lines    added  deleted
linux/CREDITS                                 :      27        7        6
linux/Documentation/Configure.help            :      52       39        0
linux/Documentation/fb/matroxfb.txt           :      25        3        3
linux/Documentation/filesystems/vfs.txt       :      17        2        2
linux/Documentation/scsi-generic.txt          :     636      636        0
linux/MAINTAINERS                             :      54       23        4
linux/Makefile                                :      16        2        2
linux/arch/alpha/kernel/setup.c               :      22        7        2
linux/arch/alpha/kernel/time.c                :      85       33       11
linux/arch/alpha/lib/clear_user.S             :       7        1        0
linux/arch/alpha/lib/copy_user.S              :       8        2        0
linux/arch/alpha/lib/strlen_user.S            :       9        2        1
linux/arch/alpha/lib/strncpy_from_user.S      :      15        2        0
linux/arch/i386/config.in                     :       8        2        0
linux/arch/i386/kernel/bios32.c               :      16        3        0
linux/arch/i386/kernel/smp.c                  :      26        2        3
linux/arch/m68k/atari/atakeyb.c               :      17        2        2
linux/arch/m68k/hp300/hil.c                   :      17        5        4
linux/arch/m68k/mac/mackeyb.c                 :      26        3        3
linux/arch/sparc/defconfig                    :       8        2        0
linux/arch/sparc/kernel/entry.S               :      32        4        4
linux/arch/sparc/kernel/head.S                :      53        7        9
linux/arch/sparc/kernel/irq.c                 :     344       79      122
linux/arch/sparc/kernel/process.c             :     102       34       23
linux/arch/sparc/kernel/setup.c               :      63       16        8
linux/arch/sparc/kernel/sun4d_irq.c           :      14        2        2
linux/arch/sparc/kernel/sun4m_irq.c           :      17        2        2
linux/arch/sparc/kernel/sun4m_smp.c           :      26        2        2
linux/arch/sparc/kernel/systbls.S             :      32        4        4
linux/arch/sparc/kernel/unaligned.c           :      21        1        3
linux/arch/sparc/lib/atomic.S                 :      15        2        0
linux/arch/sparc/lib/bitops.S                 :     177       25       60
linux/arch/sparc/lib/debuglocks.c             :      75       12       18
linux/arch/sparc/lib/irqlock.S                :      75        1       64
linux/arch/sparc/mm/init.c                    :       5        1        1
linux/arch/sparc/mm/nosrmmu.c                 :      22       11        1
linux/arch/sparc/mm/srmmu.c                   :      47       16        2
linux/arch/sparc64/config.in                  :      13        2        1
linux/arch/sparc64/defconfig                  :      16        3        0
linux/arch/sparc64/kernel/cpu.c               :       8        1        1
linux/arch/sparc64/kernel/entry.S             :      52       35        2
linux/arch/sparc64/kernel/head.S              :      26        4        4
linux/arch/sparc64/kernel/irq.c               :      14        2        2
linux/arch/sparc64/kernel/psycho.c            :     143       65       15
linux/arch/sparc64/kernel/setup.c             :      61       10       12
linux/arch/sparc64/kernel/smp.c               :     132       62       38
linux/arch/sparc64/kernel/systbls.S           :      50        6        6
linux/arch/sparc64/kernel/traps.c             :      31        2        5
linux/arch/sparc64/kernel/ttable.S            :      16        3        3
linux/arch/sparc64/kernel/unaligned.c         :      21        1        3
linux/arch/sparc64/mm/init.c                  :      27        9        1
linux/drivers/Makefile                        :      20        6        1
linux/drivers/acorn/char/keyb_ps2.c           :      20        1        6
linux/drivers/block/ide-cd.h                  :      37       10       10
linux/drivers/block/rd.c                      :       8        2        0
linux/drivers/cdrom/optcd.c                   :      19        6        0
linux/drivers/char/Makefile                   :      17        3        2
linux/drivers/char/amikeyb.c                  :      28        4        4
linux/drivers/char/bttv.c                     :      31       18        0
linux/drivers/char/bttv.h                     :      37       10        1
linux/drivers/char/dn_keyb.c                  :      27        4        4
linux/drivers/char/keyboard.c                 :     101       18       20
linux/drivers/char/mem.c                      :      25       12        0
linux/drivers/char/n_tty.c                    :      16        8        2
linux/drivers/char/pc_keyb.c                  :      72       14       29
linux/drivers/char/radio-sf16fmi.c            :      49        8        5
linux/drivers/char/radio-typhoon.c            :       8        1        1
linux/drivers/char/softdog.c                  :       7        0        1
linux/drivers/macintosh/mac_keyb.c            :      40        4        9
linux/drivers/net/3c523.c                     :     243       87       53
linux/drivers/net/ibmtr.c                     :     207       46       11
linux/drivers/net/irda/actisys.c              :      19        3        3
linux/drivers/net/irda/esi.c                  :      47        6        6
linux/drivers/net/irda/girbil.c               :      17        2        2
linux/drivers/net/irda/irport.c               :     224       29       51
linux/drivers/net/irda/irtty.c                :     667      165      150
linux/drivers/net/irda/pc87108.c              :     218       44       56
linux/drivers/net/irda/tekram.c               :     228       51       42
linux/drivers/net/irda/uircc.c                :      88       14       11
linux/drivers/net/irda/w83977af_ir.c          :     274       51       62
linux/drivers/net/net_init.c                  :      22       16        0
linux/drivers/net/pcnet32.c                   :    1801      889      616
linux/drivers/net/ppp.c                       :     402      239       34
linux/drivers/net/rrunner.c                   :    1295      371      313
linux/drivers/net/rrunner.h                   :     148       69       22
linux/drivers/net/z85230.c                    :       7        1        0
linux/drivers/pci/oldproc.c                   :      15        2        0
linux/drivers/sbus/audio/audio.c              :      93       20       11
linux/drivers/sbus/audio/cs4231.c             :    1126      330      367
linux/drivers/sbus/audio/cs4231.h             :      27       21        0
linux/drivers/sbus/char/pcikbd.c              :      61       10       19
linux/drivers/sbus/char/sunkbd.c              :       8        1        1
linux/drivers/sbus/char/sunmouse.c            :      81       20       12
linux/drivers/sbus/char/zs.c                  :      26        2        7
linux/drivers/scsi/ide-scsi.c                 :      21        4        4
linux/drivers/scsi/qlogicisp.c                :     257       66       53
linux/drivers/scsi/qlogicisp_asm.c            :    3313     2009     1279
linux/drivers/usb/CREDITS                     :      23       23        0
linux/drivers/usb/Config.in                   :      26       26        0
linux/drivers/usb/Makefile                    :      75       75        0
linux/drivers/usb/README.kbd                  :      65       65        0
linux/drivers/usb/README.ohci                 :       8        8        0
linux/drivers/usb/audio.c                     :     126      126        0
linux/drivers/usb/hub.c                       :     409      409        0
linux/drivers/usb/hub.h                       :      80       80        0
linux/drivers/usb/inits.h                     :       4        4        0
linux/drivers/usb/keyboard.c                  :     226      226        0
linux/drivers/usb/keymap.c                    :      50       50        0
linux/drivers/usb/maps/fixup.map              :      31       31        0
linux/drivers/usb/maps/serial.map             :     370      370        0
linux/drivers/usb/maps/usb.map                :     233      233        0
linux/drivers/usb/mkmap                       :      83       83        0
linux/drivers/usb/mouse.c                     :     299      299        0
linux/drivers/usb/ohci-debug.c                :     139      139        0
linux/drivers/usb/ohci.c                      :    1040     1040        0
linux/drivers/usb/ohci.h                      :     301      301        0
linux/drivers/usb/restart                     :      35       35        0
linux/drivers/usb/stopusb                     :       8        8        0
linux/drivers/usb/uhci-debug.c                :     168      168        0
linux/drivers/usb/uhci.c                      :    1202     1202        0
linux/drivers/usb/uhci.h                      :     229      229        0
linux/drivers/usb/usb-debug.c                 :     127      127        0
linux/drivers/usb/usb.c                       :     616      616        0
linux/drivers/usb/usb.h                       :     371      371        0
linux/drivers/video/atyfb.c                   :     357       90       49
linux/drivers/video/creatorfb.c               :      17        6        1
linux/drivers/video/fbcon-cfb2.c              :       8        1        1
linux/drivers/video/fbcon-cfb4.c              :       8        1        1
linux/drivers/video/fbcon.c                   :      80       26        7
linux/drivers/video/fbmem.c                   :     126       23       16
linux/drivers/video/leofb.c                   :     414      142       83
linux/drivers/video/matroxfb.c                :     116       35       11
linux/drivers/video/promcon.c                 :       5        1        1
linux/drivers/video/sbusfb.c                  :      34        9        4
linux/fs/adfs/dir.c                           :       8        0        2
linux/fs/adfs/namei.c                         :      26        4        4
linux/fs/affs/dir.c                           :       9        0        3
linux/fs/affs/namei.c                         :      22        3        3
linux/fs/autofs/dir.c                         :      12        2        2
linux/fs/autofs/root.c                        :      51        6        9
linux/fs/buffer.c                             :     106       20       35
linux/fs/coda/dir.c                           :     117        6       37
linux/fs/dcache.c                             :      14        6        2
linux/fs/devpts/root.c                        :      74        8       14
linux/fs/ext2/dir.c                           :       8        0        2
linux/fs/ext2/namei.c                         :      29        4        4
linux/fs/fat/dir.c                            :      57       18        5
linux/fs/fat/fatfs_syms.c                     :       7        1        0
linux/fs/fat/inode.c                          :      26        3        3
linux/fs/fat/misc.c                           :      14        3        3
linux/fs/hfs/dir_cap.c                        :      37        3        7
linux/fs/hfs/dir_dbl.c                        :      36        3        7
linux/fs/hfs/dir_nat.c                        :      37        3        7
linux/fs/hpfs/hpfs_fs.c                       :      53        3       16
linux/fs/inode.c                              :      20        2        4
linux/fs/isofs/dir.c                          :       9        0        3
linux/fs/isofs/namei.c                        :      32        3        9
linux/fs/minix/dir.c                          :       8        0        2
linux/fs/minix/inode.c                        :      34        4        5
linux/fs/minix/namei.c                        :      48        3        9
linux/fs/msdos/namei.c                        :      26        3        3
linux/fs/namei.c                              :      16        4        5
linux/fs/ncpfs/Config.in                      :      10        5        0
linux/fs/ncpfs/Makefile                       :       8        1        1
linux/fs/ncpfs/dir.c                          :     697      183      211
linux/fs/ncpfs/inode.c                        :     312      148       19
linux/fs/ncpfs/ioctl.c                        :      85       65        0
linux/fs/ncpfs/ncplib_kernel.c                :      90       49        5
linux/fs/ncpfs/ncplib_kernel.h                :     123       92        1
linux/fs/ncpfs/symlink.c                      :     212      212        0
linux/fs/nfs/dir.c                            :     169       31       37
linux/fs/nfs/inode.c                          :     231       77       48
linux/fs/nls/Config.in                        :       8        1        1
linux/fs/ntfs/fs.c                            :      47        5        6
linux/fs/ntfs/inode.c                         :       8        2        0
linux/fs/proc/fd.c                            :      56        5       11
linux/fs/proc/openpromfs.c                    :      54        6        7
linux/fs/proc/root.c                          :     112       12       19
linux/fs/qnx4/dir.c                           :       9        0        3
linux/fs/qnx4/namei.c                         :      44        7       13
linux/fs/romfs/inode.c                        :      38        2        9
linux/fs/smbfs/dir.c                          :      26        3        3
linux/fs/sysv/dir.c                           :      15        1        3
linux/fs/sysv/namei.c                         :      58        3       14
linux/fs/ufs/dir.c                            :      13        0        7
linux/fs/ufs/namei.c                          :      31        4        4
linux/fs/umsdos/dir.c                         :     130       20       25
linux/fs/umsdos/namei.c                       :     165       13       68
linux/fs/umsdos/rdir.c                        :      40        7        6
linux/fs/vfat/namei.c                         :     161       31       60
linux/include/asm-alpha/keyboard.h            :      15        0        2
linux/include/asm-alpha/semaphore.h           :     117       38       27
linux/include/asm-alpha/siginfo.h             :       8        1        1
linux/include/asm-alpha/uaccess.h             :     108       34       18
linux/include/asm-arm/arch-arc/keyboard.h     :      11        0        5
linux/include/asm-arm/arch-ebsa285/keyboard.h :      27        0        7
linux/include/asm-arm/arch-rpc/keyboard.h     :      19        0        6
linux/include/asm-arm/arch-vnc/keyboard.h     :      15        0        2
linux/include/asm-arm/siginfo.h               :       8        1        1
linux/include/asm-i386/bitops.h               :      62        7        7
linux/include/asm-i386/keyboard.h             :      15        0        2
linux/include/asm-i386/siginfo.h              :       8        1        1
linux/include/asm-i386/string.h               :       8        1        1
linux/include/asm-m68k/keyboard.h             :      11        0        5
linux/include/asm-mips/keyboard.h             :      15        0        2
linux/include/asm-mips/siginfo.h              :       8        1        1
linux/include/asm-ppc/keyboard.h              :      39        0       19
linux/include/asm-ppc/siginfo.h               :       8        1        1
linux/include/asm-sparc/asmmacro.h            :      17        2        2
linux/include/asm-sparc/atomic.h              :      19        6        5
linux/include/asm-sparc/floppy.h              :      24        9        2
linux/include/asm-sparc/hardirq.h             :      66       17       10
linux/include/asm-sparc/head.h                :      14        1        3
linux/include/asm-sparc/irq.h                 :      81       13       40
linux/include/asm-sparc/keyboard.h            :      21        1        3
linux/include/asm-sparc/namei.h               :      17        1        4
linux/include/asm-sparc/siginfo.h             :       8        1        1
linux/include/asm-sparc/softirq.h             :      94       14       10
linux/include/asm-sparc/spinlock.h            :      35        6        2
linux/include/asm-sparc/system.h              :      14        3        1
linux/include/asm-sparc/timer.h               :      23        3        3
linux/include/asm-sparc/uaccess.h             :      16        2        3
linux/include/asm-sparc/unistd.h              :      14        2        2
linux/include/asm-sparc/vaddrs.h              :      14        2        2
linux/include/asm-sparc64/ide.h               :      23        3        3
linux/include/asm-sparc64/keyboard.h          :      21        1        3
linux/include/asm-sparc64/namei.h             :      17        1        4
linux/include/asm-sparc64/psycho.h            :      14        2        2
linux/include/asm-sparc64/siginfo.h           :       8        1        1
linux/include/asm-sparc64/ttable.h            :      28       12        2
linux/include/asm-sparc64/unistd.h            :      14        2        2
linux/include/asm-sparc64/visasm.h            :      14        2        2
linux/include/linux/adfs_fs.h                 :       8        1        1
linux/include/linux/affs_fs.h                 :       8        1        1
linux/include/linux/ext2_fs.h                 :       8        1        1
linux/include/linux/fb.h                      :      25        4        1
linux/include/linux/fs.h                      :      38        4       14
linux/include/linux/if_ppp.h                  :      45        5       10
linux/include/linux/if_pppvar.h               :      16        2        1
linux/include/linux/in6.h                     :      65       36        2
linux/include/linux/irda.h                    :     120      120        0
linux/include/linux/iso_fs.h                  :       8        1        1
linux/include/linux/kbd_ll.h                  :       7        1        1
linux/include/linux/minix_fs.h                :       8        1        1
linux/include/linux/msdos_fs.h                :      26        3        3
linux/include/linux/ncp.h                     :      31       13        2
linux/include/linux/ncp_fs.h                  :      67       28        2
linux/include/linux/ncp_fs_sb.h               :      10        4        0
linux/include/linux/ncp_mount.h               :      18        7        5
linux/include/linux/pagemap.h                 :       8        0        2
linux/include/linux/pci.h                     :       9        3        0
linux/include/linux/proc_fs.h                 :      17        2        2
linux/include/linux/qnx4_fs.h                 :       8        1        1
linux/include/linux/sysctl.h                  :      35       16        2
linux/include/linux/sysv_fs.h                 :       8        1        1
linux/include/linux/ufs_fs.h                  :       8        1        1
linux/include/linux/umsdos_fs.p               :      21        4        4
linux/include/linux/wireless.h                :      52       15        3
linux/include/net/dst.h                       :      11        0        4
linux/include/net/flow.h                      :      12        2        0
linux/include/net/ipv6.h                      :      52       38        1
linux/include/net/irda/discovery.h            :      16        2        1
linux/include/net/irda/ircomm_common.h        :      54       16        3
linux/include/net/irda/irda.h                 :      49       13        4
linux/include/net/irda/irda_device.h          :     121       43       21
linux/include/net/irda/iriap.h                :      21        4        3
linux/include/net/irda/irkbd.h                :      91        0       91
linux/include/net/irda/irlan_client.h         :      27        5        4
linux/include/net/irda/irlan_common.h         :      36        6        3
linux/include/net/irda/irlan_eth.h            :      18        4        1
linux/include/net/irda/irlan_provider.h       :      24        4        4
linux/include/net/irda/irlap.h                :      28        8        8
linux/include/net/irda/irlap_frame.h          :      17        1        3
linux/include/net/irda/irlmp.h                :      52       14       14
linux/include/net/irda/irlpt_cli.h            :      17        2        2
linux/include/net/irda/irmod.h                :      32       17        2
linux/include/net/irda/irobex.h               :     114        0      114
linux/include/net/irda/irttp.h                :      17        2        2
linux/include/net/pkt_sched.h                 :       8        2        0
linux/include/net/route.h                     :       7        1        0
linux/include/net/sock.h                      :      34        4        3
linux/include/net/tcp.h                       :      49       17        4
linux/include/net/transp_v6.h                 :      18        3        2
linux/init/main.c                             :      26        5        1
linux/ipc/shm.c                               :      11        1        1
linux/mm/page_alloc.c                         :       8        1        1
linux/mm/vmalloc.c                            :      12        1        1
linux/mm/vmscan.c                             :      36        7        8
linux/net/802/tr.c                            :      85       17        5
linux/net/core/neighbour.c                    :      40        9        7
linux/net/core/scm.c                          :      16        9        1
linux/net/ipv4/af_inet.c                      :      44       12       12
linux/net/ipv4/ip_fw.c                        :      19        6        0
linux/net/ipv4/ip_input.c                     :      29       14        2
linux/net/ipv4/ip_sockglue.c                  :      18        3        2
linux/net/ipv4/route.c                        :      66       19        4
linux/net/ipv4/tcp.c                          :      43        8        5
linux/net/ipv4/tcp_input.c                    :     125       27       13
linux/net/ipv4/tcp_ipv4.c                     :      98       25        8
linux/net/ipv4/tcp_output.c                   :     107       12       12
linux/net/ipv4/tcp_timer.c                    :      26        3        3
linux/net/ipv6/Makefile                       :       9        2        1
linux/net/ipv6/af_inet6.c                     :      86       16        8
linux/net/ipv6/datagram.c                     :     113       34       13
linux/net/ipv6/ip6_fib.c                      :      28        4        4
linux/net/ipv6/ip6_flowlabel.c                :     620      620        0
linux/net/ipv6/ip6_output.c                   :      95       13       24
linux/net/ipv6/ipv6_sockglue.c                :      65       19        4
linux/net/ipv6/ndisc.c                        :      17        2        2
linux/net/ipv6/raw.c                          :     112       39        7
linux/net/ipv6/tcp_ipv6.c                     :     205       51       10
linux/net/ipv6/udp.c                          :     225       69       21
linux/net/irda/af_irda.c                      :      78       21        5
linux/net/irda/discovery.c                    :      35        4        4
linux/net/irda/ircomm/ircomm_common.c         :     853      385      282
linux/net/irda/ircomm/irvtd_driver.c          :     358       70       58
linux/net/irda/irda_device.c                  :     118       15       36
linux/net/irda/iriap.c                        :     272       60       46
linux/net/irda/irlan/irlan_client.c           :     181       17       49
linux/net/irda/irlan/irlan_client_event.c     :      56        5       10
linux/net/irda/irlan/irlan_common.c           :     314       57      148
linux/net/irda/irlan/irlan_eth.c              :     190      160        1
linux/net/irda/irlan/irlan_provider.c         :     106       15       21
linux/net/irda/irlan/irlan_provider_event.c   :      43       11        4
linux/net/irda/irlap.c                        :     147       25       40
linux/net/irda/irlap_event.c                  :     900      305      297
linux/net/irda/irlap_frame.c                  :     345       55      106
linux/net/irda/irlmp.c                        :      50        7       12
linux/net/irda/irlmp_event.c                  :     230       64       68
linux/net/irda/irlmp_frame.c                  :     177       39       46
linux/net/irda/irlpt/irlpt_cli.c              :      19        3        3
linux/net/irda/irmod.c                        :      46        3       19
linux/net/irda/irsysctl.c                     :      29        7        2
linux/net/irda/irttp.c                        :     163       47       28
linux/net/irda/qos.c                          :      17        2        2
linux/net/irda/wrapper.c                      :     304       63       69
linux/net/netsyms.c                           :      34       14        0
linux/net/sched/cls_fw.c                      :      28        6        2
linux/net/sched/cls_rsvp.h                    :      30        7        7
linux/net/sched/sch_cbq.c                     :       7        0        1
linux/net/sched/sch_sfq.c                     :       7        0        1
linux/net/socket.c                            :      31        8        3
linux/scripts/ksymoops/oops.c                 :       8        1        1
-- 
Thomas Koenig, Thomas...@ciw.uni-karlsruhe.de, ig...@dkauni2.bitnet.
The joy of engineering is to find a straight line on a double
logarithmic diagram.
#!/bin/sh
# This is a shell archive
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
# existing files will NOT be overwritten unless -c is specified
#
# This is part 01 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
#
if test -r _shar_seq_.tmp; then
        echo 'Must unpack archives in sequence!'
        echo Please unpack part `cat _shar_seq_.tmp` next
        exit 1
fi
# ============= patch-2.2.7 ==============
if test -f 'patch-2.2.7' -a X"$1" != X"-c"; then
        echo 'x - skipping patch-2.2.7 (File already exists)'
        rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting patch-2.2.7 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'patch-2.2.7' &&
diff -u --recursive --new-file v2.2.6/linux/CREDITS linux/CREDITS
--- v2.2.6/linux/CREDITS	Tue Mar 23 14:35:46 1999
+++ linux/CREDITS	Fri Apr 23 08:42:03 1999
@@ -810,12 +810,13 @@
X D: Transmeta BOFH in my copius free time
X 
X N: Dirk Hohndel
-E: hoh...@aib.com
+E: hoh...@suse.de
X D: The XFree86[tm] Project
-S: AIB Software Corporation
-S: 46030 Manekin Plaza, Suite 160
-S: Dulles, Virginia 20166
-S: USA
+D: USB mouse maintainer
+S: SuSE Rhein/Main AG
+S: Mergenthalerallee 45-47
+S: 65760 Eschborn
+S: Germany
X 
X N: Kenji Tsutomu Hollis
X E: kho...@bitgate.com
@@ -1874,7 +1875,7 @@
X 
X N: Linus Torvalds
X E: torv...@transmeta.com
-W: http://www.cs.helsinki.fi/~torvalds/
+W: http://www.cs.helsinki.fi/Linus.Torvalds
X P: 1024/A86B35C5 96 54 50 29 EC 11 44 7A  BE 67 3C 24 03 13 62 C8
X D: Original kernel hacker
X S: 1050 Woodduck Avenue
diff -u --recursive --new-file v2.2.6/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.2.6/linux/Documentation/Configure.help	Fri Apr 16 14:47:30 1999
+++ linux/Documentation/Configure.help	Tue Apr 20 15:17:20 1999
@@ -7443,6 +7443,26 @@
X   case insensitive, and case in names is preserved. Say Y. You can
X   disable it at mount time with the -N os2 parameter of ncpmount.
X 
+Lowercase DOS filenames on LONG namespace volume
+CONFIG_NCPFS_SMALLDOS
+  Saying Y here will convert every filename with creator/owner DOS
+  namespace on NetWare servers to lowercase characters as silently
+  kernel does when you mount  NetWare file server volumes with DOS
+  namespace without OS2/LONG namespace support. Saying N here will
+  give you these filenames with uppercase characters.
+  
+  This is  only cosmetic option  because of OS2/LONG  namespace is
+  case  insensitive.  The  only major  reason for  this option  is
+  backward  compatibility when  you want  to do  step from  DOS to
+  OS2/LONG  namespace support.  Long filenames  (created by Win95)
+  will not be affected.
+
+  This  option  does not  solve a  problem that  filenames  appear
+  differently  in Linux box  and in MS  environment because  of MS
+  does an additional  conversions on client side.  You can achieve
+  simillar effects  enabling ncpfs  option "Allow  using of Native
+  Language Support" below.
+
X Allow mounting of volume subdirectories
X CONFIG_NCPFS_MOUNT_SUBDIR
X   Allows you to mount not only whole servers or whole volumes, but
@@ -7461,6 +7481,25 @@
X   servers. Do not say Y if security is primary for you because root
X   can read your session key (from /proc/kcore).
X 
+Allow using of Native Language Support
+CONFIG_NCPFS_NLS
+  Allows you to use codepages and I/O charsets for file name translation
+  between file system on server and input/output. This may be useful,
+  if you want to access to the server with other operating systems,
+  e.g. Windows 95. See also NLS for more Information.
+
+  To select codepages and I/O charsets use ncpfs-2.2.0.13 or newer.
+
+Symbolic links and mode permission bits
+CONFIG_NCPFS_EXTRAS
+  This enables the use of symbolic links and an execute permission
+  bit on NCPFS. The file server need not have long name space or NFS
+  name space loaded for these to work, they are stored using rarely
+  found combinations of Hidden, System and Shared flags.
+
+  To use the new attributes, you are recommended to use the flags
+  '-f 600 -d 755' on the ncpmount commandline.
+  
X nls codepage 437
X CONFIG_NLS_CODEPAGE_437
X   The Microsoft fat filesystem family can deal with filenames in
diff -u --recursive --new-file v2.2.6/linux/Documentation/fb/matroxfb.txt linux/Documentation/fb/matroxfb.txt
--- v2.2.6/linux/Documentation/fb/matroxfb.txt	Tue Jan 19 11:32:50 1999
+++ linux/Documentation/fb/matroxfb.txt	Tue Apr 20 15:13:00 1999
@@ -1,6 +1,6 @@
X [This file is cloned from VesaFB. Thanks go to Gerd Knorr]
X 
-what is matroxfb?
+What is matroxfb?
X =================
X 
X This is a driver for a graphic framebuffer for Matrox devices on
@@ -221,6 +221,8 @@
X sync:X   - sync. pulse - bit 0 inverts HSYNC polarity, bit 1 VSYNC polarity.
X            If bit 3 (value 0x08) is set, composite sync instead of HSYNC is
X 	   generated. If bit 5 (value 0x20) is set, sync on green is turned on.
+	   Do not forget that if you want sync on green, you also probably
+	   want composite sync.
X 	   Default depends on `vesa'.
X depth:X  - Bits per pixel: 0=text, 4,8,15,16,24 or 32. Default depends on
X            `vesa'.
@@ -284,8 +286,6 @@
X  + current fbset is not able to set 15bpp videomode: you must specify
X    depth==16 and green.length==5. fbset does not allow you to set 
X    green.length.
- + hardware cursor is available only in accelerated videomodes. Maybe that
-   this is misfeature and not feature.
X  + text mode uses 6 bit VGA palette instead of 8 bit (one of 262144 colors
X    instead of one of 16M colors). It is due to hardware limitation of 
X    MilleniumI/II and SVGALib compatibility.
diff -u --recursive --new-file v2.2.6/linux/Documentation/filesystems/vfs.txt linux/Documentation/filesystems/vfs.txt
--- v2.2.6/linux/Documentation/filesystems/vfs.txt	Wed Jul  1 19:38:51 1998
+++ linux/Documentation/filesystems/vfs.txt	Tue Apr 27 09:24:34 1999
@@ -4,7 +4,7 @@
X 
X 		Richard Gooch <rgo...@atnf.csiro.au>
X 
-			      27-JUN-1998
+			      23-APR-1999
X 
X 
X Conventions used in this document                                     <section>
@@ -129,7 +129,7 @@
X   name: the name of the filesystem type, such as "ext2", "iso9660",
X 	"msdos" and so on
X 
-  fs_flags: various flags (i.e. if it is a read-only FS)
+  fs_flags: various flags (i.e. FS_REQUIRES_DEV, FS_NO_DCACHE, etc.)
X 
X   read_super: the method to call when a new instance of this
X 	filesystem should be mounted
diff -u --recursive --new-file v2.2.6/linux/Documentation/scsi-generic.txt linux/Documentation/scsi-generic.txt
--- v2.2.6/linux/Documentation/scsi-generic.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/scsi-generic.txt	Sat Apr 24 17:49:37 1999
@@ -0,0 +1,636 @@
+            Notes on Linux's SG driver version 2.1.30
+            -----------------------------------------
+                                                        990328
+
+Introduction
+============
+These are notes on the Linux SCSI generic packet device driver (sg)
+describing version 2.1.30 . The original driver was written by Lawrence
+Foard and has remained in place with minimal changes since circa 1992.
+Version 2 of this driver remains backward compatible (binary and
+source **) with the original. It adds scatter gather, command queuing,
+per file descriptor sequencing, asynchronous notification and better
+error reporting.
+
+Sg is one of the four "high level" SCSI device drivers along with
+sd, st and sr (disk, tape and CDROM respectively). Sg is more generalized
+(but lower level) than its sibling and tends to be used on SCSI devices
+that don't fit into the already serviced categories. Thus sg is used for
+scanners, cd writers and reading audio cds amongst other things.
+
+The interface and usage of the original sg driver has been documented
+by Heiko Eissfeldt in a HOWTO called SCSI-Programming-HOWTO. My copy
+of the document is version 1.5 dated 7th May 1996. It can found at
+ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/SCSI-Programming-HOWTO .
+Amongst other things it has a lot of tables from the SCSI-2 standard
+that are very useful for programming this interface.
+
+** It is possible to write applications that perform differently
+depending on whether they are using the original or this version of
+the sg device driver. The author is not aware of any useful applications
+that have problems with version 2 (yet).
+
+
+Architecture
+============
+The SCSI generic packet device driver (sg) is a character based device.
+It is one of the four high level device driver in the SCSI sub-system;
+the others are sd (for direct-access devices - disks), st (for tapes)
+and sr (for data cdroms). The other three devices are block devices.
+
+The unifying layer of the SCSI sub-system in the so-called mid-level.
+Below that are all the drivers for the various adapters supported by
+Linux.
+
+Since sg is a character device it supports the traditional Unix
+system calls of open(), close(), read(), write() and ioctl(). Two other
+related system calls: poll() and fcntl() are added to this list and
+how they interact with the sg device driver is documented later.
+ 
+An SG device is accessed by write()ing SCSI commands plus any associated 
+outgoing data to it; the resulting status codes and any incoming data are
+then obtained by a read() call. The device can be opened O_NONBLOCK
+(non-blocking) and poll() used to monitor its progress. The device may be
+opened O_EXCL which excludes other "sg" users from this device (but not 
+"sd", "st" or "sr" users). The buffer given to the write() call is made
+up as follows:
+        - struct sg_header image (see below)
+        - scsi command (6, 10 or 12 bytes long)
+        - data to be written to the device (if any)
+
+The buffer received from the corresponding read() call contains:
+        - struct sg_header image (check status/errors + sense_buffer)
+        - data read back from device (if any)
+
+The given SCSI command has its LUN field overwritten by the LUN value of
+the associated sg device that has been open()ed.
+
+
+sg_header
+=========
+This is the name of the control structure that conveys information
+about the length of data to be read/written by the associated SCSI
+command. It also conveys error and status information from the
+read() call. An instance of this structure is the first thing that
+is placed in the data buffers of both write() and read().
+
+In its original form it looked like this:
+struct sg_header {
+    int pack_len;
+    int reply_len;
+    int pack_id;
+    int result;
+    unsigned int twelve_byte:1;
+    unsigned int other_flags:31;
+    unsigned char sense_buffer[16];
+}; /* this structure is 36 bytes long */
+
+The 'pack_len' is bizzare and ends up having the 'reply_len' put in it
+(perhaps it had a use at some stage). 
+
+The 'reply_len' is the length of the data the corresponding read()
+will/should request (including the sg_header). 
+
+The 'pack_id' is not acted upon by the sg device driver but is conveyed
+back to the corresponding read() so it can be used for sequencing by an
+application. 
+
+The 'result' is also bizzare, turning certain types of host codes it 0 (no
+error), EBUSY or EIO. With better error reporting now available, the
+'result' is best ignored.
+
+The 'twelve_byte' field overrides the internal SCSI command length "guessing"
+algorithm for group 6 and 7 commands (ie when 1st byte >= 0xc0) and forces
+a command lenth of 12 bytes.
+The command length "guessing" algorithm is as follows:
+Group:  0    1    2    3    4    5    6    7
+Length: 6   10   10   12   12   12   10   10
+
+'other_flags' was originally documented as "not used" but some current
+applications assume it has 0 placed in it.
+
+The 'sense_buffer' is the first 16 bytes of SCSI sense buffer that is
+returned when the target returns a SCSI status code of CHECK_CONDITION
+or COMMAND_TERMINATED [or (driver_status & DRIVER_SENSE) is true]. This
+buffer should be at least 18 bytes long and arguably 32 bytes; unfortunately
+this is unlikely to happen in the 2.2.x series of kernels.
+
+The new sg_header offered in this driver is:
+#define SG_MAX_SENSE 16
+struct sg_header
+{
+    int pack_len;    /* [o] reply_len (ie useless) ignored as input */
+    int reply_len;   /* [i] max length of expected reply (inc. sg_header) */
+    int pack_id;     /* [io] id number of packet (use ints >= 0) */
+    int result;      /* [o] 0==ok, else (+ve) Unix errno code (e.g. EIO) */
+    unsigned int twelve_byte:1;
+        /* [i] Force 12 byte command length for group 6 & 7 commands  */
+    unsigned int target_status:5;   /* [o] scsi status from target */
+    unsigned int host_status:8;     /* [o] host status (see "DID" codes) */
+    unsigned int driver_status:8;   /* [o] driver status+suggestion */
+    unsigned int other_flags:10;    /* unused */
+    unsigned char sense_buffer[SG_MAX_SENSE]; /* [o] when target_status is
+               CHECK_CONDITION or COMMAND_TERMINATED this is output. */
+};      /* This structure is 36 bytes long on i386 */
+
+Firstly the new header is binary compatible with the original. This is
+important for keeping existing apps working without recompilation.
+
+Only those elements (or fields) that are new or in some way different
+from the original are documented below.
+
+'pack_id' becomes input to a read() when ioctl(sg_fd, SG_SET_FORCE_PACK_ID,
+&one) is active. A 'pack_id' of -1 is interpreted as fetch the oldest
+waiting packet; any other value will cause the read() to wait (or yield
+EAGAIN) until a packet with that 'pack_id' becomes available. In all cases
+the value of 'pack_id' available after a read() is the value given to that
+variable in the prior, corresponding write().
+
+The 'target_status' field is always output and is the (masked and shifted
+1 bit right) SCSI status code from the target device. The allowable
+values are (found in <scsi/scsi.h>):
+/* N.B. 1 bit offset from usual SCSI status values */
+#define GOOD                 0x00
+#define CHECK_CONDITION      0x01  
+#define CONDITION_GOOD       0x02
+#define BUSY                 0x04
+#define INTERMEDIATE_GOOD    0x08
+#define INTERMEDIATE_C_GOOD  0x0a
+#define RESERVATION_CONFLICT 0x0c
+#define COMMAND_TERMINATED   0x11
+#define QUEUE_FULL           0x14
+When the 'target_status' is CHECK_CONDITION or COMMAND_TERMINATED the
+'sense_buffer' is output. Note that when (driver_status & DRIVER_SENSE)
+is true then the 'sense_buffer' is also output (this seems to occur when
+the scsi ide emulation is used). When the 'sense_buffer' is output the 
+SCSI Sense Key can be found at (sense_buffer[2] & 0x0f) .
+
+The 'host_status' field is always output and has the following values
+whose "defines" are not visible outside the kernel (unfortunately):
+#define DID_OK          0x00 /* NO error                                */
+#define DID_NO_CONNECT  0x01 /* Couldn't connect before timeout period  */
+#define DID_BUS_BUSY    0x02 /* BUS stayed busy through time out period */
+#define DID_TIME_OUT    0x03 /* TIMED OUT for other reason              */
+#define DID_BAD_TARGET  0x04 /* BAD target.                             */
+#define DID_ABORT       0x05 /* Told to abort for some other reason     */
+#define DID_PARITY      0x06 /* Parity error                            */
+#define DID_ERROR       0x07 /* Internal error                          */
+#define DID_RESET       0x08 /* Reset by somebody.                      */
+#define DID_BAD_INTR    0x09 /* Got an interrupt we weren't expecting.  */
+#define DID_PASSTHROUGH 0x0a /* Force command past mid-layer            */
+#define DID_SOFT_ERROR  0x0b /* The low level driver just wish a retry  */
+
+The 'driver_status' field is always output. When ('driver_status' &
+DRIVER_SENSE) is true the 'sense_buffer' is also output. The following
+values whose "defines" are not visible outside the kernel (unfortunately)
+can occur:
+#define DRIVER_OK           0x00 /* Typically no suggestion */
+#define DRIVER_BUSY         0x01
+#define DRIVER_SOFT         0x02
+#define DRIVER_MEDIA        0x03
+#define DRIVER_ERROR        0x04
+#define DRIVER_INVALID      0x05
+#define DRIVER_TIMEOUT      0x06
+#define DRIVER_HARD         0x07
+#define DRIVER_SENSE        0x08
+/* above status 'or'ed with one of the following suggestions */
+#define SUGGEST_RETRY       0x10
+#define SUGGEST_ABORT       0x20
+#define SUGGEST_REMAP       0x30
+#define SUGGEST_DIE         0x40
+#define SUGGEST_SENSE       0x80
+
+'other_flags' still remains as a 10 bit field, so code that places 0 in it
+will still be happy. It is not used.
+
+
+memory
+======
+Memory is a scarce resource in any computer. Sg needs to reserve memory
+suitable for DMA roughly equal in size to the maximum of the write and
+read data buffers for each packet. This DMA memory is obtained at the time
+of a write() and released when the corresponding read() is called (although
+if memory is tight it may be using the buffer reserved by the open() ).
+
+Linux obtaining memory a challenge for several reasons. The memory pool
+that sg uses is in common with all other device drivers and all user
+processes. In this environment the only way to 99.9% guarantee a driver
+will have memory in Linux is to build it into the kernel (ie not as a
+module) and then reserve it on initialization before user processes get
+a chance. [Of course, another driver initialized before sg could take
+all available memory ...] Another problem is the biggest contiguous
+chunk of memory that can be obtained from the kernel is 32 * PAGE_SIZE
+(which is 128KBytes on i386). As memory gets "splintered" there is a good
+chance that buffers won't be available (my machine has 64 MBytes of RAM
+and has 3 available at the moment).
+
+The original sg driver used the following technique: grab a SG_BIG_BUFF
+sized buffer at driver initialization and use it for all requests greater
+than PAGE_SIZE (4096 bytes on i386). By default SG_BIG_BUFF is set to
+32 KBytes in the origianl driver but many applications suggest that the
+user increases this number. Linux limits the biggest single buffer of
+this type to 32 * PAGE_SIZE (128KBytes on i386). Unfortunately if the
+sg driver is a module then there is a high chance a contiguous block of
+that large size will not be available at module initialization.
+
+The author has found no "silver bullet" solution but uses multiple
+techniques hoping that at least one is able provide memory at the critical
+time. Listed below are some of these techniques:
+        - use scatter gather: then instead of one large buffer needing to
+          be found, multiple smaller buffer can be used
+        - use memory above the 16MByte level: the original driver limited
+          itself to obtaining memory below the 16MByte level (on the i386)
+          due to the shortcomings of DMA on ISA adapters. Yet more and more
+          people use PCI adapters that don't have this problem. So make
+          the decision based on the capabilities of the host adpater
+          associated with the current SCSI device
+        - reserve some memory at open() for emergencies but otherwise
+          fetch and release it on a per packet basis
+        - if the kernel is short of memory then dip into the SCSI DMA
+          pool (maintained by the mid-level driver) to a limited amount
+
+
+
+System Calls
+============
+What follows are descriptions of the characteristics of the standard
+Unix operating system calls when applied to a SCSI generic device
+using this version of the device driver.
+
+open
+----
+The filename should be an 'sg' device such as
+/dev/sg[a-z]
+/dev/sg[0,1,2,...]
+or a symbolic link to one of these. [Devfs has its own sub-directory for
+sg devices.] It seems as though SCSI devices are allocated to sg minor
+numbers in the same order as they appear in 'cat /proc/scsi/scsi'.
+Sg is a "character" based Linux device driver. This means it has an
+open/close/read/write/ioctl type interface.
+
+Flags can be either O_RDONLY or O_RDWR or-ed with either
+O_EXCL          waits for other opens on sg device to be closed before
+                proceeding. If O_NONBLOCK is set then yields EBUSY when
+                someone else has the sg device open. The combination of
+                O_RDONLY and O_EXCL is disallowed.
+O_NONBLOCK      Sets non-blocking mode. Calls that would otherwise block
+                yield EAGAIN (eg read() ) or EBUSY (eg open() ).
+
+The original version of sg did not allow the O_RDONLY (yielding a EACCES
+error). This version allows it for accessing ioctls (e.g. doing an sg
+device scan with the SG_GET_SCSI_ID ioctl) but write()s will not be
+allowed.
+
+By default, sequencing is per file descriptor in this version of sg. This
+means, for example that 2 processes can independently manipulate the same
+sg device at the same time. This may or may not make sense depending on
+the application: 2 processes (logically) reading from the same direct access
+device (ie a disk) is ok while running 2 instances of cd writing software
+on the same device at the same time probably wouldn't be a good idea. The
+previous version of sg supported only per device sequencing and this can
+still be selected with the SG_SET_MERGE_FD,1 ioctl().
+
+The driver will attempt to reserve SG_SCATTER_SZ bytes (32KBytes in the
+current sg.h) on open() for "emergency" situations. If this is unavailable
+it will halve its request and try again. It gives up if PAGE_SIZE bytes
+(4096 bytes on i386) cannot be obtained so no memory is reserved. In this
+case open() will still return successfully. The actual amount of memory
+reserved can be found with the SG_GET_RESERVED_SIZE ioctl().
+
+Returns a file descriptor if >= 0 , otherwise -1 implies an error.
+
+Error codes (value in 'errno' after -1 returned):
+ENODEV          sg not compiled into kernel or the kernel cannot find the
+                sg module (or it can't initialize itself (low memory??))
+ENXIO           either scsi sub-system is currently processing some error
+                (eg doing a device reset) or the sg driver/module removed
+                or corrupted
+EBUSY           O_NONBLOCK set and some user of this sg device has O_EXCL
+                set while someone is already using this device
+EINTR           while waiting for an "exclusive" lock to clear, a signal
+                is received, just try again ...        
+ENOMEM          An attempt to get memory to store this open's context
+                failed (this was _not_ a request to reserve DMA memory)
+EACCES          An attempt to use both O_RDONLY and O_EXCL
+
+
+write
+-----
+Even though sg is a character-based device driver it sends and receives
+packets to/from the associated scsi device. Write() is used to send a
+packet containing 2 mandatory parts and 1 optional part. The mandatory
+parts are:
+  - a control block (an instance of struct sg_header)
+  - a SCSI command (6, 10 or 12 bytes long)
+The optional part is:
+  - outgoing data (eg if a SCSI write command is being sent)
+These should appear as one contiguous string in the buffer given to
+write() in the above order with no pad characters.
+
+If a write() accepts this packet then at some later time the user should
+call a read() to get the result of the SCSI command. The previous sg
+driver enforced a strict write()/read()/write()/read() regime so that a
+second write() would block until first read() was finished. This sg
+driver relaxes that condition and thereby allows command queuing
+(limit is SG_MAX_QUEUE (16) outstanding packets per file descriptor).
+However, for backward compatibility, command queuing is turned off
+by default (#define SG_DEF_COMMAND_Q 0 in sg.h). This can be changed
+via the the SG_SET_COMMAND_Q ioctl() [or by recompiling after changing
+the above define to 1].
+
+In this sg driver a write() should return more or less immediately.
+
+Returns number of bytes written if > 0 , otherwise -1 implies an error.
+
+Error codes (value in 'errno' after -1 returned):
+ENXIO           either scsi sub-system is currently processing some error
+                (eg doing a device reset) or the sg driver/module removed
+                or corrupted
+EACCES          opened with RD_ONLY flag
+EIO             incoming buffer too short. It should be at least (6 +
+                sizeof(struct sg_header))==42 bytes long
+EDOM            a) command queuing off: a packet is already queued
+                b) command queuing on: too many packets queued 
+                   (SG_MAX_QUEUE exceeded)
+EAGAIN          SCSI mid-level out of command blocks (rare), try again.
+                This is more likely to happen when queuing commands,
+                so wait a bit (eg usleep(10000) ) before trying again
+ENOMEM          can't get memory for DMA. Take evasive action ...
+                (see section on memory)
+
+
+read
+----
+Read() is used to receive a packet containing 1 mandatory part and 1 
+optional part. The mandatory part is:
+  - a control block (an instance of struct sg_header)
+The optional part is:
+  - incoming data (eg if a SCSI read command was sent by earlier write() )
+The buffer given to a read() and its corresponding count should be
+sufficient to accommodate this packet to avoid truncation. Truncation has
+occurred if count < sg_header::replylen .
+
+By default, read() will return the oldest packet queued up. If the 
+SG_SET_FORCE_PACK_ID,1 ioctl() is active then read() will attempt to
+fetch the packet whose pack_id (given earlier to write()) matches the
+sg_header::pack_id given to this read(). If not available it will either
+wait or yield EAGAIN. As a special case, -1 in sg_header::pack_id given
+to read() will match the oldest packet.
+
+
+Returns number of bytes read if > 0 , otherwise -1 implies an error.
+Unfortunately the return value in the non-error case is simply the
+same as the count argument. It is not the actual number of bytes
+DMA-ed by the SCSI device. This driver is currently unable to provide
+such an underrun indication.
+
+Error codes (value in 'errno' after -1 returned):
+ENXIO           either scsi sub-system is currently processing some error
+                (eg doing a device reset) or the sg driver/module removed
+                or corrupted
+EAGAIN          either no waiting packet or requested packet is not
+                available while O_NONBLOCK flag was set
+EINTR           while waiting for a packet, a signal is received, just
+                try again ...        
+EIO             if the 'count' given to read() is < sizeof(struct sg_header)
+                and the 'result' element in sg_header is non-zero. Not a
+                recommended error reporting technique
+
+
+close
+-----
+Preferably a close() should be done after all issued write()s have had
+their corresponding read() calls completed. Unfortunately this is not
+always possible. The semantics of close() in Unix are to return more
+or less immediately (ie not wait on any event) so the driver needs to
+arrange to an orderly cleanup of those packets that are still "in
+flight".
+
+A process that has an open file descriptor to an sg device may be aborted
+(eg by a kill signal). In this case, the kernel automatically calls close 
+(which is called 'sg_release()' in the version 2 driver) to facilitate
+the cleanup mentioned above.
+
+A problem persists in version 2.1.8 if the sg driver is a module and is
+removed while packets are still "in flight". Hopefully this will be soon
+fixed.
+
+Returns 0 if successful, otherwise -1 implies an error.
+
+Error codes (value in 'errno' after -1 returned):
+ENXIO           sg driver/module removed or corrupted
+
+ioctl (sg specific)
+-------------------
+Ken Thompson (or perhaps some other Unix luminary) described ioctl() as 
+the "garbage bin of Unix". This driver compounds the situation by adding
+around 18 more commands. These commands either yield state information (10
+of them), change the driver's characteristics (8 of them) or allow direct
+communication with the common SCSI mid-level driver.
+
+Those commands with an appended "+" are new in version 2.
+
+Those commands with an appended "W" are only accessible from file
+descriptors opened with O_RDWR. They will yield EACCES otherwise.
+
+SG_GET_TIMEOUT:
+Ignores its 3rd argument and _returns_ the timeout value (which will be
+>= 0 ). The unit of this timeout is "jiffies" which are currently 10
+millisecond intervals on i386 (less on an alpha). Linux supplies
+a manifest constant HZ which is the number of "jiffies" in 1 second.
+
+SG_SET_TIMEOUT:
+Assumes 3rd argument points to an int containing the new timeout value
+for this file descriptor. The unit is a "jiffy". Packets that are
+already "in flight" will not be effected. The default value is set
+on open() and is SG_DEFAULT_TIMEOUT (defined in sg.h).
+
+SG_EMULATED_HOST:
+Assumes 3rd argument points to an int and outputs a flag indicating
+whether the host (adapter) is connected to a real SCSI bus or is
+emulated one (eg ide-scsi device driver). A value of 1 means emulated
+while 0 is not.
+
+SG_SET_FORCE_LOW_DMA +:
+Assumes 3rd argument points to an int containing 0 or 1. 0 (default)
+means sg decides whether to use memory above 16 Mbyte level (on i386)
+based on the host adapter being used by this SCSI device. Typically
+PCI SCSI adapters will indicate they can DMA to the whole 32 bit address
+space. 
+If 1 is given then the host adapter is overridden and only memory below
+the 16MB level is used for DMA. A requirement for this should be
+extremely rare. If the "reserve" buffer allocated on open() is not in
+use then it will be de-allocated and re-allocated under the 16MB level
+(and the latter operation could fail yielding ENOMEM).
+Only the current file descriptor is effected.
+
+SG_GET_LOW_DMA +:
+Assumes 3rd argument points to an int and places 0 or 1 in it. 0
+indicates the whole 32 bit address space is being used for DMA transfers
+on this file descriptor. 1 indicates the memory below the 16MB level
+(on i386) is being used (and this may be the case because the host
+adapters setting has been overridden by SG_SET_FORCE_LOW_DMA,1 .
+
+SG_GET_SCSI_ID +:
+Assumes 3rd argument is pointing to an object of type Sg_scsi_id and
+populates it. That structure contains ints for host_no, channel,
+scsi_id, lun and scsi_type. Most of this information is available from
+other sources (eg SCSI_IOCTL_GET_IDLUN and SCSI_IOCTL_GET_BUS_NUMBER)
+but tends to be awkward to collect.
+
+SG_SET_FORCE_PACK_ID +:
+Assumes 3rd argument is pointing to an int. 0 (default) instructs read()
+to return the oldest (written) packet if multiple packets are
+waiting to be read (when command queuing is being used). 
+1 instructs read() to view the sg_header::pack_id as input and return the
+oldest packet matching that pack_id or wait until it arrives (or yield
+EAGAIN if O_NONBLOCK is in force). As a special case the pack_id of -1
+given to read() in the mode will match the oldest packet.
+Only the current file descriptor is effected by this command.
+
+SG_GET_LOW_DMA +:
+Assumes 3rd argument points to an int and places the pack_id of the
+oldest (written) packet in it. If no packet is waiting to be read then
+yields -1.
+
+SG_GET_NUM_WAITING +:
+Assumes 3rd argument points to an int and places the number of packets
+waiting to be read in it.
+
+SG_GET_SG_TABLESIZE +:
+Assumes 3rd argument points to an int and places the maximum number of
+scatter gather elements supported by the host adapter. 0 indicates that
+the adapter does support scatter gather.
+
+SG_SET_RESERVED_SIZE +W:
+This is not currently implemented. It is intended for reserving either a
+large buffer or scatter gather list that will be available until the
+current file descriptor is closed. The requested amount of memory may
+not be available so SG_GET_RESERVED_SIZE should be used after this call
+to see how much was reserved. (EBUSY error possible)
+
+SG_GET_RESERVED_SIZE +:
+Assumes 3rd argument points to an int and places the size in bytes of
+the DMA buffer reserved on open() for emergencies. If this is 0 then it
+is probably not wise to attempt on operation like burning a CD on this
+file descriptor.
+
+SG_SET_MERGE_FD +W:
+Assumes 3rd argument is pointing to an int. 0 (the default) causes all
+subsequent sequencing to be per file descriptor. 1 causes all subsequent
+sequencing to be per device. If this command tries to change the current
+state and the is one or more _other_ file descriptors using this sg
+device then an EBUSY error occurs. Also if this file descriptor was not
+open()ed with the O_RDWR flag then an EACCES error occurs.
+Per device sequencing was the original semantics and allowed, for example
+different processes to "share" the device, one perhaps write()ing with
+the other one read()ing. This command is supplied if anyone needs those
+semantics. Per file descriptor sequencing, perhaps with the usage of
+the O_EXCL flag, seems more sensible.
+
+SG_GET_MERGE_FD +:
+Assumes 3rd argument points to an int and places 0 or 1 in it. 0 implies
+sequencing is per file descriptor. 1 implies sequencing is per device
+(original sg driver's semantics).
+
+SG_SET_COMMAND_Q +:
+Assumes 3rd argument is pointing to an int. 0 (current default, set by
+SG_DEF_COMMAND_Q in sg.h) disables command queuing. Attempts to write()
+a packet while one is already queued will result in a EDOM error.
+1 turns command queuing on.
+Changing the queuing state only effects write()s done after the change.
+Only the current file descriptor is effected by this command.
+
+SG_GET_COMMAND_Q +:
+Assumes 3rd argument points to an int and places 0 or 1 in it. 0 implies
+that command queuing is off on this file descriptor. 1 implies command
+queuing is on.
+
+SG_SET_DEBUG +:
+Assumes 3rd argument is pointing to an int. 0 (default) turns debugging
+off. Values > 0 cause the SCSI sense buffer to be decoded and output
+to the console/log when a SCSI device error occurs. Values > 8 cause
+the current sg device driver's state to be output to the console/log
+(this is a "one off" effect).
+If you need a _lot_ of the SCSI sub-system debug information (mainly from
+the mid-level) then try 'echo "scsi dump 0" > /proc/scsi/scsi' and lots of
+debug will appear in your console/log.
+
+ioctl (in common with sd, st + sr)
+----------------------------------
+The following ioctl()s can be called from any high-level scsi device
+driver (ie sd, st, sr + sg). Access permissions may differ a bit from
+one device to another, the access information given below is specific to
+the sg device driver.
+
+SCSI_IOCTL_GET_IDLUN:
+SCSI_IOCTL_GET_BUS_NUMBER:
+
+SCSI_IOCTL_SEND_COMMAND:  W
+If open()ed O_RDONLY yields an EACCESS error. Otherwise is forwarded onto
+the SCSI mid-level driver for processing.
+Don't know much about this one but it looks pretty powerful and
+dangerous. Some comments says it is also deprecated.
+
+<any_command_not matching_above>:  W
+If open()ed O_RDONLY yields an EACCESS error. Otherwise is forwarded onto
+the SCSI mid-level driver for processing.
+
+
+poll
+----
+This is a native call in Linux 2.2 but most of its capabilities are available
+through the older select() call. Given a choice poll() should probably be
+used. Typically poll() is used when a sg scsi device is open()ed O_NONBLOCK
+for polling; or alternatively with asynchronous notification using the
+fcntl() system call (below) and the SIGPOLL (aka SIGIO) signal.
+Only if something drastically is wrong (eg file handle gone stale) will
+POLLERR ever be set. POLLPRI, POLLHUP and POLLNVAL are never set.
+POLLIN is set when there is one or more packets waiting to be read.
+When POLLIN is set it implies that a read() will not block (or yield
+EAGAIN in non-blocking mode) but return a packet immediately.
+POLLOUT (aka POLLWRNORM) is set when write() is able to accept a packet
+(ie will _not_ yield an EDOM error). The setting of POLLOUT is effected
+by the SG_SET_COMMAND_Q state: if the state is on then POLLOUT will remain
+set until the number of queued packets reaches SG_MAX_QUEUE, if the
+state is off then POLLOUT is only set when no packets are queued.
+Note that a packet can be queued after write()ing but not available to be
+read(); this typically happens when a SCSI read command is issued while
+the data is being retreaved.
+Poll() is per file descriptor unless SG_SET_MERGE_FD is set in which case
+it is per device.
+
+
+fcntl
+-----
+There are several uses for this system call in association with a sg
+file descriptor. The first pseudo code shows code that is useful for
+scanning the sg devices, taking care not to be caught in a wait for
+an O_EXCL lock by another process, and when the appropriate device is
+found switching to normal blocked io. A working example of this logic
+is in the sg_scan.c utility program.
+
+open("/dev/sga", O_RDONLY | O_NONBLOCK)
+/* check device, EBUSY means some other process has O_EXCL lock on it */
+/* one the device you want is found then ... */
+flags = fcntl(sg_fd, F_GETFL)
+fcntl(sg_fd, F_SETFL, flags & (~ O_NONBLOCK))
+/* for simple apps is is easier to use normal blocked io */
+
+
+Some work has to be done in Linux to set up for asynchronous notification.
+This is a non-blocking mode of operation in which when the driver receives
+data back from a device so that a read() can be done, it sends a SIGPOLL
+(aka SIGIO) signal to the owning process. A working example of this logic
+is in the sg_poll.c test program.
+
+sigemptyset(&sig_set)
+sigaddset(&sig_set, SIGPOLL)
+sigaction(SIGPOLL, &s_action, 0)
+fcntl(sg_fd, F_SETOWN, getpid())
+flags = fcntl(sg_fd, F_GETFL);
+fcntl(sg_fd, F_SETFL, flags | O_ASYNC)
+
+
+Utility and Test Programs
+=========================
diff -u --recursive --new-file v2.2.6/linux/MAINTAINERS linux/MAINTAINERS
--- v2.2.6/linux/MAINTAINERS	Fri Apr 16 14:47:30 1999
+++ linux/MAINTAINERS	Sat Apr 24 18:23:38 1999
@@ -650,6 +650,11 @@
X W:	http://www.torque.net/sg
X S:	Maintained
X 
+SCSI GENERIC
+L:	linux...@vger.rutgers.edu
+M:	douglas...@rbcds.com
+S:	Maintained
+
X SCSI SUBSYSTEM
X L:	linux...@vger.rutgers.edu
X S:	Unmaintained
@@ -698,7 +703,7 @@
X P:	Jakub Jelinek
X M:	j...@sunsite.ms.mff.cuni.cz
X P:	Anton Blanchard
-M:	an...@jubilex.progsoc.uts.edu.au
+M:	an...@progsoc.uts.edu.au
X L:	sparc...@vger.rutgers.edu
X L:	ultra...@vger.rutgers.edu
X W:	http://ultra.linux.cz
@@ -771,6 +776,20 @@
X L:	linux-...@vger.rutgers.edu
X S:	Maintained
X 
+USB HUB AND UHCI DRIVERS
+P:	Johannes Erdfelt
+M:	jerd...@sventech.com
+L:	linu...@peloncho.fis.ucm.es
+S:	Maintained
+
+USB OHCI DRIVER
+P:	Gregory P. Smith
+M:	gr...@electricrain.com
+M:	gr...@suitenine.com
+L:	linu...@peloncho.fis.ucm.es
+S:	Maintained (not yet usable)
+W:	http://suitenine.com/usb/
+
X VFAT FILESYSTEM:
X P:	Gordon Chaffee
X M:	cha...@cs.berkeley.edu
@@ -784,9 +803,9 @@
X W:	http://roadrunner.swansea.linux.org.uk/v4l.shtml
X S:	Maintained
X 
-WAN ROUTER AND SANGOMA WANPIPE DRIVERS (X.25, FRAME RELAY, PPP)
-P:     Gene Kozin
-M:     ge...@compuserve.com
+WAN ROUTER & SANGOMA WANPIPE DRIVERS & API (X.25, FRAME RELAY, PPP, CISCO HDLC)
+P:     Jaspreet Singh
+M:     jasp...@sangoma.com
X M:     d...@sangoma.com
X W:     http://www.sangoma.com
X S:     Supported
diff -u --recursive --new-file v2.2.6/linux/Makefile linux/Makefile
--- v2.2.6/linux/Makefile	Fri Apr 16 14:47:30 1999
+++ linux/Makefile	Mon Apr 26 12:24:24 1999
@@ -1,6 +1,6 @@
X VERSION = 2
X PATCHLEVEL = 2
-SUBLEVEL = 6
+SUBLEVEL = 7
X EXTRAVERSION =
X 
X ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
@@ -175,7 +175,7 @@
X endif
X 
X ifeq ($(CONFIG_USB),y)
-DRIVERS := $(DRIVERS) drivers/uusbd/usb.a
+DRIVERS := $(DRIVERS) drivers/usb/usb.a
X endif
X 
X ifeq ($(CONFIG_I2O),y)
diff -u --recursive --new-file v2.2.6/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
--- v2.2.6/linux/arch/alpha/kernel/setup.c	Tue Jan 19 11:32:50 1999
+++ linux/arch/alpha/kernel/setup.c	Sat Apr 24 17:54:08 1999
@@ -183,6 +183,11 @@
X 			vec = get_sysvec_byname(p+9);
X 			continue;
X 		}
+
+		if (strncmp(p, "cycle=", 6) == 0) {
+			est_cycle_freq = simple_strtol(p+6, NULL, 0);
+			continue;
+		}
X 	}
X 
X 	/* Replace the command line, not that we've killed it with strtok.  */
@@ -721,8 +726,8 @@
X 		       (char*)cpu->serial_no,
X 		       systype_name, sysvariation_name, hwrpb->sys_revision,
X 		       (char*)hwrpb->ssn,
-		       hwrpb->cycle_freq ? : est_cycle_freq,
-		       hwrpb->cycle_freq ? "" : "est.",
+		       est_cycle_freq ? : hwrpb->cycle_freq,
+		       est_cycle_freq ? "est." : "",
X 		       hwrpb->intr_freq / 4096,
X 		       (100 * hwrpb->intr_freq / 4096) % 100,
X 		       hwrpb->pagesize,
diff -u --recursive --new-file v2.2.6/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c
--- v2.2.6/linux/arch/alpha/kernel/time.c	Tue Mar 23 14:35:46 1999
+++ linux/arch/alpha/kernel/time.c	Sat Apr 24 17:54:08 1999
@@ -18,6 +18,9 @@
X  *      fixed tick loss calculation in timer_interrupt
X  *      (round system clock to nearest tick instead of truncating)
X  *      fixed algorithm in time_init for getting time from CMOS clock
+ * 1999-04-16	Thorsten Kranzkowski (dl8...@gmx.net)
+ *	fixed algorithm in do_gettimeofday() for calculating the precise time
+ *	from processor cycle counter (now taking lost_ticks into account)
X  */
X #include <linux/config.h>
X #include <linux/errno.h>
@@ -223,7 +226,7 @@
X {
X 	void (*irq_handler)(int, void *, struct pt_regs *);
X 	unsigned int year, mon, day, hour, min, sec, cc1, cc2;
-	unsigned long cycle_freq;
+	unsigned long cycle_freq, diff, one_percent;
X 
X 	/*
X 	 * The Linux interpretation of the CMOS clock register contents:
@@ -237,19 +240,30 @@
X 	/* Read cycle counter exactly on falling edge of update flag */
X 	cc1 = rpcc();
X 
-	/* If our cycle frequency isn't valid, go another round and give
-	   a guess at what it should be.  */
-	cycle_freq = hwrpb->cycle_freq;
-	if (cycle_freq == 0) {
-		printk("HWRPB cycle frequency bogus.  Estimating... ");
-
+	if (!est_cycle_freq) {
+		/* Sometimes the hwrpb->cycle_freq value is bogus. 
+	   	Go another round to check up on it and see.  */
X 		do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
X 		do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
X 		cc2 = rpcc();
-		est_cycle_freq = cycle_freq = cc2 - cc1;
+		est_cycle_freq = cc2 - cc1;
X 		cc1 = cc2;
+	}
X 
-		printk("%lu Hz\n", cycle_freq);
+	/* If the given value is within 1% of what we calculated, 
+	   accept it.  Otherwise, use what we found.  */
+	cycle_freq = hwrpb->cycle_freq;
+	one_percent = cycle_freq / 100;
+	diff = cycle_freq - est_cycle_freq;
+	if (diff < 0)
+		diff = -diff;
+	if (diff > one_percent) {
+		cycle_freq = est_cycle_freq;
+		printk("HWRPB cycle frequency bogus.  Estimated %lu Hz\n",
+		       cycle_freq);
+	}
+	else {
+		est_cycle_freq = 0;
X 	}
X 
X 	/* From John Bowman <bow...@math.ualberta.ca>: allow the values
@@ -314,8 +328,10 @@
X void
X do_gettimeofday(struct timeval *tv)
X {
-	unsigned long flags, now, delta_cycles, delta_usec;
+	unsigned long flags, delta_cycles, delta_usec;
X 	unsigned long sec, usec;
+	__u32 now;
+	extern volatile unsigned long lost_ticks;	/*kernel/sched.c*/
X 
X 	now = rpcc();
X 	save_and_cli(flags);
@@ -337,8 +353,14 @@
X 	 * with no clear gain.
X 	 */
X 
-	delta_usec = delta_cycles * state.scaled_ticks_per_cycle * 15625;
+	delta_usec = (delta_cycles * state.scaled_ticks_per_cycle 
+			+ state.partial_tick
+			+ (lost_ticks << FIX_SHIFT) ) * 15625;
X 	delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2;
+
+	/* the 'lost_tics' term above implements this:	
+	 * delta_usec += lost_ticks * (1000000 / HZ);
+	 */
X 
X 	usec += delta_usec;
X 	if (usec >= 1000000) {
diff -u --recursive --new-file v2.2.6/linux/arch/alpha/lib/clear_user.S linux/arch/alpha/lib/clear_user.S
--- v2.2.6/linux/arch/alpha/lib/clear_user.S	Sun Nov 30 10:59:02 1997
+++ linux/arch/alpha/lib/clear_user.S	Sat Apr 24 17:54:08 1999
@@ -80,6 +80,7 @@
X 	ret	$31, ($28), 1	# .. e1 :
X 
X __do_clear_user:
+	ldgp	$29,0($27)	# we do exceptions -- we need the gp.
X 	and	$6, 7, $4	# e0    : find dest misalignment
X 	beq	$0, $zerolength # .. e1 :
X 	addq	$0, $4, $1	# e0    : bias counter
diff -u --recursive --new-file v2.2.6/linux/arch/alpha/lib/copy_user.S linux/arch/alpha/lib/copy_user.S
--- v2.2.6/linux/arch/alpha/lib/copy_user.S	Sat May  2 14:19:52 1998
+++ linux/arch/alpha/lib/copy_user.S	Sat Apr 24 17:54:08 1999
@@ -46,6 +46,8 @@
X 	.globl __copy_user
X 	.ent __copy_user
X __copy_user:
+	ldgp $29,0($27)			# we do exceptions -- we need the gp.
+	.prologue 1
X 	and $6,7,$3
X 	beq $0,$35
X 	beq $3,$36
diff -u --recursive --new-file v2.2.6/linux/arch/alpha/lib/strlen_user.S linux/arch/alpha/lib/strlen_user.S
--- v2.2.6/linux/arch/alpha/lib/strlen_user.S	Wed Jun 24 22:54:03 1998
+++ linux/arch/alpha/lib/strlen_user.S	Sat Apr 24 17:54:08 1999
@@ -27,7 +27,8 @@
X 
X 	.align 3
X __strlen_user:
-	.prologue 0
+	ldgp	$29,0($27)	# we do exceptions -- we need the gp.
+	.prologue 1
X 
X 	EX( ldq_u t0, 0(a0) )	# load first quadword (a0 may be misaligned)
X 	lda     t1, -1(zero)
diff -u --recursive --new-file v2.2.6/linux/arch/alpha/lib/strncpy_from_user.S linux/arch/alpha/lib/strncpy_from_user.S
--- v2.2.6/linux/arch/alpha/lib/strncpy_from_user.S	Thu Feb  6 04:48:45 1997
+++ linux/arch/alpha/lib/strncpy_from_user.S	Sat Apr 24 17:54:08 1999
@@ -31,6 +31,7 @@
X 	.globl __strncpy_from_user
X 	.ent __strncpy_from_user
X 	.frame $30, 0, $26
+	.prologue 1
X 
X 	.align 3
X $aligned:
@@ -99,6 +100,7 @@
X 	/*** The Function Entry Point ***/
X 	.align 3
X __strncpy_from_user:
+	ldgp	$29, 0($27)	# we do exceptions -- we need the gp.
X 
X 	mov	a0, v0		# save the string start
X 	beq	a2, $zerolength
diff -u --recursive --new-file v2.2.6/linux/arch/i386/config.in linux/arch/i386/config.in
--- v2.2.6/linux/arch/i386/config.in	Tue Feb 23 15:21:32 1999
+++ linux/arch/i386/config.in	Mon Apr 26 13:49:17 1999
@@ -168,6 +168,8 @@
X 
X source drivers/char/Config.in
X 
+# source drivers/usb/Config.in
+
X source fs/Config.in
X 
X if [ "$CONFIG_VT" = "y" ]; then
diff -u --recursive --new-file v2.2.6/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c
--- v2.2.6/linux/arch/i386/kernel/bios32.c	Tue Mar 23 14:35:46 1999
+++ linux/arch/i386/kernel/bios32.c	Sat Apr 24 17:49:37 1999
@@ -1095,6 +1095,8 @@
X  * for buggy PCI BIOS'es :-[).
X  */
X 
+extern int skip_ioapic_setup;
+
X static void __init pcibios_fixup_devices(void)
X {
X 	struct pci_dev *dev;
@@ -1147,6 +1149,7 @@
X 		/*
X 		 * Recalculate IRQ numbers if we use the I/O APIC
X 		 */
+		if(!skip_ioapic_setup)
X 		{
X 			int irq;
X 			unsigned char pin;
diff -u --recursive --new-file v2.2.6/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.2.6/linux/arch/i386/kernel/smp.c	Fri Apr 16 14:47:30 1999
+++ linux/arch/i386/kernel/smp.c	Thu Apr 22 19:24:50 1999
@@ -29,6 +29,7 @@
X  *					from Jose Renau
X  *		Alan Cox	:	Added EBDA scanning
X  *		Ingo Molnar	:	various cleanups and rewrites
+ *		Tigran Aivazian	:	fixed "0.00 in /proc/uptime on SMP" bug.
X  */
X 
X #include <linux/config.h>
@@ -1707,9 +1708,8 @@
X 			system=1;
X 
X  		irq_enter(cpu, 0);
+		update_one_process(p, 1, user, system, cpu);
X 		if (p->pid) {
-			update_one_process(p, 1, user, system, cpu);
-
X 			p->counter -= 1;
X 			if (p->counter < 0) {
X 				p->counter = 0;
@@ -1722,7 +1722,6 @@
X 				kstat.cpu_user += user;
X 				kstat.per_cpu_user[cpu] += user;
X 			}
-
X 			kstat.cpu_system += system;
X 			kstat.per_cpu_system[cpu] += system;
X 
diff -u --recursive --new-file v2.2.6/linux/arch/m68k/atari/atakeyb.c linux/arch/m68k/atari/atakeyb.c
--- v2.2.6/linux/arch/m68k/atari/atakeyb.c	Wed Jan 20 23:14:04 1999
+++ linux/arch/m68k/atari/atakeyb.c	Mon Apr 26 13:35:34 1999
@@ -291,7 +291,7 @@
X 		atakeyb_rep_timer.prev = atakeyb_rep_timer.next = NULL;
X 		add_timer( &atakeyb_rep_timer );
X 
-		handle_scancode(rep_scancode);
+		handle_scancode(rep_scancode, 1);
X 	}
X 
X 	atari_enable_irq( IRQ_MFP_ACIA );
@@ -448,7 +448,7 @@
X 		    add_timer( &atakeyb_rep_timer );
X 		}
X 
-		handle_scancode(break_flag | scancode);
+		handle_scancode(scancode, !break_flag);
X 		break;
X 	    }
X 	    break;
diff -u --recursive --new-file v2.2.6/linux/arch/m68k/hp300/hil.c linux/arch/m68k/hp300/hil.c
--- v2.2.6/linux/arch/m68k/hp300/hil.c	Sat Sep  5 16:46:40 1998
+++ linux/arch/m68k/hp300/hil.c	Mon Apr 26 13:37:14 1999
@@ -223,12 +223,13 @@
X   {
X   case 0x40:
X     {
-      unsigned char scode = (poll.data[1] >> 1) | ((poll.data[1] & 1)?0x80:0);
+      int down = (poll.data[1] & 1) == 0;
+      unsigned char scode = poll.data[1] >> 1;
X #if 0
-      if (scode & 0x80)
-	printk("[%02x]", scode & 0x7f);
+      if (down)
+	printk("[%02x]", scode);
X #endif
-      handle_scancode(scode);
+      handle_scancode(scode, down);
X     }
X     break;
X   }
diff -u --recursive --new-file v2.2.6/linux/arch/m68k/mac/mackeyb.c linux/arch/m68k/mac/mackeyb.c
--- v2.2.6/linux/arch/m68k/mac/mackeyb.c	Wed Jan 20 23:14:04 1999
+++ linux/arch/m68k/mac/mackeyb.c	Mon Apr 26 13:38:03 1999
@@ -60,7 +60,7 @@
X extern struct kbd_struct kbd_table[];
X 
X extern void adb_bus_init(void);
-extern void handle_scancode(unsigned char);
+extern void handle_scancode(unsigned char, int);
X extern void put_queue(int);
X 
X /* keyb */
@@ -387,7 +387,7 @@
X 		 */
X 		switch (keycode) {
X 		case 0x39:
-			handle_scancode(keycode);	/* down */
+			handle_scancode(keycode, 1);	/* down */
X 			up_flag = 0x80;			/* see below ... */
X 		 	mark_bh(KEYBOARD_BH);
X 			break;
@@ -397,7 +397,7 @@
X 		}
X 	}
X 
-	handle_scancode(keycode + up_flag);
+	handle_scancode(keycode, !up_flag);
X }
X 
X static void
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/defconfig linux/arch/sparc/defconfig
--- v2.2.6/linux/arch/sparc/defconfig	Tue Mar 23 14:35:46 1999
+++ linux/arch/sparc/defconfig	Thu Apr 22 19:24:51 1999
@@ -261,6 +261,8 @@
X # CONFIG_NCPFS_NFS_NS is not set
X # CONFIG_NCPFS_OS2_NS is not set
X # CONFIG_NCPFS_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
X 
X #
X # Partition Types
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S
--- v2.2.6/linux/arch/sparc/kernel/entry.S	Tue Mar 23 14:35:46 1999
+++ linux/arch/sparc/kernel/entry.S	Wed Apr 28 08:47:39 1999
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.157 1999/01/19 07:54:32 davem Exp $
+/* $Id: entry.S,v 1.158 1999/04/27 14:35:07 davem Exp $
X  * arch/sparc/kernel/entry.S:  Sparc trap low-level entry points.
X  *
X  * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -874,7 +874,7 @@
X ! We want error in %l5, vaddr in %l6
X sun4c_fault:
X #ifdef CONFIG_SUN4
-	sethi	C_LABEL(sun4c_memerr_reg), %l4
+	sethi	%hi(C_LABEL(sun4c_memerr_reg)), %l4
X 	ld	[%l4+%lo(C_LABEL(sun4c_memerr_reg))], %l4  ! memerr ctrl reg addr
X 	ld	[%l4], %l6		! memerr ctrl reg
X 	ld	[%l4 + 4], %l5		! memerr vaddr reg
@@ -956,7 +956,7 @@
X 	sll     %l6, 2, %l6
X 	ld      [%l4 + %l6], %l4
X #ifdef CONFIG_SUN4
-	sethi	PAGE_MASK, %l6
+	sethi	%hi(PAGE_MASK), %l6
X 	andcc	%l4, %l6, %g0
X #else
X 	andcc   %l4, PAGE_MASK, %g0
@@ -1117,7 +1117,7 @@
X #ifndef CONFIG_SUN4
X 	and	%l4, PAGE_MASK, %l4
X #else
-	sethi	PAGE_MASK, %l6
+	sethi	%hi(PAGE_MASK), %l6
X 	and	%l4, %l6, %l4
X #endif
X 
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/kernel/head.S linux/arch/sparc/kernel/head.S
--- v2.2.6/linux/arch/sparc/kernel/head.S	Tue Mar 23 14:35:46 1999
+++ linux/arch/sparc/kernel/head.S	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.93 1999/01/10 06:03:14 jj Exp $
+/* $Id: head.S,v 1.95 1999/04/13 07:40:34 anton Exp $
X  * head.S: The initial boot code for the Sparc port of Linux.
X  *
X  * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -408,13 +408,11 @@
X /* This was the only reasonable way I could think of to properly align
X  * these page-table data structures.
X  */
-	.globl C_LABEL(bootup_user_stack)
X 	.globl C_LABEL(pg0), C_LABEL(pg1), C_LABEL(pg2), C_LABEL(pg3)
X 	.globl C_LABEL(empty_bad_page)
X 	.globl C_LABEL(empty_bad_page_table)
X 	.globl C_LABEL(empty_zero_page)
X 	.globl C_LABEL(swapper_pg_dir)
-C_LABEL(bootup_user_stack):		.skip 0x2000
X C_LABEL(swapper_pg_dir):		.skip PAGE_SIZE
X C_LABEL(pg0):				.skip PAGE_SIZE
X C_LABEL(pg1):				.skip PAGE_SIZE
@@ -427,8 +425,8 @@
X 	.global C_LABEL(root_flags)
X 	.global C_LABEL(ram_flags)
X 	.global C_LABEL(root_dev)
-	.global C_LABEL(ramdisk_image)
-	.global C_LABEL(ramdisk_size)
+	.global C_LABEL(sparc_ramdisk_image)
+	.global C_LABEL(sparc_ramdisk_size)
X 
X /* This stuff has to be in sync with SILO and other potential boot loaders
X  * Fields should be kept upward compatible and whenever any change is made,
@@ -443,9 +441,9 @@
X 	.half	0
X C_LABEL(ram_flags):
X 	.half	0
-C_LABEL(ramdisk_image):
+C_LABEL(sparc_ramdisk_image):
X 	.word	0
-C_LABEL(ramdisk_size):
+C_LABEL(sparc_ramdisk_size):
X 	.word	0
X 	.word	C_LABEL(reboot_command)
X 
@@ -1005,8 +1003,8 @@
X 		WRITE_PAUSE
X 
X 		/* I want a kernel stack NOW! */
-		set	C_LABEL(bootup_user_stack), %g1
-		set	(0x2000 - REGWIN_SZ), %g2
+		set	C_LABEL(init_task_union), %g1
+		set	(TASK_UNION_SIZE - REGWIN_SZ), %g2
X 		add	%g1, %g2, %sp
X 		mov	0, %fp			/* And for good luck */
X 
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/kernel/irq.c linux/arch/sparc/kernel/irq.c
--- v2.2.6/linux/arch/sparc/kernel/irq.c	Sun Nov  8 14:02:45 1998
+++ linux/arch/sparc/kernel/irq.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/*  $Id: irq.c,v 1.91 1998/10/14 07:04:17 jj Exp $
+/*  $Id: irq.c,v 1.93 1999/04/21 06:15:45 anton Exp $
X  *  arch/sparc/kernel/irq.c:  Interrupt request handling routines. On the
X  *                            Sparc the IRQ's are basically 'cast in stone'
X  *                            and you are supposed to probe the prom's device
@@ -8,7 +8,7 @@
X  *  Copyright (C) 1995 Miguel de Icaza (mig...@nuclecu.unam.mx)
X  *  Copyright (C) 1995 Pete A. Zaitcev (zai...@metabyte.com)
X  *  Copyright (C) 1996 Dave Redman (dj...@tadpole.co.uk)
- *  Copyright (C) 1998 Anton Blanchard (an...@progsoc.uts.edu.au)
+ *  Copyright (C) 1998-99 Anton Blanchard (an...@progsoc.uts.edu.au)
X  */
X 
X #include <linux/config.h>
@@ -24,6 +24,8 @@
X #include <linux/init.h>
X #include <linux/smp.h>
X #include <linux/smp_lock.h>
+#include <linux/delay.h>
+#include <linux/tasks.h>
X 
X #include <asm/ptrace.h>
X #include <asm/processor.h>
@@ -192,12 +194,18 @@
X         restore_flags(flags);
X }
X 
-/* Per-processor IRQ and bh locking depth, both SMP and non-SMP code use this. */
+#ifndef __SMP__
+unsigned int local_bh_count;
+unsigned int local_irq_count;
+
+#else
+/* SMP interrupt locking on Sparc. */
+
X unsigned int local_bh_count[NR_CPUS];
X unsigned int local_irq_count[NR_CPUS];
X 
-#ifdef __SMP__
-/* SMP interrupt locking on Sparc. */
+atomic_t global_bh_lock = ATOMIC_INIT(0);
+spinlock_t global_bh_count = SPIN_LOCK_UNLOCKED;
X 
X /* Who has global_irq_lock. */
X unsigned char global_irq_holder = NO_PROC_ID;
@@ -208,58 +216,71 @@
X /* Global IRQ locking depth. */
X atomic_t global_irq_count = ATOMIC_INIT(0);
X 
-atomic_t global_bh_count = ATOMIC_INIT(0);
-atomic_t global_bh_lock = ATOMIC_INIT(0);
-
X /* This protects BH software state (masks, things like that). */
X spinlock_t sparc_bh_lock = SPIN_LOCK_UNLOCKED;
X 
-#ifdef DEBUG_IRQLOCK
+void smp_show_backtrace_all_cpus(void);
+void show_backtrace(void);
X 
-#undef INIT_STUCK
-#define INIT_STUCK 100000000
+#define MAXCOUNT 100000000
+#define VERBOSE_DEBUG_IRQLOCK
X 
-#undef STUCK
-#define STUCK \
-if (!--stuck) {printk("wait_on_bh CPU#%d stuck at %08lx\n", cpu, where); stuck = INIT_STUCK; }
-
-static inline void wait_on_bh(int cpu, unsigned long where)
+static void show(char * str)
X {
-	int stuck = INIT_STUCK;
-	do {
-		STUCK;
-		/* nothing .. wait for the other bh's to go away */
-	} while (atomic_read(&global_bh_count) != 0);
-}
+	int i;
+	int cpu = smp_processor_id();
+
+	printk("\n%s, CPU %d:\n", str, cpu);
+	printk("irq:  %d [ ", atomic_read(&global_irq_count));
X 
-static unsigned long previous_irqholder;
+	for (i = 0; i < NR_CPUS; i++) {
+		printk("%d ", local_irq_count[i]);
+	}
+	printk("]\n");
X 
-#undef INIT_STUCK
-#define INIT_STUCK 100000000
+	printk("bh:   %d [ ", (spin_is_locked(&global_bh_count) ? 1 : 0));
X 
-#undef STUCK
-#define STUCK \
-if (!--stuck) {printk("wait_on_irq CPU#%d stuck at %08lx, waiting for %08lx (local=%d, global=%d)\n", cpu, where, previous_irqholder, local_count, atomic_read(&global_irq_count)); stuck = INIT_STUCK; }
+	for (i = 0; i < NR_CPUS; i++) {
+		printk("%d ", local_bh_count[cpu]);
+	}
+	printk("]\n");
+
+#ifdef VERBOSE_DEBUG_IRQLOCK
+	smp_show_backtrace_all_cpus();
+#else
+	show_backtrace();
+#endif
+}
+
+static inline void wait_on_bh(void)
+{
+	int count = MAXCOUNT;
+	do {
+		if(!--count) {
+			show("wait_on_bh");
+			count = 0;
+		}
+		barrier();
+	} while(spin_is_locked(&global_bh_count));
+}
X 
X /*
X  * We have to allow irqs to arrive between __sti and __cli
X  */
-#define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
+#define SYNC_OTHER_CORES(x) udelay(x+1)
X 
-static inline void wait_on_irq(int cpu, unsigned long where)
+static inline void wait_on_irq(int cpu)
X {
-	int stuck = INIT_STUCK;
-	int local_count = local_irq_count[cpu];
+	int count = MAXCOUNT;
X 
X 	for (;;) {
-
X 		/*
X 		 * Wait until all interrupts are gone. Wait
X 		 * for bottom half handlers unless we're
X 		 * already executing in one..
X 		 */
X 		if (!atomic_read(&global_irq_count)) {
-			if (local_bh_count[cpu] || !atomic_read(&global_bh_count))
+			if (local_bh_count[cpu] || !spin_is_locked(&global_bh_count))
X 				break;
X 		}
X 
@@ -267,17 +288,18 @@
X 		spin_unlock(&global_irq_lock);
X 
X 		for (;;) {
-			STUCK;
-
+			if (!--count) {
+				show("wait_on_irq");
+				count = ~0;
+			}
X 			__sti();
X 			SYNC_OTHER_CORES(cpu);
X 			__cli();
-
X 			if (atomic_read(&global_irq_count))
X 				continue;
-			if (*((unsigned char *)&global_irq_lock))
+			if (spin_is_locked (&global_irq_lock))
X 				continue;
-			if (!local_bh_count[cpu] && atomic_read(&global_bh_count))
+			if (!local_bh_count[cpu] && spin_is_locked(&global_bh_count))
X 				continue;
X 			if (spin_trylock(&global_irq_lock))
X 				break;
@@ -295,14 +317,8 @@
X  */
X void synchronize_bh(void)
X {
-	unsigned long where;
-
-	__asm__("mov %%i7, %0" : "=r" (where));
-
-	if (atomic_read(&global_bh_count) && !in_interrupt()) {
-		int cpu = smp_processor_id();
-		wait_on_bh(cpu, where);
-	}
+        if (spin_is_locked (&global_bh_count) && !in_interrupt())
+                wait_on_bh();
X }
X 
X /*
@@ -321,16 +337,9 @@
X 	}
X }
X 
-#undef INIT_STUCK
-#define INIT_STUCK 10000000
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 01'
echo 'File patch-2.2.7 is continued in part 02'
echo 02 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 02 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 02; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
-
-#undef STUCK
-#define STUCK \
-if (!--stuck) {printk("get_irqlock stuck at %08lx, waiting for %08lx\n", where, previous_irqholder); stuck = INIT_STUCK;}
-
-static inline void get_irqlock(int cpu, unsigned long where)
+static inline void get_irqlock(int cpu)
X {
-	int stuck = INIT_STUCK;
+	int count = MAXCOUNT;
X 
X 	if (!spin_trylock(&global_irq_lock)) {
X 		/* do we already hold the lock? */
@@ -338,23 +347,25 @@
X 			return;
X 		/* Uhhuh.. Somebody else got it. Wait.. */
X 		do {
-			do {
-				STUCK;
+			while (spin_is_locked(&global_irq_lock)) {
+				if (!--count) {
+					show("get_irqlock");
+					count = ~0;
+				}
X 				barrier();
-			} while (*((volatile unsigned char *)&global_irq_lock));
+			}
X 		} while (!spin_trylock(&global_irq_lock));
X 	}
X 	/* 
X 	 * We also to make sure that nobody else is running
X 	 * in an interrupt context. 
X 	 */
-	wait_on_irq(cpu, where);
+	wait_on_irq(cpu);
X 
X 	/*
X 	 * Ok, finally..
X 	 */
X 	global_irq_holder = cpu;
-	previous_irqholder = where;
X }
X 
X /*
@@ -372,9 +383,6 @@
X void __global_cli(void)
X {
X 	unsigned int flags;
-	unsigned long where;
-
-	__asm__("mov %%i7, %0" : "=r" (where));
X 
X 	__save_flags(flags);
X 
@@ -382,7 +390,7 @@
X 		int cpu = smp_processor_id();
X 		__cli();
X 		if (!local_irq_count[cpu])
-			get_irqlock(cpu, where);
+			get_irqlock(cpu);
X 	}
X }
X 
@@ -442,65 +450,14 @@
X 		__sti();
X 		break;
X 	default:
-		printk("global_restore_flags: %08lx (%08lx)\n",
-			flags, (&flags)[-1]);
+	{
+		unsigned long pc;
+		__asm__ __volatile__("mov %%i7, %0" : "=r" (pc));
+		printk("global_restore_flags: Bogon flags(%08lx) caller %08lx\n", flags, pc);
X 	}
-}
-
-#undef INIT_STUCK
-#define INIT_STUCK 200000000
-
-#undef STUCK
-#define STUCK \
-if (!--stuck) {printk("irq_enter stuck (irq=%d, cpu=%d, global=%d)\n",irq,cpu,global_irq_holder); stuck = INIT_STUCK;}
-
-#define VERBOSE_IRQLOCK_DEBUGGING
-
-void irq_enter(int cpu, int irq, void *_opaque)
-{
-#ifdef VERBOSE_IRQLOCK_DEBUGGING
-	extern void smp_show_backtrace_all_cpus(void);
-#endif
-	int stuck = INIT_STUCK;
-
-	hardirq_enter(cpu);
-	barrier();
-	while (*((volatile unsigned char *)&global_irq_lock)) {
-		if ((unsigned char) cpu == global_irq_holder) {
-			struct pt_regs *regs = _opaque;
-			int sbh_cnt = atomic_read(&global_bh_count);
-			int globl_locked = *((unsigned char *)&global_irq_lock);
-			int globl_icount = atomic_read(&global_irq_count);
-			int local_count = local_irq_count[cpu];
-			unsigned long pc = regs->pc;
-
-			/* It is very important that we load the state variables
-			 * before we do the first call to printk() as printk()
-			 * could end up changing them...
-			 */
-
-			printk("CPU[%d]: BAD! Local IRQ's enabled, global disabled "
-			       "interrupt at PC[%08lx]\n", cpu, pc);
-			printk("CPU[%d]: bhcnt[%d] glocked[%d] gicnt[%d] licnt[%d]\n",
-			       cpu, sbh_cnt, globl_locked, globl_icount, local_count);
-#ifdef VERBOSE_IRQLOCK_DEBUGGING
-			printk("Performing backtrace on all cpus, write this down!\n");
-			smp_show_backtrace_all_cpus();
-#endif
-			break;
-		}
-		STUCK;
-		barrier();
X 	}
X }
X 
-void irq_exit(int cpu, int irq)
-{
-	hardirq_exit(cpu);
-	release_irqlock(cpu);
-}
-
-#endif /* DEBUG_IRQLOCK */
X #endif /* __SMP__ */
X 
X void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs)
@@ -542,7 +499,7 @@
X 		smp4m_irq_rotate(cpu);
X #endif
X #endif
-	irq_enter(cpu, irq, regs);
+	irq_enter(cpu, irq);
X 	action = *(irq + irq_action);
X 	kstat.irqs[cpu][irq]++;
X 	do {
@@ -563,7 +520,7 @@
X 	int cpu = smp_processor_id();
X 
X 	disable_pil_irq(irq);
-	irq_enter(cpu, irq, regs);
+	irq_enter(cpu, irq);
X 	kstat.irqs[cpu][irq]++;
X 	floppy_interrupt(irq, dev_id, regs);
X 	irq_exit(cpu, irq);
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c
--- v2.2.6/linux/arch/sparc/kernel/process.c	Mon Mar 29 11:09:11 1999
+++ linux/arch/sparc/kernel/process.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/*  $Id: process.c,v 1.133 1999/03/24 11:42:30 davem Exp $
+/*  $Id: process.c,v 1.136 1999/04/16 01:20:33 anton Exp $
X  *  linux/arch/sparc/kernel/process.c
X  *
X  *  Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -205,8 +205,10 @@
X 	int cpu = smp_processor_id();
X 
X 	spin_lock_irqsave(&sparc_backtrace_lock, flags);
-	rw = (struct reg_window *) fp;
-	while(rw) {
+
+	rw = (struct reg_window *)fp;
+        while(rw && (((unsigned long) rw) >= PAGE_OFFSET) &&
+            !(((unsigned long) rw) & 0x7)) {
X 		printk("CPU[%d]: ARGS[%08lx,%08lx,%08lx,%08lx,%08lx,%08lx] "
X 		       "FP[%08lx] CALLER[%08lx]\n", cpu,
X 		       rw->ins[0], rw->ins[1], rw->ins[2], rw->ins[3],
@@ -218,28 +220,21 @@
X 	spin_unlock_irqrestore(&sparc_backtrace_lock, flags);
X }
X 
+#define __SAVE __asm__ __volatile__("save %sp, -0x40, %sp\n\t")
+#define __RESTORE __asm__ __volatile__("restore %g0, %g0, %g0\n\t")
+#define __GET_FP(fp) __asm__ __volatile__("mov %%i6, %0" : "=r" (fp))
+
X void show_backtrace(void)
X {
X 	unsigned long fp;
X 
-	__asm__ __volatile__(
-		"save %%sp, -64, %%sp\n\t"
-		"save %%sp, -64, %%sp\n\t"
-		"save %%sp, -64, %%sp\n\t"
-		"save %%sp, -64, %%sp\n\t"
-		"save %%sp, -64, %%sp\n\t"
-		"save %%sp, -64, %%sp\n\t"
-		"save %%sp, -64, %%sp\n\t"
-		"save %%sp, -64, %%sp\n\t"
-		"restore\n\t"
-		"restore\n\t"
-		"restore\n\t"
-		"restore\n\t"
-		"restore\n\t"
-		"restore\n\t"
-		"restore\n\t"
-		"restore\n\t"
-		"mov %%i6, %0" : "=r" (fp));
+	__SAVE; __SAVE; __SAVE; __SAVE;
+	__SAVE; __SAVE; __SAVE; __SAVE;
+	__RESTORE; __RESTORE; __RESTORE; __RESTORE;
+	__RESTORE; __RESTORE; __RESTORE; __RESTORE;
+
+	__GET_FP(fp);
+
X 	__show_backtrace(fp);
X }
X 
@@ -381,8 +376,21 @@
X 	current->tss.current_ds = USER_DS;
X 	if (current->tss.flags & SPARC_FLAG_KTHREAD) {
X 		current->tss.flags &= ~SPARC_FLAG_KTHREAD;
-		switch_to_context(current);
+
+		/* We must fixup kregs as well. */
+		current->tss.kregs = (struct pt_regs *)
+			(((unsigned long)current) +
+			 (TASK_UNION_SIZE - TRACEREG_SZ));
X 	}
+
+	/* Exec'ing out of a vfork() shared address space is
+	 * tricky on sparc32.  exec_mmap will not set the mmu
+	 * context because it sets the new current->mm after
+	 * calling init_new_context and activate_context is
+	 * a nop on sparc32, so we gotta catch it here.  And
+	 * clone()'s had the same problem.  -DaveM
+	 */
+	switch_to_context(current);
X }
X 
X static __inline__ void copy_regs(struct pt_regs *dst, struct pt_regs *src)
@@ -514,9 +522,11 @@
X 	p->tss.kpsr = current->tss.fork_kpsr;
X #endif
X 	p->tss.kwim = current->tss.fork_kwim;
-	p->tss.kregs = childregs;
X 
X 	if(regs->psr & PSR_PS) {
+		extern struct pt_regs fake_swapper_regs;
+
+		p->tss.kregs = &fake_swapper_regs;
X 		new_stack = (struct reg_window *)
X 			((((unsigned long)p) +
X 			  (TASK_UNION_SIZE)) -
@@ -529,6 +539,7 @@
X 		       sizeof(struct reg_window));
X 		childregs->u_regs[UREG_G6] = (unsigned long) p;
X 	} else {
+		p->tss.kregs = childregs;
X 		childregs->u_regs[UREG_FP] = sp;
X 		p->tss.flags &= ~SPARC_FLAG_KTHREAD;
X 		p->tss.current_ds = USER_DS;
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/kernel/setup.c linux/arch/sparc/kernel/setup.c
--- v2.2.6/linux/arch/sparc/kernel/setup.c	Mon Oct  5 13:13:37 1998
+++ linux/arch/sparc/kernel/setup.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.103 1998/09/21 05:05:23 jj Exp $
+/*  $Id: setup.c,v 1.105 1999/04/13 14:17:08 jj Exp $
X  *  linux/arch/sparc/kernel/setup.c
X  *
X  *  Copyright (C) 1995  David S. Miller (da...@caip.rutgers.edu)
@@ -271,8 +271,8 @@
X extern unsigned short root_flags;
X extern unsigned short root_dev;
X extern unsigned short ram_flags;
-extern unsigned ramdisk_image;
-extern unsigned ramdisk_size;
+extern unsigned sparc_ramdisk_image;
+extern unsigned sparc_ramdisk_size;
X #define RAMDISK_IMAGE_START_MASK	0x07FF
X #define RAMDISK_PROMPT_FLAG		0x8000
X #define RAMDISK_LOAD_FLAG		0x4000
@@ -285,7 +285,7 @@
X 
X struct tt_entry *sparc_ttable;
X 
-static struct pt_regs fake_swapper_regs = { 0, 0, 0, 0, { 0, } };
+struct pt_regs fake_swapper_regs = { 0, 0, 0, 0, { 0, } };
X 
X static void prom_cons_write(struct console *con, const char *str, unsigned count)
X {
@@ -375,7 +375,7 @@
X 		sun4c_probe_vac();
X 	load_mmu();
X 	total = prom_probe_memory();
-	*memory_start_p = (((unsigned long) &end));
+	*memory_start_p = PAGE_ALIGN(((unsigned long) &end));
X 
X 	if(!packed) {
X 		for(i=0; sp_banks[i].num_bytes != 0; i++) {
@@ -404,10 +404,10 @@
X 	rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0);	
X #endif
X #ifdef CONFIG_BLK_DEV_INITRD
-	if (ramdisk_image) {
-		initrd_start = ramdisk_image;
+	if (sparc_ramdisk_image) {
+		initrd_start = sparc_ramdisk_image;
X 		if (initrd_start < KERNBASE) initrd_start += KERNBASE;
-		initrd_end = initrd_start + ramdisk_size;
+		initrd_end = initrd_start + sparc_ramdisk_size;
X 		if (initrd_end > *memory_end_p) {
X 			printk(KERN_CRIT "initrd extends beyond end of memory "
X 		                 	 "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
@@ -417,6 +417,14 @@
X 		if (initrd_start >= *memory_start_p && initrd_start < *memory_start_p + 2 * PAGE_SIZE) {
X 			initrd_below_start_ok = 1;
X 			*memory_start_p = PAGE_ALIGN (initrd_end);
+		} else if (initrd_start && sparc_ramdisk_image < KERNBASE) {
+			switch (sparc_cpu_model) {
+			case sun4m:
+			case sun4d:
+				initrd_start -= KERNBASE;
+				initrd_end -= KERNBASE;
+				break;
+			}
X 		}
X 	}
X #endif	
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/kernel/sun4d_irq.c linux/arch/sparc/kernel/sun4d_irq.c
--- v2.2.6/linux/arch/sparc/kernel/sun4d_irq.c	Sun Nov  8 14:02:45 1998
+++ linux/arch/sparc/kernel/sun4d_irq.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/*  $Id: sun4d_irq.c,v 1.17 1998/10/18 03:31:03 davem Exp $
+/*  $Id: sun4d_irq.c,v 1.18 1999/04/20 13:22:30 anton Exp $
X  *  arch/sparc/kernel/sun4d_irq.c:
X  *			SS1000/SC2000 interrupt handling.
X  *
@@ -193,7 +193,7 @@
X 	
X 	cc_set_iclr(1 << irq);
X 	
-	irq_enter(cpu, irq, regs);
+	irq_enter(cpu, irq);
X 	kstat.irqs[cpu][irq]++;
X 	if (!sbusl) {
X 		action = *(irq + irq_action);
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/kernel/sun4m_irq.c linux/arch/sparc/kernel/sun4m_irq.c
--- v2.2.6/linux/arch/sparc/kernel/sun4m_irq.c	Mon Oct  5 13:13:37 1998
+++ linux/arch/sparc/kernel/sun4m_irq.c	Thu Apr 22 19:24:51 1999
@@ -253,7 +253,7 @@
X     
X 	/* Map the per-cpu Counter registers. */
X 	sun4m_timers = sparc_alloc_io(cnt_regs[0].phys_addr, 0,
-				      PAGE_SIZE*NCPUS, "counters_percpu",
+				      PAGE_SIZE*SUN4M_NCPUS, "counters_percpu",
X 				      cnt_regs[0].which_io, 0x0);
X     
X 	/* Map the system Counter register. */
@@ -334,7 +334,7 @@
X 
X 	/* Map the interrupt registers for all possible cpus. */
X 	sun4m_interrupts = sparc_alloc_io(int_regs[0].phys_addr, 0,
-					  PAGE_SIZE*NCPUS, "interrupts_percpu",
+					  PAGE_SIZE*SUN4M_NCPUS, "interrupts_percpu",
X 					  int_regs[0].which_io, 0x0);
X     
X 	/* Map the system interrupt control registers. */
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/kernel/sun4m_smp.c linux/arch/sparc/kernel/sun4m_smp.c
--- v2.2.6/linux/arch/sparc/kernel/sun4m_smp.c	Thu Nov 19 09:56:27 1998
+++ linux/arch/sparc/kernel/sun4m_smp.c	Thu Apr 22 19:24:51 1999
@@ -448,6 +448,7 @@
X 	if(!--prof_counter[cpu]) {
X 		int user = user_mode(regs);
X 
+		irq_enter(cpu, 0);
X 		if(current->pid) {
X 			update_one_process(current, 1, user, !user, cpu);
X 
@@ -456,7 +457,6 @@
X 				current->need_resched = 1;
X 			}
X 
-			spin_lock(&ticker_lock);
X 			if(user) {
X 				if(current->priority < DEF_PRIORITY) {
X 					kstat.cpu_nice++;
@@ -469,9 +469,9 @@
X 				kstat.cpu_system++;
X 				kstat.per_cpu_system[cpu]++;
X 			}
-			spin_unlock(&ticker_lock);
X 		}
X 		prof_counter[cpu] = prof_multiplier[cpu];
+		irq_exit(cpu, 0);
X 	}
X }
X 
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/kernel/systbls.S linux/arch/sparc/kernel/systbls.S
--- v2.2.6/linux/arch/sparc/kernel/systbls.S	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc/kernel/systbls.S	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.82 1999/03/20 22:01:59 davem Exp $
+/* $Id: systbls.S,v 1.83 1999/04/07 17:14:06 davem Exp $
X  * systbls.S: System call entry point tables for OS compatibility.
X  *            The native Linux system call table lives here also.
X  *
@@ -25,7 +25,7 @@
X /*30*/	.long sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice
X /*35*/	.long sys_nis_syscall, sys_sync, sys_kill, sys_newstat, sys_sendfile
X /*40*/	.long sys_newlstat, sys_dup, sys_pipe, sys_times, sys_nis_syscall
-/*45*/	.long sys_nis_syscall, sys_setgid, sys_getgid, sys_signal, sys_geteuid
+/*45*/	.long sys_umount, sys_setgid, sys_getgid, sys_signal, sys_geteuid
X /*50*/	.long sys_getegid, sys_acct, sys_nis_syscall, sys_nis_syscall, sys_ioctl
X /*55*/	.long sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys_execve
X /*60*/	.long sys_umask, sys_chroot, sys_newfstat, sys_nis_syscall, sys_getpagesize
@@ -47,7 +47,7 @@
X /*140*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getrlimit
X /*145*/	.long sys_setrlimit, sys_nis_syscall, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
X /*150*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_nis_syscall
-/*155*/	.long sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_umount
+/*155*/	.long sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
X /*160*/	.long sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
X /*165*/	.long sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
X /*170*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
@@ -129,7 +129,7 @@
X /*150*/	.long sys_getsockname, sunos_nosys, sunos_nosys
X 	.long sys_poll, sunos_nosys, sunos_nosys
X 	.long sunos_getdirentries, sys_statfs, sys_fstatfs
-	.long sys_umount, sunos_nosys, sunos_nosys
+	.long sys_oldumount, sunos_nosys, sunos_nosys
X 	.long sys_getdomainname, sys_setdomainname
X 	.long sunos_nosys, sys_quotactl, sunos_nosys
X 	.long sunos_mount, sys_ustat, sunos_semsys
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/kernel/unaligned.c linux/arch/sparc/kernel/unaligned.c
--- v2.2.6/linux/arch/sparc/kernel/unaligned.c	Mon Apr 14 16:28:07 1997
+++ linux/arch/sparc/kernel/unaligned.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/* $Id: unaligned.c,v 1.17 1997/04/11 00:42:08 davem Exp $
+/* $Id: unaligned.c,v 1.18 1999/04/03 11:36:17 anton Exp $
X  * unaligned.c: Unaligned load/store trap handling with special
X  *              cases for the kernel to do them more quickly.
X  *
@@ -332,7 +332,6 @@
X 	enum direction dir = decode_direction(insn);
X 	int size = decode_access_size(insn);
X 
-	lock_kernel();
X 	if(!ok_for_kernel(insn) || dir == both) {
X 		printk("Unsupported unaligned load/store trap for kernel at <%08lx>.\n",
X 		       regs->pc);
@@ -380,7 +379,6 @@
X 		}
X 		advance(regs);
X 	}
-	unlock_kernel();
X }
X 
X static inline int ok_for_user(struct pt_regs *regs, unsigned int insn,
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/lib/atomic.S linux/arch/sparc/lib/atomic.S
--- v2.2.6/linux/arch/sparc/lib/atomic.S	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc/lib/atomic.S	Thu Apr 22 19:24:51 1999
@@ -44,6 +44,7 @@
X 	.globl	___atomic_add
X ___atomic_add:
X 	rd	%psr, %g3		! Keep the code small, old way was stupid
+	nop; nop; nop;			! Let the bits set
X 	or	%g3, PSR_PIL, %g7	! Disable interrupts
X 	wr	%g7, 0x0, %psr		! Set %psr
X 	nop; nop; nop;			! Let the bits set
@@ -69,6 +70,7 @@
X 	.globl	___atomic_sub
X ___atomic_sub:
X 	rd	%psr, %g3		! Keep the code small, old way was stupid
+	nop; nop; nop;			! Let the bits set
X 	or	%g3, PSR_PIL, %g7	! Disable interrupts
X 	wr	%g7, 0x0, %psr		! Set %psr
X 	nop; nop; nop;			! Let the bits set
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/lib/bitops.S linux/arch/sparc/lib/bitops.S
--- v2.2.6/linux/arch/sparc/lib/bitops.S	Sun Nov  8 14:02:45 1998
+++ linux/arch/sparc/lib/bitops.S	Thu Apr 22 19:24:51 1999
@@ -20,12 +20,10 @@
X 	.globl	___set_bit
X ___set_bit:
X 	rd	%psr, %g3
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 nop
-	wr	%g3, PSR_PIL, %psr
+	nop; nop; nop;
+	or	%g3, PSR_PIL, %g5
+	wr	%g5, 0x0, %psr
X 	nop; nop; nop
-1:
X #ifdef __SMP__
X 	set	C_LABEL(bitops_spinlock), %g5
X 2:	ldstub	[%g5], %g7		! Spin on the byte lock for SMP.
@@ -38,17 +36,12 @@
X #ifdef __SMP__
X 	st	%g5, [%g1]
X 	set	C_LABEL(bitops_spinlock), %g5
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 stb	%g0, [%g5]
+	stb	%g0, [%g5]
X #else
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 st	%g5, [%g1]
+	st	%g5, [%g1]
X #endif
X 	wr	%g3, 0x0, %psr
X 	nop; nop; nop
-1:
X 	jmpl	%o7, %g0
X 	 mov	%g4, %o7
X 
@@ -56,12 +49,10 @@
X 	.globl	___clear_bit
X ___clear_bit:
X 	rd	%psr, %g3
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 nop
-	wr	%g3, PSR_PIL, %psr
X 	nop; nop; nop
-1:
+	or	%g3, PSR_PIL, %g5
+	wr	%g5, 0x0, %psr
+	nop; nop; nop
X #ifdef __SMP__
X 	set	C_LABEL(bitops_spinlock), %g5
X 2:	ldstub	[%g5], %g7		! Spin on the byte lock for SMP.
@@ -74,17 +65,12 @@
X #ifdef __SMP__
X 	st	%g5, [%g1]
X 	set	C_LABEL(bitops_spinlock), %g5
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 stb	%g0, [%g5]
+	stb	%g0, [%g5]
X #else
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 st	%g5, [%g1]
+	st	%g5, [%g1]
X #endif
X 	wr	%g3, 0x0, %psr
X 	nop; nop; nop
-1:
X 	jmpl	%o7, %g0
X 	 mov	%g4, %o7
X 
@@ -92,12 +78,10 @@
X 	.globl	___change_bit
X ___change_bit:
X 	rd	%psr, %g3
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 nop
-	wr	%g3, PSR_PIL, %psr
X 	nop; nop; nop
-1:
+	or	%g3, PSR_PIL, %g5
+	wr	%g5, 0x0, %psr
+	nop; nop; nop
X #ifdef __SMP__
X 	set	C_LABEL(bitops_spinlock), %g5
X 2:	ldstub	[%g5], %g7		! Spin on the byte lock for SMP.
@@ -110,17 +94,12 @@
X #ifdef __SMP__
X 	st	%g5, [%g1]
X 	set	C_LABEL(bitops_spinlock), %g5
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 stb	%g0, [%g5]
+	stb	%g0, [%g5]
X #else
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 st	%g5, [%g1]
+	st	%g5, [%g1]
X #endif
X 	wr	%g3, 0x0, %psr
X 	nop; nop; nop
-1:
X 	jmpl	%o7, %g0
X 	 mov	%g4, %o7
X 
@@ -128,12 +107,10 @@
X 	.globl	___set_le_bit
X ___set_le_bit:
X 	rd	%psr, %g3
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 nop
-	wr	%g3, PSR_PIL, %psr
X 	nop; nop; nop
-1:
+	or	%g3, PSR_PIL, %g5
+	wr	%g5, 0x0, %psr
+	nop; nop; nop
X #ifdef __SMP__
X 	set	C_LABEL(bitops_spinlock), %g5
X 2:	ldstub	[%g5], %g7		! Spin on the byte lock for SMP.
@@ -146,29 +123,22 @@
X #ifdef __SMP__
X 	stb	%g5, [%g1]
X 	set	C_LABEL(bitops_spinlock), %g5
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 stb	%g0, [%g5]
+	stb	%g0, [%g5]
X #else
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 stb	%g5, [%g1]
+	stb	%g5, [%g1]
X #endif
X 	wr	%g3, 0x0, %psr
X 	nop; nop; nop
-1:
X 	jmpl	%o7, %g0
X 	 mov	%g4, %o7
X 
X 	.globl	___clear_le_bit
X ___clear_le_bit:
X 	rd	%psr, %g3
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 nop
-	wr	%g3, PSR_PIL, %psr
X 	nop; nop; nop
-1:
+	or	%g3, PSR_PIL, %g5
+	wr	%g5, 0x0, %psr
+	nop; nop; nop
X #ifdef __SMP__
X 	set	C_LABEL(bitops_spinlock), %g5
X 2:	ldstub	[%g5], %g7		! Spin on the byte lock for SMP.
@@ -181,16 +151,11 @@
X #ifdef __SMP__
X 	stb	%g5, [%g1]
X 	set	C_LABEL(bitops_spinlock), %g5
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 stb	%g0, [%g5]
+	stb	%g0, [%g5]
X #else
-	andcc	%g3, PSR_PIL, %g0
-	bne	1f
-	 stb	%g5, [%g1]
+	stb	%g5, [%g1]
X #endif
X 	wr	%g3, 0x0, %psr
X 	nop; nop; nop
-1:
X 	jmpl	%o7, %g0
X 	 mov	%g4, %o7
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/lib/debuglocks.c linux/arch/sparc/lib/debuglocks.c
--- v2.2.6/linux/arch/sparc/lib/debuglocks.c	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc/lib/debuglocks.c	Thu Apr 22 19:24:51 1999
@@ -1,12 +1,13 @@
-/* $Id: debuglocks.c,v 1.6 1999/02/23 13:23:55 jj Exp $
+/* $Id: debuglocks.c,v 1.7 1999/04/21 02:26:58 anton Exp $
X  * debuglocks.c: Debugging versions of SMP locking primitives.
X  *
X  * Copyright (C) 1997 David S. Miller (da...@caip.rutgers.edu)
- * Copyright (C) 1998 Anton Blanchard (an...@progsoc.uts.edu.au)
+ * Copyright (C) 1998-99 Anton Blanchard (an...@progsoc.uts.edu.au)
X  */
X 
X #include <linux/kernel.h>
X #include <linux/sched.h>
+#include <linux/tasks.h>	/* For NR_CPUS */
X #include <asm/psr.h>
X #include <asm/system.h>
X #include <asm/spinlock.h>
@@ -39,20 +40,22 @@
X {
X 	int cpu = smp_processor_id();
X 
-	printk("%s(%p) CPU#%d stuck at %08lx, owner PC(%08lx):CPU(%lx)\n",str,
+	printk("%s(%p) CPU#%d stuck at %08lx, owner PC(%08lx):CPU(%lx)\n", str,
X 		lock, cpu, caller, lock->owner_pc & ~3, lock->owner_pc & 3);
X }
X 
X static inline void show_write(char *str, rwlock_t *lock, unsigned long caller)
X {
X 	int cpu = smp_processor_id();
+	int i;
X 
-	printk("%s(%p) CPU#%d stuck at %08lx, owner PC(%08lx):CPU(%lx) reader[0]=%08lx reader[1]=%08lx reader[2]=%08lx reader[3]=%08lx\n",
-		str, lock, cpu, caller, lock->owner_pc & ~3, lock->owner_pc & 3,
-		lock->reader_pc[0],
-		lock->reader_pc[1],
-		lock->reader_pc[2],
-		lock->reader_pc[3]);
+	printk("%s(%p) CPU#%d stuck at %08lx, owner PC(%08lx):CPU(%lx)", str,
+		lock, cpu, caller, lock->owner_pc & ~3, lock->owner_pc & 3);
+
+	for(i = 0; i < NR_CPUS; i++)
+		printk(" reader[i]=%08lx", lock->reader_pc[i]);
+
+	printk("\n");
X }
X 
X #undef INIT_STUCK
@@ -105,9 +108,6 @@
X 	lock->lock = 0;
X }
X 
-#undef INIT_STUCK
-#define INIT_STUCK 100000000
-
X void _do_read_lock(rwlock_t *rw, char *str)
X {
X 	unsigned long caller;
@@ -135,9 +135,6 @@
X 	rw->lock++;
X }
X 
-#undef INIT_STUCK
-#define INIT_STUCK 100000000
-
X void _do_read_unlock(rwlock_t *rw, char *str)
X {
X 	unsigned long caller;
@@ -164,9 +161,6 @@
X 	barrier();
X 	rw->lock -= 0x1ff;
X }
-
-#undef INIT_STUCK
-#define INIT_STUCK 100000000
X 
X void _do_write_lock(rwlock_t *rw, char *str)
X {
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/lib/irqlock.S linux/arch/sparc/lib/irqlock.S
--- v2.2.6/linux/arch/sparc/lib/irqlock.S	Tue May 13 22:41:03 1997
+++ linux/arch/sparc/lib/irqlock.S	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/* $Id: irqlock.S,v 1.4 1997/05/01 02:26:54 davem Exp $
+/* $Id: irqlock.S,v 1.5 1999/04/20 13:22:37 anton Exp $
X  * irqlock.S: High performance IRQ global locking and interrupt entry.
X  *
X  * Copyright (C) 1997 David S. Miller (da...@caip.rutgers.edu)
@@ -9,69 +9,6 @@
X 
X 	.text
X 	.align	4
-
-	/* This is incredibly insane... */
-	.globl	___irq_enter
-___irq_enter:
-	sethi	%hi(local_irq_count), %g2
-	sll	%g1, 2, %g1
-	or	%g2, %lo(local_irq_count), %g2
-	ld	[%g2 + %g1], %g3
-	sethi	%hi(global_irq_count), %g5
-	add	%g3, 1, %g3
-	or	%g5, %lo(global_irq_count), %g5
-	st	%g3, [%g2 + %g1]
-1:
-	ldstub	[%g5 + 3], %g2
-	orcc	%g2, 0x0, %g0
-	bne	1b
-	 ld	[%g5], %g3
-	sra	%g3, 8, %g3
-	add	%g3, 1, %g3
-	sll	%g3, 8, %g3
-	st	%g3, [%g5]
-	sethi	%hi(global_irq_lock), %g1
-	ldub	[%g1 + %lo(global_irq_lock)], %g2
-1:	
-	orcc	%g2, 0x0, %g0
-	bne,a	1b
-	 ldub	[%g1 + %lo(global_irq_lock)], %g2
-___irq_enter_out:
-	jmpl	%o7, %g0
-	 mov	%g4, %o7
-
-	.globl	___irq_exit
-___irq_exit:
-	rd	%psr, %g3
-	sethi	%hi(global_irq_count), %g1
-	or	%g3, PSR_PIL, %g3
-	or	%g1, %lo(global_irq_count), %g1
-	wr	%g3, 0x0, %psr
-	sethi	%hi(local_irq_count), %g2
-	sll	%g7, 2, %g7
-	or	%g2, %lo(local_irq_count), %g2
-	ld	[%g2 + %g7], %g3
-1:	
-	ldstub	[%g1 + 3], %g5
-	orcc	%g5, 0x0, %g0
-	bne	1b
-	 ld	[%g1], %g5
-	sra	%g5, 8, %g5
-	sub	%g5, 1, %g5
-	sll	%g5, 8, %g5
-	st	%g5, [%g1]
-	sub	%g3, 1, %g3
-	sethi	%hi(global_irq_holder), %g1
-	st	%g3, [%g2 + %g7]
-	srl	%g7, 2, %g7
-	ldub	[%g1 + %lo(global_irq_holder)], %g5
-	cmp	%g5, %g7
-	bne	___irq_enter_out
-	 mov	NO_PROC_ID, %g2
-	stb	%g2, [%g1 + %lo(global_irq_holder)]
-	sethi	%hi(global_irq_lock), %g5
-	b	___irq_enter_out
-	 stb	%g0, [%g5 + %lo(global_irq_lock)]
X 
X 	/* Weird calling conventions... %g7=flags, %g4=%prev_o7
X 	 * Very clever for the __global_sti case, the inline which
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/mm/init.c linux/arch/sparc/mm/init.c
--- v2.2.6/linux/arch/sparc/mm/init.c	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc/mm/init.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.63 1999/03/20 22:02:01 davem Exp $
+/*  $Id: init.c,v 1.65 1999/04/09 16:28:03 davem Exp $
X  *  linux/arch/sparc/mm/init.c
X  *
X  *  Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/mm/nosrmmu.c linux/arch/sparc/mm/nosrmmu.c
--- v2.2.6/linux/arch/sparc/mm/nosrmmu.c	Thu Apr 23 20:21:31 1998
+++ linux/arch/sparc/mm/nosrmmu.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/* $Id: nosrmmu.c,v 1.1 1998/03/09 14:04:15 jj Exp $
+/* $Id: nosrmmu.c,v 1.2 1999/03/30 10:17:39 jj Exp $
X  * nosrmmu.c: This file is a bunch of dummies for sun4 compiles, 
X  *         so that it does not need srmmu and avoid ifdefs.
X  *
@@ -45,6 +45,16 @@
X }
X 
X __initfunc(void srmmu_end_memory(unsigned long memory_size, unsigned long *mem_end_p))
+{
+	return 0;
+}
+
+__u32 iounit_map_dma_init(struct linux_sbus *sbus, int size)
+{
+	return 0;
+}
+
+__u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct linux_sbus *sbus)
X {
X 	return 0;
X }
diff -u --recursive --new-file v2.2.6/linux/arch/sparc/mm/srmmu.c linux/arch/sparc/mm/srmmu.c
--- v2.2.6/linux/arch/sparc/mm/srmmu.c	Mon Mar 29 11:09:11 1999
+++ linux/arch/sparc/mm/srmmu.c	Wed Apr 28 10:58:10 1999
@@ -1,4 +1,4 @@
-/* $Id: srmmu.c,v 1.185 1999/03/24 11:42:35 davem Exp $
+/* $Id: srmmu.c,v 1.187 1999/04/28 17:00:45 davem Exp $
X  * srmmu.c:  SRMMU specific routines for memory management.
X  *
X  * Copyright (C) 1995 David S. Miller  (da...@caip.rutgers.edu)
@@ -14,6 +14,7 @@
X #include <linux/vmalloc.h>
X #include <linux/pagemap.h>
X #include <linux/init.h>
+#include <linux/blk.h>
X 
X #include <asm/page.h>
X #include <asm/pgtable.h>
@@ -1948,12 +1949,13 @@
X 		/* Find the number of contexts on the srmmu. */
X 		cpunode = prom_getchild(prom_root_node);
X 		num_contexts = 0;
-		while((cpunode = prom_getsibling(cpunode)) != 0) {
+		while(cpunode != 0) {
X 			prom_getstring(cpunode, "device_type", node_str, sizeof(node_str));
X 			if(!strcmp(node_str, "cpu")) {
X 				num_contexts = prom_getintdefault(cpunode, "mmu-nctx", 0x8);
X 				break;
X 			}
+			cpunode = prom_getsibling(cpunode);
X 		}
X 	}
X 
@@ -2000,6 +2002,18 @@
X 
X 	start_mem = sparc_context_init(start_mem, num_contexts);
X 	start_mem = free_area_init(start_mem, end_mem);
+	
+#ifdef CONFIG_BLK_DEV_INITRD
+	/* If initial ramdisk was specified with physical address,
+	   translate it here, as the p2v translation in srmmu
+	   is not straightforward. */
+	if (initrd_start && initrd_start < KERNBASE) {
+		initrd_start = srmmu_p2v(initrd_start);
+		initrd_end = srmmu_p2v(initrd_end);
+		if (initrd_end <= initrd_start)
+			initrd_start = 0;
+	}
+#endif
X 
X 	return PAGE_ALIGN(start_mem);
X }
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/config.in linux/arch/sparc64/config.in
--- v2.2.6/linux/arch/sparc64/config.in	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc64/config.in	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.65 1999/03/14 03:12:48 anton Exp $
+# $Id: config.in,v 1.66 1999/03/29 05:08:42 davem Exp $
X # For a description of the syntax of this configuration file,
X # see the Configure script.
X #
@@ -185,6 +185,7 @@
X 	      bool '  assume boards are SYMBIOS compatible' CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT
X 	    fi
X 	  fi
+          dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI
X 	fi
X 
X 	endmenu
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.2.6/linux/arch/sparc64/defconfig	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc64/defconfig	Thu Apr 22 19:24:51 1999
@@ -208,6 +208,7 @@
X CONFIG_SCSI_NCR53C8XX_SYNC=10
X # CONFIG_SCSI_NCR53C8XX_PROFILE is not set
X # CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+CONFIG_SCSI_QLOGIC_ISP=y
X 
X #
X # Fibre Channel support
@@ -298,6 +299,8 @@
X # CONFIG_NCPFS_NFS_NS is not set
X # CONFIG_NCPFS_OS2_NS is not set
X # CONFIG_NCPFS_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
X 
X #
X # Partition Types
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/kernel/cpu.c linux/arch/sparc64/kernel/cpu.c
--- v2.2.6/linux/arch/sparc64/kernel/cpu.c	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc64/kernel/cpu.c	Wed Apr 28 08:47:39 1999
@@ -69,7 +69,7 @@
X 
X 	fprs = fprs_read ();
X 	fprs_write (FPRS_FEF);
-	__asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]" : "=r" (ver) : "r" (&fpu_vers));
+	__asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]" : "=&r" (ver) : "r" (&fpu_vers));
X 	fprs_write (fprs);
X 	
X 	manuf = ((ver >> 48)&0xffff);
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/kernel/entry.S linux/arch/sparc64/kernel/entry.S
--- v2.2.6/linux/arch/sparc64/kernel/entry.S	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc64/kernel/entry.S	Thu Apr 22 19:24:51 1999
@@ -1,10 +1,10 @@
-/* $Id: entry.S,v 1.101 1999/01/19 07:54:38 davem Exp $
+/* $Id: entry.S,v 1.102 1999/03/29 12:38:09 jj Exp $
X  * arch/sparc64/kernel/entry.S:  Sparc64 trap low-level entry points.
X  *
X  * Copyright (C) 1995,1997 David S. Miller (da...@caip.rutgers.edu)
X  * Copyright (C) 1996 Eddie C. Dost        (e...@skynet.be)
X  * Copyright (C) 1996 Miguel de Icaza      (mig...@nuclecu.unam.mx)
- * Copyright (C) 1996,1998 Jakub Jelinek   (j...@sunsite.mff.cuni.cz)
+ * Copyright (C) 1996,98,99 Jakub Jelinek  (j...@sunsite.mff.cuni.cz)
X  */
X 
X #include <linux/config.h>
@@ -163,6 +163,39 @@
X 	wrpr		%g3, %tstate
X 	wr		%g0, FPRS_FEF, %fprs	! clean DU/DL bits
X 	retry
+
+	.globl		do_fptrap
+	.align		32
+do_fptrap:
+	ldub		[%g6 + AOFF_task_tss + AOFF_thread_fpsaved], %g3
+	stx		%fsr, [%g6 + AOFF_task_tss + AOFF_thread_xfsr]
+	rd		%fprs, %g1
+	or		%g3, %g1, %g3
+	stb		%g3, [%g6 + AOFF_task_tss + AOFF_thread_fpsaved]
+	rd		%gsr, %g3
+	stb		%g3, [%g6 + AOFF_task_tss + AOFF_thread_gsr]
+	mov		SECONDARY_CONTEXT, %g3
+	add		%g6, AOFF_task_fpregs, %g2
+	ldxa		[%g3] ASI_DMMU, %g5
+	stxa		%g0, [%g3] ASI_DMMU
+	flush		%g6
+	membar		#StoreStore | #LoadStore
+	andcc		%g1, FPRS_DL, %g0
+	be,pn		%icc, 4f
+	 mov		0x40, %g3
+	stda		%f0, [%g2] ASI_BLK_S
+	stda		%f16, [%g2 + %g3] ASI_BLK_S
+	andcc		%g1, FPRS_DU, %g0
+	be,pn		%icc, 5f
+4:       add		%g2, 128, %g2
+	stda		%f32, [%g2] ASI_BLK_S
+	stda		%f48, [%g2 + %g3] ASI_BLK_S
+5:	mov		SECONDARY_CONTEXT, %g1
+	membar		#Sync
+	stxa		%g5, [%g1] ASI_DMMU
+	flush		%g6
+	ba,pt		%xcc, etrap
+	 wr		%g0, 0, %fprs
X 
X 	/* The registers for cross calls will be:
X 	 *
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/kernel/head.S linux/arch/sparc64/kernel/head.S
--- v2.2.6/linux/arch/sparc64/kernel/head.S	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc64/kernel/head.S	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.59 1999/01/06 01:37:35 davem Exp $
+/* $Id: head.S,v 1.60 1999/04/12 08:08:21 davem Exp $
X  * head.S: Initial boot code for the Sparc64 port of Linux.
X  *
X  * Copyright (C) 1996,1997 David S. Miller (da...@caip.rutgers.edu)
@@ -47,7 +47,7 @@
X  * HdrS version should be incremented.
X  */
X         .global root_flags, ram_flags, root_dev
-        .global ramdisk_image, ramdisk_size
+        .global sparc_ramdisk_image, sparc_ramdisk_size
X 	.globl	silo_args
X 
X         .ascii  "HdrS"
@@ -59,9 +59,9 @@
X         .half   0
X ram_flags:
X         .half   0
-ramdisk_image:
+sparc_ramdisk_image:
X         .word   0
-ramdisk_size:
+sparc_ramdisk_size:
X         .word   0
X         .xword  reboot_command
X 	.xword	bootstr_len
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/kernel/irq.c linux/arch/sparc64/kernel/irq.c
--- v2.2.6/linux/arch/sparc64/kernel/irq.c	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc64/kernel/irq.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.75 1999/01/28 12:37:56 jj Exp $
+/* $Id: irq.c,v 1.76 1999/04/02 14:54:30 davem Exp $
X  * irq.c: UltraSparc IRQ handling/init/registry.
X  *
X  * Copyright (C) 1997  David S. Miller  (da...@caip.rutgers.edu)
@@ -309,7 +309,7 @@
X unsigned int build_irq(int pil, int inofixup, unsigned int *iclr, unsigned int *imap)
X {
X 	struct ino_bucket *bucket;
-	unsigned short ino;
+	int ino;
X 
X 	if(pil == 0) {
X 		if(iclr != NULL || imap != NULL) {
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/kernel/psycho.c linux/arch/sparc64/kernel/psycho.c
--- v2.2.6/linux/arch/sparc64/kernel/psycho.c	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc64/kernel/psycho.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/* $Id: psycho.c,v 1.79 1999/03/19 05:38:46 davem Exp $
+/* $Id: psycho.c,v 1.85 1999/04/02 14:54:28 davem Exp $
X  * psycho.c: Ultra/AX U2P PCI controller support.
X  *
X  * Copyright (C) 1997 David S. Miller (da...@caipfs.rutgers.edu)
@@ -680,20 +680,23 @@
X {
X 	unsigned int devfn, l, class;
X 	unsigned char hdr_type = 0;
+	int is_multi = 0;
X 
X 	for (devfn = 0; devfn < 0xff; ++devfn) {
-		if (PCI_FUNC(devfn) == 0) {
-			pbm_read_config_byte(pbm, bus, devfn,
-					     PCI_HEADER_TYPE, &hdr_type);
-		} else if (!(hdr_type & 0x80)) {
+		if (PCI_FUNC(devfn) != 0 && is_multi == 0) {
X 			/* not a multi-function device */
X 			continue;
X 		}
+		pbm_read_config_byte(pbm, bus, devfn,
+				     PCI_HEADER_TYPE, &hdr_type);
+		if (PCI_FUNC(devfn) == 0)
+			is_multi = hdr_type & 0x80;
X 
X 		/* Check if there is anything here. */
X 		pbm_read_config_dword(pbm, bus, devfn, PCI_VENDOR_ID, &l);
-		if (l == 0xffffffff || l == 0x00000000) {
-			hdr_type = 0;
+		if (l == 0xffffffff || l == 0x00000000 ||
+		    l == 0x0000ffff || l == 0xffff0000) {
+			is_multi = 0;
X 			continue;
X 		}
X 
@@ -1234,12 +1237,13 @@
X 		}
X 		if (bsreg == PCI_ROM_ADDRESS) {
X 			pdev->rom_address = (unsigned long)__va(pci_addr);
-			pdev->rom_address |= 1;
+			pdev->rom_address &= ~1UL;
+
X 			/*
-			 * Enable access to the ROM.
+			 * Disable access to the ROM.
X 			 */
X 			pci_read_config_dword(pdev, PCI_ROM_ADDRESS, &rtmp);
-			pci_write_config_dword(pdev, PCI_ROM_ADDRESS, rtmp | 1);
+			pci_write_config_dword(pdev, PCI_ROM_ADDRESS, rtmp & ~1);
X 		} else
X 			pdev->base_address[brindex] = (unsigned long)__va(pci_addr);
X 
@@ -1408,7 +1412,7 @@
X 
X 			rtmp = new_base;
X 			pci_read_config_dword(pdev, breg, &base);
-			rtmp |= (base & ~PCI_ROM_ADDRESS_MASK);
+			rtmp &= ~(base & ~PCI_ROM_ADDRESS_MASK);
X 			pci_write_config_dword(pdev, breg, rtmp);
X 
X 			/* Apply PBM ranges and update pci_dev. */
@@ -1431,8 +1435,7 @@
X 					    "PBM ranges\n");
X 			}
X 			pdev->rom_address = (unsigned long)__va(pci_addr);
-
-			pdev->rom_address |= (base & ~PCI_ROM_ADDRESS_MASK);
+			pdev->rom_address &= ~(base & ~PCI_ROM_ADDRESS_MASK);
X 			MEM_seen = 1;
X 		}
X 	rom_address_done:
@@ -1588,6 +1591,36 @@
X 			imap_off = imap_offset(imap_ser);
X 			break;
X 
+		case 0x2c:
+			/* Onboard Timer 0 */
+			imap_off = imap_offset(imap_tim0);
+			break;
+
+		case 0x2d:
+			/* Onboard Timer 1 */
+			imap_off = imap_offset(imap_tim1);
+			break;
+
+		case 0x2e:
+			/* Psycho UE Interrupt */
+			imap_off = imap_offset(imap_ue);
+			break;
+
+		case 0x2f:
+			/* Psycho CE Interrupt */
+			imap_off = imap_offset(imap_ce);
+			break;
+
+		case 0x30:
+			/* Psycho PCI A Error Interrupt */
+			imap_off = imap_offset(imap_a_err);
+			break;
+
+		case 0x31:
+			/* Psycho PCI B Error Interrupt */
+			imap_off = imap_offset(imap_b_err);
+			break;
+
X 		case 0x32:
X 			/* Power Management */
X 			imap_off = imap_offset(imap_pmgmt);
@@ -1720,7 +1753,6 @@
X 			     int node)
X {
X 	unsigned int prom_irq, portid = pbm->parent->upa_portid;
-	unsigned char pci_irq_line = pdev->irq;
X 	int err;
X 
X #ifdef FIXUP_IRQ_DEBUG
@@ -1764,7 +1796,25 @@
X 		unsigned int bus, slot, line;
X 
X 		bus = (pbm == &pbm->parent->pbm_B) ? (1 << 4) : 0;
-		line = (pci_irq_line) & 3;
+
+		/* Use the given interrupt property value as the line if it
+		 * is non-zero and legal.  Legal encodings are INTA=1, INTB=2,
+		 * INTC=3, INTD=4 as per PCI OBP binding spec version 2.1 -DaveM
+		 */
+		if(prom_irq > 0 && prom_irq < 5) {
+			line = ((prom_irq - 1) & 3);
+		} else {
+			unsigned char pci_irq_line;
+
+			/* The generic PCI probing layer will read the
+			 * interrupt line into pdev->irq if the interrupt
+			 * pin is non-zero, so we have to explicitly fetch
+			 * the pin here to be certain (the interrupt line is
+			 * typically left at zero by OBP).
+			 */
+			pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pci_irq_line);
+			line = ((pci_irq_line - 1) & 3);
+		}
X 
X 		/* Slot determination is only slightly complex.  Handle
X 		 * the easy case first.
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/kernel/setup.c linux/arch/sparc64/kernel/setup.c
--- v2.2.6/linux/arch/sparc64/kernel/setup.c	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc64/kernel/setup.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.41 1999/01/04 20:12:25 davem Exp $
+/*  $Id: setup.c,v 1.43 1999/04/12 08:08:24 davem Exp $
X  *  linux/arch/sparc64/kernel/setup.c
X  *
X  *  Copyright (C) 1995,1996  David S. Miller (da...@caip.rutgers.edu)
@@ -413,13 +413,12 @@
X extern int prom_probe_memory(void);
X extern unsigned long start, end;
X extern void panic_setup(char *, int *);
-extern unsigned long sun_serial_setup(unsigned long);
X 
X extern unsigned short root_flags;
X extern unsigned short root_dev;
X extern unsigned short ram_flags;
-extern unsigned int ramdisk_image;
-extern unsigned int ramdisk_size;
+extern unsigned int sparc_ramdisk_image;
+extern unsigned int sparc_ramdisk_size;
X #define RAMDISK_IMAGE_START_MASK	0x07FF
X #define RAMDISK_PROMPT_FLAG		0x8000
X #define RAMDISK_LOAD_FLAG		0x4000
@@ -509,13 +508,13 @@
X 	rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0);	
X #endif
X #ifdef CONFIG_BLK_DEV_INITRD
-	if (ramdisk_image) {
+	if (sparc_ramdisk_image) {
X 		unsigned long start = 0;
X 		
-		if (ramdisk_image >= (unsigned long)&end - 2 * PAGE_SIZE)
-			ramdisk_image -= KERNBASE;
-		initrd_start = ramdisk_image + phys_base + PAGE_OFFSET;
-		initrd_end = initrd_start + ramdisk_size;
+		if (sparc_ramdisk_image >= (unsigned long)&end - 2 * PAGE_SIZE)
+			sparc_ramdisk_image -= KERNBASE;
+		initrd_start = sparc_ramdisk_image + phys_base + PAGE_OFFSET;
+		initrd_end = initrd_start + sparc_ramdisk_size;
X 		if (initrd_end > *memory_end_p) {
X 			printk(KERN_CRIT "initrd extends beyond end of memory "
X 		                 	 "(0x%016lx > 0x%016lx)\ndisabling initrd\n",
@@ -523,10 +522,10 @@
X 			initrd_start = 0;
X 		}
X 		if (initrd_start)
-			start = ramdisk_image + KERNBASE;
+			start = sparc_ramdisk_image + KERNBASE;
X 		if (start >= *memory_start_p && start < *memory_start_p + 2 * PAGE_SIZE) {
X 			initrd_below_start_ok = 1;
-			*memory_start_p = PAGE_ALIGN (start + ramdisk_size);
+			*memory_start_p = PAGE_ALIGN (start + sparc_ramdisk_size);
X 		}
X 	}
X #endif	
@@ -586,7 +585,6 @@
X 		serial_console = 2;
X 		break;
X 	}
-	*memory_start_p = sun_serial_setup(*memory_start_p); /* set this up ASAP */
X #else
X 	serial_console = 0;
X #endif
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/kernel/smp.c linux/arch/sparc64/kernel/smp.c
--- v2.2.6/linux/arch/sparc64/kernel/smp.c	Mon Mar 29 11:09:11 1999
+++ linux/arch/sparc64/kernel/smp.c	Thu Apr 22 19:24:51 1999
@@ -380,37 +380,51 @@
X  * to the stack before we get here because all callers of us
X  * are flush_tlb_*() routines, and these run after flush_cache_*()
X  * which performs the flushw.
+ *
+ * The SMP TLB coherency scheme we use works as follows:
+ *
+ * 1) mm->cpu_vm_mask is a bit mask of which cpus an address
+ *    space has (potentially) executed on, this is the heuristic
+ *    we use to avoid doing cross calls.
+ *
+ * 2) TLB context numbers are shared globally across all processors
+ *    in the system, this allows us to play several games to avoid
+ *    cross calls.
+ *
+ *    One invariant is that when a cpu switches to a process, and
+ *    that processes tsk->mm->cpu_vm_mask does not have the current
+ *    cpu's bit set, that tlb context is flushed locally.
+ *
+ *    If the address space is non-shared (ie. mm->count == 1) we avoid
+ *    cross calls when we want to flush the currently running process's
+ *    tlb state.  This is done by clearing all cpu bits except the current
+ *    processor's in current->mm->cpu_vm_mask and performing the flush
+ *    locally only.  This will force any subsequent cpus which run this
+ *    task to flush the context from the local tlb if the process migrates
+ *    to another cpu (again).
+ *
+ * 3) For shared address spaces (threads) and swapping we bite the
+ *    bullet for most cases and perform the cross call.
+ *
+ *    The performance gain from "optimizing" away the cross call for threads is
+ *    questionable (in theory the big win for threads is the massive sharing of
+ *    address space state across processors).
+ *
+ *    For the swapping case the locking is difficult to get right, we'd have to
+ *    enforce strict ordered access to mm->cpu_vm_mask via a spinlock for example.
+ *    Then again one could argue that when you are swapping, the cost of a cross
+ *    call won't even show up on the performance radar.  But in any case we do get
+ *    rid of the cross-call when the task has a dead context or the task has only
+ *    ever run on the local cpu.
X  */
-static void smp_cross_call_avoidance(struct mm_struct *mm)
-{
-	u32 ctx;
-
-	spin_lock(&scheduler_lock);
-	get_new_mmu_context(mm);
-	mm->cpu_vm_mask = (1UL << smp_processor_id());
-	current->tss.ctx = ctx = mm->context & 0x3ff;
-	spitfire_set_secondary_context(ctx);
-	__asm__ __volatile__("flush %g6");
-	spitfire_flush_dtlb_secondary_context();
-	spitfire_flush_itlb_secondary_context();
-	__asm__ __volatile__("flush %g6");
-	if(!segment_eq(current->tss.current_ds,USER_DS)) {
-		/* Rarely happens. */
-		current->tss.ctx = 0;
-		spitfire_set_secondary_context(0);
-		__asm__ __volatile__("flush %g6");
-	}
-	spin_unlock(&scheduler_lock);
-}
-
X void smp_flush_tlb_mm(struct mm_struct *mm)
X {
X 	u32 ctx = mm->context & 0x3ff;
X 
X 	if(mm == current->mm && atomic_read(&mm->count) == 1) {
-		if(mm->cpu_vm_mask == (1UL << smp_processor_id()))
-			goto local_flush_and_out;
-		return smp_cross_call_avoidance(mm);
+		if(mm->cpu_vm_mask != (1UL << smp_processor_id()))
+			mm->cpu_vm_mask = (1UL << smp_processor_id());
+		goto local_flush_and_out;
X 	}
X 	smp_cross_call(&xcall_flush_tlb_mm, ctx, 0, 0);
X 
@@ -426,9 +440,9 @@
X 	start &= PAGE_MASK;
X 	end   &= PAGE_MASK;
X 	if(mm == current->mm && atomic_read(&mm->count) == 1) {
-		if(mm->cpu_vm_mask == (1UL << smp_processor_id()))
-			goto local_flush_and_out;
-		return smp_cross_call_avoidance(mm);
+		if(mm->cpu_vm_mask != (1UL << smp_processor_id()))
+			mm->cpu_vm_mask = (1UL << smp_processor_id());
+		goto local_flush_and_out;
X 	}
X 	smp_cross_call(&xcall_flush_tlb_range, ctx, start, end);
X 
@@ -442,22 +456,32 @@
X 
X 	page &= PAGE_MASK;
X 	if(mm == current->mm && atomic_read(&mm->count) == 1) {
-		if(mm->cpu_vm_mask == (1UL << smp_processor_id()))
-			goto local_flush_and_out;
-		return smp_cross_call_avoidance(mm);
-	}
-#if 0 /* XXX Disabled until further notice... */
-	else if(atomic_read(&mm->count) == 1) {
+		if(mm->cpu_vm_mask != (1UL << smp_processor_id()))
+			mm->cpu_vm_mask = (1UL << smp_processor_id());
+		goto local_flush_and_out;
+	} else {
+		spin_lock(&scheduler_lock);
+
X 		/* Try to handle two special cases to avoid cross calls
X 		 * in common scenerios where we are swapping process
X 		 * pages out.
X 		 */
-		if((mm->context ^ tlb_context_cache) & CTX_VERSION_MASK)
+		if(((mm->context ^ tlb_context_cache) & CTX_VERSION_MASK) ||
+		   (mm->cpu_vm_mask == 0)) {
+			/* A dead context cannot ever become "alive" until
+			 * a task switch is done to it.
+			 */
+			spin_unlock(&scheduler_lock);
X 			return; /* It's dead, nothing to do. */
-		if(mm->cpu_vm_mask == (1UL << smp_processor_id()))
-			goto local_flush_and_out;
+		}
+		if(mm->cpu_vm_mask == (1UL << smp_processor_id())) {
+			spin_unlock(&scheduler_lock);
+			__flush_tlb_page(ctx, page, SECONDARY_CONTEXT);
+			return; /* Only local flush is necessary. */
+		}
+
+		spin_unlock(&scheduler_lock);
X 	}
-#endif
X 	smp_cross_call(&xcall_flush_tlb_page, ctx, page, 0);
X 
X local_flush_and_out:
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/kernel/systbls.S linux/arch/sparc64/kernel/systbls.S
--- v2.2.6/linux/arch/sparc64/kernel/systbls.S	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc64/kernel/systbls.S	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.52 1999/03/20 22:02:05 davem Exp $
+/* $Id: systbls.S,v 1.53 1999/04/07 17:14:11 davem Exp $
X  * systbls.S: System call entry point tables for OS compatibility.
X  *            The native Linux system call table lives here also.
X  *
@@ -26,7 +26,7 @@
X /*30*/	.word sys32_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice
X 	.word sys_nis_syscall, sys_sync, sys_kill, sys32_newstat, sys32_sendfile
X /*40*/	.word sys32_newlstat, sys_dup, sys_pipe, sys32_times, sys_nis_syscall
-	.word sys_nis_syscall, sys_setgid, sys_getgid, sys_signal, sys_geteuid
+	.word sys_umount, sys_setgid, sys_getgid, sys_signal, sys_geteuid
X /*50*/	.word sys_getegid, sys_acct, sys_nis_syscall, sys_nis_syscall, sys32_ioctl
X 	.word sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys32_execve
X /*60*/	.word sys_umask, sys_chroot, sys32_newfstat, sys_nis_syscall, sys_getpagesize
@@ -48,7 +48,7 @@
X /*140*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getrlimit
X 	.word sys32_setrlimit, sys_nis_syscall, sys32_prctl, sys32_pciconfig_read, sys32_pciconfig_write
X /*150*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_nis_syscall
-	.word sys_nis_syscall, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_umount
+	.word sys_nis_syscall, sys_nis_syscall, sys32_statfs, sys32_fstatfs, sys_oldumount
X /*160*/	.word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_nis_syscall
X 	.word sys32_quotactl, sys_nis_syscall, sys32_mount, sys_ustat, sys_nis_syscall
X /*170*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getdents
@@ -85,7 +85,7 @@
X /*30*/	.word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice
X 	.word sys_nis_syscall, sys_sync, sys_kill, sys_newstat, sys_sendfile
X /*40*/	.word sys_newlstat, sys_dup, sys_pipe, sys_times, sys_nis_syscall
-	.word sys_nis_syscall, sys_setgid, sys_getgid, sys_signal, sys_geteuid
+	.word sys_umount, sys_setgid, sys_getgid, sys_signal, sys_geteuid
X /*50*/	.word sys_getegid, sys_acct, sys_memory_ordering, sys_nis_syscall, sys_ioctl
X 	.word sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys_execve
X /*60*/	.word sys_umask, sys_chroot, sys_newfstat, sys_nis_syscall, sys_getpagesize
@@ -107,7 +107,7 @@
X /*140*/	.word sys_nis_syscall, sys_getpeername, sys_nis_syscall, sys_nis_syscall, sys_getrlimit
X 	.word sys_setrlimit, sys_nis_syscall, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
X /*150*/	.word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_nis_syscall
-	.word sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_umount
+	.word sys_nis_syscall, sys_nis_syscall, sys_statfs, sys_fstatfs, sys_oldumount
X /*160*/	.word sys_nis_syscall, sys_nis_syscall, sys_getdomainname, sys_setdomainname, sys_utrap_install
X 	.word sys_quotactl, sys_nis_syscall, sys_mount, sys_ustat, sys_nis_syscall
X /*170*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents
@@ -188,7 +188,7 @@
X /*150*/	.word sys_getsockname, sunos_nosys, sunos_nosys
X 	.word sys_poll, sunos_nosys, sunos_nosys
X 	.word sunos_getdirentries, sys32_statfs, sys32_fstatfs
-	.word sys_umount, sunos_nosys, sunos_nosys
+	.word sys_oldumount, sunos_nosys, sunos_nosys
X 	.word sys_getdomainname, sys_setdomainname
X 	.word sunos_nosys, sys32_quotactl, sunos_nosys
X 	.word sunos_mount, sys_ustat, sunos_semsys
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/kernel/traps.c linux/arch/sparc64/kernel/traps.c
--- v2.2.6/linux/arch/sparc64/kernel/traps.c	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc64/kernel/traps.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.57 1999/03/02 15:42:18 jj Exp $
+/* $Id: traps.c,v 1.58 1999/03/29 12:38:10 jj Exp $
X  * arch/sparc64/kernel/traps.c
X  *
X  * Copyright (C) 1995,1997 David S. Miller (da...@caip.rutgers.edu)
@@ -406,8 +406,6 @@
X void do_fpieee(struct pt_regs *regs)
X {
X #ifdef DEBUG_FPU
-	save_and_clear_fpu();
-	
X 	printk("fpieee %016lx\n", current->tss.xfsr[0]);
X #endif
X 	do_fpe_common(regs);
@@ -420,7 +418,6 @@
X 	struct fpustate *f = FPUSTATE;
X 	int ret = 0;
X 
-	save_and_clear_fpu();
X 	switch ((current->tss.xfsr[0] & 0x1c000)) {
X 	case (2 << 14): /* unfinished_FPop */
X 	case (3 << 14): /* unimplemented_FPop */
@@ -428,7 +425,7 @@
X 		break;
X 	}
X 	if (ret) return;
-#ifdef DEBUG_FPU	
+#ifdef DEBUG_FPU
X 	printk("fpother %016lx\n", current->tss.xfsr[0]);
X #endif
X 	do_fpe_common(regs);
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/kernel/ttable.S linux/arch/sparc64/kernel/ttable.S
--- v2.2.6/linux/arch/sparc64/kernel/ttable.S	Mon Oct  5 13:13:38 1998
+++ linux/arch/sparc64/kernel/ttable.S	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/* $Id: ttable.S,v 1.27 1998/09/25 01:09:10 davem Exp $
+/* $Id: ttable.S,v 1.28 1999/03/29 12:38:10 jj Exp $
X  * ttable.S: Sparc V9 Trap Table(s) with SpitFire extensions.
X  *
X  * Copyright (C) 1996 David S. Miller (da...@caip.rutgers.edu)
@@ -21,8 +21,8 @@
X tl0_resv018:	BTRAP(0x18) BTRAP(0x19) BTRAP(0x1a) BTRAP(0x1b) BTRAP(0x1c) BTRAP(0x1d)
X tl0_resv01e:	BTRAP(0x1e) BTRAP(0x1f)
X tl0_fpdis:	TRAP_NOSAVE(do_fpdis)
-tl0_fpieee:	TRAP(do_fpieee)
-tl0_fpother:	TRAP(do_fpother)
+tl0_fpieee:	TRAP_SAVEFPU(do_fpieee)
+tl0_fpother:	TRAP_SAVEFPU(do_fpother)
X tl0_tof:	TRAP(do_tof)
X tl0_cwin:	CLEAN_WINDOW
X tl0_div0:	TRAP(do_div0)
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/kernel/unaligned.c linux/arch/sparc64/kernel/unaligned.c
--- v2.2.6/linux/arch/sparc64/kernel/unaligned.c	Tue Mar 23 14:35:47 1999
+++ linux/arch/sparc64/kernel/unaligned.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/* $Id: unaligned.c,v 1.14 1999/03/02 15:42:16 jj Exp $
+/* $Id: unaligned.c,v 1.15 1999/04/03 11:36:21 anton Exp $
X  * unaligned.c: Unaligned load/store trap handling with special
X  *              cases for the kernel to do them more quickly.
X  *
@@ -374,7 +374,6 @@
X 	enum direction dir = decode_direction(insn);
X 	int size = decode_access_size(insn);
X 
-	lock_kernel();
X 	if(!ok_for_kernel(insn) || dir == both) {
X 		printk("Unsupported unaligned load/store trap for kernel at <%016lx>.\n",
X 		       regs->tpc);
@@ -423,7 +422,6 @@
X 		}
X 		advance(regs);
X 	}
-	unlock_kernel();
X }
X 
X static char popc_helper[] = {
diff -u --recursive --new-file v2.2.6/linux/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- v2.2.6/linux/arch/sparc64/mm/init.c	Mon Mar 29 11:09:11 1999
+++ linux/arch/sparc64/mm/init.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.125 1999/03/28 08:39:33 davem Exp $
+/*  $Id: init.c,v 1.126 1999/04/09 16:16:41 jj Exp $
X  *  arch/sparc64/mm/init.c
X  *
X  *  Copyright (C) 1996-1999 David S. Miller (da...@caip.rutgers.edu)
@@ -1127,6 +1127,7 @@
X /* paging_init() sets up the page tables */
X 
X extern unsigned long free_area_init(unsigned long, unsigned long);
+extern unsigned long sun_serial_setup(unsigned long);
X 
X __initfunc(unsigned long 
X paging_init(unsigned long start_mem, unsigned long end_mem))
@@ -1195,6 +1196,13 @@
X 	 * such that __pa() macros etc. work.
X 	 */
X 	mempool = PAGE_ALIGN(start_mem) + shift;
+	
+#ifdef CONFIG_SUN_SERIAL
+	/* This does not logically belong here, but is the first place
+	   we can initialize it at, so that we work in the PAGE_OFFSET+
+	   address space. */
+	mempool = sun_serial_setup(mempool);
+#endif
X 
X 	/* Allocate 64M for dynamic DVMA mapping area. */
X 	allocate_ptable_skeleton(DVMA_VADDR, DVMA_VADDR + 0x4000000);
diff -u --recursive --new-file v2.2.6/linux/drivers/Makefile linux/drivers/Makefile
--- v2.2.6/linux/drivers/Makefile	Fri Nov 27 13:09:22 1998
+++ linux/drivers/Makefile	Sat Apr 24 18:45:18 1999
@@ -10,7 +10,7 @@
X SUB_DIRS     := block char net misc sound
X MOD_SUB_DIRS := $(SUB_DIRS)
X ALL_SUB_DIRS := $(SUB_DIRS) pci scsi sbus cdrom isdn pnp \
-				 macintosh video dio zorro fc4
+				 macintosh video dio zorro fc4 usb
X 
X ifdef CONFIG_DIO
X SUB_DIRS += dio
@@ -42,6 +42,11 @@
X ifdef CONFIG_PPC
X SUB_DIRS += macintosh
X MOD_SUB_DIRS += macintosh
+endif
+
+ifeq ($(CONFIG_USB),y)
+SUB_DIRS += usb
+MOD_SUB_DIRS += usb
X endif
X 
X # If CONFIG_SCSI is set, the core of SCSI support will be added to the kernel,
diff -u --recursive --new-file v2.2.6/linux/drivers/acorn/char/keyb_ps2.c linux/drivers/acorn/char/keyb_ps2.c
--- v2.2.6/linux/drivers/acorn/char/keyb_ps2.c	Tue Dec 22 14:16:54 1998
+++ linux/drivers/acorn/char/keyb_ps2.c	Mon Apr 26 13:31:49 1999
@@ -221,11 +221,6 @@
X };
X #endif
X 
-int ps2kbd_pretranslate(unsigned char scancode)
-{
-	return 1;
-}
-
X int ps2kbd_translate(unsigned char scancode, unsigned char *keycode_p, char *uf_p)
X {
X 	*uf_p = scancode & 0200;
@@ -235,7 +230,7 @@
X 
X static void ps2kbd_key(unsigned int keycode, unsigned int up_flag)
X {
-	handle_scancode(keycode + (up_flag ? 0x80 : 0));
+	handle_scancode(keycode, !up_flag);
X }
X 
X static inline void ps2kbd_sendbyte(unsigned char val)
diff -u --recursive --new-file v2.2.6/linux/drivers/block/ide-cd.h linux/drivers/block/ide-cd.h
--- v2.2.6/linux/drivers/block/ide-cd.h	Tue Mar 23 14:35:47 1999
+++ linux/drivers/block/ide-cd.h	Tue Apr 27 09:56:22 1999
@@ -334,13 +334,13 @@
X 
X #if defined(__BIG_ENDIAN_BITFIELD)
X 	__u8 reserved3           : 2;
-	/* Drive can fake writes */
-	__u8 test_write          : 1;
-	__u8 reserved3a          : 1;
-	/* Drive can write DVD-R discs */
-	__u8 dvd_r_write         : 1;
X 	/* Drive can write DVD-RAM discs */
X 	__u8 dvd_ram_write       : 1;
+	/* Drive can write DVD-R discs */
+	__u8 dvd_r_write         : 1;
+	__u8 reserved3a          : 1;
+	/* Drive can fake writes */
+	__u8 test_write          : 1;
X 	/* Drive can write to CD-R/W (CD-E) discs (orange book, part III) */
X 	__u8 cd_rw_write	 : 1; /* reserved in 1.2 */
X 	/* Drive supports write to CD-R discs (orange book, part II) */
@@ -350,13 +350,13 @@
X 	__u8 cd_r_write          : 1; /* reserved in 1.2 */
X 	/* Drive can write to CD-R/W (CD-E) discs (orange book, part III) */
X 	__u8 cd_rw_write	 : 1; /* reserved in 1.2 */
-	/* Drive can write DVD-RAM discs */
-	__u8 dvd_ram_write       : 1;
-	/* Drive can write DVD-R discs */
-	__u8 dvd_r_write         : 1;
-	__u8 reserved3a          : 1;
X 	/* Drive can fake writes */
X 	__u8 test_write          : 1;
+	__u8 reserved3a          : 1;
+	/* Drive can write DVD-R discs */
+	__u8 dvd_r_write         : 1;
+	/* Drive can write DVD-RAM discs */
+	__u8 dvd_ram_write       : 1;
X 	__u8 reserved3           : 2;
X #else
X #error "Please fix <asm/byteorder.h>"
diff -u --recursive --new-file v2.2.6/linux/drivers/block/rd.c linux/drivers/block/rd.c
--- v2.2.6/linux/drivers/block/rd.c	Mon Mar 29 11:09:11 1999
+++ linux/drivers/block/rd.c	Tue Apr 27 09:24:34 1999
@@ -295,6 +295,8 @@
X 
X #ifdef MODULE
X 
+MODULE_PARM (rd_size, "1i");
+
X int init_module(void)
X {
X 	int error = rd_init();
diff -u --recursive --new-file v2.2.6/linux/drivers/cdrom/optcd.c linux/drivers/cdrom/optcd.c
--- v2.2.6/linux/drivers/cdrom/optcd.c	Wed Aug 26 11:37:36 1998
+++ linux/drivers/cdrom/optcd.c	Sat Apr 24 17:49:37 1999
@@ -100,6 +100,10 @@
X #else
X #define DEBUG(x)
X #endif
+
+static int blksize = 2048;
+static int hsecsize = 2048;
+
X 
X /* Drive hardware/firmware characteristics
X    Identifiers in accordance with Optics Storage documentation */
@@ -2061,6 +2065,8 @@
X 		return -EIO;
X 	}
X 
+	hardsect_size[MAJOR_NR] = &hsecsize;
+	blksize_size[MAJOR_NR] = &blksize;
X 	blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
X 	read_ahead[MAJOR_NR] = 4;
X 	request_region(optcd_port, 4, "optcd");
diff -u --recursive --new-file v2.2.6/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.2.6/linux/drivers/char/Makefile	Fri Apr 16 14:47:30 1999
+++ linux/drivers/char/Makefile	Mon Apr 26 11:08:17 1999
@@ -42,14 +42,15 @@
X 
X ifndef CONFIG_SUN_KEYBOARD
X ifdef CONFIG_VT
-L_OBJS += keyboard.o
+LX_OBJS += keyboard.o
X endif
X  ifneq ($(ARCH),m68k)
X    L_OBJS += pc_keyb.o defkeymap.o
X  endif
X else
X ifdef CONFIG_PCI
-L_OBJS += defkeymap.o keyboard.o
+L_OBJS += defkeymap.o
+LX_OBJS += keyboard.o
X endif
X endif
X 
diff -u --recursive --new-file v2.2.6/linux/drivers/char/amikeyb.c linux/drivers/char/amikeyb.c
--- v2.2.6/linux/drivers/char/amikeyb.c	Mon Aug  3 12:45:45 1998
+++ linux/drivers/char/amikeyb.c	Mon Apr 26 13:25:54 1999
@@ -188,7 +188,7 @@
X     amikeyb_rep_timer.expires = jiffies + key_repeat_rate;
X     amikeyb_rep_timer.prev = amikeyb_rep_timer.next = NULL;
X     add_timer(&amikeyb_rep_timer);
-    handle_scancode(rep_scancode);
+    handle_scancode(rep_scancode, 1);
X 
X     restore_flags(flags);
X }
@@ -243,8 +243,8 @@
X 
X     if (keycode == AMIKEY_CAPS) {
X 	/* if the key is CAPS, fake a press/release. */
-	handle_scancode(AMIKEY_CAPS);
-	handle_scancode(BREAK_MASK | AMIKEY_CAPS);
+	handle_scancode(AMIKEY_CAPS, 1);
+	handle_scancode(AMIKEY_CAPS, 0);
X     } else if (keycode < 0x78) {
X 	/* handle repeat */
X 	if (break_flag) {
@@ -257,7 +257,7 @@
X 	    amikeyb_rep_timer.prev = amikeyb_rep_timer.next = NULL;
X 	    add_timer(&amikeyb_rep_timer);
X 	}
-	handle_scancode(scancode);
+	handle_scancode(scancode, !break_flag);
X     } else
X 	switch (keycode) {
X 	    case 0x78:
diff -u --recursive --new-file v2.2.6/linux/drivers/char/bttv.c linux/drivers/char/bttv.c
--- v2.2.6/linux/drivers/char/bttv.c	Fri Apr 16 14:47:30 1999
+++ linux/drivers/char/bttv.c	Sat Apr 24 17:49:37 1999
@@ -2853,6 +2853,16 @@
X }
X #endif
X 
+static void init_tea6300(struct i2c_bus *bus) 
+{
+        I2CWrite(bus, I2C_TEA6300, TEA6300_VL, 0x35, 1); /* volume left 0dB  */
+        I2CWrite(bus, I2C_TEA6300, TEA6300_VR, 0x35, 1); /* volume right 0dB */
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 02'
echo 'File patch-2.2.7 is continued in part 03'
echo 03 > _shar_seq_.tmp
#!/bin/sh
# this is part 04 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 04; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
-	idev->rx_buff.head = idev->rx_buff.data;
-	idev->rx_buff.offset = 0;
+	idev->rx_buff.data = idev->rx_buff.head;
X 
X 	/* Reset Rx FIFO. This will also flush the ST_FIFO */
X 	outb(FCR_RXTH|FCR_TXTH|FCR_RXSR|FCR_FIFO_EN, iobase+FCR);
@@ -1024,42 +1021,41 @@
X 				/* Skip frame */
X 				idev->stats.rx_errors++;
X 				
-				idev->rx_buff.offset  += len;
-				idev->rx_buff.head += len;
+				idev->rx_buff.data += len;
X 			
-				if ( status & FRM_ST_MAX_LEN)
+				if (status & FRM_ST_MAX_LEN)
X 					idev->stats.rx_length_errors++;
X 				
-				if ( status & FRM_ST_PHY_ERR) 
+				if (status & FRM_ST_PHY_ERR) 
X 					idev->stats.rx_frame_errors++;
X 				
-				if ( status & FRM_ST_BAD_CRC) 
+				if (status & FRM_ST_BAD_CRC) 
X 					idev->stats.rx_crc_errors++;
X 			}
X 			/* The errors below can be reported in both cases */
-			if ( status & FRM_ST_OVR1)
+			if (status & FRM_ST_OVR1)
X 				idev->stats.rx_fifo_errors++;
X 			
-			if ( status & FRM_ST_OVR2)
+			if (status & FRM_ST_OVR2)
X 				idev->stats.rx_fifo_errors++;
X 			
X 		} else {
X 			/* Check if we have transfered all data to memory */
-			if ( inb( iobase+LSR) & LSR_RXDA) {
+			if (inb(iobase+LSR) & LSR_RXDA) {
X 				/* Put this entry back in fifo */
X 				st_fifo->head--;
X 				st_fifo->len++;
X 				st_fifo->entries[st_fifo->head].status = status;
-				st_fifo->entries[ st_fifo->head].len = len;
+				st_fifo->entries[st_fifo->head].len = len;
X 
X 				/* Restore bank register */
-				outb( bank, iobase+BSR);
+				outb(bank, iobase+BSR);
X 			
X 				return FALSE; 	/* I'll be back! */
X 			}
X 
X 			/* Should be OK then */			
-			skb = dev_alloc_skb( len+1);
+			skb = dev_alloc_skb(len+1);
X 			if (skb == NULL)  {
X 				printk( KERN_INFO __FUNCTION__ 
X 					"(), memory squeeze, dropping frame.\n");
@@ -1070,20 +1066,19 @@
X 			}
X 			
X 			/* Make sure IP header gets aligned */
-			skb_reserve( skb, 1); 
+			skb_reserve(skb, 1); 
X 
X 			/* Copy frame without CRC */
-			if ( idev->io.baudrate < 4000000) {
-				skb_put( skb, len-2);
-				memcpy( skb->data, idev->rx_buff.head, len-2);
+			if (idev->io.baudrate < 4000000) {
+				skb_put(skb, len-2);
+				memcpy(skb->data, idev->rx_buff.data, len-2);
X 			} else {
-				skb_put( skb, len-4);
-				memcpy( skb->data, idev->rx_buff.head, len-4);
+				skb_put(skb, len-4);
+				memcpy(skb->data, idev->rx_buff.data, len-4);
X 			}
X 
X 			/* Move to next frame */
-			idev->rx_buff.offset += len;
-			idev->rx_buff.head += len;
+			idev->rx_buff.data += len;
X 			idev->stats.rx_packets++;
X 
X 			skb->dev = &idev->netdev;
@@ -1093,7 +1088,7 @@
X 		}
X 	}
X 	/* Restore bank register */
-	outb( bank, iobase+BSR);
+	outb(bank, iobase+BSR);
X 
X 	return TRUE;
X }
@@ -1109,23 +1104,19 @@
X 	__u8 byte = 0x00;
X 	int iobase;
X 
-	DEBUG( 4, __FUNCTION__ "()\n");
+	DEBUG(4, __FUNCTION__ "()\n");
X 
-	ASSERT( idev != NULL, return;);
-	ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
+	ASSERT(idev != NULL, return;);
+	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
X 	
X 	iobase = idev->io.iobase;
X 	
-	if ( idev->rx_buff.len == 0) {
-		idev->rx_buff.head = idev->rx_buff.data;
-	}
-
X 	/*  Receive all characters in Rx FIFO */
X 	do {
-		byte = inb( iobase+RXD);
-		async_unwrap_char( idev, byte);
+		byte = inb(iobase+RXD);
+		async_unwrap_char(idev, byte);
X 
-	} while ( inb( iobase+LSR) & LSR_RXDA); /* Data available */	
+	} while (inb(iobase+LSR) & LSR_RXDA); /* Data available */	
X }
X 
X /*
@@ -1134,38 +1125,35 @@
X  *    Handle SIR interrupt
X  *
X  */
-static __u8 pc87108_sir_interrupt( struct irda_device *idev, int eir)
+static __u8 pc87108_sir_interrupt(struct irda_device *idev, int eir)
X {
-	int len;
X 	int actual;
X 	__u8 new_ier = 0;
X 
X 	/* Transmit FIFO low on data */
X 	if ( eir & EIR_TXLDL_EV) {
X 		/* Write data left in transmit buffer */
-		len = idev->tx_buff.len - idev->tx_buff.offset;
-
-		ASSERT( len > 0, return 0;);
-		actual = pc87108_pio_write( idev->io.iobase, 
-					    idev->tx_buff.head, 
-					    len, idev->io.fifo_size);
-		idev->tx_buff.offset += actual;
-		idev->tx_buff.head += actual;
+		actual = pc87108_pio_write(idev->io.iobase, 
+					   idev->tx_buff.data, 
+					   idev->tx_buff.len, 
+					   idev->io.fifo_size);
+		idev->tx_buff.data += actual;
+		idev->tx_buff.len  -= actual;
X 		
X 		idev->io.direction = IO_XMIT;
-		ASSERT( actual <= len, return 0;);
X 
X 		/* Check if finished */
-		if ( actual == len) { 
-			DEBUG( 4, __FUNCTION__ "(), finished with frame!\n");
+		if (idev->tx_buff.len > 0)
+			new_ier |= IER_TXLDL_IE;
+		else { 
X 			idev->netdev.tbusy = 0; /* Unlock */
X 			idev->stats.tx_packets++;
-
+			
X 		        mark_bh(NET_BH);	
X 
X 			new_ier |= IER_TXEMP_IE;
-		} else
-			new_ier |= IER_TXLDL_IE;
+		}
+			
X 	}
X 	/* Check if transmission has completed */
X 	if ( eir & EIR_TXEMP_EV) {
diff -u --recursive --new-file v2.2.6/linux/drivers/net/irda/tekram.c linux/drivers/net/irda/tekram.c
--- v2.2.6/linux/drivers/net/irda/tekram.c	Fri Apr 16 14:47:30 1999
+++ linux/drivers/net/irda/tekram.c	Sat Apr 24 17:49:37 1999
@@ -1,12 +1,12 @@
X /*********************************************************************
X  *                
X  * Filename:      tekram.c
- * Version:       0.5
+ * Version:       1.0
X  * Description:   Implementation of the Tekram IrMate IR-210B dongle
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Wed Oct 21 20:02:35 1998
- * Modified at:   Mon Feb 15 14:13:17 1999
+ * Modified at:   Tue Apr 13 16:33:54 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
@@ -33,16 +33,23 @@
X #include <asm/uaccess.h>
X 
X #include <net/irda/irda.h>
-#include <net/irda/irmod.h>
X #include <net/irda/irda_device.h>
X #include <net/irda/irtty.h>
X #include <net/irda/dongle.h>
X 
-static void tekram_reset( struct irda_device *dev, int unused);
-static void tekram_open( struct irda_device *dev, int type);
-static void tekram_close( struct irda_device *dev);
-static void tekram_change_speed( struct irda_device *dev, int baud);
-static void tekram_init_qos( struct irda_device *idev, struct qos_info *qos);
+static void tekram_reset(struct irda_device *dev, int unused);
+static void tekram_open(struct irda_device *dev, int type);
+static void tekram_close(struct irda_device *dev);
+static void tekram_change_speed(struct irda_device *dev, int baud);
+static void tekram_init_qos(struct irda_device *idev, struct qos_info *qos);
+
+#define TEKRAM_115200 0x00
+#define TEKRAM_57600  0x01
+#define TEKRAM_38400  0x02
+#define TEKRAM_19200  0x03
+#define TEKRAM_9600   0x04
+
+#define TEKRAM_PW 0x10 /* Pulse select bit */
X 
X static struct dongle dongle = {
X 	TEKRAM_DONGLE,
@@ -53,9 +60,9 @@
X 	tekram_init_qos,
X };
X 
-__initfunc(void tekram_init(void))
+__initfunc(int tekram_init(void))
X {
-	irtty_register_dongle( &dongle);
+	return irtty_register_dongle(&dongle);
X }
X 
X void tekram_cleanup(void)
@@ -102,17 +109,17 @@
X 	int cflag;
X 	__u8 byte;
X 	
-	DEBUG( 4, __FUNCTION__ "()\n");
+	DEBUG(4, __FUNCTION__ "()\n");
X 
-	ASSERT( dev != NULL, return;);
-	ASSERT( dev->magic == IRDA_DEVICE_MAGIC, return;);
+	ASSERT(dev != NULL, return;);
+	ASSERT(dev->magic == IRDA_DEVICE_MAGIC, return;);
X 	
X 	self = (struct irtty_cb *) dev->priv;
X 	
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRTTY_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IRTTY_MAGIC, return;);
X 	
-	if ( !self->tty)
+	if (!self->tty)
X 		return;
X 
X 	tty = self->tty;
@@ -123,26 +130,27 @@
X 	cflag &= ~CBAUD;
X 
X 	switch (baud) {
-	case 9600:
X 	default:
+		/* FALLTHROUGH */
+	case 9600:
X 		cflag |= B9600;
-		byte = 4;
+		byte = TEKRAM_PW|TEKRAM_9600;
X 		break;
X 	case 19200:
X 		cflag |= B19200;
-		byte = 3;
+		byte = TEKRAM_PW|TEKRAM_19200;
X 		break;
X 	case 34800:
X 		cflag |= B38400;
-		byte = 2;
+		byte = TEKRAM_PW|TEKRAM_38400;
X 		break;
X 	case 57600:
X 		cflag |= B57600;
-		byte = 1;
+		byte = TEKRAM_PW|TEKRAM_57600;
X 		break;
X 	case 115200:
X 		cflag |= B115200;
-		byte = 0;
+		byte = TEKRAM_PW|TEKRAM_115200;
X 		break;
X 	}
X 
@@ -150,22 +158,22 @@
X 	irtty_set_dtr_rts(tty, TRUE, FALSE);
X 	
X 	/* Wait at least 7us */
-	udelay( 7);
+	udelay(7);
X 
X 	/* Write control byte */
-	if ( tty->driver.write)
-		tty->driver.write( self->tty, 0, &byte, 1);
+	if (tty->driver.write)
+		tty->driver.write(self->tty, 0, &byte, 1);
X 	
X 	/* Wait at least 100 ms */
X 	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout( 10);
+	schedule_timeout(MSECS_TO_JIFFIES(100));
X         
X 	/* Set DTR, Set RTS */
X 	irtty_set_dtr_rts(tty, TRUE, TRUE);
X 
X 	/* Now change the speed of the serial port */
X 	tty->termios->c_cflag = cflag;
-	tty->driver.set_termios( tty, &old_termios);	
+	tty->driver.set_termios(tty, &old_termios);	
X }
X 
X /*
@@ -175,30 +183,29 @@
X  *      must be called with a process context!! 
X  *
X  *      Algorithm:
- *    	  0. set RTS and DTR, and wait 50 ms 
- *           ( power off the IR-210 )
+ *    	  0. Clear RTS and DTR, and wait 50 ms (power off the IR-210 )
X  *        1. clear RTS 
X  *        2. set DTR, and wait at least 1 ms 
X  *        3. clear DTR to SPACE state, wait at least 50 us for further 
X  *         operation
X  */
-void tekram_reset( struct irda_device *dev, int unused)
+void tekram_reset(struct irda_device *dev, int unused)
X {
X 	struct irtty_cb *self;
X 	struct tty_struct *tty;
X 
-	DEBUG( 4, __FUNCTION__ "()\n");
+	DEBUG(4, __FUNCTION__ "()\n");
X 
-	ASSERT( dev != NULL, return;);
-	ASSERT( dev->magic == IRDA_DEVICE_MAGIC, return;);
+	ASSERT(dev != NULL, return;);
+	ASSERT(dev->magic == IRDA_DEVICE_MAGIC, return;);
X 	
X 	self = (struct irtty_cb *) dev->priv;
X 	
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRTTY_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IRTTY_MAGIC, return;);
X 
X 	tty = self->tty;
-	if ( !tty)
+	if (!tty)
X 		return;
X 
X 	/* Power off dongle */
@@ -206,18 +213,20 @@
X 
X 	/* Sleep 50 ms */
X 	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(5);
+	schedule_timeout(MSECS_TO_JIFFIES(50));
X 
X 	/* Clear DTR, Set RTS */
X 	irtty_set_dtr_rts(tty, FALSE, TRUE); 
X 
X 	/* Should sleep 1 ms, but 10-20 should not do any harm */
X 	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(2);
+	schedule_timeout(MSECS_TO_JIFFIES(20));
X 
X 	/* Set DTR, Set RTS */
X 	irtty_set_dtr_rts(tty, TRUE, TRUE);
X 	
+	udelay(50);
+
X 	/* Finished! */
X }
X 
@@ -227,10 +236,11 @@
X  *    Initialize QoS capabilities
X  *
X  */
-static void tekram_init_qos( struct irda_device *idev, struct qos_info *qos)
+static void tekram_init_qos(struct irda_device *idev, struct qos_info *qos)
X {
X 	qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
-	qos->min_turn_time.bits &= 0xfe; /* All except 0 ms */
+	qos->min_turn_time.bits &= 0x01; /* Needs at least 10 ms */
+	irda_qos_bits_to_value(qos);
X }
X 
X #ifdef MODULE
@@ -246,8 +256,7 @@
X  */
X int init_module(void)
X {
-	tekram_init();
-	return(0);
+	return tekram_init();
X }
X 
X /*
diff -u --recursive --new-file v2.2.6/linux/drivers/net/irda/uircc.c linux/drivers/net/irda/uircc.c
--- v2.2.6/linux/drivers/net/irda/uircc.c	Fri Apr 16 14:47:30 1999
+++ linux/drivers/net/irda/uircc.c	Sat Apr 24 17:49:37 1999
@@ -7,7 +7,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sat Dec 26 10:59:03 1998
- * Modified at:   Sat Apr  3 15:54:41 1999
+ * Modified at:   Tue Apr 20 11:15:52 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
@@ -190,7 +190,7 @@
X 	
X 	/* The only value we must override it the baudrate */
X 	idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
-		IR_115200|/*IR_576000|IR_1152000| */(IR_4000000 << 8);
+		IR_115200/*IR_576000|IR_1152000 |(IR_4000000 << 8)*/;
X 
X 	idev->qos.min_turn_time.bits = 0x0f;
X 	irda_qos_bits_to_value(&idev->qos);
@@ -372,7 +372,7 @@
X 		DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n");
X 
X 		/* Set self pole address */
-		outb(0x10, iobase+UIRCC_CR8);
+		//outb(0xfe, iobase+UIRCC_CR8);
X 
X 	 	/* outb(0x10, iobase+UIRCC_CR11); */
X 		break;
@@ -443,8 +443,7 @@
X 		skb->len++;
X 
X 	idev->tx_buff.len = skb->len;
-	idev->tx_buff.head = idev->tx_buff.data;
-	idev->tx_buff.offset = 0;
+	idev->tx_buff.data = idev->tx_buff.head;
X 	
X 	mtt = irda_get_mtt(skb);
X 	
@@ -586,11 +585,15 @@
X 	outb(self->cr3, iobase+UIRCC_CR3);
X 
X 	/* Transmit reset (just in case) */
-	outb(UIRCC_CR0_XMIT_RST, iobase+UIRCC_CR0);
+	outb(UIRCC_CR0_XMIT_RST|0x17, iobase+UIRCC_CR0);
X 
X 	/* Set modem */
X 	outb(0x08, iobase+UIRCC_CR10);
X 
+	/* Enable receiving with CRC */
+	self->cr3 = (UIRCC_CR3_RECV_EN|UIRCC_CR3_RX_CRC_EN);
+	outb(self->cr3, iobase+UIRCC_CR3);
+
X 	/* Make sure Rx DMA is set */
X  	outb(UIRCC_CR1_RX_DMA|UIRCC_CR1_MUST_SET, iobase+UIRCC_CR1);
X 
@@ -602,13 +605,13 @@
X 	
X 	/* driver->media_busy = FALSE; */
X 	idev->io.direction = IO_RECV;
-	idev->rx_buff.head = idev->rx_buff.data;
-	idev->rx_buff.offset = 0;
+	idev->rx_buff.data = idev->rx_buff.head;
X 
+#if 0
X 	/* Enable receiving with CRC */
X 	self->cr3 = (UIRCC_CR3_RECV_EN|UIRCC_CR3_RX_CRC_EN);
X 	outb(self->cr3, iobase+UIRCC_CR3);
-
+#endif
X 	DEBUG(4, __FUNCTION__ "(), cr3=%#x\n", self->cr3);
X 	
X 	/* Address check? */
@@ -673,7 +676,7 @@
X /* 	} */
X 
X 	skb_put(skb, len);
-	memcpy(skb->data, idev->rx_buff.head, len);
+	memcpy(skb->data, idev->rx_buff.data, len);
X 	idev->stats.rx_packets++;
X 
X 	skb->dev = &idev->netdev;
@@ -737,7 +740,7 @@
X 		uircc_dma_xmit_complete(idev, FALSE);
X 		uircc_dma_receive(idev);
X 
-		/* outb(0, iobase+UIRCC_CR2);  */
+		outb(0x0d, iobase+UIRCC_CR2);
X 		break;
X 	case UIRCC_SR3_TMR_OUT:
X 		/* Disable timer */
diff -u --recursive --new-file v2.2.6/linux/drivers/net/irda/w83977af_ir.c linux/drivers/net/irda/w83977af_ir.c
--- v2.2.6/linux/drivers/net/irda/w83977af_ir.c	Fri Apr 16 14:47:30 1999
+++ linux/drivers/net/irda/w83977af_ir.c	Sat Apr 24 17:49:37 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Paul VanderSpek
X  * Created at:    Wed Nov  4 11:46:16 1998
- * Modified at:   Wed Apr  7 17:35:59 1999
+ * Modified at:   Tue Apr 20 11:15:00 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Corel Computer Corp.
@@ -482,8 +482,7 @@
X 	if (idev->io.baudrate > 115200) {
X 		memcpy(idev->tx_buff.data, skb->data, skb->len);
X 		idev->tx_buff.len = skb->len;
-		idev->tx_buff.head = idev->tx_buff.data;
-		idev->tx_buff.offset = 0;
+		idev->tx_buff.data = idev->tx_buff.head;
X 		
X 		mtt = irda_get_mtt(skb);
X 	        if (mtt > 50) {
@@ -512,20 +511,18 @@
X 	     		w83977af_dma_write(idev, iobase);
X 		}
X 	} else {
+		idev->tx_buff.data = idev->tx_buff.head;
X 		idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, 
X 						   idev->tx_buff.truesize);
X 		
-		idev->tx_buff.offset = 0;
-		idev->tx_buff.head = idev->tx_buff.data;
-		
X 		/* Add interrupt on tx low level (will fire immediately) */
-		switch_bank( iobase, SET0);
+		switch_bank(iobase, SET0);
X 		outb(ICR_ETXTHI, iobase+ICR);
X 	}
X 	dev_kfree_skb(skb);
X 
X 	/* Restore set register */
-	outb( set, iobase+SSR);
+	outb(set, iobase+SSR);
X 
X 	return 0;
X }
@@ -594,9 +591,9 @@
X 	}
X 
X 	/* Fill FIFO with current frame */
-	while (( fifo_size-- > 0) && (actual < len)) {
+	while ((fifo_size-- > 0) && (actual < len)) {
X 		/* Transmit next byte */
-		outb( buf[actual++], iobase+TBR);
+		outb(buf[actual++], iobase+TBR);
X 	}
X         
X 	DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n", 
@@ -702,8 +699,7 @@
X #endif
X 	/* driver->media_busy = FALSE; */
X 	idev->io.direction = IO_RECV;
-	idev->rx_buff.head = idev->rx_buff.data;
-	idev->rx_buff.offset = 0;
+	idev->rx_buff.data = idev->rx_buff.head;
X 
X 	/* 
X 	 * Reset Rx FIFO. This will also flush the ST_FIFO, it's very 
@@ -751,30 +747,30 @@
X 	__u8 set;
X 	__u8 status;
X 
-	DEBUG( 0, __FUNCTION__ "\n");
+	DEBUG(0, __FUNCTION__ "\n");
X 
X 	iobase = idev->io.iobase;
X 
X 	/* Save current set */
-	set = inb( iobase+SSR);
+	set = inb(iobase+SSR);
X 	
X 	iobase = idev->io.iobase;
X 
X 	switch_bank(iobase, SET5);
-	if ( prev.status & FS_FO_FSFDR) {
+	if (prev.status & FS_FO_FSFDR) {
X 		status = prev.status;
X 		len = prev.len;
-
+		
X 		prev.status = 0;
X 	} else {
-		status = inb( iobase+FS_FO);
-		len = inb( iobase+RFLFL);
-		len |= inb( iobase+RFLFH) << 8;
+		status = inb(iobase+FS_FO);
+		len = inb(iobase+RFLFL);
+		len |= inb(iobase+RFLFH) << 8;
X 	}
X 
-	while ( status & FS_FO_FSFDR) {
+	while (status & FS_FO_FSFDR) {
X 		/* Check for errors */
-		if ( status & FS_FO_ERR_MSK) {
+		if (status & FS_FO_ERR_MSK) {
X 			if ( status & FS_FO_LST_FR) {
X 				/* Add number of lost frames to stats */
X 				idev->stats.rx_errors += len;	
@@ -782,29 +778,28 @@
X 				/* Skip frame */
X 				idev->stats.rx_errors++;
X 				
-				idev->rx_buff.offset += len;
-				idev->rx_buff.head   += len;
+				idev->rx_buff.data += len;
X 				
-				if ( status & FS_FO_MX_LEX)
+				if (status & FS_FO_MX_LEX)
X 					idev->stats.rx_length_errors++;
X 				
-				if ( status & FS_FO_PHY_ERR) 
+				if (status & FS_FO_PHY_ERR) 
X 					idev->stats.rx_frame_errors++;
X 				
-				if ( status & FS_FO_CRC_ERR) 
+				if (status & FS_FO_CRC_ERR) 
X 					idev->stats.rx_crc_errors++;
X 			}
X 			/* The errors below can be reported in both cases */
-			if ( status & FS_FO_RX_OV)
+			if (status & FS_FO_RX_OV)
X 				idev->stats.rx_fifo_errors++;
X 			
-			if ( status & FS_FO_FSF_OV)
+			if (status & FS_FO_FSF_OV)
X 				idev->stats.rx_fifo_errors++;
X 			
X 		} else {
X 			/* Check if we have transfered all data to memory */
X 			switch_bank(iobase, SET0);
-			if ( inb( iobase+USR) & USR_RDR) {
+			if (inb(iobase+USR) & USR_RDR) {
X 				/* Put this entry back in fifo */
X 				prev.status = status;
X 				prev.len = len;
@@ -815,31 +810,30 @@
X 				return FALSE; 	/* I'll be back! */
X 			}
X 						
-			skb = dev_alloc_skb( len+1);
+			skb = dev_alloc_skb(len+1);
X 			if (skb == NULL)  {
-				printk( KERN_INFO __FUNCTION__ 
-					"(), memory squeeze, dropping frame.\n");
+				printk(KERN_INFO __FUNCTION__ 
+				       "(), memory squeeze, dropping frame.\n");
X 				/* Restore set register */
-				outb( set, iobase+SSR);
+				outb(set, iobase+SSR);
X 
X 				return FALSE;
X 			}
X 			
X 			/*  Align to 20 bytes */
-			skb_reserve( skb, 1); 
+			skb_reserve(skb, 1); 
X 			
X 			/* Copy frame without CRC */
X 			if ( idev->io.baudrate < 4000000) {
X 				skb_put( skb, len-2);
-				memcpy( skb->data, idev->rx_buff.head, len-2);
+				memcpy( skb->data, idev->rx_buff.data, len-2);
X 			} else {
X 				skb_put( skb, len-4);
-				memcpy( skb->data, idev->rx_buff.head, len-4);
+				memcpy( skb->data, idev->rx_buff.data, len-4);
X 			}
X 
X 			/* Move to next frame */
-			idev->rx_buff.offset += len;
-			idev->rx_buff.head += len;
+			idev->rx_buff.data += len;
X 			
X 			skb->dev = &idev->netdev;
X 			skb->mac.raw  = skb->data;
@@ -854,7 +848,7 @@
X 		len |= inb( iobase+RFLFH) << 8;
X 	}
X 	/* Restore set register */
-	outb( set, iobase+SSR);
+	outb(set, iobase+SSR);
X 
X 	return TRUE;
X }
@@ -865,28 +859,24 @@
X  *    Receive all data in receiver FIFO
X  *
X  */
-static void w83977af_pio_receive( struct irda_device *idev) 
+static void w83977af_pio_receive(struct irda_device *idev) 
X {
X 	__u8 byte = 0x00;
X 	int iobase;
X 
-	DEBUG( 4, __FUNCTION__ "()\n");
+	DEBUG(4, __FUNCTION__ "()\n");
X 
-	ASSERT( idev != NULL, return;);
-	ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
+	ASSERT(idev != NULL, return;);
+	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
X 	
X 	iobase = idev->io.iobase;
X 	
-	if ( idev->rx_buff.len == 0) {
-		idev->rx_buff.head = idev->rx_buff.data;
-	}
-
X 	/*  Receive all characters in Rx FIFO */
X 	do {
-		byte = inb( iobase+RBR);
-		async_unwrap_char( idev, byte);
+		byte = inb(iobase+RBR);
+		async_unwrap_char(idev, byte);
X 
-	} while ( inb( iobase+USR) & USR_RDR); /* Data available */	
+	} while (inb(iobase+USR) & USR_RDR); /* Data available */	
X }
X 
X /*
@@ -897,7 +887,6 @@
X  */
X static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr)
X {
-	int len;
X 	int actual;
X 	__u8 new_icr = 0;
X 
@@ -906,19 +895,19 @@
X 	/* Transmit FIFO low on data */
X 	if (isr & ISR_TXTH_I) {
X 		/* Write data left in transmit buffer */
-		len = idev->tx_buff.len - idev->tx_buff.offset;
-
-		ASSERT(len > 0, return 0;);
X 		actual = w83977af_pio_write(idev->io.iobase, 
-					    idev->tx_buff.head, 
-					    len, idev->io.fifo_size);
-		idev->tx_buff.offset += actual;
-		idev->tx_buff.head += actual;
+					    idev->tx_buff.data, 
+					    idev->tx_buff.len, 
+					    idev->io.fifo_size);
+		idev->tx_buff.data += actual;
+		idev->tx_buff.len  -= actual;
X 		
X 		idev->io.direction = IO_XMIT;
-		ASSERT( actual <= len, return 0;);
+
X 		/* Check if finished */
-		if ( actual == len) { 
+		if (idev->tx_buff.len > 0)
+			new_icr |= ICR_ETXTHI;
+		else { 
X 			DEBUG( 4, __FUNCTION__ "(), finished with frame!\n");
X 			idev->netdev.tbusy = 0; /* Unlock */
X 			idev->stats.tx_packets++;
@@ -927,8 +916,8 @@
X 		        mark_bh(NET_BH);	
X 
X 			new_icr |= ICR_ETBREI;
-		} else
-			new_icr |= ICR_ETXTHI;
+		}
+		
X 	}
X 	/* Check if transmission has completed */
X 	if (isr & ISR_TXEMP_I) {
diff -u --recursive --new-file v2.2.6/linux/drivers/net/net_init.c linux/drivers/net/net_init.c
--- v2.2.6/linux/drivers/net/net_init.c	Tue Dec 22 14:16:55 1998
+++ linux/drivers/net/net_init.c	Sat Apr 24 17:51:48 1999
@@ -252,6 +252,22 @@
X 	return dev;
X }
X 
+
+void unregister_hipdev(struct device *dev)
+{
+	int i;
+	rtnl_lock();
+	unregister_netdevice(dev);
+	for (i = 0; i < MAX_HIP_CARDS; ++i) {
+		if (hipdev_index[i] == dev) {
+			hipdev_index[i] = NULL;
+			break;
+		}
+	}
+	rtnl_unlock();
+}
+
+
X static int hippi_neigh_setup_dev(struct device *dev, struct neigh_parms *p)
X {
X 	/* Never send broadcast/multicast ARP messages */
diff -u --recursive --new-file v2.2.6/linux/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c
--- v2.2.6/linux/drivers/net/pcnet32.c	Tue Jan 19 11:32:51 1999
+++ linux/drivers/net/pcnet32.c	Sat Apr 24 17:51:48 1999
@@ -13,7 +13,7 @@
X  * 	This driver is for PCnet32 and PCnetPCI based ethercards
X  */
X 
-static const char *version = "pcnet32.c:v1.11 17.1.99 tsbo...@alpha.franken.de\n";
+static const char *version = "pcnet32.c:v1.21 31.3.99 tsbo...@alpha.franken.de\n";
X 
X #include <linux/config.h>
X #include <linux/module.h>
@@ -58,9 +58,36 @@
X 
X #define PORT_PORTSEL  0x03
X #define PORT_ASEL     0x04
+#define PORT_100      0x40
X #define PORT_FD       0x80
X 
-static int options = PORT_ASEL;  /* port selection */
+
+/*
+ * table to translate option values from tulip
+ * to internal options
+ */
+static unsigned char options_mapping[] = {
+    PORT_ASEL,			   /*  0 Auto-select      */
+    PORT_AUI,			   /*  1 BNC/AUI          */
+    PORT_AUI,			   /*  2 AUI/BNC          */ 
+    PORT_ASEL,			   /*  3 not supported    */
+    PORT_10BT | PORT_FD,	   /*  4 10baseT-FD       */
+    PORT_ASEL,			   /*  5 not supported    */
+    PORT_ASEL,			   /*  6 not supported    */
+    PORT_ASEL,			   /*  7 not supported    */
+    PORT_ASEL,			   /*  8 not supported    */
+    PORT_MII,		           /*  9 MII 10baseT      */
+    PORT_MII | PORT_FD,            /* 10 MII 10baseT-FD   */
+    PORT_MII,			   /* 11 MII (autosel)    */
+    PORT_10BT,			   /* 12 10BaseT	  */
+    PORT_MII | PORT_100,	   /* 13 MII 100BaseTx    */
+    PORT_MII | PORT_100 | PORT_FD, /* 14 MII 100BaseTx-FD */
+    PORT_ASEL			   /* 15 not supported    */
+};
+
+#define MAX_UNITS 8
+static int options[MAX_UNITS] = {0, };
+static int full_duplex[MAX_UNITS] = {0, };
X 
X /*
X  * 				Theory of Operation
@@ -116,6 +143,12 @@
X  *         added port selection for modules
X  *         detect special T1/E1 WAN card and setup port selection
X  * v1.11:  fixed wrong checking of Tx errors
+ * v1.20:  added check of return value kmalloc (cpet...@cs.washington.edu)
+ *         added save original kmalloc addr for freeing (m...@solidum.com)
+ *         added support for PCnetHome chip (j...@MIT.EDU)
+ *         rewritten PCI card detection
+ *         added dwio mode to get driver working on some PPC machines
+ * v1.21:  added mii selection and mii ioctl
X  */
X 
X 
@@ -140,202 +173,402 @@
X #define PKT_BUF_SZ		1544
X 
X /* Offsets from base I/O address. */
-#define PCNET32_DATA 0x10
-#define PCNET32_ADDR 0x12
-#define PCNET32_RESET 0x14
-#define PCNET32_BUS_IF 0x16
-#define PCNET32_TOTAL_SIZE 0x18
+#define PCNET32_WIO_RDP		0x10
+#define PCNET32_WIO_RAP		0x12
+#define PCNET32_WIO_RESET	0x14
+#define PCNET32_WIO_BDP		0x16
+
+#define PCNET32_DWIO_RDP	0x10
+#define PCNET32_DWIO_RAP	0x14
+#define PCNET32_DWIO_RESET	0x18
+#define PCNET32_DWIO_BDP	0x1C
+
+#define PCNET32_TOTAL_SIZE 0x20
X 
X #define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
X 
X /* The PCNET32 Rx and Tx ring descriptors. */
X struct pcnet32_rx_head {
-	u32 base;
-	s16 buf_length;
-        s16 status;    
-	u32 msg_length;
-	u32 reserved;
+    u32 base;
+    s16 buf_length;
+    s16 status;    
+    u32 msg_length;
+    u32 reserved;
X };
X 	
X struct pcnet32_tx_head {
-	u32 base;
-	s16 length;
-        s16 status;
-	u32 misc;
-	u32 reserved;
+    u32 base;
+    s16 length;
+    s16 status;
+    u32 misc;
+    u32 reserved;
X };
X 
-
X /* The PCNET32 32-Bit initialization block, described in databook. */
X struct pcnet32_init_block {
-	u16 mode;
-	u16 tlen_rlen;
-	u8  phys_addr[6];
-	u16 reserved;
-	u32 filter[2];
-	/* Receive and transmit ring base, along with extra bits. */    
-	u32 rx_ring;
-	u32 tx_ring;
+    u16 mode;
+    u16 tlen_rlen;
+    u8  phys_addr[6];
+    u16 reserved;
+    u32 filter[2];
+    /* Receive and transmit ring base, along with extra bits. */    
+    u32 rx_ring;
+    u32 tx_ring;
+};
+
+/* PCnet32 access functions */
+struct pcnet32_access {
+    u16 (*read_csr)(unsigned long, int);
+    void (*write_csr)(unsigned long, int, u16);
+    u16 (*read_bcr)(unsigned long, int);
+    void (*write_bcr)(unsigned long, int, u16);
+    u16 (*read_rap)(unsigned long);
+    void (*write_rap)(unsigned long, u16);
+    void (*reset)(unsigned long);
X };
X 
X struct pcnet32_private {
-	/* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
-	struct pcnet32_rx_head   rx_ring[RX_RING_SIZE];
-	struct pcnet32_tx_head   tx_ring[TX_RING_SIZE];
-	struct pcnet32_init_block	init_block;
-	const char *name;
-	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
-	struct sk_buff *tx_skbuff[TX_RING_SIZE];
-        struct sk_buff *rx_skbuff[RX_RING_SIZE];
-	int cur_rx, cur_tx;			/* The next free ring entry */
-	int dirty_rx, dirty_tx;		        /* The ring entries to be free()ed. */
-	struct net_device_stats stats;
-	char tx_full;
-        int  options;
-        int  shared_irq:1,                      /* shared irq possible */
-             full_duplex:1;                     /* full duplex possible */
+    /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
+    struct pcnet32_rx_head   rx_ring[RX_RING_SIZE];
+    struct pcnet32_tx_head   tx_ring[TX_RING_SIZE];
+    struct pcnet32_init_block	init_block;
+    const char *name;
+    /* The saved address of a sent-in-place packet/buffer, for skfree(). */
+    struct sk_buff *tx_skbuff[TX_RING_SIZE];
+    struct sk_buff *rx_skbuff[RX_RING_SIZE];
+    struct pcnet32_access a;
+    void *origmem;
+    int cur_rx, cur_tx;			/* The next free ring entry */
+    int dirty_rx, dirty_tx;		        /* The ring entries to be free()ed. */
+    struct net_device_stats stats;
+    char tx_full;
+    int  options;
+    int  shared_irq:1,                      /* shared irq possible */
+         full_duplex:1,                     /* full duplex possible */
+         mii:1;                             /* mii port available */
X #ifdef MODULE
-        struct device *next;
+    struct device *next;
X #endif    
X };
X 
-int  pcnet32_probe(struct device *dev);
-static int  pcnet32_probe1(struct device *dev, unsigned int ioaddr, unsigned char irq_line, int shared);
-static int  pcnet32_open(struct device *dev);
-static int  pcnet32_init_ring(struct device *dev);
-static int  pcnet32_start_xmit(struct sk_buff *skb, struct device *dev);
-static int  pcnet32_rx(struct device *dev);
-static void pcnet32_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static int  pcnet32_close(struct device *dev);
-static struct net_device_stats *pcnet32_get_stats(struct device *dev);
-static void pcnet32_set_multicast_list(struct device *dev);
+int  pcnet32_probe(struct device *);
+static int  pcnet32_probe1(struct device *, unsigned long, unsigned char, int, int);
+static int  pcnet32_open(struct device *);
+static int  pcnet32_init_ring(struct device *);
+static int  pcnet32_start_xmit(struct sk_buff *, struct device *);
+static int  pcnet32_rx(struct device *);
+static void pcnet32_interrupt(int, void *, struct pt_regs *);
+static int  pcnet32_close(struct device *);
+static struct net_device_stats *pcnet32_get_stats(struct device *);
+static void pcnet32_set_multicast_list(struct device *);
+#ifdef HAVE_PRIVATE_IOCTL
+static int  pcnet32_mii_ioctl(struct device *, struct ifreq *, int);
+#endif
+
+enum pci_flags_bit {
+    PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
+    PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
+};
+
+struct pcnet32_pci_id_info {
+    const char *name;
+    u16 vendor_id, device_id, device_id_mask, flags;
+    int io_size;
+    int (*probe1) (struct device *, unsigned long, unsigned char, int, int);
+};
+
+static struct pcnet32_pci_id_info pcnet32_tbl[] = {
+    { "AMD PCnetPCI series",
+	0x1022, 0x2000, 0xfffe, PCI_USES_IO|PCI_USES_MASTER, PCNET32_TOTAL_SIZE,
+	pcnet32_probe1},
+    {0,}
+};
+
+static u16 pcnet32_wio_read_csr (unsigned long addr, int index)
+{
+    outw (index, addr+PCNET32_WIO_RAP);
+    return inw (addr+PCNET32_WIO_RDP);
+}
+
+static void pcnet32_wio_write_csr (unsigned long addr, int index, u16 val)
+{
+    outw (index, addr+PCNET32_WIO_RAP);
+    outw (val, addr+PCNET32_WIO_RDP);
+}
+
+static u16 pcnet32_wio_read_bcr (unsigned long addr, int index)
+{
+    outw (index, addr+PCNET32_WIO_RAP);
+    return inw (addr+PCNET32_WIO_BDP);
+}
+
+static void pcnet32_wio_write_bcr (unsigned long addr, int index, u16 val)
+{
+    outw (index, addr+PCNET32_WIO_RAP);
+    outw (val, addr+PCNET32_WIO_BDP);
+}
+
+static u16 pcnet32_wio_read_rap (unsigned long addr)
+{
+    return inw (addr+PCNET32_WIO_RAP);
+}
+
+static void pcnet32_wio_write_rap (unsigned long addr, u16 val)
+{
+    outw (val, addr+PCNET32_WIO_RAP);
+}
+
+static void pcnet32_wio_reset (unsigned long addr)
+{
+    inw (addr+PCNET32_WIO_RESET);
+}
+
+static int pcnet32_wio_check (unsigned long addr)
+{
+    outw (88, addr+PCNET32_WIO_RAP);
+    return (inw (addr+PCNET32_WIO_RAP) == 88);
+}
+
+static struct pcnet32_access pcnet32_wio = {
+    pcnet32_wio_read_csr,
+    pcnet32_wio_write_csr,
+    pcnet32_wio_read_bcr,
+    pcnet32_wio_write_bcr,
+    pcnet32_wio_read_rap,
+    pcnet32_wio_write_rap,
+    pcnet32_wio_reset
+};
+
+static u16 pcnet32_dwio_read_csr (unsigned long addr, int index)
+{
+    outl (index, addr+PCNET32_DWIO_RAP);
+    return (inl (addr+PCNET32_DWIO_RDP) & 0xffff);
+}
+
+static void pcnet32_dwio_write_csr (unsigned long addr, int index, u16 val)
+{
+    outl (index, addr+PCNET32_DWIO_RAP);
+    outl (val, addr+PCNET32_DWIO_RDP);
+}
+
+static u16 pcnet32_dwio_read_bcr (unsigned long addr, int index)
+{
+    outl (index, addr+PCNET32_DWIO_RAP);
+    return (inl (addr+PCNET32_DWIO_BDP) & 0xffff);
+}
+
+static void pcnet32_dwio_write_bcr (unsigned long addr, int index, u16 val)
+{
+    outl (index, addr+PCNET32_DWIO_RAP);
+    outl (val, addr+PCNET32_DWIO_BDP);
+}
+
+static u16 pcnet32_dwio_read_rap (unsigned long addr)
+{
+    return (inl (addr+PCNET32_DWIO_RAP) & 0xffff);
+}
+
+static void pcnet32_dwio_write_rap (unsigned long addr, u16 val)
+{
+    outl (val, addr+PCNET32_DWIO_RAP);
+}
+
+static void pcnet32_dwio_reset (unsigned long addr)
+{
+    inl (addr+PCNET32_DWIO_RESET);
+}
+
+static int pcnet32_dwio_check (unsigned long addr)
+{
+    outl (88, addr+PCNET32_DWIO_RAP);
+    return (inl (addr+PCNET32_DWIO_RAP) == 88);
+}
+
+static struct pcnet32_access pcnet32_dwio = {
+    pcnet32_dwio_read_csr,
+    pcnet32_dwio_write_csr,
+    pcnet32_dwio_read_bcr,
+    pcnet32_dwio_write_bcr,
+    pcnet32_dwio_read_rap,
+    pcnet32_dwio_write_rap,
+    pcnet32_dwio_reset
+
+};
X 
X 
X 
-__initfunc(int pcnet32_probe (struct device *dev))
+int __init pcnet32_probe (struct device *dev)
X {
-    unsigned int  ioaddr = dev ? dev->base_addr: 0;
+    unsigned long ioaddr = dev ? dev->base_addr: 0;
X     unsigned int  irq_line = dev ? dev->irq : 0;
X     int *port;
+    int cards_found = 0;
X     
-    if (ioaddr > 0x1ff)
-      return pcnet32_probe1(dev, ioaddr, irq_line, 0);
-    else if(ioaddr != 0)
-      return ENXIO;
+    
+#ifndef __powerpc__
+    if (ioaddr > 0x1ff) {
+	if (check_region(ioaddr, PCNET32_TOTAL_SIZE) == 0)
+	    return pcnet32_probe1(dev, ioaddr, irq_line, 0, 0);
+	else
+	    return ENODEV;
+    } else
+#endif
+	if(ioaddr != 0)
+	    return ENXIO;
X     
X #if defined(CONFIG_PCI)
X     if (pci_present()) {
-	struct pci_dev *pdev = NULL;
+	struct pci_dev *pdev;
+	unsigned char pci_bus, pci_device_fn;
+	int pci_index;
X 	
X 	printk("pcnet32.c: PCI bios is present, checking for devices...\n");
-	while ((pdev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, pdev))) {
-	    unsigned short pci_command;
+	for (pci_index = 0; pci_index < 0xff; pci_index++) {
+	    u16 vendor, device, pci_command;
+	    int chip_idx;
X 
-	    irq_line = pdev->irq;
+	    if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,
+				    pci_index, &pci_bus, &pci_device_fn) != PCIBIOS_SUCCESSFUL)
+		break;
+	    
+	    pcibios_read_config_word(pci_bus, pci_device_fn, PCI_VENDOR_ID, &vendor);
+	    pcibios_read_config_word(pci_bus, pci_device_fn, PCI_DEVICE_ID, &device);
+
+	    for (chip_idx = 0; pcnet32_tbl[chip_idx].vendor_id; chip_idx++)
+		if (vendor == pcnet32_tbl[chip_idx].vendor_id &&
+		    (device & pcnet32_tbl[chip_idx].device_id_mask) == pcnet32_tbl[chip_idx].device_id)
+		    break;
+	    if (pcnet32_tbl[chip_idx].vendor_id == 0)
+		continue;
+	    
+	    pdev = pci_find_slot(pci_bus, pci_device_fn);
X 	    ioaddr = pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;
+#if defined(ADDR_64BITS) && defined(__alpha__)
+	    ioaddr |= ((long)pdev->base_address[1]) << 32;
+#endif
+	    irq_line = pdev->irq;
+	    
+	    /* Avoid already found cards from previous pcnet32_probe() calls */
+	    if ((pcnet32_tbl[chip_idx].flags & PCI_USES_IO) &&
+		check_region(ioaddr, pcnet32_tbl[chip_idx].io_size))
+		continue;
+
X 	    /* PCI Spec 2.1 states that it is either the driver or PCI card's
X 	     * responsibility to set the PCI Master Enable Bit if needed.
X 	     *	(From Mark Stockton <ma...@schooner.sys.hou.compaq.com>)
X 	     */
X 	    pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-	    
-	    /* Avoid already found cards from previous pcnet32_probe() calls */
-	    if (check_region(ioaddr, PCNET32_TOTAL_SIZE))
-	      continue;
-
X 	    if ( ! (pci_command & PCI_COMMAND_MASTER)) {
X 		printk("PCI Master Bit has not been set. Setting...\n");
X 		pci_command |= PCI_COMMAND_MASTER|PCI_COMMAND_IO;
X 		pci_write_config_word(pdev, PCI_COMMAND, pci_command);
X 	    }
+	    printk("Found PCnet/PCI at %#lx, irq %d.\n", ioaddr, irq_line);
X 	    
-	    printk("Found PCnet/PCI at %#x, irq %d.\n",
-		   ioaddr, irq_line);
-	    
-	    if (pcnet32_probe1(dev, ioaddr, irq_line, 1) != 0) {	/* Shouldn't happen. */
-		printk(KERN_ERR "pcnet32.c: Probe of PCI card at %#x failed.\n", ioaddr);
-		break;
+	    if (pcnet32_tbl[chip_idx].probe1(dev, ioaddr, irq_line, 1, cards_found) == 0) {
+		cards_found++;
+		dev = NULL;
X 	    }
-	    return 0;
X 	}
X     } else 
X #endif  /* defined(CONFIG_PCI) */
X     
X     /* now look for PCnet32 VLB cards */
X     for (port = pcnet32_portlist; *port; port++) {
-	unsigned int ioaddr = *port;
+	unsigned long ioaddr = *port;
X 	
X 	if ( check_region(ioaddr, PCNET32_TOTAL_SIZE) == 0) {
X     	    /* check if there is really a pcnet chip on that ioaddr */
X     	    if ((inb(ioaddr + 14) == 0x57) &&
X 		(inb(ioaddr + 15) == 0x57) &&
-	        (pcnet32_probe1(dev, ioaddr, 0, 0) == 0))
-	      return 0;
+	        (pcnet32_probe1(dev, ioaddr, 0, 0, 0) == 0))
+		cards_found++;
X 	}
X     }
-    return ENODEV;
+    return cards_found ? 0: ENODEV;
X }
X 
X 
X /* pcnet32_probe1 */
-__initfunc(static int pcnet32_probe1(struct device *dev, unsigned int ioaddr, unsigned char irq_line, int shared))
+static int __init
+pcnet32_probe1(struct device *dev, unsigned long ioaddr, unsigned char irq_line, int shared, int card_idx)
X {
X     struct pcnet32_private *lp;
-    int i,full_duplex = 0;
+    int i,media,fdx = 0, mii = 0;
+    int chip_version;
X     char *chipname;
+    char *priv;
+    struct pcnet32_access *a;
X 
-    inw(ioaddr+PCNET32_RESET); /* Reset the PCNET32 */
+    /* reset the chip */
+    pcnet32_dwio_reset(ioaddr);
+    pcnet32_wio_reset(ioaddr);
+
+    if (pcnet32_wio_read_csr (ioaddr, 0) == 4 && pcnet32_wio_check (ioaddr)) {
+	a = &pcnet32_wio;
+    } else {
+	if (pcnet32_dwio_read_csr (ioaddr, 0) == 4 && pcnet32_dwio_check(ioaddr)) {
+	    a = &pcnet32_dwio;
+	} else
+	    return ENODEV;
+    }
X 
-    outw(0x0000, ioaddr+PCNET32_ADDR); /* Switch to window 0 */
-    if (inw(ioaddr+PCNET32_DATA) != 0x0004)
-      return ENODEV;
-
-    /* Get the version of the chip. */
-    outw(88, ioaddr+PCNET32_ADDR);
-    if (inw(ioaddr+PCNET32_ADDR) != 88) {
-	/* should never happen */
+    chip_version = a->read_csr (ioaddr, 88) | (a->read_csr (ioaddr,89) << 16);
+    if (pcnet32_debug > 2)
+	printk("  PCnet chip version is %#x.\n", chip_version);
+    if ((chip_version & 0xfff) != 0x003)
X 	return ENODEV;
-    } else {			/* Good, it's a newer chip. */
-	int chip_version = inw(ioaddr+PCNET32_DATA);
-	outw(89, ioaddr+PCNET32_ADDR);
-	chip_version |= inw(ioaddr+PCNET32_DATA) << 16;
+    chip_version = (chip_version >> 12) & 0xffff;
+    switch (chip_version) {
+     case 0x2420:
+	chipname = "PCnet/PCI 79C970";
+	break;
+     case 0x2430:
+	if (shared)
+	    chipname = "PCnet/PCI 79C970"; /* 970 gives the wrong chip id back */
+	else
+	    chipname = "PCnet/32 79C965";
+	break;
+     case 0x2621:
+	chipname = "PCnet/PCI II 79C970A";
+	fdx = 1;
+	break;
+     case 0x2623:
+	chipname = "PCnet/FAST 79C971";
+	fdx = 1; mii = 1;
+	break;
+     case 0x2624:
+	chipname = "PCnet/FAST+ 79C972";
+	fdx = 1; mii = 1;
+	break;
+     case 0x2626:
+	chipname = "PCnet/Home 79C978";
+	fdx = 1;
+	/* 
+	 * This is based on specs published at www.amd.com.  This section
+	 * assumes that a card with a 79C978 wants to go into 1Mb HomePNA
+	 * mode.  The 79C978 can also go into standard ethernet, and there
+	 * probably should be some sort of module option to select the
+	 * mode by which the card should operate
+	 */
+	/* switch to home wiring mode */
+	media = a->read_bcr (ioaddr, 49);
X 	if (pcnet32_debug > 2)
-	  printk("  PCnet chip version is %#x.\n", chip_version);
-	if ((chip_version & 0xfff) != 0x003)
-	  return ENODEV;
-	chip_version = (chip_version >> 12) & 0xffff;
-	switch (chip_version) {
-	 case 0x2420:
-	    chipname = "PCnet/PCI 79C970";
-	    break;
-	 case 0x2430:
-	    if (shared)
-		chipname = "PCnet/PCI 79C970"; /* 970 gives the wrong chip id back */
-	    else
-		chipname = "PCnet/32 79C965";
-	    break;
-	 case 0x2621:
-	    chipname = "PCnet/PCI II 79C970A";
-	    full_duplex = 1;
-	    break;
-	 case 0x2623:
-	    chipname = "PCnet/FAST 79C971";
-	    full_duplex = 1;
-	    break;
-	 case 0x2624:
-	    chipname = "PCnet/FAST+ 79C972";
-	    full_duplex = 1;
-	    break;
-	 default:
-	    printk("pcnet32: PCnet version %#x, no PCnet32 chip.\n",chip_version);
-	    return ENODEV;
-	}
+	    printk("pcnet32: pcnet32 media value %#x.\n",  media);
+	media &= ~3;
+	media |= 1;
+	if (pcnet32_debug > 2)
+	    printk("pcnet32: pcnet32 media reset to %#x.\n",  media);
+	a->write_bcr (ioaddr, 49, media);
+	break;
+     default:
+	printk("pcnet32: PCnet version %#x, no PCnet32 chip.\n",chip_version);
+	return ENODEV;
X     }
X     
-    if (dev == NULL)
-	dev = init_etherdev(0, 0);
+    dev = init_etherdev(dev, 0);
X 
-    printk("%s: %s at %#3x,", dev->name, chipname, ioaddr);
+    printk(KERN_INFO "%s: %s at %#3lx,", dev->name, chipname, ioaddr);
X 
X     /* There is a 16 byte station address PROM at the base address.
X      The first six bytes are the station address. */
@@ -345,15 +578,31 @@
X     dev->base_addr = ioaddr;
X     request_region(ioaddr, PCNET32_TOTAL_SIZE, chipname);
X     
-    /* Make certain the data structures used by the PCnet32 are 16byte aligned and DMAble. */
-    lp = (struct pcnet32_private *) (((unsigned long)kmalloc(sizeof(*lp)+15, GFP_DMA | GFP_KERNEL)+15) & ~15);
+    if ((priv = kmalloc(sizeof(*lp)+15,GFP_KERNEL)) == NULL)
+	return ENOMEM;
+
+    /*
+     * Make certain the data structures used by
+     * the PCnet32 are 16byte aligned
+      */
+    lp = (struct pcnet32_private *)(((unsigned long)priv+15) & ~15);
X       
X     memset(lp, 0, sizeof(*lp));
X     dev->priv = lp;
X     lp->name = chipname;
X     lp->shared_irq = shared;
-    lp->full_duplex = full_duplex;
-    lp->options = options;
+    lp->full_duplex = fdx;
+    lp->mii = mii;
+    if (options[card_idx] > sizeof (options_mapping))
+	lp->options = PORT_ASEL;
+    else
+	lp->options = options_mapping[options[card_idx]];
+    
+    if (fdx && !(lp->options & PORT_ASEL) && full_duplex[card_idx])
+	lp->options |= PORT_FD;
+    
+    lp->origmem = priv;
+    lp->a = *a;
X     
X     /* detect special T1/E1 WAN card by checking for MAC address */
X     if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0 && dev->dev_addr[2] == 0x75)
@@ -369,24 +618,17 @@
X     lp->init_block.tx_ring = (u32)le32_to_cpu(virt_to_bus(lp->tx_ring));
X     
X     /* switch pcnet32 to 32bit mode */
-    outw(0x0014, ioaddr+PCNET32_ADDR);
-    outw(0x0002, ioaddr+PCNET32_BUS_IF);
+    a->write_bcr (ioaddr, 20, 2);
X 
-    outw(0x0001, ioaddr+PCNET32_ADDR);
-    inw(ioaddr+PCNET32_ADDR);
-    outw(virt_to_bus(&lp->init_block) & 0xffff, ioaddr+PCNET32_DATA);
-    outw(0x0002, ioaddr+PCNET32_ADDR);
-    inw(ioaddr+PCNET32_ADDR);
-    outw(virt_to_bus(&lp->init_block) >> 16, ioaddr+PCNET32_DATA);
-    outw(0x0000, ioaddr+PCNET32_ADDR);
-    inw(ioaddr+PCNET32_ADDR);
+    a->write_csr (ioaddr, 1, virt_to_bus(&lp->init_block) & 0xffff);
+    a->write_csr (ioaddr, 2, virt_to_bus(&lp->init_block) >> 16);
X     
X     if (irq_line) {
X 	dev->irq = irq_line;
X     }
X     
X     if (dev->irq >= 2)
-      printk(" assigned IRQ %d.\n", dev->irq);
+	printk(" assigned IRQ %d.\n", dev->irq);
X     else {
X 	unsigned long irq_mask = probe_irq_on();
X 	
@@ -396,7 +638,7 @@
X 	 * boards will work.
X 	 */
X 	/* Trigger an initialization just for the interrupt. */
-	outw(0x0041, ioaddr+PCNET32_DATA);
+	a->write_csr (ioaddr, 0, 0x41);
X 	mdelay (1);
X 	
X 	dev->irq = probe_irq_off (irq_mask);
@@ -409,7 +651,7 @@
X     }
X 
X     if (pcnet32_debug > 0)
-      printk(version);
+	printk(version);
X     
X     /* The PCNET32-specific entries in the device structure. */
X     dev->open = &pcnet32_open;
@@ -417,6 +659,10 @@
X     dev->stop = &pcnet32_close;
X     dev->get_stats = &pcnet32_get_stats;
X     dev->set_multicast_list = &pcnet32_set_multicast_list;
+#ifdef HAVE_PRIVATE_IOCTL
+    dev->do_ioctl = &pcnet32_mii_ioctl;
+#endif
+
X     
X #ifdef MODULE
X     lp->next = pcnet32_dev;
@@ -432,95 +678,96 @@
X static int
X pcnet32_open(struct device *dev)
X {
-	struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
-	unsigned int ioaddr = dev->base_addr;
-        unsigned short val;
-	int i;
-
-	if (dev->irq == 0 ||
-		request_irq(dev->irq, &pcnet32_interrupt,
-			    lp->shared_irq ? SA_SHIRQ : 0, lp->name, (void *)dev)) {
-		return -EAGAIN;
-	}
+    struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+    u16 val;
+    int i;
+
+    if (dev->irq == 0 ||
+	request_irq(dev->irq, &pcnet32_interrupt,
+		    lp->shared_irq ? SA_SHIRQ : 0, lp->name, (void *)dev)) {
+	return -EAGAIN;
+    }
X 
-	/* Reset the PCNET32 */
-	inw(ioaddr+PCNET32_RESET);
+    /* Reset the PCNET32 */
+    lp->a.reset (ioaddr);
X 
-	/* switch pcnet32 to 32bit mode */
-	outw(0x0014, ioaddr+PCNET32_ADDR);
-	outw(0x0002, ioaddr+PCNET32_BUS_IF);
-
-	if (pcnet32_debug > 1)
-		printk("%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n",
-			   dev->name, dev->irq,
-		           (u32) virt_to_bus(lp->tx_ring),
-		           (u32) virt_to_bus(lp->rx_ring),
-			   (u32) virt_to_bus(&lp->init_block));
-    
-        /* set/reset autoselect bit */
-    	outw(0x0002, ioaddr+PCNET32_ADDR);
-        val = inw(ioaddr+PCNET32_BUS_IF) & ~2;
-        if (lp->options & PORT_ASEL)
-	        val |= 2;
-        outw(val, ioaddr+PCNET32_BUS_IF);
-
-        /* handle full duplex setting */
-        if (lp->full_duplex) {
-	    outw (0x0009, ioaddr+PCNET32_ADDR);
-	    val = inw(ioaddr+PCNET32_BUS_IF) & ~3;
-	    if (lp->options & PORT_FD) {
-		val |= 1;
-		if (lp->options == (PORT_FD | PORT_AUI))
-		    val |= 2;
-	    }
-	    outw(val, ioaddr+PCNET32_BUS_IF);
+    /* switch pcnet32 to 32bit mode */
+    lp->a.write_csr (ioaddr, 20, 2);
+
+    if (pcnet32_debug > 1)
+	printk("%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n",
+	       dev->name, dev->irq,
+	       (u32) virt_to_bus(lp->tx_ring),
+	       (u32) virt_to_bus(lp->rx_ring),
+	       (u32) virt_to_bus(&lp->init_block));
+    
+    /* set/reset autoselect bit */
+    val = lp->a.read_bcr (ioaddr, 2) & ~2;
+    if (lp->options & PORT_ASEL)
+	val |= 2;
+    lp->a.write_bcr (ioaddr, 2, val);
+    
+    /* handle full duplex setting */
+    if (lp->full_duplex) {
+	val = lp->a.read_bcr (ioaddr, 9) & ~3;
+	if (lp->options & PORT_FD) {
+	    val |= 1;
+	    if (lp->options == (PORT_FD | PORT_AUI))
+		val |= 2;
X 	}
+	lp->a.write_bcr (ioaddr, 9, val);
+    }
X     
-        /* set/reset GPSI bit in test register */
-        outw (0x007c, ioaddr+PCNET32_ADDR);
-        val = inw(ioaddr+PCNET32_DATA) & ~0x10;
-        if ((lp->options & PORT_PORTSEL) == PORT_GPSI)
-	        val |= 0x10;
-    	outw(val, ioaddr+PCNET32_DATA);
-	    
-	lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7);
-	lp->init_block.filter[0] = 0x00000000;
-	lp->init_block.filter[1] = 0x00000000;
-	if (pcnet32_init_ring(dev))
-		return -ENOMEM;
-    
-	/* Re-initialize the PCNET32, and start it when done. */
-	outw(0x0001, ioaddr+PCNET32_ADDR);
-	outw(virt_to_bus(&lp->init_block) &0xffff, ioaddr+PCNET32_DATA);
-	outw(0x0002, ioaddr+PCNET32_ADDR);
-	outw(virt_to_bus(&lp->init_block) >> 16, ioaddr+PCNET32_DATA);
-
-	outw(0x0004, ioaddr+PCNET32_ADDR);
-	outw(0x0915, ioaddr+PCNET32_DATA);
-
-	outw(0x0000, ioaddr+PCNET32_ADDR);
-	outw(0x0001, ioaddr+PCNET32_DATA);
-
-	dev->tbusy = 0;
-	dev->interrupt = 0;
-	dev->start = 1;
-	i = 0;
-	while (i++ < 100)
-		if (inw(ioaddr+PCNET32_DATA) & 0x0100)
-			break;
-	/* 
-	 * We used to clear the InitDone bit, 0x0100, here but Mark Stockton
-	 * reports that doing so triggers a bug in the '974.
-	 */
- 	outw(0x0042, ioaddr+PCNET32_DATA);
-
-	if (pcnet32_debug > 2)
-		printk("%s: PCNET32 open after %d ticks, init block %#x csr0 %4.4x.\n",
-			   dev->name, i, (u32) virt_to_bus(&lp->init_block), inw(ioaddr+PCNET32_DATA));
+    /* set/reset GPSI bit in test register */
+    val = lp->a.read_csr (ioaddr, 124) & ~0x10;
+    if ((lp->options & PORT_PORTSEL) == PORT_GPSI)
+	val |= 0x10;
+    lp->a.write_csr (ioaddr, 124, val);
+    
+    if (lp->mii & (lp->options & PORT_ASEL)) {
+	val = lp->a.read_bcr (ioaddr, 32) & ~0x38; /* disable Auto Negotiation, set 10Mpbs, HD */
+	if (lp->options & PORT_FD)
+	    val |= 0x10;
+	if (lp->options & PORT_100)
+	    val |= 0x08;
+	lp->a.write_bcr (ioaddr, 32, val);
+    }
+    
+    lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7);
+    lp->init_block.filter[0] = 0x00000000;
+    lp->init_block.filter[1] = 0x00000000;
+    if (pcnet32_init_ring(dev))
+	return -ENOMEM;
+    
+    /* Re-initialize the PCNET32, and start it when done. */
+    lp->a.write_csr (ioaddr, 1, virt_to_bus(&lp->init_block) &0xffff);
+    lp->a.write_csr (ioaddr, 2, virt_to_bus(&lp->init_block) >> 16);
+
+    lp->a.write_csr (ioaddr, 4, 0x0915);
+    lp->a.write_csr (ioaddr, 0, 0x0001);
+
+    dev->tbusy = 0;
+    dev->interrupt = 0;
+    dev->start = 1;
+    i = 0;
+    while (i++ < 100)
+	if (lp->a.read_csr (ioaddr, 0) & 0x0100)
+	    break;
+    /* 
+     * We used to clear the InitDone bit, 0x0100, here but Mark Stockton
+     * reports that doing so triggers a bug in the '974.
+     */
+    lp->a.write_csr (ioaddr, 0, 0x0042);
+
+    if (pcnet32_debug > 2)
+	printk("%s: PCNET32 open after %d ticks, init block %#x csr0 %4.4x.\n",
+	       dev->name, i, (u32) virt_to_bus(&lp->init_block),
+	       lp->a.read_csr (ioaddr, 0));
X 
-        MOD_INC_USE_COUNT;
+    MOD_INC_USE_COUNT;
X     
-	return 0;					/* Always succeed */
+    return 0;	/* Always succeed */
X }
X 
X /*
@@ -539,15 +786,15 @@
X static void 
X pcnet32_purge_tx_ring(struct device *dev)
X {
-	struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
-	int i;
+    struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
+    int i;
X 
-	for (i = 0; i < TX_RING_SIZE; i++) {
-		if (lp->tx_skbuff[i]) {
-			dev_kfree_skb(lp->tx_skbuff[i]);
-			lp->tx_skbuff[i] = NULL;
-		}
+    for (i = 0; i < TX_RING_SIZE; i++) {
+	if (lp->tx_skbuff[i]) {
+	    dev_kfree_skb(lp->tx_skbuff[i]);
+	    lp->tx_skbuff[i] = NULL;
X 	}
+    }
X }
X 
X 
@@ -555,445 +802,437 @@
X static int
X pcnet32_init_ring(struct device *dev)
X {
-	struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
-	int i;
+    struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
+    int i;
X 
-	lp->tx_full = 0;
-	lp->cur_rx = lp->cur_tx = 0;
-	lp->dirty_rx = lp->dirty_tx = 0;
-
-	for (i = 0; i < RX_RING_SIZE; i++) {
-	    if (lp->rx_skbuff[i] == NULL) {
-		if (!(lp->rx_skbuff[i] = dev_alloc_skb (PKT_BUF_SZ))) {
-		    /* there is not much, we can do at this point */
-		    printk ("%s: pcnet32_init_ring dev_alloc_skb failed.\n",dev->name);
-		    return -1;
-		}
-		skb_reserve (lp->rx_skbuff[i], 2);
+    lp->tx_full = 0;
+    lp->cur_rx = lp->cur_tx = 0;
+    lp->dirty_rx = lp->dirty_tx = 0;
+
+    for (i = 0; i < RX_RING_SIZE; i++) {
+	if (lp->rx_skbuff[i] == NULL) {
+	    if (!(lp->rx_skbuff[i] = dev_alloc_skb (PKT_BUF_SZ))) {
+		/* there is not much, we can do at this point */
+		printk ("%s: pcnet32_init_ring dev_alloc_skb failed.\n",dev->name);
+		return -1;
X 	    }
-	    lp->rx_ring[i].base = (u32)le32_to_cpu(virt_to_bus(lp->rx_skbuff[i]->tail));
-	    lp->rx_ring[i].buf_length = le16_to_cpu(-PKT_BUF_SZ);
-	    lp->rx_ring[i].status = le16_to_cpu(0x8000);
-	}
-	/* The Tx buffer address is filled in as needed, but we do need to clear
-	   the upper ownership bit. */
-	for (i = 0; i < TX_RING_SIZE; i++) {
-	        lp->tx_ring[i].base = 0;
-	        lp->tx_ring[i].status = 0;
+	    skb_reserve (lp->rx_skbuff[i], 2);
X 	}
+	lp->rx_ring[i].base = (u32)le32_to_cpu(virt_to_bus(lp->rx_skbuff[i]->tail));
+	lp->rx_ring[i].buf_length = le16_to_cpu(-PKT_BUF_SZ);
+	lp->rx_ring[i].status = le16_to_cpu(0x8000);
+    }
+    /* The Tx buffer address is filled in as needed, but we do need to clear
+     the upper ownership bit. */
+    for (i = 0; i < TX_RING_SIZE; i++) {
+	lp->tx_ring[i].base = 0;
+	lp->tx_ring[i].status = 0;
+    }
X 
-        lp->init_block.tlen_rlen = TX_RING_LEN_BITS | RX_RING_LEN_BITS;
-	for (i = 0; i < 6; i++)
-		lp->init_block.phys_addr[i] = dev->dev_addr[i];
-	lp->init_block.rx_ring = (u32)le32_to_cpu(virt_to_bus(lp->rx_ring));
-	lp->init_block.tx_ring = (u32)le32_to_cpu(virt_to_bus(lp->tx_ring));
-	return 0;
+    lp->init_block.tlen_rlen = TX_RING_LEN_BITS | RX_RING_LEN_BITS;
+    for (i = 0; i < 6; i++)
+	lp->init_block.phys_addr[i] = dev->dev_addr[i];
+    lp->init_block.rx_ring = (u32)le32_to_cpu(virt_to_bus(lp->rx_ring));
+    lp->init_block.tx_ring = (u32)le32_to_cpu(virt_to_bus(lp->tx_ring));
+    return 0;
X }
X 
X static void
X pcnet32_restart(struct device *dev, unsigned int csr0_bits)
X {
-        int i;
-	unsigned int ioaddr = dev->base_addr;
+    struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+    int i;
X     
-	pcnet32_purge_tx_ring(dev);
-	if (pcnet32_init_ring(dev))
-		return;
-    
-	outw(0x0000, ioaddr + PCNET32_ADDR);
-        /* ReInit Ring */
-        outw(0x0001, ioaddr + PCNET32_DATA);
-	i = 0;
-	while (i++ < 100)
-		if (inw(ioaddr+PCNET32_DATA) & 0x0100)
-			break;
+    pcnet32_purge_tx_ring(dev);
+    if (pcnet32_init_ring(dev))
+	return;
+    
+    /* ReInit Ring */
+    lp->a.write_csr (ioaddr, 0, 1);
+    i = 0;
+    while (i++ < 100)
+	if (lp->a.read_csr (ioaddr, 0) & 0x0100)
+	    break;
X 
-	outw(csr0_bits, ioaddr + PCNET32_DATA);
+    lp->a.write_csr (ioaddr, 0, csr0_bits);
X }
X 
X static int
X pcnet32_start_xmit(struct sk_buff *skb, struct device *dev)
X {
-	struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
-	unsigned int ioaddr = dev->base_addr;
-	int entry;
-	unsigned long flags;
-
-	/* Transmitter timeout, serious problems. */
-	if (dev->tbusy) {
-		int tickssofar = jiffies - dev->trans_start;
-		if (tickssofar < HZ/2)
-			return 1;
-		outw(0, ioaddr+PCNET32_ADDR);
-		printk("%s: transmit timed out, status %4.4x, resetting.\n",
-			   dev->name, inw(ioaddr+PCNET32_DATA));
-		outw(0x0004, ioaddr+PCNET32_DATA);
-		lp->stats.tx_errors++;
-		if (pcnet32_debug > 2) {
-			int i;
-			printk(" Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.",
-				   lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "",
-				   lp->cur_rx);
-			for (i = 0 ; i < RX_RING_SIZE; i++)
-				printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
-					   lp->rx_ring[i].base, -lp->rx_ring[i].buf_length,
-					   lp->rx_ring[i].msg_length, (unsigned)lp->rx_ring[i].status);
-			for (i = 0 ; i < TX_RING_SIZE; i++)
-				printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
-					   lp->tx_ring[i].base, -lp->tx_ring[i].length,
-					   lp->tx_ring[i].misc, (unsigned)lp->tx_ring[i].status);
-			printk("\n");
-		}
-		pcnet32_restart(dev, 0x0042);
-
-		dev->tbusy = 0;
-		dev->trans_start = jiffies;
-		dev_kfree_skb(skb);
-		return 0;
+    struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
+    unsigned int ioaddr = dev->base_addr;
+    int entry;
+    unsigned long flags;
+
+    /* Transmitter timeout, serious problems. */
+    if (dev->tbusy) {
+	int tickssofar = jiffies - dev->trans_start;
+	if (tickssofar < HZ/2)
+	    return 1;
+	printk("%s: transmit timed out, status %4.4x, resetting.\n",
+	       dev->name, lp->a.read_csr (ioaddr, 0));
+	lp->a.write_csr (ioaddr, 0, 0x0004);
+	lp->stats.tx_errors++;
+	if (pcnet32_debug > 2) {
+	    int i;
+	    printk(" Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.",
+		   lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "",
+		   lp->cur_rx);
+	    for (i = 0 ; i < RX_RING_SIZE; i++)
+		printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
+		       lp->rx_ring[i].base, -lp->rx_ring[i].buf_length,
+		       lp->rx_ring[i].msg_length, (unsigned)lp->rx_ring[i].status);
+	    for (i = 0 ; i < TX_RING_SIZE; i++)
+		printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
+		       lp->tx_ring[i].base, -lp->tx_ring[i].length,
+		       lp->tx_ring[i].misc, (unsigned)lp->tx_ring[i].status);
+	    printk("\n");
X 	}
+	pcnet32_restart(dev, 0x0042);
X 
-	if (pcnet32_debug > 3) {
-		outw(0x0000, ioaddr+PCNET32_ADDR);
-		printk("%s: pcnet32_start_xmit() called, csr0 %4.4x.\n", dev->name,
-			   inw(ioaddr+PCNET32_DATA));
-	}
+	dev->tbusy = 0;
+	dev->trans_start = jiffies;
+	dev_kfree_skb(skb);
+	return 0;
+    }
X 
-	/* Block a timer-based transmit from overlapping.  This could better be
-	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
-	if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
-		printk("%s: Transmitter access conflict.\n", dev->name);
-		return 1;
-	}
+    if (pcnet32_debug > 3) {
+	printk("%s: pcnet32_start_xmit() called, csr0 %4.4x.\n",
+	       dev->name, lp->a.read_csr (ioaddr, 0));
+    }
X 
-	save_flags (flags);
-	cli ();
+    /* Block a timer-based transmit from overlapping.  This could better be
+       done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
+    if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
+	printk("%s: Transmitter access conflict.\n", dev->name);
+	return 1;
+    }
X 
-	/* Fill in a Tx ring entry */
+    save_flags (flags);
+    cli ();
X 
-	/* Mask to ring buffer boundary. */
-	entry = lp->cur_tx & TX_RING_MOD_MASK;
+    /* Fill in a Tx ring entry */
X 
-	/* Caution: the write order is important here, set the base address
-	   with the "ownership" bits last. */
+    /* Mask to ring buffer boundary. */
+    entry = lp->cur_tx & TX_RING_MOD_MASK;
X 
-	lp->tx_ring[entry].length = le16_to_cpu(-skb->len);
+    /* Caution: the write order is important here, set the base address
+       with the "ownership" bits last. */
X 
-	lp->tx_ring[entry].misc = 0x00000000;
+    lp->tx_ring[entry].length = le16_to_cpu(-skb->len);
X 
-	lp->tx_skbuff[entry] = skb;
-	lp->tx_ring[entry].base = (u32)le32_to_cpu(virt_to_bus(skb->data));
-        lp->tx_ring[entry].status = le16_to_cpu(0x8300);
+    lp->tx_ring[entry].misc = 0x00000000;
X 
-	lp->cur_tx++;
-        lp->stats.tx_bytes += skb->len;
+    lp->tx_skbuff[entry] = skb;
+    lp->tx_ring[entry].base = (u32)le32_to_cpu(virt_to_bus(skb->data));
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 04'
echo 'File patch-2.2.7 is continued in part 05'
echo 05 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 03 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 03; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
+        I2CWrite(bus, I2C_TEA6300, TEA6300_BA, 0x07, 1); /* bass 0dB         */
+        I2CWrite(bus, I2C_TEA6300, TEA6300_TR, 0x07, 1); /* treble 0dB       */
+        I2CWrite(bus, I2C_TEA6300, TEA6300_FA, 0x0f, 1); /* fader off        */
+        I2CWrite(bus, I2C_TEA6300, TEA6300_SW, 0x01, 1); /* mute off input A */
+}
+
X static void init_tda8425(struct i2c_bus *bus) 
X {
X         I2CWrite(bus, I2C_TDA8425, TDA8425_VL, 0xFC, 1); /* volume left 0dB  */
@@ -2978,6 +2988,14 @@
X                         break;
X         }
X         
+        if (I2CRead(&(btv->i2c), I2C_TEA6300) >=0)
+        {
+		printk(KERN_INFO "bttv%d: fader chip: TEA6300\n",btv->nr);
+		btv->audio_chip = TEA6300;
+		init_tea6300(&(btv->i2c));
+        } else
+		printk(KERN_INFO "bttv%d: NO fader chip: TEA6300\n",btv->nr);
+
X 	printk(KERN_INFO "bttv%d: model: ",btv->nr);
X 
X 	sprintf(btv->video_dev.name,"BT%d",btv->id);
diff -u --recursive --new-file v2.2.6/linux/drivers/char/bttv.h linux/drivers/char/bttv.h
--- v2.2.6/linux/drivers/char/bttv.h	Fri Apr 16 14:47:30 1999
+++ linux/drivers/char/bttv.h	Sat Apr 24 17:49:37 1999
@@ -114,6 +114,7 @@
X 	int type;            /* card type  */
X 	int audio;           /* audio mode */
X 	int audio_chip;
+	int fader_chip;
X 	int radio;
X 
X 	u32 *risc_jmp;
@@ -222,6 +223,7 @@
X #define TDA9850            0x01
X #define TDA8425            0x02
X #define TDA9840            0x03
+#define TEA6300            0x04
X 
X #define I2C_TSA5522        0xc2
X #define I2C_TDA9840	   0x84
@@ -230,6 +232,7 @@
X #define I2C_HAUPEE         0xa0
X #define I2C_STBEE          0xae
X #define I2C_VHX 	   0xc0
+#define I2C_TEA6300        0x80
X 
X #define TDA9840_SW	   0x00
X #define TDA9840_LVADJ	   0x02
@@ -249,6 +252,12 @@
X #define TDA8425_BA         0x02
X #define TDA8425_TR         0x03
X #define TDA8425_S1         0x08
- 
+
+#define TEA6300_VL         0x00		/* volume control left */
+#define TEA6300_VR         0x01		/* volume control right */
+#define TEA6300_BA         0x02		/* bass control */
+#define TEA6300_TR         0x03		/* treble control */
+#define TEA6300_FA         0x04		/* fader control */
+#define TEA6300_SW         0x05		/* mute and source switch */
X 
X #endif
diff -u --recursive --new-file v2.2.6/linux/drivers/char/dn_keyb.c linux/drivers/char/dn_keyb.c
--- v2.2.6/linux/drivers/char/dn_keyb.c	Wed Aug 26 11:37:36 1998
+++ linux/drivers/char/dn_keyb.c	Mon Apr 26 13:28:07 1999
@@ -414,9 +414,9 @@
X 	}
X 	else if((scancode & (~BREAK_FLAG)) == DNKEY_CAPS) {
X     	/* printk("handle_scancode: %02x\n",DNKEY_CAPS); */
-		handle_scancode(DNKEY_CAPS);
+		handle_scancode(DNKEY_CAPS, 1);
X 		/*    printk("handle_scancode: %02x\n",BREAK_FLAG | DNKEY_CAPS); */
-		handle_scancode(BREAK_FLAG | DNKEY_CAPS);
+		handle_scancode(DNKEY_CAPS, 0);
X 	}
X 	else if( (scancode == DNKEY_REPEAT) && (prev_scancode < 0x7e) &&
X    			!(prev_scancode==DNKEY_CTRL || prev_scancode==DNKEY_LSHIFT ||
@@ -424,13 +424,13 @@
X        	  	prev_scancode==DNKEY_LALT || prev_scancode==DNKEY_RALT)) {
X         		if(jiffies-lastkeypress > DNKEY_REPEAT_DELAY) {
X 			/*    	printk("handle_scancode: %02x\n",prev_scancode); */
-           			handle_scancode(prev_scancode);
+           			handle_scancode(prev_scancode, 1);
X 			  	}
X 	   			lastscancode=prev_scancode;
X   			}
X   	else {
X 	/*    	printk("handle_scancode: %02x\n",scancode);  */
-   			handle_scancode(scancode);
+   			handle_scancode(scancode & ~BREAK_FLAG, !(scancode & BREAK_FLAG));
X    			lastkeypress=jiffies;
X   	}
X }
diff -u --recursive --new-file v2.2.6/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c
--- v2.2.6/linux/drivers/char/keyboard.c	Fri Jan  8 22:36:05 1999
+++ linux/drivers/char/keyboard.c	Mon Apr 26 13:21:42 1999
@@ -24,6 +24,7 @@
X  */
X 
X #include <linux/config.h>
+#include <linux/module.h>
X #include <linux/sched.h>
X #include <linux/tty.h>
X #include <linux/tty_flip.h>
@@ -59,6 +60,8 @@
X #define KBD_DEFLOCK 0
X #endif
X 
+EXPORT_SYMBOL(handle_scancode);
+
X extern void ctrl_alt_del(void);
X 
X struct wait_queue * keypress_wait = NULL;
@@ -190,15 +193,15 @@
X     return kbd_getkeycode(scancode);
X }
X 
-void handle_scancode(unsigned char scancode)
+void handle_scancode(unsigned char scancode, int down)
X {
X 	unsigned char keycode;
-	char up_flag;				 /* 0 or 0200 */
+	char up_flag = down ? 0 : 0200;
X 	char raw_mode;
X 
X 	do_poke_blanked_console = 1;
X 	mark_bh(CONSOLE_BH);
-	add_keyboard_randomness(scancode);
+	add_keyboard_randomness(scancode | up_flag);
X 
X 	tty = ttytab? ttytab[fg_console]: NULL;
X 	if (tty && (!tty->driver_data)) {
@@ -213,20 +216,15 @@
X 	}
X 	kbd = kbd_table + fg_console;
X 	if ((raw_mode = (kbd->kbdmode == VC_RAW))) {
- 		put_queue(scancode);
+		put_queue(scancode | up_flag);
X 		/* we do not return yet, because we want to maintain
X 		   the key_down array, so that we have the correct
X 		   values when finishing RAW mode or when changing VT's */
- 	}
+	}
X 
-	if (!kbd_pretranslate(scancode, raw_mode))
-	    return;
- 	/*
+	/*
X 	 *  Convert scancode to keycode
- 	 */
-	up_flag = (scancode & 0200);
- 	scancode &= 0x7f;
-
+	 */
X 	if (!kbd_translate(scancode, &keycode, raw_mode))
X 	    return;
X 
@@ -239,10 +237,10 @@
X 
X 	if (up_flag) {
X 		rep = 0;
- 		if(!test_and_clear_bit(keycode, key_down))
+		if(!test_and_clear_bit(keycode, key_down))
X 		    up_flag = kbd_unexpected_up(keycode);
X 	} else
- 		rep = test_and_set_bit(keycode, key_down);
+		rep = test_and_set_bit(keycode, key_down);
X 
X #ifdef CONFIG_MAGIC_SYSRQ		/* Handle the SysRq Hack */
X 	if (keycode == SYSRQ_KEY) {
@@ -257,11 +255,11 @@
X 
X 	if (kbd->kbdmode == VC_MEDIUMRAW) {
X 		/* soon keycodes will require more than one byte */
- 		put_queue(keycode + up_flag);
+		put_queue(keycode + up_flag);
X 		raw_mode = 1;	/* Most key classes will be ignored */
- 	}
+	}
X 
- 	/*
+	/*
X 	 * Small change in philosophy: earlier we defined repetition by
X 	 *	 rep = keycode == prev_keycode;
X 	 *	 prev_keycode = keycode;
@@ -270,9 +268,9 @@
X 	 */
X 
X 	/*
- 	 *  Repeat a key only if the input buffers are empty or the
- 	 *  characters get echoed locally. This makes key repeat usable
- 	 *  with slow applications and under heavy loads.
+	 *  Repeat a key only if the input buffers are empty or the
+	 *  characters get echoed locally. This makes key repeat usable
+	 *  with slow applications and under heavy loads.
X 	 */
X 	if (!rep ||
X 	    (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
diff -u --recursive --new-file v2.2.6/linux/drivers/char/mem.c linux/drivers/char/mem.c
--- v2.2.6/linux/drivers/char/mem.c	Fri Apr 16 14:47:30 1999
+++ linux/drivers/char/mem.c	Mon Apr 26 12:55:29 1999
@@ -51,6 +51,12 @@
X #if defined(CONFIG_PPC) || defined(CONFIG_MAC)
X extern void adbdev_init(void);
X #endif
+#ifdef CONFIG_USB_UHCI
+int uhci_init(void);
+#endif
+#ifdef CONFIG_USB_OHCI
+int ohci_init(void);
+#endif
X 
X static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
X 			    const char * buf, size_t count, loff_t *ppos)
@@ -599,6 +605,12 @@
X 	if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
X 		printk("unable to get major %d for memory devs\n", MEM_MAJOR);
X 	rand_initialize();
+#ifdef CONFIG_USB_UHCI
+	uhci_init();
+#endif
+#ifdef CONFIG_USB_OHCI
+	ohci_init();
+#endif
X #if defined (CONFIG_FB)
X 	fbmem_init();
X #endif
diff -u --recursive --new-file v2.2.6/linux/drivers/char/n_tty.c linux/drivers/char/n_tty.c
--- v2.2.6/linux/drivers/char/n_tty.c	Tue Jan 19 11:32:51 1999
+++ linux/drivers/char/n_tty.c	Sat Apr 24 17:49:37 1999
@@ -922,8 +922,14 @@
X 		}
X 	}
X 
-	if (down_interruptible(&tty->atomic_read))
-		return -ERESTARTSYS;
+	if (file->f_flags & O_NONBLOCK) {
+		if (down_trylock(&tty->atomic_read))
+			return -EAGAIN;
+	}
+	else {
+		if (down_interruptible(&tty->atomic_read))
+			return -ERESTARTSYS;
+	}
X 
X 	add_wait_queue(&tty->read_wait, &wait);
X 	set_bit(TTY_DONT_FLIP, &tty->flags);
diff -u --recursive --new-file v2.2.6/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c
--- v2.2.6/linux/drivers/char/pc_keyb.c	Tue Feb 23 15:21:33 1999
+++ linux/drivers/char/pc_keyb.c	Mon Apr 26 13:43:01 1999
@@ -240,8 +240,6 @@
X   0, 0, 0, 0, 0, 0, 0, 0			      /* 0x78-0x7f */
X };
X 
-static unsigned int prev_scancode = 0;   /* remember E0, E1 */
-
X int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
X {
X 	if (scancode < SC_LIM || scancode > 255 || keycode > 127)
@@ -284,41 +282,28 @@
X 		       scancode);
X #endif
X 	}
-	if (scancode == 0) {
-#ifdef KBD_REPORT_ERR
-		printk(KERN_INFO "Keyboard buffer overflow\n");
-#endif
-		prev_scancode = 0;
-		return 0;
-	}
X 	return 1;
X }
X 
-int pckbd_pretranslate(unsigned char scancode, char raw_mode)
+int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+		    char raw_mode)
X {
-	if (scancode == 0xff) {
-		/* in scancode mode 1, my ESC key generates 0xff */
-		/* the calculator keys on a FOCUS 9000 generate 0xff */
-#ifndef KBD_IS_FOCUS_9000
-#ifdef KBD_REPORT_ERR
-		if (!raw_mode)
-		  printk(KERN_DEBUG "Keyboard error\n");
-#endif
-#endif
-		prev_scancode = 0;
-		return 0;
-	}
+	static int prev_scancode = 0;
X 
+	/* special prefix scancodes.. */
X 	if (scancode == 0xe0 || scancode == 0xe1) {
X 		prev_scancode = scancode;
X 		return 0;
- 	}
- 	return 1;
-}
+	}
+
+	/* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
+	if (scancode == 0x00 || scancode == 0xff) {
+		prev_scancode = 0;
+		return 0;
+	}
+
+	scancode &= 0x7f;
X 
-int pckbd_translate(unsigned char scancode, unsigned char *keycode,
-		    char raw_mode)
-{
X 	if (prev_scancode) {
X 	  /*
X 	   * usually it will be 0xe0, but a Pause key generates
@@ -452,7 +437,7 @@
X 			handle_mouse_event(scancode);
X 		} else {
X 			if (do_acknowledge(scancode))
-				handle_scancode(scancode);
+				handle_scancode(scancode, !(scancode & 0x80));
X 			mark_bh(KEYBOARD_BH);
X 		}
X 
diff -u --recursive --new-file v2.2.6/linux/drivers/char/radio-sf16fmi.c linux/drivers/char/radio-sf16fmi.c
--- v2.2.6/linux/drivers/char/radio-sf16fmi.c	Fri Apr 16 14:47:30 1999
+++ linux/drivers/char/radio-sf16fmi.c	Sat Apr 24 17:49:37 1999
@@ -4,6 +4,7 @@
X  * (c) 1998 Petr Vandrovec, vand...@vc.cvut.cz
X  *
X  * Fitted to new interface by Alan Cox <alan...@linux.org>
+ * Made working and cleaned up functions <mikael...@irf.se>
X  *
X  * Notes on the hardware
X  *
@@ -74,9 +75,10 @@
X 	outb(0x08, port);
X }
X 
-static inline int fmi_setfreq(struct fmi_device *dev, unsigned long freq)
+static inline int fmi_setfreq(struct fmi_device *dev)
X {
X         int myport = dev->port;
+	unsigned long freq = dev->curfreq;
X 	int i;
X 	
X 	outbits(16, RSF16_ENCODE(freq), myport);
@@ -158,7 +160,6 @@
X 			v.flags=fmi->flags;
X 			v.mode=VIDEO_MODE_AUTO;
X 			v.signal = fmi_getsigstr(fmi);
-			strcpy(v.name, "FM");
X 			if(copy_to_user(arg,&v, sizeof(v)))
X 				return -EFAULT;
X 			return 0;
@@ -192,8 +193,10 @@
X 				tmp *= 1000;
X 			if ( tmp<RSF16_MINFREQ || tmp>RSF16_MAXFREQ )
X 			  return -EINVAL;
-			fmi->curfreq = tmp;
-			fmi_setfreq(fmi, fmi->curfreq);
+			/*rounding in steps of 800 to match th freq
+			  that will be used */
+			fmi->curfreq = (tmp/800)*800; 
+			fmi_setfreq(fmi);
X 			return 0;
X 		}
X 		case VIDIOCGAUDIO:
@@ -205,7 +208,7 @@
X 			v.treble=0;
X 			v.flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
X 			strcpy(v.name, "Radio");
-			v.mode=VIDEO_SOUND_MONO;
+			v.mode=VIDEO_SOUND_STEREO;
X 			v.balance=0;
X 			v.step=0; /* No volume, just (un)mute */
X 			if(copy_to_user(arg,&v, sizeof(v)))
diff -u --recursive --new-file v2.2.6/linux/drivers/char/radio-typhoon.c linux/drivers/char/radio-typhoon.c
--- v2.2.6/linux/drivers/char/radio-typhoon.c	Fri Apr 16 14:47:30 1999
+++ linux/drivers/char/radio-typhoon.c	Sat Apr 24 17:49:37 1999
@@ -196,7 +196,7 @@
X 			v.flags = VIDEO_TUNER_LOW;
X 			v.mode = VIDEO_MODE_AUTO;
X 			v.signal = 0xFFFF;	/* We can't get the signal strength */
-			strcpy(v.tuner, "FM");
+			strcpy(v.name, "FM");
X 			if (copy_to_user(arg, &v, sizeof(v)))
X 				return -EFAULT;
X 			return 0;
diff -u --recursive --new-file v2.2.6/linux/drivers/char/softdog.c linux/drivers/char/softdog.c
--- v2.2.6/linux/drivers/char/softdog.c	Fri Apr 16 14:47:30 1999
+++ linux/drivers/char/softdog.c	Sat Apr 24 17:49:37 1999
@@ -132,7 +132,6 @@
X static int softdog_ioctl(struct inode *inode, struct file *file,
X 	unsigned int cmd, unsigned long arg)
X {
-	int i;
X 	static struct watchdog_info ident=
X 	{
X 		0,
diff -u --recursive --new-file v2.2.6/linux/drivers/macintosh/mac_keyb.c linux/drivers/macintosh/mac_keyb.c
--- v2.2.6/linux/drivers/macintosh/mac_keyb.c	Tue Mar 23 14:35:47 1999
+++ linux/drivers/macintosh/mac_keyb.c	Mon Apr 26 13:31:31 1999
@@ -194,7 +194,7 @@
X extern struct kbd_struct kbd_table[];
X extern struct wait_queue * keypress_wait;
X 
-extern void handle_scancode(unsigned char);
+extern void handle_scancode(unsigned char, int);
X 
X static struct adb_ids keyboard_ids;
X static struct adb_ids mouse_ids;
@@ -234,11 +234,6 @@
X 	return -EINVAL;
X }
X 
-int mackbd_pretranslate(unsigned char scancode, char raw_mode)
-{
-	return 1;
-}
-
X int mackbd_translate(unsigned char keycode, unsigned char *keycodep,
X 		     char raw_mode)
X {
@@ -338,8 +333,8 @@
X 		 switch (keycode) {
X 		 /*case 0xb9:*/
X 		 case 0x39:
-			handle_scancode(0x39);
-			handle_scancode(0xb9);
+			handle_scancode(0x39, 1);
+			handle_scancode(0x39, 0);
X 		 	mark_bh(KEYBOARD_BH);
X 		 	return;
X 		 case 0x47:
@@ -349,7 +344,7 @@
X 		 }
X 	}
X 
-	handle_scancode(keycode + up_flag);
+	handle_scancode(keycode, !up_flag);
X }
X 
X static void
diff -u --recursive --new-file v2.2.6/linux/drivers/net/3c523.c linux/drivers/net/3c523.c
--- v2.2.6/linux/drivers/net/3c523.c	Tue Jan 19 11:32:51 1999
+++ linux/drivers/net/3c523.c	Sat Apr 24 17:49:37 1999
@@ -62,8 +62,8 @@
X    search the MCA slots until it finds a 3c523 with the specified
X    parameters.
X 
-   This driver should support multiple ethernet cards, but I can't test
-   that.  If someone would I'd greatly appreciate it.
+   This driver does support multiple ethernet cards when used as a module
+   (up to MAX_3C523_CARDS, the default being 4)
X 
X    This has been tested with both BNC and TP versions, internal and
X    external transceivers.  Haven't tested with the 64K version (that I
@@ -76,7 +76,12 @@
X    update to 1.3.59, incorporated multicast diffs from ni52.c
X    Feb 15th, 1996
X    added shared irq support
-
+   Apr 1999
+   added support for multiple cards when used as a module
+   added option to disable multicast as is causes problems
+       Ganesh Sittampalam <ganesh.si...@magdalen.oxford.ac.uk>
+       Stuart Adamson <stuart....@compsoc.net>
+	
X    $Header: /fsys2/home/chrisb/linux-1.3.59-MCA/drivers/net/RCS/3c523.c,v 1.1 1996/02/05 01:53:46 chrisb Exp chrisb $
X  */
X 
@@ -107,6 +112,7 @@
X /*************************************************************************/
X #define DEBUG			/* debug on */
X #define SYSBUSVAL 0		/* 1 = 8 Bit, 0 = 16 bit - 3c523 only does 16 bit */
+#undef ELMC_MULTICAST		/* Disable multicast support as it is somewhat seriously broken at the moment */
X 
X #define make32(ptr16) (p->memtop + (short) (ptr16) )
X #define make24(ptr32) ((char *) (ptr32) - p->base)
@@ -180,7 +186,9 @@
X static int elmc_close(struct device *dev);
X static int elmc_send_packet(struct sk_buff *, struct device *);
X static struct net_device_stats *elmc_get_stats(struct device *dev);
+#ifdef ELMC_MULTICAST
X static void set_multicast_list(struct device *dev);
+#endif
X 
X /* helper-functions */
X static int init586(struct device *dev);
@@ -432,21 +440,19 @@
X 	while (slot != -1) {
X 		status = mca_read_stored_pos(slot, 2);
X 
+		dev->irq=irq_table[(status & ELMC_STATUS_IRQ_SELECT) >> 6];
+		dev->base_addr=csr_table[(status & ELMC_STATUS_CSR_SELECT) >> 1];
+		
X 		/*
X 		   If we're trying to match a specified irq or IO address,
X 		   we'll reject a match unless it's what we're looking for.
+		   Also reject it if the card is already in use.
X 		 */
-		if (base_addr || irq) {
-			/* we're looking for a card at a particular place */
X 
-			if (irq && irq != irq_table[(status & ELMC_STATUS_IRQ_SELECT) >> 6]) {
-				slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
-				continue;
-			}
-			if (base_addr && base_addr != csr_table[(status & ELMC_STATUS_CSR_SELECT) >> 1]) {
-				slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
-				continue;
-			}
+		if((irq && irq != dev->irq) || (base_addr && base_addr != dev->base_addr)
+		   || check_region(dev->base_addr,ELMC_IO_EXTENT)) {
+			slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
+			continue;
X 		}
X 		/* found what we're looking for... */
X 		break;
@@ -476,9 +482,6 @@
X 	/* revision is stored in the first 4 bits of the revision register */
X 	revision = inb(dev->base_addr + ELMC_REVISION) & 0xf;
X 
-	/* figure out our irq */
-	dev->irq = irq_table[(status & ELMC_STATUS_IRQ_SELECT) >> 6];
-
X 	/* according to docs, we read the interrupt and write it back to
X 	   the IRQ select register, since the POST might not configure the IRQ
X 	   properly. */
@@ -497,9 +500,6 @@
X 		break;
X 	}
X 
-	/* Our IO address? */
-	dev->base_addr = csr_table[(status & ELMC_STATUS_CSR_SELECT) >> 1];
-
X 	request_region(dev->base_addr, ELMC_IO_EXTENT, "3c523");
X 
X 	dev->priv = (void *) kmalloc(sizeof(struct priv), GFP_KERNEL);
@@ -565,7 +565,11 @@
X 	dev->stop = &elmc_close;
X 	dev->get_stats = &elmc_get_stats;
X 	dev->hard_start_xmit = &elmc_send_packet;
+#ifdef ELMC_MULTICAST
X 	dev->set_multicast_list = &set_multicast_list;
+#else
+	dev->set_multicast_list = NULL;
+#endif
X 
X 	ether_setup(dev);
X 
@@ -577,6 +581,10 @@
X 	   That gets done in elmc_open().  I'm not sure that's such a good idea,
X 	   but it works, so I'll go with it. */
X 
+#ifndef ELMC_MULTICAST
+        dev->flags&=~IFF_MULTICAST;     /* Multicast doesn't work */
+#endif
+
X 	return 0;
X }
X 
@@ -1210,6 +1218,7 @@
X  * Set MC list ..
X  */
X 
+#ifdef ELMC_MULTICAST
X static void set_multicast_list(struct device *dev)
X {
X 	if (!dev->start) {
@@ -1222,60 +1231,85 @@
X 	startrecv586(dev);
X 	dev->start = 1;
X }
+#endif
X 
X /*************************************************************************/
X 
X #ifdef MODULE
X 
-static char devicename[9] = {0,};
+/* Increase if needed ;) */
+#define MAX_3C523_CARDS 4
+/* I'm not sure where this magic 9 comes from */
+#define NAMELEN 9
X 
-static struct device dev_elmc =
-{
-	devicename /*"3c523" */ , 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, elmc_probe
+static char devicenames[NAMELEN * MAX_3C523_CARDS] = {0,};
+
+static struct device dev_elmc[MAX_3C523_CARDS] =
+{	
+	{
+	NULL /*"3c523" */ , 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL
+	},
X };
X 
-static int irq = 0;
-static int io = 0;
-MODULE_PARM(irq, "i");
-MODULE_PARM(io, "i");
+static int irq[MAX_3C523_CARDS] = {0,};
+static int io[MAX_3C523_CARDS] = {0,};
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_3C523_CARDS) "i");
X 
X int init_module(void)
X {
-	struct device *dev = &dev_elmc;
+	int this_dev,found = 0;
X 
-	dev->base_addr = io;
-	dev->irq = irq;
-	if (register_netdev(dev) != 0) {
-		return -EIO;
-	}
-	return 0;
+	/* Loop until we either can't find any more cards, or we have MAX_3C523_CARDS */	
+	for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) 
+		{
+		struct device *dev = &dev_elmc[this_dev];
+		dev->name=devicenames+(NAMELEN*this_dev);
+		dev->irq=irq[this_dev];
+		dev->base_addr=io[this_dev];
+		dev->init=elmc_probe;
+		if(register_netdev(dev)!=0) {
+			if(io[this_dev]==0) break;
+			printk(KERN_WARNING "3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
+		} else found++;
+	}
+
+	if(found==0) {
+		if(io[0]==0) printk(KERN_NOTICE "3c523.c: No 3c523 cards found\n");
+		return -ENXIO;
+	} else return 0;
X }
X 
X void cleanup_module(void)
X {
-	struct device *dev = &dev_elmc;
+	int this_dev;
+	for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
X 
-	/* shutdown interrupts on the card */
-	elmc_id_reset586();
-	if (dev->irq != 0) {
-		/* this should be done by close, but if we failed to
-		   initialize properly something may have gotten hosed. */
-		free_irq(dev->irq, dev);
-		dev->irq = 0;
-	}
-	if (dev->base_addr != 0) {
-		release_region(dev->base_addr, ELMC_IO_EXTENT);
-		dev->base_addr = 0;
-	}
-	irq = 0;
-	io = 0;
-	unregister_netdev(dev);
+		struct device *dev = &dev_elmc[this_dev];
+		if(dev->priv) {
+			/* shutdown interrupts on the card */
+			elmc_id_reset586();
+			if (dev->irq != 0) {
+				/* this should be done by close, but if we failed to
+				   initialize properly something may have gotten hosed. */
+				free_irq(dev->irq, dev);
+				dev->irq = 0;
+			}
+			if (dev->base_addr != 0) {
+				release_region(dev->base_addr, ELMC_IO_EXTENT);
+				dev->base_addr = 0;
+			}
+			irq[this_dev] = 0;
+			io[this_dev] = 0;
+			unregister_netdev(dev);
X 
-	mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot,
+			mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot,
X 			       NULL, NULL);
X 
-	kfree_s(dev->priv, sizeof(struct priv));
-	dev->priv = NULL;
+			kfree_s(dev->priv, sizeof(struct priv));
+			dev->priv = NULL;
+		}
+	}
X }
X 
X #endif				/* MODULE */
diff -u --recursive --new-file v2.2.6/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c
--- v2.2.6/linux/drivers/net/ibmtr.c	Tue Mar 23 14:35:47 1999
+++ linux/drivers/net/ibmtr.c	Sat Apr 24 17:49:37 1999
@@ -70,6 +70,12 @@
X  *      Changes by Joel Sloan (j...@c-me.com) :
X  *      + disable verbose debug messages by default - to enable verbose
X  *	  debugging, edit the IBMTR_DEBUG_MESSAGES define below 
+ *	
+ *	Changes by Mike Phillips <phi...@amtrak.com> :
+ *	+ Added extra #ifdef's to work with new PCMCIA Token Ring Code.
+ *	  The PCMCIA code now just sets up the card so it can be recognized
+ *        by ibmtr_probe. Also checks allocated memory vs. on-board memory
+ *	  for correct figure to use.
X  *
X  *	Changes by Tim Hockin (tho...@isunix.it.ilstu.edu) :
X  *	+ added spinlocks for SMP sanity (10 March 1999)
@@ -94,6 +100,7 @@
X #undef NO_AUTODETECT
X #undef ENABLE_PAGING
X 
+
X #define FALSE 0
X #define TRUE (!FALSE)
X 
@@ -191,6 +198,9 @@
X int		ibmtr_probe(struct device *dev);
X static int	ibmtr_probe1(struct device *dev, int ioaddr);
X static unsigned char	get_sram_size(struct tok_info *adapt_info);
+#ifdef PCMCIA
+extern unsigned char 	pcmcia_reality_check(unsigned char gss);
+#endif
X static int	tok_init_card(struct device *dev);
X void		tok_interrupt(int irq, void *dev_id, struct pt_regs *regs);
X static int	trdev_init(struct device *dev);
@@ -256,8 +266,10 @@
X 	        if (ibmtr_probe1(dev, base_addr)) 
X 	        {
X #ifndef MODULE
+#ifndef PCMCIA
X 		       tr_freedev(dev);
X #endif
+#endif
X 		       return -ENODEV;
X 		} else
X 		       return 0;
@@ -272,8 +284,10 @@
X 		        continue;
X                 if (ibmtr_probe1(dev, ioaddr)) {
X #ifndef MODULE
+#ifndef PCMCIA
X 		        tr_freedev(dev);
X #endif
+#endif
X 		} else
X 			return 0;
X         }
@@ -291,8 +305,10 @@
X 	unsigned long timeout;
X 
X #ifndef MODULE
+#ifndef PCMCIA
X 	dev = init_trdev(dev,0);
X #endif
+#endif
X 
X 	/*	Query the adapter PIO base port which will return
X 	 *	indication of where MMIO was placed. We also have a
@@ -300,7 +316,7 @@
X 	 */
X 
X        	segment = inb(PIOaddr);
-	
+
X 	/*
X 	 *	Out of range values so we'll assume non-existent IO device 
X 	 */
@@ -373,12 +389,19 @@
X 	}
X 
X 	/* Now, allocate some of the pl0 buffers for this driver.. */
+
+	/* If called from PCMCIA, ti is already set up, so no need to 
+	   waste the memory, just use the existing structure */
+
+#ifndef PCMCIA
X 	ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL);
X 	if (ti == NULL) 
X 		return -ENOMEM;
X 
X 	memset(ti, 0, sizeof(struct tok_info));
-
+#else
+	ti = dev->priv ; 
+#endif
X 	ti->mmio= t_mmio;
X 	ti->readlog_pending = 0;
X 
@@ -388,6 +411,10 @@
X                          should fit with out future hope of multiple
X                          adapter support as well /dwm   */
X 
+	/* if PCMCIA, then the card is recognized as TR_ISAPNP 
+	 * and there is no need to set up the interrupt, it is already done. */
+        
+#ifndef PCMCIA
X 	switch (cardpresent) 
X 	{
X 		case TR_ISA:
@@ -428,7 +455,6 @@
X 				irq=10;
X 			if (intr==3)
X 				irq=11;
-
X 			timeout = jiffies + TR_SPIN_INTERVAL;
X 			while(!readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN))
X 				if (time_after(jiffies, timeout)) {
@@ -436,11 +462,13 @@
X 					kfree_s(ti, sizeof(struct tok_info));
X 					return -ENODEV;
X 			        }
+
X 			ti->sram=((__u32)readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)<<12);
X 			ti->global_int_enable=PIOaddr+ADAPTINTREL;
X 			ti->adapter_int_enable=PIOaddr+ADAPTINTREL;
X 			break;
X 	}
+#endif
X 
X 	if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
X 		DPRINTK("irq=%d",irq);
@@ -483,8 +511,11 @@
X 	ti->token_release = readb(ti->mmio + AIPEARLYTOKEN);
X 
X 	/* How much shared RAM is on adapter ? */
+#ifdef PCMCIA
+	ti->avail_shared_ram = pcmcia_reality_check(get_sram_size(ti));
+#else
X 	ti->avail_shared_ram = get_sram_size(ti);
-
+#endif
X 	/* We need to set or do a bunch of work here based on previous results.. */
X 	/* Support paging?  What sizes?:  F=no, E=16k, D=32k, C=16 & 32k */
X 	ti->shared_ram_paging = readb(ti->mmio + AIPSHRAMPAGE);
@@ -593,7 +624,6 @@
X 		}
X #endif
X 	}
-
X 	/* finish figuring the shared RAM address */
X 	if (cardpresent==TR_ISA) {
X 		static __u32 ram_bndry_mask[]={0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000};
@@ -619,15 +649,20 @@
X 	DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2);
X #endif
X 
+	/* The PCMCIA has already got the interrupt line and the io port, 
+	   so no chance of anybody else getting it - MLP */
+
+#ifndef PCMCIA
X 	if (request_irq (dev->irq = irq, &tok_interrupt,0,"ibmtr", dev) != 0) {
X 		DPRINTK("Could not grab irq %d.  Halting Token Ring driver.\n",irq);
X 		kfree_s(ti, sizeof(struct tok_info));
X 		return -ENODEV;
X 	}
+ 
+	/*?? Now, allocate some of the PIO PORTs for this driver.. */
+	request_region(PIOaddr,IBMTR_IO_EXTENT,"ibmtr");  /* record PIOaddr range as busy */
+#endif
X 
- /*?? Now, allocate some of the PIO PORTs for this driver.. */
-	request_region(PIOaddr,IBMTR_IO_EXTENT,"ibmtr");  /* record PIOaddr range
-								  as busy */
X #if !TR_NEWFORMAT
X 	DPRINTK("%s",version); /* As we have passed card identification,
X                                   let the world know we're here! */
@@ -717,7 +752,6 @@
X 
X 	unsigned char avail_sram_code;
X 	static unsigned char size_code[]={ 0,16,32,64,127,128 };
-
X 	/* Adapter gives
X 	   'F' -- use RRR bits 3,2
X 	   'E' -- 8kb   'D' -- 16kb
@@ -747,8 +781,10 @@
X 	dev->change_mtu         = ibmtr_change_mtu;
X 
X #ifndef MODULE
+#ifndef PCMCIA
X 	tr_setup(dev);
X #endif
+#endif
X 	return 0;
X }
X 
@@ -842,7 +878,7 @@
X 		          DPRINTK("PCMCIA card removed.\n");
X 			  spin_unlock(&(ti->lock));
X         		  dev->interrupt = 0;
-          		  return;
+         		  return;
X        		}
X 
X     	        /* Check ISRP EVEN too. */
@@ -1186,7 +1222,6 @@
X 	__u32 encoded_addr;
X 	__u32 hw_encoded_addr;
X 	struct tok_info *ti;
-
X 	ti=(struct tok_info *) dev->priv;
X 
X 	ti->do_tok_int=NOT_FIRST;
diff -u --recursive --new-file v2.2.6/linux/drivers/net/irda/actisys.c linux/drivers/net/irda/actisys.c
--- v2.2.6/linux/drivers/net/irda/actisys.c	Wed Mar 10 15:29:46 1999
+++ linux/drivers/net/irda/actisys.c	Sat Apr 24 17:49:37 1999
@@ -7,7 +7,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Wed Oct 21 20:02:35 1998
- * Modified at:   Tue Feb  9 15:38:16 1999
+ * Modified at:   Mon Apr 12 11:56:35 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
@@ -234,8 +234,8 @@
X 	/* Remove support for 38400 if this is not a 220L+ dongle */
X 	if ( idev->io.dongle_id == ACTISYS_DONGLE)
X 		qos->baud_rate.bits &= ~IR_38400;
-		
-	qos->min_turn_time.bits &= 0xfe; /* All except 0 ms */
+	
+ qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */
X }
X 
X #ifdef MODULE
diff -u --recursive --new-file v2.2.6/linux/drivers/net/irda/esi.c linux/drivers/net/irda/esi.c
--- v2.2.6/linux/drivers/net/irda/esi.c	Wed Mar 10 15:29:46 1999
+++ linux/drivers/net/irda/esi.c	Sat Apr 24 17:49:37 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Thomas Davis, <rat...@radiks.net>
X  * Created at:    Sat Feb 21 18:54:38 1998
- * Modified at:   Tue Feb  9 15:36:47 1999
+ * Modified at:   Mon Apr 12 11:55:30 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * Sources:	  esi.c
X  *
@@ -56,9 +56,9 @@
X 	esi_qos_init,
X };
X 
-__initfunc(void esi_init(void))
+__initfunc(int esi_init(void))
X {
-	irtty_register_dongle( &dongle);
+	return irtty_register_dongle(&dongle);
X }
X 
X void esi_cleanup(void)
@@ -132,7 +132,7 @@
X 	}
X 	/* Change speed of serial driver */
X 	tty->termios->c_cflag = cflag;
-	tty->driver.set_termios( tty, &old_termios);
+	tty->driver.set_termios(tty, &old_termios);
X 
X 	irtty_set_dtr_rts(tty, dtr, rts);
X }
@@ -151,6 +151,7 @@
X static void esi_qos_init( struct irda_device *idev, struct qos_info *qos)
X {
X 	qos->baud_rate.bits &= IR_9600|IR_19200|IR_115200;
+	qos->min_turn_time.bits &= 0x01; /* Needs at least 10 ms */
X }
X 
X #ifdef MODULE
@@ -163,8 +164,7 @@
X  */
X int init_module(void)
X {
-	esi_init();
-	return(0);
+	return esi_init();
X }
X 
X /*
diff -u --recursive --new-file v2.2.6/linux/drivers/net/irda/girbil.c linux/drivers/net/irda/girbil.c
--- v2.2.6/linux/drivers/net/irda/girbil.c	Wed Mar 10 15:29:46 1999
+++ linux/drivers/net/irda/girbil.c	Sat Apr 24 17:49:37 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sat Feb  6 21:02:33 1999
- * Modified at:   Tue Feb  9 15:36:36 1999
+ * Modified at:   Sat Apr 10 19:53:12 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -195,7 +195,7 @@
X {
X 	struct irtty_cb *self;
X 	struct tty_struct *tty;
-	__u8 control = GIRBIL_TXEN | GIRBIL_RXEN /* | GIRBIL_ECAN */;
+	__u8 control = GIRBIL_TXEN | GIRBIL_RXEN;
X 
X 	ASSERT(idev != NULL, return;);
X 	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
diff -u --recursive --new-file v2.2.6/linux/drivers/net/irda/irport.c linux/drivers/net/irda/irport.c
--- v2.2.6/linux/drivers/net/irda/irport.c	Fri Apr 16 14:47:30 1999
+++ linux/drivers/net/irda/irport.c	Sat Apr 24 17:49:37 1999
@@ -1,7 +1,7 @@
X /*********************************************************************
X  *		  
X  * Filename:	  irport.c
- * Version:	  0.8
+ * Version:	  0.9
X  * Description:   Serial driver for IrDA. 
X  * Status:	  Experimental.
X  * Author:	  Dag Brattli <da...@cs.uit.no>
@@ -9,7 +9,6 @@
X  * Modified at:   Sat May 23 23:15:20 1998
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * Sources:	  serial.c by Linus Torvalds 
- *		  serial_serial.c by Aage Kvalnes <aa...@cs.uit.no>
X  * 
X  *     Copyright (c) 1997,1998 Dag Brattli <da...@cs.uit.no>
X  *     All Rights Reserved.
@@ -25,10 +24,10 @@
X  *
X  *     NOTICE:
X  *
- *     This driver is ment to be a small serial driver to be used for
- *     IR-chipsets that has a UART (16550) compatibility mode. If your
- *     chipset is is UART only, you should probably use IrTTY instead since
- *     the Linux serial driver is probably more robust and optimized.
+ *     This driver is ment to be a small half duplex serial driver to be
+ *     used for IR-chipsets that has a UART (16550) compatibility mode. If
+ *     your chipset is is UART only, you should probably use IrTTY instead
+ *     since the Linux serial driver is probably more robust and optimized.
X  *
X  *     The functions in this file may be used by FIR drivers, but this
X  *     driver knows nothing about FIR drivers so don't ever insert such
@@ -64,7 +63,6 @@
X #include <net/irda/irport.h>
X 
X #define IO_EXTENT 8
-#define CONFIG_HALF_DUPLEX
X 
X /* static unsigned int io[]  = { 0x3e8, ~0, ~0, ~0 }; */
X /* static unsigned int irq[] = { 11, 0, 0, 0 }; */
@@ -114,7 +112,7 @@
X  *    Start IO port 
X  *
X  */
-int irport_open( int iobase)
+int irport_open(int iobase)
X {
X 	DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase);
X 
@@ -134,7 +132,7 @@
X  *    Stop IO port
X  *
X  */
-void irport_close( int iobase) 
+void irport_close(int iobase) 
X {
X 	DEBUG(4, __FUNCTION__ "()\n");
X 
@@ -142,7 +140,7 @@
X 	outb(0, iobase+UART_MCR);
X 
X 	/* Turn off interrupts */
-	outb(0, iobase+UART_IER); 
+	outb(0, iobase+UART_IER);
X }
X 
X /*
@@ -186,16 +184,22 @@
X  *    more packets to send, we send them here.
X  *
X  */
-static void irport_write_wakeup( struct irda_device *idev)
+static void irport_write_wakeup(struct irda_device *idev)
X {
-	int actual = 0, count;
+	int actual = 0;
X 	int iobase;
X 
X 	ASSERT(idev != NULL, return;);
X 	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
X 
X 	/* Finished with frame?  */
-	if (idev->tx_buff.offset == idev->tx_buff.len)  {
+	if (idev->tx_buff.len > 0)  {
+		/* Write data left in transmit buffer */
+		actual = irport_write(idev->io.iobase2, idev->io.fifo_size, 
+				      idev->tx_buff.data, idev->tx_buff.len);
+		idev->tx_buff.data += actual;
+		idev->tx_buff.len  -= actual;
+	} else {
X 		iobase = idev->io.iobase2;
X 		/* 
X 		 *  Now serial buffer is almost free & we can start 
@@ -206,23 +210,14 @@
X 
X 		/* Schedule network layer, so we can get some more frames */
X 		mark_bh(NET_BH);
-#ifdef CONFIG_HALF_DUPLEX
+
X 		outb(UART_FCR_ENABLE_FIFO | 
X 		     UART_FCR_TRIGGER_14  |
X 		     UART_FCR_CLEAR_RCVR, iobase+UART_FCR); /* Enable FIFO's */
X 
X 		/* Turn on receive interrupts */
X 		outb(UART_IER_RLSI|UART_IER_RDI, iobase+UART_IER); 
-#endif
-		return;
X 	}
-
-	/* Write data left in transmit buffer */
-	count = idev->tx_buff.len - idev->tx_buff.offset;
-	actual = irport_write(idev->io.iobase2, idev->io.fifo_size, 
-			      idev->tx_buff.head, count);
-	idev->tx_buff.offset += actual;
-	idev->tx_buff.head += actual;
X }
X 
X /*
@@ -283,22 +278,19 @@
X 	if (irda_lock((void *) &dev->tbusy) == FALSE)
X 		return -EBUSY;
X 	
-        /*  
-	 *  Transfer skb to tx_buff while wrapping, stuffing and making CRC 
-	 */
+	/* Init tx buffer */
+	idev->tx_buff.data = idev->tx_buff.head;
+
+        /* Copy skb to tx_buff while wrapping, stuffing and making CRC */
X 	idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, 
X 					   idev->tx_buff.truesize);
X 	
-/* 	actual = irport_write(idev->io.iobase2, idev->io.fifo_size,  */
-/* 			      idev->tx_buff.data, idev->tx_buff.len); */
-	
-	idev->tx_buff.offset = actual;
-	idev->tx_buff.head = idev->tx_buff.data + actual;
+	idev->tx_buff.data += actual;
+	idev->tx_buff.len  -= actual;
X 
-#ifdef CONFIG_HALF_DUPLEX
X 	/* Turn on transmit finished interrupt. Will fire immediately!  */
X 	outb(UART_IER_THRI, iobase+UART_IER); 
-#endif
+
X 	dev_kfree_skb(skb);
X 	
X 	return 0;
@@ -318,44 +310,37 @@
X 	if (!idev)
X 		return;
X 
-	DEBUG( 4, __FUNCTION__ "()\n");
+	DEBUG(4, __FUNCTION__ "()\n");
X 
X 	iobase = idev->io.iobase2;
X 
-	if (idev->rx_buff.len == 0)
-		idev->rx_buff.head = idev->rx_buff.data;
-	
X 	/*  
X 	 * Receive all characters in Rx FIFO, unwrap and unstuff them. 
X          * async_unwrap_char will deliver all found frames  
X 	 */
X 	do {
-		async_unwrap_char(idev, inb( iobase+UART_RX));
+		async_unwrap_char(idev, inb(iobase+UART_RX));
X 
X 		/* Make sure we don't stay here to long */
X 		if (boguscount++ > 32) {
X 			DEBUG(0,__FUNCTION__ "(), breaking!\n");
X 			break;
X 		}
-
X 	} while (inb(iobase+UART_LSR) & UART_LSR_DR);	
X }
X 
X /*
X  * Function irport_interrupt (irq, dev_id, regs)
X  *
- *    
+ *    Interrupt handler
X  */
X void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs) 
X {
X 	struct irda_device *idev = (struct irda_device *) dev_id;
-
X 	int iobase;
X 	int iir, lsr;
X 	int boguscount = 0;
X 
-	DEBUG(5, __FUNCTION__ "(), irq %d\n", irq);
-	
X 	if (!idev) {
X 		printk(KERN_WARNING __FUNCTION__ 
X 		       "() irq %d for unknown device.\n", irq);
@@ -368,19 +353,13 @@
X 
X 	iir = inb(iobase + UART_IIR) & UART_IIR_ID;
X 	while (iir) {
-		DEBUG(4,__FUNCTION__ "(), iir=%#x\n", iir);
-
X 		/* Clear interrupt */
X 		lsr = inb(iobase+UART_LSR);
X 
X 		if ((iir & UART_IIR_THRI) && (lsr & UART_LSR_THRE)) {
X 			/* Transmitter ready for data */
X 			irport_write_wakeup(idev);
-		}
-#ifdef CONFIG_HALF_DUPLEX
-		else 
-#endif
-		if ((iir & UART_IIR_RDI) && (lsr & UART_LSR_DR)) {
+		} else if ((iir & UART_IIR_RDI) && (lsr & UART_LSR_DR)) {
X 	       		/* Receive interrupt */
X 			irport_receive(idev);
X 		}
@@ -393,7 +372,6 @@
X 	}
X 	idev->netdev.interrupt = 0;
X }
-
X 
X #ifdef MODULE
X 
diff -u --recursive --new-file v2.2.6/linux/drivers/net/irda/irtty.c linux/drivers/net/irda/irtty.c
--- v2.2.6/linux/drivers/net/irda/irtty.c	Fri Apr 16 14:47:30 1999
+++ linux/drivers/net/irda/irtty.c	Sat Apr 24 17:49:37 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Tue Dec  9 21:18:38 1997
- * Modified at:   Tue Apr  6 21:35:25 1999
+ * Modified at:   Thu Apr 22 09:20:24 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * Sources:       slip.c by Laurence Culhane,   <l...@holmes.demon.co.uk>
X  *                          Fred N. van Kempen, <wal...@uwalt.nl.mugnet.org>
@@ -45,22 +45,22 @@
X 
X static struct tty_ldisc irda_ldisc;
X 
-static int irtty_hard_xmit( struct sk_buff *skb, struct device *dev);
-static void irtty_wait_until_sent( struct irda_device *driver);
-static int irtty_is_receiving( struct irda_device *idev);
-static int irtty_net_init( struct device *dev);
+static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev);
+static void irtty_wait_until_sent(struct irda_device *driver);
+static int irtty_is_receiving(struct irda_device *idev);
+static int irtty_net_init(struct device *dev);
X static int irtty_net_open(struct device *dev);
X static int irtty_net_close(struct device *dev);
X 
-static int  irtty_open( struct tty_struct *tty);
-static void irtty_close( struct tty_struct *tty);
-static int  irtty_ioctl( struct tty_struct *, void *, int, void *);
-static int  irtty_receive_room( struct tty_struct *tty);
-static void irtty_change_speed( struct irda_device *dev, int baud);
-static void irtty_write_wakeup( struct tty_struct *tty);
+static int  irtty_open(struct tty_struct *tty);
+static void irtty_close(struct tty_struct *tty);
+static int  irtty_ioctl(struct tty_struct *, void *, int, void *);
+static int  irtty_receive_room(struct tty_struct *tty);
+static void irtty_change_speed(struct irda_device *dev, int baud);
+static void irtty_write_wakeup(struct tty_struct *tty);
X 
-static void irtty_receive_buf( struct tty_struct *, const unsigned char *, 
-			       char *, int);
+static void irtty_receive_buf(struct tty_struct *, const unsigned char *, 
+			      char *, int);
X char *driver_name = "irtty";
X 
X __initfunc(int irtty_init(void))
@@ -73,15 +73,15 @@
X 		return -ENOMEM;
X 	}
X 
-	dongles = hashbin_new( HB_LOCAL);
-	if ( dongles == NULL) {
-		printk( KERN_WARNING 
-			"IrDA: Can't allocate dongles hashbin!\n");
+	dongles = hashbin_new(HB_LOCAL);
+	if (dongles == NULL) {
+		printk(KERN_WARNING 
+		       "IrDA: Can't allocate dongles hashbin!\n");
X 		return -ENOMEM;
X 	}
X 
X 	/* Fill in our line protocol discipline, and register it */
-	memset( &irda_ldisc, 0, sizeof( irda_ldisc));
+	memset(&irda_ldisc, 0, sizeof( irda_ldisc));
X 
X 	irda_ldisc.magic = TTY_LDISC_MAGIC;
X  	irda_ldisc.name  = "irda";
@@ -97,10 +97,10 @@
X 	irda_ldisc.receive_room = irtty_receive_room;
X 	irda_ldisc.write_wakeup = irtty_write_wakeup;
X 	
-	if (( status = tty_register_ldisc( N_IRDA, &irda_ldisc)) != 0)  {
-		printk( KERN_ERR 
-			"IrDA: can't register line discipline (err = %d)\n", 
-			status);
+	if (( status = tty_register_ldisc(N_IRDA, &irda_ldisc)) != 0)  {
+		printk(KERN_ERR 
+		       "IrDA: can't register line discipline (err = %d)\n", 
+		       status);
X 	}
X 	
X 	return status;
@@ -120,10 +120,10 @@
X 	/*
X 	 *  Unregister tty line-discipline
X 	 */
-	if (( ret = tty_register_ldisc( N_IRDA, NULL))) {
-		printk( KERN_ERR 
-			"IrTTY: can't unregister line discipline (err = %d)\n",
- 			ret);
+	if ((ret = tty_register_ldisc(N_IRDA, NULL))) {
+		ERROR(__FUNCTION__ 
+		      "(), can't unregister line discipline (err = %d)\n",
+		      ret);
X 	}
X 
X 	/*
@@ -131,8 +131,8 @@
X 	 *  callback to irtty_close(), therefore we do give any deallocation
X 	 *  function to hashbin_destroy().
X 	 */
-	hashbin_delete( irtty, NULL);
-	hashbin_delete( dongles, NULL);
+	hashbin_delete(irtty, NULL);
+	hashbin_delete(dongles, NULL);
X }
X #endif /* MODULE */
X 
@@ -143,47 +143,45 @@
X  *    discipline is called for.  Because we are sure the tty line exists,
X  *    we only have to link it to a free IrDA channel.  
X  */
-static int irtty_open( struct tty_struct *tty) 
+static int irtty_open(struct tty_struct *tty) 
X {
X 	struct irtty_cb *self;
X 	char name[16];
X 	
-	ASSERT( tty != NULL, return -EEXIST;);
+	ASSERT(tty != NULL, return -EEXIST;);
X 
X 	/* First make sure we're not already connected. */
X 	self = (struct irtty_cb *) tty->disc_data;
-	if ( self != NULL && self->magic == IRTTY_MAGIC)
+	if (self != NULL && self->magic == IRTTY_MAGIC)
X 		return -EEXIST;
X 	
X 	/*
X 	 *  Allocate new instance of the driver
X 	 */
-	self = kmalloc( sizeof(struct irtty_cb), GFP_KERNEL);
-	if ( self == NULL) {
-		printk( KERN_ERR "IrDA: Can't allocate memory for "
-			"IrDA control block!\n");
+	self = kmalloc(sizeof(struct irtty_cb), GFP_KERNEL);
+	if (self == NULL) {
+		printk(KERN_ERR "IrDA: Can't allocate memory for "
+		       "IrDA control block!\n");
X 		return -ENOMEM;
X 	}
-	memset( self, 0, sizeof(struct irtty_cb));
+	memset(self, 0, sizeof(struct irtty_cb));
X 	
X 	self->tty = tty;
X 	tty->disc_data = self;
X 
X 	/* Give self a name */
-	sprintf( name, "%s%d", tty->driver.name,
-		 MINOR(tty->device) - tty->driver.minor_start +
-		 tty->driver.name_base);
-
+	sprintf(name, "%s%d", tty->driver.name,
+		MINOR(tty->device) - tty->driver.minor_start +
+		tty->driver.name_base);
+	
X 	/* hashbin_insert( irtty, (QUEUE*) self, 0, self->name); */
-	hashbin_insert( irtty, (QUEUE*) self, (int) self, NULL);
+	hashbin_insert(irtty, (QUEUE*) self, (int) self, NULL);
X 
-	if (tty->driver.flush_buffer) {
+	if (tty->driver.flush_buffer)
X 		tty->driver.flush_buffer(tty);
-	}
-
-	if (tty->ldisc.flush_buffer) {
+	
+	if (tty->ldisc.flush_buffer)
X 		tty->ldisc.flush_buffer(tty);
-	}
X 	
X 	self->magic = IRTTY_MAGIC;
X 
@@ -198,12 +196,12 @@
X 	 *  that are not device dependent (such as link disconnect time) so
X 	 *  this parameter can be set by IrLAP (or the user) instead. DB
X 	 */
-	irda_init_max_qos_capabilies( &self->idev.qos);
+	irda_init_max_qos_capabilies(&self->idev.qos);
X 
X 	/* The only value we must override it the baudrate */
X 	self->idev.qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
X 		IR_115200;
-	self->idev.qos.min_turn_time.bits = 0x03;
+	self->idev.qos.min_turn_time.bits = 0x0f;
X 	self->idev.flags = IFF_SIR | IFF_PIO;
X 	irda_qos_bits_to_value(&self->idev.qos);
X 
@@ -236,7 +234,7 @@
X }
X 
X /* 
- *  Function irtty_close ( tty)
+ *  Function irtty_close (tty)
X  *
X  *    Close down a IrDA channel. This means flushing out any pending queues,
X  *    and then restoring the TTY line discipline to what it was before it got
@@ -272,14 +270,40 @@
X  	MOD_DEC_USE_COUNT;
X }
X 
+/*
+ * Function irtty_stop_receiver (irda_device, stop)
+ *
+ *    
+ *
+ */
+static void irtty_stop_receiver(struct irda_device *idev, int stop)
+{
+	struct termios old_termios;
+	struct irtty_cb *self;
+	int cflag;
+
+	self = (struct irtty_cb *) idev->priv;
+
+	old_termios = *(self->tty->termios);
+	cflag = self->tty->termios->c_cflag;
+	
+	if (stop)
+		cflag &= ~CREAD;
+	else
+		cflag |= CREAD;
+
+	self->tty->termios->c_cflag = cflag;
+	self->tty->driver.set_termios(self->tty, &old_termios);
+}
+
X /* 
- *  Function irtty_change_speed ( self, baud)
+ *  Function irtty_change_speed (self, baud)
X  *
X  *    Change the speed of the serial port. The driver layer must check that
X  *    all transmission has finished using the irtty_wait_until_sent() 
X  *    function.
X  */
-static void irtty_change_speed( struct irda_device *idev, int baud) 
+static void irtty_change_speed(struct irda_device *idev, int baud) 
X {
X         struct termios old_termios;
X 	struct irtty_cb *self;
@@ -287,22 +311,22 @@
X 
X 	DEBUG(4,__FUNCTION__ "(), <%ld>\n", jiffies); 
X 
-	ASSERT( idev != NULL, return;);
-	ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
+	ASSERT(idev != NULL, return;);
+	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
X 
X self = (struct irtty_cb *) idev->priv;
X 
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRTTY_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IRTTY_MAGIC, return;);
X 
X 	old_termios = *(self->tty->termios);
X 	cflag = self->tty->termios->c_cflag;
X 
X 	cflag &= ~CBAUD;
X 
-	DEBUG( 4, __FUNCTION__ "(), Setting speed to %d\n", baud);
+	DEBUG(4, __FUNCTION__ "(), Setting speed to %d\n", baud);
X 
-	switch( baud) {
+	switch (baud) {
X 	case 1200:
X 		cflag |= B1200;
X 		break;
@@ -331,7 +355,7 @@
X 	}	
X 
X 	self->tty->termios->c_cflag = cflag;
-	self->tty->driver.set_termios( self->tty, &old_termios);
+	self->tty->driver.set_termios(self->tty, &old_termios);
X }
X 
X /*
@@ -340,43 +364,42 @@
X  *    Initialize attached dongle. Warning, must be called with a process
X  *    context!
X  */
-static void irtty_init_dongle( struct irtty_cb *self, int type)
+static void irtty_init_dongle(struct irtty_cb *self, int type)
X {
X 	struct dongle_q *node;
X 
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRTTY_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IRTTY_MAGIC, return;);
X 
X #ifdef CONFIG_KMOD
X 	/* Try to load the module needed */
X 	switch( type) {
X 	case ESI_DONGLE:
-		DEBUG( 0, __FUNCTION__ "(), ESI dongle!\n");
-		request_module( "esi");
+		MESSAGE("IrDA: Trying to initialize ESI dongle!\n");
+		request_module("esi");
X 		break;
X 	case TEKRAM_DONGLE:
-		DEBUG( 0, __FUNCTION__ "(), Tekram dongle!\n");
-		request_module( "tekram");
+		MESSAGE("IrDA: Trying to initialize Tekram dongle!\n");
+		request_module("tekram");
X 		break;
X 	case ACTISYS_DONGLE:     /* FALLTHROUGH */
X 	case ACTISYS_PLUS_DONGLE:
-		DEBUG( 0, __FUNCTION__ "(), ACTiSYS dongle!\n");
-		request_module( "actisys");
+		MESSAGE("IrDA: Trying to initialize ACTiSYS dongle!\n");
+		request_module("actisys");
X 		break;
X 	case GIRBIL_DONGLE:
-		DEBUG( 0, __FUNCTION__ "(), GIrBIL dongle!\n");
-		request_module( "girbil");
+		MESSAGE("IrDA: Trying to initialize GIrBIL dongle!\n");
+		request_module("girbil");
X 		break;
X 	default:
-		DEBUG( 0, __FUNCTION__ "(), Unknown dongle type!\n");
+		ERROR("Unknown dongle type!\n");
X 		return;
-		break;
X 	}
X #endif /* CONFIG_KMOD */
X 
-	node = hashbin_find( dongles, type, NULL);
+	node = hashbin_find(dongles, type, NULL);
X 	if ( !node) {
-		DEBUG(0, __FUNCTION__ "(), Unable to find requested dongle\n");
+		ERROR("Unable to find requested dongle\n");
X 		return;
X 	}
X 	self->dongle_q = node;
@@ -387,14 +410,14 @@
X 	/*
X 	 * Now initialize the dongle!
X 	 */
-	node->dongle->open( &self->idev, type);
-	node->dongle->qos_init( &self->idev, &self->idev.qos);
+	node->dongle->open(&self->idev, type);
+	node->dongle->qos_init(&self->idev, &self->idev.qos);
X 	
X 	/* Reset dongle */
-	node->dongle->reset( &self->idev, 0);
+	node->dongle->reset(&self->idev, 0);
X 
X 	/* Set to default baudrate */
-	node->dongle->change_speed( &self->idev, 9600);
+	node->dongle->change_speed(&self->idev, 9600);
X }
X 
X /*
@@ -411,25 +434,25 @@
X 
X 	self = (struct irtty_cb *) tty->disc_data;
X 
-	ASSERT( self != NULL, return -ENODEV;);
-	ASSERT( self->magic == IRTTY_MAGIC, return -EBADR;);
+	ASSERT(self != NULL, return -ENODEV;);
+	ASSERT(self->magic == IRTTY_MAGIC, return -EBADR;);
X 
-	if ( _IOC_DIR(cmd) & _IOC_READ)
+	if (_IOC_DIR(cmd) & _IOC_READ)
X 		err = verify_area( VERIFY_WRITE, (void *) arg, size);
-	else if ( _IOC_DIR(cmd) & _IOC_WRITE)
+	else if (_IOC_DIR(cmd) & _IOC_WRITE)
X 		err = verify_area( VERIFY_READ, (void *) arg, size);
-	if ( err)
+	if (err)
X 		return err;
X 	
X 	switch(cmd) {
X 	case TCGETS:
X 	case TCGETA:
-		return n_tty_ioctl( tty, (struct file *) file, cmd, 
-				    (unsigned long) arg);
+		return n_tty_ioctl(tty, (struct file *) file, cmd, 
+				   (unsigned long) arg);
X 		break;
X 	case IRTTY_IOCTDONGLE:
X 		/* Initialize dongle */
-		irtty_init_dongle( self, (int) arg);
+		irtty_init_dongle(self, (int) arg);
X 		break;
X 	default:
X 		return -ENOIOCTLCMD;
@@ -450,8 +473,8 @@
X {
X 	struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
X 
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRTTY_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IRTTY_MAGIC, return;);
X 	
X 	/* Read the characters out of the buffer */
X  	while (count--) {
@@ -461,19 +484,19 @@
X  		if (fp && *fp++) { 
X 			DEBUG( 0, "Framing or parity error!\n");
X 			irda_device_set_media_busy( &self->idev, TRUE);
-			/* sl->rx_errors++; */
+
X  			cp++;
X  			continue;
X  		}
X 		/* Unwrap and destuff one byte */
-		async_unwrap_char( &self->idev, *cp++);
+		async_unwrap_char(&self->idev, *cp++);
X 	}
X }
X 
X /*
X  * Function irtty_hard_xmit (skb, dev)
X  *
- *    Transmit skb
+ *    Transmit frame
X  *
X  */
X static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev)
@@ -482,9 +505,6 @@
X 	struct irda_device *idev;
X 	int actual = 0;
X 
-	ASSERT( dev != NULL, return 0;);
-	ASSERT( skb != NULL, return 0;);
-
X 	idev = (struct irda_device *) dev->priv;
X 
X 	ASSERT(idev != NULL, return 0;);
@@ -498,10 +518,11 @@
X 	/* Lock transmit buffer */
X 	if (irda_lock((void *) &dev->tbusy) == FALSE)
X 		return -EBUSY;
-
-        /*  
-	 *  Transfer skb to tx_buff while wrapping, stuffing and making CRC 
-	 */
+	
+	/* Init tx buffer*/
+	idev->tx_buff.data = idev->tx_buff.head;
+	
+        /* Copy skb to tx_buff while wrapping, stuffing and making CRC */
X         idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, 
X 					   idev->tx_buff.truesize); 
X 
@@ -509,13 +530,14 @@
X 
X 	dev->trans_start = jiffies;
X 
-	if ( self->tty->driver.write)
+	if (self->tty->driver.write)
X 		actual = self->tty->driver.write(self->tty, 0, 
X 						 idev->tx_buff.data, 
X 						 idev->tx_buff.len);
X 
-	idev->tx_buff.offset = actual;
-	idev->tx_buff.head = idev->tx_buff.data + actual;
+	/* Hide the part we just transmitted */
+	idev->tx_buff.data += actual;
+	idev->tx_buff.len -= actual;
X 
X 	idev->stats.tx_packets++;
X 	idev->stats.tx_bytes += idev->tx_buff.len;
@@ -524,7 +546,7 @@
X 	 *  Did we transmit the whole frame? Commented out for now since
X 	 *  I must check if this optimalization really works. DB.
X 	 */
- 	if (( idev->tx.count - idev->tx.ptr) <= 0) {
+ 	if ((idev->tx_buff.len) == 0) {
X  		DEBUG( 4, "irtty_xmit_buf: finished with frame!\n");
X  		self->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
X  		irda_unlock( &self->tbusy);
@@ -541,8 +563,9 @@
X  *    Used by the TTY to find out how much data we can receive at a time
X  * 
X */
-static int irtty_receive_room( struct tty_struct *tty) 
+static int irtty_receive_room(struct tty_struct *tty) 
X {
+	DEBUG(0, __FUNCTION__ "()\n");
X 	return 65536;  /* We can handle an infinite amount of data. :-) */
X }
X 
@@ -553,47 +576,42 @@
X  *    more packets to send, we send them here.
X  *
X  */
-static void irtty_write_wakeup( struct tty_struct *tty) 
+static void irtty_write_wakeup(struct tty_struct *tty) 
X {
-	int actual = 0, count;
X 	struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
X 	struct irda_device *idev;
+	int actual = 0;
X 	
X 	/* 
X 	 *  First make sure we're connected. 
X 	 */
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRTTY_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IRTTY_MAGIC, return;);
X 
X 	idev = &self->idev;
X 
-	/*
-	 *  Finished with frame?
-	 */
-	if ( idev->tx_buff.offset == idev->tx_buff.len)  {
-
+	/* Finished with frame?  */
+	if (idev->tx_buff.len > 0)  {
+		/* Write data left in transmit buffer */
+		actual = tty->driver.write(tty, 0, idev->tx_buff.data, 
+					   idev->tx_buff.len);
+
+		idev->tx_buff.data += actual;
+		idev->tx_buff.len  -= actual;
+	} else {		
X 		/* 
X 		 *  Now serial buffer is almost free & we can start 
X 		 *  transmission of another packet 
X 		 */
X 		DEBUG(5, __FUNCTION__ "(), finished with frame!\n");
-
+		
X 		tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
X 
X 		idev->netdev.tbusy = 0; /* Unlock */
-
+			
X 		/* Tell network layer that we want more frames */
-		mark_bh( NET_BH);
-
-		return;
+		mark_bh(NET_BH);
X 	}
-	/*
-	 *  Write data left in transmit buffer
-	 */
-	count = idev->tx_buff.len - idev->tx_buff.offset;
-	actual = tty->driver.write( tty, 0, idev->tx_buff.head, count);
-	idev->tx_buff.offset += actual;
-	idev->tx_buff.head += actual;
X }
X 
X /*
@@ -602,9 +620,9 @@
X  *    Return TRUE is we are currently receiving a frame
X  *
X  */
-static int irtty_is_receiving( struct irda_device *idev)
+static int irtty_is_receiving(struct irda_device *idev)
X {
-	return ( idev->rx_buff.state != OUTSIDE_FRAME);
+	return (idev->rx_buff.state != OUTSIDE_FRAME);
X }
X 
X /*
@@ -614,20 +632,20 @@
X  *    to change the speed of the serial port. Warning this function must
X  *    be called with a process context!
X  */
-static void irtty_wait_until_sent( struct irda_device *idev)
+static void irtty_wait_until_sent(struct irda_device *idev)
X {
X 	struct irtty_cb *self = (struct irtty_cb *) idev->priv;
X 
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRTTY_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IRTTY_MAGIC, return;);
X 	
-	DEBUG( 4, "Chars in buffer %d\n", 
-	       self->tty->driver.chars_in_buffer( self->tty));
+	DEBUG(4, "Chars in buffer %d\n", 
+	      self->tty->driver.chars_in_buffer(self->tty));
X 	
-	tty_wait_until_sent( self->tty, 0);
+	tty_wait_until_sent(self->tty, 0);
X }
X 
-int irtty_register_dongle( struct dongle *dongle)
+int irtty_register_dongle(struct dongle *dongle)
X {
X 	struct dongle_q *new;
X 	
@@ -638,12 +656,11 @@
X         }
X 	
X 	/* Make new IrDA dongle */
-        new = (struct dongle_q *)kmalloc(sizeof(struct dongle_q), GFP_KERNEL);
-        if (new == NULL) {
-                return 1;
+        new = (struct dongle_q *) kmalloc(sizeof(struct dongle_q), GFP_KERNEL);
+        if (new == NULL)
+                return -1;
X 		
-        }
-	memset( new, 0, sizeof( struct dongle_q));
+	memset(new, 0, sizeof( struct dongle_q));
X         new->dongle = dongle;
X 
X 	/* Insert IrDA dongle into hashbin */
@@ -652,16 +669,16 @@
X         return 0;
X }
X 
-void irtty_unregister_dongle( struct dongle *dongle)
+void irtty_unregister_dongle(struct dongle *dongle)
X {
X 	struct dongle_q *node;
X 
-	node = hashbin_remove( dongles, dongle->type, NULL);
-	if ( !node) {
-		DEBUG( 0, __FUNCTION__ "(), dongle not found!\n");
+	node = hashbin_remove(dongles, dongle->type, NULL);
+	if (!node) {
+		ERROR(__FUNCTION__ "(), dongle not found!\n");
X 		return;
X 	}
-	kfree( node);
+	kfree(node);
X }
X 
X 
@@ -696,26 +713,24 @@
X 	set_fs(get_ds());
X 	
X 	if (tty->driver.ioctl(tty, NULL, TIOCMSET, (unsigned long) &arg)) { 
-		DEBUG(0, __FUNCTION__ "(), error!\n");
+		ERROR(__FUNCTION__ "(), error doing ioctl!\n");
X 	}
X 	set_fs(fs);
X }
X 
-
-static int irtty_net_init( struct device *dev)
+static int irtty_net_init(struct device *dev)
X {
X 	/* Set up to be a normal IrDA network device driver */
-	irda_device_setup( dev);
+	irda_device_setup(dev);
X 
X 	/* Insert overrides below this line! */
X 
X 	return 0;
X }
X 
-
-static int irtty_net_open( struct device *dev)
+static int irtty_net_open(struct device *dev)
X {
-	ASSERT( dev != NULL, return -1;);
+	ASSERT(dev != NULL, return -1;);
X 
X 	/* Ready to play! */
X 	dev->tbusy = 0;
@@ -729,7 +744,7 @@
X 
X static int irtty_net_close(struct device *dev)
X {
-	ASSERT( dev != NULL, return -1;);
+	ASSERT(dev != NULL, return -1;);
X 	
X 	/* Stop device */
X 	dev->tbusy = 1;
diff -u --recursive --new-file v2.2.6/linux/drivers/net/irda/pc87108.c linux/drivers/net/irda/pc87108.c
--- v2.2.6/linux/drivers/net/irda/pc87108.c	Fri Apr 16 14:47:30 1999
+++ linux/drivers/net/irda/pc87108.c	Sat Apr 24 17:49:37 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sat Nov  7 21:43:15 1998
- * Modified at:   Sat Apr  3 15:54:47 1999
+ * Modified at:   Tue Apr 20 11:11:39 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>
@@ -734,10 +734,9 @@
X 
X 	/* Decide if we should use PIO or DMA transfer */
X 	if ( idev->io.baudrate > 115200) {
-		memcpy( idev->tx_buff.data, skb->data, skb->len);
+		idev->tx_buff.data = idev->tx_buff.head;
+ memcpy(idev->tx_buff.data, skb->data, skb->len);
X 		idev->tx_buff.len = skb->len;
-		idev->tx_buff.head = idev->tx_buff.data;
-		idev->tx_buff.offset = 0;
X 
X 		mtt = irda_get_mtt( skb);
X 	        if ( mtt > 50) {
@@ -767,11 +766,10 @@
X 	     		pc87108_dma_write( idev, iobase);
X 		}
X         } else {
-	        idev->tx_buff.len = async_wrap_skb( skb, idev->tx_buff.data, 
-						    idev->tx_buff.truesize);
+	        idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, 
+						   idev->tx_buff.truesize);
X 		
-		idev->tx_buff.offset = 0;
-		idev->tx_buff.head = idev->tx_buff.data;
+		idev->tx_buff.data = idev->tx_buff.head;
X 		
X 		/* Add interrupt on tx low level (will fire immediately) */
X 		switch_bank( iobase, BANK0);
@@ -945,8 +943,7 @@
X 	
X 	/* driver->media_busy = FALSE; */
X 	idev->io.direction = IO_RECV;
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 03'
echo 'File patch-2.2.7 is continued in part 04'
echo 04 > _shar_seq_.tmp
#!/bin/sh
# this is part 06 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 06; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
+	if (!rrpriv->info){
+		kfree(rrpriv->rx_ctrl);
+		ecode = -ENOMEM;
+		goto error;
+	}
+	memset(rrpriv->rx_ctrl, 0, 256 * sizeof(struct ring_ctrl));
+	memset(rrpriv->info, 0, sizeof(struct rr_info));
+	mb();
+
+	spin_lock_irqsave(&rrpriv->lock, flags);
+	writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, ®s->HostCtrl);
+	spin_unlock_irqrestore(&rrpriv->lock, flags);
X 
X 	if (request_irq(dev->irq, rr_interrupt, SA_SHIRQ, rrpriv->name, dev))
X 	{
X 		printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
X 		       dev->name, dev->irq);
-		return -EAGAIN;
+		ecode = -EAGAIN;
+		goto error;
X 	}
X 
-	rrpriv->rx_ctrl = kmalloc(256*sizeof(struct ring_ctrl),
-				  GFP_KERNEL | GFP_DMA);
-	rrpriv->info = kmalloc(sizeof(struct rr_info), GFP_KERNEL | GFP_DMA);
-
X 	rr_init1(dev);
X 
X 	dev->tbusy = 0;
-#if 0
-	dev->interrupt = 0;
-#endif
X 	dev->start = 1;
X 
X 	MOD_INC_USE_COUNT;
X 	return 0;
+
+ error:
+	spin_lock_irqsave(&rrpriv->lock, flags);
+	writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, ®s->HostCtrl);
+	spin_unlock_irqrestore(&rrpriv->lock, flags);
+
+	dev->tbusy = 1;
+	dev->start = 0;
+	return -ENOMEM;
X }
X 
X 
@@ -965,12 +1009,13 @@
X 	printk("%s: dumping NIC TX rings\n", dev->name);
X 
X 	printk("RxPrd %08x, TxPrd %02x, EvtPrd %08x, TxPi %02x, TxCtrlPi %02x\n",
-	       regs->RxPrd, regs->TxPrd, regs->EvtPrd, regs->TxPi,
+	       readl(®s->RxPrd), readl(®s->TxPrd),
+	       readl(®s->EvtPrd), readl(®s->TxPi),
X 	       rrpriv->info->tx_ctrl.pi);
X 
-	printk("Error code 0x%x\n", regs->Fail1);
+	printk("Error code 0x%x\n", readl(®s->Fail1));
X 
-	index = (((regs->EvtPrd >> 8) & 0xff ) - 1) % EVT_RING_ENTRIES;
+	index = (((readl(®s->EvtPrd) >> 8) & 0xff ) - 1) % EVT_RING_ENTRIES;
X 	cons = rrpriv->dirty_tx;
X 	printk("TX ring index %i, TX consumer %i\n",
X 	       index, cons);
@@ -989,12 +1034,12 @@
X 	if (rrpriv->tx_skbuff[cons]){
X 		len = min(0x80, rrpriv->tx_skbuff[cons]->len);
X 		printk("skbuff for cons %i is valid - dumping data (0x%x bytes - skbuff len 0x%x)\n", cons, len, rrpriv->tx_skbuff[cons]->len);
-		printk("mode 0x%x, size 0x%x,\n phys %08x (virt %08x), skbuff-addr %08x, truesize 0x%x\n",
+		printk("mode 0x%x, size 0x%x,\n phys %08x (virt %08lx), skbuff-addr %08lx, truesize 0x%x\n",
X 		       rrpriv->tx_ring[cons].mode,
X 		       rrpriv->tx_ring[cons].size,
-		       rrpriv->tx_ring[cons].addr,
-		       (unsigned int)bus_to_virt(rrpriv->tx_ring[cons].addr),
-		       (unsigned int)rrpriv->tx_skbuff[cons]->data,
+		       rrpriv->tx_ring[cons].addr.addrlo,
+		       (unsigned long)bus_to_virt(rrpriv->tx_ring[cons].addr.addrlo),
+		       (unsigned long)rrpriv->tx_skbuff[cons]->data,
X 		       (unsigned int)rrpriv->tx_skbuff[cons]->truesize);
X 		for (i = 0; i < len; i++){
X 			if (!(i & 7))
@@ -1009,7 +1054,7 @@
X 		printk("mode 0x%x, size 0x%x, phys-addr %08x\n",
X 		       rrpriv->tx_ring[i].mode,
X 		       rrpriv->tx_ring[i].size,
-		       rrpriv->tx_ring[i].addr);
+		       rrpriv->tx_ring[i].addr.addrlo);
X 
X }
X 
@@ -1033,24 +1078,26 @@
X 	 */
X 	spin_lock(&rrpriv->lock);
X 
-	tmp = regs->HostCtrl;
+	tmp = readl(®s->HostCtrl);
X 	if (tmp & NIC_HALTED){
X 		printk("%s: NIC already halted\n", dev->name);
X 		rr_dump(dev);
-	}else
-		tmp |= HALT_NIC;
-	regs->HostCtrl = tmp;
+	}else{
+		tmp |= HALT_NIC | RR_CLEAR_INT;
+		writel(tmp, ®s->HostCtrl);
+		mb();
+	}
X 
X 	rrpriv->fw_running = 0;
X 
-	regs->TxPi = 0;
-	regs->IpRxPi = 0;
+	writel(0, ®s->TxPi);
+	writel(0, ®s->IpRxPi);
X 
-	regs->EvtCon = 0;
-	regs->EvtPrd = 0;
+	writel(0, ®s->EvtCon);
+	writel(0, ®s->EvtPrd);
X 
X 	for (i = 0; i < CMD_RING_ENTRIES; i++)
-		regs->CmdRing[i] = 0;
+		writel(0, ®s->CmdRing[i]);
X 
X 	rrpriv->info->tx_ctrl.entries = 0;
X 	rrpriv->info->cmd_ctrl.pi = 0;
@@ -1060,7 +1107,7 @@
X 	for (i = 0; i < TX_RING_ENTRIES; i++) {
X 		if (rrpriv->tx_skbuff[i]) {
X 			rrpriv->tx_ring[i].size = 0;
-			rrpriv->tx_ring[i].addr = 0;
+			set_rraddr(&rrpriv->tx_ring[i].addr, 0);
X 			dev_kfree_skb(rrpriv->tx_skbuff[i]);
X 		}
X 	}
@@ -1068,7 +1115,7 @@
X 	for (i = 0; i < RX_RING_ENTRIES; i++) {
X 		if (rrpriv->rx_skbuff[i]) {
X 			rrpriv->rx_ring[i].size = 0;
-			rrpriv->rx_ring[i].addr = 0;
+			set_rraddr(&rrpriv->rx_ring[i].addr, 0);
X 			dev_kfree_skb(rrpriv->rx_skbuff[i]);
X 		}
X 	}
@@ -1094,6 +1141,10 @@
X 	u32 *ifield;
X 	struct sk_buff *new_skb;
X 
+	if (readl(®s->Mode) & FATAL_ERR)
+		printk("error codes Fail1 %02x, Fail2 %02x\n",
+		       readl(®s->Fail1), readl(®s->Fail2));
+
X 	/*
X 	 * We probably need to deal with tbusy here to prevent overruns.
X 	 */
@@ -1128,11 +1179,11 @@
X 	index = txctrl->pi;
X 
X 	rrpriv->tx_skbuff[index] = skb;
-	rrpriv->tx_ring[index].addr = virt_to_bus(skb->data);
+	set_rraddr(&rrpriv->tx_ring[index].addr, skb->data);
X 	rrpriv->tx_ring[index].size = len + 8; /* include IFIELD */
X 	rrpriv->tx_ring[index].mode = PACKET_START | PACKET_END;
X 	txctrl->pi = (index + 1) % TX_RING_ENTRIES;
-	regs->TxPi = txctrl->pi;
+	writel(txctrl->pi, ®s->TxPi);
X 
X 	if (txctrl->pi == rrpriv->dirty_tx){
X 		rrpriv->tx_full = 1;
@@ -1167,8 +1218,9 @@
X {
X 	struct rr_private *rrpriv;
X 	struct rr_regs *regs;
+	unsigned long eptr, segptr;
X 	int i, j;
-	u32 localctrl, eptr, sptr, segptr, len, tmp;
+	u32 localctrl, sptr, len, tmp;
X 	u32 p2len, p2size, nr_seg, revision, io, sram_size;
X 	struct eeprom *hw = NULL;
X 
@@ -1178,40 +1230,44 @@
X 	if (dev->flags & IFF_UP)
X 		return -EBUSY;
X 
-	if (!(regs->HostCtrl & NIC_HALTED)){
+	if (!(readl(®s->HostCtrl) & NIC_HALTED)){
X 		printk("%s: Trying to load firmware to a running NIC.\n", 
X 		       dev->name);
X 		return -EBUSY;
X 	}
X 
-	localctrl = regs->LocalCtrl;
-	regs->LocalCtrl = 0;
+	localctrl = readl(®s->LocalCtrl);
+	writel(0, ®s->LocalCtrl);
X 
-	regs->EvtPrd = 0;
-	regs->RxPrd = 0;
-	regs->TxPrd = 0;
+	writel(0, ®s->EvtPrd);
+	writel(0, ®s->RxPrd);
+	writel(0, ®s->TxPrd);
X 
X 	/*
X 	 * First wipe the entire SRAM, otherwise we might run into all
X 	 * kinds of trouble ... sigh, this took almost all afternoon
X 	 * to track down ;-(
X 	 */
-	io = regs->ExtIo;
-	regs->ExtIo = 0;
-	sram_size = read_eeprom_word(rrpriv, (void *)8);
+	io = readl(®s->ExtIo);
+	writel(0, ®s->ExtIo);
+	sram_size = rr_read_eeprom_word(rrpriv, (void *)8);
X 
X 	for (i = 200; i < sram_size / 4; i++){
-		regs->WinBase = i * 4;
-		regs->WinData = 0;
+		writel(i * 4, ®s->WinBase);
+		mb();
+		writel(0, ®s->WinData);
+		mb();
X 	}
-	regs->ExtIo = io;
+	writel(io, ®s->ExtIo);
+	mb();
X 
-	eptr = read_eeprom_word(rrpriv, &hw->rncd_info.AddrRunCodeSegs);
+	eptr = (unsigned long)rr_read_eeprom_word(rrpriv,
+					       &hw->rncd_info.AddrRunCodeSegs);
X 	eptr = ((eptr & 0x1fffff) >> 3);
X 
-	p2len = read_eeprom_word(rrpriv, (void *)(0x83*4));
+	p2len = rr_read_eeprom_word(rrpriv, (void *)(0x83*4));
X 	p2len = (p2len << 2);
-	p2size = read_eeprom_word(rrpriv, (void *)(0x84*4));
+	p2size = rr_read_eeprom_word(rrpriv, (void *)(0x84*4));
X 	p2size = ((p2size & 0x1fffff) >> 3);
X 
X 	if ((eptr < p2size) || (eptr > (p2size + p2len))){
@@ -1219,7 +1275,7 @@
X 		goto out;
X 	}
X 
-	revision = read_eeprom_word(rrpriv, &hw->manf.HeaderFmt);
+	revision = rr_read_eeprom_word(rrpriv, &hw->manf.HeaderFmt);
X 
X 	if (revision != 1){
X 		printk("%s: invalid firmware format (%i)\n",
@@ -1227,18 +1283,18 @@
X 		goto out;
X 	}
X 
-	nr_seg = read_eeprom_word(rrpriv, (void *)eptr);
+	nr_seg = rr_read_eeprom_word(rrpriv, (void *)eptr);
X 	eptr +=4;
X #if (DEBUG > 1)
X 	printk("%s: nr_seg %i\n", dev->name, nr_seg);
X #endif
X 
X 	for (i = 0; i < nr_seg; i++){
-		sptr = read_eeprom_word(rrpriv, (void *)eptr);
+		sptr = rr_read_eeprom_word(rrpriv, (void *)eptr);
X 		eptr += 4;
-		len = read_eeprom_word(rrpriv, (void *)eptr);
+		len = rr_read_eeprom_word(rrpriv, (void *)eptr);
X 		eptr += 4;
-		segptr = read_eeprom_word(rrpriv, (void *)eptr);
+		segptr = (unsigned long)rr_read_eeprom_word(rrpriv, (void *)eptr);
X 		segptr = ((segptr & 0x1fffff) >> 3);
X 		eptr += 4;
X #if (DEBUG > 1)
@@ -1246,16 +1302,19 @@
X 		       dev->name, i, sptr, len, segptr);
X #endif
X 		for (j = 0; j < len; j++){
-			tmp = read_eeprom_word(rrpriv, (void *)segptr);
-			regs->WinBase = sptr;
-			regs->WinData = tmp;
+			tmp = rr_read_eeprom_word(rrpriv, (void *)segptr);
+			writel(sptr, ®s->WinBase);
+			mb();
+			writel(tmp, ®s->WinData);
+			mb();
X 			segptr += 4;
X 			sptr += 4;
X 		}
X 	}
X 
X out:
-	regs->LocalCtrl = localctrl;
+	writel(localctrl, ®s->LocalCtrl);
+	mb();
X 	return 0;
X }
X 
@@ -1291,7 +1350,7 @@
X 			error = -ENOMEM;
X 			goto out;
X 		}
-		i = read_eeprom(rrpriv, 0, image, EEPROM_BYTES);
+		i = rr_read_eeprom(rrpriv, 0, image, EEPROM_BYTES);
X 		if (i != EEPROM_BYTES){
X 			kfree(image);
X 			printk(KERN_ERR "%s: Error reading EEPROM\n",
@@ -1325,7 +1384,7 @@
X 		}
X 
X 		oldimage = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL);
-		if (!image){
+		if (!oldimage){
X 			printk(KERN_ERR "%s: Unable to allocate memory "
X 			       "for old EEPROM image\n", dev->name);
X 			error = -ENOMEM;
@@ -1343,7 +1402,7 @@
X 			printk(KERN_ERR "%s: Error writing EEPROM\n",
X 			       dev->name);
X 
-		i = read_eeprom(rrpriv, 0, oldimage, EEPROM_BYTES);
+		i = rr_read_eeprom(rrpriv, 0, oldimage, EEPROM_BYTES);
X 		if (i != EEPROM_BYTES)
X 			printk(KERN_ERR "%s: Error reading back EEPROM "
X 			       "image\n", dev->name);
@@ -1354,7 +1413,6 @@
X 			       dev->name);
X 			error = -EFAULT;
X 		}
-
X 		kfree(image);
X 		kfree(oldimage);
X 		break;
@@ -1374,6 +1432,6 @@
X 
X /*
X  * Local variables:
- * compile-command: "gcc -D__SMP__ -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -pipe -fomit-frame-pointer -fno-strength-reduce -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 -DCPU=686 -c rrunner.c"
+ * compile-command: "gcc -D__SMP__ -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -pipe -fomit-frame-pointer -fno-strength-reduce -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 -DCPU=686 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h -c rrunner.c"
X  * End:
X  */
diff -u --recursive --new-file v2.2.6/linux/drivers/net/rrunner.h linux/drivers/net/rrunner.h
--- v2.2.6/linux/drivers/net/rrunner.h	Tue Dec 22 14:16:56 1998
+++ linux/drivers/net/rrunner.h	Sat Apr 24 17:51:48 1999
@@ -278,7 +278,6 @@
X #define TRACE_ON_WHAT_BIT	0x00020000    /* Traces on */
X #define ONEM_BUF_WHAT_BIT	0x00040000    /* 1Meg vs 256K */
X #define CHAR_API_WHAT_BIT	0x00080000    /* Char API vs network only */
-#define MS_DOS_WHAT_BIT		0x00100000    /* MS_DOS */
X #define CMD_EVT_WHAT_BIT	0x00200000    /* Command event */
X #define LONG_TX_WHAT_BIT	0x00400000
X #define LONG_RX_WHAT_BIT	0x00800000
@@ -486,6 +485,63 @@
X #define  SAME_IFIELD		0x80
X 
X 
+typedef struct {
+#if (BITS_PER_LONG == 64)
+	u64 addrlo;
+#else
+	u32 addrhi;
+	u32 addrlo;
+#endif
+} rraddr;
+
+
+static inline void set_rraddr(rraddr *ra, volatile void *addr)
+{
+	unsigned long baddr = virt_to_bus((void *)addr);
+#if (BITS_PER_LONG == 64)
+	ra->addrlo = baddr;
+#else
+    /* Don't bother setting zero every time */
+	ra->addrlo = baddr;
+#endif
+	mb();
+}
+
+
+static inline void set_rxaddr(struct rr_regs *regs, volatile void *addr)
+{
+	unsigned long baddr = virt_to_bus((void *)addr);
+#if (BITS_PER_LONG == 64) && defined(__LITTLE_ENDIAN)
+	writel(baddr & 0xffffffff, ®s->RxRingHi);
+	writel(baddr >> 32, ®s->RxRingLo);
+#elif (BITS_PER_LONG == 64)
+	writel(baddr >> 32, ®s->RxRingHi);
+	writel(baddr & 0xffffffff, ®s->RxRingLo);
+#else
+	writel(0, ®s->RxRingHi);
+	writel(baddr, ®s->RxRingLo);
+#endif
+	mb();
+}
+
+
+static inline void set_infoaddr(struct rr_regs *regs, volatile void *addr)
+{
+	unsigned long baddr = virt_to_bus((void *)addr);
+#if (BITS_PER_LONG == 64) && defined(__LITTLE_ENDIAN)
+	writel(baddr & 0xffffffff, ®s->InfoPtrHi);
+	writel(baddr >> 32, ®s->InfoPtrLo);
+#elif (BITS_PER_LONG == 64)
+	writel(baddr >> 32, ®s->InfoPtrHi);
+	writel(baddr & 0xffffffff, ®s->InfoPtrLo);
+#else
+	writel(0, ®s->InfoPtrHi);
+	writel(baddr, ®s->InfoPtrLo);
+#endif
+	mb();
+}
+
+
X /*
X  * TX ring
X  */
@@ -498,12 +554,7 @@
X #define TX_RING_SIZE	(TX_RING_ENTRIES * sizeof(struct tx_desc))
X 
X struct tx_desc{
-#if (BITS_PER_LONG == 64)
-	u64	addr;
-#else
-        u32	zero;
-	u32	addr;
-#endif
+	rraddr	addr;
X 	u32	res;
X #ifdef __LITTLE_ENDIAN
X 	u16	size;
@@ -525,12 +576,7 @@
X #define RX_RING_SIZE	(RX_RING_ENTRIES * sizeof(struct rx_desc))
X 
X struct rx_desc{
-#if (BITS_PER_LONG == 64)
-	u64	addr;
-#else
-        u32	zero;
-	u32	addr;
-#endif
+	rraddr	addr;
X 	u32	res;
X #ifdef __LITTLE_ENDIAN
X 	u16	size;
@@ -714,12 +760,7 @@
X  * This struct is shared with the NIC firmware.
X  */
X struct ring_ctrl {
-#if (BITS_PER_LONG == 64)
-	u64	rngptr;
-#else
-	u32	zero;
-	u32	rngptr;
-#endif
+	rraddr	rngptr;
X #ifdef __LITTLE_ENDIAN
X 	u16	entries;
X 	u8	pad;
@@ -759,19 +800,19 @@
X 	struct rx_desc		rx_ring[RX_RING_ENTRIES];
X 	struct tx_desc		tx_ring[TX_RING_ENTRIES];
X 	struct event		evt_ring[EVT_RING_ENTRIES];
-	struct sk_buff		*tx_skbuff[TX_RING_ENTRIES];
X 	struct sk_buff		*rx_skbuff[RX_RING_ENTRIES];
+	struct sk_buff		*tx_skbuff[TX_RING_ENTRIES];
X 	struct rr_regs		*regs;		/* Register base */
X 	struct ring_ctrl	*rx_ctrl;	/* Receive ring control */
X 	struct rr_info		*info;		/* Shared info page */
+	struct device		*next;
X 	spinlock_t		lock;
X 	struct timer_list	timer;
X 	u32			cur_rx, cur_cmd, cur_evt;
X 	u32			dirty_rx, dirty_tx;
X 	u32			tx_full;
+	u32			fw_rev;
X 	short			fw_running;
-	u8			pci_bus;	/* PCI bus number */
-	u8			pci_dev_fun;	/* PCI device numbers */
X 	char			name[24];	/* The assigned name */
X 	struct net_device_stats stats;
X };
@@ -789,5 +830,11 @@
X static int rr_close(struct device *dev);
X static struct net_device_stats *rr_get_stats(struct device *dev);
X static int rr_ioctl(struct device *dev, struct ifreq *rq, int cmd);
+static unsigned int rr_read_eeprom(struct rr_private *rrpriv,
+				   unsigned long offset,
+				   unsigned char *buf,
+				   unsigned long length);
+static u32 rr_read_eeprom_word(struct rr_private *rrpriv, void * offset);
+static int rr_load_firmware(struct device *dev);
X 
X #endif /* _RRUNNER_H_ */
diff -u --recursive --new-file v2.2.6/linux/drivers/net/z85230.c linux/drivers/net/z85230.c
--- v2.2.6/linux/drivers/net/z85230.c	Fri Apr 16 14:47:30 1999
+++ linux/drivers/net/z85230.c	Sat Apr 24 17:51:48 1999
@@ -48,6 +48,7 @@
X #include <asm/spinlock.h>
X 
X #include "z85230.h"
+#include "syncppp.h"
X 
X 
X static spinlock_t z8530_buffer_lock = SPIN_LOCK_UNLOCKED;
diff -u --recursive --new-file v2.2.6/linux/drivers/pci/oldproc.c linux/drivers/pci/oldproc.c
--- v2.2.6/linux/drivers/pci/oldproc.c	Fri Apr 16 14:47:30 1999
+++ linux/drivers/pci/oldproc.c	Wed Apr 21 09:28:49 1999
@@ -445,6 +445,7 @@
X 	DEVICE( 3DFX,		3DFX_VOODOO2,	"Voodoo2"),
X 	DEVICE( 3DFX,           3DFX_BANSHEE,   "Banshee"),
X 	DEVICE( SIGMADES,	SIGMADES_6425,	"REALmagic64/GX"),
+	DEVICE( AVM,		AVM_A1,		"A1 (Fritz)"),
X 	DEVICE( STALLION,	STALLION_ECHPCI832,"EasyConnection 8/32"),
X 	DEVICE( STALLION,	STALLION_ECHPCI864,"EasyConnection 8/64"),
X 	DEVICE( STALLION,	STALLION_EIOPCI,"EasyIO"),
@@ -784,6 +785,7 @@
X 	      case PCI_VENDOR_ID_O2:		return "O2 Micro";
X 	      case PCI_VENDOR_ID_3DFX:		return "3Dfx";
X 	      case PCI_VENDOR_ID_SIGMADES:	return "Sigma Designs";
+	      case PCI_VENDOR_ID_AVM:		return "AVM";
X 	      case PCI_VENDOR_ID_CCUBE:		return "C-Cube";
X 	      case PCI_VENDOR_ID_DIPIX:		return "Dipix";
X 	      case PCI_VENDOR_ID_STALLION:	return "Stallion Technologies";
diff -u --recursive --new-file v2.2.6/linux/drivers/sbus/audio/audio.c linux/drivers/sbus/audio/audio.c
--- v2.2.6/linux/drivers/sbus/audio/audio.c	Tue Mar 23 14:35:48 1999
+++ linux/drivers/sbus/audio/audio.c	Thu Apr 22 19:24:51 1999
@@ -7,6 +7,7 @@
X  * 
X  * Mixer code adapted from code contributed by and
X  * Copyright (C) 1998 Michael Mraka (mic...@fi.muni.cz)
+ * and with fixes from Michael Shuey (sh...@ecn.purdue.edu)
X  * The mixer code cheats; Sparc hardware doesn't generally allow independent
X  * line control, and this fakes it badly.
X  *
@@ -628,13 +629,12 @@
X #define MONO_DEVICES (SOUND_MASK_SPEAKER | SOUND_MASK_MIC)
X 
X static int sparcaudio_mixer_ioctl(struct inode * inode, struct file * file,
-			    unsigned int cmd, unsigned long arg)
+			    unsigned int cmd, unsigned int *arg)
X {
X   struct sparcaudio_driver *drv = drivers[(MINOR(inode->i_rdev) >>
X 					   SPARCAUDIO_DEVICE_SHIFT)];
-  unsigned long i = 0, j = 0, k = 0;
-
-  k = arg;
+  unsigned long i = 0, j = 0;
+  unsigned int k;
X 
X   if(cmd == SOUND_MIXER_INFO) {
X           audio_device_t tmp;
@@ -663,6 +663,9 @@
X   case SOUND_MIXER_WRITE_MIC:
X   case SOUND_MIXER_WRITE_CD:
X   case SOUND_MIXER_WRITE_LINE:
+  case SOUND_MIXER_WRITE_IMIX:
+    if(get_user(k, arg))
+      return -EFAULT;
X     tprintk(("setting input volume (0x%x)", k));
X     if (drv->ops->get_input_channels)
X       j = drv->ops->get_input_channels(drv);
@@ -692,6 +695,8 @@
X   case SOUND_MIXER_WRITE_PCM:
X   case SOUND_MIXER_WRITE_VOLUME:
X   case SOUND_MIXER_WRITE_SPEAKER:
+    if(get_user(k, arg))
+	return -EFAULT;
X     tprintk(("setting output volume (0x%x)", k));
X     if (drv->ops->get_output_channels)
X       j = drv->ops->get_output_channels(drv);
@@ -731,10 +736,13 @@
X   case SOUND_MIXER_WRITE_RECSRC: 
X     if (!drv->ops->set_input_port)
X       return -EINVAL;
-    if (arg & SOUND_MASK_IMIX) j |= AUDIO_ANALOG_LOOPBACK;
-    if (arg & SOUND_MASK_CD) j |= AUDIO_CD;
-    if (arg & SOUND_MASK_LINE) j |= AUDIO_LINE_IN;
-    if (arg & SOUND_MASK_MIC) j |= AUDIO_MICROPHONE;
+    if(get_user(k, arg))
+      return -EFAULT;
+    /* only one should ever be selected */
+    if (k & SOUND_MASK_IMIX) j = AUDIO_ANALOG_LOOPBACK;
+    if (k & SOUND_MASK_CD) j = AUDIO_CD;
+    if (k & SOUND_MASK_LINE) j = AUDIO_LINE_IN;
+    if (k & SOUND_MASK_MIC) j = AUDIO_MICROPHONE;
X     tprintk(("setting inport to %d\n", j));
X     i = drv->ops->set_input_port(drv, j);
X     
@@ -790,11 +798,12 @@
X 	j = drv->ops->get_output_balance(drv);
X       i = b_to_s(i,j);
X     }
-    return COPY_OUT((int *)arg, i);
+    return COPY_OUT(arg, i);
X   case SOUND_MIXER_READ_RECLEV:
X   case SOUND_MIXER_READ_MIC:
X   case SOUND_MIXER_READ_CD:
X   case SOUND_MIXER_READ_LINE:
+  case SOUND_MIXER_READ_IMIX:
X     if (drv->ops->get_input_channels)
X       j = drv->ops->get_input_channels(drv);
X     if (j == 1) {
@@ -808,7 +817,7 @@
X 	j = drv->ops->get_input_balance(drv);
X       i = b_to_s(i,j);
X     }
-    return COPY_OUT((int *)arg, i);
+    return COPY_OUT(arg, i);
X   default:
X     return -EINVAL;
X   }
@@ -862,7 +871,7 @@
X 
X 	switch (minor & 0xf) {
X 	case SPARCAUDIO_MIXER_MINOR:
-	  return sparcaudio_mixer_ioctl(inode, file, cmd, arg);
+	  return sparcaudio_mixer_ioctl(inode, file, cmd, (unsigned int *)arg);
X 	case SPARCAUDIO_DSP16_MINOR:
X         case SPARCAUDIO_DSP_MINOR:
X 	case SPARCAUDIO_AUDIO_MINOR:
diff -u --recursive --new-file v2.2.6/linux/drivers/sbus/audio/cs4231.c linux/drivers/sbus/audio/cs4231.c
--- v2.2.6/linux/drivers/sbus/audio/cs4231.c	Tue Mar 23 14:35:48 1999
+++ linux/drivers/sbus/audio/cs4231.c	Wed Apr 28 08:47:39 1999
@@ -73,6 +73,7 @@
X static int cs4231_recintr(struct sparcaudio_driver *drv);
X static int cs4231_output_muted(struct sparcaudio_driver *drv, int value);
X static void cs4231_pollinput(struct sparcaudio_driver *drv);
+static void eb4231_pollinput(struct sparcaudio_driver *drv);
X static int cs4231_length_to_samplecount(struct audio_prinfo *thisdir, 
X                                         unsigned int length);
X static void cs4231_getsamplecount(struct sparcaudio_driver *drv, 
@@ -92,8 +93,8 @@
X   tprintk(("enabling interrupts\n"));
X   save_flags(flags);
X   cli();
-  cs4231_chip->regs->iar = 0xa;
-  cs4231_chip->regs->idr = INTR_ON;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0xa);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), INTR_ON);
X   restore_flags(flags);
X 
X   cs4231_chip->status |= CS_STATUS_INTS_ON;
@@ -111,8 +112,8 @@
X   tprintk(("disabling interrupts\n"));
X   save_flags(flags);
X   cli();
-  cs4231_chip->regs->iar = 0xa;
-  cs4231_chip->regs->idr = INTR_OFF;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0xa);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), INTR_OFF);
X   restore_flags(flags);
X 
X   cs4231_chip->status &= ~CS_STATUS_INTS_ON;
@@ -127,8 +128,9 @@
X   save_flags(flags);
X   cli();
X   
-  cs4231_chip->regs->iar = 0x9;
-  cs4231_chip->regs->idr |= PEN_ENABLE;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x9);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) | PEN_ENABLE));
X   restore_flags(flags);
X }
X 
@@ -140,8 +142,9 @@
X   tprintk(("disabling play\n"));
X   save_flags(flags);
X   cli();
-  cs4231_chip->regs->iar = 0x9;
-  cs4231_chip->regs->idr &= PEN_DISABLE;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x9);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) & PEN_DISABLE));
X   restore_flags(flags);
X }
X 
@@ -153,8 +156,9 @@
X   tprintk(("enabling rec\n"));
X   save_flags(flags);
X   cli();
-  cs4231_chip->regs->iar = 0x9;
-  cs4231_chip->regs->idr |= CEN_ENABLE;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x9);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) | CEN_ENABLE));
X   restore_flags(flags);
X }
X 
@@ -166,64 +170,68 @@
X   tprintk(("disabling rec\n"));
X   save_flags(flags);
X   cli();
-  cs4231_chip->regs->iar = 0x9;
-  cs4231_chip->regs->idr &= CEN_DISABLE;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x9);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) & CEN_DISABLE));
X   restore_flags(flags);
X }
X 
+static struct cs4231_rates {
+  int speed, bits;
+} cs4231_rate_table[] = {
+  { 5512, CS4231_DFR_5512 },
+  { 6615, CS4231_DFR_6615 },
+  { 8000, CS4231_DFR_8000 },
+  { 9600, CS4231_DFR_9600 },
+  { 11025, CS4231_DFR_11025 },
+  { 16000, CS4231_DFR_16000 },
+  { 18900, CS4231_DFR_18900 },
+  { 22050, CS4231_DFR_22050 },
+  { 27429, CS4231_DFR_27429 },
+  { 32000, CS4231_DFR_32000 },
+  { 33075, CS4231_DFR_33075 },
+  { 37800, CS4231_DFR_37800 },
+  { 44100, CS4231_DFR_44100 },
+  { 48000, CS4231_DFR_48000 }
+};
+
+#define NUM_RATES	(sizeof(cs4231_rate_table) / sizeof(struct cs4231_rates))
+
X static int 
-cs4231_rate_to_bits(struct sparcaudio_driver *drv, int value)
+cs4231_rate_to_bits(struct sparcaudio_driver *drv, int *value)
X {
-  int set_bits;
+  struct cs4231_rates *p = &cs4231_rate_table[0];
+  int i, wanted = *value;
X 
-  switch (value) {
-  case 5512:
-    set_bits = CS4231_DFR_5512;
-    break;
-  case 6615:
-    set_bits = CS4231_DFR_6615;
-    break;
-  case 8000:
-    set_bits = CS4231_DFR_8000;
-    break;
-  case 9600:
-    set_bits = CS4231_DFR_9600;
-    break;
-  case 11025:
-    set_bits = CS4231_DFR_11025;
-    break;
-  case 16000:
-    set_bits = CS4231_DFR_16000;
-    break;
-  case 18900:
-    set_bits = CS4231_DFR_18900;
-    break;
-  case 22050:
-    set_bits = CS4231_DFR_22050;
-    break;
-  case 27429:
-    set_bits = CS4231_DFR_27429;
-    break;
-  case 32000:
-    set_bits = CS4231_DFR_32000;
-    break;
-  case 33075:
-    set_bits = CS4231_DFR_33075;
-    break;
-  case 37800:
-    set_bits = CS4231_DFR_37800;
-    break;
-  case 44100:
-    set_bits = CS4231_DFR_44100;
-    break;
-  case 48000:
-    set_bits = CS4231_DFR_48000;
-    break;
-  default:
-    set_bits = -(EINVAL);
-    break;
+  /* We try to be nice and approximate what the user asks for. */
+  if(wanted < 5512)
+    wanted = 5512;
+  if(wanted > 48000)
+    wanted = 48000;
+
+  for(i = 0; i < NUM_RATES; i++, p++) {
+    /* Exact match? */
+    if(wanted == p->speed)
+      break;
+
+    /* If we're inbetween two entries, and neither is exact,
+     * pick the closest one.
+     */
+    if(wanted == p[1].speed)
+      continue;
+    if(wanted > p->speed &&
+       wanted < p[1].speed) {
+      int diff1, diff2;
+
+      diff1 = wanted - p->speed;
+      diff2 = p[1].speed - wanted;
+      if(diff2 < diff1)
+        p++;
+      break;
+    }
X   }
-  return set_bits;
+  *value = p->speed;
+  return p->bits;
X }
X 
X static int 
@@ -268,9 +276,14 @@
X   if (value != 0) {
X     set_bits = cs4231_encoding_to_bits(drv, value);
X     if (set_bits >= 0) {
-        cs4231_chip->regs->iar = IAR_AUTOCAL_BEGIN | 0x8;
-        tmp_bits = cs4231_chip->regs->idr;
-        cs4231_chip->regs->idr = CHANGE_ENCODING(tmp_bits, set_bits);
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), IAR_AUTOCAL_BEGIN | 0x8);
+        tmp_bits = CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                      CHANGE_ENCODING(tmp_bits, set_bits));
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
X     
X         CHIP_READY
X 
@@ -298,9 +311,14 @@
X   if (value != 0) {
X     set_bits = cs4231_encoding_to_bits(drv, value);
X     if (set_bits >= 0) {
-        cs4231_chip->regs->iar = IAR_AUTOCAL_BEGIN | 0x1c;
-        tmp_bits = cs4231_chip->regs->idr;
-        cs4231_chip->regs->idr = CHANGE_ENCODING(tmp_bits, set_bits);
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), IAR_AUTOCAL_BEGIN | 0x1c);
+        tmp_bits = CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                      CHANGE_ENCODING(tmp_bits, set_bits));
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
X 
X         CHIP_READY
X 
@@ -326,15 +344,22 @@
X 
X   tprintk(("output rate %d\n", value));
X   if (value != 0) {
-    set_bits = cs4231_rate_to_bits(drv, value);
+    set_bits = cs4231_rate_to_bits(drv, &value);
X     if (set_bits >= 0) {
-        cs4231_chip->regs->iar = IAR_AUTOCAL_BEGIN | 0x8;
-        tmp_bits = cs4231_chip->regs->idr;
-        cs4231_chip->regs->idr = CHANGE_DFR(tmp_bits, set_bits);
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), IAR_AUTOCAL_BEGIN | 0x8);
+        tmp_bits = CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                      CHANGE_DFR(tmp_bits, set_bits));
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
X 
X         CHIP_READY
X 
X         cs4231_chip->perchip_info.play.sample_rate = value;
+        tprintk(("tmp_bits[%02x] set_bits[%02x] CHANGE_DFR[%02x]\n",
+                 tmp_bits, set_bits, CHANGE_DFR(tmp_bits, set_bits)));
X         return 0;
X     }
X   }
@@ -356,11 +381,16 @@
X 
X   tprintk(("input rate %d\n", value));
X   if (value != 0) {
-    set_bits = cs4231_rate_to_bits(drv, value);
+    set_bits = cs4231_rate_to_bits(drv, &value);
X     if (set_bits >= 0) {
-        cs4231_chip->regs->iar = IAR_AUTOCAL_BEGIN | 0x1c;
-        tmp_bits = cs4231_chip->regs->idr;
-        cs4231_chip->regs->idr = CHANGE_DFR(tmp_bits, set_bits);
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), IAR_AUTOCAL_BEGIN | 0x1c);
+        tmp_bits = CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                      CHANGE_DFR(tmp_bits, set_bits));
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+        CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
X       
X         CHIP_READY
X 
@@ -390,10 +420,10 @@
X   tmp_bits = cs4231_chip->regs->idr;
X   switch (value) {
X   case 1:
-      cs4231_chip->regs->idr = CS4231_MONO_ON(tmp_bits);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), CS4231_MONO_ON(tmp_bits));
X       break;
X   case 2:
-      cs4231_chip->regs->idr = CS4231_STEREO_ON(tmp_bits);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), CS4231_STEREO_ON(tmp_bits));
X       break;
X   default:
X       dprintk(("input chan failed\n"));
@@ -420,14 +450,14 @@
X   int tmp_bits;
X 
X   tprintk(("output channels %d\n", value));
-  cs4231_chip->regs->iar = IAR_AUTOCAL_BEGIN | 0x8;
-  tmp_bits = cs4231_chip->regs->idr;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), IAR_AUTOCAL_BEGIN | 0x8);
+  tmp_bits = CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
X   switch (value) {
X   case 1:
-      cs4231_chip->regs->idr = CS4231_MONO_ON(tmp_bits);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), CS4231_MONO_ON(tmp_bits));
X       break;
X   case 2:
-      cs4231_chip->regs->idr = CS4231_STEREO_ON(tmp_bits);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), CS4231_STEREO_ON(tmp_bits));
X       break;
X   default:
X       dprintk(("output chan failed\n"));
@@ -483,14 +513,16 @@
X   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
X   unsigned int x = 0;
X 
-  cs4231_chip->regs->iar = IAR_AUTOCAL_END;
-  while (cs4231_chip->regs->idr == IAR_NOT_READY && x <= CS_TIMEOUT) {
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), IAR_AUTOCAL_END);
+  while (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) == IAR_NOT_READY &&
+         x <= CS_TIMEOUT) {
X     x++;
X   }
X 
X   x = 0;
-  cs4231_chip->regs->iar = 0x0b;
-  while (cs4231_chip->regs->idr == AUTOCAL_IN_PROGRESS && x <= CS_TIMEOUT) {
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x0b);
+  while (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) == AUTOCAL_IN_PROGRESS &&
+         x <= CS_TIMEOUT) {
X     x++;
X   }
X }
@@ -501,16 +533,20 @@
X   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
X   tprintk(("in cs4231_output_muted: %d\n", value));
X   if (!value) {
-      cs4231_chip->regs->iar = 0x7;
-      cs4231_chip->regs->idr &= OUTCR_UNMUTE;
-      cs4231_chip->regs->iar = 0x6;
-      cs4231_chip->regs->idr &= OUTCR_UNMUTE;
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x7);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                    (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) & OUTCR_UNMUTE));
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x6);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                    (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) & OUTCR_UNMUTE));
X       cs4231_chip->perchip_info.output_muted = 0;
X   } else {
-      cs4231_chip->regs->iar = 0x7;
-      cs4231_chip->regs->idr |= OUTCR_MUTE;
-      cs4231_chip->regs->iar = 0x6;
-      cs4231_chip->regs->idr |= OUTCR_MUTE;
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x7);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                    (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) | OUTCR_MUTE));
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x6);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                    (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) | OUTCR_MUTE));
X       cs4231_chip->perchip_info.output_muted = 1;
X   }
X   return 0;
@@ -555,27 +591,33 @@
X   /* Aaaaaah! It's all coming so fast! Turn it all off, then selectively
X    * enable things.
X    */
-  cs4231_chip->regs->iar = 0x1a;
-  cs4231_chip->regs->idr |= MONO_IOCR_MUTE;
-  cs4231_chip->regs->iar = 0x0a;
-  cs4231_chip->regs->idr |= PINCR_LINE_MUTE;
-  cs4231_chip->regs->idr |= PINCR_HDPH_MUTE;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x1a);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) | MONO_IOCR_MUTE));
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x0a);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) | PINCR_LINE_MUTE));
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) | PINCR_HDPH_MUTE));
X 
X   if (value & AUDIO_SPEAKER) {
-      cs4231_chip->regs->iar = 0x1a;
-      cs4231_chip->regs->idr &= ~MONO_IOCR_MUTE;
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x1a);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                    (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) & ~MONO_IOCR_MUTE));
X       retval |= AUDIO_SPEAKER;
X   }
X 
X   if (value & AUDIO_HEADPHONE) {
-      cs4231_chip->regs->iar = 0x0a;
-      cs4231_chip->regs->idr &= ~PINCR_HDPH_MUTE;
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x0a);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                    (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) & ~PINCR_HDPH_MUTE));
X       retval |= AUDIO_HEADPHONE;
X   }
X 
X   if (value & AUDIO_LINE_OUT) {
-      cs4231_chip->regs->iar = 0x0a;
-      cs4231_chip->regs->idr &= ~PINCR_LINE_MUTE;
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x0a);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                    (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) & ~PINCR_LINE_MUTE));
X       retval |= AUDIO_LINE_OUT;
X   }
X   
@@ -605,32 +647,40 @@
X 
X   /* Ultra systems do not support AUDIO_INTERNAL_CD_IN */
X   /* This apparently applies only to APC ultras, not ebus ultras */
-  if (!cs4231_chip->status & CS_STATUS_IS_ULTRA) {
+  if (!(cs4231_chip->status & CS_STATUS_IS_ULTRA)) {
X     if (value & AUDIO_INTERNAL_CD_IN) {
-        cs4231_chip->regs->iar = 0x1;
-        cs4231_chip->regs->idr = CDROM_ENABLE(cs4231_chip->regs->idr);
-        cs4231_chip->regs->iar = 0x0;
-        cs4231_chip->regs->idr = CDROM_ENABLE(cs4231_chip->regs->idr);
+        CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x1);
+        CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                      CDROM_ENABLE(CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr))));
+        CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x0);
+        CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                      CDROM_ENABLE(CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr))));
X         retval = AUDIO_INTERNAL_CD_IN;
X     }
X   }
X   if ((value & AUDIO_LINE_IN)) {
-      cs4231_chip->regs->iar = 0x1;
-      cs4231_chip->regs->idr = LINE_ENABLE(cs4231_chip->regs->idr);
-      cs4231_chip->regs->iar = 0x0;
-      cs4231_chip->regs->idr = LINE_ENABLE(cs4231_chip->regs->idr);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x1);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                    LINE_ENABLE(CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr))));
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x0);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                    LINE_ENABLE(CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr))));
X       retval = AUDIO_LINE_IN;
X   } else if (value & AUDIO_MICROPHONE) {
-      cs4231_chip->regs->iar = 0x1;
-      cs4231_chip->regs->idr = MIC_ENABLE(cs4231_chip->regs->idr);
-      cs4231_chip->regs->iar = 0x0;
-      cs4231_chip->regs->idr = MIC_ENABLE(cs4231_chip->regs->idr);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x1);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                    MIC_ENABLE(CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr))));
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x0);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                    MIC_ENABLE(CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr))));
X       retval = AUDIO_MICROPHONE;
X   } else if (value & AUDIO_ANALOG_LOOPBACK) {
-      cs4231_chip->regs->iar = 0x1;
-      cs4231_chip->regs->idr = OUTPUTLOOP_ENABLE(cs4231_chip->regs->idr);
-      cs4231_chip->regs->iar = 0x0;
-      cs4231_chip->regs->idr = OUTPUTLOOP_ENABLE(cs4231_chip->regs->idr);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x1);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                    OUTPUTLOOP_ENABLE(CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr))));
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x0);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                    OUTPUTLOOP_ENABLE(CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr))));
X       retval = AUDIO_ANALOG_LOOPBACK;
X   }
X 
@@ -659,18 +709,19 @@
X   a = CS4231_MON_MAX_ATEN - (value * (CS4231_MON_MAX_ATEN + 1) / 
X                              (AUDIO_MAX_GAIN + 1));
X 
-  cs4231_chip->regs->iar = 0x0d;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x0d);
X   if (a >= CS4231_MON_MAX_ATEN) 
-      cs4231_chip->regs->idr = LOOPB_OFF;
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), LOOPB_OFF);
X   else 
-      cs4231_chip->regs->idr = ((a << 2) | LOOPB_ON);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), ((a << 2) | LOOPB_ON));
X 
X   if (value == AUDIO_MAX_GAIN) 
-    cs4231_chip->perchip_info.monitor_gain = AUDIO_MAX_GAIN;
+    CS4231_WRITE8(cs4231_chip, &(cs4231_chip->perchip_info.monitor_gain), AUDIO_MAX_GAIN);
X   else 
-    cs4231_chip->perchip_info.monitor_gain = ((CS4231_MAX_DEV_ATEN - a) * 
-                                              (AUDIO_MAX_GAIN + 1) / 
-                                              (CS4231_MAX_DEV_ATEN + 1));
+    CS4231_WRITE8(cs4231_chip, &(cs4231_chip->perchip_info.monitor_gain),
+                  ((CS4231_MAX_DEV_ATEN - a) * 
+                   (AUDIO_MAX_GAIN + 1) / 
+                   (CS4231_MAX_DEV_ATEN + 1)));
X 
X   return 0;
X }
@@ -852,12 +903,12 @@
X   l_adj = l * (CS4231_MAX_GAIN + 1) / (AUDIO_MAX_GAIN + 1);
X   r_adj = r * (CS4231_MAX_GAIN + 1) / (AUDIO_MAX_GAIN + 1);
X   
-  cs4231_chip->regs->iar = 0x0;
-  old_gain = cs4231_chip->regs->idr;
-  cs4231_chip->regs->idr = RECGAIN_SET(old_gain, l_adj);
-  cs4231_chip->regs->iar = 0x1;
-  old_gain = cs4231_chip->regs->idr;
-  cs4231_chip->regs->idr = RECGAIN_SET(old_gain, r_adj);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x0);
+  old_gain = CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), RECGAIN_SET(old_gain, l_adj));
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x1);
+  old_gain = CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), RECGAIN_SET(old_gain, r_adj));
X   
X   if (l == value) {
X     (l == 0) ? (tmp = 0) : (tmp = ((l_adj + 1) * AUDIO_MAX_GAIN) / 
@@ -894,12 +945,12 @@
X                                               (r * (CS4231_MAX_ATEN + 1) /
X                                                (AUDIO_MAX_GAIN + 1)));
X   
-  cs4231_chip->regs->iar = 0x6;
-  old_gain = cs4231_chip->regs->idr;
-  cs4231_chip->regs->idr = GAIN_SET(old_gain, l_adj);
-  cs4231_chip->regs->iar = 0x7;
-  old_gain = cs4231_chip->regs->idr;
-  cs4231_chip->regs->idr = GAIN_SET(old_gain, r_adj);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x6);
+  old_gain = CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), GAIN_SET(old_gain, l_adj));
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x7);
+  old_gain = CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), GAIN_SET(old_gain, r_adj));
X   
X   if ((value == 0) || (value == AUDIO_MAX_GAIN)) {
X     tmp = value;
@@ -920,13 +971,16 @@
X static void cs4231_chip_reset(struct sparcaudio_driver *drv)
X {
X   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
+  unsigned char vers;
X 
X   tprintk(("in cs4231_chip_reset\n"));
X 
X   if (cs4231_chip->status & CS_STATUS_IS_EBUS) {
X #ifdef EB4231_SUPPORT
-    writel(EBUS_DCSR_RESET, &cs4231_chip->eb2p->dcsr);
-    writel(EBUS_DCSR_RESET, &cs4231_chip->eb2c->dcsr);
+    writel(EBUS_DCSR_RESET, &(cs4231_chip->eb2p->dcsr));
+    writel(EBUS_DCSR_RESET, &(cs4231_chip->eb2c->dcsr));
+    writel(EBUS_DCSR_BURST_SZ_16, &(cs4231_chip->eb2p->dcsr));
+    writel(EBUS_DCSR_BURST_SZ_16, &(cs4231_chip->eb2c->dcsr));
X #endif
X   } else {
X     cs4231_chip->regs->dmacsr = APC_CHIP_RESET;
@@ -938,12 +992,13 @@
X     cs4231_chip->regs->dmacsr &= ~(APC_CDC_RESET);
X   }
X 
-  cs4231_chip->regs->iar |= IAR_AUTOCAL_BEGIN;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar),
+                (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->iar)) | IAR_AUTOCAL_BEGIN));
X   
X   CHIP_READY
X     
-  cs4231_chip->regs->iar = IAR_AUTOCAL_BEGIN | 0x0c;
-  cs4231_chip->regs->idr = MISC_IR_MODE2;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), IAR_AUTOCAL_BEGIN | 0x0c);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), MISC_IR_MODE2);
X 
X   /* This is the equivalent of DEFAULT_DATA_FMAT */
X   cs4231_set_input_encoding(drv, AUDIO_ENCODING_ULAW);
@@ -956,25 +1011,27 @@
X   cs4231_set_output_channels(drv, CS4231_CHANNELS);
X   cs4231_set_output_precision(drv, CS4231_PRECISION);
X 
-  cs4231_chip->regs->iar = 0x19;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x19);
+
X   /* see what we can turn on */
-  if (cs4231_chip->regs->idr & CS4231A) {
+  vers = CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr));
+  if (vers & CS4231A) {
X     tprintk(("This is a CS4231A\n"));
X     cs4231_chip->status |= CS_STATUS_REV_A;
X   } else
X     cs4231_chip->status &= ~CS_STATUS_REV_A;
X   
-  cs4231_chip->regs->iar = IAR_AUTOCAL_BEGIN | 0x10;
-  cs4231_chip->regs->idr = OLB_ENABLE;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), IAR_AUTOCAL_BEGIN | 0x10);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), OLB_ENABLE);
X   
-  cs4231_chip->regs->iar = IAR_AUTOCAL_BEGIN | 0x11;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), IAR_AUTOCAL_BEGIN | 0x11);
X   if (cs4231_chip->status & CS_STATUS_REV_A)
-      cs4231_chip->regs->idr = (HPF_ON | XTALE_ON);
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), (HPF_ON | XTALE_ON));
X   else
-      cs4231_chip->regs->idr = HPF_ON;
+      CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), HPF_ON);
X   
-  cs4231_chip->regs->iar = IAR_AUTOCAL_BEGIN | 0x1a;
-  cs4231_chip->regs->idr = 0x00;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), IAR_AUTOCAL_BEGIN | 0x1a);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), 0x00);
X   
X   /* Now set things up for defaults */
X   cs4231_set_input_balance(drv, AUDIO_MID_BALANCE);
@@ -988,13 +1045,14 @@
X 
X   cs4231_set_monitor_volume(drv, LOOPB_OFF);
X   
-  cs4231_chip->regs->iar = IAR_AUTOCAL_END;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), IAR_AUTOCAL_END);
X   
X   cs4231_ready(drv);
X   
-  cs4231_chip->regs->iar = IAR_AUTOCAL_BEGIN | 0x09;
-  cs4231_chip->regs->idr &= ACAL_DISABLE;
-  cs4231_chip->regs->iar = IAR_AUTOCAL_END;
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), IAR_AUTOCAL_BEGIN | 0x09);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr),
+                (CS4231_READ8(cs4231_chip, &(cs4231_chip->regs->idr)) & ACAL_DISABLE));
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), IAR_AUTOCAL_END);
X   
X   cs4231_ready(drv);
X 
@@ -1036,24 +1094,18 @@
X {
X   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
X   struct audio_prinfo *thisdir;
-  unsigned int count, nextcount, curcount;
+  unsigned int count, curcount, nextcount, dbcr;
X 
-  if (direction == 1) /* record */ 
-    {
-      thisdir = &cs4231_chip->perchip_info.record;
-      curcount = 
-	cs4231_length_to_samplecount(thisdir, readl(&cs4231_chip->eb2c->dbcr));
-      nextcount = 
-	cs4231_length_to_samplecount(thisdir, 0/*cs4231_chip->regs->dmacnc*/);
-    }
-  else /* play */
-    {
-      thisdir = &cs4231_chip->perchip_info.play;
-      curcount = 
-	cs4231_length_to_samplecount(thisdir, readl(&cs4231_chip->eb2p->dbcr));
-      nextcount = 
-	cs4231_length_to_samplecount(thisdir, 0/*cs4231_chip->regs->dmapnc*/);
-    }
+  if(direction == 1) {
+    thisdir = &cs4231_chip->perchip_info.record;
+    dbcr = readl(&(cs4231_chip->eb2c->dbcr));
+    nextcount = cs4231_chip->input_next_dma_size;
+  } else {
+    thisdir = &cs4231_chip->perchip_info.play;
+    dbcr = readl(&(cs4231_chip->eb2p->dbcr));
+    nextcount = cs4231_chip->output_next_dma_size;
+  }
+  curcount = cs4231_length_to_samplecount(thisdir, dbcr);
X   count = thisdir->samples;
X   length = cs4231_length_to_samplecount(thisdir, length);
X   /* normalize for where we are. */
@@ -1131,18 +1183,16 @@
X     /* stop capture here or midlevel? */
X     cs4231_chip->perchip_info.record.open = 0;
X     if (cs4231_chip->input_dma_handle) {
-#if 0
-      mmu_release_scsi_one(cs4231_chip->input_dma_handle,
-                           cs4231_chip->input_dma_size, drv->dev->my_bus);
-#endif
+      if(!(cs4231_chip->status & CS_STATUS_IS_EBUS))
+              mmu_release_scsi_one(cs4231_chip->input_dma_handle,
+                                   cs4231_chip->input_dma_size, drv->dev->my_bus);
X       cs4231_chip->input_dma_handle = 0;
X       cs4231_chip->input_dma_size = 0;
X     }
X     if (cs4231_chip->input_next_dma_handle) {
-#if 0
-      mmu_release_scsi_one(cs4231_chip->input_next_dma_handle,
-                           cs4231_chip->input_next_dma_size, drv->dev->my_bus);
-#endif
+      if(!(cs4231_chip->status & CS_STATUS_IS_EBUS))
+              mmu_release_scsi_one(cs4231_chip->input_next_dma_handle,
+                                   cs4231_chip->input_next_dma_size, drv->dev->my_bus);
X       cs4231_chip->input_next_dma_handle = 0;
X       cs4231_chip->input_next_dma_size = 0;
X     }
@@ -1152,19 +1202,17 @@
X     cs4231_chip->perchip_info.play.active =
X       cs4231_chip->perchip_info.play.open = 0;
X     if (cs4231_chip->output_dma_handle) {
-#if 0
-      mmu_release_scsi_one(cs4231_chip->output_dma_handle,
-                           cs4231_chip->output_dma_size, drv->dev->my_bus);
-#endif
+      if(!(cs4231_chip->status & CS_STATUS_IS_EBUS))
+              mmu_release_scsi_one(cs4231_chip->output_dma_handle,
+                                   cs4231_chip->output_dma_size, drv->dev->my_bus);
X       cs4231_chip->output_dma_handle = 0;
X       cs4231_chip->output_dma_size = 0;
X     }
X     if (cs4231_chip->output_next_dma_handle) {
-#if 0
-      mmu_release_scsi_one(cs4231_chip->output_next_dma_handle,
-                           cs4231_chip->output_next_dma_size, 
-                           drv->dev->my_bus);
-#endif
+      if(!(cs4231_chip->status & CS_STATUS_IS_EBUS))
+              mmu_release_scsi_one(cs4231_chip->output_next_dma_handle,
+                                   cs4231_chip->output_next_dma_size, 
+                                   drv->dev->my_bus);
X       cs4231_chip->output_next_dma_handle = 0;
X       cs4231_chip->output_next_dma_size = 0;
X     }
@@ -1230,11 +1278,7 @@
X {
X   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
X   int status = 0;
-  unsigned int dcsr;
-
-  dcsr = readl(&cs4231_chip->eb2p->dcsr);
X 
-  printk("pintr\ncsr 0x%x acr 0x%x bcr %d\n", readl(&cs4231_chip->eb2p->dcsr), readl(&cs4231_chip->eb2p->dacr), readl(&cs4231_chip->eb2p->dbcr));
X   if (cs4231_chip->playlen == 0 && cs4231_chip->output_size > 0) 
X     cs4231_chip->playlen = cs4231_chip->output_size;
X 
@@ -1244,35 +1288,24 @@
X     cs4231_chip->playing_count--;
X     status++;
X   }
-
-#if 0
-  if (cs4231_chip->output_next_dma_handle) {
+  if(cs4231_chip->output_next_dma_handle) {
X     cs4231_chip->output_dma_handle = cs4231_chip->output_next_dma_handle;
X     cs4231_chip->output_dma_size = cs4231_chip->output_next_dma_size;
-    cs4231_chip->output_next_dma_size = 0;
X     cs4231_chip->output_next_dma_handle = 0;
+    cs4231_chip->output_next_dma_size = 0;
X   }
-#endif
X 
X   if ((cs4231_chip->output_ptr && cs4231_chip->output_size > 0) && 
X       !(cs4231_chip->perchip_info.play.pause)) {
-#if 0
-    if (dcsr & EBUS_DCSR_A_LOADED) {
-      cs4231_chip->output_next_dma_handle = virt_to_bus(cs4231_chip->output_ptr);
-      cs4231_chip->output_next_dma_size = cs4231_chip->output_size;
-    } else {
-#endif
-      cs4231_chip->output_dma_handle = virt_to_bus(cs4231_chip->output_ptr);
-      cs4231_chip->output_dma_size = cs4231_chip->output_size;
-#if 0
-    }
-#endif
-    writel(virt_to_bus(cs4231_chip->output_ptr), &cs4231_chip->eb2p->dacr);
-    writel(cs4231_chip->output_size, &cs4231_chip->eb2p->dbcr);
+    cs4231_chip->output_next_dma_handle = virt_to_bus(cs4231_chip->output_ptr);
+    cs4231_chip->output_next_dma_size = cs4231_chip->output_size;
+
+    writel(cs4231_chip->output_next_dma_size, &(cs4231_chip->eb2p->dbcr));
+    writel(cs4231_chip->output_next_dma_handle, &(cs4231_chip->eb2p->dacr));
X     cs4231_chip->output_size = 0;
X     cs4231_chip->output_ptr = NULL;
X     cs4231_chip->playing_count++;
-    status+=2;
+    status += 2;
X   }
X 
X   sparcaudio_output_done(drv, status);
@@ -1354,14 +1387,11 @@
X 
X   if (cs4231_chip->perchip_info.record.active == 0) {
X     dprintk(("going inactive\n"));
+    eb4231_pollinput(drv);
X     cs4231_disable_rec(drv);    
X   } 
X 
X   if (cs4231_chip->input_dma_handle) {
-#if 0
-    mmu_release_scsi_one(cs4231_chip->input_dma_handle, 
-                         cs4231_chip->input_dma_size, drv->dev->my_bus);
-#endif
X     cs4231_chip->input_dma_handle = 0;
X     cs4231_chip->input_dma_size = 0;
X     cs4231_chip->recording_count--;
@@ -1378,29 +1408,17 @@
X       !(cs4231_chip->perchip_info.record.pause)) {
X     cs4231_recclear(cs4231_chip->perchip_info.record.encoding, 
X                     (char *)cs4231_chip->input_ptr, cs4231_chip->input_size);
-#if 0
-    cs4231_chip->input_next_dma_handle =
-      mmu_get_scsi_one((char *) cs4231_chip->input_ptr, 
-                       cs4231_chip->input_size, drv->dev->my_bus);
-    cs4231_chip->regs->dmacnva = cs4231_chip->input_next_dma_handle;
-    cs4231_chip->input_next_dma_size = cs4231_chip->regs->dmacnc = 
-      cs4231_chip->input_size;
-#else
-    cs4231_chip->input_next_dma_handle = cs4231_chip->eb2c->dacr = virt_to_bus(cs4231_chip->input_ptr);
-    cs4231_chip->input_next_dma_size = cs4231_chip->eb2c->dbcr = cs4231_chip->input_size;
-#endif
+
+    cs4231_chip->input_next_dma_handle = virt_to_bus(cs4231_chip->input_ptr);
+    cs4231_chip->input_next_dma_size = cs4231_chip->input_size;
+
+    writel(cs4231_chip->input_next_dma_size, &(cs4231_chip->eb2c->dbcr));
+    writel(cs4231_chip->input_next_dma_handle, &(cs4231_chip->eb2c->dacr));
+
X     cs4231_chip->input_size = 0;
X     cs4231_chip->input_ptr = NULL;
X     cs4231_chip->recording_count++;
X     status += 2;
-  } else {
-#if 0
-    cs4231_chip->regs->dmacnva = 0;
-    cs4231_chip->regs->dmacnc = 0;
-#else
-    cs4231_chip->eb2c->dacr = 0;
-    cs4231_chip->eb2c->dbcr = 0;
-#endif
X   }
X 
X   sparcaudio_input_done(drv, 1);
@@ -1416,7 +1434,6 @@
X   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
X   unsigned int dcsr;
X 
-  dprintk(("in eb4231 start output act %d pau %d\n", cs4231_chip->perchip_info.play.active, cs4231_chip->perchip_info.play.pause));
X   cs4231_chip->output_ptr = buffer;
X   cs4231_chip->output_size = count;
X 
@@ -1431,17 +1448,19 @@
X 
X   dcsr = readl(&cs4231_chip->eb2p->dcsr);
X   if (!(dcsr & EBUS_DCSR_EN_DMA)) {
-    dprintk(("about to go setup\n"));
+    writel(EBUS_DCSR_RESET, &(cs4231_chip->eb2p->dcsr));
+    writel(EBUS_DCSR_BURST_SZ_16, &(cs4231_chip->eb2p->dcsr));
X 
-    dcsr = EB2_PLAY_SETUP;
-    writel(dcsr, (unsigned long)&cs4231_chip->eb2p->dcsr);
X     eb4231_playintr(drv);
-    dprintk(("enabling\n"));
+
+    writel(EBUS_DCSR_BURST_SZ_16 |
+           (EBUS_DCSR_EN_DMA | EBUS_DCSR_INT_EN | EBUS_DCSR_EN_CNT | EBUS_DCSR_EN_NEXT),
+           &(cs4231_chip->eb2p->dcsr));
+
X     cs4231_enable_play(drv);
X 
X     cs4231_ready(drv);
X   } else {
-    dprintk(("playing next block\n"));
X     eb4231_playintr(drv);
X   }
X }
@@ -1484,21 +1503,28 @@
X static void eb4231_stop_output(struct sparcaudio_driver *drv)
X {
X   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
+  int dcsr;
X 
-  dprintk(("in cs4231_stop_output\n"));
-  dprintk(("csr 0x%x acr 0x%x bcr %d\n", readl(&cs4231_chip->eb2p->dcsr), readl(&cs4231_chip->eb2p->dacr), readl(&cs4231_chip->eb2p->dbcr)));
+  dprintk(("eb4231_stop_output: dcsr 0x%x dacr 0x%x dbcr %d\n",
+           readl(&cs4231_chip->eb2p->dcsr),
+           readl(&cs4231_chip->eb2p->dacr),
+           readl(&cs4231_chip->eb2p->dbcr)));
X   cs4231_chip->output_ptr = NULL;
X   cs4231_chip->output_size = 0;
X   if (cs4231_chip->output_dma_handle) {
X     cs4231_chip->output_dma_handle = 0;
X     cs4231_chip->output_dma_size = 0;
X   }
-#if 0
X   if (cs4231_chip->output_next_dma_handle) {
X     cs4231_chip->output_next_dma_handle = 0;
X     cs4231_chip->output_next_dma_size = 0;
X   }
-#endif
+  dcsr = readl(&(cs4231_chip->eb2p->dcsr));
+  if(dcsr & EBUS_DCSR_EN_DMA)
+    writel(dcsr & ~EBUS_DCSR_EN_DMA, &(cs4231_chip->eb2p->dcsr));
+
+  /* Else subsequent speed setting changes are ignored by the chip. */
+  cs4231_disable_play(drv);
X }
X #endif
X 
@@ -1521,8 +1547,27 @@
X     cs4231_chip->output_next_dma_handle = 0;
X     cs4231_chip->output_next_dma_size = 0;
X   }
+#if 0 /* Not safe without shutting off the DMA controller as well. -DaveM */
+  /* Else subsequent speed setting changes are ignored by the chip. */
+  cs4231_disable_play(drv);
+#endif
X }
X 
+#ifdef EB4231_SUPPORT
+static void eb4231_pollinput(struct sparcaudio_driver *drv)
+{
+  struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
+  int x = 0, dcsr;
+
+  while (!((dcsr = readl(&(cs4231_chip->eb2c->dcsr))) & EBUS_DCSR_TC) &&
+         x <= CS_TIMEOUT) {
+    x++;
+  }
+
+  writel(dcsr | EBUS_DCSR_TC, &(cs4231_chip->eb2c->dcsr));
+}
+#endif
+
X static void cs4231_pollinput(struct sparcaudio_driver *drv)
X {
X   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
@@ -1687,8 +1732,8 @@
X {
X   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
X 
-  cs4231_chip->regs->iar = 0x0d;
-  cs4231_chip->regs->idr = (value ? LOOPB_ON : 0);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->iar), 0x0d);
+  CS4231_WRITE8(cs4231_chip, &(cs4231_chip->regs->idr), (value ? LOOPB_ON : 0));
X }
X 
X static int cs4231_ioctl(struct inode * inode, struct file * file,
@@ -1716,61 +1761,15 @@
X {
X   struct sparcaudio_driver *drv = (struct sparcaudio_driver *)dev_id;
X   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
-  int dummy1, dummy2;
+  int dummy;
X   
-  printk("in eb4231_interrupt\n");
-
-  /* Clear the interrupt. */
-  dummy1 = readl(&cs4231_chip->eb2p->dcsr);
-  dummy2 = readl(&cs4231_chip->eb2c->dcsr);
+  /* Read status. */
+  dummy = readl(&cs4231_chip->eb2c->dcsr);
X 
-  printk("play csr 0x%x capt csr 0x%x\n", dummy1, dummy2);
-
-  cs4231_chip->eb2p->dcsr = dummy1;
-  cs4231_chip->eb2c->dcsr = dummy2;
-#if 0
-  if (dummy & APC_PLAY_INT) {
-    if (dummy & APC_XINT_PNVA) {
-      cs4231_chip->perchip_info.play.samples += 
-	cs4231_length_to_samplecount(&(cs4231_chip->perchip_info.play), 
-				     cs4231_chip->playlen); 
-      eb4231_playintr(drv);
-    } 
-    /* Any other conditions we need worry about? */
-  }
-
-  if (dummy & APC_CAPT_INT) {
-    if (dummy & APC_XINT_CNVA) {
-      cs4231_chip->perchip_info.record.samples += 
-	cs4231_length_to_samplecount(&(cs4231_chip->perchip_info.record), 
-				     cs4231_chip->reclen);
-      eb4231_recintr(drv);
-    }
-    /* Any other conditions we need worry about? */
-  }
-
-  
-  if (dummy & APC_XINT_CEMP) {
-    if (cs4231_chip->perchip_info.record.active == 0) {
-      /* Fix me */
-      cs4231_chip->perchip_info.record.active = 0;
-      cs4231_chip->perchip_info.record.error = 1;
-      eb4231_recintr(drv);
-    }
-  }
-
-  if (dummy & APC_XINT_EMPT) {
-    if (!cs4231_chip->output_next_dma_handle) {
-      cs4231_chip->regs->dmacsr |= (APC_PPAUSE);
-      cs4231_disable_play(drv);
-      cs4231_chip->perchip_info.play.error = 1;
-    }
-    cs4231_chip->perchip_info.play.active = 0;
-    eb4231_playintr(drv);
-
-    eb4231_getsamplecount(drv, cs4231_chip->playlen, 0);
-  }
-#endif
+  cs4231_chip->perchip_info.record.samples += 
+          cs4231_length_to_samplecount(&(cs4231_chip->perchip_info.record), 
+                                       cs4231_chip->reclen);
+  eb4231_recintr(drv);
X }
X 
X /* ebus audio play interrupt handler. */
@@ -1780,42 +1779,29 @@
X   struct cs4231_chip *cs4231_chip = (struct cs4231_chip *)drv->private;
X   unsigned int dummy;
X   
-  dprintk(("in eb4231_interrupt2\n"));
-
-  /* Clear the interrupt. */
-  dummy = readl(&cs4231_chip->eb2p->dcsr);
-  dprintk(("play csr 0x%x\n", dummy));
+  /* Clear the interrupt.  Bleh, when not using the next-address
+   * feature, TC can only be cleared by a reset.
+   */
+  dummy = readl(&(cs4231_chip->eb2p->dcsr));
+  writel(dummy, &(cs4231_chip->eb2p->dcsr));
X 
-  if (dummy & EBUS_DCSR_INT_PEND) {
-#if 0
-    if (!(dummy & EBUS_DCSR_NA_LOADED)) {
-#endif
-      cs4231_chip->perchip_info.play.samples += 
-        cs4231_length_to_samplecount(&(cs4231_chip->perchip_info.play), 
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 06'
echo 'File patch-2.2.7 is continued in part 07'
echo 07 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 07 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 07; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
-                                     cs4231_chip->playlen); 
-      eb4231_playintr(drv);
-#if 0
-    } 
-#endif
+  /* If we get a terminal count and address loaded condition,
+   * this means the DNAR was copied into DACR.
+   */
+  if((dummy & EBUS_DCSR_TC) != 0
+     /*&& (dummy & EBUS_DCSR_A_LOADED) != 0*/) {
+    cs4231_chip->perchip_info.play.samples += 
+      cs4231_length_to_samplecount(&(cs4231_chip->perchip_info.play), 
+                                   cs4231_chip->playlen); 
+    eb4231_playintr(drv);
X   }
X 
-  if (!(dummy & EBUS_DCSR_A_LOADED)) {
-#if 0
-    if (!cs4231_chip->output_next_dma_handle) {
-#endif
-      writel((dummy & ~EBUS_DCSR_EN_DMA), &cs4231_chip->eb2p->dcsr);
-      cs4231_disable_play(drv);
-      cs4231_chip->perchip_info.play.error = 1;
-#if 0
-    }
-#endif
+  if((dummy & EBUS_DCSR_A_LOADED) == 0) {
X     cs4231_chip->perchip_info.play.active = 0;
-#if 0
X     eb4231_playintr(drv);
-#endif
+
X     eb4231_getsamplecount(drv, cs4231_chip->playlen, 0);
X   }
-
X }
X #endif
X 
@@ -2151,26 +2137,6 @@
X 
X   nregs = len / sizeof(regs[0]);
X 
-  /* Make sure we can map the registers first */
-  if (check_region(edev->base_address[0],
-                   sizeof(struct cs4231_regs))) {
-    printk("eb4231_attach: can't get region at %016lx\n",
-           edev->base_address[0]);
-    goto cleanup;
-  }
-  if (check_region(edev->base_address[1],
-                   sizeof(struct linux_ebus_dma))) {
-    printk("eb4231_attach: can't get region at %016lx\n",
-           edev->base_address[1]);
-    goto cleanup;
-  }
-  if (check_region(edev->base_address[2],
-                   sizeof(struct linux_ebus_dma))) {
-    printk("eb4231_attach: can't get region at %016lx\n",
-           edev->base_address[2]);
-    goto cleanup;
-  }
-
X   cs4231_chip->regs = (struct cs4231_regs *)edev->base_address[0];
X   cs4231_chip->eb2p = (struct linux_ebus_dma *)edev->base_address[1];
X   cs4231_chip->eb2c = (struct linux_ebus_dma *)edev->base_address[2];
@@ -2188,13 +2154,9 @@
X   cs4231_chip->irq = edev->irqs[0];
X   cs4231_chip->irq2 = edev->irqs[1];
X 
-  request_irq(cs4231_chip->irq, eb4231_cinterrupt, SA_SHIRQ, "cs4231", drv);
-#if 0
-  enable_irq(cs4231_chip->irq);
-#endif
-
-  request_irq(cs4231_chip->irq2, eb4231_pinterrupt, SA_SHIRQ, "cs4231", drv);
-  enable_irq(cs4231_chip->irq2);
+  if(request_irq(cs4231_chip->irq, eb4231_cinterrupt, SA_SHIRQ, "cs4231", drv) ||
+     request_irq(cs4231_chip->irq2, eb4231_pinterrupt, SA_SHIRQ, "cs4231", drv))
+          goto bail;
X 
X   cs4231_chip->nirqs = 2;
X 
@@ -2207,21 +2169,20 @@
X   err = register_sparcaudio_driver(drv, 1);
X 
X   if (err < 0) {
+  bail:
X     printk(KERN_ERR "cs4231: unable to register\n");
X     cs4231_disable_interrupts(drv);
X     disable_irq(cs4231_chip->irq);
X     free_irq(cs4231_chip->irq, drv);
-    if (cs4231_chip->nirqs == 2) {
-      disable_irq(cs4231_chip->irq2);
-      free_irq(cs4231_chip->irq2, drv);
-    }
+    disable_irq(cs4231_chip->irq2);
+    free_irq(cs4231_chip->irq2, drv);
+
X     release_region((unsigned long)cs4231_chip->regs, 
X                    sizeof(struct cs4231_regs));
X     release_region((unsigned long)cs4231_chip->eb2c, 
X                    sizeof(struct linux_ebus_dma));
X     release_region((unsigned long)cs4231_chip->eb2p, 
X                    sizeof(struct linux_ebus_dma));
-  cleanup:
X     kfree(drv->private);
X     return -EIO;
X   }
@@ -2312,9 +2273,11 @@
X           sparc_free_io(cs4231_chip->regs, cs4231_chip->regs_size);
X         } else {
X #ifdef EB4231_SUPPORT
-          release_region(cs4231_chip->regs, sizeof(struct cs4231_regs));
-          release_region(cs4231_chip->eb2c, sizeof(struct linux_ebus_dma));
-          release_region(cs4231_chip->eb2p, sizeof(struct linux_ebus_dma));
+          disable_irq(cs4231_chip->irq2);
+          free_irq(cs4231_chip->irq2, drv);
+          release_region((unsigned long)cs4231_chip->regs, sizeof(struct cs4231_regs));
+          release_region((unsigned long)cs4231_chip->eb2c, sizeof(struct linux_ebus_dma));
+          release_region((unsigned long)cs4231_chip->eb2p, sizeof(struct linux_ebus_dma));
X #endif
X         }
X         kfree(drv->private);
diff -u --recursive --new-file v2.2.6/linux/drivers/sbus/audio/cs4231.h linux/drivers/sbus/audio/cs4231.h
--- v2.2.6/linux/drivers/sbus/audio/cs4231.h	Tue Mar 23 14:35:48 1999
+++ linux/drivers/sbus/audio/cs4231.h	Thu Apr 22 19:24:51 1999
@@ -64,6 +64,27 @@
X   volatile unsigned long recording_count;
X };
X 
+#ifdef EB4231_SUPPORT
+#define CS4231_READ32(__C, __REG) \
+	(((__C)->status & CS_STATUS_IS_EBUS) ? readl((unsigned long)(__REG)) : (*(__REG)))
+#define CS4231_READ8(__C, __REG) \
+	(((__C)->status & CS_STATUS_IS_EBUS) ? readb((unsigned long)(__REG)) : (*(__REG)))
+#define CS4231_WRITE32(__C, __REG, __VAL) \
+	(((__C)->status & CS_STATUS_IS_EBUS) ? \
+         writel((__VAL), (unsigned long)(__REG)) : \
+         (*(__REG) = (__VAL)))
+#define CS4231_WRITE8(__C, __REG, __VAL) \
+	(((__C)->status & CS_STATUS_IS_EBUS) ? \
+         writeb((__VAL), (unsigned long)(__REG)) : \
+         (*(__REG) = (__VAL)))
+#else
+/* We can assume all is SBUS in this case. */
+#define CS4231_READ32(__C, __REG) (*(__REG))
+#define CS4231_READ8(__C, __REG) (*(__REG))
+#define CS4231_WRITE32(__C, __REG, __VAL) (*(__REG) = (__VAL))
+#define CS4231_WRITE8(__C, __REG, __VAL) (*(__REG) = (__VAL))
+#endif
+
X /* Local status bits */
X #define CS_STATUS_NEED_INIT 0x01
X #define CS_STATUS_INIT_ON_CLOSE 0x02
diff -u --recursive --new-file v2.2.6/linux/drivers/sbus/char/pcikbd.c linux/drivers/sbus/char/pcikbd.c
--- v2.2.6/linux/drivers/sbus/char/pcikbd.c	Tue Mar 23 14:35:48 1999
+++ linux/drivers/sbus/char/pcikbd.c	Wed Apr 28 08:47:39 1999
@@ -1,4 +1,4 @@
-/* $Id: pcikbd.c,v 1.25 1999/02/08 07:01:48 ecd Exp $
+/* $Id: pcikbd.c,v 1.26 1999/04/28 11:55:42 davem Exp $
X  * pcikbd.c: Ultra/AX PC keyboard support.
X  *
X  * Copyright (C) 1997  Eddie C. Dost  (e...@skynet.be)
@@ -228,8 +228,6 @@
X 	"\r\000/";					/* 0x60 - 0x6f */
X #endif
X 
-static unsigned int prev_scancode = 0;
-
X int pcikbd_setkeycode(unsigned int scancode, unsigned int keycode)
X {
X 	if(scancode < SC_LIM || scancode > 255 || keycode > 127)
@@ -262,29 +260,22 @@
X 			return 0;
X 		}
X 	}
- if(scancode == 0) {
-		prev_scancode = 0;
-		return 0;
-	}
X 	return 1;
X }
X 
-int pcikbd_pretranslate(unsigned char scancode, char raw_mode)
+int pcikbd_translate(unsigned char scancode, unsigned char *keycode,
+		     char raw_mode)
X {
-	if(scancode == 0xff) {
- prev_scancode = 0;
+	static int prev_scancode = 0;
+
+	if (scancode == 0xe0 || scancode == 0xe1) {
+		prev_scancode = scancode;
X 		return 0;
X 	}
-	if(scancode == 0xe0 || scancode == 0xe1) {
-		prev_scancode = scancode;
+	if (scancode == 0x00 || scancode == 0xff) {
+		prev_scancode = 0;
X 		return 0;
X 	}
-	return 1;
-}
-
-int pcikbd_translate(unsigned char scancode, unsigned char *keycode,
-		     char raw_mode)
-{
X 	if(prev_scancode) {
X 		if(prev_scancode != 0xe0) {
X 			if(prev_scancode == 0xe1 && scancode == 0x1d) {
@@ -338,7 +329,7 @@
X 			break;
X 		scancode = pcikbd_inb(pcikbd_iobase + KBD_DATA_REG);
X 		if((status & KBD_STAT_OBF) && do_acknowledge(scancode))
-			handle_scancode(scancode);
+			handle_scancode(scancode, !(scancode & 0x80));
X 		status = pcikbd_inb(pcikbd_iobase + KBD_STATUS_REG);
X 	} while(status & KBD_STAT_OBF);
X 	mark_bh(KEYBOARD_BH);
diff -u --recursive --new-file v2.2.6/linux/drivers/sbus/char/sunkbd.c linux/drivers/sbus/char/sunkbd.c
--- v2.2.6/linux/drivers/sbus/char/sunkbd.c	Tue Mar 23 14:35:48 1999
+++ linux/drivers/sbus/char/sunkbd.c	Thu Apr 22 19:24:51 1999
@@ -1479,7 +1479,7 @@
X 		return 0;
X 
X 	if (kbd_redirected)
-		kbd_table [kbd_opened-1].kbdmode = VC_XLATE;
+		kbd_table [kbd_redirected-1].kbdmode = VC_XLATE;
X 
X 	kbd_redirected = 0;
X 	kbd_opened = 0;
diff -u --recursive --new-file v2.2.6/linux/drivers/sbus/char/sunmouse.c linux/drivers/sbus/char/sunmouse.c
--- v2.2.6/linux/drivers/sbus/char/sunmouse.c	Mon Oct  5 13:13:40 1998
+++ linux/drivers/sbus/char/sunmouse.c	Thu Apr 22 19:24:51 1999
@@ -94,7 +94,7 @@
X 
X #undef SMOUSE_DEBUG
X 
-static void
+static int
X push_event (Firm_event *ev)
X {
X 	int next = (sunmouse.head + 1) % EV_SIZE;
@@ -102,7 +102,9 @@
X 	if (next != sunmouse.tail){
X 		sunmouse.queue.ev [sunmouse.head] = *ev;
X 		sunmouse.head = next;
+		return 1;
X 	}
+	return 0;
X }
X 
X static int
@@ -150,7 +152,11 @@
X 	extern void rs_change_mouse_baud(int newbaud);
X 
X 	if(mouse_baud == 1200)
+		mouse_baud = 2400;
+	else if(mouse_baud == 2400)
X 		mouse_baud = 4800;
+	else if(mouse_baud == 4800)
+		mouse_baud = 9600;
X 	else
X 		mouse_baud = 1200;
X 
@@ -196,7 +202,7 @@
X sun_mouse_inbyte(unsigned char byte)
X {
X 	signed char mvalue;
-	int d;
+	int d, pushed = 0;
X 	Firm_event ev;
X 
X 	add_mouse_randomness (byte);
@@ -290,29 +296,31 @@
X 		}
X 		ev.time = xtime;
X 		ev.value = ev.value ? VKEY_DOWN : VKEY_UP;
-		push_event (&ev);
+		pushed += push_event (&ev);
X 	}
X 	if (sunmouse.delta_x){
X 		ev.id = LOC_X_DELTA;
X 		ev.time = xtime;
X 		ev.value = sunmouse.delta_x;
-		push_event (&ev);
+		pushed += push_event (&ev);
X 		sunmouse.delta_x = 0;
X 	}
X 	if (sunmouse.delta_y){
X 		ev.id = LOC_Y_DELTA;
X 		ev.time = xtime;
X 		ev.value = sunmouse.delta_y;
-		push_event (&ev);
+		pushed += push_event (&ev);
X 	}
X 	
-        /* We just completed a transaction, wake up whoever is awaiting
-	 * this event.
-	 */
-	sunmouse.ready = 1;
-	if (sunmouse.fasync)
-		kill_fasync (sunmouse.fasync, SIGIO);
-	wake_up_interruptible(&sunmouse.proc_list);
+	if(pushed != 0) {
+		/* We just completed a transaction, wake up whoever is awaiting
+		 * this event.
+		 */
+		sunmouse.ready = 1;
+		if (sunmouse.fasync)
+			kill_fasync (sunmouse.fasync, SIGIO);
+		wake_up_interruptible(&sunmouse.proc_list);
+	}
X 	return;
X }
X 
diff -u --recursive --new-file v2.2.6/linux/drivers/sbus/char/zs.c linux/drivers/sbus/char/zs.c
--- v2.2.6/linux/drivers/sbus/char/zs.c	Tue Mar 23 14:35:48 1999
+++ linux/drivers/sbus/char/zs.c	Thu Apr 22 19:24:51 1999
@@ -1,4 +1,4 @@
-/* $Id: zs.c,v 1.40 1999/02/23 15:14:45 jj Exp $
+/* $Id: zs.c,v 1.41 1999/04/16 16:22:27 jj Exp $
X  * zs.c: Zilog serial port driver for the Sparc.
X  *
X  * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -1844,7 +1844,7 @@
X 
X static void show_serial_version(void)
X {
-	char *revision = "$Revision: 1.40 $";
+	char *revision = "$Revision: 1.41 $";
X 	char *version, *p;
X 
X 	version = strchr(revision, ' ');
@@ -2276,11 +2276,6 @@
X #if CONFIG_AP1000
X         printk("not doing zs_init()\n");
X         return 0;
-#endif
-
-#ifdef CONFIG_PCI
-	if (pci_present())
-		return 0;
X #endif
X 
X 	/* Setup base handler, and timer table. */
diff -u --recursive --new-file v2.2.6/linux/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- v2.2.6/linux/drivers/scsi/ide-scsi.c	Tue Feb 23 15:21:33 1999
+++ linux/drivers/scsi/ide-scsi.c	Thu Apr 22 19:24:50 1999
@@ -67,7 +67,7 @@
X 	int b_count;				/* Bytes transferred from current entry */
X 	Scsi_Cmnd *scsi_cmd;			/* SCSI command */
X 	void (*done)(Scsi_Cmnd *);		/* Scsi completion routine */
-	unsigned int flags;			/* Status/Action flags */
+	unsigned long flags;			/* Status/Action flags */
X 	unsigned long timeout;			/* Command timeout */
X } idescsi_pc_t;
X 
@@ -92,9 +92,9 @@
X typedef struct {
X 	ide_drive_t *drive;
X 	idescsi_pc_t *pc;			/* Current packet command */
-	unsigned int flags;			/* Status/Action flags */
-	int transform;				/* SCSI cmd translation layer */
-	int log;				/* log flags */
+	unsigned long flags;			/* Status/Action flags */
+	unsigned long transform;		/* SCSI cmd translation layer */
+	unsigned long log;			/* log flags */
X } idescsi_scsi_t;
X 
X /*
diff -u --recursive --new-file v2.2.6/linux/drivers/scsi/qlogicisp.c linux/drivers/scsi/qlogicisp.c
--- v2.2.6/linux/drivers/scsi/qlogicisp.c	Fri Nov 27 13:09:24 1998
+++ linux/drivers/scsi/qlogicisp.c	Thu Apr 22 19:30:08 1999
@@ -27,6 +27,7 @@
X #include <asm/io.h>
X #include <asm/irq.h>
X #include <asm/spinlock.h>
+#include <asm/byteorder.h>
X 
X #include "sd.h"
X #include "hosts.h"
@@ -49,7 +50,7 @@
X /*  Macros used for debugging */
X 
X #define DEBUG_ISP1020		0
-#define DEBUG_ISP1020_INT	0
+#define DEBUG_ISP1020_INTR	0
X #define DEBUG_ISP1020_SETUP	0
X #define TRACE_ISP		0
X 
@@ -730,17 +731,17 @@
X 	cmd->hdr.entry_type = ENTRY_COMMAND;
X 	cmd->hdr.entry_cnt = 1;
X 
-	cmd->handle = (u_int) virt_to_bus(Cmnd);
+	cmd->handle = cpu_to_le32((u_int) virt_to_bus(Cmnd));
X 	cmd->target_lun = Cmnd->lun;
X 	cmd->target_id = Cmnd->target;
-	cmd->cdb_length = Cmnd->cmd_len;
-	cmd->control_flags = CFLAG_READ | CFLAG_WRITE;
-	cmd->time_out = 30;
+	cmd->cdb_length = cpu_to_le16(Cmnd->cmd_len);
+	cmd->control_flags = cpu_to_le16(CFLAG_READ | CFLAG_WRITE);
+	cmd->time_out = cpu_to_le16(30);
X 
X 	memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len);
X 
X 	if (Cmnd->use_sg) {
-		cmd->segment_cnt = sg_count = Cmnd->use_sg;
+		cmd->segment_cnt = cpu_to_le16(sg_count = Cmnd->use_sg);
X 		sg = (struct scatterlist *) Cmnd->request_buffer;
X 		ds = cmd->dataseg;
X 
@@ -749,8 +750,8 @@
X 		if (n > 4)
X 			n = 4;
X 		for (i = 0; i < n; i++) {
-			ds[i].d_base  = (u_int) virt_to_bus(sg->address);
-			ds[i].d_count = sg->length;
+			ds[i].d_base  = cpu_to_le32((u_int) virt_to_bus(sg->address));
+			ds[i].d_count = cpu_to_le32(sg->length);
X 			++sg;
X 		}
X 		sg_count -= 4;
@@ -776,18 +777,18 @@
X 			if (n > 7)
X 				n = 7;
X 			for (i = 0; i < n; ++i) {
-				ds[i].d_base = (u_int)virt_to_bus(sg->address);
-				ds[i].d_count = sg->length;
+				ds[i].d_base = cpu_to_le32((u_int)virt_to_bus(sg->address));
+				ds[i].d_count = cpu_to_le32(sg->length);
X 				++sg;
X 			}
X 			sg_count -= n;
X 		}
X 	} else {
X 		cmd->dataseg[0].d_base =
-			(u_int) virt_to_bus(Cmnd->request_buffer);
+			cpu_to_le32((u_int) virt_to_bus(Cmnd->request_buffer));
X 		cmd->dataseg[0].d_count =
-			(u_int) Cmnd->request_bufflen;
-		cmd->segment_cnt = 1;
+			cpu_to_le32((u_int) Cmnd->request_bufflen);
+		cmd->segment_cnt = cpu_to_le16(1);
X 	}
X 
X 	outw(in_ptr, host->io_port + MBOX4);
@@ -861,22 +862,22 @@
X 
X 	DEBUG_INTR(printk("qlogicisp : response queue update\n"));
X 	DEBUG_INTR(printk("qlogicisp : response queue depth %d\n",
-			  QUEUE_DEPTH(in_ptr, out_ptr)));
+			  QUEUE_DEPTH(in_ptr, out_ptr, RES_QUEUE_LEN)));
X 
X 	while (out_ptr != in_ptr) {
X 		sts = (struct Status_Entry *) &hostdata->res[out_ptr][0];
X 		out_ptr = (out_ptr + 1) & RES_QUEUE_LEN;
X 
-		Cmnd = (Scsi_Cmnd *) bus_to_virt(sts->handle);
+		Cmnd = (Scsi_Cmnd *) bus_to_virt(le32_to_cpu(sts->handle));
X 
X 		TRACE("done", out_ptr, Cmnd);
X 
-		if (sts->completion_status == CS_RESET_OCCURRED
-		    || sts->completion_status == CS_ABORTED
-		    || (sts->status_flags & STF_BUS_RESET))
+		if (le16_to_cpu(sts->completion_status) == CS_RESET_OCCURRED
+		    || le16_to_cpu(sts->completion_status) == CS_ABORTED
+		    || (le16_to_cpu(sts->status_flags) & STF_BUS_RESET))
X 			hostdata->send_marker = 1;
X 
-		if (sts->state_flags & SF_GOT_SENSE)
+		if (le16_to_cpu(sts->state_flags) & SF_GOT_SENSE)
X 			memcpy(Cmnd->sense_buffer, sts->req_sense_data,
X 			       sizeof(Cmnd->sense_buffer));
X 
@@ -917,24 +918,24 @@
X 	ENTER("isp1020_return_status");
X 
X 	DEBUG(printk("qlogicisp : completion status = 0x%04x\n",
-		     sts->completion_status));
+		     le16_to_cpu(sts->completion_status)));
X 
-	switch(sts->completion_status) {
+	switch(le16_to_cpu(sts->completion_status)) {
X 	      case CS_COMPLETE:
X 		host_status = DID_OK;
X 		break;
X 	      case CS_INCOMPLETE:
-		if (!(sts->state_flags & SF_GOT_BUS))
+		if (!(le16_to_cpu(sts->state_flags) & SF_GOT_BUS))
X 			host_status = DID_NO_CONNECT;
-		else if (!(sts->state_flags & SF_GOT_TARGET))
+		else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_TARGET))
X 			host_status = DID_BAD_TARGET;
-		else if (!(sts->state_flags & SF_SENT_CDB))
+		else if (!(le16_to_cpu(sts->state_flags) & SF_SENT_CDB))
X 			host_status = DID_ERROR;
-		else if (!(sts->state_flags & SF_TRANSFERRED_DATA))
+		else if (!(le16_to_cpu(sts->state_flags) & SF_TRANSFERRED_DATA))
X 			host_status = DID_ERROR;
-		else if (!(sts->state_flags & SF_GOT_STATUS))
+		else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_STATUS))
X 			host_status = DID_ERROR;
-		else if (!(sts->state_flags & SF_GOT_SENSE))
+		else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_SENSE))
X 			host_status = DID_ERROR;
X 		break;
X 	      case CS_DMA_ERROR:
@@ -970,17 +971,17 @@
X 		break;
X 	      default:
X 		printk("qlogicisp : unknown completion status 0x%04x\n",
-		       sts->completion_status);
+		       le16_to_cpu(sts->completion_status));
X 		host_status = DID_ERROR;
X 		break;
X 	}
X 
X 	DEBUG_INTR(printk("qlogicisp : host status (%s) scsi status %x\n",
-			  reason[host_status], sts->scsi_status));
+			  reason[host_status], le16_to_cpu(sts->scsi_status)));
X 
X 	LEAVE("isp1020_return_status");
X 
-	return (sts->scsi_status & STATUS_MASK) | (host_status << 16);
+	return (le16_to_cpu(sts->scsi_status) & STATUS_MASK) | (host_status << 16);
X }
X 
X 
@@ -1082,7 +1083,9 @@
X 	ENTER("isp1020_reset_hardware");
X 
X 	outw(ISP_RESET, host->io_port + PCI_INTF_CTL);
+	udelay(100);
X 	outw(HCCR_RESET, host->io_port + HOST_HCCR);
+	udelay(100);
X 	outw(HCCR_RELEASE, host->io_port + HOST_HCCR);
X 	outw(HCCR_BIOS_DISABLE, host->io_port + HOST_HCCR);
X 
@@ -1103,27 +1106,25 @@
X 	printk("qlogicisp : mbox 5 0x%04x \n", inw(host->io_port + MBOX5));
X #endif /* DEBUG_ISP1020 */
X 
+	param[0] = MBOX_NO_OP;
+	isp1020_mbox_command(host, param);
+	if (param[0] != MBOX_COMMAND_COMPLETE) {
+		printk("qlogicisp : NOP test failed\n");
+		return 1;
+	}
+
X 	DEBUG(printk("qlogicisp : loading risc ram\n"));
X 
X #if RELOAD_FIRMWARE
-	/* Do not reload firmware if 1040B, i.e. revision 5 chip.  */
-	if (((struct isp1020_hostdata *) host->hostdata)->revision >= 5)
-		printk("qlogicisp : 1040B or later chip,"
-		       " firmware not (re)loaded\n");
-	else
-	{
-		int i;
-		for (i = 0; i < risc_code_length01; i++) {
-			param[0] = MBOX_WRITE_RAM_WORD;
-			param[1] = risc_code_addr01 + i;
-			param[2] = risc_code01[i];
-
-			isp1020_mbox_command(host, param);
-
-			if (param[0] != MBOX_COMMAND_COMPLETE) {
-				printk("qlogicisp : firmware load failure\n");
-				return 1;
-			}
+	for (loop_count = 0; loop_count < risc_code_length01; loop_count++) {
+		param[0] = MBOX_WRITE_RAM_WORD;
+		param[1] = risc_code_addr01 + loop_count;
+		param[2] = risc_code01[loop_count];
+		isp1020_mbox_command(host, param);
+		if (param[0] != MBOX_COMMAND_COMPLETE) {
+			printk("qlogicisp : firmware load failure at %d\n",
+			    loop_count);
+			return 1;
X 		}
X 	}
X #endif /* RELOAD_FIRMWARE */
@@ -1200,6 +1201,15 @@
X 		return 1;
X 	}
X 
+#ifdef __sparc__
+	command |= (PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY|
+		    PCI_COMMAND_INVALIDATE|PCI_COMMAND_SERR);
+	pci_write_config_word(pdev, PCI_COMMAND, command);
+	pci_read_config_word(pdev, PCI_COMMAND, &command);
+	pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 16);
+	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
+#endif
+
X 	if (command & PCI_COMMAND_IO && (io_base & 3) == 1)
X 		io_base &= PCI_BASE_ADDRESS_IO_MASK;
X 	else {
@@ -1227,6 +1237,8 @@
X 
X 	sh->irq = irq;
X 	sh->io_port = io_base;
+	sh->max_id = MAX_TARGETS;
+	sh->max_lun = MAX_LUNS;
X 
X 	LEAVE("isp1020_init");
X 
@@ -1691,14 +1703,15 @@
X 	printk("qlogicisp : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n",
X 	       status->hdr.entry_cnt, status->hdr.entry_type, status->hdr.flags);
X 	printk("qlogicisp : scsi status = 0x%04x, completion status = 0x%04x\n",
-	       status->scsi_status, status->completion_status);
+	       le16_to_cpu(status->scsi_status), le16_to_cpu(status->completion_status));
X 	printk("qlogicisp : state flags = 0x%04x, status flags = 0x%04x\n",
-	       status->state_flags, status->status_flags);
+	       le16_to_cpu(status->state_flags), le16_to_cpu(status->status_flags));
X 	printk("qlogicisp : time = 0x%04x, request sense length = 0x%04x\n",
-	       status->time, status->req_sense_len);
-	printk("qlogicisp : residual transfer length = 0x%08x\n", status->residual);
+	       le16_to_cpu(status->time), le16_to_cpu(status->req_sense_len));
+	printk("qlogicisp : residual transfer length = 0x%08x\n",
+	       le32_to_cpu(status->residual));
X 
-	for (i = 0; i < status->req_sense_len; i++)
+	for (i = 0; i < le16_to_cpu(status->req_sense_len); i++)
X 		printk("qlogicisp : sense data = 0x%02x\n", status->req_sense_data[i]);
X }
X 
diff -u --recursive --new-file v2.2.6/linux/drivers/scsi/qlogicisp_asm.c linux/drivers/scsi/qlogicisp_asm.c
--- v2.2.6/linux/drivers/scsi/qlogicisp_asm.c	Sun Feb  2 05:34:32 1997
+++ linux/drivers/scsi/qlogicisp_asm.c	Thu Apr 22 19:30:08 1999
@@ -1,1304 +1,2034 @@
X /*
- *	Version 2.10 Initiator Firmware (16:13 Oct 18, 1995)
+ *      Firmware Version 7.63.00 (12:07 Jan 27, 1999)
X  */
-
-static const unsigned short risc_code_version = 2*1024+10;
+static const unsigned short risc_code_version = 7*1024+63;
X 
X static const unsigned short risc_code_addr01 = 0x1000 ;
X 
X #if RELOAD_FIRMWARE
X 
-static const unsigned short risc_code01[] = { 
-	0x0078, 0x1041, 0x0000, 0x283a, 0x0000, 0x2043, 0x4f50, 0x5952,
-	0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
-	0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320,
-	0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350,
-	0x3130, 0x3230, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056,
-	0x6572, 0x7369, 0x6f6e, 0x2030, 0x322e, 0x3130, 0x2020, 0x2043,
-	0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050,
-	0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020,
-	0x2400, 0x20b9, 0x1212, 0x2071, 0x0010, 0x70c3, 0x0004, 0x20c9,
-	0x43ff, 0x2089, 0x115b, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf,
-	0x2020, 0x70d3, 0x0002, 0x3f00, 0x70d6, 0x20c1, 0x0008, 0x2019,
-	0x0000, 0x2009, 0xfeff, 0x2100, 0x200b, 0xa5a5, 0xa1ec, 0x7fff,
-	0x2d64, 0x206b, 0x0a0a, 0xaddc, 0x3fff, 0x2b54, 0x205b, 0x5050,
-	0x2114, 0xa286, 0xa5a5, 0x0040, 0x10b3, 0xa386, 0x000f, 0x0040,
-	0x1079, 0x2c6a, 0x2a5a, 0x20c1, 0x0000, 0x2019, 0x000f, 0x0078,
-	0x1059, 0x2c6a, 0x2a5a, 0x20c1, 0x0008, 0x2009, 0x7fff, 0x2148,
-	0x2944, 0x204b, 0x0a0a, 0xa9bc, 0x3fff, 0x2734, 0x203b, 0x5050,
-	0x2114, 0xa286, 0x0a0a, 0x0040, 0x109d, 0x284a, 0x263a, 0x20c1,
-	0x0004, 0x2009, 0x3fff, 0x2134, 0x200b, 0x5050, 0x2114, 0xa286,
-	0x5050, 0x0040, 0x109e, 0x0078, 0x1163, 0x284a, 0x263a, 0x98c0,
-	0xa188, 0x1000, 0x212c, 0x200b, 0xa5a5, 0x2114, 0xa286, 0xa5a5,
-	0x0040, 0x10b0, 0x250a, 0xa18a, 0x1000, 0x98c1, 0x0078, 0x10b5,
-	0x250a, 0x0078, 0x10b5, 0x2c6a, 0x2a5a, 0x2130, 0xa18a, 0x0040,
-	0x2128, 0xa1a2, 0x3900, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
-	0x8424, 0xa192, 0x4400, 0x2009, 0x0000, 0x2001, 0x002f, 0x1078,
-	0x1a70, 0x2218, 0x2079, 0x3900, 0x2fa0, 0x2408, 0x2011, 0x0000,
-	0x20a9, 0x0040, 0x42a4, 0x8109, 0x00c0, 0x10d0, 0x7eea, 0x7dde,
-	0x8528, 0x7dda, 0x7ce2, 0x7be6, 0x787b, 0x0000, 0x2031, 0x0030,
-	0x78c3, 0x0101, 0x780b, 0x0002, 0x780f, 0x0002, 0x784f, 0x0003,
-	0x2069, 0x3940, 0x681b, 0x0028, 0x6807, 0x0007, 0x680b, 0x00fa,
-	0x680f, 0x0008, 0x6813, 0x0005, 0x681f, 0x0000, 0x6823, 0x0006,
-	0x6817, 0x0008, 0x6827, 0x0000, 0x2069, 0x3a00, 0x2011, 0x0020,
-	0x2009, 0x0010, 0x680b, 0x0c19, 0x680f, 0x0019, 0x6803, 0xfd00,
+static const unsigned short risc_code01[] = {
+	0x0078, 0x103a, 0x0000, 0x3f14, 0x0000, 0x2043, 0x4f50, 0x5952,
+	0x4947, 0x4854, 0x2031, 0x3939, 0x3520, 0x514c, 0x4f47, 0x4943,
+	0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
+	0x3130, 0x3230, 0x2049, 0x2f54, 0x2046, 0x6972, 0x6d77, 0x6172,
+	0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, 0x372e, 0x3633,
+	0x2020, 0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20,
+	0x3030, 0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020,
+	0x3031, 0x2024, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x0048,
+	0x1045, 0x0038, 0x104b, 0x0078, 0x1047, 0x0028, 0x104b, 0x20b9,
+	0x1212, 0x0078, 0x104d, 0x20b9, 0x2222, 0x20c1, 0x0008, 0x2071,
+	0x0010, 0x70c3, 0x0004, 0x20c9, 0x76ff, 0x2089, 0x1186, 0x70c7,
+	0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x0007, 0x3f00,
+	0x70d6, 0x20c1, 0x0008, 0x2019, 0x0000, 0x2009, 0xfeff, 0x2100,
+	0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64, 0x206b, 0x0a0a, 0xaddc,
+	0x3fff, 0x2b54, 0x205b, 0x5050, 0x2114, 0xa286, 0xa5a5, 0x0040,
+	0x10bf, 0xa386, 0x000f, 0x0040, 0x1085, 0x2c6a, 0x2a5a, 0x20c1,
+	0x0000, 0x2019, 0x000f, 0x0078, 0x1065, 0x2c6a, 0x2a5a, 0x20c1,
+	0x0008, 0x2009, 0x7fff, 0x2148, 0x2944, 0x204b, 0x0a0a, 0xa9bc,
+	0x3fff, 0x2734, 0x203b, 0x5050, 0x2114, 0xa286, 0x0a0a, 0x0040,
+	0x10a9, 0x284a, 0x263a, 0x20c1, 0x0004, 0x2009, 0x3fff, 0x2134,
+	0x200b, 0x5050, 0x2114, 0xa286, 0x5050, 0x0040, 0x10aa, 0x0078,
+	0x118e, 0x284a, 0x263a, 0x98c0, 0xa188, 0x1000, 0x212c, 0x200b,
+	0xa5a5, 0x2114, 0xa286, 0xa5a5, 0x0040, 0x10bc, 0x250a, 0xa18a,
+	0x1000, 0x98c1, 0x0078, 0x10c1, 0x250a, 0x0078, 0x10c1, 0x2c6a,
+	0x2a5a, 0x2130, 0xa18a, 0x0040, 0x2128, 0xa1a2, 0x5000, 0x8424,
+	0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0xa192, 0x7700, 0x2009,
+	0x0000, 0x2001, 0x0031, 0x1078, 0x1c9d, 0x2218, 0x2079, 0x5000,
+	0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109,
+	0x00c0, 0x10dc, 0x7ef2, 0x8528, 0x7de6, 0x7cea, 0x7bee, 0x7883,
+	0x0000, 0x2031, 0x0030, 0x78cf, 0x0101, 0x780b, 0x0002, 0x780f,
+	0x0002, 0x784f, 0x0003, 0x2069, 0x5040, 0x2001, 0x04fd, 0x2004,
+	0xa082, 0x0005, 0x0048, 0x1104, 0x0038, 0x1100, 0x0078, 0x1108,
+	0x681b, 0x003c, 0x0078, 0x110a, 0x00a8, 0x1108, 0x681b, 0x003c,
+	0x681b, 0x0028, 0x6807, 0x0007, 0x680b, 0x00fa, 0x680f, 0x0008,
+	0x6813, 0x0005, 0x6823, 0x0000, 0x6827, 0x0006, 0x6817, 0x0008,
+	0x682b, 0x0000, 0x681f, 0x0019, 0x2069, 0x5280, 0x2011, 0x0020,
+	0x2009, 0x0010, 0x680b, 0x080c, 0x680f, 0x0019, 0x6803, 0xfd00,
X 	0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004,
-	0x8109, 0x00c0, 0x1102, 0x2069, 0x3a80, 0x20a9, 0x0080, 0x680b,
-	0x0040, 0x7be8, 0xa386, 0xfeff, 0x00c0, 0x1124, 0x6817, 0x0100,
-	0x681f, 0x0064, 0x0078, 0x1128, 0x6817, 0x0064, 0x681f, 0x0002,
-	0xade8, 0x0010, 0x0070, 0x112e, 0x0078, 0x1117, 0x1078, 0x1d15,
-	0x1078, 0x3366, 0x1078, 0x18a4, 0x1078, 0x37fc, 0x3200, 0xa085,
-	0x000d, 0x2090, 0x70c3, 0x0000, 0x0090, 0x1145, 0x70c0, 0xa086,
-	0x0002, 0x00c0, 0x1145, 0x1078, 0x1274, 0x1078, 0x1186, 0x78c0,
-	0xa005, 0x00c0, 0x1151, 0x1078, 0x1a99, 0x0068, 0x1155, 0x1078,
-	0x1c6f, 0x0068, 0x1155, 0x1078, 0x1997, 0x00e0, 0x1145, 0x1078,
-	0x369a, 0x0078, 0x1145, 0x1163, 0x1165, 0x1ebb, 0x1ebb, 0x33d7,
-	0x33d7, 0x1ebb, 0x1ebb, 0x0078, 0x1163, 0x0078, 0x1165, 0x0078,
-	0x1167, 0x0078, 0x1169, 0x2009, 0x0022, 0x2104, 0xa086, 0x4000,
-	0x0040, 0x1181, 0x7008, 0x800b, 0x00c8, 0x1181, 0x7007, 0x0002,
-	0xa08c, 0x0060, 0x00c0, 0x1182, 0xa084, 0x0008, 0x0040, 0x1181,
-	0x087a, 0x097a, 0x70c3, 0x4002, 0x0078, 0x1277, 0x0068, 0x11f1,
-	0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x11f1, 0x7814,
-	0xa005, 0x00c0, 0x1197, 0x0010, 0x11f2, 0x0078, 0x11f1, 0x2009,
-	0x3968, 0x2104, 0xa005, 0x00c0, 0x11f1, 0x2009, 0x3971, 0x200b,
-	0x0000, 0x7914, 0xa186, 0x0042, 0x00c0, 0x11bc, 0x7816, 0x2009,
-	0x396f, 0x2164, 0x200b, 0x0000, 0x6018, 0x70c6, 0x6014, 0x70ca,
+	0x8109, 0x00c0, 0x1122, 0x2069, 0x5300, 0x2009, 0x0002, 0x20a9,
+	0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bf0, 0xa386, 0xfeff,
+	0x00c0, 0x1148, 0x6817, 0x0100, 0x681f, 0x0064, 0x0078, 0x114c,
+	0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, 0x0070, 0x1152,
+	0x0078, 0x1139, 0x8109, 0x00c0, 0x1137, 0x1078, 0x21e9, 0x1078,
+	0x46e9, 0x1078, 0x1946, 0x1078, 0x4bdf, 0x3200, 0xa085, 0x000d,
+	0x2090, 0x70c3, 0x0000, 0x0090, 0x116c, 0x70c0, 0xa086, 0x0002,
+	0x00c0, 0x116c, 0x1078, 0x1284, 0x1078, 0x1196, 0x78cc, 0xa005,
+	0x00c0, 0x117a, 0x1078, 0x1cc6, 0x0010, 0x1180, 0x0068, 0x1180,
+	0x1078, 0x20c8, 0x0010, 0x1180, 0x0068, 0x1180, 0x1078, 0x1a2b,
+	0x00e0, 0x116c, 0x1078, 0x4a66, 0x0078, 0x116c, 0x118e, 0x1190,
+	0x23ea, 0x23ea, 0x476a, 0x476a, 0x23ea, 0x23ea, 0x0078, 0x118e,
+	0x0078, 0x1190, 0x0078, 0x1192, 0x0078, 0x1194, 0x0068, 0x1201,
+	0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1201, 0x7814,
+	0xa005, 0x00c0, 0x11a7, 0x0010, 0x1202, 0x0078, 0x1201, 0x2009,
+	0x505b, 0x2104, 0xa005, 0x00c0, 0x1201, 0x2009, 0x5064, 0x200b,
+	0x0000, 0x7914, 0xa186, 0x0042, 0x00c0, 0x11cc, 0x7816, 0x2009,
+	0x5062, 0x2164, 0x200b, 0x0000, 0x6018, 0x70c6, 0x6014, 0x70ca,
X 	0x611c, 0xa18c, 0xff00, 0x6020, 0xa084, 0x00ff, 0xa105, 0x70ce,
-	0x1078, 0x1896, 0x0078, 0x11ef, 0x7814, 0xa086, 0x0018, 0x00c0,
-	0x11c3, 0x1078, 0x1622, 0x7817, 0x0000, 0x2009, 0x396f, 0x2104,
-	0xa065, 0x0040, 0x11df, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x18f6,
-	0x0c7f, 0x609f, 0x0000, 0x1078, 0x16e9, 0x2009, 0x001c, 0x6087,
-	0x0103, 0x1078, 0x181d, 0x00c0, 0x11eb, 0x1078, 0x1896, 0x2009,
-	0x396f, 0x200b, 0x0000, 0x2009, 0x3969, 0x2104, 0x200b, 0x0000,
-	0xa005, 0x0040, 0x11ef, 0x2001, 0x4005, 0x0078, 0x1276, 0x0078,
-	0x1274, 0x007c, 0x70c3, 0x0000, 0x70c7, 0x0000, 0x70cb, 0x0000,
-	0x70cf, 0x0000, 0x70c0, 0xa0bc, 0xffc0, 0x00c0, 0x1242, 0x2038,
-	0x0079, 0x1202, 0x1274, 0x12cf, 0x1293, 0x12cf, 0x1338, 0x1338,
-	0x128a, 0x16fd, 0x1343, 0x1282, 0x1297, 0x1299, 0x129b, 0x129d,
-	0x1702, 0x1282, 0x1355, 0x1380, 0x163a, 0x16f7, 0x129f, 0x1569,
-	0x158b, 0x15a1, 0x15be, 0x1526, 0x1534, 0x1548, 0x155c, 0x13f3,
-	0x1282, 0x13a1, 0x13a7, 0x13ac, 0x13b1, 0x13b7, 0x13bc, 0x13c1,
-	0x13c6, 0x13cb, 0x13cf, 0x13e4, 0x13f0, 0x1282, 0x1282, 0x1282,
-	0x1282, 0x13ff, 0x1408, 0x1417, 0x143d, 0x1447, 0x144e, 0x1474,
-	0x1483, 0x1492, 0x14a4, 0x1506, 0x1516, 0x1282, 0x1282, 0x1282,
-	0x1282, 0x151b, 0xa0bc, 0xffa0, 0x00c0, 0x1282, 0x2038, 0xa084,
-	0x001f, 0x0079, 0x124b, 0x1719, 0x171c, 0x172c, 0x17a8, 0x17e1,
-	0x1282, 0x1282, 0x1282, 0x1282, 0x1282, 0x1282, 0x1282, 0x1282,
-	0x1282, 0x1282, 0x1282, 0x12c5, 0x132e, 0x134b, 0x1376, 0x1630,
-	0x1282, 0x1282, 0x1282, 0x1282, 0x1282, 0x17f9, 0x1803, 0x1807,
-	0x1815, 0x1282, 0x1282, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078,
-	0x1276, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068,
-	0x1277, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091,
-	0x4080, 0x007c, 0x70c3, 0x4001, 0x0078, 0x1277, 0x70c3, 0x4006,
-	0x0078, 0x1277, 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005,
-	0x53a3, 0x0078, 0x1274, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078,
-	0x1274, 0x0078, 0x1274, 0x0078, 0x1274, 0x0078, 0x1274, 0x2091,
-	0x8000, 0x70c3, 0x0000, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf,
-	0x2020, 0x70d3, 0x0002, 0x3f00, 0x70d6, 0x2079, 0x0000, 0x781b,
-	0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x0457, 0x2051,
-	0x0470, 0x2061, 0x0472, 0x20b9, 0xffff, 0x20c1, 0x0000, 0x2091,
-	0x5000, 0x2091, 0x4080, 0x0078, 0x0455, 0x1078, 0x1a04, 0x00c0,
-	0x1286, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x12d2, 0x2029,
-	0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0, 0x2098,
-	0x2031, 0x0030, 0x81ff, 0x0040, 0x1274, 0x7007, 0x0004, 0x731a,
-	0x721e, 0x7422, 0x7526, 0x2051, 0x0012, 0x2049, 0x130d, 0x2041,
-	0x1274, 0x7003, 0x0002, 0xa786, 0x0001, 0x0040, 0x12f5, 0xa786,
-	0x0050, 0x0040, 0x12f5, 0x0078, 0x12fb, 0x2049, 0x131a, 0x2041,
-	0x1326, 0x7003, 0x0003, 0x7017, 0x0000, 0x810b, 0x7112, 0x00c8,
-	0x1303, 0x7017, 0x0001, 0x7007, 0x0001, 0xa786, 0x0001, 0x0040,
-	0x131a, 0xa786, 0x0050, 0x0040, 0x131a, 0x700c, 0xa084, 0x007f,
-	0x2009, 0x0040, 0xa102, 0x8004, 0x094a, 0x20a8, 0x26a0, 0x53a6,
-	0x0078, 0x116b, 0x700c, 0xa084, 0x007f, 0x0040, 0x131a, 0x80ac,
-	0x0048, 0x131a, 0x2698, 0x53a5, 0x0078, 0x116b, 0x700c, 0xa084,
-	0x007f, 0x80ac, 0x2698, 0x53a5, 0x0078, 0x1274, 0x1078, 0x1a04,
-	0x00c0, 0x1286, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x12d2,
-	0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x00c0, 0x1340, 0x200a,
-	0x72ca, 0x0078, 0x1273, 0x70c7, 0x0002, 0x70cb, 0x000a, 0x70cf,
-	0x0000, 0x0078, 0x1274, 0x1078, 0x1a04, 0x00c0, 0x1286, 0x75d8,
-	0x76dc, 0x75da, 0x76de, 0x0078, 0x1358, 0x2029, 0x0000, 0x2530,
-	0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca, 0x73ce, 0x74d2,
-	0xa005, 0x0040, 0x1370, 0x8001, 0x788a, 0x7a92, 0x7b96, 0x7d9a,
-	0x7e9e, 0x7c8e, 0x78c0, 0xa084, 0xfffc, 0x78c2, 0x0078, 0x1374,
-	0x78c0, 0xa085, 0x0001, 0x78c2, 0x0078, 0x1274, 0x1078, 0x1a04,
-	0x00c0, 0x1286, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x1383,
+	0x1078, 0x192b, 0x0078, 0x11ff, 0x7814, 0xa086, 0x0018, 0x00c0,
+	0x11d3, 0x1078, 0x165a, 0x7817, 0x0000, 0x2009, 0x5062, 0x2104,
+	0xa065, 0x0040, 0x11ef, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x1996,
+	0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, 0x000c, 0x6007,
+	0x0103, 0x1078, 0x1907, 0x00c0, 0x11fb, 0x1078, 0x192b, 0x2009,
+	0x5062, 0x200b, 0x0000, 0x2009, 0x505c, 0x2104, 0x200b, 0x0000,
+	0xa005, 0x0040, 0x11ff, 0x2001, 0x4005, 0x0078, 0x1286, 0x0078,
+	0x1284, 0x007c, 0x70c3, 0x0000, 0x70c7, 0x0000, 0x70cb, 0x0000,
+	0x70cf, 0x0000, 0x70c0, 0xa0bc, 0xffc0, 0x00c0, 0x1252, 0x2038,
+	0x0079, 0x1212, 0x1284, 0x12e5, 0x12a9, 0x12fe, 0x130d, 0x1313,
+	0x12a0, 0x1748, 0x1317, 0x1298, 0x12ad, 0x12af, 0x12b1, 0x12b3,
+	0x174d, 0x1298, 0x1329, 0x1360, 0x1672, 0x1742, 0x12b5, 0x1591,
+	0x15ad, 0x15c9, 0x15f4, 0x154a, 0x1558, 0x156c, 0x1580, 0x13df,
+	0x1298, 0x138d, 0x1393, 0x1398, 0x139d, 0x13a3, 0x13a8, 0x13ad,
+	0x13b2, 0x13b7, 0x13bb, 0x13d0, 0x13dc, 0x1298, 0x1298, 0x1298,
+	0x1298, 0x13eb, 0x13f4, 0x1403, 0x1429, 0x1433, 0x143a, 0x1480,
+	0x148f, 0x149e, 0x14b0, 0x152a, 0x153a, 0x1298, 0x1298, 0x1298,
+	0x1298, 0x153f, 0xa0bc, 0xffa0, 0x00c0, 0x1298, 0x2038, 0xa084,
+	0x001f, 0x0079, 0x125b, 0x1786, 0x1789, 0x1799, 0x1298, 0x1298,
+	0x18d8, 0x18f5, 0x1298, 0x1298, 0x1298, 0x18f9, 0x1901, 0x1298,
+	0x1298, 0x1298, 0x1298, 0x12db, 0x12f4, 0x131f, 0x1356, 0x1668,
+	0x1764, 0x1778, 0x1298, 0x1829, 0x1298, 0x18b4, 0x18be, 0x18c2,
+	0x18d0, 0x1298, 0x1298, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078,
+	0x1286, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068,
+	0x1287, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x00e0,
+	0x128f, 0x00e0, 0x1291, 0x0068, 0x1291, 0x2091, 0x4080, 0x007c,
+	0x70c3, 0x4001, 0x0078, 0x1287, 0x70c3, 0x4006, 0x0078, 0x1287,
+	0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078,
+	0x1284, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x1284, 0x0078,
+	0x1284, 0x0078, 0x1284, 0x0078, 0x1284, 0x2091, 0x8000, 0x70c3,
+	0x0000, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3,
+	0x0007, 0x3f00, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001, 0x2031,
+	0x0030, 0x2059, 0x1000, 0x2029, 0x0457, 0x2051, 0x0470, 0x2061,
+	0x0472, 0x20b9, 0xffff, 0x20c1, 0x0000, 0x2091, 0x5000, 0x2091,
+	0x4080, 0x0078, 0x0455, 0x1078, 0x1b36, 0x00c0, 0x129c, 0x75d8,
+	0x74dc, 0x75da, 0x74de, 0x0078, 0x12e8, 0x2029, 0x0000, 0x2520,
+	0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1a70, 0x0040, 0x1284,
+	0x70c3, 0x4002, 0x0078, 0x1284, 0x1078, 0x1b36, 0x00c0, 0x129c,
+	0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1301, 0x2029, 0x0000,
+	0x2520, 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1ad0, 0x0040,
+	0x1284, 0x70c3, 0x4002, 0x0078, 0x1284, 0x71c4, 0x70c8, 0x2114,
+	0x200a, 0x0078, 0x1282, 0x71c4, 0x2114, 0x0078, 0x1282, 0x70c7,
+	0x0007, 0x70cb, 0x003f, 0x70cf, 0x0000, 0x0078, 0x1284, 0x1078,
+	0x1b36, 0x00c0, 0x129c, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078,
+	0x132c, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0,
+	0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x1350, 0x8001,
+	0x7892, 0xa084, 0xfc00, 0x0040, 0x1345, 0x78cc, 0xa085, 0x0001,
+	0x78ce, 0x2001, 0x4005, 0x0078, 0x1286, 0x7a9a, 0x7b9e, 0x7da2,
+	0x7ea6, 0x7c96, 0x78cc, 0xa084, 0xfffc, 0x78ce, 0x0078, 0x1354,
+	0x78cc, 0xa085, 0x0001, 0x78ce, 0x0078, 0x1284, 0x1078, 0x1b36,
+	0x00c0, 0x129c, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x1363,
X 	0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6,
-	0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0040, 0x139b, 0x8001, 0x78a6,
-	0x7aae, 0x7bb2, 0x7db6, 0x7eba, 0x7caa, 0x78c0, 0xa084, 0xfcff,
-	0x78c2, 0x0078, 0x139f, 0x78c0, 0xa085, 0x0100, 0x78c2, 0x0078,
-	0x1274, 0x2009, 0x395f, 0x210c, 0x7ae4, 0x0078, 0x1272, 0x2009,
-	0x3941, 0x210c, 0x0078, 0x1273, 0x2009, 0x3942, 0x210c, 0x0078,
-	0x1273, 0x2061, 0x3940, 0x610c, 0x6210, 0x0078, 0x1272, 0x2009,
-	0x3945, 0x210c, 0x0078, 0x1273, 0x2009, 0x3946, 0x210c, 0x0078,
-	0x1273, 0x2009, 0x3947, 0x210c, 0x0078, 0x1273, 0x2009, 0x3948,
-	0x210c, 0x0078, 0x1273, 0x7908, 0x7a0c, 0x0078, 0x1272, 0x71c4,
-	0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8, 0x3a00,
-	0x6a00, 0x6804, 0xa084, 0x0008, 0x0040, 0x13e1, 0x6b08, 0x0078,
-	0x13e2, 0x6b0c, 0x0078, 0x1271, 0x77c4, 0x1078, 0x18b4, 0x2091,
-	0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x1271,
-	0x794c, 0x0078, 0x1273, 0x77c4, 0x1078, 0x18b4, 0x2091, 0x8000,
-	0x6908, 0x6a18, 0x6b10, 0x2091, 0x8001, 0x0078, 0x1271, 0x71c4,
-	0xa182, 0x0010, 0x00c8, 0x126c, 0x1078, 0x1d9b, 0x0078, 0x1271,
-	0x71c4, 0xa182, 0x0010, 0x00c8, 0x126c, 0x2011, 0x3941, 0x2204,
-	0x007e, 0x2112, 0x1078, 0x1d54, 0x017f, 0x0078, 0x1273, 0x71c4,
-	0x2011, 0x1435, 0x20a9, 0x0008, 0x2204, 0xa106, 0x0040, 0x1427,
-	0x8210, 0x0070, 0x1425, 0x0078, 0x141c, 0x0078, 0x126c, 0xa292,
-	0x1435, 0x027e, 0x2011, 0x3942, 0x2204, 0x2112, 0x017f, 0x007e,
-	0x1078, 0x1d60, 0x017f, 0x0078, 0x1273, 0x03e8, 0x00fa, 0x01f4,
-	0x02ee, 0x0064, 0x0019, 0x0032, 0x004b, 0x2061, 0x3940, 0x610c,
-	0x6210, 0x70c4, 0x600e, 0x70c8, 0x6012, 0x0078, 0x1272, 0x2061,
-	0x3940, 0x6114, 0x70c4, 0x6016, 0x0078, 0x1273, 0x71c4, 0x2011,
-	0x0004, 0x2019, 0x1212, 0xa186, 0x0028, 0x0040, 0x1467, 0x2011,
-	0x0005, 0x2019, 0x1212, 0xa186, 0x0032, 0x0040, 0x1467, 0x2011,
-	0x0006, 0x2019, 0x2323, 0xa186, 0x003c, 0x00c0, 0x126c, 0x2061,
-	0x3940, 0x6018, 0x007e, 0x611a, 0x23b8, 0x1078, 0x1d71, 0x1078,
-	0x37fc, 0x017f, 0x0078, 0x1273, 0x71c4, 0xa184, 0xffcf, 0x00c0,
-	0x126c, 0x2011, 0x3947, 0x2204, 0x2112, 0x007e, 0x1078, 0x1d93,
-	0x017f, 0x0078, 0x1273, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x126c,
-	0x2011, 0x3948, 0x2204, 0x007e, 0x2112, 0x1078, 0x1d82, 0x017f,
-	0x0078, 0x1273, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x126b,
-	0xa284, 0xfffd, 0x00c0, 0x126b, 0x2100, 0x7908, 0x780a, 0x2200,
-	0x7a0c, 0x780e, 0x0078, 0x1272, 0x71c4, 0x8107, 0xa084, 0x000f,
-	0x8003, 0x8003, 0x8003, 0xa0e8, 0x3a00, 0x2019, 0x0000, 0x72c8,
-	0x6800, 0x007e, 0xa226, 0x0040, 0x14d3, 0x6a02, 0xa484, 0x2000,
-	0x0040, 0x14bc, 0xa39d, 0x0010, 0xa484, 0x1000, 0x0040, 0x14c2,
-	0xa39d, 0x0008, 0xa484, 0x4000, 0x0040, 0x14d3, 0x810f, 0xa284,
-	0x4000, 0x0040, 0x14cf, 0x1078, 0x1db5, 0x0078, 0x14d3, 0x1078,
-	0x1da7, 0x0078, 0x14d3, 0x72cc, 0x82ff, 0x0040, 0x14ff, 0x6808,
-	0xa206, 0x0040, 0x14ff, 0xa2a4, 0x00ff, 0x2061, 0x3940, 0x6118,
-	0xa186, 0x0028, 0x0040, 0x14ec, 0xa186, 0x0032, 0x0040, 0x14f2,
-	0xa186, 0x003c, 0x0040, 0x14f8, 0xa482, 0x0064, 0x00c8, 0x126d,
-	0x0078, 0x14fc, 0xa482, 0x0050, 0x00c8, 0x126d, 0x0078, 0x14fc,
-	0xa482, 0x0043, 0x00c8, 0x126d, 0x6a0a, 0xa39d, 0x000a, 0x6804,
-	0xa305, 0x6806, 0x027f, 0x6b0c, 0x0078, 0x1271, 0x77c4, 0x1078,
-	0x18b4, 0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8,
-	0x6816, 0x70cc, 0x681e, 0x2708, 0x0078, 0x1271, 0x70c4, 0x794c,
-	0x784e, 0x0078, 0x1273, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010,
-	0x00c8, 0x126c, 0x1078, 0x1dc3, 0x0078, 0x1271, 0x77c4, 0x1078,
-	0x18b4, 0x2091, 0x8000, 0x6a08, 0xa295, 0x0002, 0x6a0a, 0x2091,
-	0x8001, 0x2708, 0x0078, 0x1272, 0x77c4, 0x1078, 0x18b4, 0x2091,
-	0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0040,
-	0x1543, 0x1078, 0x1cf6, 0x2091, 0x8001, 0x2708, 0x0078, 0x1272,
-	0x77c4, 0x1078, 0x18b4, 0x2091, 0x8000, 0x6a08, 0xa295, 0x0004,
-	0x6a0a, 0x6804, 0xa005, 0x0040, 0x1557, 0x1078, 0x1cf6, 0x2091,
-	0x8001, 0x2708, 0x0078, 0x1272, 0x77c4, 0x2041, 0x0001, 0x2049,
-	0x0005, 0x2051, 0x0020, 0x1078, 0x18c1, 0x2708, 0x6a08, 0x0078,
-	0x1272, 0x77c4, 0x73c8, 0x72cc, 0x77c6, 0x73ca, 0x72ce, 0x1078,
-	0x193c, 0x00c0, 0x1587, 0x6818, 0xa005, 0x0040, 0x1581, 0x2708,
-	0x1078, 0x1dd3, 0x00c0, 0x1581, 0x7817, 0x0015, 0x2091, 0x8001,
-	0x007c, 0x2091, 0x8001, 0x2001, 0x4005, 0x0078, 0x1276, 0x2091,
-	0x8001, 0x0078, 0x1274, 0x77c4, 0x77c6, 0x2061, 0x3940, 0x60a3,
-	0x0003, 0x67b6, 0x60c7, 0x000f, 0x2041, 0x0021, 0x2049, 0x0005,
-	0x2051, 0x0020, 0x1078, 0x18c1, 0x7817, 0x0016, 0x1078, 0x1cf6,
-	0x007c, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2061, 0x3940, 0x60a3,
-	0x0002, 0x67b6, 0x60c7, 0x000f, 0x7817, 0x0017, 0x1078, 0x1cf6,
-	0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x1078, 0x18c1,
-	0x8738, 0xa784, 0x0007, 0x00c0, 0x15b6, 0x007c, 0x78c0, 0xa084,
-	0x0003, 0x00c0, 0x15e2, 0x2039, 0x0000, 0x2041, 0x0021, 0x2049,
-	0x0004, 0x2051, 0x0008, 0x1078, 0x18b4, 0x2091, 0x8000, 0x6808,
-	0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x0007, 0x00c0,
-	0x15cb, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00,
-	0x00c0, 0x15cb, 0x2091, 0x8000, 0x2069, 0x0100, 0x6830, 0xa084,
-	0x0040, 0x0040, 0x160b, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848,
-	0xa084, 0x0004, 0x0040, 0x15f8, 0x0070, 0x15f8, 0x0078, 0x15ef,
-	0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0040,
-	0x1605, 0x0070, 0x1605, 0x0078, 0x15fc, 0x20a9, 0x00fa, 0x0070,
-	0x160b, 0x0078, 0x1607, 0x2079, 0x3900, 0x7817, 0x0018, 0x2061,
-	0x3940, 0x60a3, 0x0001, 0x60c7, 0x000f, 0x78c0, 0xa085, 0x0002,
-	0x78c2, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0047, 0x2091,
-	0x8001, 0x007c, 0x78c0, 0xa084, 0xfffd, 0x78c2, 0xa084, 0x0001,
-	0x00c0, 0x162c, 0x1078, 0x197e, 0x71c4, 0x71c6, 0x794a, 0x007c,
-	0x1078, 0x1a04, 0x00c0, 0x1286, 0x75d8, 0x74dc, 0x75da, 0x74de,
-	0x0078, 0x163d, 0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8, 0x72cc,
-	0x71c6, 0x73ca, 0x72ce, 0x2079, 0x3900, 0x1078, 0x188d, 0x0040,
-	0x16e5, 0x20a9, 0x0005, 0x20a1, 0x3916, 0x41a1, 0x2009, 0x0040,
-	0x1078, 0x1857, 0x0040, 0x1658, 0x1078, 0x1896, 0x0078, 0x16e5,
-	0x6004, 0xa084, 0xff00, 0x8007, 0x8009, 0x0040, 0x16b9, 0x0c7e,
-	0x2c68, 0x1078, 0x188d, 0x0040, 0x1688, 0x2c00, 0x689e, 0x8109,
-	0x00c0, 0x1660, 0x609f, 0x0000, 0x0c7f, 0x0c7e, 0x7218, 0x731c,
-	0x7420, 0x7524, 0x2c68, 0x689c, 0xa065, 0x0040, 0x16b8, 0x2009,
-	0x0040, 0x1078, 0x1857, 0x00c0, 0x16a1, 0x6004, 0xa084, 0x00ff,
-	0xa086, 0x0002, 0x00c0, 0x1688, 0x2d00, 0x6002, 0x0078, 0x166e,
-	0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x18f6, 0x0c7f, 0x609f,
-	0x0000, 0x1078, 0x16e9, 0x2009, 0x001c, 0x6008, 0xa085, 0x0200,
-	0x600a, 0x6004, 0x6086, 0x1078, 0x181d, 0x1078, 0x1896, 0x0078,
-	0x16e5, 0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x18f6, 0x0c7f,
-	0x609f, 0x0000, 0x1078, 0x16e9, 0x2009, 0x001c, 0x6087, 0x0103,
-	0x601b, 0x0003, 0x1078, 0x181d, 0x1078, 0x1896, 0x0078, 0x16e5,
-	0x0c7f, 0x74c4, 0x73c8, 0x72cc, 0x6014, 0x7817, 0x0012, 0x0e7e,
-	0x2071, 0x3940, 0x70a3, 0x0005, 0x70a7, 0x0000, 0x73aa, 0x72ae,
-	0x74b2, 0x70b6, 0x70bb, 0x0000, 0x2c00, 0x70be, 0x70c3, 0x0000,
-	0xa02e, 0x2530, 0x611c, 0xa184, 0x0060, 0x0040, 0x16d9, 0x1078,
-	0x330a, 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x669a, 0x60af, 0x0000,
-	0x60b3, 0x0000, 0x1078, 0x1cf6, 0x007c, 0x70c3, 0x4005, 0x0078,
-	0x1277, 0x20a9, 0x0005, 0x2099, 0x3916, 0x530a, 0x2100, 0xa210,
-	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c, 0x71c4,
-	0x70c7, 0x0000, 0x7906, 0x0078, 0x1274, 0x71c4, 0x71c6, 0x2168,
-	0x0078, 0x1704, 0x2069, 0x1000, 0x690c, 0xa016, 0x2d04, 0xa210,
-	0x8d68, 0x8109, 0x00c0, 0x1706, 0xa285, 0x0000, 0x00c0, 0x1714,
-	0x70c3, 0x4000, 0x0078, 0x1716, 0x70c3, 0x4003, 0x70ca, 0x0078,
-	0x1277, 0x79d8, 0x0078, 0x1273, 0x71c4, 0x71c6, 0x2198, 0x20a1,
-	0x0042, 0x20a9, 0x0004, 0x53a3, 0x21a0, 0x2099, 0x0042, 0x20a9,
-	0x0004, 0x53a3, 0x0078, 0x1274, 0x70c4, 0x2068, 0x2079, 0x3900,
-	0x1078, 0x188d, 0x0040, 0x17a4, 0x6007, 0x0001, 0x600b, 0x0000,
-	0x602b, 0x0000, 0x601b, 0x0006, 0x6a10, 0xa28c, 0x0007, 0xa284,
-	0x00f0, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x6016, 0xa284,
-	0x0800, 0x0040, 0x174f, 0x601b, 0x000a, 0x0078, 0x1755, 0xa284,
-	0x1000, 0x0040, 0x1755, 0x601b, 0x000c, 0xa284, 0x0300, 0x0040,
-	0x175e, 0x602b, 0x0001, 0x8004, 0x8004, 0x8004, 0xa085, 0x0001,
-	0x601e, 0x6023, 0x0000, 0x6027, 0x000a, 0xa284, 0x0400, 0x0040,
-	0x176b, 0x602b, 0x0000, 0x20a9, 0x0006, 0xac80, 0x000b, 0x20a0,
-	0xad80, 0x0005, 0x2098, 0x53a3, 0xa284, 0x0300, 0x00c0, 0x1780,
-	0x6046, 0x604a, 0x604e, 0x6052, 0x6096, 0x609a, 0x0078, 0x178a,
-	0x6800, 0x6046, 0x6804, 0x604a, 0x6e08, 0x664e, 0x6d0c, 0x6552,
-	0x6596, 0x669a, 0x6014, 0x7817, 0x0042, 0x2c08, 0x2061, 0x3940,
-	0x60a3, 0x0005, 0x60a7, 0x0000, 0x60ab, 0x0000, 0x60af, 0x0000,
-	0x60b3, 0x0000, 0x60b6, 0x61be, 0xa284, 0x0400, 0x60c2, 0x1078,
-	0x32f5, 0x1078, 0x1cf6, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1277,
-	0x78f0, 0xa005, 0x0040, 0x1282, 0x2091, 0x8000, 0x70c4, 0x800a,
-	0x2011, 0x0010, 0x810c, 0x0048, 0x17ba, 0x3a00, 0xa084, 0xfff7,
-	0x0078, 0x17bd, 0x3a00, 0xa085, 0x0008, 0x20d0, 0x0005, 0x0005,
-	0xa084, 0xfffb, 0x20d0, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005,
-	0x0005, 0x0005, 0x0005, 0xa085, 0x0004, 0x20d0, 0x0005, 0x0005,
-	0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x8211, 0x00c0,
-	0x17b2, 0x3a00, 0xa085, 0x0008, 0x20d0, 0x2091, 0x8001, 0x0078,
-	0x1274, 0x2011, 0x04fd, 0x2204, 0xa082, 0x0004, 0x0048, 0x17f5,
-	0x78f3, 0x0001, 0x2009, 0xff01, 0x200a, 0x2001, 0x000c, 0x20d8,
-	0x2001, 0x000c, 0x20d0, 0x0078, 0x1274, 0x2001, 0x4005, 0x0078,
-	0x1276, 0x7978, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x00c8, 0x126c,
-	0x797a, 0x0078, 0x1274, 0x7978, 0x71c6, 0x0078, 0x1274, 0x796c,
-	0x71c6, 0x71c4, 0x796e, 0x7970, 0x71ca, 0x71c8, 0x7972, 0x7974,
-	0x71ce, 0x71cc, 0x7976, 0x0078, 0x1274, 0x796c, 0x71c6, 0x7970,
-	0x71ca, 0x7974, 0x71ce, 0x0078, 0x1274, 0x700c, 0xa084, 0x00ff,
-	0x0040, 0x1829, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
-	0x1824, 0x7017, 0x0000, 0x7112, 0x721a, 0x731e, 0x7422, 0x7526,
-	0xac80, 0x0001, 0x8108, 0x810c, 0x81a9, 0x8098, 0x20a1, 0x0030,
-	0x6084, 0x20a2, 0x53a6, 0x780c, 0xa085, 0x0000, 0x7002, 0x7007,
-	0x0001, 0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x1841,
-	0x7108, 0x8103, 0x00c8, 0x1841, 0x7014, 0xa005, 0x0040, 0x1841,
-	0x7007, 0x0002, 0xa184, 0x0060, 0x7003, 0x0000, 0x007c, 0x700c,
-	0xa084, 0x00ff, 0x0040, 0x1863, 0x7007, 0x0004, 0x7004, 0xa084,
-	0x0004, 0x00c0, 0x185e, 0x7017, 0x0000, 0x7112, 0x721a, 0x7422,
-	0x7526, 0x731e, 0x2099, 0x0030, 0x8108, 0x81ac, 0x780c, 0xa085,
-	0x0001, 0x7002, 0x7007, 0x0001, 0x2009, 0x0022, 0x2104, 0xa084,
-	0x4000, 0x00c0, 0x1874, 0x7008, 0x800b, 0x00c8, 0x1874, 0x7007,
-	0x0002, 0xa08c, 0x0060, 0x00c0, 0x188a, 0xac80, 0x0001, 0x20a0,
-	0x53a5, 0xa006, 0x7003, 0x0000, 0x007c, 0x7850, 0xa065, 0x0040,
-	0x1895, 0x2c04, 0x7852, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079,
-	0x3900, 0x7850, 0x2062, 0x2c00, 0xa005, 0x00c0, 0x18a1, 0x1078,
-	0x1eac, 0x7852, 0x0f7f, 0x007c, 0x2011, 0x4400, 0x7a52, 0x7be4,
-	0x8319, 0x0040, 0x18b1, 0xa280, 0x002f, 0x2012, 0x2010, 0x0078,
-	0x18a8, 0x2013, 0x0000, 0x007c, 0xa784, 0x0f00, 0x800c, 0xa784,
-	0x0007, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e8, 0x3a80,
-	0x007c, 0x1078, 0x18b4, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808,
-	0xa084, 0xffef, 0xa80d, 0x690a, 0x2091, 0x8000, 0x2009, 0x394f,
-	0x210c, 0x6804, 0xa005, 0x0040, 0x18de, 0xa116, 0x00c0, 0x18de,
-	0x2060, 0x6000, 0x6806, 0x017e, 0x0078, 0x18e1, 0x2009, 0x0000,
-	0x017e, 0x6804, 0xa065, 0x0040, 0x18f0, 0x6000, 0x6806, 0x1078,
-	0x1903, 0x1078, 0x1a14, 0x6810, 0x8001, 0x6812, 0x00c0, 0x18e1,
-	0x017f, 0x6902, 0x6906, 0x2091, 0x8001, 0x007c, 0xa065, 0x0040,
-	0x1902, 0x609c, 0x609f, 0x0000, 0x2008, 0x1078, 0x1896, 0x2100,
-	0x0078, 0x18f6, 0x007c, 0x6007, 0x0103, 0x20a9, 0x001c, 0xac80,
-	0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a, 0x682c,
-	0x6022, 0x007c, 0x0e7e, 0x2071, 0x3940, 0x7040, 0xa08c, 0x0080,
-	0x00c0, 0x1920, 0xa088, 0x3980, 0x2d0a, 0x8000, 0x7042, 0xa006,
-	0x0e7f, 0x007c, 0x0e7e, 0x2071, 0x3940, 0x2009, 0x3980, 0x7240,
-	0x8221, 0x8211, 0x0048, 0x193a, 0x2104, 0x8108, 0xad06, 0x00c0,
-	0x1929, 0x8119, 0x211e, 0x8108, 0x8318, 0x8211, 0x00c8, 0x1932,
-	0x7442, 0xa006, 0x0e7f, 0x007c, 0x1078, 0x18b4, 0x2091, 0x8000,
-	0x6804, 0x781e, 0xa065, 0x0040, 0x197d, 0x0078, 0x194d, 0x2c00,
-	0x781e, 0x6000, 0xa065, 0x0040, 0x197d, 0x6010, 0xa306, 0x00c0,
-	0x1947, 0x600c, 0xa206, 0x00c0, 0x1947, 0x2c28, 0x6804, 0xac06,
-	0x00c0, 0x1964, 0x6000, 0x2060, 0x6806, 0xa005, 0x00c0, 0x1964,
-	0x6803, 0x0000, 0x0078, 0x196e, 0x6400, 0x781c, 0x2060, 0x6402,
-	0xa486, 0x0000, 0x00c0, 0x196e, 0x2c00, 0x6802, 0x2560, 0x1078,
-	0x1903, 0x601b, 0x0005, 0x6023, 0x0020, 0x1078, 0x1a14, 0x6810,
-	0x8001, 0x6812, 0x2001, 0xffff, 0xa005, 0x007c, 0x2039, 0x0000,
-	0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x1078, 0x18c1,
-	0x8738, 0xa784, 0x0007, 0x00c0, 0x1986, 0xa7bc, 0xff00, 0x873f,
-	0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1986, 0x007c, 0x2061,
-	0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x19a8, 0x2091, 0x8000,
-	0x78d4, 0x78d7, 0x0000, 0x2091, 0x8001, 0xa005, 0x00c0, 0x19a9,
-	0x007c, 0xa08c, 0xfff0, 0x0040, 0x19af, 0x1078, 0x1eac, 0x0079,
-	0x19b1, 0x19c1, 0x19c3, 0x19c9, 0x19cd, 0x19c1, 0x19d1, 0x19c1,
-	0x19d8, 0x19dc, 0x19e0, 0x1a0a, 0x1a0e, 0x19c1, 0x19c1, 0x19c1,
-	0x19c1, 0x1078, 0x1eac, 0x1078, 0x197e, 0x2001, 0x8001, 0x0078,
-	0x1276, 0x2001, 0x8003, 0x0078, 0x1276, 0x2001, 0x8004, 0x0078,
-	0x1276, 0x1078, 0x197e, 0x2001, 0x8006, 0x007c, 0x0078, 0x1276,
-	0x2001, 0x8008, 0x0078, 0x1276, 0x2001, 0x8009, 0x0078, 0x1276,
-	0x2091, 0x8000, 0x2069, 0x3940, 0x6800, 0xa086, 0x0000, 0x0040,
-	0x19ee, 0x2091, 0x8001, 0x78d7, 0x0009, 0x007c, 0x68b4, 0xa0bc,
-	0xff00, 0x2091, 0x8000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051,
-	0x0010, 0x1078, 0x18c1, 0x8738, 0xa784, 0x0007, 0x00c0, 0x19f9,
-	0x2001, 0x800a, 0x0078, 0x1276, 0x2001, 0x04fd, 0x2004, 0xa086,
-	0x0004, 0x007c, 0x2001, 0x800c, 0x0078, 0x1276, 0x1078, 0x197e,
-	0x2001, 0x800d, 0x0078, 0x1276, 0x6004, 0x6086, 0x2c08, 0x2063,
-	0x0000, 0x787c, 0x8000, 0x787e, 0x7880, 0xa005, 0x7982, 0x0040,
-	0x1a24, 0x2c02, 0x0078, 0x1a25, 0x7986, 0x007c, 0x0c7e, 0x2061,
-	0x3900, 0x6887, 0x0103, 0x2d08, 0x206b, 0x0000, 0x607c, 0x8000,
-	0x607e, 0x6080, 0xa005, 0x6182, 0x0040, 0x1a39, 0x2d02, 0x0078,
-	0x1a3a, 0x6186, 0x0c7f, 0x007c, 0x1078, 0x1a4d, 0x0040, 0x1a4c,
-	0x0c7e, 0x609c, 0xa065, 0x0040, 0x1a47, 0x1078, 0x18f6, 0x0c7f,
-	0x609f, 0x0000, 0x1078, 0x1896, 0x007c, 0x7884, 0xa065, 0x0040,
-	0x1a5f, 0x2091, 0x8000, 0x787c, 0x8001, 0x787e, 0x2c04, 0x7886,
-	0xa005, 0x00c0, 0x1a5d, 0x7882, 0x8000, 0x2091, 0x8001, 0x007c,
-	0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x00c8, 0x1a69,
-	0xa200, 0x0070, 0x1a6d, 0x0078, 0x1a64, 0x8086, 0x818e, 0x007c,
-	0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x1a93, 0xa11a, 0x00c8,
-	0x1a93, 0x8213, 0x818d, 0x0048, 0x1a84, 0xa11a, 0x00c8, 0x1a85,
-	0x0070, 0x1a8b, 0x0078, 0x1a79, 0xa11a, 0x2308, 0x8210, 0x0070,
-	0x1a8b, 0x0078, 0x1a79, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080,
-	0x007f, 0x157f, 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078,
-	0x1a8f, 0x798c, 0x70d0, 0x007e, 0x007f, 0xa106, 0x0040, 0x1ae9,
-	0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x1ae9,
-	0x7008, 0x7208, 0xa206, 0x00c0, 0x1ae9, 0xa286, 0x0008, 0x00c0,
-	0x1ae9, 0x2071, 0x0010, 0x1078, 0x188d, 0x0040, 0x1ae9, 0x7a94,
-	0x7b90, 0x7c9c, 0x7d98, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399,
-	0x0000, 0x2009, 0x0040, 0x1078, 0x1857, 0x2091, 0x8001, 0x0040,
-	0x1ae0, 0x1078, 0x1896, 0x78a0, 0x8000, 0x78a2, 0xa086, 0x0002,
-	0x00c0, 0x1ae9, 0x2091, 0x8000, 0x78d7, 0x0002, 0x78a3, 0x0000,
-	0x78c0, 0xa085, 0x0003, 0x78c2, 0x2091, 0x8001, 0x0078, 0x1ae9,
-	0x78a3, 0x0000, 0x1078, 0x1c38, 0x6004, 0xa084, 0x000f, 0x0079,
-	0x1aee, 0x2071, 0x0010, 0x2091, 0x8001, 0x007c, 0x1afe, 0x1b20,
-	0x1b46, 0x1afe, 0x1b58, 0x1b0d, 0x1afe, 0x1afe, 0x1afe, 0x1b1a,
-	0x1b40, 0x1afe, 0x1afe, 0x1afe, 0x1afe, 0x1afe, 0x2039, 0x0400,
-	0x78d0, 0xa705, 0x78d2, 0x6008, 0xa705, 0x600a, 0x1078, 0x1b96,
-	0x609c, 0x78ce, 0x1078, 0x1c20, 0x007c, 0x78d0, 0xa084, 0x0100,
-	0x0040, 0x1b14, 0x0078, 0x1afe, 0x601c, 0xa085, 0x0080, 0x601e,
-	0x0078, 0x1b27, 0x1078, 0x1a04, 0x00c0, 0x1afe, 0x1078, 0x1c52,
-	0x78d0, 0xa084, 0x0100, 0x0040, 0x1b27, 0x0078, 0x1afe, 0x78d3,
-	0x0000, 0x6004, 0x8007, 0xa084, 0x00ff, 0x78c6, 0x8001, 0x609f,
-	0x0000, 0x0040, 0x1b3d, 0x1078, 0x1b96, 0x0040, 0x1b3d, 0x78d0,
-	0xa085, 0x0100, 0x78d2, 0x0078, 0x1b3f, 0x1078, 0x1bba, 0x007c,
-	0x1078, 0x1a04, 0x00c0, 0x1afe, 0x1078, 0x1c4e, 0x78d0, 0xa08c,
-	0x0e00, 0x00c0, 0x1b4f, 0xa084, 0x0100, 0x00c0, 0x1b51, 0x0078,
-	0x1afe, 0x1078, 0x1b96, 0x00c0, 0x1b57, 0x1078, 0x1bba, 0x007c,
-	0x78d0, 0xa084, 0x0100, 0x0040, 0x1b5f, 0x0078, 0x1afe, 0x78d3,
-	0x0000, 0x6714, 0x20a9, 0x0001, 0x6018, 0xa005, 0x0040, 0x1b7a,
-	0xa7bc, 0xff00, 0x20a9, 0x0008, 0xa08e, 0x0001, 0x0040, 0x1b7a,
-	0x2039, 0x0000, 0x20a9, 0x0080, 0xa08e, 0x0002, 0x0040, 0x1b7a,
-	0x0078, 0x1b93, 0x1078, 0x18b4, 0x2d00, 0xa088, 0x0002, 0x2091,
-	0x8000, 0x2168, 0x682b, 0x0000, 0x682f, 0x0000, 0x2104, 0xa084,
-	0xffde, 0x200a, 0x2100, 0xa088, 0x0010, 0x2091, 0x8001, 0x0070,
-	0x1b93, 0x0078, 0x1b7f, 0x1078, 0x1896, 0x007c, 0x78c8, 0xa06d,
-	0x00c0, 0x1ba1, 0x2c00, 0x78ca, 0x78ce, 0x609f, 0x0000, 0x0078,
-	0x1bad, 0x2c00, 0x689e, 0x609f, 0x0000, 0x78ca, 0x2d00, 0x6002,
-	0x78cc, 0xad06, 0x00c0, 0x1bad, 0x6002, 0x78c4, 0x8001, 0x78c6,
-	0x00c0, 0x1bb9, 0x78d0, 0xa084, 0x0000, 0x78d2, 0x78cc, 0x2060,
-	0xa006, 0x007c, 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184, 0xc1ff,
-	0x601e, 0xa184, 0x0060, 0x0040, 0x1bc9, 0x0e7e, 0x1078, 0x330a,
-	0x0e7f, 0x6596, 0x669a, 0x6714, 0x1078, 0x18b4, 0x2091, 0x8000,
-	0x6808, 0xa084, 0x0001, 0x0040, 0x1be5, 0x2091, 0x8001, 0x1078,
-	0x1903, 0x2091, 0x8000, 0x1078, 0x1a14, 0x2091, 0x8001, 0x78cb,
-	0x0000, 0x78cf, 0x0000, 0x0078, 0x1c1f, 0x6024, 0xa096, 0x0001,
-	0x00c0, 0x1bec, 0x8000, 0x6026, 0x6a10, 0x6814, 0x2091, 0x8001,
-	0xa202, 0x0048, 0x1bfb, 0x0040, 0x1bfb, 0x2039, 0x0200, 0x1078,
-	0x1c20, 0x0078, 0x1c1f, 0x2c08, 0x2091, 0x8000, 0x6800, 0xa065,
-	0x0040, 0x1c03, 0x6102, 0x6902, 0x00c0, 0x1c07, 0x6906, 0x2160,
-	0x6003, 0x0000, 0x6810, 0x8000, 0x6812, 0x2091, 0x8001, 0x6808,
-	0xa08c, 0x0040, 0x0040, 0x1c19, 0xa086, 0x0040, 0x680a, 0x1078,
-	0x1912, 0x1078, 0x1cf6, 0x78cf, 0x0000, 0x78cb, 0x0000, 0x007c,
-	0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x1a14, 0x2091,
-	0x8001, 0x78cc, 0xa065, 0x0040, 0x1c33, 0x609c, 0x78ce, 0x609f,
-	0x0000, 0x0078, 0x1c23, 0x78cb, 0x0000, 0x78cf, 0x0000, 0x007c,
-	0x7988, 0x788c, 0x8000, 0xa10a, 0x00c8, 0x1c3f, 0xa006, 0x788e,
-	0x70d2, 0x7804, 0xa005, 0x0040, 0x1c4d, 0x8001, 0x7806, 0x00c0,
-	0x1c4d, 0x0068, 0x1c4d, 0x2091, 0x4080, 0x007c, 0x2039, 0x1c66,
-	0x0078, 0x1c54, 0x2039, 0x1c6c, 0x2704, 0xa005, 0x0040, 0x1c65,
-	0xac00, 0x2068, 0x6b08, 0x6c0c, 0x6910, 0x6a14, 0x690a, 0x6a0e,
-	0x6b12, 0x6c16, 0x8738, 0x0078, 0x1c54, 0x007c, 0x0003, 0x0009,
-	0x000f, 0x0015, 0x001b, 0x0000, 0x0015, 0x001b, 0x0000, 0x0068,
-	0x1c87, 0x2029, 0x0000, 0x7884, 0xa065, 0x0040, 0x1c82, 0x1078,
-	0x1c88, 0x0040, 0x1c82, 0x1078, 0x1c99, 0x00c0, 0x1c82, 0x8528,
-	0x0078, 0x1c73, 0x85ff, 0x0040, 0x1c87, 0x2091, 0x4080, 0x007c,
-	0x7ba4, 0x79a8, 0x70d4, 0x007e, 0x007f, 0xa102, 0x00c0, 0x1c93,
-	0x2300, 0xa005, 0x007c, 0x0048, 0x1c97, 0xa302, 0x007c, 0x8002,
-	0x007c, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0,
-	0x1cdd, 0x7008, 0x7208, 0xa206, 0x00c0, 0x1cdd, 0xa286, 0x0008,
-	0x00c0, 0x1cdd, 0x2071, 0x0010, 0x1078, 0x1ce2, 0x2009, 0x001c,
-	0x6028, 0xa005, 0x0040, 0x1cb6, 0x2009, 0x0040, 0x1078, 0x181d,
-	0x0040, 0x1ccf, 0x78bc, 0x8000, 0x78be, 0xa086, 0x0002, 0x00c0,
-	0x1cdd, 0x2091, 0x8000, 0x78d7, 0x0003, 0x78bf, 0x0000, 0x78c0,
-	0xa085, 0x0300, 0x78c2, 0x2091, 0x8001, 0x0078, 0x1cdd, 0x78bf,
-	0x0000, 0x1078, 0x1a3c, 0x79a4, 0x78a8, 0x8000, 0xa10a, 0x00c8,
-	0x1cda, 0xa006, 0x78aa, 0x70d6, 0xa006, 0x2071, 0x0010, 0x2091,
-	0x8001, 0x007c, 0x8107, 0x8004, 0x8004, 0x7ab0, 0x7bac, 0x7cb8,
-	0x7db4, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
-	0x007c, 0x2009, 0x3968, 0x2091, 0x8000, 0x200a, 0x0f7e, 0x2079,
-	0x0100, 0x2009, 0x3940, 0x2091, 0x8000, 0x2104, 0xa086, 0x0000,
-	0x00c0, 0x1d11, 0x2009, 0x3912, 0x2104, 0xa005, 0x00c0, 0x1d11,
-	0x7830, 0xa084, 0x00c0, 0x00c0, 0x1d11, 0x0018, 0x1d11, 0x781b,
-	0x0045, 0x2091, 0x8001, 0x0f7f, 0x007c, 0x127e, 0x2091, 0x2300,
-	0x2071, 0x3940, 0x2079, 0x0100, 0x784b, 0x000f, 0x2019, 0x3205,
-	0x20a1, 0x012b, 0x2304, 0xa005, 0x0040, 0x1d2f, 0x789a, 0x8318,
-	0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318, 0x0078, 0x1d22, 0x789b,
-	0x0020, 0x20a9, 0x0010, 0x78af, 0x0000, 0x78af, 0x0020, 0x0070,
-	0x1d3b, 0x0078, 0x1d33, 0x7003, 0x0000, 0x1078, 0x1e40, 0x7004,
-	0xa084, 0x000f, 0xa085, 0x6280, 0x7806, 0x780f, 0x9200, 0x7843,
-	0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x7047, 0x397f, 0x7043,
-	0x0000, 0x127f, 0x2000, 0x007c, 0xa18c, 0x000f, 0x2011, 0x0101,
-	0x2204, 0xa084, 0xfff0, 0xa105, 0x2012, 0x1078, 0x1e40, 0x007c,
-	0x2011, 0x0101, 0x20a9, 0x0009, 0x810b, 0x0070, 0x1d69, 0x0078,
-	0x1d64, 0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012,
-	0x007c, 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x0070, 0x1d7a,
-	0x0078, 0x1d75, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205,
-	0x200a, 0x007c, 0x2011, 0x0101, 0x20a9, 0x000c, 0x810b, 0x0070,
-	0x1d8b, 0x0078, 0x1d86, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff,
-	0xa105, 0x2012, 0x007c, 0x2011, 0x0102, 0x2204, 0xa084, 0xffcf,
-	0xa105, 0x2012, 0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e,
-	0x2061, 0x0100, 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x8103,
-	0x8003, 0xa080, 0x0022, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4,
-	0xa084, 0xffdf, 0x60ae, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080,
-	0x0022, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0xa085, 0x0020,
-	0x60ae, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e,
-	0x2061, 0x0100, 0x609a, 0x60a4, 0x62ae, 0x2010, 0x60a4, 0x63ae,
-	0x2018, 0x0c7f, 0x007c, 0x0c7e, 0x0e7e, 0x6818, 0xa005, 0x0040,
-	0x1e1c, 0x2061, 0x4380, 0x1078, 0x1e22, 0x0040, 0x1e06, 0x20a9,
-	0x0000, 0x2061, 0x4280, 0x0c7e, 0x1078, 0x1e22, 0x0040, 0x1df0,
-	0x0c7f, 0x8c60, 0x0070, 0x1dee, 0x0078, 0x1de3, 0x0078, 0x1e1c,
-	0x007f, 0xa082, 0x4280, 0x2071, 0x3940, 0x70ba, 0x6020, 0xa085,
-	0x0800, 0x6022, 0x2091, 0x8001, 0x71b6, 0x2001, 0x0004, 0x70a2,
-	0x70c7, 0x000f, 0x1078, 0x1cf1, 0x0078, 0x1e18, 0x2071, 0x3940,
-	0x6020, 0xa085, 0x0800, 0x6022, 0x2091, 0x8001, 0x71b6, 0x2c00,
-	0x70be, 0x2001, 0x0006, 0x70a2, 0x70c7, 0x000f, 0x1078, 0x1cf1,
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 07'
echo 'File patch-2.2.7 is continued in part 08'
echo 08 > _shar_seq_.tmp
#!/bin/sh
# this is part 08 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 08; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
-	0x2001, 0x0000, 0x0078, 0x1e1e, 0x2001, 0x0001, 0xa005, 0x0e7f,
-	0x0c7f, 0x007c, 0x2091, 0x8000, 0x2c04, 0xa005, 0x0040, 0x1e3b,
-	0x2060, 0x6010, 0xa306, 0x00c0, 0x1e38, 0x600c, 0xa206, 0x00c0,
-	0x1e38, 0x6014, 0xa106, 0x00c0, 0x1e38, 0xa006, 0x0078, 0x1e3f,
-	0x6000, 0x0078, 0x1e25, 0xa085, 0x0001, 0x2091, 0x8001, 0x007c,
-	0x2011, 0x3941, 0x220c, 0xa18c, 0x000f, 0x2011, 0x013b, 0x2204,
-	0xa084, 0x0100, 0x0040, 0x1e56, 0x2021, 0xff04, 0x2122, 0x810b,
-	0x810b, 0x810b, 0x810b, 0xa18d, 0x0f00, 0x2104, 0x007c, 0x0e7e,
-	0x68e4, 0xa08c, 0x0020, 0x0040, 0x1eaa, 0xa084, 0x0006, 0x00c0,
-	0x1eaa, 0x6014, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-	0xa0f0, 0x3a00, 0x7004, 0xa084, 0x000a, 0x00c0, 0x1eaa, 0x7108,
-	0xa194, 0xff00, 0x0040, 0x1eaa, 0xa18c, 0x00ff, 0x2001, 0x000c,
-	0xa106, 0x0040, 0x1e91, 0x2001, 0x0012, 0xa106, 0x0040, 0x1e95,
-	0x2001, 0x0014, 0xa106, 0x0040, 0x1e99, 0x2001, 0x0019, 0xa106,
-	0x0040, 0x1e9d, 0x2001, 0x0032, 0xa106, 0x0040, 0x1ea1, 0x0078,
-	0x1ea5, 0x2009, 0x0012, 0x0078, 0x1ea7, 0x2009, 0x0014, 0x0078,
-	0x1ea7, 0x2009, 0x0019, 0x0078, 0x1ea7, 0x2009, 0x0020, 0x0078,
-	0x1ea7, 0x2009, 0x003f, 0x0078, 0x1ea7, 0x2011, 0x0000, 0x2100,
-	0xa205, 0x700a, 0x0e7f, 0x007c, 0x2071, 0x0010, 0x70ca, 0x007f,
-	0x70c6, 0x70c3, 0x8002, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091,
-	0x4080, 0x0078, 0x1eb9, 0x107e, 0x007e, 0x127e, 0x2091, 0x2300,
-	0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x2009, 0x3974, 0x78a0, 0x200a,
-	0x8108, 0x250a, 0x8108, 0x240a, 0x8108, 0x260a, 0x8108, 0x270a,
-	0xa594, 0x003f, 0xa484, 0x4000, 0x0040, 0x1edc, 0xa784, 0x007c,
-	0x00c0, 0x318f, 0x1078, 0x1eac, 0xa49c, 0x000f, 0xa382, 0x0004,
-	0x0050, 0x1ee4, 0x1078, 0x1eac, 0x8507, 0xa084, 0x000f, 0x0079,
-	0x1ee9, 0x236e, 0x240d, 0x242e, 0x2699, 0x28dd, 0x293b, 0x2984,
-	0x29f0, 0x2a8d, 0x2b1a, 0x1f11, 0x1ef9, 0x21c3, 0x2288, 0x28bc,
-	0x1ef9, 0x1078, 0x1eac, 0x0018, 0x1ec0, 0x127f, 0x2091, 0x8001,
-	0x007f, 0x107f, 0x007c, 0x7003, 0x0000, 0x703f, 0x0000, 0x7030,
-	0xa005, 0x0040, 0x1f0d, 0x7033, 0x0000, 0x1078, 0x316a, 0x0018,
-	0x1ec0, 0x2009, 0x390f, 0x200b, 0x0000, 0x705c, 0xa005, 0x00c0,
-	0x1fe2, 0x70a0, 0xa084, 0x0007, 0x0079, 0x1f1e, 0x2005, 0x1f26,
-	0x1f34, 0x1f51, 0x1f73, 0x1fc0, 0x1f99, 0x1f26, 0x7808, 0xa084,
-	0xfffd, 0x780a, 0x2009, 0x0047, 0x1078, 0x27c1, 0x00c0, 0x1f32,
-	0x7003, 0x0004, 0x0078, 0x1efb, 0x1078, 0x3151, 0x00c0, 0x1f4f,
-	0x70b4, 0x8007, 0x7882, 0x789b, 0x0010, 0x78ab, 0x000c, 0x789b,
-	0x0060, 0x78ab, 0x0001, 0x785b, 0x0004, 0x2009, 0x00fb, 0x1078,
-	0x27bf, 0x00c0, 0x1f4f, 0x7003, 0x0004, 0x70c7, 0x000f, 0x0078,
-	0x1efb, 0x1078, 0x3151, 0x00c0, 0x1f71, 0x71b4, 0x8107, 0x7882,
-	0x789b, 0x0010, 0xa18c, 0x0007, 0xa18d, 0x00c0, 0x79aa, 0x78ab,
-	0x0006, 0x789b, 0x0060, 0x78ab, 0x0002, 0x785b, 0x0004, 0x2009,
-	0x00fb, 0x1078, 0x27bf, 0x00c0, 0x1f71, 0x7003, 0x0004, 0x70c7,
-	0x000f, 0x0078, 0x1efb, 0x1078, 0x3151, 0x00c0, 0x1f97, 0x71b4,
-	0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x0007, 0xa18d, 0x00c0,
-	0x79aa, 0x78ab, 0x0020, 0x71b8, 0x79aa, 0x78ab, 0x000d, 0x789b,
-	0x0060, 0x78ab, 0x0004, 0x785b, 0x0004, 0x2009, 0x00fb, 0x1078,
-	0x27bf, 0x00c0, 0x1f97, 0x7003, 0x0004, 0x70c7, 0x000f, 0x0078,
-	0x1efb, 0x1078, 0x3151, 0x00c0, 0x1fbe, 0x71b4, 0x8107, 0x7882,
-	0x789b, 0x0010, 0xa18c, 0x0007, 0xa18d, 0x00c0, 0x79aa, 0x78ab,
-	0x0006, 0x789b, 0x0060, 0x78ab, 0x0002, 0x785b, 0x0004, 0x2009,
-	0x00fb, 0x1078, 0x27bf, 0x00c0, 0x1fbe, 0x70bc, 0x70bf, 0x0000,
-	0x2068, 0x703e, 0x7003, 0x0002, 0x70c7, 0x000f, 0x0078, 0x1efb,
-	0x1078, 0x3151, 0x00c0, 0x1efb, 0x70bc, 0x2068, 0x1078, 0x31f3,
-	0x789b, 0x0010, 0x6814, 0xa084, 0x0007, 0xa085, 0x0080, 0x007e,
-	0x007f, 0x78aa, 0x6e1c, 0x067e, 0x067f, 0x2041, 0x0001, 0x70c0,
-	0xa084, 0x0400, 0x2001, 0x0004, 0x0040, 0x1fe0, 0x2001, 0x0006,
-	0x0078, 0x20e1, 0x1078, 0x3151, 0x00c0, 0x1efb, 0x789b, 0x0010,
-	0x705c, 0x2068, 0x1078, 0x31f3, 0x6f14, 0x1078, 0x3099, 0x6008,
-	0xa085, 0x0010, 0x600a, 0xad80, 0x0009, 0x2003, 0x0005, 0x6814,
-	0xa084, 0x0007, 0xa085, 0x0080, 0x78aa, 0x2031, 0x0020, 0x2041,
-	0x0001, 0x2001, 0x0003, 0x0078, 0x20e1, 0x0018, 0x1ec0, 0x7440,
-	0xa485, 0x0000, 0x0040, 0x201f, 0xa080, 0x3980, 0x2030, 0x7144,
-	0x8108, 0xa12a, 0x0048, 0x2016, 0x2009, 0x3980, 0x2164, 0x6504,
-	0x85ff, 0x00c0, 0x202c, 0x8421, 0x00c0, 0x2010, 0x7146, 0x7003,
-	0x0000, 0x703f, 0x0000, 0x0078, 0x1efb, 0x7640, 0xa6b0, 0x3980,
-	0x7144, 0x2600, 0x0078, 0x201b, 0x7146, 0x2568, 0x2558, 0x753e,
-	0x2c50, 0x6708, 0x7736, 0xa784, 0x013f, 0x0040, 0x2059, 0xa784,
-	0x0021, 0x00c0, 0x2029, 0xa784, 0x0002, 0x0040, 0x2046, 0xa784,
-	0x0004, 0x0040, 0x2029, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0008,
-	0x00c0, 0x2029, 0xa784, 0x0010, 0x00c0, 0x2029, 0xa784, 0x0100,
-	0x0040, 0x2059, 0x6018, 0xa005, 0x00c0, 0x2029, 0xa7bc, 0xfeff,
-	0x670a, 0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e, 0x6118, 0x0040,
-	0x2069, 0x601c, 0xa102, 0x0048, 0x206c, 0x0040, 0x206c, 0x0078,
-	0x2025, 0x81ff, 0x00c0, 0x2025, 0xa784, 0x0080, 0x00c0, 0x2072,
-	0x700c, 0x6022, 0x1078, 0x31f3, 0x0018, 0x1ec0, 0x789b, 0x0010,
-	0xa046, 0x1078, 0x3151, 0x00c0, 0x1efb, 0x6b14, 0xa39c, 0x0007,
-	0xa39d, 0x00c0, 0x704c, 0xa084, 0x8000, 0x0040, 0x208b, 0xa684,
-	0x0001, 0x0040, 0x208d, 0xa39c, 0xffbf, 0xa684, 0x0010, 0x0040,
-	0x2093, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684, 0x000e, 0x00c0,
-	0x209e, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x20df, 0x714c, 0xa18c,
-	0x0800, 0x0040, 0x2cfc, 0x2011, 0x0021, 0x8004, 0x8004, 0x0048,
-	0x20b5, 0x2011, 0x0022, 0x8004, 0x0048, 0x20b5, 0x2011, 0x0020,
-	0x8004, 0x0048, 0x20b5, 0x0040, 0x20df, 0x7aaa, 0x8840, 0x1078,
-	0x316a, 0x6a14, 0x610c, 0x8108, 0xa18c, 0x00ff, 0xa1e0, 0x4280,
-	0x2c64, 0x8cff, 0x0040, 0x20d6, 0x6014, 0xa206, 0x00c0, 0x20c0,
-	0x60b8, 0x8001, 0x60ba, 0x00c0, 0x20bb, 0x0c7e, 0x2a60, 0x6008,
-	0xa085, 0x0100, 0x600a, 0x0c7f, 0x0078, 0x2005, 0x1078, 0x3151,
-	0x00c0, 0x1efb, 0x2a60, 0x610e, 0x79aa, 0x8840, 0x712e, 0x2001,
-	0x0001, 0x007e, 0x7150, 0xa184, 0x0018, 0x0040, 0x20fc, 0xa184,
-	0x0010, 0x0040, 0x20ef, 0x1078, 0x2ee3, 0x00c0, 0x211f, 0xa184,
-	0x0008, 0x0040, 0x20fc, 0x69a0, 0xa184, 0x0600, 0x00c0, 0x20fc,
-	0x1078, 0x2ddf, 0x0078, 0x211f, 0x69a0, 0xa184, 0x0800, 0x0040,
-	0x2113, 0x0c7e, 0x027e, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002,
-	0x6104, 0xa18d, 0x0010, 0x6106, 0x027f, 0x0c7f, 0x1078, 0x2ee3,
-	0x00c0, 0x211f, 0x69a0, 0xa184, 0x0200, 0x0040, 0x211b, 0x1078,
-	0x2e2e, 0x0078, 0x211f, 0xa184, 0x0400, 0x00c0, 0x20f8, 0x69a0,
-	0xa184, 0x1000, 0x0040, 0x212a, 0x6914, 0xa18c, 0xff00, 0x810f,
-	0x1078, 0x1da7, 0x007f, 0x7002, 0xa68c, 0x00e0, 0xa684, 0x0060,
-	0x0040, 0x2138, 0xa086, 0x0060, 0x00c0, 0x2138, 0xa18d, 0x4000,
-	0x88ff, 0x0040, 0x213d, 0xa18d, 0x0004, 0x795a, 0x69b6, 0x789b,
-	0x0060, 0x2800, 0x78aa, 0x789b, 0x0061, 0x6818, 0xa08d, 0x8000,
-	0xa084, 0x7fff, 0x691a, 0xa68c, 0x0080, 0x0040, 0x215c, 0x70cb,
-	0x0000, 0xa08a, 0x000d, 0x0050, 0x215a, 0xa08a, 0x000c, 0x71ca,
-	0x2001, 0x000c, 0x800c, 0x71ce, 0x78aa, 0x8008, 0x810c, 0x0040,
-	0x2d07, 0xa18c, 0x00f8, 0x00c0, 0x2d07, 0x157e, 0x137e, 0x147e,
-	0x20a1, 0x012b, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b,
-	0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6814, 0x8007, 0x7882,
-	0x6d94, 0x7dd6, 0x7dde, 0x6e98, 0x7ed2, 0x7eda, 0x7830, 0xa084,
-	0x00c0, 0x00c0, 0x2185, 0x0098, 0x218d, 0x6008, 0xa084, 0xffef,
-	0x600a, 0x1078, 0x316a, 0x0078, 0x1f03, 0x7200, 0xa284, 0x0007,
-	0xa086, 0x0001, 0x00c0, 0x219a, 0x781b, 0x004a, 0x1078, 0x316a,
-	0x0078, 0x21ab, 0x6ab4, 0xa295, 0x2000, 0x7a5a, 0x781b, 0x004a,
-	0x1078, 0x316a, 0x7200, 0x2500, 0xa605, 0x0040, 0x21ab, 0xa284,
-	0x0007, 0x1079, 0x21b9, 0xa284, 0x0007, 0xa086, 0x0001, 0x00c0,
-	0x1efb, 0x6018, 0x8000, 0x601a, 0xad80, 0x0009, 0x7032, 0x0078,
-	0x1efb, 0x21c1, 0x3571, 0x3571, 0x3560, 0x3571, 0x21c1, 0x3560,
-	0x21c1, 0x1078, 0x1eac, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0f7e,
-	0x2079, 0x3900, 0x78c0, 0x0f7f, 0xa084, 0x0001, 0x0040, 0x21e9,
-	0x70a0, 0xa086, 0x0001, 0x00c0, 0x21d8, 0x70a2, 0x0078, 0x226c,
-	0x70a0, 0xa086, 0x0005, 0x00c0, 0x21e7, 0x70bc, 0x2068, 0x681b,
-	0x0004, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x70a3,
-	0x0000, 0x157e, 0x2011, 0x0004, 0x71a0, 0xa186, 0x0001, 0x0040,
-	0x2207, 0xa186, 0x0007, 0x00c0, 0x21fb, 0x2009, 0x3935, 0x200b,
-	0x0005, 0x0078, 0x2207, 0x2009, 0x3913, 0x2104, 0x2009, 0x3912,
-	0x200a, 0x2009, 0x3935, 0x200b, 0x0001, 0x0078, 0x2209, 0x70a3,
-	0x0000, 0x1078, 0x32f5, 0x20a9, 0x0010, 0x2039, 0x0000, 0x1078,
-	0x2f9a, 0xa7b8, 0x0100, 0x0070, 0x2217, 0x0078, 0x220f, 0x7000,
-	0x0079, 0x221a, 0x2248, 0x2231, 0x2231, 0x2224, 0x2248, 0x2248,
-	0x2248, 0x2222, 0x1078, 0x1eac, 0x2021, 0x3957, 0x2404, 0xa005,
-	0x0040, 0x2248, 0xad06, 0x00c0, 0x2231, 0x6800, 0x2022, 0x0078,
-	0x2241, 0x6820, 0xa084, 0x0001, 0x00c0, 0x223d, 0x6f14, 0x1078,
-	0x3099, 0x1078, 0x2cc9, 0x0078, 0x2241, 0x7054, 0x2060, 0x6800,
-	0x6002, 0x6a1a, 0x6820, 0xa085, 0x0008, 0x6822, 0x1078, 0x1a26,
-	0x2021, 0x4380, 0x1078, 0x2272, 0x2021, 0x3957, 0x1078, 0x2272,
-	0x20a9, 0x0000, 0x2021, 0x4280, 0x1078, 0x2272, 0x8420, 0x0070,
-	0x225b, 0x0078, 0x2254, 0x20a9, 0x0080, 0x2061, 0x3a80, 0x6018,
-	0x6110, 0xa102, 0x6012, 0x601b, 0x0000, 0xace0, 0x0010, 0x0070,
-	0x226b, 0x0078, 0x225f, 0x157f, 0x7003, 0x0000, 0x703f, 0x0000,
-	0x0078, 0x1efb, 0x047e, 0x2404, 0xa005, 0x0040, 0x2284, 0x2068,
-	0x6800, 0x007e, 0x6a1a, 0x6820, 0xa085, 0x0008, 0x6822, 0x1078,
-	0x1a26, 0x007f, 0x0078, 0x2274, 0x047f, 0x2023, 0x0000, 0x007c,
-	0xa282, 0x0003, 0x0050, 0x228e, 0x1078, 0x1eac, 0x2300, 0x0079,
-	0x2291, 0x2294, 0x2311, 0x232e, 0xa282, 0x0002, 0x0040, 0x229a,
-	0x1078, 0x1eac, 0x70a0, 0x70a3, 0x0000, 0x70c7, 0x0000, 0x0079,
-	0x22a1, 0x22a9, 0x22a9, 0x22ab, 0x22e9, 0x2d0d, 0x22a9, 0x22e9,
-	0x22a9, 0x1078, 0x1eac, 0x77b4, 0x1078, 0x2f9a, 0x77b4, 0xa7bc,
-	0x0f00, 0x1078, 0x3099, 0x6018, 0xa005, 0x0040, 0x22e0, 0x2021,
-	0x4380, 0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x2349, 0x0040,
-	0x22e0, 0x157e, 0x20a9, 0x0000, 0x2021, 0x4280, 0x047e, 0x2009,
-	0x0004, 0x2011, 0x0010, 0x1078, 0x2349, 0x047f, 0x0040, 0x22d5,
-	0x8420, 0x0070, 0x22d5, 0x0078, 0x22c6, 0x157f, 0x2021, 0x3957,
-	0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x2349, 0x0040, 0x22e0,
-	0x8738, 0xa784, 0x0007, 0x00c0, 0x22b1, 0x0078, 0x1f03, 0x0078,
-	0x1f03, 0x77b4, 0x1078, 0x3099, 0x6018, 0xa005, 0x0040, 0x230f,
-	0x2021, 0x4380, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x2349,
-	0x0040, 0x230f, 0x157e, 0x20a9, 0x0000, 0x2021, 0x4280, 0x047e,
-	0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x2349, 0x047f, 0x0040,
-	0x230e, 0x8420, 0x0070, 0x230e, 0x0078, 0x22ff, 0x157f, 0x0078,
-	0x1f03, 0x2200, 0x0079, 0x2314, 0x2317, 0x2319, 0x2319, 0x1078,
-	0x1eac, 0x2009, 0x0012, 0x70a0, 0xa086, 0x0002, 0x0040, 0x2322,
-	0x2009, 0x000e, 0x6818, 0xa084, 0x8000, 0x0040, 0x2328, 0x691a,
-	0x70a3, 0x0000, 0x70a7, 0x0001, 0x0078, 0x311c, 0x2200, 0x0079,
-	0x2331, 0x2336, 0x2319, 0x2334, 0x1078, 0x1eac, 0x1078, 0x27ce,
-	0x7000, 0xa086, 0x0001, 0x00c0, 0x2c9f, 0x1078, 0x2cdf, 0x6008,
-	0xa084, 0xffef, 0x600a, 0x1078, 0x2c92, 0x0040, 0x2c9f, 0x0078,
-	0x2005, 0x2404, 0xa005, 0x0040, 0x236a, 0x2068, 0x2d04, 0x007e,
-	0x6814, 0xa706, 0x0040, 0x2358, 0x2d20, 0x007f, 0x0078, 0x234a,
-	0x007f, 0x2022, 0x691a, 0x6820, 0xa205, 0x6822, 0x1078, 0x1a26,
-	0x6010, 0x8001, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078,
-	0x2cdf, 0x007c, 0xa085, 0x0001, 0x0078, 0x2369, 0x2300, 0x0079,
-	0x2371, 0x2376, 0x2374, 0x23c2, 0x1078, 0x1eac, 0x78e4, 0xa005,
-	0x00d0, 0x238a, 0x0018, 0x238a, 0xa084, 0x0007, 0x0079, 0x2380,
-	0x239b, 0x23a8, 0x238e, 0x2388, 0x3144, 0x3144, 0x2388, 0x23b5,
-	0x1078, 0x1eac, 0x2001, 0x0003, 0x0078, 0x26ad, 0x6818, 0xa084,
-	0x8000, 0x0040, 0x2395, 0x681b, 0x001d, 0x1078, 0x2f7d, 0x781b,
-	0x0053, 0x0078, 0x1efb, 0x6818, 0xa084, 0x8000, 0x0040, 0x23a2,
-	0x681b, 0x001d, 0x1078, 0x2f7d, 0x781b, 0x00de, 0x0078, 0x1efb,
-	0x6818, 0xa084, 0x8000, 0x0040, 0x23af, 0x681b, 0x001d, 0x1078,
-	0x2f7d, 0x781b, 0x00e5, 0x0078, 0x1efb, 0x6818, 0xa084, 0x8000,
-	0x0040, 0x23bc, 0x681b, 0x001d, 0x1078, 0x2f7d, 0x781b, 0x009c,
-	0x0078, 0x1efb, 0xa584, 0x000f, 0x00c0, 0x23e1, 0x1078, 0x27ce,
-	0x7000, 0x0079, 0x23cb, 0x23d3, 0x23d5, 0x23d3, 0x2c9f, 0x2c9f,
-	0x2c9f, 0x2c9f, 0x23d3, 0x1078, 0x1eac, 0x1078, 0x2cdf, 0x6008,
-	0xa084, 0xffef, 0x600a, 0x1078, 0x2c92, 0x0040, 0x2c9f, 0x0078,
-	0x2005, 0x79e4, 0xa005, 0x00d0, 0x238a, 0x0018, 0x238a, 0xa184,
-	0x0007, 0x0079, 0x23eb, 0x23fb, 0x2401, 0x23f5, 0x23f3, 0x3144,
-	0x3144, 0x23f3, 0x313c, 0x1078, 0x1eac, 0x1078, 0x2f85, 0x781b,
-	0x0053, 0x0078, 0x1efb, 0x1078, 0x2f85, 0x781b, 0x00de, 0x0078,
-	0x1efb, 0x1078, 0x2f85, 0x781b, 0x00e5, 0x0078, 0x1efb, 0x1078,
-	0x2f85, 0x781b, 0x009c, 0x0078, 0x1efb, 0x2300, 0x0079, 0x2410,
-	0x2415, 0x2413, 0x2417, 0x1078, 0x1eac, 0x0078, 0x29f0, 0x681b,
-	0x0008, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x29f0,
-	0xa184, 0x0007, 0x0079, 0x2424, 0x242c, 0x2401, 0x238e, 0x311c,
-	0x3144, 0x3144, 0x242c, 0x313c, 0x1078, 0x1eac, 0xa282, 0x0005,
-	0x0050, 0x2434, 0x1078, 0x1eac, 0x2300, 0x0079, 0x2437, 0x243a,
-	0x265e, 0x266a, 0x2200, 0x0079, 0x243d, 0x2457, 0x2444, 0x2457,
-	0x2442, 0x2643, 0x1078, 0x1eac, 0x789b, 0x0018, 0x78a8, 0xa084,
-	0x00ff, 0xa082, 0x0020, 0x0048, 0x2f69, 0xa08a, 0x0004, 0x00c8,
-	0x2f69, 0x0079, 0x2453, 0x2f69, 0x2f69, 0x2f69, 0x2f23, 0x789b,
-	0x0018, 0x79a8, 0xa184, 0x0080, 0x0040, 0x246c, 0xa184, 0x0018,
-	0x0040, 0x2468, 0x0078, 0x2f69, 0x7000, 0xa005, 0x00c0, 0x2462,
-	0x2011, 0x0004, 0x0078, 0x2b28, 0xa184, 0x00ff, 0xa08a, 0x0010,
-	0x00c8, 0x2f69, 0x0079, 0x2474, 0x2486, 0x2484, 0x249e, 0x24a2,
-	0x255a, 0x2f69, 0x2f69, 0x255c, 0x2f69, 0x2f69, 0x263f, 0x263f,
-	0x2f69, 0x2f69, 0x2f69, 0x2641, 0x1078, 0x1eac, 0xa684, 0x1000,
-	0x0040, 0x2493, 0x2001, 0x0300, 0x8000, 0x8000, 0x783a, 0x781b,
-	0x0099, 0x0078, 0x1efb, 0x6818, 0xa084, 0x8000, 0x0040, 0x249c,
-	0x681b, 0x001d, 0x0078, 0x248a, 0x0078, 0x311c, 0x681b, 0x001d,
-	0x0078, 0x2f75, 0x6920, 0xa184, 0x8000, 0x00c0, 0x24ae, 0x68af,
-	0x0000, 0x68b3, 0x0000, 0xa18d, 0x8000, 0x6922, 0xa684, 0x1800,
-	0x00c0, 0x24ed, 0x6820, 0xa084, 0x0001, 0x00c0, 0x24f3, 0x6818,
-	0xa086, 0x0008, 0x00c0, 0x24be, 0x681b, 0x0000, 0xa684, 0x0400,
-	0x0040, 0x2556, 0xa684, 0x0080, 0x0040, 0x24e9, 0x70cb, 0x0000,
-	0x6818, 0xa084, 0x003f, 0xa08a, 0x000d, 0x0050, 0x24e9, 0xa08a,
-	0x000c, 0x71ca, 0x2001, 0x000c, 0x800c, 0x71ce, 0x789b, 0x0061,
-	0x78aa, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000,
-	0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f,
-	0x157f, 0x781b, 0x0056, 0x0078, 0x1efb, 0xa684, 0x1000, 0x0040,
-	0x24f3, 0x0078, 0x1efb, 0xa684, 0x0060, 0x0040, 0x2552, 0xa684,
-	0x0800, 0x0040, 0x2552, 0xa684, 0x8000, 0x00c0, 0x2503, 0x69b0,
-	0x6aac, 0x0078, 0x251d, 0xa6b4, 0x7fff, 0x7e5a, 0x6eb6, 0x789b,
-	0x0074, 0x7aac, 0x79ac, 0x78ac, 0x801b, 0x00c8, 0x2510, 0x8000,
-	0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302,
-	0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0xa684, 0x4000, 0x0040,
-	0x2525, 0xa6b4, 0xbfff, 0x7e5a, 0x6eb6, 0xa006, 0x1078, 0x362f,
-	0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040, 0x2534,
-	0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x6ba6, 0x7bd6,
-	0x2300, 0xa405, 0x00c0, 0x2544, 0xa6b5, 0x4000, 0x7e5a, 0x6eb6,
-	0x781b, 0x0065, 0x0078, 0x1efb, 0x781b, 0x0065, 0x2200, 0xa115,
-	0x00c0, 0x254e, 0x1078, 0x3571, 0x0078, 0x1efb, 0x1078, 0x35a6,
-	0x0078, 0x1efb, 0x781b, 0x0068, 0x0078, 0x1efb, 0x781b, 0x0056,
-	0x0078, 0x1efb, 0x1078, 0x1eac, 0x0078, 0x25b1, 0x6920, 0xa184,
-	0x0100, 0x0040, 0x2570, 0xa18c, 0xfeff, 0x6922, 0x0c7e, 0x7048,
-	0x2060, 0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078, 0x25a0,
-	0xa184, 0x0200, 0x0040, 0x25a0, 0xa18c, 0xfdff, 0x6922, 0x0c7e,
-	0x7048, 0x2060, 0x6004, 0xa084, 0xffef, 0x6006, 0x2008, 0x2c48,
-	0x0c7f, 0xa184, 0x0008, 0x0040, 0x25a0, 0x1078, 0x3095, 0x1078,
-	0x2ddf, 0x88ff, 0x0040, 0x25a0, 0x789b, 0x0060, 0x2800, 0x78aa,
-	0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x259c,
-	0x781b, 0x0053, 0x0078, 0x1efb, 0x781b, 0x0067, 0x0078, 0x1efb,
-	0x7e58, 0xa684, 0x0400, 0x00c0, 0x25a9, 0x781b, 0x0056, 0x0078,
-	0x1efb, 0x781b, 0x0068, 0x0078, 0x1efb, 0x0078, 0x2f6f, 0x0078,
-	0x2f6f, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x0040, 0x25af,
-	0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0,
-	0x25d4, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x25cc,
-	0x0048, 0x25cc, 0x0078, 0x25ce, 0x0078, 0x255e, 0x24a8, 0x7aa8,
-	0x00f0, 0x25ce, 0x0078, 0x25ba, 0xa284, 0x00f0, 0xa086, 0x0020,
-	0x00c0, 0x2630, 0x8318, 0x8318, 0x2300, 0xa102, 0x0040, 0x25e4,
-	0x0048, 0x25e4, 0x0078, 0x262d, 0xa286, 0x0023, 0x0040, 0x25af,
-	0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1, 0xa085,
-	0x0010, 0x2030, 0x7e5a, 0x6008, 0xa085, 0x0010, 0x600a, 0x0c7e,
-	0x7048, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0010,
-	0x0040, 0x2608, 0x1078, 0x3095, 0x1078, 0x2ee3, 0x0078, 0x2617,
-	0x0c7e, 0x7048, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xa184,
-	0x0008, 0x0040, 0x25a0, 0x1078, 0x3095, 0x1078, 0x2ddf, 0x88ff,
-	0x0040, 0x25a0, 0x789b, 0x0060, 0x2800, 0x78aa, 0xa6b5, 0x0004,
-	0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2629, 0x781b, 0x0053, 0x0078,
-	0x1efb, 0x781b, 0x0067, 0x0078, 0x1efb, 0x7aa8, 0x0078, 0x25ba,
-	0x8318, 0x2300, 0xa102, 0x0040, 0x2639, 0x0048, 0x2639, 0x0078,
-	0x25ba, 0xa284, 0x0080, 0x00c0, 0x2f75, 0x0078, 0x2f6f, 0x0078,
-	0x2f75, 0x0078, 0x2f69, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff,
-	0xa08e, 0x0001, 0x0040, 0x264e, 0x1078, 0x1eac, 0x7aa8, 0xa294,
-	0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x2f69,
-	0x0079, 0x265a, 0x2f69, 0x2d32, 0x2f69, 0x2e7e, 0xa282, 0x0000,
-	0x00c0, 0x2664, 0x1078, 0x1eac, 0x1078, 0x2f7d, 0x781b, 0x0067,
-	0x0078, 0x1efb, 0xa282, 0x0003, 0x00c0, 0x2670, 0x1078, 0x1eac,
-	0xa484, 0x8000, 0x00c0, 0x2693, 0x70a0, 0xa005, 0x0040, 0x267a,
-	0x1078, 0x1eac, 0x6f14, 0x77b6, 0xa7bc, 0x0f00, 0x1078, 0x3099,
-	0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x0007, 0x00c0,
-	0x267e, 0x1078, 0x2f81, 0x70a3, 0x0002, 0x2009, 0x3935, 0x200b,
-	0x0009, 0x0078, 0x2695, 0x1078, 0x2f8d, 0x781b, 0x0067, 0x0078,
-	0x1efb, 0xa282, 0x0004, 0x0050, 0x269f, 0x1078, 0x1eac, 0x2300,
-	0x0079, 0x26a2, 0x26a5, 0x2781, 0x27a9, 0xa286, 0x0003, 0x0040,
-	0x26ab, 0x1078, 0x1eac, 0x2001, 0x0000, 0x703a, 0x7000, 0xa084,
-	0x0007, 0x0079, 0x26b3, 0x26bb, 0x26bd, 0x26bd, 0x2871, 0x28a2,
-	0x1f03, 0x28a2, 0x26bb, 0x1078, 0x1eac, 0xa684, 0x1000, 0x00c0,
-	0x26c5, 0x1078, 0x32f5, 0x0040, 0x275b, 0x7868, 0xa08c, 0x00ff,
-	0x0040, 0x270d, 0xa186, 0x0008, 0x00c0, 0x26dc, 0x1078, 0x2cdf,
-	0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x2c92, 0x0040, 0x270d,
-	0x1078, 0x32f5, 0x0078, 0x26f4, 0xa186, 0x0028, 0x00c0, 0x270d,
-	0x1078, 0x32f5, 0x6008, 0xa084, 0xffef, 0x600a, 0x6018, 0xa005,
-	0x0040, 0x26f4, 0x8001, 0x601a, 0xa005, 0x0040, 0x26f4, 0x8001,
-	0xa005, 0x0040, 0x26f4, 0x601e, 0x6820, 0xa084, 0x0001, 0x0040,
-	0x1f03, 0x6820, 0xa084, 0xfffe, 0x6822, 0x7054, 0x0c7e, 0x2060,
-	0x6800, 0x6002, 0x0c7f, 0x6004, 0x6802, 0xa005, 0x2d00, 0x00c0,
-	0x270a, 0x6002, 0x6006, 0x0078, 0x1f03, 0x017e, 0x1078, 0x27ce,
-	0x017f, 0xa684, 0xdf00, 0x681e, 0x682b, 0x0000, 0x6f14, 0x81ff,
-	0x0040, 0x275b, 0xa186, 0x0002, 0x00c0, 0x2753, 0xa684, 0x0800,
-	0x00c0, 0x272a, 0xa684, 0x0060, 0x0040, 0x272a, 0x78d8, 0x7adc,
-	0x682e, 0x6a32, 0x6820, 0xa084, 0x0800, 0x00c0, 0x275b, 0x8717,
-	0xa294, 0x000f, 0x8213, 0x8213, 0x8213, 0xa290, 0x3a00, 0xa290,
-	0x0000, 0x221c, 0x8210, 0x2204, 0xa085, 0x0018, 0x2012, 0x8211,
-	0xa384, 0x0400, 0x0040, 0x274d, 0x68a0, 0xa084, 0x0100, 0x00c0,
-	0x274d, 0x1078, 0x2830, 0x0078, 0x1f03, 0x6008, 0xa085, 0x0002,
-	0x600a, 0x0078, 0x275b, 0xa186, 0x0018, 0x0040, 0x275b, 0xa186,
-	0x0014, 0x0040, 0x1f03, 0x6916, 0x6818, 0xa084, 0x8000, 0x0040,
-	0x2763, 0x7038, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x1078, 0x2cd0,
-	0x1078, 0x2cdf, 0x00c0, 0x2770, 0x6008, 0xa084, 0xffef, 0x600a,
-	0x6820, 0xa084, 0x0001, 0x00c0, 0x2779, 0x1078, 0x2cc9, 0x0078,
-	0x277d, 0x7054, 0x2060, 0x6800, 0x6002, 0x1078, 0x1a26, 0x0078,
-	0x1f03, 0xa282, 0x0004, 0x0048, 0x2787, 0x1078, 0x1eac, 0x2200,
-	0x0079, 0x278a, 0x2785, 0x278e, 0x2794, 0x278e, 0x1078, 0x2f7d,
-	0x781b, 0x0067, 0x0078, 0x1efb, 0x7890, 0x8007, 0x8001, 0xa084,
-	0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186,
-	0x0003, 0x0040, 0x27a5, 0x0078, 0x2f69, 0x781b, 0x0068, 0x0078,
-	0x1efb, 0x6820, 0xa085, 0x0004, 0x6822, 0x82ff, 0x00c0, 0x27b4,
-	0x1078, 0x2f7d, 0x0078, 0x27bb, 0x8211, 0x0040, 0x27b9, 0x1078,
-	0x1eac, 0x1078, 0x2f8d, 0x781b, 0x0067, 0x0078, 0x1efb, 0x1078,
-	0x316a, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x27cb, 0x0018, 0x27cb,
-	0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684, 0x0060,
-	0x00c0, 0x27d8, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x282f,
-	0xa684, 0x0800, 0x00c0, 0x27e8, 0x6998, 0x6a94, 0x692e, 0x6a32,
-	0x7000, 0xa086, 0x0006, 0x0040, 0x27e7, 0x1078, 0x32f5, 0x007c,
-	0xa684, 0x0020, 0x0040, 0x2802, 0xa684, 0x4000, 0x0040, 0x27f6,
-	0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x27e0, 0x7038, 0xa005,
-	0x00c0, 0x27fc, 0x703b, 0x0015, 0x79d8, 0x7adc, 0x692e, 0x6a32,
-	0x0078, 0x27e0, 0xa684, 0x4000, 0x0040, 0x280c, 0x682f, 0x0000,
-	0x6833, 0x0000, 0x0078, 0x27e0, 0x7038, 0xa005, 0x00c0, 0x2812,
-	0x703b, 0x0015, 0x79d8, 0x7adc, 0x78d0, 0x80fb, 0x00c8, 0x2819,
+	0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0040, 0x1387, 0x8001, 0x78ae,
+	0xa084, 0xfc00, 0x0040, 0x137c, 0x78cc, 0xa085, 0x0100, 0x78ce,
+	0x2001, 0x4005, 0x0078, 0x1286, 0x7ab6, 0x7bba, 0x7dbe, 0x7ec2,
+	0x7cb2, 0x78cc, 0xa084, 0xfcff, 0x78ce, 0x0078, 0x138b, 0x78cc,
+	0xa085, 0x0100, 0x78ce, 0x0078, 0x1284, 0x2009, 0x5061, 0x210c,
+	0x7aec, 0x0078, 0x1282, 0x2009, 0x5041, 0x210c, 0x0078, 0x1283,
+	0x2009, 0x5042, 0x210c, 0x0078, 0x1283, 0x2061, 0x5040, 0x610c,
+	0x6210, 0x0078, 0x1282, 0x2009, 0x5045, 0x210c, 0x0078, 0x1283,
+	0x2009, 0x5046, 0x210c, 0x0078, 0x1283, 0x2009, 0x5048, 0x210c,
+	0x0078, 0x1283, 0x2009, 0x5049, 0x210c, 0x0078, 0x1283, 0x7908,
+	0x7a0c, 0x0078, 0x1282, 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003,
+	0x8003, 0x8003, 0xa0e8, 0x5280, 0x6a00, 0x6804, 0xa084, 0x0008,
+	0x0040, 0x13cd, 0x6b08, 0x0078, 0x13ce, 0x6b0c, 0x0078, 0x1281,
+	0x77c4, 0x1078, 0x1956, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091,
+	0x8001, 0x2708, 0x0078, 0x1281, 0x794c, 0x0078, 0x1283, 0x77c4,
+	0x1078, 0x1956, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x2091,
+	0x8001, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x127c,
+	0x1078, 0x22c1, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010, 0x00c8,
+	0x127c, 0x2011, 0x5041, 0x2204, 0x007e, 0x2112, 0x1078, 0x227a,
+	0x017f, 0x0078, 0x1283, 0x71c4, 0x2011, 0x1421, 0x20a9, 0x0008,
+	0x2204, 0xa106, 0x0040, 0x1413, 0x8210, 0x0070, 0x1411, 0x0078,
+	0x1408, 0x0078, 0x127c, 0xa292, 0x1421, 0x027e, 0x2011, 0x5042,
+	0x2204, 0x2112, 0x017f, 0x007e, 0x1078, 0x2286, 0x017f, 0x0078,
+	0x1283, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032,
+	0x004b, 0x2061, 0x5040, 0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8,
+	0x6012, 0x0078, 0x1282, 0x2061, 0x5040, 0x6114, 0x70c4, 0x6016,
+	0x0078, 0x1283, 0x2061, 0x5040, 0x71c4, 0x2011, 0x0004, 0x601f,
+	0x0019, 0x2019, 0x1212, 0xa186, 0x0028, 0x0040, 0x145b, 0x2011,
+	0x0005, 0x601f, 0x0019, 0x2019, 0x1212, 0xa186, 0x0032, 0x0040,
+	0x145b, 0x2011, 0x0006, 0x601f, 0x000c, 0x2019, 0x2222, 0xa186,
+	0x003c, 0x00c0, 0x127c, 0x6018, 0x007e, 0x611a, 0x7800, 0xa084,
+	0x0001, 0x00c0, 0x1476, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
+	0x0048, 0x146e, 0x0038, 0x1472, 0x0078, 0x1476, 0x0028, 0x1472,
+	0x0078, 0x1476, 0x2019, 0x2222, 0x0078, 0x1478, 0x2019, 0x1212,
+	0x23b8, 0x1078, 0x2297, 0x1078, 0x4bdf, 0x017f, 0x0078, 0x1283,
+	0x71c4, 0xa184, 0xffcf, 0x00c0, 0x127c, 0x2011, 0x5048, 0x2204,
+	0x2112, 0x007e, 0x1078, 0x22b9, 0x017f, 0x0078, 0x1283, 0x71c4,
+	0xa182, 0x0010, 0x00c8, 0x127c, 0x2011, 0x5049, 0x2204, 0x007e,
+	0x2112, 0x1078, 0x22a8, 0x017f, 0x0078, 0x1283, 0x71c4, 0x72c8,
+	0xa184, 0xfffd, 0x00c0, 0x127b, 0xa284, 0xfffd, 0x00c0, 0x127b,
+	0x2100, 0x7908, 0x780a, 0x2200, 0x7a0c, 0x780e, 0x0078, 0x1282,
+	0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
+	0x5280, 0x2019, 0x0000, 0x72c8, 0xa284, 0x0080, 0x0040, 0x14c6,
+	0x6c14, 0x84ff, 0x00c0, 0x14c6, 0x6817, 0x0040, 0xa284, 0x0040,
+	0x0040, 0x14d0, 0x6c10, 0x84ff, 0x00c0, 0x14d0, 0x6813, 0x0001,
+	0x6800, 0x007e, 0xa226, 0x0040, 0x14f3, 0x6a02, 0xa484, 0x2000,
+	0x0040, 0x14dc, 0xa39d, 0x0010, 0xa484, 0x1000, 0x0040, 0x14e2,
+	0xa39d, 0x0008, 0xa484, 0x4000, 0x0040, 0x14f3, 0x810f, 0xa284,
+	0x4000, 0x0040, 0x14ef, 0x1078, 0x22db, 0x0078, 0x14f3, 0x1078,
+	0x22cd, 0x0078, 0x14f3, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1522,
+	0xa2a4, 0x00ff, 0x2061, 0x5040, 0x6118, 0xa186, 0x0028, 0x0040,
+	0x1509, 0xa186, 0x0032, 0x0040, 0x150f, 0xa186, 0x003c, 0x0040,
+	0x1515, 0xa482, 0x0064, 0x0048, 0x151f, 0x0078, 0x1519, 0xa482,
+	0x0050, 0x0048, 0x151f, 0x0078, 0x1519, 0xa482, 0x0043, 0x0048,
+	0x151f, 0x71c4, 0x71c6, 0x027f, 0x72ca, 0x0078, 0x127d, 0x6a0a,
+	0xa39d, 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4,
+	0x0078, 0x1281, 0x77c4, 0x1078, 0x1956, 0x2091, 0x8000, 0x6a14,
+	0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708,
+	0x0078, 0x1281, 0x70c4, 0x794c, 0x784e, 0x0078, 0x1283, 0x71c4,
+	0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, 0x127c, 0x1078, 0x22e9,
+	0x0078, 0x1281, 0x77c4, 0x1078, 0x1956, 0x2091, 0x8000, 0x6a08,
+	0xa295, 0x0002, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282,
+	0x77c4, 0x1078, 0x1956, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9,
+	0x6a0a, 0x6804, 0xa005, 0x0040, 0x1567, 0x1078, 0x21b1, 0x2091,
+	0x8001, 0x2708, 0x0078, 0x1282, 0x77c4, 0x1078, 0x1956, 0x2091,
+	0x8000, 0x6a08, 0xa295, 0x0004, 0x6a0a, 0x6804, 0xa005, 0x0040,
+	0x157b, 0x1078, 0x21b1, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282,
+	0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091,
+	0x8000, 0x1078, 0x1963, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078,
+	0x1282, 0x77c4, 0x72c8, 0x73cc, 0x77c6, 0x72ca, 0x73ce, 0x1078,
+	0x19c4, 0x00c0, 0x15a9, 0x6818, 0xa005, 0x0040, 0x15a9, 0x2708,
+	0x1078, 0x22f9, 0x00c0, 0x15a9, 0x7817, 0x0015, 0x2091, 0x8001,
+	0x007c, 0x2091, 0x8001, 0x0078, 0x1284, 0x77c4, 0x77c6, 0x2041,
+	0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
+	0x1963, 0x2061, 0x5040, 0x606f, 0x0003, 0x6782, 0x6093, 0x000f,
+	0x6073, 0x0000, 0x7817, 0x0016, 0x1078, 0x21b1, 0x2091, 0x8001,
+	0x007c, 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2091,
+	0x8000, 0x2061, 0x5040, 0x606f, 0x0002, 0x6073, 0x0000, 0x6782,
+	0x6093, 0x000f, 0x7817, 0x0017, 0x1078, 0x21b1, 0x2091, 0x8001,
+	0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x2091, 0x8000,
+	0x1078, 0x1963, 0x70c8, 0x6836, 0x8738, 0xa784, 0x001f, 0x00c0,
+	0x15e8, 0x2091, 0x8001, 0x007c, 0x78cc, 0xa084, 0x0003, 0x00c0,
+	0x1618, 0x2039, 0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051,
+	0x0008, 0x1078, 0x1956, 0x2091, 0x8000, 0x6808, 0xa80d, 0x690a,
+	0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1601, 0xa7bc,
+	0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1601,
+	0x2091, 0x8000, 0x2069, 0x0100, 0x6830, 0xa084, 0x0040, 0x0040,
+	0x1641, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0004,
+	0x0040, 0x162e, 0x0070, 0x162e, 0x0078, 0x1625, 0x684b, 0x0009,
+	0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0040, 0x163b, 0x0070,
+	0x163b, 0x0078, 0x1632, 0x20a9, 0x00fa, 0x0070, 0x1641, 0x0078,
+	0x163d, 0x2079, 0x5000, 0x7817, 0x0018, 0x2061, 0x5040, 0x606f,
+	0x0001, 0x6073, 0x0000, 0x6093, 0x000f, 0x78cc, 0xa085, 0x0002,
+	0x78ce, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0048, 0x2091,
+	0x8001, 0x007c, 0x78cc, 0xa084, 0xfffd, 0x78ce, 0xa084, 0x0001,
+	0x00c0, 0x1664, 0x1078, 0x1a0e, 0x71c4, 0x71c6, 0x794a, 0x007c,
+	0x1078, 0x1b36, 0x00c0, 0x129c, 0x75d8, 0x74dc, 0x75da, 0x74de,
+	0x0078, 0x1675, 0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8, 0x72cc,
+	0x71c6, 0x73ca, 0x72ce, 0x2079, 0x5000, 0x2091, 0x8000, 0x1078,
+	0x1911, 0x2091, 0x8001, 0x0040, 0x172c, 0x20a9, 0x0005, 0x20a1,
+	0x5018, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0020,
+	0x1078, 0x190c, 0x0040, 0x1698, 0x1078, 0x192b, 0x0078, 0x172c,
+	0x6004, 0xa084, 0xff00, 0x8007, 0x8009, 0x0040, 0x16fb, 0x0c7e,
+	0x2c68, 0x2091, 0x8000, 0x1078, 0x1911, 0x2091, 0x8001, 0x0040,
+	0x16cc, 0x2c00, 0x689e, 0x8109, 0x00c0, 0x16a0, 0x609f, 0x0000,
+	0x0c7f, 0x0c7e, 0x7218, 0x731c, 0x7420, 0x7524, 0x2c68, 0x689c,
+	0xa065, 0x0040, 0x16fa, 0x2009, 0x0020, 0x1078, 0x190c, 0x00c0,
+	0x16e3, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0002, 0x00c0, 0x16cc,
+	0x2d00, 0x6002, 0x0078, 0x16b2, 0x0c7f, 0x0c7e, 0x609c, 0x2060,
+	0x1078, 0x1996, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009,
+	0x000c, 0x6008, 0xa085, 0x0200, 0x600a, 0x1078, 0x1907, 0x1078,
+	0x192b, 0x0078, 0x172c, 0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078,
+	0x1996, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, 0x000c,
+	0x6007, 0x0103, 0x601b, 0x0003, 0x1078, 0x1907, 0x1078, 0x192b,
+	0x0078, 0x172c, 0x0c7f, 0x74c4, 0x73c8, 0x72cc, 0x6014, 0x2091,
+	0x8000, 0x7817, 0x0012, 0x0e7e, 0x2071, 0x5040, 0x706f, 0x0005,
+	0x7073, 0x0000, 0x7376, 0x727a, 0x747e, 0x7082, 0x7087, 0x0000,
+	0x2c00, 0x708a, 0x708f, 0x0000, 0xa02e, 0x2530, 0x611c, 0x61a2,
+	0xa184, 0x0060, 0x0040, 0x171e, 0x1078, 0x467f, 0x0e7f, 0x6596,
+	0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x1078,
+	0x21b1, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1287,
+	0x20a9, 0x0005, 0x2099, 0x5018, 0x2091, 0x8000, 0x530a, 0x2091,
+	0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
+	0x0000, 0x007c, 0x71c4, 0x70c7, 0x0000, 0x7906, 0x0078, 0x1284,
+	0x71c4, 0x71c6, 0x2168, 0x0078, 0x174f, 0x2069, 0x1000, 0x690c,
+	0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0, 0x1751, 0xa285,
+	0x0000, 0x00c0, 0x175f, 0x70c3, 0x4000, 0x0078, 0x1761, 0x70c3,
+	0x4003, 0x70ca, 0x0078, 0x1287, 0x2011, 0x5067, 0x220c, 0x70c4,
+	0x8003, 0x0048, 0x1771, 0x1078, 0x3b49, 0xa184, 0x7fff, 0x0078,
+	0x1775, 0x1078, 0x3b3c, 0xa185, 0x8000, 0x2012, 0x0078, 0x1283,
+	0x71c4, 0x1078, 0x3b33, 0x6100, 0x2001, 0x5067, 0x2004, 0xa084,
+	0x8000, 0xa10d, 0x6204, 0x6308, 0x0078, 0x1281, 0x79e4, 0x0078,
+	0x1283, 0x71c4, 0x71c6, 0x2198, 0x20a1, 0x0042, 0x20a9, 0x0004,
+	0x53a3, 0x21a0, 0x2099, 0x0042, 0x20a9, 0x0004, 0x53a3, 0x0078,
+	0x1284, 0x70c4, 0x2068, 0x2079, 0x5000, 0x2091, 0x8000, 0x1078,
+	0x1911, 0x2091, 0x8001, 0x0040, 0x1825, 0x6007, 0x0001, 0x600b,
+	0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x6a10, 0xa28c, 0x000f,
+	0xa284, 0x00f0, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x6016,
+	0xa284, 0x0800, 0x0040, 0x17c0, 0x601b, 0x000a, 0x0078, 0x17c6,
+	0xa284, 0x1000, 0x0040, 0x17c6, 0x601b, 0x000c, 0xa284, 0x0300,
+	0x0040, 0x17cf, 0x602b, 0x0001, 0x8004, 0x8004, 0x8004, 0xa085,
+	0x0001, 0x601e, 0x6023, 0x0000, 0x6027, 0x0000, 0xa284, 0x0400,
+	0x0040, 0x17dc, 0x602b, 0x0000, 0x20a9, 0x0006, 0xac80, 0x000b,
+	0x20a0, 0xad80, 0x0005, 0x2098, 0x53a3, 0xa284, 0x0300, 0x00c0,
+	0x17f1, 0x6046, 0x604a, 0x604e, 0x6052, 0x6096, 0x609a, 0x0078,
+	0x17fb, 0x6800, 0x6046, 0x6804, 0x604a, 0x6e08, 0x664e, 0x6d0c,
+	0x6552, 0x6596, 0x669a, 0x6014, 0x2091, 0x8000, 0x7817, 0x0042,
+	0x2c08, 0x2061, 0x5040, 0x606f, 0x0005, 0x6073, 0x0000, 0x6077,
+	0x0000, 0x607b, 0x0000, 0x607f, 0x0000, 0x6082, 0x618a, 0xa284,
+	0x0400, 0x608e, 0x2091, 0x8001, 0x0e7e, 0x2071, 0x0020, 0x7007,
+	0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x0e7f, 0x2091, 0x8000,
+	0x1078, 0x21b1, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078,
+	0x1287, 0x0c7e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2091, 0x8000, 0x2071,
+	0x5040, 0x2079, 0x0100, 0x2061, 0x0010, 0x70a0, 0xa06d, 0x0040,
+	0x18aa, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0007, 0x0040, 0x1844,
+	0xa286, 0x000f, 0x00c0, 0x18aa, 0x691c, 0xa184, 0x0080, 0x00c0,
+	0x18aa, 0x6824, 0xa18c, 0xff00, 0xa085, 0x0019, 0x6826, 0x71b0,
+	0x81ff, 0x0040, 0x1865, 0x0d7e, 0x2069, 0x0020, 0x6908, 0x6808,
+	0xa106, 0x00c0, 0x1856, 0x690c, 0x680c, 0xa106, 0x00c0, 0x185b,
+	0xa184, 0x00ff, 0x00c0, 0x185b, 0x0d7f, 0x78b8, 0xa084, 0x801f,
+	0x00c0, 0x1865, 0x7848, 0xa085, 0x000c, 0x784a, 0x71b0, 0x81ff,
+	0x0040, 0x1888, 0x70b3, 0x0000, 0x0d7e, 0x2069, 0x0020, 0x6807,
+	0x0008, 0x6804, 0xa084, 0x0008, 0x00c0, 0x1879, 0x6807, 0x0008,
+	0x6804, 0xa084, 0x0008, 0x00c0, 0x1880, 0x6807, 0x0002, 0x0d7f,
+	0x61c4, 0x62c8, 0x63cc, 0x61c6, 0x62ca, 0x63ce, 0x0e7e, 0x2071,
+	0x5000, 0x7266, 0x736a, 0xae80, 0x0019, 0x0e7f, 0x1078, 0x4598,
+	0x78a3, 0x0000, 0x7858, 0xa084, 0xedff, 0x785a, 0x70b4, 0xa080,
+	0x00da, 0x781a, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091, 0x8001,
+	0x0078, 0x1284, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091, 0x8001,
+	0x2001, 0x4005, 0x0078, 0x1286, 0x7980, 0x71c6, 0x71c4, 0xa182,
+	0x0003, 0x00c8, 0x127c, 0x7982, 0x0078, 0x1284, 0x7980, 0x71c6,
+	0x0078, 0x1284, 0x7974, 0x71c6, 0x71c4, 0x7976, 0x7978, 0x71ca,
+	0x71c8, 0x797a, 0x797c, 0x71ce, 0x71cc, 0x797e, 0x0078, 0x1284,
+	0x7974, 0x71c6, 0x7978, 0x71ca, 0x797c, 0x71ce, 0x0078, 0x1284,
+	0x7900, 0x71c6, 0x71c4, 0x7902, 0x2001, 0x04fd, 0x2004, 0xa082,
+	0x0005, 0x0048, 0x18e7, 0x0038, 0x18e9, 0x0078, 0x18f3, 0x00a8,
+	0x18f3, 0xa18c, 0x0001, 0x00c0, 0x18f1, 0x20b9, 0x2222, 0x0078,
+	0x18f3, 0x20b9, 0x1212, 0x0078, 0x1284, 0x7900, 0x71c6, 0x0078,
+	0x1284, 0x2009, 0x5074, 0x2104, 0x70c6, 0x70c4, 0x200a, 0x0078,
+	0x1284, 0x2009, 0x5074, 0x2104, 0x70c6, 0x0078, 0x1284, 0xac80,
+	0x0001, 0x1078, 0x1af2, 0x007c, 0xac80, 0x0001, 0x1078, 0x1a92,
+	0x007c, 0x7850, 0xa065, 0x0040, 0x1919, 0x2c04, 0x7852, 0x2063,
+	0x0000, 0x007c, 0x0f7e, 0x2079, 0x5000, 0x7850, 0xa06d, 0x0040,
+	0x1929, 0x2d04, 0x7852, 0x6803, 0x0000, 0x6807, 0x0000, 0x680b,
+	0x0000, 0x0f7f, 0x007c, 0x2091, 0x8000, 0x0f7e, 0x2079, 0x5000,
+	0x7850, 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1938, 0x1078, 0x23ca,
+	0x7852, 0x0f7f, 0x2091, 0x8001, 0x007c, 0x0f7e, 0x2079, 0x5000,
+	0x7850, 0x206a, 0x2d00, 0x7852, 0x0f7f, 0x007c, 0x2011, 0x7700,
+	0x7a52, 0x7bec, 0x8319, 0x0040, 0x1953, 0xa280, 0x0031, 0x2012,
+	0x2010, 0x0078, 0x194a, 0x2013, 0x0000, 0x007c, 0xa784, 0x0f00,
+	0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105,
+	0xa0e8, 0x5300, 0x007c, 0x1078, 0x1956, 0x2900, 0x682a, 0x2a00,
+	0x682e, 0x6808, 0xa084, 0xffef, 0xa80d, 0x690a, 0x2009, 0x5052,
+	0x210c, 0x6804, 0xa005, 0x0040, 0x1995, 0xa116, 0x00c0, 0x1980,
+	0x2060, 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x1983,
+	0x2009, 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1992, 0x6000,
+	0x6806, 0x1078, 0x19a3, 0x1078, 0x1c42, 0x6810, 0x8001, 0x6812,
+	0x00c0, 0x1983, 0x017f, 0x6902, 0x6906, 0x007c, 0xa065, 0x0040,
+	0x19a2, 0x609c, 0x609f, 0x0000, 0x2008, 0x1078, 0x192b, 0x2100,
+	0x0078, 0x1996, 0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9,
+	0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828,
+	0x601a, 0x682c, 0x6022, 0x007c, 0x0e7e, 0x2071, 0x5040, 0x704c,
+	0xa08c, 0x0200, 0x00c0, 0x19c2, 0xa088, 0x5080, 0x2d0a, 0x8000,
+	0x704e, 0xa006, 0x0e7f, 0x007c, 0x1078, 0x1956, 0x2091, 0x8000,
+	0x6804, 0x781e, 0xa065, 0x0040, 0x1a0d, 0x0078, 0x19d5, 0x2c00,
+	0x781e, 0x6000, 0xa065, 0x0040, 0x1a0d, 0x600c, 0xa306, 0x00c0,
+	0x19cf, 0x6010, 0xa206, 0x00c0, 0x19cf, 0x2c28, 0x2001, 0x5052,
+	0x2004, 0xac06, 0x00c0, 0x19e6, 0x0078, 0x1a0b, 0x6804, 0xac06,
+	0x00c0, 0x19f3, 0x6000, 0xa065, 0x6806, 0x00c0, 0x19fd, 0x6803,
+	0x0000, 0x0078, 0x19fd, 0x6400, 0x781c, 0x2060, 0x6402, 0xa486,
+	0x0000, 0x00c0, 0x19fd, 0x2c00, 0x6802, 0x2560, 0x1078, 0x19a3,
+	0x601b, 0x0005, 0x6023, 0x0020, 0x1078, 0x1c42, 0x6810, 0x8001,
+	0x1050, 0x23ca, 0x6812, 0xa085, 0xffff, 0x007c, 0x2039, 0x0000,
+	0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000,
+	0x1078, 0x1963, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1a18, 0xa7bc,
+	0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1a18,
+	0x2091, 0x8001, 0x007c, 0x2061, 0x0000, 0x6018, 0xa084, 0x0001,
+	0x00c0, 0x1a3c, 0x2091, 0x8000, 0x78e0, 0x78e3, 0x0000, 0x2091,
+	0x8001, 0xa005, 0x00c0, 0x1a3d, 0x007c, 0xa08c, 0xfff0, 0x0040,
+	0x1a43, 0x1078, 0x23ca, 0x0079, 0x1a45, 0x1a55, 0x1a58, 0x1a5e,
+	0x1a62, 0x1a56, 0x1a66, 0x1a6c, 0x1a56, 0x1a56, 0x1c0c, 0x1c30,
+	0x1c34, 0x1a56, 0x1a56, 0x1a56, 0x1a56, 0x007c, 0x1078, 0x23ca,
+	0x1078, 0x1a0e, 0x2001, 0x8001, 0x0078, 0x1c3a, 0x2001, 0x8003,
+	0x0078, 0x1c3a, 0x2001, 0x8004, 0x0078, 0x1c3a, 0x1078, 0x1a0e,
+	0x2001, 0x8006, 0x0078, 0x1c3a, 0x2001, 0x8007, 0x0078, 0x1c3a,
+	0x2030, 0x2138, 0xa782, 0x0021, 0x0048, 0x1a78, 0x2009, 0x0020,
+	0x2600, 0x1078, 0x1a92, 0x00c0, 0x1a91, 0xa7ba, 0x0020, 0x0048,
+	0x1a90, 0x0040, 0x1a90, 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040,
+	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1a72,
+	0xa006, 0x007c, 0x81ff, 0x0040, 0x1acd, 0x2099, 0x0030, 0x20a0,
+	0x700c, 0xa084, 0x00ff, 0x0040, 0x1aa4, 0x7007, 0x0004, 0x7004,
+	0xa084, 0x0004, 0x00c0, 0x1a9f, 0x21a8, 0x7017, 0x0000, 0x810b,
+	0x7112, 0x721a, 0x731e, 0x7422, 0x7526, 0x780c, 0xa085, 0x0001,
+	0x7002, 0x7007, 0x0001, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
+	0x00c8, 0x1ac1, 0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0,
+	0x1ab3, 0x7008, 0x800b, 0x00c8, 0x1ab3, 0x7007, 0x0002, 0xa08c,
+	0x01e0, 0x00c0, 0x1acd, 0x53a5, 0xa006, 0x7003, 0x0000, 0x007c,
+	0x2030, 0x2138, 0xa782, 0x0021, 0x0048, 0x1ad8, 0x2009, 0x0020,
+	0x2600, 0x1078, 0x1af2, 0x00c0, 0x1af1, 0xa7ba, 0x0020, 0x0048,
+	0x1af0, 0x0040, 0x1af0, 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040,
+	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1ad2,
+	0xa006, 0x007c, 0x81ff, 0x0040, 0x1b33, 0x2098, 0x20a1, 0x0030,
+	0x700c, 0xa084, 0x00ff, 0x0040, 0x1b04, 0x7007, 0x0004, 0x7004,
+	0xa084, 0x0004, 0x00c0, 0x1aff, 0x21a8, 0x7017, 0x0000, 0x810b,
+	0x7112, 0x721a, 0x731e, 0x7422, 0x7526, 0x780c, 0xa085, 0x0000,
+	0x7002, 0x53a6, 0x7007, 0x0001, 0x2001, 0x04fd, 0x2004, 0xa082,
+	0x0005, 0x00c8, 0x1b22, 0x2009, 0x0022, 0x2104, 0xa084, 0x4000,
+	0x00c0, 0x1b14, 0x7010, 0xa084, 0xf000, 0x0040, 0x1b2b, 0x7007,
+	0x0008, 0x0078, 0x1b2f, 0x7108, 0x8103, 0x00c8, 0x1b14, 0x7007,
+	0x0002, 0xa184, 0x01e0, 0x7003, 0x0000, 0x007c, 0x2001, 0x04fd,
+	0x2004, 0xa082, 0x0004, 0x00c8, 0x1b3f, 0x0078, 0x1b42, 0xa006,
+	0x0078, 0x1b44, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x2071, 0x5000,
+	0x2d08, 0x7058, 0x6802, 0xa005, 0x00c0, 0x1b4f, 0x715e, 0x715a,
+	0x0e7f, 0x007c, 0x2c08, 0x7858, 0x6002, 0xa005, 0x00c0, 0x1b59,
+	0x795e, 0x795a, 0x007c, 0x2091, 0x8000, 0x6003, 0x0000, 0x2c08,
+	0x785c, 0xa065, 0x00c0, 0x1b67, 0x795a, 0x0078, 0x1b68, 0x6102,
+	0x795e, 0x2091, 0x8001, 0x1078, 0x21ce, 0x007c, 0x0e7e, 0x2071,
+	0x5000, 0x7058, 0xa06d, 0x0040, 0x1b7c, 0x6800, 0x705a, 0xa005,
+	0x00c0, 0x1b7b, 0x705e, 0x8dff, 0x0e7f, 0x007c, 0x0d7e, 0x0c7e,
+	0x0f7e, 0x2079, 0x5000, 0xaf80, 0x0016, 0x2060, 0x6000, 0xa005,
+	0x0040, 0x1bac, 0x2068, 0x6814, 0xa306, 0x00c0, 0x1b95, 0x6828,
+	0xa084, 0x00ff, 0xa406, 0x0040, 0x1b98, 0x2d60, 0x0078, 0x1b86,
+	0x6800, 0xa005, 0x6002, 0x00c0, 0x1ba4, 0xaf80, 0x0016, 0xac06,
+	0x0040, 0x1ba3, 0x2c00, 0x785e, 0x0d7e, 0x689c, 0xa005, 0x0040,
+	0x1bab, 0x1078, 0x1996, 0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005,
+	0x007c, 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5000, 0xaf80, 0x0016,
+	0x2060, 0x6000, 0xa005, 0x0040, 0x1bdb, 0x2068, 0x6814, 0xa084,
+	0x00ff, 0xa306, 0x0040, 0x1bc7, 0x2d60, 0x0078, 0x1bb9, 0x6800,
+	0xa005, 0x6002, 0x00c0, 0x1bd3, 0xaf80, 0x0016, 0xac06, 0x0040,
+	0x1bd2, 0x2c00, 0x785e, 0x0d7e, 0x689c, 0xa005, 0x0040, 0x1bda,
+	0x1078, 0x1996, 0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c,
+	0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5000, 0xaf80, 0x0016, 0x2060,
+	0x6000, 0xa06d, 0x0040, 0x1c07, 0x6814, 0xa306, 0x0040, 0x1bf3,
+	0x2d60, 0x0078, 0x1be8, 0x6800, 0xa005, 0x6002, 0x00c0, 0x1bff,
+	0xaf80, 0x0016, 0xac06, 0x0040, 0x1bfe, 0x2c00, 0x785e, 0x0d7e,
+	0x689c, 0xa005, 0x0040, 0x1c06, 0x1078, 0x1996, 0x007f, 0x0f7f,
+	0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x2091, 0x8000, 0x2069, 0x5040,
+	0x6800, 0xa086, 0x0000, 0x0040, 0x1c1a, 0x2091, 0x8001, 0x78e3,
+	0x0009, 0x007c, 0x6880, 0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049,
+	0x0004, 0x2051, 0x0010, 0x1078, 0x1963, 0x8738, 0xa784, 0x001f,
+	0x00c0, 0x1c23, 0x2091, 0x8001, 0x2001, 0x800a, 0x0078, 0x1c3a,
+	0x2001, 0x800c, 0x0078, 0x1c3a, 0x1078, 0x1a0e, 0x2001, 0x800d,
+	0x0078, 0x1c3a, 0x70c2, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091,
+	0x4080, 0x007c, 0x6004, 0x2c08, 0x2063, 0x0000, 0x7884, 0x8000,
+	0x7886, 0x7888, 0xa005, 0x798a, 0x0040, 0x1c51, 0x2c02, 0x0078,
+	0x1c52, 0x798e, 0x007c, 0x6807, 0x0103, 0x0c7e, 0x2061, 0x5000,
+	0x2d08, 0x206b, 0x0000, 0x6084, 0x8000, 0x6086, 0x6088, 0xa005,
+	0x618a, 0x0040, 0x1c66, 0x2d02, 0x0078, 0x1c67, 0x618e, 0x0c7f,
+	0x007c, 0x1078, 0x1c7a, 0x0040, 0x1c79, 0x0c7e, 0x609c, 0xa065,
+	0x0040, 0x1c74, 0x1078, 0x1996, 0x0c7f, 0x609f, 0x0000, 0x1078,
+	0x192b, 0x007c, 0x788c, 0xa065, 0x0040, 0x1c8c, 0x2091, 0x8000,
+	0x7884, 0x8001, 0x7886, 0x2c04, 0x788e, 0xa005, 0x00c0, 0x1c8a,
+	0x788a, 0x8000, 0x2091, 0x8001, 0x007c, 0x20a9, 0x0010, 0xa006,
+	0x8004, 0x8086, 0x818e, 0x00c8, 0x1c96, 0xa200, 0x0070, 0x1c9a,
+	0x0078, 0x1c91, 0x8086, 0x818e, 0x007c, 0x157e, 0x20a9, 0x0010,
+	0xa005, 0x0040, 0x1cc0, 0xa11a, 0x00c8, 0x1cc0, 0x8213, 0x818d,
+	0x0048, 0x1cb1, 0xa11a, 0x00c8, 0x1cb2, 0x0070, 0x1cb8, 0x0078,
+	0x1ca6, 0xa11a, 0x2308, 0x8210, 0x0070, 0x1cb8, 0x0078, 0x1ca6,
+	0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f, 0x007c,
+	0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x1cbc, 0x7994, 0x70d0,
+	0xa106, 0x0040, 0x1d34, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004,
+	0xa005, 0x00c0, 0x1d34, 0x7008, 0x7208, 0xa206, 0x00c0, 0x1d34,
+	0xa286, 0x0008, 0x00c0, 0x1d34, 0x2071, 0x0010, 0x1078, 0x1911,
+	0x0040, 0x1d34, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa184, 0xff00,
+	0x0040, 0x1d02, 0x2031, 0x0000, 0x810b, 0x86b5, 0x810b, 0x86b5,
+	0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5,
+	0x2100, 0xa210, 0x2600, 0xa319, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
+	0x0078, 0x1d0c, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399, 0x0000,
+	0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x2009, 0x0020, 0x1078, 0x190c,
+	0x2091, 0x8001, 0x0040, 0x1d2b, 0x1078, 0x192b, 0x78a8, 0x8000,
+	0x78aa, 0xa086, 0x0002, 0x00c0, 0x1d34, 0x2091, 0x8000, 0x78e3,
+	0x0002, 0x78ab, 0x0000, 0x78cc, 0xa085, 0x0003, 0x78ce, 0x2091,
+	0x8001, 0x0078, 0x1d34, 0x78ab, 0x0000, 0x1078, 0x208b, 0x6004,
+	0xa084, 0x000f, 0x0079, 0x1d39, 0x2071, 0x0010, 0x2091, 0x8001,
+	0x007c, 0x1d49, 0x1d6b, 0x1d91, 0x1d49, 0x1dae, 0x1d58, 0x1f0d,
+	0x1f28, 0x1d49, 0x1d65, 0x1d8b, 0x1df6, 0x1e63, 0x1eb3, 0x1ec5,
+	0x1f24, 0x2039, 0x0400, 0x78dc, 0xa705, 0x78de, 0x6008, 0xa705,
+	0x600a, 0x1078, 0x1fa6, 0x609c, 0x78da, 0x1078, 0x2073, 0x007c,
+	0x78dc, 0xa084, 0x0100, 0x0040, 0x1d5f, 0x0078, 0x1d49, 0x601c,
+	0xa085, 0x0080, 0x601e, 0x0078, 0x1d72, 0x1078, 0x1b36, 0x00c0,
+	0x1d49, 0x1078, 0x20a5, 0x78dc, 0xa084, 0x0100, 0x0040, 0x1d72,
+	0x0078, 0x1d49, 0x78df, 0x0000, 0x6004, 0x8007, 0xa084, 0x00ff,
+	0x78d2, 0x8001, 0x609f, 0x0000, 0x0040, 0x1d88, 0x1078, 0x1fa6,
+	0x0040, 0x1d88, 0x78dc, 0xa085, 0x0100, 0x78de, 0x0078, 0x1d8a,
+	0x1078, 0x1fca, 0x007c, 0x1078, 0x1b36, 0x00c0, 0x1d49, 0x1078,
+	0x20a1, 0x78dc, 0xa08c, 0x0e00, 0x00c0, 0x1d9a, 0xa084, 0x0100,
+	0x00c0, 0x1d9c, 0x0078, 0x1d49, 0x1078, 0x1fa6, 0x00c0, 0x1dad,
+	0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x1f63, 0xa186,
+	0x000f, 0x0040, 0x1f63, 0x1078, 0x1fca, 0x007c, 0x78dc, 0xa084,
+	0x0100, 0x0040, 0x1db5, 0x0078, 0x1d49, 0x78df, 0x0000, 0x6714,
+	0x2011, 0x0001, 0x20a9, 0x0001, 0x6018, 0xa084, 0x00ff, 0xa005,
+	0x0040, 0x1dd8, 0x2011, 0x0001, 0xa7bc, 0xff00, 0x20a9, 0x0020,
+	0xa08e, 0x0001, 0x0040, 0x1dd8, 0x2039, 0x0000, 0x2011, 0x0002,
+	0x20a9, 0x0100, 0xa08e, 0x0002, 0x0040, 0x1dd8, 0x0078, 0x1df3,
+	0x1078, 0x1956, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000,
+	0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001,
+	0x0070, 0x1dec, 0x0078, 0x1dda, 0x8211, 0x0040, 0x1df3, 0x20a9,
+	0x0100, 0x0078, 0x1dda, 0x1078, 0x192b, 0x007c, 0x2001, 0x5067,
+	0x2004, 0xa084, 0x8000, 0x0040, 0x1f8b, 0x6114, 0x1078, 0x20c2,
+	0x6900, 0xa184, 0x0001, 0x0040, 0x1e17, 0x6028, 0xa084, 0x00ff,
+	0x00c0, 0x1f83, 0x6800, 0xa084, 0x0001, 0x0040, 0x1f8b, 0x6803,
+	0x0000, 0x680b, 0x0000, 0x6807, 0x0000, 0x0078, 0x1f93, 0x2011,
+	0x0001, 0x6020, 0xa084, 0x4000, 0x0040, 0x1e20, 0xa295, 0x0002,
+	0x6020, 0xa084, 0x0100, 0x0040, 0x1e27, 0xa295, 0x0008, 0x601c,
+	0xa084, 0x0002, 0x0040, 0x1e2e, 0xa295, 0x0004, 0x602c, 0xa08c,
+	0x00ff, 0xa182, 0x0002, 0x0048, 0x1f8f, 0xa182, 0x001b, 0x00c8,
+	0x1f8f, 0x0040, 0x1f8f, 0x690e, 0x602c, 0x8007, 0xa08c, 0x00ff,
+	0xa182, 0x0002, 0x0048, 0x1f8f, 0xa182, 0x001b, 0x00c8, 0x1f8f,
+	0x0040, 0x1f8f, 0x6912, 0x6030, 0xa005, 0x00c0, 0x1e51, 0x2001,
+	0x001e, 0x8000, 0x6816, 0x6028, 0xa084, 0x00ff, 0x0040, 0x1f8b,
+	0x6806, 0x6028, 0x8007, 0xa084, 0x00ff, 0x0040, 0x1f8b, 0x680a,
+	0x6a02, 0x0078, 0x1f93, 0x2001, 0x5067, 0x2004, 0xa084, 0x8000,
+	0x0040, 0x1f8b, 0x6114, 0x1078, 0x20c2, 0x2091, 0x8000, 0x6a04,
+	0x6b08, 0x6418, 0xa484, 0x0003, 0x0040, 0x1e89, 0x6128, 0xa18c,
+	0x00ff, 0x8001, 0x00c0, 0x1e82, 0x2100, 0xa210, 0x0048, 0x1eaf,
+	0x0078, 0x1e89, 0x8001, 0x00c0, 0x1eaf, 0x2100, 0xa212, 0x0048,
+	0x1eaf, 0xa484, 0x000c, 0x0040, 0x1ea3, 0x6128, 0x810f, 0xa18c,
+	0x00ff, 0xa082, 0x0004, 0x00c0, 0x1e9b, 0x2100, 0xa318, 0x0048,
+	0x1eaf, 0x0078, 0x1ea3, 0xa082, 0x0004, 0x00c0, 0x1eaf, 0x2100,
+	0xa31a, 0x0048, 0x1eaf, 0x6030, 0xa005, 0x0040, 0x1ea9, 0x8000,
+	0x6816, 0x6a06, 0x6b0a, 0x2091, 0x8001, 0x0078, 0x1f93, 0x2091,
+	0x8001, 0x0078, 0x1f8f, 0x6114, 0x1078, 0x20c2, 0x2091, 0x8000,
+	0x6b08, 0x8318, 0x0048, 0x1ec1, 0x6b0a, 0x2091, 0x8001, 0x0078,
+	0x1fa2, 0x2091, 0x8001, 0x0078, 0x1f8f, 0x6024, 0x8007, 0xa084,
+	0x00ff, 0x0040, 0x1ee3, 0xa086, 0x0080, 0x00c0, 0x1f0b, 0x20a9,
+	0x0008, 0x2069, 0x7410, 0x2091, 0x8000, 0x6800, 0xa084, 0xfcff,
+	0x6802, 0xade8, 0x0008, 0x0070, 0x1edf, 0x0078, 0x1ed5, 0x2091,
+	0x8001, 0x0078, 0x1f93, 0x6028, 0xa015, 0x0040, 0x1f0b, 0x6114,
+	0x1078, 0x20c2, 0x0d7e, 0xade8, 0x0007, 0x2091, 0x8000, 0x6800,
+	0xa00d, 0x0040, 0x1f08, 0xa206, 0x0040, 0x1ef9, 0x2168, 0x0078,
+	0x1eef, 0x0c7e, 0x2160, 0x6000, 0x6802, 0x1078, 0x192b, 0x0c7f,
+	0x0d7f, 0x6808, 0x8000, 0x680a, 0x2091, 0x8001, 0x0078, 0x1fa2,
+	0x2091, 0x8001, 0x0d7f, 0x0078, 0x1f8b, 0x6114, 0x1078, 0x20c2,
+	0x6800, 0xa084, 0x0001, 0x0040, 0x1f7b, 0x2091, 0x8000, 0x6a04,
+	0x8210, 0x0048, 0x1f20, 0x6a06, 0x2091, 0x8001, 0x0078, 0x1fa2,
+	0x2091, 0x8001, 0x0078, 0x1f8f, 0x1078, 0x1b36, 0x00c0, 0x1d49,
+	0x6114, 0x1078, 0x20c2, 0x60be, 0x6900, 0xa184, 0x0008, 0x0040,
+	0x1f35, 0x6020, 0xa085, 0x0100, 0x6022, 0xa184, 0x0001, 0x0040,
+	0x1f8b, 0xa184, 0x0100, 0x00c0, 0x1f77, 0xa184, 0x0200, 0x00c0,
+	0x1f73, 0x681c, 0xa005, 0x00c0, 0x1f7f, 0x6004, 0xa084, 0x00ff,
+	0xa086, 0x000f, 0x00c0, 0x1f4e, 0x1078, 0x20a5, 0x78df, 0x0000,
+	0x6004, 0x8007, 0xa084, 0x00ff, 0x78d2, 0x8001, 0x609f, 0x0000,
+	0x0040, 0x1f63, 0x1078, 0x1fa6, 0x0040, 0x1f63, 0x78dc, 0xa085,
+	0x0100, 0x78de, 0x007c, 0x78d7, 0x0000, 0x78db, 0x0000, 0x6024,
+	0xa084, 0xff00, 0x6026, 0x1078, 0x39aa, 0x0040, 0x1cc6, 0x1078,
+	0x1b5b, 0x0078, 0x1cc6, 0x2009, 0x0017, 0x0078, 0x1f95, 0x2009,
+	0x000e, 0x0078, 0x1f95, 0x2009, 0x0007, 0x0078, 0x1f95, 0x2009,
+	0x0035, 0x0078, 0x1f95, 0x2009, 0x003e, 0x0078, 0x1f95, 0x2009,
+	0x0004, 0x0078, 0x1f95, 0x2009, 0x0006, 0x0078, 0x1f95, 0x2009,
+	0x0016, 0x0078, 0x1f95, 0x2009, 0x0001, 0x6024, 0xa084, 0xff00,
+	0xa105, 0x6026, 0x2091, 0x8000, 0x1078, 0x1c42, 0x2091, 0x8001,
+	0x0078, 0x1cc6, 0x1078, 0x192b, 0x0078, 0x1cc6, 0x78d4, 0xa06d,
+	0x00c0, 0x1fb1, 0x2c00, 0x78d6, 0x78da, 0x609f, 0x0000, 0x0078,
+	0x1fbd, 0x2c00, 0x689e, 0x609f, 0x0000, 0x78d6, 0x2d00, 0x6002,
+	0x78d8, 0xad06, 0x00c0, 0x1fbd, 0x6002, 0x78d0, 0x8001, 0x78d2,
+	0x00c0, 0x1fc9, 0x78dc, 0xa084, 0xfeff, 0x78de, 0x78d8, 0x2060,
+	0xa006, 0x007c, 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184, 0xe1ff,
+	0x601e, 0xa184, 0x0060, 0x0040, 0x1fd9, 0x0e7e, 0x1078, 0x467f,
+	0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3,
+	0x0000, 0x6714, 0x1078, 0x1956, 0x2091, 0x8000, 0x60a0, 0xa084,
+	0x8000, 0x00c0, 0x2000, 0x6808, 0xa084, 0x0001, 0x0040, 0x2000,
+	0x2091, 0x8001, 0x1078, 0x19a3, 0x2091, 0x8000, 0x1078, 0x1c42,
+	0x2091, 0x8001, 0x78d7, 0x0000, 0x78db, 0x0000, 0x0078, 0x2072,
+	0x6024, 0xa096, 0x0001, 0x00c0, 0x2007, 0x8000, 0x6026, 0x6a10,
+	0x6814, 0x2091, 0x8001, 0xa202, 0x0048, 0x2016, 0x0040, 0x2016,
+	0x2039, 0x0200, 0x1078, 0x2073, 0x0078, 0x2072, 0x2c08, 0x2091,
+	0x8000, 0x60a0, 0xa084, 0x8000, 0x0040, 0x2043, 0x6800, 0xa065,
+	0x0040, 0x2048, 0x6a04, 0x0e7e, 0x2071, 0x5040, 0x7000, 0xa084,
+	0x0001, 0x0040, 0x203d, 0x7048, 0xa206, 0x00c0, 0x203d, 0x6b04,
+	0x231c, 0x2160, 0x6302, 0x2300, 0xa005, 0x00c0, 0x2038, 0x6902,
+	0x2260, 0x6102, 0x0e7f, 0x0078, 0x204f, 0x2160, 0x6202, 0x6906,
+	0x0e7f, 0x0078, 0x204f, 0x6800, 0xa065, 0x0040, 0x2048, 0x6102,
+	0x6902, 0x00c0, 0x204c, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160,
+	0x60a0, 0xa084, 0x8000, 0x0040, 0x2059, 0x6808, 0xa084, 0xfffc,
+	0x680a, 0x6810, 0x8000, 0x6812, 0x2091, 0x8001, 0x6808, 0xa08c,
+	0x0040, 0x0040, 0x2068, 0xa086, 0x0040, 0x680a, 0x1078, 0x19b4,
+	0x2091, 0x8000, 0x1078, 0x21b1, 0x2091, 0x8001, 0x78db, 0x0000,
+	0x78d7, 0x0000, 0x007c, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000,
+	0x1078, 0x1c42, 0x2091, 0x8001, 0x78d8, 0xa065, 0x0040, 0x2086,
+	0x609c, 0x78da, 0x609f, 0x0000, 0x0078, 0x2076, 0x78d7, 0x0000,
+	0x78db, 0x0000, 0x007c, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8,
+	0x2092, 0xa006, 0x7896, 0x70d2, 0x7804, 0xa005, 0x0040, 0x20a0,
+	0x8001, 0x7806, 0x00c0, 0x20a0, 0x0068, 0x20a0, 0x2091, 0x4080,
+	0x007c, 0x2039, 0x20b9, 0x0078, 0x20a7, 0x2039, 0x20bf, 0x2704,
+	0xa005, 0x0040, 0x20b8, 0xac00, 0x2068, 0x6b08, 0x6c0c, 0x6910,
+	0x6a14, 0x690a, 0x6a0e, 0x6b12, 0x6c16, 0x8738, 0x0078, 0x20a7,
+	0x007c, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015,
+	0x001b, 0x0000, 0x0c7e, 0x1078, 0x3b33, 0x2c68, 0x0c7f, 0x007c,
+	0x0010, 0x2139, 0x0068, 0x2139, 0x2029, 0x0000, 0x78cb, 0x0000,
+	0x788c, 0xa065, 0x0040, 0x2132, 0x2009, 0x5074, 0x2104, 0xa084,
+	0x0001, 0x0040, 0x2100, 0x6004, 0xa086, 0x0103, 0x00c0, 0x2100,
+	0x6018, 0xa005, 0x00c0, 0x2100, 0x6014, 0xa005, 0x00c0, 0x2100,
+	0x0d7e, 0x2069, 0x0000, 0x6818, 0xa084, 0x0001, 0x00c0, 0x20ff,
+	0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001,
+	0x2091, 0x4080, 0x0d7f, 0x1078, 0x1c69, 0x0078, 0x2137, 0x0d7f,
+	0x1078, 0x213a, 0x0040, 0x2132, 0x6204, 0xa294, 0x00ff, 0xa296,
+	0x0003, 0x0040, 0x2112, 0x6204, 0xa296, 0x0110, 0x00c0, 0x2120,
+	0x78cb, 0x0001, 0x6204, 0xa294, 0xff00, 0x8217, 0x8211, 0x0040,
+	0x2120, 0x85ff, 0x00c0, 0x2132, 0x8210, 0xa202, 0x00c8, 0x2132,
+	0x057e, 0x1078, 0x2149, 0x057f, 0x0040, 0x212d, 0x78e0, 0xa086,
+	0x0003, 0x0040, 0x2132, 0x0078, 0x2120, 0x8528, 0x78c8, 0xa005,
+	0x0040, 0x20d0, 0x85ff, 0x0040, 0x2139, 0x2091, 0x4080, 0x78b0,
+	0x70d6, 0x007c, 0x7bac, 0x79b0, 0x70d4, 0xa102, 0x00c0, 0x2143,
+	0x2300, 0xa005, 0x007c, 0x0048, 0x2147, 0xa302, 0x007c, 0x8002,
+	0x007c, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x2163,
+	0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x2198,
+	0x7008, 0x7208, 0xa206, 0x00c0, 0x2198, 0xa286, 0x0008, 0x00c0,
+	0x2198, 0x2071, 0x0010, 0x1078, 0x219d, 0x2009, 0x0020, 0x6004,
+	0xa086, 0x0103, 0x00c0, 0x2172, 0x6028, 0xa005, 0x00c0, 0x2172,
+	0x2009, 0x000c, 0x1078, 0x1907, 0x0040, 0x218b, 0x78c4, 0x8000,
+	0x78c6, 0xa086, 0x0002, 0x00c0, 0x2198, 0x2091, 0x8000, 0x78e3,
+	0x0003, 0x78c7, 0x0000, 0x78cc, 0xa085, 0x0300, 0x78ce, 0x2091,
+	0x8001, 0x0078, 0x2198, 0x78c7, 0x0000, 0x1078, 0x1c69, 0x79ac,
+	0x78b0, 0x8000, 0xa10a, 0x00c8, 0x2196, 0xa006, 0x78b2, 0xa006,
+	0x2071, 0x0010, 0x2091, 0x8001, 0x007c, 0x8107, 0x8004, 0x8004,
+	0x7ab8, 0x7bb4, 0x7cc0, 0x7dbc, 0xa210, 0xa399, 0x0000, 0xa4a1,
+	0x0000, 0xa5a9, 0x0000, 0x007c, 0x2009, 0x505b, 0x2091, 0x8000,
+	0x200a, 0x0f7e, 0x0e7e, 0x2071, 0x5040, 0x7000, 0xa086, 0x0000,
+	0x00c0, 0x21cb, 0x2009, 0x5012, 0x2104, 0xa005, 0x00c0, 0x21cb,
+	0x2079, 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x21cb, 0x0018,
+	0x21cb, 0x781b, 0x004b, 0x0e7f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e,
+	0x2071, 0x5040, 0x2091, 0x8000, 0x7000, 0xa086, 0x0000, 0x00c0,
+	0x21e4, 0x2079, 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x21e4,
+	0x0018, 0x21e4, 0x781b, 0x004d, 0x2091, 0x8001, 0x0e7f, 0x0f7f,
+	0x007c, 0x127e, 0x2091, 0x2300, 0x2071, 0x5040, 0x2079, 0x0100,
+	0x784b, 0x000f, 0x0098, 0x21f7, 0x7838, 0x0078, 0x21f0, 0x20a9,
+	0x0040, 0x7800, 0xa082, 0x0004, 0x0048, 0x2200, 0x20a9, 0x0060,
+	0x789b, 0x0000, 0x78af, 0x0000, 0x78af, 0x0000, 0x0070, 0x220a,
+	0x0078, 0x2202, 0x7800, 0xa082, 0x0004, 0x0048, 0x2219, 0x70b7,
+	0x009b, 0x2019, 0x4da4, 0x1078, 0x2255, 0x702f, 0x8001, 0x0078,
+	0x2225, 0x70b7, 0x0000, 0x2019, 0x4c1c, 0x1078, 0x2255, 0x2019,
+	0x4c5b, 0x1078, 0x2255, 0x702f, 0x8000, 0x7003, 0x0000, 0x1078,
+	0x235e, 0x7004, 0xa084, 0x000f, 0x017e, 0x2009, 0x04fd, 0x210c,
+	0xa18a, 0x0005, 0x0048, 0x223a, 0x0038, 0x2240, 0xa085, 0x6280,
+	0x0078, 0x2242, 0x0028, 0x2240, 0xa085, 0x6280, 0x0078, 0x2242,
+	0xa085, 0x62c0, 0x017f, 0x7806, 0x780f, 0xb204, 0x7843, 0x00d8,
+	0x7853, 0x0080, 0x780b, 0x0008, 0x7047, 0x0008, 0x7053, 0x507f,
+	0x704f, 0x0000, 0x127f, 0x2000, 0x007c, 0x137e, 0x147e, 0x157e,
+	0x047e, 0x20a1, 0x012b, 0x2304, 0xa005, 0x789a, 0x0040, 0x2275,
+	0x8318, 0x2324, 0x8318, 0x2398, 0x24a8, 0xa484, 0xff00, 0x0040,
+	0x226d, 0xa482, 0x0100, 0x20a9, 0x0100, 0x2020, 0x53a6, 0xa005,
+	0x00c0, 0x2264, 0x3318, 0x0078, 0x225b, 0x047f, 0x157f, 0x147f,
+	0x137f, 0x007c, 0xa18c, 0x000f, 0x2011, 0x0101, 0x2204, 0xa084,
+	0xfff0, 0xa105, 0x2012, 0x1078, 0x235e, 0x007c, 0x2011, 0x0101,
+	0x20a9, 0x0009, 0x810b, 0x0070, 0x228f, 0x0078, 0x228a, 0xa18c,
+	0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2009,
+	0x0101, 0x20a9, 0x0005, 0x8213, 0x0070, 0x22a0, 0x0078, 0x229b,
+	0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x007c,
+	0x2011, 0x0101, 0x20a9, 0x000c, 0x810b, 0x0070, 0x22b1, 0x0078,
+	0x22ac, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012,
+	0x007c, 0x2011, 0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012,
+	0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100,
+	0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080,
+	0x0022, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0xa084, 0xffdf,
+	0x60ae, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e,
+	0x2061, 0x0100, 0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae, 0x0c7f,
+	0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100,
+	0x609a, 0x60a4, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x0c7f,
+	0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005, 0x0040,
+	0x233c, 0x2061, 0x7400, 0x1078, 0x2344, 0x0040, 0x2328, 0x20a9,
+	0x0000, 0x2061, 0x7300, 0x0c7e, 0x1078, 0x2344, 0x0040, 0x2318,
+	0x0c7f, 0x8c60, 0x0070, 0x2316, 0x0078, 0x230b, 0x0078, 0x233c,
+	0x007f, 0xa082, 0x7300, 0x2071, 0x5040, 0x7086, 0x7182, 0x2001,
+	0x0004, 0x706e, 0x7093, 0x000f, 0x1078, 0x21ac, 0x0078, 0x2338,
+	0x60c0, 0xa005, 0x00c0, 0x233c, 0x2071, 0x5040, 0x7182, 0x2c00,
+	0x708a, 0x2001, 0x0006, 0x706e, 0x7093, 0x000f, 0x1078, 0x21ac,
+	0x2001, 0x0000, 0x0078, 0x233e, 0x2001, 0x0001, 0x2091, 0x8001,
+	0xa005, 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005, 0x0040, 0x235b,
+	0x2060, 0x600c, 0xa306, 0x00c0, 0x2358, 0x6010, 0xa206, 0x00c0,
+	0x2358, 0x6014, 0xa106, 0x00c0, 0x2358, 0xa006, 0x0078, 0x235d,
+	0x6000, 0x0078, 0x2345, 0xa085, 0x0001, 0x007c, 0x2011, 0x5041,
+	0x220c, 0xa18c, 0x000f, 0x2011, 0x013b, 0x2204, 0xa084, 0x0100,
+	0x0040, 0x2374, 0x2021, 0xff04, 0x2122, 0x810b, 0x810b, 0x810b,
+	0x810b, 0xa18d, 0x0f00, 0x2104, 0x007c, 0x0e7e, 0x68e4, 0xa08c,
+	0x0020, 0x0040, 0x23c8, 0xa084, 0x0006, 0x00c0, 0x23c8, 0x6014,
+	0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0f0, 0x5280,
+	0x7004, 0xa084, 0x000a, 0x00c0, 0x23c8, 0x7108, 0xa194, 0xff00,
+	0x0040, 0x23c8, 0xa18c, 0x00ff, 0x2001, 0x000c, 0xa106, 0x0040,
+	0x23af, 0x2001, 0x0012, 0xa106, 0x0040, 0x23b3, 0x2001, 0x0014,
+	0xa106, 0x0040, 0x23b7, 0x2001, 0x0019, 0xa106, 0x0040, 0x23bb,
+	0x2001, 0x0032, 0xa106, 0x0040, 0x23bf, 0x0078, 0x23c3, 0x2009,
+	0x0012, 0x0078, 0x23c5, 0x2009, 0x0014, 0x0078, 0x23c5, 0x2009,
+	0x0019, 0x0078, 0x23c5, 0x2009, 0x0020, 0x0078, 0x23c5, 0x2009,
+	0x003f, 0x0078, 0x23c5, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a,
+	0x0e7f, 0x007c, 0x0068, 0x23ca, 0x2091, 0x8000, 0x2071, 0x0000,
+	0x007e, 0x7018, 0xa084, 0x0001, 0x00c0, 0x23d1, 0x007f, 0x2071,
+	0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x073f,
+	0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
+	0x0078, 0x23e8, 0x107e, 0x007e, 0x127e, 0x2091, 0x2300, 0x7f3c,
+	0x7e58, 0x7c30, 0x7d38, 0x77c2, 0x74c6, 0x76ca, 0x75ce, 0xa594,
+	0x003f, 0xa49c, 0x0003, 0xa484, 0x000f, 0x0079, 0x23ff, 0x2411,
+	0x2411, 0x2411, 0x274b, 0x3907, 0x240f, 0x2440, 0x244a, 0x240f,
+	0x240f, 0x240f, 0x240f, 0x240f, 0x240f, 0x240f, 0x240f, 0x1078,
+	0x23ca, 0x8507, 0xa084, 0x001f, 0x0079, 0x2416, 0x2454, 0x274b,
+	0x2905, 0x2a02, 0x2a2a, 0x2cc3, 0x2f6e, 0x2fb1, 0x2ffc, 0x3081,
+	0x3139, 0x31e2, 0x2440, 0x2827, 0x2f43, 0x2436, 0x3c78, 0x3c98,
+	0x3e5e, 0x3e6a, 0x3f3f, 0x2436, 0x2436, 0x4012, 0x4016, 0x3c76,
+	0x2436, 0x3dc9, 0x2436, 0x3b56, 0x244a, 0x2436, 0x1078, 0x23ca,
+	0x0018, 0x23ef, 0x127f, 0x2091, 0x8001, 0x007f, 0x107f, 0x007c,
+	0x2019, 0x4cfd, 0x1078, 0x2255, 0x702f, 0x0001, 0x781b, 0x004f,
+	0x0078, 0x2438, 0x2019, 0x4c5b, 0x1078, 0x2255, 0x702f, 0x8000,
+	0x781b, 0x00d5, 0x0078, 0x2438, 0x7242, 0x2009, 0x500f, 0x200b,
+	0x0000, 0xa584, 0x0001, 0x00c0, 0x3b6a, 0x0040, 0x2471, 0x1078,
+	0x23ca, 0x7003, 0x0000, 0x704b, 0x0000, 0x7043, 0x0000, 0x7037,
+	0x0000, 0x1078, 0x38de, 0x0018, 0x23ef, 0x2009, 0x500f, 0x200b,
+	0x0000, 0x7068, 0xa005, 0x00c0, 0x253c, 0x706c, 0xa084, 0x0007,
+	0x0079, 0x247a, 0x2573, 0x2482, 0x248e, 0x24ab, 0x24cd, 0x251a,
+	0x24f3, 0x2482, 0x1078, 0x38c6, 0x2009, 0x0048, 0x1078, 0x2e0f,
+	0x00c0, 0x248c, 0x7003, 0x0004, 0x0078, 0x2438, 0x1078, 0x38c6,
+	0x00c0, 0x24a9, 0x7080, 0x8007, 0x7882, 0x789b, 0x0010, 0x78ab,
+	0x000c, 0x789b, 0x0060, 0x78ab, 0x0001, 0x785b, 0x0004, 0x2009,
+	0x00e5, 0x1078, 0x2e03, 0x00c0, 0x24a9, 0x7003, 0x0004, 0x7093,
+	0x000f, 0x0078, 0x2438, 0x1078, 0x38c6, 0x00c0, 0x24cb, 0x7180,
+	0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d, 0x00c0,
+	0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab, 0x0002, 0x785b,
+	0x0004, 0x2009, 0x00e5, 0x1078, 0x2e03, 0x00c0, 0x24cb, 0x7003,
+	0x0004, 0x7093, 0x000f, 0x0078, 0x2438, 0x1078, 0x38c6, 0x00c0,
+	0x24f1, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f,
+	0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0020, 0x7184, 0x79aa, 0x78ab,
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 08'
echo 'File patch-2.2.7 is continued in part 09'
echo 09 > _shar_seq_.tmp
#!/bin/sh
# this is part 05 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 05; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
+    lp->tx_ring[entry].status = le16_to_cpu(0x8300);
X 
-	/* Trigger an immediate send poll. */
-	outw(0x0000, ioaddr+PCNET32_ADDR);
-	outw(0x0048, ioaddr+PCNET32_DATA);
+    lp->cur_tx++;
+    lp->stats.tx_bytes += skb->len;
X 
-	dev->trans_start = jiffies;
+    /* Trigger an immediate send poll. */
+    lp->a.write_csr (ioaddr, 0, 0x0048);
X 
-	if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0)
-		clear_bit (0, (void *)&dev->tbusy);
-	else
-		lp->tx_full = 1;
-	restore_flags(flags);
-	return 0;
+    dev->trans_start = jiffies;
+
+    if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0)
+	clear_bit (0, (void *)&dev->tbusy);
+    else
+	lp->tx_full = 1;
+    restore_flags(flags);
+    return 0;
X }
X 
X /* The PCNET32 interrupt handler. */
X static void
X pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
X {
-	struct device *dev = (struct device *)dev_id;
-	struct pcnet32_private *lp;
-	unsigned int csr0, ioaddr;
-	int boguscnt =  max_interrupt_work;
-	int must_restart;
-
-	if (dev == NULL) {
-		printk ("pcnet32_interrupt(): irq %d for unknown device.\n", irq);
-		return;
-	}
+    struct device *dev = (struct device *)dev_id;
+    struct pcnet32_private *lp;
+    unsigned long ioaddr;
+    u16 csr0;
+    int boguscnt =  max_interrupt_work;
+    int must_restart;
X 
-	ioaddr = dev->base_addr;
-	lp = (struct pcnet32_private *)dev->priv;
-	if (dev->interrupt)
-		printk("%s: Re-entering the interrupt handler.\n", dev->name);
+    if (dev == NULL) {
+	printk ("pcnet32_interrupt(): irq %d for unknown device.\n", irq);
+	return;
+    }
X 
-	dev->interrupt = 1;
+    ioaddr = dev->base_addr;
+    lp = (struct pcnet32_private *)dev->priv;
+    if (dev->interrupt)
+	printk("%s: Re-entering the interrupt handler.\n", dev->name);
X 
-	outw(0x00, dev->base_addr + PCNET32_ADDR);
-	while ((csr0 = inw(dev->base_addr + PCNET32_DATA)) & 0x8600 && --boguscnt >= 0) {
-		/* Acknowledge all of the current interrupt sources ASAP. */
-		outw(csr0 & ~0x004f, dev->base_addr + PCNET32_DATA);
+    dev->interrupt = 1;
X 
-		must_restart = 0;
+    while ((csr0 = lp->a.read_csr (ioaddr, 0)) & 0x8600 && --boguscnt >= 0) {
+	/* Acknowledge all of the current interrupt sources ASAP. */
+	lp->a.write_csr (ioaddr, 0, csr0 & ~0x004f);
X 
-		if (pcnet32_debug > 5)
-			printk("%s: interrupt  csr0=%#2.2x new csr=%#2.2x.\n",
-				   dev->name, csr0, inw(dev->base_addr + PCNET32_DATA));
+	must_restart = 0;
X 
-		if (csr0 & 0x0400)			/* Rx interrupt */
-			pcnet32_rx(dev);
+	if (pcnet32_debug > 5)
+	    printk("%s: interrupt  csr0=%#2.2x new csr=%#2.2x.\n",
+		   dev->name, csr0, lp->a.read_csr (ioaddr, 0));
X 
-		if (csr0 & 0x0200) {		/* Tx-done interrupt */
-			int dirty_tx = lp->dirty_tx;
+	if (csr0 & 0x0400)		/* Rx interrupt */
+	    pcnet32_rx(dev);
X 
-			while (dirty_tx < lp->cur_tx) {
-				int entry = dirty_tx & TX_RING_MOD_MASK;
-				int status = (short)le16_to_cpu(lp->tx_ring[entry].status);
+	if (csr0 & 0x0200) {		/* Tx-done interrupt */
+	    int dirty_tx = lp->dirty_tx;
+
+	    while (dirty_tx < lp->cur_tx) {
+		int entry = dirty_tx & TX_RING_MOD_MASK;
+		int status = (short)le16_to_cpu(lp->tx_ring[entry].status);
X 			
-				if (status < 0)
-					break;			/* It still hasn't been Txed */
+		if (status < 0)
+		    break;		/* It still hasn't been Txed */
X 
-				lp->tx_ring[entry].base = 0;
+		lp->tx_ring[entry].base = 0;
X 
-				if (status & 0x4000) {
-					/* There was an major error, log it. */
-					int err_status = le32_to_cpu(lp->tx_ring[entry].misc);
-					lp->stats.tx_errors++;
-					if (err_status & 0x04000000) lp->stats.tx_aborted_errors++;
-					if (err_status & 0x08000000) lp->stats.tx_carrier_errors++;
-					if (err_status & 0x10000000) lp->stats.tx_window_errors++;
-					if (err_status & 0x40000000) {
-						/* Ackk!  On FIFO errors the Tx unit is turned off! */
-						lp->stats.tx_fifo_errors++;
-						/* Remove this verbosity later! */
-						printk("%s: Tx FIFO error! Status %4.4x.\n",
-							   dev->name, csr0);
-						must_restart = 1;
+		if (status & 0x4000) {
+		    /* There was an major error, log it. */
+		    int err_status = le32_to_cpu(lp->tx_ring[entry].misc);
+		    lp->stats.tx_errors++;
+		    if (err_status & 0x04000000) lp->stats.tx_aborted_errors++;
+		    if (err_status & 0x08000000) lp->stats.tx_carrier_errors++;
+		    if (err_status & 0x10000000) lp->stats.tx_window_errors++;
+		    if (err_status & 0x40000000) {
+			/* Ackk!  On FIFO errors the Tx unit is turned off! */
+			lp->stats.tx_fifo_errors++;
+			/* Remove this verbosity later! */
+			printk("%s: Tx FIFO error! Status %4.4x.\n",
+			       dev->name, csr0);
+			must_restart = 1;
X 					}
-				} else {
-					if (status & 0x1800)
-						lp->stats.collisions++;
-					lp->stats.tx_packets++;
-				}
-
-				/* We must free the original skb */
-				if (lp->tx_skbuff[entry]) {
-					dev_kfree_skb(lp->tx_skbuff[entry]);
-					lp->tx_skbuff[entry] = 0;
-				}
-				dirty_tx++;
-			}
+		} else {
+		    if (status & 0x1800)
+			lp->stats.collisions++;
+		    lp->stats.tx_packets++;
+		}
+
+		/* We must free the original skb */
+		if (lp->tx_skbuff[entry]) {
+		    dev_kfree_skb(lp->tx_skbuff[entry]);
+		    lp->tx_skbuff[entry] = 0;
+		}
+		dirty_tx++;
+	    }
X 
X #ifndef final_version
-			if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
-				printk("out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
-					   dirty_tx, lp->cur_tx, lp->tx_full);
-				dirty_tx += TX_RING_SIZE;
-			}
+	    if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
+		printk("out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
+		       dirty_tx, lp->cur_tx, lp->tx_full);
+		dirty_tx += TX_RING_SIZE;
+	    }
X #endif
+	    if (lp->tx_full && dev->tbusy
+		&& dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
+		/* The ring is no longer full, clear tbusy. */
+		lp->tx_full = 0;
+		clear_bit(0, (void *)&dev->tbusy);
+		mark_bh(NET_BH);
+	    }
+	    lp->dirty_tx = dirty_tx;
+	}
X 
-			if (lp->tx_full && dev->tbusy
-				&& dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
-				/* The ring is no longer full, clear tbusy. */
-				lp->tx_full = 0;
-				clear_bit(0, (void *)&dev->tbusy);
-				mark_bh(NET_BH);
-			}
-			lp->dirty_tx = dirty_tx;
-		}
-
-		/* Log misc errors. */
-		if (csr0 & 0x4000) lp->stats.tx_errors++; /* Tx babble. */
-		if (csr0 & 0x1000) {
-		    /*
-		     * this happens when our receive ring is full. This shouldn't
-		     * be a problem as we will see normal rx interrupts for the frames
-		     * in the receive ring. But there are some PCI chipsets (I can reproduce
-		     * this on SP3G with Intel saturn chipset) which have sometimes problems
-		     * and will fill up the receive ring with error descriptors. In this
-		     * situation we don't get a rx interrupt, but a missed frame interrupt sooner
-		     * or later. So we try to clean up our receive ring here.
-		     */
-		    pcnet32_rx(dev);
-		    lp->stats.rx_errors++; /* Missed a Rx frame. */
-		}
-		if (csr0 & 0x0800) {
-			printk("%s: Bus master arbitration failure, status %4.4x.\n",
-				   dev->name, csr0);
-		        /* unlike for the lance, there is no restart needed */
-		}
+	/* Log misc errors. */
+	if (csr0 & 0x4000) lp->stats.tx_errors++; /* Tx babble. */
+	if (csr0 & 0x1000) {
+	    /*
+	     * this happens when our receive ring is full. This shouldn't
+	     * be a problem as we will see normal rx interrupts for the frames
+	     * in the receive ring. But there are some PCI chipsets (I can reproduce
+	     * this on SP3G with Intel saturn chipset) which have sometimes problems
+	     * and will fill up the receive ring with error descriptors. In this
+	     * situation we don't get a rx interrupt, but a missed frame interrupt sooner
+	     * or later. So we try to clean up our receive ring here.
+	     */
+	    pcnet32_rx(dev);
+	    lp->stats.rx_errors++; /* Missed a Rx frame. */
+	}
+	if (csr0 & 0x0800) {
+	    printk("%s: Bus master arbitration failure, status %4.4x.\n",
+		   dev->name, csr0);
+	    /* unlike for the lance, there is no restart needed */
+	}
X 
-		if (must_restart) {
-			/* stop the chip to clear the error condition, then restart */
-		        outw(0x0000, dev->base_addr + PCNET32_ADDR);
-		        outw(0x0004, dev->base_addr + PCNET32_DATA);
-		        pcnet32_restart(dev, 0x0002);
-		}
+	if (must_restart) {
+	    /* stop the chip to clear the error condition, then restart */
+	    lp->a.write_csr (ioaddr, 0, 0x0004);
+	    pcnet32_restart(dev, 0x0002);
X 	}
+    }
X 
X     /* Clear any other interrupt, and set interrupt enable. */
-    outw(0x0000, dev->base_addr + PCNET32_ADDR);
-    outw(0x7940, dev->base_addr + PCNET32_DATA);
+    lp->a.write_csr (ioaddr, 0, 0x7940);
X 
-	if (pcnet32_debug > 4)
-		printk("%s: exiting interrupt, csr%d=%#4.4x.\n",
-			   dev->name, inw(ioaddr + PCNET32_ADDR),
-			   inw(dev->base_addr + PCNET32_DATA));
+    if (pcnet32_debug > 4)
+	printk("%s: exiting interrupt, csr0=%#4.4x.\n",
+	       dev->name, lp->a.read_csr (ioaddr, 0));
X 
-	dev->interrupt = 0;
- return;
+    dev->interrupt = 0;
+ return;
X }
X 
X static int
X pcnet32_rx(struct device *dev)
X {
-	struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
-	int entry = lp->cur_rx & RX_RING_MOD_MASK;
-	int i;
-
-	/* If we own the next entry, it's a new packet. Send it up. */
-	while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) {
-		int status = (short)le16_to_cpu(lp->rx_ring[entry].status) >> 8;
-
-		if (status != 0x03) {			/* There was an error. */
-			/* There is a tricky error noted by John Murphy,
-			   <mu...@perftech.com> to Russ Nelson: Even with full-sized
-			   buffers it's possible for a jabber packet to use two
-			   buffers, with only the last correctly noting the error. */
-			if (status & 0x01)	/* Only count a general error at the */
-				lp->stats.rx_errors++; /* end of a packet.*/
-			if (status & 0x20) lp->stats.rx_frame_errors++;
-			if (status & 0x10) lp->stats.rx_over_errors++;
-			if (status & 0x08) lp->stats.rx_crc_errors++;
-			if (status & 0x04) lp->stats.rx_fifo_errors++;
-			lp->rx_ring[entry].status &= le16_to_cpu(0x03ff);
-		}
-		else 
-		{
-			/* Malloc up new buffer, compatible with net-2e. */
-			short pkt_len = (le32_to_cpu(lp->rx_ring[entry].msg_length) & 0xfff)-4;
-			struct sk_buff *skb;
+    struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
+    int entry = lp->cur_rx & RX_RING_MOD_MASK;
+    int i;
+
+    /* If we own the next entry, it's a new packet. Send it up. */
+    while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) {
+	int status = (short)le16_to_cpu(lp->rx_ring[entry].status) >> 8;
+
+	if (status != 0x03) {			/* There was an error. */
+	    /* 
+	     * There is a tricky error noted by John Murphy,
+	     * <mu...@perftech.com> to Russ Nelson: Even with full-sized
+	     * buffers it's possible for a jabber packet to use two
+	     * buffers, with only the last correctly noting the error.
+	     */
+	    if (status & 0x01)	/* Only count a general error at the */
+		lp->stats.rx_errors++; /* end of a packet.*/
+	    if (status & 0x20) lp->stats.rx_frame_errors++;
+	    if (status & 0x10) lp->stats.rx_over_errors++;
+	    if (status & 0x08) lp->stats.rx_crc_errors++;
+	    if (status & 0x04) lp->stats.rx_fifo_errors++;
+	    lp->rx_ring[entry].status &= le16_to_cpu(0x03ff);
+	} else {
+	    /* Malloc up new buffer, compatible with net-2e. */
+	    short pkt_len = (le32_to_cpu(lp->rx_ring[entry].msg_length) & 0xfff)-4;
+	    struct sk_buff *skb;
X 			
-			if(pkt_len < 60) {
-				printk("%s: Runt packet!\n",dev->name);
-				lp->stats.rx_errors++;
-			} else {
-			    int rx_in_place = 0;
+	    if(pkt_len < 60) {
+		printk("%s: Runt packet!\n",dev->name);
+		lp->stats.rx_errors++;
+	    } else {
+		int rx_in_place = 0;
X 			    
-			    if (pkt_len > rx_copybreak) {
-				struct sk_buff *newskb;
+		if (pkt_len > rx_copybreak) {
+		    struct sk_buff *newskb;
X 				
-				if ((newskb = dev_alloc_skb (PKT_BUF_SZ))) {
-				    skb_reserve (newskb, 2);
-				    skb = lp->rx_skbuff[entry];
-				    skb_put (skb, pkt_len);
-				    lp->rx_skbuff[entry] = newskb;
-				    newskb->dev = dev;
-				    lp->rx_ring[entry].base = le32_to_cpu(virt_to_bus(newskb->tail));
-				    rx_in_place = 1;
-				} else
-				    skb = NULL;
-			    } else
-				skb = dev_alloc_skb(pkt_len+2);
+		    if ((newskb = dev_alloc_skb (PKT_BUF_SZ))) {
+			skb_reserve (newskb, 2);
+			skb = lp->rx_skbuff[entry];
+			skb_put (skb, pkt_len);
+			lp->rx_skbuff[entry] = newskb;
+			newskb->dev = dev;
+			lp->rx_ring[entry].base = le32_to_cpu(virt_to_bus(newskb->tail));
+			rx_in_place = 1;
+		    } else
+			skb = NULL;
+		} else
+		    skb = dev_alloc_skb(pkt_len+2);
X 			    
-			    if (skb == NULL) {
-				printk("%s: Memory squeeze, deferring packet.\n", dev->name);
-				for (i=0; i < RX_RING_SIZE; i++)
-				    if ((short)le16_to_cpu(lp->rx_ring[(entry+i) & RX_RING_MOD_MASK].status) < 0)
-					break;
-
-				if (i > RX_RING_SIZE -2) {
-				    lp->stats.rx_dropped++;
-				    lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
-				    lp->cur_rx++;
-				}
-				break;
-			    }
-			    skb->dev = dev;
-			    if (!rx_in_place) {
-				skb_reserve(skb,2);	/* 16 byte align */
-				skb_put(skb,pkt_len);	/* Make room */
-				eth_copy_and_sum(skb,
-					(unsigned char *)bus_to_virt(le32_to_cpu(lp->rx_ring[entry].base)),
-					pkt_len,0);
-			    }
-			    lp->stats.rx_bytes += skb->len;
-			    skb->protocol=eth_type_trans(skb,dev);
-			    netif_rx(skb);
-			    lp->stats.rx_packets++;
-			}
+		if (skb == NULL) {
+		    printk("%s: Memory squeeze, deferring packet.\n", dev->name);
+		    for (i=0; i < RX_RING_SIZE; i++)
+			if ((short)le16_to_cpu(lp->rx_ring[(entry+i) & RX_RING_MOD_MASK].status) < 0)
+			    break;
+
+		    if (i > RX_RING_SIZE -2) {
+			lp->stats.rx_dropped++;
+			lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
+			lp->cur_rx++;
+		    }
+		    break;
X 		}
-		/* The docs say that the buffer length isn't touched, but Andrew Boyd
-		   of QNX reports that some revs of the 79C965 clear it. */
-		lp->rx_ring[entry].buf_length = le16_to_cpu(-PKT_BUF_SZ);
-		lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
-		entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
+		skb->dev = dev;
+		if (!rx_in_place) {
+		    skb_reserve(skb,2);	/* 16 byte align */
+		    skb_put(skb,pkt_len);	/* Make room */
+		    eth_copy_and_sum(skb,
+				     (unsigned char *)bus_to_virt(le32_to_cpu(lp->rx_ring[entry].base)),
+				     pkt_len,0);
+		}
+		lp->stats.rx_bytes += skb->len;
+		skb->protocol=eth_type_trans(skb,dev);
+		netif_rx(skb);
+		lp->stats.rx_packets++;
+	    }
X 	}
+	/*
+	 * The docs say that the buffer length isn't touched, but Andrew Boyd
+	 * of QNX reports that some revs of the 79C965 clear it.
+	 */
+	lp->rx_ring[entry].buf_length = le16_to_cpu(-PKT_BUF_SZ);
+	lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
+	entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
+    }
X 
-	/* We should check that at least two ring entries are free.	 If not,
-	   we should free one and mark stats->rx_dropped++. */
-
-	return 0;
+    return 0;
X }
X 
X static int
X pcnet32_close(struct device *dev)
X {
-	unsigned int ioaddr = dev->base_addr;
-	struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
-        int i;
-
-	dev->start = 0;
-	set_bit (0, (void *)&dev->tbusy);
-
-	outw(112, ioaddr+PCNET32_ADDR);
-	lp->stats.rx_missed_errors = inw(ioaddr+PCNET32_DATA);
-
-	outw(0, ioaddr+PCNET32_ADDR);
-
-	if (pcnet32_debug > 1)
- printk("%s: Shutting down ethercard, status was %2.2x.\n",
-			   dev->name, inw(ioaddr+PCNET32_DATA));
-
-	/* We stop the PCNET32 here -- it occasionally polls
-	   memory if we don't. */
-	outw(0x0004, ioaddr+PCNET32_DATA);
-
-	free_irq(dev->irq, dev);
-    
-        /* free all allocated skbuffs */
-        for (i = 0; i < RX_RING_SIZE; i++) {
-	    lp->rx_ring[i].status = 0;	    	    	    
-	    if (lp->rx_skbuff[i])
-		dev_kfree_skb(lp->rx_skbuff[i]);
-	    lp->rx_skbuff[i] = NULL;
-	}
+    unsigned long ioaddr = dev->base_addr;
+    struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
+    int i;
+
+    dev->start = 0;
+    set_bit (0, (void *)&dev->tbusy);
+
+    lp->stats.rx_missed_errors = lp->a.read_csr (ioaddr, 112);
+
+    if (pcnet32_debug > 1)
+ printk("%s: Shutting down ethercard, status was %2.2x.\n",
+	       dev->name, lp->a.read_csr (ioaddr, 0));
+
+    /* We stop the PCNET32 here -- it occasionally polls memory if we don't. */
+    lp->a.write_csr (ioaddr, 0, 0x0004);
+
+    /*
+     * Switch back to 16bit mode to avoid problems with dumb 
+     * DOS packet driver after a warm reboot
+     */
+    lp->a.write_bcr (ioaddr, 20, 4);
+
+    free_irq(dev->irq, dev);
+    
+    /* free all allocated skbuffs */
+    for (i = 0; i < RX_RING_SIZE; i++) {
+	lp->rx_ring[i].status = 0;	    	    	    
+	if (lp->rx_skbuff[i])
+	    dev_kfree_skb(lp->rx_skbuff[i]);
+	lp->rx_skbuff[i] = NULL;
+    }
X     
-        for (i = 0; i < TX_RING_SIZE; i++) {
-	    if (lp->tx_skbuff[i])
-		dev_kfree_skb(lp->tx_skbuff[i]);
- lp->rx_skbuff[i] = NULL;
-	}
+    for (i = 0; i < TX_RING_SIZE; i++) {
+	if (lp->tx_skbuff[i])
+	    dev_kfree_skb(lp->tx_skbuff[i]);
+	lp->rx_skbuff[i] = NULL;
+    }
X     
-        MOD_DEC_USE_COUNT;
+    MOD_DEC_USE_COUNT;
X 
-	return 0;
+    return 0;
X }
X 
X static struct net_device_stats *
X pcnet32_get_stats(struct device *dev)
X {
-	struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
-	unsigned int ioaddr = dev->base_addr;
- unsigned short saved_addr;
-	unsigned long flags;
-
-	save_flags(flags);
-	cli();
-	saved_addr = inw(ioaddr+PCNET32_ADDR);
-	outw(112, ioaddr+PCNET32_ADDR);
-	lp->stats.rx_missed_errors = inw(ioaddr+PCNET32_DATA);
-	outw(saved_addr, ioaddr+PCNET32_ADDR);
-	restore_flags(flags);
+    struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;
+    unsigned long ioaddr = dev->base_addr;
+ u16 saved_addr;
+    unsigned long flags;
+
+    save_flags(flags);
+    cli();
+    saved_addr = lp->a.read_rap(ioaddr);
+    lp->stats.rx_missed_errors = lp->a.read_csr (ioaddr, 112);
+    lp->a.write_rap(ioaddr, saved_addr);
+    restore_flags(flags);
X 
-	return &lp->stats;
+    return &lp->stats;
X }
X 
-
X /* taken from the sunlance driver, which it took from the depca driver */
X static void pcnet32_load_multicast (struct device *dev)
X {
@@ -1044,34 +1283,68 @@
X }
X 
X 
-/* Set or clear the multicast filter for this adaptor.
+/*
+ * Set or clear the multicast filter for this adaptor.
X  */
-
X static void pcnet32_set_multicast_list(struct device *dev)
X {
-	unsigned int ioaddr = dev->base_addr;
-	struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;    
+    unsigned long ioaddr = dev->base_addr;
+    struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;    
X 
-	if (dev->flags&IFF_PROMISC) {
-		/* Log any net taps. */
-		printk("%s: Promiscuous mode enabled.\n", dev->name);
-	        lp->init_block.mode = le16_to_cpu(0x8000 | (lp->options & PORT_PORTSEL) << 7);
-	} else {
-	    	lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7);
-	        pcnet32_load_multicast (dev);
-	}
+    if (dev->flags&IFF_PROMISC) {
+	/* Log any net taps. */
+	printk("%s: Promiscuous mode enabled.\n", dev->name);
+	lp->init_block.mode = le16_to_cpu(0x8000 | (lp->options & PORT_PORTSEL) << 7);
+    } else {
+	lp->init_block.mode = le16_to_cpu((lp->options & PORT_PORTSEL) << 7);
+	pcnet32_load_multicast (dev);
+    }
X     
-	outw(0, ioaddr+PCNET32_ADDR);
-	outw(0x0004, ioaddr+PCNET32_DATA); /* Temporarily stop the lance.	 */
+    lp->a.write_csr (ioaddr, 0, 0x0004); /* Temporarily stop the lance. */
X 
-	pcnet32_restart(dev, 0x0042); /*  Resume normal operation */
+    pcnet32_restart(dev, 0x0042); /*  Resume normal operation */
X }
X 
+#ifdef HAVE_PRIVATE_IOCTL
+static int pcnet32_mii_ioctl(struct device *dev, struct ifreq *rq, int cmd)
+{
+    unsigned long ioaddr = dev->base_addr;
+    struct pcnet32_private *lp = (struct pcnet32_private *)dev->priv;    
+    u16 *data = (u16 *)&rq->ifr_data;
+    int phyaddr = lp->a.read_bcr (ioaddr, 33);
+
+    if (lp->mii) {
+	switch(cmd) {
+	 case SIOCDEVPRIVATE:            /* Get the address of the PHY in use. */
+	    data[0] = (phyaddr >> 5) & 0x1f;
+	    /* Fall Through */
+	 case SIOCDEVPRIVATE+1:          /* Read the specified MII register. */
+	    lp->a.write_bcr (ioaddr, 33, ((data[0] & 0x1f) << 5) | (data[1] & 0x1f));
+	    data[3] = lp->a.read_bcr (ioaddr, 34);
+	    lp->a.write_bcr (ioaddr, 33, phyaddr);
+	    return 0;
+	 case SIOCDEVPRIVATE+2:          /* Write the specified MII register */
+	    if (!suser())
+		return -EPERM;
+	    lp->a.write_bcr (ioaddr, 33, ((data[0] & 0x1f) << 5) | (data[1] & 0x1f));
+	    lp->a.write_bcr (ioaddr, 34, data[2]);
+	    lp->a.write_bcr (ioaddr, 33, phyaddr);
+	    return 0;
+	 default:
+	    return -EOPNOTSUPP;
+	}
+    }
+    return -EOPNOTSUPP;
+}
+#endif  /* HAVE_PRIVATE_IOCTL */
+					    
X #ifdef MODULE
X MODULE_PARM(debug, "i");
-MODULE_PARM(options, "i");
X MODULE_PARM(max_interrupt_work, "i");
X MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+					     
X 
X /* An additional parameter that may be passed in... */
X static int debug = -1;
@@ -1079,27 +1352,27 @@
X int
X init_module(void)
X {
-        if (debug > 0)
-	        pcnet32_debug = debug;
+    if (debug > 0)
+	pcnet32_debug = debug;
X     
-	pcnet32_dev = NULL;
-	return pcnet32_probe(NULL);
+    pcnet32_dev = NULL;
+    return pcnet32_probe(NULL);
X }
X 
X void
X cleanup_module(void)
X {
-	struct device *next_dev;
+    struct device *next_dev;
X 
-	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
-	while (pcnet32_dev) {
-		next_dev = ((struct pcnet32_private *) pcnet32_dev->priv)->next;
-		unregister_netdev(pcnet32_dev);
-		release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
-	        kfree(pcnet32_dev->priv);
-		kfree(pcnet32_dev);
-		pcnet32_dev = next_dev;
-	}
+    /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+    while (pcnet32_dev) {
+	next_dev = ((struct pcnet32_private *) pcnet32_dev->priv)->next;
+	unregister_netdev(pcnet32_dev);
+	release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
+	kfree(((struct pcnet32_private *)pcnet32_dev->priv)->origmem);
+	kfree(pcnet32_dev);
+	pcnet32_dev = next_dev;
+    }
X }
X #endif /* MODULE */
X 
diff -u --recursive --new-file v2.2.6/linux/drivers/net/ppp.c linux/drivers/net/ppp.c
--- v2.2.6/linux/drivers/net/ppp.c	Tue Mar 23 14:35:48 1999
+++ linux/drivers/net/ppp.c	Tue Apr 27 00:38:27 1999
@@ -4,7 +4,7 @@
X  *  Al Longyear <long...@netcom.com>
X  *  Extensively rewritten by Paul Mackerras <pau...@cs.anu.edu.au>
X  *
- *  ==FILEVERSION 990114==
+ *  ==FILEVERSION 990331==
X  *
X  *  NOTE TO MAINTAINERS:
X  *     If you modify this file at all, please set the number above to the
@@ -45,9 +45,8 @@
X 
X #define PPP_MAX_RCV_QLEN	32	/* max # frames we queue up for pppd */
X 
-/* $Id: ppp.c,v 1.19 1998/07/07 04:27:37 paulus Exp $ */
+/* $Id: ppp.c,v 1.24 1999/03/31 06:07:57 paulus Exp $ */
X 
-#include <linux/version.h>
X #include <linux/config.h>
X #include <linux/module.h>
X #include <linux/kernel.h>
@@ -61,6 +60,7 @@
X #include <linux/malloc.h>
X #include <linux/tty.h>
X #include <linux/errno.h>
+#include <linux/sched.h>	/* to get the struct task_struct */
X #include <linux/string.h>	/* used in new tty drivers */
X #include <linux/signal.h>	/* used in new tty drivers */
X #include <asm/system.h>
@@ -90,6 +90,9 @@
X #include <linux/kmod.h>
X #endif
X 
+typedef ssize_t		rw_ret_t;
+typedef size_t		rw_count_t;
+
X /*
X  * Local functions
X  */
@@ -101,9 +104,11 @@
X 
X static void ppp_async_init(struct ppp *ppp);
X static void ppp_async_release(struct ppp *ppp);
+static int ppp_tty_sync_push(struct ppp *ppp);
X static int ppp_tty_push(struct ppp *ppp);
X static int ppp_async_encode(struct ppp *ppp);
X static int ppp_async_send(struct ppp *, struct sk_buff *);
+static int ppp_sync_send(struct ppp *, struct sk_buff *);
X 
X static int ppp_ioctl(struct ppp *, unsigned int, unsigned long);
X static int ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp);
@@ -186,10 +191,10 @@
X  * TTY callbacks
X  */
X 
-static ssize_t ppp_tty_read(struct tty_struct *, struct file *, __u8 *,
-			    size_t);
-static ssize_t ppp_tty_write(struct tty_struct *, struct file *, const __u8 *,
-			     size_t);
+static rw_ret_t ppp_tty_read(struct tty_struct *, struct file *, __u8 *,
+			     rw_count_t);
+static rw_ret_t ppp_tty_write(struct tty_struct *, struct file *, const __u8 *,
+			      rw_count_t);
X static int ppp_tty_ioctl(struct tty_struct *, struct file *, unsigned int,
X 			 unsigned long);
X static unsigned int ppp_tty_poll(struct tty_struct *tty, struct file *filp,
@@ -236,7 +241,6 @@
X 	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
X 	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
X };
-EXPORT_SYMBOL(ppp_crc16_table);
X 
X #ifdef CHECK_CHARACTERS
X static __u32 paritytab[8] =
@@ -458,13 +462,13 @@
X  * Read a PPP frame from the rcv_q list,
X  * waiting if necessary
X  */
-static ssize_t
+static rw_ret_t
X ppp_tty_read(struct tty_struct *tty, struct file *file, __u8 * buf,
-	     size_t nr)
+	     rw_count_t nr)
X {
X 	struct ppp *ppp = tty2ppp (tty);
X 	struct sk_buff *skb;
-	ssize_t len, err;
+	rw_ret_t len, err;
X 
X 	/*
X 	 * Validate the pointers
@@ -546,9 +550,9 @@
X  * Writing to a tty in ppp line discipline sends a PPP frame.
X  * Used by pppd to send control packets (LCP, etc.).
X  */
-static ssize_t
+static rw_ret_t
X ppp_tty_write(struct tty_struct *tty, struct file *file, const __u8 * data,
-	      size_t count)
+	      rw_count_t count)
X {
X 	struct ppp *ppp = tty2ppp (tty);
X 	__u8 *new_data;
@@ -600,7 +604,7 @@
X 	 */
X 	ppp_send_ctrl(ppp, skb);
X 
-	return (ssize_t) count;
+	return (rw_ret_t) count;
X }
X 
X /*
@@ -799,6 +803,135 @@
X }
X 
X /*
+ * Send a packet to the peer over a synchronous tty line.
+ * All encoding and FCS are handled by hardware.
+ * Addr/Ctrl and Protocol field compression implemented.
+ * Returns -1 iff the packet could not be accepted at present,
+ * 0 if the packet was accepted but we can't accept another yet, or
+ * 1 if we can accept another packet immediately.
+ * If this procedure returns 0, ppp_output_wakeup will be called
+ * exactly once.
+ */
+static int
+ppp_sync_send(struct ppp *ppp, struct sk_buff *skb)
+{
+	unsigned char *data;
+	int islcp;
+	
+	CHECK_PPP(0);
+
+	if (ppp->tpkt != NULL)
+		return -1;
+	ppp->tpkt = skb;
+
+	data = ppp->tpkt->data;
+	
+	/*
+	 * LCP packets with code values between 1 (configure-reqest)
+	 * and 7 (code-reject) must be sent as though no options
+	 * had been negotiated.
+	 */
+	islcp = PPP_PROTOCOL(data) == PPP_LCP
+		&& 1 <= data[PPP_HDRLEN] && data[PPP_HDRLEN] <= 7;
+
+	/* only reset idle time for data packets */
+	if (PPP_PROTOCOL(data) < 0x8000)
+		ppp->last_xmit = jiffies;
+	++ppp->stats.ppp_opackets;
+	ppp->stats.ppp_ooctects += ppp->tpkt->len;
+
+	if ( !(data[2]) && (ppp->flags & SC_COMP_PROT) ) {
+		/* compress protocol field */
+		data[2] = data[1];
+		data[1] = data[0];
+		skb_pull(ppp->tpkt,1);
+		data = ppp->tpkt->data;
+	}
+	
+	/*
+	 * Do address/control compression
+	 */
+	if ((ppp->flags & SC_COMP_AC) && !islcp
+	    && PPP_ADDRESS(data) == PPP_ALLSTATIONS
+	    && PPP_CONTROL(data) == PPP_UI) {
+		/* strip addr and control field */
+		skb_pull(ppp->tpkt,2);
+	}
+
+	return ppp_tty_sync_push(ppp);
+}
+
+/*
+ * Push a synchronous frame out to the tty.
+ * Returns 1 if frame accepted (or discarded), 0 otherwise.
+ */
+static int
+ppp_tty_sync_push(struct ppp *ppp)
+{
+	int sent;
+	struct tty_struct *tty = ppp2tty(ppp);
+	unsigned long flags;
+		
+	CHECK_PPP(0);
+
+	if (ppp->tpkt == NULL)
+		return 0;
+		
+	/* prevent reentrancy with tty_pushing flag */		
+	save_flags(flags);
+	cli();
+	if (ppp->tty_pushing) {
+		/* record wakeup attempt so we don't loose */
+		/* a wakeup call while doing push processing */
+		ppp->woke_up=1;
+		restore_flags(flags);
+		return 0;
+	}
+	ppp->tty_pushing = 1;
+	restore_flags(flags);
+	
+	if (tty == NULL || tty->disc_data != (void *) ppp)
+		goto flush;
+		
+	for(;;){
+		ppp->woke_up=0;
+		
+		/* Note: Sync driver accepts complete frame or nothing */
+		tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
+		sent = tty->driver.write(tty, 0, ppp->tpkt->data, ppp->tpkt->len);
+		if (sent < 0) {
+			/* write error (possible loss of CD) */
+			/* record error and discard current packet */
+			ppp->stats.ppp_oerrors++;
+			break;
+		}
+		ppp->stats.ppp_obytes += sent;
+		if (sent < ppp->tpkt->len) {
+			/* driver unable to accept frame just yet */
+			save_flags(flags);
+			cli();
+			if (ppp->woke_up) {
+				/* wake up called while processing */
+				/* try to send the frame again */
+				restore_flags(flags);
+				continue;
+			}
+			/* wait for wakeup callback to try send again */
+			ppp->tty_pushing = 0;
+			restore_flags(flags);
+			return 0;
+		}
+		break;
+	}
+flush:	
+	/* done with current packet (sent or discarded) */
+	kfree_skb(ppp->tpkt);
+	ppp->tpkt = 0;
+	ppp->tty_pushing = 0;
+	return 1;
+}
+
+/*
X  * Send a packet to the peer over an async tty line.
X  * Returns -1 iff the packet could not be accepted at present,
X  * 0 if the packet was accepted but we can't accept another yet, or
@@ -830,6 +963,9 @@
X {
X 	int avail, sent, done = 0;
X 	struct tty_struct *tty = ppp2tty(ppp);
+	
+	if ( ppp->flags & SC_SYNC ) 
+		return ppp_tty_sync_push(ppp);
X 
X 	CHECK_PPP(0);
X 	if (ppp->tty_pushing)
@@ -1028,6 +1164,73 @@
X 
X 	ppp->stats.ppp_ibytes += count;
X 	skb = ppp->rpkt;
+	
+	if ( ppp->flags & SC_SYNC ) {
+		/* synchronous mode */
+		
+		if (ppp->toss==0xE0) {
+			/* this is the 1st frame, reset vj comp */
+			ppp_receive_error(ppp);
+			ppp->toss = 0;
+		}
+		
+		/*
+		 * Allocate an skbuff for frame.
+		 * The 128 is room for VJ header expansion.
+		 */
+		
+		if (skb == NULL)
+			skb = dev_alloc_skb(ppp->mru + 128 + PPP_HDRLEN);
+			
+		if (skb == NULL) {
+			if (ppp->flags & SC_DEBUG)
+				printk(KERN_DEBUG "couldn't "
+				       "alloc skb for recv\n");
+		} else {
+			/*
+			 * Decompress A/C and protocol compression here.
+			 */
+			p = skb_put(skb, 2);
+			p[0] = PPP_ALLSTATIONS;
+			p[1] = PPP_UI;
+			if (*data == PPP_ALLSTATIONS) {
+				data += 2;
+				count -= 2;
+			}
+			if ((*data & 1) != 0) {
+				p = skb_put(skb, 1);
+				p[0] = 0;
+			}
+
+			/* copy frame to socket buffer */
+			p = skb_put(skb, count);
+			memcpy(p,data,count);
+			
+			/*
+			 * Check if we've overflowed the MRU
+			 */
+			if (skb->len >= ppp->mru + PPP_HDRLEN + 2
+			    || skb_tailroom(skb) <= 0) {
+				++ppp->estats.rx_length_errors;
+				if (ppp->flags & SC_DEBUG)
+					printk(KERN_DEBUG "rcv frame too long: "
+					       "len=%d mru=%d hroom=%d troom=%d\n",
+					       skb->len, ppp->mru, skb_headroom(skb),
+					       skb_tailroom(skb));
+			} else {
+				if (!ppp_receive_frame(ppp, skb)) {
+					kfree_skb(skb);
+					ppp_receive_error(ppp);
+				}
+			}
+		
+			/* Reset for the next frame */
+			skb = NULL;
+		}
+		ppp->rpkt = skb;
+		return;
+	}
+	
X 	while (count-- > 0) {
X 		/*
X 		 * Collect the character and error condition for the character.
@@ -1291,9 +1494,6 @@
X 
X 	CHECK_PPP_MAGIC(ppp);
X 
-	/* ppp_dev_close may be called with tbusy==1 so we must set it to 0 */
-	dev->tbusy=0;
-
X 	MOD_DEC_USE_COUNT;
X 
X 	return 0;
@@ -1850,23 +2050,25 @@
X 		return 0;
X 	}
X 
-	/*
-	 * Verify the FCS of the frame and discard the FCS characters
-	 * from the end of the buffer.
-	 */
-	if (ppp->rfcs != PPP_GOODFCS) {
-		if (ppp->flags & SC_DEBUG) {
-			printk(KERN_DEBUG
-			       "ppp: frame with bad fcs, length = %d\n",
-			       count);
-			ppp_print_buffer("bad frame", data, count);
+	if ( !(ppp->flags & SC_SYNC) ) { 
+		/*
+		 * Verify the FCS of the frame and discard the FCS characters
+		 * from the end of the buffer.
+		 */
+		if (ppp->rfcs != PPP_GOODFCS) {
+			if (ppp->flags & SC_DEBUG) {
+				printk(KERN_DEBUG
+				       "ppp: frame with bad fcs, length = %d\n",
+				       count);
+				ppp_print_buffer("bad frame", data, count);
+			}
+			++ppp->estats.rx_crc_errors;
+			return 0;
X 		}
-		++ppp->estats.rx_crc_errors;
-		return 0;
+		count -= 2;		/* ignore the fcs characters */
+		skb_trim(skb, count);
X 	}
-	count -= 2;		/* ignore the fcs characters */
-	skb_trim(skb, count);
-
+	
X 	/*
X 	 * Process the active decompressor.
X 	 */
@@ -2055,7 +2257,7 @@
X 		return 0;
X 	new_count = slhc_uncompress(ppp->slcomp, skb->data + PPP_HDRLEN,
X 				    skb->len - PPP_HDRLEN);
-	if (new_count<=0) {
+	if (new_count <= 0) {
X 		if (ppp->flags & SC_DEBUG)
X 			printk(KERN_NOTICE
X 			       "ppp: error in VJ decompression\n");
@@ -2234,7 +2436,10 @@
X 	/*
X 	 * Send the frame
X 	 */
-	ret = ppp_async_send(ppp, skb);
+	if ( ppp->flags & SC_SYNC ) 
+		ret = ppp_sync_send(ppp, skb);
+	else
+		ret = ppp_async_send(ppp, skb);
X 	if (ret > 0) {
X 		/* we can release the lock */
X 		ppp->xmit_busy = 0;
diff -u --recursive --new-file v2.2.6/linux/drivers/net/rrunner.c linux/drivers/net/rrunner.c
--- v2.2.6/linux/drivers/net/rrunner.c	Tue Dec 22 14:16:56 1998
+++ linux/drivers/net/rrunner.c	Sat Apr 24 17:51:48 1999
@@ -59,15 +59,7 @@
X  * stack will need to know about I/O vectors or something similar.
X  */
X 
-static const char *version = "rrunner.c: v0.09 12/14/98  Jes Sorensen (Jes.So...@cern.ch)\n";
-
-static unsigned int read_eeprom(struct rr_private *rrpriv,
-				unsigned long offset,
-				unsigned char *buf,
-				unsigned long length);
-static u32 read_eeprom_word(struct rr_private *rrpriv,
-			    void * offset);
-static int rr_load_firmware(struct device *dev);
+static const char __initdata *version = "rrunner.c: v0.17 03/09/99  Jes Sorensen (Jes.So...@cern.ch)\n";
X 
X 
X /*
@@ -78,44 +70,32 @@
X extern __u32 sysctl_wmem_max;
X extern __u32 sysctl_rmem_max;
X 
+static int probed __initdata = 0;
+
X __initfunc(int rr_hippi_probe (struct device *dev))
X {
-	static int i = 0;
X 	int boards_found = 0;
X 	int version_disp;	/* was version info already displayed? */
-	u8 pci_bus;		/* PCI bus number (0-255) */
-	u8 pci_dev_fun;		/* PCI device and function numbers (0-255) */
+	struct pci_dev *pdev = NULL;
+	struct pci_dev *opdev = NULL;
X 	u8 pci_latency;
-	u16 command;		/* PCI Configuration space Command register */
-	unsigned int tmp;
-	u8 irq;
X 	struct rr_private *rrpriv;
X 
+	if (probed)
+		return -ENODEV;
+	probed++;
+
X 	if (!pci_present())		/* is PCI BIOS even present? */
X 		return -ENODEV;
X 
X 	version_disp = 0;
X 
-	for (; i < 255; i++)
+	while((pdev = pci_find_device(PCI_VENDOR_ID_ESSENTIAL,
+				      PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER,
+				      pdev)))
X 	{
-		if (pcibios_find_device(PCI_VENDOR_ID_ESSENTIAL,
-					PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER,
-					i, &pci_bus, &pci_dev_fun) != 0)
-			break;
-
-		pcibios_read_config_word(pci_bus, pci_dev_fun,
-					 PCI_COMMAND, &command);
-
-		/* Enable mastering */
-
-		command |= PCI_COMMAND_MASTER;
-		pcibios_write_config_word(pci_bus, pci_dev_fun,
-					  PCI_COMMAND, command);
-
-		if (!(command & PCI_COMMAND_MEMORY)){
-			printk("shared mem not enabled - unable to configure RoadRunner\n");
-			break;
-		}
+		if (pdev == opdev)
+			return 0;
X 
X 		/*
X 		 * So we found our HIPPI ... time to tell the system.
@@ -123,31 +103,24 @@
X 
X 		dev = init_hippi_dev(dev, sizeof(struct rr_private));
X 
-		if (dev == NULL)
+		if (!dev)
X 			break;
X 
X 		if (!dev->priv)
X 			dev->priv = kmalloc(sizeof(*rrpriv), GFP_KERNEL);
X 
-		rrpriv = (struct rr_private *)dev->priv;
-
-		/* Read register base address from
-		   PCI Configuration Space */
-
-		pcibios_read_config_dword(pci_bus, pci_dev_fun,
-					  PCI_BASE_ADDRESS_0, &tmp);
+		if (!dev->priv)
+			return -ENOMEM;
X 
-		pcibios_read_config_byte(pci_bus, pci_dev_fun,
-					 PCI_INTERRUPT_LINE, &irq);
+		rrpriv = (struct rr_private *)dev->priv;
+		memset(rrpriv, 0, sizeof(*rrpriv));
X 
-		dev->irq = irq;
-		rrpriv->pci_bus = pci_bus;
-		rrpriv->pci_dev_fun = pci_dev_fun;
-		sprintf(rrpriv->name, "RoadRunner serial HIPPI");
X #ifdef __SMP__
X 		spin_lock_init(&rrpriv->lock);
X #endif
+		sprintf(rrpriv->name, "RoadRunner serial HIPPI");
X 
+		dev->irq = pdev->irq;
X 		dev->open = &rr_open;
X 		dev->hard_start_xmit = &rr_start_xmit;
X 		dev->stop = &rr_close;
@@ -168,29 +141,30 @@
X 			printk(version);
X 		}
X 
-		printk(KERN_INFO "%s: Essential RoadRunner serial HIPPI at 0x%08x, irq %i\n",
-		       dev->name, tmp, dev->irq);
-
-		pcibios_read_config_byte(pci_bus, pci_dev_fun,
-					 PCI_LATENCY_TIMER, &pci_latency);
-#if 0
-		if (pci_latency <= 48){
-			printk("  PCI latency counter too low (%i), setting to 48 clocks\n", pci_latency);
-			pcibios_write_config_byte(pci_bus, pci_dev_fun,
-						  PCI_LATENCY_TIMER, 48);
+		pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
+		if (pci_latency <= 0x58){
+			pci_latency = 0x58;
+			pci_write_config_byte(pdev, PCI_LATENCY_TIMER,
+					      pci_latency);
X 		}
-#else
-		if (pci_latency <= 0x58)
-			pcibios_write_config_byte(pci_bus, pci_dev_fun,
-						  PCI_LATENCY_TIMER, 0x58);
-#endif
+
+		pci_set_master(pdev);
+
+		printk(KERN_INFO "%s: Essential RoadRunner serial HIPPI "
+		       "at 0x%08lx, irq %i, PCI latency %i\n", dev->name,
+		       pdev->base_address[0], dev->irq, pci_latency);
+
X 		/*
X 		 * Remap the regs into kernel space.
X 		 */
X 
-		rrpriv->regs = (struct rr_regs *)ioremap(tmp, 0x1000);
+		rrpriv->regs = (struct rr_regs *)
+			ioremap(pdev->base_address[0], 0x1000);
+
X 		if (!rrpriv->regs){
-			printk(KERN_ERR "%s:  Unable to map I/O register, RoadRunner %i will be disabled.\n", dev->name, i);
+			printk(KERN_ERR "%s:  Unable to map I/O register, "
+			       "RoadRunner %i will be disabled.\n",
+			       dev->name, boards_found);
X 			break;
X 		}
X 
@@ -198,7 +172,7 @@
X 		 * Don't access any registes before this point!
X 		 */
X #ifdef __BIG_ENDIAN
-		regs->HostCtrl |= NO_SWAP;
+		writel(readl(®s->HostCtrl) | NO_SWAP, ®s->HostCtrl);
X #endif
X 		/*
X 		 * Need to add a case for little-endian 64-bit hosts here.
@@ -209,6 +183,7 @@
X 		boards_found++;
X 		dev->base_addr = 0;
X 		dev = NULL;
+		opdev = pdev;
X 	}
X 
X 	/*
@@ -217,12 +192,59 @@
X 	 * 1 or more boards. Otherwise, return failure (-ENODEV).
X 	 */
X 
+#ifdef MODULE
+	return boards_found;
+#else
X 	if (boards_found > 0)
X 		return 0;
X 	else
X 		return -ENODEV;
+#endif
+}
+
+static struct device *root_dev = NULL;
+
+#ifdef MODULE
+#if LINUX_VERSION_CODE > 0x20118
+MODULE_AUTHOR("Jes Sorensen <Jes.So...@cern.ch>");
+MODULE_DESCRIPTION("Essential RoadRunner HIPPI driver");
+#endif
+
+
+int init_module(void)
+{
+	int cards;
+
+	root_dev = NULL;
+
+	cards = rr_hippi_probe(NULL);
+	return cards ? 0 : -ENODEV;
X }
X 
+void cleanup_module(void)
+{
+	struct rr_private *rr;
+	struct device *next;
+
+	while (root_dev) {
+		next = ((struct rr_private *)root_dev->priv)->next;
+		rr = (struct rr_private *)root_dev->priv;
+
+		if (!(readl(&rr->regs->HostCtrl) & NIC_HALTED)){
+			printk(KERN_ERR "%s: trying to unload running NIC\n",
+			       root_dev->name);
+			writel(HALT_NIC, &rr->regs->HostCtrl);
+		}
+
+		iounmap(rr->regs);
+		unregister_hipdev(root_dev);
+		kfree(root_dev);
+
+		root_dev = next;
+	}
+}
+#endif
+
X 
X /*
X  * Commands are considered to be slow, thus there is no reason to
@@ -238,21 +260,25 @@
X 	 * This is temporary - it will go away in the final version.
X 	 * We probably also want to make this function inline.
X 	 */
-	if (regs->HostCtrl & NIC_HALTED){
-		printk("issuing command for halted NIC, code 0x%x, HostCtrl %08x\n", cmd->code, regs->HostCtrl);
-		if (regs->Mode & FATAL_ERR)
-			printk("error code %02x\n", regs->Fail1);
+	if (readl(®s->HostCtrl) & NIC_HALTED){
+		printk("issuing command for halted NIC, code 0x%x, "
+		       "HostCtrl %08x\n", cmd->code, readl(®s->HostCtrl));
+		if (readl(®s->Mode) & FATAL_ERR)
+			printk("error codes Fail1 %02x, Fail2 %02x\n",
+			       readl(®s->Fail1), readl(®s->Fail2));
X 	}
X 
X 	idx = rrpriv->info->cmd_ctrl.pi;
X 
-	regs->CmdRing[idx] = *(u32*)(cmd);
+	writel(*(u32*)(cmd), ®s->CmdRing[idx]);
+	mb();
X 
X 	idx = (idx - 1) % CMD_RING_ENTRIES;
X 	rrpriv->info->cmd_ctrl.pi = idx;
+	mb();
X 
-	if (regs->Mode & FATAL_ERR)
-		printk("error code %02x\n", regs->Fail1);
+	if (readl(®s->Mode) & FATAL_ERR)
+		printk("error code %02x\n", readl(®s->Fail1));
X }
X 
X 
@@ -273,85 +299,97 @@
X 
X 	rr_load_firmware(dev);
X 
-	regs->TX_state = 0x01000000;
-	regs->RX_state = 0xff800000;
-	regs->AssistState = 0;
-	regs->LocalCtrl = CLEAR_INTA;
-	regs->BrkPt = 0x01;
-	regs->Timer = 0;
-	regs->TimerRef = 0;
-	regs->DmaReadState = RESET_DMA;
-	regs->DmaWriteState = RESET_DMA;
-	regs->DmaWriteHostHi = 0;
-	regs->DmaWriteHostLo = 0;
-	regs->DmaReadHostHi = 0;
-	regs->DmaReadHostLo = 0;
-	regs->DmaReadLen = 0;
-	regs->DmaWriteLen = 0;
-	regs->DmaWriteLcl = 0;
-	regs->DmaWriteIPchecksum = 0;
-	regs->DmaReadLcl = 0;
-	regs->DmaReadIPchecksum = 0;
-	regs->PciState = 0; /* 0x90 for GE? */
-	regs->Mode = SWAP_DATA;
+	writel(0x01000000, ®s->TX_state);
+	writel(0xff800000, ®s->RX_state);
+	writel(0, ®s->AssistState);
+	writel(CLEAR_INTA, ®s->LocalCtrl);
+	writel(0x01, ®s->BrkPt);
+	writel(0, ®s->Timer);
+	writel(0, ®s->TimerRef);
+	writel(RESET_DMA, ®s->DmaReadState);
+	writel(RESET_DMA, ®s->DmaWriteState);
+	writel(0, ®s->DmaWriteHostHi);
+	writel(0, ®s->DmaWriteHostLo);
+	writel(0, ®s->DmaReadHostHi);
+	writel(0, ®s->DmaReadHostLo);
+	writel(0, ®s->DmaReadLen);
+	writel(0, ®s->DmaWriteLen);
+	writel(0, ®s->DmaWriteLcl);
+	writel(0, ®s->DmaWriteIPchecksum);
+	writel(0, ®s->DmaReadLcl);
+	writel(0, ®s->DmaReadIPchecksum);
+	writel(0, ®s->PciState);
+#if (BITS_PER_LONG == 64) && defined __LITTLE_ENDIAN
+	writel(SWAP_DATA | PTR64BIT | PTR_WD_SWAP, ®s->Mode);
+#elif (BITS_PER_LONG == 64)
+	writel(SWAP_DATA | PTR64BIT | PTR_WD_NOSWAP, ®s->Mode);
+#else
+	writel(SWAP_DATA | PTR32BIT | PTR_WD_NOSWAP, ®s->Mode);
+#endif
X 
X #if 0
X 	/*
X 	 * Don't worry, this is just black magic.
X 	 */
-	regs->RxBase = 0xdf000;
-	regs->RxPrd = 0xdf000;
-	regs->RxCon = 0xdf000;
-	regs->TxBase = 0xce000;
-	regs->TxPrd = 0xce000;
-	regs->TxCon = 0xce000;
-	regs->RxIndPro = 0;
-	regs->RxIndCon = 0;
-	regs->RxIndRef = 0;
-	regs->TxIndPro = 0;
-	regs->TxIndCon = 0;
-	regs->TxIndRef = 0;
-	regs->pad10[0] = 0xcc000;
-	regs->DrCmndPro = 0;
-	regs->DrCmndCon = 0;
-	regs->DwCmndPro = 0;
-	regs->DwCmndCon = 0;
-	regs->DwCmndRef = 0;
-	regs->DrDataPro = 0;
-	regs->DrDataCon = 0;
-	regs->DrDataRef = 0;
-	regs->DwDataPro = 0;
-	regs->DwDataCon = 0;
-	regs->DwDataRef = 0;
+	writel(0xdf000, ®s->RxBase);
+	writel(0xdf000, ®s->RxPrd);
+	writel(0xdf000, ®s->RxCon);
+	writel(0xce000, ®s->TxBase);
+	writel(0xce000, ®s->TxPrd);
+	writel(0xce000, ®s->TxCon);
+	writel(0, ®s->RxIndPro);
+	writel(0, ®s->RxIndCon);
+	writel(0, ®s->RxIndRef);
+	writel(0, ®s->TxIndPro);
+	writel(0, ®s->TxIndCon);
+	writel(0, ®s->TxIndRef);
+	writel(0xcc000, ®s->pad10[0]);
+	writel(0, ®s->DrCmndPro);
+	writel(0, ®s->DrCmndCon);
+	writel(0, ®s->DwCmndPro);
+	writel(0, ®s->DwCmndCon);
+	writel(0, ®s->DwCmndRef);
+	writel(0, ®s->DrDataPro);
+	writel(0, ®s->DrDataCon);
+	writel(0, ®s->DrDataRef);
+	writel(0, ®s->DwDataPro);
+	writel(0, ®s->DwDataCon);
+	writel(0, ®s->DwDataRef);
X #endif
X 
-	regs->MbEvent = 0xffffffff;
-	regs->Event = 0;
+	writel(0xffffffff, ®s->MbEvent);
+	writel(0, ®s->Event);
X 
-	regs->TxPi = 0;
-	regs->IpRxPi = 0;
+	writel(0, ®s->TxPi);
+	writel(0, ®s->IpRxPi);
X 
-	regs->EvtCon = 0;
-	regs->EvtPrd = 0;
+	writel(0, ®s->EvtCon);
+	writel(0, ®s->EvtPrd);
X 
X rrpriv->info->evt_ctrl.pi = 0;
X 
X 	for (i = 0; i < CMD_RING_ENTRIES; i++)
-		regs->CmdRing[i] = 0;
+		writel(0, ®s->CmdRing[i]);
X 
-	regs->PciState = 0;
+/*
+ * Why 32 ? is this not cache line size dependant?
+ */
+	writel(WBURST_32, ®s->PciState);
+	mb();
X 
-	start_pc = read_eeprom_word(rrpriv, &hw->rncd_info.FwStart);
+	start_pc = rr_read_eeprom_word(rrpriv, &hw->rncd_info.FwStart);
X 
X #if (DEBUG > 1)
X 	printk("%s: Executing firmware at address 0x%06x\n",
X 	       dev->name, start_pc);
X #endif
X 
-	regs->Pc = start_pc + 0x800;
+	writel(start_pc + 0x800, ®s->Pc);
+	mb();
X 	udelay(5);
X 
-	regs->Pc = start_pc;
+	writel(start_pc, ®s->Pc);
+	mb();
X 
X 	return 0;
X }
@@ -360,7 +398,7 @@
X /*
X  * Read a string from the EEPROM.
X  */
-static unsigned int read_eeprom(struct rr_private *rrpriv,
+static unsigned int rr_read_eeprom(struct rr_private *rrpriv,
X 				unsigned long offset,
X 				unsigned char *buf,
X 				unsigned long length)
@@ -368,22 +406,25 @@
X 	struct rr_regs *regs = rrpriv->regs;
X 	u32 misc, io, host, i;
X 
-	io = regs->ExtIo;
-	regs->ExtIo = 0;
- misc = regs->LocalCtrl;
-	regs->LocalCtrl = 0;
-	host = regs->HostCtrl;
-	regs->HostCtrl |= HALT_NIC;
+	io = readl(®s->ExtIo);
+	writel(0, ®s->ExtIo);
+	misc = readl(®s->LocalCtrl);
+	writel(0, ®s->LocalCtrl);
+	host = readl(®s->HostCtrl);
+	writel(host | HALT_NIC, ®s->HostCtrl);
+	mb();
X 
X 	for (i = 0; i < length; i++){
-		regs->WinBase = (EEPROM_BASE + ((offset+i) << 3));
-		buf[i] = (regs->WinData >> 24) & 0xff;
+		writel((EEPROM_BASE + ((offset+i) << 3)), ®s->WinBase);
+		mb();
+		buf[i] = (readl(®s->WinData) >> 24) & 0xff;
+		mb();
X 	}
X 
-	regs->HostCtrl = host;
-	regs->LocalCtrl = misc;
-	regs->ExtIo = io;
-
+	writel(host, ®s->HostCtrl);
+	writel(misc, ®s->LocalCtrl);
+	writel(io, ®s->ExtIo);
+	mb();
X 	return i;
X }
X 
@@ -392,13 +433,13 @@
X  * Shortcut to read one word (4 bytes) out of the EEPROM and convert
X  * it to our CPU byte-order.
X  */
-static u32 read_eeprom_word(struct rr_private *rrpriv,
+static u32 rr_read_eeprom_word(struct rr_private *rrpriv,
X 			    void * offset)
X {
X 	u32 word;
X 
-	if ((read_eeprom(rrpriv, (unsigned long)offset,
-			 (char *)&word, 4) == 4))
+	if ((rr_read_eeprom(rrpriv, (unsigned long)offset,
+			    (char *)&word, 4) == 4))
X 		return be32_to_cpu(word);
X 	return 0;
X }
@@ -410,38 +451,42 @@
X  * This is only called when the firmware is not running.
X  */
X static unsigned int write_eeprom(struct rr_private *rrpriv,
-				unsigned long offset,
-				unsigned char *buf,
-				unsigned long length)
+				 unsigned long offset,
+				 unsigned char *buf,
+				 unsigned long length)
X {
X 	struct rr_regs *regs = rrpriv->regs;
X 	u32 misc, io, data, i, j, ready, error = 0;
X 
-	io = regs->ExtIo;
-	regs->ExtIo = 0;
-	misc = regs->LocalCtrl;
-	regs->LocalCtrl = ENABLE_EEPROM_WRITE;
+	io = readl(®s->ExtIo);
+	writel(0, ®s->ExtIo);
+	misc = readl(®s->LocalCtrl);
+	writel(ENABLE_EEPROM_WRITE, ®s->LocalCtrl);
+	mb();
X 
X 	for (i = 0; i < length; i++){
-		regs->WinBase = (EEPROM_BASE + ((offset+i) << 3));
+		writel((EEPROM_BASE + ((offset+i) << 3)), ®s->WinBase);
+		mb();
X 		data = buf[i] << 24;
X 		/*
X 		 * Only try to write the data if it is not the same
X 		 * value already.
X 		 */
-		if ((regs->WinData & 0xff000000) != data){
-			regs->WinData = data;
+		if ((readl(®s->WinData) & 0xff000000) != data){
+			writel(data, ®s->WinData);
X 			ready = 0;
X 			j = 0;
X 			mb();
X 			while(!ready){
-				udelay(1000);
-				if ((regs->WinData & 0xff000000) == data)
+				udelay(20);
+				if ((readl(®s->WinData) & 0xff000000) ==
+				    data)
X 					ready = 1;
+				mb();
X 				if (j++ > 5000){
X 					printk("data mismatch: %08x, "
X 					       "WinData %08x\n", data,
-					       regs->WinData);
+					       readl(®s->WinData));
X 					ready = 1;
X 					error = 1;
X 				}
@@ -449,8 +494,9 @@
X 		}
X 	}
X 
-	regs->LocalCtrl = misc;
-	regs->ExtIo = io;
+ writel(misc, ®s->LocalCtrl);
+	writel(io, ®s->ExtIo);
+	mb();
X 
X 	return error;
X }
@@ -465,7 +511,8 @@
X 	rrpriv = (struct rr_private *)dev->priv;
X 	regs = rrpriv->regs;
X 
-	rev = regs->FwRev;
+	rev = readl(®s->FwRev);
+	rrpriv->fw_rev = rev;
X 	if (rev > 0x00020024)
X 		printk("  Firmware revision: %i.%i.%i\n", (rev >> 16),
X 		       ((rev >> 8) & 0xff), (rev & 0xff));
@@ -477,13 +524,13 @@
X 		printk("  Firmware revision too old: %i.%i.%i, please "
X 		       "upgrade to 2.0.37 or later.\n",
X 		       (rev >> 16), ((rev >> 8) & 0xff), (rev & 0xff));
-		return -EFAULT;
-		
X 	}
X 
-	printk("  Maximum receive rings %i\n", regs->MaxRxRng);
+#if (DEBUG > 2)
+	printk("  Maximum receive rings %i\n", readl(®s->MaxRxRng));
+#endif
X 
-	sram_size = read_eeprom_word(rrpriv, (void *)8);
+	sram_size = rr_read_eeprom_word(rrpriv, (void *)8);
X 	printk("  SRAM size 0x%06x\n", sram_size);
X 
X 	if (sysctl_rmem_max < 262144){
@@ -498,6 +545,9 @@
X 		sysctl_wmem_max = 262144;
X 	}
X 
+	rrpriv->next = root_dev;
+	root_dev = dev;
+
X 	return 0;
X }
X 
@@ -507,7 +557,7 @@
X 	struct rr_private *rrpriv;
X 	struct rr_regs *regs;
X 	u32 hostctrl;
-	unsigned long myjif, flags, tmp_ptr;
+	unsigned long myjif, flags;
X 	struct cmd cmd;
X 	short i;
X 
@@ -516,8 +566,9 @@
X 
X 	spin_lock_irqsave(&rrpriv->lock, flags);
X 
-	hostctrl = regs->HostCtrl;
-	regs->HostCtrl |= HALT_NIC;
+	hostctrl = readl(®s->HostCtrl);
+	writel(hostctrl | HALT_NIC | RR_CLEAR_INT, ®s->HostCtrl);
+	mb();
X 
X 	if (hostctrl & PARITY_ERR){
X 		printk("%s: Parity error halting NIC - this is serious!\n",
@@ -526,31 +577,14 @@
X 		return -EFAULT;
X 	}
X 
-
-	memset(rrpriv->rx_ctrl, 0, 256 * sizeof(struct ring_ctrl));
-	memset(rrpriv->info, 0, sizeof(struct rr_info));
-
-	tmp_ptr = virt_to_bus((void *)rrpriv->rx_ctrl);
-#if (BITS_PER_LONG == 64)
-	regs->RxRingHi = (tmp_ptr >> 32);
-#else
-	regs->RxRingHi = 0;
-#endif
-	regs->RxRingLo = ((tmp_ptr) & 0xffffffff);
-
-	tmp_ptr = virt_to_bus((void *)rrpriv->info);
-#if (BITS_PER_LONG == 64)
-	regs->InfoPtrHi = (tmp_ptr >> 32);
-#else
-	regs->InfoPtrHi = 0;
-#endif
-	regs->InfoPtrLo = ((tmp_ptr) & 0xffffffff);
+	set_rxaddr(regs, rrpriv->rx_ctrl);
+	set_infoaddr(regs, rrpriv->info);
X 
X 	rrpriv->info->evt_ctrl.entry_size = sizeof(struct event);
X 	rrpriv->info->evt_ctrl.entries = EVT_RING_ENTRIES;
X 	rrpriv->info->evt_ctrl.mode = 0;
X 	rrpriv->info->evt_ctrl.pi = 0;
-	rrpriv->info->evt_ctrl.rngptr = virt_to_bus(rrpriv->evt_ring);
+	set_rraddr(&rrpriv->info->evt_ctrl.rngptr, rrpriv->evt_ring);
X 
X 	rrpriv->info->cmd_ctrl.entry_size = sizeof(struct cmd);
X 	rrpriv->info->cmd_ctrl.entries = CMD_RING_ENTRIES;
@@ -558,20 +592,19 @@
X 	rrpriv->info->cmd_ctrl.pi = 15;
X 
X 	for (i = 0; i < CMD_RING_ENTRIES; i++) {
-		regs->CmdRing[i] = 0;
+		writel(0, ®s->CmdRing[i]);
X 	}
X 
X for (i = 0; i < TX_RING_ENTRIES; i++) {
X 		rrpriv->tx_ring[i].size = 0;
-		rrpriv->tx_ring[i].addr = 0;
+		set_rraddr(&rrpriv->tx_ring[i].addr, 0);
X 		rrpriv->tx_skbuff[i] = 0;
X 	}
-
X 	rrpriv->info->tx_ctrl.entry_size = sizeof(struct tx_desc);
X 	rrpriv->info->tx_ctrl.entries = TX_RING_ENTRIES;
X 	rrpriv->info->tx_ctrl.mode = 0;
X 	rrpriv->info->tx_ctrl.pi = 0;
-	rrpriv->info->tx_ctrl.rngptr = virt_to_bus(rrpriv->tx_ring);
+	set_rraddr(&rrpriv->info->tx_ctrl.rngptr, rrpriv->tx_ring);
X 
X 	/*
X 	 * Set dirty_tx before we start receiving interrupts, otherwise
@@ -585,14 +618,20 @@
X 
X 	rr_reset(dev);
X 
-	regs->IntrTmr = 0x60;
-	regs->WriteDmaThresh = 0x80 | 0x1f;
-	regs->ReadDmaThresh = 0x80 | 0x1f;
+	writel(0x60, ®s->IntrTmr);
+	/*
+	 * These seem to have no real effect as the Firmware sets
+	 * it's own default values
+	 */
+	writel(0x10, ®s->WriteDmaThresh);
+	writel(0x20, ®s->ReadDmaThresh);
X 
X 	rrpriv->fw_running = 0;
+	mb();
X 
X 	hostctrl &= ~(HALT_NIC | INVALID_INST_B | PARITY_ERR);
-	regs->HostCtrl = hostctrl;
+	writel(hostctrl, ®s->HostCtrl);
+	mb();
X 
X 	spin_unlock_irqrestore(&rrpriv->lock, flags);
X 
@@ -626,10 +665,7 @@
X 		if ((((unsigned long)skb->data) & 0xfff) > ~65320)
X 			printk("skb alloc error\n");
X 
-#if (BITS_PER_LONG == 32)
-		rrpriv->rx_ring[i].zero = 0;
-#endif
-		rrpriv->rx_ring[i].addr = virt_to_bus(skb->data);
+		set_rraddr(&rrpriv->rx_ring[i].addr, skb->data);
X 		rrpriv->rx_ring[i].size = dev->mtu + HIPPI_HLEN;
X 	}
X 
@@ -637,7 +673,8 @@
X 	rrpriv->rx_ctrl[4].entries = RX_RING_ENTRIES;
X 	rrpriv->rx_ctrl[4].mode = 8;
X 	rrpriv->rx_ctrl[4].pi = 0;
-	rrpriv->rx_ctrl[4].rngptr = virt_to_bus(rrpriv->rx_ring);
+	mb();
+	set_rraddr(&rrpriv->rx_ctrl[4].rngptr, rrpriv->rx_ring);
X 
X 	cmd.code = C_NEW_RNG;
X 	cmd.ring = 4;
@@ -647,18 +684,15 @@
X #if 0
X {
X 	u32 tmp;
-	tmp = regs->ExtIo;
-	regs->ExtIo = 0x80;
+	tmp = readl(®s->ExtIo);
+	writel(0x80, ®s->ExtIo);
X 	
X 	i = jiffies + 1 * HZ;
X 	while (jiffies < i);
-	regs->ExtIo = tmp;
+	writel(tmp, ®s->ExtIo);
X }
X #endif
X 	dev->tbusy = 0;
-#if 0
-	dev->interrupt = 0;
-#endif
X 	dev->start = 1;
X 	return 0;
X }
@@ -669,24 +703,24 @@
X  * events) and are handled here, outside the main interrupt handler,
X  * to reduce the size of the handler.
X  */
-static u32 rr_handle_event(struct device *dev, u32 prodidx)
+static u32 rr_handle_event(struct device *dev, u32 prodidx, u32 eidx)
X {
X 	struct rr_private *rrpriv;
X 	struct rr_regs *regs;
-	u32 tmp, eidx;
+	u32 tmp;
X 
X 	rrpriv = (struct rr_private *)dev->priv;
X 	regs = rrpriv->regs;
-	eidx = rrpriv->info->evt_ctrl.pi;
X 
X 	while (prodidx != eidx){
X 		switch (rrpriv->evt_ring[eidx].code){
X 		case E_NIC_UP:
-			tmp = regs->FwRev;
+			tmp = readl(®s->FwRev);
X 			printk("%s: Firmware revision %i.%i.%i up and running\n",
X 			       dev->name, (tmp >> 16), ((tmp >> 8) & 0xff),
X 			       (tmp & 0xff));
X 			rrpriv->fw_running = 1;
+			mb();
X 			break;
X 		case E_LINK_ON:
X 			printk("%s: Optical link ON\n", dev->name);
@@ -729,7 +763,7 @@
X #if (DEBUG > 2)
X 			printk("%s: RX ring valid event\n", dev->name);
X #endif
-			regs->IpRxPi = RX_RING_ENTRIES - 1;
+			writel(RX_RING_ENTRIES - 1, ®s->IpRxPi);
X 			break;
X 		case E_INV_RNG:
X 			printk("%s: RX ring invalid event\n", dev->name);
@@ -756,35 +790,24 @@
X 	}
X 
X 	rrpriv->info->evt_ctrl.pi = eidx;
+	mb();
X 	return eidx;
X }
X 
X 
-static int rx_int(struct device *dev, u32 rxlimit)
+static void rx_int(struct device *dev, u32 rxlimit, u32 index)
X {
X 	struct rr_private *rrpriv = (struct rr_private *)dev->priv;
-	u32 index, pkt_len;
+	u32 pkt_len;
X 	struct rr_regs *regs = rrpriv->regs;
X 
-	index = rrpriv->cur_rx;
-
-	while(index != rxlimit){
+	do {
X 		pkt_len = rrpriv->rx_ring[index].size;
X #if (DEBUG > 2)
X 		printk("index %i, rxlimit %i\n", index, rxlimit);
X 		printk("len %x, mode %x\n", pkt_len,
X 		       rrpriv->rx_ring[index].mode);
X #endif
-#if 0
-/*
- * I have never seen this occur
- */
-		if(!(rrpriv->rx_skbuff[index])){
-			printk("Trying to receive in empty skbuff\n");
-			goto out;
-		}
-#endif
-
X 		if (pkt_len > 0){
X 			struct sk_buff *skb;
X 
@@ -808,7 +831,7 @@
X 					skb = rrpriv->rx_skbuff[index];
X 					skb_put(skb, pkt_len);
X 					rrpriv->rx_skbuff[index] = newskb;
-					rrpriv->rx_ring[index].addr = virt_to_bus(newskb->data);
+					set_rraddr(&rrpriv->rx_ring[index].addr, newskb->data);
X 				}else{
X 					printk("%s: Out of memory, deferring "
X 					       "packet\n", dev->name);
@@ -829,13 +852,13 @@
X 		rrpriv->rx_ring[index].size = dev->mtu + HIPPI_HLEN;
X 
X 		if ((index & 7) == 7)
-			regs->IpRxPi = index;
+			writel(index, ®s->IpRxPi);
X 
X 		index = (index + 1) % RX_RING_ENTRIES;
-	}
+	} while(index != rxlimit);
X 
X 	rrpriv->cur_rx = index;
-	return index;
+	mb();
X }
X 
X 
@@ -844,25 +867,18 @@
X 	struct rr_private *rrpriv;
X 	struct rr_regs *regs;
X 	struct device *dev = (struct device *)dev_id;
-	u32 prodidx, eidx, txcsmr, rxlimit, txcon;
+	u32 prodidx, rxindex, eidx, txcsmr, rxlimit, txcon;
X 	unsigned long flags;
X 
X 	rrpriv = (struct rr_private *)dev->priv;
X 	regs = rrpriv->regs;
X 
-	if (!(regs->HostCtrl & RR_INT))
+	if (!(readl(®s->HostCtrl) & RR_INT))
X 		return;
X 
-#if 0
-	if (test_and_set_bit(0, (void*)&dev->interrupt) != 0) {
-		printk("%s: Re-entering the interrupt handler.\n", dev->name);
-		return;
-	}
-#endif
-
X 	spin_lock_irqsave(&rrpriv->lock, flags);
X 
-	prodidx = regs->EvtPrd;
+	prodidx = readl(®s->EvtPrd);
X 	txcsmr = (prodidx >> 8) & 0xff;
X 	rxlimit = (prodidx >> 16) & 0xff;
X 	prodidx &= 0xff;
@@ -872,6 +888,10 @@
X 	       prodidx, rrpriv->info->evt_ctrl.pi);
X #endif
X 
+	rxindex = rrpriv->cur_rx;
+	if (rxindex != rxlimit)
+		rx_int(dev, rxlimit, rxindex);
+
X 	txcon = rrpriv->dirty_tx;
X 	if (txcsmr != txcon) {
X 		do {
@@ -881,11 +901,12 @@
X 
X 			rrpriv->tx_skbuff[txcon] = NULL;
X 			rrpriv->tx_ring[txcon].size = 0;
-			rrpriv->tx_ring[txcon].addr = 0;
+			set_rraddr(&rrpriv->tx_ring[txcon].addr, 0);
X 			rrpriv->tx_ring[txcon].mode = 0;
X 
X 			txcon = (txcon + 1) % TX_RING_ENTRIES;
X 		} while (txcsmr != txcon);
+		mb();
X 
X 		rrpriv->dirty_tx = txcon;
X 		if (rrpriv->tx_full && dev->tbusy &&
@@ -897,21 +918,15 @@
X 		}
X 	}
X 
-	rx_int(dev, rxlimit);
-
X 	eidx = rrpriv->info->evt_ctrl.pi;
-
X 	if (prodidx != eidx)
-		eidx = rr_handle_event(dev, prodidx);
+		eidx = rr_handle_event(dev, prodidx, eidx);
X 
X 	eidx |= ((txcsmr << 8) | (rxlimit << 16));
-	regs->EvtCon = eidx;
+	writel(eidx, ®s->EvtCon);
+	mb();
X 
X 	spin_unlock_irqrestore(&rrpriv->lock, flags);
-
-#if 0
-	dev->interrupt = 0;
-#endif
X }
X 
X 
@@ -919,35 +934,64 @@
X {
X 	struct rr_private *rrpriv;
X 	struct rr_regs *regs;
+	int ecode = 0;
+	unsigned long flags;
X 
X 	rrpriv = (struct rr_private *)dev->priv;
X 	regs = rrpriv->regs;
X 
-#if 0
-	regs->HostCtrl |= (HALT_NIC | RR_CLEAR_INT);
-#endif
+	if (rrpriv->fw_rev < 0x00020000) {
+		printk(KERN_WARNING "%s: trying to configure device with "
+		       "obsolete firmware\n", dev->name);
+		ecode = -EBUSY;
+		goto error;
+	}
+
+	rrpriv->rx_ctrl = kmalloc(256*sizeof(struct ring_ctrl),
+				  GFP_KERNEL | GFP_DMA);
+	if (!rrpriv->rx_ctrl) {
+		ecode = -ENOMEM;
+		goto error;
+	}
+
+ rrpriv->info = kmalloc(sizeof(struct rr_info), GFP_KERNEL | GFP_DMA);
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 05'
echo 'File patch-2.2.7 is continued in part 06'
echo 06 > _shar_seq_.tmp
#!/bin/sh
# this is part 10 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 10; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
+	0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e0,
+	0x5300, 0x007c, 0x79d8, 0x7adc, 0x78d0, 0x801b, 0x00c8, 0x37d1,
+	0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x007c, 0x0f7e,
+	0x2079, 0x0100, 0x2009, 0x5040, 0x2091, 0x8000, 0x2104, 0x0079,
+	0x37e1, 0x3817, 0x37eb, 0x37eb, 0x37eb, 0x37eb, 0x37eb, 0x37eb,
+	0x381b, 0x1078, 0x23ca, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
+	0x00c0, 0x37ed, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0,
+	0x37f4, 0x68b4, 0xa085, 0x4000, 0x68b6, 0x7858, 0xa085, 0x4000,
+	0x785a, 0x7830, 0xa084, 0x0080, 0x00c0, 0x3817, 0x0018, 0x3817,
+	0x681c, 0xa084, 0x0020, 0x00c0, 0x3815, 0x0e7e, 0x2071, 0x5040,
+	0x1078, 0x3868, 0x0e7f, 0x0078, 0x3817, 0x781b, 0x00d2, 0x2091,
+	0x8001, 0x0f7f, 0x007c, 0x1078, 0x3a42, 0x0078, 0x3817, 0x0c7e,
X 	0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0,
-	0x3a00, 0x6004, 0xa084, 0x000a, 0x00c0, 0x311a, 0x6108, 0xa194,
-	0xff00, 0x0040, 0x311a, 0xa18c, 0x00ff, 0x2001, 0x0019, 0xa106,
-	0x0040, 0x3109, 0x2001, 0x0032, 0xa106, 0x0040, 0x310d, 0x0078,
-	0x3111, 0x2009, 0x0020, 0x0078, 0x3113, 0x2009, 0x003f, 0x0078,
-	0x3113, 0x2011, 0x0000, 0x2100, 0xa205, 0x600a, 0x6004, 0xa085,
-	0x0002, 0x6006, 0x0c7f, 0x007c, 0x781b, 0x0068, 0x0078, 0x1efb,
-	0x781b, 0x0067, 0x0078, 0x1efb, 0x781b, 0x0056, 0x0078, 0x1efb,
-	0x781b, 0x0053, 0x0078, 0x1efb, 0x781b, 0x00df, 0x0078, 0x1efb,
-	0x781b, 0x00de, 0x0078, 0x1efb, 0x781b, 0x00e6, 0x0078, 0x1efb,
-	0x781b, 0x00e5, 0x0078, 0x1efb, 0x781b, 0x009d, 0x0078, 0x1efb,
-	0x781b, 0x009c, 0x0078, 0x1efb, 0x6818, 0xa084, 0x8000, 0x0040,
-	0x314b, 0x681b, 0x001d, 0x70a3, 0x0001, 0x781b, 0x0047, 0x0078,
-	0x1efb, 0x007e, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3168, 0x7808,
-	0xa084, 0xfffd, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec,
-	0xa084, 0x0021, 0x0040, 0x3168, 0x7808, 0xa085, 0x0002, 0x780a,
-	0x007f, 0x007c, 0x7808, 0xa085, 0x0002, 0x780a, 0x007c, 0x7830,
-	0xa084, 0x0040, 0x00c0, 0x316f, 0x0098, 0x3178, 0x78ac, 0x007c,
+	0x5280, 0x6004, 0xa084, 0x000a, 0x00c0, 0x3852, 0x6108, 0xa194,
+	0xff00, 0x0040, 0x3852, 0xa18c, 0x00ff, 0x2001, 0x0019, 0xa106,
+	0x0040, 0x3841, 0x2001, 0x0032, 0xa106, 0x0040, 0x3845, 0x0078,
+	0x3849, 0x2009, 0x0020, 0x0078, 0x384b, 0x2009, 0x003f, 0x0078,
+	0x384b, 0x2011, 0x0000, 0x2100, 0xa205, 0x600a, 0x6004, 0xa085,
+	0x0002, 0x6006, 0x0c7f, 0x007c, 0x781b, 0x0065, 0x0078, 0x2438,
+	0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x781b, 0x0058,
+	0x0078, 0x2438, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2438,
+	0x2009, 0x5020, 0x210c, 0xa186, 0x0000, 0x0040, 0x387c, 0xa186,
+	0x0001, 0x0040, 0x387f, 0x2009, 0x5038, 0x200b, 0x000b, 0x706f,
+	0x0001, 0x781b, 0x0048, 0x007c, 0x781b, 0x00cc, 0x007c, 0x2009,
+	0x5038, 0x200b, 0x000a, 0x007c, 0x2009, 0x5020, 0x210c, 0xa186,
+	0x0000, 0x0040, 0x389f, 0xa186, 0x0001, 0x0040, 0x3899, 0x2009,
+	0x5038, 0x200b, 0x000b, 0x706f, 0x0001, 0x781b, 0x0048, 0x0078,
+	0x2438, 0x2009, 0x5038, 0x200b, 0x000a, 0x0078, 0x2438, 0x782b,
+	0x3008, 0x781b, 0x00cc, 0x0078, 0x2438, 0x781b, 0x00d2, 0x0078,
+	0x2438, 0x782b, 0x3008, 0x781b, 0x00d2, 0x0078, 0x2438, 0x781b,
+	0x0093, 0x0078, 0x2438, 0x782b, 0x3008, 0x781b, 0x0093, 0x0078,
+	0x2438, 0x6818, 0xa084, 0x8000, 0x0040, 0x38c0, 0x681b, 0x001d,
+	0x706f, 0x0001, 0x781b, 0x0048, 0x0078, 0x2438, 0x007e, 0x7830,
+	0xa084, 0x00c0, 0x00c0, 0x38dc, 0x7808, 0xa084, 0xfffc, 0x780a,
+	0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040,
+	0x38dc, 0x7044, 0x780a, 0xa005, 0x007f, 0x007c, 0x7044, 0xa085,
+	0x0002, 0x7046, 0x780a, 0x007c, 0x007e, 0x7830, 0xa084, 0x0040,
+	0x00c0, 0x38e5, 0x0098, 0x38f0, 0x007f, 0x789a, 0x78ac, 0x007c,
X 	0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005,
-	0x78ec, 0xa084, 0x0021, 0x0040, 0x3187, 0x0098, 0x3185, 0x78ac,
-	0x007e, 0x7808, 0xa085, 0x0002, 0x780a, 0x007f, 0x007c, 0xa784,
-	0x0070, 0x0040, 0x319b, 0x0c7e, 0x2d60, 0x2f68, 0x1078, 0x1e57,
-	0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040, 0x31a8, 0x784b,
-	0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x1f03, 0x0078, 0x311c,
-	0xa784, 0x0004, 0x0040, 0x31db, 0x78b8, 0xa084, 0x4001, 0x0040,
-	0x31db, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x1f03,
-	0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0, 0x31db, 0x78c0,
-	0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00e6, 0x0078, 0x1efb,
-	0x784b, 0x0008, 0x6818, 0xa084, 0x8000, 0x0040, 0x31d7, 0x681b,
-	0x0015, 0xa684, 0x4000, 0x0040, 0x31d7, 0x681b, 0x0007, 0x781b,
-	0x00df, 0x0078, 0x1efb, 0x681b, 0x0003, 0x7858, 0xa084, 0x3f00,
-	0x681e, 0x682f, 0x0000, 0x6833, 0x0000, 0x784b, 0x0008, 0x78e4,
-	0xa005, 0x00d0, 0x238a, 0xa084, 0x0020, 0x0040, 0x238a, 0x0018,
-	0x238a, 0x0078, 0x2f6f, 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003,
-	0x8003, 0x8003, 0xa080, 0x3a00, 0x2060, 0x2048, 0x704a, 0x6000,
-	0x704e, 0x6004, 0x7052, 0x2a60, 0x007c, 0x0020, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0062,
-	0x0009, 0x0014, 0x0014, 0x9848, 0x0014, 0x0014, 0x98f9, 0x98e9,
-	0x0014, 0x0014, 0x0080, 0x00c0, 0x0100, 0x0402, 0x2008, 0xf880,
-	0x0018, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, 0xa200, 0x8838,
-	0x3806, 0x8839, 0x28c2, 0x9cc2, 0xa805, 0x0864, 0xa83d, 0x3008,
-	0x28c1, 0x9cc2, 0xa201, 0x300c, 0x2847, 0x8161, 0x846a, 0x8000,
-	0x84a4, 0x1856, 0x883a, 0xa808, 0x28e2, 0x9c9f, 0xa8f3, 0x0864,
-	0xa82b, 0x300c, 0xa801, 0x3008, 0x28e1, 0x9c9f, 0x280d, 0xa204,
-	0x64c0, 0x67a0, 0x6fc0, 0x1814, 0x883b, 0x7023, 0x8576, 0x8677,
-	0xa80f, 0x786e, 0x883e, 0xa80c, 0x282b, 0xa205, 0x64a0, 0x67a0,
-	0x6fc0, 0x1814, 0x883b, 0x7023, 0x8576, 0x8677, 0xa801, 0x883e,
-	0x206b, 0x28c1, 0x9cc2, 0x2044, 0x2103, 0x20a2, 0x2081, 0xa8dc,
-	0xa207, 0x2901, 0xa80a, 0x0014, 0xa203, 0x8000, 0x85a4, 0x1872,
-	0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208, 0x856e, 0x866f, 0x0704,
-	0x3008, 0x9c9f, 0x0014, 0xa202, 0x8000, 0x85a4, 0x3009, 0x84a8,
-	0x19e2, 0xf848, 0x8174, 0x86eb, 0x85eb, 0x872e, 0x87a9, 0x883f,
-	0x08e6, 0xa8f1, 0xf861, 0xa8e8, 0xf801, 0x0014, 0xf881, 0x0016,
-	0x85b2, 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014, 0x8532, 0xf221,
-	0x0014, 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014, 0xa206, 0x6865,
-	0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016, 0x6042, 0x8008, 0xa8fa,
-	0x8000, 0x84a4, 0x8160, 0x842a, 0xf021, 0x3008, 0x84a8, 0x11d6,
-	0x7042, 0x20dd, 0x0011, 0x20d4, 0x8822, 0x0016, 0x8000, 0x2848,
-	0x1011, 0xa8fc, 0x3008, 0x8000, 0xa000, 0x2802, 0x1011, 0xa8fd,
-	0xa883, 0x3008, 0x283d, 0x1011, 0xa8fd, 0xa209, 0x0017, 0x300c,
-	0x8000, 0x85a4, 0x1de2, 0xdac1, 0x0014, 0xd301, 0x0014, 0x26e0,
-	0x873a, 0xfaa2, 0x19f2, 0x1fe2, 0x0014, 0xa20b, 0x0014, 0xa20d,
-	0x3806, 0x0210, 0x9ccc, 0x0704, 0x0000, 0x127e, 0x2091, 0x2200,
-	0x2049, 0x32f5, 0x7000, 0x7204, 0xa205, 0x720c, 0xa215, 0x7008,
-	0xa084, 0xfff7, 0xa205, 0x0040, 0x3307, 0x1078, 0x3380, 0x127f,
-	0x2000, 0x007c, 0x6428, 0x84ff, 0x0040, 0x3336, 0x2c70, 0x7004,
-	0xa0bc, 0x000f, 0xa7b8, 0x3346, 0x273c, 0x87fb, 0x00c0, 0x3324,
-	0x0048, 0x331c, 0x1078, 0x1eac, 0x609c, 0xa075, 0x0040, 0x3336,
-	0x0078, 0x330f, 0x2039, 0x333b, 0x2704, 0xae68, 0x6808, 0xa630,
-	0x680c, 0xa529, 0x8421, 0x0040, 0x3336, 0x8738, 0x2704, 0xa005,
-	0x00c0, 0x3325, 0x709c, 0xa075, 0x00c0, 0x330f, 0x007c, 0x0000,
-	0x0005, 0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000,
-	0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x333b,
-	0x3338, 0x0000, 0x0000, 0x8000, 0x0000, 0x333b, 0x0000, 0x3343,
-	0x3340, 0x0000, 0x0000, 0x0000, 0x0000, 0x3343, 0x0000, 0x333e,
-	0x333e, 0x0000, 0x0000, 0x8000, 0x0000, 0x333e, 0x0000, 0x3344,
-	0x3344, 0x0000, 0x0000, 0x0000, 0x0000, 0x3344, 0x127e, 0x2091,
-	0x2200, 0x2079, 0x3900, 0x2071, 0x0010, 0x7007, 0x000a, 0x7007,
-	0x0002, 0x7003, 0x0000, 0x2071, 0x0020, 0x7007, 0x000a, 0x7007,
-	0x0002, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c,
-	0x2049, 0x3380, 0x2019, 0x0000, 0x7004, 0x8004, 0x00c8, 0x33b2,
-	0x7007, 0x0012, 0x7108, 0x7008, 0xa106, 0x00c0, 0x338a, 0xa184,
-	0x01e0, 0x0040, 0x3395, 0x1078, 0x1eac, 0xa184, 0x4000, 0x00c0,
-	0x338a, 0xa19c, 0x300c, 0xa386, 0x2004, 0x0040, 0x33a7, 0xa386,
-	0x0008, 0x0040, 0x33b2, 0xa386, 0x200c, 0x00c0, 0x338a, 0x7200,
-	0x8204, 0x0048, 0x33b2, 0x730c, 0xa384, 0x00ff, 0x0040, 0x33b2,
-	0x1078, 0x1eac, 0x7007, 0x0012, 0x7000, 0xa084, 0x0001, 0x00c0,
-	0x33c3, 0x7310, 0x7014, 0xa305, 0x0040, 0x33c3, 0x700c, 0xa084,
-	0x00ff, 0x00c0, 0x3380, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004,
-	0xa084, 0x0008, 0x00c0, 0x33c7, 0x7007, 0x0012, 0x7108, 0x8103,
-	0x0048, 0x33cc, 0x7003, 0x0000, 0x2049, 0x0000, 0x007c, 0x107e,
-	0x007e, 0x127e, 0x157e, 0x2091, 0x2200, 0x7108, 0x1078, 0x33e7,
-	0x157f, 0x127f, 0x2091, 0x8001, 0x007f, 0x107f, 0x007c, 0x7204,
-	0x7500, 0x730c, 0xa384, 0x0300, 0x00c0, 0x3426, 0xa184, 0x0060,
-	0x00c0, 0x3442, 0x7008, 0x7108, 0xa106, 0x00c0, 0x33f2, 0xa184,
-	0x01e0, 0x00c0, 0x3442, 0xa184, 0x4000, 0x00c0, 0x33f2, 0xa986,
-	0x362f, 0x00c0, 0x341a, 0xa19c, 0x300c, 0xa386, 0x2004, 0x0040,
-	0x3411, 0xa386, 0x0008, 0x0040, 0x341a, 0xa386, 0x200c, 0x00c0,
-	0x33f2, 0x7200, 0x8204, 0x0048, 0x341a, 0x730c, 0xa384, 0x00ff,
-	0x00c0, 0x3426, 0xa184, 0x0007, 0x0079, 0x341e, 0x3428, 0x3436,
-	0x3426, 0x3436, 0x3426, 0x348f, 0x3426, 0x348d, 0x1078, 0x1eac,
-	0x7007, 0x0002, 0x8aff, 0x00c0, 0x3431, 0x2049, 0x0000, 0x0078,
-	0x3435, 0x1078, 0x3606, 0x00c0, 0x3431, 0x007c, 0x7007, 0x0002,
-	0x8aff, 0x00c0, 0x343d, 0x0078, 0x3441, 0x1078, 0x3606, 0x00c0,
-	0x343d, 0x007c, 0x7108, 0x7008, 0xa106, 0x00c0, 0x3442, 0xa184,
-	0x4000, 0x00c0, 0x3442, 0x7007, 0x0012, 0x7108, 0x7008, 0xa106,
-	0x00c0, 0x344d, 0xa184, 0x4000, 0x00c0, 0x344d, 0x00e0, 0x3456,
-	0x2091, 0x6000, 0x00e0, 0x345a, 0x2091, 0x6000, 0x7007, 0x0012,
-	0x7007, 0x0008, 0x7004, 0xa084, 0x0008, 0x00c0, 0x3462, 0x7007,
-	0x0012, 0x7108, 0x8103, 0x0048, 0x3467, 0x7003, 0x0000, 0x7000,
-	0xa005, 0x00c0, 0x347b, 0x7004, 0xa005, 0x00c0, 0x347b, 0x700c,
-	0xa005, 0x0040, 0x347d, 0x0078, 0x345e, 0x2049, 0x0000, 0x1078,
-	0x30b3, 0x6818, 0xa084, 0x8000, 0x0040, 0x3488, 0x681b, 0x0002,
-	0x007c, 0x1078, 0x1eac, 0x1078, 0x1eac, 0x1078, 0x34ed, 0x7210,
-	0x7114, 0x700c, 0xa09c, 0x00ff, 0x2800, 0xa300, 0xa211, 0xa189,
-	0x0000, 0x1078, 0x34ed, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200,
-	0xa322, 0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x34b2,
-	0x00c8, 0x34b2, 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60,
-	0x0078, 0x3499, 0x2b60, 0x8a07, 0x007e, 0x6004, 0xa084, 0x0008,
-	0x0040, 0x34be, 0xa7ba, 0x3340, 0x0078, 0x34c0, 0xa7ba, 0x3338,
-	0x007f, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x1078,
-	0x3380, 0x007c, 0x8738, 0x2704, 0xa005, 0x00c0, 0x34dd, 0x609c,
-	0xa005, 0x0040, 0x34ea, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080,
-	0x3346, 0x203c, 0x87fb, 0x1040, 0x1eac, 0x8a51, 0x0040, 0x34e9,
-	0x7008, 0x7508, 0xa52e, 0x00c0, 0x34e0, 0xa084, 0x0003, 0xa086,
+	0x78ec, 0xa084, 0x0021, 0x0040, 0x38ff, 0x0098, 0x38fd, 0x007f,
+	0x789a, 0x78ac, 0x007e, 0x7044, 0x780a, 0x007f, 0x007c, 0x78ec,
+	0xa084, 0x0002, 0x00c0, 0x461d, 0xa784, 0x007d, 0x00c0, 0x3913,
+	0x2700, 0x1078, 0x23ca, 0xa784, 0x0001, 0x00c0, 0x2f43, 0xa784,
+	0x0070, 0x0040, 0x3923, 0x0c7e, 0x2d60, 0x2f68, 0x1078, 0x2375,
+	0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040, 0x3930, 0x784b,
+	0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2461, 0x0078, 0x3854,
+	0xa784, 0x0004, 0x0040, 0x3963, 0x78b8, 0xa084, 0x4001, 0x0040,
+	0x3963, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2461,
+	0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0, 0x3963, 0x78c0,
+	0xa085, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00d2, 0x0078, 0x2438,
+	0x784b, 0x0008, 0x6818, 0xa084, 0x8000, 0x0040, 0x395f, 0x681b,
+	0x0015, 0xa684, 0x4000, 0x0040, 0x395f, 0x681b, 0x0007, 0x1078,
+	0x3868, 0x0078, 0x2438, 0x681b, 0x0003, 0x7858, 0xa084, 0x3f00,
+	0x681e, 0x682f, 0x0000, 0x6833, 0x0000, 0x784b, 0x0008, 0x78ec,
+	0xa084, 0x0003, 0x0040, 0x2944, 0x0018, 0x2438, 0x0078, 0x3673,
+	0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080,
+	0x5280, 0x2060, 0x2048, 0x7056, 0x6000, 0x705a, 0x6004, 0x705e,
+	0x2a60, 0x007c, 0x0079, 0x398c, 0x3994, 0x3995, 0x3994, 0x3997,
+	0x3994, 0x3994, 0x3994, 0x399c, 0x007c, 0x1078, 0x33c4, 0x1078,
+	0x4633, 0x7038, 0x600a, 0x007c, 0x70a0, 0xa005, 0x0040, 0x39a9,
+	0x2068, 0x1078, 0x1b45, 0x1078, 0x45b5, 0x1078, 0x45bc, 0x70a3,
+	0x0000, 0x007c, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x5040, 0x7000,
+	0xa086, 0x0007, 0x00c0, 0x39c0, 0x6110, 0x70bc, 0xa106, 0x00c0,
+	0x39c0, 0x0e7f, 0x1078, 0x1b52, 0x1078, 0x39c6, 0xa006, 0x007c,
+	0x2091, 0x8001, 0x0e7f, 0xa085, 0x0001, 0x007c, 0x0f7e, 0x0e7e,
+	0x2071, 0x5040, 0x0078, 0x21d9, 0x785b, 0x0000, 0x70af, 0x000e,
+	0x2009, 0x0100, 0x017e, 0x70a0, 0xa06d, 0x0040, 0x39db, 0x70a3,
+	0x0000, 0x0078, 0x39e1, 0x70b3, 0x0000, 0x1078, 0x1b6e, 0x0040,
+	0x39e7, 0x70ac, 0x6826, 0x1078, 0x3ac2, 0x0078, 0x39db, 0x017f,
+	0x157e, 0x0c7e, 0x0d7e, 0x20a9, 0x0008, 0x2061, 0x7410, 0x6000,
+	0xa105, 0x6002, 0x601c, 0xa06d, 0x0040, 0x39ff, 0x6800, 0x601e,
+	0x1078, 0x193d, 0x6008, 0x8000, 0x600a, 0x0078, 0x39f2, 0x6018,
+	0xa06d, 0x0040, 0x3a09, 0x6800, 0x601a, 0x1078, 0x193d, 0x0078,
+	0x39ff, 0xace0, 0x0008, 0x0070, 0x3a0f, 0x0078, 0x39ef, 0x709c,
+	0xa084, 0x8000, 0x0040, 0x3a16, 0x1078, 0x3b3c, 0x0d7f, 0x0c7f,
+	0x157f, 0x007c, 0x127e, 0x2091, 0x2300, 0x6804, 0xa084, 0x000f,
+	0x0079, 0x3a22, 0x3a32, 0x3a32, 0x3a32, 0x3a32, 0x3a32, 0x3a32,
+	0x3a34, 0x3a3a, 0x3a32, 0x3a32, 0x3a32, 0x3a32, 0x3a32, 0x3a3c,
+	0x3a32, 0x3a34, 0x1078, 0x23ca, 0x1078, 0x4466, 0x1078, 0x193d,
+	0x0078, 0x3a40, 0x6827, 0x000b, 0x1078, 0x4466, 0x1078, 0x3ac2,
+	0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x0098, 0x3a5e, 0x7830,
+	0xa084, 0x00c0, 0x00c0, 0x3a5e, 0x0d7e, 0x1078, 0x45c5, 0x2d00,
+	0x682e, 0x2009, 0x0004, 0x2001, 0x0000, 0x6827, 0x0084, 0x1078,
+	0x457e, 0x1078, 0x3ac2, 0x0d7f, 0x0078, 0x3a90, 0x7948, 0xa185,
+	0x4000, 0x784a, 0x0098, 0x3a67, 0x794a, 0x0078, 0x3a4c, 0x7828,
+	0xa086, 0x1834, 0x00c0, 0x3a70, 0xa185, 0x0004, 0x0078, 0x3a77,
+	0x7828, 0xa186, 0x1814, 0x00c0, 0x3a64, 0xa185, 0x000c, 0x784a,
+	0x789b, 0x000e, 0x78ab, 0x0002, 0x7858, 0xa084, 0x00ff, 0xa085,
+	0x0400, 0x785a, 0x70b4, 0xa080, 0x0091, 0x781a, 0x6827, 0x0002,
+	0x6827, 0x0084, 0x2009, 0x0004, 0x2001, 0x0000, 0x1078, 0x457e,
+	0x127f, 0x007c, 0x0d7e, 0x6b14, 0x1078, 0x1be0, 0x0040, 0x3a9f,
+	0x2068, 0x6827, 0x0002, 0x1078, 0x3ac2, 0x0078, 0x3a94, 0x0d7f,
+	0x007c, 0x0d7e, 0x6b14, 0x6c28, 0xa4a4, 0x00ff, 0x1078, 0x1b7e,
+	0x0040, 0x3aaf, 0x2068, 0x6827, 0x0002, 0x1078, 0x3ac2, 0x0d7f,
+	0x007c, 0x0d7e, 0x6b14, 0xa39c, 0x00ff, 0x1078, 0x1bb1, 0x0040,
+	0x3ac0, 0x2068, 0x6827, 0x0002, 0x1078, 0x3ac2, 0x0078, 0x3ab5,
+	0x0d7f, 0x007c, 0x0c7e, 0x6914, 0x1078, 0x3b33, 0x6904, 0xa18c,
+	0x00ff, 0xa186, 0x0006, 0x0040, 0x3add, 0xa186, 0x000d, 0x0040,
+	0x3afc, 0xa186, 0x0017, 0x00c0, 0x3ad9, 0x1078, 0x193d, 0x0078,
+	0x3adb, 0x1078, 0x1c55, 0x0c7f, 0x007c, 0x6004, 0x8001, 0x0048,
+	0x3afa, 0x6006, 0x2009, 0x0000, 0xa684, 0x0001, 0x00c0, 0x3aea,
+	0xa18d, 0x8000, 0xa684, 0x0004, 0x0040, 0x3af0, 0xa18d, 0x0002,
+	0x691e, 0x6823, 0x0000, 0x7104, 0x810f, 0x6818, 0xa105, 0x681a,
+	0x0078, 0x3ad9, 0x1078, 0x23ca, 0x6018, 0xa005, 0x00c0, 0x3b0b,
+	0x6008, 0x8001, 0x0048, 0x3b0b, 0x600a, 0x601c, 0x6802, 0x2d00,
+	0x601e, 0x0078, 0x3b21, 0xac88, 0x0006, 0x2104, 0xa005, 0x0040,
+	0x3b14, 0x2008, 0x0078, 0x3b0d, 0x6802, 0x2d0a, 0x6008, 0x8001,
+	0x0048, 0x3adb, 0x600a, 0x6018, 0x2068, 0x6800, 0x601a, 0x0078,
+	0x3b05, 0x157e, 0x137e, 0x147e, 0x0c7e, 0x0d7e, 0x1078, 0x191a,
+	0x2da0, 0x137f, 0x20a9, 0x0031, 0x53a3, 0x0c7f, 0x147f, 0x137f,
+	0x157f, 0x0078, 0x3ad9, 0xa184, 0x001f, 0x8003, 0x8003, 0x8003,
+	0xa080, 0x7410, 0x2060, 0x007c, 0x2019, 0x5051, 0x2304, 0xa085,
+	0x0001, 0x201a, 0x2019, 0x0102, 0x2304, 0xa085, 0x0001, 0x201a,
+	0x007c, 0x2019, 0x5051, 0x2304, 0xa084, 0xfffe, 0x201a, 0x2019,
+	0x0102, 0x2304, 0xa084, 0xfffe, 0x201a, 0x007c, 0x7990, 0xa18c,
+	0xfff8, 0x7992, 0x70b4, 0xa080, 0x00d8, 0x781a, 0x0078, 0x2438,
+	0x70a3, 0x0000, 0x7003, 0x0000, 0x7043, 0x0001, 0x7037, 0x0000,
+	0x0018, 0x23ef, 0x1078, 0x1b6e, 0x0040, 0x3b91, 0x2009, 0x500f,
+	0x200b, 0x0000, 0x68bc, 0x2060, 0x6100, 0xa184, 0x0300, 0x0040,
+	0x3b85, 0x6827, 0x000e, 0xa084, 0x0200, 0x0040, 0x3b81, 0x6827,
+	0x0017, 0x1078, 0x3ac2, 0x0078, 0x3b60, 0x7000, 0xa086, 0x0007,
+	0x00c0, 0x3be3, 0x2d00, 0x70a2, 0xad80, 0x000f, 0x7036, 0x0078,
+	0x3b98, 0x7040, 0xa086, 0x0001, 0x0040, 0x2471, 0x0078, 0x2438,
+	0x2031, 0x0000, 0x691c, 0xa184, 0x0002, 0x0040, 0x3ba1, 0xa6b5,
+	0x0004, 0xa184, 0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x3c72,
+	0x2004, 0xa635, 0x6820, 0xa084, 0x0400, 0x0040, 0x3bb9, 0x789b,
+	0x0018, 0x78ab, 0x0003, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5,
+	0x1000, 0x6820, 0xa084, 0x8000, 0x0040, 0x3bc5, 0xa6b5, 0x0400,
+	0x789b, 0x000e, 0x6824, 0x8007, 0x78aa, 0xa684, 0x0200, 0x0040,
+	0x3bdf, 0x682c, 0x78d2, 0x6830, 0x78d6, 0xa684, 0x0100, 0x0040,
+	0x3bdd, 0x682c, 0xa084, 0x0001, 0x0040, 0x3bdd, 0x7888, 0xa084,
+	0x0040, 0x0040, 0x3bdd, 0xa6b5, 0x8000, 0x1078, 0x45ad, 0x7e5a,
+	0x6eb6, 0x0078, 0x45e4, 0x1078, 0x38c6, 0x00c0, 0x3c6c, 0x702c,
+	0x8004, 0x0048, 0x3bf1, 0x2019, 0x4cfd, 0x1078, 0x2255, 0x702f,
+	0x0001, 0x2011, 0x0001, 0x2031, 0x1000, 0x789b, 0x0018, 0x6814,
+	0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x691c, 0xa184, 0x0002,
+	0x0040, 0x3c0a, 0xa6b5, 0x0004, 0x78ab, 0x0020, 0x6828, 0x78aa,
+	0xa290, 0x0002, 0x6820, 0xa084, 0x8000, 0x0040, 0x3c18, 0xa6b5,
+	0x0400, 0x789b, 0x000e, 0x6824, 0x8007, 0x78aa, 0x0078, 0x3c26,
+	0x681c, 0xa084, 0x8000, 0x00c0, 0x3c26, 0xa6b5, 0x0800, 0x6820,
+	0xa084, 0x0100, 0x0040, 0x3c26, 0xa6b5, 0x4000, 0x681c, 0xa084,
+	0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x3c72, 0x2004, 0xa635,
+	0xa684, 0x0100, 0x0040, 0x3c40, 0x682c, 0xa084, 0x0001, 0x0040,
+	0x3c40, 0x7888, 0xa084, 0x0040, 0x0040, 0x3c40, 0xa6b5, 0x8000,
+	0x789b, 0x007e, 0x7eae, 0x6eb6, 0x6814, 0x8007, 0x78aa, 0x7882,
+	0x7aaa, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3c6c, 0x0018, 0x3c6c,
+	0x70b4, 0xa080, 0x00dd, 0x781a, 0x1078, 0x38de, 0xa684, 0x0200,
+	0x0040, 0x3c60, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x1078, 0x45ad,
+	0x2d00, 0x70a2, 0x704a, 0x6810, 0x70be, 0x7003, 0x0007, 0xad80,
+	0x000f, 0x7036, 0x0078, 0x2438, 0x1078, 0x1b45, 0x1078, 0x38de,
+	0x0078, 0x2438, 0x0000, 0x0300, 0x0200, 0x0000, 0x1078, 0x23ca,
+	0x2300, 0x0079, 0x3c7b, 0x3c7e, 0x3c7e, 0x3c80, 0x1078, 0x23ca,
+	0x1078, 0x45bc, 0x6924, 0xa184, 0x00ff, 0xa086, 0x000a, 0x0040,
+	0x3c92, 0xa184, 0xff00, 0xa085, 0x000a, 0x6826, 0x1078, 0x1b45,
+	0x0078, 0x3b60, 0x2001, 0x000a, 0x1078, 0x454c, 0x0078, 0x3b60,
+	0xa282, 0x0005, 0x0050, 0x3c9e, 0x1078, 0x23ca, 0x7000, 0xa084,
+	0x0007, 0x10c0, 0x398a, 0x1078, 0x191a, 0x00c0, 0x3cbd, 0xa684,
+	0x0004, 0x0040, 0x3caf, 0x2001, 0x2800, 0x0078, 0x3cb1, 0x2001,
+	0x0800, 0x71b4, 0xa188, 0x0091, 0x789b, 0x000e, 0x78aa, 0x2031,
+	0x0400, 0x7e5a, 0x791a, 0x0078, 0x2438, 0x6807, 0x0106, 0x680b,
+	0x0000, 0x689f, 0x0000, 0x6827, 0x0000, 0xa386, 0x0002, 0x00c0,
+	0x3cde, 0xa286, 0x0002, 0x00c0, 0x3cde, 0x78a0, 0xa005, 0x00c0,
+	0x3cde, 0xa484, 0x8000, 0x00c0, 0x3cde, 0x78e4, 0xa084, 0x0008,
+	0x0040, 0x3cde, 0xa6b5, 0x0008, 0x2019, 0x0000, 0x1078, 0x40d3,
+	0x2d00, 0x70a2, 0x704a, 0x7003, 0x0007, 0x7037, 0x0000, 0x6824,
+	0xa084, 0x0080, 0x0040, 0x3cf0, 0x1078, 0x4180, 0x0078, 0x2438,
+	0x2300, 0x0079, 0x3cf3, 0x3cf6, 0x3d77, 0x3d96, 0x2200, 0x0079,
+	0x3cf9, 0x3cfe, 0x3d0e, 0x3d34, 0x3d40, 0x3d63, 0x2029, 0x0001,
+	0xa026, 0x2011, 0x0000, 0x1078, 0x428d, 0x0079, 0x3d07, 0x3d0c,
+	0x2438, 0x3b60, 0x3d0c, 0x3d0c, 0x1078, 0x23ca, 0x7990, 0xa18c,
+	0x0007, 0x00c0, 0x3d15, 0x2009, 0x0008, 0x2011, 0x0001, 0xa684,
+	0x0004, 0x0040, 0x3d1d, 0x2011, 0x0003, 0x2220, 0xa12a, 0x2011,
+	0x0001, 0x1078, 0x428d, 0x0079, 0x3d25, 0x3d2a, 0x2438, 0x3b60,
+	0x3d32, 0x3d2c, 0x0078, 0x45ea, 0x70ab, 0x3d30, 0x0078, 0x2438,
+	0x0078, 0x3d2a, 0x1078, 0x23ca, 0xa684, 0x0010, 0x0040, 0x3d3e,
+	0x1078, 0x414f, 0x0040, 0x3d3e, 0x0078, 0x2438, 0x0078, 0x41bc,
+	0x6000, 0xa084, 0x0002, 0x0040, 0x3d5d, 0x70b4, 0xa080, 0x00cd,
+	0x781a, 0x0d7e, 0x1078, 0x45c5, 0x2d00, 0x682e, 0x6827, 0x0000,
+	0x1078, 0x3ac2, 0x0d7f, 0x1078, 0x193d, 0x7003, 0x0000, 0x7037,
+	0x0000, 0x704b, 0x0000, 0x0078, 0x3b60, 0xa684, 0x0004, 0x00c0,
+	0x3d63, 0x0078, 0x45ea, 0x6000, 0xa084, 0x0004, 0x00c0, 0x3d75,
+	0x6000, 0xa084, 0x0001, 0x0040, 0x3d75, 0x70ab, 0x3d75, 0x2001,
+	0x0007, 0x1078, 0x4544, 0x0078, 0x45f0, 0x0078, 0x45ea, 0x2200,
+	0x0079, 0x3d7a, 0x3d7f, 0x3d7f, 0x3d7f, 0x3d81, 0x3d7f, 0x1078,
+	0x23ca, 0x70a7, 0x3d85, 0x0078, 0x45f6, 0x2011, 0x0018, 0x1078,
+	0x4287, 0x0079, 0x3d8b, 0x3d90, 0x2438, 0x3b60, 0x3d92, 0x3d94,
+	0x1078, 0x23ca, 0x1078, 0x23ca, 0x1078, 0x23ca, 0x2200, 0x0079,
+	0x3d99, 0x3d9e, 0x3da0, 0x3da0, 0x3d9e, 0x3d9e, 0x1078, 0x23ca,
+	0x78e4, 0xa084, 0x0008, 0x0040, 0x3db5, 0x70a7, 0x3da9, 0x0078,
+	0x45f6, 0x2011, 0x0004, 0x1078, 0x4287, 0x0079, 0x3daf, 0x3db5,
+	0x2438, 0x3b60, 0x3db5, 0x3dbf, 0x3dc3, 0x70ab, 0x3dbd, 0x2001,
+	0x0003, 0x1078, 0x4544, 0x0078, 0x45f0, 0x0078, 0x45ea, 0x70ab,
+	0x3db5, 0x0078, 0x2438, 0x70ab, 0x3dc7, 0x0078, 0x2438, 0x0078,
+	0x3dbd, 0xa282, 0x0003, 0x0050, 0x3dcf, 0x1078, 0x23ca, 0xa386,
+	0x0002, 0x00c0, 0x3de8, 0xa286, 0x0002, 0x00c0, 0x3dee, 0x78a0,
+	0xa005, 0x00c0, 0x3dee, 0xa484, 0x8000, 0x00c0, 0x3dee, 0x78e4,
+	0xa084, 0x0008, 0x0040, 0x3de8, 0xa6b5, 0x0008, 0x2019, 0x0000,
+	0xa684, 0x0008, 0x0040, 0x3dee, 0x1078, 0x412c, 0x6810, 0x70be,
+	0x7003, 0x0007, 0x2300, 0x0079, 0x3df5, 0x3df8, 0x3e25, 0x3e2d,
+	0x2200, 0x0079, 0x3dfb, 0x3e00, 0x3dfe, 0x3e19, 0x1078, 0x23ca,
+	0x7990, 0xa1ac, 0x0007, 0xa026, 0x2011, 0x0001, 0x1078, 0x428d,
+	0x0079, 0x3e0a, 0x3e0f, 0x2438, 0x3b60, 0x3e17, 0x3e11, 0x0078,
+	0x45ea, 0x70ab, 0x3e15, 0x0078, 0x2438, 0x0078, 0x3e0f, 0x1078,
+	0x23ca, 0xa684, 0x0010, 0x0040, 0x3e23, 0x1078, 0x414f, 0x0040,
+	0x3e23, 0x0078, 0x2438, 0x0078, 0x41bc, 0x2200, 0x0079, 0x3e28,
+	0x3e2b, 0x3e2b, 0x3e2b, 0x1078, 0x23ca, 0x2200, 0x0079, 0x3e30,
+	0x3e33, 0x3e35, 0x3e35, 0x1078, 0x23ca, 0x78e4, 0xa084, 0x0008,
+	0x0040, 0x3e4a, 0x70a7, 0x3e3e, 0x0078, 0x45f6, 0x2011, 0x0004,
+	0x1078, 0x4287, 0x0079, 0x3e44, 0x3e4a, 0x2438, 0x3b60, 0x3e4a,
+	0x3e54, 0x3e58, 0x70ab, 0x3e52, 0x2001, 0x0003, 0x1078, 0x4544,
+	0x0078, 0x45f0, 0x0078, 0x45ea, 0x70ab, 0x3e4a, 0x0078, 0x2438,
+	0x70ab, 0x3e5c, 0x0078, 0x2438, 0x0078, 0x3e52, 0x2300, 0x0079,
+	0x3e61, 0x3e66, 0x3e68, 0x3e64, 0x1078, 0x23ca, 0x70a4, 0x007a,
+	0x70a4, 0x007a, 0xa282, 0x0002, 0x0050, 0x3e70, 0x1078, 0x23ca,
+	0xa684, 0x0200, 0x0040, 0x3e7a, 0x1078, 0x45b5, 0x1078, 0x426f,
+	0x1078, 0x45bc, 0x2300, 0x0079, 0x3e7d, 0x3e80, 0x3ea4, 0x3f0a,
+	0xa286, 0x0001, 0x0040, 0x3e86, 0x1078, 0x23ca, 0xa684, 0x0200,
+	0x0040, 0x3e8e, 0x1078, 0x45b5, 0x1078, 0x45bc, 0x2001, 0x0001,
+	0x1078, 0x454c, 0x78b8, 0xa084, 0xc001, 0x0040, 0x3ea0, 0x7848,
+	0xa085, 0x0008, 0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x3e9b,
+	0x7003, 0x0000, 0x0078, 0x3b60, 0x2200, 0x0079, 0x3ea7, 0x3ea9,
+	0x3eda, 0x70a7, 0x3ead, 0x0078, 0x45f6, 0x2011, 0x000d, 0x1078,
+	0x4287, 0x0079, 0x3eb3, 0x3eba, 0x2438, 0x3b60, 0x3ec2, 0x3eca,
+	0x3ed0, 0x3ed2, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
+	0x0078, 0x45e4, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
+	0x0078, 0x45e4, 0x70ab, 0x3ece, 0x0078, 0x2438, 0x0078, 0x3eba,
+	0x1078, 0x23ca, 0x70ab, 0x3ed6, 0x0078, 0x2438, 0x1078, 0x45fc,
+	0x0078, 0x2438, 0x70a7, 0x3ede, 0x0078, 0x45f6, 0x2011, 0x0012,
+	0x1078, 0x4287, 0x0079, 0x3ee4, 0x3eea, 0x2438, 0x3b60, 0x3ef6,
+	0x3efe, 0x3f04, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
+	0x70b4, 0xa080, 0x00a5, 0x781a, 0x0078, 0x2438, 0xa6b4, 0x00ff,
+	0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078, 0x45e4, 0x70ab, 0x3f02,
+	0x0078, 0x2438, 0x0078, 0x3eea, 0x70ab, 0x3f08, 0x0078, 0x2438,
+	0x0078, 0x3ef6, 0xa286, 0x0001, 0x0040, 0x3f10, 0x1078, 0x23ca,
+	0x70a7, 0x3f14, 0x0078, 0x45f6, 0x2011, 0x0015, 0x1078, 0x4287,
+	0x0079, 0x3f1a, 0x3f1f, 0x2438, 0x3b60, 0x3f2d, 0x3f39, 0xa6b4,
+	0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x783b, 0x1301, 0x70b4,
+	0xa080, 0x00b5, 0x781a, 0x0078, 0x2438, 0xa6b4, 0x00ff, 0xa6b5,
+	0x0400, 0x6eb6, 0x7e5a, 0x70b4, 0xa080, 0x00a5, 0x781a, 0x0078,
+	0x2438, 0x70ab, 0x3f3d, 0x0078, 0x2438, 0x0078, 0x3f1f, 0xa282,
+	0x0003, 0x0050, 0x3f45, 0x1078, 0x23ca, 0x2300, 0x0079, 0x3f48,
+	0x3f4b, 0x3f82, 0x3fdd, 0xa286, 0x0001, 0x0040, 0x3f51, 0x1078,
+	0x23ca, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x3f5e,
+	0x1078, 0x3ac2, 0x7003, 0x0000, 0x0078, 0x3b60, 0x683b, 0x0000,
+	0x6837, 0x0000, 0xa684, 0x0200, 0x0040, 0x3f6c, 0x1078, 0x45b5,
+	0x1078, 0x426f, 0x1078, 0x45bc, 0x2001, 0x0001, 0x1078, 0x454c,
+	0x78b8, 0xa084, 0xc001, 0x0040, 0x3f7e, 0x7848, 0xa085, 0x0008,
+	0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x3f79, 0x7003, 0x0000,
+	0x0078, 0x3b60, 0x2200, 0x0079, 0x3f85, 0x3f87, 0x3fb8, 0x70a7,
+	0x3f8b, 0x0078, 0x45f6, 0x2011, 0x000d, 0x1078, 0x4287, 0x0079,
+	0x3f91, 0x3f98, 0x2438, 0x3b60, 0x3fa0, 0x3fa8, 0x3fae, 0x3fb0,
+	0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4,
+	0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4,
+	0x70ab, 0x3fac, 0x0078, 0x2438, 0x0078, 0x3f98, 0x1078, 0x23ca,
+	0x70ab, 0x3fb4, 0x0078, 0x2438, 0x1078, 0x45fc, 0x0078, 0x2438,
+	0x70a7, 0x3fbc, 0x0078, 0x45f6, 0x2011, 0x0005, 0x1078, 0x4287,
+	0x0079, 0x3fc2, 0x3fc7, 0x2438, 0x3b60, 0x3fcf, 0x3fd7, 0xa6b4,
+	0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4, 0xa6b4,
+	0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4, 0x70ab,
+	0x3fdb, 0x0078, 0x2438, 0x0078, 0x3fc7, 0xa286, 0x0001, 0x0040,
+	0x3fe3, 0x1078, 0x23ca, 0x70a7, 0x3fe7, 0x0078, 0x45f6, 0x2011,
+	0x0006, 0x1078, 0x4287, 0x0079, 0x3fed, 0x3ff2, 0x2438, 0x3b60,
+	0x3ff8, 0x4002, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4,
+	0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0xa6b5, 0x4000, 0x7e5a,
+	0x0078, 0x45e4, 0x70ab, 0x4006, 0x0078, 0x2438, 0x0078, 0x3ff2,
+	0x2300, 0x0079, 0x400b, 0x4010, 0x400e, 0x400e, 0x1078, 0x23ca,
+	0x1078, 0x23ca, 0x2300, 0x71a8, 0xa005, 0x017a, 0x6810, 0x70be,
+	0xa282, 0x0003, 0x0050, 0x401e, 0x1078, 0x23ca, 0x2300, 0x0079,
+	0x4021, 0x4024, 0x4037, 0x4059, 0x82ff, 0x00c0, 0x4029, 0x1078,
+	0x23ca, 0xa684, 0x0200, 0x0040, 0x4031, 0x1078, 0x45b5, 0x1078,
+	0x45bc, 0x2001, 0x0001, 0x1078, 0x454c, 0x0078, 0x2438, 0xa296,
+	0x0002, 0x0040, 0x4040, 0x82ff, 0x0040, 0x4040, 0x1078, 0x23ca,
+	0x70a7, 0x4044, 0x0078, 0x45f6, 0x2011, 0x0018, 0x1078, 0x4287,
+	0x0079, 0x404a, 0x404f, 0x2438, 0x3b60, 0x4051, 0x4053, 0x0078,
+	0x45e4, 0x0078, 0x45e4, 0x70ab, 0x4057, 0x0078, 0x2438, 0x0078,
+	0x404f, 0x2200, 0x0079, 0x405c, 0x405e, 0x4077, 0x70a7, 0x4062,
+	0x0078, 0x45f6, 0x2011, 0x0017, 0x1078, 0x4287, 0x0079, 0x4068,
+	0x406d, 0x2438, 0x3b60, 0x406f, 0x4071, 0x0078, 0x45e4, 0x0078,
+	0x45e4, 0x70ab, 0x4075, 0x0078, 0x2438, 0x0078, 0x406d, 0xa484,
+	0x8000, 0x00c0, 0x40c1, 0xa684, 0x0100, 0x0040, 0x408b, 0x1078,
+	0x45b5, 0x1078, 0x426f, 0x1078, 0x45bc, 0x7848, 0xa085, 0x000c,
+	0x784a, 0x0078, 0x408f, 0x78d8, 0x78d2, 0x78dc, 0x78d6, 0xa6b4,
+	0xefff, 0x7e5a, 0x70a7, 0x4096, 0x0078, 0x45f6, 0x2011, 0x000d,
+	0x1078, 0x4287, 0x0079, 0x409c, 0x40a3, 0x2438, 0x3b60, 0x40a3,
+	0x40b1, 0x40b7, 0x40b9, 0xa684, 0x0100, 0x0040, 0x40af, 0x1078,
+	0x4573, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x1078, 0x45ad, 0x0078,
+	0x45e4, 0x70ab, 0x40b5, 0x0078, 0x2438, 0x0078, 0x40a3, 0x1078,
+	0x23ca, 0x70ab, 0x40bd, 0x0078, 0x2438, 0x1078, 0x45fc, 0x0078,
+	0x2438, 0x1078, 0x45bc, 0x70ab, 0x40cb, 0x2001, 0x0003, 0x1078,
+	0x4544, 0x0078, 0x45f0, 0x1078, 0x45ad, 0x682c, 0x78d2, 0x6830,
+	0x78d6, 0x0078, 0x45e4, 0x70b8, 0x6812, 0x70be, 0x8000, 0x70ba,
+	0x681b, 0x0000, 0xa684, 0x0008, 0x0040, 0x40f6, 0x157e, 0x137e,
+	0x147e, 0x7890, 0x8004, 0x8004, 0x8004, 0x8004, 0xa084, 0x000f,
+	0x681a, 0x80ac, 0x789b, 0x0000, 0xaf80, 0x002b, 0x2098, 0xad80,
+	0x000b, 0x20a0, 0x53a5, 0x147f, 0x137f, 0x157f, 0xa6c4, 0x0f00,
+	0xa684, 0x0002, 0x00c0, 0x4102, 0x692c, 0x810d, 0x810d, 0x810d,
+	0x0078, 0x410f, 0x789b, 0x0010, 0x79ac, 0x0078, 0x410f, 0x017e,
+	0x2009, 0x0005, 0x2001, 0x3d00, 0x1078, 0x457e, 0x017f, 0xa184,
+	0x001f, 0xa805, 0x6816, 0x1078, 0x3b33, 0x68be, 0xa684, 0x0004,
+	0x0040, 0x4120, 0xa18c, 0xff00, 0x78a8, 0xa084, 0x00ff, 0xa105,
+	0x682a, 0xa6b4, 0x00ff, 0x6000, 0xa084, 0x0008, 0x0040, 0x412a,
+	0xa6b5, 0x4000, 0x6eb6, 0x007c, 0x157e, 0x137e, 0x147e, 0x6918,
+	0x7890, 0x8004, 0x8004, 0x8004, 0x8004, 0xa084, 0x000f, 0x007e,
+	0xa100, 0x681a, 0x007f, 0x8000, 0x8004, 0x0040, 0x414b, 0x20a8,
+	0x8104, 0xa080, 0x000b, 0xad00, 0x20a0, 0x789b, 0x0000, 0xaf80,
+	0x002b, 0x2098, 0x53a5, 0x147f, 0x137f, 0x157f, 0x007c, 0x682c,
+	0xa084, 0x0020, 0x00c0, 0x4157, 0x620c, 0x0078, 0x4158, 0x6210,
+	0x6b18, 0x2300, 0xa202, 0x0040, 0x4178, 0x2018, 0xa382, 0x000e,
+	0x0048, 0x4168, 0x0040, 0x4168, 0x2019, 0x000e, 0x0078, 0x416c,
+	0x7858, 0xa084, 0xffef, 0x785a, 0x783b, 0x1b01, 0x7893, 0x0000,
+	0x7ba2, 0x70b4, 0xa080, 0x008e, 0x781a, 0xa085, 0x0001, 0x007c,
+	0x7858, 0xa084, 0xffef, 0x785a, 0x7893, 0x0000, 0xa006, 0x007c,
+	0x6904, 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x418d, 0xa196,
+	0x000f, 0x0040, 0x418d, 0x6807, 0x0117, 0x6914, 0x1078, 0x3b33,
+	0x6100, 0x8104, 0x00c8, 0x41a8, 0x601c, 0xa005, 0x0040, 0x419c,
+	0x2001, 0x0800, 0x0078, 0x41aa, 0x0d7e, 0x6824, 0x007e, 0x1078,
+	0x45c5, 0x007f, 0x6826, 0x2d00, 0x682e, 0x1078, 0x3ac2, 0x0d7f,
+	0x2001, 0x0200, 0x6826, 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820,
+	0xa085, 0x8000, 0x6822, 0x2031, 0x0400, 0x6eb6, 0x7e5a, 0x71b4,
+	0xa188, 0x0091, 0x791a, 0x007c, 0xa6c4, 0x0f00, 0xa684, 0x0002,
+	0x00c0, 0x41cf, 0x692c, 0x810d, 0x810d, 0x810d, 0xa184, 0x001f,
+	0xa805, 0x6816, 0x1078, 0x3b33, 0x68be, 0x0078, 0x41d2, 0x6914,
+	0x1078, 0x3b33, 0x6100, 0x8104, 0x00c8, 0x421c, 0xa184, 0x0300,
+	0x0040, 0x41de, 0x6807, 0x0117, 0x0078, 0x41fc, 0x6004, 0xa005,
+	0x00c0, 0x4205, 0x6807, 0x0117, 0x601c, 0xa005, 0x00c0, 0x41f2,
+	0x0d7e, 0x1078, 0x45c5, 0x6827, 0x0034, 0x2d00, 0x682e, 0x1078,
+	0x3ac2, 0x0d7f, 0xa684, 0x0004, 0x0040, 0x41fc, 0x2031, 0x0400,
+	0x2001, 0x2800, 0x0078, 0x4200, 0x2031, 0x0400, 0x2001, 0x0800,
+	0x71b4, 0xa188, 0x0091, 0x0078, 0x424a, 0x6018, 0xa005, 0x00c0,
+	0x41f2, 0x601c, 0xa005, 0x00c0, 0x41f2, 0x689f, 0x0000, 0x6827,
+	0x003d, 0xa684, 0x0001, 0x0040, 0x4258, 0xa6b5, 0x0800, 0x71b4,
+	0xa188, 0x00ae, 0x0078, 0x4253, 0x6807, 0x0117, 0x2031, 0x0400,
+	0x692c, 0xa18c, 0x00ff, 0xa186, 0x0012, 0x00c0, 0x422d, 0x2001,
+	0x4265, 0x2009, 0x0001, 0x0078, 0x423e, 0xa186, 0x0003, 0x00c0,
+	0x4237, 0x2001, 0x4266, 0x2009, 0x0012, 0x0078, 0x423e, 0x2001,
+	0x0200, 0x71b4, 0xa188, 0x0091, 0x0078, 0x424a, 0x1078, 0x4598,
+	0x78a3, 0x0000, 0x681c, 0xa085, 0x0040, 0x681e, 0x71b4, 0xa188,
+	0x00da, 0xa006, 0x6826, 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820,
+	0xa085, 0x8000, 0x6822, 0x6eb6, 0x7e5a, 0x791a, 0x0078, 0x2438,
+	0x6eb6, 0x1078, 0x3ac2, 0x6810, 0x70be, 0x7003, 0x0007, 0x70a3,
+	0x0000, 0x704b, 0x0000, 0x0078, 0x2438, 0x0023, 0x0070, 0x0005,
+	0x0000, 0x0a00, 0x0000, 0x0000, 0x0025, 0x0000, 0x0000, 0x683b,
+	0x0000, 0x6837, 0x0000, 0xa684, 0x0200, 0x0040, 0x4286, 0x78b8,
+	0xa08c, 0x001f, 0xa084, 0x8000, 0x0040, 0x427f, 0x8108, 0x78d8,
+	0xa100, 0x6836, 0x78dc, 0xa081, 0x0000, 0x683a, 0x007c, 0x7990,
+	0x810f, 0xa5ac, 0x0007, 0x2021, 0x0000, 0xa480, 0x0010, 0x789a,
+	0x79a8, 0xa18c, 0x00ff, 0xa184, 0x0080, 0x00c0, 0x42b5, 0xa182,
+	0x0020, 0x00c8, 0x42cf, 0xa182, 0x0012, 0x00c8, 0x4536, 0x2100,
+	0x1079, 0x42a3, 0x007c, 0x4536, 0x447e, 0x4536, 0x4536, 0x42dc,
+	0x42df, 0x4319, 0x434f, 0x4381, 0x4384, 0x4536, 0x4536, 0x433a,
+	0x43a8, 0x43e2, 0x4536, 0x4536, 0x4409, 0xa18c, 0x001f, 0x6814,
+	0xa084, 0x001f, 0xa106, 0x0040, 0x42cc, 0x70b4, 0xa080, 0x00cd,
+	0x781a, 0x2001, 0x0014, 0x1078, 0x454c, 0x1078, 0x45bc, 0x7003,
+	0x0000, 0x2001, 0x0002, 0x007c, 0x2001, 0x0000, 0x007c, 0xa182,
+	0x0024, 0x00c8, 0x4536, 0xa184, 0x0003, 0x1079, 0x42a3, 0x007c,
+	0x4536, 0x4536, 0x4536, 0x4536, 0x1078, 0x4536, 0x007c, 0x2200,
+	0x0079, 0x42e2, 0x440c, 0x440c, 0x4306, 0x4306, 0x4306, 0x4306,
+	0x4306, 0x4306, 0x4306, 0x4306, 0x4304, 0x4306, 0x42fb, 0x4306,
+	0x4306, 0x4306, 0x4306, 0x4306, 0x430e, 0x4311, 0x440c, 0x4311,
+	0x4306, 0x4306, 0x4306, 0x0c7e, 0x077e, 0x6f14, 0x1078, 0x36b0,
+	0x077f, 0x0c7f, 0x0078, 0x4306, 0x1078, 0x44d1, 0x6827, 0x02b3,
+	0x2009, 0x000b, 0x2001, 0x4800, 0x0078, 0x4440, 0x1078, 0x452b,
+	0x007c, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4800, 0x0078,
+	0x4428, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0,
+	0x4323, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078, 0x45c5, 0x6827,
+	0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3a92, 0x1078,
+	0x4466, 0x2b68, 0x1078, 0x3ac2, 0x0d7f, 0x1078, 0x3ac2, 0x2001,
+	0x0002, 0x007c, 0x1078, 0x4466, 0x2001, 0x0017, 0x1078, 0x454c,
+	0x70a3, 0x0000, 0x2009, 0x5038, 0x200b, 0x0006, 0x70af, 0x0017,
+	0x2009, 0x0200, 0x1078, 0x39d2, 0x2001, 0x0001, 0x007c, 0x2200,
+	0x0079, 0x4352, 0x440c, 0x443d, 0x443d, 0x443d, 0x4373, 0x444d,
+	0x4379, 0x444d, 0x444d, 0x4450, 0x4450, 0x4455, 0x4455, 0x436b,
+	0x436b, 0x443d, 0x443d, 0x444d, 0x443d, 0x4379, 0x440c, 0x4379,
+	0x4379, 0x4379, 0x4379, 0x6827, 0x0084, 0x2009, 0x000b, 0x2001,
+	0x4300, 0x0078, 0x445f, 0x2009, 0x000b, 0x2001, 0x4300, 0x0078,
+	0x4440, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4300, 0x0078,
+	0x4428, 0x2001, 0x0000, 0x007c, 0x2200, 0x0079, 0x4387, 0x440c,
+	0x43a0, 0x43a0, 0x43a0, 0x43a0, 0x444d, 0x444d, 0x444d, 0x444d,
+	0x444d, 0x444d, 0x444d, 0x444d, 0x43a0, 0x43a0, 0x43a0, 0x43a0,
+	0x444d, 0x43a0, 0x43a0, 0x444d, 0x444d, 0x444d, 0x444d, 0x440c,
+	0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4300, 0x0078, 0x4428,
+	0xa684, 0x0004, 0x00c0, 0x43bc, 0x6804, 0xa084, 0x00ff, 0xa086,
+	0x0006, 0x00c0, 0x4536, 0x1078, 0x4466, 0x6807, 0x0117, 0x1078,
+	0x3ac2, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084, 0x0004, 0x0040,
+	0x4536, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0,
+	0x43cb, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078, 0x45c5, 0x6827,
+	0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3aa1, 0x1078,
+	0x4466, 0x2b68, 0x1078, 0x3ac2, 0x0d7f, 0x1078, 0x3ac2, 0x2001,
+	0x0002, 0x007c, 0x6000, 0xa084, 0x0004, 0x0040, 0x4536, 0x2d58,
+	0x6a04, 0xa294, 0x00ff, 0xa286, 0x0006, 0x00c0, 0x43f1, 0x6807,
+	0x0117, 0x6827, 0x0002, 0x2d58, 0x1078, 0x45c5, 0x6827, 0x0036,
+	0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3ab1, 0x1078, 0x4466,
+	0x2b68, 0x1078, 0x3ac2, 0x0d7f, 0x1078, 0x3ac2, 0x2001, 0x0002,
+	0x007c, 0x1078, 0x4536, 0x007c, 0x70b4, 0xa080, 0x00cd, 0x781a,
+	0x2001, 0x0001, 0x1078, 0x454c, 0x1078, 0x45bc, 0x7003, 0x0000,
+	0x2001, 0x0002, 0x007c, 0x1078, 0x457e, 0x1078, 0x45b5, 0x1078,
+	0x426f, 0x1078, 0x4180, 0x1078, 0x45bc, 0x2001, 0x0001, 0x007c,
+	0x1078, 0x457e, 0x1078, 0x45b5, 0x1078, 0x426f, 0x70b4, 0xa080,
+	0x00cd, 0x781a, 0x2001, 0x0013, 0x1078, 0x454c, 0x1078, 0x45bc,
+	0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078, 0x4536, 0x007c,
+	0x1078, 0x457e, 0x1078, 0x45b5, 0x1078, 0x426f, 0x1078, 0x4180,
+	0x1078, 0x45bc, 0x2001, 0x0001, 0x007c, 0x2001, 0x0003, 0x007c,
+	0x1078, 0x44d1, 0x2001, 0x0000, 0x007c, 0x0c7e, 0x077e, 0x6f14,
+	0x1078, 0x36b0, 0x077f, 0x0c7f, 0x2001, 0x0000, 0x007c, 0x1078,
+	0x457e, 0x1078, 0x4536, 0x2001, 0x0006, 0x007c, 0x6904, 0xa18c,
+	0x00ff, 0xa186, 0x0007, 0x0040, 0x4471, 0xa186, 0x000f, 0x00c0,
+	0x4475, 0x1078, 0x45b5, 0x1078, 0x426f, 0x70b4, 0xa080, 0x00cd,
+	0x781a, 0x1078, 0x45bc, 0x7003, 0x0000, 0x007c, 0x7aa8, 0xa294,
+	0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x4536,
+	0x1079, 0x448b, 0x007c, 0x4536, 0x448f, 0x4536, 0x44df, 0xa282,
+	0x0003, 0x0040, 0x4496, 0x1078, 0x4536, 0x007c, 0x7da8, 0xa5ac,
+	0x00ff, 0x7ca8, 0xa4a4, 0x00ff, 0xa482, 0x000c, 0x0048, 0x44a4,
+	0x0040, 0x44a4, 0x2021, 0x000c, 0x701c, 0xa502, 0x00c8, 0x44a9,
+	0x751c, 0x1078, 0x451c, 0x852b, 0x852b, 0x1078, 0x372e, 0x0040,
+	0x44b5, 0x1078, 0x44c3, 0x0078, 0x44b9, 0x1078, 0x4518, 0x1078,
+	0x44d1, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, 0x781a,
+	0x2001, 0x0004, 0x007c, 0x0c7e, 0x6914, 0x810f, 0xa18c, 0x000f,
+	0x810b, 0x810b, 0x810b, 0xa1e0, 0x5280, 0x1078, 0x3538, 0x0c7f,
+	0x007c, 0x0c7e, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003,
+	0x8003, 0xa0e0, 0x5280, 0x1078, 0x355f, 0x0c7f, 0x007c, 0xa282,
+	0x0002, 0x00c0, 0x4536, 0x7aa8, 0xa294, 0x00ff, 0xa284, 0xfffe,
+	0x0040, 0x44ec, 0x2011, 0x0001, 0x1078, 0x450a, 0x1078, 0x44fc,
+	0x1078, 0x44d1, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9,
+	0x781a, 0x2001, 0x0004, 0x007c, 0x0c7e, 0x6814, 0x8007, 0xa084,
+	0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0, 0x5280, 0x1078, 0x3604,
+	0x0c7f, 0x007c, 0x789b, 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0002,
+	0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0081, 0x78ab, 0x0004, 0x007c,
+	0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0018, 0x78ab, 0x0001,
+	0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b, 0x0081,
+	0x78ab, 0x0005, 0x007c, 0x2001, 0x0003, 0x1078, 0x4544, 0x70b4,
+	0xa080, 0x00b9, 0x781a, 0x2001, 0x0005, 0x007c, 0x2001, 0x0007,
+	0x1078, 0x4544, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9,
+	0x781a, 0x2001, 0x0004, 0x007c, 0x789b, 0x0018, 0x78aa, 0x789b,
+	0x0081, 0x78ab, 0x0001, 0x007c, 0x6904, 0xa18c, 0x00ff, 0xa196,
+	0x0007, 0x0040, 0x455a, 0xa196, 0x000f, 0x0040, 0x455a, 0x1078,
+	0x193d, 0x007c, 0x6924, 0xa194, 0x003f, 0x00c0, 0x4563, 0xa18c,
+	0xffc0, 0xa105, 0x6826, 0x1078, 0x3ac2, 0x691c, 0xa184, 0x0100,
+	0x0040, 0x4572, 0x1078, 0x1b7e, 0x6914, 0x1078, 0x3b33, 0x6204,
+	0x8210, 0x6206, 0x007c, 0x692c, 0x6834, 0x682e, 0xa112, 0x6930,
+	0x6838, 0x6832, 0xa11b, 0xa200, 0xa301, 0x007c, 0x0c7e, 0xade0,
+	0x0018, 0x6003, 0x0070, 0x6106, 0x600b, 0x0000, 0x600f, 0x0a00,
+	0x6013, 0x0000, 0x6017, 0x0000, 0x8007, 0x601a, 0x601f, 0x0000,
+	0x6023, 0x0000, 0x0c7f, 0x6824, 0xa085, 0x0080, 0x6826, 0x007c,
+	0x157e, 0x137e, 0x147e, 0x2098, 0xaf80, 0x002d, 0x20a0, 0x81ac,
+	0x0040, 0x45a3, 0x53a6, 0xa184, 0x0001, 0x0040, 0x45a9, 0x3304,
+	0x78be, 0x147f, 0x137f, 0x157f, 0x007c, 0x70b0, 0xa005, 0x10c0,
+	0x23ca, 0x70b3, 0x8000, 0x0078, 0x48f7, 0x71b0, 0x81ff, 0x0040,
+	0x45bb, 0x1078, 0x49ed, 0x007c, 0x71b0, 0x81ff, 0x0040, 0x45c4,
+	0x70b3, 0x0000, 0x1078, 0x4633, 0x007c, 0x0c7e, 0x0d7e, 0x1078,
+	0x191a, 0x0c7f, 0x157e, 0x137e, 0x147e, 0x2da0, 0x2c98, 0x20a9,
+	0x0031, 0x53a3, 0x147f, 0x137f, 0x157f, 0x6807, 0x010d, 0x680b,
+	0x0000, 0x7004, 0x8007, 0x681a, 0x6823, 0x0000, 0x681f, 0x0000,
+	0x689f, 0x0000, 0x0c7f, 0x007c, 0x70b4, 0xa080, 0x0091, 0x781a,
+	0x0078, 0x2438, 0x70b4, 0xa080, 0x0081, 0x781a, 0x0078, 0x2438,
+	0x70b4, 0xa080, 0x00b9, 0x781a, 0x0078, 0x2438, 0x70b4, 0xa080,
+	0x00c3, 0x781a, 0x0078, 0x2438, 0x6904, 0xa18c, 0x00ff, 0xa196,
+	0x0007, 0x0040, 0x4609, 0xa196, 0x000f, 0x0040, 0x4609, 0x6807,
+	0x0117, 0x2001, 0x0200, 0x6826, 0x8007, 0x789b, 0x000e, 0x78aa,
+	0x6820, 0xa085, 0x8000, 0x6822, 0x2031, 0x0400, 0x6eb6, 0x7e5a,
+	0x71b4, 0xa188, 0x0091, 0x791a, 0x007c, 0x1078, 0x45bc, 0x7848,
+	0xa085, 0x000c, 0x784a, 0x70b4, 0xa080, 0x00cd, 0x781a, 0x2009,
+	0x000b, 0x2001, 0x4400, 0x1078, 0x457e, 0x2001, 0x0013, 0x1078,
+	0x454c, 0x0078, 0x3b60, 0x127e, 0x2091, 0x2200, 0x2049, 0x4633,
+	0x7000, 0x7204, 0xa205, 0x720c, 0xa215, 0x7008, 0xa084, 0xfff7,
+	0xa205, 0x0040, 0x4645, 0x0078, 0x464a, 0x7003, 0x0000, 0x127f,
+	0x2000, 0x007c, 0x7000, 0xa084, 0x0001, 0x00c0, 0x4678, 0x7108,
+	0x8103, 0x00c8, 0x4657, 0x1078, 0x477a, 0x0078, 0x464f, 0x700c,
+	0xa08c, 0x00ff, 0x0040, 0x4678, 0x7004, 0x8004, 0x00c8, 0x466f,
+	0x7014, 0xa005, 0x00c0, 0x466b, 0x7010, 0xa005, 0x0040, 0x466f,
+	0xa102, 0x00c8, 0x464f, 0x7007, 0x0010, 0x0078, 0x4678, 0x8aff,
+	0x0040, 0x4678, 0x1078, 0x49c4, 0x00c0, 0x4672, 0x0040, 0x464f,
+	0x1078, 0x4703, 0x7003, 0x0000, 0x127f, 0x2000, 0x007c, 0x017e,
+	0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x468b, 0xa18e,
+	0x000f, 0x00c0, 0x468e, 0x6040, 0x0078, 0x468f, 0x6428, 0x017f,
+	0x84ff, 0x0040, 0x46b9, 0x2c70, 0x7004, 0xa0bc, 0x000f, 0xa7b8,
+	0x46c9, 0x273c, 0x87fb, 0x00c0, 0x46a7, 0x0048, 0x46a1, 0x1078,
+	0x23ca, 0x609c, 0xa075, 0x0040, 0x46b9, 0x0078, 0x4694, 0x2704,
+	0xae68, 0x6808, 0xa630, 0x680c, 0xa529, 0x8421, 0x0040, 0x46b9,
+	0x8738, 0x2704, 0xa005, 0x00c0, 0x46a8, 0x709c, 0xa075, 0x00c0,
+	0x4694, 0x007c, 0x0000, 0x0005, 0x0009, 0x000d, 0x0011, 0x0015,
+	0x0019, 0x001d, 0x0000, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b,
+	0x0000, 0x0000, 0x46be, 0x46bb, 0x0000, 0x0000, 0x8000, 0x0000,
+	0x46be, 0x0000, 0x46c6, 0x46c3, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x46c6, 0x0000, 0x46c1, 0x46c1, 0x0000, 0x0000, 0x8000, 0x0000,
+	0x46c1, 0x0000, 0x46c7, 0x46c7, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x46c7, 0x127e, 0x2091, 0x2200, 0x2079, 0x5000, 0x2071, 0x0010,
+	0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2071, 0x0020,
+	0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2049, 0x0000,
+	0x127f, 0x2000, 0x007c, 0x2049, 0x4703, 0x2019, 0x0000, 0x7004,
+	0x8004, 0x00c8, 0x4756, 0x7007, 0x0012, 0x7108, 0x7008, 0xa106,
+	0x00c0, 0x470d, 0xa184, 0x01e0, 0x0040, 0x4718, 0x1078, 0x23ca,
+	0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x4723, 0xa184,
+	0x4000, 0x00c0, 0x470d, 0xa19c, 0x300c, 0xa386, 0x2004, 0x0040,
+	0x4731, 0xa386, 0x0008, 0x0040, 0x473c, 0xa386, 0x200c, 0x00c0,
+	0x470d, 0x7200, 0x8204, 0x0048, 0x473c, 0x730c, 0xa384, 0x00ff,
+	0x0040, 0x473c, 0x1078, 0x23ca, 0x7007, 0x0012, 0x7000, 0xa084,
+	0x0001, 0x00c0, 0x4756, 0x7008, 0xa084, 0x01e0, 0x00c0, 0x4756,
+	0x7310, 0x7014, 0xa305, 0x0040, 0x4756, 0x710c, 0xa184, 0x0300,
+	0x00c0, 0x4756, 0xa184, 0x00ff, 0x00c0, 0x4703, 0x7007, 0x0012,
+	0x7007, 0x0008, 0x7004, 0xa084, 0x0008, 0x00c0, 0x475a, 0x7007,
+	0x0012, 0x7108, 0x8103, 0x0048, 0x475f, 0x7003, 0x0000, 0x2049,
+	0x0000, 0x007c, 0x107e, 0x007e, 0x127e, 0x157e, 0x2091, 0x2200,
+	0x7108, 0x1078, 0x477a, 0x157f, 0x127f, 0x2091, 0x8001, 0x007f,
+	0x107f, 0x007c, 0x7204, 0x7500, 0x730c, 0xa384, 0x0300, 0x00c0,
+	0x47a1, 0xa184, 0x01e0, 0x00c0, 0x47c5, 0x7108, 0xa184, 0x01e0,
+	0x00c0, 0x47c5, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8,
+	0x4795, 0xa184, 0x4000, 0x00c0, 0x4785, 0xa184, 0x0007, 0x0079,
+	0x4799, 0x47a3, 0x47b5, 0x47a1, 0x47b5, 0x47a1, 0x4801, 0x47a1,
+	0x47ff, 0x1078, 0x23ca, 0x7004, 0xa084, 0x0010, 0xa085, 0x0002,
+	0x7006, 0x8aff, 0x00c0, 0x47b0, 0x2049, 0x0000, 0x0078, 0x47b4,
+	0x1078, 0x49c4, 0x00c0, 0x47b0, 0x007c, 0x7004, 0xa084, 0x0010,
+	0xa085, 0x0002, 0x7006, 0x8aff, 0x00c0, 0x47c0, 0x0078, 0x47c4,
+	0x1078, 0x49c4, 0x00c0, 0x47c0, 0x007c, 0x7007, 0x0012, 0x7108,
+	0x00e0, 0x47c8, 0x2091, 0x6000, 0x00e0, 0x47cc, 0x2091, 0x6000,
+	0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xa084, 0x0008, 0x00c0,
+	0x47d4, 0x7007, 0x0012, 0x7108, 0x8103, 0x0048, 0x47d9, 0x7003,
+	0x0000, 0x7000, 0xa005, 0x00c0, 0x47ed, 0x7004, 0xa005, 0x00c0,
+	0x47ed, 0x700c, 0xa005, 0x0040, 0x47ef, 0x0078, 0x47d0, 0x2049,
+	0x0000, 0x1078, 0x37d7, 0x6818, 0xa084, 0x8000, 0x0040, 0x47fa,
+	0x681b, 0x0002, 0x007c, 0x1078, 0x23ca, 0x1078, 0x23ca, 0x1078,
+	0x485d, 0x7210, 0x7114, 0x700c, 0xa09c, 0x00ff, 0x2800, 0xa300,
+	0xa211, 0xa189, 0x0000, 0x1078, 0x485d, 0x2704, 0x2c58, 0xac60,
+	0x6308, 0x2200, 0xa322, 0x630c, 0x2100, 0xa31b, 0x2400, 0xa305,
+	0x0040, 0x4824, 0x00c8, 0x4824, 0x8412, 0x8210, 0x830a, 0xa189,
+	0x0000, 0x2b60, 0x0078, 0x480b, 0x2b60, 0x8a07, 0x007e, 0x6004,
+	0xa084, 0x0008, 0x0040, 0x4830, 0xa7ba, 0x46c3, 0x0078, 0x4832,
+	0xa7ba, 0x46bb, 0x007f, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92,
+	0x6b8e, 0x7007, 0x0012, 0x1078, 0x4703, 0x007c, 0x8738, 0x2704,
+	0xa005, 0x00c0, 0x4851, 0x609c, 0xa005, 0x0040, 0x485a, 0x2060,
+	0x6004, 0xa084, 0x000f, 0xa080, 0x46c9, 0x203c, 0x87fb, 0x1040,
+	0x23ca, 0x8a51, 0x0040, 0x4859, 0x7008, 0xa084, 0x0003, 0xa086,
X 	0x0003, 0x007c, 0x2051, 0x0000, 0x007c, 0x8a50, 0x8739, 0x2704,
-	0xa004, 0x00c0, 0x3501, 0x6000, 0xa064, 0x00c0, 0x34f8, 0x2d60,
-	0x6004, 0xa084, 0x000f, 0xa080, 0x3356, 0x203c, 0x87fb, 0x1040,
-	0x1eac, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x6884,
+	0xa004, 0x00c0, 0x4871, 0x6000, 0xa064, 0x00c0, 0x4868, 0x2d60,
+	0x6004, 0xa084, 0x000f, 0xa080, 0x46d9, 0x203c, 0x87fb, 0x1040,
+	0x23ca, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x6884,
X 	0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084,
-	0x00ff, 0x007e, 0x6804, 0xa084, 0x0008, 0x007f, 0x0040, 0x351c,
-	0xa0b8, 0x3340, 0x0078, 0x351e, 0xa0b8, 0x3338, 0x7e08, 0xa6b5,
-	0x000c, 0x681c, 0xa084, 0x0040, 0x0040, 0x3528, 0xa6b5, 0x0001,
-	0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x352a, 0x2400,
-	0xa305, 0x00c0, 0x3535, 0x0078, 0x3559, 0x2c58, 0x2704, 0x6104,
-	0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184,
-	0x0008, 0x0040, 0x3549, 0x6010, 0xa001, 0x7022, 0x6014, 0xa001,
-	0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300, 0xa203,
-	0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078, 0x34ca, 0x0078,
-	0x355b, 0x1078, 0x3606, 0x00c0, 0x3559, 0x127f, 0x2000, 0x007c,
-	0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x7007, 0x0004, 0x7004,
-	0xa084, 0x0004, 0x00c0, 0x3567, 0x7003, 0x0008, 0x127f, 0x2000,
-	0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049, 0x3571,
-	0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x357a, 0x7e08,
-	0xa6b5, 0x000c, 0x681c, 0xa084, 0x0020, 0x00c0, 0x3589, 0xa6b5,
-	0x0001, 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8,
-	0x3346, 0x273c, 0x87fb, 0x00c0, 0x359f, 0x0048, 0x3599, 0x1078,
-	0x1eac, 0x689c, 0xa065, 0x0040, 0x35a3, 0x0078, 0x358c, 0x1078,
-	0x3606, 0x00c0, 0x359f, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e,
-	0x017e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x037f, 0x047f, 0x7e08,
-	0xa6b5, 0x000c, 0x681c, 0xa084, 0x0040, 0x0040, 0x35b9, 0xa6b5,
-	0x0001, 0x2049, 0x35a6, 0x6828, 0xa055, 0x0040, 0x3603, 0x2d70,
-	0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x3346, 0x273c, 0x87fb,
-	0x00c0, 0x35d5, 0x0048, 0x35ce, 0x1078, 0x1eac, 0x709c, 0xa075,
-	0x2060, 0x0040, 0x3603, 0x0078, 0x35c1, 0x2704, 0xae68, 0x6808,
-	0xa422, 0x680c, 0xa31b, 0x0048, 0x35f0, 0x8a51, 0x00c0, 0x35e2,
-	0x1078, 0x1eac, 0x8738, 0x2704, 0xa005, 0x00c0, 0x35d6, 0x709c,
-	0xa075, 0x2060, 0x0040, 0x3603, 0x2039, 0x3338, 0x0078, 0x35c1,
-	0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122,
-	0x690c, 0x2300, 0xa11b, 0x00c8, 0x35ff, 0x1078, 0x1eac, 0x2071,
-	0x0020, 0x0078, 0x3528, 0x127f, 0x2000, 0x007c, 0x7008, 0x7508,
-	0xa52e, 0x00c0, 0x3606, 0xa084, 0x0003, 0xa086, 0x0003, 0x0040,
-	0x362e, 0x2704, 0xac08, 0x2104, 0x701a, 0x8108, 0x2104, 0x701e,
-	0x8108, 0x2104, 0x7012, 0x8108, 0x2104, 0x7016, 0x6004, 0xa084,
-	0x0008, 0x0040, 0x3629, 0x8108, 0x2104, 0x7022, 0x8108, 0x2104,
-	0x7026, 0x7602, 0x7007, 0x0001, 0x1078, 0x34ca, 0x007c, 0x127e,
-	0x007e, 0x0d7e, 0x2091, 0x2200, 0x2049, 0x362f, 0x0d7f, 0x087f,
-	0x7108, 0x7008, 0xa106, 0x00c0, 0x3638, 0xa184, 0x4000, 0x00c0,
-	0x3638, 0xa184, 0x0003, 0x00c0, 0x364f, 0x6828, 0xa005, 0x0040,
-	0x365d, 0x0020, 0x364f, 0x1078, 0x348f, 0x0078, 0x365d, 0x00a0,
-	0x3656, 0x7108, 0x1078, 0x33e7, 0x0078, 0x3638, 0x7007, 0x0010,
-	0x00a0, 0x3658, 0x7108, 0x1078, 0x33e7, 0x7008, 0xa086, 0x0008,
-	0x00c0, 0x3638, 0x7000, 0xa005, 0x00c0, 0x3638, 0x2049, 0x0000,
-	0x127f, 0x2000, 0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0d7e,
-	0x2091, 0x2200, 0x0d7f, 0x2049, 0x366b, 0xad80, 0x0011, 0x20a0,
-	0x2099, 0x0031, 0x700c, 0xa084, 0x00ff, 0x682a, 0x7007, 0x0008,
-	0x7007, 0x0002, 0x7003, 0x0001, 0x0040, 0x3689, 0x8000, 0x80ac,
-	0x53a5, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x368b,
-	0x2049, 0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f,
-	0x2000, 0x007c, 0x2091, 0x6000, 0x78c0, 0xa005, 0x0040, 0x36af,
-	0x798c, 0x70d0, 0xa106, 0x00c0, 0x36af, 0x7804, 0xa005, 0x0040,
-	0x36af, 0x7807, 0x0000, 0x0068, 0x36af, 0x2091, 0x4080, 0x7820,
-	0x8001, 0x7822, 0x00c0, 0x370f, 0x7824, 0x7822, 0x2091, 0x8000,
-	0x78f0, 0xa005, 0x0040, 0x36dc, 0x78d4, 0xa005, 0x00c0, 0x36dc,
-	0x3a10, 0xa284, 0x0002, 0x00c0, 0x36cc, 0x78d7, 0x0007, 0x2009,
-	0xff01, 0x200a, 0x0078, 0x36dc, 0xa284, 0x0001, 0x00c0, 0x36d4,
-	0x78ef, 0x0000, 0x0078, 0x36dc, 0x78ec, 0xa005, 0x00c0, 0x36dc,
-	0x78d7, 0x0008, 0x78ef, 0x0001, 0x2069, 0x3940, 0x6800, 0xa084,
-	0x0007, 0x0040, 0x36f3, 0xa086, 0x0002, 0x0040, 0x36f3, 0x6830,
-	0xa00d, 0x0040, 0x36f3, 0x2104, 0xa005, 0x0040, 0x36f3, 0x8001,
-	0x200a, 0x0040, 0x37b1, 0x7848, 0xa005, 0x0040, 0x3703, 0x8001,
-	0x784a, 0x00c0, 0x3703, 0x0f7e, 0x2079, 0x0100, 0x1078, 0x316a,
-	0x0f7f, 0x1078, 0x1cf6, 0x68c4, 0xa005, 0x0040, 0x370f, 0x8001,
-	0x68c6, 0x00c0, 0x370f, 0x68a3, 0x0000, 0x68a7, 0x0001, 0x1078,
-	0x3716, 0x1078, 0x373b, 0x2091, 0x8001, 0x007c, 0x7834, 0x8001,
-	0x7836, 0x00c0, 0x373a, 0x7838, 0x7836, 0x2091, 0x8000, 0x7844,
-	0xa005, 0x00c0, 0x3725, 0x2001, 0x0101, 0x8001, 0x7846, 0xa080,
-	0x4280, 0x2040, 0x2004, 0xa065, 0x0040, 0x373a, 0x6024, 0xa005,
-	0x0040, 0x3736, 0x8001, 0x6026, 0x0040, 0x376a, 0x6000, 0x2c40,
-	0x0078, 0x372b, 0x007c, 0x7828, 0x8001, 0x782a, 0x00c0, 0x3769,
-	0x782c, 0x782a, 0x7830, 0xa005, 0x00c0, 0x3748, 0x2001, 0x0080,
-	0x8001, 0x7832, 0x8003, 0x8003, 0x8003, 0x8003, 0xa090, 0x3a80,
-	0xa298, 0x0002, 0x2304, 0xa084, 0x0008, 0x0040, 0x3769, 0xa290,
-	0x0009, 0x2204, 0xa005, 0x0040, 0x3761, 0x8001, 0x2012, 0x00c0,
-	0x3769, 0x2304, 0xa084, 0xfff7, 0xa085, 0x0080, 0x201a, 0x1078,
-	0x1cf6, 0x007c, 0x2069, 0x3940, 0x6800, 0xa005, 0x0040, 0x3774,
-	0x683c, 0xac06, 0x0040, 0x37b1, 0x601b, 0x0006, 0x60b4, 0xa084,
-	0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0060, 0x6022,
-	0x6000, 0x2042, 0x6714, 0x6fb6, 0x1078, 0x18b4, 0x6818, 0xa005,
-	0x0040, 0x378c, 0x8001, 0x681a, 0x6808, 0xa084, 0xffef, 0x680a,
-	0x6810, 0x8001, 0x00d0, 0x3796, 0x1078, 0x1eac, 0x6812, 0x602f,
-	0x0000, 0x6033, 0x0000, 0x2c68, 0x1078, 0x1a26, 0x2069, 0x3940,
-	0x2001, 0x0006, 0x68a2, 0x7944, 0xa184, 0x0100, 0x00c0, 0x37ac,
-	0x69ba, 0x2001, 0x0004, 0x68a2, 0x1078, 0x1cf1, 0x2091, 0x8001,
-	0x007c, 0x2009, 0x394f, 0x2164, 0x2069, 0x0100, 0x1078, 0x1e57,
-	0x601b, 0x0006, 0x6858, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084,
-	0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000,
-	0x6830, 0xa084, 0x0040, 0x0040, 0x37ed, 0x684b, 0x0004, 0x20a9,
-	0x0014, 0x6848, 0xa084, 0x0004, 0x0040, 0x37da, 0x0070, 0x37da,
-	0x0078, 0x37d1, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084,
-	0x0001, 0x0040, 0x37e7, 0x0070, 0x37e7, 0x0078, 0x37de, 0x20a9,
-	0x00fa, 0x0070, 0x37ed, 0x0078, 0x37e9, 0x6808, 0xa084, 0xfffd,
-	0x680a, 0x681b, 0x0047, 0x2009, 0x3968, 0x200b, 0x0007, 0x784c,
-	0x784a, 0x2091, 0x8001, 0x007c, 0x2079, 0x3900, 0x1078, 0x3827,
-	0x1078, 0x380b, 0x1078, 0x3819, 0x7833, 0x0000, 0x7847, 0x0000,
-	0x784b, 0x0000, 0x007c, 0x2019, 0x000c, 0x2011, 0x3946, 0x2204,
-	0xa086, 0x003c, 0x0040, 0x3816, 0x2019, 0x0008, 0x7b2a, 0x7b2e,
-	0x007c, 0x2019, 0x0039, 0x2011, 0x3946, 0x2204, 0xa086, 0x003c,
-	0x0040, 0x3824, 0x2019, 0x0027, 0x7b36, 0x7b3a, 0x007c, 0x2019,
-	0x3971, 0x2011, 0x3946, 0x2204, 0xa086, 0x003c, 0x0040, 0x3832,
-	0x2019, 0x2626, 0x7b22, 0x7b26, 0x783f, 0x0000, 0x7843, 0x000a,
-	0x007c, 0x8e59
+	0x00ff, 0x007e, 0x6804, 0xa084, 0x0008, 0x007f, 0x0040, 0x488c,
+	0xa0b8, 0x46c3, 0x0078, 0x488e, 0xa0b8, 0x46bb, 0x7e08, 0xa6b5,
+	0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x489c,
+	0xa18e, 0x000f, 0x00c0, 0x48a5, 0x681c, 0xa084, 0x0040, 0x0040,
+	0x48ac, 0xa6b5, 0x0001, 0x0078, 0x48ac, 0x681c, 0xa084, 0x0040,
+	0x0040, 0x48ac, 0xa6b5, 0x0001, 0x7007, 0x0004, 0x7004, 0xa084,
+	0x0004, 0x00c0, 0x48ae, 0x2400, 0xa305, 0x00c0, 0x48b9, 0x0078,
+	0x48df, 0x2c58, 0x2704, 0x6104, 0xac60, 0x6000, 0xa400, 0x701a,
+	0x6004, 0xa301, 0x701e, 0xa184, 0x0008, 0x0040, 0x48cf, 0x6010,
+	0xa081, 0x0000, 0x7022, 0x6014, 0xa081, 0x0000, 0x7026, 0x6208,
+	0x2400, 0xa202, 0x7012, 0x620c, 0x2300, 0xa203, 0x7016, 0x7602,
+	0x7007, 0x0001, 0x2b60, 0x1078, 0x483e, 0x0078, 0x48e1, 0x1078,
+	0x49c4, 0x00c0, 0x48df, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e,
+	0x2091, 0x2200, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004,
+	0x00c0, 0x48ed, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e,
+	0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049, 0x48f7, 0x7007, 0x0004,
+	0x7004, 0xa084, 0x0004, 0x00c0, 0x4900, 0x7e08, 0xa6b5, 0x000c,
+	0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4913, 0xa18e,
+	0x000f, 0x00c0, 0x491e, 0x681c, 0xa084, 0x0040, 0x0040, 0x491a,
+	0xa6b5, 0x0001, 0x6840, 0x2050, 0x0078, 0x4927, 0x681c, 0xa084,
+	0x0020, 0x00c0, 0x4925, 0xa6b5, 0x0001, 0x6828, 0x2050, 0x2d60,
+	0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x46c9, 0x273c, 0x87fb, 0x00c0,
+	0x493b, 0x0048, 0x4935, 0x1078, 0x23ca, 0x689c, 0xa065, 0x0040,
+	0x493f, 0x0078, 0x4928, 0x1078, 0x49c4, 0x00c0, 0x493b, 0x127f,
+	0x2000, 0x007c, 0x127e, 0x007e, 0x017e, 0x0d7e, 0x2091, 0x2200,
+	0x0d7f, 0x037f, 0x047f, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c,
+	0x00ff, 0xa186, 0x0007, 0x0040, 0x4959, 0xa18e, 0x000f, 0x00c0,
+	0x4962, 0x681c, 0xa084, 0x0040, 0x0040, 0x4969, 0xa6b5, 0x0001,
+	0x0078, 0x4969, 0x681c, 0xa084, 0x0040, 0x0040, 0x4969, 0xa6b5,
+	0x0001, 0x2049, 0x4942, 0x017e, 0x6904, 0xa18c, 0x00ff, 0xa186,
+	0x0007, 0x0040, 0x4977, 0xa18e, 0x000f, 0x00c0, 0x497a, 0x6840,
+	0x0078, 0x497b, 0x6828, 0x017f, 0xa055, 0x0040, 0x49c1, 0x2d70,
+	0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x46c9, 0x273c, 0x87fb,
+	0x00c0, 0x4995, 0x0048, 0x498e, 0x1078, 0x23ca, 0x709c, 0xa075,
+	0x2060, 0x0040, 0x49c1, 0x0078, 0x4981, 0x2704, 0xae68, 0x6808,
+	0xa422, 0x680c, 0xa31b, 0x0048, 0x49ae, 0x8a51, 0x00c0, 0x49a2,
+	0x1078, 0x23ca, 0x8738, 0x2704, 0xa005, 0x00c0, 0x4996, 0x709c,
+	0xa075, 0x2060, 0x0040, 0x49c1, 0x0078, 0x4981, 0x8422, 0x8420,
+	0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300,
+	0xa11b, 0x00c8, 0x49bd, 0x1078, 0x23ca, 0x2071, 0x0020, 0x0078,
+	0x48ac, 0x127f, 0x2000, 0x007c, 0x7008, 0xa084, 0x0003, 0xa086,
+	0x0003, 0x0040, 0x49ec, 0x2704, 0xac08, 0x2104, 0x701a, 0x8108,
+	0x2104, 0x701e, 0x8108, 0x2104, 0x7012, 0x8108, 0x2104, 0x7016,
+	0x6004, 0xa084, 0x0008, 0x0040, 0x49e3, 0x8108, 0x2104, 0x7022,
+	0x8108, 0x2104, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xa085,
+	0x0001, 0x7006, 0x1078, 0x483e, 0x007c, 0x127e, 0x007e, 0x0d7e,
+	0x2091, 0x2200, 0x2049, 0x49ed, 0x0d7f, 0x087f, 0x7108, 0xa184,
+	0x0003, 0x00c0, 0x4a17, 0x017e, 0x6904, 0xa18c, 0x00ff, 0xa186,
+	0x0007, 0x0040, 0x4a07, 0xa18e, 0x000f, 0x00c0, 0x4a0a, 0x6840,
+	0x0078, 0x4a0b, 0x6828, 0x017f, 0xa005, 0x0040, 0x4a25, 0x0078,
+	0x464a, 0x0020, 0x4a17, 0x1078, 0x4801, 0x0078, 0x4a25, 0x00a0,
+	0x4a1e, 0x7108, 0x1078, 0x477a, 0x0078, 0x49f6, 0x7007, 0x0010,
+	0x00a0, 0x4a20, 0x7108, 0x1078, 0x477a, 0x7008, 0xa086, 0x0008,
+	0x00c0, 0x49f6, 0x7000, 0xa005, 0x00c0, 0x49f6, 0x7003, 0x0000,
+	0x2049, 0x0000, 0x127f, 0x2000, 0x007c, 0x127e, 0x147e, 0x137e,
+	0x157e, 0x0c7e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049, 0x4a35,
+	0xad80, 0x0011, 0x20a0, 0x2099, 0x0031, 0x700c, 0xa084, 0x00ff,
+	0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0040,
+	0x4a54, 0x8000, 0x80ac, 0x53a5, 0x7007, 0x0004, 0x7004, 0xa084,
+	0x0004, 0x00c0, 0x4a56, 0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000,
+	0x157f, 0x137f, 0x147f, 0x127f, 0x2000, 0x007c, 0x2091, 0x6000,
+	0x2091, 0x8000, 0x78cc, 0xa005, 0x0040, 0x4a7d, 0x7994, 0x70d0,
+	0xa106, 0x00c0, 0x4a7d, 0x7804, 0xa005, 0x0040, 0x4a7d, 0x7807,
+	0x0000, 0x0068, 0x4a7d, 0x2091, 0x4080, 0x7820, 0x8001, 0x7822,
+	0x00c0, 0x4ad8, 0x7824, 0x7822, 0x2069, 0x5040, 0x6800, 0xa084,
+	0x0007, 0x0040, 0x4a9b, 0xa086, 0x0002, 0x0040, 0x4a9b, 0x6834,
+	0xa00d, 0x0040, 0x4a9b, 0x2104, 0xa005, 0x0040, 0x4a9b, 0x8001,
+	0x200a, 0x0040, 0x4b80, 0x7848, 0xa005, 0x0040, 0x4aa9, 0x8001,
+	0x784a, 0x00c0, 0x4aa9, 0x2009, 0x0102, 0x6844, 0x200a, 0x1078,
+	0x21b1, 0x6890, 0xa005, 0x0040, 0x4ab5, 0x8001, 0x6892, 0x00c0,
+	0x4ab5, 0x686f, 0x0000, 0x6873, 0x0001, 0x2061, 0x5300, 0x20a9,
+	0x0100, 0x2009, 0x0002, 0x6034, 0xa005, 0x0040, 0x4acb, 0x8001,
+	0x6036, 0x00c0, 0x4acb, 0x6010, 0xa005, 0x0040, 0x4acb, 0x017e,
+	0x1078, 0x21b1, 0x017f, 0xace0, 0x0010, 0x0070, 0x4ad1, 0x0078,
+	0x4abb, 0x8109, 0x0040, 0x4ad8, 0x20a9, 0x0100, 0x0078, 0x4abb,
+	0x1078, 0x4ae5, 0x1078, 0x4b0a, 0x2009, 0x5051, 0x2104, 0x2009,
+	0x0102, 0x200a, 0x2091, 0x8001, 0x007c, 0x7834, 0x8001, 0x7836,
+	0x00c0, 0x4b09, 0x7838, 0x7836, 0x2091, 0x8000, 0x7844, 0xa005,
+	0x00c0, 0x4af4, 0x2001, 0x0101, 0x8001, 0x7846, 0xa080, 0x7300,
+	0x2040, 0x2004, 0xa065, 0x0040, 0x4b09, 0x6024, 0xa005, 0x0040,
+	0x4b05, 0x8001, 0x6026, 0x0040, 0x4b39, 0x6000, 0x2c40, 0x0078,
+	0x4afa, 0x007c, 0x7828, 0x8001, 0x782a, 0x00c0, 0x4b38, 0x782c,
+	0x782a, 0x7830, 0xa005, 0x00c0, 0x4b17, 0x2001, 0x0200, 0x8001,
+	0x7832, 0x8003, 0x8003, 0x8003, 0x8003, 0xa090, 0x5300, 0xa298,
+	0x0002, 0x2304, 0xa084, 0x0008, 0x0040, 0x4b38, 0xa290, 0x0009,
+	0x2204, 0xa005, 0x0040, 0x4b30, 0x8001, 0x2012, 0x00c0, 0x4b38,
+	0x2304, 0xa084, 0xfff7, 0xa085, 0x0080, 0x201a, 0x1078, 0x21b1,
+	0x007c, 0x2069, 0x5040, 0x6800, 0xa005, 0x0040, 0x4b43, 0x6848,
+	0xac06, 0x0040, 0x4b80, 0x601b, 0x0006, 0x60b4, 0xa084, 0x3f00,
+	0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0060, 0x6022, 0x6000,
+	0x2042, 0x6714, 0x6f82, 0x1078, 0x1956, 0x6818, 0xa005, 0x0040,
+	0x4b5b, 0x8001, 0x681a, 0x6808, 0xa084, 0xffef, 0x680a, 0x6810,
+	0x8001, 0x00d0, 0x4b65, 0x1078, 0x23ca, 0x6812, 0x602f, 0x0000,
+	0x6033, 0x0000, 0x2c68, 0x1078, 0x1c53, 0x2069, 0x5040, 0x7944,
+	0xa184, 0x0100, 0x2001, 0x0006, 0x686e, 0x00c0, 0x4b7b, 0x6986,
+	0x2001, 0x0004, 0x686e, 0x1078, 0x21ac, 0x2091, 0x8001, 0x007c,
+	0x2069, 0x0100, 0x2009, 0x5040, 0x2104, 0xa084, 0x0007, 0x0040,
+	0x4bdc, 0xa086, 0x0007, 0x00c0, 0x4b96, 0x0d7e, 0x2009, 0x5052,
+	0x216c, 0x1078, 0x3a1a, 0x0d7f, 0x0078, 0x4bdc, 0x2009, 0x5052,
+	0x2164, 0x1078, 0x2375, 0x601b, 0x0006, 0x6858, 0xa084, 0x3f00,
+	0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f,
+	0x0000, 0x6033, 0x0000, 0x6830, 0xa084, 0x0040, 0x0040, 0x4bd0,
+	0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0004, 0x0040,
+	0x4bbd, 0x0070, 0x4bbd, 0x0078, 0x4bb4, 0x684b, 0x0009, 0x20a9,
+	0x0014, 0x6848, 0xa084, 0x0001, 0x0040, 0x4bca, 0x0070, 0x4bca,
+	0x0078, 0x4bc1, 0x20a9, 0x00fa, 0x0070, 0x4bd0, 0x0078, 0x4bcc,
+	0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0048, 0x2009, 0x505b,
+	0x200b, 0x0007, 0x784c, 0x784a, 0x2091, 0x8001, 0x007c, 0x2079,
+	0x5000, 0x1078, 0x4c0a, 0x1078, 0x4bee, 0x1078, 0x4bfc, 0x7833,
+	0x0000, 0x7847, 0x0000, 0x784b, 0x0000, 0x007c, 0x2019, 0x0003,
+	0x2011, 0x5046, 0x2204, 0xa086, 0x003c, 0x0040, 0x4bf9, 0x2019,
+	0x0002, 0x7b2a, 0x7b2e, 0x007c, 0x2019, 0x0039, 0x2011, 0x5046,
+	0x2204, 0xa086, 0x003c, 0x0040, 0x4c07, 0x2019, 0x0027, 0x7b36,
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 10'
echo 'File patch-2.2.7 is continued in part 11'
echo 11 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 09 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 09; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
+	0x000d, 0x789b, 0x0060, 0x78ab, 0x0004, 0x785b, 0x0004, 0x2009,
+	0x00e5, 0x1078, 0x2e03, 0x00c0, 0x24f1, 0x7003, 0x0004, 0x7093,
+	0x000f, 0x0078, 0x2438, 0x1078, 0x38c6, 0x00c0, 0x2518, 0x7180,
+	0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d, 0x00c0,
+	0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab, 0x0002, 0x785b,
+	0x0004, 0x2009, 0x00e5, 0x1078, 0x2e03, 0x00c0, 0x2518, 0x7088,
+	0x708b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0002, 0x7093, 0x000f,
+	0x0078, 0x2438, 0x1078, 0x38c6, 0x00c0, 0x2438, 0x7088, 0x2068,
+	0x6f14, 0x1078, 0x37bd, 0x2c50, 0x1078, 0x3978, 0x789b, 0x0010,
+	0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x6e1c, 0x2041,
+	0x0001, 0x708c, 0xa084, 0x0400, 0x2001, 0x0004, 0x0040, 0x253a,
+	0x2001, 0x0006, 0x0078, 0x265b, 0x1078, 0x38c6, 0x00c0, 0x2438,
+	0x789b, 0x0010, 0x7068, 0x2068, 0x6f14, 0x1078, 0x37bd, 0x2c50,
+	0x1078, 0x3978, 0x6008, 0xa085, 0x0010, 0x600a, 0x6824, 0xa005,
+	0x0040, 0x255a, 0xa082, 0x0006, 0x0048, 0x2558, 0x0078, 0x255a,
+	0x6827, 0x0005, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0x7058,
+	0xa084, 0x8000, 0x0040, 0x2568, 0xa684, 0x0001, 0x0040, 0x256a,
+	0xa39c, 0xffbf, 0x7baa, 0x2031, 0x0020, 0x2041, 0x0001, 0x2001,
+	0x0003, 0x0078, 0x265b, 0x0018, 0x23ef, 0x744c, 0xa485, 0x0000,
+	0x0040, 0x258d, 0xa080, 0x5080, 0x2030, 0x7150, 0x8108, 0xa12a,
+	0x0048, 0x2584, 0x2009, 0x5080, 0x2164, 0x6504, 0x85ff, 0x00c0,
+	0x259e, 0x8421, 0x00c0, 0x257e, 0x7152, 0x7003, 0x0000, 0x704b,
+	0x0000, 0x7040, 0xa005, 0x0040, 0x3b6a, 0x0078, 0x2438, 0x764c,
+	0xa6b0, 0x5080, 0x7150, 0x2600, 0x0078, 0x2589, 0x7152, 0x2568,
+	0x2558, 0x754a, 0x2c50, 0x6034, 0xa085, 0x0000, 0x00c0, 0x259b,
+	0x6708, 0x773a, 0xa784, 0x033f, 0x0040, 0x25d4, 0xa784, 0x0021,
+	0x00c0, 0x259b, 0xa784, 0x0002, 0x0040, 0x25bd, 0xa784, 0x0004,
+	0x0040, 0x259b, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0008, 0x00c0,
+	0x259b, 0xa784, 0x0010, 0x00c0, 0x259b, 0xa784, 0x0200, 0x00c0,
+	0x259b, 0xa784, 0x0100, 0x0040, 0x25d4, 0x6018, 0xa005, 0x00c0,
+	0x259b, 0xa7bc, 0xfeff, 0x670a, 0x6823, 0x0000, 0x6e1c, 0xa684,
+	0x000e, 0x6118, 0x0040, 0x25e4, 0x601c, 0xa102, 0x0048, 0x25e7,
+	0x0040, 0x25e7, 0x0078, 0x2597, 0x81ff, 0x00c0, 0x2597, 0x68c3,
+	0x0000, 0xa784, 0x0080, 0x00c0, 0x25ef, 0x700c, 0x6022, 0xa7bc,
+	0xff7f, 0x670a, 0x1078, 0x3978, 0x0018, 0x23ef, 0x789b, 0x0010,
+	0xa046, 0x1078, 0x38c6, 0x00c0, 0x2438, 0x6b14, 0xa39c, 0x001f,
+	0xa39d, 0x00c0, 0x7058, 0xa084, 0x8000, 0x0040, 0x260b, 0xa684,
+	0x0001, 0x0040, 0x260d, 0xa39c, 0xffbf, 0xa684, 0x0010, 0x0040,
+	0x2613, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684, 0x000e, 0x00c0,
+	0x261e, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x2659, 0x7158, 0xa18c,
+	0x0800, 0x0040, 0x33d7, 0x2011, 0x0020, 0xa684, 0x0008, 0x00c0,
+	0x262f, 0x8210, 0xa684, 0x0002, 0x00c0, 0x262f, 0x8210, 0x7aaa,
+	0x8840, 0x1078, 0x38de, 0x6a14, 0x610c, 0x8108, 0xa18c, 0x00ff,
+	0xa1e0, 0x7300, 0x2c64, 0x8cff, 0x0040, 0x2650, 0x6014, 0xa206,
+	0x00c0, 0x263a, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2635, 0x0c7e,
+	0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x0c7f, 0x0078, 0x2573,
+	0x1078, 0x38c6, 0x00c0, 0x2438, 0x2a60, 0x610e, 0x79aa, 0x8840,
+	0x7132, 0x2001, 0x0001, 0x007e, 0x715c, 0xa184, 0x0018, 0x0040,
+	0x2676, 0xa184, 0x0010, 0x0040, 0x2669, 0x1078, 0x35d6, 0x00c0,
+	0x2699, 0xa184, 0x0008, 0x0040, 0x2676, 0x69a0, 0xa184, 0x0600,
+	0x00c0, 0x2676, 0x1078, 0x34c7, 0x0078, 0x2699, 0x69a0, 0xa184,
+	0x0800, 0x0040, 0x268d, 0x0c7e, 0x027e, 0x2960, 0x6000, 0xa085,
+	0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106, 0x027f, 0x0c7f,
+	0x1078, 0x35d6, 0x00c0, 0x2699, 0x69a0, 0xa184, 0x0200, 0x0040,
+	0x2695, 0x1078, 0x3516, 0x0078, 0x2699, 0xa184, 0x0400, 0x00c0,
+	0x2672, 0x69a0, 0xa184, 0x1000, 0x0040, 0x26a4, 0x6914, 0xa18c,
+	0xff00, 0x810f, 0x1078, 0x22cd, 0x007f, 0x7002, 0xa68c, 0x00e0,
+	0xa684, 0x0060, 0x0040, 0x26b2, 0xa086, 0x0060, 0x00c0, 0x26b2,
+	0xa18d, 0x4000, 0x88ff, 0x0040, 0x26b7, 0xa18d, 0x0004, 0x795a,
+	0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x789b, 0x0061, 0x6818,
+	0xa08d, 0x8000, 0xa084, 0x7fff, 0x691a, 0xa68c, 0x0080, 0x0040,
+	0x26d6, 0x7097, 0x0000, 0xa08a, 0x000d, 0x0050, 0x26d4, 0xa08a,
+	0x000c, 0x7196, 0x2001, 0x000c, 0x800c, 0x719a, 0x78aa, 0x8008,
+	0x810c, 0x0040, 0x33dd, 0xa18c, 0x00f8, 0x00c0, 0x33dd, 0x157e,
+	0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8000, 0x80ac,
+	0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6814,
+	0x8007, 0x7882, 0x6d94, 0x7dd6, 0x7dde, 0x6e98, 0x7ed2, 0x7eda,
+	0x1078, 0x38c6, 0x00c0, 0x270d, 0x702c, 0x8003, 0x0048, 0x2706,
+	0x2019, 0x4c5b, 0x1078, 0x2255, 0x702f, 0x8000, 0x7830, 0xa084,
+	0x00c0, 0x00c0, 0x270d, 0x0098, 0x2715, 0x6008, 0xa084, 0xffef,
+	0x600a, 0x1078, 0x38de, 0x0078, 0x2461, 0x7200, 0xa284, 0x0007,
+	0xa086, 0x0001, 0x00c0, 0x2722, 0x781b, 0x004f, 0x1078, 0x38de,
+	0x0078, 0x2733, 0x6ab4, 0xa295, 0x2000, 0x7a5a, 0x781b, 0x004f,
+	0x1078, 0x38de, 0x7200, 0x2500, 0xa605, 0x0040, 0x2733, 0xa284,
+	0x0007, 0x1079, 0x2741, 0xad80, 0x0009, 0x7036, 0xa284, 0x0007,
+	0xa086, 0x0001, 0x00c0, 0x2438, 0x6018, 0x8000, 0x601a, 0x0078,
+	0x2438, 0x2749, 0x48f7, 0x48f7, 0x48e6, 0x48f7, 0x2749, 0x48e6,
+	0x2749, 0x1078, 0x23ca, 0x1078, 0x38c6, 0x0f7e, 0x2079, 0x5000,
+	0x78cc, 0x0f7f, 0xa084, 0x0001, 0x0040, 0x276f, 0x706c, 0xa086,
+	0x0001, 0x00c0, 0x275e, 0x706e, 0x0078, 0x2802, 0x706c, 0xa086,
+	0x0005, 0x00c0, 0x276d, 0x7088, 0x2068, 0x681b, 0x0004, 0x6817,
+	0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x706f, 0x0000, 0x2011,
+	0x0004, 0x716c, 0xa186, 0x0001, 0x0040, 0x2790, 0xa186, 0x0007,
+	0x00c0, 0x2780, 0x2009, 0x5038, 0x200b, 0x0005, 0x0078, 0x2790,
+	0x2009, 0x5013, 0x2104, 0x2009, 0x5012, 0x200a, 0x2009, 0x5038,
+	0x200b, 0x0001, 0x706f, 0x0000, 0x7073, 0x0001, 0x0078, 0x2792,
+	0x706f, 0x0000, 0x1078, 0x4633, 0x157e, 0x20a9, 0x0010, 0x2039,
+	0x0000, 0x1078, 0x36b0, 0xa7b8, 0x0100, 0x0070, 0x27a1, 0x0078,
+	0x2799, 0x157f, 0x7000, 0x0079, 0x27a5, 0x27d3, 0x27ba, 0x27ba,
+	0x27ad, 0x27d3, 0x27d3, 0x27d3, 0x27d3, 0x2021, 0x505a, 0x2404,
+	0xa005, 0x0040, 0x27d3, 0xad06, 0x00c0, 0x27ba, 0x6800, 0x2022,
+	0x0078, 0x27ca, 0x6820, 0xa084, 0x0001, 0x00c0, 0x27c6, 0x6f14,
+	0x1078, 0x37bd, 0x1078, 0x33ae, 0x0078, 0x27ca, 0x7060, 0x2060,
+	0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008,
+	0x6822, 0x1078, 0x1c53, 0x2021, 0x7400, 0x1078, 0x280f, 0x2021,
+	0x505a, 0x1078, 0x280f, 0x157e, 0x20a9, 0x0000, 0x2021, 0x7300,
+	0x1078, 0x280f, 0x8420, 0x0070, 0x27e7, 0x0078, 0x27e0, 0x2061,
+	0x5300, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6018, 0x6110, 0x81ff,
+	0x0040, 0x27f6, 0xa102, 0x0050, 0x27f6, 0x6012, 0x601b, 0x0000,
+	0xace0, 0x0010, 0x0070, 0x27fe, 0x0078, 0x27ed, 0x8421, 0x00c0,
+	0x27eb, 0x157f, 0x709c, 0xa084, 0x8000, 0x0040, 0x2809, 0x1078,
+	0x39cc, 0x7003, 0x0000, 0x704b, 0x0000, 0x0078, 0x2438, 0x047e,
+	0x2404, 0xa005, 0x0040, 0x2823, 0x2068, 0x6800, 0x007e, 0x6a1a,
+	0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x1078, 0x1c53,
+	0x007f, 0x0078, 0x2811, 0x047f, 0x2023, 0x0000, 0x007c, 0xa282,
+	0x0003, 0x0050, 0x282d, 0x1078, 0x23ca, 0x2300, 0x0079, 0x2830,
+	0x2833, 0x28a6, 0x28c3, 0xa282, 0x0002, 0x0040, 0x2839, 0x1078,
+	0x23ca, 0x706c, 0x706f, 0x0000, 0x7093, 0x0000, 0x0079, 0x2840,
+	0x2848, 0x2848, 0x284a, 0x287e, 0x33e3, 0x2848, 0x287e, 0x2848,
+	0x1078, 0x23ca, 0x7780, 0x1078, 0x36b0, 0x7780, 0xa7bc, 0x0f00,
+	0x1078, 0x37bd, 0x6018, 0xa005, 0x0040, 0x2875, 0x2021, 0x7400,
+	0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x28de, 0x0040, 0x2875,
+	0x157e, 0x20a9, 0x0000, 0x2021, 0x7300, 0x047e, 0x2009, 0x0004,
+	0x2011, 0x0010, 0x1078, 0x28de, 0x047f, 0x0040, 0x2874, 0x8420,
+	0x0070, 0x2874, 0x0078, 0x2865, 0x157f, 0x8738, 0xa784, 0x001f,
+	0x00c0, 0x2850, 0x0078, 0x2461, 0x0078, 0x2461, 0x7780, 0x1078,
+	0x37bd, 0x6018, 0xa005, 0x0040, 0x28a4, 0x2021, 0x7400, 0x2009,
+	0x0005, 0x2011, 0x0020, 0x1078, 0x28de, 0x0040, 0x28a4, 0x157e,
+	0x20a9, 0x0000, 0x2021, 0x7300, 0x047e, 0x2009, 0x0005, 0x2011,
+	0x0020, 0x1078, 0x28de, 0x047f, 0x0040, 0x28a3, 0x8420, 0x0070,
+	0x28a3, 0x0078, 0x2894, 0x157f, 0x0078, 0x2461, 0x2200, 0x0079,
+	0x28a9, 0x28ac, 0x28ae, 0x28ae, 0x1078, 0x23ca, 0x2009, 0x0012,
+	0x706c, 0xa086, 0x0002, 0x0040, 0x28b7, 0x2009, 0x000e, 0x6818,
+	0xa084, 0x8000, 0x0040, 0x28bd, 0x691a, 0x706f, 0x0000, 0x7073,
+	0x0001, 0x0078, 0x3854, 0x2200, 0x0079, 0x28c6, 0x28cb, 0x28ae,
+	0x28c9, 0x1078, 0x23ca, 0x1078, 0x4633, 0x7000, 0xa086, 0x0001,
+	0x00c0, 0x3373, 0x1078, 0x33c4, 0x6008, 0xa084, 0xffef, 0x600a,
+	0x1078, 0x3366, 0x0040, 0x3373, 0x0078, 0x2573, 0x2404, 0xa005,
+	0x0040, 0x2901, 0x2068, 0x2d04, 0x007e, 0x6814, 0xa706, 0x0040,
+	0x28ed, 0x2d20, 0x007f, 0x0078, 0x28df, 0x007f, 0x2022, 0x691a,
+	0x6817, 0x0000, 0x6820, 0xa205, 0x6822, 0x1078, 0x1c53, 0x6010,
+	0x8001, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x33c4,
+	0x007c, 0xa085, 0x0001, 0x0078, 0x2900, 0x2300, 0x0079, 0x2908,
+	0x290d, 0x290b, 0x29a6, 0x1078, 0x23ca, 0x78ec, 0xa084, 0x0001,
+	0x00c0, 0x2921, 0x7000, 0xa086, 0x0004, 0x00c0, 0x2919, 0x0078,
+	0x2944, 0x1078, 0x33c4, 0x6008, 0xa084, 0xffef, 0x600a, 0x0078,
+	0x3373, 0x78e4, 0xa005, 0x00d0, 0x2944, 0x0018, 0x2438, 0x2008,
+	0xa084, 0x0030, 0x00c0, 0x2930, 0x781b, 0x004f, 0x0078, 0x2438,
+	0x78ec, 0xa084, 0x0003, 0x0040, 0x292c, 0x2100, 0xa084, 0x0007,
+	0x0079, 0x293a, 0x297d, 0x2988, 0x296e, 0x2942, 0x38b9, 0x38b9,
+	0x2942, 0x2997, 0x1078, 0x23ca, 0x7000, 0xa086, 0x0004, 0x00c0,
+	0x295e, 0x706c, 0xa086, 0x0002, 0x00c0, 0x2954, 0x2011, 0x0002,
+	0x2019, 0x0000, 0x0078, 0x2827, 0x706c, 0xa086, 0x0006, 0x0040,
+	0x294e, 0x706c, 0xa086, 0x0004, 0x0040, 0x294e, 0x79e4, 0xa184,
+	0x0030, 0x0040, 0x2968, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x296a,
+	0x0078, 0x2f43, 0x2001, 0x0003, 0x0078, 0x2cd7, 0x6818, 0xa084,
+	0x8000, 0x0040, 0x2975, 0x681b, 0x001d, 0x1078, 0x368f, 0x782b,
+	0x3008, 0x781b, 0x0056, 0x0078, 0x2438, 0x6818, 0xa084, 0x8000,
+	0x0040, 0x2984, 0x681b, 0x001d, 0x1078, 0x368f, 0x0078, 0x3884,
+	0x6818, 0xa084, 0x8000, 0x0040, 0x298f, 0x681b, 0x001d, 0x1078,
+	0x368f, 0x782b, 0x3008, 0x781b, 0x00d2, 0x0078, 0x2438, 0x6818,
+	0xa084, 0x8000, 0x0040, 0x299e, 0x681b, 0x001d, 0x1078, 0x368f,
+	0x782b, 0x3008, 0x781b, 0x0093, 0x0078, 0x2438, 0xa584, 0x000f,
+	0x00c0, 0x29c3, 0x7000, 0x0079, 0x29ad, 0x2461, 0x29b7, 0x29b5,
+	0x3373, 0x3373, 0x3373, 0x3373, 0x29b5, 0x1078, 0x23ca, 0x1078,
+	0x33c4, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x3366, 0x0040,
+	0x3373, 0x0078, 0x2573, 0x78e4, 0xa005, 0x00d0, 0x2944, 0x0018,
+	0x2944, 0x2008, 0xa084, 0x0030, 0x00c0, 0x29d2, 0x781b, 0x004f,
+	0x0078, 0x2438, 0x78ec, 0xa084, 0x0003, 0x0040, 0x29ce, 0x2100,
+	0xa184, 0x0007, 0x0079, 0x29dc, 0x29ee, 0x29f2, 0x29e6, 0x29e4,
+	0x38b9, 0x38b9, 0x29e4, 0x38af, 0x1078, 0x23ca, 0x1078, 0x3697,
+	0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2438, 0x1078, 0x3697,
+	0x0078, 0x3884, 0x1078, 0x3697, 0x782b, 0x3008, 0x781b, 0x00d2,
+	0x0078, 0x2438, 0x1078, 0x3697, 0x782b, 0x3008, 0x781b, 0x0093,
+	0x0078, 0x2438, 0x2300, 0x0079, 0x2a05, 0x2a0a, 0x2a08, 0x2a0c,
+	0x1078, 0x23ca, 0x0078, 0x3081, 0x681b, 0x0008, 0x78a3, 0x0000,
+	0x79e4, 0xa184, 0x0030, 0x0040, 0x3081, 0x78ec, 0xa084, 0x0003,
+	0x0040, 0x3081, 0xa184, 0x0007, 0x0079, 0x2a1e, 0x2a26, 0x29f2,
+	0x296e, 0x3854, 0x38b9, 0x38b9, 0x2a26, 0x38af, 0x1078, 0x3868,
+	0x0078, 0x2438, 0xa282, 0x0005, 0x0050, 0x2a30, 0x1078, 0x23ca,
+	0x2300, 0x0079, 0x2a33, 0x2a36, 0x2c84, 0x2c92, 0x2200, 0x0079,
+	0x2a39, 0x2a53, 0x2a40, 0x2a53, 0x2a3e, 0x2c69, 0x1078, 0x23ca,
+	0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0048,
+	0x366b, 0xa08a, 0x0004, 0x00c8, 0x366b, 0x0079, 0x2a4f, 0x366b,
+	0x366b, 0x366b, 0x3619, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080,
+	0x0040, 0x2a64, 0x0078, 0x366b, 0x7000, 0xa005, 0x00c0, 0x2a5a,
+	0x2011, 0x0004, 0x0078, 0x31f5, 0xa184, 0x00ff, 0xa08a, 0x0010,
+	0x00c8, 0x366b, 0x0079, 0x2a6c, 0x2a7e, 0x2a7c, 0x2a96, 0x2a9a,
+	0x2b55, 0x366b, 0x366b, 0x2b57, 0x366b, 0x366b, 0x2c65, 0x2c65,
+	0x366b, 0x366b, 0x366b, 0x2c67, 0x1078, 0x23ca, 0xa684, 0x1000,
+	0x0040, 0x2a8b, 0x2001, 0x0500, 0x8000, 0x8000, 0x783a, 0x781b,
+	0x0091, 0x0078, 0x2438, 0x6818, 0xa084, 0x8000, 0x0040, 0x2a94,
+	0x681b, 0x001d, 0x0078, 0x2a82, 0x0078, 0x3854, 0x681b, 0x001d,
+	0x0078, 0x367b, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0, 0x2adb,
+	0x6820, 0xa084, 0x0001, 0x00c0, 0x2ae1, 0x6818, 0xa086, 0x0008,
+	0x00c0, 0x2aac, 0x681b, 0x0000, 0xa684, 0x0400, 0x0040, 0x2b51,
+	0xa684, 0x0080, 0x0040, 0x2ad7, 0x7097, 0x0000, 0x6818, 0xa084,
+	0x003f, 0xa08a, 0x000d, 0x0050, 0x2ad7, 0xa08a, 0x000c, 0x7196,
+	0x2001, 0x000c, 0x800c, 0x719a, 0x789b, 0x0061, 0x78aa, 0x157e,
+	0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8000, 0x80ac,
+	0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x781b,
+	0x0058, 0x0078, 0x2438, 0xa684, 0x1000, 0x0040, 0x2ae1, 0x0078,
+	0x2438, 0xa684, 0x0060, 0x0040, 0x2b4d, 0xa684, 0x0800, 0x0040,
+	0x2b4d, 0xa684, 0x8000, 0x00c0, 0x2aef, 0x0078, 0x2b09, 0xa6b4,
+	0x7fff, 0x7e5a, 0x6eb6, 0x789b, 0x0076, 0x7aac, 0x79ac, 0x78ac,
+	0x801b, 0x00c8, 0x2afc, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291,
+	0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303,
+	0x68ae, 0xa684, 0x4000, 0x0040, 0x2b11, 0xa6b4, 0xbfff, 0x7e5a,
+	0x6eb6, 0x7000, 0xa086, 0x0003, 0x00c0, 0x2b1e, 0x1078, 0x46e9,
+	0x1078, 0x48e6, 0x781b, 0x0064, 0x0078, 0x2438, 0xa006, 0x1078,
+	0x49ed, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040,
+	0x2b2d, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda,
+	0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x00c0, 0x2b3f, 0xa6b5,
+	0x4000, 0x7e5a, 0x6eb6, 0x781b, 0x0064, 0x0078, 0x2438, 0x781b,
+	0x0064, 0x2200, 0xa115, 0x00c0, 0x2b49, 0x1078, 0x48f7, 0x0078,
+	0x2438, 0x1078, 0x4942, 0x0078, 0x2438, 0x781b, 0x0065, 0x0078,
+	0x2438, 0x781b, 0x0058, 0x0078, 0x2438, 0x1078, 0x23ca, 0x0078,
+	0x2bb8, 0x6920, 0xa184, 0x0100, 0x0040, 0x2b6f, 0xa18c, 0xfeff,
+	0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084, 0xefff, 0x6002,
+	0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078, 0x2ba7, 0xa184,
+	0x0200, 0x0040, 0x2ba7, 0xa18c, 0xfdff, 0x6922, 0x0c7e, 0x7054,
+	0x2060, 0x6000, 0xa084, 0xdfff, 0x6002, 0x6004, 0xa084, 0xffef,
+	0x6006, 0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2ba7,
+	0x1078, 0x37b9, 0x1078, 0x34c7, 0x88ff, 0x0040, 0x2ba7, 0x789b,
+	0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684,
+	0x0400, 0x00c0, 0x2ba1, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078,
+	0x2438, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x7e58,
+	0xa684, 0x0400, 0x00c0, 0x2bb0, 0x781b, 0x0058, 0x0078, 0x2438,
+	0x781b, 0x0065, 0x0078, 0x2438, 0x0078, 0x3673, 0x0078, 0x3673,
+	0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x0040, 0x2bb6, 0x789b,
+	0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0, 0x2bf6,
+	0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x2bee, 0x0048,
+	0x2bd3, 0x0078, 0x2bf0, 0xa380, 0x0002, 0xa102, 0x00c8, 0x2bee,
+	0x6920, 0xa18c, 0xfcff, 0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000,
+	0xa084, 0xefef, 0x6002, 0x6004, 0xa084, 0xffe5, 0x6006, 0x0c7f,
+	0x7e58, 0xa6b4, 0xfffb, 0x7e5a, 0x0078, 0x2ba8, 0x0078, 0x2b59,
+	0x24a8, 0x7aa8, 0x00f0, 0x2bf0, 0x0078, 0x2bc1, 0xa284, 0x00f0,
+	0xa086, 0x0020, 0x00c0, 0x2c56, 0x8318, 0x8318, 0x2300, 0xa102,
+	0x0040, 0x2c06, 0x0048, 0x2c06, 0x0078, 0x2c53, 0xa286, 0x0023,
+	0x0040, 0x2bb6, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684,
+	0xfff1, 0xa085, 0x0010, 0x2030, 0x7e5a, 0x6008, 0xa085, 0x0010,
+	0x600a, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f,
+	0xa184, 0x0010, 0x0040, 0x2c2a, 0x1078, 0x37b9, 0x1078, 0x35d6,
+	0x0078, 0x2c39, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008, 0x2c48,
+	0x0c7f, 0xa184, 0x0008, 0x0040, 0x2ba7, 0x1078, 0x37b9, 0x1078,
+	0x34c7, 0x88ff, 0x0040, 0x2ba7, 0x789b, 0x0060, 0x2800, 0x78aa,
+	0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2c4d, 0x782b,
+	0x3008, 0x781b, 0x0056, 0x0078, 0x2438, 0x782b, 0x3008, 0x781b,
+	0x0065, 0x0078, 0x2438, 0x7aa8, 0x0078, 0x2bc1, 0x8318, 0x2300,
+	0xa102, 0x0040, 0x2c5f, 0x0048, 0x2c5f, 0x0078, 0x2bc1, 0xa284,
+	0x0080, 0x00c0, 0x367b, 0x0078, 0x3673, 0x0078, 0x367b, 0x0078,
+	0x366b, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001,
+	0x0040, 0x2c74, 0x1078, 0x23ca, 0x7aa8, 0xa294, 0x00ff, 0x78a8,
+	0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x366b, 0x0079, 0x2c80,
+	0x366b, 0x3414, 0x366b, 0x356b, 0xa282, 0x0000, 0x00c0, 0x2c8a,
+	0x1078, 0x23ca, 0x1078, 0x368f, 0x782b, 0x3008, 0x781b, 0x0065,
+	0x0078, 0x2438, 0xa282, 0x0003, 0x00c0, 0x2c98, 0x1078, 0x23ca,
+	0xa484, 0x8000, 0x00c0, 0x2cbb, 0x706c, 0xa005, 0x0040, 0x2ca2,
+	0x1078, 0x23ca, 0x6f14, 0x7782, 0xa7bc, 0x0f00, 0x1078, 0x37bd,
+	0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f, 0x00c0,
+	0x2ca6, 0x1078, 0x3693, 0x706f, 0x0002, 0x2009, 0x5038, 0x200b,
+	0x0009, 0x0078, 0x2cbd, 0x1078, 0x369f, 0x782b, 0x3008, 0x781b,
+	0x0065, 0x0078, 0x2438, 0xa282, 0x0004, 0x0050, 0x2cc9, 0x1078,
+	0x23ca, 0x2300, 0x0079, 0x2ccc, 0x2ccf, 0x2db8, 0x2deb, 0xa286,
+	0x0003, 0x0040, 0x2cd5, 0x1078, 0x23ca, 0x2001, 0x0000, 0x007e,
+	0x68c0, 0xa005, 0x0040, 0x2cde, 0x7003, 0x0003, 0x68a0, 0xa084,
+	0x2000, 0x0040, 0x2ce7, 0x6008, 0xa085, 0x0002, 0x600a, 0x007f,
+	0x703e, 0x7000, 0xa084, 0x0007, 0x0079, 0x2cee, 0x2461, 0x2cf8,
+	0x2cf8, 0x2eed, 0x2f29, 0x2461, 0x2f29, 0x2cf6, 0x1078, 0x23ca,
+	0xa684, 0x1000, 0x00c0, 0x2d00, 0x1078, 0x4633, 0x0040, 0x2d92,
+	0x7868, 0xa08c, 0x00ff, 0x0040, 0x2d48, 0xa186, 0x0008, 0x00c0,
+	0x2d17, 0x1078, 0x33c4, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078,
+	0x3366, 0x0040, 0x2d48, 0x1078, 0x4633, 0x0078, 0x2d2f, 0xa186,
+	0x0028, 0x00c0, 0x2d48, 0x1078, 0x4633, 0x6008, 0xa084, 0xffef,
+	0x600a, 0x6018, 0xa005, 0x0040, 0x2d2f, 0x8001, 0x601a, 0xa005,
+	0x0040, 0x2d2f, 0x8001, 0xa005, 0x0040, 0x2d2f, 0x601e, 0x6820,
+	0xa084, 0x0001, 0x0040, 0x2461, 0x6820, 0xa084, 0xfffe, 0x6822,
+	0x7060, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, 0x6802,
+	0xa005, 0x2d00, 0x00c0, 0x2d45, 0x6002, 0x6006, 0x0078, 0x2461,
+	0x017e, 0x1078, 0x2e1c, 0x017f, 0xa684, 0xdf00, 0x681e, 0x682b,
+	0x0000, 0x6f14, 0x81ff, 0x0040, 0x2d92, 0xa186, 0x0002, 0x00c0,
+	0x2d92, 0xa684, 0x0800, 0x00c0, 0x2d65, 0xa684, 0x0060, 0x0040,
+	0x2d65, 0x78d8, 0x7adc, 0x682e, 0x6a32, 0x6820, 0xa084, 0x0800,
+	0x00c0, 0x2d92, 0x8717, 0xa294, 0x000f, 0x8213, 0x8213, 0x8213,
+	0xa290, 0x5280, 0xa290, 0x0000, 0x221c, 0xa384, 0x0100, 0x00c0,
+	0x2d7b, 0x0078, 0x2d81, 0x8210, 0x2204, 0xa085, 0x0018, 0x2012,
+	0x8211, 0xa384, 0x0400, 0x0040, 0x2d8e, 0x68a0, 0xa084, 0x0100,
+	0x00c0, 0x2d8e, 0x1078, 0x2ea0, 0x0078, 0x2461, 0x6008, 0xa085,
+	0x0002, 0x600a, 0x6916, 0x6818, 0xa084, 0x8000, 0x0040, 0x2d9a,
+	0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x1078, 0x33b5, 0x1078,
+	0x33c4, 0x00c0, 0x2da7, 0x6008, 0xa084, 0xffef, 0x600a, 0x6820,
+	0xa084, 0x0001, 0x00c0, 0x2db0, 0x1078, 0x33ae, 0x0078, 0x2db4,
+	0x7060, 0x2060, 0x6800, 0x6002, 0x1078, 0x1c53, 0x0078, 0x2461,
+	0xa282, 0x0004, 0x0048, 0x2dbe, 0x1078, 0x23ca, 0x2200, 0x0079,
+	0x2dc1, 0x2dbc, 0x2dc5, 0x2dd2, 0x2dc5, 0x7000, 0xa086, 0x0005,
+	0x0040, 0x2dce, 0x1078, 0x368f, 0x782b, 0x3008, 0x781b, 0x0065,
+	0x0078, 0x2438, 0x7890, 0x8007, 0x8001, 0xa084, 0x0007, 0xa080,
+	0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186, 0x0003, 0x0040,
+	0x2de7, 0xa186, 0x0000, 0x0040, 0x2de7, 0x0078, 0x366b, 0x781b,
+	0x0065, 0x0078, 0x2438, 0x6820, 0xa085, 0x0004, 0x6822, 0x82ff,
+	0x00c0, 0x2df6, 0x1078, 0x368f, 0x0078, 0x2dfd, 0x8211, 0x0040,
+	0x2dfb, 0x1078, 0x23ca, 0x1078, 0x369f, 0x782b, 0x3008, 0x781b,
+	0x0065, 0x0078, 0x2438, 0x702c, 0x8003, 0x0048, 0x2e0d, 0x2019,
+	0x4c5b, 0x1078, 0x2255, 0x702f, 0x8000, 0x1078, 0x38de, 0x7830,
+	0xa084, 0x00c0, 0x00c0, 0x2e19, 0x0018, 0x2e19, 0x791a, 0xa006,
+	0x007c, 0xa085, 0x0001, 0x007c, 0xa684, 0x0060, 0x00c0, 0x2e26,
+	0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2e9f, 0xa684, 0x0800,
+	0x00c0, 0x2e48, 0x68b4, 0xa084, 0x4800, 0xa635, 0xa684, 0x0800,
+	0x00c0, 0x2e48, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x703c, 0xa005,
+	0x00c0, 0x2e40, 0x2200, 0xa105, 0x0040, 0x2e47, 0x703f, 0x0015,
+	0x7000, 0xa086, 0x0006, 0x0040, 0x2e47, 0x1078, 0x4633, 0x007c,
+	0xa684, 0x0020, 0x0040, 0x2e6a, 0xa684, 0x4000, 0x0040, 0x2e56,
+	0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2e40, 0x68b4, 0xa084,
+	0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2e50, 0x703c, 0xa005,
+	0x00c0, 0x2e64, 0x703f, 0x0015, 0x79d8, 0x7adc, 0x692e, 0x6a32,
+	0x0078, 0x2e40, 0xa684, 0x4000, 0x0040, 0x2e74, 0x682f, 0x0000,
+	0x6833, 0x0000, 0x0078, 0x2e40, 0x68b4, 0xa084, 0x4800, 0xa635,
+	0xa684, 0x4000, 0x00c0, 0x2e6e, 0x703c, 0xa005, 0x00c0, 0x2e82,
+	0x703f, 0x0015, 0x79d8, 0x7adc, 0x78d0, 0x80fb, 0x00c8, 0x2e89,
X 	0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a32,
-	0x2100, 0xa205, 0x00c0, 0x2826, 0x0078, 0x27e0, 0x7000, 0xa086,
-	0x0006, 0x0040, 0x282f, 0x1078, 0x362f, 0x0078, 0x27e0, 0x007c,
-	0xa384, 0x0200, 0x0040, 0x2838, 0x6008, 0xa085, 0x0002, 0x600a,
-	0x681b, 0x0006, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003,
+	0x2100, 0xa205, 0x00c0, 0x2e96, 0x0078, 0x2e40, 0x7000, 0xa086,
+	0x0006, 0x0040, 0x2e9f, 0x1078, 0x49ed, 0x0078, 0x2e40, 0x007c,
+	0x6008, 0xa085, 0x0200, 0x600a, 0xa384, 0x0200, 0x0040, 0x2eac,
+	0x6008, 0xa085, 0x0002, 0x600a, 0x681b, 0x0006, 0x688f, 0x0000,
+	0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003,
X 	0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020,
-	0x7000, 0x0079, 0x284b, 0x2853, 0x2855, 0x285e, 0x2853, 0x2853,
-	0x2853, 0x2853, 0x2853, 0x1078, 0x1eac, 0x6820, 0xa084, 0x0001,
-	0x00c0, 0x285e, 0x1078, 0x2cc9, 0x0078, 0x2864, 0x7054, 0x2c50,
-	0x2060, 0x6800, 0x6002, 0x2a60, 0x2021, 0x3957, 0x2404, 0xa005,
-	0x0040, 0x286d, 0x2020, 0x0078, 0x2866, 0x2d22, 0x206b, 0x0000,
-	0x007c, 0x1078, 0x2cd0, 0x1078, 0x2cdf, 0x682b, 0x0000, 0x789b,
-	0x000e, 0x6f14, 0x6817, 0x0002, 0x1078, 0x366b, 0xa684, 0x0800,
-	0x0040, 0x2886, 0x691c, 0xa18d, 0x2000, 0x691e, 0x6818, 0xa084,
-	0x8000, 0x0040, 0x2896, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2894,
-	0x681b, 0x001e, 0x0078, 0x2896, 0x681b, 0x0000, 0x2021, 0x3957,
-	0x6800, 0x2022, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078, 0x1a26,
-	0x0078, 0x1f03, 0x1078, 0x27ce, 0x682b, 0x0000, 0x789b, 0x000e,
-	0x6f14, 0x1078, 0x316f, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xa084,
-	0x8000, 0x0040, 0x28b5, 0x7038, 0x681a, 0xa68c, 0xdf00, 0x691e,
-	0x70a3, 0x0000, 0x0078, 0x1f03, 0xa006, 0x1078, 0x32f5, 0x6817,
-	0x0000, 0x681b, 0x0001, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000,
-	0x7000, 0x0079, 0x28cb, 0x28d3, 0x28d5, 0x28d5, 0x28d7, 0x28d7,
-	0x28d7, 0x28d7, 0x28d3, 0x1078, 0x1eac, 0x1078, 0x2cdf, 0x6008,
-	0xa084, 0xffef, 0x600a, 0x0078, 0x2caa, 0x2300, 0x0079, 0x28e0,
-	0x28e3, 0x28e5, 0x2939, 0x1078, 0x1eac, 0x7000, 0x0079, 0x28e8,
-	0x28f0, 0x28f2, 0x28f2, 0x290d, 0x28f2, 0x291a, 0x290d, 0x28f0,
-	0x1078, 0x1eac, 0xa684, 0x0060, 0xa086, 0x0060, 0x00c0, 0x2909,
-	0xa6b4, 0xffdf, 0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a, 0x681c,
-	0xa084, 0xffdf, 0x681e, 0x1078, 0x32f5, 0x1078, 0x3571, 0x0078,
-	0x311c, 0xa684, 0x2000, 0x0040, 0x28fc, 0x6818, 0xa084, 0x8000,
-	0x0040, 0x291a, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040, 0x291a,
-	0x681b, 0x0007, 0x2009, 0x391e, 0x210c, 0xa186, 0x0000, 0x0040,
-	0x292f, 0xa186, 0x0001, 0x0040, 0x2933, 0x2009, 0x3935, 0x200b,
-	0x000b, 0x70a3, 0x0001, 0x781b, 0x0047, 0x0078, 0x1efb, 0x781b,
-	0x00df, 0x0078, 0x1efb, 0x2009, 0x3935, 0x200b, 0x000a, 0x0078,
-	0x1efb, 0x1078, 0x1eac, 0x2300, 0x0079, 0x293e, 0x2941, 0x2943,
-	0x2976, 0x1078, 0x1eac, 0x7000, 0x0079, 0x2946, 0x294e, 0x2950,
-	0x2950, 0x296b, 0x2950, 0x2972, 0x296b, 0x294e, 0x1078, 0x1eac,
-	0xa684, 0x0060, 0xa086, 0x0060, 0x00c0, 0x2967, 0xa6b4, 0xffbf,
-	0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a, 0x681c, 0xa084, 0xffbf,
-	0x681e, 0x1078, 0x32f5, 0x1078, 0x3571, 0x0078, 0x311c, 0xa684,
-	0x2000, 0x0040, 0x295a, 0x6818, 0xa084, 0x8000, 0x0040, 0x2972,
-	0x681b, 0x0007, 0x781b, 0x00e6, 0x0078, 0x1efb, 0x6820, 0xa085,
-	0x0004, 0x6822, 0x1078, 0x30e7, 0xa6b5, 0x0800, 0x1078, 0x2f7d,
-	0x781b, 0x0067, 0x0078, 0x1efb, 0x2300, 0x0079, 0x2987, 0x298a,
-	0x298c, 0x298e, 0x1078, 0x1eac, 0x1078, 0x1eac, 0xa684, 0x0400,
-	0x00c0, 0x29ae, 0x782b, 0x3009, 0x6920, 0xa18c, 0xfdff, 0xa18c,
-	0xfeff, 0x6922, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb,
-	0x785a, 0x79e4, 0xa184, 0x0020, 0x00c0, 0x29aa, 0x2001, 0x0014,
-	0x0078, 0x26ad, 0xa184, 0x0007, 0x0079, 0x29e6, 0x7a90, 0xa294,
-	0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, 0x0040, 0x29e4, 0x789b,
-	0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0, 0x29d5, 0x7ba8, 0x7ba8,
-	0xa386, 0x0001, 0x00c0, 0x29c8, 0x2009, 0xfff7, 0x0078, 0x29ce,
-	0xa386, 0x0003, 0x00c0, 0x29d5, 0x2009, 0xffef, 0x0c7e, 0x7048,
-	0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab,
-	0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c,
-	0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x311c, 0x239b, 0x23a8,
-	0x3124, 0x3124, 0x29ee, 0x29ee, 0x29ee, 0x3124, 0x1078, 0x1eac,
-	0x79e4, 0xa184, 0x0030, 0x00c0, 0x2a06, 0x70a0, 0xa086, 0x0002,
-	0x00c0, 0x29fe, 0x2011, 0x0002, 0x0078, 0x2288, 0x6818, 0xa085,
-	0x8000, 0x681a, 0x2001, 0x0014, 0x0078, 0x26ad, 0xa184, 0x0007,
-	0x0079, 0x2a0a, 0x311c, 0x311c, 0x2a12, 0x311c, 0x3144, 0x3144,
-	0x311c, 0x311c, 0xa684, 0x0080, 0x0040, 0x2a41, 0x71c8, 0x81ff,
-	0x0040, 0x2a41, 0xa182, 0x000d, 0x00d0, 0x2a22, 0x70cb, 0x0000,
-	0x0078, 0x2a27, 0xa182, 0x000c, 0x70ca, 0x2009, 0x000c, 0x789b,
-	0x0061, 0x79aa, 0x157e, 0x137e, 0x147e, 0x70cc, 0x8114, 0xa210,
-	0x72ce, 0xa080, 0x000b, 0xad00, 0x2098, 0x20a1, 0x012b, 0x789b,
-	0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f, 0x137f, 0x157f, 0x0078,
-	0x3124, 0xa684, 0x0400, 0x00c0, 0x2a82, 0x6820, 0xa084, 0x0001,
-	0x0040, 0x3124, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0040, 0x2a56,
-	0xa086, 0x0060, 0x00c0, 0x2a56, 0xa18d, 0x4000, 0xa18c, 0xfffb,
-	0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061,
-	0x6818, 0xa085, 0x8000, 0x681a, 0x78aa, 0x8008, 0x810c, 0x0040,
-	0x2d07, 0xa18c, 0x00f8, 0x00c0, 0x2d07, 0x157e, 0x137e, 0x147e,
-	0x20a1, 0x012b, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b,
-	0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6814, 0x8007, 0x7882,
-	0x0078, 0x3124, 0x6818, 0xa084, 0x8000, 0x0040, 0x2a89, 0x681b,
-	0x0008, 0x781b, 0x00da, 0x0078, 0x1efb, 0x2300, 0x0079, 0x2a90,
-	0x2a95, 0x2b18, 0x2a93, 0x1078, 0x1eac, 0x7000, 0xa084, 0x0007,
-	0x0079, 0x2a9a, 0x2aa2, 0x2aa4, 0x2ac0, 0x2aa2, 0x2aa2, 0x1f03,
-	0x2aa2, 0x2aa2, 0x1078, 0x1eac, 0x6920, 0xa18d, 0x0001, 0x6922,
-	0x6800, 0x6006, 0xa005, 0x00c0, 0x2aae, 0x6002, 0x681c, 0xa084,
-	0x000e, 0x0040, 0x2aba, 0x7014, 0x68ba, 0x712c, 0xa188, 0x4280,
-	0x0078, 0x2abc, 0x2009, 0x4380, 0x2104, 0x6802, 0x2d0a, 0x7156,
-	0x6920, 0xa184, 0x8000, 0x00c0, 0x2acc, 0x68af, 0x0000, 0x68b3,
-	0x0000, 0xa18d, 0x8000, 0x6922, 0x6eb6, 0xa684, 0x0060, 0x0040,
-	0x2b16, 0xa684, 0x0800, 0x00c0, 0x2add, 0x6894, 0x68a6, 0x6898,
-	0x68aa, 0x1078, 0x32f5, 0x0078, 0x2b16, 0xa684, 0x0020, 0x0040,
-	0x2aea, 0xa006, 0x1078, 0x362f, 0x79d8, 0x7adc, 0x69aa, 0x6aa6,
-	0x0078, 0x2af0, 0x1078, 0x30a6, 0x69aa, 0x6aa6, 0x1078, 0x362f,
-	0xa684, 0x8000, 0x0040, 0x2b16, 0xa684, 0x7fff, 0x68b6, 0x789b,
-	0x0074, 0x1078, 0x316f, 0x2010, 0x1078, 0x316f, 0x2008, 0xa684,
-	0x0020, 0x00c0, 0x2b0e, 0x1078, 0x316f, 0x801b, 0x00c8, 0x2b09,
+	0x68b3, 0x0000, 0x68af, 0x0000, 0x7000, 0x0079, 0x2ec7, 0x2461,
+	0x2ed1, 0x2eda, 0x2ecf, 0x2ecf, 0x2ecf, 0x2ecf, 0x2ecf, 0x1078,
+	0x23ca, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2eda, 0x1078, 0x33ae,
+	0x0078, 0x2ee0, 0x7060, 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60,
+	0x2021, 0x505a, 0x2404, 0xa005, 0x0040, 0x2ee9, 0x2020, 0x0078,
+	0x2ee2, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078, 0x33b5, 0x1078,
+	0x33c4, 0x6008, 0xa084, 0xfdff, 0x600a, 0x682b, 0x0000, 0x789b,
+	0x000e, 0x6f14, 0x6817, 0x0002, 0x1078, 0x4a35, 0xa684, 0x0800,
+	0x0040, 0x2f06, 0x691c, 0xa18d, 0x2000, 0x691e, 0x6818, 0xa084,
+	0x8000, 0x0040, 0x2f16, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2f14,
+	0x681b, 0x001e, 0x0078, 0x2f16, 0x681b, 0x0000, 0x2021, 0x505a,
+	0x2404, 0xad06, 0x0040, 0x2f1d, 0x7460, 0x6800, 0x2022, 0x68c3,
+	0x0000, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078, 0x1c53, 0x0078,
+	0x2461, 0x1078, 0x2e1c, 0x682b, 0x0000, 0x2001, 0x000e, 0x6f14,
+	0x1078, 0x38e4, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xa084, 0x8000,
+	0x0040, 0x2f3c, 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x706f,
+	0x0000, 0x0078, 0x2461, 0x7000, 0xa005, 0x00c0, 0x2f49, 0x0078,
+	0x2461, 0xa006, 0x1078, 0x4633, 0x6817, 0x0000, 0x681b, 0x0014,
+	0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa085, 0x00ff,
+	0x6822, 0x7000, 0x0079, 0x2f5c, 0x2461, 0x2f66, 0x2f66, 0x2f68,
+	0x2f68, 0x2f68, 0x2f68, 0x2f64, 0x1078, 0x23ca, 0x1078, 0x33c4,
+	0x6008, 0xa084, 0xffef, 0x600a, 0x0078, 0x337e, 0x2300, 0x0079,
+	0x2f71, 0x2f74, 0x2f76, 0x2faf, 0x1078, 0x23ca, 0x7000, 0x0079,
+	0x2f79, 0x2461, 0x2f83, 0x2f83, 0x2f9e, 0x2f83, 0x2fab, 0x2f9e,
+	0x2f81, 0x1078, 0x23ca, 0xa684, 0x0060, 0xa086, 0x0060, 0x00c0,
+	0x2f9a, 0xa6b4, 0xffdf, 0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a,
+	0x681c, 0xa084, 0xffdf, 0x681e, 0x1078, 0x4633, 0x1078, 0x48f7,
+	0x0078, 0x3854, 0xa684, 0x2000, 0x0040, 0x2f8d, 0x6818, 0xa084,
+	0x8000, 0x0040, 0x2fab, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040,
+	0x2fab, 0x681b, 0x0007, 0x1078, 0x3868, 0x0078, 0x2438, 0x1078,
+	0x23ca, 0x2300, 0x0079, 0x2fb4, 0x2fb7, 0x2fb9, 0x2fec, 0x1078,
+	0x23ca, 0x7000, 0x0079, 0x2fbc, 0x2461, 0x2fc6, 0x2fc6, 0x2fe1,
+	0x2fc6, 0x2fe8, 0x2fe1, 0x2fc4, 0x1078, 0x23ca, 0xa684, 0x0060,
+	0xa086, 0x0060, 0x00c0, 0x2fdd, 0xa6b4, 0xffbf, 0xa6b4, 0xbfff,
+	0xa6b5, 0x2000, 0x7e5a, 0x681c, 0xa084, 0xffbf, 0x681e, 0x1078,
+	0x4633, 0x1078, 0x48f7, 0x0078, 0x3854, 0xa684, 0x2000, 0x0040,
+	0x2fd0, 0x6818, 0xa084, 0x8000, 0x0040, 0x2fe8, 0x681b, 0x0007,
+	0x781b, 0x00d2, 0x0078, 0x2438, 0x6820, 0xa085, 0x0004, 0x6822,
+	0x1078, 0x381f, 0xa6b5, 0x0800, 0x1078, 0x368f, 0x782b, 0x3008,
+	0x781b, 0x0065, 0x0078, 0x2438, 0x2300, 0x0079, 0x2fff, 0x3002,
+	0x3004, 0x3006, 0x1078, 0x23ca, 0x0078, 0x367b, 0xa684, 0x0400,
+	0x00c0, 0x302f, 0x79e4, 0xa184, 0x0020, 0x0040, 0x3016, 0x78ec,
+	0xa084, 0x0003, 0x0040, 0x3016, 0x782b, 0x3009, 0x789b, 0x0060,
+	0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, 0xa184, 0x0020,
+	0x0040, 0x3027, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x302b, 0x2001,
+	0x0014, 0x0078, 0x2cd7, 0xa184, 0x0007, 0x0079, 0x3067, 0x7a90,
+	0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, 0x0040, 0x3065,
+	0x789b, 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0, 0x3056, 0x7ba8,
+	0x7ba8, 0xa386, 0x0001, 0x00c0, 0x3049, 0x2009, 0xfff7, 0x0078,
+	0x304f, 0xa386, 0x0003, 0x00c0, 0x3056, 0x2009, 0xffef, 0x0c7e,
+	0x7054, 0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f, 0x789b, 0x0060,
+	0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920,
+	0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x3854, 0x297d,
+	0x2988, 0x3071, 0x3079, 0x306f, 0x306f, 0x3854, 0x3854, 0x1078,
+	0x23ca, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078,
+	0x385e, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078,
+	0x3854, 0x79e4, 0xa184, 0x0030, 0x0040, 0x308b, 0x78ec, 0xa084,
+	0x0003, 0x00c0, 0x30b2, 0x7000, 0xa086, 0x0004, 0x00c0, 0x30a5,
+	0x706c, 0xa086, 0x0002, 0x00c0, 0x309b, 0x2011, 0x0002, 0x2019,
+	0x0000, 0x0078, 0x2827, 0x706c, 0xa086, 0x0006, 0x0040, 0x3095,
+	0x706c, 0xa086, 0x0004, 0x0040, 0x3095, 0x7000, 0xa086, 0x0000,
+	0x0040, 0x2438, 0x6818, 0xa085, 0x8000, 0x681a, 0x2001, 0x0014,
+	0x0078, 0x2cd7, 0xa184, 0x0007, 0x0079, 0x30b6, 0x3854, 0x3854,
+	0x30be, 0x3854, 0x38b9, 0x38b9, 0x3854, 0x3854, 0xa684, 0x0080,
+	0x0040, 0x30ed, 0x7194, 0x81ff, 0x0040, 0x30ed, 0xa182, 0x000d,
+	0x00d0, 0x30ce, 0x7097, 0x0000, 0x0078, 0x30d3, 0xa182, 0x000c,
+	0x7096, 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa, 0x157e, 0x137e,
+	0x147e, 0x7098, 0x8114, 0xa210, 0x729a, 0xa080, 0x000b, 0xad00,
+	0x2098, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6,
+	0x147f, 0x137f, 0x157f, 0x0078, 0x385e, 0xa684, 0x0400, 0x00c0,
+	0x312e, 0x6820, 0xa084, 0x0001, 0x0040, 0x385e, 0xa68c, 0x0060,
+	0xa684, 0x0060, 0x0040, 0x3102, 0xa086, 0x0060, 0x00c0, 0x3102,
+	0xa18d, 0x4000, 0xa18c, 0xfffb, 0x795a, 0x69b6, 0x789b, 0x0060,
+	0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xa085, 0x8000, 0x681a,
+	0x78aa, 0x8008, 0x810c, 0x0040, 0x33dd, 0xa18c, 0x00f8, 0x00c0,
+	0x33dd, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000,
+	0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f,
+	0x157f, 0x6814, 0x8007, 0x7882, 0x0078, 0x385e, 0x6818, 0xa084,
+	0x8000, 0x0040, 0x3135, 0x681b, 0x0008, 0x781b, 0x00c8, 0x0078,
+	0x2438, 0x2300, 0x0079, 0x313c, 0x3141, 0x31e0, 0x313f, 0x1078,
+	0x23ca, 0x7000, 0xa084, 0x0007, 0x0079, 0x3146, 0x2461, 0x3150,
+	0x3185, 0x315b, 0x314e, 0x2461, 0x314e, 0x314e, 0x1078, 0x23ca,
+	0x681c, 0xa084, 0x2000, 0x0040, 0x3169, 0x6008, 0xa085, 0x0002,
+	0x600a, 0x0078, 0x3169, 0x68c0, 0xa005, 0x00c0, 0x3185, 0x6920,
+	0xa18d, 0x0001, 0x6922, 0x68c3, 0x0001, 0x6800, 0x706a, 0x0078,
+	0x317f, 0x6920, 0xa18d, 0x0001, 0x6922, 0x6800, 0x6006, 0xa005,
+	0x00c0, 0x3173, 0x6002, 0x681c, 0xa084, 0x000e, 0x0040, 0x317f,
+	0x7014, 0x68ba, 0x7130, 0xa188, 0x7300, 0x0078, 0x3181, 0x2009,
+	0x7400, 0x2104, 0x6802, 0x2d0a, 0x7162, 0x6eb6, 0xa684, 0x0060,
+	0x0040, 0x31de, 0xa684, 0x0800, 0x00c0, 0x3199, 0xa684, 0x7fff,
+	0x68b6, 0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078, 0x4633, 0x0078,
+	0x31de, 0xa684, 0x0020, 0x0040, 0x31ae, 0x68c0, 0xa005, 0x0040,
+	0x31a5, 0x1078, 0x4a35, 0x0078, 0x31a8, 0xa006, 0x1078, 0x49ed,
+	0x79d8, 0x7adc, 0x69aa, 0x6aa6, 0x0078, 0x31b4, 0x1078, 0x37ca,
+	0x69aa, 0x6aa6, 0x1078, 0x49ed, 0xa684, 0x8000, 0x0040, 0x31de,
+	0xa684, 0x7fff, 0x68b6, 0x2001, 0x0076, 0x1078, 0x38e4, 0x2010,
+	0x2001, 0x0078, 0x1078, 0x38e4, 0x2008, 0xa684, 0x0020, 0x00c0,
+	0x31d6, 0x2001, 0x007a, 0x1078, 0x38e4, 0x801b, 0x00c8, 0x31d1,
X 	0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100,
-	0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x0078, 0x1f03,
-	0x0078, 0x2f75, 0x7033, 0x0000, 0xa282, 0x0006, 0x0050, 0x2b22,
-	0x1078, 0x1eac, 0x2300, 0x0079, 0x2b25, 0x2b28, 0x2b4e, 0x2b72,
-	0x2200, 0x0079, 0x2b2b, 0x2b31, 0x2f75, 0x2b33, 0x2b31, 0x2b9c,
-	0x2bed, 0x1078, 0x1eac, 0x7003, 0x0005, 0x2001, 0x4390, 0x2068,
-	0x703e, 0x157e, 0x20a9, 0x002f, 0x2003, 0x0000, 0x8000, 0x0070,
-	0x2b43, 0x0078, 0x2b3c, 0x157f, 0x6817, 0x0000, 0x68b7, 0x0700,
-	0x6823, 0x0800, 0x6827, 0x0003, 0x0078, 0x2f69, 0x7000, 0xa086,
-	0x0001, 0x00c0, 0x2b5b, 0x1078, 0x2cdf, 0x1078, 0x32f5, 0x7034,
-	0x600a, 0x0078, 0x2b60, 0x7000, 0xa086, 0x0003, 0x0040, 0x2b55,
-	0x7003, 0x0005, 0x2001, 0x4390, 0x2068, 0x703e, 0x7032, 0x2200,
-	0x0079, 0x2b6a, 0x2f75, 0x2b70, 0x2b70, 0x2b9c, 0x2b70, 0x2f75,
-	0x1078, 0x1eac, 0x7000, 0xa086, 0x0001, 0x00c0, 0x2b7f, 0x1078,
-	0x2cdf, 0x1078, 0x32f5, 0x7034, 0x600a, 0x0078, 0x2b84, 0x7000,
-	0xa086, 0x0003, 0x0040, 0x2b79, 0x7003, 0x0005, 0x2001, 0x4390,
-	0x2068, 0x703e, 0x7032, 0x2200, 0x0079, 0x2b8e, 0x2b96, 0x2b94,
-	0x2b94, 0x2b96, 0x2b94, 0x2b96, 0x1078, 0x1eac, 0x1078, 0x2f8d,
-	0x781b, 0x0067, 0x0078, 0x1efb, 0x7000, 0xa086, 0x0001, 0x00c0,
-	0x2ba9, 0x1078, 0x2cdf, 0x1078, 0x32f5, 0x7034, 0x600a, 0x0078,
-	0x2bae, 0x7000, 0xa086, 0x0003, 0x0040, 0x2ba3, 0x7003, 0x0002,
-	0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x0007,
-	0xa215, 0x2069, 0x4380, 0x2d04, 0x2d08, 0x7156, 0x2068, 0xa005,
-	0x0040, 0x2bc9, 0x6814, 0xa206, 0x0040, 0x2be2, 0x6800, 0x0078,
-	0x2bbc, 0x7003, 0x0005, 0x2001, 0x4390, 0x2068, 0x703e, 0x7032,
-	0x157e, 0x20a9, 0x002f, 0x2003, 0x0000, 0x8000, 0x0070, 0x2bda,
-	0x0078, 0x2bd3, 0x157f, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800,
+	0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x0078, 0x2461,
+	0x0078, 0x367b, 0x7037, 0x0000, 0xa282, 0x0006, 0x0050, 0x31ea,
+	0x1078, 0x23ca, 0x7000, 0xa084, 0x0007, 0x10c0, 0x398a, 0x2300,
+	0x0079, 0x31f2, 0x31f5, 0x321e, 0x3232, 0x2200, 0x0079, 0x31f8,
+	0x321c, 0x367b, 0x31fe, 0x321c, 0x324e, 0x3290, 0x7003, 0x0005,
+	0x2001, 0x7510, 0x2068, 0x704a, 0x157e, 0x20a9, 0x0031, 0x2003,
+	0x0000, 0x8000, 0x0070, 0x320e, 0x0078, 0x3207, 0x157f, 0xad80,
+	0x0009, 0x7036, 0x6817, 0x0000, 0x68b7, 0x0700, 0x6823, 0x0800,
+	0x6827, 0x0003, 0x0078, 0x366b, 0x1078, 0x23ca, 0x7003, 0x0005,
+	0x2001, 0x7510, 0x2068, 0x704a, 0xad80, 0x0009, 0x7036, 0x2200,
+	0x0079, 0x322a, 0x367b, 0x3230, 0x3230, 0x324e, 0x3230, 0x367b,
+	0x1078, 0x23ca, 0x7003, 0x0005, 0x2001, 0x7510, 0x2068, 0x704a,
+	0xad80, 0x0009, 0x7036, 0x2200, 0x0079, 0x323e, 0x3246, 0x3244,
+	0x3244, 0x3246, 0x3244, 0x3246, 0x1078, 0x23ca, 0x1078, 0x369f,
+	0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x7003, 0x0002,
+	0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f,
+	0xa215, 0x2069, 0x7400, 0x2d04, 0x2d08, 0x7162, 0x2068, 0xa005,
+	0x0040, 0x3269, 0x6814, 0xa206, 0x0040, 0x3285, 0x6800, 0x0078,
+	0x325c, 0x7003, 0x0005, 0x2001, 0x7510, 0x2068, 0x704a, 0x7036,
+	0x157e, 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x327a,
+	0x0078, 0x3273, 0x157f, 0xad80, 0x0009, 0x7036, 0x6a16, 0x68b7,
+	0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6820,
+	0xa084, 0x0c00, 0x0040, 0x32df, 0x1078, 0x3697, 0x0078, 0x32df,
+	0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8,
+	0xa484, 0x001f, 0xa215, 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0xa1e8,
+	0x7300, 0x2d04, 0x2d08, 0x7162, 0x2068, 0xa005, 0x0040, 0x32af,
+	0x6814, 0xa206, 0x0040, 0x32ca, 0x6800, 0x0078, 0x32a2, 0x7003,
+	0x0005, 0x2001, 0x7510, 0x2068, 0x704a, 0x157e, 0x20a9, 0x0031,
+	0x2003, 0x0000, 0x8000, 0x0070, 0x32bf, 0x0078, 0x32b8, 0x157f,
+	0xad80, 0x0009, 0x7036, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800,
X 	0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040,
-	0x2c4b, 0x1078, 0x2f85, 0x0078, 0x2c4b, 0x7000, 0xa086, 0x0001,
-	0x00c0, 0x2bfa, 0x1078, 0x2cdf, 0x1078, 0x32f5, 0x7034, 0x600a,
-	0x0078, 0x2bff, 0x7000, 0xa086, 0x0003, 0x0040, 0x2bf4, 0x7003,
-	0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484,
-	0x0007, 0xa215, 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0xa1e8, 0x4280,
-	0x2d04, 0x2d08, 0x7156, 0x2068, 0xa005, 0x0040, 0x2c1e, 0x6814,
-	0xa206, 0x0040, 0x2c36, 0x6800, 0x0078, 0x2c11, 0x7003, 0x0005,
-	0x2001, 0x4390, 0x2068, 0x703e, 0x157e, 0x20a9, 0x002f, 0x2003,
-	0x0000, 0x8000, 0x0070, 0x2c2e, 0x0078, 0x2c27, 0x157f, 0x6a16,
-	0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a,
-	0x6820, 0xa084, 0x0c00, 0x0040, 0x2c4b, 0xa084, 0x0800, 0x0040,
-	0x2c45, 0x1078, 0x2f89, 0x0078, 0x2c4b, 0x1078, 0x2f85, 0x70bf,
-	0x0000, 0x0078, 0x2c4b, 0x027e, 0x8207, 0xa084, 0x000f, 0x8003,
-	0x8003, 0x8003, 0xa080, 0x3a00, 0x2060, 0x704a, 0x6000, 0x704e,
-	0x6004, 0x7052, 0xa684, 0x0060, 0x0040, 0x2c64, 0x68a8, 0x78d2,
-	0x78da, 0x68a4, 0x78d6, 0x78de, 0x077f, 0x1078, 0x3099, 0x2009,
-	0x0068, 0xa684, 0x0008, 0x0040, 0x2c6f, 0x2009, 0x0067, 0xa6b5,
-	0x2000, 0x7e5a, 0x791a, 0xa684, 0x0060, 0x0040, 0x2c85, 0xa684,
-	0x0800, 0x00c0, 0x2c7f, 0x1078, 0x3571, 0x0078, 0x2c85, 0xa684,
-	0x4000, 0x00c0, 0x2c85, 0x1078, 0x3502, 0x2d00, 0x703e, 0x8207,
-	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x3a00, 0x2048,
-	0x0078, 0x1efb, 0x6020, 0xa005, 0x0040, 0x2c9e, 0x8001, 0x6022,
-	0x6008, 0xa085, 0x0008, 0x600a, 0x7010, 0x6026, 0x007c, 0xa006,
-	0x1078, 0x32f5, 0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040,
-	0x681f, 0x0100, 0x7000, 0xa084, 0x0007, 0x0079, 0x2caf, 0x2cb7,
-	0x2cb9, 0x2cb9, 0x2cc5, 0x2cc1, 0x2cb7, 0x2cc1, 0x2cb7, 0x1078,
-	0x1eac, 0x1078, 0x2cd0, 0x1078, 0x2cc9, 0x1078, 0x1a26, 0x0078,
-	0x1f03, 0x70a3, 0x0000, 0x0078, 0x1f03, 0x681b, 0x0000, 0x0078,
-	0x2871, 0x6800, 0xa005, 0x00c0, 0x2cce, 0x6002, 0x6006, 0x007c,
-	0x6010, 0xa005, 0x0040, 0x2cd9, 0x8001, 0x00d0, 0x2cd9, 0x1078,
-	0x1eac, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x007c, 0x6018,
-	0xa005, 0x0040, 0x2ce5, 0x8001, 0x601a, 0x007c, 0x1078, 0x316a,
-	0x6818, 0xa084, 0x8000, 0x0040, 0x2cef, 0x681b, 0x0018, 0x0078,
-	0x2d26, 0x1078, 0x316a, 0x6818, 0xa084, 0x8000, 0x0040, 0x2cfa,
-	0x681b, 0x0019, 0x0078, 0x2d26, 0x1078, 0x316a, 0x6818, 0xa084,
-	0x8000, 0x0040, 0x2d05, 0x681b, 0x001a, 0x0078, 0x2d26, 0x1078,
-	0x316a, 0x681b, 0x0003, 0x0078, 0x2d26, 0x71b8, 0xa18c, 0x00ff,
-	0xa1e8, 0x4280, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x00c0, 0x2d1a,
-	0x0078, 0x1f03, 0x6814, 0x72b4, 0xa206, 0x0040, 0x2d22, 0x6800,
-	0x0078, 0x2d13, 0x6800, 0x200a, 0x681b, 0x0005, 0x681f, 0x0000,
-	0x6823, 0x0020, 0x1078, 0x2cd0, 0x1078, 0x2cc9, 0x1078, 0x1a26,
-	0x0078, 0x1f03, 0xa282, 0x0003, 0x00c0, 0x2f69, 0x7da8, 0xa5ac,
-	0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920, 0xa18d, 0x0080, 0x6922,
-	0xa184, 0x0100, 0x0040, 0x2d92, 0xa18c, 0xfeff, 0x6922, 0xa6b4,
-	0x00ff, 0x0040, 0x2d7c, 0xa682, 0x000c, 0x0048, 0x2d53, 0x0040,
-	0x2d53, 0x2031, 0x000c, 0x852b, 0x852b, 0x1078, 0x3018, 0x0040,
-	0x2d5d, 0x1078, 0x2e4a, 0x0078, 0x2d85, 0x1078, 0x2fd3, 0x0c7e,
-	0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x2e6e, 0x0c7f,
-	0x6920, 0xa18d, 0x0100, 0x6922, 0x7e58, 0xa6b5, 0x0004, 0x7e5a,
-	0xa684, 0x0400, 0x00c0, 0x2d78, 0x781b, 0x0053, 0x0078, 0x1efb,
-	0x781b, 0x0067, 0x0078, 0x1efb, 0x0c7e, 0x2960, 0x6004, 0xa084,
-	0xfff5, 0x6006, 0x1078, 0x2e6e, 0x0c7f, 0x7e58, 0xa684, 0x0400,
-	0x00c0, 0x2d8e, 0x781b, 0x0056, 0x0078, 0x1efb, 0x781b, 0x0068,
-	0x0078, 0x1efb, 0x0c7e, 0x7048, 0x2060, 0x6100, 0xa18c, 0x1000,
-	0x0040, 0x2dd2, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c,
-	0x0048, 0x2da6, 0x0040, 0x2da6, 0x2011, 0x000c, 0x2600, 0xa202,
-	0x00c8, 0x2dab, 0x2230, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086,
-	0x0028, 0x00c0, 0x2dbb, 0xa282, 0x0019, 0x00c8, 0x2dc1, 0x2011,
-	0x0019, 0x0078, 0x2dc1, 0xa282, 0x000c, 0x00c8, 0x2dc1, 0x2011,
-	0x000c, 0x2200, 0xa502, 0x00c8, 0x2dc6, 0x2228, 0x1078, 0x2fd7,
-	0x852b, 0x852b, 0x1078, 0x3018, 0x0040, 0x2dd2, 0x1078, 0x2e4a,
-	0x0078, 0x2dd6, 0x1078, 0x2fd3, 0x1078, 0x2e6e, 0x7858, 0xa085,
-	0x0004, 0x785a, 0x0c7f, 0x781b, 0x0067, 0x0078, 0x1efb, 0x0c7e,
-	0x2960, 0x6000, 0xa084, 0x1000, 0x00c0, 0x2df7, 0x6010, 0xa084,
-	0x000f, 0x00c0, 0x2df1, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x0c7f,
-	0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x2e1e, 0x68a0,
-	0xa084, 0x0200, 0x00c0, 0x2df1, 0x6208, 0xa294, 0x00ff, 0x7018,
-	0xa086, 0x0028, 0x00c0, 0x2e0c, 0xa282, 0x0019, 0x00c8, 0x2e12,
-	0x2011, 0x0019, 0x0078, 0x2e12, 0xa282, 0x000c, 0x00c8, 0x2e12,
+	0x32df, 0xa084, 0x0800, 0x0040, 0x32d9, 0x1078, 0x369b, 0x0078,
+	0x32df, 0x1078, 0x3697, 0x708b, 0x0000, 0x0078, 0x32df, 0x027e,
+	0x8207, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x5280,
+	0x2060, 0x7056, 0x6000, 0x705a, 0x6004, 0x705e, 0xa684, 0x0060,
+	0x0040, 0x3337, 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x00c0,
+	0x3319, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, 0xb7ff, 0x7e5a,
+	0xa684, 0x0060, 0xa086, 0x0060, 0x0040, 0x3337, 0x68c0, 0xa005,
+	0x0040, 0x3312, 0x7003, 0x0003, 0x682b, 0x0000, 0x1078, 0x48e6,
+	0x0078, 0x3314, 0x1078, 0x48f7, 0xa6b5, 0x2000, 0x7e5a, 0x0078,
+	0x3337, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x0040,
+	0x3337, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xa6b4, 0xbfff,
+	0x7e5a, 0x007e, 0x68c0, 0xa005, 0x007f, 0x0040, 0x3335, 0x7003,
+	0x0003, 0x1078, 0x48e6, 0x0078, 0x3337, 0x1078, 0x4942, 0x077f,
+	0x1078, 0x37bd, 0x2009, 0x0065, 0xa684, 0x0004, 0x0040, 0x3358,
+	0x78e4, 0xa084, 0x0030, 0x0040, 0x3350, 0x78ec, 0xa084, 0x0003,
+	0x0040, 0x3350, 0x782b, 0x3008, 0x2009, 0x0065, 0x0078, 0x3358,
+	0x0f7e, 0x2079, 0x5000, 0x1078, 0x4633, 0x0f7f, 0x0040, 0x2461,
+	0x791a, 0x2d00, 0x704a, 0x8207, 0xa084, 0x000f, 0x8003, 0x8003,
+	0x8003, 0xa080, 0x5280, 0x2048, 0x0078, 0x2438, 0x6020, 0xa005,
+	0x0040, 0x3372, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008, 0x600a,
+	0x7010, 0x6026, 0x007c, 0xa006, 0x1078, 0x4633, 0x6817, 0x0000,
+	0x681b, 0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084,
+	0x0007, 0x0079, 0x3383, 0x2461, 0x338d, 0x338d, 0x33aa, 0x3395,
+	0x3393, 0x3395, 0x338b, 0x1078, 0x23ca, 0x1078, 0x33b5, 0x1078,
+	0x33ae, 0x1078, 0x1c53, 0x0078, 0x2461, 0x706c, 0x706f, 0x0000,
+	0x7093, 0x0000, 0x0079, 0x339c, 0x33a6, 0x33a6, 0x33a4, 0x33a4,
+	0x33a4, 0x33a6, 0x33a4, 0x33a6, 0x0079, 0x2840, 0x706f, 0x0000,
+	0x0078, 0x2461, 0x681b, 0x0000, 0x0078, 0x2eed, 0x6800, 0xa005,
+	0x00c0, 0x33b3, 0x6002, 0x6006, 0x007c, 0x6010, 0xa005, 0x0040,
+	0x33be, 0x8001, 0x00d0, 0x33be, 0x1078, 0x23ca, 0x6012, 0x6008,
+	0xa084, 0xffef, 0x600a, 0x007c, 0x6018, 0xa005, 0x0040, 0x33ca,
+	0x8001, 0x601a, 0x007c, 0x1078, 0x38de, 0x681b, 0x0018, 0x0078,
+	0x3401, 0x1078, 0x38de, 0x681b, 0x0019, 0x0078, 0x3401, 0x1078,
+	0x38de, 0x681b, 0x001a, 0x0078, 0x3401, 0x1078, 0x38de, 0x681b,
+	0x0003, 0x0078, 0x3401, 0x7780, 0x1078, 0x37bd, 0x7184, 0xa18c,
+	0x00ff, 0xa1e8, 0x7300, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x00c0,
+	0x33f3, 0x0078, 0x2461, 0x6814, 0x7280, 0xa206, 0x0040, 0x33fb,
+	0x6800, 0x0078, 0x33ec, 0x6800, 0x200a, 0x681b, 0x0005, 0x708b,
+	0x0000, 0x1078, 0x33b5, 0x6820, 0xa084, 0x0001, 0x00c0, 0x340a,
+	0x1078, 0x33ae, 0x1078, 0x33c4, 0x681f, 0x0000, 0x6823, 0x0020,
+	0x1078, 0x1c53, 0x0078, 0x2461, 0xa282, 0x0003, 0x00c0, 0x366b,
+	0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4, 0x00ff, 0x6920, 0xa18d,
+	0x0080, 0x6922, 0xa184, 0x0100, 0x0040, 0x3478, 0xa18c, 0xfeff,
+	0x6922, 0xa4a4, 0x00ff, 0x0040, 0x3462, 0xa482, 0x000c, 0x0048,
+	0x3435, 0x0040, 0x3435, 0x2021, 0x000c, 0x852b, 0x852b, 0x1078,
+	0x372e, 0x0040, 0x343f, 0x1078, 0x3531, 0x0078, 0x346b, 0x1078,
+	0x36e9, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078,
+	0x3558, 0x0c7f, 0x6920, 0xa18d, 0x0100, 0x6922, 0x7e58, 0xa6b5,
+	0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x345c, 0x782b, 0x3008,
+	0x781b, 0x0056, 0x0078, 0x2438, 0x782b, 0x3008, 0x781b, 0x0065,
+	0x0078, 0x2438, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, 0x6006,
+	0x1078, 0x3558, 0x0c7f, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x3474,
+	0x781b, 0x0058, 0x0078, 0x2438, 0x781b, 0x0065, 0x0078, 0x2438,
+	0x0c7e, 0x7054, 0x2060, 0x6100, 0xa18c, 0x1000, 0x0040, 0x34b8,
+	0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048, 0x348c,
+	0x0040, 0x348c, 0x2011, 0x000c, 0x2400, 0xa202, 0x00c8, 0x3491,
+	0x2220, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086, 0x0028, 0x00c0,
+	0x34a1, 0xa282, 0x0019, 0x00c8, 0x34a7, 0x2011, 0x0019, 0x0078,
+	0x34a7, 0xa282, 0x000c, 0x00c8, 0x34a7, 0x2011, 0x000c, 0x2200,
+	0xa502, 0x00c8, 0x34ac, 0x2228, 0x1078, 0x36ed, 0x852b, 0x852b,
+	0x1078, 0x372e, 0x0040, 0x34b8, 0x1078, 0x3531, 0x0078, 0x34bc,
+	0x1078, 0x36e9, 0x1078, 0x3558, 0x7858, 0xa085, 0x0004, 0x785a,
+	0x0c7f, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x0c7e,
+	0x2960, 0x6000, 0xa084, 0x1000, 0x00c0, 0x34df, 0x6010, 0xa084,
+	0x000f, 0x00c0, 0x34d9, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x0c7f,
+	0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3506, 0x68a0,
+	0xa084, 0x0200, 0x00c0, 0x34d9, 0x6208, 0xa294, 0x00ff, 0x7018,
+	0xa086, 0x0028, 0x00c0, 0x34f4, 0xa282, 0x0019, 0x00c8, 0x34fa,
+	0x2011, 0x0019, 0x0078, 0x34fa, 0xa282, 0x000c, 0x00c8, 0x34fa,
X 	0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c,
-	0x0048, 0x2e1e, 0x0040, 0x2e1e, 0x2019, 0x000c, 0x78ab, 0x0001,
+	0x0048, 0x3506, 0x0040, 0x3506, 0x2019, 0x000c, 0x78ab, 0x0001,
X 	0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005,
X 	0x6820, 0xa085, 0x0100, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x2960,
-	0x6104, 0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032, 0x2019, 0x0000,
-	0x0078, 0x2e3a, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001,
-	0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xa085, 0x0100, 0x6822,
-	0x0c7f, 0x007c, 0x0c7e, 0x7148, 0x2160, 0x2008, 0xa084, 0xfff0,
-	0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4, 0xa084,
-	0xfff8, 0xa18c, 0x0007, 0xa105, 0x78a6, 0x6016, 0x788a, 0xa6b4,
-	0x000f, 0x8637, 0x8204, 0x8004, 0xa084, 0x00ff, 0xa605, 0x600e,
-	0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x007c, 0x0c7e, 0x7048,
-	0x2060, 0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6, 0x6012,
-	0x7884, 0xa084, 0xfff0, 0x7886, 0x0c7f, 0x007c, 0xa282, 0x0002,
-	0x00c0, 0x2f69, 0x7aa8, 0x6920, 0xa18d, 0x0080, 0x6922, 0xa184,
-	0x0200, 0x0040, 0x2ec3, 0xa18c, 0xfdff, 0x6922, 0xa294, 0x00ff,
-	0xa282, 0x0002, 0x00c8, 0x2f69, 0x1078, 0x2f0a, 0x1078, 0x2e6e,
-	0xa980, 0x0001, 0x200c, 0x1078, 0x3095, 0x1078, 0x2ddf, 0x88ff,
-	0x0040, 0x2eb6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5,
-	0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2eb2, 0x781b, 0x0053,
-	0x0078, 0x1efb, 0x781b, 0x0067, 0x0078, 0x1efb, 0x7e58, 0xa684,
-	0x0400, 0x00c0, 0x2ebf, 0x781b, 0x0056, 0x0078, 0x1efb, 0x781b,
-	0x0068, 0x0078, 0x1efb, 0xa282, 0x0002, 0x00c8, 0x2ecb, 0xa284,
-	0x0001, 0x0040, 0x2ed5, 0x7148, 0xa188, 0x0000, 0x210c, 0xa18c,
-	0x2000, 0x00c0, 0x2ed5, 0x2011, 0x0000, 0x1078, 0x2fc5, 0x1078,
-	0x2f0a, 0x1078, 0x2e6e, 0x7858, 0xa085, 0x0004, 0x785a, 0x781b,
-	0x0067, 0x0078, 0x1efb, 0x0c7e, 0x027e, 0x2960, 0x6000, 0x2011,
-	0x0001, 0xa084, 0x2000, 0x00c0, 0x2efa, 0x6014, 0xa084, 0x0040,
-	0x00c0, 0x2ef8, 0xa18c, 0xffef, 0x6106, 0xa006, 0x0078, 0x2f07,
-	0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003,
-	0x7aaa, 0xa8c0, 0x0004, 0x6820, 0xa085, 0x0200, 0x6822, 0x027f,
-	0x0c7f, 0x007c, 0x0c7e, 0x7048, 0x2060, 0x82ff, 0x0040, 0x2f12,
-	0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084,
-	0xffbf, 0xa205, 0x78a6, 0x6016, 0x788a, 0x6004, 0xa084, 0xffef,
-	0x6006, 0x0c7f, 0x007c, 0xa684, 0x0020, 0x0040, 0x2f65, 0x7888,
-	0xa084, 0x0040, 0x0040, 0x2f65, 0x7bb8, 0xa384, 0x003f, 0x831b,
-	0x00c8, 0x2f33, 0x8000, 0xa005, 0x0040, 0x2f4c, 0x831b, 0x00c8,
-	0x2f3c, 0x8001, 0x0040, 0x2f61, 0xa684, 0x4000, 0x0040, 0x2f4c,
-	0x78b8, 0x801b, 0x00c8, 0x2f45, 0x8000, 0xa084, 0x003f, 0x00c0,
-	0x2f61, 0xa6b4, 0xbfff, 0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001,
-	0xa108, 0x00c8, 0x2f55, 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6,
-	0x7ade, 0x1078, 0x362f, 0x781b, 0x0065, 0x1078, 0x3502, 0x0078,
-	0x1efb, 0x781b, 0x0065, 0x0078, 0x1efb, 0x781b, 0x0068, 0x0078,
-	0x1efb, 0x1078, 0x2f91, 0x781b, 0x0067, 0x0078, 0x1efb, 0x1078,
-	0x2f7d, 0x781b, 0x0067, 0x0078, 0x1efb, 0x6827, 0x0002, 0x1078,
-	0x2f85, 0x781b, 0x0067, 0x0078, 0x1efb, 0x2001, 0x0005, 0x0078,
-	0x2f93, 0x2001, 0x000c, 0x0078, 0x2f93, 0x2001, 0x0006, 0x0078,
-	0x2f93, 0x2001, 0x000d, 0x0078, 0x2f93, 0x2001, 0x0009, 0x0078,
-	0x2f93, 0x2001, 0x0007, 0x789b, 0x007e, 0x78aa, 0xa6b5, 0x0008,
-	0x7e5a, 0x007c, 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b,
-	0x8703, 0xa0e0, 0x3a00, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184,
-	0x000f, 0x0040, 0x2fb3, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004,
-	0xa085, 0x0008, 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184,
-	0x0040, 0x0040, 0x2fc3, 0xa184, 0xffbf, 0x78a6, 0x6016, 0x6004,
-	0xa085, 0x0010, 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab,
-	0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060,
-	0x78ab, 0x0004, 0x007c, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b,
-	0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa,
-	0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x007c, 0x157e, 0x8007,
-	0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4,
-	0xa18c, 0xfff0, 0x2001, 0x3946, 0x2004, 0xa082, 0x0028, 0x0040,
-	0x3001, 0x2021, 0x307c, 0x2019, 0x0014, 0x20a9, 0x000c, 0x0078,
-	0x3007, 0x2021, 0x3088, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011,
-	0x0064, 0x2404, 0xa084, 0xfff0, 0xa106, 0x0040, 0x3016, 0x8420,
-	0x2300, 0xa210, 0x0070, 0x3016, 0x0078, 0x3009, 0x157f, 0x007c,
-	0x157e, 0x2011, 0x3946, 0x2214, 0xa282, 0x0032, 0x0048, 0x302c,
-	0x0040, 0x3030, 0x2021, 0x306e, 0x2019, 0x0011, 0x20a9, 0x000e,
-	0x2011, 0x0032, 0x0078, 0x3042, 0xa282, 0x0028, 0x0040, 0x303a,
-	0x2021, 0x307c, 0x2019, 0x0014, 0x20a9, 0x000c, 0x2011, 0x0064,
-	0x0078, 0x3042, 0x2021, 0x3088, 0x2019, 0x0019, 0x20a9, 0x000d,
-	0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x3052, 0x0048, 0x3052,
-	0x8420, 0x2300, 0xa210, 0x0070, 0x304f, 0x0078, 0x3042, 0x157f,
-	0xa006, 0x007c, 0x157f, 0x7a08, 0xa582, 0x0064, 0x00c8, 0x305d,
-	0xa285, 0x0040, 0x780a, 0x0078, 0x305d, 0x78ec, 0xa084, 0x0300,
-	0x0040, 0x306b, 0x2404, 0xa09e, 0x2002, 0x00c0, 0x306b, 0x2001,
-	0x2101, 0x0078, 0x306c, 0x2404, 0xa015, 0x007c, 0x2002, 0x3002,
-	0x3202, 0x4203, 0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806,
-	0x7a06, 0x0a07, 0x0c07, 0x0e07, 0x3202, 0x4202, 0x5202, 0x6202,
-	0x7202, 0x6605, 0x7605, 0x7805, 0x7a05, 0x7c05, 0x7e05, 0x7f05,
-	0x2202, 0x3202, 0x4202, 0x5202, 0x5404, 0x6404, 0x7404, 0x7604,
-	0x7804, 0x7a04, 0x7c04, 0x7e04, 0x7f04, 0x789b, 0x0010, 0xa046,
-	0x007c, 0xa784, 0x0f00, 0x800c, 0xa784, 0x0007, 0x8003, 0x8003,
-	0x8003, 0x8003, 0xa105, 0xa0e0, 0x3a80, 0x007c, 0x79d8, 0x7adc,
-	0x78d0, 0x801b, 0x00c8, 0x30ad, 0x8000, 0xa084, 0x003f, 0xa108,
-	0xa291, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x0100, 0x2009, 0x3940,
-	0x2091, 0x8000, 0x2104, 0x0079, 0x30bd, 0x30e3, 0x30c7, 0x30c7,
-	0x30c7, 0x30c7, 0x30c7, 0x30c7, 0x30c5, 0x1078, 0x1eac, 0x784b,
-	0x0004, 0x68b4, 0xa085, 0x4000, 0x68b6, 0x7858, 0xa085, 0x4000,
-	0x785a, 0x7830, 0xa084, 0x0080, 0x00c0, 0x30e3, 0x0018, 0x30e3,
-	0x681c, 0xa084, 0x0020, 0x00c0, 0x30e1, 0x781b, 0x00df, 0x0078,
-	0x30e3, 0x781b, 0x00e6, 0x2091, 0x8001, 0x0f7f, 0x007c, 0x0c7e,
+	0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078,
+	0x3521, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa,
+	0x7baa, 0xa8c0, 0x0005, 0x6820, 0xa085, 0x0100, 0x6822, 0x0c7f,
+	0x007c, 0x0c7e, 0x7154, 0x2160, 0x1078, 0x3538, 0x0c7f, 0x007c,
+	0x2008, 0xa084, 0xfff0, 0xa425, 0x7c86, 0x6018, 0x789a, 0x7cae,
+	0x6412, 0x78a4, 0xa084, 0xfff8, 0xa18c, 0x0007, 0xa105, 0x78a6,
+	0x6016, 0x788a, 0xa4a4, 0x000f, 0x8427, 0x8204, 0x8004, 0xa084,
+	0x00ff, 0xa405, 0x600e, 0x6004, 0xa084, 0xfff5, 0x6006, 0x007c,
+	0x0c7e, 0x7054, 0x2060, 0x1078, 0x355f, 0x0c7f, 0x007c, 0x6018,
+	0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084,
+	0xfff0, 0x7886, 0x007c, 0xa282, 0x0002, 0x00c0, 0x366b, 0x7aa8,
+	0x6920, 0xa18d, 0x0080, 0x6922, 0xa184, 0x0200, 0x0040, 0x35b4,
+	0xa18c, 0xfdff, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8,
+	0x366b, 0x1078, 0x35fd, 0x1078, 0x3558, 0xa980, 0x0001, 0x200c,
+	0x1078, 0x37b9, 0x1078, 0x34c7, 0x88ff, 0x0040, 0x35a7, 0x789b,
+	0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684,
+	0x0400, 0x00c0, 0x35a1, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078,
+	0x2438, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x7e58,
+	0xa684, 0x0400, 0x00c0, 0x35b0, 0x781b, 0x0058, 0x0078, 0x2438,
+	0x781b, 0x0065, 0x0078, 0x2438, 0xa282, 0x0002, 0x00c8, 0x35bc,
+	0xa284, 0x0001, 0x0040, 0x35c6, 0x7154, 0xa188, 0x0000, 0x210c,
+	0xa18c, 0x2000, 0x00c0, 0x35c6, 0x2011, 0x0000, 0x1078, 0x36db,
+	0x1078, 0x35fd, 0x1078, 0x3558, 0x7858, 0xa085, 0x0004, 0x785a,
+	0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x0c7e, 0x027e,
+	0x2960, 0x6000, 0x2011, 0x0001, 0xa084, 0x2000, 0x00c0, 0x35ed,
+	0x6014, 0xa084, 0x0040, 0x00c0, 0x35eb, 0xa18c, 0xffef, 0x6106,
+	0xa006, 0x0078, 0x35fa, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
+	0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x6820, 0xa085,
+	0x0200, 0x6822, 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7054, 0x2060,
+	0x1078, 0x3604, 0x0c7f, 0x007c, 0x82ff, 0x0040, 0x3609, 0x2011,
+	0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, 0xffbf,
+	0xa205, 0x78a6, 0x788a, 0x6016, 0x6004, 0xa084, 0xffef, 0x6006,
+	0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x3622, 0x007f,
+	0x0078, 0x3625, 0x007f, 0x0078, 0x3667, 0xa684, 0x0020, 0x0040,
+	0x3667, 0x7888, 0xa084, 0x0040, 0x0040, 0x3667, 0x7bb8, 0xa384,
+	0x003f, 0x831b, 0x00c8, 0x3635, 0x8000, 0xa005, 0x0040, 0x364b,
+	0x831b, 0x00c8, 0x363e, 0x8001, 0x0040, 0x3663, 0xa684, 0x4000,
+	0x0040, 0x364b, 0x78b8, 0x801b, 0x00c8, 0x3647, 0x8000, 0xa084,
+	0x003f, 0x00c0, 0x3663, 0xa6b4, 0xbfff, 0x7e5a, 0x79d8, 0x7adc,
+	0x2001, 0x0001, 0xa108, 0x00c8, 0x3657, 0xa291, 0x0000, 0x79d2,
+	0x79da, 0x7ad6, 0x7ade, 0x1078, 0x49ed, 0x781b, 0x0064, 0x1078,
+	0x4872, 0x0078, 0x2438, 0x781b, 0x0064, 0x0078, 0x2438, 0x781b,
+	0x0065, 0x0078, 0x2438, 0x1078, 0x36a3, 0x782b, 0x3008, 0x781b,
+	0x0065, 0x0078, 0x2438, 0x1078, 0x368f, 0x782b, 0x3008, 0x781b,
+	0x0065, 0x0078, 0x2438, 0x6827, 0x0002, 0x1078, 0x3697, 0x78e4,
+	0xa084, 0x0030, 0x0040, 0x2461, 0x78ec, 0xa084, 0x0003, 0x0040,
+	0x2461, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x2001,
+	0x0005, 0x0078, 0x36a5, 0x2001, 0x000c, 0x0078, 0x36a5, 0x2001,
+	0x0006, 0x0078, 0x36a5, 0x2001, 0x000d, 0x0078, 0x36a5, 0x2001,
+	0x0009, 0x0078, 0x36a5, 0x2001, 0x0007, 0x789b, 0x0010, 0x78aa,
+	0x789b, 0x0060, 0x78ab, 0x0001, 0xa6b5, 0x0004, 0x7e5a, 0x007c,
+	0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0,
+	0x5280, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040,
+	0x36c9, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004, 0xa085, 0x0008,
+	0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040, 0x0040,
+	0x36d9, 0xa184, 0xffbf, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0010,
+	0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab,
+	0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004,
+	0x007c, 0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab,
+	0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b,
+	0x0060, 0x78ab, 0x0005, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff,
+	0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0,
+	0x2001, 0x5046, 0x2004, 0xa082, 0x0028, 0x0040, 0x3717, 0x2021,
+	0x37a0, 0x2019, 0x0014, 0x20a9, 0x000c, 0x0078, 0x371d, 0x2021,
+	0x37ac, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064, 0x2404,
+	0xa084, 0xfff0, 0xa106, 0x0040, 0x372c, 0x8420, 0x2300, 0xa210,
+	0x0070, 0x372c, 0x0078, 0x371f, 0x157f, 0x007c, 0x157e, 0x2009,
+	0x5046, 0x210c, 0xa182, 0x0032, 0x0048, 0x3742, 0x0040, 0x3746,
+	0x2009, 0x3792, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032,
+	0x0078, 0x3758, 0xa182, 0x0028, 0x0040, 0x3750, 0x2009, 0x37a0,
+	0x2019, 0x0014, 0x20a9, 0x000c, 0x2011, 0x0064, 0x0078, 0x3758,
+	0x2009, 0x37ac, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064,
+	0x2200, 0xa502, 0x0040, 0x3768, 0x0048, 0x3768, 0x8108, 0x2300,
+	0xa210, 0x0070, 0x3765, 0x0078, 0x3758, 0x157f, 0xa006, 0x007c,
+	0x157f, 0xa582, 0x0064, 0x00c8, 0x3777, 0x7808, 0xa085, 0x0070,
+	0x780a, 0x7044, 0xa085, 0x0070, 0x7046, 0x0078, 0x3777, 0x78ec,
+	0xa084, 0x0300, 0x0040, 0x377f, 0x2104, 0x0078, 0x3790, 0x2104,
+	0xa09e, 0x1102, 0x00c0, 0x3790, 0x2001, 0x04fd, 0x2004, 0xa082,
+	0x0005, 0x0048, 0x378f, 0x2001, 0x1201, 0x0078, 0x3790, 0x2104,
+	0xa005, 0x007c, 0x1102, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404,
+	0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, 0x0e07,
+	0x3202, 0x4202, 0x5202, 0x6202, 0x7202, 0x6605, 0x7605, 0x7805,
+	0x7a05, 0x7c05, 0x7e05, 0x7f05, 0x2202, 0x3202, 0x4202, 0x5202,
+	0x5404, 0x6404, 0x7404, 0x7604, 0x7804, 0x7a04, 0x7c04, 0x7e04,
+	0x7f04, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784, 0x0f00, 0x800b,
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 09'
echo 'File patch-2.2.7 is continued in part 10'
echo 10 > _shar_seq_.tmp
#!/bin/sh
# this is part 11 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 11; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
+	0x7b3a, 0x007c, 0x2019, 0x3971, 0x2011, 0x5046, 0x2204, 0xa086,
+	0x003c, 0x0040, 0x4c15, 0x2019, 0x2626, 0x7b22, 0x7b26, 0x783f,
+	0x0000, 0x7843, 0x000a, 0x007c, 0x0020, 0x002b, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0014,
+	0x0014, 0x9849, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014,
+	0x0014, 0x0080, 0x000f, 0x0000, 0x0201, 0x0604, 0x0c08, 0x2120,
+	0x4022, 0xf880, 0x0018, 0x300b, 0xa201, 0x0014, 0xa200, 0x0014,
+	0xa200, 0x0214, 0x0000, 0x006c, 0x0002, 0x0014, 0x98d5, 0x009e,
+	0x009b, 0xa202, 0x8838, 0x3806, 0x8839, 0x20c3, 0x0864, 0x9889,
+	0x28c1, 0x9cb6, 0xa203, 0x300c, 0x2846, 0x8161, 0x846a, 0x8300,
+	0x1856, 0x883a, 0x9865, 0x28f2, 0x9c95, 0x9858, 0x300c, 0x28e1,
+	0x9c95, 0x2809, 0xa206, 0x64c0, 0x67a0, 0x6fc0, 0x1814, 0x883b,
+	0x782c, 0x786d, 0x9879, 0x282b, 0xa207, 0x64a0, 0x67a0, 0x6fc0,
+	0x1814, 0x883b, 0x7822, 0x883e, 0x987d, 0x8576, 0x8677, 0x206b,
+	0x28c1, 0x9cb6, 0x2044, 0x2103, 0x20a2, 0x2081, 0x9865, 0xa209,
+	0x2901, 0x9891, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a, 0x883c,
+	0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c95, 0x0014, 0xa204,
+	0xa300, 0x3009, 0x19e2, 0xf868, 0x8176, 0x86eb, 0x85eb, 0x872e,
+	0x87a9, 0x883f, 0x08e6, 0x9895, 0xf881, 0x9890, 0xc801, 0x0014,
+	0xf8c1, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfb02, 0x1de2, 0x0014,
+	0x8532, 0xf241, 0x0014, 0x1de2, 0x84a8, 0xd7a0, 0x1fe6, 0x0014,
+	0xa208, 0x6043, 0x8008, 0x1dc1, 0x0016, 0x8300, 0x8160, 0x842a,
+	0xf041, 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d5,
+	0x8822, 0x0016, 0x8000, 0x2847, 0x1011, 0x98c8, 0x8000, 0xa000,
+	0x2802, 0x1011, 0x98ce, 0x9865, 0x283e, 0x1011, 0x98d2, 0xa20b,
+	0x0017, 0x300c, 0xa300, 0x1de2, 0xdb81, 0x0014, 0x0210, 0x98df,
+	0x0014, 0x26e0, 0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d,
+	0x3806, 0x0210, 0x9cbb, 0x0704, 0x0000, 0x006c, 0x0002, 0x984f,
+	0x0014, 0x009e, 0x00a0, 0x0017, 0x60ff, 0x300c, 0x8720, 0xa211,
+	0x9cd0, 0x8772, 0x8837, 0x2101, 0x987a, 0x10d2, 0x78e2, 0x9cd3,
+	0x9859, 0xd984, 0xf0e2, 0xf0a1, 0x98cd, 0x0014, 0x8831, 0xd166,
+	0x8830, 0x800f, 0x9401, 0xb520, 0xc802, 0x8820, 0x987a, 0x2301,
+	0x987a, 0x10d2, 0x78e4, 0x9cd3, 0x8821, 0x8820, 0x9859, 0xf123,
+	0xf142, 0xf101, 0x98c6, 0x10d2, 0x70f6, 0x8832, 0x8203, 0x870c,
+	0xd99e, 0x6001, 0x0014, 0x6845, 0x0214, 0xa21b, 0x9cd0, 0x2001,
+	0x98c5, 0x8201, 0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0x988d,
+	0x3027, 0x84a8, 0x1a56, 0x8833, 0x0014, 0xa218, 0x6981, 0x9cbc,
+	0x6b2a, 0x6902, 0x1834, 0x989d, 0x1814, 0x8010, 0x8592, 0x8026,
+	0x84b9, 0x7021, 0x0014, 0xa300, 0x69e1, 0x9ca9, 0x694b, 0xa213,
+	0x1462, 0xa213, 0x8000, 0x16e1, 0x98b5, 0x8023, 0x16e1, 0x8001,
+	0x10f1, 0x0016, 0x6969, 0xa214, 0x61c2, 0x8002, 0x14e1, 0x8004,
+	0x16e1, 0x0101, 0x300a, 0x8827, 0x0014, 0xa217, 0x9cbc, 0x0014,
+	0xa300, 0x8181, 0x842a, 0x84a8, 0x1ce6, 0x882c, 0x0016, 0xa212,
+	0x9cd0, 0x10d2, 0x70e4, 0x0004, 0x8007, 0x9424, 0xcc1a, 0x9cd3,
+	0x98c5, 0x8827, 0x300a, 0x0013, 0x8000, 0x84a4, 0x0016, 0x11c2,
+	0x211e, 0x870e, 0xa21d, 0x0014, 0x878e, 0x0016, 0xa21c, 0x1035,
+	0x9891, 0xa210, 0xa000, 0x8010, 0x8592, 0x853b, 0xd044, 0x8022,
+	0x3807, 0x84bb, 0x98ea, 0x8021, 0x3807, 0x84b9, 0x300c, 0x817e,
+	0x872b, 0x8772, 0x9891, 0x0000, 0x0020, 0x002b, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0014,
+	0x0014, 0x9849, 0x0014, 0x0014, 0x98ea, 0x98d5, 0x0014, 0x0014,
+	0x0014, 0x0080, 0x013f, 0x0000, 0x0201, 0x0604, 0x0c08, 0x2120,
+	0x4022, 0xf880, 0x0018, 0x300b, 0xa201, 0x0014, 0xa200, 0x0014,
+	0xa200, 0x0214, 0xa202, 0x8838, 0x3806, 0x8839, 0x20c3, 0x0864,
+	0xa833, 0x28c1, 0x9cb6, 0xa203, 0x300c, 0x2846, 0x8161, 0x846a,
+	0x8300, 0x1856, 0x883a, 0xa804, 0x28f2, 0x9c95, 0xa8f4, 0x300c,
+	0x28e1, 0x9c95, 0x2809, 0xa206, 0x64c0, 0x67a0, 0x6fc0, 0x1814,
+	0x883b, 0x782c, 0x786d, 0xa808, 0x282b, 0xa207, 0x64a0, 0x67a0,
+	0x6fc0, 0x1814, 0x883b, 0x7822, 0x883e, 0xa802, 0x8576, 0x8677,
+	0x206b, 0x28c1, 0x9cb6, 0x2044, 0x2103, 0x20a2, 0x2081, 0xa8e0,
+	0xa209, 0x2901, 0xa809, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a,
+	0x883c, 0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c95, 0x0014,
+	0xa204, 0xa300, 0x3009, 0x19e2, 0xf868, 0x8176, 0x86eb, 0x85eb,
+	0x872e, 0x87a9, 0x883f, 0x08e6, 0xa8f3, 0xf881, 0xa8ec, 0xc801,
+	0x0014, 0xf8c1, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfb02, 0x1de2,
+	0x0014, 0x8532, 0xf241, 0x0014, 0x1de2, 0x84a8, 0xd7a0, 0x1fe6,
+	0x0014, 0xa208, 0x6043, 0x8008, 0x1dc1, 0x0016, 0x8300, 0x8160,
+	0x842a, 0xf041, 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011,
+	0x20d5, 0x8822, 0x0016, 0x8000, 0x2847, 0x1011, 0xa8fc, 0x8000,
+	0xa000, 0x2802, 0x1011, 0xa8fd, 0xa893, 0x283e, 0x1011, 0xa8fd,
+	0xa20b, 0x0017, 0x300c, 0xa300, 0x1de2, 0xdb81, 0x0014, 0x0210,
+	0xa801, 0x0014, 0x26e0, 0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014,
+	0xa20d, 0x3806, 0x0210, 0x9cbb, 0x0704, 0x0017, 0x60ff, 0x300c,
+	0x8720, 0xa211, 0x9d6b, 0x8772, 0x8837, 0x2101, 0xa821, 0x10d2,
+	0x78e2, 0x9d6e, 0xa8fc, 0xd984, 0xf0e2, 0xf0a1, 0xa86c, 0x0014,
+	0x8831, 0xd166, 0x8830, 0x800f, 0x9401, 0xb520, 0xc802, 0x8820,
+	0xa80f, 0x2301, 0xa80d, 0x10d2, 0x78e4, 0x9d6e, 0x8821, 0x8820,
+	0xa8e6, 0xf123, 0xf142, 0xf101, 0xa84f, 0x10d2, 0x70f6, 0x8832,
+	0x8203, 0x870c, 0xd99e, 0x6001, 0x0014, 0x6845, 0x0214, 0xa21b,
+	0x9d6b, 0x2001, 0xa840, 0x8201, 0x1852, 0xd184, 0xd163, 0x8834,
+	0x8001, 0xa801, 0x3027, 0x84a8, 0x1a56, 0x8833, 0x0014, 0xa218,
+	0x6981, 0x9d57, 0x6b2a, 0x6902, 0x1834, 0xa805, 0x1814, 0x8010,
+	0x8592, 0x8026, 0x84b9, 0x7021, 0x0014, 0xa300, 0x69e1, 0x9d44,
+	0x694b, 0xa213, 0x1462, 0xa213, 0x8000, 0x16e1, 0xa80c, 0x8023,
+	0x16e1, 0x8001, 0x10f1, 0x0016, 0x6969, 0xa214, 0x61c2, 0x8002,
+	0x14e1, 0x8004, 0x16e1, 0x0101, 0x300a, 0x8827, 0x0014, 0xa217,
+	0x9d57, 0x0014, 0xa300, 0x8181, 0x842a, 0x84a8, 0x1ce6, 0x882c,
+	0x0016, 0xa212, 0x9d6b, 0x10d2, 0x70e4, 0x0004, 0x8007, 0x9424,
+	0xcc1a, 0x9d6e, 0xa8f8, 0x8827, 0x300a, 0x0013, 0x8000, 0x84a4,
+	0x0016, 0x11c2, 0x211e, 0x870e, 0xa21d, 0x0014, 0x878e, 0x0016,
+	0xa21c, 0x1035, 0xa8b4, 0xa210, 0x3807, 0x300c, 0x817e, 0x872b,
+	0x8772, 0xa8ad, 0x0000, 0x8ec6
X };
X 
X #endif /* RELOAD_FIRMWARE */
X 
-static const unsigned short risc_code_length01 = 0x283a;
+static const unsigned short risc_code_length01 = 0x3f14;
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/CREDITS linux/drivers/usb/CREDITS
--- v2.2.6/linux/drivers/usb/CREDITS	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/CREDITS	Sat Apr 24 04:48:49 1999
@@ -0,0 +1,23 @@
+Credits for the Simple Linux USB Driver:
+
+The following people have contributed to this code (in alphabetical
+order by last name).  I'm sure this list should be longer, its
+difficult to maintain.
+
+  Johannes Erdfelt <jerd...@sventech.com>
+  ham <h...@unsuave.com>
+  Bradley M Keryan <ker...@andrew.cmu.edu>
+  Vojtech Pavlik <voj...@twilight.ucw.cz>
+  Gregory P. Smith <gr...@electricrain.com>
+  Linus Torvalds <torv...@transmeta.com>
+  <Kazuki.Y...@fujixerox.co.jp>
+
+Special thanks to:
+
+  Inaky Perez Gonzalez <in...@peloncho.fis.ucm.es> for starting the
+  Linux USB driver effort and writing much of the larger uusbd driver.
+  Much has been learned from that effort.
+
+  The NetBSD & FreeBSD USB developers.  For being on the Linux USB list
+  and offering suggestions and sharing implementation experiences.
+
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/Config.in linux/drivers/usb/Config.in
--- v2.2.6/linux/drivers/usb/Config.in	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/Config.in	Wed Apr 28 11:14:03 1999
@@ -0,0 +1,26 @@
+#
+# USB device configuration
+#
+# NOTE NOTE NOTE! This is still considered extremely experimental.
+# Right now hubs, mice and keyboards work - at least with UHCI.
+# But that may be more a lucky coincidence than anything else..
+#
+# This was all developed modularly, but I've been lazy in cleaning
+# it up, so right now they are all bools. 
+#
+mainmenu_option next_comment
+comment 'USB drivers - not for the faint of heart'
+
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  tristate 'Support for USB (EXPERIMENTAL!)' CONFIG_USB
+  if [ ! "$CONFIG_USB" = "n" ]; then
+    bool 'UHCI (intel PIIX4 and others) support?' CONFIG_USB_UHCI
+    bool 'OHCI (compaq and some others) support?' CONFIG_USB_OHCI
+
+    bool 'USB mouse support' CONFIG_USB_MOUSE
+    bool 'USB keyboard support' CONFIG_USB_KBD
+    bool 'USB audio parsing support' CONFIG_USB_AUDIO
+  fi
+fi
+
+endmenu
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/Makefile linux/drivers/usb/Makefile
--- v2.2.6/linux/drivers/usb/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/Makefile	Wed Apr 28 11:14:03 1999
@@ -0,0 +1,75 @@
+#
+# Makefile for the kernel usb device drivers.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now inherited from the
+# parent makes..
+#
+# This isn't actually supported yet. Don't try to use it.
+
+SUB_DIRS     :=
+MOD_SUB_DIRS := $(SUB_DIRS)
+ALL_SUB_DIRS := $(SUB_DIRS)
+
+L_TARGET := usb.a
+M_OBJS   :=
+L_OBJS   :=
+LX_OBJS  :=
+USBX_OBJS := usb.o hub.o usb-debug.o
+
+ifeq ($(CONFIG_USB_MOUSE),y)
+  USBX_OBJS += mouse.o
+endif
+
+ifeq ($(CONFIG_USB_KBD),y)
+  USBX_OBJS += keyboard.o keymap.o
+endif
+
+ifeq ($(CONFIG_USB_AUDIO),y)
+  USBX_OBJS += audio.o
+endif
+
+ifeq ($(CONFIG_USB), y)
+  L_OBJS += $(USBX_OBJS)
+endif
+
+ifeq ($(CONFIG_USB_UHCI),y)
+  ifeq ($(CONFIG_USB), y)
+    L_OBJS += uhci.o uhci-debug.o
+  else
+    ifeq ($(CONFIG_USB),m)
+      M_OBJS += usb-uhci.o
+      MIX_OBJS += $(USBX_OBJS)
+    endif
+  endif
+endif
+
+ifeq ($(CONFIG_USB_OHCI),y)
+  ifeq ($(CONFIG_USB), y)
+    L_OBJS += ohci.o ohci-debug.o
+  else
+    ifeq ($(CONFIG_USB),m)
+      USBO_OBJS += ohci.o ohci-debug.o
+      M_OBJS += usb-ohci.o
+      MIX_OBJS += $(USBX_OBJS)
+    endif
+  endif
+endif
+
+
+include $(TOPDIR)/Rules.make
+
+keymap.o: keymap.c
+
+keymap.c: maps/serial.map maps/usb.map maps/fixup.map
+	./mkmap > $@
+
+usb-uhci.o: uhci.o uhci-debug.o $(USBX_OBJS)
+	$(LD) $(LD_RFLAG) -r -o $@  uhci.o uhci-debug.o $(USBX_OBJS)
+
+usb-ohci.o: ohci.o ohci-debug.o $(USBX_OBJS)
+	$(LD) $(LD_RFLAG) -r -o $@ ohci.o ohci-debug.o $(USBX_OBJS)
+
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/README.kbd linux/drivers/usb/README.kbd
--- v2.2.6/linux/drivers/usb/README.kbd	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/README.kbd	Wed Apr 21 10:29:09 1999
@@ -0,0 +1,65 @@
+This is a simple USB keyboard driver written from Linus'
+USB driver (started with Greg's usb-0.03b.tar.gz source
+tree)
+
+It works fine with my BTC keyboard but I'm still investigating
+trouble with my MS keyboard (trouble starts with an inability
+to set into boot protocol mode, though, this very well could
+be all due to crappy hardware).
+
+Anyway, I would appreciate you taking a look if you have
+any USB keyboards lying around.  Oh also, I'm doing this on
+UHCI so sorry if it breaks with OHCI.
+
+-ham
+
+
+
+Keyboard patch
+--------------
+
+Instead of using the multiple keyboard patch and then running into all
+of the kernel version problems that the current Linux-USB project has
+had, I'm just mapping the USB keycodes to the standard AT-101 keycodes
+and sending them directly to "handle_scancode".
+
+This may or may not be considered a hack.  Anyway it is effective, and
+I think safe, and allows USB keyboards to coexist with a serial
+keyboard (oh yeah, one side effect is that you can for example hold
+down the control key on the serial keyboard and press "a" on the USB
+keyboard and you get Control-a like with Windows USB) and works
+fine for console and X.
+
+You do need to make a *tiny* patch the kernel source tree so that the
+function "handle_scancode" is exported from keyboard.c though.
+
+  $ cd /usr/src/linux
+  $ patch -p0 < kbd.patch
+
+And, of course, then, you need to rebuild and install the kernel.
+
+** [Vojtech]: Alternately, just 'insmod kbd-stub', if you don't want
+to use the keyboard and are too lazy to patch the kernel.
+
+Keyboard map
+------------
+
+I'm including a stupid utility "mkmap" which generates the USB->serial
+keymap.  It takes in maps/serial.map (the current serial keymap,
+generated by "dumpkeys"), maps/usb.map (the USB keymap), and
+maps/fixup.map (fixes for e0 keys and misc.) and spits out keymap.c
+Anyway, it is not beautiful but should serve its purpose for the
+moment.
+
+Other changes
+-------------
+uhci.c:
+  * added a context value to the irq callback function
+    (this is exactly like the "dev_id" field to request_irq)
+  * played with uhci_reset_port to get better hot-plug results
+    (eg. do a wait_ms(200) before calling uhci_reset_port)
+usb.c:
+  * disconnect all devices after uhci-control thread is killed
+  * skip over the HID descriptor
+  * disconnect the high-level driver in usb_disconnect
+
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/README.ohci linux/drivers/usb/README.ohci
--- v2.2.6/linux/drivers/usb/README.ohci	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/README.ohci	Sat Apr 24 04:40:07 1999
@@ -0,0 +1,8 @@
+April 24, 1999 04:37:42 PST
+
+Okay, I've written a lot more of the OHCI code and actually got it back to
+a compiling state now with all of the recent improvements to the way stuff
+is structured.  It is completely untested.
+
+- gr...@electricrain.com
+
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/audio.c linux/drivers/usb/audio.c
--- v2.2.6/linux/drivers/usb/audio.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/audio.c	Wed Apr 28 11:14:03 1999
@@ -0,0 +1,126 @@
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include "usb.h"
+
+static int usb_audio_probe(struct usb_device *dev);
+static void usb_audio_disconnect(struct usb_device *dev);
+static LIST_HEAD(usb_audio_list);
+
+struct usb_audio
+{
+	struct usb_device *dev;
+	struct list_head list;
+};
+
+static struct usb_driver usb_audio_driver =
+{
+	"audio",
+	usb_audio_probe,
+	usb_audio_disconnect,
+	{NULL, NULL}
+};
+
+
+static int usb_audio_irq(int state, void *buffer, void *dev_id)
+{
+	struct usb_audio *aud = (struct usb_audio*) dev_id;
+	return 1;
+}
+
+static int usb_audio_probe(struct usb_device *dev)
+{
+	struct usb_interface_descriptor *interface;
+	struct usb_endpoint_descriptor *endpoint;
+	struct usb_audio *aud;
+
+	int i;
+	int na=0;
+	
+	interface = &dev->config[0].interface[0];
+
+	for(i=0;i<dev->config[0].bNumInterfaces;i++)
+	{
+		int x;
+		
+		endpoint = &interface->endpoint[i];
+
+		if(interface->bInterfaceClass != 1) 
+	        	continue;
+
+		printk(KERN_INFO "USB audio device detected.\n");
+	
+		switch(interface->bInterfaceSubClass)
+		{
+			case 0x01:
+				printk(KERN_INFO "audio: Control device.\n");
+				break;
+			case 0x02:
+				printk(KERN_INFO "audio: streaming.\n");
+				break;
+			case 0x03:
+				printk(KERN_INFO "audio: nonstreaming.\n");
+				break;
+		}
+		na++;
+	}
+	
+	if(na==0)
+		return -1;
+
+	aud = kmalloc(sizeof(struct usb_audio), GFP_KERNEL);
+	if(aud)
+	{
+        	memset(aud, 0, sizeof(*aud));
+        	aud->dev = dev;
+        	dev->private = aud;
+
+		endpoint = &interface->endpoint[0];
+
+//        	usb_set_configuration(dev, dev->config[0].bConfigurationValue);
+//        	usb_set_protocol(dev, 0);
+//        	usb_set_idle(dev, 0, 0);
+        
+        	usb_request_irq(dev,
+                        usb_rcvctrlpipe(dev, endpoint->bEndpointAddress),
+                        usb_audio_irq,
+                        endpoint->bInterval,
+                        aud);
+
+		list_add(&aud->list, &usb_audio_list);
+	}
+	return 0;
+}
+
+static void usb_audio_disconnect(struct usb_device *dev)
+{
+	struct usb_audio *aud = (struct usb_audio*) dev->private;
+	if(aud)
+	{
+        	dev->private = NULL;
+        	list_del(&aud->list);
+        	kfree(aud);
+	}
+	printk(KERN_INFO "USB audio driver removed.\n");
+}
+
+int usb_audio_init(void)
+{
+	usb_register(&usb_audio_driver);
+	return 0;
+}
+
+/*
+ *	Support functions for parsing
+ */
+ 
+void usb_audio_interface(struct usb_interface_descriptor *interface, u8 *data)
+{
+}
+
+void usb_audio_endpoint(struct usb_endpoint_descriptor *interface, u8 *data)
+{
+}
+
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/hub.c linux/drivers/usb/hub.c
--- v2.2.6/linux/drivers/usb/hub.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/hub.c	Sat Apr 24 17:11:41 1999
@@ -0,0 +1,409 @@
+/*
+ * USB hub driver.
+ *
+ * This is horrible, it knows about the UHCI driver
+ * internals, but it's just meant as a rough example,
+ * let's do the virtualization later when this works.
+ *
+ * (C) Copyright 1999 Linus Torvalds
+ * (C) Copyright 1999 Johannes Erdfelt
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/malloc.h>
+#include <linux/smp_lock.h>
+
+#include <asm/spinlock.h>
+
+#include "usb.h"
+#include "uhci.h"
+#include "hub.h"
+
+extern struct usb_operations uhci_device_operations;
+
+/* Wakes up khubd */
+static struct wait_queue *usb_hub_wait = NULL;
+static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED;
+
+/* List of hubs needing servicing */
+static struct list_head hub_event_list;
+
+/*
+ * A irq handler returns non-zero to indicate to
+ * the low-level driver that it wants to be re-activated,
+ * or zero to say "I'm done".
+ */
+static int hub_irq(int status, void *__buffer, void *dev_id)
+{
+	struct usb_hub *hub = dev_id;
+	unsigned long flags;
+
+	if (waitqueue_active(&usb_hub_wait)) {
+		/* Add the hub to the event queue */
+		spin_lock_irqsave(&hub_event_lock, flags);
+		if (hub->event_list.next == &hub->event_list) {
+			list_add(&hub->event_list, &hub_event_list);
+			/* Wake up khubd */
+			wake_up(&usb_hub_wait);
+		}
+		spin_unlock_irqrestore(&hub_event_lock, flags);
+	}
+
+	return 1;
+}
+
+static void usb_hub_configure(struct usb_hub *hub)
+{
+	struct usb_device *dev = hub->dev;
+	unsigned char hubdescriptor[8], buf[4];
+	int charac, i;
+
+	usb_set_configuration(dev, dev->config[0].bConfigurationValue);
+
+	if (usb_get_hub_descriptor(dev, hubdescriptor, 8))
+		return;
+
+	hub->nports = dev->maxchild = hubdescriptor[2];
+	printk("hub: %d-port%s detected\n", hub->nports,
+		(hub->nports == 1) ? "" : "s");
+
+	charac = (hubdescriptor[4] << 8) + hubdescriptor[3];
+	switch (charac & HUB_CHAR_LPSM) {
+		case 0x00:
+			printk("hub: ganged power switching\n");
+			break;
+		case 0x01:
+			printk("hub: individual port power switching\n");
+			break;
+		case 0x02:
+		case 0x03:
+			printk("hub: unknown reserved power switching mode\n");
+			break;
+	}
+
+	if (charac & HUB_CHAR_COMPOUND)
+		printk("hub: part of a compound device\n");
+	else
+		printk("hub: standalone hub\n");
+
+	switch (charac & HUB_CHAR_OCPM) {
+		case 0x00:
+			printk("hub: global over current protection\n");
+			break;
+		case 0x08:
+			printk("hub: individual port over current protection\n");
+			break;
+		case 0x10:
+		case 0x18:
+			printk("hub: no over current protection\n");
+                        break;
+	}
+
+	printk("hub: power on to power good time: %dms\n",
+		hubdescriptor[5] * 2);
+
+	printk("hub: hub controller current requirement: %dmA\n",
+		hubdescriptor[6]);
+
+	for (i = 0; i < dev->maxchild; i++)
+		printk("hub:  port %d is%s removable\n", i + 1,
+			hubdescriptor[7 + ((i + 1)/8)] & (1 << ((i + 1) % 8))
+			? " not" : "");
+
+	if (usb_get_hub_status(dev, buf))
+		return;
+
+	printk("hub: local power source is %s\n",
+		(buf[0] & 1) ? "lost (inactive)" : "good");
+
+	printk("hub: %sover current condition exists\n",
+		(buf[0] & 2) ? "" : "no ");
+
+#if 0
+	for (i = 0; i < hub->nports; i++) {
+		int portstat, portchange;
+		unsigned char portstatus[4];
+
+		if (usb_get_port_status(dev, i + 1, portstatus))
+			return;
+		portstat = (portstatus[1] << 8) + portstatus[0];
+		portchange = (portstatus[3] << 8) + portstatus[2];
+
+		printk("hub: port %d status\n", i + 1);
+		printk("hub:  %sdevice present\n", (portstat & 1) ? "" : "no ");
+		printk("hub:  %s\n", (portstat & 2) ? "enabled" : "disabled");
+		printk("hub:  %ssuspended\n", (portstat & 4) ? "" : "not ");
+		printk("hub:  %sover current\n", (portstat & 8) ? "" : "not ");
+		printk("hub:  has %spower\n", (portstat & 0x100) ? "" : "no ");
+		printk("hub:  %s speed\n", (portstat & 0x200) ? "low" : "full");
+	}
+#endif
+
+	/* Enable power to the ports */
+	printk("enabling power on all ports\n");
+	for (i = 0; i < hub->nports; i++)
+		usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
+}
+
+static int hub_probe(struct usb_device *dev)
+{
+	struct usb_interface_descriptor *interface;
+	struct usb_endpoint_descriptor *endpoint;
+	struct usb_hub *hub;
+
+	/* We don't handle multi-config hubs */
+	if (dev->descriptor.bNumConfigurations != 1)
+		return -1;
+
+	/* We don't handle multi-interface hubs */
+	if (dev->config[0].bNumInterfaces != 1)
+		return -1;
+
+	interface = &dev->config[0].interface[0];
+
+	/* Is it a hub? */
+	if (interface->bInterfaceClass != 9)
+		return -1;
+	if (interface->bInterfaceSubClass != 0)
+		return -1;
+
+	/* Multiple endpoints? What kind of mutant ninja-hub is this? */
+	if (interface->bNumEndpoints != 1)
+		return -1;
+
+	endpoint = &interface->endpoint[0];
+
+	/* Output endpoint? Curiousier and curiousier.. */
+	if (!(endpoint->bEndpointAddress & 0x80))
+		return -1;
+
+	/* If it's not an interrupt endpoint, we'd better punt! */
+	if ((endpoint->bmAttributes & 3) != 3)
+		return -1;
+
+	/* We found a hub */
+	printk("USB hub found\n");
+
+	if ((hub = kmalloc(sizeof(*hub), GFP_KERNEL)) == NULL) {
+		printk("couldn't kmalloc hub struct\n");
+		return -1;
+	}
+
+	memset(hub, 0, sizeof(*hub));
+
+	dev->private = hub;
+
+	INIT_LIST_HEAD(&hub->event_list);
+	hub->dev = dev;
+
+	usb_hub_configure(hub);
+
+	usb_request_irq(dev, usb_rcvctrlpipe(dev, endpoint->bEndpointAddress), hub_irq, endpoint->bInterval, hub);
+
+	/* Wake up khubd */
+	wake_up(&usb_hub_wait);
+
+	return 0;
+}
+
+static void hub_disconnect(struct usb_device *dev)
+{
+	struct usb_hub *hub = dev->private;
+	unsigned long flags;
+
+	spin_lock_irqsave(&hub_event_lock, flags);
+
+	/* Delete it and then reset it */
+	list_del(&hub->event_list);
+	INIT_LIST_HEAD(&hub->event_list);
+
+	spin_unlock_irqrestore(&hub_event_lock, flags);
+
+	/* Free the memory */
+	kfree(hub);
+}
+
+static void usb_hub_port_connect_change(struct usb_device *hub, int port)
+{
+	struct usb_device *usb;
+	unsigned char buf[4];
+	unsigned short portstatus, portchange;
+
+	usb_disconnect(&hub->children[port]);
+
+	usb_set_port_feature(hub, port + 1, USB_PORT_FEAT_RESET);
+
+	wait_ms(50);	/* FIXME: This is from the *BSD stack, thanks! :) */
+
+	if (usb_get_port_status(hub, port + 1, buf)) {
+		printk("get_port_status failed\n");
+		return;
+	}
+
+	portstatus = *((unsigned short *)buf + 0);
+	portchange = *((unsigned short *)buf + 1);
+
+	if ((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
+		(!(portstatus & USB_PORT_STAT_ENABLE))) {
+		/* We're done now, we already disconnected the device */
+		/* printk("not connected/enabled\n"); */
+		return;
+	}
+
+	usb = hub->bus->op->allocate(hub);
+	if (!usb) {
+		printk("couldn't allocate usb_device\n");
+		return;
+	}
+
+	usb_connect(usb);
+
+	usb->slow = (portstatus & USB_PORT_STAT_LOW_SPEED) ? 1 : 0;
+
+	hub->children[port] = usb;
+
+	usb_new_device(usb);
+}
+
+static void usb_hub_events(void)
+{
+	unsigned long flags;
+	unsigned char buf[4];
+	unsigned short portstatus, portchange;
+	int i;
+	struct list_head *next, *tmp, *head = &hub_event_list;
+	struct usb_device *dev;
+	struct usb_hub *hub;
+
+	spin_lock_irqsave(&hub_event_lock, flags);
+
+	tmp = head->next;
+	while (tmp != head) {
+		hub = list_entry(tmp, struct usb_hub, event_list);
+		dev = hub->dev;
+
+		next = tmp->next;
+
+		list_del(tmp);
+		INIT_LIST_HEAD(tmp);
+
+		for (i = 0; i < hub->nports; i++) {
+			if (usb_get_port_status(dev, i + 1, buf)) {
+				printk("get_port_status failed\n");
+				continue;
+			}
+
+			portstatus = *((unsigned short *)buf + 0);
+			portchange = *((unsigned short *)buf + 1);
+
+			if (portchange & USB_PORT_STAT_C_CONNECTION) {
+				printk("hub: port %d connection change\n", i + 1);
+
+				usb_clear_port_feature(dev, i + 1,
+					USB_PORT_FEAT_C_CONNECTION);
+
+				usb_hub_port_connect_change(dev, i);
+			}
+
+			if (portchange & USB_PORT_STAT_C_ENABLE) {
+				printk("hub: port %d enable change\n", i + 1);
+				usb_clear_port_feature(dev, i + 1,
+					USB_PORT_FEAT_C_ENABLE);
+			}
+
+			if (portchange & USB_PORT_STAT_C_SUSPEND)
+				printk("hub: port %d suspend change\n", i + 1);
+
+			if (portchange & USB_PORT_STAT_C_OVERCURRENT)
+				printk("hub: port %d over-current change\n", i + 1);
+
+			if (portchange & USB_PORT_STAT_C_RESET) {
+				printk("hub: port %d reset change\n", i + 1);
+				usb_clear_port_feature(dev, i + 1,
+					USB_PORT_FEAT_C_RESET);
+			}
+
+#if 0
+			if (!portchange)
+				continue;
+
+			if (usb_get_port_status(dev, i + 1, buf))
+				return;
+
+			portstatus = (buf[1] << 8) + buf[0];
+			portchange = (buf[3] << 8) + buf[2];
+
+			printk("hub: port %d status\n", i + 1);
+			printk("hub:  %sdevice present\n", (portstatus & 1) ? "" : "no ");
+			printk("hub:  %s\n", (portstatus & 2) ? "enabled" : "disabled");
+			printk("hub:  %ssuspended\n", (portstatus & 4) ? "" : "not ");
+			printk("hub:  %sover current\n", (portstatus & 8) ? "" : "not ");
+			printk("hub:  has %spower\n", (portstatus & 0x100) ? "" : "no ");
+			printk("hub:  %s speed\n", (portstatus & 0x200) ? "low" : "full");
+#endif
+		}
+		tmp = next;
+#if 0
+		wait_ms(1000);
+#endif
+        }
+
+	spin_unlock_irqrestore(&hub_event_lock, flags);
+}
+
+static int usb_hub_thread(void *__hub)
+{
+	lock_kernel();
+
+	/*
+	 * This thread doesn't need any user-level access,
+	 * so get rid of all our resources
+	 */
+	printk("usb_hub_thread at %p\n", &usb_hub_thread);
+	exit_mm(current);
+	exit_files(current);
+	exit_fs(current);
+
+	/* Setup a nice name */
+	strcpy(current->comm, "khubd");
+
+	/* Send me a signal to get me die (for debugging) */
+	do {
+		interruptible_sleep_on(&usb_hub_wait);
+		usb_hub_events();
+	} while (!signal_pending(current));
+
+	printk("usb_hub_thread exiting\n");
+
+	return 0;
+}
+
+static struct usb_driver hub_driver = {
+	"hub",
+	hub_probe,
+	hub_disconnect,
+	{ NULL, NULL }
+};
+
+/*
+ * This should be a separate module.
+ */
+int hub_init(void)
+{
+	int pid;
+
+	INIT_LIST_HEAD(&hub_event_list);
+
+	usb_register(&hub_driver);
+	pid = kernel_thread(usb_hub_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+	if (pid >= 0)
+		return 0;
+
+	/* Fall through if kernel_thread failed */
+	usb_deregister(&hub_driver);
+
+	return 0;
+}
+
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/hub.h linux/drivers/usb/hub.h
--- v2.2.6/linux/drivers/usb/hub.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/hub.h	Wed Apr 21 05:41:59 1999
@@ -0,0 +1,80 @@
+#ifndef __LINUX_HUB_H
+#define __LINUX_HUB_H
+
+#include <linux/list.h>
+
+/*
+ * Hub feature numbers
+ */
+#define C_HUB_LOCAL_POWER	0
+#define C_HUB_OVER_CURRENT	1
+
+/*
+ * Port feature numbers
+ */
+#define USB_PORT_FEAT_ENABLE		1
+#define USB_PORT_FEAT_SUSPEND		2
+#define USB_PORT_FEAT_OVER_CURRENT	3
+#define USB_PORT_FEAT_RESET		4
+#define USB_PORT_FEAT_POWER		8
+#define USB_PORT_FEAT_LOWSPEED		9
+#define USB_PORT_FEAT_C_CONNECTION	16
+#define USB_PORT_FEAT_C_ENABLE		17
+#define USB_PORT_FEAT_C_SUSPEND		18
+#define USB_PORT_FEAT_C_OVER_CURRENT	19
+#define USB_PORT_FEAT_C_RESET		20
+
+/* wPortStatus */
+#define USB_PORT_STAT_CONNECTION	0x0001
+#define USB_PORT_STAT_ENABLE		0x0002
+#define USB_PORT_STAT_SUSPEND		0x0004
+#define USB_PORT_STAT_OVERCURRENT	0x0008
+#define USB_PORT_STAT_RESET		0x0010
+#define USB_PORT_STAT_POWER		0x0100
+#define USB_PORT_STAT_LOW_SPEED		0x0200
+
+/* wPortChange */
+#define USB_PORT_STAT_C_CONNECTION	0x0001
+#define USB_PORT_STAT_C_ENABLE		0x0002
+#define USB_PORT_STAT_C_SUSPEND		0x0004
+#define USB_PORT_STAT_C_OVERCURRENT	0x0008
+#define USB_PORT_STAT_C_RESET		0x0010
+
+/* Characteristics */
+#define HUB_CHAR_LPSM		0x0003
+#define HUB_CHAR_COMPOUND	0x0004
+#define HUB_CHAR_OCPM		0x0018
+
+struct usb_device;
+
+typedef enum {
+	USB_PORT_UNPOWERED = 0,		/* Default state */
+	USB_PORT_POWERED,		/* When we've put power to it */
+	USB_PORT_ENABLED,		/* When it's been enabled */
+	USB_PORT_DISABLED,		/* If it's been disabled */
+	USB_PORT_ADMINDISABLED,		/* Forced down */
+} usb_hub_port_state;
+
+struct usb_hub_port {
+	usb_hub_port_state cstate;	/* Configuration state */
+
+	struct usb_device *child;	/* Device attached to this port */
+
+	struct usb_hub *parent;		/* Parent hub */
+};
+
+struct usb_hub {
+	/* Device structure */
+	struct usb_device *dev;
+
+	/* Temporary event list */
+	struct list_head event_list;
+
+	/* Number of ports on the hub */
+	int nports;
+
+	struct usb_hub_port ports[0];	/* Dynamically allocated */
+};
+
+#endif
+
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/inits.h linux/drivers/usb/inits.h
--- v2.2.6/linux/drivers/usb/inits.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/inits.h	Wed Apr 28 11:14:03 1999
@@ -0,0 +1,4 @@
+int bp_mouse_init(void);
+int usb_kbd_init(void);
+int usb_audio_init(void);
+int hub_init(void);
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/keyboard.c linux/drivers/usb/keyboard.c
--- v2.2.6/linux/drivers/usb/keyboard.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/keyboard.c	Mon Apr 26 13:35:01 1999
@@ -0,0 +1,226 @@
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <linux/kbd_ll.h>
+#include "usb.h"
+
+#define PCKBD_PRESSED  0x00
+#define PCKBD_RELEASED 0x80
+#define PCKBD_NEEDS_E0 0x80
+
+#define USBKBD_MODIFIER_BASE  120
+#define USBKBD_KEYCODE_OFFSET 2
+#define USBKBD_KEYCODE_COUNT  6
+
+#define USBKBD_VALID_KEYCODE(key) ((unsigned char)(key) > 3)
+#define USBKBD_FIND_KEYCODE(down, key, count) \
+    ((unsigned char*) memscan((down), (key), (count)) < ((down) + (count)))
+
+#define USBKBD_REPEAT_DELAY (HZ / 4)
+#define USBKBD_REPEAT_RATE (HZ / 20)
+
+struct usb_keyboard
+{
+    struct usb_device *dev;
+    unsigned long down[2];
+    unsigned char repeat_key;
+    struct timer_list repeat_timer;
+    struct list_head list;
+};
+
+extern unsigned char usb_kbd_map[];
+
+static int usb_kbd_probe(struct usb_device *dev);
+static void usb_kbd_disconnect(struct usb_device *dev);
+static void usb_kbd_repeat(unsigned long dummy);
+
+static LIST_HEAD(usb_kbd_list);
+
+static struct usb_driver usb_kbd_driver =
+{
+    "keyboard",
+    usb_kbd_probe,
+    usb_kbd_disconnect,
+    {NULL, NULL}
+};
+
+
+static void
+usb_kbd_handle_key(unsigned char key, int down)
+{
+    int scancode = (int) usb_kbd_map[key];
+    if(scancode)
+    {
+        if(scancode & PCKBD_NEEDS_E0)
+        {
+            handle_scancode(0xe0, 1);
+        }
+        handle_scancode((scancode & ~PCKBD_NEEDS_E0), down);
+    }
+}
+
+static void
+usb_kbd_repeat(unsigned long dev_id)
+{
+    struct usb_keyboard *kbd = (struct usb_keyboard*) dev_id;
+
+    unsigned long flags;
+    save_flags(flags);
+    cli();
+
+    if(kbd->repeat_key)
+    {
+        usb_kbd_handle_key(kbd->repeat_key, 1);
+
+        /* reset repeat timer */
+        kbd->repeat_timer.function = usb_kbd_repeat;
+        kbd->repeat_timer.expires = jiffies + USBKBD_REPEAT_RATE;
+        kbd->repeat_timer.data = (unsigned long) kbd;
+        kbd->repeat_timer.prev = NULL;
+        kbd->repeat_timer.next = NULL;
+        add_timer(&kbd->repeat_timer);
+    }
+
+    restore_flags(flags);
+}
+
+static int
+usb_kbd_irq(int state, void *buffer, void *dev_id)
+{
+    struct usb_keyboard *kbd = (struct usb_keyboard*) dev_id;
+    unsigned long *down = (unsigned long*) buffer;
+
+    if(kbd->down[0] != down[0] || kbd->down[1] != down[1])
+    {
+        unsigned char *olddown, *newdown;
+        unsigned char modsdelta, key;
+        int i;
+
+        /* handle modifier change */
+        modsdelta = (*(unsigned char*) down ^ *(unsigned char*) kbd->down);
+        if(modsdelta)
+        {
+            for(i = 0; i < 8; i++)
+            {
+                if(modsdelta & 0x01)
+                {
+                    int pressed = (*(unsigned char*) down >> i) & 0x01;
+                    usb_kbd_handle_key(
+                        i + USBKBD_MODIFIER_BASE,
+                        pressed);
+                }
+                modsdelta >>= 1;
+            }
+        }
+
+        olddown = (unsigned char*) kbd->down + USBKBD_KEYCODE_OFFSET;
+        newdown = (unsigned char*) down + USBKBD_KEYCODE_OFFSET;
+
+        /* handle released keys */
+        for(i = 0; i < USBKBD_KEYCODE_COUNT; i++)
+        {
+            key = olddown[i];
+            if(USBKBD_VALID_KEYCODE(key)
+               && !USBKBD_FIND_KEYCODE(newdown, key, USBKBD_KEYCODE_COUNT))
+            {
+                usb_kbd_handle_key(key, 0);
+            }
+        }
+
+        /* handle pressed keys */
+        kbd->repeat_key = 0;
+        for(i = 0; i < USBKBD_KEYCODE_COUNT; i++)
+        {
+            key = newdown[i];
+            if(USBKBD_VALID_KEYCODE(key)
+               && !USBKBD_FIND_KEYCODE(olddown, key, USBKBD_KEYCODE_COUNT))
+            {
+                usb_kbd_handle_key(key, 1);
+                kbd->repeat_key = key;
+            }
+        }
+
+        /* set repeat timer if any keys were pressed */
+        if(kbd->repeat_key)
+        {
+            del_timer(&kbd->repeat_timer);
+            kbd->repeat_timer.function = usb_kbd_repeat;
+            kbd->repeat_timer.expires = jiffies + USBKBD_REPEAT_DELAY;
+            kbd->repeat_timer.data = (unsigned long) kbd;
+            kbd->repeat_timer.prev = NULL;
+            kbd->repeat_timer.next = NULL;
+            add_timer(&kbd->repeat_timer);
+        }
+
+        kbd->down[0] = down[0];
+        kbd->down[1] = down[1];
+    }
+
+    return 1;
+}
+
+static int
+usb_kbd_probe(struct usb_device *dev)
+{
+    struct usb_interface_descriptor *interface;
+    struct usb_endpoint_descriptor *endpoint;
+    struct usb_keyboard *kbd;
+
+    interface = &dev->config[0].interface[0];
+    endpoint = &interface->endpoint[0];
+
+    if(interface->bInterfaceClass != 3
+       || interface->bInterfaceSubClass != 1
+       || interface->bInterfaceProtocol != 1)
+    {
+        return -1;
+    }
+
+    printk(KERN_INFO "USB HID boot protocol keyboard detected.\n");
+
+    kbd = kmalloc(sizeof(struct usb_keyboard), GFP_KERNEL);
+    if(kbd)
+    {
+        memset(kbd, 0, sizeof(*kbd));
+        kbd->dev = dev;
+        dev->private = kbd;
+
+        usb_set_configuration(dev, dev->config[0].bConfigurationValue);
+        usb_set_protocol(dev, 0);
+        usb_set_idle(dev, 0, 0);
+        
+        usb_request_irq(dev,
+                        usb_rcvctrlpipe(dev, endpoint->bEndpointAddress),
+                        usb_kbd_irq,
+                        endpoint->bInterval,
+                        kbd);
+
+        list_add(&kbd->list, &usb_kbd_list);
+    }
+
+    return 0;
+}
+
+static void
+usb_kbd_disconnect(struct usb_device *dev)
+{
+    struct usb_keyboard *kbd = (struct usb_keyboard*) dev->private;
+    if(kbd)
+    {
+        dev->private = NULL;
+        list_del(&kbd->list);
+        del_timer(&kbd->repeat_timer);
+        kfree(kbd);
+    }
+
+    printk(KERN_INFO "USB HID boot protocol keyboard removed.\n");
+}
+
+int
+usb_kbd_init(void)
+{
+    usb_register(&usb_kbd_driver);
+    return 0;
+}
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/keymap.c linux/drivers/usb/keymap.c
--- v2.2.6/linux/drivers/usb/keymap.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/keymap.c	Mon Apr 26 12:19:05 1999
@@ -0,0 +1,50 @@
+unsigned char usb_kbd_map[256] = 
+{
+    0x00,  0x00,  0x00,  0x00,  0x1e,  0x30,  0x2e,  0x20,
+    0x12,  0x21,  0x22,  0x23,  0x17,  0x24,  0x25,  0x26,
+
+    0x32,  0x31,  0x18,  0x19,  0x10,  0x13,  0x1f,  0x14,
+    0x16,  0x2f,  0x11,  0x2d,  0x15,  0x2c,  0x02,  0x03,
+
+    0x04,  0x05,  0x06,  0x07,  0x08,  0x09,  0x0a,  0x0b,
+    0x1c,  0x01,  0xd3,  0x0f,  0x39,  0x0c,  0x0d,  0x1a,
+
+    0x1b,  0x2b,  0x00,  0x27,  0x28,  0x29,  0x33,  0x34,
+    0x35,  0x3a,  0x3b,  0x3c,  0x3d,  0x3e,  0x3f,  0x40,
+
+    0x41,  0x42,  0x43,  0x44,  0x57,  0x58,  0xb7,  0x46,
+    0x00,  0xd2,  0xc7,  0xc9,  0x63,  0xcf,  0xd1,  0xcd,
+
+    0xcb,  0xd0,  0xc8,  0x45,  0xb5,  0x37,  0x4a,  0x4e,
+    0x9c,  0x4f,  0x50,  0x51,  0x4b,  0x4c,  0x4d,  0x47,
+
+    0x48,  0x49,  0x52,  0x53,  0x00,  0x6d,  0x00,  0x00,
+    0xbd,  0xbe,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+    0x1d,  0x2a,  0x38,  0xdb,  0x9d,  0x36,  0xb8,  0xdc,
+
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+    0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
+};
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/maps/fixup.map linux/drivers/usb/maps/fixup.map
--- v2.2.6/linux/drivers/usb/maps/fixup.map	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/maps/fixup.map	Fri Apr 16 15:38:24 1999
@@ -0,0 +1,31 @@
+# misc fixes
+keycode   0 = Pause
+keycode  29 = Control
+keycode  99 = Remove
+keycode  42 = Shift
+keycode  54 = Shift_R
+keycode 109 = Application
+
+# E0 keys (or'ed with 0x80)
+keycode 156 = KP_Enter
+keycode 157 = Control_R
+keycode 181 = KP_Divide
+keycode 183 = Print_Screen
+keycode 184 = Alt_R
+keycode 189 = F13
+keycode 190 = F14
+keycode 193 = F17
+keycode 198 = Break
+keycode 199 = Home
+keycode 200 = Up
+keycode 201 = Prior
+keycode 203 = Left
+keycode 205 = Right
+keycode 207 = End
+keycode 208 = Down
+keycode 209 = Next
+keycode 210 = Insert
+keycode 211 = Delete
+keycode 219 = Window
+keycode 220 = Window_R
+keycode 221 = Menu
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/maps/serial.map linux/drivers/usb/maps/serial.map
--- v2.2.6/linux/drivers/usb/maps/serial.map	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/maps/serial.map	Mon Apr 19 11:47:54 1999
@@ -0,0 +1,370 @@
+keymaps 0-2,4-6,8-9,12
+keycode   1 = Escape          
+	alt	keycode   1 = Meta_Escape     
+	shift	alt	keycode   1 = Meta_Escape     
+	control	alt	keycode   1 = Meta_Escape     
+keycode   2 = one              exclam          
+	alt	keycode   2 = Meta_one        
+	shift	alt	keycode   2 = Meta_exclam     
+keycode   3 = two              at               at               nul              nul             
+	alt	keycode   3 = Meta_two        
+	shift	alt	keycode   3 = Meta_at         
+	control	alt	keycode   3 = Meta_nul        
+keycode   4 = three            numbersign      
+	control	keycode   4 = Escape          
+	alt	keycode   4 = Meta_three      
+	shift	alt	keycode   4 = Meta_numbersign 
+keycode   5 = four             dollar           dollar           Control_backslash
+	alt	keycode   5 = Meta_four       
+	shift	alt	keycode   5 = Meta_dollar     
+	control	alt	keycode   5 = Meta_Control_backslash
+keycode   6 = five             percent         
+	control	keycode   6 = Control_bracketright
+	alt	keycode   6 = Meta_five       
+	shift	alt	keycode   6 = Meta_percent    
+keycode   7 = six              asciicircum     
+	control	keycode   7 = Control_asciicircum
+	alt	keycode   7 = Meta_six        
+	shift	alt	keycode   7 = Meta_asciicircum
+keycode   8 = seven            ampersand        braceleft        Control_underscore
+	alt	keycode   8 = Meta_seven      
+	shift	alt	keycode   8 = Meta_ampersand  
+	control	alt	keycode   8 = Meta_Control_underscore
+keycode   9 = eight            asterisk         bracketleft      Delete          
+	alt	keycode   9 = Meta_eight      
+	shift	alt	keycode   9 = Meta_asterisk   
+	control	alt	keycode   9 = Meta_Delete     
+keycode  10 = nine             parenleft        bracketright    
+	alt	keycode  10 = Meta_nine       
+	shift	alt	keycode  10 = Meta_parenleft  
+keycode  11 = zero             parenright       braceright      
+	alt	keycode  11 = Meta_zero       
+	shift	alt	keycode  11 = Meta_parenright 
+keycode  12 = minus            underscore       backslash        Control_underscore Control_underscore
+	alt	keycode  12 = Meta_minus      
+	shift	alt	keycode  12 = Meta_underscore 
+	control	alt	keycode  12 = Meta_Control_underscore
+keycode  13 = equal            plus            
+	alt	keycode  13 = Meta_equal      
+	shift	alt	keycode  13 = Meta_plus       
+keycode  14 = Delete          
+	alt	keycode  14 = Meta_Delete     
+	shift	alt	keycode  14 = Meta_Delete     
+	control	alt	keycode  14 = Meta_Delete     
+keycode  15 = Tab             
+	alt	keycode  15 = Meta_Tab        
+	shift	alt	keycode  15 = Meta_Tab        
+	control	alt	keycode  15 = Meta_Tab        
+keycode  16 = q               
+keycode  17 = w               
+keycode  18 = e               
+keycode  19 = r               
+keycode  20 = t               
+keycode  21 = y               
+keycode  22 = u               
+keycode  23 = i               
+keycode  24 = o               
+keycode  25 = p               
+keycode  26 = bracketleft      braceleft       
+	control	keycode  26 = Escape          
+	alt	keycode  26 = Meta_bracketleft
+	shift	alt	keycode  26 = Meta_braceleft  
+keycode  27 = bracketright     braceright       asciitilde       Control_bracketright
+	alt	keycode  27 = Meta_bracketright
+	shift	alt	keycode  27 = Meta_braceright 
+	control	alt	keycode  27 = Meta_Control_bracketright
+keycode  28 = Return          
+	alt	keycode  28 = Meta_Control_m  
+keycode  29 = Control         
+keycode  30 = a               
+keycode  31 = s               
+keycode  32 = d               
+keycode  33 = f               
+keycode  34 = g               
+keycode  35 = h               
+keycode  36 = j               
+keycode  37 = k               
+keycode  38 = l               
+keycode  39 = semicolon        colon           
+	alt	keycode  39 = Meta_semicolon  
+	shift	alt	keycode  39 = Meta_colon      
+keycode  40 = apostrophe       quotedbl        
+	control	keycode  40 = Control_g       
+	alt	keycode  40 = Meta_apostrophe 
+	shift	alt	keycode  40 = Meta_quotedbl   
+keycode  41 = grave            asciitilde      
+	control	keycode  41 = nul             
+	alt	keycode  41 = Meta_grave      
+	shift	alt	keycode  41 = Meta_asciitilde 
+keycode  42 = Shift           
+keycode  43 = backslash        bar             
+	control	keycode  43 = Control_backslash
+	alt	keycode  43 = Meta_backslash  
+	shift	alt	keycode  43 = Meta_bar        
+keycode  44 = z               
+keycode  45 = x               
+keycode  46 = c               
+keycode  47 = v               
+keycode  48 = b               
+keycode  49 = n               
+keycode  50 = m               
+keycode  51 = comma            less            
+	alt	keycode  51 = Meta_comma      
+	shift	alt	keycode  51 = Meta_less       
+keycode  52 = period           greater         
+	alt	keycode  52 = Meta_period     
+	shift	alt	keycode  52 = Meta_greater    
+keycode  53 = slash            question        
+	control	keycode  53 = Delete          
+	alt	keycode  53 = Meta_slash      
+	shift	alt	keycode  53 = Meta_question   
+keycode  54 = Shift           
+keycode  55 = KP_Multiply     
+	altgr	keycode  55 = Hex_C           
+keycode  56 = Alt             
+keycode  57 = space           
+	control	keycode  57 = nul             
+	alt	keycode  57 = Meta_space      
+	shift	alt	keycode  57 = Meta_space      
+	control	alt	keycode  57 = Meta_nul        
+keycode  58 = Caps_Lock       
+keycode  59 = F1               F13              Console_13       F25             
+	alt	keycode  59 = Console_1       
+	control	alt	keycode  59 = Console_1       
+keycode  60 = F2               F14              Console_14       F26             
+	alt	keycode  60 = Console_2       
+	control	alt	keycode  60 = Console_2       
+keycode  61 = F3               F15              Console_15       F27             
+	alt	keycode  61 = Console_3       
+	control	alt	keycode  61 = Console_3       
+keycode  62 = F4               F16              Console_16       F28             
+	alt	keycode  62 = Console_4       
+	control	alt	keycode  62 = Console_4       
+keycode  63 = F5               F17              Console_17       F29             
+	alt	keycode  63 = Console_5       
+	control	alt	keycode  63 = Console_5       
+keycode  64 = F6               F18              Console_18       F30             
+	alt	keycode  64 = Console_6       
+	control	alt	keycode  64 = Console_6       
+keycode  65 = F7               F19              Console_19       F31             
+	alt	keycode  65 = Console_7       
+	control	alt	keycode  65 = Console_7       
+keycode  66 = F8               F20              Console_20       F32             
+	alt	keycode  66 = Console_8       
+	control	alt	keycode  66 = Console_8       
+keycode  67 = F9               F21              Console_21       F33             
+	alt	keycode  67 = Console_9       
+	control	alt	keycode  67 = Console_9       
+keycode  68 = F10              F22              Console_22       F34             
+	alt	keycode  68 = Console_10      
+	control	alt	keycode  68 = Console_10      
+keycode  69 = Num_Lock        
+	altgr	keycode  69 = Hex_E           
+keycode  70 = Scroll_Lock      Show_Memory      Show_Registers   Show_State      
+	alt	keycode  70 = Scroll_Lock     
+keycode  71 = KP_7            
+	altgr	keycode  71 = Hex_7           
+	alt	keycode  71 = Ascii_7         
+keycode  72 = KP_8            
+	altgr	keycode  72 = Hex_8           
+	alt	keycode  72 = Ascii_8         
+keycode  73 = KP_9            
+	altgr	keycode  73 = Hex_9           
+	alt	keycode  73 = Ascii_9         
+keycode  74 = KP_Subtract     
+keycode  75 = KP_4            
+	altgr	keycode  75 = Hex_4           
+	alt	keycode  75 = Ascii_4         
+keycode  76 = KP_5            
+	altgr	keycode  76 = Hex_5           
+	alt	keycode  76 = Ascii_5         
+keycode  77 = KP_6            
+	altgr	keycode  77 = Hex_6           
+	alt	keycode  77 = Ascii_6         
+keycode  78 = KP_Add          
+keycode  79 = KP_1            
+	altgr	keycode  79 = Hex_1           
+	alt	keycode  79 = Ascii_1         
+keycode  80 = KP_2            
+	altgr	keycode  80 = Hex_2           
+	alt	keycode  80 = Ascii_2         
+keycode  81 = KP_3            
+	altgr	keycode  81 = Hex_3           
+	alt	keycode  81 = Ascii_3         
+keycode  82 = KP_0            
+	altgr	keycode  82 = Hex_0           
+	alt	keycode  82 = Ascii_0         
+keycode  83 = KP_Period       
+	altgr	control	keycode  83 = Boot            
+	control	alt	keycode  83 = Boot            
+keycode  84 = Last_Console    
+keycode  85 =
+keycode  86 = less             greater          bar             
+	alt	keycode  86 = Meta_less       
+	shift	alt	keycode  86 = Meta_greater    
+keycode  87 = F11              F23              Console_23       F35             
+	alt	keycode  87 = Console_11      
+	control	alt	keycode  87 = Console_11      
+keycode  88 = F12              F24              Console_24       F36             
+	alt	keycode  88 = Console_12      
+	control	alt	keycode  88 = Console_12      
+keycode  89 =
+keycode  90 =
+keycode  91 =
+keycode  92 =
+keycode  93 =
+keycode  94 =
+keycode  95 =
+keycode  96 = KP_Enter        
+keycode  97 = Control         
+keycode  98 = KP_Divide       
+	altgr	keycode  98 = Hex_B           
+keycode  99 = Control_backslash
+	alt	keycode  99 = Meta_Control_backslash
+	shift	alt	keycode  99 = Meta_Control_backslash
+	control	alt	keycode  99 = Meta_Control_backslash
+keycode 100 = AltGr           
+keycode 101 = Break           
+keycode 102 = Find            
+keycode 103 = Up              
+	alt	keycode 103 = KeyboardSignal  
+keycode 104 = Prior           
+	shift	keycode 104 = Scroll_Backward 
+keycode 105 = Left            
+	alt	keycode 105 = Decr_Console    
+keycode 106 = Right           
+	alt	keycode 106 = Incr_Console    
+keycode 107 = Select          
+keycode 108 = Down            
+keycode 109 = Next            
+	shift	keycode 109 = Scroll_Forward  
+keycode 110 = Insert          
+keycode 111 = Remove          
+	altgr	control	keycode 111 = Boot            
+	control	alt	keycode 111 = Boot            
+keycode 112 = Macro           
+	altgr	control	keycode 112 = VoidSymbol      
+	shift	alt	keycode 112 = VoidSymbol      
+keycode 113 = F13             
+	altgr	control	keycode 113 = VoidSymbol      
+	shift	alt	keycode 113 = VoidSymbol      
+keycode 114 = F14             
+	altgr	control	keycode 114 = VoidSymbol      
+	shift	alt	keycode 114 = VoidSymbol      
+keycode 115 = Help            
+	altgr	control	keycode 115 = VoidSymbol      
+	shift	alt	keycode 115 = VoidSymbol      
+keycode 116 = Do              
+	altgr	control	keycode 116 = VoidSymbol      
+	shift	alt	keycode 116 = VoidSymbol      
+keycode 117 = F17             
+	altgr	control	keycode 117 = VoidSymbol      
+	shift	alt	keycode 117 = VoidSymbol      
+keycode 118 = KP_MinPlus      
+	altgr	control	keycode 118 = VoidSymbol      
+	shift	alt	keycode 118 = VoidSymbol      
+keycode 119 = Pause           
+keycode 120 =
+keycode 121 =
+keycode 122 =
+keycode 123 =
+keycode 124 =
+keycode 125 =
+keycode 126 =
+keycode 127 =
+string F1 = "\033[[A"
+string F2 = "\033[[B"
+string F3 = "\033[[C"
+string F4 = "\033[[D"
+string F5 = "\033[[E"
+string F6 = "\033[17~"
+string F7 = "\033[18~"
+string F8 = "\033[19~"
+string F9 = "\033[20~"
+string F10 = "\033[21~"
+string F11 = "\033[23~"
+string F12 = "\033[24~"
+string F13 = "\033[25~"
+string F14 = "\033[26~"
+string F15 = "\033[28~"
+string F16 = "\033[29~"
+string F17 = "\033[31~"
+string F18 = "\033[32~"
+string F19 = "\033[33~"
+string F20 = "\033[34~"
+string Find = "\033[1~"
+string Insert = "\033[2~"
+string Remove = "\033[3~"
+string Select = "\033[4~"
+string Prior = "\033[5~"
+string Next = "\033[6~"
+string Macro = "\033[M"
+string Pause = "\033[P"
+compose '`' 'A' to 'À'
+compose '`' 'a' to 'à'
+compose '\'' 'A' to 'Á'
+compose '\'' 'a' to 'á'
+compose '^' 'A' to 'Â'
+compose '^' 'a' to 'â'
+compose '~' 'A' to 'Ã'
+compose '~' 'a' to 'ã'
+compose '"' 'A' to 'Ä'
+compose '"' 'a' to 'ä'
+compose 'O' 'A' to 'Å'
+compose 'o' 'a' to 'å'
+compose '0' 'A' to 'Å'
+compose '0' 'a' to 'å'
+compose 'A' 'A' to 'Å'
+compose 'a' 'a' to 'å'
+compose 'A' 'E' to 'Æ'
+compose 'a' 'e' to 'æ'
+compose ',' 'C' to 'Ç'
+compose ',' 'c' to 'ç'
+compose '`' 'E' to 'È'
+compose '`' 'e' to 'è'
+compose '\'' 'E' to 'É'
+compose '\'' 'e' to 'é'
+compose '^' 'E' to 'Ê'
+compose '^' 'e' to 'ê'
+compose '"' 'E' to 'Ë'
+compose '"' 'e' to 'ë'
+compose '`' 'I' to 'Ì'
+compose '`' 'i' to 'ì'
+compose '\'' 'I' to 'Í'
+compose '\'' 'i' to 'í'
+compose '^' 'I' to 'Î'
+compose '^' 'i' to 'î'
+compose '"' 'I' to 'Ï'
+compose '"' 'i' to 'ï'
+compose '-' 'D' to 'Ð'
+compose '-' 'd' to 'ð'
+compose '~' 'N' to 'Ñ'
+compose '~' 'n' to 'ñ'
+compose '`' 'O' to 'Ò'
+compose '`' 'o' to 'ò'
+compose '\'' 'O' to 'Ó'
+compose '\'' 'o' to 'ó'
+compose '^' 'O' to 'Ô'
+compose '^' 'o' to 'ô'
+compose '~' 'O' to 'Õ'
+compose '~' 'o' to 'õ'
+compose '"' 'O' to 'Ö'
+compose '"' 'o' to 'ö'
+compose '/' 'O' to 'Ø'
+compose '/' 'o' to 'ø'
+compose '`' 'U' to 'Ù'
+compose '`' 'u' to 'ù'
+compose '\'' 'U' to 'Ú'
+compose '\'' 'u' to 'ú'
+compose '^' 'U' to 'Û'
+compose '^' 'u' to 'û'
+compose '"' 'U' to 'Ü'
+compose '"' 'u' to 'ü'
+compose '\'' 'Y' to 'Ý'
+compose '\'' 'y' to 'ý'
+compose 'T' 'H' to 'Þ'
+compose 't' 'h' to 'þ'
+compose 's' 's' to 'ß'
+compose '"' 'y' to 'ÿ'
+compose 's' 'z' to 'ß'
+compose 'i' 'j' to 'ÿ'
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/maps/usb.map linux/drivers/usb/maps/usb.map
--- v2.2.6/linux/drivers/usb/maps/usb.map	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/maps/usb.map	Fri Apr 16 15:38:24 1999
@@ -0,0 +1,233 @@
+# USB kernel keymap.
+keymaps 0-2,4-5,8,12
+
+keycode   4 = a
+	altgr   keycode  30 = Hex_A
+keycode   5 = b
+	altgr   keycode  48 = Hex_B
+keycode   6 = c
+	altgr   keycode  46 = Hex_C   
+keycode   7 = d
+	altgr   keycode  32 = Hex_D   
+keycode   8 = e
+	altgr   keycode  18 = Hex_E   
+keycode   9 = f
+	altgr   keycode  33 = Hex_F               
+keycode  10 = g               
+keycode  11 = h               
+keycode  12 = i               
+keycode  13 = j               
+keycode  14 = k               
+keycode  15 = l               
+keycode  16 = m               
+keycode  17 = n               
+keycode  18 = o               
+keycode  19 = p               
+keycode  20 = q               
+keycode  21 = r               
+keycode  22 = s               
+keycode  23 = t               
+keycode  24 = u               
+keycode  25 = v               
+keycode  26 = w               
+keycode  27 = x               
+keycode  28 = y               
+keycode  29 = z               
+keycode  30 = one              exclam          
+	alt     keycode   2 = Meta_one        
+keycode  31 = two              at
+	control	keycode   3 = nul             
+	shift	control	keycode   3 = nul             
+	alt	keycode   3 = Meta_two        
+keycode  32 = three            numbersign      
+	control keycode   4 = Escape          
+	alt     keycode   4 = Meta_three      
+keycode  33 = four             dollar
+	control keycode   5 = Control_backslash
+	alt     keycode   5 = Meta_four       
+keycode  34 = five             percent         
+	control keycode   6 = Control_bracketright
+	alt     keycode   6 = Meta_five       
+keycode  35 = six              asciicircum     
+	control keycode   7 = Control_asciicircum
+	alt     keycode   7 = Meta_six        
+keycode  36 = seven            ampersand
+	control keycode   8 = Control_underscore
+	alt     keycode   8 = Meta_seven      
+keycode  37 = eight            asterisk
+	control keycode   9 = Delete          
+	alt     keycode   9 = Meta_eight      
+keycode  38 = nine             parenleft
+	alt     keycode  10 = Meta_nine       
+keycode  39 = zero             parenright
+	alt     keycode  11 = Meta_zero       
+keycode  40 = Return          
+	alt     keycode  28 = Meta_Control_m  
+keycode  41 = Escape           Escape          
+	alt     keycode   1 = Meta_Escape     
+keycode  42 = Delete           Delete          
+	control keycode  14 = BackSpace
+	alt     keycode  14 = Meta_Delete     
+keycode  43 = Tab              Tab             
+	alt     keycode  15 = Meta_Tab        
+keycode  44 = space            space           
+	control keycode  57 = nul             
+	alt     keycode  57 = Meta_space      
+keycode  45 = minus            underscore       backslash       
+	control	keycode  12 = Control_underscore
+	shift	control	keycode  12 = Control_underscore
+	alt	keycode  12 = Meta_minus      
+keycode  46 = equal            plus            
+	alt     keycode  13 = Meta_equal      
+keycode  47 = bracketleft      braceleft       
+	control keycode  26 = Escape          
+	alt     keycode  26 = Meta_bracketleft
+keycode  48 = bracketright     braceright       asciitilde      
+	control keycode  27 = Control_bracketright
+	alt     keycode  27 = Meta_bracketright
+keycode  49 = backslash        bar             
+	control keycode  43 = Control_backslash
+	alt     keycode  43 = Meta_backslash  
+keycode 50 =
+keycode  51 = semicolon        colon           
+	alt     keycode  39 = Meta_semicolon  
+keycode  52 = apostrophe       quotedbl        
+	control keycode  40 = Control_g       
+	alt     keycode  40 = Meta_apostrophe 
+keycode  53 = grave            asciitilde      
+	control keycode  41 = nul             
+	alt     keycode  41 = Meta_grave      
+keycode  54 = comma            less            
+	alt     keycode  51 = Meta_comma      
+keycode  55 = period           greater         
+	control keycode  52 = Compose         
+	alt     keycode  52 = Meta_period     
+keycode  56 = slash            question        
+	control keycode  53 = Delete          
+	alt     keycode  53 = Meta_slash      
+keycode  57 = Caps_Lock       
+keycode  58 = F1               F11              Console_13      
+	control keycode  59 = F1              
+	alt     keycode  59 = Console_1       
+	control alt     keycode  59 = Console_1       
+keycode  59 = F2               F12              Console_14      
+	control keycode  60 = F2              
+	alt     keycode  60 = Console_2       
+	control alt     keycode  60 = Console_2       
+keycode  60 = F3               F13              Console_15      
+	control keycode  61 = F3              
+	alt     keycode  61 = Console_3       
+	control alt     keycode  61 = Console_3       
+keycode  61 = F4               F14              Console_16      
+	control keycode  62 = F4              
+	alt     keycode  62 = Console_4       
+	control alt     keycode  62 = Console_4       
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 11'
echo 'File patch-2.2.7 is continued in part 12'
echo 12 > _shar_seq_.tmp
#!/bin/sh
# this is part 12 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 12; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
+keycode  62 = F5               F15              Console_17      
+	control keycode  63 = F5              
+	alt     keycode  63 = Console_5       
+	control alt     keycode  63 = Console_5       
+keycode  63 = F6               F16              Console_18      
+	control keycode  64 = F6              
+	alt     keycode  64 = Console_6       
+	control alt     keycode  64 = Console_6       
+keycode  64 = F7               F17              Console_19      
+	control keycode  65 = F7              
+	alt     keycode  65 = Console_7       
+	control alt     keycode  65 = Console_7       
+keycode  65 = F8               F18              Console_20      
+	control keycode  66 = F8              
+	alt     keycode  66 = Console_8       
+	control alt     keycode  66 = Console_8       
+keycode  66 = F9               F19              Console_21      
+	control keycode  67 = F9              
+	alt     keycode  67 = Console_9       
+	control alt     keycode  67 = Console_9       
+keycode  67 = F10              F20              Console_22      
+	control keycode  68 = F10             
+	alt     keycode  68 = Console_10      
+	control alt     keycode  68 = Console_10      
+keycode  68 = F11              F11              Console_23      
+	control keycode  87 = F11             
+	alt     keycode  87 = Console_11      
+	control alt     keycode  87 = Console_11      
+keycode  69 = F12              F12              Console_24      
+	control keycode  88 = F12             
+	alt     keycode  88 = Console_12      
+	control alt     keycode  88 = Console_12      
+keycode  70 = Print_Screen
+keycode  71 = Scroll_Lock      Show_Memory      Show_Registers  
+	control keycode  70 = Show_State      
+	alt     keycode  70 = Scroll_Lock     
+keycode  72 = Pause           
+keycode  73 = Insert          
+keycode  74 = Home
+keycode  75 = Prior           
+	shift   keycode 104 = Scroll_Backward 
+keycode  76 = Remove          
+#	altgr   control keycode 111 = Boot            
+	control alt     keycode 111 = Boot            
+keycode  77 = End
+keycode  78 = Next            
+	shift   keycode 109 = Scroll_Forward  
+keycode  79 = Right           
+	alt     keycode 106 = Incr_Console
+keycode  80 = Left            
+	alt     keycode 105 = Decr_Console
+keycode  81 = Down            
+keycode  82 = Up              
+keycode  83 = Num_Lock
+	shift   keycode  69 = Bare_Num_Lock
+keycode  84 = KP_Divide       
+keycode  85 = KP_Multiply     
+keycode  86 = KP_Subtract     
+keycode  87 = KP_Add          
+keycode  88 = KP_Enter        
+keycode  89 = KP_1            
+	alt     keycode  79 = Ascii_1         
+	altgr   keycode  79 = Hex_1         
+keycode  90 = KP_2            
+	alt     keycode  80 = Ascii_2         
+	altgr   keycode  80 = Hex_2         
+keycode  91 = KP_3            
+	alt     keycode  81 = Ascii_3         
+	altgr   keycode  81 = Hex_3         
+keycode  92 = KP_4            
+	alt     keycode  75 = Ascii_4         
+	altgr   keycode  75 = Hex_4         
+keycode  93 = KP_5            
+	alt     keycode  76 = Ascii_5         
+	altgr   keycode  76 = Hex_5         
+keycode  94 = KP_6            
+	alt     keycode  77 = Ascii_6         
+	altgr   keycode  77 = Hex_6         
+keycode  95 = KP_7            
+	alt     keycode  71 = Ascii_7         
+	altgr   keycode  71 = Hex_7         
+keycode  96 = KP_8            
+	alt     keycode  72 = Ascii_8         
+	altgr   keycode  72 = Hex_8         
+keycode  97 = KP_9            
+	alt     keycode  73 = Ascii_9         
+	altgr   keycode  73 = Hex_9         
+keycode  98 = KP_0            
+	alt     keycode  82 = Ascii_0         
+	altgr   keycode  82 = Hex_0         
+keycode  99 = KP_Period       
+#	altgr   control keycode  83 = Boot            
+	control alt     keycode  83 = Boot            
+keycode 100 =
+keycode 101 = Application
+keycode 102 =
+keycode 103 =
+keycode 104 = F13             
+keycode 105 = F14             
+
+# modifiers
+keycode 120 = Control
+keycode 121 = Shift
+keycode 122 = Alt
+keycode 123 = Window
+keycode 124 = Control_R
+keycode 125 = Shift_R
+keycode 126 = Alt_R
+keycode 127 = Window_R
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/mkmap linux/drivers/usb/mkmap
--- v2.2.6/linux/drivers/usb/mkmap	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/mkmap	Mon Apr 19 11:53:27 1999
@@ -0,0 +1,83 @@
+#!/usr/bin/perl
+
+($ME = $0) =~ s|.*/||;
+
+$file = "maps/serial.map";
+$line = 1;
+open(PC, $file) || die("$!");
+while(<PC>)
+{
+    if(/^\s*keycode\s+(\d+)\s*=\s*(\S+)/)
+    {
+	my($idx) = int($1);
+	my($sym) = $2;
+	if(defined($map{uc($sym)}))
+	{
+	    # print STDERR "$file:$line: warning: `$sym' redefined\n";
+	}
+	$map{uc($sym)} = $idx;
+    }
+    $line++;
+}
+close(PC);
+
+$file = "maps/fixup.map";
+$line = 1;
+open(FIXUP, $file) || die("$!");
+while(<FIXUP>)
+{
+    if(/^\s*keycode\s+(\d+)\s*=\s*/)
+    {
+	my($idx) = int($1);
+	for $sym (split(/\s+/, $'))
+        {
+	    $map{uc($sym)} = $idx;
+	}
+    }
+    $line++;
+}
+close(FIXUP);
+
+$file = "maps/usb.map";
+$line = 1;
+open(USB, $file) || die("$!");
+while(<USB>)
+{
+    if(/^\s*keycode\s+(\d+)\s*=\s*/)
+    {
+	my($idx) = int($1);
+	for $sym (split(/\s+/, $'))
+        {
+	    my($val) = $map{uc($sym)};
+	    $map[$idx] = $val;
+	    if(!defined($val))
+	    {
+		print STDERR "$file:$line: warning: `$sym' undefined\n";
+	    }
+	    else
+	    {
+		last;
+	    }
+	}
+    }
+    $line++;
+}
+close(USB);
+
+print "unsigned char usb_kbd_map[256] = \n{\n";
+for($x = 0; $x < 32; $x++)
+{
+    if($x && !($x % 2))
+    {
+	print "\n";
+    }
+    print "  ";
+    for($y = 0; $y < 8; $y++)
+    {
+	my($idx) = $x * 8 + $y;
+	print sprintf("  0x%02x,",
+		      int(defined($map[$idx]) ? $map[$idx]:0));
+    }
+    print "\n";
+}
+print "};\n";
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/mouse.c linux/drivers/usb/mouse.c
--- v2.2.6/linux/drivers/usb/mouse.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/mouse.c	Sat Apr 24 17:11:41 1999
@@ -0,0 +1,299 @@
+/*
+ * USB HID boot protocol mouse support based on MS BusMouse driver, psaux 
+ * driver, and Linus's skeleton USB mouse driver
+ *
+ * Brad Keryan 4/3/1999
+ *
+ * version 0.02: Hmm, the mouse seems drunk because I'm queueing the events.
+ * This is wrong: when an application (like X or gpm) reads the mouse device,
+ * it wants to find out the mouse's current position, not its recent history.
+ * The button thing turned out to be UHCI not flipping data toggle, so half the
+ * packets were thrown out.
+ *
+ * version 0.01: Switched over to busmouse protocol, and changed the minor
+ * number to 32 (same as uusbd's hidbp driver). Buttons work more sanely now, 
+ * but it still doesn't generate button events unless you move the mouse.
+ *
+ * version 0.0: Driver emulates a PS/2 mouse, stealing /dev/psaux (sorry, I 
+ * know that's not very nice). Moving in the X and Y axes works. Buttons don't
+ * work right yet: X sees a lot of MotionNotify/ButtonPress/ButtonRelease 
+ * combos when you hold down a button and drag the mouse around. Probably has 
+ * some additional bugs on an SMP machine.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/random.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/malloc.h>
+
+#include <asm/spinlock.h>
+
+#include "usb.h"
+
+#define USB_MOUSE_MINOR 32
+
+struct mouse_state {
+	unsigned char buttons; /* current button state */
+	long dx; /* dx, dy, dz are change since last read */
+	long dy; 
+	long dz;
+	int present; /* this mouse is plugged in */
+	int active; /* someone is has this mouse's device open */
+	int ready; /* the mouse has changed state since the last read */
+	struct wait_queue *wait; /* for polling */
+	struct fasync_struct *fasync;
+	/* later, add a list here to support multiple mice */
+	/* but we will also need a list of file pointers to identify it */
+};
+
+static struct mouse_state static_mouse_state;
+
+spinlock_t usb_mouse_lock = SPIN_LOCK_UNLOCKED;
+
+static int mouse_irq(int state, void *__buffer, void *dev_id)
+{
+	signed char *data = __buffer;
+	/* finding the mouse is easy when there's only one */
+	struct mouse_state *mouse = &static_mouse_state; 
+
+	/* if a mouse moves with no one listening, do we care? no */
+	if(!mouse->active)
+		return 1;
+
+	/* if the USB mouse sends an interrupt, then something noteworthy
+	   must have happened */
+	mouse->buttons = data[0] & 0x07;
+	mouse->dx += data[1]; /* data[] is signed, so this works */
+	mouse->dy -= data[2]; /* y-axis is reversed */
+	mouse->dz += data[3];
+	mouse->ready = 1;
+
+	add_mouse_randomness((mouse->buttons << 24) + (mouse->dz << 16 ) + 
+				     (mouse->dy << 8) + mouse->dx);
+
+	wake_up_interruptible(&mouse->wait);
+	if (mouse->fasync)
+		kill_fasync(mouse->fasync, SIGIO);
+
+	return 1;
+}
+
+static int fasync_mouse(int fd, struct file *filp, int on)
+{
+	int retval;
+	struct mouse_state *mouse = &static_mouse_state;
+
+	retval = fasync_helper(fd, filp, on, &mouse->fasync);
+	if (retval < 0)
+		return retval;
+	return 0;
+}
+
+static int release_mouse(struct inode * inode, struct file * file)
+{
+	struct mouse_state *mouse = &static_mouse_state;
+
+	fasync_mouse(-1, file, 0);
+	if (--mouse->active)
+		return 0;
+	return 0;
+}
+
+static int open_mouse(struct inode * inode, struct file * file)
+{
+	struct mouse_state *mouse = &static_mouse_state;
+
+	if (!mouse->present)
+		return -EINVAL;
+	if (mouse->active++)
+		return 0;
+	/* flush state */
+	mouse->buttons = mouse->dx = mouse->dy = mouse->dz = 0;
+	return 0;
+}
+
+static ssize_t write_mouse(struct file * file,
+       const char * buffer, size_t count, loff_t *ppos)
+{
+	return -EINVAL;
+}
+
+/*
+ * Look like a PS/2 mouse, please..
+ *
+ * The PS/2 protocol is fairly strange, but
+ * oh, well, it's at least common..
+ */
+static ssize_t read_mouse(struct file * file, char * buffer, size_t count, loff_t *ppos)
+{
+	int retval = 0;
+	static int state = 0;
+	struct mouse_state *mouse = &static_mouse_state;
+
+	if (count) {
+		mouse->ready = 0;
+		switch (state) {
+		case 0: { /* buttons and sign */
+			int buttons = mouse->buttons;
+			mouse->buttons = 0;
+			if (mouse->dx < 0)
+				buttons |= 0x10;
+			if (mouse->dy < 0)
+				buttons |= 0x20;
+			put_user(buttons, buffer);
+			buffer++;
+			retval++;
+			state = 1;
+			if (!--count)
+				break;
+		}
+		case 1: { /* dx */
+			int dx = mouse->dx;
+			mouse->dx = 0;
+			put_user(dx, buffer);
+			buffer++;
+			retval++;
+			state = 2;
+			if (!--count)
+				break;
+		}
+		case 2:	{ /* dy */
+			int dy = mouse->dy;
+			mouse->dy = 0;
+			put_user(dy, buffer);
+			buffer++;
+			retval++;
+			state = 0;
+		}
+		break;
+		}
+	}
+	return retval;
+}
+
+static unsigned int mouse_poll(struct file *file, poll_table * wait)
+{
+	struct mouse_state *mouse = &static_mouse_state;
+
+	poll_wait(file, &mouse->wait, wait);
+	if (mouse->ready)
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+struct file_operations usb_mouse_fops = {
+	NULL,		/* mouse_seek */
+	read_mouse,
+	write_mouse,
+	NULL, 		/* mouse_readdir */
+	mouse_poll, 	/* mouse_poll */
+	NULL, 		/* mouse_ioctl */
+	NULL,		/* mouse_mmap */
+	open_mouse,
+	NULL,		/* flush */
+	release_mouse,
+	NULL,
+	fasync_mouse,
+};
+
+static struct miscdevice usb_mouse = {
+	USB_MOUSE_MINOR, "USB mouse", &usb_mouse_fops
+};
+
+static int mouse_probe(struct usb_device *dev)
+{
+	struct usb_interface_descriptor *interface;
+	struct usb_endpoint_descriptor *endpoint;
+	struct mouse_state *mouse = &static_mouse_state;
+
+	/* We don't handle multi-config mice */
+	if (dev->descriptor.bNumConfigurations != 1)
+		return -1;
+
+ /* We don't handle multi-interface mice */
+	if (dev->config[0].bNumInterfaces != 1)
+		return -1;
+
+ /* Is it a mouse interface? */
+	interface = &dev->config[0].interface[0];
+	if (interface->bInterfaceClass != 3)
+		return -1;
+	if (interface->bInterfaceSubClass != 1)
+		return -1;
+	if (interface->bInterfaceProtocol != 2)
+		return -1;
+
+	/* Multiple endpoints? What kind of mutant ninja-mouse is this? */
+	if (interface->bNumEndpoints != 1)
+		return -1;
+
+	endpoint = &interface->endpoint[0];
+
+	/* Output endpoint? Curiousier and curiousier.. */
+	if (!(endpoint->bEndpointAddress & 0x80))
+		return -1;
+
+	/* If it's not an interrupt endpoint, we'd better punt! */
+	if ((endpoint->bmAttributes & 3) != 3)
+		return -1;
+
+	printk("USB mouse found\n");
+
+	usb_set_configuration(dev, dev->config[0].bConfigurationValue);
+
+	usb_request_irq(dev, usb_rcvctrlpipe(dev, endpoint->bEndpointAddress), mouse_irq, endpoint->bInterval, NULL);
+
+	mouse->present = 1;
+	return 0;
+}
+
+static void mouse_disconnect(struct usb_device *dev)
+{
+	struct mouse_state *mouse = &static_mouse_state;
+
+	/* this might need work */
+	mouse->present = 0;
+}
+
+static struct usb_driver mouse_driver = {
+	"mouse",
+	mouse_probe,
+	mouse_disconnect,
+	{ NULL, NULL }
+};
+
+int usb_mouse_init(void)
+{
+	struct mouse_state *mouse = &static_mouse_state;
+
+	misc_register(&usb_mouse);
+
+	mouse->present = mouse->active = 0;
+	mouse->wait = NULL;
+	mouse->fasync = NULL;
+
+	usb_register(&mouse_driver);
+	printk(KERN_INFO "USB HID boot protocol mouse registered.\n");
+	return 0;
+}
+
+#if 0
+
+int init_module(void)
+{
+	return usb_mouse_init();
+}
+
+void cleanup_module(void)
+{
+	/* this, too, probably needs work */
+	usb_deregister(&mouse_driver);
+	misc_deregister(&usb_mouse);
+}
+
+#endif
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/ohci-debug.c linux/drivers/usb/ohci-debug.c
--- v2.2.6/linux/drivers/usb/ohci-debug.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/ohci-debug.c	Mon Apr 26 12:52:33 1999
@@ -0,0 +1,139 @@
+/*
+ * OHCI debugging code.  It's gross.
+ *
+ * (C) Copyright 1999 Gregory P. Smith
+ */
+
+#include <linux/kernel.h>
+#include <asm/io.h>
+
+#include "ohci.h"
+
+void show_ohci_status(struct ohci *ohci)
+{
+	struct ohci_regs regs;
+	int i;
+
+	regs.revision = readl(ohci->regs->revision);
+	regs.control = readl(ohci->regs->control);
+	regs.cmdstatus = readl(ohci->regs->cmdstatus);
+	regs.intrstatus = readl(ohci->regs->intrstatus);
+	regs.intrenable = readl(ohci->regs->intrenable);
+	regs.intrdisable = readl(ohci->regs->intrdisable);
+	regs.hcca = readl(ohci->regs->hcca);
+	regs.ed_periodcurrent = readl(ohci->regs->ed_periodcurrent);
+	regs.ed_controlhead = readl(ohci->regs->ed_controlhead);
+	regs.ed_bulkhead = readl(ohci->regs->ed_bulkhead);
+	regs.ed_bulkcurrent = readl(ohci->regs->ed_bulkcurrent);
+	regs.current_donehead = readl(ohci->regs->current_donehead);
+	regs.fminterval = readl(ohci->regs->fminterval);
+	regs.fmremaining = readl(ohci->regs->fmremaining);
+	regs.fmnumber = readl(ohci->regs->fmnumber);
+	regs.periodicstart = readl(ohci->regs->periodicstart);
+	regs.lsthresh = readl(ohci->regs->lsthresh);
+	regs.roothub.a = readl(ohci->regs->roothub.a);
+	regs.roothub.b = readl(ohci->regs->roothub.b);
+	regs.roothub.status = readl(ohci->regs->roothub.status);
+	for (i=0; i<MAX_ROOT_PORTS; ++i)
+		regs.roothub.portstatus[i] = readl(ohci->regs->roothub.portstatus[i]);
+
+	printk("  ohci revision    =  0x%x\n", regs.revision);
+	printk("  ohci control     =  0x%x\n", regs.control);
+	printk("  ohci cmdstatus   =  0x%x\n", regs.cmdstatus);
+	printk("  ohci intrstatus  =  0x%x\n", regs.intrstatus);
+	printk("  ohci roothub.a   =  0x%x\n", regs.roothub.a);
+	printk("  ohci roothub.b   =  0x%x\n", regs.roothub.b);
+	printk("  ohci root status =  0x%x\n", regs.roothub.status);
+} /* show_ohci_status() */
+
+
+static void show_ohci_ed(struct ohci_ed *ed)
+{
+	int stat = ed->status;
+	int skip = (stat & OHCI_ED_SKIP);
+	int mps = (stat & OHCI_ED_MPS) >> 16;
+	int isoc = (stat & OHCI_ED_F_ISOC);
+	int low_speed = (stat & OHCI_ED_S_LOW);
+	int dir = (stat & OHCI_ED_D);
+	int endnum = (stat & OHCI_ED_EN) >> 7;
+	int funcaddr = (stat & OHCI_ED_FA);
+	int halted = (ed->head_td & 1);
+	int toggle = (ed->head_td & 2) >> 1;
+
+	printk("   ohci ED:\n");
+	printk("     status     =  0x%x\n", stat);
+	printk("       %sMPS %d%s%s%s%s tc%d e%d fa%d\n",
+			skip ? "Skip " : "",
+			mps,
+			isoc ? "Isoc. " : "",
+			low_speed ? "LowSpd " : "",
+			(dir == OHCI_ED_D_IN) ? "Input " :
+			(dir == OHCI_ED_D_OUT) ? "Output " : "",
+			halted ? "Halted " : "",
+			toggle,
+			endnum,
+			funcaddr);
+	printk("     tail_td    =  0x%x\n", ed->tail_td);
+	printk("     head_td    =  0x%x\n", ed->head_td);
+	printk("     next_ed    =  0x%x\n", ed->next_ed);
+} /* show_ohci_ed() */
+
+
+static void show_ohci_td(struct ohci_td *td)
+{
+	int td_round = td->info & OHCI_TD_ROUND;
+	int td_dir = td->info & OHCI_TD_D;
+	int td_int_delay = td->info & OHCI_TD_IOC_DELAY;
+	int td_toggle = td->info & OHCI_TD_DT;
+	int td_errcnt = td_errorcount(td->info);
+	int td_cc = td->info & OHCI_TD_CC;
+
+	printk("   ohci TD hardware fields:\n");
+	printk("      info     =  0x%x\n", td->info);
+	printk("        %s%s%s%d%s%s%d%s%d\n",
+		td_round ? "Rounding " : "",
+		(td_dir == OHCI_TD_D_IN) ? "Input " :
+		(td_dir == OHCI_TD_D_OUT) ? "Output " :
+		(td_dir == OHCI_TD_D_SETUP) ? "Setup " : "",
+		"IntDelay ", td_int_delay >> 21,
+		td_toggle ? "Data1 " : "Data0 ",
+		"ErrorCnt ", td_errcnt,
+		"ComplCode ", td_cc);
+	printk("       %sAccessed, %sActive\n",
+			td_cc_accessed(td->info) ? "" : "Not ",
+			td_active(td->info) ? "" : "Not ");
+
+	printk("      cur_buf  =  0x%x\n", td->cur_buf);
+	printk("      next_td  =  0x%x\n", td->next_td);
+	printk("      buf_end  =  0x%x\n", td->buf_end);
+	printk("   ohci TD driver fields:\n");
+	printk("      data     =  %p\n", td->data);
+	printk("      dev_id   =  %p\n", td->dev_id);
+	printk("      ed_bus   =  %x\n", td->ed_bus);
+} /* show_ohci_td() */
+
+
+void show_ohci_device(struct ohci_device *dev)
+{
+	int idx;
+	printk("  ohci_device usb       =  %p\n", dev->usb);
+	printk("  ohci_device ohci      =  %p\n", dev->ohci);
+	printk("  ohci_device ohci_hcca =  %p\n", dev->hcca);
+	for (idx=0; idx<8 /*NUM_EDS*/; ++idx) {
+		printk("   [ed num %d] ", idx);
+		show_ohci_ed(&dev->ed[idx]);
+	}
+	for (idx=0; idx<8 /*NUM_TDS*/; ++idx) {
+		printk("   [td num %d] ", idx);
+		show_ohci_td(&dev->td[idx]);
+	}
+	printk("  ohci_device data\n    ");
+	for (idx=0; idx<4; ++idx) {
+		printk(" %08lx", dev->data[idx]);
+	}
+	printk("\n");
+} /* show_ohci_device() */
+
+
+/* vim:sw=8
+ */
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/ohci.c linux/drivers/usb/ohci.c
--- v2.2.6/linux/drivers/usb/ohci.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/ohci.c	Mon Apr 26 12:57:22 1999
@@ -0,0 +1,1040 @@
+/*
+ * Open Host Controller Interface driver for USB.
+ *
+ * (C) Copyright 1999 Gregory P. Smith <gr...@electricrain.com>
+ *
+ * This is the "other" host controller interface for USB.  You will
+ * find this on many non-Intel based motherboards, and of course the
+ * Mac.  As Linus hacked his UHCI driver together first, I modeled
+ * this after his.. (it should be obvious)
+ *
+ * From the programming standpoint the OHCI interface seems a little
+ * prettier and potentially less CPU intensive.  This remains to be
+ * proven.  In reality, I don't believe it'll make one darn bit of
+ * difference.  USB v1.1 is a slow bus by today's standards.
+ *
+ * OHCI hardware takes care of most of the scheduling of different
+ * transfer types with the correct prioritization for us.
+ *
+ * To get started in USB, I used the "Universal Serial Bus System
+ * Architecture" book by Mindshare, Inc.  It was a reasonable introduction
+ * and overview of USB and the two dominant host controller interfaces
+ * however you're better off just reading the real specs available
+ * from www.usb.org as you'll need them to get enough detailt to
+ * actually implement a HCD.  The book has many typos and omissions
+ * Beware, the specs are the victim of a committee.
+ *
+ * This code was written with Guinness on the brain, xsnow on the desktop
+ * and Orbital, Orb, Enya & Massive Attack on the CD player.  What a life!  ;) 
+ *
+ * No filesystems were harmed in the development of this code.
+ *
+ * $Id: ohci.c,v 1.11 1999/04/25 00:18:52 greg Exp $
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+
+#include <asm/spinlock.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include "ohci.h"
+#include "inits.h"
+
+#ifdef CONFIG_APM
+#include <linux/apm_bios.h>
+static int handle_apm_event(apm_event_t event);
+static int apm_resume = 0;
+#endif
+
+static struct wait_queue *ohci_configure = NULL;
+
+
+static int ohci_td_result(struct ohci_device *dev, struct ohci_td *td)
+{
+	unsigned int status;
+
+	status = td->info & OHCI_TD_CC;
+
+	/* TODO Debugging code for TD failures goes here */
+
+	return status;
+}
+
+
+static spinlock_t ohci_edtd_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * Add a TD to the end of the TD list on a given ED.  td->next_td is
+ * assumed to be set correctly for the situation of no TDs already
+ * being on the list (ie: pointing to NULL).
+ */
+static void ohci_add_td_to_ed(struct ohci_td *td, struct ohci_ed *ed)
+{
+	struct ohci_td *tail = bus_to_virt(ed->tail_td);
+	struct ohci_td *head = bus_to_virt(ed->head_td);
+	unsigned long flags;
+
+	spin_lock_irqsave(&ohci_edtd_lock, flags);
+
+	if (tail == head) {	/* empty list, put it on the head */
+		head = (struct ohci_td *) virt_to_bus(td);
+		tail = 0;
+	} else {
+		if (!tail) {	/* no tail, single element list */
+			td->next_td = head->next_td;
+			head->next_td = virt_to_bus(td);
+			tail = (struct ohci_td *) virt_to_bus(td);
+		} else {	/* append to the list */
+			td->next_td = tail->next_td;
+			tail->next_td = virt_to_bus(td);
+			tail = (struct ohci_td *) virt_to_bus(td);
+		}
+	}
+	/* save the reverse link */
+	td->ed_bus = virt_to_bus(ed);
+
+	spin_unlock_irqrestore(&ohci_edtd_lock, flags);
+} /* ohci_add_td_to_ed() */
+
+
+/*
+ *  Remove a TD from the given EDs TD list
+ */
+static void ohci_remove_td_from_ed(struct ohci_td *td, struct ohci_ed *ed)
+{
+	struct ohci_td *head = bus_to_virt(ed->head_td);
+	struct ohci_td *tmp_td;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ohci_edtd_lock, flags);
+
+	/* set the "skip me bit" in this ED */
+	writel_set(OHCI_ED_SKIP, ed->status);
+
+	/* XXX Assuming this list will never be circular */
+
+	if (td == head) {
+		/* unlink this TD; it was at the beginning */
+		ed->head_td = head->next_td;
+	}
+
+	tmp_td = head;
+	head = (struct ohci_td *) ed->head_td;
+	
+	while (head != NULL) {
+
+		if (td == head) {
+			/* unlink this TD from the middle or end */
+			tmp_td->next_td = head->next_td;
+		}
+
+		tmp_td = head;
+		head = bus_to_virt(head->next_td);
+	}
+
+	td->next_td = virt_to_bus(NULL);  /* remove links to ED list */
+
+	/* XXX mark this TD for possible cleanup? */
+
+	/* unset the "skip me bit" in this ED */
+	writel_mask(~(__u32)OHCI_ED_SKIP, ed->status);
+
+	spin_unlock_irqrestore(&ohci_edtd_lock, flags);
+} /* ohci_remove_td_from_ed() */
+
+
+/*
+ * Get a pointer (virtual) to an available TD from the given device's
+ * pool.
+ *
+ * Return NULL if none are left.
+ */
+static struct ohci_td *ohci_get_free_td(struct ohci_device *dev)
+{
+	int idx;
+
+	for (idx=0; idx < NUM_TDS; idx++) {
+		if (td_done(dev->td[idx].info)) {
+			/* XXX should this also zero out the structure? */
+			/* mark all new TDs as unaccessed */
+			dev->td[idx].info = OHCI_TD_CC_NEW;
+			return &dev->td[idx];
+		}
+	}
+
+	return NULL;
+} /* ohci_get_free_td() */
+
+
+/**********************************
+ * OHCI interrupt list operations *
+ **********************************/
+static spinlock_t irqlist_lock = SPIN_LOCK_UNLOCKED;
+
+static void ohci_add_irq_list(struct ohci *ohci, struct ohci_td *td, usb_device_irq completed, void *dev_id)
+{
+	unsigned long flags;
+
+	/* save the irq in our private portion of the TD */
+	td->completed = completed;
+	td->dev_id = dev_id;
+
+	spin_lock_irqsave(&irqlist_lock, flags);
+	list_add(&td->irq_list, &ohci->interrupt_list);
+	spin_unlock_irqrestore(&irqlist_lock, flags);
+} /* ohci_add_irq_list() */
+
+static void ohci_remove_irq_list(struct ohci_td *td)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&irqlist_lock, flags);
+	list_del(&td->irq_list);
+	spin_unlock_irqrestore(&irqlist_lock, flags);
+} /* ohci_remove_irq_list() */
+
+/*
+ * Request an interrupt handler for one "pipe" of a USB device.
+ * (this function is pretty minimal right now)
+ *
+ * At the moment this is only good for input interrupts. (ie: for a
+ * mouse)
+ *
+ * period is desired polling interval in ms.  The closest, shorter
+ * match will be used.  Powers of two from 1-32 are supported by OHCI.
+ */
+static int ohci_request_irq(struct usb_device *usb, unsigned int pipe,
+	usb_device_irq handler, int period, void *dev_id)
+{
+	struct ohci_device *dev = usb_to_ohci(usb);
+	struct ohci_td *td = dev->td;	/* */
+	struct ohci_ed *interrupt_ed;	/* endpoint descriptor for this irq */
+
+	/*
+	 * Pick a good frequency endpoint based on the requested period
+	 */
+	interrupt_ed = &dev->ohci->root_hub->ed[ms_to_ed_int(period)];
+
+	/*
+	 * Set the max packet size, device speed, endpoint number, usb
+	 * device number (function address), and type of TD.
+	 *
+	 * FIXME: Isochronous transfers need a pool of special 32 byte
+	 * TDs (32 byte aligned) in order to be supported.
+	 */
+	interrupt_ed->status = \
+		ed_set_maxpacket(usb_maxpacket(pipe)) |
+		ed_set_speed(usb_pipeslow(pipe)) |
+		usb_pipe_endpdev(pipe) |
+		OHCI_ED_F_NORM;
+
+	/*
+	 * Set the not accessed condition code, allow odd sized data,
+	 * and set the data transfer direction.
+	 */
+	td->info = OHCI_TD_CC_NEW | OHCI_TD_ROUND |
+		td_set_dir_out(usb_pipeout(pipe));
+
+	/* point it to our data buffer */
+	td->cur_buf = virt_to_bus(dev->data);
+
+	/* FIXME: we're only using 1 TD right now! */
+	td->next_td = virt_to_bus(&td);
+
+	/*
+	 * FIXME: be aware that OHCI won't advance out of the 4kb
+	 * page cur_buf started in.  It'll wrap around to the start
+	 * of the page...  annoying or useful? you decide.
+	 *
+	 * A pointer to the last *byte* in the buffer (ergh.. we get
+	 * to work around C's pointer arithmatic here with a typecast)
+	 */
+	td->buf_end = virt_to_bus(((u8*)(dev->data + DATA_BUF_LEN)) - 1);
+
+	/* does this make sense for ohci?.. time to think.. */
+	ohci_add_irq_list(dev->ohci, td, handler, dev_id);
+	wmb();     /* found in asm/system.h; scary concept... */
+	ohci_add_td_to_ed(td, interrupt_ed);
+
+	return 0;
+} /* ohci_request_irq() */
+
+/*
+ * Control thread operations:
+ */
+static struct wait_queue *control_wakeup;
+
+static int ohci_control_completed(int stats, void *buffer, void *dev_id)
+{
+	wake_up(&control_wakeup);
+	return 0;
+} /* ohci_control_completed() */
+
+
+/*
+ * Run a control transaction from the root hub's control endpoint.
+ * The passed in TD is the control transfer's Status TD.
+ */
+static int ohci_run_control(struct ohci_device *dev, struct ohci_td *status_td)
+{
+	struct wait_queue wait = { current, NULL };
+	struct ohci_ed *control_ed = &dev->ohci->root_hub->ed[ED_CONTROL];
+
+	current->state = TASK_UNINTERRUPTIBLE;
+	add_wait_queue(&control_wakeup, &wait);
+
+	ohci_add_irq_list(dev->ohci, status_td, ohci_control_completed, NULL);
+	ohci_add_td_to_ed(status_td, control_ed);
+
+	/* FIXME? isn't this a little gross */
+	schedule_timeout(HZ/10);
+
+	ohci_remove_irq_list(status_td);
+	ohci_remove_td_from_ed(status_td, control_ed);
+
+	return ohci_td_result(dev, status_td);
+} /* ohci_run_control() */
+
+/*
+ * Send or receive a control message on a "pipe"
+ *
+ * A control message contains:
+ *   - The command itself
+ *   - An optional data phase
+ *   - Status complete phase
+ *
+ * The data phase can be an arbitrary number of TD's.  Currently since
+ * we use statically allocated TDs if too many come in we'll just
+ * start tossing them and printk() some warning goo...  Most control
+ * messages won't have much data anyways.
+ */
+static int ohci_control_msg(struct usb_device *usb, unsigned int pipe, void *cmd, void *data, int len)
+{
+	struct ohci_device *dev = usb_to_ohci(usb);
+	/*
+	 * ideally dev->ed should be linked into the root hub's
+	 * control_ed list and used instead of just using it directly.
+	 * This could present a problem as is with more than one
+	 * device.  (but who wants to use a keyboard AND a mouse
+	 * anyways? ;)
+	 */
+	struct ohci_ed *control_ed = &dev->ohci->root_hub->ed[ED_CONTROL];
+	struct ohci_td *control_td;
+	struct ohci_td *data_td;
+	struct ohci_td *last_td;
+	__u32 data_td_info;
+
+	/*
+	 * Set the max packet size, device speed, endpoint number, usb
+	 * device number (function address), and type of TD.
+	 *
+	 */
+	control_ed->status = \
+		ed_set_maxpacket(usb_maxpacket(pipe)) |
+		ed_set_speed(usb_pipeslow(pipe)) |
+		usb_pipe_endpdev(pipe) |
+		OHCI_ED_F_NORM;
+
+	/*
+	 * Build the control TD
+	 */
+
+	/* get a TD to send this control message with */
+	control_td = ohci_get_free_td(dev);
+	/* TODO check for NULL */
+
+	/*
+	 * Set the not accessed condition code, allow odd sized data,
+	 * and set the data transfer type to SETUP.  Setup DATA always
+	 * uses a DATA0 packet.
+	 */
+	control_td->info = OHCI_TD_CC_NEW | OHCI_TD_ROUND |
+		OHCI_TD_D_SETUP | OHCI_TD_IOC_OFF | td_force_toggle(0);
+
+	/* point it to the command */
+	control_td->cur_buf = virt_to_bus(cmd);
+
+	/* link to a free TD for the control data input */
+	data_td = ohci_get_free_td(dev);  /* TODO check for NULL */
+	control_td->next_td = virt_to_bus(data_td);
+
+	/*
+	 * Build the DATA TDs
+	 */
+
+	data_td_info = OHCI_TD_CC_NEW | OHCI_TD_ROUND | OHCI_TD_IOC_OFF |
+		td_set_dir_out(usb_pipeout(pipe));
+
+	while (len > 0) {
+		int pktsize = len;
+		struct ohci_td *tmp_td;
+
+		if (pktsize > usb_maxpacket(pipe))
+			pktsize = usb_maxpacket(pipe);
+
+		/* set the data transaction type */
+		data_td->info = data_td_info;
+		/* point to the current spot in the data buffer */
+		data_td->cur_buf = virt_to_bus(data);
+		/* point to the end of this data */
+		data_td->buf_end = virt_to_bus(data+pktsize-1);
+
+		/* allocate the next TD */
+		tmp_td = ohci_get_free_td(dev);  /* TODO check for NULL */
+		data_td->next_td = virt_to_bus(tmp_td);
+		data_td = tmp_td;
+
+		/* move on.. */
+		data += pktsize;
+		len -= pktsize;
+	}
+
+	/* point it at the newly allocated TD from above */
+	last_td = data_td;
+
+	/* The control status packet always uses a DATA1 */
+	last_td->info = OHCI_TD_CC_NEW | OHCI_TD_ROUND | td_force_toggle(1);
+	last_td->next_td = 0; /* end of TDs */
+	last_td->cur_buf = 0; /* no data in this packet */
+	last_td->buf_end = 0;
+
+	/*
+	 * Start the control transaction.. give it the last TD so the
+	 * result can be returned.
+	 */
+	return ohci_run_control(dev, last_td);
+} /* ohci_control_msg() */
+
+
+static struct usb_device *ohci_usb_allocate(struct usb_device *parent)
+{
+	struct usb_device *usb_dev;
+	struct ohci_device *dev;
+
+	usb_dev = kmalloc(sizeof(*usb_dev), GFP_KERNEL);
+	if (!usb_dev)
+		return NULL;
+
+	memset(usb_dev, 0, sizeof(*usb_dev));
+
+	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev) {
+		kfree(usb_dev);
+		return NULL;
+	}
+
+	/* Initialize "dev" */
+	memset(dev, 0, sizeof(*dev));
+
+	usb_dev->hcpriv = dev;
+	dev->usb = usb_dev;
+
+	usb_dev->parent = parent;
+
+	if (parent) {
+		usb_dev->bus = parent->bus;
+		dev->ohci = usb_to_ohci(parent)->ohci;
+	}
+
+	return usb_dev;
+}
+
+static int ohci_usb_deallocate(struct usb_device *usb_dev)
+{
+	kfree(usb_to_ohci(usb_dev));
+	kfree(usb_dev);
+	return 0;
+}
+
+/*
+ * functions for the generic USB driver
+ */
+struct usb_operations ohci_device_operations = {
+	ohci_usb_allocate,
+	ohci_usb_deallocate,
+	ohci_control_msg,
+	ohci_request_irq,
+};
+
+/*
+ * Reset an OHCI controller
+ */
+static void reset_hc(struct ohci *ohci)
+{
+	writel((1<<31), &ohci->regs->intrdisable); /* Disable HC interrupts */
+	writel(1,  &ohci->regs->cmdstatus);	   /* HC Reset */
+	writel_mask(0x3f, &ohci->regs->control);   /* move to UsbReset state */
+} /* reset_hc() */
+
+
+/*
+ * Reset and start an OHCI controller
+ */
+static void start_hc(struct ohci *ohci)
+{
+	int timeout = 1000;	/* used to prevent an infinite loop. */
+
+	reset_hc(ohci);
+
+	while ((readl(&ohci->regs->control) & 0xc0) == 0) {
+		if (!--timeout) {
+			printk("USB HC Reset timed out!\n");
+			break;
+		}
+	}
+
+	/* Choose the interrupts we care about */
+	writel( OHCI_INTR_MIE | OHCI_INTR_RHSC | OHCI_INTR_SF |
+		OHCI_INTR_WDH | OHCI_INTR_SO | OHCI_INTR_UE |
+		OHCI_INTR_FNO,
+		&ohci->regs->intrenable);
+
+	/* Enter the USB Operational state & start the frames a flowing.. */
+	writel_set(OHCI_USB_OPER, &ohci->regs->control);
+
+} /* start_hc() */
+
+
+/*
+ * Reset a root hub port
+ */
+static void ohci_reset_port(struct ohci *ohci, unsigned int port)
+{
+	short ms;
+	int status;
+
+	/* Don't allow overflows. */
+	if (port >= MAX_ROOT_PORTS) {
+		printk("Bad port # passed to ohci_reset_port\n");
+		port = MAX_ROOT_PORTS-1;
+	}
+
+	writel(PORT_PRS, &ohci->regs->roothub.portstatus[port]);  /* Reset */
+
+	/*
+	 * Get the time required for a root hub port to reset and wait
+	 * it out (adding 1ms for good measure).
+	 */
+	ms = (readl(&ohci->regs->roothub.a) >> 24) * 2 + 1;
+	wait_ms(ms);
+
+	/* check port status to see that the reset completed */
+	status = readl(&ohci->regs->roothub.portstatus[port]);
+	if (status & PORT_PRS) {
+		/* reset failed, try harder? */
+		printk("usb-ohci: port %d reset failed, retrying\n", port);
+		writel(PORT_PRS, &ohci->regs->roothub.portstatus[port]);
+		wait_ms(50);
+	}
+
+	/* TODO we might need to re-enable the port here or is that
+	 * done elsewhere? */
+
+} /* ohci_reset_port */
+
+
+/*
+ * This gets called if the connect status on the root hub changes.
+ */
+static void ohci_connect_change(struct ohci * ohci, int port)
+{
+	struct usb_device *usb_dev;
+	struct ohci_device *dev;
+	/* memory I/O address of the port status register */
+	void *portaddr = &ohci->regs->roothub.portstatus[port];
+	int portstatus;	
+
+	/*
+	 * Because of the status change we have to forget
+	 * everything we think we know about the device
+	 * on this root hub port.  It may have changed.
+	 */
+	usb_disconnect(ohci->root_hub->usb->children + port);
+
+	portstatus = readl(portaddr);
+
+	/* disable the port if nothing is connected */
+	if (!(portstatus & PORT_CCS)) {
+		writel(PORT_CCS, portaddr);
+		return;
+	}
+
+	/*
+	 * Allocate a device for the new thingy that's been attached
+	 */
+	usb_dev = ohci_usb_allocate(ohci->root_hub->usb);
+	dev = usb_dev->hcpriv;
+
+	dev->ohci = ohci;
+
+	usb_connect(dev->usb);
+
+	/* link it into the bus's device tree */
+	ohci->root_hub->usb->children[port] = usb_dev;
+
+	wait_ms(200); /* wait for powerup; XXX is this needed? */
+	ohci_reset_port(ohci, port);
+
+	/* Get information on speed by using LSD */
+	usb_dev->slow = readl(portaddr) & PORT_LSDA ? 1 : 0;
+
+	/*
+	 * Do generic USB device tree processing on the new device.
+	 */
+	usb_new_device(usb_dev);
+} /* ohci_connect_change() */
+
+
+/*
+ * This gets called when the root hub configuration
+ * has changed.  Just go through each port, seeing if
+ * there is something interesting happening.
+ */
+static void ohci_check_configuration(struct ohci *ohci)
+{
+	int num = 0;
+	int maxport = readl(&ohci->regs->roothub) & 0xff;
+
+	do {
+		if (readl(ohci->regs->roothub.portstatus[num]) & PORT_CSC)
+			ohci_connect_change(ohci, num);
+	} while (++num < maxport);
+} /* ohci_check_configuration() */
+
+
+/*
+ * Get annoyed at the controller for bothering us.
+ */
+static void ohci_interrupt(int irq, void *__ohci, struct pt_regs *r)
+{
+	struct ohci *ohci = __ohci;
+	struct ohci_regs *regs = ohci->regs;
+	struct ohci_hcca *hcca = ohci->root_hub->hcca;
+	__u32 donehead = hcca->donehead;
+
+	/*
+	 * Check the interrupt status register if needed
+	 */
+	if (!donehead || (donehead & 1)) {
+		__u32 intrstatus = readl(®s->intrstatus);
+
+		/*
+		 * XXX eek! printk's in an interrupt handler.  shoot me!
+		 */
+		if (intrstatus & OHCI_INTR_SO) {
+			printk(KERN_DEBUG "usb-ohci: scheduling overrun\n");
+		}
+		if (intrstatus & OHCI_INTR_RD) {
+			printk(KERN_DEBUG "usb-ohci: resume detected\n");
+		}
+		if (intrstatus & OHCI_INTR_UE) {
+			printk(KERN_DEBUG "usb-ohci: unrecoverable error\n");
+		}
+		if (intrstatus & OHCI_INTR_OC) {
+			printk(KERN_DEBUG "usb-ohci: ownership change?\n");
+		}
+
+		if (intrstatus & OHCI_INTR_RHSC) {
+			/* TODO Process events on the root hub */
+		}
+	}
+
+	/*
+	 * Process the done list
+	 */
+	if (donehead &= ~0x1) {
+		/*
+		 * TODO See which TD's completed..
+		 */
+	}
+
+	/* Re-enable done queue interrupts and reset the donehead */
+	hcca->donehead = 0;
+	writel(OHCI_INTR_WDH, ®s->intrenable);
+	
+} /* ohci_interrupt() */
+
+
+/*
+ * Allocate the resources required for running an OHCI controller.
+ * Host controller interrupts must not be running while calling this
+ * function or the penguins will get angry.
+ *
+ * The mem_base parameter must be the usable -virtual- address of the
+ * host controller's memory mapped I/O registers.
+ */
+static struct ohci *alloc_ohci(void* mem_base)
+{
+	int i;
+	struct ohci *ohci;
+	struct usb_bus *bus;
+	struct ohci_device *dev;
+	struct usb_device *usb;
+
+	ohci = kmalloc(sizeof(*ohci), GFP_KERNEL);
+	if (!ohci)
+		return NULL;
+
+	memset(ohci, 0, sizeof(*ohci));
+
+	ohci->irq = -1;
+	ohci->regs = mem_base;
+	INIT_LIST_HEAD(&ohci->interrupt_list);
+
+	bus = kmalloc(sizeof(*bus), GFP_KERNEL);
+	if (!bus)
+		return NULL;
+
+	memset(bus, 0, sizeof(*bus));
+
+	ohci->bus = bus;
+	bus->hcpriv = ohci;
+	bus->op = &ohci_device_operations;
+
+	/*
+	 * Here we allocate our own root hub and TDs as well as the
+	 * OHCI host controller communications area.  The HCCA is just
+	 * a nice pool of memory with pointers to endpoint descriptors
+	 * for the different interrupts.
+	 */
+	usb = ohci_usb_allocate(NULL);
+	if (!usb)
+		return NULL;
+
+	dev = ohci->root_hub = usb_to_ohci(usb);
+
+	usb->bus = bus;
+
+	/* Initialize the root hub */
+	memset(dev, 0, sizeof(*dev));
+	dev->ohci = ohci;    /* link back to the controller */
+
+	/*
+	 * Allocate the Host Controller Communications Area
+	 */
+	dev->hcca = (struct ohci_hcca *) kmalloc(sizeof(*dev->hcca), GFP_KERNEL);
+
+	/* Tell the controller where the HCCA is */
+	writel(virt_to_bus(dev->hcca), &ohci->regs->hcca);
+
+	/* Get the number of ports on the root hub */
+	usb->maxchild = readl(&ohci->regs->roothub.a) & 0xff;
+	if (usb->maxchild > MAX_ROOT_PORTS) {
+		printk("usb-ohci: Limited to %d ports\n", MAX_ROOT_PORTS);
+		usb->maxchild = MAX_ROOT_PORTS;
+	}
+	if (usb->maxchild < 1) {
+		printk("usb-ohci: Less than one root hub port? Impossible!\n");
+		usb->maxchild = 1;
+	}
+	printk("usb-ohci: %d root hub ports found\n", usb->maxchild);
+
+	printk("alloc_ohci() controller\n");
+	show_ohci_status(ohci);
+	printk("alloc_ohci() root_hub device\n");
+	show_ohci_device(dev);
+
+	/*
+	 * Initialize the ED polling "tree" (for simplicity's sake in
+	 * this driver many nodes in the tree will be identical)
+	 */
+	dev->ed[ED_INT_32].next_ed = virt_to_bus(&dev->ed[ED_INT_16]);
+	dev->ed[ED_INT_16].next_ed = virt_to_bus(&dev->ed[ED_INT_8]);
+	dev->ed[ED_INT_8].next_ed = virt_to_bus(&dev->ed[ED_INT_4]);
+	dev->ed[ED_INT_4].next_ed = virt_to_bus(&dev->ed[ED_INT_2]);
+	dev->ed[ED_INT_2].next_ed = virt_to_bus(&dev->ed[ED_INT_1]);
+
+	/*
+	 * Initialize the polling table to call interrupts at the
+	 * intended intervals.
+	 */
+	for (i = 0; i < NUM_INTS; i++) {
+		if (i == 0)
+			dev->hcca->int_table[i] =
+				virt_to_bus(&dev->ed[ED_INT_32]);
+		else if (i & 1)
+			dev->hcca->int_table[i] =
+				virt_to_bus(&dev->ed[ED_INT_16]);
+		else if (i & 2)
+			dev->hcca->int_table[i] =
+				virt_to_bus(&dev->ed[ED_INT_8]);
+		else if (i & 4)
+			dev->hcca->int_table[i] =
+				virt_to_bus(&dev->ed[ED_INT_4]);
+		else if (i & 8)
+			dev->hcca->int_table[i] =
+				virt_to_bus(&dev->ed[ED_INT_2]);
+		else if (i & 16)
+			dev->hcca->int_table[i] =
+				virt_to_bus(&dev->ed[ED_INT_1]);
+	}
+
+	/*
+	 * Tell the controller where the control and bulk lists are
+	 */
+	writel(virt_to_bus(&dev->ed[ED_CONTROL]), &ohci->regs->ed_controlhead);
+	writel(virt_to_bus(&dev->ed[ED_BULK]), &ohci->regs->ed_bulkhead);
+
+	return ohci;
+} /* alloc_ohci() */
+
+
+/*
+ * De-allocate all resoueces..
+ */
+static void release_ohci(struct ohci *ohci)
+{
+	if (ohci->irq >= 0) {
+		free_irq(ohci->irq, ohci);
+		ohci->irq = -1;
+	}
+
+	if (ohci->root_hub) {
+		/* ensure that HC is stopped before releasing the HCCA */
+		writel(OHCI_USB_SUSPEND, &ohci->regs->control);
+		free_pages((unsigned int) ohci->root_hub->hcca, 1);
+		free_pages((unsigned int) ohci->root_hub, 1);
+		ohci->root_hub->hcca = NULL;
+		ohci->root_hub = NULL;
+	}
+
+	/* unmap the IO address space */
+	iounmap(ohci->regs);
+
+	/* If the ohci itself were dynamic we'd free it here */
+
+} /* release_ohci() */
+
+/*
+ * USB OHCI control thread
+ */
+static int ohci_control_thread(void * __ohci)
+{
+	struct ohci *ohci = (struct ohci *)__ohci;
+	
+	/*
+	 * I'm unfamiliar with the SMP kernel locking.. where should
+	 * this be released?  -greg
+	 */
+	lock_kernel();
+
+	/*
+	 * This thread doesn't need any user-level access,
+	 * so get rid of all of our resources..
+	 */
+	printk("ohci_control_thread at %p\n", &ohci_control_thread);
+	exit_mm(current);
+	exit_files(current);
+	exit_fs(current);
+
+	strcpy(current->comm, "ohci-control");
+
+	/*
+	 * Damn the torpedoes, full speed ahead
+	 */
+	start_hc(ohci);
+	do {
+		interruptible_sleep_on(&ohci_configure);
+#ifdef CONFIG_APM
+		if (apm_resume) {
+			apm_resume = 0;
+			start_hc(ohci);
+			continue;
+		}
+#endif
+		ohci_check_configuration(ohci);
+	} while (!signal_pending(current));
+
+	reset_hc(ohci);
+
+	release_ohci(ohci);
+	MOD_DEC_USE_COUNT;
+	return 0;
+} /* ohci_control_thread() */
+
+
+#ifdef CONFIG_APM
+static int handle_apm_event(apm_event_t event)
+{
+	static int down = 0;
+
+	switch (event) {
+	case APM_SYS_SUSPEND:
+	case APM_USER_SUSPEND:
+		if (down) {
+			printk(KERN_DEBUG "usb-ohci: received extra suspend event\n");
+			break;
+		}
+		down = 1;
+		break;
+	case APM_NORMAL_RESUME:
+	case APM_CRITICAL_RESUME:
+		if (!down) {
+			printk(KERN_DEBUG "usb-ohci: received bogus resume event\n");
+			break;
+		}
+		down = 0;
+		if (waitqueue_active(&ohci_configure)) {
+			apm_resume = 1;
+			wake_up(&ohci_configure);
+		}
+		break;
+	}
+	return 0;
+}
+#endif
+
+/* ... */
+
+/*
+ * Increment the module usage count, start the control thread and
+ * return success if the controller is good.
+ */
+static int found_ohci(int irq, void* mem_base)
+{
+	int retval;
+	struct ohci *ohci;
+
+	/* Allocate the running OHCI structures */
+	ohci = alloc_ohci(mem_base);
+	if (!ohci)
+		return -ENOMEM;
+
+	printk("usb-ohci: alloc_ohci() = %p\n", ohci);
+
+	reset_hc(ohci);
+
+	retval = -EBUSY;
+	if (request_irq(irq, ohci_interrupt, SA_SHIRQ, "usb-ohci", ohci) == 0) {
+		int pid;
+
+		MOD_INC_USE_COUNT;
+		ohci->irq = irq;
+
+		/* fork off the handler */
+		pid = kernel_thread(ohci_control_thread, ohci,
+				CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+		if (pid >= 0)
+			return 0;
+
+		MOD_DEC_USE_COUNT;
+		retval = pid;
+	}
+	release_ohci(ohci);
+	return retval;
+} /* found_ohci() */
+
+
+/*
+ * If this controller is for real, map the IO memory and proceed
+ */
+static int init_ohci(struct pci_dev *dev)
+{
+	unsigned int mem_base = dev->base_address[0];
+	
+	printk("usb-ohci: mem_base is %p\n", (void*)mem_base);
+
+	/* If its OHCI, its memory */
+	if (mem_base & PCI_BASE_ADDRESS_SPACE_IO)
+		return -ENODEV;
+
+	/* Get the memory address and map it for IO */
+	mem_base &= PCI_BASE_ADDRESS_MEM_MASK;
+	/* 
+	 * FIXME ioremap_nocache isn't implemented on all CPUs (such
+	 * as the Alpha) [?]  What should I use instead...
+	 *
+	 * The iounmap() is done on in release_ohci.
+	 */
+	mem_base = (unsigned int) ioremap_nocache(mem_base, 4096);
+
+	if (!mem_base) {
+		printk("Error mapping OHCI memory\n");
+		return -EFAULT;
+	}
+
+	return found_ohci(dev->irq, (void *) mem_base);
+} /* init_ohci() */
+
+
+#ifdef MODULE
+
+/*
+ *  Clean up when unloading the module
+ */
+void cleanup_module(void)
+{
+#ifdef CONFIG_APM
+	apm_unregister_callback(&handle_apm_event);
+#endif
+}
+
+#define ohci_init init_module
+
+#endif
+
+
+/* TODO this should be named following Linux convention and go in pci.h */
+#define PCI_CLASS_SERIAL_USB_OHCI ((PCI_CLASS_SERIAL_USB << 8) | 0x0010)
+
+/*
+ * Search the PCI bus for an OHCI USB controller and set it up
+ *
+ * If anyone wants multiple controllers this will need to be
+ * updated..  Right now, it just picks the first one it finds.
+ */
+int ohci_init(void)
+{
+	int retval;
+	struct pci_dev *dev = NULL;
+	/*u8 type;*/
+
+	if (sizeof(struct ohci_device) > 4096) {
+		printk("usb-ohci: struct ohci_device to large\n");
+		return -ENODEV;
+	}
+
+	retval = -ENODEV;
+	for (;;) {
+		/* Find an OHCI USB controller */
+		dev = pci_find_class(PCI_CLASS_SERIAL_USB_OHCI, dev);
+		if (!dev)
+			break;
+
+		/* Verify that its OpenHCI by checking for MMIO */
+		/* pci_read_config_byte(dev, PCI_CLASS_PROG, &type);
+		if (!type)
+			continue; */
+
+		/* Ok, set it up */
+		retval = init_ohci(dev);
+		if (retval < 0)
+			continue;
+
+		/* TODO check module params here to determine what to load */
+
+/*		usb_mouse_init(); */
+/*		usb_kbd_init();
+		hub_init();	*/
+#ifdef CONFIG_APM
+		apm_register_callback(&handle_apm_event);
+#endif
+
+		return 0; /* no error */
+	}
+	return retval;
+} /* init_module() */
+
+/* vim:sw=8
+ */
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/ohci.h linux/drivers/usb/ohci.h
--- v2.2.6/linux/drivers/usb/ohci.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/ohci.h	Mon Apr 26 12:51:57 1999
@@ -0,0 +1,301 @@
+#ifndef __LINUX_OHCI_H
+#define __LINUX_OHCI_H
+
+/*
+ * Open Host Controller Interface data structures and defines.
+ *
+ * (C) Copyright 1999 Gregory P. Smith <gr...@electricrain.com>
+ *
+ * $Id: ohci.h,v 1.6 1999/04/24 22:50:06 greg Exp $
+ */
+
+#include <linux/list.h>
+#include <asm/io.h>
+
+#include "usb.h"
+
+/*
+ * Each TD must be aligned on a 16-byte boundary.  From the OHCI v1.0 spec
+ * it does not state that TDs must be contiguious in memory (due to the
+ * use of the next_td field).  This gives us extra room at the end of a
+ * TD for our own driver specific data.
+ *
+ * This structure's size must be a multiple of 16 bytes.
+ */
+struct ohci_td {
+    	/* OHCI Hardware fields */
+    	__u32 info;
+	__u32 cur_buf;		/* Current Buffer Pointer */
+	__u32 next_td;		/* Next TD Pointer */
+	__u32 buf_end;		/* Memory Buffer End Pointer */
+
+	/* Driver specific fields */
+	struct list_head irq_list;	/* Active interrupt list */
+	usb_device_irq completed;	/* Completion handler routine */
+	void *data;	/* XXX ? */
+	void *dev_id;	/* XXX ? */
+	__u32 ed_bus;			/* bus address of original ED */
+} __attribute((aligned(32)));
+
+#define OHCI_TD_ROUND	(1 << 18)	/* buffer rounding bit */
+#define OHCI_TD_D	(3 << 11)	/* direction of xfer: */
+#define OHCI_TD_D_IN	(2 << 11)
+#define OHCI_TD_D_OUT	(1 << 11)
+#define OHCI_TD_D_SETUP (0)
+#define td_set_dir_in(d)	((d) ? OHCI_TD_D_IN : OHCI_TD_D_OUT )
+#define td_set_dir_out(d)	((d) ? OHCI_TD_D_OUT : OHCI_TD_D_IN )
+#define OHCI_TD_IOC_DELAY (7 << 21)	/* frame delay allowed before int. */
+#define OHCI_TD_IOC_OFF	(OHCI_TD_IOC_DELAY)	/* no interrupt on complete */
+#define OHCI_TD_DT	(3 << 24)	/* data toggle bits */
+#define td_force_toggle(b)	(((b) | 2) << 24)
+#define OHCI_TD_ERRCNT	(3 << 26)	/* error count */
+#define td_errorcount(td)	(((td) >> 26) & 3)
+#define OHCI_TD_CC	(0xf << 28)	/* condition code */
+#define OHCI_TD_CC_NEW	(OHCI_TD_CC)	/* set this on all unaccessed TDs! */
+#define td_cc_notaccessed(td)	((td >> 29) == 7)
+#define td_cc_accessed(td)	((td >> 29) != 7)
+#define td_cc_noerror(td)	(((td) & OHCI_TD_CC) == 0)
+#define td_active(td)	(!td_cc_noerror((td)) && (td_errorcount((td)) < 3))
+#define td_done(td)	(td_cc_noerror((td)) || (td_errorcount((td)) == 3))
+
+/*
+ * The endpoint descriptors also requires 16-byte alignment
+ */
+struct ohci_ed {
+	/* OHCI hardware fields */
+	__u32 status;
+	__u32 tail_td;	/* TD Queue tail pointer */
+	__u32 head_td;	/* TD Queue head pointer */
+	__u32 next_ed;	/* Next ED */
+} __attribute((aligned(16)));
+
+#define OHCI_ED_SKIP	(1 << 14)
+#define OHCI_ED_MPS	(0x7ff << 16)
+/* FIXME: should cap at the USB max packet size [0x4ff] */
+#define ed_set_maxpacket(s)	(((s) << 16) & OHCI_ED_MPS)
+#define OHCI_ED_F_NORM	(0)
+#define OHCI_ED_F_ISOC	(1 << 15)
+#define ed_set_type_isoc(i)	((i) ? OHCI_ED_F_ISOC : OHCI_ED_F_NORM)
+#define OHCI_ED_S_LOW	(1 << 13)
+#define OHCI_ED_S_HIGH	(0)
+#define ed_set_speed(s)		((s) ? OHCI_ED_S_LOW : OHCI_ED_S_HIGH)
+#define OHCI_ED_D	(3 << 11)
+#define OHCI_ED_D_IN	(2 << 11)
+#define OHCI_ED_D_OUT	(1 << 11)
+#define ed_set_dir_in(d)	((d) ? OHCI_ED_D_IN : OHCI_ED_D_OUT)
+#define ed_set_dir_out(d)	((d) ? OHCI_ED_D_OUT : OHCI_ED_D_IN)
+#define OHCI_ED_EN	(0xf << 7)
+#define OHCI_ED_FA	(0x7f)
+
+
+/* NOTE: bits 27-31 of the status dword are reserved for the driver */
+/*
+ * We'll use this status flag for the non-predefined EDs to mark if
+ * they're in use or not.
+ *
+ * FIXME: unimplemented (needed?)
+ */
+#define ED_USED	(1 << 31)
+
+/*
+ * The HCCA (Host Controller Communications Area) is a 256 byte
+ * structure defined in the OHCI spec. that the host controller is
+ * told the base address of.  It must be 256-byte aligned.
+ */
+#define NUM_INTS 32	/* part of the OHCI standard */
+struct ohci_hcca {
+    	__u32	int_table[NUM_INTS];	/* Interrupt ED table */
+	__u16	frame_no;		/* current frame number */
+	__u16	pad1;			/* set to 0 on each frame_no change */
+	__u32	donehead;		/* info returned for an interrupt */
+	u8	reserved_for_hc[116];
+} __attribute((aligned(256)));
+
+/*
+ * The TD entries here are pre-allocated as Linus did with his simple
+ * UHCI implementation.  With the current state of this driver that
+ * shouldn't be a problem.  However if someone ever connects 127
+ * supported devices to this driver and tries to use them all at once:
+ * 	a)  They're insane!
+ * 	b)  They should code in dynamic allocation
+ */
+struct ohci;
+
+/*
+ *  Warning: These constants must not be so large as to cause the
+ *  ohci_device structure to exceed one 4096 byte page.  Or "weird
+ *  things will happen" as the alloc_ohci() function assumes that
+ *  its less than one page.  (FIXME)
+ */
+#define NUM_TDS	32		/* num of preallocated transfer descriptors */
+#define DATA_BUF_LEN 16		/* num of unsigned long's for the data buf */
+
+/*
+ * For this "simple" driver we only support a single ED for each
+ * polling rate.
+ *
+ * Later on this driver should be extended to use a full tree of EDs
+ * so that there can be 32 different 32ms polling frames, etc.
+ * Individual devices shouldn't need as many as the root hub in that
+ * case; complicating how things are done at the moment.
+ *
+ * Bulk and Control transfers hang off of their own ED lists.
+ */
+#define NUM_EDS 16		/* num of preallocated endpoint descriptors */
+
+#define ohci_to_usb(ohci)	((ohci)->usb)
+#define usb_to_ohci(usb)	((struct ohci_device *)(usb)->hcpriv)
+
+/* The usb_device must be first! */
+struct ohci_device {
+    	struct usb_device	*usb;
+
+	struct ohci		*ohci;
+	struct ohci_hcca 	*hcca;		/* OHCI mem. mapped IO area */
+
+	struct ohci_ed		ed[NUM_EDS];	/* Endpoint Descriptors */
+	struct ohci_td		td[NUM_TDS];	/* Transfer Descriptors */
+
+	unsigned long		data[DATA_BUF_LEN];
+};
+
+/* .... */
+
+#define ED_INT_1	0
+#define ED_INT_2	1
+#define ED_INT_4	2
+#define ED_INT_8	3
+#define ED_INT_16	4
+#define ED_INT_32	5
+#define ED_CONTROL	6
+#define ED_BULK		7
+#define ED_ISO		ED_INT_1	/* same as 1ms interrupt queue */
+#define ED_FIRST_AVAIL  8		/* first non-reserved ED */
+
+/*
+ * Given a period p in ms, convert it to the closest endpoint
+ * interrupt frequency; rounding down.  I'm sure many feel that this
+ * is a gross macro.  Feel free to toss it for actual code.
+ */
+#define ms_to_ed_int(p) \
+	((p >= 32) ? ED_INT_32 : \
+	 ((p & 16) ? ED_INT_16 : \
+	  ((p & 8) ? ED_INT_8 : \
+	   ((p & 4) ? ED_INT_4 : \
+	    ((p & 2) ? ED_INT_2 : \
+	     ED_INT_1)))))  /* hmm.. scheme or lisp anyone? */
+
+/*
+ * This is the maximum number of root hub ports.  I don't think we'll
+ * ever see more than two as that's the space available on an ATX
+ * motherboard's case, but it could happen.  The OHCI spec allows for
+ * up to 15... (which is insane!)
+ * 
+ * Although I suppose several "ports" could be connected directly to
+ * internal laptop devices such as a keyboard, mouse, camera and
+ * serial/parallel ports.  hmm...  That'd be neat.
+ */
+#define MAX_ROOT_PORTS	15	/* maximum OHCI root hub ports */
+
+/*
+ * This is the structure of the OHCI controller's memory mapped I/O
+ * region.  This is Memory Mapped I/O.  You must use the readl() and
+ * writel() macros defined in asm/io.h to access these!!
+ */
+struct ohci_regs {
+	/* control and status registers */
+	__u32	revision;
+	__u32	control;
+	__u32	cmdstatus;
+	__u32	intrstatus;
+	__u32	intrenable;
+	__u32	intrdisable;
+	/* memory pointers */
+	__u32	hcca;
+	__u32	ed_periodcurrent;
+	__u32	ed_controlhead;
+	__u32	ed_controlcurrent;
+	__u32	ed_bulkhead;
+	__u32	ed_bulkcurrent;
+	__u32	current_donehead; /* The driver should get this from the HCCA */
+	/* frame counters */
+	__u32	fminterval;
+	__u32	fmremaining;
+	__u32	fmnumber;
+	__u32	periodicstart;
+	__u32	lsthresh;
+	/* Root hub ports */
+	struct	ohci_roothub_regs {
+		__u32	a;
+		__u32	b;
+		__u32	status;
+		__u32	portstatus[MAX_ROOT_PORTS];
+	} roothub;
+} __attribute((aligned(32)));
+
+/* 
+ * Read a MMIO register and re-write it after ANDing with (m)
+ */
+#define writel_mask(m, a) writel( (readl((__u32)(a))) & (__u32)(m), (__u32)(a) )
+
+/*
+ * Read a MMIO register and re-write it after ORing with (b)
+ */
+#define writel_set(b, a) writel( (readl((__u32)(a))) | (__u32)(b), (__u32)(a) )
+
+
+#define PORT_CCS	(1)		/* port current connect status */
+#define PORT_PES	(1 << 1)	/* port enable status */
+#define PORT_PSS	(1 << 2)	/* port suspend status */
+#define PORT_POCI	(1 << 3)	/* port overcurrent indicator */
+#define PORT_PRS	(1 << 4)	/* port reset status */
+#define PORT_PPS	(1 << 8)	/* port power status */
+#define PORT_LSDA	(1 << 9)	/* port low speed dev. attached */
+#define PORT_CSC	(1 << 16)	/* port connect status change */
+#define PORT_PESC	(1 << 17)	/* port enable status change */
+#define PORT_PSSC	(1 << 18)	/* port suspend status change */
+#define PORT_OCIC	(1 << 19)	/* port over current indicator chg */
+#define PORT_PRSC	(1 << 20)	/* port reset status change */
+
+
+/*
+ * Interrupt register masks
+ */
+#define OHCI_INTR_SO	(1)
+#define OHCI_INTR_WDH	(1 << 1)
+#define OHCI_INTR_SF	(1 << 2)
+#define OHCI_INTR_RD	(1 << 3)
+#define OHCI_INTR_UE	(1 << 4)
+#define OHCI_INTR_FNO	(1 << 5)
+#define OHCI_INTR_RHSC	(1 << 6)
+#define OHCI_INTR_OC	(1 << 30)
+#define OHCI_INTR_MIE	(1 << 31)
+
+/*
+ * Control register masks
+ */
+#define OHCI_USB_OPER		(2 << 6)
+#define OHCI_USB_SUSPEND	(3 << 6)
+
+/*
+ * This is the full ohci controller description
+ *
+ * Note how the "proper" USB information is just
+ * a subset of what the full implementation needs. (Linus)
+ */
+struct ohci {
+    	int irq;
+	struct ohci_regs *regs;			/* OHCI controller's memory */
+	struct usb_bus *bus;
+	struct ohci_device *root_hub;		/* Root hub & controller */
+	struct list_head interrupt_list;	/* List of interrupt active TDs for this OHCI */
+};
+
+/* Debugging code */
+void show_ed(struct ohci_ed *ed);
+void show_td(struct ohci_td *td);
+void show_status(struct ohci *ohci);
+
+#endif
+/* vim:sw=8
+ */
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/restart linux/drivers/usb/restart
--- v2.2.6/linux/drivers/usb/restart	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/restart	Fri Apr 16 15:22:40 1999
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+ME=`basename $0`
+
+#UMOD=`lsmod | grep '^bp-mouse' | grep -v grep`
+#if test "$UMOD"; then
+#  echo "$ME: removing bp-mouse.o"
+#  if ! rmmod bp-mouse; then
+#    echo "$ME: cannot remove bp-mouse.o"
+#    exit 1
+#  fi
+#fi
+
+UPID=`ps aux | grep uhci-control | grep -v grep | awk '{print $2}'`
+if test "$UPID"; then
+  echo "$ME: killing $UPID"
+  kill $UPID
+fi
+
+UMOD=`lsmod | grep '^usb-uhci' | grep -v grep`
+if test "$UMOD"; then
+  echo "$ME: removing usb-uhci.o"
+  sleep 1
+  if ! rmmod usb-uhci; then
+    echo "$ME: cannot remove usb-uhci.o"
+    exit 1
+  fi
+fi
+
+dmesg -c > /dev/null
+
+echo "$ME: starting usb-uhci.o"
+insmod -m usb-uhci.o > usb-uhci.map
+#echo "$ME: starting bp-mouse.o"
+#insmod -m bp-mouse.o > bp-mouse.map
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/stopusb linux/drivers/usb/stopusb
--- v2.2.6/linux/drivers/usb/stopusb	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/stopusb	Wed Apr 21 02:42:11 1999
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+killall uhci-control
+killall khubd
+
+sleep 1
+
+rmmod usb-uhci
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/uhci-debug.c linux/drivers/usb/uhci-debug.c
--- v2.2.6/linux/drivers/usb/uhci-debug.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/uhci-debug.c	Mon Apr 26 12:22:58 1999
@@ -0,0 +1,168 @@
+/*
+ * UHCI-specific debugging code. Invaluable when something
+ * goes wrong, but don't get in my face.
+ *
+ * (C) Copyright 1999 Linus Torvalds
+ */
+
+#include <linux/kernel.h>
+#include <asm/io.h>
+
+#include "uhci.h"
+
+void show_td(struct uhci_td * td)
+{
+	printk("%08x ", td->link);
+	printk("%se%d %s%s%s%s%s%s%s%s%s%sLength=%x ",
+		((td->status >> 29) & 1) ? "SPD " : "",
+		((td->status >> 27) & 3),
+		((td->status >> 26) & 1) ? "LS " : "",
+		((td->status >> 25) & 1) ? "IOS " : "",
+		((td->status >> 24) & 1) ? "IOC " : "",
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 12'
echo 'File patch-2.2.7 is continued in part 13'
echo 13 > _shar_seq_.tmp
#!/bin/sh
# this is part 14 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 14; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
+	{
+		printk(KERN_INFO "usb: truncated DT_CONFIG (want %d).\n", size);
+		size = sizeof(buffer);
+	}
+
+	if (usb_get_descriptor(dev, USB_DT_CONFIG, 0, buffer, size))
+		return -1;
+
+	return usb_parse_configuration(dev, buffer, size);
+}
+
+/*
+ * By the time we get here, the device has gotten a new device ID
+ * and is in the default state. We need to identify the thing and
+ * get the ball rolling..
+ */
+void usb_new_device(struct usb_device *dev)
+{
+	int addr, i;
+
+	printk("USB new device connect, assigned device number %d\n",
+		dev->devnum);
+
+	dev->maxpacketsize = 0;		/* Default to 8 byte max packet size */
+
+	addr = dev->devnum;
+	dev->devnum = 0;
+
+	/* Slow devices */
+	for (i = 0; i < 5; i++) {
+		if (!usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8))
+			break;
+
+		printk("get_descriptor failed, waiting\n");
+		wait_ms(200);
+	}
+	if (i == 5) {
+		printk("giving up\n");
+		return;
+	}
+
+#if 0
+	printk("maxpacketsize: %d\n", dev->descriptor.bMaxPacketSize0);
+#endif
+	switch (dev->descriptor.bMaxPacketSize0) {
+		case 8: dev->maxpacketsize = 0; break;
+		case 16: dev->maxpacketsize = 1; break;
+		case 32: dev->maxpacketsize = 2; break;
+		case 64: dev->maxpacketsize = 3; break;
+	}
+#if 0
+	printk("dev->mps: %d\n", dev->maxpacketsize);
+#endif
+
+	dev->devnum = addr;
+
+	if (usb_set_address(dev)) {
+		printk("Unable to set address\n");
+		/* FIXME: We should disable the port */
+		return;
+	}
+
+	wait_ms(10);	/* Let the SET_ADDRESS settle */
+
+	if (usb_get_device_descriptor(dev)) {
+		printk("Unable to get device descriptor\n");
+		return;
+	}
+
+	if (usb_get_configuration(dev)) {
+		printk("Unable to get configuration\n");
+		return;
+	}
+
+#if 0
+	printk("Vendor: %X\n", dev->descriptor.idVendor);
+	printk("Product: %X\n", dev->descriptor.idProduct);
+#endif
+
+	usb_device_descriptor(dev);
+}
+
+int usb_request_irq(struct usb_device *dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id)
+{
+	return dev->bus->op->request_irq(dev, pipe, handler, period, dev_id);
+}
+
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/usb.h linux/drivers/usb/usb.h
--- v2.2.6/linux/drivers/usb/usb.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/usb.h	Wed Apr 28 11:14:03 1999
@@ -0,0 +1,371 @@
+#ifndef __LINUX_USB_H
+#define __LINUX_USB_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+
+static __inline__ void wait_ms(unsigned int ms)
+{
+        current->state = TASK_UNINTERRUPTIBLE;
+        schedule_timeout(1 + ms / 10);
+}
+
+
+typedef struct {
+  unsigned char requesttype;
+  unsigned char request;
+  unsigned short value;
+  unsigned short index;
+  unsigned short length;
+} devrequest;
+
+/*
+ * Class codes
+ */
+#define USB_CLASS_HUB			9
+
+/*
+ * Descriptor types
+ */
+#define USB_DT_DEVICE			0x01
+#define USB_DT_CONFIG			0x02
+#define USB_DT_STRING			0x03
+#define USB_DT_INTERFACE		0x04
+#define USB_DT_ENDPOINT			0x05
+
+#define USB_DT_HUB			0x29
+#define USB_DT_HID			0x21
+
+/*
+ * Standard requests
+ */
+#define USB_REQ_GET_STATUS		0x00
+#define USB_REQ_CLEAR_FEATURE		0x01
+/* 0x02 is reserved */
+#define USB_REQ_SET_FEATURE		0x03
+/* 0x04 is reserved */
+#define USB_REQ_SET_ADDRESS		0x05
+#define USB_REQ_GET_DESCRIPTOR		0x06
+#define USB_REQ_SET_DESCRIPTOR		0x07
+#define USB_REQ_GET_CONFIGURATION	0x08
+#define USB_REQ_SET_CONFIGURATION	0x09
+#define USB_REQ_GET_INTERFACE		0x0A
+#define USB_REQ_SET_INTERFACE		0x0B
+#define USB_REQ_SYNCH_FRAME		0x0C
+
+/*
+ * HIDD requests
+ */
+#define USB_REQ_GET_REPORT		0x01
+#define USB_REQ_GET_IDLE		0x02
+#define USB_REQ_GET_PROTOCOL		0x03
+#define USB_REQ_SET_REPORT		0x09
+#define USB_REQ_SET_IDLE		0x0A
+#define USB_REQ_SET_PROTOCOL		0x0B
+
+#define USB_TYPE_STANDARD		(0x00 << 5)
+#define USB_TYPE_CLASS			(0x01 << 5)
+#define USB_TYPE_VENDOR			(0x02 << 5)
+#define USB_TYPE_RESERVED		(0x03 << 5)
+
+#define USB_RECIP_DEVICE		0x00
+#define USB_RECIP_INTERFACE		0x01
+#define USB_RECIP_ENDPOINT		0x02
+#define USB_RECIP_OTHER			0x03
+
+/*
+ * Request target types.
+ */
+#define USB_RT_DEVICE			0x00
+#define USB_RT_INTERFACE		0x01
+#define USB_RT_ENDPOINT			0x02
+
+#define USB_RT_HUB			(USB_TYPE_CLASS | USB_RECIP_DEVICE)
+#define USB_RT_PORT			(USB_TYPE_CLASS | USB_RECIP_OTHER)
+
+#define USB_RT_HIDD			(USB_TYPE_CLASS | USB_RECIP_INTERFACE)
+
+/*
+ * USB device number allocation bitmap. There's one bitmap
+ * per USB tree.
+ */
+struct usb_devmap {
+	unsigned long devicemap[128 / (8*sizeof(unsigned long))];
+};
+
+/*
+ * This is a USB device descriptor.
+ *
+ * USB device information
+ *
+ * Make this MUCH dynamic, right now
+ * it contains enough information for
+ * a USB floppy controller, and nothing
+ * else.
+ *
+ * I'm not proud. I just want this dang
+ * thing to start working.
+ */
+#define USB_MAXCONFIG		2
+#define USB_MAXINTERFACES	8
+#define USB_MAXENDPOINTS	4
+
+struct usb_device_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u16 bcdUSB;
+	__u8  bDeviceClass;
+	__u8  bDeviceSubClass;
+	__u8  bDeviceProtocol;
+	__u8  bMaxPacketSize0;
+	__u16 idVendor;
+	__u16 idProduct;
+	__u16 bcdDevice;
+	__u8  iManufacturer;
+	__u8  iProduct;
+	__u8  iSerialNumber;
+	__u8  bNumConfigurations;
+};
+
+/* Endpoint descriptor */
+struct usb_endpoint_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u8  bEndpointAddress;
+	__u8  bmAttributes;
+	__u16 wMaxPacketSize;
+	__u8  bInterval;
+};
+
+/* Interface descriptor */
+struct usb_interface_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u8  bInterfaceNumber;
+	__u8  bAlternateSetting;
+	__u8  bNumEndpoints;
+	__u8  bInterfaceClass;
+	__u8  bInterfaceSubClass;
+	__u8  bInterfaceProtocol;
+	__u8  iInterface;
+
+	struct usb_endpoint_descriptor endpoint[USB_MAXENDPOINTS];
+};
+
+/* Configuration descriptor information.. */
+struct usb_config_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u16 wTotalLength;
+	__u8  bNumInterfaces;
+	__u8  bConfigurationValue;
+	__u8  iConfiguration;
+	__u8  bmAttributes;
+	__u8  MaxPower;
+
+	struct usb_interface_descriptor interface[USB_MAXINTERFACES];
+};
+
+/* String descriptor */
+struct usb_string_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+};
+
+/* Hub descriptor */
+struct usb_hub_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u8  bNbrPorts;
+	__u16 wHubCharacteristics;
+	__u8  bPwrOn2PwrGood;
+	__u8  bHubContrCurrent;
+	/* DeviceRemovable and PortPwrCtrlMask want to be variable-length 
+	   bitmaps that hold max 256 entries, but for now they're ignored */
+	__u8  filler;
+};
+
+struct usb_device;
+
+struct usb_driver {
+	const char * name;
+	int (*probe)(struct usb_device *);
+	void (*disconnect)(struct usb_device *);
+	struct list_head driver_list;
+};
+
+/*
+ * Pointer to a device endpoint interrupt function -greg
+ */
+typedef int (*usb_device_irq)(int, void *, void *);
+
+struct usb_operations {
+	struct usb_device *(*allocate)(struct usb_device *);
+	int (*deallocate)(struct usb_device *);
+	int (*control_msg)(struct usb_device *, unsigned int, void *, void *, int);
+	int (*request_irq)(struct usb_device *, unsigned int, usb_device_irq, int, void *);
+};
+
+/*
+ * Allocated per bus we have
+ */
+struct usb_bus {
+	struct usb_devmap devmap;       /* Device map */
+	struct usb_operations *op;      /* Operations (specific to the HC) */
+	struct usb_device *root_hub;    /* Root hub */
+	void *hcpriv;                   /* Host Controller private data */
+};
+
+
+#define USB_MAXCHILDREN (8)
+
+struct usb_device {
+	int devnum;						/* Device number on USB bus */
+	int slow;						/* Slow device? */
+	int maxpacketsize;					/* Maximum packet size */
+
+	struct usb_bus *bus;					/* Bus we're apart of */
+	struct usb_driver *driver;				/* Driver */
+	struct usb_device_descriptor descriptor;		/* Descriptor */
+	struct usb_config_descriptor config[USB_MAXCONFIG];	/* All of the configs */
+	struct usb_device *parent;
+  
+	/*
+	 * Child devices - these can be either new devices
+	 * (if this is a hub device), or different instances
+	 * of this same device.
+	 *
+	 * Each instance needs its own set of data structuctures.
+	 */
+
+	int maxchild;			/* Number of ports if hub */
+	struct usb_device *children[USB_MAXCHILDREN];
+
+	void *hcpriv;			/* Host Controller private data */
+	void *private;			/* Upper layer private data */
+};
+
+extern int usb_register(struct usb_driver *);
+extern void usb_deregister(struct usb_driver *);
+
+extern int usb_request_irq(struct usb_device *, unsigned int, usb_device_irq, int, void *);
+
+extern void usb_init_root_hub(struct usb_device *dev);
+extern void usb_connect(struct usb_device *dev);
+extern void usb_disconnect(struct usb_device **);
+extern void usb_device_descriptor(struct usb_device *dev);
+
+extern int  usb_parse_configuration(struct usb_device *dev, void *buf, int len);
+
+/*
+ * Calling this entity a "pipe" is glorifying it. A USB pipe
+ * is something embarrassingly simple: it basically consists
+ * of the following information:
+ *  - device number (7 bits)
+ *  - endpoint number (4 bits)
+ *  - current Data0/1 state (1 bit)
+ *  - direction (1 bit)
+ *  - speed (1 bit)
+ *  - max packet size (2 bits: 8, 16, 32 or 64)
+ *  - pipe type (2 bits: control, interrupt, bulk, isochronous)
+ *
+ * That's 18 bits. Really. Nothing more. And the USB people have
+ * documented these eighteen bits as some kind of glorious
+ * virtual data structure.
+ *
+ * Let's not fall in that trap. We'll just encode it as a simple
+ * unsigned int. The encoding is:
+ *
+ *  - device:		bits 8-14
+ *  - endpoint:		bits 15-18
+ *  - Data0/1:		bit 19
+ *  - direction:	bit 7		(0 = Host-to-Device, 1 = Device-to-Host)
+ *  - speed:		bit 26		(0 = High, 1 = Low Speed)
+ *  - max size:		bits 0-1	(00 = 8, 01 = 16, 10 = 32, 11 = 64)
+ *  - pipe type:	bits 30-31	(00 = isochronous, 01 = interrupt, 10 = control, 11 = bulk)
+ *
+ * Why? Because it's arbitrary, and whatever encoding we select is really
+ * up to us. This one happens to share a lot of bit positions with the UCHI
+ * specification, so that much of the uhci driver can just mask the bits
+ * appropriately.
+ */
+
+#define usb_maxpacket(pipe)	(8 << ((pipe) & 3))
+#define usb_packetid(pipe)	(((pipe) & 0x80) ? 0x69 : 0xE1)
+
+#define usb_pipedevice(pipe)	(((pipe) >> 8) & 0x7f)
+#define usb_pipeendpoint(pipe)	(((pipe) >> 15) & 0xf)
+#define usb_pipedata(pipe)	(((pipe) >> 19) & 1)
+#define usb_pipeout(pipe)	(((pipe) & 0x80) == 0)
+#define usb_pipeslow(pipe)	(((pipe) >> 26) & 1)
+
+#define usb_pipetype(pipe)	(((pipe) >> 30) & 3)
+#define usb_pipeisoc(pipe)	(usb_pipetype((pipe)) == 0)
+#define usb_pipeint(pipe)	(usb_pipetype((pipe)) == 1)
+#define usb_pipecontrol(pipe)	(usb_pipetype((pipe)) == 2)
+#define usb_pipebulk(pipe)	(usb_pipetype((pipe)) == 3)
+
+#define usb_pipe_endpdev(pipe)	(((pipe) >> 8) & 0x7ff)
+
+static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int endpoint)
+{
+	return (dev->devnum << 8) | (endpoint << 15) | (dev->slow << 26) | dev->maxpacketsize;
+}
+
+static inline unsigned int __default_pipe(struct usb_device *dev)
+{
+	return (dev->slow << 26);
+}
+
+/* Create control pipes.. */
+#define usb_sndctrlpipe(dev,endpoint)	((2 << 30) | __create_pipe(dev,endpoint))
+#define usb_rcvctrlpipe(dev,endpoint)	((2 << 30) | __create_pipe(dev,endpoint) | 0x80)
+#define usb_snddefctrl(dev)		((2 << 30) | __default_pipe(dev))
+#define usb_rcvdefctrl(dev)		((2 << 30) | __default_pipe(dev) | 0x80)
+
+/* Create .. */
+
+/*
+ * Send and receive control messages..
+ */
+void usb_new_device(struct usb_device *dev);
+int usb_set_address(struct usb_device *dev);
+int usb_get_descriptor(struct usb_device *dev, unsigned char desctype, unsigned
+char descindex, void *buf, int size);
+int usb_get_device_descriptor(struct usb_device *dev);
+int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size);
+int usb_clear_port_feature(struct usb_device *dev, int port, int feature);
+int usb_set_port_feature(struct usb_device *dev, int port, int feature);
+int usb_get_hub_status(struct usb_device *dev, void *data);
+int usb_get_port_status(struct usb_device *dev, int port, void *data);
+int usb_get_protocol(struct usb_device *dev);
+int usb_set_protocol(struct usb_device *dev, int protocol);
+int usb_set_idle(struct usb_device *dev, int duration, int report_id);
+int usb_set_configuration(struct usb_device *dev, int configuration);
+int usb_get_report(struct usb_device *dev);
+
+/*
+ * Debugging helpers..
+ */
+void usb_show_device_descriptor(struct usb_device_descriptor *);
+void usb_show_config_descriptor(struct usb_config_descriptor *);
+void usb_show_interface_descriptor(struct usb_interface_descriptor *);
+void usb_show_endpoint_descriptor(struct usb_endpoint_descriptor *);
+void usb_show_hub_descriptor(struct usb_hub_descriptor *);
+void usb_show_device(struct usb_device *);
+
+/*
+ * Audio parsing helpers
+ */
+
+#ifdef CONFIG_USB_AUDIO
+void usb_audio_interface(struct usb_interface_descriptor *, u8 *);
+void usb_audio_endpoint(struct usb_endpoint_descriptor *, u8 *);
+#else
+extern inline void usb_audio_interface(struct usb_interface_descriptor *, u8 *) {}
+extern inline void usb_audio_endpoint(struct usb_endpoint_descriptor *, u8 *) {}
+#endif
+
+#endif
+
diff -u --recursive --new-file v2.2.6/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c
--- v2.2.6/linux/drivers/video/atyfb.c	Tue Mar 23 14:35:48 1999
+++ linux/drivers/video/atyfb.c	Thu Apr 22 19:30:08 1999
@@ -1,4 +1,4 @@
-/*  $Id: atyfb.c,v 1.103 1999/03/09 14:01:44 davem Exp $
+/*  $Id: atyfb.c,v 1.106 1999/04/16 11:20:49 geert Exp $
X  *  linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
X  *
X  *	Copyright (C) 1997-1998  Geert Uytterhoeven
@@ -385,7 +385,6 @@
X #endif
X void atyfb_setup(char *options, int *ints);
X 
-
X static int currcon = 0;
X 
X static struct fb_ops atyfb_ops = {
@@ -779,7 +778,8 @@
X 		return;
X 
X #ifdef __sparc__
-	if (fb->mmaped && currcon == fb->vtconsole)
+	if (fb->mmaped && (!fb->fb_info.display_fg
+	    || fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 		return;
X #endif
X 
@@ -806,7 +806,8 @@
X 		return;
X 
X #ifdef __sparc__
-	if (fb->mmaped && currcon == fb->vtconsole)
+	if (fb->mmaped && (!fb->fb_info.display_fg
+	    || fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 		return;
X #endif
X 
@@ -840,7 +841,8 @@
X 		return;
X 
X #ifdef __sparc__
-	if (fb->mmaped && currcon == fb->vtconsole)
+	if (fb->mmaped && (!fb->fb_info.display_fg
+	    || fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 		return;
X #endif
X 
@@ -910,7 +912,8 @@
X 		return;
X 
X #ifdef __sparc__
-	if (fb->mmaped && currcon == fb->vtconsole)
+	if (fb->mmaped && (!fb->fb_info.display_fg
+	    || fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 		return;
X #endif
X 
@@ -1644,30 +1647,24 @@
X     	pll_ext_cntl = mpostdiv;	/* xclk == mclk */
X 
X     switch (vclk_post_div) {
-	case 1:
-	    vpostdiv = 0;
-	    break;
X 	case 2:
X 	    vpostdiv = 1;
X 	    break;
X 	case 3:
-	    vpostdiv = 0;
X 	    pll_ext_cntl |= 0x10;
+	case 1:
+	    vpostdiv = 0;
X 	    break;
+	case 6:
+	    pll_ext_cntl |= 0x10;
X 	case 4:
X 	    vpostdiv = 2;
X 	    break;
-	case 6:
-	    vpostdiv = 2;
+	case 12:
X 	    pll_ext_cntl |= 0x10;
-	    break;
X 	case 8:
X 	    vpostdiv = 3;
X 	    break;
-	case 12:
-	    vpostdiv = 3;
-	    pll_ext_cntl |= 0x10;
-	    break;
X     }
X     vclk_post_div = vpostdiv;
X 
@@ -1690,7 +1687,7 @@
X 	1, 2, 4, 8,
X 	3, 0, 6, 12
X     };
-    u8 vpostdiv = vclk_post_div_tab[((pll_ext_cntl & 0x10) >> 1) |
+    u8 vpostdiv = vclk_post_div_tab[((pll_ext_cntl & 0x10) >> 2) |
X 				    (vclk_post_div & 3)];
X     if (vpostdiv == 0)
X 	return -EINVAL;
@@ -2114,7 +2111,8 @@
X 	    if (info->fb_info.changevar)
X 		(*info->fb_info.changevar)(con);
X 	}
-	if (con == currcon)
+	if (!info->fb_info.display_fg ||
+	    info->fb_info.display_fg->vc_num == con)
X 	    atyfb_set_par(&par, info);
X 	if (oldbpp != var->bits_per_pixel) {
X 	    if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
@@ -2159,7 +2157,7 @@
X static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
X 			  struct fb_info *info)
X {
-    if (con == currcon) /* current console? */
+    if (!info->display_fg || con == info->display_fg->vc_num) /* current console? */
X 	return fb_get_cmap(cmap, kspc, atyfb_getcolreg, info);
X     else if (fb_display[con].cmap.len) /* non default colormap? */
X 	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
@@ -2178,16 +2176,21 @@
X 			  struct fb_info *info)
X {
X     int err;
+    struct display *disp;
X 
-    if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
-	int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
-	if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0)))
+    if (con >= 0)
+    	disp = &fb_display[con];
+    else
+        disp = info->disp;
+    if (!disp->cmap.len) {	/* no colormap allocated? */
+	int size = disp->var.bits_per_pixel == 16 ? 32 : 256;
+	if ((err = fb_alloc_cmap(&disp->cmap, size, 0)))
X 	    return err;
X     }
-    if (con == currcon)			/* current console? */
+    if (!info->display_fg || con == info->display_fg->vc_num)			/* current console? */
X 	return fb_set_cmap(cmap, kspc, atyfb_setcolreg, info);
X     else
-	fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+	fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
X     return 0;
X }
X 
@@ -2198,6 +2201,12 @@
X #ifdef __sparc__
X     struct fb_info_aty *fb = (struct fb_info_aty *)info;
X     struct fbtype fbtyp;
+    struct display *disp;
+    
+    if (con >= 0)
+    	disp = &fb_display[con];
+    else
+        disp = info->disp;
X 
X     switch (cmd) {
X     case FBIOGTYPE:
@@ -2205,7 +2214,7 @@
X 	fbtyp.fb_width = fb->current_par.crtc.vxres;
X 	fbtyp.fb_height = fb->current_par.crtc.vyres;
X 	fbtyp.fb_depth = fb->current_par.crtc.bpp;
-	fbtyp.fb_cmsize = fb_display[con].cmap.len;
+	fbtyp.fb_cmsize = disp->cmap.len;
X 	fbtyp.fb_size = fb->total_vram;
X 	copy_to_user_ret((struct fbtype *)arg, &fbtyp, sizeof(fbtyp), -EFAULT);
X 	break;
@@ -2785,7 +2794,7 @@
X 	     */
X 	    for (i = 0; i < 6 && pdev->base_address[i]; i++)
X 		/* nothing */;
-	    j = i + 3;
+	    j = i + 4;
X 
X 	    info->mmap_map = kmalloc(j * sizeof(*info->mmap_map), GFP_ATOMIC);
X 	    if (!info->mmap_map) {
@@ -2813,15 +2822,33 @@
X 			size &= ~1;
X 		size = ~(size) + 1;
X 
+		/*
+		 * Map the framebuffer a second time, this time without
+		 * the braindead _PAGE_IE setting. This is used by the
+		 * fixed Xserver, but we need to maintain the old mapping
+		 * to stay compatible with older ones...
+		 */
+		if (base == addr) {
+		    info->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK;
+		    info->mmap_map[j].poff = __pa(base & PAGE_MASK);
+		    info->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
+		    info->mmap_map[j].prot_mask = _PAGE_CACHE;
+		    info->mmap_map[j].prot_flag = _PAGE_E;
+		    j++;
+		}
+
+		/*
+		 * Here comes the old framebuffer mapping with _PAGE_IE
+		 * set for the big endian half of the framebuffer...
+		 */
X 		if (base == addr) {
-			info->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK;
-			info->mmap_map[j].poff = __pa((base + 0x800000)
-								& PAGE_MASK);
-			info->mmap_map[j].size = 0x800000;
-			info->mmap_map[j].prot_mask = _PAGE_CACHE;
-			info->mmap_map[j].prot_flag = _PAGE_E|_PAGE_IE;
-			size -= 0x800000;
-			j++;
+		    info->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK;
+		    info->mmap_map[j].poff = __pa((base+0x800000) & PAGE_MASK);
+		    info->mmap_map[j].size = 0x800000;
+		    info->mmap_map[j].prot_mask = _PAGE_CACHE;
+		    info->mmap_map[j].prot_flag = _PAGE_E|_PAGE_IE;
+		    size -= 0x800000;
+		    j++;
X 		}
X 
X 		info->mmap_map[j].voff = pbase & PAGE_MASK;
@@ -3556,7 +3583,8 @@
X #ifdef __sparc__
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
@@ -3578,7 +3606,8 @@
X #ifdef __sparc__
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
@@ -3602,7 +3631,8 @@
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
X #ifdef __sparc__
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
@@ -3618,7 +3648,8 @@
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
X #ifdef __sparc__
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
@@ -3633,7 +3664,8 @@
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
X #ifdef __sparc__
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
@@ -3656,7 +3688,8 @@
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
X #ifdef __sparc__
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
@@ -3672,7 +3705,8 @@
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
X #ifdef __sparc__
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
@@ -3687,7 +3721,8 @@
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
X #ifdef __sparc__
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
@@ -3710,7 +3745,8 @@
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
X #ifdef __sparc__
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
@@ -3726,7 +3762,8 @@
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
X #ifdef __sparc__
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
@@ -3741,7 +3778,8 @@
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
X #ifdef __sparc__
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
@@ -3764,7 +3802,8 @@
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
X #ifdef __sparc__
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
@@ -3780,7 +3819,8 @@
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
X #ifdef __sparc__
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
@@ -3795,7 +3835,8 @@
X     struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
X 
X #ifdef __sparc__
-    if (fb->mmaped && currcon == fb->vtconsole)
+    if (fb->mmaped && (!fb->fb_info.display_fg
+	|| fb->fb_info.display_fg->vc_num == fb->vtconsole))
X 	return;
X #endif
X 
diff -u --recursive --new-file v2.2.6/linux/drivers/video/creatorfb.c linux/drivers/video/creatorfb.c
--- v2.2.6/linux/drivers/video/creatorfb.c	Tue Mar 23 14:35:48 1999
+++ linux/drivers/video/creatorfb.c	Thu Apr 22 19:30:08 1999
@@ -1,4 +1,4 @@
-/* $Id: creatorfb.c,v 1.26 1999/03/11 00:29:54 davem Exp $
+/* $Id: creatorfb.c,v 1.27 1999/03/28 12:37:12 jj Exp $
X  * creatorfb.c: Creator/Creator3D frame buffer driver
X  *
X  * Copyright (C) 1997,1998,1999 Jakub Jelinek (j...@ultra.linux.cz)
@@ -718,6 +718,11 @@
X 	i = prom_getintdefault (fb->prom_node, "board_type", 8);
X 	                                                        
X 	sprintf(idstring, "%s at %016lx type %d DAC %d", fix->id, regs[0].phys_addr, i, fb->s.ffb.dac_rev);
+	
+	/* Elite3D has different DAC revision numbering, and no DAC revisions
+	   have the reversed meaning of cursor enable */
+	if (afb)
+		fb->s.ffb.dac_rev = 10;
X 	
X 	return idstring;
X }
diff -u --recursive --new-file v2.2.6/linux/drivers/video/fbcon-cfb2.c linux/drivers/video/fbcon-cfb2.c
--- v2.2.6/linux/drivers/video/fbcon-cfb2.c	Wed Mar 10 15:29:48 1999
+++ linux/drivers/video/fbcon-cfb2.c	Wed Apr 28 08:48:45 1999
@@ -50,7 +50,7 @@
X 
X void fbcon_cfb2_setup(struct display *p)
X {
-    p->next_line = p->var.xres_virtual>>2;
+    p->next_line = p->line_length ? p->line_length : p->var.xres_virtual>>2;
X     p->next_plane = 0;
X }
X 
diff -u --recursive --new-file v2.2.6/linux/drivers/video/fbcon-cfb4.c linux/drivers/video/fbcon-cfb4.c
--- v2.2.6/linux/drivers/video/fbcon-cfb4.c	Wed Mar 10 15:29:48 1999
+++ linux/drivers/video/fbcon-cfb4.c	Wed Apr 28 08:48:45 1999
@@ -50,7 +50,7 @@
X 
X void fbcon_cfb4_setup(struct display *p)
X {
-    p->next_line = p->var.xres_virtual>>1;
+    p->next_line = p->line_length ? p->line_length : p->var.xres_virtual>>1;
X     p->next_plane = 0;
X }
X 
diff -u --recursive --new-file v2.2.6/linux/drivers/video/fbcon.c linux/drivers/video/fbcon.c
--- v2.2.6/linux/drivers/video/fbcon.c	Mon Mar 29 11:09:11 1999
+++ linux/drivers/video/fbcon.c	Thu Apr 22 19:30:08 1999
@@ -1700,6 +1700,7 @@
X     	    fb_display[i].fontdata &&
X     	    FNTSUM(fb_display[i].fontdata) == k &&
X     	    FNTSIZE(fb_display[i].fontdata) == size &&
+    	    fontwidth(&fb_display[i]) == w &&
X 	    !memcmp(fb_display[i].fontdata, new_data, size)) {
X 	    kfree(new_data - FONT_EXTRA_WORDS*sizeof(int));
X 	    new_data = fb_display[i].fontdata;
@@ -1961,7 +1962,7 @@
X     /* Return if the frame buffer is not mapped */
X     if (!fb)
X 	return 0;
-
+	
X     /* Set colors if visual is PSEUDOCOLOR and we have enough colors, or for
X      * DIRECTCOLOR */
X     if ((p->visual == FB_VISUAL_PSEUDOCOLOR && depth >= 4) ||
@@ -2013,6 +2014,9 @@
X 	logo = linux_logo_bw;
X 	logo_depth = 1;
X     }
+    
+    if (p->fb_info->fbops->fb_rasterimg)
+    	p->fb_info->fbops->fb_rasterimg(p->fb_info, 1);
X 
X     for (x = 0; x < smp_num_cpus * (LOGO_W + 8) &&
X     	 x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
@@ -2039,12 +2043,18 @@
X 			val = (*src << redshift) |
X 			      (*src << greenshift) |
X 			      (*src << blueshift);
+			if (bdepth == 4 && !((long)dst & 3)) {
+			    /* Some cards require 32bit access */
+			    *(u32 *)dst = val;
+			    dst += 4;
+			} else {
X #ifdef __LITTLE_ENDIAN
-			for( i = 0; i < bdepth; ++i )
+			    for( i = 0; i < bdepth; ++i )
X #else
-			for( i = bdepth-1; i >= 0; --i )
+			    for( i = bdepth-1; i >= 0; --i )
X #endif
-			    *dst++ = val >> (i*8);
+			        *dst++ = val >> (i*8);
+			}
X 		    }
X 		}
X 	    }
@@ -2107,12 +2117,18 @@
X 		    val = safe_shift((linux_logo_red[*src-32]   & redmask), redshift) |
X 		          safe_shift((linux_logo_green[*src-32] & greenmask), greenshift) |
X 		          safe_shift((linux_logo_blue[*src-32]  & bluemask), blueshift);
+		    if (bdepth == 4 && !((long)dst & 3)) {
+			/* Some cards require 32bit access */
+			*(u32 *)dst = val;
+			dst += 4;
+		    } else {
X #ifdef __LITTLE_ENDIAN
-		    for( i = 0; i < bdepth; ++i )
+			for( i = 0; i < bdepth; ++i )
X #else
-		    for( i = bdepth-1; i >= 0; --i )
+			for( i = bdepth-1; i >= 0; --i )
X #endif
-			*dst++ = val >> (i*8);
+			    *dst++ = val >> (i*8);
+		    }
X 		}
X 	    }
X 	    done = 1;
@@ -2223,6 +2239,9 @@
X #endif
X     }
X     
+    if (p->fb_info->fbops->fb_rasterimg)
+    	p->fb_info->fbops->fb_rasterimg(p->fb_info, 0);
+
X     /* Modes not yet supported: packed pixels with depth != 8 (does such a
X      * thing exist in reality?) */
X 
diff -u --recursive --new-file v2.2.6/linux/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- v2.2.6/linux/drivers/video/fbmem.c	Tue Mar 23 14:35:48 1999
+++ linux/drivers/video/fbmem.c	Thu Apr 22 19:30:08 1999
@@ -203,17 +203,24 @@
X static int last_fb_vc = MAX_NR_CONSOLES-1;
X static int fbcon_is_default = 1;
X 
-static inline int PROC_CONSOLE(void)
+static int PROC_CONSOLE(struct fb_info *info)
X {
+	int fgc;
+	
+	if (info->display_fg != NULL)
+		fgc = info->display_fg->vc_num;
+	else
+		return -1;
+		
X 	if (!current->tty)
-		return fg_console;
+		return fgc;
X 
X 	if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
X 		/* XXX Should report error here? */
-		return fg_console;
+		return fgc;
X 
X 	if (MINOR(current->tty->device) < 1)
-		return fg_console;
+		return fgc;
X 
X 	return MINOR(current->tty->device) - 1;
X }
@@ -248,7 +255,7 @@
X 	if (! fb || ! info->disp)
X 		return -ENODEV;
X 
-	fb->fb_get_fix(&fix,PROC_CONSOLE(), info);
+	fb->fb_get_fix(&fix,PROC_CONSOLE(info), info);
X 	base_addr=info->disp->screen_base;
X 	copy_size=(count + p <= fix.smem_len ? count : fix.smem_len - p);
X 	if (copy_to_user(buf, base_addr+p, copy_size))
@@ -272,7 +279,7 @@
X 	if (! fb || ! info->disp)
X 		return -ENODEV;
X 
-	fb->fb_get_fix(&fix, PROC_CONSOLE(), info);
+	fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
X 	base_addr=info->disp->screen_base;
X 	copy_size=(count + p <= fix.smem_len ? count : fix.smem_len - p);
X 	if (copy_from_user(base_addr+p, buf, copy_size))
@@ -288,7 +295,7 @@
X     int unit, err;
X 
X     var->activate |= FB_ACTIVATE_TEST;
-    err = fb->fb_set_var(var, PROC_CONSOLE(), info);
+    err = fb->fb_set_var(var, PROC_CONSOLE(info), info);
X     var->activate &= ~FB_ACTIVATE_TEST;
X     if (err)
X 	    return err;
@@ -365,7 +372,7 @@
X 		return -ENODEV;
X 	switch (cmd) {
X 	case FBIOGET_VSCREENINFO:
-		if ((i = fb->fb_get_var(&var, PROC_CONSOLE(), info)))
+		if ((i = fb->fb_get_var(&var, PROC_CONSOLE(info), info)))
X 			return i;
X 		return copy_to_user((void *) arg, &var,
X 				    sizeof(var)) ? -EFAULT : 0;
@@ -374,29 +381,29 @@
X 			return -EFAULT;
X 		i = var.activate & FB_ACTIVATE_ALL
X 			    ? set_all_vcs(fbidx, fb, &var, info)
-			    : fb->fb_set_var(&var, PROC_CONSOLE(), info);
+			    : fb->fb_set_var(&var, PROC_CONSOLE(info), info);
X 		if (i)
X 			return i;
X 		if (copy_to_user((void *) arg, &var, sizeof(var)))
X 			return -EFAULT;
X 		return 0;
X 	case FBIOGET_FSCREENINFO:
-		if ((i = fb->fb_get_fix(&fix, PROC_CONSOLE(), info)))
+		if ((i = fb->fb_get_fix(&fix, PROC_CONSOLE(info), info)))
X 			return i;
X 		return copy_to_user((void *) arg, &fix, sizeof(fix)) ?
X 			-EFAULT : 0;
X 	case FBIOPUTCMAP:
X 		if (copy_from_user(&cmap, (void *) arg, sizeof(cmap)))
X 			return -EFAULT;
-		return (fb->fb_set_cmap(&cmap, 0, PROC_CONSOLE(), info));
+		return (fb->fb_set_cmap(&cmap, 0, PROC_CONSOLE(info), info));
X 	case FBIOGETCMAP:
X 		if (copy_from_user(&cmap, (void *) arg, sizeof(cmap)))
X 			return -EFAULT;
-		return (fb->fb_get_cmap(&cmap, 0, PROC_CONSOLE(), info));
+		return (fb->fb_get_cmap(&cmap, 0, PROC_CONSOLE(info), info));
X 	case FBIOPAN_DISPLAY:
X 		if (copy_from_user(&var, (void *) arg, sizeof(var)))
X 			return -EFAULT;
-		if ((i=fb->fb_pan_display(&var, PROC_CONSOLE(), info)))
+		if ((i=fb->fb_pan_display(&var, PROC_CONSOLE(info), info)))
X 			return i;
X 		if (copy_to_user((void *) arg, &var, sizeof(var)))
X 			return -EFAULT;
@@ -430,7 +437,7 @@
X 			set_con2fb_map(i, con2fb.framebuffer);
X 		return 0;
X 	default:
-		return fb->fb_ioctl(inode, file, cmd, arg, PROC_CONSOLE(),
+		return fb->fb_ioctl(inode, file, cmd, arg, PROC_CONSOLE(info),
X 				    info);
X 	}
X }
@@ -450,7 +457,7 @@
X 		return -ENODEV;
X 	if (fb->fb_mmap)
X 		return fb->fb_mmap(info, file, vma);
-	fb->fb_get_fix(&fix, PROC_CONSOLE(), info);
+	fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
X 
X 	/* frame buffer memory */
X 	start = (unsigned long)fix.smem_start;
@@ -460,7 +467,7 @@
X 	if (vma->vm_offset >= len) {
X 		/* memory mapped io */
X 		vma->vm_offset -= len;
-		fb->fb_get_var(&var, PROC_CONSOLE(), info);
+		fb->fb_get_var(&var, PROC_CONSOLE(info), info);
X 		if (var.accel_flags)
X 			return -EINVAL;
X 		start = (unsigned long)fix.mmio_start;
diff -u --recursive --new-file v2.2.6/linux/drivers/video/leofb.c linux/drivers/video/leofb.c
--- v2.2.6/linux/drivers/video/leofb.c	Tue Mar 23 14:35:48 1999
+++ linux/drivers/video/leofb.c	Thu Apr 22 19:30:08 1999
@@ -1,7 +1,7 @@
-/* $Id: leofb.c,v 1.5 1999/03/09 14:02:29 davem Exp $
+/* $Id: leofb.c,v 1.6 1999/04/01 13:03:25 jj Exp $
X  * leofb.c: Leo (ZX) 24/8bit frame buffer driver
X  *
- * Copyright (C) 1996,1997,1998 Jakub Jelinek (j...@ultra.linux.cz)
+ * Copyright (C) 1996-1999 Jakub Jelinek (j...@ultra.linux.cz)
X  * Copyright (C) 1997 Michal Rehacek (Michal....@st.mff.cuni.cz)
X  */
X 
@@ -80,12 +80,12 @@
X 
X struct leo_lc_ss0_usr {
X 	volatile u32	csr;
-	volatile u32	attrs;
-	volatile u32 	fontc;
-	volatile u32	fontc2;
+	volatile u32	addrspace;
+	volatile u32 	fontmsk;
+	volatile u32	fontt;
X 	volatile u32	extent;
X 	volatile u32	src;
-	u32		xxx1[1];
+	u32		dst;
X 	volatile u32	copy;
X 	volatile u32	fill;
X };
@@ -98,19 +98,42 @@
X 	u8	unknown;
X };
X 
-struct leo_ld_ss0 {
+struct leo_ld {
X 	u8		xxx0[0xe00];
-	u32		xxx1[2];
-	volatile u32	unk;
-	u32		xxx2[1];
-	volatile u32	unk2;
-	volatile u32	unk3;
-	u32		xxx3[2];
+	volatile u32	csr;
+	volatile u32	wid;
+	volatile u32	wmask;
+	volatile u32	widclip;
+	volatile u32	vclipmin;
+	volatile u32	vclipmax;
+	volatile u32	pickmin;	/* SS1 only */
+	volatile u32	pickmax;	/* SS1 only */
X 	volatile u32	fg;
X 	volatile u32	bg;
-	u8		xxx4[0x05c];
+	volatile u32	src;		/* Copy/Scroll (SS0 only) */
+	volatile u32	dst;		/* Copy/Scroll/Fill (SS0 only) */
+	volatile u32	extent;		/* Copy/Scroll/Fill size (SS0 only) */
+	u32		xxx1[3];
+	volatile u32	setsem;		/* SS1 only */
+	volatile u32	clrsem;		/* SS1 only */
+	volatile u32	clrpick;	/* SS1 only */
+	volatile u32	clrdat;		/* SS1 only */
+	volatile u32	alpha;		/* SS1 only */
+	u8		xxx2[0x2c];
+	volatile u32	winbg;
X 	volatile u32	planemask;
X 	volatile u32	rop;
+	volatile u32	z;
+	volatile u32	dczf;		/* SS1 only */
+	volatile u32	dczb;		/* SS1 only */
+	volatile u32	dcs;		/* SS1 only */
+	volatile u32	dczs;		/* SS1 only */
+	volatile u32	pickfb;		/* SS1 only */
+	volatile u32	pickbb;		/* SS1 only */
+	volatile u32	dcfc;		/* SS1 only */
+	volatile u32	forcecol;	/* SS1 only */
+	volatile u32	door[8];	/* SS1 only */
+	volatile u32	pick[5];	/* SS1 only */
X };
X 
X #define LEO_SS1_MISC_ENABLE	0x00000001
@@ -126,17 +149,17 @@
X 
X static struct sbus_mmap_map leo_mmap_map[] = {
X 	{ LEO_SS0_MAP,		LEO_OFF_SS0,		0x800000	},
-	{ LEO_LC_SS0_USR_MAP,	LEO_OFF_LC_SS0_USR,	PAGE_SIZE	},
-	{ LEO_LD_SS0_MAP,	LEO_OFF_LD_SS0,		PAGE_SIZE	},
-	{ LEO_LX_CURSOR_MAP,	LEO_OFF_LX_CURSOR,	PAGE_SIZE	},
+	{ LEO_LC_SS0_USR_MAP,	LEO_OFF_LC_SS0_USR,	0x1000		},
+	{ LEO_LD_SS0_MAP,	LEO_OFF_LD_SS0,		0x1000		},
+	{ LEO_LX_CURSOR_MAP,	LEO_OFF_LX_CURSOR,	0x1000		},
X 	{ LEO_SS1_MAP,		LEO_OFF_SS1,		0x800000	},
-	{ LEO_LC_SS1_USR_MAP,	LEO_OFF_LC_SS1_USR,	PAGE_SIZE	},
-	{ LEO_LD_SS1_MAP,	LEO_OFF_LD_SS1,		PAGE_SIZE	},
-	{ LEO_UNK_MAP,		LEO_OFF_UNK,		PAGE_SIZE	},
-	{ LEO_LX_KRN_MAP,	LEO_OFF_LX_KRN,		PAGE_SIZE	},
-	{ LEO_LC_SS0_KRN_MAP,	LEO_OFF_LC_SS0_KRN,	PAGE_SIZE	},
-	{ LEO_LC_SS1_KRN_MAP,	LEO_OFF_LC_SS1_KRN,	PAGE_SIZE	},
-	{ LEO_LD_GBL_MAP,	LEO_OFF_LD_GBL,		PAGE_SIZE	},
+	{ LEO_LC_SS1_USR_MAP,	LEO_OFF_LC_SS1_USR,	0x1000		},
+	{ LEO_LD_SS1_MAP,	LEO_OFF_LD_SS1,		0x1000		},
+	{ LEO_UNK_MAP,		LEO_OFF_UNK,		0x1000		},
+	{ LEO_LX_KRN_MAP,	LEO_OFF_LX_KRN,		0x1000		},
+	{ LEO_LC_SS0_KRN_MAP,	LEO_OFF_LC_SS0_KRN,	0x1000		},
+	{ LEO_LC_SS1_KRN_MAP,	LEO_OFF_LC_SS1_KRN,	0x1000		},
+	{ LEO_LD_GBL_MAP,	LEO_OFF_LD_GBL,		0x1000		},
X 	{ LEO_UNK2_MAP,		LEO_OFF_UNK2,		0x100000	},
X 	{ 0,			0,			0	  	}
X };
@@ -152,19 +175,14 @@
X {
X 	struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
X 	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;
-	register struct leo_ld_ss0 *ss = fb->s.leo.ld_ss0;
+	register struct leo_ld *ss = fb->s.leo.ld_ss0;
X 	int x, y, w, h;
X 	int i;
X 
X 	do {
X 		i = us->csr;
X 	} while (i & 0x20000000);
-	ss->unk = 0xffff;
-	ss->unk2 = 0;
-	ss->unk3 = fb->s.leo.extent;
-	ss->fg = (attr_bgcol_ec(p,conp)<<24) | 0x030703;
-	ss->planemask = 0xff000000;
-	ss->rop = 0xd0840;
+	ss->fg = (attr_bgcol_ec(p,conp)<<24);
X 	if (fontheightlog(p)) {
X 		y = sy << fontheightlog(p); h = height << fontheightlog(p);
X 	} else {
@@ -176,9 +194,8 @@
X 		x = sx * fontwidth(p); w = width * fontwidth(p);
X 	}
X 	us->extent = (w - 1) | ((h - 1) << 11);
-	i = us->attrs;
X 	us->fill = (x + fb->x_margin) | ((y + fb->y_margin) << 11) |
-		   ((i & 3) << 29) | ((i & 8) ? 0x80000000 : 0);
+		   0x80000000;
X }
X 
X static void leo_fill(struct fb_info_sbusfb *fb, struct display *p, int s,
@@ -186,23 +203,17 @@
X {
X 	int i;
X 	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;
-	register struct leo_ld_ss0 *ss = fb->s.leo.ld_ss0;
+	register struct leo_ld *ss = fb->s.leo.ld_ss0;
X 	
-	do {
-		i = us->csr;
-	} while (i & 0x20000000);
-	ss->unk = 0xffff;
-	ss->unk2 = 0;
-	ss->unk3 = fb->s.leo.extent;
-	ss->fg = (attr_bgcol(p,s)<<24) | 0x030703;
-	ss->planemask = 0xff000000;
-	ss->rop = 0xd0840;
+	ss->fg = (attr_bgcol(p,s)<<24);
X 	while (count-- > 0) {
+		do {
+			i = us->csr;
+		} while (i & 0x20000000);
X 		us->extent = (boxes[2] - boxes[0] - 1) | 
X 			     ((boxes[3] - boxes[1] - 1) << 11);
-		i = us->attrs;
-		us->fill = boxes[0] | (boxes[1] << 11) |
-			   ((i & 3) << 29) | ((i & 8) ? 0x80000000 : 0);
+		us->fill = boxes[0] | (boxes[1] << 11) | 0x80000000;
+		boxes += 4;
X 	}
X }
X 
@@ -210,7 +221,7 @@
X {
X 	struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
X 	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;
-	register struct leo_ld_ss0 *ss = fb->s.leo.ld_ss0;
+	register struct leo_ld *ss = fb->s.leo.ld_ss0;
X 	int i, x, y;
X 	u8 *fd;
X 	u32 *u;
@@ -235,11 +246,7 @@
X 	} while (i & 0x20000000);
X 	ss->fg = attr_fgcol(p,c) << 24;
X 	ss->bg = attr_bgcol(p,c) << 24;
-	ss->rop = 0x310040;
-	ss->planemask = 0xff000000;
-	us->fontc2 = 0xFFFFFFFE;
-	us->attrs = 4;
-	us->fontc = 0xFFFFFFFF<<(32-fontwidth(p));
+	us->fontmsk = 0xFFFFFFFF<<(32-fontwidth(p));
X 	u = ((u32 *)p->screen_base) + y + x;
X 	if (fontwidth(p) <= 8) {
X 		for (i = 0; i < fontheight(p); i++, u += 2048)
@@ -257,7 +264,7 @@
X {
X 	struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
X 	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;
-	register struct leo_ld_ss0 *ss = fb->s.leo.ld_ss0;
+	register struct leo_ld *ss = fb->s.leo.ld_ss0;
X 	int i, x, y;
X 	u8 *fd1, *fd2, *fd3, *fd4;
X 	u32 *u;
@@ -267,11 +274,7 @@
X 	} while (i & 0x20000000);
X 	ss->fg = attr_fgcol(p,scr_readw(s)) << 24;
X 	ss->bg = attr_bgcol(p,scr_readw(s)) << 24;
-	ss->rop = 0x310040;
-	ss->planemask = 0xff000000;
-	us->fontc2 = 0xFFFFFFFE;
-	us->attrs = 4;
-	us->fontc = 0xFFFFFFFF<<(32-fontwidth(p));
+	us->fontmsk = 0xFFFFFFFF<<(32-fontwidth(p));
X 	if (fontwidthlog(p))
X 		x = (xx << fontwidthlog(p));
X 	else
@@ -282,7 +285,7 @@
X 		y = (yy * fontheight(p)) << 11;
X 	u = ((u32 *)p->screen_base) + y + x;
X 	if (fontwidth(p) <= 8) {
-		us->fontc = 0xFFFFFFFF<<(32-4*fontwidth(p));
+		us->fontmsk = 0xFFFFFFFF<<(32-4*fontwidth(p));
X 		x = 4*fontwidth(p) - fontheight(p)*2048;
X 		while (count >= 4) {
X 			count -= 4;
@@ -310,7 +313,7 @@
X 			}
X 		}
X 	} else {
-		us->fontc = 0xFFFFFFFF<<(32-2*fontwidth(p));
+		us->fontmsk = 0xFFFFFFFF<<(32-2*fontwidth(p));
X 		x = 2*fontwidth(p) - fontheight(p)*2048;
X 		while (count >= 2) {
X 			count -= 2;
@@ -328,7 +331,7 @@
X 			u += x;
X 		}
X 	}
-	us->fontc = 0xFFFFFFFF<<(32-fontwidth(p));
+	us->fontmsk = 0xFFFFFFFF<<(32-fontwidth(p));
X 	x = fontwidth(p) - fontheight(p)*2048;
X 	while (count) {
X 		count--;
@@ -457,8 +460,8 @@
X 		fb->s.leo.lx_krn->krn_csr |= LEO_KRN_CSR_ENABLE;
X }
X 
-__initfunc(static int
-leo_wid_put (struct fb_info_sbusfb *fb, struct fb_wid_list *wl))
+static int __init
+leo_wid_put (struct fb_info_sbusfb *fb, struct fb_wid_list *wl)
X {
X 	struct leo_lx_krn *lx_krn = fb->s.leo.lx_krn;
X 	struct fb_wid_item *wi;
@@ -476,6 +479,8 @@
X 		lx_krn->krn_type = 0x5800 + j;
X 		lx_krn->krn_value = wi->wi_values[0];
X 	}
+	lx_krn->krn_type = LEO_KRN_TYPE_WID;
+	lx_krn->krn_csr = 3;
X 	return 0;
X }
X 
@@ -484,9 +489,43 @@
X 	p->screen_base += 8192 * (y_margin - fb->y_margin) + 4 * (x_margin - fb->x_margin);
X }
X 
+static void leo_switch_from_graph (struct fb_info_sbusfb *fb)
+{
+	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;
+	register struct leo_ld *ss = fb->s.leo.ld_ss0;
+
+	ss->wid = 0xffffffff;	
+	ss->wmask = 0xffff;
+	ss->vclipmin = 0;
+	ss->vclipmax = fb->s.leo.extent;
+	ss->planemask = 0xff000000;
+	ss->rop = 0x310850;
+	ss->widclip = 0;
+	us->addrspace = 4;
+	us->fontt = 0;
+}
+
+static void __init leo_rasterimg (struct fb_info_sbusfb *fb, int start)
+{
+	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;
+	register struct leo_ld *ss = fb->s.leo.ld_ss0;
+
+	if (start) {
+		ss->wid = 1;
+		ss->planemask = 0xffffff;
+		ss->rop = 0x310b90;
+		us->addrspace = 0;
+	} else {
+		ss->wid = 0xffffffff;
+		ss->planemask = 0xff000000;
+		ss->rop = 0x310850;
+		us->addrspace = 4;
+	}
+}
+
X static char idstring[40] __initdata = { 0 };
X 
-__initfunc(char *leofb_init(struct fb_info_sbusfb *fb))
+char * __init leofb_init(struct fb_info_sbusfb *fb)
X {
X 	struct fb_fix_screeninfo *fix = &fb->fix;
X 	struct fb_var_screeninfo *var = &fb->var;
@@ -496,44 +535,53 @@
X 	struct fb_wid_item wi;
X 	struct fb_wid_list wl;
X 	int i;
+	register struct leo_lc_ss0_usr *us;
+	register struct leo_ld *ss;
+	struct fb_ops *fbops;
X 
X 	strcpy(fb->info.modename, "Leo");
X 		
X 	strcpy(fix->id, "Leo");
-	fix->visual = 0xff; /* We only know how to do acceleration and know nothing
-	                       about the actual memory layout */
+	fix->visual = FB_VISUAL_TRUECOLOR;
X 	fix->line_length = 8192;
X 	fix->accel = FB_ACCEL_SUN_LEO;
X 	
+	var->bits_per_pixel = 32;
+	var->green.offset = 8;
+	var->blue.offset = 16;
X 	var->accel_flags = FB_ACCELF_TEXT;
X 	
+	fbops = kmalloc(sizeof(*fbops), GFP_KERNEL);
+	if (!fbops) return NULL;
+	
+	*fbops = *fb->info.fbops;
+	fbops->fb_rasterimg = leo_rasterimg;
+	fb->info.fbops = fbops;
+	
X 	disp->scrollmode = SCROLL_YREDRAW;
X 	if (!disp->screen_base)
X 		disp->screen_base = (char *)sparc_alloc_io(phys + LEO_OFF_SS0, 0, 
X 			0x800000, "leo_ram", fb->iospace, 0);
X 	disp->screen_base += 8192 * fb->y_margin + 4 * fb->x_margin;
-	fb->s.leo.lc_ss0_usr = (struct leo_lc_ss0_usr *)
+	us = fb->s.leo.lc_ss0_usr = (struct leo_lc_ss0_usr *)
X 			sparc_alloc_io(phys + LEO_OFF_LC_SS0_USR, 0, 
-			PAGE_SIZE, "leo_lc_ss0_usr", fb->iospace, 0);
-	fb->s.leo.ld_ss0 = (struct leo_ld_ss0 *)
+			0x1000, "leo_lc_ss0_usr", fb->iospace, 0);
+	ss = fb->s.leo.ld_ss0 = (struct leo_ld *)
X 			sparc_alloc_io(phys + LEO_OFF_LD_SS0, 0, 
-			PAGE_SIZE, "leo_ld_ss0", fb->iospace, 0);
+			0x1000, "leo_ld_ss0", fb->iospace, 0);
X 	fb->s.leo.ld_ss1 = (struct leo_ld_ss1 *)
X 			sparc_alloc_io(phys + LEO_OFF_LD_SS1, 0, 
-			PAGE_SIZE, "leo_ld_ss1", fb->iospace, 0);
+			0x1000, "leo_ld_ss1", fb->iospace, 0);
X 	fb->s.leo.lx_krn = (struct leo_lx_krn *)
X 			sparc_alloc_io(phys + LEO_OFF_LX_KRN, 0, 
-			PAGE_SIZE, "leo_lx_krn", fb->iospace, 0);
+			0x1000, "leo_lx_krn", fb->iospace, 0);
X 	fb->s.leo.cursor = (struct leo_cursor *)
X 			sparc_alloc_io(phys + LEO_OFF_LX_CURSOR, 0, 
X 			sizeof(struct leo_cursor), "leo_lx_cursor", fb->iospace, 0);
X 	fb->dispsw = leo_dispsw;
-
+	
X 	fb->s.leo.extent = (type->fb_width-1) | ((type->fb_height-1) << 16);
X 
-	fb->s.leo.ld_ss0->unk = 0xffff;
-	fb->s.leo.ld_ss0->unk2 = 0;
-	fb->s.leo.ld_ss0->unk3 = fb->s.leo.extent;
X 	wl.wl_count = 1;
X 	wl.wl_list = &wi;
X 	wi.wi_type = FB_WID_DBL_8;
@@ -546,17 +594,27 @@
X 	wi.wi_index = 2;
X 	wi.wi_values [0] = 0x20;
X 	leo_wid_put (fb, &wl);
+	wi.wi_type = FB_WID_DBL_24;
+	wi.wi_index = 1;
+	wi.wi_values [0] = 0x30;
+	leo_wid_put (fb, &wl);
X 
X 	fb->s.leo.ld_ss1->ss1_misc |= LEO_SS1_MISC_ENABLE;
X 
-	fb->s.leo.ld_ss0->fg = 0x30703;
-	fb->s.leo.ld_ss0->planemask = 0xff000000;
-	fb->s.leo.ld_ss0->rop = 0xd0840;
-	fb->s.leo.lc_ss0_usr->extent = (type->fb_width-1) | ((type->fb_height-1) << 11);
-	i = fb->s.leo.lc_ss0_usr->attrs;
-	fb->s.leo.lc_ss0_usr->fill = (0) | ((0) << 11) | ((i & 3) << 29) | ((i & 8) ? 0x80000000 : 0);
+	ss->wid = 0xffffffff;
+	ss->wmask = 0xffff;
+	ss->vclipmin = 0;
+	ss->vclipmax = fb->s.leo.extent;
+	ss->fg = 0;
+	ss->planemask = 0xff000000;
+	ss->rop = 0x310850;
+	ss->widclip = 0;
+	us->extent = (type->fb_width-1) | ((type->fb_height-1) << 11);
+	us->addrspace = 4;
+	us->fill = 0x80000000;
+	us->fontt = 0;
X 	do {
-		i = fb->s.leo.lc_ss0_usr->csr;
+		i = us->csr;
X 	} while (i & 0x20000000);
X 
X 	fb->margins = leo_margins;
@@ -565,6 +623,7 @@
X 	fb->setcursormap = leo_setcursormap;
X 	fb->setcurshape = leo_setcurshape;
X 	fb->restore_palette = leo_restore_palette;
+	fb->switch_from_graph = leo_switch_from_graph;
X 	fb->fill = leo_fill;
X 	fb->blank = leo_blank;
X 	fb->unblank = leo_unblank;
diff -u --recursive --new-file v2.2.6/linux/drivers/video/matroxfb.c linux/drivers/video/matroxfb.c
--- v2.2.6/linux/drivers/video/matroxfb.c	Wed Mar 10 15:29:48 1999
+++ linux/drivers/video/matroxfb.c	Tue Apr 20 15:13:00 1999
@@ -4,7 +4,7 @@
X  *
X  * (c) 1998,1999 Petr Vandrovec <vand...@vc.cvut.cz>
X  *
- * Version: 1.9 1999/01/04
+ * Version: 1.15 1999/04/19
X  *
X  * MTRR stuff: 1998 Tom Rini <tmr...@ntplx.net>
X  *
@@ -24,6 +24,9 @@
X  *               "Daniel Haun" <ha...@usa.net>
X  *                     Testing, hardware cursor fixes
X  *
+ *               "Scott Wood" <saws...@pitt.edu>
+ *                     Fixes
+ *
X  *               "Gerd Knorr" <kra...@goldbach.isdn.cs.tu-berlin.de>
X  *                     Betatesting
X  *
@@ -452,7 +455,7 @@
X #define CPMINFO	const struct matrox_fb_info* minfo,
X #define PMINFO  minfo,
X 
-static inline struct matrox_fb_info* mxinfo(struct display* p) {
+static inline struct matrox_fb_info* mxinfo(const struct display* p) {
X 	return (struct matrox_fb_info*)p->fb_info;
X }
X 
@@ -474,7 +477,7 @@
X #define PMINFO
X 
X #if 0
-static inline struct matrox_fb_info* mxinfo(struct display* p) {
+static inline struct matrox_fb_info* mxinfo(const struct display* p) {
X 	return &global_mxinfo;
X }
X #endif
@@ -2191,7 +2194,7 @@
X 
X 	step = ACCESS_FBINFO(devflags.textstep);
X 	offs = yy * p->next_line + xx * step;
-	attr = attr_fgcol(p,scr_readw(s)) | (attr_bgcol(p,scr_readw(s)) << 4);
+	attr = attr_fgcol(p, scr_readw(s)) | (attr_bgcol(p, scr_readw(s)) << 4);
X 	while (count-- > 0) {
X 		unsigned int chr = ((scr_readw(s++)) & p->charmask) << 8;
X 		if (chr & 0x10000) chr ^= 0x10008;
@@ -2395,6 +2398,10 @@
X 
X 	DBG("initMatrox")
X 	
+	if (ACCESS_FBINFO(currcon_display) != p)
+		return;
+	if (p->dispsw && p->conp)
+		fb_con.con_cursor(p->conp, CM_ERASE);
X 	p->dispsw_data = NULL;
X 	if ((p->var.accel_flags & FB_ACCELF_TEXT) != FB_ACCELF_TEXT) {
X 		if (p->type == FB_TYPE_TEXT) {
@@ -4274,6 +4281,17 @@
X 	for (i = 0; i < 21; i++) {
X 		outTi3026(PMINFO DACseq[i], hw->DACreg[i]);
X 	}
+	if (oldhw) {
+		outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
+		oldhw->DACclk[0] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
+		oldhw->DACclk[3] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
+		outTi3026(PMINFO TVP3026_XPLLADDR, 0x15);
+		oldhw->DACclk[1] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
+		oldhw->DACclk[4] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
+		outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
+		oldhw->DACclk[2] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
+		oldhw->DACclk[5] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
+	}
X 	if (!oldhw || memcmp(hw->DACclk, oldhw->DACclk, 6)) {
X 		/* agrhh... setting up PLL is very slow on Millenium... */
X 		/* Mystique PLL is locked in few ms, but Millenium PLL lock takes about 0.15 s... */
@@ -5296,7 +5314,7 @@
X 		"MGA-G200 (AGP)"},
X 	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,	0xFF,
X 		0,			0,
-		DEVF_VIDEO64BIT | DEVF_SWAPS,
+		DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
X 		230000,
X 		&vbG200,
X 		"unknown G200 (AGP)"},
@@ -5743,20 +5761,26 @@
X }
X 
X #ifndef MODULE
+static int __init initialized = 0;
+
X __initfunc(void matroxfb_init(void))
X {
X 	DBG("matroxfb_init")
-#if defined(CONFIG_FB_OF)
-/* Nothing to do, must be called from offb */
-#else	
-	matrox_init();
-#endif
+	
+	if (!initialized) {
+		initialized = 1;
+		matrox_init();
+	}
X }
X 
X #if defined(CONFIG_FB_OF)
X __initfunc(int matrox_of_init(struct device_node *dp)) {
X 	DBG("matrox_of_init");
-	matrox_init();
+	
+	if (!initialized) {
+		initialized = 1;
+		matrox_init();
+	}
X 	if (!fb_list) return -ENXIO;
X 	return 0;
X }
diff -u --recursive --new-file v2.2.6/linux/drivers/video/promcon.c linux/drivers/video/promcon.c
--- v2.2.6/linux/drivers/video/promcon.c	Fri Apr 16 14:47:31 1999
+++ linux/drivers/video/promcon.c	Thu Apr 22 19:30:08 1999
@@ -1,4 +1,4 @@
-/* $Id: promcon.c,v 1.14 1999/03/09 14:02:42 davem Exp $
+/* $Id: promcon.c,v 1.15 1999/04/22 06:35:32 davem Exp $
X  * Console driver utilizing PROM sun terminal emulation
X  *
X  * Copyright (C) 1998  Eddie C. Dost  (e...@skynet.be)
diff -u --recursive --new-file v2.2.6/linux/drivers/video/sbusfb.c linux/drivers/video/sbusfb.c
--- v2.2.6/linux/drivers/video/sbusfb.c	Tue Mar 23 14:35:48 1999
+++ linux/drivers/video/sbusfb.c	Thu Apr 22 19:30:08 1999
@@ -520,7 +520,7 @@
X static int sbusfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
X 			 struct fb_info *info)
X {
-	if (con == currcon) /* current console? */
+	if (!info->display_fg || con == info->display_fg->vc_num) /* current console? */
X 		return fb_get_cmap(cmap, kspc, sbusfb_getcolreg, info);
X 	else if (fb_display[con].cmap.len) /* non default colormap? */
X 		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
@@ -537,9 +537,14 @@
X 			 struct fb_info *info)
X {
X 	int err;
+	struct display *disp;
X 
-	if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
-		if ((err = fb_alloc_cmap(&fb_display[con].cmap, 1<<fb_display[con].var.bits_per_pixel, 0)))
+	if (con >= 0)
+		disp = &fb_display[con];
+	else
+		disp = info->disp;
+	if (!disp->cmap.len) {	/* no colormap allocated? */
+		if ((err = fb_alloc_cmap(&disp->cmap, 1<<disp->var.bits_per_pixel, 0)))
X 			return err;
X 	}
X 	if (con == currcon) {			/* current console? */
@@ -552,7 +557,7 @@
X 		}
X 		return err;
X 	} else
-		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+		fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
X 	return 0;
X }
X 
diff -u --recursive --new-file v2.2.6/linux/fs/adfs/dir.c linux/fs/adfs/dir.c
--- v2.2.6/linux/fs/adfs/dir.c	Wed Aug 26 11:37:39 1998
+++ linux/fs/adfs/dir.c	Fri Apr 23 21:20:37 1999
@@ -280,8 +280,6 @@
X 	unsigned long parent_object_id, dir_object_id;
X 	int buffers, pos;
X 
-	if (!inode || !S_ISDIR(inode->i_mode))
-		return -EBADF;
X 	sb = inode->i_sb;
X 
X 	if (filp->f_pos > ADFS_NUM_DIR_ENTRIES + 2)
diff -u --recursive --new-file v2.2.6/linux/fs/adfs/namei.c linux/fs/adfs/namei.c
--- v2.2.6/linux/fs/adfs/namei.c	Tue Jan 20 16:44:58 1998
+++ linux/fs/adfs/namei.c	Fri Apr 23 21:20:37 1999
@@ -98,22 +98,22 @@
X 	return 0;
X }
X 
-int adfs_lookup (struct inode *dir, struct dentry *dentry)
+struct dentry *adfs_lookup (struct inode *dir, struct dentry *dentry)
X {
X 	struct inode *inode = NULL;
X 	struct adfs_idir_entry de;
X 	unsigned long ino;
X 
X 	if (dentry->d_name.len > ADFS_NAME_LEN)
-		return -ENAMETOOLONG;
+		return ERR_PTR(-ENAMETOOLONG);
X 
X 	if (adfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de)) {
X 		ino = de.inode_no;
X 		inode = iget (dir->i_sb, ino);
X 
X 		if (!inode)
-			return -EACCES;
+			return ERR_PTR(-EACCES);
X 	}
X 	d_add(dentry, inode);
-	return 0;
+	return NULL;
X }
diff -u --recursive --new-file v2.2.6/linux/fs/affs/dir.c linux/fs/affs/dir.c
--- v2.2.6/linux/fs/affs/dir.c	Wed Aug 26 11:37:39 1998
+++ linux/fs/affs/dir.c	Fri Apr 23 21:20:37 1999
@@ -90,9 +90,6 @@
X 
X 	pr_debug("AFFS: readdir(ino=%lu,f_pos=%lu)\n",inode->i_ino,(unsigned long)filp->f_pos);
X 
-	if (!inode || !S_ISDIR(inode->i_mode))
-		return -EBADF;
-
X 	stored = 0;
X 	dir_bh = NULL;
X 	fh_bh  = NULL;
diff -u --recursive --new-file v2.2.6/linux/fs/affs/namei.c linux/fs/affs/namei.c
--- v2.2.6/linux/fs/affs/namei.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/affs/namei.c	Fri Apr 23 21:20:37 1999
@@ -201,7 +201,7 @@
X 	return bh;
X }
X 
-int
+struct dentry *
X affs_lookup(struct inode *dir, struct dentry *dentry)
X {
X 	unsigned long		 ino;
@@ -218,11 +218,11 @@
X 		affs_brelse(bh);
X 		inode = iget(dir->i_sb,ino);
X 		if (!inode)
-			return -EACCES;
+			return ERR_PTR(-EACCES);
X 	}
X 	dentry->d_op = &affs_dentry_operations;
X 	d_add(dentry,inode);
-	return 0;
+	return NULL;
X }
X 
X int
diff -u --recursive --new-file v2.2.6/linux/fs/autofs/dir.c linux/fs/autofs/dir.c
--- v2.2.6/linux/fs/autofs/dir.c	Sun Nov  8 14:03:04 1998
+++ linux/fs/autofs/dir.c	Fri Apr 23 21:20:37 1999
@@ -38,10 +38,10 @@
X /*
X  * No entries except for "." and "..", both of which are handled by the VFS layer
X  */
-static int autofs_dir_lookup(struct inode *dir, struct dentry * dentry)
+static struct dentry *autofs_dir_lookup(struct inode *dir,struct dentry *dentry)
X {
X 	d_add(dentry, NULL);
-	return 0;
+	return NULL;
X }
X 
X static struct file_operations autofs_dir_operations = {
diff -u --recursive --new-file v2.2.6/linux/fs/autofs/root.c linux/fs/autofs/root.c
--- v2.2.6/linux/fs/autofs/root.c	Tue Mar 23 14:35:48 1999
+++ linux/fs/autofs/root.c	Fri Apr 23 21:20:37 1999
@@ -16,7 +16,7 @@
X #include "autofs_i.h"
X 
X static int autofs_root_readdir(struct file *,void *,filldir_t);
-static int autofs_root_lookup(struct inode *,struct dentry *);
+static struct dentry *autofs_root_lookup(struct inode *,struct dentry *);
X static int autofs_root_symlink(struct inode *,struct dentry *,const char *);
X static int autofs_root_unlink(struct inode *,struct dentry *);
X static int autofs_root_rmdir(struct inode *,struct dentry *);
@@ -209,7 +209,7 @@
X 	NULL,			/* d_compare */
X };
X 
-static int autofs_root_lookup(struct inode *dir, struct dentry *dentry)
+static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentry)
X {
X 	struct autofs_sb_info *sbi;
X 	int oz_mode;
@@ -217,11 +217,8 @@
X 	DPRINTK(("autofs_root_lookup: name = "));
X 	autofs_say(dentry->d_name.name,dentry->d_name.len);
X 
-	if (!S_ISDIR(dir->i_mode))
-		return -ENOTDIR;
-
X 	if (dentry->d_name.len > NAME_MAX)
-		return -ENOENT;	/* File name too long to exist */
+		return ERR_PTR(-ENOENT);/* File name too long to exist */
X 
X 	sbi = autofs_sbi(dir->i_sb);
X 
@@ -253,7 +250,7 @@
X 	 */
X 	if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
X 		if (signal_pending(current))
-			return -ERESTARTNOINTR;
+			return ERR_PTR(-ERESTARTNOINTR);
X 	}
X 
X 	/*
@@ -263,9 +260,9 @@
X 	 * be OK for the operations we permit from an autofs.
X 	 */
X 	if ( dentry->d_inode && list_empty(&dentry->d_hash) )
-		return -ENOENT;
+		return ERR_PTR(-ENOENT);
X 
-	return 0;
+	return NULL;
X }
X 
X static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
diff -u --recursive --new-file v2.2.6/linux/fs/buffer.c linux/fs/buffer.c
--- v2.2.6/linux/fs/buffer.c	Mon Mar 29 11:09:11 1999
+++ linux/fs/buffer.c	Tue Apr 27 14:34:41 1999
@@ -486,33 +486,6 @@
X 	remove_from_lru_list(bh);
X }
X 
-static inline void put_last_lru(struct buffer_head * bh)
-{
-	if (bh) {
-		struct buffer_head **bhp = &lru_list[bh->b_list];
-
-		if (bh == *bhp) {
-			*bhp = bh->b_next_free;
-			return;
-		}
-
-		if(bh->b_dev == B_FREE)
-			panic("Wrong block for lru list");
-
-		/* Add to back of free list. */
-		remove_from_lru_list(bh);
-		if(!*bhp) {
-			*bhp = bh;
-			(*bhp)->b_prev_free = bh;
-		}
-
-		bh->b_next_free = *bhp;
-		bh->b_prev_free = (*bhp)->b_prev_free;
-		(*bhp)->b_prev_free->b_next_free = bh;
-		(*bhp)->b_prev_free = bh;
-	}
-}
-
X static inline void put_last_free(struct buffer_head * bh)
X {
X 	if (bh) {
@@ -726,8 +699,6 @@
X 	bh = get_hash_table(dev, block, size);
X 	if (bh) {
X 		if (!buffer_dirty(bh)) {
-			if (buffer_uptodate(bh))
-				 put_last_lru(bh);
X 			bh->b_flushtime = 0;
X 		}
X 		return bh;
@@ -833,6 +804,7 @@
X 	/* If dirty, mark the time this buffer should be written back. */
X 	set_writetime(buf, 0);
X 	refile_buffer(buf);
+	touch_buffer(buf);
X 
X 	if (buf->b_count) {
X 		buf->b_count--;
@@ -854,6 +826,7 @@
X 		return;
X 	}
X 	buf->b_count = 0;
+	buf->b_state = 0;
X 	remove_from_queues(buf);
X 	put_last_free(buf);
X }
@@ -867,7 +840,6 @@
X 	struct buffer_head * bh;
X 
X 	bh = getblk(dev, block, size);
-	touch_buffer(bh);
X 	if (buffer_uptodate(bh))
X 		return bh;
X 	ll_rw_block(READ, 1, &bh);
@@ -904,7 +876,6 @@
X 	bh = getblk(dev, block, bufsize);
X 	index = BUFSIZE_INDEX(bh->b_size);
X 
-	touch_buffer(bh);
X 	if (buffer_uptodate(bh))
X 		return(bh);   
X 	else ll_rw_block(READ, 1, &bh);
@@ -1525,13 +1496,27 @@
X  * Use gfp() for the hash table to decrease TLB misses, use
X  * SLAB cache for buffer heads.
X  */
-void __init buffer_init(void)
+void __init buffer_init(unsigned long memory_size)
X {
-	int order = 5;		/* Currently maximum order.. */
+	int order;
X 	unsigned int nr_hash;
X 
-	nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct buffer_head *);
-	hash_table = (struct buffer_head **) __get_free_pages(GFP_ATOMIC, order);
+	/* we need to guess at the right sort of size for a buffer cache.
+	   the heuristic from working with large databases and getting
+	   fsync times (ext2) manageable, is the following */
+
+	memory_size >>= 20;
+	for (order = 5; (1UL << order) < memory_size; order++);
+
+	/* try to allocate something until we get it or we're asking
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 14'
echo 'File patch-2.2.7 is continued in part 15'
echo 15 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 13 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 13; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
+		((td->status >> 23) & 1) ? "Active " : "",
+		((td->status >> 22) & 1) ? "Stalled " : "",
+		((td->status >> 21) & 1) ? "DataBufErr " : "",
+		((td->status >> 20) & 1) ? "Babble " : "",
+		((td->status >> 19) & 1) ? "NAK " : "",
+		((td->status >> 18) & 1) ? "CRC/Timeo " : "",
+		((td->status >> 17) & 1) ? "BitStuff " : "",
+		td->status & 0x7ff);
+	printk("MaxLen=%x %sEndPt=%x Dev=%x, PID=%x ",
+		td->info >> 21,
+		 ((td->info >> 19) & 1) ? "DT " : "",
+		 (td->info >> 15) & 15,
+		 (td->info >> 8) & 127,
+		 td->info & 0xff);
+	printk("(buf=%08x)\n", td->buffer);
+}
+
+static void show_sc(int port, unsigned short status)
+{
+	printk("  stat%d     =     %04x   %s%s%s%s%s%s%s%s\n",
+		port,
+		status,
+		(status & (1 << 12)) ? " PortSuspend" : "",
+		(status & (1 << 9)) ? " PortReset" : "",
+		(status & (1 << 8)) ? " LowSpeed" : "",
+		(status & 0x40) ? " ResumeDetect" : "",
+		(status & 0x08) ? " EnableChange" : "",
+		(status & 0x04) ? " PortEnabled" : "",
+		(status & 0x02) ? " ConnectChange" : "",
+		(status & 0x01) ? " PortConnected" : "");
+}
+
+void show_status(struct uhci *uhci)
+{
+	unsigned int io_addr = uhci->io_addr;
+	unsigned short usbcmd, usbstat, usbint, usbfrnum;
+	unsigned int flbaseadd;
+	unsigned char sof;
+	unsigned short portsc1, portsc2;
+
+	usbcmd    = inw(io_addr + 0);
+	usbstat   = inw(io_addr + 2);
+	usbint    = inw(io_addr + 4);
+	usbfrnum  = inw(io_addr + 6);
+	flbaseadd = inl(io_addr + 8);
+	sof       = inb(io_addr + 12);
+	portsc1   = inw(io_addr + 16);
+	portsc2   = inw(io_addr + 18);
+
+	printk("  usbcmd    =     %04x   %s%s%s%s%s%s%s%s\n",
+		usbcmd,
+		(usbcmd & 0x80) ? " Maxp64" : " Maxp32",
+		(usbcmd & 0x40) ? " CF" : "",
+		(usbcmd & 0x20) ? " SWDBG" : "",
+		(usbcmd & 0x10) ? " FGR" : "",
+		(usbcmd & 0x08) ? " EGSM" : "",
+		(usbcmd & 0x04) ? " GRESET" : "",
+		(usbcmd & 0x02) ? " HCRESET" : "",
+		(usbcmd & 0x01) ? " RS" : "");
+
+	printk("  usbstat   =     %04x   %s%s%s%s%s%s\n",
+		usbstat,
+		(usbstat & 0x20) ? " HCHalted" : "",
+		(usbstat & 0x10) ? " HostControllerProcessError" : "",
+		(usbstat & 0x08) ? " HostSystemError" : "",
+		(usbstat & 0x04) ? " ResumeDetect" : "",
+		(usbstat & 0x02) ? " USBError" : "",
+		(usbstat & 0x01) ? " USBINT" : "");
+
+	printk("  usbint    =     %04x\n", usbint);
+	printk("  usbfrnum  =   (%d)%03x\n", (usbfrnum >> 10) & 1, 0xfff & (4*(unsigned int)usbfrnum));
+	printk("  flbaseadd = %08x\n", flbaseadd);
+	printk("  sof       =       %02x\n", sof);
+	show_sc(1, portsc1);
+	show_sc(2, portsc2);
+}
+
+#define uhci_link_to_qh(x) ((struct uhci_qh *) uhci_link_to_td(x))
+
+struct uhci_td * uhci_link_to_td(unsigned int link)
+{
+	if (link & 1)
+		return NULL;
+
+	return bus_to_virt(link & ~15);
+}
+
+void show_queue(struct uhci_qh *qh)
+{
+	struct uhci_td *td;
+	int i = 0;
+
+#if 0
+	printk("    link = %p, element = %p\n", qh->link, qh->element);
+#endif
+	if(!qh->element) {
+		printk("    td 0 = NULL\n");
+		return;
+	}
+
+	for(td = uhci_link_to_td(qh->element); td; 
+	    td = uhci_link_to_td(td->link)) {
+		printk("    td %d = %p\n", i++, td);
+		printk("    ");
+		show_td(td);
+	}
+}
+
+int is_skeleton_qh(struct uhci *uhci, struct uhci_qh *qh)
+{
+	int j;
+
+	for (j = 0; j < UHCI_MAXQH; j++)
+		if (qh == uhci->root_hub->qh + j)
+			return 1;
+
+	return 0;
+}
+
+static const char *qh_names[] = {"isochronous", "interrupt2", "interrupt4",
+				 "interrupt8", "interrupt16", "interrupt32",
+				 "interrupt64", "interrupt128", "interrupt256",
+				 "control", "bulk0", "bulk1", "bulk2", "bulk3",
+				 "unused", "unused"};
+
+void show_queues(struct uhci *uhci)
+{
+	int i;
+	struct uhci_qh *qh;
+
+	for (i = 0; i < UHCI_MAXQH; ++i) {
+		printk("  %s:\n", qh_names[i]);
+#if 0
+		printk("  qh #%d, %p\n", i, virt_to_bus(uhci->root_hub->qh + i));
+		show_queue(uhci->root_hub->qh + i);
+#endif
+
+		qh = uhci_link_to_qh(uhci->root_hub->qh[i].link);
+		for (; qh; qh = uhci_link_to_qh(qh->link)) {
+			if (is_skeleton_qh(uhci, qh))
+				break;
+
+			show_queue(qh);
+		}
+	}
+}
+
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c
--- v2.2.6/linux/drivers/usb/uhci.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/uhci.c	Wed Apr 28 11:14:03 1999
@@ -0,0 +1,1202 @@
+/*
+ * Universal Host Controller Interface driver for USB.
+ *
+ * (C) Copyright 1999 Linus Torvalds
+ *
+ * Intel documents this fairly well, and as far as I know there
+ * are no royalties or anything like that, but even so there are
+ * people who decided that they want to do the same thing in a
+ * completely different way.
+ *
+ * Oh, well. The intel version is the more common by far. As such,
+ * that's the one I care about right now.
+ *
+ * WARNING! The USB documentation is downright evil. Most of it
+ * is just crap, written by a committee. You're better off ignoring
+ * most of it, the important stuff is:
+ *  - the low-level protocol (fairly simple but lots of small details)
+ *  - working around the horridness of the rest
+ */
+
+/* 4/4/1999 added data toggle for interrupt pipes -keryan */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/malloc.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+
+#include <asm/spinlock.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include "uhci.h"
+#include "inits.h"
+
+#ifdef CONFIG_APM
+#include <linux/apm_bios.h>
+static int handle_apm_event(apm_event_t event);
+static int apm_resume = 0;
+#endif
+
+#define compile_assert(x) do { switch (0) { case 1: case !(x): } } while (0)
+
+int usb_mouse_init(void);
+int hub_init(void);
+
+static struct wait_queue *uhci_configure = NULL;
+
+/*
+ * Return the result of a TD..
+ */
+static int uhci_td_result(struct uhci_device *dev, struct uhci_td *td)
+{
+	unsigned int status;
+
+	status = (td->status >> 16) & 0xff;
+
+	/* Some debugging code */
+	if (status) {
+		int i = 10;
+		struct uhci_td *tmp = dev->control_td;
+		printk("uhci_td_result() failed with status %d\n", status);
+		show_status(dev->uhci);
+		do {
+			show_td(tmp);
+			tmp++;
+			if (!--i)
+				break;
+		} while (tmp <= td);
+	}
+	return status;		
+}
+
+/*
+ * Inserts a td into qh list at the top.
+ *
+ * Careful about atomicity: even on UP this
+ * requires a locked access due to the concurrent
+ * DMA engine.
+ *
+ * NOTE! This assumes that first->last is a valid
+ * list of TD's with the proper backpointers set
+ * up and all..
+ */
+static void uhci_insert_tds_in_qh(struct uhci_qh *qh, struct uhci_td *first, struct uhci_td *last)
+{
+	unsigned int link = qh->element;
+	unsigned int new = 4 | virt_to_bus(first);
+
+	for (;;) {
+		unsigned char success;
+
+		last->link = link;
+		first->backptr = &qh->element;
+		asm volatile("lock ; cmpxchg %4,%2 ; sete %0"
+			:"=q" (success), "=a" (link)
+			:"m" (qh->element), "1" (link), "r" (new)
+			:"memory");
+		if (success) {
+			/* Was there a successor entry? Fix it's backpointer.. */
+			if ((link & 1) == 0) {
+				struct uhci_td *next = bus_to_virt(link & ~15);
+				next->backptr = &last->link;
+			}
+			break;
+		}
+	}
+}
+
+static inline void uhci_insert_td_in_qh(struct uhci_qh *qh, struct uhci_td *td)
+{
+	uhci_insert_tds_in_qh(qh, td, td);
+}
+
+static void uhci_insert_qh(struct uhci_qh *qh, struct uhci_qh *newqh)
+{
+	newqh->link = qh->link;
+	qh->link = virt_to_bus(newqh) | 2;
+}
+
+static void uhci_remove_qh(struct uhci_qh *qh, struct uhci_qh *remqh)
+{
+	unsigned int remphys = virt_to_bus(remqh);
+	struct uhci_qh *lqh = qh;
+
+	while ((lqh->link & ~0xF) != remphys) {
+		if (lqh->link & 1)
+			break;
+
+		lqh = bus_to_virt(lqh->link & ~0xF);
+	}
+
+	if (lqh->link & 1) {
+		printk("couldn't find qh in chain!\n");
+		return;
+	}
+
+	lqh->link = remqh->link;
+}
+
+/*
+ * Removes td from qh if present.
+ *
+ * NOTE! We keep track of both forward and back-pointers,
+ * so this should be trivial, right?
+ *
+ * Wrong. While all TD insert/remove operations are synchronous
+ * on the CPU, the UHCI controller can (and does) play with the
+ * very first forward pointer. So we need to validate the backptr
+ * before we change it, so that we don't by mistake reset the QH
+ * head to something old.
+ */
+static void uhci_remove_td(struct uhci_td *td)
+{
+	unsigned int *backptr = td->backptr;
+	unsigned int link = td->link;
+	unsigned int me;
+
+	if (!backptr)
+		return;
+
+	td->backptr = NULL;
+
+	/*
+	 * This is the easy case: the UHCI will never change "td->link",
+	 * so we can always just look at that and fix up the backpointer
+	 * of any next element..
+	 */
+	if (!(link & 1)) {
+		struct uhci_td *next = bus_to_virt(link & ~15);
+		next->backptr = backptr;
+	}
+
+	/*
+	 * The nasty case is "backptr->next", which we need to
+	 * update to "link" _only_ if "backptr" still points
+	 * to us (it may not: maybe backptr is a QH->element
+	 * pointer and the UHCI has changed the value).
+	 */
+	me = virt_to_bus(td) | (0xe & *backptr);
+	asm volatile("lock ; cmpxchg %0,%1"
+		:
+		:"r" (link), "m" (*backptr), "a" (me)
+		:"memory");
+}
+
+static struct uhci_qh *uhci_qh_allocate(struct uhci_device *dev)
+{
+	struct uhci_qh *qh;
+	int inuse;
+
+	qh = dev->qh;
+	for (; (inuse = test_and_set_bit(0, &qh->inuse)) != 0 && qh < &dev->qh[UHCI_MAXQH]; qh++)
+		;
+
+	if (!inuse)
+		return(qh);
+
+	printk("ran out of qh's for dev %p\n", dev);
+	return(NULL);
+}
+
+static void uhci_qh_deallocate(struct uhci_qh *qh)
+{
+	if (qh->element != 1)
+		printk("qh %p leaving dangling entries? (%X)\n", qh, qh->element);
+
+	qh->element = 1;
+	qh->link = 1;
+
+	clear_bit(0, &qh->inuse);
+}
+
+static struct uhci_td *uhci_td_allocate(struct uhci_device *dev)
+{
+	struct uhci_td *td;
+	int inuse;
+
+	td = dev->td;
+	for (; (inuse = test_and_set_bit(0, &td->inuse)) != 0 && td < &dev->td[UHCI_MAXTD]; td++)
+		;
+
+	if (!inuse)
+		return(td);
+
+	printk("ran out of td's for dev %p\n", dev);
+	return(NULL);
+}
+
+/*
+ * This MUST only be called when it has been removed from a QH already (or
+ * the QH has been removed from the skeleton
+ */
+static void uhci_td_deallocate(struct uhci_td *td)
+{
+	td->link = 1;
+
+	clear_bit(0, &td->inuse);
+}
+
+/*
+ * UHCI interrupt list operations..
+ */
+static spinlock_t irqlist_lock = SPIN_LOCK_UNLOCKED;
+
+static void uhci_add_irq_list(struct uhci *uhci, struct uhci_td *td, usb_device_irq completed, void *dev_id)
+{
+	unsigned long flags;
+
+	td->completed = completed;
+	td->dev_id = dev_id;
+
+	spin_lock_irqsave(&irqlist_lock, flags);
+	list_add(&td->irq_list, &uhci->interrupt_list);
+	spin_unlock_irqrestore(&irqlist_lock, flags);
+}
+
+static void uhci_remove_irq_list(struct uhci_td *td)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&irqlist_lock, flags);
+	list_del(&td->irq_list);
+	spin_unlock_irqrestore(&irqlist_lock, flags);
+}
+
+/*
+ * Request a interrupt handler..
+ */
+static int uhci_request_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id)
+{
+	struct uhci_device *dev = usb_to_uhci(usb_dev);
+	struct uhci_td *td = uhci_td_allocate(dev);
+	struct uhci_qh *interrupt_qh = uhci_qh_allocate(dev);
+
+	unsigned int destination, status;
+
+	/* Destination: pipe destination with INPUT */
+	destination = (pipe & 0x0007ff00)  |  0x69;
+
+	/* Status:    slow/fast,      Interrupt,   Active,    Short Packet Detect     Infinite Errors */
+	status = (pipe & (1 << 26)) | (1 << 24) | (1 << 23)   |   (1 << 29)       |    (0 << 27);
+
+	if(interrupt_qh->element != 1)
+		printk("interrupt_qh->element = 0x%x\n", 
+		       interrupt_qh->element);
+
+	td->link = 1;
+	td->status = status;			/* In */
+	td->info = destination | (7 << 21);	/* 8 bytes of data */
+	td->buffer = virt_to_bus(dev->data);
+	td->qh = interrupt_qh;
+	interrupt_qh->skel = &dev->uhci->root_hub->skel_int8_qh;
+
+	uhci_add_irq_list(dev->uhci, td, handler, dev_id);
+
+	uhci_insert_td_in_qh(interrupt_qh, td);
+
+	/* Add it into the skeleton */
+	uhci_insert_qh(&dev->uhci->root_hub->skel_int8_qh, interrupt_qh);
+	return 0;
+}
+
+/*
+ * Control thread operations: we just mark the last TD
+ * in a control thread as an interrupt TD, and wake up
+ * the front-end on completion.
+ *
+ * We need to remove the TD from the lists (both interrupt
+ * list and TD lists) by hand if something bad happens!
+ */
+static struct wait_queue *control_wakeup;
+
+static int uhci_control_completed(int status, void *buffer, void *dev_id)
+{
+	wake_up(&control_wakeup);
+	return 0;			/* Don't re-instate */
+}
+
+/* td points to the last td in the list, which interrupts on completion */
+static int uhci_run_control(struct uhci_device *dev, struct uhci_td *first, struct uhci_td *last)
+{
+	struct wait_queue wait = { current, NULL };
+	struct uhci_qh *ctrl_qh = uhci_qh_allocate(dev);
+	struct uhci_td *curtd;
+
+	current->state = TASK_UNINTERRUPTIBLE;
+	add_wait_queue(&control_wakeup, &wait);
+
+	uhci_add_irq_list(dev->uhci, last, uhci_control_completed, NULL);
+	
+	/* FIXME: This is kinda kludged */
+	/* Walk the TD list and update the QH pointer */
+	{
+	int maxcount = 100;
+
+	curtd = first;
+	do {
+		curtd->qh = ctrl_qh;
+		if (curtd->link & 1)
+			break;
+
+		curtd = bus_to_virt(curtd->link & ~0xF);
+		if (!--maxcount) {
+			printk("runaway tds!\n");
+			break;
+		}
+	} while (1);
+	}
+
+	uhci_insert_tds_in_qh(ctrl_qh, first, last);
+
+	/* Add it into the skeleton */
+	uhci_insert_qh(&dev->uhci->root_hub->skel_control_qh, ctrl_qh);
+
+	schedule_timeout(HZ/10);
+
+	remove_wait_queue(&control_wakeup, &wait);
+
+	/* Clean up in case it failed.. */
+	uhci_remove_irq_list(last);
+
+#if 0
+	printk("Looking for tds [%p, %p]\n", dev->control_td, td);
+#endif
+
+	/* Remove it from the skeleton */
+	uhci_remove_qh(&dev->uhci->root_hub->skel_control_qh, ctrl_qh);
+
+	uhci_qh_deallocate(ctrl_qh);
+
+	return uhci_td_result(dev, last);
+}
+
+/*
+ * Send or receive a control message on a pipe.
+ *
+ * Note that the "pipe" structure is set up to map
+ * easily to the uhci destination fields.
+ *
+ * A control message is built up from three parts:
+ *  - The command itself
+ * - [ optional ] data phase
+ *  - Status complete phase
+ *
+ * The data phase can be an arbitrary number of TD's
+ * although we currently had better not have more than
+ * 29 TD's here (we have 31 TD's allocated for control
+ * operations, and two of them are used for command and
+ * status).
+ *
+ * 29 TD's is a minimum of 232 bytes worth of control
+ * information, that's just ridiculously high. Most
+ * control messages have just a few bytes of data.
+ */
+static int uhci_control_msg(struct usb_device *usb_dev, unsigned int pipe, void *cmd, void *data, int len)
+{
+	struct uhci_device *dev = usb_to_uhci(usb_dev);
+	struct uhci_td *first, *td, *prevtd;
+	unsigned long destination, status;
+	int ret;
+
+	if (len > usb_maxpacket(usb_dev->maxpacketsize) * 29)
+		printk("Warning, too much data for a control packet, crashing\n");
+
+	first = td = uhci_td_allocate(dev);
+
+	/* The "pipe" thing contains the destination in bits 8--18, 0x2D is SETUP */
+	destination = (pipe & 0x0007ff00) | 0x2D;
+
+	/* Status:    slow/fast,       Active,    Short Packet Detect     Three Errors */
+	status = (pipe & (1 << 26)) | (1 << 23)   |   (1 << 29)       |    (3 << 27);
+
+	/*
+	 * Build the TD for the control request
+	 */
+	td->status = status;				/* Try forever */
+	td->info = destination | (7 << 21);		/* 8 bytes of data */
+	td->buffer = virt_to_bus(cmd);
+
+	/*
+	 * If direction is "send", change the frame from SETUP (0x2D)
+	 * to OUT (0xE1). Else change it from SETUP to IN (0x69)
+	 */
+	destination ^= (0x2D ^ 0x69);			/* SETUP -> IN */
+	if (usb_pipeout(pipe))
+		destination ^= (0xE1 ^ 0x69);		/* IN -> OUT */
+
+	prevtd = td;
+	td = uhci_td_allocate(dev);
+	prevtd->link = 4 | virt_to_bus(td);
+
+	/*
+	 * Build the DATA TD's
+	 */
+	while (len > 0) {
+		/* Build the TD for control status */
+		int pktsze = len;
+		int maxsze = usb_maxpacket(pipe);
+
+		if (pktsze > maxsze)
+			pktsze = maxsze;
+
+		/* Alternate Data0/1 (start with Data1) */
+		destination ^= 1 << 19;
+	
+		td->status = status;					/* Status */
+		td->info = destination | ((pktsze-1) << 21);		/* pktsze bytes of data */
+		td->buffer = virt_to_bus(data);
+		td->backptr = &prevtd->link;
+
+		prevtd = td;
+		td = uhci_td_allocate(dev);
+		prevtd->link = 4 | virt_to_bus(td);			/* Update previous TD */
+
+		data += maxsze;
+		len -= maxsze;
+	}
+
+	/*
+	 * Build the final TD for control status
+	 */
+	destination ^= (0xE1 ^ 0x69);			/* OUT -> IN */
+	destination |= 1 << 19;				/* End in Data1 */
+
+	td->link = 1;					/* Terminate */
+	td->status = status | (1 << 24);		/* IOC */
+	td->info = destination | (0x7ff << 21);		/* 0 bytes of data */
+	td->buffer = 0;
+	td->backptr = &prevtd->link;
+
+	/* Start it up.. */
+	ret = uhci_run_control(dev, first, td);
+
+	{
+		int maxcount = 100;
+		struct uhci_td *curtd = first;
+		unsigned int nextlink;
+
+		do {
+			nextlink = curtd->link;
+			uhci_remove_td(curtd);
+			uhci_td_deallocate(curtd);
+			if (nextlink & 1)	/* Tail? */
+				break;
+
+			curtd = bus_to_virt(nextlink & ~0xF);
+			if (!--maxcount) {
+				printk("runaway td's!?\n");
+				break;
+			}
+		} while (1);
+	}
+
+	return ret;
+}
+
+static struct usb_device *uhci_usb_allocate(struct usb_device *parent)
+{
+	struct usb_device *usb_dev;
+	struct uhci_device *dev;
+	int i;
+
+	usb_dev = kmalloc(sizeof(*usb_dev), GFP_KERNEL);
+	if (!usb_dev)
+		return NULL;
+
+	memset(usb_dev, 0, sizeof(*usb_dev));
+
+	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev) {
+		kfree(usb_dev);
+		return NULL;
+	}
+
+	/* Initialize "dev" */
+	memset(dev, 0, sizeof(*dev));
+
+	usb_dev->hcpriv = dev;
+	dev->usb = usb_dev;
+
+	usb_dev->parent = parent;
+
+	if (parent) {
+		usb_dev->bus = parent->bus;
+		dev->uhci = usb_to_uhci(parent)->uhci;
+	}
+
+	/* Reset the QH's and TD's */
+	for (i = 0; i < UHCI_MAXQH; i++) {
+		dev->qh[i].link = 1;
+		dev->qh[i].element = 1;
+		dev->qh[i].inuse = 0;
+	}
+
+	for (i = 0; i < UHCI_MAXTD; i++) {
+		dev->td[i].link = 1;
+		dev->td[i].inuse = 0;
+	}
+
+	return usb_dev;
+}
+
+static int uhci_usb_deallocate(struct usb_device *usb_dev)
+{
+	struct uhci_device *dev = usb_to_uhci(usb_dev);
+	int i;
+
+	/* There are UHCI_MAXTD preallocated tds */
+	for (i = 0; i < UHCI_MAXTD; ++i) {
+		struct uhci_td *td = dev->td + i;
+
+		/* And remove it from the irq list, if it's active */
+		if (td->status & (1 << 23))
+			uhci_remove_irq_list(td);
+
+		if (td->inuse)
+			uhci_remove_td(td);
+	}
+
+	/* Remove the td from any queues */
+	for (i = 0; i < UHCI_MAXQH; ++i) {
+		struct uhci_qh *qh = dev->qh + i;
+
+		if (qh->inuse)
+			uhci_remove_qh(qh->skel, qh);
+	}
+
+	kfree(dev);
+	kfree(usb_dev);
+
+	return 0;
+}
+
+struct usb_operations uhci_device_operations = {
+	uhci_usb_allocate,
+	uhci_usb_deallocate,
+	uhci_control_msg,
+	uhci_request_irq,
+};
+
+/*
+ * This is just incredibly fragile. The timings must be just
+ * right, and they aren't really documented very well.
+ *
+ * Note the short delay between disabling reset and enabling
+ * the port..
+ */
+static void uhci_reset_port(unsigned int port)
+{
+	unsigned short status;
+
+	status = inw(port);
+	outw(status | USBPORTSC_PR, port);		/* reset port */
+	wait_ms(10);
+	outw(status & ~USBPORTSC_PR, port);
+	udelay(5);
+
+	status = inw(port);
+	outw(status | USBPORTSC_PE, port);		/* enable port */
+	wait_ms(10);
+
+	status = inw(port);
+	if(!(status & USBPORTSC_PE)) {
+		outw(status | USBPORTSC_PE, port);	/* one more try at enabling port */
+		wait_ms(50);
+	}
+
+}
+
+
+/*
+ * This gets called if the connect status on the root
+ * hub (and the root hub only) changes.
+ */
+static void uhci_connect_change(struct uhci *uhci, unsigned int port, unsigned int nr)
+{
+	struct usb_device *usb_dev;
+	struct uhci_device *dev;
+	unsigned short status;
+
+	printk("uhci_connect_change: called for %d\n", nr);
+
+	/*
+	 * Even if the status says we're connected,
+	 * the fact that the status bits changed may
+	 * that we got disconnected and then reconnected.
+	 *
+	 * So start off by getting rid of any old devices..
+	 */
+	usb_disconnect(&uhci->root_hub->usb->children[nr]);
+
+	status = inw(port);
+
+	/* If we have nothing connected, then clear change status and disable the port */
+	status = (status & ~USBPORTSC_PE) | USBPORTSC_PEC;
+	if (!(status & USBPORTSC_CCS)) {
+		outw(status, port);
+		return;
+	}
+
+	/*
+	 * Ok, we got a new connection. Allocate a device to it,
+	 * and find out what it wants to do..
+	 */
+	usb_dev = uhci_usb_allocate(uhci->root_hub->usb);
+	dev = usb_dev->hcpriv;
+
+	dev->uhci = uhci;
+
+	usb_connect(usb_dev);
+
+	uhci->root_hub->usb->children[nr] = usb_dev;
+
+	wait_ms(200); /* wait for powerup */
+	uhci_reset_port(port);
+
+	/* Get speed information */
+	usb_dev->slow = (inw(port) & USBPORTSC_LSDA) ? 1 : 0;
+
+	/*
+	 * Ok, all the stuff specific to the root hub has been done.
+	 * The rest is generic for any new USB attach, regardless of
+	 * hub type.
+	 */
+	usb_new_device(usb_dev);
+}
+
+/*
+ * This gets called when the root hub configuration
+ * has changed. Just go through each port, seeing if
+ * there is something interesting happening.
+ */
+static void uhci_check_configuration(struct uhci *uhci)
+{
+	unsigned int io_addr = uhci->io_addr + USBPORTSC1;
+	int maxchild = uhci->root_hub->usb->maxchild;
+	int nr = 0;
+
+	do {
+		unsigned short status = inw(io_addr);
+
+		if (status & USBPORTSC_CSC)
+			uhci_connect_change(uhci, io_addr, nr);
+
+		nr++; io_addr += 2;
+	} while (nr < maxchild);
+}
+
+static void uhci_interrupt_notify(struct uhci *uhci)
+{
+	struct list_head *head = &uhci->interrupt_list;
+	struct list_head *tmp;
+
+	spin_lock(&irqlist_lock);
+	tmp = head->next;
+	while (tmp != head) {
+		struct uhci_td *td = list_entry(tmp, struct uhci_td, irq_list);
+		struct list_head *next;
+
+		next = tmp->next;
+
+		if (!(td->status & (1 << 23))) {	/* No longer active? */
+			/* remove from IRQ list */
+			__list_del(tmp->prev, next);
+			INIT_LIST_HEAD(tmp);
+			if (td->completed(td->status, bus_to_virt(td->buffer), td->dev_id)) {
+				struct uhci_qh *interrupt_qh = td->qh;
+
+				list_add(&td->irq_list, &uhci->interrupt_list);
+				td->info ^= 1 << 19; /* toggle between data0 and data1 */
+				td->status = (td->status & 0x2f000000) | (1 << 23) | (1 << 24);	/* active */
+
+				/* Remove then readd? Is that necessary */
+				uhci_remove_td(td);
+				uhci_insert_td_in_qh(interrupt_qh, td);
+			}
+			/* If completed wants to not reactivate, then it's */
+			/* responsible for free'ing the TD's and QH's */
+			/* or another function (such as run_control) */
+		}
+		tmp = next;
+	}
+	spin_unlock(&irqlist_lock);
+}
+
+/*
+ * Check port status - Connect Status Change - for
+ * each of the attached ports (defaults to two ports,
+ * but at least in theory there can be more of them).
+ *
+ * Wake up the configurator if something happened, we
+ * can't really do much at interrupt time.
+ */
+static void uhci_root_hub_events(struct uhci *uhci, unsigned int io_addr)
+{
+	if (waitqueue_active(&uhci_configure)) {
+		int ports = uhci->root_hub->usb->maxchild;
+		io_addr += USBPORTSC1;
+		do {
+			if (inw(io_addr) & USBPORTSC_CSC) {
+				wake_up(&uhci_configure);
+				return;
+			}
+			io_addr += 2;
+		} while (--ports > 0);
+	}
+}
+
+static void uhci_interrupt(int irq, void *__uhci, struct pt_regs *regs)
+{
+	struct uhci *uhci = __uhci;
+	unsigned int io_addr = uhci->io_addr;
+	unsigned short status;
+
+	/*
+	 * Read the interrupt status, and write it back to clear the interrupt cause
+	 */
+	status = inw(io_addr + USBSTS);
+	outw(status, io_addr + USBSTS);
+
+	/* Walk the list of pending TD's to see which ones completed.. */
+	uhci_interrupt_notify(uhci);
+
+	/* Check if there are any events on the root hub.. */
+	uhci_root_hub_events(uhci, io_addr);
+}
+
+/*
+ * We init one packet, and mark it just IOC and _not_
+ * active. Which will result in no actual USB traffic,
+ * but _will_ result in an interrupt every second.
+ *
+ * Which is exactly what we want.
+ */
+static void uhci_init_ticktd(struct uhci *uhci)
+{
+	struct uhci_device *dev = uhci->root_hub;
+	struct uhci_td *td = uhci_td_allocate(dev);
+
+	td->link = 1;
+	td->status = (1 << 24);					/* interrupt on completion */
+	td->info = (15 << 21) | 0x7f69;				/* (ignored) input packet, 16 bytes, device 127 */
+	td->buffer = 0;
+	td->qh = NULL;
+
+	uhci->fl->frame[0] = virt_to_bus(td);
+}
+
+static void reset_hc(struct uhci *uhci)
+{
+	unsigned int io_addr = uhci->io_addr;
+
+	/* Global reset for 50ms */
+	outw(USBCMD_GRESET, io_addr+USBCMD);
+	wait_ms(50);
+	outw(0, io_addr+USBCMD);
+	wait_ms(10);
+}
+
+static void start_hc(struct uhci *uhci)
+{
+	unsigned int io_addr = uhci->io_addr;
+	int timeout = 1000;
+
+	uhci_init_ticktd(uhci);
+
+	/*
+	 * Reset the HC - this will force us to get a
+	 * new notification of any already connected
+	 * ports due to the virtual disconnect that it
+	 * implies.
+	 */
+	outw(USBCMD_HCRESET, io_addr + USBCMD);
+	while (inw(io_addr + USBCMD) & USBCMD_HCRESET) {
+		if (!--timeout) {
+			printk("USBCMD_HCRESET timed out!\n");
+			break;
+		}
+	}
+
+	outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, io_addr + USBINTR);
+	outw(0, io_addr + USBFRNUM);
+	outl(virt_to_bus(uhci->fl), io_addr + USBFLBASEADD);
+
+	/* Run and mark it configured with a 64-byte max packet */
+	outw(USBCMD_RS | USBCMD_CF, io_addr + USBCMD);
+}
+
+/*
+ * Allocate a frame list, and four regular queues.
+ *
+ * The hardware doesn't really know any difference
+ * in the queues, but the order does matter for the
+ * protocols higher up. The order is:
+ *
+ *  - any isochronous events handled before any
+ *    of the queues. We don't do that here, because
+ *    we'll create the actual TD entries on demand.
+ *  - The first queue is the "interrupt queue".
+ *  - The second queue is the "control queue".
+ *  - The third queue is "bulk data".
+ *
+ * We could certainly have multiple queues of the same
+ * type, and maybe we should. We could have per-device
+ * queues, for example. We begin small.
+ */
+static struct uhci *alloc_uhci(unsigned int io_addr)
+{
+	int i;
+	struct uhci *uhci;
+	struct usb_bus *bus;
+	struct uhci_device *dev;
+	struct usb_device *usb;
+
+	uhci = kmalloc(sizeof(*uhci), GFP_KERNEL);
+	if (!uhci)
+		return NULL;
+
+	memset(uhci, 0, sizeof(*uhci));
+
+	uhci->irq = -1;
+	uhci->io_addr = io_addr;
+	INIT_LIST_HEAD(&uhci->interrupt_list);
+
+	/* We need exactly one page (per UHCI specs), how convenient */
+	uhci->fl = (void *)__get_free_page(GFP_KERNEL);
+
+	bus = kmalloc(sizeof(*bus), GFP_KERNEL);
+	if (!bus)
+		return NULL;
+
+	memset(bus, 0, sizeof(*bus));
+
+	uhci->bus = bus;
+	bus->hcpriv = uhci;
+	bus->op = &uhci_device_operations;
+
+	/*
+	 * We allocate a 8kB area for the UHCI hub. The area
+	 * is described by the uhci_device structure, and basically
+	 * contains everything needed for normal operation.
+	 *
+	 * The first page is the actual device descriptor for the
+	 * hub.
+	 *
+	 * The second page is used for the frame list.
+	 */
+	usb = uhci_usb_allocate(NULL);
+	if (!usb)
+		return NULL;
+
+ dev = uhci->root_hub = usb_to_uhci(usb);
+
+	usb->bus = bus;
+
+	/* Initialize the root hub */
+	/* UHCI specs says devices must have 2 ports, but goes on to say */
+	/* they may have more but give no way to determine how many they */
+	/* have, so default to 2 */
+	usb->maxchild = 2;
+	usb_init_root_hub(usb);
+
+	/*
+	 * Initialize the queues. They all start out empty,
+	 * linked to each other in the proper order.
+	 */
+	for (i = 1 ; i < 9; i++) {
+		dev->qh[i].link = 2 | virt_to_bus(&dev->skel_control_qh);
+		dev->qh[i].element = 1;
+	}
+	
+	dev->skel_control_qh.link = 2 | virt_to_bus(&dev->skel_bulk0_qh);
+	dev->skel_control_qh.element = 1;
+
+	dev->skel_bulk0_qh.link = 2 | virt_to_bus(&dev->skel_bulk1_qh);
+	dev->skel_bulk0_qh.element = 1;
+
+	dev->skel_bulk1_qh.link = 2 | virt_to_bus(&dev->skel_bulk2_qh);
+	dev->skel_bulk1_qh.element = 1;
+
+	dev->skel_bulk2_qh.link = 2 | virt_to_bus(&dev->skel_bulk3_qh);
+	dev->skel_bulk2_qh.element = 1;
+
+	dev->skel_bulk3_qh.link = 1;
+	dev->skel_bulk3_qh.element = 1;
+
+	/*
+	 * Fill the frame list: make all entries point to
+	 * the proper interrupt queue.
+	 *
+	 * This is probably silly, but it's a simple way to
+	 * scatter the interrupt queues in a way that gives
+	 * us a reasonable dynamic range for irq latencies.
+	 */
+	for (i = 0; i < 1024; i++) {
+		struct uhci_qh * irq = &dev->skel_int2_qh;
+		if (i & 1) {
+			irq++;
+			if (i & 2) {
+				irq++;
+				if (i & 4) { 
+					irq++;
+					if (i & 8) { 
+						irq++;
+						if (i & 16) {
+							irq++;
+							if (i & 32) {
+								irq++;
+								if (i & 64) {
+									irq++;
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+		uhci->fl->frame[i] =  2 | virt_to_bus(irq);
+	}
+
+	return uhci;
+}
+
+
+/*
+ * De-allocate all resources..
+ */
+static void release_uhci(struct uhci *uhci)
+{
+	if (uhci->irq >= 0) {
+		free_irq(uhci->irq, uhci);
+		uhci->irq = -1;
+	}
+
+#if 0
+	if (uhci->root_hub) {
+		uhci_usb_deallocate(uhci_to_usb(uhci->root_hub));
+		uhci->root_hub = NULL;
+	}
+#endif
+
+	if (uhci->fl) {
+		free_page((unsigned long)uhci->fl);
+		uhci->fl = NULL;
+	}
+
+	kfree(uhci->bus);
+	kfree(uhci);
+}
+
+static int uhci_control_thread(void * __uhci)
+{
+	struct uhci *uhci = (struct uhci *)__uhci;
+
+	lock_kernel();
+	request_region(uhci->io_addr, 32, "usb-uhci");
+
+	/*
+	 * This thread doesn't need any user-level access,
+	 * so get rid of all our resources..
+	 */
+	printk("uhci_control_thread at %p\n", &uhci_control_thread);
+	exit_mm(current);
+	exit_files(current);
+	exit_fs(current);
+
+	strcpy(current->comm, "uhci-control");
+
+	/*
+	 * Ok, all systems are go..
+	 */
+	start_hc(uhci);
+	for(;;) {
+		siginfo_t info;
+		int unsigned long signr;
+
+		interruptible_sleep_on(&uhci_configure);
+#ifdef CONFIG_APM
+		if (apm_resume) {
+			apm_resume = 0;
+			start_hc(uhci);
+			continue;
+		}
+#endif
+		uhci_check_configuration(uhci);
+
+		if(signal_pending(current)) {
+			/* sending SIGUSR1 makes us print out some info */
+			spin_lock_irq(¤t->sigmask_lock);
+			signr = dequeue_signal(¤t->blocked, &info);
+			spin_unlock_irq(¤t->sigmask_lock);
+
+			if(signr == SIGUSR1) {
+				printk("UHCI queue dump:\n");
+				show_queues(uhci);
+			} else {
+				break;
+			}
+		}
+	}
+
+#if 0
+	if(uhci->root_hub)
+		for(i = 0; i < uhci->root_hub->usb->maxchild; i++)
+			usb_disconnect(uhci->root_hub->usb->children + i);
+#endif
+
+	reset_hc(uhci);
+	release_region(uhci->io_addr, 32);
+
+	release_uhci(uhci);
+	MOD_DEC_USE_COUNT;
+
+	printk("uhci_control_thread exiting\n");
+
+	return 0;
+}	
+
+/*
+ * If we've successfully found a UHCI, now is the time to increment the
+ * module usage count, start the control thread, and return success..
+ */
+static int found_uhci(int irq, unsigned int io_addr)
+{
+	int retval;
+	struct uhci *uhci;
+
+	uhci = alloc_uhci(io_addr);
+	if (!uhci)
+		return -ENOMEM;
+
+	reset_hc(uhci);
+
+	retval = -EBUSY;
+ if (request_irq(irq, uhci_interrupt, SA_SHIRQ, "usb", uhci) == 0) {
+		int pid;
+
+		MOD_INC_USE_COUNT;
+		uhci->irq = irq;
+		pid = kernel_thread(uhci_control_thread, uhci, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+		if (pid >= 0)
+			return 0;
+
+		MOD_DEC_USE_COUNT;
+		retval = pid;
+	}
+ release_uhci(uhci);
+	return retval;
+}
+
+static int start_uhci(struct pci_dev *dev)
+{
+	int i;
+
+	/* Search for the IO base address.. */
+	for (i = 0; i < 6; i++) {
+		unsigned int io_addr = dev->base_address[i];
+
+		/* IO address? */
+		if (!(io_addr & 1))
+			continue;
+
+		io_addr &= PCI_BASE_ADDRESS_IO_MASK;
+
+		/* Is it already in use? */
+		if (check_region(io_addr, 32))
+			break;
+
+		return found_uhci(dev->irq, io_addr);
+	}
+	return -1;
+}
+
+#ifdef CONFIG_APM
+static int handle_apm_event(apm_event_t event)
+{
+	static int down = 0;
+
+	switch (event) {
+	case APM_SYS_SUSPEND:
+	case APM_USER_SUSPEND:
+		if (down) {
+ printk(KERN_DEBUG "uhci: received extra suspend event\n");
+			break;
+		}
+		down = 1;
+		break;
+	case APM_NORMAL_RESUME:
+	case APM_CRITICAL_RESUME:
+		if (!down) {
+ printk(KERN_DEBUG "uhci: received bogus resume event\n");
+			break;
+		}
+		down = 0;
+		if (waitqueue_active(&uhci_configure)) {
+			apm_resume = 1;
+			wake_up(&uhci_configure);
+		}
+		break;
+	}
+	return 0;
+}
+#endif
+
+#ifdef MODULE
+
+void cleanup_module(void)
+{
+#ifdef CONFIG_APM
+	apm_unregister_callback(&handle_apm_event);
+#endif
+}
+
+#define uhci_init init_module
+
+#endif
+
+int uhci_init(void)
+{
+	int retval;
+	struct pci_dev *dev = NULL;
+ u8 type;
+
+	retval = -ENODEV;
+	for (;;) {
+ dev = pci_find_class(PCI_CLASS_SERIAL_USB<<8, dev);
+		if (!dev)
+			break;
+		/* Is it UHCI */
+		pci_read_config_byte(dev, PCI_CLASS_PROG, &type);
+		if(type != 0)
+			continue;
+		/* Ok set it up */
+		retval = start_uhci(dev);
+		if (retval < 0)
+			continue;
+
+#ifdef CONFIG_USB_MOUSE
+		usb_mouse_init();
+#endif
+#ifdef CONFIG_USB_KBD		
+		usb_kbd_init();
+#endif		
+		hub_init();
+#ifdef CONFIG_USB_AUDIO		
+		usb_audio_init();
+#endif		
+#ifdef CONFIG_APM
+		apm_register_callback(&handle_apm_event);
+#endif
+
+		return 0;
+	}
+	return retval;
+}
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/uhci.h linux/drivers/usb/uhci.h
--- v2.2.6/linux/drivers/usb/uhci.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/uhci.h	Wed Apr 28 11:14:03 1999
@@ -0,0 +1,229 @@
+#ifndef __LINUX_UHCI_H
+#define __LINUX_UHCI_H
+
+#include <linux/list.h>
+
+#include "usb.h"
+
+/*
+ * Universal Host Controller Interface data structures and defines
+ */
+
+/* Command register */
+#define USBCMD		0
+#define   USBCMD_RS		0x0001	/* Run/Stop */
+#define   USBCMD_HCRESET	0x0002	/* Host reset */
+#define   USBCMD_GRESET		0x0004	/* Global reset */
+#define   USBCMD_EGSM		0x0008	/* Global Suspend Mode */
+#define   USBCMD_FGR		0x0010	/* Force Global Resume */
+#define   USBCMD_SWDBG		0x0020	/* SW Debug mode */
+#define   USBCMD_CF		0x0040	/* Config Flag (sw only) */
+#define   USBCMD_MAXP		0x0080	/* Max Packet (0 = 32, 1 = 64) */
+
+/* Status register */
+#define USBSTS		2
+#define   USBSTS_USBINT		0x0001	/* Interrupt due to IOC */
+#define   USBSTS_ERROR		0x0002	/* Interrupt due to error */
+#define   USBSTS_RD		0x0004	/* Resume Detect */
+#define   USBSTS_HSE		0x0008	/* Host System Error - basically PCI problems */
+#define   USBSTS_HCPE		0x0010	/* Host Controller Process Error - the scripts were buggy */
+#define   USBSTS_HCH		0x0020	/* HC Halted */
+
+/* Interrupt enable register */
+#define USBINTR		4
+#define   USBINTR_TIMEOUT	0x0001	/* Timeout/CRC error enable */
+#define   USBINTR_RESUME	0x0002	/* Resume interrupt enable */
+#define   USBINTR_IOC		0x0004	/* Interrupt On Complete enable */
+#define   USBINTR_SP		0x0008	/* Short packet interrupt enable */
+
+#define USBFRNUM	6
+#define USBFLBASEADD	8
+#define USBSOF		12
+
+/* USB port status and control registers */
+#define USBPORTSC1	16
+#define USBPORTSC2	18
+#define   USBPORTSC_CCS		0x0001	/* Current Connect Status ("device present") */
+#define   USBPORTSC_CSC		0x0002	/* Connect Status Change */
+#define   USBPORTSC_PE		0x0004	/* Port Enable */
+#define   USBPORTSC_PEC		0x0008	/* Port Enable Change */
+#define   USBPORTSC_LS		0x0030	/* Line Status */
+#define   USBPORTSC_RD		0x0040	/* Resume Detect */
+#define   USBPORTSC_LSDA	0x0100	/* Low Speed Device Attached */
+#define   USBPORTSC_PR		0x0200	/* Port Reset */
+#define   USBPORTSC_SUSP	0x1000	/* Suspend */
+
+struct uhci_qh {
+	unsigned int link;	/* Next queue */
+	unsigned int element;	/* Queue element pointer */
+	int inuse;		/* Inuse? */
+	struct uhci_qh *skel;	/* Skeleton head */
+} __attribute__((aligned(16)));
+
+struct uhci_framelist {
+	unsigned int frame[1024];
+} __attribute__((aligned(4096)));
+
+/*
+ * The documentation says "4 words for hardware, 4 words for software".
+ *
+ * That's silly, the hardware doesn't care. The hardware only cares that
+ * the hardware words are 16-byte aligned, and we can have any amount of
+ * sw space after the TD entry as far as I can tell.
+ *
+ * But let's just go with the documentation, at least for 32-bit machines.
+ * On 64-bit machines we probably want to take advantage of the fact that
+ * hw doesn't really care about the size of the sw-only area.
+ *
+ * Alas, not anymore, we have more than 4 words of software, woops
+ */
+struct uhci_td {
+	/* Hardware fields */
+	__u32 link;
+	__u32 status;
+	__u32 info;
+	__u32 buffer;
+
+	/* Software fields */
+	struct list_head irq_list;	/* Active interrupt list.. */
+	usb_device_irq completed;	/* Completion handler routine */
+	unsigned int *backptr;		/* Where to remove this from.. */
+	void *dev_id;
+	int inuse;			/* Inuse? */
+	struct uhci_qh *qh;
+} __attribute__((aligned(32)));
+
+/*
+ * Note the alignment requirements of the entries
+ *
+ * Each UHCI device has pre-allocated QH and TD entries.
+ * You can use more than the pre-allocated ones, but I
+ * don't see you usually needing to.
+ */
+struct uhci;
+
+#define UHCI_MAXTD 64
+
+#define UHCI_MAXQH	16
+
+/* The usb device part must be first! */
+struct uhci_device {
+	struct usb_device	*usb;
+
+	struct uhci		*uhci;
+	struct uhci_qh		qh[UHCI_MAXQH];		/* These are the "common" qh's for each device */
+	struct uhci_td		td[UHCI_MAXTD];
+
+	unsigned long		data[16];
+};
+
+#define uhci_to_usb(uhci)	((uhci)->usb)
+#define usb_to_uhci(usb)	((struct uhci_device *)(usb)->hcpriv)
+
+/*
+ * The root hub pre-allocated QH's and TD's have
+ * some special global uses..
+ */
+#define control_td	td		/* Td's 0-30 */
+/* This is only for the root hub's TD list */
+#define tick_td		td[31]
+
+/*
+ * There are various standard queues. We set up several different
+ * queues for each of the three basic queue types: interrupt,
+ * control, and bulk.
+ *
+ *  - There are various different interrupt latencies: ranging from
+ *    every other USB frame (2 ms apart) to every 256 USB frames (ie
+ *    256 ms apart). Make your choice according to how obnoxious you
+ *    want to be on the wire, vs how critical latency is for you.
+ *  - The control list is done every frame.
+ *  - There are 4 bulk lists, so that up to four devices can have a
+ *    bulk list of their own and when run concurrently all four lists
+ *    will be be serviced.
+ *
+ * This is a bit misleading, there are various interrupt latencies, but they
+ * vary a bit, interrupt2 isn't exactly 2ms, it can vary up to 4ms since the
+ * other queues can "override" it. interrupt4 can vary up to 8ms, etc. Minor
+ * problem
+ *
+ * In the case of the root hub, these QH's are just head's of qh's. Don't
+ * be scared, it kinda makes sense. Look at this wonderful picture care of
+ * Linus:
+ *
+ *  generic-iso-QH  ->  dev1-iso-QH  ->  generic-irq-QH  ->  dev1-irq-QH  -> ...
+ *       |                       |                  |                   |
+ *      End          dev1-iso-TD1          End            dev1-irq-TD1
+ *                       |
+ *                   dev1-iso-TD2
+ *                       |
+ *                      ....
+ *
+ * This may vary a bit (the UHCI docs don't explicitly say you can put iso
+ * transfers in QH's and all of their pictures don't have that either) but
+ * other than that, that is what we're doing now
+ *
+ * To keep with Linus' nomenclature, this is called the qh skeleton. These
+ * labels (below) are only signficant to the root hub's qh's
+ */
+#define skel_iso_qh		qh[0]
+
+#define skel_int2_qh		qh[1]
+#define skel_int4_qh		qh[2]
+#define skel_int8_qh		qh[3]
+#define skel_int16_qh		qh[4]
+#define skel_int32_qh		qh[5]
+#define skel_int64_qh		qh[6]
+#define skel_int128_qh		qh[7]
+#define skel_int256_qh		qh[8]
+
+#define skel_control_qh		qh[9]
+
+#define skel_bulk0_qh		qh[10]
+#define skel_bulk1_qh		qh[11]
+#define skel_bulk2_qh		qh[12]
+#define skel_bulk3_qh		qh[13]
+
+/*
+ * These are significant to the devices allocation of QH's
+ */
+#if 0
+#define iso_qh			qh[0]
+#define int_qh			qh[1]	/* We have 2 "common" interrupt QH's */
+#define control_qh		qh[3]
+#define bulk_qh			qh[4]	/* We have 4 "common" bulk QH's */
+#define extra_qh		qh[8]	/* The rest, anything goes */
+#endif
+
+/*
+ * This describes the full uhci information.
+ *
+ * Note how the "proper" USB information is just
+ * a subset of what the full implementation needs.
+ */
+struct uhci {
+	int irq;
+	unsigned int io_addr;
+
+	struct usb_bus *bus;
+
+#if 0
+	/* These are "standard" QH's for the entire bus */
+	struct uhci_qh qh[UHCI_MAXQH];
+#endif
+	struct uhci_device *root_hub;		/* Root hub device descriptor.. */
+
+	struct uhci_framelist *fl;		/* Frame list */
+	struct list_head interrupt_list;	/* List of interrupt-active TD's for this uhci */
+};
+
+/* needed for the debugging code */
+struct uhci_td *uhci_link_to_td(unsigned int element);
+
+/* Debugging code */
+void show_td(struct uhci_td * td);
+void show_status(struct uhci *uhci);
+void show_queues(struct uhci *uhci);
+
+#endif
+
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/usb-debug.c linux/drivers/usb/usb-debug.c
--- v2.2.6/linux/drivers/usb/usb-debug.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/usb-debug.c	Wed Apr 21 02:32:59 1999
@@ -0,0 +1,127 @@
+/*
+ * debug.c - USB debug helper routines.
+ *
+ * I just want these out of the way where they aren't in your
+ * face, but so that you can still use them..
+ */
+#include <linux/kernel.h>
+
+#include "usb.h"
+
+static void usb_show_endpoint(struct usb_endpoint_descriptor *endpoint)
+{
+	usb_show_endpoint_descriptor(endpoint);
+}
+
+static void usb_show_interface(struct usb_interface_descriptor *interface)
+{
+	int i;
+
+	usb_show_interface_descriptor(interface);
+	for (i = 0 ; i < interface->bNumEndpoints; i++)
+		usb_show_endpoint(interface->endpoint + i);
+}
+
+static void usb_show_config(struct usb_config_descriptor *config)
+{
+	int i;
+
+	usb_show_config_descriptor(config);
+	for (i = 0 ; i < config->bNumInterfaces; i++)
+		usb_show_interface(config->interface + i);
+}
+
+void usb_show_device(struct usb_device *dev)
+{
+	int i;
+
+	usb_show_device_descriptor(&dev->descriptor);
+	for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
+		usb_show_config(dev->config + i);
+}
+
+
+/*
+ * Parse and show the different USB descriptors.
+ */
+void usb_show_device_descriptor(struct usb_device_descriptor *desc)
+{
+	printk("  USB version %x.%02x\n", desc->bcdUSB >> 8, desc->bcdUSB & 0xff);
+	printk("  Vendor:  %04x\n", desc->idVendor);
+	printk("  Product: %04x\n", desc->idProduct);
+	printk("  Configurations: %d\n", desc->bNumConfigurations);
+
+	printk("  Device Class: %d\n", desc->bDeviceClass);
+	switch (desc->bDeviceClass) {
+	case 0:
+		printk("    Per-interface classes\n");
+		break;
+	case 9:
+		printk("    Hub device class\n");
+		break;
+	case 0xff:
+		printk("    Vendor class\n");
+		break;
+	default:
+		printk("    Unknown class\n");
+	}
+}
+
+void usb_show_config_descriptor(struct usb_config_descriptor * desc)
+{
+	printk("Configuration:\n");
+	printk("  bLength             = %4d%s\n", desc->bLength,
+		desc->bLength == 9 ? "" : " (!!!)");
+	printk("  bDescriptorType     =   %02x\n", desc->bDescriptorType);
+	printk("  wTotalLength        = %04x\n", desc->wTotalLength);
+	printk("  bNumInterfaces      =   %02x\n", desc->bNumInterfaces);
+	printk("  bConfigurationValue =   %02x\n", desc->bConfigurationValue);
+	printk("  iConfiguration      =   %02x\n", desc->iConfiguration);
+	printk("  bmAttributes        =   %02x\n", desc->bmAttributes);
+	printk("  MaxPower            = %4dmA\n", desc->MaxPower * 2);
+}
+
+void usb_show_interface_descriptor(struct usb_interface_descriptor * desc)
+{
+	printk("  Interface:\n");
+	printk("    bLength             = %4d%s\n", desc->bLength,
+		desc->bLength == 9 ? "" : " (!!!)");
+	printk("    bDescriptorType     =   %02x\n", desc->bDescriptorType);
+	printk("    bInterfaceNumber    =   %02x\n", desc->bInterfaceNumber);
+	printk("    bAlternateSetting   =   %02x\n", desc->bAlternateSetting);
+	printk("    bNumEndpoints       =   %02x\n", desc->bNumEndpoints);
+	printk("    bInterfaceClass     =   %02x\n", desc->bInterfaceClass);
+	printk("    bInterfaceSubClass  =   %02x\n", desc->bInterfaceSubClass);
+	printk("    bInterfaceProtocol  =   %02x\n", desc->bInterfaceProtocol);
+	printk("    iInterface          =   %02x\n", desc->iInterface);
+}
+
+void usb_show_endpoint_descriptor(struct usb_endpoint_descriptor * desc)
+{
+	char *EndpointType[4] = { "Control", "Isochronous", "Bulk", "Interrupt" };
+	printk("    Endpoint:\n");
+	printk("      bLength             = %4d%s\n", desc->bLength,
+		desc->bLength == 7 ? "" : " (!!!)");
+	printk("      bDescriptorType     =   %02x\n", desc->bDescriptorType);
+	printk("      bEndpointAddress    =   %02x (%s)\n", desc->bEndpointAddress,
+		(desc->bEndpointAddress & 0x80) ? "in" : "out");
+	printk("      bmAttributes        =   %02x (%s)\n", desc->bmAttributes,
+		EndpointType[3 & desc->bmAttributes]);
+	printk("      wMaxPacketSize      = %04x\n", desc->wMaxPacketSize);
+	printk("      bInterval           =   %02x\n", desc->bInterval);
+}
+
+void usb_show_hub_descriptor(struct usb_hub_descriptor * desc)
+{
+	int len = 7;
+	unsigned char *ptr = (unsigned char *) desc;
+
+	printk("Interface:");
+	while (len) {
+		printk(" %02x", *ptr);
+		ptr++; len--;
+	}
+	printk("\n");
+}
+
+
diff -u --recursive --new-file v2.2.6/linux/drivers/usb/usb.c linux/drivers/usb/usb.c
--- v2.2.6/linux/drivers/usb/usb.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/usb.c	Wed Apr 28 11:14:03 1999
@@ -0,0 +1,616 @@
+/*
+ * driver/usb/usb.c
+ *
+ * (C) Copyright Linus Torvalds 1999
+ *
+ * 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..
+ *
+ * Think of this as a "USB library" rather than anything else.
+ * It should be considered a slave, with no callbacks. Callbacks
+ * are evil.
+ */
+
+/*
+ * Table 9-2
+ *
+ * Offset	Field		Size	Value		Desc
+ * 0		bmRequestType	1	Bitmap		D7:	Direction
+ *							0 = Host-to-device
+ *							1 = Device-to-host
+ *							D6..5:	Type
+ *							0 = Standard
+ *							1 = Class
+ *							2 = Vendor
+ *							3 = Reserved
+ *							D4..0:	Recipient
+ *							0 = Device
+ *							1 = Interface
+ *							2 = Endpoint
+ *							3 = Other
+ *							4..31 = Reserved
+ * 1		bRequest	1	Value		Specific request (9-3)
+ * 2		wValue		2	Value		Varies
+ * 4		wIndex		2	Index/Offset	Varies
+ * 6		wLength		2	Count		Bytes for data
+ */
+
+#include <linux/string.h>
+#include <linux/bitops.h>
+#include <linux/malloc.h>
+
+#include "usb.h"
+
+/*
+ * We have a per-interface "registered driver" list.
+ */
+static LIST_HEAD(usb_driver_list);
+
+int usb_register(struct usb_driver *new_driver)
+{
+	/* Add it to the list of known drivers */
+	list_add(&new_driver->driver_list, &usb_driver_list);
+
+	/*
+	 * We should go through all existing devices, and see if any of
+	 * them would be acceptable to the new driver.. Let's do that
+	 * in version 2.0.
+	 */
+	return 0;
+}
+
+void usb_deregister(struct usb_driver *driver)
+{
+	list_del(&driver->driver_list);
+}
+
+/*
+ * This entrypoint gets called for each new device.
+ *
+ * We now walk the list of registered USB drivers,
+ * looking for one that will accept this device as
+ * his..
+ */
+void usb_device_descriptor(struct usb_device *dev)
+{
+	struct list_head *tmp = usb_driver_list.next;
+
+	while (tmp != &usb_driver_list) {
+		struct usb_driver *driver = list_entry(tmp, struct usb_driver, driver_list);
+		tmp = tmp->next;
+		if (driver->probe(dev))
+			continue;
+		dev->driver = driver;
+		return;
+	}
+
+	/*
+	 * Ok, no driver accepted the device, so show the info
+	 * for debugging..
+	 */
+	printk("Unknown new USB device:\n");
+	usb_show_device(dev);
+}
+
+/*
+ * Parse the fairly incomprehensible output of
+ * the USB configuration data, and build up the
+ * USB device database.
+ */
+static int usb_expect_descriptor(unsigned char *ptr, int len, unsigned char desctype, unsigned char descindex)
+{
+	int parsed = 0;
+	int n_len;
+	unsigned short n_desc;
+
+	for (;;) {
+		int i;
+
+		if (len < descindex)
+			return -1;
+		n_desc = *(unsigned short *)ptr;
+		n_len = n_desc & 0xff;
+
+		if (n_desc == ((desctype << 8) + descindex))
+			break;
+
+		if (((n_desc >> 8)&0xFF) == desctype &&
+			n_len > descindex)
+		{
+			printk("bug: oversized descriptor.\n");
+			break;
+		}
+			
+		if (n_len < 2 || n_len > len)
+		{
+			printk("Short descriptor.\n");
+			return -1;
+		}
+		printk(
+		"Expected descriptor %02X/%02X, got %02X/%02X - skipping\n",
+			desctype, descindex,
+			(n_desc >> 8) & 0xFF, n_desc & 0xFF);
+		for (i = 0 ; i < n_len; i++)
+			printk("   %d %02x\n", i, ptr[i]);
+		len -= n_len;
+		ptr += n_len;
+		parsed += n_len;
+	}
+	
+	printk("Found %02X:%02X\n",
+		desctype, descindex);
+	return parsed;
+}
+
+/*
+ * Parse the even more incomprehensible mess made of the USB spec
+ * by USB audio having private magic to go with it.
+ */
+ 
+static int usb_check_descriptor(unsigned char *ptr, int len, unsigned char desctype)
+{
+	int n_len = ptr[0];
+
+	if (n_len < 2 || n_len > len)
+	{
+		printk("Short descriptor.\n");
+		return -1;
+	}
+
+	if (ptr[1] == desctype)
+		return 0;
+		
+	return -1;
+}
+
+
+static int usb_parse_endpoint(struct usb_device *dev, struct usb_endpoint_descriptor *endpoint, unsigned char *ptr, int len)
+{
+	int parsed = usb_expect_descriptor(ptr, len, USB_DT_ENDPOINT, 7);
+	int i;
+
+	if (parsed < 0)
+		return parsed;
+	memcpy(endpoint, ptr + parsed, ptr[parsed]);
+
+	parsed += ptr[parsed];
+	len -= ptr[parsed];
+
+	while((i = usb_check_descriptor(ptr+parsed, len, 0x25))>=0)
+	{
+		usb_audio_endpoint(endpoint, ptr+parsed+i);
+		len -= ptr[parsed+i];
+		parsed += ptr[parsed+i];
+	}
+	
+	return parsed;// + ptr[parsed];
+}
+
+static int usb_parse_interface(struct usb_device *dev, struct usb_interface_descriptor *interface, unsigned char *ptr, int len)
+{
+	int i;
+	int parsed = usb_expect_descriptor(ptr, len, USB_DT_INTERFACE, 9);
+	int retval;
+
+	if (parsed < 0)
+		return parsed;
+
+	memcpy(interface, ptr + parsed, *ptr);
+	len -= ptr[parsed];
+	parsed += ptr[parsed];
+
+	while((i=usb_check_descriptor(ptr+parsed, len, 0x24))>=0)
+	{
+		usb_audio_interface(interface, ptr+parsed+i);
+		len -= ptr[parsed+i];
+		parsed += ptr[parsed+i];
+	}
+	
+	if (interface->bNumEndpoints > USB_MAXENDPOINTS)
+	{
+		printk(KERN_WARNING "usb: too many endpoints.\n");
+		return -1;
+	}
+
+	for (i = 0; i < interface->bNumEndpoints; i++) {
+//		if(((USB_DT_HID << 8) | 9) == *(unsigned short*)(ptr + parsed)) {
+//			parsed += 9;	/* skip over the HID descriptor for now */
+//			len -= 9;
+//		}
+		retval = usb_parse_endpoint(dev, interface->endpoint + i, ptr + parsed, len);
+		if (retval < 0) return retval;
+		parsed += retval;
+		len -= retval;
+	}
+	return parsed;
+}
+
+static int usb_parse_config(struct usb_device *dev, struct usb_config_descriptor *config, unsigned char *ptr, int len)
+{
+	int i;
+	int parsed = usb_expect_descriptor(ptr, len, USB_DT_CONFIG, 9);
+
+	if (parsed < 0)
+		return parsed;
+
+	memcpy(config, ptr + parsed, *ptr);
+	len -= *ptr;
+	parsed += *ptr;
+
+	if (config->bNumInterfaces > USB_MAXINTERFACES)
+	{
+		printk(KERN_WARNING "usb: too many interfaces.\n");
+		return -1;
+	}
+
+	for (i = 0; i < config->bNumInterfaces; i++) {
+		int retval = usb_parse_interface(dev, config->interface + i, ptr + parsed, len);
+		if (retval < 0)
+			return parsed; // HACK
+//			return retval;
+		parsed += retval;
+		len -= retval;
+	}
+	return parsed;
+}
+
+int usb_parse_configuration(struct usb_device *dev, void *__buf, int bytes)
+{
+	int i;
+	unsigned char *ptr = __buf;
+
+	if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG)
+	{
+		printk(KERN_WARNING "usb: too many configurations.\n");
+		return -1;
+	}
+
+	for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
+		int retval = usb_parse_config(dev, dev->config + i, ptr, bytes);
+		if (retval < 0)
+			return retval;
+		ptr += retval;
+		bytes += retval;
+	}
+	return 0;
+}
+
+void usb_init_root_hub(struct usb_device *dev)
+{
+	dev->devnum = -1;
+	dev->slow = 0;
+}
+
+/*
+ * Something got disconnected. Get rid of it, and all of its children.
+ */
+void usb_disconnect(struct usb_device **pdev)
+{
+	struct usb_device * dev = *pdev;
+
+	if (dev) {
+		int i;
+
+		*pdev = NULL;
+
+		printk("USB disconnect on device %d\n", dev->devnum);
+
+		if(dev->driver) dev->driver->disconnect(dev);
+
+		/* Free up all the children.. */
+		for (i = 0; i < USB_MAXCHILDREN; i++) {
+			struct usb_device **child = dev->children + i;
+			usb_disconnect(child);
+		}
+
+		/* Free up the device itself, including its device number */
+		if (dev->devnum > 0)
+			clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
+		dev->bus->op->deallocate(dev);
+	}
+}
+
+
+/*
+ * Connect a new USB device. This basically just initializes
+ * the USB device information and sets up the topology - it's
+ * up to the low-level driver to reset the port and actually
+ * do the setup (the upper levels don't know how to do that).
+ */
+void usb_connect(struct usb_device *dev)
+{
+	int devnum;
+
+	dev->descriptor.bMaxPacketSize0 = 8;  /* XXX fixed 8 bytes for now */
+
+	devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1);
+	if (devnum < 128) {
+		set_bit(devnum, dev->bus->devmap.devicemap);
+		dev->devnum = devnum;
+	}
+}
+
+/*
+ * These are the actual routines to send
+ * and receive control messages.
+ */
+int usb_set_address(struct usb_device *dev)
+{
+	devrequest dr;
+
+	dr.requesttype = 0;
+	dr.request = USB_REQ_SET_ADDRESS;
+	dr.value = dev->devnum;
+	dr.index = 0;
+	dr.length = 0;
+
+	return dev->bus->op->control_msg(dev, usb_snddefctrl(dev), &dr, NULL, 0);
+}
+
+int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size)
+{
+	devrequest dr;
+
+	dr.requesttype = 0x80;
+	dr.request = USB_REQ_GET_DESCRIPTOR;
+	dr.value = (type << 8) + index;
+	dr.index = 0;
+	dr.length = size;
+
+	return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, size);
+}
+
+int usb_get_device_descriptor(struct usb_device *dev)
+{
+	return usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, sizeof(dev->descriptor));
+}
+
+int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
+{
+	devrequest dr;
+
+	dr.requesttype = USB_RT_HUB | 0x80;
+	dr.request = USB_REQ_GET_DESCRIPTOR;
+	dr.value = (USB_DT_HUB << 8);
+	dr.index = 0;
+	dr.length = size;
+
+	return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, data, size);
+}
+
+int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
+{
+	devrequest dr;
+
+	dr.requesttype = USB_RT_PORT;
+	dr.request = USB_REQ_CLEAR_FEATURE;
+	dr.value = feature;
+	dr.index = port;
+	dr.length = 0;
+
+	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
+}
+
+int usb_set_port_feature(struct usb_device *dev, int port, int feature)
+{
+	devrequest dr;
+
+	dr.requesttype = USB_RT_PORT;
+	dr.request = USB_REQ_SET_FEATURE;
+	dr.value = feature;
+	dr.index = port;
+	dr.length = 0;
+
+	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0);
+}
+
+int usb_get_hub_status(struct usb_device *dev, void *data)
+{
+	devrequest dr;
+
+	dr.requesttype = USB_RT_HUB | 0x80;
+	dr.request = USB_REQ_GET_STATUS;
+	dr.value = 0;
+	dr.index = 0;
+	dr.length = 4;
+
+	return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, data, 4);
+}
+
+int usb_get_port_status(struct usb_device *dev, int port, void *data)
+{
+	devrequest dr;
+
+	dr.requesttype = USB_RT_PORT | 0x80;
+	dr.request = USB_REQ_GET_STATUS;
+	dr.value = 0;
+	dr.index = port;
+	dr.length = 4;
+
+	return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, data, 4);
+}
+
+int usb_get_protocol(struct usb_device *dev)
+{
+	unsigned char buf[8];
+	devrequest dr;
+
+	dr.requesttype = USB_RT_HIDD | 0x80;
+	dr.request = USB_REQ_GET_PROTOCOL;
+	dr.value = 0;
+	dr.index = 1;
+	dr.length = 1;
+
+	if (dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev, 0), &dr, buf, 1))
+		return -1;
+
+	return buf[0];
+}
+
+int usb_set_protocol(struct usb_device *dev, int protocol)
+{
+	devrequest dr;
+
+	dr.requesttype = USB_RT_HIDD;
+	dr.request = USB_REQ_SET_PROTOCOL;
+	dr.value = protocol;
+	dr.index = 1;
+	dr.length = 0;
+
+	if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0))
+		return -1;
+
+	return 0;
+}
+
+/* keyboards want a nonzero duration according to HID spec, but
+   mice should use infinity (0) -keryan */
+int usb_set_idle(struct usb_device *dev,  int duration, int report_id)
+{
+	devrequest dr;
+
+	dr.requesttype = USB_RT_HIDD;
+	dr.request = USB_REQ_SET_IDLE;
+	dr.value = (duration << 8) | report_id;
+	dr.index = 1;
+	dr.length = 0;
+
+	if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0))
+		return -1;
+
+	return 0;
+}
+
+int usb_set_configuration(struct usb_device *dev, int configuration)
+{
+	devrequest dr;
+
+	dr.requesttype = 0;
+	dr.request = USB_REQ_SET_CONFIGURATION;
+	dr.value = configuration;
+	dr.index = 0;
+	dr.length = 0;
+
+	if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0))
+		return -1;
+
+	return 0;
+}
+
+int usb_get_report(struct usb_device *dev)
+{
+	unsigned char buf[8];
+	devrequest dr;
+
+	dr.requesttype = USB_RT_HIDD | 0x80;
+	dr.request = USB_REQ_GET_REPORT;
+	dr.value = 0x100;
+	dr.index = 1;
+	dr.length = 3;
+
+	if (dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev, 0), &dr, buf, 3))
+		return -1;
+
+	return buf[0];
+}
+
+int usb_get_configuration(struct usb_device *dev)
+{
+	unsigned int size;
+	unsigned char buffer[400];
+
+	/* Get the first 8 bytes - guaranteed */
+	if (usb_get_descriptor(dev, USB_DT_CONFIG, 0, buffer, 8))
+		return -1;
+
+	/* Get the full buffer */
+	size = *(unsigned short *)(buffer+2);
+	if (size > sizeof(buffer))
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 13'
echo 'File patch-2.2.7 is continued in part 14'
echo 14 > _shar_seq_.tmp
#!/bin/sh
# this is part 15 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 15; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
+           for something that is really too small */
+
+	do {
+		nr_hash = (1UL << order) * PAGE_SIZE /
+		    sizeof(struct buffer_head *);
+		hash_table = (struct buffer_head **)
+		    __get_free_pages(GFP_ATOMIC, order);
+	} while (hash_table == NULL && --order > 4);
X 	
X 	if (!hash_table)
X 		panic("Failed to allocate buffer hash table\n");
diff -u --recursive --new-file v2.2.6/linux/fs/coda/dir.c linux/fs/coda/dir.c
--- v2.2.6/linux/fs/coda/dir.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/coda/dir.c	Fri Apr 23 21:20:37 1999
@@ -29,7 +29,7 @@
X /* dir inode-ops */
X static int coda_create(struct inode *dir, struct dentry *new, int mode);
X static int coda_mknod(struct inode *dir, struct dentry *new, int mode, int rdev);
-static int coda_lookup(struct inode *dir, struct dentry *target);
+static struct dentry *coda_lookup(struct inode *dir, struct dentry *target);
X static int coda_link(struct dentry *old_dentry, struct inode *dir_inode, 
X 		     struct dentry *entry);
X static int coda_unlink(struct inode *dir_inode, struct dentry *entry);
@@ -107,7 +107,7 @@
X 
X /* inode operations for directories */
X /* acces routines: lookup, readlink, permission */
-static int coda_lookup(struct inode *dir, struct dentry *entry)
+static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry)
X {
X         struct coda_inode_info *dircnp;
X 	struct inode *res_inode = NULL;
@@ -125,16 +125,9 @@
X 	if ( length > CODA_MAXNAMLEN ) {
X 	        printk("name too long: lookup, %s (%*s)\n", 
X 		       coda_f2s(&dircnp->c_fid), length, name);
-		return -ENAMETOOLONG;
+		return ERR_PTR(-ENAMETOOLONG);
X 	}
X 
-
-	if (!dir || !S_ISDIR(dir->i_mode)) {
-		printk("coda_lookup: inode is NULL or not a directory\n");
-		return -ENOTDIR;
-	}
-
-
X         CDEBUG(D_INODE, "name %s, len %d in ino %ld, fid %s\n", 
X 	       name, length, dir->i_ino, coda_f2s(&dircnp->c_fid));
X 
@@ -160,11 +153,11 @@
X 		}
X 	    	error = coda_cnode_make(&res_inode, &resfid, dir->i_sb);
X 		if (error)
-			return error;
+			return ERR_PTR(error);
X 	} else if (error != -ENOENT) {
X 	        CDEBUG(D_INODE, "error for %s(%*s)%d\n",
X 		       coda_f2s(&dircnp->c_fid), length, name, error);
-		return error;
+		return ERR_PTR(error);
X 	}
X 	CDEBUG(D_INODE, "lookup: %s is (%s), type %d result %d, dropme %d\n",
X 	       name, coda_f2s(&resfid), type, error, dropme);
@@ -178,7 +171,7 @@
X 		ITOC(res_inode)->c_flags |= C_VATTR;
X 	}
X         EXIT;
-        return 0;
+        return NULL;
X }
X 
X 
@@ -236,11 +229,6 @@
X 
X 	CDEBUG(D_INODE, "name: %s, length %d, mode %o\n",name, length, mode);
X 
-        if (!dir || !S_ISDIR(dir->i_mode)) {
-                printk("coda_create: inode is null or not a directory\n");
-                return -ENOENT;
-        }
-
X 	if (coda_isroot(dir) && coda_iscontrol(name, length))
X 		return -EPERM;
X 
@@ -286,11 +274,6 @@
X 
X 	CDEBUG(D_INODE, "name: %s, length %d, mode %o, rdev %x\n",name, length, mode, rdev);
X 
-        if (!dir || !S_ISDIR(dir->i_mode)) {
-                printk("coda_mknod: inode is null or not a directory\n");
-                return -ENOENT;
-        }
-
X 	if (coda_isroot(dir) && coda_iscontrol(name, length))
X 		return -EPERM;
X 
@@ -332,11 +315,6 @@
X 	ENTRY;
X 	coda_vfs_stat.mkdir++;
X 
-	if (!dir || !S_ISDIR(dir->i_mode)) {
-		printk("coda_mkdir: inode is NULL or not a directory\n");
-		return -ENOENT;
-	}
-
X 	if (coda_isroot(dir) && coda_iscontrol(name, len))
X 		return -EPERM;
X 
@@ -490,10 +468,6 @@
X 	ENTRY;
X 	coda_vfs_stat.rmdir++;
X 
-	if (!dir || !S_ISDIR(dir->i_mode)) {
-		printk("coda_rmdir: inode is NULL or not a directory\n");
-		return -ENOENT;
-	}
X         dircnp = ITOC(dir);
X 
X 	if (!list_empty(&de->d_hash))
@@ -571,11 +545,6 @@
X 
X         ENTRY;
X 	coda_vfs_stat.readdir++;
-
-        if (!inode || !inode->i_sb || !S_ISDIR(inode->i_mode)) {
-                printk("coda_readdir: inode is NULL or not a directory\n");
-                return -EBADF;
-        }
X 
X         cnp = ITOC(inode);
X         if ( !cnp->c_ovp ) {
diff -u --recursive --new-file v2.2.6/linux/fs/dcache.c linux/fs/dcache.c
--- v2.2.6/linux/fs/dcache.c	Tue Mar 23 14:35:48 1999
+++ linux/fs/dcache.c	Sun Apr 25 23:17:56 1999
@@ -471,8 +471,12 @@
X  */
X void shrink_dcache_memory(int priority, unsigned int gfp_mask)
X {
-	if (gfp_mask & __GFP_IO)
-		prune_dcache(0);
+	if (gfp_mask & __GFP_IO) {
+		int count = 0;
+		if (priority)
+			count = dentry_stat.nr_unused / priority;
+		prune_dcache(count);
+	}
X }
X 
X #define NAME_ALLOC_LEN(len)	((len+16) & ~15)
diff -u --recursive --new-file v2.2.6/linux/fs/devpts/root.c linux/fs/devpts/root.c
--- v2.2.6/linux/fs/devpts/root.c	Mon Oct  5 13:13:42 1998
+++ linux/fs/devpts/root.c	Fri Apr 23 21:20:37 1999
@@ -17,7 +17,7 @@
X #include "devpts_i.h"
X 
X static int devpts_root_readdir(struct file *,void *,filldir_t);
-static int devpts_root_lookup(struct inode *,struct dentry *);
+static struct dentry *devpts_root_lookup(struct inode *,struct dentry *);
X static int devpts_revalidate(struct dentry *);
X 
X static struct file_operations devpts_root_operations = {
@@ -81,9 +81,6 @@
X 	off_t nr;
X 	char numbuf[16];
X 
-	if (!inode || !S_ISDIR(inode->i_mode))
-		return -ENOTDIR;
-
X 	nr = filp->f_pos;
X 
X 	switch(nr)
@@ -131,42 +128,39 @@
X 	return ( sbi->inodes[dentry->d_inode->i_ino - 2] == dentry->d_inode );
X }
X 
-static int devpts_root_lookup(struct inode * dir, struct dentry * dentry)
+static struct dentry *devpts_root_lookup(struct inode * dir, struct dentry * dentry)
X {
X 	struct devpts_sb_info *sbi = SBI(dir->i_sb);
X 	unsigned int entry;
X 	int i;
X 	const char *p;
X 
-	if (!S_ISDIR(dir->i_mode))
-		return -ENOTDIR;
-
X 	dentry->d_inode = NULL;	/* Assume failure */
X 	dentry->d_op    = &devpts_dentry_operations;
X 
X 	if ( dentry->d_name.len == 1 && dentry->d_name.name[0] == '0' ) {
X 		entry = 0;
X 	} else if ( dentry->d_name.len < 1 ) {
-		return 0;
+		return NULL;
X 	} else {
X 		p = dentry->d_name.name;
X 		if ( *p < '1' || *p > '9' )
-			return 0;
+			return NULL;
X 		entry = *p++ - '0';
X 
X 		for ( i = dentry->d_name.len-1 ; i ; i-- ) {
X 			unsigned int nentry = *p++ - '0';
X 			if ( nentry > 9 )
-				return 0;
+				return NULL;
X 			nentry += entry * 10;
X 			if (nentry < entry)
-				return 0;
+				return NULL;
X 			entry = nentry;
X 		}
X 	}
X 
X 	if ( entry >= sbi->max_ptys )
-		return 0;
+		return NULL;
X 
X 	dentry->d_inode = sbi->inodes[entry];
X 	if ( dentry->d_inode )
@@ -174,5 +168,5 @@
X 	
X 	d_add(dentry, dentry->d_inode);
X 
-	return 0;
+	return NULL;
X }
diff -u --recursive --new-file v2.2.6/linux/fs/ext2/dir.c linux/fs/ext2/dir.c
--- v2.2.6/linux/fs/ext2/dir.c	Thu Nov 12 16:21:22 1998
+++ linux/fs/ext2/dir.c	Fri Apr 23 21:20:37 1999
@@ -115,8 +115,6 @@
X 	int err;
X 	struct inode *inode = filp->f_dentry->d_inode;
X 
-	if (!inode || !S_ISDIR(inode->i_mode))
-		return -EBADF;
X 	sb = inode->i_sb;
X 
X 	stored = 0;
diff -u --recursive --new-file v2.2.6/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
--- v2.2.6/linux/fs/ext2/namei.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/ext2/namei.c	Fri Apr 23 21:20:37 1999
@@ -168,14 +168,14 @@
X 	return NULL;
X }
X 
-int ext2_lookup(struct inode * dir, struct dentry *dentry)
+struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry)
X {
X 	struct inode * inode;
X 	struct ext2_dir_entry_2 * de;
X 	struct buffer_head * bh;
X 
X if (dentry->d_name.len > EXT2_NAME_LEN)
-		return -ENAMETOOLONG;
+		return ERR_PTR(-ENAMETOOLONG);
X 
X 	bh = ext2_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
X 	inode = NULL;
@@ -185,10 +185,10 @@
X 		inode = iget(dir->i_sb, ino);
X 
X 		if (!inode)
-			return -EACCES;
+			return ERR_PTR(-EACCES);
X 	}
X 	d_add(dentry, inode);
-	return 0;
+	return NULL;
X }
X 
X /*
diff -u --recursive --new-file v2.2.6/linux/fs/fat/dir.c linux/fs/fat/dir.c
--- v2.2.6/linux/fs/fat/dir.c	Wed Aug 26 11:37:40 1998
+++ linux/fs/fat/dir.c	Fri Apr 23 21:20:37 1999
@@ -9,6 +9,7 @@
X  *
X  *  VFAT extensions by Gordon Chaffee <cha...@plateau.cs.berkeley.edu>
X  *  Merged with msdos fs by Henrik Storner <sto...@osiris.ping.dk>
+ *  Plugged buffer overrun in readdir(). AV
X  */
X 
X #define ASC_LINUX_VERSION(V, P, S)	(((V) * 65536) + ((P) * 256) + (S))
@@ -59,6 +60,7 @@
X  * characters are a sort of uuencoded 16 bit Unicode value.  This lets
X  * us do a full dump and restore of Unicode filenames.  We could get
X  * into some trouble with long Unicode names, but ignore that right now.
+ * Ahem... Stack smashing in ring 0 isn't fun. Fixed.
X  */
X static int
X uni16_to_x8(unsigned char *ascii, unsigned char *uni, int uni_xlate,
@@ -93,6 +95,11 @@
X 				*op++ = '?';
X 			}
X 		}
+		/* We have some slack there, so it's OK */
+		if (op>ascii+256) {
+			op = ascii + 256;
+			break;
+		}
X 	}
X 	*op = 0;
X 	return (op - ascii);
@@ -138,8 +145,6 @@
X 	unsigned char *unicode = NULL;
X 	struct nls_table *nls = MSDOS_SB(sb)->nls_io;
X 
-	if (!inode || !S_ISDIR(inode->i_mode))
-		return -EBADF;
X /* Fake . and .. for the root directory. */
X 	if (inode->i_ino == MSDOS_ROOT_INO) {
X 		while (oldpos < 2) {
@@ -186,9 +191,17 @@
X 			id = ds->id;
X 			if (id & 0x40) {
X 				slots = id & ~0x40;
-				long_slots = slots;
-				is_long = 1;
-				alias_checksum = ds->alias_checksum;
+				/*
+				 * Dirty, but not dirtier than the original,
+				 * and plugs the hole.
+				 */
+				if (slots > 20)
+					slots = 0;
+				else {
+					long_slots = slots;
+					is_long = 1;
+					alias_checksum = ds->alias_checksum;
+				}
X 			}
X 
X 			get_new_entry = 1;
diff -u --recursive --new-file v2.2.6/linux/fs/fat/fatfs_syms.c linux/fs/fat/fatfs_syms.c
--- v2.2.6/linux/fs/fat/fatfs_syms.c	Wed May 20 19:10:40 1998
+++ linux/fs/fat/fatfs_syms.c	Tue Apr 20 14:37:10 1999
@@ -54,6 +54,7 @@
X EXPORT_SYMBOL(unlock_fat);
X EXPORT_SYMBOL(fat_dir_ioctl);
X EXPORT_SYMBOL(fat_readpage);
+EXPORT_SYMBOL(fat_is_binary);
X 
X int init_fat_fs(void)
X {
diff -u --recursive --new-file v2.2.6/linux/fs/fat/inode.c linux/fs/fat/inode.c
--- v2.2.6/linux/fs/fat/inode.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/fat/inode.c	Fri Apr 23 21:20:37 1999
@@ -332,7 +332,6 @@
X 		fat_brelse (sb, bh);
X 		goto out_no_bread;
X 	}
-	set_blocksize(sb->s_dev, blksize);
X 
X /*
X  * The DOS3 partition size limit is *not* 32M as many people think.  
@@ -423,6 +422,7 @@
X 		    || !b->secs_track || !b->heads;
X 	}
X 	fat_brelse(sb, bh);
+	set_blocksize(sb->s_dev, blksize);
X 	/*
X 		This must be done after the brelse because the bh is a dummy
X 		allocated by fat_bread (see buffer.c)
@@ -703,8 +703,8 @@
X 	if(raw_entry->attr & ATTR_SYS)
X 		if (MSDOS_SB(sb)->options.sys_immutable)
X 			inode->i_flags |= S_IMMUTABLE;
-	MSDOS_I(inode)->i_binary = is_binary(MSDOS_SB(sb)->options.conversion,
-	    raw_entry->ext);
+	MSDOS_I(inode)->i_binary =
+	    fat_is_binary(MSDOS_SB(sb)->options.conversion, raw_entry->ext);
X 	MSDOS_I(inode)->i_attrs = raw_entry->attr & ATTR_UNUSED;
X 	/* this is as close to the truth as we can get ... */
X 	inode->i_blksize = MSDOS_SB(sb)->cluster_size*SECTOR_SIZE;
diff -u --recursive --new-file v2.2.6/linux/fs/fat/misc.c linux/fs/fat/misc.c
--- v2.2.6/linux/fs/fat/misc.c	Fri Jan 23 18:10:32 1998
+++ linux/fs/fat/misc.c	Tue Apr 20 14:37:10 1999
@@ -51,11 +51,11 @@
X 
X 
X /*
- * is_binary selects optional text conversion based on the conversion mode and
- * the extension part of the file name.
+ * fat_is_binary selects optional text conversion based on the conversion mode
+ * and the extension part of the file name.
X  */
X 
-int is_binary(char conversion,char *extension)
+int fat_is_binary(char conversion,char *extension)
X {
X 	char *walk;
X 
diff -u --recursive --new-file v2.2.6/linux/fs/hfs/dir_cap.c linux/fs/hfs/dir_cap.c
--- v2.2.6/linux/fs/hfs/dir_cap.c	Sun Nov  8 14:03:06 1998
+++ linux/fs/hfs/dir_cap.c	Fri Apr 23 21:20:37 1999
@@ -27,7 +27,7 @@
X 
X /*================ Forward declarations ================*/
X 
-static int cap_lookup(struct inode *, struct dentry *);
+static struct dentry *cap_lookup(struct inode *, struct dentry *);
X static int cap_readdir(struct file *, void *, filldir_t);
X 
X /*================ Global variables ================*/
@@ -147,7 +147,7 @@
X  * inode corresponding to an entry in a directory, given the inode for
X  * the directory and the name (and its length) of the entry.
X  */
-static int cap_lookup(struct inode * dir, struct dentry *dentry)
+static struct dentry *cap_lookup(struct inode * dir, struct dentry *dentry)
X {
X 	ino_t dtype;
X 	struct hfs_name cname;
@@ -155,10 +155,6 @@
X 	struct hfs_cat_key key;
X 	struct inode *inode = NULL;
X 
-	if (!dir || !S_ISDIR(dir->i_mode)) {
-		return -ENOENT;
-	}
-
X 	dentry->d_op = &hfs_dentry_operations;
X 	entry = HFS_I(dir)->entry;
X 	dtype = HFS_ITYPE(dir->i_ino);
@@ -207,7 +203,7 @@
X 
X done:
X 	d_add(dentry, inode);
-	return 0;
+	return NULL;
X }
X 
X /*
diff -u --recursive --new-file v2.2.6/linux/fs/hfs/dir_dbl.c linux/fs/hfs/dir_dbl.c
--- v2.2.6/linux/fs/hfs/dir_dbl.c	Sun Nov  8 14:03:06 1998
+++ linux/fs/hfs/dir_dbl.c	Fri Apr 23 21:20:37 1999
@@ -23,7 +23,7 @@
X 
X /*================ Forward declarations ================*/
X 
-static int dbl_lookup(struct inode *, struct dentry *);
+static struct dentry *dbl_lookup(struct inode *, struct dentry *);
X static int dbl_readdir(struct file *, void *, filldir_t);
X static int dbl_create(struct inode *, struct dentry *, int);
X static int dbl_mkdir(struct inode *, struct dentry *, int);
@@ -130,17 +130,13 @@
X  * the inode for the directory and the name (and its length) of the
X  * entry.
X  */
-static int dbl_lookup(struct inode * dir, struct dentry *dentry)
+static struct dentry *dbl_lookup(struct inode * dir, struct dentry *dentry)
X {
X 	struct hfs_name cname;
X 	struct hfs_cat_entry *entry;
X 	struct hfs_cat_key key;
X 	struct inode *inode = NULL;
X 
-	if (!dir || !S_ISDIR(dir->i_mode)) {
-		return -ENOENT;
-	}
-
X 	dentry->d_op = &hfs_dentry_operations;
X 	entry = HFS_I(dir)->entry;
X 	
@@ -173,7 +169,7 @@
X 	
X done:
X 	d_add(dentry, inode);
-	return 0;
+	return NULL;
X }
X 
X /*
diff -u --recursive --new-file v2.2.6/linux/fs/hfs/dir_nat.c linux/fs/hfs/dir_nat.c
--- v2.2.6/linux/fs/hfs/dir_nat.c	Sun Nov  8 14:03:06 1998
+++ linux/fs/hfs/dir_nat.c	Fri Apr 23 21:20:37 1999
@@ -29,7 +29,7 @@
X 
X /*================ Forward declarations ================*/
X 
-static int nat_lookup(struct inode *, struct dentry *);
+static struct dentry *nat_lookup(struct inode *, struct dentry *);
X static int nat_readdir(struct file *, void *, filldir_t);
X static int nat_rmdir(struct inode *, struct dentry *);
X static int nat_hdr_unlink(struct inode *, struct dentry *);
@@ -136,7 +136,7 @@
X  * the inode corresponding to an entry in a directory, given the inode
X  * for the directory and the name (and its length) of the entry.
X  */
-static int nat_lookup(struct inode * dir, struct dentry *dentry)
+static struct dentry *nat_lookup(struct inode * dir, struct dentry *dentry)
X {
X 	ino_t dtype;
X 	struct hfs_name cname;
@@ -144,10 +144,6 @@
X 	struct hfs_cat_key key;
X 	struct inode *inode = NULL;
X 
-	if (!dir || !S_ISDIR(dir->i_mode)) {
-		return -ENOENT;
-	}
-
X 	dentry->d_op = &hfs_dentry_operations;
X 	entry = HFS_I(dir)->entry;
X 	dtype = HFS_ITYPE(dir->i_ino);
@@ -199,7 +195,7 @@
X 
X done:
X 	d_add(dentry, inode);
-	return 0;
+	return NULL;
X }
X 
X /*
diff -u --recursive --new-file v2.2.6/linux/fs/hpfs/hpfs_fs.c linux/fs/hpfs/hpfs_fs.c
--- v2.2.6/linux/fs/hpfs/hpfs_fs.c	Fri Oct  9 13:27:14 1998
+++ linux/fs/hpfs/hpfs_fs.c	Fri Apr 23 21:20:38 1999
@@ -192,7 +192,7 @@
X 			     size_t count, loff_t *ppos);
X static int hpfs_readdir(struct file *filp,
X 			void *dirent, filldir_t filldir);
-static int hpfs_lookup(struct inode *, struct dentry *);
+static struct dentry *hpfs_lookup(struct inode *, struct dentry *);
X 
X static const struct file_operations hpfs_dir_ops =
X {
@@ -1119,7 +1119,7 @@
X  * the boondocks.)
X  */
X 
-static int hpfs_lookup(struct inode *dir, struct dentry *dentry)
+static struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry)
X {
X 	const char *name = dentry->d_name.name;
X 	int len = dentry->d_name.len;
@@ -1129,14 +1129,6 @@
X 	int retval;
X 	struct quad_buffer_head qbh;
X 
-	/* In case of madness */
-
-	retval = -ENOTDIR;
-	if (dir == 0)
-		goto out;
-	if (!S_ISDIR(dir->i_mode))
-		goto out;
-
X 	/*
X 	 * Read in the directory entry. "." is there under the name ^A^A .
X 	 * Always read the dir even for . and .. in case we need the dates.
@@ -1208,7 +1200,7 @@
X 	brelse4(&qbh);
X 
X       out:
-	return retval;
+	return ERR_PTR(retval);
X }
X 
X /*
@@ -1373,11 +1365,6 @@
X 	char * tempname;
X 	long old_pos;
X 	struct inode *inode = filp->f_dentry->d_inode;
-
-	if (inode == 0
-	    || inode->i_sb == 0
-	    || !S_ISDIR(inode->i_mode))
-		return -EBADF;
X 
X 	tempname = (char *) __get_free_page(GFP_KERNEL);
X 	if (!tempname)
diff -u --recursive --new-file v2.2.6/linux/fs/inode.c linux/fs/inode.c
--- v2.2.6/linux/fs/inode.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/inode.c	Mon Apr 26 13:56:49 1999
@@ -359,10 +359,8 @@
X 		found = 1;
X 	}
X 
-	if (found) {
+	if (found)
X 		dispose_list(freeable);
-		found = 1;	/* silly compiler */
-	}
X 
X 	return found;
X }
@@ -750,7 +748,7 @@
X  * Initialize the hash tables and default
X  * value for max inodes
X  */
-#define MAX_INODE (12288)
+#define MAX_INODE (16384)
X 
X void __init inode_init(void)
X {
diff -u --recursive --new-file v2.2.6/linux/fs/isofs/dir.c linux/fs/isofs/dir.c
--- v2.2.6/linux/fs/isofs/dir.c	Thu Nov 12 16:21:22 1998
+++ linux/fs/isofs/dir.c	Fri Apr 23 21:20:38 1999
@@ -295,9 +295,6 @@
X 	struct iso_directory_record * tmpde;
X 	struct inode *inode = filp->f_dentry->d_inode;
X 
-	if (!inode || !S_ISDIR(inode->i_mode))
-		return -EBADF;
-
X 	tmpname = (char *) __get_free_page(GFP_KERNEL);
X 	if (!tmpname)
X 		return -ENOMEM;
diff -u --recursive --new-file v2.2.6/linux/fs/isofs/namei.c linux/fs/isofs/namei.c
--- v2.2.6/linux/fs/isofs/namei.c	Tue Jan 19 11:32:52 1999
+++ linux/fs/isofs/namei.c	Fri Apr 23 21:20:38 1999
@@ -228,7 +228,7 @@
X 	return retval;
X }
X 
-int isofs_lookup(struct inode * dir, struct dentry * dentry)
+struct dentry *isofs_lookup(struct inode * dir, struct dentry * dentry)
X {
X 	unsigned long ino;
X 	struct buffer_head * bh;
@@ -237,12 +237,6 @@
X #ifdef DEBUG
X 	printk("lookup: %x %s\n",dir->i_ino, dentry->d_name.name);
X #endif
-	if (!dir)
-		return -ENOENT;
-
-	if (!S_ISDIR(dir->i_mode))
-		return -ENOENT;
-
X 	dentry->d_op = dir->i_sb->s_root->d_op;
X 
X 	bh = isofs_find_entry(dir, dentry, &ino);
@@ -253,8 +247,8 @@
X 
X 		inode = iget(dir->i_sb,ino);
X 		if (!inode)
-			return -EACCES;
+			return ERR_PTR(-EACCES);
X 	}
X 	d_add(dentry, inode);
-	return 0;
+	return NULL;
X }
diff -u --recursive --new-file v2.2.6/linux/fs/minix/dir.c linux/fs/minix/dir.c
--- v2.2.6/linux/fs/minix/dir.c	Thu Nov 12 16:21:22 1998
+++ linux/fs/minix/dir.c	Fri Apr 23 21:20:38 1999
@@ -68,8 +68,6 @@
X 	struct minix_sb_info * info;
X 	struct inode *inode = filp->f_dentry->d_inode;
X 
-	if (!inode || !inode->i_sb || !S_ISDIR(inode->i_mode))
-		return -EBADF;
X 	info = &inode->i_sb->u.minix_sb;
X 	if (filp->f_pos & (info->s_dirsize - 1))
X 		return -EBADF;
diff -u --recursive --new-file v2.2.6/linux/fs/minix/inode.c linux/fs/minix/inode.c
--- v2.2.6/linux/fs/minix/inode.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/minix/inode.c	Sat Apr 24 12:45:37 1999
@@ -38,14 +38,13 @@
X 	minix_free_inode(inode);
X }
X 
-static void minix_commit_super (struct super_block * sb,
-			       struct minix_super_block * ms)
+static void minix_commit_super(struct super_block * sb)
X {
X 	mark_buffer_dirty(sb->u.minix_sb.s_sbh, 1);
X 	sb->s_dirt = 0;
X }
X 
-static void minix_write_super (struct super_block * sb)
+static void minix_write_super(struct super_block * sb)
X {
X 	struct minix_super_block * ms;
X 
@@ -54,7 +53,7 @@
X 
X 		if (ms->s_state & MINIX_VALID_FS)
X 			ms->s_state &= ~MINIX_VALID_FS;
-		minix_commit_super (sb, ms);
+		minix_commit_super(sb);
X 	}
X 	sb->s_dirt = 0;
X }
@@ -106,7 +105,7 @@
X 		ms->s_state = sb->u.minix_sb.s_mount_state;
X 		mark_buffer_dirty(sb->u.minix_sb.s_sbh, 1);
X 		sb->s_dirt = 1;
-		minix_commit_super (sb, ms);
+		minix_commit_super(sb);
X 	}
X 	else {
X 	  	/* Mount a partition which is read-only, read-write. */
diff -u --recursive --new-file v2.2.6/linux/fs/minix/namei.c linux/fs/minix/namei.c
--- v2.2.6/linux/fs/minix/namei.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/minix/namei.c	Fri Apr 23 21:20:38 1999
@@ -116,7 +116,7 @@
X 	0		/* compare */
X };
X 
-int minix_lookup(struct inode * dir, struct dentry *dentry)
+struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry)
X {
X 	struct inode * inode = NULL;
X 	struct minix_dir_entry * de;
@@ -132,10 +132,10 @@
X 		inode = iget(dir->i_sb, ino);
X  
X 		if (!inode)
-			return -EACCES;
+			return ERR_PTR(-EACCES);
X 	}
X 	d_add(dentry, inode);
-	return 0;
+	return NULL;
X }
X 
X /*
@@ -221,8 +221,6 @@
X 	struct buffer_head * bh;
X 	struct minix_dir_entry * de;
X 
-	if (!dir)
-		return -ENOENT;
X 	inode = minix_new_inode(dir);
X 	if (!inode)
X 		return -ENOSPC;
@@ -251,8 +249,6 @@
X 	struct buffer_head * bh;
X 	struct minix_dir_entry * de;
X 
-	if (!dir)
-		return -ENOENT;
X 	bh = minix_find_entry(dir, dentry->d_name.name,
X 			      dentry->d_name.len, &de);
X 	if (bh) {
@@ -298,8 +294,6 @@
X 	struct minix_dir_entry * de;
X 	struct minix_sb_info * info;
X 
-	if (!dir || !dir->i_sb)
-		return -EINVAL;
X 	info = &dir->i_sb->u.minix_sb;
X 	bh = minix_find_entry(dir, dentry->d_name.name,
X 			      dentry->d_name.len, &de);
diff -u --recursive --new-file v2.2.6/linux/fs/msdos/namei.c linux/fs/msdos/namei.c
--- v2.2.6/linux/fs/msdos/namei.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/msdos/namei.c	Fri Apr 23 21:20:38 1999
@@ -250,7 +250,7 @@
X 
X 
X /***** Get inode using directory and name */
-int msdos_lookup(struct inode *dir,struct dentry *dentry)
+struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry)
X {
X 	struct super_block *sb = dir->i_sb;
X 	struct inode *inode = NULL;
@@ -292,7 +292,7 @@
X 	d_add(dentry, inode);
X 	res = 0;
X out:
-	return res;
+	return ERR_PTR(res);
X }
X 
X 
@@ -713,7 +713,7 @@
X 	fat_cache_inval_inode(old_inode);
X 	old_inode->i_version = ++event;
X 	MSDOS_I(old_inode)->i_binary =
-		is_binary(MSDOS_SB(sb)->options.conversion, free_de->ext);
+		fat_is_binary(MSDOS_SB(sb)->options.conversion, free_de->ext);
X 	old_inode->i_ino = free_ino;
X 	fat_mark_buffer_dirty(sb, free_bh, 1);
X 	old_de->name[0] = DELETED_FLAG;
diff -u --recursive --new-file v2.2.6/linux/fs/namei.c linux/fs/namei.c
--- v2.2.6/linux/fs/namei.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/namei.c	Fri Apr 23 21:20:38 1999
@@ -263,12 +263,11 @@
X 		struct dentry * dentry = d_alloc(parent, name);
X 		result = ERR_PTR(-ENOMEM);
X 		if (dentry) {
-			int error = dir->i_op->lookup(dir, dentry);
-			result = dentry;
-			if (error) {
+			result = dir->i_op->lookup(dir, dentry);
+			if (result)
X 				dput(dentry);
-				result = ERR_PTR(error);
-			}
+			else
+				result = dentry;
X 		}
X 	}
X 	up(&dir->i_sem);
diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/Config.in linux/fs/ncpfs/Config.in
--- v2.2.6/linux/fs/ncpfs/Config.in	Sun Jul 26 11:57:18 1998
+++ linux/fs/ncpfs/Config.in	Tue Apr 20 15:17:20 1999
@@ -6,5 +6,10 @@
X bool     '   Clear remove/delete inhibit when needed' CONFIG_NCPFS_STRONG
X bool     '   Use NFS namespace if available' CONFIG_NCPFS_NFS_NS
X bool     '   Use LONG (OS/2) namespace if available' CONFIG_NCPFS_OS2_NS
+if [ "$CONFIG_NCPFS_OS2_NS" = "y" ]; then
+  bool   '      Lowercase DOS filenames' CONFIG_NCPFS_SMALLDOS
+fi
X bool     '   Allow mounting of volume subdirectories' CONFIG_NCPFS_MOUNT_SUBDIR
X # bool     '   NDS interserver authentication support' CONFIG_NCPFS_NDS_DOMAINS
+bool     '   Use Native Language Support' CONFIG_NCPFS_NLS
+bool     '   Enable symbolic links and execute flags' CONFIG_NCPFS_EXTRAS
diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/Makefile linux/fs/ncpfs/Makefile
--- v2.2.6/linux/fs/ncpfs/Makefile	Thu Jul 16 18:09:28 1998
+++ linux/fs/ncpfs/Makefile	Tue Apr 20 15:17:20 1999
@@ -9,7 +9,7 @@
X 
X O_TARGET := ncpfs.o
X O_OBJS   := dir.o file.o inode.o ioctl.o mmap.o ncplib_kernel.o sock.o \
-		ncpsign_kernel.o
+		symlink.o ncpsign_kernel.o
X M_OBJS   := $(O_TARGET)
X 
X # If you want debugging output, please uncomment the following line
diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c
--- v2.2.6/linux/fs/ncpfs/dir.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/ncpfs/dir.c	Mon Apr 26 09:26:55 1999
@@ -4,6 +4,7 @@
X  *  Copyright (C) 1995, 1996 by Volker Lendecke
X  *  Modified for big endian by J.F. Chadima and David S. Miller
X  *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
+ *  Modified 1998 Wolfram Pienkoss for NLS
X  *
X  */
X 
@@ -22,6 +23,7 @@
X #include <linux/locks.h>
X 
X #include <linux/ncp_fs.h>
+
X #include "ncplib_kernel.h"
X 
X struct ncp_dirent {
@@ -48,13 +50,16 @@
X static int ncp_readdir(struct file *, void *, filldir_t);
X 
X static int ncp_create(struct inode *, struct dentry *, int);
-static int ncp_lookup(struct inode *, struct dentry *);
+static struct dentry *ncp_lookup(struct inode *, struct dentry *);
X static int ncp_unlink(struct inode *, struct dentry *);
X static int ncp_mkdir(struct inode *, struct dentry *, int);
X static int ncp_rmdir(struct inode *, struct dentry *);
X static int ncp_rename(struct inode *, struct dentry *,
X 	  	      struct inode *, struct dentry *);
-
+#ifdef CONFIG_NCPFS_EXTRAS
+extern int ncp_symlink(struct inode *, struct dentry *, const char *);
+#endif
+		      
X static struct file_operations ncp_dir_operations =
X {
X 	NULL,			/* lseek - default */
@@ -77,7 +82,11 @@
X 	ncp_lookup,		/* lookup */
X 	NULL,			/* link */
X 	ncp_unlink,		/* unlink */
+#ifdef CONFIG_NCPFS_EXTRAS
+	ncp_symlink,		/* symlink */
+#else
X 	NULL,			/* symlink */
+#endif
X 	ncp_mkdir,		/* mkdir */
X 	ncp_rmdir,		/* rmdir */
X 	NULL,			/* mknod */
@@ -191,14 +200,6 @@
X 	}
X }
X 
-/* Here we encapsulate the inode number handling that depends upon the
- * mount mode: When we mount a complete server, the memory address of
- * the ncp_inode_info is used as the inode number. When only a single
- * volume is mounted, then the dirEntNum is used as the inode
- * number. As this is unique for the complete volume, this should
- * enable the NFS exportability of a ncpfs-mounted volume.
- */
-
X /*
X  * Generate a unique inode number.
X  */
@@ -253,37 +254,30 @@
X ncp_force_unlink(struct inode *dir, struct dentry* dentry)
X {
X         int res=0x9c,res2;
-        struct iattr ia;
+	struct nw_modify_dos_info info;
+	__u32 old_nwattr;
+	struct inode *inode;
X 
+	memset(&info, 0, sizeof(info));
+	
X         /* remove the Read-Only flag on the NW server */
+	inode = dentry->d_inode;
X 
-        memset(&ia,0,sizeof(struct iattr));
-        ia.ia_mode = dentry->d_inode->i_mode;
-        ia.ia_mode |= NCP_SERVER(dir)->m.file_mode & 0222;  /* set write bits */
-        ia.ia_valid = ATTR_MODE;
-
-        res2=ncp_notify_change(dentry, &ia);
-        if (res2)
-        {
-                goto leave_me;
-        }
+	old_nwattr = NCP_FINFO(inode)->nwattr;
+	info.attributes = old_nwattr & ~(aRONLY|aDELETEINHIBIT|aRENAMEINHIBIT);
+	res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(inode), inode, NULL, DM_ATTRIBUTES, &info);
+	if (res2)
+		goto leave_me;
X 
X         /* now try again the delete operation */
-
X         res = ncp_del_file_or_subdir2(NCP_SERVER(dir), dentry);
X 
X         if (res)  /* delete failed, set R bit again */
X         {
-                memset(&ia,0,sizeof(struct iattr));
-                ia.ia_mode = dentry->d_inode->i_mode;
-                ia.ia_mode &= ~(NCP_SERVER(dir)->m.file_mode & 0222);  /* clear write bits */
-                ia.ia_valid = ATTR_MODE;
-
-                res2=ncp_notify_change(dentry, &ia);
-                if (res2)
-                {
+		info.attributes = old_nwattr;
+		res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(inode), inode, NULL, DM_ATTRIBUTES, &info);
+		if (res2)
X                         goto leave_me;
-                }
X         }
X leave_me:
X         return(res);
@@ -293,63 +287,58 @@
X #ifdef CONFIG_NCPFS_STRONG
X static int
X ncp_force_rename(struct inode *old_dir, struct dentry* old_dentry, char *_old_name,
-                 struct inode *new_dir, struct dentry* new_dentry, char *_new_name,
-                 int *done_flag)
+                 struct inode *new_dir, struct dentry* new_dentry, char *_new_name)
X {
+	struct nw_modify_dos_info info;
X         int res=0x90,res2;
-        struct iattr ia;
+	struct inode *old_inode = old_dentry->d_inode;
+	__u32 old_nwattr = NCP_FINFO(old_inode)->nwattr;
+	__u32 new_nwattr = 0; /* shut compiler warning */
+	int old_nwattr_changed = 0;
+	int new_nwattr_changed = 0;
X 
+	memset(&info, 0, sizeof(info));
+	
X         /* remove the Read-Only flag on the NW server */
X 
-        memset(&ia,0,sizeof(struct iattr));
-        ia.ia_mode = old_dentry->d_inode->i_mode;
-	if (S_ISDIR(ia.ia_mode))
-		goto leave_me;
-        ia.ia_mode |= NCP_SERVER(old_dir)->m.file_mode & 0222;  /* set write bits */
-        ia.ia_valid = ATTR_MODE;
-
-        res2=ncp_notify_change(old_dentry, &ia);
-        if (res2)
-        {
-                goto leave_me;
-        }
-
+	info.attributes = old_nwattr & ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
+	res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(old_inode), old_inode, NULL, DM_ATTRIBUTES, &info);
+	if (!res2)
+		old_nwattr_changed = 1;
+	if (new_dentry && new_dentry->d_inode) {
+		new_nwattr = NCP_FINFO(new_dentry->d_inode)->nwattr;
+		info.attributes = new_nwattr & ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
+		res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir), new_dir, _new_name, DM_ATTRIBUTES, &info);
+		if (!res2)
+			new_nwattr_changed = 1;
+	}
X         /* now try again the rename operation */
-        res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir),
-                                            old_dir, _old_name,
-                                            new_dir, _new_name);
-
-        if (!res) {
-                ncp_invalid_dir_cache(old_dir);
-                ncp_invalid_dir_cache(new_dir);
-                d_move(old_dentry,new_dentry);
-                *done_flag=1;
-
-                if (!old_dentry->d_inode) {
-                        DPRINTK(KERN_INFO "ncpfs: no inode -- file remains rw\n");
-                        goto leave_me;
-                }
-                if ((res2=ncp_lookup_validate(old_dentry))) {
-                        DPRINTK(KERN_DEBUG "ncpfs: ncp_lookup_validate returned %d\n",res2);
-                }
-        }
-
-        memset(&ia,0,sizeof(struct iattr));
-        ia.ia_mode = old_dentry->d_inode->i_mode;
-        ia.ia_mode &= ~(NCP_SERVER(old_dentry->d_inode)->m.file_mode & 0222);  /* clear write bits */
-        ia.ia_valid = ATTR_MODE;
-
-        DPRINTK(KERN_INFO "calling ncp_notify_change() with %s/%s\n",
-               old_dentry->d_parent->d_name.name,old_dentry->d_name.name);
-
-        res2=ncp_notify_change(old_dentry, &ia);
-        if (res2)
-        {
-                printk(KERN_INFO "ncpfs: ncp_notify_change (2) failed: %08x\n",res2);
-                /* goto leave_me; */
-        }
-
- leave_me:
+	/* but only if something really happened */
+	if (new_nwattr_changed || old_nwattr_changed) {
+	        res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir),
+        	                                    old_dir, _old_name,
+                	                            new_dir, _new_name);
+	} 
+	if (res)
+		goto leave_me;
+	/* file was successfully renamed, so:
+	   do not set attributes on old file - it no longer exists
+	   copy attributes from old file to new */
+	new_nwattr_changed = old_nwattr_changed;
+	new_nwattr = old_nwattr;
+	old_nwattr_changed = 0;
+	
+leave_me:;
+	if (old_nwattr_changed) {
+		info.attributes = old_nwattr;
+		res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(old_inode), old_inode, NULL, DM_ATTRIBUTES, &info);
+		/* ignore errors */
+	}
+	if (new_nwattr_changed)	{
+		info.attributes = new_nwattr;
+		res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir), new_dir, _new_name, DM_ATTRIBUTES, &info);
+		/* ignore errors */
+	}
X         return(res);
X }
X #endif	/* CONFIG_NCPFS_STRONG */
@@ -386,11 +375,6 @@
X printk(KERN_DEBUG "ncp_lookup_validate: %s, len %d\n", __name, len);
X #endif
X 
-	if (!ncp_preserve_case(dir)) { 
-	  str_lower(__name);
-          down_case = 1;
-	}
-	
X 	/* If the file is in the dir cache, we do not have to ask the
X 	   server. */
X 
@@ -400,17 +384,14 @@
X #endif
X 		if (ncp_is_server_root(dir))
X 		{
-			str_upper(__name);
+			io2vol(server, __name, 1);
X 			down_case = 1;
X 			res = ncp_lookup_volume(server, __name,
X 						&(finfo.nw_info.i));
X 		} else
X 	    	{
-			if (!ncp_preserve_case(dir))
-			{
-				str_upper(__name);
-				down_case = 1;
-			}
+			down_case = !ncp_preserve_case(dir);
+			io2vol(server, __name, down_case);
X 			res = ncp_obtain_info(server, dir, __name,
X 						&(finfo.nw_info.i));
X 		}
@@ -429,6 +410,9 @@
X 		  else
X 		    printk(KERN_DEBUG "ncp_lookup_validate: found, but dirEntNum changed\n");
X #endif
+		  vol2io(server, finfo.nw_info.i.entryName,
+			 !ncp_preserve_entry_case(dir,
+			 finfo.nw_info.i.NSCreator));
X  		  ncp_update_inode2(dentry->d_inode, &finfo.nw_info);
X 		}
X 		if (!val) ncp_invalid_dir_cache(dir);
@@ -456,11 +440,6 @@
X 	DDPRINTK(KERN_DEBUG "ncp_readdir: inode->i_ino = %ld, c_ino = %ld\n",
X 		 inode->i_ino, c_ino);
X 
-	result = -EBADF;
-	if (!inode || !S_ISDIR(inode->i_mode)) {
-		printk(KERN_WARNING "ncp_readdir: inode is NULL or not a directory\n");
-		goto out;
-	}
X 	result = -EIO;
X 	if (!ncp_conn_valid(server))
X 		goto out;
@@ -535,10 +514,11 @@
X 			c_last_returned_index = 0;
X 			index = 0;
X 
-			if (!ncp_preserve_case(inode)) {
-				for (i = 0; i < c_size; i++) {
-					str_lower(c_entry[i].i.entryName);
-				}
+			for (i = 0; i < c_size; i++)
+			{
+				vol2io(server, c_entry[i].i.entryName,
+					!ncp_preserve_entry_case(inode,
+					c_entry[i].i.NSCreator));
X 			}
X 		}
X 	}
@@ -730,7 +710,7 @@
X 		struct dentry* dent;
X 
X 		result = -ENOENT;
-		str_upper(server->m.mounted_vol);
+		io2vol(server, server->m.mounted_vol, 1);
X 		if (ncp_lookup_volume(server, server->m.mounted_vol,
X 				      &(server->root.finfo.i)) != 0) {
X #ifdef NCPFS_PARANOIA
@@ -738,7 +718,7 @@
X #endif
X 			goto out;
X 		}
-		str_lower(server->root.finfo.i.entryName);
+		vol2io(server, server->root.finfo.i.entryName, 1);
X 		dent = server->root_dentry;
X 		if (dent) {
X 			struct inode* ino = dent->d_inode;
@@ -759,7 +739,7 @@
X 	return result;
X }
X 
-static int ncp_lookup(struct inode *dir, struct dentry *dentry)
+static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry)
X {
X 	struct ncp_server *server;
X 	struct inode *inode = NULL;
@@ -769,11 +749,6 @@
X 	struct ncpfs_inode_info finfo;
X 	__u8 __name[dentry->d_name.len + 1];
X 
-	error =  -ENOENT;
-	if (!dir || !S_ISDIR(dir->i_mode)) {
-		printk(KERN_WARNING "ncp_lookup: inode is NULL or not a directory.\n");
-		goto finished;
-	}
X 	server = NCP_SERVER(dir);
X 
X 	error = -EIO;
@@ -786,11 +761,6 @@
X printk(KERN_DEBUG "ncp_lookup: %s, len %d\n", __name, len);
X #endif
X 
-	if (!ncp_preserve_case(dir)) { 
-	  str_lower(__name);
-          down_case = 1;
-	}
-	
X 	/* If the file is in the dir cache, we do not have to ask the
X 	   server. */
X 
@@ -830,17 +800,14 @@
X #endif
X 		if (ncp_is_server_root(dir))
X 		{
-			str_upper(__name);
+			io2vol(server, __name, 1);
X 			down_case = 1;
X 			res = ncp_lookup_volume(server, __name,
X 						&(finfo.nw_info.i));
X 		} else
X 	    	{
-			if (!ncp_preserve_case(dir))
-			{
-				str_upper(__name);
-				down_case = 1;
-			}
+			down_case = !ncp_preserve_case(dir);
+			io2vol(server, __name, down_case);
X 			res = ncp_obtain_info(server, dir, __name,
X 						&(finfo.nw_info.i));
X 		}
@@ -851,8 +818,11 @@
X 		/*
X 		 * If we didn't find an entry, make a negative dentry.
X 		 */
-	   	if (res != 0)
+	   	if (res != 0) {
X 			goto add_entry;
+		} else vol2io(server, finfo.nw_info.i.entryName,
+			      !ncp_preserve_entry_case(dir,
+			      finfo.nw_info.i.NSCreator));
X 	}
X 
X 	/*
@@ -874,7 +844,7 @@
X #ifdef NCPFS_PARANOIA
X printk(KERN_DEBUG "ncp_lookup: result=%d\n", error);
X #endif
-	return error;
+	return ERR_PTR(error);
X }
X 
X /*
@@ -906,20 +876,17 @@
X 	goto out;
X }
X 
-static int ncp_create(struct inode *dir, struct dentry *dentry, int mode)
+int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode,
+		int attributes)
X {
X 	int error, result;
X 	struct ncpfs_inode_info finfo;
X 	__u8 _name[dentry->d_name.len + 1];
-
+	
X #ifdef NCPFS_PARANOIA
-printk(KERN_DEBUG "ncp_create: creating %s/%s, mode=%x\n",
+printk(KERN_DEBUG "ncp_create_new: creating %s/%s, mode=%x\n",
X dentry->d_parent->d_name.name, dentry->d_name.name, mode);
X #endif
-	if (!dir || !S_ISDIR(dir->i_mode)) {
-		printk(KERN_WARNING "ncp_create: inode is NULL or not a directory\n");
-		return -ENOENT;
-	}
X 	error = -EIO;
X 	if (!ncp_conn_valid(NCP_SERVER(dir)))
X 		goto out;
@@ -927,14 +894,12 @@
X 	strncpy(_name, dentry->d_name.name, dentry->d_name.len);
X 	_name[dentry->d_name.len] = '\0';
X 
-	if (!ncp_preserve_case(dir)) {
-		str_upper(_name);
-	}
+	io2vol(NCP_SERVER(dir), _name, !ncp_preserve_case(dir));
X 
X 	error = -EACCES;
X 	result = ncp_open_create_file_or_subdir(NCP_SERVER(dir), dir, _name,
X 			   OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE,
-			   0, AR_READ | AR_WRITE, &finfo.nw_info);
+			   attributes, AR_READ | AR_WRITE, &finfo.nw_info);
X 	if (!result) {
X 		finfo.nw_info.access = O_RDWR;
X 		error = ncp_instantiate(dir, dentry, &finfo);
@@ -948,6 +913,11 @@
X 	return error;
X }
X 
+static int ncp_create(struct inode *dir, struct dentry *dentry, int mode)
+{
+	return ncp_create_new(dir, dentry, mode, 0);
+}
+
X static int ncp_mkdir(struct inode *dir, struct dentry *dentry, int mode)
X {
X 	int error;
@@ -956,20 +926,13 @@
X 
X 	DPRINTK(KERN_DEBUG "ncp_mkdir: making %s/%s\n",
X 		dentry->d_parent->d_name.name, dentry->d_name.name);
-	error = -ENOTDIR;
-	if (!dir || !S_ISDIR(dir->i_mode)) {
-		printk(KERN_WARNING "ncp_mkdir: inode is NULL or not a directory\n");
-		goto out;
-	}
X 	error = -EIO;
X 	if (!ncp_conn_valid(NCP_SERVER(dir)))
X 		goto out;
X 
X 	strncpy(_name, dentry->d_name.name, dentry->d_name.len);
X 	_name[dentry->d_name.len] = '\0';
-	if (!ncp_preserve_case(dir)) {
-		str_upper(_name);
-	}
+	io2vol(NCP_SERVER(dir), _name, !ncp_preserve_case(dir));
X 
X 	error = -EACCES;
X 	if (ncp_open_create_file_or_subdir(NCP_SERVER(dir), dir, _name,
@@ -989,13 +952,6 @@
X 
X 	DPRINTK(KERN_DEBUG "ncp_rmdir: removing %s/%s\n",
X 		dentry->d_parent->d_name.name, dentry->d_name.name);
-	
-	error = -ENOENT;
-	if (!dir || !S_ISDIR(dir->i_mode))
-	{
-		printk(KERN_WARNING "ncp_rmdir: inode is NULL or not a directory\n");
-		goto out;
-	}
X 
X 	error = -EIO;
X 	if (!ncp_conn_valid(NCP_SERVER(dir)))
@@ -1008,17 +964,34 @@
X 	strncpy(_name, dentry->d_name.name, dentry->d_name.len);
X 	_name[dentry->d_name.len] = '\0';
X 	    
-	if (!ncp_preserve_case(dir))
-	{
-		str_upper(_name);
-	}
-	error = -EACCES;
+	io2vol(NCP_SERVER(dir), _name, !ncp_preserve_case(dir));
X 	result = ncp_del_file_or_subdir(NCP_SERVER(dir), dir, _name);
-	if (!result)
-	{
-		ncp_invalid_dir_cache(dir);
-		error = 0;
-    	}
+	switch (result) {
+		case 0x00:
+   			ncp_invalid_dir_cache(dir);
+			error = 0;
+			break;
+		case 0x85:	/* unauthorized to delete file */
+		case 0x8A:	/* unauthorized to delete file */
+			error = -EACCES;
+			break;
+		case 0x8F:
+		case 0x90:	/* read only */
+			error = -EPERM;
+			break;
+		case 0x9F:	/* in use by another client */
+			error = -EBUSY;
+			break;
+		case 0xA0:	/* directory not empty */
+			error = -ENOTEMPTY;
+			break;
+		case 0xFF:	/* someone deleted file */
+			error = -ENOENT;
+			break;
+		default:
+			error = -EACCES;
+			break;
+       	}
X out:
X 	return error;
X }
@@ -1031,11 +1004,6 @@
X 	DPRINTK(KERN_DEBUG "ncp_unlink: unlinking %s/%s\n",
X 		dentry->d_parent->d_name.name, dentry->d_name.name);
X 	
-	error = -ENOTDIR;
-	if (!dir || !S_ISDIR(dir->i_mode)) {
-		printk(KERN_WARNING "ncp_unlink: inode is NULL or not a directory\n");
-		goto out;
-	}
X 	error = -EIO;
X 	if (!ncp_conn_valid(NCP_SERVER(dir)))
X 		goto out;
@@ -1052,19 +1020,38 @@
X 
X 	error = ncp_del_file_or_subdir2(NCP_SERVER(dir), dentry);
X #ifdef CONFIG_NCPFS_STRONG
+	/* 9C is Invalid path.. It should be 8F, 90 - read only, but
+	   it is not :-( */
X 	if (error == 0x9C && NCP_SERVER(dir)->m.flags & NCP_MOUNT_STRONG) { /* R/O */
X 		error = ncp_force_unlink(dir, dentry);
X 	}
X #endif
-	if (!error) {
-		DPRINTK(KERN_DEBUG "ncp: removed %s/%s\n",
-			dentry->d_parent->d_name.name, dentry->d_name.name);
-		ncp_invalid_dir_cache(dir);
-		d_delete(dentry);
-	} else if (error == 0xFF) {
-		error = -ENOENT;
-	} else {
-		error = -EACCES;
+	switch (error) {
+		case 0x00:
+			DPRINTK(KERN_DEBUG "ncp: removed %s/%s\n",
+				dentry->d_parent->d_name.name, dentry->d_name.name);
+			ncp_invalid_dir_cache(dir);
+			d_delete(dentry);
+			break;
+		case 0x85:
+		case 0x8A:
+			error = -EACCES;
+			break;
+		case 0x8D:	/* some files in use */
+		case 0x8E:	/* all files in use */
+			error = -EBUSY;
+			break;
+		case 0x8F:	/* some read only */
+		case 0x90:	/* all read only */
+		case 0x9C:	/* !!! returned when in-use or read-only by NW4 */
+			error = -EPERM;
+			break;
+		case 0xFF:
+			error = -ENOENT;
+			break;
+		default:
+			error = -EACCES;
+			break;
X 	}
X 		
X out:
@@ -1076,7 +1063,7 @@
X {
X 	int old_len = old_dentry->d_name.len;
X 	int new_len = new_dentry->d_name.len;
-	int error, done_flag=0;
+	int error;
X 	char _old_name[old_dentry->d_name.len + 1];
X 	char _new_name[new_dentry->d_name.len + 1];
X 
@@ -1084,59 +1071,44 @@
X 		old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
X 		new_dentry->d_parent->d_name.name, new_dentry->d_name.name);
X 
-	error = -ENOTDIR;
-	if (!old_dir || !S_ISDIR(old_dir->i_mode)) {
-		printk(KERN_WARNING "ncp_rename: old inode is NULL or not a directory\n");
-		goto out;
-	}
-	if (!new_dir || !S_ISDIR(new_dir->i_mode)) {
-		printk(KERN_WARNING "ncp_rename: new inode is NULL or not a directory\n");
-		goto out;
-	}
X 	error = -EIO;
X 	if (!ncp_conn_valid(NCP_SERVER(old_dir)))
X 		goto out;
X 
X 	strncpy(_old_name, old_dentry->d_name.name, old_len);
X 	_old_name[old_len] = '\0';
-	if (!ncp_preserve_case(old_dir)) {
-		str_upper(_old_name);
-	}
+	io2vol(NCP_SERVER(old_dir), _old_name, !ncp_preserve_case(old_dir));
X 
X 	strncpy(_new_name, new_dentry->d_name.name, new_len);
X 	_new_name[new_len] = '\0';
-	if (!ncp_preserve_case(new_dir)) {
-		str_upper(_new_name);
-	}
+	io2vol(NCP_SERVER(new_dir), _new_name, !ncp_preserve_case(new_dir));
X 
X 	error = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir),
X 					    old_dir, _old_name,
X 					    new_dir, _new_name);
X #ifdef CONFIG_NCPFS_STRONG
-	if (error == 0x90 && NCP_SERVER(old_dir)->m.flags & NCP_MOUNT_STRONG) {	/* RO */
+	if ((error == 0x90 || error == -EACCES) && NCP_SERVER(old_dir)->m.flags & NCP_MOUNT_STRONG) {	/* RO */
X 		error = ncp_force_rename(old_dir, old_dentry, _old_name,
-                                         new_dir, new_dentry, _new_name,
-                                         &done_flag);
+                                         new_dir, new_dentry, _new_name);
X 	}
X #endif
-	if (error == 0)
-	{
-                if (done_flag == 0)  /* if 1, the following already happened */
-                {                    /* in ncp_force_rename() */
-                        DPRINTK(KERN_DEBUG "ncp renamed %s -> %s.\n",
+	switch (error) {
+		case 0x00:
+               	        DPRINTK(KERN_DEBUG "ncp renamed %s -> %s.\n",
X                                 old_dentry->d_name.name,new_dentry->d_name.name);
-                        ncp_invalid_dir_cache(old_dir);
-                        ncp_invalid_dir_cache(new_dir);
-			if (!S_ISDIR(old_dentry->d_inode->i_mode))
-				d_move(old_dentry,new_dentry);
-                }
-	} else {
-		if (error == 0x9E)
+       	                ncp_invalid_dir_cache(old_dir);
+               	        ncp_invalid_dir_cache(new_dir);
+			/* d_move(old_dentry, new_dentry); */
+			break;
+		case 0x9E:
X 			error = -ENAMETOOLONG;
-		else if (error == 0xFF)
+			break;
+		case 0xFF:
X 			error = -ENOENT;
-		else
+			break;
+		default:
X 			error = -EACCES;
+			break;
X 	}
X out:
X 	return error;
@@ -1155,14 +1127,12 @@
X 
X static int utc2local(int time)
X {
-	return time - sys_tz.tz_minuteswest * 60 +
-	    (sys_tz.tz_dsttime ? 3600 : 0);
+	return time - sys_tz.tz_minuteswest * 60;
X }
X 
X static int local2utc(int time)
X {
-	return time + sys_tz.tz_minuteswest * 60 -
-	    (sys_tz.tz_dsttime ? 3600 : 0);
+	return time + sys_tz.tz_minuteswest * 60;
X }
X 
X /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
@@ -1171,7 +1141,9 @@
X {
X 	int month, year, secs;
X 
-	month = ((date >> 5) & 15) - 1;
+	/* first subtract and mask after that... Otherwise, if
+	   date == 0, bad things happen */
+	month = ((date >> 5) - 1) & 15;
X 	year = date >> 9;
X 	secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 +
X 		86400 * ((date & 31) - 1 + day_n[month] + (year / 4) + 
diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c
--- v2.2.6/linux/fs/ncpfs/inode.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/ncpfs/inode.c	Tue Apr 20 15:17:20 1999
@@ -4,6 +4,7 @@
X  *  Copyright (C) 1995, 1996 by Volker Lendecke
X  *  Modified for big endian by J.F. Chadima and David S. Miller
X  *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
+ *  Modified 1998 Wolfram Pienkoss for NLS
X  *
X  */
X 
@@ -27,6 +28,7 @@
X #include <linux/init.h>
X 
X #include <linux/ncp_fs.h>
+
X #include "ncplib_kernel.h"
X 
X static void ncp_read_inode(struct inode *);
@@ -49,6 +51,10 @@
X };
X 
X extern struct dentry_operations ncp_dentry_operations;
+#ifdef CONFIG_NCPFS_EXTRAS
+extern struct inode_operations ncp_symlink_inode_operations;
+extern int ncp_symlink(struct inode*, struct dentry*, const char*);
+#endif
X 
X static struct nw_file_info *read_nwinfo = NULL;
X static struct semaphore read_sem = MUTEX;
@@ -62,6 +68,12 @@
X 	NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
X 	NCP_FINFO(inode)->volNumber = nwinfo->i.volNumber;
X 
+#ifdef CONFIG_NCPFS_SMALLDOS
+	NCP_FINFO(inode)->origNS = nwinfo->i.NSCreator;
+#endif
+#ifdef CONFIG_NCPFS_STRONG
+	NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
+#endif
X 	NCP_FINFO(inode)->opened = nwinfo->opened;
X 	NCP_FINFO(inode)->access = nwinfo->access;
X 	NCP_FINFO(inode)->server_file_handle = nwinfo->server_file_handle;
@@ -79,12 +91,42 @@
X 	struct ncp_server *server = NCP_SERVER(inode);
X 
X 	if (!NCP_FINFO(inode)->opened) {
+#ifdef CONFIG_NCPFS_STRONG
+		NCP_FINFO(inode)->nwattr = nwi->attributes;
+#endif
X 		if (nwi->attributes & aDIR) {
X 			inode->i_mode = server->m.dir_mode;
X 			inode->i_size = 512;
X 		} else {
X 			inode->i_mode = server->m.file_mode;
X 			inode->i_size = le32_to_cpu(nwi->dataStreamSize);
+#ifdef CONFIG_NCPFS_EXTRAS
+			if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS)) && (nwi->attributes & aSHARED)) {
+				switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
+					case aHIDDEN:
+						if (server->m.flags & NCP_MOUNT_SYMLINKS) {
+							if ((inode->i_size >= NCP_MIN_SYMLINK_SIZE)
+							 && (inode->i_size <= NCP_MAX_SYMLINK_SIZE)) {
+								inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
+								break;
+							}
+						}
+						/* FALLTHROUGH */
+					case 0:
+						if (server->m.flags & NCP_MOUNT_EXTRAS)
+							inode->i_mode |= 0444;
+						break;
+					case aSYSTEM:
+						if (server->m.flags & NCP_MOUNT_EXTRAS)
+							inode->i_mode |= (inode->i_mode >> 2) & 0111;
+						break;
+					/* case aSYSTEM|aHIDDEN: */
+					default:
+						/* reserved combination */
+						break;
+				}
+			}
+#endif
X 		}
X 		if (nwi->attributes & aRONLY) inode->i_mode &= ~0222;
X 	}
@@ -114,6 +156,34 @@
X 	} else {
X 		inode->i_mode = server->m.file_mode;
X 		inode->i_size = le32_to_cpu(nwi->dataStreamSize);
+#ifdef CONFIG_NCPFS_EXTRAS
+		if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS)) 
+		 && (nwi->attributes & aSHARED)) {
+			switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
+				case aHIDDEN:
+					if (server->m.flags & NCP_MOUNT_SYMLINKS) {
+						if ((inode->i_size >= NCP_MIN_SYMLINK_SIZE)
+						 && (inode->i_size <= NCP_MAX_SYMLINK_SIZE)) {
+							inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
+							break;
+						}
+					}
+					/* FALLTHROUGH */
+				case 0:
+					if (server->m.flags & NCP_MOUNT_EXTRAS)
+						inode->i_mode |= 0444;
+					break;
+				case aSYSTEM:
+					if (server->m.flags & NCP_MOUNT_EXTRAS)
+						inode->i_mode |= (inode->i_mode >> 2) & 0111;
+					break;
+				/* case aSYSTEM|aHIDDEN: */
+				default:
+					/* reserved combination */
+					break;
+			}
+		}
+#endif
X 	}
X 	if (nwi->attributes & aRONLY) inode->i_mode &= ~0222;
X 
@@ -157,6 +227,10 @@
X 		inode->i_op = &ncp_file_inode_operations;
X 	} else if (S_ISDIR(inode->i_mode)) {
X 		inode->i_op = &ncp_dir_inode_operations;
+#ifdef CONFIG_NCPFS_EXTRAS
+	} else if (S_ISLNK(inode->i_mode)) {
+		inode->i_op = &ncp_symlink_inode_operations;
+#endif
X 	} else {
X 		inode->i_op = NULL;
X 	}
@@ -211,7 +285,6 @@
X {
X 	struct ncp_inode_info *root = &(server->root);
X 	struct nw_info_struct *i = &(root->finfo.i);
-	unsigned short dummy;
X 
X 	DPRINTK(KERN_DEBUG "ncp_init_root: i = %x\n", (int) i);
X 
@@ -219,15 +292,13 @@
X 	i->dataStreamSize= 1024;
X 	i->dirEntNum	 = 0;
X 	i->DosDirNum	 = 0;
+#ifdef CONFIG_NCPFS_SMALLDOS
+	i->NSCreator	 = NW_NS_DOS;
+#endif
X 	i->volNumber	 = NCP_NUMBER_OF_VOLUMES + 1;	/* illegal volnum */
-	ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate));
-	ncp_date_unix2dos(0, &(i->modifyTime  ), &(i->modifyDate));
-	ncp_date_unix2dos(0, &(dummy          ), &(i->lastAccessDate));
-	i->creationTime	 = le16_to_cpu(i->creationTime);
-	i->creationDate	 = le16_to_cpu(i->creationDate);
-	i->modifyTime	 = le16_to_cpu(i->modifyTime);
-	i->modifyDate	 = le16_to_cpu(i->modifyDate);
-	i->lastAccessDate= le16_to_cpu(i->lastAccessDate);
+	/* set dates of mountpoint to Jan 1, 1986; 00:00 */
+	i->creationTime = i->modifyTime = cpu_to_le16(0x0000);
+	i->creationDate = i->modifyDate = i->lastAccessDate = cpu_to_le16(0x0C21);
X 	i->nameLen	 = 0;
X 	i->entryName[0]  = '\0';
X 
@@ -264,8 +335,6 @@
X 
X 	lock_super(sb);
X 
-	sb->s_flags |= MS_ODD_RENAME; /* This should go away */
-
X 	sb->s_blocksize = 1024;	/* Eh...  Is this correct? */
X 	sb->s_blocksize_bits = 10;
X 	sb->s_magic = NCP_SUPER_MAGIC;
@@ -310,6 +379,14 @@
X 	server->m.dir_mode = (server->m.dir_mode &
X 			      (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFDIR;
X 
+#ifdef CONFIG_NCPFS_NLS
+	/* load the default NLS charsets */
+	server->nls_charsets.codepage[0] = 0;
+	server->nls_charsets.iocharset[0] = 0;
+	server->nls_vol = load_nls_default();
+	server->nls_io = load_nls_default();
+#endif /* CONFIG_NCPFS_NLS */
+
X 	server->packet_size = NCP_PACKET_SIZE;
X 	server->packet = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL);
X 	if (server->packet == NULL)
@@ -379,6 +456,10 @@
X out_no_packet:
X 	printk(KERN_ERR "ncp_read_super: could not alloc packet\n");
X out_free_server:
+#ifdef CONFIG_NCPFS_NLS
+	unload_nls(server->nls_io);
+	unload_nls(server->nls_vol);
+#endif
X 	ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
X 	goto out_unlock;
X out_no_server:
@@ -418,6 +499,20 @@
X 	ncp_disconnect(server);
X 	ncp_unlock_server(server);
X 
+#ifdef CONFIG_NCPFS_NLS
+	/* unload the NLS charsets */
+	if (server->nls_vol)
+	{
+		unload_nls(server->nls_vol);
+		server->nls_vol = NULL;
+	}
+	if (server->nls_io)
+	{
+		unload_nls(server->nls_io);
+		server->nls_io = NULL;
+	}
+#endif /* CONFIG_NCPFS_NLS */
+
X 	fput(server->ncp_filp);
X 	kill_proc(server->m.wdog_pid, SIGTERM, 1);
X 
@@ -459,9 +554,12 @@
X 	int result = 0;
X 	int info_mask;
X 	struct nw_modify_dos_info info;
+	struct ncp_server *server;
X 
X 	result = -EIO;
-	if (!ncp_conn_valid(NCP_SERVER(inode)))
+
+	server = NCP_SERVER(inode);
+	if ((!server) || !ncp_conn_valid(server))
X 		goto out;
X 
X 	result = inode_change_ok(inode, attr);
@@ -470,11 +568,11 @@
X 
X 	result = -EPERM;
X 	if (((attr->ia_valid & ATTR_UID) &&
-	     (attr->ia_uid != NCP_SERVER(inode)->m.uid)))
+	     (attr->ia_uid != server->m.uid)))
X 		goto out;
X 
X 	if (((attr->ia_valid & ATTR_GID) &&
-	     (attr->ia_gid != NCP_SERVER(inode)->m.gid)))
+	     (attr->ia_gid != server->m.gid)))
X 		goto out;
X 
X 	if (((attr->ia_valid & ATTR_MODE) &&
@@ -488,26 +586,53 @@
X #if 1 
X         if ((attr->ia_valid & ATTR_MODE) != 0)
X         {
-                if (!S_ISREG(inode->i_mode))
+                if (S_ISDIR(inode->i_mode)) {
+                	umode_t newmode;
+
+                	info_mask |= DM_ATTRIBUTES;
+                	newmode = attr->ia_mode;
+                	newmode &= NCP_SERVER(inode)->m.dir_mode;
+
+                	if (newmode & 0222)
+                		info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
+                	else
+				info.attributes |=  (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
+                } else if (!S_ISREG(inode->i_mode))
X                 {
X                         return -EPERM;
X                 }
X                 else
X                 {
X 			umode_t newmode;
-
+#ifdef CONFIG_NCPFS_EXTRAS			
+			int extras;
+			
+			extras = server->m.flags & NCP_MOUNT_EXTRAS;
+#endif
X                         info_mask |= DM_ATTRIBUTES;
X                         newmode=attr->ia_mode;
-                        newmode &= NCP_SERVER(inode)->m.file_mode;
+#ifdef CONFIG_NCPFS_EXTRAS
+			if (!extras)
+#endif
+	                        newmode &= server->m.file_mode;
X 
X                         if (newmode & 0222) /* any write bit set */
X                         {
-                                info.attributes &= ~0x60001;
+                                info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
X                         }
X                         else
X                         {
-                                info.attributes |= 0x60001;
+                                info.attributes |=  (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
X                         }
+#ifdef CONFIG_NCPFS_EXTRAS
+			if (extras) {
+				if (newmode & 0111) /* any execute bit set */
+					info.attributes |= aSHARED | aSYSTEM;
+				/* read for group/world and not in default file_mode */
+				else if (newmode & ~server->m.file_mode & 0444)
+					info.attributes |= aSHARED;
+			}
+#endif
X                 }
X         }
X #endif
@@ -548,6 +673,10 @@
X 				result = 0;
X 			}
X 		}
+#ifdef CONFIG_NCPFS_STRONG		
+		if ((!result) && (info_mask & DM_ATTRIBUTES))
+			NCP_FINFO(inode)->nwattr = info.attributes;
+#endif
X 	}
X 	if ((attr->ia_valid & ATTR_SIZE) != 0) {
X 		int written;
diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/ioctl.c linux/fs/ncpfs/ioctl.c
--- v2.2.6/linux/fs/ncpfs/ioctl.c	Tue Mar 17 22:18:15 1998
+++ linux/fs/ncpfs/ioctl.c	Tue Apr 20 15:17:20 1999
@@ -3,6 +3,7 @@
X  *
X  *  Copyright (C) 1995, 1996 by Volker Lendecke
X  *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
+ *  Modified 1998 Wolfram Pienkoss for NLS
X  *
X  */
X 
@@ -17,6 +18,7 @@
X 
X #include <linux/ncp.h>
X #include <linux/ncp_fs.h>
+
X #include "ncplib_kernel.h"
X 
X /* maximum limit for ncp_objectname_ioctl */
@@ -485,6 +487,69 @@
X 			return 0;
X 		}
X #endif	/* CONFIG_NCPFS_NDS_DOMAINS */
+
+#ifdef CONFIG_NCPFS_NLS
+/* Here we are select the iocharset and the codepage for NLS.
+ * Thanks Petr Vandrovec for idea and many hints.
+ */
+	case NCP_IOC_SETCHARSETS:
+		if (   (permission(inode, MAY_WRITE) != 0)
+		    && (current->uid != server->m.mounted_uid))
+		{
+			return -EACCES;
+		}
+		if (server->root_setuped) return -EBUSY;
+		{
+			struct ncp_nls_ioctl user;
+			struct nls_table *codepage;
+			struct nls_table *iocharset;
+			struct nls_table *oldset_io;
+			struct nls_table *oldset_cp;
+			
+			if (copy_from_user(&user, 
+					   (struct ncp_nls_ioctl*)arg,
+					    sizeof(user))) return -EFAULT;
+
+			codepage = NULL;
+			if (!user.codepage[0]) {
+				codepage = load_nls_default();
+			}
+			else {
+				codepage = load_nls(user.codepage);
+				if (! codepage) {
+					return -EBADRQC;
+				}
+			}
+
+			iocharset = NULL;
+			if (user.iocharset[0] == 0) {
+				iocharset = load_nls_default();
+			}
+			else {
+				iocharset = load_nls(user.iocharset);
+				if (! iocharset) {
+					unload_nls(codepage);
+					return -EBADRQC;
+				}
+			}
+
+			oldset_cp = server->nls_vol;
+			server->nls_vol = codepage;
+			oldset_io = server->nls_io;
+			server->nls_io = iocharset;
+			server->nls_charsets = user;
+			if (oldset_cp) unload_nls(oldset_cp);
+			if (oldset_io) unload_nls(oldset_io);
+			return 0;
+		}
+		
+	case NCP_IOC_GETCHARSETS: /* not tested */
+		if (copy_to_user((struct ncp_nls_ioctl*)arg,
+				&(server->nls_charsets),
+				sizeof(server->nls_charsets))) return -EFAULT;
+		return 0;
+#endif /* CONFIG_NCPFS_NLS */
+
X 	default:
X 		return -EINVAL;
X 	}
diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/ncplib_kernel.c linux/fs/ncpfs/ncplib_kernel.c
--- v2.2.6/linux/fs/ncpfs/ncplib_kernel.c	Fri Oct  9 13:27:15 1998
+++ linux/fs/ncpfs/ncplib_kernel.c	Tue Apr 20 15:17:20 1999
@@ -238,7 +238,8 @@
X }
X 
X static void ncp_add_handle_path(struct ncp_server *server, __u8 vol_num,
-				__u32 dir_base, int have_dir_base, char *path)
+				__u32 dir_base, int have_dir_base, 
+				const char *path)
X {
X 	ncp_add_byte(server, vol_num);
X 	ncp_add_dword(server, dir_base);
@@ -468,12 +469,17 @@
X 	target->nameLen = strlen(volname);
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 15'
echo 'File patch-2.2.7 is continued in part 16'
echo 16 > _shar_seq_.tmp
#!/bin/sh
# this is part 16 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 16; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
X 	strcpy(target->entryName, volname);
X 	target->attributes = aDIR;
+	/* set dates to Jan 1, 1986  00:00 */
+	target->creationTime = target->modifyTime = cpu_to_le16(0x0000);
+	target->creationDate = target->modifyDate = target->lastAccessDate = cpu_to_le16(0x0C21);
X 	return 0;
X }
X 
-int ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
-					struct inode *dir, __u32 info_mask,
-				       struct nw_modify_dos_info *info)
+int ncp_modify_file_or_subdir_dos_info_path(struct ncp_server *server,
+					    struct inode *dir,
+					    const char *path,
+					    __u32 info_mask,
+					    const struct nw_modify_dos_info *info)
X {
X 	__u8  volnum = NCP_FINFO(dir)->volNumber;
X 	__u32 dirent = NCP_FINFO(dir)->dirEntNum;
@@ -487,13 +493,22 @@
X 
X 	ncp_add_dword(server, info_mask);
X 	ncp_add_mem(server, info, sizeof(*info));
-	ncp_add_handle_path(server, volnum, dirent, 1, NULL);
+	ncp_add_handle_path(server, volnum, dirent, 1, path);
X 
X 	result = ncp_request(server, 87);
X 	ncp_unlock_server(server);
X 	return result;
X }
X 
+int ncp_modify_file_or_subdir_dos_info(struct ncp_server *server,
+				       struct inode *dir,
+				       __u32 info_mask,
+				       const struct nw_modify_dos_info *info)
+{
+	return ncp_modify_file_or_subdir_dos_info_path(server, dir, NULL,
+		info_mask, info);
+}
+
X static int
X ncp_DeleteNSEntry(struct ncp_server *server,
X 		  __u8 have_dir_base, __u8 volnum, __u32 dirent,
@@ -787,6 +802,35 @@
X 	ncp_unlock_server(server);
X 	return result;
X }
+
+#ifdef CONFIG_NCPFS_EXTRAS
+int
+ncp_read_kernel(struct ncp_server *server, const char *file_id,
+		__u32 offset, __u16 to_read, char *target, int *bytes_read) {
+	int error;
+	mm_segment_t old_fs;
+	
+	old_fs = get_fs();
+	set_fs(get_ds());
+	error = ncp_read(server, file_id, offset, to_read, target, bytes_read);
+	set_fs(old_fs);
+	return error;
+}
+
+int
+ncp_write_kernel(struct ncp_server *server, const char *file_id,
+		 __u32 offset, __u16 to_write,
+		 const char *source, int *bytes_written) {
+	int error;
+	mm_segment_t old_fs;
+	
+	old_fs = get_fs();
+	set_fs(get_ds());
+	error = ncp_write(server, file_id, offset, to_write, source, bytes_written);
+	set_fs(old_fs);
+	return error;
+}
+#endif
X 
X #ifdef CONFIG_NCPFS_IOCTL_LOCKING
X int
diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/ncplib_kernel.h linux/fs/ncpfs/ncplib_kernel.h
--- v2.2.6/linux/fs/ncpfs/ncplib_kernel.h	Tue Mar 10 10:03:34 1998
+++ linux/fs/ncpfs/ncplib_kernel.h	Tue Apr 20 15:17:20 1999
@@ -4,6 +4,7 @@
X  *  Copyright (C) 1995, 1996 by Volker Lendecke
X  *  Modified for big endian by J.F. Chadima and David S. Miller
X  *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
+ *  Modified 1998 Wolfram Pienkoss for NLS
X  *
X  */
X 
@@ -23,6 +24,10 @@
X #include <asm/unaligned.h>
X #include <asm/string.h>
X 
+#ifdef CONFIG_NCPFS_NLS
+#include <linux/nls.h>
+#endif
+
X #include <linux/ncp.h>
X #include <linux/ncp_fs.h>
X #include <linux/ncp_fs_sb.h>
@@ -36,12 +41,19 @@
X int ncp_read(struct ncp_server *, const char *, __u32, __u16, char *, int *);
X int ncp_write(struct ncp_server *, const char *, __u32, __u16,
X 		const char *, int *);
+#ifdef CONFIG_NCPFS_EXTRAS
+int ncp_read_kernel(struct ncp_server *, const char *, __u32, __u16, char *, int *);
+int ncp_write_kernel(struct ncp_server *, const char *, __u32, __u16,
+		const char *, int *);
+#endif
X 
X int ncp_obtain_info(struct ncp_server *server, struct inode *, char *,
X 		struct nw_info_struct *target);
X int ncp_lookup_volume(struct ncp_server *, char *, struct nw_info_struct *);
X int ncp_modify_file_or_subdir_dos_info(struct ncp_server *, struct inode *,
-			 __u32, struct nw_modify_dos_info *info);
+	 __u32, const struct nw_modify_dos_info *info);
+int ncp_modify_file_or_subdir_dos_info_path(struct ncp_server *, struct inode *,
+	 const char* path, __u32, const struct nw_modify_dos_info *info);
X 
X int ncp_del_file_or_subdir2(struct ncp_server *, struct dentry*);
X int ncp_del_file_or_subdir(struct ncp_server *, struct inode *, char *);
@@ -75,4 +87,83 @@
X ncp_mount_subdir(struct ncp_server* server, __u8 volNumber, 
X 		 __u8 srcNS, __u32 srcDirEntNum);
X #endif	/* CONFIG_NCPFS_MOUNT_SUBDIR */
+
+#ifdef CONFIG_NCPFS_NLS
+/* This are the NLS conversion routines with inspirations and code parts
+ * from the vfat file system and hints from Petr Vandrovec.
+ */
+
+/*
+ * It should be replaced by charset specifc conversion. Gordon Chaffee
+ * has prepared some things, but I don't know, what he thinks about it.
+ * The conversion tables for the io charsets should be generatable by
+ * Unicode table, shouldn't it? I have written so generation code for it.
+ * The tables for the vendor specific codepages...? Hmm. The Samba sources
+ * contains also any hints.
+ */
+
+#define toupperif(c, u) ((((u) != 0) && ((c) >= 'a') && ((c) <= 'z')) \
+			? (c)-('a'-'A') : (c))
+#define tolowerif(c, u) ((((u) != 0) && ((c) >= 'A') && ((c) <= 'Z')) \
+			? (c)-('A'-'a') : (c))
+
+static inline void
+io2vol(struct ncp_server *server, char *name, int case_trans)
+{
+	unsigned char nc;
+	unsigned char *np;
+	unsigned char *up;
+	struct nls_unicode uc;
+	struct nls_table *nls_in;
+	struct nls_table *nls_out;
+
+	nls_in = server->nls_io;
+	nls_out = server->nls_vol;
+	np = name;
+
+	while (*np)
+	{
+		nc = 0;
+		uc = nls_in->charset2uni[toupperif(*np, case_trans)];
+		up = nls_out->page_uni2charset[uc.uni2];
+		if (up != NULL)	nc = up[uc.uni1];
+		if (nc != 0) *np = nc;
+		np++;
+	}
+}
+
+static inline void
+vol2io(struct ncp_server *server, char *name, int case_trans)
+{
+	unsigned char nc;
+	unsigned char *np;
+	unsigned char *up;
+	struct nls_unicode uc;
+	struct nls_table *nls_in;
+	struct nls_table *nls_out;
+
+	nls_in = server->nls_vol;
+	nls_out = server->nls_io;
+	np = name;
+
+	while (*np)
+	{
+		nc = 0;
+		uc = nls_in->charset2uni[*np];
+		up = nls_out->page_uni2charset[uc.uni2];
+		if (up != NULL)	nc = up[uc.uni1];
+		if (nc == 0) nc = *np;
+		*np = tolowerif(nc, case_trans);
+		np++;
+	}
+}
+
+#else
+
+#define io2vol(S,N,U) if (U) str_upper(N)
+#define vol2io(S,N,U) if (U) str_lower(N)
+
+#endif /* CONFIG_NCPFS_NLS */
+
X #endif /* _NCPLIB_H */
+
diff -u --recursive --new-file v2.2.6/linux/fs/ncpfs/symlink.c linux/fs/ncpfs/symlink.c
--- v2.2.6/linux/fs/ncpfs/symlink.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/ncpfs/symlink.c	Tue Apr 20 15:17:20 1999
@@ -0,0 +1,212 @@
+/*
+ *  linux/fs/ncpfs/symlink.c
+ *
+ *  Code for allowing symbolic links on NCPFS (i.e. NetWare)
+ *  Symbolic links are not supported on native NetWare, so we use an
+ *  infrequently-used flag (Sh) and store a two-word magic header in
+ *  the file to make sure we don't accidentally use a non-link file
+ *  as a link.
+ *
+ *  from linux/fs/ext2/symlink.c
+ *
+ *  Copyright (C) 1998-99, Frank A. Vorstenbosch
+ *
+ *  ncpfs symlink handling code
+ *  NLS support (c) 1999 Petr Vandrovec
+ *
+ */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_NCPFS_EXTRAS
+
+#include <asm/uaccess.h>
+#include <asm/segment.h>
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/ncp_fs.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/stat.h>
+#include "ncplib_kernel.h"
+
+
+/* these magic numbers must appear in the symlink file -- this makes it a bit
+   more resilient against the magic attributes being set on random files. */
+
+#define NCP_SYMLINK_MAGIC0	le32_to_cpu(0x6c6d7973)     /* "symlnk->" */
+#define NCP_SYMLINK_MAGIC1	le32_to_cpu(0x3e2d6b6e)
+
+static int ncp_readlink(struct dentry *, char *, int);
+static struct dentry *ncp_follow_link(struct dentry *, struct dentry *, unsigned int);
+int ncp_create_new(struct inode *dir, struct dentry *dentry,
+                          int mode,int attributes);
+
+/*
+ * symlinks can't do much...
+ */
+struct inode_operations ncp_symlink_inode_operations={
+	NULL,			/* no file-operations */
+	NULL,			/* create */
+	NULL,			/* lookup */
+	NULL,			/* link */
+	NULL,			/* unlink */
+	NULL,			/* symlink */
+	NULL,			/* mkdir */
+	NULL,			/* rmdir */
+	NULL,			/* mknod */
+	NULL,			/* rename */
+	ncp_readlink,		/* readlink */
+	ncp_follow_link,	/* follow_link */
+	NULL,			/* readpage */
+	NULL,			/* writepage */
+	NULL,			/* bmap */
+	NULL,			/* truncate */
+	NULL,			/* permission */
+	NULL			/* smap */
+};
+
+/* ----- follow a symbolic link ------------------------------------------ */
+
+static struct dentry *ncp_follow_link(struct dentry *dentry,
+				      struct dentry *base,
+				      unsigned int follow)
+{
+	struct inode *inode=dentry->d_inode;
+	int error, length, cnt;
+	char *link;
+
+#ifdef DEBUG
+	printk("ncp_follow_link(dentry=%p,base=%p,follow=%u)\n",dentry,base,follow);
+#endif
+
+	if(!S_ISLNK(inode->i_mode)) {
+		dput(base);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if(ncp_make_open(inode,O_RDONLY)) {
+		dput(base);
+		return ERR_PTR(-EIO);
+	}
+
+	for (cnt = 0; (link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE+1, GFP_NFS))==NULL; cnt++) {
+		if (cnt > 10) {
+			dput(base);
+			return ERR_PTR(-EAGAIN); /* -ENOMEM? */
+		}
+		schedule();
+	}
+
+	error=ncp_read_kernel(NCP_SERVER(inode),NCP_FINFO(inode)->file_handle,
+                         0,NCP_MAX_SYMLINK_SIZE,link,&length);
+
+	if (error!=0 || length<NCP_MIN_SYMLINK_SIZE || 
+	   ((__u32 *)link)[0]!=NCP_SYMLINK_MAGIC0 || ((__u32 *)link)[1]!=NCP_SYMLINK_MAGIC1) {
+		dput(base);
+		kfree(link);
+		return ERR_PTR(-EIO);
+	}
+ 
+	link[length]=0;
+
+	vol2io(NCP_SERVER(inode), link+8, 0);
+	
+	/* UPDATE_ATIME(inode); */
+	base=lookup_dentry(link+8, base, follow);
+	kfree(link);
+
+	return base;
+}
+
+/* ----- read symbolic link ---------------------------------------------- */
+
+static int ncp_readlink(struct dentry * dentry, char * buffer, int buflen)
+{
+	struct inode *inode=dentry->d_inode;
+	char *link;
+	int length,error;
+
+#ifdef DEBUG
+	printk("ncp_readlink(dentry=%p,buffer=%p,buflen=%d)\n",dentry,buffer,buflen);
+#endif
+
+	if(!S_ISLNK(inode->i_mode))
+		return -EINVAL;
+
+	if(ncp_make_open(inode,O_RDONLY))
+		return -EIO;
+
+	if((link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE+1,GFP_NFS))==NULL)
+		return -ENOMEM;
+
+	error = ncp_read_kernel(NCP_SERVER(inode),NCP_FINFO(inode)->file_handle,
+		0,NCP_MAX_SYMLINK_SIZE,link,&length);
+
+	if (error!=0 || length < NCP_MIN_SYMLINK_SIZE || buflen < (length-8) ||
+	   ((__u32 *)link)[0]!=NCP_SYMLINK_MAGIC0 ||((__u32 *)link)[1]!=NCP_SYMLINK_MAGIC1) {
+	   	error = -EIO;
+		goto out;
+	}
+
+	link[length] = 0;
+
+	vol2io(NCP_SERVER(inode), link+8, 0);
+	
+	error = length - 8;
+	if(copy_to_user(buffer, link+8, error))
+		error = -EFAULT;
+      
+out:;
+	kfree(link);
+	return error;
+}
+
+/* ----- create a new symbolic link -------------------------------------- */
+ 
+int ncp_symlink(struct inode *dir, struct dentry *dentry, const char *symname) {
+	int i,length;
+	struct inode *inode;
+	char *link;
+
+#ifdef DEBUG
+	printk("ncp_symlink(dir=%p,dentry=%p,symname=%s)\n",dir,dentry,symname);
+#endif
+
+	if (!(NCP_SERVER(dir)->m.flags & NCP_MOUNT_SYMLINKS))
+		return -EPERM;	/* EPERM is returned by VFS if symlink procedure does not exist */
+
+	if ((length=strlen(symname))>NCP_MAX_SYMLINK_SIZE)
+		return -EINVAL;
+
+	if ((link=(char *)kmalloc(length+9,GFP_NFS))==NULL)
+		return -ENOMEM;
+
+	if (ncp_create_new(dir,dentry,0,aSHARED|aHIDDEN)) {
+		kfree(link);
+		return -EIO;
+	}
+
+	inode=dentry->d_inode;
+
+	((__u32 *)link)[0]=NCP_SYMLINK_MAGIC0;
+	((__u32 *)link)[1]=NCP_SYMLINK_MAGIC1;
+	memcpy(link+8, symname, length+1); /* including last zero for io2vol */
+
+	/* map to/from server charset, do not touch upper/lower case as
+	   symlink can point out of ncp filesystem */
+	io2vol(NCP_SERVER(inode), link+8, 0);
+	
+	if(ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, 
+	    		    0, length+8, link, &i) || i!=length+8) {
+		kfree(link);
+		return -EIO;
+	}
+
+	kfree(link);
+	return 0;
+}
+#endif
+
+/* ----- EOF ----- */
diff -u --recursive --new-file v2.2.6/linux/fs/nfs/dir.c linux/fs/nfs/dir.c
--- v2.2.6/linux/fs/nfs/dir.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/nfs/dir.c	Sat Apr 24 12:45:37 1999
@@ -51,10 +51,9 @@
X 
X static int nfs_safe_remove(struct dentry *);
X 
-static int nfs_dir_open(struct inode *, struct file *);
X static ssize_t nfs_dir_read(struct file *, char *, size_t, loff_t *);
X static int nfs_readdir(struct file *, void *, filldir_t);
-static int nfs_lookup(struct inode *, struct dentry *);
+static struct dentry *nfs_lookup(struct inode *, struct dentry *);
X static int nfs_create(struct inode *, struct dentry *, int);
X static int nfs_mkdir(struct inode *, struct dentry *, int);
X static int nfs_rmdir(struct inode *, struct dentry *);
@@ -73,7 +72,7 @@
X 	NULL,			/* select - default */
X 	NULL,			/* ioctl - default */
X 	NULL,			/* mmap */
-	nfs_dir_open,		/* open - revalidate */
+	NULL,			/* no special open is needed */
X 	NULL,			/* flush */
X 	NULL,			/* no special release code */
X 	NULL			/* fsync */
@@ -102,16 +101,6 @@
X 	nfs_revalidate,		/* revalidate */
X };
X 
-static int
-nfs_dir_open(struct inode *dir, struct file *file)
-{
-	struct dentry *dentry = file->f_dentry;
-
-	dfprintk(VFS, "NFS: nfs_dir_open(%s/%s)\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name);
-	return nfs_revalidate_inode(NFS_DSERVER(dentry), dentry);
-}
-
X static ssize_t
X nfs_dir_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
X {
@@ -147,11 +136,6 @@
X 
X 	dfprintk(VFS, "NFS: nfs_readdir(%s/%s)\n",
X 		dentry->d_parent->d_name.name, dentry->d_name.name);
-	result = -EBADF;
-	if (!inode || !S_ISDIR(inode->i_mode)) {
- printk("nfs_readdir: inode is NULL or not a directory\n");
-		goto out;
-	}
X 
X 	result = nfs_revalidate_inode(NFS_DSERVER(dentry), dentry);
X 	if (result < 0)
@@ -397,7 +381,6 @@
X {
X 	struct dentry * parent = dentry->d_parent;
X 	struct inode * inode = dentry->d_inode;
-	unsigned long time = jiffies - dentry->d_time;
X 	int error;
X 	struct nfs_fh fhandle;
X 	struct nfs_fattr fattr;
@@ -406,31 +389,36 @@
X 	 * If we don't have an inode, let's just assume
X 	 * a 5-second "live" time for negative dentries.
X 	 */
-	if (!inode) {
-		if (time < NFS_REVALIDATE_INTERVAL)
-			goto out_valid;
-		goto out_bad;
-	}
+	if (!inode)
+		goto do_lookup;
X 
X 	if (is_bad_inode(inode)) {
-#ifdef NFS_PARANOIA
-printk("nfs_lookup_validate: %s/%s has dud inode\n",
-parent->d_name.name, dentry->d_name.name);
-#endif
+		dfprintk(VFS, "nfs_lookup_validate: %s/%s has dud inode\n",
+			parent->d_name.name, dentry->d_name.name);
X 		goto out_bad;
X 	}
X 
-	if (time < NFS_ATTRTIMEO(inode))
+	if (_nfs_revalidate_inode(NFS_DSERVER(dentry), dentry))
+		goto out_bad;
+
+	if (time_before(jiffies,dentry->d_time+NFS_ATTRTIMEO(inode)))
X 		goto out_valid;
X 
X 	if (IS_ROOT(dentry))
X 		goto out_valid;
X 
+do_lookup:
X 	/*
X 	 * Do a new lookup and check the dentry attributes.
X 	 */
X 	error = nfs_proc_lookup(NFS_DSERVER(parent), NFS_FH(parent), 
X 				dentry->d_name.name, &fhandle, &fattr);
+	if (dentry->d_inode == NULL) {
+		if (error == -ENOENT &&
+		    time_before(jiffies,dentry->d_time+NFS_REVALIDATE_INTERVAL))
+			goto out_valid;
+		goto out_bad;
+	}
X 	if (error)
X 		goto out_bad;
X 
@@ -439,8 +427,10 @@
X 		goto out_bad;
X 
X 	/* Filehandle matches? */
-	if (memcmp(dentry->d_fsdata, &fhandle, sizeof(struct nfs_fh)))
-		goto out_bad;
+	if (memcmp(dentry->d_fsdata, &fhandle, sizeof(struct nfs_fh))) {
+		if (dentry->d_count < 2)
+			goto out_bad;
+	}
X 
X 	/* Ok, remeber that we successfully checked it.. */
X 	nfs_renew_times(dentry);
@@ -449,6 +439,10 @@
X out_valid:
X 	return 1;
X out_bad:
+	if (dentry->d_parent->d_inode)
+		nfs_invalidate_dircache(dentry->d_parent->d_inode);
+	if (inode && S_ISDIR(inode->i_mode))
+		nfs_invalidate_dircache(inode);
X 	return 0;
X }
X 
@@ -533,7 +527,7 @@
X }
X #endif
X 
-static int nfs_lookup(struct inode *dir, struct dentry * dentry)
+static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry)
X {
X 	struct inode *inode;
X 	int error;
@@ -579,7 +573,7 @@
X 		}
X 	}
X out:
-	return error;
+	return ERR_PTR(error);
X }
X 
X /*
@@ -764,7 +758,7 @@
X {
X 	struct qstr    sqstr;
X 	struct dentry *sdentry;
-	int error;
+	struct dentry *res;
X 
X 	sqstr.name = silly;
X 	sqstr.len  = slen;
@@ -774,10 +768,10 @@
X 		sdentry = d_alloc(parent, &sqstr);
X 		if (sdentry == NULL)
X 			return ERR_PTR(-ENOMEM);
-		error = nfs_lookup(parent->d_inode, sdentry);
-		if (error) {
+		res = nfs_lookup(parent->d_inode, sdentry);
+		if (res) {
X 			dput(sdentry);
-			return ERR_PTR(error);
+			return res;
X 		}
X 	}
X 	return sdentry;
diff -u --recursive --new-file v2.2.6/linux/fs/nfs/inode.c linux/fs/nfs/inode.c
--- v2.2.6/linux/fs/nfs/inode.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/nfs/inode.c	Sat Apr 24 12:45:37 1999
@@ -37,6 +37,8 @@
X #define NFS_PARANOIA 1
X 
X static struct inode * __nfs_fhget(struct super_block *, struct nfs_fattr *);
+static void nfs_zap_caches(struct inode *);
+static void nfs_invalidate_inode(struct inode *);
X 
X static void nfs_read_inode(struct inode *);
X static void nfs_put_inode(struct inode *);
@@ -234,6 +236,11 @@
X 	server->rsize    = nfs_block_size(data->rsize, NULL);
X 	server->wsize    = nfs_block_size(data->wsize, NULL);
X 	server->flags    = data->flags;
+
+	if (data->flags & NFS_MOUNT_NOAC) {
+		data->acregmin = data->acregmax = 0;
+		data->acdirmin = data->acdirmax = 0;
+	}
X 	server->acregmin = data->acregmin*HZ;
X 	server->acregmax = data->acregmax*HZ;
X 	server->acdirmin = data->acdirmin*HZ;
@@ -388,25 +395,61 @@
X  * could cause file corruption. But since the dentry
X  * count is 0 and all pending IO for a dentry has been
X  * flushed when the count went to 0, we're safe here.
+ * Also returns the number of unhashed dentries
X  */
-void nfs_free_dentries(struct inode *inode)
+static int
+nfs_free_dentries(struct inode *inode)
X {
X 	struct list_head *tmp, *head = &inode->i_dentry;
+	int unhashed;
X 
X restart:
X 	tmp = head;
+	unhashed = 0;
X 	while ((tmp = tmp->next) != head) {
X 		struct dentry *dentry = list_entry(tmp, struct dentry, d_alias);
-printk("nfs_free_dentries: found %s/%s, d_count=%d, hashed=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name,
-dentry->d_count, !list_empty(&dentry->d_hash));
+		dprintk("nfs_free_dentries: found %s/%s, d_count=%d, hashed=%d\n",
+			dentry->d_parent->d_name.name, dentry->d_name.name,
+			dentry->d_count, !list_empty(&dentry->d_hash));
X 		if (!dentry->d_count) {
X 			dget(dentry);
X 			d_drop(dentry);
X 			dput(dentry);
X 			goto restart;
X 		}
+		if (!list_empty(&dentry->d_hash))
+			unhashed++;
X 	}
+	return unhashed;
+}
+
+/*
+ * Invalidate the local caches
+ */
+static void
+nfs_zap_caches(struct inode *inode)
+{
+	NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
+	NFS_CACHEINV(inode);
+
+	if (S_ISDIR(inode->i_mode))
+		nfs_invalidate_dircache(inode);
+	else
+		invalidate_inode_pages(inode);
+}
+
+/*
+ * Invalidate, but do not unhash, the inode
+ */
+static void
+nfs_invalidate_inode(struct inode *inode)
+{
+	umode_t save_mode = inode->i_mode;
+
+	make_bad_inode(inode);
+	inode->i_mode = save_mode;
+	nfs_inval(inode);
+	nfs_zap_caches(inode);
X }
X 
X /*
@@ -508,7 +551,7 @@
X __nfs_fhget(struct super_block *sb, struct nfs_fattr *fattr)
X {
X 	struct inode *inode;
-	int max_count;
+	int max_count, stale_inode, unhashed = 0;
X 
X retry:
X 	inode = iget(sb, fattr->fileid);
@@ -527,27 +570,30 @@
X 	 * as the inode may have become a different object.
X 	 * (We can probably handle modes changes here, too.)
X 	 */
+	stale_inode = inode->i_mode &&
+		      ((fattr->mode ^ inode->i_mode) & S_IFMT);
+	stale_inode |= inode->i_count && inode->i_count == unhashed;
X 	max_count = S_ISDIR(fattr->mode) ? 1 : fattr->nlink;
-	if (inode->i_count > max_count) {
-printk("__nfs_fhget: inode %ld busy, i_count=%d, i_nlink=%d\n",
-inode->i_ino, inode->i_count, inode->i_nlink);
-		nfs_free_dentries(inode);
-		if (inode->i_count > max_count) {
-printk("__nfs_fhget: inode %ld still busy, i_count=%d\n",
-inode->i_ino, inode->i_count);
+	if (stale_inode || inode->i_count > max_count + unhashed) {
+		dprintk("__nfs_fhget: inode %ld busy, i_count=%d, i_nlink=%d\n",
+			inode->i_ino, inode->i_count, inode->i_nlink);
+		unhashed = nfs_free_dentries(inode);
+		if (stale_inode || inode->i_count > max_count + unhashed) {
+			printk("__nfs_fhget: inode %ld still busy, i_count=%d\n",
+				inode->i_ino, inode->i_count);
X 			if (!list_empty(&inode->i_dentry)) {
X 				struct dentry *dentry;
X 				dentry = list_entry(inode->i_dentry.next,
X 						 struct dentry, d_alias);
-printk("__nfs_fhget: killing %s/%s filehandle\n",
-dentry->d_parent->d_name.name, dentry->d_name.name);
-				memset(dentry->d_fsdata, 0, 
+				printk("__nfs_fhget: killing %s/%s filehandle\n",
+					dentry->d_parent->d_name.name,
+					dentry->d_name.name);
+				memset(dentry->d_fsdata, 0,
X 					sizeof(struct nfs_fh));
-			} else
-				printk("NFS: inode %ld busy, no aliases?\n",
-					inode->i_ino);
-			make_bad_inode(inode);
+			}
X 			remove_inode_hash(inode);
+			nfs_invalidate_inode(inode);
+			unhashed = 0;
X 		}
X 		iput(inode);
X 		goto retry;
@@ -660,10 +706,6 @@
X 	int		 status = 0;
X 	struct nfs_fattr fattr;
X 
-	/* Don't bother revalidating if we've done it recently */
-	if (jiffies - NFS_READTIME(inode) < NFS_ATTRTIMEO(inode))
-		goto out;
-
X 	dfprintk(PAGECACHE, "NFS: revalidating %s/%s, ino=%ld\n",
X 		dentry->d_parent->d_name.name, dentry->d_name.name,
X 		inode->i_ino);
@@ -672,10 +714,9 @@
X 		int error;
X 		u32 *fh;
X 		struct nfs_fh fhandle;
-#ifdef NFS_PARANOIA
-printk("nfs_revalidate_inode: %s/%s getattr failed, ino=%ld, error=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, inode->i_ino, status);
-#endif
+		dfprintk(PAGECACHE, "nfs_revalidate_inode: %s/%s getattr failed, ino=%ld, error=%d\n",
+			dentry->d_parent->d_name.name,
+			dentry->d_name.name, inode->i_ino, status);
X 		if (status != -ESTALE)
X 			goto out;
X 		/*
@@ -683,26 +724,25 @@
X 		 * and find out what the filehandle should be.
X 		 */
X 		fh = (u32 *) NFS_FH(dentry);
-		printk("NFS: bad fh %08x%08x%08x%08x%08x%08x%08x%08x\n",
+		dfprintk(PAGECACHE, "NFS: bad fh %08x%08x%08x%08x%08x%08x%08x%08x\n",
X 			fh[0],fh[1],fh[2],fh[3],fh[4],fh[5],fh[6],fh[7]);
X 		error = nfs_proc_lookup(server, NFS_FH(dentry->d_parent), 
X 					dentry->d_name.name, &fhandle, &fattr);
X 		if (error) {
-			printk("NFS: lookup failed, error=%d\n", error);
+			dfprintk(PAGECACHE, "NFS: lookup failed, error=%d\n", error);
X 			goto out;
X 		}
X 		fh = (u32 *) &fhandle;
-		printk("            %08x%08x%08x%08x%08x%08x%08x%08x\n",
+		dfprintk(PAGECACHE, "            %08x%08x%08x%08x%08x%08x%08x%08x\n",
X 			fh[0],fh[1],fh[2],fh[3],fh[4],fh[5],fh[6],fh[7]);
X 		goto out;
X 	}
X 
X 	status = nfs_refresh_inode(inode, &fattr);
X 	if (status) {
-#ifdef NFS_PARANOIA
-printk("nfs_revalidate_inode: %s/%s refresh failed, ino=%ld, error=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, inode->i_ino, status);
-#endif
+		dfprintk(PAGECACHE, "nfs_revalidate_inode: %s/%s refresh failed, ino=%ld, error=%d\n",
+			dentry->d_parent->d_name.name,
+			dentry->d_name.name, inode->i_ino, status);
X 		goto out;
X 	}
X 	dfprintk(PAGECACHE, "NFS: %s/%s revalidation complete\n",
@@ -808,29 +848,18 @@
X printk("nfs_refresh_inode: inode %ld mode changed, %07o to %07o\n",
X inode->i_ino, inode->i_mode, fattr->mode);
X #endif
-	fattr->mode = inode->i_mode; /* save mode */
-	make_bad_inode(inode);
-	nfs_inval(inode);
-	inode->i_mode = fattr->mode; /* restore mode */
X 	/*
X 	 * No need to worry about unhashing the dentry, as the
X 	 * lookup validation will know that the inode is bad.
-	 * (But we fall through to invalidate the caches.)
X 	 */
+	nfs_invalidate_inode(inode);
+	goto out;
X 
X out_invalid:
-	/*
-	 * Invalidate the local caches
-	 */
X #ifdef NFS_DEBUG_VERBOSE
X printk("nfs_refresh_inode: invalidating %ld pages\n", inode->i_nrpages);
X #endif
-	if (!S_ISDIR(inode->i_mode))
-		invalidate_inode_pages(inode);
-	else
-		nfs_invalidate_dircache(inode);
-	NFS_CACHEINV(inode);
-	NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
+	nfs_zap_caches(inode);
X 	goto out;
X }
X 
diff -u --recursive --new-file v2.2.6/linux/fs/nls/Config.in linux/fs/nls/Config.in
--- v2.2.6/linux/fs/nls/Config.in	Wed Jan 13 15:00:43 1999
+++ linux/fs/nls/Config.in	Tue Apr 20 15:17:20 1999
@@ -4,7 +4,7 @@
X 
X # msdos and Joliet want NLS
X if [ "$CONFIG_JOLIET" = "y" -o "$CONFIG_FAT_FS" != "n" \
-	-o "$CONFIG_NTFS_FS" != "n" ]; then
+	-o "$CONFIG_NTFS_FS" != "n" -o "$CONFIG_NCPFS_NLS" = "y" ]; then
X   define_bool CONFIG_NLS y
X else
X   define_bool CONFIG_NLS n
diff -u --recursive --new-file v2.2.6/linux/fs/ntfs/fs.c linux/fs/ntfs/fs.c
--- v2.2.6/linux/fs/ntfs/fs.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/ntfs/fs.c	Fri Apr 23 21:20:38 1999
@@ -215,7 +215,6 @@
X 
X 	ntfs_debug(DEBUG_OTHER, "ntfs_readdir ino %x mode %x\n",
X 	       (unsigned)dir->i_ino,(unsigned int)dir->i_mode);
-	if(!dir || (dir->i_ino==0) || !S_ISDIR(dir->i_mode))return -EBADF;
X 
X 	ntfs_debug(DEBUG_OTHER, "readdir: Looking for file %x dircount %d\n",
X 	       (unsigned)filp->f_pos,dir->i_count);
@@ -373,7 +372,7 @@
X 	return 0;
X }
X 			
-static int ntfs_lookup(struct inode *dir, struct dentry *d)
+static struct dentry *ntfs_lookup(struct inode *dir, struct dentry *d)
X {
X 	struct inode *res=0;
X 	char *item=0;
@@ -385,10 +384,10 @@
X 	error=ntfs_decodeuni(NTFS_INO2VOL(dir),(char*)d->d_name.name,
X 			     d->d_name.len,&walk.name,&walk.namelen);
X 	if(error)
-		return error;
+		return ERR_PTR(-error);
X 	item=ntfs_malloc(ITEM_SIZE);
X 	if( !item )
-		return ENOMEM;
+		return ERR_PTR(-ENOMEM);
X 	/* ntfs_getdir will place the directory entry into item,
X 	   and the first long long is the MFT record number */
X 	walk.type=BY_NAME;
@@ -402,7 +401,7 @@
X 	ntfs_free(item);
X 	ntfs_free(walk.name);
X 	/* Always return success, the dcache will handle negative entries. */
-	return 0;
+	return NULL;
X }
X 
X static struct file_operations ntfs_file_operations_nommap = {
@@ -829,7 +828,7 @@
X 
X 	error = ntfs_get_volumesize( NTFS_SB2VOL( sb ), &fs.f_blocks );
X 	if( error )
-		return error;
+		return -error;
X 	fs.f_bfree=ntfs_get_free_cluster_count(vol->bitmap);
X 	fs.f_bavail=fs.f_bfree;
X 
diff -u --recursive --new-file v2.2.6/linux/fs/ntfs/inode.c linux/fs/ntfs/inode.c
--- v2.2.6/linux/fs/ntfs/inode.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/ntfs/inode.c	Sat Apr 24 17:51:48 1999
@@ -150,6 +150,8 @@
X 	ntfs_insert_fixups(buf,vol->blocksize);
X 	io.param=buf;
X 	io.size=vol->mft_recordsize;
+	io.fn_put = ntfs_put;
+	io.fn_get = ntfs_get;
X 	error=ntfs_write_attr(vol->mft_ino,vol->at_data,0,
X 			      (rcount-1)*vol->mft_recordsize,&io);
X 	if(error)return error;
diff -u --recursive --new-file v2.2.6/linux/fs/proc/fd.c linux/fs/proc/fd.c
--- v2.2.6/linux/fs/proc/fd.c	Thu Nov 19 09:56:28 1998
+++ linux/fs/proc/fd.c	Fri Apr 23 21:20:38 1999
@@ -19,7 +19,7 @@
X #include <asm/uaccess.h>
X 
X static int proc_readfd(struct file *, void *, filldir_t);
-static int proc_lookupfd(struct inode *, struct dentry *);
+static struct dentry *proc_lookupfd(struct inode *, struct dentry *);
X 
X static struct file_operations proc_fd_operations = {
X 	NULL,			/* lseek - default */
@@ -67,7 +67,7 @@
X  *
X  * Thus just return -ENOENT instead.
X  */
-static int proc_lookupfd(struct inode * dir, struct dentry * dentry)
+static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
X {
X 	unsigned int ino, pid, fd, c;
X 	struct task_struct * p;
@@ -77,13 +77,11 @@
X 	int len, err;
X 
X 	err = -ENOENT;
-	if (!dir)
-		goto out;
X 	ino = dir->i_ino;
X 	pid = ino >> 16;
X 	ino &= 0x0000ffff;
X 
-	if (!pid || ino != PROC_PID_FD || !S_ISDIR(dir->i_mode))
+	if (!pid || ino != PROC_PID_FD)
X 		goto out;
X 
X 	fd = 0;
@@ -121,10 +119,10 @@
X 	if (inode) {
X 		dentry->d_op = &proc_dentry_operations;
X 		d_add(dentry, inode);
-		err = 0;
+		return NULL;
X 	}
X out:
-	return err;
+	return ERR_PTR(err);
X }
X 
X #define NUMBUF 10
@@ -136,10 +134,6 @@
X 	unsigned int fd, pid, ino;
X 	int retval;
X 	char buf[NUMBUF];
-
-	retval = -EBADF;
-	if (!inode || !S_ISDIR(inode->i_mode))
-		goto out;
X 
X 	retval = 0;
X 	ino = inode->i_ino;
diff -u --recursive --new-file v2.2.6/linux/fs/proc/openpromfs.c linux/fs/proc/openpromfs.c
--- v2.2.6/linux/fs/proc/openpromfs.c	Thu Nov 19 09:56:29 1998
+++ linux/fs/proc/openpromfs.c	Wed Apr 28 08:47:39 1999
@@ -1,4 +1,4 @@
-/* $Id: openpromfs.c,v 1.32 1998/11/18 06:15:20 davem Exp $
+/* $Id: openpromfs.c,v 1.33 1999/04/28 11:57:33 davem Exp $
X  * openpromfs.c: /proc/openprom handling routines
X  *
X  * Copyright (C) 1996-1998 Jakub Jelinek  (j...@sunsite.mff.cuni.cz)
@@ -59,7 +59,7 @@
X 
X static int openpromfs_create (struct inode *, struct dentry *, int);
X static int openpromfs_readdir(struct file *, void *, filldir_t);
-static int openpromfs_lookup(struct inode *, struct dentry *dentry);
+static struct dentry *openpromfs_lookup(struct inode *, struct dentry *dentry);
X static int openpromfs_unlink (struct inode *, struct dentry *dentry);
X 
X static ssize_t nodenum_read(struct file *file, char *buf,
@@ -685,7 +685,7 @@
X 	return 0;
X }
X 
-static int openpromfs_lookup(struct inode * dir, struct dentry *dentry)
+static struct dentry *openpromfs_lookup(struct inode * dir, struct dentry *dentry)
X {
X 	int ino = 0;
X #define OPFSL_DIR	0
@@ -776,11 +776,11 @@
X 		if (ino)
X 			type = OPFSL_DIR;
X 		else
-			return -ENOENT;
+			return ERR_PTR(-ENOENT);
X 	}
X 	inode = proc_get_inode (dir->i_sb, ino, 0);
X 	if (!inode)
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
X 	switch (type) {
X 	case OPFSL_DIR:
X 		inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
@@ -827,7 +827,7 @@
X 	inode->i_uid = 0;
X 
X 	d_add(dentry, inode);
-	return 0;
+	return NULL;
X }
X 
X static int openpromfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
@@ -842,7 +842,6 @@
X 	struct openpromfs_dev *d;
X 	char buffer2[64];
X 	
-	if (!inode || !S_ISDIR (inode->i_mode)) return -ENOTDIR;
X 	ino = inode->i_ino;
X 	i = filp->f_pos;
X 	switch (i) {
diff -u --recursive --new-file v2.2.6/linux/fs/proc/root.c linux/fs/proc/root.c
--- v2.2.6/linux/fs/proc/root.c	Tue Jan 19 11:32:52 1999
+++ linux/fs/proc/root.c	Wed Apr 28 08:47:39 1999
@@ -28,7 +28,7 @@
X #define FIRST_PROCESS_ENTRY 256
X 
X static int proc_root_readdir(struct file *, void *, filldir_t);
-static int proc_root_lookup(struct inode *,struct dentry *);
+static struct dentry *proc_root_lookup(struct inode *,struct dentry *);
X static int proc_unlink(struct inode *, struct dentry *);
X 
X static unsigned char proc_alloc_map[PROC_NDYNAMIC / 8] = {0};
@@ -181,14 +181,14 @@
X #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
X 
X static int (*proc_openprom_defreaddir_ptr)(struct file *, void *, filldir_t);
-static int (*proc_openprom_deflookup_ptr)(struct inode *, struct dentry *);
+static struct dentry * (*proc_openprom_deflookup_ptr)(struct inode *, struct dentry *);
X void (*proc_openprom_use)(struct inode *, int) = 0;
X static struct openpromfs_dev *proc_openprom_devices = NULL;
X static ino_t proc_openpromdev_ino = PROC_OPENPROMD_FIRST;
X 
X struct inode_operations *
X proc_openprom_register(int (*readdir)(struct file *, void *, filldir_t),
-		       int (*lookup)(struct inode *, struct dentry *),
+		       struct dentry * (*lookup)(struct inode *, struct dentry *),
X 		       void (*use)(struct inode *, int),
X 		       struct openpromfs_dev ***devices)
X {
@@ -250,7 +250,7 @@
X }
X #define OPENPROM_DEFREADDIR proc_openprom_defreaddir
X 
-static int 
+static struct dentry *
X proc_openprom_deflookup(struct inode * dir, struct dentry *dentry)
X {
X 	request_module("openpromfs");
@@ -258,7 +258,7 @@
X 	    proc_openprom_deflookup)
X 		return proc_openprom_inode_operations.lookup 
X 				(dir, dentry);
-	return -ENOENT;
+	return ERR_PTR(-ENOENT);
X }
X #define OPENPROM_DEFLOOKUP proc_openprom_deflookup
X #else
@@ -769,16 +769,12 @@
X  * Don't create negative dentries here, return -ENOENT by hand
X  * instead.
X  */
-int proc_lookup(struct inode * dir, struct dentry *dentry)
+struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry)
X {
X 	struct inode *inode;
X 	struct proc_dir_entry * de;
X 	int error;
X 
-	error = -ENOTDIR;
-	if (!dir || !S_ISDIR(dir->i_mode))
-		goto out;
-
X 	error = -ENOENT;
X 	inode = NULL;
X 	de = (struct proc_dir_entry *) dir->u.generic_ip;
@@ -800,13 +796,12 @@
X 	if (inode) {
X 		dentry->d_op = &proc_dentry_operations;
X 		d_add(dentry, inode);
-		error = 0;
+		return NULL;
X 	}
-out:
-	return error;
+	return ERR_PTR(error);
X }
X 
-static int proc_root_lookup(struct inode * dir, struct dentry * dentry)
+static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
X {
X 	unsigned int pid, c;
X 	struct task_struct *p;
@@ -826,7 +821,7 @@
X 	}
X 
X 	if (!proc_lookup(dir, dentry))
-		return 0;
+		return NULL;
X 	
X 	pid = 0;
X 	name = dentry->d_name.name;
@@ -853,13 +848,13 @@
X 		unsigned long ino = (pid << 16) + PROC_PID_INO;
X 		inode = proc_get_inode(dir->i_sb, ino, &proc_pid);
X 		if (!inode)
-			return -EINVAL;
+			return ERR_PTR(-EINVAL);
X 		inode->i_flags|=S_IMMUTABLE;
X 	}
X 
X 	dentry->d_op = &proc_dentry_operations;
X 	d_add(dentry, inode);
-	return 0;
+	return NULL;
X }
X 
X /*
@@ -879,8 +874,6 @@
X 	int i;
X 	struct inode *inode = filp->f_dentry->d_inode;
X 
-	if (!inode || !S_ISDIR(inode->i_mode))
-		return -ENOTDIR;
X 	ino = inode->i_ino;
X 	de = (struct proc_dir_entry *) inode->u.generic_ip;
X 	if (!de)
diff -u --recursive --new-file v2.2.6/linux/fs/qnx4/dir.c linux/fs/qnx4/dir.c
--- v2.2.6/linux/fs/qnx4/dir.c	Sat Sep  5 16:46:41 1998
+++ linux/fs/qnx4/dir.c	Fri Apr 23 21:20:38 1999
@@ -35,9 +35,6 @@
X 	blknum = inode->u.qnx4_i.i_first_xtnt.xtnt_blk - 1 +
X 	    ((filp->f_pos >> 6) >> 3);
X 
-	if (!inode || !inode->i_sb || !S_ISDIR(inode->i_mode)) {
-		return -EBADF;
-	}
X 	QNX4DEBUG(("qnx4_readdir:i_size = %ld\n", (long) inode->i_size));
X 	QNX4DEBUG(("filp->f_pos         = %ld\n", (long) filp->f_pos));
X 	QNX4DEBUG(("BlkNum              = %ld\n", (long) blknum));
diff -u --recursive --new-file v2.2.6/linux/fs/qnx4/namei.c linux/fs/qnx4/namei.c
--- v2.2.6/linux/fs/qnx4/namei.c	Tue Dec 22 14:16:57 1998
+++ linux/fs/qnx4/namei.c	Fri Apr 23 21:20:38 1999
@@ -108,7 +108,7 @@
X 	return NULL;
X }
X 
-int qnx4_lookup(struct inode *dir, struct dentry *dentry)
+struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry)
X {
X 	int ino;
X 	struct qnx4_inode_entry *de;
@@ -116,17 +116,10 @@
X 	struct buffer_head *bh;
X 	const char *name = dentry->d_name.name;
X 	int len = dentry->d_name.len;
-	struct inode *foundinode;
+	struct inode *foundinode = NULL;
X 
-	if (!dir) {
-		return -EBADF;
-	}
-	if (!S_ISDIR(dir->i_mode)) {
-		return -EBADF;
-	}
-	if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino))) {
-		return -ENOENT;
-	}
+	if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino)))
+		goto out;
X 	/* The entry is linked, let's get the real info */
X 	if ((de->di_status & QNX4_FILE_LINK) == QNX4_FILE_LINK) {
X 		lnk = (struct qnx4_link_info *) de;
@@ -137,11 +130,12 @@
X 
X 	if ((foundinode = iget(dir->i_sb, ino)) == NULL) {
X 		QNX4DEBUG(("qnx4: lookup->iget -> NULL\n"));
-		return -EACCES;
+		return ERR_PTR(-EACCES);
X 	}
+out:
X 	d_add(dentry, foundinode);
X 
-	return 0;
+	return NULL;
X }
X 
X #ifdef CONFIG_QNX4FS_RW
diff -u --recursive --new-file v2.2.6/linux/fs/romfs/inode.c linux/fs/romfs/inode.c
--- v2.2.6/linux/fs/romfs/inode.c	Mon Sep 28 10:51:35 1998
+++ linux/fs/romfs/inode.c	Fri Apr 23 21:20:38 1999
@@ -267,9 +267,6 @@
X 	int stored = 0;
X 	char fsname[ROMFS_MAXFN];	/* XXX dynamic? */
X 
-	if (!i || !S_ISDIR(i->i_mode))
-		return -EBADF;
-
X 	maxoff = i->i_sb->u.romfs_sb.s_maxsize;
X 
X 	offset = filp->f_pos;
@@ -312,7 +309,7 @@
X 	}
X }
X 
-static int
+static struct dentry *
X romfs_lookup(struct inode *dir, struct dentry *dentry)
X {
X 	unsigned long offset, maxoff;
@@ -323,10 +320,6 @@
X 	const char *name;		/* got from dentry */
X 	int len;
X 
-	res = -EBADF;
-	if (!dir || !S_ISDIR(dir->i_mode))
-		goto out;
-
X 	res = 0;			/* instead of ENOENT */
X 	offset = dir->i_ino & ROMFH_MASK;
X 	if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)
@@ -379,7 +372,7 @@
X 	}
X 
X out:
-	return res;
+	return ERR_PTR(res);
X }
X 
X /*
diff -u --recursive --new-file v2.2.6/linux/fs/smbfs/dir.c linux/fs/smbfs/dir.c
--- v2.2.6/linux/fs/smbfs/dir.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/smbfs/dir.c	Fri Apr 23 21:20:38 1999
@@ -22,7 +22,7 @@
X static int smb_readdir(struct file *, void *, filldir_t);
X static int smb_dir_open(struct inode *, struct file *);
X 
-static int smb_lookup(struct inode *, struct dentry *);
+static struct dentry *smb_lookup(struct inode *, struct dentry *);
X static int smb_create(struct inode *, struct dentry *, int);
X static int smb_mkdir(struct inode *, struct dentry *, int);
X static int smb_rmdir(struct inode *, struct dentry *);
@@ -324,7 +324,7 @@
X 	}
X }
X 
-static int
+static struct dentry *
X smb_lookup(struct inode *dir, struct dentry *dentry)
X {
X 	struct smb_fattr finfo;
@@ -360,7 +360,7 @@
X 		}
X 	}
X out:
-	return error;
+	return ERR_PTR(error);
X }
X 
X /*
diff -u --recursive --new-file v2.2.6/linux/fs/sysv/dir.c linux/fs/sysv/dir.c
--- v2.2.6/linux/fs/sysv/dir.c	Thu Nov 12 16:21:23 1998
+++ linux/fs/sysv/dir.c	Fri Apr 23 21:20:38 1999
@@ -69,14 +69,12 @@
X static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
X {
X 	struct inode *inode = filp->f_dentry->d_inode;
-	struct super_block * sb;
+	struct super_block * sb = inode->i_sb;
X 	unsigned int offset,i;
X 	struct buffer_head * bh;
X 	char* bh_data;
X 	struct sysv_dir_entry * de, sde;
X 
-	if (!inode || !(sb = inode->i_sb) || !S_ISDIR(inode->i_mode))
-		return -EBADF;
X 	if ((unsigned long)(filp->f_pos) % SYSV_DIRSIZE)
X 		return -EBADF;
X 	while (filp->f_pos < inode->i_size) {
diff -u --recursive --new-file v2.2.6/linux/fs/sysv/namei.c linux/fs/sysv/namei.c
--- v2.2.6/linux/fs/sysv/namei.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/sysv/namei.c	Fri Apr 23 21:20:38 1999
@@ -103,17 +103,12 @@
X 	return NULL;
X }
X 
-int sysv_lookup(struct inode * dir, struct dentry * dentry)
+struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry)
X {
X 	struct inode * inode = NULL;
X struct sysv_dir_entry * de;
X 	struct buffer_head * bh;
X 
-	if (!dir)
-		return -ENOENT;
-	if (!S_ISDIR(dir->i_mode)) {
-		return -ENOENT;
-	}
X 	bh = sysv_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
X 
X 	if (bh) {
@@ -122,10 +117,10 @@
X 		inode = iget(dir->i_sb, ino);
X 	
X 		if (!inode) 
-			return -EACCES;
+			return ERR_PTR(-EACCES);
X 	}
X 	d_add(dentry, inode);
-	return 0;
+	return NULL;
X }
X 
X /*
@@ -209,8 +204,6 @@
X 	struct buffer_head * bh;
X struct sysv_dir_entry * de;
X 
-	if (!dir)
-		return -ENOENT;
X inode = sysv_new_inode(dir);
X 	if (!inode) 
X 		return -ENOSPC;
@@ -239,8 +232,6 @@
X 	struct buffer_head * bh;
X struct sysv_dir_entry * de;
X 
-	if (!dir)
-		return -ENOENT;
X bh = sysv_find_entry(dir, dentry->d_name.name,
X 			     dentry->d_name.len, &de);
X 	if (bh) {
@@ -286,8 +277,6 @@
X 	struct buffer_head * bh, *dir_block;
X 	struct sysv_dir_entry * de;
X 
-	if (!dir)
-		return -EINVAL;
X 	bh = sysv_find_entry(dir, dentry->d_name.name,
X                               dentry->d_name.len, &de);
X 	if (bh) {
diff -u --recursive --new-file v2.2.6/linux/fs/ufs/dir.c linux/fs/ufs/dir.c
--- v2.2.6/linux/fs/ufs/dir.c	Tue Jan 19 11:32:52 1999
+++ linux/fs/ufs/dir.c	Fri Apr 23 21:20:38 1999
@@ -43,13 +43,6 @@
X 	int de_reclen;
X 	unsigned flags, swab;
X 
-
-	/* Isn't that already done in the upper layer???
-	 * the VFS layer really needs some explicit documentation!
-	 */
-	if (!inode || !S_ISDIR(inode->i_mode))
-		return -EBADF;
-
X 	sb = inode->i_sb;
X 	swab = sb->u.ufs_sb.s_swab;
X 	flags = sb->u.ufs_sb.s_flags;
diff -u --recursive --new-file v2.2.6/linux/fs/ufs/namei.c linux/fs/ufs/namei.c
--- v2.2.6/linux/fs/ufs/namei.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/ufs/namei.c	Fri Apr 23 21:20:38 1999
@@ -185,7 +185,7 @@
X 	return NULL;
X }
X 
-int ufs_lookup(struct inode * dir, struct dentry *dentry)
+struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry)
X {
X 	struct super_block * sb;
X 	struct inode * inode;
@@ -199,7 +199,7 @@
X 	swab = sb->u.ufs_sb.s_swab;
X 	
X 	if (dentry->d_name.len > UFS_MAXNAMLEN)
-		return -ENAMETOOLONG;
+		return ERR_PTR(-ENAMETOOLONG);
X 
X 	bh = ufs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de);
X 	inode = NULL;
@@ -208,11 +208,11 @@
X 		brelse (bh);
X 		inode = iget(sb, ino);
X 		if (!inode) 
-			return -EACCES;
+			return ERR_PTR(-EACCES);
X 	}
X 	d_add(dentry, inode);
X UFSD(("EXIT\n"))
-	return 0;
+	return NULL;
X }
X 
X /*
diff -u --recursive --new-file v2.2.6/linux/fs/umsdos/dir.c linux/fs/umsdos/dir.c
--- v2.2.6/linux/fs/umsdos/dir.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/umsdos/dir.c	Fri Apr 23 21:20:38 1999
@@ -210,8 +210,8 @@
X 		/*
X 		 * Do a real lookup on the short name.
X 		 */
-		dret = umsdos_lookup_dentry(filp->f_dentry, info.fake.fname,
-						 info.fake.len, 1);
+		dret = umsdos_covered(filp->f_dentry, info.fake.fname,
+						 info.fake.len);
X 		ret = PTR_ERR(dret);
X 		if (IS_ERR(dret))
X 			break;
@@ -459,7 +459,7 @@
X  * entry from the EMD file, and return ENOENT.
X  */
X 
-int umsdos_lookup_x (struct inode *dir, struct dentry *dentry, int nopseudo)
+struct dentry *umsdos_lookup_x (struct inode *dir, struct dentry *dentry, int nopseudo)
X {				
X 	struct dentry *dret = NULL;
X 	struct inode *inode;
@@ -500,8 +500,7 @@
X info.fake.len, info.fake.fname, info.f_pos, ret, info.fake.len));
X 
X 	/* do a real lookup to get the short name ... */
-	dret = umsdos_lookup_dentry(dentry->d_parent, info.fake.fname,
-					info.fake.len, 1);
+	dret = umsdos_covered(dentry->d_parent, info.fake.fname, info.fake.len);
X 	ret = PTR_ERR(dret);
X 	if (IS_ERR(dret)) {
X printk("umsdos_lookup_x: %s/%s real lookup failed, ret=%d\n", 
@@ -563,7 +562,7 @@
X 	dput(dret);
X out:
X 	umsdos_endlookup (dir);
-	return ret;
+	return ERR_PTR(ret);
X 
X out_remove:
X 	printk(KERN_WARNING "UMSDOS:  entry %s/%s out of sync, erased\n",
@@ -581,19 +580,19 @@
X  * Called by VFS; should fill dentry->d_inode via d_add.
X  */
X 
-int UMSDOS_lookup (struct inode *dir, struct dentry *dentry)
+struct dentry *UMSDOS_lookup (struct inode *dir, struct dentry *dentry)
X {
-	int ret;
+	struct dentry *ret;
X 
X 	ret = umsdos_lookup_x (dir, dentry, 0);
X 
X 	/* Create negative dentry if not found. */
-	if (ret == -ENOENT) {
+	if (ret == ERR_PTR(-ENOENT)) {
X 		Printk ((KERN_DEBUG 
X 			"UMSDOS_lookup: converting -ENOENT to negative\n"));
X 		d_add (dentry, NULL);
X 		dentry->d_op = &umsdos_dentry_operations;
-		ret = 0;
+		ret = NULL;
X 	}
X 	return ret;
X }
@@ -601,7 +600,6 @@
X struct dentry *umsdos_covered(struct dentry *parent, char *name, int len)
X {
X 	struct dentry *result, *dentry;
-	int error;
X 	struct qstr qstr;
X 
X 	qstr.name = name;
@@ -610,19 +608,18 @@
X 	result = ERR_PTR(-ENOMEM);
X 	dentry = d_alloc(parent, &qstr);
X 	if (dentry) {
-		result = dentry;
X 		/* XXXXXXXXXXXXXXXXXXX Race alert! */
-		error = UMSDOS_rlookup(parent->d_inode, result);
-		d_drop(result);
-		if (error)
+		result = UMSDOS_rlookup(parent->d_inode, dentry);
+		d_drop(dentry);
+		if (result)
X 			goto out_fail;
+		return dentry;
X 	}
X out:
X 	return result;
X 
X out_fail:
-	dput(result);
-	result = ERR_PTR(error);
+	dput(dentry);
X 	goto out;
X }
X 
@@ -636,7 +633,6 @@
X 					int real)
X {
X 	struct dentry *result, *dentry;
-	int error;
X 	struct qstr qstr;
X 
X 	qstr.name = name;
@@ -647,20 +643,19 @@
X 		result = ERR_PTR(-ENOMEM);
X 		dentry = d_alloc(parent, &qstr);
X 		if (dentry) {
-			result = dentry;
-			error = real ?
-				UMSDOS_rlookup(parent->d_inode, result) :
-				UMSDOS_lookup(parent->d_inode, result);
-			if (error)
+			result = real ?
+				UMSDOS_rlookup(parent->d_inode, dentry) :
+				UMSDOS_lookup(parent->d_inode, dentry);
+			if (result)
X 				goto out_fail;
+			return dentry;
X 		}
X 	}
X out:
X 	return result;
X 
X out_fail:
-	dput(result);
-	result = ERR_PTR(error);
+	dput(dentry);
X 	goto out;
X }
X 
diff -u --recursive --new-file v2.2.6/linux/fs/umsdos/namei.c linux/fs/umsdos/namei.c
--- v2.2.6/linux/fs/umsdos/namei.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/umsdos/namei.c	Fri Apr 23 21:20:38 1999
@@ -175,18 +175,6 @@
X 
X #endif
X 
-/*
- * Check whether we can delete from the directory.
- */
-static int is_sticky(struct inode *dir, int uid)
-{
-	return !((dir->i_mode & S_ISVTX) == 0 || 
-		current->fsuid == uid ||
-		current->fsuid == dir->i_uid ||
-		capable (CAP_FOWNER));
-}
-
-
X static int umsdos_nevercreat (struct inode *dir, struct dentry *dentry,
X 				int errcod)
X {
@@ -696,9 +684,8 @@
X olddentry->d_parent->d_name.name, olddentry->d_name.name, old_info.fake.fname));
X 
X 	/* Do a real lookup to get the short name dentry */
-	temp = umsdos_lookup_dentry(olddentry->d_parent,
-					old_info.fake.fname, 
-					old_info.fake.len, 1);
+	temp = umsdos_covered(olddentry->d_parent, old_info.fake.fname, 
+					old_info.fake.len);
X 	ret = PTR_ERR(temp);
X 	if (IS_ERR(temp))
X 		goto out_unlock;
@@ -784,16 +771,11 @@
X 		goto out;
X 
X 	/* lookup the short name dentry */
-	temp = umsdos_lookup_dentry(dentry->d_parent, info.fake.fname, 
-					info.fake.len, 1);
+	temp = umsdos_covered(dentry->d_parent, info.fake.fname, info.fake.len);
X 	ret = PTR_ERR(temp);
X 	if (IS_ERR(temp))
X 		goto out_remove;
X 
-	/* Keep the short name dentry anonymous */ 
-	if (temp != dentry)
-		d_drop(temp);
-
X 	/* Make sure the short name doesn't exist */
X 	ret = -EEXIST;
X 	if (temp->d_inode) {
@@ -812,16 +794,9 @@
X 	inode = temp->d_inode;
X 	down(&inode->i_sem);
X 
-	/*
-	 * Note! The long and short name might be the same,
-	 * so check first before doing the instantiate ...
-	 */
-	if (dentry != temp) {
-if (dentry->d_inode)
-printk("umsdos_mkdir: dentry not negative!\n");
-		inode->i_count++;
-		d_instantiate(dentry, inode);
-	}
+	inode->i_count++;
+	d_instantiate(dentry, inode);
+
X 	/* N.B. this should have an option to create the EMD ... */
X 	umsdos_lookup_patch_new(dentry, &info);
X 
@@ -921,21 +896,11 @@
X 	umsdos_parse (dentry->d_name.name, dentry->d_name.len, &info);
X 	/* Call findentry to complete the mangling */
X 	umsdos_findentry (dentry->d_parent, &info, 2);
-	temp = umsdos_lookup_dentry(dentry->d_parent, info.fake.fname, 
-					info.fake.len, 1);
+	temp = umsdos_covered(dentry->d_parent, info.fake.fname, info.fake.len);
X 	ret = PTR_ERR(temp);
X 	if (IS_ERR(temp))
X 		goto out;
X 	/*
-	 * If the short name is an alias, dput() it now;
-	 * otherwise d_drop() it to keep it anonymous.
-	 */
-	if (temp == dentry)
-		dput(temp);
-	else
-		d_drop(temp);
-
-	/*
X 	 * Attempt to remove the msdos name.
X 	 */
X 	ret = msdos_rmdir (dir, temp);
@@ -951,8 +916,7 @@
X 
X 	/* dput() temp if we didn't do it above */
X out_dput:
-	if (temp != dentry)
-		dput(temp);
+	dput(temp);
X 
X out:
X 	Printk (("umsdos_rmdir %d\n", ret));
@@ -999,14 +963,6 @@
X 
X Printk (("UMSDOS_unlink %.*s ", info.fake.len, info.fake.fname));
X 
-	ret = -EPERM;
-	/* check sticky bit */
-	if (is_sticky(dir, info.entry.uid)) {
-printk("umsdos_unlink: %s/%s is sticky\n",
-dentry->d_parent->d_name.name, dentry->d_name.name);
-		goto out_unlock;
-	}
-
X 	/*
X 	 * Note! If this is a hardlink and the names are aliased,
X 	 * the short-name lookup will return the hardlink dentry.
@@ -1018,8 +974,7 @@
X 	}
X 
X 	/* Do a real lookup to get the short name dentry */
-	temp = umsdos_lookup_dentry(dentry->d_parent, info.fake.fname, 
-					info.fake.len, 1);
+	temp = umsdos_covered(dentry->d_parent, info.fake.fname, info.fake.len);
X 	ret = PTR_ERR(temp);
X 	if (IS_ERR(temp))
X 		goto out_unlock;
@@ -1031,13 +986,6 @@
X 		link = umsdos_solve_hlink(dget(temp));
X 	}
X 
-	/*
-	 * If the short and long names are aliased,
-	 * dput() it now so the dentry isn't busy.
-	 */
-	if (temp == dentry)
-		dput(temp);
-
X 	/* Delete the EMD entry */
X 	ret = umsdos_delentry (dentry->d_parent, &info, 0);
X 	if (ret && ret != -ENOENT) {
@@ -1046,7 +994,7 @@
X 		goto out_dput;
X 	}
X 
-	ret = msdos_unlink_umsdos (dir, temp);
+	ret = msdos_unlink(dir, temp);
X #ifdef UMSDOS_PARANOIA
X if (ret)
X printk("umsdos_unlink: %s/%s unlink failed, ret=%d\n",
@@ -1055,12 +1003,9 @@
X 
X 	/* dput() temp if we didn't do it above */
X out_dput:
-	if (temp != dentry) {
-		d_drop(temp);
-		dput(temp);
-		if (!ret)
-			d_delete (dentry);
-	}
+	dput(temp);
+	if (!ret)
+		d_delete (dentry);
X 
X out_unlock:
X 	umsdos_unlockcreate (dir);
diff -u --recursive --new-file v2.2.6/linux/fs/umsdos/rdir.c linux/fs/umsdos/rdir.c
--- v2.2.6/linux/fs/umsdos/rdir.c	Wed Dec 16 10:32:56 1998
+++ linux/fs/umsdos/rdir.c	Fri Apr 23 21:20:38 1999
@@ -79,9 +79,9 @@
X  * In the real root directory (c:\), the directory ..
X  * is the pseudo root (c:\linux).
X  */
-int umsdos_rlookup_x ( struct inode *dir, struct dentry *dentry, int nopseudo)
+struct dentry *umsdos_rlookup_x ( struct inode *dir, struct dentry *dentry, int nopseudo)
X {
-	int ret;
+	struct dentry *ret;
X 
X 	if (saved_root && dir == saved_root->d_inode && !nopseudo &&
X 	    dentry->d_name.len == UMSDOS_PSDROOT_LEN &&
@@ -91,15 +91,16 @@
X 		 * /linux won't show
X 		 */
X 		 
-		ret = -ENOENT;
+		ret = ERR_PTR(-ENOENT);
X 		goto out;
X 	}
X 
X 	ret = msdos_lookup (dir, dentry);
X 	if (ret) {
X 		printk(KERN_WARNING
-			"umsdos_rlookup_x: %s/%s failed, ret=%d\n",
-			dentry->d_parent->d_name.name, dentry->d_name.name,ret);
+			"umsdos_rlookup_x: %s/%s failed, ret=%ld\n",
+			dentry->d_parent->d_name.name, dentry->d_name.name,
+			PTR_ERR(ret));
X 		goto out;
X 	}
X 	if (dentry->d_inode) {
@@ -119,7 +120,7 @@
X }
X 
X 
-int UMSDOS_rlookup ( struct inode *dir, struct dentry *dentry)
+struct dentry *UMSDOS_rlookup ( struct inode *dir, struct dentry *dentry)
X {
X 	return umsdos_rlookup_x (dir, dentry, 0);
X }
diff -u --recursive --new-file v2.2.6/linux/fs/vfat/namei.c linux/fs/vfat/namei.c
--- v2.2.6/linux/fs/vfat/namei.c	Fri Apr 16 14:47:31 1999
+++ linux/fs/vfat/namei.c	Fri Apr 23 21:20:38 1999
@@ -1140,11 +1140,30 @@
X 	return res;
X }
X 
-int vfat_lookup(struct inode *dir,struct dentry *dentry)
+/* Find a hashed dentry for inode; NULL if there are none */
+static struct dentry *find_alias(struct inode *inode)
+{
+	struct list_head *head, *next, *tmp;
+	struct dentry *alias;
+
+	head = &inode->i_dentry;
+	next = inode->i_dentry.next;
+	while (next != head) {
+		tmp = next;
+		next = tmp->next;
+		alias = list_entry(tmp, struct dentry, d_alias);
+		if (!list_empty(&alias->d_hash))
+			return dget(alias);
+	}
+	return NULL;
+}
+
+struct dentry *vfat_lookup(struct inode *dir,struct dentry *dentry)
X {
X 	int res;
X 	struct vfat_slot_info sinfo;
X 	struct inode *result;
+	struct dentry *alias;
X 	int table;
X 	
X 	PRINTK2(("vfat_lookup: name=%s, len=%d\n", 
@@ -1161,7 +1180,7 @@
X 	}
X 	PRINTK3(("vfat_lookup 4.5\n"));
X 	if (!(result = iget(dir->i_sb,sinfo.ino)))
-		return -EACCES;
+		return ERR_PTR(-EACCES);
X 	PRINTK3(("vfat_lookup 5\n"));
X 	if (MSDOS_I(result)->i_busy) { /* mkdir in progress */
X 		iput(result);
@@ -1169,6 +1188,15 @@
X 		table++;
X 		goto error;
X 	}
+	alias = find_alias(result);
+	if (alias) {
+		if (d_invalidate(alias)==0)
+			dput(alias);
+		else {
+			iput(result);
+			return alias;
+		}
+	}
X 	PRINTK3(("vfat_lookup 6\n"));
X error:
X 	dentry->d_op = &vfat_dentry_ops[table];
@@ -1397,28 +1425,6 @@
X 	return 0;
X }
X 
-/* Drop all aliases */
-static void drop_aliases(struct dentry *dentry)
-{
-	struct list_head *head, *next, *tmp;
-	struct dentry *alias;
-
-	PRINTK1(("drop_replace_inodes: dentry=%p, inode=%p\n", dentry, inode));
-	head = &dentry->d_inode->i_dentry;
-	if (dentry->d_inode) {
-		next = dentry->d_inode->i_dentry.next;
-		while (next != head) {
-			tmp = next;
-			next = tmp->next;
-			alias = list_entry(tmp, struct dentry, d_alias);
-			if (alias == dentry)
-				continue;
-
-			d_drop(alias);
-		}
-	}
-}
-
X static int vfat_rmdirx(struct inode *dir,struct dentry* dentry)
X {
X 	int res;
@@ -1430,12 +1436,6 @@
X 	if (res >= 0 && sinfo.total_slots > 0) {
X 		if (!list_empty(&dentry->d_hash))
X 			return -EBUSY;
-		/* Take care of aliases */
-		if (dentry->d_inode->i_count > 1) {
-			shrink_dcache_parent(dentry->d_parent);
-			if (dentry->d_inode->i_count > 1)
-				return -EBUSY;
-		}
X 		res = vfat_empty(dentry->d_inode);
X 		if (res)
X 			return res;
@@ -1535,10 +1535,8 @@
X 
X 	PRINTK1(("vfat_unlink: dentry=%p, inode=%p\n", dentry, dentry->d_inode));
X 	res = vfat_unlinkx (dir,dentry,1);
-	if (res >= 0) {
-		drop_aliases(dentry);
+	if (res >= 0)
X 		d_delete(dentry);
-	}
X 	return res;
X }
X 
@@ -1561,7 +1559,6 @@
X 	loff_t old_offset,new_offset,old_longname_offset;
X 	int old_slots,old_ino,new_ino,dotdot_ino;
X 	struct inode *old_inode, *new_inode, *dotdot_inode;
-	struct dentry *walk;
X 	int res, is_dir, i;
X 	int locked = 0;
X 	struct vfat_slot_info sinfo;
@@ -1589,16 +1586,6 @@
X 	old_inode = old_dentry->d_inode;
X 	is_dir = S_ISDIR(old_inode->i_mode);
X 
-	if (is_dir) {
-		/* We can't use is_subdir() here. Even now. Arrgh. */
-		for (walk=new_dentry;walk!=walk->d_parent;walk=walk->d_parent) {
-			if (walk->d_inode != old_dentry->d_inode)
-				continue;
-			res = -EINVAL;
-			goto rename_done;
-		}
-	}
-
X 	fat_lock_creation(); locked = 1;
X 
X 	if (new_dentry->d_inode) {
@@ -1620,25 +1607,9 @@
X 		}
X 
X 		if (is_dir) {
-			/*
-			 * Target is a directory. No other owners will
-			 * be tolerated.
-			 */
-			res = -EBUSY;
-			/*
-			 * OK, let's try to get rid of other dentries.
-			 * No need to do it if i_count is 1.
-			 */
-			if (new_inode->i_count>1) {
-				shrink_dcache_parent(new_dentry->d_parent);
-				if (new_inode->i_count>1)
-					goto rename_done;
-			}
X 			res = vfat_empty(new_inode);
X 			if (res)
X 				goto rename_done;
-		} else {
-			drop_aliases(new_dentry);
X 		}
X 		res = vfat_remove_entry(new_dir,&sinfo,new_inode);
X 		if (res)
diff -u --recursive --new-file v2.2.6/linux/include/asm-alpha/keyboard.h linux/include/asm-alpha/keyboard.h
--- v2.2.6/linux/include/asm-alpha/keyboard.h	Thu Jul 31 13:09:18 1997
+++ linux/include/asm-alpha/keyboard.h	Mon Apr 26 10:54:25 1999
@@ -18,7 +18,6 @@
X 
X extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
X extern int pckbd_getkeycode(unsigned int scancode);
-extern int pckbd_pretranslate(unsigned char scancode, char raw_mode);
X extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
X 			   char raw_mode);
X extern char pckbd_unexpected_up(unsigned char keycode);
@@ -28,7 +27,6 @@
X 
X #define kbd_setkeycode		pckbd_setkeycode
X #define kbd_getkeycode		pckbd_getkeycode
-#define kbd_pretranslate	pckbd_pretranslate
X #define kbd_translate		pckbd_translate
X #define kbd_unexpected_up	pckbd_unexpected_up
X #define kbd_leds		pckbd_leds
diff -u --recursive --new-file v2.2.6/linux/include/asm-alpha/semaphore.h linux/include/asm-alpha/semaphore.h
--- v2.2.6/linux/include/asm-alpha/semaphore.h	Fri Apr 16 14:47:31 1999
+++ linux/include/asm-alpha/semaphore.h	Sat Apr 24 17:54:08 1999
@@ -53,24 +53,31 @@
X 	   it's return address in $28.  The pv is loaded as usual.
X 	   The gp is clobbered (in the module case) as usual.  */
X 
+	/* This little bit of silliness is to get the GP loaded for
+	   a function that ordinarily wouldn't.  Otherwise we could
+	   have it done by the macro directly, which can be optimized
+	   the linker.  */
+	register void *pv __asm__("$27") = __down_failed;
+	
X 	__asm__ __volatile__ (
X 		"/* semaphore down operation */\n"
-		"1:	ldl_l	$27,%0\n"
-		"	subl	$27,1,$27\n"
-		"	mov	$27,$28\n"
-		"	stl_c	$28,%0\n"
+		"1:	ldl_l	$24,%1\n"
+		"	subl	$24,1,$24\n"
+		"	mov	$24,$28\n"
+		"	stl_c	$28,%1\n"
X 		"	beq	$28,2f\n"
-		"	blt	$27,3f\n"
+		"	blt	$24,3f\n"
X 		"4:	mb\n"
X 		".section .text2,\"ax\"\n"
X 		"2:	br	1b\n"
-		"3:	lda	$24,%0\n"
-		"	jsr	$28,__down_failed\n"
+		"3:	lda	$24,%1\n"
+		"	jsr	$28,($27),__down_failed\n"
X 		"	ldgp	$29,0($28)\n"
X 		"	br	4b\n"
X 		".previous"
-		: : "m"(sem->count)
-		: "$24", "$27", "$28", "memory");
+		: "=r"(pv)
+		: "m"(sem->count), "r"(pv)
+		: "$24", "$28", "memory");
X }
X 
X extern inline int down_interruptible(struct semaphore * sem)
@@ -81,27 +88,28 @@
X 	   value is in $24.  */
X 
X 	register int ret __asm__("$24");
+	register void *pv __asm__("$27") = __down_failed_interruptible;
X 
X 	__asm__ __volatile__ (
X 		"/* semaphore down interruptible operation */\n"
-		"1:	ldl_l	$27,%1\n"
-		"	subl	$27,1,$27\n"
-		"	mov	$27,$28\n"
-		"	stl_c	$28,%1\n"
+		"1:	ldl_l	$24,%2\n"
+		"	subl	$24,1,$24\n"
+		"	mov	$24,$28\n"
+		"	stl_c	$28,%2\n"
X 		"	beq	$28,2f\n"
-		"	blt	$27,3f\n"
+		"	blt	$24,3f\n"
X 		"	mov	$31,%0\n"
X 		"4:	mb\n"
X 		".section .text2,\"ax\"\n"
X 		"2:	br	1b\n"
-		"3:	lda	$24,%1\n"
-		"	jsr	$28,__down_failed_interruptible\n"
+		"3:	lda	$24,%2\n"
+		"	jsr	$28,($27),__down_failed_interruptible\n"
X 		"	ldgp	$29,0($28)\n"
X 		"	br	4b\n"
X 		".previous"
-		: "=r"(ret)
-		: "m"(sem->count)
-		: "$27", "$28", "memory");
+		: "=r"(ret), "=r"(pv)
+		: "m"(sem->count), "r"(pv)
+		: "$28", "memory");
X 
X 	return ret;
X }
@@ -171,26 +179,29 @@
X 	   it's return address in $28.  The pv is loaded as usual.
X 	   The gp is clobbered (in the module case) as usual.  */
X 
+	register void *pv __asm__("$27") = __up_wakeup;
+
X 	__asm__ __volatile__ (
X 		"/* semaphore up operation */\n"
X 		"	mb\n"
-		"1:	ldl_l	$27,%0\n"
-		"	addl	$27,1,$27\n"
-		"	mov	$27,$28\n"
-		"	stl_c	$28,%0\n"
+		"1:	ldl_l	$24,%1\n"
+		"	addl	$24,1,$24\n"
+		"	mov	$24,$28\n"
+		"	stl_c	$28,%1\n"
X 		"	beq	$28,2f\n"
X 		"	mb\n"
X 		"	ble	$27,3f\n"
X 		"4:\n"
X 		".section .text2,\"ax\"\n"
X 		"2:	br	1b\n"
-		"3:	lda	$24,%0\n"
-		"	jsr	$28,__up_wakeup\n"
+		"3:	lda	$24,%1\n"
+		"	jsr	$28,($27),__up_wakeup\n"
X 		"	ldgp	$29,0($28)\n"
X 		"	br	4b\n"
X 		".previous"
-		: : "m"(sem->count)
-		: "$24", "$27", "$28", "memory");
+		: "=r"(pv)
+		: "m"(sem->count), "r"(pv)
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 16'
echo 'File patch-2.2.7 is continued in part 17'
echo 17 > _shar_seq_.tmp
#!/bin/sh
# this is part 17 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 17; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
+		: "$24", "$28", "memory");
X }
X 
X #endif
diff -u --recursive --new-file v2.2.6/linux/include/asm-alpha/siginfo.h linux/include/asm-alpha/siginfo.h
--- v2.2.6/linux/include/asm-alpha/siginfo.h	Thu Aug 20 17:05:18 1998
+++ linux/include/asm-alpha/siginfo.h	Mon Apr 26 15:55:54 1999
@@ -138,7 +138,7 @@
X  */
X #define TRAP_BRKPT	1	/* process breakpoint */
X #define TRAP_TRACE	2	/* process trace trap */
-#define NSIGTRAP
+#define NSIGTRAP	2
X 
X /*
X  * SIGCHLD si_codes
diff -u --recursive --new-file v2.2.6/linux/include/asm-alpha/uaccess.h linux/include/asm-alpha/uaccess.h
--- v2.2.6/linux/include/asm-alpha/uaccess.h	Fri Apr 16 14:47:31 1999
+++ linux/include/asm-alpha/uaccess.h	Sat Apr 24 17:54:08 1999
@@ -160,7 +160,7 @@
X 		: "=r"(__gu_val), "=r"(__gu_err)	\
X 		: "m"(__m(addr)), "1"(__gu_err))
X 
-#ifdef __HAVE_CPU_BWX
+#ifdef __alpha_bwx__
X /* Those lucky bastards with ev56 and later CPUs can do byte/word moves.  */
X 
X #define __get_user_16(addr)				\
@@ -274,7 +274,7 @@
X 		: "=r"(__pu_err)				\
X 		: "m"(__m(addr)), "rJ"(x), "0"(__pu_err))
X 
-#ifdef __HAVE_CPU_BWX
+#ifdef __alpha_bwx__
X /* Those lucky bastards with ev56 and later CPUs can do byte/word moves.  */
X 
X #define __put_user_16(x,addr)					\
@@ -363,15 +363,21 @@
X extern inline long
X __copy_tofrom_user_nocheck(void *to, const void *from, long len)
X {
+	/* This little bit of silliness is to get the GP loaded for
+	   a function that ordinarily wouldn't.  Otherwise we could
+	   have it done by the macro directly, which can be optimized
+	   the linker.  */
+	register void * pv __asm__("$27") = __copy_user;
+
X 	register void * __cu_to __asm__("$6") = to;
X 	register const void * __cu_from __asm__("$7") = from;
X 	register long __cu_len __asm__("$0") = len;
X 
X 	__asm__ __volatile__(
-		"jsr $28,__copy_user"
-		: "=r" (__cu_len), "=r" (__cu_from), "=r" (__cu_to)
-		: "0" (__cu_len), "1" (__cu_from), "2" (__cu_to)
-		: "$1","$2","$3","$4","$5","$27","$28","memory");
+		"jsr $28,(%3),__copy_user\n\tldgp $29,0($28)"
+		: "=r" (__cu_len), "=r" (__cu_from), "=r" (__cu_to), "=r"(pv)
+		: "0" (__cu_len), "1" (__cu_from), "2" (__cu_to), "3"(pv)
+		: "$1","$2","$3","$4","$5","$28","memory");
X 
X 	return __cu_len;
X }
@@ -380,14 +386,17 @@
X __copy_tofrom_user(void *to, const void *from, long len, const void *validate)
X {
X 	if (__access_ok((long)validate, len, get_fs())) {
+		register void * pv __asm__("$27") = __copy_user;
X 		register void * __cu_to __asm__("$6") = to;
X 		register const void * __cu_from __asm__("$7") = from;
X 		register long __cu_len __asm__("$0") = len;
X 		__asm__ __volatile__(
-			"jsr $28,__copy_user"
-			: "=r" (__cu_len), "=r" (__cu_from), "=r" (__cu_to)
-			: "0" (__cu_len), "1" (__cu_from), "2" (__cu_to)
-			: "$1","$2","$3","$4","$5","$27","$28","memory");
+			"jsr $28,(%3),__copy_user\n\tldgp $29,0($28)"
+			: "=r"(__cu_len), "=r"(__cu_from), "=r"(__cu_to),
+			  "=r" (pv)
+			: "0" (__cu_len), "1" (__cu_from), "2" (__cu_to), 
+			  "3" (pv)
+			: "$1","$2","$3","$4","$5","$28","memory");
X 		len = __cu_len;
X 	}
X 	return len;
@@ -423,13 +432,19 @@
X extern inline long
X __clear_user(void *to, long len)
X {
+	/* This little bit of silliness is to get the GP loaded for
+	   a function that ordinarily wouldn't.  Otherwise we could
+	   have it done by the macro directly, which can be optimized
+	   the linker.  */
+	register void * pv __asm__("$27") = __do_clear_user;
+
X 	register void * __cl_to __asm__("$6") = to;
X 	register long __cl_len __asm__("$0") = len;
X 	__asm__ __volatile__(
-		"jsr $28,__do_clear_user"
-		: "=r"(__cl_len), "=r"(__cl_to)
-		: "0"(__cl_len), "1"(__cl_to)
-		: "$1","$2","$3","$4","$5","$27","$28","memory");
+		"jsr $28,(%2),__do_clear_user\n\tldgp $29,0($28)"
+		: "=r"(__cl_len), "=r"(__cl_to), "=r"(pv)
+		: "0"(__cl_len), "1"(__cl_to), "2"(pv)
+		: "$1","$2","$3","$4","$5","$28","memory");
X 	return __cl_len;
X }
X 
@@ -437,13 +452,14 @@
X clear_user(void *to, long len)
X {
X 	if (__access_ok((long)to, len, get_fs())) {
+		register void * pv __asm__("$27") = __do_clear_user;
X 		register void * __cl_to __asm__("$6") = to;
X 		register long __cl_len __asm__("$0") = len;
X 		__asm__ __volatile__(
-			"jsr $28,__do_clear_user"
-			: "=r"(__cl_len), "=r"(__cl_to)
-			: "0"(__cl_len), "1"(__cl_to)
-			: "$1","$2","$3","$4","$5","$27","$28","memory");
+			"jsr $28,(%2),__do_clear_user\n\tldgp $29,0($28)"
+			: "=r"(__cl_len), "=r"(__cl_to), "=r"(pv)
+			: "0"(__cl_len), "1"(__cl_to), "2"(pv)
+			: "$1","$2","$3","$4","$5","$28","memory");
X 		len = __cl_len;
X 	}
X 	return len;
diff -u --recursive --new-file v2.2.6/linux/include/asm-arm/arch-arc/keyboard.h linux/include/asm-arm/arch-arc/keyboard.h
--- v2.2.6/linux/include/asm-arm/arch-arc/keyboard.h	Tue Dec 22 14:16:57 1998
+++ linux/include/asm-arm/arch-arc/keyboard.h	Mon Apr 26 10:56:18 1999
@@ -19,11 +19,6 @@
X #define kbd_setkeycode(sc,kc)		(-EINVAL)
X #define kbd_getkeycode(sc)		(-EINVAL)
X 
-/* Prototype: int kbd_pretranslate(scancode, raw_mode)
- * Returns  : 0 to ignore scancode
- */
-#define kbd_pretranslate(sc,rm)	(1)
-
X /* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode)
X  * Returns  : 0 to ignore scancode, *keycode set to keycode, *up_flag
X  *            set to 0200 if scancode indicates release
diff -u --recursive --new-file v2.2.6/linux/include/asm-arm/arch-ebsa285/keyboard.h linux/include/asm-arm/arch-ebsa285/keyboard.h
--- v2.2.6/linux/include/asm-arm/arch-ebsa285/keyboard.h	Tue Dec 22 14:16:58 1998
+++ linux/include/asm-arm/arch-ebsa285/keyboard.h	Mon Apr 26 10:56:18 1999
@@ -19,7 +19,6 @@
X 
X extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
X extern int pckbd_getkeycode(unsigned int scancode);
-extern int pckbd_pretranslate(unsigned char scancode, char raw_mode);
X extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
X 			   char raw_mode);
X extern char pckbd_unexpected_up(unsigned char keycode);
@@ -29,7 +28,6 @@
X 
X #define kbd_setkeycode			pckbd_setkeycode
X #define kbd_getkeycode			pckbd_getkeycode
-#define kbd_pretranslate		pckbd_pretranslate
X #define kbd_translate(sc, kcp, ufp, rm) ({ *ufp = sc & 0200; \
X 		pckbd_translate(sc & 0x7f, kcp, rm);})
X 
@@ -49,11 +47,6 @@
X 
X #define kbd_setkeycode(sc,kc)		(-EINVAL)
X #define kbd_getkeycode(sc)		(-EINVAL)
-
-/* Prototype: int kbd_pretranslate(scancode, raw_mode)
- * Returns  : 0 to ignore scancode
- */
-#define kbd_pretranslate(sc,rm)		(1)
X 
X /* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode)
X  * Returns  : 0 to ignore scancode, *keycode set to keycode, *up_flag
diff -u --recursive --new-file v2.2.6/linux/include/asm-arm/arch-rpc/keyboard.h linux/include/asm-arm/arch-rpc/keyboard.h
--- v2.2.6/linux/include/asm-arm/arch-rpc/keyboard.h	Tue Dec 22 14:16:58 1998
+++ linux/include/asm-arm/arch-rpc/keyboard.h	Mon Apr 26 10:55:47 1999
@@ -10,7 +10,6 @@
X 
X #define NR_SCANCODES 128
X 
-extern int ps2kbd_pretranslate(unsigned char scancode);
X extern int ps2kbd_translate(unsigned char scancode, unsigned char *keycode_p, char *up_flag_p);
X extern void ps2kbd_leds(unsigned char leds);
X extern void ps2kbd_init_hw(void);
@@ -18,11 +17,6 @@
X 
X #define kbd_setkeycode(sc,kc)		(-EINVAL)
X #define kbd_getkeycode(sc)		(-EINVAL)
-
-/* Prototype: int kbd_pretranslate(scancode, raw_mode)
- * Returns  : 0 to ignore scancode
- */
-#define kbd_pretranslate(sc,rm)		ps2kbd_pretranslate(sc)
X 
X /* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode)
X  * Returns  : 0 to ignore scancode, *keycode set to keycode, *up_flag
diff -u --recursive --new-file v2.2.6/linux/include/asm-arm/arch-vnc/keyboard.h linux/include/asm-arm/arch-vnc/keyboard.h
--- v2.2.6/linux/include/asm-arm/arch-vnc/keyboard.h	Tue Dec 22 14:16:58 1998
+++ linux/include/asm-arm/arch-vnc/keyboard.h	Mon Apr 26 10:56:18 1999
@@ -14,7 +14,6 @@
X 
X extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
X extern int pckbd_getkeycode(unsigned int scancode);
-extern int pckbd_pretranslate(unsigned char scancode, char raw_mode);
X extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
X 			   char raw_mode);
X extern char pckbd_unexpected_up(unsigned char keycode);
@@ -24,7 +23,6 @@
X 
X #define kbd_setkeycode			pckbd_setkeycode
X #define kbd_getkeycode			pckbd_getkeycode
-#define kbd_pretranslate		pckbd_pretranslate
X #define kbd_translate(sc, kcp, ufp, rm) ({ *ufp = sc & 0200; \
X 		pckbd_translate(sc & 0x7f, kcp, rm);})
X 
diff -u --recursive --new-file v2.2.6/linux/include/asm-arm/siginfo.h linux/include/asm-arm/siginfo.h
--- v2.2.6/linux/include/asm-arm/siginfo.h	Thu Aug 20 17:05:18 1998
+++ linux/include/asm-arm/siginfo.h	Mon Apr 26 15:55:54 1999
@@ -138,7 +138,7 @@
X  */
X #define TRAP_BRKPT	1	/* process breakpoint */
X #define TRAP_TRACE	2	/* process trace trap */
-#define NSIGTRAP
+#define NSIGTRAP	2
X 
X /*
X  * SIGCHLD si_codes
diff -u --recursive --new-file v2.2.6/linux/include/asm-i386/bitops.h linux/include/asm-i386/bitops.h
--- v2.2.6/linux/include/asm-i386/bitops.h	Mon Dec 28 15:00:53 1998
+++ linux/include/asm-i386/bitops.h	Tue Apr 27 09:56:21 1999
@@ -46,7 +46,7 @@
X 	__asm__ __volatile__( LOCK_PREFIX
X 		"btsl %1,%0"
X 		:"=m" (ADDR)
-		:"ir" (nr));
+		:"Ir" (nr));
X }
X 
X extern __inline__ void clear_bit(int nr, volatile void * addr)
@@ -54,7 +54,7 @@
X 	__asm__ __volatile__( LOCK_PREFIX
X 		"btrl %1,%0"
X 		:"=m" (ADDR)
-		:"ir" (nr));
+		:"Ir" (nr));
X }
X 
X extern __inline__ void change_bit(int nr, volatile void * addr)
@@ -62,7 +62,7 @@
X 	__asm__ __volatile__( LOCK_PREFIX
X 		"btcl %1,%0"
X 		:"=m" (ADDR)
-		:"ir" (nr));
+		:"Ir" (nr));
X }
X 
X extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
@@ -72,7 +72,7 @@
X 	__asm__ __volatile__( LOCK_PREFIX
X 		"btsl %2,%1\n\tsbbl %0,%0"
X 		:"=r" (oldbit),"=m" (ADDR)
-		:"ir" (nr));
+		:"Ir" (nr));
X 	return oldbit;
X }
X 
@@ -83,7 +83,7 @@
X 	__asm__ __volatile__( LOCK_PREFIX
X 		"btrl %2,%1\n\tsbbl %0,%0"
X 		:"=r" (oldbit),"=m" (ADDR)
-		:"ir" (nr));
+		:"Ir" (nr));
X 	return oldbit;
X }
X 
@@ -94,7 +94,7 @@
X 	__asm__ __volatile__( LOCK_PREFIX
X 		"btcl %2,%1\n\tsbbl %0,%0"
X 		:"=r" (oldbit),"=m" (ADDR)
-		:"ir" (nr));
+		:"Ir" (nr));
X 	return oldbit;
X }
X 
@@ -113,7 +113,7 @@
X 	__asm__ __volatile__(
X 		"btl %2,%1\n\tsbbl %0,%0"
X 		:"=r" (oldbit)
-		:"m" (ADDR),"ir" (nr));
+		:"m" (ADDR),"Ir" (nr));
X 	return oldbit;
X }
X 
diff -u --recursive --new-file v2.2.6/linux/include/asm-i386/keyboard.h linux/include/asm-i386/keyboard.h
--- v2.2.6/linux/include/asm-i386/keyboard.h	Thu Jul 31 13:09:18 1997
+++ linux/include/asm-i386/keyboard.h	Mon Apr 26 10:54:03 1999
@@ -18,7 +18,6 @@
X 
X extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
X extern int pckbd_getkeycode(unsigned int scancode);
-extern int pckbd_pretranslate(unsigned char scancode, char raw_mode);
X extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
X 			   char raw_mode);
X extern char pckbd_unexpected_up(unsigned char keycode);
@@ -28,7 +27,6 @@
X 
X #define kbd_setkeycode		pckbd_setkeycode
X #define kbd_getkeycode		pckbd_getkeycode
-#define kbd_pretranslate	pckbd_pretranslate
X #define kbd_translate		pckbd_translate
X #define kbd_unexpected_up	pckbd_unexpected_up
X #define kbd_leds		pckbd_leds
diff -u --recursive --new-file v2.2.6/linux/include/asm-i386/siginfo.h linux/include/asm-i386/siginfo.h
--- v2.2.6/linux/include/asm-i386/siginfo.h	Thu Aug 20 17:05:18 1998
+++ linux/include/asm-i386/siginfo.h	Mon Apr 26 15:55:54 1999
@@ -138,7 +138,7 @@
X  */
X #define TRAP_BRKPT	1	/* process breakpoint */
X #define TRAP_TRACE	2	/* process trace trap */
-#define NSIGTRAP
+#define NSIGTRAP	2
X 
X /*
X  * SIGCHLD si_codes
diff -u --recursive --new-file v2.2.6/linux/include/asm-i386/string.h linux/include/asm-i386/string.h
--- v2.2.6/linux/include/asm-i386/string.h	Wed Jan 20 23:14:06 1999
+++ linux/include/asm-i386/string.h	Thu Apr 22 09:59:46 1999
@@ -462,7 +462,7 @@
X #define __HAVE_ARCH_MEMSET
X #define memset(s, c, count) \
X (__builtin_constant_p(c) ? \
- __constant_c_x_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \
+ __constant_c_x_memset((s),(0x01010101UL*(unsigned char)(c)),(count)) : \
X  __memset((s),(c),(count)))
X 
X /*
diff -u --recursive --new-file v2.2.6/linux/include/asm-m68k/keyboard.h linux/include/asm-m68k/keyboard.h
--- v2.2.6/linux/include/asm-m68k/keyboard.h	Wed Jan 20 23:14:06 1999
+++ linux/include/asm-m68k/keyboard.h	Mon Apr 26 10:53:51 1999
@@ -27,11 +27,6 @@
X     return scancode > 127 ? -EINVAL : scancode;
X }
X 
-static __inline__ int kbd_pretranslate(unsigned char scancode, char raw_mode)
-{
-    return 1;
-}
-
X static __inline__ int kbd_translate(unsigned char scancode,
X 				    unsigned char *keycode, char raw_mode)
X {
diff -u --recursive --new-file v2.2.6/linux/include/asm-mips/keyboard.h linux/include/asm-mips/keyboard.h
--- v2.2.6/linux/include/asm-mips/keyboard.h	Fri Oct 23 22:01:22 1998
+++ linux/include/asm-mips/keyboard.h	Mon Apr 26 10:54:13 1999
@@ -19,7 +19,6 @@
X 
X extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
X extern int pckbd_getkeycode(unsigned int scancode);
-extern int pckbd_pretranslate(unsigned char scancode, char raw_mode);
X extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
X 			   char raw_mode);
X extern char pckbd_unexpected_up(unsigned char keycode);
@@ -29,7 +28,6 @@
X 
X #define kbd_setkeycode		pckbd_setkeycode
X #define kbd_getkeycode		pckbd_getkeycode
-#define kbd_pretranslate	pckbd_pretranslate
X #define kbd_translate		pckbd_translate
X #define kbd_unexpected_up	pckbd_unexpected_up
X #define kbd_leds		pckbd_leds
diff -u --recursive --new-file v2.2.6/linux/include/asm-mips/siginfo.h linux/include/asm-mips/siginfo.h
--- v2.2.6/linux/include/asm-mips/siginfo.h	Fri Oct 23 22:01:23 1998
+++ linux/include/asm-mips/siginfo.h	Mon Apr 26 15:55:54 1999
@@ -146,7 +146,7 @@
X  */
X #define TRAP_BRKPT	1	/* process breakpoint */
X #define TRAP_TRACE	2	/* process trace trap */
-#define NSIGTRAP
+#define NSIGTRAP	2
X 
X /*
X  * SIGCHLD si_codes
diff -u --recursive --new-file v2.2.6/linux/include/asm-ppc/keyboard.h linux/include/asm-ppc/keyboard.h
--- v2.2.6/linux/include/asm-ppc/keyboard.h	Tue Mar 23 14:35:48 1999
+++ linux/include/asm-ppc/keyboard.h	Mon Apr 26 10:55:17 1999
@@ -28,7 +28,6 @@
X 
X extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
X extern int mackbd_getkeycode(unsigned int scancode);
-extern int mackbd_pretranslate(unsigned char scancode, char raw_mode);
X extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
X 			   char raw_mode);
X extern int mackbd_unexpected_up(unsigned char keycode);
@@ -37,7 +36,6 @@
X 
X extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
X extern int pckbd_getkeycode(unsigned int scancode);
-extern int pckbd_pretranslate(unsigned char scancode, char raw_mode);
X extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
X 			   char raw_mode);
X extern char pckbd_unexpected_up(unsigned char keycode);
@@ -82,23 +80,6 @@
X #endif
X 	else
X 		return mackbd_getkeycode(x);
-}
-
-static inline int kbd_pretranslate(unsigned char x,char y)
-{
-	if ( is_prep || (_machine == _MACH_mbx) )
-		return pckbd_pretranslate(x,y);
-	else if ( is_chrp )
-#ifndef CONFIG_MAC_KEYBOARD
-		return pckbd_pretranslate(x,y);
-#else
-		if ( adb_hardware == ADB_NONE )
-			return pckbd_pretranslate(x,y);
-		else
-			return mackbd_pretranslate(x,y);
-#endif
-	else
-		return mackbd_pretranslate(x,y);
X }
X 
X static inline int kbd_translate(unsigned char keycode, unsigned char *keycodep,
diff -u --recursive --new-file v2.2.6/linux/include/asm-ppc/siginfo.h linux/include/asm-ppc/siginfo.h
--- v2.2.6/linux/include/asm-ppc/siginfo.h	Thu Aug 20 17:05:18 1998
+++ linux/include/asm-ppc/siginfo.h	Mon Apr 26 15:55:54 1999
@@ -138,7 +138,7 @@
X  */
X #define TRAP_BRKPT	1	/* process breakpoint */
X #define TRAP_TRACE	2	/* process trace trap */
-#define NSIGTRAP
+#define NSIGTRAP	2
X 
X /*
X  * SIGCHLD si_codes
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/asmmacro.h linux/include/asm-sparc/asmmacro.h
--- v2.2.6/linux/include/asm-sparc/asmmacro.h	Thu Apr 23 20:21:38 1998
+++ linux/include/asm-sparc/asmmacro.h	Wed Apr 28 08:47:39 1999
@@ -26,7 +26,7 @@
X 
X #define GET_PROCESSOR_MID(reg, tmp) \
X 	rd	%tbr, %reg; \
-	sethi	C_LABEL(mid_xlate), %tmp; \
+	sethi	%hi(C_LABEL(mid_xlate)), %tmp; \
X 	srl	%reg, 12, %reg; \
X 	or	%tmp, %lo(C_LABEL(mid_xlate)), %tmp; \
X 	and	%reg, 3, %reg; \
@@ -34,7 +34,7 @@
X 
X #define GET_PROCESSOR_OFFSET(reg, tmp) \
X 	GET_PROCESSOR_ID(reg) \
-	sethi	C_LABEL(cpu_offset), %tmp; \
+	sethi	%hi(C_LABEL(cpu_offset)), %tmp; \
X 	sll	%reg, 2, %reg; \
X 	or	%tmp, %lo(C_LABEL(cpu_offset)), %tmp; \
X 	ld	[%tmp + %reg], %reg;
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/atomic.h linux/include/asm-sparc/atomic.h
--- v2.2.6/linux/include/asm-sparc/atomic.h	Tue Mar 23 14:35:48 1999
+++ linux/include/asm-sparc/atomic.h	Thu Apr 22 19:24:51 1999
@@ -41,13 +41,14 @@
X 
X static __inline__ int atomic_read(atomic_t *v)
X {
-	int val;
+	int ret = v->counter;
X 
-	__asm__ __volatile__("sra	%1, 0x8, %0"
-			     : "=r" (val)
-			     : "r" (v->counter));
-	return val;
+	while(ret & 0xff)
+		ret = v->counter;
+
+	return ret >> 8;
X }
+
X #define atomic_set(v, i)	(((v)->counter) = ((i) << 8))
X #endif
X 
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/floppy.h linux/include/asm-sparc/floppy.h
--- v2.2.6/linux/include/asm-sparc/floppy.h	Tue Mar 23 14:35:48 1999
+++ linux/include/asm-sparc/floppy.h	Thu Apr 22 19:24:51 1999
@@ -15,6 +15,14 @@
X #include <asm/auxio.h>
X #include <asm/irq.h>
X 
+/* We don't need no stinkin' I/O port allocation crap. */
+#undef release_region
+#undef check_region
+#undef request_region
+#define release_region(X, Y)	do { } while(0)
+#define check_region(X, Y)	(0)
+#define request_region(X, Y, Z)	do { } while(0)
+
X /* References:
X  * 1) Netbsd Sun floppy driver.
X  * 2) NCR 82077 controller manual
@@ -320,8 +328,7 @@
X 								"floppy",
X 								fd_regs[0].which_io,
X 								0x0);
-	release_region((long)sun_fdc & PAGE_MASK, 
-		       (((long)sun_fdc & ~PAGE_MASK) + fd_regs[0].reg_size + PAGE_SIZE - 1) & PAGE_MASK);
+
X 	/* Last minute sanity check... */
X 	if(sun_fdc->status_82072 == 0xff) {
X 		sun_fdc = NULL;
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/hardirq.h linux/include/asm-sparc/hardirq.h
--- v2.2.6/linux/include/asm-sparc/hardirq.h	Sun Nov  8 14:03:09 1998
+++ linux/include/asm-sparc/hardirq.h	Thu Apr 22 19:24:51 1999
@@ -1,7 +1,7 @@
X /* hardirq.h: 32-bit Sparc hard IRQ support.
X  *
X  * Copyright (C) 1997 David S. Miller (da...@caip.rutgers.edu)
- * Copyright (C) 1998 Anton Blanchard (an...@progsoc.uts.edu.au)
+ * Copyright (C) 1998-99 Anton Blanchard (an...@progsoc.uts.edu.au)
X  */
X 
X #ifndef __SPARC_HARDIRQ_H
@@ -9,22 +9,20 @@
X 
X #include <linux/tasks.h>
X 
-extern unsigned int local_irq_count[NR_CPUS];
+#ifndef __SMP__
+extern unsigned int local_irq_count;
X 
X /*
X  * Are we in an interrupt context? Either doing bottom half
X  * or hardware interrupt processing?
X  */
-#define in_interrupt() ({ int __cpu = smp_processor_id(); \
-	(local_irq_count[__cpu] + local_bh_count[__cpu] != 0); })
+#define in_interrupt()  ((local_irq_count + local_bh_count) != 0)
X 
-#ifndef __SMP__
-
-#define hardirq_trylock(cpu)	(local_irq_count[cpu] == 0)
+#define hardirq_trylock(cpu)	(local_irq_count == 0)
X #define hardirq_endlock(cpu)	do { } while (0)
X 
-#define hardirq_enter(cpu)	(local_irq_count[cpu]++)
-#define hardirq_exit(cpu)	(local_irq_count[cpu]--)
+#define hardirq_enter(cpu)	(local_irq_count++)
+#define hardirq_exit(cpu)	(local_irq_count--)
X 
X #define synchronize_irq()	barrier()
X 
@@ -35,10 +33,18 @@
X #include <asm/system.h>
X #include <asm/smp.h>
X 
+extern unsigned int local_irq_count[NR_CPUS];
X extern unsigned char global_irq_holder;
X extern spinlock_t global_irq_lock;
X extern atomic_t global_irq_count;
X 
+/*
+ * Are we in an interrupt context? Either doing bottom half
+ * or hardware interrupt processing?
+ */
+#define in_interrupt() ({ int __cpu = smp_processor_id(); \
+	(local_irq_count[__cpu] + local_bh_count[__cpu] != 0); })
+
X static inline void release_irqlock(int cpu)
X {
X 	/* if we didn't own the irq lock, just ignore.. */
@@ -62,7 +68,8 @@
X 
X static inline int hardirq_trylock(int cpu)
X {
-	return !atomic_read(&global_irq_count) && !*(((volatile unsigned char *)(&global_irq_lock)));
+	return (! atomic_read(&global_irq_count) &&
+		! spin_is_locked (&global_irq_lock));
X }
X 
X #define hardirq_endlock(cpu)	do { } while (0)
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/head.h linux/include/asm-sparc/head.h
--- v2.2.6/linux/include/asm-sparc/head.h	Thu Apr 23 20:21:38 1998
+++ linux/include/asm-sparc/head.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: head.h,v 1.35 1998/03/18 09:15:40 jj Exp $ */
+/* $Id: head.h,v 1.36 1999/04/20 13:22:42 anton Exp $ */
X #ifndef __SPARC_HEAD_H
X #define __SPARC_HEAD_H
X 
@@ -7,8 +7,6 @@
X #define SUN4C_SEGSZ     (1 << 18)
X #define SRMMU_L1_KBASE_OFFSET ((KERNBASE>>24)<<2)  /* Used in boot remapping. */
X #define INTS_ENAB        0x01           /* entry.S uses this. */
-
-#define NCPUS            4              /* Architectural limit of sun4m. */
X 
X #define SUN4_PROM_VECTOR 0xFFE81000     /* SUN4 PROM needs to be hardwired */
X 
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/irq.h linux/include/asm-sparc/irq.h
--- v2.2.6/linux/include/asm-sparc/irq.h	Thu Aug  6 14:06:34 1998
+++ linux/include/asm-sparc/irq.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: irq.h,v 1.25 1998/06/04 09:55:04 jj Exp $
+/* $Id: irq.h,v 1.26 1999/04/20 13:22:44 anton Exp $
X  * irq.h: IRQ registers on the Sparc.
X  *
X  * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -8,8 +8,9 @@
X #define _SPARC_IRQ_H
X 
X #include <linux/linkage.h>
+#include <linux/tasks.h>     /* For NR_CPUS */
X 
-#include <asm/system.h>     /* For NCPUS */
+#include <asm/system.h>     /* For SUN4M_NCPUS */
X #include <asm/btfixup.h>
X 
X #define __irq_ino(irq) irq
@@ -19,46 +20,18 @@
X 
X #define NR_IRQS    15
X 
-/* Get rid of this when lockups have gone away. -DaveM */
-#ifndef DEBUG_IRQLOCK
-#define DEBUG_IRQLOCK
-#endif
-
X /* IRQ handler dispatch entry and exit. */
X #ifdef __SMP__
-#ifdef DEBUG_IRQLOCK
-extern void irq_enter(int cpu, int irq, void *regs);
-extern void irq_exit(int cpu, int irq);
-#else
-extern __inline__ void irq_enter(int cpu, int irq, void *regs)
-{
-	register int proc asm("g1");
-	proc = cpu;
-	__asm__ __volatile__("
-	mov	%%o7, %%g4
-	call	___irq_enter
-	 add	%%o7, 8, %%o7
-"	: "=&r" (proc)
-	: "0" (proc)
-	: "g2", "g3", "g4", "g5", "memory", "cc");
-}
-
-extern __inline__ void irq_exit(int cpu, int irq)
-{
-	register int proc asm("g7");
-	proc = cpu;
-	__asm__ __volatile__("
-	mov	%%o7, %%g4
-	call	___irq_exit
-	 add	%%o7, 8, %%o7
-"	: "=&r" (proc)
-	: "0" (proc)
-	: "g1", "g2", "g3", "g4", "g5", "memory", "cc");
-}
-#endif /* DEBUG_IRQLOCK */
+extern unsigned int local_irq_count[NR_CPUS];
+#define irq_enter(cpu, irq)                     \
+do {    hardirq_enter(cpu);                     \
+        spin_unlock_wait(&global_irq_lock);     \
+	} while(0)
+#define irq_exit(cpu, irq)      hardirq_exit(cpu)
X #else
-#define irq_enter(cpu, irq, regs)	(local_irq_count[cpu]++)
-#define irq_exit(cpu, irq)		(local_irq_count[cpu]--)
+extern unsigned int local_irq_count;
+#define irq_enter(cpu, irq)     (local_irq_count++)
+#define irq_exit(cpu, irq)      (local_irq_count--)
X #endif
X 
X /* Dave Redman (dj...@tadpole.co.uk)
@@ -133,7 +106,7 @@
X  *             sun4m machines, for MP the layout makes more sense.
X  */
X struct sun4m_intregs {
-	struct sun4m_intreg_percpu cpu_intregs[NCPUS];
+	struct sun4m_intreg_percpu cpu_intregs[SUN4M_NCPUS];
X 	unsigned int tbt;                /* IRQ's that are still pending. */
X 	unsigned int irqs;               /* Master IRQ bits. */
X 
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/keyboard.h linux/include/asm-sparc/keyboard.h
--- v2.2.6/linux/include/asm-sparc/keyboard.h	Mon Oct  5 13:13:43 1998
+++ linux/include/asm-sparc/keyboard.h	Wed Apr 28 08:47:39 1999
@@ -1,4 +1,4 @@
-/* $Id: keyboard.h,v 1.1 1998/09/22 05:54:42 jj Exp $
+/* $Id: keyboard.h,v 1.2 1999/04/28 11:59:07 davem Exp $
X  * linux/include/asm-sparc/keyboard.h
X  *
X  * sparc64 Created Aug 29 1997 by Eddie C. Dost (e...@skynet.be)
@@ -18,7 +18,6 @@
X 
X extern int pcikbd_setkeycode(unsigned int scancode, unsigned int keycode);
X extern int pcikbd_getkeycode(unsigned int scancode);
-extern int pcikbd_pretranslate(unsigned char scancode, char raw_mode);
X extern int pcikbd_translate(unsigned char scancode, unsigned char *keycode,
X 			    char raw_mode);
X extern char pcikbd_unexpected_up(unsigned char keycode);
@@ -28,7 +27,6 @@
X 
X #define kbd_setkeycode			pcikbd_setkeycode
X #define kbd_getkeycode			pcikbd_getkeycode
-#define kbd_pretranslate		pcikbd_pretranslate
X #define kbd_translate			pcikbd_translate
X #define kbd_unexpected_up		pcikbd_unexpected_up
X #define kbd_leds			pcikbd_leds
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/namei.h linux/include/asm-sparc/namei.h
--- v2.2.6/linux/include/asm-sparc/namei.h	Thu Nov 19 09:56:29 1998
+++ linux/include/asm-sparc/namei.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: namei.h,v 1.12 1998/10/28 08:13:42 jj Exp $
+/* $Id: namei.h,v 1.13 1999/04/06 06:54:36 jj Exp $
X  * linux/include/asm-sparc/namei.h
X  *
X  * Routines to handle famous /usr/gnemul/s*.
@@ -18,11 +18,8 @@
X 	char *emul;
X 
X 	switch (current->personality) {
-#if 0
-/* Until we solve, why SunOS apps sometime crash, disable gnemul support for SunOS */
X 	case PER_BSD:
X 		emul = SPARC_BSD_EMUL; break;
-#endif
X 	case PER_SVR4:
X 		emul = SPARC_SOL_EMUL; break;
X 	default:
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/siginfo.h linux/include/asm-sparc/siginfo.h
--- v2.2.6/linux/include/asm-sparc/siginfo.h	Mon Oct  5 13:13:43 1998
+++ linux/include/asm-sparc/siginfo.h	Mon Apr 26 15:55:54 1999
@@ -142,7 +142,7 @@
X  */
X #define TRAP_BRKPT	1	/* process breakpoint */
X #define TRAP_TRACE	2	/* process trace trap */
-#define NSIGTRAP
+#define NSIGTRAP	2
X 
X /*
X  * SIGCHLD si_codes
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/softirq.h linux/include/asm-sparc/softirq.h
--- v2.2.6/linux/include/asm-sparc/softirq.h	Tue Mar 23 14:35:48 1999
+++ linux/include/asm-sparc/softirq.h	Thu Apr 22 19:24:52 1999
@@ -1,21 +1,23 @@
X /* softirq.h: 32-bit Sparc soft IRQ support.
X  *
X  * Copyright (C) 1997 David S. Miller (da...@caip.rutgers.edu)
- * Copyright (C) 1998 Anton Blanchard (an...@progsoc.uts.edu.au)
+ * Copyright (C) 1998-99 Anton Blanchard (an...@progsoc.uts.edu.au)
X  */
X 
X #ifndef __SPARC_SOFTIRQ_H
X #define __SPARC_SOFTIRQ_H
X 
+#include <linux/tasks.h>	/* For NR_CPUS */
+
X #include <asm/atomic.h>
X #include <asm/smp.h>
X #include <asm/hardirq.h>
X 
-extern unsigned int local_bh_count[NR_CPUS];
X 
X #define get_active_bhs()	(bh_mask & bh_active)
X 
X #ifdef __SMP__
+extern unsigned int local_bh_count[NR_CPUS];
X 
X /*
X  * The locking mechanism for base handlers, to prevent re-entrancy,
@@ -23,7 +25,7 @@
X  * referenced at all outside of this file.
X  */
X extern atomic_t global_bh_lock;
-extern atomic_t global_bh_count;
+extern spinlock_t global_bh_count;
X extern spinlock_t sparc_bh_lock;
X 
X extern void synchronize_bh(void);
@@ -100,30 +102,31 @@
X /* These are for the IRQs testing the lock */
X static inline int softirq_trylock(int cpu)
X {
-	if (atomic_add_return(1, &global_bh_count) == 1) {
+	if (spin_trylock(&global_bh_count)) {
X 		if (atomic_read(&global_bh_lock) == 0) {
X 			++local_bh_count[cpu];
X 			return 1;
X 		}
+		spin_unlock(&global_bh_count);
X 	}
-	atomic_dec(&global_bh_count);
X 	return 0;
X }
X 
X static inline void softirq_endlock(int cpu)
X {
X 	local_bh_count[cpu]--;
-	atomic_dec(&global_bh_count);
+	spin_unlock(&global_bh_count);
X }
X 
X #else
+extern unsigned int local_bh_count;
X 
X #define clear_active_bhs(x)	(bh_active &= ~(x))
X #define mark_bh(nr)		(bh_active |= (1 << (nr)))
X 
X /* These are for the irq's testing the lock */
-#define softirq_trylock(cpu)	(local_bh_count[cpu] ? 0 : (local_bh_count[cpu]=1))
-#define softirq_endlock(cpu)	(local_bh_count[cpu] = 0)
+#define softirq_trylock(cpu)	(local_bh_count ? 0 : (local_bh_count=1))
+#define softirq_endlock(cpu)	(local_bh_count = 0)
X #define synchronize_bh()	barrier()
X 
X /*
@@ -153,19 +156,20 @@
X extern inline void remove_bh(int nr)
X {
X 	bh_mask &= ~(1 << nr);
+	mb();
X 	bh_base[nr] = NULL;
X }
X 
X extern inline void start_bh_atomic(void)
X {
-	local_bh_count[0]++;
+	local_bh_count++;
X 	barrier();
X }
X 
X extern inline void end_bh_atomic(void)
X {
X 	barrier();
-	local_bh_count[0]--;
+	local_bh_count--;
X }
X 
X #endif	/* SMP */
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/spinlock.h linux/include/asm-sparc/spinlock.h
--- v2.2.6/linux/include/asm-sparc/spinlock.h	Tue Mar 23 14:35:48 1999
+++ linux/include/asm-sparc/spinlock.h	Thu Apr 22 19:24:52 1999
@@ -6,6 +6,8 @@
X #ifndef __SPARC_SPINLOCK_H
X #define __SPARC_SPINLOCK_H
X 
+#include <linux/tasks.h>	/* For NR_CPUS */
+
X #ifndef __ASSEMBLY__
X 
X #ifndef __SMP__
@@ -67,6 +69,7 @@
X 
X #define SPIN_LOCK_UNLOCKED	(spinlock_t) { 0, 0 }
X #define spin_lock_init(lp)	do { (lp)->owner_pc = 0; (lp)->lock = 0; } while(0)
+#define spin_is_locked(lp)  (*((volatile unsigned char *)(&((lp)->lock))) != 0)
X #define spin_unlock_wait(lp)	do { barrier(); } while(*(volatile unsigned char *)(&(lp)->lock))
X 
X extern void _do_spin_lock(spinlock_t *lock, char *str);
@@ -86,7 +89,7 @@
X struct _rwlock_debug {
X 	volatile unsigned int lock;
X 	unsigned long owner_pc;
-	unsigned long reader_pc[NCPUS];
+	unsigned long reader_pc[NR_CPUS];
X };
X typedef struct _rwlock_debug rwlock_t;
X 
@@ -139,7 +142,8 @@
X #define SPIN_LOCK_UNLOCKED	0
X 
X #define spin_lock_init(lock)	(*(lock) = 0)
-#define spin_unlock_wait(lock)	do { barrier(); } while(*(volatile spinlock_t *)lock)
+#define spin_is_locked(lock)    (*((volatile unsigned char *)(lock)) != 0)
+#define spin_unlock_wait(lock)	do { barrier(); } while(*(volatile unsigned char *)lock)
X 
X extern __inline__ void spin_lock(spinlock_t *lock)
X {
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/system.h linux/include/asm-sparc/system.h
--- v2.2.6/linux/include/asm-sparc/system.h	Tue Mar 23 14:35:48 1999
+++ linux/include/asm-sparc/system.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: system.h,v 1.72 1999/01/02 16:50:21 davem Exp $ */
+/* $Id: system.h,v 1.73 1999/04/20 13:22:49 anton Exp $ */
X #include <linux/config.h>
X 
X #ifndef __SPARC_SYSTEM_H
@@ -47,6 +47,8 @@
X #define ARCH_SUN4C_SUN4 1
X #define ARCH_SUN4 1
X #endif
+
+#define SUN4M_NCPUS            4              /* Architectural limit of sun4m. */
X 
X extern unsigned long empty_bad_page;
X extern unsigned long empty_bad_page_table;
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/timer.h linux/include/asm-sparc/timer.h
--- v2.2.6/linux/include/asm-sparc/timer.h	Mon Oct  5 13:13:43 1998
+++ linux/include/asm-sparc/timer.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: timer.h,v 1.20 1998/09/21 05:07:37 jj Exp $
+/* $Id: timer.h,v 1.21 1999/04/20 13:22:51 anton Exp $
X  * timer.h:  Definitions for the timer chips on the Sparc.
X  *
X  * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -9,7 +9,7 @@
X #ifndef _SPARC_TIMER_H
X #define _SPARC_TIMER_H
X 
-#include <asm/system.h>  /* For NCPUS */
+#include <asm/system.h>  /* For SUN4M_NCPUS */
X #include <asm/sun4paddr.h>
X #include <asm/btfixup.h>
X 
@@ -70,7 +70,7 @@
X };
X 
X struct sun4m_timer_regs {
-	struct sun4m_timer_percpu_info cpu_timers[NCPUS];
+	struct sun4m_timer_percpu_info cpu_timers[SUN4M_NCPUS];
X 	volatile unsigned int l10_timer_limit;
X 	volatile unsigned int l10_cur_count;
X 
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/uaccess.h linux/include/asm-sparc/uaccess.h
--- v2.2.6/linux/include/asm-sparc/uaccess.h	Mon Oct  5 13:13:43 1998
+++ linux/include/asm-sparc/uaccess.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: uaccess.h,v 1.17 1998/09/16 12:25:29 jj Exp $
+/* $Id: uaccess.h,v 1.18 1999/03/30 06:38:38 jj Exp $
X  * uaccess.h: User space memore access functions.
X  *
X  * Copyright (C) 1996 David S. Miller (da...@caip.rutgers.edu)
@@ -349,9 +349,8 @@
X 	.align 4
X 	.word 1f,3
X 	.previous
-1:
X 	mov %2, %%o1
-	call __bzero
+1:	call __bzero
X 	 mov %1, %%o0
X 	mov %%o0, %0 
X 	" : "=r" (ret) : "r" (addr), "r" (size) :
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/unistd.h linux/include/asm-sparc/unistd.h
--- v2.2.6/linux/include/asm-sparc/unistd.h	Mon Mar 29 11:09:12 1999
+++ linux/include/asm-sparc/unistd.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.54 1999/03/25 00:40:12 davem Exp $ */
+/* $Id: unistd.h,v 1.55 1999/04/07 17:14:15 davem Exp $ */
X #ifndef _SPARC_UNISTD_H
X #define _SPARC_UNISTD_H
X 
@@ -60,7 +60,7 @@
X #define __NR_pipe                42 /* Common                                      */
X #define __NR_times               43 /* Implemented via getrusage() in SunOS        */
X /* #define __NR_profil           44    Common                                      */
-/* #define __NR_ni_syscall       45    ENOSYS under SunOS                          */
+#define __NR_umount2             45 /* Linux Specific                              */
X #define __NR_setgid              46 /* Implemented via setregid() in SunOS         */
X #define __NR_getgid              47 /* Common                                      */
X #define __NR_signal              48 /* Implemented via sigvec() in SunOS           */
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc/vaddrs.h linux/include/asm-sparc/vaddrs.h
--- v2.2.6/linux/include/asm-sparc/vaddrs.h	Sat Nov  9 00:30:26 1996
+++ linux/include/asm-sparc/vaddrs.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: vaddrs.h,v 1.21 1996/10/07 03:03:02 davem Exp $ */
+/* $Id: vaddrs.h,v 1.22 1999/04/20 13:22:55 anton Exp $ */
X #ifndef _SPARC_VADDRS_H
X #define _SPARC_VADDRS_H
X 
@@ -51,7 +51,7 @@
X /* On sun4m machines we need per-cpu virtual areas */
X #define  PERCPU_VADDR   0xffc00000  /* Base for per-cpu virtual mappings */
X #define  PERCPU_ENTSIZE 0x00100000
-#define  PERCPU_LEN     ((PERCPU_ENTSIZE*NCPUS))
+#define  PERCPU_LEN     ((PERCPU_ENTSIZE*SUN4M_NCPUS))
X 
X /* per-cpu offsets */
X #define  PERCPU_TBR_OFFSET      0x00000      /* %tbr, mainly used for identification. */
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc64/ide.h linux/include/asm-sparc64/ide.h
--- v2.2.6/linux/include/asm-sparc64/ide.h	Mon Oct  5 13:13:44 1998
+++ linux/include/asm-sparc64/ide.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: ide.h,v 1.11 1998/08/12 22:19:37 ecd Exp $
+/* $Id: ide.h,v 1.12 1999/04/17 14:25:29 davem Exp $
X  * ide.h: Ultra/PCI specific IDE glue.
X  *
X  * Copyright (C) 1997  David S. Miller (da...@caip.rutgers.edu)
@@ -123,7 +123,7 @@
X 				unsigned long count)
X {
X 	volatile unsigned short *data_port;
-	unsigned long end = (unsigned long)dst + count;
+	unsigned long end = (unsigned long)dst + (count << 1);
X 	u16 *ps = dst;
X 	u32 *pi;
X 
@@ -154,7 +154,7 @@
X 				 unsigned long count)
X {
X 	volatile unsigned short *data_port;
-	unsigned long end = (unsigned long)src + count;
+	unsigned long end = (unsigned long)src + (count << 1);
X 	const u16 *ps = src;
X 	const u32 *pi;
X 
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc64/keyboard.h linux/include/asm-sparc64/keyboard.h
--- v2.2.6/linux/include/asm-sparc64/keyboard.h	Mon Jan 12 15:15:58 1998
+++ linux/include/asm-sparc64/keyboard.h	Wed Apr 28 08:47:39 1999
@@ -1,4 +1,4 @@
-/* $Id: keyboard.h,v 1.2 1997/09/07 15:40:49 ecd Exp $
+/* $Id: keyboard.h,v 1.3 1999/04/28 11:59:12 davem Exp $
X  * linux/include/asm-sparc64/keyboard.h
X  *
X  * Created Aug 29 1997 by Eddie C. Dost (e...@skynet.be)
@@ -18,7 +18,6 @@
X 
X extern int pcikbd_setkeycode(unsigned int scancode, unsigned int keycode);
X extern int pcikbd_getkeycode(unsigned int scancode);
-extern int pcikbd_pretranslate(unsigned char scancode, char raw_mode);
X extern int pcikbd_translate(unsigned char scancode, unsigned char *keycode,
X 			    char raw_mode);
X extern char pcikbd_unexpected_up(unsigned char keycode);
@@ -28,7 +27,6 @@
X 
X #define kbd_setkeycode			pcikbd_setkeycode
X #define kbd_getkeycode			pcikbd_getkeycode
-#define kbd_pretranslate		pcikbd_pretranslate
X #define kbd_translate			pcikbd_translate
X #define kbd_unexpected_up		pcikbd_unexpected_up
X #define kbd_leds			pcikbd_leds
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc64/namei.h linux/include/asm-sparc64/namei.h
--- v2.2.6/linux/include/asm-sparc64/namei.h	Thu Nov 19 09:56:29 1998
+++ linux/include/asm-sparc64/namei.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: namei.h,v 1.13 1998/10/28 08:13:49 jj Exp $
+/* $Id: namei.h,v 1.14 1999/04/06 06:54:39 jj Exp $
X  * linux/include/asm-sparc64/namei.h
X  *
X  * Routines to handle famous /usr/gnemul/s*.
@@ -18,11 +18,8 @@
X 	char *emul;
X 
X 	switch (current->personality) {
-#if 0
-/* Until we solve, why SunOS apps sometime crash, disable gnemul support for SunOS */
X 	case PER_BSD:
X 		emul = SPARC_BSD_EMUL; break;
-#endif		
X 	case PER_SVR4:
X 		emul = SPARC_SOL_EMUL; break;
X 	default:
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc64/psycho.h linux/include/asm-sparc64/psycho.h
--- v2.2.6/linux/include/asm-sparc64/psycho.h	Tue Mar 23 14:35:48 1999
+++ linux/include/asm-sparc64/psycho.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: psycho.h,v 1.4 1998/12/23 10:08:16 davem Exp $
+/* $Id: psycho.h,v 1.5 1999/04/01 12:27:28 davem Exp $
X  * psycho.h: UltraSparc AX specific PCI definitions.
X  *
X  * Copyright (C) 1997 Eddie C. Dost (e...@skynet.be)
@@ -257,7 +257,7 @@
X #define PSYCHO_CEAFSR_SDWR	0x0400000000000000 /* Secondary DVMA write is cause*/
X #define PSYCHO_CEAFSR_RESV1	0x0300000000000000 /* Reserved                     */
X #define PSYCHO_CEAFSR_ESYND	0x00ff000000000000 /* Syndrome Bits                */
-#define PSYCHO_UEAFSR_SIZE	0x0000ffff00000000 /* Bytemask of failed transfer  */
+#define PSYCHO_CEAFSR_SIZE	0x0000ffff00000000 /* Bytemask of failed transfer  */
X #define PSYCHO_CEAFSR_DOFF	0x00000000e0000000 /* Double Offset                */
X #define PSYCHO_CEAFSR_MID	0x000000001f000000 /* UPA MID causing the fault    */
X #define PSYCHO_CEAFSR_BLK	0x0000000000800000 /* Trans was block operation    */
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc64/siginfo.h linux/include/asm-sparc64/siginfo.h
--- v2.2.6/linux/include/asm-sparc64/siginfo.h	Thu Aug 20 17:05:18 1998
+++ linux/include/asm-sparc64/siginfo.h	Mon Apr 26 15:55:54 1999
@@ -201,7 +201,7 @@
X  */
X #define TRAP_BRKPT	1	/* process breakpoint */
X #define TRAP_TRACE	2	/* process trace trap */
-#define NSIGTRAP
+#define NSIGTRAP	2
X 
X /*
X  * SIGCHLD si_codes
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc64/ttable.h linux/include/asm-sparc64/ttable.h
--- v2.2.6/linux/include/asm-sparc64/ttable.h	Mon Oct  5 13:13:44 1998
+++ linux/include/asm-sparc64/ttable.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: ttable.h,v 1.10 1998/09/25 01:09:45 davem Exp $ */
+/* $Id: ttable.h,v 1.11 1999/03/29 12:38:12 jj Exp $ */
X #ifndef _SPARC64_TTABLE_H
X #define _SPARC64_TTABLE_H
X 
@@ -29,11 +29,21 @@
X 	 clr	%l6;					\
X 	nop;
X 
+#define TRAP_SAVEFPU(routine)				\
+	sethi	%hi(109f), %g7;				\
+	ba,pt	%xcc, do_fptrap;			\
+109:	 or	%g7, %lo(109b), %g7;			\
+	call	routine;				\
+	 add	%sp, STACK_BIAS + REGWIN_SZ, %o0;	\
+	ba,pt	%xcc, rtrap;				\
+	 clr	%l6;					\
+	nop;
+
X #define TRAP_NOSAVE(routine)				\
X 	ba,pt	%xcc, routine;				\
X 	 nop;						\
X 	nop; nop; nop; nop; nop; nop;
-
+	
X #define TRAPTL1(routine)				\
X 	sethi	%hi(109f), %g7;				\
X 	ba,pt	%xcc, etraptl1;				\
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc64/unistd.h linux/include/asm-sparc64/unistd.h
--- v2.2.6/linux/include/asm-sparc64/unistd.h	Mon Mar 29 11:09:12 1999
+++ linux/include/asm-sparc64/unistd.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: unistd.h,v 1.27 1999/03/25 00:40:14 davem Exp $ */
+/* $Id: unistd.h,v 1.28 1999/04/07 17:14:19 davem Exp $ */
X #ifndef _SPARC64_UNISTD_H
X #define _SPARC64_UNISTD_H
X 
@@ -60,7 +60,7 @@
X #define __NR_pipe                42 /* Common                                      */
X #define __NR_times               43 /* Implemented via getrusage() in SunOS        */
X /* #define __NR_profil           44    Common                                      */
-/* #define __NR_ni_syscall       45    ENOSYS under SunOS                          */
+#define __NR_umount2             45 /* Linux Specific                              */
X #define __NR_setgid              46 /* Implemented via setregid() in SunOS         */
X #define __NR_getgid              47 /* Common                                      */
X #define __NR_signal              48 /* Implemented via sigvec() in SunOS           */
diff -u --recursive --new-file v2.2.6/linux/include/asm-sparc64/visasm.h linux/include/asm-sparc64/visasm.h
--- v2.2.6/linux/include/asm-sparc64/visasm.h	Mon Oct  5 13:13:44 1998
+++ linux/include/asm-sparc64/visasm.h	Thu Apr 22 19:24:52 1999
@@ -1,4 +1,4 @@
-/* $Id: visasm.h,v 1.3 1998/09/04 01:59:48 ecd Exp $ */
+/* $Id: visasm.h,v 1.4 1999/04/19 01:25:55 davem Exp $ */
X #ifndef _SPARC64_VISASM_H
X #define _SPARC64_VISASM_H
X 
@@ -10,7 +10,7 @@
X #include <asm/pstate.h>
X #include <asm/ptrace.h>
X 
-#define AOFF_task_fpregs	(((ASIZ_task) + 255) & ~255)
+#define AOFF_task_fpregs	(((ASIZ_task) + (64 - 1)) & ~(64 - 1))
X  
X /* Clobbers %o5, %g1, %g2, %g3, %g7, %icc, %xcc */
X 
diff -u --recursive --new-file v2.2.6/linux/include/linux/adfs_fs.h linux/include/linux/adfs_fs.h
--- v2.2.6/linux/include/linux/adfs_fs.h	Fri Jul 31 17:05:52 1998
+++ linux/include/linux/adfs_fs.h	Fri Apr 23 21:20:38 1999
@@ -155,7 +155,7 @@
X extern int adfs_map_lookup (struct super_block *sb, int frag_id, int offset);
X 
X /* namei.c */
-extern int adfs_lookup (struct inode *dir, struct dentry *dentry);
+extern struct dentry *adfs_lookup (struct inode *dir, struct dentry *dentry);
X 
X /* super.c */
X extern int init_adfs_fs (void);
diff -u --recursive --new-file v2.2.6/linux/include/linux/affs_fs.h linux/include/linux/affs_fs.h
--- v2.2.6/linux/include/linux/affs_fs.h	Fri Jul 31 17:10:57 1998
+++ linux/include/linux/affs_fs.h	Fri Apr 23 21:20:38 1999
@@ -60,7 +60,7 @@
X /* namei.c */
X 
X extern int	affs_hash_name(const unsigned char *name, int len, int intl, int hashsize);
-extern int	affs_lookup(struct inode *dir, struct dentry *dentry);
+extern struct dentry *affs_lookup(struct inode *dir, struct dentry *dentry);
X extern int	affs_unlink(struct inode *dir, struct dentry *dentry);
X extern int	affs_create(struct inode *dir, struct dentry *dentry, int mode);
X extern int	affs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
diff -u --recursive --new-file v2.2.6/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h
--- v2.2.6/linux/include/linux/ext2_fs.h	Mon Sep 28 10:51:35 1998
+++ linux/include/linux/ext2_fs.h	Fri Apr 23 21:20:38 1999
@@ -572,7 +572,7 @@
X 
X /* namei.c */
X extern void ext2_release (struct inode *, struct file *);
-extern int ext2_lookup (struct inode *, struct dentry *);
+extern struct dentry *ext2_lookup (struct inode *, struct dentry *);
X extern int ext2_create (struct inode *,struct dentry *,int);
X extern int ext2_mkdir (struct inode *,struct dentry *,int);
X extern int ext2_rmdir (struct inode *,struct dentry *);
diff -u --recursive --new-file v2.2.6/linux/include/linux/fb.h linux/include/linux/fb.h
--- v2.2.6/linux/include/linux/fb.h	Wed Mar 10 15:29:50 1999
+++ linux/include/linux/fb.h	Sat Apr 24 17:51:48 1999
@@ -31,6 +31,7 @@
X #define FB_TYPE_PLANES			1	/* Non interleaved planes */
X #define FB_TYPE_INTERLEAVED_PLANES	2	/* Interleaved planes	*/
X #define FB_TYPE_TEXT			3	/* Text/attributes	*/
+#define FB_TYPE_VGA_PLANES		4	/* EGA/VGA planes	*/
X 
X #define FB_AUX_TEXT_MDA		0	/* Monochrome text */
X #define FB_AUX_TEXT_CGA		1	/* CGA/EGA/VGA Color text */
@@ -236,6 +237,8 @@
X 		    unsigned long arg, int con, struct fb_info *info);
X     /* perform fb specific mmap */
X     int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
+    /* switch to/from raster image mode */
+    int (*fb_rasterimg)(struct fb_info *info, int start);
X };
X 
X 
@@ -295,7 +298,7 @@
X 
X struct fb_info {
X    char modename[40];			/* default video mode */
-   int node;
+   kdev_t node;
X    int flags;
X #define FBINFO_FLAG_MODULE	1	/* Low-level driver is a module */
X    struct fb_ops *fbops;
diff -u --recursive --new-file v2.2.6/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.2.6/linux/include/linux/fs.h	Fri Apr 16 14:47:31 1999
+++ linux/include/linux/fs.h	Tue Apr 27 09:56:21 1999
@@ -169,7 +169,7 @@
X extern void update_atime (struct inode *inode);
X #define UPDATE_ATIME(inode) update_atime (inode)
X 
-extern void buffer_init(void);
+extern void buffer_init(unsigned long);
X extern void inode_init(void);
X extern void file_table_init(void);
X extern void dcache_init(void);
@@ -254,18 +254,8 @@
X 	return test_bit(BH_Protected, &bh->b_state);
X }
X 
-/*
- * Deprecated - we don't keep per-buffer reference flags
- * any more.
- *
- * We _could_ try to update the page reference, but that
- * doesn't seem to really be worth it either. If we did,
- * it would look something like this:
- *
- *	#define buffer_page(bh)		(mem_map + MAP_NR((bh)->b_data))
- *	#define touch_buffer(bh)	set_bit(PG_referenced, &buffer_page(bh)->flags)
- */
-#define touch_buffer(bh)	do { } while (0)
+#define buffer_page(bh)		(mem_map + MAP_NR((bh)->b_data))
+#define touch_buffer(bh)	set_bit(PG_referenced, &buffer_page(bh)->flags)
X 
X #include <linux/pipe_fs_i.h>
X #include <linux/minix_fs_i.h>
@@ -607,7 +597,7 @@
X struct inode_operations {
X 	struct file_operations * default_file_ops;
X 	int (*create) (struct inode *,struct dentry *,int);
-	int (*lookup) (struct inode *,struct dentry *);
+	struct dentry * (*lookup) (struct inode *,struct dentry *);
X 	int (*link) (struct dentry *,struct inode *,struct dentry *);
X 	int (*unlink) (struct inode *,struct dentry *);
X 	int (*symlink) (struct inode *,struct dentry *,const char *);
diff -u --recursive --new-file v2.2.6/linux/include/linux/if_ppp.h linux/include/linux/if_ppp.h
--- v2.2.6/linux/include/linux/if_ppp.h	Thu Jul 16 18:09:29 1998
+++ linux/include/linux/if_ppp.h	Tue Apr 27 00:38:28 1999
@@ -1,4 +1,4 @@
-/*	$Id: if_ppp.h,v 1.14 1998/07/07 04:27:33 paulus Exp $	*/
+/*	$Id: if_ppp.h,v 1.19 1999/03/31 06:07:57 paulus Exp $	*/
X 
X /*
X  * if_ppp.h - Point-to-Point Protocol definitions.
@@ -21,7 +21,7 @@
X  */
X 
X /*
- *  ==FILEVERSION 980704==
+ *  ==FILEVERSION 990331==
X  *
X  *  NOTE TO MAINTAINERS:
X  *     If you modify this file at all, please set the above date.
@@ -35,19 +35,13 @@
X #ifndef _IF_PPP_H_
X #define _IF_PPP_H_
X 
-#if defined(__linux__)
-#include <linux/if.h>
-#include <linux/ioctl.h>
-#include <linux/ppp_defs.h>
-#endif
-
X /*
X  * Packet sizes
X  */
X 
X #define	PPP_MTU		1500	/* Default MTU (size of Info field) */
X #define PPP_MAXMRU	65000	/* Largest MRU we allow */
-#define PPP_VERSION	"2.3.3"
+#define PPP_VERSION	"2.3.7"
X #define PPP_MAGIC	0x5002	/* Magic value for the ppp structure */
X #define PROTO_IPX	0x002b	/* protocol numbers */
X #define PROTO_DNA_RT    0x0027  /* DNA Routing */
@@ -73,7 +67,8 @@
X #define SC_LOG_OUTPKT	0x00040000	/* log contents of pkts sent */
X #define SC_LOG_RAWIN	0x00080000	/* log all chars received */
X #define SC_LOG_FLUSH	0x00100000	/* log all chars flushed */
-#define	SC_MASK		0x0f0000ff	/* bits that user can change */
+#define	SC_SYNC		0x00200000	/* synchronous serial mode */
+#define	SC_MASK		0x0f2000ff	/* bits that user can change */
X 
X /* state bits */
X #define SC_XMIT_BUSY	0x10000000	/* (used by isdn_ppp?) */
diff -u --recursive --new-file v2.2.6/linux/include/linux/if_pppvar.h linux/include/linux/if_pppvar.h
--- v2.2.6/linux/include/linux/if_pppvar.h	Tue Jan 19 11:32:53 1999
+++ linux/include/linux/if_pppvar.h	Tue Apr 27 00:38:28 1999
@@ -42,7 +42,7 @@
X  */
X 
X /*
- *  ==FILEVERSION 990114==
+ *  ==FILEVERSION 990325==
X  *
X  *  NOTE TO MAINTAINERS:
X  *   If you modify this file at all, please set the above date.
@@ -89,6 +89,7 @@
X 	__u8		escape;		/* 0x20 if prev char was PPP_ESC */
X 	__u8		toss;		/* toss this frame		*/
X 	volatile __u8	tty_pushing;	/* internal state flag		*/
+	volatile __u8	woke_up;	/* internal state flag		*/
X 	__u32		xmit_async_map[8]; /* 1 bit means that given control 
X 					   character is quoted on output*/
X 	__u32		recv_async_map; /* 1 bit means that given control 
diff -u --recursive --new-file v2.2.6/linux/include/linux/in6.h linux/include/linux/in6.h
--- v2.2.6/linux/include/linux/in6.h	Mon Oct  5 13:13:44 1998
+++ linux/include/linux/in6.h	Thu Apr 22 19:45:19 1999
@@ -67,6 +67,33 @@
X 	int		ipv6mr_ifindex;
X };
X 
+struct in6_flowlabel_req
+{
+	struct in6_addr	flr_dst;
+	__u32	flr_label;
+	__u8	flr_action;
+	__u8	flr_share;
+	__u16	flr_flags;
+	__u16 	flr_expires;
+	__u16	flr_linger;
+	__u32	__flr_pad;
+	/* Options in format of IPV6_PKTOPTIONS */
+};
+
+#define IPV6_FL_A_GET	0
+#define IPV6_FL_A_PUT	1
+#define IPV6_FL_A_RENEW	2
+
+#define IPV6_FL_F_CREATE	1
+#define IPV6_FL_F_EXCL		2
+
+#define IPV6_FL_S_NONE		0
+#define IPV6_FL_S_EXCL		1
+#define IPV6_FL_S_PROCESS	2
+#define IPV6_FL_S_USER		3
+#define IPV6_FL_S_ANY		255
+
+
X /*
X  *	Bitmask constant declarations to help applications select out the 
X  *	flow label and priority fields.
@@ -75,9 +102,10 @@
X  *	sockaddr_in6 is in network byte order.
X  */
X 
-#define IPV6_FLOWINFO_FLOWLABEL		0x00ff
-#define IPV6_FLOWINFO_PRIORITY		0x0f00
+#define IPV6_FLOWINFO_FLOWLABEL		0x000fffff
+#define IPV6_FLOWINFO_PRIORITY		0x0ff00000
X 
+/* These defintions are obsolete */
X #define IPV6_PRIORITY_UNCHARACTERIZED	0x0000
X #define IPV6_PRIORITY_FILLER		0x0100
X #define IPV6_PRIORITY_UNATTENDED	0x0200
@@ -129,6 +157,7 @@
X #define IPV6_HOPLIMIT		8
X #define IPV6_NEXTHOP		9
X #define IPV6_AUTHHDR		10
+#define IPV6_FLOWINFO		11
X 
X #if 0
X /* Aliases for obsolete names */
@@ -157,5 +186,10 @@
X #define IPV6_PMTUDISC_DONT		0
X #define IPV6_PMTUDISC_WANT		1
X #define IPV6_PMTUDISC_DO		2
+
+/* Flowlabel */
+#define IPV6_FLOWLABEL_MGR	32
+#define IPV6_FLOWINFO_SEND	33
+
X 
X #endif
diff -u --recursive --new-file v2.2.6/linux/include/linux/irda.h linux/include/linux/irda.h
--- v2.2.6/linux/include/linux/irda.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/irda.h	Sat Apr 24 17:49:37 1999
@@ -0,0 +1,120 @@
+/*********************************************************************
+ *                
+ * Filename:      irda.h
+ * Version:       
+ * Description:   
+ * Status:        Experimental.
+ * Author:        Dag Brattli <da...@cs.uit.no>
+ * Created at:    Mon Mar  8 14:06:12 1999
+ * Modified at:   Mon Mar 22 14:14:54 1999
+ * Modified by:   Dag Brattli <da...@cs.uit.no>
+ * 
+ *     Copyright (c) 1999 Dag Brattli, 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.
+ *  
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     provide warranty for any of this software. This material is 
+ *     provided "AS-IS" and at no charge.
+ *     
+ ********************************************************************/
+
+#ifndef KERNEL_IRDA_H
+#define KERNEL_IRDA_H
+
+/* Hint bit positions for first hint byte */
+#define HINT_PNP         0x01
+#define HINT_PDA         0x02
+#define HINT_COMPUTER    0x04
+#define HINT_PRINTER     0x08
+#define HINT_MODEM       0x10
+#define HINT_FAX         0x20
+#define HINT_LAN         0x40
+#define HINT_EXTENSION   0x80
+
+/* Hint bit positions for second hint byte (first extension byte) */
+#define HINT_TELEPHONY   0x01
+#define HINT_FILE_SERVER 0x02
+#define HINT_COMM        0x04
+#define HINT_MESSAGE     0x08
+#define HINT_HTTP        0x10
+#define HINT_OBEX        0x20
+
+/* IrLMP character code values */
+#define CS_ASCII       0x00
+#define	CS_ISO_8859_1  0x01
+#define	CS_ISO_8859_2  0x02
+#define	CS_ISO_8859_3  0x03
+#define	CS_ISO_8859_4  0x04
+#define	CS_ISO_8859_5  0x05
+#define	CS_ISO_8859_6  0x06
+#define	CS_ISO_8859_7  0x07
+#define	CS_ISO_8859_8  0x08
+#define	CS_ISO_8859_9  0x09
+#define CS_UNICODE     0xff
+
+#define SOL_IRLMP      266 /* Same as SOL_IRDA for now */
+#define SOL_IRTTP      266 /* Same as SOL_IRDA for now */
+
+#define IRLMP_ENUMDEVICES        1
+#define IRLMP_IAS_SET            2
+#define IRLMP_IAS_QUERY          3
+#define IRLMP_DISCOVERY_MASK_SET 4
+
+#define IRTTP_QOS_SET            5
+#define IRTTP_QOS_GET            6
+#define IRTTP_MAX_SDU_SIZE       7
+
+#define IAS_MAX_STRING           256
+#define IAS_MAX_OCTET_STRING     1024
+#define IAS_MAX_CLASSNAME        64
+#define IAS_MAX_ATTRIBNAME       256
+
+#define LSAP_ANY                 0xff
+
+struct sockaddr_irda {
+	sa_family_t   sir_family;   /* AF_IRDA */
+	unsigned char sir_lsap_sel; /* LSAP/TSAP selector */
+	unsigned int  sir_addr;     /* Device address */
+	char          sir_name[25]; /* Usually <service>:IrDA:TinyTP */
+};
+
+struct irda_device_info {
+	unsigned int  saddr;       /* Address of remote device */
+	unsigned int  daddr;       /* Link where it was discovered */
+	char          info[22];     /* Description */
+	unsigned char charset;      /* Charset used for description */
+	unsigned char hints[2];     /* Hint bits */
+};
+
+struct irda_device_list {
+       unsigned int len;
+       struct irda_device_info dev[0];
+};
+
+struct irda_ias_set {
+	char irda_class_name[IAS_MAX_CLASSNAME];
+	char irda_attrib_name[IAS_MAX_ATTRIBNAME];
+	unsigned int irda_attrib_type;
+	union {
+		unsigned int irda_attrib_int;
+		struct {
+			unsigned short len;
+			u_char OctetSeq[IAS_MAX_OCTET_STRING];
+		} irda_attrib_octet_seq;
+		struct {
+			unsigned char len;
+			unsigned char charset;
+			unsigned char string[IAS_MAX_STRING];
+		} irda_attrib_string;
+	} attribute;
+};
+
+#endif /* KERNEL_IRDA_H */
+
+
+
+
diff -u --recursive --new-file v2.2.6/linux/include/linux/iso_fs.h linux/include/linux/iso_fs.h
--- v2.2.6/linux/include/linux/iso_fs.h	Fri Jul 31 17:09:42 1998
+++ linux/include/linux/iso_fs.h	Fri Apr 23 21:20:38 1999
@@ -189,7 +189,7 @@
X 
X extern int isofs_open(struct inode * inode, struct file * filp);
X extern void isofs_release(struct inode * inode, struct file * filp);
-extern int isofs_lookup(struct inode * dir, struct dentry *);
+extern struct dentry *isofs_lookup(struct inode * dir, struct dentry *);
X extern unsigned long isofs_count_free_inodes(struct super_block *sb);
X extern int isofs_new_block(int dev);
X extern int isofs_free_block(int dev, int block);
diff -u --recursive --new-file v2.2.6/linux/include/linux/kbd_ll.h linux/include/linux/kbd_ll.h
--- v2.2.6/linux/include/linux/kbd_ll.h	Mon Jun 16 16:36:00 1997
+++ linux/include/linux/kbd_ll.h	Mon Apr 26 13:22:33 1999
@@ -7,6 +7,6 @@
X 
X extern struct pt_regs *kbd_pt_regs;
X 
-void handle_scancode(unsigned char scancode);
+void handle_scancode(unsigned char scancode, int down);
X 
X #endif	/* _KBD_LL_H */
diff -u --recursive --new-file v2.2.6/linux/include/linux/minix_fs.h linux/include/linux/minix_fs.h
--- v2.2.6/linux/include/linux/minix_fs.h	Fri Nov 27 13:09:29 1998
+++ linux/include/linux/minix_fs.h	Fri Apr 23 21:20:38 1999
@@ -89,7 +89,7 @@
X 
X #ifdef __KERNEL__
X 
-extern int minix_lookup(struct inode * dir, struct dentry *dentry);
+extern struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry);
X extern int minix_create(struct inode * dir, struct dentry *dentry, int mode);
X extern int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode);
X extern int minix_rmdir(struct inode * dir, struct dentry *dentry);
diff -u --recursive --new-file v2.2.6/linux/include/linux/msdos_fs.h linux/include/linux/msdos_fs.h
--- v2.2.6/linux/include/linux/msdos_fs.h	Fri Jul 31 17:10:57 1998
+++ linux/include/linux/msdos_fs.h	Tue Apr 27 09:58:11 1999
@@ -195,7 +195,7 @@
X };
X 
X /* misc.c */
-extern int is_binary(char conversion,char *extension);
+extern int fat_is_binary(char conversion,char *extension);
X extern void lock_fat(struct super_block *sb);
X extern void unlock_fat(struct super_block *sb);
X extern int fat_add_cluster(struct inode *inode);
@@ -271,7 +271,7 @@
X 
X /* msdos.c - these are for Umsdos */
X extern void msdos_read_inode(struct inode *inode);
-extern int msdos_lookup(struct inode *dir,struct dentry *);
+extern struct dentry *msdos_lookup(struct inode *dir,struct dentry *);
X extern int msdos_create(struct inode *dir,struct dentry *dentry,int mode);
X extern int msdos_rmdir(struct inode *dir,struct dentry *dentry);
X extern int msdos_mkdir(struct inode *dir,struct dentry *dentry,int mode);
@@ -312,7 +312,7 @@
X extern struct super_block *vfat_read_super(struct super_block *sb,void *data,
X 					   int silent);
X extern void vfat_read_inode(struct inode *inode);
-extern int vfat_lookup(struct inode *dir,struct dentry *);
+extern struct dentry *vfat_lookup(struct inode *dir,struct dentry *);
X 
X /* vfat/vfatfs_syms.c */
X extern struct file_system_type vfat_fs_type;
diff -u --recursive --new-file v2.2.6/linux/include/linux/ncp.h linux/include/linux/ncp.h
--- v2.2.6/linux/include/linux/ncp.h	Fri Jul 31 17:10:57 1998
+++ linux/include/linux/ncp.h	Tue Apr 27 09:58:13 1999
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 17'
echo 'File patch-2.2.7 is continued in part 18'
echo 18 > _shar_seq_.tmp
#!/bin/sh
# this is part 18 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 18; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
@@ -3,6 +3,7 @@
X  *
X  *  Copyright (C) 1995 by Volker Lendecke
X  *  Modified for sparc by J.F. Chadima
+ *  Modified for __constant_ntoh by Frank A. Vorstenbosch
X  *
X  */
X 
@@ -58,11 +59,21 @@
X 
X /* these define the attribute byte as seen by NCP */
X #define aRONLY     (ntohl(0x01000000))
-#define aHIDDEN    (ntohl(0x02000000))
-#define aSYSTEM    (ntohl(0x04000000))
+#define aHIDDEN    (__constant_ntohl(0x02000000))
+#define aSYSTEM    (__constant_ntohl(0x04000000))
X #define aEXECUTE   (ntohl(0x08000000))
X #define aDIR       (ntohl(0x10000000))
X #define aARCH      (ntohl(0x20000000))
+#define aSHARED	   (ntohl(0x80000000))
+#define aDONTSUBALLOCATE (ntohl(1L<<(11+8)))
+#define aTRANSACTIONAL   (ntohl(1L<<(12+8)))
+#define aPURGE		 (ntohl(1L<<(16-8)))
+#define aRENAMEINHIBIT	 (ntohl(1L<<(17-8)))
+#define aDELETEINHIBIT	 (ntohl(1L<<(18-8)))
+#define aDONTCOMPRESS	 (nothl(1L<<(27-24)))
+
+#define NCP_MIN_SYMLINK_SIZE	8
+#define NCP_MAX_SYMLINK_SIZE	512
X 
X #define AR_READ      (ntohs(0x0100))
X #define AR_WRITE     (ntohs(0x0200))
diff -u --recursive --new-file v2.2.6/linux/include/linux/ncp_fs.h linux/include/linux/ncp_fs.h
--- v2.2.6/linux/include/linux/ncp_fs.h	Fri Jul 31 17:11:03 1998
+++ linux/include/linux/ncp_fs.h	Tue Apr 27 09:58:24 1999
@@ -13,6 +13,15 @@
X #include <linux/types.h>
X 
X #include <linux/ncp_mount.h>
+
+/* NLS charsets by ioctl */
+#define NCP_IOCSNAME_LEN 20
+struct ncp_nls_ioctl
+{
+	unsigned char codepage[NCP_IOCSNAME_LEN+1];
+	unsigned char iocharset[NCP_IOCSNAME_LEN+1];
+};
+                
X #include <linux/ncp_fs_sb.h>
X #include <linux/ncp_fs_i.h>
X 
@@ -111,6 +120,9 @@
X #define NCP_IOC_GETPRIVATEDATA		_IOWR('n', 10, struct ncp_privatedata_ioctl)
X #define NCP_IOC_SETPRIVATEDATA		_IOR('n', 10, struct ncp_privatedata_ioctl)
X 
+#define NCP_IOC_GETCHARSETS		_IOWR('n', 11, struct ncp_nls_ioctl)
+#define NCP_IOC_SETCHARSETS		_IOR('n', 11, struct ncp_nls_ioctl)
+
X /*
X  * The packet size to allocate. One page should be enough.
X  */
@@ -155,6 +167,12 @@
X 	__u32	dirEntNum __attribute__((packed));
X 	__u32	DosDirNum __attribute__((packed));
X 	__u32	volNumber __attribute__((packed));
+#ifdef CONFIG_NCPFS_SMALLDOS
+	__u32	origNS;
+#endif
+#ifdef CONFIG_NCPFS_STRONG
+	__u32	nwattr;
+#endif
X 	int	opened;
X 	int	access;
X 	__u32	server_file_handle __attribute__((packed));
@@ -272,11 +290,14 @@
X 	return server->name_space[NCP_FINFO(inode)->volNumber];
X }
X 
-static inline int ncp_preserve_case(struct inode *i)
-{
+static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator) {
X #if defined(CONFIG_NCPFS_NFS_NS) || defined(CONFIG_NCPFS_OS2_NS)
X 	int ns = ncp_namespace(i);
X #endif
+#if defined(CONFIG_NCPFS_SMALLDOS) && defined(CONFIG_NCPFS_OS2_NS)
+	if ((ns == NW_NS_OS2) && (nscreator == NW_NS_DOS))
+		return 0;
+#endif
X 	return
X #ifdef CONFIG_NCPFS_OS2_NS
X 	(ns == NW_NS_OS2) ||
@@ -285,6 +306,11 @@
X 	(ns == NW_NS_NFS) ||
X #endif	/* CONFIG_NCPFS_NFS_NS */
X 	0;
+}
+
+static inline int ncp_preserve_case(struct inode *i)
+{
+	return ncp_preserve_entry_case(i, NW_NS_OS2);
X }
X 
X static inline int ncp_case_sensitive(struct inode *i)
diff -u --recursive --new-file v2.2.6/linux/include/linux/ncp_fs_sb.h linux/include/linux/ncp_fs_sb.h
--- v2.2.6/linux/include/linux/ncp_fs_sb.h	Fri Jul 31 17:11:03 1998
+++ linux/include/linux/ncp_fs_sb.h	Tue Apr 27 09:58:24 1999
@@ -73,6 +73,10 @@
X 		size_t len;
X 		void*  data;
X 	} priv;
+
+	struct ncp_nls_ioctl nls_charsets;	/* NLS user data */
+	struct nls_table *nls_vol;    /* codepage used on volume */
+	struct nls_table *nls_io;     /* charset used for input and display */
X };
X 
X static inline int ncp_conn_valid(struct ncp_server *server)
diff -u --recursive --new-file v2.2.6/linux/include/linux/ncp_mount.h linux/include/linux/ncp_mount.h
--- v2.2.6/linux/include/linux/ncp_mount.h	Fri Jul 31 17:11:03 1998
+++ linux/include/linux/ncp_mount.h	Tue Apr 27 09:58:23 1999
@@ -16,11 +16,13 @@
X #define NCP_MOUNT_VERSION 3
X 
X /* Values for flags */
-#define NCP_MOUNT_SOFT 0x0001
-#define NCP_MOUNT_INTR 0x0002
-#define NCP_MOUNT_STRONG 0x0004   /* enable delete/rename of r/o files */
-#define NCP_MOUNT_NO_OS2 0x0008
-#define NCP_MOUNT_NO_NFS 0x0010
+#define NCP_MOUNT_SOFT		0x0001
+#define NCP_MOUNT_INTR		0x0002
+#define NCP_MOUNT_STRONG	0x0004	/* enable delete/rename of r/o files */
+#define NCP_MOUNT_NO_OS2	0x0008	/* do not use OS/2 (LONG) namespace */
+#define NCP_MOUNT_NO_NFS	0x0010	/* do not use NFS namespace */
+#define NCP_MOUNT_EXTRAS	0x0020
+#define NCP_MOUNT_SYMLINKS	0x0040	/* enable symlinks */
X 
X struct ncp_mount_data {
X 	int version;
diff -u --recursive --new-file v2.2.6/linux/include/linux/pagemap.h linux/include/linux/pagemap.h
--- v2.2.6/linux/include/linux/pagemap.h	Fri Apr 16 14:47:31 1999
+++ linux/include/linux/pagemap.h	Tue Apr 27 09:56:34 1999
@@ -20,8 +20,6 @@
X #define PAGE_HASH_BITS 12
X #define PAGE_HASH_SIZE (1 << PAGE_HASH_BITS)
X 
-#define PAGE_AGE_VALUE 16
-
X extern unsigned long page_cache_size; /* # of pages currently in the hash table */
X extern struct page * page_hash_table[PAGE_HASH_SIZE];
X 
diff -u --recursive --new-file v2.2.6/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.2.6/linux/include/linux/pci.h	Fri Apr 16 14:47:31 1999
+++ linux/include/linux/pci.h	Tue Apr 27 09:56:21 1999
@@ -927,6 +927,9 @@
X 
X #define PCI_VENDOR_ID_CCUBE		0x123f
X 
+#define PCI_VENDOR_ID_AVM		0x1244
+#define PCI_DEVICE_ID_AVM_A1		0x0a00
+
X #define PCI_VENDOR_ID_DIPIX		0x1246
X 
X #define PCI_VENDOR_ID_STALLION		0x124d
diff -u --recursive --new-file v2.2.6/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- v2.2.6/linux/include/linux/proc_fs.h	Fri Apr 16 14:47:31 1999
+++ linux/include/linux/proc_fs.h	Wed Apr 28 08:47:39 1999
@@ -382,7 +382,7 @@
X  * of the /proc/<pid> subdirectories.
X  */
X extern int proc_readdir(struct file *, void *, filldir_t);
-extern int proc_lookup(struct inode *, struct dentry *);
+extern struct dentry *proc_lookup(struct inode *, struct dentry *);
X 
X struct openpromfs_dev {
X  	struct openpromfs_dev *next;
@@ -394,7 +394,7 @@
X };
X extern struct inode_operations *
X proc_openprom_register(int (*readdir)(struct file *, void *, filldir_t),
-		       int (*lookup)(struct inode *, struct dentry *),
+		       struct dentry * (*lookup)(struct inode *, struct dentry *),
X 		       void (*use)(struct inode *, int),
X 		       struct openpromfs_dev ***);
X extern void proc_openprom_deregister(void);
diff -u --recursive --new-file v2.2.6/linux/include/linux/qnx4_fs.h linux/include/linux/qnx4_fs.h
--- v2.2.6/linux/include/linux/qnx4_fs.h	Sat Sep  5 16:46:41 1998
+++ linux/include/linux/qnx4_fs.h	Fri Apr 23 21:20:38 1999
@@ -95,7 +95,7 @@
X #define QNX4DEBUG(X) (void) 0
X #endif
X 
-extern int qnx4_lookup(struct inode *dir, struct dentry *dentry);
+extern struct dentry *qnx4_lookup(struct inode *dir, struct dentry *dentry);
X extern unsigned long qnx4_count_free_inodes(struct super_block *sb);
X extern unsigned long qnx4_count_free_blocks(struct super_block *sb);
X 
diff -u --recursive --new-file v2.2.6/linux/include/linux/sysctl.h linux/include/linux/sysctl.h
--- v2.2.6/linux/include/linux/sysctl.h	Tue Mar 23 14:35:48 1999
+++ linux/include/linux/sysctl.h	Sat Apr 24 12:47:47 1999
@@ -56,9 +56,15 @@
X 	CTL_PROC=4,		/* Process info */
X 	CTL_FS=5,		/* Filesystems */
X 	CTL_DEBUG=6,		/* Debugging */
-	CTL_DEV=7		/* Devices */
+	CTL_DEV=7,		/* Devices */
+	CTL_BUS=8		/* Buses */
X };
X 
+/* CTL_BUS names: */
+enum
+{
+	BUS_ISA=1		/* ISA */
+};
X 
X /* CTL_KERN names: */
X enum
@@ -133,9 +139,17 @@
X 	NET_IPV6=12,
X 	NET_X25=13,
X 	NET_TR=14,
-	NET_DECNET=15
+	NET_DECNET=15,
+	NET_ECONET=16
X };
X 
+/* /proc/sys/bus/isa */
+enum
+{
+	BUS_ISA_MEM_BASE=1,
+	BUS_ISA_PORT_BASE=2,
+	BUS_ISA_PORT_SHIFT=3
+};
X 
X /* /proc/sys/net/core */
X enum
diff -u --recursive --new-file v2.2.6/linux/include/linux/sysv_fs.h linux/include/linux/sysv_fs.h
--- v2.2.6/linux/include/linux/sysv_fs.h	Tue Mar 23 14:35:48 1999
+++ linux/include/linux/sysv_fs.h	Tue Apr 27 09:58:12 1999
@@ -367,7 +367,7 @@
X  * Function prototypes
X  */
X 
-extern int sysv_lookup(struct inode * dir, struct dentry * dentry);
+extern struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry);
X extern int sysv_create(struct inode * dir, struct dentry * dentry, int mode);
X extern int sysv_mkdir(struct inode * dir, struct dentry * dentry, int mode);
X extern int sysv_rmdir(struct inode * dir, struct dentry * dentry);
diff -u --recursive --new-file v2.2.6/linux/include/linux/ufs_fs.h linux/include/linux/ufs_fs.h
--- v2.2.6/linux/include/linux/ufs_fs.h	Fri Apr 16 14:47:31 1999
+++ linux/include/linux/ufs_fs.h	Fri Apr 23 21:20:38 1999
@@ -540,7 +540,7 @@
X extern struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *);
X 
X /* namei.c */
-extern int ufs_lookup (struct inode *, struct dentry *);
+extern struct dentry *ufs_lookup (struct inode *, struct dentry *);
X extern int ufs_mkdir(struct inode *, struct dentry *, int);
X extern int ufs_rmdir (struct inode *, struct dentry *);
X extern int ufs_unlink (struct inode *, struct dentry *);
diff -u --recursive --new-file v2.2.6/linux/include/linux/umsdos_fs.p linux/include/linux/umsdos_fs.p
--- v2.2.6/linux/include/linux/umsdos_fs.p	Fri Apr 16 14:47:31 1999
+++ linux/include/linux/umsdos_fs.p	Fri Apr 23 21:20:38 1999
@@ -9,8 +9,8 @@
X char * umsdos_d_path(struct dentry *, char *, int);
X void umsdos_lookup_patch_new(struct dentry *, struct umsdos_info *);
X int umsdos_is_pseudodos (struct inode *dir, struct dentry *dentry);
-int umsdos_lookup_x ( struct inode *dir, struct dentry *dentry, int nopseudo);
-int UMSDOS_lookup(struct inode *, struct dentry *);
+struct dentry *umsdos_lookup_x ( struct inode *dir, struct dentry *dentry, int nopseudo);
+struct dentry *UMSDOS_lookup(struct inode *, struct dentry *);
X struct dentry *umsdos_lookup_dentry(struct dentry *, char *, int, int);
X struct dentry *umsdos_covered(struct dentry *, char *, int);
X 
@@ -106,8 +106,8 @@
X 		   struct dentry *new_dentry);
X 
X /* rdir.c 22/03/95 03.31.42 */
-int umsdos_rlookup_x (struct inode *dir, struct dentry *dentry, int nopseudo);
-int UMSDOS_rlookup (struct inode *dir, struct dentry *dentry);
+struct dentry *umsdos_rlookup_x (struct inode *dir, struct dentry *dentry, int nopseudo);
+struct dentry *UMSDOS_rlookup (struct inode *dir, struct dentry *dentry);
X 
X /* symlink.c 23/01/95 03.38.30 */
X 
diff -u --recursive --new-file v2.2.6/linux/include/linux/wireless.h linux/include/linux/wireless.h
--- v2.2.6/linux/include/linux/wireless.h	Tue Mar 23 14:35:48 1999
+++ linux/include/linux/wireless.h	Sat Apr 24 17:51:48 1999
@@ -1,7 +1,7 @@
X /*
X  * This file define a set of standard wireless extensions
X  *
- * Version :	6	18.2.99
+ * Version :	7	23.4.99
X  *
X  * Authors :	Jean Tourrilhes - HPLB - <j...@hplb.hpl.hp.com>
X  */
@@ -85,7 +85,11 @@
X  *
X  * V5 to V6
X  * --------
- *	- 802.11 support
+ *	- 802.11 support (ESSID ioctls)
+ *
+ * V6 to V7
+ * --------
+ *	- define IW_ESSID_MAX_SIZE and IW_MAX_AP
X  */
X 
X /* -------------------------- IOCTL LIST -------------------------- */
@@ -123,6 +127,7 @@
X /* As the ESSID is a string up to 32 bytes long, it doesn't fit within the
X  * 'iwreq' structure, so we need to use the 'data' member to point to a
X  * string in user space, like it is done for RANGE...
+ * The "flags" member indicate if the ESSID is active or not.
X  */
X 
X /* ------------------------- IOCTL STUFF ------------------------- */
@@ -169,6 +174,13 @@
X /* Maximum of address that you may set with SPY */
X #define IW_MAX_SPY		8
X 
+/* Maximum of address that you may get in the
+   list of access points in range */
+#define IW_MAX_AP		8
+
+/* Maximum size of the ESSID string */
+#define IW_ESSID_MAX_SIZE	32
+
X /****************************** TYPES ******************************/
X 
X /* --------------------------- SUBTYPES --------------------------- */
@@ -278,7 +290,7 @@
X 			caddr_t	pointer;	/* Pointer to the data
X 						 * (in user space) */
X 			__u16	length;		/* fields or byte size */
-			__u16	flags;		/* Unused */
+			__u16	flags;		/* Optional params */
X 		}	data;
X 	}	u;
X };
diff -u --recursive --new-file v2.2.6/linux/include/net/dst.h linux/include/net/dst.h
--- v2.2.6/linux/include/net/dst.h	Tue Mar 23 14:35:48 1999
+++ linux/include/net/dst.h	Tue Apr 27 09:57:25 1999
@@ -16,11 +16,7 @@
X  * 1 - rare events and bugs (default)
X  * 2 - trace mode.
X  */
-#ifdef  NO_ANK_FIX
X #define RT_CACHE_DEBUG		0
-#else
-#define RT_CACHE_DEBUG		1
-#endif
X 
X #define DST_GC_MIN	(1*HZ)
X #define DST_GC_INC	(5*HZ)
diff -u --recursive --new-file v2.2.6/linux/include/net/flow.h linux/include/net/flow.h
--- v2.2.6/linux/include/net/flow.h	Sat Sep  5 16:46:41 1998
+++ linux/include/net/flow.h	Thu Apr 22 19:45:19 1999
@@ -19,10 +19,12 @@
X 		struct {
X 			struct in6_addr *	daddr;
X 			struct in6_addr *	saddr;
+			__u32			flowlabel;
X 		} ip6_u;
X 	} nl_u;
X #define fl6_dst		nl_u.ip6_u.daddr
X #define fl6_src		nl_u.ip6_u.saddr
+#define fl6_flowlabel	nl_u.ip6_u.flowlabel
X #define fl4_dst		nl_u.ip4_u.daddr
X #define fl4_src		nl_u.ip4_u.saddr
X 
diff -u --recursive --new-file v2.2.6/linux/include/net/ipv6.h linux/include/net/ipv6.h
--- v2.2.6/linux/include/net/ipv6.h	Tue Mar 23 14:35:48 1999
+++ linux/include/net/ipv6.h	Tue Apr 27 09:57:29 1999
@@ -4,7 +4,7 @@
X  *	Authors:
X  *	Pedro Roque		<ro...@di.fc.ul.pt>
X  *
- *	$Id: ipv6.h,v 1.15 1999/03/21 05:22:16 davem Exp $
+ *	$Id: ipv6.h,v 1.16 1999/04/22 10:07:27 davem Exp $
X  *
X  *	This program is free software; you can redistribute it and/or
X  *      modify it under the terms of the GNU General Public License
@@ -124,6 +124,43 @@
X 	/* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
X };
X 
+struct ip6_flowlabel
+{
+	struct ip6_flowlabel	*next;
+	u32			label;
+	struct in6_addr		dst;
+	struct ipv6_txoptions	*opt;
+	atomic_t		users;
+	u32			linger;
+	u8			share;
+	u32			owner;
+	unsigned long		lastuse;
+	unsigned long		expires;
+};
+
+#define IPV6_FLOWINFO_MASK	__constant_htonl(0x0FFFFFFF)
+#define IPV6_FLOWLABEL_MASK	__constant_htonl(0x000FFFFF)
+
+struct ipv6_fl_socklist
+{
+	struct ipv6_fl_socklist	*next;
+	struct ip6_flowlabel	*fl;
+};
+
+extern struct ip6_flowlabel	*fl6_sock_lookup(struct sock *sk, u32 label);
+extern struct ipv6_txoptions	*fl6_merge_options(struct ipv6_txoptions * opt_space,
+						   struct ip6_flowlabel * fl,
+						   struct ipv6_txoptions * fopt);
+extern void			fl6_free_socklist(struct sock *sk);
+extern int			ipv6_flowlabel_opt(struct sock *sk, char *optval, int optlen);
+extern void			ip6_flowlabel_init(void);
+extern void			ip6_flowlabel_cleanup(void);
+
+extern __inline__ void fl6_sock_release(struct ip6_flowlabel *fl)
+{
+	if (fl)
+		atomic_dec(&fl->users);
+}
X 
X extern int 			ip6_ra_control(struct sock *sk, int sel,
X 					       void (*destructor)(struct sock *));
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/discovery.h linux/include/net/irda/discovery.h
--- v2.2.6/linux/include/net/irda/discovery.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/discovery.h	Sat Apr 24 17:50:05 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Tue Apr  6 16:53:53 1999
- * Modified at:   Tue Apr  6 20:44:35 1999
+ * Modified at:   Thu Apr 22 11:04:56 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -37,6 +37,7 @@
X #include <net/irda/irqueue.h>
X 
X #define DISCOVERY_EXPIRE_TIMEOUT 6*HZ
+#define DISCOVERY_DEFAULT_SLOTS  0
X 
X /*
X  * The DISCOVERY structure is used for both discovery requests and responses
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/ircomm_common.h linux/include/net/irda/ircomm_common.h
--- v2.2.6/linux/include/net/irda/ircomm_common.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/ircomm_common.h	Sat Apr 24 17:50:05 1999
@@ -28,8 +28,12 @@
X #include <net/irda/irmod.h> 
X 
X typedef enum {
-	COMM_DISCOVERY,
X         COMM_IDLE,
+
+	COMM_DISCOVERY_WAIT,
+	COMM_QUERYPARAM_WAIT,
+	COMM_QUERYLSAP_WAIT,
+
X 	COMM_WAITI,
X 	COMM_WAITR,
X 	COMM_CONN,
@@ -53,6 +57,12 @@
X 	IRCOMM_DATA_REQUEST,
X 	LMP_DATA_INDICATION,
X 	IRCOMM_CONTROL_REQUEST,
+	
+	DISCOVERY_INDICATION,
+	GOT_PARAMETERS,
+	GOT_LSAPSEL,
+	QUERYIAS_ERROR,
+
X } IRCOMM_EVENT;
X 
X typedef enum {
@@ -172,6 +182,9 @@
X 
X  	__u32 daddr;        /* Device address of the peer device */ 
X 	__u32 saddr;
+	__u32 skey;
+	__u32 ckey;
+	int                 queryias_lock;
X 	int                 ias_type;
X 	int disconnect_priority; /* P_NORMAL or P_HIGH. see irttp.h */
X 	struct notify_t notify;     /* container of callbacks */
@@ -206,6 +219,7 @@
X 	__u8 peer_port_type;
X 
X 	__u8 servicetype;    
+	__u8 peer_servicetype;    
X 	__u8 data_format;   
X 	__u8 peer_data_format;   
X 	__u8 flow_ctrl;
@@ -241,8 +255,7 @@
X 
X 
X 
-int  ircomm_query_ias_and_connect(struct ircomm_cb *self, __u8 servicetype); 
-void ircomm_connect_request(struct ircomm_cb *self);
+void ircomm_connect_request(struct ircomm_cb *self, __u8 servicetype);
X void ircomm_connect_response(struct ircomm_cb *self, struct sk_buff *userdata,
X 			     __u32 maxsdusize);
X void ircomm_disconnect_request(struct ircomm_cb *self,
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irda.h linux/include/net/irda/irda.h
--- v2.2.6/linux/include/net/irda/irda.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/irda.h	Tue Apr 27 09:57:25 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Tue Dec  9 21:13:12 1997
- * Modified at:   Tue Apr  6 20:31:08 1999
+ * Modified at:   Wed Apr 21 17:49:00 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
@@ -43,14 +43,15 @@
X #define ALIGN __attribute__((aligned))
X #define PACK __attribute__((packed))
X 
-/* use 0 for production, 1 for verification, >2 for debug */
+
X #ifdef CONFIG_IRDA_DEBUG
X 
X extern __u32 irda_debug;
X 
-#define IRDA_DEBUG 0
+/* use 0 for production, 1 for verification, >2 for debug */
+#define IRDA_DEBUG_LEVEL 0
X 
-#define DEBUG(n, args...) if (irda_debug >= (n)) printk( KERN_DEBUG args)
+#define DEBUG(n, args...) if (irda_debug >= (n)) printk(KERN_DEBUG args)
X #define ASSERT(expr, func) \
X if(!(expr)) { \
X         printk( "Assertion failed! %s,%s,%s,line=%d\n",\
@@ -61,6 +62,12 @@
X #define ASSERT(expr, func)
X #endif /* CONFIG_IRDA_DEBUG */
X 
+#define WARNING(args...) printk(KERN_WARNING args)
+#define MESSAGE(args...) printk(KERN_INFO args)
+#define ERROR(args...)   printk(KERN_ERR args)
+
+#define MSECS_TO_JIFFIES(ms) (ms*HZ/1000)
+
X /*
X  *  Magic numbers used by Linux/IR. Random numbers which must be unique to 
X  *  give the best protection
@@ -111,6 +118,8 @@
X 	__u32 skey;           /* IrLMP service handle */
X 
X 	int nslots;           /* Number of slots to use for discovery */
+
+	int errno;
X 
X 	struct sock *sk;
X 	struct wait_queue *ias_wait;       /* Wait for LM-IAS answer */
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irda_device.h linux/include/net/irda/irda_device.h
--- v2.2.6/linux/include/net/irda/irda_device.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/irda_device.h	Sat Apr 24 17:50:05 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Haris Zukanovic <ha...@stud.cs.uit.no>
X  * Created at:    Tue Apr 14 12:41:42 1998
- * Modified at:   Wed Apr  7 17:17:16 1999
+ * Modified at:   Tue Apr 20 11:06:28 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Haris Zukanovic, <ha...@stud.cs.uit.no>
@@ -36,15 +36,18 @@
X #include <net/irda/irda.h>
X #include <net/irda/qos.h>
X #include <net/irda/irqueue.h>
+#include <net/irda/irlap_frame.h>
X 
X /* Some non-standard interface flags (should not conflict with any in if.h) */
-#define IFF_SIR 	0x01 /* Supports SIR speeds */
-#define IFF_MIR 	0x02 /* Supports MIR speeds */
-#define IFF_FIR 	0x04 /* Supports FIR speeds */
-#define IFF_PIO   	0x08 /* Supports PIO transfer of data */
-#define IFF_DMA		0x10 /* Supports DMA transfer of data */
-#define IFF_SHM         0x20 /* Supports shared memory data transfers */
-#define IFF_DONGLE      0x40 /* Interface has a dongle attached */
+#define IFF_SIR 	0x0001 /* Supports SIR speeds */
+#define IFF_MIR 	0x0002 /* Supports MIR speeds */
+#define IFF_FIR 	0x0004 /* Supports FIR speeds */
+#define IFF_VFIR        0x0008 /* Supports VFIR speeds */
+#define IFF_PIO   	0x0010 /* Supports PIO transfer of data */
+#define IFF_DMA		0x0020 /* Supports DMA transfer of data */
+#define IFF_SHM         0x0040 /* Supports shared memory data transfers */
+#define IFF_DONGLE      0x0080 /* Interface has a dongle attached */
+#define IFF_AIR         0x0100 /* Supports A(dvanced)IR standards */
X 
X #define IO_XMIT 0x01
X #define IO_RECV 0x02
@@ -65,18 +68,17 @@
X 	int dongle_id;        /* Dongle or transceiver currently used */
X };
X 
-/* Buffer specific info */
+/* IO buffer specific info (inspired by struct sk_buff) */
X struct iobuff_t {
X 	int state;            /* Receiving state (transmit state not used) */
X 	int in_frame;         /* True if receiving frame */
X 
-	__u8 *data;	      /* the buffer */
-	__u8 *head;	      /* start of data in buffer */
+	__u8 *head;	      /* start of buffer */
+	__u8 *data;	      /* start of data in buffer */
X 	__u8 *tail;           /* end of data in buffer */
X 
-	int offset;	      /* Usually data + offset = head */
-	int len;	      /* currently used bytes in buffer */
-	int truesize;	      /* total size of the data area */
+	int len;	      /* length of data */
+	int truesize;	      /* total size of buffer */
X 	__u16 fcs;
X 
X 	int flags;            /* Allocation flags (GFP_KERNEL | GFP_DMA ) */
@@ -89,7 +91,7 @@
X  * stuff from IrDA port implementations.
X  */
X struct irda_device {
-	QUEUE q; /* Must be first */
+	QUEUE q;               /* Must be first */
X 
X         int  magic;	       /* Our magic bullet */
X 	char name[16];         /* Name of device "irda0" */
@@ -109,18 +111,18 @@
X 	struct iobuff_t tx_buff;
X 	struct iobuff_t rx_buff;
X 
-	int xbofs;
-	int media_busy;
X 	/* spinlock_t lock; */ /* For serializing operations */
X 	
X 	/* Media busy stuff */
+	int media_busy;
X 	struct timer_list media_busy_timer;
X 
-	/* Driver specific implementation */
+	/* Callbacks for driver specific implementation */
X         void (*change_speed)(struct irda_device *driver, int baud);
- 	int (*is_receiving)(struct irda_device *);     /* receiving? */
+ 	int  (*is_receiving)(struct irda_device *);    /* receiving? */
X 	/* int (*is_tbusy)(struct irda_device *); */   /* transmitting? */
X 	void (*wait_until_sent)(struct irda_device *);
+	void (*set_caddr)(struct irda_device *);      /* Set connection addr */
X };
X 
X extern hashbin_t *irda_device;
@@ -143,8 +145,28 @@
X 
X int irda_device_setup(struct device *dev);
X 
-inline unsigned short irda_get_mtt(struct sk_buff *skb);
-
X void setup_dma(int channel, char *buffer, int count, int mode);
X 
+/*
+ * Function irda_get_mtt (skb)
+ *
+ *    Utility function for getting the minimum turnaround time out of 
+ *    the skb, where it has been hidden in the cb field.
+ */
+inline static __u16 irda_get_mtt(struct sk_buff *skb)
+{
+	__u16 mtt;
+
+	if (((struct irlap_skb_cb *)(skb->cb))->magic != LAP_MAGIC)
+		mtt = 10000;
+	else
+		mtt = ((struct irlap_skb_cb *)(skb->cb))->mtt;
+
+	ASSERT(mtt <= 10000, return 10000;);
+	
+	return mtt;
+}
+
X #endif
+
+
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/iriap.h linux/include/net/irda/iriap.h
--- v2.2.6/linux/include/net/irda/iriap.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/iriap.h	Sat Apr 24 17:50:05 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Thu Aug 21 00:02:07 1997
- * Modified at:   Mon Mar 22 13:15:04 1999
+ * Modified at:   Wed Apr 21 16:37:21 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1997 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
@@ -51,9 +51,10 @@
X #define IAS_SUCCESS        0
X #define IAS_CLASS_UNKNOWN  1
X #define IAS_ATTRIB_UNKNOWN 2
+#define IAS_DISCONNECT     10
X 
-typedef void (*CONFIRM_CALLBACK)( __u16 obj_id, struct ias_value *value,
-				  void *priv);
+typedef void (*CONFIRM_CALLBACK)(int result, __u16 obj_id, 
+				 struct ias_value *value, void *priv);
X 
X struct iriap_cb {
X 	QUEUE queue; /* Must be first */
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irkbd.h linux/include/net/irda/irkbd.h
--- v2.2.6/linux/include/net/irda/irkbd.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/irkbd.h	Wed Dec 31 16:00:00 1969
@@ -1,91 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      irkbd.h
- * Version:       0.2
- * Description:   IrDA Keyboard/Mouse driver (Tekram IR-660)
- * Status:        Experimental.
- * Author:        Dag Brattli <da...@cs.uit.no>
- * Created at:    Mon Mar  1 00:24:19 1999
- * Modified at:   Thu Mar 11 14:54:00 1999
- * Modified by:   Dag Brattli <da...@cs.uit.no>
- * 
- *     Copyright (c) 1999 Dag Brattli, 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.
- *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
- *     provided "AS-IS" and at no charge.
- *     
- ********************************************************************/
-
-#ifndef IRKBD_H
-#define IRKBD_H
-
-/* Some commands */
-#define IRKBD_CMD_INIT_KBD   0xfe
-#define IRKBD_CMD_INIT_MOUSE 0xff
-#define IRKBD_CMD_ENABLE     0x41
-#define IRKBD_CMD_LED        0x31
-#define IRKBD_CMD_KDB_SPEED  0x33
-
-/* Some responses */
-#define IRKBD_RSP_KBDOK      0x11
-#define IRKBD_RSP_KBDERR     0x12
-#define IRKBD_RSP_MSOK       0x21
-#define IRKBD_RSP_MSERR      0x22
-#define IRKBD_RSP_LEDOK      0x31
-#define IRKBD_RSP_KBDSPEEDOK 0x33
-#define IRKBD_RSP_RSPN41     0x41
-
-#define IRKBD_RATE       2 /* Polling rate, should be 15 ms */
-#define IRKBD_TIMEOUT  100 /* 1000 ms */
-
-#define SUBFRAME_MASK     0xc0
-#define SUBFRAME_MOUSE    0x80
-#define SUBFRAME_KEYBOARD 0x40
-#define SUBFRAME_RESPONSE 0x00
-
-#define IRKBD_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_HEADER)
-
-#define IRKBD_BUF_SIZE 4096 /* Must be power of 2! */
-
-enum {
-	IRKBD_IDLE,       /* Not connected */
-	IRKBD_INIT_KBD,   /* Initializing keyboard */
-	IRKBD_INIT_MOUSE, /* Initializing mouse */
-	IRKBD_POLLING,    /* Polling device */
-};
-
-/* Main structure */
-struct irkbd_cb {
-	struct miscdevice dev;
-	char devname[9];    /* name of the registered device */
-	int state;
-
-	int count;          /* Open count */
-
-	__u32 saddr;        /* my local address */
-	__u32 daddr;        /* peer address */
-
-	struct tsap_cb *tsap;		
-	__u8 dtsap_sel;     /* remote TSAP address */
-	__u8 stsap_sel;     /* local TSAP address */
-
-	struct timer_list watchdog_timer;
-
-	LOCAL_FLOW tx_flow;
-	LOCAL_FLOW rx_flow;
-
-	__u8 scancodes[IRKBD_BUF_SIZE]; /* Buffer for mouse events */
-	int head;
-	int tail;
-
-	struct wait_queue *read_wait;
-	struct fasync_struct *async;
-};
-
-#endif /* IRKBD_H */
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irlan_client.h linux/include/net/irda/irlan_client.h
--- v2.2.6/linux/include/net/irda/irlan_client.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/irlan_client.h	Sat Apr 24 17:50:05 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Thu Feb 25 21:05:53 1999
+ * Modified at:   Thu Apr 22 14:13:34 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
@@ -30,6 +30,7 @@
X #include <linux/skbuff.h>
X #include <linux/netdevice.h>
X 
+#include <net/irda/irias_object.h>
X #include <net/irda/irlan_event.h>
X 
X void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout);
@@ -38,7 +39,7 @@
X 
X void irlan_client_open_ctrl_tsap( struct irlan_cb *self);
X 
-void irlan_client_extract_params(struct irlan_cb *self, struct sk_buff *skb);
-void irlan_client_get_value_confirm( __u16 obj_id, struct ias_value *value, 
-				     void *priv);
+void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb);
+void irlan_client_get_value_confirm(int result, __u16 obj_id, 
+				    struct ias_value *value, void *priv);
X #endif
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irlan_common.h linux/include/net/irda/irlan_common.h
--- v2.2.6/linux/include/net/irda/irlan_common.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/irlan_common.h	Sat Apr 24 17:50:05 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Tue Apr  6 16:19:41 1999
+ * Modified at:   Thu Apr 22 14:30:37 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
@@ -121,7 +121,6 @@
X 	int broadcast_open;
X 
X 	struct timer_list kick_timer;
-	int start_new_provider;
X };
X 
X /*
@@ -183,6 +182,10 @@
X 
X struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr, int netdev);
X void irlan_close(struct irlan_cb *self);
+void irlan_close_tsaps(struct irlan_cb *self);
+void irlan_mod_inc_use_count(void);
+void irlan_mod_dec_use_count(void);
+
X int  irlan_register_netdev(struct irlan_cb *self);
X void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel);
X void irlan_start_watchdog_timer(struct irlan_cb *self, int timeout);
@@ -204,7 +207,7 @@
X int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *value, 
X 			     __u16 value_len);
X 
-int irlan_get_param(__u8 *buf, char *name, char *value, __u16 *len);
+int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len);
X void print_ret_code(__u8 code);
X 
X extern hashbin_t *irlan;
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irlan_eth.h linux/include/net/irda/irlan_eth.h
--- v2.2.6/linux/include/net/irda/irlan_eth.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/irlan_eth.h	Sat Apr 24 17:50:05 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Thu Oct 15 08:36:58 1998
- * Modified at:   Mon Mar 22 12:57:11 1999
+ * Modified at:   Thu Apr 22 14:09:37 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
@@ -25,6 +25,9 @@
X #ifndef IRLAN_ETH_H
X #define IRLAN_ETH_H
X 
+int  irlan_eth_init(struct device *dev);
+int  irlan_eth_open(struct device *dev);
+int  irlan_eth_close(struct device *dev);
X int  irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb);
X int  irlan_eth_xmit(struct sk_buff *skb, struct device *dev);
X 
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irlan_provider.h linux/include/net/irda/irlan_provider.h
--- v2.2.6/linux/include/net/irda/irlan_provider.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/irlan_provider.h	Sat Apr 24 17:50:05 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Mon Mar  8 15:32:35 1999
+ * Modified at:   Thu Apr 22 14:29:16 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
@@ -46,12 +46,12 @@
X void irlan_provider_connect_response(struct irlan_cb *, struct tsap_cb *);
X 
X int irlan_parse_open_data_cmd(struct irlan_cb *self, struct sk_buff *skb);
-int irlan_provider_extract_params(struct irlan_cb *self, int cmd,
-				  struct sk_buff *skb);
+int irlan_provider_parse_command(struct irlan_cb *self, int cmd,
+				 struct sk_buff *skb);
X 
X void irlan_provider_send_reply(struct irlan_cb *self, int command, 
X 			       int ret_code);
-void irlan_provider_open_ctrl_tsap( struct irlan_cb *self);
+int irlan_provider_open_ctrl_tsap(struct irlan_cb *self);
X 
X #endif
X 
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irlap.h linux/include/net/irda/irlap.h
--- v2.2.6/linux/include/net/irda/irlap.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/irlap.h	Sat Apr 24 17:50:05 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Fri Mar 26 15:15:17 1999
+ * Modified at:   Fri Apr 23 09:51:15 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
@@ -219,12 +219,12 @@
X 
X int  irlap_generate_rand_time_slot( int S, int s);
X void irlap_initiate_connection_state( struct irlap_cb *);
-void irlap_flush_all_queues( struct irlap_cb *);
-void irlap_change_speed( struct irlap_cb *, int);
-void irlap_wait_min_turn_around( struct irlap_cb *, struct qos_info *);
-
-void irlap_init_qos_capabilities( struct irlap_cb *, struct qos_info *);
-void irlap_apply_default_connection_parameters( struct irlap_cb *self);
-void irlap_apply_connection_parameters( struct irlap_cb *, struct qos_info *);
+void irlap_flush_all_queues(struct irlap_cb *);
+void irlap_change_speed(struct irlap_cb *, int);
+void irlap_wait_min_turn_around(struct irlap_cb *, struct qos_info *);
+
+void irlap_init_qos_capabilities(struct irlap_cb *, struct qos_info *);
+void irlap_apply_default_connection_parameters(struct irlap_cb *self);
+void irlap_apply_connection_parameters(struct irlap_cb *, struct qos_info *);
X 
X #endif
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irlap_frame.h linux/include/net/irda/irlap_frame.h
--- v2.2.6/linux/include/net/irda/irlap_frame.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/irlap_frame.h	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Tue Aug 19 10:27:26 1997
- * Modified at:   Fri Mar 26 14:10:53 1999
+ * Modified at:   Fri Apr 23 09:33:55 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
@@ -116,8 +116,6 @@
X 	int vs;    /* next frame to send */
X 	int vr;    /* next frame to receive */
X };
-
-__inline__ void irlap_insert_mtt( struct irlap_cb *self, struct sk_buff *skb);
X 
X void irlap_send_discovery_xid_frame( struct irlap_cb *, int S, __u8 s, 
X 				     __u8 command, discovery_t *discovery);
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irlmp.h linux/include/net/irda/irlmp.h
--- v2.2.6/linux/include/net/irda/irlmp.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/irlmp.h	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun Aug 17 20:54:32 1997
- * Modified at:   Tue Apr  6 20:05:14 1999
+ * Modified at:   Fri Apr 23 09:15:07 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
@@ -202,12 +202,12 @@
X void irlmp_register_link(struct irlap_cb *, __u32 saddr, struct notify_t *);
X void irlmp_unregister_link(__u32 saddr);
X 
-int  irlmp_connect_request( struct lsap_cb *, __u8 dlsap_sel, 
-			    __u32 saddr, __u32 daddr,
-			    struct qos_info *, struct sk_buff *);
-void irlmp_connect_indication( struct lsap_cb *self, struct sk_buff *skb);
-void irlmp_connect_response( struct lsap_cb *, struct sk_buff *);
-void irlmp_connect_confirm( struct lsap_cb *, struct sk_buff *);
+int  irlmp_connect_request(struct lsap_cb *, __u8 dlsap_sel, 
+			   __u32 saddr, __u32 daddr,
+			   struct qos_info *, struct sk_buff *);
+void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb);
+void irlmp_connect_response(struct lsap_cb *, struct sk_buff *);
+void irlmp_connect_confirm(struct lsap_cb *, struct sk_buff *);
X struct lsap_cb *irlmp_dup(struct lsap_cb *self, void *instance);
X 
X void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, 
@@ -219,17 +219,17 @@
X void irlmp_do_discovery(int nslots);
X discovery_t *irlmp_get_discovery_response(void);
X 
-void irlmp_data_request( struct lsap_cb *, struct sk_buff *);
-void irlmp_udata_request( struct lsap_cb *, struct sk_buff *);
-void irlmp_data_indication( struct lsap_cb *, struct sk_buff *);
-void irlmp_udata_indication( struct lsap_cb *, struct sk_buff *);
+void irlmp_data_request(struct lsap_cb *, struct sk_buff *);
+inline void irlmp_udata_request(struct lsap_cb *, struct sk_buff *);
+inline void irlmp_data_indication(struct lsap_cb *, struct sk_buff *);
+inline void irlmp_udata_indication(struct lsap_cb *, struct sk_buff *);
X 
X void irlmp_status_request(void);
-void irlmp_status_indication( LINK_STATUS link, LOCK_STATUS lock);
+void irlmp_status_indication(LINK_STATUS link, LOCK_STATUS lock);
X 
-int  irlmp_slsap_inuse( __u8 slsap);
+int  irlmp_slsap_inuse(__u8 slsap);
X __u8 irlmp_find_free_slsap(void);
-LM_REASON irlmp_convert_lap_reason( LAP_REASON);
+LM_REASON irlmp_convert_lap_reason(LAP_REASON);
X 
X __u32 irlmp_get_saddr(struct lsap_cb *self);
X __u32 irlmp_get_daddr(struct lsap_cb *self);
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irlpt_cli.h linux/include/net/irda/irlpt_cli.h
--- v2.2.6/linux/include/net/irda/irlpt_cli.h	Wed Mar 10 15:29:50 1999
+++ linux/include/net/irda/irlpt_cli.h	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X * Author: Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sat Feb 21 18:54:38 1998
- * Modified at:   Mon Jan 11 15:58:16 1999
+ * Modified at:   Wed Apr 21 16:46:26 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998, Thomas Davis, <rat...@radiks.net>
@@ -34,7 +34,7 @@
X  * if it's static, it doesn't go in here.
X  */
X 
-void irlpt_client_get_value_confirm(__u16 obj_id, 
+void irlpt_client_get_value_confirm(int result, __u16 obj_id, 
X 				    struct ias_value *value, 
X 				    void *priv);
X void irlpt_client_connect_indication( void *instance, 
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irmod.h linux/include/net/irda/irmod.h
--- v2.2.6/linux/include/net/irda/irmod.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/irmod.h	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Mon Dec 15 13:58:52 1997
- * Modified at:   Tue Mar 16 22:27:41 1999
+ * Modified at:   Fri Apr  9 11:13:39 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  *
X  *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
@@ -101,7 +101,22 @@
X int irmod_init_module(void);
X void irmod_cleanup_module(void);
X 
-inline int irda_lock(int *lock);
+/*
+ * Function irda_lock (lock)
+ *
+ *    Lock variable. Returns false if the lock is already set.
+ *    
+ */
+static inline int irda_lock(int *lock) 
+{
+	if (test_and_set_bit( 0, (void *) lock))  {
+		DEBUG(3, __FUNCTION__ 
+		      "(), Trying to lock, already locked variable!\n");
+		return FALSE;
+        }  
+	return TRUE;
+}
+
X inline int irda_unlock(int *lock);
X 
X void irda_notify_init(struct notify_t *notify);
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irobex.h linux/include/net/irda/irobex.h
--- v2.2.6/linux/include/net/irda/irobex.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/irobex.h	Wed Dec 31 16:00:00 1969
@@ -1,114 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      irobex.h
- * Version:       0.8
- * Description:   
- * Status:        Experimental.
- * Author:        Dag Brattli <da...@cs.uit.no>
- * Created at:    Sat Jul  4 22:43:57 1998
- * Modified at:   Thu Mar 11 16:11:54 1999
- * Modified by:   Dag Brattli <da...@cs.uit.no>
- * 
- *     Copyright (c) 1998 Dag Brattli, 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.
- *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
- *     provided "AS-IS" and at no charge.
- *     
- ********************************************************************/
-
-#ifndef IROBEX_H
-#define IROBEX_H
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/skbuff.h>
-#include <linux/miscdevice.h>
-
-#include <net/irda/timer.h>
-#include <net/irda/qos.h>
-#include <net/irda/irmod.h>
-
-#define LOW_THRESHOLD      4
-#define HIGH_THRESHOLD     8
-#define IROBEX_MAX_QUEUE  12
-
-/* Small structure to be used by the IOCTL call */
-struct irobex_ioc_t {
-     __u32 daddr;
-};
-
-#define IROBEX_IOC_MAGIC 'k'
-
-#define IROBEX_IOCSCONNECT    _IOW(IROBEX_IOC_MAGIC, 1, 4)
-#define IROBEX_IOCSDISCONNECT _IOW(IROBEX_IOC_MAGIC, 2, 4)
-#define IROBEX_IOC_MAXNR 2
-
-#define IROBEX_MAX_HEADER (TTP_HEADER+LMP_HEADER+LAP_HEADER)
-
-typedef enum {
-	OBEX_IDLE,       /* Doing nothing */
-	OBEX_DISCOVER,   /* Trying to discovery remote device */
-	OBEX_QUERY,      /* Querying remote LM-IAS */
-	OBEX_CONN,       /* Trying to connect to remote device */
-	OBEX_DATA,       /* Data transfer ready */
-} OBEX_STATE;
-
-struct irobex_cb {
-	QUEUE queue;        /* Must be first! */
-
-        int magic;          /* magic used to detect corruption of the struct */
-
-	OBEX_STATE state;   /* Current state */
-
-	__u32 saddr;        /* my local address */
-	__u32 daddr;        /* peer address */
-	unsigned long time_discovered;
-
-	__u32 ckey;           /* IrLMP client handle */
-	__u32 skey;           /* IrLMP service handle */
-
-        char devname[9];    /* name of the registered device */
-	struct tsap_cb *tsap;
-	int eof;
-
-	__u8 dtsap_sel;         /* remote TSAP address */
-	__u8 stsap_sel;         /* local TSAP address */
-
-	int irlap_data_size;
-
-	struct miscdevice dev;
-
-	int count;                /* open count */
-
-	struct sk_buff_head rx_queue; /* Receive queue */
-
-	struct wait_queue *read_wait;
-	struct wait_queue *write_wait;
-
-	struct fasync_struct *async;
-
-	struct timer_list watchdog_timer;
-
-	LOCAL_FLOW tx_flow;
-	LOCAL_FLOW rx_flow;
-};
-
-int irobex_init(void);
-
-void irobex_watchdog_timer_expired( unsigned long data);
-
-inline void irobex_start_watchdog_timer( struct irobex_cb *self, int timeout) 
-{
-	irda_start_timer( &self->watchdog_timer, timeout, (unsigned long) self,
-			  irobex_watchdog_timer_expired);
-}
-
-extern struct irobex_cb *irobex;
-
-#endif
diff -u --recursive --new-file v2.2.6/linux/include/net/irda/irttp.h linux/include/net/irda/irttp.h
--- v2.2.6/linux/include/net/irda/irttp.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/irda/irttp.h	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun Aug 31 20:14:31 1997
- * Modified at:   Mon Mar 22 13:17:30 1999
+ * Modified at:   Sat Apr 10 10:19:56 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
@@ -93,7 +93,7 @@
X 	__u32 rx_max_sdu_size; /* Max receive user data size */
X 
X 	int tx_sdu_busy;       /* TxSdu.busy */
-	int tx_max_sdu_size;   /* Max transmit user data size */
+	__u32 tx_max_sdu_size; /* Max transmit user data size */
X 
X 	int close_pend;        /* Close, but disconnect_pend */
X 	int disconnect_pend;   /* Disconnect, but still data to send */
diff -u --recursive --new-file v2.2.6/linux/include/net/pkt_sched.h linux/include/net/pkt_sched.h
--- v2.2.6/linux/include/net/pkt_sched.h	Tue Mar 23 14:35:48 1999
+++ linux/include/net/pkt_sched.h	Thu Apr 22 19:45:19 1999
@@ -215,6 +215,8 @@
X    (stamp) = __cur>>psched_clock_scale; \
X })
X 
+#define PSCHED_EXPORTLIST_1
+
X #elif defined (__alpha__)
X 
X #define PSCHED_WATCHER u32
diff -u --recursive --new-file v2.2.6/linux/include/net/route.h linux/include/net/route.h
--- v2.2.6/linux/include/net/route.h	Tue Mar 23 14:35:48 1999
+++ linux/include/net/route.h	Tue Apr 27 09:57:27 1999
@@ -114,6 +114,7 @@
X extern int		ip_route_output(struct rtable **, u32 dst, u32 src, u32 tos, int oif);
X extern int		ip_route_input(struct sk_buff*, u32 dst, u32 src, u8 tos, struct device *devin);
X extern unsigned short	ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
+extern void		ip_rt_update_pmtu(struct dst_entry *dst, unsigned mtu);
X extern void		ip_rt_send_redirect(struct sk_buff *skb);
X 
X extern unsigned		inet_addr_type(u32 addr);
diff -u --recursive --new-file v2.2.6/linux/include/net/sock.h linux/include/net/sock.h
--- v2.2.6/linux/include/net/sock.h	Fri Apr 16 14:47:31 1999
+++ linux/include/net/sock.h	Tue Apr 27 09:57:28 1999
@@ -146,12 +146,11 @@
X 	struct in6_addr		daddr;
X 	struct in6_addr		*daddr_cache;
X 
-	__u32			flow_lbl;
+	__u32			flow_label;
X 	__u32			frag_size;
X 	int			hop_limit;
X 	int			mcast_hops;
X 	int			mcast_oif;
-	__u8			priority;
X 
X 	/* pktoption flags */
X 	union {
@@ -162,7 +161,7 @@
X 				hopopts:1,
X 				dstopts:1,
X                                 authhdr:1,
-                                unused:1;
+                                rxflow:1;
X 		} bits;
X 		__u8		all;
X 	} rxopt;
@@ -170,9 +169,11 @@
X 	/* sockopt flags */
X 	__u8			mc_loop:1,
X 	                        recverr:1,
+	                        sndflow:1,
X 	                        pmtudisc:2;
X 
X 	struct ipv6_mc_socklist	*ipv6_mc_list;
+	struct ipv6_fl_socklist *ipv6_fl_list;
X 	__u32			dst_cookie;
X 
X 	struct ipv6_txoptions	*opt;
diff -u --recursive --new-file v2.2.6/linux/include/net/tcp.h linux/include/net/tcp.h
--- v2.2.6/linux/include/net/tcp.h	Tue Mar 23 14:35:48 1999
+++ linux/include/net/tcp.h	Wed Apr 28 09:51:57 1999
@@ -716,6 +716,14 @@
X 	return (new_win && (new_win > (cur_win << 1)));
X }
X 
+/* TCP timestamps are only 32-bits, this causes a slight
+ * complication on 64-bit systems since we store a snapshot
+ * of jiffies in the buffer control blocks below.  We decidely
+ * only use of the low 32-bits of jiffies and hide the ugly
+ * casts with the following macro.
+ */
+#define tcp_time_stamp		((__u32)(jiffies))
+
X /* This is what the send packet queueing engine uses to pass
X  * TCP per-packet control information to the transmission
X  * code.  We also store the host-order sequence numbers in
@@ -732,7 +740,7 @@
X 	} header;	/* For incoming frames		*/
X 	__u32		seq;		/* Starting sequence number	*/
X 	__u32		end_seq;	/* SEQ + FIN + SYN + datalen	*/
-	unsigned long	when;		/* used to compute rtt's	*/
+	__u32		when;		/* used to compute rtt's	*/
X 	__u8		flags;		/* TCP header flags.		*/
X 
X 	/* NOTE: These must match up to the flags byte in a
@@ -793,17 +801,22 @@
X 	 *	c) We are retransmiting [Nagle]
X 	 *	d) We have too many packets 'in flight'
X 	 *
-	 * 	Don't use the nagle rule for urgent data.
+	 * 	Don't use the nagle rule for urgent data (or
+	 *	for the final FIN -DaveM).
X 	 */
X 	if ((sk->nonagle == 2 && (skb->len < tp->mss_cache)) ||
X 	    (!sk->nonagle &&
X 	     skb->len < (tp->mss_cache >> 1) &&
X 	     tp->packets_out &&
-	     !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG)))
+	     !(TCP_SKB_CB(skb)->flags & (TCPCB_FLAG_URG|TCPCB_FLAG_FIN))))
X 		nagle_check = 0;
X 
+	/* Don't be strict about the congestion window for the
+	 * final FIN frame.  -DaveM
+	 */
X 	return (nagle_check &&
-		(tcp_packets_in_flight(tp) < tp->snd_cwnd) &&
+		((tcp_packets_in_flight(tp) < tp->snd_cwnd) ||
+		 (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) &&
X 		!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) &&
X 		tp->retransmits == 0);
X }
diff -u --recursive --new-file v2.2.6/linux/include/net/transp_v6.h linux/include/net/transp_v6.h
--- v2.2.6/linux/include/net/transp_v6.h	Sat Sep  5 16:46:42 1998
+++ linux/include/net/transp_v6.h	Tue Apr 27 09:57:33 1999
@@ -13,6 +13,8 @@
X extern struct proto udpv6_prot;
X extern struct proto tcpv6_prot;
X 
+struct flowi;
+
X extern void				rawv6_init(void);
X extern void				udpv6_init(void);
X extern void				tcpv6_init(void);
@@ -26,8 +28,7 @@
X 						  struct sk_buff *skb);
X 
X extern int			datagram_send_ctl(struct msghdr *msg,
-						  int *oif,
-						  struct in6_addr **src_addr,
+						  struct flowi *fl,
X 						  struct ipv6_txoptions *opt,
X 						  int *hlimit);
X 
diff -u --recursive --new-file v2.2.6/linux/init/main.c linux/init/main.c
--- v2.2.6/linux/init/main.c	Fri Apr 16 14:47:31 1999
+++ linux/init/main.c	Sat Apr 24 17:51:48 1999
@@ -184,6 +184,7 @@
X extern void u14_34f_setup(char *str, int *ints);
X extern void fdomain_setup(char *str, int *ints);
X extern void ibmmca_scsi_setup(char *str, int *ints);
+extern void fd_mcs_setup(char *str, int *ints);
X extern void in2000_setup(char *str, int *ints);
X extern void NCR53c406a_setup(char *str, int *ints);
X extern void sym53c416_setup(char *str, int *ints);
@@ -709,6 +710,9 @@
X #ifdef CONFIG_SCSI_IBMMCA
X         { "ibmmcascsi=", ibmmca_scsi_setup },
X #endif
+#ifdef CONFIG_SCSI_FD_MCS
+	{ "fd_mcs=", fd_mcs_setup },
+#endif
X #if defined(CONFIG_SCSI_DC390T) && ! defined(CONFIG_SCSI_DC390T_NOGENSUPP)
X         { "tmscsim=", dc390_setup },
X #endif
@@ -1166,7 +1170,7 @@
X 	filescache_init();
X 	dcache_init();
X 	vma_init();
-	buffer_init();
+	buffer_init(memory_end-memory_start);
X 	signals_init();
X 	inode_init();
X 	file_table_init();
diff -u --recursive --new-file v2.2.6/linux/ipc/shm.c linux/ipc/shm.c
--- v2.2.6/linux/ipc/shm.c	Fri Apr 16 14:47:31 1999
+++ linux/ipc/shm.c	Thu Apr 22 23:31:06 1999
@@ -691,10 +691,10 @@
X 		next_id:
X 		swap_idx = 0;
X 		if (++swap_id > max_shmid) {
+			swap_id = 0;
X 			if (loop)
X 				goto failed;
X 			loop = 1;
-			swap_id = 0;
X 		}
X 		goto check_id;
X 	}
diff -u --recursive --new-file v2.2.6/linux/mm/page_alloc.c linux/mm/page_alloc.c
--- v2.2.6/linux/mm/page_alloc.c	Mon Jan 25 17:44:34 1999
+++ linux/mm/page_alloc.c	Wed Apr 21 13:03:48 1999
@@ -33,7 +33,7 @@
X    for the ring buffers */
X #define NR_MEM_LISTS 12
X #else
-#define NR_MEM_LISTS 6
+#define NR_MEM_LISTS 10
X #endif
X 
X /* The start of this MUST match the start of "struct page" */
diff -u --recursive --new-file v2.2.6/linux/mm/vmalloc.c linux/mm/vmalloc.c
--- v2.2.6/linux/mm/vmalloc.c	Tue Jan 19 11:32:53 1999
+++ linux/mm/vmalloc.c	Wed Apr 21 23:12:32 1999
@@ -161,11 +161,11 @@
X 	for (p = &vmlist; (tmp = *p) ; p = &tmp->next) {
X 		if (size + addr < (unsigned long) tmp->addr)
X 			break;
+		addr = tmp->size + (unsigned long) tmp->addr;
X 		if (addr > VMALLOC_END-size) {
X 			kfree(area);
X 			return NULL;
X 		}
-		addr = tmp->size + (unsigned long) tmp->addr;
X 	}
X 	area->addr = (void *)addr;
X 	area->size = size + PAGE_SIZE;
diff -u --recursive --new-file v2.2.6/linux/mm/vmscan.c linux/mm/vmscan.c
--- v2.2.6/linux/mm/vmscan.c	Tue Feb 23 15:21:35 1999
+++ linux/mm/vmscan.c	Fri Apr 23 11:07:30 1999
@@ -45,12 +45,7 @@
X 	page = pte_page(pte);
X 	if (MAP_NR(page) >= max_mapnr)
X 		return 0;
-
X 	page_map = mem_map + MAP_NR(page);
-	if (PageReserved(page_map)
-	    || PageLocked(page_map)
-	    || ((gfp_mask & __GFP_DMA) && !PageDMA(page_map)))
-		return 0;
X 
X 	if (pte_young(pte)) {
X 		/*
@@ -62,6 +57,11 @@
X 		return 0;
X 	}
X 
+	if (PageReserved(page_map)
+	    || PageLocked(page_map)
+	    || ((gfp_mask & __GFP_DMA) && !PageDMA(page_map)))
+		return 0;
+
X 	/*
X 	 * Is the page already in the swap cache? If so, then
X 	 * we can just drop our reference to it without doing
@@ -248,9 +248,8 @@
X 	pgd_t *pgdir;
X 	unsigned long end;
X 
-	/* Don't swap out areas like shared memory which have their
-	    own separate swapping mechanism or areas which are locked down */
-	if (vma->vm_flags & (VM_SHM | VM_LOCKED))
+	/* Don't swap out areas which are locked down */
+	if (vma->vm_flags & VM_LOCKED)
X 		return 0;
X 
X 	pgdir = pgd_offset(tsk->mm, address);
diff -u --recursive --new-file v2.2.6/linux/net/802/tr.c linux/net/802/tr.c
--- v2.2.6/linux/net/802/tr.c	Tue Dec 22 14:16:59 1998
+++ linux/net/802/tr.c	Sat Apr 24 17:51:48 1999
@@ -30,7 +30,6 @@
X #include <linux/trdevice.h>
X #include <linux/skbuff.h>
X #include <linux/errno.h>
-#include <linux/string.h>
X #include <linux/timer.h>
X #include <linux/net.h>
X #include <linux/proc_fs.h>
@@ -68,6 +67,8 @@
X  
X rif_cache rif_table[RIF_TABLE_SIZE]={ NULL, };
X 
+static spinlock_t rif_lock = SPIN_LOCK_UNLOCKED;
+
X #define RIF_TIMEOUT 60*10*HZ
X #define RIF_CHECK_INTERVAL 60*HZ
X 
@@ -230,6 +231,9 @@
X 	unsigned int hash;
X 	rif_cache entry;
X 	unsigned char *olddata;
+	unsigned long flags;
+	
+	spin_lock_irqsave(&rif_lock, flags);
X 
X 	/*
X 	 *	Broadcasts are single route as stated in RFC 1042 
@@ -298,6 +302,8 @@
X 	else 
X 		slack = 18 - ((ntohs(trh->rcf) & TR_RCF_LEN_MASK)>>8);
X 	olddata = skb->data;
+	spin_unlock_irqrestore(&rif_lock, flags);
+
X 	skb_pull(skb, slack);
X 	memmove(skb->data, olddata, sizeof(struct trh_hdr) - slack);
X }
@@ -312,7 +318,11 @@
X 	int i;
X 	unsigned int hash, rii_p = 0;
X 	rif_cache entry;
+	unsigned long flags;
+
X 
+	spin_lock_irqsave(&rif_lock, flags);
+	
X 	/*
X 	 *	Firstly see if the entry exists
X 	 */
@@ -350,6 +360,7 @@
X 		if(!entry) 
X 		{
X 			printk(KERN_DEBUG "tr.c: Couldn't malloc rif cache entry !\n");
+			spin_unlock_irqrestore(&rif_lock, flags);
X 			return;
X 		}
X 
@@ -391,6 +402,7 @@
X 		    }                                         
X            	entry->last_used=jiffies;               
X 	}
+	spin_unlock_irqrestore(&rif_lock, flags);
X }
X 
X /*
@@ -402,9 +414,8 @@
X 	int i;
X 	unsigned long now=jiffies,flags;
X 
-	save_flags(flags);
-	cli();
-
+	spin_lock_irqsave(&rif_lock, flags);
+	
X 	for(i=0; i < RIF_TABLE_SIZE;i++) 
X 	{
X 		rif_cache entry, *pentry=rif_table+i;	
@@ -422,7 +433,8 @@
X 				pentry=&entry->next;
X 		}
X 	}
-	restore_flags(flags);
+	
+	spin_unlock_irqrestore(&rif_lock, flags);
X 
X 	/*
X 	 *	Reset the timer
diff -u --recursive --new-file v2.2.6/linux/net/core/neighbour.c linux/net/core/neighbour.c
--- v2.2.6/linux/net/core/neighbour.c	Mon Mar 29 11:09:12 1999
+++ linux/net/core/neighbour.c	Thu Apr 22 19:45:19 1999
@@ -1170,7 +1170,7 @@
X 	for (h=0; h <= NEIGH_HASHMASK; h++) {
X 		if (h < s_h) continue;
X 		if (h > s_h)
-			memset(&cb->args[2], 0, sizeof(cb->args) - 2*sizeof(cb->args[0]));
+			s_idx = 0;
X 		start_bh_atomic();
X 		for (n = tbl->hash_buckets[h], idx = 0; n;
X 		     n = n->next, idx++) {
@@ -1179,12 +1179,14 @@
X 			if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid,
X 					    cb->nlh->nlmsg_seq, RTM_NEWNEIGH) <= 0) {
X 				end_bh_atomic();
-				goto done;
+				cb->args[1] = h;
+				cb->args[2] = idx;
+				return -1;
X 			}
X 		}
X 		end_bh_atomic();
X 	}
-done:
+
X 	cb->args[1] = h;
X 	cb->args[2] = idx;
X 	return skb->len;
@@ -1355,10 +1357,10 @@
X 		t->neigh_dev[0].ctl_name = dev->ifindex;
X 		memset(&t->neigh_vars[12], 0, sizeof(ctl_table));
X 	} else {
-		t->neigh_vars[12].data = (&p->locktime) + 1;
-		t->neigh_vars[13].data = (&p->locktime) + 2;
-		t->neigh_vars[14].data = (&p->locktime) + 3;
-		t->neigh_vars[15].data = (&p->locktime) + 4;
+		t->neigh_vars[12].data = (int*)(p+1);
+		t->neigh_vars[13].data = (int*)(p+1) + 1;
+		t->neigh_vars[14].data = (int*)(p+1) + 2;
+		t->neigh_vars[15].data = (int*)(p+1) + 3;
X 	}
X 	t->neigh_neigh_dir[0].ctl_name = pdev_id;
X 
diff -u --recursive --new-file v2.2.6/linux/net/core/scm.c linux/net/core/scm.c
--- v2.2.6/linux/net/core/scm.c	Wed Mar 10 15:29:52 1999
+++ linux/net/core/scm.c	Thu Apr 22 19:45:19 1999
@@ -122,7 +122,15 @@
X 		err = -EINVAL;
X 
X 		/* Verify that cmsg_len is at least sizeof(struct cmsghdr) */
-		if ((unsigned long)(((char*)cmsg - (char*)msg->msg_control)
+		/* The first check was omitted in <= 2.2.5. The reasoning was
+		   that parser checks cmsg_len in any case, so that
+		   additional check would be work duplication.
+		   But if cmsg_level is not SOL_SOCKET, we do not check 
+		   for too short ancillary data object at all! Oops.
+		   OK, let's add it...
+		 */
+		if (cmsg->cmsg_len < sizeof(struct cmsghdr) ||
+		    (unsigned long)(((char*)cmsg - (char*)msg->msg_control)
X 				    + cmsg->cmsg_len) > msg->msg_controllen)
X 			goto error;
X 
diff -u --recursive --new-file v2.2.6/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- v2.2.6/linux/net/ipv4/af_inet.c	Mon Mar 29 11:09:12 1999
+++ linux/net/ipv4/af_inet.c	Thu Apr 22 19:45:19 1999
@@ -5,7 +5,7 @@
X  *
X  *		PF_INET protocol family socket handler.
X  *
- * Version:	$Id: af_inet.c,v 1.86 1999/03/25 00:38:15 davem Exp $
+ * Version:	$Id: af_inet.c,v 1.87 1999/04/22 10:07:33 davem Exp $
X  *
X  * Authors:	Ross Biro, <bi...@leland.Stanford.Edu>
X  *		Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -513,17 +513,6 @@
X 	    (sk->num != 0))
X 		return -EINVAL;
X 		
-	snum = ntohs(addr->sin_port);
-#ifdef CONFIG_IP_MASQUERADE
-	/* The kernel masquerader needs some ports. */
-	if((snum >= PORT_MASQ_BEGIN) && (snum <= PORT_MASQ_END))
-		return -EADDRINUSE;
-#endif		 
-	if (snum == 0) 
-		snum = sk->prot->good_socknum();
-	if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
-		return(-EACCES);
-	
X 	chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
X 	if (addr->sin_addr.s_addr != 0 && chk_addr_ret != RTN_LOCAL &&
X 	    chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) {
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 18'
echo 'File patch-2.2.7 is continued in part 19'
echo 19 > _shar_seq_.tmp
#!/bin/sh
# this is part 21 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 21; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
X {
X 	struct irmanager_event mgr_event;
-	struct irlan_cb *self = (struct irlan_cb *) data;
+	struct irlan_cb *self, *entry;
X 	
-	DEBUG(2, __FUNCTION__ "()\n");
+	DEBUG(0, __FUNCTION__ "()\n");
+
+	self = (struct irlan_cb *) data;
X 
X 	ASSERT(self != NULL, return;);
X 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -132,147 +134,38 @@
X 		 *  by the user.
X 		 */
X 		self->notify_irmanager = FALSE;
-	} else
-		irlan_close(self);
-}
-
-void irlan_start_watchdog_timer(struct irlan_cb *self, int timeout)
-{
-	DEBUG(4, __FUNCTION__ "()\n");
-	
-	irda_start_timer(&self->watchdog_timer, timeout, (unsigned long) self,
-			 irlan_watchdog_timer_expired);
-}
-
-/*
- * Function irlan_eth_open (dev)
- *
- *    Network device has been opened by user
- *
- */
-static int irlan_eth_open(struct device *dev)
-{
-	struct irlan_cb *self;
-	
-	DEBUG(4, __FUNCTION__ "()\n");
-
-	ASSERT(dev != NULL, return -1;);
-
-	self = (struct irlan_cb *) dev->priv;
-
-	ASSERT(self != NULL, return -1;);
-
-	/* Ready to play! */
-/* 	dev->tbusy = 0; */ /* Wait until data link is ready */
-	dev->interrupt = 0;
-	dev->start = 1;
-
-	self->notify_irmanager = TRUE;
+	} else {
+		DEBUG(0, __FUNCTION__ "(), recycling instance!\n");
+		if (self->netdev_registered) {
+			DEBUG(0, __FUNCTION__ "(), removing netdev!\n");
+			unregister_netdev(&self->dev);
+			self->netdev_registered = FALSE;
+		}
+
+		/* Unbind from daddr */
+		entry = hashbin_remove(irlan, self->daddr, NULL);
+		ASSERT(entry == self, return;);
X 
-	/* We are now open, so time to do some work */
-	irlan_client_wakeup(self, self->saddr, self->daddr);
+		self->daddr = DEV_ADDR_ANY;
+		self->saddr = DEV_ADDR_ANY;
X 
-	MOD_INC_USE_COUNT;
-	
-	return 0;
+		DEBUG(2, __FUNCTION__ "(), daddr=%08x\n", self->daddr);
+		hashbin_insert(irlan, (QUEUE*) self, self->daddr, NULL);
+	}
X }
X 
X /*
- * Function irlan_eth_close (dev)
+ * Function irlan_start_watchdog_timer (self, timeout)
X  *
- *    Stop the ether network device, his function will usually be called by
- *    ifconfig down. We should now disconnect the link, We start the 
- *    close timer, so that the instance will be removed if we are unable
- *    to discover the remote device after the disconnect.
- */
-static int irlan_eth_close(struct device *dev)
-{
-	struct irlan_cb *self = (struct irlan_cb *) dev->priv;
-
-	DEBUG(4, __FUNCTION__ "()\n");
-	
-	/* Stop device */
-	dev->tbusy = 1;
-	dev->start = 0;
-
-	MOD_DEC_USE_COUNT;
-
-	irlan_close_data_channel(self);
-
-	irlan_close_tsaps(self);
-
-	irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
-	irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);	
-	
-	irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
-
-	/* Device closed by user! */
-	if (self->notify_irmanager)
-		self->notify_irmanager = FALSE;
-	else
-		self->notify_irmanager = TRUE;
-
-	return 0;
-}
-/*
- * Function irlan_eth_init (dev)
- *
- *    The network device initialization function.
+ *    
X  *
X  */
-int irlan_eth_init(struct device *dev)
+void irlan_start_watchdog_timer(struct irlan_cb *self, int timeout)
X {
-	struct irmanager_event mgr_event;
-	struct irlan_cb *self;
-
-	DEBUG(4, __FUNCTION__"()\n");
-
-	ASSERT(dev != NULL, return -1;);
-       
-	self = (struct irlan_cb *) dev->priv;
-
-	dev->open               = irlan_eth_open;
-	dev->stop               = irlan_eth_close;
-	dev->hard_start_xmit    = irlan_eth_xmit; 
-	dev->get_stats	        = irlan_eth_get_stats;
-	dev->set_multicast_list = irlan_eth_set_multicast_list;
-
-	dev->tbusy = 1;
-	
-	ether_setup(dev);
+	DEBUG(4, __FUNCTION__ "()\n");
X 	
-	dev->tx_queue_len = TTP_MAX_QUEUE;
-
-#if 0
-	/*  
-	 *  OK, since we are emulating an IrLAN sever we will have to give
-	 *  ourself an ethernet address!
-	 *  FIXME: this must be more dynamically
-	 */
-	dev->dev_addr[0] = 0x40;
-	dev->dev_addr[1] = 0x00;
-	dev->dev_addr[2] = 0x00;
-	dev->dev_addr[3] = 0x00;
-	dev->dev_addr[4] = 0x23;
-	dev->dev_addr[5] = 0x45;
-#endif
-	/* 
-	 * Network device has now been registered, so tell irmanager about
-	 * it, so it can be configured with network parameters
-	 */
-	mgr_event.event = EVENT_IRLAN_START;
-	sprintf(mgr_event.devname, "%s", self->ifname);
-	irmanager_notify(&mgr_event);
-
-	/* 
-	 * We set this so that we only notify once, since if 
-	 * configuration of the network device fails, the user
-	 * will have to sort it out first anyway. No need to 
-	 * try again.
-	 */
-	self->notify_irmanager = FALSE;
-
-	return 0;
+	irda_start_timer(&self->watchdog_timer, timeout, (unsigned long) self,
+			 irlan_watchdog_timer_expired);
X }
X 
X /*
@@ -312,8 +205,12 @@
X 	/* Start the first IrLAN instance */
X  	new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY, FALSE);
X 
+	irlan_open_data_tsap(new);
+ 	irlan_client_open_ctrl_tsap(new);
+	irlan_provider_open_ctrl_tsap(new);
+
X 	/* Do some fast discovery! */
-	irlmp_discovery_request(8);
+	irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);
X 
X 	return 0;
X }
@@ -345,7 +242,7 @@
X {
X 	int i=0;
X 
-	DEBUG(4, __FUNCTION__ "()\n");
+	DEBUG(0, __FUNCTION__ "()\n");
X 
X 	/* Check if we should call the device eth<x> or irlan<x> */
X 	if (!eth) {
@@ -416,10 +313,6 @@
X 	irlan_next_client_state(self, IRLAN_IDLE);
X 	irlan_next_provider_state(self, IRLAN_IDLE);
X 
-	irlan_open_data_tsap(self);
-  	irlan_provider_open_ctrl_tsap(self);
-	irlan_client_open_ctrl_tsap(self);
-
X 	/* Register network device now, or wait until some later time? */
X 	if (netdev)
X 		irlan_register_netdev(self);
@@ -436,7 +329,7 @@
X  */
X static void __irlan_close(struct irlan_cb *self)
X {
-	DEBUG(2, __FUNCTION__ "()\n");
+	DEBUG(0, __FUNCTION__ "()\n");
X 	
X 	ASSERT(self != NULL, return;);
X 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -447,11 +340,13 @@
X 	/* Close all open connections and remove TSAPs */
X 	irlan_close_tsaps(self);
X 
-	if (self->netdev_registered)
+	if (self->netdev_registered) {
X 		unregister_netdev(&self->dev);
+		self->netdev_registered = FALSE;
+	}
X 	
X 	self->magic = 0;
-	kfree(self);
+ 	kfree(self);
X }
X 
X /*
@@ -464,7 +359,7 @@
X {
X 	struct irlan_cb *entry;
X 	
-	DEBUG(2, __FUNCTION__ "()\n");
+	DEBUG(0, __FUNCTION__ "()\n");
X 
X         ASSERT(self != NULL, return;);
X 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -572,7 +467,7 @@
X 
X 	switch(reason) {
X 	case LM_USER_REQUEST: /* User request */
-		irlan_close(self);
+		//irlan_close(self);
X 		break;
X 	case LM_LAP_DISCONNECT: /* Unexpected IrLAP disconnect */
X 		irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
@@ -636,7 +531,7 @@
X 	self->stsap_sel_data = self->tsap_data->stsap_sel;
X }
X 
-static void irlan_close_tsaps(struct irlan_cb *self)
+void irlan_close_tsaps(struct irlan_cb *self)
X {
X 	DEBUG(4, __FUNCTION__ "()\n");
X 
@@ -1122,12 +1017,12 @@
X }
X 
X /*
- * Function irlan_get_response_param (buf, param, value)
+ * Function irlan_extract_param (buf, name, value, len)
X  *
X  *    Extracts a single parameter name/value pair from buffer and updates
X  *    the buffer pointer to point to the next name/value pair. 
X  */
-int irlan_get_param(__u8 *buf, char *name, char *value, __u16 *len)
+int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len)
X {
X 	__u8 name_len;
X 	__u16 val_len;
@@ -1274,6 +1169,20 @@
X 		printk(KERN_WARNING "Asynchronous status\n");
X 		break;
X 	}
+}
+
+void irlan_mod_inc_use_count(void)
+{
+#ifdef MODULE
+	MOD_INC_USE_COUNT;
+#endif
+}
+
+void irlan_mod_dec_use_count(void)
+{
+#ifdef MODULE
+	MOD_DEC_USE_COUNT;
+#endif
X }
X 
X #ifdef MODULE
diff -u --recursive --new-file v2.2.6/linux/net/irda/irlan/irlan_eth.c linux/net/irda/irlan/irlan_eth.c
--- v2.2.6/linux/net/irda/irlan/irlan_eth.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irlan/irlan_eth.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Thu Oct 15 08:37:58 1998
- * Modified at:   Mon Mar 22 17:41:59 1999
+ * Modified at:   Thu Apr 22 14:26:39 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * Sources:       skeleton.c by Donald Becker <bec...@CESDIS.gsfc.nasa.gov>
X  *                slip.c by Laurence Culhane,   <l...@holmes.demon.co.uk>
@@ -27,15 +27,150 @@
X 
X #include <linux/netdevice.h>
X #include <linux/etherdevice.h>
+#include <linux/inetdevice.h>
X #include <linux/if_arp.h>
X #include <net/arp.h>
X 
X #include <net/irda/irda.h>
X #include <net/irda/irmod.h>
X #include <net/irda/irlan_common.h>
+#include <net/irda/irlan_client.h>
+#include <net/irda/irlan_event.h>
X #include <net/irda/irlan_eth.h>
X 
X /*
+ * Function irlan_eth_init (dev)
+ *
+ *    The network device initialization function.
+ *
+ */
+int irlan_eth_init(struct device *dev)
+{
+	struct irmanager_event mgr_event;
+	struct irlan_cb *self;
+
+	DEBUG(0, __FUNCTION__"()\n");
+
+	ASSERT(dev != NULL, return -1;);
+       
+	self = (struct irlan_cb *) dev->priv;
+
+	dev->open               = irlan_eth_open;
+	dev->stop               = irlan_eth_close;
+	dev->hard_start_xmit    = irlan_eth_xmit; 
+	dev->get_stats	        = irlan_eth_get_stats;
+	dev->set_multicast_list = irlan_eth_set_multicast_list;
+
+	dev->tbusy = 1;
+	
+	ether_setup(dev);
+	
+	dev->tx_queue_len = TTP_MAX_QUEUE;
+
+#if 0
+	/*  
+	 *  OK, since we are emulating an IrLAN sever we will have to give
+	 *  ourself an ethernet address!
+	 *  FIXME: this must be more dynamically
+	 */
+	dev->dev_addr[0] = 0x40;
+	dev->dev_addr[1] = 0x00;
+	dev->dev_addr[2] = 0x00;
+	dev->dev_addr[3] = 0x00;
+	dev->dev_addr[4] = 0x23;
+	dev->dev_addr[5] = 0x45;
+#endif
+	/* 
+	 * Network device has now been registered, so tell irmanager about
+	 * it, so it can be configured with network parameters
+	 */
+	mgr_event.event = EVENT_IRLAN_START;
+	sprintf(mgr_event.devname, "%s", self->ifname);
+	irmanager_notify(&mgr_event);
+
+	/* 
+	 * We set this so that we only notify once, since if 
+	 * configuration of the network device fails, the user
+	 * will have to sort it out first anyway. No need to 
+	 * try again.
+	 */
+	self->notify_irmanager = FALSE;
+
+	return 0;
+}
+
+/*
+ * Function irlan_eth_open (dev)
+ *
+ *    Network device has been opened by user
+ *
+ */
+int irlan_eth_open(struct device *dev)
+{
+	struct irlan_cb *self;
+	
+	DEBUG(0, __FUNCTION__ "()\n");
+
+	ASSERT(dev != NULL, return -1;);
+
+	self = (struct irlan_cb *) dev->priv;
+
+	ASSERT(self != NULL, return -1;);
+
+	/* Ready to play! */
+/* 	dev->tbusy = 0; */ /* Wait until data link is ready */
+	dev->interrupt = 0;
+	dev->start = 1;
+
+	self->notify_irmanager = TRUE;
+
+	/* We are now open, so time to do some work */
+	irlan_client_wakeup(self, self->saddr, self->daddr);
+
+	irlan_mod_inc_use_count();
+	
+	return 0;
+}
+
+/*
+ * Function irlan_eth_close (dev)
+ *
+ *    Stop the ether network device, his function will usually be called by
+ *    ifconfig down. We should now disconnect the link, We start the 
+ *    close timer, so that the instance will be removed if we are unable
+ *    to discover the remote device after the disconnect.
+ */
+int irlan_eth_close(struct device *dev)
+{
+	struct irlan_cb *self = (struct irlan_cb *) dev->priv;
+
+	DEBUG(0, __FUNCTION__ "()\n");
+	
+	/* Stop device */
+	dev->tbusy = 1;
+	dev->start = 0;
+
+	irlan_mod_dec_use_count();
+
+	irlan_close_data_channel(self);
+
+	irlan_close_tsaps(self);
+
+	irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
+	irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);	
+	
+	irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
+
+	/* Device closed by user! */
+	if (self->notify_irmanager)
+		self->notify_irmanager = FALSE;
+	else
+		self->notify_irmanager = TRUE;
+
+	return 0;
+}
+
+/*
X  * Function irlan_eth_tx (skb)
X  *
X  *    Transmits ethernet frames over IrDA link.
@@ -217,6 +352,30 @@
X 	memcpy(eth->h_dest, dev->dev_addr, dev->addr_len);
X 
X 	/* return 0; */
+}
+
+/*
+ * Function irlan_etc_send_gratuitous_arp (dev)
+ *
+ *    Send gratuitous ARP to announce that we have changed
+ *    hardware address, so that all peers updates their ARP tables
+ */
+void irlan_etc_send_gratuitous_arp(struct device *dev) 
+{
+	struct in_device *in_dev;
+
+	/* 
+	 * When we get a new MAC address do a gratuitous ARP. This
+	 * is useful if we have changed access points on the same
+	 * subnet.  
+	 */
+	DEBUG(4, "IrLAN: Sending gratuitous ARP\n");
+	in_dev = dev->ip_ptr;
+	arp_send(ARPOP_REQUEST, ETH_P_ARP, 
+		 in_dev->ifa_list->ifa_address,
+		 &dev, 
+		 in_dev->ifa_list->ifa_address,
+		 NULL, dev->dev_addr, NULL);
X }
X 
X /*
diff -u --recursive --new-file v2.2.6/linux/net/irda/irlan/irlan_provider.c linux/net/irda/irlan/irlan_provider.c
--- v2.2.6/linux/net/irda/irlan/irlan_provider.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irlan/irlan_provider.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Tue Apr  6 19:08:20 1999
+ * Modified at:   Thu Apr 22 14:28:52 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * Sources:       skeleton.c by Donald Becker <bec...@CESDIS.gsfc.nasa.gov>
X  *                slip.c by Laurence Culhane,   <l...@holmes.demon.co.uk>
@@ -129,7 +129,7 @@
X 	ASSERT(tsap == self->provider.tsap_ctrl,return;);
X 	ASSERT(self->provider.state == IRLAN_IDLE, return;);
X 
-	/* Check if this provider is unused */
+	/* Check if this provider is currently unused */
X 	if (self->daddr == DEV_ADDR_ANY) {
X 		/*
X 		 * Rehash instance, now we have a client (daddr) to serve.
@@ -168,14 +168,6 @@
X 	if ((self->access_type == ACCESS_PEER) && 
X 	    (self->client.state == IRLAN_IDLE))
X 		irlan_client_wakeup(self, self->saddr, self->daddr);
-
-	/* 
-	 * This provider is now in use, so start a new provider instance to
-         * serve other clients. This will also change the LM-IAS entry so that
-	 * other clients don't try to connect to us, now that we are busy.
-	 */
-	new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY, FALSE);
-	self->client.start_new_provider = FALSE;
X }
X 
X /*
@@ -231,20 +223,20 @@
X {
X 	int ret;
X 	
-	ret = irlan_provider_extract_params(self, CMD_OPEN_DATA_CHANNEL, skb);
+	ret = irlan_provider_parse_command(self, CMD_OPEN_DATA_CHANNEL, skb);
X 
X 	return ret;
X }
X 
X /*
- * Function extract_params (skb)
+ * Function parse_command (skb)
X  *
X  *    Extract all parameters from received buffer, then feed them to 
X  *    check_params for parsing
X  *
X  */
-int irlan_provider_extract_params(struct irlan_cb *self, int cmd,
-				  struct sk_buff *skb) 
+int irlan_provider_parse_command(struct irlan_cb *self, int cmd,
+				 struct sk_buff *skb) 
X {
X 	__u8 *frame;
X 	__u8 *ptr;
@@ -285,7 +277,7 @@
X 	
X 	/* For all parameters */
X  	for (i=0; i<count;i++) {
-		ret = irlan_get_param(ptr, name, value, &val_len);
+		ret = irlan_extract_param(ptr, name, value, &val_len);
X 		if (ret < 0) {
X 			DEBUG(2, __FUNCTION__ "(), IrLAN, Error!\n");
X 			break;
@@ -394,19 +386,19 @@
X  *    Register provider support so we can accept incomming connections.
X  * 
X  */
-void irlan_provider_open_ctrl_tsap(struct irlan_cb *self)
+int irlan_provider_open_ctrl_tsap(struct irlan_cb *self)
X {
X 	struct notify_t notify;
X 	struct tsap_cb *tsap;
X 	
X 	DEBUG(4, __FUNCTION__ "()\n");
X 
-	ASSERT(self != NULL, return;);
-	ASSERT(self->magic == IRLAN_MAGIC, return;);
+	ASSERT(self != NULL, return -1;);
+	ASSERT(self->magic == IRLAN_MAGIC, return -1;);
X 
X 	/* Check if already open */
X 	if (self->provider.tsap_ctrl)
-		return;
+		return -1;
X 	
X 	/*
X 	 *  First register well known control TSAP
@@ -421,11 +413,13 @@
X 	tsap = irttp_open_tsap(LSAP_ANY, 1, ¬ify);
X 	if (!tsap) {
X 		DEBUG(2, __FUNCTION__ "(), Got no tsap!\n");
-		return;
+		return -1;
X 	}
X 	self->provider.tsap_ctrl = tsap;
X 
X 	/* Register with LM-IAS */
-	irlan_ias_register(self,tsap->stsap_sel);
+	irlan_ias_register(self, tsap->stsap_sel);
+
+	return 0;
X }
X 
diff -u --recursive --new-file v2.2.6/linux/net/irda/irlan/irlan_provider_event.c linux/net/irda/irlan/irlan_provider_event.c
--- v2.2.6/linux/net/irda/irlan/irlan_provider_event.c	Wed Mar 10 15:29:52 1999
+++ linux/net/irda/irlan/irlan_provider_event.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Wed Feb  3 21:43:06 1999
+ * Modified at:   Thu Apr 22 10:46:28 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
@@ -108,8 +108,15 @@
X 	switch(event) {
X 	case IRLAN_GET_INFO_CMD:
X 		/* Be sure to use 802.3 in case of peer mode */
-		if (self->access_type == ACCESS_PEER)
+		if (self->access_type == ACCESS_PEER) {
X 			self->media = MEDIA_802_3;
+			
+			/* Check if client has started yet */
+			if (self->client.state == IRLAN_IDLE) {
+				/* This should get the client going */
+				irlmp_discovery_request(8);
+			}
+		}
X 
X 		irlan_provider_send_reply(self, CMD_GET_PROVIDER_INFO, 
X 					  RSP_SUCCESS);
@@ -165,7 +172,7 @@
X 
X 	switch(event) {
X 	case IRLAN_FILTER_CONFIG_CMD:
-		irlan_provider_extract_params(self, CMD_FILTER_OPERATION, skb);
+		irlan_provider_parse_command(self, CMD_FILTER_OPERATION, skb);
X 		irlan_provider_send_reply(self, CMD_FILTER_OPERATION, 
X 					  RSP_SUCCESS);
X 		/* Keep state */
@@ -207,7 +214,7 @@
X 
X 	switch(event) {
X 	case IRLAN_FILTER_CONFIG_CMD:
-		irlan_provider_extract_params(self, CMD_FILTER_OPERATION, skb);
+		irlan_provider_parse_command(self, CMD_FILTER_OPERATION, skb);
X 		irlan_provider_send_reply(self, CMD_FILTER_OPERATION, 
X 					  RSP_SUCCESS);
X 		break;
diff -u --recursive --new-file v2.2.6/linux/net/irda/irlap.c linux/net/irda/irlap.c
--- v2.2.6/linux/net/irda/irlap.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irlap.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Stable.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Tue Apr  6 21:07:08 1999
+ * Modified at:   Fri Apr 23 10:12:29 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, 
@@ -44,9 +44,9 @@
X #include <net/irda/irlap_comp.h>
X 
X hashbin_t *irlap = NULL;
-int sysctl_slot_timeout = SLOT_TIMEOUT;
+int sysctl_slot_timeout = SLOT_TIMEOUT * 1000 / HZ;
X 
-static void __irlap_close( struct irlap_cb *self);
+static void __irlap_close(struct irlap_cb *self);
X 
X static char *lap_reasons[] = {
X 	"ERROR, NOT USED",
@@ -301,27 +301,21 @@
X  *    IrLMP for further processing
X  *
X  */
-inline void irlap_data_indication( struct irlap_cb *self, struct sk_buff *skb) 
+inline void irlap_data_indication(struct irlap_cb *self, struct sk_buff *skb) 
X {
-	DEBUG( 4, __FUNCTION__ "()\n"); 
-
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == LAP_MAGIC, return;);
-	ASSERT( skb != NULL, return;);
-
X 	/* Hide LAP header from IrLMP layer */
-	skb_pull( skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
+	skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);
X 
X #ifdef CONFIG_IRDA_COMPRESSION
-	if ( self->qos_tx.compression.value) {
-		skb = irlap_decompress_frame( self, skb);
-		if ( !skb) {
-			DEBUG( 1, __FUNCTION__ "(), Decompress error!\n");
+	if (self->qos_tx.compression.value) {
+		skb = irlap_decompress_frame(self, skb);
+		if (!skb) {
+			DEBUG(1, __FUNCTION__ "(), Decompress error!\n");
X 			return;
X 		}
X 	}
X #endif
-	irlmp_link_data_indication( self->notify.instance, LAP_RELIABLE, skb);
+	irlmp_link_data_indication(self->notify.instance, LAP_RELIABLE, skb);
X }
X 
X /*
@@ -515,22 +509,22 @@
X 		info.discovery = discovery;
X 		
X 		/* Check if the slot timeout is within limits */
-		if ( sysctl_slot_timeout < 2) {
-			DEBUG( 1, __FUNCTION__ 
-			       "(), to low value for slot timeout!\n");
-			sysctl_slot_timeout = 2;
+		if (sysctl_slot_timeout < 20) {
+			ERROR(__FUNCTION__ 
+			      "(), to low value for slot timeout!\n");
+			sysctl_slot_timeout = 20;
X 		}
X 		/* 
X 		 * Highest value is actually 8, but we allow higher since
X 		 * some devices seems to require it.
X 		 */
-		if ( sysctl_slot_timeout > 16) {
-			DEBUG( 1, __FUNCTION__ 
-			       "(), to high value for slot timeout!\n");
-			sysctl_slot_timeout = 16;
+		if (sysctl_slot_timeout > 160) {
+			ERROR(__FUNCTION__ 
+			      "(), to high value for slot timeout!\n");
+			sysctl_slot_timeout = 160;
X 		}
X 
-		self->slot_timeout = sysctl_slot_timeout;
+		self->slot_timeout = sysctl_slot_timeout * HZ / 1000;
X 		
X 		irlap_do_event( self, DISCOVERY_REQUEST, NULL, &info);
X 	} else { 
@@ -807,24 +801,18 @@
X {
X 	int usecs;
X 	int speed;
-	int bytes = 0;
+	int bytes ;
X 	
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == LAP_MAGIC, return;);
-	ASSERT( qos != NULL, return;);
-
X 	/* Get QoS values.  */
X 	speed = qos->baud_rate.value;
X 	usecs = qos->min_turn_time.value;
X 
X 	/* No need to calculate XBOFs for speeds over 115200 bps */
-	if ( speed > 115200) {
+	if (speed > 115200) {
X 		self->mtt_required = usecs;
X 		return;
X 	}
X 	
-	DEBUG( 4, __FUNCTION__ "(), delay=%d usecs\n", usecs); 
-	
X 	/*  
X 	 *  Send additional BOF's for the next frame for the requested
X 	 *  min turn time, so now we must calculate how many chars (XBOF's) we 
@@ -832,8 +820,6 @@
X 	 */
X 	bytes = speed * usecs / 10000000;
X 
-	DEBUG( 4, __FUNCTION__ "(), xbofs delay = %d\n", bytes);
-	
X 	self->xbofs_delay = bytes;
X }
X 
@@ -1028,7 +1014,7 @@
X 	self->qos_tx.data_size.value = 64;
X 	self->qos_tx.additional_bofs.value = 11;
X 
-	irlap_flush_all_queues( self);
+	irlap_flush_all_queues(self);
X 
X 	self->disconnect_pending = FALSE;
X }
@@ -1079,11 +1065,10 @@
X 
X 	/* 
X 	 *  Initialize timeout values, some of the rules are listed on 
-	 *  page 92 in IrLAP. Divide by 10 since the kernel timers has a
-	 *  resolution of 10 ms.
+	 *  page 92 in IrLAP.
X 	 */
-	self->poll_timeout = qos->max_turn_time.value / 10;
-	self->final_timeout = qos->max_turn_time.value / 10;
+	self->poll_timeout = qos->max_turn_time.value * HZ / 1000;
+	self->final_timeout = qos->max_turn_time.value * HZ / 1000;
X 	self->wd_timeout = self->poll_timeout * 2;
X 
X #ifdef CONFIG_IRDA_COMPRESSION
diff -u --recursive --new-file v2.2.6/linux/net/irda/irlap_event.c linux/net/irda/irlap_event.c
--- v2.2.6/linux/net/irda/irlap_event.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irlap_event.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sat Aug 16 00:59:29 1997
- * Modified at:   Fri Mar 26 14:24:09 1999
+ * Modified at:   Fri Apr 23 11:55:12 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>,
@@ -40,36 +40,40 @@
X 
X #include <net/irda/irda_device.h>
X 
-static int irlap_state_ndm    ( struct irlap_cb *self, IRLAP_EVENT event, 
-				struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_query  ( struct irlap_cb *self, IRLAP_EVENT event, 
-				struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_reply  ( struct irlap_cb *self, IRLAP_EVENT event, 
-				struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_conn   ( struct irlap_cb *self, IRLAP_EVENT event, 
-				struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_setup  ( struct irlap_cb *self, IRLAP_EVENT event, 
-				struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_offline( struct irlap_cb *self, IRLAP_EVENT event, 
-				struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_xmit_p ( struct irlap_cb *self, IRLAP_EVENT event, 
-				struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_pclose ( struct irlap_cb *self, IRLAP_EVENT event, 
-				struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_nrm_p  ( struct irlap_cb *self, IRLAP_EVENT event, 
-				struct sk_buff *skb, struct irlap_info *info);
+#if CONFIG_IRDA_FAST_RR
+int sysctl_fast_poll_increase = 50;
+#endif
+
+static int irlap_state_ndm    (struct irlap_cb *self, IRLAP_EVENT event, 
+			       struct sk_buff *skb, struct irlap_info *info);
+static int irlap_state_query  (struct irlap_cb *self, IRLAP_EVENT event, 
+			       struct sk_buff *skb, struct irlap_info *info);
+static int irlap_state_reply  (struct irlap_cb *self, IRLAP_EVENT event, 
+			       struct sk_buff *skb, struct irlap_info *info);
+static int irlap_state_conn   (struct irlap_cb *self, IRLAP_EVENT event, 
+			       struct sk_buff *skb, struct irlap_info *info);
+static int irlap_state_setup  (struct irlap_cb *self, IRLAP_EVENT event, 
+			       struct sk_buff *skb, struct irlap_info *info);
+static int irlap_state_offline(struct irlap_cb *self, IRLAP_EVENT event, 
+			       struct sk_buff *skb, struct irlap_info *info);
+static int irlap_state_xmit_p (struct irlap_cb *self, IRLAP_EVENT event, 
+			       struct sk_buff *skb, struct irlap_info *info);
+static int irlap_state_pclose (struct irlap_cb *self, IRLAP_EVENT event, 
+			       struct sk_buff *skb, struct irlap_info *info);
+static int irlap_state_nrm_p  (struct irlap_cb *self, IRLAP_EVENT event, 
+			       struct sk_buff *skb, struct irlap_info *info);
X static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event, 
X 				  struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_reset  ( struct irlap_cb *self, IRLAP_EVENT event, 
-				struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_nrm_s  ( struct irlap_cb *self, IRLAP_EVENT event, 
-				struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_xmit_s ( struct irlap_cb *self, IRLAP_EVENT event, 
-				struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_sclose ( struct irlap_cb *self, IRLAP_EVENT event, 
-				struct sk_buff *skb, struct irlap_info *info);
-static int irlap_state_reset_check( struct irlap_cb *, IRLAP_EVENT event, 
-				    struct sk_buff *, struct irlap_info *);
+static int irlap_state_reset  (struct irlap_cb *self, IRLAP_EVENT event, 
+			       struct sk_buff *skb, struct irlap_info *info);
+static int irlap_state_nrm_s  (struct irlap_cb *self, IRLAP_EVENT event, 
+			       struct sk_buff *skb, struct irlap_info *info);
+static int irlap_state_xmit_s (struct irlap_cb *self, IRLAP_EVENT event, 
+			       struct sk_buff *skb, struct irlap_info *info);
+static int irlap_state_sclose (struct irlap_cb *self, IRLAP_EVENT event, 
+			       struct sk_buff *skb, struct irlap_info *info);
+static int irlap_state_reset_check(struct irlap_cb *, IRLAP_EVENT event, 
+				   struct sk_buff *, struct irlap_info *);
X 
X static const char *irlap_event[] = {
X 	"DISCOVERY_REQUEST",
@@ -145,37 +149,37 @@
X /*
X  * Function irda_poll_timer_expired (data)
X  *
- *    
- *
+ *    Poll timer has expired. Normally we must now send a RR frame to the
+ *    remote device
X  */
-static void irlap_poll_timer_expired( unsigned long data)
+static void irlap_poll_timer_expired(unsigned long data)
X {
X 	struct irlap_cb *self = (struct irlap_cb *) data;
X 	
-	ASSERT( self != NULL, return;);
- ASSERT( self->magic == LAP_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == LAP_MAGIC, return;);
X 	
-	irlap_do_event( self, POLL_TIMER_EXPIRED, NULL, NULL);
+	irlap_do_event(self, POLL_TIMER_EXPIRED, NULL, NULL);
X }
X 
-void irlap_start_poll_timer( struct irlap_cb *self, int timeout)
+void irlap_start_poll_timer(struct irlap_cb *self, int timeout)
X {
-	ASSERT( self != NULL, return;);
- ASSERT( self->magic == LAP_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == LAP_MAGIC, return;);
X 
X #ifdef CONFIG_IRDA_FAST_RR
-	if ( skb_queue_len( &self->tx_list) == 0) {
-		if ( self->fast_RR == TRUE) {
+	if (skb_queue_len(&self->tx_list) == 0) {
+		if (self->fast_RR == TRUE) {
X 			/*
X 			 *  Assert that the fast poll timer has not reached the
X 			 *  normal poll timer yet
X 			 */
-			if ( self->fast_RR_timeout < timeout) {
+			if (self->fast_RR_timeout < timeout) {
X 				/*
X 				 *  FIXME: this should be a more configurable
X 				 *         function
X 				 */
-				self->fast_RR_timeout += 15;
+				self->fast_RR_timeout += (sysctl_fast_poll_increase * HZ/1000);
X 
X 				/* Use this fast(er) timeout instead */
X 				timeout = self->fast_RR_timeout;
@@ -183,17 +187,20 @@
X 		} else {
X 			self->fast_RR = TRUE;
X 
-			/* Start with just 1 ms */
-			self->fast_RR_timeout = 1;
-			timeout = 1;
+			/* Start with just 0 ms */
+			self->fast_RR_timeout = 0;
+			timeout = 0;
X 		}
X 	} else
X 		self->fast_RR = FALSE;
X 
-	DEBUG( 4, __FUNCTION__ "(), Timeout=%d\n", timeout);
+	DEBUG(4, __FUNCTION__ "(), Timeout=%d\n", timeout);
X #endif
-	irda_start_timer( &self->poll_timer, timeout, 
-			  (unsigned long) self, irlap_poll_timer_expired);
+	if (timeout == 0)
+		irlap_do_event(self, POLL_TIMER_EXPIRED, NULL, NULL);
+	else
+		irda_start_timer(&self->poll_timer, timeout, 
+				 (unsigned long) self, irlap_poll_timer_expired);
X }
X 
X /*
@@ -338,25 +345,25 @@
X 	case DISCOVERY_REQUEST:		
X 		ASSERT( info != NULL, return -1;);
X 
-	 	if ( irda_device_is_media_busy( self->irdev)) {
+	 	if (irda_device_is_media_busy(self->irdev)) {
X  			DEBUG(0, __FUNCTION__ "(), media busy!\n"); 
X 			/* irlap->log.condition = MEDIA_BUSY; */
X 			
X 			/* Always switch state before calling upper layers */
-			irlap_next_state( self, LAP_NDM); 
+			irlap_next_state(self, LAP_NDM); 
X 			
X 			/* This will make IrLMP try again */
- 			irlap_discovery_confirm( self, NULL);
+ 			irlap_discovery_confirm(self, NULL);
X 			return 0;
X 	 	} 
X 		
X 		self->S = info->S;
X 		self->s = info->s;
-		irlap_send_discovery_xid_frame( self, info->S, info->s, TRUE,
-						info->discovery);
+		irlap_send_discovery_xid_frame(self, info->S, info->s, TRUE,
+					       info->discovery);
X 		self->s++;
X 
-		irlap_start_slot_timer( self, self->slot_timeout);
+		irlap_start_slot_timer(self, self->slot_timeout);
X 		irlap_next_state(self, LAP_QUERY);
X 		break;
X 
@@ -440,38 +447,38 @@
X 		irlap_next_state( self, LAP_QUERY); 
X 		break;
X 	case SLOT_TIMER_EXPIRED:
-		if ( self->s < self->S) {
-			irlap_send_discovery_xid_frame( self, self->S, 
-							self->s, TRUE,
-							self->discovery_cmd);
+		if (self->s < self->S) {
+			irlap_send_discovery_xid_frame(self, self->S, 
+						       self->s, TRUE,
+						       self->discovery_cmd);
X 			self->s++;
-			irlap_start_slot_timer( self, self->slot_timeout);
+			irlap_start_slot_timer(self, self->slot_timeout);
X 			
X 			/* Keep state */
-			irlap_next_state( self, LAP_QUERY);
+			irlap_next_state(self, LAP_QUERY);
X 		} else {
X 			/* This is the final slot! */
-			irlap_send_discovery_xid_frame( self, self->S, 0xff, 
-							TRUE,
-							self->discovery_cmd);
+			irlap_send_discovery_xid_frame(self, self->S, 0xff, 
+						       TRUE,
+						       self->discovery_cmd);
X 
X 			/* Always switch state before calling upper layers */
-			irlap_next_state( self, LAP_NDM);
+			irlap_next_state(self, LAP_NDM);
X 	
X 			/*
X 			 *  We are now finished with the discovery procedure, 
X 			 *  so now we must return the results
X 			 */
-			irlap_discovery_confirm( self, self->discovery_log);
+			irlap_discovery_confirm(self, self->discovery_log);
X 		}
X 		break;
X 	default:
X 		DEBUG(2, __FUNCTION__ "(), Unknown event %d, %s\n", event, 
X 		      irlap_event[event]);
X 
-		if ( skb != NULL) {
+		if (skb)
X 			dev_kfree_skb( skb);
-		}
+
X 		ret = -1;
X 		break;
X 	}
@@ -485,37 +492,37 @@
X  *    are waiting for the right time slot to send a response XID frame
X  * 
X  */
-static int irlap_state_reply( struct irlap_cb *self, IRLAP_EVENT event, 
-			      struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event, 
+			     struct sk_buff *skb, struct irlap_info *info) 
X {
X 	discovery_t *discovery_rsp;
X 	int ret=0;
X 
-	DEBUG( 4, __FUNCTION__ "()\n");
+	DEBUG(4, __FUNCTION__ "()\n");
X 
-	ASSERT( self != NULL, return -1;);
-	ASSERT( self->magic == LAP_MAGIC, return -1;);
+	ASSERT(self != NULL, return -1;);
+	ASSERT(self->magic == LAP_MAGIC, return -1;);
X 
-	switch( event) {
+	switch(event) {
X 	case QUERY_TIMER_EXPIRED:
X 		DEBUG(2, __FUNCTION__ "(), QUERY_TIMER_EXPIRED <%ld>\n",
X 		      jiffies);
-		irlap_next_state( self, LAP_NDM);
+		irlap_next_state(self, LAP_NDM);
X 		break;
X 	case RECV_DISCOVERY_XID_CMD:
-		ASSERT( info != NULL, return -1;);
+		ASSERT(info != NULL, return -1;);
X 		/*
X 		 *  Last frame?
X 		 */
-		if ( info->s == 0xff) {
-			del_timer( &self->query_timer);
+		if (info->s == 0xff) {
+			del_timer(&self->query_timer);
X 			
X 			/* info->log.condition = REMOTE; */
X 
X 			/* Always switch state before calling upper layers */
-			irlap_next_state( self, LAP_NDM);
+			irlap_next_state(self, LAP_NDM);
X 
-			irlap_discovery_indication( self, info->discovery); 
+			irlap_discovery_indication(self, info->discovery); 
X 		} else if ((info->s >= self->slot) && (!self->frame_sent)) {
X 			discovery_rsp = irlmp_get_discovery_response();
X 			discovery_rsp->daddr = info->daddr;
@@ -549,17 +556,17 @@
X  *    layer to accept or refuse connection 
X  *
X  */
-static int irlap_state_conn( struct irlap_cb *self, IRLAP_EVENT event, 
-			     struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_conn(struct irlap_cb *self, IRLAP_EVENT event, 
+			    struct sk_buff *skb, struct irlap_info *info) 
X {
X 	int ret = 0;
X 
-	DEBUG( 4, __FUNCTION__ "(), event=%s\n", irlap_event[ event]);
+	DEBUG(4, __FUNCTION__ "(), event=%s\n", irlap_event[ event]);
X 
-	ASSERT( self != NULL, return -1;);
-	ASSERT( self->magic == LAP_MAGIC, return -1;);
+	ASSERT(self != NULL, return -1;);
+	ASSERT(self->magic == LAP_MAGIC, return -1;);
X 
-	switch( event) {
+	switch (event) {
X 	case CONNECT_RESPONSE:
X 		skb_pull( skb, 11);
X 
@@ -762,7 +769,7 @@
X 	DEBUG( 4, __FUNCTION__ "(), event=%s, vs=%d, vr=%d", 
X 	       irlap_event[ event], self->vs, self->vr); 
X 		
-	switch( event) {
+	switch (event) {
X 	case SEND_I_CMD:
X 		ASSERT( skb != NULL, return -1;);
X 		DEBUG( 4, __FUNCTION__ "(), Window=%d\n", self->window);
@@ -822,7 +829,7 @@
X 		} else {
X 			DEBUG( 4, __FUNCTION__ 
X 			       "(), Unable to send! remote busy?\n");
-			skb_queue_head( &self->tx_list, skb);
+			skb_queue_head(&self->tx_list, skb);
X 
X 			/*
X 			 *  The next ret is important, because it tells 
@@ -831,19 +838,19 @@
X 			ret = -EPROTO;
X 		}
X 		break;
+	case POLL_TIMER_EXPIRED:
+		irlap_send_rr_frame(self, CMD_FRAME);
+		irlap_start_final_timer(self, self->final_timeout);
+		irlap_next_state(self, LAP_NRM_P);
+		break;
X 	case DISCONNECT_REQUEST:
-		del_timer( &self->poll_timer);
-		irlap_wait_min_turn_around( self, &self->qos_tx);
-		irlap_send_disc_frame( self);
-		irlap_flush_all_queues( self);
-		irlap_start_final_timer( self, self->final_timeout);
+		del_timer(&self->poll_timer);
+		irlap_wait_min_turn_around(self, &self->qos_tx);
+		irlap_send_disc_frame(self);
+		irlap_flush_all_queues(self);
+		irlap_start_final_timer(self, self->final_timeout);
X 		self->retry_count = 0;
-		irlap_next_state( self, LAP_PCLOSE);
-		break;
-	case POLL_TIMER_EXPIRED:
-		irlap_send_rr_frame( self, CMD_FRAME);
-		irlap_start_final_timer( self, self->final_timeout);
-		irlap_next_state( self, LAP_NRM_P);
+		irlap_next_state(self, LAP_PCLOSE);
X 		break;
X 	default:
X 		DEBUG(0, __FUNCTION__ "(), Unknown event %s\n", 
@@ -916,117 +923,18 @@
X  *   transmit any frames and is expecting to receive frames only from the
X  *   secondary to which transmission permissions has been given.
X  */
-static int irlap_state_nrm_p( struct irlap_cb *self, IRLAP_EVENT event, 
-			      struct sk_buff *skb, struct irlap_info *info) 
+static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, 
+			     struct sk_buff *skb, struct irlap_info *info) 
X {
X 	int ret = 0;
X 	int ns_status;
X 	int nr_status;
X 
-	ASSERT( self != NULL, return -1;);
-	ASSERT( self->magic == LAP_MAGIC, return -1;);
+	ASSERT(self != NULL, return -1;);
+	ASSERT(self->magic == LAP_MAGIC, return -1;);
X 
-	switch( event) {
-	case RECV_RR_RSP:
-		DEBUG( 4, __FUNCTION__ "(), RECV_RR_FRAME: "
-		       "Retrans:%d, nr=%d, va=%d, vs=%d, vr=%d\n",
-		       self->retry_count, info->nr, self->va, self->vs, 
-		       self->vr);
-
-		ASSERT( info != NULL, return -1;);
-
-		/*  
-		 *  If you get a RR, the remote isn't busy anymore, 
-		 *  no matter what the NR 
-		 */
-		self->remote_busy = FALSE;
-
-		/* 
-		 *  Nr as expected? 
-		 */
-		ret = irlap_validate_nr_received( self, info->nr);
-		if ( ret == NR_EXPECTED) {	
-			/* Stop final timer */
-			del_timer( &self->final_timer);
-			
-			/* Update Nr received */
-			irlap_update_nr_received( self, info->nr);
-			
-			/*
-			 *  Got expected NR, so reset the retry_count. This 
-			 *  is not done by the IrLAP standard , which is 
-			 *  strange! DB.
-			 */
-			self->retry_count = 0;			
-			irlap_wait_min_turn_around( self, &self->qos_tx);
-
-			/* Start poll timer */
-			irlap_start_poll_timer( self, self->poll_timeout);
-
-			irlap_next_state( self, LAP_XMIT_P);
-		} else if ( ret == NR_UNEXPECTED) {
-			ASSERT( info != NULL, return -1;);	
-			/* 
-			 *  Unexpected nr! 
-			 */
-			
-			/* Update Nr received */
-			irlap_update_nr_received( self, info->nr);
-
-			DEBUG( 4, "RECV_RR_FRAME: Retrans:%d, nr=%d, va=%d, "
-			       "vs=%d, vr=%d\n",
-			       self->retry_count, info->nr, self->va, 
-			       self->vs, self->vr);
-			
-			/* Resend rejected frames */
-			irlap_resend_rejected_frames( self, CMD_FRAME);
-			
-			/*
-			 *  Start only if not running, DB
-			 *  TODO: Should this one be here?
-			 */
-			/* if ( !self->final_timer.prev) */
-/* 				irda_start_timer( FINAL_TIMER, self->final_timeout);  */
-
-			/* Keep state */
-			irlap_next_state( self, LAP_NRM_P);
-		} else if ( ret == NR_INVALID) {
-			DEBUG(1, "irlap_state_nrm_p: received RR with "
-			      "invalid nr !\n");
-			del_timer( &self->final_timer);
-
-			irlap_next_state( self, LAP_RESET_WAIT);
-
-			irlap_disconnect_indication( self, 
-						     LAP_RESET_INDICATION);
-			self->xmitflag = TRUE;
-		}
-		if (skb)
-			dev_kfree_skb( skb);
-		break;
-	case RECV_RNR_FRAME:
-		DEBUG( 4, "irlap_state_nrm_p: RECV_RNR_FRAME: Retrans:%d, "
-		       "nr=%d, va=%d, vs=%d, vr=%d\n",
-		       self->retry_count, info->nr, self->va, self->vs, 
-		       self->vr);
-
-		ASSERT( info != NULL, return -1;);
-
-		/* Stop final timer */
-		del_timer( &self->final_timer);
-		self->remote_busy = TRUE;
-
-		/* Update Nr received */
-		irlap_update_nr_received( self, info->nr);
-			
-		/* Start poll timer */
-		irlap_start_poll_timer( self, self->poll_timeout);
-
-		irlap_next_state( self, LAP_XMIT_P);
-
-		dev_kfree_skb( skb);
-		break;
-	case RECV_I_RSP:
+	switch (event) {
+	case RECV_I_RSP: /* Optimize for the common case */
X 		/* FIXME: must check for remote_busy below */
X #ifdef CONFIG_IRDA_FAST_RR
X 		/* 
@@ -1039,8 +947,8 @@
X 
X 		ASSERT( info != NULL, return -1;);
X 
-		ns_status = irlap_validate_ns_received( self, info->ns);
-		nr_status = irlap_validate_nr_received( self, info->nr);
+		ns_status = irlap_validate_ns_received(self, info->ns);
+		nr_status = irlap_validate_nr_received(self, info->nr);
X 
X 		/* 
X 		 *  Check for expected I(nformation) frame
@@ -1049,7 +957,7 @@
X 			/* 
X 			 *  poll bit cleared?
X 			 */
-			if ( !info->pf) {
+			if (!info->pf) {
X 				self->vr = (self->vr + 1) % 8;
X 			
X 				/* Update Nr received */
@@ -1058,16 +966,16 @@
X 				self->ack_required = TRUE;
X 				
X 				/* Keep state, do not move this line */
-				irlap_next_state( self, LAP_NRM_P);
+				irlap_next_state(self, LAP_NRM_P);
X 				
-				irlap_data_indication( self, skb);
+				irlap_data_indication(self, skb);
X 			} else {
-				del_timer( &self->final_timer);
+				del_timer(&self->final_timer);
X 
X 				self->vr = (self->vr + 1) % 8;
X 			
X 				/* Update Nr received */
-				irlap_update_nr_received( self, info->nr);
+				irlap_update_nr_received(self, info->nr);
X 		
X 				/*  
X 				 *  Got expected NR, so reset the
@@ -1077,13 +985,17 @@
X 				self->retry_count = 0;
X 				self->ack_required = TRUE;
X 			
-				/* This is the last frame */
-				irlap_start_poll_timer( self, self->poll_timeout);
-				irlap_wait_min_turn_around( self, &self->qos_tx);
-				/* Do not move this line */
-				irlap_next_state( self, LAP_XMIT_P);
+				irlap_wait_min_turn_around(self, &self->qos_tx);
+				/* 
+				 * Important to switch state before calling
+				 * upper layers
+				 */
+				irlap_next_state(self, LAP_XMIT_P);
X 			
-				irlap_data_indication( self, skb);
+				irlap_data_indication(self, skb);
+
+				/* This is the last frame */
+				irlap_start_poll_timer(self, self->poll_timeout);
X 			}
X 			break;
X 			
@@ -1091,8 +1003,7 @@
X 		/*
X 		 *  Unexpected next to send (Ns)
X 		 */
-		if (( ns_status == NS_UNEXPECTED) && 
-		    ( nr_status == NR_EXPECTED)) 
+		if ((ns_status == NS_UNEXPECTED) && (nr_status == NR_EXPECTED))
X 		{
X 			if ( !info->pf) {
X 				irlap_update_nr_received( self, info->nr);
@@ -1125,8 +1036,7 @@
X 		/* 
X 		 *  Unexpected next to receive (Nr) 
X 		 */
-		if (( ns_status == NS_EXPECTED) && 
-		    ( nr_status == NR_UNEXPECTED))
+		if ((ns_status == NS_EXPECTED) && (nr_status == NR_UNEXPECTED))
X 		{
X 			if ( info->pf) {
X 				self->vr = (self->vr + 1) % 8;
@@ -1169,8 +1079,8 @@
X 		 *  Unexpected next to send (Ns) and next to receive (Nr)
X 		 *  Not documented by IrLAP!
X 		 */
-		if (( ns_status == NS_UNEXPECTED) && 
-		    ( nr_status == NR_UNEXPECTED)) 
+		if ((ns_status == NS_UNEXPECTED) && 
+		    (nr_status == NR_UNEXPECTED)) 
X 		{
X 			DEBUG( 4, "IrLAP: unexpected nr and ns!\n");
X 			if ( info->pf) {
@@ -1194,37 +1104,137 @@
X 		/*
X 		 *  Invalid NR or NS
X 		 */
-		if (( nr_status == NR_INVALID) || ( ns_status == NS_INVALID)) {
-			if ( info->pf) {
-				del_timer( &self->final_timer);
+		if ((nr_status == NR_INVALID) || (ns_status == NS_INVALID)) {
+			if (info->pf) {
+				del_timer(&self->final_timer);
X 				
-				irlap_next_state( self, LAP_RESET_WAIT);
+				irlap_next_state(self, LAP_RESET_WAIT);
X 
-				irlap_disconnect_indication( self, LAP_RESET_INDICATION);
+				irlap_disconnect_indication(self, LAP_RESET_INDICATION);
X 				self->xmitflag = TRUE;
X 			} else {
-				del_timer( &self->final_timer);
+				del_timer(&self->final_timer);
X 				
-				irlap_disconnect_indication( self, LAP_RESET_INDICATION);
+				irlap_disconnect_indication(self, LAP_RESET_INDICATION);
X 				
X 				self->xmitflag = FALSE;
X 			}
X 			break;
X 		}
X 		DEBUG(1, __FUNCTION__ "(), Not implemented!\n");
-		DEBUG(1, __FUNCTION__ "(), event=%s, ns_status=%d, nr_status=%d\n", 
-		       irlap_event[ event], ns_status, nr_status);
+		DEBUG(1, __FUNCTION__ 
+		      "(), event=%s, ns_status=%d, nr_status=%d\n", 
+		      irlap_event[ event], ns_status, nr_status);
X 		break;
X 	case RECV_UI_FRAME:
X 		/*  poll bit cleared?  */
-		if ( !info->pf) {
-			irlap_unit_data_indication( self, skb);
-			irlap_next_state( self, LAP_NRM_P);
+		if (!info->pf) {
+			irlap_unit_data_indication(self, skb);
+			irlap_next_state(self, LAP_NRM_P);
X 		} else {
+			del_timer(&self->final_timer);
+			irlap_unit_data_indication(self, skb);
+			irlap_start_poll_timer(self, self->poll_timeout);
+		}
+		break;
+	case RECV_RR_RSP:
+		DEBUG(4, __FUNCTION__ "(), RECV_RR_FRAME: "
+		      "Retrans:%d, nr=%d, va=%d, vs=%d, vr=%d\n",
+		      self->retry_count, info->nr, self->va, self->vs, 
+		      self->vr);
+
+		ASSERT(info != NULL, return -1;);
+
+		/*  
+		 *  If you get a RR, the remote isn't busy anymore, 
+		 *  no matter what the NR 
+		 */
+		self->remote_busy = FALSE;
+
+		/* 
+		 *  Nr as expected? 
+		 */
+		ret = irlap_validate_nr_received(self, info->nr);
+		if (ret == NR_EXPECTED) {	
+			/* Stop final timer */
+			del_timer(&self->final_timer);
+			
+			/* Update Nr received */
+			irlap_update_nr_received(self, info->nr);
+			
+			/*
+			 *  Got expected NR, so reset the retry_count. This 
+			 *  is not done by the IrLAP standard , which is 
+			 *  strange! DB.
+			 */
+			self->retry_count = 0;			
+			irlap_wait_min_turn_around(self, &self->qos_tx);
+
+			irlap_next_state(self, LAP_XMIT_P);
+
+			/* Start poll timer */
+			irlap_start_poll_timer(self, self->poll_timeout);
+		} else if (ret == NR_UNEXPECTED) {
+			ASSERT( info != NULL, return -1;);	
+			/* 
+			 *  Unexpected nr! 
+			 */
+			
+			/* Update Nr received */
+			irlap_update_nr_received( self, info->nr);
+
+			DEBUG( 4, "RECV_RR_FRAME: Retrans:%d, nr=%d, va=%d, "
+			       "vs=%d, vr=%d\n",
+			       self->retry_count, info->nr, self->va, 
+			       self->vs, self->vr);
+			
+			/* Resend rejected frames */
+			irlap_resend_rejected_frames( self, CMD_FRAME);
+			
+			/*
+			 *  Start only if not running, DB
+			 *  TODO: Should this one be here?
+			 */
+			/* if ( !self->final_timer.prev) */
+/* 				irda_start_timer( FINAL_TIMER, self->final_timeout);  */
+
+			/* Keep state */
+			irlap_next_state( self, LAP_NRM_P);
+		} else if (ret == NR_INVALID) {
+			DEBUG(1, "irlap_state_nrm_p: received RR with "
+			      "invalid nr !\n");
X 			del_timer( &self->final_timer);
-			irlap_unit_data_indication( self, skb);
-			irlap_start_poll_timer( self, self->poll_timeout);
+
+			irlap_next_state( self, LAP_RESET_WAIT);
+
+			irlap_disconnect_indication( self, 
+						     LAP_RESET_INDICATION);
+			self->xmitflag = TRUE;
X 		}
+		if (skb)
+			dev_kfree_skb( skb);
+		break;
+	case RECV_RNR_FRAME:
+		DEBUG( 4, "irlap_state_nrm_p: RECV_RNR_FRAME: Retrans:%d, "
+		       "nr=%d, va=%d, vs=%d, vr=%d\n",
+		       self->retry_count, info->nr, self->va, self->vs, 
+		       self->vr);
+
+		ASSERT( info != NULL, return -1;);
+
+		/* Stop final timer */
+		del_timer( &self->final_timer);
+		self->remote_busy = TRUE;
+
+		/* Update Nr received */
+		irlap_update_nr_received( self, info->nr);
+
+		irlap_next_state( self, LAP_XMIT_P);
+			
+		/* Start poll timer */
+		irlap_start_poll_timer( self, self->poll_timeout);
+
+		dev_kfree_skb( skb);
X 		break;
X 	case RECV_FRMR_RSP:
X 		del_timer( &self->final_timer);
@@ -1322,8 +1332,8 @@
X  *    awaiting reset of disconnect request.
X  *
X  */
-int irlap_state_reset_wait( struct irlap_cb *self, IRLAP_EVENT event, 
-			    struct sk_buff *skb, struct irlap_info *info)
+static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event, 
+				  struct sk_buff *skb, struct irlap_info *info)
X {
X 	int ret = 0;
X 	
@@ -1368,19 +1378,19 @@
X  *    reply.
X  *
X  */
-int irlap_state_reset( struct irlap_cb *self, IRLAP_EVENT event, 
-		       struct sk_buff *skb, struct irlap_info *info)
+static int irlap_state_reset( struct irlap_cb *self, IRLAP_EVENT event, 
+			      struct sk_buff *skb, struct irlap_info *info)
X {
X 	int ret = 0;
X 	
-	DEBUG( 3, __FUNCTION__ "(), event = %s\n", irlap_event[event]);
+	DEBUG(3, __FUNCTION__ "(), event = %s\n", irlap_event[event]);
X 	
-	ASSERT( self != NULL, return -1;);
-	ASSERT( self->magic == LAP_MAGIC, return -1;);
+	ASSERT(self != NULL, return -1;);
+	ASSERT(self->magic == LAP_MAGIC, return -1;);
X 	
-	switch( event) {
+	switch(event) {
X 	case RECV_DISC_FRAME:
-		del_timer( &self->final_timer);
+		del_timer(&self->final_timer);
X 
X 		irlap_apply_default_connection_parameters( self);
X 
@@ -1398,8 +1408,10 @@
X 		irlap_reset_confirm();
X 		
X 		self->remote_busy = FALSE;
-		irlap_start_poll_timer( self, self->poll_timeout);
+
X 		irlap_next_state( self, LAP_XMIT_P);
+
+		irlap_start_poll_timer( self, self->poll_timeout);
X 		break;
X 	case FINAL_TIMER_EXPIRED:
X 		if ( self->retry_count < 3) {
@@ -1540,53 +1552,8 @@
X 	ASSERT( self != NULL, return -1;);
X 	ASSERT( self->magic == LAP_MAGIC, return -1;);
X 
-	switch( event) {
-	case RECV_RR_CMD:
-		self->retry_count = 0;
-
-		/* 
-		 *  Nr as expected? 
-		 */
-		nr_status = irlap_validate_nr_received( self, info->nr);
-		if ( nr_status == NR_EXPECTED) {
-			if (( skb_queue_len( &self->tx_list) > 0) && 
-			    ( self->window > 0)) {
-				self->remote_busy = FALSE;
-				
-				/* Update Nr received */
-				irlap_update_nr_received( self, info->nr);
-				del_timer( &self->wd_timer);
-				
-				irlap_wait_min_turn_around( self, &self->qos_tx);
-				irlap_next_state( self, LAP_XMIT_S);
-			} else {			
-				self->remote_busy = FALSE;
-				/* Update Nr received */
-				irlap_update_nr_received( self, info->nr);
-				irlap_wait_min_turn_around( self, &self->qos_tx);
-				
-				irlap_send_rr_frame( self, RSP_FRAME);
-				
-				irlap_start_wd_timer( self, self->wd_timeout);
-				irlap_next_state( self, LAP_NRM_S);
-			}
-		} else if ( nr_status == NR_UNEXPECTED) {
-			self->remote_busy = FALSE;
-			irlap_update_nr_received( self, info->nr);
-			irlap_resend_rejected_frames( self, RSP_FRAME);
-
-			irlap_start_wd_timer( self, self->wd_timeout);
-
-			/* Keep state */
-			irlap_next_state( self, LAP_NRM_S); 
-		} else {
-			DEBUG(1, __FUNCTION__ "(), invalid nr not implemented!\n");
-		} 
-		if ( skb)
-			dev_kfree_skb( skb);
-
-		break;
-	case RECV_I_CMD:
+	switch(event) {
+	case RECV_I_CMD: /* Optimize for the common case */
X 		/* FIXME: must check for remote_busy below */
X 		DEBUG( 4, __FUNCTION__ "(), event=%s nr=%d, vs=%d, ns=%d, "
X 		       "vr=%d, pf=%d\n", irlap_event[event], info->nr, 
@@ -1765,6 +1732,51 @@
X 			}
X 		}
X 		break;
+	case RECV_RR_CMD:
+		self->retry_count = 0;
+
+		/* 
+		 *  Nr as expected? 
+		 */
+		nr_status = irlap_validate_nr_received( self, info->nr);
+		if ( nr_status == NR_EXPECTED) {
+			if (( skb_queue_len( &self->tx_list) > 0) && 
+			    ( self->window > 0)) {
+				self->remote_busy = FALSE;
+				
+				/* Update Nr received */
+				irlap_update_nr_received( self, info->nr);
+				del_timer( &self->wd_timer);
+				
+				irlap_wait_min_turn_around( self, &self->qos_tx);
+				irlap_next_state( self, LAP_XMIT_S);
+			} else {			
+				self->remote_busy = FALSE;
+				/* Update Nr received */
+				irlap_update_nr_received( self, info->nr);
+				irlap_wait_min_turn_around( self, &self->qos_tx);
+				
+				irlap_send_rr_frame( self, RSP_FRAME);
+				
+				irlap_start_wd_timer( self, self->wd_timeout);
+				irlap_next_state( self, LAP_NRM_S);
+			}
+		} else if ( nr_status == NR_UNEXPECTED) {
+			self->remote_busy = FALSE;
+			irlap_update_nr_received( self, info->nr);
+			irlap_resend_rejected_frames( self, RSP_FRAME);
+
+			irlap_start_wd_timer( self, self->wd_timeout);
+
+			/* Keep state */
+			irlap_next_state( self, LAP_NRM_S); 
+		} else {
+			DEBUG(1, __FUNCTION__ "(), invalid nr not implemented!\n");
+		} 
+		if ( skb)
+			dev_kfree_skb( skb);
+
+		break;
X 	case RECV_SNRM_CMD:
X 		del_timer( &self->wd_timer);
X 		DEBUG(1, __FUNCTION__ "(), received SNRM cmd\n");
@@ -1897,7 +1909,3 @@
X 
X 	return ret;
X }
-
-
-
-
diff -u --recursive --new-file v2.2.6/linux/net/irda/irlap_frame.c linux/net/irda/irlap_frame.c
--- v2.2.6/linux/net/irda/irlap_frame.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irlap_frame.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Tue Aug 19 10:27:26 1997
- * Modified at:   Tue Apr  6 16:35:21 1999
+ * Modified at:   Fri Apr 23 09:30:42 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Resrved.
@@ -48,13 +48,10 @@
X  *    need to do this since it's per packet relevant information.
X  *
X  */
-void irlap_insert_mtt( struct irlap_cb *self, struct sk_buff *skb)
+static inline void irlap_insert_mtt(struct irlap_cb *self, struct sk_buff *skb)
X {
X 	struct irlap_skb_cb *cb;
X 
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == LAP_MAGIC, return;);
-
X 	cb = (struct irlap_skb_cb *) skb->cb;
X 	
X 	cb->magic = LAP_MAGIC;
@@ -71,8 +68,6 @@
X 	
X 	/* Reset XBOF's delay (used only for getting min turn time) */
X 	self->xbofs_delay = 0;
-
-	DEBUG( 4, __FUNCTION__ "(), using %d xbofs\n", cb->xbofs);
X }
X 
X /*
@@ -83,10 +78,11 @@
X  */
X void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb)
X {
-	/* Some init stuff */
+	/* Some common init stuff */
X 	skb->dev = self->netdev;
X 	skb->h.raw = skb->nh.raw = skb->mac.raw = skb->data;
X  	skb->protocol = htons(ETH_P_IRDA);
+	skb->priority = TC_PRIO_BESTEFFORT;
X 
X 	/* 
X 	 * Insert MTT (min. turn time) into skb, so that the device driver 
@@ -534,13 +530,10 @@
X  *    Build and transmit RR (Receive Ready) frame. Notice that it is currently
X  *    only possible to send RR frames with the poll bit set.
X  */
-void irlap_send_rr_frame( struct irlap_cb *self, int command) 
+void irlap_send_rr_frame(struct irlap_cb *self, int command) 
X {
-	struct sk_buff *skb = NULL;
+	struct sk_buff *skb;
X 	__u8 *frame;
-	
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == LAP_MAGIC, return;);
X 
X 	skb = dev_alloc_skb(32);
X 	if (!skb)
@@ -553,8 +546,6 @@
X 
X 	frame[1] = RR | PF_BIT | (self->vr << 5);
X 
-   	DEBUG(4, __FUNCTION__ "(), vr=%d, %ld\n", self->vr, jiffies); 
-
X 	irlap_queue_xmit(self, skb);
X }
X 
@@ -569,27 +560,7 @@
X 				       struct sk_buff *skb, 
X 				       struct irlap_info *info, int command)
X {
-	__u8 *frame;
-
-	frame = skb->data;
-	info->nr = frame[1] >> 5;
-
-	DEBUG(4, __FUNCTION__ "(), nr=%d, %ld\n", info->nr, jiffies);
-
-	/*
-	 *  Make sure the state-machine is in the right state for receiving, 
-	 *  if not, then we just discard the received frame for now!
-	 *  TODO: check if we should queue this frame, or make tty tell that
-	 *  it is receiving frames until the frame is delivered instead of
-	 *  until it is outside a frame.
-	 */
-#if 0
-	if ((self->state != LAP_NRM_P) && (self->state != LAP_NRM_S)) {
-		DEBUG(0, __FUNCTION__ "(), Wrong state, dropping frame!\n");
-		dev_kfree_skb(skb);
-		return;
-	}
-#endif
+	info->nr = skb->data[1] >> 5;
X 
X 	/* Check if this is a command or a response frame */
X 	if (command)
@@ -676,16 +647,7 @@
X {
X 	struct sk_buff *tx_skb;
X 
-	DEBUG( 4, __FUNCTION__ "()\n");
-
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == LAP_MAGIC, return;);
-	ASSERT( skb != NULL, return;);
-
-	/* Initialize variables */
-	tx_skb = NULL;
-
-	if ( skb->data[1] == I_FRAME) {
+	if (skb->data[1] == I_FRAME) {
X 
X 		/*  
X 		 *  Insert frame sequence number (Vs) in control field before
@@ -693,10 +655,10 @@
X 		 */
X 		skb->data[1] = I_FRAME | (self->vs << 1);
X 		
-		/* * Copy buffer */
-		tx_skb = skb_clone( skb, GFP_ATOMIC);
-		if ( tx_skb == NULL) {
-			dev_kfree_skb( skb);
+		/* Copy buffer */
+		tx_skb = skb_clone(skb, GFP_ATOMIC);
+		if (tx_skb == NULL) {
+			dev_kfree_skb(skb);
X 			return;
X 		}
X 		
@@ -704,12 +666,12 @@
X 		 *  make sure the skb->sk accounting of memory usage is sane
X 		 */
X 		if (skb->sk != NULL)
-			skb_set_owner_w( tx_skb, skb->sk);
+			skb_set_owner_w(tx_skb, skb->sk);
X 		
X 		/* 
X 		 *  Insert frame in store, in case of retransmissions 
X 		 */
-		skb_queue_tail( &self->wx_list, skb);
+		skb_queue_tail(&self->wx_list, skb);
X 		
X 		self->vs = (self->vs + 1) % 8;
X 		self->ack_required = FALSE;		
@@ -718,7 +680,7 @@
X 		irlap_send_i_frame( self, tx_skb, CMD_FRAME);
X 	} else {
X 		DEBUG( 4, __FUNCTION__ "(), sending unreliable frame\n");
-		irlap_send_ui_frame( self, skb, CMD_FRAME);
+		irlap_send_ui_frame(self, skb, CMD_FRAME);
X 		self->window -= 1;
X 	}
X }
@@ -731,17 +693,8 @@
X {
X 	struct sk_buff *tx_skb;
X 
-	DEBUG( 4, __FUNCTION__ "()\n");
-
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == LAP_MAGIC, return;);
-	ASSERT( skb != NULL, return;);
-
-	/* Initialize variables */
-	tx_skb = NULL;
-
X 	/* Is this reliable or unreliable data? */
-	if ( skb->data[1] == I_FRAME) {
+	if (skb->data[1] == I_FRAME) {
X 		
X 		/*  
X 		 *  Insert frame sequence number (Vs) in control field before
@@ -750,9 +703,9 @@
X 		skb->data[1] = I_FRAME | (self->vs << 1);
X 		
X 		/* Copy buffer */
-		tx_skb = skb_clone( skb, GFP_ATOMIC);
-		if ( tx_skb == NULL) {
-			dev_kfree_skb( skb);
+		tx_skb = skb_clone(skb, GFP_ATOMIC);
+		if (tx_skb == NULL) {
+			dev_kfree_skb(skb);
X 			return;
X 		}
X 		
@@ -760,20 +713,20 @@
X 		 *  make sure the skb->sk accounting of memory usage is sane
X 		 */
X 		if (skb->sk != NULL)
-			skb_set_owner_w( tx_skb, skb->sk);
+			skb_set_owner_w(tx_skb, skb->sk);
X 		
X 		/* 
X 		 *  Insert frame in store, in case of retransmissions 
X 		 */
-		skb_queue_tail( &self->wx_list, skb);
+		skb_queue_tail(&self->wx_list, skb);
X 		
X 		/*  
X 		 *  Set poll bit if necessary. We do this to the copied
X 		 *  skb, since retransmitted need to set or clear the poll
-		 *  bit depending on when * they are sent.  
+		 *  bit depending on when they are sent.  
X 		 */
X 		/* Stop P timer */
-		del_timer( &self->poll_timer);
+		del_timer(&self->poll_timer);
X 		
X 		tx_skb->data[1] |= PF_BIT;
X 		
@@ -781,24 +734,24 @@
X 		self->ack_required = FALSE;
X 		self->window = self->window_size;
X 
-		irlap_start_final_timer( self, self->final_timeout);
+		irlap_start_final_timer(self, self->final_timeout);
X 
-		irlap_send_i_frame( self, tx_skb, CMD_FRAME);
+		irlap_send_i_frame(self, tx_skb, CMD_FRAME);
X 	} else {
-		DEBUG( 4, __FUNCTION__ "(), sending unreliable frame\n");
+		DEBUG(4, __FUNCTION__ "(), sending unreliable frame\n");
X 
-		del_timer( &self->poll_timer);
+		del_timer(&self->poll_timer);
X 
-		if ( self->ack_required) {
-			irlap_send_ui_frame( self, skb, CMD_FRAME);
-			irlap_send_rr_frame( self, CMD_FRAME);
+		if (self->ack_required) {
+			irlap_send_ui_frame(self, skb, CMD_FRAME);
+			irlap_send_rr_frame(self, CMD_FRAME);
X 			self->ack_required = FALSE;
X 		} else {
X 			skb->data[1] |= PF_BIT;
-			irlap_send_ui_frame( self, skb, CMD_FRAME);
+			irlap_send_ui_frame(self, skb, CMD_FRAME);
X 		}
X 		self->window = self->window_size;
-		irlap_start_final_timer( self, self->final_timeout);
+		irlap_start_final_timer(self, self->final_timeout);
X 	}
X }
X 
@@ -926,7 +879,7 @@
X 	ASSERT( self != NULL, return;);
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 21'
echo 'File patch-2.2.7 is continued in part 22'
echo 22 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 22 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 22; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
X 	ASSERT( self->magic == LAP_MAGIC, return;);
X 
-	DEBUG( 4, __FUNCTION__ "(), retry_count=%d\n", self->retry_count);
+	DEBUG(2, __FUNCTION__ "(), retry_count=%d\n", self->retry_count);
X 
X 	/* Initialize variables */
X 	skb = tx_skb = NULL;
@@ -939,7 +892,11 @@
X 	while ( skb != NULL) {
X 		irlap_wait_min_turn_around( self, &self->qos_tx);
X 
-		tx_skb = skb_clone( skb, GFP_ATOMIC);
+		/* We copy the skb to be retransmitted since we will have to 
+		 * modify it. Cloning will confuse packet sniffers 
+		 */
+		/* tx_skb = skb_clone( skb, GFP_ATOMIC); */
+		tx_skb = skb_copy(skb, GFP_ATOMIC);
X 		if ( tx_skb == NULL) {
X 			/* Unlink tx_skb from list */
X 			tx_skb->next = tx_skb->prev = NULL;
@@ -997,12 +954,12 @@
X 			 *  If send window > 1 then send frame with pf 
X 			 *  bit cleared
X 			 */ 
-			if (( self->window > 1) && 
-			    skb_queue_len( &self->tx_list) > 0) 
+			if ((self->window > 1) && 
+			    skb_queue_len(&self->tx_list) > 0) 
X 			{
-				irlap_send_data_primary( self, skb);
+				irlap_send_data_primary(self, skb);
X 			} else {
-				irlap_send_data_primary_poll( self, skb);
+				irlap_send_data_primary_poll(self, skb);
X 			}
X 		}
X 	}
@@ -1057,6 +1014,15 @@
X 	/* Insert next to receive (Vr) */
X 	frame[1] |= (self->vr << 5);  /* insert nr */
X 
+#if 0
+	{
+		int ns;
+		ns = (frame[1] >> 1) & 0x07; /* Next to send */
+
+		DEBUG(0, __FUNCTION__ "(), ns=%d\n", ns);
+	}
+#endif
+
X 	irlap_queue_xmit(self, skb);
X }
X 
@@ -1070,30 +1036,13 @@
X 				      struct sk_buff *skb, 
X 				      struct irlap_info *info, int command) 
X {
-	__u8 *frame;
-
-	frame = skb->data;
-
-	info->nr = frame[1] >> 5;          /* Next to receive */
-	info->pf = frame[1] & PF_BIT;      /* Final bit */
-	info->ns = (frame[1] >> 1) & 0x07; /* Next to send */
+	info->nr = skb->data[1] >> 5;          /* Next to receive */
+	info->pf = skb->data[1] & PF_BIT;      /* Final bit */
+	info->ns = (skb->data[1] >> 1) & 0x07; /* Next to send */
X 
X  	DEBUG(4, __FUNCTION__"(), ns=%d, nr=%d, pf=%d, %ld\n", 
X 	      info->ns, info->nr, info->pf>>4, jiffies); 
X 
-	/*
-	 *  Make sure the state-machine is in the right state for receiving, 
-	 *  if not, then we just discard the received frame for now!
-	 *  TODO: check if we should queue this frame, or make tty tell that
-	 *  it is receiving frames until the frame is delivered instead of
-	 *  until it is outside a frame.
-	 */
- if ((self->state != LAP_NRM_P) && ( self->state != LAP_NRM_S)) {
-		DEBUG(0, __FUNCTION__ "(), Wrong state, dropping frame!\n");
-		dev_kfree_skb(skb);
-		return;
-	}
-
X 	/* Check if this is a command or a response frame */
X 	if (command)
X 		irlap_do_event(self, RECV_I_CMD, skb, info);
@@ -1266,7 +1215,7 @@
X 
X 	ASSERT( self != NULL, return -1;);
X 	ASSERT( self->magic == LAP_MAGIC, return -1;);
-	ASSERT(( skb != NULL) && (skb->len > 1), return -1;);
+	ASSERT( skb->len > 1, return -1;);
X 	
X 	frame = skb->data;
X 
diff -u --recursive --new-file v2.2.6/linux/net/irda/irlmp.c linux/net/irda/irlmp.c
--- v2.2.6/linux/net/irda/irlmp.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irlmp.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Stable.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun Aug 17 20:54:32 1997
- * Modified at:   Wed Apr  7 17:31:48 1999
+ * Modified at:   Fri Apr 23 09:13:24 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, 
@@ -719,9 +719,12 @@
X  */
X void irlmp_discovery_request(int nslots)
X {
-
X 	DEBUG(4, __FUNCTION__ "(), nslots=%d\n", nslots);
X 
+	/* Check if user wants to override the default */
+	if (nslots == DISCOVERY_DEFAULT_SLOTS)
+		nslots = sysctl_discovery_slots;
+
X 	/* 
X 	 * If discovery is already running, then just return the current 
X 	 * discovery log
@@ -877,10 +880,8 @@
X  *    Send some data to peer device
X  *
X  */
-void irlmp_data_request( struct lsap_cb *self, struct sk_buff *skb) 
+void irlmp_data_request(struct lsap_cb *self, struct sk_buff *skb) 
X {
- 	DEBUG(4, __FUNCTION__ "()\n"); 
-
X ASSERT(skb != NULL, return;);
X 	ASSERT(self != NULL, return;);
X 	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
@@ -898,14 +899,8 @@
X  *    Got data from LAP layer so pass it up to upper layer
X  *
X  */
-void irlmp_data_indication(struct lsap_cb *self, struct sk_buff *skb) 
+inline void irlmp_data_indication(struct lsap_cb *self, struct sk_buff *skb) 
X {
- 	DEBUG(4, __FUNCTION__ "()\n"); 
-
-	ASSERT(self != NULL, return;);
-	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
-	ASSERT(skb != NULL, return;);
-
X 	/* Hide LMP header from layer above */
X 	skb_pull(skb, LMP_HEADER);
X 
diff -u --recursive --new-file v2.2.6/linux/net/irda/irlmp_event.c linux/net/irda/irlmp_event.c
--- v2.2.6/linux/net/irda/irlmp_event.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irlmp_event.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Thu Apr  8 16:26:41 1999
+ * Modified at:   Fri Apr 23 08:57:23 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, 
@@ -114,16 +114,16 @@
X };
X 
X /* Do connection control events */
-void irlmp_do_lsap_event( struct lsap_cb *self, IRLMP_EVENT event, 
-			  struct sk_buff *skb)
+void irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event, 
+			 struct sk_buff *skb)
X {
-	ASSERT( self != NULL, return;);
- ASSERT( self->magic == LMP_LSAP_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
X 
-	DEBUG( 4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n",
-	       irlmp_event[ event], irlmp_state[ self->lsap_state]);
+	DEBUG(4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n",
+	      irlmp_event[ event], irlmp_state[ self->lsap_state]);
X 
-	(*lsap_state[ self->lsap_state]) ( self, event, skb);
+	(*lsap_state[self->lsap_state]) (self, event, skb);
X }
X 
X /*
@@ -132,23 +132,21 @@
X  *    Do IrLAP control events
X  *
X  */
-void irlmp_do_lap_event( struct lap_cb *self, IRLMP_EVENT event, 
-			 struct sk_buff *skb) 
+void irlmp_do_lap_event(struct lap_cb *self, IRLMP_EVENT event, 
+			struct sk_buff *skb) 
X {
-	ASSERT( self != NULL, return;);
- ASSERT( self->magic == LMP_LAP_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == LMP_LAP_MAGIC, return;);
X 	
-	DEBUG( 4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n",
-	       irlmp_event[event], 
-	       irlmp_state[self->lap_state]);
+	DEBUG(4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n",
+	      irlmp_event[event], 
+	      irlmp_state[self->lap_state]);
X 
-	(*lap_state[ self->lap_state]) ( self, event, skb);
+	(*lap_state[self->lap_state]) (self, event, skb);
X }
X 
X void irlmp_discovery_timer_expired( unsigned long data)
X {
-/* 	struct irlmp_cb *self = ( struct irlmp_cb *) data; */
-	
X 	DEBUG(4, "IrLMP, discovery timer expired!\n");
X 	
X 	if (sysctl_discovery)
@@ -306,8 +304,8 @@
X  *    ACTIVE, IrLAP connection is active
X  *
X  */
-static void irlmp_state_active( struct lap_cb *self, IRLMP_EVENT event, 
-				struct sk_buff *skb)
+static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event, 
+			       struct sk_buff *skb)
X {
X 	struct lsap_cb *lsap;
X 	struct lsap_cb *lsap_current;
@@ -343,7 +341,7 @@
X 		/* Keep state */
X 		break;
X 	case LM_LAP_DISCONNECT_REQUEST:
-		DEBUG( 4, __FUNCTION__ "(), LM_LAP_DISCONNECT_REQUEST\n");
+		DEBUG(4, __FUNCTION__ "(), LM_LAP_DISCONNECT_REQUEST\n");
X 
X 		/*
X 		 *  Need to find out if we should close IrLAP or not. If there
@@ -357,7 +355,7 @@
X 		break;
X 	case LM_LAP_IDLE_TIMEOUT:
X 		if (hashbin_get_size(self->lsaps) == 0) {
-			DEBUG(0, __FUNCTION__ 
+			DEBUG(2, __FUNCTION__ 
X 			      "(), no more LSAPs so time to close IrLAP\n");
X 			irlmp_next_lap_state(self, LAP_STANDBY);
X 			
@@ -365,7 +363,7 @@
X 		}
X 		break;
X 	case LM_LAP_DISCONNECT_INDICATION:
-		DEBUG( 4, __FUNCTION__ "(), IRLAP_DISCONNECT_INDICATION\n");
+		DEBUG(4, __FUNCTION__ "(), IRLAP_DISCONNECT_INDICATION\n");
X 	
X 		irlmp_next_lap_state( self, LAP_STANDBY);		
X 		
@@ -525,18 +523,36 @@
X  *    DATA_TRANSFER_READY
X  *
X  */
-static void irlmp_state_dtr( struct lsap_cb *self, IRLMP_EVENT event, 
-			     struct sk_buff *skb) 
+static void irlmp_state_dtr(struct lsap_cb *self, IRLMP_EVENT event, 
+			    struct sk_buff *skb) 
X {
X LM_REASON reason;
X 
- 	DEBUG( 4, __FUNCTION__ "()\n");
+ 	DEBUG(4, __FUNCTION__ "()\n");
X 
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == LMP_LSAP_MAGIC, return;);
-	ASSERT( self->lap != NULL, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == LMP_LSAP_MAGIC, return;);
+	ASSERT(self->lap != NULL, return;);
X 
-	switch( event) {
+	switch (event) {
+	case LM_DATA_REQUEST: /* Optimize for the common case */
+		irlmp_send_data_pdu(self->lap, self->dlsap_sel, 
+				    self->slsap_sel, FALSE, skb);
+		/* irlmp_next_lsap_state( DATA_TRANSFER_READY, info->handle);*/
+		break;
+	case LM_DATA_INDICATION: /* Optimize for the common case */
+		irlmp_data_indication(self, skb); 
+		/* irlmp_next_lsap_state( DATA_TRANSFER_READY, info->handle);*/
+		break;
+	case LM_UDATA_REQUEST:
+		ASSERT(skb != NULL, return;);
+		irlmp_send_data_pdu(self->lap, self->dlsap_sel, 
+				    self->slsap_sel, TRUE, skb);
+		break;
+	case LM_UDATA_INDICATION:
+		irlmp_udata_indication(self, skb); 
+		/* irlmp_next_lsap_state( DATA_TRANSFER_READY, info->handle);*/
+		break;
X 	case LM_CONNECT_REQUEST:
X 		DEBUG(0, __FUNCTION__ "(), LM_CONNECT_REQUEST, "
X 		      "error, LSAP already connected\n");
@@ -548,65 +564,45 @@
X 		/* Keep state */
X 		break;
X 	case LM_DISCONNECT_REQUEST:
-		ASSERT( skb != NULL, return;);
+		ASSERT(skb != NULL, return;);
X 
-		irlmp_send_lcf_pdu( self->lap, self->dlsap_sel, 
-				    self->slsap_sel, DISCONNECT, skb);
-		irlmp_next_lsap_state( self, LSAP_DISCONNECTED);
+		irlmp_send_lcf_pdu(self->lap, self->dlsap_sel, 
+				   self->slsap_sel, DISCONNECT, skb);
+		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
X 		
X 		/* Try to close the LAP connection if its still there */
-		if ( self->lap) {
-			DEBUG( 4, __FUNCTION__ "(), trying to close IrLAP\n");
-			irlmp_do_lap_event( self->lap, 
-					    LM_LAP_DISCONNECT_REQUEST, 
-					    NULL);
+		if (self->lap) {
+			DEBUG(4, __FUNCTION__ "(), trying to close IrLAP\n");
+			irlmp_do_lap_event(self->lap, 
+					   LM_LAP_DISCONNECT_REQUEST, 
+					   NULL);
X 		}
-
-		break;
-	case LM_DATA_REQUEST:
-		ASSERT( skb != NULL, return;);
-		irlmp_send_data_pdu( self->lap, self->dlsap_sel, 
-				     self->slsap_sel, FALSE, skb);
-		/* irlmp_next_lsap_state( DATA_TRANSFER_READY, info->handle);*/
-		break;
-	case LM_UDATA_REQUEST:
-		ASSERT( skb != NULL, return;);
-		irlmp_send_data_pdu( self->lap, self->dlsap_sel, 
-				     self->slsap_sel, TRUE, skb);
-		break;
-	case LM_DATA_INDICATION:
-		irlmp_data_indication( self, skb); 
-		/* irlmp_next_lsap_state( DATA_TRANSFER_READY, info->handle);*/
-		break;
-	case LM_UDATA_INDICATION:
-		irlmp_udata_indication( self, skb); 
-		/* irlmp_next_lsap_state( DATA_TRANSFER_READY, info->handle);*/
X 		break;
X 	case LM_LAP_DISCONNECT_INDICATION:
-		irlmp_next_lsap_state( self, LSAP_DISCONNECTED);
+		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
X 
-		reason = irlmp_convert_lap_reason( self->lap->reason);
+		reason = irlmp_convert_lap_reason(self->lap->reason);
X 
-		irlmp_disconnect_indication( self, reason, NULL);
+		irlmp_disconnect_indication(self, reason, NULL);
X 		break;
X 	case LM_DISCONNECT_INDICATION:
-		irlmp_next_lsap_state( self, LSAP_DISCONNECTED);
+		irlmp_next_lsap_state(self, LSAP_DISCONNECTED);
X 			
-		ASSERT( self->lap != NULL, return;);
-		ASSERT( self->lap->magic == LMP_LAP_MAGIC, return;);
+		ASSERT(self->lap != NULL, return;);
+		ASSERT(self->lap->magic == LMP_LAP_MAGIC, return;);
X 	
X 		ASSERT(skb != NULL, return;);
X 		ASSERT(skb->len > 3, return;);
X 		reason = skb->data[3];
X 
X 		 /* Try to close the LAP connection */
-		DEBUG( 4, __FUNCTION__ "(), trying to close IrLAP\n");
+		DEBUG(4, __FUNCTION__ "(), trying to close IrLAP\n");
X 		irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL);
X 
-		irlmp_disconnect_indication( self, reason, skb);
+		irlmp_disconnect_indication(self, reason, skb);
X 		break;
X 	default:
-		DEBUG( 4, __FUNCTION__ "(), Unknown event %d\n", event);
+		DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event);
X 		break;	
X 	}	
X }
diff -u --recursive --new-file v2.2.6/linux/net/irda/irlmp_frame.c linux/net/irda/irlmp_frame.c
--- v2.2.6/linux/net/irda/irlmp_frame.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irlmp_frame.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Tue Aug 19 02:09:59 1997
- * Modified at:   Tue Apr  6 18:31:11 1999
+ * Modified at:   Fri Apr 23 09:12:23 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>
@@ -34,30 +34,24 @@
X #include <net/irda/irlmp_frame.h>
X #include <net/irda/discovery.h>
X 
-static struct lsap_cb *irlmp_find_lsap( struct lap_cb *self, __u8 dlsap, 
-					__u8 slsap, int status, hashbin_t *);
+static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap, 
+				       __u8 slsap, int status, hashbin_t *);
X 
-inline void irlmp_send_data_pdu( struct lap_cb *self, __u8 dlsap, __u8 slsap,
-				 int expedited, struct sk_buff *skb)
+inline void irlmp_send_data_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap,
+				int expedited, struct sk_buff *skb)
X {
X 	__u8 *frame;
X 
-	ASSERT( self != NULL, return;);
- ASSERT( self->magic == LMP_LAP_MAGIC, return;);
-	ASSERT( skb != NULL, return;);
-
X 	frame = skb->data;
X 
X 	frame[0] = dlsap;
X 	frame[1] = slsap;
X 
-	if ( expedited) {
+	if (expedited) {
X 		DEBUG( 4, __FUNCTION__ "(), sending expedited data\n");
X 		irlap_data_request( self->irlap, skb, FALSE);
-	} else {
-		DEBUG( 4, __FUNCTION__ "(), sending reliable data\n");
-		irlap_data_request( self->irlap, skb, TRUE);	
-	}
+	} else
+		irlap_data_request( self->irlap, skb, TRUE);
X }
X 
X /*
@@ -98,18 +92,17 @@
X  *    Used by IrLAP to pass received data frames to IrLMP layer
X  *
X  */
-void irlmp_link_data_indication( struct lap_cb *self, int reliable, 
-				 struct sk_buff *skb)
+void irlmp_link_data_indication(struct lap_cb *self, int reliable, 
+			        struct sk_buff *skb)
X {
-	__u8 *fp;
-	__u8  slsap_sel;   /* Source (this) LSAP address */
-	__u8  dlsap_sel;   /* Destination LSAP address */
X 	struct lsap_cb *lsap;
+	__u8   slsap_sel;   /* Source (this) LSAP address */
+	__u8   dlsap_sel;   /* Destination LSAP address */
+	__u8   *fp;
X 	
-	ASSERT( self != NULL, return;);
- ASSERT( self->magic == LMP_LAP_MAGIC, return;);
-	ASSERT( skb != NULL, return;);
- ASSERT( skb->len > 2, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == LMP_LAP_MAGIC, return;);
+	ASSERT(skb->len > 2, return;);
X 
X 	fp = skb->data;
X 
@@ -124,7 +117,7 @@
X 	 *  Check if this is an incoming connection, since we must deal with
X 	 *  it in a different way than other established connections.
X 	 */
-	if ((fp[0] & CONTROL_BIT) && ( fp[2] == CONNECT_CMD)) {
+	if ((fp[0] & CONTROL_BIT) && (fp[2] == CONNECT_CMD)) {
X 		DEBUG(3,"Incoming connection, source LSAP=%d, dest LSAP=%d\n",
X 		      slsap_sel, dlsap_sel);
X 		
@@ -184,10 +177,17 @@
X 			break;
X 		}
X 	} else if (reliable == LAP_RELIABLE) {
-		/* Must be pure data */
-		irlmp_do_lsap_event( lsap, LM_DATA_INDICATION, skb);
+		/* Optimize and bypass the state machine if possible */
+		if (lsap->lsap_state == LSAP_DATA_TRANSFER_READY)
+			irlmp_data_indication(lsap, skb);
+		else
+			irlmp_do_lsap_event(lsap, LM_DATA_INDICATION, skb);
X 	} else if (reliable == LAP_UNRELIABLE) {
-		irlmp_do_lsap_event( lsap, LM_UDATA_INDICATION, skb);
+		/* Optimize and bypass the state machine if possible */
+		if (lsap->lsap_state == LSAP_DATA_TRANSFER_READY)
+			irlmp_data_indication(lsap, skb);
+		else
+			irlmp_do_lsap_event(lsap, LM_UDATA_INDICATION, skb);
X 	}
X }
X 
@@ -297,8 +297,6 @@
X 	irlmp_add_discovery_log(irlmp->cachelog, log);
X       
X 	irlmp_do_lap_event(self, LM_LAP_DISCOVERY_CONFIRM, NULL);
-
-	DEBUG( 4, __FUNCTION__ "() -->\n");
X }
X 
X #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
@@ -324,36 +322,31 @@
X {
X 	struct lsap_cb *lsap;
X 	
-	ASSERT( self != NULL, return NULL;);
-	ASSERT( self->magic == LMP_LAP_MAGIC, return NULL;);
-
X 	/* 
X 	 *  Optimize for the common case. We assume that the last frame
X 	 *  received is in the same connection as the last one, so check in
X 	 *  cache first to avoid the linear search
X 	 */
X #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
-	if (( irlmp->cache.valid) && 
-	    ( irlmp->cache.slsap_sel == slsap_sel) && 
-	    ( irlmp->cache.dlsap_sel == dlsap_sel)) 
+	if ((irlmp->cache.valid) && 
+	    (irlmp->cache.slsap_sel == slsap_sel) && 
+	    (irlmp->cache.dlsap_sel == dlsap_sel)) 
X 	{
X 		return (irlmp->cache.lsap);
X 	}
X #endif
-	lsap = ( struct lsap_cb *) hashbin_get_first(queue);
-	while ( lsap != NULL) {
+	lsap = (struct lsap_cb *) hashbin_get_first(queue);
+	while (lsap != NULL) {
X 		/* 
X 		 *  If this is an incomming connection, then the destination 
X 		 *  LSAP selector may have been specified as LM_ANY so that 
X 		 *  any client can connect. In that case we only need to check
X 		 *  if the source LSAP (in our view!) match!
X 		 */
-		if (( status == CONNECT_CMD) && 
-		    ( lsap->slsap_sel == slsap_sel) &&      
-		    ( lsap->dlsap_sel == LSAP_ANY)) 
+		if ((status == CONNECT_CMD) && 
+		    (lsap->slsap_sel == slsap_sel) &&      
+		    (lsap->dlsap_sel == LSAP_ANY)) 
X 		{
-			DEBUG( 4,"Incoming connection: Setting dlsap_sel=%d\n",
-			       dlsap_sel);
X 			lsap->dlsap_sel = dlsap_sel;
X 			
X #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
@@ -364,15 +357,15 @@
X 		/*
X 		 *  Check if source LSAP and dest LSAP selectors match.
X 		 */
-		if (( lsap->slsap_sel == slsap_sel) && 
-		    ( lsap->dlsap_sel == dlsap_sel)) 
+		if ((lsap->slsap_sel == slsap_sel) && 
+		    (lsap->dlsap_sel == dlsap_sel)) 
X 		{
X #ifdef CONFIG_IRDA_CACHE_LAST_LSAP
-			irlmp_update_cache( lsap);
+			irlmp_update_cache(lsap);
X #endif
X 			return lsap;
X 		}
-		lsap = ( struct lsap_cb *) hashbin_get_next( queue);
+		lsap = ( struct lsap_cb *) hashbin_get_next(queue);
X 	}
X 
X 	/* Sorry not found! */
diff -u --recursive --new-file v2.2.6/linux/net/irda/irlpt/irlpt_cli.c linux/net/irda/irlpt/irlpt_cli.c
--- v2.2.6/linux/net/irda/irlpt/irlpt_cli.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irlpt/irlpt_cli.c	Sat Apr 24 17:50:06 1999
@@ -518,8 +518,8 @@
X  *    Fixed to match changes in iriap.h, DB.
X  *
X  */
-void irlpt_client_get_value_confirm(__u16 obj_id, struct ias_value *value, 
-				    void *priv)
+void irlpt_client_get_value_confirm(int result, __u16 obj_id, 
+				    struct ias_value *value, void *priv)
X {
X 	struct irlpt_info info;
X 	struct irlpt_cb *self;
@@ -534,7 +534,7 @@
X 	ASSERT( self->magic == IRLPT_MAGIC, return;);
X 
X 	/* Check if request succeeded */
-	if ( !value) {
+	if (result != IAS_SUCCESS) {
X 		DEBUG( 0, __FUNCTION__ "(), got NULL value!\n");
X 		irlpt_client_do_event( self, IAS_PROVIDER_NOT_AVAIL, NULL, 
X 				       &info);
diff -u --recursive --new-file v2.2.6/linux/net/irda/irmod.c linux/net/irda/irmod.c
--- v2.2.6/linux/net/irda/irmod.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irmod.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Mon Dec 15 13:55:39 1997
- * Modified at:   Mon Mar 29 09:06:52 1999
+ * Modified at:   Mon Apr 12 11:31:01 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1997 Dag Brattli, All Rights Reserved.
@@ -50,12 +50,12 @@
X struct irda_cb irda; /* One global instance */
X 
X #ifdef CONFIG_IRDA_DEBUG
-__u32 irda_debug = IRDA_DEBUG;
+__u32 irda_debug = IRDA_DEBUG_LEVEL;
X #endif
X 
X extern void irda_proc_register(void);
X extern void irda_proc_unregister(void);
-extern int irda_sysctl_register(void);
+extern int  irda_sysctl_register(void);
X extern void irda_sysctl_unregister(void);
X 
X extern void irda_proto_init(struct net_proto *pro);
@@ -265,22 +265,6 @@
X 	irlmp_cleanup();
X }
X #endif /* MODULE */
-
-/*
- * Function irda_lock (lock)
- *
- *    Lock variable. Returns false if the lock is already set.
- *    
- */
-inline int irda_lock(int *lock) 
-{
-	if (test_and_set_bit( 0, (void *) lock))  {
-		DEBUG(3, __FUNCTION__ 
-		      "(), Trying to lock, already locked variable!\n");
-		return FALSE;
-        }  
-	return TRUE;
-}
X 
X /*
X  * Function irda_unlock (lock)
diff -u --recursive --new-file v2.2.6/linux/net/irda/irsysctl.c linux/net/irda/irsysctl.c
--- v2.2.6/linux/net/irda/irsysctl.c	Wed Mar 10 15:29:53 1999
+++ linux/net/irda/irsysctl.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun May 24 22:12:06 1998
- * Modified at:   Mon Jan 25 13:55:54 1999
+ * Modified at:   Fri Apr 23 09:46:38 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1997 Dag Brattli, All Rights Reserved.
@@ -36,6 +36,7 @@
X extern int sysctl_discovery;
X extern int sysctl_discovery_slots;
X extern int sysctl_slot_timeout;
+extern int sysctl_fast_poll_increase;
X int sysctl_compression = 0;
X extern char sysctl_devname[];
X 
@@ -52,7 +53,11 @@
X 	{ COMPRESSION, "compression", &sysctl_compression,
X 	  sizeof(int), 0644, NULL, &proc_dointvec },
X #ifdef CONFIG_IRDA_DEBUG
-	{ DEBUG, "debug", &irda_debug,
+        { DEBUG, "debug", &irda_debug,
+	  sizeof(int), 0644, NULL, &proc_dointvec },
+#endif
+#ifdef CONFIG_IRDA_FAST_RR
+        { SLOTS, "fast_poll_increase", &sysctl_fast_poll_increase,
X 	  sizeof(int), 0644, NULL, &proc_dointvec },
X #endif
X 	{ SLOTS, "discovery_slots", &sysctl_discovery_slots,
diff -u --recursive --new-file v2.2.6/linux/net/irda/irttp.c linux/net/irda/irttp.c
--- v2.2.6/linux/net/irda/irttp.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irttp.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun Aug 31 20:14:31 1997
- * Modified at:   Thu Mar 25 10:27:08 1999
+ * Modified at:   Sat Apr 10 10:32:21 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, 
@@ -28,6 +28,7 @@
X #include <linux/init.h>
X 
X #include <asm/byteorder.h>
+#include <asm/unaligned.h>
X 
X #include <net/irda/irda.h>
X #include <net/irda/irmod.h>
@@ -639,7 +640,6 @@
X 			  struct sk_buff *userdata) 
X {
X 	struct sk_buff *skb;
-	__u16 tmp_be;
X 	__u8 *frame;
X 	__u8 n;
X 	
@@ -703,8 +703,8 @@
X 		frame[2] = 0x01; /* MaxSduSize */
X 		frame[3] = 0x02; /* Value length */
X 
-		tmp_be = cpu_to_be16((__u16) max_sdu_size);
-		memcpy(frame+4, &tmp_be, 2);
+		put_unaligned(cpu_to_be16((__u16) max_sdu_size), 
+			      (__u16 *)(frame+4));
X 	} else {
X 		/* Insert plain TTP header */
X 		frame = skb_push(skb, TTP_HEADER);
@@ -728,11 +728,10 @@
X 			   __u32 max_seg_size, struct sk_buff *skb) 
X {
X 	struct tsap_cb *self;
-	__u16 tmp_cpu;
-	__u8 *frame;
-	__u8 n;
X 	int parameters;
+	__u8 *frame;
X 	__u8 plen, pi, pl;
+	__u8 n;
X 
X 	DEBUG(4, __FUNCTION__ "()\n");
X 	
@@ -770,14 +769,26 @@
X 		pi   = frame[2];
X 		pl   = frame[3];
X 
-		ASSERT(pl == 2, return;);
-
-		memcpy(&tmp_cpu, frame+4, 2); /* Align value */
-		be16_to_cpus(&tmp_cpu);       /* Convert to host order */
-		self->tx_max_sdu_size = tmp_cpu;
+		switch (pl) {
+		case 1:
+			self->tx_max_sdu_size = *(frame+4);
+			break;
+		case 2:
+			self->tx_max_sdu_size = 
+				be16_to_cpu(get_unaligned((__u16 *)(frame+4)));
+			break;
+		case 4:
+			self->tx_max_sdu_size = 
+				be32_to_cpu(get_unaligned((__u32 *)(frame+4)));
+			break;
+		default:
+			printk(KERN_ERR __FUNCTION__ 
+			       "() illegal value length for max_sdu_size!\n");
+			self->tx_max_sdu_size = 0;
+		};
X 
X 		DEBUG(4, __FUNCTION__ "(), RxMaxSduSize=%d\n", 
-		       self->tx_max_sdu_size);
+		      self->tx_max_sdu_size);
X 	}
X 	
X 	DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n", 
@@ -804,11 +815,10 @@
X {
X 	struct tsap_cb *self;
X 	struct lsap_cb *lsap;
-	__u16 tmp_cpu;
-	__u8 *frame;
X 	int parameters;
-	int n;
+	__u8 *frame;
X 	__u8 plen, pi, pl;
+	__u8 n;
X 
X 	self = (struct tsap_cb *) instance;
X 
@@ -818,9 +828,6 @@
X 
X 	lsap = (struct lsap_cb *) sap;
X 
-	/* FIXME: just remove this when we know its working */
-	ASSERT(max_seg_size == qos->data_size.value, return;);
-
X 	self->max_seg_size = max_seg_size-LMP_HEADER-LAP_HEADER;
X 
X 	DEBUG(4, __FUNCTION__ "(), TSAP sel=%02x\n", self->stsap_sel);
@@ -836,18 +843,31 @@
X 	
X 	parameters = frame[0] & 0x80;	
X 	if (parameters) {
-		DEBUG(4, __FUNCTION__ "(), Contains parameters!\n");
+		DEBUG(3, __FUNCTION__ "(), Contains parameters!\n");
X 		plen = frame[1];
X 		pi   = frame[2];
X 		pl   = frame[3];
X 
-		ASSERT(pl == 2, return;);
+		switch (pl) {
+		case 1:
+			self->tx_max_sdu_size = *(frame+4);
+			break;
+		case 2:
+			self->tx_max_sdu_size = 
+				be16_to_cpu(get_unaligned((__u16 *)(frame+4)));
+			break;
+		case 4:
+			self->tx_max_sdu_size = 
+				be32_to_cpu(get_unaligned((__u32 *)(frame+4)));
+			break;
+		default:
+			printk(KERN_ERR __FUNCTION__ 
+			       "() illegal value length for max_sdu_size!\n");
+			self->tx_max_sdu_size = 0;
+		};
X 
-		memcpy(&tmp_cpu, frame+4, 2); /* Align value */
-		be16_to_cpus(&tmp_cpu);       /* Convert to host order */
X 
-		self->tx_max_sdu_size = tmp_cpu;
-		DEBUG(4, __FUNCTION__ "(), MaxSduSize=%d\n", 
+		DEBUG(3, __FUNCTION__ "(), MaxSduSize=%d\n", 
X 		      self->tx_max_sdu_size);
X 	}
X 
@@ -873,7 +893,6 @@
X 			    struct sk_buff *userdata)
X {
X 	struct sk_buff *skb;
-	__u32 tmp_be;
X 	__u8 *frame;
X 	__u8 n;
X 
@@ -932,8 +951,8 @@
X 		frame[2] = 0x01; /* MaxSduSize */
X 		frame[3] = 0x02; /* Value length */
X 
-		tmp_be = cpu_to_be16((__u16)max_sdu_size);
-		memcpy(frame+4, &tmp_be, 2);
+		put_unaligned(cpu_to_be16((__u16) max_sdu_size), 
+			      (__u16 *)(frame+4));
X 	} else {
X 		/* Insert TTP header */
X 		frame = skb_push(skb, TTP_HEADER);
diff -u --recursive --new-file v2.2.6/linux/net/irda/qos.c linux/net/irda/qos.c
--- v2.2.6/linux/net/irda/qos.c	Wed Mar 10 15:29:53 1999
+++ linux/net/irda/qos.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Tue Sep  9 00:00:26 1997
- * Modified at:   Mon Feb  1 09:56:21 1999
+ * Modified at:   Mon Apr 12 11:49:24 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
@@ -70,7 +70,7 @@
X 	qos->compression.bits     &= new->compression.bits;
X #endif
X 
-	irda_qos_bits_to_value( qos);
+	irda_qos_bits_to_value(qos);
X }
X 
X /*
diff -u --recursive --new-file v2.2.6/linux/net/irda/wrapper.c linux/net/irda/wrapper.c
--- v2.2.6/linux/net/irda/wrapper.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/wrapper.c	Sat Apr 24 17:50:06 1999
@@ -1,12 +1,12 @@
X /*********************************************************************
X  *                
X  * Filename:      wrapper.c
- * Version:       1.0
+ * Version:       1.1
X  * Description:   SIR wrapper layer
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Fri Mar 26 21:52:53 1999
+ * Modified at:   Wed Apr 21 12:45:55 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, 
@@ -34,9 +34,7 @@
X #include <net/irda/irlap_frame.h>
X #include <net/irda/irda_device.h>
X 
-#define MIN_LENGTH 14
-
-inline static int stuff_byte( __u8 byte, __u8 *buf);
+inline static int stuff_byte(__u8 byte, __u8 *buf);
X 
X /*
X  * Function async_wrap (skb, *tx_buff)
@@ -44,17 +42,17 @@
X  *    Makes a new buffer with wrapping and stuffing, should check that 
X  *    we don't get tx buffer overflow.
X  */
-int async_wrap_skb( struct sk_buff *skb, __u8 *tx_buff, int buffsize)
+int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
X {
-	__u8 byte;
-	int i, n;
+ 	int i;
+	int n;
X 	int xbofs;
X 	union {
X 		__u16 value;
X 		__u8 bytes[2];
X 	} fcs;
X 
-	ASSERT( skb != NULL, return 0;);
+	ASSERT(skb != NULL, return 0;);
X 
X 	/* Initialize variables */
X 	fcs.value = INIT_FCS;
@@ -72,33 +70,31 @@
X 	 */
X 	if (((struct irlap_skb_cb *)(skb->cb))->magic != LAP_MAGIC) {
X 		DEBUG(1, __FUNCTION__ "(), wrong magic in skb!\n");
-		xbofs = 11;
+		xbofs = 10;
X 	} else
X 		xbofs = ((struct irlap_skb_cb *)(skb->cb))->xbofs;
X 
-	for (i=0; i<xbofs; i++) {
- 		tx_buff[n++] = XBOF; 
- 	}
-
+#if 0
+ 	for (i=0; i<xbofs; i++)
+  		tx_buff[n++] = XBOF;
+#else
+	memset(tx_buff+n, XBOF, xbofs);
+	n += xbofs;
+#endif
X 	/* Start of packet character BOF */
X 	tx_buff[n++] = BOF;
X 
X 	/* Insert frame and calc CRC */
X 	for (i=0; i < skb->len; i++) {
-		byte = skb->data[i];
-		
X 		/*
X 		 *  Check for the possibility of tx buffer overflow. We use
X 		 *  bufsize-5 since the maximum number of bytes that can be 
X 		 *  transmitted after this point is 5.
X 		 */
-		if ( n > buffsize-5) {
-			printk( KERN_WARNING 
-				"IrDA Wrapper: TX-buffer overflow!\n");
-			return n;
-		}
-		n+=stuff_byte( byte, tx_buff+n);
-		fcs.value = IR_FCS( fcs.value, byte);
+		ASSERT(n < (buffsize-5), return n;);
+
+		n += stuff_byte(skb->data[i], tx_buff+n);
+		fcs.value = IR_FCS(fcs.value, skb->data[i]);
X 	}
X 	
X 	/* Insert CRC in little endian format (LSB first) */
@@ -111,7 +107,16 @@
X 	n += stuff_byte(fcs.bytes[0], tx_buff+n);
X #endif
X 	tx_buff[n++] = EOF;
-	
+
+#if 0
+	{
+		int i;
+		
+		for (i=0;i<n;i++)
+			printk("%02x", tx_buff[i]);
+		printk("\n");
+	}
+#endif
X 	return n;
X }
X 
@@ -121,10 +126,10 @@
X  *    Got a frame, make a copy of it, and pass it up the stack!
X  *
X  */
-static inline void async_bump( struct irda_device *idev, __u8 *buf, int len)
+static inline void async_bump(struct irda_device *idev, __u8 *buf, int len)
X {
X        	struct sk_buff *skb;
- 
+
X 	skb = dev_alloc_skb(len+1);
X 	if (!skb)  {
X 		idev->stats.rx_dropped++;
@@ -132,18 +137,14 @@
X 	}
X 
X 	/*  Align IP header to 20 bytes */
-	skb_reserve( skb, 1);
+	skb_reserve(skb, 1);
X 	
-	ASSERT( len-2 > 0, return;);
-
X         /* Copy data without CRC */
-	skb_put( skb, len-2);
-	memcpy( skb->data, buf, len-2); 
+	memcpy(skb_put(skb, len-2), buf, len-2); 
X 	
X 	/* 
X 	 *  Feed it to IrLAP layer 
X 	 */
-	/* memcpy(skb_put(skb,count), ax->rbuff, count); */
X 	skb->dev = &idev->netdev;
X 	skb->mac.raw  = skb->data;
X 	skb->protocol = htons(ETH_P_IRDA);
@@ -159,18 +160,18 @@
X  *    Parse and de-stuff frame received from the IR-port
X  *
X  */
-void async_unwrap_char( struct irda_device *idev, __u8 byte) 
+void async_unwrap_char(struct irda_device *idev, __u8 byte) 
X {
X 	/* State machine for receiving frames */	   
-	switch( idev->rx_buff.state) {
+	switch (idev->rx_buff.state) {
X 	case OUTSIDE_FRAME:
-		switch( byte) {
+		switch(byte) {
X 		case BOF:
X 			idev->rx_buff.state = BEGIN_FRAME;
X 			idev->rx_buff.in_frame = TRUE;
X 			break;
X 		case XBOF:
-			idev->xbofs++;
+			/* idev->xbofs++; */
X 			break;
X 		case EOF:
X 			irda_device_set_media_busy( idev, TRUE);
@@ -180,9 +181,8 @@
X 		}
X 		break;
X 	case BEGIN_FRAME:
-		switch ( byte) {
+		switch (byte) {
X 		case BOF:
-			
X 			/* Continue */
X 			break;
X 		case CE:
@@ -198,28 +198,29 @@
X 			break;
X 		default:
X 			/* Got first byte of frame */
-			idev->rx_buff.data[ idev->rx_buff.len++] = byte;
+			idev->rx_buff.data = idev->rx_buff.head;
+			idev->rx_buff.len = 0;
+
+			idev->rx_buff.data[idev->rx_buff.len++] = byte;
X 			
-			idev->rx_buff.fcs = IR_FCS( INIT_FCS, byte);
+			idev->rx_buff.fcs = IR_FCS(INIT_FCS, byte);
X 			idev->rx_buff.state = INSIDE_FRAME;
X 			break;
X 		}
X 		break;
X 	case LINK_ESCAPE:
-		switch ( byte) {
+		switch (byte) {
X 		case BOF:
X 			/* New frame? */
X 			idev->rx_buff.state = BEGIN_FRAME;
-			idev->rx_buff.len = 0;
-			irda_device_set_media_busy( idev, TRUE);
+			irda_device_set_media_busy(idev, TRUE);
X 			break;
X 		case CE:
-			DEBUG( 4, "WARNING: State not defined\n");
+			DEBUG(4, "WARNING: State not defined\n");
X 			break;
X 		case EOF:
X 			/* Abort frame */
X 			idev->rx_buff.state = OUTSIDE_FRAME;
-			idev->rx_buff.len = 0;
X 			break;
X 		default:
X 			/* 
@@ -227,28 +228,25 @@
X 			 *  following CE, IrLAP p.114 
X 			 */
X 			byte ^= IR_TRANS;
-			if ( idev->rx_buff.len < idev->rx_buff.truesize)  {
-				idev->rx_buff.data[ idev->rx_buff.len++] = byte;
-			
+			if (idev->rx_buff.len < idev->rx_buff.truesize)  {
+				idev->rx_buff.data[idev->rx_buff.len++] = byte;
X 				idev->rx_buff.fcs = IR_FCS(idev->rx_buff.fcs,
X 							   byte);
X 				idev->rx_buff.state = INSIDE_FRAME;
X 			} else {
-				DEBUG( 1, __FUNCTION__ 
+				DEBUG(1, __FUNCTION__ 
X 				       "(), Rx buffer overflow, aborting\n");
X 				idev->rx_buff.state = OUTSIDE_FRAME;
-				idev->rx_buff.len = 0;
X 			}
X 			break;
X 		}
X 		break;
X 	case INSIDE_FRAME:
-		switch ( byte) {
+		switch (byte) {
X 		case BOF:
X 			/* New frame? */
X 			idev->rx_buff.state = BEGIN_FRAME;
-			idev->rx_buff.len = 0;
-			irda_device_set_media_busy( idev, TRUE);
+			irda_device_set_media_busy(idev, TRUE);
X 			break;
X 		case CE:
X 			/* Stuffed char */
@@ -262,14 +260,12 @@
X 			/* 
X 			 *  Test FCS and deliver frame if it's good
X 			 */			
-			if ( idev->rx_buff.fcs == GOOD_FCS) {
-				async_bump( idev, idev->rx_buff.data, 
-					    idev->rx_buff.len);
-				idev->rx_buff.len = 0;
+			if (idev->rx_buff.fcs == GOOD_FCS) {
+				async_bump(idev, idev->rx_buff.data, 
+					   idev->rx_buff.len);
X 			} else {
X 				/* Wrong CRC, discard frame!  */
-				irda_device_set_media_busy( idev, TRUE); 
-				idev->rx_buff.len = 0;
+				irda_device_set_media_busy(idev, TRUE); 
X 
X 				idev->stats.rx_errors++;
X 				idev->stats.rx_crc_errors++;
@@ -277,16 +273,14 @@
X 			break;
X 		default:
X 			/* Next byte of frame */
-			if ( idev->rx_buff.len < idev->rx_buff.truesize)  {
-				idev->rx_buff.data[ idev->rx_buff.len++] = byte;
-				
-				idev->rx_buff.fcs = IR_FCS( idev->rx_buff.fcs,
-							    byte);
+			if (idev->rx_buff.len < idev->rx_buff.truesize)  {
+				idev->rx_buff.data[idev->rx_buff.len++] = byte;
+				idev->rx_buff.fcs = IR_FCS(idev->rx_buff.fcs,
+							   byte);
X 			} else {
-				DEBUG( 1, __FUNCTION__ 
-				       "(), Rx buffer overflow, aborting\n");
+				DEBUG(1, __FUNCTION__ 
+				      "(), Rx buffer overflow, aborting\n");
X 				idev->rx_buff.state = OUTSIDE_FRAME;
-				idev->rx_buff.len = 0;
X 			}
X 			break;
X 		}
@@ -301,9 +295,9 @@
X  *    buf. The buffer must at all times be able to have two bytes inserted.
X  * 
X  */
-inline static int stuff_byte( __u8 byte, __u8 *buf) 
+inline static int stuff_byte(__u8 byte, __u8 *buf) 
X {
-	switch ( byte) {
+	switch (byte) {
X 	case BOF: /* FALLTHROUGH */
X 	case EOF: /* FALLTHROUGH */
X 	case CE:
diff -u --recursive --new-file v2.2.6/linux/net/netsyms.c linux/net/netsyms.c
--- v2.2.6/linux/net/netsyms.c	Tue Mar 23 14:35:48 1999
+++ linux/net/netsyms.c	Sat Apr 24 17:51:48 1999
@@ -21,6 +21,9 @@
X #include <net/dst.h>
X #include <net/checksum.h>
X #include <linux/etherdevice.h>
+#ifdef CONFIG_HIPPI
+#include <linux/hippidevice.h>
+#endif
X #include <net/pkt_sched.h>
X 
X #ifdef CONFIG_BRIDGE
@@ -45,6 +48,8 @@
X #include <linux/igmp.h>
X 
X extern struct net_proto_family inet_family_ops;
+extern __u32 sysctl_wmem_max;
+extern __u32 sysctl_rmem_max;
X 
X #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
X #include <linux/in6.h>
@@ -474,6 +479,15 @@
X EXPORT_SYMBOL(kill_fasync);
X 
X EXPORT_SYMBOL(if_port_text);
+
+#ifdef CONFIG_HIPPI
+EXPORT_SYMBOL(hippi_type_trans);
+EXPORT_SYMBOL(init_hippi_dev);
+EXPORT_SYMBOL(unregister_hipdev);
+#endif
+
+EXPORT_SYMBOL(sysctl_wmem_max);
+EXPORT_SYMBOL(sysctl_rmem_max);
X 
X #if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) 
X #include<linux/if_ltalk.h>
diff -u --recursive --new-file v2.2.6/linux/net/sched/cls_fw.c linux/net/sched/cls_fw.c
--- v2.2.6/linux/net/sched/cls_fw.c	Mon Mar 29 11:09:12 1999
+++ linux/net/sched/cls_fw.c	Thu Apr 22 19:45:20 1999
@@ -7,6 +7,10 @@
X  *		2 of the License, or (at your option) any later version.
X  *
X  * Authors:	Alexey Kuznetsov, <kuz...@ms2.inr.ac.ru>
+ *
+ * Changes:
+ * Karlis Peisenieks <kar...@mt.lv> : 990415 : fw_walk off by one
+ * Karlis Peisenieks <kar...@mt.lv> : 990415 : fw_delete killed all the filter (and kernel).
X  */
X 
X #include <linux/config.h>
@@ -146,7 +150,7 @@
X 
X static int fw_delete(struct tcf_proto *tp, unsigned long arg)
X {
-	struct fw_head *head = (struct fw_head*)xchg(&tp->root, NULL);
+	struct fw_head *head = (struct fw_head*)tp->root;
X 	struct fw_filter *f = (struct fw_filter*)arg;
X 	struct fw_filter **fp;
X 
@@ -273,7 +277,7 @@
X 	if (arg->stop)
X 		return;
X 
-	for (h = 0; h <= 256; h++) {
+	for (h = 0; h < 256; h++) {
X 		struct fw_filter *f;
X 
X 		for (f = head->ht[h]; f; f = f->next) {
diff -u --recursive --new-file v2.2.6/linux/net/sched/cls_rsvp.h linux/net/sched/cls_rsvp.h
--- v2.2.6/linux/net/sched/cls_rsvp.h	Mon Mar 29 11:09:12 1999
+++ linux/net/sched/cls_rsvp.h	Thu Apr 22 19:45:20 1999
@@ -193,23 +193,23 @@
X 				    && src[2] == f->src[2]
X #endif
X 				    ) {
+					*res = f->res;
X 
X 					RSVP_POLICE();
X 
X matched:
-					if (f->tunnelhdr == 0) {
-						*res = f->res;
+					if (f->tunnelhdr == 0)
X 						return 0;
-					} else {
-						tunnelid = f->res.classid;
-						nhptr = (void*)(xprt + f->tunnelhdr - sizeof(*nhptr));
-						goto restart;
-					}
+
+					tunnelid = f->res.classid;
+					nhptr = (void*)(xprt + f->tunnelhdr - sizeof(*nhptr));
+					goto restart;
X 				}
X 			}
X 
X 			/* And wildcard bucket... */
X 			for (f = s->ht[16]; f; f = f->next) {
+				*res = f->res;
X 				RSVP_POLICE();
X 				goto matched;
X 			}
diff -u --recursive --new-file v2.2.6/linux/net/sched/sch_cbq.c linux/net/sched/sch_cbq.c
--- v2.2.6/linux/net/sched/sch_cbq.c	Tue Mar 23 14:35:48 1999
+++ linux/net/sched/sch_cbq.c	Sat Apr 24 17:51:48 1999
@@ -30,7 +30,6 @@
X #include <linux/netdevice.h>
X #include <linux/etherdevice.h>
X #include <linux/notifier.h>
-#include <linux/module.h>
X #include <net/ip.h>
X #include <net/route.h>
X #include <linux/skbuff.h>
diff -u --recursive --new-file v2.2.6/linux/net/sched/sch_sfq.c linux/net/sched/sch_sfq.c
--- v2.2.6/linux/net/sched/sch_sfq.c	Tue Mar 23 14:35:48 1999
+++ linux/net/sched/sch_sfq.c	Sat Apr 24 17:51:48 1999
@@ -14,7 +14,6 @@
X #include <asm/uaccess.h>
X #include <asm/system.h>
X #include <asm/bitops.h>
-#include <linux/module.h>
X #include <linux/types.h>
X #include <linux/kernel.h>
X #include <linux/sched.h>
diff -u --recursive --new-file v2.2.6/linux/net/socket.c linux/net/socket.c
--- v2.2.6/linux/net/socket.c	Tue Mar 23 14:35:48 1999
+++ linux/net/socket.c	Thu Apr 22 19:45:20 1999
@@ -279,8 +279,8 @@
X 
X 	inode->i_mode = S_IFSOCK|S_IRWXUGO;
X 	inode->i_sock = 1;
-	inode->i_uid = current->uid;
-	inode->i_gid = current->gid;
+	inode->i_uid = current->fsuid;
+	inode->i_gid = current->fsgid;
X 
X 	sock->inode = inode;
X 	init_waitqueue(&sock->wait);
@@ -1135,7 +1135,7 @@
X 	/* Check whether to allocate the iovec area*/
X 	err = -ENOMEM;
X 	iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
-	if (msg_sys.msg_iovlen > 1 /* UIO_FASTIOV */) {
+	if (msg_sys.msg_iovlen > UIO_FASTIOV) {
X 		iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
X 		if (!iov)
X 			goto out_put;
@@ -1147,6 +1147,11 @@
X 		goto out_freeiov;
X 	total_len = err;
X 
+	err = -ENOBUFS;
+
+	/* msg_controllen must fit to int */
+	if (msg_sys.msg_controllen > INT_MAX)
+		goto out_freeiov;
X 	ctl_len = msg_sys.msg_controllen; 
X 	if (ctl_len) 
X 	{
diff -u --recursive --new-file v2.2.6/linux/scripts/ksymoops/oops.c linux/scripts/ksymoops/oops.c
--- v2.2.6/linux/scripts/ksymoops/oops.c	Mon Mar 29 11:09:12 1999
+++ linux/scripts/ksymoops/oops.c	Thu Apr 22 19:24:52 1999
@@ -288,7 +288,7 @@
X 		errno = 0;
X 		eip_relative = strtoul(string[5], NULL, 16);
X 		if (errno) {
-#if 0
+#ifdef __sparc__
X 			/* Try strtoull also, e.g. sparc binutils print <_PC+0xfffffffffffffd58> */
X 			errno = 0;
X 			eip_relative = strtoull(string[5], NULL, 16);
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
echo 'File patch-2.2.7 is complete' &&
chmod 644 patch-2.2.7 ||
echo 'restore of patch-2.2.7 failed'
Cksum="`cksum < 'patch-2.2.7'`"
if ! test "2457858966 1247802" = "$Cksum"
then
	echo 'patch-2.2.7: original Checksum 2457858966 1247802, current one' "$Cksum" 
	rm -f _shar_wnt_.tmp
	rm -f _shar_seq_.tmp
	exit 1
fi
rm -f _shar_wnt_.tmp
fi
rm -f _shar_seq_.tmp
echo 'You have unpacked the last part.'
#!/bin/sh
# this is part 20 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 20; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
+			fl.fl6_dst = rt0->addr;
+		}
+	} else if (np->opt && np->opt->srcrt) {
X 		struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
-		fl.nl_u.ip6_u.daddr = rt0->addr;
+		fl.fl6_dst = rt0->addr;
X 	}
X 
X 	dst = ip6_route_output(sk, &fl);
X 
X 	if ((err = dst->error) != 0) {
X 		dst_release(dst);
+		fl6_sock_release(flowlabel);
X 		return err;
X 	}
X 
-	ip6_dst_store(sk, dst, fl.nl_u.ip6_u.daddr);
+	ip6_dst_store(sk, dst, fl.fl6_dst);
X 
X 	/* get the source adddress used in the apropriate device */
X 
@@ -305,6 +324,7 @@
X 		}
X 		sk->state = TCP_ESTABLISHED;
X 	}
+	fl6_sock_release(flowlabel);
X 
X 	return err;
X }
@@ -396,6 +416,7 @@
X 		sin6 = (struct sockaddr_in6 *) msg->msg_name;
X 		sin6->sin6_family = AF_INET6;
X 		sin6->sin6_port = skb->h.uh->source;
+		sin6->sin6_flowinfo = 0;
X 
X 		if (skb->protocol == __constant_htons(ETH_P_IP)) {
X 			ipv6_addr_set(&sin6->sin6_addr, 0, 0,
@@ -734,10 +755,10 @@
X 	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
X 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name;
X 	struct ipv6_txoptions *opt = NULL;
+	struct ip6_flowlabel *flowlabel = NULL;
X 	struct flowi fl;
X 	int addr_len = msg->msg_namelen;
X 	struct in6_addr *daddr;
-	struct in6_addr *saddr = NULL;
X 	int len = ulen + sizeof(struct udphdr);
X 	int addr_type;
X 	int hlimit = -1;
@@ -752,23 +773,35 @@
X 	
X 	if (msg->msg_flags & ~(MSG_DONTROUTE|MSG_DONTWAIT))
X 		return(-EINVAL);
-	
+
+	fl.fl6_flowlabel = 0;
+
X 	if (sin6) {
X 		if (sin6->sin6_family == AF_INET)
X 			return udp_sendmsg(sk, msg, ulen);
X 
X 		if (addr_len < sizeof(*sin6))
X 			return(-EINVAL);
-		
+
X 		if (sin6->sin6_family && sin6->sin6_family != AF_INET6)
X 			return(-EINVAL);
X 
X 		if (sin6->sin6_port == 0)
X 			return(-EINVAL);
-	       
+
X 		udh.uh.dest = sin6->sin6_port;
X 		daddr = &sin6->sin6_addr;
X 
+		if (np->sndflow) {
+			fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+			if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
+				flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+				if (flowlabel == NULL)
+					return -EINVAL;
+				daddr = &flowlabel->dst;
+			}
+		}
+
X 		/* Otherwise it will be difficult to maintain sk->dst_cache. */
X 		if (sk->state == TCP_ESTABLISHED &&
X 		    !ipv6_addr_cmp(daddr, &sk->net_pinfo.af_inet6.daddr))
@@ -776,38 +809,52 @@
X 	} else {
X 		if (sk->state != TCP_ESTABLISHED)
X 			return(-ENOTCONN);
-		
+
X 		udh.uh.dest = sk->dport;
X 		daddr = &sk->net_pinfo.af_inet6.daddr;
+		fl.fl6_flowlabel = np->flow_label;
X 	}
-	
+
X 	addr_type = ipv6_addr_type(daddr);
-	
+
X 	if (addr_type == IPV6_ADDR_MAPPED) {
X 		struct sockaddr_in sin;
-		
+
X 		sin.sin_family = AF_INET;
X 		sin.sin_addr.s_addr = daddr->s6_addr32[3];
X 		sin.sin_port = udh.uh.dest;
X 		msg->msg_name = (struct sockaddr *)(&sin);
X 		msg->msg_namelen = sizeof(sin);
+		fl6_sock_release(flowlabel);
X 
X 		return udp_sendmsg(sk, msg, ulen);
X 	}
-	
+
X 	udh.daddr = NULL;
X 	fl.oif = sk->bound_dev_if;
-	
+	fl.fl6_src = NULL;
+
X 	if (msg->msg_controllen) {
X 		opt = &opt_space;
X 		memset(opt, 0, sizeof(struct ipv6_txoptions));
X 
-		err = datagram_send_ctl(msg, &fl.oif, &saddr, opt, &hlimit);
-		if (err < 0)
+		err = datagram_send_ctl(msg, &fl, opt, &hlimit);
+		if (err < 0) {
+			fl6_sock_release(flowlabel);
X 			return err;
+		}
+		if ((fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) {
+			flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+			if (flowlabel == NULL)
+				return -EINVAL;
+		}
+		if (!(opt->opt_nflen|opt->opt_flen))
+			opt = NULL;
X 	}
-	if (opt == NULL || !(opt->opt_nflen|opt->opt_flen))
+	if (opt == NULL)
X 		opt = np->opt;
+	if (flowlabel)
+		opt = fl6_merge_options(&opt_space, flowlabel, opt);
X 	if (opt && opt->srcrt)
X 		udh.daddr = daddr;
X 
@@ -819,13 +866,14 @@
X 	udh.pl_len = len;
X 
X 	fl.proto = IPPROTO_UDP;
-	fl.nl_u.ip6_u.daddr = daddr;
-	fl.nl_u.ip6_u.saddr = saddr;
+	fl.fl6_dst = daddr;
X 	fl.uli_u.ports.dport = udh.uh.dest;
X 	fl.uli_u.ports.sport = udh.uh.source;
X 
X 	err = ip6_build_xmit(sk, udpv6_getfrag, &udh, &fl, len, opt, hlimit,
X 			     msg->msg_flags);
+
+	fl6_sock_release(flowlabel);
X 
X 	if (err < 0)
X 		return err;
diff -u --recursive --new-file v2.2.6/linux/net/irda/af_irda.c linux/net/irda/af_irda.c
--- v2.2.6/linux/net/irda/af_irda.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/af_irda.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun May 31 10:12:43 1998
- * Modified at:   Wed Apr  7 17:32:27 1999
+ * Modified at:   Thu Apr 22 12:08:04 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * Sources:       af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc.
X  * 
@@ -39,6 +39,7 @@
X #include <net/irda/iriap.h>
X #include <net/irda/irias_object.h>
X #include <net/irda/irttp.h>
+#include <net/irda/discovery.h>
X 
X extern int  irda_init(void);
X extern void irda_cleanup(void);
@@ -237,8 +238,8 @@
X  *    Got answer from remote LM-IAS
X  *
X  */
-static void irda_get_value_confirm(__u16 obj_id, struct ias_value *value, 
-				   void *priv)
+static void irda_get_value_confirm(int result, __u16 obj_id, 
+				   struct ias_value *value, void *priv)
X {
X 	struct irda_sock *self;
X 	
@@ -251,11 +252,14 @@
X 		return;
X 
X 	/* Check if request succeeded */
-	if (!value) {
+	if (result != IAS_SUCCESS) {
X 		DEBUG(0, __FUNCTION__ "(), IAS query failed!\n");
X 
+		self->errno = result;
+
X 		/* Wake up any processes waiting for result */
X 		wake_up_interruptible(&self->ias_wait);
+
X 		return;
X 	}
X 
@@ -673,7 +677,7 @@
X 	self->mask = 0xffff;
X 	self->rx_flow = self->tx_flow = FLOW_START;
X 	self->max_sdu_size_rx = SAR_DISABLE; /* Default value */
-	self->nslots = 6; /* Default for now */
+	self->nslots = DISCOVERY_DEFAULT_SLOTS;
X 
X 	/* Notify that we are using the irda module, so nobody removes it */
X 	irda_mod_inc_use_count();
@@ -857,6 +861,12 @@
X 	return copied;
X }
X 
+/*
+ * Function irda_shutdown (sk, how)
+ *
+ *    
+ *
+ */
X static int irda_shutdown( struct socket *sk, int how)
X {
X 	DEBUG( 0, __FUNCTION__ "()\n");
@@ -866,6 +876,12 @@
X }
X 
X 
+/*
+ * Function irda_poll (file, sock, wait)
+ *
+ *    
+ *
+ */
X unsigned int irda_poll(struct file *file, struct socket *sock, 
X 		       struct poll_table_struct *wait)
X {
diff -u --recursive --new-file v2.2.6/linux/net/irda/discovery.c linux/net/irda/discovery.c
--- v2.2.6/linux/net/irda/discovery.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/discovery.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Tue Apr  6 15:33:50 1999
- * Modified at:   Tue Apr  6 20:26:46 1999
+ * Modified at:   Sun Apr 11 00:41:58 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -46,7 +46,7 @@
X {
X 	discovery_t *old;
X 
-	DEBUG(2, __FUNCTION__ "()\n");
+	DEBUG(4, __FUNCTION__ "()\n");
X 
X 	/* Check if we have discovered this device before */
X 	old = hashbin_remove(cachelog, discovery->daddr, NULL);
@@ -67,7 +67,7 @@
X {
X 	discovery_t *discovery;
X 
-	DEBUG(2, __FUNCTION__ "()\n");
+	DEBUG(4, __FUNCTION__ "()\n");
X 
X 	/*
X 	 *  If log is missing this means that IrLAP was unable to perform the
@@ -100,7 +100,7 @@
X {
X 	discovery_t *discovery, *curr;
X 
-	DEBUG(3, __FUNCTION__ "()\n");
+	DEBUG(4, __FUNCTION__ "()\n");
X 
X 	discovery = (discovery_t *) hashbin_get_first(log);
X 	while (discovery != NULL) {
diff -u --recursive --new-file v2.2.6/linux/net/irda/ircomm/ircomm_common.c linux/net/irda/ircomm/ircomm_common.c
--- v2.2.6/linux/net/irda/ircomm/ircomm_common.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/ircomm/ircomm_common.c	Sat Apr 24 17:50:06 1999
@@ -41,13 +41,21 @@
X 
X #include <net/irda/ircomm_common.h>
X 
-static char *revision_date = "Tue Mar  2 02:03:58 1999";
+static char *revision_date = "Sun Apr 18 00:40:19 1999";
X 
X 
-static void ircomm_state_discovery(struct ircomm_cb *self,
-				   IRCOMM_EVENT event, struct sk_buff *skb );
X static void ircomm_state_idle( struct ircomm_cb *self, IRCOMM_EVENT event, 
X 			       struct sk_buff *skb );
+
+static void ircomm_state_discoverywait( struct ircomm_cb *self, IRCOMM_EVENT event, 
+					struct sk_buff *skb );
+
+static void ircomm_state_queryparamwait( struct ircomm_cb *self, IRCOMM_EVENT event, 
+					 struct sk_buff *skb );
+
+static void ircomm_state_querylsapwait( struct ircomm_cb *self, IRCOMM_EVENT event, 
+					struct sk_buff *skb );
+
X static void ircomm_state_waiti( struct ircomm_cb *self, IRCOMM_EVENT event, 
X 				struct sk_buff *skb );
X static void ircomm_state_waitr( struct ircomm_cb *self, IRCOMM_EVENT event, 
@@ -63,13 +71,14 @@
X static int ircomm_proc_read(char *buf, char **start, off_t offset,
X 			    int len, int unused);
X 
+static void start_discovering(struct ircomm_cb *self);
X static void query_lsapsel(struct ircomm_cb * self);
-static void ircomm_getvalue_confirm( __u16 obj_id, struct ias_value *value, 
-				     void *priv);
+static void query_parameters(struct ircomm_cb *self);
+static void queryias_done(struct ircomm_cb *self);
+static void ircomm_getvalue_confirm(int result, __u16 obj_id, 
+				    struct ias_value *value, void *priv);
X 
X 
-static __u32 ckey;
-static __u32 skey;
X struct ircomm_cb *discovering_instance;
X 
X /*
@@ -86,8 +95,12 @@
X 
X 
X static char *ircommstate[] = {
-	"DISCOVERY",
X 	"IDLE",
+
+	"DISCOVERY_WAIT",
+	"QUERYPARAM_WAIT",
+	"QUERYLSAP_WAIT",
+
X 	"WAITI",
X 	"WAITR",
X 	"CONN",
@@ -126,6 +139,11 @@
X 	"IRCOMM_DATA_REQUEST",
X 	"LMP_DATA_INDICATION",
X 	"IRCOMM_CONTROL_REQUEST",
+
+	"DISCOVERY_INDICATION",
+	"GOT_PARAMETERS",
+	"GOT_LSAPSEL",
+	"QUERYIAS_ERROR",
X };
X 
X #ifdef CONFIG_PROC_FS
@@ -141,8 +159,12 @@
X static void (*state[])( struct ircomm_cb *self, IRCOMM_EVENT event,
X 			struct sk_buff *skb) = 
X {
-	ircomm_state_discovery,
X 	ircomm_state_idle,
+
+	ircomm_state_discoverywait,
+	ircomm_state_queryparamwait,
+	ircomm_state_querylsapwait,
+
X 	ircomm_state_waiti,
X 	ircomm_state_waitr,
X 	ircomm_state_conn,
@@ -376,6 +398,146 @@
X 
X }
X 
+
+/*
+ * ircomm_discovery_indication()
+ *    Remote device is discovered, try query the remote IAS to see which
+ *    device it is, and which services it has.
+ */
+
+static void ircomm_discovery_indication(discovery_t *discovery)
+{
+	struct ircomm_cb *self;
+
+	self = discovering_instance;
+	if(self == NULL)
+		return;
+	ASSERT(self->magic == IRCOMM_MAGIC, return;);
+
+	self->daddr = discovery->daddr;
+	self->saddr = discovery->saddr;
+
+	DEBUG( 0, __FUNCTION__"():daddr=%08x\n", self->daddr);
+
+	ircomm_do_event(self, DISCOVERY_INDICATION, NULL);
+	return;
+}
+
+/*
+ * ircomm_getvalue_confirm()
+ * handler for iriap_getvaluebyclass_request() 
+ */
+static void ircomm_getvalue_confirm(int result, __u16 obj_id, 
+				    struct ias_value *value, void *priv)
+{
+	struct ircomm_cb *self = (struct ircomm_cb *) priv;
+	struct sk_buff *skb= NULL;
+	__u8 *frame;
+	__u8 servicetype = 0 ;
+	ASSERT( self != NULL, return;);
+	ASSERT( self->magic == IRCOMM_MAGIC, return;);
+
+	/* Check if request succeeded */
+	if (result != IAS_SUCCESS) {
+		DEBUG( 0, __FUNCTION__ "(), got NULL value!\n");
+		ircomm_do_event(self, QUERYIAS_ERROR, NULL);
+		return;
+	}
+
+	DEBUG(4, __FUNCTION__"():type(%d)\n", value->type);
+
+	self->ias_type = value->type;
+	switch(value->type){
+ 	case IAS_OCT_SEQ:
+		
+		DEBUG(4, __FUNCTION__"():got octet sequence:\n");
+#if 0
+		{
+			int i;
+			for ( i=0;i<value->len;i++)
+				printk("%02x",
+				       (__u8)(*(value->t.oct_seq + i)));
+			printk("\n");
+		}
+#endif
+		skb = dev_alloc_skb((value->len) + 2);
+		ASSERT(skb != NULL, ircomm_do_event(self, QUERYIAS_ERROR, NULL);return;);
+		frame = skb_put(skb,2);
+		/* MSB first */
+		frame[0] = ( value->len >> 8 ) & 0xff;
+		frame[1] = value->len & 0xff;
+		
+		frame = skb_put(skb,value->len);
+		memcpy(frame, value->t.oct_seq, value->len);
+		ircomm_parse_tuples(self, skb, IAS_PARAM);
+		kfree_skb(skb);
+
+		/* 
+		 * check if servicetype we want is available 
+		 */
+
+		DEBUG(0,__FUNCTION__"():peer capability is:\n");
+		DEBUG(0,"3wire raw: %s\n",
+		      ((self->peer_servicetype & THREE_WIRE_RAW) ? "yes":"no"));
+		DEBUG(0,"3wire    : %s\n",
+		      ((self->peer_servicetype & THREE_WIRE) ? "yes":"no"));
+		DEBUG(0,"9wire    : %s\n",
+		      ((self->peer_servicetype & NINE_WIRE) ? "yes":"no"));
+		DEBUG(0,"IEEE1284 : %s\n",
+		      ((self->peer_servicetype & CENTRONICS) ? "yes":"no"));
+
+		self->servicetype &= self->peer_servicetype;
+		if(!(self->servicetype)){
+			DEBUG(0,__FUNCTION__"(): servicetype mismatch!\n");
+			ircomm_do_event(self, QUERYIAS_ERROR, NULL);
+			break;
+		}
+
+		/*
+		 * then choose better one 
+		 */
+		if(self->servicetype & THREE_WIRE_RAW)
+			servicetype = THREE_WIRE_RAW;
+		if(self->servicetype & THREE_WIRE)
+			servicetype = THREE_WIRE;
+		if(self->servicetype & NINE_WIRE)
+			servicetype = NINE_WIRE;
+		if(self->servicetype & CENTRONICS)
+			servicetype = CENTRONICS;
+
+		self->servicetype = servicetype;
+
+		/* enter next state */
+		ircomm_do_event(self, GOT_PARAMETERS, NULL);
+		break;
+
+	case IAS_INTEGER:
+		/* LsapSel seems to be sent to me */	
+		DEBUG(0, __FUNCTION__"():got lsapsel = %d\n", value->t.integer);
+
+		if ( value->t.integer == -1){
+			DEBUG( 0, __FUNCTION__"():invalid value!\n");
+			ircomm_do_event(self, QUERYIAS_ERROR, NULL);
+			return;
+		}
+		self->dlsap = value->t.integer;
+		ircomm_do_event(self, GOT_LSAPSEL, NULL);
+		break;
+
+	case IAS_MISSING:
+		DEBUG( 0, __FUNCTION__":got IAS_MISSING\n");
+		ircomm_do_event(self, QUERYIAS_ERROR, NULL);
+		break;
+   
+	default:
+		DEBUG( 0, __FUNCTION__":got unknown (strange?)type!\n");
+		ircomm_do_event(self, QUERYIAS_ERROR, NULL);
+		break;
+	}
+}
+
+
+
X /* 
X  * ----------------------------------------------------------------------
X  * Impl. of actions (descrived in section 7.4 of the reference)
@@ -583,19 +745,6 @@
X }
X 
X 
-/* 
- * we currently need dummy (discovering) state for debugging,
- * which state is not defined in the reference.
- */
-
-static void ircomm_state_discovery( struct ircomm_cb *self,
-				    IRCOMM_EVENT event, struct sk_buff *skb )
-{
-	printk(KERN_ERR __FUNCTION__"():why call me? something is wrong..\n");
-	if(skb)
-		dev_kfree_skb( skb);
-}
-
X 
X /*
X  * ircomm_state_idle
@@ -607,8 +756,11 @@
X 	switch(event){
X 	case IRCOMM_CONNECT_REQUEST:
X 
-		ircomm_next_state(self, COMM_WAITI);
-		issue_connect_request( self, skb );
+		/* ircomm_next_state(self, COMM_WAITI); */
+		/* issue_connect_request( self, skb ); */
+
+		ircomm_next_state(self, COMM_DISCOVERY_WAIT);
+		start_discovering(self);
X 		break;
X 		
X 	case TTP_CONNECT_INDICATION:
@@ -631,6 +783,121 @@
X }
X 
X /*
+ * ircomm_state_discoverywait
+ */
+static void ircomm_state_discoverywait(struct ircomm_cb *self, IRCOMM_EVENT event, 
+				       struct sk_buff *skb )
+{
+	switch(event){
+
+	case TTP_CONNECT_INDICATION:
+
+		ircomm_next_state(self, COMM_WAITR);
+		queryias_done(self);
+		connect_indication( self, self->qos, skb);
+		break;
+
+	case DISCOVERY_INDICATION:
+		ircomm_next_state(self, COMM_QUERYPARAM_WAIT);
+		query_parameters(self);
+		break;
+
+	case IRCOMM_DISCONNECT_REQUEST:
+		ircomm_next_state(self, COMM_IDLE);
+		queryias_done(self);
+		break;
+
+	case QUERYIAS_ERROR:
+		ircomm_next_state(self, COMM_IDLE);
+		disconnect_indication(self, NULL);
+		queryias_done(self);
+		break;
+
+	default:
+		DEBUG(0,__FUNCTION__"():unknown event =%d(%s)\n",
+		      event, ircommevent[event]);
+	}
+}
+
+/*
+ * ircomm_state_queryparamwait
+ */
+
+static void ircomm_state_queryparamwait(struct ircomm_cb *self, IRCOMM_EVENT event, 
+					struct sk_buff *skb )
+{
+	switch(event){
+
+	case TTP_CONNECT_INDICATION:
+
+		ircomm_next_state(self, COMM_WAITR);
+		connect_indication( self, self->qos, skb);
+		break;
+
+	case GOT_PARAMETERS:
+		
+		ircomm_next_state(self, COMM_QUERYLSAP_WAIT);
+		query_lsapsel( self );
+		break;
+
+	case IRCOMM_DISCONNECT_REQUEST:
+		ircomm_next_state(self, COMM_IDLE);
+		queryias_done(self);
+		break;
+
+	case QUERYIAS_ERROR:
+		ircomm_next_state(self, COMM_IDLE);
+		disconnect_indication(self, NULL);
+		queryias_done(self);
+		break;
+
+	default:
+		DEBUG(0,__FUNCTION__"():unknown event =%d(%s)\n",
+		      event, ircommevent[event]);
+	}
+}
+
+/*
+ * ircomm_state_querylsapwait
+ */
+
+static void ircomm_state_querylsapwait(struct ircomm_cb *self, IRCOMM_EVENT event, 
+				       struct sk_buff *skb )
+{
+	switch(event){
+
+	case TTP_CONNECT_INDICATION:
+
+		ircomm_next_state(self, COMM_WAITR);
+		connect_indication( self, self->qos, skb);
+		break;
+
+	case GOT_LSAPSEL:
+		
+		ircomm_next_state(self, COMM_WAITI);
+		queryias_done(self);
+		issue_connect_request( self, skb );
+		break;
+
+	case IRCOMM_DISCONNECT_REQUEST:
+		ircomm_next_state(self, COMM_IDLE);
+		queryias_done(self);
+		break;
+
+	case QUERYIAS_ERROR:
+		ircomm_next_state(self, COMM_IDLE);
+		disconnect_indication(self, NULL);
+		queryias_done(self);
+		break;
+
+
+	default:
+		DEBUG(0,__FUNCTION__"():unknown event =%d(%s)\n",
+		      event, ircommevent[event]);
+	}
+}
+
+/*
X  * ircomm_state_waiti
X  */
X 
@@ -688,6 +955,7 @@
X 	case IRCOMM_DISCONNECT_REQUEST:
X 		ircomm_next_state(self, COMM_IDLE);
X 		issue_disconnect_request(self, skb);
+		queryias_done(self);
X 		break;
X 
X 	case TTP_DISCONNECT_INDICATION:
@@ -695,6 +963,19 @@
X 		disconnect_indication(self, skb);
X 		break;
X 
+	case DISCOVERY_INDICATION:
+		DEBUG(0, __FUNCTION__"():DISCOVERY_INDICATION\n");
+		queryias_done(self);
+		break;
+	case GOT_PARAMETERS:
+		DEBUG(0, __FUNCTION__"():GOT_PARAMETERS\n");
+		queryias_done(self);
+		break;
+	case GOT_LSAPSEL:
+		DEBUG(0, __FUNCTION__"():GOT_LSAPSEL\n");
+		queryias_done(self);
+		break;
+
X /* 	case LMP_DISCONNECT_INDICATION: */
X /* 		disconnect_indication();		 */
X /* 		ircomm_next_state(self, COMM_IDLE);		 */
@@ -732,11 +1013,26 @@
X 	case IRCOMM_DISCONNECT_REQUEST:
X 		ircomm_next_state(self, COMM_IDLE);
X 		issue_disconnect_request(self, skb);
+		queryias_done(self);
X 		break;
X /* 	case LM_DISCONNECT_INDICATION: */
X /* 		disconnect_indication(); */
X /* 		ircomm_next_state(self, COMM_IDLE); */
X /* 		break; */
+
+	case DISCOVERY_INDICATION:
+		DEBUG(0, __FUNCTION__"():DISCOVERY_INDICATION\n");
+		queryias_done(self);
+		break;
+	case GOT_PARAMETERS:
+		DEBUG(0, __FUNCTION__"():GOT_PARAMETERS\n");
+		queryias_done(self);
+		break;
+	case GOT_LSAPSEL:
+		DEBUG(0, __FUNCTION__"():GOT_LSAPSEL\n");
+		queryias_done(self);
+		break;
+
X 	default:
X 		DEBUG(0,"ircomm_state_conn:unknown event =%d(%s)\n",
X 		      event, ircommevent[event]);
@@ -744,6 +1040,7 @@
X }
X 
X 
+
X /*
X  *  ----------------------------------------------------------------------
X  *  IrCOMM service interfaces and supporting functions
@@ -751,172 +1048,97 @@
X  *  ----------------------------------------------------------------------
X  */
X 
-int ircomm_query_ias_and_connect(struct ircomm_cb *self, __u8 servicetype)
-{
-	int retval=0;
-	__u16 hints;
-
-	ASSERT( self != NULL, return -EFAULT;);
-	ASSERT( self->magic == IRCOMM_MAGIC, return -EFAULT;);
-	DEBUG(4,__FUNCTION__"():servicetype = %d\n",servicetype);
+/* 
+ * start_discovering()
+ *
+ * start discovering and enter DISCOVERY_WAIT state
+ */
X 
-	/*
-	 * wait if another instance is discovering now
-	 */  
-	if(discovering_instance){
-		interruptible_sleep_on( &self->discovery_wait);
-		if(signal_pending(current)){
-			return -EINTR; /* cought a signal */
-		}
-		if(self->state == COMM_CONN)
-			return 0;  /* got connected */
-	}
-	ASSERT(discovering_instance == NULL, return -EFAULT;);
-	discovering_instance = self;
+static void start_discovering(struct ircomm_cb *self)
+{
+	__u16  hints; 
+	ASSERT( self != NULL, return;);
+	ASSERT( self->magic == IRCOMM_MAGIC, return;);
+	DEBUG(4,__FUNCTION__"():servicetype = %d\n",self->servicetype);
X 	
-	/*
-	 * start discovering
-	 */
+
X 	hints = irlmp_service_to_hint(S_COMM);
X 
X 	DEBUG(0,__FUNCTION__"():start discovering..\n");
X 	switch (ircomm_cs) {
X 	case 0:
-		skey = irlmp_register_service(hints);
-		ckey = irlmp_register_client(hints, ircomm_discovery_indication,
+		MOD_INC_USE_COUNT;
+		self->queryias_lock = 1;
+		discovering_instance = self;
+		self->skey = irlmp_register_service(hints);
+		self->ckey = irlmp_register_client(hints, ircomm_discovery_indication,
X 					     NULL);
X 		break;
X 		
X 	case 1:    /* client only */
+		MOD_INC_USE_COUNT;
+		self->queryias_lock = 1;
+		discovering_instance = self;
X 		DEBUG( 0, __FUNCTION__"():client only mode\n");
-		ckey = irlmp_register_client(hints, ircomm_discovery_indication,
+		self->ckey = irlmp_register_client(hints, ircomm_discovery_indication,
X 					     NULL);
X 		break;
X 
X 	case 2:     /*  server only  */
X 	default:
X 		DEBUG( 0, __FUNCTION__"():server only mode\n");
-		skey = irlmp_register_service(hints);
+		self->skey = irlmp_register_service(hints);
X 		discovering_instance = NULL;
-		return 0;
+		break;
X 	}
+	
+	return;
+}
X 
+/*
+ * queryias_done(self)
+ *
+ * called when discovery process got wrong results, completed, or terminated.
+ */
X 
-	/*
-	 * waiting for discovery
-	 */
-	interruptible_sleep_on( &self->discovery_wait);
-	if(signal_pending(current)){
-		retval = -EINTR; goto bailout; /* cought a signal */
+static void queryias_done(struct ircomm_cb *self)
+{
+	DEBUG(0, __FUNCTION__"():\n");
+	if(self->queryias_lock){
+		self->queryias_lock = 0;
+		discovering_instance = NULL;
+		MOD_DEC_USE_COUNT;
+		irlmp_unregister_client(self->ckey);
X 	}
-	if(self->state == COMM_CONN)
-		goto bailout;     /* got connected */
+	if(ircomm_cs != 1)
+		irlmp_unregister_service(self->skey);
+	return;
+}
X 
-	/*
-	 * query Parameters field of IAS and waiting for answer
-	 */
X 
-	self->servicetype = 0;
+
+static void query_parameters(struct ircomm_cb *self)
+{
+
X 	DEBUG(0, __FUNCTION__"():querying IAS: Parameters..\n");
X 	iriap_getvaluebyclass_request( "IrDA:IrCOMM", "Parameters",
X 				       self->saddr, self->daddr,
X 				       ircomm_getvalue_confirm, self );
+}
X 
-	interruptible_sleep_on( &self->ias_wait);
-	if(signal_pending(current)){
-		retval = -EINTR; goto bailout; /* cought a signal */
-	}
-	if(self->state == COMM_CONN)
-		goto bailout;     /* got connected */
-
-
-	/* really got Parameters field? */
-	if(self->ias_type != IAS_OCT_SEQ){
-		retval = -EFAULT;
-		goto bailout;
-	}
-
-	/* 
-	 * check if servicetype we want is available 
-	 */
-	self->peer_cap = self->servicetype;
-
-	DEBUG(0,__FUNCTION__"():peer capability is:\n");
-	DEBUG(0,"3wire raw: %s\n",((self->servicetype & THREE_WIRE_RAW) ? "yes":"no"));
-	DEBUG(0,"3wire    : %s\n",((self->servicetype & THREE_WIRE) ? "yes":"no"));
-	DEBUG(0,"9wire    : %s\n",((self->servicetype & NINE_WIRE) ? "yes":"no"));
-	DEBUG(0,"IEEE1284 : %s\n",((self->servicetype & CENTRONICS) ? "yes":"no"));
-
-	self->servicetype &= servicetype;
-	if(!(self->servicetype)){
-		retval = -ENODEV;
-		goto bailout;
-	}
-
-	/*
-	 * then choose better one 
-	 */
X 
-	if(self->servicetype & THREE_WIRE_RAW)
-		servicetype = THREE_WIRE_RAW;
-	if(self->servicetype & THREE_WIRE)
-		servicetype = THREE_WIRE;
-	if(self->servicetype & NINE_WIRE)
-		servicetype = NINE_WIRE;
-	if(self->servicetype & CENTRONICS)
-		servicetype = CENTRONICS;
+static void query_lsapsel(struct ircomm_cb * self)
+{
+	DEBUG(0, __FUNCTION__"():querying IAS: Lsapsel...\n");
X 
-	self->servicetype = servicetype;
-#if 1
-	/*
-	 * waiting for discovery again 
-	 */
-	interruptible_sleep_on( &self->discovery_wait);
-	if(signal_pending(current)){
-		retval = -EINTR; goto bailout; /* cought a signal */
-	}
-	if(self->state == COMM_CONN)
-		goto bailout;     /* got connected */
-#endif
-	/*
-	 * query lsapsel field and waiting for answer
-	 */
-	query_lsapsel(self);
-	interruptible_sleep_on( &self->ias_wait);
-	if(signal_pending(current)){
-		retval = -EINTR; goto bailout; /* cought a signal */
-	}
-	if(self->state == COMM_CONN)
-		goto bailout;     /* got connected */
-
-	/* really got Lsapsel field? */
-	if(self->ias_type != IAS_INTEGER){
-		retval = -EFAULT;
-		goto bailout;
-	} 
-#if 1
-	/*
-	 * waiting for discovery again...
-	 */
-	interruptible_sleep_on( &self->discovery_wait);
-	if(signal_pending(current)){
-		retval = -EINTR; goto bailout; /* cought a signal */
+	if (!(self->servicetype & THREE_WIRE_RAW)) {
+		iriap_getvaluebyclass_request( 
+			"IrDA:IrCOMM", "IrDA:TinyTP:LsapSel",
+			self->saddr, self->daddr,
+			ircomm_getvalue_confirm, self );
+	} else {
+		DEBUG(0, __FUNCTION__ "THREE_WIRE_RAW is not implemented!\n");
X 	}
-	if(self->state == COMM_CONN)
-		goto bailout;     /* got connected */
-#endif
-
-	/* succeed! ready to connect */
-	discovering_instance = NULL;
-	ircomm_connect_request(self);
-	return 0; 
-
- bailout:
-	/* failed.  not ready to connect */
-	discovering_instance = NULL;
-	irlmp_unregister_service(skey);
-	irlmp_unregister_client(ckey);
-	return retval;
X }
X 
X /* 
@@ -926,7 +1148,7 @@
X  */
X 
X 
-void ircomm_connect_request(struct ircomm_cb *self)
+void ircomm_connect_request(struct ircomm_cb *self, __u8 servicetype)
X {
X 	/*
X 	 * TODO:build a packet which contains "initial control parameters"
@@ -939,7 +1161,8 @@
X 
X 	DEBUG(0, __FUNCTION__"():sending connect_request...\n");
X 
-	ircomm_control_request(self, SERVICETYPE); /*servictype*/
+	self->servicetype= servicetype;
+	/* ircomm_control_request(self, SERVICETYPE); */ /*servictype*/
X 
X 	self->maxsdusize = SAR_DISABLE;
X 	ircomm_do_event( self, IRCOMM_CONNECT_REQUEST, NULL);
@@ -986,6 +1209,7 @@
X 	ASSERT( self->magic == IRCOMM_MAGIC, return;);
X 	DEBUG(0,__FUNCTION__"()\n");
X 
+#if 0
X 	/* unregister layer */
X 	switch (ircomm_cs) {
X 	case 1:    /* client only */
@@ -1001,6 +1225,7 @@
X 		irlmp_unregister_service(skey);
X 		break;
X 	}
+#endif
X 
X 	self->disconnect_priority = priority;
X 	if(priority != P_HIGH)
@@ -1353,7 +1578,7 @@
X 			break;
X 		
X 		case SERVICETYPE:
-			self->servicetype = data[2];
+			self->peer_servicetype = data[2];
X 			break;
X 
X 		case PORT_TYPE:
@@ -1480,128 +1705,6 @@
X  * ----------------------------------------------------------------------
X  */
X 
-
-
-/*
- * ircomm_getvalue_confirm()
- * handler for iriap_getvaluebyclass_request() 
- */
-
-static void ircomm_getvalue_confirm( __u16 obj_id, struct ias_value *value,
-				     void *priv)
-{
-	struct ircomm_cb *self = (struct ircomm_cb *) priv;
-	struct sk_buff *skb= NULL;
-	__u8 *frame;
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IRCOMM_MAGIC, return;);
-
-	/* Check if request succeeded */
-	if ( !value) {
-		DEBUG( 0, __FUNCTION__ "(), got NULL value!\n");
-		return;
-	}
-
-	DEBUG(4, __FUNCTION__"():type(%d)\n", value->type);
-
-	self->ias_type = value->type;
-	switch(value->type){
- 	case IAS_OCT_SEQ:
-		
-		DEBUG(4, __FUNCTION__"():got octet sequence:\n");
-#if 0
-		{
-			int i;
-			for ( i=0;i<value->len;i++)
-				printk("%02x",
-				       (__u8)(*(value->t.oct_seq + i)));
-			printk("\n");
-		}
-#endif
-		skb = dev_alloc_skb((value->len) + 2);
-		ASSERT(skb != NULL, return;);
-		frame = skb_put(skb,2);
-		/* MSB first */
-		frame[0] = ( value->len >> 8 ) & 0xff;
-		frame[1] = value->len & 0xff;
-		
-		frame = skb_put(skb,value->len);
-		memcpy(frame, value->t.oct_seq, value->len);
-		ircomm_parse_tuples(self, skb, IAS_PARAM);
-		kfree_skb(skb);
-
-		wake_up_interruptible( &self->ias_wait);
-		break;
-
-	case IAS_INTEGER:
-		/* LsapSel seems to be sent to me */	
-		DEBUG(0, __FUNCTION__"():got lsapsel = %d\n", value->t.integer);
-
-		if ( value->t.integer == -1){
-			DEBUG( 0, __FUNCTION__"():invalid value!\n");
-			return;
-		}
-
-		if(self->state == COMM_IDLE){
-			self->dlsap = value->t.integer;
-
-			wake_up_interruptible( &self->ias_wait);
-		}
-		break;
-
-	case IAS_MISSING:
-		DEBUG( 0, __FUNCTION__":got IAS_MISSING\n");
-		break;
-   
-	default:
-		DEBUG( 0, __FUNCTION__":got unknown (strange?)type!\n");
-		break;
-	}
-}
-
-
-/*
- * query_lsapsel()
- *    quering the remote IAS to ask which
- *    dlsap we should use
- */
-
-static void query_lsapsel(struct ircomm_cb * self)
-{
-	DEBUG(0, __FUNCTION__"():querying IAS: Lsapsel...\n");
-
-	if (!(self->servicetype & THREE_WIRE_RAW)) {
-		iriap_getvaluebyclass_request( 
-			"IrDA:IrCOMM", "IrDA:TinyTP:LsapSel",
-			self->saddr, self->daddr,
-			ircomm_getvalue_confirm, self );
-	} else {
-		DEBUG(0, __FUNCTION__ "THREE_WIRE_RAW is not implemented!\n");
-	}
-}
-
-/*
- * ircomm_discovery_indication()
- *    Remote device is discovered, try query the remote IAS to see which
- *    device it is, and which services it has.
- */
-
-static void ircomm_discovery_indication(discovery_t *discovery)
-{
-	struct ircomm_cb *self;
-
-	self = discovering_instance;
-	ASSERT(self != NULL, return;);
-	ASSERT(self->magic == IRCOMM_MAGIC, return;);
-
-	self->daddr = discovery->daddr;
-	self->saddr = discovery->saddr;
-
-	DEBUG( 0, __FUNCTION__"():daddr=%08x\n", self->daddr);
-
-	wake_up_interruptible( &self->discovery_wait);
-	return;
-}
X 
X 
X struct ircomm_cb * ircomm_open_instance( struct notify_t client_notify)
diff -u --recursive --new-file v2.2.6/linux/net/irda/ircomm/irvtd_driver.c linux/net/irda/ircomm/irvtd_driver.c
--- v2.2.6/linux/net/irda/ircomm/irvtd_driver.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/ircomm/irvtd_driver.c	Sat Apr 24 17:50:06 1999
@@ -51,7 +51,7 @@
X static int irvtd_refcount;
X struct irvtd_cb **irvtd = NULL;
X 
-static char *revision_date = "Wed Mar 10 15:33:03 1999";
+static char *revision_date = "Sun Apr 18 17:31:53 1999";
X 
X 
X /*
@@ -74,6 +74,7 @@
X void irvtd_start(struct tty_struct *tty);
X void irvtd_hangup(struct tty_struct *tty);
X void irvtd_flush_buffer(struct tty_struct *tty);
+void irvtd_flush_chars(struct tty_struct *tty);
X 
X static void change_speed(struct irvtd_cb *driver);
X static void irvtd_write_to_tty( struct irvtd_cb *);
@@ -91,14 +92,6 @@
X 
X 
X /*
- * ----------------------------------------------------------------------
- * 
- *
-
- * ----------------------------------------------------------------------
- */
-
-/*
X  **********************************************************************
X  *
X  * ircomm_receive_data() and friends
@@ -122,11 +115,13 @@
X 	struct sk_buff *skb;
X 	struct tty_struct *tty = driver->tty;
X 	
+	if(driver->rx_disable)
+		return;
+
X 	skb = skb_dequeue(&driver->rxbuff);
X 	if(skb == NULL)
X 		return; /* there's nothing */
X 
-
X 	/* 
X 	 * we should parse controlchannel field here. 
X 	 * (see process_data() in ircomm.c)
@@ -244,6 +239,7 @@
X 		irttp_flow_request(driver->comm->tsap, FLOW_STOP);
X 		driver->ttp_stoprx = 1;
X 	}
+	irvtd_write_to_tty(driver);
X 	return 0;
X }
X 
@@ -268,7 +264,7 @@
X 	
X 	driver->timer.data     = (unsigned long) driver;
X 	driver->timer.function = &irvtd_timer_expired;
-	driver->timer.expires  = jiffies + (HZ / 20);  /* 50msec */
+	driver->timer.expires  = jiffies + (HZ / 5);  /* 200msec */
X 	
X 	add_timer( &driver->timer);
X }
@@ -282,13 +278,10 @@
X 	ASSERT(driver->magic == IRVTD_MAGIC,return;);
X 	DEBUG(4, __FUNCTION__"()\n");
X 
-	if(!(driver->tty->hw_stopped) && !(driver->tx_disable))
-		irvtd_send_data_request(driver);
+	irvtd_send_data_request(driver);
+
+	irvtd_write_to_tty(driver);
X 
-	if(!(driver->rx_disable)){
-		irvtd_write_to_tty(driver);
-	}
-	
X 	/* start our timer again and again */
X 	irvtd_start_timer(driver);
X }
@@ -302,6 +295,8 @@
X 	ASSERT(skb != NULL,return;);
X 	DEBUG(4, __FUNCTION__"()\n");
X 
+	if(driver->tty->hw_stopped || driver->tx_disable)
+		return;
X 	if(!skb->len)
X 		return;   /* no data to send */
X 
@@ -315,7 +310,7 @@
X 	}
X #endif
X 
-	DEBUG(4, __FUNCTION__"():sending %d bytes\n",(int)skb->len );
+	DEBUG(1, __FUNCTION__"():sending %d octets\n",(int)skb->len );
X 	driver->icount.tx += skb->len;
X 	err = ircomm_data_request(driver->comm, driver->txbuff);
X 	if (err){
@@ -327,7 +322,7 @@
X 	/* allocate a new frame */
X 	skb = driver->txbuff = dev_alloc_skb(driver->comm->max_txbuff_size);
X 	if (skb == NULL){
-		printk(__FUNCTION__"():flush_txbuff():alloc_skb failed!\n");
+		printk(__FUNCTION__"():alloc_skb failed!\n");
X 	} else {
X 		skb_reserve(skb, COMM_HEADER_SIZE);
X 	}
@@ -369,10 +364,11 @@
X 	/*
X 	 * sending initial control parameters here
X 	 */
-#if 1
X 	if(driver->comm->servicetype ==	THREE_WIRE_RAW)
X 		return;                /* do nothing */
X 
+	driver->comm->dte |= (MCR_DTR | MCR_RTS | DELTA_DTR | DELTA_RTS);
+
X 	ircomm_control_request(driver->comm, SERVICETYPE);
X 	ircomm_control_request(driver->comm, DATA_RATE);
X 	ircomm_control_request(driver->comm, DATA_FORMAT);
@@ -389,7 +385,6 @@
X 		break;
X 	default:
X 	}
-#endif
X 	
X 	driver->tx_disable = 0;
X 	wake_up_interruptible(&driver->open_wait);
@@ -414,15 +409,27 @@
X 
X 	DEBUG(4,"irvtd_connect_indication:sending connect_response...\n");
X 
-	/*TODO: connect_response should send initialcontrolparameters! TH*/
-
X 	ircomm_connect_response(comm, NULL, SAR_DISABLE );
X 
+	driver->tx_disable = 0;
+
X 	/*
-	 * set default value
+	 * send initial control parameters
X 	 */
+	if(driver->comm->servicetype ==	THREE_WIRE_RAW)
+		return;                /* do nothing */
+
+	driver->comm->dte |= (MCR_DTR | MCR_RTS | DELTA_DTR | DELTA_RTS);
+
+	switch(driver->comm->servicetype){
+	case NINE_WIRE:
+		ircomm_control_request(driver->comm, DTELINE_STATE);
+		break;
+	default:
+	}
+
+
X 	driver->msr |= (MSR_DCD|MSR_RI|MSR_DSR|MSR_CTS);
-	driver->tx_disable = 0;
X 	wake_up_interruptible(&driver->open_wait);
X }
X 
@@ -445,7 +452,13 @@
X 	DEBUG(4,"irvtd_disconnect_indication:\n");
X 
X 	driver->tx_disable = 1;
-	driver->disconnect_pend = 1;
+	if(skb_queue_empty(&driver->rxbuff)){
+		/* disconnect */
+		driver->rx_disable = 1;
+		tty_hangup(driver->tty);
+	} else {
+		driver->disconnect_pend = 1;
+	}
X }
X 
X /*
@@ -559,6 +572,12 @@
X         }
X 	break;
X 
+	case FLOW_CONTROL:
+	case DATA_RATE:
+	case XON_XOFF_CHAR:
+	case DTELINE_STATE:
+		/* (maybe) nothing to do  */
+		break;
X 	default:
X 		DEBUG(0,__FUNCTION__"():PI = 0x%02x is not implemented\n",
X 		      (int)driver->comm->pi);
@@ -624,19 +643,6 @@
X 	while (1) {
X 		current->state = TASK_INTERRUPTIBLE;
X 		
-		if (driver->comm->state == COMM_CONN){
-			/* 
-			 * signal DTR and RTS
-			 */
-			driver->comm->dte = driver->mcr |= (MCR_DTR  |
-							    MCR_RTS  |
-							    DELTA_DTR|
-							    DELTA_RTS );
-
-			ircomm_control_request(driver->comm, DTELINE_STATE);
-		}
-
-
X 		if (tty_hung_up_p(filp) ||
X 		    !(driver->flags & ASYNC_INITIALIZED)) {
X #ifdef DO_RESTART
@@ -755,7 +761,6 @@
X 
X static int irvtd_startup(struct irvtd_cb *driver)
X {
-	int retval = 0;
X 	struct ias_object* obj;
X 	struct notify_t irvtd_notify;
X 
@@ -805,17 +810,13 @@
X 	irias_insert_object( obj);
X 
X 	driver->flags |= ASYNC_INITIALIZED;
+
X 	/*
X 	 * discover a peer device
X 	 *	   TODO: other servicetype(i.e. 3wire,3wireraw) support
X 	 */
-	retval = ircomm_query_ias_and_connect(driver->comm, NINE_WIRE);
-	if(retval){
-		DEBUG(0, __FUNCTION__"(): ircomm_query_ias returns %d\n",
-		      retval);
-		return retval;
-	}
-
+	ircomm_connect_request(driver->comm, NINE_WIRE);
+	
X 	/*
X 	 * TODO:we have to initialize control-channel here!
X 	 *   i.e.set something into RTS,CTS and so on....
@@ -931,7 +932,7 @@
X 	ASSERT(driver->magic == IRVTD_MAGIC, return;);
X 	ASSERT(driver->comm != NULL, return;);
X 
-	DEBUG(0, __FUNCTION__"():\n");	
+	DEBUG(1, __FUNCTION__"():\n");	
X 	if(!tty->closing)
X 		return;   /* nothing to do */
X 	
@@ -944,7 +945,7 @@
X 	orig_jiffies = jiffies;
X 
X 	while (driver->comm->tsap->disconnect_pend) {
-		DEBUG(0, __FUNCTION__"():wait..\n");
+		DEBUG(1, __FUNCTION__"():wait..\n");
X 		current->state = TASK_INTERRUPTIBLE;
X 		current->counter = 0;	/* make us low-priority */
X 		schedule_timeout(HZ);    /* 1sec */
@@ -964,7 +965,7 @@
X 	if (!(driver->flags & ASYNC_INITIALIZED))
X 		return;
X 
-	DEBUG(0,__FUNCTION__"()\n");
+	DEBUG(1,__FUNCTION__"()\n");
X 
X 	/*
X 	 * This comment is written in serial.c:
@@ -1017,7 +1018,7 @@
X 	int line;
X 	unsigned long flags;
X 
-	DEBUG(0, __FUNCTION__"():refcount= %d\n",irvtd_refcount);
+	DEBUG(1, __FUNCTION__"():refcount= %d\n",irvtd_refcount);
X 
X 	ASSERT(driver != NULL, return;);
X 	ASSERT(driver->magic == IRVTD_MAGIC, return;);
@@ -1030,7 +1031,7 @@
X 		 * upper tty layer caught a HUP signal and called irvtd_hangup()
X 		 * before. so we do nothing here.
X 		 */
-		DEBUG(0, __FUNCTION__"():tty_hung_up_p.\n");
+		DEBUG(1, __FUNCTION__"():tty_hung_up_p.\n");
X 		MOD_DEC_USE_COUNT;
X 		restore_flags(flags);
X 		return;
@@ -1142,7 +1143,6 @@
X 
X 	DEBUG(4, __FUNCTION__"()\n");
X 
-
X 	save_flags(flags);
X 	while(1){
X 		cli();
@@ -1164,11 +1164,23 @@
X 		wrote += c;
X 		count -= c;
X 		buf += c;
+		irvtd_send_data_request(driver);
X 	}
X 	restore_flags(flags);
X 	return (wrote);
X }
X 
+void irvtd_flush_chars(struct tty_struct *tty)
+{
+	struct irvtd_cb *driver = (struct irvtd_cb *)tty->driver_data;
+	ASSERT( driver != NULL, return;);
+	ASSERT( driver->magic == IRVTD_MAGIC, return;);
+
+	DEBUG(4, __FUNCTION__"()\n");
+	irvtd_send_data_request(driver);
+}
+
+
X /*
X  * Function irvtd_put_char (tty, ch)
X  *
@@ -1606,14 +1618,14 @@
X 
X static void irvtd_send_xchar(struct tty_struct *tty, char ch){
X 
-	DEBUG(0, __FUNCTION__"():\n");
+	DEBUG(1, __FUNCTION__"():\n");
X 	irvtd_put_char(tty, ch);
X }
X 
X void irvtd_throttle(struct tty_struct *tty){
X 	struct irvtd_cb *driver = (struct irvtd_cb *)tty->driver_data;
X 
-	DEBUG(0, "irvtd_throttle:\n");
+	DEBUG(1, "irvtd_throttle:\n");
X 
X 	if (I_IXOFF(tty))
X 		irvtd_put_char(tty, STOP_CHAR(tty));
@@ -1628,7 +1640,7 @@
X 
X void irvtd_unthrottle(struct tty_struct *tty){
X 	struct irvtd_cb *driver = (struct irvtd_cb *)tty->driver_data;
-	DEBUG(0, "irvtd_unthrottle:\n");
+	DEBUG(1, "irvtd_unthrottle:\n");
X 
X 	if (I_IXOFF(tty))
X 		irvtd_put_char(tty, START_CHAR(tty));
@@ -1760,7 +1772,7 @@
X         irvtd_drv.close = irvtd_close;
X         irvtd_drv.write = irvtd_write;
X         irvtd_drv.put_char = irvtd_put_char;
-	irvtd_drv.flush_chars = NULL;
+	irvtd_drv.flush_chars = irvtd_flush_chars;
X         irvtd_drv.write_room = irvtd_write_room;
X 	irvtd_drv.chars_in_buffer = irvtd_chars_in_buffer; 
X         irvtd_drv.flush_buffer = irvtd_flush_buffer;
@@ -1916,7 +1928,7 @@
X 		memset( irvtd[i], 0, sizeof(struct irvtd_cb));
X 		irvtd[i]->magic = IRVTD_MAGIC;
X 		irvtd[i]->line = i;
-		irvtd[i]->closing_wait = 30*HZ ;
+		irvtd[i]->closing_wait = 10*HZ ;
X 		irvtd[i]->close_delay = 5*HZ/10 ; 
X 	}
X 
diff -u --recursive --new-file v2.2.6/linux/net/irda/irda_device.c linux/net/irda/irda_device.c
--- v2.2.6/linux/net/irda/irda_device.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irda_device.c	Sat Apr 24 17:50:06 1999
@@ -1,12 +1,12 @@
X /*********************************************************************
X  *                
X  * Filename:      irda_device.c
- * Version:       0.4
+ * Version:       0.5
X  * Description:   Abstract device driver layer and helper functions
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Wed Sep  2 20:22:08 1998
- * Modified at:   Wed Apr  7 17:16:54 1999
+ * Modified at:   Wed Apr 21 09:48:19 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
@@ -129,26 +129,28 @@
X 
X 	/* Allocate memory if needed */
X 	if (self->rx_buff.truesize > 0) {
-		self->rx_buff.data = ( __u8 *) kmalloc(self->rx_buff.truesize,
+		self->rx_buff.head = ( __u8 *) kmalloc(self->rx_buff.truesize,
X 						       self->rx_buff.flags);
-		if (self->rx_buff.data == NULL)
+		if (self->rx_buff.head == NULL)
X 			return -ENOMEM;
X 
-		memset(self->rx_buff.data, 0, self->rx_buff.truesize);
+		memset(self->rx_buff.head, 0, self->rx_buff.truesize);
X 	}
X 	if (self->tx_buff.truesize > 0) {
-		self->tx_buff.data = ( __u8 *) kmalloc(self->tx_buff.truesize, 
+		self->tx_buff.head = ( __u8 *) kmalloc(self->tx_buff.truesize, 
X 						       self->tx_buff.flags);
-		if (self->tx_buff.data == NULL)
+		if (self->tx_buff.head == NULL)
X 			return -ENOMEM;
X 
-		memset(self->tx_buff.data, 0, self->tx_buff.truesize);
+		memset(self->tx_buff.head, 0, self->tx_buff.truesize);
X 	}
X 	
X       	self->magic = IRDA_DEVICE_MAGIC;
X 
X 	self->rx_buff.in_frame = FALSE;
X 	self->rx_buff.state = OUTSIDE_FRAME;
+	self->tx_buff.data = self->tx_buff.head;
+	self->rx_buff.data = self->rx_buff.head;
X 
X 	/* Initialize timers */
X 	init_timer(&self->media_busy_timer);	
@@ -184,7 +186,7 @@
X 	/* Open network device */
X 	dev_open(&self->netdev);
X 
-	printk("IrDA device %s registered.\n", self->name);
+	MESSAGE("IrDA: Registred device %s\n", self->name);
X 
X 	irda_device_set_media_busy(self, FALSE);
X 
@@ -197,8 +199,6 @@
X 	/* It's now safe to initilize the saddr */
X 	memcpy(self->netdev.dev_addr, &self->irlap->saddr, 4);
X 
-	DEBUG(4, __FUNCTION__ "()->\n");
-
X 	return 0;
X }
X 
@@ -226,11 +226,11 @@
X 	/* Stop timers */
X 	del_timer(&self->media_busy_timer);
X 
-	if (self->tx_buff.data)
-		kfree(self->tx_buff.data);
+	if (self->tx_buff.head)
+		kfree(self->tx_buff.head);
X 
-	if (self->rx_buff.data)
-		kfree(self->rx_buff.data);
+	if (self->rx_buff.head)
+		kfree(self->rx_buff.head);
X 
X 	self->magic = 0;
X }
@@ -463,26 +463,6 @@
X }
X 
X /*
- * Function irda_get_mtt (skb)
- *
- *    Utility function for getting the minimum turnaround time out of 
- *    the skb, where it has been hidden in the cb field.
- */
-inline unsigned short irda_get_mtt(struct sk_buff *skb)
-{
-	unsigned short mtt;
-
-	if (((struct irlap_skb_cb *)(skb->cb))->magic != LAP_MAGIC)
-		mtt = 10000;
-	else
-		mtt = ((struct irlap_skb_cb *)(skb->cb))->mtt;
-
-	ASSERT(mtt <= 10000, return 10000;);
-	
-	return mtt;
-}
-
-/*
X  * Function setup_dma (idev, buffer, count, mode)
X  *
X  *    Setup the DMA channel
@@ -561,7 +541,6 @@
X 			       self->description);
X 		
X 		len += irda_device_print_flags(self, buf+len);
-
X 		len += sprintf(buf+len, "\tbps\tmaxtt\tdsize\twinsize\taddbofs\tmintt\tldisc\n");
X 		
X 		len += sprintf(buf+len, "\t%d\t", 
diff -u --recursive --new-file v2.2.6/linux/net/irda/iriap.c linux/net/irda/iriap.c
--- v2.2.6/linux/net/irda/iriap.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/iriap.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Thu Aug 21 00:02:07 1997
- * Modified at:   Tue Mar 23 19:38:46 1999
+ * Modified at:   Fri Apr 23 09:57:12 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, 
@@ -31,6 +31,7 @@
X #include <linux/irda.h>
X 
X #include <asm/byteorder.h>
+#include <asm/unaligned.h>
X 
X #include <net/irda/irda.h>
X #include <net/irda/irttp.h>
@@ -172,6 +173,7 @@
X 		DEBUG( 0, "iriap_open: Unable to allocated LSAP!\n");
X 		return NULL;
X 	}
+	slsap_sel = lsap->slsap_sel;
X 	DEBUG( 4, __FUNCTION__ "(), source LSAP sel=%02x\n", slsap_sel);
X 	
X 	self->magic = IAS_MAGIC;
@@ -179,7 +181,7 @@
X 	self->slsap_sel = slsap_sel;
X 	self->mode = mode;
X 
-	/* init_timer( &self->watchdog_timer); */
+	init_timer( &self->watchdog_timer);
X 
X 	hashbin_insert( iriap, (QUEUE*) self, slsap_sel, NULL);
X 	
@@ -204,7 +206,7 @@
X 	ASSERT( self != NULL, return;);
X 	ASSERT( self->magic == IAS_MAGIC, return;);
X 
-	/* del_timer( &self->watchdog_timer); */
+	del_timer( &self->watchdog_timer);
X 
X 	self->magic = 0;
X 
@@ -258,7 +260,7 @@
X 
X 	ASSERT( iriap != NULL, return;);
X 
-	/* del_timer( &self->watchdog_timer); */
+	del_timer( &self->watchdog_timer);
X 
X 	if ( self->mode == IAS_CLIENT) {
X 		DEBUG( 4, __FUNCTION__ "(), disconnect as client\n");
@@ -267,8 +269,8 @@
X 		 * Inform service user that the request failed by sending 
X 		 * it a NULL value.
X 		 */
-		if ( self->confirm)
- 			self->confirm( 0, NULL, self->priv);
+		if (self->confirm)
+ 			self->confirm(IAS_DISCONNECT, 0, NULL, self->priv);
X 		
X 		
X 		iriap_do_client_event( self, IAP_LM_DISCONNECT_INDICATION, 
@@ -348,9 +350,9 @@
X  *    Retreive all values from attribute in all objects with given class
X  *    name
X  */
-void iriap_getvaluebyclass_request( char *name, char *attr, 
-				    __u32 saddr, __u32 daddr,
-				    CONFIRM_CALLBACK callback, void *priv)
+void iriap_getvaluebyclass_request(char *name, char *attr, 
+				   __u32 saddr, __u32 daddr,
+				   CONFIRM_CALLBACK callback, void *priv)
X {
X 	struct sk_buff *skb;
X 	struct iriap_cb *self;
@@ -358,9 +360,9 @@
X 	int name_len, attr_len;
X 	__u8 slsap = LSAP_ANY;  /* Source LSAP to use */
X 
-	DEBUG( 4, __FUNCTION__ "()\n");
+	DEBUG(4, __FUNCTION__ "()\n");
X 	
-	self = iriap_open( slsap, IAS_CLIENT);
+	self = iriap_open(slsap, IAS_CLIENT);
X 	if (!self)
X 		return;
X 
@@ -376,29 +378,29 @@
X 	 */
X 	self->operation = GET_VALUE_BY_CLASS; 
X 
-	/* Give ourselves 7 secs to finish this operation */
-	/* iriap_start_watchdog_timer( self, 700); */
+	/* Give ourselves 10 secs to finish this operation */
+	iriap_start_watchdog_timer(self, 10*HZ);
X 	
X 	skb = dev_alloc_skb( 64);
X 	if (!skb)
X 		return;
X 
-	name_len = strlen( name);
-	attr_len = strlen( attr);
+	name_len = strlen(name);
+	attr_len = strlen(attr);
X 
X 	/* Reserve space for MUX and LAP header */
- 	skb_reserve( skb, LMP_CONTROL_HEADER+LAP_HEADER);
-	skb_put( skb, 3+name_len+attr_len);
+ 	skb_reserve(skb, LMP_CONTROL_HEADER+LAP_HEADER);
+	skb_put(skb, 3+name_len+attr_len);
X 	frame = skb->data;
X 
X 	/* Build frame */
X 	frame[0] = IAP_LST | GET_VALUE_BY_CLASS;
X 	frame[1] = name_len;                       /* Insert length of name */
-	memcpy( frame+2, name, name_len);          /* Insert name */
+	memcpy(frame+2, name, name_len);           /* Insert name */
X 	frame[2+name_len] = attr_len;              /* Insert length of attr */
-	memcpy( frame+3+name_len, attr, attr_len); /* Insert attr */
+	memcpy(frame+3+name_len, attr, attr_len);  /* Insert attr */
X 
-	iriap_do_client_event( self, IAP_CALL_REQUEST_GVBC, skb);
+	iriap_do_client_event(self, IAP_CALL_REQUEST_GVBC, skb);
X }
X 
X /*
@@ -415,7 +417,6 @@
X 	int charset;
X 	__u32 value_len;
X 	__u32 tmp_cpu32;
-	__u16 tmp_cpu16;
X 	__u16 obj_id;
X 	__u16 len;
X 	__u8  type;
@@ -430,14 +431,14 @@
X 	n = 2;
X 
X 	/* Get length, MSB first */
-	memcpy(&len, fp+n, 2); n += 2;
-	be16_to_cpus(&len); 
+	len = be16_to_cpu(get_unaligned((__u16 *)(fp+n))); n += 2;
X 
X 	DEBUG(4, __FUNCTION__ "(), len=%d\n", len);
X 
X 	/* Get object ID, MSB first */
-	memcpy(&obj_id, fp+n, 2); n += 2;
-	be16_to_cpus(&obj_id);
+	obj_id = be16_to_cpu(get_unaligned((__u16 *)(fp+n))); n += 2;
+/* 	memcpy(&obj_id, fp+n, 2); n += 2; */
+/* 	be16_to_cpus(&obj_id); */
X 
X 	type = fp[n++];
X 	DEBUG( 4, __FUNCTION__ "(), Value type = %d\n", type);
@@ -484,9 +485,8 @@
X 		value = irias_new_string_value(fp+n);
X 		break;
X 	case IAS_OCT_SEQ:
-		memcpy(&tmp_cpu16, fp+n, 2);  n += 2;
-		be16_to_cpus(&tmp_cpu16);
-		value_len = tmp_cpu16;
+		value_len = be16_to_cpu(get_unaligned((__u16 *)(fp+n)));
+		n += 2;
X 		
X 		/* FIXME:should be 1024, but.... */
X 		DEBUG(0, __FUNCTION__ "():octet sequence:len=%d\n", value_len);
@@ -499,11 +499,11 @@
X 		break;
X 	}
X 	
-	if (self->confirm)
-		self->confirm(obj_id, value, self->priv);
-	
X 	/* Finished, close connection! */
X 	iriap_disconnect_request(self);
+
+	if (self->confirm)
+		self->confirm(IAS_SUCCESS, obj_id, value, self->priv);
X }
X 
X /*
@@ -550,7 +550,7 @@
X 	fp[n++] = ret_code;
X 
X 	/* Insert list length (MSB first) */
-	tmp_be16 = __constant_htons( 0x0001);
+	tmp_be16 = __constant_htons(0x0001);
X 	memcpy(fp+n, &tmp_be16, 2);  n += 2; 
X 
X 	/* Insert object identifier ( MSB first) */
@@ -703,17 +703,17 @@
X {
X 	struct iriap_cb *self;
X 	
-	self = ( struct iriap_cb *) instance;
+	self = (struct iriap_cb *) instance;
X 
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IAS_MAGIC, return;);
-	ASSERT( userdata != NULL, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IAS_MAGIC, return;);
+	ASSERT(userdata != NULL, return;);
X 	
-	DEBUG( 4, __FUNCTION__ "()\n");
+	DEBUG(4, __FUNCTION__ "()\n");
X 	
X 	/* del_timer( &self->watchdog_timer); */
X 
-	iriap_do_client_event( self, IAP_LM_CONNECT_CONFIRM, userdata);
+	iriap_do_client_event(self, IAP_LM_CONNECT_CONFIRM, userdata);
X }
X 
X /*
@@ -778,7 +778,7 @@
X 	}
X 
X 	if (~opcode & IAP_ACK) {
-		DEBUG(0, __FUNCTION__ "() Got ack frame!\n");
+		DEBUG(2, __FUNCTION__ "() Got ack frame!\n");
X 	/* 	return; */
X 	}
X 
@@ -797,9 +797,21 @@
X 			break;
X 		case IAS_CLASS_UNKNOWN:
X 			printk(KERN_WARNING "IrIAP No such class!\n");
+			/* Finished, close connection! */
+			iriap_disconnect_request(self);
+
+			if (self->confirm)
+				self->confirm(IAS_CLASS_UNKNOWN, 0, NULL, 
+					      self->priv);
X 			break;
X 		case IAS_ATTRIB_UNKNOWN:
X 			printk(KERN_WARNING "IrIAP No such attribute!\n");
+		       	/* Finished, close connection! */
+			iriap_disconnect_request(self);
+
+			if (self->confirm)
+				self->confirm(IAS_CLASS_UNKNOWN, 0, NULL, 
+					      self->priv);
X 			break;
X 		}
X 		iriap_do_call_event( self, IAP_RECV_F_LST, skb);
@@ -854,18 +866,20 @@
X 	}
X }
X 
+/*
+ * Function iriap_watchdog_timer_expired (data)
+ *
+ *    
+ *
+ */
X void iriap_watchdog_timer_expired( unsigned long data)
X {
X 	struct iriap_cb *self = ( struct iriap_cb *) data;
X 	
-	DEBUG( 0, __FUNCTION__ "()\n");
-
-	return;
-
-	ASSERT( self != NULL, return;);
- ASSERT( self->magic == IAS_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IAS_MAGIC, return;);
X 
-	DEBUG( 0, __FUNCTION__ "() Timeout! closing myself!\n");
+	DEBUG(0, __FUNCTION__ "() Timeout! closing myself!\n");
X 	iriap_close( self);
X }
X 
diff -u --recursive --new-file v2.2.6/linux/net/irda/irlan/irlan_client.c linux/net/irda/irlan/irlan_client.c
--- v2.2.6/linux/net/irda/irlan/irlan_client.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irlan/irlan_client.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Wed Apr  7 16:56:35 1999
+ * Modified at:   Thu Apr 22 23:03:55 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * Sources:       skeleton.c by Donald Becker <bec...@CESDIS.gsfc.nasa.gov>
X  *                slip.c by Laurence Culhane, <l...@holmes.demon.co.uk>
@@ -30,7 +30,6 @@
X #include <linux/errno.h>
X #include <linux/init.h>
X #include <linux/netdevice.h>
-#include <linux/inetdevice.h>
X #include <linux/etherdevice.h>
X #include <linux/if_arp.h>
X #include <net/arp.h>
@@ -106,7 +105,7 @@
X {
X 	struct irmanager_event mgr_event;
X 
-	DEBUG(2, __FUNCTION__ "()\n");
+	DEBUG(0, __FUNCTION__ "()\n");
X 
X 	ASSERT(self != NULL, return;);
X 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -122,8 +121,8 @@
X 	if (self->dev.start) {
X 		/* Open TSAPs */
X 		irlan_client_open_ctrl_tsap(self);
-		irlan_provider_open_ctrl_tsap(self);
-		irlan_open_data_tsap(self);
+ 		irlan_provider_open_ctrl_tsap(self);
+ 		irlan_open_data_tsap(self);
X 		
X 		irlan_do_client_event(self, IRLAN_DISCOVERY_INDICATION, NULL);
X 	} else if (self->notify_irmanager) {
@@ -162,7 +161,7 @@
X 	struct irlan_cb *self, *entry;
X 	__u32 saddr, daddr;
X 	
-	DEBUG(2, __FUNCTION__"()\n");
+	DEBUG(0, __FUNCTION__"()\n");
X 
X 	ASSERT(irlan != NULL, return;);
X 	ASSERT(discovery != NULL, return;);
@@ -171,8 +170,7 @@
X 	daddr = discovery->daddr;
X 
X 	/* 
-	 *  Check if we already have an instance for dealing with this 
-	 *  provider.
+	 *  Check if we already dealing with this provider.
X 	 */
X 	self = (struct irlan_cb *) hashbin_find(irlan, daddr, NULL);
X       	if (self) {
@@ -190,7 +188,7 @@
X 	 */
X 	self = hashbin_find(irlan, DEV_ADDR_ANY, NULL);
X 	if (self) {
-		DEBUG(2, __FUNCTION__ "(), Found instance with DEV_ADDR_ANY!\n");
+		DEBUG(0, __FUNCTION__ "(), Found instance with DEV_ADDR_ANY!\n");
X 		/*
X 		 * Rehash instance, now we have a client (daddr) to serve.
X 		 */
@@ -200,27 +198,16 @@
X 		self->daddr = daddr;
X 		self->saddr = saddr;
X 
-		DEBUG(2, __FUNCTION__ "(), daddr=%08x\n", self->daddr);
+		DEBUG(0, __FUNCTION__ "(), daddr=%08x\n", self->daddr);
X 		hashbin_insert(irlan, (QUEUE*) self, self->daddr, NULL);
X 		
X 		/* Check if network device has been registered */
X 		if (!self->netdev_registered)
X 			irlan_register_netdev(self);
X 		
-		/* Remember that we might have to start a new provider */
-		self->client.start_new_provider = TRUE;
-	} else {
-		DEBUG(2, __FUNCTION__ "(), Found none, starting new one!\n");
-		/* No instance available, so we have to start one! */
-		self = irlan_open(saddr, daddr, TRUE);
-		if (!self) {
-			DEBUG(2, __FUNCTION__ "(), irlan_open failed!\n");
-			return;
-		}
-		ASSERT( self != NULL, return;);
+		/* Restart watchdog timer */
+		irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
X 	}
-	/* Restart watchdog timer */
-	irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
X }
X 	
X /*
@@ -367,13 +354,12 @@
X }
X 
X /*
- * Function irlan_client_extract_params (skb)
+ * Function irlan_client_parse_response (self, skb)
X  *
X  *    Extract all parameters from received buffer, then feed them to 
X  *    check_params for parsing
- *
X  */
-void irlan_client_extract_params(struct irlan_cb *self, struct sk_buff *skb)
+void irlan_client_parse_response(struct irlan_cb *self, struct sk_buff *skb)
X {
X 	__u8 *frame;
X 	__u8 *ptr;
@@ -392,7 +378,7 @@
X 	ASSERT(self->magic == IRLAN_MAGIC, return;);
X 	
X 	if (!skb) {
-		DEBUG(2, __FUNCTION__ "(), Got NULL skb!\n");
+		ERROR( __FUNCTION__ "(), Got NULL skb!\n");
X 		return;
X 	}
X 	frame = skb->data;
@@ -423,7 +409,7 @@
X 
X 	/* For all parameters */
X  	for (i=0; i<count;i++) {
-		ret = irlan_get_param(ptr, name, value, &val_len);
+		ret = irlan_extract_param(ptr, name, value, &val_len);
X if (ret == -1) {
X 			DEBUG(2, __FUNCTION__ "(), IrLAN, Error!\n");
X 			break;
@@ -445,9 +431,6 @@
X static void irlan_check_response_param(struct irlan_cb *self, char *param, 
X 				       char *value, int val_len) 
X {
-#ifdef CONFIG_IRLAN_GRATUITOUS_ARP
-	struct in_device *in_dev;
-#endif
X 	__u16 tmp_cpu; /* Temporary value in host order */
X 	__u8 *bytes;
X 	int i;
@@ -550,21 +533,6 @@
X 		      bytes[5]);
X 		for (i = 0; i < 6; i++) 
X 			self->dev.dev_addr[i] = bytes[i];
-
-#ifdef CONFIG_IRLAN_GRATUITOUS_ARP
-		/* 
-		 * When we get a new MAC address do a gratuitous ARP. This
-		 * is useful if we have changed access points on the same
-		 * subnet.  
-		 */
-		DEBUG(4, "IrLAN: Sending gratuitous ARP\n");
-		in_dev = self->dev.ip_ptr;
-		arp_send(ARPOP_REQUEST, ETH_P_ARP, 
-			  in_dev->ifa_list->ifa_address,
-			  &self->dev, 
-			  in_dev->ifa_list->ifa_address,
-			  NULL, self->dev.dev_addr, NULL);
-#endif
X 	}
X }
X 
@@ -574,8 +542,8 @@
X  *    Got results from remote LM-IAS
X  *
X  */
-void irlan_client_get_value_confirm(__u16 obj_id, struct ias_value *value,
-				    void *priv) 
+void irlan_client_get_value_confirm(int result, __u16 obj_id, 
+				    struct ias_value *value, void *priv) 
X {
X 	struct irlan_cb *self;
X 	
@@ -587,7 +555,7 @@
X 	ASSERT(self->magic == IRLAN_MAGIC, return;);
X 
X 	/* Check if request succeeded */
-	if (!value) {
+	if (result != IAS_SUCCESS) {
X 		DEBUG(2, __FUNCTION__ "(), got NULL value!\n");
X 		irlan_do_client_event(self, IRLAN_IAS_PROVIDER_NOT_AVAIL, 
X 				      NULL);
diff -u --recursive --new-file v2.2.6/linux/net/irda/irlan/irlan_client_event.c linux/net/irda/irlan/irlan_client_event.c
--- v2.2.6/linux/net/irda/irlan/irlan_client_event.c	Wed Mar 10 15:29:52 1999
+++ linux/net/irda/irlan/irlan_client_event.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Thu Feb  4 16:08:07 1999
+ * Modified at:   Thu Apr 22 12:23:22 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1998 Dag Brattli <da...@cs.uit.no>, 
@@ -226,7 +226,7 @@
X 	case IRLAN_DATA_INDICATION:
X 		ASSERT(skb != NULL, return -1;);
X 	
-		irlan_client_extract_params(self, skb);
+		irlan_client_parse_response(self, skb);
X 		
X 		irlan_next_client_state(self, IRLAN_MEDIA);
X 		
@@ -266,7 +266,7 @@
X 
X 	switch(event) {
X 	case IRLAN_DATA_INDICATION:
-		irlan_client_extract_params(self, skb);
+		irlan_client_parse_response(self, skb);
X 		irlan_open_data_channel(self);
X 		irlan_next_client_state(self, IRLAN_OPEN);
X 		break;
@@ -305,7 +305,7 @@
X 
X 	switch(event) {
X 	case IRLAN_DATA_INDICATION:
-		irlan_client_extract_params(self, skb);
+		irlan_client_parse_response(self, skb);
X 		
X 		/*
X 		 *  Check if we have got the remote TSAP for data 
@@ -336,11 +336,6 @@
X 					      IRLAN_MTU, NULL);
X 			
X 			irlan_next_client_state(self, IRLAN_DATA);
-
-			if (self->client.start_new_provider) {
-				irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY, FALSE);
-				self->client.start_new_provider = FALSE;
-			}
X 			break;
X 		default:
X 			DEBUG(2, __FUNCTION__ "(), unknown access type!\n");
@@ -468,7 +463,7 @@
X 
X 	switch(event) {
X 	case IRLAN_DATA_INDICATION:
-		irlan_client_extract_params(self, skb);
+		irlan_client_parse_response(self, skb);
X 		break;		
X 	case IRLAN_LMP_DISCONNECT: /* FALLTHROUGH */
X 	case IRLAN_LAP_DISCONNECT:
diff -u --recursive --new-file v2.2.6/linux/net/irda/irlan/irlan_common.c linux/net/irda/irlan/irlan_common.c
--- v2.2.6/linux/net/irda/irlan/irlan_common.c	Fri Apr 16 14:47:31 1999
+++ linux/net/irda/irlan/irlan_common.c	Sat Apr 24 17:50:06 1999
@@ -6,7 +6,7 @@
X  * Status:        Experimental.
X  * Author:        Dag Brattli <da...@cs.uit.no>
X  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Wed Apr  7 17:03:21 1999
+ * Modified at:   Thu Apr 22 23:13:47 1999
X  * Modified by:   Dag Brattli <da...@cs.uit.no>
X  * 
X  *     Copyright (c) 1997 Dag Brattli <da...@cs.uit.no>, All Rights Reserved.
@@ -112,9 +112,11 @@
X void irlan_watchdog_timer_expired(unsigned long data)
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 20'
echo 'File patch-2.2.7 is continued in part 21'
echo 21 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 19 of a 22 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.2.7 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 19; then
        echo Please unpack part "$Scheck" next!
        exit 1
 else
        exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.2.7'
else
echo 'x - continuing with patch-2.2.7'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.2.7' &&
@@ -545,6 +534,17 @@
X 	if(chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
X 		sk->saddr = 0;  /* Use device */
X 
+	snum = ntohs(addr->sin_port);
+#ifdef CONFIG_IP_MASQUERADE
+	/* The kernel masquerader needs some ports. */
+	if((snum >= PORT_MASQ_BEGIN) && (snum <= PORT_MASQ_END))
+		return -EADDRINUSE;
+#endif		 
+	if (snum == 0) 
+		snum = sk->prot->good_socknum();
+	if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
+		return(-EACCES);
+	
X 	/* Make sure we are allowed to bind here. */
X 	if(sk->prot->verify_bind(sk, snum))
X 		return -EADDRINUSE;
diff -u --recursive --new-file v2.2.6/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
--- v2.2.6/linux/net/ipv4/ip_fw.c	Wed Jan 13 15:00:44 1999
+++ linux/net/ipv4/ip_fw.c	Thu Apr 22 19:45:19 1999
@@ -32,6 +32,8 @@
X  * 3-Jan-1999:  Fixed serious procfs security hole -- users should never
X  *              be allowed to view the chains!
X  *              Marc Santoro <ult...@snicker.emoti.com>
+ * 29-Jan-1999: Locally generated bogus IPs dealt with, rather than crash
+ *              during dump_packet. --RR.
X  */
X 
X /*
@@ -1660,6 +1662,10 @@
X int ipfw_output_check(struct firewall_ops *this, int pf, struct device *dev, 
X 		      void *phdr, void *arg, struct sk_buff **pskb)
X {
+	/* Locally generated bogus packets by root. <SIGH>. */
+	if (((struct iphdr *)phdr)->ihl * 4 < sizeof(struct iphdr)
+	    || (*pskb)->len < sizeof(struct iphdr))
+		return FW_ACCEPT;
X 	return ip_fw_check(phdr, dev->name,
X 			   arg, IP_FW_OUTPUT_CHAIN, *pskb, SLOT_NUMBER(), 0);
X }
diff -u --recursive --new-file v2.2.6/linux/net/ipv4/ip_input.c linux/net/ipv4/ip_input.c
--- v2.2.6/linux/net/ipv4/ip_input.c	Tue Mar 23 14:35:48 1999
+++ linux/net/ipv4/ip_input.c	Thu Apr 22 19:45:19 1999
@@ -5,7 +5,7 @@
X  *
X  *		The Internet Protocol (IP) module.
X  *
- * Version:	$Id: ip_input.c,v 1.36 1999/03/21 05:22:38 davem Exp $
+ * Version:	$Id: ip_input.c,v 1.37 1999/04/22 10:38:36 davem Exp $
X  *
X  * Authors:	Ross Biro, <bi...@leland.Stanford.Edu>
X  *		Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -253,7 +253,19 @@
X 	 * Do we need to de-masquerade this packet?
X 	 */
X         {
-		int ret = ip_fw_demasquerade(&skb);
+		int ret;
+		/*
+		 *	Some masq modules can re-inject packets if
+		 *	bad configured.
+		 */
+
+		if((IPCB(skb)->flags&IPSKB_MASQUERADED)) {
+			printk(KERN_DEBUG "ip_input(): demasq recursion detected. Check masq modules configuration\n");
+			kfree_skb(skb);
+			return 0;
+		}
+
+		ret = ip_fw_demasquerade(&skb);
X 		if (ret < 0) {
X 			kfree_skb(skb);
X 			return 0;
diff -u --recursive --new-file v2.2.6/linux/net/ipv4/ip_sockglue.c linux/net/ipv4/ip_sockglue.c
--- v2.2.6/linux/net/ipv4/ip_sockglue.c	Mon Mar 29 11:09:12 1999
+++ linux/net/ipv4/ip_sockglue.c	Thu Apr 22 19:45:19 1999
@@ -5,7 +5,7 @@
X  *
X  *		The IP to API glue.
X  *		
- * Version:	$Id: ip_sockglue.c,v 1.41 1999/03/25 10:04:29 davem Exp $
+ * Version:	$Id: ip_sockglue.c,v 1.42 1999/04/22 10:07:34 davem Exp $
X  *
X  * Authors:	see ip.c
X  *
@@ -150,7 +150,8 @@
X 	struct cmsghdr *cmsg;
X 
X 	for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
-		if ((unsigned long)(((char*)cmsg - (char*)msg->msg_control)
+		if (cmsg->cmsg_len < sizeof(struct cmsghdr) ||
+		    (unsigned long)(((char*)cmsg - (char*)msg->msg_control)
X 				    + cmsg->cmsg_len) > msg->msg_controllen) {
X 			return -EINVAL;
X 		}
diff -u --recursive --new-file v2.2.6/linux/net/ipv4/route.c linux/net/ipv4/route.c
--- v2.2.6/linux/net/ipv4/route.c	Mon Mar 29 11:09:12 1999
+++ linux/net/ipv4/route.c	Thu Apr 22 19:45:19 1999
@@ -5,7 +5,7 @@
X  *
X  *		ROUTE - implementation of the IP router.
X  *
- * Version:	$Id: route.c,v 1.65 1999/03/25 10:04:35 davem Exp $
+ * Version:	$Id: route.c,v 1.66 1999/04/22 10:07:35 davem Exp $
X  *
X  * Authors:	Ross Biro, <bi...@leland.Stanford.Edu>
X  *		Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -281,6 +281,9 @@
X 	if (atomic_read(&rth->u.dst.use))
X 		return 0;
X 
+	if (rth->u.dst.expires && (long)(rth->u.dst.expires - jiffies) <= 0)
+		return 1;
+
X 	age = jiffies - rth->u.dst.lastuse;
X 	if (age <= tmo1 && !rt_fast_clean(rth))
X 		return 0;
@@ -305,7 +308,7 @@
X 		while ((rth = *rthp) != NULL) {
X 			if (rth->u.dst.expires) {
X 				/* Entrie is expired even if it is in use */
-				if ((long)(now - rth->u.dst.expires) < tmo) {
+				if ((long)(now - rth->u.dst.expires) <= 0) {
X 					tmo >>= 1;
X 					rthp = &rth->u.rt_next;
X 					continue;
@@ -564,8 +567,11 @@
X 			 */
X 			if (attempts-- > 0) {
X 				int saved_elasticity = ip_rt_gc_elasticity;
+				int saved_int = ip_rt_gc_min_interval;
X 				ip_rt_gc_elasticity = 1;
+				ip_rt_gc_min_interval = 0;
X 				rt_garbage_collect();
+				ip_rt_gc_min_interval = saved_int;
X 				ip_rt_gc_elasticity = saved_elasticity;
X 				goto restart;
X 			}
@@ -885,7 +891,16 @@
X 			}
X 		}
X 	}
-	return est_mtu;
+	return est_mtu ? : new_mtu;
+}
+
+void ip_rt_update_pmtu(struct dst_entry *dst, unsigned mtu)
+{
+	if (dst->pmtu > mtu && mtu >= 68 &&
+	    !(dst->mxlock&(1<<RTAX_MTU))) {
+		dst->pmtu = mtu;
+		dst_set_expires(dst, ip_rt_mtu_expires);
+	}
X }
X 
X static struct dst_entry * ipv4_dst_check(struct dst_entry * dst, u32 cookie)
@@ -1850,7 +1865,7 @@
X 	for (h=0; h < RT_HASH_DIVISOR; h++) {
X 		if (h < s_h) continue;
X 		if (h > s_h)
- memset(&cb->args[1], 0, sizeof(cb->args) - sizeof(cb->args[0]));
+			s_idx = 0;
X 		start_bh_atomic();
X 		for (rt = rt_hash_table[h], idx = 0; rt; rt = rt->u.rt_next, idx++) {
X 			if (idx < s_idx)
diff -u --recursive --new-file v2.2.6/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v2.2.6/linux/net/ipv4/tcp.c	Tue Mar 23 14:35:48 1999
+++ linux/net/ipv4/tcp.c	Thu Apr 22 19:45:19 1999
@@ -5,7 +5,7 @@
X  *
X  *		Implementation of the Transmission Control Protocol(TCP).
X  *
- * Version:	$Id: tcp.c,v 1.139 1999/03/17 19:30:34 davem Exp $
+ * Version:	$Id: tcp.c,v 1.140 1999/04/22 10:34:31 davem Exp $
X  *
X  * Authors:	Ross Biro, <bi...@leland.Stanford.Edu>
X  *		Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -772,7 +772,7 @@
X 		iov++;
X 
X 		while(seglen > 0) {
-			int copy, tmp, queue_it;
+			int copy, tmp, queue_it, psh;
X 
X 			if (err)
X 				goto do_fault2;
@@ -854,11 +854,14 @@
X 			 * being outside the window, it will be queued
X 			 * for later rather than sent.
X 			 */
+			psh = 0;
X 			copy = tp->snd_wnd - (tp->snd_nxt - tp->snd_una);
-			if(copy > (tp->max_window >> 1))
+			if(copy > (tp->max_window >> 1)) {
X 				copy = min(copy, mss_now);
-			else
+				psh = 1;
+			} else {
X 				copy = mss_now;
+			}
X 			if(copy > seglen)
X 				copy = seglen;
X 
@@ -906,7 +909,7 @@
X 
X 			/* Prepare control bits for TCP header creation engine. */
X 			TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK |
-						  (PSH_NEEDED ?
+						  ((PSH_NEEDED || psh) ?
X 						   TCPCB_FLAG_PSH : 0));
X 			TCP_SKB_CB(skb)->sacked = 0;
X 			if (flags & MSG_OOB) {
diff -u --recursive --new-file v2.2.6/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- v2.2.6/linux/net/ipv4/tcp_input.c	Tue Mar 23 14:35:48 1999
+++ linux/net/ipv4/tcp_input.c	Wed Apr 28 09:51:57 1999
@@ -5,7 +5,7 @@
X  *
X  *		Implementation of the Transmission Control Protocol(TCP).
X  *
- * Version:	$Id: tcp_input.c,v 1.159 1999/03/17 19:30:39 davem Exp $
+ * Version:	$Id: tcp_input.c,v 1.163 1999/04/28 16:08:05 davem Exp $
X  *
X  * Authors:	Ross Biro, <bi...@leland.Stanford.Edu>
X  *		Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -97,7 +97,7 @@
X static void tcp_delack_estimator(struct tcp_opt *tp)
X {
X 	if(tp->ato == 0) {
-		tp->lrcvtime = jiffies;
+		tp->lrcvtime = tcp_time_stamp;
X 
X 		/* Help sender leave slow start quickly,
X 		 * and also makes sure we do not take this
@@ -106,9 +106,9 @@
X 		tp->ato = 1;
X 		tcp_enter_quickack_mode(tp);
X 	} else {
-		int m = jiffies - tp->lrcvtime;
+		int m = tcp_time_stamp - tp->lrcvtime;
X 
-		tp->lrcvtime = jiffies;
+		tp->lrcvtime = tcp_time_stamp;
X 		if(m <= 0)
X 			m = 1;
X 		if(m > tp->rto)
@@ -231,7 +231,7 @@
X 		 */
X 		if((s32)(tp->rcv_tsval - tp->ts_recent) >= 0) {
X 			tp->ts_recent = tp->rcv_tsval;
-			tp->ts_recent_stamp = jiffies;
+			tp->ts_recent_stamp = tcp_time_stamp;
X 		}
X 	}
X }
@@ -241,7 +241,7 @@
X extern __inline__ int tcp_paws_discard(struct tcp_opt *tp, struct tcphdr *th, unsigned len)
X {
X 	/* ts_recent must be younger than 24 days */
-	return (((s32)(jiffies - tp->ts_recent_stamp) >= PAWS_24DAYS) ||
+	return (((s32)(tcp_time_stamp - tp->ts_recent_stamp) >= PAWS_24DAYS) ||
X 		(((s32)(tp->rcv_tsval - tp->ts_recent) < 0) &&
X 		 /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM */
X 		 (len != (th->doff * 4))));
@@ -609,7 +609,7 @@
X {
X 	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
X 	struct sk_buff *skb;
-	unsigned long now = jiffies;
+	__u32 now = tcp_time_stamp;
X 	int acked = 0;
X 
X 	/* If we are retransmitting, and this ACK clears up to
@@ -725,7 +725,7 @@
X 	if (!(flag & FLAG_DATA_ACKED))
X 		return;
X 
-	seq_rtt = jiffies-tp->rcv_tsecr;
+	seq_rtt = tcp_time_stamp - tp->rcv_tsecr;
X 	tcp_rtt_estimator(tp, seq_rtt);
X 	if (tp->retransmits) {
X 		if (tp->packets_out == 0) {
@@ -749,7 +749,7 @@
X static __inline__ void tcp_ack_packets_out(struct sock *sk, struct tcp_opt *tp)
X {
X 	struct sk_buff *skb = skb_peek(&sk->write_queue);
-	long when = tp->rto - (jiffies - TCP_SKB_CB(skb)->when);
+	__u32 when = tp->rto - (tcp_time_stamp - TCP_SKB_CB(skb)->when);
X 
X 	/* Some data was ACK'd, if still retransmitting (due to a
X 	 * timeout), resend more of the retransmit queue.  The
@@ -778,7 +778,7 @@
X 	if (tp->pending == TIME_KEEPOPEN)
X 	  	tp->probes_out = 0;
X 
-	tp->rcv_tstamp = jiffies;
+	tp->rcv_tstamp = tcp_time_stamp;
X 
X 	/* If the ack is newer than sent or older than previous acks
X 	 * then we can probably ignore it.
@@ -2112,7 +2112,7 @@
X 				tp->tcp_header_len = sizeof(struct tcphdr);
X 			if (tp->saw_tstamp) {
X 				tp->ts_recent = tp->rcv_tsval;
-				tp->ts_recent_stamp = jiffies;
+				tp->ts_recent_stamp = tcp_time_stamp;
X 			}
X 
X 			/* Can't be earlier, doff would be wrong. */
@@ -2136,7 +2136,7 @@
X 				tcp_parse_options(sk, th, tp, 0);
X 				if (tp->saw_tstamp) {
X 					tp->ts_recent = tp->rcv_tsval;
-					tp->ts_recent_stamp = jiffies;
+					tp->ts_recent_stamp = tcp_time_stamp;
X 				}
X 				
X 				tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;
@@ -2189,8 +2189,22 @@
X 		}
X 	}
X 
+	/* The silly FIN test here is necessary to see an advancing ACK in
+	 * retransmitted FIN frames properly.  Consider the following sequence:
+	 *
+	 *	host1 --> host2		FIN XSEQ:XSEQ(0) ack YSEQ
+	 *	host2 --> host1		FIN YSEQ:YSEQ(0) ack XSEQ
+	 *	host1 --> host2		XSEQ:XSEQ(0) ack YSEQ+1
+	 *	host2 --> host1		FIN YSEQ:YSEQ(0) ack XSEQ+1	(fails tcp_sequence test)
+	 *
+	 * At this point the connection will deadlock with host1 believing
+	 * that his FIN is never ACK'd, and thus it will retransmit it's FIN
+	 * forever.  The following fix is from Taral (ta...@taral.net).
+	 */
+
X 	/* step 1: check sequence number */
-	if (!tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)) {
+	if (!tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq) &&
+	    !(th->fin && TCP_SKB_CB(skb)->end_seq == tp->rcv_nxt)) {
X 		if (!th->rst) {
X 			tcp_send_ack(sk);
X 			goto discard;
diff -u --recursive --new-file v2.2.6/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- v2.2.6/linux/net/ipv4/tcp_ipv4.c	Mon Mar 29 11:09:12 1999
+++ linux/net/ipv4/tcp_ipv4.c	Wed Apr 28 09:51:57 1999
@@ -5,7 +5,7 @@
X  *
X  *		Implementation of the Transmission Control Protocol(TCP).
X  *
- * Version:	$Id: tcp_ipv4.c,v 1.171 1999/03/28 10:18:26 davem Exp $
+ * Version:	$Id: tcp_ipv4.c,v 1.174 1999/04/28 16:08:19 davem Exp $
X  *
X  *		IPv4 specific functions
X  *
@@ -629,6 +629,7 @@
X 
X 	if (!tcp_v4_unique_address(sk)) {
X 		kfree_skb(buff);
+		sk->daddr = 0;
X 		return -EADDRNOTAVAIL;
X 	}
X 
@@ -722,7 +723,7 @@
X /* 
X  * This routine does path mtu discovery as defined in RFC1191.
X  */
-static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *ip)
+static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *ip, unsigned mtu)
X {
X 	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
X 
@@ -742,8 +743,10 @@
X      	 * There is a small race when the user changes this flag in the
X 	 * route, but I think that's acceptable.
X 	 */
-	if (sk->dst_cache &&
-	    sk->ip_pmtudisc != IP_PMTUDISC_DONT &&
+	if (sk->dst_cache == NULL)
+		return;
+	ip_rt_update_pmtu(sk->dst_cache, mtu);
+	if (sk->ip_pmtudisc != IP_PMTUDISC_DONT &&
X 	    tp->pmtu_cookie > sk->dst_cache->pmtu) {
X 		tcp_sync_mss(sk, sk->dst_cache->pmtu);
X 
@@ -830,7 +833,7 @@
X 			return;
X 
X 		if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */
-			do_pmtu_discovery(sk, iph); 
+			do_pmtu_discovery(sk, iph, ntohs(skb->h.icmph->un.frag.mtu));
X 			return;
X 		}
X 
@@ -1355,7 +1358,14 @@
X 		newtp->last_ack_sent = req->rcv_isn + 1;
X 		newtp->backoff = 0;
X 		newtp->mdev = TCP_TIMEOUT_INIT;
-		newtp->snd_cwnd = 1;
+
+		/* So many TCP implementations out there (incorrectly) count the
+		 * initial SYN frame in their delayed-ACK and congestion control
+		 * algorithms that we must have the following bandaid to talk
+		 * efficiently to them.  -DaveM
+		 */
+		newtp->snd_cwnd = 2;
+
X 		newtp->rto = TCP_TIMEOUT_INIT;
X 		newtp->packets_out = 0;
X 		newtp->fackets_out = 0;
@@ -1420,7 +1430,7 @@
X 		}
X 		if (newtp->tstamp_ok) {
X 			newtp->ts_recent = req->ts_recent;
-			newtp->ts_recent_stamp = jiffies;
+			newtp->ts_recent_stamp = tcp_time_stamp;
X 			newtp->tcp_header_len = sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED;
X 		} else {
X 			newtp->tcp_header_len = sizeof(struct tcphdr);
@@ -1595,6 +1605,7 @@
X 		 * the new socket..
X 		 */
X 		if (atomic_read(&nsk->sock_readers)) {
+			skb_orphan(skb);
X 			__skb_queue_tail(&nsk->back_log, skb);
X 			return 0;
X 		}
@@ -1835,10 +1846,16 @@
X 	tp->mdev = TCP_TIMEOUT_INIT;
X 	tp->mss_clamp = ~0;
X       
+	/* So many TCP implementations out there (incorrectly) count the
+	 * initial SYN frame in their delayed-ACK and congestion control
+	 * algorithms that we must have the following bandaid to talk
+	 * efficiently to them.  -DaveM
+	 */
+	tp->snd_cwnd = 2;
+
X 	/* See draft-stevens-tcpca-spec-01 for discussion of the
X 	 * initialization of these values.
X 	 */
-	tp->snd_cwnd = 1;
X 	tp->snd_cwnd_cnt = 0;
X 	tp->snd_ssthresh = 0x7fffffff;	/* Infinity */
X 
diff -u --recursive --new-file v2.2.6/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
--- v2.2.6/linux/net/ipv4/tcp_output.c	Tue Mar 23 14:35:48 1999
+++ linux/net/ipv4/tcp_output.c	Wed Apr 28 09:51:57 1999
@@ -5,7 +5,7 @@
X  *
X  *		Implementation of the Transmission Control Protocol(TCP).
X  *
- * Version:	$Id: tcp_output.c,v 1.106 1999/03/12 03:43:51 davem Exp $
+ * Version:	$Id: tcp_output.c,v 1.107 1999/04/28 16:08:12 davem Exp $
X  *
X  * Authors:	Ross Biro, <bi...@leland.Stanford.Edu>
X  *		Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -167,7 +167,7 @@
X 
X 	if (!force_queue && tp->send_head == NULL && tcp_snd_test(sk, skb)) {
X 		/* Send it out now. */
-		TCP_SKB_CB(skb)->when = jiffies;
+		TCP_SKB_CB(skb)->when = tcp_time_stamp;
X 		tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
X 		tp->packets_out++;
X 		tcp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL));
@@ -344,7 +344,7 @@
X 
X 			/* Advance the send_head.  This one is going out. */
X 			update_send_head(sk);
-			TCP_SKB_CB(skb)->when = jiffies;
+			TCP_SKB_CB(skb)->when = tcp_time_stamp;
X 			tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
X 			tp->packets_out++;
X 			tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
@@ -600,7 +600,7 @@
X 	/* Make a copy, if the first transmission SKB clone we made
X 	 * is still in somebody's hands, else make a clone.
X 	 */
-	TCP_SKB_CB(skb)->when = jiffies;
+	TCP_SKB_CB(skb)->when = tcp_time_stamp;
X 	if(skb_cloned(skb))
X 		skb = skb_copy(skb, GFP_ATOMIC);
X 	else
@@ -723,7 +723,7 @@
X 		   tp->packets_out &&
X 		   !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG)) {
X 			update_send_head(sk);
-			TCP_SKB_CB(skb)->when = jiffies;
+			TCP_SKB_CB(skb)->when = tcp_time_stamp;
X 			tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
X 			tp->packets_out++;
X 			tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
@@ -778,7 +778,7 @@
X 	/* Send it off. */
X 	TCP_SKB_CB(skb)->seq = tp->write_seq;
X 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
-	TCP_SKB_CB(skb)->when = jiffies;
+	TCP_SKB_CB(skb)->when = tcp_time_stamp;
X 	tcp_transmit_skb(sk, skb);
X }
X 
@@ -808,7 +808,7 @@
X 	TCP_SKB_CB(skb)->seq = tp->snd_una;
X 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
X 	__skb_queue_tail(&sk->write_queue, skb);
-	TCP_SKB_CB(skb)->when = jiffies;
+	TCP_SKB_CB(skb)->when = tcp_time_stamp;
X 	tp->packets_out++;
X 	tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
X 	return 0;
@@ -875,7 +875,7 @@
X 	/* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */
X 	th->window = htons(req->rcv_wnd);
X 
-	TCP_SKB_CB(skb)->when = jiffies;
+	TCP_SKB_CB(skb)->when = tcp_time_stamp;
X 	tcp_syn_build_options((__u32 *)(th + 1), req->mss, req->tstamp_ok,
X 			      req->sack_ok, req->wscale_ok, req->rcv_wscale,
X 			      TCP_SKB_CB(skb)->when,
@@ -963,7 +963,7 @@
X 
X 	/* Send it off. */
X 	__skb_queue_tail(&sk->write_queue, buff);
-	TCP_SKB_CB(buff)->when = jiffies;
+	TCP_SKB_CB(buff)->when = tcp_time_stamp;
X 	tp->packets_out++;
X 	tcp_transmit_skb(sk, skb_clone(buff, GFP_KERNEL));
X 	tcp_statistics.TcpActiveOpens++;
@@ -1037,7 +1037,7 @@
X 
X 		/* Send it off, this clears delayed acks for us. */
X 		TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tp->snd_nxt;
-		TCP_SKB_CB(buff)->when = jiffies;
+		TCP_SKB_CB(buff)->when = tcp_time_stamp;
X 		tcp_transmit_skb(sk, buff);
X 	}
X }
@@ -1075,7 +1075,7 @@
X 					return; /* Let a retransmit get it. */
X 			}
X 			update_send_head(sk);
-			TCP_SKB_CB(skb)->when = jiffies;
+			TCP_SKB_CB(skb)->when = tcp_time_stamp;
X 			tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
X 			tp->packets_out++;
X 			tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
@@ -1101,7 +1101,7 @@
X 			 */
X 			TCP_SKB_CB(skb)->seq = tp->snd_nxt - 1;
X 			TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
-			TCP_SKB_CB(skb)->when = jiffies;
+			TCP_SKB_CB(skb)->when = tcp_time_stamp;
X 			tcp_transmit_skb(sk, skb);
X 		}
X 	}
diff -u --recursive --new-file v2.2.6/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
--- v2.2.6/linux/net/ipv4/tcp_timer.c	Tue Mar 23 14:35:48 1999
+++ linux/net/ipv4/tcp_timer.c	Wed Apr 28 09:51:57 1999
@@ -5,7 +5,7 @@
X  *
X  *		Implementation of the Transmission Control Protocol(TCP).
X  *
- * Version:	$Id: tcp_timer.c,v 1.59 1999/03/23 21:21:09 davem Exp $
+ * Version:	$Id: tcp_timer.c,v 1.60 1999/04/28 16:08:21 davem Exp $
X  *
X  * Authors:	Ross Biro, <bi...@leland.Stanford.Edu>
X  *		Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -224,7 +224,7 @@
X 
X 	if ((1<<sk->state) & (TCPF_ESTABLISHED|TCPF_CLOSE_WAIT|TCPF_FIN_WAIT2)) {
X 		struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-		__u32 elapsed = jiffies - tp->rcv_tstamp;
+		__u32 elapsed = tcp_time_stamp - tp->rcv_tstamp;
X 
X 		if (elapsed >= sysctl_tcp_keepalive_time) {
X 			if (tp->probes_out > sysctl_tcp_keepalive_probes) {
@@ -561,7 +561,7 @@
X 						if (!tp->syn_wait_queue)
X 							break;
X 					} else {
-						__u32 timeo;
+						unsigned long timeo;
X 						struct open_request *op; 
X 
X 						(*conn->class->rtx_syn_ack)(sk, conn);
diff -u --recursive --new-file v2.2.6/linux/net/ipv6/Makefile linux/net/ipv6/Makefile
--- v2.2.6/linux/net/ipv6/Makefile	Thu Mar 27 14:40:16 1997
+++ linux/net/ipv6/Makefile	Thu Apr 22 19:45:20 1999
@@ -11,7 +11,8 @@
X IPV6_OBJS :=	af_inet6.o ip6_output.o ip6_input.o addrconf.o sit.o \
X 		route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \
X 		protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
-		exthdrs.o sysctl_net_ipv6.o datagram.o proc.o
+		exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
+		ip6_flowlabel.o
X 
X MOD_LIST_NAME := IPV6_MODULES
X M_OBJS   := $(O_TARGET)
diff -u --recursive --new-file v2.2.6/linux/net/ipv6/af_inet6.c linux/net/ipv6/af_inet6.c
--- v2.2.6/linux/net/ipv6/af_inet6.c	Wed Jan 20 23:14:07 1999
+++ linux/net/ipv6/af_inet6.c	Thu Apr 22 19:45:20 1999
@@ -7,7 +7,7 @@
X  *
X  *	Adapted from linux/net/ipv4/af_inet.c
X  *
- *	$Id: af_inet6.c,v 1.42 1999/01/19 08:20:06 davem Exp $
+ *	$Id: af_inet6.c,v 1.43 1999/04/22 10:07:39 davem Exp $
X  *
X  *	This program is free software; you can redistribute it and/or
X  *      modify it under the terms of the GNU General Public License
@@ -190,7 +190,7 @@
X 	struct sockaddr_in6 *addr=(struct sockaddr_in6 *)uaddr;
X 	struct sock *sk = sock->sk;
X 	__u32 v4addr = 0;
-	unsigned short snum = 0;
+	unsigned short snum;
X 	int addr_type = 0;
X 
X 	/* If the socket has its own bind function then use it. */
@@ -203,12 +203,6 @@
X 	    (sk->num != 0))
X 		return -EINVAL;
X 		
- snum = ntohs(addr->sin6_port);
-	if (snum == 0) 
-		snum = sk->prot->good_socknum();
-	if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
-		return(-EACCES);
-	
X 	addr_type = ipv6_addr_type(&addr->sin6_addr);
X 	if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM)
X 		return(-EINVAL);
@@ -241,6 +235,12 @@
X 		memcpy(&sk->net_pinfo.af_inet6.saddr, &addr->sin6_addr, 
X 		       sizeof(struct in6_addr));
X 
+	snum = ntohs(addr->sin6_port);
+	if (snum == 0) 
+		snum = sk->prot->good_socknum();
+	if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
+		return(-EACCES);
+
X 	/* Make sure we are allowed to bind here. */
X 	if(sk->prot->verify_bind(sk, snum))
X 		return -EADDRINUSE;
@@ -292,6 +292,9 @@
X 	if ((skb = xchg(&sk->net_pinfo.af_inet6.pktoptions, NULL)) != NULL)
X 		kfree_skb(skb);
X 
+	/* Free flowlabels */
+	fl6_free_socklist(sk);
+
X 	/* Free tx options */
X 
X 	if ((opt = xchg(&sk->net_pinfo.af_inet6.opt, NULL)) != NULL)
@@ -311,6 +314,7 @@
X 	struct sock *sk;
X   
X 	sin->sin6_family = AF_INET6;
+	sin->sin6_flowinfo = 0;
X 	sk = sock->sk;
X 	if (peer) {
X 		if (!tcp_connected(sk->state))
@@ -318,6 +322,8 @@
X 		sin->sin6_port = sk->dport;
X 		memcpy(&sin->sin6_addr, &sk->net_pinfo.af_inet6.daddr,
X 		       sizeof(struct in6_addr));
+		if (sk->net_pinfo.af_inet6.sndflow)
+			sin->sin6_flowinfo = sk->net_pinfo.af_inet6.flow_label;
X 	} else {
X 		if (ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr) == IPV6_ADDR_ANY)
X 			memcpy(&sin->sin6_addr, 
@@ -537,6 +543,7 @@
X 	ipv6_netdev_notif_init();
X 	ipv6_packet_init();
X 	ip6_route_init();
+	ip6_flowlabel_init();
X 	addrconf_init();
X 	sit_init();
X 
@@ -592,6 +599,7 @@
X 	/* Cleanup code parts. */
X 	sit_cleanup();
X 	ipv6_netdev_notif_cleanup();
+	ip6_flowlabel_cleanup();
X 	addrconf_cleanup();
X 	ip6_route_cleanup();
X 	ipv6_packet_cleanup();
diff -u --recursive --new-file v2.2.6/linux/net/ipv6/datagram.c linux/net/ipv6/datagram.c
--- v2.2.6/linux/net/ipv6/datagram.c	Mon Oct  5 13:13:49 1998
+++ linux/net/ipv6/datagram.c	Thu Apr 22 19:45:20 1999
@@ -5,7 +5,7 @@
X  *	Authors:
X  *	Pedro Roque		<ro...@di.fc.ul.pt>	
X  *
- *	$Id: datagram.c,v 1.16 1998/10/03 09:38:25 davem Exp $
+ *	$Id: datagram.c,v 1.17 1999/04/22 10:07:40 davem Exp $
X  *
X  *	This program is free software; you can redistribute it and/or
X  *      modify it under the terms of the GNU General Public License
@@ -132,10 +132,13 @@
X 	sin = (struct sockaddr_in6 *)msg->msg_name;
X 	if (sin) {
X 		sin->sin6_family = AF_INET6;
+		sin->sin6_flowinfo = 0;
X 		sin->sin6_port = serr->port; 
-		if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6)
+		if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
X 			memcpy(&sin->sin6_addr, skb->nh.raw + serr->addr_offset, 16);
-		else
+			if (sk->net_pinfo.af_inet6.sndflow)
+				sin->sin6_flowinfo = *(u32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK;
+		} else
X 			ipv6_addr_set(&sin->sin6_addr, 0, 0,
X 				      __constant_htonl(0xffff),
X 				      *(u32*)(skb->nh.raw + serr->addr_offset));
@@ -146,6 +149,7 @@
X 	sin->sin6_family = AF_UNSPEC;
X 	if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) {
X 		sin->sin6_family = AF_INET6;
+		sin->sin6_flowinfo = 0;
X 		if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) {
X 			memcpy(&sin->sin6_addr, &skb->nh.ipv6h->saddr, 16);
X 			if (sk->net_pinfo.af_inet6.rxopt.all)
@@ -199,6 +203,10 @@
X 		put_cmsg(msg, SOL_IPV6, IPV6_HOPLIMIT, sizeof(hlim), &hlim);
X 	}
X 
+	if (np->rxopt.bits.rxflow && (*(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) {
+		u32 flowinfo = *(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK;
+		put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
+	}
X 	if (np->rxopt.bits.hopopts && opt->hop) {
X 		u8 *ptr = skb->nh.raw + opt->hop;
X 		put_cmsg(msg, SOL_IPV6, IPV6_HOPOPTS, (ptr[1]+1)<<3, ptr);
@@ -222,8 +230,8 @@
X 	return 0;
X }
X 
-int datagram_send_ctl(struct msghdr *msg, int *oif,
-		      struct in6_addr **src_addr, struct ipv6_txoptions *opt,
+int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
+		      struct ipv6_txoptions *opt,
X 		      int *hlimit)
X {
X 	struct in6_pktinfo *src_info;
@@ -235,17 +243,15 @@
X 
X 	for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
X 
-		if ((unsigned long)(((char*)cmsg - (char*)msg->msg_control)
+		if (cmsg->cmsg_len < sizeof(struct cmsghdr) ||
+		    (unsigned long)(((char*)cmsg - (char*)msg->msg_control)
X 				    + cmsg->cmsg_len) > msg->msg_controllen) {
X 			err = -EINVAL;
X 			goto exit_f;
X 		}
X 
-		if (cmsg->cmsg_level != SOL_IPV6) {
-			if (net_ratelimit())
-				printk(KERN_DEBUG "invalid cmsg_level %d\n", cmsg->cmsg_level);
+		if (cmsg->cmsg_level != SOL_IPV6)
X 			continue;
-		}
X 
X 		switch (cmsg->cmsg_type) {
X  		case IPV6_PKTINFO:
@@ -257,9 +263,9 @@
X 			src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg);
X 			
X 			if (src_info->ipi6_ifindex) {
-				if (*oif && src_info->ipi6_ifindex != *oif)
+				if (fl->oif && src_info->ipi6_ifindex != fl->oif)
X 					return -EINVAL;
-				*oif = src_info->ipi6_ifindex;
+				fl->oif = src_info->ipi6_ifindex;
X 			}
X 
X 			if (!ipv6_addr_any(&src_info->ipi6_addr)) {
@@ -272,9 +278,24 @@
X 					goto exit_f;
X 				}
X 
-				*src_addr = &src_info->ipi6_addr;
+				fl->fl6_src = &src_info->ipi6_addr;
+			}
+
+			break;
+
+		case IPV6_FLOWINFO:
+                        if (cmsg->cmsg_len < CMSG_LEN(4)) {
+				err = -EINVAL;
+				goto exit_f;
X 			}
X 
+			if (fl->fl6_flowlabel&IPV6_FLOWINFO_MASK) {
+				if ((fl->fl6_flowlabel^*(u32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) {
+					err = -EINVAL;
+					goto exit_f;
+				}
+			}
+			fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(u32 *)CMSG_DATA(cmsg);
X 			break;
X 
X 		case IPV6_HOPOPTS:
diff -u --recursive --new-file v2.2.6/linux/net/ipv6/ip6_fib.c linux/net/ipv6/ip6_fib.c
--- v2.2.6/linux/net/ipv6/ip6_fib.c	Tue Mar 23 14:35:48 1999
+++ linux/net/ipv6/ip6_fib.c	Thu Apr 22 19:45:20 1999
@@ -5,7 +5,7 @@
X  *	Authors:
X  *	Pedro Roque		<ro...@di.fc.ul.pt>	
X  *
- *	$Id: ip6_fib.c,v 1.16 1999/03/21 05:22:52 davem Exp $
+ *	$Id: ip6_fib.c,v 1.17 1999/04/22 10:07:41 davem Exp $
X  *
X  *	This program is free software; you can redistribute it and/or
X  *      modify it under the terms of the GNU General Public License
@@ -890,9 +890,6 @@
X 
X 	RT6_TRACE("fib6_del_route\n");
X 
-	if (!(rt->rt6i_flags&RTF_CACHE))
-		fib6_prune_clones(fn, rt);
-
X 	/* Unlink it */
X 	*rtp = rt->u.next;
X 	rt->rt6i_node = NULL;
@@ -938,6 +935,9 @@
X 		return -ENOENT;
X 
X 	BUG_TRAP(fn->fn_flags&RTN_RTINFO);
+
+	if (!(rt->rt6i_flags&RTF_CACHE))
+		fib6_prune_clones(fn, rt);
X 
X 	/*
X 	 *	Walk the leaf entries looking for ourself
diff -u --recursive --new-file v2.2.6/linux/net/ipv6/ip6_flowlabel.c linux/net/ipv6/ip6_flowlabel.c
--- v2.2.6/linux/net/ipv6/ip6_flowlabel.c	Wed Dec 31 16:00:00 1969
+++ linux/net/ipv6/ip6_flowlabel.c	Fri Apr 23 18:39:47 1999
@@ -0,0 +1,620 @@
+/*
+ *	ip6_flowlabel.c		IPv6 flowlabel manager.
+ *
+ *	This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ *
+ *	Authors:	Alexey Kuznetsov, <kuz...@ms2.inr.ac.ru>
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/in6.h>
+#include <linux/route.h>
+#include <linux/proc_fs.h>
+
+#include <net/sock.h>
+
+#include <net/ipv6.h>
+#include <net/ndisc.h>
+#include <net/protocol.h>
+#include <net/ip6_route.h>
+#include <net/addrconf.h>
+#include <net/rawv6.h>
+#include <net/icmp.h>
+#include <net/transp_v6.h>
+
+#include <asm/uaccess.h>
+
+#define FL_MIN_LINGER	6	/* Minimal linger. It is set to 6sec specified
+				   in old IPv6 RFC. Well, it was reasonable value.
+				 */
+#define FL_MAX_LINGER	60	/* Maximal linger timeout */
+
+/* FL hash table */
+
+#define FL_MAX_PER_SOCK	32
+#define FL_MAX_SIZE	4096
+#define FL_HASH_MASK	255
+#define FL_HASH(l)	(ntohl(l)&FL_HASH_MASK)
+
+static atomic_t fl_size = ATOMIC_INIT(0);
+static struct ip6_flowlabel *fl_ht[FL_HASH_MASK+1];
+
+static struct timer_list ip6_fl_gc_timer;
+
+/* FL hash table lock: it protects only of GC */
+
+static atomic_t ip6_fl_lock = ATOMIC_INIT(0);
+
+static __inline__ void fl_lock(void)
+{
+	atomic_inc(&ip6_fl_lock);
+	synchronize_bh();
+}
+
+static __inline__ void fl_unlock(void)
+{
+	atomic_dec(&ip6_fl_lock);
+}
+
+static struct ip6_flowlabel * fl_lookup(u32 label)
+{
+	struct ip6_flowlabel *fl;
+
+	fl_lock();
+	for (fl=fl_ht[FL_HASH(label)]; fl; fl = fl->next) {
+		if (fl->label == label) {
+			atomic_inc(&fl->users);
+			break;
+		}
+	}
+	fl_unlock();
+	return fl;
+}
+
+static void fl_free(struct ip6_flowlabel *fl)
+{
+	if (fl->opt)
+		kfree(fl->opt);
+	kfree(fl);
+}
+
+static void fl_release(struct ip6_flowlabel *fl)
+{
+	fl_lock();
+	fl->lastuse = jiffies;
+	if (atomic_dec_and_test(&fl->users)) {
+		unsigned long ttd = fl->lastuse + fl->linger;
+		if ((long)(ttd - fl->expires) > 0)
+			fl->expires = ttd;
+		ttd = fl->expires;
+		if (fl->opt && fl->share == IPV6_FL_S_EXCL) {
+			struct ipv6_txoptions *opt = fl->opt;
+			fl->opt = NULL;
+			kfree(opt);
+		}
+		if (!del_timer(&ip6_fl_gc_timer) ||
+		    (long)(ip6_fl_gc_timer.expires - ttd) > 0)
+			ip6_fl_gc_timer.expires = ttd;
+		add_timer(&ip6_fl_gc_timer);
+	}
+	fl_unlock();
+}
+
+static void ip6_fl_gc(unsigned long dummy)
+{
+	int i;
+	unsigned long now = jiffies;
+	unsigned long sched = 0;
+
+	if (atomic_read(&ip6_fl_lock)) {
+		ip6_fl_gc_timer.expires = now + HZ/10;
+		add_timer(&ip6_fl_gc_timer);
+		return;
+	}
+
+	for (i=0; i<=FL_HASH_MASK; i++) {
+		struct ip6_flowlabel *fl, **flp;
+		flp = &fl_ht[i];
+		while ((fl=*flp) != NULL) {
+			if (atomic_read(&fl->users) == 0) {
+				unsigned long ttd = fl->lastuse + fl->linger;
+				if ((long)(ttd - fl->expires) > 0)
+					fl->expires = ttd;
+				ttd = fl->expires;
+				if ((long)(now - ttd) >= 0) {
+					*flp = fl->next;
+					fl_free(fl);
+					atomic_dec(&fl_size);
+					continue;
+				}
+				if (!sched || (long)(ttd - sched) < 0)
+					sched = ttd;
+			}
+			flp = &fl->next;
+		}
+	}
+	if (!sched && atomic_read(&fl_size))
+		sched = now + FL_MAX_LINGER;
+	if (sched) {
+		ip6_fl_gc_timer.expires = sched;
+		add_timer(&ip6_fl_gc_timer);
+	}
+}
+
+static int fl_intern(struct ip6_flowlabel *fl, __u32 label)
+{
+	fl->label = label & IPV6_FLOWLABEL_MASK;
+
+	fl_lock();
+	if (label == 0) {
+		for (;;) {
+			fl->label = htonl(net_random())&IPV6_FLOWLABEL_MASK;
+			if (fl->label) {
+				struct ip6_flowlabel *lfl;
+				lfl = fl_lookup(fl->label);
+				if (lfl == NULL)
+					break;
+				fl_release(lfl);
+			}
+		}
+	}
+
+	fl->lastuse = jiffies;
+	fl->next = fl_ht[FL_HASH(fl->label)];
+	fl_ht[FL_HASH(fl->label)] = fl;
+	atomic_inc(&fl_size);
+	fl_unlock();
+	return 0;
+}
+
+
+
+/* Socket flowlabel lists */
+
+struct ip6_flowlabel * fl6_sock_lookup(struct sock *sk, u32 label)
+{
+	struct ipv6_fl_socklist *sfl;
+	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
+
+	label &= IPV6_FLOWLABEL_MASK;
+
+	for (sfl=np->ipv6_fl_list; sfl; sfl = sfl->next) {
+		struct ip6_flowlabel *fl = sfl->fl;
+		if (fl->label == label) {
+			fl->lastuse = jiffies;
+			atomic_inc(&fl->users);
+			return fl;
+		}
+	}
+	return NULL;
+}
+
+void fl6_free_socklist(struct sock *sk)
+{
+	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
+	struct ipv6_fl_socklist *sfl;
+
+	while ((sfl = np->ipv6_fl_list) != NULL) {
+		np->ipv6_fl_list = sfl->next;
+		fl_release(sfl->fl);
+		kfree(sfl);
+	}
+}
+
+/* Service routines */
+
+
+/*
+   It is the only difficult place. flowlabel enforces equal headers
+   before and including routing header, however user may supply options
+   following rthdr.
+ */
+
+struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space,
+					 struct ip6_flowlabel * fl,
+					 struct ipv6_txoptions * fopt)
+{
+	struct ipv6_txoptions * fl_opt = fl->opt;
+
+	if (fopt == NULL || fopt->opt_flen == 0)
+		return fl_opt;
+
+	if (fl_opt != NULL) {
+		opt_space->hopopt = fl_opt->hopopt;
+		opt_space->dst0opt = fl_opt->dst0opt;
+		opt_space->srcrt = fl_opt->srcrt;
+		opt_space->opt_nflen = fl_opt->opt_nflen;
+	} else {
+		if (fopt->opt_nflen == 0)
+			return fopt;
+		opt_space->hopopt = NULL;
+		opt_space->dst0opt = NULL;
+		opt_space->srcrt = NULL;
+		opt_space->opt_nflen = 0;
+	}
+	opt_space->dst1opt = fopt->dst1opt;
+	opt_space->auth = fopt->auth;
+	opt_space->opt_flen = fopt->opt_flen;
+	return opt_space;
+}
+
+static __u32 check_linger(__u16 ttl)
+{
+	if (ttl < FL_MIN_LINGER)
+		return FL_MIN_LINGER*HZ;
+	if (ttl > FL_MAX_LINGER && !capable(CAP_NET_ADMIN))
+		return 0;
+	return ttl*HZ;
+}
+
+static int fl6_renew(struct ip6_flowlabel *fl, unsigned linger, unsigned expires)
+{
+	linger = check_linger(linger);
+	if (!linger)
+		return -EPERM;
+	expires = check_linger(expires);
+	if (!expires)
+		return -EPERM;
+	fl->lastuse = jiffies;
+	if (fl->linger < linger)
+		fl->linger = linger;
+	if (expires < fl->linger)
+		expires = fl->linger;
+	if ((long)(fl->expires - (fl->lastuse+expires)) < 0)
+		fl->expires = fl->lastuse + expires;
+	return 0;
+}
+
+static struct ip6_flowlabel *
+fl_create(struct in6_flowlabel_req *freq, char *optval, int optlen, int *err_p)
+{
+	struct ip6_flowlabel *fl;
+	int olen;
+	int addr_type;
+	int err;
+
+	err = -ENOMEM;
+	fl = kmalloc(sizeof(*fl), GFP_KERNEL);
+	if (fl == NULL)
+		goto done;
+	memset(fl, 0, sizeof(*fl));
+
+	olen = optlen - CMSG_ALIGN(sizeof(*freq));
+	if (olen > 0) {
+		struct msghdr msg;
+		struct flowi flowi;
+		int junk;
+
+		err = -ENOMEM;
+		fl->opt = kmalloc(sizeof(*fl->opt) + olen, GFP_KERNEL);
+		if (fl->opt == NULL)
+			goto done;
+
+		memset(fl->opt, 0, sizeof(*fl->opt));
+		fl->opt->tot_len = sizeof(*fl->opt) + olen;
+		err = -EFAULT;
+		if (copy_from_user(fl->opt+1, optval+CMSG_ALIGN(sizeof(*freq)), olen))
+			goto done;
+
+		msg.msg_controllen = olen;
+		msg.msg_control = (void*)(fl->opt+1);
+		flowi.oif = 0;
+
+		err = datagram_send_ctl(&msg, &flowi, fl->opt, &junk);
+		if (err)
+			goto done;
+		err = -EINVAL;
+		if (fl->opt->opt_flen)
+			goto done;
+		if (fl->opt->opt_nflen == 0) {
+			kfree(fl->opt);
+			fl->opt = NULL;
+		}
+	}
+
+	fl->expires = jiffies;
+	err = fl6_renew(fl, freq->flr_linger, freq->flr_expires);
+	if (err)
+		goto done;
+	fl->share = freq->flr_share;
+	addr_type = ipv6_addr_type(&freq->flr_dst);
+	if ((addr_type&IPV6_ADDR_MAPPED)
+	    || addr_type == IPV6_ADDR_ANY)
+		goto done;
+	ipv6_addr_copy(&fl->dst, &freq->flr_dst);
+	atomic_set(&fl->users, 1);
+	switch (fl->share) {
+	case IPV6_FL_S_EXCL:
+	case IPV6_FL_S_ANY:
+		break;
+	case IPV6_FL_S_PROCESS:
+		fl->owner = current->pid;
+		break;
+	case IPV6_FL_S_USER:
+		fl->owner = current->euid;
+		break;
+	default:
+		err = -EINVAL;
+		goto done;
+	}
+	return fl;
+
+done:
+	if (fl)
+		fl_free(fl);
+	*err_p = err;
+	return NULL;
+}
+
+static int mem_check(struct sock *sk)
+{
+	struct ipv6_fl_socklist *sfl;
+	int room = FL_MAX_SIZE - atomic_read(&fl_size);
+	int count = 0;
+
+	if (room > FL_MAX_SIZE - FL_MAX_PER_SOCK)
+		return 0;
+
+	for (sfl = sk->net_pinfo.af_inet6.ipv6_fl_list; sfl; sfl = sfl->next)
+		count++;
+
+	if (room <= 0 ||
+	    ((count >= FL_MAX_PER_SOCK ||
+	     (count > 0 && room < FL_MAX_SIZE/2) || room < FL_MAX_SIZE/4)
+	     && !capable(CAP_NET_ADMIN)))
+		return -ENOBUFS;
+
+	return 0;
+}
+
+static int ipv6_hdr_cmp(struct ipv6_opt_hdr *h1, struct ipv6_opt_hdr *h2)
+{
+	if (h1 == h2)
+		return 0;
+	if (h1 == NULL || h2 == NULL)
+		return 1;
+	if (h1->hdrlen != h2->hdrlen)
+		return 1;
+	return memcmp(h1+1, h2+1, ((h1->hdrlen+1)<<3) - sizeof(*h1));
+}
+
+static int ipv6_opt_cmp(struct ipv6_txoptions *o1, struct ipv6_txoptions *o2)
+{
+	if (o1 == o2)
+		return 0;
+	if (o1 == NULL || o2 == NULL)
+		return 1;
+	if (o1->opt_nflen != o2->opt_nflen)
+		return 1;
+	if (ipv6_hdr_cmp(o1->hopopt, o2->hopopt))
+		return 1;
+	if (ipv6_hdr_cmp(o1->dst0opt, o2->dst0opt))
+		return 1;
+	if (ipv6_hdr_cmp((struct ipv6_opt_hdr *)o1->srcrt, (struct ipv6_opt_hdr *)o2->srcrt))
+		return 1;
+	return 0;
+}
+
+int ipv6_flowlabel_opt(struct sock *sk, char *optval, int optlen)
+{
+	int err;
+	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
+	struct in6_flowlabel_req freq;
+	struct ipv6_fl_socklist *sfl1=NULL;
+	struct ipv6_fl_socklist *sfl, **sflp;
+	struct ip6_flowlabel *fl;
+
+	if (optlen < sizeof(freq))
+		return -EINVAL;
+
+	if (copy_from_user(&freq, optval, sizeof(freq)))
+		return -EFAULT;
+
+	switch (freq.flr_action) {
+	case IPV6_FL_A_PUT:
+		for (sflp = &np->ipv6_fl_list; (sfl=*sflp)!=NULL; sflp = &sfl->next) {
+			if (sfl->fl->label == freq.flr_label) {
+				if (freq.flr_label == (np->flow_label&IPV6_FLOWLABEL_MASK))
+					np->flow_label &= ~IPV6_FLOWLABEL_MASK;
+				*sflp = sfl->next;
+				synchronize_bh();
+				fl_release(sfl->fl);
+				kfree(sfl);
+				return 0;
+			}
+		}
+		return -ESRCH;
+
+	case IPV6_FL_A_RENEW:
+		for (sfl = np->ipv6_fl_list; sfl; sfl = sfl->next) {
+			if (sfl->fl->label == freq.flr_label)
+				return fl6_renew(sfl->fl, freq.flr_linger, freq.flr_expires);
+		}
+		if (freq.flr_share == IPV6_FL_S_NONE && capable(CAP_NET_ADMIN)) {
+			fl = fl_lookup(freq.flr_label);
+			if (fl) {
+				err = fl6_renew(fl, freq.flr_linger, freq.flr_expires);
+				fl_release(fl);
+				return err;
+			}
+		}
+		return -ESRCH;
+
+	case IPV6_FL_A_GET:
+		if (freq.flr_label & ~IPV6_FLOWLABEL_MASK)
+			return -EINVAL;
+
+		fl = fl_create(&freq, optval, optlen, &err);
+		if (fl == NULL)
+			return err;
+		sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL);
+
+		if (freq.flr_label) {
+			struct ip6_flowlabel *fl1 = NULL;
+
+			err = -EEXIST;
+			for (sfl = np->ipv6_fl_list; sfl; sfl = sfl->next) {
+				if (sfl->fl->label == freq.flr_label) {
+					if (freq.flr_flags&IPV6_FL_F_EXCL)
+						goto done;
+					fl1 = sfl->fl;
+					atomic_inc(&fl->users);
+					break;
+				}
+			}
+
+			if (fl1 == NULL)
+				fl1 = fl_lookup(freq.flr_label);
+			if (fl1) {
+				err = -EEXIST;
+				if (freq.flr_flags&IPV6_FL_F_EXCL)
+					goto release;
+				err = -EPERM;
+				if (fl1->share == IPV6_FL_S_EXCL ||
+				    fl1->share != fl->share ||
+				    fl1->owner != fl->owner)
+					goto release;
+
+				err = -EINVAL;
+				if (ipv6_addr_cmp(&fl1->dst, &fl->dst) ||
+				    ipv6_opt_cmp(fl1->opt, fl->opt))
+					goto release;
+
+				err = -ENOMEM;
+				if (sfl1 == NULL)
+					goto release;
+				if (fl->linger > fl1->linger)
+					fl1->linger = fl->linger;
+				if ((long)(fl->expires - fl1->expires) > 0)
+					fl1->expires = fl->expires;
+				sfl1->fl = fl1;
+				sfl1->next = np->ipv6_fl_list;
+				np->ipv6_fl_list = sfl1;
+				synchronize_bh();
+				fl_free(fl);
+				return 0;
+
+release:
+				fl_release(fl1);
+				goto done;
+			}
+		}
+		err = -ENOENT;
+		if (!(freq.flr_flags&IPV6_FL_F_CREATE))
+			goto done;
+
+		err = -ENOMEM;
+		if (sfl1 == NULL || (err = mem_check(sk)) != 0)
+			goto done;
+
+		err = fl_intern(fl, freq.flr_label);
+		if (err)
+			goto done;
+
+		/* Do not check for fault */
+		if (!freq.flr_label)
+			copy_to_user(optval + ((u8*)&freq.flr_label - (u8*)&freq), &fl->label, sizeof(fl->label));
+
+		sfl1->fl = fl;
+		sfl1->next = np->ipv6_fl_list;
+		np->ipv6_fl_list = sfl1;
+		return 0;
+
+	default:
+		return -EINVAL;
+	}
+
+done:
+	if (fl)
+		fl_free(fl);
+	if (sfl1)
+		kfree(sfl1);
+	return err;
+}
+
+#ifdef CONFIG_PROC_FS
+
+
+static int ip6_fl_read_proc(char *buffer, char **start, off_t offset,
+			    int length, int *eof, void *data)
+{
+	off_t pos=0;
+	off_t begin=0;
+	int len=0;
+	int i, k;
+	struct ip6_flowlabel *fl;
+
+	len+= sprintf(buffer,"Label S Owner  Users  Linger Expires  "
+		      "Dst                              Opt\n");
+
+	fl_lock();
+	for (i=0; i<=FL_HASH_MASK; i++) {
+		for (fl = fl_ht[i]; fl; fl = fl->next) {
+			len+=sprintf(buffer+len,"%05X %-1d %-6d %-6d %-6d %-8ld ",
+				     (unsigned)ntohl(fl->label),
+				     fl->share,
+				     (unsigned)fl->owner,
+				     atomic_read(&fl->users),
+				     fl->linger/HZ,
+				     (long)(fl->expires - jiffies)/HZ);
+
+			for (k=0; k<16; k++)
+				len+=sprintf(buffer+len, "%02x", fl->dst.s6_addr[k]);
+			buffer[len++]=' ';
+			len+=sprintf(buffer+len, "%-4d", fl->opt ? fl->opt->opt_nflen : 0);
+			buffer[len++]='\n';
+
+			pos=begin+len;
+			if(pos<offset) {
+				len=0;
+				begin=pos;
+			}
+			if(pos>offset+length)
+				goto done;
+		}
+	}
+	*eof = 1;
+
+done:
+	fl_unlock();
+	*start=buffer+(offset-begin);
+	len-=(offset-begin);
+	if(len>length)
+		len=length;
+	if(len<0)
+		len=0;
+	return len;
+}
+#endif
+
+
+void ip6_flowlabel_init()
+{
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry *ent;
+#endif
+
+	init_timer(&ip6_fl_gc_timer);
+	ip6_fl_gc_timer.function = ip6_fl_gc;
+#ifdef CONFIG_PROC_FS
+	ent = create_proc_entry("net/ip6_flowlabel", 0, 0);
+	ent->read_proc = ip6_fl_read_proc;
+#endif
+}
+
+void ip6_flowlabel_cleanup()
+{
+	del_timer(&ip6_fl_gc_timer);
+#ifdef CONFIG_PROC_FS
+	remove_proc_entry("net/ip6_flowlabel", 0);
+#endif
+}
diff -u --recursive --new-file v2.2.6/linux/net/ipv6/ip6_output.c linux/net/ipv6/ip6_output.c
--- v2.2.6/linux/net/ipv6/ip6_output.c	Tue Mar 23 14:35:48 1999
+++ linux/net/ipv6/ip6_output.c	Thu Apr 22 19:45:20 1999
@@ -5,7 +5,7 @@
X  *	Authors:
X  *	Pedro Roque		<ro...@di.fc.ul.pt>	
X  *
- *	$Id: ip6_output.c,v 1.16 1999/03/21 05:22:54 davem Exp $
+ *	$Id: ip6_output.c,v 1.17 1999/04/22 10:07:42 davem Exp $
X  *
X  *	Based on linux/net/ipv4/ip_output.c
X  *
@@ -140,16 +140,10 @@
X 	 *	Fill in the IPv6 header
X 	 */
X 
-	hdr->version = 6;
-	if (np) {
-		hdr->priority = np->priority;
-		memcpy(hdr->flow_lbl, (void *) &np->flow_lbl, 3);
+	*(u32*)hdr = __constant_htonl(0x60000000) | fl->fl6_flowlabel;
+	hlimit = -1;
+	if (np)
X 		hlimit = np->hop_limit;
-	} else {
-		hdr->priority = 0;
-		memset(hdr->flow_lbl, 0, 3);
-		hlimit = -1;
-	}
X 	if (hlimit < 0)
X 		hlimit = ((struct rt6_info*)dst)->rt6i_hoplimit;
X 
@@ -197,9 +191,7 @@
X 	hdr = (struct ipv6hdr *) skb_put(skb, sizeof(struct ipv6hdr));
X 	skb->nh.ipv6h = hdr;
X 
-	hdr->version  = 6;
-	hdr->priority = np->priority & 0x0f;
-	memset(hdr->flow_lbl, 0, 3);
+	*(u32*)hdr = htonl(0x60000000);
X 
X 	hdr->payload_len = htons(len);
X 	hdr->nexthdr = proto;
@@ -214,16 +206,13 @@
X static struct ipv6hdr * ip6_bld_1(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
X 				  int hlimit, unsigned pktlength)
X {
-	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
X 	struct ipv6hdr *hdr;
X 	
X 	skb->nh.raw = skb_put(skb, sizeof(struct ipv6hdr));
X 	hdr = skb->nh.ipv6h;
X 	
-	hdr->version = 6;
-	hdr->priority = np->priority;
-	memcpy(hdr->flow_lbl, &np->flow_lbl, 3);
-	
+	*(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000);
+
X 	hdr->payload_len = htons(pktlength - sizeof(struct ipv6hdr));
X 	hdr->hop_limit = hlimit;
X 	hdr->nexthdr = fl->proto;
@@ -436,8 +425,8 @@
X 
X 	if (opt && opt->srcrt) {
X 		struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-		final_dst = fl->nl_u.ip6_u.daddr;
-		fl->nl_u.ip6_u.daddr = rt0->addr;
+		final_dst = fl->fl6_dst;
+		fl->fl6_dst = rt0->addr;
X 	}
X 
X 	if (!fl->oif && ipv6_addr_is_multicast(fl->nl_u.ip6_u.daddr))
@@ -486,8 +475,8 @@
X 		return -ENETUNREACH;
X 	}
X 
-	if (fl->nl_u.ip6_u.saddr == NULL) {
-		err = ipv6_get_saddr(dst, fl->nl_u.ip6_u.daddr, &saddr);
+	if (fl->fl6_src == NULL) {
+		err = ipv6_get_saddr(dst, fl->fl6_dst, &saddr);
X 
X 		if (err) {
X #if IP6_DEBUG >= 2
@@ -496,12 +485,12 @@
X #endif
X 			goto out;
X 		}
-		fl->nl_u.ip6_u.saddr = &saddr;
+		fl->fl6_src = &saddr;
X 	}
X 	pktlength = length;
X 
X 	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(fl->nl_u.ip6_u.daddr))
+		if (ipv6_addr_is_multicast(fl->fl6_dst))
X 			hlimit = np->mcast_hops;
X 		else
X 			hlimit = np->hop_limit;
diff -u --recursive --new-file v2.2.6/linux/net/ipv6/ipv6_sockglue.c linux/net/ipv6/ipv6_sockglue.c
--- v2.2.6/linux/net/ipv6/ipv6_sockglue.c	Mon Mar 29 11:09:12 1999
+++ linux/net/ipv6/ipv6_sockglue.c	Thu Apr 22 19:45:20 1999
@@ -7,7 +7,7 @@
X  *
X  *	Based on linux/net/ipv4/ip_sockglue.c
X  *
- *	$Id: ipv6_sockglue.c,v 1.26 1999/03/25 10:04:53 davem Exp $
+ *	$Id: ipv6_sockglue.c,v 1.27 1999/04/22 10:07:43 davem Exp $
X  *
X  *	This program is free software; you can redistribute it and/or
X  *      modify it under the terms of the GNU General Public License
@@ -151,6 +151,9 @@
X 				goto addrform_done;
X 			}
X 
+			fl6_free_socklist(sk);
+			ipv6_sock_mc_close(sk);
+
X 			if (sk->protocol == IPPROTO_TCP) {
X 				struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
X 				
@@ -211,12 +214,19 @@
X 		retv = 0;
X 		break;
X 
+	case IPV6_FLOWINFO:
+		np->rxopt.bits.rxflow = valbool;
+		return 0;
+
X 	case IPV6_PKTOPTIONS:
X 	{
X 		struct ipv6_txoptions *opt = NULL;
X 		struct msghdr msg;
+		struct flowi fl;
X 		int junk;
-		struct in6_addr *saddr;
+
+		fl.fl6_flowlabel = 0;
+		fl.oif = sk->bound_dev_if;
X 
X 		if (optlen == 0)
X 			goto update;
@@ -235,7 +245,7 @@
X 		msg.msg_controllen = optlen;
X 		msg.msg_control = (void*)(opt+1);
X 
-		retv = datagram_send_ctl(&msg, &junk, &saddr, opt, &junk);
+		retv = datagram_send_ctl(&msg, &fl, opt, &junk);
X 		if (retv)
X 			goto done;
X update:
@@ -321,10 +331,15 @@
X 		np->frag_size = val;
X 		return 0;
X 	case IPV6_RECVERR:
-		np->recverr = !!val;
+		np->recverr = valbool;
X 		if (!val)
X 			skb_queue_purge(&sk->error_queue);
X 		return 0;
+	case IPV6_FLOWINFO_SEND:
+		np->sndflow = valbool;
+		return 0;
+	case IPV6_FLOWLABEL_MGR:
+		return ipv6_flowlabel_opt(sk, optval, optlen);
X 	};
X 
X out:
diff -u --recursive --new-file v2.2.6/linux/net/ipv6/ndisc.c linux/net/ipv6/ndisc.c
--- v2.2.6/linux/net/ipv6/ndisc.c	Tue Mar 23 14:35:48 1999
+++ linux/net/ipv6/ndisc.c	Thu Apr 22 19:45:20 1999
@@ -813,7 +813,7 @@
X 		}
X 	}
X 
-	rd_len = min(IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, ntohs(skb->nh.ipv6h->payload_len) + 8);
+	rd_len = min(IPV6_MIN_MTU-sizeof(struct ipv6hdr)-len, skb->len + 8);
X 	rd_len &= ~0x7;
X 	len += rd_len;
X 
@@ -873,7 +873,7 @@
X 	*(opt++) = (rd_len >> 3);
X 	opt += 6;
X 
-	memcpy(opt, &skb->nh.ipv6h, rd_len - 8);
+	memcpy(opt, skb->nh.ipv6h, rd_len - 8);
X 
X 	icmph->icmp6_cksum = csum_ipv6_magic(&ifp->addr, &skb->nh.ipv6h->saddr,
X 					     len, IPPROTO_ICMPV6,
diff -u --recursive --new-file v2.2.6/linux/net/ipv6/raw.c linux/net/ipv6/raw.c
--- v2.2.6/linux/net/ipv6/raw.c	Thu Nov 19 09:56:29 1998
+++ linux/net/ipv6/raw.c	Thu Apr 22 19:45:20 1999
@@ -7,7 +7,7 @@
X  *
X  *	Adapted from linux/net/ipv4/raw.c
X  *
- *	$Id: raw.c,v 1.23 1998/11/08 11:17:09 davem Exp $
+ *	$Id: raw.c,v 1.24 1999/04/22 10:07:45 davem Exp $
X  *
X  *	This program is free software; you can redistribute it and/or
X  *      modify it under the terms of the GNU General Public License
@@ -283,6 +283,7 @@
X 		sin6->sin6_family = AF_INET6;
X 		memcpy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr, 
X 		       sizeof(struct in6_addr));
+		sin6->sin6_flowinfo = 0;
X 	}
X 
X 	if (sk->net_pinfo.af_inet6.rxopt.all)
@@ -363,7 +364,7 @@
X 	struct sockaddr_in6 * sin6 = (struct sockaddr_in6 *) msg->msg_name;
X 	struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
X struct ipv6_txoptions *opt = NULL;
-	struct in6_addr *saddr = NULL;
+	struct ip6_flowlabel *flowlabel = NULL;
X 	struct flowi fl;
X 	int addr_len = msg->msg_namelen;
X 	struct in6_addr *daddr;
@@ -388,6 +389,8 @@
X 	 *	Get and verify the address. 
X 	 */
X 
+	fl.fl6_flowlabel = 0;
+
X 	if (sin6) {
X 		if (addr_len < sizeof(struct sockaddr_in6)) 
X 			return(-EINVAL);
@@ -405,12 +408,28 @@
X 			return(-EINVAL);
X 
X 		daddr = &sin6->sin6_addr;
+		if (np->sndflow) {
+			fl.fl6_flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+			if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
+				flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+				if (flowlabel == NULL)
+					return -EINVAL;
+				daddr = &flowlabel->dst;
+			}
+		}
+
+
+		/* Otherwise it will be difficult to maintain sk->dst_cache. */
+		if (sk->state == TCP_ESTABLISHED &&
+		    !ipv6_addr_cmp(daddr, &sk->net_pinfo.af_inet6.daddr))
+			daddr = &sk->net_pinfo.af_inet6.daddr;
X 	} else {
X 		if (sk->state != TCP_ESTABLISHED) 
X 			return(-EINVAL);
X 		
X 		proto = sk->num;
X 		daddr = &(sk->net_pinfo.af_inet6.daddr);
+		fl.fl6_flowlabel = np->flow_label;
X 	}
X 
X 	if (ipv6_addr_any(daddr)) {
@@ -422,23 +441,34 @@
X 	}
X 
X 	fl.oif = sk->bound_dev_if;
+	fl.fl6_src = NULL;
X 
X 	raw_opt = &sk->tp_pinfo.tp_raw;
X 
X 	fl.proto = proto;
-	fl.nl_u.ip6_u.daddr = daddr;
-	fl.nl_u.ip6_u.saddr = saddr;
+	fl.fl6_dst = daddr;
X 	fl.uli_u.icmpt.type = 0;
X 	fl.uli_u.icmpt.code = 0;
X 	
@@ -462,6 +492,8 @@
X 		err = ip6_build_xmit(sk, rawv6_getfrag, msg->msg_iov, &fl, len,
X 				     opt, hlimit, msg->msg_flags);
X 	}
+
+	fl6_sock_release(flowlabel);
X 
X 	return err<0?err:len;
X }
diff -u --recursive --new-file v2.2.6/linux/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
--- v2.2.6/linux/net/ipv6/tcp_ipv6.c	Fri Apr 16 14:47:31 1999
+++ linux/net/ipv6/tcp_ipv6.c	Fri Apr 23 18:39:47 1999
@@ -5,7 +5,7 @@
X  *	Authors:
X  *	Pedro Roque		<ro...@di.fc.ul.pt>	
X  *
- *	$Id: tcp_ipv6.c,v 1.101 1999/03/28 10:18:30 davem Exp $
+ *	$Id: tcp_ipv6.c,v 1.104 1999/04/24 00:27:25 davem Exp $
X  *
X  *	Based on: 
X  *	linux/net/ipv4/tcp.c
@@ -401,6 +401,19 @@
X 	if (usin->sin6_family && usin->sin6_family != AF_INET6) 
X 		return(-EAFNOSUPPORT);
X 
+	fl.fl6_flowlabel = 0;
+	if (np->sndflow) {
+		fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+		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);
+		}
+	}
+
X 	/*
X   	 *	connect() to INADDR_ANY means loopback (BSD'ism).
X   	 */
@@ -422,6 +435,7 @@
X 		return (-EINVAL);
X 
X 	memcpy(&np->daddr, &usin->sin6_addr, sizeof(struct in6_addr));
+	np->flow_label = fl.fl6_flowlabel;
X 
X 	/*
X 	 *	TCP over IPv4
@@ -446,6 +460,7 @@
X 			tp->ext_header_len = exthdrlen;
X 			sk->tp_pinfo.af_tcp.af_specific = &ipv6_specific;
X 			sk->backlog_rcv = tcp_v6_do_rcv;
+			goto failure;
X 		} else {
X 			ipv6_addr_set(&np->saddr, 0, 0, __constant_htonl(0x0000FFFF),
X 				      sk->saddr);
@@ -460,8 +475,8 @@
X 		saddr = &np->rcv_saddr;
X 
X 	fl.proto = IPPROTO_TCP;
-	fl.nl_u.ip6_u.daddr = &np->daddr;
-	fl.nl_u.ip6_u.saddr = saddr;
+	fl.fl6_dst = &np->daddr;
+	fl.fl6_src = saddr;
X 	fl.oif = sk->bound_dev_if;
X 	fl.uli_u.ports.dport = usin->sin6_port;
X 	fl.uli_u.ports.sport = sk->sport;
@@ -475,7 +490,7 @@
X 
X 	if ((err = dst->error) != 0) {
X 		dst_release(dst);
-		return err;
+		goto failure;
X 	}
X 
X 	if (fl.oif == 0 && addr_type&IPV6_ADDR_LINKLOCAL) {
@@ -492,7 +507,7 @@
X 	if (saddr == NULL) {
X 		err = ipv6_get_saddr(dst, &np->daddr, &saddr_buf);
X 		if (err)
-			return err;
+			goto failure;
X 
X 		saddr = &saddr_buf;
X 	}
@@ -507,17 +522,19 @@
X 	/* Reset mss clamp */
X 	tp->mss_clamp = ~0;
X 
+	err = -ENOBUFS;
X 	buff = sock_wmalloc(sk, (MAX_HEADER + sk->prot->max_header),
X 			    0, GFP_KERNEL);
X 
X 	if (buff == NULL)
-		return -ENOBUFS;
+		goto failure;
X 
X 	sk->dport = usin->sin6_port;
X 
X 	if (!tcp_v6_unique_address(sk)) {
X 		kfree_skb(buff);
-		return -EADDRNOTAVAIL;
+		err = -EADDRNOTAVAIL;
+		goto failure;
X 	}
X 
X 	/*
@@ -531,6 +548,12 @@
X 	tcp_connect(sk, buff, dst->pmtu);
X 
X 	return 0;
+
+failure:
+	dst_release(xchg(&sk->dst_cache, NULL));
+	memcpy(&np->daddr, 0, sizeof(struct in6_addr));
+	sk->daddr = 0;
+	return err;
X }
X 
X static int tcp_v6_sendmsg(struct sock *sk, struct msghdr *msg, int len)
@@ -561,6 +584,8 @@
X 			goto out;
X 		if (ipv6_addr_cmp(&addr->sin6_addr, &np->daddr))
X 			goto out;
+		if (np->sndflow && np->flow_label != (addr->sin6_flowinfo&IPV6_FLOWINFO_MASK))
+			goto out;
X 	}
X 
X 	retval = tcp_do_sendmsg(sk, msg);
@@ -712,6 +737,7 @@
X 	fl.proto = IPPROTO_TCP;
X 	fl.nl_u.ip6_u.daddr = &req->af.v6_req.rmt_addr;
X 	fl.nl_u.ip6_u.saddr = &req->af.v6_req.loc_addr;
+	fl.fl6_flowlabel = 0;
X 	fl.oif = req->af.v6_req.iif;
X 	fl.uli_u.ports.dport = req->rmt_port;
X 	fl.uli_u.ports.sport = sk->sport;
@@ -775,6 +801,8 @@
X 
X 	if (sk->net_pinfo.af_inet6.rxopt.all) {
X 		if ((opt->hop && sk->net_pinfo.af_inet6.rxopt.bits.hopopts) ||
+		    ((IPV6_FLOWINFO_MASK&*(u32*)skb->nh.raw) &&
+		     sk->net_pinfo.af_inet6.rxopt.bits.rxflow) ||
X 		    (opt->srcrt && sk->net_pinfo.af_inet6.rxopt.bits.srcrt) ||
X 		    ((opt->dst1 || opt->dst0) && sk->net_pinfo.af_inet6.rxopt.bits.dstopts))
X 			return 1;
@@ -953,6 +981,7 @@
X 			fl.nl_u.ip6_u.daddr = rt0->addr;
X 		}
X 		fl.nl_u.ip6_u.saddr = &req->af.v6_req.loc_addr;
+		fl.fl6_flowlabel = 0;
X 		fl.oif = sk->bound_dev_if;
X 		fl.uli_u.ports.dport = req->rmt_port;
X 		fl.uli_u.ports.sport = sk->sport;
@@ -1078,6 +1107,7 @@
X 
X 	fl.nl_u.ip6_u.daddr = &skb->nh.ipv6h->saddr;
X 	fl.nl_u.ip6_u.saddr = &skb->nh.ipv6h->daddr;
+	fl.fl6_flowlabel = 0;
X 
X 	t1->check = csum_ipv6_magic(fl.nl_u.ip6_u.saddr,
X 				    fl.nl_u.ip6_u.daddr, 
@@ -1257,6 +1287,7 @@
X 		 * the new socket..
X 		 */
X 		if (atomic_read(&nsk->sock_readers)) {
+			skb_orphan(skb);
X 			__skb_queue_tail(&nsk->back_log, skb);
X 			return 0;
X 		}
@@ -1404,6 +1435,7 @@
X 		fl.proto = IPPROTO_TCP;
X 		fl.nl_u.ip6_u.daddr = &np->daddr;
X 		fl.nl_u.ip6_u.saddr = &np->saddr;
+		fl.fl6_flowlabel = np->flow_label;
X 		fl.oif = sk->bound_dev_if;
X 		fl.uli_u.ports.dport = sk->dport;
X 		fl.uli_u.ports.sport = sk->sport;
@@ -1448,8 +1480,9 @@
X 	struct dst_entry *dst = sk->dst_cache;
X 
X 	fl.proto = IPPROTO_TCP;
-	fl.nl_u.ip6_u.daddr = &np->daddr;
-	fl.nl_u.ip6_u.saddr = &np->saddr;
+	fl.fl6_dst = &np->daddr;
+	fl.fl6_src = &np->saddr;
+	fl.fl6_flowlabel = np->flow_label;
X 	fl.oif = sk->bound_dev_if;
X 	fl.uli_u.ports.sport = sk->sport;
X 	fl.uli_u.ports.dport = sk->dport;
@@ -1490,6 +1523,8 @@
X 	sin6->sin6_family = AF_INET6;
X 	memcpy(&sin6->sin6_addr, &np->daddr, sizeof(struct in6_addr));
X 	sin6->sin6_port	= sk->dport;
+	/* We do not store received flowlabel for TCP */
+	sin6->sin6_flowinfo = 0;
X }
X 
X static struct tcp_func ipv6_specific = {
@@ -1540,10 +1575,16 @@
X 	tp->mdev = TCP_TIMEOUT_INIT;
X 	tp->mss_clamp = ~0;
X 
+	/* So many TCP implementations out there (incorrectly) count the
+	 * initial SYN frame in their delayed-ACK and congestion control
+	 * algorithms that we must have the following bandaid to talk
+	 * efficiently to them.  -DaveM
+	 */
+	tp->snd_cwnd = 2;
+
X 	/* See draft-stevens-tcpca-spec-01 for discussion of the
X 	 * initialization of these values.
X 	 */
-	tp->snd_cwnd = 1;
X 	tp->snd_cwnd_cnt = 0;
X 	tp->snd_ssthresh = 0x7fffffff;
X 
diff -u --recursive --new-file v2.2.6/linux/net/ipv6/udp.c linux/net/ipv6/udp.c
--- v2.2.6/linux/net/ipv6/udp.c	Tue Mar 23 14:35:48 1999
+++ linux/net/ipv6/udp.c	Thu Apr 22 19:45:20 1999
@@ -7,7 +7,7 @@
X  *
X  *	Based on linux/ipv4/udp.c
X  *
- *	$Id: udp.c,v 1.38 1999/03/21 05:23:00 davem Exp $
+ *	$Id: udp.c,v 1.39 1999/04/22 10:07:47 davem Exp $
X  *
X  *	This program is free software; you can redistribute it and/or
X  *      modify it under the terms of the GNU General Public License
@@ -204,6 +204,7 @@
X 	struct in6_addr		saddr;
X 	struct dst_entry	*dst;
X 	struct flowi		fl;
+	struct ip6_flowlabel	*flowlabel = NULL;
X 	int			addr_type;
X 	int			err;
X 
@@ -218,6 +219,17 @@
X 	if (usin->sin6_family && usin->sin6_family != AF_INET6) 
X 	  	return(-EAFNOSUPPORT);
X 
+	fl.fl6_flowlabel = 0;
+	if (np->sndflow) {
+		fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
+		if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
+			flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+			if (flowlabel == NULL)
+				return -EINVAL;
+			ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
+		}
+	}
+
X 	addr_type = ipv6_addr_type(&usin->sin6_addr);
X 
X 	if (addr_type == IPV6_ADDR_ANY) {
@@ -262,6 +274,7 @@
X 	}
X 
X 	ipv6_addr_copy(&np->daddr, daddr);
+	np->flow_label = fl.fl6_flowlabel;
X 
X 	sk->dport = usin->sin6_port;
X 
@@ -271,25 +284,31 @@
X 	 */
X 
X 	fl.proto = IPPROTO_UDP;
-	fl.nl_u.ip6_u.daddr = &np->daddr;
-	fl.nl_u.ip6_u.saddr = NULL;
+	fl.fl6_dst = &np->daddr;
+	fl.fl6_src = &saddr;
X 	fl.oif = sk->bound_dev_if;
X 	fl.uli_u.ports.dport = sk->dport;
X 	fl.uli_u.ports.sport = sk->sport;
X 
-	if (np->opt && np->opt->srcrt) {
+	if (flowlabel) {
+		if (flowlabel->opt && flowlabel->opt->srcrt) {
+			struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt;
SHAR_EOF
true || echo 'restore of patch-2.2.7 failed'
fi
echo 'End of  part 19'
echo 'File patch-2.2.7 is continued in part 20'
echo 20 > _shar_seq_.tmp