lines    added  deleted
linux/CREDITS                                      :      60       25        7
linux/Documentation/Changes                        :      12        0        6
linux/Documentation/Configure.help                 :     673      355       61
linux/Documentation/SMP.txt                        :       8        1        1
linux/Documentation/cpqarray.txt                   :     107      107        0
linux/Documentation/fb/tgafb.txt                   :      51       51        0
linux/Documentation/java.txt                       :     365      295       34
linux/Documentation/kernel-parameters.txt          :       8        1        1
linux/Documentation/networking/arcnet-hardware.txt :     167       27       27
linux/Documentation/networking/arcnet.txt          :     141       18       19
linux/Documentation/networking/baycom.txt          :      21        3        3
linux/Documentation/networking/cs89x0.txt          :      58        9        9
linux/Documentation/networking/olympic.txt         :      75       75        0
linux/Documentation/networking/policy-routing.txt  :       8        1        1
linux/Documentation/networking/z8530drv.txt        :       8        1        1
linux/Documentation/oops-tracing.txt               :      35       10       10
linux/Documentation/parport.txt                    :     150       75       35
linux/Documentation/pcwd-watchdog.txt              :      25        6        3
linux/Documentation/sound/Introduction             :     263      142       17
linux/Documentation/sound/OPL3-SA2                 :      21       15        0
linux/Documentation/sysctl/README                  :       5        1        1
linux/Documentation/sysctl/fs.txt                  :       5        1        1
linux/Documentation/sysctl/kernel.txt              :      32       15        6
linux/Documentation/sysctl/sunrpc.txt              :       5        1        1
linux/Documentation/sysctl/vm.txt                  :       5        1        1
linux/Documentation/video4linux/API.html           :      60       24        4
linux/Documentation/video4linux/README.buz         :     212      212        0
linux/Documentation/video4linux/bttv/PROBLEMS      :      31        7        7
linux/Documentation/video4linux/bttv/README.RADIO  :       8        1        1
linux/Documentation/video4linux/bttv/THANKS        :       8        1        1
linux/MAINTAINERS                                  :     106       42        9
linux/Makefile                                     :      25        2        4
linux/README                                       :      21        4        4
linux/arch/alpha/config.in                         :      14        1        7
linux/arch/alpha/kernel/ptrace.c                   :     292       20      243
linux/arch/alpha/kernel/signal.c                   :       7        0        1
linux/arch/alpha/kernel/smp.c                      :       8        1        1
linux/arch/arm/kernel/process.c                    :       9        0        2
linux/arch/arm/kernel/time.c                       :       8        0        2
linux/arch/arm/nwfpe/fpmodule.c                    :       7        0        1
linux/arch/i386/boot/setup.S                       :      33       14        4
linux/arch/i386/config.in                          :      14        1        7
linux/arch/i386/defconfig                          :      65       21        7
linux/arch/i386/kernel/irq.h                       :       8        1        1
linux/arch/i386/kernel/process.c                   :       9        0        2
linux/arch/i386/kernel/ptrace.c                    :     238       10      207
linux/arch/i386/kernel/setup.c                     :      44       11       12
linux/arch/i386/kernel/smp.c                       :       8        1        1
linux/arch/i386/math-emu/fpu_emu.h                 :       8        0        2
linux/arch/i386/mm/fault.c                         :      39       16        3
linux/arch/mips/boot/elf2ecoff.c                   :       7        0        1
linux/arch/mips/config.in                          :       8        1        1
linux/arch/mips/defconfig                          :      11        0        5
linux/arch/mips/kernel/irixioctl.c                 :      29        9        8
linux/arch/mips/kernel/ptrace.c                    :     255       11      220
linux/arch/mips/kernel/r4k_misc.S                  :       7        0        1
linux/arch/mips/kernel/setup.c                     :       7        0        1
linux/arch/mips/mm/fault.c                         :      94       44        7
linux/arch/mips/sgi/kernel/indy_sc.c               :       7        0        1
linux/arch/ppc/amiga/amiints.c                     :       8        1        1
linux/arch/ppc/amiga/config.c                      :       7        0        1
linux/arch/ppc/config.in                           :      14        1        7
linux/arch/ppc/kernel/irq.c                        :       7        0        1
linux/arch/ppc/kernel/pci.c                        :       7        0        1
linux/arch/ppc/kernel/ppc-stub.c                   :       7        0        1
linux/arch/ppc/kernel/prep_setup.c                 :       7        0        1
linux/arch/ppc/kernel/process.c                    :       7        0        1
linux/arch/ppc/kernel/setup.c                      :       7        0        1
linux/arch/ppc/kernel/smp.c                        :       8        1        1
linux/arch/sparc/ap1000/aplib.c                    :       7        0        1
linux/arch/sparc/kernel/pcic.c                     :      15        0        2
linux/arch/sparc/kernel/process.c                  :       7        0        1
linux/arch/sparc/kernel/ptrace.c                   :     334       27      271
linux/arch/sparc/kernel/sparc-stub.c               :       7        0        1
linux/arch/sparc/kernel/sparc_ksyms.c              :       7        0        1
linux/arch/sparc/kernel/sun4d_smp.c                :       8        1        1
linux/arch/sparc/kernel/sun4m_smp.c                :       8        1        1
linux/arch/sparc/kernel/sunos_ioctl.c              :      12        1        2
linux/arch/sparc/kernel/sys_sunos.c                :       7        0        1
linux/arch/sparc/mm/asyncd.c                       :       5        1        1
linux/arch/sparc/mm/fault.c                        :      13        1        2
linux/arch/sparc/mm/srmmu.c                        :      15        2        0
linux/arch/sparc/mm/sun4c.c                        :      19        4        1
linux/arch/sparc64/config.in                       :      45       13       15
linux/arch/sparc64/defconfig                       :      29       11        3
linux/arch/sparc64/kernel/binfmt_aout32.c          :      27        4        1
linux/arch/sparc64/kernel/ioctl32.c                :      20        4        2
linux/arch/sparc64/kernel/psycho.c                 :      48        8        6
linux/arch/sparc64/kernel/ptrace.c                 :     656       55      541
linux/arch/sparc64/kernel/smp.c                    :       8        1        1
linux/arch/sparc64/kernel/sparc64_ksyms.c          :      37       11        2
linux/arch/sparc64/kernel/sys_sparc32.c            :      37        2        6
linux/arch/sparc64/kernel/sys_sunos32.c            :      16        1        2
linux/arch/sparc64/lib/Makefile                    :      15        3        2
linux/arch/sparc64/lib/atomic.S                    :      32       32        0
linux/arch/sparc64/lib/rwlock.S                    :      81       81        0
linux/arch/sparc64/mm/asyncd.c                     :       5        1        1
linux/arch/sparc64/mm/fault.c                      :       5        1        1
linux/arch/sparc64/solaris/ioctl.c                 :      69        7       15
linux/arch/sparc64/solaris/socksys.c               :       7        0        1
linux/drivers/acorn/char/keyb_arc.c                :       7        0        1
linux/drivers/ap1000/bif.c                         :       7        0        1
linux/drivers/ap1000/ringbuf.c                     :       7        1        0
linux/drivers/block/Config.in                      :     112       47       28
linux/drivers/block/Makefile                       :      25       10        2
linux/drivers/block/alim15x3.c                     :     114       66        5
linux/drivers/block/amiflop.c                      :      24        3        3
linux/drivers/block/ataflop.c                      :      44        5        5
linux/drivers/block/cmd646.c                       :      32        6        2
linux/drivers/block/cpqarray.c                     :    1730     1730        0
linux/drivers/block/cpqarray.h                     :     120      120        0
linux/drivers/block/floppy.c                       :      71        8        8
linux/drivers/block/genhd.c                        :     340      114       29
linux/drivers/block/hd.c                           :      17        2        2
linux/drivers/block/hpt343.c                       :     392        0      392
linux/drivers/block/hpt34x.c                       :     408      408        0
linux/drivers/block/icside.c                       :      17        4        0
linux/drivers/block/ida_cmd.h                      :     347      347        0
linux/drivers/block/ida_ioctl.h                    :      83       83        0
linux/drivers/block/ide-disk.c                     :      11        3        2
linux/drivers/block/ide-dma.c                      :      99       13       13
linux/drivers/block/ide-pci.c                      :     101       26       20
linux/drivers/block/ide-probe.c                    :      32        9        4
linux/drivers/block/ide-tape.c                     :     185       31       18
linux/drivers/block/ide.c                          :     111       42        7
linux/drivers/block/ll_rw_blk.c                    :      33       12        1
linux/drivers/block/loop.c                         :      51       13        4
linux/drivers/block/nbd.c                          :       8        1        1
linux/drivers/block/pdc202xx.c                     :      78        3       15
linux/drivers/block/piix.c                         :      98       21       10
linux/drivers/block/smart1,2.h                     :     274      274        0
linux/drivers/cdrom/aztcd.c                        :      17        2        2
linux/drivers/cdrom/cdu31a.c                       :      35        6        6
linux/drivers/cdrom/cm206.c                        :      44        5        5
linux/drivers/cdrom/gscd.c                         :      44        5        5
linux/drivers/cdrom/isp16.c                        :      65       12       12
linux/drivers/cdrom/mcd.c                          :      18        2        3
linux/drivers/cdrom/mcdx.c                         :      26        3        3
linux/drivers/cdrom/optcd.c                        :      26        3        3
linux/drivers/cdrom/sbpcd.c                        :      74        9        9
linux/drivers/cdrom/sjcd.c                         :      17        2        2
linux/drivers/cdrom/sonycd535.c                    :      21        4        4
linux/drivers/char/Config.in                       :      55       14        3
linux/drivers/char/Makefile                        :      75       48        0
linux/drivers/char/acquirewdt.c                    :       8        1        1
linux/drivers/char/adbmouse.c                      :      35        2        5
linux/drivers/char/amigamouse.c                    :      16        1        2
linux/drivers/char/amikeyb.c                       :      16        2        2
linux/drivers/char/atarimouse.c                    :      17        2        2
linux/drivers/char/atixlmouse.c                    :       8        1        1
linux/drivers/char/bttv.c                          :     625      183      133
linux/drivers/char/bttv.h                          :      20        3        3
linux/drivers/char/busmouse.c                      :      17        2        2
linux/drivers/char/buz.c                           :    3478     3478        0
linux/drivers/char/buz.h                           :     319      319        0
linux/drivers/char/bw-qcam.c                       :      17        3        1
linux/drivers/char/c-qcam.c                        :     132       39       24
linux/drivers/char/chipsets.h                      :      41       41        0
linux/drivers/char/console.c                       :       8        1        1
linux/drivers/char/consolemap.c                    :      10        2        2
linux/drivers/char/cyclades.c                      :     767      387       63
linux/drivers/char/dn_keyb.c                       :       8        1        1
linux/drivers/char/dsp56k.c                        :       9        1        2
linux/drivers/char/dz.c                            :      34        5        6
linux/drivers/char/esp.c                           :      16        1        2
linux/drivers/char/ftape/lowlevel/ftape-init.c     :       8        1        1
linux/drivers/char/ftape/lowlevel/ftape-proc.c     :      16        2        1
linux/drivers/char/ftape/lowlevel/ftape-setup.c    :       8        1        1
linux/drivers/char/ftape/zftape/zftape-init.c      :       8        1        1
linux/drivers/char/hfmodem/main.c                  :      70        7        8
linux/drivers/char/hfmodem/refclock.c              :      17        2        2
linux/drivers/char/i2c-parport.c                   :       9        0        2
linux/drivers/char/i2c.c                           :      29       16        0
linux/drivers/char/joystick/joy-db9.c              :       8        1        1
linux/drivers/char/lp.c                            :    1105      367      492
linux/drivers/char/lp_intern.c                     :       7        0        1
linux/drivers/char/n_hdlc.c                        :       7        0        1
linux/drivers/char/pc_keyb.c                       :       7        0        1
linux/drivers/char/pcwd.c                          :     136       50        9
linux/drivers/char/ppdev.c                         :     548      548        0
linux/drivers/char/ppdev.h                         :      65       65        0
linux/drivers/char/radio-aimslab.c                 :       8        1        1
linux/drivers/char/radio-aztech.c                  :       8        1        1
linux/drivers/char/radio-cadet.c                   :      37        4        8
linux/drivers/char/radio-gemtek.c                  :      26        3        3
linux/drivers/char/radio-miropcm20.c               :       8        1        1
linux/drivers/char/radio-rtrack2.c                 :       8        1        1
linux/drivers/char/radio-sf16fmi.c                 :       8        1        1
linux/drivers/char/radio-terratec.c                :     353      353        0
linux/drivers/char/radio-zoltrix.c                 :       8        1        1
linux/drivers/char/rocket.c                        :      31        1        4
linux/drivers/char/saa7111.c                       :     421      421        0
linux/drivers/char/saa7185.c                       :     379      379        0
linux/drivers/char/serial.c                        :       7        0        1
linux/drivers/char/sysrq.c                         :      49       10       12
linux/drivers/char/tpqic02.c                       :      26        3        3
linux/drivers/char/tty_io.c                        :     101       19       10
linux/drivers/char/videodev.c                      :      48       18        0
linux/drivers/char/zr36057.h                       :     168      168        0
linux/drivers/char/zr36060.h                       :      35       35        0
linux/drivers/fc4/socal.c                          :       7        0        1
linux/drivers/i2o/README                           :      47       14        6
linux/drivers/i2o/README.lan                       :      32        4        4
linux/drivers/i2o/i2o_block.c                      :      97       12       14
linux/drivers/i2o/i2o_config.c                     :     252      141        6
linux/drivers/i2o/i2o_core.c                       :    1730      662      618
linux/drivers/i2o/i2o_lan.c                        :     953      321      231
linux/drivers/i2o/i2o_lan.h                        :      45        8        8
linux/drivers/i2o/i2o_pci.c                        :      42       13        2
linux/drivers/i2o/i2o_proc.c                       :    2780     1414      695
linux/drivers/i2o/i2o_proc.h                       :     111        1      106
linux/drivers/i2o/i2o_scsi.c                       :     299       87       54
linux/drivers/isdn/avmb1/capidrv.c                 :      15        2        1
linux/drivers/isdn/hisax/amd7930.c                 :      10        2        2
linux/drivers/isdn/hisax/asuscom.c                 :      10        2        2
linux/drivers/isdn/hisax/avm_a1.c                  :      10        2        2
linux/drivers/isdn/hisax/config.c                  :      21        4        4
linux/drivers/isdn/hisax/diva.c                    :      10        2        2
linux/drivers/isdn/hisax/foreign.c                 :      10        2        2
linux/drivers/isdn/hisax/hfc_2bds0.c               :      21        4        4
linux/drivers/isdn/hisax/hfc_2bs0.c                :      21        4        4
linux/drivers/isdn/hisax/ix1_micro.c               :      10        2        2
linux/drivers/isdn/hisax/mic.c                     :      10        2        2
linux/drivers/isdn/hisax/netjet.c                  :      21        4        4
linux/drivers/isdn/hisax/niccy.c                   :      10        2        2
linux/drivers/isdn/hisax/sedlbauer.c               :      10        2        2
linux/drivers/isdn/hisax/sportster.c               :      21        4        4
linux/drivers/isdn/hisax/teleint.c                 :      10        2        2
linux/drivers/isdn/hisax/teles0.c                  :      10        2        2
linux/drivers/isdn/hisax/teles3.c                  :      10        2        2
linux/drivers/isdn/hisax/teles3c.c                 :      10        2        2
linux/drivers/isdn/isdn_bsdcomp.c                  :       7        0        1
linux/drivers/macintosh/macserial.c                :       7        0        1
linux/drivers/misc/Config.in                       :      37       37        0
linux/drivers/misc/Makefile                        :      26       11        2
linux/drivers/misc/parport_arc.c                   :      87       24       32
linux/drivers/misc/parport_atari.c                 :       9        0        3
linux/drivers/misc/parport_ax.c                    :     201       55       82
linux/drivers/misc/parport_daisy.c                 :     473      473        0
linux/drivers/misc/parport_ieee1284.c              :     555      489       35
linux/drivers/misc/parport_ieee1284_ops.c          :     848      848        0
linux/drivers/misc/parport_init.c                  :      65       33        7
linux/drivers/misc/parport_pc.c                    :    2008     1162      396
linux/drivers/misc/parport_probe.c                 :     212      212        0
linux/drivers/misc/parport_procfs.c                :      59        8       12
linux/drivers/misc/parport_share.c                 :     374       99       80
linux/drivers/net/3c501.c                          :      17        2        2
linux/drivers/net/3c503.c                          :      32        6        6
linux/drivers/net/3c505.c                          :      26        3        3
linux/drivers/net/3c507.c                          :      17        2        2
linux/drivers/net/3c523.c                          :      17        2        2
linux/drivers/net/3c527.c                          :      17        2        2
linux/drivers/net/82596.c                          :       8        1        1
linux/drivers/net/Config.in                        :     188       54       17
linux/drivers/net/Makefile                         :      80       37        9
linux/drivers/net/Space.c                          :      62       11        3
linux/drivers/net/a2065.c                          :       9        1        2
linux/drivers/net/ac3200.c                         :      17        2        2
linux/drivers/net/acenic.c                         :      44        5        5
linux/drivers/net/apne.c                           :      18        2        3
linux/drivers/net/arc-rimi.c                       :      35        4        4
linux/drivers/net/arcnet.c                         :      44       11        5
linux/drivers/net/ariadne.c                        :       8        1        1
linux/drivers/net/ariadne2.c                       :      20        3        4
linux/drivers/net/arlan-proc.c                     :    1059     1059        0
linux/drivers/net/arlan.c                          :    2079     2079        0
linux/drivers/net/arlan.h                          :     575      574        0
linux/drivers/net/atari_bionet.c                   :      10        2        2
linux/drivers/net/atari_pamsnet.c                  :      10        2        2
linux/drivers/net/atarilance.c                     :      40       10       10
linux/drivers/net/atp.c                            :      37        5        5
linux/drivers/net/com20020.c                       :      35        4        4
linux/drivers/net/com90io.c                        :      35        4        4
linux/drivers/net/com90xx.c                        :      44        5        5
linux/drivers/net/cops.c                           :      26        3        3
linux/drivers/net/cosa.c                           :       8        1        1
linux/drivers/net/cs89x0.c                         :      65       11       13
linux/drivers/net/de4x5.c                          :     144       21       28
linux/drivers/net/de600.c                          :      10        2        2
linux/drivers/net/de620.c                          :      32        6        6
linux/drivers/net/defxx.c                          :      70       10       26
linux/drivers/net/depca.c                          :     133       24       26
linux/drivers/net/dgrs.c                           :      72       12       12
linux/drivers/net/dlci.c                           :       8        1        1
linux/drivers/net/dummy.c                          :      17        2        2
linux/drivers/net/e2100.c                          :      17        2        2
linux/drivers/net/eepro100.c                       :      18        3        2
linux/drivers/net/eexpress.c                       :      28        4        4
linux/drivers/net/eql.c                            :     103       10       16
linux/drivers/net/es3210.c                         :      17        2        2
linux/drivers/net/eth16i.c                         :      26        3        3
linux/drivers/net/ethertap.c                       :       8        1        1
linux/drivers/net/ewrk3.c                          :     256       49       50
linux/drivers/net/fmv18x.c                         :      19        3        3
linux/drivers/net/hamradio/6pack.c                 :       8        1        1
linux/drivers/net/hamradio/baycom_par.c            :      26        3        3
linux/drivers/net/hamradio/baycom_ser_fdx.c        :      26        3        3
linux/drivers/net/hamradio/baycom_ser_hdx.c        :      26        3        3
linux/drivers/net/hamradio/bpqether.c              :       8        1        1
linux/drivers/net/hamradio/dmascc.c                :      27        3        4
linux/drivers/net/hamradio/hdlcdrv.c               :      16        1        2
linux/drivers/net/hamradio/mkiss.c                 :      17        2        2
linux/drivers/net/hamradio/pi2.c                   :      17        2        2
linux/drivers/net/hamradio/pt.c                    :      18        2        3
linux/drivers/net/hamradio/scc.c                   :       8        1        1
linux/drivers/net/hamradio/soundmodem/sm.c         :      29        4        4
linux/drivers/net/hamradio/soundmodem/sm.h         :       8        0        2
linux/drivers/net/hostess_sv11.c                   :       9        2        1
linux/drivers/net/hp-plus.c                        :      17        2        2
linux/drivers/net/hp.c                             :      17        2        2
linux/drivers/net/hp100.c                          :      28        4        3
linux/drivers/net/hplance.c                        :      17        2        2
linux/drivers/net/hydra.c                          :       8        1        1
linux/drivers/net/ibmtr.c                          :      74        7        9
linux/drivers/net/irda/actisys.c                   :       8        1        1
linux/drivers/net/irda/esi.c                       :       8        1        1
linux/drivers/net/irda/girbil.c                    :       8        1        1
linux/drivers/net/irda/irport.c                    :       8        1        1
linux/drivers/net/irda/irtty.c                     :       8        1        1
linux/drivers/net/irda/litelink.c                  :       8        1        1
linux/drivers/net/irda/pc87108.c                   :       8        1        1
linux/drivers/net/irda/smc-ircc.c                  :      17        1        3
linux/drivers/net/irda/tekram.c                    :       8        1        1
linux/drivers/net/irda/toshoboe.c                  :      22        3        3
linux/drivers/net/irda/uircc.c                     :      17        1        3
linux/drivers/net/irda/w83977af_ir.c               :       8        1        1
linux/drivers/net/lance.c                          :      17        3        1
linux/drivers/net/lne390.c                         :      17        2        2
linux/drivers/net/loopback.c                       :       8        1        1
linux/drivers/net/ltpc.c                           :      26        3        3
linux/drivers/net/myri_sbus.c                      :       8        1        1
linux/drivers/net/ne.c                             :      26        3        3
linux/drivers/net/ne2.c                            :      18        2        3
linux/drivers/net/ne2k-pci.c                       :     346       97       86
linux/drivers/net/ne3210.c                         :      17        2        2
linux/drivers/net/olympic.c                        :    1663     1663        0
linux/drivers/net/olympic.h                        :     303      303        0
linux/drivers/net/ppp.c                            :       7        0        1
linux/drivers/net/rtl8139.c                        :     368      105       52
linux/drivers/net/sealevel.c                       :     471      471        0
linux/drivers/net/seeq8005.c                       :      74       51        3
linux/drivers/net/slhc.c                           :       7        0        1
linux/drivers/net/sunbmac.c                        :       7        0        1
linux/drivers/net/sunhme.c                         :       8        1        1
linux/drivers/net/sunlance.c                       :       7        0        1
linux/drivers/net/tulip.c                          :      68       16        5
linux/drivers/net/via-rhine.c                      :      86       11       10
linux/drivers/net/wavelan.c                        :     184       36       56
linux/drivers/net/z85230.c                         :      71       16        2
linux/drivers/net/zlib.c                           :      10        0        4
linux/drivers/pci/oldproc.c                        :      56        7        1
linux/drivers/pci/pci.c                            :      59       14        4
linux/drivers/pnp/Config.in                        :      16        0       13
linux/drivers/pnp/Makefile                         :      24        0       12
linux/drivers/pnp/parport_probe.c                  :     288        0      288
linux/drivers/sbus/char/bpp.c                      :      20        2        3
linux/drivers/sbus/char/sab82532.c                 :      22        2        3
linux/drivers/sbus/char/su.c                       :      22        2        3
linux/drivers/sbus/sbus.c                          :       7        0        1
linux/drivers/scsi/53c7xx.c                        :      26        1        3
linux/drivers/scsi/NCR53C9x.c                      :      27        5        0
linux/drivers/scsi/aha152x.c                       :    5441     2452     2285
linux/drivers/scsi/aic7xxx/aic7xxx.reg             :       8        1        1
linux/drivers/scsi/aic7xxx.c                       :     308       88       70
linux/drivers/scsi/aic7xxx_reg.h                   :      12        1        1
linux/drivers/scsi/atp870u.c                       :      37        8        1
linux/drivers/scsi/constants.c                     :     148       45       20
linux/drivers/scsi/i60uscsi.c                      :      14        3        3
linux/drivers/scsi/ide-scsi.c                      :      38       10        5
linux/drivers/scsi/ini9100u.c                      :      64        5       22
linux/drivers/scsi/inia100.c                       :      58        5       17
linux/drivers/scsi/megaraid.c                      :       9        0        2
linux/drivers/scsi/mvme16x.c                       :       7        0        1
linux/drivers/scsi/ncr53c8xx.c                     :       8        1        1
linux/drivers/scsi/pas16.c                         :       6        0        1
linux/drivers/scsi/ppa.c                           :      17        3        3
linux/drivers/scsi/qlogicfc.c                      :    1001      275      143
linux/drivers/scsi/qlogicfc.h                      :      39       14        5
linux/drivers/scsi/qlogicisp.c                     :      10        2        0
linux/drivers/scsi/scsi_debug.c                    :      10        0        4
linux/drivers/scsi/sd.c                            :       7        1        0
linux/drivers/scsi/st.c                            :       8        1        1
linux/drivers/scsi/sym53c416.c                     :      84       18        1
linux/drivers/sgi/char/graphics.c                  :       9        1        2
linux/drivers/sgi/char/shmiq.c                     :       9        1        2
linux/drivers/sgi/char/usema.c                     :      10        2        2
linux/drivers/sound/cmpci.c                        :      17        0        3
linux/drivers/sound/dev_table.h                    :      56        8       18
linux/drivers/sound/es1370.c                       :      11        2        2
linux/drivers/sound/es1371.c                       :      11        2        2
linux/drivers/sound/lowlevel/awe_compat-fbsd.h     :       7        0        1
linux/drivers/sound/maui.c                         :      14        5        2
linux/drivers/sound/msnd_pinnacle.c                :     110       13       13
linux/drivers/sound/opl3sa2.c                      :      34        6        3
linux/drivers/sound/sb_ess.c                       :    1438      615      420
linux/drivers/sound/sb_mixer.c                     :      52       31        7
linux/drivers/sound/sb_mixer.h                     :      11        5        0
linux/drivers/sound/sgalaxy.c                      :       8        1        1
linux/drivers/sound/sonicvibes.c                   :      11        2        2
linux/drivers/sound/sound_calls.h                  :      57       23        5
linux/drivers/sound/sound_syms.c                   :      17        4        0
linux/drivers/sound/trix.c                         :      33        9        4
linux/drivers/sound/wavfront.c                     :      73        6       12
linux/drivers/sound/wf_midi.c                      :      18        2        3
linux/drivers/usb/CREDITS                          :       8        1        1
linux/drivers/usb/hub.h                            :      16        2        1
linux/drivers/usb/ohci-debug.c                     :      21        3        4
linux/drivers/usb/ohci.c                           :     208       64       22
linux/drivers/usb/ohci.h                           :       7        0        1
linux/drivers/usb/printer.c                        :      28        6        2
linux/drivers/usb/uhci.c                           :      74       18        9
linux/drivers/usb/uhci.h                           :      18        6        6
linux/drivers/usb/usb.c                            :      65       20        9
linux/drivers/usb/usb.h                            :     123       43       12
linux/drivers/video/Makefile                       :      11        2        0
linux/drivers/video/fbmem.c                        :      16        2        1
linux/drivers/video/tgafb.c                        :    1551      695      593
linux/drivers/video/tgafb.h                        :     190      190        0
linux/fs/binfmt_aout.c                             :       9        2        1
linux/fs/binfmt_elf.c                              :       8        2        0
linux/fs/coda/cache.c                              :       9        1        1
linux/fs/coda/cnode.c                              :      49       19       10
linux/fs/coda/coda_linux.c                         :       8        2        0
linux/fs/coda/dir.c                                :      20        4        4
linux/fs/coda/inode.c                              :      99       23       13
linux/fs/coda/sysctl.c                             :     122       36       14
linux/fs/coda/upcall.c                             :      71       44        4
linux/fs/devices.c                                 :      15        2        0
linux/fs/dquot.c                                   :      70       13        8
linux/fs/exec.c                                    :      39        7        3
linux/fs/ext2/ioctl.c                              :      58       23       15
linux/fs/fat/dir.c                                 :      44        9        3
linux/fs/fat/mmap.c                                :       9        1        2
linux/fs/fcntl.c                                   :     109       26       26
linux/fs/fifo.c                                    :       7        1        0
linux/fs/file_table.c                              :     192       87       45
linux/fs/inode.c                                   :      48        2       26
linux/fs/ioctl.c                                   :      31        4        2
linux/fs/locks.c                                   :     157       40       47
linux/fs/minix/file.c                              :      15        0        2
linux/fs/namei.c                                   :      25        7        3
linux/fs/ncpfs/dir.c                               :       7        0        1
linux/fs/ncpfs/mmap.c                              :       9        1        2
linux/fs/nfs/read.c                                :      11        3        2
linux/fs/nfs/write.c                               :      15        1        1
linux/fs/nfsd/nfsctl.c                             :       7        0        1
linux/fs/nfsd/vfs.c                                :       8        1        1
linux/fs/open.c                                    :     242       39       35
linux/fs/pipe.c                                    :      29        5        1
linux/fs/proc/fd.c                                 :      29        3        4
linux/fs/proc/inode.c                              :      59       22        2
linux/fs/proc/link.c                               :      24        7        0
linux/fs/proc/root.c                               :      52       28       16
linux/fs/qnx4/dir.c                                :      11        5        0
linux/fs/qnx4/symlinks.c                           :      14        2        2
linux/fs/select.c                                  :      26        7        5
linux/fs/super.c                                   :       7        1        0
linux/fs/sysv/file.c                               :       9        0        3
linux/fs/ufs/balloc.c                              :      29       15        7
linux/fs/ufs/super.c                               :       9        2        1
linux/fs/umsdos/file.c                             :       7        0        1
linux/include/asm-i386/bugs.h                      :      22        0       16
linux/include/asm-i386/setup.h                     :       4        4        0
linux/include/asm-mips/processor.h                 :       9        0        3
linux/include/asm-mips/ptrace.h                    :       8        1        1
linux/include/asm-sparc/asm_offsets.h              :     135       44       40
linux/include/asm-sparc/audioio.h                  :       7        0        1
linux/include/asm-sparc/page.h                     :      13        1        2
linux/include/asm-sparc64/asm_offsets.h            :     212       69       63
linux/include/asm-sparc64/atomic.h                 :     100       29       61
linux/include/asm-sparc64/audioio.h                :       7        0        1
linux/include/asm-sparc64/spinlock.h               :     135       37       83
linux/include/linux/blk.h                          :      33       19        1
linux/include/linux/coda.h                         :     167       44       27
linux/include/linux/coda_proc.h                    :       7        1        0
linux/include/linux/coda_psdev.h                   :       7        1        0
linux/include/linux/cyclades.h                     :       8        1        1
linux/include/linux/file.h                         :      66       20       10
linux/include/linux/fs.h                           :     130       30       24
linux/include/linux/i2c.h                          :      19        6        4
linux/include/linux/i2o.h                          :     229      124       34
linux/include/linux/ide.h                          :      23        3        0
linux/include/linux/isdn.h                         :       9        0        3
linux/include/linux/isdn_timru.h                   :     119        0      119
linux/include/linux/lp.h                           :      54       10        9
linux/include/linux/major.h                        :      21       13        0
linux/include/linux/mm.h                           :      19        4        2
linux/include/linux/mount.h                        :       8        1        1
linux/include/linux/parport.h                      :     580      248      143
linux/include/linux/parport_pc.h                   :     222       82       83
linux/include/linux/pci.h                          :      86       17        0
linux/include/linux/proc_fs.h                      :      26        7        6
linux/include/linux/sched.h                        :      24        3        1
linux/include/linux/soundcard.h                    :      12        6        0
linux/include/linux/swap.h                         :       9        0        3
linux/include/linux/tty.h                          :       7        1        0
linux/include/linux/video_decoder.h                :      37       37        0
linux/include/linux/video_encoder.h                :      21       21        0
linux/include/linux/videodev.h                     :       7        1        0
linux/include/net/irda/irmod.h                     :       8        1        1
linux/include/net/sock.h                           :      73        1       45
linux/include/net/tcp.h                            :      93        5       47
linux/include/net/udp.h                            :      27       13        1
linux/init/main.c                                  :      19        6        0
linux/ipc/shm.c                                    :      41        5        2
linux/kernel/Makefile                              :       8        1        1
linux/kernel/acct.c                                :       8        1        1
linux/kernel/exit.c                                :      25        3        6
linux/kernel/fork.c                                :      71       13        8
linux/kernel/ksyms.c                               :      27        4        2
linux/kernel/ptrace.c                              :     163      163        0
linux/kernel/sched.c                               :      17        2        2
linux/kernel/signal.c                              :      67        9        7
linux/kernel/sys.c                                 :       8        2        0
linux/kernel/sysctl.c                              :       7        0        1
linux/lib/string.c                                 :      17       14        0
linux/mm/filemap.c                                 :     105        5       19
linux/mm/memory.c                                  :     431      162       94
linux/mm/mlock.c                                   :      71        2       10
linux/mm/mmap.c                                    :     100       12       12
linux/mm/mprotect.c                                :      33        2        4
linux/mm/mremap.c                                  :      48        7        6
linux/mm/page_alloc.c                              :      90        0       87
linux/mm/vmscan.c                                  :      71       13        4
linux/net/appletalk/ddp.c                          :      26        5        1
linux/net/ax25/af_ax25.c                           :       9        3        0
linux/net/bridge/br.c                              :      12        0        4
linux/net/core/scm.c                               :      23        4        5
linux/net/decnet/dn_fib.c                          :       7        0        1
linux/net/econet/econet.c                          :       9        2        1
linux/net/ipv4/af_inet.c                           :     271       56       55
linux/net/ipv4/icmp.c                              :       7        0        1
linux/net/ipv4/proc.c                              :     198        1      184
linux/net/ipv4/raw.c                               :     165       77       47
linux/net/ipv4/tcp.c                               :       8        1        1
linux/net/ipv4/tcp_input.c                         :      58       13       14
linux/net/ipv4/tcp_ipv4.c                          :     633      352      162
linux/net/ipv4/tcp_timer.c                         :      70        2       41
linux/net/ipv4/udp.c                               :     394      144      151
linux/net/ipv6/af_inet6.c                          :      76        9       14
linux/net/ipv6/ip6_fw.c                            :      15        3        4
linux/net/ipv6/proc.c                              :     149        1      135
linux/net/ipv6/raw.c                               :     182       88       49
linux/net/ipv6/route.c                             :       7        0        1
linux/net/ipv6/tcp_ipv6.c                          :     484      297      111
linux/net/ipv6/udp.c                               :     332      158       89
linux/net/ipx/af_ipx.c                             :       9        2        1
linux/net/irda/compressors/irda_deflate.c          :       7        0        1
linux/net/irda/irmod.c                             :       8        2        0
linux/net/netrom/af_netrom.c                       :      19        5        1
linux/net/netsyms.c                                :      93       10       13
linux/net/rose/af_rose.c                           :      19        5        1
linux/net/socket.c                                 :       8        1        1
linux/net/sunrpc/xprt.c                            :      51        1       37
linux/net/unix/af_unix.c                           :       7        0        1
linux/net/unix/garbage.c                           :       8        1        1
linux/net/wanrouter/wanproc.c                      :      41       12        6
linux/net/x25/af_x25.c                             :       7        0        1
linux/net/x25/x25_dev.c                            :       7        0        1
linux/scripts/ksymoops/Makefile                    :      79        0       79
linux/scripts/ksymoops/README                      :     405        6      398
linux/scripts/ksymoops/io.c                        :     139        0      139
linux/scripts/ksymoops/ksymoops.c                  :     678        0      678
linux/scripts/ksymoops/ksymoops.h                  :     146        0      146
linux/scripts/ksymoops/ksyms.c                     :     294        0      294
linux/scripts/ksymoops/map.c                       :     251        0      251
linux/scripts/ksymoops/misc.c                      :     108        0      108
linux/scripts/ksymoops/object.c                    :     230        0      230
linux/scripts/ksymoops/oops.c                      :    1377        0     1377
linux/scripts/ksymoops/re.c                        :     145        0      145
linux/scripts/ksymoops/symbol.c                    :     444        0      444
linux/scripts/ver_linux                            :      15        5        3
#!/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 37 - 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.3.10 ==============
if test -f 'patch-2.3.10' -a X"$1" != X"-c"; then
        echo 'x - skipping patch-2.3.10 (File already exists)'
        rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting patch-2.3.10 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'patch-2.3.10' &&
diff -u --recursive --new-file v2.3.9/linux/CREDITS linux/CREDITS
--- v2.3.9/linux/CREDITS	Wed Jun 30 13:38:18 1999
+++ linux/CREDITS	Tue Jul  6 10:19:57 1999
@@ -163,7 +163,7 @@
X D: Various bugfixes and changes to sound drivers
X S: USA 
X 
-M: Krzysztof G. Baranowski
+N: Krzysztof G. Baranowski
X E: k...@manjak.knm.org.pl
X P: 1024/FA6F16D1 96 D1 1A CF 5F CA 69 EC  F9 4F 36 1F 6D 60 7B DA
X D: Maintainer of the System V file system.
@@ -174,6 +174,17 @@
X S: 62-300 Wrzesnia
X S: Poland
X 
+N: Carlos Henrique Bauer
+E: chb...@acm.org
+E: ba...@atlas.unisinos.tche.br
+D: A test for detection of EPP-1.7 and ECP/EPP parports.
+D: Some new sysctl entries for the parport driver.
+S: Universidade do Vale do Rio dos Sinos - UNISINOS
+S: DSI/IDASI
+S: Av. Unisinos, 950
+S: 93022000 Sao Leopoldo RS
+S: Brazil
+
X N: Peter Bauer
X E: 10013...@compuserve.com
X D: Driver for depca-ethernet-board
@@ -869,13 +880,11 @@
X S: 65760 Eschborn
X S: Germany
X 
-N: Kenji Tsutomu Hollis
-E: kho...@bitgate.com
-W: http://www.nurk.org/
+N: Kenji Hollis
+E: ke...@bitgate.com
+W: http://www.bitgate.com/
X D: Berkshire PC Watchdog Driver
-S: Post Office Box 15
-S: Grants Pass, Oregon 97526
-S: USA
+D: Small/Industrial Driver Project
X 
X N: Nick Holloway
X E: Nick.H...@alfie.demon.co.uk
@@ -1660,6 +1669,15 @@
X S: 4390 Albany Drive #41A
X S: San Jose, California 95129
X S: USA
+
+N: Augusto Cesar Radtke
+E: bis...@sekure.org
+W: http://bishop.sekure.org
+D: {copy,get,put}_user calls updates
+D: Miscellaneous hacks
+S: R. Otto Marquardt, 226 - Garcia
+S: 89020-350 Blumenau - Santa Catarina
+S: Brazil
X 
X N: Eric S. Raymond
X E: e...@thyrsus.com
diff -u --recursive --new-file v2.3.9/linux/Documentation/Changes linux/Documentation/Changes
--- v2.3.9/linux/Documentation/Changes	Fri May  7 09:31:25 1999
+++ linux/Documentation/Changes	Thu Jul  1 10:54:31 1999
@@ -191,12 +191,6 @@
X users should especially try to use the 2.9.1.0.x releases, as they
X resolve known issues with glibc2 and binutils-2.8.x releases.
X 
-   libbfd, libiberty, and /usr/include/bfd.h, which are part of recent
-binutils packages, are also required to compile ksymoops.  Depending
-upon your distribution, this may require you to install both binutils
-and binutils-development packages (Debian puts bfd.h in binutils-dev,
-for example).
-
X Gnu C
X =====
X 
diff -u --recursive --new-file v2.3.9/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.3.9/linux/Documentation/Configure.help	Wed Jun 30 13:38:18 1999
+++ linux/Documentation/Configure.help	Mon Jul  5 20:37:25 1999
@@ -530,7 +530,7 @@
X   People with SCSI-only systems should say N here; if unsure say Y.
X 
X Generic PCI bus-master DMA support
-CONFIG_BLK_DEV_IDEDMA
+CONFIG_BLK_DEV_IDEDMA_PCI
X   If your PCI system uses IDE drive(s) (as opposed to SCSI, say) and
X   is capable of bus-master DMA operation (most Pentium PCI systems),
X   you will want to say Y here to reduce CPU overhead. You can then use
@@ -546,6 +546,26 @@
X 
X   It is safe to say Y to this question.
X 
+Good-Bad DMA Model-Firmware (EXPERIMENTAL)
+IDEDMA_NEW_DRIVE_LISTINGS
+  This test compares both the model and firmware revision for buggy drives
+  that claim to (U)DMA capable.  This is a blanket on/off test with no speed
+  limit options.  Straight GNU GCC 2.7.3/2.8.X compilers are known to be safe;
+  whereas, many versions of EGCS have a problem and miscompile.
+
+  If in doubt, say N.
+
+Generic ATA-66 support (DANGEROUS)
+CONFIG_IDEDMA_ULTRA_66
+  This allows for your Generic IDE control to attempt support for
+  using ATA-66 or UDMA-66 transfer modes 3/4.  If you are not sure what you
+  are attempting, "DO NOT" even think about this option, unless your
+  mainboard's chipset is verified.  Do not complain to anyone if you
+  do not know what you are doing and are just playing around.
+  This option has no known success cases to date.
+
+  Say N, or beware.........
+
X Winbond SL82c105 support
X CONFIG_BLK_DEV_SL82C105
X   If you have a Winbond SL82c105 IDE controller, say Y here to enable
@@ -562,13 +582,16 @@
X   improve the usability of some boot managers such as LILO when
X   booting from a drive on an off-board controller.
X 
+  Requires that all onboard ide controllers be disabled or calling
+  "pci=reverse" to invert the device scan order.
+
X   Note that, if you say Y here, the order of the hd* devices will be
X   rearranged which may require modification of fstab and other files.
X 
X   If in doubt, say N.
X 
X Use DMA by default when available
-CONFIG_IDEDMA_AUTO
+CONFIG_IDEDMA_PCI_AUTO
X   Prior to kernel version 2.1.112, Linux used to automatically use
X   DMA for IDE drives and chipsets which support it. Due to concerns
X   about a couple of cases where buggy hardware may have caused damage,
@@ -664,7 +687,7 @@
X   This driver adds detection and support for the CY82C693 chipset
X   used on Digital's PC-Alpha 164SX boards.
X 
-  This requires CONFIG_IDEDMA_AUTO to be enabled.
+  This requires CONFIG_IDEDMA_PCI_AUTO to be enabled.
X 
X   Please read the comments at the top of drivers/block/cy82c693.c
X 
@@ -679,7 +702,7 @@
X   (while running a "cat") provided you enabled "proc" support and
X   set DISPLAY_APOLLO_TIMINGS in via82c586.c
X 
-  This requires CONFIG_IDEDMA_AUTO to be enabled.
+  This requires CONFIG_IDEDMA_PCI_AUTO to be enabled.
X 
X   If unsure, say N.
X 
@@ -693,14 +716,15 @@
X   onboard chipsets.  It also tests for Simplex mode and enables
X   normal dual channel support.
X 
-  This requires CONFIG_IDEDMA_AUTO to be enabled.
+  This requires CONFIG_IDEDMA_PCI_AUTO to be enabled.
X 
X   Please read the comments at the top of drivers/block/alim15x3.c
X 
X   If unsure, say N.
X 
-PROMISE PDC20246 support (EXPERIMENTAL)
-CONFIG_BLK_DEV_PDC20246
+PROMISE PDC20246/PDC20262 support
+CONFIG_BLK_DEV_PDC202XX
+  Promise Ultra33 or PDC20246.
X   This driver adds up to 4 more eide devices sharing a single interrupt.
X   This add-on card is a bootable PCI UDMA controller.
X   Since multiple cards can be installed and there are BIOS ROM problems
@@ -708,38 +732,49 @@
X   do not match.  Should you be unable to make new BIOS chips with a burner,
X   the driver attempts to dynamic tuning of the chipset at boot-time
X   for max-speed.  Ultra33 BIOS 1.25 or new required for more than one card.
+  This card may require "PDC202XX Special UDMA Feature (EXPERIMENTAL)".
X 
-  This requires CONFIG_IDEDMA_AUTO to be enabled.
-
-  Please read the comments at the top of drivers/block/pdc202xx.c
-
-  If unsure, say N.
-
-PROMISE PDC20262 support (EXPERIMENTAL)
-CONFIG_BLK_DEV_PDC20262
+  Promise Ultra66 or PDC20262.
X   This driver adds up to 4 more eide devices sharing a single interrupt.
X   This add-on card is a bootable PCI UDMA ATA-66 controller.
X   The driver attempts to dynamic tuning of the chipset at boot-time
X   for max-speed.  Note tested limits are UDMA-2.
X   Ultra66 BIOS 1.11 or newer required.
X 
-  This requires CONFIG_IDEDMA_AUTO to be enabled.
+  This requires CONFIG_IDEDMA_PCI_AUTO to be enabled.
X 
X   Please read the comments at the top of drivers/block/pdc202xx.c
X 
X   If unsure, say N.
X 
+Special UDMA Feature (EXPERIMENTAL)
+PDC202XX_FORCE_BURST_BIT
+  For PDC20246 and PDC20262 Ultra DMA chipsets.
+  Designed originally for PDC20246/Ultra33 that has BIOS setup failures
+  when using 3 or more cards.
+
+  Please read the comments at the top of drivers/block/pdc202xx.c
+
+  If unsure, say N.
+
+Special Mode Feature (DANGEROUS)
+PDC202XX_FORCE_MASTER_MODE
+  For PDC20246 and PDC20262 Ultra DMA chipsets.
+  This is reserved for possible Hardware RAID 0,1 for the FastTrak Series.
+
+  Say N. 
+
X AEC6210 chipset support
X CONFIG_BLK_DEV_AEC6210
X   This driver adds up to 4 more eide devices sharing a single interrupt.
X   This add-on card is a bootable PCI UDMA controller.  In order to get this
X   card to initialize correctly in some cases, you should include this driver.
X 
-  This prefers CONFIG_IDEDMA_AUTO to be enabled, regardless.
+  This prefers CONFIG_IDEDMA_PCI_AUTO to be enabled, regardless.
X 
X   Please read the comments at the top of drivers/block/aec6210.c
X 
-Intel PIIXn chipsets support (EXPERIMENTAL)
+Intel PIIXn chipsets support
X CONFIG_BLK_DEV_PIIX
X   This driver adds PIO mode setting and tuning for all PIIX IDE
X   controllers by Intel.  Since the BIOS can sometimes improperly tune
@@ -750,15 +785,31 @@
X 
X   If unsure, say N.
X 
-HPT343 chipset support (EXPERIMENTAL)
-CONFIG_BLK_DEV_HPT343
+PIIXn Tuning support (EXPERIMENTAL)
+CONFIG_BLK_DEV_PIIX_TUNING
+  This driver extension adds DMA mode setting and tuning for all PIIX IDE
+  controllers by Intel.  Since the BIOS can sometimes improperly setup
+  the device/adapter combination and speed limits, It has become a necessity
+  to back/forward speed devices as needed.
+
+  Case 430HX/440FX PIIX3 need speed limits to reduce UDMA to DMA mode 2
+  if the BIOS can to perform this task at INIT.
+
+  If unsure, say N.
+
+HPT34X chipset support
+CONFIG_BLK_DEV_HPT34X
X   This driver adds up to 4 more EIDE devices sharing a single
-  interrupt. The HPT343 chipset in its current form is a non-bootable
-  PCI UDMA controller. This driver requires dynamic tuning of the
-  chipset during the ide-probe at boot. It is reported to support DVD
-  II drives, by the manufacturer.
+  interrupt. The HPT343 chipset in its current form is a non-bootable or
+  HPT345/HPT363 chipset is bootable (needs BIOS FIX) PCI UDMA controllers.
+  This driver requires dynamic tuning of the chipset during the ide-probe
+  at boot. It is reported to support DVD II drives, by the manufacturer.
+
+  Please read the comments at the top of drivers/block/hpt343.c
X 
-  This requires CONFIG_IDEDMA_AUTO to be enabled.
+HPT34X DMA support (DANGEROUS)
+CONFIG_BLK_DEV_HPT34X_DMA
+  This requires CONFIG_IDEDMA_PCI_AUTO to be enabled.
X 
X   Please read the comments at the top of drivers/block/hpt343.c
X 
@@ -821,17 +872,17 @@
X   Say Y if you have an IDE doubler.  The driver is enabled at kernel
X   runtime using the "ide=doubler" kernel boot parameter.
X 
- Support for PowerMac IDE devices (must also enable IDE)
- CONFIG_BLK_DEV_IDE_PMAC
-   No help for CONFIG_BLK_DEV_IDE_PMAC
-
- PowerMac IDE DMA support
- CONFIG_BLK_DEV_IDEDMA_PMAC
-   No help for CONFIG_BLK_DEV_IDEDMA_PMAC
-
- Use DMA by default
- CONFIG_PMAC_IDEDMA_AUTO
-   No help for CONFIG_PMAC_IDEDMA_AUTO
+Support for PowerMac IDE devices (must also enable IDE)
+CONFIG_BLK_DEV_IDE_PMAC
+  No help for CONFIG_BLK_DEV_IDE_PMAC
+
+PowerMac IDE DMA support
+CONFIG_BLK_DEV_IDEDMA_PMAC
+  No help for CONFIG_BLK_DEV_IDEDMA_PMAC
+
+Use DMA by default
+CONFIG_IDEDMA_PMAC_AUTO
+  No help for CONFIG_IDEDMA_PMAC_AUTO
X 
X Macintosh Quadra/Powerbook IDE interface support
X CONFIG_BLK_DEV_MAC_IDE
@@ -843,9 +894,21 @@
X   (hard disks, CD-ROM drives, etc.) that are connected to the builtin
X   IDE interface.
X 
- RapIDE interface support
- CONFIG_BLK_DEV_IDE_RAPIDE
-   No help for CONFIG_BLK_DEV_IDE_RAPIDE
+ICS IDE interface support
+CONFIG_BLK_DEV_IDE_ICSIDE
+  No help for CONFIG_BLK_DEV_IDE_ICSIDE
+
+ICS DMA support
+CONFIG_BLK_DEV_IDEDMA_ICS
+  No help for CONFIG_BLK_DEV_IDEDMA_ICS
+
+Use ICS DMA by default
+CONFIG_IDEDMA_ICS_AUTO
+  No help for CONFIG_IDEDMA_ICS_AUTO
+
+RapIDE interface support
+CONFIG_BLK_DEV_IDE_RAPIDE
+  No help for CONFIG_BLK_DEV_IDE_RAPIDE
X 
X XT hard disk support
X CONFIG_BLK_DEV_XD
@@ -1611,6 +1674,45 @@
X CONFIG_FB_SGIVW
X   SGI Visual Workstation support for framebuffer graphics.
X 
+I2O support
+CONFIG_I2O
+  The Intelligent Input/Output (I2O) architecture allows
+  hardware drivers to be split into two parts: an operating system
+  specific module called the OSM and an hardware specific module
+  called the HDM. The OSM can talk to a whole range of HDM's, and
+  ideally the HDM's are not OS dependent. This allows for the same
+  driver to be used under different operating systems if the relevant
+  OSM is in place. If you say Y here, you will get a choice of OSM's
+  with the following questions.
+
+  This support is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.
+
+  If unsure, say N.
+
+I2O PCI support
+CONFIG_I2O_PCI
+  Build in support for PCI bus I2O interface adapters. Currently this
+  is the only variety supported.
+
+I2O Block OSM
+CONFIG_I2O_BLOCK
+  Include support for the I2O Block OSM. The Block OSM presents disk and
+  other structured block devices to the operating system.
+
+I2O LAN OSM
+CONFIG_I2O_LAN
+  Include support for the LAN OSM. You will also need to include support
+  for token ring or fddi if you wish to use token ring or FDDI I2O cards
+  with this driver.
+
+I2O SCSI OSM
+CONFIG_I2O_SCSI
+  Allow direct scsi access to scsi devices on a SCSI or FibreChannel I2O 
+  controller. You can use both the SCSI and Block OSM together if you wish.
+
X System V IPC
X CONFIG_SYSVIPC
X   Inter Process Communication is a suite of library functions and
@@ -1977,6 +2079,11 @@
X   You will get a boot time penguin logo at no additional cost. Please
X   read Documentation/fb/vesafb.txt. If unsure, say Y.
X 
+VGA 16-color graphics console
+CONFIG_FB_VGA16
+  This is the frame buffer device driver for VGA 16 color graphic
+  cards. Say Y if you have such a card.
+
X Backward compatibility mode for Xpmac
X CONFIG_FB_COMPAT_XPMAC
X   If you use the Xpmac X server (common with mklinux), you'll need to
@@ -2218,12 +2325,12 @@
X   whenever you want), say M here and read Documentation/modules.txt.
X   The module will be called parport.o. If you have more than one
X   parallel port and want to specify which port and IRQ to be used by
-  this driver at module load time, read
-  Documentation/networking/net-modules.txt.
+  this driver at module load time, take a look at
+  Documentation/networking/parport.txt.
X 
X   If unsure, say Y.
X 
-PC-style hardware 
+PC-style hardware
X CONFIG_PARPORT_PC
X   You should say Y here if you have a PC-style parallel port. All IBM
X   PC compatible computers and some Alphas have PC-style parallel
@@ -2236,28 +2343,36 @@
X   
X   If unsure, say Y.
X 
+Use FIFO/DMA if available
+CONFIG_PARPORT_PC_FIFO
+  Many parallel port chipsets provide hardware that can speed up
+  printing. Say Y here if you want to take advantage of that.
+
+  As well as actually having a FIFO, or DMA capability, the kernel
+  will need to know which IRQ the parallel port has. By default,
+  parallel port interrupts will not be used, and so neither will the
+  FIFO. See Documentation/parport.txt to find out how to specify
+  which IRQ/DMA to use.
+
X Support foreign hardware
X CONFIG_PARPORT_OTHER
X   Say Y here if you want to be able to load driver modules to support
X   other non-standard types of parallel ports. This causes a
X   performance loss, so most people say N.
X 
-Sun Ultra/AX-style hardware 
+Sun Ultra/AX-style hardware
X CONFIG_PARPORT_AX
X   Say Y here if you need support for the parallel port hardware on Sun
X   Ultra/AX machines. This code is also available as a module (say M),
X   called parport_ax.o. If in doubt, saying N is the safe plan.
X 
-Plug and Play support
-CONFIG_PNP
-  Plug and Play support allows the kernel to automatically configure
-  some peripheral devices. Say Y to enable PnP.
-
-Auto-probe for parallel devices
-CONFIG_PNP_PARPORT
-  Some IEEE-1284 conforming parallel-port devices can identify
-  themselves when requested. Say Y to enable this feature, or M to
-  compile it as a module (parport_probe.o). If in doubt, say N.
+IEEE1284 transfer modes
+CONFIG_PARPORT_1284
+  If you have a printer that supports status readback or device ID, or
+  want to use a device that uses enhanced parallel port transfer modes
+  such as EPP and ECP, say Y here to enable advanced IEEE 1284
+  transfer modes. Also say Y if you want device ID information to
+  appear in /proc/sys/dev/parport/*/autoprobe*. It is safe to say N.
X 
X Enable loadable module support
X CONFIG_MODULES
@@ -5160,6 +5275,17 @@
X   module, say M here and read Documentation/modules.txt as well as
X   Documentation/networking/net-modules.txt.
X 
+Aironet Arlan 655 & IC2200 DS support
+CONFIG_ARLAN
+  Aironet makes Arlan. www.aironet.com. Uses www.Telxon.com chip, which is
+  used on several similar cards. Driver is tested on 655 and IC2200 series. 
+  Look for http://www.ylenurme.ee/~elmer/655/ for latest information. 
+  Driver is build as two modules, arlan and arlan-proc. The later is /proc
+  interface and not needed most of time.
+  On some computers the card ends up in non-valid state after some time.
+  Use a ping-reset script to clear it.
+   
+
X LAPB over Ethernet driver
X CONFIG_LAPBETHER
X   This is a driver for a pseudo device (typically called /dev/lapb0)
@@ -5286,6 +5412,15 @@
X   module, say M here and read Documentation/modules.txt. If you don't
X   know what to use this for, you don't need it.
X 
+Sealevel Systems 4021 support
+CONFIG_SEALEVEL_4021
+  This is a driver for the Sealevel Systems ACB 56 serial I/O adapter.
+  
+  This driver can only be compiled as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to do that, say M here. The module will be called
+  sealevel.o.
+
X Frame Relay (DLCI) support
X CONFIG_DLCI
X   This is support for the frame relay protocol; frame relay is a fast
@@ -5692,6 +5827,40 @@
X   you say N, the PPP support will not be included in the driver (saves
X   about 16 KB of kernel memory).
X 
+Cyclom 2X(tm) multiprotocol cards
+CONFIG_CYCLADES_SYNC
+  Cyclom 2X from Cyclades Corporation (http://www.cyclades.com and
+  http://www.cyclades.com.br; to browse the WWW, you need to have
+  access to a machine on the Internet that has a program like lynx or
+  netscape) is an intelligent multiprotocol WAN adapter with data
+  transfer rates up to 512 Kbps). These cards support the X.25 and SNA
+  related protocols. If you have one or more of these cards, say Y to
+  this option. The next questions will ask you about the protocols you
+  want the driver to support (for now only X.25 is supported).
+
+  While no documentation is available at this time please grab the
+  wanconfig tarball in http://www.conectiva.com.br/~acme/cycsyn-devel
+  (with minor changes to make it compile with the current wanrouter
+  include files; efforts are being made to use the original package
+  available at ftp://ftp.sangoma.com).
+
+  Feel free to contact me or the cycsyn-devel mailing list at
+  ac...@conectiva.com.br and cycsyn...@bazar.conectiva.com.br for
+  aditional details, I hope to have documentation available as soon
+  as possible.
+
+  The driver will be compiled as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called cyclomx.o. For general information about
+  modules read Documentation/modules.txt.
+
+Cyclom 2X X.25 support
+CONFIG_CYCLOMX_X25
+  Say Y to this option if you are planning to connect a Cyclom 2X card
+  to an X.25 network. 
+  If you say N, the X.25 support will not be included in the driver
+  (saves about 11 KB of kernel memory).
+
X Ethernet (10 or 100Mbit)
X CONFIG_NET_ETHERNET
X   Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
@@ -5905,7 +6074,7 @@
X   say M here and read Documentation/modules.txt. This is recommended.
X   The module will be called yellowfin.o.
X 
-Alteon AceNIC / 3Com 3C985 Gigabit Ethernet support.
+Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support
X CONFIG_ACENIC
X   Say Y here if you have an Alteon AceNIC or 3Com 3C985 PCI Gigabit
X   Ethernet adapter. The driver allows for using the Jumbo Frame
@@ -6663,6 +6832,25 @@
X   The module will be called ibmtr.o. If you want to compile it as a
X   module, say M here and read Documentation/modules.txt.
X 
+IBM Olympic chipset PCI adapter support
+CONFIG_IBMOL
+  This is support for all non-Lanstreamer IBM PCI Token Ring Cards. 
+  Specifically this is all IBM PCI, PCI Wake On Lan, PCI II, PCI II
+  Wake On Lan, and PCI 100/16/4 adapters.
+
+  If you have such an adapter, say Y and read the Token-Ring mini-HOWTO,
+  available via FTP (user:anonymous) from
+  ftp://metalab.unc/edu/pub/Linux/docs/HOWTO.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will will be called olympic.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
+
+  Also read the linux/Documentation/networking/olympic.txt or check the 
+  Linux Token Ring Project site for the latest information at
+  http://www.linuxtr.net
+
X SysKonnect adapter support
X CONFIG_SKTR
X   This is support for all SysKonnect Token Ring cards, specifically
@@ -8316,6 +8504,16 @@
X 
X   If you haven't heard about it, it's safe to say N.
X 
+Cyclades-Z interrupt mode operation (EXPERIMENTAL)
+CONFIG_CYZ_INTR
+  The Cyclades-Z family of multiport cards allows 2 (two) driver
+  op modes: polling and interrupt. In polling mode, the driver will
+  check the status of the Cyclades-Z ports every certain amount of
+  time (which is called polling cycle and is configurable). In
+  interrupt mode, it will use an interrupt line (IRQ) in order to check
+  the status of the Cyclades-Z ports. The default op mode is polling.
+  If unsure, say N.
+
X Stallion multiport serial support 
X CONFIG_STALDRV
X   Stallion cards give you many serial ports. You would need something
@@ -8440,7 +8638,8 @@
X   corresponding drivers into the kernel. If you want to compile this
X   driver as a module however ( = code which can be inserted in and
X   removed from the running kernel whenever you want), say M here and
-  read Documentation/modules.txt. The module will be called lp.o. 
+  read Documentation/modules.txt and Documentation/parport.txt. The
+  module will be called lp.o. 
X 
X   If you have several parallel ports, you can specify which ports to
X   use with the "lp" kernel command line option. (Try "man bootparam"
@@ -8454,11 +8653,18 @@
X   If you have more than 3 printers, you need to increase the LP_NO
X   variable in lp.c.
X 
-Support IEEE1284 status readback
-CONFIG_PRINTER_READBACK
-  If your printer conforms to IEEE 1284, it may be able to provide a
-  status indication when you read from it (for example, with `cat
-  /dev/lp1'). To use this feature, say Y here.
+Support for console on line printer
+CONFIG_LP_CONSOLE
+  If you want kernel messages to be printed out as they occur, you
+  can have a console on the printer. This option adds support for
+  doing that; to actually get it to happen you need to pass the
+  option "console=lp" to the kernel at boot time.
+
+  Note that kernel messages can get lost if the printer is out of
+  paper (or off, or unplugged, or too busy..), but this behaviour
+  can be changed. See drivers/char/lp.c (do this at your own risk).
+
+  If unsure, say N.
X 
X Mouse Support (not serial mice)
X CONFIG_MOUSE
@@ -9397,7 +9603,7 @@
X   after the PnP configuration is finished. To do this, say M here and
X   read Documentation/modules.txt as well as
X   Documentation/sound/README.modules; the module will be called
-  sound.o.
+  soundcore.o.
X 
X   I'm told that even without a sound card, you can make your computer
X   say more than an occasional beep, by programming the PC speaker.
@@ -10943,6 +11149,11 @@
X   Choose Y here if you have this FM radio card, and then fill in the 
X   port address below.
X 
+  If you have GemTeks combined (PnP) sound- and radio card you must use
+  this driver as a module and setup the card with isapnptools. You must
+  also pass the module a suitable io parameter, 0x248 has been reported
+  to be used by these cards.
+
X   In order to control your radio card, you will need to use programs
X   that are compatible with the Video for Linux API. Information on 
X   this API and pointers to "v4l" programs may be found on the WWW at
@@ -11119,6 +11330,40 @@
X   Enter either 0x20c, 0x30c, 0x24c or 0x34c here. The card default is
X   0x34c, if you haven't changed the jumper setting on the card.
X 
+PlanB Video-In for PowerMacs
+CONFIG_VIDEO_PLANB
+  PlanB is the V4L driver for the PowerMac 7x00/8x00 series video
+  input hardware. If you want to experiment with this, say Y.
+  Otherwise, or if you don't understand a word, say N.
+  See http://www.cpu.lu/~mlan/planb.html for more info.
+
+  Saying M will compile this driver as a module (planb.o).
+
+TerraTec ActiveRadio
+CONFIG_RADIO_TERRATEC
+  Choose Y here if you have this FM radio card, and then fill in the
+  port address below. (TODO)
+
+  Note: This driver is in its early stages. Right now volume and frequency
+  control and muting works at least for me, but unfortunately i have not
+  found anybody who wants to use this card with linux. So if it is this
+  what YOU are trying to do right now, PLEASE DROP ME A NOTE!!
+  Rolf Offermanns (ro...@offermanns.de)
+  
+  In order to control your radio card, you will need to use programs
+  that are compatible with the Video for Linux API. Information on
+  this API and pointers to "v4l" programs may be found on the WWW at
+  http://roadrunner.swansea.uk.linux.org/v4l.shtml; to browse the WWW,
+  you need to have access to a machine on the Internet that has a
+  program like lynx or netscape.
+
+
+  If you want to compile this driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt. The module will be
+  called radio-terratec.o.
+  
+
X BT848 Video For Linux
X CONFIG_VIDEO_BT848
X   Support for BT848 based frame grabber/overlay boards. This includes
@@ -11165,6 +11410,14 @@
X   from the running kernel whenever you want). If you want to compile
X   it as a module, say M here and read Documentation/modules.txt.
X 
+Compaq SMART2 support
+CONFIG_BLK_CPQ_DA
+   This is the driver for Compaq Smart Array controllers.  
+   Everyone using these boards should say Y here.  
+   See "linux/Documentation/cpqarray.txt" for the current list of 
+   boards supported by this driver, and for further information 
+   on the use of this driver. 
+ 
X #
X # ARM options
X #
@@ -11463,6 +11716,21 @@
X 
X   If unsure, say Y.
X 
+IrPORT IrDA Device Driver
+CONFIG_IRPORT_SIR
+  Say Y here if you want to build support for the IrPORT IrDA device
+  driver. If you want to compile it as a module, say M here and
+  read Documentation/modules.txt. IrPORT can be used instead of
+  IrTTY and sometimes this can be better. One example is if your
+  IrDA port does not have echo-canceling, which will work OK with
+  IrPORT since this driver is working in half-duplex mode only. You
+  don't need to use irattach with IrPORT, but you just insert it 
+  the same way as FIR drivers (insmod irport io=0x3e8 irq=11).
+  Notice that IrPORT is a SIR device driver which means that speed
+  is limited to 115200 bps.
+
+  If unsure, say Y.
+
X Winbond W83977AF IrDA Device Driver
X CONFIG_WINBOND_FIR
X   Say Y here if you want to build IrDA support for the Winbond
@@ -11486,6 +11754,13 @@
X   read Documentation/modules.txt. This chipset is used by the Toshiba
X   Tecra laptops.
X 
+Toshiba Type-O IR Port Device Driver
+CONFIG_TOSHIBA_FIR
+  Say Y here if you want to build support for the Toshiba Type-O IR
+  chipset. If you want to compile it as a module, say M here and
+  read Documentation/modules.txt. This chipset is used by the Toshiba
+  Libretto 100CT, and many more laptops.
+
X ESI JetEye PC Dongle
X CONFIG_ESI_DONGLE
X   Say Y here if you want to build support for the Extended Systems
@@ -11523,6 +11798,15 @@
X   by IrTTY. To activate support for Greenwich dongles you will have to
X   insert "irattach -d girbil" in the /etc/irda/drivers script.
X 
+Parallax Litelink dongle
+CONFIG_LITELINK_DONGLE
+  Say Y here if you want to build support for the Parallax Litelink
+  dongle. If you want to compile it as a module, say M here and read
+  Documentation/modules.txt. The Parallax dongle attaches to the
+  normal 9-pin serial port connector, and can currently only be used
+  by IrTTY. To activate support for Parallax dongles you will have to
+  insert "irattach -d litelink" in the /etc/irda/drivers script.
+
X VME (Motorola and BVM) support
X CONFIG_VME
X   Say Y here if you want to build a kernel for a 680x0 based VME
@@ -11658,6 +11942,16 @@
X CONFIG_USB_ACM
X   This driver allows for devices which support the Abstract Control Model,
X   including many USB-based modems, ISDN adapters, and network adapters.
+
+Support for user-space parallel port device drivers
+CONFIG_PPDEV
+  Saying Y to this adds support for /dev/parport device nodes.
+  NB. You have to make them before you can use them:
+    mknod /dev/parport00 c 99 0
+    mknod /dev/parport01 c 99 1
+    mknod /dev/parport10 c 99 16
+    mknod /dev/parport11 c 99 17
+    etc..
X 
X #
X # A couple of things I keep forgetting:
diff -u --recursive --new-file v2.3.9/linux/Documentation/SMP.txt linux/Documentation/SMP.txt
--- v2.3.9/linux/Documentation/SMP.txt	Wed Jun 24 14:30:07 1998
+++ linux/Documentation/SMP.txt	Thu Jul  1 10:45:57 1999
@@ -1,7 +1,7 @@
X SMP on x86/Linux is now an official feature and is not experimental.
X Experimental SMP support for other architectures is underway.
X 
-Please view linux/Documentation/smp for more information about enabling SMP.
+Please view linux/Documentation/smp.txt for more information about enabling SMP.
X 
X SMP support for Linux with up to 16 processors using the Intel MP
X specification. 
diff -u --recursive --new-file v2.3.9/linux/Documentation/cpqarray.txt linux/Documentation/cpqarray.txt
--- v2.3.9/linux/Documentation/cpqarray.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/cpqarray.txt	Mon Jul  5 19:52:13 1999
@@ -0,0 +1,107 @@
+This driver is for Compaq's SMART2 Intellegent Disk Array Controllers.
+
+WARNING:
+--------
+
+This driver comes with NO WARRANTY.  It is not officially supported by
+Compaq.  Do not call technical support.  Use at your own risk.
+
+Supported Cards:
+----------------
+
+This driver is known to work with the following cards:
+
+	* SMART (EISA)
+	* SMART-2/E (EISA)
+	* SMART-2/P
+	* SMART-2DH
+	* SMART-2SL
+	* SMART-221
+	* SMART-3100ES
+	* SMART-3200
+	* Integrated Smart Array Controller
+	* SA 4200
+	* SA 4250ES
+
+It should also work with some really old Disk array adapters, but I am
+unable to test against these cards:
+
+	* IDA
+	* IDA-2
+	* IAES
+
+Installing:
+-----------
+
+You need to build a new kernel to use this device, even if you want to
+use a loadable module.  
+
+Apply the patch to a 2.2.x kernel:
+
+# cd linux
+# patch -p1 <smart2.patch
+
+Then build a new kernel and turn on Compaq SMART2 Disk Array support.
+Create device nodes for the diskarray device:
+
+# mkdev.ida [ctlrs]
+
+Where ctlrs is the number of controllers you have (defaults to 1 if not
+specified).
+
+EISA Controllers:
+-----------------
+
+If you want to use an EISA controller you'll have to supply some
+insmod/lilo paramaters.  If the driver is compiled into the kernel, must
+give it the controller's IO port address at boot time (it is no longer
+necessary to specifiy the IRQ).  For example, if you had two SMART-2/E
+controllers, in EISA slots 1 and 2 you'd give it a boot argument like
+this:
+
+	smart2=0x1000,0x2000
+
+If you were loading the driver as a module, you'd give load it like this:
+
+	insmod cpqarray.o eisa=0x1000,0x2000
+
+You can use EISA and PCI adapters at the same time.
+
+Booting:
+--------
+
+You'll need to use a modified lilo if you want to boot from a disk array.
+Its simply a version of lilo with some code added to tell it how to
+understand Compaq diskarray devices.
+
+Device Naming:
+--------------
+
+You need some entries in /dev for the ida device.  The mkdev.ida script
+can make device nodes for you automatically.  Currently the device setup
+is as follows:
+
+Major numbers:
+	72	ida0
+	73	ida1
+	74	ida2
+	etc...
+
+Minor numbers:
+        b7 b6 b5 b4 b3 b2 b1 b0
+        |----+----| |----+----|
+             |           |
+             |           +-------- Partition ID (0=wholedev, 1-15 partition)
+             |
+             +-------------------- Logical Volume number
+
+The suggested device naming scheme is:
+/dev/ida/c0d0		Controller 0, disk 0, whole device
+/dev/ida/c0d0p1		Controller 0, disk 0, partition 1
+/dev/ida/c0d0p2		Controller 0, disk 0, partition 2
+/dev/ida/c0d0p3		Controller 0, disk 0, partition 3
+
+/dev/ida/c1d1		Controller 1, disk 1, whole device
+/dev/ida/c1d1p1		Controller 1, disk 1, partition 1
+/dev/ida/c1d1p2		Controller 1, disk 1, partition 2
+/dev/ida/c1d1p3		Controller 1, disk 1, partition 3
diff -u --recursive --new-file v2.3.9/linux/Documentation/fb/tgafb.txt linux/Documentation/fb/tgafb.txt
--- v2.3.9/linux/Documentation/fb/tgafb.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/fb/tgafb.txt	Thu Jul  1 10:57:36 1999
@@ -0,0 +1,51 @@
+[Also cloned from vesafb.txt, thanks to Gerd]
+
+What is tgafb?
+===============
+
+This is a driver for DECChip 21030 based graphics framebuffers, a.k.a. TGA
+cards, specifically the following models
+
+ZLxP-E1 (8bpp, 4 MB VRAM)
+ZLxP-E2 (32bpp, 8 MB VRAM)
+ZLxP-E3 (32bpp, 16 MB VRAM, Zbuffer)
+
+This version, tgafb-1.12, is almost a complete rewrite of the code written
+by Geert Uytterhoeven, which was based on the original TGA console code
+written by Jay Estabrook.
+
+Major new features:
+
+ * Support for multiple resolutions, including setting the resolution at
+   boot time, allowing the use of a fixed-frequency monitor.
+ * Complete code rewrite to follow Geert's skeletonfb spec which will allow
+   future implementation of hardware acceleration and other features.
+
+
+Configuration
+=============
+
+You can pass kernel command line options to tgafb with
+`video=tga:option1,option2:value2,option3' (multiple options should be
+separated by comma, values are separated from options by `:').
+Accepted options:
+
+font:X    - default font to use. All fonts are supported, including the
+            SUN12x22 font which is very nice at high resolutions.
+mode:X    - default video mode. See drivers/video/tgafb.c for a list.
+            
+X11
+===
+
+XF68_FBDev should work just fine, but I haven't tested it.  Running
+the XF86_TGA server (reasonably recent versions of which support all TGA
+cards) works fine for me.
+
+One minor problem with XF86_TGA is when running tgafb in resolutions higher
+than 640x480, on switching VCs from tgafb to X, the entire screen is not
+re-drawn and must be manually refreshed. This is an X server problem, not a
+tgafb problem.
+
+Enjoy!
+
+Martin Lucina <ma...@kotelna.sk>
diff -u --recursive --new-file v2.3.9/linux/Documentation/java.txt linux/Documentation/java.txt
--- v2.3.9/linux/Documentation/java.txt	Tue Apr 28 14:22:04 1998
+++ linux/Documentation/java.txt	Thu Jul  1 10:47:08 1999
@@ -21,7 +21,7 @@
X 2) You have to compile BINFMT_MISC either as a module or into
X    the kernel (CONFIG_BINFMT_MISC) and set it up properly.
X    If you choose to compile it as a module, you will have
-   to insert it manually with modprobe/insmod, as kerneld
+   to insert it manually with modprobe/insmod, as kmod
X    can not easy be supported with binfmt_misc. 
X    Read the file 'binfmt_misc.txt' in this directory to know
X    more about the configuration process.
@@ -29,14 +29,15 @@
X 3) Add the following configuration items to binfmt_misc
X    (you should really have read binfmt_misc.txt now):
X    support for Java applications:
-     ':Java:M::\xca\xfe\xba\xbe::/usr/local/java/bin/javawrapper:'
+     ':Java:M::\xca\xfe\xba\xbe::/usr/local/bin/javawrapper:'
X    support for Java Applets:
-     ':Applet:E::html::/usr/local/java/bin/appletviewer:'
+     ':Applet:E::html::/usr/bin/appletviewer:'
X    or the following, if you want to be more selective:
-     ':Applet:M::<!--applet::/usr/local/java/bin/appletviewer:'
+     ':Applet:M::<!--applet::/usr/bin/appletviewer:'
X 
-   Of cause you have to fix the path names, if you installed the JDK
-   at another place than /usr/local/java.
+   Of cause you have to fix the path names. Given path/file names in this
+   document match the Debian 2.1 system. (i.e. jdk installed in /usr,
+   custom wrappers from this document in /usr/local)
X 
X    Note, that for the more selective applet support you have to modify
X    existing html-files to contain <!--applet--> in the first line
@@ -45,42 +46,300 @@
X    For the compiled Java programs you need a wrapper script like the
X    following (this is because Java is broken in case of the filename
X    handling), again fix the path names, both in the script and in the
-   above given configuration string:
+   above given configuration string.
+
+   You, too, need the little program after the script. Compile like
+   gcc -O2 -o javaclassname javaclassname.c
+   and stick it to /usr/local/bin.
+
+   Both the javawrapper shellscript and the javaclassname program
+   were supplied by Colin J. Watson <cj...@cam.ac.uk>.
X 
X ====================== Cut here ===================
X #!/bin/bash
-# /usr/local/java/bin/javawrapper - the wrapper for binfmt_misc/java
-CLASS=$1
+# /usr/local/bin/javawrapper - the wrapper for binfmt_misc/java
X 
-# if classname is a link, we follow it (this could be done easier - how?)
-if [ -L "$1" ] ; then
-        CLASS=`ls --color=no -l $1 | tr -s '\t ' '  ' | cut -d ' ' -f 11`
+if [ -z "$1" ]; then
+	exec 1>&2
+	echo Usage: $0 class-file
+	exit 1
X fi
-CLASSN=`basename $CLASS .class`
-CLASSP=`dirname $CLASS`
X 
-FOO=$PATH
-PATH=$CLASSPATH
-if [ -z "`type -p -a $CLASSN.class`" ] ; then
-        # class is not in CLASSPATH
-        if [ -e "$CLASSP/$CLASSN.class" ] ; then
-                # append dir of class to CLASSPATH
-                if [ -z "${CLASSPATH}" ] ; then
-                        export CLASSPATH=$CLASSP
-                else
-                        export CLASSPATH=$CLASSP:$CLASSPATH
-                fi
-        else
-                # uh! now we would have to create a symbolic link - really
-                # ugly, i.e. print a message that one has to change the setup
-                echo "Hey! This is not a good setup to run $1 !"
-                exit 1
-        fi
+CLASS=$1
+FQCLASS=`/usr/local/bin/javaclassname $1`
+FQCLASSN=`echo $FQCLASS | sed -e 's/^.*\.\([^.]*\)$/\1/'`
+FQCLASSP=`echo $FQCLASS | sed -e 's-\.-/-g' -e 's-^[^/]*$--' -e 's-/[^/]*$--'`
+
+# for example:
+# CLASS=Test.class
+# FQCLASS=foo.bar.Test
+# FQCLASSN=Test
+# FQCLASSP=foo/bar
+
+unset CLASSBASE
+
+declare -i LINKLEVEL=0
+
+while :; do
+	if [ "`basename $CLASS .class`" == "$FQCLASSN" ]; then
+		# See if this directory works straight off
+		cd -L `dirname $CLASS`
+		CLASSDIR=$PWD
+		cd $OLDPWD
+		if echo $CLASSDIR | grep -q "$FQCLASSP$"; then
+			CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."`
+			break;
+		fi
+		# Try dereferencing the directory name
+		cd -P `dirname $CLASS`
+		CLASSDIR=$PWD
+		cd $OLDPWD
+		if echo $CLASSDIR | grep -q "$FQCLASSP$"; then
+			CLASSBASE=`echo $CLASSDIR | sed -e "s.$FQCLASSP$.."`
+			break;
+		fi
+		# If no other possible filename exists
+		if [ ! -L $CLASS ]; then
+			exec 1>&2
+			echo $0:
+			echo "  $CLASS should be in a" \
+			     "directory tree called $FQCLASSP"
+			exit 1
+		fi
+	fi
+	if [ ! -L $CLASS ]; then break; fi
+	# Go down one more level of symbolic links
+	let LINKLEVEL+=1
+	if [ $LINKLEVEL -gt 5 ]; then
+		exec 1>&2
+		echo $0:
+		echo "  Too many symbolic links encountered"
+		exit 1
+	fi
+	CLASS=`ls --color=no -l $CLASS | sed -e 's/^.* \([^ ]*\)$/\1/'`
+done
+
+if [ -z "$CLASSBASE" ]; then
+	if [ -z "$FQCLASSP" ]; then
+		GOODNAME=$FQCLASSN.class
+	else
+		GOODNAME=$FQCLASSP/$FQCLASSN.class
+	fi
+	exec 1>&2
+	echo $0:
+	echo "  $FQCLASS should be in a file called $GOODNAME"
+	exit 1
+fi
+
+if ! echo $CLASSPATH | grep -q "^\(.*:\)*$CLASSBASE\(:.*\)*"; then
+	# class is not in CLASSPATH, so prepend dir of class to CLASSPATH
+	if [ -z "${CLASSPATH}" ] ; then
+		export CLASSPATH=$CLASSBASE
+	else
+		export CLASSPATH=$CLASSBASE:$CLASSPATH
+	fi
X fi
-PATH=$FOO
X 
X shift
-/usr/local/java/bin/java $CLASSN "$@"
+/usr/bin/java $FQCLASS "$@"
+====================== Cut here ===================
+
+
+====================== Cut here ===================
+/* javaclassname.c
+ *
+ * Extracts the class name from a Java class file; intended for use in a Java
+ * wrapper of the type supported by the binfmt_misc option in the Linux kernel.
+ *
+ * Copyright (C) 1999 Colin J. Watson <cj...@cam.ac.uk>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <sys/types.h>
+
+/* From Sun's Java VM Specification, as tag entries in the constant pool. */
+
+#define CP_UTF8 1
+#define CP_INTEGER 3
+#define CP_FLOAT 4
+#define CP_LONG 5
+#define CP_DOUBLE 6
+#define CP_CLASS 7
+#define CP_STRING 8
+#define CP_FIELDREF 9
+#define CP_METHODREF 10
+#define CP_INTERFACEMETHODREF 11
+#define CP_NAMEANDTYPE 12
+
+/* Define some commonly used error messages */
+
+#define seek_error() error("%s: Cannot seek\n", program)
+#define corrupt_error() error("%s: Class file corrupt\n", program)
+#define eof_error() error("%s: Unexpected end of file\n", program)
+#define utf8_error() error("%s: Only ASCII 1-255 supported\n", program);
+
+char *program;
+
+long *pool;
+
+u_int8_t read_8(FILE *classfile);
+u_int16_t read_16(FILE *classfile);
+void skip_constant(FILE *classfile, u_int16_t *cur);
+void error(const char *format, ...);
+int main(int argc, char **argv);
+
+/* Reads in an unsigned 8-bit integer. */
+u_int8_t read_8(FILE *classfile)
+{
+	int b = fgetc(classfile);
+	if(b == EOF)
+		eof_error();
+	return (u_int8_t)b;
+}
+
+/* Reads in an unsigned 16-bit integer. */
+u_int16_t read_16(FILE *classfile)
+{
+	int b1, b2;
+	b1 = fgetc(classfile);
+	if(b1 == EOF)
+		eof_error();
+	b2 = fgetc(classfile);
+	if(b2 == EOF)
+		eof_error();
+	return (u_int16_t)((b1 << 8) | b2);
+}
+
+/* Reads in a value from the constant pool. */
+void skip_constant(FILE *classfile, u_int16_t *cur)
+{
+	u_int16_t len;
+	int seekerr = 1;
+	pool[*cur] = ftell(classfile);
+	switch(read_8(classfile))
+	{
+	case CP_UTF8:
+		len = read_16(classfile);
+		seekerr = fseek(classfile, len, SEEK_CUR);
+		break;
+	case CP_CLASS:
+	case CP_STRING:
+		seekerr = fseek(classfile, 2, SEEK_CUR);
+		break;
+	case CP_INTEGER:
+	case CP_FLOAT:
+	case CP_FIELDREF:
+	case CP_METHODREF:
+	case CP_INTERFACEMETHODREF:
+	case CP_NAMEANDTYPE:
+		seekerr = fseek(classfile, 4, SEEK_CUR);
+		break;
+	case CP_LONG:
+	case CP_DOUBLE:
+		seekerr = fseek(classfile, 8, SEEK_CUR);
+		++(*cur);
+		break;
+	default:
+		corrupt_error();
+	}
+	if(seekerr)
+		seek_error();
+}
+
+void error(const char *format, ...)
+{
+	va_list ap;
+	va_start(ap, format);
+	vfprintf(stderr, format, ap);
+	va_end(ap);
+	exit(1);
+}
+
+int main(int argc, char **argv)
+{
+	FILE *classfile;
+	u_int16_t cp_count, i, this_class, classinfo_ptr;
+	u_int8_t length;
+
+	program = argv[0];
+
+	if(!argv[1])
+		error("%s: Missing input file\n", program);
+	classfile = fopen(argv[1], "rb");
+	if(!classfile)
+		error("%s: Error opening %s\n", program, argv[1]);
+
+	if(fseek(classfile, 8, SEEK_SET))  /* skip magic and version numbers */
+		seek_error();
+	cp_count = read_16(classfile);
+	pool = calloc(cp_count, sizeof(long));
+	if(!pool)
+		error("%s: Out of memory for constant pool\n", program);
+
+	for(i = 1; i < cp_count; ++i)
+		skip_constant(classfile, &i);
+	if(fseek(classfile, 2, SEEK_CUR))	/* skip access flags */
+		seek_error();
+
+	this_class = read_16(classfile);
+	if(this_class < 1 || this_class >= cp_count)
+		corrupt_error();
+	if(!pool[this_class] || pool[this_class] == -1)
+		corrupt_error();
+	if(fseek(classfile, pool[this_class] + 1, SEEK_SET))
+		seek_error();
+
+	classinfo_ptr = read_16(classfile);
+	if(classinfo_ptr < 1 || classinfo_ptr >= cp_count)
+		corrupt_error();
+	if(!pool[classinfo_ptr] || pool[classinfo_ptr] == -1)
+		corrupt_error();
+	if(fseek(classfile, pool[classinfo_ptr] + 1, SEEK_SET))
+		seek_error();
+
+	length = read_16(classfile);
+	for(i = 0; i < length; ++i)
+	{
+		u_int8_t x = read_8(classfile);
+		if((x & 0x80) || !x)
+		{
+			if((x & 0xE0) == 0xC0)
+			{
+				u_int8_t y = read_8(classfile);
+				if((y & 0xC0) == 0x80)
+				{
+					int c = ((x & 0x1f) << 6) + (y & 0x3f);
+					if(c) putchar(c);
+					else utf8_error();
+				}
+				else utf8_error();
+			}
+			else utf8_error();
+		}
+		else if(x == '/') putchar('.');
+		else putchar(x);
+	}
+	putchar('\n');
+	free(pool);
+	fclose(classfile);
+	return 0;
+}
X ====================== Cut here ===================
X 
X 
@@ -116,4 +375,6 @@
X 
X 
X originally by Brian A. Lantz, br...@lantz.com
-heavily edited for binfmt_misc by Richard Günther.
+heavily edited for binfmt_misc by Richard Günther
+new scripts by Colin J. Watson <cj...@cam.ac.uk>.
+
diff -u --recursive --new-file v2.3.9/linux/Documentation/kernel-parameters.txt linux/Documentation/kernel-parameters.txt
--- v2.3.9/linux/Documentation/kernel-parameters.txt	Wed Jun  2 11:32:45 1999
+++ linux/Documentation/kernel-parameters.txt	Mon Jul  5 19:52:52 1999
@@ -37,7 +37,7 @@
X     SOUND	Appropriate sound system support is enabled.
X     VGA 	The VGA console has been enabled.
X     VT		Virtual terminal support is enabled.
-    XT		IBM PC/XT support is enabled.
+    XT		IBM PC/XT MFM hard disk support is enabled.
X 
X In addition, the following text indicates that the option:
X 
diff -u --recursive --new-file v2.3.9/linux/Documentation/networking/arcnet-hardware.txt linux/Documentation/networking/arcnet-hardware.txt
--- v2.3.9/linux/Documentation/networking/arcnet-hardware.txt	Thu Jan  7 08:41:55 1999
+++ linux/Documentation/networking/arcnet-hardware.txt	Mon Jul  5 19:52:52 1999
@@ -20,14 +20,14 @@
X ARCnet is a network type which works in a way similar to popular Ethernet
X networks but which is also different in some very important ways.
X 
-First of all, you can get ARCnet cards in at least two speeds: 2.5Mbps
-(slower than Ethernet) and 100Mbps (faster than normal Ethernet).  In fact,
+First of all, you can get ARCnet cards in at least two speeds: 2.5 Mbps
+(slower than Ethernet) and 100 Mbps (faster than normal Ethernet).  In fact,
X there are others as well, but these are less common.  The different hardware
X types, as far as I'm aware, are not compatible and so you cannot wire a
-100Mbps card to a 2.5Mbps card, and so on.  From what I hear, my driver does
-work with 100Mbps cards, but I haven't been able to verify this myself,
-since I only have the 2.5Mbps variety.  It is probably not going to saturate
-your 100Mbps card.  Stop complaining :)
+100 Mbps card to a 2.5 Mbps card, and so on.  From what I hear, my driver does
+work with 100 Mbps cards, but I haven't been able to verify this myself,
+since I only have the 2.5 Mbps variety.  It is probably not going to saturate
+your 100 Mbps card.  Stop complaining. :)
X 
X You also cannot connect an ARCnet card to any kind of Ethernet card and
X expect it to work.  
@@ -52,17 +52,17 @@
X useful for realtime networks.
X 
X In addition, all known ARCnet cards have an (almost) identical programming
-interface.  This means that with one "arcnet" driver you can support any
-card; whereas, with Ethernet, each manufacturer uses what is sometimes a
+interface.  This means that with one ARCnet driver you can support any
+card, whereas with Ethernet each manufacturer uses what is sometimes a
X completely different programming interface, leading to a lot of different,
X sometimes very similar, Ethernet drivers.  Of course, always using the same
X programming interface also means that when high-performance hardware
-facilities like PCI busmastering DMA appear, it's hard to take advantage of
+facilities like PCI bus mastering DMA appear, it's hard to take advantage of
X them.  Let's not go into that.
X 
X One thing that makes ARCnet cards difficult to program for, however, is the
X limit on their packet sizes; standard ARCnet can only send packets that are
-up to 508 bytes in length.  This is smaller than the internet "bare minimum"
+up to 508 bytes in length.  This is smaller than the Internet "bare minimum"
X of 576 bytes, let alone the Ethernet MTU of 1500.  To compensate, an extra
X level of encapsulation is defined by RFC1201, which I call "packet
X splitting," that allows "virtual packets" to grow as large as 64K each,
@@ -1005,9 +1005,9 @@
X     only (the JP0 jumper is hardwired), and BNC only.
X 	
X This is a LCS-8830-T made by SMC, I think ('SMC' only appears on one PLCC,
-nowhere else, not even on the few xeroxed sheets from the manual).
+nowhere else, not even on the few Xeroxed sheets from the manual).
X 
-SMC Arcnet Board Type LCS-8830-T
+SMC ARCnet Board Type LCS-8830-T
X 
X    ------------------------------------
X   |                                    |
@@ -1070,7 +1070,7 @@
X 
X DIP Switches 1-5 of SW2 encode the RAM and ROM Address Range:
X 
-Switches        Ram           Rom
+Switches        RAM           ROM
X 12345           Address Range  Address Range
X 00000		C:0000-C:07ff	C:2000-C:3fff
X 10000		C:0800-C:0fff
@@ -1170,11 +1170,11 @@
X DIP Switches:
X 
X 	The DIP switches accessible on the accessible end of the card while
-        it is installed, is used to set the arcnet address.  There are 8
+        it is installed, is used to set the ARCnet address.  There are 8
X         switches.  Use an address from 1 to 254.
X 
X 	Switch No.
-	12345678	Arcnet address
+	12345678	ARCnet address
X 	-----------------------------------------
X 	00000000	FF  	(Don't use this!)
X 	00000001	FE
@@ -1222,7 +1222,7 @@
X         from the upper memory regions, and then attempting to load ARCETHER
X         using these addresses.
X 
-	I recommend using an arcnet memory address of 0xD000, and putting
+	I recommend using an ARCnet memory address of 0xD000, and putting
X         the EMS page frame at 0xC000 while using QEMM stealth mode.  That
X         way, you get contiguous high memory from 0xD100 almost all the way
X         the end of the megabyte.
@@ -1687,7 +1687,7 @@
X                 |____________________________________________| |__|
X 
X 
-UM9065L : Arcnet Controller
+UM9065L : ARCnet Controller
X 
X SW 1    : Shared Memory Address and I/O Base
X 
@@ -1800,7 +1800,7 @@
X J1-J5       IRQ Select
X J6-J21      Unknown (Probably extra timeouts & ROM enable ...)
X LED1        Activity LED 
-BNC         Coax connector (STAR arcnet)
+BNC         Coax connector (STAR ARCnet)
X RAM         2k of SRAM
X ROM         Boot ROM socket
X UFS         Unidentified Flying Sockets
@@ -1905,7 +1905,7 @@
X ------------------------
X   - from Vojtech Pavlik <Vojtech...@st.mff.cuni.cz>
X 
-This is another SMC 90C65 based arcnet card. I couldn't identify the
+This is another SMC 90C65-based ARCnet card. I couldn't identify the
X manufacturer, but it might be DataPoint, because the card has the
X original arcNet logo in its upper right corner.
X 
@@ -1942,9 +1942,9 @@
X SW2 1-8:    Node ID Select
X SW3 1-5:    IRQ Select   
X     6-7:    Extra Timeout
-    8  :    Rom Enable   
+    8  :    ROM Enable   
X BNC         Coax connector
-XTAL        20MHz Crystal
+XTAL        20 MHz Crystal
X 
X 
X Setting the Node ID
@@ -2081,11 +2081,11 @@
X     6-8     Base I/O Address Select
X SW2 1-8     Node ID Select (ID0-ID7)
X J1          IRQ Select
-J2          Rom Enable
+J2          ROM Enable
X J3          Extra Timeout
X LED1        Activity LED 
-BNC         Coax connector (BUS arcnet)
-RJ          Twisted Pair Connector (daisychain)
+BNC         Coax connector (BUS ARCnet)
+RJ          Twisted Pair Connector (daisy chain)
X 
X 
X Setting the Node ID
@@ -2419,7 +2419,7 @@
X 
X Legend:
X 
-COM90C65:       Arcnet Probe
+COM90C65:       ARCnet Probe
X S1  1-8:    Node ID Select
X S2  1-3:    I/O Base Address Select
X     4-6:    Memory Base Address Select
@@ -2791,7 +2791,7 @@
X SW2 1-8:    Node ID Select (ID0-ID7)
X SW3 1-5:    IRQ Select   
X     6-7:    Extra Timeout
-    8  :    Rom Enable   
+    8  :    ROM Enable   
X JP1         Led connector
X BNC         Coax connector
X 
@@ -3089,7 +3089,7 @@
X 0 = Jumper Installed
X 1 = Open
X 
-Top Jumper line Bit 7 = Rom Enable 654=Memory location 321=I/O
+Top Jumper line Bit 7 = ROM Enable 654=Memory location 321=I/O
X 
X Settings for Memory Location (Top Jumper Line)
X 456     Address selected
diff -u --recursive --new-file v2.3.9/linux/Documentation/networking/arcnet.txt linux/Documentation/networking/arcnet.txt
--- v2.3.9/linux/Documentation/networking/arcnet.txt	Mon Sep 14 11:32:22 1998
+++ linux/Documentation/networking/arcnet.txt	Mon Jul  5 19:52:52 1999
@@ -1,4 +1,3 @@
-
X ----------------------------------------------------------------------------
X NOTE:  See also arcnet-hardware.txt in this directory for jumper-setting
X and cabling information if you're like many of us and didn't happen to get a
@@ -92,10 +91,10 @@
X 	http://www.perftech.com/ or ftp to ftp.perftech.com.
X 	
X Novell makes a networking stack for DOS which includes ARCnet drivers.  Try
-ftp'ing to ftp.novell.com.
+FTPing to ftp.novell.com.
X 
X You can get the Crynwr packet driver collection (including arcether.com, the
-one you'll want to use with arcnet cards) from
+one you'll want to use with ARCnet cards) from
X oak.oakland.edu:/simtel/msdos/pktdrvr. It won't work perfectly on a 386+
X without patches, though, and also doesn't like several cards.  Fixed
X versions are available on my WWW page, or via e-mail if you don't have WWW
@@ -183,7 +182,7 @@
X -----------------------
X 
X Configure and rebuild Linux.  When asked, answer 'm' to "Generic ARCnet 
-support" and to support for your ARcnet chipset if you want to use the
+support" and to support for your ARCnet chipset if you want to use the
X loadable module. You can also say 'y' to "Generic ARCnet support" and 'm' 
X to the chipset support if you wish.
X 
@@ -269,7 +268,7 @@
X 	Arcether client, assuming you remember to load winpkt of course.
X 
X LAN Manager and Windows for Workgroups: These programs use protocols that
-        are incompatible with the internet standard.  They try to pretend
+        are incompatible with the Internet standard.  They try to pretend
X         the cards are Ethernet, and confuse everyone else on the network. 
X         
X         However, v2.00 and higher of the Linux ARCnet driver supports this
@@ -288,7 +287,7 @@
X 	you're completely insane, and/or you need to build some kind of
X 	hybrid network that uses both encapsulation types.
X 
-OS2: I've been told it works under Warp Connect with an ARCnet driver from
+OS/2: I've been told it works under Warp Connect with an ARCnet driver from
X 	SMC.  You need to use the 'arc0e' interface for this.  If you get
X 	the SMC driver to work with the TCP/IP stuff included in the
X 	"normal" Warp Bonus Pack, let me know.
@@ -309,7 +308,7 @@
X The ARCnet driver v2.10 ALPHA supports three protocols, each on its own
X "virtual network device":
X 
-	arc0  - RFC1201 protocol, the official internet standard which just
+	arc0  - RFC1201 protocol, the official Internet standard which just
X 		happens to be 100% compatible with Novell's TRXNET driver. 
X 		Version 1.00 of the ARCnet driver supported _only_ this
X 		protocol.  arc0 is the fastest of the three protocols (for
@@ -331,13 +330,13 @@
X 		reasons yet to be determined.  (Probably it's the smaller
X 		MTU that does it.)
X 		
-	arc0s - The "[s]imple" RFC1051 protocol is the "previous" internet
+	arc0s - The "[s]imple" RFC1051 protocol is the "previous" Internet
X 		standard that is completely incompatible with the new
X 		standard.  Some software today, however, continues to
X 		support the old standard (and only the old standard)
X 		including NetBSD and AmiTCP.  RFC1051 also does not support
X 		RFC1201's packet splitting, and the MTU of 507 is still
-		smaller than the internet "requirement," so it's quite
+		smaller than the Internet "requirement," so it's quite
X 		possible that you may run into problems.  It's also slower
X 		than RFC1201 by about 25%, for the same reason as arc0e.
X 		
@@ -388,16 +387,16 @@
X    Linux but runs the free Microsoft LANMAN Client instead.
X 
X    Worse, one of the Linux computers (freedom) also has a modem and acts as
-   a router to my internet provider.  The other Linux box (insight) also has
+   a router to my Internet provider.  The other Linux box (insight) also has
X    its own IP address and needs to use freedom as its default gateway.  The
-   XT (patience), however, does not have its own internet IP address and so
+   XT (patience), however, does not have its own Internet IP address and so
X    I assigned it one on a "private subnet" (as defined by RFC1597).
X 
X    To start with, take a simple network with just insight and freedom. 
X    Insight needs to:
X    	- talk to freedom via RFC1201 (arc0) protocol, because I like it
X 	  more and it's faster.
-	- use freedom as its internet gateway.
+	- use freedom as its Internet gateway.
X 	
X    That's pretty easy to do.  Set up insight like this:
X    	ifconfig arc0 insight
@@ -417,20 +416,20 @@
X    	/* and default gateway is configured by pppd */
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 01'
echo 'File patch-2.3.10 is continued in part 02'
echo 02 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 02 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
X    	
X    Great, now insight talks to freedom directly on arc0, and sends packets
-   to the internet through freedom.  If you didn't know how to do the above,
+   to the Internet through freedom.  If you didn't know how to do the above,
X    you should probably stop reading this section now because it only gets
X    worse.
X 
X    Now, how do I add patience into the network?  It will be using LANMAN
X    Client, which means I need the arc0e device.  It needs to be able to talk
X    to both insight and freedom, and also use freedom as a gateway to the
-   internet.  (Recall that patience has a "private IP address" which won't
-   work on the internet; that's okay, I configured Linux IP masquerading on
+   Internet.  (Recall that patience has a "private IP address" which won't
+   work on the Internet; that's okay, I configured Linux IP masquerading on
X    freedom for this subnet).
X    
X    So patience (necessarily; I don't have another IP number from my
X    provider) has an IP address on a different subnet than freedom and
-   insight, but needs to use freedom as an internet gateway.  Worse, most
+   insight, but needs to use freedom as an Internet gateway.  Worse, most
X    DOS networking programs, including LANMAN, have braindead networking
X    schemes that rely completely on the netmask and a 'default gateway' to
X    determine how to route packets.  This means that to get to freedom or
@@ -449,7 +448,7 @@
X    
X    This way, freedom will send all packets for patience through arc0e,
X    giving its IP address as gatekeeper (on the private subnet).  When it
-   talks to insight or the internet, it will use its "freedom" internet IP
+   talks to insight or the Internet, it will use its "freedom" Internet IP
X    address.
X    
X    You will notice that we haven't configured the arc0e device on insight. 
@@ -473,7 +472,7 @@
X    
X                                                     
X           [RFC1201 NETWORK]                   [ETHER-ENCAP NETWORK]
-      (registered internet subnet)           (RFC1597 private subnet)
+      (registered Internet subnet)           (RFC1597 private subnet)
X   
X                              (IP Masquerade)
X           /---------------\         *            /---------------\
@@ -523,7 +522,7 @@
X Once the driver is running, you can run the arcdump shell script (available
X from me or in the full ARCnet package, if you have it) as root to list the
X contents of the arcnet buffers at any time.  To make any sense at all out of
-this, you should grab the pertinent RFC's. (some are listed near the top of
+this, you should grab the pertinent RFCs. (some are listed near the top of
X arcnet.c).  arcdump assumes your card is at 0xD0000.  If it isn't, edit the
X script.
X 
diff -u --recursive --new-file v2.3.9/linux/Documentation/networking/baycom.txt linux/Documentation/networking/baycom.txt
--- v2.3.9/linux/Documentation/networking/baycom.txt	Sun Jun  7 11:13:44 1998
+++ linux/Documentation/networking/baycom.txt	Tue Jul  6 19:16:55 1999
@@ -31,7 +31,7 @@
X   Its devices are called bcp0 through bcp3.
X 
X baycom_epp:
-  This driver supports the epp modem.
+  This driver supports the EPP modem.
X   Its devices are called bce0 through bce3.
X   This driver is work-in-progress.
X 
@@ -60,10 +60,10 @@
X         an additional power supply. Furthermore, it incorporates a carrier
X         detect circuitry.
X 
-epp:    This is a high speed modem adaptor that connects to an enhanced parallel port.
+EPP:    This is a high-speed modem adaptor that connects to an enhanced parallel port.
X         Its target audience is users working over a high speed hub (76.8kbit/s).
X 
-eppfpga: This is a redesign of the epp adaptor.
+eppfpga: This is a redesign of the EPP adaptor.
X 
X 
X 
diff -u --recursive --new-file v2.3.9/linux/Documentation/networking/cs89x0.txt linux/Documentation/networking/cs89x0.txt
--- v2.3.9/linux/Documentation/networking/cs89x0.txt	Fri Sep 11 11:21:57 1998
+++ linux/Documentation/networking/cs89x0.txt	Tue Jul  6 19:16:55 1999
@@ -203,7 +203,7 @@
X * io=###              - specify IO address (200h-360h)
X * irq=##              - specify interrupt level
X * mmode=#####         - specify memory base address
-* dma=#               - specify dma channel
+* dma=#               - specify DMA channel
X * media=rj45          - specify media type
X    or media=2
X    or media=aui
@@ -412,33 +412,33 @@
X assigned during hardware configuration.  The following tests are performed:
X 
X    * IO Register Read/Write Test
-     The IO Register Read/Write test insures that the CS8900/20 can be 
+     The IO Register Read/Write test ensures that the CS8900/20 can be 
X      accessed in IO mode, and that the IO base address is correct.
X 
X    * Shared Memory Test
-     The Shared Memory test insures the CS8900/20 can be accessed in memory 
+     The Shared Memory test ensures the CS8900/20 can be accessed in memory 
X      mode and that the range of memory addresses assigned does not conflict 
X      with other devices in the system.
X 
X    * Interrupt Test
-     The Interrupt test insures there are no conflicts with the assigned IRQ
+     The Interrupt test ensures there are no conflicts with the assigned IRQ
X      signal.
X 
X    * EEPROM Test
-     The EEPROM test insures the EEPROM can be read.
+     The EEPROM test ensures the EEPROM can be read.
X 
X    * Chip RAM Test
-     The Chip RAM test insures the 4K of memory internal to the CS8900/20 is
+     The Chip RAM test ensures the 4 K of memory internal to the CS8900/20 is
X      working properly.
X 
X    * Internal Loop-back Test
-     The Internal Loop Back test insures the adapter's transmitter and 
+     The Internal Loop Back test ensures the adapter's transmitter and 
X      receiver are operating properly.  If this test fails, make sure the 
X      adapter's cable is connected to the network (check for LED activity for 
X      example).
X 
X    * Boot PROM Test
-     The Boot PROM  test insures the Boot PROM is present, and can be read.
+     The Boot PROM test ensures the Boot PROM is present, and can be read.
X      Failure indicates the Boot PROM  was not successfully read due to a
X      hardware problem or due to a conflicts on the Boot PROM address
X      assignment. (Test only applies if the adapter is configured to use the
@@ -564,7 +564,7 @@
X Telephone  :(800) 888-5016 (from inside U.S. and Canada)
X            :(512) 442-7555 (from outside the U.S. and Canada)
X Fax	   :(512) 912-3871
-Email	   :ethe...@crystal.cirrus.com
+E-mail	   :ethe...@crystal.cirrus.com
X WWW        :http://www.crystal.com
X 
X 
diff -u --recursive --new-file v2.3.9/linux/Documentation/networking/olympic.txt linux/Documentation/networking/olympic.txt
--- v2.3.9/linux/Documentation/networking/olympic.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/networking/olympic.txt	Mon Jul  5 19:54:55 1999
@@ -0,0 +1,75 @@
+
+IBM PCI Pit/Pit-Phy/Olympic CHIPSET BASED TOKEN RING CARDS README
+
+Release 0.2.0 - Release    
+	June 8th 1999 Peter De Schrijver & Mike Phillips
+
+
+Thanks:
+Erik De Cock, Adrian Bridgett and Frank Fiene for their 
+patience and testing.  
+Paul Norton without whose tr.c code we would have had
+a lot more work to do.
+ 
+Options:
+
+The driver accepts three options: ringspeed, pkt_buf_sz, and  
+message_level.
+
+These options can be specified differently for each card found. 
+
+ringspeed:  Has one of three settings 0 (default), 4 or 16.  0 will 
+make the card autosense the ringspeed and join at the appropriate speed, 
+this will be the default option for most people.  4 or 16 allow you to 
+explicitly force the card to operate at a certain speed.  The card will fail 
+if you try to insert it at the wrong speed. (Although some hubs will allow 
+this so be *very* careful).  The main purpose for explicitly setting the ring
+speed is for when the card is first on the ring.  In autosense mode, if the card
+cannot detect any active monitors on the ring it will not open, so you must 
+re-init the card at the appropriate speed.  Unfortunately at present the only
+way of doing this is rmmod and insmod which is a bit tough if it is compiled
+in the kernel.
+
+pkt_buf_sz:  This is this initial receive buffer allocation size.  This will
+default to 4096 if no value is entered. You may increase performance of the 
+driver by setting this to a value larger than the network packet size, although
+the driver now re-sizes buffers based on MTU settings as well. 
+
+message_level: Controls level of messages created by the driver. Defaults to 0:
+which only displays start-up and critical messages.  Presently any non-zero 
+value will display all soft messages as well.  NB This does not turn 
+debuging messages on, that must be done by modified the source code.
+
+Multi-card:
+
+The driver will detect multiple cards and will work with shared interrupts,
+each card is assigned the next token ring device, i.e. tr0 , tr1, tr2.  The 
+driver should also happily reside in the system with other drivers.  It has 
+been tested with ibmtr.c running, and I personnally have had one Olicom PCI 
+card and two IBM olympic cards (all on the same interrupt), all running
+together. 
+
+Variable MTU size:
+
+The driver can handle a MTU size upto either 4500 or 18000 depending upon 
+ring speed.  The driver also changes the size of the receive buffers as part
+of the mtu re-sizing, so if you set mtu = 18000, you will need to be able
+to allocate 16 * (sk_buff with 18000 buffer size) call it 18500 bytes per ring 
+position = 296,000 bytes of memory space, plus of course anything 
+necessary for the tx sk_buff's.  Remember this is per card, so if you are
+building routers, gateway's etc, you could start to use a lot of memory
+real fast.
+
+Network Monitor Mode:
+
+By modifying the #define OLYMPIC_NETWORK_MONITOR from 0 to 1 in the 
+source code the driver will implement a quasi network monitoring 
+mode.  All unexpected MAC frames (beaconing etc.) will be received
+by the driver and the source and destination addresses printed. 
+Also an entry will be added in  /proc/net called olympic_tr. This 
+displays low level information about the configuration of the ring and
+the adapter. This feature has been designed for network adiministrators
+to assist in the diagnosis of network / ring problems.
+
+6/8/99 Peter De Schrijver and Mike Phillips
+
diff -u --recursive --new-file v2.3.9/linux/Documentation/networking/policy-routing.txt linux/Documentation/networking/policy-routing.txt
--- v2.3.9/linux/Documentation/networking/policy-routing.txt	Thu May 14 10:26:22 1998
+++ linux/Documentation/networking/policy-routing.txt	Tue Jul  6 19:05:48 1999
@@ -83,7 +83,7 @@
X 2.	Opposite case. Just forget all that you know about routing
X 	tables. Every rule is supplied with its own gateway, device
X 	info. record. This approach is not appropriate for automated
-	route maintanance, but it is ideal for manual configuration.
+	route maintenance, but it is ideal for manual configuration.
X 
X 	HOWTO:  iproute addrule [ from PREFIX ] [ to PREFIX ] [ tos TOS ]
X 		[ dev INPUTDEV] [ pref PREFERENCE ] route [ gw GATEWAY ]
diff -u --recursive --new-file v2.3.9/linux/Documentation/networking/z8530drv.txt linux/Documentation/networking/z8530drv.txt
--- v2.3.9/linux/Documentation/networking/z8530drv.txt	Wed May 20 18:54:34 1998
+++ linux/Documentation/networking/z8530drv.txt	Tue Jul  6 19:05:48 1999
@@ -252,7 +252,7 @@
X 
X speed 1200		# the default baudrate
X clock dpll		# clock source: 
-			# 	dpll     = normal halfduplex operation
+			# 	dpll     = normal half duplex operation
X 			# 	external = MODEM provides own Rx/Tx clock
X 			#	divider  = use full duplex divider if
X 			#		   installed (1)
diff -u --recursive --new-file v2.3.9/linux/Documentation/oops-tracing.txt linux/Documentation/oops-tracing.txt
--- v2.3.9/linux/Documentation/oops-tracing.txt	Tue Jan  5 11:14:24 1999
+++ linux/Documentation/oops-tracing.txt	Thu Jul  1 10:54:31 1999
@@ -1,15 +1,16 @@
X Quick Summary
X -------------
X 
-cd /usr/src/linux/scripts/ksymoops
-make ksymoops
-./ksymoops < the_oops.txt
+Install ksymoops from ftp://ftp.ocs.com.au/pub/ksymoops
+Read the ksymoops man page.
+ksymoops < the_oops.txt
X 
X and send the output the maintainer of the kernel area that seems to be
-involved with the problem. Don't worry too much about getting the wrong
-person. If you are unsure send it to the person responsible for the code
-relevant to what you were doing. If it occurs repeatably try and describe
-how to recreate it. Thats worth even more than the oops
+involved with the problem, not to the ksymoops maintainer. Don't worry
+too much about getting the wrong person. If you are unsure send it to
+the person responsible for the code relevant to what you were doing.
+If it occurs repeatably try and describe how to recreate it. Thats
+worth even more than the oops
X 
X If you are totally stumped as to whom to send the report, send it to 
X linux-...@vger.rutgers.edu. Thanks for your help in making Linux as
@@ -41,9 +42,8 @@
X same compiler and similar setups.
X 
X The other thing to do is disassemble the "Code:" part of the bug report: 
-ksymoops will do this too with the correct tools (and new version of 
-ksymoops), but if you don't have the tools you can just do a silly 
-program:
+ksymoops will do this too with the correct tools, but if you don't have
+the tools you can just do a silly program:
X 
X 	char str[] = "\xXX\xXX\xXX...";
X 	main(){}
diff -u --recursive --new-file v2.3.9/linux/Documentation/parport.txt linux/Documentation/parport.txt
--- v2.3.9/linux/Documentation/parport.txt	Fri Mar 26 13:23:24 1999
+++ linux/Documentation/parport.txt	Sun Jul  4 10:14:13 1999
@@ -28,8 +28,8 @@
X 
X to tell the parport code that you want three PC-style ports, one at
X 0x3bc with no IRQ, one at 0x378 using IRQ 7, and one at 0x278 with an
-auto-detected IRQ.  Currently, PC-style (parport_pc) and Sun Ultra/AX
-(parport_ax) hardware is supported; more is in the works.
+auto-detected IRQ.  Currently, PC-style (parport_pc), Sun Ultra/AX
+(parport_ax), Amiga, Atari, and MFC3 hardware is supported.
X 
X 
X KMod
@@ -38,7 +38,7 @@
X If you use kmod, you will find it useful to edit /etc/conf.modules.
X Here is an example of the lines that need to be added:
X 
-	alias parport_lowlevel parport_pc
+	post-install parport modprobe -k parport_pc
X 	options parport_pc io=0x378,0x278 irq=7,auto
X 
X KMod will then automatically load parport_pc (with the options
@@ -49,20 +49,15 @@
X Parport probe [optional]
X -------------
X 
-Once the architecture-dependent part of the parport code is loaded
-into the kernel, you can insert the parport_probe module with:
-
-	# insmod parport_probe.o
-
-This will perform an IEEE1284 probe of any attached devices and log a
-message similar to:
+In 2.2 kernels there was a module called parport_probe, which was used
+for collecting IEEE 1284 device ID information.  This has now been
+enhanced and now lives with the IEEE 1284 support.  When a parallel
+port is detected, the devices that are connected to it are analysed,
+and information is logged like this:
X 
X 	parport0: Printer, BJC-210 (Canon)
X 
-(If you are using kmod and have configured parport_probe as a module,
-this will just happen.)
-
-The probe information is available in /proc/parport/?/autoprobe.
+The probe information is available from files in /proc/sys/dev/parport/.
X 
X 
X Parport linked into the kernel statically
@@ -85,29 +80,74 @@
X ==============
X 
X If you have configured the /proc filesystem into your kernel, you will
-see a new directory entry: /proc/parport.  In there will be a
+see a new directory entry: /proc/sys/dev/parport.  In there will be a
X directory entry for each parallel port for which parport is
-configured.  In each of those directories are four files describing
-that parallel port.  For example:
-
-File:				Contents:
-
-/proc/parport/0/devices		A list of the device drivers using
-				that port.  A "+" will appear by the
-				name of the device currently using the
-				port (it might not appear against any).
-
-/proc/parport/0/hardware	Parallel port's base address, IRQ line
-				and DMA channel.
-
-/proc/parport/0/irq		The IRQ that parport is using for that
-				port.  This is in a separate file to
-                                allow you to alter it by writing a new
-				value in (IRQ number or "none").
+configured.  In each of those directories are a collection of files
+describing that parallel port.
X 
-/proc/parport/0/autoprobe	Any IEEE-1284 device ID information
-				that has been acquired.
+The /proc/sys/dev/parport directory tree looks like:
X 
+parport
+|-- default
+|   |-- spintime
+|   `-- timeslice
+|-- parport0
+|   |-- autoprobe
+|   |-- autoprobe0
+|   |-- autoprobe1
+|   |-- autoprobe2
+|   |-- autoprobe3
+|   |-- devices
+|   |   |-- active
+|   |   `-- lp
+|   |       `-- timeslice
+|   |-- hardware
+|   `-- spintime
+`-- parport1
+    |-- autoprobe
+    |-- autoprobe0
+    |-- autoprobe1
+    |-- autoprobe2
+    |-- autoprobe3
+    |-- devices
+    |   |-- active
+    |   `-- ppa
+    |       `-- timeslice
+    |-- hardware
+    `-- spintime
+
+
+File:		Contents:
+
+devices/active	A list of the device drivers using that port.  A "+"
+		will appear by the name of the device currently using
+		the port (it might not appear against any).  The
+		string "none" means that there are no device drivers
+		using that port.
+
+hardware	Parallel port's base address, IRQ line and DMA channel.
+
+autoprobe	Any IEEE-1284 device ID information that has been
+		acquired from the (non-IEEE 1284.3) device.
+
+autoprobe[0-3]	IEEE 1284 device ID information retrieved from
+		daisy-chain devices that conform to IEEE 1284.3.
+
+spintime	The number of microseconds to busy-loop while waiting
+		for the peripheral to respond.  You might find that
+		adjusting this improves performance, depending on your
+		peripherals.  This is a port-wide setting, i.e. it
+		applies to all devices on a particular port.
+
+timeslice	The number of jiffies (FIXME: this should be in
+		milliseconds or something) that a device driver is
+		allowed to keep a port claimed for.  This is advisory,
+		and driver can ignore it if it must.
+
+default/*	The defaults for spintime and timeslice. When a new
+		port is	registered, it picks up the default spintime.
+		When a new device is registered, it picks up the
+		default timeslice.
X 
X Device drivers
X ==============
@@ -135,7 +175,7 @@
X 
X Also:
X 
- * If you selected the IEEE-1284 autoprobe at compile time, you can say
+ * If you selected the IEEE 1284 support at compile time, you can say
X    `lp=auto' on the kernel command line, and lp will create devices
X    only for those ports that seem to have printers attached.
X 
diff -u --recursive --new-file v2.3.9/linux/Documentation/pcwd-watchdog.txt linux/Documentation/pcwd-watchdog.txt
--- v2.3.9/linux/Documentation/pcwd-watchdog.txt	Sun Jan 19 05:47:24 1997
+++ linux/Documentation/pcwd-watchdog.txt	Tue Jul  6 19:05:48 1999
@@ -1,6 +1,6 @@
X                      Berkshire Products PC Watchdog Card
X                    Support for ISA Cards  Revision A and C
-           Documentation and Driver by Ken Hollis <kho...@nurk.org>
+           Documentation and Driver by Ken Hollis <ke...@bitgate.com>
X 
X  The PC Watchdog is a card that offers the same type of functionality that
X  the WDT card does, only it doesn't require an IRQ to run.  Furthermore,
@@ -15,7 +15,7 @@
X  The Watchdog Driver will automatically find your watchdog card, and will
X  attach a running driver for use with that card.  After the watchdog
X  drivers have initialized, you can then talk to the card using the PC
- Watchdog program, available from ftp.bitgate.com:/pub/bitgate/pcwd.
+ Watchdog program, available from http://ftp.bitgate.com/pcwd/.
X 
X  I suggest putting a "watchdog -d" before the beginning of an fsck, and
X  a "watchdog -e -t 1" immediately after the end of an fsck.  (Remember
@@ -128,4 +128,7 @@
X  And that's all she wrote!
X 
X  -- Ken Hollis
-    (kho...@nurk.org)
+    (ke...@bitgate.com)
+
+(This documentation may be out of date.  Check
+ http://ftp.bitgate.com/pcwd/ for the absolute latest additions.)
diff -u --recursive --new-file v2.3.9/linux/Documentation/sound/Introduction linux/Documentation/sound/Introduction
--- v2.3.9/linux/Documentation/sound/Introduction	Thu Apr 29 11:53:41 1999
+++ linux/Documentation/sound/Introduction	Mon Jul  5 20:04:47 1999
@@ -1,6 +1,6 @@
-Soundcore	Notes on Modular Sound Drivers and Soundcore
+Introduction	Notes on Modular Sound Drivers and Soundcore
X Wade Hampton 
-11/20/1998
+6/30/1999
X 
X Purpose:  
X ========
@@ -10,13 +10,21 @@
X 
X Note, some of this probably should be added to the Sound-HOWTO!
X 
+
X Copying:
X ========
X none
X 
+
X History:
X ========
-0.1.0  11/20/1998  First version
+0.1.0  11/20/1998  First version, draft
+1.0.0  11/1998     Alan Cox changes, incorporation in 2.2.0
+                   as /usr/src/linux/Documentation/sound/Introduction
+1.1.0  6/30/1999   Second version, added notes on making the drivers,
+                   added info on multiple sound cards of similar types,]
+                   added more diagnostics info, added info about esd.
+                   added info on OSS and ALSA.
X 
X 
X Modular Sound Drivers:
@@ -58,6 +66,53 @@
X for the same or a similar feature (dma1= versus dma16=).  As a last 
X resort, inspect the code (search for MODULE_PARM).
X 
+Notes:
+
+1.  There is a new OpenSource sound driver called ALSA which is
+    currently under development:  http://www.alsa-project.org/
+    I have not tried it nor am I aware of its status, but it is
+    currently under development.
+
+2.  The commercial OSS driver may be obtained from the site:
+    http://www/opensound.com.  This may be used for cards that
+    are unsupported by the kernel driver, or may be used
+    by other operating systems.  
+
+3.  The enlightenment sound daemon may be used for playing
+    multiple sounds at the same time via a single card, eliminating
+    some of the requirements for multiple sound card systems.  For
+    more information, see:  http://www.tux.org/~ricdude/EsounD.html  
+    The "esd" program may be used with the real-player and mpeg 
+    players like mpg123 and x11amp.
+
+
+Building the Modules:
+=====================
+
+This document does not provide full details on building the 
+kernel, etc.  The notes below apply only to making the kernel
+sound modules.   If this conflicts with the kernel's README,
+the README takes precedence. 
+
+1.  To make the kernel sound modules, cd to your /usr/src/linux
+    directory (typically) and type make config, make menuconfig, 
+    or make xconfig (to start the command line, dialog, or x-based
+    configuration tool).  
+
+2.  Select the Sound option and a dialog will be displayed.  
+
+3.  Select M (module) for "Sound card support".
+
+4.  Select your sound driver(s) as a module.  For ProAudio, Sound
+    Blaster, etc., select M (module) for OSS sound modules.
+    [thanks to marvin stodolsky <stod...@erols.com>]A
+
+5.  Make the kernel (e.g., make dep ; make bzImage), and install
+    the kernel.
+
+6.  Make the modules and install them (make modules; make modules_install).
+
+
X 
X INSMOD:
X =======
@@ -82,6 +137,9 @@
X /sbin/insmod uart401
X /sbin/insmod sb io=$SB_BASE irq=$SB_IRQ dma=$SB_DMA dma16=$SB_DMA2 mpu_io=$SB_MP
X 
+When using sound as a module, I typically put these commands
+in a file such as /root/soundon.sh.
+
X 
X MODPROBE:
X =========
@@ -117,8 +175,8 @@
X 	soundcore               1968   8  [sb sound]
X 
X 
-Removing Sound:
-===============
+Removing Sound: 
+=============== 
X 
X Sound may be removed by using /sbin/rmmod in the reverse order
X in which you load the modules.  Note, if a program has a sound device
@@ -134,6 +192,25 @@
X /sbin/rmmod soundlow
X /sbin/rmmod soundcore
X 
+When using sound as a module, I typically put these commands
+in a script such as /root/soundoff.sh.
+
+
+Removing Sound for use with OSS: 
+================================ 
+
+If you get really stuck or have a card that the kernel modules
+will not support, you can get a commercial sound driver from
+http://www.opensound.com.  Before loading the commercial sound
+driver, you should do the following:
+
+1.  remove sound modules (detailed above)
+2.  remove the sound modules from /etc/conf.modules
+3.  move the sound modules from /lib/modules/<kernel>/misc
+    (for example, I make a /lib/modules/<kernel>/misc/tmp
+    directory and copy the sound module files to that 
+    directory).
+
X 
X Multiple Sound Cards:
X =====================
@@ -154,11 +231,30 @@
X first (in my case "sb") and then load the other one
X (in my case "cs4232").
X 
+If you have two cards of the same type that are jumpered 
+cards or different PnP revisions, you may load the same 
+module twice.  For example, I have a SoundBlaster vibra 16
+and an older SoundBlaster 16 (jumpers).  To load the module
+twice, you need to do the following:
+
+1.  Copy the sound modules to a new name.  For example
+    sb.o could be copied (or symlinked) to sb1.o for the
+    second SoundBlasster.
+
+2.  Make a second entry in /etc/conf.modules, for example,
+    sound1 or sb1.  This second entry should refer to the
+    new module names for example sb1, and should include
+    the I/O, etc. for the second sound card.
+
+3.  Update your soundon.sh script, etc.
+
X Warning:  I have never been able to get two PnP sound cards of the
X same type to load at the same time.  I have tried this several times
X with the Soundblaster Vibra 16 cards.  OSS has indicated that this
X is a PnP problem....  If anyone has any luck doing this, please 
-send me an E-MAIL.  PCI sound cards should not have this problem.
+send me an E-MAIL.  PCI sound cards should not have this problem.a
+Since this was originally release, I have received a couple of 
+mails from people who have accomplished this!
X 
X 
X Sound Problems:
@@ -175,6 +271,8 @@
X       write down what addresses, IRQ, and DMA channels
X       those were using for the same hardware.  You probably 
X       can use these addresses, IRQs, and DMA channels.
+      You should really do this BEFORE attempting to get
+      sound working!
X   
X   B)  Check (cat) /proc/interrupts, /proc/ioports,
X       and /proc/dma.  Are you trying to use an address,
@@ -184,22 +282,44 @@
X       may need a kernel patch to get this device).
X   
X   D)  Inspect your /var/log/messages file.  Often that will 
-      indicate what IRQ or IO port could not be obtained
+      indicate what IRQ or IO port could not be obtained.
X   
X   E)  Try another port or IRQ.  Note this may involve 
X       using the PnP tools to move the sound card to 
-      another location.
+      another location.  Sometimes this is the only way 
+      and it is more or less trial and error.
X 
-2)  If you get motorboating (the same sound or part of a 
+2)  If you get motor-boating (the same sound or part of a 
X     sound clip repeated), you probably have either an IRQ
-    or DMA conflict.  Move the card to another address.  This
-    has happened to me when playing long files when I had 
-    an IRQ conflict.
+    or DMA conflict.  Move the card to another IRQ or DMA
+    port.  This has happened to me when playing long files 
+    when I had an IRQ conflict.
+
+3.  If you get dropouts or pauses when playing high sample
+    rate files such as using mpg123 or x11amp/xmms, you may 
+    have too slow of a CPU and may have to use the options to 
+    play the files at 1/2 speed.  For example, you may use
+    the -2 or -4 option on mpg123.  You may also get this
+    when trying to play mpeg files stored on a CD-ROM
+    (my Toshiba T8000 PII/366 sometimes has this problem).
+
+4.  If you get "cannot access device" errors, your /dev/dsp
+    files, etc. may be set to owner root, mode 600.  You 
+    may have to use the command:
+      chmod 666 /dev/dsp /dev/mixer /dev/audio
+
+5.  If you get "device busy" errors, another program has the
+    sound device open.  For example, if using the Enlightenment
+    sound daemon "esd", the "esd" program has the sound device.
+    If using "esd", please RTFM the docs on ESD.  For example,
+    esddsp <program> may be used to play files via a non-esd
+    aware program.
+
X 
-3)  Ask for help on the sound list or send E-MAIL to the
+6)  Ask for help on the sound list or send E-MAIL to the
X     sound driver author/maintainer.
X 
-4)  Turn on debug in drivers/sound/sound_config.h (DEB, DDB, MDB).
+7)  Turn on debug in drivers/sound/sound_config.h (DEB, DDB, MDB).
X 
X 
X Configuring Sound:
@@ -210,7 +330,8 @@
X 1)  Hardcoded in the kernel at compile time (not applicable when
X     using sound modules).  This was the OLD way!
X 
-2)  On the command line when using insmod.
+2)  On the command line when using insmod or in a bash script
+    using command line calls to load sound.
X 
X 3)  In /etc/conf.modules when using modprobe.
X 
@@ -224,7 +345,6 @@
X Anyone want to write a linuxconf module for configuring sound?
X 
X 
-
X For More Information (RTFM):
X ============================
X 1)  Information on kernel modules:  linux/Documentation/modules.txt
@@ -242,12 +362,17 @@
X 
X 7)  The sndconfig and rhsound documentation from Red Hat.
X 
-8)  The Linux-sound mailing list:  sound...@redhat.com
+8)  The Linux-sound mailing list:  sound...@redhat.com.
+
+9)  Enlightenment documentation (for info on esd)
+    http://www.tux.org/~ricdude/EsounD.html.
X 
+10) ALSA home page:  http://www.alsa-project.org/
X 
X 
X Contact Information:
X ====================
X Wade Hampton:  (wham...@staffnet.com)
+
X 
X 
diff -u --recursive --new-file v2.3.9/linux/Documentation/sound/OPL3-SA2 linux/Documentation/sound/OPL3-SA2
--- v2.3.9/linux/Documentation/sound/OPL3-SA2	Thu Jan 14 22:53:02 1999
+++ linux/Documentation/sound/OPL3-SA2	Mon Jul  5 20:04:47 1999
@@ -46,6 +46,21 @@
X then email me if you are willing to experiment in an effort to make it
X work.
X 
+************************************************************************
+* I have now had two such machines, and I have fixed this to work
+* properly when built into the kernel.  The Toshiba Libretto series, or
+* at least models 70CT and 110CT which I have owned, use a Yamaha
+* OPL3-SAx (OPL3-SA3 according to documentation) sound chip, IRQ 5,
+* IO addresses 220/530/388/330/370 and DMA 1,0 (_not_ 0,1).  All these
+* configuration settings can be gathered by booting another OS which
+* recognizes the card already.
+*
+* I have made things 'just work' for the non-modular case on such
+* machines when configured properly.
+*
+* David Luyer <lu...@ucs.uwa.edu.au>
+************************************************************************
+
X If you are using isapnp, follow the directions in its documentation to
X produce a configuration file.  Here is the relevant excerpt I use for
X my SAx card from my isapnp.conf:
diff -u --recursive --new-file v2.3.9/linux/Documentation/sysctl/README linux/Documentation/sysctl/README
--- v2.3.9/linux/Documentation/sysctl/README	Mon Apr 12 10:10:27 1999
+++ linux/Documentation/sysctl/README	Mon Jul  5 20:04:47 1999
@@ -1,4 +1,4 @@
-Documentation for /proc/sys/		kernel version 2.2.5
+Documentation for /proc/sys/		kernel version 2.2.10
X 	(c) 1998, 1999,  Rik van Riel <ri...@nl.linux.org>
X 
X 'Why', I hear you ask, 'would anyone even _want_ documentation
diff -u --recursive --new-file v2.3.9/linux/Documentation/sysctl/fs.txt linux/Documentation/sysctl/fs.txt
--- v2.3.9/linux/Documentation/sysctl/fs.txt	Mon Apr 12 10:10:27 1999
+++ linux/Documentation/sysctl/fs.txt	Mon Jul  5 20:04:47 1999
@@ -1,4 +1,4 @@
-Documentation for /proc/sys/fs/*	kernel version 2.2.5
+Documentation for /proc/sys/fs/*	kernel version 2.2.10
X 	(c) 1998, 1999,  Rik van Riel <ri...@nl.linux.org>
X 
X For general info and legal blurb, please look in README.
diff -u --recursive --new-file v2.3.9/linux/Documentation/sysctl/kernel.txt linux/Documentation/sysctl/kernel.txt
--- v2.3.9/linux/Documentation/sysctl/kernel.txt	Mon Apr 12 10:10:27 1999
+++ linux/Documentation/sysctl/kernel.txt	Mon Jul  5 20:04:47 1999
@@ -1,4 +1,4 @@
-Documentation for /proc/sys/kernel/*	kernel version 2.2.5
+Documentation for /proc/sys/kernel/*	kernel version 2.2.10
X 	(c) 1998, 1999,  Rik van Riel <ri...@nl.linux.org>
X 
X For general info and legal blurb, please look in README.
@@ -76,12 +76,21 @@
X 
X domainname & hostname:
X 
-These files can be controlled to set the domainname and
-hostname of your box. For the classic darkstar.frop.org
-a simple:
+These files can be used to set the NIS/YP domainname and the
+hostname of your box in exactly the same way as the commands
+domainname and hostname, i.e.:
X # echo "darkstar" > /proc/sys/kernel/hostname
-# echo "frop.org" > /proc/sys/kernel/domainname
-would suffice to set your hostname and domainname.
+# echo "mydomain" > /proc/sys/kernel/domainname
+has the same effect as
+# hostname "darkstar" > /proc/sys/kernel/hostname
+# domainname "mydomain" > /proc/sys/kernel/domainname
+
+Note, however, that the classic darkstar.frop.org has the
+hostname "darkstar" and DNS (Internet Domain Name Server)
+domainname "frop.org", not to be confused with the NIS (Network
+Information Service) or YP (Yellow Pages) domainname. These two
+domain names are in general different. For a detailed discussion
+see the hostname(1) man page.
X 
X ==============================================================
X 
diff -u --recursive --new-file v2.3.9/linux/Documentation/sysctl/sunrpc.txt linux/Documentation/sysctl/sunrpc.txt
--- v2.3.9/linux/Documentation/sysctl/sunrpc.txt	Mon Apr 12 10:10:27 1999
+++ linux/Documentation/sysctl/sunrpc.txt	Mon Jul  5 20:04:47 1999
@@ -1,4 +1,4 @@
-Documentation for /proc/sys/sunrpc/*	kernel version 2.2.5
+Documentation for /proc/sys/sunrpc/*	kernel version 2.2.10
X 	(c) 1998, 1999,  Rik van Riel <ri...@nl.linux.org>
X 
X For general info and legal blurb, please look in README.
diff -u --recursive --new-file v2.3.9/linux/Documentation/sysctl/vm.txt linux/Documentation/sysctl/vm.txt
--- v2.3.9/linux/Documentation/sysctl/vm.txt	Thu Apr 29 11:53:41 1999
+++ linux/Documentation/sysctl/vm.txt	Mon Jul  5 20:04:47 1999
@@ -1,4 +1,4 @@
-Documentation for /proc/sys/vm/*	kernel version 2.2.5
+Documentation for /proc/sys/vm/*	kernel version 2.2.10
X 	(c) 1998, 1999,  Rik van Riel <ri...@nl.linux.org>
X 
X For general info and legal blurb, please look in README.
diff -u --recursive --new-file v2.3.9/linux/Documentation/video4linux/API.html linux/Documentation/video4linux/API.html
--- v2.3.9/linux/Documentation/video4linux/API.html	Thu Jan  7 08:41:55 1999
+++ linux/Documentation/video4linux/API.html	Mon Jul  5 20:04:47 1999
@@ -1,6 +1,9 @@
X <HTML><HEAD>
-<TITLE>Video4Linux Kernel API Reference v0.1:19980516</TITLE>
+<TITLE>Video4Linux Kernel API Reference v0.1:19990430</TITLE>
X </HEAD>
+<! Revision History: >
+<!   4/30/1999 - Fred Gleason (fr...@wava.com)>
+<! Documented extensions for the Radio Data System (RDS) extensions >
X <BODY bgcolor="#ffffff">
X <H3>Devices</H3>
X Video4Linux provides the following sets of device files. These live on the
@@ -117,7 +120,7 @@
X </TABLE>
X <P>
X Merely setting the window does not enable capturing. Overlay capturing
-is activatied by passing the <b>VIDIOCCAPTURE</b> ioctl a value of 1, and
+is activated by passing the <b>VIDIOCCAPTURE</b> ioctl a value of 1, and
X disabled by passing it a value of 0. 
X <P>
X Some capture devices can capture a subfield of the image they actually see.
@@ -150,7 +153,7 @@
X nature of the channel itself.
X <P>
X The <b>VIDIOCSCHAN</b> ioctl takes an integer argument and switches the
-capture to this input. It is not defined whether paramters such as colour
+capture to this input. It is not defined whether parameters such as colour
X settings or tuning are maintained across a channel switch. The caller should
X maintain settings as desired for each channel. (This is reasonable as 
X different video inputs may have different properties).
@@ -249,6 +252,8 @@
X <TR><TD><b>VIDEO_TUNER_LOW</b><TD>Frequency is in a lower range</TD>
X <TR><TD><b>VIDEO_TUNER_NORM</b><TD>The norm for this tuner is settable</TD>
X <TR><TD><b>VIDEO_TUNER_STEREO_ON</b><TD>The tuner is seeing stereo audio</TD>
+<TR><TD><b>VIDEO_TUNER_RDS_ON</b><TD>The tuner is seeing a RDS datastream</TD>
+<TR><TD><b>VIDEO_TUNER_MBS_ON</b><TD>The tuner is seeing a MBS datastream</TD>
X </TABLE>
X <P>
X The following modes are defined
@@ -349,6 +354,21 @@
X <TR><TD><b>teletext</b><TD>Teletext device</TD>
X </TABLE>
X <P>
-
+<H3>RDS Datastreams</H3>
+For radio devices that support it, it is possible to receive Radio Data
+System (RDS) data by means of a read() on the device.  The data is packed in
+groups of three, as follows:
+<TABLE>
+<TR><TD>First Octet</TD><TD>Least Siginificant Byte of RDS Block</TD></TR>
+<TR><TD>Second Octet</TD><TD>Most Siginificant Byte of RDS Block
+<TR><TD>Third Octet</TD><TD>Bit 7:</TD><TD>Error bit.  Indicates that
+an uncorrectable error occured during reception of this block.</TD></TR>
+<TR><TD> </TD><TD>Bit 6:</TD><TD>Corrected bit.  Indicates that  
+an error was corrected for this data block.</TD></TR>
+<TR><TD> </TD><TD>Bits 5-3:</TD><TD>Reeived Offset.  Indicates the  
+offset received by the sync system.</TD></TR>
+<TR><TD> </TD><TD>Bits 2-0:</TD><TD>Offset Name.  Indicates the  
+offset applied to this data.</TD></TR>
+</TABLE>
X </BODY>
X </HTML>
diff -u --recursive --new-file v2.3.9/linux/Documentation/video4linux/README.buz linux/Documentation/video4linux/README.buz
--- v2.3.9/linux/Documentation/video4linux/README.buz	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/video4linux/README.buz	Mon Jul  5 20:04:47 1999
@@ -0,0 +1,212 @@
+Iomega Buz Driver for Linux
+===========================
+
+by Rainer Johanni <Rai...@Johanni.de>
+
+Compiling and Loading the Driver
+================================
+
+You must run a 2.2.x kernel in order to use this driver.
+
+To compile the driver, just type make.
+
+Besides the files in this directory, the driver needs the
+'videodev' and the 'i2c' module from the Linux kernel.
+In order to get these modules available, enable module support
+for VIDEODEV and BTTV (which implies i2c) in your kernel
+configuration. You find these devices in the menu
+"Character Devices" in your Kernel Configuration.
+
+Before you load the driver you must have a video device
+at major device node 81. If you don't have it yet, do the
+following (as root!):
+
+cd /dev
+mknod video0 c 81 0
+ln -s video0 video
+
+Edit the 'update' script if you want to give the driver
+special options and then type (as root)
+
+./update
+
+to insert all the necessary modules into the kernel.
+
+If you want to make full use of the Video for Linux uncompressed
+grabbing facilities, you must either
+
+- obtain and install the "big_physarea patch" for your kernel and
+  set aside the necessary memory during boot time.
+  There seem to be several versions of this patch against
+  various kernel versions floating around in the net,
+  you may obtain one e.g. from:
+  http://www.polyware.nl/~middelin/patch/bigphysarea-2.2.1.tar.gz
+  You also have to compile your driber AFTER installing that patch
+  in order to get it working
+
+  or
+
+- start your kernel with the mem=xxx option, where xxx is your
+  real memory minus the memory needed for the buffers.
+  For doing this add an entry in lilo.conf (if you use lilo):
+    append "mem=xxxM"
+  or add a line in your linux.par file (if you use loadlin):
+    mem=xxxM
+
+The second method is by far easier, however it is dangerous
+if more than one driver at a time has the idea to use the memory
+leftover by setting the mem=xxx parameter below the actual
+memory size.
+
+Read also below how to use this memory!
+
+
+
+Driver Options
+==============
+
+You are able to customize the behavior of the driver by giving
+it some options at start time.
+
+default_input, default_norm
+---------------------------
+
+As soon as the driver is loaded, the Buz samples video signals
+from one of its input ports and displays it on its output.
+The driver uses the Composite Input and the video norm PAL for this.
+If you want to change this default behavior, set default_input=1
+(for S-VHS input) or default_norm=1 for NTSC.
+
+v4l_nbufs, v4l_bufsize
+----------------------
+
+In order to make to make full use of the Video for Linux picture
+grabbing facilities of the driver (which are needed by many
+Video for Linux applications), the driver needs a set of
+physically contiguous buffers for grabbing. These parameters
+determine how many buffers of which size the driver will
+allocate at open (the open will fail if it is unable to do so!).
+
+These values do not affect the MJPEG grabbing facilities of the driver,
+they are needed for uncompressed image grabbing only!!!
+
+v4l_nbufs is the number of buffers to allocate, a value of 2 (the default)
+should be sufficient in allmost all cases. Only special applications
+(streaming captures) will need more buffers and then mostly the
+MJPEG capturing features of the Buz will be more apropriate.
+So leave this parameter at it's default unless you know what you do.
+
+The things for v4l_bufsize are more complicated:
+v4l_bufsize is set by default to 128 [KB] which is the maximum
+amount of physically contiguous memory Linux is able to allocate
+without kernel changes. This is sufficient for grabbing 24 bit color images
+up to sizes of approx. 240x180 pixels (240*180*3 = 129600, 128 KB = 131072).
+
+In order to be able to capture bigger images you have either to
+- obtain and install the "big_physarea patch" and set aside
+  the necessary memory during boot time or
+- start your kernel with the mem=xxx option, where xxx is your
+  real memory minus the memory needed for the buffers.
+In that case, usefull settings for v4l_bufsize are
+- 1296 [Kb] for grabbing 24 bit images of max size 768*576
+- 1728 [Kb] for 32bit images of same size (4*768*576 = 1728 Kb!)
+You may reduce these numbers accordingly if you know you are only
+grabbing 720 pixels wide images or NTSC images (max height 480).
+
+In some cases it may happen that Linux isn't even able to obtain
+the default 128 KB buffers. If you don't need uncompressed image
+grabbing at all, set v4l_bufsize to an arbitrary small value (e.g. 4)
+in order to be able to open the video device.
+
+vidmem
+------
+
+The video mem address of the video card.
+The driver has a little database for some videocards
+to determine it from there. If your video card is not in there
+you have either to give it to the driver as a parameter
+or set in in a VIDIOCSFBUF ioctl
+
+The videocard database is contained in the file "videocards.h"
+Gernot Ziegler wants to keep an actual version of that file.
+If your card is not contained in that file, look at
+http://www.lysator.liu.se/~gz/buz/ for an actual version of
+"videocards.h".
+
+triton, natoma
+--------------
+
+The driver tries to detect if you have a triton or natome chipset
+in order to take special messures for these chipsets.
+If this detection fails but you are sure you have such a chipset,
+set the corresponding variable to 1.
+This is a very special option and may go away in the future.
+
+
+
+Programming interface
+=====================
+
+This driver should be fully compliant to Video for Linux, so all
+tools working with Video for Linux should work with (hopefully)
+no problems.
+
+A description of the Video for Linux programming interace can be found at:
+http://roadrunner.swansea.linux.org.uk/v4lapi.shtml
+
+Besides the Video for Linux interface, the driver has a "proprietary"
+interface for accessing the Buz's MJPEG capture and playback facilities.
+
+The ioctls for that interface are as follows:
+
+BUZIOC_G_PARAMS
+BUZIOC_S_PARAMS
+
+Get and set the parameters of the buz. The user should allways
+do a BUZIOC_G_PARAMS (with a struct buz_params) to obtain the default
+settings, change what he likes and then make a BUZIOC_S_PARAMS call.
+A typical application should at least set the members
+input, norm and decimation of the struct buz_params.
+For a full description of all members see "buz.h"
+
+BUZIOC_REQBUFS
+
+Before being able to capture/playback, the user has to request
+the buffers he is wanting to use. Fill the structure
+buz_requestbuffers with the size (recommended: 256*1024) and
+the number (recommended 32 up to 256). There are no such restrictions
+as for the Video for Linux buffers, you should LEAVE SUFFICIENT
+MEMORY for your system however, else strange things will happen ....
+On return, the buz_requestbuffers structure contains number and
+size of the actually allocated buffers.
+You should use these numbers for doing a mmap of the buffers
+into the user space.
+The BUZIOC_REQBUFS ioctl also makes it happen, that the next mmap
+maps the MJPEG buffer instead of the V4L buffers.
+
+BUZIOC_QBUF_CAPT
+BUZIOC_QBUF_PLAY
+
+Queue a buffer for capture or playback. The first call also starts
+streaming capture. When streaming capture is going on, you may
+only queue further buffers or issue syncs until streaming
+capture is switched off again with a argument of -1 to
+a BUZIOC_QBUF_CAPT/BUZIOC_QBUF_PLAY ioctl.
+
+BUZIOC_SYNC
+
+Issue this ioctl when all buffers are queued. This ioctl will
+block until the first buffer becomes free for saving its
+data to disk (after BUZIOC_QBUF_CAPT) or for reuse (after BUZIOC_QBUF_PLAY).
+
+BUZIOC_G_STATUS
+
+Get the status of the input lines (video source connected/norm).
+This ioctl may be subject to change.
+
+
+
+
+
+See the examples directory delivered with this driver
+for actual coding examples!
diff -u --recursive --new-file v2.3.9/linux/Documentation/video4linux/bttv/PROBLEMS linux/Documentation/video4linux/bttv/PROBLEMS
--- v2.3.9/linux/Documentation/video4linux/bttv/PROBLEMS	Sun Aug 23 13:32:25 1998
+++ linux/Documentation/video4linux/bttv/PROBLEMS	Mon Jul  5 20:04:47 1999
@@ -17,9 +17,9 @@
X   If this 64MB area overlaps the IO memory of the Bt848 you also have to
X   remap this. E.g.: insmod bttv vidmem=0xfb0 remap=0xfa0
X 
-  If the videomemory is found at the right place and there are no address
-  conflicts but still no picture (or the computer even crashes.),
-  try disabling features of your PCI chipset in the BIOS Setup.
+  If the video memory is found at the right place and there are no address
+  conflicts but still no picture (or the computer even crashes),
+  try disabling features of your PCI chipset in the BIOS setup.
X 
X   Frank Kapahnke <fr...@kapahnke.prima.ruhr.de> also reported that problems
X   with his S3 868 went away when he upgraded to XFree 3.2.
@@ -50,13 +50,13 @@
X   
X   Disable backing store by starting X with the option "-bs"
X 
-- When using 32bpp in XFree or 24+8bpp mode in AccelX 3.1 the system
+- When using 32 bpp in XFree or 24+8bpp mode in AccelX 3.1 the system
X   can sometimes lock up if you use more than 1 bt848 card at the same time.
X   You will always get pixel errors when e.g. using more than 1 card in full
X   screen mode. Maybe we need something faster than the PCI bus ...
X 
X 
-- Some S3 cards and the Matrox Mystique will produce pixel erros with
-  full resolution in 32bit mode.
+- Some S3 cards and the Matrox Mystique will produce pixel errors with
+  full resolution in 32-bit mode.
X 
-- Some video cards have problems with Accelerated X 4.1
\ No newline at end of file
+- Some video cards have problems with Accelerated X 4.1
diff -u --recursive --new-file v2.3.9/linux/Documentation/video4linux/bttv/README.RADIO linux/Documentation/video4linux/bttv/README.RADIO
--- v2.3.9/linux/Documentation/video4linux/bttv/README.RADIO	Sun Aug 23 13:32:25 1998
+++ linux/Documentation/video4linux/bttv/README.RADIO	Mon Jul  5 20:04:47 1999
@@ -6,7 +6,7 @@
X 
X So you should have TV with (stereo) sound now.  Radio does _not_ work.
X It probably does not work with sat receivers. I can't test this and
-therefore hav'nt added support for it yet. If someone needs this and
+therefore have not added support for it yet. If someone needs this and
X can help testing the sat stuff, drop me a note.
X 
X   Gerd
diff -u --recursive --new-file v2.3.9/linux/Documentation/video4linux/bttv/THANKS linux/Documentation/video4linux/bttv/THANKS
--- v2.3.9/linux/Documentation/video4linux/bttv/THANKS	Sun Aug 23 13:32:25 1998
+++ linux/Documentation/video4linux/bttv/THANKS	Mon Jul  5 20:04:47 1999
@@ -17,7 +17,7 @@
X   components on their cards. (E.g. how the tuner type is detected)
X   Without their card I could not have debugged the NTSC mode.
X 	
-- Hauppauge for telling how the sound input is selected and what compenents
+- Hauppauge for telling how the sound input is selected and what components
X   they do and will use on their radio cards.
X   Also many thanks for faxing me the FM1216 data sheet.
X 
diff -u --recursive --new-file v2.3.9/linux/MAINTAINERS linux/MAINTAINERS
--- v2.3.9/linux/MAINTAINERS	Wed Jun 30 13:38:18 1999
+++ linux/MAINTAINERS	Tue Jul  6 19:16:55 1999
@@ -16,8 +16,8 @@
X 	SMC etherpower for that.)
X 
X 3.	Make sure your changes compile correctly in multiple
-	configurations. In paticular check changes work both as a module
-	and built into the kernel.
+	configurations. In particular check that changes work both as a
+	module and built into the kernel.
X 
X 4.	When you are happy with a change make it generally available for
X 	testing and await feedback.
@@ -28,7 +28,7 @@
X 	and variable names.  These aren't as silly as they seem. One
X 	job the maintainers (and especially Linus) do is to keep things
X 	looking the same. Sometimes this means that the clever hack in
-	your driver to get around a problem actual needs to become a
+	your driver to get around a problem actually needs to become a
X 	generalized kernel feature ready for next time. See 
X 	Documentation/CodingStyle for guidance here.
X 
@@ -49,8 +49,8 @@
X 
X Maintainers List (try to look for most precise areas first)
X 
-Note: For the hard of thinking, this list is meant to remain in Alphabetical
-order. If you could add yourselves to it in Alphabetical order that would
+Note: For the hard of thinking, this list is meant to remain in alphabetical
+order. If you could add yourselves to it in alphabetical order that would
X so much easier [Ed]
X 
X P: Person
@@ -163,6 +163,12 @@
X W:	http://www.ife.ee.ethz.ch/~sailer/ham/ham.html
X S:	Maintained
X 
+BERKSHIRE PRODUCTS PC WATCHDOG DRIVER
+P:	Kenji Hollis
+M:	ke...@bitgate.com
+W:	http://ftp.bitgate.com/pcwd/
+S:	Maintained
+
X BUSLOGIC SCSI DRIVER
X P:	Leonard N. Zubkoff
X M:	Leonard N. Zubkoff <l...@dandelion.com>
@@ -271,6 +277,12 @@
X L:	linux...@i-connect.net, linux...@vger.rutgers.edu
X S:	Maintained
X 
+COMPAQ SMART2 RAID DRIVER
+P:	Charles White	
+M:	Charles White <arr...@compaq.com>
+L:	compaqa...@yps.org	
+S:	Maintained
+
X EATA ISA/EISA/PCI SCSI DRIVER
X P:	Dario Ballabio
X M:	da...@milano.europe.dg.com
@@ -579,6 +591,26 @@
X L:	linux-...@vger.rutgers.edu
X S:	Maintained
X 
+OLYMPIC NETWORK DRIVER
+P:	Peter De Shrijver
+M:	p...@ace.ulyssis.sutdent.kuleuven.ac.be	
+P:	Mike Phillips
+M:	phi...@amtrak.com
+L:	linu...@vger.rutgers.edu
+L:	linu...@emissary.aus-etc.com
+W:	http://www.linuxtr.net
+S:	Maintained
+
+OLYMPIC NETWORK DRIVER
+P:	Peter De Shrijver
+M:	p...@ace.ulyssis.sutdent.kuleuven.ac.be	
+P:	Mike Phillips
+M:	phi...@amtrak.com
+L:	linu...@vger.rutgers.edu
+L:	linu...@emissary.aus-etc.com
+W:	http://www.linuxtr.net
+S:	Maintained
+
X OPL3-SA2, SA3, and SAx DRIVER
X P:	Scott Murray
X M:	sco...@interlog.com
@@ -645,7 +677,7 @@
X 
X REAL TIME CLOCK DRIVER
X P:	Paul Gortmaker
-M	gpg...@rsphy1.anu.edu.au
+M:	gpg...@rsphy1.anu.edu.au
X L:	linux-...@vger.rutgers.edu
X S:	Maintained
X 
@@ -697,9 +729,10 @@
X S:	Maintained
X 
X SMB FILESYSTEM
-P:	Volker Lendecke
-M:	v...@kki.org
-L:	sa...@listproc.anu.edu.au
+P:	Andrew Tridgell
+M:	tri...@samba.org
+W:	http://samba.org/
+L:	sa...@samba.org
X S:	Maintained
X 
X SMP: (except SPARC)
diff -u --recursive --new-file v2.3.9/linux/Makefile linux/Makefile
--- v2.3.9/linux/Makefile	Wed Jun 30 13:38:18 1999
+++ linux/Makefile	Thu Jul  1 10:54:31 1999
@@ -1,6 +1,6 @@
X VERSION = 2
X PATCHLEVEL = 3
-SUBLEVEL = 9
+SUBLEVEL = 10
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/)
@@ -351,8 +351,7 @@
X 
X clean:	archclean
X 	rm -f kernel/ksyms.lst include/linux/compile.h
-	rm -f core `find . -name '*.[oas]' ! -regex '.*lxdialog/.*' \
-		! -regex '.*ksymoops/.*' -print`
+	rm -f core `find . -name '*.[oas]' ! -regex '.*lxdialog/.*' -print`
X 	rm -f core `find . -type f -name 'core' -print`
X 	rm -f core `find . -name '.*.flags' -print`
X 	rm -f vmlinux System.map
@@ -376,7 +375,6 @@
X 	rm -f .version .config* config.in config.old
X 	rm -f scripts/tkparse scripts/kconfig.tk scripts/kconfig.tmp
X 	rm -f scripts/lxdialog/*.o scripts/lxdialog/lxdialog
-	rm -f scripts/ksymoops/*.o scripts/ksymoops/ksymoops
X 	rm -f .menuconfig.log
X 	rm -f include/asm
X 	rm -rf include/config
diff -u --recursive --new-file v2.3.9/linux/README linux/README
--- v2.3.9/linux/README	Sun May 30 10:17:43 1999
+++ linux/README	Thu Jul  1 10:54:08 1999
@@ -9,9 +9,9 @@
X bugs.  It is *strongly* recommended that you back up the previous kernel
X before installing any new 2.3.xx release.
X 
-If you need to use a proven and stable Linux kernel, please use 1.2.13,
-2.0.36 or 2.2.xx.  All features which will be in the 2.3.xx releases will
-be contained in 2.4.xx when the code base has stabilized again.
+If you need to use a proven and stable Linux kernel, please use 2.0.37
+or 2.2.xx.  All features which will be in the 2.3.xx releases will be
+contained in 2.4.xx when the code base has stabilized again. 
X 
X If you decide to use 2.3, it is recommended that you join the kernel mailing
X list.  To do this, e-mail majo...@vger.rutgers.edu, and put in the body
@@ -105,7 +105,7 @@
X 
X SOFTWARE REQUIREMENTS
X 
-   Compiling and running the 2.3.x kernels requires up-to-date
+   Compiling and running the 2.3.xx kernels requires up-to-date
X    versions of various software packages.  Consult
X    ./Documentation/Changes for the minimum version numbers required
X    and how to get updates for these packages.  Beware that using
diff -u --recursive --new-file v2.3.9/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v2.3.9/linux/arch/alpha/config.in	Wed Jun 30 13:38:18 1999
+++ linux/arch/alpha/config.in	Thu Jul  1 14:22:56 1999
@@ -188,13 +188,7 @@
X tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
X tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
X tristate 'Kernel support for Linux/Intel ELF binaries' CONFIG_BINFMT_EM86
-tristate 'Parallel port support' CONFIG_PARPORT
-if [ "$CONFIG_PARPORT" != "n" ]; then
-  dep_tristate '  PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
-  if [ "$CONFIG_PARPORT_PC" != "n" ]; then
-    bool '   Support foreign hardware' CONFIG_PARPORT_OTHER
-  fi
-fi
+source drivers/misc/Config.in
X endmenu
X 
X source drivers/pnp/Config.in
diff -u --recursive --new-file v2.3.9/linux/arch/alpha/kernel/ptrace.c linux/arch/alpha/kernel/ptrace.c
--- v2.3.9/linux/arch/alpha/kernel/ptrace.c	Mon Jun  7 11:15:33 1999
+++ linux/arch/alpha/kernel/ptrace.c	Sun Jul  4 13:41:08 1999
@@ -135,242 +135,18 @@
X 	return 0;
X }
X 
-/*
- * This routine gets a long from any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- */
-static unsigned long
-get_long(struct task_struct * tsk, struct vm_area_struct * vma,
-	 unsigned long addr)
-{
-	pgd_t * pgdir;
-	pmd_t * pgmiddle;
-	pte_t * pgtable;
-	unsigned long page;
-
-	DBG(DBG_MEM_ALL, ("getting long at 0x%lx\n", addr));
- repeat:
-	pgdir = pgd_offset(vma->vm_mm, addr);
-	if (pgd_none(*pgdir)) {
-		handle_mm_fault(tsk, vma, addr, 0);
-		goto repeat;
-	}
-	if (pgd_bad(*pgdir)) {
-		printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
-		pgd_clear(pgdir);
-		return 0;
-	}
-	pgmiddle = pmd_offset(pgdir, addr);
-	if (pmd_none(*pgmiddle)) {
-		handle_mm_fault(tsk, vma, addr, 0);
-		goto repeat;
-	}
-	if (pmd_bad(*pgmiddle)) {
-		printk("ptrace: bad page middle %08lx\n", pmd_val(*pgmiddle));
-		pmd_clear(pgmiddle);
-		return 0;
-	}
-	pgtable = pte_offset(pgmiddle, addr);
-	if (!pte_present(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, 0);
-		goto repeat;
-	}
-	page = pte_page(*pgtable);
-	/* this is a hack for non-kernel-mapped video buffers and similar */
-	if (MAP_NR(page) >= max_mapnr)
-		return 0;
-	page += addr & ~PAGE_MASK;
-	return *(unsigned long *) page;
-}
-
-/*
- * This routine puts a long into any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- *
- * Now keeps R/W state of page so that a text page stays readonly
- * even if a debugger scribbles breakpoints into it.  -M.U-
- */
-static void
-put_long(struct task_struct * tsk, struct vm_area_struct * vma,
-	 unsigned long addr, unsigned long data)
+static inline int
+read_int(struct task_struct *task, unsigned long addr, int * data)
X {
-	pgd_t *pgdir;
-	pmd_t *pgmiddle;
-	pte_t *pgtable;
-	unsigned long page;
-
- repeat:
-	pgdir = pgd_offset(vma->vm_mm, addr);
-	if (!pgd_present(*pgdir)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
-	}
-	if (pgd_bad(*pgdir)) {
-		printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
-		pgd_clear(pgdir);
-		return;
-	}
-	pgmiddle = pmd_offset(pgdir, addr);
-	if (pmd_none(*pgmiddle)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
-	}
-	if (pmd_bad(*pgmiddle)) {
-		printk("ptrace: bad page middle %08lx\n", pmd_val(*pgmiddle));
-		pmd_clear(pgmiddle);
-		return;
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 02'
echo 'File patch-2.3.10 is continued in part 03'
echo 03 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 07 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
X 
X #if PDC202XX_DECODE_REGISTER_INFO
X 	pci_read_config_byte(dev, (drive_pci), &AP);
@@ -436,8 +426,6 @@
X 	printk("0x%08x\n", drive_conf);
X #endif /* PDC202XX_DEBUG_DRIVE_INFO */
X 
-chipset_is_set:
-
X 	return ((int)	((id->dma_ultra >> 11) & 3) ? ide_dma_on :
X 			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
X 			((id->dma_mword >> 8) & 7) ? ide_dma_on : 
@@ -533,7 +521,7 @@
X 		(primary_mode & 1) ? "MASTER" : "PCI",
X 		(secondary_mode & 1) ? "MASTER" : "PCI" );
X 
-#if PDC202XX_FORCE_BURST_BIT
+#ifdef PDC202XX_FORCE_BURST_BIT
X 	if (!(udma_speed_flag & 1)) {
X 		printk("%s: FORCING BURST BIT 0x%02x -> 0x%02x ", name, udma_speed_flag, (udma_speed_flag|1));
X 		outb(udma_speed_flag|1, high_16 + 0x001f);
@@ -541,7 +529,7 @@
X 	}
X #endif /* PDC202XX_FORCE_BURST_BIT */
X 
-#if PDC202XX_FORCE_MASTER_MODE
+#ifdef PDC202XX_FORCE_MASTER_MODE
X 	if (!(primary_mode & 1)) {
X 		printk("%s: FORCING PRIMARY MODE BIT 0x%02x -> 0x%02x ",
X 			name, primary_mode, (primary_mode|1));
diff -u --recursive --new-file v2.3.9/linux/drivers/block/piix.c linux/drivers/block/piix.c
--- v2.3.9/linux/drivers/block/piix.c	Wed Jun  2 22:21:51 1999
+++ linux/drivers/block/piix.c	Sat Jul  3 10:45:04 1999
@@ -1,5 +1,5 @@
X /*
- * linux/drivers/block/piix.c	Version 0.23	May 29, 1999
+ * linux/drivers/block/piix.c	Version 0.24	June 28, 1999
X  *
X  *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
X  *  Copyright (C) 1998-1999 Andre Hedrick, Author and Maintainer
@@ -44,8 +44,15 @@
X  * pci_read_config_word(HWIF(drive)->pci_dev, 0x48, ®48);
X  * pci_read_config_word(HWIF(drive)->pci_dev, 0x4a, ®4a);
X  *
+ * #if 0
+ * int err;
+ * err = ide_config_drive_speed(drive, speed);
+ * (void) ide_config_drive_speed(drive, speed);
+ * #else
+ * #endif
X  */
X 
+#include <linux/config.h>
X #include <linux/types.h>
X #include <linux/kernel.h>
X #include <linux/ioport.h>
@@ -62,6 +69,7 @@
X 
X extern char *ide_xfer_verbose (byte xfer_rate);
X 
+#ifdef CONFIG_BLK_DEV_PIIX_TUNING
X /*
X  *
X  */
@@ -91,6 +99,7 @@
X 			return 0;
X 	}
X }
+#endif /* CONFIG_BLK_DEV_PIIX_TUNING */
X 
X /*
X  *  Based on settings done by AMI BIOS
@@ -111,11 +120,7 @@
X 				    { 2, 1 },
X 				    { 2, 3 }, };
X 
-#if 1
X 	pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
-#else
-	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
-#endif
X 	pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data);
X 	if (is_slave) {
X 		master_data = master_data | 0x4000;
@@ -142,6 +147,8 @@
X 	restore_flags(flags);
X }
X 
+#ifdef CONFIG_BLK_DEV_PIIX_TUNING
+
X static int piix_config_drive_for_dma(ide_drive_t *drive, int ultra)
X {
X 	struct hd_driveid *id = drive->id;
@@ -246,17 +253,13 @@
X 		}
X 		speed = XFER_SW_DMA_2;
X         } else {
-#if 0
-		speed = XFER_PIO_0;
-#else
X 		speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
-#endif
X 	}
X 
X 	restore_flags(flags);
X 	piix_tune_drive(drive, piix_dma_2_pio(speed));
X 
-	(void) ide_wait_cmd(drive, WIN_SETFEATURES, speed, SETFEATURES_XFER, 0, NULL);
+	(void) ide_config_drive_speed(drive, speed);
X 
X #if PIIX_DEBUG_DRIVE_INFO
X 	printk("%s: %s drive%d ",
@@ -284,11 +287,19 @@
X 	/* Other cases are done by generic IDE-DMA code. */
X 	return ide_dmaproc(func, drive);
X }
+#endif /* CONFIG_BLK_DEV_PIIX_TUNING */
X 
X void ide_init_piix (ide_hwif_t *hwif)
X {
X 	hwif->tuneproc = &piix_tune_drive;
+#ifdef CONFIG_BLK_DEV_PIIX_TUNING
X 	if (hwif->dma_base) {
X 		hwif->dmaproc = &piix_dmaproc;
+	} else
+#endif /* CONFIG_BLK_DEV_PIIX_TUNING */
+	{
+		hwif->drives[0].autotune = 1;
+		hwif->drives[1].autotune = 1;
X 	}
+
X }
diff -u --recursive --new-file v2.3.9/linux/drivers/block/smart1,2.h linux/drivers/block/smart1,2.h
--- v2.3.9/linux/drivers/block/smart1,2.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/block/smart1,2.h	Mon Jul  5 19:52:52 1999
@@ -0,0 +1,274 @@
+/*
+ *    Disk Array driver for Compaq SMART2 Controllers
+ *    Copyright 1998 Compaq Computer Corporation
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *    NON INFRINGEMENT.  See the GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *    Questions/Comments/Bugfixes to arr...@compaq.com
+ *
+ *    If you want to make changes, improve or add functionality to this
+ *    driver, you'll probably need the Compaq Array Controller Interface
+ *    Specificiation (Document number ECG086/1198)
+ */
+
+/*
+ * This file contains the controller communication implementation for
+ * Compaq SMART-1 and SMART-2 controllers.  To the best of my knowledge,
+ * this should support:
+ *
+ *  PCI:
+ *  SMART-2/P, SMART-2DH, SMART-2SL, SMART-221, SMART-3100ES, SMART-3200
+ *  Integerated SMART Array Controller, SMART-4200, SMART-4250ES
+ *
+ *  EISA:
+ *  SMART-2/E, SMART, IAES, IDA-2, IDA
+ */
+
+/*
+ * Memory mapped FIFO interface (SMART 42xx cards)
+ */
+static void smart4_submit_command(ctlr_info_t *h, cmdlist_t *c)
+{
+        writel(c->busaddr, h->vaddr + S42XX_REQUEST_PORT_OFFSET);
+}
+
+/*  
+ *  This card is the oposite of the other cards.  
+ *   0 turns interrupts on... 
+ *   0x08 turns them off... 
+ */
+static void smart4_intr_mask(ctlr_info_t *h, unsigned long val)
+{
+	if (val) 
+	{ /* Turn interrupts on */
+		writel(0, h->vaddr + S42XX_REPLY_INTR_MASK_OFFSET);
+	} else /* Turn them off */
+	{
+        	writel( S42XX_INTR_OFF, 
+			h->vaddr + S42XX_REPLY_INTR_MASK_OFFSET);
+	}
+}
+
+/*
+ *  For this card fifo is full if reading this port returns 0! 
+ * 
+ */ 
+static unsigned long smart4_fifo_full(ctlr_info_t *h)
+{
+	
+        return (~readl(h->vaddr + S42XX_REQUEST_PORT_OFFSET));
+}
+
+/* This type of controller returns -1 if the fifo is empty, 
+ *    Not 0 like the others.
+ *    And we need to let it know we read a value out 
+ */ 
+static unsigned long smart4_completed(ctlr_info_t *h)
+{
+	long register_value 
+		= readl(h->vaddr + S42XX_REPLY_PORT_OFFSET);
+
+	/* Fifo is empty */
+	if( register_value == -1)
+		return 0; 	
+
+	/* Need to let it know we got the reply */
+	/* We do this by writing a 0 to the port we just read from */
+	writel(0, h->vaddr + S42XX_REPLY_PORT_OFFSET);
+
+	return ((unsigned long) register_value); 
+}
+
+ /*
+ *  This hardware returns interrupt pending at a different place and 
+ *  it does not tell us if the fifo is empty, we will have check  
+ *  that by getting a 0 back from the comamnd_completed call. 
+ */
+static unsigned long smart4_intr_pending(ctlr_info_t *h)
+{
+	unsigned long register_value  = 
+		readl(h->vaddr + S42XX_INTR_STATUS);
+
+	if( register_value &  S42XX_INTR_PENDING) 
+		return  FIFO_NOT_EMPTY;	
+	return 0 ;
+}
+
+static struct access_method smart4_access = {
+	smart4_submit_command,
+	smart4_intr_mask,
+	smart4_fifo_full,
+	smart4_intr_pending,
+	smart4_completed,
+};
+
+/*
+ * Memory mapped FIFO interface (PCI SMART2 and SMART 3xxx cards)
+ */
+static void smart2_submit_command(ctlr_info_t *h, cmdlist_t *c)
+{
+	writel(c->busaddr, h->vaddr + COMMAND_FIFO);
+}
+
+static void smart2_intr_mask(ctlr_info_t *h, unsigned long val)
+{
+	writel(val, h->vaddr + INTR_MASK);
+}
+
+static unsigned long smart2_fifo_full(ctlr_info_t *h)
+{
+	return readl(h->vaddr + COMMAND_FIFO);
+}
+
+static unsigned long smart2_completed(ctlr_info_t *h)
+{
+	return readl(h->vaddr + COMMAND_COMPLETE_FIFO);
+}
+
+static unsigned long smart2_intr_pending(ctlr_info_t *h)
+{
+	return readl(h->vaddr + INTR_PENDING);
+}
+
+static struct access_method smart2_access = {
+	smart2_submit_command,
+	smart2_intr_mask,
+	smart2_fifo_full,
+	smart2_intr_pending,
+	smart2_completed,
+};
+
+/*
+ *  IO access for SMART-2/E cards
+ */
+static void smart2e_submit_command(ctlr_info_t *h, cmdlist_t *c)
+{
+	outl(c->busaddr, h->ioaddr + COMMAND_FIFO);
+}
+
+static void smart2e_intr_mask(ctlr_info_t *h, unsigned long val)
+{
+	outl(val, h->ioaddr + INTR_MASK);
+}
+
+static unsigned long smart2e_fifo_full(ctlr_info_t *h)
+{
+	return inl(h->ioaddr + COMMAND_FIFO);
+}
+
+static unsigned long smart2e_completed(ctlr_info_t *h)
+{
+	return inl(h->ioaddr + COMMAND_COMPLETE_FIFO);
+}
+
+static unsigned long smart2e_intr_pending(ctlr_info_t *h)
+{
+	return inl(h->ioaddr + INTR_PENDING);
+}
+
+static struct access_method smart2e_access = {
+	smart2e_submit_command,
+	smart2e_intr_mask,
+	smart2e_fifo_full,
+	smart2e_intr_pending,
+	smart2e_completed,
+};
+
+/*
+ *  IO access for older SMART-1 type cards
+ */
+#define SMART1_SYSTEM_MASK		0xC8E
+#define SMART1_SYSTEM_DOORBELL		0xC8F
+#define SMART1_LOCAL_MASK		0xC8C
+#define SMART1_LOCAL_DOORBELL		0xC8D
+#define SMART1_INTR_MASK		0xC89
+#define SMART1_LISTADDR			0xC90
+#define SMART1_LISTLEN			0xC94
+#define SMART1_TAG			0xC97
+#define SMART1_COMPLETE_ADDR		0xC98
+#define SMART1_LISTSTATUS		0xC9E
+
+#define CHANNEL_BUSY			0x01
+#define CHANNEL_CLEAR			0x02
+
+static void smart1_submit_command(ctlr_info_t *h, cmdlist_t *c)
+{
+	/*
+	 * This __u16 is actually a bunch of control flags on SMART
+	 * and below.  We want them all to be zero.
+	 */
+	c->hdr.size = 0;
+
+	outb(CHANNEL_CLEAR, h->ioaddr + SMART1_SYSTEM_DOORBELL);
+
+	outl(c->busaddr, h->ioaddr + SMART1_LISTADDR);
+	outw(c->size, h->ioaddr + SMART1_LISTLEN);
+
+	outb(CHANNEL_BUSY, h->ioaddr + SMART1_LOCAL_DOORBELL);
+}
+
+static void smart1_intr_mask(ctlr_info_t *h, unsigned long val)
+{
+	if (val == 1) {
+		outb(0xFD, h->ioaddr + SMART1_SYSTEM_DOORBELL);
+		outb(CHANNEL_BUSY, h->ioaddr + SMART1_LOCAL_DOORBELL);
+		outb(0x01, h->ioaddr + SMART1_INTR_MASK);
+		outb(0x01, h->ioaddr + SMART1_SYSTEM_MASK);
+	} else {
+		outb(0, h->ioaddr + 0xC8E);
+	}
+}
+
+static unsigned long smart1_fifo_full(ctlr_info_t *h)
+{
+	unsigned char chan;
+	chan = inb(h->ioaddr + SMART1_SYSTEM_DOORBELL) & CHANNEL_CLEAR;
+	return chan;
+}
+
+static unsigned long smart1_completed(ctlr_info_t *h)
+{
+	unsigned char status;
+	unsigned long cmd;
+
+	if (inb(h->ioaddr + SMART1_SYSTEM_DOORBELL) & CHANNEL_BUSY) {
+		outb(CHANNEL_BUSY, h->ioaddr + SMART1_SYSTEM_DOORBELL);
+
+		cmd = inl(h->ioaddr + SMART1_COMPLETE_ADDR);
+		status = inb(h->ioaddr + SMART1_LISTSTATUS);
+
+		outb(CHANNEL_CLEAR, h->ioaddr + SMART1_LOCAL_DOORBELL);
+
+		if (cmd) ((cmdlist_t*)bus_to_virt(cmd))->req.hdr.rcode = status;
+	} else {
+		cmd = 0;
+	}
+	return cmd;
+}
+
+static unsigned long smart1_intr_pending(ctlr_info_t *h)
+{
+	unsigned char chan;
+	chan = inb(h->ioaddr + SMART1_SYSTEM_DOORBELL) & CHANNEL_BUSY;
+	return chan;
+}
+
+static struct access_method smart1_access = {
+	smart1_submit_command,
+	smart1_intr_mask,
+	smart1_fifo_full,
+	smart1_intr_pending,
+	smart1_completed,
+};
diff -u --recursive --new-file v2.3.9/linux/drivers/cdrom/aztcd.c linux/drivers/cdrom/aztcd.c
--- v2.3.9/linux/drivers/cdrom/aztcd.c	Wed May 12 13:27:37 1999
+++ linux/drivers/cdrom/aztcd.c	Tue Jul  6 19:05:48 1999
@@ -1087,7 +1087,7 @@
X #ifdef AZT_KERNEL_PRIOR_2_1
X void aztcd_setup(char *str, int *ints)
X #else
-__initfunc(void aztcd_setup(char *str, int *ints))
+void __init aztcd_setup(char *str, int *ints)
X #endif
X {  if (ints[0] > 0)
X       azt_port = ints[1];
@@ -1617,7 +1617,7 @@
X #ifdef AZT_KERNEL_PRIOR_2_1
X int aztcd_init(void)
X #else
-__initfunc(int aztcd_init(void))
+int __init aztcd_init(void)
X #endif
X {       long int count, max_count;
X 	unsigned char result[50];
diff -u --recursive --new-file v2.3.9/linux/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c
--- v2.3.9/linux/drivers/cdrom/cdu31a.c	Wed May 12 13:27:37 1999
+++ linux/drivers/cdrom/cdu31a.c	Tue Jul  6 19:05:48 1999
@@ -3251,10 +3251,10 @@
X /* The different types of disc loading mechanisms supported */
X static const char *load_mech[] __initdata = { "caddy", "tray", "pop-up", "unknown" };
X 
-__initfunc(static void
+static void __init 
X get_drive_configuration(unsigned short base_io,
X                         unsigned char res_reg[],
-                        unsigned int *res_size))
+                        unsigned int *res_size)
X {
X    int retry_count;
X 
@@ -3318,9 +3318,9 @@
X /*
X  * Set up base I/O and interrupts, called from main.c.
X  */
-__initfunc(void
+void __init 
X cdu31a_setup(char *strings,
-	     int  *ints))
+	     int  *ints)
X {
X    if (ints[0] > 0)
X    {
@@ -3349,8 +3349,8 @@
X /*
X  * Initialize the driver.
X  */
-__initfunc(int
-cdu31a_init(void))
+int __init 
+cdu31a_init(void)
X {
X    struct s_sony_drive_config drive_config;
X    unsigned int res_size;
diff -u --recursive --new-file v2.3.9/linux/drivers/cdrom/cm206.c linux/drivers/cdrom/cm206.c
--- v2.3.9/linux/drivers/cdrom/cm206.c	Wed May 12 13:27:37 1999
+++ linux/drivers/cdrom/cm206.c	Tue Jul  6 19:05:48 1999
@@ -1294,7 +1294,7 @@
X    check_region, 15 bits of one port and 6 of another make things
X    likely enough to accept the region on the first hit...
X  */
-__initfunc(int probe_base_port(int base))
+int __init probe_base_port(int base)
X {
X   int b=0x300, e=0x370;		/* this is the range of start addresses */
X   volatile int fool, i;
@@ -1314,7 +1314,7 @@
X 
X #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
X /* Probe for irq# nr. If nr==0, probe for all possible irq's. */
-__initfunc(int probe_irq(int nr)) {
+int __init probe_irq(int nr){
X   int irqs, irq;
X   outw(dc_normal | READ_AHEAD, r_data_control);	/* disable irq-generation */
X   sti(); 
@@ -1328,7 +1328,7 @@
X }
X #endif
X 
-__initfunc(int cm206_init(void))
+int __init cm206_init(void)
X {
X   uch e=0;
X   long int size=sizeof(struct cm206_struct);
@@ -1413,7 +1413,7 @@
X 
X static int cm206[2] = {0,0};	/* for compatible `insmod' parameter passing */
X 
-__initfunc(void parse_options(void))
+void __init parse_options(void)
X {
X   int i;
X   for (i=0; i<2; i++) {
@@ -1447,7 +1447,7 @@
X 
X /* This setup function accepts either `auto' or numbers in the range
X  * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */
-__initfunc(void cm206_setup(char *s, int *p))
+void __init cm206_setup(char *s, int *p)
X {
X   int i;
X   if (!strcmp(s, "auto")) auto_probe=1;
diff -u --recursive --new-file v2.3.9/linux/drivers/cdrom/gscd.c linux/drivers/cdrom/gscd.c
--- v2.3.9/linux/drivers/cdrom/gscd.c	Sat May 15 15:05:36 1999
+++ linux/drivers/cdrom/gscd.c	Tue Jul  6 19:05:48 1999
@@ -194,7 +194,7 @@
X }
X 
X 
-__initfunc(void gscd_setup (char *str, int *ints))
+void __init gscd_setup (char *str, int *ints)
X {
X   if (ints[0] > 0) 
X   {
@@ -851,7 +851,7 @@
X      return;
X }
X 
-__initfunc(int find_drives (void))
+int __init find_drives (void)
X {
X int *pdrv;
X int drvnum;
@@ -902,7 +902,7 @@
X     return drvnum;
X }    
X 
-__initfunc(void init_cd_drive ( int num ))
+void __init init_cd_drive ( int num )
X {
X char resp [50];
X int  i;
@@ -994,7 +994,7 @@
X 
X 
X /* Test for presence of drive and initialize it.  Called only at boot time. */
-__initfunc(int gscd_init (void))
+int __init gscd_init (void)
X {
X    return my_gscd_init ();
X }
@@ -1002,7 +1002,7 @@
X 
X /* This is the common initialisation for the GoldStar drive. */
X /* It is called at boot time AND for module init.           */
-__initfunc(int my_gscd_init (void))
+int __init my_gscd_init (void)
X {
X int i;
X int result;
diff -u --recursive --new-file v2.3.9/linux/drivers/cdrom/isp16.c linux/drivers/cdrom/isp16.c
--- v2.3.9/linux/drivers/cdrom/isp16.c	Tue Dec  2 11:41:44 1997
+++ linux/drivers/cdrom/isp16.c	Tue Jul  6 19:05:48 1999
@@ -77,8 +77,8 @@
X #define ISP16_OUT(p,b) (outb(isp16_ctrl,ISP16_CTRL_PORT), outb(b,p))
X 
X 
-__initfunc(void
-isp16_setup(char *str, int *ints))
+void __init 
+isp16_setup(char *str, int *ints)
X {
X   if ( ints[0] > 0 )
X     isp16_cdrom_base = ints[1];
@@ -94,8 +94,8 @@
X  *  ISP16 initialisation.
X  *
X  */
-__initfunc(int
-isp16_init(void))
+int __init 
+isp16_init(void)
X {
X   u_char expected_drive;
X 
@@ -144,8 +144,8 @@
X   return(0);
X }
X 
-__initfunc(static short
-isp16_detect(void))
+static short __init 
+isp16_detect(void)
X {
X 
X   if ( isp16_c929__detect() >= 0 )
@@ -154,8 +154,8 @@
X     return(isp16_c928__detect());
X }
X 
-__initfunc(static short
-isp16_c928__detect(void))
+static short __init 
+isp16_c928__detect(void)
X {
X   u_char ctrl;
X   u_char enable_cdrom;
@@ -203,8 +203,8 @@
X   return(i);
X }
X 
-__initfunc(static short
-isp16_c929__detect(void))
+static short __init 
+isp16_c929__detect(void)
X {
X   u_char ctrl;
X   u_char tmp;
@@ -230,8 +230,8 @@
X   return(2);
X }
X 
-__initfunc(static short
-isp16_cdi_config(int base, u_char drive_type, int irq, int dma))
+static short __init 
+isp16_cdi_config(int base, u_char drive_type, int irq, int dma)
X {
X   u_char base_code;
X   u_char irq_code;
diff -u --recursive --new-file v2.3.9/linux/drivers/cdrom/mcd.c linux/drivers/cdrom/mcd.c
--- v2.3.9/linux/drivers/cdrom/mcd.c	Wed May 12 13:27:37 1999
+++ linux/drivers/cdrom/mcd.c	Tue Jul  6 19:05:48 1999
@@ -230,8 +230,7 @@
X };
X 
X 
-
-__initfunc(void mcd_setup(char *str, int *ints))
+void __init mcd_setup(char *str, int *ints)
X {
X    if (ints[0] > 0)
X       mcd_port = ints[1];
@@ -1155,7 +1154,7 @@
X  * Test for presence of drive and initialize it.  Called at boot time.
X  */
X 
-__initfunc(int mcd_init(void))
+int __init mcd_init(void)
X {
X 	int count;
X 	unsigned char result[3];
diff -u --recursive --new-file v2.3.9/linux/drivers/cdrom/mcdx.c linux/drivers/cdrom/mcdx.c
--- v2.3.9/linux/drivers/cdrom/mcdx.c	Wed May 12 13:27:37 1999
+++ linux/drivers/cdrom/mcdx.c	Tue Jul  6 19:05:48 1999
@@ -770,7 +770,7 @@
X 	return 1;
X }
X 
-__initfunc(void mcdx_setup(char *str, int *pi))
+void __init mcdx_setup(char *str, int *pi)
X {
X 	if (pi[0] > 0) mcdx_drive_map[0][0] = pi[1];
X 	if (pi[0] > 1) mcdx_drive_map[0][1] = pi[2];
@@ -1013,7 +1013,7 @@
X 
X /* Support functions ************************************************/
X 
-__initfunc(int mcdx_init_drive(int drive))
+int __init mcdx_init_drive(int drive)
X {
X 	struct s_version version;
X 	struct s_drive_stuff* stuffp;
@@ -1174,7 +1174,7 @@
X 	return 0;
X }
X 
-__initfunc(int mcdx_init(void))
+int __init mcdx_init(void)
X {
X 	int drive;
X #ifdef MODULE
diff -u --recursive --new-file v2.3.9/linux/drivers/cdrom/optcd.c linux/drivers/cdrom/optcd.c
--- v2.3.9/linux/drivers/cdrom/optcd.c	Wed May 12 13:27:37 1999
+++ linux/drivers/cdrom/optcd.c	Tue Jul  6 19:05:48 1999
@@ -1966,7 +1966,7 @@
X 
X /* Returns 1 if a drive is detected with a version string
X    starting with "DOLPHIN". Otherwise 0. */
-__initfunc(static int version_ok(void))
+static int __init version_ok(void)
X {
X 	char devname[100];
X 	int count, i, ch, status;
@@ -2022,7 +2022,7 @@
X 
X 
X /* Get kernel parameter when used as a kernel driver */
-__initfunc(void optcd_setup(char *str, int *ints))
+void __init optcd_setup(char *str, int *ints)
X {
X 	if (ints[0] > 0)
X 		optcd_port = ints[1];
@@ -2030,7 +2030,7 @@
X 
X /* Test for presence of drive and initialize it. Called at boot time
X    or during module initialisation. */
-__initfunc(int optcd_init(void))
+int __init optcd_init(void)
X {
X 	int status;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c
--- v2.3.9/linux/drivers/cdrom/sbpcd.c	Sat May 15 15:05:36 1999
+++ linux/drivers/cdrom/sbpcd.c	Tue Jul  6 19:05:48 1999
@@ -3215,7 +3215,7 @@
X }
X #endif FUTURE
X /*==========================================================================*/
-__initfunc(static void check_datarate(void))
+static void __init check_datarate(void)
X {
X 	int i=0;
X 	
@@ -3285,7 +3285,7 @@
X }
X #endif
X /*==========================================================================*/
-__initfunc(static void ask_mail(void))
+static void __init ask_mail(void)
X {
X 	int i;
X 	
@@ -3304,7 +3304,7 @@
X 	msg(DBG_INF,"infobuf =%s\n", msgbuf);
X }
X /*==========================================================================*/
-__initfunc(static int check_version(void))
+static int __init check_version(void)
X {
X 	int i, j, l;
X 	int teac_possible=0;
@@ -3602,7 +3602,7 @@
X /*
X  * probe for the presence of an interface card
X  */
-__initfunc(static int check_card(int port))
+static int __init check_card(int port)
X {
X #undef N_RESPO
X #define N_RESPO 20
@@ -3706,7 +3706,7 @@
X /*
X  * probe for the presence of drives on the selected controller
X  */
-__initfunc(static int check_drives(void))
+static int __init check_drives(void)
X {
X 	int i, j;
X 	
@@ -5458,9 +5458,9 @@
X  *
X  */
X #if (SBPCD_ISSUE-1)
-__initfunc(static void sbpcd_setup(const char *s, int *p))
+static void __init sbpcd_setup(const char *s, int *p)
X #else
-__initfunc(void sbpcd_setup(const char *s, int *p))
+void __init sbpcd_setup(const char *s, int *p)
X #endif
X {
X 	setup_done++;
@@ -5512,7 +5512,7 @@
X  *        port 0x330, we have to use an offset of 8; so, the real CDROM port
X  *        address is 0x338.
X  */
-__initfunc(static int config_spea(void))
+static int __init config_spea(void)
X {
X 	/*
X          * base address offset between configuration port and CDROM port,
@@ -5571,7 +5571,7 @@
X #ifdef MODULE
X int init_module(void)
X #else
-__initfunc(int SBPCD_INIT(void))
+int __init SBPCD_INIT(void)
X #endif MODULE
X {
X 	int i=0, j=0;
diff -u --recursive --new-file v2.3.9/linux/drivers/cdrom/sjcd.c linux/drivers/cdrom/sjcd.c
--- v2.3.9/linux/drivers/cdrom/sjcd.c	Wed May 12 13:27:37 1999
+++ linux/drivers/cdrom/sjcd.c	Tue Jul  6 19:05:48 1999
@@ -163,7 +163,7 @@
X  * Set up device, i.e., use command line data to set
X  * base address.
X  */
-__initfunc(void sjcd_setup( char *str, int *ints ))
+void __init sjcd_setup( char *str, int *ints )
X {
X    if (ints[0] > 0)
X       sjcd_base = ints[1];
@@ -1457,7 +1457,7 @@
X  * Test for presence of drive and initialize it. Called at boot time.
X  * Probe cdrom, find out version and status.
X  */
-__initfunc(int sjcd_init( void )){
+int __init sjcd_init( void ){
X   int i;
X 
X   printk(KERN_INFO "SJCD: Sanyo CDR-H94A cdrom driver version %d.%d.\n", SJCD_VERSION_MAJOR,
diff -u --recursive --new-file v2.3.9/linux/drivers/cdrom/sonycd535.c linux/drivers/cdrom/sonycd535.c
--- v2.3.9/linux/drivers/cdrom/sonycd535.c	Wed May 26 09:31:44 1999
+++ linux/drivers/cdrom/sonycd535.c	Tue Jul  6 19:05:48 1999
@@ -1486,8 +1486,8 @@
X /*
X  * Initialize the driver.
X  */
-__initfunc(int
-sony535_init(void))
+int __init 
+sony535_init(void)
X {
X 	struct s535_sony_drive_config drive_config;
X 	Byte cmd_buff[3];
@@ -1655,8 +1655,8 @@
X  *
X  * the address value has to be the existing CDROM port address.
X  */
-__initfunc(void
-sonycd535_setup(char *strings, int *ints))
+void __init 
+sonycd535_setup(char *strings, int *ints)
X {
X 	/* if IRQ change and default io base desired,
X 	 * then call with io base of 0
diff -u --recursive --new-file v2.3.9/linux/drivers/char/Config.in linux/drivers/char/Config.in
--- v2.3.9/linux/drivers/char/Config.in	Wed Jun 30 13:38:19 1999
+++ linux/drivers/char/Config.in	Tue Jul  6 19:16:55 1999
@@ -28,6 +28,9 @@
X       tristate 'Digiboard PC/Xx Support' CONFIG_DIGI
X    fi
X    tristate 'Cyclades async mux support' CONFIG_CYCLADES
+   if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_CYCLADES" != "n" ]; then
+      bool '  Cyclades-Z interrupt mode operation (EXPERIMENTAL)' CONFIG_CYZ_INTR
+   fi
X    bool 'Stallion multiport serial support' CONFIG_STALDRV
X    if [ "$CONFIG_STALDRV" = "y" ]; then
X      tristate '  Stallion EasyIO or EC8/32 support' CONFIG_STALLION
@@ -52,8 +55,9 @@
X if [ "$CONFIG_PARPORT" != "n" ]; then
X   dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
X   if [ "$CONFIG_PRINTER" != "n" ]; then
-    bool '  Support IEEE1284 status readback' CONFIG_PRINTER_READBACK
+    bool '  Support for console on line printer' CONFIG_LP_CONSOLE
X   fi
+  dep_tristate 'Support for user-space parallel port device drivers' CONFIG_PPDEV $CONFIG_PARPORT
X fi
X 
X bool 'Mouse Support (not serial mice)' CONFIG_MOUSE
@@ -79,6 +83,9 @@
X     comment '   from the tpqic02-support package.  It is available at'
X     comment '   metalab.unc.edu or ftp://titus.cfw.com/pub/Linux/util/'
X   fi
+  dep_tristate 'Zoran ZR36057/36060 support' CONFIG_VIDEO_ZORAN $CONFIG_VIDEO_DEV
+  dep_tristate ' Include support for Iomega Buz' CONFIG_VIDEO_BUZ $CONFIG_VIDEO_ZORAN
+  dep_tristate '  Include support for LML33' CONFIG_VIDEO_LML33 $CONFIG_VIDEO_ZORAN
X fi
X 
X bool 'Watchdog Timer Support'	CONFIG_WATCHDOG
@@ -111,6 +118,7 @@
X 
X tristate 'Video For Linux' CONFIG_VIDEO_DEV
X if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
+  dep_tristate 'ADS Cadet AM/FM Tuner' CONFIG_RADIO_CADET $CONFIG_VIDEO_DEV
X   dep_tristate 'AIMSlab RadioTrack (aka RadioReveal) support' CONFIG_RADIO_RTRACK $CONFIG_VIDEO_DEV
X   if [ "$CONFIG_RADIO_RTRACK" = "y" ]; then
X     hex '  RadioTrack i/o port (0x20f or 0x30f)' CONFIG_RADIO_RTRACK_PORT 20f
@@ -123,11 +131,14 @@
X   if [ "$CONFIG_RADIO_AZTECH" = "y" ]; then
X     hex '  Aztech/Packard Bell I/O port (0x350 or 0x358)' CONFIG_RADIO_AZTECH_PORT 350
X   fi
-  dep_tristate 'ADS Cadet AM/FM Tuner' CONFIG_RADIO_CADET $CONFIG_VIDEO_DEV
-  dep_tristate 'Miro PCM20 Radio' CONFIG_RADIO_MIROPCM20 $CONFIG_VIDEO_DEV
X   dep_tristate 'GemTek Radio Card support' CONFIG_RADIO_GEMTEK $CONFIG_VIDEO_DEV
X   if [ "$CONFIG_RADIO_GEMTEK" = "y" ]; then
X     hex '  GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)' CONFIG_RADIO_GEMTEK_PORT 34c
+  fi
+  dep_tristate 'Miro PCM20 Radio' CONFIG_RADIO_MIROPCM20 $CONFIG_VIDEO_DEV
+  dep_tristate 'TerraTec ActiveRadio ISA Standalone' CONFIG_RADIO_TERRATEC $CONFIG_VIDEO_DEV
+  if [ "$CONFIG_RADIO_TERRATEC" = "y" ]; then
+    hex '  Terratec i/o port (normally 0x590)' CONFIG_RADIO_TERRATEC_PORT 590
X   fi
X   if [ "$CONFIG_PCI" != "n" ]; then
X     dep_tristate 'BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV
diff -u --recursive --new-file v2.3.9/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.3.9/linux/drivers/char/Makefile	Sat May 22 15:02:48 1999
+++ linux/drivers/char/Makefile	Tue Jul  6 19:16:55 1999
@@ -356,6 +356,30 @@
X   endif
X endif
X 
+ifeq ($(CONFIG_VIDEO_ZORAN),y)
+L_OBJS += buz.o
+else
+  ifeq ($(CONFIG_VIDEO_LML33),m)
+    M_OBJS += buz.o
+  endif
+endif
+
+ifeq ($(CONFIG_VIDEO_LML33),y)
+L_OBJS += bt856.o bt819.o
+else
+  ifeq ($(CONFIG_VIDEO_LML33),m)
+    M_OBJS += bt856.o bt819.o
+  endif
+endif
+
+ifeq ($(CONFIG_VIDEO_BUZ),y)
+L_OBJS += saa7111.o saa7185.o
+else
+  ifeq ($(CONFIG_VIDEO_BUZ),m)
+    M_OBJS += saa7111.o saa7185.o
+  endif
+endif
+
X ifeq ($(CONFIG_VIDEO_PMS),y)
X L_OBJS += pms.o
X else
@@ -372,6 +396,14 @@
X   endif
X endif
X 
+ifeq ($(CONFIG_VIDEO_VINO),y)
+L_OBJS += vino.o
+else
+  ifeq ($(CONFIG_VIDEO_VINO),m)
+  M_OBJS += vino.o
+  endif
+endif
+
X ifeq ($(CONFIG_RADIO_AZTECH),y)
X L_OBJS += radio-aztech.o
X else
@@ -444,6 +476,14 @@
X   endif
X endif                                             
X 
+ifeq ($(CONFIG_RADIO_TERRATEC),y)
+L_OBJS += radio-terratec.o
+else
+  ifeq ($(CONFIG_RADIO_TERRATEC),m)
+  M_OBJS += radio-terratec.o
+  endif
+endif
+
X ifeq ($(CONFIG_QIC02_TAPE),y)
X L_OBJS += tpqic02.o
X else
@@ -466,6 +506,14 @@
X 
X ifdef CONFIG_H8
X LX_OBJS += h8.o
+endif
+
+ifeq ($(CONFIG_PPDEV),y)
+L_OBJS += ppdev.o
+else
+  ifeq ($(CONFIG_PPDEV),m)
+  M_OBJS += ppdev.o
+  endif
X endif
X 
X ifeq ($(L_I2C),y)
diff -u --recursive --new-file v2.3.9/linux/drivers/char/acquirewdt.c linux/drivers/char/acquirewdt.c
--- v2.3.9/linux/drivers/char/acquirewdt.c	Wed Jun  2 11:29:13 1999
+++ linux/drivers/char/acquirewdt.c	Tue Jul  6 19:16:55 1999
@@ -212,7 +212,7 @@
X 
X #endif
X 
-__initfunc(int acq_init(void))
+int __init acq_init(void)
X {
X 	printk("WDT driver for Acquire single board computer initialising.\n");
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/char/adbmouse.c linux/drivers/char/adbmouse.c
--- v2.3.9/linux/drivers/char/adbmouse.c	Mon Jun  7 12:12:22 1999
+++ linux/drivers/char/adbmouse.c	Tue Jul  6 19:16:55 1999
@@ -38,9 +38,7 @@
X #ifdef __powerpc__
X #include <asm/processor.h>
X #endif
-#ifdef __mc68000__
X #include <asm/setup.h>
-#endif
X 
X static struct mouse_status mouse;
X static unsigned char adb_mouse_buttons[16];
@@ -244,7 +242,7 @@
X     ADB_MOUSE_MINOR, "adbmouse", &adb_mouse_fops
X };
X 
-__initfunc(int adb_mouse_init(void))
+int __init adb_mouse_init(void)
X {
X     mouse.active = 0;
X     mouse.ready = 0;
@@ -270,7 +268,7 @@
X  * option, which is about using ADB keyboard buttons to emulate
X  * mouse buttons. -- paulus
X  */
-__initfunc(void adb_mouse_setup(char *str, int *ints))
+void __init adb_mouse_setup(char *str, int *ints)
X {
X 	if (ints[0] >= 1) {
X 		adb_emulate_buttons = ints[1] > 0;
@@ -282,7 +280,6 @@
X }
X 
X #ifdef MODULE
-#include <asm/setup.h>
X 
X int init_module(void)
X {
diff -u --recursive --new-file v2.3.9/linux/drivers/char/amigamouse.c linux/drivers/char/amigamouse.c
--- v2.3.9/linux/drivers/char/amigamouse.c	Mon Aug 24 13:02:43 1998
+++ linux/drivers/char/amigamouse.c	Tue Jul  6 19:16:55 1999
@@ -309,7 +309,7 @@
X 	AMIGAMOUSE_MINOR, "amigamouse", &amiga_mouse_fops
X };
X 
-__initfunc(int amiga_mouse_init(void))
+int __init amiga_mouse_init(void)
X {
X 	if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE))
X 		return -ENODEV;
@@ -333,7 +333,6 @@
X }
X 
X #ifdef MODULE
-#include <asm/setup.h>
X 
X int init_module(void)
X {
diff -u --recursive --new-file v2.3.9/linux/drivers/char/amikeyb.c linux/drivers/char/amikeyb.c
--- v2.3.9/linux/drivers/char/amikeyb.c	Mon Apr 26 13:25:54 1999
+++ linux/drivers/char/amikeyb.c	Tue Jul  6 19:16:55 1999
@@ -295,7 +295,7 @@
X 	}
X }
X 
-__initfunc(int amiga_keyb_init(void))
+int __init amiga_keyb_init(void)
X {
X     if (!AMIGAHW_PRESENT(AMI_KEYBOARD))
X         return -EIO;
@@ -343,6 +343,6 @@
X }
X 
X /* for "kbd-reset" cmdline param */
-__initfunc(void amiga_kbd_reset_setup(char *str, int *ints))
+void __init amiga_kbd_reset_setup(char *str, int *ints)
X {
X }
diff -u --recursive --new-file v2.3.9/linux/drivers/char/atarimouse.c linux/drivers/char/atarimouse.c
--- v2.3.9/linux/drivers/char/atarimouse.c	Mon Aug 24 13:02:43 1998
+++ linux/drivers/char/atarimouse.c	Tue Jul  6 19:16:55 1999
@@ -159,7 +159,7 @@
X     ATARIMOUSE_MINOR, "atarimouse", &atari_mouse_fops
X };
X 
-__initfunc(int atari_mouse_init(void))
+int __init atari_mouse_init(void)
X {
X 	int r;
X 
@@ -182,7 +182,7 @@
X #define	MIN_THRESHOLD 1
X #define	MAX_THRESHOLD 20	/* more seems not reasonable... */
X 
-__initfunc(void atari_mouse_setup( char *str, int *ints ))
+void __init atari_mouse_setup( char *str, int *ints )
X {
X     if (ints[0] < 1) {
X 	printk( "atari_mouse_setup: no arguments!\n" );
diff -u --recursive --new-file v2.3.9/linux/drivers/char/atixlmouse.c linux/drivers/char/atixlmouse.c
--- v2.3.9/linux/drivers/char/atixlmouse.c	Wed May 12 13:27:37 1999
+++ linux/drivers/char/atixlmouse.c	Tue Jul  6 19:16:55 1999
@@ -202,7 +202,7 @@
X };
X 
X 
-__initfunc(int atixl_busmouse_init(void))
+int __init atixl_busmouse_init(void)
X {
X 	unsigned char a,b,c;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/char/bttv.c linux/drivers/char/bttv.c
--- v2.3.9/linux/drivers/char/bttv.c	Mon Jun  7 16:17:59 1999
+++ linux/drivers/char/bttv.c	Mon Jul  5 20:35:18 1999
@@ -43,7 +43,6 @@
X #include <linux/types.h>
X #include <linux/wrapper.h>
X #include <linux/interrupt.h>
-#include <linux/version.h>
X 
X #if LINUX_VERSION_CODE >= 0x020100
X #include <asm/uaccess.h>
@@ -81,8 +80,8 @@
X #include "bttv.h"
X #include "tuner.h"
X 
-#define DEBUG(x) 		/* Debug driver */	
-#define IDEBUG(x) 		/* Debug interrupt handler */
+#define DEBUG(x)		/* Debug driver */	
+#define IDEBUG(x)		/* Debug interrupt handler */
X 
X #if LINUX_VERSION_CODE >= 0x020117
X MODULE_PARM(vidmem,"i");
@@ -110,7 +109,7 @@
X #define CARD_DEFAULT 0
X #endif
X 
-static unsigned int remap[BTTV_MAX];    /* remap Bt848 */
+static unsigned long remap[BTTV_MAX];    /* remap Bt848 */
X static unsigned int radio[BTTV_MAX];
X static unsigned int card[BTTV_MAX] = { CARD_DEFAULT, CARD_DEFAULT, 
X                                        CARD_DEFAULT, CARD_DEFAULT };
@@ -129,51 +128,80 @@
X #define EEPROM_WRITE_DELAY    20000
X #define BURSTOFFSET 76
X 
-
-
X /*******************************/
X /* Memory management functions */
X /*******************************/
X 
-/* convert virtual user memory address to physical address */
-/* (virt_to_phys only works for kmalloced kernel memory) */
+#define MDEBUG(x)	do { } while(0)		/* Debug memory management */
+
+/* [DaveM] I've recoded most of this so that:
+ * 1) It's easier to tell what is happening
+ * 2) It's more portable, especially for translating things
+ *    out of vmalloc mapped areas in the kernel.
+ * 3) Less unnecessary translations happen.
+ *
+ * The code used to assume that the kernel vmalloc mappings
+ * existed in the page tables of every process, this is simply
+ * not guarenteed.  We now use pgd_offset_k which is the
+ * defined way to get at the kernel page tables.
+ */
X 
-static inline unsigned long uvirt_to_phys(unsigned long adr)
+/* Given PGD from the address space's page table, return the kernel
+ * virtual mapping of the physical memory mapped at ADR.
+ */
+static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
X {
-	pgd_t *pgd;
+        unsigned long ret = 0UL;
X 	pmd_t *pmd;
X 	pte_t *ptep, pte;
X   
-	pgd = pgd_offset(current->mm, adr);
-	if (pgd_none(*pgd))
-		return 0;
-	pmd = pmd_offset(pgd, adr);
-	if (pmd_none(*pmd))
-		return 0;
-	ptep = pte_offset(pmd, adr/*&(~PGDIR_MASK)*/);
-	pte = *ptep;
-	if(pte_present(pte))
-		return 
-		  virt_to_phys((void *)(pte_page(pte)|(adr&(PAGE_SIZE-1))));
-	return 0;
+	if (!pgd_none(*pgd)) {
+                pmd = pmd_offset(pgd, adr);
+                if (!pmd_none(*pmd)) {
+                        ptep = pte_offset(pmd, adr);
+                        pte = *ptep;
+                        if(pte_present(pte))
+                                ret = (pte_page(pte)|(adr&(PAGE_SIZE-1)));
+                }
+        }
+        MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
+	return ret;
X }
X 
X static inline unsigned long uvirt_to_bus(unsigned long adr) 
X {
-	return virt_to_bus(phys_to_virt(uvirt_to_phys(adr)));
-}
+        unsigned long kva, ret;
X 
-/* convert virtual kernel memory address to physical address */
-/* (virt_to_phys only works for kmalloced kernel memory) */
+        kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
+	ret = virt_to_bus((void *)kva);
+        MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
+        return ret;
+}
X 
-static inline unsigned long kvirt_to_phys(unsigned long adr) 
+static inline unsigned long kvirt_to_bus(unsigned long adr) 
X {
-	return uvirt_to_phys(VMALLOC_VMADDR(adr));
+        unsigned long va, kva, ret;
+
+        va = VMALLOC_VMADDR(adr);
+        kva = uvirt_to_kva(pgd_offset_k(va), va);
+	ret = virt_to_bus((void *)kva);
+        MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
+        return ret;
X }
X 
-static inline unsigned long kvirt_to_bus(unsigned long adr) 
+/* Here we want the physical address of the memory.
+ * This is used when initializing the contents of the
+ * area and marking the pages as reserved.
+ */
+static inline unsigned long kvirt_to_pa(unsigned long adr) 
X {
-	return uvirt_to_bus(VMALLOC_VMADDR(adr));
+        unsigned long va, kva, ret;
+
+        va = VMALLOC_VMADDR(adr);
+        kva = uvirt_to_kva(pgd_offset_k(va), va);
+	ret = __pa(kva);
+        MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
+        return ret;
X }
X 
X static void * rvmalloc(unsigned long size)
@@ -188,8 +216,8 @@
X 	        adr=(unsigned long) mem;
X 		while (size > 0) 
X                 {
-	                page = kvirt_to_phys(adr);
-			mem_map_reserve(MAP_NR(phys_to_virt(page)));
+	                page = kvirt_to_pa(adr);
+			mem_map_reserve(MAP_NR(__va(page)));
X 			adr+=PAGE_SIZE;
X 			size-=PAGE_SIZE;
X 		}
@@ -206,8 +234,8 @@
X 	        adr=(unsigned long) mem;
X 		while (size > 0) 
X                 {
-	                page = kvirt_to_phys(adr);
-			mem_map_unreserve(MAP_NR(phys_to_virt(page)));
+	                page = kvirt_to_pa(adr);
+			mem_map_unreserve(MAP_NR(__va(page)));
X 			adr+=PAGE_SIZE;
X 			size-=PAGE_SIZE;
X 		}
@@ -541,13 +569,13 @@
X         /* Aimslab VHX */
X         { 3, 1, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4}},
X         /* Zoltrix TV-Max */
-        { 3, 1, 0, 2,15, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0}},
+        { 3, 1, 0, 2, 0x00000f, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0x8}},
X         /* Pixelview PlayTV (bt878) */
X         { 3, 4, 0, 2, 0x01e000, { 2, 0, 1, 1}, {0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 }},
X         /* "Leadtek WinView 601", */
X         { 3, 1, 0, 2, 0x8300f8, { 2, 3, 1, 1,0}, {0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007}},
X         /* AVEC Intercapture */
-        { 3, 1, 9, 2, 0, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0}},
+        { 3, 2, 0, 2, 0, { 2, 3, 1, 1}, { 1, 0, 0, 0, 0}},
X };
X #define TVCARDS (sizeof(tvcards)/sizeof(tvcard))
X 
@@ -823,30 +851,30 @@
X 	unsigned int *po=(unsigned int *) btv->vbi_odd;
X 	unsigned int *pe=(unsigned int *) btv->vbi_even;
X   
-	DEBUG(printk(KERN_DEBUG "vbiodd: 0x%08x\n",(int)btv->vbi_odd));
-	DEBUG(printk(KERN_DEBUG "vbievn: 0x%08x\n",(int)btv->vbi_even));
-	DEBUG(printk(KERN_DEBUG "po: 0x%08x\n",(int)po));
-	DEBUG(printk(KERN_DEBUG "pe: 0x%08x\n",(int)pe));
+	DEBUG(printk(KERN_DEBUG "vbiodd: 0x%lx\n",(long)btv->vbi_odd));
+	DEBUG(printk(KERN_DEBUG "vbievn: 0x%lx\n",(long)btv->vbi_even));
+	DEBUG(printk(KERN_DEBUG "po: 0x%lx\n",(long)po));
+	DEBUG(printk(KERN_DEBUG "pe: 0x%lx\n",(long)pe));
X         
-	*(po++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(po++)=0;
+	*(po++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(po++)=0;
X 	for (i=0; i<16; i++) 
X 	{
-		*(po++)=VBI_RISC;
-		*(po++)=kvirt_to_bus((unsigned long)btv->vbibuf+i*2048);
+		*(po++)=cpu_to_le32(VBI_RISC);
+		*(po++)=cpu_to_le32(kvirt_to_bus((unsigned long)btv->vbibuf+i*2048));
X 	}
-	*(po++)=BT848_RISC_JUMP;
-	*(po++)=virt_to_bus(btv->risc_jmp+4);
+	*(po++)=cpu_to_le32(BT848_RISC_JUMP);
+	*(po++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+4));
X 
-	*(pe++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(pe++)=0;
+	*(pe++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(pe++)=0;
X 	for (i=16; i<32; i++) 
X 	{
-		*(pe++)=VBI_RISC;
-		*(pe++)=kvirt_to_bus((unsigned long)btv->vbibuf+i*2048);
+		*(pe++)=cpu_to_le32(VBI_RISC);
+		*(pe++)=cpu_to_le32(kvirt_to_bus((unsigned long)btv->vbibuf+i*2048));
X 	}
-	*(pe++)=BT848_RISC_JUMP|BT848_RISC_IRQ|(0x01<<16);
-	*(pe++)=virt_to_bus(btv->risc_jmp+10);
-	DEBUG(printk(KERN_DEBUG "po: 0x%08x\n",(int)po));
-	DEBUG(printk(KERN_DEBUG "pe: 0x%08x\n",(int)pe));
+	*(pe++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(0x01<<16));
+	*(pe++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+10));
+	DEBUG(printk(KERN_DEBUG "po: 0x%lx\n",(long)po));
+	DEBUG(printk(KERN_DEBUG "pe: 0x%lx\n",(long)pe));
X }
X 
X int fmtbppx2[16] = {
@@ -881,8 +909,8 @@
X 	unsigned long bpl=1024;		/* bytes per line */
X 	unsigned long vadr=(unsigned long) vbuf;
X 
-	*(ro++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(ro++)=0;
-	*(re++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(re++)=0;
+	*(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(ro++)=0;
+	*(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(re++)=0;
X   
X         /* In PAL 650 blocks of 256 DWORDs are sampled, but only if VDELAY
X            is 2 and without separate VBI grabbing.
@@ -890,17 +918,17 @@
X 
X 	for (line=0; line < 640; line++)
X 	{
-                *(ro++)=BT848_RISC_WRITE|bpl|BT848_RISC_SOL|BT848_RISC_EOL;
-                *(ro++)=kvirt_to_bus(vadr);
-                *(re++)=BT848_RISC_WRITE|bpl|BT848_RISC_SOL|BT848_RISC_EOL;
-                *(re++)=kvirt_to_bus(vadr+BTTV_MAX_FBUF/2);
+                *(ro++)=cpu_to_le32(BT848_RISC_WRITE|bpl|BT848_RISC_SOL|BT848_RISC_EOL);
+                *(ro++)=cpu_to_le32(kvirt_to_bus(vadr));
+                *(re++)=cpu_to_le32(BT848_RISC_WRITE|bpl|BT848_RISC_SOL|BT848_RISC_EOL);
+                *(re++)=cpu_to_le32(kvirt_to_bus(vadr+BTTV_MAX_FBUF/2));
X                 vadr+=bpl;
X 	}
X 	
-	*(ro++)=BT848_RISC_JUMP;
-	*(ro++)=btv->bus_vbi_even;
-	*(re++)=BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16);
-	*(re++)=btv->bus_vbi_odd;
+	*(ro++)=cpu_to_le32(BT848_RISC_JUMP);
+	*(ro++)=cpu_to_le32(btv->bus_vbi_even);
+	*(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));
+	*(re++)=cpu_to_le32(btv->bus_vbi_odd);
X 	
X 	return 0;
X }
@@ -954,8 +982,8 @@
X 	cradr=cbadr+csize;
X 	inter = (height>btv->win.cropheight/2) ? 1 : 0;
X 	
-	*(ro++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3; *(ro++)=0;
-	*(re++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3; *(re++)=0;
+	*(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3); *(ro++)=0;
+	*(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3); *(re++)=0;
X   
X 	for (line=0; line < (height<<(1^inter)); line++)
X 	{
@@ -991,15 +1019,15 @@
X 		 todo-=bl;
X 		 if(!todo) rcmd|=BT848_RISC_EOL; /* if this is the last EOL */
X 		 
-		 *((*rp)++)=rcmd|bl;
-		 *((*rp)++)=blcb|(blcr<<16);
-		 *((*rp)++)=kvirt_to_bus(vadr);
+		 *((*rp)++)=cpu_to_le32(rcmd|bl);
+		 *((*rp)++)=cpu_to_le32(blcb|(blcr<<16));
+		 *((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));
X 		 vadr+=bl;
X 		 if((rcmd&(15<<28))==BT848_RISC_WRITE123)
X 		 {
-		 	*((*rp)++)=kvirt_to_bus(cbadr);
+		 	*((*rp)++)=cpu_to_le32(kvirt_to_bus(cbadr));
X 		 	cbadr+=blcb;
-		 	*((*rp)++)=kvirt_to_bus(cradr);
+		 	*((*rp)++)=cpu_to_le32(kvirt_to_bus(cradr));
X 		 	cradr+=blcr;
X 		 }
X 		 
@@ -1007,10 +1035,10 @@
X 		}
X 	}
X 	
-	*(ro++)=BT848_RISC_JUMP;
-	*(ro++)=btv->bus_vbi_even;
-	*(re++)=BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16);
-	*(re++)=btv->bus_vbi_odd;
+	*(ro++)=cpu_to_le32(BT848_RISC_JUMP);
+	*(ro++)=cpu_to_le32(btv->bus_vbi_even);
+	*(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));
+	*(re++)=cpu_to_le32(btv->bus_vbi_odd);
X 	
X 	return 0;
X }
@@ -1037,8 +1065,8 @@
X 	inter = (height>btv->win.cropheight/2) ? 1 : 0;
X 	bpl=width*fmtbppx2[palette2fmt[palette]&0xf]/2;
X 	
-	*(ro++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(ro++)=0;
-	*(re++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(re++)=0;
+	*(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(ro++)=0;
+	*(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(re++)=0;
X   
X 	for (line=0; line < (height<<(1^inter)); line++)
X 	{
@@ -1050,35 +1078,35 @@
X 		bl=PAGE_SIZE-((PAGE_SIZE-1)&vadr);
X 		if (bpl<=bl)
X                 {
-		        *((*rp)++)=BT848_RISC_WRITE|BT848_RISC_SOL|
-			        BT848_RISC_EOL|bpl; 
-			*((*rp)++)=kvirt_to_bus(vadr);
+		        *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
+                                               BT848_RISC_EOL|bpl);
+			*((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));
X 			vadr+=bpl;
X 		}
X 		else
X 		{
X 		        todo=bpl;
-		        *((*rp)++)=BT848_RISC_WRITE|BT848_RISC_SOL|bl;
-			*((*rp)++)=kvirt_to_bus(vadr);
+		        *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|bl);
+			*((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));
X 			vadr+=bl;
X 			todo-=bl;
X 			while (todo>PAGE_SIZE)
X 			{
-			        *((*rp)++)=BT848_RISC_WRITE|PAGE_SIZE;
-				*((*rp)++)=kvirt_to_bus(vadr);
+			        *((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|PAGE_SIZE);
+				*((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));
X 				vadr+=PAGE_SIZE;
X 				todo-=PAGE_SIZE;
X 			}
-			*((*rp)++)=BT848_RISC_WRITE|BT848_RISC_EOL|todo;
-			*((*rp)++)=kvirt_to_bus(vadr);
+			*((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|todo);
+			*((*rp)++)=cpu_to_le32(kvirt_to_bus(vadr));
X 			vadr+=todo;
X 		}
X 	}
X 	
-	*(ro++)=BT848_RISC_JUMP;
-	*(ro++)=btv->bus_vbi_even;
-	*(re++)=BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16);
-	*(re++)=btv->bus_vbi_odd;
+	*(ro++)=cpu_to_le32(BT848_RISC_JUMP);
+	*(ro++)=cpu_to_le32(btv->bus_vbi_even);
+	*(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));
+	*(re++)=cpu_to_le32(btv->bus_vbi_odd);
X 	
X 	return 0;
X }
@@ -1162,10 +1190,10 @@
X 	adr=btv->win.vidadr+btv->win.x*bpp+btv->win.y*bpl;
X 	if ((clipmap=vmalloc(VIDEO_CLIPMAP_SIZE))==NULL) {
X 		/* can't clip, don't generate any risc code */
-		*(ro++)=BT848_RISC_JUMP;
-		*(ro++)=btv->bus_vbi_even;
-		*(re++)=BT848_RISC_JUMP;
-		*(re++)=btv->bus_vbi_odd;
+		*(ro++)=cpu_to_le32(BT848_RISC_JUMP);
+		*(ro++)=cpu_to_le32(btv->bus_vbi_even);
+		*(re++)=cpu_to_le32(BT848_RISC_JUMP);
+		*(re++)=cpu_to_le32(btv->bus_vbi_odd);
X 	}
X 	if (ncr < 0) {	/* bitmap was pased */
X 		memcpy(clipmap, (unsigned char *)cr, VIDEO_CLIPMAP_SIZE);
@@ -1187,8 +1215,8 @@
X 	if (btv->win.y<0)
X 		clip_draw_rectangle(clipmap, 0, 0, 1024, -(btv->win.y));
X 	
-	*(ro++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(ro++)=0;
-	*(re++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(re++)=0;
+	*(ro++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(ro++)=0;
+	*(re++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(re++)=0;
X 	
X 	/* translate bitmap to risc code */
X         for (line=outofmem=0; line < (height<<inter) && !outofmem; line++)
@@ -1206,10 +1234,10 @@
X 				flags |= ((!sx) ? BT848_RISC_SOL : 0);
X 				flags |= ((sx + dx == width) ? BT848_RISC_EOL : 0);
X 				if (!lastbit) {
-					*((*rp)++)=BT848_RISC_WRITE|flags|len;
-					*((*rp)++)=adr + bpp * sx;
+					*((*rp)++)=cpu_to_le32(BT848_RISC_WRITE|flags|len);
+					*((*rp)++)=cpu_to_le32(adr + bpp * sx);
X 				} else
-					*((*rp)++)=BT848_RISC_SKIP|flags|len;
+					*((*rp)++)=cpu_to_le32(BT848_RISC_SKIP|flags|len);
X 				lastbit=cbit;
X 				sx += dx;
X 				dx = 1;
@@ -1224,10 +1252,10 @@
X 	}
X 	vfree(clipmap);
X 	/* outofmem flag relies on the following code to discard extra data */
-	*(ro++)=BT848_RISC_JUMP;
-	*(ro++)=btv->bus_vbi_even;
-	*(re++)=BT848_RISC_JUMP;
-	*(re++)=btv->bus_vbi_odd;
+	*(ro++)=cpu_to_le32(BT848_RISC_JUMP);
+	*(ro++)=cpu_to_le32(btv->bus_vbi_even);
+	*(re++)=cpu_to_le32(BT848_RISC_JUMP);
+	*(re++)=cpu_to_le32(btv->bus_vbi_odd);
X }
X 
X /* set geometry for even/odd frames 
@@ -1297,6 +1325,23 @@
X         set_pll(btv);
X 
X 	btwrite(fmt, BT848_COLOR_FMT);
+#ifdef __sparc__
+        if(fmt == BT848_COLOR_FMT_RGB32 ||
+           fmt == BT848_COLOR_FMT_RGB24) {
+                btwrite((BT848_COLOR_CTL_GAMMA		|
+                         BT848_COLOR_CTL_WSWAP_ODD	|
+                         BT848_COLOR_CTL_WSWAP_EVEN	|
+                         BT848_COLOR_CTL_BSWAP_ODD	|
+                         BT848_COLOR_CTL_BSWAP_EVEN),
+                        BT848_COLOR_CTL);
+        } else if(fmt == BT848_COLOR_FMT_RGB16 ||
+           fmt == BT848_COLOR_FMT_RGB15) {
+                btwrite((BT848_COLOR_CTL_GAMMA		|
+                         BT848_COLOR_CTL_BSWAP_ODD	|
+                         BT848_COLOR_CTL_BSWAP_EVEN),
+                        BT848_COLOR_CTL);
+        }
+#endif
X 	hactive=width;
X 
X         vtc=0;
@@ -1474,7 +1519,7 @@
X 			btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI);
X 			btor(BT848_VSCALE_COMB, BT848_O_VSCALE_HI);
X 		}
-		btv->risc_jmp[12]=BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ;
+		btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ);
X         }
X 	btor(3, BT848_CAP_CTL);
X 	btor(3, BT848_GPIO_DMA_CTL);
@@ -2268,7 +2313,7 @@
X 	pos=(unsigned long) btv->fbuffer;
X 	while (size > 0) 
X 	{
-	        page = kvirt_to_phys(pos);
+	        page = kvirt_to_pa(pos);
X 		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
X 		        return -EAGAIN;
X 		start+=PAGE_SIZE;
@@ -3110,44 +3155,44 @@
X 	int flags=btv->cap;
X 
X 	/* Sync to start of odd field */
-	btv->risc_jmp[0]=BT848_RISC_SYNC|BT848_RISC_RESYNC|BT848_FIFO_STATUS_VRE;
+	btv->risc_jmp[0]=cpu_to_le32(BT848_RISC_SYNC|BT848_RISC_RESYNC|BT848_FIFO_STATUS_VRE);
X 	btv->risc_jmp[1]=0;
X 
X 	/* Jump to odd vbi sub */
-	btv->risc_jmp[2]=BT848_RISC_JUMP|(0x5<<20);
+	btv->risc_jmp[2]=cpu_to_le32(BT848_RISC_JUMP|(0x5<<20));
X 	if (flags&8)
-		btv->risc_jmp[3]=virt_to_bus(btv->vbi_odd);
+		btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->vbi_odd));
X 	else
-		btv->risc_jmp[3]=virt_to_bus(btv->risc_jmp+4);
+		btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->risc_jmp+4));
X 
X         /* Jump to odd sub */
-	btv->risc_jmp[4]=BT848_RISC_JUMP|(0x6<<20);
+	btv->risc_jmp[4]=cpu_to_le32(BT848_RISC_JUMP|(0x6<<20));
X 	if (flags&2)
-		btv->risc_jmp[5]=virt_to_bus(btv->risc_odd);
+		btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_odd));
X 	else
-		btv->risc_jmp[5]=virt_to_bus(btv->risc_jmp+6);
+		btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_jmp+6));
X 
X 
X 	/* Sync to start of even field */
-	btv->risc_jmp[6]=BT848_RISC_SYNC|BT848_RISC_RESYNC|BT848_FIFO_STATUS_VRO;
+	btv->risc_jmp[6]=cpu_to_le32(BT848_RISC_SYNC|BT848_RISC_RESYNC|BT848_FIFO_STATUS_VRO);
X 	btv->risc_jmp[7]=0;
X 
X 	/* Jump to even vbi sub */
-	btv->risc_jmp[8]=BT848_RISC_JUMP;
+	btv->risc_jmp[8]=cpu_to_le32(BT848_RISC_JUMP);
X 	if (flags&4)
-		btv->risc_jmp[9]=virt_to_bus(btv->vbi_even);
+		btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->vbi_even));
X 	else
-		btv->risc_jmp[9]=virt_to_bus(btv->risc_jmp+10);
+		btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->risc_jmp+10));
X 
X 	/* Jump to even sub */
-	btv->risc_jmp[10]=BT848_RISC_JUMP|(8<<20);
+	btv->risc_jmp[10]=cpu_to_le32(BT848_RISC_JUMP|(8<<20));
X 	if (flags&1)
-		btv->risc_jmp[11]=virt_to_bus(btv->risc_even);
+		btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_even));
X 	else
-		btv->risc_jmp[11]=virt_to_bus(btv->risc_jmp+12);
+		btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_jmp+12));
X 
-	btv->risc_jmp[12]=BT848_RISC_JUMP;
-	btv->risc_jmp[13]=virt_to_bus(btv->risc_jmp);
+	btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP);
+	btv->risc_jmp[13]=cpu_to_le32(virt_to_bus(btv->risc_jmp));
X 
X 	/* enable capturing */
X 	btaor(flags, ~0x0f, BT848_CAP_CTL);
@@ -3165,7 +3210,7 @@
X 
X 	/* reset the bt848 */
X 	btwrite(0, BT848_SRESET);
-	DEBUG(printk(KERN_DEBUG "bttv%d: bt848_mem: 0x%08x\n",i,(unsigned int) btv->bt848_mem));
+	DEBUG(printk(KERN_DEBUG "bttv%d: bt848_mem: 0x%lx\n",i,(unsigned long) btv->bt848_mem));
X 
X 	/* default setup for max. PAL size in a 1024xXXX hicolor framebuffer */
X 	btv->win.norm=0; /* change this to 1 for NTSC, 2 for SECAM */
@@ -3330,8 +3375,7 @@
X 		if (!astat)
X 			return;
X 		btwrite(astat,BT848_INT_STAT);
-		IDEBUG(printk ("bttv%d: astat %08x\n", btv->nr, astat));
-		IDEBUG(printk ("bttv%d:  stat %08x\n", btv->nr, stat));
+		IDEBUG(printk ("bttv%d: astat %08x stat %08x\n", btv->nr, astat, stat));
X 
X 		/* get device status bits */
X 		dstat=btread(BT848_DSTATUS);
@@ -3387,8 +3431,8 @@
X 					btv->gro = btv->gro_next;
X 					btv->gre = btv->gre_next;
X 					btv->grf = btv->grf_next;
-                                        btv->risc_jmp[5]=btv->gro;
-					btv->risc_jmp[11]=btv->gre;
+                                        btv->risc_jmp[5]=cpu_to_le32(btv->gro);
+					btv->risc_jmp[11]=cpu_to_le32(btv->gre);
X 					bt848_set_geo(btv, btv->gwidth,
X 						      btv->gheight,
X 						      btv->gfmt);
@@ -3405,9 +3449,9 @@
X 			}
X 			if (stat&(8<<28)) 
X 			{
-			        btv->risc_jmp[5]=btv->gro;
-				btv->risc_jmp[11]=btv->gre;
-				btv->risc_jmp[12]=BT848_RISC_JUMP;
+			        btv->risc_jmp[5]=cpu_to_le32(btv->gro);
+				btv->risc_jmp[11]=cpu_to_le32(btv->gre);
+				btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP);
X 				bt848_set_geo(btv, btv->gwidth, btv->gheight,
X 					      btv->gfmt);
X 			}
@@ -3502,14 +3546,16 @@
X 
X         if (remap[bttv_num])
X         {
+                unsigned int dw = btv->bt848_adr;
+
X                 if (remap[bttv_num] < 0x1000)
X                         remap[bttv_num]<<=20;
X                 remap[bttv_num]&=PCI_BASE_ADDRESS_MEM_MASK;
-                printk(KERN_INFO "bttv%d: remapping to : 0x%08x.\n",
+                printk(KERN_INFO "bttv%d: remapping to : 0x%lx.\n",
X                        bttv_num,remap[bttv_num]);
X                 remap[bttv_num]|=btv->bt848_adr&(~PCI_BASE_ADDRESS_MEM_MASK);
X                 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, remap[bttv_num]);
-                pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &btv->bt848_adr);
+                pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &dw);
X                 btv->dev->base_address[0] = btv->bt848_adr;
X         }					
X         btv->bt848_adr&=PCI_BASE_ADDRESS_MEM_MASK;
@@ -3518,7 +3564,7 @@
X                bttv_num,btv->id, btv->revision);
X         printk("bus: %d, devfn: %d, ",dev->bus->number, dev->devfn);
X         printk("irq: %d, ",btv->irq);
-        printk("memory: 0x%08x.\n", btv->bt848_adr);
+        printk("memory: 0x%lx.\n", btv->bt848_adr);
X 
X         btv->pll.pll_crystal = 0;
X         btv->pll.pll_ifreq   = 0;
@@ -3542,7 +3588,11 @@
X                 }
X         }
X         
+#ifdef __sparc__
+        btv->bt848_mem=(unsigned char *)btv->bt848_adr;
+#else
X         btv->bt848_mem=ioremap(btv->bt848_adr, 0x1000);
+#endif
X         
X         /* clear interrupt mask */
X 	btwrite(0, BT848_INT_MASK);
@@ -3817,17 +3867,17 @@
X 		if (btv->risc_even)
X 			kfree((void *) btv->risc_even);
X 
-		DEBUG(printk(KERN_DEBUG "free: risc_jmp: 0x%08x.\n", btv->risc_jmp));
+		DEBUG(printk(KERN_DEBUG "free: risc_jmp: 0x%p.\n", btv->risc_jmp));
X 		if (btv->risc_jmp)
X 			kfree((void *) btv->risc_jmp);
X 
-		DEBUG(printk(KERN_DEBUG "bt848_vbibuf: 0x%08x.\n", btv->vbibuf));
+		DEBUG(printk(KERN_DEBUG "bt848_vbibuf: 0x%p.\n", btv->vbibuf));
X 		if (btv->vbibuf)
X 			vfree((void *) btv->vbibuf);
X 
X 
X 		free_irq(btv->irq,btv);
-		DEBUG(printk(KERN_DEBUG "bt848_mem: 0x%08x.\n", btv->bt848_mem));
+		DEBUG(printk(KERN_DEBUG "bt848_mem: 0x%p.\n", btv->bt848_mem));
X 		if (btv->bt848_mem)
X 			iounmap(btv->bt848_mem);
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/char/bttv.h linux/drivers/char/bttv.h
--- v2.3.9/linux/drivers/char/bttv.h	Mon Jun  7 16:17:59 1999
+++ linux/drivers/char/bttv.h	Mon Jul  5 20:07:02 1999
@@ -102,9 +102,9 @@
X #else
X 	struct pci_dev *dev;
X #endif
-	unsigned char irq;          /* IRQ used by Bt848 card */
+	unsigned int irq;           /* IRQ used by Bt848 card */
X 	unsigned char revision;
-	unsigned int bt848_adr;      /* bus address of IO mem returned by PCI BIOS */
+	unsigned long bt848_adr;    /* bus address of IO mem returned by PCI BIOS */
X 	unsigned char *bt848_mem;   /* pointer to mapped IO memory */
X 	unsigned long busriscmem; 
X 	u32 *riscmem;
@@ -274,7 +274,7 @@
X #define TEA6320_S          0x07  /* switch register */
X                                  /* values for those registers: */
X #define TEA6320_S_SA       0x01  /* stereo A input */
-#define TEA6320_S_SB       0x02  /* stereo B */
+#define TEA6320_S_SB       0x07  /* stereo B -- databook wrong? this works */
X #define TEA6320_S_SC       0x04  /* stereo C */
X #define TEA6320_S_GMU      0x80  /* general mute */
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c
--- v2.3.9/linux/drivers/char/busmouse.c	Wed May 12 13:27:37 1999
+++ linux/drivers/char/busmouse.c	Tue Jul  6 19:16:55 1999
@@ -60,7 +60,7 @@
X MODULE_PARM(mouse_irq, "i");
X #endif
X 
-__initfunc(void bmouse_setup(char *str, int *ints))
+void __init bmouse_setup(char *str, int *ints)
X {
X 	if (ints[0] > 0)
X 		mouse_irq=ints[1];
@@ -252,7 +252,7 @@
X 	LOGITECH_BUSMOUSE, "busmouse", &bus_mouse_fops
X };
X 
-__initfunc(int bus_mouse_init(void))
+int __init bus_mouse_init(void)
X {
X 	if (check_region(LOGIBM_BASE, LOGIBM_EXTENT)) {
X 	  mouse.present = 0;
diff -u --recursive --new-file v2.3.9/linux/drivers/char/buz.c linux/drivers/char/buz.c
--- v2.3.9/linux/drivers/char/buz.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/buz.c	Tue Jul  6 10:11:40 1999
@@ -0,0 +1,3478 @@
+#define MAX_KMALLOC_MEM (512*1024)
+/*
+   buz - Iomega Buz driver version 1.0
+
+   Copyright (C) 1999 Rainer Johanni <Rai...@Johanni.de>
+
+   based on
+
+   buz.0.0.3 Copyright (C) 1998 Dave Perks <dpe...@ibm.net>
+
+   and
+
+   bttv - Bt848 frame grabber driver
+
+   Copyright (C) 1996,97,98 Ralph  Metzler (rj...@thp.uni-koeln.de)
+   & Marcus Metzler (mo...@thp.uni-koeln.de)
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/malloc.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/signal.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <linux/sched.h>
+#include <asm/segment.h>
+#include <linux/types.h>
+#include <linux/wrapper.h>
+#include <asm/spinlock.h>
+
+#include <linux/videodev.h>
+
+#include <linux/version.h>
+#include <asm/uaccess.h>
+
+#include <linux/i2c.h>
+#include "buz.h"
+#include <linux/video_decoder.h>
+#include <linux/video_encoder.h>
+
+#define IRQ_MASK ( ZR36057_ISR_GIRQ0 | /* ZR36057_ISR_GIRQ1 | ZR36057_ISR_CodRepIRQ | */ ZR36057_ISR_JPEGRepIRQ )
+#define GPIO_MASK 0xdf
+
+/*
+ 
+ BUZ
+ 
+   GPIO0 = 1, take board out of reset
+   GPIO1 = 1, take JPEG codec out of sleep mode
+   GPIO3 = 1, deassert FRAME# to 36060
+   
+
+   GIRQ0 signals a vertical sync of the video signal
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 07'
echo 'File patch-2.3.10 is continued in part 08'
echo 08 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 04 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
-    fi
-    dep_tristate '  Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
-    if [ "$CONFIG_PRINTER" != "n" ]; then
-      bool '    Support IEEE1284 status readback' CONFIG_PRINTER_READBACK
-    fi
-  fi
+  source drivers/misc/Config.in
+  dep_tristate '  Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
X   tristate 'SUNW,envctrl support' CONFIG_ENVCTRL
X fi
X endmenu
@@ -232,6 +220,16 @@
X bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
X if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
X 	int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'Video For Linux'
+tristate 'Video For Linux' CONFIG_VIDEO_DEV
+if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
+  if [ "$CONFIG_PCI" != "n" ]; then
+    dep_tristate 'BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV
+  fi
X fi
X endmenu
X 
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.3.9/linux/arch/sparc64/defconfig	Wed Jun 30 13:38:19 1999
+++ linux/arch/sparc64/defconfig	Tue Jul  6 19:05:48 1999
@@ -93,11 +93,13 @@
X CONFIG_BINFMT_MISC=m
X CONFIG_SOLARIS_EMUL=m
X CONFIG_PARPORT=m
-CONFIG_PARPORT_AX=m
-CONFIG_PARPORT_LOWLEVEL_MODULE=y
+# CONFIG_PARPORT_PC is not set
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
X # CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_1284 is not set
X CONFIG_PRINTER=m
-CONFIG_PRINTER_READBACK=y
X CONFIG_ENVCTRL=m
X 
X #
@@ -260,6 +262,12 @@
X #
X CONFIG_UNIX98_PTYS=y
X CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# Video For Linux
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_BT848=y
X 
X #
X # Filesystems
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/kernel/binfmt_aout32.c linux/arch/sparc64/kernel/binfmt_aout32.c
--- v2.3.9/linux/arch/sparc64/kernel/binfmt_aout32.c	Wed Jun 30 13:38:19 1999
+++ linux/arch/sparc64/kernel/binfmt_aout32.c	Thu Jul  1 17:33:12 1999
@@ -311,9 +311,10 @@
X 		fd = open_dentry(bprm->dentry, O_RDONLY);
X 		if (fd < 0)
X 			return fd;
-		file = fcheck(fd);
+		file = fget(fd);
X 
X 		if (!file->f_op || !file->f_op->mmap) {
+			fput(fd);
X 			sys_close(fd);
X 			do_brk(0, ex.a_text+ex.a_data);
X 			read_exec(bprm->dentry, fd_offset,
@@ -327,6 +328,7 @@
X 			fd_offset);
X 
X 		if (error != N_TXTADDR(ex)) {
+			fput(file);
X 			sys_close(fd);
X 			send_sig(SIGKILL, current, 0);
X 			return error;
@@ -336,6 +338,7 @@
X 				PROT_READ | PROT_WRITE | PROT_EXEC,
X 				MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
X 				fd_offset + ex.a_text);
+		fput(file);
X 		sys_close(fd);
X 		if (error != N_DATADDR(ex)) {
X 			send_sig(SIGKILL, current, 0);
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/kernel/ioctl32.c linux/arch/sparc64/kernel/ioctl32.c
--- v2.3.9/linux/arch/sparc64/kernel/ioctl32.c	Wed Jun  9 14:44:25 1999
+++ linux/arch/sparc64/kernel/ioctl32.c	Tue Jul  6 10:11:40 1999
@@ -1696,9 +1696,9 @@
X 	int error = -EBADF;
X 
X 	lock_kernel();
-	filp = fcheck(fd);
+	filp = fget(fd);
X 	if(!filp)
-		goto out;
+		goto out2;
X 
X 	if (!filp->f_op || !filp->f_op->ioctl) {
X 		error = sys_ioctl (fd, cmd, arg);
@@ -2381,6 +2381,8 @@
X 		break;
X 	}
X out:
+	fput(filp);
+out2:
X 	unlock_kernel();
X 	return error;
X }
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/kernel/psycho.c linux/arch/sparc64/kernel/psycho.c
--- v2.3.9/linux/arch/sparc64/kernel/psycho.c	Thu Apr 22 19:24:51 1999
+++ linux/arch/sparc64/kernel/psycho.c	Mon Jul  5 20:35:18 1999
@@ -1,4 +1,4 @@
-/* $Id: psycho.c,v 1.85 1999/04/02 14:54:28 davem Exp $
+/* $Id: psycho.c,v 1.86 1999/07/01 10:39:43 davem Exp $
X  * psycho.c: Ultra/AX U2P PCI controller support.
X  *
X  * Copyright (C) 1997 David S. Miller (da...@caipfs.rutgers.edu)
@@ -68,7 +68,6 @@
X #include <linux/smp_lock.h>
X #include <linux/pci.h>
X 
-#include <asm/io.h>
X #include <asm/oplib.h>
X #include <asm/pbm.h>
X #include <asm/apb.h>
@@ -757,13 +756,15 @@
X 	unsigned short stmp;
X 	unsigned int itmp;
X 
+#if 0
X 	for(pdev = pci_devices; pdev; pdev = pdev->next) {
X 		if(pdev->vendor == PCI_VENDOR_ID_SUN &&
X 		   pdev->device == PCI_DEVICE_ID_SUN_SABRE) {
-			pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 128);
+			pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
X 			break;
X 		}
X 	}
+#endif
X 	for (pdev = sabre->pci_bus->devices; pdev; pdev = pdev->sibling) {
X 		if (pdev->vendor == PCI_VENDOR_ID_SUN &&
X 		    pdev->device == PCI_DEVICE_ID_SUN_SIMBA) {
@@ -795,13 +796,14 @@
X 			pci_read_config_dword(pdev, APB_PCI_CONTROL_LOW, &itmp);
X 			itmp = APB_PCI_CTL_LOW_ERRINT_EN | 0x0f;
X 			pci_write_config_dword(pdev, APB_PCI_CONTROL_LOW, itmp);
-
+#if 0
X 			/* Don't mess with the retry limit and PIO/DMA latency
X 			 * timer settings.  But do set primary and secondary
X 			 * latency timers.
X 			 */
-			pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 128);
-			pci_write_config_byte(pdev, PCI_SEC_LATENCY_TIMER, 128);
+			pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
+			pci_write_config_byte(pdev, PCI_SEC_LATENCY_TIMER, 64);
+#endif
X 		}
X 	}
X }
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/kernel/ptrace.c linux/arch/sparc64/kernel/ptrace.c
--- v2.3.9/linux/arch/sparc64/kernel/ptrace.c	Thu Jun 17 01:08:50 1999
+++ linux/arch/sparc64/kernel/ptrace.c	Mon Jul  5 11:30:11 1999
@@ -28,242 +28,6 @@
X 
X #define MAGIC_CONSTANT 0x80000000
X 
-/*
- * This routine gets a long from any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- */
-static pte_t *ptrace_get_page(struct task_struct * tsk,
-	struct vm_area_struct * vma, unsigned long addr, int write)
-{
-	pgd_t * pgdir;
-	pmd_t * pgmiddle;
-	pte_t * pgtable;
-
-repeat:
-	pgdir = pgd_offset(vma->vm_mm, addr);
-
-	/* Seems non-intuitive but the page copy/clear routines always
-	 * check current's value.
-	 */
-	current->mm->segments = (void *) (addr & PAGE_SIZE);
-
-	if (pgd_none(*pgdir)) {
-		handle_mm_fault(tsk, vma, addr, write);
-		goto repeat;
-	}
-	if (pgd_bad(*pgdir)) {
- printk("ptrace: bad page directory %016lx\n", pgd_val(*pgdir));
-		pgd_clear(pgdir);
-		return 0;
-	}
-	pgmiddle = pmd_offset(pgdir, addr);
-	if (pmd_none(*pgmiddle)) {
- handle_mm_fault(tsk, vma, addr, write);
-		goto repeat;
-	}
-	if (pmd_bad(*pgmiddle)) {
- printk("ptrace: bad page middle %016lx\n", pmd_val(*pgmiddle));
-		pmd_clear(pgmiddle);
-		return 0;
-	}
-	pgtable = pte_offset(pgmiddle, addr);
-	if (!pte_present(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, write);
-		goto repeat;
-	}
-	if (write && !pte_write(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, write);
-		goto repeat;
-	}
-	return pgtable;
-}
-
-/* We must bypass the L1-cache to avoid alias issues.  -DaveM */
-static __inline__ unsigned long read_user_long(unsigned long kvaddr)
-{
-	unsigned long ret;
-
-	__asm__ __volatile__("ldxa [%1] %2, %0"
-			     : "=r" (ret)
-			     : "r" (__pa(kvaddr)), "i" (ASI_PHYS_USE_EC));
-	return ret;
-}
-
-static __inline__ unsigned int read_user_int(unsigned long kvaddr)
-{
-	unsigned int ret;
-
-	__asm__ __volatile__("lduwa [%1] %2, %0"
-			     : "=r" (ret)
-			     : "r" (__pa(kvaddr)), "i" (ASI_PHYS_USE_EC));
-	return ret;
-}
-
-static __inline__ void write_user_long(unsigned long kvaddr, unsigned long val)
-{
-	__asm__ __volatile__("stxa %0, [%1] %2"
-			     : /* no outputs */
-			     : "r" (val), "r" (__pa(kvaddr)), "i" (ASI_PHYS_USE_EC));
-}
-
-static __inline__ void write_user_int(unsigned long kvaddr, unsigned int val)
-{
-	__asm__ __volatile__("stwa %0, [%1] %2"
-			     : /* no outputs */
-			     : "r" (val), "r" (__pa(kvaddr)), "i" (ASI_PHYS_USE_EC));
-}
-
-static inline unsigned long get_long(struct task_struct * tsk,
-	struct vm_area_struct * vma, unsigned long addr)
-{
-	pte_t * pgtable;
-	unsigned long page, retval;
-	
-	if (!(pgtable = ptrace_get_page (tsk, vma, addr, 0))) return 0;
-	page = pte_page(*pgtable);
-/* this is a hack for non-kernel-mapped video buffers and similar */
-	if (MAP_NR(page) >= max_mapnr)
-		return 0;
-	page += addr & ~PAGE_MASK;
-	retval = read_user_long(page);
-	flush_page_to_ram(page);
-	return retval;
-}
-
-static inline void put_long(struct task_struct * tsk, struct vm_area_struct * vma,
-	unsigned long addr, unsigned long data)
-{
-	pte_t *pgtable;
-	unsigned long page;
-
-	if (!(pgtable = ptrace_get_page (tsk, vma, addr, 1))) return;
-	page = pte_page(*pgtable);
-/* this is a hack for non-kernel-mapped video buffers and similar */
-	flush_cache_page(vma, addr);
-	if (MAP_NR(page) < max_mapnr) {
-		unsigned long pgaddr;
-
-		pgaddr = page + (addr & ~PAGE_MASK);
-		write_user_long(pgaddr, data);
-
-		__asm__ __volatile__("
-		membar	#StoreStore
-		flush	%0
-"		: : "r" (pgaddr & ~7) : "memory");
-	}
-/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
-/* this should also re-instate whatever read-only mode there was before */
-	set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-	flush_tlb_page(vma, addr);
-}
-
-static inline unsigned int get_int(struct task_struct * tsk,
-	struct vm_area_struct * vma, unsigned long addr)
-{
-	pte_t * pgtable;
-	unsigned long page;
-	unsigned int retval;
-	
-	if (!(pgtable = ptrace_get_page (tsk, vma, addr, 0))) return 0;
-	page = pte_page(*pgtable);
-/* this is a hack for non-kernel-mapped video buffers and similar */
-	if (MAP_NR(page) >= max_mapnr)
-		return 0;
-	page += addr & ~PAGE_MASK;
-	retval = read_user_int(page);
-	flush_page_to_ram(page);
-	return retval;
-}
-
-static inline void put_int(struct task_struct * tsk, struct vm_area_struct * vma,
-	unsigned long addr, unsigned int data)
-{
-	pte_t *pgtable;
-	unsigned long page;
-
-	if (!(pgtable = ptrace_get_page (tsk, vma, addr, 1))) return;
-	page = pte_page(*pgtable);
-/* this is a hack for non-kernel-mapped video buffers and similar */
-	flush_cache_page(vma, addr);
-	if (MAP_NR(page) < max_mapnr) {
-		unsigned long pgaddr;
-
-		pgaddr = page + (addr & ~PAGE_MASK);
-		write_user_int(pgaddr, data);
-
-		__asm__ __volatile__("
-		membar	#StoreStore
-		flush	%0
-"		: : "r" (pgaddr & ~7) : "memory");
-	}
-/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
-/* this should also re-instate whatever read-only mode there was before */
-	set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-	flush_tlb_page(vma, addr);
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls get_long() to read a long.
- */
-static int read_long(struct task_struct * tsk, unsigned long addr,
-		     unsigned long * result)
-{
-	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
-	if (!vma)
-		return -EIO;
-	*result = get_long(tsk, vma, addr);
-	return 0;
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls get_int() to read a int.
- */
-static int read_int(struct task_struct * tsk, unsigned long addr,
-		     unsigned int * result)
-{
-	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
-	if (!vma)
-		return -EIO;
-	*result = get_int(tsk, vma, addr);
-	return 0;
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls put_long() to write a long.
- */
-static int write_long(struct task_struct * tsk, unsigned long addr,
-		      unsigned long data)
-{
-	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
-	if (!vma)
-		return -EIO;
-	put_long(tsk, vma, addr, data);
-	return 0;
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls put_int() to write a int.
- */
-static int write_int(struct task_struct * tsk, unsigned long addr,
-		     unsigned int data)
-{
-	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
-	if (!vma)
-		return -EIO;
-	put_int(tsk, vma, addr, data);
-	return 0;
-}
-
X /* Returning from ptrace is a bit tricky because the syscall return
X  * low level code assumes any value returned which is negative and
X  * is a valid errno will mean setting the condition codes to indicate
@@ -310,175 +74,6 @@
X 		pt_succ_return_linux (regs, val, addr);
X }
X 
-#if 0
-/* XXX: Implement this some day */
-/* Fuck me gently with a chainsaw... */
-static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
-				   struct task_struct *tsk, long *addr)
-{
-	struct pt_regs *cregs = tsk->tss.kregs;
-	struct thread_struct *t = &tsk->tss;
-	int v;
-	
-	if(offset >= 1024)
-		offset -= 1024; /* whee... */
-	if(offset & ((sizeof(unsigned int) - 1))) {
-		pt_error_return(regs, EIO);
-		return;
-	}
-	if(offset >= 16 && offset < 784) {
-		offset -= 16; offset >>= 2;
-		if (t->w_saved)
-			pt_os_succ_return(regs, *(((unsigned long *)(&t->reg_window[0]))+offset), addr);
-		return;
-	}
-	if(offset >= 784 && offset < 832) {
-		offset -= 784; offset >>= 2;
-		if (t->w_saved)
-			pt_os_succ_return(regs, *(((unsigned long *)(&t->rwbuf_stkptrs[0]))+offset), addr);
-		return;
-	}
-	switch(offset) {
-	case 0:
-		v = t->ksp;
-		break;
-#if 0
-	case 4:
-		v = t->kpc;
-		break;
-#endif
-	case 8:
-		v = t->kpsr;
-		break;
-	case 12:
-		v = t->uwinmask;
-		break;
-	case 832:
-		v = t->w_saved;
-		break;
-	case 896:
-		v = cregs->u_regs[UREG_I0];
-		break;
-	case 900:
-		v = cregs->u_regs[UREG_I1];
-		break;
-	case 904:
-		v = cregs->u_regs[UREG_I2];
-		break;
-	case 908:
-		v = cregs->u_regs[UREG_I3];
-		break;
-	case 912:
-		v = cregs->u_regs[UREG_I4];
-		break;
-	case 916:
-		v = cregs->u_regs[UREG_I5];
-		break;
-	case 920:
-		v = cregs->u_regs[UREG_I6];
-		break;
-	case 924:
-		if(tsk->tss.flags & MAGIC_CONSTANT)
-			v = cregs->u_regs[UREG_G1];
-		else
-			v = 0;
-		break;
-	case 940:
-		v = cregs->u_regs[UREG_I0];
-		break;
-	case 944:
-		v = cregs->u_regs[UREG_I1];
-		break;
-
-	case 948:
-		/* Isn't binary compatibility _fun_??? */
-		if(cregs->psr & PSR_C)
-			v = cregs->u_regs[UREG_I0] << 24;
-		else
-			v = 0;
-		break;
-
-		/* Rest of them are completely unsupported. */
-	default:
-		printk("%s [%d]: Wants to read user offset %ld\n",
-		       current->comm, current->pid, offset);
-		pt_error_return(regs, EIO);
-		return;
-	}
-	pt_os_succ_return_linux (regs, v, addr);
-	return;
-}
-
-static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset,
-				    struct task_struct *tsk)
-{
-	struct pt_regs *cregs = tsk->tss.kregs;
-	struct thread_struct *t = &tsk->tss;
-	unsigned int value = regs->u_regs[UREG_I3];
-
-	if(offset >= 1024)
-		offset -= 1024; /* whee... */
-	if(offset & ((sizeof(unsigned long) - 1)))
-		goto failure;
-	if(offset >= 16 && offset < 784) {
-		offset -= 16; offset >>= 2;
-		if (t->w_saved)
-			*(((unsigned long *)(&t->reg_window[0]))+offset) = value;
-		goto success;
-	}
-	if(offset >= 784 && offset < 832) {
-		offset -= 784; offset >>= 2;
-		if (t->w_saved)
-			*(((unsigned long *)(&t->rwbuf_stkptrs[0]))+offset) = value;
-		goto success;
-	}
-	switch(offset) {
-	case 896:
-		cregs->u_regs[UREG_I0] = value;
-		break;
-	case 900:
-		cregs->u_regs[UREG_I1] = value;
-		break;
-	case 904:
-		cregs->u_regs[UREG_I2] = value;
-		break;
-	case 908:
-		cregs->u_regs[UREG_I3] = value;
-		break;
-	case 912:
-		cregs->u_regs[UREG_I4] = value;
-		break;
-	case 916:
-		cregs->u_regs[UREG_I5] = value;
-		break;
-	case 920:
-		cregs->u_regs[UREG_I6] = value;
-		break;
-	case 924:
-		cregs->u_regs[UREG_I7] = value;
-		break;
-	case 940:
-		cregs->u_regs[UREG_I0] = value;
-		break;
-	case 944:
-		cregs->u_regs[UREG_I1] = value;
-		break;
-
-		/* Rest of them are completely unsupported or "no-touch". */
-	default:
-		printk("%s [%d]: Wants to write user offset %ld\n",
-		       current->comm, current->pid, offset);
-		goto failure;
-	}
-success:
-	pt_succ_return(regs, 0);
-	return;
-failure:
-	pt_error_return(regs, EIO);
-	return;
-}
-#endif
-
X /* #define ALLOW_INIT_TRACING */
X /* #define DEBUG_PTRACE */
X 
@@ -642,76 +237,54 @@
X 	switch(request) {
X 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
X 	case PTRACE_PEEKDATA: {
-		unsigned long tmp;
-		int res;
+		unsigned long tmp64;
+		unsigned int tmp32;
+		int res, copied;
X 
-		/* Non-word alignment _not_ allowed on Sparc. */
+		res = -EIO;
X 		if (current->tss.flags & SPARC_FLAG_32BIT) {
-			unsigned int x;
-			if(addr & (sizeof(unsigned int) - 1)) {
-				pt_error_return(regs, EINVAL);
-				goto out;
-			}
-			down(&child->mm->mmap_sem);
-			res = read_int(child, addr, &x);
-			up(&child->mm->mmap_sem);
-			tmp = x;
+			copied = access_process_vm(child, addr,
+						   &tmp32, sizeof(tmp32), 0);
+			tmp64 = (unsigned long) tmp32;
+			if (copied == sizeof(tmp32))
+				res = 0;
X 		} else {
-			if(addr & (sizeof(unsigned long) - 1)) {
-				pt_error_return(regs, EINVAL);
-				goto out;
-			}
-			down(&child->mm->mmap_sem);
-			res = read_long(child, addr, &tmp);
-			up(&child->mm->mmap_sem);
+			copied = access_process_vm(child, addr,
+						   &tmp64, sizeof(tmp64), 0);
+			if (copied == sizeof(tmp64))
+				res = 0;
X 		}
-		if (res < 0) {
+		if (res < 0)
X 			pt_error_return(regs, -res);
-			goto out;
-		}
-		pt_os_succ_return(regs, tmp, (long *) data);
-		goto out;
+		else
+			pt_os_succ_return(regs, tmp64, (long *) data);
+		goto flush_and_out;
X 	}
X 
-	case PTRACE_PEEKUSR:
-#if 0	
-		read_sunos_user(regs, addr, child, (long *) data);
-#endif
-		goto out;
-
-	case PTRACE_POKEUSR:
-#if 0	
-		write_sunos_user(regs, addr, child);
-#endif		
-		goto out;
-
X 	case PTRACE_POKETEXT: /* write the word at location addr. */
X 	case PTRACE_POKEDATA: {
-		int res;
+		unsigned long tmp64;
+		unsigned int tmp32;
+		int copied, res = -EIO;
X 
-		/* Non-word alignment _not_ allowed on Sparc. */
X 		if (current->tss.flags & SPARC_FLAG_32BIT) {
-			if(addr & (sizeof(unsigned int) - 1)) {
-				pt_error_return(regs, EINVAL);
-				goto out;
-			}
-			down(&child->mm->mmap_sem);
-			res = write_int(child, addr, data);
-			up(&child->mm->mmap_sem);
+			tmp32 = data;
+			copied = access_process_vm(child, addr,
+						   &tmp32, sizeof(tmp32), 1);
+			if (copied == sizeof(tmp32))
+				res = 0;
X 		} else {
-			if(addr & (sizeof(unsigned long) - 1)) {
-				pt_error_return(regs, EINVAL);
-				goto out;
-			}
-			down(&child->mm->mmap_sem);
-			res = write_long(child, addr, data);
-			up(&child->mm->mmap_sem);
+			tmp64 = data;
+			copied = access_process_vm(child, addr,
+						   &tmp64, sizeof(tmp64), 1);
+			if (copied == sizeof(tmp64))
+				res = 0;
X 		}
X 		if(res < 0)
X 			pt_error_return(regs, -res);
X 		else
X 			pt_succ_return(regs, res);
-		goto out;
+		goto flush_and_out;
X 	}
X 
X 	case PTRACE_GETREGS: {
@@ -926,98 +499,31 @@
X 
X 	case PTRACE_READTEXT:
X 	case PTRACE_READDATA: {
-		unsigned char *dest = (unsigned char *) addr2;
-		unsigned long src = addr;
-		int len = data, curlen;
-		struct vm_area_struct *vma;
-		pte_t *pgtable;
-		unsigned long page;
-
-		while(len) {
-			down(&child->mm->mmap_sem);
-			vma = find_extend_vma(child, src);
-			if (!vma) {
-				up(&child->mm->mmap_sem);
-				pt_error_return(regs, EIO);
-				goto flush_and_out;
-			}
-			pgtable = ptrace_get_page (child, vma, src, 0);
-			up(&child->mm->mmap_sem);
-			if (src & ~PAGE_MASK) {
-				curlen = PAGE_SIZE - (src & ~PAGE_MASK);
-				if (curlen > len) curlen = len;
-			} else if (len > PAGE_SIZE)
-				curlen = PAGE_SIZE;
-			else
-				curlen = len;
-			if (pgtable && MAP_NR(page = pte_page(*pgtable)) < max_mapnr) {
-				if (copy_to_user (dest, ((char *)page) + (src & ~PAGE_MASK), curlen)) {
-					flush_page_to_ram(page);
-					pt_error_return(regs, EFAULT);
-					goto flush_and_out;
-				}
-				flush_page_to_ram(page);
-			} else {
-				if (clear_user (dest, curlen)) {
-					pt_error_return(regs, EFAULT);
-					goto flush_and_out;
-				}
-			}
-			src += curlen;
-			dest += curlen;
-			len -= curlen;
+		int res = ptrace_readdata(child, addr,
+					  (void *)addr2, data);
+		if (res == data) {
+			pt_succ_return(regs, 0);
+			goto flush_and_out;
X 		}
-		pt_succ_return(regs, 0);
+		if (res >= 0)
+			res = -EIO;
+		pt_error_return(regs, -res);
X 		goto flush_and_out;
X 	}
X 
X 	case PTRACE_WRITETEXT:
X 	case PTRACE_WRITEDATA: {
-		unsigned char *src = (unsigned char *) addr2;
-		unsigned long dest = addr;
-		int len = data, curlen;
-		struct vm_area_struct *vma;
-		pte_t *pgtable;
-		unsigned long page;
-
-		while(len) {
-			down(&child->mm->mmap_sem);
-			vma = find_extend_vma(child, dest);
-			if (!vma) {
-				up(&child->mm->mmap_sem);
-				pt_error_return(regs, EIO);
-				goto flush_and_out;
-			}
-			pgtable = ptrace_get_page (child, vma, dest, 1);
-			up(&child->mm->mmap_sem);
-			if (dest & ~PAGE_MASK) {
-				curlen = PAGE_SIZE - (dest & ~PAGE_MASK);
-				if (curlen > len) curlen = len;
-			} else if (len > PAGE_SIZE)
-				curlen = PAGE_SIZE;
-			else
-				curlen = len;
-			if (pgtable && MAP_NR(page = pte_page(*pgtable)) < max_mapnr) {
-				flush_cache_page(vma, dest);
-				if (copy_from_user (((char *)page) + (dest & ~PAGE_MASK), src, curlen)) {
-					flush_page_to_ram(page);
-					set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-					flush_tlb_page(vma, dest);
-					pt_error_return(regs, EFAULT);
-					goto flush_and_out;
-				}
-				flush_page_to_ram(page);
-				set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-				flush_tlb_page(vma, dest);
-			}
-			src += curlen;
-			dest += curlen;
-			len -= curlen;
+		int res = ptrace_writedata(child, (void *) addr2,
+					   addr, data);
+		if (res == data) {
+			pt_succ_return(regs, 0);
+			goto flush_and_out;
X 		}
-		pt_succ_return(regs, 0);
+		if (res >= 0)
+			res = -EIO;
+		pt_error_return(regs, -res);
X 		goto flush_and_out;
X 	}
-
X 	case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */
X 		addr = 1;
X 
@@ -1105,6 +611,14 @@
X 		unsigned long va;
X 		for(va =  0; va < (PAGE_SIZE << 1); va += 32)
X 			spitfire_put_dcache_tag(va, 0x0);
+		if (request == PTRACE_PEEKTEXT ||
+		    request == PTRACE_POKETEXT ||
+		    request == PTRACE_READTEXT ||
+		    request == PTRACE_WRITETEXT) {
+			for(va =  0; va < (PAGE_SIZE << 1); va += 32)
+				spitfire_put_icache_tag(va, 0x0);
+			__asm__ __volatile__("flush %g6");
+		}
X 	}
X out:
X 	unlock_kernel();
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/kernel/smp.c linux/arch/sparc64/kernel/smp.c
--- v2.3.9/linux/arch/sparc64/kernel/smp.c	Thu May 27 09:55:21 1999
+++ linux/arch/sparc64/kernel/smp.c	Thu Jul  1 15:09:01 1999
@@ -615,7 +615,7 @@
X 				unsigned int *inc, *inc2;
X 
X 				update_one_process(current, 1, user, !user, cpu);
-				if(--current->counter < 0) {
+				if(--current->counter <= 0) {
X 					current->counter = 0;
X 					current->need_resched = 1;
X 				}
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/kernel/sparc64_ksyms.c linux/arch/sparc64/kernel/sparc64_ksyms.c
--- v2.3.9/linux/arch/sparc64/kernel/sparc64_ksyms.c	Wed Jun 30 13:38:19 1999
+++ linux/arch/sparc64/kernel/sparc64_ksyms.c	Mon Jul  5 20:35:18 1999
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.59 1999/06/28 11:28:50 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.60 1999/07/03 22:11:12 davem Exp $
X  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
X  *
X  * Copyright (C) 1996 David S. Miller (da...@caip.rutgers.edu)
@@ -45,7 +45,6 @@
X #include <asm/ebus.h>
X #endif
X #include <asm/a.out.h>
-#include <asm/svr4.h>
X 
X struct poll {
X 	int fd;
@@ -118,6 +117,12 @@
X 
X /* used by various drivers */
X #ifdef __SMP__
+/* Out of line rw-locking implementation. */
+EXPORT_SYMBOL_PRIVATE(read_lock);
+EXPORT_SYMBOL_PRIVATE(read_unlock);
+EXPORT_SYMBOL_PRIVATE(write_lock);
+EXPORT_SYMBOL_PRIVATE(write_unlock);
+
X /* Kernel wide locking */
X EXPORT_SYMBOL(kernel_flag);
X 
@@ -157,6 +162,10 @@
X EXPORT_SYMBOL(local_irq_count);
X EXPORT_SYMBOL(local_bh_count);
X #endif
+
+/* Atomic counter implementation. */
+EXPORT_SYMBOL_PRIVATE(atomic_add);
+EXPORT_SYMBOL_PRIVATE(atomic_sub);
X 
X EXPORT_SYMBOL(ivector_table);
X EXPORT_SYMBOL(enable_irq);
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
--- v2.3.9/linux/arch/sparc64/kernel/sys_sparc32.c	Wed Jun 30 13:38:19 1999
+++ linux/arch/sparc64/kernel/sys_sparc32.c	Tue Jul  6 10:11:40 1999
@@ -17,7 +17,6 @@
X #include <linux/utime.h>
X #include <linux/resource.h>
X #include <linux/times.h>
-#include <linux/utime.h>
X #include <linux/utsname.h>
X #include <linux/timex.h>
X #include <linux/smp.h>
@@ -32,18 +31,15 @@
X #include <linux/smb_mount.h>
X #include <linux/ncp_fs.h>
X #include <linux/quota.h>
-#include <linux/file.h>
X #include <linux/module.h>
X #include <linux/sunrpc/svc.h>
X #include <linux/nfsd/nfsd.h>
X #include <linux/nfsd/cache.h>
X #include <linux/nfsd/xdr.h>
X #include <linux/nfsd/syscall.h>
-#include <linux/module.h>
X #include <linux/poll.h>
X #include <linux/personality.h>
X #include <linux/stat.h>
-#include <linux/timex.h>
X 
X #include <asm/types.h>
X #include <asm/ipc.h>
@@ -2328,8 +2324,8 @@
X 			break;
X 		}
X 		/* Bump the usage count and install the file. */
-		atomic_inc(&fp[i]->f_count);
-		current->files->fd[new_fd] = fp[i];
+		get_file(fp[i]);
+		fd_install(new_fd, fp[i]);
X 	}
X 
X 	if (i > 0) {
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/kernel/sys_sunos32.c linux/arch/sparc64/kernel/sys_sunos32.c
--- v2.3.9/linux/arch/sparc64/kernel/sys_sunos32.c	Wed Jun 30 13:38:19 1999
+++ linux/arch/sparc64/kernel/sys_sunos32.c	Tue Jul  6 10:11:40 1999
@@ -25,7 +25,6 @@
X #include <linux/signal.h>
X #include <linux/uio.h>
X #include <linux/utsname.h>
-#include <linux/fs.h>
X #include <linux/major.h>
X #include <linux/stat.h>
X #include <linux/malloc.h>
@@ -712,7 +711,7 @@
X 	struct inode  *inode;
X 	struct file   *file;
X 
-	file = current->files->fd [fd];
+	file = fcheck(fd);
X 	if(!file)
X 		return 0;
X 
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/lib/Makefile linux/arch/sparc64/lib/Makefile
--- v2.3.9/linux/arch/sparc64/lib/Makefile	Tue Oct 27 09:52:20 1998
+++ linux/arch/sparc64/lib/Makefile	Sun Jul  4 09:53:12 1999
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.18 1998/10/13 09:07:24 davem Exp $
+# $Id: Makefile,v 1.19 1999/07/03 22:11:08 davem Exp $
X # Makefile for Sparc library files..
X #
X 
@@ -6,7 +6,8 @@
X 
X OBJS  = PeeCeeI.o blockops.o debuglocks.o strlen.o strncmp.o \
X 	memscan.o strncpy_from_user.o strlen_user.o memcmp.o checksum.o \
-	VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o VISsave.o
+	VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o VISsave.o \
+	atomic.o rwlock.o
X 
X lib.a: $(OBJS)
X 	$(AR) rcs lib.a $(OBJS)
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/lib/atomic.S linux/arch/sparc64/lib/atomic.S
--- v2.3.9/linux/arch/sparc64/lib/atomic.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/sparc64/lib/atomic.S	Sun Jul  4 09:53:12 1999
@@ -0,0 +1,32 @@
+/* $Id: atomic.S,v 1.1 1999/07/03 22:11:04 davem Exp $
+ * atomic.S: These things are too big to do inline.
+ *
+ * Copyright (C) 1999 David S. Miller (da...@redhat.com)
+ */
+
+#include <asm/asi.h>
+
+	.text
+	.align	64
+
+	.globl	__atomic_add
+__atomic_add:
+	lduw	[%g1], %g5
+	add	%g5, %g2, %g7
+	cas	[%g1], %g5, %g7
+	cmp	%g5, %g7
+	bne,pn	%icc, __atomic_add
+	 nop
+	jmpl	%g3 + 8, %g0
+	 add	%g7, %g2, %g2
+
+	.globl	__atomic_sub
+__atomic_sub:
+	lduw	[%g1], %g5
+	sub	%g5, %g2, %g7
+	cas	[%g1], %g5, %g7
+	cmp	%g5, %g7
+	bne,pn	%icc, __atomic_sub
+	 nop
+	jmpl	%g3 + 8, %g0
+	 sub	%g7, %g2, %g2
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/lib/rwlock.S linux/arch/sparc64/lib/rwlock.S
--- v2.3.9/linux/arch/sparc64/lib/rwlock.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/sparc64/lib/rwlock.S	Sun Jul  4 09:53:12 1999
@@ -0,0 +1,81 @@
+/* $Id: rwlock.S,v 1.1 1999/07/03 22:11:06 davem Exp $
+ * rwlocks.S: These things are too big to do inline.
+ *
+ * Copyright (C) 1999 David S. Miller (da...@redhat.com)
+ */
+
+	.text
+	.align	64
+
+	/* The non-contention read lock usage is 2 cache lines. */
+
+	.globl	__read_lock, __read_unlock
+	/* g1=lock, g3=retpc, g5/g7=scratch */
+__read_lock:
+	ldsw		[%g1], %g5
+	brlz,pn		%g5, __read_wait_for_writer
+4:	 add		%g5, 1, %g7
+	cas		[%g1], %g5, %g7
+	cmp		%g5, %g7
+	bne,pn		%icc, __read_lock
+	 membar		#StoreLoad | #StoreStore
+99:	jmpl		%g3 + 8, %g0
+	 nop
+__read_unlock:
+	lduw		[%g1], %g5
+	sub		%g5, 1, %g7
+	cas		[%g1], %g5, %g7
+	cmp		%g5, %g7
+	be,pt		%xcc, 99b
+	 membar		#StoreLoad | #StoreStore
+	b,a,pt		%xcc, __read_unlock
+
+__read_wait_for_writer:
+	ldsw		[%g1], %g5
+	brlz,pt		%g5, __read_wait_for_writer
+	 membar		#LoadLoad
+	b,a,pt		%xcc, 4b
+__write_wait_for_writer:
+	ldsw		[%g1], %g5
+	brlz,pt		%g5, __write_wait_for_writer
+	 membar		#LoadLoad
+	b,a,pt		%xcc, 4f
+
+	/* Similarly, 2 cache lines for non-contention write locks. */
+
+	.align		64
+	.globl		__write_unlock
+	/* g1=lock, g3=retpc, g2/g5/g7=scratch */
+__write_unlock:
+	sethi		%hi(0x80000000), %g2
+1:	lduw		[%g1], %g5
+	andn		%g5, %g2, %g7
+	cas		[%g1], %g5, %g7
+	cmp		%g5, %g7
+	be,pt		%icc, 99b
+	 membar		#StoreLoad | #StoreStore
+	b,a,pt		%xcc, 1b
+
+	.globl		__write_lock
+__write_lock:
+	sethi		%hi(0x80000000), %g2
+1:	ldsw		[%g1], %g5
+4:	brnz,pn		%g5, 5f
+	 or		%g5, %g2, %g7
+	cas		[%g1], %g5, %g7
+	cmp		%g5, %g7
+	be,pt		%icc, 99b
+	 membar		#StoreLoad | #StoreStore
+
+	b,a,pt		%xcc, 1b
+5:	brlz		%g5, __write_wait_for_writer
+	or		%g5, %g2, %g7
+	cas		[%g1], %g5, %g7
+	cmp		%g5, %g7
+	bne,pn		%icc, 5b
+8:	 ldsw		[%g1], %g5
+	cmp		%g5, %g2
+	be,pn		%icc, 99b
+	 membar		#LoadLoad
+	b,a,pt		%xcc, 99b
+
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/mm/asyncd.c linux/arch/sparc64/mm/asyncd.c
--- v2.3.9/linux/arch/sparc64/mm/asyncd.c	Wed May 12 08:41:12 1999
+++ linux/arch/sparc64/mm/asyncd.c	Sun Jul  4 09:53:12 1999
@@ -1,4 +1,4 @@
-/*  $Id: asyncd.c,v 1.6 1999/05/12 11:11:48 davem Exp $
+/*  $Id: asyncd.c,v 1.8 1999/07/04 04:35:55 davem Exp $
X  *  The asyncd kernel daemon. This handles paging on behalf of 
X  *  processes that receive page faults due to remote (async) memory
X  *  accesses. 
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/mm/fault.c linux/arch/sparc64/mm/fault.c
--- v2.3.9/linux/arch/sparc64/mm/fault.c	Tue Mar 16 21:52:06 1999
+++ linux/arch/sparc64/mm/fault.c	Sun Jul  4 09:53:12 1999
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.34 1999/03/16 12:12:28 jj Exp $
+/* $Id: fault.c,v 1.36 1999/07/04 04:35:56 davem Exp $
X  * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
X  *
X  * Copyright (C) 1996 David S. Miller (da...@caip.rutgers.edu)
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/solaris/ioctl.c linux/arch/sparc64/solaris/ioctl.c
--- v2.3.9/linux/arch/sparc64/solaris/ioctl.c	Wed May 26 18:14:37 1999
+++ linux/arch/sparc64/solaris/ioctl.c	Tue Jul  6 10:11:40 1999
@@ -367,15 +367,8 @@
X static inline int solaris_timod(unsigned int fd, unsigned int cmd, u32 arg,
X                                     int len, int *len_p)
X {
-        struct file *filp;
X         struct inode *ino;
X 	int ret;
-
-        filp = current->files->fd[fd];
-        if (! filp ||
-	    ! (ino = filp->f_dentry->d_inode) ||
-	    ! ino->i_sock)
-		return TBADF;
X 		
X 	switch (cmd & 0xff) {
X 	case 141: /* TI_OPTMGMT */
@@ -459,7 +452,7 @@
X 	return TNOTSUPPORT;
X }
X 
-static inline int solaris_S(unsigned int fd, unsigned int cmd, u32 arg)
+static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd, u32 arg)
X {
X 	char *p;
X 	int ret;
@@ -470,9 +463,7 @@
X         struct sol_socket_struct *sock;
X         struct module_info *mi;
X 
-        filp = current->files->fd[fd];
-        if (! filp ||
-	    ! (ino = filp->f_dentry->d_inode) ||
+        if (! (ino = filp->f_dentry->d_inode) ||
X 	    ! ino->i_sock)
X 		return -EBADF;
X         sock = filp->private_data;
@@ -696,14 +687,14 @@
X 	struct file *filp;
X 	int error = -EBADF;
X 
-	lock_kernel();
-	filp = fcheck(fd);
+	filp = fget(fd);
X 	if (!filp)
X 		goto out;
X 
+	lock_kernel();
X 	error = -EFAULT;
X 	switch ((cmd >> 8) & 0xff) {
-	case 'S': error = solaris_S(fd, cmd, arg); break;
+	case 'S': error = solaris_S(filp, fd, cmd, arg); break;
X 	case 'T': error = solaris_T(fd, cmd, arg); break;
X 	case 'i': error = solaris_i(fd, cmd, arg); break;
X 	case 'r': error = solaris_r(fd, cmd, arg); break;
@@ -714,6 +705,8 @@
X 		error = -ENOSYS;
X 		break;
X 	}
+	unlock_kernel();
+	fput(filp);
X out:
X 	if (error == -ENOSYS) {
X 		unsigned char c = cmd>>8;
@@ -723,6 +716,5 @@
X 		       (int)fd, (unsigned int)cmd, c, (unsigned int)arg);
X 		error = -EINVAL;
X 	}
-	unlock_kernel();
X 	return error;
X }
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/solaris/socksys.c linux/arch/sparc64/solaris/socksys.c
--- v2.3.9/linux/arch/sparc64/solaris/socksys.c	Sun Oct  4 10:22:43 1998
+++ linux/arch/sparc64/solaris/socksys.c	Mon Jul  5 20:35:18 1999
@@ -16,7 +16,6 @@
X #include <linux/file.h>
X #include <linux/init.h>
X #include <linux/poll.h>
-#include <linux/file.h>
X #include <linux/malloc.h>
X 
X #include <asm/uaccess.h>
diff -u --recursive --new-file v2.3.9/linux/drivers/acorn/char/keyb_arc.c linux/drivers/acorn/char/keyb_arc.c
--- v2.3.9/linux/drivers/acorn/char/keyb_arc.c	Thu Jun 17 01:11:35 1999
+++ linux/drivers/acorn/char/keyb_arc.c	Mon Jul  5 20:35:18 1999
@@ -22,7 +22,6 @@
X #include <linux/ctype.h>
X #include <linux/init.h>
X #include <linux/kbd_ll.h>
-#include <linux/tty.h>
X #include <linux/kbd_kern.h>
X #include <linux/delay.h>
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/ap1000/bif.c linux/drivers/ap1000/bif.c
--- v2.3.9/linux/drivers/ap1000/bif.c	Fri May  8 00:47:24 1998
+++ linux/drivers/ap1000/bif.c	Mon Jul  5 20:35:18 1999
@@ -30,7 +30,6 @@
X #include <asm/io.h>
X 
X #include <linux/inet.h>
-#include <linux/netdevice.h>
X #include <linux/etherdevice.h>
X #include <linux/skbuff.h>
X #include <net/sock.h>
diff -u --recursive --new-file v2.3.9/linux/drivers/ap1000/ringbuf.c linux/drivers/ap1000/ringbuf.c
--- v2.3.9/linux/drivers/ap1000/ringbuf.c	Wed Jun 30 13:38:19 1999
+++ linux/drivers/ap1000/ringbuf.c	Sun Jul  4 10:02:30 1999
@@ -318,6 +318,7 @@
X 	NULL,			/* mknod */
X 	NULL,			/* rename */
X 	NULL,			/* readlink */
+	NULL,			/* follow_link */
X 	NULL,			/* get_block */
X 	NULL,			/* readpage */
X 	NULL,			/* writepage */
diff -u --recursive --new-file v2.3.9/linux/drivers/block/Config.in linux/drivers/block/Config.in
--- v2.3.9/linux/drivers/block/Config.in	Wed Jun 30 13:38:19 1999
+++ linux/drivers/block/Config.in	Mon Jul  5 19:52:13 1999
@@ -41,30 +41,49 @@
X         bool '     Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI
X         if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then
X           bool '     Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO
+          if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+            bool '       Good-Bad DMA Model-Firmware (EXPERIMENTAL)' IDEDMA_NEW_DRIVE_LISTINGS
+            bool '       Generic ATA-66 support (DANGEROUS)' CONFIG_IDEDMA_ULTRA_66
+            define_bool IDEDMA_PCI_EXPERIMENTAL y
+          else
+            define_bool IDEDMA_PCI_EXPERIMENTAL n
+          fi
X         fi
X         bool '     Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD
X         bool '     AEC6210 chipset support' CONFIG_BLK_DEV_AEC6210
+        if [ "$IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
+          bool '     ALI M15x3 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_ALI15X3
+          bool '     CMD646 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CMD646
+          bool '     CY82C693 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CY82C693
+        fi
+        bool '     HPT34X chipset support' CONFIG_BLK_DEV_HPT34X
+        if [ "$IDEDMA_PCI_EXPERIMENTAL" = "y" -a \
+             "$CONFIG_BLK_DEV_HPT34X" = "y" ]; then
+          bool '       HPT34X DMA support (DANGEROUS)' CONFIG_BLK_DEV_HPT34X_DMA
+        fi
+        bool '     Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX
+        if [ "$IDEDMA_PCI_EXPERIMENTAL" = "y" -a \
+             "$CONFIG_BLK_DEV_PIIX" = "y" ]; then
+          bool '       PIIXn Tuning support (EXPERIMENTAL)' CONFIG_BLK_DEV_PIIX_TUNING
+        fi
+        if [ "$IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
+          bool '     NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415
+        fi
X         if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
X           bool '     OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621
-          bool '     Intel PIIXn chipsets support (EXPERIMENTAL)' CONFIG_BLK_DEV_PIIX
-          if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then
-            bool '     Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290
-            bool '     NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415
-            bool '     VIA82C586 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82C586
-            bool '     CMD646 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CMD646
-            bool '     ALI M15x3 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_ALI15X3
-            bool '     CY82C693 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CY82C693
-            bool '     PDC20246 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC20246
-            bool '     PDC20262 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC20262
-            if [ "$CONFIG_BLK_DEV_PDC20246" = "y" -o \
-                 "$CONFIG_BLK_DEV_PDC20262" = "y" ]; then
-              define_bool CONFIG_BLK_DEV_PDC202XX y
-            else
-              define_bool CONFIG_BLK_DEV_PDC202XX n
-            fi
-            bool '     HPT343 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_HPT343
+        fi
+        if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then
+          bool '     PROMISE PDC20246/PDC20262 support' CONFIG_BLK_DEV_PDC202XX
+          if [ "$CONFIG_EXPERIMENTAL" = "y" -a \
+               "$CONFIG_BLK_DEV_PDC202XX" = "y" ]; then
+            bool '       Special UDMA Feature (EXPERIMENTAL)' PDC202XX_FORCE_BURST_BIT
+            bool '       Special Mode Feature (DANGEROUS)' PDC202XX_FORCE_MASTER_MODE
X           fi
X         fi
+        if [ "$IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
+          bool '     Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290
+          bool '     VIA82C586 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82C586
+        fi
X       fi
X       if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then
X           bool '   Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105
@@ -106,13 +125,12 @@
X       bool '     ALI M14xx support' CONFIG_BLK_DEV_ALI14XX
X       bool '     DTC-2278 support' CONFIG_BLK_DEV_DTC2278
X       bool '     Holtek HT6560B support' CONFIG_BLK_DEV_HT6560B
+      if [ "$CONFIG_BLK_DEV_IDEDISK" = "y" -a \
+           "$CONFIG_EXPERIMENTAL" = "y" ]; then
+        bool '     PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030
+      fi
X       bool '     QDI QD6580 support' CONFIG_BLK_DEV_QD6580
X       bool '     UMC-8672 support' CONFIG_BLK_DEV_UMC8672
-      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-        if [ "$CONFIG_BLK_DEV_IDEDISK" = "y" ]; then
-          bool '     PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030
-        fi
-      fi
X     fi
X     if [ "$CONFIG_AMIGA" = "y" ]; then
X       bool '   Amiga Gayle IDE interface support' CONFIG_BLK_DEV_GAYLE
@@ -145,6 +163,7 @@
X     dep_tristate 'Atari SLM laser printer support' CONFIG_ATARI_SLM $CONFIG_ATARI_ACSI
X   fi
X fi
+tristate 'Compaq SMART2 support' CONFIG_BLK_CPQ_DA
X 
X comment 'Additional Block Devices'
X 
@@ -182,13 +201,13 @@
X   source drivers/block/paride/Config.in
X fi
X 
-
-if [ "$CONFIG_BLK_DEV_CMD640" = "y" -o \
-     "$CONFIG_IDE_CHIPSETS" = "y" -o \
-     "$CONFIG_BLK_DEV_OPTI621" = "y" -o \
-     "$CONFIG_BLK_DEV_IDE_PMAC" = "y" -o \
+if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \
+     "$CONFIG_BLK_DEV_ALI15X3" = "y" -o \
+     "$CONFIG_BLK_DEV_CMD640" = "y" -o \
X      "$CONFIG_BLK_DEV_CY82C693" = "y" -o \
-     "$CONFIG_BLK_DEV_HPT343" = "y" -o \
+     "$CONFIG_BLK_DEV_HPT34X" = "y" -o \
+     "$CONFIG_BLK_DEV_IDE_PMAC" = "y" -o \
+     "$CONFIG_BLK_DEV_OPTI621" = "y" -o \
X      "$CONFIG_BLK_DEV_PIIX" = "y" -o \
X      "$CONFIG_BLK_DEV_SL82C105" = "y" ]; then
X   define_bool CONFIG_BLK_DEV_IDE_MODES y
diff -u --recursive --new-file v2.3.9/linux/drivers/block/Makefile linux/drivers/block/Makefile
--- v2.3.9/linux/drivers/block/Makefile	Wed May 26 09:30:31 1999
+++ linux/drivers/block/Makefile	Mon Jul  5 19:52:13 1999
@@ -202,8 +202,8 @@
X IDE_OBJS += aec6210.o
X endif
X 
-ifeq ($(CONFIG_BLK_DEV_HPT343),y)
-IDE_OBJS += hpt343.o
+ifeq ($(CONFIG_BLK_DEV_HPT34X),y)
+IDE_OBJS += hpt34x.o
X endif
X 
X ### if CONFIG_BLK_DEV_IDE is n, IDE_OBJS will be ignored
@@ -271,6 +271,14 @@
X else
X   ifeq ($(CONFIG_BLK_DEV_XD),m)
X   M_OBJS += xd.o
+  endif
+endif
+
+ifeq ($(CONFIG_BLK_CPQ_DA),y)
+L_OBJS += cpqarray.o
+else
+  ifeq ($(CONFIG_BLK_CPQ_DA),m)
+  M_OBJS += cpqarray.o
X   endif
X endif
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/block/alim15x3.c linux/drivers/block/alim15x3.c
--- v2.3.9/linux/drivers/block/alim15x3.c	Wed May 26 16:55:40 1999
+++ linux/drivers/block/alim15x3.c	Thu Jul  1 10:25:38 1999
@@ -1,5 +1,5 @@
X /*
- * linux/drivers/block/alim15x3.c	Version 0.04	Feb. 8, 1999
+ * linux/drivers/block/alim15x3.c	Version 0.05	Jun. 29, 1999
X  *
X  *  Copyright (C) 1998-99 Michel Aubry, Maintainer
X  *  Copyright (C) 1998-99 Andrzej Krzysztofowicz, Maintainer
@@ -20,6 +20,8 @@
X 
X #include <asm/io.h>
X 
+#include "ide_modes.h"
+
X #define DISPLAY_ALI_TIMINGS
X 
X #if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
@@ -59,6 +61,55 @@
X };
X #endif  /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
X 
+static void ali15x3_tune_drive (ide_drive_t *drive, byte pio)
+{
+	ide_pio_data_t d;
+	ide_hwif_t *hwif = HWIF(drive);
+	struct pci_dev *dev = hwif->pci_dev;
+	int s_time, a_time, c_time;
+	byte s_clc, a_clc, r_clc;
+	unsigned long flags;
+	int bus_speed = ide_system_bus_speed();
+	int port = hwif->index ? 0x5c : 0x58;
+
+	pio = ide_get_best_pio_mode(drive, pio, 5, &d);
+	s_time = ide_pio_timings[pio].setup_time;
+	a_time = ide_pio_timings[pio].active_time;
+	if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8)
+		s_clc = 0;
+	if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8)
+		a_clc = 0;
+	c_time = ide_pio_timings[pio].cycle_time;
+
+#if 0
+	if ((r_clc = ((c_time - s_time - a_time) * bus_speed + 999) / 1000) >= 16)
+		r_clc = 0;
+#endif
+
+	if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) {
+		r_clc = 1;
+	} else {
+		if (r_clc >= 16)
+		r_clc = 0;
+	}
+	save_flags(flags);
+	cli();
+	pci_write_config_byte(dev, port, s_clc);
+	pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc);
+	restore_flags(flags);
+
+	/*
+	 * setup   active  rec
+	 * { 70,   165,    365 },   PIO Mode 0
+	 * { 50,   125,    208 },   PIO Mode 1
+	 * { 30,   100,    110 },   PIO Mode 2
+	 * { 30,   80,     70  },   PIO Mode 3 with IORDY
+	 * { 25,   70,     25  },   PIO Mode 4 with IORDY  ns
+	 * { 20,   50,     30  }    PIO Mode 5 with IORDY (nonstandard)
+	 */
+
+}
+
X __initfunc(unsigned int pci_init_ali15x3 (struct pci_dev *dev, const char *name))
X {
X 	byte confreg0 = 0, confreg1 =0, progif = 0;
@@ -146,19 +197,22 @@
X __initfunc(void ide_init_ali15x3 (ide_hwif_t *hwif))
X {
X 	struct pci_dev *dev;
-	byte ideic, inmir;
+	byte ideic, inmir, iderev;
X 	byte irq_routing_table[] = { -1,  9, 3, 10, 4,  5, 7,  6,
X 				      1, 11, 0, 12, 0, 14, 0, 15 };
+
+	pci_read_config_byte(hwif->pci_dev, PCI_REVISION_ID, &iderev);
+
X 	hwif->irq = hwif->channel ? 15 : 14;
X 	for (dev = pci_devices; dev; dev=dev->next) /* look for ISA bridge */
X 		if (dev->vendor==PCI_VENDOR_ID_AL &&
-		   dev->device==PCI_DEVICE_ID_AL_M1533)
+		    dev->device==PCI_DEVICE_ID_AL_M1533)
X 			break;
X 	if (dev) {			
X 		pci_read_config_byte(dev, 0x58, &ideic);
X 		ideic = ideic & 0x03;
X 		if ((hwif->channel && ideic == 0x03) ||
-		   (!hwif->channel && !ideic)) {
+		    (!hwif->channel && !ideic)) {
X 			pci_read_config_byte(dev, 0x44, &inmir);
X 			inmir = inmir & 0x0f;
X 			hwif->irq = irq_routing_table[inmir];
@@ -174,8 +228,15 @@
X 	ali_display_info = &ali_get_info;
X #endif  /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
X 
-	if (hwif->dma_base)
+	hwif->tuneproc = &ali15x3_tune_drive;
+	if ((hwif->dma_base) && (iderev >= 0xC1)) {
+		/* M1543C or newer for DMAing */
X 		hwif->dmaproc = &ali15x3_dmaproc;
+	} else {
+		hwif->autodma = 0;
+		hwif->drives[0].autotune = 1;
+		hwif->drives[1].autotune = 1;
+	}
X 	return;
X }
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/block/amiflop.c linux/drivers/block/amiflop.c
--- v2.3.9/linux/drivers/block/amiflop.c	Tue May 11 23:33:42 1999
+++ linux/drivers/block/amiflop.c	Tue Jul  6 19:05:48 1999
@@ -1755,13 +1755,13 @@
X 	NULL,			/* revalidate */
X };
X 
-__initfunc(void amiga_floppy_setup (char *str, int *ints))
+void __init amiga_floppy_setup (char *str, int *ints)
X {
X 	printk (KERN_INFO "amiflop: Setting default df0 to %x\n", ints[1]);
X 	fd_def_df0 = ints[1];
X }
X 
-__initfunc(static int fd_probe_drives(void))
+static int __init fd_probe_drives(void)
X {
X 	int drive,drives,nomem;
X 
@@ -1791,7 +1791,7 @@
X 	return -ENOMEM;
X }
X 
-__initfunc(int amiga_floppy_init(void))
+int __init amiga_floppy_init(void)
X {
X   int i;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/block/ataflop.c linux/drivers/block/ataflop.c
--- v2.3.9/linux/drivers/block/ataflop.c	Sat May 15 23:43:04 1999
+++ linux/drivers/block/ataflop.c	Tue Jul  6 19:05:48 1999
@@ -1771,7 +1771,7 @@
X 
X /* Initialize the 'unit' variable for drive 'drive' */
X 
-__initfunc(static void fd_probe( int drive ))
+static void __init fd_probe( int drive )
X {
X 	UD.connected = 0;
X 	UDT  = NULL;
@@ -1814,7 +1814,7 @@
X  * declared absent.
X  */
X 
-__initfunc(static int fd_test_drive_present( int drive ))
+static int __init fd_test_drive_present( int drive )
X {
X 	unsigned long timeout;
X 	unsigned char status;
@@ -1861,7 +1861,7 @@
X  * floppies, additionally start the disk-change and motor-off timers.
X  */
X 
-__initfunc(static void config_types( void ))
+static void __init config_types( void )
X {
X 	int drive, cnt = 0;
X 
@@ -2006,7 +2006,7 @@
X 	floppy_revalidate,	/* revalidate */
X };
X 
-__initfunc(int atari_floppy_init (void))
+int __init atari_floppy_init (void)
X {
X 	int i;
X 
@@ -2075,7 +2075,7 @@
X }
X 
X 
-__initfunc(void atari_floppy_setup( char *str, int *ints ))
+void __init atari_floppy_setup( char *str, int *ints )
X {
X 	int i;
X 	
diff -u --recursive --new-file v2.3.9/linux/drivers/block/cmd646.c linux/drivers/block/cmd646.c
--- v2.3.9/linux/drivers/block/cmd646.c	Thu May 27 09:55:21 1999
+++ linux/drivers/block/cmd646.c	Tue Jul  6 19:05:48 1999
@@ -1,4 +1,4 @@
-/* $Id: cmd646.c,v 1.13 1999/05/27 04:49:38 davem Exp $
+/* $Id: cmd646.c,v 1.14 1999/07/03 08:56:09 davem Exp $
X  * cmd646.c: Enable interrupts at initialization time on Ultra/PCI machines.
X  *           Note, this driver is not used at all on other systems because
X  *           there the "BIOS" has done all of the following already.
@@ -94,6 +94,9 @@
X 
X static void cmd646_do_setfeature(ide_drive_t *drive, byte command)
X {
+#if 0
+	(void) ide_config_drive_speed(drive, command);
+#else
X 	unsigned long flags;
X 	byte old_select;
X 
@@ -116,6 +119,7 @@
X out:
X 	OUT_BYTE(old_select, IDE_SELECT_REG);
X 	restore_flags(flags);
+#endif
X }
X 
X static void cmd646_dma2_enable(ide_drive_t *drive, unsigned long dma_base)
@@ -236,7 +240,7 @@
X 	return cmd646_dmaproc(func, drive);
X }
X 
-__initfunc(void ide_init_cmd646 (ide_hwif_t *hwif))
+void __init ide_init_cmd646 (ide_hwif_t *hwif)
X {
X 	struct pci_dev *dev = hwif->pci_dev;
X 	unsigned char mrdmode;
diff -u --recursive --new-file v2.3.9/linux/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c
--- v2.3.9/linux/drivers/block/cpqarray.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/block/cpqarray.c	Tue Jul  6 10:11:40 1999
@@ -0,0 +1,1730 @@
+/*
+ *    Disk Array driver for Compaq SMART2 Controllers
+ *    Copyright 1998 Compaq Computer Corporation
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *    NON INFRINGEMENT.  See the GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *    Questions/Comments/Bugfixes to arr...@compaq.com
+ *
+ *    If you want to make changes, improve or add functionality to this
+ *    driver, you'll probably need the Compaq Array Controller Interface
+ *    Specificiation (Document number ECG086/1198)
+ */
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/blkpg.h>
+#include <linux/timer.h>
+#include <linux/proc_fs.h>
+#include <linux/hdreg.h>
+#include <asm/uaccess.h>
+#include <asm/spinlock.h>
+#include <asm/io.h>
+
+
+#define SMART2_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
+
+#define DRIVER_NAME "Compaq SMART2 Driver (v 1.0.4)"
+#define DRIVER_VERSION SMART2_DRIVER_VERSION(1,0,4)
+#define MAJOR_NR COMPAQ_SMART2_MAJOR
+#include <linux/blk.h>
+#include <linux/blkdev.h>
+#include <linux/genhd.h>
+
+#include "cpqarray.h"
+#include "ida_cmd.h"
+#include "smart1,2.h"
+#include "ida_ioctl.h"
+
+#define READ_AHEAD	128
+#define NR_CMDS		128 /* This could probably go as high as ~400 */
+
+#define MAX_CTLR	8
+#define CTLR_SHIFT	8
+
+static int nr_ctlr = 0;
+static ctlr_info_t *hba[MAX_CTLR] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static int eisa[8] = { 0, 0 ,0 ,0, 0, 0 ,0 ,0 };
+
+#define NR_PRODUCTS (sizeof(products)/sizeof(struct board_type))
+
+/*  board_id = Subsystem Device ID & Vendor ID
+ *  product = Marketing Name for the board
+ *  access = Address of the struct of function pointers 
+ */
+struct board_type products[] = {
+	{ 0x0040110E, "IDA",			&smart1_access },
+	{ 0x0140110E, "IDA-2",			&smart1_access },
+	{ 0x1040110E, "IAES",			&smart1_access },
+	{ 0x2040110E, "SMART",			&smart1_access },
+	{ 0x3040110E, "SMART-2/E",		&smart2e_access },
+	{ 0x40300E11, "SMART-2/P",		&smart2_access },
+	{ 0x40310E11, "SMART-2SL",		&smart2_access },
+	{ 0x40320E11, "Smart Array 3200",	&smart2_access },
+	{ 0x40330E11, "Smart Array 3100ES",	&smart2_access },
+	{ 0x40340E11, "Smart Array 221",	&smart2_access },
+	{ 0x40400E11, "Integrated Array",	&smart4_access },
+	{ 0x40500E11, "Smart Array 4200",	&smart4_access },
+	{ 0x40510E11, "Smart Array 4250ES",	&smart4_access },
+};
+
+static struct hd_struct * ida;
+static int * ida_sizes;
+static int * ida_blocksizes;
+static int * ida_hardsizes;
+static struct gendisk ida_gendisk[MAX_CTLR];
+
+struct proc_dir_entry *proc_array = NULL;
+
+/* Debug... */
+#define DBG(s)	do { s } while(0)
+/* Debug (general info)... */
+#define DBGINFO(s) do { } while(0)
+/* Debug Paranoid... */
+#define DBGP(s)  do { } while(0)
+/* Debug Extra Paranoid... */
+#define DBGPX(s) do { } while(0)
+
+void cpqarray_init(void);
+static int cpqarray_pci_detect(void);
+static int cpqarray_pci_init(ctlr_info_t *c, unchar bus, unchar device_fn);
+static ulong remap_pci_mem(ulong base, ulong size);
+static int cpqarray_eisa_detect(void);
+static int pollcomplete(int ctlr);
+static void getgeometry(int ctlr);
+static void start_fwbk(int ctlr);
+
+static cmdlist_t * cmd_alloc(ctlr_info_t *h);
+static void cmd_free(ctlr_info_t *h, cmdlist_t *c);
+
+static int sendcmd(
+	__u8	cmd,
+	int	ctlr,
+	void	*buff,
+	size_t	size,
+	unsigned int blk,
+	unsigned int blkcnt,
+	unsigned int log_unit );
+
+static int ida_open(struct inode *inode, struct file *filep);
+static int ida_release(struct inode *inode, struct file *filep);
+static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
+static int ida_ctlr_ioctl(int ctlr, int dsk, ida_ioctl_t *io);
+
+static void do_ida_request(int i);
+/*
+ * This is a hack.  This driver eats a major number for each controller, and
+ * sets blkdev[xxx].request_fn to each one of these so the real request
+ * function knows what controller its working with.
+ */
+#define DO_IDA_REQUEST(x) { do_ida_request(x); }
+
+static void do_ida_request0(void) DO_IDA_REQUEST(0);
+static void do_ida_request1(void) DO_IDA_REQUEST(1);
+static void do_ida_request2(void) DO_IDA_REQUEST(2);
+static void do_ida_request3(void) DO_IDA_REQUEST(3);
+static void do_ida_request4(void) DO_IDA_REQUEST(4);
+static void do_ida_request5(void) DO_IDA_REQUEST(5);
+static void do_ida_request6(void) DO_IDA_REQUEST(6);
+static void do_ida_request7(void) DO_IDA_REQUEST(7);
+
+static void start_io(ctlr_info_t *h);
+
+static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c);
+static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c);
+static inline void complete_buffers(struct buffer_head *bh, int ok);
+static inline void complete_command(cmdlist_t *cmd, int timeout);
+
+static void do_ida_intr(int irq, void *dev_id, struct pt_regs * regs);
+static void ida_timer(unsigned long tdata);
+static int frevalidate_logvol(kdev_t dev);
+static int revalidate_logvol(kdev_t dev, int maxusage);
+static int revalidate_allvol(kdev_t dev);
+
+static void ida_procinit(int i);
+static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
+
+static void ida_geninit(struct gendisk *g)
+{
+	int ctlr = g-ida_gendisk;
+	int i,j;
+	drv_info_t *drv;
+
+	for(i=0; i<NWD; i++) {
+		drv = &hba[ctlr]->drv[i];
+		if (!drv->nr_blks)
+			continue;
+		ida[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)].nr_sects =
+		ida_sizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)] =
+				drv->nr_blks;
+
+		for(j=0; j<16; j++) {
+			ida_blocksizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)+j] =
+				1024;
+			ida_hardsizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)+j] =
+				drv->blk_size;
+		}
+		ida_gendisk[ctlr].nr_real++;
+	}
+
+}
+
+struct file_operations ida_fops  = {
+	NULL,                        /* lseek - default */
+	block_read,                  /* read - general block-dev read */
+	block_write,                 /* write - general block-dev write */
+	NULL,                        /* readdir - bad */
+	NULL,                        /* select */
+	ida_ioctl,                  /* ioctl */
+	NULL,                        /* mmap */
+	ida_open,                     /* open code */
+	NULL,
+	ida_release,                  /* release */
+	block_fsync,	              /* fsync */
+	NULL,                        /* fasync */
+	NULL,			/* Disk change */
+	frevalidate_logvol,	/* revalidate */
+};
+
+
+/*
+ * Get us a file in /proc/array that says something about each controller.
+ * Create /proc/array if it doesn't exist yet.
+ */
+static void ida_procinit(int i)
+{
+	struct proc_dir_entry *pd;
+
+	if (proc_array == NULL) {
+		proc_array = create_proc_entry("array", S_IFDIR|S_IRUGO|S_IXUGO,
+								&proc_root);
+		if (!proc_array) return;
+	}
+
+	pd = create_proc_entry(hba[i]->devname, S_IFREG|S_IRUGO, proc_array);
+	if (!pd) return;
+	pd->read_proc = ida_proc_get_info;
+	pd->data = hba[i];
+}
+
+/*
+ * Report information about this controller.
+ */
+static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
+{
+	off_t pos = 0;
+	off_t len = 0;
+	int size, i, ctlr;
+	ctlr_info_t *h = (ctlr_info_t*)data;
+	drv_info_t *drv;
+#ifdef CPQ_PROC_PRINT_QUEUES
+	cmdlist_t *c;
+#endif
+
+	ctlr = h->ctlr;
+	size = sprintf(buffer, "%s:  Compaq %s Controller\n"
+		"       Board ID: %08lx\n"
+		"       Firmware Revision: %c%c%c%c\n"
+		"       Controller Sig: %08lx\n"
+		"       Memory Address: %08lx\n"
+		"       I/O Port: %04x\n"
+		"       IRQ: %x\n"
+		"       Logical drives: %d\n"
+		"       Physical drives: %d\n\n"
+		"       Current Q depth: %d\n"
+		"       Max Q depth since init: %d\n\n",
+		h->devname, 
+		h->product_name,
+		(unsigned long)h->board_id,
+		h->firm_rev[0], h->firm_rev[1], h->firm_rev[2], h->firm_rev[3],
+		(unsigned long)h->ctlr_sig, (unsigned long)h->vaddr,
+		(unsigned int) h->ioaddr, (unsigned int)h->intr,
+		h->log_drives, h->phys_drives,
+		h->Qdepth, h->maxQsinceinit);
+
+	pos += size; len += size;
+	
+	size = sprintf(buffer+len, "Logical Drive Info:\n");
+	pos += size; len += size;
+
+	for(i=0; i<h->log_drives; i++) {
+		drv = &h->drv[i];
+		size = sprintf(buffer+len, "ida/c%dd%d: blksz=%d nr_blks=%d\n",
+				ctlr, i, drv->blk_size, drv->nr_blks);
+		pos += size; len += size;
+	}
+
+#ifdef CPQ_PROC_PRINT_QUEUES
+	size = sprintf(buffer+len, "\nCurrent Queues:\n");
+	pos += size; len += size;
+
+	c = h->reqQ;
+	size = sprintf(buffer+len, "reqQ = %p", c); pos += size; len += size;
+	if (c) c=c->next;
+	while(c && c != h->reqQ) {
+		size = sprintf(buffer+len, "->%p", c);
+		pos += size; len += size;
+		c=c->next;
+	}
+
+	c = h->cmpQ;
+	size = sprintf(buffer+len, "\ncmpQ = %p", c); pos += size; len += size;
+	if (c) c=c->next;
+	while(c && c != h->cmpQ) {
+		size = sprintf(buffer+len, "->%p", c);
+		pos += size; len += size;
+		c=c->next;
+	}
+
+	size = sprintf(buffer+len, "\n"); pos += size; len += size;
+#endif
+	size = sprintf(buffer+len, "nr_allocs = %d\nnr_frees = %d\n",
+			h->nr_allocs, h->nr_frees);
+	pos += size; len += size;
+
+	*eof = 1;
+	*start = buffer+offset;
+	len -= offset;
+	if (len>length)
+		len = length;
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 04'
echo 'File patch-2.3.10 is continued in part 05'
echo 05 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 08 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
+   GIRQ1 signals that ZR36060's DATERR# line is asserted.
+
+   SAA7111A
+
+   In their infinite wisdom, the Iomega engineers decided to
+   use the same input line for composite and S-Video Color,
+   although there are two entries not connected at all!
+   Through this ingenious strike, it is not possible to
+   keep two running video sources connected at the same time
+   to Composite and S-VHS input!
+
+   mode 0 - N/C
+   mode 1 - S-Video Y
+   mode 2 - noise or something I don't know
+   mode 3 - Composite and S-Video C
+   mode 4 - N/C
+   mode 5 - S-Video (gain C independently selectable of gain Y)
+   mode 6 - N/C
+   mode 7 - S-Video (gain C adapted to gain Y)
+ */
+
+#define MAJOR_VERSION 1		/* driver major version */
+#define MINOR_VERSION 0		/* driver minor version */
+
+#define BUZ_NAME      "Iomega BUZ V-1.0"	/* name of the driver */
+
+#define DEBUG(x)		/* Debug driver */
+#define IDEBUG(x)		/* Debug interrupt handler */
+#define IOCTL_DEBUG(x)
+
+
+/* The parameters for this driver */
+
+/*
+   The video mem address of the video card.
+   The driver has a little database for some videocards
+   to determine it from there. If your video card is not in there
+   you have either to give it to the driver as a parameter
+   or set in in a VIDIOCSFBUF ioctl
+ */
+
+static unsigned long vidmem = 0;	/* Video memory base address */
+
+/* Special purposes only: */
+
+static int triton = 0;		/* 0=no, 1=yes */
+static int natoma = 0;		/* 0=no, 1=yes */
+
+/*
+   Number and size of grab buffers for Video 4 Linux
+   The vast majority of applications should not need more than 2,
+   the very popular BTTV driver actually does ONLY have 2.
+   Time sensitive applications might need more, the maximum
+   is VIDEO_MAX_FRAME (defined in <linux/videodev.h>).
+
+   The size is set so that the maximum possible request
+   can be satisfied. Decrease  it, if bigphys_area alloc'd
+   memory is low. If you don't have the bigphys_area patch,
+   set it to 128 KB. Will you allow only to grab small
+   images with V4L, but that's better than nothing.
+
+   v4l_bufsize has to be given in KB !
+
+ */
+
+static int v4l_nbufs = 2;
+static int v4l_bufsize = 128;	/* Everybody should be able to work with this setting */
+
+/*
+   Default input and video norm at startup of the driver.
+ */
+
+static int default_input = 0;	/* 0=Composite, 1=S-VHS */
+static int default_norm = 0;	/* 0=PAL, 1=NTSC */
+
+MODULE_PARM(vidmem, "i");
+MODULE_PARM(triton, "i");
+MODULE_PARM(natoma, "i");
+MODULE_PARM(v4l_nbufs, "i");
+MODULE_PARM(v4l_bufsize, "i");
+MODULE_PARM(default_input, "i");
+MODULE_PARM(default_norm, "i");
+
+/* Anybody who uses more than four? */
+#define BUZ_MAX 4
+
+static int zoran_num;		/* number of Buzs in use */
+static struct zoran zoran[BUZ_MAX];
+
+/* forward references */
+
+static void v4l_fbuffer_free(struct zoran *zr);
+static void jpg_fbuffer_free(struct zoran *zr);
+static void zoran_feed_stat_com(struct zoran *zr);
+
+
+
+/*
+ *   Allocate the V4L grab buffers
+ *
+ *   These have to be pysically contiguous.
+ *   If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc
+ */
+
+static int v4l_fbuffer_alloc(struct zoran *zr)
+{
+	int i, off;
+	unsigned char *mem;
+
+	for (i = 0; i < v4l_nbufs; i++) {
+		if (zr->v4l_gbuf[i].fbuffer)
+			printk(KERN_WARNING "%s: v4l_fbuffer_alloc: buffer %d allready allocated ?\n", zr->name, i);
+
+		if (v4l_bufsize <= MAX_KMALLOC_MEM) {
+			/* Use kmalloc */
+
+			mem = (unsigned char *) kmalloc(v4l_bufsize, GFP_KERNEL);
+			if (mem == 0) {
+				printk(KERN_ERR "%s: kmalloc for V4L bufs failed\n", zr->name);
+				v4l_fbuffer_free(zr);
+				return -ENOBUFS;
+			}
+			zr->v4l_gbuf[i].fbuffer = mem;
+			zr->v4l_gbuf[i].fbuffer_phys = virt_to_phys(mem);
+			zr->v4l_gbuf[i].fbuffer_bus = virt_to_bus(mem);
+			for (off = 0; off < v4l_bufsize; off += PAGE_SIZE)
+				mem_map_reserve(MAP_NR(mem + off));
+			DEBUG(printk(BUZ_INFO ": V4L frame %d mem 0x%x (bus: 0x%x=%d)\n", i, mem, virt_to_bus(mem), virt_to_bus(mem)));
+		} else {
+			return -ENOBUFS;
+		}
+	}
+
+	return 0;
+}
+
+/* free the V4L grab buffers */
+static void v4l_fbuffer_free(struct zoran *zr)
+{
+	int i, off;
+	unsigned char *mem;
+
+	for (i = 0; i < v4l_nbufs; i++) {
+		if (!zr->v4l_gbuf[i].fbuffer)
+			continue;
+
+		mem = zr->v4l_gbuf[i].fbuffer;
+		for (off = 0; off < v4l_bufsize; off += PAGE_SIZE)
+			mem_map_unreserve(MAP_NR(mem + off));
+		kfree((void *) zr->v4l_gbuf[i].fbuffer);
+		zr->v4l_gbuf[i].fbuffer = NULL;
+	}
+}
+
+/*
+ *   Allocate the MJPEG grab buffers.
+ *
+ *   If the requested buffer size is smaller than MAX_KMALLOC_MEM,
+ *   kmalloc is used to request a physically contiguous area,
+ *   else we allocate the memory in framgents with get_free_page.
+ *
+ *   If a Natoma chipset is present and this is a revision 1 zr36057,
+ *   each MJPEG buffer needs to be physically contiguous.
+ *   (RJ: This statement is from Dave Perks' original driver,
+ *   I could never check it because I have a zr36067)
+ *   The driver cares about this because it reduces the buffer
+ *   size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation).
+ *
+ *   RJ: The contents grab buffers needs never be accessed in the driver.
+ *       Therefore there is no need to allocate them with vmalloc in order
+ *       to get a contiguous virtual memory space.
+ *       I don't understand why many other drivers first allocate them with
+ *       vmalloc (which uses internally also get_free_page, but delivers you
+ *       virtual addresses) and then again have to make a lot of efforts
+ *       to get the physical address.
+ *
+ */
+
+static int jpg_fbuffer_alloc(struct zoran *zr)
+{
+	int i, j, off, alloc_contig;
+	unsigned long mem;
+
+	/* Decide if we should alloc contiguous or fragmented memory */
+	/* This has to be identical in jpg_fbuffer_alloc and jpg_fbuffer_free */
+
+	alloc_contig = (zr->jpg_bufsize < MAX_KMALLOC_MEM);
+
+	for (i = 0; i < zr->jpg_nbufs; i++) {
+		if (zr->jpg_gbuf[i].frag_tab)
+			printk(KERN_WARNING "%s: jpg_fbuffer_alloc: buffer %d allready allocated ???\n", zr->name, i);
+
+		/* Allocate fragment table for this buffer */
+
+		mem = get_free_page(GFP_KERNEL);
+		if (mem == 0) {
+			printk(KERN_ERR "%s: jpg_fbuffer_alloc: get_free_page (frag_tab) failed for buffer %d\n", zr->name, i);
+			jpg_fbuffer_free(zr);
+			return -ENOBUFS;
+		}
+		memset((void *) mem, 0, PAGE_SIZE);
+		zr->jpg_gbuf[i].frag_tab = (u32 *) mem;
+		zr->jpg_gbuf[i].frag_tab_bus = virt_to_bus((void *) mem);
+
+		if (alloc_contig) {
+			mem = (unsigned long) kmalloc(zr->jpg_bufsize, GFP_KERNEL);
+			if (mem == 0) {
+				jpg_fbuffer_free(zr);
+				return -ENOBUFS;
+			}
+			zr->jpg_gbuf[i].frag_tab[0] = virt_to_bus((void *) mem);
+			zr->jpg_gbuf[i].frag_tab[1] = ((zr->jpg_bufsize / 4) << 1) | 1;
+			for (off = 0; off < zr->jpg_bufsize; off += PAGE_SIZE)
+				mem_map_reserve(MAP_NR(mem + off));
+		} else {
+			/* jpg_bufsize is alreay page aligned */
+			for (j = 0; j < zr->jpg_bufsize / PAGE_SIZE; j++) {
+				mem = get_free_page(GFP_KERNEL);
+				if (mem == 0) {
+					jpg_fbuffer_free(zr);
+					return -ENOBUFS;
+				}
+				zr->jpg_gbuf[i].frag_tab[2 * j] = virt_to_bus((void *) mem);
+				zr->jpg_gbuf[i].frag_tab[2 * j + 1] = (PAGE_SIZE / 4) << 1;
+				mem_map_reserve(MAP_NR(mem));
+			}
+
+			zr->jpg_gbuf[i].frag_tab[2 * j - 1] |= 1;
+		}
+	}
+
+	DEBUG(printk("jpg_fbuffer_alloc: %d KB allocated\n",
+		     (zr->jpg_nbufs * zr->jpg_bufsize) >> 10));
+	zr->jpg_buffers_allocated = 1;
+	return 0;
+}
+
+/* free the MJPEG grab buffers */
+static void jpg_fbuffer_free(struct zoran *zr)
+{
+	int i, j, off, alloc_contig;
+	unsigned char *mem;
+
+	/* Decide if we should alloc contiguous or fragmented memory */
+	/* This has to be identical in jpg_fbuffer_alloc and jpg_fbuffer_free */
+
+	alloc_contig = (zr->jpg_bufsize < MAX_KMALLOC_MEM);
+
+	for (i = 0; i < zr->jpg_nbufs; i++) {
+		if (!zr->jpg_gbuf[i].frag_tab)
+			continue;
+
+		if (alloc_contig) {
+			if (zr->jpg_gbuf[i].frag_tab[0]) {
+				mem = (unsigned char *) bus_to_virt(zr->jpg_gbuf[i].frag_tab[0]);
+				for (off = 0; off < zr->jpg_bufsize; off += PAGE_SIZE)
+					mem_map_unreserve(MAP_NR(mem + off));
+				kfree((void *) mem);
+				zr->jpg_gbuf[i].frag_tab[0] = 0;
+				zr->jpg_gbuf[i].frag_tab[1] = 0;
+			}
+		} else {
+			for (j = 0; j < zr->jpg_bufsize / PAGE_SIZE; j++) {
+				if (!zr->jpg_gbuf[i].frag_tab[2 * j])
+					break;
+				mem_map_unreserve(MAP_NR(bus_to_virt(zr->jpg_gbuf[i].frag_tab[2 * j])));
+				free_page((unsigned long) bus_to_virt(zr->jpg_gbuf[i].frag_tab[2 * j]));
+				zr->jpg_gbuf[i].frag_tab[2 * j] = 0;
+				zr->jpg_gbuf[i].frag_tab[2 * j + 1] = 0;
+			}
+		}
+
+		free_page((unsigned long) zr->jpg_gbuf[i].frag_tab);
+		zr->jpg_gbuf[i].frag_tab = NULL;
+	}
+	zr->jpg_buffers_allocated = 0;
+}
+
+
+/* ----------------------------------------------------------------------- */
+
+/* I2C functions                                                           */
+
+#define I2C_DELAY   10
+
+
+/* software I2C functions */
+
+static void i2c_setlines(struct i2c_bus *bus, int ctrl, int data)
+{
+	struct zoran *zr = (struct zoran *) bus->data;
+	btwrite((data << 1) | ctrl, ZR36057_I2CBR);
+	btread(ZR36057_I2CBR);
+	udelay(I2C_DELAY);
+}
+
+static int i2c_getdataline(struct i2c_bus *bus)
+{
+	struct zoran *zr = (struct zoran *) bus->data;
+	return (btread(ZR36057_I2CBR) >> 1) & 1;
+}
+
+void attach_inform(struct i2c_bus *bus, int id)
+{
+	DEBUG(struct zoran *zr = (struct zoran *) bus->data);
+	DEBUG(printk(BUZ_DEBUG "-%u: i2c attach %02x\n", zr->id, id));
+}
+
+void detach_inform(struct i2c_bus *bus, int id)
+{
+	DEBUG(struct zoran *zr = (struct zoran *) bus->data);
+	DEBUG(printk(BUZ_DEBUG "-%u: i2c detach %02x\n", zr->id, id));
+}
+
+static struct i2c_bus zoran_i2c_bus_template =
+{
+	"zr36057",
+	I2C_BUSID_BT848,
+	NULL,
+
+	SPIN_LOCK_UNLOCKED,
+
+	attach_inform,
+	detach_inform,
+
+	i2c_setlines,
+	i2c_getdataline,
+	NULL,
+	NULL,
+};
+
+
+/* ----------------------------------------------------------------------- */
+
+static void GPIO(struct zoran *zr, unsigned bit, unsigned value)
+{
+	u32 reg;
+	u32 mask;
+
+	mask = 1 << (24 + bit);
+	reg = btread(ZR36057_GPPGCR1) & ~mask;
+	if (value) {
+		reg |= mask;
+	}
+	btwrite(reg, ZR36057_GPPGCR1);
+	/* Stop any PCI posting on the GPIO bus */
+	btread(ZR36057_I2CBR);
+}
+
+
+/*
+ *   Set the registers for the size we have specified. Don't bother
+ *   trying to understand this without the ZR36057 manual in front of
+ *   you [AC].
+ *
+ *   PS: The manual is free for download in .pdf format from
+ *   www.zoran.com - nicely done those folks.
+ */
+
+struct tvnorm {
+	u16 Wt, Wa, Ht, Ha, HStart, VStart;
+};
+
+static struct tvnorm tvnorms[] =
+{
+   /* PAL-BDGHI */
+	{864, 720, 625, 576, 31, 16},
+   /* NTSC */
+	{858, 720, 525, 480, 21, 8},
+};
+#define TVNORMS (sizeof(tvnorms) / sizeof(tvnorm))
+
+static int format2bpp(int format)
+{
+	int bpp;
+
+	/* Determine the number of bytes per pixel for the video format requested */
+
+	switch (format) {
+
+	case VIDEO_PALETTE_YUV422:
+		bpp = 2;
+		break;
+
+	case VIDEO_PALETTE_RGB555:
+		bpp = 2;
+		break;
+
+	case VIDEO_PALETTE_RGB565:
+		bpp = 2;
+		break;
+
+	case VIDEO_PALETTE_RGB24:
+		bpp = 3;
+		break;
+
+	case VIDEO_PALETTE_RGB32:
+		bpp = 4;
+		break;
+
+	default:
+		bpp = 0;
+	}
+
+	return bpp;
+}
+
+/*
+ * set geometry
+ */
+static void zr36057_set_vfe(struct zoran *zr, int video_width, int video_height,
+			    unsigned int video_format)
+{
+	struct tvnorm *tvn;
+	unsigned HStart, HEnd, VStart, VEnd;
+	unsigned DispMode;
+	unsigned VidWinWid, VidWinHt;
+	unsigned hcrop1, hcrop2, vcrop1, vcrop2;
+	unsigned Wa, We, Ha, He;
+	unsigned X, Y, HorDcm, VerDcm;
+	u32 reg;
+	unsigned mask_line_size;
+
+	if (zr->params.norm < 0 || zr->params.norm > 1) {
+		printk(KERN_ERR "%s: set_vfe: video_norm = %d not valid\n", zr->name,  zr->params.norm);
+		return;
+	}
+	if (video_width < BUZ_MIN_WIDTH || video_height < BUZ_MIN_HEIGHT) {
+		printk(KERN_ERR "%s: set_vfe: w=%d h=%d not valid\n", zr->name, video_width, video_height);
+		return;
+	}
+	tvn = &tvnorms[zr->params.norm];
+
+	Wa = tvn->Wa;
+	Ha = tvn->Ha;
+
+	/* if window has more than half of active height,
+	   switch on interlacing - we want the full information */
+
+	zr->video_interlace = (video_height > Ha / 2);
+
+/**** zr36057 ****/
+
+	/* horizontal */
+	VidWinWid = video_width;
+	X = (VidWinWid * 64 + tvn->Wa - 1) / tvn->Wa;
+	We = (VidWinWid * 64) / X;
+	HorDcm = 64 - X;
+	hcrop1 = 2 * ((tvn->Wa - We) / 4);
+	hcrop2 = tvn->Wa - We - hcrop1;
+	HStart = tvn->HStart | 1;
+	HEnd = HStart + tvn->Wa - 1;
+	HStart += hcrop1;
+	HEnd -= hcrop2;
+	reg = ((HStart & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HStart)
+	    | ((HEnd & ZR36057_VFEHCR_Hmask) << ZR36057_VFEHCR_HEnd);
+	reg |= ZR36057_VFEHCR_HSPol;
+	btwrite(reg, ZR36057_VFEHCR);
+
+	/* Vertical */
+	DispMode = !zr->video_interlace;
+	VidWinHt = DispMode ? video_height : video_height / 2;
+	Y = (VidWinHt * 64 * 2 + tvn->Ha - 1) / tvn->Ha;
+	He = (VidWinHt * 64) / Y;
+	VerDcm = 64 - Y;
+	vcrop1 = (tvn->Ha / 2 - He) / 2;
+	vcrop2 = tvn->Ha / 2 - He - vcrop1;
+	VStart = tvn->VStart;
+	VEnd = VStart + tvn->Ha / 2 - 1;
+	VStart += vcrop1;
+	VEnd -= vcrop2;
+	reg = ((VStart & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VStart)
+	    | ((VEnd & ZR36057_VFEVCR_Vmask) << ZR36057_VFEVCR_VEnd);
+	reg |= ZR36057_VFEVCR_VSPol;
+	btwrite(reg, ZR36057_VFEVCR);
+
+	/* scaler and pixel format */
+	reg = 0			// ZR36057_VFESPFR_ExtFl /* Trying to live without ExtFl */
+	     | (HorDcm << ZR36057_VFESPFR_HorDcm)
+	    | (VerDcm << ZR36057_VFESPFR_VerDcm)
+	    | (DispMode << ZR36057_VFESPFR_DispMode)
+	    | ZR36057_VFESPFR_LittleEndian;
+	/* RJ: I don't know, why the following has to be the opposite
+	   of the corresponding ZR36060 setting, but only this way
+	   we get the correct colors when uncompressing to the screen  */
+	reg |= ZR36057_VFESPFR_VCLKPol;
+	/* RJ: Don't know if that is needed for NTSC also */
+	reg |= ZR36057_VFESPFR_TopField;
+	switch (video_format) {
+
+	case VIDEO_PALETTE_YUV422:
+		reg |= ZR36057_VFESPFR_YUV422;
+		break;
+
+	case VIDEO_PALETTE_RGB555:
+		reg |= ZR36057_VFESPFR_RGB555 | ZR36057_VFESPFR_ErrDif;
+		break;
+
+	case VIDEO_PALETTE_RGB565:
+		reg |= ZR36057_VFESPFR_RGB565 | ZR36057_VFESPFR_ErrDif;
+		break;
+
+	case VIDEO_PALETTE_RGB24:
+		reg |= ZR36057_VFESPFR_RGB888 | ZR36057_VFESPFR_Pack24;
+		break;
+
+	case VIDEO_PALETTE_RGB32:
+		reg |= ZR36057_VFESPFR_RGB888;
+		break;
+
+	default:
+		printk(KERN_INFO "%s: Unknown color_fmt=%x\n", zr->name, video_format);
+		return;
+
+	}
+	if (HorDcm >= 48) {
+		reg |= 3 << ZR36057_VFESPFR_HFilter;	/* 5 tap filter */
+	} else if (HorDcm >= 32) {
+		reg |= 2 << ZR36057_VFESPFR_HFilter;	/* 4 tap filter */
+	} else if (HorDcm >= 16) {
+		reg |= 1 << ZR36057_VFESPFR_HFilter;	/* 3 tap filter */
+	}
+	btwrite(reg, ZR36057_VFESPFR);
+
+	/* display configuration */
+
+	reg = (16 << ZR36057_VDCR_MinPix)
+	    | (VidWinHt << ZR36057_VDCR_VidWinHt)
+	    | (VidWinWid << ZR36057_VDCR_VidWinWid);
+	if (triton)
+		reg &= ~ZR36057_VDCR_Triton;
+	else
+		reg |= ZR36057_VDCR_Triton;
+	btwrite(reg, ZR36057_VDCR);
+
+	/* Write overlay clipping mask data, but don't enable overlay clipping */
+	/* RJ: since this makes only sense on the screen, we use 
+	   zr->window.width instead of video_width */
+
+	mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
+	reg = virt_to_bus(zr->overlay_mask);
+	btwrite(reg, ZR36057_MMTR);
+	reg = virt_to_bus(zr->overlay_mask + mask_line_size);
+	btwrite(reg, ZR36057_MMBR);
+	reg = mask_line_size - (zr->window.width + 31) / 32;
+	if (DispMode == 0)
+		reg += mask_line_size;
+	reg <<= ZR36057_OCR_MaskStride;
+	btwrite(reg, ZR36057_OCR);
+
+}
+
+/*
+ * Switch overlay on or off
+ */
+
+static void zr36057_overlay(struct zoran *zr, int on)
+{
+	int fmt, bpp;
+	u32 reg;
+
+	if (on) {
+		/* do the necessary settings ... */
+
+		btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);	/* switch it off first */
+
+		switch (zr->buffer.depth) {
+		case 15:
+			fmt = VIDEO_PALETTE_RGB555;
+			bpp = 2;
+			break;
+		case 16:
+			fmt = VIDEO_PALETTE_RGB565;
+			bpp = 2;
+			break;
+		case 24:
+			fmt = VIDEO_PALETTE_RGB24;
+			bpp = 3;
+			break;
+		case 32:
+			fmt = VIDEO_PALETTE_RGB32;
+			bpp = 4;
+			break;
+		default:
+			fmt = 0;
+			bpp = 0;
+		}
+
+		zr36057_set_vfe(zr, zr->window.width, zr->window.height, fmt);
+
+		/* Start and length of each line MUST be 4-byte aligned.
+		   This should be allready checked before the call to this routine.
+		   All error messages are internal driver checking only! */
+
+		/* video display top and bottom registers */
+
+		reg = (u32) zr->buffer.base
+		    + zr->window.x * bpp
+		    + zr->window.y * zr->buffer.bytesperline;
+		btwrite(reg, ZR36057_VDTR);
+		if (reg & 3)
+			printk(KERN_ERR "%s: zr36057_overlay: video_address not aligned\n", zr->name);
+		if (zr->video_interlace)
+			reg += zr->buffer.bytesperline;
+		btwrite(reg, ZR36057_VDBR);
+
+		/* video stride, status, and frame grab register */
+
+		reg = zr->buffer.bytesperline - zr->window.width * bpp;
+		if (zr->video_interlace)
+			reg += zr->buffer.bytesperline;
+		if (reg & 3)
+			printk(KERN_ERR "%s: zr36057_overlay: video_stride not aligned\n", zr->name);
+		reg = (reg << ZR36057_VSSFGR_DispStride);
+		reg |= ZR36057_VSSFGR_VidOvf;	/* clear overflow status */
+		btwrite(reg, ZR36057_VSSFGR);
+
+		/* Set overlay clipping */
+
+		if (zr->window.clipcount)
+			btor(ZR36057_OCR_OvlEnable, ZR36057_OCR);
+
+		/* ... and switch it on */
+
+		btor(ZR36057_VDCR_VidEn, ZR36057_VDCR);
+	} else {
+		/* Switch it off */
+
+		btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);
+	}
+}
+
+/*
+ * The overlay mask has one bit for each pixel on a scan line,
+ *  and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels.
+ */
+static void write_overlay_mask(struct zoran *zr, struct video_clip *vp, int count)
+{
+	unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
+	u32 *mask;
+	int x, y, width, height;
+	unsigned i, j, k;
+	u32 reg;
+
+	/* fill mask with one bits */
+	memset(zr->overlay_mask, ~0, mask_line_size * 4 * BUZ_MAX_HEIGHT);
+	reg = 0;
+
+	for (i = 0; i < count; ++i) {
+		/* pick up local copy of clip */
+		x = vp[i].x;
+		y = vp[i].y;
+		width = vp[i].width;
+		height = vp[i].height;
+
+		/* trim clips that extend beyond the window */
+		if (x < 0) {
+			width += x;
+			x = 0;
+		}
+		if (y < 0) {
+			height += y;
+			y = 0;
+		}
+		if (x + width > zr->window.width) {
+			width = zr->window.width - x;
+		}
+		if (y + height > zr->window.height) {
+			height = zr->window.height - y;
+		}
+		/* ignore degenerate clips */
+		if (height <= 0) {
+			continue;
+		}
+		if (width <= 0) {
+			continue;
+		}
+		/* apply clip for each scan line */
+		for (j = 0; j < height; ++j) {
+			/* reset bit for each pixel */
+			/* this can be optimized later if need be */
+			mask = zr->overlay_mask + (y + j) * mask_line_size;
+			for (k = 0; k < width; ++k) {
+				mask[(x + k) / 32] &= ~((u32) 1 << (x + k) % 32);
+			}
+		}
+	}
+}
+
+/* Enable/Disable uncompressed memory grabbing of the 36057 */
+
+static void zr36057_set_memgrab(struct zoran *zr, int mode)
+{
+	if (mode) {
+		if (btread(ZR36057_VSSFGR) & (ZR36057_VSSFGR_SnapShot | ZR36057_VSSFGR_FrameGrab))
+			printk(KERN_WARNING "%s: zr36057_set_memgrab_on with SnapShot or FrameGrab on ???\n", zr->name);
+
+		/* switch on VSync interrupts */
+
+		btwrite(IRQ_MASK, ZR36057_ISR);		// Clear Interrupts
+
+		btor(ZR36057_ICR_GIRQ0, ZR36057_ICR);
+
+		/* enable SnapShot */
+
+		btor(ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR);
+
+		/* Set zr36057 video front end  and enable video */
+
+#ifdef XAWTV_HACK
+		zr36057_set_vfe(zr, zr->gwidth > 720 ? 720 : zr->gwidth, zr->gheight, zr->gformat);
+#else
+		zr36057_set_vfe(zr, zr->gwidth, zr->gheight, zr->gformat);
+#endif
+
+		zr->v4l_memgrab_active = 1;
+	} else {
+		zr->v4l_memgrab_active = 0;
+
+		/* switch off VSync interrupts */
+
+		btand(~ZR36057_ICR_GIRQ0, ZR36057_ICR);
+
+		/* reenable grabbing to screen if it was running */
+
+		if (zr->v4l_overlay_active) {
+			zr36057_overlay(zr, 1);
+		} else {
+			btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);
+			btand(~ZR36057_VSSFGR_SnapShot, ZR36057_VSSFGR);
+		}
+	}
+}
+
+static int wait_grab_pending(struct zoran *zr)
+{
+	unsigned long flags;
+
+	/* wait until all pending grabs are finished */
+
+	if (!zr->v4l_memgrab_active)
+		return 0;
+
+	while (zr->v4l_pend_tail != zr->v4l_pend_head) {
+		interruptible_sleep_on(&zr->v4l_capq);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+	}
+
+	spin_lock_irqsave(&zr->lock, flags);
+	zr36057_set_memgrab(zr, 0);
+	spin_unlock_irqrestore(&zr->lock, flags);
+
+	return 0;
+}
+
+/*
+ *   V4L Buffer grabbing
+ */
+
+static int v4l_grab(struct zoran *zr, struct video_mmap *mp)
+{
+	unsigned long flags;
+	int res, bpp;
+
+	/*
+	 * There is a long list of limitations to what is allowed to be grabbed
+	 * We don't output error messages her, since some programs (e.g. xawtv)
+	 * just try several settings to find out what is valid or not.
+	 */
+
+	/* No grabbing outside the buffer range! */
+
+	if (mp->frame >= v4l_nbufs || mp->frame < 0)
+		return -EINVAL;
+
+	/* Check size and format of the grab wanted */
+
+	if (mp->height < BUZ_MIN_HEIGHT || mp->width < BUZ_MIN_WIDTH)
+		return -EINVAL;
+	if (mp->height > BUZ_MAX_HEIGHT || mp->width > BUZ_MAX_WIDTH)
+		return -EINVAL;
+
+	bpp = format2bpp(mp->format);
+	if (bpp == 0)
+		return -EINVAL;
+
+	/* Check against available buffer size */
+
+	if (mp->height * mp->width * bpp > v4l_bufsize)
+		return -EINVAL;
+
+	/* The video front end needs 4-byte alinged line sizes */
+
+	if ((bpp == 2 && (mp->width & 1)) || (bpp == 3 && (mp->width & 3)))
+		return -EINVAL;
+
+	/*
+	 * To minimize the time spent in the IRQ routine, we avoid setting up
+	 * the video front end there.
+	 * If this grab has different parameters from a running streaming capture
+	 * we stop the streaming capture and start it over again.
+	 */
+
+	if (zr->v4l_memgrab_active &&
+	    (zr->gwidth != mp->width || zr->gheight != mp->height || zr->gformat != mp->format)) {
+		res = wait_grab_pending(zr);
+		if (res)
+			return res;
+	}
+	zr->gwidth = mp->width;
+	zr->gheight = mp->height;
+	zr->gformat = mp->format;
+	zr->gbpl = bpp * zr->gwidth;
+
+
+	spin_lock_irqsave(&zr->lock, flags);
+
+	/* make sure a grab isn't going on currently with this buffer */
+
+	switch (zr->v4l_gbuf[mp->frame].state) {
+
+	default:
+	case BUZ_STATE_PEND:
+		res = -EBUSY;	/* what are you doing? */
+		break;
+
+	case BUZ_STATE_USER:
+	case BUZ_STATE_DONE:
+		/* since there is at least one unused buffer there's room for at least one more pend[] entry */
+		zr->v4l_pend[zr->v4l_pend_head++ & V4L_MASK_FRAME] = mp->frame;
+		zr->v4l_gbuf[mp->frame].state = BUZ_STATE_PEND;
+		res = 0;
+		break;
+
+	}
+
+	/* put the 36057 into frame grabbing mode */
+
+	if (!res && !zr->v4l_memgrab_active)
+		zr36057_set_memgrab(zr, 1);
+
+	spin_unlock_irqrestore(&zr->lock, flags);
+
+	return res;
+}
+
+/*
+ * Sync on a V4L buffer
+ */
+
+static int v4l_sync(struct zoran *zr, int frame)
+{
+	unsigned long flags;
+
+
+	/* check passed-in frame number */
+	if (frame >= v4l_nbufs || frame < 0) {
+		printk(KERN_ERR "%s: v4l_sync: frame %d is invalid\n", zr->name, frame);
+		return -EINVAL;
+	}
+	/* Check if is buffer was queued at all */
+
+	if (zr->v4l_gbuf[frame].state == BUZ_STATE_USER) {
+//		printk(KERN_ERR "%s: v4l_sync: Trying to sync on a buffer which was not queued?\n", zr->name);
+		return -EINVAL;
+	}
+	/* wait on this buffer to get ready */
+
+	while (zr->v4l_gbuf[frame].state == BUZ_STATE_PEND) {
+		interruptible_sleep_on(&zr->v4l_capq);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+	}
+
+	/* buffer should now be in BUZ_STATE_DONE */
+
+	if (zr->v4l_gbuf[frame].state != BUZ_STATE_DONE)
+		printk(KERN_ERR "%s: v4l_sync - internal error\n", zr->name);
+
+	/* Check if streaming capture has finished */
+
+	spin_lock_irqsave(&zr->lock, flags);
+
+	if (zr->v4l_pend_tail == zr->v4l_pend_head)
+		zr36057_set_memgrab(zr, 0);
+
+	spin_unlock_irqrestore(&zr->lock, flags);
+
+	return 0;
+}
+/*****************************************************************************
+ *                                                                           *
+ *  Set up the Buz-specific MJPEG part                                       *
+ *                                                                           *
+ *****************************************************************************/
+
+/*
+ *	Wait til post office is no longer busy 
+ */
+ 
+static int post_office_wait(struct zoran *zr)
+{
+	u32 por;
+	u32 ct=0;
+
+	while (((por = btread(ZR36057_POR)) & (ZR36057_POR_POPen | ZR36057_POR_POTime)) == ZR36057_POR_POPen) {
+		ct++;
+		if(ct>100000)
+		{
+			printk(KERN_ERR "%s: timeout on post office.\n", zr->name);
+			return -1;
+		}
+		/* wait for something to happen */
+	}
+	if ((por & ZR36057_POR_POPen) != 0) {
+		printk(KERN_WARNING "%s: pop pending %08x\n", zr->name, por);
+		return -1;
+	}
+	if ((por & (ZR36057_POR_POTime | ZR36057_POR_POPen)) != 0) {
+		printk(KERN_WARNING "%s: pop timeout %08x\n", zr->name, por);
+		return -1;
+	}
+	return 0;
+}
+
+static int post_office_write(struct zoran *zr, unsigned guest, unsigned reg, unsigned value)
+{
+	u32 por;
+
+	post_office_wait(zr);
+	por = ZR36057_POR_PODir | ZR36057_POR_POTime | ((guest & 7) << 20) | ((reg & 7) << 16) | (value & 0xFF);
+	btwrite(por, ZR36057_POR);
+	return post_office_wait(zr);
+}
+
+static int post_office_read(struct zoran *zr, unsigned guest, unsigned reg)
+{
+	u32 por;
+
+	post_office_wait(zr);
+	por = ZR36057_POR_POTime | ((guest & 7) << 20) | ((reg & 7) << 16);
+	btwrite(por, ZR36057_POR);
+	if (post_office_wait(zr) < 0) {
+		return -1;
+	}
+	return btread(ZR36057_POR) & 0xFF;
+}
+
+static int zr36060_write_8(struct zoran *zr, unsigned reg, unsigned val)
+{
+	if (post_office_wait(zr)
+	    || post_office_write(zr, 0, 1, reg >> 8)
+	    || post_office_write(zr, 0, 2, reg)) {
+		return -1;
+	}
+	return post_office_write(zr, 0, 3, val);
+}
+
+static int zr36060_write_16(struct zoran *zr, unsigned reg, unsigned val)
+{
+	if (zr36060_write_8(zr, reg + 0, val >> 8)) {
+		return -1;
+	}
+	return zr36060_write_8(zr, reg + 1, val >> 0);
+}
+
+static int zr36060_write_24(struct zoran *zr, unsigned reg, unsigned val)
+{
+	if (zr36060_write_8(zr, reg + 0, val >> 16)) {
+		return -1;
+	}
+	return zr36060_write_16(zr, reg + 1, val >> 0);
+}
+
+static int zr36060_write_32(struct zoran *zr, unsigned reg, unsigned val)
+{
+	if (zr36060_write_16(zr, reg + 0, val >> 16)) {
+		return -1;
+	}
+	return zr36060_write_16(zr, reg + 2, val >> 0);
+}
+
+static u32 zr36060_read_8(struct zoran *zr, unsigned reg)
+{
+	if (post_office_wait(zr)
+	    || post_office_write(zr, 0, 1, reg >> 8)
+	    || post_office_write(zr, 0, 2, reg)) {
+		return -1;
+	}
+	return post_office_read(zr, 0, 3) & 0xFF;
+}
+
+static int zr36060_reset(struct zoran *zr)
+{
+	return post_office_write(zr, 3, 0, 0);
+}
+
+static void zr36060_sleep(struct zoran *zr, int sleep)
+{
+	GPIO(zr, 1, !sleep);
+}
+
+
+static void zr36060_set_jpg(struct zoran *zr, enum zoran_codec_mode mode)
+{
+	struct tvnorm *tvn;
+	u32 reg;
+	int size;
+
+	reg = (1 << 0)		/* CodeMstr */
+	    |(0 << 2)		/* CFIS=0 */
+	    |(0 << 6)		/* Endian=0 */
+	    |(0 << 7);		/* Code16=0 */
+	zr36060_write_8(zr, 0x002, reg);
+
+	switch (mode) {
+
+	case BUZ_MODE_MOTION_DECOMPRESS:
+	case BUZ_MODE_STILL_DECOMPRESS:
+		reg = 0x00;	/* Codec mode = decompression */
+		break;
+
+	case BUZ_MODE_MOTION_COMPRESS:
+	case BUZ_MODE_STILL_COMPRESS:
+	default:
+		reg = 0xa4;	/* Codec mode = compression with variable scale factor */
+		break;
+
+	}
+	zr36060_write_8(zr, 0x003, reg);
+
+	reg = 0x00;		/* reserved, mbz */
+	zr36060_write_8(zr, 0x004, reg);
+
+	reg = 0xff;		/* 510 bits/block */
+	zr36060_write_8(zr, 0x005, reg);
+
+	/* JPEG markers */
+	reg = (zr->params.jpeg_markers) & 0x38;	/* DRI, DQT, DHT */
+	if (zr->params.COM_len)
+		reg |= JPEG_MARKER_COM;
+	if (zr->params.APP_len)
+		reg |= JPEG_MARKER_APP;
+	zr36060_write_8(zr, 0x006, reg);
+
+	reg = (0 << 3)		/* DATERR=0 */
+	    |(0 << 2)		/* END=0 */
+	    |(0 << 1)		/* EOI=0 */
+	    |(0 << 0);		/* EOAV=0 */
+	zr36060_write_8(zr, 0x007, reg);
+
+	/* code volume */
+
+	/* Target field size in pixels: */
+	tvn = &tvnorms[zr->params.norm];
+	size = (tvn->Ha / 2) * (tvn->Wa) / (zr->params.HorDcm) / (zr->params.VerDcm);
+
+	/* Target compressed field size in bits: */
+	size = size * 16;	/* uncompressed size in bits */
+	size = size * zr->params.quality / 400;	/* quality = 100 is a compression ratio 1:4 */
+
+	/* Lower limit (arbitrary, 1 KB) */
+	if (size < 8192)
+		size = 8192;
+
+	/* Upper limit: 7/8 of the code buffers */
+	if (size * zr->params.field_per_buff > zr->jpg_bufsize * 7)
+		size = zr->jpg_bufsize * 7 / zr->params.field_per_buff;
+
+	reg = size;
+	zr36060_write_32(zr, 0x009, reg);
+
+	/* how do we set initial SF as a function of quality parameter? */
+	reg = 0x0100;		/* SF=1.0 */
+	zr36060_write_16(zr, 0x011, reg);
+
+	reg = 0x00ffffff;	/* AF=max */
+	zr36060_write_24(zr, 0x013, reg);
+
+	reg = 0x0000;		/* test */
+	zr36060_write_16(zr, 0x024, reg);
+}
+
+static void zr36060_set_video(struct zoran *zr, enum zoran_codec_mode mode)
+{
+	struct tvnorm *tvn;
+	u32 reg;
+
+	reg = (0 << 7)		/* Video8=0 */
+	    |(0 << 6)		/* Range=0 */
+	    |(0 << 3)		/* FlDet=0 */
+	    |(1 << 2)		/* FlVedge=1 */
+	    |(0 << 1)		/* FlExt=0 */
+	    |(0 << 0);		/* SyncMstr=0 */
+
+	/* According to ZR36067 documentation, FlDet should correspond
+	   to the odd_even flag of the ZR36067 */
+	if (zr->params.odd_even)
+		reg |= (1 << 3);
+
+	if (mode != BUZ_MODE_STILL_DECOMPRESS) {
+		/* limit pixels to range 16..235 as per CCIR-601 */
+		reg |= (1 << 6);	/* Range=1 */
+	}
+	zr36060_write_8(zr, 0x030, reg);
+
+	reg = (0 << 7)		/* VCLKPol=0 */
+	    |(0 << 6)		/* PValPol=0 */
+	    |(1 << 5)		/* PoePol=1 */
+	    |(0 << 4)		/* SImgPol=0 */
+	    |(0 << 3)		/* BLPol=0 */
+	    |(0 << 2)		/* FlPol=0 */
+	    |(0 << 1)		/* HSPol=0, sync on falling edge */
+	    |(1 << 0);		/* VSPol=1 */
+	zr36060_write_8(zr, 0x031, reg);
+
+	switch (zr->params.HorDcm) {
+	default:
+	case 1:
+		reg = (0 << 0);
+		break;		/* HScale = 0 */
+
+	case 2:
+		reg = (1 << 0);
+		break;		/* HScale = 1 */
+
+	case 4:
+		reg = (2 << 0);
+		break;		/* HScale = 2 */
+	}
+	if (zr->params.VerDcm == 2)
+		reg |= (1 << 2);
+	zr36060_write_8(zr, 0x032, reg);
+
+	reg = 0x80;		/* BackY */
+	zr36060_write_8(zr, 0x033, reg);
+
+	reg = 0xe0;		/* BackU */
+	zr36060_write_8(zr, 0x034, reg);
+
+	reg = 0xe0;		/* BackV */
+	zr36060_write_8(zr, 0x035, reg);
+
+	/* sync generator */
+
+	tvn = &tvnorms[zr->params.norm];
+
+	reg = tvn->Ht - 1;	/* Vtotal */
+	zr36060_write_16(zr, 0x036, reg);
+
+	reg = tvn->Wt - 1;	/* Htotal */
+	zr36060_write_16(zr, 0x038, reg);
+
+	reg = 6 - 1;		/* VsyncSize */
+	zr36060_write_8(zr, 0x03a, reg);
+
+	reg = 100 - 1;		/* HsyncSize */
+	zr36060_write_8(zr, 0x03b, reg);
+
+	reg = tvn->VStart - 1;	/* BVstart */
+	zr36060_write_8(zr, 0x03c, reg);
+
+	reg += tvn->Ha / 2;	/* BVend */
+	zr36060_write_16(zr, 0x03e, reg);
+
+	reg = tvn->HStart - 1;	/* BHstart */
+	zr36060_write_8(zr, 0x03d, reg);
+
+	reg += tvn->Wa;		/* BHend */
+	zr36060_write_16(zr, 0x040, reg);
+
+	/* active area */
+	reg = zr->params.img_y + tvn->VStart;	/* Vstart */
+	zr36060_write_16(zr, 0x042, reg);
+
+	reg += zr->params.img_height;	/* Vend */
+	zr36060_write_16(zr, 0x044, reg);
+
+	reg = zr->params.img_x + tvn->HStart;	/* Hstart */
+	zr36060_write_16(zr, 0x046, reg);
+
+	reg += zr->params.img_width;	/* Hend */
+	zr36060_write_16(zr, 0x048, reg);
+
+	/* subimage area */
+	reg = zr->params.img_y + tvn->VStart;	/* SVstart */
+	zr36060_write_16(zr, 0x04a, reg);
+
+	reg += zr->params.img_height;	/* SVend */
+	zr36060_write_16(zr, 0x04c, reg);
+
+	reg = zr->params.img_x + tvn->HStart;	/* SHstart */
+	zr36060_write_16(zr, 0x04e, reg);
+
+	reg += zr->params.img_width;	/* SHend */
+	zr36060_write_16(zr, 0x050, reg);
+}
+
+static void zr36060_set_jpg_SOF(struct zoran *zr)
+{
+	u32 reg;
+
+
+	reg = 0xffc0;		/* SOF marker */
+	zr36060_write_16(zr, 0x060, reg);
+
+	reg = 17;		/* SOF length */
+	zr36060_write_16(zr, 0x062, reg);
+
+	reg = 8;		/* precision 8 bits */
+	zr36060_write_8(zr, 0x064, reg);
+
+	reg = zr->params.img_height / zr->params.VerDcm;	/* image height */
+	zr36060_write_16(zr, 0x065, reg);
+
+	reg = zr->params.img_width / zr->params.HorDcm;	/* image width */
+	zr36060_write_16(zr, 0x067, reg);
+
+	reg = 3;		/* 3 color components */
+	zr36060_write_8(zr, 0x069, reg);
+
+	reg = 0x002100;		/* Y component */
+	zr36060_write_24(zr, 0x06a, reg);
+
+	reg = 0x011101;		/* U component */
+	zr36060_write_24(zr, 0x06d, reg);
+
+	reg = 0x021101;		/* V component */
+	zr36060_write_24(zr, 0x070, reg);
+}
+
+static void zr36060_set_jpg_SOS(struct zoran *zr)
+{
+	u32 reg;
+
+
+	reg = 0xffda;		/* SOS marker */
+	zr36060_write_16(zr, 0x07a, reg);
+
+	reg = 12;		/* SOS length */
+	zr36060_write_16(zr, 0x07c, reg);
+
+	reg = 3;		/* 3 color components */
+	zr36060_write_8(zr, 0x07e, reg);
+
+	reg = 0x0000;		/* Y component */
+	zr36060_write_16(zr, 0x07f, reg);
+
+	reg = 0x0111;		/* U component */
+	zr36060_write_16(zr, 0x081, reg);
+
+	reg = 0x0211;		/* V component */
+	zr36060_write_16(zr, 0x083, reg);
+
+	reg = 0x003f00;		/* Start, end spectral scans */
+	zr36060_write_24(zr, 0x085, reg);
+}
+
+static void zr36060_set_jpg_DRI(struct zoran *zr)
+{
+	u32 reg;
+
+
+	reg = 0xffdd;		/* DRI marker */
+	zr36060_write_16(zr, 0x0c0, reg);
+
+	reg = 4;		/* DRI length */
+	zr36060_write_16(zr, 0x0c2, reg);
+
+	reg = 8;		/* length in MCUs */
+	zr36060_write_16(zr, 0x0c4, reg);
+}
+
+static void zr36060_set_jpg_DQT(struct zoran *zr)
+{
+	unsigned i;
+	unsigned adr;
+	static const u8 dqt[] =
+	{
+		0xff, 0xdb,	/* DHT marker */
+		0x00, 0x84,	/* DHT length */
+		0x00,		/* table ID 0 */
+		0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
+		0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
+		0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
+		0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
+		0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
+		0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
+		0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
+		0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
+		0x01,		/* table ID 1 */
+		0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
+		0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
+		0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+		0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+		0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+		0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+		0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+		0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
+	};
+
+	/* write fixed quantitization tables */
+	adr = 0x0cc;
+	for (i = 0; i < sizeof(dqt); ++i) {
+		zr36060_write_8(zr, adr++, dqt[i]);
+	}
+}
+
+static void zr36060_set_jpg_DHT(struct zoran *zr)
+{
+	unsigned i;
+	unsigned adr;
+	static const u8 dht[] =
+	{
+		0xff, 0xc4,	/* DHT marker */
+		0x01, 0xa2,	/* DHT length */
+		0x00,		/* table class 0, ID 0 */
+		0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,		/* # codes of length 1..8 */
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		/* # codes of length 8..16 */
+		0x00,		/* values for codes of length 2 */
+		0x01, 0x02, 0x03, 0x04, 0x05,	/* values for codes of length 3 */
+		0x06,		/* values for codes of length 4 */
+		0x07,		/* values for codes of length 5 */
+		0x08,		/* values for codes of length 6 */
+		0x09,		/* values for codes of length 7 */
+		0x0a,		/* values for codes of length 8 */
+		0x0b,		/* values for codes of length 9 */
+		0x01,		/* table class 0, ID 1 */
+		0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,		/* # codes of length 1..8 */
+		0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,		/* # codes of length 9..16 */
+		0x00, 0x01, 0x02,	/* values for codes of length 2 */
+		0x03,		/* values for codes of length 3 */
+		0x04,		/* values for codes of length 4 */
+		0x05,		/* values for codes of length 5 */
+		0x06,		/* values for codes of length 6 */
+		0x07,		/* values for codes of length 7 */
+		0x08,		/* values for codes of length 8 */
+		0x09,		/* values for codes of length 9 */
+		0x0a,		/* values for codes of length 10 */
+		0x0b,		/* values for codes of length 11 */
+		0x10,
+		0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
+		0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
+		0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+		0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+		0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+		0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+		0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+		0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+		0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+		0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+		0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+		0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+		0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+		0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+		0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+		0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+		0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+		0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+		0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+		0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+		0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+		0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+		0xf9, 0xfa, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04,
+		0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00,
+		0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11,
+		0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51,
+		0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08,
+		0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23,
+		0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a,
+		0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18,
+		0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35,
+		0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
+		0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55,
+		0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65,
+		0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75,
+		0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84,
+		0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93,
+		0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2,
+		0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
+		0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
+		0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
+		0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+		0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+		0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5,
+		0xf6, 0xf7, 0xf8, 0xf9, 0xfa
+	};
+
+	/* write fixed Huffman tables */
+	adr = 0x1d4;
+	for (i = 0; i < sizeof(dht); ++i) {
+		zr36060_write_8(zr, adr++, dht[i]);
+	}
+}
+
+static void zr36060_set_jpg_APP(struct zoran *zr)
+{
+	unsigned adr;
+	int len, i;
+	u32 reg;
+
+
+	len = zr->params.APP_len;
+	if (len < 0)
+		len = 0;
+	if (len > 60)
+		len = 60;
+
+	i = zr->params.APPn;
+	if (i < 0)
+		i = 0;
+	if (i > 15)
+		i = 15;
+
+	reg = 0xffe0 + i;	/* APPn marker */
+	zr36060_write_16(zr, 0x380, reg);
+
+	reg = len + 2;		/* APPn len */
+	zr36060_write_16(zr, 0x382, reg);
+
+	/* write APPn data */
+	adr = 0x384;
+	for (i = 0; i < 60; i++) {
+		zr36060_write_8(zr, adr++, (i < len ? zr->params.APP_data[i] : 0));
+	}
+}
+
+static void zr36060_set_jpg_COM(struct zoran *zr)
+{
+	unsigned adr;
+	int len, i;
+	u32 reg;
+
+
+	len = zr->params.COM_len;
+	if (len < 0)
+		len = 0;
+	if (len > 60)
+		len = 60;
+
+	reg = 0xfffe;		/* COM marker */
+	zr36060_write_16(zr, 0x3c0, reg);
+
+	reg = len + 2;		/* COM len */
+	zr36060_write_16(zr, 0x3c2, reg);
+
+	/* write COM data */
+	adr = 0x3c4;
+	for (i = 0; i < 60; i++) {
+		zr36060_write_8(zr, adr++, (i < len ? zr->params.COM_data[i] : 0));
+	}
+}
+
+static void zr36060_set_cap(struct zoran *zr, enum zoran_codec_mode mode)
+{
+	unsigned i;
+	u32 reg;
+
+	zr36060_reset(zr);
+	mdelay(10);
+
+	reg = (0 << 7)		/* Load=0 */
+	    |(1 << 0);		/* SynRst=1 */
+	zr36060_write_8(zr, 0x000, reg);
+
+	zr36060_set_jpg(zr, mode);
+	zr36060_set_video(zr, mode);
+	zr36060_set_jpg_SOF(zr);
+	zr36060_set_jpg_SOS(zr);
+	zr36060_set_jpg_DRI(zr);
+	zr36060_set_jpg_DQT(zr);
+	zr36060_set_jpg_DHT(zr);
+	zr36060_set_jpg_APP(zr);
+	zr36060_set_jpg_COM(zr);
+
+	reg = (1 << 7)		/* Load=1 */
+	    |(0 << 0);		/* SynRst=0 */
+	zr36060_write_8(zr, 0x000, reg);
+
+	/* wait for codec to unbusy */
+	for (i = 0; i < 1000; ++i) {
+		reg = zr36060_read_8(zr, 0x001);
+		if ((reg & (1 << 7)) == 0) {
+			DEBUG(printk(KERN_DEBUG "060: loaded, loops=%u\n", i));
+			return;
+		}
+		udelay(1000);
+	}
+	printk(KERN_INFO "060: stuck busy, statux=%02x\n", reg);
+}
+
+static void zr36057_set_jpg(struct zoran *zr, enum zoran_codec_mode mode)
+{
+	struct tvnorm *tvn;
+	u32 reg;
+	int i;
+
+	tvn = &tvnorms[zr->params.norm];
+
+	/* assert P_Reset */
+	btwrite(0, ZR36057_JPC);
+
+	/* re-initialize DMA ring stuff */
+	zr->jpg_que_head = 0;
+	zr->jpg_dma_head = 0;
+	zr->jpg_dma_tail = 0;
+	zr->jpg_que_tail = 0;
+	zr->jpg_seq_num = 0;
+	for (i = 0; i < BUZ_NUM_STAT_COM; ++i) {
+		zr->stat_com[i] = 1;	/* mark as unavailable to zr36057 */
+	}
+	for (i = 0; i < zr->jpg_nbufs; i++) {
+		zr->jpg_gbuf[i].state = BUZ_STATE_USER;	/* nothing going on */
+	}
+
+	/* MJPEG compression mode */
+	switch (mode) {
+
+	case BUZ_MODE_MOTION_COMPRESS:
+	default:
+		reg = ZR36057_JMC_MJPGCmpMode;
+		break;
+
+	case BUZ_MODE_MOTION_DECOMPRESS:
+		reg = ZR36057_JMC_MJPGExpMode;
+		reg |= ZR36057_JMC_SyncMstr;
+		/* RJ: The following is experimental - improves the output to screen */
+		if (zr->params.VFIFO_FB)
+			reg |= ZR36057_JMC_VFIFO_FB;
+		break;
+
+	case BUZ_MODE_STILL_COMPRESS:
+		reg = ZR36057_JMC_JPGCmpMode;
+		break;
+
+	case BUZ_MODE_STILL_DECOMPRESS:
+		reg = ZR36057_JMC_JPGExpMode;
+		break;
+
+	}
+	reg |= ZR36057_JMC_JPG;
+	if (zr->params.field_per_buff == 1)
+		reg |= ZR36057_JMC_Fld_per_buff;
+	btwrite(reg, ZR36057_JMC);
+
+	/* vertical */
+	btor(ZR36057_VFEVCR_VSPol, ZR36057_VFEVCR);
+	reg = (6 << ZR36057_VSP_VsyncSize) | (tvn->Ht << ZR36057_VSP_FrmTot);
+	btwrite(reg, ZR36057_VSP);
+	reg = ((zr->params.img_y + tvn->VStart) << ZR36057_FVAP_NAY)
+	    | (zr->params.img_height << ZR36057_FVAP_PAY);
+	btwrite(reg, ZR36057_FVAP);
+
+	/* horizontal */
+	btor(ZR36057_VFEHCR_HSPol, ZR36057_VFEHCR);
+	reg = ((tvn->Wt - 100) << ZR36057_HSP_HsyncStart) | (tvn->Wt << ZR36057_HSP_LineTot);
+	btwrite(reg, ZR36057_HSP);
+	reg = ((zr->params.img_x + tvn->HStart) << ZR36057_FHAP_NAX)
+	    | (zr->params.img_width << ZR36057_FHAP_PAX);
+	btwrite(reg, ZR36057_FHAP);
+
+	/* field process parameters */
+	if (zr->params.odd_even)
+		reg = ZR36057_FPP_Odd_Even;
+	else
+		reg = 0;
+	btwrite(reg, ZR36057_FPP);
+
+	/* Set proper VCLK Polarity, else colors will be wrong during playback */
+	btor(ZR36057_VFESPFR_VCLKPol, ZR36057_VFESPFR);
+
+	/* code base address and FIFO threshold */
+	reg = virt_to_bus(zr->stat_com);
+	btwrite(reg, ZR36057_JCBA);
+	reg = 0x50;
+	btwrite(reg, ZR36057_JCFT);
+
+	/* JPEG codec guest ID */
+	reg = (1 << ZR36057_JCGI_JPEGuestID) | (0 << ZR36057_JCGI_JPEGuestReg);
+	btwrite(reg, ZR36057_JCGI);
+
+	/* Code transfer guest ID */
+	reg = (0 << ZR36057_MCTCR_CodGuestID) | (3 << ZR36057_MCTCR_CodGuestReg);
+	reg |= ZR36057_MCTCR_CFlush;
+	btwrite(reg, ZR36057_MCTCR);
+
+	/* deassert P_Reset */
+	btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC);
+}
+
+static void zr36057_enable_jpg(struct zoran *zr, enum zoran_codec_mode mode)
+{
+	static int zero = 0;
+	static int one = 1;
+
+	switch (mode) {
+
+	case BUZ_MODE_MOTION_COMPRESS:
+		zr36060_set_cap(zr, mode);
+		zr36057_set_jpg(zr, mode);
+		i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_ENABLE_OUTPUT, &one);
+		i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_INPUT, &zero);
+
+		/* deassert P_Reset, assert Code transfer enable */
+		btwrite(IRQ_MASK, ZR36057_ISR);
+		btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
+		break;
+
+	case BUZ_MODE_MOTION_DECOMPRESS:
+		i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_ENABLE_OUTPUT, &zero);
+		i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_INPUT, &one);
+		zr36060_set_cap(zr, mode);
+		zr36057_set_jpg(zr, mode);
+
+		/* deassert P_Reset, assert Code transfer enable */
+		btwrite(IRQ_MASK, ZR36057_ISR);
+		btand(~ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
+		break;
+
+	case BUZ_MODE_IDLE:
+	default:
+		/* shut down processing */
+		btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
+		btwrite(ZR36057_JPC_P_Reset, ZR36057_JPC);
+		btand(~ZR36057_JMC_VFIFO_FB, ZR36057_JMC);
+		btand(~ZR36057_JMC_SyncMstr, ZR36057_JMC);
+		btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
+		btwrite(0, ZR36057_ISR);
+		zr36060_reset(zr);
+		i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_ENABLE_OUTPUT, &one);
+		i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_INPUT, &zero);
+		break;
+
+	}
+	zr->codec_mode = mode;
+}
+
+/*
+ *   Queue a MJPEG buffer for capture/playback
+ */
+
+static int jpg_qbuf(struct zoran *zr, int frame, enum zoran_codec_mode mode)
+{
+	unsigned long flags;
+	int res;
+
+	/* Check if buffers are allocated */
+
+	if (!zr->jpg_buffers_allocated) {
+		printk(KERN_ERR "%s: jpg_qbuf: buffers not yet allocated\n", zr->name);
+		return -ENOMEM;
+	}
+	/* Does the user want to stop streaming? */
+
+	if (frame < 0) {
+		if (zr->codec_mode == mode) {
+			zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
+			return 0;
+		} else {
+			printk(KERN_ERR "%s: jpg_qbuf - stop streaming but not in streaming mode\n", zr->name);
+			return -EINVAL;
+		}
+	}
+	/* No grabbing outside the buffer range! */
+
+	if (frame >= zr->jpg_nbufs) {
+		printk(KERN_ERR "%s: jpg_qbuf: buffer %d out of range\n", zr->name, frame);
+		return -EINVAL;
+	}
+	/* what is the codec mode right now? */
+
+	if (zr->codec_mode == BUZ_MODE_IDLE) {
+		/* Ok load up the zr36060 and go */
+		zr36057_enable_jpg(zr, mode);
+	} else if (zr->codec_mode != mode) {
+		/* wrong codec mode active - invalid */
+		printk(KERN_ERR "%s: jpg_qbuf - codec in wrong mode\n", zr->name);
+		return -EINVAL;
+	}
+	spin_lock_irqsave(&zr->lock, flags);
+
+	/* make sure a grab isn't going on currently with this buffer */
+
+	switch (zr->jpg_gbuf[frame].state) {
+
+	default:
+	case BUZ_STATE_DMA:
+	case BUZ_STATE_PEND:
+	case BUZ_STATE_DONE:
+		res = -EBUSY;	/* what are you doing? */
+		break;
+
+	case BUZ_STATE_USER:
+		/* since there is at least one unused buffer there's room for at least one more pend[] entry */
+		zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = frame;
+		zr->jpg_gbuf[frame].state = BUZ_STATE_PEND;
+		zoran_feed_stat_com(zr);
+		res = 0;
+		break;
+
+	}
+
+	spin_unlock_irqrestore(&zr->lock, flags);
+
+	/* Start the zr36060 when the first frame is queued  */
+	if (zr->jpg_que_head == 1) {
+		btor(ZR36057_JMC_Go_en, ZR36057_JMC);
+		btwrite(ZR36057_JPC_P_Reset | ZR36057_JPC_CodTrnsEn | ZR36057_JPC_Active, ZR36057_JPC);
+	}
+	return res;
+}
+
+/*
+ *   Sync on a MJPEG buffer
+ */
+
+static int jpg_sync(struct zoran *zr, struct zoran_sync *bs)
+{
+	unsigned long flags;
+	int frame;
+
+	if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS &&
+	    zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) {
+		return -EINVAL;
+	}
+	while (zr->jpg_que_tail == zr->jpg_dma_tail) {
+		interruptible_sleep_on(&zr->jpg_capq);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+	}
+
+	spin_lock_irqsave(&zr->lock, flags);
+
+	frame = zr->jpg_pend[zr->jpg_que_tail++ & BUZ_MASK_FRAME];
+
+	/* buffer should now be in BUZ_STATE_DONE */
+
+	if (zr->jpg_gbuf[frame].state != BUZ_STATE_DONE)
+		printk(KERN_ERR "%s: jpg_sync - internal error\n", zr->name);
+
+	*bs = zr->jpg_gbuf[frame].bs;
+	zr->jpg_gbuf[frame].state = BUZ_STATE_USER;
+
+	spin_unlock_irqrestore(&zr->lock, flags);
+
+	return 0;
+}
+
+/* when this is called the spinlock must be held */
+static void zoran_feed_stat_com(struct zoran *zr)
+{
+	/* move frames from pending queue to DMA */
+
+	int frame, i, max_stat_com;
+
+	max_stat_com = (zr->params.TmpDcm == 1) ? BUZ_NUM_STAT_COM : (BUZ_NUM_STAT_COM >> 1);
+
+	while ((zr->jpg_dma_head - zr->jpg_dma_tail) < max_stat_com
+	       && zr->jpg_dma_head != zr->jpg_que_head) {
+
+		frame = zr->jpg_pend[zr->jpg_dma_head & BUZ_MASK_FRAME];
+		if (zr->params.TmpDcm == 1) {
+			/* fill 1 stat_com entry */
+			i = zr->jpg_dma_head & BUZ_MASK_STAT_COM;
+			zr->stat_com[i] = zr->jpg_gbuf[frame].frag_tab_bus;
+		} else {
+			/* fill 2 stat_com entries */
+			i = (zr->jpg_dma_head & 1) * 2;
+			zr->stat_com[i] = zr->jpg_gbuf[frame].frag_tab_bus;
+			zr->stat_com[i + 1] = zr->jpg_gbuf[frame].frag_tab_bus;
+		}
+		zr->jpg_gbuf[frame].state = BUZ_STATE_DMA;
+		zr->jpg_dma_head++;
+
+	}
+}
+
+/* when this is called the spinlock must be held */
+static void zoran_reap_stat_com(struct zoran *zr)
+{
+	/* move frames from DMA queue to done queue */
+
+	int i;
+	u32 stat_com;
+	unsigned int seq;
+	unsigned int dif;
+	int frame;
+	struct zoran_gbuffer *gbuf;
+
+	/* In motion decompress we don't have a hardware frame counter,
+	   we just count the interrupts here */
+
+	if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS)
+		zr->jpg_seq_num++;
+
+	while (zr->jpg_dma_tail != zr->jpg_dma_head) {
+		if (zr->params.TmpDcm == 1)
+			i = zr->jpg_dma_tail & BUZ_MASK_STAT_COM;
+		else
+			i = (zr->jpg_dma_tail & 1) * 2 + 1;
+
+		stat_com = zr->stat_com[i];
+
+		if ((stat_com & 1) == 0) {
+			return;
+		}
+		frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
+		gbuf = &zr->jpg_gbuf[frame];
+		get_fast_time(&gbuf->bs.timestamp);
+
+		if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
+			gbuf->bs.length = (stat_com & 0x7fffff) >> 1;
+
+			/* update sequence number with the help of the counter in stat_com */
+
+			seq = stat_com >> 24;
+			dif = (seq - zr->jpg_seq_num) & 0xff;
+			zr->jpg_seq_num += dif;
+		} else {
+			gbuf->bs.length = 0;
+		}
+		gbuf->bs.seq = zr->params.TmpDcm == 2 ? (zr->jpg_seq_num >> 1) : zr->jpg_seq_num;
+		gbuf->state = BUZ_STATE_DONE;
+
+		zr->jpg_dma_tail++;
+	}
+}
+
+static void zoran_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32 stat, astat;
+	int count;
+	struct zoran *zr;
+	unsigned long flags;
+
+	zr = (struct zoran *) dev_id;
+	count = 0;
+
+	spin_lock_irqsave(&zr->lock, flags);
+	while (1) {
+		/* get/clear interrupt status bits */
+		stat = btread(ZR36057_ISR);
+		astat = stat & IRQ_MASK;
+		if (!astat) {
+			break;
+		}
+		btwrite(astat, ZR36057_ISR);
+		IDEBUG(printk(BUZ_DEBUG "-%u: astat %08x stat %08x\n", zr->id, astat, stat));
+
+#if (IRQ_MASK & ZR36057_ISR_GIRQ0)
+		if (astat & ZR36057_ISR_GIRQ0) {
+
+			/* Interrupts may still happen when zr->v4l_memgrab_active is switched off.
+			   We simply ignore them */
+
+			if (zr->v4l_memgrab_active) {
+
+/* A lot more checks should be here ... */
+				if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) == 0)
+					printk(KERN_WARNING "%s: BuzIRQ with SnapShot off ???\n", zr->name);
+
+				if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) {
+					/* There is a grab on a frame going on, check if it has finished */
+
+					if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FrameGrab) == 0) {
+						/* it is finished, notify the user */
+
+						zr->v4l_gbuf[zr->v4l_grab_frame].state = BUZ_STATE_DONE;
+						zr->v4l_grab_frame = NO_GRAB_ACTIVE;
+						zr->v4l_grab_seq++;
+						zr->v4l_pend_tail++;
+					}
+				}
+				if (zr->v4l_grab_frame == NO_GRAB_ACTIVE)
+					wake_up_interruptible(&zr->v4l_capq);
+
+				/* Check if there is another grab queued */
+
+				if (zr->v4l_grab_frame == NO_GRAB_ACTIVE &&
+				    zr->v4l_pend_tail != zr->v4l_pend_head) {
+
+					int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME];
+					u32 reg;
+
+					zr->v4l_grab_frame = frame;
+
+					/* Set zr36057 video front end and enable video */
+
+					/* Buffer address */
+
+					reg = zr->v4l_gbuf[frame].fbuffer_bus;
+					btwrite(reg, ZR36057_VDTR);
+					if (zr->video_interlace)
+						reg += zr->gbpl;
+					btwrite(reg, ZR36057_VDBR);
+
+					/* video stride, status, and frame grab register */
+
+#ifdef XAWTV_HACK
+					reg = (zr->gwidth > 720) ? ((zr->gwidth & ~3) - 720) * zr->gbpl / zr->gwidth : 0;
+#else
+					reg = 0;
+#endif
+					if (zr->video_interlace)
+						reg += zr->gbpl;
+					reg = (reg << ZR36057_VSSFGR_DispStride);
+					reg |= ZR36057_VSSFGR_VidOvf;
+					reg |= ZR36057_VSSFGR_SnapShot;
+					reg |= ZR36057_VSSFGR_FrameGrab;
+					btwrite(reg, ZR36057_VSSFGR);
+
+					btor(ZR36057_VDCR_VidEn, ZR36057_VDCR);
+				}
+			}
+		}
+#endif				/* (IRQ_MASK & ZR36057_ISR_GIRQ0) */
+
+#if (IRQ_MASK & ZR36057_ISR_GIRQ1)
+		if (astat & ZR36057_ISR_GIRQ1) {
+			unsigned csr = zr36060_read_8(zr, 0x001);
+			unsigned isr = zr36060_read_8(zr, 0x008);
+
+			IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_GIRQ1 60_code=%02x 60_intr=%02x\n",
+				      zr->name, csr, isr));
+
+			btand(~ZR36057_ICR_GIRQ1, ZR36057_ICR);
+			zoran_reap_stat_com(zr);
+			zoran_feed_stat_com(zr);
+		}
+#endif				/* (IRQ_MASK & ZR36057_ISR_GIRQ1) */
+
+#if (IRQ_MASK & ZR36057_ISR_CodRepIRQ)
+		if (astat & ZR36057_ISR_CodRepIRQ) {
+			IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n", zr->name));
+			btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR);
+		}
+#endif				/* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */
+
+#if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ)
+		if ((astat & ZR36057_ISR_JPEGRepIRQ) &&
+		    (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
+		     zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) {
+			zoran_reap_stat_com(zr);
+			zoran_feed_stat_com(zr);
+			wake_up_interruptible(&zr->jpg_capq);
+		}
+#endif				/* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */
+
+		count++;
+		if (count > 10) {
+			printk(KERN_WARNING "%s: irq loop %d\n", zr->name, count);
+			if (count > 20) {
+				btwrite(0, ZR36057_ICR);
+				printk(KERN_ERR  "%s: IRQ lockup, cleared int mask\n", zr->name);
+				break;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&zr->lock, flags);
+}
+
+/* Check a zoran_params struct for correctness, insert default params */
+
+static int zoran_check_params(struct zoran *zr, struct zoran_params *params)
+{
+	int err = 0, err0 = 0;
+
+	/* insert constant params */
+
+	params->major_version = MAJOR_VERSION;
+	params->minor_version = MINOR_VERSION;
+
+	/* Check input and norm */
+
+	if (params->input != 0 && params->input != 1) {
+		err++;
+	}
+	if (params->norm != VIDEO_MODE_PAL && params->norm != VIDEO_MODE_NTSC) {
+		err++;
+	}
+	/* Check decimation, set default values for decimation = 1, 2, 4 */
+
+	switch (params->decimation) {
+	case 1:
+
+		params->HorDcm = 1;
+		params->VerDcm = 1;
+		params->TmpDcm = 1;
+		params->field_per_buff = 2;
+
+		params->img_x = 0;
+		params->img_y = 0;
+		params->img_width = 720;
+		params->img_height = tvnorms[params->norm].Ha / 2;
+		break;
+
+	case 2:
+
+		params->HorDcm = 2;
+		params->VerDcm = 1;
+		params->TmpDcm = 2;
+		params->field_per_buff = 1;
+
+		params->img_x = 8;
+		params->img_y = 0;
+		params->img_width = 704;
+		params->img_height = tvnorms[params->norm].Ha / 2;
+		break;
+
+	case 4:
+
+		params->HorDcm = 4;
+		params->VerDcm = 2;
+		params->TmpDcm = 2;
+		params->field_per_buff = 1;
+
+		params->img_x = 8;
+		params->img_y = 0;
+		params->img_width = 704;
+		params->img_height = tvnorms[params->norm].Ha / 2;
+		break;
+
+	case 0:
+
+		/* We have to check the data the user has set */
+
+		if (params->HorDcm != 1 && params->HorDcm != 2 && params->HorDcm != 4)
+			err0++;
+		if (params->VerDcm != 1 && params->VerDcm != 2)
+			err0++;
+		if (params->TmpDcm != 1 && params->TmpDcm != 2)
+			err0++;
+		if (params->field_per_buff != 1 && params->field_per_buff != 2)
+			err0++;
+
+		if (params->img_x < 0)
+			err0++;
+		if (params->img_y < 0)
+			err0++;
+		if (params->img_width < 0)
+			err0++;
+		if (params->img_height < 0)
+			err0++;
+		if (params->img_x + params->img_width > 720)
+			err0++;
+		if (params->img_y + params->img_height > tvnorms[params->norm].Ha / 2)
+			err0++;
+		if (params->img_width % (16 * params->HorDcm) != 0)
+			err0++;
+		if (params->img_height % (8 * params->VerDcm) != 0)
+			err0++;
+
+		if (err0) {
+			err++;
+		}
+		break;
+
+	default:
+		err++;
+		break;
+	}
+
+	if (params->quality > 100)
+		params->quality = 100;
+	if (params->quality < 5)
+		params->quality = 5;
+
+	if (params->APPn < 0)
+		params->APPn = 0;
+	if (params->APPn > 15)
+		params->APPn = 15;
+	if (params->APP_len < 0)
+		params->APP_len = 0;
+	if (params->APP_len > 60)
+		params->APP_len = 60;
+	if (params->COM_len < 0)
+		params->COM_len = 0;
+	if (params->COM_len > 60)
+		params->COM_len = 60;
+
+	if (err)
+		return -EINVAL;
+
+	return 0;
+
+}
+static void zoran_open_init_params(struct zoran *zr)
+{
+	int i;
+
+	/* Per default, map the V4L Buffers */
+
+	zr->map_mjpeg_buffers = 0;
+
+	/* User must explicitly set a window */
+
+	zr->window_set = 0;
+
+	zr->window.x = 0;
+	zr->window.y = 0;
+	zr->window.width = 0;
+	zr->window.height = 0;
+	zr->window.chromakey = 0;
+	zr->window.flags = 0;
+	zr->window.clips = NULL;
+	zr->window.clipcount = 0;
+
+	zr->video_interlace = 0;
+
+	zr->v4l_memgrab_active = 0;
+	zr->v4l_overlay_active = 0;
+
+	zr->v4l_grab_frame = NO_GRAB_ACTIVE;
+	zr->v4l_grab_seq = 0;
+
+	zr->gwidth = 0;
+	zr->gheight = 0;
+	zr->gformat = 0;
+	zr->gbpl = 0;
+
+	/* DMA ring stuff for V4L */
+
+	zr->v4l_pend_tail = 0;
+	zr->v4l_pend_head = 0;
+	for (i = 0; i < v4l_nbufs; i++) {
+		zr->v4l_gbuf[i].state = BUZ_STATE_USER;	/* nothing going on */
+	}
+
+	/* Set necessary params and call zoran_check_params to set the defaults */
+
+	zr->params.decimation = 1;
+
+	zr->params.quality = 50;	/* default compression factor 8 */
+	zr->params.odd_even = 1;
+
+	zr->params.APPn = 0;
+	zr->params.APP_len = 0;	/* No APPn marker */
+	for (i = 0; i < 60; i++)
+		zr->params.APP_data[i] = 0;
+
+	zr->params.COM_len = 0;	/* No COM marker */
+	for (i = 0; i < 60; i++)
+		zr->params.COM_data[i] = 0;
+
+	zr->params.VFIFO_FB = 0;
+
+	memset(zr->params.reserved, 0, sizeof(zr->params.reserved));
+
+	zr->params.jpeg_markers = JPEG_MARKER_DHT | JPEG_MARKER_DQT;
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 08'
echo 'File patch-2.3.10 is continued in part 09'
echo 09 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 09 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
+
+	i = zoran_check_params(zr, &zr->params);
+	if (i)
+		printk(KERN_ERR "%s: zoran_open_init_params internal error\n", zr->name);
+}
+
+/*
+ *   Open a buz card. Right now the flags stuff is just playing
+ */
+
+static int zoran_open(struct video_device *dev, int flags)
+{
+	struct zoran *zr = (struct zoran *) dev;
+
+	DEBUG(printk(KERN_INFO ": zoran_open\n"));
+
+	switch (flags) {
+
+	case 0:
+		if (zr->user)
+			return -EBUSY;
+		zr->user++;
+
+		if (v4l_fbuffer_alloc(zr) < 0) {
+			zr->user--;
+			return -ENOMEM;
+		}
+		/* default setup */
+
+		zoran_open_init_params(zr);
+
+		zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
+
+		btwrite(IRQ_MASK, ZR36057_ISR);		// Clears interrupts
+
+		btor(ZR36057_ICR_IntPinEn, ZR36057_ICR);
+
+		break;
+
+	default:
+		return -EBUSY;
+
+	}
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static void zoran_close(struct video_device *dev)
+{
+	struct zoran *zr = (struct zoran *) dev;
+
+	DEBUG(printk(KERN_INFO ": zoran_close\n"));
+	
+	/* disable interrupts */
+	btand(~ZR36057_ICR_IntPinEn, ZR36057_ICR);
+
+	/* wake up sleeping beauties */
+	wake_up_interruptible(&zr->v4l_capq);
+	wake_up_interruptible(&zr->jpg_capq);
+
+	zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
+	zr36057_set_memgrab(zr, 0);
+	if (zr->v4l_overlay_active)
+		zr36057_overlay(zr, 0);
+
+	zr->user--;
+
+	v4l_fbuffer_free(zr);
+	jpg_fbuffer_free(zr);
+	zr->jpg_nbufs = 0;
+
+	MOD_DEC_USE_COUNT;
+	DEBUG(printk(KERN_INFO ": zoran_close done\n"));
+}
+
+
+static long zoran_read(struct video_device *dev, char *buf, unsigned long count, int nonblock)
+{
+	return -EINVAL;
+}
+
+static long zoran_write(struct video_device *dev, const char *buf, unsigned long count, int nonblock)
+{
+	return -EINVAL;
+}
+
+/*
+ *   ioctl routine
+ */
+
+
+static int zoran_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+	struct zoran *zr = (struct zoran *) dev;
+
+	switch (cmd) {
+
+	case VIDIOCGCAP:
+		{
+			struct video_capability b;
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCGCAP\n"));
+			strncpy(b.name, zr->video_dev.name, sizeof(b.name));
+			b.type = VID_TYPE_CAPTURE |
+			    VID_TYPE_OVERLAY |
+			    VID_TYPE_CLIPPING |
+			    VID_TYPE_FRAMERAM |
+			    VID_TYPE_SCALES;
+			/* theoretically we could also flag VID_TYPE_SUBCAPTURE
+			   but this is not even implemented in the BTTV driver */
+
+			b.channels = 2;		/* composite, svhs */
+			b.audios = 0;
+			b.maxwidth = BUZ_MAX_WIDTH;
+			b.maxheight = BUZ_MAX_HEIGHT;
+			b.minwidth = BUZ_MIN_WIDTH;
+			b.minheight = BUZ_MIN_HEIGHT;
+			if (copy_to_user(arg, &b, sizeof(b))) {
+				return -EFAULT;
+			}
+			return 0;
+		}
+
+	case VIDIOCGCHAN:
+		{
+			struct video_channel v;
+
+			if (copy_from_user(&v, arg, sizeof(v))) {
+				return -EFAULT;
+			}
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCGCHAN for channel %d\n", v.channel));
+			switch (v.channel) {
+			case 0:
+				strcpy(v.name, "Composite");
+				break;
+			case 1:
+				strcpy(v.name, "SVHS");
+				break;
+			default:
+				return -EINVAL;
+			}
+			v.tuners = 0;
+			v.flags = 0;
+			v.type = VIDEO_TYPE_CAMERA;
+			v.norm = zr->params.norm;
+			if (copy_to_user(arg, &v, sizeof(v))) {
+				return -EFAULT;
+			}
+			return 0;
+		}
+
+		/* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says:
+
+		 * "The VIDIOCSCHAN ioctl takes an integer argument and switches the capture to this input."
+		 *                                 ^^^^^^^
+		 * The famos BTTV driver has it implemented with a struct video_channel argument
+		 * and we follow it for compatibility reasons
+		 *
+		 * BTW: this is the only way the user can set the norm!
+		 */
+
+	case VIDIOCSCHAN:
+		{
+			struct video_channel v;
+			int input;
+			int on, res;
+
+			if (copy_from_user(&v, arg, sizeof(v))) {
+				return -EFAULT;
+			}
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCSCHAN: channel=%d, norm=%d\n", v.channel, v.norm));
+			switch (v.channel) {
+			case 0:
+				input = 3;
+				break;
+			case 1:
+				input = 7;
+				break;
+			default:
+				return -EINVAL;
+			}
+
+			if (v.norm != VIDEO_MODE_PAL
+			    && v.norm != VIDEO_MODE_NTSC) {
+				return -EINVAL;
+			}
+			zr->params.norm = v.norm;
+			zr->params.input = v.channel;
+
+			/* We switch overlay off and on since a change in the norm
+			   needs different VFE settings */
+
+			on = zr->v4l_overlay_active && !zr->v4l_memgrab_active;
+			if (on)
+				zr36057_overlay(zr, 0);
+
+			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &input);
+			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &zr->params.norm);
+			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_NORM, &zr->params.norm);
+
+			if (on)
+				zr36057_overlay(zr, 1);
+
+			/* Make sure the changes come into effect */
+			res = wait_grab_pending(zr);
+			if (res)
+				return res;
+
+			return 0;
+		}
+
+	case VIDIOCGTUNER:
+	case VIDIOCSTUNER:
+			return -EINVAL;
+
+	case VIDIOCGPICT:
+		{
+			struct video_picture p = zr->picture;
+
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCGPICT\n"));
+			p.depth = zr->buffer.depth;
+			switch (zr->buffer.depth) {
+			case 15:
+				p.palette = VIDEO_PALETTE_RGB555;
+				break;
+
+			case 16:
+				p.palette = VIDEO_PALETTE_RGB565;
+				break;
+
+			case 24:
+				p.palette = VIDEO_PALETTE_RGB24;
+				break;
+
+			case 32:
+				p.palette = VIDEO_PALETTE_RGB32;
+				break;
+			}
+
+			if (copy_to_user(arg, &p, sizeof(p))) {
+				return -EFAULT;
+			}
+			return 0;
+		}
+
+	case VIDIOCSPICT:
+		{
+			struct video_picture p;
+
+			if (copy_from_user(&p, arg, sizeof(p))) {
+				return -EFAULT;
+			}
+			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_PICTURE, &p);
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCSPICT bri=%d hue=%d col=%d con=%d dep=%d pal=%d\n",
+					   p.brightness, p.hue, p.colour, p.contrast, p.depth, p.palette));
+			/* The depth and palette values have no meaning to us,
+			   should we return  -EINVAL if they don't fit ? */
+			zr->picture = p;
+			return 0;
+		}
+
+	case VIDIOCCAPTURE:
+		{
+			int v, res;
+
+			if (copy_from_user(&v, arg, sizeof(v))) {
+				return -EFAULT;
+			}
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCCAPTURE: %d\n", v));
+			/* If there is nothing to do, return immediatly */
+
+			if ((v && zr->v4l_overlay_active) || (!v && !zr->v4l_overlay_active))
+				return 0;
+
+			if (v == 0) {
+				zr->v4l_overlay_active = 0;
+				if (!zr->v4l_memgrab_active)
+					zr36057_overlay(zr, 0);
+				/* When a grab is running, the video simply won't be switched on any more */
+			} else {
+				if (!zr->buffer_set || !zr->window_set) {
+					return -EINVAL;
+				}
+				zr->v4l_overlay_active = 1;
+				if (!zr->v4l_memgrab_active)
+					zr36057_overlay(zr, 1);
+				/* When a grab is running, the video will be switched on when grab is finished */
+			}
+			/* Make sure the changes come into effect */
+			res = wait_grab_pending(zr);
+			if (res)
+				return res;
+			return 0;
+		}
+
+	case VIDIOCGWIN:
+		{
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCGWIN\n"));
+			if (copy_to_user(arg, &zr->window, sizeof(zr->window))) {
+				return -EFAULT;
+			}
+			return 0;
+		}
+
+	case VIDIOCSWIN:
+		{
+			struct video_clip *vcp;
+			struct video_window vw;
+			int on, end, res;
+
+			if (copy_from_user(&vw, arg, sizeof(vw))) {
+				return -EFAULT;
+			}
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCSWIN: x=%d y=%d w=%d h=%d clipcount=%d\n", vw.x, vw.y, vw.width, vw.height, vw.clipcount));
+			if (!zr->buffer_set) {
+				return -EINVAL;
+			}
+			/*
+			 * The video front end needs 4-byte alinged line sizes, we correct that
+			 * silently here if necessary
+			 */
+
+			if (zr->buffer.depth == 15 || zr->buffer.depth == 16) {
+				end = (vw.x + vw.width) & ~1;	/* round down */
+				vw.x = (vw.x + 1) & ~1;		/* round up */
+				vw.width = end - vw.x;
+			}
+			if (zr->buffer.depth == 24) {
+				end = (vw.x + vw.width) & ~3;	/* round down */
+				vw.x = (vw.x + 3) & ~3;		/* round up */
+				vw.width = end - vw.x;
+			}
+#if 0
+			// At least xawtv seems to care about the following - just leave it away
+			/*
+			 * Also corrected silently (as long as window fits at all):
+			 * video not fitting the screen
+			 */
+#if 0
+			if (vw.x < 0 || vw.y < 0 || vw.x + vw.width > zr->buffer.width ||
+			    vw.y + vw.height > zr->buffer.height) {
+				printk(BUZ_ERR ": VIDIOCSWIN: window does not fit frame buffer: %dx%d+%d*%d\n",
+				       vw.width, vw.height, vw.x, vw.y);
+				return -EINVAL;
+			}
+#else
+			if (vw.x < 0)
+				vw.x = 0;
+			if (vw.y < 0)
+				vw.y = 0;
+			if (vw.x + vw.width > zr->buffer.width)
+				vw.width = zr->buffer.width - vw.x;
+			if (vw.y + vw.height > zr->buffer.height)
+				vw.height = zr->buffer.height - vw.y;
+#endif
+#endif
+
+			/* Check for vaild parameters */
+			if (vw.width < BUZ_MIN_WIDTH || vw.height < BUZ_MIN_HEIGHT ||
+			    vw.width > BUZ_MAX_WIDTH || vw.height > BUZ_MAX_HEIGHT) {
+				return -EINVAL;
+			}
+#ifdef XAWTV_HACK
+			if (vw.width > 720)
+				vw.width = 720;
+#endif
+
+			zr->window.x = vw.x;
+			zr->window.y = vw.y;
+			zr->window.width = vw.width;
+			zr->window.height = vw.height;
+			zr->window.chromakey = 0;
+			zr->window.flags = 0;	// RJ: Is this intended for interlace on/off ?
+
+			zr->window.clips = NULL;
+			zr->window.clipcount = vw.clipcount;
+
+			/*
+			 * If an overlay is running, we have to switch it off
+			 * and switch it on again in order to get the new settings in effect.
+			 *
+			 * We also want to avoid that the overlay mask is written
+			 * when an overlay is running.
+			 */
+
+			on = zr->v4l_overlay_active && !zr->v4l_memgrab_active;
+			if (on)
+				zr36057_overlay(zr, 0);
+
+			/*
+			 *   Write the overlay mask if clips are wanted.
+			 */
+			if (vw.clipcount) {
+				vcp = vmalloc(sizeof(struct video_clip) * (vw.clipcount + 4));
+				if (vcp == NULL) {
+					return -ENOMEM;
+				}
+				if (copy_from_user(vcp, vw.clips, sizeof(struct video_clip) * vw.clipcount)) {
+					vfree(vcp);
+					return -EFAULT;
+				}
+				write_overlay_mask(zr, vcp, vw.clipcount);
+				vfree(vcp);
+			}
+			if (on)
+				zr36057_overlay(zr, 1);
+			zr->window_set = 1;
+
+			/* Make sure the changes come into effect */
+			res = wait_grab_pending(zr);
+			if (res)
+				return res;
+
+			return 0;
+		}
+
+	case VIDIOCGFBUF:
+		{
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCGFBUF\n"));
+			if (copy_to_user(arg, &zr->buffer, sizeof(zr->buffer))) {
+				return -EFAULT;
+			}
+			return 0;
+		}
+
+	case VIDIOCSFBUF:
+		{
+			struct video_buffer v;
+
+			if (!capable(CAP_SYS_ADMIN))
+				return -EPERM;
+
+			if (copy_from_user(&v, arg, sizeof(v)))
+				return -EFAULT;
+			
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCSFBUF: base=0x%x w=%d h=%d depth=%d bpl=%d\n", (u32) v.base, v.width, v.height, v.depth, v.bytesperline));
+			if (zr->v4l_overlay_active) {
+				/* Has the user gotten crazy ... ? */
+				return -EINVAL;
+			}
+			if (v.depth != 15
+			    && v.depth != 16
+			    && v.depth != 24
+			    && v.depth != 32) {
+				return -EINVAL;
+			}
+			if (v.height <= 0 || v.width <= 0 || v.bytesperline <= 0) {
+				return -EINVAL;
+			}
+			if (v.bytesperline & 3) {
+				return -EINVAL;
+			}
+			if (v.base) {
+				zr->buffer.base = (void *) ((unsigned long) v.base & ~3);
+			}
+			zr->buffer.height = v.height;
+			zr->buffer.width = v.width;
+			zr->buffer.depth = v.depth;
+			zr->buffer.bytesperline = v.bytesperline;
+
+			if (zr->buffer.base)
+				zr->buffer_set = 1;
+			zr->window_set = 0;	/* The user should set new window parameters */
+			return 0;
+		}
+
+		/* RJ: what is VIDIOCKEY intended to do ??? */
+
+	case VIDIOCGFREQ:
+	case VIDIOCSFREQ:
+	case VIDIOCGAUDIO:
+	case VIDIOCSAUDIO:
+		return -EINVAL;
+		
+	case VIDIOCSYNC:
+		{
+			int v;
+
+			if (copy_from_user(&v, arg, sizeof(v))) {
+				return -EFAULT;
+			}
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCSYNC %d\n", v));
+			return v4l_sync(zr, v);
+		}
+
+	case VIDIOCMCAPTURE:
+		{
+			struct video_mmap vm;
+
+			if (copy_from_user((void *) &vm, (void *) arg, sizeof(vm))) {
+				return -EFAULT;
+			}
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCMCAPTURE frame=%d geom=%dx%d fmt=%d\n",
+			       vm.frame, vm.height, vm.width, vm.format));
+			return v4l_grab(zr, &vm);
+		}
+
+	case VIDIOCGMBUF:
+		{
+			struct video_mbuf vm;
+			int i;
+
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCGMBUF\n"));
+		
+			vm.size = v4l_nbufs * v4l_bufsize;
+			vm.frames = v4l_nbufs;
+			for (i = 0; i < v4l_nbufs; i++) {
+				vm.offsets[i] = i * v4l_bufsize;
+			}
+
+			/* The next mmap will map the V4L buffers */
+			zr->map_mjpeg_buffers = 0;
+
+			if (copy_to_user(arg, &vm, sizeof(vm))) {
+				return -EFAULT;
+			}
+			return 0;
+		}
+
+	case VIDIOCGUNIT:
+		{
+			struct video_unit vu;
+
+			IOCTL_DEBUG(printk("buz ioctl VIDIOCGUNIT\n"));
+			vu.video = zr->video_dev.minor;
+			vu.vbi = VIDEO_NO_UNIT;
+			vu.radio = VIDEO_NO_UNIT;
+			vu.audio = VIDEO_NO_UNIT;
+			vu.teletext = VIDEO_NO_UNIT;
+			if (copy_to_user(arg, &vu, sizeof(vu)))
+				return -EFAULT;
+			return 0;
+		}
+
+		/*
+		 * RJ: In principal we could support subcaptures for V4L grabbing.
+		 *     Not even the famous BTTV driver has them, however.
+		 *     If there should be a strong demand, one could consider
+		 *     to implement them.
+		 */
+	case VIDIOCGCAPTURE:
+	case VIDIOCSCAPTURE:
+			return -EINVAL;
+
+	case BUZIOC_G_PARAMS:
+		{
+			IOCTL_DEBUG(printk("buz ioctl BUZIOC_G_PARAMS\n"));
+			if (copy_to_user(arg, &(zr->params), sizeof(zr->params))) 
+				return -EFAULT;
+			return 0;
+		}
+
+	case BUZIOC_S_PARAMS:
+		{
+			struct zoran_params bp;
+			int input, on;
+
+			if (zr->codec_mode != BUZ_MODE_IDLE) {
+				return -EINVAL;
+			}
+			if (copy_from_user(&bp, arg, sizeof(bp))) {
+				return -EFAULT;
+			}
+			IOCTL_DEBUG(printk("buz ioctl BUZIOC_S_PARAMS\n"));
+			
+			/* Check the params first before overwriting our internal values */
+
+			if (zoran_check_params(zr, &bp))
+				return -EINVAL;
+
+			zr->params = bp;
+
+			/* Make changes of input and norm go into effect immediatly */
+
+			/* We switch overlay off and on since a change in the norm
+			   needs different VFE settings */
+
+			on = zr->v4l_overlay_active && !zr->v4l_memgrab_active;
+			if (on)
+				zr36057_overlay(zr, 0);
+
+			input = zr->params.input == 0 ? 3 : 7;
+			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &input);
+			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &zr->params.norm);
+			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_NORM, &zr->params.norm);
+
+			if (on)
+				zr36057_overlay(zr, 1);
+
+			if (copy_to_user(arg, &bp, sizeof(bp))) {
+				return -EFAULT;
+			}
+			return 0;
+		}
+
+	case BUZIOC_REQBUFS:
+		{
+			struct zoran_requestbuffers br;
+
+			if (zr->jpg_buffers_allocated) {
+				return -EINVAL;
+			}
+			if (copy_from_user(&br, arg, sizeof(br))) {
+				return -EFAULT;
+			}
+			IOCTL_DEBUG(printk("buz ioctl BUZIOC_REQBUFS count = %lu size=%lu\n",
+					   br.count, br.size));
+			/* Enforce reasonable lower and upper limits */
+			if (br.count < 4)
+				br.count = 4;	/* Could be choosen smaller */
+			if (br.count > BUZ_MAX_FRAME)
+				br.count = BUZ_MAX_FRAME;
+			br.size = PAGE_ALIGN(br.size);
+			if (br.size < 8192)
+				br.size = 8192;		/* Arbitrary */
+			/* br.size is limited by 1 page for the stat_com tables to a Maximum of 2 MB */
+			if (br.size > (512 * 1024))
+				br.size = (512 * 1024);		/* 512 K should be enough */
+			if (zr->need_contiguous && br.size > MAX_KMALLOC_MEM)
+				br.size = MAX_KMALLOC_MEM;
+
+			zr->jpg_nbufs = br.count;
+			zr->jpg_bufsize = br.size;
+
+			if (jpg_fbuffer_alloc(zr))
+				return -ENOMEM;
+
+			/* The next mmap will map the MJPEG buffers */
+			zr->map_mjpeg_buffers = 1;
+
+			if (copy_to_user(arg, &br, sizeof(br))) {
+				return -EFAULT;
+			}
+			return 0;
+		}
+
+	case BUZIOC_QBUF_CAPT:
+		{
+			int nb;
+
+			if (copy_from_user((void *) &nb, (void *) arg, sizeof(int))) {
+				return -EFAULT;
+			}
+			IOCTL_DEBUG(printk("buz ioctl BUZIOC_QBUF_CAPT %d\n", nb));
+			return jpg_qbuf(zr, nb, BUZ_MODE_MOTION_COMPRESS);
+		}
+
+	case BUZIOC_QBUF_PLAY:
+		{
+			int nb;
+
+			if (copy_from_user((void *) &nb, (void *) arg, sizeof(int))) {
+				return -EFAULT;
+			}
+			IOCTL_DEBUG(printk("buz ioctl BUZIOC_QBUF_PLAY %d\n", nb));
+			return jpg_qbuf(zr, nb, BUZ_MODE_MOTION_DECOMPRESS);
+		}
+
+	case BUZIOC_SYNC:
+		{
+			struct zoran_sync bs;
+			int res;
+
+			IOCTL_DEBUG(printk("buz ioctl BUZIOC_SYNC\n"));
+			res = jpg_sync(zr, &bs);
+			if (copy_to_user(arg, &bs, sizeof(bs))) {
+				return -EFAULT;
+			}
+			return res;
+		}
+
+	case BUZIOC_G_STATUS:
+		{
+			struct zoran_status bs;
+			int norm, input, status;
+
+			if (zr->codec_mode != BUZ_MODE_IDLE) {
+				return -EINVAL;
+			}
+			if (copy_from_user(&bs, arg, sizeof(bs))) {
+				return -EFAULT;
+			}
+			IOCTL_DEBUG(printk("buz ioctl BUZIOC_G_STATUS\n"));
+			switch (bs.input) {
+			case 0:
+				input = 3;
+				break;
+			case 1:
+				input = 7;
+				break;
+			default:
+				return -EINVAL;
+			}
+
+			/* Set video norm to VIDEO_MODE_AUTO */
+
+			norm = VIDEO_MODE_AUTO;
+			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &input);
+			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &norm);
+
+			/* sleep 1 second */
+
+			schedule_timeout(HZ);
+			
+			/* Get status of video decoder */
+
+			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_GET_STATUS, &status);
+			bs.signal = (status & DECODER_STATUS_GOOD) ? 1 : 0;
+			bs.norm = (status & DECODER_STATUS_NTSC) ? VIDEO_MODE_NTSC : VIDEO_MODE_PAL;
+			bs.color = (status & DECODER_STATUS_COLOR) ? 1 : 0;
+
+			/* restore previous input and norm */
+			input = zr->params.input == 0 ? 3 : 7;
+			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &input);
+			i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &zr->params.norm);
+
+			if (copy_to_user(arg, &bs, sizeof(bs))) {
+				return -EFAULT;
+			}
+			return 0;
+		}
+
+	default:
+		    return -ENOIOCTLCMD;
+
+	}
+	return 0;
+}
+
+
+/*
+ *   This maps the buffers to user space.
+ *
+ *   Depending on the state of zr->map_mjpeg_buffers
+ *   the V4L or the MJPEG buffers are mapped
+ *
+ */
+
+static int zoran_mmap(struct video_device *dev, const char *adr, unsigned long size)
+{
+	struct zoran *zr = (struct zoran *) dev;
+	unsigned long start = (unsigned long) adr;
+	unsigned long page, pos, todo, fraglen;
+	int i, j;
+
+	if (zr->map_mjpeg_buffers) {
+		/* Map the MJPEG buffers */
+
+		if (!zr->jpg_buffers_allocated) {
+			return -ENOMEM;
+		}
+		if (size > zr->jpg_nbufs * zr->jpg_bufsize) {
+			return -EINVAL;
+		}
+
+		for (i = 0; i < zr->jpg_nbufs; i++) {
+			for (j = 0; j < zr->jpg_bufsize / PAGE_SIZE; j++) {
+				fraglen = (zr->jpg_gbuf[i].frag_tab[2 * j + 1] & ~1) << 1;
+				todo = size;
+				if (todo > fraglen)
+					todo = fraglen;
+				pos = (unsigned long) zr->jpg_gbuf[i].frag_tab[2 * j];
+				page = virt_to_phys(bus_to_virt(pos));	/* should just be pos on i386 */
+				if (remap_page_range(start, page, todo, PAGE_SHARED)) {
+					printk(KERN_ERR "%s: zoran_mmap(V4L): remap_page_range failed\n", zr->name);
+					return -EAGAIN;
+				}
+				size -= todo;
+				start += todo;
+				if (size == 0)
+					break;
+				if (zr->jpg_gbuf[i].frag_tab[2 * j + 1] & 1)
+					break;	/* was last fragment */
+			}
+			if (size == 0)
+				break;
+		}
+	} else {
+		/* Map the V4L buffers */
+
+		if (size > v4l_nbufs * v4l_bufsize) {
+			return -EINVAL;
+		}
+
+		for (i = 0; i < v4l_nbufs; i++) {
+			todo = size;
+			if (todo > v4l_bufsize)
+				todo = v4l_bufsize;
+			page = zr->v4l_gbuf[i].fbuffer_phys;
+			DEBUG(printk("V4L remap page range %d 0x%x %d to 0x%x\n", i, page, todo, start));
+			if (remap_page_range(start, page, todo, PAGE_SHARED)) {
+				printk(KERN_ERR "%s: zoran_mmap(V4L): remap_page_range failed\n", zr->name);
+				return -EAGAIN;
+			}
+			size -= todo;
+			start += todo;
+			if (size == 0)
+				break;
+		}
+	}
+	return 0;
+}
+
+static int zoran_init_done(struct video_device *dev)
+{
+	return 0;
+}
+
+static struct video_device zoran_template =
+{
+	BUZ_NAME,
+	VID_TYPE_CAPTURE | VID_TYPE_OVERLAY | VID_TYPE_CLIPPING | VID_TYPE_FRAMERAM |
+	VID_TYPE_SCALES | VID_TYPE_SUBCAPTURE,
+	VID_HARDWARE_BT848,	/* Not true, but the buz is not yet in the list */
+	zoran_open,
+	zoran_close,
+	zoran_read,
+	zoran_write,
+	NULL,
+	zoran_ioctl,
+	zoran_mmap,
+	zoran_init_done,
+	NULL,
+	0,
+	0
+};
+
+static int zr36057_init(int i)
+{
+	struct zoran *zr = &zoran[i];
+	unsigned long mem;
+	unsigned mem_needed;
+	int j;
+	int rev;
+
+	/* reset zr36057 */
+	btwrite(0, ZR36057_SPGPPCR);
+	mdelay(10);
+
+	/* default setup of all parameters which will persist beetween opens */
+
+	zr->user = 0;
+	
+	init_waitqueue_head(&zr->v4l_capq);
+	init_waitqueue_head(&zr->jpg_capq);
+
+	zr->map_mjpeg_buffers = 0;	/* Map V4L buffers by default */
+
+	zr->jpg_nbufs = 0;
+	zr->jpg_bufsize = 0;
+	zr->jpg_buffers_allocated = 0;
+
+	zr->buffer_set = 0;	/* Flag if frame buffer has been set */
+	zr->buffer.base = (void *) vidmem;
+	zr->buffer.width = 0;
+	zr->buffer.height = 0;
+	zr->buffer.depth = 0;
+	zr->buffer.bytesperline = 0;
+
+	zr->params.norm = default_norm ? 1 : 0;	/* Avoid nonsense settings from user */
+	zr->params.input = default_input ? 1 : 0;	/* Avoid nonsense settings from user */
+	zr->video_interlace = 0;
+
+	/* Should the following be reset at every open ? */
+
+	zr->picture.colour = 32768;
+	zr->picture.brightness = 32768;
+	zr->picture.hue = 32768;
+	zr->picture.contrast = 32768;
+	zr->picture.whiteness = 0;
+	zr->picture.depth = 0;
+	zr->picture.palette = 0;
+
+	for (j = 0; j < VIDEO_MAX_FRAME; j++) {
+		zr->v4l_gbuf[i].fbuffer = 0;
+		zr->v4l_gbuf[i].fbuffer_phys = 0;
+		zr->v4l_gbuf[i].fbuffer_bus = 0;
+	}
+
+	zr->stat_com = 0;
+
+	/* default setup (will be repeated at every open) */
+
+	zoran_open_init_params(zr);
+
+	/* allocate memory *before* doing anything to the hardware in case allocation fails */
+
+	/* STAT_COM table and overlay mask */
+
+	mem_needed = (BUZ_NUM_STAT_COM + ((BUZ_MAX_WIDTH + 31) / 32) * BUZ_MAX_HEIGHT) * 4;
+	mem = (unsigned long) kmalloc(mem_needed, GFP_KERNEL);
+	if (!mem) {
+		return -ENOMEM;
+	}
+	memset((void *) mem, 0, mem_needed);
+
+	zr->stat_com = (u32 *) mem;
+	for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
+		zr->stat_com[j] = 1;	/* mark as unavailable to zr36057 */
+	}
+	zr->overlay_mask = (u32 *) (mem + BUZ_NUM_STAT_COM * 4);
+
+	/* Initialize zr->jpg_gbuf */
+
+	for (j = 0; j < BUZ_MAX_FRAME; j++) {
+		zr->jpg_gbuf[j].frag_tab = 0;
+		zr->jpg_gbuf[j].frag_tab_bus = 0;
+		zr->jpg_gbuf[j].state = BUZ_STATE_USER;
+		zr->jpg_gbuf[j].bs.frame = j;
+	}
+
+	/* take zr36057 out of reset now */
+	btwrite(ZR36057_SPGPPCR_SoftReset, ZR36057_SPGPPCR);
+	mdelay(10);
+
+	/* stop all DMA processes */
+	btwrite(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
+	btand(~ZR36057_VDCR_VidEn, ZR36057_VDCR);
+	/* assert P_Reset */
+	btwrite(0, ZR36057_JPC);
+
+	switch(zr->board)
+	{
+		case BOARD_BUZ:
+	
+			/* set up GPIO direction */
+			btwrite(ZR36057_SPGPPCR_SoftReset | 0, ZR36057_SPGPPCR);
+
+			/* Set up guest bus timing - Guests 0..3 Tdur=12, Trec=3 */
+			btwrite((GPIO_MASK << 24) | 0x8888, ZR36057_GPPGCR1);
+			mdelay(10);
+
+			/* reset video decoder */
+
+			GPIO(zr, 0, 0);
+			mdelay(10);
+			GPIO(zr, 0, 1);
+			mdelay(10);
+
+			/* reset JPEG codec */
+			zr36060_sleep(zr, 0);
+			mdelay(10);
+			zr36060_reset(zr);
+			mdelay(10);
+			zr36060_sleep(zr, 1);
+			mdelay(10);
+	
+			/* display codec revision */
+			if ((rev=zr36060_read_8(zr, 0x022)) == 0x33) {
+				printk(KERN_INFO "%s: Zoran ZR36060 (rev %d)\n",
+			       zr->name, zr36060_read_8(zr, 0x023));
+			} else {
+				printk(KERN_ERR "%s: Zoran ZR36060 not found (Rev=%d)\n", zr->name, rev);
+				kfree((void *) zr->stat_com);
+				return -1;
+			}
+			break;
+			
+		case BOARD_LML33:
+//			btwrite(btread(ZR36057_SPGPPCR)&~ZR36057_SPGPPCR_SoftReset , ZR36057_SPGPPCR);
+//			udelay(100);
+//			btwrite(btread(ZR36057_SPGPPCR)|ZR36057_SPGPPCR_SoftReset , ZR36057_SPGPPCR);
+//			udelay(1000);
+
+			/*
+			 *	Set up the GPIO direction
+			 */
+			btwrite(btread(ZR36057_SPGPPCR_SoftReset)|0 , ZR36057_SPGPPCR);
+			/* Set up guest bus timing - Guests 0..2 Tdur=12, Trec=3 */
+			btwrite(0xFF00F888, ZR36057_GPPGCR1);
+			mdelay(10);
+			GPIO(zr, 5, 0);		/* Analog video bypass */
+			udelay(3000);
+			GPIO(zr, 0, 0); 	/* Reset 819 */
+			udelay(3000);
+			GPIO(zr, 0, 1);		/* 819 back */
+			udelay(3000);
+			/* reset JPEG codec */
+			zr36060_sleep(zr, 0);
+			udelay(3000);
+			zr36060_reset(zr);
+			udelay(3000);
+			zr36060_sleep(zr, 1);
+			udelay(3000);
+
+			/* display codec revision */
+			if ((rev=zr36060_read_8(zr, 0x022)) == 0x33) {
+				printk(KERN_INFO "%s: Zoran ZR36060 (rev %d)\n",
+			       zr->name, zr36060_read_8(zr, 0x023));
+			} else {
+				printk(KERN_ERR "%s: Zoran ZR36060 not found (rev=%d)\n", zr->name, rev);
+//				kfree((void *) zr->stat_com);
+//				return -1;
+			}
+			break;
+	}
+	/* i2c */
+	memcpy(&zr->i2c, &zoran_i2c_bus_template, sizeof(struct i2c_bus));
+	sprintf(zr->i2c.name, "zoran%u%u", zr->id);
+	zr->i2c.data = zr;
+	if (i2c_register_bus(&zr->i2c) < 0) {
+		kfree((void *) zr->stat_com);
+		return -1;
+	}
+	/*
+	 *   Now add the template and register the device unit.
+	 */
+	memcpy(&zr->video_dev, &zoran_template, sizeof(zoran_template));
+	sprintf(zr->video_dev.name, "zoran%u", zr->id);
+	if (video_register_device(&zr->video_dev, VFL_TYPE_GRABBER) < 0) {
+		i2c_unregister_bus(&zr->i2c);
+		kfree((void *) zr->stat_com);
+		return -1;
+	}
+	/* toggle JPEG codec sleep to sync PLL */
+	zr36060_sleep(zr, 1);
+	mdelay(10);
+	zr36060_sleep(zr, 0);
+	mdelay(10);
+
+	/* Enable bus-mastering */
+	pci_set_master(zr->pci_dev);
+
+	j = zr->params.input == 0 ? 3 : 7;
+	i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &j);
+	i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &zr->params.norm);
+	i2c_control_device(&zr->i2c, I2C_DRIVERID_VIDEOENCODER, ENCODER_SET_NORM, &zr->params.norm);
+
+	/* set individual interrupt enables (without GIRQ0)
+	   but don't global enable until zoran_open() */
+
+	btwrite(IRQ_MASK & ~ZR36057_ISR_GIRQ0, ZR36057_ICR);
+
+	if(request_irq(zr->pci_dev->irq, zoran_irq,
+	       SA_SHIRQ | SA_INTERRUPT, zr->name, (void *) zr)<0)
+	{
+		printk(KERN_ERR "%s: Can't assign irq.\n", zr->name);
+		video_unregister_device(&zr->video_dev);
+		i2c_unregister_bus(&zr->i2c);
+		kfree((void *) zr->stat_com);
+		return -1;
+	}
+	zr->initialized = 1;
+	return 0;
+}
+
+
+
+static void release_zoran(void)
+{
+	u8 command;
+	int i;
+	struct zoran *zr;
+
+	for (i = 0; i < zoran_num; i++) {
+		zr = &zoran[i];
+
+		if (!zr->initialized)
+			continue;
+
+		/* unregister i2c_bus */
+		i2c_unregister_bus((&zr->i2c));
+
+		/* disable PCI bus-mastering */
+		pci_read_config_byte(zr->pci_dev, PCI_COMMAND, &command);
+		command &= ~PCI_COMMAND_MASTER;
+		pci_write_config_byte(zr->pci_dev, PCI_COMMAND, command);
+
+		/* put chip into reset */
+		btwrite(0, ZR36057_SPGPPCR);
+
+		free_irq(zr->pci_dev->irq, zr);
+
+		/* unmap and free memory */
+
+		kfree((void *) zr->stat_com);
+
+		iounmap(zr->zr36057_mem);
+
+		video_unregister_device(&zr->video_dev);
+	}
+}
+
+/*
+ *   Scan for a Buz card (actually for the PCI controller ZR36057),
+ *   request the irq and map the io memory
+ */
+
+static int find_zr36057(void)
+{
+	unsigned char latency;
+	struct zoran *zr;
+	struct pci_dev *dev = NULL;
+
+	zoran_num = 0;
+
+	while (zoran_num < BUZ_MAX
+	       && (dev = pci_find_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) {
+		zr = &zoran[zoran_num];
+		zr->pci_dev = dev;
+		zr->zr36057_mem = NULL;
+		zr->id = zoran_num;
+		sprintf(zr->name, "zoran%u", zr->id);
+
+		spin_lock_init(&zr->lock);
+
+		zr->zr36057_adr = zr->pci_dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK;
+		pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
+		if (zr->revision < 2) {
+			printk(KERN_INFO "%s: Zoran ZR36057 (rev %d) irq: %d, memory: 0x%08x.\n",
+			       zr->name, zr->revision, zr->pci_dev->irq, zr->zr36057_adr);
+		} else {
+			unsigned short ss_vendor_id, ss_id;
+
+			pci_read_config_word(zr->pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor_id);
+			pci_read_config_word(zr->pci_dev, PCI_SUBSYSTEM_ID, &ss_id);
+			printk(KERN_INFO "%s: Zoran ZR36067 (rev %d) irq: %d, memory: 0x%08x\n",
+			       zr->name, zr->revision, zr->pci_dev->irq, zr->zr36057_adr);
+			printk(KERN_INFO "%s: subsystem vendor=0x%04x id=0x%04x\n",
+			       zr->name, ss_vendor_id, ss_id);
+			if(ss_vendor_id==0xFF10 && ss_id == 0xDE41)
+			{
+				zr->board = BOARD_LML33;
+				printk(KERN_INFO "%s: LML33 detected.\n", zr->name);
+			}
+		}
+
+		zr->zr36057_mem = ioremap(zr->zr36057_adr, 0x1000);
+
+		/* set PCI latency timer */
+		pci_read_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, &latency);
+		if (latency != 48) {
+			printk(KERN_INFO "%s: Changing PCI latency from %d to 48.\n", zr->name, latency);
+			latency = 48;
+			pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER, latency);
+		}
+		zoran_num++;
+	}
+	if (zoran_num == 0)
+		printk(KERN_INFO "zoran: no cards found.\n");
+
+	return zoran_num;
+}
+
+#include "chipsets.h"
+
+static void handle_chipset(void)
+{
+	int index;
+	struct pci_dev *dev = NULL;
+
+	for (index = 0; index < sizeof(black) / sizeof(black[0]); index++) {
+		if ((dev = pci_find_device(black[index].vendor, black[index].device, dev)) != NULL) {
+			printk(KERN_INFO ": Host bridge: %s, ", black[index].name);
+			switch (black[index].action) {
+
+			case TRITON:
+				printk("enabling Triton support.\n");
+				triton = 1;
+				break;
+
+			case NATOMA:
+				printk("enabling Natoma workaround.\n");
+				natoma = 1;
+				break;
+			}
+		}
+	}
+}
+
+#ifdef MODULE
+int init_module(void)
+#else
+int init_zoran_cards(struct video_init *unused)
+#endif
+{
+	int i;
+
+
+	printk(KERN_INFO "Zoran driver 1.00 (c) 1999 Rainer Johanni, Dave Perks.\n");
+
+	/* Look for Buz cards */
+
+	if (find_zr36057() <= 0) {
+		return -EIO;
+	}
+	printk(KERN_INFO"zoran: %d zoran card(s) found\n", zoran_num);
+
+	if (zoran_num == 0)
+		return -ENXIO;
+
+	
+	/* check the parameters we have been given, adjust if necessary */
+
+	if (v4l_nbufs < 0)
+		v4l_nbufs = 0;
+	if (v4l_nbufs > VIDEO_MAX_FRAME)
+		v4l_nbufs = VIDEO_MAX_FRAME;
+	/* The user specfies the in KB, we want them in byte (and page aligned) */
+	v4l_bufsize = PAGE_ALIGN(v4l_bufsize * 1024);
+	if (v4l_bufsize < 32768)
+		v4l_bufsize = 32768;
+	/* 2 MB is arbitrary but sufficient for the maximum possible images */
+	if (v4l_bufsize > 2048 * 1024)
+		v4l_bufsize = 2048 * 1024;
+
+	printk(KERN_INFO "zoran: using %d V4L buffers of size %d KB\n", v4l_nbufs, v4l_bufsize >> 10);
+
+	/* Use parameter for vidmem or try to find a video card */
+
+	if (vidmem) {
+		printk(KERN_INFO "zoran: Using supplied video memory base address @ 0x%lx\n", vidmem);
+	}
+
+	/* check if we have a Triton or Natome chipset */
+
+	handle_chipset();
+
+	/* take care of Natoma chipset and a revision 1 zr36057 */
+
+	for (i = 0; i < zoran_num; i++) {
+		if (natoma && zoran[i].revision <= 1) {
+			zoran[i].need_contiguous = 1;
+			printk(KERN_INFO "%s: ZR36057/Natome bug, max. buffer size is 128K\n", zoran[i].name);
+		} else {
+			zoran[i].need_contiguous = 0;
+		}
+	}
+
+	/* initialize the Buzs */
+
+	/* We have to know which ones must be released if an error occurs */
+	for (i = 0; i < zoran_num; i++)
+		zoran[i].initialized = 0;
+
+	for (i = 0; i < zoran_num; i++) {
+		if (zr36057_init(i) < 0) {
+			release_zoran();
+			return -EIO;
+		}
+	}
+
+	return 0;
+}
+
+
+
+#ifdef MODULE
+
+void cleanup_module(void)
+{
+	release_zoran();
+}
+
+#endif
diff -u --recursive --new-file v2.3.9/linux/drivers/char/buz.h linux/drivers/char/buz.h
--- v2.3.9/linux/drivers/char/buz.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/buz.h	Mon Jul  5 20:07:02 1999
@@ -0,0 +1,319 @@
+/* 
+   buz - Iomega Buz driver
+
+   Copyright (C) 1999 Rainer Johanni <Rai...@Johanni.de>
+
+   based on
+
+   buz.0.0.3 Copyright (C) 1998 Dave Perks <dpe...@ibm.net>
+
+   and
+
+   bttv - Bt848 frame grabber driver
+   Copyright (C) 1996,97 Ralph Metzler (rj...@thp.uni-koeln.de)
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _BUZ_H_
+#define _BUZ_H_
+
+/* The Buz only supports a maximum width of 720, but some V4L
+   applications (e.g. xawtv are more happy with 768).
+   If XAWTV_HACK is defined, we try to fake a device with bigger width */
+
+#define XAWTV_HACK
+
+#ifdef XAWTV_HACK
+#define   BUZ_MAX_WIDTH   768	/* never display more than 768 pixels */
+#else
+#define   BUZ_MAX_WIDTH   720	/* never display more than 720 pixels */
+#endif
+#define   BUZ_MAX_HEIGHT  576	/* never display more than 576 rows */
+#define   BUZ_MIN_WIDTH    32	/* never display less than 32 pixels */
+#define   BUZ_MIN_HEIGHT   24	/* never display less than 24 rows */
+
+struct zoran_requestbuffers {
+	unsigned long count;	/* Number of buffers for MJPEG grabbing */
+	unsigned long size;	/* Size PER BUFFER in bytes */
+};
+
+struct zoran_sync {
+	unsigned long frame;	/* number of buffer that has been free'd */
+	unsigned long length;	/* number of code bytes in buffer (capture only) */
+	unsigned long seq;	/* frame sequence number */
+	struct timeval timestamp;	/* timestamp */
+};
+
+struct zoran_status {
+	int input;		/* Input channel, has to be set prior to BUZIOC_G_STATUS */
+	int signal;		/* Returned: 1 if valid video signal detected */
+	int norm;		/* Returned: VIDEO_MODE_PAL or VIDEO_MODE_NTSC */
+	int color;		/* Returned: 1 if color signal detected */
+};
+
+struct zoran_params {
+
+	/* The following parameters can only be queried */
+
+	int major_version;	/* Major version number of driver */
+	int minor_version;	/* Minor version number of driver */
+
+	/* Main control parameters */
+
+	int input;		/* Input channel: 0 = Composite, 1 = S-VHS */
+	int norm;		/* Norm: VIDEO_MODE_PAL or VIDEO_MODE_NTSC */
+	int decimation;		/* decimation of captured video,
+				   enlargement of video played back.
+				   Valid values are 1, 2, 4 or 0.
+				   0 is a special value where the user
+				   has full control over video scaling */
+
+	/* The following parameters only have to be set if decimation==0,
+	   for other values of decimation they provide the data how the image is captured */
+
+	int HorDcm;		/* Horizontal decimation: 1, 2 or 4 */
+	int VerDcm;		/* Vertical decimation: 1 or 2 */
+	int TmpDcm;		/* Temporal decimation: 1 or 2,
+				   if TmpDcm==2 in capture every second frame is dropped,
+				   in playback every frame is played twice */
+	int field_per_buff;	/* Number of fields per buffer: 1 or 2 */
+	int img_x;		/* start of image in x direction */
+	int img_y;		/* start of image in y direction */
+	int img_width;		/* image width BEFORE decimation,
+				   must be a multiple of HorDcm*16 */
+	int img_height;		/* image height BEFORE decimation,
+				   must be a multiple of VerDcm*8 */
+
+	/* --- End of parameters for decimation==0 only --- */
+
+	/* JPEG control parameters */
+
+	int quality;		/* Measure for quality of compressed images.
+				   Scales linearly with the size of the compressed images.
+				   Must be beetween 0 and 100, 100 is a compression
+				   ratio of 1:4 */
+
+	int odd_even;		/* Which field should come first ??? */
+
+	int APPn;		/* Number of APP segment to be written, must be 0..15 */
+	int APP_len;		/* Length of data in JPEG APPn segment */
+	char APP_data[60];	/* Data in the JPEG APPn segment. */
+
+	int COM_len;		/* Length of data in JPEG COM segment */
+	char COM_data[60];	/* Data in JPEG COM segment */
+
+	unsigned long jpeg_markers;	/* Which markers should go into the JPEG output.
+					   Unless you exactly know what you do, leave them untouched.
+					   Inluding less markers will make the resulting code
+					   smaller, but there will be fewer aplications
+					   which can read it.
+					   The presence of the APP and COM marker is
+					   influenced by APP0_len and COM_len ONLY! */
+#define JPEG_MARKER_DHT (1<<3)	/* Define Huffman Tables */
+#define JPEG_MARKER_DQT (1<<4)	/* Define Quantization Tables */
+#define JPEG_MARKER_DRI (1<<5)	/* Define Restart Interval */
+#define JPEG_MARKER_COM (1<<6)	/* Comment segment */
+#define JPEG_MARKER_APP (1<<7)	/* App segment, driver will allways use APP0 */
+
+	int VFIFO_FB;		/* Flag for enabling Video Fifo Feedback.
+				   If this flag is turned on and JPEG decompressing
+				   is going to the screen, the decompress process
+				   is stopped every time the Video Fifo is full.
+				   This enables a smooth decompress to the screen
+				   but the video output signal will get scrambled */
+
+	/* Misc */
+
+	char reserved[312];	/* Makes 512 bytes for this structure */
+};
+
+/*
+   Private IOCTL to set up for displaying MJPEG
+ */
+#define BUZIOC_G_PARAMS       _IOR ('v', BASE_VIDIOCPRIVATE+0,  struct zoran_params)
+#define BUZIOC_S_PARAMS       _IOWR('v', BASE_VIDIOCPRIVATE+1,  struct zoran_params)
+#define BUZIOC_REQBUFS        _IOWR('v', BASE_VIDIOCPRIVATE+2,  struct zoran_requestbuffers)
+#define BUZIOC_QBUF_CAPT      _IOW ('v', BASE_VIDIOCPRIVATE+3,  int)
+#define BUZIOC_QBUF_PLAY      _IOW ('v', BASE_VIDIOCPRIVATE+4,  int)
+#define BUZIOC_SYNC           _IOR ('v', BASE_VIDIOCPRIVATE+5,  struct zoran_sync)
+#define BUZIOC_G_STATUS       _IOWR('v', BASE_VIDIOCPRIVATE+6,  struct zoran_status)
+
+
+#ifdef __KERNEL__
+
+#define BUZ_NUM_STAT_COM    4
+#define BUZ_MASK_STAT_COM   3
+
+#define BUZ_MAX_FRAME     256	/* Must be a power of 2 */
+#define BUZ_MASK_FRAME    255	/* Must be BUZ_MAX_FRAME-1 */
+
+#if VIDEO_MAX_FRAME <= 32
+#define   V4L_MAX_FRAME   32
+#elif VIDEO_MAX_FRAME <= 64
+#define   V4L_MAX_FRAME   64
+#else
+#error   "Too many video frame buffers to handle"
+#endif
+#define   V4L_MASK_FRAME   (V4L_MAX_FRAME - 1)
+
+
+#include "zr36057.h"
+
+enum zoran_codec_mode {
+	BUZ_MODE_IDLE,		/* nothing going on */
+	BUZ_MODE_MOTION_COMPRESS,	/* grabbing frames */
+	BUZ_MODE_MOTION_DECOMPRESS,	/* playing frames */
+	BUZ_MODE_STILL_COMPRESS,	/* still frame conversion */
+	BUZ_MODE_STILL_DECOMPRESS	/* still frame conversion */
+};
+
+enum zoran_buffer_state {
+	BUZ_STATE_USER,		/* buffer is owned by application */
+	BUZ_STATE_PEND,		/* buffer is queued in pend[] ready to feed to I/O */
+	BUZ_STATE_DMA,		/* buffer is queued in dma[] for I/O */
+	BUZ_STATE_DONE		/* buffer is ready to return to application */
+};
+
+struct zoran_gbuffer {
+	u32 *frag_tab;		/* addresses of frag table */
+	u32 frag_tab_bus;	/* same value cached to save time in ISR */
+	enum zoran_buffer_state state;	/* non-zero if corresponding buffer is in use in grab queue */
+	struct zoran_sync bs;	/* DONE: info to return to application */
+};
+
+struct v4l_gbuffer {
+	char *fbuffer;		/* virtual  address of frame buffer */
+	unsigned long fbuffer_phys;	/* physical address of frame buffer */
+	unsigned long fbuffer_bus;	/* bus      address of frame buffer */
+	enum zoran_buffer_state state;	/* state: unused/pending/done */
+};
+
+struct zoran {
+	struct video_device video_dev;
+	struct i2c_bus i2c;
+
+	int initialized;	/* flag if zoran has been correctly initalized */
+	int user;		/* number of current users (0 or 1) */
+
+	unsigned short id;	/* number of this device */
+	char name[32];		/* name of this device */
+	struct pci_dev *pci_dev;	/* PCI device */
+	unsigned char revision;		/* revision of zr36057 */
+	int board;			/* Board type */
+#define BOARD_BUZ		0
+#define BOARD_LML33		1	
+	unsigned int zr36057_adr;	/* bus address of IO mem returned by PCI BIOS */
+	unsigned char *zr36057_mem;	/* pointer to mapped IO memory */
+
+	int map_mjpeg_buffers;	/* Flag which bufferset will map by next mmap() */
+
+	spinlock_t lock;	/* Spinlock */
+
+	/* Video for Linux parameters */
+
+	struct video_picture picture;	/* Current picture params */
+	struct video_buffer buffer;	/* Current buffer params */
+	struct video_window window;	/* Current window params */
+	int buffer_set, window_set;	/* Flags if the above structures are set */
+	int video_interlace;	/* Image on screen is interlaced */
+
+	u32 *overlay_mask;
+
+	wait_queue_head_t v4l_capq;	/* wait here for grab to finish */
+
+	int v4l_overlay_active;	/* Overlay grab is activated */
+	int v4l_memgrab_active;	/* Memory grab is activated */
+
+	int v4l_grab_frame;	/* Frame number being currently grabbed */
+#define NO_GRAB_ACTIVE (-1)
+	int v4l_grab_seq;	/* Number of frames grabbed */
+	int gwidth;		/* Width of current memory capture */
+	int gheight;		/* Height of current memory capture */
+	int gformat;		/* Format of ... */
+	int gbpl;		/* byte per line of ... */
+
+	/* V4L grab queue of frames pending */
+
+	unsigned v4l_pend_head;
+	unsigned v4l_pend_tail;
+	int v4l_pend[V4L_MAX_FRAME];
+
+	struct v4l_gbuffer v4l_gbuf[VIDEO_MAX_FRAME];	/* V4L   buffers' info */
+
+	/* Buz MJPEG parameters */
+
+	unsigned long jpg_nbufs;	/* Number of buffers */
+	unsigned long jpg_bufsize;	/* Size of mjpeg buffers in bytes */
+	int jpg_buffers_allocated;	/* Flag if buffers are allocated  */
+	int need_contiguous;	/* Flag if contiguous buffers are needed */
+
+	enum zoran_codec_mode codec_mode;		/* status of codec */
+	struct zoran_params params;	/* structure with a lot of things to play with */
+
+	wait_queue_head_t  jpg_capq;	/* wait here for grab to finish */
+
+	/* grab queue counts/indices, mask with BUZ_MASK_STAT_COM before using as index */
+	/* (dma_head - dma_tail) is number active in DMA, must be <= BUZ_NUM_STAT_COM */
+	/* (value & BUZ_MASK_STAT_COM) corresponds to index in stat_com table */
+	unsigned long jpg_que_head;	/* Index where to put next buffer which is queued */
+	unsigned long jpg_dma_head;	/* Index of next buffer which goes into stat_com  */
+	unsigned long jpg_dma_tail;	/* Index of last buffer in stat_com               */
+	unsigned long jpg_que_tail;	/* Index of last buffer in queue                  */
+	unsigned long jpg_seq_num;	/* count of frames since grab/play started */
+
+	/* zr36057's code buffer table */
+	u32 *stat_com;		/* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */
+
+	/* (value & BUZ_MASK_FRAME) corresponds to index in pend[] queue */
+	int jpg_pend[BUZ_MAX_FRAME];
+
+	/* array indexed by frame number */
+	struct zoran_gbuffer jpg_gbuf[BUZ_MAX_FRAME];	/* MJPEG buffers' info */
+};
+
+#endif
+
+/*The following should be done in more portable way. It depends on define
+   of _ALPHA_BUZ in the Makefile. */
+
+#ifdef _ALPHA_BUZ
+#define btwrite(dat,adr)    writel((dat),(char *) (zr->zr36057_adr+(adr)))
+#define btread(adr)         readl(zr->zr36057_adr+(adr))
+#else
+#define btwrite(dat,adr)    writel((dat), (char *) (zr->zr36057_mem+(adr)))
+#define btread(adr)         readl(zr->zr36057_mem+(adr))
+#endif
+
+#define btand(dat,adr)      btwrite((dat) & btread(adr), adr)
+#define btor(dat,adr)       btwrite((dat) | btread(adr), adr)
+#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
+
+#define I2C_TSA5522        0xc2
+#define I2C_TDA9850        0xb6
+#define I2C_HAUPEE         0xa0
+#define I2C_STBEE          0xae
+#define   I2C_SAA7111        0x48
+#define   I2C_SAA7185        0x88
+
+#define TDA9850_CON1       0x04
+#define TDA9850_CON2       0x05
+#define TDA9850_CON3       0x06
+#define TDA9850_CON4       0x07
+#define TDA9850_ALI1       0x08
+#define TDA9850_ALI2       0x09
+#define TDA9850_ALI3       0x0a
+
+#endif
diff -u --recursive --new-file v2.3.9/linux/drivers/char/bw-qcam.c linux/drivers/char/bw-qcam.c
--- v2.3.9/linux/drivers/char/bw-qcam.c	Fri Mar 26 13:57:41 1999
+++ linux/drivers/char/bw-qcam.c	Mon Jul  5 20:07:02 1999
@@ -159,6 +159,8 @@
X 	struct qcam_device *q;
X 	
X 	q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
+	if(q==NULL)
+		return NULL;
X 
X 	q->pport = port;
X 	q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
@@ -1045,7 +1047,7 @@
X 		close_bwqcam(qcams[i]);
X }
X #else
-__initfunc(int init_bw_qcams(struct video_init *unused))
+int __init init_bw_qcams(struct video_init *unused)
X {
X 	struct parport *port;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/char/c-qcam.c linux/drivers/char/c-qcam.c
--- v2.3.9/linux/drivers/char/c-qcam.c	Wed Dec 16 12:53:13 1998
+++ linux/drivers/char/c-qcam.c	Mon Jul  5 20:07:02 1999
@@ -1,6 +1,6 @@
X /*
X  *	Video4Linux Colour QuickCam driver
- *	Copyright 1997-1998 Philip Blundell <ph...@gnu.org>
+ *	Copyright 1997-1999 Philip Blundell <ph...@gnu.org>
X  *
X  */
X 
@@ -294,7 +294,7 @@
X 	if (is_bi_dir)
X 	{
X 		/* Turn the port around */
-		parport_frob_control(q->pport, 0x20, 0x20);
+		parport_data_reverse(q->pport);
X 		mdelay(3);
X 		qcam_set_ack(q, 0);
X 		if (qcam_await_ready1(q, 1)) {
@@ -336,7 +336,7 @@
X 	{
X 		printk("qcam: short read.\n");
X 		if (is_bi_dir)
-			parport_frob_control(q->pport, 0x20, 0);
+			parport_data_forward(q->pport);
X 		qc_setup(q);
X 		return len;
X 	}
@@ -355,11 +355,11 @@
X 		if (qcam_await_ready1(q, 1))
X 		{
X 			printk("qcam: no ack after EOF\n");
-			parport_frob_control(q->pport, 0x20, 0);
+			parport_data_forward(q->pport);
X 			qc_setup(q);
X 			return len;
X 		}
-		parport_frob_control(q->pport, 0x20, 0);
+		parport_data_forward(q->pport);
X 		mdelay(3);
X 		qcam_set_ack(q, 1);
X 		if (qcam_await_ready1(q, 0))
@@ -641,12 +641,14 @@
X 	struct qcam_device *q;
X 	
X 	q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
+	if(q==NULL)
+		return NULL;
X 
X 	q->pport = port;
X 	q->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
X 					  NULL, 0, NULL);
X 
-	q->bidirectional = (q->pport->modes & PARPORT_MODE_PCPS2)?1:0;
+	q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE)?1:0;
X 
X 	if (q->pdev == NULL) 
X 	{
@@ -678,10 +680,7 @@
X 	struct qcam_device *qcam;
X 
X 	if (num_cams == MAX_CAMS)
-	{
-		printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
X 		return -ENOSPC;
-	}
X 
X 	qcam = qcam_init(port);
X 	if (qcam==NULL)
@@ -725,19 +724,40 @@
X 	kfree(qcam);
X }
X 
-#define BANNER "Connectix Colour Quickcam driver v0.02\n"
+#define BANNER "Connectix Colour Quickcam driver v0.03"
X 
-#ifdef MODULE
-int init_module(void)
+static void cq_attach(struct parport *port)
+{
+	init_cqcam(port);
+}
+
+static void cq_detach(struct parport *port)
+{
+	/* Write this some day. */
+}
+
+static struct parport_driver cqcam_driver = {
+	"cqcam",
+	cq_attach,
+	cq_detach,
+	NULL
+};
+
+static void cqcam_init(void)
X {
-	struct parport *port;
+	printk(BANNER "\n");
+	parport_register_driver(&cqcam_driver);
+}
X 
-	printk(BANNER);
+#ifdef MODULE
X 
-	for (port = parport_enumerate(); port; port=port->next)
-		init_cqcam(port);
+MODULE_AUTHOR("Philip Blundell <ph...@gnu.org>");
+MODULE_DESCRIPTION(BANNER);
X 
-	return (num_cams)?0:-ENODEV;
+int init_module(void)
+{
+	cqcam_init();
+	return 0;
X }
X 
X void cleanup_module(void)
@@ -747,14 +767,9 @@
X 		close_cqcam(qcams[i]);
X }
X #else
-__initfunc(int init_colour_qcams(struct video_init *unused))
+int __init init_colour_qcams(struct video_init *unused)
X {
-	struct parport *port;
-
-	printk(BANNER);
-
-	for (port = parport_enumerate(); port; port=port->next)
-		init_cqcam(port);
+	cqcam_init();
X 	return 0;
X }
X #endif
diff -u --recursive --new-file v2.3.9/linux/drivers/char/chipsets.h linux/drivers/char/chipsets.h
--- v2.3.9/linux/drivers/char/chipsets.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/chipsets.h	Mon Jul  5 20:07:02 1999
@@ -0,0 +1,41 @@
+static const struct {
+	unsigned short vendor;
+	unsigned short device;
+	enum {
+		TRITON,
+		NATOMA
+	} action;
+	const char *name;
+} black[] = {
+
+	{
+		PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, TRITON, "82437"
+	},
+	{
+		PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX, TRITON, "82437VX Triton II"
+	},
+	{
+		PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439, TRITON, "82439HX Triton II"
+	},
+	{
+		PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, TRITON, "82439TX"
+	},
+	{
+		PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, NATOMA, "82441FX Natoma"
+	},
+	{
+		PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443LX_0, NATOMA, "440LX - 82443LX PAC Host"
+	},
+	{
+		PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443LX_1, NATOMA, "440LX - 82443LX PAC AGP"
+	},
+	{
+		PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_0, NATOMA, "440BX - 82443BX Host"
+	},
+	{
+		PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_1, NATOMA, "440BX - 82443BX AGP"
+	},
+	{
+		PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2, NATOMA, "440BX - 82443BX Host (no AGP)"
+	},
+};
diff -u --recursive --new-file v2.3.9/linux/drivers/char/console.c linux/drivers/char/console.c
--- v2.3.9/linux/drivers/char/console.c	Tue May 11 14:37:40 1999
+++ linux/drivers/char/console.c	Tue Jul  6 19:16:55 1999
@@ -2282,7 +2282,7 @@
X struct tty_driver console_driver;
X static int console_refcount;
X 
-__initfunc(unsigned long con_init(unsigned long kmem_start))
+unsigned long __init con_init(unsigned long kmem_start)
X {
X 	const char *display_desc = NULL;
X 	unsigned int currcons = 0;
diff -u --recursive --new-file v2.3.9/linux/drivers/char/consolemap.c linux/drivers/char/consolemap.c
--- v2.3.9/linux/drivers/char/consolemap.c	Tue Dec 29 14:28:37 1998
+++ linux/drivers/char/consolemap.c	Tue Jul  6 19:16:55 1999
@@ -671,8 +671,8 @@
X  * initialized.  It must be possible to call kmalloc(..., GFP_KERNEL)
X  * from this function, hence the call from sys_setup.
X  */
-__initfunc(void
-console_map_init(void))
+void __init 
+console_map_init(void)
X {
X 	int i;
X 	
diff -u --recursive --new-file v2.3.9/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
--- v2.3.9/linux/drivers/char/cyclades.c	Mon May 24 22:38:07 1999
+++ linux/drivers/char/cyclades.c	Tue Jul  6 19:05:48 1999
@@ -1,7 +1,7 @@
X #define BLOCKMOVE
X #define	Z_WAKE
X static char rcsid[] =
-"$Revision: 2.2.2.2 $$Date: 1999/05/21 17:18:15 $";
+"$Revision: 2.2.2.3 $$Date: 1999/06/28 11:13:29 $";
X 
X /*
X  *  linux/drivers/char/cyclades.c
@@ -31,6 +31,16 @@
X  *   void cleanup_module(void);
X  *
X  * $Log: cyclades.c,v $
+ * Revision 2.2.2.3   1999/06/28 11:13:29 ivan
+ * Added support for interrupt mode operation for the Z cards;
+ * Removed the driver inactivity control for the Z;
+ * Added a missing MOD_DEC_USE_COUNT in the cy_open function for when 
+ * the Z firmware is not loaded yet;
+ * Replaced the "manual" Z Tx flush buffer by a call to a FW command of 
+ * same functionality;
+ * Implemented workaround for IRQ setting loss on the PCI configuration 
+ * registers after a PCI bridge EEPROM reload (affects PLX9060 only);
+ *
X  * Revision 2.2.2.2  1999/05/14 17:18:15 ivan
X  * /proc entry location changed to /proc/tty/driver/cyclades;
X  * Added support to shared IRQ's (only for PCI boards);
@@ -528,7 +538,7 @@
X    constant in the definition below. No other change is necessary to
X    support more boards/ports. */
X 
-#define NR_PORTS        128
+#define NR_PORTS        256
X 
X #define ZE_V1_NPORTS	64
X #define ZO_V1	0
@@ -810,13 +820,15 @@
X #ifndef CONFIG_COBALT_27
X static void cy_probe(int, void *, struct pt_regs *);
X #endif /* CONFIG_COBALT_27 */
-static void cyz_poll(unsigned long);
X #ifdef CYCLOM_SHOW_STATUS
X static void show_status(int);
X #endif
X 
X static int cyclades_get_proc_info(char *, char **, off_t , int , int *, void *);
X 
+#ifndef CONFIG_CYZ_INTR
+static void cyz_poll(unsigned long);
+
X /* The Cyclades-Z polling cycle is defined by this variable */
X static long cyz_polling_cycle = CZ_DEF_POLL;
X 
@@ -825,6 +837,7 @@
X cyz_timerlist = {
X     NULL, NULL, 0, 0, cyz_poll
X };
+#endif /* CONFIG_CYZ_INTR */
X 
X /**************************************************
X error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long));
@@ -1197,7 +1210,7 @@
X 
X     if((cinfo = (struct cyclades_card *)dev_id) == 0){
X #ifdef CY_DEBUG_INTERRUPTS
-	printk("cy_interrupt: spurious interrupt %d\n\r", irq);
+	printk("cyy_interrupt: spurious interrupt %d\n\r", irq);
X #endif
X         return; /* spurious interrupt */
X     }
@@ -1229,7 +1242,7 @@
X                 }
X                 if (status & CySRReceive) { /* reception interrupt */
X #ifdef CY_DEBUG_INTERRUPTS
-		    printk("cy_interrupt: rcvd intr, chip %d\n\r", chip);
+		    printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip);
X #endif
X                     /* determine the channel & change to that context */
X                     save_xir = (u_char) cy_readb(base_addr+(CyRIR<<index));
@@ -1356,7 +1369,7 @@
X                        is empty, we know we can always stuff a dozen
X                        characters. */
X #ifdef CY_DEBUG_INTERRUPTS
-		    printk("cy_interrupt: xmit intr, chip %d\n\r", chip);
+		    printk("cyy_interrupt: xmit intr, chip %d\n\r", chip);
X #endif
X 
X                     /* determine the channel & change to that context */
@@ -1636,12 +1649,285 @@
X } /* cyz_update_channel */
X #endif
X 
-
+#ifdef CONFIG_CYZ_INTR
X static void
X cyz_interrupt(int irq, void *dev_id, struct pt_regs *regs)
X {
+  struct tty_struct *tty;
+  struct cyclades_card *cinfo;
+  struct cyclades_port *info;
+  static volatile struct FIRM_ID *firm_id;
+  static volatile struct ZFW_CTRL *zfw_ctrl;
+  static volatile struct BOARD_CTRL *board_ctrl;
+  static volatile struct CH_CTRL *ch_ctrl;
+  static volatile struct BUF_CTRL *buf_ctrl;
+  uclong channel;
+  ucchar cmd;
+  uclong param;
+  uclong hw_ver, fw_ver;
+  char data;
+  volatile int char_count, special_count;
+#ifdef BLOCKMOVE
+  int small_count;
+#endif
+  volatile uclong tx_put, tx_get, tx_bufsize;
+  volatile uclong rx_put, rx_get, rx_bufsize;
+
+    if((cinfo = (struct cyclades_card *)dev_id) == 0){
+#ifdef CY_DEBUG_INTERRUPTS
+	printk("cyz_interrupt: spurious interrupt %d\n\r", irq);
+#endif
+        return; /* spurious interrupt */
+    }
+
+	firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
+        if (!ISZLOADED(*cinfo)) {
+#ifdef CY_DEBUG_INTERRUPTS
+	    printk("cyz_interrupt: board not yet loaded (INT %d).\n\r", irq);
+#endif
+	    return;
+	}
+
+	zfw_ctrl = (struct ZFW_CTRL *)
+	           (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
+	board_ctrl = &(zfw_ctrl->board_ctrl);
+	fw_ver = cy_readl(&board_ctrl->fw_version);
+	hw_ver = cy_readl(&((struct RUNTIME_9060 *)
+                            (cinfo->ctl_addr))->mail_box_0);
+
+	while(cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1) {
+	    special_count = 0;
+	    info = &cy_port[channel + cinfo->first_line];
+            if((tty = info->tty) == 0) continue;
+	    ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
+	    buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
+
+	    switch(cmd){
+	    case C_CM_PR_ERROR:
+		tty->flip.count++;
+		*tty->flip.flag_buf_ptr++ = TTY_PARITY;
+		*tty->flip.char_buf_ptr++ = 0;
+		special_count++;
+	        break;
+	    case C_CM_FR_ERROR:
+		tty->flip.count++;
+		*tty->flip.flag_buf_ptr++ = TTY_FRAME;
+		*tty->flip.char_buf_ptr++ = 0;
+		special_count++;
+	        break;
+	    case C_CM_RXBRK:
+		tty->flip.count++;
+		*tty->flip.flag_buf_ptr++ = TTY_BREAK;
+		*tty->flip.char_buf_ptr++ = 0;
+		special_count++;
+	        break;
+	    case C_CM_MDCD:
+		if (info->flags & ASYNC_CHECK_CD){
+		    if ((fw_ver > 241 ? 
+                          ((u_long)param) : 
+                          cy_readl(&ch_ctrl[channel].rs_status)) & C_RS_DCD) {
+			/* SP("Open Wakeup\n"); */
+			cy_sched_event(info,
+			    Cy_EVENT_OPEN_WAKEUP);
+		    }else if(!((info->flags
+				& ASYNC_CALLOUT_ACTIVE)
+			 &&(info->flags
+			    & ASYNC_CALLOUT_NOHUP))){
+			/* SP("Hangup\n"); */
+			cy_sched_event(info,
+			    Cy_EVENT_HANGUP);
+		    }
+		}
+	        break;
+	    case C_CM_MCTS:
+		if (info->flags & ASYNC_CTS_FLOW) {
+		    if(info->tty->hw_stopped){
+			if( cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD){
+			    /* cy_start isn't used because... 
+			       HW flow is handled by the board */
+			    /* SP("Write Wakeup\n"); */
+			    cy_sched_event(info,
+				Cy_EVENT_WRITE_WAKEUP);
+			}
+		    }else{
+			if(!(cy_readl(&ch_ctrl[channel].rs_status) & C_RS_CTS)){
+			    /* cy_stop isn't used because 
+			       HW flow is handled by the board */
+			    /* SP("Write stop\n"); */
+			}
+		    }
+		}
+	        break;
+	    case C_CM_MRI:
+	        break;
+	    case C_CM_MDSR:
+	        break;
+#ifdef Z_WAKE
+	    case C_CM_IOCTLW:
+		cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP);
+	        break;
+#endif
+	    case C_CM_RXHIWM:
+	    case C_CM_RXNNDT:
+		/* Reception Interrupt */
+#ifdef CY_DEBUG_INTERRUPTS
+	    printk("cyz_interrupt: rcvd intr, card %d, port %ld\n\r", 
+		info->card, channel);
+#endif
+
+	    rx_get = cy_readl(&buf_ctrl->rx_get);
+	    rx_put = cy_readl(&buf_ctrl->rx_put);
+	    rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize);
+	    if (rx_put >= rx_get)
+	    	char_count = rx_put - rx_get;
+	    else
+	    	char_count = rx_put - rx_get + rx_bufsize;
+
+	    if ( char_count ){
+
+#ifdef CY_ENABLE_MONITORING
+		info->mon.int_count++;
+		info->mon.char_count += char_count;
+		if (char_count > info->mon.char_max)
+		   info->mon.char_max = char_count;
+		info->mon.char_last = char_count;
+#endif
+		info->idle_stats.recv_bytes += char_count;
+		info->idle_stats.recv_idle   = jiffies;
+		if( tty == 0){
+		    /* flush received characters */
+		    rx_get = (rx_get + char_count) & (rx_bufsize - 1);
+		    /* SP("-"); */
+		    info->rflush_count++;
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 09'
echo 'File patch-2.3.10 is continued in part 10'
echo 10 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 15 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
+	len += sprintf(buf+len, "FrameCopiedErrors   : " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[5]));
+	len += sprintf(buf+len, "FrequencyErrors     : " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[6]));
+	len += sprintf(buf+len, "InternalErrors      : " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[7]));
+	len += sprintf(buf+len, "LastRingStatus      : %s\n", ring_status[work64[8]]);
+	len += sprintf(buf+len, "TokenError          : " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[9]));
+	len += sprintf(buf+len, "UpstreamNodeAddress : " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[10]));
+	len += sprintf(buf+len, "LastRingID          : " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[11]));
+	len += sprintf(buf+len, "LastBeaconType      : " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[12]));
+
+	spin_unlock(&i2o_proc_lock);
+	return len;
+}
X 
X /* LAN group 0400h - Required FDDI Statistics (scalar) */
X int i2o_proc_read_lan_fddi_stats(char *buf, char **start, off_t offset,
@@ -2208,23 +2846,31 @@
X 		return len;
X 	}
X 
-	len += sprintf(buf, "ConfigurationState: %s\n", conf_state[work64[0]]);
-	len += sprintf(buf+len, "UpstreamNode: " FMT_U64_HEX "\n", U64_VAL(&work64[1]));
-	len += sprintf(buf+len, "DownStreamNode: " FMT_U64_HEX "\n", U64_VAL(&work64[2]));
-	len += sprintf(buf+len, "FrameErrors: " FMT_U64_HEX "\n", U64_VAL(&work64[3]));
-	len += sprintf(buf+len, "FramesLost: " FMT_U64_HEX "\n", U64_VAL(&work64[4]));
-	len += sprintf(buf+len, "RingMgmtState: %s\n", ring_state[work64[5]]);
-	len += sprintf(buf+len, "LCTFailures: " FMT_U64_HEX "\n", U64_VAL(&work64[6]));
-	len += sprintf(buf+len, "LEMRejects: " FMT_U64_HEX "\n", U64_VAL(&work64[7]));
-	len += sprintf(buf+len, "LEMCount: " FMT_U64_HEX "\n", U64_VAL(&work64[8]));
-	len += sprintf(buf+len, "LConnectionState: %s\n", link_state[work64[9]]);
+	len += sprintf(buf,     "ConfigurationState : %s\n", conf_state[work64[0]]);
+	len += sprintf(buf+len, "UpstreamNode       : " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[1]));
+	len += sprintf(buf+len, "DownStreamNode     : " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[2]));
+	len += sprintf(buf+len, "FrameErrors        : " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[3]));
+	len += sprintf(buf+len, "FramesLost         : " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[4]));
+	len += sprintf(buf+len, "RingMgmtState      : %s\n", ring_state[work64[5]]);
+	len += sprintf(buf+len, "LCTFailures: " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[6]));
+	len += sprintf(buf+len, "LEMRejects         : " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[7]));
+	len += sprintf(buf+len, "LEMCount           : " FMT_U64_HEX "\n",
+		       U64_VAL(&work64[8]));
+	len += sprintf(buf+len, "LConnectionState   : %s\n",
+		       link_state[work64[9]]);
X 
X 	spin_unlock(&i2o_proc_lock);
X 	return len;
X }
X 
-static int i2o_proc_create_entries(void *data,
-	i2o_proc_entry *pentry, struct proc_dir_entry *parent)
+static int i2o_proc_create_entries(void *data, i2o_proc_entry *pentry,
+				   struct proc_dir_entry *parent)
X {
X 	struct proc_dir_entry *ent;
X 	
@@ -2245,7 +2891,7 @@
X }
X 
X static void i2o_proc_remove_entries(i2o_proc_entry *pentry, 
-	struct proc_dir_entry *parent)
+				    struct proc_dir_entry *parent)
X {
X 	while(pentry->name != NULL)
X 	{
@@ -2255,7 +2901,7 @@
X }
X 
X static int i2o_proc_add_controller(struct i2o_controller *pctrl, 
-	struct proc_dir_entry *root )
+				   struct proc_dir_entry *root )
X {
X 	struct proc_dir_entry *dir, *dir1;
X 	struct i2o_device *dev;
@@ -2291,6 +2937,23 @@
X 			break;
X 		case I2O_CLASS_LAN:
X 			i2o_proc_create_entries(dev, lan_entries, dir1);
+			switch(dev->subclass)
+			{
+			case I2O_LAN_ETHERNET:
+				i2o_proc_create_entries(dev, lan_eth_entries,
+							dir1);
+				break;
+			case I2O_LAN_FDDI:
+				i2o_proc_create_entries(dev, lan_fddi_entries,
+							dir1);
+				break;
+			case I2O_LAN_TR:
+				i2o_proc_create_entries(dev, lan_tr_entries,
+							dir1);
+				break;
+			default:
+				break;
+			}
X 			break;
X 		default:
X 			break;
@@ -2301,17 +2964,58 @@
X }
X 
X static void i2o_proc_remove_controller(struct i2o_controller *pctrl, 
-	struct proc_dir_entry *parent)
+				       struct proc_dir_entry *parent)
X {
X 	char buff[10];
+	char dev_id[10];
+	struct proc_dir_entry *de;
+	struct i2o_device *dev;
X 
-	sprintf(buff, "iop%d", pctrl->unit);
+	/* Remove unused device entries */
+	for(dev=pctrl->devices; dev; dev=dev->next)
+	{
+		de=dev->proc_entry;
+		sprintf(dev_id, "%0#5x", dev->id);
X 
-	i2o_proc_remove_entries(generic_iop_entries, pctrl->proc_entry);
+		/* Would it be safe to remove _files_ even if they are in use? */
+		if((de) && (!de->count))
+		{
+			i2o_proc_remove_entries(generic_dev_entries, de);
X 
-	remove_proc_entry(buff, parent);
+			switch(dev->class)
+			{
+			case I2O_CLASS_SCSI_PERIPHERAL:
+			case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+				i2o_proc_remove_entries(rbs_dev_entries, de);
+				break;
+			case I2O_CLASS_LAN:
+				i2o_proc_remove_entries(lan_entries, de);
+				switch(dev->subclass)
+				{
+				case I2O_LAN_ETHERNET:
+					i2o_proc_remove_entries(lan_eth_entries, de);
+					break;
+				case I2O_LAN_FDDI:
+					i2o_proc_remove_entries(lan_fddi_entries, de);
+					break;
+				case I2O_LAN_TR:
+					i2o_proc_remove_entries(lan_tr_entries, de);
+					break;
+				}
+			}
+			remove_proc_entry(dev_id, parent);
+		}
+	}
X 
-	pctrl->proc_entry = NULL;
+	if(!pctrl->proc_entry->count)
+	{
+		sprintf(buff, "iop%d", pctrl->unit);
+
+		i2o_proc_remove_entries(generic_iop_entries, pctrl->proc_entry);
+
+		remove_proc_entry(buff, parent);
+		pctrl->proc_entry = NULL;
+	}
X }
X 
X static int create_i2o_procfs(void)
@@ -2327,7 +3031,10 @@
X 	{
X 		pctrl = i2o_find_controller(i);
X 		if(pctrl)
+		{
X 			i2o_proc_add_controller(pctrl, i2o_proc_dir_root);
+			i2o_unlock_controller(pctrl);
+		}
X 	};
X 
X 	return 0;
@@ -2345,19 +3052,25 @@
X 	{
X 		pctrl = i2o_find_controller(i);
X 		if(pctrl)
+		{
X 			i2o_proc_remove_controller(pctrl, i2o_proc_dir_root);
+			i2o_unlock_controller(pctrl);
+		}
X 	};
X 
-	remove_proc_entry("i2o", 0);
+	if(!i2o_proc_dir_root->count)
+		remove_proc_entry("i2o", 0);
+	else
+		return -1;
+
X 	return 0;
X }
X 		
X #ifdef MODULE
+#define i2o_proc_init init_module
+#endif
X 
-MODULE_AUTHOR("Intel Corporation");
-MODULE_DESCRIPTION("I2O procfs Handler");
-
-int init_module(void)
+__init int i2o_proc_init(void)
X {
X 	if(create_i2o_procfs())
X 		return -EBUSY;
@@ -2372,6 +3085,12 @@
X 
X 	return 0;
X }
+
+#ifdef MODULE
+
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("I2O procfs Handler");
X 
X void cleanup_module(void)
X {
diff -u --recursive --new-file v2.3.9/linux/drivers/i2o/i2o_proc.h linux/drivers/i2o/i2o_proc.h
--- v2.3.9/linux/drivers/i2o/i2o_proc.h	Wed Jun  2 14:40:22 1999
+++ linux/drivers/i2o/i2o_proc.h	Mon Jul  5 20:09:40 1999
@@ -32,110 +32,5 @@
X 	u8 reserved;
X 	u8 req_status;
X } i2o_mult_reply_msg, *pi2o_mult_reply_msg;
-
-/**************************************************************************
- * HRT related constants and structures
- **************************************************************************/
-#define    I2O_BUS_LOCAL                               0
-#define    I2O_BUS_ISA                                 1
-#define    I2O_BUS_EISA                                2
-#define    I2O_BUS_MCA                                 3
-#define    I2O_BUS_PCI                                 4
-#define    I2O_BUS_PCMCIA                              5
-#define    I2O_BUS_NUBUS                               6
-#define    I2O_BUS_CARDBUS                             7
-#define    I2O_BUS_UNKNOWN                            0x80
-
-typedef struct _i2o_pci_bus {
-	u8 PciFunctionNumber;
-	u8 PciDeviceNumber;
-	u8 PciBusNumber;
-	u8 reserved;
-	u16 PciVendorID;
-	u16 PciDeviceID;
-} i2o_pci_bus, *pi2o_pci_bus;
-
-typedef struct _i2o_local_bus {
-	u16 LbBaseIOPort;
-	u16 reserved;
-	u32 LbBaseMemoryAddress;
-} i2o_local_bus, *pi2o_local_bus;
-
-typedef struct _i2o_isa_bus {
-	u16 IsaBaseIOPort;
-	u8 CSN;
-	u8 reserved;
-	u32 IsaBaseMemoryAddress;
-} i2o_isa_bus, *pi2o_isa_bus;
-
-/* I2O_EISA_BUS_INFO  */
-typedef struct _i2o_eisa_bus_info {
-	u16 EisaBaseIOPort;
-	u8 reserved;
-	u8 EisaSlotNumber;
-	u32 EisaBaseMemoryAddress;
-} i2o_eisa_bus, *pi2o_eisa_bus;
-
-typedef struct _i2o_mca_bus {
-	u16 McaBaseIOPort;
-	u8 reserved;
-	u8 McaSlotNumber;
-	u32 McaBaseMemoryAddress;
-} i2o_mca_bus, *pi2o_mca_bus;
-
-typedef struct _i2o_other_bus {
-	u16 BaseIOPort;
-	u16 reserved;
-	u32 BaseMemoryAddress;
-} i2o_other_bus, *pi2o_other_bus;
-
-
-typedef struct _i2o_hrt_entry {
-	u32 adapter_id;
-	u32 parent_tid:12;
-	u32 state:4;
-	u32 bus_num:8;
-	u32 bus_type:8;
-	union {
-		i2o_pci_bus pci_bus;
-		i2o_local_bus local_bus;
-		i2o_isa_bus isa_bus;
-		i2o_eisa_bus eisa_bus;
-		i2o_mca_bus mca_bus;
-		i2o_other_bus other_bus;
-	} bus;
-} i2o_hrt_entry, *pi2o_hrt_entry;
-
-typedef struct _i2o_hrt {
-	u16 num_entries;
-	u8 entry_len;
-	u8 hrt_version;
-	u32 change_ind;
-	i2o_hrt_entry hrt_entry[1];
-} i2o_hrt, *pi2o_hrt;
-
-typedef struct _i2o_lct_entry {
-	u32 entry_size:16;
-	u32 tid:12;
-	u32 reserved:4;
-	u32 change_ind;
-	u32 device_flags;
-	u32 class_id;
-	u32 sub_class;
-	u32 user_tid:12;
-	u32 parent_tid:12;
-	u32 bios_info:8;
-	u8 identity_tag[8];
-	u32 event_capabilities;
-} i2o_lct_entry, *pi2o_lct_entry;
-
-typedef struct _i2o_lct {
-	u32 table_size:16;
-	u32 boot_tid:12;
-	u32 lct_ver:4;
-	u32 iop_flags;
-	u32 current_change_ind;
-	i2o_lct_entry lct_entry[1];
-} i2o_lct, *pi2o_lct;
-
+   
X #endif				/* i2oproc_h */
diff -u --recursive --new-file v2.3.9/linux/drivers/i2o/i2o_scsi.c linux/drivers/i2o/i2o_scsi.c
--- v2.3.9/linux/drivers/i2o/i2o_scsi.c	Wed Jun  2 14:40:22 1999
+++ linux/drivers/i2o/i2o_scsi.c	Mon Jul  5 20:35:18 1999
@@ -26,6 +26,9 @@
X  *	Fixes:
X  *		Steve Ralston	:	Scatter gather now works
X  *
+ *	To Do
+ *		64bit cleanups
+ *		Fix the resource management problems.
X  */
X 
X #include <linux/module.h>
@@ -37,7 +40,6 @@
X #include <linux/interrupt.h>
X #include <linux/timer.h>
X #include <linux/delay.h>
-#include <linux/sched.h>
X #include <linux/proc_fs.h>
X #include <asm/dma.h>
X #include <asm/system.h>
@@ -83,6 +85,7 @@
X /*
X  *	SG Chain buffer support...
X  */
+
X #define SG_MAX_FRAGS		64
X 
X /*
@@ -204,9 +207,12 @@
X 	}
X 			
X 	
-	/* Low byte is the adapter status, next is the device */
-	as=(u8)m[4]; 
-	ds=(u8)(m[4]>>8);
+	/*
+	 *	Low byte is device status, next is adapter status,
+	 *	(then one byte reserved), then request status.
+	 */
+	ds=(u8)m[4]; 
+	as=(u8)(m[4]>>8);
X 	st=(u8)(m[4]>>24);
X 	
X 	dprintk(("i2o got a scsi reply %08X: ", m[0]));
@@ -264,10 +270,10 @@
X 
X 		dprintk((KERN_DEBUG "SCSI error %08X", m[4]));
X 			
-		if (ds == 0x0E) 
+		if (as == 0x0E) 
X 			/* SCSI Reset */
X 			current_command->result = DID_RESET << 16;
-		else if (ds == 0x0F)
+		else if (as == 0x0F)
X 			current_command->result = DID_PARITY << 16;
X 		else
X 			current_command->result = DID_ERROR << 16;
@@ -433,7 +439,6 @@
X 			  )
X 				continue;
X 		
-//			printk("Found a controller.\n");	
X 			shpnt = scsi_register(tpnt, sizeof(struct i2o_scsi_host));
X 			save_flags(flags);
X 			cli();
@@ -443,7 +448,6 @@
X 			shpnt->irq = 0;
X 			shpnt->this_id = /* Good question */15;
X 			restore_flags(flags);
-//			printk("Scanning I2O port %d.\n", d->id);
X 			i2o_scsi_init(c, d, shpnt);
X 			count++;
X 		}
@@ -534,25 +538,12 @@
X 	int direction;
X 	int scsidir;
X 	u32 len;
+	u32 reqlen;
+	u32 tag;
X 	
X 	static int max_qd = 1;
X 	
X 	/*
-	 *	The scsi layer should be handling this stuff
-	 */
-
-	if(is_dir_out(SCpnt))
-	{
-		direction=0x04000000;
-		scsidir=0x80000000;
-	}
-	else
-	{
-		scsidir=0x40000000;
-		direction=0x00000000;
-	}
-	
-	/*
X 	 *	Do the incoming paperwork
X 	 */
X 	 
@@ -604,13 +595,45 @@
X 	 *	Put together a scsi execscb message
X 	 */
X 	
+	len = SCpnt->request_bufflen;
+	direction = 0x00000000;			// SGL IN  (osm<--iop)
+	
+	/*
+	 *	The scsi layer should be handling this stuff
+	 */
+	
+	scsidir = 0x00000000;			// DATA NO XFER
+	if(len)
+	{
+		if(is_dir_out(SCpnt))
+		{
+			direction=0x04000000;	// SGL OUT  (osm-->iop)
+			scsidir  =0x80000000;	// DATA OUT (iop-->dev)
+		}
+		else
+		{
+			scsidir  =0x40000000;	// DATA IN  (iop<--dev)
+		}
+	}
+	
X 	msg[1] = I2O_CMD_SCSI_EXEC<<24|HOST_TID<<12|tid;
X 	msg[2] = scsi_context;		/* So the I2O layer passes to us */
X 	/* Sorry 64bit folks. FIXME */
X 	msg[3] = (u32)SCpnt;		/* We want the SCSI control block back */
-	/* Direction, disconnect ok, no tagging (yet) */
-	msg[4] = scsidir|(1<<29)|SCpnt->cmd_len;
X 
+	/* LSI_920_PCI_QUIRK
+	 *
+	 *	Intermittant observations of msg frame word data corruption
+	 *	observed on msg[4] after:
+	 *	  WRITE, READ-MODIFY-WRITE
+	 *	operations.  19990606 -sralston
+	 *
+	 *	(Hence we build this word via tag. Its good practice anyway
+	 *	 we don't want fetches over PCI needlessly)
+	 */
+
+	tag=0;
+	
X 	/*
X 	 *	Attach tags to the devices
X 	 */	
@@ -623,25 +646,24 @@
X 		 */
X 		if((jiffies - hostdata->tagclock[SCpnt->target][SCpnt->lun]) > (5*HZ))
X 		{
-			msg[4]|=(1<<23)|(1<<24);
+			tag=0x01800000;		/* ORDERED! */
X 			hostdata->tagclock[SCpnt->target][SCpnt->lun]=jiffies;
X 		}
-		else switch(SCpnt->tag)
+		else
X 		{
-			case SIMPLE_QUEUE_TAG:
-				msg[4]|=(1<<23);
-				break;
-			case HEAD_OF_QUEUE_TAG:
-				msg[4]|=(1<<24);
-				break;
-			case ORDERED_QUEUE_TAG:
-				msg[4]|=(1<<23)|(1<<24);
-				break;
-			default:
-				msg[4]|=(1<<23);
+			/* Hmmm...  I always see value of 0 here,
+			 *  of which {HEAD_OF, ORDERED, SIMPLE} are NOT!  -sralston
+			 */
+			if(SCpnt->tag == HEAD_OF_QUEUE_TAG)
+				tag=0x01000000;
+			else if(SCpnt->tag == ORDERED_QUEUE_TAG)
+				tag=0x01800000;
X 		}
X 	}
X 
+	/* Direction, disconnect ok, tag, CDBLen */
+	msg[4] = scsidir|0x20000000|SCpnt->cmd_len|tag;
+
X 	mptr=msg+5;
X 
X 	/* 
@@ -652,7 +674,7 @@
X 	mptr+=4;
X 	lenptr=mptr++;		/* Remember me - fill in when we know */
X 	
-			
+	reqlen = 12;		// SINGLE SGE
X 	/*
X 	 *	Now fill in the SGList and command 
X 	 *
@@ -664,21 +686,22 @@
X 	if(SCpnt->use_sg)
X 	{
X 		struct scatterlist *sg = (struct scatterlist *)SCpnt->request_buffer;
+		int chain = 0;
X 		
X 		if((sg_max_frags > 11) && (SCpnt->use_sg > 11))
X 		{
+			chain = 1;
X 			/*
X 			 *	Need to chain!
X 			 */
-			SCpnt->host_scribble = (void*)(sg_chain_pool + sg_chain_tag);
X 			*mptr++=direction|0xB0000000|(SCpnt->use_sg*2*4);
-			*mptr=virt_to_bus(SCpnt->host_scribble);
-			mptr = (u32*)SCpnt->host_scribble;
+			*mptr=virt_to_bus(sg_chain_pool + sg_chain_tag);
+			mptr = (u32*)(sg_chain_pool + sg_chain_tag);
X 			if (SCpnt->use_sg > max_sg_len)
X 			{
X 				max_sg_len = SCpnt->use_sg;
X 				printk("i2o_scsi: Chain SG! SCpnt=%p, SG_FragCnt=%d, SG_idx=%d\n",
-					SCpnt, SCpnt->use_sg, (chain_buf*)SCpnt->host_scribble-sg_chain_pool);
+					SCpnt, SCpnt->use_sg, sg_chain_tag);
X 			}
X 			if ( ++sg_chain_tag == SG_MAX_BUFS )
X 				sg_chain_tag = 0;
@@ -693,7 +716,15 @@
X 			*mptr++=virt_to_bus(sg->address);
X 			sg++;
X 		}
-		mptr[-2]|=0xC0000000;	/* End of List and block */
+
+		/* Make this an end of list. Again evade the 920 bug and
+		   unwanted PCI read traffic */
+		
+		mptr[-2]=direction|0xD0000000|(sg-1)->length;
+		
+		if(!chain)
+			reqlen = mptr - msg;
+		
X 		*lenptr=len;
X 		if(len != SCpnt->underflow)
X 			printk("Cmd len %08X Cmd underflow %08X\n",
@@ -703,19 +734,23 @@
X 	{
X 		dprintk(("non sg for %p, %d\n", SCpnt->request_buffer,
X 				SCpnt->request_bufflen));
-		*mptr++=0xD0000000|direction|SCpnt->request_bufflen;
-		*mptr++=virt_to_bus(SCpnt->request_buffer);
X 		*lenptr = len = SCpnt->request_bufflen;
-		/* No transfer ? - fix up the request */
X 		if(len == 0)
-			msg[4]&=~0xC0000000;
+		{
+			reqlen = 9;
+		}
+		else
+		{
+			*mptr++=0xD0000000|direction|SCpnt->request_bufflen;
+			*mptr++=virt_to_bus(SCpnt->request_buffer);
+		}
X 	}
X 	
X 	/*
X 	 *	Stick the headers on 
X 	 */
X 
-	msg[0] = (mptr-msg)<<16 | SGL_OFFSET_10;
+	msg[0] = reqlen<<16 | SGL_OFFSET_10;
X 	
X 	/* Queue the message */
X 	i2o_post_message(c,m);
@@ -757,7 +792,7 @@
X 	u32 m;
X 	int tid;
X 	
-	printk("i2o_scsi_abort\n");
+	printk("i2o_scsi: Aborting command block.\n");
X 	
X 	host = SCpnt->host;
X 	hostdata = (struct i2o_scsi_host *)host->hostdata;
@@ -790,8 +825,6 @@
X 	wmb();
X 	i2o_post_message(c,m);
X 	wmb();
-//	SCpnt->result = DID_RESET << 16;
-//	SCpnt->scsi_done(SCpnt);
X 	return SCSI_ABORT_PENDING;
X }
X 
@@ -804,12 +837,12 @@
X 	u32 m;
X 	u32 *msg;
X 
-	printk("i2o_scsi_reset\n");
-	
X 	/*
X 	 *	Find the TID for the bus
X 	 */
X 
+	printk("i2o_scsi: Attempting to reset the bus.\n");
+	
X 	host = SCpnt->host;
X 	hostdata = (struct i2o_scsi_host *)host->hostdata;
X 	tid = hostdata->bus_task;
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/avmb1/capidrv.c linux/drivers/isdn/avmb1/capidrv.c
--- v2.3.9/linux/drivers/isdn/avmb1/capidrv.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/avmb1/capidrv.c	Mon Jul  5 20:09:40 1999
@@ -1386,13 +1386,14 @@
X 			handle_data(&s_cmsg, skb);
X 			continue;
X 		}
-		kfree_skb(skb);
X 		if ((s_cmsg.adr.adrController & 0xffffff00) == 0)
X 			handle_controller(&s_cmsg);
X 		else if ((s_cmsg.adr.adrPLCI & 0xffff0000) == 0)
X 			handle_plci(&s_cmsg);
X 		else
X 			handle_ncci(&s_cmsg);
+
+		kfree_skb(skb);
X 	}
X }
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/amd7930.c linux/drivers/isdn/hisax/amd7930.c
--- v2.3.9/linux/drivers/isdn/hisax/amd7930.c	Wed Apr  1 16:20:57 1998
+++ linux/drivers/isdn/hisax/amd7930.c	Tue Jul  6 19:05:48 1999
@@ -747,8 +747,8 @@
X 	return(0);
X }
X 
-__initfunc(int
-setup_amd7930(struct IsdnCard *card))
+int __init 
+setup_amd7930(struct IsdnCard *card)
X {
X 	struct IsdnCardState *cs = card->cs;
X 	char tmp[64];
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/asuscom.c linux/drivers/isdn/hisax/asuscom.c
--- v2.3.9/linux/drivers/isdn/hisax/asuscom.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/asuscom.c	Tue Jul  6 19:05:48 1999
@@ -334,8 +334,8 @@
X 	return(0);
X }
X 
-__initfunc(int
-setup_asuscom(struct IsdnCard *card))
+int __init 
+setup_asuscom(struct IsdnCard *card)
X {
X 	int bytecnt;
X 	struct IsdnCardState *cs = card->cs;
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/avm_a1.c linux/drivers/isdn/hisax/avm_a1.c
--- v2.3.9/linux/drivers/isdn/hisax/avm_a1.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/avm_a1.c	Tue Jul  6 19:05:48 1999
@@ -234,8 +234,8 @@
X 	return(0);
X }
X 
-__initfunc(int
-setup_avm_a1(struct IsdnCard *card))
+int __init 
+setup_avm_a1(struct IsdnCard *card)
X {
X 	u_char val;
X 	struct IsdnCardState *cs = card->cs;
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c
--- v2.3.9/linux/drivers/isdn/hisax/config.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/config.c	Tue Jul  6 19:05:48 1999
@@ -442,8 +442,8 @@
X #ifdef MODULE
X #define HiSax_init init_module
X #else
-__initfunc(void
-HiSax_setup(char *str, int *ints))
+void __init 
+HiSax_setup(char *str, int *ints)
X {
X 	int i, j, argc;
X 
@@ -1236,8 +1236,8 @@
X }
X 
X 
-__initfunc(int
-HiSax_init(void))
+int __init 
+HiSax_init(void)
X {
X 	int i;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/diva.c linux/drivers/isdn/hisax/diva.c
--- v2.3.9/linux/drivers/isdn/hisax/diva.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/diva.c	Tue Jul  6 19:05:48 1999
@@ -459,8 +459,8 @@
X static 	struct pci_dev *dev_diva __initdata = NULL;
X static 	struct pci_dev *dev_diva_u __initdata = NULL;
X 
-__initfunc(int
-setup_diva(struct IsdnCard *card))
+int __init 
+setup_diva(struct IsdnCard *card)
X {
X 	int bytecnt;
X 	u_char val;
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/foreign.c linux/drivers/isdn/hisax/foreign.c
--- v2.3.9/linux/drivers/isdn/hisax/foreign.c	Mon Mar 15 16:11:30 1999
+++ linux/drivers/isdn/hisax/foreign.c	Tue Jul  6 19:05:48 1999
@@ -744,8 +744,8 @@
X extern struct foreign_interface dbri_foreign_interface;
X #endif
X 
-__initfunc(int
-setup_foreign(struct IsdnCard *card))
+int __init 
+setup_foreign(struct IsdnCard *card)
X {
X 	struct IsdnCardState *cs = card->cs;
X 	char tmp[64];
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/hfc_2bds0.c linux/drivers/isdn/hisax/hfc_2bds0.c
--- v2.3.9/linux/drivers/isdn/hisax/hfc_2bds0.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/hfc_2bds0.c	Tue Jul  6 19:05:48 1999
@@ -1166,8 +1166,8 @@
X #endif
X }
X 
-__initfunc(unsigned int
-*init_send_hfcd(int cnt))
+unsigned int __init 
+*init_send_hfcd(int cnt)
X {
X 	int i, *send;
X 
@@ -1181,8 +1181,8 @@
X 	return(send);
X }
X 
-__initfunc(void
-init2bds0(struct IsdnCardState *cs))
+void __init 
+init2bds0(struct IsdnCardState *cs)
X {
X 	cs->setstack_d = setstack_hfcd;
X 	cs->dbusytimer.function = (void *) hfc_dbusy_timer;
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/hfc_2bs0.c linux/drivers/isdn/hisax/hfc_2bs0.c
--- v2.3.9/linux/drivers/isdn/hisax/hfc_2bs0.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/hfc_2bs0.c	Tue Jul  6 19:05:48 1999
@@ -555,8 +555,8 @@
X 	return (0);
X }
X 
-__initfunc(void
-init_send(struct BCState *bcs))
+void __init 
+init_send(struct BCState *bcs)
X {
X 	int i;
X 
@@ -569,8 +569,8 @@
X 		bcs->hw.hfc.send[i] = 0x1fff;
X }
X 
-__initfunc(void
-inithfc(struct IsdnCardState *cs))
+void __init 
+inithfc(struct IsdnCardState *cs)
X {
X 	init_send(&cs->bcs[0]);
X 	init_send(&cs->bcs[1]);
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/ix1_micro.c linux/drivers/isdn/hisax/ix1_micro.c
--- v2.3.9/linux/drivers/isdn/hisax/ix1_micro.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/ix1_micro.c	Tue Jul  6 19:05:48 1999
@@ -289,8 +289,8 @@
X }
X 
X 
-__initfunc(int
-setup_ix1micro(struct IsdnCard *card))
+int __init 
+setup_ix1micro(struct IsdnCard *card)
X {
X 	struct IsdnCardState *cs = card->cs;
X 	char tmp[64];
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/mic.c linux/drivers/isdn/hisax/mic.c
--- v2.3.9/linux/drivers/isdn/hisax/mic.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/mic.c	Tue Jul  6 19:05:48 1999
@@ -231,8 +231,8 @@
X 	return(0);
X }
X 
-__initfunc(int
-setup_mic(struct IsdnCard *card))
+int __init 
+setup_mic(struct IsdnCard *card)
X {
X 	int bytecnt;
X 	struct IsdnCardState *cs = card->cs;
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/netjet.c linux/drivers/isdn/hisax/netjet.c
--- v2.3.9/linux/drivers/isdn/hisax/netjet.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/netjet.c	Tue Jul  6 19:05:48 1999
@@ -858,8 +858,8 @@
X }
X 
X  
-__initfunc(void
-inittiger(struct IsdnCardState *cs))
+void __init 
+inittiger(struct IsdnCardState *cs)
X {
X 	if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_SIZE * sizeof(unsigned int),
X 		GFP_KERNEL | GFP_DMA))) {
@@ -1050,8 +1050,8 @@
X 
X static 	struct pci_dev *dev_netjet __initdata = NULL;
X 
-__initfunc(int
-setup_netjet(struct IsdnCard *card))
+int __init 
+setup_netjet(struct IsdnCard *card)
X {
X 	int bytecnt;
X 	struct IsdnCardState *cs = card->cs;
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/niccy.c linux/drivers/isdn/hisax/niccy.c
--- v2.3.9/linux/drivers/isdn/hisax/niccy.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/niccy.c	Tue Jul  6 19:05:48 1999
@@ -263,8 +263,8 @@
X 
X static 	struct pci_dev *niccy_dev __initdata = NULL;
X 
-__initfunc(int
-setup_niccy(struct IsdnCard *card))
+int __init 
+setup_niccy(struct IsdnCard *card)
X {
X 	struct IsdnCardState *cs = card->cs;
X 	char tmp[64];
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/sedlbauer.c linux/drivers/isdn/hisax/sedlbauer.c
--- v2.3.9/linux/drivers/isdn/hisax/sedlbauer.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/sedlbauer.c	Tue Jul  6 19:05:48 1999
@@ -533,8 +533,8 @@
X static  int pci_index __initdata = 0;
X #endif
X 
-__initfunc(int
-setup_sedlbauer(struct IsdnCard *card))
+int __init 
+setup_sedlbauer(struct IsdnCard *card)
X {
X 	int bytecnt, ver, val;
X 	struct IsdnCardState *cs = card->cs;
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/sportster.c linux/drivers/isdn/hisax/sportster.c
--- v2.3.9/linux/drivers/isdn/hisax/sportster.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/sportster.c	Tue Jul  6 19:05:48 1999
@@ -204,8 +204,8 @@
X 	return(0);
X }
X 
-__initfunc(int
-get_io_range(struct IsdnCardState *cs))
+int __init 
+get_io_range(struct IsdnCardState *cs)
X {
X 	int i, j, adr;
X 	
@@ -230,8 +230,8 @@
X 	}
X }
X 
-__initfunc(int
-setup_sportster(struct IsdnCard *card))
+int __init 
+setup_sportster(struct IsdnCard *card)
X {
X 	struct IsdnCardState *cs = card->cs;
X 	char tmp[64];
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/teleint.c linux/drivers/isdn/hisax/teleint.c
--- v2.3.9/linux/drivers/isdn/hisax/teleint.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/teleint.c	Tue Jul  6 19:05:49 1999
@@ -289,8 +289,8 @@
X 	return(0);
X }
X 
-__initfunc(int
-setup_TeleInt(struct IsdnCard *card))
+int __init 
+setup_TeleInt(struct IsdnCard *card)
X {
X 	struct IsdnCardState *cs = card->cs;
X 	char tmp[64];
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/teles0.c linux/drivers/isdn/hisax/teles0.c
--- v2.3.9/linux/drivers/isdn/hisax/teles0.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/teles0.c	Tue Jul  6 19:05:49 1999
@@ -302,8 +302,8 @@
X 	return(0);
X }
X 
-__initfunc(int
-setup_teles0(struct IsdnCard *card))
+int __init 
+setup_teles0(struct IsdnCard *card)
X {
X 	u_char val;
X 	struct IsdnCardState *cs = card->cs;
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/teles3.c linux/drivers/isdn/hisax/teles3.c
--- v2.3.9/linux/drivers/isdn/hisax/teles3.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/teles3.c	Tue Jul  6 19:05:49 1999
@@ -321,8 +321,8 @@
X 	return(0);
X }
X 
-__initfunc(int
-setup_teles3(struct IsdnCard *card))
+int __init 
+setup_teles3(struct IsdnCard *card)
X {
X 	u_char val;
X 	struct IsdnCardState *cs = card->cs;
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/hisax/teles3c.c linux/drivers/isdn/hisax/teles3c.c
--- v2.3.9/linux/drivers/isdn/hisax/teles3c.c	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/hisax/teles3c.c	Tue Jul  6 19:05:49 1999
@@ -140,8 +140,8 @@
X 	return(0);
X }
X 
-__initfunc(int
-setup_t163c(struct IsdnCard *card))
+int __init 
+setup_t163c(struct IsdnCard *card)
X {
X 	struct IsdnCardState *cs = card->cs;
X 	char tmp[64];
diff -u --recursive --new-file v2.3.9/linux/drivers/isdn/isdn_bsdcomp.c linux/drivers/isdn/isdn_bsdcomp.c
--- v2.3.9/linux/drivers/isdn/isdn_bsdcomp.c	Sun May 23 10:03:42 1999
+++ linux/drivers/isdn/isdn_bsdcomp.c	Mon Jul  5 20:35:18 1999
@@ -64,7 +64,6 @@
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 
diff -u --recursive --new-file v2.3.9/linux/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c
--- v2.3.9/linux/drivers/macintosh/macserial.c	Mon Jun  7 12:12:32 1999
+++ linux/drivers/macintosh/macserial.c	Thu Jul  1 15:09:01 1999
@@ -1558,7 +1558,6 @@
X 		char_time = MIN(char_time, timeout);
X 	while ((read_zsreg(info->zs_channel, 1) & ALL_SNT) == 0) {
X 		current->state = TASK_INTERRUPTIBLE;
-		current->counter = 0;	/* make us low-priority */
X 		schedule_timeout(char_time);
X 		if (signal_pending(current))
X 			break;
diff -u --recursive --new-file v2.3.9/linux/drivers/misc/Config.in linux/drivers/misc/Config.in
--- v2.3.9/linux/drivers/misc/Config.in	Wed Dec 31 16:00:00 1969
+++ linux/drivers/misc/Config.in	Thu Jul  1 14:22:57 1999
@@ -0,0 +1,37 @@
+#
+# For a description of the syntax of this configuration file,
+# see the Configure script.
+#
+# Parport configuration.
+#
+
+tristate 'Parallel port support' CONFIG_PARPORT
+if [ "$CONFIG_PARPORT" != "n" ]; then
+  dep_tristate '   PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
+  if [ "$CONFIG_PARPORT_PC" != "n" ]; then
+    bool '   Use FIFO/DMA if available' CONFIG_PARPORT_PC_FIFO
+  fi
+  if [ "$CONFIG_ARM" = "y" ]; then
+    dep_tristate '   Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT
+  fi
+  if [ "$CONFIG_AMIGA" = "y" ]; then
+    dep_tristate '   Amiga builtin port' CONFIG_PARPORT_AMIGA $CONFIG_PARPORT
+    if [ "$CONFIG_ZORRO" != "n" ]; then
+      dep_tristate '   Multiface III parallel port' CONFIG_PARPORT_MFC3 $CONFIG_PARPORT
+    fi
+  else
+    define_bool CONFIG_PARPORT_AMIGA n
+    define_bool CONFIG_PARPORT_MFC3 n
+  fi
+  if [ "$CONFIG_ATARI" = "y" ]; then
+    dep_tristate '   Atari hardware' CONFIG_PARPORT_ATARI $CONFIG_PARPORT
+  else
+    define_bool CONFIG_PARPORT_ATARI n
+  fi
+
+  # If exactly one hardware type is selected then parport will optimise away
+  # support for loading any others.  Defeat this if the user is keen.
+  bool '   Support foreign hardware' CONFIG_PARPORT_OTHER
+
+  bool '   IEEE 1284 transfer modes' CONFIG_PARPORT_1284
+fi
diff -u --recursive --new-file v2.3.9/linux/drivers/misc/Makefile linux/drivers/misc/Makefile
--- v2.3.9/linux/drivers/misc/Makefile	Thu Jun  3 16:21:47 1999
+++ linux/drivers/misc/Makefile	Thu Jul  1 14:22:57 1999
@@ -23,7 +23,13 @@
X MIX_OBJS :=
X 
X ifeq ($(CONFIG_PARPORT),y)
-  L_OBJS += parport_share.o parport_ieee1284.o parport_procfs.o
+  L_OBJS += parport_share.o parport_ieee1284.o parport_ieee1284_ops.o \
+            parport_procfs.o
+
+  ifeq ($(CONFIG_PARPORT_1284),y)
+    L_OBJS += parport_daisy.o parport_probe.o
+  endif
+
X   ifeq ($(CONFIG_PARPORT_PC),y)
X     LX_OBJS += parport_pc.o
X   else
@@ -62,7 +68,10 @@
X   LX_OBJS += parport_init.o
X else
X   ifeq ($(CONFIG_PARPORT),m)
-    MI_OBJS += parport_share.o parport_ieee1284.o
+    MI_OBJS += parport_share.o parport_ieee1284.o parport_ieee1284_ops.o
+    ifeq ($(CONFIG_PARPORT_1284),y)
+      MI_OBJS += parport_daisy.o parport_probe.o
+    endif
X     ifneq ($(CONFIG_PROC_FS),n) 
X       MI_OBJS += parport_procfs.o
X     endif
diff -u --recursive --new-file v2.3.9/linux/drivers/misc/parport_arc.c linux/drivers/misc/parport_arc.c
--- v2.3.9/linux/drivers/misc/parport_arc.c	Thu Jun  3 16:21:47 1999
+++ linux/drivers/misc/parport_arc.c	Thu Jul  1 14:22:57 1999
@@ -98,41 +98,36 @@
X 	arc_read_control,
X 	arc_frob_control,
X 
-	NULL, /* write_econtrol */
-	NULL, /* read_econtrol */
-	NULL, /* frob_econtrol */
-
-	arc_write_status,
X 	arc_read_status,
X 
-	NULL, /* write_fifo */
-	NULL, /* read_fifo */
-	
-	NULL, /* change_mode */
-	
-	NULL, /* epp_write_data */
-	NULL, /* epp_read_data */
-	NULL, /* epp_write_addr */
-	NULL, /* epp_read_addr */
-	NULL, /* epp_check_timeout */
+	arc_enable_irq,
+	arc_disable_irq,
X 
-	NULL, /* epp_write_block */
-	NULL, /* epp_read_block */
+	arc_data_forward,
+	arc_data_reverse,
+
+	arc_interrupt,
X 
-	NULL, /* ecp_write_block */
-	NULL, /* epp_write_block */
-	
X 	arc_init_state,
X 	arc_save_state,
X 	arc_restore_state,
X 
-	arc_enable_irq,
-	arc_disable_irq,
-	arc_interrupt,
-
X 	arc_inc_use_count,
X 	arc_dec_use_count,
-	arc_fill_inode
+	arc_fill_inode,
+
+	parport_ieee1284_epp_write_data,
+	parport_ieee1284_epp_read_data,
+	parport_ieee1284_epp_write_addr,
+	parport_ieee1284_epp_read_addr,
+
+	parport_ieee1284_ecp_write_data,
+	parport_ieee1284_ecp_read_data,
+	parport_ieee1284_ecp_write_addr,
+	
+	parport_ieee1284_write_compat,
+	parport_ieee1284_read_nibble,
+	parport_ieee1284_read_byte,
X };
X 
X /* --- Initialisation code -------------------------------- */
@@ -142,11 +137,11 @@
X 	/* Archimedes hardware provides only one port, at a fixed address */
X 	struct parport *p;
X 
-	if (check_region(PORT_BASE, 4))
+	if (check_region(PORT_BASE, 1))
X 		return 0;
-	
-	p = parport_register_port(base, IRQ_PRINTERACK, 
-				  PARPORT_DMA_NONE, &parport_arc_ops);
+
+	p = parport_register_port (PORT_BASE, IRQ_PRINTERACK,
+				   PARPORT_DMA_NONE, &parport_arc_ops);
X 
X 	if (!p)
X 		return 0;
@@ -157,9 +152,6 @@
X 	printk(KERN_INFO "%s: Archimedes on-board port, using irq %d\n",
X 	       p->irq);
X 	parport_proc_register(p);
-
-	if (parport_probe_hook)
-		(*parport_probe_hook)(p);
X 
X 	/* Tell the high-level drivers about the port. */
X 	parport_announce_port (p);
diff -u --recursive --new-file v2.3.9/linux/drivers/misc/parport_atari.c linux/drivers/misc/parport_atari.c
--- v2.3.9/linux/drivers/misc/parport_atari.c	Thu Jun  3 16:21:47 1999
+++ linux/drivers/misc/parport_atari.c	Thu Jul  1 14:22:57 1999
@@ -221,9 +221,6 @@
X 		printk(KERN_INFO "%s: Atari built-in port using irq\n", p->name);
X 		parport_proc_register(p);
X 
-		if (parport_probe_hook)
-			(*parport_probe_hook)(p);
-
X 		parport_announce_port (p);
X 
X 		return 1;
diff -u --recursive --new-file v2.3.9/linux/drivers/misc/parport_ax.c linux/drivers/misc/parport_ax.c
--- v2.3.9/linux/drivers/misc/parport_ax.c	Wed Jun  9 14:44:25 1999
+++ linux/drivers/misc/parport_ax.c	Sun Jul  4 09:53:12 1999
@@ -1,4 +1,4 @@
-/* $Id: parport_ax.c,v 1.19 1999/06/09 08:24:40 davem Exp $
+/* $Id: parport_ax.c,v 1.20 1999/07/03 08:56:21 davem Exp $
X  * Parallel-port routines for Sun Ultra/AX architecture
X  * 
X  * Author: Eddie C. Dost <e...@skynet.be>
@@ -164,6 +164,7 @@
X void
X parport_ax_change_mode(struct parport *p, int m)
X {
+	/* FIXME */
X 	parport_ax_frob_econtrol(p, 0xe0, m << 5);
X }
X 
@@ -201,58 +202,40 @@
X 	writel(dcsr, (unsigned long)&dma->dcsr);
X }
X 
-int
-parport_ax_claim_resources(struct parport *p)
-{
-}
-
X void
-parport_ax_init_state(struct parport_state *s)
+parport_ax_init_state(struct pardevice *dev, struct parport_state *s)
X {
-	s->u.pc.ctr = 0xc;
-	s->u.pc.ecr = 0x0;
+	struct linux_ebus_dma *dma = dev->port->private_data;
+
+	s->u.ax.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0);
+	s->u.ax.ecr = 0x0;
+
+	if (dev->irq_func)
+		s->u.ax.dcsr = (readl((unsigned long)&dma->dcsr)
+				| EBUS_DCSR_INT_EN);
+	else
+		s->u.ax.dcsr = (readl((unsigned long)&dma->dcsr)
+				& ~EBUS_DCSR_INT_EN);
X }
X 
X void
X parport_ax_save_state(struct parport *p, struct parport_state *s)
X {
-	s->u.pc.ctr = parport_ax_read_control(p);
-	s->u.pc.ecr = parport_ax_read_econtrol(p);
+	struct linux_ebus_dma *dma = p->private_data;
+
+	s->u.ax.ctr = parport_ax_read_control(p);
+	s->u.ax.ecr = parport_ax_read_econtrol(p);
+	s->u.ax.dcsr = readl((unsigned long)&dma->dcsr);
X }
X 
X void
X parport_ax_restore_state(struct parport *p, struct parport_state *s)
X {
-	parport_ax_write_control(p, s->u.pc.ctr);
-	parport_ax_write_econtrol(p, s->u.pc.ecr);
-}
-
-size_t
-parport_ax_epp_read_block(struct parport *p, void *buf, size_t length)
-{
-	return 0; /* FIXME */
-}
-
-size_t
-parport_ax_epp_write_block(struct parport *p, void *buf, size_t length)
-{
-	return 0; /* FIXME */
-}
-
-int
-parport_ax_ecp_read_block(struct parport *p, void *buf, size_t length,
-			  void (*fn)(struct parport *, void *, size_t),
-			  void *handle)
-{
-	return 0; /* FIXME */
-}
+	struct linux_ebus_dma *dma = p->private_data;
X 
-int
-parport_ax_ecp_write_block(struct parport *p, void *buf, size_t length,
-			   void (*fn)(struct parport *, void *, size_t),
-			   void *handle)
-{
-	return 0; /* FIXME */
+	parport_ax_write_control(p, s->u.ax.ctr);
+	parport_ax_write_econtrol(p, s->u.ax.ecr);
+	writel(s->u.ax.dcsr, (unsigned long)&dma->dcsr);
X }
X 
X void
@@ -290,41 +273,36 @@
X 	parport_ax_read_control,
X 	parport_ax_frob_control,
X 
-	parport_ax_write_econtrol,
-	parport_ax_read_econtrol,
-	parport_ax_frob_econtrol,
-
-	parport_ax_write_status,
X 	parport_ax_read_status,
X 
-	parport_ax_write_fifo,
-	parport_ax_read_fifo,
-	
-	parport_ax_change_mode,
-	
-	parport_ax_write_epp,
-	parport_ax_read_epp,
-	parport_ax_write_epp_addr,
-	parport_ax_read_epp_addr,
-	parport_ax_check_epp_timeout,
+	parport_ax_enable_irq,
+	parport_ax_disable_irq,
X 
-	parport_ax_epp_write_block,
-	parport_ax_epp_read_block,
+	parport_ax_data_forward,
+	parport_ax_data_reverse,
+
+	parport_ax_interrupt,
X 
-	parport_ax_ecp_write_block,
-	parport_ax_ecp_read_block,
-	
X 	parport_ax_init_state,
X 	parport_ax_save_state,
X 	parport_ax_restore_state,
X 
-	parport_ax_enable_irq,
-	parport_ax_disable_irq,
-	parport_ax_interrupt,
-
X 	parport_ax_inc_use_count,
X 	parport_ax_dec_use_count,
-	parport_ax_fill_inode
+	parport_ax_fill_inode,
+
+	parport_ieee1284_epp_write_data,
+	parport_ieee1284_epp_read_data,
+	parport_ieee1284_epp_write_addr,
+	parport_ieee1284_epp_read_addr,
+
+	parport_ieee1284_ecp_write_data,
+	parport_ieee1284_ecp_read_data,
+	parport_ieee1284_ecp_write_addr,
+
+	parport_ieee1284_write_compat,
+	parport_ieee1284_read_nibble,
+	parport_ieee1284_read_byte,
X };
X 
X 
@@ -539,20 +517,6 @@
X 	if (p->dma == PARPORT_DMA_AUTO)
X 		p->dma = (p->modes & PARPORT_MODE_PCECP) ? 0 : PARPORT_DMA_NONE;
X 
-	if (p->irq != PARPORT_IRQ_NONE) {
-		int err;
-		if ((err = request_irq(p->irq, parport_ax_interrupt,
-				       0, p->name, p)) != 0)
-			return err;
-		else
-			parport_ax_enable_irq(p);
-	}
-	request_region(p->base, p->size, p->name);
-	if (p->modes & PARPORT_MODE_PCECR)
-		request_region(p->base+0x400, 3, p->name);
-	request_region((unsigned long)p->private_data,
-		       sizeof(struct linux_ebus_dma), p->name);
-
X 	printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base);
X 	if (p->irq != PARPORT_IRQ_NONE)
X 		printk(", irq %s", __irq_itoa(p->irq));
@@ -569,12 +533,21 @@
X 	printk("]\n");
X 	parport_proc_register(p);
X 
+	if (p->irq != PARPORT_IRQ_NONE)
+		if ((err = request_irq(p->irq, parport_ax_interrupt,
+				       0, p->name, p)) != 0)
+			return 0;		/* @@@ FIXME */
+
+	request_region(p->base, p->size, p->name);
+	if (p->modes & PARPORT_MODE_PCECR)
+		request_region(p->base+0x400, 3, p->name);
+	request_region((unsigned long)p->private_data,
+		       sizeof(struct linux_ebus_dma), p->name);
+
X 	p->ops->write_control(p, 0x0c);
X 	p->ops->write_data(p, 0);
X 
-	if (parport_probe_hook)
-		(*parport_probe_hook)(p);
-
+	/* Tell the high-level drivers about the port. */
X 	parport_announce_port (p);
X 
X 	return 1;
diff -u --recursive --new-file v2.3.9/linux/drivers/misc/parport_daisy.c linux/drivers/misc/parport_daisy.c
--- v2.3.9/linux/drivers/misc/parport_daisy.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/misc/parport_daisy.c	Sat Jul  3 10:45:04 1999
@@ -0,0 +1,473 @@
+/*
+ * IEEE 1284.3 Parallel port daisy chain and multiplexor code
+ * 
+ * Copyright (C) 1999  Tim Waugh <t...@cyberelk.demon.co.uk>
+ *
+ * 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.
+ *
+ * ??-12-1998: Initial implementation.
+ * 31-01-1999: Make port-cloning transparent.
+ * 13-02-1999: Move DeviceID technique from parport_probe.
+ * 13-03-1999: Get DeviceID from non-IEEE 1284.3 devices too.
+ *
+ */
+
+#include <linux/parport.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+
+#define DEBUG /* undef me for production */
+
+#ifdef DEBUG
+#define DPRINTK(stuff...) printk (stuff)
+#else
+#define DPRINTK(stuff...)
+#endif
+
+static struct daisydev {
+	struct daisydev *next;
+	struct parport *port;
+	int daisy;
+	int devnum;
+} *topology = NULL;
+
+static int numdevs = 0;
+
+/* Forward-declaration of lower-level functions. */
+static int mux_present (struct parport *port);
+static int num_mux_ports (struct parport *port);
+static int select_port (struct parport *port);
+static int assign_addrs (struct parport *port);
+
+/* Add a device to the discovered topology. */
+static void add_dev (int devnum, struct parport *port, int daisy)
+{
+	struct daisydev *newdev;
+	newdev = kmalloc (GFP_KERNEL, sizeof (struct daisydev));
+	if (newdev) {
+		newdev->port = port;
+		newdev->daisy = daisy;
+		newdev->devnum = devnum;
+		newdev->next = topology;
+		if (!topology || topology->devnum >= devnum)
+			topology = newdev;
+		else {
+			struct daisydev *prev = topology;
+			while (prev->next && prev->next->devnum < devnum)
+				prev = prev->next;
+			newdev->next = prev->next;
+			prev->next = newdev;
+		}
+	}
+}
+
+/* Clone a parport (actually, make an alias). */
+static struct parport *clone_parport (struct parport *real, int muxport)
+{
+	struct parport *extra = parport_register_port (real->base,
+						       real->irq,
+						       real->dma,
+						       real->ops);
+	if (extra) {
+		extra->portnum = real->portnum;
+		extra->physport = real;
+		extra->muxport = muxport;
+	}
+
+	return extra;
+}
+
+/* Discover the IEEE1284.3 topology on a port -- muxes and daisy chains. */
+int parport_daisy_init (struct parport *port)
+{
+	char *deviceid;
+	static const char *th[] = { /*0*/"th", "st", "nd", "rd", "th" };
+	int num_ports;
+	int i;
+
+	/* Because this is called before any other devices exist,
+	 * we don't have to claim exclusive access.  */
+
+	/* If mux present on normal port, need to create new
+	 * parports for each extra port. */
+	if (port->muxport < 0 && mux_present (port) &&
+	    /* don't be fooled: a mux must have 2 or 4 ports. */
+	    ((num_ports = num_mux_ports (port)) == 2 || num_ports == 4)) {
+		/* Leave original as port zero. */
+		port->muxport = 0;
+		printk (KERN_INFO
+			"%s: 1st (default) port of %d-way multiplexor\n",
+			port->name, num_ports);
+		for (i = 1; i < num_ports; i++) {
+			/* Clone the port. */
+			struct parport *extra = clone_parport (port, i);
+			if (!extra) {
+				if (signal_pending (current))
+					break;
+
+				schedule ();
+				continue;
+			}
+
+			printk (KERN_INFO
+				"%s: %d%s port of %d-way multiplexor on %s\n",
+				extra->name, i + 1, th[i + 1], num_ports,
+				port->name);
+
+			/* Analyse that port too.  We won't recurse
+			   forever because of the 'port->muxport < 0'
+			   test above. */
+			parport_announce_port (extra);
+		}
+	}
+
+	if (port->muxport >= 0)
+		select_port (port);
+
+	parport_daisy_deselect_all (port);
+	assign_addrs (port);
+
+	/* Count the potential legacy device at the end. */
+	add_dev (numdevs++, port, -1);
+
+	/* Find out the legacy device's IEEE 1284 device ID. */
+	deviceid = kmalloc (1000, GFP_KERNEL);
+	if (deviceid) {
+		parport_device_id (numdevs - 1, deviceid, 1000);
+		kfree (deviceid);
+	}
+
+	return 0;
+}
+
+/* Forget about devices on a physical port. */
+void parport_daisy_fini (struct parport *port)
+{
+	struct daisydev *dev, *prev = topology;
+	while (prev && prev->port == port)
+		prev = topology = topology->next;
+
+	while (prev) {
+		dev = prev->next;
+		if (dev && dev->port == port)
+			prev->next = dev->next;
+
+		prev = prev->next;
+	}
+
+	/* Gaps in the numbering could be handled better.  How should
+           someone enumerate through all IEEE1284.3 devices in the
+           topology?. */
+	if (!topology) numdevs = 0;
+	return; }
+
+/* Find a device by canonical device number. */
+struct pardevice *parport_open (int devnum, const char *name,
+				int (*pf) (void *), void (*kf) (void *),
+				void (*irqf) (int, void *, struct pt_regs *),
+				int flags, void *handle)
+{
+	struct parport *port = parport_enumerate ();
+	struct pardevice *dev;
+	int portnum;
+	int muxnum;
+	int daisynum;
+
+	if (parport_device_coords (devnum,  &portnum, &muxnum, &daisynum))
+		return NULL;
+
+	while (port && ((port->portnum != portnum) ||
+			(port->muxport != muxnum)))
+		port = port->next;
+
+	if (!port)
+		/* No corresponding parport. */
+		return NULL;
+
+	dev = parport_register_device (port, name, pf, kf,
+				       irqf, flags, handle);
+	if (dev)
+		dev->daisy = daisynum;
+
+	/* Check that there really is a device to select. */
+	if (daisynum >= 0) {
+		int selected;
+		parport_claim_or_block (dev);
+		selected = port->daisy;
+		parport_release (dev);
+
+		if (selected != port->daisy) {
+			/* No corresponding device. */
+			parport_unregister_device (dev);
+			return NULL;
+		}
+	}
+
+	return dev;
+}
+
+/* The converse of parport_open. */
+void parport_close (struct pardevice *dev)
+{
+	parport_unregister_device (dev);
+}
+
+/* Convert device coordinates into a canonical device number. */
+int parport_device_num (int parport, int mux, int daisy)
+{
+	struct daisydev *dev = topology;
+
+	while (dev && dev->port->portnum != parport &&
+	       dev->port->muxport != mux && dev->daisy != daisy)
+		dev = dev->next;
+
+	if (!dev)
+		return -ENXIO;
+
+	return dev->devnum;
+}
+
+/* Convert a canonical device number into device coordinates. */
+int parport_device_coords (int devnum, int *parport, int *mux, int *daisy)
+{
+	struct daisydev *dev = topology;
+
+	while (dev && dev->devnum != devnum)
+		dev = dev->next;
+
+	if (!dev)
+		return -ENXIO;
+
+	if (parport) *parport = dev->port->portnum;
+	if (mux) *mux = dev->port->muxport;
+	if (daisy) *daisy = dev->daisy;
+	return 0;
+}
+
+/* Send a daisy-chain-style CPP command packet. */
+static int cpp_daisy (struct parport *port, int cmd)
+{
+	unsigned char s;
+
+	parport_write_data (port, 0xaa); udelay (2);
+	parport_write_data (port, 0x55); udelay (2);
+	parport_write_data (port, 0x00); udelay (2);
+	parport_write_data (port, 0xff); udelay (2);
+	s = parport_read_status (port) & (PARPORT_STATUS_BUSY
+					  | PARPORT_STATUS_PAPEROUT
+					  | PARPORT_STATUS_SELECT
+					  | PARPORT_STATUS_ERROR);
+	if (s != (PARPORT_STATUS_BUSY
+		  | PARPORT_STATUS_PAPEROUT
+		  | PARPORT_STATUS_SELECT
+		  | PARPORT_STATUS_ERROR)) {
+		DPRINTK (KERN_DEBUG "%s: cpp_daisy: aa5500ff(%02x)\n",
+			 port->name, s);
+		return -ENXIO;
+	}
+
+	parport_write_data (port, 0x87); udelay (2);
+	s = parport_read_status (port) & (PARPORT_STATUS_BUSY
+					  | PARPORT_STATUS_PAPEROUT
+					  | PARPORT_STATUS_SELECT
+					  | PARPORT_STATUS_ERROR);
+	if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) {
+		DPRINTK (KERN_DEBUG "%s: cpp_daisy: aa5500ff87(%02x)\n",
+			 port->name, s);
+		return -ENXIO;
+	}
+
+	parport_write_data (port, 0x78); udelay (2);
+	parport_write_data (port, cmd); udelay (2);
+	parport_frob_control (port,
+			      PARPORT_CONTROL_STROBE,
+			      PARPORT_CONTROL_STROBE);
+	udelay (1);
+	parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
+	udelay (1);
+	s = parport_read_status (port);
+	parport_write_data (port, 0xff); udelay (2);
+
+	return s;
+}
+
+/* Send a mux-style CPP command packet. */
+static int cpp_mux (struct parport *port, int cmd)
+{
+	unsigned char s;
+	int rc;
+
+	parport_write_data (port, 0xaa); udelay (2);
+	parport_write_data (port, 0x55); udelay (2);
+	parport_write_data (port, 0xf0); udelay (2);
+	parport_write_data (port, 0x0f); udelay (2);
+	parport_write_data (port, 0x52); udelay (2);
+	parport_write_data (port, 0xad); udelay (2);
+	parport_write_data (port, cmd); udelay (2);
+
+	s = parport_read_status (port);
+	if (!(s & PARPORT_STATUS_ACK)) {
+		DPRINTK (KERN_DEBUG "%s: cpp_mux: aa55f00f52ad%02x(%02x)\n",
+			 port->name, cmd, s);
+		return -EIO;
+	}
+
+	rc = (((s & PARPORT_STATUS_SELECT   ? 1 : 0) << 0) |
+	      ((s & PARPORT_STATUS_PAPEROUT ? 1 : 0) << 1) |
+	      ((s & PARPORT_STATUS_BUSY     ? 0 : 1) << 2) |
+	      ((s & PARPORT_STATUS_ERROR    ? 0 : 1) << 3));
+
+	return rc;
+}
+
+void parport_daisy_deselect_all (struct parport *port)
+{
+	cpp_daisy (port, 0x30);
+}
+
+int parport_daisy_select (struct parport *port, int daisy, int mode)
+{
+	/* mode is currently ignored. FIXME? */
+	return cpp_daisy (port, 0xe0 + daisy) & PARPORT_STATUS_ERROR;
+}
+
+static int mux_present (struct parport *port)
+{
+	return cpp_mux (port, 0x51) == 3;
+}
+
+static int num_mux_ports (struct parport *port)
+{
+	return cpp_mux (port, 0x58);
+}
+
+static int select_port (struct parport *port)
+{
+	int muxport = port->muxport;
+	return cpp_mux (port, 0x60 + muxport) == muxport;
+}
+
+static int assign_addrs (struct parport *port)
+{
+	unsigned char s, last_dev;
+	unsigned char daisy;
+	int thisdev = numdevs;
+	char *deviceid;
+
+	parport_write_data (port, 0xaa); udelay (2);
+	parport_write_data (port, 0x55); udelay (2);
+	parport_write_data (port, 0x00); udelay (2);
+	parport_write_data (port, 0xff); udelay (2);
+	s = parport_read_status (port) & (PARPORT_STATUS_BUSY
+					  | PARPORT_STATUS_PAPEROUT
+					  | PARPORT_STATUS_SELECT
+					  | PARPORT_STATUS_ERROR);
+	if (s != (PARPORT_STATUS_BUSY
+		  | PARPORT_STATUS_PAPEROUT
+		  | PARPORT_STATUS_SELECT
+		  | PARPORT_STATUS_ERROR)) {
+		DPRINTK (KERN_DEBUG "%s: assign_addrs: aa5500ff(%02x)\n",
+			 port->name, s);
+		return -ENXIO;
+	}
+
+	parport_write_data (port, 0x87); udelay (2);
+	s = parport_read_status (port) & (PARPORT_STATUS_BUSY
+					  | PARPORT_STATUS_PAPEROUT
+					  | PARPORT_STATUS_SELECT
+					  | PARPORT_STATUS_ERROR);
+	if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) {
+		DPRINTK (KERN_DEBUG "%s: assign_addrs: aa5500ff87(%02x)\n",
+			 port->name, s);
+		return -ENXIO;
+	}
+
+	parport_write_data (port, 0x78); udelay (2);
+	last_dev = 0; /* We've just been speaking to a device, so we
+			 know there must be at least _one_ out there. */
+
+	for (daisy = 0; daisy < 4; daisy++) {
+		parport_write_data (port, daisy);
+		udelay (2);
+		parport_frob_control (port,
+				      PARPORT_CONTROL_STROBE,
+				      PARPORT_CONTROL_STROBE);
+		udelay (1);
+		parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
+		udelay (1);
+
+		if (last_dev)
+			/* No more devices. */
+			break;
+
+		last_dev = !(parport_read_status (port)
+			     & PARPORT_STATUS_BUSY);
+
+		add_dev (numdevs++, port, daisy);
+	}
+
+	parport_write_data (port, 0xff); udelay (2);
+	DPRINTK (KERN_DEBUG "%s: Found %d daisy-chained devices\n", port->name,
+		numdevs - thisdev);
+
+	/* Ask the new devices to introduce themselves. */
+	deviceid = kmalloc (1000, GFP_KERNEL);
+	if (!deviceid) return 0;
+
+	for (daisy = 0; thisdev < numdevs; thisdev++, daisy++)
+		parport_device_id (thisdev, deviceid, 1000);
+
+	kfree (deviceid);
+	return 0;
+}
+
+/* Find a device with a particular manufacturer and model string,
+   starting from a given device number.  Like the PCI equivalent,
+   'from' itself is skipped. */
+int parport_find_device (const char *mfg, const char *mdl, int from)
+{
+	struct daisydev *d = topology; /* sorted by devnum */
+
+	/* Find where to start. */
+	while (d && d->devnum <= from)
+		d = d->next;
+
+	/* Search. */
+	while (d) {
+		struct parport_device_info *info;
+		info = &d->port->probe_info[1 + d->daisy];
+		if ((!mfg || !strcmp (mfg, info->mfr)) &&
+		    (!mdl || !strcmp (mdl, info->model)))
+			break;
+
+		d = d->next;
+	}
+
+	if (d)
+		return d->devnum;
+
+	return -1;
+}
+
+/* Find a device in a particular class.  Like the PCI equivalent,
+   'from' itself is skipped. */
+int parport_find_class (parport_device_class cls, int from)
+{
+	struct daisydev *d = topology; /* sorted by devnum */
+
+	/* Find where to start. */
+	while (d && d->devnum <= from)
+		d = d->next;
+
+	/* Search. */
+	while (d && d->port->probe_info[1 + d->daisy].class != cls)
+		d = d->next;
+
+	if (d)
+		return d->devnum;
+
+	return -1;
+}
diff -u --recursive --new-file v2.3.9/linux/drivers/misc/parport_ieee1284.c linux/drivers/misc/parport_ieee1284.c
--- v2.3.9/linux/drivers/misc/parport_ieee1284.c	Mon May 10 10:26:31 1999
+++ linux/drivers/misc/parport_ieee1284.c	Wed Jul  7 12:55:47 1999
@@ -4,12 +4,73 @@
X  * Authors: Phil Blundell <Philip....@pobox.com>
X  *          Carsten Gross <car...@sol.wohnheim.uni-ulm.de>
X  *	    Jose Renau <re...@acm.org>
+ *          Tim Waugh <t...@cyberelk.demon.co.uk> (largely rewritten)
+ *
+ * This file is responsible for IEEE 1284 negotiation, and for handing
+ * read/write requests to low-level drivers.
X  */
X 
+#include <linux/config.h>
X #include <linux/tasks.h>
X #include <linux/parport.h>
X #include <linux/delay.h>
X #include <linux/kernel.h>
+#include <linux/interrupt.h>
+
+#undef DEBUG /* undef me for production */
+
+#ifdef CONFIG_LP_CONSOLE
+#undef DEBUG /* Don't want a garbled console */
+#endif
+
+#ifdef DEBUG
+#define DPRINTK(stuff...) printk (stuff)
+#else
+#define DPRINTK(stuff...)
+#endif
+
+/* Make parport_wait_peripheral wake up.
+ * It will be useful to call this from an interrupt handler. */
+void parport_ieee1284_wakeup (struct parport *port)
+{
+	up (&port->physport->ieee1284.irq);
+}
+
+static struct parport *port_from_cookie[PARPORT_MAX];
+static void timeout_waiting_on_port (unsigned long cookie)
+{
+	parport_ieee1284_wakeup (port_from_cookie[cookie % PARPORT_MAX]);
+}
+
+/* Wait for a parport_ieee1284_wakeup.
+ * 0:      success
+ * <0:     error (exit as soon as possible)
+ * >0:     timed out
+ */
+int parport_wait_event (struct parport *port, signed long timeout)
+{
+	int ret;
+	struct timer_list timer;
+
+	if (!port->physport->cad->timeout)
+		/* Zero timeout is special, and we can't down() the
+		   semaphore. */
+		return 1;
+
+	init_timer (&timer);
+	timer.expires = jiffies + timeout;
+	timer.function = timeout_waiting_on_port;
+	port_from_cookie[port->number % PARPORT_MAX] = port;
+	timer.data = port->number;
+
+	add_timer (&timer);
+	ret = down_interruptible (&port->physport->ieee1284.irq);
+	if (!del_timer (&timer) && !ret)
+		/* Timed out. */
+		ret = 1;
+
+	return ret;
+}
X 
X /* Wait for Status line(s) to change in 35 ms - see IEEE1284-1994 page 24 to
X  * 25 for this. After this time we can create a timeout because the
@@ -19,53 +80,446 @@
X  * are able to eat the time up to 40ms.
X  */ 
X 
-int parport_wait_peripheral(struct parport *port, unsigned char mask, 
-	unsigned char result)
+int parport_wait_peripheral(struct parport *port,
+			    unsigned char mask, 
+			    unsigned char result)
X {
X 	int counter;
-	unsigned char status; 
-	
-	for (counter = 0; counter < 20; counter++) {
-		status = parport_read_status(port);
+	long deadline;
+	unsigned char status;
+
+	counter = port->physport->spintime; /* usecs of fast polling */
+	if (!port->physport->cad->timeout)
+		/* A zero timeout is "special": busy wait for the
+		   entire 35ms. */
+		counter = 35000;
+
+	/* Fast polling.
+	 *
+	 * This should be adjustable.
+	 * How about making a note (in the device structure) of how long
+	 * it takes, so we know for next time?
+	 */
+	for (counter /= 5; counter > 0; counter--) {
+		status = parport_read_status (port);
X 		if ((status & mask) == result)
X 			return 0;
-		udelay(25);
+		if (signal_pending (current))
+			return -EINTR;
X 		if (current->need_resched)
-			schedule();
+			break;
+		udelay(5);
X 	}
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(HZ/25);				/* wait for 40ms */
-	status = parport_read_status(port);
-	return ((status & mask) == result)?0:1;
+
+	if (!port->physport->cad->timeout)
+		/* We may be in an interrupt handler, so we can't poll
+		 * slowly anyway. */
+		return 1;
+
+	/* 40ms of slow polling. */
+	deadline = jiffies + (HZ + 24) / 25;
+	while (time_before (jiffies, deadline)) {
+		int ret;
+
+		if (signal_pending (current))
+			return -EINTR;
+
+		/* Wait for 10ms (or until an interrupt occurs if
+		 * the handler is set) */
+		if ((ret = parport_wait_event (port, (HZ + 99) / 100)) < 0)
+			return ret;
+
+		status = parport_read_status (port);
+		if ((status & mask) == result)
+			return 0;
+
+		if (!ret) {
+			/* parport_wait_event didn't time out, but the
+			 * peripheral wasn't actually ready either.
+			 * Wait for another 10ms. */
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout ((HZ+ 99) / 100);
+		}
+	}
+
+	return 1;
+}
+
+#ifdef CONFIG_PARPORT_1284
+/* Terminate a negotiated mode. */
+static void parport_ieee1284_terminate (struct parport *port)
+{
+	port = port->physport;
+
+	port->ieee1284.phase = IEEE1284_PH_TERMINATE;
+
+	/* EPP terminates differently. */
+	switch (port->ieee1284.mode) {
+	case IEEE1284_MODE_EPP:
+	case IEEE1284_MODE_EPPSL:
+	case IEEE1284_MODE_EPPSWE:
+		/* Terminate from EPP mode. */
+
+		/* Event 68: Set nInit low */
+		parport_frob_control (port,
+				      PARPORT_CONTROL_INIT,
+				      PARPORT_CONTROL_INIT);
+		udelay (50);
+
+		/* Event 69: Set nInit high, nSelectIn low */
+		parport_frob_control (port,
+				      PARPORT_CONTROL_SELECT,
+				      PARPORT_CONTROL_SELECT);
+		break;
+		
+	default:
+		/* Terminate from all other modes. */
+
+		/* Event 22: Set nSelectIn low, nAutoFd high */
+		parport_frob_control (port,
+				      PARPORT_CONTROL_SELECT
+				      | PARPORT_CONTROL_AUTOFD,
+				      PARPORT_CONTROL_SELECT);
+
+		/* Event 24: nAck goes low */
+		parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0);
+
+		/* Event 25: Set nAutoFd low */
+		parport_frob_control (port,
+				      PARPORT_CONTROL_AUTOFD,
+				      PARPORT_CONTROL_AUTOFD);
+
+		/* Event 27: nAck goes high */
+		parport_wait_peripheral (port,
+					 PARPORT_STATUS_ACK, 
+					 PARPORT_STATUS_ACK);
+
+		/* Event 29: Set nAutoFd high */
+		parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0);
+	}
+
+	port->ieee1284.mode = IEEE1284_MODE_COMPAT;
+	port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;
+
+	DPRINTK (KERN_DEBUG "%s: In compatibility (forward idle) mode\n",
+		 port->name);
X }		
+#endif /* IEEE1284 support */
X 
-/* Test if the peripheral is IEEE 1284 compliant.
+/* Negotiate an IEEE 1284 mode.
X  * return values are:
- *   0 - handshake failed; peripheral is not compliant (or none present)
- *   1 - handshake OK; IEEE1284 peripheral present but no data available
- *   2 - handshake OK; IEEE1284 peripheral and data available
+ *   0 - handshake OK; IEEE1284 peripheral and mode available
+ *  -1 - handshake failed; peripheral is not compliant (or none present)
+ *   1 - handshake OK; IEEE1284 peripheral present but mode not available
X  */
-int parport_ieee1284_nibble_mode_ok(struct parport *port, unsigned char mode) 
+int parport_negotiate (struct parport *port, int mode)
X {
-	/* make sure it's a valid state, set nStrobe & nAutoFeed high */
-	parport_frob_control (port, (1|2), 0);
-	udelay(1);
-	parport_write_data(port, mode);
-	udelay(400);
-	/* nSelectIn high, nAutoFd low */
-	parport_frob_control(port, (2|8), 2);
-	if (parport_wait_peripheral(port, 0x78, 0x38)) {
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 15'
echo 'File patch-2.3.10 is continued in part 16'
echo 16 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 11 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
X 	NULL,		/* Seek */
X 	pcwd_read,	/* Read */
@@ -539,14 +577,14 @@
X #ifdef	MODULE
X int init_module(void)
X #else
-__initfunc(int pcwatchdog_init(void))
+int __init pcwatchdog_init(void)
X #endif
X {
X 	int i, found = 0;
X 
X 	revision = PCWD_REVISION_A;
X 
-	printk("pcwd: v%s Ken Hollis (kho...@nurk.org)\n", WD_VER);
+	printk("pcwd: v%s Ken Hollis (ke...@bitgate.com)\n", WD_VER);
X 
X 	/* Initial variables */
X 	is_open = 0;
@@ -588,6 +626,9 @@
X 		printk("pcwd: Unable to get revision.\n");
X 		return -1;
X 	}
+
+	if (supports_temp)
+		printk("pcwd: Temperature Option Detected.\n");
X 
X 	debug_off();
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/char/ppdev.c linux/drivers/char/ppdev.c
--- v2.3.9/linux/drivers/char/ppdev.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/ppdev.c	Mon Jul  5 20:31:26 1999
@@ -0,0 +1,548 @@
+/*
+ * linux/drivers/char/ppdev.c
+ *
+ * This is the code behind /dev/parport* -- it allows a user-space
+ * application to use the parport subsystem.
+ *
+ * Copyright (C) 1998-9 Tim Waugh <t...@cyberelk.demon.co.uk>
+ *
+ * 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.
+ *
+ * A /dev/parportxy device node represents an arbitrary device ('y')
+ * on port 'x'.  The following operations are possible:
+ *
+ * open		do nothing, set up default IEEE 1284 protocol to be COMPAT
+ * close	release port and unregister device (if necessary)
+ * ioctl
+ *   EXCL	register device exclusively (may fail)
+ *   CLAIM	(register device first time) parport_claim_or_block
+ *   RELEASE	parport_release
+ *   SETMODE	set the IEEE 1284 protocol to use for read/write
+ *   DATADIR	data_forward / data_reverse
+ *   WDATA	write_data
+ *   RDATA	read_data
+ *   WCONTROL	write_control
+ *   RCONTROL	read_control
+ *   FCONTROL	frob_control
+ *   RSTATUS	read_status
+ *   NEGOT	parport_negotiate
+ *   YIELD	parport_yield_blocking
+ * read/write	read or write in current IEEE 1284 protocol
+ * select	wait for interrupt (in readfds)
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/ioctl.h>
+#include <linux/parport.h>
+#include <linux/ctype.h>
+#include <linux/poll.h>
+#include <asm/uaccess.h>
+#include "ppdev.h"
+
+#define PP_VERSION "ppdev: user-space parallel port driver"
+#define CHRDEV "ppdev"
+
+#ifndef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+/* The device minor encodes the parport number and (arbitrary) 
+ * pardevice number as (port << 4) | dev. */
+#define PP_PORT(minor) ((minor >> 4) & 0xf)
+#define PP_DEV(minor) ((minor) & 0xf)
+
+struct pp_struct {
+	struct pardevice * pdev;
+	wait_queue_head_t irq_wait;
+	int mode;
+	unsigned int flags;
+};
+
+/* pp_struct.flags bitfields */
+#define PP_CLAIMED    (1<<0)
+#define PP_EXCL       (1<<1)
+
+/* Other constants */
+#define PP_INTERRUPT_TIMEOUT (10 * HZ) /* 10s */
+#define PP_BUFFER_SIZE 256
+#define PARDEVICE_MAX 8
+
+static struct pp_struct pp_table[PARPORT_MAX][PARDEVICE_MAX];
+
+static loff_t pp_lseek (struct file * file, long long offset, int origin)
+{
+	return -ESPIPE;
+}
+
+/* This looks a bit like parport_read.  The difference is that we don't
+ * determine the mode to use from the port data, but rather from the
+ * mode the driver told us to use. */
+static ssize_t do_read (struct pp_struct *pp, void *buf, size_t len)
+{
+	size_t (*fn) (struct parport *, void *, size_t, int);
+	struct parport *port = pp->pdev->port;
+
+	switch (pp->mode) {
+	case IEEE1284_MODE_COMPAT:
+		/* This is a write-only mode. */
+		return -EIO;
+
+	case IEEE1284_MODE_NIBBLE:
+		fn = port->ops->nibble_read_data;
+		break;
+
+	case IEEE1284_MODE_BYTE:
+		fn = port->ops->byte_read_data;
+		break;
+
+	case IEEE1284_MODE_EPP:
+		fn = port->ops->epp_read_data;
+		break;
+
+	case IEEE1284_MODE_ECP:
+	case IEEE1284_MODE_ECPRLE:
+		fn = port->ops->ecp_read_data;
+		break;
+
+	case IEEE1284_MODE_ECPSWE:
+		fn = parport_ieee1284_ecp_read_data;
+		break;
+
+	default:
+		printk (KERN_DEBUG "%s: unknown mode 0x%02x\n",
+			pp->pdev->name, pp->mode);
+		return -EINVAL;
+	}
+
+	return (*fn) (port, buf, len, 0);
+}
+
+/* This looks a bit like parport_write.  The difference is that we don't
+ * determine the mode to use from the port data, but rather from the
+ * mode the driver told us to use. */
+static ssize_t do_write (struct pp_struct *pp, const void *buf, size_t len)
+{
+	size_t (*fn) (struct parport *, const void *, size_t, int);
+	struct parport *port = pp->pdev->port;
+
+	switch (pp->mode) {
+	case IEEE1284_MODE_NIBBLE:
+	case IEEE1284_MODE_BYTE:
+		/* Read-only modes. */
+		return -EIO;
+
+	case IEEE1284_MODE_COMPAT:
+		fn = port->ops->compat_write_data;
+		break;
+
+	case IEEE1284_MODE_EPP:
+		fn = port->ops->epp_write_data;
+		break;
+
+	case IEEE1284_MODE_ECP:
+	case IEEE1284_MODE_ECPRLE:
+		fn = port->ops->ecp_write_data;
+		break;
+
+	case IEEE1284_MODE_ECPSWE:
+		fn = parport_ieee1284_ecp_write_data;
+		break;
+
+	default:
+		printk (KERN_DEBUG "%s: unknown mode 0x%02x\n",
+			pp->pdev->name, pp->mode);
+		return -EINVAL;
+	}
+
+	return (*fn) (port, buf, len, 0);
+}
+
+static ssize_t pp_read (struct file * file, char * buf, size_t count,
+			loff_t * ppos)
+{
+	unsigned int minor = MINOR (file->f_dentry->d_inode->i_rdev);
+	unsigned int portnum = PP_PORT (minor);
+	unsigned int dev = PP_DEV (minor);
+	char * kbuffer;
+	ssize_t bytes_read = 0;
+	ssize_t got = 0;
+
+	if (!(pp_table[portnum][dev].flags & PP_CLAIMED)) {
+		/* Don't have the port claimed */
+		printk (KERN_DEBUG CHRDEV "%02x: claim the port first\n",
+			minor);
+		return -EPERM;
+	}
+
+	kbuffer = kmalloc (min (count, PP_BUFFER_SIZE), GFP_KERNEL);
+	if (!kbuffer)
+		return -ENOMEM;
+
+	while (bytes_read < count) {
+		ssize_t need = min(count - bytes_read, PP_BUFFER_SIZE);
+
+		got = do_read (&pp_table[portnum][dev], kbuffer, need);
+
+		if (got < 0) {
+			if (!bytes_read)
+				bytes_read = got;
+
+			break;
+		}
+
+		if (copy_to_user (kbuffer, buf + bytes_read, got)) {
+			bytes_read = -EFAULT;
+			break;
+		}
+
+		bytes_read += got;
+
+		if (signal_pending (current)) {
+			if (!bytes_read)
+				bytes_read = -EINTR;
+			break;
+		}
+
+		if (current->need_resched)
+			schedule ();
+	}
+
+	kfree (kbuffer);
+	return bytes_read;
+}
+
+static ssize_t pp_write (struct file * file, const char * buf, size_t count,
+			 loff_t * ppos)
+{
+	unsigned int minor = MINOR (file->f_dentry->d_inode->i_rdev);
+	unsigned int portnum = PP_PORT (minor);
+	unsigned int dev = PP_DEV (minor);
+	char * kbuffer;
+	ssize_t bytes_written = 0;
+	ssize_t wrote;
+
+	if (!(pp_table[portnum][dev].flags & PP_CLAIMED)) {
+		/* Don't have the port claimed */
+		printk (KERN_DEBUG CHRDEV "%02x: claim the port first\n",
+			minor);
+		return -EPERM;
+	}
+
+	kbuffer = kmalloc (min (count, PP_BUFFER_SIZE), GFP_KERNEL);
+	if (!kbuffer)
+		return -ENOMEM;
+
+	while (bytes_written < count) {
+		ssize_t n = min(count - bytes_written, PP_BUFFER_SIZE);
+
+		if (copy_from_user (kbuffer, buf + bytes_written, n)) {
+			bytes_written = -EFAULT;
+			break;
+		}
+
+		wrote = do_write (&pp_table[portnum][dev], kbuffer, n);
+
+		if (wrote < 0) {
+			if (!bytes_written)
+				bytes_written = wrote;
+			break;
+		}
+
+		bytes_written += wrote;
+
+		if (signal_pending (current)) {
+			if (!bytes_written)
+				bytes_written = -EINTR;
+			break;
+		}
+
+		if (current->need_resched)
+			schedule ();
+	}
+
+	kfree (kbuffer);
+	return bytes_written;
+}
+
+static void pp_irq (int irq, void * private, struct pt_regs * unused)
+{
+	struct pp_struct * pp = (struct pp_struct *) private;
+	wake_up_interruptible (&pp->irq_wait);
+}
+
+static int register_device (int minor)
+{
+	unsigned int portnum = PP_PORT (minor);
+	unsigned int dev = PP_DEV (minor);
+	struct parport * port;
+	struct pardevice * pdev = NULL;
+	char *name;
+	int fl;
+
+	name = kmalloc (strlen (CHRDEV) + 3, GFP_KERNEL);
+	if (name == NULL)
+		return -ENOMEM;
+
+	sprintf (name, CHRDEV "%02x", minor);
+	port = parport_enumerate (); /* FIXME: use attach/detach */
+
+	while (port && port->number != portnum)
+		port = port->next;
+
+	if (!port) {
+		printk (KERN_WARNING "%s: no associated port!\n", name);
+		kfree (name);
+		return -ENXIO;
+	}
+
+	fl = (pp_table[portnum][dev].flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0;
+	pdev = parport_register_device (port, name, NULL, NULL, pp_irq, fl,
+					&pp_table[portnum][dev]);
+
+	if (!pdev) {
+		printk (KERN_WARNING "%s: failed to register device!\n", name);
+		kfree (name);
+		return -ENXIO;
+	}
+
+	pp_table[portnum][dev].pdev = pdev;
+	printk (KERN_DEBUG "%s: registered pardevice\n", name);
+	return 0;
+}
+
+static int pp_ioctl(struct inode *inode, struct file *file,
+		    unsigned int cmd, unsigned long arg)
+{
+	unsigned int minor = MINOR(inode->i_rdev);
+	unsigned int portnum = PP_PORT (minor);
+	unsigned int dev = PP_DEV (minor);
+	struct parport * port;
+
+	/* First handle the cases that don't take arguments. */
+	if (cmd == PPCLAIM) {
+		if (pp_table[portnum][dev].flags & PP_CLAIMED) {
+			printk (KERN_DEBUG CHRDEV
+				"%02x: you've already got it!\n", minor);
+			return -EINVAL;
+		}
+
+		/* Deferred device registration. */
+		if (!pp_table[portnum][dev].pdev) {
+			int err = register_device (minor);
+			if (err)
+				return err;
+		}
+
+		parport_claim_or_block (pp_table[portnum][dev].pdev);
+		pp_table[portnum][dev].flags |= PP_CLAIMED;
+		return 0;
+	}
+
+	port = pp_table[portnum][dev].pdev->port;
+	if (cmd == PPEXCL) {
+		if (pp_table[portnum][dev].pdev) {
+			printk (KERN_DEBUG CHRDEV "%02x: too late for PPEXCL; "
+				"already registered\n", minor);
+			if (pp_table[portnum][dev].flags & PP_EXCL)
+				/* But it's not really an error. */
+				return 0;
+			/* There's no chance of making the driver happy. */
+			return -EINVAL;
+		}
+
+		/* Just remember to register the device exclusively
+		 * when we finally do the registration. */
+		pp_table[portnum][dev].flags |= PP_EXCL;
+		return 0;
+	}
+
+	/* Everything else requires the port to be claimed, so check
+	 * that now. */
+	if ((pp_table[portnum][dev].flags & PP_CLAIMED) == 0) {
+		printk (KERN_DEBUG CHRDEV "%02x: claim the port first\n",
+			minor);
+		return -EPERM;
+	}
+
+	switch (cmd) {
+		unsigned char reg;
+		unsigned char mask;
+		int mode;
+
+	case PPRSTATUS:
+		reg = parport_read_status (port);
+		return copy_to_user ((unsigned char *) arg, ®,
+				     sizeof (reg));
+
+	case PPRDATA:
+		reg = parport_read_data (port);
+		return copy_to_user ((unsigned char *) arg, ®,
+				     sizeof (reg));
+
+	case PPRCONTROL:
+		reg = parport_read_control (port);
+		return copy_to_user ((unsigned char *) arg, ®,
+				     sizeof (reg));
+
+	case PPYIELD:
+		parport_yield_blocking (pp_table[portnum][dev].pdev);
+		return 0;
+
+	case PPRELEASE:
+		parport_release (pp_table[portnum][dev].pdev);
+		pp_table[portnum][dev].flags &= ~PP_CLAIMED;
+		return 0;
+
+	case PPSETMODE:
+		if (copy_from_user (&mode, (int *) arg, sizeof (mode)))
+			return -EFAULT;
+		/* FIXME: validate mode */
+		pp_table[portnum][dev].mode = mode;
+		return 0;
+
+	case PPWCONTROL:
+		if (copy_from_user (®, (unsigned char *) arg, sizeof (reg)))
+			return -EFAULT;
+		parport_write_control (port, reg);
+		return 0;
+
+	case PPWDATA:
+		if (copy_from_user (®, (unsigned char *) arg, sizeof (reg)))
+			return -EFAULT;
+		parport_write_data (port, reg);
+		return 0;
+
+	case PPFCONTROL:
+		if (copy_from_user (&mask, (unsigned char *) arg,
+				    sizeof (mask)))
+			return -EFAULT;
+		if (copy_from_user (®, 1 + (unsigned char *) arg,
+				    sizeof (reg)))
+			return -EFAULT;
+		parport_frob_control (port, mask, reg);
+		return 0;
+
+	case PPDATADIR:
+		if (copy_from_user (&mode, (int *) arg, sizeof (mode)))
+			return -EFAULT;
+		if (mode)
+			port->ops->data_reverse (port);
+		else
+			port->ops->data_forward (port);
+		return 0;
+
+	case PPNEGOT:
+		if (copy_from_user (&mode, (int *) arg, sizeof (mode)))
+			return -EFAULT;
+		/* FIXME: validate mode */
+		return parport_negotiate (port, mode);
+
+	default:
+		printk (KERN_DEBUG CHRDEV "%02x: What? (cmd=0x%x\n", minor,
+			cmd);
+		return -EINVAL;
+	}
+
+ /* Keep the compiler happy */
+	return 0;
+}
+
+static int pp_open (struct inode * inode, struct file * file)
+{
+	unsigned int minor = MINOR (inode->i_rdev);
+	unsigned int portnum = PP_PORT (minor);
+	unsigned int dev = PP_DEV (minor);
+
+	if (portnum >= PARPORT_MAX)
+		return -ENXIO;
+
+	if (pp_table[portnum][dev].pdev)
+		return -EBUSY;
+
+	pp_table[portnum][dev].mode = IEEE1284_MODE_COMPAT;
+	pp_table[portnum][dev].flags = 0;
+	init_waitqueue_head (&pp_table[portnum][dev].irq_wait);
+
+	/* Defer the actual device registration until the first claim.
+	 * That way, we know whether or not the driver wants to have
+	 * exclusive access to the port (PPEXCL).
+	 */
+	pp_table[portnum][dev].pdev = NULL;
+
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int pp_release (struct inode * inode, struct file * file)
+{
+	unsigned int minor = MINOR (inode->i_rdev);
+	unsigned int portnum = PP_PORT (minor);
+	unsigned int dev = PP_DEV (minor);
+
+	if (pp_table[portnum][dev].flags & PP_CLAIMED) {
+		parport_release (pp_table[portnum][dev].pdev);
+		printk (KERN_DEBUG CHRDEV "%02x: released pardevice because "
+			"user-space forgot\n", minor);
+	}
+
+	if (pp_table[portnum][dev].pdev) {
+		kfree (pp_table[portnum][dev].pdev->name);
+		parport_unregister_device (pp_table[portnum][dev].pdev);
+		pp_table[portnum][dev].pdev = NULL;
+		printk (KERN_DEBUG CHRDEV "%02x: unregistered pardevice\n",
+			minor);
+	}
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+#if 0
+static unsigned int pp_poll (struct file * file, poll_table * wait)
+{
+	unsigned int minor = MINOR (file->f_dentry->d_inode->i_rdev);
+	poll_wait (file, &pp_table[minor].irq_wait, wait);
+	return 0; /* FIXME! Return value is wrong here */
+}
+#endif
+
+static struct file_operations pp_fops = {
+	pp_lseek,
+	pp_read,
+	pp_write,
+	NULL,	/* pp_readdir */
+	NULL,   /* pp_poll */
+	pp_ioctl,
+	NULL,	/* pp_mmap */
+	pp_open,
+	NULL,   /* pp_flush */
+	pp_release
+};
+
+#ifdef MODULE
+#define pp_init init_module
+#endif
+
+int pp_init (void)
+{
+	if (register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) {
+		printk (KERN_WARNING CHRDEV ": unable to get major %d\n",
+			PP_MAJOR);
+		return -EIO;
+	}
+
+ printk (KERN_INFO PP_VERSION "\n");
+	return 0;
+}
+
+#ifdef MODULE
+void cleanup_module (void)
+{
+	/* Clean up all parport stuff */
+	unregister_chrdev (PP_MAJOR, CHRDEV);
+}
+#endif /* MODULE */
diff -u --recursive --new-file v2.3.9/linux/drivers/char/ppdev.h linux/drivers/char/ppdev.h
--- v2.3.9/linux/drivers/char/ppdev.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/ppdev.h	Mon Jul  5 20:31:26 1999
@@ -0,0 +1,65 @@
+/*
+ * linux/drivers/char/ppdev.h
+ *
+ * User-space parallel port device driver (header file).
+ *
+ * Copyright (C) 1998-9 Tim Waugh <t...@cyberelk.demon.co.uk>
+ *
+ * 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.
+ *
+ */
+
+#define PP_MAJOR	99
+
+#define PP_IOCTL	'p'
+
+/* Set mode for read/write (e.g. IEEE1284_MODE_EPP) */
+#define PPSETMODE	_IOW(PP_IOCTL, 0x80, int)
+
+/* Read status */
+#define PPRSTATUS	_IOR(PP_IOCTL, 0x81, unsigned char)
+#define PPWSTATUS	OBSOLETE__IOW(PP_IOCTL, 0x82, unsigned char)
+
+/* Read/write control */
+#define PPRCONTROL	_IOR(PP_IOCTL, 0x83, unsigned char)
+#define PPWCONTROL	_IOW(PP_IOCTL, 0x84, unsigned char)
+
+struct ppdev_frob_struct {
+	unsigned char mask;
+	unsigned char val;
+};
+#define PPFCONTROL      _IOW(PP_IOCTL, 0x8e, struct ppdev_frob_struct)
+
+/* Read/write data */
+#define PPRDATA		_IOR(PP_IOCTL, 0x85, unsigned char)
+#define PPWDATA		_IOW(PP_IOCTL, 0x86, unsigned char)
+
+/* Read/write econtrol (not used) */
+#define PPRECONTROL	OBSOLETE__IOR(PP_IOCTL, 0x87, unsigned char)
+#define PPWECONTROL	OBSOLETE__IOW(PP_IOCTL, 0x88, unsigned char)
+
+/* Read/write FIFO (not used) */
+#define PPRFIFO		OBSOLETE__IOR(PP_IOCTL, 0x89, unsigned char)
+#define PPWFIFO		OBSOLETE__IOW(PP_IOCTL, 0x8a, unsigned char)
+
+/* Claim the port to start using it */
+#define PPCLAIM		_IO(PP_IOCTL, 0x8b)
+
+/* Release the port when you aren't using it */
+#define PPRELEASE	_IO(PP_IOCTL, 0x8c)
+
+/* Yield the port (release it if another driver is waiting,
+ * then reclaim) */
+#define PPYIELD		_IO(PP_IOCTL, 0x8d)
+
+/* Register device exclusively (must be before PPCLAIM). */
+#define PPEXCL		_IO(PP_IOCTL, 0x8f)
+
+/* Data line direction: non-zero for input mode. */
+#define PPDATADIR	_IOW(PP_IOCTL, 0x90, int)
+
+/* Negotiate a particular IEEE 1284 mode. */
+#define PPNEGOT		_IOW(PP_IOCTL, 0x91, int)
diff -u --recursive --new-file v2.3.9/linux/drivers/char/radio-aimslab.c linux/drivers/char/radio-aimslab.c
--- v2.3.9/linux/drivers/char/radio-aimslab.c	Thu Apr 15 05:42:40 1999
+++ linux/drivers/char/radio-aimslab.c	Mon Jul  5 20:07:02 1999
@@ -324,7 +324,7 @@
X 	NULL
X };
X 
-__initfunc(int rtrack_init(struct video_init *v))
+int __init rtrack_init(struct video_init *v)
X {
X 	if (check_region(io, 2)) 
X 	{
diff -u --recursive --new-file v2.3.9/linux/drivers/char/radio-aztech.c linux/drivers/char/radio-aztech.c
--- v2.3.9/linux/drivers/char/radio-aztech.c	Thu Apr 15 05:42:40 1999
+++ linux/drivers/char/radio-aztech.c	Mon Jul  5 20:07:02 1999
@@ -279,7 +279,7 @@
X 	NULL
X };
X 
-__initfunc(int aztech_init(struct video_init *v))
+int __init aztech_init(struct video_init *v)
X {
X 	if (check_region(io, 2)) 
X 	{
diff -u --recursive --new-file v2.3.9/linux/drivers/char/radio-cadet.c linux/drivers/char/radio-cadet.c
--- v2.3.9/linux/drivers/char/radio-cadet.c	Mon Jun  7 16:17:59 1999
+++ linux/drivers/char/radio-cadet.c	Mon Jul  5 20:07:02 1999
@@ -1,7 +1,7 @@
-/* cadet.c - A video4linux driver for the ADS Cadet AM/FM Radio Card 
+/* radio-cadet.c - A video4linux driver for the ADS Cadet AM/FM Radio Card 
X  *
X  * by Fred Gleason <fr...@wava.com>
- * Version 0.3.2
+ * Version 0.3.3
X  *
X  * (Loosely) based on code for the Aztech radio card by
X  *
@@ -346,17 +346,13 @@
X static long cadet_read(struct video_device *v,char *buf,unsigned long count,
X 		       int nonblock)
X {
-        int i=0,c;
+        int i=0;
X 	unsigned char readbuf[RDS_BUFFER];
X 
X         if(rdsstat==0) {
X 	        cadet_lock++;
X 	        rdsstat=1;
X 		outb(0x80,io);        /* Select RDS fifo */
-		c=3*(inb(io)&0x03);
-		for(i=0;i<c;i++) {    /* Flush the fifo */
-		        inb(io+1);
-		}
X 		cadet_lock--;
X 		init_timer(&readtimer);
X 		readtimer.function=cadet_handler;
@@ -546,7 +542,7 @@
X 	NULL
X };
X 
-__initfunc(int cadet_init(struct video_init *v))
+int __init cadet_init(struct video_init *v)
X {
X #ifndef MODULE        
X         if(cadet_probe()<0) {
diff -u --recursive --new-file v2.3.9/linux/drivers/char/radio-gemtek.c linux/drivers/char/radio-gemtek.c
--- v2.3.9/linux/drivers/char/radio-gemtek.c	Thu Apr 15 05:42:40 1999
+++ linux/drivers/char/radio-gemtek.c	Mon Jul  5 20:07:02 1999
@@ -250,7 +250,7 @@
X 	NULL
X };
X 
-__initfunc(int gemtek_init(struct video_init *v))
+int __init gemtek_init(struct video_init *v)
X {
X 	if (check_region(io, 4)) 
X 	{
@@ -282,7 +282,7 @@
X MODULE_AUTHOR("Jonas Munsin");
X MODULE_DESCRIPTION("A driver for the GemTek Radio Card");
X MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "I/O address of the GemTek card (0x20c, 0x30c, 0x24c or 0x34c)");
+MODULE_PARM_DESC(io, "I/O address of the GemTek card (0x20c, 0x30c, 0x24c or 0x34c (or 0x248 for the combined sound/radiocard))");
X 
X EXPORT_NO_SYMBOLS;
X 
@@ -290,7 +290,7 @@
X {
X 	if(io==-1)
X 	{
-		printk(KERN_ERR "You must set an I/O address with io=0x20c, io=0x30c, io=0x24c or io=0x34c\n");
+		printk(KERN_ERR "You must set an I/O address with io=0x20c, io=0x30c, io=0x24c or io=0x34c (or io=0x248 for the combined sound/radiocard)\n");
X 		return -EINVAL;
X 	}
X 	return gemtek_init(NULL);
diff -u --recursive --new-file v2.3.9/linux/drivers/char/radio-miropcm20.c linux/drivers/char/radio-miropcm20.c
--- v2.3.9/linux/drivers/char/radio-miropcm20.c	Thu Apr 15 05:42:40 1999
+++ linux/drivers/char/radio-miropcm20.c	Mon Jul  5 20:07:02 1999
@@ -205,7 +205,7 @@
X 	NULL
X };
X 
-__initfunc(int pcm20_init(struct video_init *v))
+int __init pcm20_init(struct video_init *v)
X {
X 
X 	pcm20_radio.priv=&pcm20_unit;
diff -u --recursive --new-file v2.3.9/linux/drivers/char/radio-rtrack2.c linux/drivers/char/radio-rtrack2.c
--- v2.3.9/linux/drivers/char/radio-rtrack2.c	Thu Apr 15 05:42:40 1999
+++ linux/drivers/char/radio-rtrack2.c	Mon Jul  5 20:07:02 1999
@@ -218,7 +218,7 @@
X 	NULL
X };
X 
-__initfunc(int rtrack2_init(struct video_init *v))
+int __init rtrack2_init(struct video_init *v)
X {
X 	if (check_region(io, 4)) 
X 	{
diff -u --recursive --new-file v2.3.9/linux/drivers/char/radio-sf16fmi.c linux/drivers/char/radio-sf16fmi.c
--- v2.3.9/linux/drivers/char/radio-sf16fmi.c	Sat Apr 24 17:49:37 1999
+++ linux/drivers/char/radio-sf16fmi.c	Mon Jul  5 20:07:02 1999
@@ -276,7 +276,7 @@
X 	NULL
X };
X 
-__initfunc(int fmi_init(struct video_init *v))
+int __init fmi_init(struct video_init *v)
X {
X 	if (check_region(io, 2)) 
X 	{
diff -u --recursive --new-file v2.3.9/linux/drivers/char/radio-terratec.c linux/drivers/char/radio-terratec.c
--- v2.3.9/linux/drivers/char/radio-terratec.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/radio-terratec.c	Mon Jul  5 20:07:02 1999
@@ -0,0 +1,353 @@
+/* Terratec ActiveRadio ISA Standalone card driver for Linux radio support
+ * (c) 1999 R. Offermanns (ro...@offermanns.de)
+ * based on the aimslab radio driver from M. Kirkwood
+ * many thanks to Michael Becker and Friedhelm Birth (from TerraTec)
+ * 
+ *
+ * History:
+ * 1999-05-21	First preview release
+ * 
+ *  Notes on the hardware:
+ *  There are two "main" chips on the card:
+ *  - Philips OM5610 (http://www-us.semiconductors.philips.com/acrobat/datasheets/OM5610_2.pdf)
+ *  - Philips SAA6588 (http://www-us.semiconductors.philips.com/acrobat/datasheets/SAA6588_1.pdf)
+ *  (you can get the datasheet at the above links)
+ *
+ *  Frequency control is done digitally -- ie out(port,encodefreq(95.8));
+ *  Volume Control is done digitally
+ *
+ *  there is a I2C controlled RDS decoder (SAA6588)  onboard, which i would like to support someday
+ *  (as soon i have understand how to get started :)
+ *  If you can help me out with that, please contact me!!
+ *
+ *  
+ */
+
+#include <linux/module.h>	/* Modules 			*/
+#include <linux/init.h>		/* Initdata			*/
+#include <linux/ioport.h>	/* check_region, request_region	*/
+#include <linux/delay.h>	/* udelay			*/
+#include <asm/io.h>		/* outb, outb_p			*/
+#include <asm/uaccess.h>	/* copy to/from user		*/
+#include <linux/videodev.h>	/* kernel radio structs		*/
+#include <linux/config.h>	/* CONFIG_RADIO_TERRATEC_PORT 	*/
+
+#ifndef CONFIG_RADIO_TERRATEC_PORT
+#define CONFIG_RADIO_TERRATEC_PORT 0x590
+#endif
+
+/**************** this ones are for the terratec *******************/
+#define BASEPORT 	0x590
+#define VOLPORT 	0x591
+#define WRT_DIS 	0x00
+#define CLK_OFF		0x00
+#define IIC_DATA	0x01
+#define IIC_CLK		0x02
+#define DATA		0x04
+#define CLK_ON 		0x08
+#define WRT_EN		0x10
+/*******************************************************************/
+
+static int io = CONFIG_RADIO_TERRATEC_PORT; 
+static int users = 0;
+
+struct tt_device
+{
+	int port;
+	int curvol;
+	unsigned long curfreq;
+	int muted;
+};
+
+
+/* local things */
+
+static void cardWriteVol(int volume)
+{
+	int i;
+	volume = volume+(volume * 32); // change both channels
+	for (i=0;i<8;i++)
+	{
+		if (volume & (0x80>>i))
+			outb(0x80, VOLPORT);
+		else outb(0x00, VOLPORT);
+	}
+}
+
+
+
+static void tt_mute(struct tt_device *dev)
+{
+	dev->muted = 1;
+	cardWriteVol(0);
+}
+
+static int tt_setvol(struct tt_device *dev, int vol)
+{
+	
+//	printk(KERN_ERR "setvol called, vol = %d\n", vol);
+
+	if(vol == dev->curvol) {	/* requested volume = current */
+		if (dev->muted) {	/* user is unmuting the card  */
+			dev->muted = 0;
+			cardWriteVol(vol);	/* enable card */
+		}	
+	
+		return 0;
+	}
+
+	if(vol == 0) {			/* volume = 0 means mute the card */
+		cardWriteVol(0);	/* "turn off card" by setting vol to 0 */
+		dev->curvol = vol;	/* track the volume state!	*/
+		return 0;
+	}
+
+	dev->muted = 0;
+	
+	cardWriteVol(vol);
+	 
+	dev->curvol = vol;
+
+	return 0;
+
+}
+
+
+/* this is the worst part in this driver */
+/* many more or less strange things are going on here, but hey, it works :) */
+
+static int tt_setfreq(struct tt_device *dev, unsigned long freq1)
+{	
+	int freq;
+	int i;
+	int p;
+	int  temp;
+	long rest;
+     
+	unsigned char buffer[25];		/* we have to bit shift 25 registers */
+	freq = freq1/160;			/* convert the freq. to a nice to handel value */
+	for(i=24;i>-1;i--)
+		buffer[i]=0;
+
+	rest = freq*10+10700;		/* i once had understood what is going on here */
+					/* maybe some wise guy (friedhelm?) can comment this stuff */
+	i=13;
+	p=10;
+	temp=102400;
+	while (rest!=0)
+	{
+		if (rest%temp  == rest)
+			buffer[i] = 0;
+		else 
+		{
+			buffer[i] = 1; 
+			rest = rest-temp;
+		}
+		i--;
+		p--;
+		temp = temp/2;
+       }
+
+	for (i=24;i>-1;i--)			/* bit shift the values to the radiocard */
+	{
+		if (buffer[i]==1) 
+		{
+			outb(WRT_EN|DATA, BASEPORT);
+			outb(WRT_EN|DATA|CLK_ON  , BASEPORT);
+			outb(WRT_EN|DATA, BASEPORT);
+		}
+		else
+		{
+			outb(WRT_EN|0x00, BASEPORT);
+			outb(WRT_EN|0x00|CLK_ON  , BASEPORT);
+		}
+	}
+	outb(0x00, BASEPORT);     
+  
+  	return 0;
+}
+
+int tt_getsigstr(struct tt_device *dev)		/* TODO */
+{
+	if (inb(io) & 2)	/* bit set = no signal present	*/
+		return 0;
+	return 1;		/* signal present		*/
+}
+
+
+/* implement the video4linux api */
+
+static int tt_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+	struct tt_device *tt=dev->priv;
+	
+	switch(cmd)
+	{
+		case VIDIOCGCAP:
+		{
+			struct video_capability v;
+			v.type=VID_TYPE_TUNER;
+			v.channels=1;
+			v.audios=1;
+			/* No we don't do pictures */
+			v.maxwidth=0;
+			v.maxheight=0;
+			v.minwidth=0;
+			v.minheight=0;
+			strcpy(v.name, "ActiveRadio");
+			if(copy_to_user(arg,&v,sizeof(v)))
+				return -EFAULT;
+			return 0;
+		}
+		case VIDIOCGTUNER:
+		{
+			struct video_tuner v;
+			if(copy_from_user(&v, arg,sizeof(v))!=0) 
+				return -EFAULT;
+			if(v.tuner)	/* Only 1 tuner */ 
+				return -EINVAL;
+			v.rangelow=(87*16000);
+			v.rangehigh=(108*16000);
+			v.flags=VIDEO_TUNER_LOW;
+			v.mode=VIDEO_MODE_AUTO;
+			strcpy(v.name, "FM");
+			v.signal=0xFFFF*tt_getsigstr(tt);
+			if(copy_to_user(arg,&v, sizeof(v)))
+				return -EFAULT;
+			return 0;
+		}
+		case VIDIOCSTUNER:
+		{
+			struct video_tuner v;
+			if(copy_from_user(&v, arg, sizeof(v)))
+				return -EFAULT;
+			if(v.tuner!=0)
+				return -EINVAL;
+			/* Only 1 tuner so no setting needed ! */
+			return 0;
+		}
+		case VIDIOCGFREQ:
+			if(copy_to_user(arg, &tt->curfreq, sizeof(tt->curfreq)))
+				return -EFAULT;
+			return 0;
+		case VIDIOCSFREQ:
+			if(copy_from_user(&tt->curfreq, arg,sizeof(tt->curfreq)))
+				return -EFAULT;
+			tt_setfreq(tt, tt->curfreq);
+			return 0;
+		case VIDIOCGAUDIO:
+		{	
+			struct video_audio v;
+			memset(&v,0, sizeof(v));
+			v.flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
+			v.volume=tt->curvol * 6554;
+			v.step=6554;
+			strcpy(v.name, "Radio");
+			if(copy_to_user(arg,&v, sizeof(v)))
+				return -EFAULT;
+			return 0;			
+		}
+		case VIDIOCSAUDIO:
+		{
+			struct video_audio v;
+			if(copy_from_user(&v, arg, sizeof(v))) 
+				return -EFAULT;	
+			if(v.audio) 
+				return -EINVAL;
+
+			if(v.flags&VIDEO_AUDIO_MUTE) 
+				tt_mute(tt);
+			else
+				tt_setvol(tt,v.volume/6554);	
+
+			return 0;
+		}
+		default:
+			return -ENOIOCTLCMD;
+	}
+}
+
+static int tt_open(struct video_device *dev, int flags)
+{
+	if(users)
+		return -EBUSY;
+	users++;
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static void tt_close(struct video_device *dev)
+{
+	users--;
+	MOD_DEC_USE_COUNT;
+}
+
+static struct tt_device terratec_unit;
+
+static struct video_device terratec_radio=
+{
+	"TerraTec ActiveRadio",
+	VID_TYPE_TUNER,
+	VID_HARDWARE_TERRATEC,
+	tt_open,
+	tt_close,
+	NULL,	/* Can't read  (no capture ability) */
+	NULL,	/* Can't write */
+	NULL,	/* No poll */
+	tt_ioctl,
+	NULL,
+	NULL
+};
+
+__initfunc(int terratec_init(struct video_init *v))
+{
+	if (check_region(io, 2)) 
+	{
+		printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io);
+		return -EBUSY;
+	}
+
+	terratec_radio.priv=&terratec_unit;
+	
+	if(video_register_device(&terratec_radio, VFL_TYPE_RADIO)==-1)
+		return -EINVAL;
+		
+	request_region(io, 2, "terratec");
+	printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver.\n");
+
+ 	/* mute card - prevents noisy bootups */
+
+	/* this ensures that the volume is all the way down  */
+	cardWriteVol(0);
+	terratec_unit.curvol = 0;
+
+	return 0;
+}
+
+#ifdef MODULE
+
+MODULE_AUTHOR("R.OFFERMANNS & others");
+MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
+MODULE_PARM(io, "i");
+MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)");
+
+EXPORT_NO_SYMBOLS;
+
+int init_module(void)
+{
+	if(io==-1)
+	{
+		printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+		return -EINVAL;
+	}
+	return terratec_init(NULL);
+}
+
+void cleanup_module(void)
+{
+	video_unregister_device(&terratec_radio);
+	release_region(io,2);
+	printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n");	
+}
+
+#endif
diff -u --recursive --new-file v2.3.9/linux/drivers/char/radio-zoltrix.c linux/drivers/char/radio-zoltrix.c
--- v2.3.9/linux/drivers/char/radio-zoltrix.c	Mon May 10 13:00:10 1999
+++ linux/drivers/char/radio-zoltrix.c	Mon Jul  5 20:07:02 1999
@@ -333,7 +333,7 @@
X 	NULL
X };
X 
-__initfunc(int zoltrix_init(struct video_init *v))
+int __init zoltrix_init(struct video_init *v)
X {
X 	if (check_region(io, 2)) {
X 		printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io);
diff -u --recursive --new-file v2.3.9/linux/drivers/char/rocket.c linux/drivers/char/rocket.c
--- v2.3.9/linux/drivers/char/rocket.c	Wed May 12 13:27:37 1999
+++ linux/drivers/char/rocket.c	Mon Jul  5 20:35:18 1999
@@ -57,14 +57,13 @@
X #ifdef MODVERSIONS
X #include <linux/modversions.h>
X #endif
-#include <linux/module.h>
X #else /* !NEW_MODULES */
X #ifdef MODVERSIONS
X #define MODULE
X #endif
-#include <linux/module.h>
X #endif /* NEW_MODULES */
X 
+#include <linux/module.h>
X #include <linux/errno.h>
X #include <linux/major.h>
X #include <linux/kernel.h>
@@ -154,7 +153,6 @@
X /*
X  * NB. we must include the kernel idenfication string in to install the module.
X  */
-#include <linux/version.h>
X /*static*/ char kernel_version[] = UTS_RELEASE;
X #endif
X 
@@ -1664,7 +1662,6 @@
X 		       jiffies, check_time);
X #endif
X 		current->state = TASK_INTERRUPTIBLE;
-		current->counter = 0;	/* make us low-priority */
X schedule_timeout(check_time);
X 		if (signal_pending(current))
X 			break;
diff -u --recursive --new-file v2.3.9/linux/drivers/char/saa7111.c linux/drivers/char/saa7111.c
--- v2.3.9/linux/drivers/char/saa7111.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/saa7111.c	Mon Jul  5 20:07:02 1999
@@ -0,0 +1,421 @@
+/* 
+   saa7111 - Philips SAA7111A video decoder driver version 0.0.3
+
+   Copyright (C) 1998 Dave Perks <dpe...@ibm.net>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/malloc.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/signal.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <linux/sched.h>
+#include <asm/segment.h>
+#include <linux/types.h>
+#include <linux/wrapper.h>
+
+#include <linux/videodev.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+
+#include <linux/i2c.h>
+#include <linux/video_decoder.h>
+
+#define DEBUG(x)		/* Debug driver */
+
+/* ----------------------------------------------------------------------- */
+
+struct saa7111 {
+	struct i2c_bus *bus;
+	int addr;
+	unsigned char reg[32];
+
+	int norm;
+	int input;
+	int enable;
+	int bright;
+	int contrast;
+	int hue;
+	int sat;
+};
+
+#define   I2C_SAA7111        0x48
+
+#define   I2C_DELAY   10
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7111_write(struct saa7111 *dev, unsigned char subaddr, unsigned char data)
+{
+	int ack;
+	unsigned long flags;
+
+	LOCK_I2C_BUS(dev->bus);
+	i2c_start(dev->bus);
+	i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
+	i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
+	ack = i2c_sendbyte(dev->bus, data, I2C_DELAY);
+	dev->reg[subaddr] = data;
+	i2c_stop(dev->bus);
+	UNLOCK_I2C_BUS(dev->bus);
+	return ack;
+}
+
+static int saa7111_write_block(struct saa7111 *dev, unsigned const char *data, unsigned int len)
+{
+	int ack;
+	unsigned subaddr;
+	unsigned long flags;
+
+	while (len > 1) {
+		LOCK_I2C_BUS(dev->bus);
+		i2c_start(dev->bus);
+		i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
+		ack = i2c_sendbyte(dev->bus, (subaddr = *data++), I2C_DELAY);
+		ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
+		len -= 2;
+		while (len > 1 && *data == ++subaddr) {
+			data++;
+			ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
+			len -= 2;
+		}
+		i2c_stop(dev->bus);
+		UNLOCK_I2C_BUS(dev->bus);
+	}
+	return ack;
+}
+
+static int saa7111_read(struct saa7111 *dev, unsigned char subaddr)
+{
+	int data;
+	unsigned long flags;
+
+	LOCK_I2C_BUS(dev->bus);
+	i2c_start(dev->bus);
+	i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
+	i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
+	i2c_start(dev->bus);
+	i2c_sendbyte(dev->bus, dev->addr | 1, I2C_DELAY);
+	data = i2c_readbyte(dev->bus, 1);
+	i2c_stop(dev->bus);
+	UNLOCK_I2C_BUS(dev->bus);
+	return data;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7111_attach(struct i2c_device *device)
+{
+	int i;
+	struct saa7111 *decoder;
+
+	static const unsigned char init[] =
+	{
+		0x00, 0x00,	/* 00 - ID byte */
+		0x01, 0x00,	/* 01 - reserved */
+
+	/*front end */
+		0x02, 0xd0,	/* 02 - FUSE=3, GUDL=2, MODE=0 */
+		0x03, 0x23,	/* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
+		0x04, 0x00,	/* 04 - GAI1=256 */
+		0x05, 0x00,	/* 05 - GAI2=256 */
+
+	/* decoder */
+		0x06, 0xf6,	/* 06 - HSB at  13(50Hz) /  17(60Hz) pixels after end of last line */
+		0x07, 0xdd,	/* 07 - HSS at 113(50Hz) / 117(60Hz) pixels after end of last line */
+		0x08, 0xc8,	/* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1, HPLL=0, VNOI=0 */
+		0x09, 0x01,	/* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0, UPTCV=0, APER=1 */
+		0x0a, 0x80,	/* 0a - BRIG=128 */
+		0x0b, 0x47,	/* 0b - CONT=1.109 */
+		0x0c, 0x40,	/* 0c - SATN=1.0 */
+		0x0d, 0x00,	/* 0d - HUE=0 */
+		0x0e, 0x01,	/* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
+		0x0f, 0x00,	/* 0f - reserved */
+		0x10, 0x48,	/* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
+		0x11, 0x1c,	/* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
+		0x12, 0x00,	/* 12 - output control 2 */
+		0x13, 0x00,	/* 13 - output control 3 */
+		0x14, 0x00,	/* 14 - reserved */
+		0x15, 0x00,	/* 15 - VBI */
+		0x16, 0x00,	/* 16 - VBI */
+		0x17, 0x00,	/* 17 - VBI */
+	};
+
+	device->data = decoder = kmalloc(sizeof(struct saa7111), GFP_KERNEL);
+	if (decoder == NULL) {
+		return -ENOMEM;
+	}
+	MOD_INC_USE_COUNT;
+
+	memset(decoder, 0, sizeof(struct saa7111));
+	strcpy(device->name, "saa7111");
+	decoder->bus = device->bus;
+	decoder->addr = device->addr;
+	decoder->norm = VIDEO_MODE_NTSC;
+	decoder->input = 0;
+	decoder->enable = 1;
+	decoder->bright = 32768;
+	decoder->contrast = 32768;
+	decoder->hue = 32768;
+	decoder->sat = 32768;
+
+	i = saa7111_write_block(decoder, init, sizeof(init));
+	if (i < 0) {
+		printk(KERN_ERR "%s_attach: init status %d\n", device->name, i);
+	} else {
+		printk(KERN_INFO "%s_attach: chip version %x\n", device->name, saa7111_read(decoder, 0x00));
+	}
+	return 0;
+}
+
+
+static int saa7111_detach(struct i2c_device *device)
+{
+	kfree(device->data);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static int saa7111_command(struct i2c_device *device, unsigned int cmd, void *arg)
+{
+	struct saa7111 *decoder = device->data;
+
+	switch (cmd) {
+
+#if defined(DECODER_DUMP)
+	case DECODER_DUMP:
+		{
+			int i;
+
+			for (i = 0; i < 32; i += 16) {
+				int j;
+
+				printk("KERN_DEBUG %s: %03x", device->name, i);
+				for (j = 0; j < 16; ++j) {
+					printk(" %02x", saa7111_read(decoder, i + j));
+				}
+				printk("\n");
+			}
+		}
+		break;
+#endif				/* defined(DECODER_DUMP) */
+
+	case DECODER_GET_CAPABILITIES:
+		{
+			struct video_decoder_capability *cap = arg;
+
+			cap->flags
+			    = VIDEO_DECODER_PAL
+			    | VIDEO_DECODER_NTSC
+			    | VIDEO_DECODER_AUTO
+			    | VIDEO_DECODER_CCIR;
+			cap->inputs = 8;
+			cap->outputs = 1;
+		}
+		break;
+
+	case DECODER_GET_STATUS:
+		{
+			int *iarg = arg;
+			int status;
+			int res;
+
+			status = saa7111_read(decoder, 0x1f);
+			res = 0;
+			if ((status & (1 << 6)) == 0) {
+				res |= DECODER_STATUS_GOOD;
+			}
+			switch (decoder->norm) {
+			case VIDEO_MODE_NTSC:
+				res |= DECODER_STATUS_NTSC;
+				break;
+			case VIDEO_MODE_PAL:
+				res |= DECODER_STATUS_PAL;
+				break;
+			default:
+			case VIDEO_MODE_AUTO:
+				if ((status & (1 << 5)) != 0) {
+					res |= DECODER_STATUS_NTSC;
+				} else {
+					res |= DECODER_STATUS_PAL;
+				}
+				break;
+			}
+			if ((status & (1 << 0)) != 0) {
+				res |= DECODER_STATUS_COLOR;
+			}
+			*iarg = res;
+		}
+		break;
+
+	case DECODER_SET_NORM:
+		{
+			int *iarg = arg;
+
+			switch (*iarg) {
+
+			case VIDEO_MODE_NTSC:
+				saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0x3f) | 0x40);
+				break;
+
+			case VIDEO_MODE_PAL:
+				saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0x3f) | 0x00);
+				break;
+
+			case VIDEO_MODE_AUTO:
+				saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0x3f) | 0x80);
+				break;
+
+			default:
+				return -EINVAL;
+
+			}
+			decoder->norm = *iarg;
+		}
+		break;
+
+	case DECODER_SET_INPUT:
+		{
+			int *iarg = arg;
+
+			if (*iarg < 0 || *iarg > 7) {
+				return -EINVAL;
+			}
+			if (decoder->input != *iarg) {
+				decoder->input = *iarg;
+				/* select mode */
+				saa7111_write(decoder, 0x02, (decoder->reg[0x02] & 0xf8) | decoder->input);
+				/* bypass chrominance trap for modes 4..7 */
+				saa7111_write(decoder, 0x09, (decoder->reg[0x09] & 0x7f) | ((decoder->input > 3) ? 0x80 : 0));
+			}
+		}
+		break;
+
+	case DECODER_SET_OUTPUT:
+		{
+			int *iarg = arg;
+
+			/* not much choice of outputs */
+			if (*iarg != 0) {
+				return -EINVAL;
+			}
+		}
+		break;
+
+	case DECODER_ENABLE_OUTPUT:
+		{
+			int *iarg = arg;
+			int enable = (*iarg != 0);
+
+			if (decoder->enable != enable) {
+				decoder->enable = enable;
+
+// RJ: If output should be disabled (for playing videos), we also need a open PLL.
+				//     The input is set to 0 (where no input source is connected), although this
+				//     is not necessary.
+				//
+				//     If output should be enabled, we have to reverse the above.
+
+				if (decoder->enable) {
+					saa7111_write(decoder, 0x02, (decoder->reg[0x02] & 0xf8) | decoder->input);
+					saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0xfb));
+					saa7111_write(decoder, 0x11, (decoder->reg[0x11] & 0xf3) | 0x0c);
+				} else {
+					saa7111_write(decoder, 0x02, (decoder->reg[0x02] & 0xf8));
+					saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0xfb) | 0x04);
+					saa7111_write(decoder, 0x11, (decoder->reg[0x11] & 0xf3));
+				}
+			}
+		}
+		break;
+
+	case DECODER_SET_PICTURE:
+		{
+			struct video_picture *pic = arg;
+
+			if (decoder->bright != pic->brightness) {
+				/* We want 0 to 255 we get 0-65535 */
+				decoder->bright = pic->brightness;
+				saa7111_write(decoder, 0x0a, decoder->bright >> 8);
+			}
+			if (decoder->contrast != pic->contrast) {
+				/* We want 0 to 127 we get 0-65535 */
+				decoder->contrast = pic->contrast;
+				saa7111_write(decoder, 0x0b, decoder->contrast >> 9);
+			}
+			if (decoder->sat != pic->colour) {
+				/* We want 0 to 127 we get 0-65535 */
+				decoder->sat = pic->colour;
+				saa7111_write(decoder, 0x0c, decoder->sat >> 9);
+			}
+			if (decoder->hue != pic->hue) {
+				/* We want -128 to 127 we get 0-65535 */
+				decoder->hue = pic->hue;
+				saa7111_write(decoder, 0x0d, (decoder->hue - 32768) >> 8);
+			}
+		}
+		break;
+
+	default:
+ return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+struct i2c_driver i2c_driver_saa7111 =
+{
+	"saa7111",		/* name */
+	I2C_DRIVERID_VIDEODECODER,	/* ID */
+	I2C_SAA7111, I2C_SAA7111 + 1,
+
+	saa7111_attach,
+	saa7111_detach,
+	saa7111_command
+};
+
+EXPORT_NO_SYMBOLS;
+
+#ifdef MODULE
+int init_module(void)
+#else
+int saa7111_init(void)
+#endif
+{
+	return i2c_register_driver(&i2c_driver_saa7111);
+}
+
+
+
+#ifdef MODULE
+
+void cleanup_module(void)
+{
+	i2c_unregister_driver(&i2c_driver_saa7111);
+}
+
+#endif
diff -u --recursive --new-file v2.3.9/linux/drivers/char/saa7185.c linux/drivers/char/saa7185.c
--- v2.3.9/linux/drivers/char/saa7185.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/saa7185.c	Mon Jul  5 20:07:02 1999
@@ -0,0 +1,379 @@
+/* 
+   saa7185 - Philips SAA7185B video encoder driver version 0.0.3
+
+   Copyright (C) 1998 Dave Perks <dpe...@ibm.net>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/malloc.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/signal.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <linux/sched.h>
+#include <asm/segment.h>
+#include <linux/types.h>
+#include <linux/wrapper.h>
+
+#include <linux/videodev.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+
+#include <linux/i2c.h>
+#include <linux/video_encoder.h>
+
+#define DEBUG(x)   x		/* Debug driver */
+
+/* ----------------------------------------------------------------------- */
+
+struct saa7185 {
+	struct i2c_bus *bus;
+	int addr;
+	unsigned char reg[128];
+
+	int norm;
+	int enable;
+	int bright;
+	int contrast;
+	int hue;
+	int sat;
+};
+
+#define   I2C_SAA7185        0x88
+
+#define I2C_DELAY   10
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7185_write(struct saa7185 *dev, unsigned char subaddr, unsigned char data)
+{
+	int ack;
+	unsigned long flags;
+
+	LOCK_I2C_BUS(dev->bus);
+
+	i2c_start(dev->bus);
+	i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
+	i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
+	ack = i2c_sendbyte(dev->bus, data, I2C_DELAY);
+	dev->reg[subaddr] = data;
+	i2c_stop(dev->bus);
+	UNLOCK_I2C_BUS(dev->bus);
+	return ack;
+}
+
+static int saa7185_write_block(struct saa7185 *dev, unsigned const char *data, unsigned int len)
+{
+	int ack;
+	unsigned subaddr;
+	unsigned long flags;
+
+	while (len > 1) {
+		LOCK_I2C_BUS(dev->bus);
+		i2c_start(dev->bus);
+		i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
+		ack = i2c_sendbyte(dev->bus, (subaddr = *data++), I2C_DELAY);
+		ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
+		len -= 2;
+		while (len > 1 && *data == ++subaddr) {
+			data++;
+			ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
+			len -= 2;
+		}
+		i2c_stop(dev->bus);
+		UNLOCK_I2C_BUS(dev->bus);
+	}
+	return ack;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const unsigned char init_common[] =
+{
+	0x3a, 0x0f,		/* CBENB=0, V656=0, VY2C=1, YUV2C=1, MY2C=1, MUV2C=1 */
+
+	0x42, 0x6b,		/* OVLY0=107 */
+	0x43, 0x00,		/* OVLU0=0     white */
+	0x44, 0x00,		/* OVLV0=0   */
+	0x45, 0x22,		/* OVLY1=34  */
+	0x46, 0xac,		/* OVLU1=172   yellow */
+	0x47, 0x0e,		/* OVLV1=14  */
+	0x48, 0x03,		/* OVLY2=3   */
+	0x49, 0x1d,		/* OVLU2=29    cyan */
+	0x4a, 0xac,		/* OVLV2=172 */
+	0x4b, 0xf0,		/* OVLY3=240 */
+	0x4c, 0xc8,		/* OVLU3=200   green */
+	0x4d, 0xb9,		/* OVLV3=185 */
+	0x4e, 0xd4,		/* OVLY4=212 */
+	0x4f, 0x38,		/* OVLU4=56    magenta */
+	0x50, 0x47,		/* OVLV4=71  */
+	0x51, 0xc1,		/* OVLY5=193 */
+	0x52, 0xe3,		/* OVLU5=227   red */
+	0x53, 0x54,		/* OVLV5=84  */
+	0x54, 0xa3,		/* OVLY6=163 */
+	0x55, 0x54,		/* OVLU6=84    blue */
+	0x56, 0xf2,		/* OVLV6=242 */
+	0x57, 0x90,		/* OVLY7=144 */
+	0x58, 0x00,		/* OVLU7=0     black */
+	0x59, 0x00,		/* OVLV7=0   */
+
+	0x5a, 0x00,		/* CHPS=0    */
+	0x5b, 0x76,		/* GAINU=118 */
+	0x5c, 0xa5,		/* GAINV=165 */
+	0x5d, 0x3c,		/* BLCKL=60  */
+	0x5e, 0x3a,		/* BLNNL=58  */
+	0x5f, 0x3a,		/* CCRS=0, BLNVB=58 */
+	0x60, 0x00,		/* NULL      */
+
+/* 0x61 - 0x66 set according to norm */
+
+	0x67, 0x00,		/* 0 : caption 1st byte odd  field */
+	0x68, 0x00,		/* 0 : caption 2nd byte odd  field */
+	0x69, 0x00,		/* 0 : caption 1st byte even field */
+	0x6a, 0x00,		/* 0 : caption 2nd byte even field */
+
+	0x6b, 0x91,		/* MODIN=2, PCREF=0, SCCLN=17 */
+	0x6c, 0x20,		/* SRCV1=0, TRCV2=1, ORCV1=0, PRCV1=0, CBLF=0, ORCV2=0, PRCV2=0 */
+	0x6d, 0x00,		/* SRCM1=0, CCEN=0 */
+
+	0x6e, 0x0e,		/* HTRIG=0x00e, approx. centered, at least for PAL */
+	0x6f, 0x00,		/* HTRIG upper bits */
+	0x70, 0x20,		/* PHRES=0, SBLN=1, VTRIG=0 */
+
+/* The following should not be needed */
+
+	0x71, 0x15,		/* BMRQ=0x115 */
+	0x72, 0x90,		/* EMRQ=0x690 */
+	0x73, 0x61,		/* EMRQ=0x690, BMRQ=0x115 */
+	0x74, 0x00,		/* NULL       */
+	0x75, 0x00,		/* NULL       */
+	0x76, 0x00,		/* NULL       */
+	0x77, 0x15,		/* BRCV=0x115 */
+	0x78, 0x90,		/* ERCV=0x690 */
+	0x79, 0x61,		/* ERCV=0x690, BRCV=0x115 */
+
+/* Field length controls */
+
+	0x7a, 0x70,		/* FLC=0 */
+
+/* The following should not be needed if SBLN = 1 */
+
+	0x7b, 0x16,		/* FAL=22 */
+	0x7c, 0x35,		/* LAL=244 */
+	0x7d, 0x20,		/* LAL=244, FAL=22 */
+};
+
+static const unsigned char init_pal[] =
+{
+	0x61, 0x1e,		/* FISE=0, PAL=1, SCBW=1, RTCE=1, YGS=1, INPI=0, DOWN=0 */
+	0x62, 0xc8,		/* DECTYP=1, BSTA=72 */
+	0x63, 0xcb,		/* FSC0 */
+	0x64, 0x8a,		/* FSC1 */
+	0x65, 0x09,		/* FSC2 */
+	0x66, 0x2a,		/* FSC3 */
+};
+
+static const unsigned char init_ntsc[] =
+{
+	0x61, 0x1d,		/* FISE=1, PAL=0, SCBW=1, RTCE=1, YGS=1, INPI=0, DOWN=0 */
+	0x62, 0xe6,		/* DECTYP=1, BSTA=102 */
+	0x63, 0x1f,		/* FSC0 */
+	0x64, 0x7c,		/* FSC1 */
+	0x65, 0xf0,		/* FSC2 */
+	0x66, 0x21,		/* FSC3 */
+};
+
+static int saa7185_attach(struct i2c_device *device)
+{
+	int i;
+	struct saa7185 *encoder;
+
+	device->data = encoder = kmalloc(sizeof(struct saa7185), GFP_KERNEL);
+	if (encoder == NULL) {
+		return -ENOMEM;
+	}
+	MOD_INC_USE_COUNT;
+
+	memset(encoder, 0, sizeof(struct saa7185));
+	strcpy(device->name, "saa7185");
+	encoder->bus = device->bus;
+	encoder->addr = device->addr;
+	encoder->norm = VIDEO_MODE_NTSC;
+	encoder->enable = 1;
+
+	i = saa7185_write_block(encoder, init_common, sizeof(init_common));
+	if (i >= 0) {
+		i = saa7185_write_block(encoder, init_ntsc, sizeof(init_ntsc));
+	}
+	if (i < 0) {
+		printk(KERN_ERR "%s_attach: init error %d\n", device->name, i);
+	}
+	return 0;
+}
+
+
+static int saa7185_detach(struct i2c_device *device)
+{
+	kfree(device->data);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static int saa7185_command(struct i2c_device *device, unsigned int cmd, void *arg)
+{
+	struct saa7185 *encoder = device->data;
+
+	switch (cmd) {
+
+	case ENCODER_GET_CAPABILITIES:
+		{
+			struct video_encoder_capability *cap = arg;
+
+			cap->flags
+			    = VIDEO_ENCODER_PAL
+			    | VIDEO_ENCODER_NTSC
+			    | VIDEO_ENCODER_SECAM
+			    | VIDEO_ENCODER_CCIR;
+			cap->inputs = 1;
+			cap->outputs = 1;
+		}
+		break;
+
+	case ENCODER_SET_NORM:
+		{
+			int *iarg = arg;
+
+			switch (*iarg) {
+
+			case VIDEO_MODE_NTSC:
+				saa7185_write_block(encoder, init_ntsc, sizeof(init_ntsc));
+				break;
+
+			case VIDEO_MODE_PAL:
+				saa7185_write_block(encoder, init_pal, sizeof(init_pal));
+				break;
+
+			case VIDEO_MODE_SECAM:
+			default:
+				return -EINVAL;
+
+			}
+			encoder->norm = *iarg;
+		}
+		break;
+
+	case ENCODER_SET_INPUT:
+		{
+			int *iarg = arg;
+
+#if 0
+			/* not much choice of inputs */
+			if (*iarg != 0) {
+				return -EINVAL;
+			}
+#else
+			/* RJ: *iarg = 0: input is from SA7111
+			   *iarg = 1: input is from ZR36060 */
+
+			switch (*iarg) {
+
+			case 0:
+				/* Switch RTCE to 1 */
+				saa7185_write(encoder, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08);
+				break;
+
+			case 1:
+				/* Switch RTCE to 0 */
+				saa7185_write(encoder, 0x61, (encoder->reg[0x61] & 0xf7) | 0x00);
+				break;
+
+			default:
+				return -EINVAL;
+
+			}
+#endif
+		}
+		break;
+
+	case ENCODER_SET_OUTPUT:
+		{
+			int *iarg = arg;
+
+			/* not much choice of outputs */
+			if (*iarg != 0) {
+				return -EINVAL;
+			}
+		}
+		break;
+
+	case ENCODER_ENABLE_OUTPUT:
+		{
+			int *iarg = arg;
+
+			encoder->enable = !!*iarg;
+			saa7185_write(encoder, 0x61, (encoder->reg[0x61] & 0xbf) | (encoder->enable ? 0x00 : 0x40));
+		}
+		break;
+
+	default:
+ return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+struct i2c_driver i2c_driver_saa7185 =
+{
+	"saa7185",		/* name */
+	I2C_DRIVERID_VIDEOENCODER,	/* ID */
+	I2C_SAA7185, I2C_SAA7185 + 1,
+
+	saa7185_attach,
+	saa7185_detach,
+	saa7185_command
+};
+
+EXPORT_NO_SYMBOLS;
+
+#ifdef MODULE
+int init_module(void)
+#else
+int saa7185_init(void)
+#endif
+{
+	return i2c_register_driver(&i2c_driver_saa7185);
+}
+
+
+
+#ifdef MODULE
+
+void cleanup_module(void)
+{
+	i2c_unregister_driver(&i2c_driver_saa7185);
+}
+
+#endif
diff -u --recursive --new-file v2.3.9/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- v2.3.9/linux/drivers/char/serial.c	Wed Jun 30 13:38:19 1999
+++ linux/drivers/char/serial.c	Thu Jul  1 15:09:01 1999
@@ -2380,7 +2380,6 @@
X 		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
X #endif
X 		current->state = TASK_INTERRUPTIBLE;
-		current->counter = 0;	/* make us low-priority */
X 		schedule_timeout(char_time);
X 		if (signal_pending(current))
X 			break;
diff -u --recursive --new-file v2.3.9/linux/drivers/char/sysrq.c linux/drivers/char/sysrq.c
--- v2.3.9/linux/drivers/char/sysrq.c	Wed Jun 30 13:38:19 1999
+++ linux/drivers/char/sysrq.c	Sat Jul  3 10:42:21 1999
@@ -150,15 +150,6 @@
X 
X /* Aux routines for the syncer */
X 
-static void all_files_read_only(void)	    /* Kill write permissions of all files */
-{
-	struct file *file;
-
-	for (file = inuse_filps; file; file = file->f_next)
-		if (file->f_dentry && atomic_read(&file->f_count) && S_ISREG(file->f_dentry->d_inode->i_mode))
-			file->f_mode &= ~2;
-}
-
X static int is_local_disk(kdev_t dev)	    /* Guess if the device is a local hard drive */
X {
X 	unsigned int major = MAJOR(dev);
@@ -192,6 +183,7 @@
X 		struct super_block *sb = get_super(dev);
X 		struct vfsmount *vfsmnt;
X 		int ret, flags;
+		struct list_head *p;
X 
X 		if (!sb) {
X 			printk("Superblock not found\n");
@@ -201,6 +193,15 @@
X 			printk("R/O\n");
X 			return;
X 		}
+
+		file_list_lock();
+		for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
+			struct file *file = list_entry(p, struct file, f_list);
+			if (file->f_dentry && file_count(file)
+				&& S_ISREG(file->f_dentry->d_inode->i_mode))
+				file->f_mode &= ~2;
+		}
+		file_list_unlock();
X 		DQUOT_OFF(dev);
X 		fsync_dev(dev);
X 		flags = MS_RDONLY;
@@ -239,9 +240,6 @@
X 	lock_kernel();
X 	remount_flag = (emergency_sync_scheduled == EMERG_REMOUNT);
X 	emergency_sync_scheduled = 0;
-
-	if (remount_flag)
-		all_files_read_only();
X 
X 	for (mnt = vfsmntlist; mnt; mnt = mnt->mnt_next)
X 		if (is_local_disk(mnt->mnt_dev))
diff -u --recursive --new-file v2.3.9/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c
--- v2.3.9/linux/drivers/char/tpqic02.c	Wed Jun 30 13:38:19 1999
+++ linux/drivers/char/tpqic02.c	Tue Jul  6 10:11:40 1999
@@ -127,7 +127,7 @@
X 
X static volatile int ctlbits = 0;     /* control reg bits for tape interface */
X 
-static wait_queue_t qic02_tape_transfer; /* sync rw with interrupts */
+static wait_queue_head_t qic02_tape_transfer; /* sync rw with interrupts */
X 
X static volatile struct mtget ioctl_status;	/* current generic status */
X 
@@ -2216,7 +2216,7 @@
X     }
X     
X 	/* Only one at a time from here on... */
-    if (atomic_read(&filp->f_count)>1) 	/* filp->f_count==1 for the first open() */
+    if (file_count(filp)>1) 	/* filp->f_count==1 for the first open() */
X     {
X 	return -EBUSY;
X     }
@@ -2889,7 +2889,7 @@
X     return 0;
X } /* qic02_get_resources */
X 
-__initfunc(int qic02_tape_init(void))
+int __init qic02_tape_init(void)
X {
X     if (TPSTATSIZE != 6)
X     {
diff -u --recursive --new-file v2.3.9/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c
--- v2.3.9/linux/drivers/char/tty_io.c	Wed Jun 30 13:38:19 1999
+++ linux/drivers/char/tty_io.c	Sun Jul  4 10:18:52 1999
@@ -173,13 +173,15 @@
X static int check_tty_count(struct tty_struct *tty, const char *routine)
X {
X #ifdef CHECK_TTY_COUNT
-	struct file *f;
+	struct list_head *p;
X 	int count = 0;
X 	
-	for(f = inuse_filps; f; f = f->f_next) {
-		if(f->private_data == tty)
+	file_list_lock();
+	for(p = tty->tty_files.next; p != &tty->tty_files; p = p->next) {
+		if(list_entry(p, struct file, f_list)->private_data == tty)
X 			count++;
X 	}
+	file_list_unlock();
X 	if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
X 	    tty->driver.subtype == PTY_TYPE_SLAVE &&
X 	    tty->link && tty->link->count)
@@ -383,9 +385,9 @@
X void do_tty_hangup(void *data)
X {
X 	struct tty_struct *tty = (struct tty_struct *) data;
-	struct file * filp;
X 	struct file * cons_filp = NULL;
X 	struct task_struct *p;
+	struct list_head *l;
X 	int    closecount = 0, n;
X 
X 	if (!tty)
@@ -395,13 +397,11 @@
X 	lock_kernel();
X 	
X 	check_tty_count(tty, "do_tty_hangup");
-	for (filp = inuse_filps; filp; filp = filp->f_next) {
-		if (filp->private_data != tty)
-			continue;
+	file_list_lock();
+	for (l = tty->tty_files.next; l != &tty->tty_files; l = l->next) {
+		struct file * filp = list_entry(l, struct file, f_list);
X 		if (!filp->f_dentry)
X 			continue;
-		if (!filp->f_dentry->d_inode)
-			continue;
X 		if (filp->f_dentry->d_inode->i_rdev == CONSOLE_DEV ||
X 		    filp->f_dentry->d_inode->i_rdev == SYSCONS_DEV) {
X 			cons_filp = filp;
@@ -410,9 +410,10 @@
X 		if (filp->f_op != &tty_fops)
X 			continue;
X 		closecount++;
-		tty_fasync(-1, filp, 0);
+		tty_fasync(-1, filp, 0);	/* can't block */
X 		filp->f_op = &hung_up_tty_fops;
X 	}
+	file_list_unlock();
X 	
X 	/* FIXME! What are the locking issues here? This may me overdoing things.. */
X 	{
@@ -1307,6 +1308,7 @@
X init_dev_done:
X #endif
X 	filp->private_data = tty;
+	file_move(filp, &tty->tty_files);
X 	check_tty_count(tty, "tty_open");
X 	if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
X 	    tty->driver.subtype == PTY_TYPE_MASTER)
@@ -1788,6 +1790,10 @@
X  * have to coordinate with the init process, since all processes associated
X  * with the current tty must be dead before the new getty is allowed
X  * to spawn.
+ *
+ * Now, if it would be correct ;-/ The current code has a nasty hole -
+ * it doesn't catch files in flight. We may send the descriptor to ourselves
+ * via AF_UNIX socket, close it and later fetch from socket. FIXME.
X  */
X void do_SAK( struct tty_struct *tty)
X {
@@ -1812,6 +1818,7 @@
X 		    ((session > 0) && (p->session == session)))
X 			send_sig(SIGKILL, p, 1);
X 		else if (p->files) {
+			read_lock(&p->files->file_lock);
X 			for (i=0; i < p->files->max_fds; i++) {
X 				filp = fcheck_task(p, i);
X 				if (filp && (filp->f_op == &tty_fops) &&
@@ -1820,6 +1827,7 @@
X 					break;
X 				}
X 			}
+			read_unlock(&p->files->file_lock);
X 		}
X 	}
X 	read_unlock(&tasklist_lock);
@@ -1937,6 +1945,7 @@
X 	tty->tq_hangup.routine = do_tty_hangup;
X 	tty->tq_hangup.data = tty;
X 	sema_init(&tty->atomic_read, 1);
+	INIT_LIST_HEAD(&tty->tty_files);
X }
X 
X /*
diff -u --recursive --new-file v2.3.9/linux/drivers/char/videodev.c linux/drivers/char/videodev.c
--- v2.3.9/linux/drivers/char/videodev.c	Wed Jun  2 11:29:13 1999
+++ linux/drivers/char/videodev.c	Mon Jul  5 20:09:40 1999
@@ -63,6 +63,9 @@
X #ifdef CONFIG_RADIO_RTRACK
X extern int rtrack_init(struct video_init *);
X #endif
+#ifdef CONFIG_RADIO_RTRACK2
+extern int rtrack2_init(struct video_init *);
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 11'
echo 'File patch-2.3.10 is continued in part 12'
echo 12 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 12 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
+#endif
X #ifdef CONFIG_RADIO_SF16FMI
X extern int fmi_init(struct video_init *);
X #endif
@@ -78,9 +81,15 @@
X #ifdef CONFIG_RADIO_CADET
X extern int cadet_init(struct video_init *);
X #endif
+#ifdef CONFIG_RADIO_TERRATEC
+extern int terratec_init(struct video_init *);
+#endif
X #ifdef CONFIG_VIDEO_PMS
X extern int init_pms_cards(struct video_init *);
X #endif
+#ifdef CONFIG_VIDEO_ZORAN
+extern int init_zoran_cards(struct video_init *);
+#endif
X 
X static struct video_init video_init_list[]={
X #ifdef CONFIG_VIDEO_BT848
@@ -108,6 +117,9 @@
X #ifdef CONFIG_RADIO_RTRACK
X 	{"RTrack", rtrack_init}, 
X #endif 
+#ifdef CONFIG_RADIO_RTRACK2
+	{"RTrack2", rtrack2_init}, 
+#endif
X #ifdef CONFIG_RADIO_SF16FMI
X 	{"SF16FMI", fmi_init}, 
X #endif	
@@ -123,6 +135,12 @@
X #ifdef CONFIG_RADIO_TYPHOON
X 	{"radio-typhoon", typhoon_init},
X #endif
+#ifdef CONFIG_RADIO_TERRATEC
+	{"radio-terratec", terratec_init},
+#endif
+#ifdef CONFIG_VIDEO_ZORAN
+	{"zoran", init_zoran_cards},
+#endif	
X 	{"end", NULL}
X };
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/char/zr36057.h linux/drivers/char/zr36057.h
--- v2.3.9/linux/drivers/char/zr36057.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/zr36057.h	Mon Jul  5 20:09:40 1999
@@ -0,0 +1,168 @@
+/* 
+   zr36057.h - zr36057 register offsets
+
+   Copyright (C) 1998 Dave Perks <dpe...@ibm.net>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _ZR36057_H_
+#define _ZR36057_H_
+
+
+/* Zoran ZR36057 registers */
+
+#define ZR36057_VFEHCR          0x000	/* Video Front End, Horizontal Configuration Register */
+#define ZR36057_VFEHCR_HSPol            (1<<30)
+#define ZR36057_VFEHCR_HStart           10
+#define ZR36057_VFEHCR_HEnd	        0
+#define ZR36057_VFEHCR_Hmask	        0x3ff
+
+#define ZR36057_VFEVCR          0x004	/* Video Front End, Vertical Configuration Register */
+#define ZR36057_VFEVCR_VSPol            (1<<30)
+#define ZR36057_VFEVCR_VStart           10
+#define ZR36057_VFEVCR_VEnd	        0
+#define ZR36057_VFEVCR_Vmask	        0x3ff
+
+#define ZR36057_VFESPFR         0x008	/* Video Front End, Scaler and Pixel Format Register */
+#define ZR36057_VFESPFR_ExtFl           (1<<26)
+#define ZR36057_VFESPFR_TopField        (1<<25)
+#define ZR36057_VFESPFR_VCLKPol         (1<<24)
+#define ZR36057_VFESPFR_HFilter         21
+#define ZR36057_VFESPFR_HorDcm          14
+#define ZR36057_VFESPFR_VerDcm          8
+#define ZR36057_VFESPFR_DispMode        6
+#define ZR36057_VFESPFR_YUV422          (0<<3)
+#define ZR36057_VFESPFR_RGB888          (1<<3)
+#define ZR36057_VFESPFR_RGB565          (2<<3)
+#define ZR36057_VFESPFR_RGB555          (3<<3)
+#define ZR36057_VFESPFR_ErrDif          (1<<2)
+#define ZR36057_VFESPFR_Pack24          (1<<1)
+#define ZR36057_VFESPFR_LittleEndian    (1<<0)
+
+#define ZR36057_VDTR            0x00c	/* Video Display "Top" Register */
+
+#define ZR36057_VDBR            0x010	/* Video Display "Bottom" Register */
+
+#define ZR36057_VSSFGR          0x014	/* Video Stride, Status, and Frame Grab Register */
+#define ZR36057_VSSFGR_DispStride       16
+#define ZR36057_VSSFGR_VidOvf           (1<<8)
+#define ZR36057_VSSFGR_SnapShot         (1<<1)
+#define ZR36057_VSSFGR_FrameGrab        (1<<0)
+
+#define ZR36057_VDCR            0x018	/* Video Display Configuration Register */
+#define ZR36057_VDCR_VidEn              (1<<31)
+#define ZR36057_VDCR_MinPix             24
+#define ZR36057_VDCR_Triton             (1<<24)
+#define ZR36057_VDCR_VidWinHt           12
+#define ZR36057_VDCR_VidWinWid          0
+
+#define ZR36057_MMTR            0x01c	/* Masking Map "Top" Register */
+
+#define ZR36057_MMBR            0x020	/* Masking Map "Bottom" Register */
+
+#define ZR36057_OCR             0x024	/* Overlay Control Register */
+#define ZR36057_OCR_OvlEnable           (1 << 15)
+#define ZR36057_OCR_MaskStride          0
+
+#define ZR36057_SPGPPCR         0x028	/* System, PCI, and General Purpose Pins Control Register */
+#define ZR36057_SPGPPCR_SoftReset	(1<<24)
+
+#define ZR36057_GPPGCR1         0x02c	/* General Purpose Pins and GuestBus Control Register (1) */
+
+#define ZR36057_MCSAR           0x030	/* MPEG Code Source Address Register */
+
+#define ZR36057_MCTCR           0x034	/* MPEG Code Transfer Control Register */
+#define ZR36057_MCTCR_CodTime           (1 << 30)
+#define ZR36057_MCTCR_CEmpty            (1 << 29)
+#define ZR36057_MCTCR_CFlush            (1 << 28)
+#define ZR36057_MCTCR_CodGuestID	20
+#define ZR36057_MCTCR_CodGuestReg	16
+
+#define ZR36057_MCMPR           0x038	/* MPEG Code Memory Pointer Register */
+
+#define ZR36057_ISR             0x03c	/* Interrupt Status Register */
+#define ZR36057_ISR_GIRQ1               (1<<30)
+#define ZR36057_ISR_GIRQ0               (1<<29)
+#define ZR36057_ISR_CodRepIRQ           (1<<28)
+#define ZR36057_ISR_JPEGRepIRQ          (1<<27)
+
+#define ZR36057_ICR             0x040	/* Interrupt Control Register */
+#define ZR36057_ICR_GIRQ1               (1<<30)
+#define ZR36057_ICR_GIRQ0               (1<<29)
+#define ZR36057_ICR_CodRepIRQ           (1<<28)
+#define ZR36057_ICR_JPEGRepIRQ          (1<<27)
+#define ZR36057_ICR_IntPinEn            (1<<24)
+
+#define ZR36057_I2CBR           0x044	/* I2C Bus Register */
+#define ZR36057_I2CBR_SDA       	(1<<1)
+#define ZR36057_I2CBR_SCL       	(1<<0)
+
+#define ZR36057_JMC             0x100	/* JPEG Mode and Control */
+#define ZR36057_JMC_JPG                 (1 << 31)
+#define ZR36057_JMC_JPGExpMode          (0 << 29)
+#define ZR36057_JMC_JPGCmpMode          (1 << 29)
+#define ZR36057_JMC_MJPGExpMode         (2 << 29)
+#define ZR36057_JMC_MJPGCmpMode         (3 << 29)
+#define ZR36057_JMC_RTBUSY_FB           (1 << 6)
+#define ZR36057_JMC_Go_en               (1 << 5)
+#define ZR36057_JMC_SyncMstr            (1 << 4)
+#define ZR36057_JMC_Fld_per_buff        (1 << 3)
+#define ZR36057_JMC_VFIFO_FB            (1 << 2)
+#define ZR36057_JMC_CFIFO_FB            (1 << 1)
+#define ZR36057_JMC_Stll_LitEndian      (1 << 0)
+
+#define ZR36057_JPC             0x104	/* JPEG Process Control */
+#define ZR36057_JPC_P_Reset             (1 << 7)
+#define ZR36057_JPC_CodTrnsEn           (1 << 5)
+#define ZR36057_JPC_Active              (1 << 0)
+
+#define ZR36057_VSP             0x108	/* Vertical Sync Parameters */
+#define ZR36057_VSP_VsyncSize           16
+#define ZR36057_VSP_FrmTot              0
+
+#define ZR36057_HSP             0x10c	/* Horizontal Sync Parameters */
+#define ZR36057_HSP_HsyncStart          16
+#define ZR36057_HSP_LineTot             0
+
+#define ZR36057_FHAP            0x110	/* Field Horizontal Active Portion */
+#define ZR36057_FHAP_NAX                16
+#define ZR36057_FHAP_PAX                0
+
+#define ZR36057_FVAP            0x114	/* Field Vertical Active Portion */
+#define ZR36057_FVAP_NAY                16
+#define ZR36057_FVAP_PAY                0
+
+#define ZR36057_FPP             0x118	/* Field Process Parameters */
+#define ZR36057_FPP_Odd_Even            (1 << 0)
+
+#define ZR36057_JCBA            0x11c	/* JPEG Code Base Address */
+
+#define ZR36057_JCFT            0x120	/* JPEG Code FIFO Threshold */
+
+#define ZR36057_JCGI            0x124	/* JPEG Codec Guest ID */
+#define ZR36057_JCGI_JPEGuestID         4
+#define ZR36057_JCGI_JPEGuestReg        0
+
+#define ZR36057_GCR2            0x12c	/* GuestBus Control Register (2) */
+
+#define ZR36057_POR             0x200	/* Post Office Register */
+#define ZR36057_POR_POPen               (1<<25)
+#define ZR36057_POR_POTime              (1<<24)
+#define ZR36057_POR_PODir               (1<<23)
+
+#define ZR36057_STR             0x300	/* "Still" Transfer Register */
+
+#endif
diff -u --recursive --new-file v2.3.9/linux/drivers/char/zr36060.h linux/drivers/char/zr36060.h
--- v2.3.9/linux/drivers/char/zr36060.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/zr36060.h	Mon Jul  5 20:09:40 1999
@@ -0,0 +1,35 @@
+/* 
+   zr36060.h - zr36060 register offsets
+
+   Copyright (C) 1998 Dave Perks <dpe...@ibm.net>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _ZR36060_H_
+#define _ZR36060_H_
+
+
+/* Zoran ZR36060 registers */
+
+#define ZR36060_LoadParameters  	0x000
+#define ZR36060_Load                    (1<<7)
+#define ZR36060_SyncRst                 (1<<0)
+
+#define ZR36060_CodeFifoStatus  	0x001
+#define ZR36060_Load                    (1<<7)
+#define ZR36060_SyncRst                 (1<<0)
+
+#endif
diff -u --recursive --new-file v2.3.9/linux/drivers/fc4/socal.c linux/drivers/fc4/socal.c
--- v2.3.9/linux/drivers/fc4/socal.c	Sun Mar 28 09:07:47 1999
+++ linux/drivers/fc4/socal.c	Mon Jul  5 20:35:18 1999
@@ -37,7 +37,6 @@
X #include <asm/openprom.h>
X #include <asm/oplib.h>
X #include <asm/auxio.h>
-#include <asm/system.h>
X #include <asm/pgtable.h>
X #include <asm/irq.h>
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/i2o/README linux/drivers/i2o/README
--- v2.3.9/linux/drivers/i2o/README	Wed Jun  2 14:40:22 1999
+++ linux/drivers/i2o/README	Mon Jul  5 20:09:40 1999
@@ -22,8 +22,15 @@
X Philip Rumpf
X 	Fixed assorted dumb SMP locking bugs
X 
-Juha Sievanen,  University Of Helsinki Finland
+Juha Sievanen,  University of Helsinki Finland
X 	LAN OSM
+	/proc interface to LAN class
+	Bug fixes
+	Core code extensions
+
+Auvo Häkkinen,  University of Helsinki Finland
+	LAN OSM
+	/Proc interface to LAN class
X 	Bug fixes
X 	Core code extensions
X 
@@ -41,13 +48,16 @@
X BoxHill Corporation
X 	Loan of initial FibreChannel disk array used for development work.
X 
+European Comission
+	Funding the work done by the University of Helsinki
+
X STATUS:
X 
X o	The core setup works within limits.
X o	The scsi layer seems to almost work. I'm still chasing down the hang
X 	bug.
X o	The block OSM is fairly minimal but does seem to work.
-
+o	LAN OSM works with FDDI cards.
X 
X TO DO:
X 
@@ -69,10 +79,8 @@
X SCSI:
X o	Find the right way to associate drives/luns/busses
X 
-Net:
-o	Port the existing RCPCI work to the frame work or write a new
-	driver. This one is with the Finns
+Lan:	Batch mode sends
+	Fix the "killing interrupt handler" in i2o_set_multicast_list
X 
X Tape:
X o	Anyone seen anything implementing this ?
-
diff -u --recursive --new-file v2.3.9/linux/drivers/i2o/README.lan linux/drivers/i2o/README.lan
--- v2.3.9/linux/drivers/i2o/README.lan	Wed Jun  2 14:40:22 1999
+++ linux/drivers/i2o/README.lan	Mon Jul  5 20:09:40 1999
@@ -1,5 +1,6 @@
X 
X 	Linux I2O LAN OSM
+
X 	(c) University of Helsinki, Department of Computer Science
X 
X 	This program is free software; you can redistribute it and/or
@@ -8,14 +9,14 @@
X 	2 of the License, or (at your option) any later version.
X 
X AUTHORS
-Auvo Häkkinen, Auvo.H...@cs.Helsinki.FI
-Juha Sievänen, Juha.S...@cs.Helsinki.FI
+	Auvo Häkkinen, Auvo.H...@cs.Helsinki.FI
+	Juha Sievänen, Juha.S...@cs.Helsinki.FI
X 
X CREDITS
X 
X 	This work was made possible by 
X 
-European Committee
+European Commission
X 	Funding for the project
X 
X SysKonnect
@@ -32,7 +33,6 @@
X 
X LAN:
X o	Add support for bactches
-o	Find why big packets flow from I2O box out, but don't want to come in
X o	Find the bug in i2o_set_multicast_list(), which kills interrupt
X 	handler in i2o_wait_reply()
X o	Add support for Ethernet, Token Ring, AnyLAN, Fibre Channel
diff -u --recursive --new-file v2.3.9/linux/drivers/i2o/i2o_block.c linux/drivers/i2o/i2o_block.c
--- v2.3.9/linux/drivers/i2o/i2o_block.c	Wed Jun  2 14:40:22 1999
+++ linux/drivers/i2o/i2o_block.c	Mon Jul  5 20:09:40 1999
@@ -10,13 +10,17 @@
X  * 	as published by the Free Software Foundation; either version
X  *	2 of the License, or (at your option) any later version.
X  *
- *	This is an initial test release. Most of the good code was taken
+ *	This is a beta test release. Most of the good code was taken
X  *	from the nbd driver by Pavel Machek, who in turn took some of it
X  *	from loop.c. Isn't free software great for reusability 8)
X  *
X  *	Fixes:
X  *		Steve Ralston:	Multiple device handling error fixes,
X  *				Added a queue depth.
+ *
+ *	Todo:
+ *		64bit cleanness.
+ *		Remove the queue walk. We can do that better.
X  */
X 
X #include <linux/major.h>
@@ -31,6 +35,7 @@
X #include <linux/ioctl.h>
X #include <linux/i2o.h>
X #include <linux/blkdev.h>
+#include <linux/blkpg.h>
X #include <linux/malloc.h>
X #include <linux/hdreg.h>
X 
@@ -47,7 +52,7 @@
X 
X #define MAX_I2OB	16
X 
-#define MAX_I2OB_DEPTH	4
+#define MAX_I2OB_DEPTH	8
X 
X /*
X  *	Some of these can be made smaller later
@@ -61,9 +66,7 @@
X 
X static int i2ob_context;
X 
-#ifdef __SMP__
X static spinlock_t i2ob_lock = SPIN_LOCK_UNLOCKED;
-#endif
X 
X struct i2ob_device
X {
@@ -175,15 +178,10 @@
X 		msg[5] -= count;
X 	}
X 
-//	printk("Send for %p\n", req);
-
X 	i2o_post_message(c,m);
X 	atomic_inc(&queue_depth);
X 	if(atomic_read(&queue_depth)>old_qd)
-	{
X 		old_qd=atomic_read(&queue_depth);
-		printk("Depth now %d.\n", old_qd);
-	}
X 	return 0;
X }
X 
@@ -825,7 +823,7 @@
X                                  */
X                                 if(i2ob_claim_device(dev, 1)==0)
X                                 {
-                                        printk(KERN_INFO "Claimed Dev %x Tid %d Unit %d\n",dev,dev->tid,unit);
+                                        printk(KERN_INFO "Claimed Dev %p Tid %d Unit %d\n",dev,dev->tid,unit);
X                                         i2ob_install_device(c,d,unit);
X                                         unit+=16;
X  
@@ -836,7 +834,7 @@
X                                          * the block or scsi driver.
X                                          */
X                                         if (i2ob_claim_device(dev, 0)<0)
-                                                printk(KERN_INFO "Could not unclaim Dev %x Tid %d\n",dev,dev->tid);
+                                                printk(KERN_INFO "Could not unclaim Dev %p Tid %d\n",dev,dev->tid);
X  
X                                 }
X                                 else
@@ -966,14 +964,14 @@
X  */
X 
X #ifdef MODULE
-#define i2ob_init init_module
+#define i2o_block_init init_module
X #endif
X 
-int i2ob_init(void)
+int i2o_block_init(void)
X {
X 	int i;
X 
-	printk("I2O block device OSM v0.06. (C) 1999 Red Hat Software.\n");
+	printk(KERN_INFO "I2O block device OSM v0.06. (C) 1999 Red Hat Software.\n");
X 	
X 	/*
X 	 *	Register the block device interfaces
diff -u --recursive --new-file v2.3.9/linux/drivers/i2o/i2o_config.c linux/drivers/i2o/i2o_config.c
--- v2.3.9/linux/drivers/i2o/i2o_config.c	Wed Jun 30 13:38:19 1999
+++ linux/drivers/i2o/i2o_config.c	Mon Jul  5 20:35:18 1999
@@ -5,8 +5,10 @@
X  *	
X  *	Written by Alan Cox, Building Number Three Ltd
X  *
- *      Modified 04/20/199 by Deepak Saxena
+ *      Modified 04/20/1999 by Deepak Saxena
X  *         - Added basic ioctl() support
+ *      Modified 06/07/1999 by Deepak Saxena
+ *         - Added software download ioctl (still testing)
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
@@ -22,7 +24,6 @@
X #include <linux/init.h>
X #include <linux/malloc.h>
X #include <linux/miscdevice.h>
-#include <linux/kernel.h>
X #include <linux/mm.h>
X 
X #include <asm/uaccess.h>
@@ -210,7 +211,10 @@
X 	workspace = kmalloc(8192, GFP_KERNEL);
X 	hrt = (pi2o_hrt)workspace;
X 	if(workspace==NULL)
+	{
+		i2o_unlock_controller(c);
X 		return -ENOMEM;
+	}
X 
X 	memset(workspace, 0, 8192);
X 
@@ -271,7 +275,10 @@
X 	workspace = kmalloc(8192, GFP_KERNEL);
X 	lct = (pi2o_lct)workspace;
X 	if(workspace==NULL)
+	{
+		i2o_unlock_controller(c);
X 		return -ENOMEM;
+	}
X 
X 	memset(workspace, 0, 8192);
X 
@@ -337,10 +344,14 @@
X 
X 	ops = (u8*)kmalloc(kcmd.oplen, GFP_KERNEL);
X 	if(!ops)
+	{
+		i2o_unlock_controller(c);
X 		return -ENOMEM;
+	}
X 
X 	if(copy_from_user(ops, kcmd.opbuf, kcmd.oplen))
X 	{
+		i2o_unlock_controller(c);
X 		kfree(ops);
X 		return -EFAULT;
X 	}
@@ -352,6 +363,7 @@
X 	res = (u8*)kmalloc(65536, GFP_KERNEL);
X 	if(!res)
X 	{
+		i2o_unlock_controller(c);
X 		kfree(ops);
X 		return -ENOMEM;
X 	}
@@ -374,11 +386,12 @@
X 	token = i2o_post_wait(c, kcmd.tid, msg, 9*4, &i2o_cfg_token,10);
X 	if(token == I2O_POST_WAIT_TIMEOUT)
X 	{
+		i2o_unlock_controller(c);
X 		kfree(ops);
X 		kfree(res);
X 		return -ETIMEDOUT;
X 	}
-
+	i2o_unlock_controller(c);
X 	kfree(ops);
X 
X 	/* 
@@ -448,9 +461,13 @@
X 	{
X 		query = kmalloc(kcmd.qlen, GFP_KERNEL);
X 		if(!query)
+		{
+			i2o_unlock_controller(c);
X 			return -ENOMEM;
+		}
X 		if(copy_from_user(query, kcmd.qbuf, kcmd.qlen))
X 		{
+			i2o_unlock_controller(c);
X 			printk(KERN_INFO "i2o_config: could not get query\n");
X 			kfree(query);
X 			return -EFAULT;
@@ -459,7 +476,10 @@
X 
X 	res = kmalloc(4096, GFP_KERNEL);
X 	if(!res)
+	{
+		i2o_unlock_controller(c);
X 		return -ENOMEM;
+	}
X 
X 	msg[1] = (I2O_CMD_UTIL_CONFIG_DIALOG << 24)|HOST_TID<<12|kcmd.tid;
X 	msg[2] = i2o_cfg_context;
@@ -480,11 +500,13 @@
X 	token = i2o_post_wait(c, cmd->tid, msg, 9*4, &i2o_cfg_token, 10);
X 	if(token == I2O_POST_WAIT_TIMEOUT)
X 	{
+		i2o_unlock_controller(c);
X 		kfree(res);
X 		if(kcmd.qlen) kfree(query);
X 
X 		return -ETIMEDOUT;
X 	}
+	i2o_unlock_controller(c);
X 
X 	len = strnlen(res, 8192);
X 	put_user(len, kcmd.reslen);
@@ -500,10 +522,123 @@
X 	return ret;
X }
X 
-/* To be written */
X int ioctl_swdl(unsigned long arg)
X {
-	return -ENOSYS;
+	struct i2o_sw_xfer kxfer;
+	struct i2o_sw_xfer *pxfer = (struct i2o_sw_xfer *)arg;
+	unsigned char maxfrag = 0, curfrag = 0;
+	unsigned char buffer[8192];
+	u32 msg[MSG_FRAME_SIZE/4];
+	unsigned int token = 0, diff = 0, swlen = 0, swxfer = 0;
+	struct i2o_controller *c;
+	int foo = 0;
+
+	printk("*** foo%d ***\n", foo++);
+	if(copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer)))
+	{
+		printk( "i2o_config: can't copy i2o_sw cmd @ %p\n", pxfer);
+		return -EFAULT;
+	}
+	printk("*** foo%d ***\n", foo++);
+
+	printk("Attempting to copy swlen from %p\n", kxfer.swlen);
+	if(get_user(swlen, kxfer.swlen) < 0)
+	{
+		printk( "i2o_config: can't copy swlen\n");
+		return -EFAULT;
+	}
+	printk("*** foo%d ***\n", foo++);
+
+	maxfrag = swlen >> 13;	// Transfer in 8k fragments
+
+	printk("Attempting to write maxfrag @ %p\n", kxfer.maxfrag);
+	if(put_user(maxfrag, kxfer.maxfrag) < 0)
+	{
+		printk( "i2o_config: can't write maxfrag\n");
+		return -EFAULT;
+	}
+	printk("*** foo%d ***\n", foo++);
+
+	printk("Attempting to write curfrag @ %p\n", kxfer.curfrag);
+	if(put_user(curfrag, kxfer.curfrag) < 0)
+	{
+		printk( "i2o_config: can't write curfrag\n");
+		return -EFAULT;
+	}
+	printk("*** foo%d ***\n", foo++);
+
+	if(!kxfer.buf)
+	{
+		printk( "i2o_config: NULL software buffer\n");
+		return -EFAULT;
+	}
+	printk("*** foo%d ***\n", foo++);
+	
+	// access_ok doesn't check for NULL...
+	if(!access_ok(VERIFY_READ, kxfer.buf, swlen))
+	{
+                printk( "i2o_config: Cannot read sw buffer\n");
+                return -EFAULT;
+	}
+	printk("*** foo%d ***\n", foo++);
+
+	c = i2o_find_controller(kxfer.iop);
+	if(!c)
+		return -ENXIO;
+	printk("*** foo%d ***\n", foo++);
+
+	msg[0]= EIGHT_WORD_MSG_SIZE| SGL_OFFSET_7;
+	msg[1]= I2O_CMD_SW_DOWNLOAD<<24 | HOST_TID<<12 | ADAPTER_TID;
+	msg[2]= (u32)cfg_handler.context;
+	msg[3]= 0;
+	msg[4]= ((u32)kxfer.dl_flags)<<24|((u32)kxfer.sw_type)<<16|((u32)maxfrag)<<8|((u32)curfrag);
+	msg[5]= swlen;
+	msg[6]= kxfer.sw_id;
+	msg[7]= (0xD0000000 | 8192);
+	msg[8]= virt_to_phys(buffer);
+
+	printk("*** foo%d ***\n", foo++);
+
+	//
+	// Loop through all fragments but last and transfer them...
+	// We already checked memory, so from now we assume it's all good
+	//
+	for(curfrag = 0; curfrag < maxfrag-1; curfrag++)
+	{
+		printk("Transfering fragment %d\n", curfrag);
+
+		msg[4] |= (u32)curfrag;
+
+		__copy_from_user(buffer, kxfer.buf, 8192);
+		swxfer += 8129;
+
+		// Yes...that's one minute, but the spec states that
+		// transfers take a long time, and I've seen just how
+		// long they can take.
+		token = i2o_post_wait(c, ADAPTER_TID, msg, 6*4, &i2o_cfg_token,60);
+		if( token == I2O_POST_WAIT_TIMEOUT )	// Something very wrong
+		{
+			printk("Timeout downloading software");
+			return -ETIMEDOUT;
+		}
+
+		__put_user(curfrag, kxfer.curfrag);
+	}
+
+	// Last frag is special case since it's not exactly 8K
+	diff = swlen - swxfer;
+	msg[4] |= (u32)maxfrag;
+	msg[7] = (0xD0000000 | diff);
+	__copy_from_user(buffer, kxfer.buf, 8192);
+	token = i2o_post_wait(c, ADAPTER_TID, msg, 6*4, &i2o_cfg_token,60);
+	if( token == I2O_POST_WAIT_TIMEOUT )	// Something very wrong
+	{
+		printk("Timeout downloading software");
+		return -ETIMEDOUT;
+	}
+	__put_user(curfrag, kxfer.curfrag);
+
+	return 0;
X }
X 
X /* To be written */
@@ -557,7 +692,7 @@
X #ifdef MODULE
X int init_module(void)
X #else
-int i2o_config_init(void)
+__init int i2o_config_init(void)
X #endif
X {
X 	printk(KERN_INFO "i2o configuration manager v 0.02\n");
diff -u --recursive --new-file v2.3.9/linux/drivers/i2o/i2o_core.c linux/drivers/i2o/i2o_core.c
--- v2.3.9/linux/drivers/i2o/i2o_core.c	Wed Jun 30 13:38:19 1999
+++ linux/drivers/i2o/i2o_core.c	Tue Jul  6 10:11:40 1999
@@ -13,12 +13,12 @@
X  *	A lot of the I2O message side code from this is taken from the
X  *	Red Creek RCPCI45 adapter driver by Red Creek Communications
X  *
- *	Some fixes and cleanup by Philipp Rumpf
- *
- *	Additional fixes by Juha Sievänen <Juha.S...@cs.Helsinki.FI>
- *	
+ *	Fixes by Philipp Rumpf
+ *		 Juha Sievänen <Juha.S...@cs.Helsinki.FI>
+ *	         Auvo Häkkinen <Auvo.H...@cs.Helsinki.FI>
X  */
X  
+#include <linux/config.h>
X #include <linux/module.h>
X #include <linux/kernel.h>
X #include <linux/pci.h>
@@ -32,26 +32,69 @@
X 
X #include "i2o_lan.h"
X 
+
X /*
X  *	Size of the I2O module table
X  */
X  
-
X static struct i2o_handler *i2o_handlers[MAX_I2O_MODULES];
X static struct i2o_controller *i2o_controllers[MAX_I2O_CONTROLLERS];
X int i2o_num_controllers = 0;
-
+static int core_context = 0;
+static int reply_flag = 0;
X 
X extern int i2o_online_controller(struct i2o_controller *c);
+static void i2o_core_reply(struct i2o_handler *, struct i2o_controller *,
+			   struct i2o_message *);
+
+/* Message handler */ 
+static struct i2o_handler i2o_core_handler =
+{
+	(void *)i2o_core_reply,
+	"I2O core layer",
+	0
+};
X 
X /*
X  *	I2O configuration spinlock. This isnt a big deal for contention
X  *	so we have one only
X  */
X  
-#ifdef __SMP__
X static spinlock_t i2o_configuration_lock = SPIN_LOCK_UNLOCKED;
+
+void i2o_core_reply(struct i2o_handler *h, struct i2o_controller *c,
+		    struct i2o_message *m)
+{
+	u32 *msg=(u32 *)m;
+	u32 *flag = (u32 *)msg[3];
+
+#if 0
+	i2o_report_status(KERN_INFO, "i2o_core", msg);
X #endif
+	
+	if (msg[0] & (1<<13)) // Fail bit is set
+        {
+                printk(KERN_ERR "IOP failed to process the msg:\n");
+                printk(KERN_ERR "  Cmd = 0x%02X, InitiatorTid = %d, TargetTid =%d\n",
+		       (msg[1] >> 24) & 0xFF, (msg[1] >> 12) & 0xFFF, msg[1] &
+		       0xFFF);
+                printk(KERN_ERR "  FailureCode = 0x%02X\n  Severity = 0x%02X\n"
+		       "LowestVersion = 0x%02X\n  HighestVersion = 0x%02X\n",
+		       msg[4] >> 24, (msg[4] >> 16) & 0xFF,
+		       (msg[4] >> 8) & 0xFF, msg[4] & 0xFF);
+                printk(KERN_ERR "  FailingHostUnit = 0x%04X\n  FailingIOP = 0x%03X\n",
+		       msg[5] >> 16, msg[5] & 0xFFF);
+                return;
+        }
+
+	if (msg[4] >> 24)
+	{
+		i2o_report_status(KERN_WARNING, "i2o_core", msg);
+		*flag = -(msg[4] & 0xFFFF);
+	}
+	else
+		*flag = I2O_POST_WAIT_OK;
+}
X 
X /*
X  *	Install an I2O handler - these handle the asynchronous messaging
@@ -179,10 +222,11 @@
X int i2o_delete_controller(struct i2o_controller *c)
X {
X 	struct i2o_controller **p;
-	
+
X 	spin_lock(&i2o_configuration_lock);
X 	if(atomic_read(&c->users))
X 	{
+		printk("Someones using controller iop%d\n", c->unit);
X 		spin_unlock(&i2o_configuration_lock);
X 		return -EBUSY;
X 	}
@@ -195,21 +239,41 @@
X 			return -EBUSY;
X 		}
X 	}
-	c->destructor(c);
-	
+//	c->destructor(c); /* We dont want to free the IRQ yet */
+
X 	p=&i2o_controller_chain;
-	
+
+	/* Send first SysQuiesce to other IOPs */
+	while(*p)
+	{
+		if(*p!=c)
+			if(i2o_quiesce_controller(*p)<0)
+				printk(KERN_INFO "Unable to quiesce iop%d\n",
+				       (*p)->unit);
+		p=&((*p)->next);
+	}
+
+	p=&i2o_controller_chain;
+
X 	while(*p)
X 	{
X 		if(*p==c)
X 		{
-			/* Prepare for restart */
-//			i2o_clear_controller(c);
+			/* Ask the IOP to switch to HOLD state */
+			if (i2o_clear_controller(c) < 0)
+				printk("Unable to clear iop%d\n", c->unit);
+
+			/* Release IRQ */
+			c->destructor(c);
X 
X 			*p=c->next;
X 			spin_unlock(&i2o_configuration_lock);
X 			if(c->page_frame);
X 				kfree(c->page_frame);
+			if(c->hrt)
+				kfree(c->hrt);
+			if(c->lct)
+				kfree(c->lct);
X 			i2o_controllers[c->unit]=NULL;
X 			kfree(c);
X 			i2o_num_controllers--;
@@ -317,7 +381,7 @@
X 		"Device Driver Module",
X 		"Block Device",
X 		"Tape Device",
-		"LAN Inteface",
+		"LAN Interface",
X 		"WAN Interface",
X 		"Fibre Channel Port",
X 		"Fibre Channel Device",
@@ -384,7 +448,7 @@
X 	{
X 		if((jiffies-time)>=5*HZ)
X 		{
-			printk(KERN_ERR "%s: Timeout waiting for message to send %s.\n", 
+			printk(KERN_ERR "%s: Timeout waiting for message frame to send %s.\n", 
X 				c->name, why);
X 			return 0xFFFFFFFF;
X 		}
@@ -396,7 +460,7 @@
X 
X 
X /*
- *	Wait up to 5 seconds for a reply to be available.
+ *	Wait up to timeout seconds for a reply to be available.
X  */
X  
X u32 i2o_wait_reply(struct i2o_controller *c, char *why, int timeout)
@@ -418,173 +482,6 @@
X }
X 	
X 
-
-/* Quiesce and clear IOP  */
-int i2o_quiesce_controller(struct i2o_controller *c)
-{
-	u32 m;
-	u32 *msg;
-
-	/* now we stop receiving messages to this IOP */
-	m=i2o_wait_message(c, "Quiesce IOP");
-	if(m==0xFFFFFFFF)
-		return -ETIMEDOUT;
-
-	msg=(u32 *)(c->mem_offset+m);
-
-	msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
-	msg[1]=I2O_CMD_SYS_QUIESCE<<24|HOST_TID<<12|ADAPTER_TID;
-	msg[2]=0;
-	msg[3]=0;
-
-	printk(KERN_DEBUG "Sending SysQuiesce to %s\n", c->name);
-	i2o_post_message(c,m);
-
-	m=i2o_wait_reply(c, "System Quiesce", 20);
-
-	if (m==0xFFFFFFFF)
-		return -ETIMEDOUT;
-	/* Someday we should check return status... */
-
-	return 0;
-}
-
-int i2o_clear_controller(struct i2o_controller *c)
-{
-	u32 m;
-	u32 *msg;
-
-	m=i2o_wait_message(c, "IOP Clear");
-	if (m==0xFFFFFFFF)
-		return -ETIMEDOUT;
-
-	msg=(u32 *)(c->mem_offset+m);
-
-	msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
-	msg[1]=I2O_CMD_ADAPTER_CLEAR<<24|HOST_TID<<12|ADAPTER_TID;
-	msg[2]=0;
-	msg[3]=0;
-
-	printk(KERN_DEBUG "Sending IOPClear to %s\n", c->name);
-	i2o_post_message(c, m);
-
-	m=i2o_wait_reply(c, "IOP Clear timeout", 5);
-
-	if(m==0xFFFFFFFF)
-		return -ETIMEDOUT;
-
-	return 0;
-}
-
-
-/*
- *	i2o table walking. We just provide a single element retrieve. You can
- *	all sorts of fancy lookups in I2O but we have no performance critical
- *	lookups so why write all the code for it.
- */
- 
-#if 0
-static int i2o_query_table_polled(struct i2o_controller *c, int tid, void *buf, int buflen, 
-	int group, int field, u32 *key, int keylen)
-{
-	u32 m;
-	u32 *msg;
-	u16 op[64];
-	u32 *p;
-	int i;
-	u32 *rbuf;
-
-	op[0]=1;			/* One Operation */
-	op[1]=0;			/* PAD */
-	op[2]=2;			/* LIST_GET */
-	op[3]=group;			/* group number */
-	op[4]=1;			/* 1 field */
-	op[5]=field;			/* Field number */
-	op[6]=1;			/* Key count */
-	memcpy(op+7, key, keylen);	/* Key */
-	
-	m=i2o_wait_message(c, "I2O query table.");
-	if(m==0xFFFFFFFF)
-	{	
-		return -ETIMEDOUT;
-	}
-	
-	msg=(u32 *)(c->mem_offset+m);
-	
-	rbuf=kmalloc(buflen+32, GFP_KERNEL);
-	if(rbuf==NULL)
-	{
-		printk(KERN_ERR "No free memory for table read.\n");
-		return -ENOMEM;
-	}
-	msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_5;
-	msg[1]=I2O_CMD_UTIL_PARAMS_GET<<24|HOST_TID<<12|tid;
-	msg[2]=0;			/* Context */
-	msg[3]=0;
-	msg[4]=0;
-	msg[5]=0x54000000|(14);
-	msg[6]=virt_to_bus(op);
-	msg[7]=0xD0000000|(32+buflen);
-	msg[8]=virt_to_bus(rbuf);
-
-	i2o_post_message(c,m);
-	barrier();
-	
-	/*
-	 *	Now wait for a reply
-	 */
-	 
-	
-	m=i2o_wait_reply(c, "Table read timeout", 5);
-	
-	if(m==0xFFFFFFFF)
-	{
-		kfree(rbuf);
-		return -ETIMEDOUT;
-	}
-	
-	msg = (u32 *)bus_to_virt(m);
-
-	if(msg[4]>>24)
-	{
-		i2o_report_status(KERN_WARNING, "i2o_core",
-				  (msg[1]>>24)&0xFF, (msg[4]>>24)&0xFF,
-				  msg[4]&0xFFFF);
-	}
-	
-	p=rbuf;
-
-	/* Ok 'p' is the reply block - lets see what happened */
-	/* p0->p2 are the header */
-	
-	/* FIXME: endians - turn p3 to little endian */
-	
-	i=(p[0]&0xFFFF)<<2;		/* Message size */
-	if(i<buflen)
-		buflen=i;
-	
-	/* Do we have an error block ? */
-	if(p[0]&0xFF000000)
-	{
-		printk(KERN_ERR "%s: error in field read.\n",
-			c->name);
-		kfree(rbuf);
-		return -EBADR;
-	}
-		
-	/* p[1] holds the more flag and row count - we dont care */
-	
-	/* Ok it worked p[2]-> hold the data */
-	memcpy(buf,  p+2, buflen);
-	
-	kfree(rbuf);
-	
-	/* Finally return the message */
-	I2O_REPLY_WRITE32(c,m);
-	return buflen;
-}
-#endif
-
X static int i2o_query_scalar_polled(struct i2o_controller *c, int tid, void *buf, int buflen, 
X 	int group, int field)
X {
@@ -602,7 +499,7 @@
X 	op[4]=1;			/* 1 field */
X 	op[5]=field;			/* Field number */
X 
-	m=i2o_wait_message(c, "I2O query scalar.");
+	m=i2o_wait_message(c, "ParamsGet");
X 	if(m==0xFFFFFFFF)
X 	{	
X 		return -ETIMEDOUT;
@@ -634,8 +531,7 @@
X 	 *	Now wait for a reply
X 	 */
X 	 
-	
-	m=i2o_wait_reply(c, "Scalar read timeout", 5);
+	m=i2o_wait_reply(c, "ParamsGet", 5);
X 	
X 	if(m==0xFFFFFFFF)
X 	{
@@ -646,9 +542,7 @@
X 	msg = (u32 *)bus_to_virt(m);
X 	if(msg[4]>>24)
X 	{
-		i2o_report_status(KERN_WARNING, "i2o_core",
-				  (msg[1]>>24)&0xFF, (msg[4]>>24)&0xFF,
-				  msg[4]&0xFFFF);
+		i2o_report_status(KERN_WARNING, "i2o_core", msg);
X 	}
X 	
X 	p=rbuf;
@@ -729,9 +623,10 @@
X  *	This is full of endianisms!
X  */
X  
-static int i2o_parse_hrt(struct i2o_controller *c, u8 *p)
+static int i2o_parse_hrt(struct i2o_controller *c)
X {
-	u32 *rows=(u32 *)p;
+	u32 *rows=c->hrt;
+	u8 *p=(u8 *)c->hrt;
X 	u8 *d;
X 	int count;
X 	int length;
@@ -818,7 +713,7 @@
X  *	on the board. Most of the stuff isn't interesting to us. 
X  */
X 
-static int i2o_parse_lct(struct i2o_controller *c, u32 *lct)
+static int i2o_parse_lct(struct i2o_controller *c)
X {
X 	int i;
X 	int max;
@@ -826,11 +721,18 @@
X 	u32 *p;
X 	struct i2o_device *d;
X 	char str[22];
+	u32 *lct=(u32 *)c->lct;
X 
X 	max=lct[0]&0xFFFF;
X 	
X 	max-=3;
X 	max/=9;
+
+	if(max==0)
+	{
+		printk(KERN_ERR "LCT is empty????\n");
+		return -1;
+	}
X 	
X 	printk(KERN_INFO "LCT has %d entries.\n", max);
X 	
@@ -891,37 +793,61 @@
X 	return 0;
X }
X 
-#if 0
-/* Reset the IOP to sane state */
-/* I think we need handler for core (or executive class in I2O terms) */
-static int i2o_reset_adapter(struct i2o_controller *c)
+/* Quiesce IOP */
+int i2o_quiesce_controller(struct i2o_controller *c)
X {
-	u32 m;
-	u8 *work8;
-	u32 *msg;
-	long time;
+	u32 msg[4];
X 
-	/* First stop extral operations */
-	m=i2o_wait_message(c, "quiesce IOP");
-	if(m==0xFFFFFFFF)
-		return -ETIMEDOUT;
-	
-	msg=(u32 *)(c->mem_offset+m);
-				
X 	msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
X 	msg[1]=I2O_CMD_SYS_QUIESCE<<24|HOST_TID<<12|ADAPTER_TID;
-	msg[2]=0;
-	msg[3]=0;
+	msg[2]=core_context;
+	msg[3]=(u32)&reply_flag;
X 
-	i2o_post_message(c,m);
+	return i2o_post_wait(c, ADAPTER_TID, msg, sizeof(msg), &reply_flag, 10);
+}
X 
-	m=i2o_wait_reply(c, "System Quiesce timeout", 5);
X 
-	if(m==0xFFFFFFFF)
-		return -ETIMEDOUT;
+int i2o_clear_controller(struct i2o_controller *c)
+{
+	u32 msg[4];
+
+	/* First stop external operations for this IOP */
+	if(i2o_quiesce_controller(c)<0)
+		printk(KERN_INFO "Unable to quiesce iop%d\n", c->unit);
+	else
+		printk(KERN_INFO "Iop%d quiesced\n", c->unit);
+
+	/* Then clear the IOP */
+	msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+	msg[1]=I2O_CMD_ADAPTER_CLEAR<<24|HOST_TID<<12|ADAPTER_TID;
+	msg[2]=core_context;
+	msg[3]=(u32)&reply_flag;
+
+	return i2o_post_wait(c, ADAPTER_TID, msg, sizeof(msg), &reply_flag, 10);
+}
+
+
+/* Reset the IOP to sane state */
+static int i2o_reset_controller(struct i2o_controller *c)
+{
+	u32 m;
+	u8 *work8;
+	u32 *msg;
+	long time;
+	struct i2o_controller *iop;
+
+	/* First stop external operations */
+	for(iop=i2o_controller_chain; iop != NULL; iop=iop->next)
+	{
+		if(i2o_quiesce_controller(iop)<0)
+			printk(KERN_INFO "Unable to quiesce iop%d\n",
+			       iop->unit);
+		else
+			printk(KERN_DEBUG "%s quiesced\n", iop->name);
+	}
X 
X 	/* Then reset the IOP */
-	m=i2o_wait_message(c, "reset IOP");
+	m=i2o_wait_message(c, "AdapterReset");
X 	if(m==0xFFFFFFFF)
X 		return -ETIMEDOUT;
X 
@@ -937,8 +863,8 @@
X 	
X 	msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
X 	msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
-	msg[2]=0;
-	msg[3]=0;
+	msg[2]=core_context;
+	msg[3]=(u32)&reply_flag;
X 	msg[4]=0;
X 	msg[5]=0;
X 	msg[6]=virt_to_phys(work8);
@@ -949,8 +875,10 @@
X 	/* Wait for a reply */
X 	time=jiffies;
X 
-	while(work8[0]==0x01) {
-		if((jiffies-time)>=5*HZ) {
+	while(work8[0]==0x01)
+	{
+		if((jiffies-time)>=5*HZ)
+		{
X 			printk(KERN_ERR "IOP reset timeout.\n");
X 			kfree(work8);
X 			return -ETIMEDOUT;
@@ -964,113 +892,186 @@
X 
X 	return 0;
X }
-#endif
X 
-/*
- *	Bring an I2O controller into HOLD state. See the 1.5
- *	spec. Basically we go
- *
- *	Wait for the message queue to initialise. 
- *	If it didnt -> controller is dead
- *	
- *	Send a get status using the message queue
- *	Poll for a reply block 88 bytes long
- *
- *	Send an initialise outbound queue
- *	Poll for a reply
- *
- *	Post our blank messages to the queue FIFO
- *
- *	Send GetHRT, Parse it
- */
X 
-int i2o_activate_controller(struct i2o_controller *c)
+int i2o_status_get(struct i2o_controller *c)
X {
X 	long time;
X 	u32 m;
-	u8 *workspace;
X 	u32 *msg;
-	int i;
-	
-	printk(KERN_INFO "Configuring I2O controller at 0x%08X.\n", (u32)c->mem_phys);
+	u8 *status_block;
X 
-	/* First reset the IOP to sane state */
-//	i2o_reset_adapter(c)
-	
-	m=i2o_wait_message(c, "initialise");
+	status_block=(void *)kmalloc(88, GFP_KERNEL);
+	if(status_block==NULL)
+	{
+		printk(KERN_ERR "StatusGet failed - no free memory.\n");
+		return -ENOMEM;
+	}
+
+	m=i2o_wait_message(c, "StatusGet");
X 	if(m==0xFFFFFFFF)
X 		return -ETIMEDOUT;
X 
X 	msg=(u32 *)(c->mem_offset+m);
-	
-	workspace = (void *)kmalloc(88, GFP_KERNEL);
-	if(workspace==NULL)
-	{
-		printk(KERN_ERR "IOP initialisation failed - no free memory.\n");
-		return -ENOMEM;
-	}
-	
-	memset(workspace, 0, 88);
-	
+
X 	msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_0;
X 	msg[1]=I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID;
-	msg[2]=0;
+	msg[2]=core_context;
X 	msg[3]=0;
X 	msg[4]=0;
X 	msg[5]=0;
-	msg[6]=virt_to_phys(workspace);
+	msg[6]=virt_to_phys(status_block);
X 	msg[7]=0;	/* 64bit host FIXME */
X 	msg[8]=88;
X 
X 	i2o_post_message(c,m);
X 
-	/*
-	 *	Wait for a reply
-	 */
-
+	/* Wait for a reply */
X 	time=jiffies;
X 		 
-	while(workspace[87]!=0xFF)
+	while(status_block[87]!=0xFF)
X 	{
X 		if((jiffies-time)>=5*HZ)
X 		{
X 			printk(KERN_ERR "IOP get status timeout.\n");
-			kfree(workspace);
X 			return -ETIMEDOUT;
X 		}
X 		schedule();
X 		barrier();
X 	}
X 	
-	/*
-	 *	Ok the reply has arrived. Fill in the important stuff
-	 */
-	 
-	c->status = workspace[10];
-	c->i2oversion = (workspace[9]>>4)&0xFF;
-	c->inbound_size = (workspace[12]|(workspace[13]<<8))*4; /* 32bit words */
-	
+	/* Ok the reply has arrived. Fill in the important stuff */
+	c->status = status_block[10];
+	c->i2oversion = (status_block[9]>>4)&0xFF;
+	c->inbound_size = (status_block[12]|(status_block[13]<<8))*4;
+
+	return 0;
+}
+
+
+int i2o_hrt_get(struct i2o_controller *c)
+{
+	u32 m;
+	u32 *msg;
+
+	c->hrt=kmalloc(2048, GFP_KERNEL);
+	if(c->hrt==NULL)
+	{
+		printk(KERN_ERR "IOP init failed; no memory.\n");
+		return -ENOMEM;
+	}
+
+	m=i2o_wait_message(c, "HRTGet");
+	if(m==0xFFFFFFFF)
+		return -ETIMEDOUT;
+
+	msg=(u32 *)(c->mem_offset+m);
+
+	msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4;
+	msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID;
+	msg[2]= core_context;
+	msg[3]= 0x0;				/* Transaction context */
+	msg[4]= (0xD0000000 | 2048);		/* Simple transaction , 2K */
+	msg[5]= virt_to_phys(c->hrt);		/* Dump it here */
+
+	i2o_post_message(c,m);
+
+	barrier();
+
+	/* Now wait for a reply */
+	m=i2o_wait_reply(c, "HRTGet", 5);
+
+	if(m==0xFFFFFFFF)
+		return -ETIMEDOUT;
+
+	msg=(u32 *)bus_to_virt(m);
+
+	if(msg[4]>>24)
+		i2o_report_status(KERN_WARNING, "i2o_core", msg);
+
+	I2O_REPLY_WRITE32(c,m);
+
+	return 0;
+}
+
+
+/*
+ *	Bring an I2O controller into HOLD state. See the 1.5
+ *	spec. Basically we go
+ *
+ *	Wait for the message queue to initialise. 
+ *	If it didnt -> controller is dead
+ *	
+ *	Send a get status using the message queue
+ *	Poll for a reply block 88 bytes long
+ *
+ *	Send an initialise outbound queue
+ *	Poll for a reply
+ *
+ *	Post our blank messages to the queue FIFO
+ *
+ *	Send GetHRT, Parse it
+ */
+
+int i2o_activate_controller(struct i2o_controller *c)
+{
+	long time;
+	u32 m;
+	u8 *workspace;
+	u32 *msg;
+	int i;
+	int ret;
+
+	printk(KERN_INFO "Configuring I2O controller at 0x%08X.\n",
+	       (u32)c->mem_phys);
+
+	if((ret=i2o_status_get(c)))
+		return ret;
+
+	if(c->status == ADAPTER_STATE_FAULTED) /* not likely to be seen */
+	{
+		printk(KERN_CRIT "i2o: iop%d has hardware fault\n",
+		       c->unit);
+		return -1;
+	}
+
X 	/*
X 	 *	If the board is running, reset it - we have no idea
X 	 *	what kind of a mess the previous owner left it in.
X 	 */
-	 
-//	if(c->status == ADAPTER_STATE_OPERATIONAL)
-//		i2o_reset_device(c);
+	if(c->status == ADAPTER_STATE_HOLD ||
+	   c->status == ADAPTER_STATE_READY ||
+	   c->status == ADAPTER_STATE_OPERATIONAL ||
+	   c->status == ADAPTER_STATE_FAILED)
+	{
+		if((ret=i2o_reset_controller(c)))
+			return ret;
X 
-	
-	m=i2o_wait_message(c, "initqueue");
+		if((ret=i2o_status_get(c)))
+			return ret;
+	}
+
+	workspace = (void *)kmalloc(88, GFP_KERNEL);
+	if(workspace==NULL)
+	{
+		printk(KERN_ERR "IOP initialisation failed - no free memory.\n");
+		return -ENOMEM;
+	}
+
+	memset(workspace, 0, 88);
+
+	m=i2o_wait_message(c, "OutboundInit");
X 	if(m==0xFFFFFFFF)
X 	{	
X 		kfree(workspace);
X 		return -ETIMEDOUT;
X 	}
-	
+
X 	msg=(u32 *)(c->mem_offset+m);
X 
X 	msg[0]= EIGHT_WORD_MSG_SIZE| TRL_OFFSET_6;
X 	msg[1]= I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID;
-	msg[2]= 0;
+	msg[2]= core_context;
X 	msg[3]= 0x0106;			/* Transaction context */
X 	msg[4]= 4096;			/* Host page frame size */
X 	msg[5]= MSG_FRAME_SIZE<<16|0x80;	/* Outbound msg frame size and Initcode */
@@ -1099,9 +1100,11 @@
X 		schedule();
X 		barrier();
X 	}
-	
+
X 	kfree(workspace);
X 
+	/* TODO: v2.0: Set Executive class group 000Bh - OS Operating Info */
+
X 	c->page_frame = kmalloc(MSG_POOL_SIZE, GFP_KERNEL);
X 	if(c->page_frame==NULL)
X 	{
@@ -1124,64 +1127,71 @@
X 	 *	Now we need the Hardware Resource Table. We must ask for
X 	 *	this next we can't issue random messages yet.
X 	 */
+	ret=i2o_hrt_get(c);
+	if(ret)
+		return ret;
+
+	ret=i2o_parse_hrt(c);
+	if(ret)
+		return ret;
+
+	return i2o_online_controller(c);
+//	i2o_report_controller_unit(c, ADAPTER_TID);
+}
X 
X 
-	workspace=kmalloc(2048, GFP_KERNEL);
-	if(workspace==NULL)
+int i2o_lct_get(struct i2o_controller *c)
+{
+	u32 m;
+	u32 *msg;
+
+	m=i2o_wait_message(c, "LCTNotify");
+
+	if(m==0xFFFFFFFF)
+		return -ETIMEDOUT;
+
+	msg=(u32 *)(c->mem_offset+m);
+
+	c->lct = kmalloc(8192, GFP_KERNEL);
+	if(c->lct==NULL)
X 	{
-		printk(KERN_ERR "IOP init failed; no memory.\n");
+		msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+		msg[1]= HOST_TID<<12|ADAPTER_TID;	/* NOP */
+		i2o_post_message(c,m);
+		printk(KERN_ERR "No free memory for i2o controller buffer.\n");
X 		return -ENOMEM;
X 	}
X 	
-	m=i2o_wait_message(c, "I2O HRT timeout.");
-	if(m==0xFFFFFFFF)
-	{	
-		kfree(workspace);
-		return -ETIMEDOUT;
-	}
+	memset(c->lct, 0, 8192);
X 	
-	msg=(u32 *)(c->mem_offset+m);
+	msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6;
+	msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID;
+	msg[2] = 0;		/* Context not needed */
+	msg[3] = 0;
+	msg[4] = 0xFFFFFFFF;	/* All devices */
+	msg[5] = 0x00000000;	/* Report now */
+	msg[6] = 0xD0000000|8192;
+	msg[7] = virt_to_bus(c->lct);
X 
-	msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4;
-	msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID;
-	msg[2]= 0x0;
-	msg[3]= 0x0;				/* Transaction context */
-	msg[4]= (0xD0000000 | 2048);		/* Simple transaction , 2K */
-	msg[5]= virt_to_phys(workspace);	/* Dump it here */
-	*((u32 *)workspace)=0xFFFFFFFF;
-	
X 	i2o_post_message(c,m);
-	
+
X 	barrier();
-	
-	/*
-	 *	Now wait for a reply
-	 */
-	 
-	m=i2o_wait_reply(c, "HRT table", 5);
-	 
+
+	/* Now wait for a reply */
+	m=i2o_wait_reply(c, "LCTNotify", 5);
+
X 	if(m==0xFFFFFFFF)
-	{
-		kfree(workspace);
X 		return -ETIMEDOUT;
-	}
-	
+
X 	msg=(u32 *)bus_to_virt(m);
-	
+
+	/* TODO: Check TableSize for big LCTs and send new ExecLctNotify 
+	 * with bigger workspace */
+
X 	if(msg[4]>>24)
-	{
-		i2o_report_status(KERN_WARNING, "i2o_core",
-				  (msg[1]>>24)&0xFF, (msg[4]>>24)&0xFF,
-				  msg[4]&0xFFFF);
-	}
-	I2O_REPLY_WRITE32(c,m);
-	
-	i2o_parse_hrt(c, workspace);
-	
-	kfree(workspace);
-	
-	return i2o_online_controller(c);
-//	i2o_report_controller_unit(c, ADAPTER_TID);
+		i2o_report_status(KERN_ERR, "i2o_core", msg);
+
+	return 0;
X }
X 
X 
@@ -1196,7 +1206,7 @@
X 	u32 systab[32];
X 	u32 privmem[2];
X 	u32 privio[2];
-	u32 *workspace;
+	int ret;
X 	
X 	systab[0]=1;
X 	systab[1]=0;
@@ -1216,7 +1226,7 @@
X 	privio[0]=c->priv_io;		/* Private I/O address */
X 	privio[1]=c->priv_io_size;
X 	
-	m=i2o_wait_message(c, "SetSysTab");
+	m=i2o_wait_message(c, "SysTabSet");
X 	if(m==0xFFFFFFFF)
X 		return -ETIMEDOUT;
X 	
@@ -1249,7 +1259,7 @@
X 	 */
X 	 
X 	 
-	m=i2o_wait_reply(c, "Systab read", 5);
+	m=i2o_wait_reply(c, "SysTabSet", 5);
X 		
X 	if(m==0xFFFFFFFF)
X 		return -ETIMEDOUT;
@@ -1258,9 +1268,7 @@
X 	
X 	if(msg[4]>>24)
X 	{
-		i2o_report_status(KERN_ERR, "i2o_core",
-				  (msg[1]>>24)&0xFF, (msg[4]>>24)&0xFF,
-				  msg[4]&0xFFFF);
+		i2o_report_status(KERN_ERR, "i2o_core", msg);
X 	}
X 	I2O_REPLY_WRITE32(c,m);
X 	
@@ -1268,7 +1276,7 @@
X 	 *	Finally we go online
X 	 */
X 	 
-	m=i2o_wait_message(c, "No message for SysEnable");
+	m=i2o_wait_message(c, "SysEnable");
X 	
X 	if(m==0xFFFFFFFF)
X 		return -ETIMEDOUT;
@@ -1289,7 +1297,7 @@
X 	 */
X 	 
X 	
-	m=i2o_wait_reply(c, "Enable", 240);
+	m=i2o_wait_reply(c, "SysEnable", 240);
X 
X 	if(m==0xFFFFFFFF)
X 		return -ETIMEDOUT;
@@ -1298,73 +1306,25 @@
X 	
X 	if(msg[4]>>24)
X 	{
-		i2o_report_status(KERN_ERR, "i2o_core",
-				  (msg[1]>>24)&0xFF, (msg[4]>>24)&0xFF,
-				  msg[4]&0xFFFF);
+		i2o_report_status(KERN_ERR, "i2o_core", msg);
X 	}
X 	I2O_REPLY_WRITE32(c,m);
X 	
X 	/*
X 	 *	Grab the LCT, see what is attached
X 	 */
-	 
-	m=i2o_wait_message(c, "No message for LCT");
-	
-	if(m==0xFFFFFFFF)
-		return -ETIMEDOUT;
-	
-	msg=(u32 *)(c->mem_offset+m);
-	
-	
-	workspace = kmalloc(8192, GFP_KERNEL);
-	if(workspace==NULL)
-	{
-		msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
-		msg[1]= HOST_TID<<12|ADAPTER_TID;	/* NOP */
-		i2o_post_message(c,m);
-		printk(KERN_ERR "No free memory for i2o controller buffer.\n");
-		return -ENOMEM;
-	}
-	
-	memset(workspace, 0, 8192);
-	
-	msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_6;
-	msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID;
-	msg[2] = 0;		/* Context not needed */
-	msg[3] = 0;
-	msg[4] = 0xFFFFFFFF;	/* All devices */
-	msg[5] = 0x00000000;	/* Report now */
-	msg[6] = 0xD0000000|8192;
-	msg[7] = virt_to_bus(workspace);
-	
-	i2o_post_message(c,m);
-	
-	barrier();
X 
-	/*
-	 *	Now wait for a reply
-	 */
-	 
-	m=i2o_wait_reply(c, "LCT", 5);
-	
-	if(m==0xFFFFFFFF)
+	ret=i2o_lct_get(c);
+	if(ret)
X 	{
-		kfree(workspace);
-		return -ETIMEDOUT;
+		/* Maybe we should do also sthg else */
+		return ret;
X 	}
-	
-	msg=(u32 *)bus_to_virt(m);
-	
-	if(msg[4]>>24)
-	{
-		i2o_report_status(KERN_ERR, "i2o_core",
-				  (msg[1]>>24)&0xFF, (msg[4]>>24)&0xFF,
-				  msg[4]&0xFFFF);
-	}
-	
-	i2o_parse_lct(c, workspace);
-	kfree(workspace);
-	
+
+	ret=i2o_parse_lct(c);
+	if(ret)
+		return ret;
+
X 	I2O_REPLY_WRITE32(c,m);
X 	
X 	return 0;
@@ -1417,16 +1377,21 @@
X 	*flag = 0;
X 		
X 	if(i2o_post_this(c, tid, data, len))
-		return -1;
+		return I2O_POST_WAIT_TIMEOUT;
X 		
X 	while(!*flag && (jiffies-t)<timeout*HZ)
X 	{
X 		schedule();
X 		mb();
X 	}
-	if(*flag <= 0)
-		return -1;
-	return 0;
+
+	if (*flag < 0)
+		return *flag; /* DetailedStatus */
+
+	if (*flag == 0)
+		return I2O_POST_WAIT_TIMEOUT;
+	
+	return I2O_POST_WAIT_OK;
X }
X 
X /*
@@ -1452,247 +1417,262 @@
X 	return i2o_post_wait(c, tid, msg, 20, flag,2);
X }
X 
+/*	Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET
+ *
+ *	This function can be used for all UtilParamsGet/Set operations.
+ *	The OperationBlock is given in opblk-buffer, 
+ *	and results are returned in resblk-buffer.
+ *	Note that the minimum sized resblk is 8 bytes and contains
+ *	ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
+ */
+int i2o_issue_params(int cmd, 
+                struct i2o_controller *iop, int tid, int context, 
+                void *opblk, int oplen, void *resblk, int reslen, 
+                int *flag)
+{
+        u32 msg[9]; 
+	u8 *res = (u8 *)resblk;
+	int res_count;
+	int blk_size;
+	int bytes;
+	int wait_status;
+
+        msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5;
+        msg[1] = cmd << 24 | HOST_TID << 12 | tid; 
+        msg[2] = context | 0x80000000;
+        msg[3] = (u32)flag;
+        msg[4] = 0;
+        msg[5] = 0x54000000 | oplen;	/* OperationBlock */
+        msg[6] = virt_to_bus(opblk);
+        msg[7] = 0xD0000000 | reslen;	/* ResultBlock */
+        msg[8] = virt_to_bus(resblk);
+
+        wait_status = i2o_post_wait(iop, tid, msg, sizeof(msg), flag, 10);
+	if (wait_status < 0)       
+                return wait_status; 	/* -DetailedStatus */
+
+        if (res[1]&0x00FF0000) 	/* BlockStatus != SUCCESS */
+        {
+                printk(KERN_WARNING "%s - Error:\n  ErrorInfoSize = 0x%02x, " 
+                	"BlockStatus = 0x%02x, BlockSize = 0x%04x\n",
+                        (cmd == I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET"
+                                                         : "PARAMS_GET",   
+                        res[1]>>24, (res[1]>>16)&0xFF, res[1]&0xFFFF);
+                return -((res[1] >> 16) & 0xFF); /* -BlockStatus */
+        }
+
+    	res_count = res[0] & 0xFFFF; /* # of resultblocks */
+    	bytes = 4; 
+    	res  += 4;
+    	while (res_count--)
+	{
+		blk_size = (res[0] & 0xFFFF) << 2;
+		bytes   += blk_size;
+		res     += blk_size;
+	}
+
+        return bytes; /* total sizeof Result List in bytes */
+}
+
+/*
+ *	 Query one scalar group value or a whole scalar group.
+ */                  	
+int i2o_query_scalar(struct i2o_controller *iop, int tid, int context, 
+                     int group, int field, void *buf, int buflen, int *flag)
+{
+	u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
+	u8  resblk[8+buflen]; /* 8 bytes for header */
+	int size;
+
+	if (field == -1)  		/* whole group */
+       		opblk[4] = -1;
+              
+        size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, iop, tid, context, 
+			opblk, sizeof(opblk), resblk, sizeof(resblk), flag);
+			
+	if (size < 0)
+		return size;	
+
+	memcpy(buf, resblk+8, buflen);  /* cut off header */
+	return buflen;
+}
+
X /*
- *	Query a scalar value
+ *	Set a scalar group value or a whole group.
X  */
-
-int i2o_query_scalar(struct i2o_controller *c, int tid, int context,
-		     int group, int field, void *buf, int buflen, int *flag)
+int i2o_set_scalar(struct i2o_controller *iop, int tid, int context, 
+		   int group, int field, void *buf, int buflen, int *flag)
X {
-	u16 *op;
-	u32 *bl;
-	u32 msg[9];
-
-	bl=kmalloc(buflen+64, GFP_KERNEL); /* Enough space for error replys */
-	if(bl==NULL)
-	{
-		printk(KERN_ERR "i2o: no memory for query buffer.\n");
-		return -ENOMEM;
-	}
-
-	op = (u16*)bl;
-	op[0]=1;			/* One Operation */
-	op[1]=0;			/* PAD */
-	op[2]=1;			/* FIELD_GET */
-	op[3]=group;			/* group number */
-	op[4]=1;			/* field count, default = 1 */
-	op[5]=field;			/* field index */
+	u16 *opblk;
+	u8  resblk[8+buflen]; /* 8 bytes for header */
+        int size;
+
+        opblk = kmalloc(buflen+64, GFP_KERNEL);
+        if (opblk == NULL)
+        {
+                printk(KERN_ERR "i2o: no memory for operation buffer.\n");
+                return -ENOMEM;
+        }
+
+        opblk[0] = 1;                        /* operation count */
+        opblk[1] = 0;                        /* pad */
+        opblk[2] = I2O_PARAMS_FIELD_SET;
+        opblk[3] = group;
+
+        if(field == -1) {               /* whole group */
+                opblk[4] = -1;
+                memcpy(opblk+5, buf, buflen);
+        }
+        else                            /* single field */
+        {
+                opblk[4] = 1;
+                opblk[5] = field;
+                memcpy(opblk+6, buf, buflen);
+        }   
X 
-	if(field == -1)
-	/* Single value or the whole group? */
-	{
-		op[4]=-1;
-		op[5]=0;
-	}
+        size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, context, 
+			opblk, 12+buflen, resblk, sizeof(resblk), flag);
X 
-	msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_5;
-	msg[1]=I2O_CMD_UTIL_PARAMS_GET<<24|HOST_TID<<12|tid;
-	msg[2]=context|0x80000000;	/* So we can pick it out */
-	msg[3]=(u32)flag;
-	msg[4]=0;
-	msg[5]=0x54000000|12;
-	msg[6]=virt_to_bus(bl);
-		/*
-		 *	There are 8 bytes of "overhead" required to pull in
-		 *	a Params ResultsList; 2 bytes for ResultCount
-		 *	(which should have value=1), plus 2 bytes for pad,
-		 *	plus 2 bytes for BlockSize, plus 1 byte BlockStatus,
-		 *	plus 1 byte ErrorInfoSize (8 bytes total overhead).
-		 *	This is followed finally by actual result value(s).
-		 *
-		 *	Tell the IOP to return 8 + buflen bytes.
-		 */
-	msg[7]=0xD0000000|(8+buflen);
-	msg[8]=virt_to_bus(bl+3);
-	
-	bl[3]=0xFCFCFCFC;		// Pad,ResultCount
-	bl[4]=0xFAFAFCFC;		// ErrorInfoSize,BlockStatus,BlockSize
-
-	/*
-	 *	Post the message and await a reply
-	 */
-
-	if (i2o_post_wait(c, tid, msg, sizeof(msg), flag,2) < 0)
-	{
-		kfree(bl);		
-		return -1;
-	}
-
-	if(bl[4]&0x00FF00000) /* BlockStatus != SUCCESS */
-	{
-		printk(KERN_WARNING "i2o_query_scalar - Error\n"
-			"ErrorInfoSize = 0x%02x, BlockStatus = 0x%02x, "
-			"BlockSize = 0x%04x\n", 
-			bl[4]>>24, (bl[4]>>16)&0xFF, bl[4]&0xFFFF);
-		kfree(bl);
-		return -1;
-	}
-	if((bl[3] & 0xFFFF) != 1)
-	{
-		printk(KERN_ERR "i2o: query ResultCount = 0x%04x\n", bl[3]&0xFFFF);
-	}
-	
-	memcpy(buf, bl+5, buflen);
-	kfree(bl);
-	return 0;
+	kfree(opblk);
+	return size;
X }
X 
-
-#if 0
X /* 
- * Query a table field 
- * FIXME: NOT TESTED! 
+ * 	if oper == I2O_PARAMS_TABLE_GET: 
+ *		Get all table group fields from all rows or
+ *		get specific table group fields from all rows.
+ *
+ * 		if fieldcount == -1 we query all fields from all rows
+ *			ibuf is NULL and ibuflen is 0
+ * 		else we query specific fields from all rows
+ *  			ibuf contains fieldindexes
+ *
+ * 	if oper == I2O_PARAMS_LIST_GET:
+ *		Get all table group fields from specified rows or
+ *		get specific table group fields from specified rows.
+ *
+ * 		if fieldcount == -1 we query all fields from specified rows
+ *			ibuf contains rowcount, keyvalues
+ * 		else we query specific fields from specified rows
+ *  			ibuf contains fieldindexes, rowcount, keyvalues
+ *
+ *	You could also use directly function i2o_issue_params().
X  */
-int i2o_query_table(struct i2o_controller *c, int tid, int context,
-		    void *buf, int buflen,
-		    int table,
-		    int *field, int fieldlen,
-		    u32 *key, int keylen,
-		    int *flag)
+int i2o_query_table(int oper,
+		struct i2o_controller *iop, int tid, int context, int group,
+		int fieldcount, void *ibuf, int ibuflen,
+		void *resblk, int reslen, int *flag) 
X {
-	static u16 op[32];
-	u32 *bl;
-	u32 msg[9];
-	int i;
+	u16 *opblk;
+	int size;
X 
-	bl=kmalloc(buflen+64, GFP_KERNEL);
-	if(bl==NULL)
+	opblk = kmalloc(10 + ibuflen, GFP_KERNEL);
+	if (opblk == NULL)
X 	{
X 		printk(KERN_ERR "i2o: no memory for query buffer.\n");
X 		return -ENOMEM;
X 	}
X 
-	op[0]=1;			/* Operation count */
-	op[1]=0;			/* Reserved */
-	op[2]=I2O_PARAMS_LIST_GET;	/* Operation */
-	op[3]=table;			/* Group */
-	/* Specific fields or the whole group? */
-	if(*field != -1)
-	{ /* FIXME: Fields can be variable size */
-		op[4]=fieldlen;
-		for (i=0; i < fieldlen; i++)
-			op[4+i]=field[i];
-	}
-	else
-	{
-		op[4]=-1;
-		op[5]=0;
-	}
-
-	memcpy(bl, op, 12);
-	       	
-	msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_5;
-	msg[1]=I2O_CMD_UTIL_PARAMS_GET<<24|HOST_TID<<12|tid;
-	msg[2]=context|0x80000000;	/* So we can pick it out */
-	msg[3]=(u32)flag;
-	msg[4]=0;
-	msg[5]=0x54000000|12;
-	msg[6]=virt_to_bus(bl);
+	opblk[0] = 1;				/* operation count */
+	opblk[1] = 0;				/* pad */
+	opblk[2] = oper;
+	opblk[3] = group;		
+	opblk[4] = fieldcount;
+	memcpy(opblk+5, ibuf, ibuflen);		/* other params */
X 
-	msg[7]=0xD0000000|(buflen+48);
-	msg[8]=virt_to_bus(bl+4);
+        size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET,iop, tid, context, 
+			opblk, 10+ibuflen, resblk, reslen, flag);
X 
-	/*
-	 *	Post the message and await a reply
-	 */
+	kfree(opblk);
+	return size;
+}
X 
-	if(i2o_post_wait(c, tid, msg, sizeof(msg), flag,2)<0)
-		return -1;
-	
-	if(bl[5]&0x00FF00000)	/* BlockStatus != SUCCESS */
-	{
-		printk(KERN_WARNING "i2o_query_table - Error\n"
-			"ErrorInfoSize = 0x%02x, BlockStatus = 0x%02x, "
-			"BlockSize = 0x%04x\n", 
-			bl[5]>>24, (bl[5]>>16)&0xFF, bl[5]&0xFFFF);
-		kfree(bl);
-		return -1;
-	}
+/*
+ * 	Clear table group, i.e. delete all rows.
+ */
X 
-	if((bl[4]&0xFFFF)!=1)
-		printk(KERN_ERR "i2o: query ResultCount = %0#4x\n",
-		       bl[4]&0xFFFF);
+int i2o_clear_table(struct i2o_controller *iop, int tid, int context,
+		    int group, int *flag)
+{
+	u16 opblk[] = { 1, 0, I2O_PARAMS_TABLE_CLEAR, group };
+	u8  resblk[32]; /* min 8 bytes for result header */
X 
-	memcpy(buf, bl+6, buflen);
-	kfree(bl);
-	return 0;
+        return i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, context, 
+			opblk, sizeof(opblk), resblk, sizeof(resblk), flag);
X }
-#endif
X 
X /*
- * Set (for now) scalar value
+ * 	Add a new row into a table group.
X  *
- * TODO: Add support for table groups
- */
+ * 	if fieldcount==-1 then we add whole rows
+ *		buf contains rowcount, keyvalues
+ * 	else just specific fields are given, rest use defaults
+ *  		buf contains fieldindexes, rowcount, keyvalues
+ */	
X 
-int i2o_params_set(struct i2o_controller *c, int tid, int context, int table,
-		   int field, void *buf, int buflen, int *flag)
+int i2o_row_add_table(struct i2o_controller *iop, int tid, int context,
+		    int group, int fieldcount, void *buf, int buflen,
+		    int *flag)
X {
-	static u16 opdata[]={1,0,6,0,1,4,0};
-	u32 *bl;
-	u32 msg[9];
+	u16 *opblk;
+	u8  resblk[32]; /* min 8 bytes for header */
+	int size;
X 
-	bl=kmalloc(buflen+64, GFP_KERNEL);
-	if(bl==NULL)
+	opblk = kmalloc(buflen+64, GFP_KERNEL);
+	if (opblk == NULL)
X 	{
-		printk(KERN_ERR "i2o: no memory for set buffer.\n");
+		printk(KERN_ERR "i2o: no memory for operation buffer.\n");
X 		return -ENOMEM;
X 	}
X 
-	opdata[3]=table;
-	/* Single value or the whole group? */
-	if(field != -1) {
-		opdata[4]=1;	
-		opdata[5]=field;
-		opdata[6]=*(u16 *)buf;
-	}
-	else {
-		opdata[4]=-1;
-		opdata[5]=0;
-	}
+	opblk[0] = 1;			/* operation count */
+	opblk[1] = 0;			/* pad */
+	opblk[2] = I2O_PARAMS_ROW_ADD;
+	opblk[3] = group;	
+	opblk[4] = fieldcount;
+	memcpy(opblk+5, buf, buflen);
X 
-	memcpy(bl, opdata, 14);
+        size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, context, 
+			opblk, 10+buflen, resblk, sizeof(resblk), flag);
X 
-	msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_5;
-	msg[1]=I2O_CMD_UTIL_PARAMS_SET<<24|HOST_TID<<12|tid;
-	msg[2]=context|0x80000000;	/* So we can pick it out */
-	msg[3]=(u32)flag;
-	msg[4]=0;
-	msg[5]=0x54000000|14;
-	msg[6]=virt_to_bus(bl);
-	msg[7]=0xD0000000|(buflen+48);
-	msg[8]=virt_to_bus(bl+4);
-	
-	/* Post the message and wait for a reply */
-	if(i2o_post_wait(c, tid, msg, 36, flag, 5)<0)
-	{
-		kfree(bl);
-		return -1;
-	}
+	kfree(opblk);
+	return size;
+}
X 
-	/* Perhaps we should check errors, eh? */
-	if(bl[5]&0x00FF00000)	/* BlockStatus != SUCCESS */
-	{
-		printk(KERN_WARNING "i2o_params_set - Error\n"
-			"ErrorInfoSize = %0#2x, BlockStatus = %0#2x, "
-			"BlockSize = %0#4x\n", 
-			bl[5]>>24, (bl[5]>>16)&0xFF, bl[5]&0xFFFF);
-		kfree(bl);
-		return -1;
-	}
+/*
+ *	Delete rows from a table group.
+ */ 
+
+int i2o_row_delete_table(struct i2o_controller *iop, int tid, int context,
+		    int group, int keycount, void *keys, int keyslen,
+		    int *flag)
+{
+	u16 *opblk; 
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 12'
echo 'File patch-2.3.10 is continued in part 13'
echo 13 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 13 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
+	u8  resblk[32]; /* min 8 bytes for header */
+	int size;
X 
-	if((bl[4] & 0xFFFF) != 1)
+	opblk = kmalloc(keyslen+64, GFP_KERNEL);
+	if (opblk == NULL)
X 	{
-		printk(KERN_ERR "i2o: params set ResultCount = %0#4x\n",
-		       bl[4]&0xFFFF);
+		printk(KERN_ERR "i2o: no memory for operation buffer.\n");
+		return -ENOMEM;
X 	}
X 
-	kfree(bl);
-	return 0;
-}
+	opblk[0] = 1;			/* operation count */
+	opblk[1] = 0;			/* pad */
+ opblk[2] = I2O_PARAMS_ROW_DELETE;
+	opblk[3] = group;	
+	opblk[4] = keycount;
+	memcpy(opblk+5, keys, keyslen);
X 
+        size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, context, 
+			opblk, 10+keyslen, resblk, sizeof(resblk), flag);
+
+	kfree(opblk);
+	return size;
+}
X 
-void report_common_status(u8 req_status)
+void i2o_report_common_status(u8 req_status)
X {
X 	/* the following reply status strings are common to all classes */
X 
@@ -1719,7 +1699,7 @@
X 	return;
X }
X 
-static void report_common_dsc(u16 detailed_status)
+static void i2o_report_common_dsc(u16 detailed_status)
X {
X 	/* The following detailed statuscodes are valid 
X 	   - for executive class, utility class, DDM class and
@@ -1766,7 +1746,7 @@
X 	return;
X }
X 
-void report_lan_dsc(u16 detailed_status)
+static void i2o_report_lan_dsc(u16 detailed_status)
X {
X 	static char *LAN_DSC[] = {	// Lan detailed status code strings
X 		"SUCCESS",
@@ -1786,10 +1766,11 @@
X 		"DEST_ADDRESS_DETECTED",
X 		"DEST_ADDRESS_OMITTED",
X 		"PARTIAL_PACKET_RETURNED",
-		"TEMP_SUSPENDED_STATE"
+		"TEMP_SUSPENDED_STATE",	// last Lan detailed status code
+		"INVALID_REQUEST"	// general detailed status code
X 	};
X 
-	if (detailed_status > I2O_LAN_DSC_TEMP_SUSPENDED_STATE)
+	if (detailed_status > I2O_DSC_INVALID_REQUEST)
X 		printk("%0#4x.\n", detailed_status);
X 	else
X 		printk("%s.\n", LAN_DSC[detailed_status]);
@@ -1797,7 +1778,7 @@
X 	return;	
X }
X 
-static void report_util_cmd(u8 cmd)
+static void i2o_report_util_cmd(u8 cmd)
X {
X 	switch (cmd) {
X 	case I2O_CMD_UTIL_NOP:
@@ -1850,7 +1831,7 @@
X }
X 
X 
-static void report_exec_cmd(u8 cmd)
+static void i2o_report_exec_cmd(u8 cmd)
X {
X 	switch (cmd) {
X 	case I2O_CMD_ADAPTER_ASSIGN:
@@ -1959,7 +1940,7 @@
X 	return;	
X }
X 
-static void report_lan_cmd(u8 cmd)
+static void i2o_report_lan_cmd(u8 cmd)
X {
X 	switch (cmd) {
X 	case LAN_PACKET_SEND:
@@ -1985,30 +1966,32 @@
X }
X 
X /* TODO: Add support for other classes */
-void i2o_report_status(const char *severity, const char *module, u8 cmd,
-		       u8 req_status, u16 detailed_status)
+void i2o_report_status(const char *severity, const char *module, u32 *msg)
X {
-	printk("%s", severity);
-	printk("%s: ", module);
+	u8 cmd = (msg[1]>>24)&0xFF;
+	u8 req_status = (msg[4]>>24)&0xFF;
+	u16 detailed_status = msg[4]&0xFFFF;
+
+	printk("%s%s: ", severity, module);
X 
X 	if (cmd < 0x1F) { 			// Utility Class
-		report_util_cmd(cmd);
-		report_common_status(req_status);
-		report_common_dsc(detailed_status);
+		i2o_report_util_cmd(cmd);
+		i2o_report_common_status(req_status);
+		i2o_report_common_dsc(detailed_status);
X 		return;
X 	}
X 
X 	if (cmd >= 0x30 && cmd <= 0x3F) {	// LAN class
-		report_lan_cmd(cmd);
-		report_common_status(req_status);		
-		report_lan_dsc(detailed_status);
+		i2o_report_lan_cmd(cmd);
+		i2o_report_common_status(req_status);		
+		i2o_report_lan_dsc(detailed_status);
X 		return;
X 	}
X 	
X 	if (cmd >= 0xA0 && cmd <= 0xEF) {	// Executive class
-		report_exec_cmd(cmd);
-		report_common_status(req_status);
-		report_common_dsc(detailed_status);
+		i2o_report_exec_cmd(cmd);
+		i2o_report_common_status(req_status);
+		i2o_report_common_dsc(detailed_status);
X 		return;
X 	}
X 	
@@ -2017,6 +2000,8 @@
X }
X 
X 
+#ifdef CONFIG_MODULE
+
X EXPORT_SYMBOL(i2o_install_handler);
X EXPORT_SYMBOL(i2o_remove_handler);
X EXPORT_SYMBOL(i2o_install_device);
@@ -2037,16 +2022,75 @@
X EXPORT_SYMBOL(i2o_get_class_name);
X 
X EXPORT_SYMBOL(i2o_query_scalar);
-EXPORT_SYMBOL(i2o_params_set);
+EXPORT_SYMBOL(i2o_set_scalar);
+EXPORT_SYMBOL(i2o_query_table);
+EXPORT_SYMBOL(i2o_clear_table);
+EXPORT_SYMBOL(i2o_row_add_table);
+EXPORT_SYMBOL(i2o_row_delete_table);
+
X EXPORT_SYMBOL(i2o_post_this);
X EXPORT_SYMBOL(i2o_post_wait);
X EXPORT_SYMBOL(i2o_issue_claim);
X 
X EXPORT_SYMBOL(i2o_report_status);
-EXPORT_SYMBOL(report_common_status);
-EXPORT_SYMBOL(report_lan_dsc);
-
-EXPORT_SYMBOL(i2o_wait_message);
X 
X MODULE_AUTHOR("Red Hat Software");
X MODULE_DESCRIPTION("I2O Core");
+
+
+int init_module(void)
+{
+        if (i2o_install_handler(&i2o_core_handler) < 0)
+        {
+                printk(KERN_ERR "i2o_core: Unable to install core handler.\n");
+                return 0;
+        }
+
+ core_context = i2o_core_handler.context;
+
+        return 0;
+}
+
+void cleanup_module(void)
+{
+	i2o_remove_handler(&i2o_core_handler);
+}
+
+#else
+
+extern int i2o_block_init(void);
+extern int i2o_config_init(void);
+extern int i2o_lan_init(void);
+extern int i2o_pci_init(void);
+extern int i2o_proc_init(void);
+extern int i2o_scsi_init(void);
+
+__init int i2o_init(void)
+{
+        if (i2o_install_handler(&i2o_core_handler) < 0)
+        {
+                printk(KERN_ERR "i2o_core: Unable to install core handler.\n");
+                return 0;
+        }
+
+        core_context = i2o_core_handler.context;
+#ifdef CONFIG_I2O_PCI
+	i2o_pci_init();
+#endif
+	i2o_config_init();
+#ifdef CONFIG_I2O_BLOCK
+	i2o_block_init();
+#endif
+#ifdef CONFIG_I2O_SCSI
+	i2o_scsi_init();
+#endif
+#ifdef CONFIG_I2O_LAN
+	i2o_lan_init();
+#endif
+#ifdef CONFIG_I2O_PROC
+	i2o_proc_init();
+#endif
+	return 0;
+}
+
+#endif
\ No newline at end of file
diff -u --recursive --new-file v2.3.9/linux/drivers/i2o/i2o_lan.c linux/drivers/i2o/i2o_lan.c
--- v2.3.9/linux/drivers/i2o/i2o_lan.c	Wed Jun 30 13:38:19 1999
+++ linux/drivers/i2o/i2o_lan.c	Mon Jul  5 20:09:40 1999
@@ -1,7 +1,7 @@
X /*
X  * 	linux/drivers/i2o/i2o_lan.c
X  *
- *    	I2O LAN CLASS OSM 	Prototyping, May 7th 1999
+ *    	I2O LAN CLASS OSM 	Prototyping, June 4th 1999
X  *
X  *	(C) Copyright 1999 	University of Helsinki,
X  *				Department of Computer Science
@@ -13,16 +13,19 @@
X  *      as published by the Free Software Foundation; either version
X  *      2 of the License, or (at your option) any later version.    
X  *
- * 	Author: 	Auvo Häkkinen <Auvo.H...@cs.Helsinki.FI>
+ * 	Authors: 	Auvo Häkkinen <Auvo.H...@cs.Helsinki.FI>
+ *			Juha Sievänen <Juha.S...@cs.Helsinki.FI>
X  *
X  *	Tested:		in FDDI environment (using SysKonnect's DDM)
- *			in ETH environment (using Intel 82558 DDM proto)
+ *			in Ethernet environment (using Intel 82558 DDM proto)
X  *
X  *	TODO:		batch mode networking
- *			- this one assumes that we always get one packet in a bucket
- *			- we've not been able to test batch replies and batch receives
- *			error checking / timeouts
- *			- code/test for other LAN classes
+ *			- this one assumes that we always get one packet 
+ *			  in a bucket
+ *			- we've not been able to test batch replies and 
+ *			  batch receives
+ *			- error checking / timeouts
+ *			- code / test for other LAN classes
X  */
X 
X #include <linux/config.h>
@@ -35,6 +38,7 @@
X #include <linux/if_arp.h>
X #include <linux/malloc.h>
X #include <linux/trdevice.h>
+#include <linux/init.h>
X #include <asm/io.h>
X 
X #include <linux/errno.h>
@@ -56,9 +60,9 @@
X struct i2o_lan_local {
X 	u8 unit;
X 	struct i2o_device *i2o_dev;
-	int reply_flag; 		// needed by scalar/table queries
-	struct fddi_statistics stats;
-/*	first fields are same as in struct net_device_stats stats; */ 
+	int reply_flag; 		/* needed by scalar/table queries */
+	u32 packet_tresh;		/* treshold for incoming skb's */	
+	struct fddi_statistics stats;   /* see also struct net_device_stats */ 
X 	unsigned short (*type_trans)(struct sk_buff *, struct device *);
X };
X 
@@ -66,6 +70,11 @@
X static int i2o_lan_receive_post(struct device *dev);
X static int i2o_lan_receive_post_reply(struct device *dev, struct i2o_message *m);
X 
+/*
+ * Module params
+ */
+static u32 bucketpost = 64;
+static u32 bucketthresh = 8;
X 
X static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop, 
X 			  struct i2o_message *m)
@@ -74,17 +83,25 @@
X 	u8 unit  = (u8)(msg[2]>>16); // InitiatorContext
X 	struct device *dev = i2o_landevs[unit];
X 
-#ifdef DRIVERDEBUG
-	i2o_report_status(KERN_INFO, "i2o_lan", msg[1]>>24, msg[4]>>24,
-			  msg[4]&0xFFFF);
-#endif
X     	if (msg[0] & (1<<13)) // Fail bit is set
X  	{
- 		printk(KERN_INFO "IOP failed to process the msg\n");
-		printk("From tid=%d to tid=%d",(msg[1]>>12)&0xFFF,msg[1]&0xFFF);
+ 		printk(KERN_ERR "IOP failed to process the msg:\n");
+		printk(KERN_ERR "  Cmd = 0x%02X, InitiatorTid = %d, TargetTid = %d\n",
+			(msg[1] >> 24) & 0xFF, (msg[1] >> 12) & 0xFFF, msg[1] & 0xFFF);
+		printk(KERN_ERR "  FailureCode = 0x%02X\n  Severity = 0x%02X\n  "
+			"LowestVersion = 0x%02X\n  HighestVersion = 0x%02X\n",
+			 msg[4] >> 24, (msg[4] >> 16) & 0xFF, 
+			(msg[4] >> 8) & 0xFF, msg[4] & 0xFF);
+		printk(KERN_ERR "  FailingHostUnit = 0x%04X\n  FailingIOP = 0x%03X\n",
+			msg[5] >> 16, msg[5] & 0xFFF);
X 		return;
X 	}	
X 
+#ifdef DRIVERDEBUG
+//	if (msg[4] >> 24) 	/* ReqStatus != SUCCESS */
+		i2o_report_status(KERN_INFO, "i2o_lan", msg);
+#endif
+
X 	switch (msg[1] >> 24) {
X 	case LAN_RECEIVE_POST: 
X 		if (dev->start) 
@@ -94,11 +111,9 @@
X 			u8 trl_count  = msg[3] & 0x000000FF; 	
X 			struct i2o_bucket_descriptor *bucket =
X 				(struct i2o_bucket_descriptor *)&msg[6];
-			struct sk_buff *skb;
X 			do {	
-				dprintk("Releasing unused bucket\n");
-				skb = (struct sk_buff *)bucket->context;
-				dev_kfree_skb(skb);
+				dprintk("%s: Releasing unused bucket\n",dev->name);
+				dev_kfree_skb((struct sk_buff *)bucket->context);
X 				bucket++;
X 			} while (--trl_count);
X 		}			
@@ -110,30 +125,30 @@
X 		u8 trl_count  = msg[3] & 0x000000FF; 	
X 		
X 		if (msg[4] >> 24) 	// ReqStatus != SUCCESS
-		{
-			printk(KERN_WARNING "%s: ",dev->name); 
-			report_common_status(msg[4]>>24);
-			report_lan_dsc(msg[4]&0xFFFF);
-		}
+			i2o_report_status(KERN_WARNING, dev->name, msg);
X 
-		do {	// The HDM has handled the outgoing packet
+		do { 	// The HDM has handled the outgoing packet
X 			dev_kfree_skb((struct sk_buff *)msg[4 + trl_count]);
X 			dprintk(KERN_INFO "%s: Request skb freed (trl_count=%d).\n",
X 				dev->name,trl_count);
X 		} while (--trl_count);
X 		
-			dev->tbusy = 0;
-			mark_bh(NET_BH); /* inform upper layers */
+		dev->tbusy = 0;
+		mark_bh(NET_BH); /* inform upper layers */
X 	}
X 	break;	
X 
X 	default: 
-		if (msg[2] & 0x80000000)  	// reply to a util get/set
-		{	// flag for the i2o_post_wait
-	       		int *flag = (int *)msg[3];
-	       		// ReqStatus != I2O_REPLY_STATUS_SUCCESS
-	      		 *flag = (msg[4] >> 24) ? I2O_POST_WAIT_TIMEOUT 
-	       				        : I2O_POST_WAIT_OK ;
+		if (msg[2] & 0x80000000)  // reply to a UtilParamsGet/Set
+		{	
+	       		int *flag = (int *)msg[3]; // flag for i2o_post_wait
+			if (msg[4] >> 24) // ReqStatus != SUCCESS
+			{
+				i2o_report_status(KERN_WARNING, dev->name, msg);
+	      		 	*flag = -(msg[4] & 0xFFFF); // DetailedStatus
+	      		}
+	      		else
+	      			*flag = I2O_POST_WAIT_OK;
X 		}
X 	}
X }
@@ -155,40 +170,54 @@
X 	struct i2o_packet_info *packet;
X 	
X 	u8 trl_count  = msg[3] & 0x000000FF; 	
-	struct sk_buff *skb;
+	struct sk_buff *skb, *newskb;
X 
-#ifdef 0
+#if 0
X 	dprintk(KERN_INFO "TrlFlags = 0x%02X, TrlElementSize = %d, TrlCount = %d\n"
X 		"msgsize = %d, buckets_remaining = %d\n", 
X 		msg[3]>>24, msg[3]&0x0000FF00, trl_count, msg[0]>>16, msg[5]);	
X #endif
+	dprintk(KERN_INFO "Buckets_remaining = %d\n",msg[5]);
X 
-/* 
- * NOTE: here we assume that also in batch mode we will get only 
- * one packet per bucket. This can be ensured by setting the 
- * PacketOrphanLimit to MaxPacketSize, as well as the bucket size.
- */
X 	do {
-		/* packet is not at all needed here */
+		skb = (struct sk_buff *)(bucket->context);		
X 		packet = (struct i2o_packet_info *)bucket->packet_info;	
-#ifdef 0
+#if 0
X 		dprintk(KERN_INFO "flags = 0x%02X, offset = 0x%06X, status = 0x%02X, length = %d\n",
X 			packet->flags, packet->offset, packet->status, packet->len);
X #endif
-		skb = (struct sk_buff *)(bucket->context);
-		skb_put(skb,packet->len);
-		skb->dev  = dev;		
-		skb->protocol = priv->type_trans(skb, dev);
-		netif_rx(skb);
+		if (packet->len < priv->packet_tresh) {
+			newskb = (struct sk_buff *)
+					dev_alloc_skb(packet->len+2);	
+			if (newskb) {
+				skb_reserve(newskb,2);
+				memcpy(skb_put(newskb,packet->len), 
+				       skb->data, packet->len);
+				newskb->dev = dev;
+				newskb->protocol = priv->type_trans(newskb, dev);
X 
+				netif_rx(newskb);
+				dev_kfree_skb(skb); // FIXME: reuse this skb? 
+			}
+			else {
+				printk("Can't allocate skb.\n");
+				return -ENOMEM;
+			}
+		} else {
+			skb_put(skb,packet->len);		
+			skb->dev  = dev;		
+			skb->protocol = priv->type_trans(skb, dev);
+
+			netif_rx(skb);
+		}
X 		dprintk(KERN_INFO "%s: Incoming packet (%d bytes) delivered "
X 			"to upper level.\n",dev->name,packet->len);
-			
-		bucket++; // to next Packet Descriptor Block
X 
+		bucket++; // to next Packet Descriptor Block
X 	} while (--trl_count);
X 
-	if (msg[5] <= I2O_BUCKET_THRESH)  	// BucketsRemaining
+
+	if (msg[5] <= bucketthresh)  	// BucketsRemaining
X 		i2o_lan_receive_post(dev);
X 
X 	return 0;
@@ -198,6 +227,7 @@
X  *  Interface to i2o:  functions to send lan class request 
X  */
X 
+
X /* 
X  * i2o_lan_receive_post(): Post buckets to receive packets.
X  */
@@ -211,25 +241,22 @@
X 	
X 	u32 bucket_len = (dev->mtu + dev->hard_header_len);
X 	u32 bucket_count;
-	int n_elems = (iop->inbound_size - 16 ) / 12; // msg header + SGLs
+	int n_elems = (iop->inbound_size - 16 ) / 12; /* msg header + SGLs */
X 	u32 total = 0;
X 	int i;
X 
-	dprintk(KERN_INFO "%s: Allocating %d buckets (size %d).\n", 
-		dev->name, I2O_BUCKET_COUNT, bucket_len);
-
-	while (total < I2O_BUCKET_COUNT)
+	while (total < bucketpost)
X 	{
X 		m = I2O_POST_READ32(iop);
X 		if (m == 0xFFFFFFFF)
X 			return -ETIMEDOUT;		
X 		msg = bus_to_virt(iop->mem_offset + m);
X 	
-		bucket_count = (total + n_elems < I2O_BUCKET_COUNT)
+		bucket_count = (total + n_elems < bucketpost)
X 			     ? n_elems
-			     : I2O_BUCKET_COUNT - total;
-			     
-		msg[0] = I2O_MESSAGE_SIZE(4 + 3 *  bucket_count) | 1<<12 | SGL_OFFSET_4;
+			     : bucketpost - total;
+
+		msg[0] = I2O_MESSAGE_SIZE(4 + 3 *  bucket_count) | SGL_OFFSET_4;
X 		msg[1] = LAN_RECEIVE_POST<<24 | HOST_TID<<12 | i2o_dev->id;
X 		msg[2] = priv->unit << 16 | lan_context; // InitiatorContext	
X 		msg[3] = bucket_count;			 // BucketCount
@@ -248,7 +275,7 @@
X 		i2o_post_message(iop,m);
X 
X 		dprintk(KERN_INFO "%s: Sending %d buckets (size %d) to LAN HDM.\n",
-			dev->name,bucket_count,bucket_len);
+			dev->name, bucket_count, bucket_len);
X 
X 		total += bucket_count;
X 	}
@@ -264,12 +291,7 @@
X 	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;	
X 	struct i2o_device *i2o_dev = priv->i2o_dev;
X 	struct i2o_controller *iop = i2o_dev->controller;	
-	u32 m; u32 *msg;
-
-	m = I2O_POST_READ32(iop);
-	if (m == 0xFFFFFFFF)
-		return -ETIMEDOUT;
-	msg = bus_to_virt(iop->mem_offset + m);
+	u32 msg[5];
X 
X 	msg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
X 	msg[1] = LAN_RESET<<24 | HOST_TID<<12 | i2o_dev->id;
@@ -277,7 +299,8 @@
X 	msg[3] = 0; 				 // TransactionContext
X 	msg[4] = 1 << 16; 			 // return posted buckets
X 
-	i2o_post_message(iop,m);
+	if (i2o_post_this(iop, i2o_dev->id, msg, sizeof(msg)) < 0)
+		return -ETIMEDOUT;		
X 
X 	return 0; 
X }
@@ -292,12 +315,7 @@
X 	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;	
X 	struct i2o_device *i2o_dev = priv->i2o_dev;
X 	struct i2o_controller *iop = i2o_dev->controller;	
-	u32 m; u32 *msg;
-
-	m = I2O_POST_READ32(iop);
-	if (m == 0xFFFFFFFF)
-		return -ETIMEDOUT;
-	msg = bus_to_virt(iop->mem_offset + m);
+	u32 msg[5];
X 
X 	msg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
X 	msg[1] = LAN_SUSPEND<<24 | HOST_TID<<12 | i2o_dev->id;
@@ -305,7 +323,8 @@
X 	msg[3] = 0; 				 // TransactionContext
X 	msg[4] = 1 << 16; 			 // return posted buckets
X 
-	i2o_post_message(iop,m);
+	if (i2o_post_this(iop, i2o_dev->id, msg, sizeof(msg)) < 0)
+		return -ETIMEDOUT;
X 
X 	return 0;
X }
@@ -330,12 +349,13 @@
X 
X 	// enable batch mode, toggle automatically
X 	val = 0x00000000;
-	if (i2o_params_set(iop, i2o_dev->id, lan_context, 0x0003, 0,
+//	val = 0x00000001; // turn off batch mode
+	if (i2o_set_scalar(iop, i2o_dev->id, lan_context, 0x0003, 0,
X 			&val, 4, &priv->reply_flag) <0)
X 		printk(KERN_WARNING "Unable to enter I2O LAN batch mode.\n");
X 	else
X 		dprintk(KERN_INFO "%s: I2O LAN batch mode enabled.\n",dev->name);
-
+//		dprintk(KERN_INFO "%s: I2O LAN batch mode disabled.\n",dev->name);
X 	/*
X 	 * When PacketOrphanlimit is same as the maximum packet length,
X 	 * the packets will never be split into two separate buckets
@@ -344,46 +364,12 @@
X 	/* set LAN_OPERATION attributes */
X 
X 	val = dev->mtu + dev->hard_header_len; // PacketOrphanLimit
-	if (i2o_params_set(iop, i2o_dev->id, lan_context, 0x0004, 2,
+	if (i2o_set_scalar(iop, i2o_dev->id, lan_context, 0x0004, 2,
X 		&val, 4, &priv->reply_flag) < 0)
X 		printk(KERN_WARNING "i2o_lan: Unable to set PacketOrphanLimit.\n");
X 	else
-		dprintk(KERN_INFO "PacketOrphanLimit set to %d\n",val);
-
-#ifdef 0
-/*
- * I2O spec 2.0: there should be proper default values for other attributes 
- * used in batch mode.
- */
-
-	/* set LAN_RECEIVE_INFO attributes */
-	
-	val = 10; // RxMaxBucketsReply
-	if (i2o_params_set(iop, i2o_dev->id, lan_context, 0x0008, 3,
-		&val, 4, &priv->reply_flag) < 0)
-		printk(KERN_WARNING "%s: Unable to set RxMaxBucketsReply.\n",
-			dev->name);
-
-	val = 10; // RxMaxPacketsBuckets
-	if (i2o_params_set(iop, i2o_dev->id, lan_context, 0x0008, 4,
-		&val, 4, &priv->reply_flag) < 0)
-		printk(KERN_WARNING "%s: Unable to set RxMaxPacketsBucket.\n",
-			dev->name);
-
-	/* set LAN_BATCH_CONTROL attributes */
-
-	val = 10; // MaxRxBatchCount
-	if (i2o_params_set(iop, i2o_dev->id, lan_context, 0x0003, 5,
-		&val, 4, &priv->reply_flag) < 0)
-		printk(KERN_WARNING "%s: Unable to set MaxRxBatchCount.\n",
-			dev->name);
-
-	val = 10; // MaxTxBatchCount
-	if (i2o_params_set(iop, i2o_dev->id, lan_context, 0x0003, 8,
-		&val, 4, &priv->reply_flag) < 0)
-		printk(KERN_WARNING "%s Unable to set MaxTxBatchCount.\n",
-			dev->name);
-#endif
+		dprintk(KERN_INFO "%s: PacketOrphanLimit set to %d\n",
+			dev->name,val);
X 
X 	return;	
X }
@@ -398,24 +384,26 @@
X 	struct i2o_device *i2o_dev = priv->i2o_dev;	
X 	struct i2o_controller *iop = i2o_dev->controller;
X 
-	i2o_lan_reset(dev);
-	
X 	if (i2o_issue_claim(iop, i2o_dev->id, lan_context, 1, 
-		&priv->reply_flag) < 0)
+			    &priv->reply_flag) < 0)
X 	{
X 		printk(KERN_WARNING "%s: Unable to claim the I2O LAN device.\n", dev->name);
X 		return -EAGAIN;
X 	}
X 	dprintk(KERN_INFO "%s: I2O LAN device claimed (tid=%d).\n", dev->name, i2o_dev->id);
X 
+	i2o_lan_reset(dev);
+	
X 	dev->tbusy = 0;
X 	dev->start = 1;
X 
+	priv->packet_tresh = dev->mtu - (dev->mtu >> 3);
+
X 	i2o_set_batch_mode(dev);
X 	i2o_lan_receive_post(dev);
X 
X 	MOD_INC_USE_COUNT;
-	
+
X 	return 0;
X }
X 
@@ -431,15 +419,16 @@
X 	dev->tbusy = 1;
X 	dev->start = 0;
X 
-	if (i2o_issue_claim(iop, i2o_dev->id, lan_context, 0, 
-	    &priv->reply_flag) < 0)
-	{
-		printk(KERN_WARNING "%s: Unable to unclaim I2O LAN device (tid=%d)\n",
-		       dev->name, i2o_dev->id);
-	}
+// This is the right place for LanSuspend, but it seems to cause 
+// a kernel crash when we are using 82558 HDM proto
X 
X 	i2o_lan_suspend(dev);
X 
+	if (i2o_issue_claim(iop, i2o_dev->id, lan_context, 0, 
+			    &priv->reply_flag) < 0)
+		printk(KERN_WARNING "%s: Unable to unclaim I2O LAN device "
+		       "(tid=%d)\n", dev->name, i2o_dev->id);
+
X 	MOD_DEC_USE_COUNT;
X 
X 	return 0;
@@ -452,7 +441,7 @@
X  */
X static int i2o_lan_sdu_send(struct sk_buff *skb, struct device *dev)
X {	
-#ifdef 0
+#if 0
X /* not yet tested */
X         struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; 
X         struct i2o_device *i2o_dev = priv->i2o_dev;     
@@ -461,13 +450,13 @@
X 
X 	dprintk(KERN_INFO "LanSDUSend called, skb->len = %d\n", skb->len);
X 
-        m = *iop->post_port;
-        if (m == 0xFFFFFFFF)
+        m = I2O_POST_READ32(iop);
+	if (m == 0xFFFFFFFF) 
X 	{
-                dev_kfree_skb(skb);     
-                return -1;
-        }
-        msg = bus_to_virt(iop->mem_offset + m);
+		dev_kfree_skb(skb);
+		return -ETIMEDOUT;
+	}    
+	msg = bus_to_virt(iop->mem_offset + m);
X 
X         msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_4;
X         msg[1] = LAN_SDU_SEND<<24 | HOST_TID<<12 | i2o_dev->id; 
@@ -483,7 +472,7 @@
X         msg[7] &= 0x0000FFFF;		   // followed by two bytes zeros
X         msg[8] = virt_to_bus(skb->data);
X         dev->trans_start = jiffies;
-        i2o_post_message(iop,m);
+	i2o_post_message(iop,m);
X 
X 	dprintk(KERN_INFO "%s: Packet (%d bytes) sent to network.\n",
X 		dev->name,skb->len);
@@ -502,16 +491,15 @@
X 	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;	
X 	struct i2o_device *i2o_dev = priv->i2o_dev;	
X 	struct i2o_controller *iop = i2o_dev->controller;
-	u32 m; u32 *msg;
+        u32 m; u32 *msg;
X 
-	m = *iop->post_port;
+        m = I2O_POST_READ32(iop);
X 	if (m == 0xFFFFFFFF) {
X 		dev_kfree_skb(skb);
-		return -1;
-	}
-
+		return -ETIMEDOUT;
+	}    
X 	msg = bus_to_virt(iop->mem_offset + m);
-
+	
X 	msg[0] = SEVEN_WORD_MSG_SIZE | 1<<12 | SGL_OFFSET_4;
X 	msg[1] = LAN_PACKET_SEND<<24 | HOST_TID<<12 | i2o_dev->id;	
X 	msg[2] = priv->unit << 16 | lan_context; // IntiatorContext
@@ -524,37 +512,130 @@
X 	msg[5] = (u32)skb; 			// TransactionContext
X 	msg[6] = virt_to_bus(skb->data);
X 
-	i2o_post_message(iop,m);
-
+        i2o_post_message(iop,m);
+        
X 	dprintk(KERN_INFO "%s: Packet (%d bytes) sent to network.\n",
X 		dev->name, skb->len);
X 
X 	return 0;
X }
X 
-/*
- * net_device_stats(): Return statistical information.
- */
X static struct net_device_stats *i2o_lan_get_stats(struct device *dev)
X {
X 	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;	
X 	struct i2o_device *i2o_dev = priv->i2o_dev;
X 	struct i2o_controller *iop = i2o_dev->controller;
-	u64 val[16];
+	u64 val64[16];
+	u64 supported_group[4] = { 0, 0, 0, 0 };
X 
-	/* query LAN_HISTORICAL_STATS scalar parameter group 0x0100 */
+        if (i2o_query_scalar(iop, i2o_dev->id, lan_context, 0x0100, -1, 
+        		 val64, sizeof(val64), &priv->reply_flag) < 0)
+        	dprintk("%s: Unable to query LAN_HISTORICAL_STATS.\n",dev->name);
+	else {
+        	dprintk("%s: LAN_HISTORICAL_STATS queried.\n",dev->name);
+        	priv->stats.tx_packets = val64[0];
+        	priv->stats.tx_bytes   = val64[1];
+        	priv->stats.rx_packets = val64[2];
+        	priv->stats.rx_bytes   = val64[3];
+        	priv->stats.tx_errors  = val64[4];
+        	priv->stats.rx_errors  = val64[5];
+		priv->stats.rx_dropped = val64[6];
+	}
X 
-        i2o_query_scalar(iop, i2o_dev->id, lan_context, 0x0100, -1, 
-        		 &val, 16*8, &priv->reply_flag);
-        priv->stats.tx_packets = val[0];
-        priv->stats.tx_bytes   = val[1];
-        priv->stats.rx_packets = val[2];
-        priv->stats.rx_bytes   = val[3];
-        priv->stats.tx_errors  = val[4];
-        priv->stats.rx_errors  = val[5];
-	priv->stats.rx_dropped = val[6];
+        i2o_query_scalar(iop, i2o_dev->id, lan_context, 0x0180, -1, 
+        		&supported_group, sizeof(supported_group), &priv->reply_flag);
X 
-	// other net_device_stats and FDDI class specific fields follow ...
+	if (supported_group[2]) {
+        	if (i2o_query_scalar(iop, i2o_dev->id, lan_context, 0x0183, -1, 
+        	 	val64, sizeof(val64), &priv->reply_flag) < 0)
+        		dprintk("%s: Unable to query LAN_OPTIONAL_RX_HISTORICAL_STATS.\n",dev->name);
+		else {
+        		dprintk("%s: LAN_OPTIONAL_RX_HISTORICAL_STATS queried.\n",dev->name);
+			priv->stats.multicast        = val64[4];
+			priv->stats.rx_length_errors = val64[10];
+			priv->stats.rx_crc_errors    = val64[0];
+		}
+	}
+
+	if (i2o_dev->subclass == I2O_LAN_ETHERNET)
+	{
+		u64 supported_stats = 0;		
+
+        	if (i2o_query_scalar(iop, i2o_dev->id, lan_context, 0x0200, -1, 
+        			 val64, sizeof(val64), &priv->reply_flag) < 0)
+        		dprintk("%s: Unable to query LAN_802_3_HISTORICAL_STATS.\n",dev->name);
+		else {
+        		dprintk("%s: LAN_802_3_HISTORICAL_STATS queried.\n",dev->name);
+	 		priv->stats.transmit_collision = val64[1] + val64[2];
+			priv->stats.rx_frame_errors    = val64[0];		
+			priv->stats.tx_carrier_errors  = val64[6];
+		}
+	
+        	i2o_query_scalar(iop, i2o_dev->id, lan_context, 0x0280, -1, 
+        			 &supported_stats, 8, &priv->reply_flag);
+        			
+        	if (supported_stats != 0) {
+        		if (i2o_query_scalar(iop, i2o_dev->id, lan_context, 0x0281, -1, 
+        				 val64, sizeof(val64), &priv->reply_flag) < 0)
+        			dprintk("%s: Unable to query LAN_OPTIONLA_802_3_HISTORICAL_STATS.\n",dev->name);
+			else {
+        			dprintk("%s: LAN_OPTIONAL_802_3_HISTORICAL_STATS queried.\n",dev->name);
+				if (supported_stats & 0x1)
+					priv->stats.rx_over_errors = val64[0];
+				if (supported_stats & 0x4)
+					priv->stats.tx_heartbeat_errors = val64[2];
+			}
+		}
+	}
+
+#ifdef CONFIG_TR
+	if (i2o_dev->subclass == I2O_LAN_TR)
+	{
+        	if (i2o_query_scalar(iop, i2o_dev->id, lan_context, 0x0300, -1, 
+        			 val64, sizeof(val64), &priv->reply_flag) < 0)
+        		dprintk("%s: Unable to query LAN_802_5_HISTORICAL_STATS.\n",dev->name);
+		else {
+			struct tr_statistics *stats = 
+					(struct tr_statistics *)&priv->stats;
+        		dprintk("%s: LAN_802_5_HISTORICAL_STATS queried.\n",dev->name);
+
+			stats->line_errors		= val64[0];
+			stats->internal_errors		= val64[7];
+			stats->burst_errors		= val64[4];
+			stats->A_C_errors		= val64[2];
+			stats->abort_delimiters		= val64[3];
+			stats->lost_frames		= val64[1];
+			/* stats->recv_congest_count	= ?;  FIXME ??*/
+			stats->frame_copied_errors	= val64[5];
+			stats->frequency_errors		= val64[6];
+			stats->token_errors		= val64[9];
+		}
+		/* Token Ring optional stats not yet defined */
+	}
+#endif
+
+#ifdef CONFIG_FDDI
+	if (i2o_dev->subclass == I2O_LAN_FDDI)
+	{
+        	if (i2o_query_scalar(iop, i2o_dev->id, lan_context, 0x0400, -1, 
+        			 val64, sizeof(val64), &priv->reply_flag) < 0)
+        		dprintk("%s: Unable to query LAN_FDDI_HISTORICAL_STATS.\n",dev->name);
+		else {
+        		dprintk("%s: LAN_FDDI_HISTORICAL_STATS queried.\n",dev->name);
+			priv->stats.smt_cf_state = val64[0];
+			memcpy(priv->stats.mac_upstream_nbr, &val64[1], FDDI_K_ALEN);
+			memcpy(priv->stats.mac_downstream_nbr, &val64[2], FDDI_K_ALEN);			
+			priv->stats.mac_error_cts = val64[3];
+			priv->stats.mac_lost_cts  = val64[4];
+			priv->stats.mac_rmt_state = val64[5];
+			memcpy(priv->stats.port_lct_fail_cts, &val64[6], 8);
+			memcpy(priv->stats.port_lem_reject_cts, &val64[7], 8);	
+			memcpy(priv->stats.port_lem_cts, &val64[8], 8);
+			memcpy(priv->stats.port_pcm_state, &val64[9], 8);
+		}
+		/* FDDI optional stats not yet defined */
+	}		
+#endif
X 
X 	return (struct net_device_stats *)&priv->stats;
X }
@@ -569,75 +650,78 @@
X 	struct i2o_device *i2o_dev = priv->i2o_dev;
X 	struct i2o_controller *iop = i2o_dev->controller;
X 	u32 filter_mask;
+	u32 work32[64];
X 
-	dprintk(KERN_INFO "Entered i2o_lan_set_multicast_list().\n");
+	dprintk(KERN_INFO "%s: Entered i2o_lan_set_multicast_list().\n", dev->name);
X 
X return;
X 
-/*
- * FIXME: For some reason this kills interrupt handler in i2o_post_wait :-(
- * 
+/* FIXME: Why does the next call kill the interrupt handler?
+ * The same works fine in function lan_open(), and in i2o_proc.c
+ *
+ *  *because its trying to sleep in an irq - this must be async - Alan
X  */
-	dprintk(KERN_INFO "dev->flags = 0x%08X, dev->mc_count = 0x%08X\n",
-		dev->flags,dev->mc_count);
X 
-	if (i2o_query_scalar(iop, i2o_dev->id, lan_context, 0x0001, 3, 
-			     &filter_mask, 4, &priv->reply_flag) < 0 )
-		printk(KERN_WARNING "i2o_lan: Unable to query filter mask.\n");	
+	if (i2o_query_scalar(iop, i2o_dev->id, lan_context, 0x0001, -1,
+			     &work32, sizeof(work32), &priv->reply_flag) < 0 ) 
+	{
+		printk(KERN_WARNING "i2o_lan: Unable to query "
+			" LAN_MAC_ADDRESS table.\n");	
+		return;
+	}
+	printk(KERN_INFO "capab mask = 0x%08X, filter mask = 0x%08X\n",
+		work32[7], work32[6]);
X 
-	dprintk(KERN_INFO "filter_mask = 0x%08X\n",filter_mask);
+	filter_mask = work32[6];
X 
X 	if (dev->flags & IFF_PROMISC)
X 	{
-        	// Enable promiscuous mode
-
X 		filter_mask |= 0x00000002; 
-		if (i2o_params_set(iop, i2o_dev->id, lan_context, 0x0001, 3,
-				&filter_mask, 4, &priv->reply_flag) <0)
-			printk(KERN_WARNING "i2o_lan: Unable to enable promiscuous multicast mode.\n");
-		else
-			dprintk(KERN_INFO "i2o_lan: Promiscuous multicast mode enabled.\n");
-
-		return;
+		dprintk(KERN_INFO "i2o_lan: Enabling promiscuous mode...\n");
X         }
X         
-// 	if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS)
-// 	{
-//        	// Disable promiscuous mode, use normal mode.
-// 		hardware_set_filter(NULL);
-//
-//		dprintk(KERN_INFO "i2o_lan: Disabled promiscuous mode, uses normal mode\n"); 
-//
-//		filter_mask = 0x00000000; 
-//		i2o_params_set(iop, i2o_dev->id, lan_context, 0x0001, 3,
-//				&filter_mask, 4, &priv->reply_flag);
-//		
-//		return;
-//      }
+ 	else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > work32[5])
+ 	{
+		filter_mask |= 0x00000000; 
+		dprintk(KERN_INFO "i2o_lan: Enabling all multicast mode...\n");
+	}
X 
-        if (dev->mc_count)
-	{
-        	// Walk the address list, and load the filter
-//              hardware_set_filter(dev->mc_list);
+        else if (dev->mc_count)
+	{	
+		struct dev_mc_list *mclist;
+		int i;
+		u8 *work8 = (u8 *)work32;
X 
+		dprintk(KERN_INFO "i2o_lan: Enabling multicast mode...\n");
X                 filter_mask = 0x00000004; 
-		if (i2o_params_set(iop, i2o_dev->id, lan_context, 0x0001, 3,
-				   &filter_mask, 4, &priv->reply_flag) <0)
-			printk(KERN_WARNING "i2o_lan: Unable to enable Promiscuous multicast mode.\n");
-		else
-			dprintk(KERN_INFO "i2o_lan: Promiscuous multicast mode enabled.\n");			
-        
-       		return;
-	}
-        
-        // Unicast
-        
-        filter_mask |= 0x00000300; // Broadcast, Multicast disabled
-	if (i2o_params_set(iop, i2o_dev->id, lan_context, 0x0001, 3,
+
+		/* Fill the multicast addresses */
+		mclist = dev->mc_list;
+
+		for (i = 0; i < dev->mc_count; i++)
+		{	
+			memcpy(work8, mclist->dmi_addr, mclist->dmi_addrlen);
+			work8 += 8;
+			mclist = mclist->next;
+		} 
+
+		if (i2o_clear_table(iop, i2o_dev->id, lan_context, 0x0002,
+				&priv->reply_flag) < 0 ) 
+			dprintk("%s: Unable to clear LAN_MULTICAST_MAC_ADDRESS table.\n",dev->name);
+
+		if (i2o_row_add_table(iop, i2o_dev->id, lan_context, 0x0002, -1,
+			work32, dev->mc_count*8, &priv->reply_flag) < 0)	
+			dprintk("%s: Unable to set LAN_MULTICAST_MAC_ADDRESS table.\n",dev->name);
+	} 
+	
+	else {
+        	filter_mask |= 0x00000300; // Broadcast, Multicast disabled
+		dprintk(KERN_INFO "i2o_lan: Enabling unicast mode...\n");
+        }
+
+	if (i2o_set_scalar(iop, i2o_dev->id, lan_context, 0x0001, 3,
X 			&filter_mask, 4, &priv->reply_flag) <0)
-		printk(KERN_WARNING "i2o_lan: Unable to enable unicast mode.\n");
-	else
-		dprintk(KERN_INFO "i2o_lan: Unicast mode enabled.\n");	
+		printk(KERN_WARNING "i2o_lan: Unable to set MAC FilterMask.\n");
X 
X 	return;
X }
@@ -648,34 +732,31 @@
X 	struct i2o_lan_local *priv = NULL;
X 	u8 hw_addr[8];
X 	unsigned short (*type_trans)(struct sk_buff *, struct device *);
+	void (*unregister_dev)(struct device *dev);
X 
X 	switch (i2o_dev->subclass)
X 	{
X 	case I2O_LAN_ETHERNET:
-		/* Note: init_etherdev calls 
-			 ether_setup() and register_netdevice() 
-			 and allocates the priv structure	 */
-
X         	dev = init_etherdev(NULL, sizeof(struct i2o_lan_local));
X 		if (dev == NULL)
X 			return NULL;
X 		type_trans = eth_type_trans;
+		unregister_dev = unregister_netdev;
X 		break;
X 
-/*
X #ifdef CONFIG_ANYLAN
X 	case I2O_LAN_100VG:
-		printk(KERN_WARNING "i2o_lan: 100base VG not yet supported\n");
+		printk(KERN_ERR "i2o_lan: 100base VG not yet supported\n");
X 		break;
X #endif
-*/
X 
X #ifdef CONFIG_TR
X 	case I2O_LAN_TR:
X 		dev = init_trdev(NULL, sizeof(struct i2o_lan_local));
-		if(dev==NULL)
+		if (dev==NULL)
X 			return NULL;
X 		type_trans = tr_type_trans;
+		unregister_dev = unregister_trdev;		
X 		break;
X #endif
X 
@@ -697,23 +778,23 @@
X 			return NULL;
X 		}
X 		type_trans = fddi_type_trans;
-
+		unregister_dev = (void *)unregister_netdevice;
+		
X 		fddi_setup(dev);
X 		register_netdev(dev);
X       	}
X 	break;
X #endif
X 
-/*
X #ifdef CONFIG_FIBRE_CHANNEL
X 	case I2O_LAN_FIBRE_CHANNEL:
-		printk(KERN_WARNING "i2o_lan: Fibre Channel not yet supported\n");
+		printk(KERN_INFO "i2o_lan: Fibre Channel not yet supported\n");
X 	break;
X #endif
-*/
+
X 	case I2O_LAN_UNKNOWN:
X 	default:
-		printk(KERN_WARNING "i2o_lan: LAN type 0x%08X not supported\n",
+		printk(KERN_ERR "i2o_lan: LAN type 0x%08X not supported\n",
X 		       i2o_dev->subclass);
X 		return NULL;
X 	}
@@ -721,16 +802,17 @@
X 	priv = (struct i2o_lan_local *)dev->priv;
X 	priv->i2o_dev = i2o_dev;
X 	priv->type_trans = type_trans;
-
+	
X         if (i2o_query_scalar(i2o_dev->controller, i2o_dev->id, lan_context,
X 			     0x0001, 0, &hw_addr, 8, &priv->reply_flag) < 0)
X 	{
-        	printk("%s: Unable to query hardware address.\n",
-		       dev->name);
+        	printk(KERN_ERR "%s: Unable to query hardware address.\n", dev->name);
+		unregister_dev(dev);
+		kfree(dev);
X       		return NULL;  
X         }
-        
-	dprintk("%s hwaddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
+
+	dprintk("%s: hwaddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
X       		dev->name,hw_addr[0], hw_addr[1], hw_addr[2], hw_addr[3],
X       		hw_addr[4], hw_addr[5]);
X 
@@ -747,8 +829,10 @@
X }
X 
X #ifdef MODULE
+#define i2o_lan_init	init_module
+#endif
X 
-int init_module(void)
+__init int i2o_lan_init(void)
X {
X 	struct device *dev;
X 	struct i2o_lan_local *priv;
@@ -772,13 +856,12 @@
X 
X                 for (i2o_dev=iop->devices;i2o_dev != NULL;i2o_dev=i2o_dev->next)
X 		{
-                        int class = i2o_dev->class;
-
-                        if (class != 0x020) /* not I2O_CLASS_LAN device*/ 
+                        if (i2o_dev->class != I2O_CLASS_LAN) 
X                                 continue;
X 
X 			if (unit == MAX_LAN_CARDS)
X 			{
+				i2o_unlock_controller(iop);
X 				printk(KERN_WARNING "Too many I2O LAN devices.\n");
X 				return -EINVAL;
X 			}
@@ -786,7 +869,7 @@
X 			dev = i2o_lan_register_device(i2o_dev);
X  			if (dev == NULL)
X 			{
-				printk(KERN_WARNING "Unable to register I2O LAN device\n");
+				printk(KERN_ERR "Unable to register I2O LAN device\n");
X 				continue; // try next one
X 			}
X 			priv = (struct i2o_lan_local *)dev->priv;	
@@ -800,6 +883,7 @@
X 				dev->name, i2o_dev->id, i2o_dev->subclass, 
X 				priv->unit);
X                 }
+		i2o_unlock_controller(iop);
X         }
X 
X 	dprintk(KERN_INFO "%d I2O LAN devices found and registered.\n", unit+1);
@@ -807,6 +891,8 @@
X 	return 0;
X }
X 
+#ifdef MODULE
+
X void cleanup_module(void)
X {
X 	int i;
@@ -831,7 +917,7 @@
X #endif
X #ifdef CONFIG_TR
X 		case I2O_LAN_TR:
-			unregister_netdev(dev);
+			unregister_trdev(dev);
X 			kfree(dev);
X 			break;
X #endif
@@ -848,7 +934,11 @@
X }
X 
X EXPORT_NO_SYMBOLS;
+
X MODULE_AUTHOR("Univ of Helsinki, CS Department");
X MODULE_DESCRIPTION("I2O Lan OSM");
+
+MODULE_PARM(bucketpost, "i");           // Number of buckets to post
+MODULE_PARM(bucketthresh, "i"); // Bucket post threshold
X 
X #endif    
diff -u --recursive --new-file v2.3.9/linux/drivers/i2o/i2o_lan.h linux/drivers/i2o/i2o_lan.h
--- v2.3.9/linux/drivers/i2o/i2o_lan.h	Wed Jun  2 14:40:22 1999
+++ linux/drivers/i2o/i2o_lan.h	Mon Jul  5 20:09:40 1999
@@ -1,7 +1,7 @@
X /*
X  *   	i2o_lan.h		LAN Class specific definitions
X  *
- *      I2O LAN CLASS OSM       Prototyping, May 7th 1999
+ *      I2O LAN CLASS OSM       Prototyping, May 17th 1999
X  *
X  *      (C) Copyright 1999      University of Helsinki,
X  *                              Department of Computer Science
@@ -9,16 +9,16 @@
X  *      This code is still under development / test.
X  *
X  *      Author:         Auvo Häkkinen <Auvo.H...@cs.Helsinki.FI>
- *    
+ *			Juha Sievänen <Juha.S...@cs.Helsinki.FI>    
X  */
X 
-#ifndef I2O_LAN_H
-#define I2O_LAN_H
+#ifndef _I2O_LAN_H
+#define _I2O_LAN_H
X 
X /* Tunable parameters first */
X 
-#define I2O_BUCKET_COUNT 	64
-#define I2O_BUCKET_THRESH	5
+#define I2O_BUCKET_COUNT 	16
+#define I2O_BUCKET_THRESH	0
X 
X /* LAN types */
X #define I2O_LAN_ETHERNET	0x0030
@@ -75,7 +75,7 @@
X #define LAN_SDU_SEND		0x3D
X #define LAN_RECEIVE_POST	0x3E
X #define LAN_RESET		0x35
-#define LAN_SUSPEND	0x37
+#define LAN_SUSPEND		0x37
X 
X /* LAN DetailedStatusCode defines */
X #define I2O_LAN_DSC_SUCCESS			0x00
@@ -109,4 +109,4 @@
X 	struct i2o_packet_info packet_info[1];
X };
X  
-#endif /* I2O_LAN_H */
+#endif /* _I2O_LAN_H */
diff -u --recursive --new-file v2.3.9/linux/drivers/i2o/i2o_pci.c linux/drivers/i2o/i2o_pci.c
--- v2.3.9/linux/drivers/i2o/i2o_pci.c	Wed Jun 30 13:38:19 1999
+++ linux/drivers/i2o/i2o_pci.c	Mon Jul  5 20:09:40 1999
@@ -10,6 +10,9 @@
X  *	modify it under the terms of the GNU General Public License
X  * 	as published by the Free Software Foundation; either version
X  *	2 of the License, or (at your option) any later version.
+ *
+ *	TODO:
+ *		Support polled I2O PCI controllers. 
X  */
X  
X #include <linux/module.h>
@@ -187,9 +190,9 @@
X 		c=i2o_find_controller(i);
X 		if(c==NULL)
X 			continue;		
+		i2o_unlock_controller(c);
X 		if(c->type == I2O_TYPE_PCI)
X 			i2o_delete_controller(c);
-		i2o_unlock_controller(c);
X 	}
X }
X 
@@ -209,7 +212,6 @@
X 			{
X 				printk("I2O: Failed to initialize iop%d\n", c->unit);
X 				i2o_unlock_controller(c);
-				free_irq(c->bus.pci.irq, c);
X 				i2o_delete_controller(c);
X 				continue;
X 			}
@@ -239,4 +241,13 @@
X 	i2o_pci_unload();
X }
X 
+#else
+__init void i2o_pci_init(void)
+{
+	if(i2o_pci_scan()>=0)
+	{
+		printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n");
+		i2o_pci_activate();
+	}
+}
X #endif
diff -u --recursive --new-file v2.3.9/linux/drivers/i2o/i2o_proc.c linux/drivers/i2o/i2o_proc.c
--- v2.3.9/linux/drivers/i2o/i2o_proc.c	Wed Jun 30 13:38:19 1999
+++ linux/drivers/i2o/i2o_proc.c	Mon Jul  5 20:09:40 1999
@@ -17,9 +17,9 @@
X  *   DISCLAIMER: This code is still under development/test and may cause
X  *   your system to behave unpredictably.  Use at your own discretion.
X  *
- *   LAN entries by Juha Sievänen(Juha.S...@cs.Helsinki.FI),
+ *   LAN entries by Juha Sievänen (Juha.S...@cs.Helsinki.FI),
+ *		    Auvo Häkkinen (Auvo.H...@cs.Helsinki.FI)
X  *   University of Helsinki, Department of Computer Science
- *
X  */
X 
X /*
@@ -61,8 +61,8 @@
X  */
X typedef struct _i2o_proc_entry_t
X {
-	char *name;						/* entry name */
-	mode_t mode;					/* mode */
+	char *name;			/* entry name */
+	mode_t mode;			/* mode */
X 	read_proc_t *read_proc;		/* read func */
X 	write_proc_t *write_proc;	/* write func */
X } i2o_proc_entry;
@@ -74,66 +74,66 @@
X static int i2o_proc_read_hrt(char *, char **, off_t, int, int *, void *);
X static int i2o_proc_read_stat(char *, char **, off_t, int, int *, void *);
X static int i2o_proc_read_hw(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_dst(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_ddm_table(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_ds(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_groups(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_priv_msgs(char *, char **, off_t, int, int *, void *);
X static int i2o_proc_read_dev(char *, char **, off_t, int, int *, void *);
X static int i2o_proc_read_dev_name(char *, char **, off_t, int, int *, void *);
X static int i2o_proc_read_ddm(char *, char **, off_t, int, int *, void *);
X static int i2o_proc_read_uinfo(char *, char **, off_t, int, int *, void *);
+static int i2o_proc_read_sgl_limits(char *, char **, off_t, int, int *, void *);
X static int print_serial_number(char *, int, u8 *, int);
X static int i2o_proc_create_entries(void *, 
-	i2o_proc_entry *p, struct proc_dir_entry *);
-static void i2o_proc_remove_entries(i2o_proc_entry *p, 
-	struct proc_dir_entry *);
+				   i2o_proc_entry *, struct proc_dir_entry *);
+static void i2o_proc_remove_entries(i2o_proc_entry *, struct proc_dir_entry *);
X static int i2o_proc_add_controller(struct i2o_controller *, 
-	struct proc_dir_entry * );
+				   struct proc_dir_entry * );
X static void i2o_proc_remove_controller(struct i2o_controller *, 
-	struct proc_dir_entry * );
+				       struct proc_dir_entry * );
X static int create_i2o_procfs(void);
X static int destroy_i2o_procfs(void);
X static void i2o_proc_reply(struct i2o_handler *, struct i2o_controller *,
-			struct i2o_message *);
+			   struct i2o_message *);
X 
X static int i2o_proc_read_lan_dev_info(char *, char **, off_t, int, int *,
X 				      void *);
X static int i2o_proc_read_lan_mac_addr(char *, char **, off_t, int, int *,
X 				      void *);
-static int i2o_proc_read_lan_curr_addr(char *, char **, off_t, int, int *,
-				       void *);
-#if 0
X static int i2o_proc_read_lan_mcast_addr(char *, char **, off_t, int, int *,
X 					void *);
-#endif
X static int i2o_proc_read_lan_batch_control(char *, char **, off_t, int, int *,
X 					   void *);
X static int i2o_proc_read_lan_operation(char *, char **, off_t, int, int *,
X 				       void *);
X static int i2o_proc_read_lan_media_operation(char *, char **, off_t, int,
X 					     int *, void *);
-#if 0
X static int i2o_proc_read_lan_alt_addr(char *, char **, off_t, int, int *,
X 				      void *);
-#endif
X static int i2o_proc_read_lan_tx_info(char *, char **, off_t, int, int *,
X 				     void *);
X static int i2o_proc_read_lan_rx_info(char *, char **, off_t, int, int *,
X 				     void *);
X static int i2o_proc_read_lan_hist_stats(char *, char **, off_t, int, int *,
X 					void *);
+static int i2o_proc_read_lan_supp_opt_stats(char *, char **, off_t, int, int *,
+					    void *);
X static int i2o_proc_read_lan_opt_tx_hist_stats(char *, char **, off_t, int,
X 					       int *, void *);
X static int i2o_proc_read_lan_opt_rx_hist_stats(char *, char **, off_t, int,
X 					       int *, void *);
+static int i2o_proc_read_lan_eth_stats(char *, char **, off_t, int,
+				       int *, void *);
+static int i2o_proc_read_lan_supp_eth_stats(char *, char **, off_t, int, int *,
+					    void *);
+static int i2o_proc_read_lan_opt_eth_stats(char *, char **, off_t, int, int *,
+					   void *);
+static int i2o_proc_read_lan_tr_stats(char *, char **, off_t, int, int *,
+				      void *);
X static int i2o_proc_read_lan_fddi_stats(char *, char **, off_t, int, int *,
X 					void *);
X 
-#if 0
-/* Do we really need this??? */
-
-static loff_t i2o_proc_lseek(struct file *file, loff_t off, int whence)
-{
-	return 0;
-}
-#endif
-
X static struct proc_dir_entry *i2o_proc_dir_root;
X 
X /*
@@ -156,6 +156,9 @@
X 	{"lct", S_IFREG|S_IRUGO, i2o_proc_read_lct, NULL},
X 	{"stat", S_IFREG|S_IRUGO, i2o_proc_read_stat, NULL},
X 	{"hw", S_IFREG|S_IRUGO, i2o_proc_read_hw, NULL},
+	{"dst", S_IFREG|S_IRUGO, i2o_proc_read_dst, NULL},
+	{"ddm_table", S_IFREG|S_IRUGO, i2o_proc_read_ddm_table, NULL},
+	{"ds", S_IFREG|S_IRUGO, i2o_proc_read_ds, NULL},
X 	{NULL, 0, NULL, NULL}
X };
X 
@@ -164,8 +167,11 @@
X  */
X static i2o_proc_entry generic_dev_entries[] = 
X {
+	{"groups", S_IFREG|S_IRUGO, i2o_proc_read_groups, NULL},
+	{"priv_msgs", S_IFREG|S_IRUGO, i2o_proc_read_priv_msgs, NULL},
X 	{"dev_identity", S_IFREG|S_IRUGO, i2o_proc_read_dev, NULL},
X 	{"ddm_identity", S_IFREG|S_IRUGO, i2o_proc_read_ddm, NULL},
+	{"sgl_limits", S_IFREG|S_IRUGO, i2o_proc_read_sgl_limits, NULL},
X 	{"user_info", S_IFREG|S_IRUGO, i2o_proc_read_uinfo, NULL},
X 	{NULL, 0, NULL, NULL}
X };
@@ -200,7 +206,7 @@
X /* private */
X 
X /*
- * LAN specific entries
+ * Generic LAN specific entries
X  * 
X  * Should groups with r/w entries have their own subdirectory?
X  *
@@ -210,34 +216,79 @@
X 	/* LAN param groups 0000h-0008h */
X 	{"lan_dev_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_dev_info, NULL},
X 	{"lan_mac_addr", S_IFREG|S_IRUGO, i2o_proc_read_lan_mac_addr, NULL},
-#if 0
X 	{"lan_mcast_addr", S_IFREG|S_IRUGO|S_IWUSR,
X 	 i2o_proc_read_lan_mcast_addr, NULL},
-#endif
X 	{"lan_batch_ctrl", S_IFREG|S_IRUGO|S_IWUSR,
X 	 i2o_proc_read_lan_batch_control, NULL},
X 	{"lan_operation", S_IFREG|S_IRUGO, i2o_proc_read_lan_operation, NULL},
X 	{"lan_media_operation", S_IFREG|S_IRUGO,
X 	 i2o_proc_read_lan_media_operation, NULL},
-#if 0
X 	{"lan_alt_addr", S_IFREG|S_IRUGO, i2o_proc_read_lan_alt_addr, NULL},
-#endif
X 	{"lan_tx_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_tx_info, NULL},
X 	{"lan_rx_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_rx_info, NULL},
+	/* LAN param groups 0100h, 0180h, 0182h, 0183h */
X 	{"lan_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_hist_stats, NULL},
+	{"lan_supp_opt_stats", S_IFREG|S_IRUGO,
+	 i2o_proc_read_lan_supp_opt_stats, NULL},
X 	{"lan_opt_tx_stats", S_IFREG|S_IRUGO,
X 	 i2o_proc_read_lan_opt_tx_hist_stats, NULL},
X 	{"lan_opt_rx_stats", S_IFREG|S_IRUGO,
X 	 i2o_proc_read_lan_opt_rx_hist_stats, NULL},
-	{"lan_fddi_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_fddi_stats, NULL},
-	/* some useful r/w entries, no write yet */
-	{"lan_curr_addr", S_IFREG|S_IRUGO|S_IWUSR,
-	 i2o_proc_read_lan_curr_addr, NULL},
+	/* TODO: LAN param group 0184h */
+	{NULL, 0, NULL, NULL}
+};
+
+/*
+ * Ethernet specific LAN entries
+ * 
+ */
+static i2o_proc_entry lan_eth_entries[] = 
+{
+	/* LAN param groups 0200h, 0280h, 0281h */
+	{"lan_eth_stat", S_IFREG|S_IRUGO, i2o_proc_read_lan_eth_stats, NULL},
+        {"lan_supp_eth_stats", S_IFREG|S_IRUGO,
+	 i2o_proc_read_lan_supp_eth_stats, NULL},
+        {"lan_opt_eth_stats", S_IFREG|S_IRUGO,
+	 i2o_proc_read_lan_opt_eth_stats, NULL},
+	{NULL, 0, NULL, NULL}
+};
+
+/*
+ * Token Ring specific LAN entries
+ * 
+ */
+static i2o_proc_entry lan_tr_entries[] = 
+{
+	/* LAN param group 0300h */
+	{"lan_tr_stats", S_IFREG|S_IRUGO,
+	 i2o_proc_read_lan_tr_stats, NULL},
+	/* TODO: LAN param group 0380h, 0381h */
+	{NULL, 0, NULL, NULL}
+};
+
+/*
+ * FDDI specific LAN entries
+ * 
+ */
+static i2o_proc_entry lan_fddi_entries[] = 
+{
+	/* LAN param group 0400h */
+	{"lan_fddi_stats", S_IFREG|S_IRUGO,
+	 i2o_proc_read_lan_fddi_stats, NULL},
+	/* TODO: LAN param group 0480h, 0481h */
X 	{NULL, 0, NULL, NULL}
X };
X 
+
X static u32 i2o_proc_token = 0;
X 
+static char *chtostr(u8 *chars, int n)
+{
+	char tmp[256];
+	tmp[0] = 0;
+        return strncat(tmp, (char *)chars, n);
+}
+
X static char* bus_strings[] = 
X { 
X 	"Local Bus", 
@@ -253,13 +304,13 @@
X static spinlock_t i2o_proc_lock = SPIN_LOCK_UNLOCKED;
X 
X void i2o_proc_reply(struct i2o_handler *phdlr, struct i2o_controller *pctrl,
-	struct i2o_message *pmsg)
+		    struct i2o_message *pmsg)
X {
X 	i2o_proc_token = I2O_POST_WAIT_OK;
X }
X 
X int i2o_proc_read_hrt(char *buf, char **start, off_t offset, int len, 
-	int *eof, void *data)
+		      int *eof, void *data)
X {
X 	struct i2o_controller *c = (struct i2o_controller *)data;
X 	pi2o_hrt hrt;
@@ -303,8 +354,10 @@
X 
X 	if(hrt->hrt_version)
X 	{
+		kfree(workspace);
X 		len += sprintf(buf+len, 
-					"HRT table for controller is too new a version.\n");
+			       "HRT table for controller is too new a version.\n");
+		spin_unlock(&i2o_proc_lock);
X 		return len;
X 	}
X 
@@ -312,6 +365,7 @@
X 
X 	if((count * hrt->entry_len + 8) > 2048) {
X 		printk(KERN_WARNING "i2o_proc: HRT does not fit into buffer\n");
+		kfree(workspace);
X 		len += sprintf(buf+len,
X 			       "HRT table too big to fit in buffer.\n");
X 		spin_unlock(&i2o_proc_lock);
@@ -490,7 +544,8 @@
X 						break;
X 
X 					default:
-						len += sprintf(buf+len, ": Unknown");
+						len += sprintf(buf+len, ": Unknown (0x%02x)",
+							       lct->lct_entry[i].sub_class);
X 						break;
X 				}
X 				break;
@@ -519,7 +574,8 @@
X 						break;
X 
X 					default:
-						len += sprintf(buf+len, ": Unknown Sub-Class");
+						len += sprintf(buf+len, ": Unknown Sub-Class (0x%02x)",
+							       lct->lct_entry[i].sub_class & 0xFF);
X 						break;
X 				}
X 				break;
@@ -642,6 +698,8 @@
X 		len += sprintf(buf+len, "Lowest I2O version supported: ");
X 		switch(workspace[2]) {
X 		case 0x00:
+			len += sprintf(buf+len, "1.0\n");
+			break;
X 		case 0x01:
X 			len += sprintf(buf+len, "1.5\n");
X 			break;
@@ -653,6 +711,8 @@
X 		len += sprintf(buf+len, "Highest I2O version supported: ");
X 		switch(workspace[3]) {
X 		case 0x00:
+			len += sprintf(buf+len, "1.0\n");
+			break;
X 		case 0x01:
X 			len += sprintf(buf+len, "1.5\n");
X 			break;
@@ -666,10 +726,12 @@
X 	len += sprintf(buf+len, "Host Unit ID: %0#6x\n", work16[3]);
X 	len += sprintf(buf+len, "Segment Number: %0#5x\n", work16[4]&0XFFF);
X 
-	len += sprintf(buf+len, "I2O Version: ");
+	len += sprintf(buf+len, "I2O version: ");
X 	switch(version)
X 	{
X 	case 0x00:
+		len += sprintf(buf+len, "1.0\n");
+		break;
X 	case 0x01:
X 		len += sprintf(buf+len, "1.5\n");
X 		break;
@@ -722,7 +784,7 @@
X 	switch (workspace[11])
X 	{
X 	case 0x00:
-		len += sprintf(buf+len, "Memory Mapped\n");
+		len += sprintf(buf+len, "Memory mapped\n");
X 		break;
X 	case 0x01:
X 		len += sprintf(buf+len, "Memory mapped only\n");
@@ -749,26 +811,27 @@
X 
X 	len += sprintf(buf+len, "LCT Size: %d\n", work32[13]);
X 
-	len += sprintf(buf+len, "Desired Private Memory Space: %d kB\n", 
+	len += sprintf(buf+len, "Desired private memory space: %d kB\n", 
X 						work32[15]>>10);
-	len += sprintf(buf+len, "Allocated Private Memory Space: %d kB\n", 
+	len += sprintf(buf+len, "Allocated private memory space: %d kB\n", 
X 						work32[16]>>10);
-	len += sprintf(buf+len, "Private Memory Base Address: %0#10x\n", 
+	len += sprintf(buf+len, "Private memory base address: %0#10x\n", 
X 						work32[17]);
-	len += sprintf(buf+len, "Desired Private I/O Space: %d kB\n", 
+	len += sprintf(buf+len, "Desired private I/O space: %d kB\n", 
X 						work32[18]>>10);
-	len += sprintf(buf+len, "Allocated Private I/O Space: %d kB\n", 
+	len += sprintf(buf+len, "Allocated private I/O space: %d kB\n", 
X 						work32[19]>>10);
-	len += sprintf(buf+len, "Private I/O Base Address: %0#10x\n", 
+	len += sprintf(buf+len, "Private I/O base address: %0#10x\n", 
X 						work32[20]);
X 
+	kfree(workspace);
X 	spin_unlock(&i2o_proc_lock);
X 
X 	return len;
X }
X 
X int i2o_proc_read_hw(char *buf, char **start, off_t offset, int len, 
-	int *eof, void *data)
+		     int *eof, void *data)
X {
X 	struct i2o_controller *c = (struct i2o_controller*)data;
X 	static u32 work32[5];
@@ -779,14 +842,14 @@
X 
X 	static char *cpu_table[] =
X 	{
-		"Intel 80960 Series",
-		"AMD2900 Series",
-		"Motorola 68000 Series",
-		"ARM Series",
-		"MIPS Series",
-		"Sparc Series",
-		"PowerPC Series",
-		"Intel x86 Series"
+		"Intel 80960 series",
+		"AMD2900 series",
+		"Motorola 68000 series",
+		"ARM series",
+		"MIPS series",
+		"Sparc series",
+		"PowerPC series",
+		"Intel x86 series"
X 	};
X 
X 	spin_lock(&i2o_proc_lock);
@@ -807,15 +870,15 @@
X 		return len;
X 	}
X 
-	len += sprintf(buf, "IOP Hardware Information Table\n");
+	len += sprintf(buf, "IOP Hardware Information Table (group = 0x0000)\n");
X 
-	len += sprintf(buf+len, "I2O Vendor ID: %0#6x\n", work16[0]);
-	len += sprintf(buf+len, "Product ID: %0#6x\n", work16[1]);
-	len += sprintf(buf+len, "RAM: %dkB\n", work32[1]>>10);
-	len += sprintf(buf+len, "Non-Volatile Storage: %dkB\n", work32[2]>>10);
+	len += sprintf(buf+len, "I2O Vendor ID        : %0#6x\n", work16[0]);
+	len += sprintf(buf+len, "Product ID           : %0#6x\n", work16[1]);
+	len += sprintf(buf+len, "RAM                  : %dkB\n", work32[1]>>10);
+	len += sprintf(buf+len, "Non-Volatile Storage : %dkB\n", work32[2]>>10);
X 
X 	hwcap = work32[3];
-	len += sprintf(buf+len, "Capabilities:\n");
+	len += sprintf(buf+len, "Capabilities :\n");
X 	if(hwcap&0x00000001)
X 		len += sprintf(buf+len, "   Self-booting\n");
X 	if(hwcap&0x00000002)
@@ -827,7 +890,7 @@
X 	if(hwcap&0x00000010)
X 		len += sprintf(buf+len, "   Battery-backed RAM\n");
X 
-	len += sprintf(buf+len, "CPU: ");
+	len += sprintf(buf+len, "CPU                 : ");
X 	if(work8[16] > 8)
X 		len += sprintf(buf+len, "Unknown\n");
X 	else
@@ -839,14 +902,407 @@
X 	return len;
X }
X 
+
+/* Executive group 0003h - Executing DDM List (table) */
+int i2o_proc_read_ddm_table(char *buf, char **start, off_t offset, int len, 
+			    int *eof, void *data)
+{
+	struct i2o_controller *c = (struct i2o_controller*)data;
+	int token;
+	int i;
+
+	typedef struct _i2o_exec_execute_ddm_table {
+		u16 ddm_tid;
+		u8  module_type;
+		u8  reserved;
+		u16 i2o_vendor_id;
+		u16 module_id;
+		u8  module_name[24];
+		u8  module_version[4];
+		u32 data_size;
+		u32 code_size;
+	} i2o_exec_execute_ddm_table, *pi2o_exec_execute_ddm_table;
+
+	struct
+	{
+		u16 result_count;
+		u16 pad;
+		u16 block_size;
+		u8  block_status;
+		u8  error_info_size;
+		u16 row_count;
+		u16 more_flag;
+		i2o_exec_execute_ddm_table ddm_table[MAX_I2O_MODULES];
+	} result;
+
+	i2o_exec_execute_ddm_table ddm_table;
+
+	spin_lock(&i2o_proc_lock);
+	len = 0;
+
+	token = i2o_query_table(I2O_PARAMS_TABLE_GET,
+				c, ADAPTER_TID, proc_context,
+				0x0003, -1,
+				NULL, 0,
+				&result, sizeof(result), &i2o_proc_token);
+
+	if (token<0)
+		switch (token)
+		{
+		case -ETIMEDOUT:
+			len += sprintf(buf, "Timeout reading table.\n");
+			spin_unlock(&i2o_proc_lock);
+			return len;
+			break;
+		case -ENOMEM:
+			len += sprintf(buf, "No free memory to read the table.\n");
+			spin_unlock(&i2o_proc_lock);
+			return len;
+			break;
+		default:
+			len += sprintf(buf, "Error reading group. BlockStatus %d\n",
+				       token);
+			spin_unlock(&i2o_proc_lock);
+			return len;
+		}
+
+	len += sprintf(buf+len, "Tid   Type            Vendor Id     Name                     Vrs  Data_size Code_size\n");
+	ddm_table=result.ddm_table[0];
+
+	for(i=0; i < result.row_count; ddm_table=result.ddm_table[++i])
+	{
+		len += sprintf(buf+len, "0x%03x ", ddm_table.ddm_tid & 0xFFF);
+
+		switch(ddm_table.module_type)
+		{
+		case 0x01:
+			len += sprintf(buf+len, "Downloaded DDM  ");
+			break;			
+		case 0x22:
+			len += sprintf(buf+len, "Embedded DDM    ");
+			break;
+		default:
+			len += sprintf(buf+len, "                ");
+		}
+
+		len += sprintf(buf+len, "%-0#7x", ddm_table.i2o_vendor_id);
+		len += sprintf(buf+len, "%-0#7x", ddm_table.module_id);
+		len += sprintf(buf+len, "%-25s", chtostr(ddm_table.module_name, 24));
+		len += sprintf(buf+len, "%-6s", chtostr(ddm_table.module_version,4));
+		len += sprintf(buf+len, "%8d  ", ddm_table.data_size);
+		len += sprintf(buf+len, "%8d", ddm_table.code_size);
+
+		len += sprintf(buf+len, "\n");
+	}
+
+	spin_unlock(&i2o_proc_lock);
+
+	return len;
+}
+
+
+/* Executive group 0004h - Driver Store (scalar) */
+int i2o_proc_read_ds(char *buf, char **start, off_t offset, int len, 
+		     int *eof, void *data)
+{
+	struct i2o_controller *c = (struct i2o_controller*)data;
+	u32 work32[8];
+	int token;
+
+	spin_lock(&i2o_proc_lock);
+
+	len = 0;
+
+	token = i2o_query_scalar(c, ADAPTER_TID, proc_context, 0x0004, -1, 
+				 &work32, sizeof(work32), &i2o_proc_token);
+
+	if (token<0)
+	{
+		len += sprintf(buf, "Timeout waiting for reply from IOP\n");
+		spin_unlock(&i2o_proc_lock);
+		return len;
+	}
+
+	len += sprintf(buf+len, "Module limit  : %d\n"
+				"Module count  : %d\n"
+				"Current space : %d kB\n"
+				"Free space    : %d kB\n", 
+			work32[0], work32[1], work32[2]>>10, work32[3]>>10);
+
+	spin_unlock(&i2o_proc_lock);
+
+	return len;
+}
+
+
+/* Executive group 0005h - Driver Store Table (table) */
+int i2o_proc_read_dst(char *buf, char **start, off_t offset, int len, 
+		      int *eof, void *data)
+{
+	typedef struct _i2o_driver_store {
+		u16 stored_ddm_index;
+		u8  module_type;
+		u8  reserved;
+		u16 i2o_vendor_id;
+		u16 module_id;
+		u8  module_name_version[28];
+		u8  date[8];
+		u32 module_size;
+		u32 mpb_size;
+		u32 module_flags;
+	} i2o_driver_store_table;
+
+	struct i2o_controller *c = (struct i2o_controller*)data;
+	int token;
+	int i;
+
+	struct
+	{
+		u16 result_count;
+		u16 pad;
+		u16 block_size;
+		u8  block_status;
+		u8  error_info_size;
+		u16 row_count;
+		u16 more_flag;
+		i2o_driver_store_table dst[MAX_I2O_MODULES];
+	} result;
+
+	i2o_driver_store_table dst;
+
+	spin_lock(&i2o_proc_lock);
+
+	len = 0;
+
+	token = i2o_query_table(I2O_PARAMS_TABLE_GET,
+				c, ADAPTER_TID, proc_context,
+				0x0005, -1,
+				NULL, 0,
+				&result, sizeof(result), &i2o_proc_token);
+
+	if (token<0)
+		switch (token)
+		{
+		case -ETIMEDOUT:
+			len += sprintf(buf, "Timeout reading table.\n");
+			spin_unlock(&i2o_proc_lock);
+			return len;
+			break;
+		case -ENOMEM:
+			len += sprintf(buf, "No free memory to read the table.\n");
+			spin_unlock(&i2o_proc_lock);
+			return len;
+			break;
+		default:
+			len += sprintf(buf, "Error reading group. "
+					"BlockStatus %d\n",token);
+			spin_unlock(&i2o_proc_lock);
+			return len;
+		}
+
+	len += sprintf(buf+len, "#  Type            Vendor Id      Name                    Vrs  Date     Mod_size Par_size Flags\n");	
+
+	for(i=0, dst=result.dst[0]; i < result.row_count; dst=result.dst[++i])
+	{
+		len += sprintf(buf+len, "%-3d", dst.stored_ddm_index);
+		switch(dst.module_type)
+		{
+		case 0x01:
+			len += sprintf(buf+len, "Downloaded DDM  ");
+			break;			
+		case 0x22:
+			len += sprintf(buf+len, "Embedded DDM    ");
+			break;
+		default:
+			len += sprintf(buf+len, "                ");
+		}
+
+#if 0
+		if(c->i2oversion == 0x02)
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 13'
echo 'File patch-2.3.10 is continued in part 14'
echo 14 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 18 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
X   fi
X   bool 'Other ISA cards' CONFIG_NET_ISA
X   if [ "$CONFIG_NET_ISA" = "y" ]; then
-    tristate 'AT1700/1720 support' CONFIG_AT1700
+    tristate 'AT1700/1720 support (EXPERIMENTAL)' CONFIG_AT1700
X     tristate 'Cabletron E21xx support' CONFIG_E2100
X     tristate 'DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA
X     tristate 'EtherWORKS 3 (DE203, DE204, DE205) support' CONFIG_EWRK3
X     tristate 'EtherExpress 16 support' CONFIG_EEXPRESS
-    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      tristate 'EtherExpressPro support' CONFIG_EEXPRESS_PRO
-    fi
+    tristate 'EtherExpressPro support' CONFIG_EEXPRESS_PRO
X     tristate 'FMV-181/182/183/184 support' CONFIG_FMV18X
X     tristate 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS
X     tristate 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN
@@ -103,7 +109,7 @@
X     fi
X     tristate 'NE2000/NE1000 support' CONFIG_NE2000
X     if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-      bool 'SEEQ8005 support (EXPERIMENTAL)' CONFIG_SEEQ8005
+      tristate 'SEEQ8005 support (EXPERIMENTAL)' CONFIG_SEEQ8005
X     fi
X     bool 'SK_G16 support' CONFIG_SK_G16
X   fi
@@ -115,6 +121,7 @@
X   if [ "$CONFIG_NET_EISA" = "y" ]; then
X     tristate 'AMD PCnet32 (VLB and PCI) support' CONFIG_PCNET32
X     if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate 'Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACENIC
X       tristate 'Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200
X     fi
X 
@@ -145,6 +152,8 @@
X   fi
X fi
X 
+endmenu
+
X bool 'FDDI driver support' CONFIG_FDDI
X if [ "$CONFIG_FDDI" = "y" ]; then
X   bool 'Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX
@@ -153,25 +162,20 @@
X if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
X   bool 'HIPPI driver support (EXPERIMENTAL)' CONFIG_HIPPI
X   if [ "$CONFIG_HIPPI" = "y" ]; then
-    bool 'CERN HIPPI PCI adapter support' CONFIG_CERN_HIPPI
-    bool 'Essential RoadRunner HIPPI PCI adapter support' CONFIG_ROADRUNNER
+    tristate 'Essential RoadRunner HIPPI PCI adapter support' CONFIG_ROADRUNNER
X     if [ "$CONFIG_ROADRUNNER" != "n" ]; then
X       bool '  Use large TX/RX rings' CONFIG_ROADRUNNER_LARGE_RINGS
X     fi
X   fi
X fi
X 
-tristate 'Frame relay DLCI support' CONFIG_DLCI
-if [ "$CONFIG_DLCI" = "y" -o "$CONFIG_DLCI" = "m" ]; then
-  int '  Max open DLCI' CONFIG_DLCI_COUNT 24
-  int '  Max DLCI per device' CONFIG_DLCI_MAX 8
-  dep_tristate '  SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI
-fi
-
X #
X # AppleTalk
X #
+
X if [ "$CONFIG_ATALK" != "n" ]; then
+  mainmenu_option next_comment
+  comment 'Appletalk devices'
X   dep_tristate 'Apple/Farallon LocalTalk PC support' CONFIG_LTPC $CONFIG_ATALK
X   dep_tristate 'COPS LocalTalk PC support' CONFIG_COPS $CONFIG_ATALK
X   if [ "$CONFIG_COPS" != "n" ]; then
@@ -183,6 +187,7 @@
X      bool 'IP to Appletalk-IP Encapsulation support' CONFIG_IPDDP_ENCAP
X      bool 'Appletalk-IP to IP Decapsulation support' CONFIG_IPDDP_DECAP
X   fi
+  endmenu
X fi
X 
X if [ ! "$CONFIG_PARPORT" = "n" ]; then
@@ -203,23 +208,38 @@
X 
X bool 'Wireless LAN (non-hamradio)' CONFIG_NET_RADIO
X if [ "$CONFIG_NET_RADIO" = "y" ]; then
-  tristate 'STRIP (Metricom starmode radio IP)' CONFIG_STRIP
+  dep_tristate 'STRIP (Metricom starmode radio IP)' CONFIG_STRIP $CONFIG_INET
X   tristate 'AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN
+  tristate 'Aironet Arlan 655 & IC2200 DS support' CONFIG_ARLAN
+
X fi
X 
+mainmenu_option next_comment
+comment 'Token ring devices'
+
X bool 'Token Ring driver support' CONFIG_TR
X if [ "$CONFIG_TR" = "y" ]; then
X   tristate 'IBM Tropic chipset based adaptor support' CONFIG_IBMTR
X #  tristate 'IBM Lanstreamer PCI adaptor support' CONFIG_IBMLS
+  tristate 'IBM Olympic chipset PCI adapter support' CONFIG_IBMOL
X   tristate 'SysKonnect adapter support' CONFIG_SKTR
X fi
X 
+endmenu
+
X if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  tristate 'Red Creek Hardware VPN (EXPERIMENTAL)' CONFIG_RCPCI
X   tristate 'Traffic Shaper (EXPERIMENTAL)' CONFIG_SHAPER
X fi
+
X #
X # WAN drivers support
X #
+
+mainmenu_option next_comment
+comment 'Wan interfaces'
+
+
X # There is no way to detect a comtrol sv11 - force it modular for now.
X #
X dep_tristate 'Comtrol Hostess SV-11 support' CONFIG_HOSTESS_SV11 m
@@ -227,8 +247,22 @@
X # The COSA/SRP driver has not been tested as non-modular yet.
X #
X dep_tristate 'COSA/SRP sync serial boards support' CONFIG_COSA m
-tristate 'Red Creek Hardware VPN (EXPERIMENTAL)' CONFIG_RCPCI
X #
+# There is no way to detect a Sealevel board. Force it modular
+#
+dep_tristate 'Sealevel Systems 4021 support' CONFIG_SEALEVEL_4021 m
+
+tristate 'Frame relay DLCI support' CONFIG_DLCI
+if [ "$CONFIG_DLCI" != "n" ]; then
+  int '  Max open DLCI' CONFIG_DLCI_COUNT 24
+  int '  Max DLCI per device' CONFIG_DLCI_MAX 8
+  dep_tristate '  SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI
+fi
+
+#
+#	Wan router core.
+#
+
X if [ "$CONFIG_WAN_ROUTER" != "n" ]; then
X   bool 'WAN drivers' CONFIG_WAN_DRIVERS
X   if [ "$CONFIG_WAN_DRIVERS" = "y" ]; then
@@ -247,6 +281,9 @@
X     fi
X   fi
X fi
+
+endmenu
+
X #
X # X.25 network drivers
X #
diff -u --recursive --new-file v2.3.9/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v2.3.9/linux/drivers/net/Makefile	Wed Jun 30 13:38:20 1999
+++ linux/drivers/net/Makefile	Tue Jul  6 19:16:55 1999
@@ -67,6 +67,14 @@
X   endif
X endif
X 
+ifeq ($(CONFIG_IBMOL),y)
+L_OBJS += olympic.o
+else
+  ifeq ($(CONFIG_IBMOL),m)
+  M_OBJS += olympic.o
+  endif
+endif
+
X ifeq ($(CONFIG_SKTR),y)
X L_OBJS += sktr.o
X else
@@ -422,6 +430,14 @@
X   endif
X endif
X 
+ifeq ($(CONFIG_SUNBMAC),y)
+L_OBJS += sunbmac.o
+else
+  ifeq ($(CONFIG_SUNBMAC),m)
+  M_OBJS += sunbmac.o
+  endif
+endif
+
X ifeq ($(CONFIG_MYRI_SBUS),y)
X L_OBJS += myri_sbus.o
X else
@@ -566,6 +582,14 @@
X   endif
X endif
X 
+ifeq ($(CONFIG_ARLAN),y)
+LX_OBJS += arlan.o arlan-proc.o
+else
+  ifeq ($(CONFIG_ARLAN),m)
+  MX_OBJS += arlan.o arlan-proc.o
+  endif
+endif
+
X ifeq ($(CONFIG_TLAN),y)
X L_OBJS += tlan.o
X else
@@ -764,6 +788,19 @@
X   endif
X endif
X 
+ifeq ($(CONFIG_SEALEVEL_4021),y)
+L_OBJS += sealevel.o
+CONFIG_85230_BUILTIN = y
+CONFIG_SYNCPPP_BUILTIN = y
+else
+  ifeq ($(CONFIG_SEALEVEL_4021),m)
+  CONFIG_85230_MODULE = y
+  CONFIG_SYNCPPP_MODULE = y
+  M_OBJS += sealevel.o
+  endif
+endif
+
+
X ifeq ($(CONFIG_COSA),y)
X L_OBJS += cosa.o
X CONFIG_SYNCPPP_BUILTIN = y
@@ -1061,15 +1098,6 @@
X   L_OBJS += cycx_main.o
X   ifeq ($(CONFIG_CYCLOMX_X25),y)
X     L_OBJS += cycx_x25.o
-  endif
-endif
-
-ifeq ($(CONFIG_CYCLADES_SYNC),m)
-  MX_OBJS += cycx_drv.o
-  M_OBJS += cyclomx.o
-  CYCLOMX_OBJS = cycx_main.o
-  ifeq ($(CONFIG_CYCLOMX_X25),y)
-    CYCLOMX_OBJS += cycx_x25.o
X   endif
X endif
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/Space.c linux/drivers/net/Space.c
--- v2.3.9/linux/drivers/net/Space.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/net/Space.c	Tue Jul  6 19:05:49 1999
@@ -67,6 +67,7 @@
X extern int de4x5_probe(struct device *);
X extern int el1_probe(struct device *);
X extern int wavelan_probe(struct device *);
+extern int arlan_probe(struct device *);
X extern int el16_probe(struct device *);
X extern int elmc_probe(struct device *);
X extern int skmca_probe(struct device *);
@@ -147,7 +148,7 @@
X  * autoprobe (i.e. a probe that fails to find a card when autoprobing
X  * will not be asked to autoprobe again).  It exits when a card is found.
X  */
-__initfunc(static int probe_list(struct device *dev, struct devprobe *plist))
+static int __init probe_list(struct device *dev, struct devprobe *plist)
X {
X 	struct devprobe *p = plist;
X 	unsigned long base_addr = dev->base_addr;
@@ -359,6 +360,9 @@
X #ifdef CONFIG_WAVELAN		/* WaveLAN */
X 	{wavelan_probe, 0},
X #endif
+#ifdef CONFIG_ARLAN		/* Aironet */
+	{arlan_probe, 0},
+#endif
X #ifdef CONFIG_EL16		/* 3c507 */
X 	{el16_probe, 0},
X #endif
@@ -474,7 +478,7 @@
X  * Unified ethernet device probe, segmented per architecture and
X  * per bus interface.
X  */
-__initfunc(static int ethif_probe(struct device *dev))
+static int __init ethif_probe(struct device *dev)
X {
X 	unsigned long base_addr = dev->base_addr;
X 
@@ -522,7 +526,7 @@
X }
X 
X #ifdef CONFIG_FDDI
-__initfunc(static int fddiif_probe(struct device *dev))
+static int __init fddiif_probe(struct device *dev)
X {
X     unsigned long base_addr = dev->base_addr;
X 
@@ -719,6 +723,7 @@
X #ifdef CONFIG_TR
X /* Token-ring device probe */
X extern int ibmtr_probe(struct device *);
+extern int olympic_probe(struct device *);
X 
X static int
X trif_probe(struct device *dev)
@@ -726,6 +731,9 @@
X     if (1
X #ifdef CONFIG_IBMTR
X 	&& ibmtr_probe(dev)
+#endif
+#ifdef CONFIG_IBMOL
+	&& olympic_probe(dev)
X #endif
X #ifdef CONFIG_SKTR
X 	&& sktr_probe(dev)
diff -u --recursive --new-file v2.3.9/linux/drivers/net/a2065.c linux/drivers/net/a2065.c
--- v2.3.9/linux/drivers/net/a2065.c	Sun Mar 21 07:22:00 1999
+++ linux/drivers/net/a2065.c	Tue Jul  6 19:05:49 1999
@@ -739,8 +739,7 @@
X 	mark_bh(NET_BH);
X }
X 
-
-__initfunc(int a2065_probe(struct device *dev))
+int __init a2065_probe(struct device *dev)
X {
X 	unsigned int key, is_cbm;
X 	const struct ConfigDev *cd;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/ac3200.c linux/drivers/net/ac3200.c
--- v2.3.9/linux/drivers/net/ac3200.c	Thu Dec 17 09:03:57 1998
+++ linux/drivers/net/ac3200.c	Tue Jul  6 19:05:49 1999
@@ -95,7 +95,7 @@
X 	or the unique value in the station address PROM.
X 	*/
X 
-__initfunc(int ac3200_probe(struct device *dev))
+int __init ac3200_probe(struct device *dev)
X {
X 	unsigned short ioaddr = dev->base_addr;
X 
@@ -117,7 +117,7 @@
X 	return ENODEV;
X }
X 
-__initfunc(static int ac_probe1(int ioaddr, struct device *dev))
+static int __init ac_probe1(int ioaddr, struct device *dev)
X {
X 	int i;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/acenic.c linux/drivers/net/acenic.c
--- v2.3.9/linux/drivers/net/acenic.c	Mon Mar 22 08:08:12 1999
+++ linux/drivers/net/acenic.c	Tue Jul  6 19:05:49 1999
@@ -177,7 +177,7 @@
X 
X static int probed __initdata = 0;
X 
-__initfunc(int acenic_probe (struct device *dev))
+int __init acenic_probe (struct device *dev)
X {
X 	int boards_found = 0;
X 	int version_disp;
@@ -423,7 +423,7 @@
X }
X 
X 
-__initfunc(static int ace_init(struct device *dev, int board_idx))
+static int __init ace_init(struct device *dev, int board_idx)
X {
X 	struct ace_private *ap;
X 	struct ace_regs *regs;
@@ -1574,7 +1574,7 @@
X }
X 
X 
-__initfunc(void ace_copy(struct ace_regs *regs, void *src, u32 dest, int size))
+void __init ace_copy(struct ace_regs *regs, void *src, u32 dest, int size)
X {
X 	unsigned long tdest;
X 	u32 *wsrc;
@@ -1609,7 +1609,7 @@
X }
X 
X 
-__initfunc(void ace_clear(struct ace_regs *regs, u32 dest, int size))
+void __init ace_clear(struct ace_regs *regs, u32 dest, int size)
X {
X 	unsigned long tdest;
X 	short tsize = 0, i;
@@ -1642,7 +1642,7 @@
X  * This operation requires the NIC to be halted and is performed with
X  * interrupts disabled and with the spinlock hold.
X  */
-__initfunc(int ace_load_firmware(struct device *dev))
+int __init ace_load_firmware(struct device *dev)
X {
X 	struct ace_private *ap;
X 	struct ace_regs *regs;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/apne.c linux/drivers/net/apne.c
--- v2.3.9/linux/drivers/net/apne.c	Thu Dec 17 09:07:46 1998
+++ linux/drivers/net/apne.c	Tue Jul  6 19:05:49 1999
@@ -121,7 +121,7 @@
X 
X static int apne_owned = 0;	/* signal if card already owned */
X 
-__initfunc(int apne_probe(struct device *dev))
+int __init apne_probe(struct device *dev)
X {
X #ifndef MANUAL_CONFIG
X 	char tuple[8];
@@ -161,8 +161,7 @@
X 
X }
X 
-
-__initfunc(static int apne_probe1(struct device *dev, int ioaddr))
+static int __init apne_probe1(struct device *dev, int ioaddr)
X {
X     int i;
X     unsigned char SA_prom[32];
diff -u --recursive --new-file v2.3.9/linux/drivers/net/arc-rimi.c linux/drivers/net/arc-rimi.c
--- v2.3.9/linux/drivers/net/arc-rimi.c	Mon Sep 14 11:32:22 1998
+++ linux/drivers/net/arc-rimi.c	Tue Jul  6 19:05:49 1999
@@ -100,7 +100,7 @@
X MODULE_PARM(device, "s");
X MODULE_PARM (node, "i");
X #else
-__initfunc(void arcrimi_setup (char *str, int *ints));
+void __init arcrimi_setup (char *str, int *ints);
X extern struct device arcnet_devs[];
X extern char arcnet_dev_names[][10];
X extern int arcnet_num_devs;
@@ -140,7 +140,7 @@
X  * them.  In fact, we can't even get their node ID automatically.  So, we
X  * need to be passed a specific shmem address, IRQ, and node ID.
X  */
-__initfunc(int arcrimi_probe(struct device *dev))
+int __init arcrimi_probe(struct device *dev)
X {
X   BUGLVL(D_NORMAL) printk(version);
X   BUGMSG(D_NORMAL,"Given: node %02Xh, shmem %lXh, irq %d\n",
@@ -167,7 +167,7 @@
X /* Set up the struct device associated with this card.  Called after
X  * probing succeeds.
X  */
-__initfunc(int arcrimi_found(struct device *dev,int node,int airq, u_long shmem))
+int __init arcrimi_found(struct device *dev,int node,int airq, u_long shmem)
X {
X   struct arcnet_local *lp;
X   u_long first_mirror,last_mirror;
@@ -797,7 +797,7 @@
X 
X #else
X 
-__initfunc(void arcrimi_setup (char *str, int *ints))
+void __init arcrimi_setup (char *str, int *ints)
X {
X   struct device *dev;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c
--- v2.3.9/linux/drivers/net/arcnet.c	Tue May 25 13:06:34 1999
+++ linux/drivers/net/arcnet.c	Tue Jul  6 19:05:49 1999
@@ -471,9 +471,16 @@
X 
X #ifdef CONFIG_ARCNET_1051
X   /* Initialize the RFC1051-encap protocol driver */
-  lp->sdev=(struct device *)kmalloc(sizeof(struct device),GFP_KERNEL);
+  lp->sdev=(struct device *)kmalloc(sizeof(struct device)+10,GFP_KERNEL);
+  if(lp->sdev = NULL)
+  {
+  	if(lp->edev)
+  		kfree(lp->edev);
+  	lp->edev=NULL;
+  	return -ENOMEM;
+  }
X   memcpy(lp->sdev,dev,sizeof(struct device));
-  lp->sdev->name=(char *)kmalloc(10,GFP_KERNEL);
+  lp->sdev->name=(char *)(lp+1);
X   sprintf(lp->sdev->name,"%ss",dev->name);
X   lp->sdev->init=arcnetS_init;
X   register_netdevice(lp->sdev);
@@ -562,7 +569,6 @@
X   /* free the RFC1051-encap protocol device */
X   lp->sdev->priv=NULL;
X   unregister_netdevice(lp->sdev);
-  kfree(lp->sdev->name);
X   kfree(lp->sdev);
X   lp->sdev=NULL;
X #endif
@@ -1991,7 +1997,7 @@
X int arcnet_num_devs=0;
X char arcnet_dev_names[MAX_ARCNET_DEVS][10];
X 
-__initfunc(void arcnet_init(void))
+void __init arcnet_init(void)
X {
X   int c;
X 
@@ -2041,7 +2047,7 @@
X #ifdef MODULE
X int init_module(void)
X #else
-__initfunc(static int init_module(void))
+static int __init init_module(void)
X #endif
X {
X #ifdef ALPHA_WARNING
diff -u --recursive --new-file v2.3.9/linux/drivers/net/ariadne.c linux/drivers/net/ariadne.c
--- v2.3.9/linux/drivers/net/ariadne.c	Thu Feb 25 10:02:13 1999
+++ linux/drivers/net/ariadne.c	Tue Jul  6 19:05:49 1999
@@ -146,7 +146,7 @@
X }
X 
X 
-__initfunc(int ariadne_probe(struct device *dev))
+int __init ariadne_probe(struct device *dev)
X {
X     unsigned int key;
X     const struct ConfigDev *cd;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/ariadne2.c linux/drivers/net/ariadne2.c
--- v2.3.9/linux/drivers/net/ariadne2.c	Thu Jan  7 08:41:54 1999
+++ linux/drivers/net/ariadne2.c	Tue Jul  6 19:05:49 1999
@@ -81,8 +81,7 @@
X 				  const unsigned char *buf,
X 				  const int start_page);
X 
-
-__initfunc(int ariadne2_probe(struct device *dev))
+int __init ariadne2_probe(struct device *dev)
X {
X     unsigned int key;
X     const struct ConfigDev *cd;
@@ -101,8 +100,8 @@
X     return -ENODEV;
X }
X 
-__initfunc(static int ariadne2_init(struct device *dev, unsigned int key,
-				    unsigned long board))
+static int __init ariadne2_init(struct device *dev, unsigned int key,
+				    unsigned long board)
X {
X     int i;
X     unsigned char SA_prom[32];
diff -u --recursive --new-file v2.3.9/linux/drivers/net/arlan-proc.c linux/drivers/net/arlan-proc.c
--- v2.3.9/linux/drivers/net/arlan-proc.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/arlan-proc.c	Tue Jul  6 10:11:40 1999
@@ -0,0 +1,1059 @@
+#include <linux/config.h>
+#include "arlan.h"
+
+#ifdef CONFIG_PROC_FS
+
+
+#include <linux/sysctl.h>
+#include <linux/version.h>
+
+/* void enableReceive(struct device* dev);
+*/
+
+static  int	arlan_command(struct device * dev, int command);
+
+
+#define ARLAN_STR_SIZE 	0x2ff0
+#define DEV_ARLAN_INFO 	1
+#define DEV_ARLAN 	1
+#define SARLG(type,var) {\
+	pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n", #var, READSHMB(priva->card->var));	\
+	}
+
+#define SARLBN(type,var,nn) {\
+	pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x",#var);\
+	for (i=0; i < nn; i++ ) pos += sprintf(arlan_drive_info+pos, "%02x",READSHMB(priva->card->var[i]));\
+	pos += sprintf(arlan_drive_info+pos, "\n");	\
+	}
+
+#define SARLBNpln(type,var,nn) {\
+	for (i=0; i < nn; i++ ) pos += sprintf(arlan_drive_info+pos, "%02x",READSHMB(priva->card->var[i]));\
+	}
+
+#define SARLSTR(var,nn) {\
+	char tmpStr[400];\
+	int  tmpLn = nn;\
+	if (nn > 399 ) tmpLn = 399; \
+	memcpy(tmpStr,(char *) priva->conf->var,tmpLn);\
+	tmpStr[tmpLn] = 0; \
+	pos += sprintf(arlan_drive_info+pos, "%s\t=\t%s \n",#var,priva->conf->var);\
+	}
+
+#define SARLUC(var)  	SARLG(u_char, var)
+#define SARLUCN(var,nn) SARLBN(u_char,var, nn)
+#define SARLUS(var)	SARLG(u_short, var)
+#define SARLUSN(var,nn)	SARLBN(u_short,var, nn)
+#define SARLUI(var)	SARLG(u_int, var)
+
+#define SARLUSA(var) {\
+	u_short tmpVar;\
+	memcpy(&tmpVar, (short *) priva->conf->var,2); \
+	pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n",#var, tmpVar);\
+}
+
+#define SARLUIA(var) {\
+	u_int tmpVar;\
+	memcpy(&tmpVar, (int* )priva->conf->var,4); \
+	pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n",#var, tmpVar);\
+}
+
+
+const char *arlan_diagnostic_info_string(struct device *dev)
+{
+
+	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;
+	u_char diagnosticInfo;
+
+	READSHM(diagnosticInfo, arlan->diagnosticInfo, u_char);
+
+	switch (diagnosticInfo)
+	{
+		case 0xFF:
+			return "Diagnostic info is OK";
+		case 0xFE:
+			return "ERROR EPROM Checksum error ";
+		case 0xFD:
+			return "ERROR Local Ram Test Failed ";
+		case 0xFC:
+			return "ERROR SCC failure ";
+		case 0xFB:
+			return "ERROR BackBone failure ";
+		case 0xFA:
+			return "ERROR tranceiver not found ";
+		case 0xF9:
+			return "ERROR no more address space ";
+		case 0xF8:
+			return "ERROR Checksum error  ";
+		case 0xF7:
+			return "ERROR Missing SS Code";
+		case 0xF6:
+			return "ERROR Invalid config format";
+		case 0xF5:
+			return "ERROR Reserved errorcode F5";
+		case 0xF4:
+			return "ERROR Invalid spreading code/channel number";
+		case 0xF3:
+			return "ERROR Load Code Error";
+		case 0xF2:
+			return "ERROR Reserver errorcode F2 ";
+		case 0xF1:
+			return "ERROR Invalid command receivec by LAN card ";
+		case 0xF0:
+			return "ERROR Invalid parameter found in command ";
+		case 0xEF:
+			return "ERROR On-chip timer failure ";
+		case 0xEE:
+			return "ERROR T410 timer failure ";
+		case 0xED:
+			return "ERROR Too Many TxEnable commands ";
+		case 0xEC:
+			return "ERROR EEPROM error on radio module ";
+		default:
+			return "ERROR unknown Diagnostic info reply code ";
+	  }
+};
+
+static const char *arlan_hardware_type_string(struct device *dev)
+{
+	u_char hardwareType;
+	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;
+
+	READSHM(hardwareType, arlan->hardwareType, u_char);
+	switch (hardwareType)
+	{
+		case 0x00:
+			return "type A450";
+		case 0x01:
+			return "type A650 ";
+		case 0x04:
+			return "type TMA coproc";
+		case 0x0D:
+			return "type A650E ";
+		case 0x18:
+			return "type TMA coproc Australian";
+		case 0x19:
+			return "type A650A ";
+		case 0x26:
+			return "type TMA coproc European";
+		case 0x2E:
+			return "type A655 ";
+		case 0x2F:
+			return "type A655A ";
+		case 0x30:
+			return "type A655E ";
+		case 0x0B:
+			return "type A670 ";
+		case 0x0C:
+			return "type A670E ";
+		case 0x2D:
+			return "type A670A ";
+		case 0x0F:
+			return "type A411T";
+		case 0x16:
+			return "type A411TA";
+		case 0x1B:
+			return "type A440T";
+		case 0x1C:
+			return "type A412T";
+		case 0x1E:
+			return "type A412TA";
+		case 0x22:
+			return "type A411TE";
+		case 0x24:
+			return "type A412TE";
+		case 0x27:
+			return "type A671T ";
+		case 0x29:
+			return "type A671TA ";
+		case 0x2B:
+			return "type A671TE ";
+		case 0x31:
+			return "type A415T ";
+		case 0x33:
+			return "type A415TA ";
+		case 0x35:
+			return "type A415TE ";
+		case 0x37:
+			return "type A672";
+		case 0x39:
+			return "type A672A ";
+		case 0x3B:
+			return "type A672T";
+		case 0x6B:
+			return "type IC2200";
+		default:
+			return "type A672T";
+	}
+}
+
+static void arlan_print_diagnostic_info(struct device *dev)
+{
+	int i;
+	u_char diagnosticInfo;
+	u_short diagnosticOffset;
+	u_char hardwareType;
+	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;
+
+	//  ARLAN_DEBUG_ENTRY("arlan_print_diagnostic_info");
+
+	if (READSHMB(arlan->configuredStatusFlag) == 0)
+		printk("Arlan: Card NOT configured\n");
+	else
+		printk("Arlan: Card is configured\n");
+
+	READSHM(diagnosticInfo, arlan->diagnosticInfo, u_char);
+	READSHM(diagnosticOffset, arlan->diagnosticOffset, u_short);
+
+	printk(KERN_INFO "%s\n", arlan_diagnostic_info_string(dev));
+
+	if (diagnosticInfo != 0xff)
+		printk("%s arlan: Diagnostic Offset %d \n", dev->name, diagnosticOffset);
+
+	printk("arlan: LAN CODE ID = ");
+	for (i = 0; i < 6; i++)
+		DEBUGSHM(1, "%03d:", arlan->lanCardNodeId[i], u_char);
+	printk("\n");
+
+	printk("arlan: Arlan BroadCast address  = ");
+	for (i = 0; i < 6; i++)
+		DEBUGSHM(1, "%03d:", arlan->broadcastAddress[i], u_char);
+	printk("\n");
+
+	READSHM(hardwareType, arlan->hardwareType, u_char);
+	printk(KERN_INFO "%s\n", arlan_hardware_type_string(dev));
+
+
+	DEBUGSHM(1, "arlan: channelNumber=%d\n", arlan->channelNumber, u_char);
+	DEBUGSHM(1, "arlan: channelSet=%d\n", arlan->channelSet, u_char);
+	DEBUGSHM(1, "arlan: spreadingCode=%d\n", arlan->spreadingCode, u_char);
+	DEBUGSHM(1, "arlan: radioNodeId=%d\n", arlan->radioNodeId, u_short);
+	DEBUGSHM(1, "arlan: SID	=%d\n", arlan->SID, u_short);
+	DEBUGSHM(1, "arlan: rxOffset=%d\n", arlan->rxOffset, u_short);
+
+	DEBUGSHM(1, "arlan: registration mode is %d\n", arlan->registrationMode, u_char);
+
+	printk("arlan: name= ");
+	IFDEBUG(1)
+	
+	for (i = 0; i < 16; i++)
+	{
+		char c;
+		READSHM(c, arlan->name[i], char);
+		if (c)
+			printk("%c", c);
+	}
+	printk("\n");
+
+//   ARLAN_DEBUG_EXIT("arlan_print_diagnostic_info");
+
+}
+
+
+/******************************		TEST 	MEMORY	**************/
+
+static int arlan_hw_test_memory(struct device *dev)
+{
+	u_char *ptr;
+	int i;
+	int memlen = sizeof(struct arlan_shmem) - 0xF;	/* avoid control register */
+	volatile char *arlan_mem = (char *) (dev->mem_start);
+	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;
+	char pattern;
+
+	ptr = NULL;
+
+	/* hold card in reset state */
+	setHardwareReset(dev);
+
+	/* test memory */
+	pattern = 0;
+	for (i = 0; i < memlen; i++)
+		WRITESHM(arlan_mem[i], ((u_char) pattern++), u_char);
+
+	pattern = 0;
+	for (i = 0; i < memlen; i++)
+	{
+		char res;
+		READSHM(res, arlan_mem[i], char);
+		if (res != pattern++)
+		{
+			printk(KERN_ERR "Arlan driver memory test 1 failed \n");
+			return -1;
+		}
+	}
+
+	pattern = 0;
+	for (i = 0; i < memlen; i++)
+		WRITESHM(arlan_mem[i], ~(pattern++), char);
+
+	pattern = 0;
+	for (i = 0; i < memlen; i++)
+	{
+		char res;
+		READSHM(res, arlan_mem[i], char);
+		if (res != ~(pattern++))
+		{
+			printk(KERN_ERR "Arlan driver memory test 2 failed \n");
+			return -1;
+		}
+	}
+
+	/* zero memory */
+	for (i = 0; i < memlen; i++)
+		WRITESHM(arlan_mem[i], 0x00, char);
+
+	IFDEBUG(1) printk(KERN_INFO "Arlan: memory tests ok\n");
+
+	/* set reset flag and then release reset */
+	WRITESHM(arlan->resetFlag, 0xff, u_char);
+
+	clearChannelAttention(dev);
+	clearHardwareReset(dev);
+
+	/* wait for reset flag to become zero, we'll wait for two seconds */
+	if (arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW))
+	{
+		printk(KERN_ERR "%s arlan: failed to come back from memory test\n", dev->name);
+		return -1;
+	}
+	return 0;
+}
+
+
+static int arlan_setup_card_by_book(struct device *dev)
+{
+	u_char irqLevel, configuredStatusFlag;
+	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;
+
+//	ARLAN_DEBUG_ENTRY("arlan_setup_card");
+
+	READSHM(configuredStatusFlag, arlan->configuredStatusFlag, u_char);
+
+	IFDEBUG(10)
+	if (configuredStatusFlag != 0)
+		IFDEBUG(10) printk("arlan: CARD IS CONFIGURED\n");
+	else
+		IFDEBUG(10) printk("arlan: card is NOT configured\n");
+
+	if (testMemory || (READSHMB(arlan->diagnosticInfo) != 0xff))
+		if (arlan_hw_test_memory(dev))
+			return -1;
+
+	DEBUGSHM(4, "arlan configuredStatus = %d \n", arlan->configuredStatusFlag, u_char);
+	DEBUGSHM(4, "arlan driver diagnostic: 0x%2x\n", arlan->diagnosticInfo, u_char);
+
+	/* issue nop command - no interupt */
+	arlan_command(dev, ARLAN_COMMAND_NOOP);
+	if (arlan_command(dev, ARLAN_COMMAND_WAIT_NOW) != 0)
+		return -1;
+
+	IFDEBUG(50) printk("1st Noop successfully executed !!\n");
+
+	/* try to turn on the arlan interrupts */
+	clearClearInterrupt(dev);
+	setClearInterrupt(dev);
+	setInterruptEnable(dev);
+
+	/* issue nop command - with interrupt */
+
+	arlan_command(dev, ARLAN_COMMAND_NOOPINT);
+	if (arlan_command(dev, ARLAN_COMMAND_WAIT_NOW) != 0)
+		return -1;
+
+
+	IFDEBUG(50) printk("2nd Noop successfully executed !!\n");
+
+	READSHM(irqLevel, arlan->irqLevel, u_char)
+	
+	if (irqLevel != dev->irq)
+	{
+		IFDEBUG(1) printk(KERN_WARNING "arlan dip switches set irq to %d\n", irqLevel);
+		printk(KERN_WARNING "device driver irq set to %d - does not match\n", dev->irq);
+		dev->irq = irqLevel;
+	}
+	else
+		IFDEBUG(2) printk("irq level is OK\n");
+
+
+	IFDEBUG(3) arlan_print_diagnostic_info(dev);
+
+	arlan_command(dev, ARLAN_COMMAND_CONF);
+
+	READSHM(configuredStatusFlag, arlan->configuredStatusFlag, u_char);
+	if (configuredStatusFlag == 0)
+	{
+		printk(KERN_WARNING "arlan configure failed\n");
+		return -1;
+	}
+	arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW);
+	arlan_command(dev, ARLAN_COMMAND_RX);
+	arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW);
+	printk(KERN_NOTICE "%s: arlan driver version %s loaded\n",
+	       dev->name, arlan_version);
+
+//	ARLAN_DEBUG_EXIT("arlan_setup_card");
+
+	return 0;		/* no errors */
+}
+
+
+#ifdef ARLAN_PROC_INTERFACE
+#ifdef ARLAN_PROC_SHM_DUMP
+
+static char arlan_drive_info[ARLAN_STR_SIZE] = "A655\n\0";
+
+static int arlan_sysctl_info(ctl_table * ctl, int write, struct file *filp,
+		      void *buffer, size_t * lenp)
+{
+	int i;
+	int retv, pos, devnum;
+	struct arlan_private *priva = NULL;
+	struct device *dev;
+	pos = 0;
+	if (write)
+	{
+		printk("wrirte: ");
+		for (i = 0; i < 100; i++)
+			printk("adi %x \n", arlan_drive_info[i]);
+	}
+	if (ctl->procname == NULL || arlan_drive_info == NULL)
+	{
+		printk(KERN_WARNING " procname is NULL in sysctl_table or arlan_drive_info is NULL \n at arlan module\n ");
+		return -1;
+	}
+	devnum = ctl->procname[5] - '0';
+	if (devnum < 0 || devnum > MAX_ARLANS - 1)
+	{
+		printk(KERN_WARNING "too strange devnum in procfs parse\n ");
+		return -1;
+	}
+	else if (arlan_device[devnum] == NULL)
+	{
+		if (ctl->procname)
+			pos += sprintf(arlan_drive_info + pos, "\t%s\n\n", ctl->procname);
+		pos += sprintf(arlan_drive_info + pos, "No device found here \n");
+		goto final;
+	}
+	else
+		priva = arlan_device[devnum]->priv;
+
+	if (priva == NULL)
+	{
+		printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
+		return -1;
+	}
+	dev = arlan_device[devnum];
+
+	memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
+
+	pos = sprintf(arlan_drive_info, "Arlan  info \n");
+	/* Header Signature */
+	SARLSTR(textRegion, 48);
+	SARLUC(resetFlag);
+	pos += sprintf(arlan_drive_info + pos, "diagnosticInfo\t=\t%s \n", arlan_diagnostic_info_string(dev));
+	SARLUC(diagnosticInfo);
+	SARLUS(diagnosticOffset);
+	SARLUCN(_1, 12);
+	SARLUCN(lanCardNodeId, 6);
+	SARLUCN(broadcastAddress, 6);
+	pos += sprintf(arlan_drive_info + pos, "hardwareType =\t  %s \n", arlan_hardware_type_string(dev));
+	SARLUC(hardwareType);
+	SARLUC(majorHardwareVersion);
+	SARLUC(minorHardwareVersion);
+	SARLUC(radioModule);
+	SARLUC(defaultChannelSet);
+	SARLUCN(_2, 47);
+
+	/* Control/Status Block - 0x0080 */
+	SARLUC(interruptInProgress);
+	SARLUC(cntrlRegImage);
+
+	SARLUCN(_3, 14);
+	SARLUC(commandByte);
+	SARLUCN(commandParameter, 15);
+
+	/* Receive Status - 0x00a0 */
+	SARLUC(rxStatus);
+	SARLUC(rxFrmType);
+	SARLUS(rxOffset);
+	SARLUS(rxLength);
+	SARLUCN(rxSrc, 6);
+	SARLUC(rxBroadcastFlag);
+	SARLUC(rxQuality);
+	SARLUC(scrambled);
+	SARLUCN(_4, 1);
+
+	/* Transmit Status - 0x00b0 */
+	SARLUC(txStatus);
+	SARLUC(txAckQuality);
+	SARLUC(numRetries);
+	SARLUCN(_5, 14);
+	SARLUCN(registeredRouter, 6);
+	SARLUCN(backboneRouter, 6);
+	SARLUC(registrationStatus);
+	SARLUC(configuredStatusFlag);
+	SARLUCN(_6, 1);
+	SARLUCN(ultimateDestAddress, 6);
+	SARLUCN(immedDestAddress, 6);
+	SARLUCN(immedSrcAddress, 6);
+	SARLUS(rxSequenceNumber);
+	SARLUC(assignedLocaltalkAddress);
+	SARLUCN(_7, 27);
+
+	/* System Parameter Block */
+
+	/* - Driver Parameters (Novell Specific) */
+
+	SARLUS(txTimeout);
+	SARLUS(transportTime);
+	SARLUCN(_8, 4);
+
+	/* - Configuration Parameters */
+	SARLUC(irqLevel);
+	SARLUC(spreadingCode);
+	SARLUC(channelSet);
+	SARLUC(channelNumber);
+	SARLUS(radioNodeId);
+	SARLUCN(_9, 2);
+	SARLUC(scramblingDisable);
+	SARLUC(radioType);
+	SARLUS(routerId);
+	SARLUCN(_10, 9);
+	SARLUC(txAttenuation);
+	SARLUIA(systemId);
+	SARLUS(globalChecksum);
+	SARLUCN(_11, 4);
+	SARLUS(maxDatagramSize);
+	SARLUS(maxFrameSize);
+	SARLUC(maxRetries);
+	SARLUC(receiveMode);
+	SARLUC(priority);
+	SARLUC(rootOrRepeater);
+	SARLUCN(specifiedRouter, 6);
+	SARLUS(fastPollPeriod);
+	SARLUC(pollDecay);
+	SARLUSA(fastPollDelay);
+	SARLUC(arlThreshold);
+	SARLUC(arlDecay);
+	SARLUCN(_12, 1);
+	SARLUS(specRouterTimeout);
+	SARLUCN(_13, 5);
+
+	/* Scrambled Area */
+	SARLUIA(SID);
+	SARLUCN(encryptionKey, 12);
+	SARLUIA(_14);
+	SARLUSA(waitTime);
+	SARLUSA(lParameter);
+	SARLUCN(_15, 3);
+	SARLUS(headerSize);
+	SARLUS(sectionChecksum);
+
+	SARLUC(registrationMode);
+	SARLUC(registrationFill);
+	SARLUS(pollPeriod);
+	SARLUS(refreshPeriod);
+	SARLSTR(name, 16);
+	SARLUCN(NID, 6);
+	SARLUC(localTalkAddress);
+	SARLUC(codeFormat);
+	SARLUC(numChannels);
+	SARLUC(channel1);
+	SARLUC(channel2);
+	SARLUC(channel3);
+	SARLUC(channel4);
+	SARLUCN(SSCode, 59);
+
+/*      SARLUCN( _16, 0x140);
+ */
+	/* Statistics Block - 0x0300 */
+	SARLUC(hostcpuLock);
+	SARLUC(lancpuLock);
+	SARLUCN(resetTime, 18);
+	SARLUIA(numDatagramsTransmitted);
+	SARLUIA(numReTransmissions);
+	SARLUIA(numFramesDiscarded);
+	SARLUIA(numDatagramsReceived);
+	SARLUIA(numDuplicateReceivedFrames);
+	SARLUIA(numDatagramsDiscarded);
+	SARLUS(maxNumReTransmitDatagram);
+	SARLUS(maxNumReTransmitFrames);
+	SARLUS(maxNumConsecutiveDuplicateFrames);
+	/* misaligned here so we have to go to characters */
+	SARLUIA(numBytesTransmitted);
+	SARLUIA(numBytesReceived);
+	SARLUIA(numCRCErrors);
+	SARLUIA(numLengthErrors);
+	SARLUIA(numAbortErrors);
+	SARLUIA(numTXUnderruns);
+	SARLUIA(numRXOverruns);
+	SARLUIA(numHoldOffs);
+	SARLUIA(numFramesTransmitted);
+	SARLUIA(numFramesReceived);
+	SARLUIA(numReceiveFramesLost);
+	SARLUIA(numRXBufferOverflows);
+	SARLUIA(numFramesDiscardedAddrMismatch);
+	SARLUIA(numFramesDiscardedSIDMismatch);
+	SARLUIA(numPollsTransmistted);
+	SARLUIA(numPollAcknowledges);
+	SARLUIA(numStatusTimeouts);
+	SARLUIA(numNACKReceived);
+	SARLUS(auxCmd);
+	SARLUCN(dumpPtr, 4);
+	SARLUC(dumpVal);
+	SARLUC(wireTest);
+	
+	/* next 4 seems too long for procfs, over single page ?
+	SARLUCN( _17, 0x86);
+	SARLUCN( txBuffer, 0x800);
+	SARLUCN( rxBuffer,  0x800); 
+	SARLUCN( _18, 0x0bff);
+	 */
+
+	pos += sprintf(arlan_drive_info + pos, "rxRing\t=\t0x");
+	for (i = 0; i < 0x50; i++)
+		pos += sprintf(arlan_drive_info + pos, "%02x", ((char *) priva->conf)[priva->conf->rxOffset + i]);
+	pos += sprintf(arlan_drive_info + pos, "\n");
+
+	SARLUC(configStatus);
+	SARLUC(_22);
+	SARLUC(progIOCtrl);
+	SARLUC(shareMBase);
+	SARLUC(controlRegister);
+
+	pos += sprintf(arlan_drive_info + pos, " total %d chars\n", pos);
+	if (ctl)
+		if (ctl->procname)
+			pos += sprintf(arlan_drive_info + pos, " driver name : %s\n", ctl->procname);
+final:
+	*lenp = pos;
+
+	if (!write)
+		retv = proc_dostring(ctl, write, filp, buffer, lenp);
+	else
+	{
+		*lenp = 0;
+		return -1;
+	}
+	return retv;
+}
+
+
+static int arlan_sysctl_info161719(ctl_table * ctl, int write, struct file *filp,
+			    void *buffer, size_t * lenp)
+{
+	int i;
+	int retv, pos, devnum;
+	struct arlan_private *priva = NULL;
+
+	pos = 0;
+	devnum = ctl->procname[5] - '0';
+	if (arlan_device[devnum] == NULL)
+	{
+		pos += sprintf(arlan_drive_info + pos, "No device found here \n");
+		goto final;
+	}
+	else
+		priva = arlan_device[devnum]->priv;
+	if (priva == NULL)
+	{
+		printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
+		return -1;
+	}
+	memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
+	SARLUCN(_16, 0xC0);
+	SARLUCN(_17, 0x6A);
+	SARLUCN(_18, 14);
+	SARLUCN(_19, 0x86);
+	SARLUCN(_21, 0x3fd);
+
+final:
+	*lenp = pos;
+	retv = proc_dostring(ctl, write, filp, buffer, lenp);
+	return retv;
+}
+
+static int arlan_sysctl_infotxRing(ctl_table * ctl, int write, struct file *filp,
+			    void *buffer, size_t * lenp)
+{
+	int i;
+	int retv, pos, devnum;
+	struct arlan_private *priva = NULL;
+
+	pos = 0;
+	devnum = ctl->procname[5] - '0';
+	if (arlan_device[devnum] == NULL)
+	{
+		  pos += sprintf(arlan_drive_info + pos, "No device found here \n");
+		  goto final;
+	}
+	else
+		priva = arlan_device[devnum]->priv;
+	if (priva == NULL)
+	{
+		printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
+		return -1;
+	}
+	memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
+	SARLBNpln(u_char, txBuffer, 0x800);
+final:
+	*lenp = pos;
+	retv = proc_dostring(ctl, write, filp, buffer, lenp);
+	return retv;
+}
+
+static int arlan_sysctl_inforxRing(ctl_table * ctl, int write, struct file *filp,
+			    void *buffer, size_t * lenp)
+{
+	int i;
+	int retv, pos, devnum;
+	struct arlan_private *priva = NULL;
+
+	pos = 0;
+	devnum = ctl->procname[5] - '0';
+	if (arlan_device[devnum] == NULL)
+	{
+		  pos += sprintf(arlan_drive_info + pos, "No device found here \n");
+		  goto final;
+	} else
+		priva = arlan_device[devnum]->priv;
+	if (priva == NULL)
+	{
+		printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
+		return -1;
+	}
+	memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
+	SARLBNpln(u_char, rxBuffer, 0x800);
+final:
+	*lenp = pos;
+	retv = proc_dostring(ctl, write, filp, buffer, lenp);
+	return retv;
+}
+
+static int arlan_sysctl_info18(ctl_table * ctl, int write, struct file *filp,
+			void *buffer, size_t * lenp)
+{
+	int i;
+	int retv, pos, devnum;
+	struct arlan_private *priva = NULL;
+
+	pos = 0;
+	devnum = ctl->procname[5] - '0';
+	if (arlan_device[devnum] == NULL)
+	{
+		pos += sprintf(arlan_drive_info + pos, "No device found here \n");
+		goto final;
+	}
+	else
+		priva = arlan_device[devnum]->priv;
+	if (priva == NULL)
+	{
+		printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
+		return -1;
+	}
+	memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
+	SARLBNpln(u_char, _18, 0x800);
+
+final:
+	*lenp = pos;
+	retv = proc_dostring(ctl, write, filp, buffer, lenp);
+	return retv;
+}
+
+
+#endif				/* #ifdef ARLAN_PROC_SHM_DUMP */
+
+
+static char conf_reset_result[200];
+
+static int arlan_configure(ctl_table * ctl, int write, struct file *filp,
+		    void *buffer, size_t * lenp)
+{
+	int pos = 0;
+	int devnum = ctl->procname[6] - '0';
+	struct arlan_private *priv;
+
+	if (devnum < 0 || devnum > MAX_ARLANS - 1)
+	{
+		  printk(KERN_WARNING "too strange devnum in procfs parse\n ");
+		  return -1;
+	}
+	else if (arlan_device[devnum] != NULL)
+	{
+		  priv = arlan_device[devnum]->priv;
+
+		  arlan_command(arlan_device[devnum], ARLAN_COMMAND_CLEAN_AND_CONF);
+	}
+	else
+		return -1;
+
+	*lenp = pos;
+	return proc_dostring(ctl, write, filp, buffer, lenp);
+}
+
+int arlan_sysctl_reset(ctl_table * ctl, int write, struct file *filp,
+		       void *buffer, size_t * lenp)
+{
+	int pos = 0;
+	int devnum = ctl->procname[5] - '0';
+	struct arlan_private *priv;
+
+	if (devnum < 0 || devnum > MAX_ARLANS - 1)
+	{
+		  printk(KERN_WARNING "too strange devnum in procfs parse\n ");
+		  return -1;
+	}
+	else if (arlan_device[devnum] != NULL)
+	{
+		priv = arlan_device[devnum]->priv;
+		arlan_command(arlan_device[devnum], ARLAN_COMMAND_CLEAN_AND_RESET);
+
+	} else
+		return -1;
+	*lenp = pos + 3;
+	return proc_dostring(ctl, write, filp, buffer, lenp);
+}
+
+
+/* Place files in /proc/sys/dev/arlan */
+#define CTBLN(num,card,nam) \
+        {num , #nam, &(arlan_conf[card].nam), \
+         sizeof(int), 0600, NULL, &proc_dointvec}
+
+
+#define ARLAN_SYSCTL_TABLE_TOTAL(cardNo)\
+	CTBLN(1,cardNo,spreadingCode),\
+	CTBLN(2,cardNo, channelNumber),\
+	CTBLN(3,cardNo, scramblingDisable),\
+	CTBLN(4,cardNo, txAttenuation),\
+	CTBLN(5,cardNo, systemId), \
+	CTBLN(6,cardNo, maxDatagramSize),\
+	CTBLN(7,cardNo, maxFrameSize),\
+	CTBLN(8,cardNo, maxRetries),\
+	CTBLN(9,cardNo, receiveMode),\
+	CTBLN(10,cardNo, priority),\
+	CTBLN(11,cardNo, rootOrRepeater),\
+	CTBLN(12,cardNo, SID),\
+	CTBLN(13,cardNo, registrationMode),\
+	CTBLN(14,cardNo, registrationFill),\
+	CTBLN(15,cardNo, localTalkAddress),\
+	CTBLN(16,cardNo, codeFormat),\
+	CTBLN(17,cardNo, numChannels),\
+	CTBLN(18,cardNo, channel1),\
+	CTBLN(19,cardNo, channel2),\
+	CTBLN(20,cardNo, channel3),\
+	CTBLN(21,cardNo, channel4),\
+	CTBLN(22,cardNo, txClear),\
+	CTBLN(23,cardNo, txRetries),\
+	CTBLN(24,cardNo, txRouting),\
+	CTBLN(25,cardNo, txScrambled),\
+	CTBLN(26,cardNo, rxParameter),\
+	CTBLN(27,cardNo, txTimeoutMs),\
+	CTBLN(28,cardNo, waitCardTimeout),\
+	CTBLN(29,cardNo, channelSet), \
+	{30, "name", arlan_conf[cardNo].siteName, \
+                16, 0600, NULL, &proc_dostring},\
+	CTBLN(31,cardNo,waitTime),\
+	CTBLN(32,cardNo,lParameter),\
+	CTBLN(33,cardNo,_15),\
+	CTBLN(34,cardNo,headerSize),\
+	CTBLN(35,cardNo,async),\
+	CTBLN(36,cardNo,tx_delay_ms),\
+	CTBLN(37,cardNo,retries),\
+	CTBLN(38,cardNo,ReTransmitPacketMaxSize),\
+	CTBLN(39,cardNo,waitReTransmitPacketMaxSize),\
+	CTBLN(40,cardNo,fastReTransCount),\
+	CTBLN(41,cardNo,driverRetransmissions),\
+	CTBLN(42,cardNo,txAckTimeoutMs),\
+	CTBLN(43,cardNo,registrationInterrupts),\
+	CTBLN(44,cardNo,hardwareType),\
+	CTBLN(45,cardNo,radioType),\
+	CTBLN(46,cardNo,writeEEPROM),\
+	CTBLN(47,cardNo,writeRadioType),\
+	{48, "entry_exit_debug", &arlan_entry_and_exit_debug, \
+                sizeof(int), 0600, NULL, &proc_dointvec},\
+	{49, "debug", &arlan_debug, \
+                sizeof(int), 0600, NULL, &proc_dointvec},\
+	CTBLN(50,cardNo,in_speed),\
+	CTBLN(51,cardNo,out_speed),\
+	CTBLN(52,cardNo,in_speed10),\
+	CTBLN(53,cardNo,out_speed10),\
+	CTBLN(54,cardNo,in_speed_max),\
+	CTBLN(55,cardNo,out_speed_max),\
+	CTBLN(56,cardNo,measure_rate),\
+	CTBLN(57,cardNo,pre_Command_Wait),\
+	CTBLN(58,cardNo,rx_tweak1),\
+	CTBLN(59,cardNo,rx_tweak2),\
+	CTBLN(60,cardNo,tx_queue_len),\
+
+
+
+static ctl_table arlan_conf_table0[] =
+{
+	ARLAN_SYSCTL_TABLE_TOTAL(0)
+
+#ifdef ARLAN_PROC_SHM_DUMP
+	{150, "arlan0-txRing", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_infotxRing},
+	{151, "arlan0-rxRing", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_inforxRing},
+	{152, "arlan0-18", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_info18},
+	{153, "arlan0-ring", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_info161719},
+	{154, "arlan0-shm-cpy", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_info},
+#endif
+	{155, "config0", &conf_reset_result, \
+	 100, 0400, NULL, &arlan_configure}, \
+	{156, "reset0", &conf_reset_result, \
+	 100, 0400, NULL, &arlan_sysctl_reset}, \
+	{0}
+};
+
+static ctl_table arlan_conf_table1[] =
+{
+
+	ARLAN_SYSCTL_TABLE_TOTAL(1)
+
+#ifdef ARLAN_PROC_SHM_DUMP
+	{150, "arlan1-txRing", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_infotxRing},
+	{151, "arlan1-rxRing", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_inforxRing},
+	{152, "arlan1-18", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_info18},
+	{153, "arlan1-ring", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_info161719},
+	{154, "arlan1-shm-cpy", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_info},
+#endif
+	{155, "config1", &conf_reset_result,
+	 100, 0400, NULL, &arlan_configure},
+	{156, "reset1", &conf_reset_result,
+	 100, 0400, NULL, &arlan_sysctl_reset},
+	{0}
+};
+
+static ctl_table arlan_conf_table2[] =
+{
+
+	ARLAN_SYSCTL_TABLE_TOTAL(2)
+
+#ifdef ARLAN_PROC_SHM_DUMP
+	{150, "arlan2-txRing", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_infotxRing},
+	{151, "arlan2-rxRing", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_inforxRing},
+	{152, "arlan2-18", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_info18},
+	{153, "arlan2-ring", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_info161719},
+	{154, "arlan2-shm-cpy", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_info},
+#endif
+	{155, "config2", &conf_reset_result,
+	 100, 0400, NULL, &arlan_configure},
+	{156, "reset2", &conf_reset_result,
+	 100, 0400, NULL, &arlan_sysctl_reset},
+	{0}
+};
+
+static ctl_table arlan_conf_table3[] =
+{
+
+	ARLAN_SYSCTL_TABLE_TOTAL(3)
+
+#ifdef ARLAN_PROC_SHM_DUMP
+	{150, "arlan3-txRing", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_infotxRing},
+	{151, "arlan3-rxRing", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_inforxRing},
+	{152, "arlan3-18", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_info18},
+	{153, "arlan3-ring", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_info161719},
+	{154, "arlan3-shm-cpy", &arlan_drive_info,
+	 ARLAN_STR_SIZE, 0400, NULL, &arlan_sysctl_info},
+#endif
+	{155, "config3", &conf_reset_result,
+	 100, 0400, NULL, &arlan_configure},
+	{156, "reset3", &conf_reset_result,
+	 100, 0400, NULL, &arlan_sysctl_reset},
+	{0}
+};
+
+
+
+static ctl_table arlan_table[] =
+{
+	{0, "arlan0", NULL, 0, 0600, arlan_conf_table0},
+	{0, "arlan1", NULL, 0, 0600, arlan_conf_table1},
+	{0, "arlan2", NULL, 0, 0600, arlan_conf_table2},
+	{0, "arlan3", NULL, 0, 0600, arlan_conf_table3},
+	{0}
+};
+
+#else
+
+static ctl_table arlan_table[MAX_ARLANS + 1] =
+{
+	{0}
+};
+#endif
+#endif
+
+static int mmtu = 1234;
+
+static ctl_table arlan_root_table[] =
+{
+	{254, "arlan", NULL, 0, 0555, arlan_table},
+	{0}
+};
+
+/* Make sure that /proc/sys/dev is there */
+static ctl_table arlan_device_root_table[] =
+{
+	{CTL_DEV, "dev", NULL, 0, 0555, arlan_root_table},
+	{0}
+};
+
+
+
+static struct ctl_table_header *arlan_device_sysctl_header = NULL;
+
+int init_arlan_proc(void)
+{
+
+	int i = 0;
+	if (arlan_device_sysctl_header)
+		return 0;
+	for (i = 0; i < MAX_ARLANS && arlan_device[i]; i++)
+		arlan_table[i].ctl_name = i + 1;
+	arlan_device_sysctl_header = register_sysctl_table(arlan_root_table, 0);
+	if (!arlan_device_sysctl_header)
+		return -1;
+
+	return 0;
+
+};
+
+
+
+#ifdef MODULE
+
+int init_module(void)
+{
+
+ return init_arlan_proc();
+};
+
+void cleanup_module(void)
+{
+	unregister_sysctl_table(arlan_device_sysctl_header);
+	arlan_device_sysctl_header = NULL;
+
+	return;
+};
+
+#endif				// MODULE
diff -u --recursive --new-file v2.3.9/linux/drivers/net/arlan.c linux/drivers/net/arlan.c
--- v2.3.9/linux/drivers/net/arlan.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/arlan.c	Tue Jul  6 10:11:40 1999
@@ -0,0 +1,2079 @@
+/*
+ *  Copyright (C) 1997 Cullen Jennings
+ *  Copyright (C) 1998 Elmer....@ut.ee, +37-255-13500        
+ *  Gnu Public License applies
+ * This module provides support for the Arlan 655 card made by Aironet
+ */
+
+#include <linux/config.h>
+#include "arlan.h"
+
+static const char *arlan_version = "C.Jennigs 97 & Elmer....@ut.ee  Oct'98, http://www.ylenurme.ee/~elmer/655/";
+
+struct device *arlan_device[MAX_ARLANS];
+int last_arlan = 0;
+
+static int SID = SIDUNKNOWN;
+static int radioNodeId = radioNodeIdUNKNOWN;
+static char encryptionKey[12] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
+static char *siteName = siteNameUNKNOWN;
+static int irq = irqUNKNOWN;
+static int mem = memUNKNOWN;
+static int arlan_debug = debugUNKNOWN;
+static int probe = probeUNKNOWN;
+static int numDevices = numDevicesUNKNOWN;
+static int testMemory = testMemoryUNKNOWN;
+static int spreadingCode = spreadingCodeUNKNOWN;
+static int channelNumber = channelNumberUNKNOWN;
+static int channelSet = channelSetUNKNOWN;
+static int systemId = systemIdUNKNOWN;
+static int registrationMode = registrationModeUNKNOWN;
+static int txScrambled = 1;
+static int keyStart = 0;
+static int mdebug = 0;
+static int tx_delay_ms = 0;
+static int retries = 5;
+static int async = 1;
+static int tx_queue_len = 1;
+static int arlan_entry_debug = 0;
+static int arlan_exit_debug = 0;
+static int arlan_entry_and_exit_debug = 0;
+static int arlan_EEPROM_bad = 0;
+
+#if LINUX_VERSION_CODE > 0x20100
+MODULE_PARM(irq, "i");
+MODULE_PARM(mem, "i");
+MODULE_PARM(probe, "i");
+MODULE_PARM(arlan_debug, "i");
+MODULE_PARM(numDevices, "i");
+MODULE_PARM(testMemory, "i");
+MODULE_PARM(spreadingCode, "i");
+MODULE_PARM(channelNumber, "i");
+MODULE_PARM(channelSet, "i");
+MODULE_PARM(systemId, "i");
+MODULE_PARM(registrationMode, "i");
+MODULE_PARM(radioNodeId, "i");
+MODULE_PARM(SID, "i");
+MODULE_PARM(txScrambled, "i");
+MODULE_PARM(keyStart, "i");
+MODULE_PARM(mdebug, "i");
+MODULE_PARM(tx_delay_ms, "i");
+MODULE_PARM(retries, "i");
+MODULE_PARM(async, "i");
+MODULE_PARM(tx_queue_len, "i");
+MODULE_PARM(arlan_entry_debug, "i");
+MODULE_PARM(arlan_exit_debug, "i");
+MODULE_PARM(arlan_entry_and_exit_debug, "i");
+MODULE_PARM(arlan_EEPROM_bad, "i");
+
+EXPORT_SYMBOL(arlan_device);
+EXPORT_SYMBOL(last_arlan);
+
+
+//        #warning kernel 2.1.110 tested
+#define myATOMIC_INIT(a,b) atomic_set(&(a),b)
+#define __initfunctio(a)                __initfunc(a)
+
+#else
+#define test_and_set_bit	set_bit
+#define __initfunctio(a)        a
+#if LINUX_VERSION_CODE != 0x20024
+ //        #warning kernel  2.0.36  tested
+#endif
+#define myATOMIC_INIT(a,b) a = b;
+
+#endif
+
+struct arlan_conf_stru arlan_conf[MAX_ARLANS];
+int arlans_found = 0;
+
+static  int 	arlan_probe_here(struct device *dev, int ioaddr);
+static  int 	arlan_open(struct device *dev);
+static  int 	arlan_tx(struct sk_buff *skb, struct device *dev);
+static  void 	arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static  int 	arlan_close(struct device *dev);
+static  struct enet_statistics *
+		arlan_statistics		(struct device *dev);
+static  void 	arlan_set_multicast		(struct device *dev);
+static  int 	arlan_hw_tx			(struct device* dev, char *buf, int length );
+static  int	arlan_hw_config			(struct device * dev);
+static  void 	arlan_tx_done_interrupt		(struct device * dev, int status);
+static  void	arlan_rx_interrupt		(struct device * dev, u_char rxStatus, u_short, u_short);
+static  void	arlan_process_interrupt		(struct device * dev);
+static  int	arlan_command(struct device * dev, int command);
+
+EXPORT_SYMBOL(arlan_command);
+
+extern inline long long arlan_time(void)
+{
+	struct timeval timev;
+	do_gettimeofday(&timev);
+	return ((long long) timev.tv_sec * 1000000 + timev.tv_usec);
+};
+
+#ifdef ARLAN_ENTRY_EXIT_DEBUGING
+#define ARLAN_DEBUG_ENTRY(name) \
+	{\
+	struct timeval timev;\
+	do_gettimeofday(&timev);\
+		if (arlan_entry_debug || arlan_entry_and_exit_debug)\
+			printk("--->>>" name " %ld " "\n",((long int) timev.tv_sec * 1000000 + timev.tv_usec));\
+	}
+#define ARLAN_DEBUG_EXIT(name) \
+	{\
+	struct timeval timev;\
+	do_gettimeofday(&timev);\
+		if (arlan_exit_debug || arlan_entry_and_exit_debug)\
+			printk("<<<---" name " %ld " "\n",((long int) timev.tv_sec * 1000000 + timev.tv_usec) );\
+	}
+#else
+#define ARLAN_DEBUG_ENTRY(name)
+#define ARLAN_DEBUG_EXIT(name)
+#endif
+
+
+#define arlan_interrupt_ack(dev)\
+        clearClearInterrupt(dev);\
+        setClearInterrupt(dev);
+
+
+#define ARLAN_COMMAND_LOCK(dev) \
+	if (atomic_dec_and_test(&((struct arlan_private * )dev->priv)->card_users))\
+   		arlan_wait_command_complete_short(dev,__LINE__);
+#define ARLAN_COMMAND_UNLOCK(dev) \
+	atomic_inc(&((struct arlan_private * )dev->priv)->card_users);
+
+
+#define ARLAN_COMMAND_INC(dev) \
+ 	{((struct arlan_private *) dev->priv)->under_command++;}
+#define ARLAN_COMMAND_ZERO(dev) \
+ 	{((struct arlan_private *) dev->priv)->under_command =0;}
+#define ARLAN_UNDER_COMMAND(dev)\
+	(((struct arlan_private *) dev->priv)->under_command)
+
+#define ARLAN_COMMAND_START(dev) ARLAN_COMMAND_INC(dev)
+#define ARLAN_COMMAND_END(dev) ARLAN_COMMAND_ZERO(dev)
+#define ARLAN_TOGGLE_START(dev)\
+ 	{((struct arlan_private *) dev->priv)->under_toggle++;}
+#define ARLAN_TOGGLE_END(dev)\
+ 	{((struct arlan_private *) dev->priv)->under_toggle=0;}
+#define ARLAN_UNDER_TOGGLE(dev)\
+ 	(((struct arlan_private *) dev->priv)->under_toggle)
+
+
+
+extern inline int arlan_drop_tx(struct device *dev)
+{
+	struct arlan_private *priv = ((struct arlan_private *) dev->priv);
+
+	priv->stats.tx_errors++;
+	if (priv->Conf->tx_delay_ms)
+	{
+		priv->tx_done_delayed = jiffies + priv->Conf->tx_delay_ms * HZ / 1000 + 1;
+	}
+	else
+	{
+		priv->waiting_command_mask &= ~ARLAN_COMMAND_TX;
+		TXHEAD(dev).offset = 0;
+		TXTAIL(dev).offset = 0;
+		priv->txLast = 0;
+		priv->txOffset = 0;
+		priv->bad = 0;
+		if (!priv->under_reset && !priv->under_config)
+		{
+			dev->tbusy = 0;
+			mark_bh(NET_BH);
+		}
+	}
+	return 1;
+};
+
+
+static int arlan_command(struct device *dev, int command_p)
+{
+
+	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;
+	struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf;
+	struct arlan_private *priv = (struct arlan_private *) dev->priv;
+	int udelayed = 0;
+	int i = 0;
+	long long time_mks = arlan_time();
+
+	ARLAN_DEBUG_ENTRY("arlan_command");
+
+	if (priv->card_polling_interval)
+		priv->card_polling_interval = 1;
+
+	if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS)
+		printk(KERN_DEBUG "arlan_command, %lx lock %x  commandByte %x waiting %x incoming %x \n",
+		jiffies, priv->command_lock, READSHMB(arlan->commandByte),
+		       priv->waiting_command_mask, command_p);
+
+	priv->waiting_command_mask |= command_p;
+
+	if (priv->waiting_command_mask & ARLAN_COMMAND_RESET)
+		if (jiffies - priv->lastReset < 5 * HZ)
+			priv->waiting_command_mask &= ~ARLAN_COMMAND_RESET;
+
+	if (priv->waiting_command_mask & ARLAN_COMMAND_INT_ACK)
+	{
+		arlan_interrupt_ack(dev);
+		priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_ACK;
+	}
+	if (priv->waiting_command_mask & ARLAN_COMMAND_INT_ENABLE)
+	{
+		setInterruptEnable(dev);
+		priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_ENABLE;
+	}
+
+	/* Card access serializing lock */
+
+	if (test_and_set_bit(0, (void *) &priv->command_lock))
+	{
+		if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS)
+			printk(KERN_DEBUG "arlan_command: entered when command locked \n");
+		goto command_busy_end;
+	}
+	/* Check cards status and waiting */
+
+	if (priv->waiting_command_mask & (ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW))
+	{
+		while (priv->waiting_command_mask & (ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW))
+		{
+			if (READSHMB(arlan->resetFlag) ||
+				READSHMB(arlan->commandByte))	/* || 
+								   (readControlRegister(dev) & ARLAN_ACCESS))
+								 */
+				udelay(40);
+			else
+				priv->waiting_command_mask &= ~(ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW);
+
+			udelayed++;
+
+			if (priv->waiting_command_mask & ARLAN_COMMAND_LONG_WAIT_NOW)
+			{
+				if (udelayed * 40 > 1000000)
+				{
+					printk(KERN_ERR "%s long wait too long \n", dev->name);
+					priv->waiting_command_mask |= ARLAN_COMMAND_RESET;
+					break;
+				}
+			}
+			else if (priv->waiting_command_mask & ARLAN_COMMAND_WAIT_NOW)
+			{
+				if (udelayed * 40 > 1000)
+				{
+					printk(KERN_ERR "%s short wait too long \n", dev->name);
+					goto bad_end;
+				}
+			}
+		}
+	}
+	else
+	{
+		i = 0;
+		while ((READSHMB(arlan->resetFlag) ||
+			READSHMB(arlan->commandByte)) &&
+			conf->pre_Command_Wait > (i++) * 10)
+			udelay(10);
+
+
+		if ((READSHMB(arlan->resetFlag) ||
+			READSHMB(arlan->commandByte)) &&
+			!(priv->waiting_command_mask & ARLAN_COMMAND_RESET))
+		{
+			goto card_busy_end;
+		}
+	}
+	if (priv->waiting_command_mask & ARLAN_COMMAND_RESET)
+	{
+		priv->under_reset = 1;
+		dev->start = 0;
+	}
+	if (priv->waiting_command_mask & ARLAN_COMMAND_CONF)
+	{
+		priv->under_config = 1;
+		dev->start = 0;
+	}
+
+	/* Issuing command */
+	arlan_lock_card_access(dev);
+	if (priv->waiting_command_mask & ARLAN_COMMAND_POWERUP)
+	{
+	//     if (readControlRegister(dev) & (ARLAN_ACCESS && ARLAN_POWER))
+		setPowerOn(dev);
+		arlan_interrupt_lancpu(dev);
+		priv->waiting_command_mask &= ~ARLAN_COMMAND_POWERUP;
+		priv->waiting_command_mask |= ARLAN_COMMAND_RESET;
+		priv->card_polling_interval = HZ / 10;
+	}
+	else if (priv->waiting_command_mask & ARLAN_COMMAND_ACTIVATE)
+	{
+		WRITESHMB(arlan->commandByte, ARLAN_COM_ACTIVATE);
+		arlan_interrupt_lancpu(dev);
+		priv->waiting_command_mask &= ~ARLAN_COMMAND_ACTIVATE;
+		priv->card_polling_interval = HZ / 10;
+	}
+	else if (priv->waiting_command_mask & ARLAN_COMMAND_RX_ABORT)
+	{
+		if (priv->rx_command_given)
+		{
+			WRITESHMB(arlan->commandByte, ARLAN_COM_RX_ABORT);
+			arlan_interrupt_lancpu(dev);
+			priv->rx_command_given = 0;
+		}
+		priv->waiting_command_mask &= ~ARLAN_COMMAND_RX_ABORT;
+		priv->card_polling_interval = 1;
+	}
+	else if (priv->waiting_command_mask & ARLAN_COMMAND_TX_ABORT)
+	{
+		if (priv->tx_command_given)
+		{
+			WRITESHMB(arlan->commandByte, ARLAN_COM_TX_ABORT);
+			arlan_interrupt_lancpu(dev);
+			priv->tx_command_given = 0;
+		}
+		priv->waiting_command_mask &= ~ARLAN_COMMAND_TX_ABORT;
+		priv->card_polling_interval = 1;
+	}
+	else if (priv->waiting_command_mask & ARLAN_COMMAND_RESET)
+	{
+		arlan_drop_tx(dev);
+		if (priv->tx_command_given || priv->rx_command_given)
+		{
+			printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name);
+		};
+		if (arlan_debug & ARLAN_DEBUG_RESET)
+			printk(KERN_ERR "%s: Doing chip reset\n", dev->name);
+		priv->lastReset = jiffies;
+		WRITESHM(arlan->commandByte, 0, u_char);
+		/* hold card in reset state */
+		setHardwareReset(dev);
+		/* set reset flag and then release reset */
+		WRITESHM(arlan->resetFlag, 0xff, u_char);
+		clearChannelAttention(dev);
+		clearHardwareReset(dev);
+		priv->numResets++;
+		priv->card_polling_interval = HZ / 4;
+		priv->waiting_command_mask &= ~ARLAN_COMMAND_RESET;
+		priv->waiting_command_mask |= ARLAN_COMMAND_INT_RACK;
+//		priv->waiting_command_mask |= ARLAN_COMMAND_INT_RENABLE; 
+//		priv->waiting_command_mask |= ARLAN_COMMAND_RX;
+	}
+	else if (priv->waiting_command_mask & ARLAN_COMMAND_INT_RACK)
+	{
+		clearHardwareReset(dev);
+		clearClearInterrupt(dev);
+		setClearInterrupt(dev);
+		setInterruptEnable(dev);
+		priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_RACK;
+		priv->waiting_command_mask |= ARLAN_COMMAND_CONF;
+		priv->under_config = 1;
+		priv->under_reset = 0;
+	}
+	else if (priv->waiting_command_mask & ARLAN_COMMAND_INT_RENABLE)
+	{
+		setInterruptEnable(dev);
+		priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_RENABLE;
+	}
+	else if (priv->waiting_command_mask & ARLAN_COMMAND_CONF)
+	{
+		if (priv->tx_command_given || priv->rx_command_given)
+		{
+			printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name);
+		}
+		dev->start = 0;
+		arlan_drop_tx(dev);
+		setInterruptEnable(dev);
+		arlan_hw_config(dev);
+		arlan_interrupt_lancpu(dev);
+		priv->waiting_command_mask &= ~ARLAN_COMMAND_CONF;
+		priv->card_polling_interval = HZ / 10;
+//		priv->waiting_command_mask |= ARLAN_COMMAND_INT_RACK;   
+//		priv->waiting_command_mask |= ARLAN_COMMAND_INT_ENABLE; 
+		priv->waiting_command_mask |= ARLAN_COMMAND_CONF_WAIT;
+	}
+	else if (priv->waiting_command_mask & ARLAN_COMMAND_CONF_WAIT)
+	{
+		if (READSHMB(arlan->configuredStatusFlag) != 0 &&
+			READSHMB(arlan->diagnosticInfo) == 0xff)
+		{
+			priv->waiting_command_mask &= ~ARLAN_COMMAND_CONF_WAIT;
+			priv->waiting_command_mask |= ARLAN_COMMAND_RX;
+			priv->card_polling_interval = HZ / 10;
+			priv->tx_command_given = 0;
+			priv->under_config = 0;
+			if (dev->tbusy || !dev->start)
+			{
+				dev->tbusy = 0;
+				dev->start = 1;
+				mark_bh(NET_BH);
+			};
+		}
+		else
+		{
+			priv->card_polling_interval = 1;
+			if (arlan_debug & ARLAN_DEBUG_TIMING)
+				printk(KERN_ERR "configure delayed \n");
+		}
+	}
+	else if (priv->waiting_command_mask & ARLAN_COMMAND_RX)
+	{
+		if (!registrationBad(dev))
+		{
+			setInterruptEnable(dev);
+			memset_io((void *) arlan->commandParameter, 0, 0xf);
+			WRITESHMB(arlan->commandByte, ARLAN_COM_INT | ARLAN_COM_RX_ENABLE);
+			WRITESHMB(arlan->commandParameter[0], conf->rxParameter);
+			arlan_interrupt_lancpu(dev);
+			priv->rx_command_given;
+			priv->last_rx_time = arlan_time();
+			priv->waiting_command_mask &= ~ARLAN_COMMAND_RX;
+			priv->card_polling_interval = 1;
+		}
+		else
+			priv->card_polling_interval = 2;
+	}
+	else if (priv->waiting_command_mask & ARLAN_COMMAND_TX)
+	{
+		if (!test_and_set_bit(0, (void *) &priv->tx_command_given))
+		{
+			if ((time_mks - priv->last_tx_time > conf->rx_tweak1) ||
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 18'
echo 'File patch-2.3.10 is continued in part 19'
echo 19 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 03 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
-	}
-	pgtable = pte_offset(pgmiddle, addr);
-	if (!pte_present(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
-	}
-	page = pte_page(*pgtable);
-	if (!pte_write(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
-	}
-
-	/* This is a hack for non-kernel-mapped video buffers and similar.  */
-	if (MAP_NR(page) < max_mapnr)
-		*(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
-
-	/* We're bypassing pagetables, so we have to set the dirty bit
-	   ourselves.  This should also re-instate whatever read-only
-	   mode there was before.  */
-	set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-	flush_tlb();
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls get_long() to read a long.
- */
-static int
-read_long(struct task_struct * tsk, unsigned long addr, unsigned long * result)
-{
-	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
- DBG(DBG_MEM_ALL, ("in read_long\n"));
-	if (!vma)
-		return -EIO;
-	if ((addr & ~PAGE_MASK) > (PAGE_SIZE - sizeof(long))) {
-		struct vm_area_struct * vma_high = vma;
-		unsigned long low, align;
-
-		if (addr + sizeof(long) >= vma->vm_end) {
-			vma_high = vma->vm_next;
-			if (!vma_high || vma_high->vm_start != vma->vm_end)
-				return -EIO;
-		}
-		align = addr & (sizeof(long) - 1);
-		addr -= align;
-		low = get_long(tsk, vma, addr);
-		if (align) {
-			unsigned long high;
-
-			high = get_long(tsk, vma_high, addr + sizeof(long));
-			low >>= align * 8;
-			low  |= high << (64 - align * 8);
-		}
-		*result = low;
-	} else {
-	        long l = get_long(tsk, vma, addr);
-
-		DBG(DBG_MEM_ALL, ("value is 0x%lx\n", l));
-		*result = l;
-	}
-	return 0;
+	int copied = access_process_vm(task, addr, data, sizeof(int), 0);
+	return (copied == sizeof(int)) ? 0 : -EIO;
X }
X 
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls put_long() to write a long.
- */
-static int
-write_long(struct task_struct * tsk, unsigned long addr, unsigned long data)
+static inline int
+write_int(struct task_struct *task, unsigned long addr, int data)
X {
-	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
-	if (!vma)
-		return -EIO;
-	if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
-		unsigned long low, high, align;
-		struct vm_area_struct * vma_high = vma;
-
-		if (addr + sizeof(long) >= vma->vm_end) {
-			vma_high = vma->vm_next;
-			if (!vma_high || vma_high->vm_start != vma->vm_end)
-				return -EIO;
-		}
-		align = addr & (sizeof(long) - 1);
-		addr -= align;
-		low  = get_long(tsk, vma, addr);
-		high = get_long(tsk, vma_high, addr + sizeof(long));
-		low  &= ~0UL >> (64 - align * 8);
-		high &= ~0UL << (align * 8);
-		low  |= data << (align * 8);
-		high |= data >> (64 - align * 8);
-		put_long(tsk, vma, addr, low);
-		put_long(tsk, vma_high, addr + sizeof(long), high);
-	} else
-		put_long(tsk, vma, addr, data);
-	return 0;
-}
-
-/*
- * Read a 32bit int from address space TSK.
- */
-static int
-read_int(struct task_struct * tsk, unsigned long addr, unsigned int *data)
-{
-	unsigned long l, align;
-	int res;
-
-	align = addr & 0x7;
-	addr &= ~0x7;
-
-	res = read_long(tsk, addr, &l);
-	if (res < 0)
-		return res;
-
-	if (align == 0) {
-		*data = l;
-	} else {
-		*data = l >> 32;
-	}
-	return 0;
-}
-
-/*
- * Write a 32bit word to address space TSK.
- *
- * For simplicity, do a read-modify-write of the 64bit word that
- * contains the 32bit word that we are about to write.
- */
-static int
-write_int(struct task_struct * tsk, unsigned long addr, unsigned int data)
-{
-	unsigned long l, align;
-	int res;
-
-	align = addr & 0x7;
-	addr &= ~0x7;
-
-	res = read_long(tsk, addr, &l);
-	if (res < 0)
-		return res;
-
-	if (align == 0) {
-		l = (l & 0xffffffff00000000UL) | ((unsigned long) data <<  0);
-	} else {
-		l = (l & 0x00000000ffffffffUL) | ((unsigned long) data << 32);
-	}
-	return write_long(tsk, addr, l);
+	int copied = access_process_vm(task, addr, &data, sizeof(int), 1);
+	return (copied == sizeof(int)) ? 0 : -EIO;
X }
X 
X /*
@@ -521,16 +297,17 @@
X 	switch (request) {
X 	/* When I and D space are separate, these will need to be fixed.  */
X 	case PTRACE_PEEKTEXT: /* read word at location addr. */
-	case PTRACE_PEEKDATA:
-		down(&child->mm->mmap_sem);
-		ret = read_long(child, addr, &tmp);
-		up(&child->mm->mmap_sem);
-		DBG(DBG_MEM, ("peek %#lx->%#lx\n", addr, tmp));
-		if (ret < 0)
+	case PTRACE_PEEKDATA: {
+		unsigned long tmp;
+		int copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+		ret = -EIO;
+		if (copied != sizeof(tmp))
X 			goto out;
+		
X 		regs.r0 = 0;	/* special return: no errors */
X 		ret = tmp;
X 		goto out;
+	}
X 
X 	/* Read register number ADDR. */
X 	case PTRACE_PEEKUSR:
@@ -541,12 +318,12 @@
X 
X 	/* When I and D space are separate, this will have to be fixed.  */
X 	case PTRACE_POKETEXT: /* write the word at location addr. */
-	case PTRACE_POKEDATA:
-		DBG(DBG_MEM, ("poke %#lx<-%#lx\n", addr, data));
-		down(&child->mm->mmap_sem);
-		ret = write_long(child, addr, data);
-		up(&child->mm->mmap_sem);
+	case PTRACE_POKEDATA: {
+		unsigned long tmp = data;
+		int copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 1);
+		ret = (copied == sizeof(tmp)) ? 0 : -EIO;
X 		goto out;
+	}
X 
X 	case PTRACE_POKEUSR: /* write the specified register */
X 		DBG(DBG_MEM, ("poke $%ld<-%#lx\n", addr, data));
diff -u --recursive --new-file v2.3.9/linux/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c
--- v2.3.9/linux/arch/alpha/kernel/signal.c	Fri May 14 12:41:23 1999
+++ linux/arch/alpha/kernel/signal.c	Mon Jul  5 20:35:17 1999
@@ -16,7 +16,6 @@
X #include <linux/mm.h>
X #include <linux/smp.h>
X #include <linux/smp_lock.h>
-#include <linux/signal.h>
X #include <linux/stddef.h>
X 
X #include <asm/bitops.h>
diff -u --recursive --new-file v2.3.9/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c
--- v2.3.9/linux/arch/alpha/kernel/smp.c	Tue Jun 22 10:46:52 1999
+++ linux/arch/alpha/kernel/smp.c	Thu Jul  1 15:09:48 1999
@@ -603,7 +603,7 @@
X 
X 		update_one_process(current, 1, user, !user, cpu);
X 	        if (current->pid) {
-	                if (--current->counter < 0) {
+	                if (--current->counter <= 0) {
X 				current->counter = 0;
X 	                        current->need_resched = 1;
X 	                }
diff -u --recursive --new-file v2.3.9/linux/arch/arm/kernel/process.c linux/arch/arm/kernel/process.c
--- v2.3.9/linux/arch/arm/kernel/process.c	Thu Jun 17 01:11:35 1999
+++ linux/arch/arm/kernel/process.c	Mon Jul  5 20:35:17 1999
@@ -27,9 +27,7 @@
X #include <linux/a.out.h>
X #include <linux/interrupt.h>
X #include <linux/config.h>
-#include <linux/unistd.h>
X #include <linux/delay.h>
-#include <linux/smp.h>
X #include <linux/reboot.h>
X #include <linux/init.h>
X 
diff -u --recursive --new-file v2.3.9/linux/arch/arm/kernel/time.c linux/arch/arm/kernel/time.c
--- v2.3.9/linux/arch/arm/kernel/time.c	Thu Jun 17 01:11:35 1999
+++ linux/arch/arm/kernel/time.c	Mon Jul  5 20:35:17 1999
@@ -23,8 +23,6 @@
X #include <linux/delay.h>
X #include <linux/init.h>
X #include <linux/smp.h>
-#include <linux/init.h>
-#include <linux/delay.h>
X 
X #include <asm/uaccess.h>
X #include <asm/io.h>
diff -u --recursive --new-file v2.3.9/linux/arch/arm/nwfpe/fpmodule.c linux/arch/arm/nwfpe/fpmodule.c
--- v2.3.9/linux/arch/arm/nwfpe/fpmodule.c	Thu Jun 17 01:11:35 1999
+++ linux/arch/arm/nwfpe/fpmodule.c	Mon Jul  5 20:35:17 1999
@@ -36,7 +36,6 @@
X #include <linux/signal.h>
X #include <linux/sched.h>
X #include <linux/mm.h>
-#include <linux/sched.h>
X #include <linux/init.h>
X 
X #include <asm/system.h>
diff -u --recursive --new-file v2.3.9/linux/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S
--- v2.3.9/linux/arch/i386/boot/setup.S	Sat Nov 28 17:18:54 1998
+++ linux/arch/i386/boot/setup.S	Mon Jul  5 20:04:47 1999
@@ -753,19 +753,29 @@
X ! This routine checks that the keyboard command queue is empty
X ! (after emptying the output buffers)
X !
-! No timeout is used - if this hangs there is something wrong with
-! the machine, and we probably couldn't proceed anyway.
+! Some machines have delusions that the keyboard buffer is always full
+! with no keyboard attached...
+
X empty_8042:
+       push    ecx
+       mov     ecx,#0xFFFFFF
+
+empty_8042_loop:
+       dec     ecx
+       jz      empty_8042_end_loop
+
X 	call	delay
X 	in	al,#0x64	! 8042 status port
X 	test	al,#1		! output buffer?
X 	jz	no_output
X 	call	delay
X 	in	al,#0x60	! read it
-	jmp	empty_8042
+	jmp	empty_8042_loop
X no_output:
X 	test	al,#2		! is input buffer full?
-	jnz	empty_8042	! yes - loop
+	jnz	empty_8042_loop	! yes - loop
+empty_8042_end_loop:
+        pop     ecx
X 	ret
X 
X !
diff -u --recursive --new-file v2.3.9/linux/arch/i386/config.in linux/arch/i386/config.in
--- v2.3.9/linux/arch/i386/config.in	Wed Jun 30 13:38:18 1999
+++ linux/arch/i386/config.in	Thu Jul  1 14:22:56 1999
@@ -92,13 +92,7 @@
X tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
X tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
X 
-tristate 'Parallel port support' CONFIG_PARPORT
-if [ "$CONFIG_PARPORT" != "n" ]; then
-  dep_tristate '   PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
-  if [ "$CONFIG_PARPORT_PC" != "n" ]; then
-    bool '   Support foreign hardware' CONFIG_PARPORT_OTHER
-  fi
-fi
+source drivers/misc/Config.in
X 
X bool 'Advanced Power Management BIOS support' CONFIG_APM
X if [ "$CONFIG_APM" = "y" ]; then
diff -u --recursive --new-file v2.3.9/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.3.9/linux/arch/i386/defconfig	Wed Jun 30 13:38:18 1999
+++ linux/arch/i386/defconfig	Tue Jul  6 20:31:23 1999
@@ -70,11 +70,6 @@
X # CONFIG_I2O_PROC is not set
X 
X #
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
X # Block devices
X #
X CONFIG_BLK_DEV_FD=y
@@ -98,7 +93,10 @@
X # CONFIG_BLK_DEV_IDEDMA_PCI is not set
X # CONFIG_BLK_DEV_OFFBOARD is not set
X # CONFIG_BLK_DEV_AEC6210 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+CONFIG_BLK_DEV_PIIX=y
X # CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_CPQ_DA is not set
X 
X #
X # Additional Block Devices
@@ -214,9 +212,17 @@
X # Network device support
X #
X CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
X # CONFIG_ARCNET is not set
X CONFIG_DUMMY=m
X # CONFIG_EQUALIZER is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
X CONFIG_NET_ETHERNET=y
X # CONFIG_NET_VENDOR_3COM is not set
X # CONFIG_LANCE is not set
@@ -236,14 +242,22 @@
X # CONFIG_VIA_RHINE is not set
X # CONFIG_NET_POCKET is not set
X # CONFIG_FDDI is not set
-# CONFIG_DLCI is not set
X # CONFIG_PPP is not set
X # CONFIG_SLIP is not set
X # CONFIG_NET_RADIO is not set
+
+#
+# Token ring devices
+#
X # CONFIG_TR is not set
+
+#
+# Wan interfaces
+#
X # CONFIG_HOSTESS_SV11 is not set
X # CONFIG_COSA is not set
-# CONFIG_RCPCI is not set
+# CONFIG_SEALEVEL_4021 is not set
+# CONFIG_DLCI is not set
X # CONFIG_WAN_DRIVERS is not set
X # CONFIG_LAPBETHER is not set
X # CONFIG_X25_ASY is not set
diff -u --recursive --new-file v2.3.9/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h
--- v2.3.9/linux/arch/i386/kernel/irq.h	Tue Jun 22 14:43:14 1999
+++ linux/arch/i386/kernel/irq.h	Wed Jul  7 09:22:14 1999
@@ -238,7 +238,7 @@
X  */
X static inline void x86_do_profile (unsigned long eip)
X {
-	if (prof_buffer && current->pid) {
+	if (prof_buffer) {
X 		eip -= (unsigned long) &_stext;
X 		eip >>= prof_shift;
X 		/*
diff -u --recursive --new-file v2.3.9/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- v2.3.9/linux/arch/i386/kernel/process.c	Fri Apr 30 08:13:37 1999
+++ linux/arch/i386/kernel/process.c	Mon Jul  5 20:35:17 1999
@@ -26,9 +26,7 @@
X #include <linux/a.out.h>
X #include <linux/interrupt.h>
X #include <linux/config.h>
-#include <linux/unistd.h>
X #include <linux/delay.h>
-#include <linux/smp.h>
X #include <linux/reboot.h>
X #include <linux/init.h>
X #if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
diff -u --recursive --new-file v2.3.9/linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c
--- v2.3.9/linux/arch/i386/kernel/ptrace.c	Mon Jun  7 11:15:33 1999
+++ linux/arch/i386/kernel/ptrace.c	Sun Jul  4 13:41:08 1999
@@ -67,205 +67,6 @@
X 	return 0;
X }
X 
-/*
- * This routine gets a long from any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- */
-static unsigned long get_long(struct task_struct * tsk, 
-	struct vm_area_struct * vma, unsigned long addr)
-{
-	pgd_t * pgdir;
-	pmd_t * pgmiddle;
-	pte_t * pgtable;
-	unsigned long page;
-
-repeat:
-/* this is a hack for non-kernel-mapped video buffers and similar */
-	if (MAP_NR(page) >= max_mapnr)
-		return 0;
-	page += addr & ~PAGE_MASK;
-	return *(unsigned long *) page;
-}
-
-/*
- * This routine puts a long into any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- *
- * Now keeps R/W state of page so that a text page stays readonly
- * even if a debugger scribbles breakpoints into it.  -M.U-
- */
-static void put_long(struct task_struct * tsk, struct vm_area_struct * vma, unsigned long addr,
-	unsigned long data)
-{
-	}
-	pgtable = pte_offset(pgmiddle, addr);
-	if (!pte_present(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
-	}
-	page = pte_page(*pgtable);
-	if (!pte_write(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
-	}
-/* this is a hack for non-kernel-mapped video buffers and similar */
-	if (MAP_NR(page) < max_mapnr)
-		*(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
-/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
-/* this should also re-instate whatever read-only mode there was before */
-	set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-	flush_tlb();
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls get_long() to read a long.
- */
-static int read_long(struct task_struct * tsk, unsigned long addr,
-	unsigned long * result)
-{
-	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
-	if (!vma)
-		return -EIO;
-	if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
-		unsigned long low,high;
-		struct vm_area_struct * vma_high = vma;
-
-		if (addr + sizeof(long) >= vma->vm_end) {
-			vma_high = vma->vm_next;
-			if (!vma_high || vma_high->vm_start != vma->vm_end)
-				return -EIO;
-		}
-		low = get_long(tsk, vma, addr & ~(sizeof(long)-1));
-		high = get_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1));
-		switch (addr & (sizeof(long)-1)) {
-			case 1:
-				low >>= 8;
-				low |= high << 24;
-				break;
-			case 2:
-				low >>= 16;
-				low |= high << 16;
-				break;
-			case 3:
-				low >>= 24;
-				low |= high << 8;
-				break;
-		}
-		*result = low;
-	} else
-		*result = get_long(tsk, vma, addr);
-	return 0;
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls put_long() to write a long.
- */
-static int write_long(struct task_struct * tsk, unsigned long addr,
-	unsigned long data)
-{
-	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
-	if (!vma)
-		return -EIO;
-	if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
-		unsigned long low,high;
-		struct vm_area_struct * vma_high = vma;
-
-		if (addr + sizeof(long) >= vma->vm_end) {
-			vma_high = vma->vm_next;
-			if (!vma_high || vma_high->vm_start != vma->vm_end)
-				return -EIO;
-		}
-		low = get_long(tsk, vma, addr & ~(sizeof(long)-1));
-		high = get_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1));
-		switch (addr & (sizeof(long)-1)) {
-			case 0: /* shouldn't happen, but safety first */
-				low = data;
-				break;
-			case 1:
-				low &= 0x000000ff;
-				low |= data << 8;
-				high &= ~0xff;
-				high |= data >> 24;
-				break;
-			case 2:
-				low &= 0x0000ffff;
-				low |= data << 16;
-				high &= ~0xffff;
-				high |= data >> 16;
-				break;
-			case 3:
-				low &= 0x00ffffff;
-				low |= data << 24;
-				high &= ~0xffffff;
-				high |= data >> 8;
-				break;
-		}
-		put_long(tsk, vma, addr & ~(sizeof(long)-1),low);
-		put_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1),high);
-	} else
-		put_long(tsk, vma, addr, data);
-	return 0;
-}
-
X static int putreg(struct task_struct *child,
X 	unsigned long regno, unsigned long value)
X {
@@ -402,12 +203,13 @@
X 		case PTRACE_PEEKTEXT: /* read word at location addr. */ 
X 		case PTRACE_PEEKDATA: {
X 			unsigned long tmp;
+			int copied;
X 
-			down(&child->mm->mmap_sem);
-			ret = read_long(child, addr, &tmp);
-			up(&child->mm->mmap_sem);
-			if (ret >= 0)
-				ret = put_user(tmp,(unsigned long *) data);
+			copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+			ret = -EIO;
+			if (copied != sizeof(tmp))
+				goto out;
+			ret = put_user(tmp,(unsigned long *) data);
X 			goto out;
X 		}
X 
@@ -436,9 +238,10 @@
X       /* when I and D space are separate, this will have to be fixed. */
X 		case PTRACE_POKETEXT: /* write the word at location addr. */
X 		case PTRACE_POKEDATA:
-			down(&child->mm->mmap_sem);
-			ret = write_long(child,addr,data);
-			up(&child->mm->mmap_sem);
+			ret = 0;
+			if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+				goto out;
+			ret = -EIO;
X 			goto out;
X 
X 		case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
diff -u --recursive --new-file v2.3.9/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.3.9/linux/arch/i386/kernel/setup.c	Tue Jun  8 10:42:46 1999
+++ linux/arch/i386/kernel/setup.c	Mon Jul  5 20:04:47 1999
@@ -11,7 +11,7 @@
X  *      Zoltan Boszormenyi <zbo...@mol.hu> February 1999.
X  * 
X  *  Force Centaur C6 processors to report MTRR capability.
- *      Bart Hartgers <ba...@etpmod.phys.tue.nl>, May 199.
+ *      Bart Hartgers <ba...@etpmod.phys.tue.nl>, May 1999.
X  *
X  *  Intel Mobile Pentium II detection fix. Sean Gilley, June 1999.
X  */
@@ -690,8 +690,8 @@
X 	    NULL, NULL, NULL, NULL }},
X 	{ X86_VENDOR_INTEL,	6,
X 	  { "Pentium Pro A-step", "Pentium Pro", NULL, "Pentium II (Klamath)", 
-            NULL, "Pentium II (Deschutes)", "Mobile Pentium II", NULL,
-	    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }},
+	    NULL, "Pentium II (Deschutes)", "Mobile Pentium II", "Pentium III (Katmai)",
+	    "Pentium III (Coppermine)", NULL, NULL, NULL, NULL, NULL, NULL }},
X 	{ X86_VENDOR_AMD,	4,
X 	  { NULL, NULL, NULL, "486 DX/2", NULL, NULL, NULL, "486 DX/2-WB",
X 	    "486 DX/4", "486 DX/4-WB", NULL, NULL, NULL, NULL, "Am5x86-WT",
@@ -799,16 +799,15 @@
X 			/* Names for the Pentium II Celeron processors 
X                            detectable only by also checking the cache size */
X 			if ((cpu_models[i].vendor == X86_VENDOR_INTEL)
-			    && (cpu_models[i].x86 == 6)){ 
-				if(c->x86_model == 6 && c->x86_cache_size == 128) {
+			    && (cpu_models[i].x86 == 6))
+			{
+			 	if(c->x86_model == 5 &&  c->x86_cache_size == 0)
+					p = "Celeron (Covington)";						
+				else if(c->x86_model == 6 && c->x86_cache_size == 128)
X                             		p = "Celeron (Mendocino)"; 
-                          	}
-			  	else { 
-                            	if (c->x86_model == 5 && c->x86_cache_size == 0) {
-				  	p = "Celeron (Covington)";
-			    	}
-                        }
-                    }
+ 			  	else if(c->x86_model == 5 && c->x86_cache_size == 256)
+					p = "Celeron (Dixon)";
+			}
X 		}
X 			
X 	}
diff -u --recursive --new-file v2.3.9/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.3.9/linux/arch/i386/kernel/smp.c	Wed Jun 16 19:26:27 1999
+++ linux/arch/i386/kernel/smp.c	Thu Jul  1 15:09:00 1999
@@ -1792,7 +1792,7 @@
X 		update_one_process(p, 1, user, system, cpu);
X 		if (p->pid) {
X 			p->counter -= 1;
-			if (p->counter < 0) {
+			if (p->counter <= 0) {
X 				p->counter = 0;
X 				p->need_resched = 1;
X 			}
diff -u --recursive --new-file v2.3.9/linux/arch/i386/math-emu/fpu_emu.h linux/arch/i386/math-emu/fpu_emu.h
--- v2.3.9/linux/arch/i386/math-emu/fpu_emu.h	Sun Sep 13 12:58:05 1998
+++ linux/arch/i386/math-emu/fpu_emu.h	Mon Jul  5 20:35:17 1999
@@ -165,8 +165,6 @@
X #define signpositive(a) ( (signbyte(a) & 0x80) == 0 )
X #define signnegative(a) (signbyte(a) & 0x80)
X 
-#include "fpu_proto.h"
-
X static inline void reg_copy(FPU_REG const *x, FPU_REG *y)
X {
X   *(short *)&(y->exp) = *(const short *)&(x->exp); 
diff -u --recursive --new-file v2.3.9/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c
--- v2.3.9/linux/arch/i386/mm/fault.c	Tue May 11 17:11:34 1999
+++ linux/arch/i386/mm/fault.c	Sat Jul  3 12:04:12 1999
@@ -50,7 +50,8 @@
X 	start &= PAGE_MASK;
X 
X 	for (;;) {
-		handle_mm_fault(current,vma, start, 1);
+		if (handle_mm_fault(current, vma, start, 1) <= 0)
+			goto bad_area;
X 		if (!size)
X 			break;
X 		size--;
@@ -162,8 +163,13 @@
X 	 * make sure we exit gracefully rather than endlessly redo
X 	 * the fault.
X 	 */
-	if (!handle_mm_fault(tsk, vma, address, write))
-		goto do_sigbus;
+	{
+		int fault = handle_mm_fault(tsk, vma, address, write);
+		if (fault < 0)
+			goto out_of_memory;
+		if (!fault)
+			goto do_sigbus;
+	}
X 
X 	/*
X 	 * Did it hit the DOS screen memory VA from vm86 mode?
@@ -255,6 +261,13 @@
X  * We ran out of memory, or some other thing happened to us that made
X  * us unable to handle the page fault gracefully.
X  */
+out_of_memory:
+	up(&mm->mmap_sem);
+	printk("VM: killing process %s\n", tsk->comm);
+	if (error_code & 4)
+		do_exit(SIGKILL);
+	goto no_context;
+
X do_sigbus:
X 	up(&mm->mmap_sem);
X 
diff -u --recursive --new-file v2.3.9/linux/arch/mips/boot/elf2ecoff.c linux/arch/mips/boot/elf2ecoff.c
--- v2.3.9/linux/arch/mips/boot/elf2ecoff.c	Wed Jun 30 13:38:18 1999
+++ linux/arch/mips/boot/elf2ecoff.c	Mon Jul  5 20:35:17 1999
@@ -35,7 +35,6 @@
X 
X #include <stdio.h>
X #include <string.h>
-#include <string.h>
X #include <errno.h>
X #include <sys/types.h>
X #include <fcntl.h>
diff -u --recursive --new-file v2.3.9/linux/arch/mips/config.in linux/arch/mips/config.in
--- v2.3.9/linux/arch/mips/config.in	Wed Jun 30 13:38:18 1999
+++ linux/arch/mips/config.in	Mon Jul  5 19:44:57 1999
@@ -93,7 +93,7 @@
X bool 'Sysctl support' CONFIG_SYSCTL
X 
X if [ "$CONFIG_SGI" != "y" -a "$CONFIG_DECSTATION" != "y" -a "$CONFIG_BAGET_MIPS" != "y" ]; then
-  tristate 'Parallel port support' CONFIG_PARPORT
+source drivers/misc/Config.in
X fi
X endmenu
X 
diff -u --recursive --new-file v2.3.9/linux/arch/mips/defconfig linux/arch/mips/defconfig
--- v2.3.9/linux/arch/mips/defconfig	Wed Jun 30 13:38:18 1999
+++ linux/arch/mips/defconfig	Mon Jul  5 19:44:57 1999
@@ -63,11 +63,6 @@
X # CONFIG_I2O_PROC is not set
X 
X #
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
X # Block devices
X #
X CONFIG_BLK_DEV_FD=m
diff -u --recursive --new-file v2.3.9/linux/arch/mips/kernel/irixioctl.c linux/arch/mips/kernel/irixioctl.c
--- v2.3.9/linux/arch/mips/kernel/irixioctl.c	Wed Jun 30 13:38:18 1999
+++ linux/arch/mips/kernel/irixioctl.c	Tue Jul  6 10:11:40 1999
@@ -29,20 +29,21 @@
X 				unsigned long arg);
X extern asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count);
X extern void start_tty(struct tty_struct *tty);
-
X static struct tty_struct *get_tty(int fd)
X {
X 	struct file *filp;
+	struct tty_struct *ttyp = NULL;
X 
-	if(!(filp = fcheck(fd)))
-		return ((struct tty_struct *) 0);
-	if(filp->private_data) {
-		struct tty_struct *ttyp = (struct tty_struct *) filp->private_data;
+	read_lock(¤t->files->file_lock);
+	filp = fcheck(fd);
+	if(filp && filp->private_data) {
+		ttyp = (struct tty_struct *) filp->private_data;
X 
-		if(ttyp->magic == TTY_MAGIC)
-			return ttyp;
+		if(ttyp->magic != TTY_MAGIC)
+			ttyp =NULL;
X 	}
-	return ((struct tty_struct *) 0);
+	read_unlock(¤t->files->file_lock);
+	return ttyp;
X }
X 
X static struct tty_struct *get_real_tty(struct tty_struct *tp)
diff -u --recursive --new-file v2.3.9/linux/arch/mips/kernel/ptrace.c linux/arch/mips/kernel/ptrace.c
--- v2.3.9/linux/arch/mips/kernel/ptrace.c	Wed Jun 30 13:38:18 1999
+++ linux/arch/mips/kernel/ptrace.c	Mon Jul  5 19:44:57 1999
@@ -25,218 +25,6 @@
X #include <asm/system.h>
X #include <asm/uaccess.h>
X 
-/*
- * This routine gets a long from any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- */
-static unsigned long get_long(struct task_struct * tsk,
-			      struct vm_area_struct * vma, unsigned long addr)
-{
-	pgd_t *pgdir;
-	pmd_t *pgmiddle;
-	pte_t *pgtable;
-	unsigned long page, retval;
-
-repeat:
-	/* This is a hack for non-kernel-mapped video buffers and similar */
-	if (MAP_NR(page) >= MAP_NR(high_memory))
-		return 0;
-	page += addr & ~PAGE_MASK;
-	/* We can't use flush_page_to_ram() since we're running in
-	 * another context ...
-	 */
-	flush_cache_all();
-	retval = *(unsigned long *) page;
-	flush_cache_all();	/* VCED avoidance  */
-	return retval;
-}
-
-/*
- * This routine puts a long into any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- *
- * Now keeps R/W state of page so that a text page stays readonly
- * even if a debugger scribbles breakpoints into it.  -M.U-
- */
-static void put_long(struct task_struct *tsk,
-		     struct vm_area_struct * vma, unsigned long addr,
-	unsigned long data)
-{
-	}
-	pgtable = pte_offset(pgmiddle, addr);
-	if (!pte_present(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
-	}
-	page = pte_page(*pgtable);
-	if (!pte_write(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
-	}
-	/* This is a hack for non-kernel-mapped video buffers and similar */
-	if (MAP_NR(page) < MAP_NR(high_memory))
-		flush_cache_all();
-	*(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
-	if (MAP_NR(page) < MAP_NR(high_memory))
-		flush_cache_all();
-	/*
-	 * We're bypassing pagetables, so we have to set the dirty bit
-	 * ourselves this should also re-instate whatever read-only mode
-	 * there was before
-	 */
-	set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-	flush_tlb_page(vma, addr);
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls get_long() to read a long.
- */
-static int read_long(struct task_struct * tsk, unsigned long addr,
-	unsigned long * result)
-{
-	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
-	if (!vma)
-		return -EIO;
-	if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
-		unsigned long low,high;
-		struct vm_area_struct * vma_high = vma;
-
-		if (addr + sizeof(long) >= vma->vm_end) {
-			vma_high = vma->vm_next;
-			if (!vma_high || vma_high->vm_start != vma->vm_end)
-				return -EIO;
-		}
-		low = get_long(tsk, vma, addr & ~(sizeof(long)-1));
-		high = get_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1));
-		switch (addr & (sizeof(long)-1)) {
-			case 1:
-				low >>= 8;
-				low |= high << 24;
-				break;
-			case 2:
-				low >>= 16;
-				low |= high << 16;
-				break;
-			case 3:
-				low >>= 24;
-				low |= high << 8;
-				break;
-		}
-		*result = low;
-	} else
-		*result = get_long(tsk, vma, addr);
-	return 0;
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls put_long() to write a long.
- */
-static int write_long(struct task_struct * tsk, unsigned long addr,
-	unsigned long data)
-{
-	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
-	if (!vma)
-		return -EIO;
-	if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
-		unsigned long low,high;
-		struct vm_area_struct * vma_high = vma;
-
-		if (addr + sizeof(long) >= vma->vm_end) {
-			vma_high = vma->vm_next;
-			if (!vma_high || vma_high->vm_start != vma->vm_end)
-				return -EIO;
-		}
-		low = get_long(tsk, vma, addr & ~(sizeof(long)-1));
-		high = get_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1));
-		switch (addr & (sizeof(long)-1)) {
-			case 0: /* shouldn't happen, but safety first */
-				low = data;
-				break;
-			case 1:
-				low &= 0x000000ff;
-				low |= data << 8;
-				high &= ~0xff;
-				high |= data >> 24;
-				break;
-			case 2:
-				low &= 0x0000ffff;
-				low |= data << 16;
-				high &= ~0xffff;
-				high |= data >> 16;
-				break;
-			case 3:
-				low &= 0x00ffffff;
-				low |= data << 24;
-				high &= ~0xffffff;
-				high |= data >> 8;
-				break;
-		}
-		put_long(tsk, vma, addr & ~(sizeof(long)-1),low);
-		put_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1),high);
-	} else
-		put_long(tsk, vma, addr, data);
-	return 0;
-}
-
X asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
X {
X 	struct task_struct *child;
@@ -322,15 +110,16 @@
X 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
X 	case PTRACE_PEEKDATA: {
X 		unsigned long tmp;
+		int copied;
X 
-		down(&child->mm->mmap_sem);
-		res = read_long(child, addr, &tmp);
-		up(&child->mm->mmap_sem);
-		if (res < 0)
+		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+		res = -EIO;
+		if (copied != sizeof(tmp))
X 			goto out;
X 		res = put_user(tmp,(unsigned long *) data);
+
X 		goto out;
-		}
+	}
X 
X 	/* Read the word at location addr in the USER area.  */
X 	case PTRACE_PEEKUSR: {
@@ -394,9 +183,11 @@
X 
X 	case PTRACE_POKETEXT: /* write the word at location addr. */
X 	case PTRACE_POKEDATA:
-		down(&child->mm->mmap_sem);
-		res = write_long(child,addr,data);
-		up(&child->mm->mmap_sem);
+		res = 0;
+		if (access_process_vm(child, addr, &data, sizeof(data), 1)
+		    == sizeof(data))
+			goto out;
+		res = -EIO;
X 		goto out;
X 
X 	case PTRACE_POKEUSR: {
diff -u --recursive --new-file v2.3.9/linux/arch/mips/kernel/r4k_misc.S linux/arch/mips/kernel/r4k_misc.S
--- v2.3.9/linux/arch/mips/kernel/r4k_misc.S	Wed Jun 30 13:38:18 1999
+++ linux/arch/mips/kernel/r4k_misc.S	Mon Jul  5 20:35:17 1999
@@ -13,7 +13,6 @@
X #include <asm/offset.h>
X #include <asm/bootinfo.h>
X #include <asm/cachectl.h>
-#include <asm/current.h>
X #include <asm/fpregdef.h>
X #include <asm/mipsconfig.h>
X #include <asm/mipsregs.h>
diff -u --recursive --new-file v2.3.9/linux/arch/mips/kernel/setup.c linux/arch/mips/kernel/setup.c
--- v2.3.9/linux/arch/mips/kernel/setup.c	Wed Jun 30 13:38:18 1999
+++ linux/arch/mips/kernel/setup.c	Mon Jul  5 20:35:17 1999
@@ -30,7 +30,6 @@
X #endif
X #include <linux/ide.h>
X #ifdef CONFIG_RTC
-#include <linux/ioport.h>
X #include <linux/timex.h>
X #endif
X 
diff -u --recursive --new-file v2.3.9/linux/arch/mips/mm/fault.c linux/arch/mips/mm/fault.c
--- v2.3.9/linux/arch/mips/mm/fault.c	Wed Jun 30 13:38:19 1999
+++ linux/arch/mips/mm/fault.c	Mon Jul  5 19:44:57 1999
@@ -43,7 +43,7 @@
X  * and the problem, and then passes it off to one of the appropriate
X  * routines.
X  */
-asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
X 			      unsigned long address)
X {
X 	struct vm_area_struct * vma;
@@ -59,7 +59,7 @@
X 		goto no_context;
X #if 0
X 	printk("[%s:%d:%08lx:%ld:%08lx]\n", current->comm, current->pid,
-	       address, writeaccess, regs->cp0_epc);
+	       address, write, regs->cp0_epc);
X #endif
X 	down(&mm->mmap_sem);
X 	vma = find_vma(mm, address);
@@ -76,14 +76,26 @@
X  * we can handle it..
X  */
X good_area:
-	if (writeaccess) {
+	if (write) {
X 		if (!(vma->vm_flags & VM_WRITE))
X 			goto bad_area;
X 	} else {
X 		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
X 			goto bad_area;
X 	}
-	handle_mm_fault(tsk, vma, address, writeaccess);
+
+	/*
+	 * If for any reason at all we couldn't handle the fault,
+	 * make sure we exit gracefully rather than endlessly redo
+	 * the fault.
+	 */
+	{
+		int fault = handle_mm_fault(tsk, vma, address, write);
+		if (fault < 0)
+			goto out_of_memory;
+		if (!fault)
+			goto do_sigbus;
+	}
X 	up(&mm->mmap_sem);
X 	return;
X 
@@ -96,12 +108,12 @@
X 
X 	if (user_mode(regs)) {
X 		tsk->tss.cp0_badvaddr = address;
-		tsk->tss.error_code = writeaccess;
+		tsk->tss.error_code = write;
X #if 0
X 		printk("do_page_fault() #2: sending SIGSEGV to %s for illegal %s\n"
X 		       "%08lx (epc == %08lx, ra == %08lx)\n",
X 		       tsk->comm,
-		       writeaccess ? "writeaccess to" : "readaccess from",
+		       write ? "write access to" : "read access from",
X 		       address,
X 		       (unsigned long) regs->cp0_epc,
X 		       (unsigned long) regs->regs[31]);
@@ -132,6 +144,31 @@
X 	printk(KERN_ALERT "Unable to handle kernel paging request at virtual "
X 	       "address %08lx, epc == %08lx, ra == %08lx\n",
X 	       address, regs->cp0_epc, regs->regs[31]);
-	die("Oops", regs, writeaccess);
+	die("Oops", regs, write);
X 	do_exit(SIGKILL);
+
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+out_of_memory:
+	up(&mm->mmap_sem);
+	printk("VM: killing process %s\n", tsk->comm);
+	if (user_mode(regs))
+		do_exit(SIGKILL);
+	goto no_context;
+
+do_sigbus:
+	up(&mm->mmap_sem);
+
+	/*
+	 * Send a sigbus, regardless of whether we were in kernel
+	 * or user mode.
+	 * XXX Store details about fault for siginfo handling into tss.
+	 */
+	force_sig(SIGBUS, tsk);
+
+	/* Kernel mode? Handle exceptions or die */
+	if (!user_mode(regs))
+		goto no_context;
X }
diff -u --recursive --new-file v2.3.9/linux/arch/mips/sgi/kernel/indy_sc.c linux/arch/mips/sgi/kernel/indy_sc.c
--- v2.3.9/linux/arch/mips/sgi/kernel/indy_sc.c	Wed Jun 30 13:38:19 1999
+++ linux/arch/mips/sgi/kernel/indy_sc.c	Thu Jul  1 10:45:57 1999
@@ -9,7 +9,6 @@
X #include <linux/kernel.h>
X #include <linux/sched.h>
X #include <linux/mm.h>
-#include <linux/autoconf.h>
X 
X #include <asm/bcache.h>
X #include <asm/sgi.h>
diff -u --recursive --new-file v2.3.9/linux/arch/ppc/amiga/amiints.c linux/arch/ppc/amiga/amiints.c
--- v2.3.9/linux/arch/ppc/amiga/amiints.c	Thu Jan  7 08:46:58 1999
+++ linux/arch/ppc/amiga/amiints.c	Mon Jul  5 20:07:02 1999
@@ -108,7 +108,7 @@
X 	custom.intreq = 0x7fff;
X 
X #ifdef CONFIG_APUS
-	/* Clear any inter-CPU interupt requests. Circumvents bug in
+	/* Clear any inter-CPU interrupt requests. Circumvents bug in
X            Blizzard IPL emulation HW (or so it appears). */
X 	APUS_WRITE(APUS_INT_LVL, INTLVL_SETRESET | INTLVL_MASK);
X 
diff -u --recursive --new-file v2.3.9/linux/arch/ppc/amiga/config.c linux/arch/ppc/amiga/config.c
--- v2.3.9/linux/arch/ppc/amiga/config.c	Mon Dec 21 08:37:20 1998
+++ linux/arch/ppc/amiga/config.c	Mon Jul  5 20:35:17 1999
@@ -30,7 +30,6 @@
X #include <linux/kd.h>
X #include <linux/tty.h>
X #include <linux/console.h>
-#include <linux/init.h>
X 
X #include <asm/bootinfo.h>
X #include <asm/setup.h>
diff -u --recursive --new-file v2.3.9/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- v2.3.9/linux/arch/ppc/config.in	Wed Jun 30 13:38:19 1999
+++ linux/arch/ppc/config.in	Thu Jul  1 14:22:56 1999
@@ -66,13 +66,7 @@
X define_bool CONFIG_KERNEL_ELF y
X tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
X 
-tristate 'Parallel port support' CONFIG_PARPORT
-if [ "$CONFIG_PARPORT" != "n" ]; then
-  dep_tristate '   PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
-  if [ "$CONFIG_PARPORT_PC" != "n" ]; then
-    bool '   Support foreign hardware' CONFIG_PARPORT_OTHER
-  fi
-fi
+source drivers/misc/Config.in
X 
X bool 'Support for VGA Console' CONFIG_VGA_CONSOLE
X bool 'Support for frame buffer devices' CONFIG_FB
diff -u --recursive --new-file v2.3.9/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c
--- v2.3.9/linux/arch/ppc/kernel/irq.c	Wed Jun 30 13:38:19 1999
+++ linux/arch/ppc/kernel/irq.c	Mon Jul  5 20:35:17 1999
@@ -50,7 +50,6 @@
X #include <asm/io.h>
X #include <asm/pgtable.h>
X #include <asm/irq.h>
-#include <asm/bitops.h>
X #include <asm/gg2.h>
X #include <asm/cache.h>
X #include <asm/prom.h>
diff -u --recursive --new-file v2.3.9/linux/arch/ppc/kernel/pci.c linux/arch/ppc/kernel/pci.c
--- v2.3.9/linux/arch/ppc/kernel/pci.c	Thu Apr 29 12:39:01 1999
+++ linux/arch/ppc/kernel/pci.c	Mon Jul  5 20:35:17 1999
@@ -9,7 +9,6 @@
X #include <linux/string.h>
X #include <linux/init.h>
X #include <linux/config.h>
-#include <linux/pci.h>
X #include <linux/openpic.h>
X 
X #include <asm/processor.h>
diff -u --recursive --new-file v2.3.9/linux/arch/ppc/kernel/ppc-stub.c linux/arch/ppc/kernel/ppc-stub.c
--- v2.3.9/linux/arch/ppc/kernel/ppc-stub.c	Tue Aug  4 16:06:36 1998
+++ linux/arch/ppc/kernel/ppc-stub.c	Mon Jul  5 20:35:17 1999
@@ -107,7 +107,6 @@
X 
X #include <asm/system.h>
X #include <asm/signal.h>
-#include <asm/system.h>
X #include <asm/kgdb.h>
X #include <asm/pgtable.h>
X #include <asm/ptrace.h>
diff -u --recursive --new-file v2.3.9/linux/arch/ppc/kernel/prep_setup.c linux/arch/ppc/kernel/prep_setup.c
--- v2.3.9/linux/arch/ppc/kernel/prep_setup.c	Wed Jun 30 13:38:19 1999
+++ linux/arch/ppc/kernel/prep_setup.c	Mon Jul  5 20:35:17 1999
@@ -40,7 +40,6 @@
X #include <asm/residual.h>
X #include <asm/io.h>
X #include <asm/pgtable.h>
-#include <linux/ide.h>
X #include <asm/ide.h>
X #include <asm/cache.h>
X #include <asm/dma.h>
diff -u --recursive --new-file v2.3.9/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- v2.3.9/linux/arch/ppc/kernel/process.c	Wed Jun 30 13:38:19 1999
+++ linux/arch/ppc/kernel/process.c	Thu Jul  1 10:45:57 1999
@@ -31,7 +31,6 @@
X #include <linux/malloc.h>
X #include <linux/user.h>
X #include <linux/elf.h>
-#include <linux/elf.h>
X #include <linux/init.h>
X 
X #include <asm/pgtable.h>
diff -u --recursive --new-file v2.3.9/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
--- v2.3.9/linux/arch/ppc/kernel/setup.c	Wed Jun 30 13:38:19 1999
+++ linux/arch/ppc/kernel/setup.c	Mon Jul  5 20:35:17 1999
@@ -32,7 +32,6 @@
X #endif
X #include <asm/bootx.h>
X #include <asm/machdep.h>
-#include <asm/ide.h>
X 
X extern void pmac_init(unsigned long r3,
X                       unsigned long r4,
diff -u --recursive --new-file v2.3.9/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
--- v2.3.9/linux/arch/ppc/kernel/smp.c	Wed Jun 30 13:38:19 1999
+++ linux/arch/ppc/kernel/smp.c	Thu Jul  1 15:09:00 1999
@@ -85,7 +85,7 @@
X 			update_one_process(p, 1, user, system, cpu);
X 
X 			p->counter -= 1;
-			if (p->counter < 0) {
+			if (p->counter <= 0) {
X 				p->counter = 0;
X 				current->need_resched = 1;
X 			}
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/ap1000/aplib.c linux/arch/sparc/ap1000/aplib.c
--- v2.3.9/linux/arch/sparc/ap1000/aplib.c	Tue Aug  4 16:03:34 1998
+++ linux/arch/sparc/ap1000/aplib.c	Mon Jul  5 20:35:17 1999
@@ -27,7 +27,6 @@
X #include <asm/segment.h>
X #include <asm/io.h>
X #include <asm/pgtable.h>
-#include <asm/segment.h>
X #include <asm/uaccess.h>
X 
X  #include <asm/ap1000/pgtapmmu.h>
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/kernel/pcic.c linux/arch/sparc/kernel/pcic.c
--- v2.3.9/linux/arch/sparc/kernel/pcic.c	Wed Jun  9 14:44:25 1999
+++ linux/arch/sparc/kernel/pcic.c	Mon Jul  5 20:35:17 1999
@@ -20,7 +20,6 @@
X #include <asm/ebus.h>
X #include <asm/sbus.h> /* for sanity check... */
X #include <asm/swift.h> /* for cache flushing. */
-
X #include <asm/io.h>
X 
X #undef PROM_DEBUG
@@ -39,7 +38,6 @@
X #include <linux/timex.h>
X #include <linux/interrupt.h>
X 
-#include <asm/io.h>
X #include <asm/irq.h>
X #include <asm/oplib.h>
X #include <asm/pcic.h>
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c
--- v2.3.9/linux/arch/sparc/kernel/process.c	Tue May 11 08:24:31 1999
+++ linux/arch/sparc/kernel/process.c	Mon Jul  5 20:35:17 1999
@@ -37,7 +37,6 @@
X #include <asm/delay.h>
X #include <asm/processor.h>
X #include <asm/psr.h>
-#include <asm/system.h>
X #include <asm/elf.h>
X 
X extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/kernel/ptrace.c linux/arch/sparc/kernel/ptrace.c
--- v2.3.9/linux/arch/sparc/kernel/ptrace.c	Mon Jun  7 11:15:33 1999
+++ linux/arch/sparc/kernel/ptrace.c	Mon Jul  5 11:30:11 1999
@@ -24,202 +24,6 @@
X 
X #define MAGIC_CONSTANT 0x80000000
X 
-/*
- * This routine gets a long from any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- */
-static unsigned long get_long(struct task_struct * tsk,
-	struct vm_area_struct * vma, unsigned long addr)
-{
-	pgd_t * pgdir;
-	pmd_t * pgmiddle;
-	pte_t * pgtable;
-	unsigned long page, retval;
-
-repeat:
-/* this is a hack for non-kernel-mapped video buffers and similar */
-	if (MAP_NR(page) >= max_mapnr)
-		return 0;
-	page += addr & ~PAGE_MASK;
-	retval = *(unsigned long *) page;
-	flush_page_to_ram(page);
-	return retval;
-}
-
-/*
- * This routine puts a long into any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- *
- * Now keeps R/W state of page so that a text page stays readonly
- * even if a debugger scribbles breakpoints into it.  -M.U-
- */
-static void put_long(struct task_struct * tsk, struct vm_area_struct * vma,
-	unsigned long addr, unsigned long data)
-{
-	}
-	pgtable = pte_offset(pgmiddle, addr);
-	if (!pte_present(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
-	}
-	page = pte_page(*pgtable);
-	if (!pte_write(*pgtable)) {
-		handle_mm_fault(tsk, vma, addr, 1);
-		goto repeat;
-	}
-/* this is a hack for non-kernel-mapped video buffers and similar */
-	flush_cache_page(vma, addr);
-	if (MAP_NR(page) < max_mapnr) {
-		*(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
-		flush_page_to_ram(page);
-	}
-/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
-/* this should also re-instate whatever read-only mode there was before */
-	set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-	flush_tlb_page(vma, addr);
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls get_long() to read a long.
- */
-static int read_long(struct task_struct * tsk, unsigned long addr,
-		     unsigned long * result)
-{
-	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
-	if (!vma)
-		return -EIO;
-	*result = get_long(tsk, vma, addr);
-	return 0;
-}
-
-static int read_byte(struct task_struct *tsk, unsigned long addr,
-		     unsigned char *result)
-{
-	struct vm_area_struct *vma = find_extend_vma(tsk, addr&~3);
-	unsigned long tmp;
-
-	if(!vma)
-		return -EIO;
-	tmp = get_long(tsk, vma, (addr & ~3));
-	switch(addr & 3) {
-	case 0:
-		*result = (tmp & 0xff000000)>>24;
-		break;
-	case 1:
-		*result = (tmp & 0x00ff0000)>>16;
-		break;
-	case 2:
-		*result = (tmp & 0x0000ff00)>>8;
-		break;
-	case 3:
-		*result = (tmp & 0x000000ff);
-		break;
-	}
-	return 0;
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls put_long() to write a long.
- */
-static int write_long(struct task_struct * tsk, unsigned long addr,
-		      unsigned long data)
-{
-	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
-	if (!vma)
-		return -EIO;
-	put_long(tsk, vma, addr, data);
-	return 0;
-}
-
-static int write_byte(struct task_struct * tsk, unsigned long addr,
-		      unsigned char data)
-{
-	struct vm_area_struct * vma = find_extend_vma(tsk, (addr & ~3));
-	unsigned long tmp;
-
-	if (!vma)
-		return -EIO;
-	tmp = get_long(tsk, vma, (addr & ~3));
-	switch(addr & 3) {
-	case 0:
-		tmp &= 0x00ffffff;
-		tmp |= (data << 24);
-		break;
-	case 1:
-		tmp &= 0xff00ffff;
-		tmp |= ((data << 16) & 0x00ff0000);
-		break;
-	case 2:
-		tmp &= 0xffff00ff;
-		tmp |= ((data << 8) & 0x0000ff00);
-		break;
-	case 3:
-		tmp &= 0xffffff00;
-		tmp |= (data & 0x000000ff);
-		break;
-	}
-	put_long(tsk, vma, (addr & ~3), tmp);
-	return 0;
-}
X 
X /* Returning from ptrace is a bit tricky because the syscall return
X  * low level code assumes any value returned which is negative and
@@ -565,24 +369,12 @@
X 	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
X 	case PTRACE_PEEKDATA: {
X 		unsigned long tmp;
-		int res;
-
-		/* XXX Find out what is really going on. */
-		flush_cache_all();
X 
-		/* Non-word alignment _not_ allowed on Sparc. */
-		if(addr & (sizeof(unsigned long) - 1)) {
-			pt_error_return(regs, EINVAL);
-			goto out;
-		}
-		down(&child->mm->mmap_sem);
-		res = read_long(child, addr, &tmp);
-		up(&child->mm->mmap_sem);
-		if (res < 0) {
-			pt_error_return(regs, -res);
-			goto out;
-		}
-		pt_os_succ_return(regs, tmp, (long *) data);
+		if (access_process_vm(child, addr,
+				      &tmp, sizeof(tmp), 0) == sizeof(tmp))
+			pt_os_succ_return(regs, tmp, (long *)data);
+		else
+			pt_error_return(regs, EIO);
X 		goto out;
X 	}
X 
@@ -596,22 +388,11 @@
X 
X 	case PTRACE_POKETEXT: /* write the word at location addr. */
X 	case PTRACE_POKEDATA: {
-		struct vm_area_struct *vma;
-		int res;
-
-		/* Non-word alignment _not_ allowed on Sparc. */
-		if(addr & (sizeof(unsigned long) - 1)) {
-			pt_error_return(regs, EINVAL);
-			goto out;
-		}
-		down(&child->mm->mmap_sem);
- vma = find_extend_vma(child, addr);
-		res = write_long(child, addr, data);
-		up(&child->mm->mmap_sem);
-		if(res < 0)
-			pt_error_return(regs, -res);
+		if (access_process_vm(child, addr,
+				      &data, sizeof(data), 1) == sizeof(data))
+			pt_succ_return(regs, 0);
X 		else
-			pt_succ_return(regs, res);
+			pt_error_return(regs, EIO);
X 		goto out;
X 	}
X 
@@ -737,56 +518,31 @@
X 
X 	case PTRACE_READTEXT:
X 	case PTRACE_READDATA: {
-		unsigned char *dest = (unsigned char *) addr2;
-		unsigned long src = addr;
-		unsigned char tmp;
-		int res, len = data;
-
-		res = verify_area(VERIFY_WRITE, dest, len);
-		if(res) {
-			pt_error_return(regs, -res);
-			goto out;
-		}
-		while(len) {
-			down(&child->mm->mmap_sem);
-			res = read_byte(child, src, &tmp);
-			up(&child->mm->mmap_sem);
-			if(res < 0) {
-				pt_error_return(regs, -res);
-				goto out;
-			}
-			__put_user(tmp, dest);
-			src++; dest++; len--;
+		int res = ptrace_readdata(child, addr, (void *) addr2, data);
+
+		if (res == data) {
+			pt_succ_return(regs, 0);
+			goto out;
X 		}
-		pt_succ_return(regs, 0);
+		/* Partial read is an IO failure */
+		if (res >= 0)
+			res = -EIO;
+		pt_error_return(regs, -res);
X goto out;
X 	}
X 
X 	case PTRACE_WRITETEXT:
X 	case PTRACE_WRITEDATA: {
-		unsigned char *src = (unsigned char *) addr2;
-		unsigned long dest = addr;
-		int res, len = data;
-
-		res = verify_area(VERIFY_READ, src, len);
-		if(res) {
-			pt_error_return(regs, -res);
-			goto out;
-		}
-		while(len) {
-			unsigned long tmp;
-
-			__get_user(tmp, src);
-			down(&child->mm->mmap_sem);
-			res = write_byte(child, dest, tmp);
-			up(&child->mm->mmap_sem);
-			if(res < 0) {
-				pt_error_return(regs, -res);
-				goto out;
-			}
-			src++; dest++; len--;
+		int res = ptrace_writedata(child, (void *) addr2, addr, data);
+
+		if (res == data) {
+			pt_succ_return(regs, 0);
+			goto out;
X 		}
-		pt_succ_return(regs, 0);
+		/* Partial write is an IO failure */
+		if (res >= 0)
+			res = -EIO;
+		pt_error_return(regs, -res);
X 		goto out;
X 	}
X 
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/kernel/sparc-stub.c linux/arch/sparc/kernel/sparc-stub.c
--- v2.3.9/linux/arch/sparc/kernel/sparc-stub.c	Tue Apr 14 17:44:19 1998
+++ linux/arch/sparc/kernel/sparc-stub.c	Mon Jul  5 20:35:17 1999
@@ -105,7 +105,6 @@
X #include <asm/oplib.h>
X #include <asm/head.h>
X #include <asm/traps.h>
-#include <asm/system.h>
X #include <asm/vac-ops.h>
X #include <asm/kgdb.h>
X #include <asm/pgtable.h>
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/kernel/sparc_ksyms.c linux/arch/sparc/kernel/sparc_ksyms.c
--- v2.3.9/linux/arch/sparc/kernel/sparc_ksyms.c	Sun Mar 21 07:23:38 1999
+++ linux/arch/sparc/kernel/sparc_ksyms.c	Mon Jul  5 20:35:17 1999
@@ -40,7 +40,6 @@
X #include <asm/dma.h>
X #endif
X #include <asm/a.out.h>
-#include <asm/spinlock.h>
X #include <asm/io-unit.h>
X 
X struct poll {
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/kernel/sun4d_smp.c linux/arch/sparc/kernel/sun4d_smp.c
--- v2.3.9/linux/arch/sparc/kernel/sun4d_smp.c	Tue May 11 08:24:31 1999
+++ linux/arch/sparc/kernel/sun4d_smp.c	Thu Jul  1 15:09:00 1999
@@ -473,7 +473,7 @@
X 		if(current->pid) {
X 			update_one_process(current, 1, user, !user, cpu);
X 
-			if(--current->counter < 0) {
+			if(--current->counter <= 0) {
X 				current->counter = 0;
X 				current->need_resched = 1;
X 			}
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/kernel/sun4m_smp.c linux/arch/sparc/kernel/sun4m_smp.c
--- v2.3.9/linux/arch/sparc/kernel/sun4m_smp.c	Tue May 11 08:24:31 1999
+++ linux/arch/sparc/kernel/sun4m_smp.c	Thu Jul  1 15:09:01 1999
@@ -454,7 +454,7 @@
X 		if(current->pid) {
X 			update_one_process(current, 1, user, !user, cpu);
X 
-			if(--current->counter < 0) {
+			if(--current->counter <= 0) {
X 				current->counter = 0;
X 				current->need_resched = 1;
X 			}
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/kernel/sunos_ioctl.c linux/arch/sparc/kernel/sunos_ioctl.c
--- v2.3.9/linux/arch/sparc/kernel/sunos_ioctl.c	Tue Oct 27 09:52:20 1998
+++ linux/arch/sparc/kernel/sunos_ioctl.c	Tue Jul  6 10:11:40 1999
@@ -36,11 +36,10 @@
X 
X asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
X {
-	struct file *filp;
X 	int ret = -EBADF;
X 
X 	lock_kernel();
-	if (fd >= SUNOS_NR_OPEN || !(filp = current->files->fd [fd]))
+	if (fd >= SUNOS_NR_OPEN || !fcheck(fd))
X 		goto out;
X 
X 	/* First handle an easy compat. case for tty ldisc. */
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c
--- v2.3.9/linux/arch/sparc/kernel/sys_sunos.c	Wed Jun 30 13:38:19 1999
+++ linux/arch/sparc/kernel/sys_sunos.c	Mon Jul  5 20:35:17 1999
@@ -26,7 +26,6 @@
X #include <linux/signal.h>
X #include <linux/uio.h>
X #include <linux/utsname.h>
-#include <linux/fs.h>
X #include <linux/major.h>
X #include <linux/stat.h>
X #include <linux/malloc.h>
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/mm/asyncd.c linux/arch/sparc/mm/asyncd.c
--- v2.3.9/linux/arch/sparc/mm/asyncd.c	Wed May 12 08:41:12 1999
+++ linux/arch/sparc/mm/asyncd.c	Sun Jul  4 09:53:12 1999
@@ -1,4 +1,4 @@
-/*  $Id: asyncd.c,v 1.13 1999/05/12 11:11:34 davem Exp $
+/*  $Id: asyncd.c,v 1.15 1999/07/04 04:35:50 davem Exp $
X  *  The asyncd kernel daemon. This handles paging on behalf of 
X  *  processes that receive page faults due to remote (async) memory
X  *  accesses. 
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/mm/fault.c linux/arch/sparc/mm/fault.c
--- v2.3.9/linux/arch/sparc/mm/fault.c	Wed Mar 10 16:53:36 1999
+++ linux/arch/sparc/mm/fault.c	Mon Jul  5 20:35:18 1999
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.101 1999/01/04 06:24:52 jj Exp $
+/* $Id: fault.c,v 1.103 1999/07/04 04:35:51 davem Exp $
X  * fault.c:  Page fault handlers for the Sparc.
X  *
X  * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -14,7 +14,6 @@
X #include <linux/mman.h>
X #include <linux/tasks.h>
X #include <linux/kernel.h>
-#include <linux/smp.h>
X #include <linux/signal.h>
X #include <linux/mm.h>
X #include <linux/smp.h>
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/mm/srmmu.c linux/arch/sparc/mm/srmmu.c
--- v2.3.9/linux/arch/sparc/mm/srmmu.c	Wed Apr 28 10:58:10 1999
+++ linux/arch/sparc/mm/srmmu.c	Mon Jul  5 11:44:55 1999
@@ -2076,6 +2076,7 @@
X 			goto done;
X 		inode = file->f_dentry->d_inode;
X 		offset = (address & PAGE_MASK) - vma->vm_start;
+		spin_lock(&inode->i_shared_lock);
X 		vmaring = inode->i_mmap; 
X 		do {
X 			/* Do not mistake ourselves as another mapping. */
@@ -2109,6 +2110,7 @@
X 				}
X 			}
X 		} while ((vmaring = vmaring->vm_next_share) != NULL);
+		spin_unlock(&inode->i_shared_lock);
X 
X 		if(alias_found && ((pte_val(pte) & SRMMU_CACHE) != 0)) {
X 			pgdp = srmmu_pgd_offset(vma->vm_mm, address);
diff -u --recursive --new-file v2.3.9/linux/arch/sparc/mm/sun4c.c linux/arch/sparc/mm/sun4c.c
--- v2.3.9/linux/arch/sparc/mm/sun4c.c	Wed Mar 10 16:53:36 1999
+++ linux/arch/sparc/mm/sun4c.c	Mon Jul  5 11:44:55 1999
@@ -2682,8 +2682,10 @@
X 		inode = dentry->d_inode;
X 	if(inode) {
X 		unsigned long offset = (address & PAGE_MASK) - vma->vm_start;
-		struct vm_area_struct *vmaring = inode->i_mmap; 
+		struct vm_area_struct *vmaring;
X 		int alias_found = 0;
+		spin_lock(&inode->i_shared_lock);
+		vmaring = inode->i_mmap; 
X 		do {
X 			unsigned long vaddr = vmaring->vm_start + offset;
X 			unsigned long start;
@@ -2712,6 +2714,7 @@
X 				}
X 			}
X 		} while ((vmaring = vmaring->vm_next_share) != NULL);
+		spin_unlock(&inode->i_shared_lock);
X 
X 		if(alias_found && !(pte_val(pte) & _SUN4C_PAGE_NOCACHE)) {
X 			pgdp = sun4c_pgd_offset(vma->vm_mm, address);
diff -u --recursive --new-file v2.3.9/linux/arch/sparc64/config.in linux/arch/sparc64/config.in
--- v2.3.9/linux/arch/sparc64/config.in	Wed Jun 30 13:38:19 1999
+++ linux/arch/sparc64/config.in	Tue Jul  6 19:05:48 1999
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.66 1999/03/29 05:08:42 davem Exp $
+# $Id: config.in,v 1.67 1999/05/01 09:17:37 davem Exp $
X # For a description of the syntax of this configuration file,
X # see the Configure script.
X #
@@ -68,20 +68,8 @@
X fi
X 
X if [ "$CONFIG_PCI" = "y" ]; then
-  tristate 'Parallel port support' CONFIG_PARPORT
-  if [ "$CONFIG_PARPORT" != "n" ]; then
-    dep_tristate '  Ultra/AX-style hardware' CONFIG_PARPORT_AX $CONFIG_PARPORT
-    if [ "$CONFIG_PARPORT_AX" = "m" ]; then
-      define_bool CONFIG_PARPORT_LOWLEVEL_MODULE y
-    fi
-    if [ "$CONFIG_PARPORT_AX" != "n" ]; then
-      bool '  Support foreign hardware' CONFIG_PARPORT_OTHER
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 03'
echo 'File patch-2.3.10 is continued in part 04'
echo 04 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 23 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 23; 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
+static int txdma=1;
+static int rxdma=3;
+static int irq=5;
+static int slow=0;
+
+#ifdef LINUX_21
+MODULE_PARM(io,"i");
+MODULE_PARM_DESC(io, "The I/O base of the Sealevel card");
+MODULE_PARM(txdma,"i");
+MODULE_PARM_DESC(txdma, "Transmit DMA channel");
+MODULE_PARM(rxdma,"i");
+MODULE_PARM_DESC(rxdma, "Receive DMA channel");
+MODULE_PARM(irq,"i");
+MODULE_PARM_DESC(irq, "The interrupt line setting for the SeaLevel card");
+MODULE_PARM(slow,"i");
+MODULE_PARM_DESC(slow, "Set this for an older Sealevel card such as the 4012");
+
+MODULE_AUTHOR("Bulding Number Three Ltd");
+MODULE_DESCRIPTION("Modular driver for the SeaLevel 4021");
+#endif
+
+static struct slvl_board *slvl_unit;
+
+int init_module(void)
+{
+	printk(KERN_INFO "SeaLevel Z85230 Synchronous Driver v 0.01.\n");
+	printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n");	
+	if((slvl_unit=slvl_init(io,irq, txdma, rxdma, slow))==NULL)
+		return -ENODEV;
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	if(slvl_unit)
+		slvl_shutdown(slvl_unit);
+}
+
+#endif
+
diff -u --recursive --new-file v2.3.9/linux/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c
--- v2.3.9/linux/drivers/net/seeq8005.c	Tue Dec 29 11:32:06 1998
+++ linux/drivers/net/seeq8005.c	Mon Jul  5 19:56:46 1999
@@ -108,8 +108,8 @@
X struct netdev_entry seeq8005_drv =
X {"seeq8005", seeq8005_probe1, SEEQ8005_IO_EXTENT, seeq8005_portlist};
X #else
-__initfunc(int
-seeq8005_probe(struct device *dev))
+int __init 
+seeq8005_probe(struct device *dev)
X {
X 	int i;
X 	int base_addr = dev ? dev->base_addr : 0;
@@ -135,7 +135,7 @@
X    probes on the ISA bus.  A good device probes avoids doing writes, and
X    verifies that the correct device exists and functions.  */
X 
-__initfunc(static int seeq8005_probe1(struct device *dev, int ioaddr))
+static int __init seeq8005_probe1(struct device *dev, int ioaddr)
X {
X 	static unsigned version_printed = 0;
X 	int i,j;
@@ -736,6 +736,54 @@
X 		outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
X }
X 	
+#ifdef MODULE
+
+static char devicename[9] = { 0, };
+
+static struct device dev_seeq =
+{
+	devicename, /* device name is inserted by linux/drivers/net/net_init.c */
+	0, 0, 0, 0,
+	0x300, 5,
+	0, 0, 0, NULL, seeq8005_probe
+};
+
+static int io=0x320;
+static int irq=10;
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+
+int init_module(void)
+{
+	dev_seeq.irq=irq;
+	dev_seeq.base_addr=io;
+	if (register_netdev(&dev_seeq) != 0)
+		return -EIO;
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	/*
+	 *	No need to check MOD_IN_USE, as sys_delete_module() checks.
+	 */
+
+	unregister_netdev(&dev_seeq);
+
+	/*
+	 *	Free up the private structure, or leak memory :-)
+	 */
+
+	kfree(dev_seeq.priv);
+	dev_seeq.priv = NULL;	/* gets re-allocated by el1_probe1 */
+
+	/*
+	 *	If we don't do this, we can't re-insmod it later.
+	 */
+	release_region(dev_seeq.base_addr, EL1_IO_EXTENT);
+}
+
+#endif /* MODULE */
X 
X /*
X  * Local variables:
diff -u --recursive --new-file v2.3.9/linux/drivers/net/slhc.c linux/drivers/net/slhc.c
--- v2.3.9/linux/drivers/net/slhc.c	Fri Dec 18 09:40:56 1998
+++ linux/drivers/net/slhc.c	Mon Jul  5 20:35:18 1999
@@ -77,7 +77,6 @@
X #include <linux/timer.h>
X #include <asm/system.h>
X #include <asm/uaccess.h>
-#include <linux/mm.h>
X #include <linux/init.h>
X #include <net/checksum.h>
X #include <net/slhc_vj.h>
diff -u --recursive --new-file v2.3.9/linux/drivers/net/sunbmac.c linux/drivers/net/sunbmac.c
--- v2.3.9/linux/drivers/net/sunbmac.c	Mon Mar 15 16:11:30 1999
+++ linux/drivers/net/sunbmac.c	Mon Jul  5 20:35:18 1999
@@ -32,7 +32,6 @@
X #include <asm/openprom.h>
X #include <asm/oplib.h>
X #include <asm/auxio.h>
-#include <asm/system.h>
X #include <asm/pgtable.h>
X 
X #include <linux/netdevice.h>
diff -u --recursive --new-file v2.3.9/linux/drivers/net/sunhme.c linux/drivers/net/sunhme.c
--- v2.3.9/linux/drivers/net/sunhme.c	Thu May 27 09:55:21 1999
+++ linux/drivers/net/sunhme.c	Sun Jul  4 09:53:12 1999
@@ -3406,7 +3406,7 @@
X 	/* Set the latency timer and cache line size as well,
X 	 * PROM leaves it at zero.
X 	 */
-	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 128);
+	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
X #ifdef __sparc_v9__
X 	/* NOTE: Cache line size is in 32-bit word units. */
X 	pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x10);
diff -u --recursive --new-file v2.3.9/linux/drivers/net/sunlance.c linux/drivers/net/sunlance.c
--- v2.3.9/linux/drivers/net/sunlance.c	Sun Mar 21 07:22:00 1999
+++ linux/drivers/net/sunlance.c	Mon Jul  5 20:35:18 1999
@@ -108,7 +108,6 @@
X #include <linux/etherdevice.h>
X #include <linux/skbuff.h>
X 
-#include <asm/idprom.h>
X #include <asm/machines.h>
X 
X /* Define: 2^4 Tx buffers and 2^4 Rx buffers */
diff -u --recursive --new-file v2.3.9/linux/drivers/net/tulip.c linux/drivers/net/tulip.c
--- v2.3.9/linux/drivers/net/tulip.c	Tue Jan 19 13:18:45 1999
+++ linux/drivers/net/tulip.c	Mon Jul  5 19:56:46 1999
@@ -327,6 +327,10 @@
X 	TxFIFOUnderflow=0x20, TxJabber=0x08, TxNoBuf=0x04, TxDied=0x02, TxIntr=0x01,
X };
X 
+enum desc_status_bits {
+	DescOwned=0x80000000, RxDescFatalErr=0x8000, RxWholePkt=0x0300,
+};
+        
X /* The Tulip Rx and Tx buffer descriptors. */
X struct tulip_rx_desc {
X 	s32 status;
@@ -469,10 +473,12 @@
X 			(PCI_CLASS_NETWORK_ETHERNET << 8,
X 			 reverse_probe ? 0xfe - pci_index : pci_index,
X 			 &pci_bus, &pci_device_fn) != PCIBIOS_SUCCESSFUL)
+		{
X 			if (reverse_probe)
X 				continue;
X 			else
X 				break;
+		}
X 		pcibios_read_config_word(pci_bus, pci_device_fn,
X 								 PCI_VENDOR_ID, &vendor);
X 		pcibios_read_config_word(pci_bus, pci_device_fn,
@@ -1536,10 +1542,12 @@
X 		outl(dev->if_port ? 0x0000000C : 0x00000004, ioaddr + CSR13);
X 	} else {					/* Unknown chip type with no media table. */
X 		if (tp->default_port == 0)
-			if (tp->mii_cnt) {
+		{
+			if (tp->mii_cnt)
X 				dev->if_port = 11;
-			} else
+			else
X 				dev->if_port = 3;
+		}
X 		if (media_cap[dev->if_port] & MediaIsMII) {
X 			new_csr6 = 0x020E0000;
X 		} else if (media_cap[dev->if_port] & MediaIsFx) {
@@ -2698,8 +2706,8 @@
X 			/* Same setup recently queued, we need not add it. */
X 		} else {
X 			unsigned long flags;
-			unsigned int entry;
-			
+			unsigned int entry, dummy = 0;
+
X 			save_flags(flags); cli();
X 			entry = tp->cur_tx++ % TX_RING_SIZE;
X 
@@ -2709,7 +2717,8 @@
X 				tp->tx_ring[entry].length =
X 					(entry == TX_RING_SIZE-1) ? 0x02000000 : 0;
X 				tp->tx_ring[entry].buffer1 = 0;
-				tp->tx_ring[entry].status = 0x80000000;
+				/* race with chip, set DescOwned later */
+				dummy = entry;
X 				entry = tp->cur_tx++ % TX_RING_SIZE;
X 			}
X 
@@ -2724,6 +2733,8 @@
X 				dev->tbusy = 1;
X 				tp->tx_full = 1;
X 			}
+			if (dummy >= 0)
+				tp->tx_ring[dummy].status = DescOwned;
X 			restore_flags(flags);
X 			/* Trigger an immediate transmit demand. */
X 			outl(0, ioaddr + CSR1);
diff -u --recursive --new-file v2.3.9/linux/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c
--- v2.3.9/linux/drivers/net/via-rhine.c	Mon May 10 13:00:10 1999
+++ linux/drivers/net/via-rhine.c	Mon Jul  5 19:56:46 1999
@@ -1,6 +1,6 @@
X /* via-rhine.c: A Linux Ethernet device driver for VIA Rhine family chips. */
X /*
-	Written 1998 by Donald Becker.
+	Written 1998-1999 by Donald Becker.
X 
X 	This software may be used and distributed according to the terms
X 	of the GNU Public License (GPL), incorporated herein by reference.
@@ -20,7 +20,7 @@
X */
X 
X static const char *versionA =
-"via-rhine.c:v1.00 9/5/98  Written by Donald Becker\n";
+"via-rhine.c:v1.01 2/27/99  Written by Donald Becker\n";
X static const char *versionB =
X "  http://cesdis.gsfc.nasa.gov/linux/drivers/via-rhine.html\n";
X 
@@ -81,9 +81,11 @@
X #include <asm/bitops.h>
X #include <asm/io.h>
X 
-/* This driver was written to use PCI memory space, however some boards
-   only work with I/O space accesses. */
+/* This driver was written to use PCI memory space, however some x86
+   motherboards only configure I/O space accesses correctly. */
+#if defined(__i386__)  &&  !defined(VIA_USE_MEMORY)
X #define VIA_USE_IO
+#endif
X #ifdef VIA_USE_IO
X #undef readb
X #undef readw
@@ -105,6 +107,7 @@
X #define RUN_AT(x) (jiffies + (x))
X 
X #if (LINUX_VERSION_CODE >= 0x20100)
+char kernel_version[] = UTS_RELEASE;
X #else
X #ifndef __alpha__
X #define ioremap vremap
@@ -502,6 +505,7 @@
X #ifndef MODULE
X int via_rhine_probe(struct device *dev)
X {
+	printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
X 	return pci_etherdev_probe(dev, pci_tbl);
X }
X #endif
@@ -510,13 +514,9 @@
X 								 struct device *dev, long ioaddr, int irq,
X 								 int chip_id, int card_idx)
X {
-	static int did_version = 0;		/* Already printed version info */
X 	struct netdev_private *np;
X 	int i, option = card_idx < MAX_UNITS ? options[card_idx] : 0;
X 
-	if (debug > 0 && did_version++ == 0)
-		printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
-
X 	dev = init_etherdev(dev, 0);
X 
X 	printk(KERN_INFO "%s: %s at 0x%lx, ",
@@ -685,6 +685,8 @@
X 		   ioaddr + IntrEnable);
X 
X 	np->chip_cmd = CmdStart|CmdTxOn|CmdRxOn|CmdNoTxPoll;
+	if (np->duplex_lock)
+		np->chip_cmd |= CmdFDuplex;
X 	writew(np->chip_cmd, ioaddr + ChipCmd);
X 
X 	check_duplex(dev);
@@ -1053,7 +1055,6 @@
X 			skb->protocol = eth_type_trans(skb, dev);
X 			netif_rx(skb);
X 			dev->last_rx = jiffies;
-			np->stats.rx_bytes += pkt_len;
X 			np->stats.rx_packets++;
X 		}
X 		entry = (++np->cur_rx) % RX_RING_SIZE;
@@ -1182,7 +1183,7 @@
X 		}
X 		writel(mc_filter[0], ioaddr + MulticastFilter0);
X 		writel(mc_filter[1], ioaddr + MulticastFilter1);
-		rx_mode = 0x0C;
+		rx_mode = 0x08;
X 	}
X 	writeb(np->rx_thresh | rx_mode, ioaddr + RxConfig);
X }
diff -u --recursive --new-file v2.3.9/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c
--- v2.3.9/linux/drivers/net/wavelan.c	Thu Apr 29 11:53:41 1999
+++ linux/drivers/net/wavelan.c	Tue Jul  6 19:08:33 1999
@@ -64,8 +64,8 @@
X /*
X  * Translate PSA irq parameter to irq number 
X  */
-__initfunc(static int
-wv_psa_to_irq(u_char	irqval))
+static int __init 
+wv_psa_to_irq(u_char irqval)
X {
X   int	irq;
X 
@@ -2087,12 +2087,6 @@
X 	{
X 	  struct iw_range	range;
X 
-	  /* Verify the user buffer. */
-	  ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer,
-			    sizeof(struct iw_range));
-	  if(ret)
-	    break;
-
X 	  /* Set the length (useless:  it's constant). */
X 	  wrq->u.data.length = sizeof(struct iw_range);
X 
@@ -2118,8 +2112,8 @@
X 	  range.max_qual.noise = MMR_SILENCE_LVL;
X 
X 	  /* Copy structure to the user buffer. */
-	  copy_to_user(wrq->u.data.pointer, &range,
-		       sizeof(struct iw_range));
+	  if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
+	  	ret = -EFAULT;
X 	}
X       break;
X 
@@ -2136,18 +2130,12 @@
X 	    { SIOCGIPHISTO, 0,	    IW_PRIV_TYPE_INT | 16, "gethisto" },
X 	  };
X 
-	  /* Verify the user buffer. */
-	  ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer,
-			    sizeof(priv));
-	  if(ret)
-	    break;
-
X 	  /* Set the number of available ioctls. */
X 	  wrq->u.data.length = 4;
X 
X 	  /* Copy structure to the user buffer. */
-	  copy_to_user(wrq->u.data.pointer, (u_char *) priv,
-		       sizeof(priv));
+	  if (copy_to_user(wrq->u.data.pointer, (u_char *) priv, sizeof(priv)))
+	  	ret = -EFAULT;
X 	}
X       break;
X 
@@ -2169,14 +2157,11 @@
X 	  struct sockaddr	address[IW_MAX_SPY];
X 	  int			i;
X 
-	  /* Verify where the user has set his addresses. */
-	  ret = verify_area(VERIFY_READ, wrq->u.data.pointer,
-			    sizeof(struct sockaddr) * lp->spy_number);
-	  if(ret)
-	    break;
X 	  /* Copy addresses to the driver. */
-	  copy_from_user(address, wrq->u.data.pointer,
-			 sizeof(struct sockaddr) * lp->spy_number);
+	  if (copy_from_user(address, wrq->u.data.pointer, sizeof(struct sockaddr) * lp->spy_number)) {
+	  	ret = -EFAULT;
+	  	break;
+	  }
X 
X 	  /* Copy addresses to the lp structure. */
X 	  for(i = 0; i < lp->spy_number; i++)
@@ -2215,13 +2200,6 @@
X 	  struct sockaddr	address[IW_MAX_SPY];
X 	  int			i;
X 
-	  /* Verify the user buffer. */
-	  ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer,
-			    (sizeof(iw_qual) + sizeof(struct sockaddr))
-			    * IW_MAX_SPY);
-	  if(ret)
-	    break;
-
X 	  /* Copy addresses from the lp structure. */
X 	  for(i = 0; i < lp->spy_number; i++)
X 	    {
@@ -2231,13 +2209,18 @@
X 	    }
X 
X 	  /* Copy addresses to the user buffer. */
-	  copy_to_user(wrq->u.data.pointer, address,
-		       sizeof(struct sockaddr) * lp->spy_number);
-
+	  if (copy_to_user(wrq->u.data.pointer, address, sizeof(struct sockaddr) * lp->spy_number)) {
+	  	ret = -EFAULT;
+	  	break;
+	  }
+	  	
X 	  /* Copy stats to the user buffer (just after). */
-	  copy_to_user(wrq->u.data.pointer +
+	  if (copy_to_user(wrq->u.data.pointer +
X 		       (sizeof(struct sockaddr) * lp->spy_number),
-		       lp->spy_stat, sizeof(iw_qual) * lp->spy_number);
+		       lp->spy_stat, sizeof(iw_qual) * lp->spy_number)) {
+		       		ret = -EFAULT;
+		       		break;
+	  }
X 
X 	  /* Reset updated flags. */
X 	  for(i = 0; i < lp->spy_number; i++)
@@ -2283,14 +2266,11 @@
X       /* Are there addresses to copy? */
X       if(lp->his_number > 0)
X 	{
-	  /* Verify where the user has set his addresses. */
-	  ret = verify_area(VERIFY_READ, wrq->u.data.pointer,
-			    sizeof(char) * lp->his_number);
-	  if(ret)
-	    break;
X 	  /* Copy interval ranges to the driver */
-	  copy_from_user(lp->his_range, wrq->u.data.pointer,
-			 sizeof(char) * lp->his_number);
+	  if (copy_from_user(lp->his_range, wrq->u.data.pointer, sizeof(char) * lp->his_number)) {
+	  	ret = -EFAULT;
+	  	break;
+	  }
X 
X 	  /* Reset structure. */
X 	  memset(lp->his_sum, 0x00, sizeof(long) * 16);
@@ -2304,15 +2284,10 @@
X       /* Give back the distribution statistics */
X       if((lp->his_number > 0) && (wrq->u.data.pointer != (caddr_t) 0))
X 	{
-	  /* Verify the user buffer. */
-	  ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer,
-			    sizeof(long) * 16);
-	  if(ret)
-	    break;
-
X 	  /* Copy data to the user buffer. */
-	  copy_to_user(wrq->u.data.pointer, lp->his_sum,
-		       sizeof(long) * lp->his_number);
+	  if (copy_to_user(wrq->u.data.pointer, lp->his_sum, sizeof(long) * lp->his_number)) 
+			ret = -EFAULT;
+			
X 	}	/* if(pointer != NULL) */
X       break;
X #endif	/* HISTOGRAM */
@@ -4015,8 +3990,8 @@
X  * device structure
X  * (called by wavelan_probe() and via init_module()).
X  */
-__initfunc(static int
-wavelan_config(device *	dev))
+static int __init 
+wavelan_config(device *	dev)
X {
X   u_long	ioaddr = dev->base_addr;
X   u_char	irq_mask;
@@ -4132,8 +4107,8 @@
X  * We follow the example in drivers/net/ne.c.
X  * (called in "Space.c")
X  */
-__initfunc(int
-wavelan_probe(device *	dev))
+int __init 
+wavelan_probe(device *	dev)
X {
X   short		base_addr;
X   mac_addr	mac;		/* MAC address (check existence of WaveLAN) */
@@ -4265,6 +4240,11 @@
X 
X 	  /* Create device and set basic arguments. */
X 	  dev = kmalloc(sizeof(struct device), GFP_KERNEL);
+	  if(dev==NULL)
+	  {
+	  	ret = -ENOMEM;
+	  	break;
+	  }
X 	  memset(dev, 0x00, sizeof(struct device));
X 	  dev->name = name[i];
X 	  dev->base_addr = io[i];
diff -u --recursive --new-file v2.3.9/linux/drivers/net/z85230.c linux/drivers/net/z85230.c
--- v2.3.9/linux/drivers/net/z85230.c	Sat Apr 24 17:51:48 1999
+++ linux/drivers/net/z85230.c	Mon Jul  5 19:56:46 1999
@@ -23,7 +23,8 @@
X  *	Z85230:
X  *	Non DMA you want a 486DX50 or better to do 64Kbits. 9600 baud
X  *	X.25 is not unrealistic on all machines. DMA mode can in theory
- *	handle T1/E1 quite nicely.
+ *	handle T1/E1 quite nicely. In practice the limit seems to be about
+ *	512Kbit->1Mbit depending on motherboard.
X  *
X  *	Z85C30:
X  *	64K will take DMA, 9600 baud X.25 should be ok.
@@ -187,7 +188,6 @@
X 	1,	EXT_INT_ENAB|TxINT_ENAB|INT_ALL_Rx,
X 	9,	NV|MIE|NORESET,
X 	23,	3,		/* Extended mode AUTO TX and EOM*/
-	31,	3,		/* Extended mode AUTO TX and EOM*/
X 	
X 	255
X };
@@ -834,6 +834,8 @@
X 
X int z8530_sync_txdma_open(struct device *dev, struct z8530_channel *c)
X {
+	unsigned long flags;
+
X 	printk("Opening sync interface for TX-DMA\n");
X 	c->sync = 1;
X 	c->mtu = dev->mtu+64;
@@ -889,14 +891,21 @@
X 	c->regs[R14]|= DTRREQ;
X 	write_zsreg(c, R14, c->regs[R14]);     
X 	
+	c->regs[R1]&= ~TxINT_ENAB;
+	write_zsreg(c, R1, c->regs[R1]);
+	
X 	/*
X 	 *	Set up the DMA configuration
X 	 */	
X 	 
+	flags = claim_dma_lock();
+
X 	disable_dma(c->txdma);
X 	clear_dma_ff(c->txdma);
X 	set_dma_mode(c->txdma, DMA_MODE_WRITE);
X 	disable_dma(c->txdma);
+
+	release_dma_lock(flags);
X 	
X 	/*
X 	 *	Select the DMA interrupt handlers
@@ -918,6 +927,7 @@
X 	
X int z8530_sync_txdma_close(struct device *dev, struct z8530_channel *c)
X {
+	unsigned long flags;
X 	u8 chk;
X 	c->irqs = &z8530_nop;
X 	c->max = 0;
@@ -927,10 +937,14 @@
X 	 *	Disable the PC DMA channels
X 	 */
X 	 
+	flags = claim_dma_lock();
+
X 	disable_dma(c->txdma);
X 	clear_dma_ff(c->txdma);
X 	c->txdma_on = 0;
X 	c->tx_dma_used = 0;
+
+	release_dma_lock(flags);
X 
X 	/*
X 	 *	Disable DMA control mode
diff -u --recursive --new-file v2.3.9/linux/drivers/net/zlib.c linux/drivers/net/zlib.c
--- v2.3.9/linux/drivers/net/zlib.c	Tue Feb 10 12:56:45 1998
+++ linux/drivers/net/zlib.c	Mon Jul  5 20:35:18 1999
@@ -5113,10 +5113,6 @@
X 
X /* From: zutil.c,v 1.17 1996/07/24 13:41:12 me Exp $ */
X 
-#ifdef DEBUG_ZLIB
-#include <stdio.h>
-#endif
-
X /* #include "zutil.h" */
X 
X #ifndef NO_DUMMY_DECL
diff -u --recursive --new-file v2.3.9/linux/drivers/pci/oldproc.c linux/drivers/pci/oldproc.c
--- v2.3.9/linux/drivers/pci/oldproc.c	Wed Jun  9 16:59:15 1999
+++ linux/drivers/pci/oldproc.c	Thu Jul  8 14:50:20 1999
@@ -263,6 +263,7 @@
X 	DEVICE( BROOKTREE,      BROOKTREE_878,  "Bt878"),
X 	DEVICE( BROOKTREE,	BROOKTREE_8474,	"Bt8474"),
X 	DEVICE( SIERRA,		SIERRA_STB,	"STB Horizon 64"),
+	DEVICE( SGI,		SGI_IOC3,	"IOC3"),
X 	DEVICE( ACC,		ACC_2056,	"2056"),
X 	DEVICE( WINBOND,	WINBOND_83769,	"W83769F"),
X 	DEVICE( WINBOND,	WINBOND_82C105,	"SL82C105"),
@@ -308,6 +309,7 @@
X 	DEVICE( NEOMAGIC,	NEOMAGIC_MAGICGRAPH_128V, "MagicGraph 128V"),
X 	DEVICE( NEOMAGIC,	NEOMAGIC_MAGICGRAPH_128ZV, "MagicGraph 128ZV"),
X 	DEVICE( NEOMAGIC,	NEOMAGIC_MAGICGRAPH_NM2160, "MagicGraph NM2160"),
+	DEVICE( NEOMAGIC,	NEOMAGIC_MAGICGRAPH_128ZVPLUS, "MagicGraph 128ZV+"),
X 	DEVICE( ASP,		ASP_ABP940,	"ABP940"),
X 	DEVICE( ASP,		ASP_ABP940U,	"ABP940U"),
X 	DEVICE( ASP,		ASP_ABP940UW,	"ABP940UW"),
@@ -465,6 +467,7 @@
X 	DEVICE( SATSAGEM,	SATSAGEM_PCR2101,"PCR2101 DVB receiver"),
X 	DEVICE( SATSAGEM,	SATSAGEM_TELSATTURBO,"Telsat Turbo DVB"),
X 	DEVICE( HUGHES,		HUGHES_DIRECPC,	"DirecPC"),
+	DEVICE( ENSONIQ,	ENSONIQ_ES1371,	"ES1371"),
X 	DEVICE( ENSONIQ,	ENSONIQ_AUDIOPCI,"AudioPCI"),
X 	DEVICE( ALTEON,		ALTEON_ACENIC,  "AceNIC"),
X 	DEVICE( PICTUREL,	PICTUREL_PCIVST,"PCIVST"),
@@ -503,6 +506,7 @@
X 	DEVICE( S3,		S3_ViRGE_MXPMV,	"ViRGE/MX+MV"),
X 	DEVICE( S3,		S3_SONICVIBES,	"SonicVibes"),
X 	DEVICE( DCI,		DCI_PCCOM4,	"PC COM PCI Bus 4 port serial Adapter"),
+	DEVICE( GENROCO,	GENROCO_HFP832,	"TURBOstor HFP832"),
X 	DEVICE( INTEL,		INTEL_82375,	"82375EB"),
X 	DEVICE( INTEL,		INTEL_82424,	"82424ZX Saturn"),
X 	DEVICE( INTEL,		INTEL_82378,	"82378IB"),
@@ -541,6 +545,7 @@
X 	DEVICE(	KTI,		KTI_ET32P2,	"ET32P2"),
X 	DEVICE( ADAPTEC,	ADAPTEC_7810,	"AIC-7810 RAID"),
X 	DEVICE( ADAPTEC,	ADAPTEC_7821,	"AIC-7860"),
+	DEVICE( ADAPTEC,	ADAPTEC_38602,	"AIC-7860"),
X 	DEVICE( ADAPTEC,	ADAPTEC_7850,	"AIC-7850"),
X 	DEVICE( ADAPTEC,	ADAPTEC_7855,	"AIC-7855"),
X 	DEVICE( ADAPTEC,	ADAPTEC_5800,	"AIC-5800"),
@@ -831,6 +836,7 @@
X 	      case PCI_VENDOR_ID_NETVIN:	return "NetVin";
X 	      case PCI_VENDOR_ID_S3:		return "S3 Inc.";
X 	      case PCI_VENDOR_ID_DCI:		return "Decision Computer Int.";
+	      case PCI_VENDOR_ID_GENROCO:	return "Genroco";
X 	      case PCI_VENDOR_ID_INTEL:		return "Intel";
X 	      case PCI_VENDOR_ID_KTI:		return "KTI";
X 	      case PCI_VENDOR_ID_ADAPTEC:	return "Adaptec";
@@ -1027,7 +1033,7 @@
X 	0, &proc_array_inode_operations
X };
X 
-__initfunc(void proc_old_pci_init(void))
+void __init proc_old_pci_init(void)
X {
X 	proc_register(&proc_root, &proc_old_pci);
X }
diff -u --recursive --new-file v2.3.9/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.3.9/linux/drivers/pci/pci.c	Sat Jun 19 18:20:13 1999
+++ linux/drivers/pci/pci.c	Mon Jul  5 19:56:46 1999
@@ -138,7 +138,7 @@
X 	}
X }
X 
-__initfunc(void pci_read_bases(struct pci_dev *dev, unsigned int howmany))
+void __init pci_read_bases(struct pci_dev *dev, unsigned int howmany)
X {
X 	unsigned int reg;
X 	u32 l;
@@ -166,7 +166,7 @@
X }
X 
X 
-__initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
+unsigned int __init pci_scan_bus(struct pci_bus *bus)
X {
X 	unsigned int devfn, l, max, class;
X 	unsigned char cmd, irq, tmp, hdr_type, is_multi = 0;
@@ -192,6 +192,11 @@
X 			continue;
X 
X 		dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
+		if(dev==NULL)
+		{
+			printk(KERN_ERR "pci: out of memory.\n");
+			continue;
+		}
X 		memset(dev, 0, sizeof(*dev));
X 		dev->bus = bus;
X 		dev->devfn  = devfn;
@@ -300,6 +305,11 @@
X 			 * Insert it into the tree of buses.
X 			 */
X 			child = kmalloc(sizeof(*child), GFP_ATOMIC);
+			if(child==NULL)
+			{
+				printk(KERN_ERR "pci: out of memory for bridge.\n");
+				continue;
+			}
X 			memset(child, 0, sizeof(*child));
X 			child->next = bus->children;
X 			bus->children = child;
@@ -389,7 +399,7 @@
X 	return b;
X }
X 
-__initfunc(void pci_init(void))
+void __init pci_init(void)
X {
X 	pcibios_init();
X 
@@ -415,7 +425,7 @@
X #endif
X }
X 
-__initfunc(void pci_setup (char *str, int *ints))
+void __init pci_setup (char *str, int *ints)
X {
X 	while (str) {
X 		char *k = strchr(str, ',');
diff -u --recursive --new-file v2.3.9/linux/drivers/pnp/Config.in linux/drivers/pnp/Config.in
--- v2.3.9/linux/drivers/pnp/Config.in	Wed Jul 23 11:14:31 1997
+++ linux/drivers/pnp/Config.in	Thu Jul  1 14:22:57 1999
@@ -1,16 +1,3 @@
X #
X # Plug and Play configuration
X #
-
-mainmenu_option next_comment
-comment 'Plug and Play support'
- 
-bool 'Plug and Play support' CONFIG_PNP
-
-if [ "$CONFIG_PNP" = "y" ]; then
-  if [ "$CONFIG_PARPORT" != "n" ]; then
-    dep_tristate '  Auto-probe for parallel devices' CONFIG_PNP_PARPORT $CONFIG_PARPORT
-  fi
-fi
-
-endmenu
diff -u --recursive --new-file v2.3.9/linux/drivers/pnp/Makefile linux/drivers/pnp/Makefile
--- v2.3.9/linux/drivers/pnp/Makefile	Wed Jul 23 11:14:31 1997
+++ linux/drivers/pnp/Makefile	Thu Jul  1 14:22:57 1999
@@ -7,10 +7,6 @@
X #
X # Note 2! The CFLAGS definitions are now inherited from the
X # parent makes..
-#
-# Note 3! Plug and Play is the Borg.  We have assimilated some other
-# drivers in the `char', `net' and `scsi' directories, but left them
-# there to allay suspicion.
X 
X SUB_DIRS     := 
X MOD_SUB_DIRS := $(SUB_DIRS)
@@ -21,13 +17,5 @@
X LX_OBJS  := 
X MI_OBJS  :=
X MIX_OBJS :=
-
-ifeq ($(CONFIG_PNP_PARPORT),y)
-  LX_OBJS += parport_probe.o
-else
-  ifeq ($(CONFIG_PNP_PARPORT),m)
-    MX_OBJS += parport_probe.o
-  endif
-endif
X 
X include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.9/linux/drivers/pnp/parport_probe.c linux/drivers/pnp/parport_probe.c
--- v2.3.9/linux/drivers/pnp/parport_probe.c	Wed Jan 20 13:29:18 1999
+++ linux/drivers/pnp/parport_probe.c	Wed Dec 31 16:00:00 1969
@@ -1,288 +0,0 @@
-/* $Id: parport_probe.c,v 1.3 1997/10/19 18:18:46 phil Exp $ 
- * Parallel port device probing code
- * 
- * Authors:    Carsten Gross, car...@sol.wohnheim.uni-ulm.de
- *             Philip Blundell <Philip....@pobox.com>
- */
-
-#include <linux/tasks.h>
-#include <linux/parport.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include <linux/malloc.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-
-#include <linux/lp.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/uaccess.h>
-
-#undef DEBUG_PROBE
-
-static inline int read_nibble(struct parport *port) 
-{
-	unsigned char i;
-	i = parport_read_status(port)>>3;
-	i &= ~8;
-	if ((i & 0x10) == 0) i |= 8;
-	return (i & 0x0f);
-}
-
-static void read_terminate(struct parport *port) {
-	parport_write_control(port, (parport_read_control(port) & ~2) | 8);
-	/* SelectIN high, AutoFeed low */
-	if (parport_wait_peripheral(port, 0x80, 0)) 
-		/* timeout, SelectIN high, Autofeed low */
-		return;
-	parport_write_control(port, parport_read_control(port) | 2);
-	/* AutoFeed high */
-	parport_wait_peripheral(port, 0x80, 0x80);
-	/* no timeout possible, Autofeed low, SelectIN high */
-	parport_write_control(port, (parport_read_control(port) & ~2) | 8);
-}
-
-static long read_polled(struct parport *port, char *buf, 
-			   unsigned long length)
-{
-	int i;
-	char *temp=buf;
-	unsigned int count = 0;
-	unsigned char z=0;
-	unsigned char Byte=0;
-	unsigned long igiveupat=jiffies+5*HZ;
-
-	for (i=0; time_before(jiffies, igiveupat); i++) {
-	       /* if(current->need_resched) schedule(); */
-		parport_write_control(port, parport_read_control(port) | 2); /* AutoFeed high */
-		if (parport_wait_peripheral(port, 0x40, 0)) {
-#ifdef DEBUG_PROBE
-			/* Some peripherals just time out when they've sent
-			   all their data.  */
-			printk("%s: read1 timeout.\n", port->name);
-#endif
-			parport_write_control(port, parport_read_control(port) & ~2);
-			break;
-		}
-		z = read_nibble(port);
-		parport_write_control(port, parport_read_control(port) & ~2); /* AutoFeed low */
-		if (parport_wait_peripheral(port, 0x40, 0x40)) {
-			printk("%s: read2 timeout.\n", port->name);
-			break;
-		}
-		if ((i & 1) != 0) {
-			Byte |= (z<<4);
-			if (temp) 
-				*(temp++) = Byte; 
-			if (++count == length)
-				temp = NULL;
-			/* Does the error line indicate end of data? */
-			if ((parport_read_status(port) & LP_PERRORP) == 
-			    LP_PERRORP) 
-				break;
-		} else 
-			Byte=z;
-	}
-	read_terminate(port);
-	return count; 
-}
-
-int parport_probe(struct parport *port, char *buffer, int len)
-{
-	struct pardevice *dev = parport_register_device(port, "IEEE 1284 probe", NULL, NULL, NULL, 0, &dev);
-
-	int result = 0;
-
-	if (!dev) {
-		printk("%s: unable to register for probe.\n", port->name);
-		return -EINVAL;
-	}
-
-	parport_claim_or_block(dev);
-
-	switch (parport_ieee1284_nibble_mode_ok(port, 4)) {
-	case 2:
-		current->state=TASK_INTERRUPTIBLE;
-		/* HACK: wait 10ms because printer seems to ack wrong */
-		schedule_timeout((HZ+99)/100);	
-		result = read_polled(port, buffer, len);
-		break;
-	default:
-		result = -EIO;
-		break;
-	}
-
-	parport_release(dev);
-	parport_unregister_device(dev);
-
-	return result;
-}
-
-static struct {
-	char *token;
-	char *descr;
-} classes[] = {
-	{ "",        "Legacy device" },
-	{ "PRINTER", "Printer" }, 
-	{ "MODEM",   "Modem" },
-	{ "NET",     "Network device" },
-	{ "HDC",     "Hard disk" },
-	{ "PCMCIA",  "PCMCIA" },
-	{ "MEDIA",   "Multimedia device" },
-	{ "FDC",     "Floppy disk" },
-	{ "PORTS",   "Ports" },
-	{ "SCANNER", "Scanner" },
-	{ "DIGICAM", "Digital camera" },
-	{ "",        "Unknown device" },
-	{ "",        "Unspecified" }, 
-	{ NULL,      NULL }
-};
-
-static char *strdup(char *str)
-{
-	int n = strlen(str)+1;
-	char *s = kmalloc(n, GFP_KERNEL);
-	if (!s) return NULL;
-	return strcpy(s, str);
-}
-
-static void parse_data(struct parport *port, char *str)
-{
-	char *txt = kmalloc(strlen(str)+1, GFP_KERNEL);
-	char *p = txt, *q; 
-	int guessed_class = PARPORT_CLASS_UNSPEC;
-
-	if (!txt) {
-		printk("%s probe: memory squeeze\n", port->name);
-		return;
-	}
-	strcpy(txt, str);
-	while (p) {
-		char *sep; 
-		q = strchr(p, ';');
-		if (q) *q = 0;
-		sep = strchr(p, ':');
-		if (sep) {
-			char *u = p;
-			*(sep++) = 0;
-			while (*u) {
-				*u = toupper(*u);
-				u++;
-			}
-			if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) {
-				if (port->probe_info.mfr)
-					kfree (port->probe_info.mfr);
-				port->probe_info.mfr = strdup(sep);
-			} else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) {
-				if (port->probe_info.model)
-					kfree (port->probe_info.model);
-				port->probe_info.model = strdup(sep);
-			} else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) {
-				int i;
-				if (port->probe_info.class_name)
-					kfree (port->probe_info.class_name);
-				port->probe_info.class_name = strdup(sep);
-				for (u = sep; *u; u++)
-					*u = toupper(*u);
-				for (i = 0; classes[i].token; i++) {
-					if (!strcmp(classes[i].token, sep)) {
-						port->probe_info.class = i;
-						goto rock_on;
-					}
-				}
-				printk(KERN_WARNING "%s probe: warning, class '%s' not understood.\n", port->name, sep);
-				port->probe_info.class = PARPORT_CLASS_OTHER;
-			} else if (!strcmp(p, "CMD") || !strcmp(p, "COMMAND SET")) {
-				if (port->probe_info.cmdset)
-					kfree (port->probe_info.cmdset);
-				port->probe_info.cmdset = strdup(sep);
-				/* if it speaks printer language, it's
-				   probably a printer */
-				if (strstr(sep, "PJL") || strstr(sep, "PCL"))
-					guessed_class = PARPORT_CLASS_PRINTER;
-			} else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) {
-				if (port->probe_info.description)
-					kfree (port->probe_info.description);
-				port->probe_info.description = strdup(sep);
-			}
-		}
-	rock_on:
-		if (q) p = q+1; else p=NULL;
-	}
-
-	/* If the device didn't tell us its class, maybe we have managed to
-	   guess one from the things it did say. */
-	if (port->probe_info.class == PARPORT_CLASS_UNSPEC)
-		port->probe_info.class = guessed_class;
-
-	kfree(txt);
-}
-
-static void pretty_print(struct parport *port)
-{
-	printk(KERN_INFO "%s: %s", port->name,
-	       classes[port->probe_info.class].descr);
-	if (port->probe_info.class) {
-		printk(", %s %s", port->probe_info.mfr, 
-		       port->probe_info.model);
-	}
-	printk("\n");
-}
-
-void parport_probe_one(struct parport *port)
-{
-	char *buffer = kmalloc(2048, GFP_KERNEL);
-	int r;
-
-	MOD_INC_USE_COUNT;
-	port->probe_info.model = strdup ("Unknown device");
-	port->probe_info.mfr = strdup ("Unknown vendor");
-	port->probe_info.description = port->probe_info.cmdset = NULL;
-	port->probe_info.class = PARPORT_CLASS_UNSPEC;
-	port->probe_info.class_name = NULL;
-
-	if (!buffer) {
-		printk(KERN_ERR "%s probe: Memory squeeze.\n", port->name);
-		return;
-	}
-
-	r = parport_probe(port, buffer, 2047);
-
-	if (r < 0) {
-		printk(KERN_INFO "%s: no IEEE-1284 device present.\n",
-		       port->name);
-		port->probe_info.class = PARPORT_CLASS_LEGACY;
-	} else if (r == 0) {
-		printk(KERN_INFO "%s: no ID data returned by device.\n",
-		       port->name);
-	} else {
-		buffer[r] = 0; 
-#ifdef DEBUG_PROBE
-		printk("%s id: %s\n", port->name, buffer+2);
-#endif
-		parse_data(port, buffer+2); 
-		pretty_print(port);
-	}
-	kfree(buffer);
-	MOD_DEC_USE_COUNT;
-}
-
-#if MODULE
-int init_module(void)
-{
-	struct parport *p;
-	for (p = parport_enumerate(); p; p = p->next) 
-		parport_probe_one(p);
-	parport_probe_hook = &parport_probe_one;
-	return 0;
-}
-
-void cleanup_module(void)
-{
-	parport_probe_hook = NULL;
-}
-#endif
diff -u --recursive --new-file v2.3.9/linux/drivers/sbus/char/bpp.c linux/drivers/sbus/char/bpp.c
--- v2.3.9/linux/drivers/sbus/char/bpp.c	Wed Jun  9 14:44:25 1999
+++ linux/drivers/sbus/char/bpp.c	Mon Jul  5 20:35:18 1999
@@ -20,10 +20,10 @@
X #include <linux/ioport.h>
X #include <linux/major.h>
X 
-#include  <asm/uaccess.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
X 
X #if defined(__i386__)
-# include <asm/io.h>
X # include <asm/system.h>
X # include <asm/segment.h>
X #endif
@@ -34,7 +34,6 @@
X 
X # include <asm/oplib.h>           /* OpenProm Library */
X # include <asm/sbus.h>            /* struct linux_sbus *SBus_chain */
-# include <asm/io.h>              /* sparc_alloc_io() */
X #endif
X 
X #include <asm/bpp.h>
diff -u --recursive --new-file v2.3.9/linux/drivers/sbus/char/sab82532.c linux/drivers/sbus/char/sab82532.c
--- v2.3.9/linux/drivers/sbus/char/sab82532.c	Wed May 12 08:41:15 1999
+++ linux/drivers/sbus/char/sab82532.c	Sun Jul  4 09:53:12 1999
@@ -1,4 +1,4 @@
-/* $Id: sab82532.c,v 1.31 1999/05/12 11:15:10 davem Exp $
+/* $Id: sab82532.c,v 1.32 1999/07/03 08:57:41 davem Exp $
X  * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
X  *
X  * Copyright (C) 1997  Eddie C. Dost  (e...@skynet.be)
@@ -1672,7 +1672,6 @@
X #endif
X 	while (info->xmit_cnt || !info->all_sent) {
X 		current->state = TASK_INTERRUPTIBLE;
- current->counter = 0;
X 		schedule_timeout(char_time);
X 		if (signal_pending(current))
X 			break;
@@ -2136,7 +2135,7 @@
X 
X __initfunc(static inline void show_serial_version(void))
X {
-	char *revision = "$Revision: 1.31 $";
+	char *revision = "$Revision: 1.32 $";
X 	char *version, *p;
X 
X 	version = strchr(revision, ' ');
diff -u --recursive --new-file v2.3.9/linux/drivers/sbus/char/su.c linux/drivers/sbus/char/su.c
--- v2.3.9/linux/drivers/sbus/char/su.c	Thu Jun 17 01:08:50 1999
+++ linux/drivers/sbus/char/su.c	Sun Jul  4 09:53:12 1999
@@ -1,4 +1,4 @@
-/* $Id: su.c,v 1.21 1999/06/11 10:23:42 davem Exp $
+/* $Id: su.c,v 1.22 1999/07/03 08:57:43 davem Exp $
X  * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI
X  *
X  * Copyright (C) 1997  Eddie C. Dost  (e...@skynet.be)
@@ -1836,7 +1836,6 @@
X 		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
X #endif
X 		current->state = TASK_INTERRUPTIBLE;
-		current->counter = 0;	/* make us low-priority */
X 		schedule_timeout(char_time);
X 		if (signal_pending(current))
X 			break;
@@ -2215,7 +2214,7 @@
X  */
X __initfunc(static __inline__ void show_su_version(void))
X {
-	char *revision = "$Revision: 1.21 $";
+	char *revision = "$Revision: 1.22 $";
X 	char *version, *p;
X 
X 	version = strchr(revision, ' ');
diff -u --recursive --new-file v2.3.9/linux/drivers/sbus/sbus.c linux/drivers/sbus/sbus.c
--- v2.3.9/linux/drivers/sbus/sbus.c	Mon May 31 22:08:10 1999
+++ linux/drivers/sbus/sbus.c	Mon Jul  5 20:35:18 1999
@@ -8,7 +8,6 @@
X #include <linux/malloc.h>
X #include <linux/config.h>
X #include <linux/init.h>
-#include <linux/malloc.h>
X #include <linux/pci.h>
X 
X #include <asm/system.h>
diff -u --recursive --new-file v2.3.9/linux/drivers/scsi/53c7xx.c linux/drivers/scsi/53c7xx.c
--- v2.3.9/linux/drivers/scsi/53c7xx.c	Mon Oct  5 13:43:31 1998
+++ linux/drivers/scsi/53c7xx.c	Mon Jul  5 20:35:18 1999
@@ -254,9 +254,9 @@
X #include <linux/time.h>
X #include <linux/blk.h>
X #include <asm/spinlock.h>
+#include <asm/pgtable.h>
X 
X #ifdef CONFIG_AMIGA
-#include <asm/pgtable.h>
X #include <asm/amigahw.h>
X #include <asm/amigaints.h>
X #include <asm/irq.h>
@@ -266,7 +266,6 @@
X #endif
X 
X #ifdef CONFIG_MVME16x
-#include <asm/pgtable.h>
X #include <asm/mvme16xhw.h>
X 
X #define BIG_ENDIAN
@@ -275,7 +274,6 @@
X #endif
X 
X #ifdef CONFIG_BVME6000
-#include <asm/pgtable.h>
X #include <asm/bvme6000hw.h>
X 
X #define BIG_ENDIAN
diff -u --recursive --new-file v2.3.9/linux/drivers/scsi/NCR53C9x.c linux/drivers/scsi/NCR53C9x.c
--- v2.3.9/linux/drivers/scsi/NCR53C9x.c	Fri Dec 18 09:47:38 1998
+++ linux/drivers/scsi/NCR53C9x.c	Mon Jul  5 19:56:46 1999
@@ -3390,6 +3390,7 @@
X 	struct ESP_regs *eregs;
X 	Scsi_Cmnd *SCptr;
X 	int what_next = do_intr_end;
+	unsigned long flags;
X #ifdef CONFIG_SCSI_SUNESP
X 	struct sparc_dma_registers *dregs = 
X 	  (struct sparc_dma_registers*) esp->dregs;
@@ -3610,7 +3611,9 @@
X 			}
X 			SCptr->result = (DID_RESET << 16);
X 
+			spin_lock_irqsave(&io_request_lock,flags);
X 			SCptr->scsi_done(SCptr);
+			spin_unlock_irqrestore(&io_request_lock, flags);
X 		}
X 		esp->current_SC = NULL;
X 		if(esp->disconnected_SC) {
@@ -3625,7 +3628,9 @@
X 				}
X 				SCptr->result = (DID_RESET << 16);
X 
+				spin_lock_irqsave(&io_request_lock,flags);
X 				SCptr->scsi_done(SCptr);
+				spin_unlock_irqrestore(&io_request_lock, flags);
X 			}
X 		}
X 		esp->resetting_bus = 0;
diff -u --recursive --new-file v2.3.9/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- v2.3.9/linux/drivers/scsi/aha152x.c	Wed May 12 13:19:17 1999
+++ linux/drivers/scsi/aha152x.c	Tue Jul  6 19:08:33 1999
@@ -183,7 +183,7 @@
X  **************************************************************************
X 
X 
- 
+
X  DESCRIPTION:
X 
X  This is the Linux low-level SCSI driver for Adaptec AHA-1520/1522 SCSI
@@ -192,30 +192,30 @@
X 
X  CONFIGURATION ARGUMENTS:
X 
-  IOPORT        base io address                           (0x340/0x140)
-  IRQ           interrupt level                           (9-12; default 11)
-  SCSI_ID       scsi id of controller                     (0-7; default 7)
-  RECONNECT     allow targets to disconnect from the bus  (0/1; default 1 [on])
-  PARITY        enable parity checking                    (0/1; default 1 [on])
-  SYNCHRONOUS   enable synchronous transfers              (0/1; default 0 [off])
-                (NOT WORKING YET)
-  DELAY:        bus reset delay                           (default 100)
-  EXT_TRANS:    enable extended translation               (0/1: default 0 [off])
-                (see NOTES below)
+ IOPORT        base io address                           (0x340/0x140)
+ IRQ           interrupt level                           (9-12; default 11)
+ SCSI_ID       scsi id of controller                     (0-7; default 7)
+ RECONNECT     allow targets to disconnect from the bus  (0/1; default 1 [on])
+ PARITY        enable parity checking                    (0/1; default 1 [on])
+ SYNCHRONOUS   enable synchronous transfers              (0/1; default 0 [off])
+ (NOT WORKING YET)
+ DELAY:        bus reset delay                           (default 100)
+ EXT_TRANS:    enable extended translation               (0/1: default 0 [off])
+ (see NOTES below)
X 
X  COMPILE TIME CONFIGURATION (put into AHA152X in drivers/scsi/Makefile):
X 
X  -DAUTOCONF
-   use configuration the controller reports (AHA-152x only)
+ use configuration the controller reports (AHA-152x only)
X 
X  -DSKIP_BIOSTEST
-   Don't test for BIOS signature (AHA-1510 or disabled BIOS)
+ Don't test for BIOS signature (AHA-1510 or disabled BIOS)
X 
X  -DSETUP0="{ IOPORT, IRQ, SCSI_ID, RECONNECT, PARITY, SYNCHRONOUS, DELAY, EXT_TRANS }"
-   override for the first controller 
-   
+ override for the first controller 
+
X  -DSETUP1="{ IOPORT, IRQ, SCSI_ID, RECONNECT, PARITY, SYNCHRONOUS, DELAY, EXT_TRANS }"
-   override for the second controller
+ override for the second controller
X 
X 
X  LILO COMMAND LINE OPTIONS:
@@ -230,13 +230,13 @@
X 
X 
X  SYMBOLS FOR MODULE CONFIGURATION:
- 
-  aha152x=IOPORT,IRQ,SCSI_ID,RECONNECT,PARITY,SYNCHRONOUS,DELAY,EXT_TRANS
-    configuration override of first controller
-
- 
-  aha152x1=IOPORT,IRQ,SCSI_ID,RECONNECT,PARITY,SYNCHRONOUS,DELAY,EXT_TRANS
-    configuration override of second controller
+
+ aha152x=IOPORT,IRQ,SCSI_ID,RECONNECT,PARITY,SYNCHRONOUS,DELAY,EXT_TRANS
+ configuration override of first controller
+
+
+ aha152x1=IOPORT,IRQ,SCSI_ID,RECONNECT,PARITY,SYNCHRONOUS,DELAY,EXT_TRANS
+ configuration override of second controller
X 
X 
X  NOTES ON EXT_TRANS: 
@@ -287,14 +287,14 @@
X 
X  - for disks<1GB: use default translation (C/32/64)
X  - for disks>1GB:
-   - take current geometry from the partition table
-     (using scsicam_bios_param and accept only `valid' geometries,
-      ie. either (C/32/64) or (C/63/255)).  This can be extended
-      translation even if it's not enabled in the driver.
-   - if that fails, take extended translation if enabled by override,
-     kernel or module parameter, otherwise take default translation and
-     ask the user for verification.  This might on not yet partitioned
-     disks or
+ - take current geometry from the partition table
+ (using scsicam_bios_param and accept only `valid' geometries,
+ ie. either (C/32/64) or (C/63/255)).  This can be extended
+ translation even if it's not enabled in the driver.
+ - if that fails, take extended translation if enabled by override,
+ kernel or module parameter, otherwise take default translation and
+ ask the user for verification.  This might on not yet partitioned
+ disks or
X 
X 
X  REFERENCES USED:
@@ -308,7 +308,7 @@
X  "Kernel Hacker's Guide", Michael K. Johnson (john...@sunsite.unc.edu)
X 
X  "Adaptec 1520/1522 User's Guide", Adaptec Corporation.
- 
+
X  Michael K. Johnson (john...@sunsite.unc.edu)
X 
X  Drew Eckhardt (dr...@cs.colorado.edu)
@@ -350,9 +350,10 @@
X 
X #include <scsi/scsicam.h>
X 
-struct proc_dir_entry proc_scsi_aha152x = {
-    PROC_SCSI_AHA152X, 7, "aha152x",
-    S_IFDIR | S_IRUGO | S_IXUGO, 2
+struct proc_dir_entry proc_scsi_aha152x =
+{
+	PROC_SCSI_AHA152X, 7, "aha152x",
+	S_IFDIR | S_IRUGO | S_IXUGO, 2
X };
X 
X /* DEFINES */
@@ -370,25 +371,25 @@
X 
X #if defined(DEBUG_AHA152X)
X 
-#undef  SKIP_PORTS              /* don't display ports */
+#undef  SKIP_PORTS		/* don't display ports */
X 
-#undef  DEBUG_QUEUE             /* debug queue() */
-#undef  DEBUG_RESET             /* debug reset() */
-#undef  DEBUG_INTR              /* debug intr() */
-#undef  DEBUG_SELECTION         /* debug selection part in intr() */
-#undef  DEBUG_MSGO              /* debug message out phase in intr() */
-#undef  DEBUG_MSGI              /* debug message in phase in intr() */
-#undef  DEBUG_STATUS            /* debug status phase in intr() */
-#undef  DEBUG_CMD               /* debug command phase in intr() */
-#undef  DEBUG_DATAI             /* debug data in phase in intr() */
-#undef  DEBUG_DATAO             /* debug data out phase in intr() */
-#undef  DEBUG_ABORT             /* debug abort() */
-#undef  DEBUG_DONE              /* debug done() */
-#undef  DEBUG_BIOSPARAM         /* debug biosparam() */
-
-#undef  DEBUG_RACE              /* debug race conditions */
-#undef  DEBUG_PHASES            /* debug phases (useful to trace) */
-#undef  DEBUG_QUEUES            /* debug reselection */
+#undef  DEBUG_QUEUE		/* debug queue() */
+#undef  DEBUG_RESET		/* debug reset() */
+#undef  DEBUG_INTR		/* debug intr() */
+#undef  DEBUG_SELECTION		/* debug selection part in intr() */
+#undef  DEBUG_MSGO		/* debug message out phase in intr() */
+#undef  DEBUG_MSGI		/* debug message in phase in intr() */
+#undef  DEBUG_STATUS		/* debug status phase in intr() */
+#undef  DEBUG_CMD		/* debug command phase in intr() */
+#undef  DEBUG_DATAI		/* debug data in phase in intr() */
+#undef  DEBUG_DATAO		/* debug data out phase in intr() */
+#undef  DEBUG_ABORT		/* debug abort() */
+#undef  DEBUG_DONE		/* debug done() */
+#undef  DEBUG_BIOSPARAM		/* debug biosparam() */
+
+#undef  DEBUG_RACE		/* debug race conditions */
+#undef  DEBUG_PHASES		/* debug phases (useful to trace) */
+#undef  DEBUG_QUEUES		/* debug reselection */
X 
X /* recently used for debugging */
X #if 0
@@ -424,46 +425,50 @@
X #define IRQS    IRQ_MAX-IRQ_MIN+1
X 
X enum {
-  not_issued   = 0x0001,
-  in_selection = 0x0002,
-  disconnected = 0x0004,
-  aborted      = 0x0008,
-  sent_ident   = 0x0010,
-  in_other     = 0x0020,
-  in_sync      = 0x0040,
-  sync_ok      = 0x0080,
+	not_issued = 0x0001,
+	in_selection = 0x0002,
+	disconnected = 0x0004,
+	aborted = 0x0008,
+	sent_ident = 0x0010,
+	in_other = 0x0020,
+	in_sync = 0x0040,
+	sync_ok = 0x0080,
X };
X 
X #if defined(MODULE)
X #if defined(DEBUG_AHA152X)
-int aha152x[]  = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0, DEBUG_DEFAULT };
-int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0, DEBUG_DEFAULT };
+int aha152x[] =
+{0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0, DEBUG_DEFAULT};
+int aha152x1[] =
+{0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0, DEBUG_DEFAULT};
X MODULE_PARM(aha152x, "1-9i");
X MODULE_PARM(aha152x1, "1-9i");
X #else
-int aha152x[]  = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0 };
-int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0 };
+int aha152x[] =
+{0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};
+int aha152x1[] =
+{0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};
X MODULE_PARM(aha152x, "1-8i");
X MODULE_PARM(aha152x1, "1-8i");
X #endif
X #endif
X 
X /* set by aha152x_setup according to the command line */
-static int  setup_count=0;
-static int  registered_count=0;
+static int setup_count = 0;
+static int registered_count = 0;
X static struct aha152x_setup {
-  int io_port;
-  int irq;
-  int scsiid;
-  int reconnect;
-  int parity;
-  int synchronous;
-  int delay;
-  int ext_trans;
+	int io_port;
+	int irq;
+	int scsiid;
+	int reconnect;
+	int parity;
+	int synchronous;
+	int delay;
+	int ext_trans;
X #ifdef DEBUG_AHA152X
-  int debug;
+	int debug;
X #endif
-  char *conf;
+	char *conf;
X } setup[2];
X 
X static struct Scsi_Host *aha152x_host[IRQS];
@@ -480,30 +485,30 @@
X #define ADDMSG(x)         (MSG(MSGLEN++)=x)
X 
X struct aha152x_hostdata {
-  Scsi_Cmnd     *issue_SC;
-  Scsi_Cmnd     *current_SC;
-  Scsi_Cmnd     *disconnected_SC;
-  int           aborting;
-  int           abortion_complete;
-  int           abort_result;
-  int           commands;
-  
-  int           reconnect;
-  int           parity;
-  int           synchronous;
-  int           delay;
-  int           ext_trans;
-
-  int           swint;
-  int		service;
- 
-  unsigned char syncrate[8];
-  
-  unsigned char message[256];
-  int           message_len;
+	Scsi_Cmnd *issue_SC;
+	Scsi_Cmnd *current_SC;
+	Scsi_Cmnd *disconnected_SC;
+	int aborting;
+	int abortion_complete;
+	int abort_result;
+	int commands;
+
+	int reconnect;
+	int parity;
+	int synchronous;
+	int delay;
+	int ext_trans;
+
+	int swint;
+	int service;
+
+	unsigned char syncrate[8];
+
+	unsigned char message[256];
+	int message_len;
X 
X #ifdef DEBUG_AHA152X
-  int           debug;
+	int debug;
X #endif
X };
X 
@@ -516,7 +521,7 @@
X static void aha152x_panic(struct Scsi_Host *shpnt, char *msg);
X 
X static void disp_ports(struct Scsi_Host *shpnt);
-static void show_command(Scsi_Cmnd *ptr);
+static void show_command(Scsi_Cmnd * ptr);
X static void show_queues(struct Scsi_Host *shpnt);
X static void disp_enintr(struct Scsi_Host *shpnt);
X 
@@ -528,8 +533,8 @@
X /* possible i/o addresses for the AIC-6260 */
X static unsigned short ports[] =
X {
-  0x340,      /* default first */
-  0x140
+	0x340,			/* default first */
+	0x140
X };
X #define PORT_COUNT (sizeof(ports) / sizeof(unsigned short))
X 
@@ -537,15 +542,15 @@
X /* possible locations for the Adaptec BIOS */
X static unsigned int addresses[] =
X {
-  0xdc000,   /* default first */
-  0xc8000,
-  0xcc000,
-  0xd0000,
-  0xd4000,
-  0xd8000,
-  0xe0000,
-  0xeb800,   /* VTech Platinum SMP */
-  0xf0000,
+	0xdc000,		/* default first */
+	0xc8000,
+	0xcc000,
+	0xd0000,
+	0xd4000,
+	0xd8000,
+	0xe0000,
+	0xeb800,		/* VTech Platinum SMP */
+	0xf0000,
X };
X #define ADDRESS_COUNT (sizeof(addresses) / sizeof(unsigned int))
X 
@@ -557,80 +562,103 @@
X    needed anyway.  May be an information whether or not the BIOS supports
X    extended translation could be also useful here. */
X static struct signature {
-  unsigned char *signature;
-  int  sig_offset;
-  int  sig_length;
+	unsigned char *signature;
+	int sig_offset;
+	int sig_length;
X } signatures[] =
+
X {
-  { "Adaptec AHA-1520 BIOS",      0x102e, 21 },  /* Adaptec 152x */
-  { "Adaptec AHA-1520B",            0x0b, 19 },  /* Adaptec 152x rev B */
-  { "Adaptec ASW-B626 BIOS",      0x1029, 21 },  /* on-board controller */
-  { "Adaptec BIOS: ASW-B626",       0x0f, 22 },  /* on-board controller */
-  { "Adaptec ASW-B626 S2",        0x2e6c, 19 },  /* on-board controller */
-  { "Adaptec BIOS:AIC-6360",         0xc, 21 },  /* on-board controller */
-  { "ScsiPro SP-360 BIOS",        0x2873, 19 },  /* ScsiPro-Controller  */
-  { "GA-400 LOCAL BUS SCSI BIOS", 0x102e, 26 },  /* Gigabyte Local-Bus-SCSI */
-  { "Adaptec BIOS:AVA-282X",         0xc, 21 },  /* Adaptec 282x */
-  { "Adaptec IBM Dock II SCSI",   0x2edd, 24 },  /* IBM Thinkpad Dock II */
-  { "Adaptec BIOS:AHA-1532P",       0x1c, 22 },  /* IBM Thinkpad Dock II SCSI */
-  { "DTC3520A Host Adapter BIOS", 0x318a, 26 },  /* DTC 3520A ISA SCSI */
+	{
+		"Adaptec AHA-1520 BIOS", 0x102e, 21
+	},			/* Adaptec 152x */
+	{
+		"Adaptec AHA-1520B", 0x0b, 19
+	},			/* Adaptec 152x rev B */
+	{
+		"Adaptec ASW-B626 BIOS", 0x1029, 21
+	},			/* on-board controller */
+	{
+		"Adaptec BIOS: ASW-B626", 0x0f, 22
+	},			/* on-board controller */
+	{
+		"Adaptec ASW-B626 S2", 0x2e6c, 19
+	},			/* on-board controller */
+	{
+		"Adaptec BIOS:AIC-6360", 0xc, 21
+	},			/* on-board controller */
+	{
+		"ScsiPro SP-360 BIOS", 0x2873, 19
+	},			/* ScsiPro-Controller  */
+	{
+		"GA-400 LOCAL BUS SCSI BIOS", 0x102e, 26
+	},			/* Gigabyte Local-Bus-SCSI */
+	{
+		"Adaptec BIOS:AVA-282X", 0xc, 21
+	},			/* Adaptec 282x */
+	{
+		"Adaptec IBM Dock II SCSI", 0x2edd, 24
+	},			/* IBM Thinkpad Dock II */
+	{
+		"Adaptec BIOS:AHA-1532P", 0x1c, 22
+	},			/* IBM Thinkpad Dock II SCSI */
+	{
+		"DTC3520A Host Adapter BIOS", 0x318a, 26
+	},			/* DTC 3520A ISA SCSI */
X };
+
X #define SIGNATURE_COUNT (sizeof(signatures) / sizeof(struct signature))
X #endif
X 
X 
-static void do_pause(unsigned amount) /* Pause for amount*10 milliseconds */
-{
-   unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */
+static void do_pause(unsigned amount)
+{				/* Pause for amount*10 milliseconds */
+	unsigned long the_time = jiffies + amount;	/* 0.01 seconds per jiffy */
X 
-   while (time_before(jiffies, the_time))
-     barrier();
+	while (time_before(jiffies, the_time))
+		barrier();
X }
X 
X /*
X  *  queue services:
X  */
-static inline void append_SC(Scsi_Cmnd **SC, Scsi_Cmnd *new_SC)
+static inline void append_SC(Scsi_Cmnd ** SC, Scsi_Cmnd * new_SC)
X {
-  Scsi_Cmnd *end;
+	Scsi_Cmnd *end;
X 
-  new_SC->host_scribble = (unsigned char *) NULL;
-  if(!*SC)
-    *SC=new_SC;
-  else {
-    for(end=*SC; end->host_scribble; end = (Scsi_Cmnd *) end->host_scribble)
-      ;
-    end->host_scribble = (unsigned char *) new_SC;
-  }
+	new_SC->host_scribble = (unsigned char *) NULL;
+	if (!*SC)
+		*SC = new_SC;
+	else {
+		for (end = *SC; end->host_scribble; end = (Scsi_Cmnd *) end->host_scribble);
+		end->host_scribble = (unsigned char *) new_SC;
+	}
X }
X 
-static inline Scsi_Cmnd *remove_first_SC(Scsi_Cmnd **SC)
+static inline Scsi_Cmnd *remove_first_SC(Scsi_Cmnd ** SC)
X {
-  Scsi_Cmnd *ptr;
+	Scsi_Cmnd *ptr;
X 
-  ptr=*SC;
-  if(ptr)
-    *SC= (Scsi_Cmnd *) (*SC)->host_scribble;
-  return ptr;
+	ptr = *SC;
+	if (ptr)
+		*SC = (Scsi_Cmnd *) (*SC)->host_scribble;
+	return ptr;
X }
X 
-static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, int target, int lun)
+static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd ** SC, int target, int lun)
X {
-  Scsi_Cmnd *ptr, *prev;
-
-  for(ptr=*SC, prev=NULL;
-       ptr && ((ptr->target!=target) || (ptr->lun!=lun));
-      prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble)
-    ;
+	Scsi_Cmnd *ptr, *prev;
X 
-  if(ptr){
-    if(prev)
-      prev->host_scribble = ptr->host_scribble;
-    else
-      *SC= (Scsi_Cmnd *) ptr->host_scribble;
-  }
+	for (ptr = *SC, prev = NULL;
+	     ptr && ((ptr->target != target) || (ptr->lun != lun));
+	     prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble);
X 
-  return ptr;
+	if (ptr) {
+		if (prev)
+			prev->host_scribble = ptr->host_scribble;
+		else
+			*SC = (Scsi_Cmnd *) ptr->host_scribble;
+	}
+	return ptr;
X }
X 
X /*
@@ -638,12 +666,12 @@
X  */
X static void make_acklow(struct Scsi_Host *shpnt)
X {
-  SETPORT(SXFRCTL0, CH1|SPIOEN);
-  GETPORT(SCSIDAT);
-  SETPORT(SXFRCTL0, CH1);
+	SETPORT(SXFRCTL0, CH1 | SPIOEN);
+	GETPORT(SCSIDAT);
+	SETPORT(SXFRCTL0, CH1);
X 
-  while(TESTHI(SCSISIG, ACKI))
-    barrier();
+	while (TESTHI(SCSISIG, ACKI))
+		barrier();
X }
X 
X /*
@@ -658,61 +686,61 @@
X  */
X static int getphase(struct Scsi_Host *shpnt)
X {
-  int phase, sstat1;
-  
-  while(1) {
-    do {
-      while(!((sstat1 = GETPORT(SSTAT1)) & (BUSFREE|SCSIRSTI|REQINIT)))
-        barrier();
-      if(sstat1 & BUSFREE)
-        return P_BUSFREE;
-      if(sstat1 & SCSIRSTI) {
-        printk("aha152x: RESET IN\n");
-        SETPORT(SSTAT1, SCSIRSTI);
-      }
-    } while(TESTHI(SCSISIG, ACKI) || TESTLO(SSTAT1, REQINIT));
-
-    SETPORT(SSTAT1, CLRSCSIPERR);
-  
-    phase = GETPORT(SCSISIG) & P_MASK ;
-
-    if(TESTHI(SSTAT1, SCSIPERR)) {
-      if((phase & (CDO|MSGO))==0)                        /* DATA phase */
-        return P_PARITY;
-
-      make_acklow(shpnt);
-    } else
-      return phase;
-  }
+	int phase, sstat1;
+
+	while (1) {
+		do {
+			while (!((sstat1 = GETPORT(SSTAT1)) & (BUSFREE | SCSIRSTI | REQINIT)))
+				barrier();
+			if (sstat1 & BUSFREE)
+				return P_BUSFREE;
+			if (sstat1 & SCSIRSTI) {
+				printk("aha152x: RESET IN\n");
+				SETPORT(SSTAT1, SCSIRSTI);
+			}
+		} while (TESTHI(SCSISIG, ACKI) || TESTLO(SSTAT1, REQINIT));
+
+		SETPORT(SSTAT1, CLRSCSIPERR);
+
+		phase = GETPORT(SCSISIG) & P_MASK;
+
+		if (TESTHI(SSTAT1, SCSIPERR)) {
+			if ((phase & (CDO | MSGO)) == 0)	/* DATA phase */
+				return P_PARITY;
+
+			make_acklow(shpnt);
+		} else
+			return phase;
+	}
X }
X 
X /* called from init/main.c */
X void aha152x_setup(char *str, int *ints)
X {
-  if(setup_count>2)
-    panic("aha152x: you can only configure up to two controllers\n");
+	if (setup_count > 2)
+		panic("aha152x: you can only configure up to two controllers\n");
X 
-  setup[setup_count].conf        = str;
-  setup[setup_count].io_port     = ints[0] >= 1 ? ints[1] : 0x340;
-  setup[setup_count].irq         = ints[0] >= 2 ? ints[2] : 11;
-  setup[setup_count].scsiid      = ints[0] >= 3 ? ints[3] : 7;
-  setup[setup_count].reconnect   = ints[0] >= 4 ? ints[4] : 1;
-  setup[setup_count].parity      = ints[0] >= 5 ? ints[5] : 1;
-  setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 0 /* FIXME: 1 */;
-  setup[setup_count].delay       = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT;
-  setup[setup_count].ext_trans   = ints[0] >= 8 ? ints[8] : 0;
+	setup[setup_count].conf = str;
+	setup[setup_count].io_port = ints[0] >= 1 ? ints[1] : 0x340;
+	setup[setup_count].irq = ints[0] >= 2 ? ints[2] : 11;
+	setup[setup_count].scsiid = ints[0] >= 3 ? ints[3] : 7;
+	setup[setup_count].reconnect = ints[0] >= 4 ? ints[4] : 1;
+	setup[setup_count].parity = ints[0] >= 5 ? ints[5] : 1;
+	setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 0 /* FIXME: 1 */ ;
+	setup[setup_count].delay = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT;
+	setup[setup_count].ext_trans = ints[0] >= 8 ? ints[8] : 0;
X #ifdef DEBUG_AHA152X
-  setup[setup_count].debug       = ints[0] >= 9 ? ints[9] : DEBUG_DEFAULT;
-  if(ints[0]>9) { 
-    printk("aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"
-           "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>[,<DEBUG>]]]]]]]]\n");
+	setup[setup_count].debug = ints[0] >= 9 ? ints[9] : DEBUG_DEFAULT;
+	if (ints[0] > 9) {
+		printk("aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"
+		       "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>[,<DEBUG>]]]]]]]]\n");
X #else
-  if(ints[0]>8) {
-    printk("aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"
-           "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n");
+	if (ints[0] > 8) {
+		printk("aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"
+		       "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n");
X #endif
-  } else 
-    setup_count++;
+	} else
+		setup_count++;
X }
X 
X /*
@@ -720,598 +748,589 @@
X  */
X static int aha152x_porttest(int io_port)
X {
-  int i;
+	int i;
X 
-  if(check_region(io_port, IO_RANGE))
-    return 0;
+	if (check_region(io_port, IO_RANGE))
+		return 0;
X 
-  SETPORT(io_port+O_DMACNTRL1, 0);          /* reset stack pointer */
-  for(i=0; i<16; i++)
-    SETPORT(io_port+O_STACK, i);
+	SETPORT(io_port + O_DMACNTRL1, 0);	/* reset stack pointer */
+	for (i = 0; i < 16; i++)
+		SETPORT(io_port + O_STACK, i);
X 
-  SETPORT(io_port+O_DMACNTRL1, 0);          /* reset stack pointer */
-  for(i=0; i<16 && GETPORT(io_port+O_STACK)==i; i++)
-    ;
+	SETPORT(io_port + O_DMACNTRL1, 0);	/* reset stack pointer */
+	for (i = 0; i < 16 && GETPORT(io_port + O_STACK) == i; i++);
X 
-  return(i==16);
+	return (i == 16);
X }
X 
X int aha152x_checksetup(struct aha152x_setup *setup)
X {
-  int i;
-  
+	int i;
+
X #ifndef PCMCIA
-  for(i=0; i<PORT_COUNT && (setup->io_port != ports[i]); i++)
-    ;
-  
-  if(i==PORT_COUNT)
-    return 0;
-#endif
-  
-  if(!aha152x_porttest(setup->io_port))
-    return 0;
-  
-  if((setup->irq<IRQ_MIN) || (setup->irq>IRQ_MAX))
-    return 0;
-  
-  if((setup->scsiid < 0) || (setup->scsiid > 7))
-    return 0;
-  
-  if((setup->reconnect < 0) || (setup->reconnect > 1))
-    return 0;
-  
-  if((setup->parity < 0) || (setup->parity > 1))
-    return 0;
-  
-  if((setup->synchronous < 0) || (setup->synchronous > 1))
-    return 0;
-
-  if((setup->ext_trans < 0) || (setup->ext_trans > 1))
-    return 0;
-  
-  
-  return 1;
+	for (i = 0; i < PORT_COUNT && (setup->io_port != ports[i]); i++);
+
+	if (i == PORT_COUNT)
+		return 0;
+#endif
+
+	if (!aha152x_porttest(setup->io_port))
+		return 0;
+
+	if ((setup->irq < IRQ_MIN) || (setup->irq > IRQ_MAX))
+		return 0;
+
+	if ((setup->scsiid < 0) || (setup->scsiid > 7))
+		return 0;
+
+	if ((setup->reconnect < 0) || (setup->reconnect > 1))
+		return 0;
+
+	if ((setup->parity < 0) || (setup->parity > 1))
+		return 0;
+
+	if ((setup->synchronous < 0) || (setup->synchronous > 1))
+		return 0;
+
+	if ((setup->ext_trans < 0) || (setup->ext_trans > 1))
+		return 0;
+
+
+	return 1;
X }
X 
-void aha152x_swintr(int irqno, void *dev_id, struct pt_regs * regs)
+void aha152x_swintr(int irqno, void *dev_id, struct pt_regs *regs)
X {
-  struct Scsi_Host *shpnt = aha152x_host[irqno-IRQ_MIN];
+	struct Scsi_Host *shpnt = aha152x_host[irqno - IRQ_MIN];
X 
-  if(!shpnt)
-    panic("aha152x: catched software interrupt for unknown controller.\n");
+	if (!shpnt)
+		panic("aha152x: catched software interrupt for unknown controller.\n");
X 
-  HOSTDATA(shpnt)->swint++;
+	HOSTDATA(shpnt)->swint++;
X }
X 
X 
X int aha152x_detect(Scsi_Host_Template * tpnt)
X {
-  int                 i, j, ok;
+	int i, j, ok;
X #if defined(AUTOCONF)
-  aha152x_config      conf;
+	aha152x_config conf;
X #endif
-  
-  tpnt->proc_dir = &proc_scsi_aha152x;
X 
-  for(i=0; i<IRQS; i++)
-    aha152x_host[i] = (struct Scsi_Host *) NULL;
-  
-  if(setup_count) {
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 23'
echo 'File patch-2.3.10 is continued in part 24'
echo 24 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 24 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 24; 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
-    printk("aha152x: processing commandline: ");
-   
-    for(i=0; i<setup_count; i++)
-      if(!aha152x_checksetup(&setup[i])) {
-        printk("\naha152x: %s\n", setup[i].conf);
-        printk("aha152x: invalid line (controller=%d)\n", i+1);
-      }
-
-      printk("ok\n");
-  }
- 
+	tpnt->proc_dir = &proc_scsi_aha152x;
+
+	for (i = 0; i < IRQS; i++)
+		aha152x_host[i] = (struct Scsi_Host *) NULL;
+
+	if (setup_count) {
+		printk("aha152x: processing commandline: ");
+
+		for (i = 0; i < setup_count; i++)
+			if (!aha152x_checksetup(&setup[i])) {
+				printk("\naha152x: %s\n", setup[i].conf);
+				printk("aha152x: invalid line (controller=%d)\n", i + 1);
+			}
+		printk("ok\n");
+	}
X #ifdef SETUP0
-  if(setup_count<2) {
-    struct aha152x_setup override = SETUP0;
+	if (setup_count < 2) {
+		struct aha152x_setup override = SETUP0;
X 
-    if(setup_count==0 || (override.io_port != setup[0].io_port))
-      if(!aha152x_checksetup(&override)) {
-        printk("\naha152x: invalid override SETUP0={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",
-               override.io_port,
-               override.irq,
-               override.scsiid,
-               override.reconnect,
-               override.parity,
-               override.synchronous,
-               override.delay,
-               override.ext_trans);
-      } else
-        setup[setup_count++] = override;
-  }
+		if (setup_count == 0 || (override.io_port != setup[0].io_port))
+			if (!aha152x_checksetup(&override)) {
+				printk("\naha152x: invalid override SETUP0={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",
+				       override.io_port,
+				       override.irq,
+				       override.scsiid,
+				       override.reconnect,
+				       override.parity,
+				       override.synchronous,
+				       override.delay,
+				       override.ext_trans);
+			} else
+				setup[setup_count++] = override;
+	}
X #endif
X 
X #ifdef SETUP1
-  if(setup_count<2) {
-    struct aha152x_setup override = SETUP1;
+	if (setup_count < 2) {
+		struct aha152x_setup override = SETUP1;
X 
-    if(setup_count==0 || (override.io_port != setup[0].io_port))
-      if(!aha152x_checksetup(&override)) {
-        printk("\naha152x: invalid override SETUP1={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",
-               override.io_port,
-               override.irq,
-               override.scsiid,
-               override.reconnect,
-               override.parity,
-               override.synchronous,
-               override.delay,
-               override.ext_trans);
-      } else
-        setup[setup_count++] = override;
-  }
+		if (setup_count == 0 || (override.io_port != setup[0].io_port))
+			if (!aha152x_checksetup(&override)) {
+				printk("\naha152x: invalid override SETUP1={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",
+				       override.io_port,
+				       override.irq,
+				       override.scsiid,
+				       override.reconnect,
+				       override.parity,
+				       override.synchronous,
+				       override.delay,
+				       override.ext_trans);
+			} else
+				setup[setup_count++] = override;
+	}
X #endif
X 
X #if defined(MODULE)
-  if(setup_count<2 && aha152x[0]!=0) {
-    setup[setup_count].conf        = "";
-    setup[setup_count].io_port     = aha152x[0];
-    setup[setup_count].irq         = aha152x[1];
-    setup[setup_count].scsiid      = aha152x[2];
-    setup[setup_count].reconnect   = aha152x[3];
-    setup[setup_count].parity      = aha152x[4];
-    setup[setup_count].synchronous = aha152x[5];
-    setup[setup_count].delay       = aha152x[6];
-    setup[setup_count].ext_trans   = aha152x[7];
+	if (setup_count < 2 && aha152x[0] != 0) {
+		setup[setup_count].conf = "";
+		setup[setup_count].io_port = aha152x[0];
+		setup[setup_count].irq = aha152x[1];
+		setup[setup_count].scsiid = aha152x[2];
+		setup[setup_count].reconnect = aha152x[3];
+		setup[setup_count].parity = aha152x[4];
+		setup[setup_count].synchronous = aha152x[5];
+		setup[setup_count].delay = aha152x[6];
+		setup[setup_count].ext_trans = aha152x[7];
X #ifdef DEBUG_AHA152X
-    setup[setup_count].debug       = aha152x[8];
+		setup[setup_count].debug = aha152x[8];
X #endif
-    if(aha152x_checksetup(&setup[setup_count]))
-      setup_count++;
-    else
-      printk("\naha152x: invalid module argument aha152x=0x%x,%d,%d,%d,%d,%d,%d,%d\n",
-             setup[setup_count].io_port,
-             setup[setup_count].irq,
-             setup[setup_count].scsiid,
-             setup[setup_count].reconnect,
-             setup[setup_count].parity,
-             setup[setup_count].synchronous,
-             setup[setup_count].delay,
-             setup[setup_count].ext_trans);
-  }
-
-  if(setup_count<2 && aha152x1[0]!=0) {
-    setup[setup_count].conf        = "";
-    setup[setup_count].io_port     = aha152x1[0];
-    setup[setup_count].irq         = aha152x1[1];
-    setup[setup_count].scsiid      = aha152x1[2];
-    setup[setup_count].reconnect   = aha152x1[3];
-    setup[setup_count].parity      = aha152x1[4];
-    setup[setup_count].synchronous = aha152x1[5];
-    setup[setup_count].delay       = aha152x1[6];
-    setup[setup_count].ext_trans   = aha152x1[7];
+		if (aha152x_checksetup(&setup[setup_count]))
+			setup_count++;
+		else
+			printk("\naha152x: invalid module argument aha152x=0x%x,%d,%d,%d,%d,%d,%d,%d\n",
+			       setup[setup_count].io_port,
+			       setup[setup_count].irq,
+			       setup[setup_count].scsiid,
+			       setup[setup_count].reconnect,
+			       setup[setup_count].parity,
+			       setup[setup_count].synchronous,
+			       setup[setup_count].delay,
+			       setup[setup_count].ext_trans);
+	}
+	if (setup_count < 2 && aha152x1[0] != 0) {
+		setup[setup_count].conf = "";
+		setup[setup_count].io_port = aha152x1[0];
+		setup[setup_count].irq = aha152x1[1];
+		setup[setup_count].scsiid = aha152x1[2];
+		setup[setup_count].reconnect = aha152x1[3];
+		setup[setup_count].parity = aha152x1[4];
+		setup[setup_count].synchronous = aha152x1[5];
+		setup[setup_count].delay = aha152x1[6];
+		setup[setup_count].ext_trans = aha152x1[7];
X #ifdef DEBUG_AHA152X
-    setup[setup_count].debug       = aha152x1[8];
+		setup[setup_count].debug = aha152x1[8];
X #endif
-    if(aha152x_checksetup(&setup[setup_count]))
-      setup_count++;
-    else
-      printk("\naha152x: invalid module argument aha152x1=0x%x,%d,%d,%d,%d,%d,%d,%d\n",
-             setup[setup_count].io_port,
-             setup[setup_count].irq,
-             setup[setup_count].scsiid,
-             setup[setup_count].reconnect,
-             setup[setup_count].parity,
-             setup[setup_count].synchronous,
-             setup[setup_count].delay,
-             setup[setup_count].ext_trans);
-  }
+		if (aha152x_checksetup(&setup[setup_count]))
+			setup_count++;
+		else
+			printk("\naha152x: invalid module argument aha152x1=0x%x,%d,%d,%d,%d,%d,%d,%d\n",
+			       setup[setup_count].io_port,
+			       setup[setup_count].irq,
+			       setup[setup_count].scsiid,
+			       setup[setup_count].reconnect,
+			       setup[setup_count].parity,
+			       setup[setup_count].synchronous,
+			       setup[setup_count].delay,
+			       setup[setup_count].ext_trans);
+	}
X #endif
-  
+
X #if defined(AUTOCONF)
-  if(setup_count<2) {
+	if (setup_count < 2) {
X #if !defined(SKIP_BIOSTEST)
-    ok=0;
-    for(i=0; i < ADDRESS_COUNT && !ok; i++)
-      for(j=0; (j < SIGNATURE_COUNT) && !ok; j++)
-      	ok = check_signature(addresses[i]+signatures[j].sig_offset,
-      		signatures[j].signature, signatures[j].sig_length);
+		ok = 0;
+		for (i = 0; i < ADDRESS_COUNT && !ok; i++)
+			for (j = 0; (j < SIGNATURE_COUNT) && !ok; j++)
+				ok = check_signature(addresses[i] + signatures[j].sig_offset,
+						     signatures[j].signature, signatures[j].sig_length);
X 
-    if(!ok && setup_count==0)
-      return 0;
+		if (!ok && setup_count == 0)
+			return 0;
X 
-    printk("aha152x: BIOS test: passed, ");
+		printk("aha152x: BIOS test: passed, ");
X #else
-    printk("aha152x: ");
-#endif /* !SKIP_BIOSTEST */
- 
-    ok=0;
-    for(i=0; i<PORT_COUNT && setup_count<2; i++) {
-      if((setup_count==1) && (setup[0].io_port == ports[i]))
-        continue;
-
-      if(aha152x_porttest(ports[i])) {
-        ok++;
-        setup[setup_count].io_port = ports[i];
-              
-        conf.cf_port =
-          (GETPORT(ports[i]+O_PORTA)<<8) + GETPORT(ports[i]+O_PORTB);
-              
-        setup[setup_count].irq         = IRQ_MIN + conf.cf_irq;
-        setup[setup_count].scsiid      = conf.cf_id;
-        setup[setup_count].reconnect   = conf.cf_tardisc;
-        setup[setup_count].parity      = !conf.cf_parity;
-        setup[setup_count].synchronous = 0 /* FIXME: conf.cf_syncneg */;
-        setup[setup_count].delay       = DELAY_DEFAULT;
-        setup[setup_count].ext_trans   = 0;
+		printk("aha152x: ");
+#endif				/* !SKIP_BIOSTEST */
+
+		ok = 0;
+		for (i = 0; i < PORT_COUNT && setup_count < 2; i++) {
+			if ((setup_count == 1) && (setup[0].io_port == ports[i]))
+				continue;
+
+			if (aha152x_porttest(ports[i])) {
+				ok++;
+				setup[setup_count].io_port = ports[i];
+
+				conf.cf_port =
+				    (GETPORT(ports[i] + O_PORTA) << 8) + GETPORT(ports[i] + O_PORTB);
+
+				setup[setup_count].irq = IRQ_MIN + conf.cf_irq;
+				setup[setup_count].scsiid = conf.cf_id;
+				setup[setup_count].reconnect = conf.cf_tardisc;
+				setup[setup_count].parity = !conf.cf_parity;
+				setup[setup_count].synchronous = 0 /* FIXME: conf.cf_syncneg */ ;
+				setup[setup_count].delay = DELAY_DEFAULT;
+				setup[setup_count].ext_trans = 0;
X #ifdef DEBUG_AHA152X
-        setup[setup_count].debug       = DEBUG_DEFAULT;
+				setup[setup_count].debug = DEBUG_DEFAULT;
X #endif
-        setup_count++;
-      }
-    }
+				setup_count++;
+			}
+		}
X 
-    if(ok)
-      printk("auto configuration: ok, ");
-  }
+		if (ok)
+			printk("auto configuration: ok, ");
+	}
X #endif
X 
-  printk("detected %d controller(s)\n", setup_count);
+	printk("detected %d controller(s)\n", setup_count);
X 
-  for(i=0; i<setup_count; i++) {
-    struct Scsi_Host        *shpnt;
-    unsigned long int       the_time;
+	for (i = 0; i < setup_count; i++) {
+		struct Scsi_Host *shpnt;
+		unsigned long int the_time;
+
+		shpnt = aha152x_host[setup[i].irq - IRQ_MIN] =
+		    scsi_register(tpnt, sizeof(struct aha152x_hostdata));
+		registered_count++;
+
+		shpnt->io_port = setup[i].io_port;
+		shpnt->n_io_port = IO_RANGE;
+		shpnt->irq = setup[i].irq;
+
+		ISSUE_SC = (Scsi_Cmnd *) NULL;
+		CURRENT_SC = (Scsi_Cmnd *) NULL;
+		DISCONNECTED_SC = (Scsi_Cmnd *) NULL;
+
+		HOSTDATA(shpnt)->reconnect = setup[i].reconnect;
+		HOSTDATA(shpnt)->parity = setup[i].parity;
+		HOSTDATA(shpnt)->synchronous = setup[i].synchronous;
+		HOSTDATA(shpnt)->delay = setup[i].delay;
+		HOSTDATA(shpnt)->ext_trans = setup[i].ext_trans;
+#ifdef DEBUG_AHA152X
+		HOSTDATA(shpnt)->debug = setup[i].debug;
+#endif
X 
-    shpnt = aha152x_host[setup[i].irq-IRQ_MIN] =
-      scsi_register(tpnt, sizeof(struct aha152x_hostdata));
-    registered_count++;
+		HOSTDATA(shpnt)->aborting = 0;
+		HOSTDATA(shpnt)->abortion_complete = 0;
+		HOSTDATA(shpnt)->abort_result = 0;
+		HOSTDATA(shpnt)->commands = 0;
+
+		HOSTDATA(shpnt)->message_len = 0;
+
+		for (j = 0; j < 8; j++)
+			HOSTDATA(shpnt)->syncrate[j] = 0;
+
+		SETPORT(SCSIID, setup[i].scsiid << 4);
+		shpnt->this_id = setup[i].scsiid;
+
+		if (setup[i].reconnect)
+			shpnt->can_queue = AHA152X_MAXQUEUE;
+
+		/* RESET OUT */
+		SETBITS(SCSISEQ, SCSIRSTO);
+		do_pause(30);
+		CLRBITS(SCSISEQ, SCSIRSTO);
+		do_pause(setup[i].delay);
+
+		aha152x_reset_ports(shpnt);
+
+		printk("aha152x%d: vital data: PORTBASE=0x%03lx, IRQ=%d, SCSI ID=%d,"
+		       " reconnect=%s, parity=%s, synchronous=%s, delay=%d, extended translation=%s\n",
+		       i,
+		       shpnt->io_port,
+		       shpnt->irq,
+		       shpnt->this_id,
+		     HOSTDATA(shpnt)->reconnect ? "enabled" : "disabled",
+		       HOSTDATA(shpnt)->parity ? "enabled" : "disabled",
+		   HOSTDATA(shpnt)->synchronous ? "enabled" : "disabled",
+		       HOSTDATA(shpnt)->delay,
+		    HOSTDATA(shpnt)->ext_trans ? "enabled" : "disabled");
+
+		request_region(shpnt->io_port, IO_RANGE, "aha152x");	/* Register */
+
+		/* not expecting any interrupts */
+		SETPORT(SIMODE0, 0);
+		SETPORT(SIMODE1, 0);
+
+		SETBITS(DMACNTRL0, INTEN);
+
+		ok = request_irq(shpnt->irq, aha152x_swintr, SA_INTERRUPT, "aha152x", shpnt);
+		if (ok < 0) {
+			if (ok == -EINVAL)
+				printk("aha152x%d: bad IRQ %d.\n", i, shpnt->irq);
+			else if (ok == -EBUSY)
+				printk("aha152x%d: IRQ %d already in use.\n", i, shpnt->irq);
+			else
+				printk("\naha152x%d: Unexpected error code %d on requesting IRQ %d.\n", i, ok, shpnt->irq);
+			printk("aha152x: driver needs an IRQ.\n");
+
+			scsi_unregister(shpnt);
+			registered_count--;
+			release_region(shpnt->io_port, IO_RANGE);
+			shpnt = aha152x_host[shpnt->irq - IRQ_MIN] = 0;
+			continue;
+		}
+		HOSTDATA(shpnt)->swint = 0;
X 
-    shpnt->io_port                     = setup[i].io_port;
-    shpnt->n_io_port                   = IO_RANGE;
-    shpnt->irq                         = setup[i].irq;
+		printk("aha152x: trying software interrupt, ");
+		SETBITS(DMACNTRL0, SWINT);
X 
-    ISSUE_SC                           = (Scsi_Cmnd *) NULL;
-    CURRENT_SC                         = (Scsi_Cmnd *) NULL;
-    DISCONNECTED_SC                    = (Scsi_Cmnd *) NULL;
+		the_time = jiffies + 100;
+		while (!HOSTDATA(shpnt)->swint && time_before(jiffies, the_time))
+			barrier();
+
+		free_irq(shpnt->irq, shpnt);
+
+		if (!HOSTDATA(shpnt)->swint) {
+			if (TESTHI(DMASTAT, INTSTAT)) {
+				printk("lost.\n");
+			} else {
+				printk("failed.\n");
+			}
+
+			printk("aha152x: IRQ %d possibly wrong.  Please verify.\n", shpnt->irq);
+
+			scsi_unregister(shpnt);
+			registered_count--;
+			release_region(shpnt->io_port, IO_RANGE);
+			shpnt = aha152x_host[shpnt->irq - IRQ_MIN] = 0;
+			continue;
+		}
+		printk("ok.\n");
X 
-    HOSTDATA(shpnt)->reconnect         = setup[i].reconnect;
-    HOSTDATA(shpnt)->parity            = setup[i].parity;
-    HOSTDATA(shpnt)->synchronous       = setup[i].synchronous;
-    HOSTDATA(shpnt)->delay             = setup[i].delay;
-    HOSTDATA(shpnt)->ext_trans         = setup[i].ext_trans;
-#ifdef DEBUG_AHA152X
-    HOSTDATA(shpnt)->debug             = setup[i].debug;
-#endif
+		CLRBITS(DMACNTRL0, SWINT);
X 
-    HOSTDATA(shpnt)->aborting          = 0;
-    HOSTDATA(shpnt)->abortion_complete = 0;
-    HOSTDATA(shpnt)->abort_result      = 0;
-    HOSTDATA(shpnt)->commands          = 0;
-
-    HOSTDATA(shpnt)->message_len       = 0;
-
-    for(j=0; j<8; j++)
-      HOSTDATA(shpnt)->syncrate[j] = 0;
- 
-    SETPORT(SCSIID, setup[i].scsiid << 4);
-    shpnt->this_id=setup[i].scsiid;
-  
-    if(setup[i].reconnect)
-      shpnt->can_queue=AHA152X_MAXQUEUE;
-
-    /* RESET OUT */
-    SETBITS(SCSISEQ, SCSIRSTO);
-    do_pause(30);
-    CLRBITS(SCSISEQ, SCSIRSTO);
-    do_pause(setup[i].delay);
-
-    aha152x_reset_ports(shpnt);
-      
-    printk("aha152x%d: vital data: PORTBASE=0x%03lx, IRQ=%d, SCSI ID=%d,"
-           " reconnect=%s, parity=%s, synchronous=%s, delay=%d, extended translation=%s\n",
-           i,
-           shpnt->io_port,
-           shpnt->irq,
-           shpnt->this_id,
-           HOSTDATA(shpnt)->reconnect ? "enabled" : "disabled",
-           HOSTDATA(shpnt)->parity ? "enabled" : "disabled",
-           HOSTDATA(shpnt)->synchronous ? "enabled" : "disabled",
-           HOSTDATA(shpnt)->delay,
-           HOSTDATA(shpnt)->ext_trans ? "enabled" : "disabled");
-
-    request_region(shpnt->io_port, IO_RANGE, "aha152x");  /* Register */
-  
-    /* not expecting any interrupts */
-    SETPORT(SIMODE0, 0);
-    SETPORT(SIMODE1, 0);
-
-    SETBITS(DMACNTRL0, INTEN);
-
-    ok = request_irq(shpnt->irq, aha152x_swintr, SA_INTERRUPT, "aha152x", shpnt);
-    if(ok<0) {
-      if(ok == -EINVAL)
-        printk("aha152x%d: bad IRQ %d.\n", i, shpnt->irq);
-      else if(ok == -EBUSY)
-        printk("aha152x%d: IRQ %d already in use.\n", i, shpnt->irq);
-      else
-        printk("\naha152x%d: Unexpected error code %d on requesting IRQ %d.\n",                 i, ok, shpnt->irq);
-      printk("aha152x: driver needs an IRQ.\n");
-
-      scsi_unregister(shpnt);
-      registered_count--;
-      release_region(shpnt->io_port, IO_RANGE);
-      shpnt=aha152x_host[shpnt->irq-IRQ_MIN]=0;
-      continue;
-    }
-
-    HOSTDATA(shpnt)->swint=0;
-
-    printk("aha152x: trying software interrupt, ");
-    SETBITS(DMACNTRL0, SWINT);
-
-    the_time=jiffies+100;
-    while(!HOSTDATA(shpnt)->swint && time_before(jiffies, the_time))
-      barrier();
-
-    free_irq(shpnt->irq,shpnt);
-
-    if(!HOSTDATA(shpnt)->swint) {
-      if(TESTHI(DMASTAT, INTSTAT)) {
-        printk("lost.\n");
-      } else {
-        printk("failed.\n");
-      }
-
-      printk("aha152x: IRQ %d possibly wrong.  Please verify.\n", shpnt->irq);
-
-      scsi_unregister(shpnt);
-      registered_count--;
-      release_region(shpnt->io_port, IO_RANGE);
-      shpnt=aha152x_host[shpnt->irq-IRQ_MIN]=0;
-      continue;
-    }
-
-    printk("ok.\n");
-
-    CLRBITS(DMACNTRL0, SWINT);
-
-    /* clear interrupts */
-    SETPORT(SSTAT0, 0x7f);
-    SETPORT(SSTAT1, 0xef);
-
-    if(request_irq(shpnt->irq,aha152x_intr,SA_INTERRUPT,"aha152x",shpnt)<0) {
-      printk("aha152x: failed to reassign interrupt.\n");
-    }
-  }
-  
-  return (registered_count>0);
+		/* clear interrupts */
+		SETPORT(SSTAT0, 0x7f);
+		SETPORT(SSTAT1, 0xef);
+
+		if (request_irq(shpnt->irq, aha152x_intr, SA_INTERRUPT, "aha152x", shpnt) < 0) {
+			printk("aha152x: failed to reassign interrupt.\n");
+		}
+	}
+
+	return (registered_count > 0);
X }
X 
X 
X int aha152x_release(struct Scsi_Host *shpnt)
X {
-  if (shpnt->irq)
-    free_irq(shpnt->irq, shpnt);
-  if (shpnt->io_port)
-    release_region(shpnt->io_port, IO_RANGE);
+	if (shpnt->irq)
+		free_irq(shpnt->irq, shpnt);
+	if (shpnt->io_port)
+		release_region(shpnt->io_port, IO_RANGE);
X 
-  return 0;
+	return 0;
X }
X 
X /* 
X  *  Queue a command and setup interrupts for a free bus.
X  */
-int aha152x_queue(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
+int aha152x_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
X {
-  struct Scsi_Host *shpnt = SCpnt->host;
-  unsigned long flags;
+	struct Scsi_Host *shpnt = SCpnt->host;
+	unsigned long flags;
X 
X #if defined(DEBUG_RACE)
-  enter_driver("queue");
+	enter_driver("queue");
X #else
X #if defined(DEBUG_QUEUE)
-  if(HOSTDATA(shpnt)->debug & debug_queue)
-    printk("aha152x: queue(), ");
+	if (HOSTDATA(shpnt)->debug & debug_queue)
+		printk("aha152x: queue(), ");
X #endif
X #endif
X 
X #if defined(DEBUG_QUEUE)
-  if(HOSTDATA(shpnt)->debug & debug_queue) {
-    printk("SCpnt (target = %d lun = %d cmnd = ",
-           SCpnt->target, SCpnt->lun);
-    print_command(SCpnt->cmnd);
-    printk(", cmd_len=%d, pieces = %d size = %u), ",
-           SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen);
-    disp_ports(shpnt);
-  }
-#endif
-
-  SCpnt->scsi_done =       done;
-
-  /* setup scratch area
-     SCp.ptr              : buffer pointer
-     SCp.this_residual    : buffer length
-     SCp.buffer           : next buffer
-     SCp.buffers_residual : left buffers in list
-     SCp.phase            : current state of the command */
-  SCpnt->SCp.phase = not_issued;
-  if (SCpnt->use_sg) {
-    SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
-    SCpnt->SCp.ptr              = SCpnt->SCp.buffer->address;
-    SCpnt->SCp.this_residual    = SCpnt->SCp.buffer->length;
-    SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
-  } else {
-    SCpnt->SCp.ptr              = (char *)SCpnt->request_buffer;
-    SCpnt->SCp.this_residual    = SCpnt->request_bufflen;
-    SCpnt->SCp.buffer           = NULL;
-    SCpnt->SCp.buffers_residual = 0;
-  }
-          
-  SCpnt->SCp.Status              = CHECK_CONDITION;
-  SCpnt->SCp.Message             = 0;
-  SCpnt->SCp.have_data_in        = 0;
-  SCpnt->SCp.sent_command        = 0;
-
-  /* Turn led on, when this is the first command. */
-  save_flags(flags);
-  cli();
-  HOSTDATA(shpnt)->commands++;
-  if(HOSTDATA(shpnt)->commands==1)
-    SETPORT(PORTA, 1);
+	if (HOSTDATA(shpnt)->debug & debug_queue) {
+		printk("SCpnt (target = %d lun = %d cmnd = ",
+		       SCpnt->target, SCpnt->lun);
+		print_command(SCpnt->cmnd);
+		printk(", cmd_len=%d, pieces = %d size = %u), ",
+		  SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen);
+		disp_ports(shpnt);
+	}
+#endif
+
+	SCpnt->scsi_done = done;
+
+	/* setup scratch area
+	   SCp.ptr              : buffer pointer
+	   SCp.this_residual    : buffer length
+	   SCp.buffer           : next buffer
+	   SCp.buffers_residual : left buffers in list
+	   SCp.phase            : current state of the command */
+	SCpnt->SCp.phase = not_issued;
+	if (SCpnt->use_sg) {
+		SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
+		SCpnt->SCp.ptr = SCpnt->SCp.buffer->address;
+		SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
+		SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
+	} else {
+		SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
+		SCpnt->SCp.this_residual = SCpnt->request_bufflen;
+		SCpnt->SCp.buffer = NULL;
+		SCpnt->SCp.buffers_residual = 0;
+	}
+
+	SCpnt->SCp.Status = CHECK_CONDITION;
+	SCpnt->SCp.Message = 0;
+	SCpnt->SCp.have_data_in = 0;
+	SCpnt->SCp.sent_command = 0;
+
+	/* Turn led on, when this is the first command. */
+	save_flags(flags);
+	cli();
+	HOSTDATA(shpnt)->commands++;
+	if (HOSTDATA(shpnt)->commands == 1)
+		SETPORT(PORTA, 1);
X 
X #if defined(DEBUG_QUEUES)
-  if(HOSTDATA(shpnt)->debug & debug_queues)
-    printk("i+ (%d), ", HOSTDATA(shpnt)->commands);
+	if (HOSTDATA(shpnt)->debug & debug_queues)
+		printk("i+ (%d), ", HOSTDATA(shpnt)->commands);
X #endif
-  append_SC(&ISSUE_SC, SCpnt);
-  
-  /* Enable bus free interrupt, when we aren't currently on the bus */
-  if(!CURRENT_SC) {
-    SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
-    SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
-  }
-  restore_flags(flags);
+	append_SC(&ISSUE_SC, SCpnt);
+
+	/* Enable bus free interrupt, when we aren't currently on the bus */
+	if (!CURRENT_SC) {
+		SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
+		SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
+	}
+	restore_flags(flags);
X 
X #if defined(DEBUG_RACE)
-  leave_driver("queue");
+	leave_driver("queue");
X #endif
X 
-  return 0;
+	return 0;
X }
X 
X /*
X  *  We only support commands in interrupt-driven fashion
X  */
-int aha152x_command(Scsi_Cmnd *SCpnt)
+int aha152x_command(Scsi_Cmnd * SCpnt)
X {
-  printk("aha152x: interrupt driven driver; use aha152x_queue()\n");
-  return -1;
+	printk("aha152x: interrupt driven driver; use aha152x_queue()\n");
+	return -1;
X }
X 
X /*
X  *  Abort a queued command
X  *  (commands that are on the bus can't be aborted easily)
X  */
-int aha152x_abort(Scsi_Cmnd *SCpnt)
+int aha152x_abort(Scsi_Cmnd * SCpnt)
X {
-  struct Scsi_Host *shpnt = SCpnt->host;
-  unsigned long flags;
-  Scsi_Cmnd *ptr, *prev;
+	struct Scsi_Host *shpnt = SCpnt->host;
+	unsigned long flags;
+	Scsi_Cmnd *ptr, *prev;
X 
-  save_flags(flags);
-  cli();
+	save_flags(flags);
+	cli();
X 
X #if defined(DEBUG_ABORT)
-  if(HOSTDATA(shpnt)->debug & debug_abort) { 
-    printk("aha152x: abort(), SCpnt=0x%08x, ", (unsigned int) SCpnt);
-    show_queues(shpnt);
-  }
-#endif
-
-  /* look for command in issue queue */
-  for(ptr=ISSUE_SC, prev=NULL;
-       ptr && ptr!=SCpnt;
-       prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble)
-    ;
-
-  if(ptr) {
-    /* dequeue */
-    if(prev)
-      prev->host_scribble = ptr->host_scribble;
-    else
-      ISSUE_SC = (Scsi_Cmnd *) ptr->host_scribble;
-
-    HOSTDATA(shpnt)->commands--; 
-
-    restore_flags(flags);
-
-    ptr->host_scribble = NULL;
-    ptr->result = DID_ABORT << 16;
-    ptr->scsi_done(ptr);
-
-    return SCSI_ABORT_SUCCESS;
-  }
-
-  /* if the bus is busy or a command is currently processed,
-     we can't do anything more */
-  if (TESTLO(SSTAT1, BUSFREE) || (CURRENT_SC && CURRENT_SC!=SCpnt)) {
-    /* fail abortion, if bus is busy */
-
-    if(!CURRENT_SC)
-      printk("bus busy w/o current command, ");
- 
-    restore_flags(flags);
-
-    return SCSI_ABORT_BUSY;
-  }
-
-  /* bus is free */
-
-  if(CURRENT_SC) { 
-    HOSTDATA(shpnt)->commands--; 
-
-    /* target entered bus free before COMMAND COMPLETE, nothing to abort */
-    restore_flags(flags);
-    CURRENT_SC->result = DID_ERROR << 16;
-    CURRENT_SC->scsi_done(CURRENT_SC);
-    CURRENT_SC = (Scsi_Cmnd *) NULL;
-
-    return SCSI_ABORT_SUCCESS;
-  }
-
-  /* look for command in disconnected queue */
-  for(ptr=DISCONNECTED_SC, prev=NULL;
-       ptr && ptr!=SCpnt;
-       prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble)
-    ;
-
-  if(!ptr) {
-    /* command wasn't found */
-    printk("command not found\n");
-    restore_flags(flags);
-
-    return SCSI_ABORT_NOT_RUNNING;
-  }
-
-  if(!HOSTDATA(shpnt)->aborting) {
-    /* dequeue */
-    if(prev)
-      prev->host_scribble = ptr->host_scribble;
-    else
-      DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble;
-
-    HOSTDATA(shpnt)->commands--; 
-
-    /* set command current and initiate selection,
-       let the interrupt routine take care of the abortion */
-    CURRENT_SC     = ptr;
-    ptr->SCp.phase = in_selection|aborted;
-    SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target);
-      
-    ADDMSG(ABORT);
-
-    /* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */
-    SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));
-    SETPORT(SIMODE1, ENSELTIMO);
-
-    /* Enable SELECTION OUT sequence */
-    SETBITS(SCSISEQ, ENSELO | ENAUTOATNO);
-
-    SETBITS(DMACNTRL0, INTEN);
-    HOSTDATA(shpnt)->abort_result=SCSI_ABORT_SUCCESS;
-    HOSTDATA(shpnt)->aborting++;
-    HOSTDATA(shpnt)->abortion_complete=0;
-
-    restore_flags(flags);
-
-    /* sleep until the abortion is complete */
-    while(!HOSTDATA(shpnt)->abortion_complete)
-      barrier();
-    HOSTDATA(shpnt)->aborting=0;
-
-    return HOSTDATA(shpnt)->abort_result;
-  } else {
-    /* we're already aborting a command */
-    restore_flags(flags);
+	if (HOSTDATA(shpnt)->debug & debug_abort) {
+		printk("aha152x: abort(), SCpnt=0x%08x, ", (unsigned int) SCpnt);
+		show_queues(shpnt);
+	}
+#endif
+
+	/* look for command in issue queue */
+	for (ptr = ISSUE_SC, prev = NULL;
+	     ptr && ptr != SCpnt;
+	     prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble);
+
+	if (ptr) {
+		/* dequeue */
+		if (prev)
+			prev->host_scribble = ptr->host_scribble;
+		else
+			ISSUE_SC = (Scsi_Cmnd *) ptr->host_scribble;
+
+		HOSTDATA(shpnt)->commands--;
+
+		restore_flags(flags);
+
+		ptr->host_scribble = NULL;
+		ptr->result = DID_ABORT << 16;
+		spin_lock_irqsave(&io_request_lock, flags);
+		ptr->scsi_done(ptr);
+		spin_unlock_irqrestore(&io_request_lock, flags);
+
+		return SCSI_ABORT_SUCCESS;
+	}
+	/* if the bus is busy or a command is currently processed,
+	   we can't do anything more */
+	if (TESTLO(SSTAT1, BUSFREE) || (CURRENT_SC && CURRENT_SC != SCpnt)) {
+		/* fail abortion, if bus is busy */
+
+		if (!CURRENT_SC)
+			printk("bus busy w/o current command, ");
+
+		restore_flags(flags);
+
+		return SCSI_ABORT_BUSY;
+	}
+	/* bus is free */
+
+	if (CURRENT_SC) {
+		HOSTDATA(shpnt)->commands--;
+
+		/* target entered bus free before COMMAND COMPLETE, nothing to abort */
+		restore_flags(flags);
+		spin_lock_irqsave(&io_request_lock, flags);
+		CURRENT_SC->result = DID_ERROR << 16;
+		CURRENT_SC->scsi_done(CURRENT_SC);
+		CURRENT_SC = (Scsi_Cmnd *) NULL;
+		spin_unlock_irqrestore(&io_request_lock, flags);
+
+		return SCSI_ABORT_SUCCESS;
+	}
+	/* look for command in disconnected queue */
+	for (ptr = DISCONNECTED_SC, prev = NULL;
+	     ptr && ptr != SCpnt;
+	     prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble);
+
+	if (!ptr) {
+		/* command wasn't found */
+		printk("command not found\n");
+		restore_flags(flags);
+
+		return SCSI_ABORT_NOT_RUNNING;
+	}
+	if (!HOSTDATA(shpnt)->aborting) {
+		/* dequeue */
+		if (prev)
+			prev->host_scribble = ptr->host_scribble;
+		else
+			DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble;
+
+		HOSTDATA(shpnt)->commands--;
+
+		/* set command current and initiate selection,
+		   let the interrupt routine take care of the abortion */
+		CURRENT_SC = ptr;
+		ptr->SCp.phase = in_selection | aborted;
+		SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target);
+
+		ADDMSG(ABORT);
+
+		/* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */
+		SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));
+		SETPORT(SIMODE1, ENSELTIMO);
+
+		/* Enable SELECTION OUT sequence */
+		SETBITS(SCSISEQ, ENSELO | ENAUTOATNO);
+
+		SETBITS(DMACNTRL0, INTEN);
+		HOSTDATA(shpnt)->abort_result = SCSI_ABORT_SUCCESS;
+		HOSTDATA(shpnt)->aborting++;
+		HOSTDATA(shpnt)->abortion_complete = 0;
+
+		restore_flags(flags);
+
+		/* sleep until the abortion is complete */
+		while (!HOSTDATA(shpnt)->abortion_complete)
+			barrier();
+		HOSTDATA(shpnt)->aborting = 0;
+
+		return HOSTDATA(shpnt)->abort_result;
+	} else {
+		/* we're already aborting a command */
+		restore_flags(flags);
X 
-    return SCSI_ABORT_BUSY;
-  }
+		return SCSI_ABORT_BUSY;
+	}
X }
X 
X /*
@@ -1319,110 +1338,113 @@
X  */
X static void aha152x_reset_ports(struct Scsi_Host *shpnt)
X {
-  /* disable interrupts */
-  SETPORT(DMACNTRL0, RSTFIFO);
+	/* disable interrupts */
+	SETPORT(DMACNTRL0, RSTFIFO);
X 
-  SETPORT(SCSISEQ, 0);
+	SETPORT(SCSISEQ, 0);
X 
-  SETPORT(SXFRCTL1, 0);
-  SETPORT(SCSISIG, 0);
-  SETPORT(SCSIRATE, 0);
+	SETPORT(SXFRCTL1, 0);
+	SETPORT(SCSISIG, 0);
+	SETPORT(SCSIRATE, 0);
X 
-  /* clear all interrupt conditions */
-  SETPORT(SSTAT0, 0x7f);
-  SETPORT(SSTAT1, 0xef);
+	/* clear all interrupt conditions */
+	SETPORT(SSTAT0, 0x7f);
+	SETPORT(SSTAT1, 0xef);
X 
-  SETPORT(SSTAT4, SYNCERR|FWERR|FRERR);
+	SETPORT(SSTAT4, SYNCERR | FWERR | FRERR);
X 
-  SETPORT(DMACNTRL0, 0);
-  SETPORT(DMACNTRL1, 0);
+	SETPORT(DMACNTRL0, 0);
+	SETPORT(DMACNTRL1, 0);
X 
-  SETPORT(BRSTCNTRL, 0xf1);
+	SETPORT(BRSTCNTRL, 0xf1);
X 
-  /* clear SCSI fifo and transfer count */
-  SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);
-  SETPORT(SXFRCTL0, CH1);
+	/* clear SCSI fifo and transfer count */
+	SETPORT(SXFRCTL0, CH1 | CLRCH1 | CLRSTCNT);
+	SETPORT(SXFRCTL0, CH1);
X 
-  /* enable interrupts */
-  SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
-  SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
+	/* enable interrupts */
+	SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
+	SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
X }
X 
X /*
X  *  Reset registers, reset a hanging bus and
X  *  kill active and disconnected commands for target w/o soft reset
X  */
-int aha152x_reset(Scsi_Cmnd *SCpnt, unsigned int unused)
+int aha152x_reset(Scsi_Cmnd * SCpnt, unsigned int unused)
X {
-  struct Scsi_Host *shpnt = SCpnt->host;
-  unsigned long flags;
-  Scsi_Cmnd *ptr, *prev, *next;
+	struct Scsi_Host *shpnt = SCpnt->host;
+	unsigned long flags;
+	Scsi_Cmnd *ptr, *prev, *next;
X 
-  aha152x_reset_ports(shpnt);
+	aha152x_reset_ports(shpnt);
X 
-  /* Reset, if bus hangs */
-  if(TESTLO(SSTAT1, BUSFREE)) {
-    CLRBITS(DMACNTRL0, INTEN);
+	/* Reset, if bus hangs */
+	if (TESTLO(SSTAT1, BUSFREE)) {
+		CLRBITS(DMACNTRL0, INTEN);
X 
X #if defined(DEBUG_RESET)
-    if(HOSTDATA(shpnt)->debug & debug_reset) {
-      printk("aha152x: reset(), bus not free: SCSI RESET OUT\n");
-      show_queues(shpnt);
-    }
-#endif
-
-    ptr=CURRENT_SC;
-    if(ptr && !ptr->device->soft_reset) {
-      ptr->host_scribble = NULL;
-      ptr->result = DID_RESET << 16;
-      ptr->scsi_done(CURRENT_SC);
-      CURRENT_SC=NULL;
-    }
-
-    save_flags(flags);
-    cli();
-    prev=NULL; ptr=DISCONNECTED_SC;
-    while(ptr) {
-      if(!ptr->device->soft_reset) {
-        if(prev)
-          prev->host_scribble = ptr->host_scribble;
-        else
-          DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble;
-
-        next = (Scsi_Cmnd *) ptr->host_scribble;
-
-        ptr->host_scribble = NULL;
-        ptr->result        = DID_RESET << 16;
-        ptr->scsi_done(ptr);
-  
-        ptr = next; 
-      } else {
-        prev=ptr;
-        ptr = (Scsi_Cmnd *) ptr->host_scribble;
-      }
-    }
-    restore_flags(flags);
+		if (HOSTDATA(shpnt)->debug & debug_reset) {
+			printk("aha152x: reset(), bus not free: SCSI RESET OUT\n");
+			show_queues(shpnt);
+		}
+#endif
+
+		ptr = CURRENT_SC;
+		if (ptr && !ptr->device->soft_reset) {
+			ptr->host_scribble = NULL;
+			ptr->result = DID_RESET << 16;
+			spin_lock_irqsave(&io_request_lock, flags);
+			ptr->scsi_done(CURRENT_SC);
+			spin_unlock_irqrestore(&io_request_lock, flags);
+			CURRENT_SC = NULL;
+		}
+		save_flags(flags);
+		cli();
+		prev = NULL;
+		ptr = DISCONNECTED_SC;
+		while (ptr) {
+			if (!ptr->device->soft_reset) {
+				if (prev)
+					prev->host_scribble = ptr->host_scribble;
+				else
+					DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble;
+
+				next = (Scsi_Cmnd *) ptr->host_scribble;
+
+				ptr->host_scribble = NULL;
+				ptr->result = DID_RESET << 16;
+				spin_lock_irqsave(&io_request_lock, flags);
+				ptr->scsi_done(ptr);
+				spin_unlock_irqrestore(&io_request_lock, flags);
+
+				ptr = next;
+			} else {
+				prev = ptr;
+				ptr = (Scsi_Cmnd *) ptr->host_scribble;
+			}
+		}
+		restore_flags(flags);
X 
X #if defined(DEBUG_RESET)
-    if(HOSTDATA(shpnt)->debug & debug_reset) {
-      printk("commands on targets w/ soft-resets:\n");
-      show_queues(shpnt);
-    }
+		if (HOSTDATA(shpnt)->debug & debug_reset) {
+			printk("commands on targets w/ soft-resets:\n");
+			show_queues(shpnt);
+		}
X #endif
X 
-    /* RESET OUT */
-    SETPORT(SCSISEQ, SCSIRSTO);
-    do_pause(30);
-    SETPORT(SCSISEQ, 0);
-    do_pause(DELAY);
-
-    SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
-    SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
+		/* RESET OUT */
+		SETPORT(SCSISEQ, SCSIRSTO);
+		do_pause(30);
+		SETPORT(SCSISEQ, 0);
+		do_pause(DELAY);
X 
-    SETPORT(DMACNTRL0, INTEN);
-  }
+		SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
+		SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
X 
-  return SCSI_RESET_SUCCESS;
+		SETPORT(DMACNTRL0, INTEN);
+	}
+	return SCSI_RESET_SUCCESS;
X }
X 
X /*
@@ -1430,59 +1452,58 @@
X  */
X int aha152x_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array)
X {
-  struct Scsi_Host *shpnt=disk->device->host;
+	struct Scsi_Host *shpnt = disk->device->host;
X 
X #if defined(DEBUG_BIOSPARAM)
-  if(HOSTDATA(shpnt)->debug & debug_biosparam)
-    printk("aha152x_biosparam: dev=%s, size=%d, ",
-           kdevname(dev), disk->capacity);
-#endif
- 
-  /* try default translation */
-  info_array[0]=64;
-  info_array[1]=32;
-  info_array[2]=disk->capacity / (64 * 32);
-
-  /* for disks >1GB do some guessing */
-  if(info_array[2]>=1024) {
-    int info[3];
-
-    /* try to figure out the geometry from the partition table */
-    if(scsicam_bios_param(disk, dev, info)<0 ||
-       !((info[0]==64 && info[1]==32) || (info[0]==255 && info[1]==63))) {
-      if(EXT_TRANS) {
-        printk("aha152x: unable to verify geometry for disk with >1GB.\n"
-               "         using extended translation.\n");
-        info_array[0] = 255;
-        info_array[1] = 63;
-        info_array[2] = disk->capacity / (255 * 63);
-      } else {
-        printk("aha152x: unable to verify geometry for disk with >1GB.\n"
-               "         Using default translation. Please verify yourself.\n"
-               "         Perhaps you need to enable extended translation in the driver.\n"
-               "         See /usr/src/linux/drivers/scsi/aha152x.c for details.\n");
-      }
-    } else {
-      info_array[0]=info[0];
-      info_array[1]=info[1];
-      info_array[2]=info[2];
-      
-      if(info[0]==255 && !EXT_TRANS) {
-        printk("aha152x: current partition table is using extended translation.\n"
-               "         using it also, although it's not explicty enabled.\n");
-      }
-    }
-  }
-
+	if (HOSTDATA(shpnt)->debug & debug_biosparam)
+		printk("aha152x_biosparam: dev=%s, size=%d, ",
+		       kdevname(dev), disk->capacity);
+#endif
+
+	/* try default translation */
+	info_array[0] = 64;
+	info_array[1] = 32;
+	info_array[2] = disk->capacity / (64 * 32);
+
+	/* for disks >1GB do some guessing */
+	if (info_array[2] >= 1024) {
+		int info[3];
+
+		/* try to figure out the geometry from the partition table */
+		if (scsicam_bios_param(disk, dev, info) < 0 ||
+		    !((info[0] == 64 && info[1] == 32) || (info[0] == 255 && info[1] == 63))) {
+			if (EXT_TRANS) {
+				printk("aha152x: unable to verify geometry for disk with >1GB.\n"
+				"         using extended translation.\n");
+				info_array[0] = 255;
+				info_array[1] = 63;
+				info_array[2] = disk->capacity / (255 * 63);
+			} else {
+				printk("aha152x: unable to verify geometry for disk with >1GB.\n"
+				       "         Using default translation. Please verify yourself.\n"
+				       "         Perhaps you need to enable extended translation in the driver.\n"
+				       "         See /usr/src/linux/drivers/scsi/aha152x.c for details.\n");
+			}
+		} else {
+			info_array[0] = info[0];
+			info_array[1] = info[1];
+			info_array[2] = info[2];
+
+			if (info[0] == 255 && !EXT_TRANS) {
+				printk("aha152x: current partition table is using extended translation.\n"
+				       "         using it also, although it's not explicty enabled.\n");
+			}
+		}
+	}
X #if defined(DEBUG_BIOSPARAM)
-  if(HOSTDATA(shpnt)->debug & debug_biosparam) {
-    printk("bios geometry: head=%d, sec=%d, cyl=%d\n",
-           info_array[0], info_array[1], info_array[2]);
-    printk("WARNING: check, if the bios geometry is correct.\n");
-  }
+	if (HOSTDATA(shpnt)->debug & debug_biosparam) {
+		printk("bios geometry: head=%d, sec=%d, cyl=%d\n",
+		       info_array[0], info_array[1], info_array[2]);
+		printk("WARNING: check, if the bios geometry is correct.\n");
+	}
X #endif
X 
-  return 0;
+	return 0;
X }
X 
X /*
@@ -1490,71 +1511,73 @@
X  */
X void aha152x_done(struct Scsi_Host *shpnt, int error)
X {
-  unsigned long flags;
-  Scsi_Cmnd *done_SC;
+	unsigned long flags;
+	Scsi_Cmnd *done_SC;
X 
X #if defined(DEBUG_DONE)
-  if(HOSTDATA(shpnt)->debug & debug_done) {
-    printk("\naha152x: done(), ");
-    disp_ports(shpnt);
-  }
+	if (HOSTDATA(shpnt)->debug & debug_done) {
+		printk("\naha152x: done(), ");
+		disp_ports(shpnt);
+	}
X #endif
X 
-  if(CURRENT_SC) {
+	if (CURRENT_SC) {
X #if defined(DEBUG_DONE)
-    if(HOSTDATA(shpnt)->debug & debug_done)
-      printk("done(%x), ", error);
+		if (HOSTDATA(shpnt)->debug & debug_done)
+			printk("done(%x), ", error);
X #endif
X 
-    save_flags(flags);
-    cli();
+		save_flags(flags);
+		cli();
X 
-    done_SC = CURRENT_SC;
-    CURRENT_SC = NULL;
+		done_SC = CURRENT_SC;
+		CURRENT_SC = NULL;
X 
-    /* turn led off, when no commands are in the driver */
-    HOSTDATA(shpnt)->commands--;
-    if(!HOSTDATA(shpnt)->commands)
-      SETPORT(PORTA, 0);                                  /* turn led off */
+		/* turn led off, when no commands are in the driver */
+		HOSTDATA(shpnt)->commands--;
+		if (!HOSTDATA(shpnt)->commands)
+			SETPORT(PORTA, 0);	/* turn led off */
X 
X #if defined(DEBUG_QUEUES)
-    if(HOSTDATA(shpnt)->debug & debug_queues) 
-      printk("ok (%d), ", HOSTDATA(shpnt)->commands);
+		if (HOSTDATA(shpnt)->debug & debug_queues)
+			printk("ok (%d), ", HOSTDATA(shpnt)->commands);
X #endif
-    restore_flags(flags);
+		restore_flags(flags);
X 
-    SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
-    SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
+		SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
+		SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
X 
X #if 0
X /* Why poll for the BUS FREE phase, when we have setup the interrupt!? */
X #if defined(DEBUG_PHASES)
-    if(HOSTDATA(shpnt)->debug & debug_phases)
-      printk("BUS FREE loop, ");
+		if (HOSTDATA(shpnt)->debug & debug_phases)
+			printk("BUS FREE loop, ");
X #endif
-    while(TESTLO(SSTAT1, BUSFREE))
-      barrier();
+		while (TESTLO(SSTAT1, BUSFREE))
+			barrier();
X #if defined(DEBUG_PHASES)
-    if(HOSTDATA(shpnt)->debug & debug_phases)
-      printk("BUS FREE\n");
+		if (HOSTDATA(shpnt)->debug & debug_phases)
+			printk("BUS FREE\n");
X #endif
X #endif
X 
-    done_SC->result = error;
-    if(done_SC->scsi_done) {
+		done_SC->result = error;
+		if (done_SC->scsi_done) {
X #if defined(DEBUG_DONE)
-      if(HOSTDATA(shpnt)->debug & debug_done)
-        printk("calling scsi_done, ");
+			if (HOSTDATA(shpnt)->debug & debug_done)
+				printk("calling scsi_done, ");
X #endif
-      done_SC->scsi_done(done_SC);
+			spin_lock_irqsave(&io_request_lock, flags);
+			done_SC->scsi_done(done_SC);
+			spin_unlock_irqrestore(&io_request_lock, flags);
X #if defined(DEBUG_DONE)
-      if(HOSTDATA(shpnt)->debug & debug_done)
-        printk("done returned, ");
+			if (HOSTDATA(shpnt)->debug & debug_done)
+				printk("done returned, ");
X #endif
-    } else
-       panic("aha152x: current_SC->scsi_done() == NULL");
-  } else
-    aha152x_panic(shpnt, "done() called outside of command");
+		} else
+			panic("aha152x: current_SC->scsi_done() == NULL");
+	} else
+		aha152x_panic(shpnt, "done() called outside of command");
X }
X 
X 
@@ -1563,41 +1586,39 @@
X static struct tq_struct aha152x_tq;
X 
X /*
- *	Run service completions on the card with interrupts enabled.
+ *    Run service completions on the card with interrupts enabled.
X  */
- 
+
X static void aha152x_run(void)
X {
X 	int i;
-	for(i=0;i<IRQS;i++)
-	{
-		struct Scsi_Host *shpnt=aha152x_host[i];
-		if(shpnt && HOSTDATA(shpnt)->service)
-		{
-			HOSTDATA(shpnt)->service=0;
+	for (i = 0; i < IRQS; i++) {
+		struct Scsi_Host *shpnt = aha152x_host[i];
+		if (shpnt && HOSTDATA(shpnt)->service) {
+			HOSTDATA(shpnt)->service = 0;
X 			aha152x_complete(shpnt);
X 		}
X 	}
X }
X 
X /*
- *	Interrupts handler (main routine of the driver)
+ *    Interrupts handler (main routine of the driver)
X  */
X 
-static void aha152x_intr(int irqno, void *dev_id, struct pt_regs * regs)
+static void aha152x_intr(int irqno, void *dev_id, struct pt_regs *regs)
X {
-	struct Scsi_Host *shpnt = aha152x_host[irqno-IRQ_MIN];
+	struct Scsi_Host *shpnt = aha152x_host[irqno - IRQ_MIN];
X 
X #if defined(DEBUG_RACE)
X 	enter_driver("intr");
X #else
X #if defined(DEBUG_INTR)
-	if(HOSTDATA(shpnt)->debug & debug_intr)
+	if (HOSTDATA(shpnt)->debug & debug_intr)
X 		printk("\naha152x: intr(), ");
X #endif
X #endif
X 
-	if(!shpnt)
+	if (!shpnt)
X 		panic("aha152x: catched interrupt for unknown controller.\n");
X 
X 	/* no more interrupts from the controller, while we're busy.
@@ -1606,9 +1627,9 @@
X 	CLRBITS(DMACNTRL0, INTEN);
X 
X 	/* Poke the BH handler */
-	
-	HOSTDATA(shpnt)->service=1;
-	aha152x_tq.routine = (void *)aha152x_run;
+
+	HOSTDATA(shpnt)->service = 1;
+	aha152x_tq.routine = (void *) aha152x_run;
X 	queue_task(&aha152x_tq, &tq_immediate);
X 	mark_bh(IMMEDIATE_BH);
X }
@@ -1616,1020 +1637,1001 @@
X static void aha152x_complete(struct Scsi_Host *shpnt)
X {
X 	unsigned int flags;
-	int done=0, phase;
+	int done = 0, phase;
X 
X 	/* disconnected target is trying to reconnect.
X 	   Only possible, if we have disconnected nexuses and
X 	   nothing is occupying the bus.
X 	 */
-	 
-  if(TESTHI(SSTAT0, SELDI) &&
-      DISCONNECTED_SC &&
-      (!CURRENT_SC || (CURRENT_SC->SCp.phase & in_selection)) ) {
-    int identify_msg, target, i;
-
-    /* Avoid conflicts when a target reconnects
-       while we are trying to connect to another. */
-    if(CURRENT_SC) {
+
+	if (TESTHI(SSTAT0, SELDI) &&
+	    DISCONNECTED_SC &&
+	    (!CURRENT_SC || (CURRENT_SC->SCp.phase & in_selection))) {
+		int identify_msg, target, i;
+
+		/* Avoid conflicts when a target reconnects
+		   while we are trying to connect to another. */
+		if (CURRENT_SC) {
X #if defined(DEBUG_QUEUES)
-      if(HOSTDATA(shpnt)->debug & debug_queues)
-        printk("i+, ");
+			if (HOSTDATA(shpnt)->debug & debug_queues)
+				printk("i+, ");
X #endif
-      save_flags(flags);
-      cli();
-      append_SC(&ISSUE_SC, CURRENT_SC);
-      CURRENT_SC=NULL;
-      restore_flags(flags);
-    }
-
-    /* disable sequences */
-    SETPORT(SCSISEQ, 0);
-    SETPORT(SSTAT0, CLRSELDI);
-    SETPORT(SSTAT1, CLRBUSFREE);
+			save_flags(flags);
+			cli();
+			append_SC(&ISSUE_SC, CURRENT_SC);
+			CURRENT_SC = NULL;
+			restore_flags(flags);
+		}
+		/* disable sequences */
+		SETPORT(SCSISEQ, 0);
+		SETPORT(SSTAT0, CLRSELDI);
+		SETPORT(SSTAT1, CLRBUSFREE);
X 
X #if defined(DEBUG_QUEUES) || defined(DEBUG_PHASES)
-    if(HOSTDATA(shpnt)->debug & (debug_queues|debug_phases))
-      printk("reselected, ");
+		if (HOSTDATA(shpnt)->debug & (debug_queues | debug_phases))
+			printk("reselected, ");
X #endif
X 
-    i = GETPORT(SELID) & ~(1 << shpnt->this_id);
-    target=0;
+		i = GETPORT(SELID) & ~(1 << shpnt->this_id);
+		target = 0;
X 
-    if(i==0)
-      aha152x_panic(shpnt, "reconnecting target unknown");
+		if (i == 0)
+			aha152x_panic(shpnt, "reconnecting target unknown");
X 
-    for(; (i & 1)==0; target++, i>>=1)
-      ;
+		for (; (i & 1) == 0; target++, i >>= 1);
X 
X #if defined(DEBUG_QUEUES)
-    if(HOSTDATA(shpnt)->debug & debug_queues)
-      printk("SELID=%02x, target=%d, ", GETPORT(SELID), target);
+		if (HOSTDATA(shpnt)->debug & debug_queues)
+			printk("SELID=%02x, target=%d, ", GETPORT(SELID), target);
X #endif
-    SETPORT(SCSIID, (shpnt->this_id << OID_) | target);
-    SETPORT(SCSISEQ, ENRESELI);
-
-    if(TESTLO(SSTAT0, SELDI))
-      aha152x_panic(shpnt, "RESELI failed");
-
-    SETPORT(SCSIRATE, HOSTDATA(shpnt)->syncrate[target]&0x7f);
+		SETPORT(SCSIID, (shpnt->this_id << OID_) | target);
+		SETPORT(SCSISEQ, ENRESELI);
X 
-    SETPORT(SCSISIG, P_MSGI);
+		if (TESTLO(SSTAT0, SELDI))
+			aha152x_panic(shpnt, "RESELI failed");
X 
-    /* Get identify message */
-    if((i=getphase(shpnt))!=P_MSGI) {
-      printk("target doesn't enter MSGI to identify (phase=%02x)\n", i);
-      aha152x_panic(shpnt, "unknown lun");
-    }
-    SETPORT(SCSISEQ, 0);
+		SETPORT(SCSIRATE, HOSTDATA(shpnt)->syncrate[target] & 0x7f);
X 
-    SETPORT(SXFRCTL0, CH1);
+		SETPORT(SCSISIG, P_MSGI);
X 
-    identify_msg = GETPORT(SCSIBUS);
+		/* Get identify message */
+		if ((i = getphase(shpnt)) != P_MSGI) {
+			printk("target doesn't enter MSGI to identify (phase=%02x)\n", i);
+			aha152x_panic(shpnt, "unknown lun");
+		}
+		SETPORT(SCSISEQ, 0);
X 
-    if(!(identify_msg & IDENTIFY_BASE)) {
-      printk("target=%d, inbound message (%02x) != IDENTIFY\n",
-             target, identify_msg);
-      aha152x_panic(shpnt, "unknown lun");
-    }
+		SETPORT(SXFRCTL0, CH1);
X 
+		identify_msg = GETPORT(SCSIBUS);
X 
+		if (!(identify_msg & IDENTIFY_BASE)) {
+			printk("target=%d, inbound message (%02x) != IDENTIFY\n",
+			       target, identify_msg);
+			aha152x_panic(shpnt, "unknown lun");
+		}
X #if defined(DEBUG_QUEUES)
-    if(HOSTDATA(shpnt)->debug & debug_queues)
-      printk("identify=%02x, lun=%d, ", identify_msg, identify_msg & 0x3f);
+		if (HOSTDATA(shpnt)->debug & debug_queues)
+			printk("identify=%02x, lun=%d, ", identify_msg, identify_msg & 0x3f);
X #endif
X 
-    save_flags(flags);
-    cli();
+		save_flags(flags);
+		cli();
X 
X #if defined(DEBUG_QUEUES)
-    if(HOSTDATA(shpnt)->debug & debug_queues)
-      printk("d-, ");
+		if (HOSTDATA(shpnt)->debug & debug_queues)
+			printk("d-, ");
X #endif
-    CURRENT_SC = remove_SC(&DISCONNECTED_SC, target, identify_msg & 0x3f);
+		CURRENT_SC = remove_SC(&DISCONNECTED_SC, target, identify_msg & 0x3f);
+
+		if (!CURRENT_SC) {
+			printk("lun=%d, ", identify_msg & 0x3f);
+			aha152x_panic(shpnt, "no disconnected command for that lun");
+		}
+		CURRENT_SC->SCp.phase &= ~disconnected;
+		restore_flags(flags);
X 
-    if(!CURRENT_SC) {
-      printk("lun=%d, ", identify_msg & 0x3f);
-      aha152x_panic(shpnt, "no disconnected command for that lun");
-    }
-
-    CURRENT_SC->SCp.phase &= ~disconnected;
-    restore_flags(flags);
-
-    make_acklow(shpnt);
-    if(getphase(shpnt)!=P_MSGI) {
-      SETPORT(SIMODE0, 0);
-      SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE);
+		make_acklow(shpnt);
+		if (getphase(shpnt) != P_MSGI) {
+			SETPORT(SIMODE0, 0);
+			SETPORT(SIMODE1, ENPHASEMIS | ENBUSFREE);
X #if defined(DEBUG_RACE)
-      leave_driver("(reselected) intr");
+			leave_driver("(reselected) intr");
X #endif
-      SETBITS(DMACNTRL0, INTEN);
-      return;
-    }
-  }
-  
-  /* Check, if we aren't busy with a command */
-  if(!CURRENT_SC) {
-    /* bus is free to issue a queued command */
-    if(TESTHI(SSTAT1, BUSFREE) && ISSUE_SC) {
-      save_flags(flags);
-      cli();
+			SETBITS(DMACNTRL0, INTEN);
+			return;
+		}
+	}
+	/* Check, if we aren't busy with a command */
+	if (!CURRENT_SC) {
+		/* bus is free to issue a queued command */
+		if (TESTHI(SSTAT1, BUSFREE) && ISSUE_SC) {
+			save_flags(flags);
+			cli();
X #if defined(DEBUG_QUEUES)
-      if(HOSTDATA(shpnt)->debug & debug_queues)
-        printk("i-, ");
+			if (HOSTDATA(shpnt)->debug & debug_queues)
+				printk("i-, ");
X #endif
-      CURRENT_SC = remove_first_SC(&ISSUE_SC);
-      restore_flags(flags);
+			CURRENT_SC = remove_first_SC(&ISSUE_SC);
+			restore_flags(flags);
X 
X #if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
-      if(HOSTDATA(shpnt)->debug & (debug_intr|debug_selection|debug_phases))
-        printk("issuing command, ");
+			if (HOSTDATA(shpnt)->debug & (debug_intr | debug_selection | debug_phases))
+				printk("issuing command, ");
X #endif
-      CURRENT_SC->SCp.phase = in_selection;
+			CURRENT_SC->SCp.phase = in_selection;
X 
X #if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
-      if(HOSTDATA(shpnt)->debug & (debug_intr|debug_selection|debug_phases))
-        printk("selecting %d, ", CURRENT_SC->target); 
+			if (HOSTDATA(shpnt)->debug & (debug_intr | debug_selection | debug_phases))
+				printk("selecting %d, ", CURRENT_SC->target);
X #endif
-      SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target);
+			SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target);
X 
-      /* Enable interrupts for SELECTION OUT DONE and SELECTION OUT INITIATED */
-      SETPORT(SXFRCTL1, HOSTDATA(shpnt)->parity ? (ENSPCHK|ENSTIMER) : ENSTIMER);
+			/* Enable interrupts for SELECTION OUT DONE and SELECTION OUT INITIATED */
+			SETPORT(SXFRCTL1, HOSTDATA(shpnt)->parity ? (ENSPCHK | ENSTIMER) : ENSTIMER);
X 
-      /* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */
-      SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));
-      SETPORT(SIMODE1, ENSELTIMO);
-
-      /* Enable SELECTION OUT sequence */
-      SETBITS(SCSISEQ, ENSELO | ENAUTOATNO);
-        
-    } else {
-      /* No command we are busy with and no new to issue */
-      printk("aha152x: ignoring spurious interrupt, nothing to do\n");
-      if(TESTHI(DMACNTRL0, SWINT)) {
-        printk("aha152x: SWINT is set!  Why?\n");
-        CLRBITS(DMACNTRL0, SWINT);
-      }
-      show_queues(shpnt);
-    }
+			/* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */
+			SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));
+			SETPORT(SIMODE1, ENSELTIMO);
+
+			/* Enable SELECTION OUT sequence */
+			SETBITS(SCSISEQ, ENSELO | ENAUTOATNO);
+
+		} else {
+			/* No command we are busy with and no new to issue */
+			printk("aha152x: ignoring spurious interrupt, nothing to do\n");
+			if (TESTHI(DMACNTRL0, SWINT)) {
+				printk("aha152x: SWINT is set!  Why?\n");
+				CLRBITS(DMACNTRL0, SWINT);
+			}
+			show_queues(shpnt);
+		}
X 
X #if defined(DEBUG_RACE)
-    leave_driver("(selecting) intr");
+		leave_driver("(selecting) intr");
X #endif
-    SETBITS(DMACNTRL0, INTEN);
-          return;
-  }
-
-  /* the bus is busy with something */
+		SETBITS(DMACNTRL0, INTEN);
+		return;
+	}
+	/* the bus is busy with something */
X 
X #if defined(DEBUG_INTR)
-  if(HOSTDATA(shpnt)->debug & debug_intr)
-    disp_ports(shpnt);
+	if (HOSTDATA(shpnt)->debug & debug_intr)
+		disp_ports(shpnt);
X #endif
X 
-  /* we are waiting for the result of a selection attempt */
-  if(CURRENT_SC->SCp.phase & in_selection) {
-    if(TESTLO(SSTAT1, SELTO)) {
-      /* no timeout */
-      if(TESTHI(SSTAT0, SELDO)) {
-        /* clear BUS FREE interrupt */
-        SETPORT(SSTAT1, CLRBUSFREE);
-
-        /* Disable SELECTION OUT sequence */
-        CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO);
-
-        /* Disable SELECTION OUT DONE interrupt */
-        CLRBITS(SIMODE0, ENSELDO);
-        CLRBITS(SIMODE1, ENSELTIMO);
+	/* we are waiting for the result of a selection attempt */
+	if (CURRENT_SC->SCp.phase & in_selection) {
+		if (TESTLO(SSTAT1, SELTO)) {
+			/* no timeout */
+			if (TESTHI(SSTAT0, SELDO)) {
+				/* clear BUS FREE interrupt */
+				SETPORT(SSTAT1, CLRBUSFREE);
+
+				/* Disable SELECTION OUT sequence */
+				CLRBITS(SCSISEQ, ENSELO | ENAUTOATNO);
+
+				/* Disable SELECTION OUT DONE interrupt */
+				CLRBITS(SIMODE0, ENSELDO);
+				CLRBITS(SIMODE1, ENSELTIMO);
X 
-        if(TESTLO(SSTAT0, SELDO)) {
-          printk("aha152x: passing bus free condition\n");
+				if (TESTLO(SSTAT0, SELDO)) {
+					printk("aha152x: passing bus free condition\n");
X 
X #if defined(DEBUG_RACE)
-          leave_driver("(passing bus free) intr");
+					leave_driver("(passing bus free) intr");
X #endif
-          SETBITS(DMACNTRL0, INTEN);
+					SETBITS(DMACNTRL0, INTEN);
X 
-          if(CURRENT_SC->SCp.phase & aborted) {
-            HOSTDATA(shpnt)->abort_result=SCSI_ABORT_ERROR;
-            HOSTDATA(shpnt)->abortion_complete++;
-          }
+					if (CURRENT_SC->SCp.phase & aborted) {
+						HOSTDATA(shpnt)->abort_result = SCSI_ABORT_ERROR;
+						HOSTDATA(shpnt)->abortion_complete++;
+					}
+					aha152x_done(shpnt, DID_NO_CONNECT << 16);
X 
-          aha152x_done(shpnt, DID_NO_CONNECT << 16);
-
-          return;
-        }
+					return;
+				}
X #if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
-        if(HOSTDATA(shpnt)->debug & (debug_selection|debug_phases))
-          printk("SELDO (SELID=%x), ", GETPORT(SELID));
+				if (HOSTDATA(shpnt)->debug & (debug_selection | debug_phases))
+					printk("SELDO (SELID=%x), ", GETPORT(SELID));
X #endif
X 
-        /* selection was done */
-        SETPORT(SSTAT0, CLRSELDO);
+				/* selection was done */
+				SETPORT(SSTAT0, CLRSELDO);
X 
X #if defined(DEBUG_ABORT)
-        if((HOSTDATA(shpnt)->debug & debug_abort) && (CURRENT_SC->SCp.phase & aborted))
-          printk("(ABORT) target selected, ");
+				if ((HOSTDATA(shpnt)->debug & debug_abort) && (CURRENT_SC->SCp.phase & aborted))
+					printk("(ABORT) target selected, ");
X #endif
X 
-        CURRENT_SC->SCp.phase &= ~in_selection;
-        CURRENT_SC->SCp.phase |= in_other;
-
-        ADDMSG(IDENTIFY(HOSTDATA(shpnt)->reconnect,CURRENT_SC->lun));
+				CURRENT_SC->SCp.phase &= ~in_selection;
+				CURRENT_SC->SCp.phase |= in_other;
X 
-        if(!(SYNCRATE&0x80) && HOSTDATA(shpnt)->synchronous) {
-          ADDMSG(EXTENDED_MESSAGE);
-          ADDMSG(3);
-          ADDMSG(EXTENDED_SDTR);
-          ADDMSG(50);
-          ADDMSG(8);
+				ADDMSG(IDENTIFY(HOSTDATA(shpnt)->reconnect, CURRENT_SC->lun));
X 
-          printk("outbound SDTR: ");
-          print_msg(&MSG(MSGLEN-5));
+				if (!(SYNCRATE & 0x80) && HOSTDATA(shpnt)->synchronous) {
+					ADDMSG(EXTENDED_MESSAGE);
+					ADDMSG(3);
+					ADDMSG(EXTENDED_SDTR);
+					ADDMSG(50);
+					ADDMSG(8);
X 
-          SYNCRATE=0x80;
-          CURRENT_SC->SCp.phase |= in_sync;
-        }
+					printk("outbound SDTR: ");
+					print_msg(&MSG(MSGLEN - 5));
X 
+					SYNCRATE = 0x80;
+					CURRENT_SC->SCp.phase |= in_sync;
+				}
X #if defined(DEBUG_RACE)
-        leave_driver("(SELDO) intr");
+				leave_driver("(SELDO) intr");
X #endif
-        SETPORT(SCSIRATE, SYNCRATE&0x7f);
+				SETPORT(SCSIRATE, SYNCRATE & 0x7f);
X 
-        SETPORT(SCSISIG, P_MSGO);
+				SETPORT(SCSISIG, P_MSGO);
X 
-        SETPORT(SIMODE0, 0);
-        SETPORT(SIMODE1, ENREQINIT|ENBUSFREE);
-        SETBITS(DMACNTRL0, INTEN);
+				SETPORT(SIMODE0, 0);
+				SETPORT(SIMODE1, ENREQINIT | ENBUSFREE);
+				SETBITS(DMACNTRL0, INTEN);
X 
-        return;
-      } else
-        aha152x_panic(shpnt, "neither timeout nor selection\007");
-    } else {
+				return;
+			} else
+				aha152x_panic(shpnt, "neither timeout nor selection\007");
+		} else {
X #if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
-      if(HOSTDATA(shpnt)->debug & (debug_selection|debug_phases))
-        printk("SELTO, ");
+			if (HOSTDATA(shpnt)->debug & (debug_selection | debug_phases))
+				printk("SELTO, ");
X #endif
-      /* end selection attempt */
-      CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO);
+			/* end selection attempt */
+			CLRBITS(SCSISEQ, ENSELO | ENAUTOATNO);
X 
-      /* timeout */
-      SETPORT(SSTAT1, CLRSELTIMO);
+			/* timeout */
+			SETPORT(SSTAT1, CLRSELTIMO);
X 
-      SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
-      SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
-      SETBITS(DMACNTRL0, INTEN);
+			SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
+			SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
+			SETBITS(DMACNTRL0, INTEN);
X #if defined(DEBUG_RACE)
-      leave_driver("(SELTO) intr");
+			leave_driver("(SELTO) intr");
X #endif
X 
-      if(CURRENT_SC->SCp.phase & aborted) {
+			if (CURRENT_SC->SCp.phase & aborted) {
X #if defined(DEBUG_ABORT)
-        if(HOSTDATA(shpnt)->debug & debug_abort)
-          printk("(ABORT) selection timeout, ");
+				if (HOSTDATA(shpnt)->debug & debug_abort)
+					printk("(ABORT) selection timeout, ");
X #endif
-        HOSTDATA(shpnt)->abort_result=SCSI_ABORT_ERROR;
-        HOSTDATA(shpnt)->abortion_complete++;
-      }
-
-      if(TESTLO(SSTAT0, SELINGO))
-        /* ARBITRATION not won */
-        aha152x_done(shpnt, DID_BUS_BUSY << 16);
-      else
-        /* ARBITRATION won, but SELECTION failed */
-        aha152x_done(shpnt, DID_NO_CONNECT << 16);
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 24'
echo 'File patch-2.3.10 is continued in part 25'
echo 25 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 20 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
+      int	in_bytes10;
+      int	out_bytes10;
+};
+
+
+
+#define ARLAN_CLEAR		0x00
+#define ARLAN_RESET 		0x01
+#define ARLAN_CHANNEL_ATTENTION 0x02
+#define ARLAN_INTERRUPT_ENABLE 	0x04
+#define ARLAN_CLEAR_INTERRUPT 	0x08
+#define ARLAN_POWER 		0x40
+#define ARLAN_ACCESS		0x80
+
+#define ARLAN_COM_CONF                0x01
+#define ARLAN_COM_RX_ENABLE           0x03
+#define ARLAN_COM_RX_ABORT            0x04
+#define ARLAN_COM_TX_ENABLE           0x05
+#define ARLAN_COM_TX_ABORT            0x06
+#define ARLAN_COM_NOP		      0x07
+#define ARLAN_COM_STANDBY             0x08
+#define ARLAN_COM_ACTIVATE            0x09
+#define ARLAN_COM_GOTO_SLOW_POLL      0x0a
+#define ARLAN_COM_INT                 0x80
+
+
+#define TXLAST(dev) (((struct arlan_private *)dev->priv)->txRing[((struct arlan_private *)dev->priv)->txLast])
+#define TXHEAD(dev) (((struct arlan_private *)dev->priv)->txRing[0])
+#define TXTAIL(dev) (((struct arlan_private *)dev->priv)->txRing[1])
+
+#define TXBuffStart(dev) \
+ ((int)(((struct arlan_private *)dev->priv)->card)->txBuffer) - ((int)(((struct arlan_private *)dev->priv)->card) )
+#define TXBuffEnd(dev) \
+ ((int)(((struct arlan_private *)dev->priv)->card)->rxBuffer) - ((int)(((struct arlan_private *)dev->priv)->card)
+ 
+#define READSHM(to,from,atype) {\
+	atype tmp;\
+	memcpy_fromio(&(tmp),&(from),sizeof(atype));\
+	to = tmp;\
+	}
+
+#define READSHMEM(from,atype)\
+	atype from; \
+	READSHM(from, arlan->from, atype);
+
+#define WRITESHM(to,from,atype) \
+	{ atype tmpSHM = from;\
+	memcpy_toio(&(to),&tmpSHM,sizeof(atype));\
+	}
+
+#define DEBUGSHM(levelSHM,stringSHM,stuff,atype) \
+	{	atype tmpSHM; \
+		memcpy_fromio(&tmpSHM,&(stuff),sizeof(atype));\
+		IFDEBUG(levelSHM) printk(stringSHM,tmpSHM);\
+	}
+
+#define WRITESHMB(to, val) \
+	writeb(val,&(to))
+#define READSHMB(to) \
+	readb(&(to))
+#define WRITESHMS(to, val) \
+	writew(val,&(to))
+#define READSHMS(to) \
+	readw(&(to))
+#define WRITESHMI(to, val) \
+	writel(val,&(to))
+#define READSHMI(to) \
+	readl(&(to))
+
+
+
+
+
+#define registrationBad(dev)\
+   ( (   READSHMB(((struct arlan_private *)dev->priv)->card->registrationMode)    > 0) && \
+     (   READSHMB(((struct arlan_private *)dev->priv)->card->registrationStatus) == 0)    )
+
+
+#define readControlRegister(dev)\
+ 	READSHMB(((struct arlan_private *)dev->priv)->card->cntrlRegImage)
+
+#define writeControlRegister(dev, v){\
+   WRITESHMB(((struct arlan_private *)dev->priv)->card->cntrlRegImage	,((v) &0xF) );\
+   WRITESHMB(((struct arlan_private *)dev->priv)->card->controlRegister	,(v) 	);}
+
+
+#define arlan_interrupt_lancpu(dev) {\
+   int cr;   \
+   \
+   priv->under_toggle++;   \
+   cr = readControlRegister(dev);\
+   if (cr & ARLAN_CHANNEL_ATTENTION){ \
+      writeControlRegister(dev, (cr & ~ARLAN_CHANNEL_ATTENTION));\
+   }else  \
+      writeControlRegister(dev, (cr | ARLAN_CHANNEL_ATTENTION));\
+   priv->under_toggle=0;     \
+}
+
+#define clearChannelAttention(dev){ \
+   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION);}
+#define setHardwareReset(dev) {\
+   writeControlRegister(dev,readControlRegister(dev) | ARLAN_RESET);}
+#define clearHardwareReset(dev) {\
+   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_RESET);}
+#define setInterruptEnable(dev){\
+   writeControlRegister(dev,readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE)  ;}
+#define clearInterruptEnable(dev){\
+   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE)  ;}
+#define setClearInterrupt(dev){\
+   writeControlRegister(dev,readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT)   ;}
+#define clearClearInterrupt(dev){\
+   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT);}
+#define setPowerOff(dev){\
+   writeControlRegister(dev,readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\
+   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);}
+#define setPowerOn(dev){\
+   writeControlRegister(dev,readControlRegister(dev) & ~(ARLAN_POWER));   }
+#define arlan_lock_card_access(dev){\
+   writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);}
+#define arlan_unlock_card_access(dev){\
+   writeControlRegister(dev,readControlRegister(dev) | ARLAN_ACCESS ); }  
+
+
+
+
+#define ARLAN_COMMAND_RX		0x00001
+#define ARLAN_COMMAND_NOOP		0x00002
+#define ARLAN_COMMAND_NOOPINT		0x00004
+#define ARLAN_COMMAND_TX		0x00008
+#define ARLAN_COMMAND_CONF		0x00010
+#define ARLAN_COMMAND_RESET		0x00020
+#define ARLAN_COMMAND_TX_ABORT		0x00040
+#define ARLAN_COMMAND_RX_ABORT		0x00080
+#define ARLAN_COMMAND_POWERDOWN		0x00100
+#define ARLAN_COMMAND_POWERUP		0x00200
+#define ARLAN_COMMAND_SLOW_POLL 	0x00400
+#define ARLAN_COMMAND_ACTIVATE 		0x00800
+#define ARLAN_COMMAND_INT_ACK		0x01000
+#define ARLAN_COMMAND_INT_ENABLE	0x02000
+#define ARLAN_COMMAND_WAIT_NOW		0x04000
+#define ARLAN_COMMAND_LONG_WAIT_NOW	0x08000
+#define ARLAN_COMMAND_STANDBY		0x10000
+#define ARLAN_COMMAND_INT_RACK		0x20000
+#define ARLAN_COMMAND_INT_RENABLE	0x40000
+#define ARLAN_COMMAND_CONF_WAIT		0x80000
+#define ARLAN_COMMAND_CLEAN_AND_CONF	(ARLAN_COMMAND_TX_ABORT\
+					| ARLAN_COMMAND_RX_ABORT\
+					| ARLAN_COMMAND_CONF)
+#define ARLAN_COMMAND_CLEAN_AND_RESET   (ARLAN_COMMAND_TX_ABORT\
+					| ARLAN_COMMAND_RX_ABORT\
+					| ARLAN_COMMAND_RESET)
+
+
+ 
+#define ARLAN_DEBUG_CHAIN_LOCKS		0x00001
+#define ARLAN_DEBUG_RESET		0x00002
+#define ARLAN_DEBUG_TIMING		0x00004
+#define ARLAN_DEBUG_CARD_STATE		0x00008
+#define ARLAN_DEBUG_TX_CHAIN		0x00010
+#define ARLAN_DEBUG_MULTICAST		0x00020
+#define ARLAN_DEBUG_HEADER_DUMP		0x00040
+#define ARLAN_DEBUG_INTERRUPT		0x00080
+#define ARLAN_DEBUG_STARTUP		0x00100
+#define ARLAN_DEBUG_SHUTDOWN		0x00200
+ 
\ No newline at end of file
diff -u --recursive --new-file v2.3.9/linux/drivers/net/atari_bionet.c linux/drivers/net/atari_bionet.c
--- v2.3.9/linux/drivers/net/atari_bionet.c	Sat Jun 13 13:28:34 1998
+++ linux/drivers/net/atari_bionet.c	Tue Jul  6 19:05:49 1999
@@ -324,8 +324,8 @@
X 
X /* Check for a network adaptor of this type, and return '0' if one exists.
X  */
-__initfunc(int
-bionet_probe(struct device *dev)) {
+int __init 
+bionet_probe(struct device *dev){
X 	unsigned char station_addr[6];
X 	static unsigned version_printed = 0;
X 	static int no_more_found = 0; /* avoid "Probing for..." printed 4 times */
diff -u --recursive --new-file v2.3.9/linux/drivers/net/atari_pamsnet.c linux/drivers/net/atari_pamsnet.c
--- v2.3.9/linux/drivers/net/atari_pamsnet.c	Wed Oct  7 15:51:45 1998
+++ linux/drivers/net/atari_pamsnet.c	Tue Jul  6 19:05:49 1999
@@ -561,8 +561,8 @@
X /* Check for a network adaptor of this type, and return '0' if one exists.
X  */
X 
-__initfunc(extern int
-pamsnet_probe (dev))
+extern int __init 
+pamsnet_probe (dev)
X 	struct device *dev;
X {
X 	int i;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/atarilance.c linux/drivers/net/atarilance.c
--- v2.3.9/linux/drivers/net/atarilance.c	Fri Feb 20 17:55:45 1998
+++ linux/drivers/net/atarilance.c	Tue Jul  6 19:05:49 1999
@@ -370,9 +370,9 @@
X }
X 
X 
-__initfunc(int atarilance_probe( struct device *dev ))
-
-{	int i;
+int __init atarilance_probe( struct device *dev )
+{	
+    int i;
X 	static int found = 0;
X 
X 	if (!MACH_IS_ATARI || found)
@@ -393,9 +393,9 @@
X 
X /* Derived from hwreg_present() in atari/config.c: */
X 
-__initfunc(static int addr_accessible( volatile void *regp, int wordflag, int writeflag ))
-
-{	int		ret;
+static int __init addr_accessible( volatile void *regp, int wordflag, int writeflag )
+{
+	int		ret;
X 	long	flags;
X 	long	*vbr, save_berr;
X 
@@ -443,10 +443,10 @@
X }
X 
X 
-__initfunc(static unsigned long lance_probe1( struct device *dev,
-								   struct lance_addr *init_rec ))
-
-{	volatile unsigned short *memaddr =
+static unsigned long __init lance_probe1( struct device *dev,
+								   struct lance_addr *init_rec )
+{
+	volatile unsigned short *memaddr =
X 		(volatile unsigned short *)init_rec->memaddr;
X 	volatile unsigned short *ioaddr =
X 		(volatile unsigned short *)init_rec->ioaddr;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/atp.c linux/drivers/net/atp.c
--- v2.3.9/linux/drivers/net/atp.c	Fri Nov 20 08:44:06 1998
+++ linux/drivers/net/atp.c	Tue Jul  6 19:05:49 1999
@@ -150,8 +150,8 @@
X    If dev->base_addr == 2, allocate space for the device and return success
X    (detachable devices only).
X    */
-__initfunc(int
-atp_init(struct device *dev))
+int __init 
+atp_init(struct device *dev)
X {
X 	int *port, ports[] = {0x378, 0x278, 0x3bc, 0};
X 	int base_addr = dev->base_addr;
@@ -173,7 +173,7 @@
X 	return ENODEV;
X }
X 
-__initfunc(static int atp_probe1(struct device *dev, short ioaddr))
+static int __init atp_probe1(struct device *dev, short ioaddr)
X {
X 	int saved_ctrl_reg, status;
X 
@@ -259,7 +259,7 @@
X }
X 
X /* Read the station address PROM, usually a word-wide EEPROM. */
-__initfunc(static void get_node_ID(struct device *dev))
+static void __init get_node_ID(struct device *dev)
X {
X 	short ioaddr = dev->base_addr;
X 	int sa_offset = 0;
@@ -291,7 +291,7 @@
X  * DO :	 _________X_______X
X  */
X 
-__initfunc(static unsigned short eeprom_op(short ioaddr, unsigned int cmd))
+static unsigned short __init eeprom_op(short ioaddr, unsigned int cmd)
X {
X 	unsigned eedata_out = 0;
X 	int num_bits = EE_CMD_SIZE;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/com20020.c linux/drivers/net/com20020.c
--- v2.3.9/linux/drivers/net/com20020.c	Mon Sep 14 11:32:22 1998
+++ linux/drivers/net/com20020.c	Tue Jul  6 19:05:49 1999
@@ -96,7 +96,7 @@
X MODULE_PARM(backplane,"i");
X MODULE_PARM(clock,"i");
X #else
-__initfunc(void com20020_setup (char *str, int *ints));
+void __init com20020_setup (char *str, int *ints);
X extern struct device arcnet_devs[];
X extern char arcnet_dev_names[][10];
X extern int arcnet_num_devs;
@@ -224,7 +224,7 @@
X  * it's where we were told it was, and even autoirq
X  */
X 
-__initfunc(int arc20020_probe(struct device *dev))
+int __init arc20020_probe(struct device *dev)
X {
X   int ioaddr=dev->base_addr,status,delayval;
X   unsigned long airqmask;
@@ -327,7 +327,7 @@
X /* Set up the struct device associated with this card.  Called after
X  * probing succeeds.
X  */
-__initfunc(int arc20020_found(struct device *dev,int ioaddr,int airq))
+int __init arc20020_found(struct device *dev,int ioaddr,int airq)
X {
X   struct arcnet_local *lp;
X   
@@ -1035,7 +1035,7 @@
X 
X #else
X 
-__initfunc(void com20020_setup (char *str, int *ints))
+void __init com20020_setup (char *str, int *ints)
X {
X   struct device *dev;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/com90io.c linux/drivers/net/com90io.c
--- v2.3.9/linux/drivers/net/com90io.c	Mon Sep 14 11:32:22 1998
+++ linux/drivers/net/com90io.c	Tue Jul  6 19:05:49 1999
@@ -87,7 +87,7 @@
X MODULE_PARM(irq, "i");
X MODULE_PARM(device, "s");
X #else
-__initfunc(void com90io_setup (char *str, int *ints));
+void __init com90io_setup (char *str, int *ints);
X extern struct device arcnet_devs[];
X extern char arcnet_dev_names[][10];
X extern int arcnet_num_devs;
@@ -193,7 +193,7 @@
X  * it's where we were told it was, and even autoirq
X  */
X 
-__initfunc(int arc90io_probe(struct device *dev))
+int __init arc90io_probe(struct device *dev)
X {
X   int ioaddr=dev->base_addr,status,delayval;
X   unsigned long airqmask;
@@ -287,7 +287,7 @@
X /* Set up the struct device associated with this card.  Called after
X  * probing succeeds.
X  */
-__initfunc(int arc90io_found(struct device *dev,int ioaddr,int airq))
+int __init arc90io_found(struct device *dev,int ioaddr,int airq)
X {
X   struct arcnet_local *lp;
X 
@@ -914,7 +914,7 @@
X 
X #else
X 
-__initfunc(void com90io_setup (char *str, int *ints))
+void __init com90io_setup (char *str, int *ints)
X {
X   struct device *dev;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/com90xx.c linux/drivers/net/com90xx.c
--- v2.3.9/linux/drivers/net/com90xx.c	Mon Sep 14 11:32:22 1998
+++ linux/drivers/net/com90xx.c	Tue Jul  6 19:05:49 1999
@@ -117,7 +117,7 @@
X MODULE_PARM(shmem, "i");
X MODULE_PARM(device, "s");
X #else
-__initfunc(void com90xx_setup(char *str, int *ints));
+void __init com90xx_setup(char *str, int *ints);
X char __initdata com90xx_explicit = 0;
X 
X extern struct device arcnet_devs[];
@@ -179,7 +179,7 @@
X 	0
X };
X 
-__initfunc(int arc90xx_probe(struct device *dev))
+int __init arc90xx_probe(struct device *dev)
X {
X 	static int init_once = 0;
X 	static int numports = sizeof(ports) / sizeof(ports[0]), numshmems = sizeof(shmems) / sizeof(shmems[0]);
@@ -399,7 +399,7 @@
X 			 */
X 			airqmask = probe_irq_on();
X 			AINTMASK(NORXflag);
-			udelay(1);
+			mdelay(1);
X 			AINTMASK(0);
X 			airq = probe_irq_off(airqmask);
X 
@@ -493,7 +493,7 @@
X /* Set up the struct device associated with this card.  Called after
X  * probing succeeds.
X  */
-__initfunc(static int arc90xx_found(struct device *dev, int ioaddr, int airq, u_long shmem, int more))
+static int __init arc90xx_found(struct device *dev, int ioaddr, int airq, u_long shmem, int more)
X {
X 	struct arcnet_local *lp;
X 	u_long first_mirror, last_mirror;
@@ -1121,7 +1121,7 @@
X 
X #else
X 
-__initfunc(void com90xx_setup(char *str, int *ints))
+void __init com90xx_setup(char *str, int *ints)
X {
X 	struct device *dev;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/cops.c linux/drivers/net/cops.c
--- v2.3.9/linux/drivers/net/cops.c	Wed Oct  7 15:51:45 1998
+++ linux/drivers/net/cops.c	Tue Jul  6 19:05:49 1999
@@ -218,7 +218,7 @@
X  *      If dev->base_addr in [1..0x1ff], always return failure.
X  *        otherwise go with what we pass in.
X  */
-__initfunc(int cops_probe(struct device *dev))
+int __init cops_probe(struct device *dev)
X {
X 	int i;
X         int base_addr = dev ? dev->base_addr : 0;
@@ -252,7 +252,7 @@
X  *      probes on the ISA bus. A good device probes avoids doing writes, and
X  *      verifies that the correct device exists and functions.
X  */
-__initfunc(static int cops_probe1(struct device *dev, int ioaddr))
+static int __init cops_probe1(struct device *dev, int ioaddr)
X {
X         struct cops_local *lp;
X 	static unsigned version_printed = 0;
@@ -348,7 +348,7 @@
X         return 0;
X }
X 
-__initfunc(static int cops_irq (int ioaddr, int board))
+static int __init cops_irq (int ioaddr, int board)
X {       /*
X          * This does not use the IRQ to determine where the IRQ is. We just
X          * assume that when we get a correct status response that it's the IRQ.
diff -u --recursive --new-file v2.3.9/linux/drivers/net/cosa.c linux/drivers/net/cosa.c
--- v2.3.9/linux/drivers/net/cosa.c	Mon Jun  7 16:18:58 1999
+++ linux/drivers/net/cosa.c	Tue Jul  6 19:05:49 1999
@@ -362,7 +362,7 @@
X #ifdef MODULE
X int init_module(void)
X #else
-__initfunc(static int cosa_init(void))
+static int __init cosa_init(void)
X #endif
X {
X 	int i;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/cs89x0.c linux/drivers/net/cs89x0.c
--- v2.3.9/linux/drivers/net/cs89x0.c	Mon Jun  7 16:18:58 1999
+++ linux/drivers/net/cs89x0.c	Tue Jul  6 19:05:49 1999
@@ -145,8 +145,8 @@
X struct netdev_entry netcard_drv =
X {"netcard", cs89x0_probe1, NETCARD_IO_EXTENT, netcard_portlist};
X #else
-__initfunc(int
-cs89x0_probe(struct device *dev))
+int __init 
+cs89x0_probe(struct device *dev)
X {
X 	int i;
X 	int base_addr = dev ? dev->base_addr : 0;
@@ -195,8 +195,8 @@
X 	outw(value, dev->base_addr + portno);
X }
X 
-__initfunc(static int
-wait_eeprom_ready(struct device *dev))
+static int __init 
+wait_eeprom_ready(struct device *dev)
X {
X 	int timeout = jiffies;
X 	/* check to see if the EEPROM is ready, a timeout is used -
@@ -208,8 +208,8 @@
X 	return 0;
X }
X 
-__initfunc(static int
-get_eeprom_data(struct device *dev, int off, int len, int *buffer))
+static int __init 
+get_eeprom_data(struct device *dev, int off, int len, int *buffer)
X {
X 	int i;
X 
@@ -226,8 +226,8 @@
X         return 0;
X }
X 
-__initfunc(static int
-get_eeprom_cksum(int off, int len, int *buffer))
+static int  __init 
+get_eeprom_cksum(int off, int len, int *buffer)
X {
X 	int i, cksum;
X 
@@ -244,7 +244,7 @@
X    probes on the ISA bus.  A good device probes avoids doing writes, and
X    verifies that the correct device exists and functions.  */
X 
-__initfunc(static int cs89x0_probe1(struct device *dev, int ioaddr))
+static int __init cs89x0_probe1(struct device *dev, int ioaddr)
X {
X 	struct net_local *lp;
X 	static unsigned version_printed = 0;
@@ -390,10 +390,8 @@
X 	return 0;
X }
X 
-
-
-__initfunc(void
-reset_chip(struct device *dev))
+void  __init 
+reset_chip(struct device *dev)
X {
X 	struct net_local *lp = (struct net_local *)dev->priv;
X 	int ioaddr = dev->base_addr;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- v2.3.9/linux/drivers/net/de4x5.c	Sat May  8 19:46:44 1999
+++ linux/drivers/net/de4x5.c	Tue Jul  6 19:05:49 1999
@@ -1106,8 +1106,8 @@
X ** Autoprobing in modules is allowed here. See the top of the file for
X ** more info.
X */
-__initfunc(int
-de4x5_probe(struct device *dev))
+int __init 
+de4x5_probe(struct device *dev)
X {
X     u_long iobase = dev->base_addr;
X 
@@ -1121,8 +1121,8 @@
X     return (dev->priv ? 0 : -ENODEV);
X }
X 
-__initfunc(static int
-de4x5_hw_init(struct device *dev, u_long iobase))
+static int __init 
+de4x5_hw_init(struct device *dev, u_long iobase)
X {
X     struct bus_type *lp = &bus;
X     int i, status=0;
@@ -2054,8 +2054,8 @@
X ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
X ** the motherboard. Upto 15 EISA devices are supported.
X */
-__initfunc(static void
-eisa_probe(struct device *dev, u_long ioaddr))
+static void __init 
+eisa_probe(struct device *dev, u_long ioaddr)
X {
X     int i, maxSlots, status, device;
X     u_char irq;
@@ -2136,8 +2136,8 @@
X */
X #define PCI_LAST_DEV  32
X 
-__initfunc(static void
-pci_probe(struct device *dev, u_long ioaddr))
+static void __init 
+pci_probe(struct device *dev, u_long ioaddr)
X {
X     u_char pb, pbus, dev_num, dnum, timer;
X     u_short vendor, index, status;
@@ -2248,8 +2248,8 @@
X ** DECchips, we can find the base SROM irrespective of the BIOS scan direction.
X ** For single port cards this is a time waster...
X */
-__initfunc(static void
-srom_search(struct pci_dev *dev))
+static void __init 
+srom_search(struct pci_dev *dev)
X {
X     u_char pb;
X     u_short vendor, status;
@@ -2307,8 +2307,8 @@
X     return;
X }
X 
-__initfunc(static void
-link_modules(struct device *dev, struct device *tmp))
+static void __init 
+link_modules(struct device *dev, struct device *tmp)
X {
X     struct device *p=dev;
X 
@@ -5559,17 +5559,15 @@
X     switch(ioc->cmd) {
X     case DE4X5_GET_HWADDR:           /* Get the hardware address */
X 	ioc->len = ETH_ALEN;
-	if (verify_area(VERIFY_WRITE, ioc->data, ioc->len)) return -EFAULT;
X 	for (i=0; i<ETH_ALEN; i++) {
X 	    tmp.addr[i] = dev->dev_addr[i];
X 	}
-	copy_to_user(ioc->data, tmp.addr, ioc->len);
+	if (copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT;
X 	break;
X 
X     case DE4X5_SET_HWADDR:           /* Set the hardware address */
X 	if (!capable(CAP_NET_ADMIN)) return -EPERM;
-	if (verify_area(VERIFY_READ, ioc->data, ETH_ALEN)) return -EFAULT;
-	copy_from_user(tmp.addr, ioc->data, ETH_ALEN);
+	if (copy_from_user(tmp.addr, ioc->data, ETH_ALEN)) return -EFAULT;
X 	for (i=0; i<ETH_ALEN; i++) {
X 	    dev->dev_addr[i] = tmp.addr[i];
X 	}
@@ -5612,9 +5610,8 @@
X 
X     case DE4X5_GET_STATS:            /* Get the driver statistics */
X 	ioc->len = sizeof(lp->pktStats);
-	if (verify_area(VERIFY_WRITE, ioc->data, ioc->len)) return -EFAULT;
X 	spin_lock_irqsave(&lp->lock, flags);
-	copy_to_user(ioc->data, &lp->pktStats, ioc->len); 
+	if (copy_to_user(ioc->data, &lp->pktStats, ioc->len)) return -EFAULT; 
X 	spin_unlock_irqrestore(&lp->lock, flags);
X 	break;
X 
@@ -5627,14 +5624,12 @@
X 
X     case DE4X5_GET_OMR:              /* Get the OMR Register contents */
X 	tmp.addr[0] = inl(DE4X5_OMR);
-	if (verify_area(VERIFY_WRITE, ioc->data, 1)) return -EFAULT;
-	copy_to_user(ioc->data, tmp.addr, 1);
+	if (copy_to_user(ioc->data, tmp.addr, 1)) return -EFAULT;
X 	break;
X 
X     case DE4X5_SET_OMR:              /* Set the OMR Register contents */
X 	if (!capable(CAP_NET_ADMIN)) return -EPERM;
-	if (verify_area(VERIFY_READ, ioc->data, 1)) return -EFAULT;
-	copy_from_user(tmp.addr, ioc->data, 1);
+	if (copy_from_user(tmp.addr, ioc->data, 1)) return -EFAULT;
X 	outl(tmp.addr[0], DE4X5_OMR);
X 	break;
X 
@@ -5649,8 +5644,7 @@
X 	tmp.lval[6] = inl(DE4X5_STRR); j+=4;
X 	tmp.lval[7] = inl(DE4X5_SIGR); j+=4;
X 	ioc->len = j;
-	if (verify_area(VERIFY_WRITE, ioc->data, ioc->len)) return -EFAULT;
-	copy_to_user(ioc->data, tmp.addr, ioc->len);
+	if (copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT;
X 	break;
X 	
X #define DE4X5_DUMP              0x0f /* Dump the DE4X5 Status */
@@ -5739,8 +5733,7 @@
X 	tmp.addr[j++] = dev->tbusy;
X 	
X 	ioc->len = j;
-	if (verify_area(VERIFY_WRITE, ioc->data, ioc->len)) return -EFAULT;
-	copy_to_user(ioc->data, tmp.addr, ioc->len);
+	if (copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT;
X 	break;
X 
X */
@@ -5863,8 +5856,8 @@
X ** If at end of eth device list and can't use current entry, malloc
X ** one up. If memory could not be allocated, print an error message.
X */
-__initfunc(static struct device *
-insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)))
+static struct device * __init 
+insert_device(struct device *dev, u_long iobase, int (*init)(struct device *))
X {
X     struct device *new;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/de600.c linux/drivers/net/de600.c
--- v2.3.9/linux/drivers/net/de600.c	Tue Feb 10 12:56:44 1998
+++ linux/drivers/net/de600.c	Tue Jul  6 19:05:49 1999
@@ -627,8 +627,8 @@
X 	 */
X }
X 
-__initfunc(int
-de600_probe(struct device *dev))
+int __init 
+de600_probe(struct device *dev)
X {
X 	int	i;
X 	static struct net_device_stats de600_netstats;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/de620.c linux/drivers/net/de620.c
--- v2.3.9/linux/drivers/net/de620.c	Sat May 15 23:43:04 1999
+++ linux/drivers/net/de620.c	Tue Jul  6 19:05:49 1999
@@ -820,8 +820,8 @@
X  *
X  * Check if there is a DE-620 connected
X  */
-__initfunc(int
-de620_probe(struct device *dev))
+int __init 
+de620_probe(struct device *dev)
X {
X 	static struct net_device_stats de620_netstats;
X 	int i;
@@ -913,8 +913,8 @@
X  */
X #define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister);
X 
-__initfunc(static unsigned short
-ReadAWord(struct device *dev, int from))
+static unsigned short __init 
+ReadAWord(struct device *dev, int from)
X {
X 	unsigned short data;
X 	int nbits;
@@ -956,8 +956,8 @@
X 	return data;
X }
X 
-__initfunc(static int
-read_eeprom(struct device *dev))
+static int __init 
+read_eeprom(struct device *dev)
X {
X 	unsigned short wrd;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/defxx.c linux/drivers/net/defxx.c
--- v2.3.9/linux/drivers/net/defxx.c	Fri Apr 16 13:58:46 1999
+++ linux/drivers/net/defxx.c	Tue Jul  6 19:05:49 1999
@@ -446,11 +446,8 @@
X  *   the device structure.
X  */
X 
-__initfunc(int dfx_probe(
-	struct device *dev
-	))
-
-	{
+int __init dfx_probe(struct device *dev)
+{
X 	int				i;				/* used in for loops */
X 	int				version_disp;	/* was version info string already displayed? */
X 	int				port_len;		/* length of port address range (in bytes) */
@@ -641,12 +638,8 @@
X  *   None
X  */
X 
-__initfunc(struct device *dfx_alloc_device(
-	struct device	*dev,
-	u16				iobase
-	))
-
-	{
+struct device __init *dfx_alloc_device( struct device *dev, u16 iobase)
+{
X 	struct device *tmp_dev;		/* pointer to a device structure */
X 
X 	DBG_printk("In dfx_alloc_device...\n");
@@ -736,11 +729,8 @@
X  *   enabled yet.
X  */
X 
-__initfunc(void dfx_bus_init(
-	struct device *dev
-	))
-
-	{
+void __init dfx_bus_init(struct device *dev)
+{
X 	DFX_board_t *bp = (DFX_board_t *)dev->priv;
X 	u8			val;	/* used for I/O read/writes */
X 
@@ -871,11 +861,8 @@
X  *   None
X  */
X 
-__initfunc(void dfx_bus_config_check(
-	DFX_board_t *bp
-	))
-
-	{
+void __init dfx_bus_config_check(DFX_board_t *bp)
+{
X 	int	status;				/* return code from adapter port control call */
X 	u32	slot_id;			/* EISA-bus hardware id (DEC3001, DEC3002,...) */
X 	u32	host_data;			/* LW data returned from port control call */
@@ -975,11 +962,8 @@
X  *   returning from this routine.
X  */
X 
-__initfunc(int dfx_driver_init(
-	struct device *dev
-	))
-
-	{
+int __init dfx_driver_init(struct device *dev)
+{
X 	DFX_board_t *bp = (DFX_board_t *)dev->priv;
X 	int			alloc_size;			/* total buffer size needed */
X 	char		*top_v, *curr_v;	/* virtual addrs into memory block */
diff -u --recursive --new-file v2.3.9/linux/drivers/net/depca.c linux/drivers/net/depca.c
--- v2.3.9/linux/drivers/net/depca.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/net/depca.c	Tue Jul  6 19:05:49 1999
@@ -476,10 +476,8 @@
X     outw(CSR0, DEPCA_ADDR);\
X     outw(STOP, DEPCA_DATA)
X 
-
-
-__initfunc(int
-depca_probe(struct device *dev))
+int __init 
+depca_probe(struct device *dev)
X {
X   int tmp = num_depcas, status = -ENODEV;
X   u_long iobase = dev->base_addr;
@@ -512,8 +510,8 @@
X   return status;
X }
X 
-__initfunc(static int
-depca_hw_init(struct device *dev, u_long ioaddr, int mca_slot))
+static int __init 
+depca_hw_init(struct device *dev, u_long ioaddr, int mca_slot)
X {
X   struct depca_private *lp;
X   int i, j, offset, netRAM, mem_len, status=0;
@@ -1250,8 +1248,8 @@
X /*
X ** Microchannel bus I/O device probe
X */
-__initfunc(static void
-mca_probe(struct device *dev, u_long ioaddr))
+static void __init 
+mca_probe(struct device *dev, u_long ioaddr)
X {
X     unsigned char pos[2];
X     unsigned char where;
@@ -1399,8 +1397,8 @@
X /*
X ** ISA bus I/O device probe
X */
-__initfunc(static void
-isa_probe(struct device *dev, u_long ioaddr))
+static void __init 
+isa_probe(struct device *dev, u_long ioaddr)
X {
X   int i = num_depcas, maxSlots;
X   s32 ports[] = DEPCA_IO_PORTS;
@@ -1438,8 +1436,8 @@
X ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
X ** the motherboard. Upto 15 EISA devices are supported.
X */
-__initfunc(static void
-eisa_probe(struct device *dev, u_long ioaddr))
+static void __init 
+eisa_probe(struct device *dev, u_long ioaddr)
X {
X   int i, maxSlots;
X   u_long iobase;
@@ -1485,8 +1483,8 @@
X ** are not available then insert a new device structure at the end of
X ** the current list.
X */
-__initfunc(static struct device *
-alloc_device(struct device *dev, u_long iobase))
+static struct device * __init 
+alloc_device(struct device *dev, u_long iobase)
X {
X     struct device *adev = NULL;
X     int fixed = 0, new_dev = 0;
@@ -1530,8 +1528,8 @@
X ** If at end of eth device list and can't use current entry, malloc
X ** one up. If memory could not be allocated, print an error message.
X */
-__initfunc(static struct device *
-insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)))
+static struct device * __init 
+insert_device(struct device *dev, u_long iobase, int (*init)(struct device *))
X {
X     struct device *new;
X 
@@ -1556,8 +1554,8 @@
X     return dev;
X }
X 
-__initfunc(static int
-depca_dev_index(char *s))
+static int __init 
+depca_dev_index(char *s)
X {
X     int i=0, j=0;
X 
@@ -1576,8 +1574,8 @@
X ** and Boot (readb) ROM. This will also give us a clue to the network RAM
X ** base address.
X */
-__initfunc(static void
-DepcaSignature(char *name, u_long paddr))
+static void __init 
+DepcaSignature(char *name, u_long paddr)
X {
X   u_int i,j,k;
X   const char *signatures[] = DEPCA_SIGNATURE;
@@ -1629,8 +1627,8 @@
X ** PROM address counter is correctly positioned at the start of the
X ** ethernet address for later read out.
X */
-__initfunc(static int
-DevicePresent(u_long ioaddr))
+static int __init 
+DevicePresent(u_long ioaddr)
X {
X   union {
X     struct {
@@ -1682,8 +1680,8 @@
X ** reason: access the upper half of the PROM with x=0; access the lower half
X ** with x=1.
X */
-__initfunc(static int
-get_hw_addr(struct device *dev))
+static int __init 
+get_hw_addr(struct device *dev)
X {
X   u_long ioaddr = dev->base_addr;
X   int i, k, tmp, status = 0;
@@ -1771,8 +1769,8 @@
X /*
X ** Look for a particular board name in the EISA configuration space
X */
-__initfunc(static int
-EISA_signature(char *name, s32 eisa_id))
+static int __init 
+EISA_signature(char *name, s32 eisa_id)
X {
X   u_int i;
X   const char *signatures[] = DEPCA_SIGNATURE;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/dgrs.c linux/drivers/net/dgrs.c
--- v2.3.9/linux/drivers/net/dgrs.c	Tue Dec 29 11:32:06 1998
+++ linux/drivers/net/dgrs.c	Tue Jul  6 19:05:49 1999
@@ -991,8 +991,8 @@
X /*
X  *	Download the board firmware
X  */
-__initfunc(static int
-dgrs_download(struct device *dev0))
+static int __init 
+dgrs_download(struct device *dev0)
X {
X 	DGRS_PRIV	*priv0 = (DGRS_PRIV *) dev0->priv;
X 	int		is;
@@ -1150,8 +1150,8 @@
X /*
X  *	Probe (init) a board
X  */
-__initfunc(int
-dgrs_probe1(struct device *dev))
+int __init 
+dgrs_probe1(struct device *dev)
X {
X 	DGRS_PRIV	*priv = (DGRS_PRIV *) dev->priv;
X 	int		i;
@@ -1224,8 +1224,8 @@
X 	return (0);
X }
X 
-__initfunc(int
-dgrs_initclone(struct device *dev))
+int __init 
+dgrs_initclone(struct device *dev)
X {
X 	DGRS_PRIV	*priv = (DGRS_PRIV *) dev->priv;
X 	int		i;
@@ -1239,7 +1239,7 @@
X 	return (0);
X }
X 
-__initfunc(static int
+static int __init 
X dgrs_found_device(
X 	struct device	*dev,
X 	int		io,
@@ -1247,7 +1247,7 @@
X 	int		irq,
X 	ulong		plxreg,
X 	ulong		plxdma
-))
+)
X {
X 	DGRS_PRIV	*priv;
X 
@@ -1360,8 +1360,8 @@
X  */
X static int is2iv[8] __initdata = { 0, 3, 5, 7, 10, 11, 12, 15 };
X 
-__initfunc(static int
-dgrs_scan(struct device *dev))
+static int __init 
+dgrs_scan(struct device *dev)
X {
X 	int	cards_found = 0;
X 	uint	io;
@@ -1614,8 +1614,8 @@
X 
X #else
X 
-__initfunc(int
-dgrs_probe(struct device *dev))
+int __init 
+dgrs_probe(struct device *dev)
X {
X 	int	cards_found;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/dlci.c linux/drivers/net/dlci.c
--- v2.3.9/linux/drivers/net/dlci.c	Wed May  6 10:56:04 1998
+++ linux/drivers/net/dlci.c	Tue Jul  6 19:05:49 1999
@@ -601,7 +601,7 @@
X 	return(0);
X }
X 
-__initfunc(int dlci_setup(void))
+int __init dlci_setup(void)
X {
X 	int i;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/dummy.c linux/drivers/net/dummy.c
--- v2.3.9/linux/drivers/net/dummy.c	Sun Oct  4 10:21:00 1998
+++ linux/drivers/net/dummy.c	Tue Jul  6 19:05:49 1999
@@ -80,7 +80,7 @@
X }
X #endif
X 
-__initfunc(int dummy_init(struct device *dev))
+int __init dummy_init(struct device *dev)
X {
X 	/* Initialize the device structure. */
X 	dev->hard_start_xmit	= dummy_xmit;
@@ -127,7 +127,7 @@
X 
X #ifdef MODULE
X 
-__initfunc(static int dummy_probe(struct device *dev))
+static int __init dummy_probe(struct device *dev)
X {
X 	dummy_init(dev);
X 	return 0;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/e2100.c linux/drivers/net/e2100.c
--- v2.3.9/linux/drivers/net/e2100.c	Wed Dec 16 13:35:49 1998
+++ linux/drivers/net/e2100.c	Tue Jul  6 19:05:49 1999
@@ -117,7 +117,7 @@
X 	station address).
X  */
X 
-__initfunc(int e2100_probe(struct device *dev))
+int  __init e2100_probe(struct device *dev)
X {
X 	int *port;
X 	int base_addr = dev->base_addr;
@@ -137,7 +137,7 @@
X 	return ENODEV;
X }
X 
-__initfunc(int e21_probe1(struct device *dev, int ioaddr))
+int __init e21_probe1(struct device *dev, int ioaddr)
X {
X 	int i, status;
X 	unsigned char *station_addr = dev->dev_addr;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c
--- v2.3.9/linux/drivers/net/eepro100.c	Sat Feb  6 12:46:21 1999
+++ linux/drivers/net/eepro100.c	Mon Jul  5 20:09:40 1999
@@ -41,7 +41,7 @@
X static int max_interrupt_work = 200;
X 
X /* Maximum number of multicast addresses to filter (vs. rx-all-multicast) */
-static int multicast_filter_limit = 64;
+static int multicast_filter_limit = 3;
X 
X #include <linux/module.h>
X 
@@ -343,7 +343,8 @@
X 	const char *product_name;
X 	struct device *next_module;
X 	spinlock_t lock;
-	struct TxFD	tx_ring[TX_RING_SIZE];	/* Commands (usually CmdTxPacket). */
+	struct TxFD	tx_ring[TX_RING_SIZE] 	/* Commands (usually CmdTxPacket). */
+				__attribute__ ((aligned (L1_CACHE_BYTES)));;
X 	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
X 	struct sk_buff* tx_skbuff[TX_RING_SIZE];
X 	struct descriptor  *last_cmd;	/* Last command sent. */
diff -u --recursive --new-file v2.3.9/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- v2.3.9/linux/drivers/net/eexpress.c	Sun May 30 10:18:49 1999
+++ linux/drivers/net/eexpress.c	Tue Jul  6 19:05:49 1999
@@ -325,7 +325,7 @@
X  * checks for presence of EtherExpress card
X  */
X 
-__initfunc(int express_probe(struct device *dev))
+int __init express_probe(struct device *dev)
X {
X 	unsigned short *port;
X 	static unsigned short ports[] = { 0x300,0x310,0x270,0x320,0x340,0 };
@@ -961,7 +961,7 @@
X  * than one card in a machine.
X  */
X 
-__initfunc(static int eexp_hw_probe(struct device *dev, unsigned short ioaddr))
+static int __init eexp_hw_probe(struct device *dev, unsigned short ioaddr)
X {
X 	unsigned short hw_addr[3];
X 	unsigned char buswidth;
@@ -1084,8 +1084,8 @@
X  * Read a word from the EtherExpress on-board serial EEPROM.
X  * The EEPROM contains 64 words of 16 bits.
X  */
-__initfunc(static unsigned short eexp_hw_readeeprom(unsigned short ioaddr,
-						    unsigned char location))
+static unsigned short __init eexp_hw_readeeprom(unsigned short ioaddr,
+						    unsigned char location)
X {
X 	unsigned short cmd = 0x180|(location&0x7f);
X 	unsigned short rval = 0,wval = EC_CS|i586_RST;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/eql.c linux/drivers/net/eql.c
--- v2.3.9/linux/drivers/net/eql.c	Mon May 10 13:00:10 1999
+++ linux/drivers/net/eql.c	Mon Jul  5 20:09:40 1999
@@ -209,7 +209,7 @@
X    ---------------------------------------------------------
X    */
X 
-__initfunc(int eql_init(struct device *dev))
+int __init eql_init(struct device *dev)
X {
X 	static unsigned version_printed = 0;
X 	/* static unsigned num_masters     = 0; */
@@ -411,16 +411,15 @@
X 	slaving_request_t srq;
X 	int err;
X 
-	err = verify_area(VERIFY_READ, (void *)srqp, sizeof (slaving_request_t));
+	err = copy_from_user(&srq, srqp, sizeof (slaving_request_t));
X 	if (err)  
X 	  {
X #ifdef EQL_DEBUG
X 	if (eql_debug >= 20)
-		printk ("EQL enslave: error detected by verify_area\n");
+		printk ("EQL enslave: error detected by copy_from_user\n");
X #endif  
X 		return err;
X 	  }
-	copy_from_user (&srq, srqp, sizeof (slaving_request_t));
X 
X #ifdef EQL_DEBUG
X 	if (eql_debug >= 20)
@@ -473,11 +472,10 @@
X 	slaving_request_t srq;
X 	int err;
X 
-	err = verify_area(VERIFY_READ, (void *)srqp, sizeof (slaving_request_t));
+	err = copy_from_user(&srq, srqp, sizeof (slaving_request_t));
X 	if (err) 
X 		return err;
X 
-	copy_from_user (&srq, srqp, sizeof (slaving_request_t));
X #ifdef EQL_DEBUG
X 	if (eql_debug >= 20)
X 		printk ("%s: emancipate `%s`\n", dev->name, srq.slave_name);
@@ -504,11 +502,10 @@
X 	slave_config_t sc;
X 	int err;
X 
-	err = verify_area(VERIFY_READ, (void *)scp, sizeof (slave_config_t));
+	err = copy_from_user (&sc, scp, sizeof (slave_config_t));
X 	if (err) 
X 		return err;
X 
-	copy_from_user (&sc, scp, sizeof (slave_config_t));
X #ifdef EQL_DEBUG
X 	if (eql_debug >= 20)
X 		printk ("%s: get config for slave `%s'\n", dev->name, sc.slave_name);
@@ -541,7 +538,7 @@
X 	slave_config_t sc;
X 	int err;
X 
-	err = verify_area(VERIFY_READ, (void *)scp, sizeof (slave_config_t));
+	err = copy_from_user (&sc, scp, sizeof (slave_config_t));
X 	if (err) 
X 		return err;
X 
@@ -550,7 +547,6 @@
X 		printk ("%s: set config for slave `%s'\n", dev->name, sc.slave_name);
X #endif
X   
-	copy_from_user (&sc, scp, sizeof (slave_config_t));
X 
X 	eql = (equalizer_t *) dev->priv;
X 	slave_dev = dev_get (sc.slave_name);
@@ -583,13 +579,12 @@
X 	if ( eql_is_master (dev) )
X 	{
X 		int err;
-		err = verify_area(VERIFY_WRITE, (void *)mcp, sizeof (master_config_t));
-		if (err) 
-			return err;
X 		eql = (equalizer_t *) dev->priv;
X 		mc.max_slaves = eql->max_slaves;
X 		mc.min_slaves = eql->min_slaves;
-		copy_to_user (mcp, &mc, sizeof (master_config_t));
+		err = copy_to_user (mcp, &mc, sizeof (master_config_t));
+		if (err) 
+			return err;
X 		return 0;
X 	}
X 	return -EINVAL;
@@ -602,14 +597,13 @@
X 	master_config_t mc;
X 	int err;
X 
-	err = verify_area(VERIFY_READ, (void *)mcp, sizeof (master_config_t));
+	err = copy_from_user (&mc, mcp, sizeof (master_config_t));
X 	if (err)
X 		return err;
X #if EQL_DEBUG
X 	if (eql_debug >= 20)
X 		printk ("%s: set master config\n", dev->name);
X #endif
-	copy_from_user (&mc, mcp, sizeof (master_config_t));
X 	if ( eql_is_master (dev) )
X 	{
X 		eql = (equalizer_t *) dev->priv;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/es3210.c linux/drivers/net/es3210.c
--- v2.3.9/linux/drivers/net/es3210.c	Wed Dec 16 13:35:49 1998
+++ linux/drivers/net/es3210.c	Tue Jul  6 19:05:49 1999
@@ -124,7 +124,7 @@
X  *	PROM for a match against the Racal-Interlan assigned value.
X  */
X 
-__initfunc(int es_probe(struct device *dev))
+int __init es_probe(struct device *dev)
X {
X 	unsigned short ioaddr = dev->base_addr;
X 
@@ -151,7 +151,7 @@
X 	return ENODEV;
X }
X 
-__initfunc(int es_probe1(struct device *dev, int ioaddr))
+int __init es_probe1(struct device *dev, int ioaddr)
X {
X 	int i;
X 	unsigned long eisa_id;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/eth16i.c linux/drivers/net/eth16i.c
--- v2.3.9/linux/drivers/net/eth16i.c	Thu Jan  7 08:46:59 1999
+++ linux/drivers/net/eth16i.c	Mon Jul  5 20:09:40 1999
@@ -450,7 +450,7 @@
X 
X #else  /* Not HAVE_DEVLIST */
X 
-__initfunc(int eth16i_probe(struct device *dev))
+int __init eth16i_probe(struct device *dev)
X {
X 	int i;
X 	int ioaddr;
@@ -484,7 +484,7 @@
X }
X #endif  /* Not HAVE_DEVLIST */
X 
-__initfunc(static int eth16i_probe1(struct device *dev, int ioaddr))
+static int __init eth16i_probe1(struct device *dev, int ioaddr)
X {
X 	static unsigned version_printed = 0;
X 	boot = 1;  /* To inform initilization that we are in boot probe */
@@ -886,7 +886,7 @@
X 	creg[0] &= 0x0F;      /* Mask collision cnr */
X 	creg[2] &= 0x7F;      /* Mask DCLEN bit */
X 
-#ifdef 0
+#if 0
X 	/* 
X 	   This was removed because the card was sometimes left to state
X 	   from which it couldn't be find anymore. If there is need
diff -u --recursive --new-file v2.3.9/linux/drivers/net/ethertap.c linux/drivers/net/ethertap.c
--- v2.3.9/linux/drivers/net/ethertap.c	Tue May 11 08:24:31 1999
+++ linux/drivers/net/ethertap.c	Tue Jul  6 19:05:49 1999
@@ -65,7 +65,7 @@
X  *	hardware it would have to check what was present.
X  */
X  
-__initfunc(int ethertap_probe(struct device *dev))
+int __init ethertap_probe(struct device *dev)
X {
X 	memcpy(dev->dev_addr, "\xFE\xFD\x00\x00\x00\x00", 6);
X 	if (dev->mem_start & 0xf)
diff -u --recursive --new-file v2.3.9/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
--- v2.3.9/linux/drivers/net/ewrk3.c	Thu May 21 14:24:06 1998
+++ linux/drivers/net/ewrk3.c	Mon Jul  5 20:09:40 1999
@@ -342,11 +342,8 @@
X     outb(EEPROM_INIT, EWRK3_IOPR);\
X     mdelay(1);\
X }
-
-
-
X 
-__initfunc(int ewrk3_probe(struct device *dev))
+int __init ewrk3_probe(struct device *dev)
X {
X 	int tmp = num_ewrk3s, status = -ENODEV;
X 	u_long iobase = dev->base_addr;
@@ -378,8 +375,8 @@
X 	return status;
X }
X 
-__initfunc(static int
-	   ewrk3_hw_init(struct device *dev, u_long iobase))
+static int __init 
+ewrk3_hw_init(struct device *dev, u_long iobase)
X {
X 	struct ewrk3_private *lp;
X 	int i, status = 0;
@@ -1285,7 +1282,7 @@
X /*
X    ** ISA bus I/O device probe
X  */
-__initfunc(static void isa_probe(struct device *dev, u_long ioaddr))
+static void __init isa_probe(struct device *dev, u_long ioaddr)
X {
X 	int i = num_ewrk3s, maxSlots;
X 	u_long iobase;
@@ -1325,7 +1322,7 @@
X    ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
X    ** the motherboard.
X  */
-__initfunc(static void eisa_probe(struct device *dev, u_long ioaddr))
+static void __init eisa_probe(struct device *dev, u_long ioaddr)
X {
X 	int i, maxSlots;
X 	u_long iobase;
@@ -1372,8 +1369,8 @@
X    ** are not available then insert a new device structure at the end of
X    ** the current list.
X  */
-__initfunc(static struct device *
-	   alloc_device(struct device *dev, u_long iobase))
+static struct device * __init 
+alloc_device(struct device *dev, u_long iobase)
X {
X 	struct device *adev = NULL;
X 	int fixed = 0, new_dev = 0;
@@ -1417,8 +1414,8 @@
X    ** If at end of eth device list and can't use current entry, malloc
X    ** one up. If memory could not be allocated, print an error message.
X  */
-__initfunc(static struct device *
-	   insert_device(struct device *dev, u_long iobase, int (*init) (struct device *)))
+static __init struct device *
+insert_device(struct device *dev, u_long iobase, int (*init) (struct device *))
X {
X 	struct device *new;
X 
@@ -1443,8 +1440,8 @@
X 	return dev;
X }
X 
-__initfunc(static int
-	   ewrk3_dev_index(char *s))
+static int __init 
+ewrk3_dev_index(char *s)
X {
X 	int i = 0, j = 0;
X 
@@ -1499,7 +1496,7 @@
X /*
X    ** Look for a particular board name in the on-board EEPROM.
X  */
-__initfunc(static void EthwrkSignature(char *name, char *eeprom_image))
+static void __init EthwrkSignature(char *name, char *eeprom_image)
X {
X 	u_long i, j, k;
X 	char *signatures[] = EWRK3_SIGNATURE;
@@ -1536,7 +1533,7 @@
X    ** ethernet address for later read out.
X  */
X 
-__initfunc(static int DevicePresent(u_long iobase))
+static int __init DevicePresent(u_long iobase)
X {
X 	union {
X 		struct {
@@ -1573,7 +1570,7 @@
X 	return status;
X }
X 
-__initfunc(static u_char get_hw_addr(struct device *dev, u_char * eeprom_image, char chipType))
+static u_char __init get_hw_addr(struct device *dev, u_char * eeprom_image, char chipType)
X {
X 	int i, j, k;
X 	u_short chksum;
@@ -1624,7 +1621,7 @@
X /*
X    ** Look for a particular board name in the EISA configuration space
X  */
-__initfunc(static int EISA_signature(char *name, s32 eisa_id))
+static int __init EISA_signature(char *name, s32 eisa_id)
X {
X 	u_long i;
X 	char *signatures[] = EWRK3_SIGNATURE;
@@ -1679,18 +1676,20 @@
X 			tmp.addr[i] = dev->dev_addr[i];
X 		}
X 		ioc->len = ETH_ALEN;
-		if (!(status = verify_area(VERIFY_WRITE, (void *) ioc->data, ioc->len))) {
-			copy_to_user(ioc->data, tmp.addr, ioc->len);
+		if (copy_to_user(ioc->data, tmp.addr, ioc->len)) {
+			status = -EFAULT;
+			break;
X 		}
-		break;
X 	case EWRK3_SET_HWADDR:	/* Set the hardware address */
X 		if (capable(CAP_NET_ADMIN)) {
-			if (!(status = verify_area(VERIFY_READ, (void *) ioc->data, ETH_ALEN))) {
X 				csr = inb(EWRK3_CSR);
X 				csr |= (CSR_TXD | CSR_RXD);
X 				outb(csr, EWRK3_CSR);	/* Disable the TX and RX */
X 
-				copy_from_user(tmp.addr, ioc->data, ETH_ALEN);
+				if (copy_from_user(tmp.addr, ioc->data, ETH_ALEN)) {
+					status = -EFAULT;
+					break;
+				}
X 				for (i = 0; i < ETH_ALEN; i++) {
X 					dev->dev_addr[i] = tmp.addr[i];
X 					outb(tmp.addr[i], EWRK3_PAR0 + i);
@@ -1698,7 +1697,6 @@
X 
X 				csr &= ~(CSR_TXD | CSR_RXD);	/* Enable the TX and RX */
X 				outb(csr, EWRK3_CSR);
-			}
X 		} else {
X 			status = -EPERM;
X 		}
@@ -1730,7 +1728,6 @@
X 
X 		break;
X 	case EWRK3_GET_MCA:	/* Get the multicast address table */
-		if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
X 			while (test_and_set_bit(0, (void *) &lp->lock) != 0);	/* Wait for lock to free */
X 			if (lp->shmem_length == IO_ONLY) {
X 				outb(0, EWRK3_IOPR);
@@ -1743,17 +1740,21 @@
X 				memcpy_fromio(tmp.addr, (char *) (lp->shmem_base + PAGE0_HTE), (HASH_TABLE_LEN >> 3));
X 			}
X 			ioc->len = (HASH_TABLE_LEN >> 3);
-			copy_to_user(ioc->data, tmp.addr, ioc->len);
-		}
+			if (copy_to_user(ioc->data, tmp.addr, ioc->len)) {
+				status = -EFAULT;
+				break;
+			}
+
X 		lp->lock = 0;	/* Unlock the page register */
X 
X 		break;
X 	case EWRK3_SET_MCA:	/* Set a multicast address */
X 		if (capable(CAP_NET_ADMIN)) {
-			if (!(status = verify_area(VERIFY_READ, ioc->data, ETH_ALEN * ioc->len))) {
-				copy_from_user(tmp.addr, ioc->data, ETH_ALEN * ioc->len);
-				set_multicast_list(dev);
+			if (copy_from_user(tmp.addr, ioc->data, ETH_ALEN * ioc->len)) {
+				status = -EFAULT;
+				break;
X 			}
+			set_multicast_list(dev);
X 		} else {
X 			status = -EPERM;
X 		}
@@ -1781,9 +1782,8 @@
X 	case EWRK3_GET_STATS:	/* Get the driver statistics */
X 		cli();
X 		ioc->len = sizeof(lp->pktStats);
-		if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
-			copy_to_user(ioc->data, &lp->pktStats, ioc->len);
-		}
+		if (copy_to_user(ioc->data, &lp->pktStats, ioc->len))
+			status = -EFAULT;
X 		sti();
X 
X 		break;
@@ -1800,16 +1800,16 @@
X 	case EWRK3_GET_CSR:	/* Get the CSR Register contents */
X 		tmp.addr[0] = inb(EWRK3_CSR);
X 		ioc->len = 1;
-		if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
-			copy_to_user(ioc->data, tmp.addr, ioc->len);
-		}
+		if (copy_to_user(ioc->data, tmp.addr, ioc->len))
+			status = -EFAULT;
X 		break;
X 	case EWRK3_SET_CSR:	/* Set the CSR Register contents */
X 		if (capable(CAP_NET_ADMIN)) {
-			if (!(status = verify_area(VERIFY_READ, ioc->data, 1))) {
-				copy_from_user(tmp.addr, ioc->data, 1);
-				outb(tmp.addr[0], EWRK3_CSR);
+			if (copy_from_user(tmp.addr, ioc->data, 1)) {
+				status = -EFAULT;
+				break;
X 			}
+			outb(tmp.addr[0], EWRK3_CSR);
X 		} else {
X 			status = -EPERM;
X 		}
@@ -1826,9 +1826,8 @@
X 				tmp.addr[i++] = inb(EWRK3_PAR0 + j);
X 			}
X 			ioc->len = EEPROM_MAX + 1 + ETH_ALEN;
-			if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
-				copy_to_user(ioc->data, tmp.addr, ioc->len);
-			}
+			if (copy_to_user(ioc->data, tmp.addr, ioc->len))
+				status = -EFAULT;
X 		} else {
X 			status = -EPERM;
X 		}
@@ -1836,11 +1835,12 @@
X 		break;
X 	case EWRK3_SET_EEPROM:	/* Set the EEPROM contents */
X 		if (capable(CAP_NET_ADMIN)) {
-			if (!(status = verify_area(VERIFY_READ, ioc->data, EEPROM_MAX))) {
-				copy_from_user(tmp.addr, ioc->data, EEPROM_MAX);
-				for (i = 0; i < (EEPROM_MAX >> 1); i++) {
-					Write_EEPROM(tmp.val[i], iobase, i);
-				}
+			if (copy_from_user(tmp.addr, ioc->data, EEPROM_MAX)) {
+				status = -EFAULT;
+				break;
+			}
+			for (i = 0; i < (EEPROM_MAX >> 1); i++) {
+				Write_EEPROM(tmp.val[i], iobase, i);
X 			}
X 		} else {
X 			status = -EPERM;
@@ -1850,9 +1850,8 @@
X 	case EWRK3_GET_CMR:	/* Get the CMR Register contents */
X 		tmp.addr[0] = inb(EWRK3_CMR);
X 		ioc->len = 1;
-		if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
-			copy_to_user(ioc->data, tmp.addr, ioc->len);
-		}
+		if (copy_to_user(ioc->data, tmp.addr, ioc->len))
+			status = -EFAULT;
X 		break;
X 	case EWRK3_SET_TX_CUT_THRU:	/* Set TX cut through mode */
X 		if (suser()) {
diff -u --recursive --new-file v2.3.9/linux/drivers/net/fmv18x.c linux/drivers/net/fmv18x.c
--- v2.3.9/linux/drivers/net/fmv18x.c	Tue Jan 19 10:13:13 1999
+++ linux/drivers/net/fmv18x.c	Tue Jul  6 19:05:49 1999
@@ -132,8 +132,8 @@
X struct netdev_entry fmv18x_drv =
X {"fmv18x", fmv18x_probe1, FMV18X_IO_EXTENT, fmv18x_probe_list};
X #else
-__initfunc(int
-fmv18x_probe(struct device *dev))
+int __init 
+fmv18x_probe(struct device *dev)
X {
X 	int i;
X 	int base_addr = dev ? dev->base_addr : 0;
@@ -163,7 +163,7 @@
X    that can be done is checking a few bits and then diving right into MAC
X    address check. */
X 
-__initfunc(int fmv18x_probe1(struct device *dev, short ioaddr))
+int __init fmv18x_probe1(struct device *dev, short ioaddr)
X {
X 	char irqmap[4] = {3, 7, 10, 15};
X 	char irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hamradio/6pack.c linux/drivers/net/hamradio/6pack.c
--- v2.3.9/linux/drivers/net/hamradio/6pack.c	Fri Nov 20 08:44:06 1998
+++ linux/drivers/net/hamradio/6pack.c	Tue Jul  6 19:05:49 1999
@@ -726,7 +726,7 @@
X #ifdef MODULE
X static int sixpack_init_ctrl_dev(void)
X #else	/* !MODULE */
-__initfunc(int sixpack_init_ctrl_dev(struct device *dummy))
+int __init sixpack_init_ctrl_dev(struct device *dummy)
X #endif	/* !MODULE */
X {
X 	int status;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hamradio/baycom_par.c linux/drivers/net/hamradio/baycom_par.c
--- v2.3.9/linux/drivers/net/hamradio/baycom_par.c	Fri Oct  9 12:20:27 1998
+++ linux/drivers/net/hamradio/baycom_par.c	Tue Jul  6 19:05:49 1999
@@ -533,7 +533,7 @@
X 
X /* --------------------------------------------------------------------- */
X 
-__initfunc(int baycom_par_init(void))
+int __init baycom_par_init(void)
X {
X 	int i, j, found = 0;
X 	char set_hw = 1;
@@ -593,7 +593,7 @@
X 
X #endif
X 
-__initfunc(int init_module(void))
+int __init init_module(void)
X {
X 	int i;
X 
@@ -633,7 +633,7 @@
X  * mode: par96,picpar
X  */
X 
-__initfunc(void baycom_par_setup(char *str, int *ints))
+void __init baycom_par_setup(char *str, int *ints)
X {
X 	int i;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hamradio/baycom_ser_fdx.c linux/drivers/net/hamradio/baycom_ser_fdx.c
--- v2.3.9/linux/drivers/net/hamradio/baycom_ser_fdx.c	Sun Jan 17 18:28:06 1999
+++ linux/drivers/net/hamradio/baycom_ser_fdx.c	Tue Jul  6 19:05:49 1999
@@ -605,7 +605,7 @@
X 
X /* --------------------------------------------------------------------- */
X 
-__initfunc(int baycom_ser_fdx_init(void))
+int __init baycom_ser_fdx_init(void)
X {
X 	int i, j, found = 0;
X 	char set_hw = 1;
@@ -673,7 +673,7 @@
X 
X #endif
X 
-__initfunc(int init_module(void))
+int __init init_module(void)
X {
X 	int i;
X 
@@ -716,7 +716,7 @@
X  * * indicates sofware DCD
X  */
X 
-__initfunc(void baycom_ser_fdx_setup(char *str, int *ints))
+void __init baycom_ser_fdx_setup(char *str, int *ints)
X {
X 	int i;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hamradio/baycom_ser_hdx.c linux/drivers/net/hamradio/baycom_ser_hdx.c
--- v2.3.9/linux/drivers/net/hamradio/baycom_ser_hdx.c	Sun Jan 17 18:28:06 1999
+++ linux/drivers/net/hamradio/baycom_ser_hdx.c	Tue Jul  6 19:05:49 1999
@@ -643,7 +643,7 @@
X 
X /* --------------------------------------------------------------------- */
X 
-__initfunc(int baycom_ser_hdx_init(void))
+int __init baycom_ser_hdx_init(void)
X {
X 	int i, j, found = 0;
X 	char set_hw = 1;
@@ -707,7 +707,7 @@
X 
X #endif
X 
-__initfunc(int init_module(void))
+int __init init_module(void)
X {
X 	int i;
X 
@@ -749,7 +749,7 @@
X  * * indicates sofware DCD
X  */
X 
-__initfunc(void baycom_ser_hdx_setup(char *str, int *ints))
+void __init baycom_ser_hdx_setup(char *str, int *ints)
X {
X 	int i;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hamradio/bpqether.c linux/drivers/net/hamradio/bpqether.c
--- v2.3.9/linux/drivers/net/hamradio/bpqether.c	Tue May 25 13:06:34 1999
+++ linux/drivers/net/hamradio/bpqether.c	Tue Jul  6 19:05:49 1999
@@ -621,7 +621,7 @@
X  * Initialize driver. To be called from af_ax25 if not compiled as a
X  * module
X  */
-__initfunc(int bpq_init(void))
+int __init bpq_init(void)
X {
X 	struct device *dev;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hamradio/dmascc.c linux/drivers/net/hamradio/dmascc.c
--- v2.3.9/linux/drivers/net/hamradio/dmascc.c	Fri Oct  9 11:56:59 1998
+++ linux/drivers/net/hamradio/dmascc.c	Tue Jul  6 19:05:49 1999
@@ -336,7 +336,7 @@
X #else
X 
X 
-__initfunc(void dmascc_setup(char *str, int *ints))
+void __init dmascc_setup(char *str, int *ints)
X {
X    int i;
X 
@@ -350,7 +350,7 @@
X 
X /* Initialization functions */
X 
-__initfunc(int dmascc_init(void))
+int __init dmascc_init(void)
X {
X   int h, i, j, n;
X   int base[MAX_NUM_DEVS], tcmd[MAX_NUM_DEVS], t0[MAX_NUM_DEVS],
@@ -453,8 +453,7 @@
X   return -EIO;
X }
X 
-
-__initfunc(int setup_adapter(int io, int h, int n))
+int __init setup_adapter(int io, int h, int n)
X {
X   int i, irq, chip;
X   struct scc_info *info;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hamradio/hdlcdrv.c linux/drivers/net/hamradio/hdlcdrv.c
--- v2.3.9/linux/drivers/net/hamradio/hdlcdrv.c	Tue Dec 29 11:30:56 1998
+++ linux/drivers/net/hamradio/hdlcdrv.c	Tue Jul  6 19:05:49 1999
@@ -43,7 +43,6 @@
X #include <linux/config.h>
X #include <linux/version.h>
X #include <linux/module.h>
-#include <linux/version.h>
X #include <linux/types.h>
X #include <linux/net.h>
X #include <linux/in.h>
@@ -936,7 +935,7 @@
X 
X /* --------------------------------------------------------------------- */
X 
-__initfunc(int init_module(void))
+int __init init_module(void)
X {
X 	printk(KERN_INFO "hdlcdrv: (C) 1996 Thomas Sailer HB9JNX/AE4WA\n");
X 	printk(KERN_INFO "hdlcdrv: version 0.6 compiled " __TIME__ " " __DATE__ "\n");
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hamradio/mkiss.c linux/drivers/net/hamradio/mkiss.c
--- v2.3.9/linux/drivers/net/hamradio/mkiss.c	Fri Nov 13 10:29:44 1998
+++ linux/drivers/net/hamradio/mkiss.c	Tue Jul  6 19:05:50 1999
@@ -937,7 +937,7 @@
X }
X 
X /* Initialize AX25 control device -- register AX25 line discipline */
-__initfunc(int mkiss_init_ctrl_dev(void))
+int __init mkiss_init_ctrl_dev(void)
X {
X 	int status;
X 
@@ -1154,7 +1154,7 @@
X /* * 			Init MKISS driver 			      * */
X /* ******************************************************************** */
X 
-__initfunc(static int mkiss_init(void))
+static int __init mkiss_init(void)
X {
X 	memset(&mkiss_driver, 0, sizeof(struct tty_driver));
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hamradio/pi2.c linux/drivers/net/hamradio/pi2.c
--- v2.3.9/linux/drivers/net/hamradio/pi2.c	Tue Feb 10 13:07:50 1998
+++ linux/drivers/net/hamradio/pi2.c	Tue Jul  6 19:05:50 1999
@@ -927,7 +927,7 @@
X /* Probe for a PI card. */
X /* This routine also initializes the timer chip */
X 
-__initfunc(static int hw_probe(int ioaddr))
+static int __init hw_probe(int ioaddr)
X {
X     int time = 1000;		/* Number of milliseconds for test */
X     unsigned long start_time, end_time;
@@ -1182,7 +1182,7 @@
X }
X 
X 
-__initfunc(int pi_init(void))
+int __init pi_init(void)
X {
X     int *port;
X     int ioaddr = 0;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hamradio/pt.c linux/drivers/net/hamradio/pt.c
--- v2.3.9/linux/drivers/net/hamradio/pt.c	Tue Feb 10 13:07:50 1998
+++ linux/drivers/net/hamradio/pt.c	Tue Jul  6 19:05:50 1999
@@ -474,8 +474,7 @@
X } /* chipset_init() */
X 
X 
-
-__initfunc(int pt_init(void))
+int __init pt_init(void)
X {
X     int *port;
X     int ioaddr = 0;
@@ -537,7 +536,7 @@
X /*
X  * Probe for PT card.  Also initialises the timers
X  */
-__initfunc(static int hw_probe(int ioaddr))
+static int __init hw_probe(int ioaddr)
X {
X     int time = 1000;		/* Number of milliseconds to test */
X     int a = 1;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hamradio/scc.c linux/drivers/net/hamradio/scc.c
--- v2.3.9/linux/drivers/net/hamradio/scc.c	Fri Dec 18 13:57:21 1998
+++ linux/drivers/net/hamradio/scc.c	Tue Jul  6 19:05:50 1999
@@ -2193,7 +2193,7 @@
X /* * 			Init SCC driver 			      * */
X /* ******************************************************************** */
X 
-__initfunc(int scc_init (void))
+int __init scc_init (void)
X {
X 	int chip, chan, k, result;
X 	char devname[10];
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hamradio/soundmodem/sm.c linux/drivers/net/hamradio/soundmodem/sm.c
--- v2.3.9/linux/drivers/net/hamradio/soundmodem/sm.c	Sun Jan 17 18:28:06 1999
+++ linux/drivers/net/hamradio/soundmodem/sm.c	Tue Jul  6 19:05:50 1999
@@ -640,9 +640,9 @@
X /* --------------------------------------------------------------------- */
X 
X #ifdef MODULE
-__initfunc(static int sm_init(void))
+static int __init sm_init(void)
X #else /* MODULE */
-__initfunc(int sm_init(void))
+int __init sm_init(void)
X #endif /* MODULE */
X {
X 	int i, j, found = 0;
@@ -724,7 +724,7 @@
X 
X #endif
X 
-__initfunc(int init_module(void))
+int __init init_module(void)
X {
X 	if (mode) {
X 		if (iobase == -1)
@@ -778,7 +778,7 @@
X  * modem: afsk1200, fsk9600
X  */
X 
-__initfunc(void sm_setup(char *str, int *ints))
+void __init sm_setup(char *str, int *ints)
X {
X 	int i;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hamradio/soundmodem/sm.h linux/drivers/net/hamradio/soundmodem/sm.h
--- v2.3.9/linux/drivers/net/hamradio/soundmodem/sm.h	Fri Jul 10 14:01:13 1998
+++ linux/drivers/net/hamradio/soundmodem/sm.h	Mon Jul  5 20:35:18 1999
@@ -296,8 +296,6 @@
X 
X #ifdef __i386__
X 
-#include <asm/processor.h>
-
X #define HAS_RDTSC (current_cpu_data.x86_capability & X86_FEATURE_TSC)
X 
X /*
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hostess_sv11.c linux/drivers/net/hostess_sv11.c
--- v2.3.9/linux/drivers/net/hostess_sv11.c	Thu Feb 18 16:28:49 1999
+++ linux/drivers/net/hostess_sv11.c	Mon Jul  5 20:09:40 1999
@@ -389,7 +389,8 @@
X 	free_irq(dev->sync.irq, dev);
X 	if(dma)
X 	{
-		free_dma(dev->sync.chanA.rxdma);
+		if(dma==1)
+			free_dma(dev->sync.chanA.rxdma);
X 		free_dma(dev->sync.chanA.txdma);
X 	}
X 	release_region(dev->sync.chanA.ctrlio-1, 8);
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c
--- v2.3.9/linux/drivers/net/hp-plus.c	Wed Dec 16 13:35:49 1998
+++ linux/drivers/net/hp-plus.c	Tue Jul  6 19:05:50 1999
@@ -123,7 +123,7 @@
X {"hpplus", hpp_probe1, HP_IO_EXTENT, hpplus_portlist};
X #else
X 
-__initfunc(int hp_plus_probe(struct device *dev))
+int __init hp_plus_probe(struct device *dev)
X {
X 	int i;
X 	int base_addr = dev ? dev->base_addr : 0;
@@ -146,7 +146,7 @@
X #endif
X 
X /* Do the interesting part of the probe at a single address. */
-__initfunc(int hpp_probe1(struct device *dev, int ioaddr))
+int __init hpp_probe1(struct device *dev, int ioaddr)
X {
X 	int i;
X 	unsigned char checksum = 0;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hp.c linux/drivers/net/hp.c
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 20'
echo 'File patch-2.3.10 is continued in part 21'
echo 21 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 21 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
--- v2.3.9/linux/drivers/net/hp.c	Wed Dec 16 13:35:49 1998
+++ linux/drivers/net/hp.c	Tue Jul  6 19:05:50 1999
@@ -84,7 +84,7 @@
X {"hp", hp_probe1, HP_IO_EXTENT, hppclan_portlist};
X #else
X 
-__initfunc(int hp_probe(struct device *dev))
+int __init hp_probe(struct device *dev)
X {
X 	int i;
X 	int base_addr = dev ? dev->base_addr : 0;
@@ -106,7 +106,7 @@
X }
X #endif
X 
-__initfunc(int hp_probe1(struct device *dev, int ioaddr))
+int __init hp_probe1(struct device *dev, int ioaddr)
X {
X 	int i, board_id, wordmode;
X 	const char *name;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hp100.c linux/drivers/net/hp100.c
--- v2.3.9/linux/drivers/net/hp100.c	Mon Jan 11 10:55:29 1999
+++ linux/drivers/net/hp100.c	Tue Jul  6 19:05:50 1999
@@ -106,6 +106,7 @@
X #include <linux/types.h>
X #include <linux/config.h>  /* for CONFIG_PCI */
X #include <linux/delay.h>
+#include <linux/init.h>
X 
X #if LINUX_VERSION_CODE >= 0x020100
X #define LINUX_2_1
@@ -347,7 +348,7 @@
X  *  since this could cause problems when the card is not installed.
X  */
X  
-__initfunc(int hp100_probe( struct device *dev ))
+int __init hp100_probe( struct device *dev )
X {
X   int base_addr = dev ? dev -> base_addr : 0;
X   int ioaddr = 0;
@@ -524,9 +525,9 @@
X 
X 
X #ifdef LINUX_2_1
-__initfunc(static int hp100_probe1( struct device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev ))
+static int __init hp100_probe1( struct device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev )
X #else
-__initfunc(static int hp100_probe1( struct device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn ))
+static int __init hp100_probe1( struct device *dev, int ioaddr, u_char bus, u_char pci_bus, u_char pci_device_fn )
X #endif
X {
X   int i;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hplance.c linux/drivers/net/hplance.c
--- v2.3.9/linux/drivers/net/hplance.c	Thu Jun 25 11:03:42 1998
+++ linux/drivers/net/hplance.c	Tue Jul  6 19:05:50 1999
@@ -67,7 +67,7 @@
X #endif
X 
X /* Find all the HP Lance boards and initialise them... */
-__initfunc(int hplance_probe(struct device *dev))
+int __init hplance_probe(struct device *dev)
X {
X         int cards = 0, called = 0;
X 
@@ -98,7 +98,7 @@
X }
X 
X /* Initialise a single lance board at the given select code */
-__initfunc (static int hplance_init(struct device *dev, int scode))
+static int __init hplance_init(struct device *dev, int scode)
X {
X         /* const char *name = dio_scodetoname(scode); */
X         static const char name[] = "HP LANCE";
diff -u --recursive --new-file v2.3.9/linux/drivers/net/hydra.c linux/drivers/net/hydra.c
--- v2.3.9/linux/drivers/net/hydra.c	Tue Feb 10 12:56:44 1998
+++ linux/drivers/net/hydra.c	Tue Jul  6 19:05:50 1999
@@ -157,7 +157,7 @@
X 
X #endif
X 
-__initfunc(int hydra_probe(struct device *dev))
+int __init hydra_probe(struct device *dev)
X {
X 	struct hydra_private *priv;
X 	u32 board;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c
--- v2.3.9/linux/drivers/net/ibmtr.c	Wed Jun 16 19:26:27 1999
+++ linux/drivers/net/ibmtr.c	Tue Jul  6 19:05:50 1999
@@ -138,11 +138,9 @@
X #include <linux/kernel.h>
X #include <linux/sched.h>
X #include <linux/errno.h>
-#include <linux/sched.h>
X #include <linux/timer.h>
X #include <linux/in.h>
X #include <linux/ioport.h>
-#include <linux/errno.h>
X #include <linux/string.h>
X #include <linux/skbuff.h>
X #include <linux/interrupt.h>
@@ -173,7 +171,7 @@
X 	"ISA", "MCA", "ISA P&P" 
X };
X 
-__initfunc(char *adapter_def(char type))
+char __init *adapter_def(char type)
X {
X 	switch (type) 
X 	{
@@ -223,7 +221,7 @@
X 
X static __u32 ibmtr_mem_base = 0xd0000;
X 
-__initfunc(static void PrtChanID(char *pcid, short stride) )
+static void __init PrtChanID(char *pcid, short stride) 
X {
X 	short i, j;
X 	for (i=0, j=0; i<24; i++, j+=stride)
@@ -231,7 +229,7 @@
X 	printk("\n");
X }
X 
-__initfunc(static void HWPrtChanID (__u32 pcid, short stride))
+static void __init HWPrtChanID (__u32 pcid, short stride)
X {
X 	short i, j;
X 	for (i=0, j=0; i<24; i++, j+=stride)
@@ -252,7 +250,7 @@
X  *	which references it.
X  */
X  
-__initfunc(int ibmtr_probe(struct device *dev))
+int __init ibmtr_probe(struct device *dev)
X {
X         int i;
X         int base_addr = dev ? dev->base_addr : 0;
@@ -295,7 +293,7 @@
X         return -ENODEV;
X }
X 
-__initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
+static int __init ibmtr_probe1(struct device *dev, int PIOaddr)
X {
X 	unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK,temp=0;
X 	__u32 t_mmio=0;
@@ -750,7 +748,7 @@
X 
X /* query the adapter for the size of shared RAM  */
X 
-__initfunc(static unsigned char get_sram_size(struct tok_info *adapt_info))
+static unsigned char __init get_sram_size(struct tok_info *adapt_info)
X {
X 
X 	unsigned char avail_sram_code;
@@ -769,7 +767,7 @@
X 		return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4);
X }
X 
-__initfunc(static int trdev_init(struct device *dev))
+static int __init trdev_init(struct device *dev)
X {
X 	struct tok_info *ti=(struct tok_info *)dev->priv;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/irda/actisys.c linux/drivers/net/irda/actisys.c
--- v2.3.9/linux/drivers/net/irda/actisys.c	Mon Jun  7 16:18:58 1999
+++ linux/drivers/net/irda/actisys.c	Tue Jul  6 19:05:49 1999
@@ -61,7 +61,7 @@
X 	actisys_init_qos,
X };
X 
-__initfunc(int actisys_init(void))
+int __init actisys_init(void)
X {
X 	int ret;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/irda/esi.c linux/drivers/net/irda/esi.c
--- v2.3.9/linux/drivers/net/irda/esi.c	Mon Jun  7 16:18:58 1999
+++ linux/drivers/net/irda/esi.c	Tue Jul  6 19:05:49 1999
@@ -52,7 +52,7 @@
X 	esi_qos_init,
X };
X 
-__initfunc(int esi_init(void))
+int __init esi_init(void)
X {
X 	return irda_device_register_dongle(&dongle);
X }
diff -u --recursive --new-file v2.3.9/linux/drivers/net/irda/girbil.c linux/drivers/net/irda/girbil.c
--- v2.3.9/linux/drivers/net/irda/girbil.c	Mon Jun  7 16:18:58 1999
+++ linux/drivers/net/irda/girbil.c	Tue Jul  6 19:05:49 1999
@@ -76,7 +76,7 @@
X 	girbil_init_qos,
X };
X 
-__initfunc(int girbil_init(void))
+int __init girbil_init(void)
X {
X 	return irda_device_register_dongle(&dongle);
X }
diff -u --recursive --new-file v2.3.9/linux/drivers/net/irda/irport.c linux/drivers/net/irda/irport.c
--- v2.3.9/linux/drivers/net/irda/irport.c	Wed Jun 16 19:26:27 1999
+++ linux/drivers/net/irda/irport.c	Tue Jul  6 19:05:49 1999
@@ -86,7 +86,7 @@
X static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts);
X static int  irport_raw_write(struct irda_device *idev, __u8 *buf, int len);
X 
-__initfunc(int irport_init(void))
+int __init irport_init(void)
X {
X  	int i;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/irda/irtty.c linux/drivers/net/irda/irtty.c
--- v2.3.9/linux/drivers/net/irda/irtty.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/net/irda/irtty.c	Tue Jul  6 19:05:49 1999
@@ -64,7 +64,7 @@
X 			      char *, int);
X char *driver_name = "irtty";
X 
-__initfunc(int irtty_init(void))
+int __init irtty_init(void)
X {
X 	int status;
X 	
diff -u --recursive --new-file v2.3.9/linux/drivers/net/irda/litelink.c linux/drivers/net/irda/litelink.c
--- v2.3.9/linux/drivers/net/irda/litelink.c	Mon Jun  7 16:18:58 1999
+++ linux/drivers/net/irda/litelink.c	Tue Jul  6 19:05:49 1999
@@ -60,7 +60,7 @@
X 	litelink_init_qos,
X };
X 
-__initfunc(int litelink_init(void))
+int __init litelink_init(void)
X {
X 	return irda_device_register_dongle(&dongle);
X }
diff -u --recursive --new-file v2.3.9/linux/drivers/net/irda/pc87108.c linux/drivers/net/irda/pc87108.c
--- v2.3.9/linux/drivers/net/irda/pc87108.c	Mon Jun  7 16:18:58 1999
+++ linux/drivers/net/irda/pc87108.c	Tue Jul  6 19:05:49 1999
@@ -127,7 +127,7 @@
X  *    Initialize chip. Just try to find out how many chips we are dealing with
X  *    and where they are
X  */
-__initfunc(int pc87108_init(void))
+int __init pc87108_init(void)
X {
X 	int i;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/irda/smc-ircc.c linux/drivers/net/irda/smc-ircc.c
--- v2.3.9/linux/drivers/net/irda/smc-ircc.c	Mon Jun  7 16:18:58 1999
+++ linux/drivers/net/irda/smc-ircc.c	Tue Jul  6 19:05:49 1999
@@ -33,8 +33,6 @@
X #include <linux/ioport.h>
X #include <linux/delay.h>
X #include <linux/malloc.h>
-#include <linux/delay.h>
-#include <linux/init.h>
X #include <linux/init.h>
X 
X #include <asm/io.h>
@@ -102,7 +100,7 @@
X  *    Initialize chip. Just try to find out how many chips we are dealing with
X  *    and where they are
X  */
-__initfunc(int ircc_init(void))
+int __init ircc_init(void)
X {
X 	int i;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/irda/tekram.c linux/drivers/net/irda/tekram.c
--- v2.3.9/linux/drivers/net/irda/tekram.c	Mon Jun  7 16:18:58 1999
+++ linux/drivers/net/irda/tekram.c	Tue Jul  6 19:05:49 1999
@@ -56,7 +56,7 @@
X 	tekram_init_qos,
X };
X 
-__initfunc(int tekram_init(void))
+int __init tekram_init(void)
X {
X 	return irda_device_register_dongle(&dongle);
X }
diff -u --recursive --new-file v2.3.9/linux/drivers/net/irda/toshoboe.c linux/drivers/net/irda/toshoboe.c
--- v2.3.9/linux/drivers/net/irda/toshoboe.c	Sun May 30 10:27:04 1999
+++ linux/drivers/net/irda/toshoboe.c	Mon Jul  5 20:09:40 1999
@@ -568,11 +568,11 @@
X   self->rxs = inb_p (OBOE_RCVT);
X   self->txs = inb_p (OBOE_XMTT) - OBOE_XMTT_OFFSET;
X 
-#ifdef 0
+#if 0
X   self->rxs = 0;
X   self->txs = 0;
X #endif
-#ifdef 0
+#if 0
X   self->rxs = RX_SLOTS - 1;
X   self->txs = 0;
X #endif
@@ -838,7 +838,7 @@
X   return (0);
X }
X 
-__initfunc (int toshoboe_init (void))
+int __init toshoboe_init (void)
X {
X   struct pci_dev *pci_dev = NULL;
X   int found = 0;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/irda/uircc.c linux/drivers/net/irda/uircc.c
--- v2.3.9/linux/drivers/net/irda/uircc.c	Mon Jun  7 16:18:58 1999
+++ linux/drivers/net/irda/uircc.c	Tue Jul  6 19:05:49 1999
@@ -36,8 +36,6 @@
X #include <linux/ioport.h>
X #include <linux/delay.h>
X #include <linux/malloc.h>
-#include <linux/delay.h>
-#include <linux/init.h>
X #include <linux/init.h>
X 
X #include <asm/io.h>
@@ -90,7 +88,7 @@
X  *    Initialize chip. Just try to find out how many chips we are dealing with
X  *    and where they are
X  */
-__initfunc(int uircc_init(void))
+int __init uircc_init(void)
X {
X 	int i;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/irda/w83977af_ir.c linux/drivers/net/irda/w83977af_ir.c
--- v2.3.9/linux/drivers/net/irda/w83977af_ir.c	Mon Jun  7 16:18:58 1999
+++ linux/drivers/net/irda/w83977af_ir.c	Tue Jul  6 19:05:49 1999
@@ -105,7 +105,7 @@
X  *    Initialize chip. Just try to find out how many chips we are dealing with
X  *    and where they are
X  */
-__initfunc(int w83977af_init(void))
+int __init w83977af_init(void)
X {
X         int i;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/lance.c linux/drivers/net/lance.c
--- v2.3.9/linux/drivers/net/lance.c	Mon Dec 28 11:05:14 1998
+++ linux/drivers/net/lance.c	Tue Jul  6 19:05:49 1999
@@ -420,7 +420,7 @@
X 	return -ENODEV;
X }
X 
-__initfunc(int lance_probe1(struct device *dev, int ioaddr, int irq, int options))
+int __init lance_probe1(struct device *dev, int ioaddr, int irq, int options)
X {
X 	struct lance_private *lp;
X 	short dma_channels;					/* Mark spuriously-busy DMA channels */
@@ -499,6 +499,8 @@
X 		
X 	lp = (struct lance_private *)(((unsigned long)kmalloc(sizeof(*lp)+7,
X 										   GFP_DMA | GFP_KERNEL)+7) & ~7);
+	if(lp==NULL)
+		return -ENODEV;
X 	if (lance_debug > 6) printk(" (#0x%05lx)", (unsigned long)lp);
X 	memset(lp, 0, sizeof(*lp));
X 	dev->priv = lp;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/lne390.c linux/drivers/net/lne390.c
--- v2.3.9/linux/drivers/net/lne390.c	Wed Dec 16 13:35:49 1998
+++ linux/drivers/net/lne390.c	Tue Jul  6 19:08:33 1999
@@ -100,7 +100,7 @@
X  *	PROM for a match against the value assigned to Mylex.
X  */
X 
-__initfunc(int lne390_probe(struct device *dev))
+int __init lne390_probe(struct device *dev)
X {
X 	unsigned short ioaddr = dev->base_addr;
X 
@@ -127,7 +127,7 @@
X 	return ENODEV;
X }
X 
-__initfunc(int lne390_probe1(struct device *dev, int ioaddr))
+int __init lne390_probe1(struct device *dev, int ioaddr)
X {
X 	int i, revision;
X 	unsigned long eisa_id;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/loopback.c linux/drivers/net/loopback.c
--- v2.3.9/linux/drivers/net/loopback.c	Thu Jun 11 22:52:33 1998
+++ linux/drivers/net/loopback.c	Tue Jul  6 19:08:33 1999
@@ -114,7 +114,7 @@
X }
X 
X /* Initialize the rest of the LOOPBACK device. */
-__initfunc(int loopback_init(struct device *dev))
+int __init loopback_init(struct device *dev)
X {
X 	dev->mtu		= LOOPBACK_MTU;
X 	dev->tbusy		= 0;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/ltpc.c linux/drivers/net/ltpc.c
--- v2.3.9/linux/drivers/net/ltpc.c	Fri Jan 15 14:36:21 1999
+++ linux/drivers/net/ltpc.c	Tue Jul  6 19:08:33 1999
@@ -1018,7 +1018,7 @@
X 
X /* initialization stuff */
X   
-__initfunc(int ltpc_probe_dma(int base))
+int __init ltpc_probe_dma(int base)
X {
X 	int dma = 0;
X   	int timeout;
@@ -1088,7 +1088,7 @@
X 	return dma;
X }
X 
-__initfunc(int ltpc_probe(struct device *dev))
+int __init ltpc_probe(struct device *dev)
X {
X 	int err;
X 	int x=0,y=0;
@@ -1250,7 +1250,7 @@
X }
X 
X /* handles "ltpc=io,irq,dma" kernel command lines */
-__initfunc(void ltpc_setup(char *str, int *ints))
+void __init ltpc_setup(char *str, int *ints)
X {
X 	if (ints[0] == 0) {
X 		if (str && !strncmp(str, "auto", 4)) {
diff -u --recursive --new-file v2.3.9/linux/drivers/net/myri_sbus.c linux/drivers/net/myri_sbus.c
--- v2.3.9/linux/drivers/net/myri_sbus.c	Wed Jun  9 14:45:36 1999
+++ linux/drivers/net/myri_sbus.c	Tue Jul  6 19:08:33 1999
@@ -1074,7 +1074,7 @@
X 	return 0;
X }
X 
-__initfunc(int myri_sbus_probe(struct device *dev))
+int __init myri_sbus_probe(struct device *dev)
X {
X 	struct linux_sbus *bus;
X 	struct linux_sbus_device *sdev = 0;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/ne.c linux/drivers/net/ne.c
--- v2.3.9/linux/drivers/net/ne.c	Sun Mar  7 15:47:46 1999
+++ linux/drivers/net/ne.c	Tue Jul  6 19:08:33 1999
@@ -177,7 +177,7 @@
X  * the card.
X  */
X 
-__initfunc(int ne_probe(struct device *dev))
+int __init ne_probe(struct device *dev)
X {
X 	int base_addr = dev ? dev->base_addr : 0;
X 
@@ -209,7 +209,7 @@
X #endif
X 
X #ifdef CONFIG_PCI
-__initfunc(static int ne_probe_pci(struct device *dev))
+static int __init ne_probe_pci(struct device *dev)
X {
X 	int i;
X 
@@ -243,7 +243,7 @@
X }
X #endif  /* CONFIG_PCI */
X 
-__initfunc(static int ne_probe1(struct device *dev, int ioaddr))
+static int __init ne_probe1(struct device *dev, int ioaddr)
X {
X 	int i;
X 	unsigned char SA_prom[32];
diff -u --recursive --new-file v2.3.9/linux/drivers/net/ne2.c linux/drivers/net/ne2.c
--- v2.3.9/linux/drivers/net/ne2.c	Wed Mar 10 16:51:35 1999
+++ linux/drivers/net/ne2.c	Tue Jul  6 19:08:33 1999
@@ -146,7 +146,7 @@
X  * Note that at boot, this probe only picks up one card at a time.
X  */
X 
-__initfunc (int ne2_probe(struct device *dev))
+int __init ne2_probe(struct device *dev)
X {
X 	static int current_mca_slot = -1;
X 	int i;
@@ -198,8 +198,7 @@
X 	return len;
X }
X 
-
-__initfunc (static int ne2_probe1(struct device *dev, int slot))
+static int __init ne2_probe1(struct device *dev, int slot)
X {
X 	int i, base_addr, irq;
X 	unsigned char POS;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/ne2k-pci.c linux/drivers/net/ne2k-pci.c
--- v2.3.9/linux/drivers/net/ne2k-pci.c	Sun Jan 24 22:04:02 1999
+++ linux/drivers/net/ne2k-pci.c	Mon Jul  5 20:11:07 1999
@@ -24,11 +24,8 @@
X 
X /* Our copyright info must remain in the binary. */
X static const char *version =
-"ne2k-pci.c:v0.99L 2/7/98 D. Becker/P. Gortmaker http://cesdis.gsfc.nasa.gov/linux/drivers/ne2k-pci.html\n";
+"ne2k-pci.c:vpre-1.00e 5/27/99 D. Becker/P. Gortmaker http://cesdis.gsfc.nasa.gov/linux/drivers/ne2k-pci.html\n";
X 
-#ifdef MODVERSIONS
-#include <linux/modversions.h>
-#endif
X #include <linux/module.h>
X #include <linux/kernel.h>
X #include <linux/sched.h>
@@ -44,6 +41,13 @@
X #include <linux/etherdevice.h>
X #include "8390.h"
X 
+#if defined(__powerpc__)
+#define inl_le(addr)  le32_to_cpu(inl(addr))
+#define inw_le(addr)  le16_to_cpu(inw(addr))
+#define insl insl_ns
+#define outsl outsl_ns
+#endif
+
X /* Set statically or when loading the driver module. */
X static int debug = 1;
X 
@@ -58,19 +62,34 @@
X /* Do we have a non std. amount of memory? (in units of 256 byte pages) */
X /* #define PACKETBUF_MEMSIZE	0x40 */
X 
+#define ne2k_flags reg0			/* Rename an existing field to store flags! */
+
+/* Only the low 8 bits are usable for non-init-time flags! */
+enum {
+	HOLTEK_FDX=1, 		/* Full duplex -> set 0x80 at offset 0x20. */
+	ONLY_16BIT_IO=2, ONLY_32BIT_IO=4,	/* Chip can do only 16/32-bit xfers. */
+	STOP_PG_0x60=0x100,
+};
+
+/* This will eventually be converted to the standard PCI probe table. */
+
X static struct {
X 	unsigned short vendor, dev_id;
X 	char *name;
+	int flags;
X }
X pci_clone_list[] __initdata = {
-	{0x10ec, 0x8029, "RealTek RTL-8029"},
-	{0x1050, 0x0940, "Winbond 89C940"},
-	{0x11f6, 0x1401, "Compex RL2000"},
-	{0x8e2e, 0x3000, "KTI ET32P2"},
-	{0x4a14, 0x5000, "NetVin NV5000SC"},
-	{0x1106, 0x0926, "Via 82C926"},
-	{0x10bd, 0x0e34, "SureCom NE34"},
-	{0x1050, 0x5a5a, "Winbond"},
+	{0x10ec, 0x8029, "RealTek RTL-8029", 0},
+	{0x1050, 0x0940, "Winbond 89C940", 0},
+	{0x11f6, 0x1401, "Compex RL2000", 0},
+	{0x8e2e, 0x3000, "KTI ET32P2", 0},
+	{0x4a14, 0x5000, "NetVin NV5000SC", 0},
+	{0x1106, 0x0926, "Via 86C926", ONLY_16BIT_IO},
+	{0x10bd, 0x0e34, "SureCom NE34", 0},
+	{0x1050, 0x5a5a, "Winbond", 0},
+	{0x12c3, 0x0058, "Holtek HT80232", ONLY_16BIT_IO | HOLTEK_FDX},
+	{0x12c3, 0x5598, "Holtek HT80229",
+	 ONLY_32BIT_IO | HOLTEK_FDX | STOP_PG_0x60 },
X 	{0,}
X };
X 
@@ -86,7 +105,8 @@
X #define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */
X 
X int ne2k_pci_probe(struct device *dev);
-static struct device *ne2k_pci_probe1(struct device *dev, int ioaddr, int irq);
+static struct device *ne2k_pci_probe1(struct device *dev, int ioaddr, int irq,
+									  int chip_idx);
X 
X static int ne2k_pci_open(struct device *dev);
X static int ne2k_pci_close(struct device *dev);
@@ -115,17 +135,13 @@
X int
X init_module(void)
X {
-	int retval;
-
X 	/* We must emit version information. */
X 	if (debug)
X 		printk(KERN_INFO "%s", version);
X 
-	retval = ne2k_pci_probe(0);
-
-	if (retval) {
-		printk(KERN_NOTICE "ne2k-pci.c: no (useable) cards found, driver NOT installed.\n");
-		return retval;
+	if (ne2k_pci_probe(0)) {
+		printk(KERN_NOTICE "ne2k-pci.c: No useable cards found, driver NOT installed.\n");
+		return -ENODEV;
X 	}
X 	lock_8390_module();
X 	return 0;
@@ -170,7 +186,7 @@
X {"ne2k_pci", ne2k_pci_probe1, NE_IO_EXTENT, 0};
X #endif
X 
-__initfunc (int ne2k_pci_probe(struct device *dev))
+int __init ne2k_pci_probe(struct device *dev)
X {
X 	struct pci_dev *pdev = NULL;
X 	int cards_found = 0;
@@ -225,7 +241,7 @@
X 
X 		printk("ne2k-pci.c: PCI NE2000 clone '%s' at I/O %#x, IRQ %d.\n",
X 			   pci_clone_list[i].name, pci_ioaddr, pci_irq_line);
-		dev = ne2k_pci_probe1(dev, pci_ioaddr, pci_irq_line);
+		dev = ne2k_pci_probe1(dev, pci_ioaddr, pci_irq_line, i);
X 		if (dev == 0) {
X 			/* Should not happen. */
X 			printk(KERN_ERR "ne2k-pci: Probe of PCI card at %#x failed.\n",
@@ -247,11 +263,10 @@
X 	return cards_found ? 0 : -ENODEV;
X }
X 
-__initfunc (static struct device *ne2k_pci_probe1(struct device *dev, int ioaddr, int irq))
+static struct device __init *ne2k_pci_probe1(struct device *dev, int ioaddr, int irq, int chip_idx)
X {
X 	int i;
X 	unsigned char SA_prom[32];
-	const char *name = NULL;
X 	int start_page, stop_page;
X 	int reg0 = inb(ioaddr);
X 
@@ -273,6 +288,8 @@
X 		}
X 	}
X 
+	dev = init_etherdev(dev, 0);
+
X 	/* Reset card. Who knows what dain-bramaged state it was left in. */
X 	{
X 		unsigned long reset_start_time = jiffies;
@@ -321,59 +338,47 @@
X 
X 	}
X 
-#ifdef notdef
-	/* Some broken PCI cards don't respect the byte-wide
-	   request in program_seq above, and hence don't have doubled up values.
-	*/
-	for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
-		SA_prom[i] = inb(ioaddr + NE_DATAPORT);
-		SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
-		if (SA_prom[i] != SA_prom[i+1])
-			sa_prom_doubled = 0;
-	}
-
-	if (sa_prom_doubled)
-		for (i = 0; i < 16; i++)
-			SA_prom[i] = SA_prom[i+i];
-#else
-	for(i = 0; i < 32 /*sizeof(SA_prom)*/; i++)
-		SA_prom[i] = inb(ioaddr + NE_DATAPORT);
+	/* Note: all PCI cards have at least 16 bit access, so we don't have
+	   to check for 8 bit cards.  Most cards permit 32 bit access. */
X 
-#endif
+	if (pci_clone_list[chip_idx].flags & ONLY_32BIT_IO) {
+		for (i = 0; i < 4 ; i++)
+			((u32 *)SA_prom)[i] = le32_to_cpu(inl(ioaddr + NE_DATAPORT));
+	} else
+		for(i = 0; i < 32 /*sizeof(SA_prom)*/; i++)
+			SA_prom[i] = inb(ioaddr + NE_DATAPORT);
X 
X 	/* We always set the 8390 registers for word mode. */
X 	outb(0x49, ioaddr + EN0_DCFG);
X 	start_page = NESM_START_PG;
-	stop_page = NESM_STOP_PG;
X 
-	/* Set up the rest of the parameters. */
-	name = "PCI NE2000";
-
-	dev = init_etherdev(dev, 0);
+	stop_page =
+		pci_clone_list[chip_idx].flags&STOP_PG_0x60 ? 0x60 : NESM_STOP_PG;
X 
+	/* Set up the rest of the parameters. */
X 	dev->irq = irq;
X 	dev->base_addr = ioaddr;
X 
X 	/* Allocate dev->priv and fill in 8390 specific dev fields. */
X 	if (ethdev_init(dev)) {
X 		printk ("%s: unable to get memory for dev->priv.\n", dev->name);
-		kfree(dev);
X 		return 0;
X 	}
X 
X 	request_region(ioaddr, NE_IO_EXTENT, dev->name);
X 
X 	printk("%s: %s found at %#x, IRQ %d, ",
-		   dev->name, name, ioaddr, dev->irq);
+		   dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq);
X 	for(i = 0; i < 6; i++) {
X 		printk("%2.2X%s", SA_prom[i], i == 5 ? ".\n": ":");
X 		dev->dev_addr[i] = SA_prom[i];
X 	}
X 
-	ei_status.name = name;
+	ei_status.name = pci_clone_list[chip_idx].name;
X 	ei_status.tx_start_page = start_page;
X 	ei_status.stop_page = stop_page;
X 	ei_status.word16 = 1;
+	ei_status.ne2k_flags = pci_clone_list[chip_idx].flags;
X 
X 	ei_status.rx_start_page = start_page + TX_PAGES;
X #ifdef PACKETBUF_MEMSIZE
@@ -447,9 +452,9 @@
X 	/* This *shouldn't* happen. If it does, it's the last thing you'll see */
X 	if (ei_status.dmaing) {
X 		printk("%s: DMAing conflict in ne2k_pci_get_8390_hdr "
-			   "[DMAstat:%d][irqlock:%d][intr:%ld].\n",
+			   "[DMAstat:%d][irqlock:%d][intr:%d].\n",
X 			   dev->name, ei_status.dmaing, ei_status.irqlock,
-			   dev->interrupt);
+			   (int)dev->interrupt);
X 		return;
X 	}
X 
@@ -461,11 +466,12 @@
X 	outb(ring_page, nic_base + EN0_RSARHI);
X 	outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
X 
-#if defined(USE_LONGIO)
-	*(u32*)hdr = inl(NE_BASE + NE_DATAPORT);
-#else
-	insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
-#endif
+	if (ei_status.ne2k_flags & ONLY_16BIT_IO) {
+		insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
+	} else {
+		*(u32*)hdr = le32_to_cpu(inl(NE_BASE + NE_DATAPORT));
+		le16_to_cpus(&hdr->count);
+	}
X 
X 	outb(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
X 	ei_status.dmaing &= ~0x01;
@@ -485,12 +491,14 @@
X 	/* This *shouldn't* happen. If it does, it's the last thing you'll see */
X 	if (ei_status.dmaing) {
X 		printk("%s: DMAing conflict in ne2k_pci_block_input "
-			   "[DMAstat:%d][irqlock:%d][intr:%ld].\n",
+			   "[DMAstat:%d][irqlock:%d][intr:%d].\n",
X 			   dev->name, ei_status.dmaing, ei_status.irqlock,
-			   dev->interrupt);
+			   (int)dev->interrupt);
X 		return;
X 	}
X 	ei_status.dmaing |= 0x01;
+	if (ei_status.ne2k_flags & ONLY_32BIT_IO)
+		count = (count + 3) & 0xFFFC;
X 	outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
X 	outb(count & 0xff, nic_base + EN0_RCNTLO);
X 	outb(count >> 8, nic_base + EN0_RCNTHI);
@@ -498,21 +506,21 @@
X 	outb(ring_offset >> 8, nic_base + EN0_RSARHI);
X 	outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
X 
-#if defined(USE_LONGIO)
-	insl(NE_BASE + NE_DATAPORT, buf, count>>2);
-	if (count & 3) {
-		buf += count & ~3;
-		if (count & 2)
-			*((u16*)buf)++ = inw(NE_BASE + NE_DATAPORT);
-		if (count & 1)
-			*buf = inb(NE_BASE + NE_DATAPORT);
-	}
-#else
-	insw(NE_BASE + NE_DATAPORT,buf,count>>1);
-	if (count & 0x01) {
-		buf[count-1] = inb(NE_BASE + NE_DATAPORT);
+	if (ei_status.ne2k_flags & ONLY_16BIT_IO) {
+		insw(NE_BASE + NE_DATAPORT,buf,count>>1);
+		if (count & 0x01) {
+			buf[count-1] = inb(NE_BASE + NE_DATAPORT);
+		}
+	} else {
+		insl(NE_BASE + NE_DATAPORT, buf, count>>2);
+		if (count & 3) {
+			buf += count & ~3;
+			if (count & 2)
+				*((u16*)buf)++ = le16_to_cpu(inw(NE_BASE + NE_DATAPORT));
+			if (count & 1)
+				*buf = inb(NE_BASE + NE_DATAPORT);
+		}
X 	}
-#endif
X 
X 	outb(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
X 	ei_status.dmaing &= ~0x01;
@@ -527,15 +535,18 @@
X 
X 	/* On little-endian it's always safe to round the count up for
X 	   word writes. */
-	if (count & 0x01)
-		count++;
+	if (ei_status.ne2k_flags & ONLY_32BIT_IO)
+		count = (count + 3) & 0xFFFC;
+	else
+		if (count & 0x01)
+			count++;
X 
X 	/* This *shouldn't* happen. If it does, it's the last thing you'll see */
X 	if (ei_status.dmaing) {
X 		printk("%s: DMAing conflict in ne2k_pci_block_output."
-			   "[DMAstat:%d][irqlock:%d][intr:%ld]\n",
+			   "[DMAstat:%d][irqlock:%d][intr:%d]\n",
X 			   dev->name, ei_status.dmaing, ei_status.irqlock,
-			   dev->interrupt);
+			   (int)dev->interrupt);
X 		return;
X 	}
X 	ei_status.dmaing |= 0x01;
@@ -561,16 +572,16 @@
X 	outb(0x00, nic_base + EN0_RSARLO);
X 	outb(start_page, nic_base + EN0_RSARHI);
X 	outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
-#if defined(USE_LONGIO)
-	outsl(NE_BASE + NE_DATAPORT, buf, count>>2);
-	if (count & 3) {
-		buf += count & ~3;
-		if (count & 2)
-			outw(*((u16*)buf)++, NE_BASE + NE_DATAPORT);
+	if (ei_status.ne2k_flags & ONLY_16BIT_IO) {
+		outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
+	} else {
+		outsl(NE_BASE + NE_DATAPORT, buf, count>>2);
+		if (count & 3) {
+			buf += count & ~3;
+			if (count & 2)
+				outw(cpu_to_le16(*((u16*)buf)++), NE_BASE + NE_DATAPORT);
+		}
X 	}
-#else
-	outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
-#endif
X 
X 	dma_start = jiffies;
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/net/ne3210.c linux/drivers/net/ne3210.c
--- v2.3.9/linux/drivers/net/ne3210.c	Wed Dec 16 13:35:49 1998
+++ linux/drivers/net/ne3210.c	Tue Jul  6 19:08:33 1999
@@ -95,7 +95,7 @@
X  *	PROM for a match against the value assigned to Novell.
X  */
X 
-__initfunc(int ne3210_probe(struct device *dev))
+int __init ne3210_probe(struct device *dev)
X {
X 	unsigned short ioaddr = dev->base_addr;
X 
@@ -122,7 +122,7 @@
X 	return ENODEV;
X }
X 
-__initfunc(int ne3210_probe1(struct device *dev, int ioaddr))
+int __init ne3210_probe1(struct device *dev, int ioaddr)
X {
X 	int i;
X 	unsigned long eisa_id;
diff -u --recursive --new-file v2.3.9/linux/drivers/net/olympic.c linux/drivers/net/olympic.c
--- v2.3.9/linux/drivers/net/olympic.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/olympic.c	Tue Jul  6 10:11:40 1999
@@ -0,0 +1,1663 @@
+/*
+ *   olympic.c (c) 1999 Peter De Schrijver All Rights Reserved
+ *		   1999 Mike Phillips (phi...@amtrak.com)
+ *
+ *  Linux driver for IBM PCI tokenring cards based on the Pit/Pit-Phy/Olympic
+ *  chipset. 
+ *
+ *  Base Driver Skeleton:
+ *      Written 1993-94 by Donald Becker.
+ *
+ *      Copyright 1993 United States Government as represented by the
+ *      Director, National Security Agency.
+ *
+ *  Thanks to Erik De Cock, Adrian Bridgett and Frank Fiene for their 
+ *  assistance and perserverance with the testing of this driver.
+ *
+ *  This software may be used and distributed according to the terms
+ *  of the GNU Public License, incorporated herein by reference.
+ * 
+ *  4/27/99 - Alpha Release 0.1.0
+ *            First release to the public
+ *
+ *  6/8/99  - Official Release 0.2.0   
+ *            Merged into the kernel code 
+ *  
+ *  To Do:
+ *
+ *  Sanitize for smp
+ *
+ *  If Problems do Occur
+ *  Most problems can be rectified by either closing and opening the interface
+ *  (ifconfig down and up) or rmmod and insmod'ing the driver (a bit difficult
+ *  if compiled into the kernel).
+ */
+
+/* Change OLYMPIC_DEBUG to 1 to get verbose, and I mean really verbose, messages */
+
+#define OLYMPIC_DEBUG 0
+
+/* Change OLYMPIC_NETWORK_MONITOR to receive mac frames through the arb channel.
+ * Will also create a /proc/net/olympic_tr entry if proc_fs is compiled into the
+ * kernel.
+ * Intended to be used to create a ring-error reporting network module 
+ * i.e. it will give you the source address of beaconers on the ring 
+ */
+
+#define OLYMPIC_NETWORK_MONITOR 0
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/timer.h>
+#include <linux/in.h>
+#include <linux/ioport.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+#include <linux/ptrace.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/trdevice.h>
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <net/checksum.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include "olympic.h"
+
+/* I've got to put some intelligence into the version number so that Peter and I know
+ * which version of the code somebody has got. 
+ * Version Number = a.b.c.d  where a.b.c is the level of code and d is the latest author.
+ * So 0.0.1.pds = Peter, 0.0.1.mlp = Mike
+ * 
+ * Official releases will only have an a.b.c version number format.
+ */
+
+static char *version = 
+"Olympic.c v0.2.0 6/8/99 - Peter De Schrijver & Mike Phillips" ; 
+
+static char *open_maj_error[]  = {"No error", "Lobe Media Test", "Physical Insertion",
+				   "Address Verification", "Neighbor Notification (Ring Poll)",
+				   "Request Parameters","FDX Registration Request",
+				   "FDX Duplicate Address Check", "Station registration Query Wait",
+				   "Unknown stage"};
+
+static char *open_min_error[] = {"No error", "Function Failure", "Signal Lost", "Wire Fault",
+				   "Ring Speed Mismatch", "Timeout","Ring Failure","Ring Beaconing",
+				   "Duplicate Node Address","Request Parameters","Remove Received",
+				   "Reserved", "Reserved", "No Monitor Detected for RPL", 
+				   "Monitor Contention failer for RPL", "FDX Protocol Error"};
+
+/* Module paramters */
+
+/* Ring Speed 0,4,16,100 
+ * 0 = Autosense         
+ * 4,16 = Selected speed only, no autosense
+ * This allows the card to be the first on the ring
+ * and become the active monitor.
+ * 100 = Nothing at present, 100mbps is autodetected
+ * if FDX is turned on. May be implemented in the future to 
+ * fail if 100mpbs is not detected.
+ *
+ * WARNING: Some hubs will allow you to insert
+ * at the wrong speed
+ */
+
+static int ringspeed[OLYMPIC_MAX_ADAPTERS] = {0,} ;
+
+MODULE_PARM(ringspeed, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS) "i");
+
+/* Packet buffer size */
+
+static int pkt_buf_sz[OLYMPIC_MAX_ADAPTERS] = {0,} ;
+ 
+MODULE_PARM(pkt_buf_sz, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS) "i") ; 
+
+/* Message Level */
+
+static int message_level[OLYMPIC_MAX_ADAPTERS] = {0,} ; 
+
+MODULE_PARM(message_level, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS) "i") ; 
+
+static int olympic_scan(struct device *dev);
+static int olympic_init(struct device *dev);
+static int olympic_open(struct device *dev);
+static int olympic_xmit(struct sk_buff *skb, struct device *dev);
+static int olympic_close(struct device *dev);
+static void olympic_set_rx_mode(struct device *dev);
+static void olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static struct net_device_stats * olympic_get_stats(struct device *dev);
+static int olympic_set_mac_address(struct device *dev, void *addr) ; 
+static void olympic_arb_cmd(struct device *dev);
+static int olympic_change_mtu(struct device *dev, int mtu);
+static void olympic_srb_bh(struct device *dev) ; 
+static void olympic_asb_bh(struct device *dev) ; 
+#if OLYMPIC_NETWORK_MONITOR
+#ifdef CONFIG_PROC_FS
+static int sprintf_info(char *buffer, struct device *dev) ; 
+#endif
+#endif
+
+__initfunc(int olympic_probe(struct device *dev)) 
+{
+	int cards_found;
+
+	cards_found=olympic_scan(dev);
+	return cards_found ? 0 : -ENODEV;
+}
+
+__initfunc(static int olympic_scan(struct device *dev)) 
+{
+	struct pci_dev *pci_device = NULL ;
+	struct olympic_private *olympic_priv;
+	int card_no = 0 ;
+	if (pci_present()) {
+
+		while((pci_device=pci_find_device(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR_WAKE, pci_device))) {
+
+			pci_set_master(pci_device);
+
+			/* Check to see if io has been allocated, if so, we've already done this card,
+			   so continue on the card discovery loop  */
+
+			if (check_region(pci_device->base_address[0] & (~3), OLYMPIC_IO_SPACE)) {
+				card_no++ ; 
+				continue ; 
+			}
+
+			olympic_priv=kmalloc(sizeof (struct olympic_private), GFP_KERNEL);
+			memset(olympic_priv, 0, sizeof(struct olympic_private));
+			init_waitqueue_head(&olympic_priv->srb_wait);
+			init_waitqueue_head(&olympic_priv->trb_wait);
+#ifndef MODULE
+			dev=init_trdev(dev, 0);
+#endif
+			dev->priv=(void *)olympic_priv;
+#if OLYMPIC_DEBUG  
+			printk("pci_device: %p, dev:%p, dev->priv: %p\n", pci_device, dev, dev->priv);
+#endif 
+			dev->irq=pci_device->irq;
+			dev->base_addr=pci_device->base_address[0] & (~3);
+			dev->init=&olympic_init;
+			olympic_priv->olympic_mmio=ioremap(pci_device->base_address[1],256);
+			olympic_priv->olympic_lap=ioremap(pci_device->base_address[2],2048);
+			
+			if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) )
+				olympic_priv->pkt_buf_sz = PKT_BUF_SZ ; 
+			else
+				olympic_priv->pkt_buf_sz = pkt_buf_sz[card_no] ; 
+
+			olympic_priv->olympic_ring_speed = ringspeed[card_no] ; 
+			olympic_priv->olympic_message_level = message_level[card_no] ; 
+			olympic_priv->olympic_multicast_set  = 0 ; 
+	
+			if(olympic_init(dev)==-1) {
+				unregister_netdevice(dev);
+				kfree(dev->priv);
+				return 0;
+			}				
+
+			dev->open=&olympic_open;
+			dev->hard_start_xmit=&olympic_xmit;
+			dev->change_mtu=&olympic_change_mtu;
+
+			dev->stop=&olympic_close;
+			dev->do_ioctl=NULL;
+			dev->set_multicast_list=&olympic_set_rx_mode;
+			dev->get_stats=&olympic_get_stats ;
+			dev->set_mac_address=&olympic_set_mac_address ;  
+			return 1; 
+		}
+	}
+	return  0 ;
+}
+
+
+__initfunc(static int olympic_init(struct device *dev)) 
+{
+    	struct olympic_private *olympic_priv;
+	__u8 *olympic_mmio, *init_srb,*adapter_addr;
+	unsigned long t; 
+	unsigned int uaa_addr;
+
+    	olympic_priv=(struct olympic_private *)dev->priv;
+	olympic_mmio=olympic_priv->olympic_mmio;
+
+	printk("%s \n", version);
+	printk("%s: IBM PCI tokenring card. I/O at %hx, MMIO at %p, LAP at %p, using irq %d\n",dev->name, (unsigned int) dev->base_addr,olympic_priv->olympic_mmio, olympic_priv->olympic_lap, dev->irq);
+
+	request_region(dev->base_addr, OLYMPIC_IO_SPACE, "olympic");
+	writel(readl(olympic_mmio+BCTL) | BCTL_SOFTRESET,olympic_mmio+BCTL);
+	t=jiffies;
+	while((readl(olympic_priv->olympic_mmio+BCTL)) & BCTL_SOFTRESET) {
+		schedule();		
+		if(jiffies-t > 40*HZ) {
+			printk(KERN_ERR "IBM PCI tokenring card not responding.\n");
+			release_region(dev->base_addr, OLYMPIC_IO_SPACE) ; 
+			return -1;
+		}
+	}
+
+#if OLYMPIC_DEBUG
+	printk("BCTL: %x\n",readl(olympic_mmio+BCTL));
+	printk("GPR: %x\n",readw(olympic_mmio+GPR));
+	printk("SISRMASK: %x\n",readl(olympic_mmio+SISR_MASK));
+#endif
+	/* Aaaahhh, You have got to be real careful setting GPR, the card
+	   holds the previous values from flash memory, including autosense 
+           and ring speed */
+
+	writel(readl(olympic_mmio+BCTL)|BCTL_MIMREB,olympic_mmio+BCTL);
+	
+	if (olympic_priv->olympic_ring_speed  == 0) { /* Autosense */
+		writel(readl(olympic_mmio+GPR)|GPR_AUTOSENSE,olympic_mmio+GPR);
+		if (olympic_priv->olympic_message_level) 
+			printk(KERN_INFO "%s: Ringspeed autosense mode on\n",dev->name);
+	} else if (olympic_priv->olympic_ring_speed == 16) {
+		if (olympic_priv->olympic_message_level) 
+			printk(KERN_INFO "%s: Trying to open at 16 Mbps as requested\n", dev->name);
+		writel(GPR_16MBPS, olympic_mmio+GPR);
+	} else if (olympic_priv->olympic_ring_speed == 4) {
+		if (olympic_priv->olympic_message_level) 
+			printk(KERN_INFO "%s: Trying to open at 4 Mbps as requested\n", dev->name) ; 
+		writel(0, olympic_mmio+GPR);
+	} 
+	
+	writel(readl(olympic_mmio+GPR)|GPR_NEPTUNE_BF,olympic_mmio+GPR);
+
+#if OLYMPIC_DEBUG
+	printk("GPR = %x\n",readw(olympic_mmio + GPR) ) ; 
+#endif
+	/* start solo init */
+	writel((1<<15),olympic_mmio+SISR_MASK_SUM);
+
+	t=jiffies;
+	while(!((readl(olympic_mmio+SISR_RR)) & SISR_SRB_REPLY)) {
+		schedule();		
+		if(jiffies-t > 40*HZ) {
+			printk(KERN_ERR "IBM PCI tokenring card not responding.\n");
+			release_region(dev->base_addr, OLYMPIC_IO_SPACE); 
+			return -1;
+		}
+	}
+	
+	writel(readl(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
+
+#if OLYMPIC_DEBUG
+	printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));
+#endif
+
+	init_srb=olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWO)) & (~0xf800));
+
+#if OLYMPIC_DEBUG		
+{
+	int i;
+	printk("init_srb(%p): ",init_srb);
+	for(i=0;i<20;i++)
+		printk("%x ",readb(init_srb+i));
+	printk("\n");
+}
+#endif	
+	if(readw(init_srb+6)) {
+		printk(KERN_INFO "tokenring card intialization failed. errorcode : %x\n",readw(init_srb+6));
+		release_region(dev->base_addr, OLYMPIC_IO_SPACE);
+		return -1;
+	}
+
+	uaa_addr=ntohs(readw(init_srb+8));
+
+#if OLYMPIC_DEBUG
+	printk("UAA resides at %x\n",uaa_addr);
+#endif
+
+	writel(uaa_addr,olympic_mmio+LAPA);
+	adapter_addr=olympic_priv->olympic_lap + (uaa_addr & (~0xf800));
+
+#if OLYMPIC_DEBUG
+	printk("adapter address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+			readb(adapter_addr), readb(adapter_addr+1),readb(adapter_addr+2),
+			readb(adapter_addr+3),readb(adapter_addr+4),readb(adapter_addr+5));
+#endif
+
+	memcpy_fromio(&dev->dev_addr[0], adapter_addr,6);
+
+	olympic_priv->olympic_addr_table_addr = ntohs(readw(init_srb + 12)) ; 
+	olympic_priv->olympic_parms_addr      = ntohs(readw(init_srb + 14)) ; 
+
+	return 0;
+
+}
+
+static int olympic_open(struct device *dev) 
+{
+	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
+	__u8 *olympic_mmio=olympic_priv->olympic_mmio,*init_srb;
+	unsigned long flags;
+	char open_error[255] ; 
+	int i, open_finished = 1 ;
+
+#if OLYMPIC_NETWORK_MONITOR
+	__u8 *oat ; 
+	__u8 *opt ; 
+#endif
+
+	if(request_irq(dev->irq, &olympic_interrupt, SA_SHIRQ , "olympic", dev)) {
+		return -EAGAIN;
+	}
+
+#if OLYMPIC_DEBUG
+	printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));
+	printk("pending ints: %x\n",readl(olympic_mmio+SISR_RR));
+#endif
+
+	writel(SISR_MI,olympic_mmio+SISR_MASK_SUM);
+
+	writel(SISR_MI | SISR_SRB_REPLY, olympic_mmio+SISR_MASK); /* more ints later, doesn't stop arb cmd interrupt */
+
+	writel(LISR_LIE,olympic_mmio+LISR); /* more ints later */
+
+	/* adapter is closed, so SRB is pointed to by LAPWWO */
+
+	writel(readl(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
+	init_srb=olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWO)) & (~0xf800));
+	
+#if OLYMPIC_DEBUG
+	printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));
+	printk("SISR Mask = %04x\n", readl(olympic_mmio+SISR_MASK));
+	printk("Before the open command \n");
+#endif	
+	do {
+		int i;
+
+		save_flags(flags);
+		cli();
+		for(i=0;i<SRB_COMMAND_SIZE;i+=4)
+			writel(0,init_srb+i);
+		if(SRB_COMMAND_SIZE & 2)
+			writew(0,init_srb+(SRB_COMMAND_SIZE & ~3));
+		if(SRB_COMMAND_SIZE & 1)
+			writeb(0,init_srb+(SRB_COMMAND_SIZE & ~1));
+
+		writeb(SRB_OPEN_ADAPTER,init_srb) ; 	/* open */
+		writeb(OLYMPIC_CLEAR_RET_CODE,init_srb+2);
+
+		/* If Network Monitor, instruct card to copy MAC frames through the ARB */
+
+#if OLYMPIC_NETWORK_MONITOR
+		writew(ntohs(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON),init_srb+8);
+#else
+		writew(OPEN_ADAPTER_ENABLE_FDX,init_srb+8);
+#endif		
+
+		if (olympic_priv->olympic_laa[0]) {
+			writeb(olympic_priv->olympic_laa[0],init_srb+12);
+			writeb(olympic_priv->olympic_laa[1],init_srb+13);
+			writeb(olympic_priv->olympic_laa[2],init_srb+14);
+			writeb(olympic_priv->olympic_laa[3],init_srb+15);
+			writeb(olympic_priv->olympic_laa[4],init_srb+16);
+			writeb(olympic_priv->olympic_laa[5],init_srb+17);
+			memcpy(dev->dev_addr,olympic_priv->olympic_laa,dev->addr_len) ;  
+		} 	
+		writeb(1,init_srb+30);
+	
+		olympic_priv->srb_queued=1;
+
+		writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
+
+ 		while(olympic_priv->srb_queued) {        
+        		interruptible_sleep_on_timeout(&olympic_priv->srb_wait, 60*HZ);
+        		if(signal_pending(current))	{            
+				printk(KERN_WARNING "%s: SRB timed out.\n",
+                			dev->name);
+            			printk(KERN_WARNING "SISR=%x MISR=%x\n",
+                			readl(olympic_mmio+SISR),
+                			readl(olympic_mmio+LISR));
+            			olympic_priv->srb_queued=0;
+            			break;
+        		}
+    		}
+		restore_flags(flags);
+#if OLYMPIC_DEBUG
+		printk("init_srb(%p): ",init_srb);
+		for(i=0;i<20;i++)
+			printk("%x ",readb(init_srb+i));
+		printk("\n");
+#endif
+		
+		/* If we get the same return response as we set, the interrupt wasn't raised and the open
+                 * timed out.
+		 */
+
+		if(readb(init_srb+2)== OLYMPIC_CLEAR_RET_CODE) {
+			printk(KERN_WARNING "%s: Adapter Open time out or error.\n", dev->name) ; 
+			return -EIO ; 
+		}	
+
+		if(readb(init_srb+2)!=0) {
+			if (readb(init_srb+2) == 0x07) {  
+				if (!olympic_priv->olympic_ring_speed && open_finished) { /* Autosense , first time around */
+					printk(KERN_WARNING "%s: Retrying at different ring speed \n", dev->name); 
+					open_finished = 0 ;  
+				} else {
+
+					strcpy(open_error, open_maj_error[(readb(init_srb+7) & 0xf0) >> 4]) ; 
+					strcat(open_error," - ") ; 
+					strcat(open_error, open_min_error[(readb(init_srb+7) & 0x0f)]) ;
+
+					if (!olympic_priv->olympic_ring_speed && ((readb(init_srb+7) & 0x0f) == 0x0d)) { 
+						printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n",dev->name);
+						printk(KERN_WARNING "%s: Please try again with a specified ring speed \n",dev->name);
+						free_irq(dev->irq, dev);
+						return -EIO ;
+					}
+
+					printk(KERN_WARNING "%s: %s\n",dev->name,open_error);
+					free_irq(dev->irq,dev) ; 
+					return -EIO ; 
+ 
+				}	/* if autosense && open_finished */
+			} else {  
+				printk(KERN_WARNING "%s: Bad OPEN response: %x\n", dev->name,init_srb[2]);
+				free_irq(dev->irq, dev);
+				return -EIO;
+			} 
+		} else 
+			open_finished = 1 ; 
+	} while (!(open_finished)) ; /* Will only loop if ring speed mismatch re-open attempted && autosense is on */	
+
+	if (readb(init_srb+18) & (1<<3)) 
+		if (olympic_priv->olympic_message_level) 
+			printk(KERN_INFO "%s: Opened in FDX Mode\n",dev->name);
+
+	if (readb(init_srb+18) & (1<<1))
+		olympic_priv->olympic_ring_speed = 100 ; 
+	else if (readb(init_srb+18) & 1)
+		olympic_priv->olympic_ring_speed = 16 ; 
+	else
+		olympic_priv->olympic_ring_speed = 4 ; 
+
+	if (olympic_priv->olympic_message_level) 
+		printk(KERN_INFO "%s: Opened in %d Mbps mode\n",dev->name, olympic_priv->olympic_ring_speed);
+
+	olympic_priv->asb=ntohs(readw(init_srb+8));
+	olympic_priv->srb=ntohs(readw(init_srb+10));
+	olympic_priv->arb=ntohs(readw(init_srb+12));
+	olympic_priv->trb=ntohs(readw(init_srb+16));
+
+	olympic_priv->olympic_receive_options = 0x01 ; 
+	olympic_priv->olympic_copy_all_options = 0 ; 
+	
+	/* setup rx ring */
+	
+	writel((3<<16),olympic_mmio+BMCTL_RWM); /* Ensure end of frame generated interrupts */ 
+
+	writel(BMCTL_RX_DIS|3,olympic_mmio+BMCTL_RWM); /* Yes, this the enables RX channel */
+
+	for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
+
+		struct sk_buff *skb;
+		
+		skb=dev_alloc_skb(olympic_priv->pkt_buf_sz);
+		if(skb == NULL)
+			break;
+
+		skb->dev = dev;
+
+		olympic_priv->olympic_rx_ring[i].buffer=virt_to_bus(skb->data);
+		olympic_priv->olympic_rx_ring[i].res_length = olympic_priv->pkt_buf_sz ; 
+		olympic_priv->rx_ring_skb[i]=skb;
+	}
+
+	if (i==0) {
+		printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name);
+		free_irq(dev->irq, dev);
+		return -EIO;
+	}
+
+	writel(virt_to_bus(&olympic_priv->olympic_rx_ring[0]),olympic_mmio+RXDESCQ);
+	writel(virt_to_bus(&olympic_priv->olympic_rx_ring[0]),olympic_mmio+RXCDA);
+	writew(i,olympic_mmio+RXDESCQCNT);
+		
+	writel(virt_to_bus(&olympic_priv->olympic_rx_status_ring[0]),olympic_mmio+RXSTATQ);
+	writel(virt_to_bus(&olympic_priv->olympic_rx_status_ring[0]),olympic_mmio+RXCSA);
+	
+ 	olympic_priv->rx_ring_last_received=OLYMPIC_RX_RING_SIZE-1;	/* last processed rx status */
+	olympic_priv->rx_status_last_received = OLYMPIC_RX_RING_SIZE-1;  
+
+	writew(i,olympic_mmio+RXSTATQCNT);
+
+#if OLYMPIC_DEBUG 
+	printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ));
+	printk("RXCSA: %x, rx_status_ring[0]: %p\n",bus_to_virt(readl(olympic_mmio+RXCSA)),&olympic_priv->olympic_rx_status_ring[0]);
+	printk(" stat_ring[1]: %p, stat_ring[2]: %p, stat_ring[3]: %p\n", &(olympic_priv->olympic_rx_status_ring[1]), &(olympic_priv->olympic_rx_status_ring[2]), &(olympic_priv->olympic_rx_status_ring[3]) );
+	printk(" stat_ring[4]: %p, stat_ring[5]: %p, stat_ring[6]: %p\n", &(olympic_priv->olympic_rx_status_ring[4]), &(olympic_priv->olympic_rx_status_ring[5]), &(olympic_priv->olympic_rx_status_ring[6]) );
+	printk(" stat_ring[7]: %p\n", &(olympic_priv->olympic_rx_status_ring[7])  );
+
+	printk("RXCDA: %x, rx_ring[0]: %p\n",bus_to_virt(readl(olympic_mmio+RXCDA)),&olympic_priv->olympic_rx_ring[0]);
+#endif
+
+	writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | i,olympic_mmio+RXENQ);
+
+#if OLYMPIC_DEBUG 
+	printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ));
+	printk("RXCSA: %x, rx_ring[0]: %p\n",bus_to_virt(readl(olympic_mmio+RXCSA)),&olympic_priv->olympic_rx_status_ring[0]);
+	printk("RXCDA: %x, rx_ring[0]: %p\n",bus_to_virt(readl(olympic_mmio+RXCDA)),&olympic_priv->olympic_rx_ring[0]);
+#endif 
+
+	writel(SISR_RX_STATUS | SISR_RX_NOBUF,olympic_mmio+SISR_MASK_SUM);
+
+	/* setup tx ring */
+
+	writel(BMCTL_TX1_DIS,olympic_mmio+BMCTL_RWM); /* Yes, this enables TX channel 1 */
+	for(i=0;i<OLYMPIC_TX_RING_SIZE;i++) 
+		olympic_priv->olympic_tx_ring[i].buffer=0xdeadbeef;
+
+	olympic_priv->free_tx_ring_entries=OLYMPIC_TX_RING_SIZE;
+	writel(virt_to_bus(&olympic_priv->olympic_tx_ring[0]),olympic_mmio+TXDESCQ_1);
+	writel(virt_to_bus(&olympic_priv->olympic_tx_ring[0]),olympic_mmio+TXCDA_1);
+	writew(OLYMPIC_TX_RING_SIZE,olympic_mmio+TXDESCQCNT_1);
+	
+	writel(virt_to_bus(&olympic_priv->olympic_tx_status_ring[0]),olympic_mmio+TXSTATQ_1);
+	writel(virt_to_bus(&olympic_priv->olympic_tx_status_ring[0]),olympic_mmio+TXCSA_1);
+	writew(OLYMPIC_TX_RING_SIZE,olympic_mmio+TXSTATQCNT_1);
+		
+	olympic_priv->tx_ring_free=0; /* next entry in tx ring to use */
+	olympic_priv->tx_ring_last_status=OLYMPIC_TX_RING_SIZE-1; /* last processed tx status */
+
+	writel(SISR_TX1_EOF | SISR_ADAPTER_CHECK | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_ASB_FREE,olympic_mmio+SISR_MASK_SUM);
+
+#if OLYMPIC_DEBUG 
+	printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));
+	printk("SISR MASK: %x\n",readl(olympic_mmio+SISR_MASK));
+#endif
+
+#if OLYMPIC_NETWORK_MONITOR
+	oat = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; 
+	opt = (__u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; 
+
+	printk("%s: Node Address: %02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, 
+		    readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)), 
+		    readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+1),
+		    readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+2),
+		    readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+3),
+		    readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+4),
+		    readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+5));
+	printk("%s: Functional Address: %02x:%02x:%02x:%02x\n",dev->name, 
+		    readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), 
+		    readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1),
+		    readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2),
+		    readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3));
+
+	printk("%s: NAUN Address: %02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, 
+			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)),
+			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+1),
+			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+2),
+			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+3),
+			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+4),
+			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+5));
+
+
+#endif 	
+	
+	dev->start = 1;
+	dev->interrupt=0;
+	dev->tbusy=0;
+
+	MOD_INC_USE_COUNT ;
+	return 0;
+	
+}	
+
+/*
+ *	When we enter the rx routine we do not know how many frames have been 
+ *	queued on the rx channel.  Therefore we start at the next rx status
+ *	position and travel around the receive ring until we have completed
+ *	all the frames.
+ *
+ *	This means that we may process the frame before we receive the end
+ *	of frame interrupt. This is why we always test the status instead
+ *	of blindly processing the next frame.
+ *	
+ */
+static void olympic_rx(struct device *dev)
+{
+	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
+	__u8 *olympic_mmio=olympic_priv->olympic_mmio;
+	struct olympic_rx_status *rx_status;
+	struct olympic_rx_desc *rx_desc ; 
+	int rx_ring_last_received,length, buffer_cnt, cpy_length, frag_len;
+	struct sk_buff *skb, *skb2;
+	int i;
+
+	rx_status=&(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received + 1) & (OLYMPIC_RX_RING_SIZE - 1)]) ; 
+ 
+	while (rx_status->status_buffercnt) { 
+
+		olympic_priv->rx_status_last_received++ ;
+		olympic_priv->rx_status_last_received &= (OLYMPIC_RX_RING_SIZE -1);
+#if OLYMPIC_DEBUG
+		printk(" stat_ring addr: %x \n", &(olympic_priv->olympic_rx_status_ring[olympic_priv->rx_status_last_received]) ); 
+		printk("rx status: %x rx len: %x \n",rx_status->status_buffercnt,rx_status->fragmentcnt_framelen);	
+#endif
+		length=rx_status->fragmentcnt_framelen & 0xffff;
+		buffer_cnt = rx_status->status_buffercnt & 0xffff ; 
+		i = buffer_cnt ; /* Need buffer_cnt later for rxenq update */ 
+		frag_len = rx_status->fragmentcnt_framelen >> 16 ; 
+
+#if OLYMPIC_DEBUG 
+		printk("length: %x, frag_len: %x, buffer_cnt: %x\n",length,frag_len,buffer_cnt);
+#endif
+
+		if(rx_status->status_buffercnt & 0xC0000000) {
+			if (rx_status->status_buffercnt & 0x3B000000) {
+				if (olympic_priv->olympic_message_level) {
+					if (rx_status->status_buffercnt & (1<<29))  /* Rx Frame Truncated */
+						printk(KERN_WARNING "%s: Rx Frame Truncated \n",dev->name);
+					if (rx_status->status_buffercnt & (1<<28)) /*Rx receive overrun */
+						printk(KERN_WARNING "%s: Rx Frame Receive overrun \n",dev->name);
+					if (rx_status->status_buffercnt & (1<<27)) /* No receive buffers */
+						printk(KERN_WARNING "%s: No receive buffers \n",dev->name);
+					if (rx_status->status_buffercnt & (1<<25)) /* Receive frame error detect */
+						printk(KERN_WARNING "%s: Receive frame error detect \n",dev->name);
+					if (rx_status->status_buffercnt & (1<<24)) /* Received Error Detect */
+						printk(KERN_WARNING "%s: Received Error Detect \n",dev->name);
+				} 
+				olympic_priv->rx_ring_last_received += i ; 
+				olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ; 
+				olympic_priv->olympic_stats.rx_errors++;	 
+			} else {	
+			
+				if (buffer_cnt == 1) {
+					skb = dev_alloc_skb(olympic_priv->pkt_buf_sz) ; 
+				} else {
+					skb = dev_alloc_skb(length) ; 
+				}
+
+				if (skb == NULL) {
+					printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers. \n",dev->name) ;
+					olympic_priv->olympic_stats.rx_dropped++ ; 
+					/* Update counters even though we don't transfer the frame */
+					olympic_priv->rx_ring_last_received += i ; 
+					olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ;  
+				} else  {
+					skb->dev = dev ; 
+
+					/* Optimise based upon number of buffers used. 
+			   	   	   If only one buffer is used we can simply swap the buffers around.
+			   	   	   If more than one then we must use the new buffer and copy the information
+			   	   	   first. Ideally all frames would be in a single buffer, this can be tuned by
+                               	   	   altering the buffer size. */
+				
+ 					if (buffer_cnt==1) {
+						olympic_priv->rx_ring_last_received++ ; 
+						olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1);
+						rx_ring_last_received = olympic_priv->rx_ring_last_received ;
+						skb2=olympic_priv->rx_ring_skb[rx_ring_last_received] ; 
+						skb_put(skb2,length);
+						skb2->protocol = tr_type_trans(skb2,dev);
+						olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer=virt_to_bus(skb->data);
+						olympic_priv->olympic_rx_ring[rx_ring_last_received].res_length = olympic_priv->pkt_buf_sz ; 
+						olympic_priv->rx_ring_skb[rx_ring_last_received] = skb ; 
+						netif_rx(skb2) ; 
+					} else {
+						do { /* Walk the buffers */ 
+							olympic_priv->rx_ring_last_received++ ; 
+							olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1);
+							rx_ring_last_received = olympic_priv->rx_ring_last_received ; 
+							rx_desc = &(olympic_priv->olympic_rx_ring[rx_ring_last_received]);
+							cpy_length = (i == 1 ? frag_len : rx_desc->res_length); 
+							memcpy(skb_put(skb, cpy_length), bus_to_virt(rx_desc->buffer), cpy_length) ; 
+						} while (--i) ; 
+		
+						skb->protocol = tr_type_trans(skb,dev);
+						netif_rx(skb) ; 
+					} 
+					olympic_priv->olympic_stats.rx_packets++ ; 
+					olympic_priv->olympic_stats.rx_bytes += length ; 
+				} /* if skb == null */
+			} /* If status & 0x3b */
+
+		} else { /*if buffercnt & 0xC */
+			olympic_priv->rx_ring_last_received += i ; 
+			olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE - 1) ; 
+		} 
+
+		rx_status->fragmentcnt_framelen = 0 ; 
+		rx_status->status_buffercnt = 0 ; 
+		rx_status = &(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received+1) & (OLYMPIC_RX_RING_SIZE -1) ]);
+
+		writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) |  buffer_cnt , olympic_mmio+RXENQ); 
+	} /* while */
+
+}
+
+static void olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs) 
+{
+	struct device *dev= (struct device *)dev_id;
+	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
+	__u8 *olympic_mmio=olympic_priv->olympic_mmio;
+	__u32 sisr;
+	__u8 *adapter_check_area ; 
+	
+	sisr=readl(olympic_mmio+SISR_RR) ; /* Reset sisr */ 
+	
+	if (!(sisr & SISR_MI)) /* Interrupt isn't for us */ 
+		return ;
+
+	if (dev->interrupt) 
+		printk(KERN_WARNING "%s: Re-entering interrupt \n",dev->name) ; 
+
+	dev->interrupt = 1 ; 
+
+	if (sisr & (SISR_SRB_REPLY | SISR_TX1_EOF | SISR_RX_STATUS | SISR_ADAPTER_CHECK |  
+			SISR_ASB_FREE | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_RX_NOBUF)) {  
+	
+		if(sisr & SISR_SRB_REPLY) {
+			if(olympic_priv->srb_queued==1) {
+				wake_up_interruptible(&olympic_priv->srb_wait);
+			} else if (olympic_priv->srb_queued==2) { 
+				olympic_srb_bh(dev) ; 
+			}
+			olympic_priv->srb_queued=0;
+		} /* SISR_SRB_REPLY */
+
+		if (sisr & SISR_TX1_EOF) {
+			olympic_priv->tx_ring_last_status++;
+			olympic_priv->tx_ring_last_status &= (OLYMPIC_TX_RING_SIZE-1);
+			olympic_priv->free_tx_ring_entries++;
+			olympic_priv->olympic_stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len;
+			olympic_priv->olympic_stats.tx_packets++ ; 
+			dev_kfree_skb(olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]);
+			olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=0xdeadbeef;
+			olympic_priv->olympic_tx_status_ring[olympic_priv->tx_ring_last_status].status=0;
+
+			if(dev->tbusy) {
+				dev->tbusy=0;
+				mark_bh(NET_BH);
+			}
+		} /* SISR_TX1_EOF */
+	
+		if (sisr & SISR_RX_STATUS) {
+			olympic_rx(dev);
+		} /* SISR_RX_STATUS */
+	
+		if (sisr & SISR_ADAPTER_CHECK) {
+			printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name);
+			writel(readl(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
+			adapter_check_area = (__u8 *)(olympic_mmio+LAPWWO) ; 
+			printk(KERN_WARNING "%s: Bytes %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, readb(adapter_check_area+0), readb(adapter_check_area+1), readb(adapter_check_area+2), readb(adapter_check_area+3), readb(adapter_check_area+4), readb(adapter_check_area+5), readb(adapter_check_area+6), readb(adapter_check_area+7)) ; 
+			dev->interrupt = 0  ; 	
+			free_irq(dev->irq, dev) ; 
+	
+		} /* SISR_ADAPTER_CHECK */
+	
+		if (sisr & SISR_ASB_FREE) {
+			/* Wake up anything that is waiting for the asb response */  
+			if (olympic_priv->asb_queued) {
+				olympic_asb_bh(dev) ; 
+			}
+		} /* SISR_ASB_FREE */
+	
+		if (sisr & SISR_ARB_CMD) {
+			olympic_arb_cmd(dev) ; 
+		} /* SISR_ARB_CMD */
+	
+		if (sisr & SISR_TRB_REPLY) {
+			/* Wake up anything that is waiting for the trb response */
+			if (olympic_priv->trb_queued) {
+				wake_up_interruptible(&olympic_priv->trb_wait);
+			}
+			olympic_priv->trb_queued = 0 ; 
+		} /* SISR_TRB_REPLY */	
+	
+		if (sisr & SISR_RX_NOBUF) {
+			/* According to the documentation, we don't have to do anything, but trapping it keeps it out of
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 21'
echo 'File patch-2.3.10 is continued in part 22'
echo 22 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 27 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 27; 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
+		hostdata->adapter_state = AS_LOOP_GOOD;
X 		isp2100_make_portdb(host);
+		printk("qlogicfc%d : Port Database\n", hostdata->host_id);
X 		for (i = 0; hostdata->port_db[i].wwn != 0; i++) {
-			DEBUG(printk("wwn: %08x%08x  scsi_id: %x  loop_id: %x\n", (u_int) (hostdata->port_db[i].wwn >> 32), (u_int) hostdata->port_db[i].wwn, i, hostdata->port_db[i].loop_id));
+			printk("wwn: %08x%08x  scsi_id: %x  loop_id: %x\n", (u_int) (hostdata->port_db[i].wwn >> 32), (u_int) hostdata->port_db[i].wwn, i, hostdata->port_db[i].loop_id);
X 		}
X 	}
-	if (hostdata->loop_up == -1) {
-		printk("qlogicfc.c: The firmware is dead, just return.\n");
+	if (hostdata->adapter_state == AS_FIRMWARE_DEAD) {
+		printk("qlogicfc%d : The firmware is dead, just return.\n", hostdata->host_id);
X 		host->max_id = 0;
X 		return 0;
X 	}
@@ -1050,13 +1129,13 @@
X 	out_ptr = inw(host->io_port + MBOX4);
X 	in_ptr = hostdata->req_in_ptr;
X 
-	DEBUG(printk("qlogicfc : request queue depth %d\n",
+	DEBUG(printk("qlogicfc%d : request queue depth %d\n", hostdata->host_id,
X 		     REQ_QUEUE_DEPTH(in_ptr, out_ptr)));
X 
X 	cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0];
X 	in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN;
X 	if (in_ptr == out_ptr) {
-		DEBUG(printk("qlogicfc : request queue overflow\n"));
+		DEBUG(printk("qlogicfc%d : request queue overflow\n", hostdata->host_id));
X 		return 1;
X 	}
X 	if (hostdata->send_marker) {
@@ -1064,7 +1143,7 @@
X 
X 		TRACE("queue marker", in_ptr, 0);
X 
-		DEBUG(printk("qlogicfc : adding marker entry\n"));
+		DEBUG(printk("qlogicfc%d : adding marker entry\n", hostdata->host_id));
X 		marker = (struct Marker_Entry *) cmd;
X 		memset(marker, 0, sizeof(struct Marker_Entry));
X 
@@ -1077,7 +1156,7 @@
X 		if (((in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN) == out_ptr) {
X 			outw(in_ptr, host->io_port + MBOX4);
X 			hostdata->req_in_ptr = in_ptr;
-			DEBUG(printk("qlogicfc : request queue overflow\n"));
+			DEBUG(printk("qlogicfc%d : request queue overflow\n", hostdata->host_id));
X 			return 1;
X 		}
X 		cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0];
@@ -1094,8 +1173,15 @@
X 		cmd->handle = i;
X 		hostdata->handle_ptrs[i] = Cmnd;
X 		hostdata->handle_serials[i] = Cmnd->serial_number;
-	} else
-		printk("qlogicfc: no handle slots, this should not happen.\n");
+	} else {
+		printk("qlogicfc%d : no handle slots, this should not happen.\n", hostdata->host_id);
+		printk("hostdata->queued is %x, in_ptr: %x\n", hostdata->queued, in_ptr);
+		for (i = 0; i <= QLOGICFC_REQ_QUEUE_LEN; i++){
+			if (!hostdata->handle_ptrs[i]){
+				printk("slot %d has %p\n", i, hostdata->handle_ptrs[i]);
+			}
+		}
+	}
X 
X 	cmd->hdr.entry_type = ENTRY_COMMAND;
X 	cmd->hdr.entry_cnt = 1;
@@ -1106,7 +1192,7 @@
X 	cmd->target_id = Cmnd->target;
X #endif
X 	cmd->total_byte_cnt = (u_int) Cmnd->request_bufflen;
-	cmd->time_out = (SCSI_TIMEOUT / HZ) * 5;
+	cmd->time_out = 0;
X 	memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len);
X 
X 	if (Cmnd->use_sg) {
@@ -1115,15 +1201,18 @@
X 		ds = cmd->dataseg;
X 		/* fill in first two sg entries: */
X 		n = sg_count;
-		if (n > 2)
-			n = 2;
+		if (n > DATASEGS_PER_COMMAND)
+			n = DATASEGS_PER_COMMAND;
+
X 		for (i = 0; i < n; i++) {
-			ds[i].d_base_lo = virt_to_bus_low32(sg->address);
-			ds[i].d_base_high = virt_to_bus_high32(sg->address);
+			ds[i].d_base = virt_to_bus_low32(sg->address);
+#if BITS_PER_LONG > 32
+			ds[i].d_base_hi = virt_to_bus_high32(sg->address);
+#endif
X 			ds[i].d_count = sg->length;
X 			++sg;
X 		}
-		sg_count -= 2;
+		sg_count -= DATASEGS_PER_COMMAND;
X 
X 		while (sg_count > 0) {
X 			++cmd->hdr.entry_cnt;
@@ -1132,28 +1221,31 @@
X 			memset(cont, 0, sizeof(struct Continuation_Entry));
X 			in_ptr = (in_ptr + 1) & QLOGICFC_REQ_QUEUE_LEN;
X 			if (in_ptr == out_ptr) {
-				DEBUG(printk("isp2100: unexpected request queue overflow\n"));
+				DEBUG(printk("qlogicfc%d : unexpected request queue overflow\n", hostdata->host_id));
X 				return 1;
X 			}
X 			TRACE("queue continuation", in_ptr, 0);
X 			cont->hdr.entry_type = ENTRY_CONTINUATION;
X 			ds = cont->dataseg;
X 			n = sg_count;
-			if (n > 5)
-				n = 5;
+			if (n > DATASEGS_PER_CONT)
+				n = DATASEGS_PER_CONT;
X 			for (i = 0; i < n; ++i) {
-				ds[i].d_base_lo = virt_to_bus_low32(sg->address);
-				ds[i].d_base_high = virt_to_bus_high32(sg->address);
+				ds[i].d_base = virt_to_bus_low32(sg->address);
+#if BITS_PER_LONG > 32
+				ds[i].d_base_hi = virt_to_bus_high32(sg->address);
+#endif
X 				ds[i].d_count = sg->length;
X 				++sg;
X 			}
X 			sg_count -= n;
X 		}
X 	} else {
-		cmd->dataseg[0].d_base_lo = virt_to_bus_low32(Cmnd->request_buffer);
-		cmd->dataseg[0].d_base_high = virt_to_bus_high32(Cmnd->request_buffer);
-		cmd->dataseg[0].d_count =
-		    (u_int) Cmnd->request_bufflen;
+		cmd->dataseg[0].d_base = virt_to_bus_low32(Cmnd->request_buffer);
+#if BITS_PER_LONG > 32
+		cmd->dataseg[0].d_base_hi = virt_to_bus_high32(Cmnd->request_buffer);
+#endif
+		cmd->dataseg[0].d_count = (u_int) Cmnd->request_bufflen;
X 		cmd->segment_cnt = 1;
X 	}
X 
@@ -1161,12 +1253,15 @@
X 	case WRITE_10:
X 	case WRITE_6:
X 	case WRITE_BUFFER:
+	case MODE_SELECT:
X 		cmd->control_flags = CFLAG_WRITE;
X 		break;
X 	case REQUEST_SENSE:
X 		/* scsi.c expects sense info in a different buffer */
-		cmd->dataseg[0].d_base_lo = virt_to_bus_low32(Cmnd->sense_buffer);
-		cmd->dataseg[0].d_base_high = virt_to_bus_high32(Cmnd->sense_buffer);
+		cmd->dataseg[0].d_base = virt_to_bus_low32(Cmnd->sense_buffer);
+#if BITS_PER_LONG > 32
+		cmd->dataseg[0].d_base_hi = virt_to_bus_high32(Cmnd->request_buffer);
+#endif
X 		cmd->segment_cnt = 1;
X 		cmd->control_flags = CFLAG_READ;
X 		break;
@@ -1197,6 +1292,7 @@
X 	hostdata->req_in_ptr = in_ptr;
X 
X 	hostdata->queued++;
+
X 	num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
X 	num_free = (num_free > 2) ? num_free - 2 : 0;
X 	host->can_queue = hostdata->queued + num_free;
@@ -1207,7 +1303,7 @@
X 	/* this is really gross */
X 	if (host->can_queue <= host->host_busy){
X 	        if (host->can_queue+2 < host->host_busy) 
-			DEBUG(printk("qlogicfc.c crosses its fingers.\n"));
+			DEBUG(printk("qlogicfc%d.c crosses its fingers.\n", hostdata->host_id));
X 		host->can_queue = host->host_busy + 1;
X 	}
X 
@@ -1242,11 +1338,11 @@
X 
X 	hostdata = (struct isp2100_hostdata *) host->hostdata;
X 
-	DEBUG_INTR(printk("qlogicfc : interrupt on line %d\n", irq));
+	DEBUG_INTR(printk("qlogicfc%d : interrupt on line %d\n", hostdata->host_id, irq));
X 
X 	if (!(inw(host->io_port + PCI_INTER_STS) & 0x08)) {
X 		/* spurious interrupts can happen legally */
-		DEBUG_INTR(printk("qlogicfc: got spurious interrupt\n"));
+		DEBUG_INTR(printk("qlogicfc%d : got spurious interrupt\n", hostdata->host_id));
X 		return;
X 	}
X 	in_ptr = inw(host->io_port + MBOX5);
@@ -1255,26 +1351,28 @@
X 	if ((inw(host->io_port + PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) {
X 		status = inw(host->io_port + MBOX0);
X 
-		DEBUG_INTR(printk("qlogicfc : mbox completion status: %x\n",
-				  status));
+		DEBUG_INTR(printk("qlogicfc%d : mbox completion status: %x\n",
+				  hostdata->host_id, status));
X 
X 		switch (status) {
X 		case LOOP_UP:
-			hostdata->loop_up = 2;
+		        printk("qlogicfc%d : loop is up\n", hostdata->host_id);
+			hostdata->adapter_state = AS_REDO_PORTDB;
X 			break;
X 		case LOOP_DOWN:
-			hostdata->loop_up = 0;
+		        printk("qlogicfc%d : loop is down\n", hostdata->host_id);
+			hostdata->adapter_state = AS_LOOP_DOWN;
X 			break;
X 		case LIP_OCCURED:
X 		case CHANGE_NOTIFICATION:
X 		case PORT_DB_CHANGED:
X 		case LIP_RECEIVED:
-			if (hostdata->loop_up == 1)
-				hostdata->loop_up = 2;
+			if (hostdata->adapter_state == AS_LOOP_GOOD)
+				hostdata->adapter_state = AS_REDO_PORTDB;
X 			break;
X 		case SYSTEM_ERROR:
-			printk("The firmware just choked.\n");
-			hostdata->loop_up = -1;
+			printk("qlogicfc%d : The firmware just choked.\n", hostdata->host_id);
+			hostdata->adapter_state = AS_FIRMWARE_DEAD;
X 			break;
X 		case SCSI_COMMAND_COMPLETE:
X 			handle = inw(host->io_port + MBOX1) | (inw(host->io_port + MBOX2) << 16);
@@ -1286,7 +1384,7 @@
X 				Cmnd->result = 0x0;
X 				(*Cmnd->scsi_done) (Cmnd);
X 			} else
-				printk("qlogicfc.c: got a null value out of handle_ptrs, this sucks\n");
+				printk("qlogicfc%d.c : got a null value out of handle_ptrs, this sucks\n", hostdata->host_id);
X 			break;
X 		case MBOX_COMMAND_COMPLETE:
X 		case INVALID_COMMAND:
@@ -1301,12 +1399,12 @@
X 			outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
X 			return;
X 		default:
-			printk("qlogicfc: got an unknown status? %x\n", status);
+			printk("qlogicfc%d : got an unknown status? %x\n", hostdata->host_id, status);
X 		}
X 		outw(0x0, host->io_port + PCI_SEMAPHORE);
X 	} else {
-		DEBUG_INTR(printk("qlogicfc : response queue update\n"));
-		DEBUG_INTR(printk("qlogicfc : response queue depth %d\n", RES_QUEUE_DEPTH(in_ptr, out_ptr)));
+		DEBUG_INTR(printk("qlogicfc%d : response queue update\n", hostdata->host_id));
+		DEBUG_INTR(printk("qlogicfc%d : response queue depth %d\n", hostdata->host_id, RES_QUEUE_DEPTH(in_ptr, out_ptr)));
X 
X 		while (out_ptr != in_ptr) {
X 			sts = (struct Status_Entry *) &hostdata->res[out_ptr][0];
@@ -1314,24 +1412,41 @@
X                  
X 			TRACE("done", out_ptr, Cmnd);
X 			DEBUG_INTR(isp2100_print_status_entry(sts));
-			if (sts->hdr.entry_type == ENTRY_STATUS) {
-				Cmnd = hostdata->handle_ptrs[sts->handle];
+			if (sts->hdr.entry_type == ENTRY_STATUS && (Cmnd = hostdata->handle_ptrs[sts->handle])) {
X 				Cmnd->result = isp2100_return_status(sts);
X 				hostdata->handle_ptrs[sts->handle] = NULL;
X 				hostdata->queued--;
-				if (hostdata->handle_serials[sts->handle] != Cmnd->serial_number) {
+
+				/* 
+				 * if any of the following are true we do not
+				 * call scsi_done.  if the status is CS_ABORTED
+				 * we dont have to call done because the upper
+				 * level should already know its aborted.
+				 */
+				if (hostdata->handle_serials[sts->handle] != Cmnd->serial_number 
+				    || sts->completion_status == CS_ABORTED){
X 					hostdata->handle_serials[sts->handle] = 0;
X 					outw(out_ptr, host->io_port + MBOX5);
X 					continue;
X 				}
-				hostdata->handle_serials[sts->handle] = 0;
+				/*
+				 * if we get back an error indicating the port
+				 * is not there or if the loop is down and 
+				 * this is a device that used to be there 
+				 * allow the command to timeout.
+				 * the device may well be back in a couple of
+				 * seconds.
+				 */
+				if ((hostdata->adapter_state == AS_LOOP_DOWN || sts->completion_status == CS_PORT_UNAVAILABLE || sts->completion_status == CS_PORT_LOGGED_OUT || sts->completion_status == CS_PORT_CONFIG_CHANGED) && hostdata->port_db[Cmnd->target].wwn){
+					outw(out_ptr, host->io_port + MBOX5);
+					continue;
+				}
X 			} else {
X 				outw(out_ptr, host->io_port + MBOX5);
X 				continue;
X 			}
X 
X 			if (sts->completion_status == CS_RESET_OCCURRED
-			    || sts->completion_status == CS_ABORTED
X 			    || (sts->status_flags & STF_BUS_RESET))
X 				hostdata->send_marker = 1;
X 
@@ -1345,7 +1460,7 @@
X 			if (Cmnd->scsi_done != NULL) {
X 				(*Cmnd->scsi_done) (Cmnd);
X 			} else
-				printk("Ouch, scsi done is NULL\n");
+				printk("qlogicfc%d : Ouch, scsi done is NULL\n", hostdata->host_id);
X 		}
X 		hostdata->res_out_ptr = out_ptr;
X 	}
@@ -1363,7 +1478,7 @@
X 
X 	if (host->can_queue <= host->host_busy){
X 	        if (host->can_queue+2 < host->host_busy) 
-		        DEBUG(printk("qlogicfc crosses its fingers.\n"));
+		        DEBUG(printk("qlogicfc%d : crosses its fingers.\n", hostdata->host_id));
X 		host->can_queue = host->host_busy + 1;
X 	}
X 
@@ -1448,7 +1563,7 @@
X 	int i;
X 	struct Scsi_Host *host;
X 	struct isp2100_hostdata *hostdata;
-	int return_status = SCSI_ABORT_SUCCESS;
+	int return_status = SUCCESS;
X 
X 	ENTER("isp2100_abort");
X 
@@ -1459,27 +1574,39 @@
X 		if (hostdata->handle_ptrs[i] == Cmnd)
X 			break;
X 
-	if (i == QLOGICFC_REQ_QUEUE_LEN)
-		return SCSI_ABORT_ERROR;
+	if (i == QLOGICFC_REQ_QUEUE_LEN){
+		return SUCCESS;
+	}
X 
X 	isp2100_disable_irqs(host);
X 
X 	param[0] = MBOX_ABORT_IOCB;
+#if ISP2100_PORTDB
+	param[1] = (((u_short) hostdata->port_db[Cmnd->target].loop_id) << 8) | Cmnd->lun;
+#else
X 	param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun;
-	param[2] = i >> 16;
-	param[3] = i & 0xffff;
+#endif
+	param[2] = i & 0xffff;
+	param[3] = i >> 16;
X 
X 	isp2100_mbox_command(host, param);
X 
X 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		printk("qlogicfc : scsi abort failure: %x\n", param[0]);
+		printk("qlogicfc%d : scsi abort failure: %x\n", hostdata->host_id, param[0]);
X 		if (param[0] == 0x4005)
X 			Cmnd->result = DID_ERROR << 16;
X 		if (param[0] == 0x4006)
X 			Cmnd->result = DID_BAD_TARGET << 16;
-		(*Cmnd->scsi_done) (Cmnd);
-		return_status = SCSI_ABORT_ERROR;
+		return_status = FAILED;
X 	}
+
+	if (return_status != SUCCESS){
+		param[0] = MBOX_GET_FIRMWARE_STATE;
+		isp2100_mbox_command(host, param);
+		printk("qlogicfc%d : abort failed\n", hostdata->host_id);
+		printk("qlogicfc%d : firmware status is %x %x\n", hostdata->host_id, param[0], param[1]);
+	}
+
X 	isp2100_enable_irqs(host);
X 
X 	LEAVE("isp2100_abort");
@@ -1507,7 +1634,7 @@
X 	isp2100_mbox_command(host, param);
X 
X 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		printk("qlogicfc : scsi bus reset failure: %x\n", param[0]);
+		printk("qlogicfc%d : scsi bus reset failure: %x\n", hostdata->host_id, param[0]);
X 		return_status = SCSI_RESET_ERROR;
X 	}
X 	isp2100_enable_irqs(host);
@@ -1546,6 +1673,8 @@
X 
X 	ENTER("isp2100_reset_hardware");
X 
+	hostdata = (struct isp2100_hostdata *) host->hostdata;
+
X 	outw(0x01, host->io_port + ISP_CTRL_STATUS);
X 	outw(HCCR_RESET, host->io_port + HOST_HCCR);
X 	outw(HCCR_RELEASE, host->io_port + HOST_HCCR);
@@ -1555,22 +1684,22 @@
X 	while (--loop_count && inw(host->io_port + HOST_HCCR) == RISC_BUSY)
X 		barrier();
X 	if (!loop_count)
-		printk("qlogicfc: reset_hardware loop timeout\n");
+		printk("qlogicfc%d : reset_hardware loop timeout\n", hostdata->host_id);
X 
X 
X 
X #if DEBUG_ISP2100
-	printk("qlogicfc : mbox 0 0x%04x \n", inw(host->io_port + MBOX0));
-	printk("qlogicfc : mbox 1 0x%04x \n", inw(host->io_port + MBOX1));
-	printk("qlogicfc : mbox 2 0x%04x \n", inw(host->io_port + MBOX2));
-	printk("qlogicfc : mbox 3 0x%04x \n", inw(host->io_port + MBOX3));
-	printk("qlogicfc : mbox 4 0x%04x \n", inw(host->io_port + MBOX4));
-	printk("qlogicfc : mbox 5 0x%04x \n", inw(host->io_port + MBOX5));
-	printk("qlogicfc : mbox 6 0x%04x \n", inw(host->io_port + MBOX6));
-	printk("qlogicfc : mbox 7 0x%04x \n", inw(host->io_port + MBOX7));
+	printk("qlogicfc%d : mbox 0 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX0));
+	printk("qlogicfc%d : mbox 1 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX1));
+	printk("qlogicfc%d : mbox 2 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX2));
+	printk("qlogicfc%d : mbox 3 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX3));
+	printk("qlogicfc%d : mbox 4 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX4));
+	printk("qlogicfc%d : mbox 5 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX5));
+	printk("qlogicfc%d : mbox 6 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX6));
+	printk("qlogicfc%d : mbox 7 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX7));
X #endif				/* DEBUG_ISP2100 */
X 
-	DEBUG(printk("qlogicfc : verifying checksum\n"));
+	DEBUG(printk("qlogicfc%d : verifying checksum\n", hostdata->host_id));
X 
X #if RELOAD_FIRMWARE
X 	{
@@ -1583,7 +1712,7 @@
X 			isp2100_mbox_command(host, param);
X 
X 			if (param[0] != MBOX_COMMAND_COMPLETE) {
-				printk("qlogicfc : firmware load failure\n");
+				printk("qlogicfc%d : firmware load failure\n", hostdata->host_id);
X 				return 1;
X 			}
X 		}
@@ -1596,10 +1725,10 @@
X 	isp2100_mbox_command(host, param);
X 
X 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		printk("qlogicfc : ram checksum failure\n");
+		printk("qlogicfc%d : ram checksum failure\n", hostdata->host_id);
X 		return 1;
X 	}
-	DEBUG(printk("qlogicfc : executing firmware\n"));
+	DEBUG(printk("qlogicfc%d : executing firmware\n", hostdata->host_id));
X 
X 	param[0] = MBOX_EXEC_FIRMWARE;
X 	param[1] = risc_code_addr01;
@@ -1611,18 +1740,16 @@
X 	isp2100_mbox_command(host, param);
X 
X 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		printk("qlogicfc : about firmware failure\n");
+		printk("qlogicfc%d : about firmware failure\n", hostdata->host_id);
X 		return 1;
X 	}
-	DEBUG(printk("qlogicfc : firmware major revision %d\n", param[1]));
-	DEBUG(printk("qlogicfc : firmware minor revision %d\n", param[2]));
-
-	hostdata = (struct isp2100_hostdata *) host->hostdata;
+	DEBUG(printk("qlogicfc%d : firmware major revision %d\n", hostdata->host_id,  param[1]));
+	DEBUG(printk("qlogicfc%d : firmware minor revision %d\n", hostdata->host_id,  param[2]));
X 
X #ifdef USE_NVRAM_DEFAULTS
X 
X 	if (isp2100_get_nvram_defaults(host, &hostdata->control_block) != 0) {
-		printk("qlogicfc: Could not read from NVRAM\n");
+		printk("qlogicfc%d : Could not read from NVRAM\n", hostdata->host_id);
X 	}
X #endif
X 
@@ -1644,13 +1771,13 @@
X 	param[7] = (u_short) (virt_to_bus_high32(&hostdata->control_block) & 0xffff);
X 	isp2100_mbox_command(host, param);
X 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		printk("qlogicfc.c: Ouch 0x%04x\n", param[0]);
+		printk("qlogicfc%d.c: Ouch 0x%04x\n", hostdata->host_id,  param[0]);
X 		return 1;
X 	}
X 	param[0] = MBOX_GET_FIRMWARE_STATE;
X 	isp2100_mbox_command(host, param);
X 	if (param[0] != MBOX_COMMAND_COMPLETE) {
-		printk("qlogicfc.c: 0x%04x\n", param[0]);
+		printk("qlogicfc%d.c: 0x%04x\n", hostdata->host_id,  param[0]);
X 		return 1;
X 	}
X 
@@ -1698,7 +1825,7 @@
X 
X 	if (pci_read_config_word(pdev, PCI_COMMAND, &command)
X 	  || pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision)) {
-		printk("qlogicfc : error reading PCI configuration\n");
+		printk("qlogicfc%d : error reading PCI configuration\n", hostdata->host_id);
X 		return 1;
X 	}
X 	io_base = pdev->base_address[0];
@@ -1707,28 +1834,28 @@
X 
X 
X 	if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) {
-		printk("qlogicfc : 0x%04x is not QLogic vendor ID\n",
+		printk("qlogicfc%d : 0x%04x is not QLogic vendor ID\n", hostdata->host_id, 
X 		       pdev->vendor);
X 		return 1;
X 	}
X 	if (pdev->device != PCI_DEVICE_ID_QLOGIC_ISP2100) {
-		printk("qlogicfc : 0x%04x does not match ISP2100 device id\n",
+		printk("qlogicfc%d : 0x%04x does not match ISP2100 device id\n", hostdata->host_id, 
X 		       pdev->device);
X 		return 1;
X 	}
X 	if (command & PCI_COMMAND_IO && (io_base & 3) == 1)
X 		io_base &= PCI_BASE_ADDRESS_IO_MASK;
X 	else {
-		printk("qlogicfc : i/o mapping is disabled\n");
+		printk("qlogicfc%d : i/o mapping is disabled\n", hostdata->host_id);
X 		return 1;
X 	}
X 
X 	if (!(command & PCI_COMMAND_MASTER)) {
-		printk("qlogicfc : bus mastering is disabled\n");
+		printk("qlogicfc%d : bus mastering is disabled\n", hostdata->host_id);
X 		return 1;
X 	}
X 	if (revision != ISP2100_REV_ID && revision != ISP2100_REV_ID3)
-		printk("qlogicfc : new isp2100 revision ID (%d)\n", revision);
+		printk("qlogicfc%d : new isp2100 revision ID (%d)\n", hostdata->host_id,  revision);
X 
X 
X 	hostdata->revision = revision;
@@ -1800,21 +1927,22 @@
X 	int loop_count;
X 	struct isp2100_hostdata *hostdata = (struct isp2100_hostdata *) host->hostdata;
X 
-	if (mbox_param[param[0]] == 0)
+	if (mbox_param[param[0]] == 0 || hostdata->adapter_state == AS_FIRMWARE_DEAD)
X 		return 1;
X 
X 	loop_count = DEFAULT_LOOP_COUNT;
X 	while (--loop_count && inw(host->io_port + HOST_HCCR) & 0x0080)
X 		barrier();
X 	if (!loop_count) {
-		printk("qlogicfc: mbox_command loop timeout #1\n");
+		printk("qlogicfc%d : mbox_command loop timeout #1\n", hostdata->host_id);
X 		param[0] = 0x4006;
+		hostdata->adapter_state = AS_FIRMWARE_DEAD;
X 		return 1;
X 	}
X 	hostdata->mbox_done = 0;
X 
X 	if (mbox_param[param[0]] == 0)
-		printk("qlogicfc: invalid mbox command\n");
+		printk("qlogicfc%d : invalid mbox command\n", hostdata->host_id);
X 
X 	if (mbox_param[param[0]] & 0x80)
X 		outw(param[7], host->io_port + MBOX7);
@@ -1843,7 +1971,8 @@
X 		}
X 
X 		if (!loop_count) {
-			printk("qlogicfc: mbox_command loop timeout #2\n");
+			hostdata->adapter_state = AS_FIRMWARE_DEAD;
+			printk("qlogicfc%d : mbox_command loop timeout #2\n", hostdata->host_id);
X 			break;
X 		}
X 		isp2100_intr_handler(host->irq, host, NULL);
@@ -1858,7 +1987,7 @@
X 		barrier();
X 	}
X 	if (!loop_count)
-		printk("qlogicfc: mbox_command loop timeout #3\n");
+		printk("qlogicfc%d : mbox_command loop timeout #3\n", hostdata->host_id);
X 
X 	param[7] = inw(host->io_port + MBOX7);
X 	param[6] = inw(host->io_port + MBOX6);
@@ -1873,19 +2002,21 @@
X 	outw(0x0, host->io_port + PCI_SEMAPHORE);
X 
X 	if (inw(host->io_port + HOST_HCCR) & 0x0080) {
-		printk("mbox op is still pending\n");
+		hostdata->adapter_state = AS_FIRMWARE_DEAD;
+		printk("qlogicfc%d : mbox op is still pending\n", hostdata->host_id);
X 	}
X 	return 0;
X }
X 
+#if DEBUG_ISP2100_INTR
X 
X void isp2100_print_status_entry(struct Status_Entry *status)
X {
-	printk("qlogicfc : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n",
+	printk("qlogicfc : 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("qlogicfc : scsi status = 0x%04x, completion status = 0x%04x\n",
X 	       status->scsi_status, status->completion_status);
-	printk("qlogicfc : state flags = 0x%04x, status flags = 0x%04x\n",
+	printk("qlogicfc : state flags = 0x%04x, status flags = 0x%04x\n", 
X 	       status->state_flags, status->status_flags);
X 	printk("qlogicfc : response info length = 0x%04x, request sense length = 0x%04x\n",
X 	       status->res_info_len, status->req_sense_len);
@@ -1893,6 +2024,7 @@
X 
X }
X 
+#endif                         /* DEBUG_ISP2100_INTR */
X 
X 
X #if DEBUG_ISP2100
@@ -1901,7 +2033,7 @@
X {
X 	int i;
X 
-	printk("qlogicfc : target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n",
+	printk("qlogicfc : target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n", 
X 	       cmd->target, cmd->lun, cmd->cmd_len);
X 	printk("qlogicfc : command = ");
X 	for (i = 0; i < cmd->cmd_len; i++)
diff -u --recursive --new-file v2.3.9/linux/drivers/scsi/qlogicfc.h linux/drivers/scsi/qlogicfc.h
--- v2.3.9/linux/drivers/scsi/qlogicfc.h	Wed Feb 24 16:27:54 1999
+++ linux/drivers/scsi/qlogicfc.h	Mon Jul  5 19:58:24 1999
@@ -61,8 +61,17 @@
X  * requests are queued serially and the scatter/gather limit is
X  * determined for each queue request anew.
X  */
-#define QLOGICFC_REQ_QUEUE_LEN	63	/* must be power of two - 1 */
-#define QLOGICFC_MAX_SG(ql)	(2 + (((ql) > 0) ? 5*((ql) - 1) : 0))
+
+#if BITS_PER_LONG > 32
+#define DATASEGS_PER_COMMAND 2
+#define DATASEGS_PER_CONT 5
+#else
+#define DATASEGS_PER_COMMAND 3
+#define DATASEGS_PER_CONT 7
+#endif
+
+#define QLOGICFC_REQ_QUEUE_LEN	127	/* must be power of two - 1 */
+#define QLOGICFC_MAX_SG(ql)	(DATASEGS_PER_COMMAND + (((ql) > 0) ? DATASEGS_PER_CONT*((ql) - 1) : 0))
X #define QLOGICFC_CMD_PER_LUN    8
X 
X int isp2100_detect(Scsi_Host_Template *);
@@ -84,16 +93,16 @@
X         release:                isp2100_release,                           \
X         info:                   isp2100_info,                              \
X         queuecommand:           isp2100_queuecommand,                      \
-        abort:                  isp2100_abort,                             \
+        eh_abort_handler:       isp2100_abort,                             \
X         reset:                  isp2100_reset,                             \
X         bios_param:             isp2100_biosparam,                         \
X         can_queue:              QLOGICFC_REQ_QUEUE_LEN,                    \
X         this_id:                -1,                                        \
X         sg_tablesize:           QLOGICFC_MAX_SG(QLOGICFC_REQ_QUEUE_LEN),   \
-        cmd_per_lun:            QLOGICFC_CMD_PER_LUN,                      \
+	cmd_per_lun:		QLOGICFC_CMD_PER_LUN, 			   \
X         present:                0,                                         \
X         unchecked_isa_dma:      0,                                         \
-        use_clustering:         DISABLE_CLUSTERING                         \
+        use_clustering:         ENABLE_CLUSTERING 			   \
X }
X 
X #endif /* _QLOGICFC_H */
diff -u --recursive --new-file v2.3.9/linux/drivers/scsi/qlogicisp.c linux/drivers/scsi/qlogicisp.c
--- v2.3.9/linux/drivers/scsi/qlogicisp.c	Thu Apr 22 19:30:08 1999
+++ linux/drivers/scsi/qlogicisp.c	Mon Jul  5 19:58:24 1999
@@ -1065,8 +1065,10 @@
X 		ip[0] = 255;
X 		ip[1] = 63;
X 		ip[2] = size / (ip[0] * ip[1]);
+#if 0
X 		if (ip[2] > 1023)
X 			ip[2] = 1023;
+#endif			
X 	}
X 
X 	LEAVE("isp1020_biosparam");
diff -u --recursive --new-file v2.3.9/linux/drivers/scsi/scsi_debug.c linux/drivers/scsi/scsi_debug.c
--- v2.3.9/linux/drivers/scsi/scsi_debug.c	Sat Jan  2 10:23:01 1999
+++ linux/drivers/scsi/scsi_debug.c	Mon Jul  5 20:35:18 1999
@@ -22,10 +22,6 @@
X #include <asm/system.h>
X #include <asm/io.h>
X 
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
X #include <linux/blk.h>
X #include "scsi.h"
X #include "hosts.h"
diff -u --recursive --new-file v2.3.9/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.3.9/linux/drivers/scsi/sd.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/scsi/sd.c	Tue Jul  6 19:08:33 1999
@@ -1050,6 +1050,7 @@
X 
X     SCpnt->transfersize = rscsi_disks[dev].sector_size;
X     SCpnt->underflow = this_count << 9;
+    SCpnt->cmd_len = 0;
X     scsi_do_cmd (SCpnt, (void *) cmd, buff,
X 		 this_count * rscsi_disks[dev].sector_size,
X 		 rw_intr,
diff -u --recursive --new-file v2.3.9/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- v2.3.9/linux/drivers/scsi/st.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/scsi/st.c	Sat Jul  3 10:42:38 1999
@@ -890,7 +890,7 @@
X     kdev_t devt = inode->i_rdev;
X     int dev;
X 
-    if (atomic_read(&filp->f_count) > 1)
+    if (file_count(filp) > 1)
X 	return 0;
X 
X     dev = TAPE_NR(devt);
diff -u --recursive --new-file v2.3.9/linux/drivers/scsi/sym53c416.c linux/drivers/scsi/sym53c416.c
--- v2.3.9/linux/drivers/scsi/sym53c416.c	Wed Feb 24 16:28:43 1999
+++ linux/drivers/scsi/sym53c416.c	Mon Jul  5 20:35:18 1999
@@ -3,6 +3,10 @@
X  *  Low-level SCSI driver for sym53c416 chip.
X  *  Copyright (C) 1998 Lieven Willems (lw_l...@hotmail.com)
X  * 
+ *  Changes : 
+ * 
+ *  Marcelo Tosatti <mar...@conectiva.com.br> : Added io_request_lock locking
+ * 
X  *  LILO command line usage: sym53c416=<PORTBASE>[,<IRQ>]
X  *
X  *  This program is free software; you can redistribute it and/or modify it
@@ -25,11 +29,11 @@
X #include <linux/sched.h>
X #include <linux/interrupt.h>
X #include <linux/delay.h>
-#include <linux/sched.h>
X #include <linux/proc_fs.h>
X #include <asm/dma.h>
X #include <asm/system.h>
X #include <asm/io.h>
+#include <asm/spinlock.h>
X #include <linux/blk.h>
X #include <linux/version.h>
X #include "scsi.h"
@@ -371,7 +375,9 @@
X     printk("sym53c416: Warning: Reset received\n");
X     current_command->SCp.phase = idle;
X     current_command->result = DID_RESET << 16;
+    spin_lock_irqsave(&io_request_lock, flags);
X     current_command->scsi_done(current_command);
+    spin_unlock_irqrestore(&io_request_lock, flags);
X     return;
X     }
X   if(int_reg & ILCMD)       /* Illegal Command */
@@ -379,7 +385,9 @@
X     printk("sym53c416: Warning: Illegal Command: 0x%02x\n", inb(base + COMMAND_REG));
X     current_command->SCp.phase = idle;
X     current_command->result = DID_ERROR << 16;
+    spin_lock_irqsave(&io_request_lock, flags);
X     current_command->scsi_done(current_command);
+    spin_unlock_irqrestore(&io_request_lock, flags);
X     return;
X     }
X   if(status_reg & GE)         /* Gross Error */
@@ -387,7 +395,9 @@
X     printk("sym53c416: Warning: Gross Error\n");
X     current_command->SCp.phase = idle;
X     current_command->result = DID_ERROR << 16;
+    spin_lock_irqsave(&io_request_lock, flags);
X     current_command->scsi_done(current_command);
+    spin_unlock_irqrestore(&io_request_lock, flags);
X     return;
X     }
X   if(status_reg & PE)         /* Parity Error */
@@ -395,7 +405,9 @@
X     printk("sym53c416: Warning: Parity Error\n");
X     current_command->SCp.phase = idle;
X     current_command->result = DID_PARITY << 16;
+    spin_lock_irqsave(&io_request_lock, flags);
X     current_command->scsi_done(current_command);
+    spin_unlock_irqrestore(&io_request_lock, flags);
X     return;
X     }
X   if(pio_int_reg & (CE | OUE))
@@ -403,7 +415,9 @@
X     printk("sym53c416: Warning: PIO Interrupt Error\n");
X     current_command->SCp.phase = idle;
X     current_command->result = DID_ERROR << 16;
+    spin_lock_irqsave(&io_request_lock, flags);
X     current_command->scsi_done(current_command);
+    spin_unlock_irqrestore(&io_request_lock, flags);
X     return;
X     }
X   if(int_reg & DIS)           /* Disconnect */
@@ -413,7 +427,10 @@
X     else
X       current_command->result = (current_command->SCp.Status & 0xFF) | ((current_command->SCp.Message & 0xFF) << 8) | (DID_OK << 16);
X     current_command->SCp.phase = idle;
+
+    spin_lock_irqsave(&io_request_lock, flags);
X     current_command->scsi_done(current_command);
+    spin_unlock_irqrestore(&io_request_lock, flags);
X     return;
X     }
X   /* Now we handle SCSI phases         */
diff -u --recursive --new-file v2.3.9/linux/drivers/sgi/char/graphics.c linux/drivers/sgi/char/graphics.c
--- v2.3.9/linux/drivers/sgi/char/graphics.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/sgi/char/graphics.c	Fri Jul  2 15:15:51 1999
@@ -262,8 +262,7 @@
X 	NULL,			/* no special mmap-advise */
X 	sgi_graphics_nopage,	/* our magic no-page fault handler */
X 	NULL,			/* no special mmap-wppage */
-	NULL,			/* no special mmap-swapout */
-	NULL			/* no special mmap-swapin */
+	NULL			/* no special mmap-swapout */
X };
X 	
X int
diff -u --recursive --new-file v2.3.9/linux/drivers/sgi/char/shmiq.c linux/drivers/sgi/char/shmiq.c
--- v2.3.9/linux/drivers/sgi/char/shmiq.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/sgi/char/shmiq.c	Fri Jul  2 15:15:51 1999
@@ -302,8 +302,7 @@
X 	NULL,			/* no special mmap-advise */
X 	shmiq_nopage,		/* our magic no-page fault handler */
X 	NULL,			/* no special mmap-wppage */
-	NULL,			/* no special mmap-swapout */
-	NULL			/* no special mmap-swapin */
+	NULL			/* no special mmap-swapout */
X };
X 
X static int
diff -u --recursive --new-file v2.3.9/linux/drivers/sgi/char/usema.c linux/drivers/sgi/char/usema.c
--- v2.3.9/linux/drivers/sgi/char/usema.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/sgi/char/usema.c	Mon Jul  5 19:44:57 1999
@@ -53,8 +53,8 @@
X 	if (newfd < 0)
X 		return newfd;
X 	
-	current->files->fd [newfd] = usema->filp;
-	atomic_inc(&usema->filp->f_count);
+	get_file(usema->filp);
+	fd_install(newfd, usema->filp);
X 	/* Is that it? */
X 	printk("UIOCATTACHSEMA: new usema fd is %d", newfd);
X 	return newfd;
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/cmpci.c linux/drivers/sound/cmpci.c
--- v2.3.9/linux/drivers/sound/cmpci.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/sound/cmpci.c	Mon Jul  5 19:58:24 1999
@@ -2311,9 +2311,7 @@
X 		index++;
X 		continue;
X 
-	err_dev4:
X 		unregister_sound_midi(s->dev_midi);
-	err_dev3:
X 		unregister_sound_mixer(s->dev_mixer);
X 	err_dev2:
X 		unregister_sound_dsp(s->dev_audio);
@@ -2328,7 +2326,6 @@
X #ifdef CONFIG_SOUND_CMPCI_MIDI
X 		release_region(s->iomidi, CM_EXTENT_MIDI);
X #endif
-	err_region4:
X 		release_region(s->iobase, CM_EXTENT_CODEC);
X 	err_region5:
X 		kfree_s(s, sizeof(struct cm_state));
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/dev_table.h linux/drivers/sound/dev_table.h
--- v2.3.9/linux/drivers/sound/dev_table.h	Thu May 13 23:22:48 1999
+++ linux/drivers/sound/dev_table.h	Mon Jul  5 19:58:24 1999
@@ -25,30 +25,18 @@
X #define SNDCARD_DESKPROXL		27	/* Compaq Deskpro XL */
X #define SNDCARD_VIDC			28	/* ARMs VIDC */
X #define SNDCARD_SBPNP			29
-#define SNDCARD_OPL3SA1			38
-#define SNDCARD_OPL3SA1_SB		39
-#define SNDCARD_OPL3SA1_MPU		40
X #define SNDCARD_SOFTOSS			36
X #define SNDCARD_VMIDI			37
+#define SNDCARD_OPL3SA1			38	/* Note: clash in msnd.h */
+#define SNDCARD_OPL3SA1_SB		39
+#define SNDCARD_OPL3SA1_MPU		40
X #define SNDCARD_WAVEFRONT               41
X #define SNDCARD_OPL3SA2                 42
X #define SNDCARD_OPL3SA2_MPU             43
X #define SNDCARD_WAVEARTIST		44
+#define SNDCARD_OPL3SA2_MSS             45	/* Originally missed */
X #define SNDCARD_AD1816                  88
X 
-void attach_opl3sa_wss (struct address_info *hw_config);
-int probe_opl3sa_wss (struct address_info *hw_config);
-void attach_opl3sa_sb (struct address_info *hw_config);
-int probe_opl3sa_sb (struct address_info *hw_config);
-void attach_opl3sa_mpu (struct address_info *hw_config);
-int probe_opl3sa_mpu (struct address_info *hw_config);
-void unload_opl3sa_wss(struct address_info *hw_info);
-void unload_opl3sa_sb(struct address_info *hw_info);
-void unload_opl3sa_mpu(struct address_info *hw_info);
-void attach_softsyn_card (struct address_info *hw_config);
-int probe_softsyn (struct address_info *hw_config);
-void unload_softsyn (struct address_info *hw_config);
-
X /*
X  *	NOTE! 	NOTE!	NOTE!	NOTE!
X  *
@@ -424,6 +412,7 @@
X 
X #ifdef CONFIG_SOUND_OPL3SA2
X 	{"OPL3SA2", 0, SNDCARD_OPL3SA2,	"OPL3SA2",		attach_opl3sa2, probe_opl3sa2, unload_opl3sa2},
+	{"OPL3SA2MSS", 1, SNDCARD_OPL3SA2_MSS,	"OPL3SA2 MSS",		attach_opl3sa2_mss, probe_opl3sa2_mss, unload_opl3sa2_mss},
X 	{"OPL3SA2MPU", 0, SNDCARD_OPL3SA2_MPU,	"OPL3SA2 MIDI",		attach_opl3sa2_mpu, probe_opl3sa2_mpu, unload_opl3sa2_mpu},
X #endif
X 
@@ -587,10 +576,11 @@
X #ifndef CONFIG_OPL3SA2_DMA2
X #define CONFIG_OPL3SA2_DMA2 CONFIG_OPL3SA2_DMA
X #endif
+	{SNDCARD_OPL3SA2, {CONFIG_OPL3SA2_CTRL_BASE, CONFIG_OPL3SA2_IRQ, CONFIG_OPL3SA2_DMA, CONFIG_OPL3SA2_DMA2}, SND_DEFAULT_ENABLE},
+	{SNDCARD_OPL3SA2_MSS, {CONFIG_OPL3SA2_BASE, CONFIG_OPL3SA2_IRQ, CONFIG_OPL3SA2_DMA, CONFIG_OPL3SA2_DMA2}, SND_DEFAULT_ENABLE},
X #ifdef CONFIG_OPL3SA2_MPU_BASE
-	{SNDCARD_OPL3SA2_MPU, {CONFIG_OPL3SA2_MPU_BASE, CONFIG_OPL3SA2_MPU_IRQ, 0, -1}, SND_DEFAULT_ENABLE},
+	{SNDCARD_OPL3SA2_MPU, {CONFIG_OPL3SA2_MPU_BASE, CONFIG_OPL3SA2_MPU_IRQ, CONFIG_OPL3SA2_DMA, -1}, SND_DEFAULT_ENABLE},
X #endif
-	{SNDCARD_OPL3SA2, {CONFIG_OPL3SA2_BASE, CONFIG_OPL3SA2_IRQ, CONFIG_OPL3SA2_DMA, CONFIG_OPL3SA2_DMA2}, SND_DEFAULT_ENABLE},
X #endif
X 
X #ifdef CONFIG_SGALAXY
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/es1370.c linux/drivers/sound/es1370.c
--- v2.3.9/linux/drivers/sound/es1370.c	Fri Jun 18 10:45:58 1999
+++ linux/drivers/sound/es1370.c	Mon Jul  5 19:58:24 1999
@@ -2308,9 +2308,9 @@
X };
X 
X #ifdef MODULE
-__initfunc(int init_module(void))
+int __init init_module(void)
X #else
-__initfunc(int init_es1370(void))
+int __init init_es1370(void)
X #endif
X {
X 	struct es1370_state *s;
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c
--- v2.3.9/linux/drivers/sound/es1371.c	Fri Jun 18 10:45:58 1999
+++ linux/drivers/sound/es1371.c	Mon Jul  5 19:58:24 1999
@@ -2723,9 +2723,9 @@
X };
X 
X #ifdef MODULE
-__initfunc(int init_module(void))
+int __init init_module(void)
X #else
-__initfunc(int init_es1371(void))
+int __init init_es1371(void)
X #endif
X {
X 	struct es1371_state *s;
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/lowlevel/awe_compat-fbsd.h linux/drivers/sound/lowlevel/awe_compat-fbsd.h
--- v2.3.9/linux/drivers/sound/lowlevel/awe_compat-fbsd.h	Wed Dec 16 12:52:01 1998
+++ linux/drivers/sound/lowlevel/awe_compat-fbsd.h	Mon Jul  5 20:35:18 1999
@@ -51,7 +51,6 @@
X 
X #ifdef AWE_OBSOLETE_VOXWARE
X 
-#include <i386/isa/sound/sound_config.h>
X #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_AWE32)
X #define CONFIG_AWE32_SYNTH
X #endif
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/maui.c linux/drivers/sound/maui.c
--- v2.3.9/linux/drivers/sound/maui.c	Thu Nov  5 09:58:46 1998
+++ linux/drivers/sound/maui.c	Mon Jul  5 19:58:24 1999
@@ -15,9 +15,12 @@
X  *					system
X  *
X  *	Status:
- *		Untested
+ *		Andrew J. Kroll		Tested 06/01/1999 with:
+ *					* OSWF.MOT File Version: 1.15
+ *					* OSWF.MOT File Dated: 09/12/94
+ *					* Older versions will cause problems.
X  */
- 
+
X #include <linux/config.h>
X #include <linux/module.h>
X #include <asm/init.h>
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/msnd_pinnacle.c linux/drivers/sound/msnd_pinnacle.c
--- v2.3.9/linux/drivers/sound/msnd_pinnacle.c	Tue May 11 23:40:50 1999
+++ linux/drivers/sound/msnd_pinnacle.c	Mon Jul  5 19:58:24 1999
@@ -1165,7 +1165,7 @@
X 	return -EIO;
X }
X 
-__initfunc(static int probe_multisound(void))
+static int __init probe_multisound(void)
X {
X #ifndef MSND_CLASSIC
X 	char *xv, *rev = NULL;
@@ -1305,7 +1305,7 @@
X 	return 0;
X }
X 
-__initfunc(static int calibrate_adc(WORD srate))
+static int __init calibrate_adc(WORD srate)
X {
X 	writew(srate, dev.SMA + SMA_wCalFreqAtoD);
X 	if (dev.calibrate_signal == 0)
@@ -1427,7 +1427,7 @@
X 	return rv;
X }
X 
-__initfunc(static int attach_multisound(void))
+static int __init attach_multisound(void)
X {
X 	int err;
X 
@@ -1491,7 +1491,7 @@
X 
X /* Pinnacle/Fiji Logical Device Configuration */
X 
-__initfunc(static int msnd_write_cfg(int cfg, int reg, int value))
+static int __init msnd_write_cfg(int cfg, int reg, int value)
X {
X 	outb(reg, cfg);
X 	outb(value, cfg + 1);
@@ -1502,7 +1502,7 @@
X 	return 0;
X }
X 
-__initfunc(static int msnd_write_cfg_io0(int cfg, int num, WORD io))
+static int __init msnd_write_cfg_io0(int cfg, int num, WORD io)
X {
X 	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
X 		return -EIO;
@@ -1513,7 +1513,7 @@
X 	return 0;
X }
X 
-__initfunc(static int msnd_write_cfg_io1(int cfg, int num, WORD io))
+static int __init msnd_write_cfg_io1(int cfg, int num, WORD io)
X {
X 	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
X 		return -EIO;
@@ -1524,7 +1524,7 @@
X 	return 0;
X }
X 
-__initfunc(static int msnd_write_cfg_irq(int cfg, int num, WORD irq))
+static int __init msnd_write_cfg_irq(int cfg, int num, WORD irq)
X {
X 	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
X 		return -EIO;
@@ -1535,7 +1535,7 @@
X 	return 0;
X }
X 
-__initfunc(static int msnd_write_cfg_mem(int cfg, int num, int mem))
+static int __init msnd_write_cfg_mem(int cfg, int num, int mem)
X {
X 	WORD wmem;
X 
@@ -1553,7 +1553,7 @@
X 	return 0;
X }
X 
-__initfunc(static int msnd_activate_logical(int cfg, int num))
+static int __init msnd_activate_logical(int cfg, int num)
X {
X 	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
X 		return -EIO;
@@ -1562,7 +1562,7 @@
X 	return 0;
X }
X 
-__initfunc(static int msnd_write_cfg_logical(int cfg, int num, WORD io0, WORD io1, WORD irq, int mem))
+static int __init msnd_write_cfg_logical(int cfg, int num, WORD io0, WORD io1, WORD irq, int mem)
X {
X 	if (msnd_write_cfg(cfg, IREG_LOGDEVICE, num))
X 		return -EIO;
@@ -1584,7 +1584,7 @@
X 	int mem;
X } msnd_pinnacle_cfg_t[4];
X 
-__initfunc(static int msnd_pinnacle_cfg_devices(int cfg, int reset, msnd_pinnacle_cfg_t device))
+static int __init msnd_pinnacle_cfg_devices(int cfg, int reset, msnd_pinnacle_cfg_t device)
X {
X 	int i;
X 
@@ -1767,9 +1767,9 @@
X calibrate_signal __initdata =		CONFIG_MSND_CALSIGNAL;
X 
X #ifdef MSND_CLASSIC
-__initfunc(int msnd_classic_init(void))
+int __init msnd_classic_init(void)
X #else
-__initfunc(int msnd_pinnacle_init(void))
+int __init msnd_pinnacle_init(void)
X #endif /* MSND_CLASSIC */
X 
X #endif /* MODULE */
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/opl3sa2.c linux/drivers/sound/opl3sa2.c
--- v2.3.9/linux/drivers/sound/opl3sa2.c	Thu Jan  7 09:24:00 1999
+++ linux/drivers/sound/opl3sa2.c	Mon Jul  5 19:58:24 1999
@@ -467,13 +467,13 @@
X }
X 
X 
-static int probe_opl3sa2_mss(struct address_info *hw_config)
+int probe_opl3sa2_mss(struct address_info *hw_config)
X {
X 	return probe_ms_sound(hw_config);
X }
X 
X 
-static void attach_opl3sa2_mss(struct address_info *hw_config)
+void attach_opl3sa2_mss(struct address_info *hw_config)
X {
X 	char mixer_name[64];
X 
@@ -516,7 +516,7 @@
X }
X 
X 
-static void unload_opl3sa2_mss(struct address_info *hw_config)
+void unload_opl3sa2_mss(struct address_info *hw_config)
X {
X 	unload_ms_sound(hw_config);
X }
@@ -592,6 +592,9 @@
X 	{
X 		/* Generate a pretty name */
X 		sprintf(chipset_name, "OPL3-SA%c", tag);
+#if defined(CONFIG_OPL3SA2_MPU_BASE) && !defined(MODULE)
+		sound_getconf(SNDCARD_OPL3SA2_MPU)->always_detect = 1;
+#endif
X 		return 1;
X 	}
X 	return 0;
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/sb_ess.c linux/drivers/sound/sb_ess.c
--- v2.3.9/linux/drivers/sound/sb_ess.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/sound/sb_ess.c	Tue Jul  6 10:11:40 1999
@@ -40,10 +40,10 @@
X  *								recording problems for high samplerates. I
X  *								fixed this by removing ess_calc_best_speed ()
X  *								and just doing what the documentation says. 
- *Javier Achirica(May 15 1999): Major cleanup, MPU IRQ sharing, hardware
- *								volume support, PNP chip configuration,
- *								full duplex in most cards, sample rate fine
- *								tuning.
+ * Andy Sloane  (June 4 1999):  Stole some code from ALSA to fix the playback
+ * an...@guildsoftware.com		speed on ES1869, ES1879, ES1887, and ES1888.
+ * 								1879's were previously ignored by this driver;
+ * 								added (untested) support for those.
X  *
X  * This files contains ESS chip specifics. It's based on the existing ESS
X  * handling as it resided in sb_common.c, sb_mixer.c and sb_audio.c. This
@@ -183,7 +183,6 @@
X  * ES1946	yes		This is a PCI chip; not handled by this driver
X  */
X 
-#include <linux/config.h>
X #include <linux/delay.h>
X 
X #include "sound_config.h"
@@ -195,29 +194,22 @@
X #define ESSTYPE_LIKE20	-1		/* Mimic 2.0 behaviour					*/
X #define ESSTYPE_DETECT	0		/* Mimic 2.0 behaviour					*/
X 
-int esstype = ESSTYPE_LIKE20; /* module parameter in sb_card.c */
+int esstype = ESSTYPE_DETECT; /* module parameter in sb_card.c */
X 
-#define SUBMDL_ES688	0x00	/* Subtype ES688 for specific handling */
-#define SUBMDL_ES1688	0x08	/* Subtype ES1688 for specific handling */
X #define SUBMDL_ES1788	0x10	/* Subtype ES1788 for specific handling */
X #define SUBMDL_ES1868	0x11	/* Subtype ES1868 for specific handling */
X #define SUBMDL_ES1869	0x12	/* Subtype ES1869 for specific handling */
X #define SUBMDL_ES1878	0x13	/* Subtype ES1878 for specific handling */
-#define SUBMDL_ES1879	0x14	/* Subtype ES1879 for specific handling */
-#define SUBMDL_ES1887	0x15	/* Subtype ES1887 for specific handling */
-#define SUBMDL_ES1888	0x16	/* Subtype ES1888 for specific handling */
-
-	/* Recording mixer, stereo full duplex */
-#define ESSCAP_NEW		0x00000100
-	/* ISA PnP configuration */
-#define ESSCAP_PNP		0x00000200
-	/* Full duplex, 6-bit volume, hardware volume controls */
-#define ESSCAP_ES18		0x00000400
-	/* New interrupt handling system (ESS 1887) */
-#define ESSCAP_IRQ		0x00000800
-
-#define ESSFMT_16		0x00000001
-#define ESSFMT_SIGNED	0x00000004
+#define SUBMDL_ES1879	0x16    /* ES1879 was initially forgotten */
+#define SUBMDL_ES1887	0x14	/* Subtype ES1887 for specific handling */
+#define SUBMDL_ES1888	0x15	/* Subtype ES1888 for specific handling */
+
+#define SB_CAP_ES18XX_RATE 0x100
+
+#define ES1688_CLOCK1 795444 /* 128 - div */
+#define ES1688_CLOCK2 397722 /* 256 - div */
+#define ES18XX_CLOCK1 793800 /* 128 - div */
+#define ES18XX_CLOCK2 768000 /* 256 - div */
X 
X #ifdef FKS_LOGGING
X static void ess_show_mixerregs (sb_devc *devc);
@@ -233,6 +225,52 @@
X  *																			*
X  ****************************************************************************/
X 
+struct ess_command {short cmd; short data;};
+
+/*
+ * Commands for initializing Audio 1 for input (record)
+ */
+static struct ess_command ess_i08m[] =		/* input 8 bit mono */
+	{ {0xb7, 0x51}, {0xb7, 0xd0}, {-1, 0} };
+static struct ess_command ess_i16m[] =		/* input 16 bit mono */
+	{ {0xb7, 0x71}, {0xb7, 0xf4}, {-1, 0} };
+static struct ess_command ess_i08s[] =		/* input 8 bit stereo */
+	{ {0xb7, 0x51}, {0xb7, 0x98}, {-1, 0} };
+static struct ess_command ess_i16s[] =		/* input 16 bit stereo */
+	{ {0xb7, 0x71}, {0xb7, 0xbc}, {-1, 0} };
+
+static struct ess_command *ess_inp_cmds[] =
+	{ ess_i08m, ess_i16m, ess_i08s, ess_i16s };
+
+
+/*
+ * Commands for initializing Audio 1 for output (playback)
+ */
+static struct ess_command ess_o08m[] =		/* output 8 bit mono */
+	{ {0xb6, 0x80}, {0xb7, 0x51}, {0xb7, 0xd0}, {-1, 0} };
+static struct ess_command ess_o16m[] =		/* output 16 bit mono */
+	{ {0xb6, 0x00}, {0xb7, 0x71}, {0xb7, 0xf4}, {-1, 0} };
+static struct ess_command ess_o08s[] =		/* output 8 bit stereo */
+	{ {0xb6, 0x80}, {0xb7, 0x51}, {0xb7, 0x98}, {-1, 0} };
+static struct ess_command ess_o16s[] =		/* output 16 bit stereo */
+	{ {0xb6, 0x00}, {0xb7, 0x71}, {0xb7, 0xbc}, {-1, 0} };
+
+static struct ess_command *ess_out_cmds[] =
+	{ ess_o08m, ess_o16m, ess_o08s, ess_o16s };
+
+static void ess_exec_commands
+	(sb_devc *devc, struct ess_command *cmdtab[])
+{
+	struct ess_command *cmd;
+
+	cmd = cmdtab [ ((devc->channels != 1) << 1) + (devc->bits != AFMT_U8) ];
+
+	while (cmd->cmd != -1) {
+		ess_write (devc, cmd->cmd, cmd->data);
+		cmd++;
+	}
+}
+
X static void ess_change
X 	(sb_devc *devc, unsigned int reg, unsigned int mask, unsigned int val)
X {
@@ -272,21 +310,53 @@
X 	devc->irq_mode = IMODE_INPUT;
X }
X 
-static int ess_calc_div (int clock, int *speedp, int *diffp)
+static int ess_calc_div (int clock, int revert, int *speedp, int *diffp)
X {
X 	int divider;
X 	int speed, diff;
+	int retval;
X 
X 	speed   = *speedp;
X 	divider = (clock + speed / 2) / speed;
-	if (divider > 127) {
-		divider = 127;
-	}
+	retval  = revert - divider;
+	if (retval > revert - 1) {
+		retval  = revert - 1;
+		divider = revert - retval;
+	}
+	/* This line is suggested. Must be wrong I think
+	*speedp = (clock + divider / 2) / divider;
+	So I chose the next one */
+
X 	*speedp	= clock / divider;
X 	diff	= speed - *speedp;
-	*diffp = diff < 0 ? -diff : diff;
+	if (diff < 0) diff =-diff;
+	*diffp  = diff;
+
+	return retval;
+}
+
+static int ess_calc_best_speed
+	(int clock1, int rev1, int clock2, int rev2, int *divp, int *speedp)
+{
+	int speed1 = *speedp, speed2 = *speedp;
+	int div1, div2;
+	int diff1, diff2;
+	int retval;
+
+	div1 = ess_calc_div (clock1, rev1, &speed1, &diff1);
+	div2 = ess_calc_div (clock2, rev2, &speed2, &diff2);
+
+	if (diff1 < diff2) {
+		*divp   = div1;
+		*speedp = speed1;
+		retval  = 1;
+	} else {
+		*divp   = div2;
+		*speedp = speed2;
+		retval  = 2;
+	}
X 
-	return 128 - divider;
+	return retval;
X }
X 
X /*
@@ -299,30 +369,24 @@
X  */
X static void ess_common_speed (sb_devc *devc, int *speedp, int *divp)
X {
-	int speed1 = *speedp, speed2 = *speedp;
-	int div1, div2;
-	int diff1, diff2;
+	int diff = 0, div;
X 
-	if (devc->caps & ESSCAP_NEW) {
-		div1 = 0x000 | ess_calc_div (793800, &speed1, &diff1);
-		div2 = 0x080 | ess_calc_div (768000, &speed2, &diff2);
+	if (devc->duplex) {
+		/*
+		 * The 0x80 is important for the first audio channel
+		 */
+		div = 0x80 | ess_calc_div (795500, 128, speedp, &diff);
+	} else if(devc->caps & SB_CAP_ES18XX_RATE) {
+		ess_calc_best_speed(ES18XX_CLOCK1, 128, ES18XX_CLOCK2, 256, 
+						&div, speedp);
X 	} else {
X 		if (*speedp > 22000) {
-			div1 = 0x080 | ess_calc_div (795444, &speed1, &diff1);
-			div2 = 0x180 | ess_calc_div (793800, &speed2, &diff2);
+			div = 0x80 | ess_calc_div (ES1688_CLOCK1, 256, speedp, &diff);
X 		} else {
-			div1 = 0x000 | ess_calc_div (397722, &speed1, &diff1);
-			div2 = 0x100 | ess_calc_div (396900, &speed2, &diff2);
+			div = 0x00 | ess_calc_div (ES1688_CLOCK2, 128, speedp, &diff);
X 		}
X 	}
-
-	if (diff1 < diff2) {
-		*divp   = div1;
-		*speedp = speed1;
-	} else {
-		*divp   = div2;
-		*speedp = speed2;
-	}
+	*divp = div;
X }
X 
X static void ess_speed (sb_devc *devc, int audionum)
@@ -341,13 +405,21 @@
X 
X 	div2 = 256 - 7160000 / (speed * 82);
X 
-	if ((devc->caps & ESSCAP_NEW) && audionum != 1) {
-		ess_setmixer (devc, 0x70, div);
-		ess_setmixer (devc, 0x72, div2);
+	if (!devc->duplex) audionum = 1;
+
+	if (audionum == 1) {
+		/* Change behaviour of register A1 *
+		sb_chg_mixer(devc, 0x71, 0x20, 0x20)
+		* For ES1869 only??? */
+		ess_write (devc, 0xa1, div);
+		ess_write (devc, 0xa2, div2);
X 	} else {
-		ess_change (devc, 0xba, 0x40, (div & 0x100) ? 0x40 : 0x00);
-		ess_write (devc, 0xa1, div & 0xff);
+		ess_setmixer (devc, 0x70, div);
+		/*
+		 * FKS: fascinating: 0x72 doesn't seem to work.
+		 */
X 		ess_write (devc, 0xa2, div2);
+		ess_setmixer (devc, 0x72, div2);
X 	}
X }
X 
@@ -355,14 +427,77 @@
X {
X 	sb_devc *devc = audio_devs[dev]->devc;
X 
+	ess_speed(devc, 1);
+
+	sb_dsp_command(devc, DSP_CMD_SPKOFF);
+
X 	ess_write (devc, 0xb8, 0x0e);	/* Auto init DMA mode */
-	ess_change (devc, 0xa8, 0x0b, 3 - devc->channels);	/* Mono/stereo */
+	ess_change (devc, 0xa8, 0x03, 3 - devc->channels);	/* Mono/stereo */
+	ess_write (devc, 0xb9, 2);	/* Demand mode (4 bytes/DMA request) */
X 
+	ess_exec_commands (devc, ess_inp_cmds);
+
+	ess_change (devc, 0xb1, 0xf0, 0x50);
+	ess_change (devc, 0xb2, 0xf0, 0x50);
+
+	devc->trigger_bits = 0;
+	return 0;
+}
+
+static int ess_audio_prepare_for_output_audio1 (int dev, int bsize, int bcount)
+{
+	sb_devc *devc = audio_devs[dev]->devc;
+
+	sb_dsp_reset(devc);
X 	ess_speed(devc, 1);
+	ess_write (devc, 0xb8, 4);	/* Auto init DMA mode */
+	ess_change (devc, 0xa8, 0x03, 3 - devc->channels);	/* Mono/stereo */
+	ess_write (devc, 0xb9, 2);	/* Demand mode (4 bytes/request) */
X 
-    ess_write (devc, 0xb7, (devc->bits & ESSFMT_SIGNED) ? 0x71 : 0x51);
-    ess_write (devc, 0xb7, 0x90 | ((devc->bits & ESSFMT_SIGNED) ? 0x20 : 0) |
-		((devc->bits & ESSFMT_16) ? 4 : 0) | ((devc->channels > 1) ? 8 : 0x40));
+	ess_exec_commands (devc, ess_out_cmds);
+
+	ess_change (devc, 0xb1, 0xf0, 0x50);	/* Enable DMA */
+	ess_change (devc, 0xb2, 0xf0, 0x50);	/* Enable IRQ */
+
+	sb_dsp_command(devc, DSP_CMD_SPKON);	/* There be sound! */
+
+	devc->trigger_bits = 0;
+	return 0;
+}
+
+static int ess_audio_prepare_for_output_audio2 (int dev, int bsize, int bcount)
+{
+	sb_devc *devc = audio_devs[dev]->devc;
+	unsigned char bits;
+
+/* FKS: qqq
+	sb_dsp_reset(devc);
+*/
+
+	/*
+	 * Auto-Initialize:
+	 * DMA mode + demand mode (8 bytes/request, yes I want it all!)
+	 * But leave 16-bit DMA bit untouched!
+	 */
+	ess_chgmixer (devc, 0x78, 0xd0, 0xd0);
+
+	ess_speed(devc, 2);
+
+	/* bits 4:3 on ES1887 represent recording source. Keep them! */
+	bits = ess_getmixer (devc, 0x7a) & 0x18;
+
+	/* Set stereo/mono */
+	if (devc->channels != 1) bits |= 0x02;
+
+	/* Init DACs; UNSIGNED mode for 8 bit; SIGNED mode for 16 bit */
+	if (devc->bits != AFMT_U8) bits |= 0x05;	/* 16 bit */
+
+	/* Enable DMA, IRQ will be shared (hopefully)*/
+	bits |= 0x60;
+
+	ess_setmixer (devc, 0x7a, bits);
+
+	ess_mixer_reload (devc, SOUND_MIXER_PCM);	/* There be sound! */
X 
X 	devc->trigger_bits = 0;
X 	return 0;
@@ -378,79 +513,144 @@
X #endif
X 
X 	if (devc->duplex) {
-		ess_speed(devc, 2);
+		return ess_audio_prepare_for_output_audio2 (dev, bsize, bcount);
+	} else {
+		return ess_audio_prepare_for_output_audio1 (dev, bsize, bcount);
+	}
+}
X 
-	    ess_chgmixer (devc, 0x7a, 0x07, ((devc->bits & ESSFMT_SIGNED) ? 4 : 0) |
-			((devc->bits & ESSFMT_16) ? 1 : 0) | ((devc->channels > 1) ? 2 : 0));
+static void ess_audio_halt_xfer(int dev)
+{
+	unsigned long flags;
+	sb_devc *devc = audio_devs[dev]->devc;
X 
-		if (devc->caps & ESSCAP_NEW)
-			ess_mixer_reload (devc, SOUND_MIXER_PCM);	/* There be sound! */
-		else
-			sb_dsp_command(devc, DSP_CMD_SPKON);	/* There be sound! */
-	} else {
-		ess_write (devc, 0xb8, 4);	/* Auto init DMA mode */
-		ess_change (devc, 0xa8, 0x03, 3 - devc->channels);	/* Mono/stereo */
+	save_flags(flags);
+	cli();
+	sb_dsp_reset(devc);
+	restore_flags(flags);
X 
-		ess_speed(devc, 1);
+	/*
+	 * Audio 2 may still be operational! Creates awful sounds!
+	 */
+	if (devc->duplex) ess_chgmixer(devc, 0x78, 0x03, 0x00);
+}
X 
-	    ess_write (devc, 0xb6, (devc->bits & ESSFMT_SIGNED) ? 0 : 0x80);
-	    ess_write (devc, 0xb7, (devc->bits & ESSFMT_SIGNED) ? 0x71 : 0x51);
-	    ess_write (devc, 0xb7, 0x90 | ((devc->bits & ESSFMT_SIGNED) ? 0x20 : 0) |
-			((devc->bits & ESSFMT_16) ? 4 : 0) | ((devc->channels > 1) ? 8 : 0x40));
+static void ess_audio_start_input
+	(int dev, unsigned long buf, int nr_bytes, int intrflag)
+{
+	int count = nr_bytes;
+	sb_devc *devc = audio_devs[dev]->devc;
+	short c = -nr_bytes;
X 
-		sb_dsp_command(devc, DSP_CMD_SPKON);	/* There be sound! */
-	}
-	devc->trigger_bits = 0;
-	return 0;
+	/*
+	 * Start a DMA input to the buffer pointed by dmaqtail
+	 */
+
+	if (audio_devs[dev]->dmap_in->dma > 3) count >>= 1;
+	count--;
+
+	devc->irq_mode = IMODE_INPUT;
+
+	ess_write (devc, 0xa4, (unsigned char) ((unsigned short) c & 0xff));
+	ess_write (devc, 0xa5, (unsigned char) (((unsigned short) c >> 8) & 0xff));
+
+	ess_change (devc, 0xb8, 0x0f, 0x0f);	/* Go */
+	devc->intr_active = 1;
X }
X 
-static void ess_audio_halt_xfer(int dev)
+static void ess_audio_output_block_audio1
+	(int dev, unsigned long buf, int nr_bytes, int intrflag)
X {
+	int count = nr_bytes;
X 	sb_devc *devc = audio_devs[dev]->devc;
+	short c = -nr_bytes;
X 
-	sb_dsp_command (devc, DSP_CMD_SPKOFF);
+	if (audio_devs[dev]->dmap_out->dma > 3)
+		count >>= 1;
+	count--;
X 
-	if (devc->caps & ESSCAP_NEW) {
-		ess_setmixer (devc, 0x7c, 0);
-	}
+	devc->irq_mode = IMODE_OUTPUT;
X 
-	ess_change (devc, 0xb8, 0x0f, 0x00);	/* Stop */
+	ess_write (devc, 0xa4, (unsigned char) ((unsigned short) c & 0xff));
+	ess_write (devc, 0xa5, (unsigned char) (((unsigned short) c >> 8) & 0xff));
X 
-	if (devc->duplex) {			/* Audio 2 may still be operational! */
-		ess_chgmixer (devc, 0x78, 0x03, 0x00);
+	ess_change (devc, 0xb8, 0x05, 0x05);	/* Go */
+	devc->intr_active = 1;
+}
+
+static void ess_audio_output_block_audio2
+	(int dev, unsigned long buf, int nr_bytes, int intrflag)
+{
+	int count = nr_bytes;
+	sb_devc *devc = audio_devs[dev]->devc;
+	short c = -nr_bytes;
+
+	if (audio_devs[dev]->dmap_out->dma > 3) count >>= 1;
+	count--;
+
+	ess_setmixer (devc, 0x74, (unsigned char) ((unsigned short) c & 0xff));
+	ess_setmixer (devc, 0x76, (unsigned char) (((unsigned short) c >> 8) & 0xff));
+	ess_chgmixer (devc, 0x78, 0x03, 0x03);   /* Go */
+
+	devc->irq_mode_16 = IMODE_OUTPUT;
+		devc->intr_active_16 = 1;
+}
+
+static void ess_audio_output_block
+	(int dev, unsigned long buf, int nr_bytes, int intrflag)
+{
+	sb_devc *devc = audio_devs[dev]->devc;
+
+	if (devc->duplex) {
+		ess_audio_output_block_audio2 (dev, buf, nr_bytes, intrflag);
+	} else {
+		ess_audio_output_block_audio1 (dev, buf, nr_bytes, intrflag);
X 	}
X }
X 
+/*
+ * FKS: the if-statements for both bits and bits_16 are quite alike.
+ * Combine this...
+ */
X static void ess_audio_trigger(int dev, int bits)
X {
X 	sb_devc *devc = audio_devs[dev]->devc;
X 
-	int bits_16 = bits & devc->irq_mode_16 & IMODE_OUTPUT;
+	int bits_16 = bits & devc->irq_mode_16;
X 	bits &= devc->irq_mode;
X 
X 	if (!bits && !bits_16) {
-		sb_dsp_command (devc, 0xd0);			/* Halt DMA */
-		ess_chgmixer (devc, 0x78, 0x04, 0x00);	/* Halt DMA 2 */
+		/* FKS oh oh.... wrong?? for dma 16? */
+		sb_dsp_command(devc, 0xd0);	/* Halt DMA */
X 	}
X 
X 	if (bits) {
-		short c = -devc->trg_bytes;
-
-		ess_write (devc, 0xa4, (unsigned char)((unsigned short) c & 0xff));
-		ess_write (devc, 0xa5, (unsigned char)((unsigned short) c >> 8));
-		ess_change (devc, 0xb8, 0x0f, (devc->irq_mode==IMODE_INPUT)?0x0f:0x05);
+		switch (devc->irq_mode)
+		{
+			case IMODE_INPUT:
+				ess_audio_start_input(dev, devc->trg_buf, devc->trg_bytes,
+					devc->trg_intrflag);
+				break;
X 
-		devc->intr_active = 1;
+			case IMODE_OUTPUT:
+				ess_audio_output_block(dev, devc->trg_buf, devc->trg_bytes,
+					devc->trg_intrflag);
+				break;
+		}
X 	}
X 
X 	if (bits_16) {
-		short c = -devc->trg_bytes_16;
-
-		ess_setmixer (devc, 0x74, (unsigned char)((unsigned short) c & 0xff));
-		ess_setmixer (devc, 0x76, (unsigned char)((unsigned short) c >> 8));
-		ess_chgmixer (devc, 0x78, 0x03, 0x03);   /* Go */
+		switch (devc->irq_mode_16) {
+		case IMODE_INPUT:
+			ess_audio_start_input(dev, devc->trg_buf_16, devc->trg_bytes_16,
+					devc->trg_intrflag_16);
+			break;
X 
-		devc->intr_active_16 = 1;
+		case IMODE_OUTPUT:
+			ess_audio_output_block(dev, devc->trg_buf_16, devc->trg_bytes_16,
+					devc->trg_intrflag_16);
+			break;
+		}
X 	}
X 
X 	devc->trigger_bits = bits | bits_16;
@@ -462,8 +662,8 @@
X 	int minspeed, maxspeed, dummydiv;
X 
X 	if (speed > 0) {
-		minspeed = (devc->caps & ESSCAP_NEW) ? 6047  : 3125;
-		maxspeed = 48000;
+		minspeed = (devc->duplex ? 6215  : 5000 );
+		maxspeed = (devc->duplex ? 44100 : 48000);
X 		if (speed < minspeed) speed = minspeed;
X 		if (speed > maxspeed) speed = maxspeed;
X 
@@ -474,46 +674,38 @@
X 	return devc->speed;
X }
X 
+/*
+ * FKS: This is a one-on-one copy of sb1_audio_set_bits
+ */
X static unsigned int ess_audio_set_bits(int dev, unsigned int bits)
X {
X 	sb_devc *devc = audio_devs[dev]->devc;
X 
-	switch (bits) {
-		case 0:
-			break;
-		case AFMT_S16_LE:
-			devc->bits = ESSFMT_16 | ESSFMT_SIGNED;
-			break;
-		case AFMT_U16_LE:
-			devc->bits = ESSFMT_16;
-			break;
-		case AFMT_S8:
-			devc->bits = ESSFMT_SIGNED;
-			break;
-		default:
-			devc->bits = 0;
-			break;
+	if (bits != 0) {
+		if (bits == AFMT_U8 || bits == AFMT_S16_LE) {
+			devc->bits = bits;
+		} else {
+			devc->bits = AFMT_U8;
+		}
X 	}
X 
X 	return devc->bits;
X }
X 
+/*
+ * FKS: This is a one-on-one copy of sbpro_audio_set_channels
+ * (*) Modified it!!
+ */
X static short ess_audio_set_channels(int dev, short channels)
X {
X 	sb_devc *devc = audio_devs[dev]->devc;
X 
-	if (devc->fullduplex && !(devc->caps & ESSCAP_NEW)) {
-		devc->channels = 1;
-	} else {
-		if (channels == 1 || channels == 2) {
-			devc->channels = channels;
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 27'
echo 'File patch-2.3.10 is continued in part 28'
echo 28 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 28 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 28; 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
-		}
-	}
+	if (channels == 1 || channels == 2) devc->channels = channels;
X 
X 	return devc->channels;
X }
X 
-static struct audio_driver ess_audio_driver =   /* ESS ES688/1688/18xx */
+static struct audio_driver ess_audio_driver =   /* ESS ES688/1688 */
X {
X 	sb_audio_open,
X 	sb_audio_close,
@@ -540,7 +732,7 @@
X 		(sb_devc *devc, int *audio_flags, int *format_mask)
X {
X 	*audio_flags = DMA_AUTOMODE;
-	*format_mask |= AFMT_S16_LE | AFMT_U16_LE | AFMT_S8;
+	*format_mask |= AFMT_S16_LE;
X 
X 	if (devc->duplex) {
X 		int tmp_dma;
@@ -563,8 +755,10 @@
X  *								ESS common									*
X  *																			*
X  ****************************************************************************/
-static void ess_handle_channel (int dev, int irq_mode)
+static void ess_handle_channel
+	(char *channel, int dev, int intr_active, unsigned char flag, int irq_mode)
X {
+	if (!intr_active || !flag) return;
X #ifdef FKS_REG_LOGGING
X printk(KERN_INFO "FKS: ess_handle_channel %s irq_mode=%d\n", channel, irq_mode);
X #endif
@@ -586,77 +780,48 @@
X }
X 
X /*
- * In the ESS 1888 model, how do we found out if the MPU interrupted ???
+ * FKS: TODO!!! Finish this!
+ *
+ * I think midi stuff uses uart401, without interrupts.
+ * So IMODE_MIDI isn't a value for devc->irq_mode.
X  */
X void ess_intr (sb_devc *devc)
X {
X 	int				status;
X 	unsigned char	src;
X 
-	if (devc->caps & ESSCAP_PNP) {
-		outb (devc->pcibase + 7, 0);		/* Mask IRQs */
-		src = inb (devc->pcibase + 6) & 0x0f;
-	} else if (devc->caps & ESSCAP_IRQ) {
+	if (devc->submodel == SUBMDL_ES1887) {
X 		src = ess_getmixer (devc, 0x7f) >> 4;
X 	} else {
-		src = inb (DSP_STATUS) & 0x01;
-		if (devc->duplex && (ess_getmixer (devc, 0x7a) & 0x80)) {
-			src |= 0x02;
-		}
-		if ((devc->caps & ESSCAP_ES18) && (ess_getmixer (devc, 0x64) & 0x10)) {
-			src |= 0x04;
-		}
-#if defined(CONFIG_MIDI) && defined(CONFIG_SOUND_MPU401)
-		/*
-		 * This should work if dev_conf wasn't local to mpu401.c
-		 */
-#if 0
-		if ((int)devc->midi_irq_cookie >= 0 &&
-			!(inb(dev_conf[(int)devc->midi_irq_cookie].base + 1) & 0x80)) {
-			src |= 0x08;
-		}
-#endif
-#endif
+		src = 0xff;
X 	}
X 
X #ifdef FKS_REG_LOGGING
X printk(KERN_INFO "FKS: sbintr src=%x\n",(int)src);
X #endif
-	if (src & 0x01) {
-		status = inb(DSP_DATA_AVAIL);	/* Acknowledge interrupt */
-		if (devc->intr_active)
-			ess_handle_channel (devc->dev, devc->irq_mode   );
-	}
-
-	if (src & 0x02) {
-		ess_chgmixer (devc, 0x7a, 0x80, 0x00);	/* Acknowledge interrupt */
-		if (devc->intr_active_16)
-			ess_handle_channel (devc->dev, devc->irq_mode_16);
+	ess_handle_channel
+		( "Audio 1"
+		, devc->dev, devc->intr_active   , src & 0x01, devc->irq_mode   );
+	ess_handle_channel
+		( "Audio 2"
+		, devc->dev, devc->intr_active_16, src & 0x02, devc->irq_mode_16);
+	/*
+	 * Acknowledge interrupts
+	 */
+	if (devc->submodel == SUBMDL_ES1887 && (src & 0x02)) {
+		ess_chgmixer (devc, 0x7a, 0x80, 0x00);
X 	}
X 
-	if (src & 0x04) {
-		int left, right;
-
-		ess_setmixer (devc, 0x66, 0x00);	/* Hardware volume IRQ ack */
-
-		left = ess_getmixer (devc, 0x60);
-		right = ess_getmixer (devc, 0x62);
-
-		left = (left & 0x40) ? 0 : ((left * 100 + 31)/ 63);	/* Mute or scale */
-		right = (right & 0x40) ? 0 : ((right * 100 + 31)/ 63);
-
-		devc->levels[SOUND_MIXER_VOLUME] = left | (right << 8);
+	if (src & 0x01) {
+		status = inb(DSP_DATA_AVAIL);
X 	}
+}
X 
-#if defined(CONFIG_MIDI) && defined(CONFIG_SOUND_MPU401)
-	if ((int)devc->midi_irq_cookie >= 0 && (src & 0x08)) {
-		mpuintr (devc->irq, devc->midi_irq_cookie, NULL);
-	}
-#endif
+static void ess_extended (sb_devc * devc)
+{
+	/* Enable extended mode */
X 
-	if (devc->caps & ESSCAP_PNP) {
-		outb (devc->pcibase + 7, 0xff);		/* Unmask IRQs */
-	}
+	sb_dsp_command(devc, 0xc6);
X }
X 
X static int ess_write (sb_devc * devc, unsigned char reg, unsigned char data)
@@ -686,7 +851,7 @@
X 
X int ess_dsp_reset(sb_devc * devc)
X {
-	int loopc, val;
+	int loopc;
X 
X #ifdef FKS_REG_LOGGING
X printk(KERN_INFO "FKS: ess_dsp_reset 1\n");
@@ -707,102 +872,79 @@
X 		DDB(printk("sb: No response to RESET\n"));
X 		return 0;   /* Sorry */
X 	}
+	ess_extended (devc);
X 
-	sb_dsp_command(devc, 0xc6);			/* Enable extended mode */
-	if (!(devc->caps & ESSCAP_PNP)) {
-		ess_setmixer (devc, 0x40, 0x03);	/* Enable joystick and OPL3 */
-
-		switch (devc->irq) {
-			case 2:
-			case 9:
-				val = 1;
-				break;
-			case 5:
-				val = 2;
-				break;
-			case 7:
-				val = 3;
-				break;
-			case 10:
-				val = 4;
-				break;
-			case 11:
-				val = 5;
-				break;
-			default:
-				val = 0;
-		}						/* IRQ config */
-		ess_write (devc, 0xb1, 0xf0 | ((val && val != 5) ? val - 1 : 0));
+	DEB(printk("sb_dsp_reset() OK\n"));
X 
-		if (devc->caps & ESSCAP_IRQ) {
-			ess_setmixer (devc, 0x7f, 0x01 | (val << 1)); /* IRQ config */
-		}
+#ifdef FKS_LOGGING
+printk(KERN_INFO "FKS: dsp_reset 2\n");
+ess_show_mixerregs (devc);
+#endif
X 
-		switch ((devc->duplex) ? devc->dma16 : devc->dma8) {
-			case 0:
-				val = 0x54;
-				break;
-			case 1:
- val = 0x58;
-				break;
-			case 3:
-				val = 0x5c;
-				break;
-			default:
-				val = 0;
-		}
-		ess_write (devc, 0xb2, val); /* DMA1 config */
+	return 1;
+}
X 
-		if (devc->duplex) {
-			switch (devc->dma8) {
-				case 0:
-					val = 0x04;
-					break;
-				case 1:
- val = 0x05;
-					break;
-				case 3:
-					val = 0x06;
-					break;
-				case 5:
-					val = 0x07;
-					break;
-				default:
-					val = 0;
-			}
-			ess_write (devc, 0x7d, val); /* DMA2 config */
-		}
-	}
-	ess_change (devc, 0xb1, 0xf0, 0x50);	/* Enable IRQ 1 */
-	ess_change (devc, 0xb2, 0xf0, 0x50);	/* Enable DMA 1 */
-	ess_write (devc, 0xb9, 2);			/* Demand mode (4 bytes/DMA request) */
-	ess_setmixer (devc, 0x7a, 0x40);	/* Enable IRQ 2 */
-			/* Auto-Initialize DMA mode + demand mode (8 bytes/request) */
-	if (devc->caps & ESSCAP_PNP) {
-		ess_setmixer (devc, 0x78, 0xd0);
-		ess_setmixer (devc, 0x64, 0x82);		/* Enable HW volume interrupt */
-	} else {
-		ess_setmixer (devc, 0x78, (devc->dma8 > 4) ? 0xf0 : 0xd0);
-		ess_setmixer (devc, 0x64, 0x42);		/* Enable HW volume interrupt */
-	}
+static int ess_irq_bits (int irq)
+{
+	switch (irq) {
+	case 2:
+	case 9:
+		return 0;
X 
-    if (devc->caps & ESSCAP_NEW) {
-		ess_setmixer (devc, 0x71, 0x32); /* Change behaviour of register A1 */
-		ess_setmixer (devc, 0x1c, 0x05); /* Recording source is mixer */
-	} else {
-		ess_change (devc, 0xb7, 0x80, 0x80); /* Enable DMA FIFO */
+	case 5:
+		return 1;
+
+	case 7:
+		return 2;
+
+	case 10:
+		return 3;
+
+	default:
+		printk(KERN_ERR "ESS1688: Invalid IRQ %d\n", irq);
+		return -1;
X 	}
+}
X 
-	DEB(printk("sb_dsp_reset() OK\n"));
+/*
+ *	Set IRQ configuration register for all ESS models
+ */
+static int ess_common_set_irq_hw (sb_devc * devc)
+{
+	int irq_bits;
X 
-#ifdef FKS_LOGGING
-printk(KERN_INFO "FKS: dsp_reset 2\n");
-ess_show_mixerregs (devc);
-#endif
+	if ((irq_bits = ess_irq_bits (devc->irq)) == -1) return 0;
X 
+	if (!ess_write (devc, 0xb1, 0x50 | (irq_bits << 2))) {
+		printk(KERN_ERR "ES1688: Failed to write to IRQ config register\n");
+		return 0;
+	}
X 	return 1;
X }
X 
+/*
+ * I wanna use modern ES1887 mixer irq handling. Funny is the
+ * fact that my BIOS wants the same. But suppose someone's BIOS
+ * doesn't do this!
+ * This is independent of duplex. If there's a 1887 this will
+ * prevent it from going into 1888 mode.
+ */
+static void ess_es1887_set_irq_hw (sb_devc * devc)
+{
+	int irq_bits;
+
+	if ((irq_bits = ess_irq_bits (devc->irq)) == -1) return;
+
+	ess_chgmixer (devc, 0x7f, 0x0f, 0x01 | ((irq_bits + 1) << 1));
+}
+
+static int ess_set_irq_hw (sb_devc * devc)
+{
+	if (devc->submodel == SUBMDL_ES1887) ess_es1887_set_irq_hw (devc);
+
+	return ess_common_set_irq_hw (devc);
+}
+
X #ifdef FKS_TEST
X 
X /*
@@ -826,7 +968,7 @@
X };
X #endif
X 
-static unsigned int ess_identify (sb_devc * devc, int *control)
+static unsigned int ess_identify (sb_devc * devc)
X {
X 	unsigned int val;
X 	unsigned long flags;
@@ -840,15 +982,8 @@
X 	udelay(20);
X 	val |= inb(MIXER_DATA);
X 	udelay(20);
-	*control  = inb(MIXER_DATA) << 8;
-	udelay(20);
-	*control |= inb(MIXER_DATA);
-	udelay(20);
X 	restore_flags(flags);
X 
-	if (*control < 0 || *control > 0x3ff || check_region (*control, 8))
-		*control = 0;
-
X 	return val;
X }
X 
@@ -875,6 +1010,7 @@
X 
X int ess_init(sb_devc * devc, struct address_info *hw_config)
X {
+	unsigned char cfg;
X 	int ess_major = 0, ess_minor = 0;
X 	int i;
X 	static char name[100], modelname[10];
@@ -882,7 +1018,6 @@
X 	/*
X 	 * Try to detect ESS chips.
X 	 */
-	devc->pcibase = 0;
X 
X 	sb_dsp_command(devc, 0xe7); /* Return identification */
X 
@@ -934,10 +1069,10 @@
X 		case ESSTYPE_LIKE20:
X 			break;
X 		case 688:
-			submodel = SUBMDL_ES688;
+			submodel = 0x00;
X 			break;
X 		case 1688:
-			submodel = SUBMDL_ES1688;
+			submodel = 0x08;
X 			break;
X 		case 1868:
X 			submodel = SUBMDL_ES1868;
@@ -986,7 +1121,7 @@
X 		if (chip == NULL) {
X 			int type;
X 
-			type = ess_identify (devc, &devc->pcibase);
+			type = ess_identify (devc);
X 
X 			switch (type) {
X 			case 0x1868:
@@ -1063,72 +1198,139 @@
X 		strcpy(name, "Jazz16");
X 	}
X 
-	switch (devc->submodel) {
-	case SUBMDL_ES1869:
-	case SUBMDL_ES1879:
-		devc->caps |= ESSCAP_NEW;
-	case SUBMDL_ES1868:
-	case SUBMDL_ES1878:
-		devc->caps |= ESSCAP_PNP | ESSCAP_ES18;
-		break;
-	case SUBMDL_ES1887:
-		devc->caps |= ESSCAP_IRQ;
-	case SUBMDL_ES1888:
-		devc->caps |= ESSCAP_NEW | ESSCAP_ES18;
-	}
-    if (devc->caps & ESSCAP_PNP) {
-		if (!devc->pcibase) {
-			printk (KERN_ERR "ESS PnP chip without PnP registers. Ignored\n");
-			return 0;
-		}
-		request_region (devc->pcibase, 8, "ESS18xx ctrl");
+	/* AAS: info stolen from ALSA: these boards have different clocks */
+	switch(devc->submodel) {
+		case SUBMDL_ES1869:
+		case SUBMDL_ES1887:
+		case SUBMDL_ES1888:
+			devc->caps |= SB_CAP_ES18XX_RATE;
+			break;
+	}
+
+	hw_config->name = name;
+	/* FKS: sb_dsp_reset to enable extended mode???? */
+	sb_dsp_reset(devc); /* Turn on extended mode */
X 
-		outb (0x07, devc->pcibase);		/* Selects logical device #1 */
-		outb (0x01, devc->pcibase + 1);
-		outb (0x28, devc->pcibase);
-		i = inb (devc->pcibase + 1) & 0x0f;
-		outb (0x28, devc->pcibase);		/* Sets HW volume IRQ */
-		outb (devc->irq << 4 | i, devc->pcibase + 1);
-		outb (0x70, devc->pcibase);		/* Sets IRQ 1 */
-		outb (devc->irq, devc->pcibase + 1);
-		outb (0x72, devc->pcibase);		/* Sets IRQ 2 */
-		outb (devc->irq, devc->pcibase + 1);
-		outb (0x74, devc->pcibase);		/* Sets DMA 1 */
-		outb (hw_config->dma, devc->pcibase + 1);
-		outb (0x75, devc->pcibase);		/* Sets DMA 2 */
-		outb (hw_config->dma2 >= 0 ? hw_config->dma2 : 4, devc->pcibase + 1);
-	} else if (devc->pcibase) {
-		printk (KERN_INFO "Non-PnP ESS card with PnP registers at %04Xh, ignoring them.\n", devc->pcibase);
-		devc->pcibase = 0;
+	/*
+	 *  Enable joystick and OPL3
+	 */
+	cfg = ess_getmixer (devc, 0x40);
+	ess_setmixer (devc, 0x40, cfg | 0x03);
+	if (devc->submodel >= 8) {		/* ES1688 */
+		devc->caps |= SB_NO_MIDI;   /* ES1688 uses MPU401 MIDI mode */
X 	}
+	sb_dsp_reset (devc);
X 
-	devc->caps |= SB_NO_MIDI;   /* ES1688 uses MPU401 MIDI mode */
+	/*
+	 * This is important! If it's not done, the IRQ probe in sb_dsp_init
+	 * may fail.
+	 */
+	return ess_set_irq_hw (devc);
+}
X 
-	hw_config->name = name;
+static int ess_set_dma_hw(sb_devc * devc)
+{
+	unsigned char cfg, dma_bits = 0, dma16_bits;
+	int dma;
X 
-	sb_dsp_reset(devc); /* Turn on extended mode */
+#ifdef FKS_LOGGING
+printk(KERN_INFO "ess_set_dma_hw: dma8=%d,dma16=%d,dup=%d\n"
+, devc->dma8, devc->dma16, devc->duplex);
+#endif
X 
-	ess_setmixer (devc, 0x00, 0x00);	/* Reset mixer registers */
+	/*
+	 * FKS: It seems as if this duplex flag isn't set yet. Check it.
+	 */
+	dma = devc->dma8;
X 
+	if (dma > 3 || dma < 0 || dma == 2) {
+		dma_bits = 0;
+		printk(KERN_ERR "ESS1688: Invalid DMA8 %d\n", dma);
+		return 0;
+	} else {
+		/* Extended mode DMA enable */
+		cfg = 0x50;
+
+		if (dma == 3) {
+			dma_bits = 3;
+		} else {
+			dma_bits = dma + 1;
+		}
+	}
+
+	if (!ess_write (devc, 0xb2, cfg | (dma_bits << 2))) {
+		printk(KERN_ERR "ESS1688: Failed to write to DMA config register\n");
+		return 0;
+	}
+
+	if (devc->duplex) {
+		dma = devc->dma16;
+		dma16_bits = 0;
+
+		if (dma >= 0) {
+			switch (dma) {
+			case 0:
+				dma_bits = 0x04;
+				break;
+			case 1:
+				dma_bits = 0x05;
+				break;
+			case 3:
+				dma_bits = 0x06;
+				break;
+			case 5:
+				dma_bits   = 0x07;
+				dma16_bits = 0x20;
+				break;
+			default:
+				printk(KERN_ERR "ESS1887: Invalid DMA16 %d\n", dma);
+				return 0;
+			};
+			ess_chgmixer (devc, 0x78, 0x20, dma16_bits);
+			ess_chgmixer (devc, 0x7d, 0x07, dma_bits);
+		}
+	}
X 	return 1;
X }
X 
X /*
X  * This one is called from sb_dsp_init.
+ *
+ * Return values:
+ *  0: Failed
+ *  1: Succeeded or doesn't apply (not SUBMDL_ES1887)
X  */
X int ess_dsp_init (sb_devc *devc, struct address_info *hw_config)
X {
X 	/*
+	 * This for ES1887 to run Full Duplex. Actually ES1888
+	 * is allowed to do so too. I have no idea yet if this
+	 * will work for ES1888 however.
+	 *
X 	 * For SB16 having both dma8 and dma16 means enable
-	 * Full Duplex. Let's try this too
+	 * Full Duplex. Let's try this for ES1887 too
+	 *
X 	 */
-	if ((devc->caps & ESSCAP_ES18) && hw_config->dma2 >= 0) {
-		devc->dma16 = hw_config->dma2;
-		if (devc->dma8 != devc->dma16) {
+	if (devc->submodel == SUBMDL_ES1887) {
+		if (hw_config->dma2 != -1) {
+			devc->dma16 = hw_config->dma2;
+		}
+		/*
+		 * devc->duplex initialization is put here, cause
+		 * ess_set_dma_hw needs it.
+		 */
+		if (devc->dma8 != devc->dma16 && devc->dma16 != -1) {
X 			devc->duplex = 1;
X 		}
+
+		if (!ess_set_dma_hw (devc)) {
+			free_irq(devc->irq, devc);
+			return 0;
+		}
+		return 1;
+	} else {
+		return -1;
X 	}
-	return 1;
X }
X 
X /****************************************************************************
@@ -1149,13 +1351,13 @@
X #define ES1688_MIXER_DEVICES		\
X 			( ES688_MIXER_DEVICES | SOUND_MASK_RECLEV	)
X 
-#define ES_NEW_RECORDING_DEVICES	\
+#define ES1887_RECORDING_DEVICES	\
X 			( ES1688_RECORDING_DEVICES | SOUND_MASK_LINE2 | SOUND_MASK_SYNTH)
-#define ES_NEW_MIXER_DEVICES		\
+#define ES1887_MIXER_DEVICES		\
X 			( ES1688_MIXER_DEVICES											)
X 
X /*
- * Mixer registers of ES18xx with new capabilities
+ * Mixer registers of ES1887
X  *
X  * These registers specifically take care of recording levels. To make the
X  * mapping from playback devices to recording devices every recording
@@ -1285,11 +1487,11 @@
X };
X 
X /*
- * This one is for new ES's. It's little different from es_rec_mix: it
- * has 0x7c for PCM playback level. This is because uses
+ * This one is for ES1887. It's little different from es_rec_mix: it
+ * has 0x7c for PCM playback level. This is because ES1887 uses
X  * Audio 2 for playback.
X  */
-static mixer_tab es_new_mix = {
+static mixer_tab es1887_mix = {
X MIX_ENT(SOUND_MIXER_VOLUME,			0x60, 5, 6, 0x62, 5, 6),
X MIX_ENT(SOUND_MIXER_BASS,			0x00, 0, 0, 0x00, 0, 0),
X MIX_ENT(SOUND_MIXER_TREBLE,			0x00, 0, 0, 0x00, 0, 0),
@@ -1323,6 +1525,16 @@
X MIX_ENT(ES_REC_MIXER_RECLINE3,		0x00, 0, 0, 0x00, 0, 0)
X };
X 
+static int ess_has_rec_mixer (int submodel)
+{
+	switch (submodel) {
+	case SUBMDL_ES1887:
+		return 1;
+	default:
+		return 0;
+	};
+};
+
X #ifdef FKS_LOGGING
X static int ess_mixer_mon_regs[]
X 	= { 0x70, 0x71, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7d, 0x7f
@@ -1353,13 +1565,15 @@
X 
X 	save_flags(flags);
X 	cli();
+	if (port >= 0xa0) {
+		ess_write (devc, port, value);
+	} else {
+		outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
X 
-	outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
-
-	udelay(20);
-	outb(((unsigned char) (value & 0xff)), MIXER_DATA);
-	udelay(20);
-
+		udelay(20);
+		outb(((unsigned char) (value & 0xff)), MIXER_DATA);
+		udelay(20);
+	};
X 	restore_flags(flags);
X }
X 
@@ -1371,12 +1585,15 @@
X 	save_flags(flags);
X 	cli();
X 
-	outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
-
-	udelay(20);
-	val = inb(MIXER_DATA);
-	udelay(20);
+	if (port >= 0xa0) {
+		val = ess_read (devc, port);
+	} else {
+		outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
X 
+		udelay(20);
+		val = inb(MIXER_DATA);
+		udelay(20);
+	}
X 	restore_flags(flags);
X 
X 	return val;
@@ -1400,21 +1617,23 @@
X 	devc->mixer_caps = SOUND_CAP_EXCL_INPUT;
X 
X 	/*
-	* Take care of new ES's specifics...
+	* Take care of ES1887 specifics...
X 	*/
-	if (devc->caps & ESSCAP_NEW) {
-		devc->supported_devices		= ES_NEW_MIXER_DEVICES;
-		devc->supported_rec_devices	= ES_NEW_RECORDING_DEVICES;
+	switch (devc->submodel) {
+	case SUBMDL_ES1887:
+		devc->supported_devices		= ES1887_MIXER_DEVICES;
+		devc->supported_rec_devices	= ES1887_RECORDING_DEVICES;
X #ifdef FKS_LOGGING
X printk (KERN_INFO "FKS: ess_mixer_init dup = %d\n", devc->duplex);
X #endif
X 		if (devc->duplex) {
-			devc->iomap				= &es_new_mix;
+			devc->iomap				= &es1887_mix;
X 		} else {
X 			devc->iomap				= &es_rec_mix;
X 		}
-	} else {
-		if (devc->submodel == SUBMDL_ES688) {
+		break;
+	default:
+		if (devc->submodel < 8) {
X 			devc->supported_devices		= ES688_MIXER_DEVICES;
X 			devc->supported_rec_devices	= ES688_RECORDING_DEVICES;
X 			devc->iomap					= &es688_mix;
@@ -1425,10 +1644,10 @@
X 			 */
X 			devc->supported_devices		= ES1688_MIXER_DEVICES;
X 			devc->supported_rec_devices	= ES1688_RECORDING_DEVICES;
-			if (devc->caps & ESSCAP_ES18) {
-				devc->iomap				= &es1688later_mix;
-			} else {
+			if (devc->submodel < 0x10) {
X 				devc->iomap				= &es1688_mix;
+			} else {
+				devc->iomap				= &es1688later_mix;
X 			}
X 		}
X 	}
@@ -1440,15 +1659,9 @@
X  */
X int ess_mixer_set(sb_devc *devc, int dev, int left, int right)
X {
-	if ((devc->caps & ESSCAP_NEW) && (devc->recmask & (1 << dev))) {
+	if (ess_has_rec_mixer (devc->submodel) && (devc->recmask & (1 << dev))) {
X 		sb_common_mixer_set (devc, dev + ES_REC_MIXER_RECDIFF, left, right);
X 	}
-	/* Set & unmute master volume */
-	if ((devc->caps & ESSCAP_ES18) && (dev == SOUND_MIXER_VOLUME)) {
-		ess_chgmixer (devc, 0x60, 0x7f, 0x3f & ((left * 0x3f + 50) / 100));
-		ess_chgmixer (devc, 0x62, 0x7f, 0x3f & ((right * 0x3f + 50) / 100));
-		return left | (right << 8);
-	}
X 	return sb_common_mixer_set (devc, dev, left, right);
X }
X 
@@ -1494,6 +1707,7 @@
X 				right = (value & 0x0000ff00) >> 8;
X 			} else {				/* Turn it off (3)  */
X 				left  = 0;
+				left  = 0;
X 				right = 0;
X 			}
X 			sb_common_mixer_set(devc, i + ES_REC_MIXER_RECDIFF, left, right);
@@ -1506,7 +1720,7 @@
X {
X 	/* This applies to ESS chips with record mixers only! */
X 
-	if (devc->caps & ESSCAP_NEW) {
+	if (ess_has_rec_mixer (devc->submodel)) {
X 		*mask	= es_rec_set_recmask (devc, *mask);
X 		return 1;									/* Applied		*/
X 	} else {
@@ -1522,7 +1736,18 @@
X 	/*
X 	 * Separate actions for ESS chips with a record mixer:
X 	 */
-	if (devc->caps & ESSCAP_NEW) {
+	if (ess_has_rec_mixer (devc->submodel)) {
+		switch (devc->submodel) {
+		case SUBMDL_ES1887:
+			/*
+			 * Separate actions for ES1887:
+			 * Change registers 7a and 1c to make the record mixer the
+			 * actual recording source.
+			 */
+			ess_chgmixer(devc, 0x7a, 0x18, 0x08);
+			ess_chgmixer(devc, 0x1c, 0x07, 0x07);
+			break;
+		};
X 		/*
X 		 * Call set_recmask for proper initialization
X 		 */
@@ -1542,80 +1767,50 @@
X  *																			*
X  ****************************************************************************/
X 
+/*
+ * FKS: IRQ may be shared. Hm. And if so? Then What?
+ */
X int ess_midi_init(sb_devc * devc, struct address_info *hw_config)
X {
-	int val;
+	unsigned char   cfg, tmp;
X 
-	if (devc->submodel == SUBMDL_ES688) {
-		return 0;				/* ES688 doesn't support MPU401 mode */
+	cfg = ess_getmixer (devc, 0x40) & 0x03;
+
+	if (devc->submodel < 8) {
+		ess_setmixer (devc, 0x40, cfg | 0x03);	/* Enable OPL3 & joystick */
+		return 0;  					 /* ES688 doesn't support MPU401 mode */
X 	}
+	tmp = (hw_config->io_base & 0x0f0) >> 4;
X 
-	if (hw_config->irq < 2) {
-		hw_config->irq = devc->irq;
+	if (tmp > 3) {
+		ess_setmixer (devc, 0x40, cfg);
+		return 0;
X 	}
+	cfg |= tmp << 3;
X 
-	if (devc->caps & ESSCAP_PNP) {
-		outb (0x07, devc->pcibase);		/* Selects logical device #1 */
-		outb (0x01, devc->pcibase + 1);
-		outb (0x28, devc->pcibase);
-		val = inb (devc->pcibase + 1) & 0xf0;
-		outb (0x28, devc->pcibase);		/* Sets MPU IRQ */
-		outb (hw_config->irq | val, devc->pcibase + 1);
-		if (hw_config->io_base) {
-			outb (0x64, devc->pcibase);		/* Sets MPU I/O address */
-			outb ((hw_config->io_base & 0xf00) >> 8, devc->pcibase + 1);
-			outb (0x65, devc->pcibase);		/* Sets MPU I/O address */
-			outb (hw_config->io_base & 0xfc, devc->pcibase + 1);
-		} else {
-			outb (0x64, devc->pcibase);		/* Read MPU I/O address */
-			hw_config->io_base = (inb (devc->pcibase + 1) & 0x0f) << 8;
-			outb (0x65, devc->pcibase);		/* Read MPU I/O address */
-			hw_config->io_base |= inb (devc->pcibase + 1) & 0xfc;
-		}
+	tmp = 1;		/* MPU enabled without interrupts */
X 
-		ess_setmixer (devc, 0x64, 0xc2);	/* Enable MPU interrupt */
-	} else {
-		if (devc->irq == hw_config->irq && (devc->caps & ESSCAP_IRQ)) {
-			val = 0x43;
-		}
-		else switch (hw_config->irq) {
-			case 11:
-				if (!(devc->caps & ESSCAP_IRQ)) {
-					return 0;
-				}
-				val = 0x63;
-				break;
-			case 2:
-			case 9:
-				val = 0x83;
-				break;
-			case 5:
-				val = 0xa3;
-				break;
-			case 7:
-				val = 0xc3;
-				break;
-			case 10:
-				val = 0xe3;
-				break;
-			default:
-				return 0;
-		}
-		switch (hw_config->io_base) {
-			case 0x300:
-			case 0x310:
-			case 0x320:
-			case 0x330:
-				ess_setmixer (devc, 0x40, val
-								| ((hw_config->io_base & 0x0f0) >> 1));
-				break;
-			default:
-				return 0;
-		}
+	/* May be shared: if so the value is -ve */
+
+	switch (abs(hw_config->irq)) {
+		case 9:
+			tmp = 0x4;
+			break;
+		case 5:
+			tmp = 0x5;
+			break;
+		case 7:
+			tmp = 0x6;
+			break;
+		case 10:
+			tmp = 0x7;
+			break;
+		default:
+			return 0;
X 	}
X 
-	if (devc->irq == hw_config->irq)	/* Shared IRQ */
-		hw_config->irq = -devc->irq;
+	cfg |= tmp << 5;
+	ess_setmixer (devc, 0x40, cfg | 0x03);
X 
X 	return 1;
X }
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/sb_mixer.c linux/drivers/sound/sb_mixer.c
--- v2.3.9/linux/drivers/sound/sb_mixer.c	Mon Apr 12 16:18:27 1999
+++ linux/drivers/sound/sb_mixer.c	Mon Jul  5 19:58:25 1999
@@ -13,6 +13,7 @@
X  *
X  * Thomas Sailer				: ioctl code reworked (vmalloc/vfree removed)
X  * Rolf Fokkens (Dec 20 1998)	: Moved ESS stuff into sb_ess.[ch]
+ * Stanislav Voronyi <st...@esc.kharkov.com>	: Support for AWE 3DSE device (Jun 7 1999)
X  */
X 
X #include <linux/config.h>
@@ -550,14 +551,37 @@
X 	int val, ret;
X 
X 	/*
-	 * Use ioctl(fd, SOUND_MIXER_PRIVATE1, &mode) to turn AGC off (0) or on (1).
+	 * Use ioctl(fd, SOUND_MIXER_AGC, &mode) to turn AGC off (0) or on (1).
+	 * Use ioctl(fd, SOUND_MIXER_3DSE, &mode) to turn 3DSE off (0) or on (1)
+	 *					      or mode==2 put 3DSE state to mode.
X 	 */
-	if (cmd == SOUND_MIXER_PRIVATE1 && devc->model == MDL_SB16) 
-	{
-		if (get_user(val, (int *)arg))
-			return -EFAULT;
-		sb_setmixer(devc, 0x43, (~val) & 0x01);
-		return 0;
+	if (devc->model == MDL_SB16) {
+		if (cmd == SOUND_MIXER_AGC) 
+		{
+			if (get_user(val, (int *)arg))
+				return -EFAULT;
+			sb_setmixer(devc, 0x43, (~val) & 0x01);
+			return 0;
+		}
+		if (cmd == SOUND_MIXER_3DSE) 
+		{
+			/* I put here 15, but I don't know the exact version.
+			   At least my 4.13 havn't 3DSE, 4.16 has it. */
+			if (devc->minor < 15)
+				return -EINVAL;
+			if (get_user(val, (int *)arg))
+				return -EFAULT;
+			if (val == 0 || val == 1)
+				sb_chgmixer(devc, AWE_3DSE, 0x01, val);
+			else if (val == 2)
+			{
+				ret = sb_getmixer(devc, AWE_3DSE)&0x01;
+				return put_user(ret, (int *)arg);
+			}
+			else
+				return -EINVAL;
+			return 0;
+		}
X 	}
X 	if (((cmd >> 8) & 0xff) == 'M') 
X 	{
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/sb_mixer.h linux/drivers/sound/sb_mixer.h
--- v2.3.9/linux/drivers/sound/sb_mixer.h	Thu Jan  7 09:24:00 1999
+++ linux/drivers/sound/sb_mixer.h	Mon Jul  5 19:58:25 1999
@@ -78,6 +78,11 @@
X #define RIGHT_CHN	1
X 
X /*
+ * 3DSE register of AWE32/64
+ */
+#define AWE_3DSE	0x90
+
+/*
X  * Mixer registers of ALS007
X  */
X #define ALS007_RECORD_SRC	0x6c
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/sgalaxy.c linux/drivers/sound/sgalaxy.c
--- v2.3.9/linux/drivers/sound/sgalaxy.c	Sun Nov  8 13:56:11 1998
+++ linux/drivers/sound/sgalaxy.c	Mon Jul  5 19:58:25 1999
@@ -2,7 +2,7 @@
X  * sound/sgalaxy.c
X  *
X  * Low level driver for Aztech Sound Galaxy cards.
- * Copyright 1998 Artur Skawina
+ * Copyright 1998 Artur Skawina <ska...@geocities.com>
X  *
X  * Supported cards:
X  *    Aztech Sound Galaxy Waverider Pro 32 - 3D
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c
--- v2.3.9/linux/drivers/sound/sonicvibes.c	Fri Jun 18 10:45:58 1999
+++ linux/drivers/sound/sonicvibes.c	Mon Jul  5 19:58:25 1999
@@ -2312,9 +2312,9 @@
X };
X 
X #ifdef MODULE
-__initfunc(int init_module(void))
+int __init init_module(void)
X #else
-__initfunc(int init_sonicvibes(void))
+int __init init_sonicvibes(void)
X #endif
X {
X 	struct sv_state *s;
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/sound_calls.h linux/drivers/sound/sound_calls.h
--- v2.3.9/linux/drivers/sound/sound_calls.h	Mon Jan  4 11:37:30 1999
+++ linux/drivers/sound/sound_calls.h	Mon Jul  5 19:58:25 1999
@@ -256,21 +256,39 @@
X void unload_trix_mpu(struct address_info *hw_info);
X void unload_cs4232(struct address_info *hw_info);
X void unload_cs4232_mpu(struct address_info *hw_info);
+void unload_opl3sa_wss(struct address_info *hw_info);
+void unload_opl3sa_sb(struct address_info *hw_info);
+void unload_opl3sa_mpu(struct address_info *hw_info);
X void unload_opl3sa2(struct address_info *hw_info);
X void unload_opl3sa2_mpu(struct address_info *hw_info);
+void unload_opl3sa2_mss(struct address_info *hw_info);
+void unload_softsyn (struct address_info *hw_config);
X 
-/* From cs4232.c */
-
+/*	From cs4232.c */
X int probe_cs4232 (struct address_info *hw_config);
X void attach_cs4232 (struct address_info *hw_config);
X int probe_cs4232_mpu (struct address_info *hw_config);
X void attach_cs4232_mpu (struct address_info *hw_config);
X 
-/* From opl3sa2.c */
+/*	From opl3sa.c */
+void attach_opl3sa_wss (struct address_info *hw_config);
+int probe_opl3sa_wss (struct address_info *hw_config);
+void attach_opl3sa_sb (struct address_info *hw_config);
+int probe_opl3sa_sb (struct address_info *hw_config);
+void attach_opl3sa_mpu (struct address_info *hw_config);
+int probe_opl3sa_mpu (struct address_info *hw_config);
+
+/*	From opl3sa2.c */
X int probe_opl3sa2 (struct address_info *hw_config);
X void attach_opl3sa2 (struct address_info *hw_config);
X int probe_opl3sa2_mpu (struct address_info *hw_config);
X void attach_opl3sa2_mpu (struct address_info *hw_config);
+int probe_opl3sa2_mss (struct address_info *hw_config);
+void attach_opl3sa2_mss (struct address_info *hw_config);
+
+/*	From softoss.c */
+void attach_softsyn_card (struct address_info *hw_config);
+int probe_softsyn (struct address_info *hw_config);
X 
X /*	From maui.c */
X void attach_maui(struct address_info * hw_config);
@@ -291,12 +309,12 @@
X int probe_waveartist(struct address_info *hw_config);
X void unload_waveartist(struct address_info *hw_config);
X 
-/*      From wavefront.c */
+/*	From wavefront.c */
X void attach_wavefront (struct address_info *hw_config);
X int probe_wavefront (struct address_info *hw_config);
X void unload_wavefront (struct address_info *hw_config);
X 
-/*      From wf_midi.c */
+/*	From wf_midi.c */
X void attach_wf_mpu(struct address_info * hw_config);
X int probe_wf_mpu(struct address_info *hw_config);
X void unload_wf_mpu(struct address_info *hw_config);
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/sound_syms.c linux/drivers/sound/sound_syms.c
--- v2.3.9/linux/drivers/sound/sound_syms.c	Mon Jan  4 11:37:30 1999
+++ linux/drivers/sound/sound_syms.c	Mon Jul  5 19:58:25 1999
@@ -3,6 +3,9 @@
X  *	modulespace.
X  *
X  *      (C) Copyright 1997      Alan Cox, Licensed under the GNU GPL
+ *
+ *	Thu May 27 1999 Andrew J. Kroll <ag784@freenet..buffalo..edu>
+ *	left out exported symbol... fixed
X  */
X 
X #include <linux/module.h>
@@ -43,6 +46,7 @@
X 
X EXPORT_SYMBOL(load_mixer_volumes);
X 
+EXPORT_SYMBOL(trace_init); /* oops! this is needed for maui.c -- AJK */
X 
X EXPORT_SYMBOL(conf_printf);
X EXPORT_SYMBOL(conf_printf2);
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/trix.c linux/drivers/sound/trix.c
--- v2.3.9/linux/drivers/sound/trix.c	Sun Mar  7 15:22:06 1999
+++ linux/drivers/sound/trix.c	Mon Jul  5 19:58:25 1999
@@ -42,6 +42,12 @@
X 
X static int mpu = 0;
X 
+#ifdef TRIX_JOYSTICK
+static int joystick=1;
+#else
+static int joystick=0;
+#endif
+
X static unsigned char trix_read(int addr)
X {
X 	outb(((unsigned char) addr), 0x390);	/* MT-0002-PC ASIC address */
@@ -196,9 +202,8 @@
X 
X 	if (ret)
X 	{
-#ifdef TRIX_ENABLE_JOYSTICK
-		trix_write(0x15, 0x80);
-#endif
+		if(joystick==1)
+			trix_write(0x15, 0x80);
X 		request_region(0x390, 2, "AudioTrix");
X 	}
X 	return ret;
@@ -477,7 +482,7 @@
X MODULE_PARM(sb_irq,"i");
X MODULE_PARM(mpu_io,"i");
X MODULE_PARM(mpu_irq,"i");
-
+MODULE_PARM(joystick, "i");
X struct address_info config;
X struct address_info sb_config;
X struct address_info mpu_config;
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/wavfront.c linux/drivers/sound/wavfront.c
--- v2.3.9/linux/drivers/sound/wavfront.c	Tue May 11 23:40:50 1999
+++ linux/drivers/sound/wavfront.c	Mon Jul  5 19:58:25 1999
@@ -2474,8 +2474,7 @@
X 	return (1);
X }
X 
-__initfunc (static int detect_wavefront (int irq, int io_base))
-
+static int __init detect_wavefront (int irq, int io_base)
X {
X 	unsigned char   rbuf[4], wbuf[4];
X 
@@ -2653,8 +2652,7 @@
X 	return 1;
X }
X 
-__initfunc (static int wavefront_config_midi (void)) 
-
+static int __init wavefront_config_midi (void)
X {
X 	unsigned char rbuf[4], wbuf[4];
X     
@@ -2728,7 +2726,6 @@
X 
X static int
X wavefront_do_reset (int atboot)
-
X {
X 	char voices[1];
X 
@@ -2832,7 +2829,6 @@
X 
X static int
X wavefront_init (int atboot)
-
X {
X 	int samples_are_from_rom;
X 
@@ -2861,7 +2857,7 @@
X 	return (0);
X }
X 
-__initfunc (static int install_wavefront (void))
+static int __init install_wavefront (void)
X 
X {
X 	if ((dev.synth_dev = register_sound_synth (&wavefront_fops, -1)) < 0) {
@@ -2919,7 +2915,7 @@
X #endif OSS_SUPPORT_SEQ
X 	uninstall_wf_mpu ();
X }
-
+
X /***********************************************************************/
X /*   WaveFront FX control                                              */
X /***********************************************************************/
@@ -2955,8 +2951,7 @@
X 	return (1);
X }
X 
-__initfunc (static int detect_wffx (void))
-
+static int __init detect_wffx (void)
X {
X 	/* This is a crude check, but its the best one I have for now.
X 	   Certainly on the Maui and the Tropez, wffx_idle() will
@@ -2972,8 +2967,7 @@
X 	return 0;
X }	
X 
-__initfunc (static int attach_wffx (void))
-
+static int __init attach_wffx (void)
X {
X 	if ((dev.fx_mididev = sound_alloc_mididev ()) < 0) {
X 		printk (KERN_WARNING LOGNAME "cannot install FX Midi driver\n");
diff -u --recursive --new-file v2.3.9/linux/drivers/sound/wf_midi.c linux/drivers/sound/wf_midi.c
--- v2.3.9/linux/drivers/sound/wf_midi.c	Thu Jan 14 22:59:47 1999
+++ linux/drivers/sound/wf_midi.c	Mon Jul  5 19:58:25 1999
@@ -803,7 +803,7 @@
X 	return 0;
X }
X 
-__initfunc (static int detect_wf_mpu (int irq, int io_base))
+static int __init detect_wf_mpu (int irq, int io_base)
X 
X {
X 	if (check_region (io_base, 2)) {
@@ -820,8 +820,7 @@
X 	return 0;
X }
X 
-__initfunc (int install_wf_mpu (void)) 
-
+int __init install_wf_mpu (void)
X {
X 	if ((phys_dev->devno = sound_alloc_mididev()) < 0){
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/usb/CREDITS linux/drivers/usb/CREDITS
--- v2.3.9/linux/drivers/usb/CREDITS	Tue Jun  8 10:52:26 1999
+++ linux/drivers/usb/CREDITS	Thu Jul  1 10:45:57 1999
@@ -29,7 +29,7 @@
X THANKS file in Inaky's driver):
X 
X         The following corporations have helped us in the development
-of Linux USB / UUSBD:
+        of Linux USB / UUSBD:
X 
X         - USAR Systems provided us with one of their excellent USB
X           Evaluation Kits. It allows us to test the Linux-USB driver
diff -u --recursive --new-file v2.3.9/linux/drivers/usb/hub.h linux/drivers/usb/hub.h
--- v2.3.9/linux/drivers/usb/hub.h	Wed Apr 21 05:41:59 1999
+++ linux/drivers/usb/hub.h	Thu Jul  8 15:19:55 1999
@@ -12,6 +12,7 @@
X /*
X  * Port feature numbers
X  */
+#define USB_PORT_FEAT_CONNECTION	0
X #define USB_PORT_FEAT_ENABLE		1
X #define USB_PORT_FEAT_SUSPEND		2
X #define USB_PORT_FEAT_OVER_CURRENT	3
@@ -40,7 +41,7 @@
X #define USB_PORT_STAT_C_OVERCURRENT	0x0008
X #define USB_PORT_STAT_C_RESET		0x0010
X 
-/* Characteristics */
+/* wHubCharacteristics (masks) */
X #define HUB_CHAR_LPSM		0x0003
X #define HUB_CHAR_COMPOUND	0x0004
X #define HUB_CHAR_OCPM		0x0018
diff -u --recursive --new-file v2.3.9/linux/drivers/usb/ohci-debug.c linux/drivers/usb/ohci-debug.c
--- v2.3.9/linux/drivers/usb/ohci-debug.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/usb/ohci-debug.c	Sat Jul  3 18:07:29 1999
@@ -119,10 +119,9 @@
X 		(td_toggle < 2) ? " " :
X 		(td_toggle & 1) ? "Data1" : "Data0",
X 		"ErrorCnt ", td_errcnt);
-	printk(KERN_DEBUG "        ComplCode 0x%x, %sAccessed, %sActive\n",
+	printk(KERN_DEBUG "        ComplCode 0x%x, %sAccessed\n",
X 		td_cc,
-		td_cc_accessed(*td) ? "" : "Not ",
-		td_active(*td) ? "" : "Not ");
+		td_cc_accessed(*td) ? "" : "Not ");
X 
X 	printk(KERN_DEBUG "        %s%s\n",
X 		td_allocated(*td) ? "Allocated" : "Free",
@@ -159,7 +158,7 @@
X 		if (td_dummy(*cur_td)) break;
X 	}
X 
-	printk(KERN_DEBUG "--- End  TD Chain %lx: ---\n", virt_to_bus(td));
+	printk(KERN_DEBUG "--- End  TD Chain %lx. ---\n", virt_to_bus(td));
X } /* show_ohci_td_chain () */
X 
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/usb/ohci.c linux/drivers/usb/ohci.c
--- v2.3.9/linux/drivers/usb/ohci.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/usb/ohci.c	Sat Jul  3 18:07:29 1999
@@ -179,27 +179,27 @@
X /* .......... */
X 
X 
-inline void ohci_start_control(struct ohci *ohci)
+void ohci_start_control(struct ohci *ohci)
X {
X 	/* tell the HC to start processing the control list */
X 	writel_set(OHCI_USB_CLE, &ohci->regs->control);
X 	writel_set(OHCI_CMDSTAT_CLF, &ohci->regs->cmdstatus);
X }
X 
-inline void ohci_start_bulk(struct ohci *ohci)
+void ohci_start_bulk(struct ohci *ohci)
X {
X 	/* tell the HC to start processing the bulk list */
X 	writel_set(OHCI_USB_BLE, &ohci->regs->control);
X 	writel_set(OHCI_CMDSTAT_BLF, &ohci->regs->cmdstatus);
X }
X 
-inline void ohci_start_periodic(struct ohci *ohci)
+void ohci_start_periodic(struct ohci *ohci)
X {
X 	/* enable processing periodic (intr) transfers starting next frame */
X 	writel_set(OHCI_USB_PLE, &ohci->regs->control);
X }
X 
-inline void ohci_start_isoc(struct ohci *ohci)
+void ohci_start_isoc(struct ohci *ohci)
X {
X 	/* enable processing isoc. transfers starting next frame */
X 	writel_set(OHCI_USB_IE, &ohci->regs->control);
@@ -658,7 +658,7 @@
X  * 	dir = OHCI_TD_D_IN, OHCI_TD_D_OUT, or OHCI_TD_D_SETUP
X  * 	toggle = TOGGLE_AUTO, TOGGLE_DATA0, TOGGLE_DATA1
X  */
-inline struct ohci_td *ohci_fill_new_td(struct ohci_td *td, int dir, int toggle, __u32 flags, void *data, __u32 len, void *dev_id, usb_device_irq completed)
+struct ohci_td *ohci_fill_new_td(struct ohci_td *td, int dir, int toggle, __u32 flags, void *data, __u32 len, void *dev_id, usb_device_irq completed)
X {
X 	/* hardware fields */
X 	td->info = cpu_to_le32(OHCI_TD_CC_NEW |
@@ -846,16 +846,20 @@
X 		return 0;
X 
X 	/* if cur_buf is 0, all data has been transferred */
-	bus_data_end = td->cur_buf ? td->cur_buf : td->buf_end;
+	if (!td->cur_buf) {
+		return td->buf_end - bus_data_start + 1;
+	}
+
+	bus_data_end = td->cur_buf;
X 
X 	/* is it on the same page? */
X 	if ((bus_data_start & ~0xfff) == (bus_data_end & ~0xfff)) {
-		result = bus_data_end - bus_data_start + 1;
+		result = bus_data_end - bus_data_start;
X 	} else {
X 		/* compute the amount transferred on the first page */
X 		result = 0x1000 - (bus_data_start & 0xfff);
X 		/* add the amount done in the second page */
-		result += (bus_data_end & 0xfff) + 1;
+		result += (bus_data_end & 0xfff);
X 	}
X 
X 	return result;
@@ -1190,16 +1194,12 @@
X 	if (stats == USB_ST_NOERROR)
X 		req->_bytes_done += len;
X 
-#ifdef OHCI_DEBUG
-	printk(KERN_DEBUG "ohci_bulk_td_handler %d bytes done\n", req->_bytes_done);
-#endif
-
X 	/* call the real completion handler when done or on an error */
X 	if ((stats != USB_ST_NOERROR) ||
X 	    (req->_bytes_done >= req->length && req->completion != NULL)) {
X 		*req->bytes_transferred_p += req->_bytes_done;
X #ifdef OHCI_DEBUG
-		printk(KERN_DEBUG "usb-ohci: bulk request %p ending after %d bytes\n", req, req->_bytes_done);
+		printk(KERN_DEBUG "usb-ohci: bulk request %p ending\n", req);
X #endif
X 		req->completion(stats, buffer, req->_bytes_done, req->dev_id);
X 	}
@@ -1282,13 +1282,13 @@
X 
X 
X #ifdef OHCI_DEBUG
-/*	if (MegaDebug) { */
-	/* complete transaction debugging output (before) */
+	if (MegaDebug) {
+	/* complete request debugging output (before) */
X 	printk(KERN_DEBUG " Bulk ED %lx:\n", virt_to_bus(bulk_ed));
X 	show_ohci_ed(bulk_ed);
X 	printk(KERN_DEBUG " Bulk TDs %lx:\n", virt_to_bus(head_td));
X 	show_ohci_td_chain(head_td);
-/*	} */
+	}
X #endif
X 
X 	/* Give the ED to the HC */
@@ -1303,6 +1303,9 @@
X 
X static int ohci_bulk_msg_completed(int stats, void *buffer, int len, void *dev_id)
X {
+#ifdef OHCI_DEBUG
+	printk("ohci_bulk_msg_completed %x, %p, %d, %p\n", stats, buffer, len, dev_id);
+#endif
X 	if (dev_id != NULL) {
X 		int *completion_status = (int *)dev_id;
X 		*completion_status = stats;
@@ -1320,12 +1323,15 @@
X 	struct ohci_bulk_request_state req;
X 	struct ohci_ed *req_ed;
X 
-	/* ....... */
-
X #ifdef OHCI_DEBUG 
X 	printk(KERN_DEBUG "ohci_bulk_msg %p pipe %x, data %p, len %d, bytes_transferred %p\n", usb_dev, pipe, data, len, bytes_transferred_p);
X #endif
X 
+	/* initialize bytes transferred to nothing */
+	*bytes_transferred_p = 0;
+
+	/* Hopefully this is similar to the "URP" (USB Request Packet) code
+	 * that michael gee is working on... */
X 	req.usb_dev = usb_dev;
X 	req.pipe = pipe;
X 	req.data = data;
@@ -1345,9 +1351,44 @@
X 	/* FIXME this should to wait for a caller specified time... */
X 	schedule_timeout(HZ*5);
X 
+	/* it'll only stay in this state of the request never finished */
+	if (completion_status == USB_ST_INTERNALERROR) {
+		struct ohci_device *dev = usb_to_ohci(usb_dev);
+		struct ohci_regs *regs = dev->ohci->regs;
+
X #ifdef OHCI_DEBUG
-	printk(KERN_DEBUG "ohci_bulk_msg request completed or timed out w/ status %x\n", completion_status);
+		printk(KERN_DEBUG "ohci_bulk_msg timing out\n");
X #endif
+		/* XXX This code should go into a function used to stop
+		 * a previously requested bulk transfer. -greg */
+
+		/* stop the transfer & collect the number of bytes */
+		ohci_wait_for_ed_safe(regs, req_ed, HCD_ED_BULK);
+
+		/* Get the number of bytes transferred out of the head TD
+		 * on the ED if it didn't finish while we were waiting. */
+		if ( ed_head_td(req_ed) &&
+		     (ed_head_td(req_ed) != ed_tail_td(req_ed)) ) {
+			struct ohci_td *partial_td;
+			partial_td = bus_to_virt(ed_head_td(req_ed));
+
+#ifdef OHCI_DEBUG
+			if (MegaDebug) {
+			show_ohci_td(partial_td);
+			}
+#endif
+			/* Record the bytes as transferred */
+			*bytes_transferred_p += ohci_td_bytes_done(partial_td);
+			
+			/* If there was an unreported error, return it.
+			 * Otherwise return a timeout */
+			completion_status = OHCI_TD_CC_GET(partial_td->info);
+			if (completion_status == USB_ST_NOERROR) {
+				completion_status = USB_ST_TIMEOUT;
+			}
+		}
+
+	}
X 
X 	remove_wait_queue(&bulk_wakeup, &wait);
X 
@@ -1356,7 +1397,7 @@
X 	ohci_free_ed(req_ed);	 /* return it to the pool */
X 
X #ifdef OHCI_DEBUG
-	printk(KERN_DEBUG "ohci_bulk_msg done.\n");
+	printk(KERN_DEBUG "ohci_bulk_msg done, status %x (bytes_transferred = %ld).\n", completion_status, *bytes_transferred_p);
X #endif
X 
X 	return completion_status;
@@ -1761,7 +1802,7 @@
X 	struct ohci_td *td;		/* used for walking the list */
X 
X 	/* um... isn't this dangerous to do in an interrupt handler? -greg */
-	spin_lock(&ohci_edtd_lock);
+//	spin_lock(&ohci_edtd_lock);
X 
X 	/* create the FIFO ordered donelist */
X 	td = ohci_reverse_donelist(ohci);
@@ -1832,6 +1873,7 @@
X 
X 			/* insert it back on its ED */
X 			ohci_add_td_to_ed(td, td, td->ed);
+			ohci_unhalt_ed(td->ed);
X 		} else {
X 			/* return it to the pool of free TDs */
X 			if (can_auto_free(*td))
@@ -1841,7 +1883,7 @@
X 		td = next_td;
X 	}
X 
-	spin_unlock(&ohci_edtd_lock);
+//	spin_unlock(&ohci_edtd_lock);
X } /* ohci_reap_donelist() */
X 
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/usb/ohci.h linux/drivers/usb/ohci.h
--- v2.3.9/linux/drivers/usb/ohci.h	Wed Jun 30 13:38:20 1999
+++ linux/drivers/usb/ohci.h	Sat Jul  3 18:07:29 1999
@@ -71,7 +71,6 @@
X #define td_cc_notaccessed(td)	((le32_to_cpup(&(td).info) >> 29) == 7)
X #define td_cc_accessed(td)	((le32_to_cpup(&(td).info) >> 29) != 7)
X #define td_cc_noerror(td)	(((le32_to_cpup(&(td).info)) & OHCI_TD_CC) == 0)
-#define td_active(td)	(!td_cc_noerror((td)) && (td_errorcount((td)) < 3))
X #define td_done(td)	(td_cc_noerror((td)) || (td_errorcount((td)) == 3))
X 
X /*
diff -u --recursive --new-file v2.3.9/linux/drivers/usb/printer.c linux/drivers/usb/printer.c
--- v2.3.9/linux/drivers/usb/printer.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/usb/printer.c	Thu Jul  8 15:19:55 1999
@@ -124,6 +124,7 @@
X 		return -EBUSY;
X 	}
X 	if (!(p->obuf = (char *)__get_free_page(GFP_KERNEL))) {
+		p->isopen = 0;
X 		return -ENOMEM;
X 	}
X 
@@ -166,7 +167,6 @@
X 	do {
X 		char *obuf = p->obuf;
X 		unsigned long thistime;
-		partial = 0;
X 
X 		thistime = copy_size = (count > p->maxout) ? p->maxout : count;
X 		if (copy_from_user(p->obuf, buffer, copy_size))
@@ -303,7 +303,11 @@
X 	minor_data[i] = PPDATA(dev->private);
X 	minor_data[i]->minor = i;
X 	minor_data[i]->pusb_dev = dev;
-	minor_data[i]->maxout = interface->endpoint[0].wMaxPacketSize * 16;
+	/* The max packet size can't be more than 64 (& will be 64 for
+	 * any decent bulk device); this calculation was silly.  -greg
+	 * minor_data[i]->maxout = interface->endpoint[0].wMaxPacketSize * 16;
+	 */
+	minor_data[i]->maxout = 8192;
X 	if (minor_data[i]->maxout > PAGE_SIZE) {
X                 minor_data[i]->maxout = PAGE_SIZE;
X 	}
diff -u --recursive --new-file v2.3.9/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c
--- v2.3.9/linux/drivers/usb/uhci.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/usb/uhci.c	Thu Jul  8 15:19:55 1999
@@ -32,14 +32,9 @@
X #include <linux/malloc.h>
X #include <linux/smp_lock.h>
X #include <linux/errno.h>
-
-#include <linux/sched.h>
X #include <linux/unistd.h>
-#include <linux/smp_lock.h>
X 
X #include <asm/uaccess.h>
-
-
X #include <asm/spinlock.h>
X #include <asm/io.h>
X #include <asm/irq.h>
@@ -70,7 +65,7 @@
X     	    return USB_ST_BITSTUFF;
X     if (status & 0x04)	{			/* CRC/Timeout */
X 	if (dir_out)
-    	    return USB_ST_TIMEOUT;
+    	    return USB_ST_NORESPONSE;
X 	else
X 	    return USB_ST_CRC;
X     }
@@ -104,7 +99,7 @@
X 		if (status) {
X 			/* must reset the toggle on first error */
X     			if (uhci_debug) {
-			    printk("Set toggle from %x rval %d\n", (unsigned int)tmp, rval ? *rval : 0);
+			    printk("Set toggle from %x rval %ld\n", (unsigned int)tmp, rval ? *rval : 0);
X 			}
X 			usb_settoggle(dev->usb, usb_pipeendpoint(tmp->info), usb_pipeout(tmp->info), (tmp->info >> 19) & 1);
X 			break;
@@ -1442,10 +1437,12 @@
X 
X 	/* We need exactly one page (per UHCI specs), how convenient */
X 	uhci->fl = (void *)__get_free_page(GFP_KERNEL);
+	if (!uhci->fl)
+		goto au_free_uhci;
X 
X 	bus = kmalloc(sizeof(*bus), GFP_KERNEL);
X 	if (!bus)
-		return NULL;
+		goto au_free_fl;
X 
X 	memset(bus, 0, sizeof(*bus));
X 
@@ -1465,7 +1462,7 @@
X 	 */
X 	usb = uhci_usb_allocate(NULL);
X 	if (!usb)
-		return NULL;
+		goto au_free_bus;
X 
X 	usb->bus = bus;
X 	dev = usb_to_uhci(usb);
@@ -1536,6 +1533,18 @@
X 	}
X 
X 	return uhci;
+
+/*
+ * error exits:
+ */
+
+au_free_bus:
+	kfree (bus);
+au_free_fl:
+	free_page ((unsigned long)uhci->fl);
+au_free_uhci:
+	kfree (uhci);
+	return NULL;
X }
X 
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/usb/uhci.h linux/drivers/usb/uhci.h
--- v2.3.9/linux/drivers/usb/uhci.h	Tue Jun 22 14:42:27 1999
+++ linux/drivers/usb/uhci.h	Thu Jul  8 15:31:47 1999
@@ -167,12 +167,12 @@
X  * Linus:
X  *
X  *  generic-iso-QH  ->  dev1-iso-QH  ->  generic-irq-QH  ->  dev1-irq-QH  -> ...
- *       |                       |                  |                   |
- *      End          dev1-iso-TD1          End            dev1-irq-TD1
- *                       |
- *                   dev1-iso-TD2
- *                       |
- *                      ....
+ *       |                  |                  |                   |
+ *      End             dev1-iso-TD1          End            dev1-irq-TD1
+ *                          |
+ *                      dev1-iso-TD2
+ *                          |
+ *                        ....
X  *
X  * This may vary a bit (the UHCI docs don't explicitly say you can put iso
X  * transfers in QH's and all of their pictures don't have that either) but
diff -u --recursive --new-file v2.3.9/linux/drivers/usb/usb.c linux/drivers/usb/usb.c
--- v2.3.9/linux/drivers/usb/usb.c	Wed Jun 30 13:38:20 1999
+++ linux/drivers/usb/usb.c	Thu Jul  8 15:31:47 1999
@@ -260,7 +260,7 @@
X 
X static int usb_parse_endpoint(struct usb_device *dev, struct usb_endpoint_descriptor *endpoint, unsigned char *ptr, int len)
X {
-	int parsed = usb_expect_descriptor(ptr, len, USB_DT_ENDPOINT, 7);
+	int parsed = usb_expect_descriptor(ptr, len, USB_DT_ENDPOINT, USB_DT_ENDPOINT_SIZE);
X 	int i;
X 
X 	if (parsed < 0)
@@ -284,7 +284,7 @@
X static int usb_parse_interface(struct usb_device *dev, struct usb_interface_descriptor *interface, unsigned char *ptr, int len)
X {
X 	int i;
-	int parsed = usb_expect_descriptor(ptr, len, USB_DT_INTERFACE, 9);
+	int parsed = usb_expect_descriptor(ptr, len, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE);
X 	int retval;
X 
X 	if (parsed < 0)
@@ -848,29 +848,40 @@
X int usb_get_configuration(struct usb_device *dev)
X {
X 	unsigned int cfgno;
-	unsigned char buffer[400];
X 	unsigned char * bufptr;
-	
+	unsigned char * buffer;
+	int parse;
+
+	buffer = (unsigned char *) __get_free_page (GFP_KERNEL);
+	if (!buffer)
+		return -1;
+
X 	bufptr = buffer;
X 	for (cfgno = 0 ; cfgno < dev->descriptor.bNumConfigurations ; cfgno++) {
X 		unsigned int size;
X   		/* Get the first 8 bytes - guaranteed */
-	  	if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, 8))
+	  	if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, 8)) {
+			__free_page ((struct page *) buffer);
X 	    		return -1;
+		}
X 
X   	  	/* Get the full buffer */
X 	  	size = le16_to_cpup((unsigned short *)(bufptr+2));
-	  	if (bufptr+size > buffer+sizeof(buffer)) {
+	  	if (bufptr+size > buffer+PAGE_SIZE) {
X 			printk(KERN_INFO "usb: truncated DT_CONFIG (want %d).\n", size);
-			size = buffer+sizeof(buffer)-bufptr;
+			size = buffer+PAGE_SIZE-bufptr;
X 		}
-		if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, size))
+		if (usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bufptr, size)) {
+			__free_page ((struct page *) buffer);
X 			return -1;
+		}
X 			
X 		/* Prepare for next configuration */
X 		bufptr += size;
X 	}
-	return usb_parse_configuration(dev, buffer, bufptr - buffer);
+	parse = usb_parse_configuration(dev, buffer, bufptr - buffer);
+	__free_page ((struct page *) buffer);
+	return parse;
X }
X 
X int usb_get_stringtable(struct usb_device *dev)
diff -u --recursive --new-file v2.3.9/linux/drivers/usb/usb.h linux/drivers/usb/usb.h
--- v2.3.9/linux/drivers/usb/usb.h	Wed Jun 30 13:38:20 1999
+++ linux/drivers/usb/usb.h	Thu Jul  8 15:31:47 1999
@@ -31,9 +31,16 @@
X } devrequest;
X 
X /*
- * Class codes
+ * Device and/or Interface Class codes
X  */
+#define USB_CLASS_PER_INTERFACE		0	/* for DeviceClass */
+#define USB_CLASS_AUDIO			1
+#define USB_CLASS_COMM			2
+#define USB_CLASS_HID			3
+#define USB_CLASS_PRINTER		7
+#define USB_CLASS_MASS_STORAGE		8
X #define USB_CLASS_HUB			9
+#define USB_CLASS_VENDOR_SPEC		0xff
X 
X /*
X  * Descriptor types
@@ -48,6 +55,28 @@
X #define USB_DT_HID			0x21
X 
X /*
+ * Descriptor sizes per descriptor type
+ */
+#define USB_DT_DEVICE_SIZE		18
+#define USB_DT_CONFIG_SIZE		9
+#define USB_DT_INTERFACE_SIZE		9
+#define USB_DT_ENDPOINT_SIZE		7
+#define USB_DT_HUB_NONVAR_SIZE		7
+
+/*
+ * USB Request Type and Endpoint Directions
+ */
+#define USB_DIR_OUT			0
+#define USB_DIR_IN			0x80
+
+/*
+ * USB Packet IDs (PIDs)
+ */
+#define USB_PID_OUT			0xe1
+#define USB_PID_IN			0x69
+#define USB_PID_SETUP			0x2d
+
+/*
X  * Standard requests
X  */
X #define USB_REQ_GET_STATUS		0x00
@@ -97,16 +126,16 @@
X #define USB_RT_HIDD			(USB_TYPE_CLASS | USB_RECIP_INTERFACE)
X 
X /* 
- * Status codes 
+ * Status codes (these follow an OHCI controllers condition codes)
X  */
X #define USB_ST_NOERROR		0x0
X #define USB_ST_CRC		0x1
X #define USB_ST_BITSTUFF		0x2
-#define USB_ST_DTMISMATCH	0x3
+#define USB_ST_DTMISMATCH	0x3	/* data toggle mismatch */
X #define USB_ST_STALL		0x4
-#define USB_ST_TIMEOUT		0x5
-#define USB_ST_PIDCHECK		0x6
-#define USB_ST_PIDUNDEF		0x7
+#define USB_ST_NORESPONSE	0x5	/* device not responding/handshaking */
+#define USB_ST_PIDCHECK		0x6	/* Check bits on PID failed */
+#define USB_ST_PIDUNDEF		0x7	/* PID unexpected/undefined */
X #define USB_ST_DATAOVERRUN	0x8
X #define USB_ST_DATAUNDERRUN	0x9
X #define USB_ST_RESERVED1	0xA
@@ -118,6 +147,7 @@
X 
X /* internal errors */
X #define USB_ST_REMOVED		0x100
+#define USB_ST_TIMEOUT		0x110
X #define USB_ST_INTERNALERROR	-1
X 
X /*
@@ -275,7 +305,7 @@
X struct usb_device {
X 	int devnum;			/* Device number on USB bus */
X 	int slow;			/* Slow device? */
-	int maxpacketsize;		/* Maximum packet size */
+	int maxpacketsize;		/* Maximum packet size; encoded as 0,1,2,3 = 8,16,32,64 */
X 	int toggle[2];			/* one bit for each endpoint ([0] = IN, [1] = OUT) */
X 	int halted;			/* endpoint halts */
X 	struct usb_config_descriptor *actconfig;/* the active configuration */
@@ -342,16 +372,16 @@
X  * Let's not fall in that trap. We'll just encode it as a simple
X  * unsigned int. The encoding is:
X  *
+ *  - max size:		bits 0-1	(00 = 8, 01 = 16, 10 = 32, 11 = 64)
+ *  - direction:	bit 7		(0 = Host-to-Device, 1 = Device-to-Host)
X  *  - device:		bits 8-14
X  *  - endpoint:		bits 15-18
X  *  - 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)
+ *  - speed:		bit 26		(00 = Full, 01 = Low Speed)
X  *  - pipe type:	bits 30-31	(00 = isochronous, 01 = interrupt, 10 = control, 11 = bulk)
X  *
X  * 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
+ * up to us. This one happens to share a lot of bit positions with the UHCI
X  * specification, so that much of the uhci driver can just mask the bits
X  * appropriately.
X  */
@@ -372,6 +402,7 @@
X #define usb_pipebulk(pipe)	(usb_pipetype((pipe)) == 3)
X 
X #define usb_pipe_endpdev(pipe)	(((pipe) >> 8) & 0x7ff)
+#define PIPE_DEVEP_MASK		0x0007ff00
X 
X /* The D0/D1 toggle bits */
X #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> ep) & 1)
@@ -393,7 +424,7 @@
X 	return (dev->slow << 26);
X }
X 
-/* Create control pipes.. */
+/* Create various pipes... */
X #define usb_sndctrlpipe(dev,endpoint)	((2 << 30) | __create_pipe(dev,endpoint))
X #define usb_rcvctrlpipe(dev,endpoint)	((2 << 30) | __create_pipe(dev,endpoint) | 0x80)
X #define usb_sndisocpipe(dev,endpoint)	((0 << 30) | __create_pipe(dev,endpoint))
diff -u --recursive --new-file v2.3.9/linux/drivers/video/Makefile linux/drivers/video/Makefile
--- v2.3.9/linux/drivers/video/Makefile	Wed Jun 30 13:38:20 1999
+++ linux/drivers/video/Makefile	Thu Jul  1 10:57:36 1999
@@ -192,9 +192,11 @@
X 
X ifeq ($(CONFIG_FB_TGA),y)
X L_OBJS += tgafb.o
+CONFIG_FBGEN_BUILTIN = y
X else
X   ifeq ($(CONFIG_FB_TGA),m)
X   M_OBJS += tgafb.o
+  CONFIG_FBGEN_MODULE = y
X   endif
X endif
X 
diff -u --recursive --new-file v2.3.9/linux/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- v2.3.9/linux/drivers/video/fbmem.c	Thu May 13 23:48:20 1999
+++ linux/drivers/video/fbmem.c	Thu Jul  1 10:57:36 1999
@@ -74,6 +74,7 @@
X extern void imsttfb_setup(char *options, int *ints);
X extern void dnfb_init(void);
X extern void tgafb_init(void);
+extern void tgafb_setup(char *options, int *ints);
X extern void virgefb_init(void);
X extern void virgefb_setup(char *options, int *ints);
X extern void resolver_video_setup(char *options, int *ints);
@@ -158,7 +159,7 @@
X 	{ "s3trio", s3triofb_init, s3triofb_setup },
X #endif 
X #ifdef CONFIG_FB_TGA
-	{ "tga", tgafb_init, NULL },
+	{ "tga", tgafb_init, tgafb_setup },
X #endif
X #ifdef CONFIG_FB_VIRGE
X 	{ "virge", virgefb_init, virgefb_setup },
diff -u --recursive --new-file v2.3.9/linux/drivers/video/tgafb.c linux/drivers/video/tgafb.c
--- v2.3.9/linux/drivers/video/tgafb.c	Mon Dec 21 14:48:04 1998
+++ linux/drivers/video/tgafb.c	Thu Jul  1 10:57:36 1999
@@ -1,27 +1,29 @@
X /*
X  *  linux/drivers/video/tgafb.c -- DEC 21030 TGA frame buffer device
X  *
- *	Copyright (C) 1997 Geert Uytterhoeven
+ *	Copyright (C) 1999 Martin Lucina, Tom Zerucha
+ *  
+ *  $Id: tgafb.c,v 1.12 1999/07/01 13:39:23 mato Exp $
X  *
- *  This driver is partly based on the original TGA console driver
+ *  This driver is partly based on the original TGA framebuffer device, which 
+ *  was partly based on the original TGA console driver, which are
X  *
- *	Copyright (C) 1995  Jay Estabrook
+ *	Copyright (C) 1997 Geert Uytterhoeven
+ *	Copyright (C) 1995 Jay Estabrook
X  *
X  *  This file is subject to the terms and conditions of the GNU General Public
X  *  License. See the file COPYING in the main directory of this archive for
X  *  more details.
X  */
X 
-
X /* KNOWN PROBLEMS/TO DO ===================================================== *
X  *
X  *	- How to set a single color register on 24-plane cards?
X  *
- *	- Hardware cursor (useful for other graphics boards too)
- *
- *	- Support for more resolutions
+ *	- Hardware cursor/other text acceleration methods
X  *
X  *	- Some redraws can stall kernel for several seconds
+ *	  [This should now be solved by the fast memmove() patch in 2.3.6]
X  *
X  * KNOWN PROBLEMS/TO DO ==================================================== */
X 
@@ -45,477 +47,459 @@
X #include <video/fbcon.h>
X #include <video/fbcon-cfb8.h>
X #include <video/fbcon-cfb32.h>
+#include "tgafb.h"
X 
X 
-/* TGA hardware description (minimal) */
-/*
- * Offsets within Memory Space
- */
-#define	TGA_ROM_OFFSET			0x0000000
-#define	TGA_REGS_OFFSET			0x0100000
-#define	TGA_8PLANE_FB_OFFSET		0x0200000
-#define	TGA_24PLANE_FB_OFFSET		0x0804000
-#define	TGA_24PLUSZ_FB_OFFSET		0x1004000
-
-#define	TGA_PLANEMASK_REG		0x0028
-#define	TGA_MODE_REG			0x0030
-#define	TGA_RASTEROP_REG		0x0034
-#define	TGA_DEEP_REG			0x0050
-#define	TGA_PIXELMASK_REG		0x005c
-#define	TGA_CURSOR_BASE_REG		0x0060
-#define	TGA_HORIZ_REG			0x0064
-#define	TGA_VERT_REG			0x0068
-#define	TGA_BASE_ADDR_REG		0x006c
-#define	TGA_VALID_REG			0x0070
-#define	TGA_CURSOR_XY_REG		0x0074
-#define	TGA_INTR_STAT_REG		0x007c
-#define	TGA_RAMDAC_SETUP_REG		0x00c0
-#define	TGA_BLOCK_COLOR0_REG		0x0140
-#define	TGA_BLOCK_COLOR1_REG		0x0144
-#define	TGA_CLOCK_REG			0x01e8
-#define	TGA_RAMDAC_REG			0x01f0
-#define	TGA_CMD_STAT_REG		0x01f8
-
-/*
- * useful defines for managing the BT485 on the 8-plane TGA
- */
-#define	BT485_READ_BIT			0x01
-#define	BT485_WRITE_BIT			0x00
-
-#define	BT485_ADDR_PAL_WRITE		0x00
-#define	BT485_DATA_PAL			0x02
-#define	BT485_PIXEL_MASK		0x04
-#define	BT485_ADDR_PAL_READ		0x06
-#define	BT485_ADDR_CUR_WRITE		0x08
-#define	BT485_DATA_CUR			0x0a
-#define	BT485_CMD_0			0x0c
-#define	BT485_ADDR_CUR_READ		0x0e
-#define	BT485_CMD_1			0x10
-#define	BT485_CMD_2			0x12
-#define	BT485_STATUS			0x14
-#define	BT485_CMD_3			0x14
-#define	BT485_CUR_RAM			0x16
-#define	BT485_CUR_LOW_X			0x18
-#define	BT485_CUR_HIGH_X		0x1a
-#define	BT485_CUR_LOW_Y			0x1c
-#define	BT485_CUR_HIGH_Y		0x1e
-
-/*
- * useful defines for managing the BT463 on the 24-plane TGAs
- */
-#define	BT463_ADDR_LO		0x0
-#define	BT463_ADDR_HI		0x1
-#define	BT463_REG_ACC		0x2
-#define	BT463_PALETTE		0x3
+    /*
+     *  Global declarations
+     */
X 
-#define	BT463_CUR_CLR_0		0x0100
-#define	BT463_CUR_CLR_1		0x0101
+static struct tgafb_info fb_info;
+static struct tgafb_par current_par;
+static int current_par_valid = 0;
+static struct display disp;
X 
-#define	BT463_CMD_REG_0		0x0201
-#define	BT463_CMD_REG_1		0x0202
-#define	BT463_CMD_REG_2		0x0203
+static char __initdata default_fontname[40] = { 0 };
+static struct fb_var_screeninfo default_var;
+static int default_var_valid = 0;
X 
-#define	BT463_READ_MASK_0	0x0205
-#define	BT463_READ_MASK_1	0x0206
-#define	BT463_READ_MASK_2	0x0207
-#define	BT463_READ_MASK_3	0x0208
+static int currcon = 0;
X 
-#define	BT463_BLINK_MASK_0	0x0209
-#define	BT463_BLINK_MASK_1	0x020a
-#define	BT463_BLINK_MASK_2	0x020b
-#define	BT463_BLINK_MASK_3	0x020c
+#define arraysize(x)	(sizeof(x)/sizeof(*(x)))
X 
-#define	BT463_WINDOW_TYPE_BASE	0x0300
+static struct { u_char red, green, blue, pad; } palette[256];
+#ifdef FBCON_HAS_CFB32
+static u32 fbcon_cfb32_cmap[16];
+#endif
X 
X 
-int tga_type;
-unsigned int tga_mem_base;
-unsigned long tga_fb_base;
-unsigned long tga_regs_base;
+    /*
+     *  Hardware presets
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 28'
echo 'File patch-2.3.10 is continued in part 29'
echo 29 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 32 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 32; 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
+extern ssize_t parport_read (struct parport *, void *buf, size_t len);
+extern long parport_set_timeout (struct pardevice *, long inactivity);
+extern int parport_wait_event (struct parport *, long timeout);
+extern int parport_wait_peripheral (struct parport *port,
+				    unsigned char mask,
+				    unsigned char val);
+
+/* For architectural drivers */
+extern void parport_ieee1284_wakeup (struct parport *port);
+extern size_t parport_ieee1284_write_compat (struct parport *,
+					     const void *, size_t, int);
+extern size_t parport_ieee1284_read_nibble (struct parport *,
+					    void *, size_t, int);
+extern size_t parport_ieee1284_read_byte (struct parport *,
+					  void *, size_t, int);
+extern size_t parport_ieee1284_ecp_read_data (struct parport *,
+					      void *, size_t, int);
+extern size_t parport_ieee1284_ecp_write_data (struct parport *,
+					       const void *, size_t, int);
+extern size_t parport_ieee1284_ecp_write_addr (struct parport *,
+					       const void *, size_t, int);
+extern size_t parport_ieee1284_epp_write_data (struct parport *,
+					       const void *, size_t, int);
+extern size_t parport_ieee1284_epp_read_data (struct parport *,
+					      void *, size_t, int);
+extern size_t parport_ieee1284_epp_write_addr (struct parport *,
+					       const void *, size_t, int);
+extern size_t parport_ieee1284_epp_read_addr (struct parport *,
+					      void *, size_t, int);
+
+/* IEEE1284.3 functions */
+extern int parport_daisy_init (struct parport *port);
+extern void parport_daisy_fini (struct parport *port);
+extern struct pardevice *parport_open (int devnum, const char *name,
+				       int (*pf) (void *),
+ void (*kf) (void *),
+				       void (*irqf) (int, void *,
+						     struct pt_regs *),
+				       int flags, void *handle);
+extern void parport_close (struct pardevice *dev);
+extern ssize_t parport_device_id (int devnum, char *buffer, size_t len);
+extern int parport_device_num (int parport, int mux, int daisy);
+extern int parport_device_coords (int devnum, int *parport, int *mux,
+				  int *daisy);
+extern void parport_daisy_deselect_all (struct parport *port);
+extern int parport_daisy_select (struct parport *port, int daisy, int mode);
+
+/* For finding devices based on their device ID.  Example usage:
+   int devnum = -1;
+   while ((devnum = parport_find_class (PARPORT_CLASS_DIGCAM, devnum)) != -1) {
+       struct pardevice *dev = parport_open (devnum, ...);
+       ...
+   }
+*/
+extern int parport_find_device (const char *mfg, const char *mdl, int from);
+extern int parport_find_class (parport_device_class cls, int from);
+
+/* Lowlevel drivers _can_ call this support function to handle irqs.  */
+extern __inline__ void parport_generic_irq(int irq, struct parport *port,
+					   struct pt_regs *regs)
+{
+	parport_ieee1284_interrupt (irq, port, regs);
+	read_lock(&port->cad_lock);
+	if (port->cad && port->cad->irq_func)
+		port->cad->irq_func(irq, port->cad->private, regs);
+	read_unlock(&port->cad_lock);
+}
X 
X /* Prototypes from parport_procfs */
X extern int parport_proc_register(struct parport *pp);
@@ -354,12 +483,8 @@
X extern void dec_parport_count(void);
X extern void inc_parport_count(void);
X 
-extern int parport_probe(struct parport *port, char *buffer, int len);
-extern void parport_probe_one(struct parport *port);
-extern void (*parport_probe_hook)(struct parport *port);
-
X /* If PC hardware is the only type supported, we can optimise a bit.  */
-#if (defined(CONFIG_PARPORT_PC) || defined(CONFIG_PARPORT_PC_MODULE)) && !(defined(CONFIG_PARPORT_AX) || defined(CONFIG_PARPORT_AX_MODULE)) && !(defined(CONFIG_PARPORT_ARC) || defined(CONFIG_PARPORT_ARC_MODULE)) && !defined(CONFIG_PARPORT_OTHER)
+#if (defined(CONFIG_PARPORT_PC) || defined(CONFIG_PARPORT_PC_MODULE)) && !(defined(CONFIG_PARPORT_AX) || defined(CONFIG_PARPORT_AX_MODULE)) && !(defined(CONFIG_PARPORT_ARC) || defined(CONFIG_PARPORT_ARC_MODULE)) && !(defined(CONFIG_PARPORT_AMIGA) || defined(CONFIG_PARPORT_AMIGA_MODULE)) && !(defined(CONFIG_PARPORT_MFC3) || defined(CONFIG_PARPORT_MFC3_MODULE)) && !(defined(CONFIG_PARPORT_ATARI) || defined(CONFIG_PARPORT_ATARI_MODULE)) && !defined(CONFIG_PARPORT_OTHER)
X #undef PARPORT_NEED_GENERIC_OPS
X #include <linux/parport_pc.h>
X #define parport_write_data(p,x)            parport_pc_write_data(p,x)
@@ -367,21 +492,11 @@
X #define parport_write_control(p,x)         parport_pc_write_control(p,x)
X #define parport_read_control(p)            parport_pc_read_control(p)
X #define parport_frob_control(p,m,v)        parport_pc_frob_control(p,m,v)
-#define parport_write_econtrol(p,x)        parport_pc_write_econtrol(p,x)
-#define parport_read_econtrol(p)           parport_pc_read_econtrol(p)
-#define parport_frob_econtrol(p,m,v)       parport_pc_frob_econtrol(p,m,v)
-#define parport_write_status(p,v)          parport_pc_write_status(p,v)
X #define parport_read_status(p)             parport_pc_read_status(p)
-#define parport_write_fifo(p,v)            parport_pc_write_fifo(p,v)
-#define parport_read_fifo(p)               parport_pc_read_fifo(p)
-#define parport_change_mode(p,m)           parport_pc_change_mode(p,m)
-#define parport_release_resources(p)       parport_pc_release_resources(p)
-#define parport_claim_resources(p)         parport_pc_claim_resources(p)
-#define parport_epp_write_data(p,x)        parport_pc_write_epp(p,x)
-#define parport_epp_read_data(p)           parport_pc_read_epp(p)
-#define parport_epp_write_addr(p,x)        parport_pc_write_epp_addr(p,x)
-#define parport_epp_read_addr(p)           parport_pc_read_epp_addr(p)
-#define parport_epp_check_timeout(p)       parport_pc_check_epp_timeout(p)
+#define parport_enable_irq(p)              parport_pc_enable_irq(p)
+#define parport_disable_irq(p)             parport_pc_disable_irq(p)
+#define parport_data_forward(p)            parport_pc_data_forward(p)
+#define parport_data_reverse(p)            parport_pc_data_reverse(p)
X #endif
X 
X #ifdef PARPORT_NEED_GENERIC_OPS
@@ -391,21 +506,11 @@
X #define parport_write_control(p,x)         (p)->ops->write_control(p,x)
X #define parport_read_control(p)            (p)->ops->read_control(p)
X #define parport_frob_control(p,m,v)        (p)->ops->frob_control(p,m,v)
-#define parport_write_econtrol(p,x)        (p)->ops->write_econtrol(p,x)
-#define parport_read_econtrol(p)           (p)->ops->read_econtrol(p)
-#define parport_frob_econtrol(p,m,v)       (p)->ops->frob_econtrol(p,m,v)
-#define parport_write_status(p,v)          (p)->ops->write_status(p,v)
X #define parport_read_status(p)             (p)->ops->read_status(p)
-#define parport_write_fifo(p,v)            (p)->ops->write_fifo(p,v)
-#define parport_read_fifo(p)               (p)->ops->read_fifo(p)
-#define parport_change_mode(p,m)           (p)->ops->change_mode(p,m)
-#define parport_release_resources(p)       (p)->ops->release_resources(p)
-#define parport_claim_resources(p)         (p)->ops->claim_resources(p)
-#define parport_epp_write_data(p,x)        (p)->ops->epp_write_data(p,x)
-#define parport_epp_read_data(p)           (p)->ops->epp_read_data(p)
-#define parport_epp_write_addr(p,x)        (p)->ops->epp_write_addr(p,x)
-#define parport_epp_read_addr(p)           (p)->ops->epp_read_addr(p)
-#define parport_epp_check_timeout(p)       (p)->ops->epp_check_timeout(p)
+#define parport_enable_irq(p)              (p)->ops->enable_irq(p)
+#define parport_disable_irq(p)             (p)->ops->disable_irq(p)
+#define parport_data_forward(p)            (p)->ops->data_forward(p)
+#define parport_data_reverse(p)            (p)->ops->data_reverse(p)
X #endif
X 
X #endif /* __KERNEL__ */
diff -u --recursive --new-file v2.3.9/linux/include/linux/parport_pc.h linux/include/linux/parport_pc.h
--- v2.3.9/linux/include/linux/parport_pc.h	Tue Jun 22 14:41:46 1999
+++ linux/include/linux/parport_pc.h	Wed Jul  7 09:20:54 1999
@@ -5,57 +5,39 @@
X 
X /* --- register definitions ------------------------------- */
X 
-#define ECONTROL(p)	((p)->base_hi + 0x02)
-#define CONFIGB(p)	((p)->base_hi + 0x01)
-#define CONFIGA(p)	((p)->base_hi + 0x00)
-#define EPPDATA(p)	((p)->base    + 0x04)
-#define EPPADDR(p)	((p)->base    + 0x03)
-#define CONTROL(p)	((p)->base    + 0x02)
-#define STATUS(p)	((p)->base    + 0x01)
-#define DATA(p)		((p)->base    + 0x00)
+#define ECONTROL(p) ((p)->base_hi + 0x2)
+#define CONFIGB(p)  ((p)->base_hi + 0x1)
+#define CONFIGA(p)  ((p)->base_hi + 0x0)
+#define FIFO(p)     ((p)->base_hi + 0x0)
+#define EPPDATA(p)  ((p)->base    + 0x4)
+#define EPPADDR(p)  ((p)->base    + 0x3)
+#define CONTROL(p)  ((p)->base    + 0x2)
+#define STATUS(p)   ((p)->base    + 0x1)
+#define DATA(p)     ((p)->base    + 0x0)
X 
-/* Private data for PC low-level driver. */
X struct parport_pc_private {
X 	/* Contents of CTR. */
X 	unsigned char ctr;
-};
X 
-extern int parport_pc_epp_clear_timeout(struct parport *pb);
+	/* Bitmask of writable CTR bits. */
+	unsigned char ctr_writable;
X 
-extern volatile unsigned char parport_pc_ctr;
+	/* Whether or not there's an ECR. */
+	int ecr;
X 
-extern __inline__ void parport_pc_write_epp(struct parport *p, unsigned char d)
-{
-	outb(d, EPPDATA(p));
-}
-
-extern __inline__ unsigned char parport_pc_read_epp(struct parport *p)
-{
-	return inb(EPPDATA(p));
-}
+	/* Number of PWords that FIFO will hold. */
+	int fifo_depth;
X 
-extern __inline__ void parport_pc_write_epp_addr(struct parport *p, unsigned char d)
-{
-	outb(d, EPPADDR(p));
-}
+	/* Number of bytes per portword. */
+	int pword;
X 
-extern __inline__ unsigned char parport_pc_read_epp_addr(struct parport *p)
-{
-	return inb(EPPADDR(p));
-}
+	/* Not used yet. */
+	int readIntrThreshold;
+	int writeIntrThreshold;
X 
-extern __inline__ int parport_pc_check_epp_timeout(struct parport *p)
-{
-	if (!(inb(STATUS(p)) & 1))
-		return 0;
-	parport_pc_epp_clear_timeout(p);
-	return 1;
-}
-
-extern __inline__ unsigned char parport_pc_read_configb(struct parport *p)
-{
-	return inb(CONFIGB(p));
-}
+	/* buffer suitable for DMA, if DMA enabled */
+	char *dma_buf;
+};
X 
X extern __inline__ void parport_pc_write_data(struct parport *p, unsigned char d)
X {
@@ -67,31 +49,68 @@
X 	return inb(DATA(p));
X }
X 
-extern __inline__ void parport_pc_write_control(struct parport *p, unsigned char d)
+extern __inline__ unsigned char __frob_control (struct parport *p,
+						unsigned char mask,
+						unsigned char val)
X {
-	struct parport_pc_private *priv = p->private_data;
-	priv->ctr = d;/* update soft copy */
-	outb(d, CONTROL(p));
+	struct parport_pc_private *priv = p->physport->private_data;
+	unsigned char ctr = priv->ctr;
+	ctr = (ctr & ~mask) ^ val;
+	ctr &= priv->ctr_writable; /* only write writable bits. */
+	outb (ctr, CONTROL (p));
+	return priv->ctr = ctr; /* update soft copy */
X }
X 
-extern __inline__ unsigned char parport_pc_read_control(struct parport *p)
+extern __inline__ void parport_pc_data_reverse (struct parport *p)
X {
-	struct parport_pc_private *priv = p->private_data;
-	return priv->ctr;
+	__frob_control (p, 0x20, 0x20);
X }
X 
-extern __inline__ unsigned char parport_pc_frob_control(struct parport *p, unsigned char mask,  unsigned char val)
+extern __inline__ void parport_pc_write_control (struct parport *p,
+						 unsigned char d)
X {
-	struct parport_pc_private *priv = p->private_data;
-	unsigned char ctr = priv->ctr;
-	ctr = (ctr & ~mask) ^ val;
-	outb (ctr, CONTROL(p));
-	return priv->ctr = ctr; /* update soft copy */
+	const unsigned char wm = (PARPORT_CONTROL_STROBE |
+				  PARPORT_CONTROL_AUTOFD |
+				  PARPORT_CONTROL_INIT |
+				  PARPORT_CONTROL_SELECT);
+
+	/* Take this out when drivers have adapted to newer interface. */
+	if (d & 0x20) {
+			printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n",
+					p->name, p->cad->name);
+			parport_pc_data_reverse (p);
+	}
+
+	__frob_control (p, wm, d & wm);
X }
X 
-extern __inline__ void parport_pc_write_status(struct parport *p, unsigned char d)
+extern __inline__ unsigned char parport_pc_read_control(struct parport *p)
X {
-	outb(d, STATUS(p));
+	const struct parport_pc_private *priv = p->physport->private_data;
+	return priv->ctr; /* Use soft copy */
+}
+
+extern __inline__ unsigned char parport_pc_frob_control (struct parport *p,
+							 unsigned char mask,
+							 unsigned char val)
+{
+	const unsigned char wm = (PARPORT_CONTROL_STROBE |
+				  PARPORT_CONTROL_AUTOFD |
+				  PARPORT_CONTROL_INIT |
+				  PARPORT_CONTROL_SELECT);
+
+	/* Take this out when drivers have adapted to newer interface. */
+	if (mask & 0x20) {
+			printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n",
+					p->name, p->cad->name);
+			parport_pc_data_reverse (p);
+	}
+
+	/* Restrict mask and val to control lines. */
+	mask &= wm;
+	val &= wm;
+
+	return __frob_control (p, mask, val);
X }
X 
X extern __inline__ unsigned char parport_pc_read_status(struct parport *p)
@@ -99,50 +118,30 @@
X 	return inb(STATUS(p));
X }
X 
-extern __inline__ void parport_pc_write_econtrol(struct parport *p, unsigned char d)
+extern __inline__ void parport_pc_data_forward (struct parport *p)
X {
-	outb(d, ECONTROL(p));
+	__frob_control (p, 0x20, 0x00);
X }
X 
-extern __inline__ unsigned char parport_pc_read_econtrol(struct parport *p)
+extern __inline__ void parport_pc_disable_irq(struct parport *p)
X {
-	return inb(ECONTROL(p));
+	__frob_control (p, 0x10, 0x00);
X }
X 
-extern __inline__ unsigned char parport_pc_frob_econtrol(struct parport *p, unsigned char mask,  unsigned char val)
+extern __inline__ void parport_pc_enable_irq(struct parport *p)
X {
-	unsigned char old = inb(ECONTROL(p));
-	outb(((old & ~mask) ^ val), ECONTROL(p));
-	return old;
+	__frob_control (p, 0x10, 0x10);
X }
X 
-extern void parport_pc_change_mode(struct parport *p, int m);
-
-extern void parport_pc_write_fifo(struct parport *p, unsigned char v);
-
-extern unsigned char parport_pc_read_fifo(struct parport *p);
-
-extern void parport_pc_disable_irq(struct parport *p);
-
-extern void parport_pc_enable_irq(struct parport *p);
-
X extern void parport_pc_release_resources(struct parport *p);
X 
X extern int parport_pc_claim_resources(struct parport *p);
X 
-extern void parport_pc_init_state(struct parport_state *s);
+extern void parport_pc_init_state(struct pardevice *, struct parport_state *s);
X 
X extern void parport_pc_save_state(struct parport *p, struct parport_state *s);
X 
X extern void parport_pc_restore_state(struct parport *p, struct parport_state *s);
-
-extern size_t parport_pc_epp_read_block(struct parport *p, void *buf, size_t length);
-
-extern size_t parport_pc_epp_write_block(struct parport *p, void *buf, size_t length);
-
-extern int parport_pc_ecp_read_block(struct parport *p, void *buf, size_t length, void (*fn)(struct parport *, void *, size_t), void *handle);
-
-extern int parport_pc_ecp_write_block(struct parport *p, void *buf, size_t length, void (*fn)(struct parport *, void *, size_t), void *handle);
X 
X extern void parport_pc_inc_use_count(void);
X 
diff -u --recursive --new-file v2.3.9/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.3.9/linux/include/linux/pci.h	Wed Jun 30 13:38:20 1999
+++ linux/include/linux/pci.h	Thu Jul  8 14:50:20 1999
@@ -273,6 +273,9 @@
X #define PCI_CLASS_SERIAL_USB		0x0c03
X #define PCI_CLASS_SERIAL_FIBER		0x0c04
X 
+#define PCI_BASE_CLASS_INTELLIGENT	0x0e
+#define PCI_CLASS_INTELLIGENT_I2O	0x0e00
+
X #define PCI_CLASS_HOT_SWAP_CONTROLLER	0xff00
X 
X #define PCI_CLASS_OTHERS		0xff
@@ -305,6 +308,7 @@
X #define PCI_DEVICE_ID_NCR_53C895	0x000c
X #define PCI_DEVICE_ID_NCR_53C885	0x000d
X #define PCI_DEVICE_ID_NCR_53C875	0x000f
+#define PCI_DEVICE_ID_NCR_53C1510	0x0010
X #define PCI_DEVICE_ID_NCR_53C875J	0x008f
X 
X #define PCI_VENDOR_ID_ATI		0x1002
@@ -368,6 +372,7 @@
X #define PCI_DEVICE_ID_DEC_21152		0x0024
X #define PCI_DEVICE_ID_DEC_21153		0x0025
X #define PCI_DEVICE_ID_DEC_21154		0x0026
+#define PCI_DEVICE_ID_COMPAQ_42XX	0x0046
X 
X #define PCI_VENDOR_ID_CIRRUS		0x1013
X #define PCI_DEVICE_ID_CIRRUS_7548	0x0038
@@ -403,6 +408,7 @@
X 
X #define PCI_VENDOR_ID_AMD		0x1022
X #define PCI_DEVICE_ID_AMD_LANCE		0x2000
+#define PCI_DEVICE_ID_AMD_LANCE_HOME	0x2001
X #define PCI_DEVICE_ID_AMD_SCSI		0x2020
X 
X #define PCI_VENDOR_ID_TRIDENT		0x1023
@@ -616,6 +622,9 @@
X #define PCI_VENDOR_ID_SIERRA		0x10a8
X #define PCI_DEVICE_ID_SIERRA_STB	0x0000
X 
+#define PCI_VENDOR_ID_SGI		0x10a9
+#define PCI_DEVICE_ID_SGI_IOC3		0x0003
+
X #define PCI_VENDOR_ID_ACC		0x10aa
X #define PCI_DEVICE_ID_ACC_2056		0x0000
X 
@@ -686,6 +695,8 @@
X #define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128V 0x0002
X #define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZV 0x0003
X #define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004
+#define PCI_DEVICE_ID_NEOMAGIC_MAGICMEDIA_256AV       0x0005
+#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZVPLUS   0x0083
X 
X #define PCI_VENDOR_ID_ASP		0x10cd
X #define PCI_DEVICE_ID_ASP_ABP940	0x1200
@@ -868,6 +879,9 @@
X #define PCI_VENDOR_ID_GALILEO		0x11ab
X #define PCI_DEVICE_ID_GALILEO_GT64011	0x4146
X 
+#define PCI_VENDOR_ID_GALILEO		0x11ab
+#define PCI_DEVICE_ID_GALILEO_GT64011	0x4146
+
X #define PCI_VENDOR_ID_LITEON		0x11ad
X #define PCI_DEVICE_ID_LITEON_LNE100TX	0x0002
X 
@@ -966,6 +980,7 @@
X 
X #define PCI_VENDOR_ID_ENSONIQ		0x1274
X #define PCI_DEVICE_ID_ENSONIQ_AUDIOPCI	0x5000
+#define PCI_DEVICE_ID_ENSONIQ_ES1371    0x1371
X 
X #define PCI_VENDOR_ID_ALTEON		0x12ae
X #define PCI_DEVICE_ID_ALTEON_ACENIC	0x0001
@@ -1032,6 +1047,7 @@
X #define PCI_DEVICE_ID_GENROCO_HFP832	0x0003
X 
X #define PCI_VENDOR_ID_INTEL		0x8086
+#define PCI_DEVICE_ID_INTEL_21145	0x0039
X #define PCI_DEVICE_ID_INTEL_82375	0x0482
X #define PCI_DEVICE_ID_INTEL_82424	0x0483
X #define PCI_DEVICE_ID_INTEL_82378	0x0484
@@ -1075,6 +1091,7 @@
X #define PCI_VENDOR_ID_ADAPTEC		0x9004
X #define PCI_DEVICE_ID_ADAPTEC_7810	0x1078
X #define PCI_DEVICE_ID_ADAPTEC_7821	0x2178
+#define PCI_DEVICE_ID_ADAPTEC_38602	0x3860
X #define PCI_DEVICE_ID_ADAPTEC_7850	0x5078
X #define PCI_DEVICE_ID_ADAPTEC_7855	0x5578
X #define PCI_DEVICE_ID_ADAPTEC_5800	0x5800
diff -u --recursive --new-file v2.3.9/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- v2.3.9/linux/include/linux/proc_fs.h	Wed Jun 30 13:38:20 1999
+++ linux/include/linux/proc_fs.h	Wed Jul  7 09:21:05 1999
@@ -375,6 +375,7 @@
X     }
X }
X 
+extern struct super_block *proc_super_blocks;
X extern struct dentry_operations proc_dentry_operations;
X extern struct super_block *proc_read_super(struct super_block *,void *,int);
X extern int init_proc_fs(void);
@@ -456,12 +457,12 @@
X 
X #else
X 
-extern inline int proc_register(struct proc_dir_entry *a, struct proc_dir_entry *b) {};
-extern inline int proc_unregister(struct proc_dir_entry *a, int b) {};
-extern inline int proc_net_register(struct proc_dir_entry *a) {};
-extern inline int proc_net_unregister(int x) {};
-extern inline int proc_scsi_register(struct proc_dir_entry *b, struct proc_dir_entry *c) {};
-extern inline int proc_scsi_unregister(struct proc_dir_entry *a, int x);
+extern inline int proc_register(struct proc_dir_entry *a, struct proc_dir_entry *b) { return 0; }
+extern inline int proc_unregister(struct proc_dir_entry *a, int b) { return 0; }
+extern inline int proc_net_register(struct proc_dir_entry *a) { return 0; }
+extern inline int proc_net_unregister(int x) { return 0; }
+extern inline int proc_scsi_register(struct proc_dir_entry *b, struct proc_dir_entry *c) { return 0; }
+extern inline int proc_scsi_unregister(struct proc_dir_entry *a, int x) { return 0; }
X 
X extern inline struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
X 					 struct proc_dir_entry *parent)
diff -u --recursive --new-file v2.3.9/linux/include/linux/sched.h linux/include/linux/sched.h
--- v2.3.9/linux/include/linux/sched.h	Wed Jun 30 13:38:20 1999
+++ linux/include/linux/sched.h	Wed Jul  7 09:20:45 1999
@@ -172,6 +172,7 @@
X 	atomic_t count;
X 	int map_count;				/* number of VMAs */
X 	struct semaphore mmap_sem;
+	spinlock_t page_table_lock;
X 	unsigned long context;
X 	unsigned long start_code, end_code, start_data, end_data;
X 	unsigned long start_brk, brk, start_stack;
@@ -193,6 +194,7 @@
X 		swapper_pg_dir, 			\
X 		ATOMIC_INIT(1), 1,			\
X 		__MUTEX_INITIALIZER(name.mmap_sem),	\
+		SPIN_LOCK_UNLOCKED,			\
X 		0,					\
X 		0, 0, 0, 0,				\
X 		0, 0, 0, 				\
@@ -343,7 +345,7 @@
X  */
X #define _STK_LIM	(8*1024*1024)
X 
-#define DEF_PRIORITY	(20*HZ/100)	/* 210 ms time slices */
+#define DEF_PRIORITY	(20*HZ/100)	/* 200 ms time slices */
X 
X /*
X  *  INIT_TASK is used to set up the first task table, touch at
diff -u --recursive --new-file v2.3.9/linux/include/linux/soundcard.h linux/include/linux/soundcard.h
--- v2.3.9/linux/include/linux/soundcard.h	Sat Oct 24 11:40:16 1998
+++ linux/include/linux/soundcard.h	Mon Jul  5 20:02:10 1999
@@ -891,6 +891,12 @@
X #define SOUND_MIXER_ACCESS		_SIOWR('M', 102, mixer_record)
X 
X /*
+ * Two ioctls for special souncard function
+ */
+#define SOUND_MIXER_AGC  _SIOWR('M', 103, int)
+#define SOUND_MIXER_3DSE  _SIOWR('M', 104, int)
+
+/*
X  * The SOUND_MIXER_PRIVATE# commands can be redefined by low level drivers.
X  * These features can be used when accessing device specific features.
X  */
diff -u --recursive --new-file v2.3.9/linux/include/linux/swap.h linux/include/linux/swap.h
--- v2.3.9/linux/include/linux/swap.h	Wed Jun 30 13:38:20 1999
+++ linux/include/linux/swap.h	Wed Jul  7 09:20:38 1999
@@ -90,9 +90,6 @@
X extern void swap_after_unlock_page (unsigned long entry);
X 
X /* linux/mm/page_alloc.c */
-extern void swap_in(struct task_struct *, struct vm_area_struct *,
-		    pte_t *, unsigned long, int);
-
X 
X /* linux/mm/swap_state.c */
X extern void show_swap_cache_info(void);
diff -u --recursive --new-file v2.3.9/linux/include/linux/tty.h linux/include/linux/tty.h
--- v2.3.9/linux/include/linux/tty.h	Tue Jun 22 14:41:46 1999
+++ linux/include/linux/tty.h	Wed Jul  7 09:20:44 1999
@@ -277,6 +277,7 @@
X 	struct tq_struct tq_hangup;
X 	void *disc_data;
X 	void *driver_data;
+	struct list_head tty_files;
X 
X #define N_TTY_BUF_SIZE 4096
X 	
diff -u --recursive --new-file v2.3.9/linux/include/linux/video_decoder.h linux/include/linux/video_decoder.h
--- v2.3.9/linux/include/linux/video_decoder.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/video_decoder.h	Mon Jul  5 20:02:10 1999
@@ -0,0 +1,37 @@
+#ifndef _LINUX_VIDEO_DECODER_H
+#define _LINUX_VIDEO_DECODER_H
+
+struct video_decoder_capability { /* this name is too long */
+	__u32	flags;
+#define	VIDEO_DECODER_PAL	1	/* can decode PAL signal */
+#define	VIDEO_DECODER_NTSC	2	/* can decode NTSC */
+#define	VIDEO_DECODER_SECAM	4	/* can decode SECAM */
+#define	VIDEO_DECODER_AUTO	8	/* can autosense norm */
+#define	VIDEO_DECODER_CCIR	16	/* CCIR-601 pixel rate (720 pixels per line) instead of square pixel rate */
+	int	inputs;			/* number of inputs */
+	int	outputs;		/* number of outputs */
+};
+
+/*
+DECODER_GET_STATUS returns the following flags.  The only one you need is
+DECODER_STATUS_GOOD, the others are just nice things to know.
+*/
+#define	DECODER_STATUS_GOOD	1	/* receiving acceptable input */
+#define	DECODER_STATUS_COLOR	2	/* receiving color information */
+#define	DECODER_STATUS_PAL	4	/* auto detected */
+#define	DECODER_STATUS_NTSC	8	/* auto detected */
+#define	DECODER_STATUS_SECAM	16	/* auto detected */
+
+
+#define	DECODER_GET_CAPABILITIES _IOR('d', 1, struct video_decoder_capability)
+#define	DECODER_GET_STATUS    	_IOR('d', 2, int)
+#define	DECODER_SET_NORM	_IOW('d', 3, int)
+#define	DECODER_SET_INPUT	_IOW('d', 4, int)	/* 0 <= input < #inputs */
+#define	DECODER_SET_OUTPUT	_IOW('d', 5, int)	/* 0 <= output < #outputs */
+#define	DECODER_ENABLE_OUTPUT	_IOW('d', 6, int)	/* boolean output enable control */
+#define	DECODER_SET_PICTURE   	_IOW('d', 7, struct video_picture)
+
+#define	DECODER_DUMP		_IO('d', 192)		/* debug hook */
+
+
+#endif
diff -u --recursive --new-file v2.3.9/linux/include/linux/video_encoder.h linux/include/linux/video_encoder.h
--- v2.3.9/linux/include/linux/video_encoder.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/video_encoder.h	Mon Jul  5 20:02:10 1999
@@ -0,0 +1,21 @@
+#ifndef _LINUX_VIDEO_ENCODER_H
+#define _LINUX_VIDEO_ENCODER_H
+
+struct video_encoder_capability { /* this name is too long */
+	__u32	flags;
+#define	VIDEO_ENCODER_PAL	1	/* can encode PAL signal */
+#define	VIDEO_ENCODER_NTSC	2	/* can encode NTSC */
+#define	VIDEO_ENCODER_SECAM	4	/* can encode SECAM */
+#define	VIDEO_ENCODER_CCIR	16	/* CCIR-601 pixel rate (720 pixels per line) instead of square pixel rate */
+	int	inputs;			/* number of inputs */
+	int	outputs;		/* number of outputs */
+};
+
+#define	ENCODER_GET_CAPABILITIES _IOR('e', 1, struct video_encoder_capability)
+#define	ENCODER_SET_NORM	_IOW('e', 2, int)
+#define	ENCODER_SET_INPUT	_IOW('e', 3, int)	/* 0 <= input < #inputs */
+#define	ENCODER_SET_OUTPUT	_IOW('e', 4, int)	/* 0 <= output < #outputs */
+#define	ENCODER_ENABLE_OUTPUT	_IOW('e', 5, int)	/* boolean output enable control */
+
+
+#endif
diff -u --recursive --new-file v2.3.9/linux/include/linux/videodev.h linux/include/linux/videodev.h
--- v2.3.9/linux/include/linux/videodev.h	Thu May 13 14:28:30 1999
+++ linux/include/linux/videodev.h	Mon Jul  5 20:02:10 1999
@@ -279,6 +279,7 @@
X #define VID_HARDWARE_VINO	20	/* Reserved for SGI Indy Vino */
X #define VID_HARDWARE_CADET	21	/* Cadet radio */
X #define VID_HARDWARE_CPIA	22
+#define VID_HARDWARE_TERRATEC	23	/* TerraTec ActiveRadio */
X 
X /*
X  *	Initialiser list
diff -u --recursive --new-file v2.3.9/linux/include/net/irda/irmod.h linux/include/net/irda/irmod.h
--- v2.3.9/linux/include/net/irda/irmod.h	Wed May 12 13:27:37 1999
+++ linux/include/net/irda/irmod.h	Mon Jul  5 20:02:10 1999
@@ -90,7 +90,7 @@
X  */
X struct irda_cb {
X 	struct miscdevice dev;	
-	wait_queue_head_t *wait_queue;
+	wait_queue_head_t wait_queue;
X 
X 	int in_use;
X 
diff -u --recursive --new-file v2.3.9/linux/include/net/sock.h linux/include/net/sock.h
--- v2.3.9/linux/include/net/sock.h	Tue Jun 22 14:42:42 1999
+++ linux/include/net/sock.h	Wed Jul  7 09:21:42 1999
@@ -371,10 +371,6 @@
X } while(0);
X 
X struct sock {
-	/* This must be first. */
-	struct sock		*sklist_next;
-	struct sock		*sklist_prev;
-
X 	/* Local port binding hash linkage. */
X 	struct sock		*bind_next;
X 	struct sock		**bind_pprev;
@@ -579,10 +575,6 @@
X  * transport -> network interface is defined by struct inet_proto
X  */
X struct proto {
-	/* These must be first. */
-	struct sock		*sklist_next;
-	struct sock		*sklist_prev;
-
X 	void			(*close)(struct sock *sk, 
X 					long timeout);
X 	int			(*connect)(struct sock *sk,
@@ -621,9 +613,7 @@
X 	/* Keeping track of sk's, looking them up, and port selection methods. */
X 	void			(*hash)(struct sock *sk);
X 	void			(*unhash)(struct sock *sk);
-	void			(*rehash)(struct sock *sk);
-	unsigned short		(*good_socknum)(void);
-	int			(*verify_bind)(struct sock *sk, unsigned short snum);
+	int			(*get_port)(struct sock *sk, unsigned short snum);
X 
X 	unsigned short		max_header;
X 	unsigned long		retransmits;
@@ -666,40 +656,6 @@
X #define SOCKHASH_UNLOCK_READ_BH()	read_unlock(&sockhash_lock)
X #define SOCKHASH_LOCK_WRITE_BH()	write_lock(&sockhash_lock)
X #define SOCKHASH_UNLOCK_WRITE_BH()	write_unlock(&sockhash_lock)
-
-/* Some things in the kernel just want to get at a protocols
- * entire socket list commensurate, thus...
- */
-static __inline__ void add_to_prot_sklist(struct sock *sk)
-{
-	SOCKHASH_LOCK_WRITE();
-	if(!sk->sklist_next) {
-		struct proto *p = sk->prot;
-
-		sk->sklist_prev = (struct sock *) p;
-		sk->sklist_next = p->sklist_next;
-		p->sklist_next->sklist_prev = sk;
-		p->sklist_next = sk;
-
-		/* Charge the protocol. */
-		sk->prot->inuse += 1;
-		if(sk->prot->highestinuse < sk->prot->inuse)
-			sk->prot->highestinuse = sk->prot->inuse;
-	}
-	SOCKHASH_UNLOCK_WRITE();
-}
-
-static __inline__ void del_from_prot_sklist(struct sock *sk)
-{
-	SOCKHASH_LOCK_WRITE();
-	if(sk->sklist_next) {
-		sk->sklist_next->sklist_prev = sk->sklist_prev;
-		sk->sklist_prev->sklist_next = sk->sklist_next;
-		sk->sklist_next = NULL;
-		sk->prot->inuse--;
-	}
-	SOCKHASH_UNLOCK_WRITE();
-}
X 
X /* Used by processes to "lock" a socket state, so that
X  * interrupts and bottom half handlers won't change it
diff -u --recursive --new-file v2.3.9/linux/include/net/tcp.h linux/include/net/tcp.h
--- v2.3.9/linux/include/net/tcp.h	Tue Jun 22 14:42:48 1999
+++ linux/include/net/tcp.h	Wed Jul  7 09:21:48 1999
@@ -72,11 +72,7 @@
X  */
X struct tcp_bind_bucket {
X 	unsigned short		port;
-	unsigned short		flags;
-#define TCPB_FLAG_LOCKED	0x0001
-#define TCPB_FLAG_FASTREUSE	0x0002
-#define TCPB_FLAG_GOODSOCKNUM	0x0004
-
+	unsigned short		fastreuse;
X 	struct tcp_bind_bucket	*next;
X 	struct sock		*owners;
X 	struct tcp_bind_bucket	**pprev;
@@ -115,32 +111,6 @@
X 	return (lport & (tcp_bhash_size - 1));
X }
X 
-static __inline__ void tcp_sk_bindify(struct sock *sk)
-{
-	struct tcp_bind_bucket *tb;
-	unsigned short snum = sk->num;
-
-	for(tb = tcp_bhash[tcp_bhashfn(snum)]; tb->port != snum; tb = tb->next)
-		;
-	/* Update bucket flags. */
-	if(tb->owners == NULL) {
-		/* We're the first. */
-		if(sk->reuse && sk->state != TCP_LISTEN)
-			tb->flags = TCPB_FLAG_FASTREUSE;
-		else
-			tb->flags = 0;
-	} else {
-		if((tb->flags & TCPB_FLAG_FASTREUSE) &&
-		   ((sk->reuse == 0) || (sk->state == TCP_LISTEN)))
-			tb->flags &= ~TCPB_FLAG_FASTREUSE;
-	}
-	if((sk->bind_next = tb->owners) != NULL)
-		tb->owners->bind_pprev = &sk->bind_next;
-	tb->owners = sk;
-	sk->bind_pprev = &tb->owners;
-	sk->prev = (struct sock *) tb;
-}
-
X /* This is a TIME_WAIT bucket.  It works around the memory consumption
X  * problems of sockets in such a state on heavily loaded servers, but
X  * without violating the protocol specification.
@@ -150,8 +120,6 @@
X 	 * XXX Yes I know this is gross, but I'd have to edit every single
X 	 * XXX networking file if I created a "struct sock_header". -DaveM
X 	 */
-	struct sock		*sklist_next;
-	struct sock		*sklist_prev;
X 	struct sock		*bind_next;
X 	struct sock		**bind_pprev;
X 	__u32			daddr;
@@ -477,7 +445,9 @@
X extern struct proto tcp_prot;
X extern struct tcp_mib tcp_statistics;
X 
-extern unsigned short		tcp_good_socknum(void);
+extern void			tcp_put_port(struct sock *sk);
+extern void			__tcp_put_port(struct sock *sk);
+extern void			tcp_inherit_port(struct sock *sk, struct sock *child);
X 
X extern void			tcp_v4_err(struct sk_buff *skb,
X 					   unsigned char *, int);
@@ -630,8 +600,7 @@
X #define TCP_SLT_SYNACK		0
X #define TCP_SLT_KEEPALIVE	1
X #define TCP_SLT_TWKILL		2
-#define TCP_SLT_BUCKETGC	3
-#define TCP_SLT_MAX		4
+#define TCP_SLT_MAX		3
X 
X extern struct tcp_sl_timer tcp_slt_array[TCP_SLT_MAX];
X  
@@ -1067,17 +1036,6 @@
X 	struct tcp_sl_timer *slt = &tcp_slt_array[timer];
X 
X 	atomic_dec(&slt->count);
-}
-
-/* This needs to use a slow timer, so it is here. */
-static __inline__ void tcp_sk_unbindify(struct sock *sk)
-{
-	struct tcp_bind_bucket *tb = (struct tcp_bind_bucket *) sk->prev;
-	if(sk->bind_next)
-		sk->bind_next->bind_pprev = sk->bind_pprev;
-	*sk->bind_pprev = sk->bind_next;
-	if(tb->owners == NULL)
-		tcp_inc_slow_timer(TCP_SLT_BUCKETGC);
X }
X 
X extern const char timer_bug_msg[];
diff -u --recursive --new-file v2.3.9/linux/include/net/udp.h linux/include/net/udp.h
--- v2.3.9/linux/include/net/udp.h	Tue Jun  8 17:58:03 1999
+++ linux/include/net/udp.h	Wed Jul  7 09:21:42 1999
@@ -23,6 +23,7 @@
X #define _UDP_H
X 
X #include <linux/udp.h>
+#include <net/sock.h>
X 
X #define UDP_HTABLE_SIZE		128
X 
@@ -32,7 +33,18 @@
X  */
X extern struct sock *udp_hash[UDP_HTABLE_SIZE];
X 
-extern unsigned short udp_good_socknum(void);
+extern int udp_port_rover;
+
+static inline int udp_lport_inuse(u16 num)
+{
+	struct sock *sk = udp_hash[num & (UDP_HTABLE_SIZE - 1)];
+
+	for(; sk != NULL; sk = sk->next) {
+		if(sk->num == num)
+			return 1;
+	}
+	return 0;
+}
X 
X /* Note: this must match 'valbool' in sock_setsockopt */
X #define UDP_CSUM_NOXMIT		1
diff -u --recursive --new-file v2.3.9/linux/init/main.c linux/init/main.c
--- v2.3.9/linux/init/main.c	Wed Jun 30 13:38:20 1999
+++ linux/init/main.c	Mon Jul  5 19:52:52 1999
@@ -332,6 +332,9 @@
X #ifdef CONFIG_LTPC
X extern void ltpc_setup(char *str, int *ints);
X #endif
+#ifdef CONFIG_BLK_CPQ_DA
+extern void cpqarray_setup(char *str, int *ints);
+#endif
X 
X #if defined(CONFIG_SYSVIPC)
X extern void ipc_init(void);
@@ -864,6 +867,9 @@
X #endif
X #ifdef CONFIG_LTPC
X 	{ "ltpc=", ltpc_setup },
+#endif
+#ifdef CONFIG_BLK_CPQ_DA
+	{ "smart2=", cpqarray_setup },
X #endif
X 	{ 0, 0 }
X };
diff -u --recursive --new-file v2.3.9/linux/ipc/shm.c linux/ipc/shm.c
--- v2.3.9/linux/ipc/shm.c	Wed Jun 30 13:38:20 1999
+++ linux/ipc/shm.c	Sat Jul  3 12:04:12 1999
@@ -381,8 +381,7 @@
X 	NULL,			/* advise */
X 	shm_nopage,		/* nopage */
X 	NULL,			/* wppage */
-	shm_swapout,		/* swapout */
-	NULL			/* swapin */
+	shm_swapout		/* swapout */
X };
X 
X /* Insert shmd into the list shp->attaches */
@@ -548,6 +547,7 @@
X 	unsigned int id;
X 	struct shmid_kernel *shp;
X 
+	lock_kernel();
X 	id = SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK;
X 	shp = shm_segs[id];
X 	if (shp == IPC_UNUSED) {
@@ -558,6 +558,7 @@
X 	shp->u.shm_nattch++;
X 	shp->u.shm_atime = CURRENT_TIME;
X 	shp->u.shm_lpid = current->pid;
+	unlock_kernel();
X }
X 
X /*
@@ -571,6 +572,7 @@
X 	struct shmid_kernel *shp;
X 	int id;
X 
+	lock_kernel();
X 	/* remove from the list of attaches of the shm segment */
X 	id = SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK;
X 	shp = shm_segs[id];
@@ -579,6 +581,7 @@
X 	shp->u.shm_dtime = CURRENT_TIME;
X 	if (--shp->u.shm_nattch <= 0 && shp->u.shm_perm.mode & SHM_DEST)
X 		killseg (id);
+	unlock_kernel();
X }
X 
X /*
diff -u --recursive --new-file v2.3.9/linux/kernel/Makefile linux/kernel/Makefile
--- v2.3.9/linux/kernel/Makefile	Wed May  6 11:01:46 1998
+++ linux/kernel/Makefile	Sun Jul  4 13:41:08 1999
@@ -13,7 +13,7 @@
X O_TARGET := kernel.o
X O_OBJS    = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \
X 	    module.o exit.o itimer.o info.o time.o softirq.o resource.o \
-	    sysctl.o acct.o capability.o
+	    sysctl.o acct.o capability.o ptrace.o
X 
X OX_OBJS  += signal.o
X 
diff -u --recursive --new-file v2.3.9/linux/kernel/acct.c linux/kernel/acct.c
--- v2.3.9/linux/kernel/acct.c	Wed Jun 30 13:38:20 1999
+++ linux/kernel/acct.c	Sat Jul  3 10:43:52 1999
@@ -276,7 +276,7 @@
X 	 */
X 	if (!file)
X 		return 0;
-	atomic_inc(&file->f_count);
+	get_file(file);
X 	if (!check_free_space(file)) {
X 		fput(file);
X 		return 0;
diff -u --recursive --new-file v2.3.9/linux/kernel/exit.c linux/kernel/exit.c
--- v2.3.9/linux/kernel/exit.c	Tue May 11 14:37:40 1999
+++ linux/kernel/exit.c	Sun Jul  4 10:18:52 1999
@@ -166,11 +166,9 @@
X 			break;
X 		while (set) {
X 			if (set & 1) {
-				struct file * file = files->fd[i];
-				if (file) {
-					files->fd[i] = NULL;
+				struct file * file = xchg(&files->fd[i], NULL);
+				if (file)
X 					filp_close(file, files);
-				}
X 			}
X 			i++;
X 			set >>= 1;
@@ -182,10 +180,9 @@
X 
X static inline void __exit_files(struct task_struct *tsk)
X {
-	struct files_struct * files = tsk->files;
+	struct files_struct * files = xchg(&tsk->files, NULL);
X 
X 	if (files) {
-		tsk->files = NULL;
X 		if (atomic_dec_and_test(&files->count)) {
X 			close_files(files);
X 			/*
diff -u --recursive --new-file v2.3.9/linux/kernel/fork.c linux/kernel/fork.c
--- v2.3.9/linux/kernel/fork.c	Wed Jun 30 13:38:20 1999
+++ linux/kernel/fork.c	Mon Jul  5 20:34:31 1999
@@ -249,16 +249,18 @@
X 		tmp->vm_next = NULL;
X 		file = tmp->vm_file;
X 		if (file) {
-			atomic_inc(&file->f_count);
+			get_file(file);
X 			if (tmp->vm_flags & VM_DENYWRITE)
-				file->f_dentry->d_inode->i_writecount--;
+				atomic_dec(&file->f_dentry->d_inode->i_writecount);
X       
X 			/* insert tmp into the share list, just after mpnt */
+			spin_lock(&file->f_dentry->d_inode->i_shared_lock);
X 			if((tmp->vm_next_share = mpnt->vm_next_share) != NULL)
X 				mpnt->vm_next_share->vm_pprev_share =
X 					&tmp->vm_next_share;
X 			mpnt->vm_next_share = tmp;
X 			tmp->vm_pprev_share = &mpnt->vm_next_share;
+			spin_unlock(&file->f_dentry->d_inode->i_shared_lock);
X 		}
X 
X 		/* Copy the pages, but defer checking for errors */
@@ -304,6 +306,7 @@
X 		mm->map_count = 0;
X 		mm->def_flags = 0;
X 		init_MUTEX_LOCKED(&mm->mmap_sem);
+		mm->page_table_lock = SPIN_LOCK_UNLOCKED;
X 		/*
X 		 * Leave mm->pgd set to the parent's pgd
X 		 * so that pgd_offset() is always valid.
@@ -360,6 +363,10 @@
X 	struct mm_struct * mm;
X 	int retval;
X 
+	tsk->min_flt = tsk->maj_flt = 0;
+	tsk->cmin_flt = tsk->cmaj_flt = 0;
+	tsk->nswap = tsk->cnswap = 0;
+
X 	if (clone_flags & CLONE_VM) {
X 		mmget(current->mm);
X 		/*
@@ -376,9 +383,6 @@
X 		goto fail_nomem;
X 
X 	tsk->mm = mm;
-	tsk->min_flt = tsk->maj_flt = 0;
-	tsk->cmin_flt = tsk->cmaj_flt = 0;
-	tsk->nswap = tsk->cnswap = 0;
X 	copy_segments(nr, tsk, mm);
X 	retval = new_page_tables(tsk);
X 	if (retval)
@@ -478,17 +482,18 @@
X 	atomic_set(&newf->count, 1);
X 	newf->max_fds = NR_OPEN;
X 	newf->fd = new_fds;
+	read_lock(&oldf->file_lock);
X 	newf->close_on_exec = oldf->close_on_exec;
X 	i = copy_fdset(&newf->open_fds, &oldf->open_fds);
X 
X 	old_fds = oldf->fd;
X 	for (; i != 0; i--) {
X 		struct file *f = *old_fds++;
-		*new_fds = f;
X 		if (f)
-			atomic_inc(&f->f_count);
-		new_fds++;
+			get_file(f);
+		*new_fds++ = f;
X 	}
+	read_unlock(&oldf->file_lock);
X 	/* This is long word aligned thus could use a optimized version */ 
X 	memset(new_fds, 0, (char *)newf->fd + size - (char *)new_fds); 
X       
diff -u --recursive --new-file v2.3.9/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.3.9/linux/kernel/ksyms.c	Wed Jun 30 13:38:20 1999
+++ linux/kernel/ksyms.c	Mon Jul  5 11:45:30 1999
@@ -116,7 +116,8 @@
X EXPORT_SYMBOL(get_super);
X EXPORT_SYMBOL(get_fs_type);
X EXPORT_SYMBOL(getname);
-EXPORT_SYMBOL(__fput);
+EXPORT_SYMBOL(__fput);	/* goner? */
+EXPORT_SYMBOL(_fput);
X EXPORT_SYMBOL(igrab);
X EXPORT_SYMBOL(iunique);
X EXPORT_SYMBOL(iget);
@@ -141,8 +142,8 @@
X EXPORT_SYMBOL(init_private_file);
X EXPORT_SYMBOL(filp_open);
X EXPORT_SYMBOL(filp_close);
-EXPORT_SYMBOL(fput);
X EXPORT_SYMBOL(put_filp);
+EXPORT_SYMBOL(files_lock);
X EXPORT_SYMBOL(check_disk_change);
X EXPORT_SYMBOL(invalidate_buffers);
X EXPORT_SYMBOL(invalidate_inodes);
@@ -231,6 +232,7 @@
X EXPORT_SYMBOL(refile_buffer);
X EXPORT_SYMBOL(max_sectors);
X EXPORT_SYMBOL(max_readahead);
+EXPORT_SYMBOL(file_moveto);
X 
X /* tty routines */
X EXPORT_SYMBOL(tty_hangup);
diff -u --recursive --new-file v2.3.9/linux/kernel/ptrace.c linux/kernel/ptrace.c
--- v2.3.9/linux/kernel/ptrace.c	Wed Dec 31 16:00:00 1969
+++ linux/kernel/ptrace.c	Mon Jul  5 11:30:37 1999
@@ -0,0 +1,163 @@
+/*
+ * linux/kernel/ptrace.c
+ *
+ * (C) Copyright 1999 Linus Torvalds
+ *
+ * Common interfaces for "ptrace()" which we do not want
+ * to continually duplicate across every architecture.
+ */
+
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+
+/*
+ * Access another process' address space, one page at a time.
+ */
+static int access_one_page(struct task_struct * tsk, struct vm_area_struct * vma, unsigned long addr, void *buf, int len, int write)
+{
+	pgd_t * pgdir;
+	pmd_t * pgmiddle;
+	pte_t * pgtable;
+	unsigned long page;
+
+repeat:
+	pgdir = pgd_offset(vma->vm_mm, addr);
+	if (pgd_none(*pgdir))
+		goto fault_in_page;
+	if (pgd_bad(*pgdir))
+		goto bad_pgd;
+	pgmiddle = pmd_offset(pgdir, addr);
+	if (pmd_none(*pgmiddle))
+		goto fault_in_page;
+	if (pmd_bad(*pgmiddle))
+		goto bad_pmd;
+	pgtable = pte_offset(pgmiddle, addr);
+	if (!pte_present(*pgtable))
+		goto fault_in_page;
+	page = pte_page(*pgtable);
+	if (MAP_NR(page) >= max_mapnr)
+		return 0;
+	flush_cache_page(vma, addr);
+	{
+		void *src = (void *) (page + (addr & ~PAGE_MASK));
+		void *dst = buf;
+
+		if (write) {
+			dst = src;
+			src = buf;
+		}
+		memcpy(dst, src, len);
+	}
+	flush_page_to_ram(page);
+	return len;
+
+fault_in_page:
+	/* -1: out of memory. 0 - unmapped page */
+	if (handle_mm_fault(tsk, vma, addr, write) > 0)
+		goto repeat;
+	return 0;
+
+bad_pgd:
+	printk("ptrace: bad pgd in '%s' at %08lx (%08lx)\n", tsk->comm, addr, pgd_val(*pgdir));
+	return 0;
+
+bad_pmd:
+	printk("ptrace: bad pmd in '%s' at %08lx (%08lx)\n", tsk->comm, addr, pmd_val(*pgmiddle));
+	return 0;
+}
+
+int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
+{
+	int copied;
+	struct vm_area_struct * vma = find_extend_vma(tsk, addr);
+
+	if (!vma)
+		return 0;
+
+	down(&tsk->mm->mmap_sem);
+	copied = 0;
+	for (;;) {
+		unsigned long offset = addr & ~PAGE_MASK;
+		int this_len = PAGE_SIZE - offset;
+		int retval;
+
+		if (this_len > len)
+			this_len = len;
+		retval = access_one_page(tsk, vma, addr, buf, this_len, write);
+		copied += retval;
+		if (retval != this_len)
+			break;
+
+		len -= retval;
+		if (!len)
+			break;
+
+		addr += retval;
+		buf += retval;
+
+		if (addr < vma->vm_end)
+			continue;	
+		if (!vma->vm_next)
+			break;
+		if (vma->vm_next->vm_start != vma->vm_end)
+			break;
+	
+		vma = vma->vm_next;
+	}
+	up(&tsk->mm->mmap_sem);
+	return copied;
+}
+
+int ptrace_readdata(struct task_struct *tsk, unsigned long src, char *dst, int len)
+{
+	int copied = 0;
+
+	while (len > 0) {
+		char buf[128];
+		int this_len, retval;
+
+		this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
+		retval = access_process_vm(tsk, src, buf, this_len, 0);
+		if (!retval) {
+			if (copied)
+				break;
+			return -EIO;
+		}
+		if (copy_to_user(dst, buf, retval))
+			return -EFAULT;
+		copied += retval;
+		src += retval;
+		dst += retval;
+		len -= retval;			
+	}
+	return copied;
+}
+
+int ptrace_writedata(struct task_struct *tsk, char * src, unsigned long dst, int len)
+{
+	int copied = 0;
+
+	while (len > 0) {
+		char buf[128];
+		int this_len, retval;
+
+		this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
+		if (copy_from_user(buf, src, this_len))
+			return -EFAULT;
+		retval = access_process_vm(tsk, dst, buf, this_len, 1);
+		if (!retval) {
+			if (copied)
+				break;
+			return -EIO;
+		}
+		copied += retval;
+		src += retval;
+		dst += retval;
+		len -= retval;			
+	}
+	return copied;
+}
diff -u --recursive --new-file v2.3.9/linux/kernel/sched.c linux/kernel/sched.c
--- v2.3.9/linux/kernel/sched.c	Wed May 12 14:41:36 1999
+++ linux/kernel/sched.c	Thu Jul  1 15:09:01 1999
@@ -1465,7 +1465,7 @@
X 	unsigned long user = ticks - system;
X 	if (p->pid) {
X 		p->counter -= ticks;
-		if (p->counter < 0) {
+		if (p->counter <= 0) {
X 			p->counter = 0;
X 			p->need_resched = 1;
X 		}
@@ -1668,7 +1668,7 @@
X 	 * do a "normalization" of the priority (traditionally
X 	 * Unix nice values are -20 to 20; Linux doesn't really
X 	 * use that kind of thing, but uses the length of the
-	 * timeslice instead (default 210 ms). The rounding is
+	 * timeslice instead (default 200 ms). The rounding is
X 	 * why we want to avoid negative values.
X 	 */
X 	newprio = (newprio * DEF_PRIORITY + 10) / 20;
diff -u --recursive --new-file v2.3.9/linux/kernel/signal.c linux/kernel/signal.c
--- v2.3.9/linux/kernel/signal.c	Mon Jun  7 16:14:06 1999
+++ linux/kernel/signal.c	Mon Jul  5 20:02:10 1999
@@ -29,7 +29,7 @@
X 
X static kmem_cache_t *signal_queue_cachep;
X 
-int nr_queued_signals;
+atomic_t nr_queued_signals;
X int max_queued_signals = 1024;
X 
X void __init signals_init(void)
@@ -60,7 +60,7 @@
X 	while (q) {
X 		n = q->next;
X 		kmem_cache_free(signal_queue_cachep, q);
-		nr_queued_signals--;
+		atomic_dec(&nr_queued_signals);
X 		q = n;
X 	}
X }
@@ -157,7 +157,7 @@
X 					current->sigqueue_tail = pp;
X 				*info = q->info;
X 				kmem_cache_free(signal_queue_cachep,q);
-				nr_queued_signals--;
+				atomic_dec(&nr_queued_signals);
X 				
X 				/* then see if this signal is still pending. */
X 				q = *pp;
@@ -323,13 +323,13 @@
X 
X 		struct signal_queue *q = 0;
X 
-		if (nr_queued_signals < max_queued_signals) {
+		if (atomic_read(&nr_queued_signals) < max_queued_signals) {
X 			q = (struct signal_queue *)
X 			    kmem_cache_alloc(signal_queue_cachep, GFP_ATOMIC);
X 		}
X 		
X 		if (q) {
-			nr_queued_signals++;
+			atomic_inc(&nr_queued_signals);
X 			q->next = NULL;
X 			*t->sigqueue_tail = q;
X 			t->sigqueue_tail = &q->next;
@@ -872,7 +872,7 @@
X 					else {
X 						*pp = q->next;
X 						kmem_cache_free(signal_queue_cachep, q);
-						nr_queued_signals--;
+						atomic_dec(&nr_queued_signals);
X 					}
X 					q = *pp;
X 				}
@@ -1067,7 +1067,9 @@
X 
X 	return old;
X }
+#endif /* !defined(__alpha__) */
X 
+#if !defined(__alpha__) && !defined(__mips__)
X /*
X  * For backwards compatibility.  Functionality superseded by sigaction.
X  */
@@ -1084,4 +1086,4 @@
X 
X 	return ret ? ret : (unsigned long)old_sa.sa.sa_handler;
X }
-#endif /* !alpha && !__ia64__ */
+#endif /* !alpha && !__ia64__ && !defined(__mips__) */
diff -u --recursive --new-file v2.3.9/linux/kernel/sys.c linux/kernel/sys.c
--- v2.3.9/linux/kernel/sys.c	Mon Jun  7 16:17:59 1999
+++ linux/kernel/sys.c	Sat Jul  3 12:04:12 1999
@@ -930,6 +930,8 @@
X  * either stopped or zombied.  In the zombied case the task won't get
X  * reaped till shortly after the call to getrusage(), in both cases the
X  * task being examined is in a frozen state so the counters won't change.
+ *
+ * FIXME! Get the fault counts properly!
X  */
X int getrusage(struct task_struct *p, int who, struct rusage *ru)
X {
diff -u --recursive --new-file v2.3.9/linux/kernel/sysctl.c linux/kernel/sysctl.c
--- v2.3.9/linux/kernel/sysctl.c	Wed Jun 30 13:38:20 1999
+++ linux/kernel/sysctl.c	Mon Jul  5 20:35:18 1999
@@ -18,7 +18,6 @@
X #include <linux/proc_fs.h>
X #include <linux/ctype.h>
X #include <linux/utsname.h>
-#include <linux/swapctl.h>
X #include <linux/smp_lock.h>
X #include <linux/init.h>
X 
diff -u --recursive --new-file v2.3.9/linux/lib/string.c linux/lib/string.c
--- v2.3.9/linux/lib/string.c	Wed Jun 30 13:38:20 1999
+++ linux/lib/string.c	Mon Jul  5 20:02:10 1999
@@ -362,3 +362,17 @@
X 	return NULL;
X }
X #endif
+
+#ifndef __HAVE_ARCH_MEMCHR
+void *memchr(const void *s, int c, size_t n)
+{
+	unsigned char *p = s;
+	while (n-- != 0) {
+        	if ((unsigned char)c == *p++) {
+			return p-1;
+		}
+	}
+	return NULL;
+}
+
+#endif
diff -u --recursive --new-file v2.3.9/linux/mm/filemap.c linux/mm/filemap.c
--- v2.3.9/linux/mm/filemap.c	Wed Jun 30 13:38:20 1999
+++ linux/mm/filemap.c	Tue Jul  6 10:11:40 1999
@@ -1194,8 +1194,6 @@
X 	struct file * in_file, * out_file;
X 	struct inode * in_inode, * out_inode;
X 
-	lock_kernel();
-
X 	/*
X 	 * Get input file, and verify that it is ok..
X 	 */
@@ -1234,7 +1232,6 @@
X 	if (retval)
X 		goto fput_out;
X 
-	unlock_kernel();
X 	retval = 0;
X 	if (count) {
X 		read_descriptor_t desc;
@@ -1244,7 +1241,7 @@
X 		ppos = &in_file->f_pos;
X 		if (offset) {
X 			if (get_user(pos, offset))
-				goto fput_out_lock;
+				goto fput_out;
X 			ppos = &pos;
X 		}
X 
@@ -1261,14 +1258,11 @@
X 			put_user(pos, offset);
X 	}
X 
-fput_out_lock:
-	lock_kernel();
X fput_out:
X 	fput(out_file);
X fput_in:
X 	fput(in_file);
X out:
-	unlock_kernel();
X 	return retval;
X }
X 
@@ -1297,9 +1291,7 @@
X 	new_page = 0;
X 	offset = (address & PAGE_MASK) - area->vm_start + area->vm_offset;
X 	if (offset >= inode->i_size && (area->vm_flags & VM_SHARED) && area->vm_mm == current->mm)
-		goto no_page_nolock;
-
-	unlock_kernel();
+		goto no_page;
X 
X 	/*
X 	 * Do we have something in the page cache already?
@@ -1344,7 +1336,6 @@
X 			page_cache_free(new_page);
X 
X 		flush_page_to_ram(old_page);
-		lock_kernel();
X 		return old_page;
X 	}
X 
@@ -1354,7 +1345,6 @@
X 	copy_page(new_page, old_page);
X 	flush_page_to_ram(new_page);
X 	page_cache_release(page);
-	lock_kernel();
X 	return new_page;
X 
X no_cached_page:
@@ -1431,8 +1421,6 @@
X 	if (new_page)
X 		page_cache_free(new_page);
X no_page:
-	lock_kernel();
-no_page_nolock:
X 	return 0;
X }
X 
@@ -1487,7 +1475,7 @@
X 	 * If a task terminates while we're swapping the page, the vma and
X 	 * and file could be released ... increment the count to be safe.
X 	 */
-	atomic_inc(&file->f_count);
+	get_file(file);
X 	result = do_write_page(inode, file, (const char *) page, offset);
X 	fput(file);
X 	return result;
@@ -1648,8 +1636,7 @@
X 	NULL,			/* advise */
X 	filemap_nopage,		/* nopage */
X 	NULL,			/* wppage */
-	filemap_swapout,	/* swapout */
-	NULL,			/* swapin */
+	filemap_swapout		/* swapout */
X };
X 
X /*
@@ -1667,8 +1654,7 @@
X 	NULL,			/* advise */
X 	filemap_nopage,		/* nopage */
X 	NULL,			/* wppage */
-	NULL,			/* swapout */
-	NULL,			/* swapin */
+	NULL			/* swapout */
X };
X 
X /* This is used for a general mmap of a disk file */
diff -u --recursive --new-file v2.3.9/linux/mm/memory.c linux/mm/memory.c
--- v2.3.9/linux/mm/memory.c	Wed Jun 30 13:38:20 1999
+++ linux/mm/memory.c	Tue Jul  6 23:06:05 1999
@@ -36,7 +36,9 @@
X #include <linux/mm.h>
X #include <linux/mman.h>
X #include <linux/swap.h>
+#include <linux/pagemap.h>
X #include <linux/smp_lock.h>
+#include <linux/swapctl.h>
X 
X #include <asm/uaccess.h>
X #include <asm/pgtable.h>
@@ -320,7 +322,7 @@
X 	}
X }
X 
-static inline int zap_pte_range(pmd_t * pmd, unsigned long address, unsigned long size)
+static inline int zap_pte_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size)
X {
X 	pte_t * pte;
X 	int freed;
@@ -345,15 +347,15 @@
X 		page = *pte;
X 		pte++;
X 		size--;
+		pte_clear(pte-1);
X 		if (pte_none(page))
X 			continue;
-		pte_clear(pte-1);
X 		freed += free_pte(page);
X 	}
X 	return freed;
X }
X 
-static inline int zap_pmd_range(pgd_t * dir, unsigned long address, unsigned long size)
+static inline int zap_pmd_range(struct mm_struct *mm, pgd_t * dir, unsigned long address, unsigned long size)
X {
X 	pmd_t * pmd;
X 	unsigned long end;
@@ -373,7 +375,7 @@
X 		end = PGDIR_SIZE;
X 	freed = 0;
X 	do {
-		freed += zap_pte_range(pmd, address, end - address);
+		freed += zap_pte_range(mm, pmd, address, end - address);
X 		address = (address + PMD_SIZE) & PMD_MASK; 
X 		pmd++;
X 	} while (address < end);
@@ -390,11 +392,21 @@
X 	int freed = 0;
X 
X 	dir = pgd_offset(mm, address);
+
+	/*
+	 * This is a long-lived spinlock. That's fine.
+	 * There's no contention, because the page table
+	 * lock only protects against kswapd anyway, and
+	 * even if kswapd happened to be looking at this
+	 * process we _want_ it to get stuck.
+	 */
+	spin_lock(&mm->page_table_lock);
X 	while (address < end) {
-		freed += zap_pmd_range(dir, address, end - address);
+		freed += zap_pmd_range(mm, dir, address, end - address);
X 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
X 		dir++;
X 	}
+	spin_unlock(&mm->page_table_lock);
X 	/*
X 	 * Update rss for the mm_struct (not necessarily current->mm)
X 	 */
@@ -599,17 +611,16 @@
X  * We also mark the page dirty at this point even though the page will
X  * change only once the write actually happens. This avoids a few races,
X  * and potentially makes it more efficient.
+ *
+ * We enter with the page table read-lock held, and need to exit without
+ * it.
X  */
X static int do_wp_page(struct task_struct * tsk, struct vm_area_struct * vma,
X 	unsigned long address, pte_t *page_table, pte_t pte)
X {
X 	unsigned long old_page, new_page;
X 	struct page * page;
-	
-	new_page = __get_free_page(GFP_USER);
-	/* Did swap_out() unmap the protected page while we slept? */
-	if (pte_val(*page_table) != pte_val(pte))
-		goto end_wp_page;
+
X 	old_page = pte_page(pte);
X 	if (MAP_NR(old_page) >= max_mapnr)
X 		goto bad_wp_page;
@@ -634,44 +645,44 @@
X 		/* FallThrough */
X 	case 1:
X 		flush_cache_page(vma, address);
-		set_pte(page_table, pte_mkdirty(pte_mkwrite(pte)));
+		set_pte(page_table, pte_mkyoung(pte_mkdirty(pte_mkwrite(pte))));
X 		flush_tlb_page(vma, address);
-end_wp_page:
-		/*
-		 * We can release the kernel lock now.. Now swap_out will see
-		 * a dirty page and so won't get confused and flush_tlb_page
-		 * won't SMP race. -Andrea
-		 */
-		unlock_kernel();
-
-		if (new_page)
-			free_page(new_page);
+		spin_unlock(&tsk->mm->page_table_lock);
X 		return 1;
X 	}
-		
+
+	/*
+	 * Ok, we need to copy. Oh, well..
+	 */
+	spin_unlock(&tsk->mm->page_table_lock);
+	new_page = __get_free_page(GFP_USER);
X 	if (!new_page)
-		goto no_new_page;
+		return -1;
+	spin_lock(&tsk->mm->page_table_lock);
X 
-	if (PageReserved(page))
-		++vma->vm_mm->rss;
-	copy_cow_page(old_page,new_page);
-	flush_page_to_ram(old_page);
-	flush_page_to_ram(new_page);
-	flush_cache_page(vma, address);
-	set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
-	flush_tlb_page(vma, address);
-	unlock_kernel();
-	__free_page(page);
+	/*
+	 * Re-check the pte - we dropped the lock
+	 */
+	if (pte_val(*page_table) == pte_val(pte)) {
+		if (PageReserved(page))
+			++vma->vm_mm->rss;
+		copy_cow_page(old_page,new_page);
+		flush_page_to_ram(old_page);
+		flush_page_to_ram(new_page);
+		flush_cache_page(vma, address);
+		set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
+		flush_tlb_page(vma, address);
+
+		/* Free the old page.. */
+		new_page = old_page;
+	}
+	spin_unlock(&tsk->mm->page_table_lock);
+	free_page(new_page);
X 	return 1;
X 
X bad_wp_page:
X 	printk("do_wp_page: bogus page at address %08lx (%08lx)\n",address,old_page);
-	send_sig(SIGKILL, tsk, 1);
-no_new_page:
-	unlock_kernel();
-	if (new_page)
-		free_page(new_page);
-	return 0;
+	return -1;
X }
X 
X /*
@@ -725,8 +736,9 @@
X 	struct vm_area_struct * mpnt;
X 
X 	truncate_inode_pages(inode, offset);
+	spin_lock(&inode->i_shared_lock);
X 	if (!inode->i_mmap)
-		return;
+		goto out_unlock;
X 	mpnt = inode->i_mmap;
X 	do {
X 		struct mm_struct *mm = mpnt->vm_mm;
@@ -757,35 +769,81 @@
X 		zap_page_range(mm, start, len);
X 		flush_tlb_range(mm, start, end);
X 	} while ((mpnt = mpnt->vm_next_share) != NULL);
+out_unlock:
+	spin_unlock(&inode->i_shared_lock);
X }
X 
X 
-/*
- * This is called with the kernel lock held, we need
- * to return without it.
+
+/* 
+ * Primitive swap readahead code. We simply read an aligned block of
+ * (1 << page_cluster) entries in the swap area. This method is chosen
+ * because it doesn't cost us any seek time.  We also make sure to queue
+ * the 'original' request together with the readahead ones...  
X  */
-static int do_swap_page(struct task_struct * tsk, 
+static void swapin_readahead(unsigned long entry)
+{
+	int i;
+	struct page *new_page;
+	unsigned long offset = SWP_OFFSET(entry);
+	struct swap_info_struct *swapdev = SWP_TYPE(entry) + swap_info;
+	
+	offset = (offset >> page_cluster) << page_cluster;
+
+	i = 1 << page_cluster;
+	do {
+		/* Don't read-ahead past the end of the swap area */
+		if (offset >= swapdev->max)
+			break;
+		/* Don't block on I/O for read-ahead */
+		if (atomic_read(&nr_async_pages) >= pager_daemon.swap_cluster)
+			break;
+		/* Don't read in bad or busy pages */
+		if (!swapdev->swap_map[offset])
+			break;
+		if (swapdev->swap_map[offset] == SWAP_MAP_BAD)
+			break;
+
+		/* Ok, do the async read-ahead now */
+		new_page = read_swap_cache_async(SWP_ENTRY(SWP_TYPE(entry), offset), 0);
+		if (new_page != NULL)
+			__free_page(new_page);
+		offset++;
+	} while (--i);
+	return;
+}
+
+static int do_swap_page(struct task_struct * tsk,
X 	struct vm_area_struct * vma, unsigned long address,
-	pte_t * page_table, pte_t entry, int write_access)
+	pte_t * page_table, unsigned long entry, int write_access)
X {
-	if (!vma->vm_ops || !vma->vm_ops->swapin) {
-		swap_in(tsk, vma, page_table, pte_val(entry), write_access);
-		flush_page_to_ram(pte_page(*page_table));
-	} else {
-		pte_t page = vma->vm_ops->swapin(vma, address - vma->vm_start + vma->vm_offset, pte_val(entry));
-		if (pte_val(*page_table) != pte_val(entry)) {
-			free_page(pte_page(page));
-		} else {
-			if (page_count(mem_map + MAP_NR(pte_page(page))) > 1 &&
-			    !(vma->vm_flags & VM_SHARED))
-				page = pte_wrprotect(page);
-			++vma->vm_mm->rss;
-			++tsk->maj_flt;
-			flush_page_to_ram(pte_page(page));
-			set_pte(page_table, page);
-		}
+	struct page *page = lookup_swap_cache(entry);
+	pte_t pte;
+
+	if (!page) {
+		lock_kernel();
+		swapin_readahead(entry);
+		page = read_swap_cache(entry);
+		unlock_kernel();
+		if (!page)
+			return -1;
+
+		flush_page_to_ram(page_address(page));
+	}
+
+	vma->vm_mm->rss++;
+	tsk->min_flt++;
+	swap_free(entry);
+
+	pte = mk_pte(page_address(page), vma->vm_page_prot);
+
+	if (write_access && !is_page_shared(page)) {
+		delete_from_swap_cache(page);
+		pte = pte_mkwrite(pte_mkdirty(pte));
X 	}
-	unlock_kernel();
+	set_pte(page_table, pte);
+	/* No need to invalidate - it was non-present before */
+	update_mmu_cache(vma, address, pte);
X 	return 1;
X }
X 
@@ -798,7 +856,7 @@
X 	if (write_access) {
X 		unsigned long page = __get_free_page(GFP_USER);
X 		if (!page)
-			return 0;
+			return -1;
X 		clear_page(page);
X 		entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
X 		vma->vm_mm->rss++;
@@ -806,6 +864,8 @@
X 		flush_page_to_ram(page);
X 	}
X 	set_pte(page_table, entry);
+	/* No need to invalidate - it was non-present before */
+	update_mmu_cache(vma, addr, entry);
X 	return 1;
X }
X 
@@ -827,23 +887,17 @@
X 	unsigned long page;
X 	pte_t entry;
X 
-	if (!vma->vm_ops || !vma->vm_ops->nopage) {
-		unlock_kernel();
-		return do_anonymous_page(tsk, vma, page_table, write_access,
-		                         address);
-	}
+	if (!vma->vm_ops || !vma->vm_ops->nopage)
+		return do_anonymous_page(tsk, vma, page_table, write_access, address);
X 
X 	/*
X 	 * The third argument is "no_share", which tells the low-level code
X 	 * to copy, not share the page even if sharing is possible.  It's
X 	 * essentially an early COW detection.
X 	 */
-	page = vma->vm_ops->nopage(vma, address & PAGE_MASK,
-		(vma->vm_flags & VM_SHARED)?0:write_access);
-
-	unlock_kernel();
+	page = vma->vm_ops->nopage(vma, address & PAGE_MASK, (vma->vm_flags & VM_SHARED)?0:write_access);
X 	if (!page)
-		return 0;
+		return 0;	/* SIGBUS - but we _really_ should know whether it is OOM or SIGBUS */
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 32'
echo 'File patch-2.3.10 is continued in part 33'
echo 33 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 31 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 31; 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
X #define ASIZ_mm_segments	0x00000008
-#define ASIZ_mm	0x00000100
+#define ASIZ_mm	0x00000108
X #define AOFF_thread_ksp	0x00000000
X #define ASIZ_thread_ksp	0x00000008
X #define AOFF_thread_wstate	0x00000008
@@ -763,47 +767,49 @@
X #define ASIZ_mm_map_count	0x00000004
X #define AOFF_mm_mmap_sem	0x00000028
X #define ASIZ_mm_mmap_sem	0x00000040
-#define AOFF_mm_context	0x00000068
+#define AOFF_mm_page_table_lock	0x00000068
+#define ASIZ_mm_page_table_lock	0x0000000c
+#define AOFF_mm_context	0x00000078
X #define ASIZ_mm_context	0x00000008
-#define AOFF_mm_start_code	0x00000070
+#define AOFF_mm_start_code	0x00000080
X #define ASIZ_mm_start_code	0x00000008
-#define AOFF_mm_end_code	0x00000078
+#define AOFF_mm_end_code	0x00000088
X #define ASIZ_mm_end_code	0x00000008
-#define AOFF_mm_start_data	0x00000080
+#define AOFF_mm_start_data	0x00000090
X #define ASIZ_mm_start_data	0x00000008
-#define AOFF_mm_end_data	0x00000088
+#define AOFF_mm_end_data	0x00000098
X #define ASIZ_mm_end_data	0x00000008
-#define AOFF_mm_start_brk	0x00000090
+#define AOFF_mm_start_brk	0x000000a0
X #define ASIZ_mm_start_brk	0x00000008
-#define AOFF_mm_brk	0x00000098
+#define AOFF_mm_brk	0x000000a8
X #define ASIZ_mm_brk	0x00000008
-#define AOFF_mm_start_stack	0x000000a0
+#define AOFF_mm_start_stack	0x000000b0
X #define ASIZ_mm_start_stack	0x00000008
-#define AOFF_mm_arg_start	0x000000a8
+#define AOFF_mm_arg_start	0x000000b8
X #define ASIZ_mm_arg_start	0x00000008
-#define AOFF_mm_arg_end	0x000000b0
+#define AOFF_mm_arg_end	0x000000c0
X #define ASIZ_mm_arg_end	0x00000008
-#define AOFF_mm_env_start	0x000000b8
+#define AOFF_mm_env_start	0x000000c8
X #define ASIZ_mm_env_start	0x00000008
-#define AOFF_mm_env_end	0x000000c0
+#define AOFF_mm_env_end	0x000000d0
X #define ASIZ_mm_env_end	0x00000008
-#define AOFF_mm_rss	0x000000c8
+#define AOFF_mm_rss	0x000000d8
X #define ASIZ_mm_rss	0x00000008
-#define AOFF_mm_total_vm	0x000000d0
+#define AOFF_mm_total_vm	0x000000e0
X #define ASIZ_mm_total_vm	0x00000008
-#define AOFF_mm_locked_vm	0x000000d8
+#define AOFF_mm_locked_vm	0x000000e8
X #define ASIZ_mm_locked_vm	0x00000008
-#define AOFF_mm_def_flags	0x000000e0
+#define AOFF_mm_def_flags	0x000000f0
X #define ASIZ_mm_def_flags	0x00000008
-#define AOFF_mm_cpu_vm_mask	0x000000e8
+#define AOFF_mm_cpu_vm_mask	0x000000f8
X #define ASIZ_mm_cpu_vm_mask	0x00000008
-#define AOFF_mm_swap_cnt	0x000000f0
+#define AOFF_mm_swap_cnt	0x00000100
X #define ASIZ_mm_swap_cnt	0x00000008
-#define AOFF_mm_swap_address	0x000000f8
+#define AOFF_mm_swap_address	0x00000108
X #define ASIZ_mm_swap_address	0x00000008
-#define AOFF_mm_segments	0x00000100
+#define AOFF_mm_segments	0x00000110
X #define ASIZ_mm_segments	0x00000008
-#define ASIZ_mm	0x00000108
+#define ASIZ_mm	0x00000118
X #define AOFF_thread_ksp	0x00000000
X #define ASIZ_thread_ksp	0x00000008
X #define AOFF_thread_wstate	0x00000008
diff -u --recursive --new-file v2.3.9/linux/include/asm-sparc64/atomic.h linux/include/asm-sparc64/atomic.h
--- v2.3.9/linux/include/asm-sparc64/atomic.h	Sat Aug 16 09:51:10 1997
+++ linux/include/asm-sparc64/atomic.h	Sun Jul  4 09:53:12 1999
@@ -1,4 +1,4 @@
-/* $Id: atomic.h,v 1.18 1997/08/07 03:38:31 davem Exp $
+/* $Id: atomic.h,v 1.19 1999/07/03 22:11:17 davem Exp $
X  * atomic.h: Thankfully the V9 is at least reasonable for this
X  *           stuff.
X  *
@@ -20,66 +20,34 @@
X #define atomic_read(v)		((v)->counter)
X #define atomic_set(v, i)	(((v)->counter) = i)
X 
-extern __inline__ void atomic_add(int i, atomic_t *v)
-{
-	__asm__ __volatile__("
-1:	lduw		[%1], %%g5
-	add		%%g5, %0, %%g7
-	cas		[%1], %%g5, %%g7
-	sub		%%g5, %%g7, %%g5
-	brnz,pn		%%g5, 1b
-	 nop"
-	: /* No outputs */
-	: "HIr" (i), "r" (__atomic_fool_gcc(v))
-	: "g5", "g7", "memory");
-}
-
-extern __inline__ void atomic_sub(int i, atomic_t *v)
-{
-	__asm__ __volatile__("
-1:	lduw		[%1], %%g5
-	sub		%%g5, %0, %%g7
-	cas		[%1], %%g5, %%g7
-	sub		%%g5, %%g7, %%g5
-	brnz,pn		%%g5, 1b
-	 nop"
-	: /* No outputs */
-	: "HIr" (i), "r" (__atomic_fool_gcc(v))
-	: "g5", "g7", "memory");
-}
-
-/* Same as above, but return the result value. */
-extern __inline__ int atomic_add_return(int i, atomic_t *v)
-{
-	unsigned long oldval;
-	__asm__ __volatile__("
-1:	lduw		[%2], %%g5
-	add		%%g5, %1, %%g7
-	cas		[%2], %%g5, %%g7
-	sub		%%g5, %%g7, %%g5
-	brnz,pn		%%g5, 1b
-	 add		%%g7, %1, %0"
-	: "=&r" (oldval)
-	: "HIr" (i), "r" (__atomic_fool_gcc(v))
-	: "g5", "g7", "memory");
-	return (int)oldval;
-}
-
-extern __inline__ int atomic_sub_return(int i, atomic_t *v)
-{
-	unsigned long oldval;
-	__asm__ __volatile__("
-1:	lduw		[%2], %%g5
-	sub		%%g5, %1, %%g7
-	cas		[%2], %%g5, %%g7
-	sub		%%g5, %%g7, %%g5
-	brnz,pn		%%g5, 1b
-	 sub		%%g7, %1, %0"
-	: "=&r" (oldval)
-	: "HIr" (i), "r" (__atomic_fool_gcc(v))
-	: "g5", "g7", "memory");
-	return (int)oldval;
-}
+#define atomic_add_return(__i, __v) \
+({	register atomic_t *__V asm("g1"); \
+	register int __I asm("g2"); \
+	__V = (__v); __I = (__i); \
+	__asm__ __volatile__("sethi	%%hi(__atomic_add), %%g3\n\t" \
+			     "jmpl	%%g3 + %%lo(__atomic_add), %%g3\n\t" \
+			     " nop\n1:" \
+			     : "=&r" (__I) \
+			     : "0" (__I), "r" (__V) \
+			     : "g3", "g5", "g7", "cc", "memory"); \
+	__I; \
+})
+
+#define atomic_sub_return(__i, __v) \
+({	register atomic_t *__V asm("g1"); \
+	register int __I asm("g2"); \
+	__V = (__v); __I = (__i); \
+	__asm__ __volatile__("sethi	%%hi(__atomic_sub), %%g3\n\t" \
+			     "jmpl	%%g3 + %%lo(__atomic_sub), %%g3\n\t" \
+			     " nop\n1:" \
+			     : "=&r" (__I) \
+			     : "0" (__I), "r" (__V) \
+			     : "g3", "g5", "g7", "cc", "memory"); \
+	__I; \
+})
+
+#define atomic_add(i, v) atomic_add_return(i, v)
+#define atomic_sub(i, v) atomic_sub_return(i, v)
X 
X #define atomic_dec_return(v) atomic_sub_return(1,(v))
X #define atomic_inc_return(v) atomic_add_return(1,(v))
diff -u --recursive --new-file v2.3.9/linux/include/asm-sparc64/audioio.h linux/include/asm-sparc64/audioio.h
--- v2.3.9/linux/include/asm-sparc64/audioio.h	Wed May 12 08:41:15 1999
+++ linux/include/asm-sparc64/audioio.h	Mon Jul  5 20:35:18 1999
@@ -237,7 +237,6 @@
X 
X #ifdef __KERNEL__
X 
-#include <linux/types.h>
X #include <linux/fs.h>
X #include <linux/tqueue.h>
X #include <linux/wait.h>
diff -u --recursive --new-file v2.3.9/linux/include/asm-sparc64/spinlock.h linux/include/asm-sparc64/spinlock.h
--- v2.3.9/linux/include/asm-sparc64/spinlock.h	Thu Jun 17 01:08:50 1999
+++ linux/include/asm-sparc64/spinlock.h	Sun Jul  4 09:53:12 1999
@@ -42,7 +42,7 @@
X  * irq-safe write-lock, but readers can get non-irqsafe
X  * read-locks.
X  */
-typedef unsigned long rwlock_t;
+typedef unsigned int rwlock_t;
X #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
X 
X #define read_lock(lock)		do { } while(0)
@@ -255,90 +255,44 @@
X 
X #ifndef SPIN_LOCK_DEBUG
X 
-typedef unsigned long rwlock_t;
+typedef unsigned int rwlock_t;
X #define RW_LOCK_UNLOCKED	0
X 
-extern __inline__ void read_lock(rwlock_t *rw)
-{
-	__asm__ __volatile__("
-1:	ldx		[%0], %%g5
-	brlz,pn		%%g5, 2f
-4:	 add		%%g5, 1, %%g7
-	casx		[%0], %%g5, %%g7
-	cmp		%%g5, %%g7
-	bne,pn		%%xcc, 1b
-	 membar		#StoreLoad | #StoreStore
-	.subsection	2
-2:	ldx		[%0], %%g5
-	brlz,pt		%%g5, 2b
-	 membar		#LoadLoad
-	b,a,pt		%%xcc, 4b
-	.previous
-"	: /* no outputs */
-	: "r" (rw)
-	: "g5", "g7", "cc", "memory");
-}
-
-extern __inline__ void read_unlock(rwlock_t *rw)
-{
-	__asm__ __volatile__("
-1:	ldx		[%0], %%g5
-	sub		%%g5, 1, %%g7
-	casx		[%0], %%g5, %%g7
-	cmp		%%g5, %%g7
-	bne,pn		%%xcc, 1b
-	 membar		#StoreLoad | #StoreStore
-"	: /* no outputs */
-	: "r" (rw)
-	: "g5", "g7", "cc", "memory");
-}
-
-extern __inline__ void write_lock(rwlock_t *rw)
-{
-	__asm__ __volatile__("
-	sethi		%%uhi(0x8000000000000000), %%g3
-	sllx		%%g3, 32, %%g3
-1:	ldx		[%0], %%g5
-	brlz,pn		%%g5, 5f
-4:	 or		%%g5, %%g3, %%g7
-	casx		[%0], %%g5, %%g7
-	cmp		%%g5, %%g7
-	bne,pn		%%xcc, 1b
-	 andncc		%%g7, %%g3, %%g0
-	bne,pn		%%xcc, 7f
-	 membar		#StoreLoad | #StoreStore
-	.subsection	2
-7:	ldx		[%0], %%g5
-	andn		%%g5, %%g3, %%g7
-	casx		[%0], %%g5, %%g7
-	cmp		%%g5, %%g7
-	bne,pn		%%xcc, 7b
-	 membar		#StoreLoad | #StoreStore
-5:	ldx		[%0], %%g5
-	brnz,pt		%%g5, 5b
-	 membar		#LoadLoad
-	b,a,pt		%%xcc, 4b
-	.previous
-"	: /* no outputs */
-	: "r" (rw)
-	: "g3", "g5", "g7", "memory", "cc");
-}
-
-extern __inline__ void write_unlock(rwlock_t *rw)
-{
-	__asm__ __volatile__("
-	sethi		%%uhi(0x8000000000000000), %%g3
-	sllx		%%g3, 32, %%g3
-1:	ldx		[%0], %%g5
-	andn		%%g5, %%g3, %%g7
-	casx		[%0], %%g5, %%g7
-	cmp		%%g5, %%g7
-	bne,pn		%%xcc, 1b
-	 membar		#StoreLoad | #StoreStore
-"	: /* no outputs */
-	: "r" (rw)
-	: "g3", "g5", "g7", "memory", "cc");
-}
+#define read_lock(__rw_lck) \
+do {	register rwlock_t *__X asm("g1"); \
+	__asm__ __volatile__("sethi	%%hi(__read_lock), %%g3\n\t" \
+			     "jmpl	%%g3 + %%lo(__read_lock), %%g3\n\t" \
+			     " nop\n1:" \
+	: : "r" (__X = (__rw_lck)) \
+	  : "g3", "g5", "g7", "cc", "memory"); \
+} while(0)
+
+#define read_unlock(__rw_lck) \
+do {	register rwlock_t *__X asm("g1"); \
+	__asm__ __volatile__("sethi	%%hi(__read_unlock), %%g3\n\t" \
+			     "jmpl	%%g3 + %%lo(__read_unlock), %%g3\n\t" \
+			     " nop\n1:" \
+	: : "r" (__X = (__rw_lck)) \
+	  : "g3", "g5", "g7", "cc", "memory"); \
+} while(0)
+
+#define write_lock(__rw_lck) \
+do {	register rwlock_t *__X asm("g1"); \
+	__asm__ __volatile__("sethi	%%hi(__write_lock), %%g3\n\t" \
+			     "jmpl	%%g3 + %%lo(__write_lock), %%g3\n\t" \
+			     " nop\n1:" \
+	: : "r" (__X = (__rw_lck)) \
+	  : "g2", "g3", "g5", "g7", "cc", "memory"); \
+} while(0)
+
+#define write_unlock(__rw_lck) \
+do {	register rwlock_t *__X asm("g1"); \
+	__asm__ __volatile__("sethi	%%hi(__write_unlock), %%g3\n\t" \
+			     "jmpl	%%g3 + %%lo(__write_unlock), %%g3\n\t" \
+			     " nop\n1:" \
+	: : "r" (__X = (__rw_lck)) \
+	  : "g2", "g3", "g5", "g7", "cc", "memory"); \
+} while(0)
X 
X #define read_lock_irq(lock)	do { __cli(); read_lock(lock); } while (0)
X #define read_unlock_irq(lock)	do { read_unlock(lock); __sti(); } while (0)
diff -u --recursive --new-file v2.3.9/linux/include/linux/blk.h linux/include/linux/blk.h
--- v2.3.9/linux/include/linux/blk.h	Tue Jun 22 14:42:32 1999
+++ linux/include/linux/blk.h	Wed Jul  7 09:22:27 1999
@@ -359,6 +359,24 @@
X #define DEVICE_ON(device) 
X #define DEVICE_OFF(device)
X 
+#elif (MAJOR_NR == I2O_MAJOR)
+
+#define DEVICE_NAME "I2O block"
+#define DEVICE_REQUEST do_i2ob_request
+#define DEVICE_NR(device) (MINOR(device)>>4)
+#define DEVICE_ON(device) 
+#define DEVICE_OFF(device)
+
+#elif (MAJOR_NR == COMPAQ_SMART2_MAJOR)
+
+#define DEVICE_NAME "ida"
+#define DEVICE_INTR do_ida
+#define TIMEOUT_VALUE (25*HZ)
+#define DEVICE_REQUEST do_ida_request0
+#define DEVICE_NR(device) (MINOR(device) >> 4)
+#define DEVICE_ON(device)
+#define DEVICE_OFF(device)
+
X #endif /* MAJOR_NR == whatever */
X 
X #if (MAJOR_NR != SCSI_TAPE_MAJOR)
@@ -435,7 +453,7 @@
X 
X #ifndef LOCAL_END_REQUEST	/* If we have our own end_request, we do not want to include this mess */
X 
-#if ! SCSI_BLK_MAJOR(MAJOR_NR)
+#if ! SCSI_BLK_MAJOR(MAJOR_NR) && (MAJOR_NR != COMPAQ_SMART2_MAJOR)
X 
X static void end_request(int uptodate) {
X 	struct request *req = CURRENT;
diff -u --recursive --new-file v2.3.9/linux/include/linux/coda.h linux/include/linux/coda.h
--- v2.3.9/linux/include/linux/coda.h	Mon Jan 25 10:28:35 1999
+++ linux/include/linux/coda.h	Tue Jul  6 19:08:33 1999
@@ -100,22 +100,35 @@
X 
X #if defined(__linux__)
X #define cdev_t u_quad_t
+#ifndef __KERNEL__
X #if !defined(_UQUAD_T_) && (!defined(__GLIBC__) || __GLIBC__ < 2)
X #define _UQUAD_T_ 1
X typedef unsigned long long u_quad_t;
X #endif
+#else /*__KERNEL__ */
+typedef unsigned long long u_quad_t;
+#endif /* __KERNEL__ */
X #else
X #define cdev_t dev_t
X #endif
X 
X #ifdef __CYGWIN32__
-typedef unsigned char u_int8_t;
X struct timespec {
X         time_t  tv_sec;         /* seconds */
X         long    tv_nsec;        /* nanoseconds */
X };
X #endif
X 
+#ifndef __BIT_TYPES_DEFINED__
+#define __BIT_TYPES_DEFINED__
+typedef signed char	      int8_t;
+typedef unsigned char	    u_int8_t;
+typedef short		     int16_t;
+typedef unsigned short	   u_int16_t;
+typedef int		     int32_t;
+typedef unsigned int	   u_int32_t;
+#endif
+
X 
X /*
X  * Cfs constants
@@ -151,8 +164,8 @@
X struct venus_dirent {
X         unsigned long	d_fileno;		/* file number of entry */
X         unsigned short	d_reclen;		/* length of this record */
-        char 		d_type;			/* file type, see below */
-        char		d_namlen;		/* length of string in d_name */
+        unsigned char 	d_type;			/* file type, see below */
+        unsigned char	d_namlen;		/* length of string in d_name */
X         char		d_name[CODA_MAXNAMLEN + 1];/* name must be no longer than this */
X };
X #undef DIRSIZ
@@ -215,11 +228,6 @@
X #endif
X 
X 
-#ifndef __BIT_TYPES_DEFINED__
-#define u_int32_t unsigned int
-#endif
-
-
X #ifndef _VUID_T_
X #define _VUID_T_
X typedef u_int32_t vuid_t;
@@ -229,12 +237,8 @@
X #ifndef _CODACRED_T_
X #define _CODACRED_T_
X struct coda_cred {
-	vuid_t cr_uid, cr_euid, cr_suid, cr_fsuid;
-	vgid_t cr_groupid,     cr_egid, cr_sgid, cr_fsgid;
-#if   defined(CODA_SUPPORTS_SUPPLEMENTARY_GROUPS)
-	int    cr_nsupgps;
-	vgid_t cr_supgps[NGROUPS];
-#endif        /* defined(CODA_SUPPORTS_SUPPLEMENTARY_GROUPS) */
+    vuid_t cr_uid, cr_euid, cr_suid, cr_fsuid; /* Real, efftve, set, fs uid*/
+    vgid_t cr_groupid,     cr_egid, cr_sgid, cr_fsgid; /* same for groups */
X };
X #endif 
X 
@@ -246,7 +250,7 @@
X enum coda_vtype	{ C_VNON, C_VREG, C_VDIR, C_VBLK, C_VCHR, C_VLNK, C_VSOCK, C_VFIFO, C_VBAD };
X 
X struct coda_vattr {
-	int     	va_type;	/* vnode type (for create) */
+	long     	va_type;	/* vnode type (for create) */
X 	u_short		va_mode;	/* files access mode and type */
X 	short		va_nlink;	/* number of references to file */
X 	vuid_t		va_uid;		/* owner user id */
@@ -266,6 +270,15 @@
X 
X #endif 
X 
+/* structure used by CODA_STATFS for getting cache information from venus */
+struct coda_statfs {
+    int32_t f_blocks;
+    int32_t f_bfree;
+    int32_t f_bavail;
+    int32_t f_files;
+    int32_t f_ffree;
+};
+
X /*
X  * Kernel <--> Venus communications.
X  */
@@ -301,7 +314,8 @@
X #define CODA_OPEN_BY_PATH 31
X #define CODA_RESOLVE     32
X #define CODA_REINTEGRATE 33
-#define CODA_NCALLS 34
+#define CODA_STATFS	 34
+#define CODA_NCALLS 35
X 
X #define DOWNCALL(opcode) (opcode >= CODA_REPLACE && opcode <= CODA_PURGEFID)
X 
@@ -675,6 +689,16 @@
X 	int path;
X };
X 
+/* coda_statfs: NO_IN */
+struct coda_statfs_in {
+    struct coda_in_hdr in;
+};
+
+struct coda_statfs_out {
+    struct coda_out_hdr oh;
+    struct coda_statfs stat;
+};
+
X /* 
X  * Occasionally, we don't cache the fid returned by CODA_LOOKUP. 
X  * For instance, if the fid is inconsistent. 
@@ -704,7 +728,8 @@
X     struct coda_inactive_in coda_inactive;
X     struct coda_vget_in coda_vget;
X     struct coda_rdwr_in coda_rdwr;
-	struct coda_open_by_path_in coda_open_by_path;
+    struct coda_open_by_path_in coda_open_by_path;
+    struct coda_statfs_in coda_statfs;
X };
X 
X union outputArgs {
@@ -726,7 +751,8 @@
X     struct coda_purgefid_out coda_purgefid;
X     struct coda_rdwr_out coda_rdwr;
X     struct coda_replace_out coda_replace;
-	struct coda_open_by_path_out coda_open_by_path;
+    struct coda_open_by_path_out coda_open_by_path;
+    struct coda_statfs_out coda_statfs;
X };    
X 
X union coda_downcalls {
@@ -752,20 +778,11 @@
X         short out_size;         /* Maximum size of output buffer, <= 2K */
X };
X 
-#if defined(__CYGWIN32__) || defined(DJGPP)
X struct PioctlData {
-	unsigned long cmd;
X         const char *path;
X         int follow;
X         struct ViceIoctl vi;
X };
-#else
-struct PioctlData {
-        const char *path;
-        int follow;
-        struct ViceIoctl vi;
-};
-#endif
X 
X #define	CODA_CONTROL		".CONTROL"
X #define CODA_CONTROLLEN           8
diff -u --recursive --new-file v2.3.9/linux/include/linux/coda_proc.h linux/include/linux/coda_proc.h
--- v2.3.9/linux/include/linux/coda_proc.h	Mon May  4 17:09:22 1998
+++ linux/include/linux/coda_proc.h	Tue Jul  6 19:08:33 1999
@@ -98,6 +98,7 @@
X extern struct coda_vfs_stats		coda_vfs_stat;
X extern struct coda_permission_stats	coda_permission_stat;
X extern struct coda_cache_inv_stats	coda_cache_inv_stat;
+extern int				coda_upcall_timestamping;
X 
X /* reset statistics to 0 */
X void reset_coda_vfs_stats( void );
diff -u --recursive --new-file v2.3.9/linux/include/linux/coda_psdev.h linux/include/linux/coda_psdev.h
--- v2.3.9/linux/include/linux/coda_psdev.h	Wed May 12 08:41:15 1999
+++ linux/include/linux/coda_psdev.h	Tue Jul  6 19:08:33 1999
@@ -80,6 +80,7 @@
X 		 unsigned int cmd, struct PioctlData *data);
X int coda_downcall(int opcode, union outputArgs *out, struct super_block *sb);
X int venus_fsync(struct super_block *sb, struct ViceFid *fid);
+int venus_statfs(struct super_block *sb, struct statfs *sfs);
X 
X 
X /* messages between coda filesystem in kernel and Venus */
diff -u --recursive --new-file v2.3.9/linux/include/linux/cyclades.h linux/include/linux/cyclades.h
--- v2.3.9/linux/include/linux/cyclades.h	Mon May 24 22:38:07 1999
+++ linux/include/linux/cyclades.h	Tue Jul  6 19:05:48 1999
@@ -517,7 +517,7 @@
X     int num_chips;	/* 0 if card absent, -1 if Z/PCI, else Y */
X     int first_line;	/* minor number of first channel on card */
X     int bus_index;	/* address shift - 0 for ISA, 1 for PCI */
-    int	inact_ctrl;	/* FW Inactivity control - 0 disabled, 1 enabled */
+    int	intr_enabled;	/* FW Interrupt flag - 0 disabled, 1 enabled */
X };
X 
X struct cyclades_chip {
diff -u --recursive --new-file v2.3.9/linux/include/linux/file.h linux/include/linux/file.h
--- v2.3.9/linux/include/linux/file.h	Wed Jun 30 13:38:20 1999
+++ linux/include/linux/file.h	Sun Jul  4 10:18:52 1999
@@ -5,7 +5,8 @@
X #ifndef __LINUX_FILE_H
X #define __LINUX_FILE_H
X 
-extern void __fput(struct file *);
+extern void __fput(struct file *);	/* goner? */
+extern void _fput(struct file *);
X 
X /*
X  * Check whether the specified task has the fd open. Since the task
@@ -15,7 +16,7 @@
X {
X 	struct file * file = NULL;
X 
-	if (p->files && fd < p->files->max_fds)
+	if (fd < p->files->max_fds)
X 		file = p->files->fd[fd];
X 	return file;
X }
@@ -28,10 +29,17 @@
X 	struct file * file = NULL;
X 	struct files_struct *files = current->files;
X 
-	read_lock(&files->file_lock);
X 	if (fd < files->max_fds)
X 		file = files->fd[fd];
-	read_unlock(&files->file_lock);
+	return file;
+}
+
+extern inline struct file * frip(unsigned int fd)
+{
+	struct file * file = NULL;
+
+	if (fd < current->files->max_fds)
+		file = xchg(¤t->files->fd[fd], NULL);
X 	return file;
X }
X 
@@ -41,11 +49,9 @@
X 	struct files_struct *files = current->files;
X 
X 	read_lock(&files->file_lock);
-	if (fd < files->max_fds) {
-		file = files->fd[fd];
-		if (file)
-			atomic_inc(&file->f_count);
-	}
+	file = fcheck(fd);
+	if (file)
+		get_file(file);
X 	read_unlock(&files->file_lock);
X 	return file;
X }
@@ -78,7 +84,11 @@
X  * I suspect there are many other similar "optimizations" across the
X  * kernel...
X  */
-extern void fput(struct file *); 
+extern inline void fput(struct file * file)
+{
+	if (atomic_dec_and_test(&file->f_count))
+		_fput(file);
+}
X extern void put_filp(struct file *);
X 
X #endif /* __LINUX_FILE_H */
diff -u --recursive --new-file v2.3.9/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.3.9/linux/include/linux/fs.h	Wed Jun 30 13:38:20 1999
+++ linux/include/linux/fs.h	Wed Jul  7 09:20:40 1999
@@ -346,6 +346,7 @@
X 	struct file_lock	*i_flock;
X 	struct vm_area_struct	*i_mmap;
X 	struct page		*i_pages;
+	spinlock_t		i_shared_lock;
X 	struct dquot		*i_dquot[MAXQUOTAS];
X 	struct pipe_inode_info	*i_pipe;
X 
@@ -354,7 +355,7 @@
X 	unsigned int		i_flags;
X 	unsigned char		i_sock;
X 
-	int			i_writecount;
+	atomic_t		i_writecount;
X 	unsigned int		i_attr_flags;
X 	__u32			i_generation;
X 	union {
@@ -400,7 +401,7 @@
X };
X 
X struct file {
-	struct file		*f_next, **f_pprev;
+	struct list_head	f_list;
X 	struct dentry		*f_dentry;
X 	struct file_operations	*f_op;
X 	atomic_t		f_count;
@@ -417,6 +418,12 @@
X 	/* needed for tty driver, and maybe others */
X 	void			*private_data;
X };
+extern spinlock_t files_lock;
+#define file_list_lock() spin_lock(&files_lock);
+#define file_list_unlock() spin_unlock(&files_lock);
+
+#define get_file(x)	atomic_inc(&(x)->f_count)
+#define file_count(x)	atomic_read(&(x)->f_count)
X 
X extern int init_private_file(struct file *, struct dentry *, int);
X 
@@ -524,6 +531,7 @@
X 	short int		s_ibasket_count;
X 	short int		s_ibasket_max;
X 	struct list_head	s_dirty;	/* dirty inodes */
+	struct list_head	s_files;
X 
X 	union {
X 		struct minix_sb_info	minix_sb;
@@ -657,6 +665,10 @@
X extern int register_filesystem(struct file_system_type *);
X extern int unregister_filesystem(struct file_system_type *);
X 
+/* Return value for VFS lock functions - tells locks.c to lock conventionally
+ * REALLY kosha for root NFS and nfs_lock
+ */ 
+#define LOCK_USE_CLNT 1
X 
X #define FLOCK_VERIFY_READ  1
X #define FLOCK_VERIFY_WRITE 2
@@ -664,29 +676,27 @@
X extern int locks_mandatory_locked(struct inode *);
X extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t);
X 
-extern inline int locks_verify_locked(struct inode *inode)
+/*
+ * Candidates for mandatory locking have the setgid bit set
+ * but no group execute bit -  an otherwise meaningless combination.
+ */
+#define MANDATORY_LOCK(inode) \
+	(IS_MANDLOCK(inode) && ((inode)->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+
+static inline int locks_verify_locked(struct inode *inode)
X {
-	/* Candidates for mandatory locking have the setgid bit set
-	 * but no group execute bit -  an otherwise meaningless combination.
-	 */
-	if (IS_MANDLOCK(inode) &&
-	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
-		return (locks_mandatory_locked(inode));
-	return (0);
+	if (MANDATORY_LOCK(inode))
+		return locks_mandatory_locked(inode);
+	return 0;
X }
X 
X extern inline int locks_verify_area(int read_write, struct inode *inode,
X 				    struct file *filp, loff_t offset,
X 				    size_t count)
X {
-	/* Candidates for mandatory locking have the setgid bit set
-	 * but no group execute bit -  an otherwise meaningless combination.
-	 */
-	if (IS_MANDLOCK(inode) &&
-	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
-		return (locks_mandatory_area(read_write, inode, filp, offset,
-					     count));
-	return (0);
+	if (inode->i_flock && MANDATORY_LOCK(inode))
+		return locks_mandatory_area(read_write, inode, filp, offset, count);
+	return 0;
X }
X 
X 
@@ -744,8 +754,6 @@
X extern int fs_may_remount_ro(struct super_block *);
X extern int fs_may_mount(kdev_t);
X 
-extern struct file *inuse_filps;
-
X extern int try_to_free_buffers(struct page *);
X extern void refile_buffer(struct buffer_head * buf);
X 
@@ -854,6 +862,8 @@
X extern void insert_inode_hash(struct inode *);
X extern void remove_inode_hash(struct inode *);
X extern struct file * get_empty_filp(void);
+extern void file_move(struct file *f, struct list_head *list);
+extern void file_moveto(struct file *new, struct file *old);
X extern struct buffer_head * get_hash_table(kdev_t, int, int);
X extern struct buffer_head * getblk(kdev_t, int, int);
X extern void ll_rw_block(int, int, struct buffer_head * bh[]);
@@ -916,10 +926,6 @@
X 
X extern int inode_change_ok(struct inode *, struct iattr *);
X extern void inode_setattr(struct inode *, struct iattr *);
-
-/* kludge to get SCSI modules working */
-#include <linux/minix_fs.h>
-#include <linux/minix_fs_sb.h>
X 
X #endif /* __KERNEL__ */
X 
diff -u --recursive --new-file v2.3.9/linux/include/linux/i2c.h linux/include/linux/i2c.h
--- v2.3.9/linux/include/linux/i2c.h	Tue Jun 22 14:41:40 1999
+++ linux/include/linux/i2c.h	Wed Jul  7 09:20:39 1999
@@ -32,13 +32,15 @@
X struct i2c_driver;
X struct i2c_device;
X 
-#define I2C_DRIVERID_MSP3400     1
-#define I2C_DRIVERID_TUNER       2
-#define I2C_DRIVERID_VIDEOTEXT	 3
+#define I2C_DRIVERID_MSP3400    	 1
+#define I2C_DRIVERID_TUNER      	 2
+#define I2C_DRIVERID_VIDEOTEXT		 3
+#define I2C_DRIVERID_VIDEODECODER	 4
+#define I2C_DRIVERID_VIDEOENCODER	 5
X 
X #define I2C_BUSID_BT848		1	/* I2C bus on a BT848 */
X #define I2C_BUSID_PARPORT	2	/* Bit banging on a parallel port */
-
+#define I2C_BUSID_BUZ		3
X /*
X  * struct for a driver for a i2c chip (tuner, soundprocessor,
X  * videotext, ... ).
diff -u --recursive --new-file v2.3.9/linux/include/linux/i2o.h linux/include/linux/i2o.h
--- v2.3.9/linux/include/linux/i2o.h	Wed Jun  2 14:40:22 1999
+++ linux/include/linux/i2o.h	Mon Jul  5 20:09:40 1999
@@ -24,9 +24,6 @@
X  * message structures
X  */
X 
-#define    TID_SZ                                  12
-#define    FUNCTION_SZ                             8
-
X struct i2o_message
X {
X 	u32	version_size;
@@ -35,6 +32,110 @@
X 	/* List follows */
X };
X 
+/**************************************************************************
+ * HRT related constants and structures
+ **************************************************************************/
+#define I2O_BUS_LOCAL	0
+#define I2O_BUS_ISA	1
+#define I2O_BUS_EISA	2
+#define I2O_BUS_MCA	3
+#define I2O_BUS_PCI	4
+#define I2O_BUS_PCMCIA	5
+#define I2O_BUS_NUBUS	6
+#define I2O_BUS_CARDBUS	7
+#define I2O_BUS_UNKNOWN	0x80
+
+typedef struct _i2o_pci_bus {
+	u8 PciFunctionNumber;
+	u8 PciDeviceNumber;
+	u8 PciBusNumber;
+	u8 reserved;
+	u16 PciVendorID;
+	u16 PciDeviceID;
+} i2o_pci_bus, *pi2o_pci_bus;
+
+typedef struct _i2o_local_bus {
+	u16 LbBaseIOPort;
+	u16 reserved;
+	u32 LbBaseMemoryAddress;
+} i2o_local_bus, *pi2o_local_bus;
+
+typedef struct _i2o_isa_bus {
+	u16 IsaBaseIOPort;
+	u8 CSN;
+	u8 reserved;
+	u32 IsaBaseMemoryAddress;
+} i2o_isa_bus, *pi2o_isa_bus;
+
+typedef struct _i2o_eisa_bus_info {
+	u16 EisaBaseIOPort;
+	u8 reserved;
+	u8 EisaSlotNumber;
+	u32 EisaBaseMemoryAddress;
+} i2o_eisa_bus, *pi2o_eisa_bus;
+
+typedef struct _i2o_mca_bus {
+	u16 McaBaseIOPort;
+	u8 reserved;
+	u8 McaSlotNumber;
+	u32 McaBaseMemoryAddress;
+} i2o_mca_bus, *pi2o_mca_bus;
+
+typedef struct _i2o_other_bus {
+	u16 BaseIOPort;
+	u16 reserved;
+	u32 BaseMemoryAddress;
+} i2o_other_bus, *pi2o_other_bus;
+
+
+typedef struct _i2o_hrt_entry {
+	u32 adapter_id;
+	u32 parent_tid:12;
+	u32 state:4;
+	u32 bus_num:8;
+	u32 bus_type:8;
+	union {
+		i2o_pci_bus pci_bus;
+		i2o_local_bus local_bus;
+		i2o_isa_bus isa_bus;
+		i2o_eisa_bus eisa_bus;
+		i2o_mca_bus mca_bus;
+		i2o_other_bus other_bus;
+	} bus;
+} i2o_hrt_entry, *pi2o_hrt_entry;
+
+typedef struct _i2o_hrt {
+	u16 num_entries;
+	u8 entry_len;
+	u8 hrt_version;
+	u32 change_ind;
+	i2o_hrt_entry hrt_entry[1];
+} i2o_hrt, *pi2o_hrt;
+
+typedef struct _i2o_lct_entry {
+	u32 entry_size:16;
+	u32 tid:12;
+	u32 reserved:4;
+	u32 change_ind;
+	u32 device_flags;
+	u32 class_id;
+	u32 sub_class;
+	u32 user_tid:12;
+	u32 parent_tid:12;
+	u32 bios_info:8;
+	u8 identity_tag[8];
+	u32 event_capabilities;
+} i2o_lct_entry, *pi2o_lct_entry;
+
+typedef struct _i2o_lct {
+	u32 table_size:16;
+	u32 boot_tid:12;
+	u32 lct_ver:4;
+	u32 iop_flags;
+	u32 current_change_ind;
+	i2o_lct_entry lct_entry[1];
+} i2o_lct, *pi2o_lct;
+
X 
X /*
X  *	Each I2O device entity has one or more of these. There is one
@@ -85,6 +186,8 @@
X 	volatile u32 *post_port;		/* Messaging ports */
X 	volatile u32 *reply_port;
X 	volatile u32 *irq_mask;			/* Interrupt port */
+	u32 *lct;
+	u32 *hrt;
X 	u32 mem_offset;				/* MFA offset */
X 	u32 mem_phys;				/* MFA physical */
X 	u32 priv_mem;
@@ -185,18 +288,22 @@
X extern int i2o_post_this(struct i2o_controller *, int, u32 *, int);
X extern int i2o_post_wait(struct i2o_controller *, int, u32 *, int, int *, int);
X extern int i2o_issue_claim(struct i2o_controller *, int, int, int, int *);
-extern int i2o_query_scalar(struct i2o_controller *, int, int, int, int, void *,
-			    int, int *);
-extern int i2o_params_set(struct i2o_controller *c, int, int, int, int, void *,
-			  int, int *);
X 
-extern void i2o_run_queue(struct i2o_controller *);
+extern int i2o_query_scalar(struct i2o_controller *, int, int, int, int, 
+			void *, int, int *);
+extern int i2o_set_scalar(struct i2o_controller *, int, int, int, int, 
+			void *, int, int *);
+
+extern int i2o_query_table(int, struct i2o_controller *, int, int, int, int, 
+			void *, int, void *, int, int *);
+extern int i2o_clear_table(struct i2o_controller *, int, int, int, int *); 
+extern int i2o_row_add_table(struct i2o_controller *, int, int, int, int,
+			void *, int, int *);
+extern int i2o_row_delete_table(struct i2o_controller *, int, int, int, int,
+			void *, int, int *);
X 
-extern void i2o_report_status(const char *, const char *, u8, u8, u16);
-extern void report_common_status(u8);
-extern void report_lan_dsc(u16);
-
-extern u32 i2o_wait_message(struct i2o_controller *, char *);
+extern void i2o_run_queue(struct i2o_controller *);
+extern void i2o_report_status(const char *, const char *, u32 *);
X 
X extern const char *i2o_get_class_name(int);
X 
@@ -278,28 +385,12 @@
X #define    I2O_SNFORMAT_IEEE_REG128                    9
X #define    I2O_SNFORMAT_UNKNOWN2                       0xff
X 
-
-/*
- *	"Special" TID assignments
- */
-#define    I2O_IOP_TID                                 0
-#define    I2O_HOST_TID                                1
-
-
X /* Transaction Reply Lists (TRL) Control Word structure */
X 
X #define TRL_SINGLE_FIXED_LENGTH		0x00
X #define TRL_SINGLE_VARIABLE_LENGTH	0x40
X #define TRL_MULTIPLE_FIXED_LENGTH	0x80
X 
-/* LAN Class specific functions */
-
-#define    LAN_PACKET_SEND			0x3B
-#define    LAN_SDU_SEND				0x3D
-#define    LAN_RECEIVE_POST			0x3E
-#define    LAN_RESET				0x35
-#define    LAN_SUSPEND				0x37
-
X /*
X  *	Messaging API values
X  */
@@ -468,7 +559,7 @@
X #define I2O_DSC_UNSUPPORTED_VERSION            0x001A
X #define I2O_DSC_DEVICE_BUSY                    0x001B
X #define I2O_DSC_DEVICE_NOT_AVAILABLE           0x001C
-
+ 
X /* Message header defines for VersionOffset */
X #define I2OVER15	0x0001
X #define I2OVER20	0x0002
@@ -478,7 +569,9 @@
X #define SGL_OFFSET_4    (0x0040 | I2OVERSION)
X #define SGL_OFFSET_5    (0x0050 | I2OVERSION)
X #define SGL_OFFSET_6    (0x0060 | I2OVERSION)
+#define SGL_OFFSET_7    (0x0070 | I2OVERSION)
X #define SGL_OFFSET_8    (0x0080 | I2OVERSION)
+#define SGL_OFFSET_9    (0x0090 | I2OVERSION)
X #define SGL_OFFSET_10   (0x00A0 | I2OVERSION)
X 
X #define TRL_OFFSET_5    (0x0050 | I2OVERSION)
@@ -492,9 +585,6 @@
X #define MSG_LAST	0x4000
X #define MSG_REPLY	0x8000
X 
-  /* normal LAN request message MsgFlags and VersionOffset (0x1041) */
-#define LAN_MSG_REQST	(MSG_MULTI_TRANS | SGL_OFFSET_4)
-
X  /* minimum size msg */
X #define THREE_WORD_MSG_SIZE	0x00030000
X #define FOUR_WORD_MSG_SIZE	0x00040000
@@ -518,7 +608,7 @@
X #define MSG_POOL_SIZE		16384
X 
X #define I2O_POST_WAIT_OK	1
-#define I2O_POST_WAIT_TIMEOUT	-1
+#define I2O_POST_WAIT_TIMEOUT	-ETIMEDOUT
X 
X #endif /* __KERNEL__ */
X 
diff -u --recursive --new-file v2.3.9/linux/include/linux/ide.h linux/include/linux/ide.h
--- v2.3.9/linux/include/linux/ide.h	Wed Jun 30 13:38:20 1999
+++ linux/include/linux/ide.h	Wed Jul  7 09:51:41 1999
@@ -265,6 +265,7 @@
X #if FAKE_FDISK_FOR_EZDRIVE
X 	unsigned remap_0_to_1	: 1;	/* flag: partitioned with ezdrive */
X #endif /* FAKE_FDISK_FOR_EZDRIVE */
+	unsigned ata_flash	: 1;	/* 1=present, 0=default */
X 	byte		media;		/* disk, cdrom, tape, floppy, ... */
X 	select_t	select;		/* basic drive/head select reg value */
X 	byte		ctl;		/* "normal" value for IDE_CONTROL_REG */
@@ -388,6 +389,7 @@
X 	unsigned	sharing_irq: 1;	/* 1 = sharing irq with another hwif */
X 	unsigned	reset      : 1;	/* reset after probe */
X 	unsigned	autodma    : 1;	/* automatically try to enable DMA at boot */
+	unsigned	udma_four  : 1;	/* 1=ATA-66 capable, 0=default */
X 	byte		channel;	/* for dual-port chips: 0=primary, 1=secondary */
X 	struct pci_dev	*pci_dev;	/* for pci chipsets */
X 	ide_pci_devid_t	pci_devid;	/* for pci chipsets: {VID,DID} */
@@ -696,6 +698,7 @@
X int ide_wait_cmd (ide_drive_t *drive, int cmd, int nsect, int feature, int sectors, byte *buf);
X 
X void ide_delay_50ms (void);
+int ide_config_drive_speed (ide_drive_t *drive, byte speed);
X 
X /*
X  * ide_system_bus_speed() returns what we think is the system VESA/PCI
diff -u --recursive --new-file v2.3.9/linux/include/linux/isdn.h linux/include/linux/isdn.h
--- v2.3.9/linux/include/linux/isdn.h	Sun May 23 10:03:42 1999
+++ linux/include/linux/isdn.h	Thu Jul  1 10:45:57 1999
@@ -398,9 +398,6 @@
X 
X #ifdef __KERNEL__
X 
-#ifndef STANDALONE
-#include <linux/config.h>
-#endif
X #include <linux/errno.h>
X #include <linux/fs.h>
X #include <linux/major.h>
diff -u --recursive --new-file v2.3.9/linux/include/linux/isdn_timru.h linux/include/linux/isdn_timru.h
--- v2.3.9/linux/include/linux/isdn_timru.h	Sun May 23 10:03:42 1999
+++ linux/include/linux/isdn_timru.h	Wed Dec 31 16:00:00 1969
@@ -1,119 +0,0 @@
-/* isdn_timru.h
- *
- * Linux ISDN subsystem, timeout-rules for network interfaces.
- *
- * Copyright 1997       by Christian Lademann <c...@zls.de>
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
- *
- */
-
-/*
-02.06.97:cal:ISDN_TIMRU_PACKET_NONE def., ISDN_TIMRU_PACKET_* inkr.
-*/
-
-#ifndef __isdn_timru_h__
-#define __isdn_timru_h__
-
-#define	ISDN_TIMRU_PACKET_NONE		0
-#define	ISDN_TIMRU_PACKET_SKB		1
-#define	ISDN_TIMRU_PACKET_PPP		2
-#define	ISDN_TIMRU_PACKET_PPP_NO_HEADER	3
-
-#define	ISDN_TIMRU_BRINGUP		0
-#define	ISDN_TIMRU_KEEPUP_IN		1
-#define	ISDN_TIMRU_KEEPUP_OUT		2
-#define	ISDN_TIMRU_BRINGDOWN		3
-#define	ISDN_TIMRU_NUM_CHECK		4
-
-#define	ISDN_TIMRU_PROTFAM_WILDCARD	0
-#define	ISDN_TIMRU_PROTFAM_IP		1
-#define	ISDN_TIMRU_PROTFAM_PPP		2
-#define	ISDN_TIMRU_PROTFAM_IPX		3
-#define	ISDN_TIMRU_NUM_PROTFAM		4
-
-#define	ISDN_TIMRU_IP_WILDCARD		0
-#define	ISDN_TIMRU_IP_ICMP		1
-#define	ISDN_TIMRU_IP_TCP		2
-#define	ISDN_TIMRU_IP_UDP		3
-
-#define	ISDN_TIMRU_PPP_WILDCARD		0
-#define	ISDN_TIMRU_PPP_IPCP		1
-#define	ISDN_TIMRU_PPP_IPXCP		2
-#define	ISDN_TIMRU_PPP_CCP		3
-#define	ISDN_TIMRU_PPP_LCP		4
-#define	ISDN_TIMRU_PPP_PAP		5
-#define	ISDN_TIMRU_PPP_LQR		6
-#define	ISDN_TIMRU_PPP_CHAP		7
-
-typedef struct {
-	struct in_addr	saddr,		/* Source Address */
-			smask,		/* Source Subnetmask */
-			daddr,		/* Dest. Address */
-			dmask;		/* Dest. Subnetmask */
-	ushort		protocol;	/* TCP, UDP, ... */
-	union {
-		struct {
-			__u16	s_from,	/* Source Port */
-				s_to,
-				d_from,
-				d_to;
-		}		port;
-		struct {
-			__u8	from,	/* ICMP-Type */
-				to;
-		}		type;
-	}		pt;
-}	isdn_timeout_rule_ip;
-
-
-typedef struct {
-	ushort		protocol;	/* IPCP, LCP, ... */
-}	isdn_timeout_rule_ppp;
-
-
-typedef struct isdn_timeout_rule_s {
-	struct isdn_timeout_rule_s	*next,		/* Pointer to next rule */
-					*prev;		/* Pointer to previous rule */
-	ushort				type,		/* BRINGUP, KEEPUP_*, ... */
-					neg;
-	int				timeout;	/* Timeout value */
-	ushort				protfam;	/* IP, IPX, PPP, ... */
-	union {
-		isdn_timeout_rule_ip	ip;	/* IP-Rule */
-		isdn_timeout_rule_ppp	ppp;	/* PPP-Rule */
-	}				rule;	/* Prot.-specific rule */
-}	isdn_timeout_rule;
-
-
-typedef struct {
-	char			name [9];	/* Interface */
-	int			where,		/* 0/1: add to start/end of list, -1: handle default */
-				type,
-				protfam,
-				index,
-				defval;
-	isdn_timeout_rule	rule;		/* Rule */
-}	isdn_ioctl_timeout_rule;
-
-#ifdef __KERNEL__
-extern int	isdn_net_recalc_timeout(int, int, struct device *, void *, ulong);
-extern int	isdn_timru_alloc_timeout_rules(struct device *);
-extern int	isdn_timru_ioctl_add_rule(isdn_ioctl_timeout_rule *);
-extern int	isdn_timru_ioctl_del_rule(isdn_ioctl_timeout_rule *);
-extern int	isdn_timru_ioctl_get_rule(isdn_ioctl_timeout_rule *);
-#endif /* __KERNEL__ */
-
-#endif /* __isdn_timru_h__ */
diff -u --recursive --new-file v2.3.9/linux/include/linux/lp.h linux/include/linux/lp.h
--- v2.3.9/linux/include/linux/lp.h	Sat May 22 12:42:27 1999
+++ linux/include/linux/lp.h	Thu Jul  1 14:22:57 1999
@@ -21,7 +21,12 @@
X #define LP_ABORT 0x0040
X #define LP_CAREFUL 0x0080 /* obsoleted -arca */
X #define LP_ABORTOPEN 0x0100
-#define	LP_TRUST_IRQ 0x0200
+
+#define LP_TRUST_IRQ_  0x0200 /* obsolete */
+#define LP_NO_REVERSE  0x0400 /* No reverse mode available. */
+#define LP_DATA_AVAIL  0x0800 /* Data is available. */
+#define LP_HAVE_PORT_BIT   12 /* (0x1000) Port is claimed. */
+#define LP_PORT_BUSY   (1<<13) /* Reading or writing. */
X 
X /* timeout for each character.  This is relative to bus cycles -- it
X  * is the count in a busy loop.  THIS IS THE VALUE TO CHANGE if you
@@ -72,7 +77,6 @@
X #define LPGETSTATS  0x060d  /* get statistics (struct lp_stats) */
X #endif
X #define LPGETFLAGS  0x060e  /* get status flags */
-#define LPTRUSTIRQ  0x060f  /* set/unset the LP_TRUST_IRQ flag */
X 
X /* timeout for printk'ing a timeout, in jiffies (100ths of a second).
X    This is also used for re-checking error conditions if LP_ABORT is
@@ -98,7 +102,7 @@
X #ifdef LP_STATS
X #define LP_STAT(minor)	lp_table[(minor)].stats		/* statistics area */
X #endif
-#define LP_BUFFER_SIZE 256
+#define LP_BUFFER_SIZE PAGE_SIZE
X 
X #define LP_BASE(x)	lp_table[(x)].dev->port->base
X 
@@ -125,10 +129,10 @@
X 	unsigned int runchars;
X 	struct lp_stats stats;
X #endif
-	wait_queue_head_t wait_q;
+	wait_queue_head_t waitq;
X 	unsigned int last_error;
-	volatile unsigned int irq_detected:1;
-	volatile unsigned int irq_missed:1;
+	struct semaphore port_mutex;
+	wait_queue_head_t dataq;
X };
X 
X /*
@@ -173,9 +177,6 @@
X  * It is used only in the lp_init() and lp_reset() routine.
X  */
X #define LP_DELAY 	50
-
-#define LP_POLLED(minor) (lp_table[(minor)].dev->port->irq == PARPORT_IRQ_NONE)
-#define LP_PREEMPTED(minor) (lp_table[(minor)].dev->port->waithead != NULL)
X 
X /*
X  * function prototypes
diff -u --recursive --new-file v2.3.9/linux/include/linux/major.h linux/include/linux/major.h
--- v2.3.9/linux/include/linux/major.h	Wed Jun 30 13:38:20 1999
+++ linux/include/linux/major.h	Mon Jul  5 19:52:52 1999
@@ -92,8 +92,21 @@
X #define SCSI_DISK7_MAJOR	71
X 
X 
+#define LVM_BLK_MAJOR	58	/* Logical Volume Manager */
+
+#define COMPAQ_SMART2_MAJOR	72
+#define COMPAQ_SMART2_MAJOR1	73
+#define COMPAQ_SMART2_MAJOR2	74
+#define COMPAQ_SMART2_MAJOR3	75
+#define COMPAQ_SMART2_MAJOR4	76
+#define COMPAQ_SMART2_MAJOR5	77
+#define COMPAQ_SMART2_MAJOR6	78
+#define COMPAQ_SMART2_MAJOR7	79
+
X #define SPECIALIX_NORMAL_MAJOR 75
X #define SPECIALIX_CALLOUT_MAJOR 76
+
+#define LVM_CHAR_MAJOR	109	/* Logical Volume Manager */
X 
X #define I2O_MAJOR		80	/* 80->87 */
X 
diff -u --recursive --new-file v2.3.9/linux/include/linux/mm.h linux/include/linux/mm.h
--- v2.3.9/linux/include/linux/mm.h	Wed Jun 30 13:38:20 1999
+++ linux/include/linux/mm.h	Wed Jul  7 09:20:45 1999
@@ -106,7 +106,6 @@
X 	unsigned long (*wppage)(struct vm_area_struct * area, unsigned long address,
X 		unsigned long page);
X 	int (*swapout)(struct vm_area_struct *, struct page *);
-	pte_t (*swapin)(struct vm_area_struct *, unsigned long, unsigned long);
X };
X 
X /*
@@ -316,7 +315,10 @@
X 
X extern void vmtruncate(struct inode * inode, unsigned long offset);
X extern int handle_mm_fault(struct task_struct *tsk,struct vm_area_struct *vma, unsigned long address, int write_access);
-extern void make_pages_present(unsigned long addr, unsigned long end);
+extern int make_pages_present(unsigned long addr, unsigned long end);
+extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
+extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char *dst, int len);
+extern int ptrace_writedata(struct task_struct *tsk, char * src, unsigned long dst, int len);
X 
X extern int pgt_cache_water[2];
X extern int check_pgt_cache(void);
diff -u --recursive --new-file v2.3.9/linux/include/linux/mount.h linux/include/linux/mount.h
--- v2.3.9/linux/include/linux/mount.h	Sun Aug  9 12:25:12 1998
+++ linux/include/linux/mount.h	Tue Jul  6 10:18:15 1999
@@ -21,7 +21,7 @@
X 	struct file *files[MAXQUOTAS];		/* fp's to quotafiles */
X 	time_t inode_expire[MAXQUOTAS];		/* expiretime for inode-quota */
X 	time_t block_expire[MAXQUOTAS];		/* expiretime for block-quota */
-	char rsquash[MAXQUOTAS];		/* for quotas threath root as any other user */
+	char rsquash[MAXQUOTAS];		/* for quotas treat root as any other user */
X };
X 
X struct vfsmount
diff -u --recursive --new-file v2.3.9/linux/include/linux/parport.h linux/include/linux/parport.h
--- v2.3.9/linux/include/linux/parport.h	Tue Jun 22 14:42:44 1999
+++ linux/include/linux/parport.h	Wed Jul  7 09:21:33 1999
@@ -20,8 +20,6 @@
X #define PARPORT_CONTROL_AUTOFD    0x2
X #define PARPORT_CONTROL_INIT      0x4
X #define PARPORT_CONTROL_SELECT    0x8
-#define PARPORT_CONTROL_INTEN     0x10
-#define PARPORT_CONTROL_DIRECTION 0x20
X 
X #define PARPORT_STATUS_ERROR      0x8
X #define PARPORT_STATUS_SELECT     0x10
@@ -43,28 +41,43 @@
X 	PARPORT_CLASS_SCANNER,
X 	PARPORT_CLASS_DIGCAM,
X 	PARPORT_CLASS_OTHER,            /* Anything else */
-	PARPORT_CLASS_UNSPEC            /* No CLS field in ID */
+	PARPORT_CLASS_UNSPEC,           /* No CLS field in ID */
+	PARPORT_CLASS_SCSIADAPTER
X } parport_device_class;
X 
-/* The "modes" entry in parport is a bit field representing the following
- * modes.
- * Note that PARPORT_MODE_PCECPEPP is for the SMC EPP+ECP mode which is NOT
- * 100% compatible with EPP.
- */
-#define PARPORT_MODE_PCSPP	        0x0001
-#define PARPORT_MODE_PCPS2		0x0002
-#define PARPORT_MODE_PCEPP		0x0004
-#define PARPORT_MODE_PCECP		0x0008
-#define PARPORT_MODE_PCECPEPP		0x0010
-#define PARPORT_MODE_PCECR		0x0020  /* ECR Register Exists */
-#define PARPORT_MODE_PCECPPS2		0x0040
+/* The "modes" entry in parport is a bit field representing the
+   capabilities of the hardware. */
+#define PARPORT_MODE_PCSPP	(1<<0) /* IBM PC registers available. */
+#define PARPORT_MODE_TRISTATE	(1<<1) /* Can tristate. */
+#define PARPORT_MODE_EPP	(1<<2) /* Hardware EPP. */
+#define PARPORT_MODE_ECP	(1<<3) /* Hardware ECP. */
+#define PARPORT_MODE_COMPAT	(1<<4) /* Hardware 'printer protocol'. */
+#define PARPORT_MODE_DMA	(1<<5) /* Hardware can DMA. */
+
+/* IEEE1284 modes: 
+   Nibble mode, byte mode, ECP, ECPRLE and EPP are their own
+   'extensibility request' values.  Others are special.
+   'Real' ECP modes must have the IEEE1284_MODE_ECP bit set.  */
+#define IEEE1284_MODE_NIBBLE             0
+#define IEEE1284_MODE_BYTE              (1<<0)
+#define IEEE1284_MODE_COMPAT            (1<<8)
+#define IEEE1284_MODE_BECP              (1<<9) /* Bounded ECP mode */
+#define IEEE1284_MODE_ECP               (1<<4)
+#define IEEE1284_MODE_ECPRLE            (IEEE1284_MODE_ECP | (1<<5))
+#define IEEE1284_MODE_ECPSWE            (1<<10) /* Software-emulated */
+#define IEEE1284_MODE_EPP               (1<<6)
+#define IEEE1284_MODE_EPPSL             (1<<11) /* EPP 1.7 */
+#define IEEE1284_MODE_EPPSWE            (1<<12) /* Software-emulated */
+#define IEEE1284_DEVICEID               (1<<2)  /* This is a flag */
X 
X /* The rest is for the kernel only */
X #ifdef __KERNEL__
X 
+#include <linux/wait.h>
X #include <asm/system.h>
X #include <asm/ptrace.h>
X #include <asm/spinlock.h>
+#include <asm/semaphore.h>
X #include <linux/proc_fs.h>
X #include <linux/config.h>
X 
@@ -72,59 +85,92 @@
X 
X /* Define this later. */
X struct parport;
+struct pardevice;
X 
X struct pc_parport_state {
X 	unsigned int ctr;
X 	unsigned int ecr;
X };
X 
+struct ax_parport_state {
+	unsigned int ctr;
+	unsigned int ecr;
+	unsigned int dcsr;
+};
+
+/* used by both parport_amiga and parport_mfc3 */
+struct amiga_parport_state {
+       unsigned char data;     /* ciaa.prb */
+       unsigned char datadir;  /* ciaa.ddrb */
+       unsigned char status;   /* ciab.pra & 7 */
+       unsigned char statusdir;/* ciab.ddrb & 7 */
+};
+
X struct parport_state {
X 	union {
X 		struct pc_parport_state pc;
X 		/* ARC has no state. */
-		/* AX uses same state information as PC */
+		struct ax_parport_state ax;
+		struct amiga_parport_state amiga;
+		/* Atari has not state. */
X 		void *misc; 
X 	} u;
X };
X 
X struct parport_operations {
+	/* IBM PC-style virtual registers. */
X 	void (*write_data)(struct parport *, unsigned char);
X 	unsigned char (*read_data)(struct parport *);
+
X 	void (*write_control)(struct parport *, unsigned char);
X 	unsigned char (*read_control)(struct parport *);
-	unsigned char (*frob_control)(struct parport *, unsigned char mask, unsigned char val);
-	void (*write_econtrol)(struct parport *, unsigned char);
-	unsigned char (*read_econtrol)(struct parport *);
-	unsigned char (*frob_econtrol)(struct parport *, unsigned char mask, unsigned char val);
-	void (*write_status)(struct parport *, unsigned char);
+	unsigned char (*frob_control)(struct parport *, unsigned char mask,
+				      unsigned char val);
+
X 	unsigned char (*read_status)(struct parport *);
-	void (*write_fifo)(struct parport *, unsigned char);
-	unsigned char (*read_fifo)(struct parport *);
X 
-	void (*change_mode)(struct parport *, int);
+	/* IRQs. */
+	void (*enable_irq)(struct parport *);
+	void (*disable_irq)(struct parport *);
X 
-	void (*epp_write_data)(struct parport *, unsigned char);
-	unsigned char (*epp_read_data)(struct parport *);
-	void (*epp_write_addr)(struct parport *, unsigned char);
-	unsigned char (*epp_read_addr)(struct parport *);
-	int (*epp_check_timeout)(struct parport *);
-	size_t (*epp_write_block)(struct parport *, void *, size_t);
-	size_t (*epp_read_block)(struct parport *, void *, size_t);
+	/* Data direction. */
+	void (*data_forward) (struct parport *);
+	void (*data_reverse) (struct parport *);
X 
-	int (*ecp_write_block)(struct parport *, void *, size_t, void (*fn)(struct parport *, void *, size_t), void *);
-	int (*ecp_read_block)(struct parport *, void *, size_t, void (*fn)(struct parport *, void *, size_t), void *);
+	/* For core parport code. */
+	void (*interrupt)(int, void *, struct pt_regs *); /* ? */
X 
-	void (*init_state)(struct parport_state *);
+	void (*init_state)(struct pardevice *, struct parport_state *);
X 	void (*save_state)(struct parport *, struct parport_state *);
X 	void (*restore_state)(struct parport *, struct parport_state *);
X 
-	void (*enable_irq)(struct parport *);
-	void (*disable_irq)(struct parport *);
-	void (*interrupt)(int, void *, struct pt_regs *);
-
X 	void (*inc_use_count)(void);
X 	void (*dec_use_count)(void);
-	void (*fill_inode)(struct inode *inode, int fill);
+	void (*fill_inode)(struct inode *inode, int fill); /* ? */
+
+	/* Block read/write */
+	size_t (*epp_write_data) (struct parport *port, const void *buf,
+				  size_t len, int flags);
+	size_t (*epp_read_data) (struct parport *port, void *buf, size_t len,
+				 int flags);
+	size_t (*epp_write_addr) (struct parport *port, const void *buf,
+				  size_t len, int flags);
+	size_t (*epp_read_addr) (struct parport *port, void *buf, size_t len,
+				 int flags);
+
+	size_t (*ecp_write_data) (struct parport *port, const void *buf,
+				  size_t len, int flags);
+	size_t (*ecp_read_data) (struct parport *port, void *buf, size_t len,
+				 int flags);
+	size_t (*ecp_write_addr) (struct parport *port, const void *buf,
+				  size_t len, int flags);
+
+	size_t (*compat_write_data) (struct parport *port, const void *buf,
+				     size_t len, int flags);
+	size_t (*nibble_read_data) (struct parport *port, void *buf,
+				    size_t len, int flags);
+	size_t (*byte_read_data) (struct parport *port, void *buf,
+				  size_t len, int flags);
X };
X 
X struct parport_device_info {
@@ -152,6 +198,7 @@
X struct pardevice {
X 	const char *name;
X 	struct parport *port;
+	int daisy;
X 	int (*preempt)(void *);
X 	void (*wakeup)(void *);
X 	void *private;
@@ -163,34 +210,66 @@
X 	wait_queue_head_t wait_q;
X 	unsigned long int time;
X 	unsigned long int timeslice;
+	volatile long int timeout;
X 	unsigned int waiting;
X 	struct pardevice *waitprev;
X 	struct pardevice *waitnext;
-        void * sysctl_table;
+	void * sysctl_table;
X };
X 
-/* Directory information for the /proc interface */
-struct parport_dir {
-	struct proc_dir_entry *entry;    /* Directory /proc/parport/X     */
-	struct proc_dir_entry *irq;	/*		.../irq           */
-	struct proc_dir_entry *devices;  /*		.../devices       */
-	struct proc_dir_entry *hardware; /*		.../hardware      */
-	struct proc_dir_entry *probe;	 /*		.../autoprobe	  */
-	char name[4];
+/* IEEE1284 information */
+
+/* IEEE1284 phases */
+enum ieee1284_phase {
+	IEEE1284_PH_FWD_DATA,
+	IEEE1284_PH_FWD_IDLE,
+	IEEE1284_PH_TERMINATE,
+	IEEE1284_PH_NEGOTIATION,
+	IEEE1284_PH_HBUSY_DNA,
+	IEEE1284_PH_REV_IDLE,
+	IEEE1284_PH_HBUSY_DAVAIL,
+	IEEE1284_PH_REV_DATA,
+	IEEE1284_PH_ECP_SETUP,
+	IEEE1284_PH_ECP_FWD_TO_REV,
+	IEEE1284_PH_ECP_REV_TO_FWD
+};
+struct ieee1284_info {
+	int mode;
+	volatile enum ieee1284_phase phase;
+	struct semaphore irq;
X };
X 
X /* A parallel port */
X struct parport {
X 	unsigned long base;	/* base address */
-	unsigned long base_hi;	/* base address (ECR) */
+	unsigned long base_hi;  /* base address (hi - ECR) */
X 	unsigned int size;	/* IO extent */
X 	const char *name;
+	unsigned int modes;
X 	int irq;		/* interrupt (or -1 for none) */
X 	int dma;
-	unsigned int modes;
+	int muxport;		/* which muxport (if any) this is */
+	int portnum;		/* which physical parallel port (not mux) */
+
+	struct parport *physport;
+				/* If this is a non-default mux
+				   parport, i.e. we're a clone of a real
+				   physical port, this is a pointer to that
+				   port. The locking is only done in the
+				   real port.  For a clone port, the
+				   following structure members are
+				   meaningless: devices, cad, muxsel,
+				   waithead, waittail, flags, pdir,
+				   ieee1284, *_lock.
+
+				   It this is a default mux parport, or
+				   there is no mux involved, this points to
+				   ourself. */
X 
X 	struct pardevice *devices;
X 	struct pardevice *cad;	/* port owner */
+	int daisy;		/* currently selected daisy addr */
+	int muxsel;		/* currently selected mux port */
X 
X 	struct pardevice *waithead;
X 	struct pardevice *waittail;
@@ -198,8 +277,9 @@
X 	struct parport *next;
X 	unsigned int flags;
X 
-	struct parport_dir pdir;
-	struct parport_device_info probe_info; 
+	void *sysctl_table;
+	struct parport_device_info probe_info[5]; /* 0-3 + non-IEEE1284.3 */
+	struct ieee1284_info ieee1284;
X 
X 	struct parport_operations *ops;
X 	void *private_data;     /* for lowlevel driver */
@@ -208,9 +288,12 @@
X 	spinlock_t pardevice_lock;
X 	spinlock_t waitlist_lock;
X 	rwlock_t cad_lock;
-        void * sysctl_table;
+
+	int spintime;
X };
X 
+#define DEFAULT_SPIN_TIME 500 /* us */
+
X struct parport_driver {
X 	const char *name;
X 	void (*attach) (struct parport *);
@@ -218,11 +301,10 @@
X 	struct parport_driver *next;
X };
X 
-/* parport_register_port registers a new parallel port at the given address (if
- * one does not already exist) and returns a pointer to it.  This entails
- * claiming the I/O region, IRQ and DMA.
- * NULL is returned if initialisation fails. 
- */
+/* parport_register_port registers a new parallel port at the given
+   address (if one does not already exist) and returns a pointer to it.
+   This entails claiming the I/O region, IRQ and DMA.  NULL is returned
+   if initialisation fails. */
X struct parport *parport_register_port(unsigned long base, int irq, int dma,
X 				      struct parport_operations *ops);
X 
@@ -236,12 +318,12 @@
X /* Unregister a port. */
X extern void parport_unregister_port(struct parport *port);
X 
-/* parport_in_use returns nonzero if there are devices attached to a port. */
+/* parport_in_use returns nonzero if there are devices attached to a
+   port. */
X #define parport_in_use(x)  ((x)->devices != NULL)
X 
-/* parport_enumerate returns a pointer to the linked list of all the ports
- * in this machine.
- */
+/* parport_enumerate returns a pointer to the linked list of all the
+   ports in this machine. */
X struct parport *parport_enumerate(void);
X 
X /* Register a new high-level driver. */
@@ -250,13 +332,12 @@
X /* Unregister a high-level driver. */
X extern void parport_unregister_driver (struct parport_driver *);
X 
-/* parport_register_device declares that a device is connected to a port, and 
- * tells the kernel all it needs to know.  
- * pf is the preemption function (may be NULL for no callback)
- * kf is the wake-up function (may be NULL for no callback)
- * irq_func is the interrupt handler (may be NULL for no interrupts)
- * handle is a user pointer that gets handed to callback functions. 
- */
+/* parport_register_device declares that a device is connected to a
+   port, and tells the kernel all it needs to know.  pf is the
+   preemption function (may be NULL for no callback) kf is the wake-up
+   function (may be NULL for no callback) irq_func is the interrupt
+   handler (may be NULL for no interrupts) handle is a user pointer
+   that gets handed to callback functions.  */
X struct pardevice *parport_register_device(struct parport *port, 
X 			  const char *name,
X 			  int (*pf)(void *), void (*kf)(void *),
@@ -266,30 +347,29 @@
X /* parport_unregister unlinks a device from the chain. */
X extern void parport_unregister_device(struct pardevice *dev);
X 
-/* parport_claim tries to gain ownership of the port for a particular driver.
- * This may fail (return non-zero) if another driver is busy.  If this
- * driver has registered an interrupt handler, it will be enabled. 
- */
+/* parport_claim tries to gain ownership of the port for a particular
+   driver.  This may fail (return non-zero) if another driver is busy.
+   If this driver has registered an interrupt handler, it will be
+   enabled.  */
X extern int parport_claim(struct pardevice *dev);
X 
-/* parport_claim_or_block is the same, but sleeps if the port cannot be 
-   claimed.  Return value is 1 if it slept, 0 normally and -errno on error.  */
+/* parport_claim_or_block is the same, but sleeps if the port cannot
+   be claimed.  Return value is 1 if it slept, 0 normally and -errno
+   on error.  */
X extern int parport_claim_or_block(struct pardevice *dev);
X 
-/* parport_release reverses a previous parport_claim.  This can never fail, 
- * though the effects are undefined (except that they are bad) if you didn't
- * previously own the port.  Once you have released the port you should make
- * sure that neither your code nor the hardware on the port tries to initiate
- * any communication without first re-claiming the port.
- * If you mess with the port state (enabling ECP for example) you should
- * clean up before releasing the port. 
- */
+/* parport_release reverses a previous parport_claim.  This can never
+   fail, though the effects are undefined (except that they are bad)
+   if you didn't previously own the port.  Once you have released the
+   port you should make sure that neither your code nor the hardware
+   on the port tries to initiate any communication without first
+   re-claiming the port.  If you mess with the port state (enabling
+   ECP for example) you should clean up before releasing the port. */
X 
X extern void parport_release(struct pardevice *dev);
X 
X /* parport_yield relinquishes the port if it would be helpful to other
- * drivers.  The return value is the same as for parport_claim.
- */
+   drivers.  The return value is the same as for parport_claim.  */
X extern __inline__ int parport_yield(struct pardevice *dev)
X {
X 	unsigned long int timeslip = (jiffies - dev->time);
@@ -300,8 +380,7 @@
X }
X 
X /* parport_yield_blocking is the same but uses parport_claim_or_block
- * instead of parport_claim.
- */
+   instead of parport_claim.  */
X extern __inline__ int parport_yield_blocking(struct pardevice *dev)
X {
X 	unsigned long int timeslip = (jiffies - dev->time);
@@ -311,37 +390,87 @@
X 	return parport_claim_or_block(dev);
X }
X 
-/*
- * Lowlevel drivers _can_ call this support function to handle irqs.
- */
-extern __inline__ void parport_generic_irq(int irq, struct parport *port,
-					   struct pt_regs *regs)
-{
-	read_lock(&port->cad_lock);
-	if (!port->cad)
-		goto out_unlock;
-	if (port->cad->irq_func)
-		port->cad->irq_func(irq, port->cad->private, regs);
-	else
-		printk(KERN_ERR "%s: irq%d happened with irq_func NULL "
-		       "with %s as cad!\n", port->name, irq, port->cad->name);
- out_unlock:
-	read_unlock(&port->cad_lock);
-}
-
X /* Flags used to identify what a device does. */
X #define PARPORT_DEV_TRAN		0	/* WARNING !! DEPRECATED !! */
X #define PARPORT_DEV_LURK		(1<<0)	/* WARNING !! DEPRECATED !! */
X #define PARPORT_DEV_EXCL		(1<<1)	/* Need exclusive access. */
X 
-#define PARPORT_FLAG_COMA_		(1<<0)  /* No longer used. */
X #define PARPORT_FLAG_EXCL		(1<<1)	/* EXCL driver registered. */
X 
X extern int parport_parse_irqs(int, const char *[], int irqval[]);
-extern int parport_parse_dmas(int, const char *[], int irqval[]);
-extern int parport_ieee1284_nibble_mode_ok(struct parport *, unsigned char);
-extern int parport_wait_peripheral(struct parport *, unsigned char, unsigned
-				   char);
+extern int parport_parse_dmas(int, const char *[], int dmaval[]);
+
+/* IEEE1284 functions */
+extern void parport_ieee1284_interrupt (int, void *, struct pt_regs *);
+extern int parport_negotiate (struct parport *, int mode);
+extern ssize_t parport_write (struct parport *, const void *buf, size_t len);
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 31'
echo 'File patch-2.3.10 is continued in part 32'
echo 32 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 37 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 37; 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
-}
-
-static int ss_compare_atn(const void *a, const void *b)
-{
-	SYMBOL *c = (SYMBOL *) a;
-	SYMBOL *d = (SYMBOL *) b;
-	int i;
-
-	/* obsolete symbols to the top */
-	if (c->keep != d->keep)
-		return(d->keep - c->keep);
-	if (c->address > d->address)
-		return(1);
-	if (c->address < d->address)
-		return(-1);
-	if (c->type > d->type)
-		return(1);
-	if (c->type < d->type)
-		return(-1);
-	if ((i = strcmp(c->name, d->name)))
-		return(i);
-	return(0);
-}
-
-/* Sort a symbol set by address, type and name */
-void ss_sort_atn(SYMBOL_SET *ss)
-{
-	if (debug)
-		fprintf(stderr, "DEBUG: sorting symbols for %s (atn)\n",
-			ss->source);
-	qsort((char *) ss->symbol, (unsigned) ss->used,
-		sizeof(*(ss->symbol)), ss_compare_atn);
-	ss_compress(ss);
-}
-
-static int ss_compare_na(const void *a, const void *b)
-{
-	SYMBOL *c = (SYMBOL *) a;
-	SYMBOL *d = (SYMBOL *) b;
-	int i;
-
-	/* obsolete symbols to the top */
-	if (c->keep != d->keep)
-		return(d->keep - c->keep);
-	if ((i = strcmp(c->name, d->name)))
-		return(i);
-	if (c->address > d->address)
-		return(1);
-	if (c->address < d->address)
-		return(-1);
-	return(0);
-}
-
-/* Sort a symbol set by name and address, drop duplicates.  There should be
- * no duplicates but I have seen duplicates in ksyms on 2.0.35.
- */
-void ss_sort_na(SYMBOL_SET *ss)
-{
-	int i;
-	SYMBOL *s;
-	if (debug)
-		fprintf(stderr, "DEBUG: sorting symbols for %s (na)\n",
-			ss->source);
-	qsort((char *) ss->symbol, (unsigned) ss->used,
-		sizeof(*(ss->symbol)), ss_compare_na);
-	ss_compress(ss);
-	s = ss->symbol;
-	for (i = 0; i < ss->used-1; ++i) {
-		if (strcmp(s->name, (s+1)->name) == 0 &&
-		    s->address == (s+1)->address) {
-			if (s->type != ' ')
-				(s+1)->keep = 0;
-			else
-				s->keep = 0;
-		}
-		++s;
-	}
-	qsort((char *) ss->symbol, (unsigned) ss->used,
-		sizeof(*(ss->symbol)), ss_compare_na);
-	ss_compress(ss);
-}
-
-/* Copy a symbol set, including all its strings */
-SYMBOL_SET *ss_copy(const SYMBOL_SET *ss)
-{
-	SYMBOL_SET *ssc;
-	if (debug > 3)
-		fprintf(stderr,
-			"DEBUG: ss_copy %s\n", ss->source);
-	ssc = malloc(sizeof(*ssc));
-	if (!ssc)
-		malloc_error("copy ssc");
-	ss_init(ssc, ss->source);
-	ssc->used = ss->used;
-	ssc->alloc = ss->used;	/* shrink the copy */
-	ssc->symbol = malloc(ssc->used*sizeof(*(ssc->symbol)));
-	if (!(ssc->symbol))
-		malloc_error("copy ssc symbols");
-	memcpy(ssc->symbol, ss->symbol, ssc->used*sizeof(*(ssc->symbol)));
-	return(ssc);
-}
-
-/* Convert version number to major, minor string.  */
-static const char *format_Version(elf_addr_t Version)
-{
-	static char string[12];	/* 255.255.255\0 worst case */
-	snprintf(string, sizeof(string), "%d.%d.%d",
-		(int) ((Version >> 16) & 0xff),
-		(int) ((Version >> 8) & 0xff),
-		(int) ((Version) & 0xff));
-	return(string);
-}
-
-/* Save version number.  The "address" is the version number, the "symbol" is
- * the source of the version.
- */
-void add_Version(const char *version, const char *source)
-{
-	static char const procname[] = "add_Version";
-	int i = atoi(version);
-	if (debug > 1)
-		fprintf(stderr, "DEBUG: %s %s %s %s\n",
-			procname, source, version, format_Version(i));
-	add_symbol_n(&ss_Version, i, 'V', 1, source);
-}
-
-/* Extract Version_ number from a symbol set and save it.  */
-void extract_Version(SYMBOL_SET *ss)
-{
-	int i = 0;
-	SYMBOL *s;
-
-	s = find_symbol_name(ss, "Version_", &i);
-	if (!s && i < ss->used)
-		s = ss->symbol+i;	/* first symbol after "Version_" */
-	if (!s || strncmp(s->name, "Version_", 8))
-		return;
-	add_Version(s->name+8, ss->source);
-}
-
-/* Compare all extracted Version numbers.  Silent unless there is a problem. */
-void compare_Version(void)
-{
-	int i = 0;
-	SYMBOL *s, *s0;
-	static int prev_used = 0;
-
-	if (!ss_Version.used)
-		return;
-	/* Only check if the Version table has changed in size */
-	if (prev_used == ss_Version.used)
-		return;
-
-	ss_sort_na(&ss_Version);
-	s0 = s = ss_Version.symbol;
-	if (debug)
-		fprintf(stderr, "DEBUG: Version %s\n",
-			format_Version(s0->address));
-	for (i = 0; i < ss_Version.used; ++i, ++s) {
-		if (s->address != s0->address) {
-			fprintf(stderr,
-				"Version mismatch error.  %s says %s, ",
-				s0->name,
-				format_Version(s0->address));
-			fprintf(stderr,
-				"%s says %s.  Expect lots of address "
-				"mismatches.\n",
-				s->name,
-				format_Version(s->address));
-			++errors;
-		}
-	}
-	prev_used = ss_Version.used;
-}
diff -u --recursive --new-file v2.3.9/linux/scripts/ver_linux linux/scripts/ver_linux
--- v2.3.9/linux/scripts/ver_linux	Fri Apr 16 08:20:23 1999
+++ linux/scripts/ver_linux	Mon Jul  5 20:49:52 1999
@@ -21,10 +21,12 @@
X ps --version 2>&1 | awk 'NR==1{print "Procps                ", $NF}'
X mount --version | awk -F\- '{print "Mount                 ", $NF}'
X hostname -V 2>&1 | awk 'NR==1{print "Net-tools             ", $NF}'
+# Kbd needs 'loadkeys -h',
X loadkeys -h 2>&1 | awk \
-'(NR==1 && $3) {ver=$3}
- (NR==2 && $1 ~ /console-tools/) {print "Console-tools         ",$3; done=1}
- END {if (!done) print "Kbd                   ",ver}'
+'(NR==1 && ($3 !~ /option/)) {print "Kbd                   ", $3}'
+# while console-tools needs 'loadkeys -V'.
+loadkeys -V 2>&1 | awk \
+'(NR==1 && ($2 ~ /console-tools/)) {print "Console-tools         ", $3}'
X expr --v | awk '{print "Sh-utils              ", $NF}'
X X=`cat /proc/modules | sed -e "s/ .*$//"`
X echo "Modules Loaded         "$X
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
echo 'File patch-2.3.10 is complete' &&
chmod 644 patch-2.3.10 ||
echo 'restore of patch-2.3.10 failed'
Cksum="`cksum < 'patch-2.3.10'`"
if ! test "4058405324 2078222" = "$Cksum"
then
	echo 'patch-2.3.10: original Checksum 4058405324 2078222, 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.'
exit 0
#!/bin/sh
# this is part 35 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 35; 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
-endif
-
-CFLAGS += -DDEF_CODE_BYTES=$(strip $(DEF_CODE_BYTES))
-
-OBJECTS = io.o ksyms.o ksymoops.o map.o misc.o object.o oops.o re.o symbol.o
-
-all: 	$(PROGS)
-
-:	$(OBJECTS)
-
-$(OBJECTS): $(DEFS)
-
-$(PROGS): %: %.o $(DEFS) $(OBJECTS)
-	$(CC) $(OBJECTS) $(CFLAGS) -lbfd -liberty -o $@
-	-@size $@
-
-clean:
-	rm -f core *.o $(PROGS)
diff -u --recursive --new-file v2.3.9/linux/scripts/ksymoops/README linux/scripts/ksymoops/README
--- v2.3.9/linux/scripts/ksymoops/README	Mon Mar 15 16:12:14 1999
+++ linux/scripts/ksymoops/README	Thu Jul  1 10:54:31 1999
@@ -1,399 +1,7 @@
-  ksymoops.
+ksymoops has been removed from the kernel.  It was always meant to be a
+free standing utility, not linked to any particular kernel version.
+The latest version can be found in ftp://ftp.ocs.com.au/pub/ksymoops,
+together with patches to other utilities in order to give more accurate
+Oops debugging.
X 
-  Read a kernel Oops file and make the best stab at converting the code to
-  instructions and mapping stack values to kernel symbols.
-
-  Copyright Keith Owens <ka...@ocs.com.au>.
-  Released under the GNU Public Licence, Version 2.
-
-  To compile, simply type "make" in the ksymoops directory.
-
-  TESTERS WANTED.
-
-  ksymoops handles ix86.  It appears to handle Alpha, Sparc, M68K, PPC,
-  MIPS but I have no machine to test on.  I would appreciate feedback
-  from users of non ix86 machines.  In particular, it would be nice if
-  you could run
-
-   ksymoops -VMO -k /proc/ksyms -dd <oops.file >/tmp/ksymoops.log 2>&1
-
-  and mail /tmp/ksymoops.log to ka...@ocs.com.au
-
-  TODO:
-  Clean up these docs.
-  Tweak System.map to include arch information.
-  Tweak modutils to log at least one symbol for each module loaded,
-  otherwise they are invisible to ksymoops.  Also arch and version data.
-  Include sparc/sparc64 patches from Jakub Jelinek <j...@sunsite.mff.cuni.cz>.
-  Add object format override for sparc/soparc64 or any cross platform
-  oops debugging.
-
-  Mon Jan  4 09:48:13 EST 1999
-  Version 0.6e
-  Added to kernel.
-  Add ARM support.
-  Typo in oops_code.
-  Add -c option.
-  Add -1 option.
-  Report if options were specified or defaulted.
-  Remove false warnings when comparing ksyms and lsmod.
-  Performance inprovements.
-
-  Wed Oct 28 23:14:55 EST 1998
-  Version 0.5
-  No longer read vmlinux by default, it only duplicates System.map.
-
-  Wed Oct 28 13:46:39 EST 1998
-  Version 0.4
-  Split into separate sources.
-
-  Mon Oct 26 00:01:47 EST 1998
-  Version 0.3c
-  Add alpha (arm) processing.
-
-  Mon Oct 26 00:01:47 EST 1998
-  Version 0.3b
-  Add sparc processing.
-  Handle kernel symbol versions.
-
-  Fri Oct 23 13:11:20 EST 1998
-  Version 0.3
-  Add -follow to find command for people who use symlinks to modules.
-  Add Version_ checking.
-
-  Thu Oct 22 22:28:30 EST 1998
-  Version 0.2.
-  Generalise text prefix handling.
-  Handle messages on Code: line.
-  Format addresses with leading zeroes.
-  Minor bug fixes.
-
-  Wed Oct 21 23:28:48 EST 1998
-  Version 0.1.  Rewrite from scratch in C.
-
-  CREDITS.
-  Oops disassembly based on ksymoops.cc,
-    Copyright (C) 1995 Greg McGary <g...@magilla.cichlid.com>
-  m68k code based on ksymoops.cc changes by
-    Andreas Schwab <sch...@issan.informatik.uni-dortmund.de>
-
-  This code subsumes the Perl script make_System.map.pl which is no longer
-  supported.
-
-  Why another ksymoops I hear you ask?  Various complaints about
-  ksymoops.cc -
-
-  * It requires C++.
-  * It has hard wired limitations on the number of symbols.
-  * It does not handle modules at all.
-  * Very rigid requirements on the format of input, especially the Oops
-    log.
-  * No cross checking between ksyms, modules, System.map etc.
-  * Very little error checking, diagnostics are not suitable for
-    beginners.
-  * It only prints the trace and decoded code, users have to manually
-    extract the other lines from the Oops.
-  * Gives up on the slightest problem.
-  * Only handles i386 and possibly m68k.  The code is difficult to extend
-    to other architectures.
-  * Stops after the first Oops, you have to manually extract each one and
-    run through ksymoops one at a time.
-
-  This version is -
-  * C.
-  * No hard wired limitations (malloc as far as the eye can see).
-  * Handles modules by default.
-  * Uses regular pattern matching so it is a lot more forgiving about
-    input formats.
-  * By default, cross checks ksyms, modules, System.map and vmlinux.
-  * Lots of diagnostics and error checking.
-  * Prints all relevant lines for a complete Oops report.
-  * Tries to provide output no matter how bad the input is.  The level of
-     progress and error reporting is aimed at beginners.
-  * Handles i386, alpha, sparc, sparc64, m68k.  It is a lot easier to extend
-    to other architectures (patches and/or sample data gratefully accepted).
-  * Handles all Oops in the input file(s).
-
-
-  Usage:	ksymoops
-		  [-v vmlinux]	Where to read vmlinux
-		  [-V]		No vmlinux is available
-		  [-o object_dir]	Directory containing modules
-		  [-O]		No modules is available
-		  [-k ksyms]	Where to read ksyms
-		  [-K]		No ksyms is available
-		  [-l lsmod]	Where to read lsmod
-		  [-L]		No lsmod is available
-		  [-m system.map]	Where to read System.map
-		  [-M]		No System.map is available
-		  [-s save.map]	Save consolidated map
-		  [-c code_bytes]	How many bytes in each unit of code
-		  [-1]		One shot toggle (exit after first Oops)
-		  [-d]		Increase debug level by 1
-		  [-h]		Print help text
-		  Oops.file	Oops to decode
-
-	  All flags can occur more than once.  With the exception of -o
-	  and -d which are cumulative, the last occurrence of each flag is
-	  used.  Note that "-v my.vmlinux -V" will be taken as "No vmlinux
-	  available" but "-V -v my.vmlinux" will read my.vmlinux.  You
-	  will be warned about such combinations.
-
-	  Each occurrence of -d increases the debug level.
-
-	  Each -o flag can refer to a directory or to a single object
-	  file.  If a directory is specified then all *.o files in that
-	  directory and its subdirectories are assumed to be modules.
-
-	  If any of the vmlinux, object_dir, ksyms or system.map options
-	  contain the string *r (*m, *n, *s) then it is replaced at run time
-	  by the current value of `uname -r` (-m, -n, -s).
-
-	  The defaults can be changed in the Makefile, typical options are
-
-	  Defaults:	  -V
-			  -o /lib/modules/%r
-			  -k /proc/ksyms
-			  -l /proc/modules
-			  -m /usr/src/linux/System.map
-			  -c 1
-			  Oops report is read from stdin
-
-  Note:	  Unless you tell ksymoops *NOT* to read a particular file, it
-	  will try to read and reconcile almost all possible sources of kernel
-	  symbol information.  This is intended for beginners, they just
-	  type
-
-	    ksymoops < /var/log/syslog
-
-	  no thinking required.  Experts can point at different files or
-	  suppress the input from selected files.  For example, if you
-	  save /proc/ksyms before doing a test that creates an Oops, you
-	  can point ksymoops at the saved ksyms instead of using
-	  /proc/ksyms.
-
-	  vmlinux is not read by default, it only duplicates the
-	  information in System.map.  If you want to read vmlinux as well
-	  as or instead of System.map, use -v.
-
-	  To get the equivalent of the old ksymoops.cc (no vmlinux, no
-	  modules objects, no ksyms, no System.map) just do ksymoops
-	  -VOKLM.  Or to just read System.map, ksymoops -VOKL -m mapfile.
-
-
-  Return codes:	  0 - normal.
-		  1 - error(s) or warning(s) issued, results may not be
-		      reliable.
-		  2 - fatal error, no useful results.
-		  3 - One shot mode, end of input reached.
-
-  Supported architectures
-
-	  i386 tested.
-          m68k code derived from ksymoops.cc and reading traps.c, untested.
-	  MIPS tested.
-	  Sparc tested.
-	  Sparc64 tested.
-	  Alpha tested.
-	  ARM tested.
-
-	  The term "eip" is generic, for example it includes the i386 EIP
-	  and the m68k PC.  Remember that objdump output always says EIP,
-	  no matter what the architecture, see objfile_head.
-
-	  To support another arch, check the Oops_ procedures between
-	  'Start architecture sensitive code' and 'End architecture
-	  sensitive code'.
-
-	  The pattern matching should take care of different lengths for
-	  the address, i.e. addresses should not be arch sensitive.  I
-	  assume that all addresses are at least 4 characters.
-
-	  If nm output has a different format on your arch, check for uses
-	  of re_nm.
-
-
-
-  Because ksymoops reads kernel information from multiple sources, there
-  could be mismatches.  ksymoops does the following cross checks, but only
-  if the specified files exist -
-
-  * Compare Version_nnn numbers from all sources against each other.  Pity
-    that only vmlinux and System.map have these symbols (as at 2.1.125),
-    however I check ksyms, modules and Oops as well.  If somebody adds
-    symbol Version_nnn to ksyms or modules or adds a Version_nnn line to
-    the Oops log, this code is ready.
-
-  * Compare kernel ksyms against vmlinux.  vmlinux takes precedence.
-
-  * Compare System.map against vmlinux.   vmlinux takes precedence.
-
-  * Compare vmlinux against System.map.   vmlinux takes precedence.
-
-  * Compare kernel ksyms against System.map.  System.map takes precedence.
-
-  * Compare modules against module ksyms.  modules take precedence.  Only
-    if at least one module appears in ksyms.
-
-  * Compare module names in ksyms against lsmod.  Warn if a module
-    appears in lsmod but not in ksyms.  Error if a modules appears in
-    ksyms but is not in lsmod.  Only if both ksyms and lsmod have being
-    read.
-
-  The precedence order is somewhat arbitrary, however it only applies if
-  there is any difference between the various sources.
-
-  Handling modules is awkward.  They can be loaded under different names
-  (insmod -o dummy1 dummy.o) and the text, data and read only data are
-  loaded at different offsets.  Although you can give the -m option to
-  insmod which will output the module map when it is loaded, this has a
-  few problems -
-
-  * No equivalent for removing a module.  If you load and remove a lot of
-    modules, you end up with multiple sets of symbols around the same
-    offsets, which set is correct?
-
-  * "insmod -o dummy1 dummy.o" still reports as dummy.  That is, there is
-     no way of telling which particular version of a multiply loaded
-     module the insmod output refers to.  Therefore there is no way of
-     telling which instantiation failed.
-
-  * Even if the above problems are fixed, how do you tell what the module
-    environment looked like when the Oops occurred?  What if a module is
-    loaded or removed just after Oops, how is the user expected to edit
-    the insmod log?  Rule 1 - make ksymoops easy for beginners.
-
-  Although those problems could be fixed, they require changes to
-  modutils.  Working from ksyms and the module objects can be done without
-  changing modutils and without confusing beginners.
-  
-  Alas the ksyms plus object approach has another problem - matching ksyms
-  to module objects.  Nowhere does the kernel say that module dummy1 came
-  from module /lib/modules/2.1.215/net/dummy.o, ksyms just says dummy1.  I
-  have to match ksyms to the relevant object by finding a globally unique
-  external symbol in each module that can be used to map to the external
-  symbols in ksyms.  This assumes that each module exports at least one
-  text symbol that is unique amongst all modules.
-
-  It may not be possible to correctly map other sections such as data and
-  readonly data for modules because they may not have exported symbols.
-  Since the main aim of ksymoops is to map a code Oops, this should not be
-  a problem.
-
-  Unfortunately some modules export no symbols.  They are marked as
-  EXPORT_NO_SYMBOLS are simply do not export anything.  It is
-  impossible to detect these in ksyms because, by definition, ksyms
-  only contains exported symbols for modules.  Since all modules appear
-  in lsmod (/proc/modules), a cross check of lsmod against the module
-  names will find loaded modules with no symbols, at least I can warn
-  about these.
-
-  After merging the various sources, ksymoops has a (hopefully) accurate
-  map including modules.  The -s option lets you save the merged
-  System.map, but remember that module data and readonly data sections may
-  not be correctly relocated, see above.
-
-  Environment Variables.
-  KSYMOOPS_NM		path for nm, defaults to /usr/bin/nm.
-  KSYMOOPS_FIND		path for find, defaults to /usr/bin/find.
-  KSYMOOPS_OBJDUMP	path for objdump, defaults to /usr/bin/objdump.
-
-
-  Input Oops data.
-
-  The ideal input is to feed the syslog straight into this program.  If
-  you cannot do that, you need to know what the program looks for.
-  Especially if you are typing in the Oops by hand :(.  All input is case
-  insensitive.
-
-  * White space in this context means space or tab.  It does not include
-    newline.
-
-  * Oops in syslog has a syslog prefix.  Leading text up to and including
-    ' kernel: ' is always ignored, there is no need to edit syslog first.
-    This leading text need not exist but if it does, it must end in
-    ' kernel: '.
-
-  * An alternative prefix is <n> where n is the kernel print level.  Also
-    ignored if present.
-
-  * Leading white space is treated as a prefix and ignored, the input is
-    not indentation sensitive.
-
-  * In the following paragraphs, assume that any prefixes have been
-    skipped.  If there is more than one prefix, all are skipped, no matter
-    which order they appear in.
-
-  * A bracketed address is optional '[', required '<', at least 4 hex
-    digits, required '>', optional ']'.  For example [<01234567>] or
-    <1234>.
-
-  * The ix86 EIP line is identified by optional white space followed by
-    'EIP:', followed by a least one white space, followed by a bracketed
-    address.
-
-  * The m68k PC line is identified by optional white space followed by
-    'PC', optionally followed by white space, followed by '=', optionally
-    followed by white space, followed by a bracketed address.
-
-  * The sparc PC line starts with PSR and PC is the second hex value, not
-    bracketed.
-
-  * The sparc64 TPC line starts with TSTATE and TPC is the second hex value,
-    not bracketed.
-
-  * A call trace line is identified by 'Call Trace:' followed by at least
-    one white space.  Or it is a line starting with a bracketed address,
-    but only if the previous line was a call trace line (I hate multi line
-    output that relies on identation for recognition, especially when
-    lines can have a variable prefix).
-
-  * The Code line is identified by 'Code:' followed by a least one white
-    space character followed by at least one hex value.  The line can
-    contain multiple hex values, each separated by at least one white
-    space.  Each hex value must be 2 to 8 digits and must be a multiple of
-    2 digits.
-
-    On some architectures the Code: data is a stream of single bytes,
-    in machine order.  On other architectures, it is a stream of shorts
-    or ints in human readable order which does not always match the
-    machine order, endianess raises its ugly head.  We are consistently
-    inconsistent.
-
-    To cater for these architecture inconsistencies, use the -c option.
-    If the Code: line is already in machine order, use -c 1.  If the
-    Code: data is a stream of shorts or ints which do not match the
-    machine order, use -c 2 or -c 4.  Each set of 'c' bytes are swapped
-    to (hopefully) reflect the machine order.
-
-    Special cases where Code: can be followed by text.
-      'Code: general protection'
-      'Code: <n>'
-    Dump the data anyway, the code was unavailable.
-
-  * Formatted data is only output when the Code: line is seen.  If any
-    data has been stored and more than 5 lines other than Oops text (see
-    Oops_print) or end of file are encountered then ksymoops assumes that
-    the Code: line is missing or garbled and dumps the formatted data
-    anyway.  Fail safe, I hope.
-
-  * By default, ksymoops reads its entire input file.  If the -1 toggle
-    is set, it will run in one shot mode and exit after the first Oops.
-    This is useful for automatically mailing reports as they happen,
-    like this :-
-
-    #!/bin/sh
-    # ksymoops1
-    while (true)
-    do
-    	ksymoops -1 > $HOME/oops1
-	if [ $? -eq 3 ]
-	then
-	   exit 0
-	fi
-	mail -s Oops admin < $HOME/oops1
-    done
-
-    tail -f /var/log/messages | ksymoops1
-
-    Restarting after log rotation is left as an exercise for the reader.
+Keith Owens <ka...@ocs.com.au> Sat Jun 19 10:30:34 EST 1999
diff -u --recursive --new-file v2.3.9/linux/scripts/ksymoops/io.c linux/scripts/ksymoops/io.c
--- v2.3.9/linux/scripts/ksymoops/io.c	Tue Jan  5 11:13:56 1999
+++ linux/scripts/ksymoops/io.c	Wed Dec 31 16:00:00 1969
@@ -1,139 +0,0 @@
-/*
-	io.c.
-
-	Local I/O routines for ksymoops.
-
-	Copyright Keith Owens <ka...@ocs.com.au>.
-	Released under the GNU Public Licence, Version 2.
-
-	Tue Nov  3 02:31:01 EST 1998
-	Version 0.6
-	fwrite_local is redundant, replaced by bfd.
-
-	Wed Oct 28 13:47:23 EST 1998
-	Version 0.4
-	Split into separate sources.
-
- */
-
-#include "ksymoops.h"
-#include <errno.h>
-#include <malloc.h>
-#include <string.h>
-#include <sys/stat.h>
-
-int regular_file(const char *file, const char *msg)
-{
-	struct stat statbuf;
-	if (stat(file, &statbuf)) {
-		fprintf(stderr, "%s: %s stat %s failed",
-			prefix, msg, file);
-		perror(" ");
-		++errors;
-		return 0;
-	}
-
-	if (!S_ISREG(statbuf.st_mode)) {
-		fprintf(stderr,
-			"%s: %s %s is not a regular file, ignored\n",
-			prefix, msg, file);
-		++errors;
-		return 0;
-	}
-	return 1;
-}
-
-FILE *fopen_local(const char *file, const char *mode, const char *msg)
-{
-	FILE *f;
-	if (!(f = fopen(file, mode))) {
-		fprintf(stderr, "%s: %s fopen '%s' failed",
-			prefix, msg, file);
-		perror(" ");
-		++errors;
-	}
-	return f;
-}
-
-void fclose_local(FILE *f, const char *msg)
-{
-	int i;
-	if ((i = fclose(f))) {
-		fprintf(stderr, "%s: %s fclose failed %d", prefix, msg, i);
-		perror(" ");
-		++errors;
-	}
-}
-
-/* Read a line, increasing the size of the line as necessary until \n is read */
-#define INCREMENT 10	/* arbitrary */
-char *fgets_local(char **line, int *size, FILE *f, const char *msg)
-{
-	char *l, *p, *r;
-	int longline = 1;
-
-	if (!*line) {
-		*size = INCREMENT;
-		*line = malloc(*size);
-		if (!*line)
-			malloc_error("fgets_local alloc line");
-	}
-
-	l = *line;
-	while (longline) {
-		r = fgets(l, *size-(l-*line), f);
-		if (!r) {
-			if (ferror(f)) {
-				fprintf(stderr,
-					"%s: %s fgets failed", prefix, msg);
-				perror(" ");
-				++errors;
-			}
-			if (l != *line)
-				return(*line);
-			else
-				return(r);
-		}
-		if (!(p = strchr(*line, '\n'))) {
-			*size += INCREMENT;
-			*line = realloc(*line, *size);
-			if (!*line)
-				malloc_error("fgets_local realloc line");
-			l = *line+*size-INCREMENT-1;
-		}
-		else {
-			*p = '\0';
-			longline = 0;
-		}
-	}
-
-	if (debug > 3)
-		fprintf(stderr, "DEBUG: %s line '%s'\n", msg, *line);
-	return(*line);
-}
-
-FILE *popen_local(const char *cmd, const char *msg)
-{
-	FILE *f;
-	if (!(f = popen(cmd, "r"))) {
-		fprintf(stderr, "%s: %s popen '%s' failed",
-			prefix, msg, cmd);
-		perror(" ");
-		++errors;
-	}
-	return f;
-}
-
-void pclose_local(FILE *f, const char *msg)
-{
-	int i;
-	errno = 0;
-	if ((i = pclose(f))) {
-		fprintf(stderr, "%s: %s pclose failed 0x%x", prefix, msg, i);
-		if (errno)
-			perror(" ");
-		else
-			fprintf(stderr, "\n");
-		++errors;
-	}
-}
diff -u --recursive --new-file v2.3.9/linux/scripts/ksymoops/ksymoops.c linux/scripts/ksymoops/ksymoops.c
--- v2.3.9/linux/scripts/ksymoops/ksymoops.c	Tue Jan  5 11:13:56 1999
+++ linux/scripts/ksymoops/ksymoops.c	Wed Dec 31 16:00:00 1969
@@ -1,678 +0,0 @@
-/*
-	ksymoops.c.
-
-	Read a kernel Oops file and make the best stab at converting the code to
-	instructions and mapping stack values to kernel symbols.
-
-	Copyright Keith Owens <ka...@ocs.com.au>.
-	Released under the GNU Public Licence, Version 2.
-*/
-
-#define VERSION "0.6e"
-
-/*
-
-	Tue Jan  5 19:26:02 EST 1999
-	Version 0.6e
-	Added to kernel.
-
-	Mon Jan  4 09:48:13 EST 1999
-	Version 0.6d
-	Add ARM support.
-
-	Thu Nov 26 16:37:46 EST 1998
-	Version 0.6c
-	Typo in oops_code.
-	Add -c option.
-	Add -1 option.
-	Report if options were specified or defaulted.
-
-	Fri Nov  6 10:38:42 EST 1998
-	Version 0.6b
-	Remove false warnings when comparing ksyms and lsmod.
-
-	Tue Nov  3 23:33:04 EST 1998
-	Version 0.6a
-	Performance inprovements.
-
-	Tue Nov  3 02:31:01 EST 1998
-	Version 0.6
-	Read lsmod (/proc/modules).
-	Ignore addresses 0-4095 when mapping address to symbol.
-	Discard default objects if -o specified.
-	Oops file must be regular.
-	Add "invalid operand" to Oops_print.
-	Move "Using_Version" copy to map.c.
-	Add Makefile defaults for vmlinux, ksyms, objects, System.map, lsmod.
-	Minor adjustment to re for ppc.
-	Minor adjustment to re for objdump lines with <_EIP+xxx>.
-	Convert from a.out to bfd, using same format as ksymoops.
-	Added MIPS.
-	PPC handling based on patches by "Ryan Nielsen" <r...@krazynet.com>
-
-	Wed Oct 28 23:14:55 EST 1998
-	Version 0.5
-	No longer read vmlinux by default, it only duplicates System.map.
-
-	Wed Oct 28 13:47:38 EST 1998
-	Version 0.4
-	Split into separate sources.
-
-	Mon Oct 26 00:01:47 EST 1998
-	Version 0.3c
-	Add alpha (arm) processing.
-
-	Mon Oct 26 00:01:47 EST 1998
-	Version 0.3b
-	Add sparc processing.
-	Handle kernel symbol versions.
-
-	Fri Oct 23 13:11:20 EST 1998
-	Version 0.3
-	Add -follow to find command for people who use symlinks to modules.
-	Add Version_ checking.
-
-	Thu Oct 22 22:28:30 EST 1998
-	Version 0.2.
-	Generalise text prefix handling.
-	Handle messages on Code: line.
-	Format addresses with leading zeroes.
-	Minor bug fixes.
-
-	Wed Oct 21 23:28:48 EST 1998
-	Version 0.1.  Rewrite from scratch in C.
-
-	CREDITS.
-	Oops disassembly based on ksymoops.cc,
-	  Copyright (C) 1995 Greg McGary <g...@magilla.cichlid.com>
-	m68k code based on ksymoops.cc changes by
-	  Andreas Schwab <sch...@issan.informatik.uni-dortmund.de>
- */
-
-#include "ksymoops.h"
-#include <ctype.h>
-#include <errno.h>
-#include <malloc.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/utsname.h>
-
-char *prefix;
-char *path_nm = "/usr/bin/nm";			/* env KSYMOOPS_NM */
-char *path_find = "/usr/bin/find";		/* env KSYMOOPS_FIND */
-char *path_objdump = "/usr/bin/objdump";	/* env KSYMOOPS_OBJDUMP */
-int debug = 0;
-int errors = 0;
-int warnings = 0;
-
-SYMBOL_SET  ss_vmlinux;
-SYMBOL_SET  ss_ksyms_base;
-SYMBOL_SET *ss_ksyms_module;
-int         ss_ksyms_modules;
-SYMBOL_SET  ss_lsmod;
-SYMBOL_SET *ss_object;
-int         ss_objects;
-SYMBOL_SET  ss_system_map;
-
-SYMBOL_SET  ss_merged;   /* merged map with info from all sources */
-SYMBOL_SET  ss_Version;  /* Version_ numbers where available */
-
-/* Regular expression stuff */
-
-regex_t     re_nm;
-regmatch_t *re_nm_pmatch;
-regex_t     re_bracketed_address;
-regmatch_t *re_bracketed_address_pmatch;
-regex_t     re_unbracketed_address;
-regmatch_t *re_unbracketed_address_pmatch;
-
-static void usage(void)
-{
-	fprintf(stderr, "Version " VERSION "\n");
-	fprintf(stderr, "usage: %s\n", prefix);
-	fprintf(stderr,
-		"\t\t[-v vmlinux]\tWhere to read vmlinux\n"
-		"\t\t[-V]\t\tNo vmlinux is available\n"
-		"\t\t[-o object_dir]\tDirectory containing modules\n"
-		"\t\t[-O]\t\tNo modules is available\n"
-		"\t\t[-k ksyms]\tWhere to read ksyms\n"
-		"\t\t[-K]\t\tNo ksyms is available\n"
-		"\t\t[-l lsmod]\tWhere to read lsmod\n"
-		"\t\t[-L]\t\tNo lsmod is available\n"
-		"\t\t[-m system.map]\tWhere to read System.map\n"
-		"\t\t[-M]\t\tNo System.map is available\n"
-		"\t\t[-s save.map]\tSave consolidated map\n"
-		"\t\t[-d]\t\tIncrease debug level by 1\n"
-		"\t\t[-h]\t\tPrint help text\n"
-		"\t\t[-c code_bytes]\tHow many bytes in each unit of code\n"
-		"\t\t[-1]\t\tOne shot toggle (exit after first Oops)\n"
-		"\t\t<Oops.file\tOops report to decode\n"
-		"\n"
-		"\t\tAll flags can occur more than once.  With the exception "
-			"of -o\n"
-		"\t\tand -d which are cumulative, the last occurrence of each "
-			"flag is\n"
-		"\t\tused.  Note that \"-v my.vmlinux -V\" will be taken as "
-			"\"No vmlinux\n"
-		"\t\tavailable\" but \"-V -v my.vmlinux\" will read "
-			"my.vmlinux.  You\n"
-		"\t\twill be warned about such combinations.\n"
-		"\n"
-		"\t\tEach occurrence of -d increases the debug level.\n"
-		"\n"
-		"\t\tEach -o flag can refer to a directory or to a single "
-			"object\n"
-		"\t\tfile.  If a directory is specified then all *.o files in "
-			"that\n"
-		"\t\tdirectory and its subdirectories are assumed to be "
-			"modules.\n"
-		"\n"
-		"\t\tIf any of the vmlinux, object_dir, ksyms or system.map "
-		"options\n"
-		"\t\tcontain the string *r (*m, *n, *s) then it is replaced "
-		"at run\n"
-		"\t\ttime by the current value of `uname -r` (-m, -n, -s).\n"
-		"\n"
-		"\t\tThe defaults can be changed in the Makefile, current "
-		"defaults\n"
-		"\t\tare\n\n"
-		"\t\t\t"
-#ifdef DEF_VMLINUX
-		"-v " DEF_LINUX
-#else
-		"-V"
-#endif
-		"\n"
-		"\t\t\t"
-#ifdef DEF_OBJECTS
-		"-o " DEF_OBJECTS
-#else
-		"-O"
-#endif
-		"\n"
-		"\t\t\t"
-#ifdef DEF_KSYMS
-		"-k " DEF_KSYMS
-#else
-		"-K"
-#endif
-		"\n"
-		"\t\t\t"
-#ifdef DEF_LSMOD
-		"-l " DEF_LSMOD
-#else
-		"-L"
-#endif
-		"\n"
-		"\t\t\t"
-#ifdef DEF_MAP
-		"-m " DEF_MAP
-#else
-		"-M"
-#endif
-		"\n"
-		"\t\t\t-c %d\n"	/* DEF_CODE_BYTES */
-		"\t\t\tOops report is read from stdin\n"
-		"\n",
-	DEF_CODE_BYTES
-	       );
-}
-
-/* Check if possibly conflicting options were specified */
-static void multi_opt(int specl, int specu, char type, const char *using)
-{
-	if (specl && specu) {
-		fprintf(stderr,
-			"Warning - you specified both -%c and -%c.  Using '",
-			type, toupper(type));
-		++warnings;
-		if (using) {
-			fprintf(stderr, "-%c %s", type, using);
-			if (type == 'o')
-				fprintf(stderr, " ...");
-			fprintf(stderr, "'\n");
-		}
-		else
-			fprintf(stderr, "-%c'\n", toupper(type));
-	}
-	else if (specl > 1 && type != 'o') {
-		fprintf(stderr,
-			"Warning - you specified -%c more than once.  "
-			"Using '-%c %s'\n",
-			type, type, using);
-		++warnings;
-	}
-	else if (specu > 1) {
-		fprintf(stderr,
-			"Warning - you specified -%c more than once.  "
-			"Second and subsequent '-%c' ignored\n",
-			toupper(type), toupper(type));
-		++warnings;
-	}
-}
-
-/* If a name contains *r (*m, *n, *s), replace with the current value of
- * `uname -r` (-m, -n, -s).  Actually uses uname system call rather than the
- * uname command but the result is the same.
- */
-static void convert_uname(char **name)
-{
-	char *p, *newname, *oldname, *replacement;
-	unsigned len;
-	int free_oldname = 0;
-	static char procname[] = "convert_uname";
-
-	if (!*name)
-		return;
-
-	while ((p = strchr(*name, '*'))) {
-		struct utsname buf;
-		int i = uname(&buf);
-		if (debug)
-			fprintf(stderr, "DEBUG: %s %s in\n", procname, *name);
-		if (i) {
-			fprintf(stderr,
-				"%s: uname failed, %s will not be processed\n",
-				prefix, *name);
-			perror(prefix);
-			++errors;
-			return;
-		}
-		switch (*(p+1)) {
-		case 'r':
-			replacement = buf.release;
-			break;
-		case 'm':
-			replacement = buf.machine;
-			break;
-		case 'n':
-			replacement = buf.nodename;
-			break;
-		case 's':
-			replacement = buf.sysname;
-			break;
-		default:
-			fprintf(stderr,
-				"%s: invalid replacement character '*%c' "
-				"in %s\n",
-				prefix, *(p+1), *name);
-			++errors;
-			return;
-		}
-		len = strlen(*name)-2+strlen(replacement)+1;
-		if (!(newname = malloc(len)))
-			malloc_error(procname);
-		strncpy(newname, *name, (p-*name));
-		strcpy(newname+(p-*name), replacement);
-		strcpy(newname+(p-*name)+strlen(replacement), p+2);
-		p = newname+(p-*name)+strlen(replacement);	/* no rescan */
-		oldname = *name;
-		*name = newname;
-		if (free_oldname)
-			free(oldname);
-		free_oldname = 1;
-		if (debug)
-			fprintf(stderr, "DEBUG: %s %s out\n", procname, *name);
-	}
-	return;
-}
-
-/* Report if the option was specified or defaulted */
-static void spec_or_default(int spec, int *some_spec) {
-	if (spec) {
-		printf(" (specified)\n");
-		if (some_spec)
-			*some_spec = 1;
-	}
-	else
-		printf(" (default)\n");
-}
-
-/* Parse the options.  Verbose but what's new with getopt? */
-static void parse(int argc,
-		  char **argv,
-		  char **vmlinux,
-		  char ***object,
-		  int *objects,
-		  char **ksyms,
-		  char **lsmod,
-		  char **system_map,
-		  char **save_system_map,
-		  char ***filename,
-		  int *filecount,
-		  int *spec_h,
-		  int *code_bytes,
-		  int *one_shot
-		 )
-{
-	int spec_v = 0, spec_V = 0;
-	int spec_o = 0, spec_O = 0;
-	int spec_k = 0, spec_K = 0;
-	int spec_l = 0, spec_L = 0;
-	int spec_m = 0, spec_M = 0;
-	int spec_s = 0;
-	int spec_c = 0;
-
-	int c, i, some_spec = 0;
-	char *p;
-
-	while ((c = getopt(argc, argv, "v:Vo:Ok:Kl:Lm:Ms:dhc:1")) != EOF) {
-		if (debug && c != 'd')
-			fprintf(stderr, "DEBUG: getopt '%c' '%s'\n", c, optarg);
-		switch(c) {
-		case 'v':
-			*vmlinux = optarg;
-			++spec_v;
-			break;
-		case 'V':
-			*vmlinux = NULL;
-			++spec_V;
-			break;
-		case 'o':
-			if (!spec_o) {
-				/* First -o, discard default value(s) */
-				for (i = 0; i < *objects; ++i)
-					free((*object)[i]);
-				free(*object);
-				*object = NULL;
-				*objects = 0;
-			}
-			*object = realloc(*object,
-				((*objects)+1)*sizeof(**object));
-			if (!*object)
-				malloc_error("object");
-			if (!(p = strdup(optarg)))
-				malloc_error("strdup -o");
-			else {
-				(*object)[(*objects)++] = p;
-				++spec_o;
-			}
-			break;
-		case 'O':
-			++spec_O;
-			for (i = 0; i < *objects; ++i)
-				free((*object)[i]);
-			free(*object);
-			*object = NULL;
-			*objects = 0;
-			break;
-		case 'k':
-			*ksyms = optarg;
-			++spec_k;
-			break;
-		case 'K':
-			*ksyms = NULL;
-			++spec_K;
-			break;
-		case 'l':
-			*lsmod = optarg;
-			++spec_l;
-			break;
-		case 'L':
-			*lsmod = NULL;
-			++spec_L;
-			break;
-		case 'm':
-			*system_map = optarg;
-			++spec_m;
-			break;
-		case 'M':
-			*system_map = NULL;
-			++spec_M;
-			break;
-		case 's':
-			*save_system_map = optarg;
-			++spec_s;
-			break;
-		case 'd':
-			++debug;
-			break;
-		case 'h':
-			usage();
-			++*spec_h;
-			break;
-		case 'c':
-			++spec_c;
-			errno = 0;
-			*code_bytes = strtoul(optarg, &p, 10);
-			/* Oops_code_values assumes that code_bytes is a
-			 * multiple of 2.
-			 */
-			if (!*optarg || *p || errno ||
-				(*code_bytes != 1 &&
-				 *code_bytes != 2 &&
-				 *code_bytes != 4 &&
-				 *code_bytes != 8)) {
-				fprintf(stderr,
-					"%s Invalid value for -c '%s'\n",
-					prefix, optarg);
-				++errors;
-				if (errno)
-					perror(" ");
-				*code_bytes = DEF_CODE_BYTES;
-			}
-			break;
-		case '1':
-			*one_shot = !*one_shot;
-			break;
-		case '?':
-			usage();
-			exit(2);
-		}
-	}
-
-	*filecount = argc - optind;
-	*filename = argv + optind;
-
-	/* Expand any requests for the current uname values */
-	convert_uname(vmlinux);
-	if (*objects) {
-		for (i = 0; i < *objects; ++i)
-			convert_uname(*object+i);
-	}
-	convert_uname(ksyms);
-	convert_uname(lsmod);
-	convert_uname(system_map);
-
-	/* Check for multiple options specified */
-	multi_opt(spec_v, spec_V, 'v', *vmlinux);
-	multi_opt(spec_o, spec_O, 'o', *object ? **object : NULL);
-	multi_opt(spec_k, spec_K, 'k', *ksyms);
-	multi_opt(spec_l, spec_L, 'l', *lsmod);
-	multi_opt(spec_m, spec_M, 'm', *system_map);
-
-	printf("Options used:");
-	if (*vmlinux)
-		printf(" -v %s", *vmlinux);
-	else
-		printf(" -V");
-	spec_or_default(spec_v || spec_V, &some_spec);
-	
-	printf("             ");
-	if (*objects) {
-		for (i = 0; i < *objects; ++i)
-			printf(" -o %s", (*object)[i]);
-	}
-	else
-		printf(" -O");
-	spec_or_default(spec_o || spec_O, &some_spec);
-
-	printf("             ");
-	if (*ksyms)
-		printf(" -k %s", *ksyms);
-	else
-		printf(" -K");
-	spec_or_default(spec_k || spec_K, &some_spec);
-
-	printf("             ");
-	if (*lsmod)
-		printf(" -l %s", *lsmod);
-	else
-		printf(" -L");
-	spec_or_default(spec_l || spec_L, &some_spec);
-
-	printf("             ");
-	if (*system_map)
-		printf(" -m %s", *system_map);
-	else
-		printf(" -M");
-	spec_or_default(spec_m || spec_M, &some_spec);
-
-	printf("             ");
-	printf(" -c %d", *code_bytes);
-	spec_or_default(spec_c, NULL);
-
-	if (*one_shot) {
-		printf("             ");
-		printf(" -1");
-	}
-
-	printf("\n");
-
-	if (!some_spec) {
-		printf(
-"You did not tell me where to find symbol information.  I will assume\n"
-"that the log matches the kernel and modules that are running right now\n"
-"and I'll use the default options above for symbol resolution.\n"
-"If the current kernel and/or modules do not match the log, you can get\n"
-"more accurate output by telling me the kernel version and where to find\n"
-"map, modules, ksyms etc.  ksymoops -h explains the options.\n"
-			"\n");
-		++warnings;
-	}
-}
-
-/* Read environment variables */
-static void read_env(const char *external, char **internal)
-{
-	char *p;
-	if ((p = getenv(external))) {
-		*internal = p;
-		if (debug)
-			fprintf(stderr,
-				"DEBUG: env override %s=%s\n",
-				external, *internal);
-	}
-	else {
-		if (debug)
-			fprintf(stderr,
-				"DEBUG: env default %s=%s\n",
-				external, *internal);
-	}
-}
-
-
-int main(int argc, char **argv)
-{
-	char *vmlinux = NULL;
-	char **object = NULL;
-	int objects = 0;
-	char *ksyms = NULL;
-	char *lsmod = NULL;
-	char *system_map = NULL;
-	char *save_system_map = NULL;
-	char **filename;
-	int filecount = 0;
-	int spec_h = 0;		/* -h was specified */
-	int code_bytes = DEF_CODE_BYTES;
-	int one_shot = 0;
-	int i, ret;
-
-	prefix = *argv;
-	setvbuf(stdout, NULL, _IONBF, 0);
-
-#ifdef DEF_VMLINUX
-	vmlinux = DEF_LINUX;
-#endif
-#ifdef DEF_OBJECTS
-	{
-		char *p;
-		object = realloc(object, (objects+1)*sizeof(*object));
-		if (!object)
-			malloc_error("DEF_OBJECTS");
-		if (!(p = strdup(DEF_OBJECTS)))
-			malloc_error("DEF_OBJECTS");
-		else
-			object[objects++] = p;
-	}
-#endif
-#ifdef DEF_KSYMS
-	ksyms = DEF_KSYMS;
-#endif
-#ifdef DEF_LSMOD
-	lsmod = DEF_LSMOD;
-#endif
-#ifdef DEF_MAP
-	system_map = DEF_MAP;
-#endif
-
-	parse(argc,
-	      argv,
-	      &vmlinux,
-	      &object,
-	      &objects,
-	      &ksyms,
-	      &lsmod,
-	      &system_map,
-	      &save_system_map,
-	      &filename,
-	      &filecount,
-	      &spec_h,
-	      &code_bytes,
-	      &one_shot
-	     );
-
-	if (spec_h && filecount == 0)
-		return(0);	/* just the help text */
-
-	if (errors)
-		return(1);
-
-	if (debug)
-		fprintf(stderr, "DEBUG: level %d\n", debug);
-
-	read_env("KSYMOOPS_NM", &path_nm);
-	read_env("KSYMOOPS_FIND", &path_find);
-	read_env("KSYMOOPS_OBJDUMP", &path_objdump);
-
-	re_compile_common();
-	ss_init_common();
-
-	read_vmlinux(vmlinux);
-	read_ksyms(ksyms);
-	/* No point in reading modules unless ksyms shows modules loaded */
-	if (ss_ksyms_modules) {
-		expand_objects(object, objects);
-		for (i = 0; i < ss_objects; ++i)
-			read_object(ss_object[i].source, i);
-	}
-	else if (objects)
-		printf("No modules in ksyms, skipping objects\n");
-	/* No point in reading lsmod without ksyms */
-	if (ss_ksyms_modules || ss_ksyms_base.used)
-		read_lsmod(lsmod);
-	else if (lsmod)
-		printf("No ksyms, skipping lsmod\n");
-	read_system_map(system_map);
-	merge_maps(save_system_map);
-
-	/* After all that work, it is finally time to read the Oops report */
-	ret = Oops_read(filecount, filename, code_bytes, one_shot);
-
-	if (warnings || errors) {
-		printf("\n");
-		if (warnings)
-			printf("%d warning%s ",
-			       warnings, warnings == 1 ? "" : "s");
-		if (warnings && errors)
-			printf("and ");
-		if (errors)
-			printf("%d error%s ", errors, errors == 1 ? "" : "s");
-		printf("issued.  Results may not be reliable.\n");
-		if (!ret)
-			return(1);
-	}
-
-	return(ret);
-}
diff -u --recursive --new-file v2.3.9/linux/scripts/ksymoops/ksymoops.h linux/scripts/ksymoops/ksymoops.h
--- v2.3.9/linux/scripts/ksymoops/ksymoops.h	Tue Jan  5 11:13:56 1999
+++ linux/scripts/ksymoops/ksymoops.h	Wed Dec 31 16:00:00 1969
@@ -1,146 +0,0 @@
-/*
-	ksymoops.h.
-
-	Copyright Keith Owens <ka...@ocs.com.au>.
-	Released under the GNU Public Licence, Version 2.
-
-	Tue Nov  3 02:31:01 EST 1998
-	Version 0.6
-	Read lsmod (/proc/modules).
-	Convert from a.out to bfd, using same format as ksymoops.
-	PPC trace addresses are not bracketed, add new re.
-
-	Wed Oct 28 13:47:23 EST 1998
-	Version 0.4
-	Split into separate sources.
-*/
-
-#include <sys/types.h>
-#include <regex.h>
-#include <stdio.h>
-
-
-/* Pity this is not externalised, see binfmt_elf.c */
-#define elf_addr_t unsigned long
-
-extern char *prefix;
-extern char *path_nm;		/* env KSYMOOPS_NM */
-extern char *path_find;		/* env KSYMOOPS_FIND */
-extern char *path_objdump;	/* env KSYMOOPS_OBJDUMP */
-extern int debug;
-extern int errors;
-extern int warnings;
-
-typedef struct symbol SYMBOL;
-
-struct symbol {
-	char *name;		/* name of symbol */
-	char type;		/* type of symbol from nm/System.map */
-	char keep;		/* keep this symbol in merged map? */
-	elf_addr_t address;	/* address in kernel */
-};
-
-/* Header for symbols from one particular source */
-
-typedef struct symbol_set SYMBOL_SET;
-
-struct symbol_set {
-	char *source;			/* where the symbols came from */
-	int used;			/* number of symbols used */
-	int alloc;			/* number of symbols allocated */
-	SYMBOL *symbol;			/* dynamic array of symbols */
-	SYMBOL_SET *related;		/* any related symbol set */
-};
-
-extern SYMBOL_SET  ss_vmlinux;
-extern SYMBOL_SET  ss_ksyms_base;
-extern SYMBOL_SET *ss_ksyms_module;
-extern int         ss_ksyms_modules;
-extern SYMBOL_SET  ss_lsmod;
-extern SYMBOL_SET *ss_object;
-extern int         ss_objects;
-extern SYMBOL_SET  ss_system_map;
-
-extern SYMBOL_SET  ss_merged;	/* merged map with info from all sources */
-extern SYMBOL_SET  ss_Version;	/* Version_ numbers where available */
-
-/* Regular expression stuff */
-
-extern regex_t     re_nm;
-extern regmatch_t *re_nm_pmatch;
-extern regex_t     re_bracketed_address;
-extern regmatch_t *re_bracketed_address_pmatch;
-extern regex_t     re_unbracketed_address;
-extern regmatch_t *re_unbracketed_address_pmatch;
-
-/* Bracketed address: optional '[', required '<', at least 4 hex characters,
- * required '>', optional ']', optional white space.
- */
-#define BRACKETED_ADDRESS	"\\[*<([0-9a-fA-F]{4,})>\\]*[ \t]*"
-
-#define UNBRACKETED_ADDRESS	"([0-9a-fA-F]{4,})[ \t]*"
-
-/* io.c */
-extern int regular_file(const char *file, const char *msg);
-extern FILE *fopen_local(const char *file, const char *mode, const char *msg);
-extern void fclose_local(FILE *f, const char *msg);
-extern char *fgets_local(char **line, int *size, FILE *f, const char *msg);
-extern int fwrite_local(void const *ptr, size_t size, size_t nmemb,
-			FILE *stream, const char *msg);
-extern FILE *popen_local(const char *cmd, const char *msg);
-extern void pclose_local(FILE *f, const char *msg);
-
-/* ksyms.c */
-extern void read_ksyms(const char *ksyms);
-extern void map_ksyms_to_modules(void);
-extern void read_lsmod(const char *lsmod);
-extern void compare_ksyms_lsmod(void);
-
-/* misc.c */
-extern void malloc_error(const char *msg);
-extern const char *format_address(elf_addr_t address);
-extern char *find_fullpath(const char *program);
-
-/* map.c */
-extern void read_system_map(const char *system_map);
-extern void merge_maps(const char *save_system_map);
-extern void compare_maps(const SYMBOL_SET *ss1, const SYMBOL_SET *ss2,
-			 int precedence);
-
-
-/* object.c */
-extern SYMBOL_SET *adjust_object_offsets(SYMBOL_SET *ss);
-extern void read_vmlinux(const char *vmlinux);
-extern void expand_objects(char * const *object, int objects);
-extern void read_object(const char *object, int i);
-
-/* oops.c */
-extern int Oops_read(int filecount, char * const *filename, int code_bytes,
-		     int one_shot);
-
-/* re.c */
-extern void re_compile(regex_t *preg, const char *regex, int cflags,
-		       regmatch_t **pmatch);
-extern void re_compile_common(void);
-extern void re_strings(regex_t *preg, const char *text, regmatch_t *pmatch,
-		       char ***string);
-extern void re_strings_free(const regex_t *preg, char ***string);
-extern void re_string_check(int need, int available, const char *msg);
-
-/* symbol.c */
-extern void ss_init(SYMBOL_SET *ss, const char *msg);
-extern void ss_free(SYMBOL_SET *ss);
-extern void ss_init_common(void);
-extern SYMBOL *find_symbol_name(const SYMBOL_SET *ss, const char *symbol,
-				int *start);
-extern void add_symbol_n(SYMBOL_SET *ss, const elf_addr_t address,
-			 const char type, const char keep, const char *symbol);
-extern void add_symbol(SYMBOL_SET *ss, const char *address, const char type,
-		       const char keep, const char *symbol);
-extern char *map_address(const SYMBOL_SET *ss, const elf_addr_t address);
-extern void ss_sort_atn(SYMBOL_SET *ss);
-extern void ss_sort_na(SYMBOL_SET *ss);
-extern SYMBOL_SET *ss_copy(const SYMBOL_SET *ss);
-extern void add_Version(const char *version, const char *source);
-extern void extract_Version(SYMBOL_SET *ss);
-extern void compare_Version(void);
diff -u --recursive --new-file v2.3.9/linux/scripts/ksymoops/ksyms.c linux/scripts/ksymoops/ksyms.c
--- v2.3.9/linux/scripts/ksymoops/ksyms.c	Tue Jan  5 11:13:56 1999
+++ linux/scripts/ksymoops/ksyms.c	Wed Dec 31 16:00:00 1969
@@ -1,294 +0,0 @@
-/*
-	ksyms.c.
-
-	Process ksyms for ksymoops.
-
-	Copyright Keith Owens <ka...@ocs.com.au>.
-	Released under the GNU Public Licence, Version 2.
-
-	Fri Nov  6 10:38:42 EST 1998
-	Version 0.6b
-	Remove false warnings when comparing ksyms and lsmod.
-
-	Tue Nov  3 02:31:01 EST 1998
-	Version 0.6
-	Read lsmod (/proc/modules).
-	Move "Using_Version" copy to map.c.
-
-	Wed Oct 28 13:47:23 EST 1998
-	Version 0.4
-	Split into separate sources.
- */
-
-#include "ksymoops.h"
-#include <malloc.h>
-#include <string.h>
-
-/* Scan one line from ksyms.  Split lines into the base symbols and the module
- * symbols.  Separate ss for base and each module.
- */
-static void scan_ksyms_line(const char *line)
-{
-	int i;
-	char **string = NULL;
-	SYMBOL_SET *ssp;
-	static char *prev_module = NULL;
-	static regex_t     re_ksyms;
-	static regmatch_t *re_ksyms_pmatch;
-	static char const procname[] = "scan_ksyms_line";
-
-	/* ksyms: address, symbol, optional module */
-	re_compile(&re_ksyms,
-		"^([0-9a-fA-F]{4,}) +([^ \t]+)([ \t]+\\[([^ ]+)\\])?$",
-		REG_NEWLINE|REG_EXTENDED,
-		&re_ksyms_pmatch);
-
-	i = regexec(&re_ksyms, line,
-		    re_ksyms.re_nsub+1, re_ksyms_pmatch, 0);
-	if (debug > 3)
-		fprintf(stderr, "DEBUG: %s regexec %d\n", procname, i);
-	if (i)
-		return;
-
-	/* string [1] - address, [2] - symbol, [3] - white space+module,
-	 * [4] - module.
-	 */
-	re_strings(&re_ksyms, line, re_ksyms_pmatch, &string);
-	if (string[4]) {
-		if (!prev_module || strcmp(prev_module, string[4])) {
-			/* start of a new module in ksyms */
-			++ss_ksyms_modules;
-			ss_ksyms_module = realloc(ss_ksyms_module,
-				ss_ksyms_modules*sizeof(*ss_ksyms_module));
-			if (!ss_ksyms_module)
-				malloc_error("realloc ss_ksyms_module");
-			ssp = ss_ksyms_module+ss_ksyms_modules-1;
-			ss_init(ssp, string[4]);
-			prev_module = strdup(string[4]);
-			if (!prev_module)
-				malloc_error("strdup prev_module");
-		}
-		ssp = ss_ksyms_module+ss_ksyms_modules-1;
-	}
-	else
-		ssp = &ss_ksyms_base;
-	add_symbol(ssp, string[1], ' ', 1, string[2]);
-	re_strings_free(&re_ksyms, &string);
-}
-
-/* Read the symbols from ksyms.  */
-void read_ksyms(const char *ksyms)
-{
-	FILE *f;
-	char *line = NULL;
-	int i, size;
-	static char const procname[] = "read_ksyms";
-
-	if (!ksyms)
-		return;
-	ss_init(&ss_ksyms_base, "ksyms_base");
-	if (debug)
-		fprintf(stderr, "DEBUG: %s %s\n", procname, ksyms);
-
-	if (!regular_file(ksyms, procname))
-		return;
-
-	if (!(f = fopen_local(ksyms, "r", procname)))
-		return;
-
-	while (fgets_local(&line, &size, f, procname))
-		scan_ksyms_line(line);
-
-	fclose_local(f, procname);
-	free(line);
-
-	for (i = 0; i < ss_ksyms_modules; ++i) {
-		ss_sort_na(ss_ksyms_module+i);
-		extract_Version(ss_ksyms_module+i);
-	}
-	if (ss_ksyms_base.used) {
-		ss_sort_na(&ss_ksyms_base);
-		extract_Version(&ss_ksyms_base);
-	}
-	else {
-		fprintf(stderr,
-			"Warning, no kernel symbols in ksyms, is %s a valid "
-			"ksyms file?\n",
-			ksyms);
-		++warnings;
-	}
-
-	if (debug > 1) {
-		for (i = 0; i < ss_ksyms_modules; ++i) {
-			fprintf(stderr,
-				"DEBUG: %s %s used %d out of %d entries\n",
-				procname,
-				ss_ksyms_module[i].source,
-				ss_ksyms_module[i].used,
-				ss_ksyms_module[i].alloc);
-		}
-		fprintf(stderr,
-			"DEBUG: %s %s used %d out of %d entries\n",
-			procname, ss_ksyms_base.source, ss_ksyms_base.used,
-			ss_ksyms_base.alloc);
-	}
-}
-
-/* Map each ksyms module entry to the corresponding object entry.  Tricky,
- * see the comments in the docs about needing a unique symbol in each
- * module.
- */
-static void map_ksym_to_module(SYMBOL_SET *ss)
-{
-	int i, j, matches;
-	char *name = NULL;
-
-	for (i = 0; i < ss->used; ++i) {
-		matches = 0;
-		for (j = 0; j < ss_objects; ++j) {
-			name = (ss->symbol)[i].name;
-			if (find_symbol_name(ss_object+j, name, NULL)) {
-				++matches;
-				ss->related = ss_object+j;
-			}
-		}
-		if (matches == 1)
-			break;		/* unique symbol over all objects */
-		ss->related = NULL;	/* keep looking */
-	}
-	if (!(ss->related)) {
-		fprintf(stderr,
-			"Warning: cannot match loaded module %s to any "
-			"module object.  Trace may not be reliable.\n",
-			ss->source);
-		++warnings;
-	}
-	else if (debug)
-		fprintf(stderr,
-			"DEBUG: ksyms %s matches to %s based on unique "
-			"symbol %s\n",
-			ss->source, ss->related->source, name);
-}
-
-/* Map all ksyms module entries to their corresponding objects */
-void map_ksyms_to_modules(void)
-{
-	int i;
-	SYMBOL_SET *ss, *ssc;
-
-	for (i = 0; i < ss_ksyms_modules; ++i) {
-		ss = ss_ksyms_module+i;
-		map_ksym_to_module(ss);
-		if (ss->related) {
-			ssc = adjust_object_offsets(ss);
-			compare_maps(ss, ssc, 1);
-		}
-	}
-}
-
-/* Read the modules from lsmod.  */
-void read_lsmod(const char *lsmod)
-{
-	FILE *f;
-	char *line = NULL;
-	int i, size;
-	char **string = NULL;
-	static regex_t     re_lsmod;
-	static regmatch_t *re_lsmod_pmatch;
-	static char const procname[] = "read_lsmod";
-
-	if (!lsmod)
-		return;
-	ss_init(&ss_lsmod, "lsmod");
-	if (debug)
-		fprintf(stderr, "DEBUG: %s %s\n", procname, lsmod);
-
-	if (!regular_file(lsmod, procname))
-		return;
-
-	if (!(f = fopen_local(lsmod, "r", procname)))
-		return;
-
-	/* lsmod: module, size, use count, optional used by */
-	re_compile(&re_lsmod,
-		"^"
-		"[ \t]*([^ \t]+)"				/* 1 module */
-		"[ \t]*([^ \t]+)"				/* 2 size */
-		"[ \t]*([^ \t]+)"				/* 3 count */
-		"[ \t]*(.*)"					/* 4 used by */
-		"$",
-		REG_NEWLINE|REG_EXTENDED,
-		&re_lsmod_pmatch);
-
-	while (fgets_local(&line, &size, f, procname)) {
-		i = regexec(&re_lsmod, line,
-			    re_lsmod.re_nsub+1, re_lsmod_pmatch, 0);
-		if (debug > 3)
-			fprintf(stderr, "DEBUG: %s regexec %d\n", procname, i);
-		if (i)
-			continue;
-		re_strings(&re_lsmod, line, re_lsmod_pmatch, &string);
-		add_symbol(&ss_lsmod, string[2], ' ', 1, string[1]);
-	}
-
-	fclose_local(f, procname);
-	free(line);
-	re_strings_free(&re_lsmod, &string);
-	if (ss_lsmod.used)
-		ss_sort_na(&ss_lsmod);
-	else {
-		fprintf(stderr,
-			"Warning, no symbols in lsmod, is %s a valid "
-			"lsmod file?\n",
-			lsmod);
-		++warnings;
-	}
-
-	if (debug > 1)
-		fprintf(stderr,
-			"DEBUG: %s %s used %d out of %d entries\n",
-			procname, ss_lsmod.source, ss_lsmod.used,
-			ss_lsmod.alloc);
-}
-
-/* Compare modules from ksyms against module list in lsmod and vice versa.
- * There is one ss_ for each ksyms module and a single ss_lsmod to cross
- * check.
- */
-void compare_ksyms_lsmod(void)
-{
-	int i, j;
-	SYMBOL_SET *ss;
-	SYMBOL *s;
-	static char const procname[] = "compare_ksyms_lsmod";
-
-	if (!(ss_lsmod.used && ss_ksyms_modules))
-		return;
-
-	s = ss_lsmod.symbol;
-	for (i = 0; i < ss_lsmod.used; ++i, ++s) {
-		for (j = 0; j < ss_ksyms_modules; ++j) {
-			ss = ss_ksyms_module+j;
-			if (strcmp(s->name, ss->source) == 0)
-				break;
-		}
-		if (j >= ss_ksyms_modules) {
-			fprintf(stderr,
-				"Warning in %s, module %s is in lsmod but not "
-				"in ksyms, probably no symbols exported\n",
-				procname, s->name);
-			++warnings;
-		}
-	}
-
-	for (i = 0; i < ss_ksyms_modules; ++i) {
-		ss = ss_ksyms_module+i;
-		if (!find_symbol_name(&ss_lsmod, ss->source, NULL)) {
-			fprintf(stderr,
-				"Error in %s, module %s is in ksyms but not "
-				"in lsmod\n",
-				procname, ss->source);
-			++errors;
-		}
-	}
-}
diff -u --recursive --new-file v2.3.9/linux/scripts/ksymoops/map.c linux/scripts/ksymoops/map.c
--- v2.3.9/linux/scripts/ksymoops/map.c	Tue Jan  5 11:13:56 1999
+++ linux/scripts/ksymoops/map.c	Wed Dec 31 16:00:00 1969
@@ -1,251 +0,0 @@
-/*
-	map.c.
-
-	Read System.map for ksymoops, create merged System.map.
-
-	Copyright Keith Owens <ka...@ocs.com.au>.
-	Released under the GNU Public Licence, Version 2.
-
-	Tue Nov  3 02:31:01 EST 1998
-	Version 0.6
-	Remove addresses 0-4095 from merged map after writing new map.
-	Move "Using_Version" copy to map.c.
-
-	Wed Oct 28 13:47:23 EST 1998
-	Version 0.4
-	Split into separate sources.
- */
-
-#include "ksymoops.h"
-#include <malloc.h>
-
-/* Read the symbols from System.map */
-void read_system_map(const char *system_map)
-{
-	FILE *f;
-	char *line = NULL, **string = NULL;
-	int i, size = 0;
-	static char const procname[] = "read_system_map";
-
-	if (!system_map)
-		return;
-	ss_init(&ss_system_map, "System.map");
-	if (debug)
-		fprintf(stderr, "DEBUG: %s %s\n", procname, system_map);
-
-	if (!regular_file(system_map, procname))
-		return;
-
-	if (!(f = fopen_local(system_map, "r", procname)))
-		return;
-
-	while (fgets_local(&line, &size, f, procname)) {
-		i = regexec(&re_nm, line, re_nm.re_nsub+1, re_nm_pmatch, 0);
-		if (debug > 3)
-			fprintf(stderr, "DEBUG: %s regexec %d\n", procname, i);
-		if (i == 0) {
-			re_strings(&re_nm, line, re_nm_pmatch, &string);
-			add_symbol(&ss_system_map, string[1], *string[2],
-				   1, string[3]);
-		}
-	}
-
-	fclose_local(f, procname);
-	re_strings_free(&re_nm, &string);
-	free(line);
-	if (ss_system_map.used) {
-		ss_sort_na(&ss_system_map);
-		extract_Version(&ss_system_map);
-	}
-	else {
-		fprintf(stderr,
-			"Warning, no kernel symbols in System.map, is %s a "
-			"valid System.map file?\n",
-			system_map);
-		++warnings;
-	}
-
-	if (debug > 1)
-		fprintf(stderr,
-			"DEBUG: %s %s used %d out of %d entries\n",
-			procname,
-			ss_system_map.source,
-			ss_system_map.used,
-			ss_system_map.alloc);
-}
-
-/* Compare two maps, all symbols in the first should appear in the second. */
-void compare_maps(const SYMBOL_SET *ss1, const SYMBOL_SET *ss2,
-			 int precedence)
-{
-	int i, start = 0;
-	SYMBOL *s1, *s2, **sdrop = precedence == 1 ? &s2 : &s1;
-	const SYMBOL_SET **ssdrop = precedence == 1 ? &ss2 : &ss1;
-
-	if (!(ss1->used && ss2->used))
-		return;
-
-	if (debug > 1)
-		fprintf(stderr,
-			"DEBUG: compare_maps %s vs %s, %s takes precedence\n",
-			ss1->source, ss2->source,
-			precedence == 1 ? ss1->source : ss2->source);
-
-	for (i = 0; i < ss1->used; ++i) {
-		s1 = ss1->symbol+i;
-		if (!(s1->keep))
-			continue;
-		s2 = find_symbol_name(ss2, s1->name, &start);
-		if (!s2) {
-			/* Some types only appear in nm output, not in things
-			 * like System.map.  Silently ignore them.
-			 */
-			if (s1->type == 'a' || s1->type == 't')
-				continue;
-			fprintf(stderr,
-				"Warning: %s symbol %s not found in %s.  "
-				"Ignoring %s entry\n",
-				ss1->source, s1->name,
-				ss2->source, (*ssdrop)->source);
-			++warnings;
-			if (*sdrop)
-				(*sdrop)->keep = 0;
-		}
-		else if (s1->address != s2->address) {
-			/* Type C symbols cannot be resolved from nm to ksyms,
-			 * silently ignore them.
-			 */
-			if (s1->type == 'C' || s2->type == 'C')
-				continue;
-			fprintf(stderr,
-				"Warning: mismatch on symbol %s %c, "
-				"%s says %lx, %s says %lx.  "
-				"Ignoring %s entry\n",
-				s1->name, s1->type, ss1->source, s1->address,
-				ss2->source, s2->address, (*ssdrop)->source);
-			++warnings;
-			if (*sdrop)
-				(*sdrop)->keep = 0;
-		}
-		else
-			++start;	/* step to next entry in ss2 */
-	}
-}
-
-/* Append the second symbol set onto the first */
-static void append_map(SYMBOL_SET *ss1, const SYMBOL_SET *ss2)
-{
-	int i;
-	SYMBOL *s;
-
-	if (!ss2 || !ss2->used)
-		return;
-	if (debug > 1)
-		fprintf(stderr, "DEBUG: append_map %s to %s\n",
-			ss2->source, ss1->source);
-
-	for (i = 0; i < ss2->used; ++i) {
-		s = ss2->symbol+i;
-		if (s->keep)
-			add_symbol_n(ss1, s->address, s->type, 1,
-				s->name);
-	}
-}
-
-/* Compare the various sources and build a merged system map */
-void merge_maps(const char *save_system_map)
-{
-	int i;
-	SYMBOL *s;
-	FILE *f;
-	static char const procname[] = "merge_maps";
-
-	if (debug)
-		fprintf(stderr, "DEBUG: %s\n", procname);
-
-	/* Using_Versions only appears in ksyms, copy to other tables */
-	if ((s = find_symbol_name(&ss_ksyms_base,
-			"Using_Versions", 0))) {
-		if (ss_system_map.used) {
-			add_symbol_n(&ss_system_map, s->address,
-				s->type, s->keep, s->name);
-			ss_sort_na(&ss_system_map);
-		}
-		if (ss_vmlinux.used) {
-			add_symbol_n(&ss_vmlinux, s->address, s->type,
-				s->keep, s->name);
-			ss_sort_na(&ss_vmlinux);
-		}
-	}
-
-	compare_Version();	/* highlight any version problems first */
-	compare_ksyms_lsmod();	/* highlight any missing modules next */
-	compare_maps(&ss_ksyms_base, &ss_vmlinux, 2);
-	compare_maps(&ss_system_map, &ss_vmlinux, 2);
-	compare_maps(&ss_vmlinux, &ss_system_map, 1);
-	compare_maps(&ss_ksyms_base, &ss_system_map, 2);
-
-	if (ss_objects) {
-		map_ksyms_to_modules();
-	}
-
-	ss_init(&ss_merged, "merged");
-	append_map(&ss_merged, &ss_vmlinux);
-	append_map(&ss_merged, &ss_ksyms_base);
-	append_map(&ss_merged, &ss_system_map);
-	for (i = 0; i < ss_ksyms_modules; ++i)
-		append_map(&ss_merged, (ss_ksyms_module+i)->related);
-	if (!ss_merged.used) {
-		fprintf(stderr, "Warning, no symbols in merged map\n");
-		++warnings;
-	}
-
-	/* drop duplicates, type a (registers) and gcc2_compiled. */
-	ss_sort_atn(&ss_merged);
-	s = ss_merged.symbol;
-	for (i = 0; i < ss_merged.used-1; ++i) {
-		if (s->type == 'a' ||
-		    (s->type == 't' && !strcmp(s->name, "gcc2_compiled.")))
-			s->keep = 0;
- else if (strcmp(s->name, (s+1)->name) == 0 &&
-		    s->address == (s+1)->address) {
-			if (s->type != ' ')
-				(s+1)->keep = 0;
-			else
-				s->keep = 0;
-		}
-		++s;
-	}
-	ss_sort_atn(&ss_merged);	/* will remove dropped variables */
-
-	if (save_system_map) {
-		if (debug)
-			fprintf(stderr, "DEBUG: writing merged map to %s\n",
-				save_system_map);
-		if (!(f = fopen_local(save_system_map, "w", procname)))
-			return;
-		s = ss_merged.symbol;
-		for (i = 0; i < ss_merged.used; ++i) {
-			if (s->keep)
-				fprintf(f, "%s %c %s\n",
-					format_address(s->address),
-					s->type, s->name);
-			++s;
-		}
-	}
-
-	/* The merged map may contain symbols with an address of 0, e.g.
-	 * Using_Versions.  These give incorrect results for low addresses in
-	 * map_address, such addresses map to "Using_Versions+xxx".  Remove
-	 * any addresses below (arbitrary) 4096 from the merged map.  AFAIK,
-	 * Linux does not use the first page on any arch.
-	 */
-	for (i = 0; i < ss_merged.used; ++i) {
-		if ((ss_merged.symbol+i)->address < 4096)
-			(ss_merged.symbol+i)->keep = 0;
-		else
-			break;
-	}
-	if (i)
-		ss_sort_atn(&ss_merged);	/* remove dropped variables */
-}
diff -u --recursive --new-file v2.3.9/linux/scripts/ksymoops/misc.c linux/scripts/ksymoops/misc.c
--- v2.3.9/linux/scripts/ksymoops/misc.c	Tue Jan  5 11:13:56 1999
+++ linux/scripts/ksymoops/misc.c	Wed Dec 31 16:00:00 1969
@@ -1,108 +0,0 @@
-/*
-	misc.c.
-
-	Miscellaneous routines for ksymoops.
-
-	Copyright Keith Owens <ka...@ocs.com.au>.
-	Released under the GNU Public Licence, Version 2.
-
-	Tue Nov  3 02:31:01 EST 1998
-	Version 0.6
-	Convert from a.out to bfd, using same format as ksymoops.
-
-	Wed Oct 28 13:47:23 EST 1998
-	Version 0.4
-	Split into separate sources.
- */
-
-#include "ksymoops.h"
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-void malloc_error(const char *msg)
-{
-	fprintf(stderr, "%s: fatal malloc error for %s\n", prefix, msg);
-	exit(2);
-}
-
-/* Format an address with the correct number of leading zeroes */
-const char *format_address(elf_addr_t address)
-{
-	/* Well oversized */
-	static char format[10], text[200];
-	if (!*format)
-		snprintf(format, sizeof(format), "%%0%dlx",
-			2*sizeof(address));
-	snprintf(text, sizeof(text), format, address);
-	return(text);
-}
-
-/* Find the full pathname of a program.  Code heavily based on
- * glibc-2.0.5/posix/execvp.c.
- */
-char *find_fullpath(const char *program)
-{
-	char *fullpath = NULL;
-	char *path, *p;
-	size_t len;
-	static const char procname[] = "find_fullpath";
-
-	/* Don't search when it contains a slash.  */
-	if (strchr(program, '/')) {
-		if (!(fullpath = strdup(program)))
-			malloc_error(procname);
-		if (debug > 1)
-			fprintf(stderr, "DEBUG: %s %s\n", procname, fullpath);
-		return(fullpath);
-	}
-
-	path = getenv ("PATH");
-	if (!path) {
-		/* There is no `PATH' in the environment.  The default search
-		   path is the current directory followed by the path `confstr'
-		   returns for `_CS_PATH'.
-		 */
-		len = confstr(_CS_PATH, (char *) NULL, 0);
-		if (!(path = malloc(1 + len)))
-			malloc_error(procname);
-		path[0] = ':';
-		confstr(_CS_PATH, path+1, len);
-	}
-
-	len = strlen(program) + 1;
-	if (!(fullpath = malloc(strlen(path) + len)))
-		malloc_error(procname);
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 35'
echo 'File patch-2.3.10 is continued in part 36'
echo 36 > _shar_seq_.tmp
exit 0
#!/bin/sh
# this is part 33 of a 37 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.3.10 continued
if test ! -r _shar_seq_.tmp; then
        echo 'Please unpack part 1 first!'
        exit 1
fi
(read Scheck
if test "$Scheck" != 33; 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.3.10'
else
echo 'x - continuing with patch-2.3.10'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.3.10' &&
X 
X 	++tsk->maj_flt;
X 	++vma->vm_mm->rss;
@@ -866,6 +920,7 @@
X 		entry = pte_wrprotect(entry);
X 	set_pte(page_table, entry);
X 	/* no need to invalidate: a not-present page shouldn't be cached */
+	update_mmu_cache(vma, address, entry);
X 	return 1;
X }
X 
@@ -877,6 +932,15 @@
X  * There is also a hook called "update_mmu_cache()" that architectures
X  * with external mmu caches can use to update those (ie the Sparc or
X  * PowerPC hashed page tables that act as extended TLBs).
+ *
+ * Note the "page_table_lock". It is to protect against kswapd removing
+ * pages from under us. Note that kswapd only ever _removes_ pages, never
+ * adds them. As such, once we have noticed that the page is not present,
+ * we can drop the lock early.
+ *
+ * The adding of pages is protected by the MM semaphore (which we hold),
+ * so we don't need to worry about a page being suddenly been added into
+ * our VM.
X  */
X static inline int handle_pte_fault(struct task_struct *tsk,
X 	struct vm_area_struct * vma, unsigned long address,
@@ -884,27 +948,32 @@
X {
X 	pte_t entry;
X 
-	lock_kernel();
X 	entry = *pte;
-
X 	if (!pte_present(entry)) {
X 		if (pte_none(entry))
X 			return do_no_page(tsk, vma, address, write_access, pte);
-		return do_swap_page(tsk, vma, address, pte, entry, write_access);
+		return do_swap_page(tsk, vma, address, pte, pte_val(entry), write_access);
X 	}
X 
-	entry = pte_mkyoung(entry);
-	set_pte(pte, entry);
-	flush_tlb_page(vma, address);
-	if (write_access) {
-		if (!pte_write(entry))
-			return do_wp_page(tsk, vma, address, pte, entry);
+	/*
+	 * Ok, the entry was present, we need to get the page table
+	 * lock to synchronize with kswapd, and verify that the entry
+	 * didn't change from under us..
+	 */
+	spin_lock(&tsk->mm->page_table_lock);
+	if (pte_val(entry) == pte_val(*pte)) {
+		if (write_access) {
+			if (!pte_write(entry))
+				return do_wp_page(tsk, vma, address, pte, entry);
X 
-		entry = pte_mkdirty(entry);
+			entry = pte_mkdirty(entry);
+		}
+		entry = pte_mkyoung(entry);
X 		set_pte(pte, entry);
X 		flush_tlb_page(vma, address);
+		update_mmu_cache(vma, address, entry);
X 	}
-	unlock_kernel();
+	spin_unlock(&tsk->mm->page_table_lock);
X 	return 1;
X }
X 
@@ -921,28 +990,27 @@
X 	pmd = pmd_alloc(pgd, address);
X 	if (pmd) {
X 		pte_t * pte = pte_alloc(pmd, address);
-		if (pte) {
-			if (handle_pte_fault(tsk, vma, address, write_access, pte)) {
-				update_mmu_cache(vma, address, *pte);
-				return 1;
-			}
-		}
+		if (pte)
+			return handle_pte_fault(tsk, vma, address, write_access, pte);
X 	}
-	return 0;
+	return -1;
X }
X 
X /*
X  * Simplistic page force-in..
X  */
-void make_pages_present(unsigned long addr, unsigned long end)
+int make_pages_present(unsigned long addr, unsigned long end)
X {
X 	int write;
+	struct task_struct *tsk = current;
X 	struct vm_area_struct * vma;
X 
-	vma = find_vma(current->mm, addr);
+	vma = find_vma(tsk->mm, addr);
X 	write = (vma->vm_flags & VM_WRITE) != 0;
X 	while (addr < end) {
-		handle_mm_fault(current, vma, addr, write);
+		if (handle_mm_fault(tsk, vma, addr, write) < 0)
+			return -1;
X 		addr += PAGE_SIZE;
X 	}
+	return 0;
X }
diff -u --recursive --new-file v2.3.9/linux/mm/mlock.c linux/mm/mlock.c
--- v2.3.9/linux/mm/mlock.c	Wed Jun 30 13:38:20 1999
+++ linux/mm/mlock.c	Tue Jul  6 10:11:40 1999
@@ -31,7 +31,7 @@
X 	vma->vm_offset += vma->vm_start - n->vm_start;
X 	n->vm_flags = newflags;
X 	if (n->vm_file)
-		atomic_inc(&n->vm_file->f_count);
+		get_file(n->vm_file);
X 	if (n->vm_ops && n->vm_ops->open)
X 		n->vm_ops->open(n);
X 	insert_vm_struct(current->mm, n);
@@ -52,7 +52,7 @@
X 	n->vm_offset += n->vm_start - vma->vm_start;
X 	n->vm_flags = newflags;
X 	if (n->vm_file)
-		atomic_inc(&n->vm_file->f_count);
+		get_file(n->vm_file);
X 	if (n->vm_ops && n->vm_ops->open)
X 		n->vm_ops->open(n);
X 	insert_vm_struct(current->mm, n);
@@ -179,7 +179,6 @@
X 	int error = -ENOMEM;
X 
X 	down(¤t->mm->mmap_sem);
-	lock_kernel();
X 	len = (len + (start & ~PAGE_MASK) + ~PAGE_MASK) & PAGE_MASK;
X 	start &= PAGE_MASK;
X 
@@ -200,7 +199,6 @@
X 
X 	error = do_mlock(start, len, 1);
X out:
-	unlock_kernel();
X 	up(¤t->mm->mmap_sem);
X 	return error;
X }
@@ -210,11 +208,9 @@
X 	int ret;
X 
X 	down(¤t->mm->mmap_sem);
-	lock_kernel();
X 	len = (len + (start & ~PAGE_MASK) + ~PAGE_MASK) & PAGE_MASK;
X 	start &= PAGE_MASK;
X 	ret = do_mlock(start, len, 0);
-	unlock_kernel();
X 	up(¤t->mm->mmap_sem);
X 	return ret;
X }
@@ -254,7 +250,6 @@
X 	int ret = -EINVAL;
X 
X 	down(¤t->mm->mmap_sem);
-	lock_kernel();
X 	if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE)))
X 		goto out;
X 
@@ -272,7 +267,6 @@
X 
X 	ret = do_mlockall(flags);
X out:
-	unlock_kernel();
X 	up(¤t->mm->mmap_sem);
X 	return ret;
X }
@@ -282,9 +276,7 @@
X 	int ret;
X 
X 	down(¤t->mm->mmap_sem);
-	lock_kernel();
X 	ret = do_mlockall(0);
-	unlock_kernel();
X 	up(¤t->mm->mmap_sem);
X 	return ret;
X }
diff -u --recursive --new-file v2.3.9/linux/mm/mmap.c linux/mm/mmap.c
--- v2.3.9/linux/mm/mmap.c	Wed Jun 30 13:38:20 1999
+++ linux/mm/mmap.c	Tue Jul  6 10:11:40 1999
@@ -77,10 +77,12 @@
X 
X 	if (file) {
X 		if (vma->vm_flags & VM_DENYWRITE)
-			file->f_dentry->d_inode->i_writecount++;
+			atomic_inc(&file->f_dentry->d_inode->i_writecount);
+		spin_lock(&file->f_dentry->d_inode->i_shared_lock);
X 		if(vma->vm_next_share)
X 			vma->vm_next_share->vm_pprev_share = vma->vm_pprev_share;
X 		*vma->vm_pprev_share = vma->vm_next_share;
+		spin_unlock(&file->f_dentry->d_inode->i_shared_lock);
X 	}
X }
X 
@@ -294,7 +296,7 @@
X 	if (file) {
X 		int correct_wcount = 0;
X 		if (vma->vm_flags & VM_DENYWRITE) {
-			if (file->f_dentry->d_inode->i_writecount > 0) {
+			if (atomic_read(&file->f_dentry->d_inode->i_writecount) > 0) {
X 				error = -ETXTBSY;
X 				goto free_vma;
X 			}
@@ -303,17 +305,17 @@
X 			 * might). In any case, this takes care of any
X 			 * race that this might cause.
X 			 */
-			file->f_dentry->d_inode->i_writecount--;
+			atomic_dec(&file->f_dentry->d_inode->i_writecount);
X 			correct_wcount = 1;
X 		}
X 		error = file->f_op->mmap(file, vma);
X 		/* Fix up the count if necessary, then check for an error */
X 		if (correct_wcount)
-			file->f_dentry->d_inode->i_writecount++;
+			atomic_inc(&file->f_dentry->d_inode->i_writecount);
X 		if (error)
X 			goto unmap_and_free_vma;
X 		vma->vm_file = file;
-		atomic_inc(&file->f_count);
+		get_file(file);
X 	}
X 
X 	/*
@@ -547,7 +549,7 @@
X 		mpnt->vm_file = area->vm_file;
X 		mpnt->vm_pte = area->vm_pte;
X 		if (mpnt->vm_file)
-			atomic_inc(&mpnt->vm_file->f_count);
+			get_file(mpnt->vm_file);
X 		if (mpnt->vm_ops && mpnt->vm_ops->open)
X 			mpnt->vm_ops->open(mpnt);
X 		area->vm_end = addr;	/* Truncate area */
@@ -678,9 +680,9 @@
X 		size = end - st;
X 
X 		lock_kernel();
-
X 		if (mpnt->vm_ops && mpnt->vm_ops->unmap)
X 			mpnt->vm_ops->unmap(mpnt, st, size);
+		unlock_kernel();
X 
X 		remove_shared_vm_struct(mpnt);
X 		mm->map_count--;
@@ -693,8 +695,6 @@
X 		 * Fix the mapping, and free the old area if it wasn't reused.
X 		 */
X 		extra = unmap_fixup(mpnt, st, size, extra);
-
-		unlock_kernel();
X 	}
X 
X 	/* Release the extra vma struct if it wasn't used */
@@ -787,10 +787,8 @@
X 	flags = vma->vm_flags;
X 	addr = vma->vm_start;
X 
-	lock_kernel();		/* kswapd, ugh */
X 	insert_vm_struct(mm, vma);
X 	merge_segments(mm, vma->vm_start, vma->vm_end);
-	unlock_kernel();
X 	
X 	mm->total_vm += len >> PAGE_SHIFT;
X 	if (flags & VM_LOCKED) {
@@ -878,13 +876,15 @@
X 	if (file) {
X 		struct inode * inode = file->f_dentry->d_inode;
X 		if (vmp->vm_flags & VM_DENYWRITE)
-			inode->i_writecount--;
+			atomic_dec(&inode->i_writecount);
X       
X 		/* insert vmp into inode's share list */
+		spin_lock(&inode->i_shared_lock);
X 		if((vmp->vm_next_share = inode->i_mmap) != NULL)
X 			inode->i_mmap->vm_pprev_share = &vmp->vm_next_share;
X 		inode->i_mmap = vmp;
X 		vmp->vm_pprev_share = &inode->i_mmap;
+		spin_unlock(&inode->i_shared_lock);
X 	}
X }
X 
diff -u --recursive --new-file v2.3.9/linux/mm/mprotect.c linux/mm/mprotect.c
--- v2.3.9/linux/mm/mprotect.c	Wed Jun 30 13:38:20 1999
+++ linux/mm/mprotect.c	Tue Jul  6 10:11:40 1999
@@ -103,7 +103,7 @@
X 	n->vm_flags = newflags;
X 	n->vm_page_prot = prot;
X 	if (n->vm_file)
-		atomic_inc(&n->vm_file->f_count);
+		get_file(n->vm_file);
X 	if (n->vm_ops && n->vm_ops->open)
X 		n->vm_ops->open(n);
X 	insert_vm_struct(current->mm, n);
@@ -126,7 +126,7 @@
X 	n->vm_flags = newflags;
X 	n->vm_page_prot = prot;
X 	if (n->vm_file)
-		atomic_inc(&n->vm_file->f_count);
+		get_file(n->vm_file);
X 	if (n->vm_ops && n->vm_ops->open)
X 		n->vm_ops->open(n);
X 	insert_vm_struct(current->mm, n);
@@ -212,7 +212,6 @@
X 		return 0;
X 
X 	down(¤t->mm->mmap_sem);
-	lock_kernel();
X 
X 	vma = find_vma(current->mm, start);
X 	error = -EFAULT;
@@ -249,7 +248,6 @@
X 	}
X 	merge_segments(current->mm, start, end);
X out:
-	unlock_kernel();
X 	up(¤t->mm->mmap_sem);
X 	return error;
X }
diff -u --recursive --new-file v2.3.9/linux/mm/mremap.c linux/mm/mremap.c
--- v2.3.9/linux/mm/mremap.c	Wed Jun 30 13:38:20 1999
+++ linux/mm/mremap.c	Tue Jul  6 21:43:08 1999
@@ -57,11 +57,13 @@
X 	return pte;
X }
X 
-static inline int copy_one_pte(pte_t * src, pte_t * dst)
+static inline int copy_one_pte(struct mm_struct *mm, pte_t * src, pte_t * dst)
X {
X 	int error = 0;
-	pte_t pte = *src;
+	pte_t pte;
X 
+	spin_lock(&mm->page_table_lock);
+	pte = *src;
X 	if (!pte_none(pte)) {
X 		error++;
X 		if (dst) {
@@ -70,6 +72,7 @@
X 			error--;
X 		}
X 	}
+	spin_unlock(&mm->page_table_lock);
X 	return error;
X }
X 
@@ -80,7 +83,7 @@
X 
X 	src = get_one_pte(mm, old_addr);
X 	if (src)
-		error = copy_one_pte(src, alloc_one_pte(mm, new_addr));
+		error = copy_one_pte(mm, src, alloc_one_pte(mm, new_addr));
X 	return error;
X }
X 
@@ -134,14 +137,12 @@
X 			new_vma->vm_start = new_addr;
X 			new_vma->vm_end = new_addr+new_len;
X 			new_vma->vm_offset = vma->vm_offset + (addr - vma->vm_start);
-			lock_kernel();
X 			if (new_vma->vm_file)
-				atomic_inc(&new_vma->vm_file->f_count);
+				get_file(new_vma->vm_file);
X 			if (new_vma->vm_ops && new_vma->vm_ops->open)
X 				new_vma->vm_ops->open(new_vma);
X 			insert_vm_struct(current->mm, new_vma);
X 			merge_segments(current->mm, new_vma->vm_start, new_vma->vm_end);
-			unlock_kernel();
X 			do_munmap(addr, old_len);
X 			current->mm->total_vm += new_len >> PAGE_SHIFT;
X 			if (new_vma->vm_flags & VM_LOCKED) {
diff -u --recursive --new-file v2.3.9/linux/mm/page_alloc.c linux/mm/page_alloc.c
--- v2.3.9/linux/mm/page_alloc.c	Tue Jun 22 10:50:36 1999
+++ linux/mm/page_alloc.c	Fri Jul  2 15:10:36 1999
@@ -345,90 +345,3 @@
X 	}
X 	return start_mem;
X }
-
-/* 
- * Primitive swap readahead code. We simply read an aligned block of
- * (1 << page_cluster) entries in the swap area. This method is chosen
- * because it doesn't cost us any seek time.  We also make sure to queue
- * the 'original' request together with the readahead ones...  
- */
-void swapin_readahead(unsigned long entry)
-{
-	int i;
-	struct page *new_page;
-	unsigned long offset = SWP_OFFSET(entry);
-	struct swap_info_struct *swapdev = SWP_TYPE(entry) + swap_info;
-	
-	offset = (offset >> page_cluster) << page_cluster;
-
-	i = 1 << page_cluster;
-	do {
-		/* Don't read-ahead past the end of the swap area */
-		if (offset >= swapdev->max)
-			break;
-		/* Don't block on I/O for read-ahead */
-		if (atomic_read(&nr_async_pages) >= pager_daemon.swap_cluster)
-			break;
-		/* Don't read in bad or busy pages */
-		if (!swapdev->swap_map[offset])
-			break;
-		if (swapdev->swap_map[offset] == SWAP_MAP_BAD)
-			break;
-
-		/* Ok, do the async read-ahead now */
-		new_page = read_swap_cache_async(SWP_ENTRY(SWP_TYPE(entry), offset), 0);
-		if (new_page != NULL)
-			__free_page(new_page);
-		offset++;
-	} while (--i);
-	return;
-}
-
-/*
- * The tests may look silly, but it essentially makes sure that
- * no other process did a swap-in on us just as we were waiting.
- *
- * Also, don't bother to add to the swap cache if this page-in
- * was due to a write access.
- */
-void swap_in(struct task_struct * tsk, struct vm_area_struct * vma,
-	pte_t * page_table, unsigned long entry, int write_access)
-{
-	unsigned long page;
-	struct page *page_map = lookup_swap_cache(entry);
-
-	if (!page_map) {
-		swapin_readahead(entry);
-		page_map = read_swap_cache(entry);
-	}
-	if (pte_val(*page_table) != entry) {
-		if (page_map)
-			free_page_and_swap_cache(page_address(page_map));
-		return;
-	}
-	if (!page_map) {
-		set_pte(page_table, BAD_PAGE);
-		swap_free(entry);
-		oom(tsk);
-		return;
-	}
-
-	page = page_address(page_map);
-	vma->vm_mm->rss++;
-	tsk->min_flt++;
-	swap_free(entry);
-
-	if (!write_access || is_page_shared(page_map)) {
-		set_pte(page_table, mk_pte(page, vma->vm_page_prot));
-		return;
-	}
-
-	/*
-	 * The page is unshared and we're going to dirty it - so tear
-	 * down the swap cache and give exclusive access to the page to
-	 * this process.
-	 */
-	delete_from_swap_cache(page_map);
-	set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))));
-  	return;
-}
diff -u --recursive --new-file v2.3.9/linux/mm/vmscan.c linux/mm/vmscan.c
--- v2.3.9/linux/mm/vmscan.c	Tue Jun 22 14:36:36 1999
+++ linux/mm/vmscan.c	Sat Jul  3 12:04:12 1999
@@ -45,7 +45,11 @@
X 	page_addr = pte_page(pte);
X 	if (MAP_NR(page_addr) >= max_mapnr)
X 		goto out_failed;
+
X 	page = mem_map + MAP_NR(page_addr);
+	spin_lock(&tsk->mm->page_table_lock);
+	if (pte_val(pte) != pte_val(*page_table))
+		goto out_failed_unlock;
X 
X 	/*
X 	 * Dont be too eager to get aging right if
@@ -58,13 +62,13 @@
X 		 */
X 		set_pte(page_table, pte_mkold(pte));
X 		set_bit(PG_referenced, &page->flags);
-		goto out_failed;
+		goto out_failed_unlock;
X 	}
X 
X 	if (PageReserved(page)
X 	    || PageLocked(page)
X 	    || ((gfp_mask & __GFP_DMA) && !PageDMA(page)))
-		goto out_failed;
+		goto out_failed_unlock;
X 
X 	/*
X 	 * Is the page already in the swap cache? If so, then
@@ -82,7 +86,7 @@
X 		vma->vm_mm->rss--;
X 		flush_tlb_page(vma, address);
X 		__free_page(page);
-		goto out_failed;
+		goto out_failed_unlock;
X 	}
X 
X 	/*
@@ -109,7 +113,7 @@
X 	 * locks etc.
X 	 */
X 	if (!(gfp_mask & __GFP_IO))
-		goto out_failed;
+		goto out_failed_unlock;
X 
X 	/*
X 	 * Ok, it's really dirty. That means that
@@ -134,6 +138,7 @@
X 	if (vma->vm_ops && vma->vm_ops->swapout) {
X 		pid_t pid = tsk->pid;
X 		pte_clear(page_table);
+		spin_unlock(&tsk->mm->page_table_lock);
X 		flush_tlb_page(vma, address);
X 		vma->vm_mm->rss--;
X 		
@@ -155,6 +160,8 @@
X 	vma->vm_mm->rss--;
X 	tsk->nswap++;
X 	set_pte(page_table, __pte(entry));
+	spin_unlock(&tsk->mm->page_table_lock);
+
X 	flush_tlb_page(vma, address);
X 	swap_duplicate(entry);	/* One for the process, one for the swap cache */
X 
@@ -167,6 +174,8 @@
X out_free_success:
X 	__free_page(page);
X 	return 1;
+out_failed_unlock:
+	spin_unlock(&tsk->mm->page_table_lock);
X out_failed:
X 	return 0;
X }
diff -u --recursive --new-file v2.3.9/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c
--- v2.3.9/linux/net/appletalk/ddp.c	Fri Mar 26 14:01:40 1999
+++ linux/net/appletalk/ddp.c	Mon Jul  5 20:03:14 1999
@@ -894,7 +894,7 @@
X 			else
X 			{
X 				limit = ntohs(nr->nr_lastnet);
-				if(limit - ntohs(nr->nr_firstnet) > 256)
+				if(limit - ntohs(nr->nr_firstnet) > 4096)
X 				{
X 					printk(KERN_WARNING "Too many routes/iface.\n");
X 					return (-EINVAL);
@@ -938,6 +938,8 @@
X                                 return (-EPERM);
X                         if(sa->sat_family != AF_APPLETALK)
X                                 return (-EINVAL);
+                        if (atif == NULL)
+                                return (-EADDRNOTAVAIL);
X 
X                         /*
X                          * for now, we only support proxy AARP on ELAP;
@@ -987,6 +989,8 @@
X                                 return (-EPERM);
X                         if(sa->sat_family != AF_APPLETALK)
X                                 return (-EINVAL);
+                        if (atif == NULL)
+                                return (-EADDRNOTAVAIL);
X 
X                         /*
X                          * give to aarp module to remove proxy entry
diff -u --recursive --new-file v2.3.9/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c
--- v2.3.9/linux/net/ax25/af_ax25.c	Sun Mar  7 15:25:23 1999
+++ linux/net/ax25/af_ax25.c	Mon Jul  5 20:03:14 1999
@@ -462,6 +462,9 @@
X 	if ((ax25_dev = ax25_addr_ax25dev(&ax25_ctl.port_addr)) == NULL)
X 		return -ENODEV;
X 
+	if (ax25_ctl.digi_count > AX25_MAX_DIGIS)
+		return -EINVAL;
+
X 	digi.ndigi = ax25_ctl.digi_count;
X 	for (k = 0; k < digi.ndigi; k++)
X 		digi.calls[k] = ax25_ctl.digi_addr[k];
diff -u --recursive --new-file v2.3.9/linux/net/bridge/br.c linux/net/bridge/br.c
--- v2.3.9/linux/net/bridge/br.c	Sun Mar  7 15:25:23 1999
+++ linux/net/bridge/br.c	Mon Jul  5 20:03:14 1999
@@ -1831,12 +1831,8 @@
X 			
X /*			printk("Flood to port %d\n",i);*/
X 			nskb->nh.raw = nskb->data + ETH_HLEN;
-#if LINUX_VERSION_CODE >= 0x20100
X 			nskb->priority = 1;
X 			dev_queue_xmit(nskb);
-#else
-			dev_queue_xmit(nskb,nskb->dev,1);
-#endif
X 		}
X 	}
X 	return(0);
diff -u --recursive --new-file v2.3.9/linux/net/core/scm.c linux/net/core/scm.c
--- v2.3.9/linux/net/core/scm.c	Wed Jun 30 13:38:20 1999
+++ linux/net/core/scm.c	Sat Jul  3 10:43:11 1999
@@ -232,8 +232,8 @@
X 			break;
X 		}
X 		/* Bump the usage count and install the file. */
-		atomic_inc(&fp[i]->f_count);
-		current->files->fd[new_fd] = fp[i];
+		get_file(fp[i]);
+		fd_install(new_fd, fp[i]);
X 	}
X 
X 	if (i > 0)
@@ -271,10 +271,9 @@
X 
X 	new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL);
X 	if (new_fpl) {
-		memcpy(new_fpl, fpl, sizeof(*fpl));
-
X 		for (i=fpl->count-1; i>=0; i--)
-			atomic_inc(&fpl->fp[i]->f_count);
+			get_file(fpl->fp[i]);
+		memcpy(new_fpl, fpl, sizeof(*fpl));
X 	}
X 	return new_fpl;
X }
diff -u --recursive --new-file v2.3.9/linux/net/decnet/dn_fib.c linux/net/decnet/dn_fib.c
--- v2.3.9/linux/net/decnet/dn_fib.c	Wed May 26 09:36:36 1999
+++ linux/net/decnet/dn_fib.c	Mon Jul  5 20:35:18 1999
@@ -23,7 +23,6 @@
X #include <linux/proc_fs.h>
X #include <linux/netdevice.h>
X #include <linux/timer.h>
-#include <linux/rtnetlink.h>
X #include <asm/spinlock.h>
X #include <asm/atomic.h>
X #include <asm/uaccess.h>
diff -u --recursive --new-file v2.3.9/linux/net/econet/econet.c linux/net/econet/econet.c
--- v2.3.9/linux/net/econet/econet.c	Sun Mar  7 15:25:23 1999
+++ linux/net/econet/econet.c	Sat Jul  3 17:57:22 1999
@@ -759,7 +759,8 @@
X 		    (opt->station == station || opt->station == 0) &&
X 		    (opt->net == net || opt->net == 0))
X 			return sk;
-		sk = sk->sklist_next;
+
+		sk = sk->next;
X 	}
X 
X 	return NULL;
diff -u --recursive --new-file v2.3.9/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- v2.3.9/linux/net/ipv4/af_inet.c	Wed Jun  9 14:45:36 1999
+++ linux/net/ipv4/af_inet.c	Sat Jul  3 17:57:22 1999
@@ -5,7 +5,7 @@
X  *
X  *		PF_INET protocol family socket handler.
X  *
- * Version:	$Id: af_inet.c,v 1.91 1999/06/09 08:28:55 davem Exp $
+ * Version:	$Id: af_inet.c,v 1.93 1999/07/02 11:26:24 davem Exp $
X  *
X  * Authors:	Ross Biro, <bi...@leland.Stanford.Edu>
X  *		Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -162,9 +162,6 @@
X 
X static __inline__ void kill_sk_now(struct sock *sk)
X {
-	/* No longer exists. */
-	del_from_prot_sklist(sk);
-
X 	/* Remove from protocol hash chains. */
X 	sk->prot->unhash(sk);
X 
@@ -239,7 +236,7 @@
X {
X 	struct sock *sk=sock->sk;
X 	if (sk->prot->setsockopt==NULL)
-		return(-EOPNOTSUPP);
+		return -EOPNOTSUPP;
X 	return sk->prot->setsockopt(sk,level,optname,optval,optlen);
X }
X 
@@ -256,7 +253,7 @@
X {
X 	struct sock *sk=sock->sk;
X 	if (sk->prot->getsockopt==NULL)
-		return(-EOPNOTSUPP);
+		return -EOPNOTSUPP;
X 	return sk->prot->getsockopt(sk,level,optname,optval,optlen);
X }
X 
@@ -268,12 +265,10 @@
X {
X 	/* We may need to bind the socket. */
X 	if (sk->num == 0) {
-		sk->num = sk->prot->good_socknum();
-		if (sk->num == 0) 
-			return(-EAGAIN);
+		if (sk->prot->get_port(sk, 0) != 0)
+			return -EAGAIN;
X 		sk->sport = htons(sk->num);
X 		sk->prot->hash(sk);
-		add_to_prot_sklist(sk);
X 	}
X 	return 0;
X }
@@ -293,29 +288,38 @@
X int inet_listen(struct socket *sock, int backlog)
X {
X 	struct sock *sk = sock->sk;
+	unsigned char old_state;
X 
X 	if (sock->state != SS_UNCONNECTED || sock->type != SOCK_STREAM)
-		return(-EINVAL);
-
-	if (inet_autobind(sk) != 0)
-		return -EAGAIN;
+		return -EINVAL;
X 
-	/* We might as well re use these. */ 
X 	if ((unsigned) backlog == 0)	/* BSDism */
X 		backlog = 1;
X 	if ((unsigned) backlog > SOMAXCONN)
X 		backlog = SOMAXCONN;
X 	sk->max_ack_backlog = backlog;
-	if (sk->state != TCP_LISTEN) {
-		sk->ack_backlog = 0;
+
+	/* Really, if the socket is already in listen state
+	 * we can only allow the backlog to be adjusted.
+	 */
+	old_state = sk->state;
+	if (old_state != TCP_LISTEN) {
X 		sk->state = TCP_LISTEN;
+		sk->ack_backlog = 0;
+		if (sk->num == 0) {
+			if (sk->prot->get_port(sk, 0) != 0) {
+				sk->state = old_state;
+				return -EAGAIN;
+			}
+			sk->sport = htons(sk->num);
+		}
+
X 		dst_release(xchg(&sk->dst_cache, NULL));
-		sk->prot->rehash(sk);
-		add_to_prot_sklist(sk);
+		sk->prot->hash(sk);
+		sk->socket->flags |= SO_ACCEPTCON;
X 		sk->write_space = inet_listen_write_space;
X 	}
-	sk->socket->flags |= SO_ACCEPTCON;
-	return(0);
+	return 0;
X }
X 
X /*
@@ -427,7 +431,6 @@
X 
X 		/* Add to protocol hash chains. */
X 		sk->prot->hash(sk);
-		add_to_prot_sklist(sk);
X 	}
X 
X 	if (sk->prot->init) {
@@ -486,11 +489,9 @@
X 		 */
X 		timeout = 0;
X 		if (sk->linger && !(current->flags & PF_EXITING)) {
-			timeout = MAX_SCHEDULE_TIMEOUT;
-
-			/* XXX This makes no sense whatsoever... -DaveM */
-			if (!sk->lingertime)
-				timeout = HZ*sk->lingertime;
+			timeout = HZ * sk->lingertime;
+			if (!timeout)
+				timeout = MAX_SCHEDULE_TIMEOUT;
X 		}
X 		sock->sk = NULL;
X 		sk->socket = NULL;
@@ -543,21 +544,17 @@
X 	if((snum >= PORT_MASQ_BEGIN) && (snum <= PORT_MASQ_END))
X 		return -EADDRINUSE;
X #endif		 
-	if (snum == 0) 
-		snum = sk->prot->good_socknum();
-	if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
-		return(-EACCES);
+	if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
+		return -EACCES;
X 	
X 	/* Make sure we are allowed to bind here. */
-	if(sk->prot->verify_bind(sk, snum))
+	if (sk->prot->get_port(sk, snum) != 0)
X 		return -EADDRINUSE;
X 
-	sk->num = snum;
-	sk->sport = htons(snum);
+	sk->sport = htons(sk->num);
X 	sk->daddr = 0;
X 	sk->dport = 0;
-	sk->prot->rehash(sk);
-	add_to_prot_sklist(sk);
+	sk->prot->hash(sk);
X 	dst_release(sk->dst_cache);
X 	sk->dst_cache=NULL;
X 	return(0);
@@ -570,12 +567,12 @@
X 	int err;
X 
X 	if (inet_autobind(sk) != 0)
-		return(-EAGAIN);
+		return -EAGAIN;
X 	if (sk->prot->connect == NULL) 
-		return(-EOPNOTSUPP);
+		return -EOPNOTSUPP;
X 	err = sk->prot->connect(sk, (struct sockaddr *)uaddr, addr_len);
X 	if (err < 0) 
-		return(err);
+		return err;
X 	return(0);
X }
X 
@@ -626,18 +623,20 @@
X 		if (flags & O_NONBLOCK)
X 			return -EALREADY;
X 	} else {
+		if (sk->prot->connect == NULL) 
+			return -EOPNOTSUPP;
+
X 		/* We may need to bind the socket. */
X 		if (inet_autobind(sk) != 0)
-			return(-EAGAIN);
-		if (sk->prot->connect == NULL) 
-			return(-EOPNOTSUPP);
+			return -EAGAIN;
+
X 		err = sk->prot->connect(sk, uaddr, addr_len);
X 		/* Note: there is a theoretical race here when an wake up
X 		   occurred before inet_wait_for_connect is entered. In 2.3
X 		   the wait queue setup should be moved before the low level
X 		   connect call. -AK*/
X 		if (err < 0)
-			return(err);
+			return err;
X   		sock->state = SS_CONNECTING;
X 	}
X 	
@@ -645,7 +644,7 @@
X 		goto sock_error;
X 
X 	if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) 
-	  	return (-EINPROGRESS);
+	  	return -EINPROGRESS;
X 
X 	if (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV) {
X 		inet_wait_for_connect(sk);
@@ -656,7 +655,7 @@
X 	sock->state = SS_CONNECTED;
X 	if ((sk->state != TCP_ESTABLISHED) && sk->err)
X 		goto sock_error; 
-	return(0);
+	return 0;
X 
X sock_error:	
X 	/* This is ugly but needed to fix a race in the ICMP error handler */
@@ -750,7 +749,7 @@
X 	sin->sin_family = AF_INET;
X 	if (peer) {
X 		if (!tcp_connected(sk->state)) 
-			return(-ENOTCONN);
+			return -ENOTCONN;
X 		sin->sin_port = sk->dport;
X 		sin->sin_addr.s_addr = sk->daddr;
X 	} else {
@@ -774,12 +773,12 @@
X 	int err;
X 	
X 	if (sock->flags & SO_ACCEPTCON)
-		return(-EINVAL);
+		return -EINVAL;
X 	if (sk->prot->recvmsg == NULL) 
-		return(-EOPNOTSUPP);
+		return -EOPNOTSUPP;
X 	/* We may need to bind the socket. */
X 	if (inet_autobind(sk) != 0)
-		return(-EAGAIN);
+		return -EAGAIN;
X 	err = sk->prot->recvmsg(sk, msg, size, flags&MSG_DONTWAIT,
X 				flags&~MSG_DONTWAIT, &addr_len);
X 	if (err >= 0)
@@ -796,15 +795,15 @@
X 	if (sk->shutdown & SEND_SHUTDOWN) {
X 		if (!(msg->msg_flags&MSG_NOSIGNAL))
X 			send_sig(SIGPIPE, current, 1);
-		return(-EPIPE);
+		return -EPIPE;
X 	}
X 	if (sk->prot->sendmsg == NULL) 
-		return(-EOPNOTSUPP);
+		return -EOPNOTSUPP;
X 	if(sk->err)
X 		return sock_error(sk);
X 
X 	/* We may need to bind the socket. */
-	if(inet_autobind(sk) != 0)
+	if (inet_autobind(sk) != 0)
X 		return -EAGAIN;
X 
X 	return sk->prot->sendmsg(sk, msg, size);
@@ -822,11 +821,13 @@
X 		       1->2 bit 2 snds.
X 		       2->3 */
X 	if ((how & ~SHUTDOWN_MASK) || how==0)	/* MAXINT->0 */
-		return(-EINVAL);
+		return -EINVAL;
+	if (!sk)
+		return -ENOTCONN;
X 	if (sock->state == SS_CONNECTING && sk->state == TCP_ESTABLISHED)
X 		sock->state = SS_CONNECTED;
-	if (!sk || !tcp_connected(sk->state)) 
-		return(-ENOTCONN);
+	if (!tcp_connected(sk->state)) 
+		return -ENOTCONN;
X 	sk->shutdown |= how;
X 	if (sk->prot->shutdown)
X 		sk->prot->shutdown(sk, how);
diff -u --recursive --new-file v2.3.9/linux/net/ipv4/icmp.c linux/net/ipv4/icmp.c
--- v2.3.9/linux/net/ipv4/icmp.c	Wed Jun  9 14:45:37 1999
+++ linux/net/ipv4/icmp.c	Mon Jul  5 20:35:18 1999
@@ -269,7 +269,6 @@
X #include <net/tcp.h>
X #include <net/udp.h>
X #include <net/raw.h>
-#include <net/snmp.h>
X #include <linux/skbuff.h>
X #include <net/sock.h>
X #include <linux/errno.h>
diff -u --recursive --new-file v2.3.9/linux/net/ipv4/proc.c linux/net/ipv4/proc.c
--- v2.3.9/linux/net/ipv4/proc.c	Wed May 26 18:14:37 1999
+++ linux/net/ipv4/proc.c	Sat Jul  3 17:57:22 1999
@@ -7,7 +7,7 @@
X  *		PROC file system.  It is mainly used for debugging and
X  *		statistics.
X  *
- * Version:	$Id: proc.c,v 1.35 1999/05/27 00:37:38 davem Exp $
+ * Version:	$Id: proc.c,v 1.36 1999/07/02 11:26:34 davem Exp $
X  *
X  * Authors:	Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
X  *		Gerald J. Heim, <he...@peanuts.informatik.uni-tuebingen.de>
@@ -49,189 +49,6 @@
X #include <linux/skbuff.h>
X #include <net/sock.h>
X #include <net/raw.h>
-
-/* Format a single open_request into tmpbuf. */
-static inline void get__openreq(struct sock *sk, struct open_request *req, 
-				char *tmpbuf, 
-				int i)
-{
-	sprintf(tmpbuf, "%4d: %08lX:%04X %08lX:%04X"
-		" %02X %08X:%08X %02X:%08lX %08X %5d %8d %u",
-		i,
-		(long unsigned int)req->af.v4_req.loc_addr,
-		ntohs(sk->sport),
-		(long unsigned int)req->af.v4_req.rmt_addr,
-		ntohs(req->rmt_port),
-		TCP_SYN_RECV,
-		0,0, /* could print option size, but that is af dependent. */
-		1,   /* timers active (only the expire timer) */  
-		(unsigned long)(req->expires - jiffies), 
-		req->retrans,
-		sk->socket ? sk->socket->inode->i_uid : 0,
-		0,  /* non standard timer */  
-		0 /* open_requests have no inode */
-		); 
-}
-
-/* Format a single socket into tmpbuf. */
-static inline void get__sock(struct sock *sp, char *tmpbuf, int i, int format)
-{
-	unsigned long  dest, src;
-	unsigned short destp, srcp;
-	int timer_active, timer_active1, timer_active2;
-	int tw_bucket = 0;
-	unsigned long timer_expires;
-	struct tcp_opt *tp = &sp->tp_pinfo.af_tcp;
-
-	dest  = sp->daddr;
-	src   = sp->rcv_saddr;
-	destp = sp->dport;
-	srcp  = sp->sport;
-	
-	/* FIXME: The fact that retransmit_timer occurs as a field
-	 * in two different parts of the socket structure is,
-	 * to say the least, confusing. This code now uses the
-	 * right retransmit_timer variable, but I'm not sure
-	 * the rest of the timer stuff is still correct.
-	 * In particular I'm not sure what the timeout value
-	 * is suppose to reflect (as opposed to tm->when). -- erics
-	 */
-	
-	destp = ntohs(destp);
-	srcp  = ntohs(srcp);
-	if((format == 0) && (sp->state == TCP_TIME_WAIT)) {
-		extern int tcp_tw_death_row_slot;
-		struct tcp_tw_bucket *tw = (struct tcp_tw_bucket *)sp;
-		int slot_dist;
-
-		tw_bucket	= 1;
-		timer_active1	= timer_active2 = 0;
-		timer_active	= 3;
-		slot_dist	= tw->death_slot;
-		if(slot_dist > tcp_tw_death_row_slot)
-			slot_dist = (TCP_TWKILL_SLOTS - slot_dist) + tcp_tw_death_row_slot;
-		else
-			slot_dist = tcp_tw_death_row_slot - slot_dist;
-		timer_expires	= jiffies + (slot_dist * TCP_TWKILL_PERIOD);
-	} else {
-		timer_active1 = tp->retransmit_timer.prev != NULL;
-		timer_active2 = sp->timer.prev != NULL;
-		timer_active	= 0;
-		timer_expires	= (unsigned) -1;
-	}
-	if (timer_active1 && tp->retransmit_timer.expires < timer_expires) {
-		timer_active	= 1;
-		timer_expires	= tp->retransmit_timer.expires;
-	}
-	if (timer_active2 && sp->timer.expires < timer_expires) {
-		timer_active	= 2;
-		timer_expires	= sp->timer.expires;
-	}
-	if(timer_active == 0)
-		timer_expires = jiffies;
-	sprintf(tmpbuf, "%4d: %08lX:%04X %08lX:%04X"
-		" %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld",
-		i, src, srcp, dest, destp, sp->state, 
-		(tw_bucket ?
-		 0 :
-		 (format == 0) ?
-		 tp->write_seq-tp->snd_una : atomic_read(&sp->wmem_alloc)),
-		(tw_bucket ?
-		 0 :
-		 (format == 0) ?
-		 tp->rcv_nxt-tp->copied_seq: atomic_read(&sp->rmem_alloc)),
-		timer_active, timer_expires-jiffies,
-		(tw_bucket ? 0 : tp->retransmits),
-		(!tw_bucket && sp->socket) ? sp->socket->inode->i_uid : 0,
-		(!tw_bucket && timer_active) ? sp->timeout : 0,
-		(!tw_bucket && sp->socket) ? sp->socket->inode->i_ino : 0);
-}
-
-/*
- * Get__netinfo returns the length of that string.
- *
- * KNOWN BUGS
- *  As in get_unix_netinfo, the buffer might be too small. If this
- *  happens, get__netinfo returns only part of the available infos.
- *
- *  Assumes that buffer length is a multiply of 128 - if not it will
- *  write past the end.   
- */
-static int
-get__netinfo(struct proto *pro, char *buffer, int format, char **start, off_t offset, int length)
-{
-	struct sock *sp, *next;
-	int len=0, i = 0;
-	off_t pos=0;
-	off_t begin;
-	char tmpbuf[129];
-  
-	if (offset < 128) 
-		len += sprintf(buffer, "%-127s\n",
-			       "  sl  local_address rem_address   st tx_queue "
-			       "rx_queue tr tm->when retrnsmt   uid  timeout inode");
-	pos = 128;
-	SOCKHASH_LOCK_READ();
-	sp = pro->sklist_next;
-	while(sp != (struct sock *)pro) {
-		if (format == 0 && sp->state == TCP_LISTEN) {
-			struct open_request *req;
-
-			for (req = sp->tp_pinfo.af_tcp.syn_wait_queue; req;
-			     i++, req = req->dl_next) {
-				if (req->sk)
-					continue;
-				pos += 128;
-				if (pos < offset) 
-					continue;
-				get__openreq(sp, req, tmpbuf, i); 
-				len += sprintf(buffer+len, "%-127s\n", tmpbuf);
-				if(len >= length) 
-					goto out;
-			}
-		}
-		
-		pos += 128;
-		if (pos < offset)
-			goto next;
-		
-		get__sock(sp, tmpbuf, i, format);
-		
-		len += sprintf(buffer+len, "%-127s\n", tmpbuf);
-		if(len >= length)
-			break;
-	next:
-		next = sp->sklist_next;
-		sp = next;
-		i++;
-	}
-out: 
-	SOCKHASH_UNLOCK_READ();
-	
-	begin = len - (pos - offset);
-	*start = buffer + begin;
-	len -= begin;
-	if(len>length)
-		len = length;
-	if (len<0)
-		len = 0; 
-	return len;
-} 
-
-int tcp_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
-{
-	return get__netinfo(&tcp_prot, buffer,0, start, offset, length);
-}
-
-int udp_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
-{
-	return get__netinfo(&udp_prot, buffer,1, start, offset, length);
-}
-
-int raw_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
-{
-	return get__netinfo(&raw_prot, buffer,1, start, offset, length);
-}
X 
X /*
X  *	Report socket allocation statistics [m...@utu.fi]
diff -u --recursive --new-file v2.3.9/linux/net/ipv4/raw.c linux/net/ipv4/raw.c
--- v2.3.9/linux/net/ipv4/raw.c	Mon May 31 22:07:43 1999
+++ linux/net/ipv4/raw.c	Sat Jul  3 17:57:23 1999
@@ -5,7 +5,7 @@
X  *
X  *		RAW - implementation of IP "raw" sockets.
X  *
- * Version:	$Id: raw.c,v 1.41 1999/05/30 01:16:19 davem Exp $
+ * Version:	$Id: raw.c,v 1.42 1999/07/02 11:26:26 davem Exp $
X  *
X  * Authors:	Ross Biro, <bi...@leland.Stanford.Edu>
X  *		Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -70,60 +70,32 @@
X 
X static void raw_v4_hash(struct sock *sk)
X {
-	struct sock **skp;
-	int num = sk->num;
+	struct sock **skp = &raw_v4_htable[sk->num & (RAWV4_HTABLE_SIZE - 1)];
X 
-	num &= (RAWV4_HTABLE_SIZE - 1);
-	skp = &raw_v4_htable[num];
X 	SOCKHASH_LOCK_WRITE();
-	sk->next = *skp;
+	if ((sk->next = *skp) != NULL)
+		(*skp)->pprev = &sk->next;
X 	*skp = sk;
-	sk->hashent = num;
+	sk->pprev = skp;
+	sk->prot->inuse++;
+	if(sk->prot->highestinuse < sk->prot->inuse)
+		sk->prot->highestinuse = sk->prot->inuse;
X 	SOCKHASH_UNLOCK_WRITE();
X }
X 
X static void raw_v4_unhash(struct sock *sk)
X {
-	struct sock **skp;
-	int num = sk->num;
-
-	num &= (RAWV4_HTABLE_SIZE - 1);
-	skp = &raw_v4_htable[num];
-
X 	SOCKHASH_LOCK_WRITE();
-	while(*skp != NULL) {
-		if(*skp == sk) {
-			*skp = sk->next;
-			break;
-		}
-		skp = &((*skp)->next);
+	if (sk->pprev) {
+		if (sk->next)
+			sk->next->pprev = sk->pprev;
+		*sk->pprev = sk->next;
+		sk->pprev = NULL;
+		sk->prot->inuse--;
X 	}
X 	SOCKHASH_UNLOCK_WRITE();
X }
X 
-static void raw_v4_rehash(struct sock *sk)
-{
-	struct sock **skp;
-	int num = sk->num;
-	int oldnum = sk->hashent;
-
-	num &= (RAWV4_HTABLE_SIZE - 1);
-	skp = &raw_v4_htable[oldnum];
-
-	SOCKHASH_LOCK_WRITE();
-	while(*skp != NULL) {
-		if(*skp == sk) {
-			*skp = sk->next;
-			break;
-		}
-		skp = &((*skp)->next);
-	}
-	sk->next = raw_v4_htable[num];
-	raw_v4_htable[num] = sk;
-	sk->hashent = num;
-	SOCKHASH_UNLOCK_WRITE();
-}
-
X static __inline__ struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
X 					       unsigned long raddr, unsigned long laddr,
X 					       int dif)
@@ -640,9 +612,69 @@
X 	return -ENOPROTOOPT;
X }
X 
+static void get_raw_sock(struct sock *sp, char *tmpbuf, int i)
+{
+	unsigned int dest, src;
+	__u16 destp, srcp;
+	int timer_active;
+	unsigned long timer_expires;
+
+	dest  = sp->daddr;
+	src   = sp->rcv_saddr;
+	destp = ntohs(sp->dport);
+	srcp  = ntohs(sp->sport);
+	timer_active = (sp->timer.prev != NULL) ? 2 : 0;
+	timer_expires = (timer_active == 2 ? sp->timer.expires : jiffies);
+	sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
+		" %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld",
+		i, src, srcp, dest, destp, sp->state, 
+		atomic_read(&sp->wmem_alloc), atomic_read(&sp->rmem_alloc),
+		timer_active, timer_expires-jiffies, 0,
+		sp->socket->inode->i_uid, timer_active ? sp->timeout : 0,
+		sp->socket ? sp->socket->inode->i_ino : 0);
+}
+
+int raw_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
+{
+	int len = 0, num = 0, i;
+	off_t pos = 0;
+	off_t begin;
+	char tmpbuf[129];
+
+	if (offset < 128) 
+		len += sprintf(buffer, "%-127s\n",
+			       "  sl  local_address rem_address   st tx_queue "
+			       "rx_queue tr tm->when retrnsmt   uid  timeout inode");
+	pos = 128;
+	SOCKHASH_LOCK_READ();
+	for (i = 0; i < RAWV4_HTABLE_SIZE; i++) {
+		struct sock *sk;
+
+		for (sk = raw_v4_htable[i]; sk; sk = sk->next, num++) {
+			if (sk->family != PF_INET)
+				continue;
+			pos += 128;
+			if (pos < offset)
+				continue;
+			get_raw_sock(sk, tmpbuf, i);
+			len += sprintf(buffer+len, "%-127s\n", tmpbuf);
+			if(len >= length)
+				goto out;
+		}
+	}
+out:
+	SOCKHASH_UNLOCK_READ();
+	begin = len - (pos - offset);
+	*start = buffer + begin;
+	len -= begin;
+	if(len > length)
+		len = length;
+	if (len < 0)
+		len = 0; 
+	return len;
+}
+
X struct proto raw_prot = {
-	(struct sock *)&raw_prot,	/* sklist_next */
-	(struct sock *)&raw_prot,	/* sklist_prev */
X 	raw_close,			/* close */
X 	udp_connect,			/* connect */
X 	NULL,				/* accept */
@@ -666,9 +698,7 @@
X 	raw_rcv_skb,			/* backlog_rcv */
X 	raw_v4_hash,			/* hash */
X 	raw_v4_unhash,			/* unhash */
-	raw_v4_rehash,			/* rehash */
-	NULL,				/* good_socknum */
-	NULL,				/* verify_bind */
+	NULL,				/* get_port */
X 	128,				/* max_header */
X 	0,				/* retransmits */
X 	"RAW",				/* name */
diff -u --recursive --new-file v2.3.9/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v2.3.9/linux/net/ipv4/tcp.c	Wed Jun 30 13:38:20 1999
+++ linux/net/ipv4/tcp.c	Mon Jul  5 20:22:09 1999
@@ -1339,7 +1339,7 @@
X 		break;
X 	}
X 
-	if(copied > 0 && msg->msg_name)
+	if (copied > 0 && msg->msg_name)
X 		tp->af_specific->addr2sockaddr(sk, (struct sockaddr *)
X 					       msg->msg_name);       
X 
diff -u --recursive --new-file v2.3.9/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- v2.3.9/linux/net/ipv4/tcp_input.c	Wed Jun  9 14:45:37 1999
+++ linux/net/ipv4/tcp_input.c	Sat Jul  3 17:57:23 1999
@@ -5,7 +5,7 @@
X  *
X  *		Implementation of the Transmission Control Protocol(TCP).
X  *
- * Version:	$Id: tcp_input.c,v 1.169 1999/06/09 08:29:13 davem Exp $
+ * Version:	$Id: tcp_input.c,v 1.170 1999/07/02 11:26:28 davem Exp $
X  *
X  * Authors:	Ross Biro, <bi...@leland.Stanford.Edu>
X  *		Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -917,25 +917,26 @@
X /* Must be called only from BH context. */
X void tcp_timewait_kill(struct tcp_tw_bucket *tw)
X {
+	struct tcp_bind_bucket *tb = tw->tb;
+
X 	SOCKHASH_LOCK_WRITE_BH();
X 
-	/* Unlink from various places. */
+	/* Disassociate with bind bucket. */
X 	if(tw->bind_next)
X 		tw->bind_next->bind_pprev = tw->bind_pprev;
X 	*(tw->bind_pprev) = tw->bind_next;
-	if(tw->tb->owners == NULL)
-		tcp_inc_slow_timer(TCP_SLT_BUCKETGC);
+	if (tb->owners == NULL) {
+		if (tb->next)
+			tb->next->pprev = tb->pprev;
+		*(tb->pprev) = tb->next;
+		kmem_cache_free(tcp_bucket_cachep, tb);
+	}
X 
+	/* Unlink from established hashes. */
X 	if(tw->next)
X 		tw->next->pprev = tw->pprev;
X 	*tw->pprev = tw->next;
X 
-	/* We decremented the prot->inuse count when we entered TIME_WAIT
-	 * and the sock from which this came was destroyed.
-	 */
-	tw->sklist_next->sklist_prev = tw->sklist_prev;
-	tw->sklist_prev->sklist_next = tw->sklist_next;
-
X 	SOCKHASH_UNLOCK_WRITE_BH();
X 
X 	/* Ok, now free it up. */
@@ -1040,11 +1041,9 @@
X 		sk->bind_next->bind_pprev = &tw->bind_next;
X 	tw->bind_pprev = sk->bind_pprev;
X 	*sk->bind_pprev = (struct sock *)tw;
+	sk->prev = NULL;
X 
-	/* Step 3: Same for the protocol sklist. */
-	(tw->sklist_next = sk->sklist_next)->sklist_prev = (struct sock *)tw;
-	(tw->sklist_prev = sk->sklist_prev)->sklist_next = (struct sock *)tw;
-	sk->sklist_next = NULL;
+	/* Step 3: Un-charge protocol socket in-use count. */
X 	sk->prot->inuse--;
X 
X 	/* Step 4: Hash TW into TIMEWAIT half of established hash table. */
diff -u --recursive --new-file v2.3.9/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- v2.3.9/linux/net/ipv4/tcp_ipv4.c	Wed Jun  9 14:45:37 1999
+++ linux/net/ipv4/tcp_ipv4.c	Mon Jul  5 11:30:11 1999
@@ -5,7 +5,7 @@
X  *
X  *		Implementation of the Transmission Control Protocol(TCP).
X  *
- * Version:	$Id: tcp_ipv4.c,v 1.180 1999/06/09 08:29:19 davem Exp $
+ * Version:	$Id: tcp_ipv4.c,v 1.182 1999/07/05 01:34:07 davem Exp $
X  *
X  *		IPv4 specific functions
X  *
@@ -132,28 +132,9 @@
X 	return tcp_hashfn(laddr, lport, faddr, fport);
X }
X 
-/* Invariant, sk->num is non-zero. */
-void tcp_bucket_unlock(struct sock *sk)
-{
-	struct tcp_bind_bucket *tb;
-	unsigned short snum = sk->num;
-
-	SOCKHASH_LOCK_WRITE();
-	for(tb = tcp_bhash[tcp_bhashfn(snum)]; tb; tb = tb->next) {
-		if(tb->port == snum) {
-			if(tb->owners == NULL &&
-			   (tb->flags & TCPB_FLAG_LOCKED)) {
-				tb->flags &= ~(TCPB_FLAG_LOCKED |
-					       TCPB_FLAG_FASTREUSE);
-				tcp_inc_slow_timer(TCP_SLT_BUCKETGC);
-			}
-			break;
-		}
-	}
-	SOCKHASH_UNLOCK_WRITE();
-}
-
-/* The sockhash lock must be held as a writer here. */
+/* Allocate and initialize a new TCP local port bind bucket.
+ * The sockhash lock must be held as a writer here.
+ */
X struct tcp_bind_bucket *tcp_bucket_create(unsigned short snum)
X {
X 	struct tcp_bind_bucket *tb;
@@ -163,7 +144,7 @@
X 		struct tcp_bind_bucket **head =
X 			&tcp_bhash[tcp_bhashfn(snum)];
X 		tb->port = snum;
-		tb->flags = TCPB_FLAG_LOCKED;
+		tb->fastreuse = 0;
X 		tb->owners = NULL;
X 		if((tb->next = *head) != NULL)
X 			tb->next->pprev = &tb->next;
@@ -186,133 +167,176 @@
X 	tb = tcp_bhash[tcp_bhashfn(snum)];
X 	for( ; (tb && (tb->port != snum)); tb = tb->next)
X 		;
-	if(tb == NULL && tcp_bucket_create(snum) == NULL)
-		ret = 1;
+	ret = 0;
+	if (tb == NULL) {
+		if ((tb = tcp_bucket_create(snum)) == NULL)
+			ret = 1;
+	}
X 	SOCKHASH_UNLOCK_WRITE();
X 
X 	return ret;
X }
X #endif
X 
-static int tcp_v4_verify_bind(struct sock *sk, unsigned short snum)
+static __inline__ void __tcp_inherit_port(struct sock *sk, struct sock *child)
+{
+	struct tcp_bind_bucket *tb = (struct tcp_bind_bucket *)sk->prev;
+
+	if ((child->bind_next = tb->owners) != NULL)
+		tb->owners->bind_pprev = &child->bind_next;
+	tb->owners = child;
+	child->bind_pprev = &tb->owners;
+	child->prev = (struct sock *) tb;
+}
+
+__inline__ void tcp_inherit_port(struct sock *sk, struct sock *child)
+{
+	SOCKHASH_LOCK_WRITE();
+	__tcp_inherit_port(sk, child);
+	SOCKHASH_UNLOCK_WRITE();
+}
+
+/* Obtain a reference to a local port for the given sock,
+ * if snum is zero it means select any available local port.
+ */
+static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
X {
X 	struct tcp_bind_bucket *tb;
-	int result = 0;
X 
X 	SOCKHASH_LOCK_WRITE();
-	for(tb = tcp_bhash[tcp_bhashfn(snum)];
-	    (tb && (tb->port != snum));
-	    tb = tb->next)
-		;
-	if(tb && tb->owners) {
-		/* Fast path for reuse ports, see include/net/tcp.h for a very
-		 * detailed description of why this works, and why it is worth
-		 * the effort at all. -DaveM
-		 */
-		if((tb->flags & TCPB_FLAG_FASTREUSE)	&&
-		   (sk->reuse != 0)) {
-			goto go_like_smoke;
+	if (snum == 0) {
+		int rover = tcp_port_rover;
+		int low = sysctl_local_port_range[0];
+		int high = sysctl_local_port_range[1];
+		int remaining = (high - low) + 1;
+
+		do {	rover++;
+			if ((rover < low) || (rover > high))
+				rover = low;
+			tb = tcp_bhash[tcp_bhashfn(rover)];
+			for ( ; tb; tb = tb->next)
+				if (tb->port == rover)
+					goto next;
+			break;
+		next:
+		} while (--remaining > 0);
+		tcp_port_rover = rover;
+
+		/* Exhausted local port range during search? */
+		if (remaining <= 0)
+			goto fail;
+
+		/* OK, here is the one we will use. */
+		snum = rover;
+		tb = NULL;
+	} else {
+		for (tb = tcp_bhash[tcp_bhashfn(snum)];
+		     tb != NULL;
+		     tb = tb->next)
+			if (tb->port == snum)
+				break;
+	}
+	if (tb != NULL && tb->owners != NULL) {
+		if (tb->fastreuse != 0 && sk->reuse != 0) {
+			goto success;
X 		} else {
-			struct sock *sk2;
+			struct sock *sk2 = tb->owners;
X 			int sk_reuse = sk->reuse;
X 
-			/* We must walk the whole port owner list in this case. -DaveM */
-			for(sk2 = tb->owners; sk2; sk2 = sk2->bind_next) {
+			for( ; sk2 != NULL; sk2 = sk2->bind_next) {
X 				if (sk->bound_dev_if == sk2->bound_dev_if) {
-					if(!sk_reuse || !sk2->reuse || sk2->state == TCP_LISTEN) {
-						if(!sk2->rcv_saddr		||
-						   !sk->rcv_saddr		||
-						   (sk2->rcv_saddr == sk->rcv_saddr))
+					if (!sk_reuse	||
+					    !sk2->reuse	||
+					    sk2->state == TCP_LISTEN) {
+						if (!sk2->rcv_saddr	||
+						    !sk->rcv_saddr	||
+						    (sk2->rcv_saddr == sk->rcv_saddr))
X 							break;
X 					}
X 				}
X 			}
-			if(sk2 != NULL)
-				result = 1;
-		}
-	}
-	if(result == 0) {
-		if(tb == NULL) {
-			if((tb = tcp_bucket_create(snum)) == NULL)
-				result = 1;
-			else if (sk->reuse && sk->state != TCP_LISTEN)
-				tb->flags |= TCPB_FLAG_FASTREUSE;
-		} else {
-			/* It could be pending garbage collection, this
-			 * kills the race and prevents it from disappearing
-			 * out from under us by the time we use it.  -DaveM
-			 */
-			if(tb->owners == NULL) {
-				if (!(tb->flags & TCPB_FLAG_LOCKED)) {
-					tb->flags = (TCPB_FLAG_LOCKED |
-						     ((sk->reuse &&
-						       sk->state != TCP_LISTEN) ?
-						      TCPB_FLAG_FASTREUSE : 0));
-					tcp_dec_slow_timer(TCP_SLT_BUCKETGC);
-				} else if (!(tb->flags & TCPB_FLAG_GOODSOCKNUM)) {
-					/* Someone is in between the bind
-					 * and the actual connect or listen.
-					 * See if it was a legitimate reuse
-					 * and we are as well, else punt.
-					 */
-					if (sk->reuse == 0 ||
-					    !(tb->flags & TCPB_FLAG_FASTREUSE))
-						result = 1;
-				} else
-					tb->flags &= ~TCPB_FLAG_GOODSOCKNUM;
-			}
+			/* If we found a conflict, fail. */
+			if (sk2 != NULL)
+				goto fail;
X 		}
X 	}
-go_like_smoke:
+	if (tb == NULL &&
+	    (tb = tcp_bucket_create(snum)) == NULL)
+			goto fail;
+	if (tb->owners == NULL) {
+		if (sk->reuse && sk->state != TCP_LISTEN)
+			tb->fastreuse = 1;
+		else
+			tb->fastreuse = 0;
+	} else if (tb->fastreuse &&
+		   ((sk->reuse == 0) || (sk->state == TCP_LISTEN)))
+		tb->fastreuse = 0;
+success:
+	sk->num = snum;
+	if ((sk->bind_next = tb->owners) != NULL)
+		tb->owners->bind_pprev = &sk->bind_next;
+	tb->owners = sk;
+	sk->bind_pprev = &tb->owners;
+	sk->prev = (struct sock *) tb;
+
X 	SOCKHASH_UNLOCK_WRITE();
-	return result;
+	return 0;
+
+fail:
+	SOCKHASH_UNLOCK_WRITE();
+	return 1;
X }
X 
-unsigned short tcp_good_socknum(void)
+/* Get rid of any references to a local port held by the
+ * given sock.
+ */
+__inline__ void __tcp_put_port(struct sock *sk)
X {
X 	struct tcp_bind_bucket *tb;
-	int low = sysctl_local_port_range[0];
-	int high = sysctl_local_port_range[1];
-	int remaining = (high - low) + 1;
-	int rover;
X 
+	tb = (struct tcp_bind_bucket *) sk->prev;
+	if (sk->bind_next)
+		sk->bind_next->bind_pprev = sk->bind_pprev;
+	*(sk->bind_pprev) = sk->bind_next;
+	sk->prev = NULL;
+	if (tb->owners == NULL) {
+		if (tb->next)
+			tb->next->pprev = tb->pprev;
+		*(tb->pprev) = tb->next;
+		kmem_cache_free(tcp_bucket_cachep, tb);
+	}
+}
+
+void tcp_put_port(struct sock *sk)
+{
X 	SOCKHASH_LOCK_WRITE();
-	rover = tcp_port_rover;
-	do {
-		rover += 1;
-		if((rover < low) || (rover > high))
-			rover = low;
-		tb = tcp_bhash[tcp_bhashfn(rover)];
-		for( ; tb; tb = tb->next) {
-			if(tb->port == rover)
-				goto next;
-		}
-		break;
-	next:
-	} while(--remaining > 0);
-	tcp_port_rover = rover;
-	tb = NULL;
-	if((remaining <= 0) || ((tb = tcp_bucket_create(rover)) == NULL))
-		rover = 0;
-	if (tb != NULL)
-		tb->flags |= TCPB_FLAG_GOODSOCKNUM;
+	__tcp_put_port(sk);
X 	SOCKHASH_UNLOCK_WRITE();
+}
+
+static __inline__ void __tcp_v4_hash(struct sock *sk)
+{
+	struct sock **skp;
+
+	if(sk->state == TCP_LISTEN)
+		skp = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)];
+	else
+		skp = &tcp_ehash[(sk->hashent = tcp_sk_hashfn(sk))];
X 
-	return rover;
+	if((sk->next = *skp) != NULL)
+		(*skp)->pprev = &sk->next;
+	*skp = sk;
+	sk->pprev = skp;
+	sk->prot->inuse++;
+	if(sk->prot->highestinuse < sk->prot->inuse)
+		sk->prot->highestinuse = sk->prot->inuse;
X }
X 
X static void tcp_v4_hash(struct sock *sk)
X {
X 	if (sk->state != TCP_CLOSE) {
-		struct sock **skp;
-
X 		SOCKHASH_LOCK_WRITE();
-		skp = &tcp_ehash[(sk->hashent = tcp_sk_hashfn(sk))];
-		if((sk->next = *skp) != NULL)
-			(*skp)->pprev = &sk->next;
-		*skp = sk;
-		sk->pprev = skp;
-		tcp_sk_bindify(sk);
+		__tcp_v4_hash(sk);
X 		SOCKHASH_UNLOCK_WRITE();
X 	}
X }
@@ -325,39 +349,9 @@
X 			sk->next->pprev = sk->pprev;
X 		*sk->pprev = sk->next;
X 		sk->pprev = NULL;
+		sk->prot->inuse--;
X 		tcp_reg_zap(sk);
-		tcp_sk_unbindify(sk);
-	}
-	SOCKHASH_UNLOCK_WRITE();
-}
-
-static void tcp_v4_rehash(struct sock *sk)
-{
-	unsigned char state;
-
-	SOCKHASH_LOCK_WRITE();
-	state = sk->state;
-	if(sk->pprev != NULL) {
-		if(sk->next)
-			sk->next->pprev = sk->pprev;
-		*sk->pprev = sk->next;
-		sk->pprev = NULL;
-		tcp_reg_zap(sk);
-	}
-	if(state != TCP_CLOSE) {
-		struct sock **skp;
-
-		if(state == TCP_LISTEN)
-			skp = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)];
-		else
-			skp = &tcp_ehash[(sk->hashent = tcp_sk_hashfn(sk))];
-
-		if((sk->next = *skp) != NULL)
-			(*skp)->pprev = &sk->next;
-		*skp = sk;
-		sk->pprev = skp;
-		if(state == TCP_LISTEN)
-			tcp_sk_bindify(sk);
+		__tcp_put_port(sk);
X 	}
X 	SOCKHASH_UNLOCK_WRITE();
X }
@@ -1344,7 +1338,6 @@
X #endif
X 
X 		memcpy(newsk, sk, sizeof(*newsk));
-		newsk->sklist_next = NULL;
X 		newsk->state = TCP_SYN_RECV;
X 
X 		/* Clone the TCP header template */
@@ -1536,8 +1529,11 @@
X 	if (newsk->sndbuf < (3 * newtp->pmtu_cookie))
X 		newsk->sndbuf = min ((3 * newtp->pmtu_cookie), sysctl_wmem_max);
X  
-	tcp_v4_hash(newsk);
-	add_to_prot_sklist(newsk);
+	SOCKHASH_LOCK_WRITE();
+	__tcp_v4_hash(newsk);
+	__tcp_inherit_port(sk, newsk);
+	SOCKHASH_UNLOCK_WRITE();
+
X 	sk->data_ready(sk, 0); /* Deliver SIGIO */ 
X 
X 	return newsk;
@@ -1780,6 +1776,25 @@
X 	goto discard_it;
X }
X 
+static void __tcp_v4_rehash(struct sock *sk)
+{
+	struct sock **skp = &tcp_ehash[(sk->hashent = tcp_sk_hashfn(sk))];
+
+	SOCKHASH_LOCK_WRITE();
+	if(sk->pprev) {
+		if(sk->next)
+			sk->next->pprev = sk->pprev;
+		*sk->pprev = sk->next;
+		sk->pprev = NULL;
+		tcp_reg_zap(sk);
+	}
+	if((sk->next = *skp) != NULL)
+		(*skp)->pprev = &sk->next;
+	*skp = sk;
+	sk->pprev = skp;
+	SOCKHASH_UNLOCK_WRITE();
+}
+
X int tcp_v4_rebuild_header(struct sock *sk)
X {
X 	struct rtable *rt = (struct rtable *)sk->dst_cache;
@@ -1853,7 +1868,12 @@
X 
X 		sk->saddr = new_saddr;
X 		sk->rcv_saddr = new_saddr;
-		tcp_v4_rehash(sk);
+
+		/* XXX The only one ugly spot where we need to
+		 * XXX really change the sockets identity after
+		 * XXX it has entered the hashes. -DaveM
+		 */
+		__tcp_v4_rehash(sk);
X 	} 
X         
X 	return 0;
@@ -1948,20 +1968,192 @@
X   	while((skb = __skb_dequeue(&tp->out_of_order_queue)) != NULL)
X 		kfree_skb(skb);
X 
-	/* Clean up a locked TCP bind bucket, this only happens if a
+	/* Clean up a referenced TCP bind bucket, this only happens if a
X 	 * port is allocated for a socket, but it never fully connects.
-	 * In which case we will find num to be non-zero and daddr to
-	 * be zero.
X 	 */
-	if(sk->daddr == 0 && sk->num != 0)
-		tcp_bucket_unlock(sk);
+	if(sk->prev != NULL)
+		tcp_put_port(sk);
X 
X 	return 0;
X }
X 
+/* Proc filesystem TCP sock list dumping. */
+static void get_openreq(struct sock *sk, struct open_request *req, char *tmpbuf, int i)
+{
+	sprintf(tmpbuf, "%4d: %08lX:%04X %08lX:%04X"
+		" %02X %08X:%08X %02X:%08lX %08X %5d %8d %u",
+		i,
+		(long unsigned int)req->af.v4_req.loc_addr,
+		ntohs(sk->sport),
+		(long unsigned int)req->af.v4_req.rmt_addr,
+		ntohs(req->rmt_port),
+		TCP_SYN_RECV,
+		0,0, /* could print option size, but that is af dependent. */
+		1,   /* timers active (only the expire timer) */  
+		(unsigned long)(req->expires - jiffies), 
+		req->retrans,
+		sk->socket ? sk->socket->inode->i_uid : 0,
+		0,  /* non standard timer */  
+		0 /* open_requests have no inode */
+		); 
+}
+
+static void get_tcp_sock(struct sock *sp, char *tmpbuf, int i)
+{
+	unsigned int dest, src;
+	__u16 destp, srcp;
+	int timer_active, timer_active1, timer_active2;
+	unsigned long timer_expires;
+	struct tcp_opt *tp = &sp->tp_pinfo.af_tcp;
+
+	dest  = sp->daddr;
+	src   = sp->rcv_saddr;
+	destp = ntohs(sp->dport);
+	srcp  = ntohs(sp->sport);
+	timer_active1 = tp->retransmit_timer.prev != NULL;
+	timer_active2 = sp->timer.prev != NULL;
+	timer_active	= 0;
+	timer_expires	= (unsigned) -1;
+	if (timer_active1 && tp->retransmit_timer.expires < timer_expires) {
+		timer_active	= 1;
+		timer_expires	= tp->retransmit_timer.expires;
+	}
+	if (timer_active2 && sp->timer.expires < timer_expires) {
+		timer_active	= 2;
+		timer_expires	= sp->timer.expires;
+	}
+	if(timer_active == 0)
+		timer_expires = jiffies;
+
+	sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
+		" %02X %08X:%08X %02X:%08lX %08X %5d %8d %ld",
+		i, src, srcp, dest, destp, sp->state, 
+		tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq,
+		timer_active, timer_expires-jiffies,
+		tp->retransmits,
+		sp->socket ? sp->socket->inode->i_uid : 0,
+		timer_active ? sp->timeout : 0,
+		sp->socket ? sp->socket->inode->i_ino : 0);
+}
+
+static void get_timewait_sock(struct tcp_tw_bucket *tw, char *tmpbuf, int i)
+{
+	extern int tcp_tw_death_row_slot;
+	unsigned int dest, src;
+	__u16 destp, srcp;
+	int slot_dist;
+
+	dest  = tw->daddr;
+	src   = tw->rcv_saddr;
+	destp = ntohs(tw->dport);
+	srcp  = ntohs(tw->sport);
+
+	slot_dist = tw->death_slot;
+	if(slot_dist > tcp_tw_death_row_slot)
+		slot_dist = (TCP_TWKILL_SLOTS - slot_dist) + tcp_tw_death_row_slot;
+	else
+		slot_dist = tcp_tw_death_row_slot - slot_dist;
+
+	sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
+		" %02X %08X:%08X %02X:%08X %08X %5d %8d %d",
+		i, src, srcp, dest, destp, TCP_TIME_WAIT, 0, 0,
+		3, slot_dist * TCP_TWKILL_PERIOD, 0, 0, 0, 0);
+}
+
+int tcp_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
+{
+	int len = 0, num = 0, i;
+	off_t begin, pos = 0;
+	char tmpbuf[129];
+
+	if (offset < 128)
+		len += sprintf(buffer, "%-127s\n",
+			       "  sl  local_address rem_address   st tx_queue "
+			       "rx_queue tr tm->when retrnsmt   uid  timeout inode");
+
+	pos = 128;
+	SOCKHASH_LOCK_READ();
+
+	/* First, walk listening socket table. */
+	for(i = 0; i < TCP_LHTABLE_SIZE; i++) {
+		struct sock *sk = tcp_listening_hash[i];
+
+		for (sk = tcp_listening_hash[i]; sk; sk = sk->next, num++) {
+			struct open_request *req;
+			struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+
+			if (sk->family != PF_INET)
+				continue;
+			pos += 128;
+			if (pos >= offset) {
+				get_tcp_sock(sk, tmpbuf, num);
+				len += sprintf(buffer+len, "%-127s\n", tmpbuf);
+				if (len >= length)
+					goto out;
+			}
+			for (req = tp->syn_wait_queue; req; req = req->dl_next, num++) {
+				if (req->sk)
+					continue;
+				pos += 128;
+				if (pos < offset)
+					continue;
+				get_openreq(sk, req, tmpbuf, num);
+				len += sprintf(buffer+len, "%-127s\n", tmpbuf);
+				if(len >= length) 
+					goto out;
+			}
+		}
+	}
+
+	/* Next, walk established hash chain. */
+	for (i = 0; i < (tcp_ehash_size >> 1); i++) {
+		struct sock *sk;
+
+		for(sk = tcp_ehash[i]; sk; sk = sk->next, num++) {
+			if (sk->family != PF_INET)
+				continue;
+			pos += 128;
+			if (pos < offset)
+				continue;
+			get_tcp_sock(sk, tmpbuf, num);
+			len += sprintf(buffer+len, "%-127s\n", tmpbuf);
+			if(len >= length)
+				goto out;
+		}
+	}
+
+	/* Finally, walk time wait buckets. */
+	for (i = (tcp_ehash_size>>1); i < tcp_ehash_size; i++) {
+		struct tcp_tw_bucket *tw;
+		for (tw = (struct tcp_tw_bucket *)tcp_ehash[i];
+		     tw != NULL;
+		     tw = (struct tcp_tw_bucket *)tw->next, num++) {
+			if (tw->family != PF_INET)
+				continue;
+			pos += 128;
+			if (pos < offset)
+				continue;
+			get_timewait_sock(tw, tmpbuf, num);
+			len += sprintf(buffer+len, "%-127s\n", tmpbuf);
+			if(len >= length)
+				goto out;
+		}
+	}
+
+out:
+	SOCKHASH_UNLOCK_READ();
+
+	begin = len - (pos - offset);
+	*start = buffer + begin;
+	len -= begin;
+	if(len > length)
+		len = length;
+	if (len < 0)
+		len = 0; 
+	return len;
+}
+
X struct proto tcp_prot = {
-	(struct sock *)&tcp_prot,	/* sklist_next */
-	(struct sock *)&tcp_prot,	/* sklist_prev */
X 	tcp_close,			/* close */
X 	tcp_v4_connect,			/* connect */
X 	tcp_accept,			/* accept */
@@ -1981,9 +2173,7 @@
X 	tcp_v4_do_rcv,			/* backlog_rcv */
X 	tcp_v4_hash,			/* hash */
X 	tcp_v4_unhash,			/* unhash */
-	tcp_v4_rehash,			/* rehash */
-	tcp_good_socknum,		/* good_socknum */
-	tcp_v4_verify_bind,		/* verify_bind */
+	tcp_v4_get_port,		/* get_port */
X 	128,				/* max_header */
X 	0,				/* retransmits */
X 	"TCP",				/* name */
diff -u --recursive --new-file v2.3.9/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
--- v2.3.9/linux/net/ipv4/tcp_timer.c	Wed May 26 18:14:38 1999
+++ linux/net/ipv4/tcp_timer.c	Sat Jul  3 17:57:23 1999
@@ -5,7 +5,7 @@
X  *
X  *		Implementation of the Transmission Control Protocol(TCP).
X  *
- * Version:	$Id: tcp_timer.c,v 1.64 1999/05/27 00:37:31 davem Exp $
+ * Version:	$Id: tcp_timer.c,v 1.65 1999/07/02 11:26:35 davem Exp $
X  *
X  * Authors:	Ross Biro, <bi...@leland.Stanford.Edu>
X  *		Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -31,7 +31,6 @@
X static void tcp_sltimer_handler(unsigned long);
X static void tcp_syn_recv_timer(unsigned long);
X static void tcp_keepalive(unsigned long data);
-static void tcp_bucketgc(unsigned long);
X static void tcp_twkill(unsigned long);
X 
X struct timer_list	tcp_slow_timer = {
@@ -44,8 +43,7 @@
X struct tcp_sl_timer tcp_slt_array[TCP_SLT_MAX] = {
X 	{ATOMIC_INIT(0), TCP_SYNACK_PERIOD, 0, tcp_syn_recv_timer},/* SYNACK	*/
X 	{ATOMIC_INIT(0), TCP_KEEPALIVE_PERIOD, 0, tcp_keepalive},  /* KEEPALIVE	*/
-	{ATOMIC_INIT(0), TCP_TWKILL_PERIOD, 0, tcp_twkill},        /* TWKILL	*/
-	{ATOMIC_INIT(0), TCP_BUCKETGC_PERIOD, 0, tcp_bucketgc}     /* BUCKETGC	*/
+	{ATOMIC_INIT(0), TCP_TWKILL_PERIOD, 0, tcp_twkill}         /* TWKILL	*/
X };
X 
X const char timer_bug_msg[] = KERN_DEBUG "tcpbug: unknown timer value\n";
@@ -250,43 +248,6 @@
X 		}
X 	}
X 	return res;
-}
-
-/* Garbage collect TCP bind buckets. */
-static void tcp_bucketgc(unsigned long data)
-{
-	int i, reaped = 0;;
-
-	SOCKHASH_LOCK_WRITE_BH();
-	for(i = 0; i < tcp_bhash_size; i++) {
-		struct tcp_bind_bucket *tb = tcp_bhash[i];
-
-		while(tb) {
-			struct tcp_bind_bucket *next = tb->next;
-
-			if((tb->owners == NULL) &&
-			   !(tb->flags & TCPB_FLAG_LOCKED)) {
-				reaped++;
-
-				/* Unlink bucket. */
-				if(tb->next)
-					tb->next->pprev = tb->pprev;
-				*tb->pprev = tb->next;
-
SHAR_EOF
true || echo 'restore of patch-2.3.10 failed'
fi
echo 'End of  part 33'
echo 'File patch-2.3.10 is continued in part 34'
echo 34 > _shar_seq_.tmp
exit 0