diff -Nru a/Documentation/sound/rme96xx b/Documentation/sound/rme96xx
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/Documentation/sound/rme96xx	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,767 @@
+Beta release of the rme96xx (driver for RME 96XX cards like the 
+"Hammerfall" and the "Hammerfall light") 
+
+Important: The driver module has to be installed on a freshly rebooted system, 
+otherwise the driver might not be able to acquire its buffers.
+
+features:
+
+ - OSS programming interface (i.e. runs with standard OSS soundsoftware) 
+ - OSS/Multichannel interface (OSS multichannel is done by just aquiring
+   more than 2 channels). The driver does not use more than one device 
+   ( yet .. this feature may be implemented later ) 
+ - more than one RME card supported
+
+The driver uses a specific multichannel interface, which I will document
+when the driver gets stable. (take a look at the defines in rme96xx.h,
+which adds blocked multichannel formats i.e instead of 
+lrlrlrlr --> llllrrrr  etc.
+
+Use the "rmectrl" programm to look at the status of the card .. 
+or use xrmectrl, a GUI interface for the ctrl program.
+
+What you can do with the rmectrl program is to set the stereo device for
+OSS emulation (e.g. if you use SPDIF out).
+
+You do:
+
+./ctrl offset 24 24
+
+which makes the stereo device use channels 25 and 26.
+
+Guenter Geiger <geiger@epy.co.at>
+
+copy the first part of the attached source code into rmectrl.c
+and the  second part into xrmectrl (or get the program from
+http://gige.xdv.org/pages/soft/pages/rme)
+
+to compile: gcc -o rmectrl rmectrl.c
+------------------------------ snip ------------------------------------
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <linux/soundcard.h>
+#include <math.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "rme96xx.h"
+
+/*
+  remctrl.c
+  (C) 2000 Guenter Geiger <geiger@debian.org>
+  HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
+*/
+
+/* # define DEVICE_NAME "/dev/mixer" */
+# define DEVICE_NAME "/dev/mixer1"
+
+
+void usage(void)
+{
+     fprintf(stderr,"usage: rmectrl [/dev/mixer<n>] [command [options]]\n\n");
+     fprintf(stderr,"where command is one of:\n");
+     fprintf(stderr,"  help                       show this help\n");
+     fprintf(stderr,"  status                     show status bits\n");
+     fprintf(stderr,"  control                    show control bits\n");
+     fprintf(stderr,"  mix                        show mixer/offset status\n");
+     fprintf(stderr,"  master <n>                 set sync master\n");
+     fprintf(stderr,"  pro <n>                    set spdif out pro\n");
+     fprintf(stderr,"  emphasis <n>               set spdif out emphasis\n");
+     fprintf(stderr,"  dolby <n>                  set spdif out no audio\n");
+     fprintf(stderr,"  optout <n>                 set spdif out optical\n");
+     fprintf(stderr,"  wordclock <n>              set sync wordclock\n");
+     fprintf(stderr,"  spdifin <n>                set spdif in (0=optical,1=coax,2=intern)\n");
+     fprintf(stderr,"  syncref <n>                set sync source (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n");
+     fprintf(stderr,"  adat1cd <n>                set ADAT1 on internal CD\n");
+     fprintf(stderr,"  offset <devnr> <in> <out>  set dev (0..3) offset (0..25)\n");
+     exit(-1);
+}
+
+
+int main(int argc, char* argv[])
+{
+     int cards;
+     int ret;
+     int i;
+     double ft;
+     int fd, fdwr;
+     int param,orig;
+     rme_status_t stat;
+     rme_ctrl_t ctrl;
+     char *device;
+     int argidx;
+
+     if (argc < 2)
+	  usage();
+
+     if (*argv[1]=='/') {
+	  device = argv[1];
+	  argidx = 2;
+     }
+     else {
+	  device = DEVICE_NAME;
+	  argidx = 1;
+     }
+
+     fprintf(stdout,"mixer device %s\n",device);
+     if ((fd = open(device,O_RDONLY)) < 0) {
+	  fprintf(stdout,"opening device failed\n");
+	  exit(-1);
+     }
+
+     if ((fdwr = open(device,O_WRONLY)) < 0) {
+	  fprintf(stdout,"opening device failed\n");
+	  exit(-1);
+     }
+
+     if (argc < argidx+1)
+	  usage();
+
+     if (!strcmp(argv[argidx],"help"))
+        usage();
+     if (!strcmp(argv[argidx],"-h"))
+        usage();
+     if (!strcmp(argv[argidx],"--help"))
+        usage();
+
+     if (!strcmp(argv[argidx],"status")) {
+	  ioctl(fd,SOUND_MIXER_PRIVATE2,&stat);
+	  fprintf(stdout,"stat.irq %d\n",stat.irq);
+	  fprintf(stdout,"stat.lockmask %d\n",stat.lockmask);
+	  fprintf(stdout,"stat.sr48 %d\n",stat.sr48);
+	  fprintf(stdout,"stat.wclock %d\n",stat.wclock);
+	  fprintf(stdout,"stat.bufpoint %d\n",stat.bufpoint);
+	  fprintf(stdout,"stat.syncmask %d\n",stat.syncmask);
+	  fprintf(stdout,"stat.doublespeed %d\n",stat.doublespeed);
+	  fprintf(stdout,"stat.tc_busy %d\n",stat.tc_busy);
+	  fprintf(stdout,"stat.tc_out %d\n",stat.tc_out);
+	  fprintf(stdout,"stat.crystalrate %d (0=64k 3=96k 4=88.2k 5=48k 6=44.1k 7=32k)\n",stat.crystalrate);
+	  fprintf(stdout,"stat.spdif_error %d\n",stat.spdif_error);
+	  fprintf(stdout,"stat.bufid %d\n",stat.bufid);
+	  fprintf(stdout,"stat.tc_valid %d\n",stat.tc_valid);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"control")) {
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  fprintf(stdout,"ctrl.start %d\n",ctrl.start);
+	  fprintf(stdout,"ctrl.latency %d (0=64 .. 7=8192)\n",ctrl.latency);
+	  fprintf(stdout,"ctrl.master %d\n",ctrl.master);
+	  fprintf(stdout,"ctrl.ie %d\n",ctrl.ie);
+	  fprintf(stdout,"ctrl.sr48 %d\n",ctrl.sr48);
+	  fprintf(stdout,"ctrl.spare %d\n",ctrl.spare);
+	  fprintf(stdout,"ctrl.doublespeed %d\n",ctrl.doublespeed);
+	  fprintf(stdout,"ctrl.pro %d\n",ctrl.pro);
+	  fprintf(stdout,"ctrl.emphasis %d\n",ctrl.emphasis);
+	  fprintf(stdout,"ctrl.dolby %d\n",ctrl.dolby);
+	  fprintf(stdout,"ctrl.opt_out %d\n",ctrl.opt_out);
+	  fprintf(stdout,"ctrl.wordclock %d\n",ctrl.wordclock);
+	  fprintf(stdout,"ctrl.spdif_in %d (0=optical,1=coax,2=intern)\n",ctrl.spdif_in);
+	  fprintf(stdout,"ctrl.sync_ref %d (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n",ctrl.sync_ref);
+	  fprintf(stdout,"ctrl.spdif_reset %d\n",ctrl.spdif_reset);
+	  fprintf(stdout,"ctrl.spdif_select %d\n",ctrl.spdif_select);
+	  fprintf(stdout,"ctrl.spdif_clock %d\n",ctrl.spdif_clock);
+	  fprintf(stdout,"ctrl.spdif_write %d\n",ctrl.spdif_write);
+	  fprintf(stdout,"ctrl.adat1_cd %d\n",ctrl.adat1_cd);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"mix")) {
+	  rme_mixer mix;
+	  int i;
+
+	  for (i=0; i<4; i++) {
+	       mix.devnr = i;
+	       ioctl(fd,SOUND_MIXER_PRIVATE1,&mix);
+	       if (mix.devnr == i) {
+		    fprintf(stdout,"devnr %d\n",mix.devnr);
+		    fprintf(stdout,"mix.i_offset %2d (0-25)\n",mix.i_offset);
+		    fprintf(stdout,"mix.o_offset %2d (0-25)\n",mix.o_offset);
+	       }
+	  }
+	  exit (0);
+     }
+
+/* the control flags */
+
+     if (argc < argidx+2)
+	  usage();
+
+     if (!strcmp(argv[argidx],"master")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("master = %d\n",val);
+	  ctrl.master = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"pro")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("pro = %d\n",val);
+	  ctrl.pro = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"emphasis")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("emphasis = %d\n",val);
+	  ctrl.emphasis = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"dolby")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("dolby = %d\n",val);
+	  ctrl.dolby = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"optout")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("optout = %d\n",val);
+	  ctrl.opt_out = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"wordclock")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("wordclock = %d\n",val);
+	  ctrl.wordclock = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"spdifin")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("spdifin = %d\n",val);
+	  ctrl.spdif_in = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"syncref")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("syncref = %d\n",val);
+	  ctrl.sync_ref = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"adat1cd")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("adat1cd = %d\n",val);
+	  ctrl.adat1_cd = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+/* setting offset */
+
+     if (argc < argidx+4)
+	  usage();
+
+     if (!strcmp(argv[argidx],"offset")) {
+	  rme_mixer mix;
+
+	  mix.devnr = atoi(argv[argidx+1]);
+
+	  mix.i_offset = atoi(argv[argidx+2]);
+	  mix.o_offset = atoi(argv[argidx+3]);
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE1,&mix);
+	  fprintf(stdout,"devnr %d\n",mix.devnr);
+	  fprintf(stdout,"mix.i_offset to %d\n",mix.i_offset);
+	  fprintf(stdout,"mix.o_offset to %d\n",mix.o_offset);
+	  exit (0);
+     }
+
+     usage();
+     exit (0); /* to avoid warning */
+}
+
+
+---------------------------- <snip> --------------------------------
+#!/usr/bin/wish
+
+# xrmectrl
+# (C) 2000 Guenter Geiger <geiger@debian.org>
+# HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
+
+#set defaults "-relief ridged"
+set CTRLPROG "./rmectrl"
+if {$argc} {
+    set CTRLPROG "$CTRLPROG $argv"
+}
+puts "CTRLPROG $CTRLPROG"
+
+frame .butts
+button .butts.exit -text "Exit" -command "exit" -relief ridge
+#button .butts.state -text "State" -command "get_all"
+
+pack .butts.exit -side left
+pack .butts -side bottom
+
+
+#
+# STATUS
+#
+
+frame .status
+
+# Sampling Rate
+
+frame .status.sr
+label .status.sr.text -text "Sampling Rate" -justify left
+radiobutton .status.sr.441 -selectcolor red -text "44.1 kHz" -width 10 -anchor nw -variable srate -value 44100 -font times
+radiobutton .status.sr.480 -selectcolor red -text "48 kHz" -width 10 -anchor nw -variable srate -value 48000 -font times
+radiobutton .status.sr.882 -selectcolor red -text "88.2 kHz" -width 10 -anchor nw -variable srate -value 88200 -font times
+radiobutton .status.sr.960 -selectcolor red -text "96 kHz" -width 10 -anchor nw  -variable srate -value 96000 -font times
+
+pack .status.sr.text .status.sr.441 .status.sr.480 .status.sr.882 .status.sr.960 -side top -padx 3
+
+# Lock
+
+frame .status.lock
+label .status.lock.text -text "Lock" -justify left
+checkbutton .status.lock.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatlock1 -font times
+checkbutton .status.lock.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatlock2 -font times
+checkbutton .status.lock.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatlock3 -font times
+
+pack .status.lock.text .status.lock.adat1 .status.lock.adat2 .status.lock.adat3 -side top -padx 3 
+
+# Sync
+
+frame .status.sync
+label .status.sync.text -text "Sync" -justify left
+checkbutton .status.sync.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatsync1 -font times
+checkbutton .status.sync.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatsync2 -font times
+checkbutton .status.sync.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatsync3 -font times
+
+pack .status.sync.text .status.sync.adat1 .status.sync.adat2 .status.sync.adat3 -side top -padx 3 
+
+# Timecode
+
+frame .status.tc
+label .status.tc.text -text "Timecode" -justify left
+checkbutton .status.tc.busy -selectcolor red -text "busy" -anchor nw -width 10 -variable tcbusy -font times
+checkbutton .status.tc.out -selectcolor red -text "out" -anchor nw -width 10 -variable tcout -font times
+checkbutton .status.tc.valid -selectcolor red -text "valid" -anchor nw -width 10 -variable tcvalid -font times
+
+pack .status.tc.text .status.tc.busy .status.tc.out .status.tc.valid -side top -padx 3 
+
+# SPDIF In
+
+frame .status.spdif
+label .status.spdif.text -text "SPDIF In" -justify left
+label .status.spdif.sr -text "--.- kHz" -anchor n -width 10 -font times
+checkbutton .status.spdif.error -selectcolor red -text "Input Lock" -anchor nw -width 10 -variable spdiferr -font times
+
+pack .status.spdif.text .status.spdif.sr .status.spdif.error -side top -padx 3 
+
+pack .status.sr .status.lock .status.sync .status.tc .status.spdif -side left -fill x -anchor n -expand 1
+
+
+#
+# CONTROL 
+#
+
+proc setprof {} {
+    global CTRLPROG
+    global spprof
+    exec $CTRLPROG pro $spprof
+}
+
+proc setemph {} {
+    global CTRLPROG
+    global spemph
+    exec $CTRLPROG emphasis $spemph
+}
+
+proc setnoaud {} {
+    global CTRLPROG
+    global spnoaud
+    exec $CTRLPROG dolby $spnoaud
+}
+
+proc setoptical {} {
+    global CTRLPROG
+    global spoptical
+    exec $CTRLPROG optout $spoptical
+}
+
+proc setspdifin {} {
+    global CTRLPROG
+    global spdifin
+    exec $CTRLPROG spdifin [expr $spdifin - 1]
+}
+
+proc setsyncsource {} {
+    global CTRLPROG
+    global syncsource
+    exec $CTRLPROG syncref [expr $syncsource -1]
+}
+
+
+proc setmaster {} {
+    global CTRLPROG
+    global master
+    exec $CTRLPROG master $master
+}
+
+proc setwordclock {} {
+    global CTRLPROG
+    global wordclock
+    exec $CTRLPROG wordclock $wordclock
+}
+
+proc setadat1cd {} {
+    global CTRLPROG
+    global adat1cd
+    exec $CTRLPROG adat1cd $adat1cd
+}
+
+
+frame .control
+
+# SPDIF In & SPDIF Out
+
+
+frame .control.spdif
+
+frame .control.spdif.in
+label .control.spdif.in.text -text "SPDIF In" -justify left
+radiobutton .control.spdif.in.input1 -text "Optical" -anchor nw -width 13 -variable spdifin -value 1 -command setspdifin -selectcolor blue -font times
+radiobutton .control.spdif.in.input2 -text "Coaxial" -anchor nw -width 13 -variable spdifin -value 2 -command setspdifin -selectcolor blue -font times
+radiobutton .control.spdif.in.input3 -text "Intern " -anchor nw -width 13 -variable spdifin -command setspdifin -value 3 -selectcolor blue -font times
+
+checkbutton .control.spdif.in.adat1cd -text "ADAT1 Intern" -anchor nw -width 13 -variable adat1cd -command setadat1cd -selectcolor blue -font times
+
+pack .control.spdif.in.text .control.spdif.in.input1 .control.spdif.in.input2 .control.spdif.in.input3 .control.spdif.in.adat1cd
+
+label .control.spdif.space
+
+frame .control.spdif.out
+label .control.spdif.out.text -text "SPDIF Out" -justify left
+checkbutton .control.spdif.out.pro -text "Professional" -anchor nw -width 13 -variable spprof -command setprof -selectcolor blue -font times
+checkbutton .control.spdif.out.emphasis -text "Emphasis" -anchor nw -width 13 -variable spemph -command setemph -selectcolor blue -font times
+checkbutton .control.spdif.out.dolby -text "NoAudio" -anchor nw -width 13 -variable spnoaud -command setnoaud -selectcolor blue -font times
+checkbutton .control.spdif.out.optout -text "Optical Out" -anchor nw -width 13 -variable spoptical -command setoptical -selectcolor blue -font times
+
+pack .control.spdif.out.optout .control.spdif.out.dolby .control.spdif.out.emphasis .control.spdif.out.pro .control.spdif.out.text -side bottom
+
+pack .control.spdif.in .control.spdif.space .control.spdif.out -side top -fill y -padx 3 -expand 1
+
+# Sync Mode & Sync Source
+
+frame .control.sync
+frame .control.sync.mode
+label .control.sync.mode.text -text "Sync Mode" -justify left
+checkbutton .control.sync.mode.master -text "Master" -anchor nw -width 13 -variable master -command setmaster -selectcolor blue -font times
+checkbutton .control.sync.mode.wc -text "Wordclock" -anchor nw -width 13 -variable wordclock -command setwordclock -selectcolor blue -font times
+
+pack .control.sync.mode.text .control.sync.mode.master .control.sync.mode.wc
+
+label .control.sync.space
+
+frame .control.sync.src
+label .control.sync.src.text -text "Sync Source" -justify left
+radiobutton .control.sync.src.input1 -text "ADAT1" -anchor nw -width 13 -variable syncsource -value 1 -command setsyncsource -selectcolor blue -font times
+radiobutton .control.sync.src.input2 -text "ADAT2" -anchor nw -width 13 -variable syncsource -value 2 -command setsyncsource -selectcolor blue -font times
+radiobutton .control.sync.src.input3 -text "ADAT3" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 3 -selectcolor blue -font times
+radiobutton .control.sync.src.input4 -text "SPDIF" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 4 -selectcolor blue -font times
+
+pack .control.sync.src.input4 .control.sync.src.input3 .control.sync.src.input2 .control.sync.src.input1 .control.sync.src.text -side bottom
+
+pack .control.sync.mode .control.sync.space .control.sync.src -side top -fill y -padx 3 -expand 1
+
+label .control.space -text "" -width 10
+
+# Buffer Size
+
+frame .control.buf
+label .control.buf.text -text "Buffer Size (Latency)" -justify left
+radiobutton .control.buf.b1 -selectcolor red -text "64 (1.5 ms)" -width 13 -anchor nw -variable ssrate -value 1 -font times
+radiobutton .control.buf.b2 -selectcolor red -text "128 (3 ms)" -width 13 -anchor nw -variable ssrate -value 2 -font times
+radiobutton .control.buf.b3 -selectcolor red -text "256 (6 ms)" -width 13 -anchor nw -variable ssrate -value 3 -font times
+radiobutton .control.buf.b4 -selectcolor red -text "512 (12 ms)" -width 13 -anchor nw -variable ssrate -value 4 -font times
+radiobutton .control.buf.b5 -selectcolor red -text "1024 (23 ms)" -width 13 -anchor nw -variable ssrate -value 5 -font times
+radiobutton .control.buf.b6 -selectcolor red -text "2048 (46 ms)" -width 13 -anchor nw -variable ssrate -value 6 -font times
+radiobutton .control.buf.b7 -selectcolor red -text "4096 (93 ms)" -width 13 -anchor nw -variable ssrate -value 7 -font times
+radiobutton .control.buf.b8 -selectcolor red -text "8192 (186 ms)" -width 13 -anchor nw -variable ssrate -value 8 -font times
+
+pack .control.buf.text .control.buf.b1 .control.buf.b2 .control.buf.b3 .control.buf.b4 .control.buf.b5 .control.buf.b6 .control.buf.b7 .control.buf.b8 -side top -padx 3 
+
+# Offset
+
+frame .control.offset
+
+frame .control.offset.in
+label .control.offset.in.text -text "Offset In" -justify left
+label .control.offset.in.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
+label .control.offset.in.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
+label .control.offset.in.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
+label .control.offset.in.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
+
+pack .control.offset.in.text .control.offset.in.off0 .control.offset.in.off1 .control.offset.in.off2 .control.offset.in.off3
+
+label .control.offset.space
+
+frame .control.offset.out
+label .control.offset.out.text -text "Offset Out" -justify left
+label .control.offset.out.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
+label .control.offset.out.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
+label .control.offset.out.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
+label .control.offset.out.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
+
+pack .control.offset.out.off3 .control.offset.out.off2 .control.offset.out.off1 .control.offset.out.off0 .control.offset.out.text -side bottom
+
+pack .control.offset.in .control.offset.space .control.offset.out -side top -fill y -padx 3 -expand 1
+
+
+pack .control.spdif .control.sync .control.space .control.buf .control.offset -side left -fill both -anchor n -expand 1
+
+
+label .statustext -text Status -justify center -relief ridge
+label .controltext -text Control -justify center -relief ridge
+
+label .statusspace
+label .controlspace
+
+pack .statustext .status .statusspace .controltext .control .controlspace -side top -anchor nw -fill both -expand 1
+
+
+proc get_bit {output sstr} {
+    set idx1 [string last [concat $sstr 1] $output]
+    set idx1 [expr $idx1 != -1]
+    return $idx1
+}
+
+proc get_val {output sstr} {
+    set val [string wordend $output [string last $sstr $output]] 
+    set val [string range $output $val [expr $val+1]]
+    return $val
+}
+
+proc get_val2 {output sstr} {
+    set val [string wordend $output [string first $sstr $output]] 
+    set val [string range $output $val [expr $val+2]]
+    return $val
+}
+
+proc get_control {} {
+    global spprof
+    global spemph
+    global spnoaud
+    global spoptical
+    global spdifin
+    global ssrate
+    global master
+    global wordclock
+    global syncsource
+    global CTRLPROG
+
+    set f [open "| $CTRLPROG control" r+]
+    set ooo [read $f 1000]
+    close $f
+#    puts $ooo
+
+    set spprof [ get_bit $ooo "pro"]
+    set spemph [ get_bit $ooo "emphasis"]
+    set spnoaud [ get_bit $ooo "dolby"]
+    set spoptical [ get_bit $ooo "opt_out"]
+    set spdifin [ expr [ get_val $ooo "spdif_in"] + 1]
+    set ssrate [ expr [ get_val $ooo "latency"] + 1]
+    set master [ expr [ get_val $ooo "master"]]
+    set wordclock [ expr [ get_val $ooo "wordclock"]]
+    set syncsource [ expr [ get_val $ooo "sync_ref"] + 1]
+}
+
+proc get_status {} {
+    global srate
+    global ctrlcom
+
+    global adatlock1
+    global adatlock2
+    global adatlock3
+
+    global adatsync1
+    global adatsync2
+    global adatsync3
+
+    global tcbusy
+    global tcout
+    global tcvalid
+
+    global spdiferr
+    global crystal
+    global .status.spdif.text
+    global CTRLPROG
+
+
+    set f [open "| $CTRLPROG status" r+]
+    set ooo [read $f 1000]
+    close $f
+#    puts $ooo
+
+# samplerate
+
+    set idx1 [string last "sr48 1" $ooo]
+    set idx2 [string last "doublespeed 1" $ooo]
+    if {$idx1 >= 0} {
+	set fact1 48000
+    } else {
+	set fact1 44100
+    }
+
+    if {$idx2 >= 0} {
+	set fact2 2
+    } else {
+	set fact2 1
+    }
+    set srate [expr $fact1 * $fact2]
+#   ADAT lock
+
+    set val [get_val $ooo lockmask]
+    set adatlock1 0
+    set adatlock2 0
+    set adatlock3 0
+    if {[expr $val & 1]} {
+       set adatlock3 1
+    }
+    if {[expr $val & 2]} {
+       set adatlock2 1
+    }
+    if {[expr $val & 4]} {
+       set adatlock1 1
+    }
+
+#  ADAT sync
+    set val [get_val $ooo syncmask]
+    set adatsync1 0
+    set adatsync2 0
+    set adatsync3 0
+
+    if {[expr $val & 1]} {
+       set adatsync3 1
+    }
+    if {[expr $val & 2]} {
+       set adatsync2 1
+    }
+    if {[expr $val & 4]} {
+       set adatsync1 1
+    }
+
+# TC busy
+
+    set tcbusy [get_bit $ooo "busy"]
+    set tcout [get_bit $ooo "out"]
+    set tcvalid [get_bit $ooo "valid"]
+    set spdiferr [expr [get_bit $ooo "spdif_error"] == 0]
+
+#  000=64kHz, 100=88.2kHz, 011=96kHz
+#  111=32kHz, 110=44.1kHz, 101=48kHz
+
+    set val [get_val $ooo crystalrate]
+
+    set crystal "--.- kHz"
+    if {$val == 0} {
+        set crystal "64 kHz"
+    }
+    if {$val == 4} {
+        set crystal "88.2 kHz"
+    }
+    if {$val == 3} {
+        set crystal "96 kHz"
+    }
+    if {$val == 7} {
+        set crystal "32 kHz"
+    }
+    if {$val == 6} {
+        set crystal "44.1 kHz"
+    }
+    if {$val == 5} {
+        set crystal "48 kHz"
+    }
+    .status.spdif.sr configure -text $crystal
+}
+
+proc get_offset {} {
+    global inoffset
+    global outoffset
+    global CTRLPROG
+
+    set f [open "| $CTRLPROG mix" r+]
+    set ooo [read $f 1000]
+    close $f
+#    puts $ooo
+
+    if { [string match "*devnr*" $ooo] } {
+	set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
+	set val [get_val2 $ooo i_offset]
+	.control.offset.in.off0 configure -text "dev\#0: $val"
+	set val [get_val2 $ooo o_offset]
+	.control.offset.out.off0 configure -text "dev\#0: $val"
+    } else {
+	.control.offset.in.off0 configure -text "dev\#0: -"
+	.control.offset.out.off0 configure -text "dev\#0: -"
+    }
+    if { [string match "*devnr*" $ooo] } {
+	set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
+	set val [get_val2 $ooo i_offset]
+	.control.offset.in.off1 configure -text "dev\#1: $val"
+	set val [get_val2 $ooo o_offset]
+	.control.offset.out.off1 configure -text "dev\#1: $val"
+    } else {
+	.control.offset.in.off1 configure -text "dev\#1: -"
+	.control.offset.out.off1 configure -text "dev\#1: -"
+    }
+    if { [string match "*devnr*" $ooo] } {
+	set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
+	set val [get_val2 $ooo i_offset]
+	.control.offset.in.off2 configure -text "dev\#2: $val"
+	set val [get_val2 $ooo o_offset]
+	.control.offset.out.off2 configure -text "dev\#2: $val"
+    } else {
+	.control.offset.in.off2 configure -text "dev\#2: -"
+	.control.offset.out.off2 configure -text "dev\#2: -"
+    }
+    if { [string match "*devnr*" $ooo] } {
+	set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
+	set val [get_val2 $ooo i_offset]
+	.control.offset.in.off3 configure -text "dev\#3: $val"
+	set val [get_val2 $ooo o_offset]
+	.control.offset.out.off3 configure -text "dev\#3: $val"
+    } else {
+	.control.offset.in.off3 configure -text "dev\#3: -"
+	.control.offset.out.off3 configure -text "dev\#3: -"
+    }
+}
+
+
+proc get_all {} {
+get_status
+get_control
+get_offset
+}
+
+# main
+while {1} {
+  after 200
+  get_all
+  update
+}
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	Fri Feb 14 15:53:11 2003
+++ b/MAINTAINERS	Fri Feb 14 15:53:11 2003
@@ -90,6 +90,12 @@
 L:	linux-net@vger.kernel.org
 S:	Maintained
 
+3CR990 NETWORK DRIVER
+P:	David Dillow
+M:	dave@thedillows.org
+L:	linux-net@vger.kernel.org
+S:	Maintained
+
 53C700 AND 53C700-66 SCSI DRIVER
 P:	James E.J. Bottomley
 M:	James.Bottomley@HansenPartnership.com
@@ -460,6 +466,13 @@
 W:	http://www.cyclades.com/
 S:	Supported
 
+DAC960 RAID CONTROLLER DRIVER
+P:	Dave Olien
+M	dmo@osdl.org
+W:	http://www.osdl.org/archive/dmo/DAC960
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 DAMA SLAVE for AX.25
 P:	Joerg Reuter
 M:	jreuter@yaina.de
@@ -1498,6 +1511,11 @@
 P:	Eberhard Moenkeberg
 M:	emoenke@gwdg.de
 L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
+SC1200 WDT DRIVER
+P:	Zwane Mwaikambo
+M:	zwane@commfireservices.com
 S:	Maintained
 
 SCHEDULER
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Fri Feb 14 15:53:08 2003
+++ b/Makefile	Fri Feb 14 15:53:08 2003
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 5
-SUBLEVEL = 60
+SUBLEVEL = 61
 EXTRAVERSION =
 
 # *DOCUMENTATION*
@@ -36,7 +36,8 @@
 SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 ARCH := $(SUBARCH)
 
-KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
+# Remove hyphens since they have special meaning in RPM filenames
+KERNELPATH=kernel-$(subst -,,$(KERNELRELEASE))
 
 UTS_MACHINE := $(ARCH)
 
@@ -355,7 +356,7 @@
 #	It's a three stage process:
 #	o .tmp_vmlinux1 has all symbols and sections, but __kallsyms is
 #	  empty
-#	  Running kallsyms on that gives as .tmp_kallsyms1.o with
+#	  Running kallsyms on that gives us .tmp_kallsyms1.o with
 #	  the right size
 #	o .tmp_vmlinux2 now has a __kallsyms section of the right size,
 #	  but due to the added section, some addresses have shifted
@@ -689,7 +690,7 @@
 # make clean     Delete all automatically generated files, including
 #                tools and firmware.
 # make mrproper  Delete the current configuration, and related files
-#                Any core files spread around is deleted as well
+#                Any core files spread around are deleted as well
 # make distclean Remove editor backup files, patch leftover files and the like
 
 # Files removed with 'make clean'
@@ -884,9 +885,9 @@
 		          $(filter-out $(cmd_$(1)),$(cmd_$@))\
 			  $(filter-out $(cmd_$@),$(cmd_$(1)))),\
 	@set -e; \
-	$(if $($(quiet)cmd_$(1)),echo '  $($(quiet)cmd_$(1))';) \
+	$(if $($(quiet)cmd_$(1)),echo '  $(subst ','\'',$($(quiet)cmd_$(1)))';) \
 	$(cmd_$(1)); \
-	scripts/fixdep $(depfile) $@ '$(cmd_$(1))' > $(@D)/.$(@F).tmp; \
+	scripts/fixdep $(depfile) $@ '$(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \
 	rm -f $(depfile); \
 	mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd)
 
@@ -913,19 +914,19 @@
 	fi
 endef
 
-# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
+# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=dir
 # Usage:
 # $(Q)$(MAKE) $(build)=dir
 build := -f scripts/Makefile.build obj
 
-# Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir
+# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir
 # Usage:
 # $(Q)$(MAKE) $(clean)=dir
 clean := -f scripts/Makefile.clean obj
 
 #	$(call descend,<dir>,<target>)
 #	Recursively call a sub-make in <dir> with target <target>
-# Usage is deprecated, because make do not see this as an invocation of make.
+# Usage is deprecated, because make does not see this as an invocation of make.
 descend =$(Q)$(MAKE) -f scripts/Makefile.build obj=$(1) $(2)
 
 FORCE:
diff -Nru a/arch/alpha/kernel/init_task.c b/arch/alpha/kernel/init_task.c
--- a/arch/alpha/kernel/init_task.c	Fri Feb 14 15:53:09 2003
+++ b/arch/alpha/kernel/init_task.c	Fri Feb 14 15:53:09 2003
@@ -9,6 +9,7 @@
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
 struct mm_struct init_mm = INIT_MM(init_mm);
 struct task_struct init_task = INIT_TASK(init_task);
 
diff -Nru a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
--- a/arch/alpha/kernel/signal.c	Fri Feb 14 15:53:09 2003
+++ b/arch/alpha/kernel/signal.c	Fri Feb 14 15:53:09 2003
@@ -619,11 +619,11 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
-		struct k_sigaction *ka = &current->sig->action[signr-1];
+		struct k_sigaction *ka = &current->sighand->action[signr-1];
 
 		if (r0) syscall_restart(r0, r19, regs, ka);
 		handle_signal(signr, ka, &info, oldset, regs, sw);
diff -Nru a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
--- a/arch/arm/kernel/ecard.c	Fri Feb 14 15:53:12 2003
+++ b/arch/arm/kernel/ecard.c	Fri Feb 14 15:53:12 2003
@@ -290,14 +290,7 @@
 {
 	struct task_struct *tsk = current;
 
-	/*
-	 * We don't want /any/ signals, not even SIGKILL
-	 */
-	sigfillset(&tsk->blocked);
-	sigemptyset(&tsk->pending.signal);
-	recalc_sigpending();
-	strcpy(tsk->comm, "kecardd");
-	daemonize();
+	daemonize("kecardd");
 
 	/*
 	 * Allocate a mm.  We're not a lazy-TLB kernel task since we need
diff -Nru a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
--- a/arch/arm/kernel/signal.c	Fri Feb 14 15:53:08 2003
+++ b/arch/arm/kernel/signal.c	Fri Feb 14 15:53:08 2003
@@ -522,7 +522,7 @@
 		struct k_sigaction *ka;
 
 		spin_lock_irq(&current->sighand->siglock);
-		signr = dequeue_signal(&current->blocked, &info);
+		signr = dequeue_signal(current, &current->blocked, &info);
 		spin_unlock_irq(&current->sighand->siglock);
 
 		if (!signr)
diff -Nru a/arch/cris/drivers/usb-host.c b/arch/cris/drivers/usb-host.c
--- a/arch/cris/drivers/usb-host.c	Fri Feb 14 15:53:09 2003
+++ b/arch/cris/drivers/usb-host.c	Fri Feb 14 15:53:09 2003
@@ -459,7 +459,8 @@
 	*R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, stop);
 	/* Somehow wait for the DMA to finish current activities */
 	i = jiffies + 100;
-	while (jiffies < i);	
+	while (time_before(jiffies, i))
+		;
 	
 	first_ep = &TxIntrEPList[0];
 	tmp_ep = first_ep;
diff -Nru a/arch/cris/kernel/signal.c b/arch/cris/kernel/signal.c
--- a/arch/cris/kernel/signal.c	Fri Feb 14 15:53:08 2003
+++ b/arch/cris/kernel/signal.c	Fri Feb 14 15:53:08 2003
@@ -560,7 +560,7 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(canrestart, signr, &info, oldset, regs);
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/Kconfig	Fri Feb 14 15:53:09 2003
@@ -136,6 +136,7 @@
 	  - "Winchip-2" for IDT Winchip 2.
 	  - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
 	  - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
+	  - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
 
 	  If you don't know what to do, choose "386".
 
@@ -174,7 +175,7 @@
 	  against the f00f bug found in earlier Pentiums.
 
 config MPENTIUMII
-       bool "Pentium-II/Celeron(pre-Coppermine)"
+	bool "Pentium-II/Celeron(pre-Coppermine)"
 	help
 	  Select this for Intel chips based on the Pentium-II and
 	  pre-Coppermine Celeron core.  This option enables an unaligned
@@ -260,6 +261,16 @@
 	  treat this chip as a generic 586. Whilst the CPU is 686 class,
 	  it lacks the cmov extension which gcc assumes is present when
 	  generating 686 code.
+	  Note, that Nehemiah (Model 9) and above will not boot with this
+	  kernel due to them lacking the 3dnow instructions used in earlier
+	  incarnations of the CPU.
+
+config MVIAC3_2
+	bool "VIA C3-2 (Nehemiah)"
+	help
+	  Select this for a VIA C3 "Nehemiah". Selecting this enables usage of SSE
+	  and tells gcc to treat the CPU as a 686.
+	  Note, this kernel will not boot on older (pre model 9) C3s.
 
 endchoice
 
@@ -278,8 +289,8 @@
 
 config X86_L1_CACHE_SHIFT
 	int
-	default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586
 	default "4" if MELAN || M486 || M386
+	default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2
 	default "6" if MK7 || MK8
 	default "7" if MPENTIUM4
 
@@ -325,12 +336,12 @@
 
 config X86_ALIGNMENT_16
 	bool
-	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486
+	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2
 	default y
 
 config X86_TSC
 	bool
-	depends on MWINCHIP3D || MWINCHIP2 || MCRUSOE || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8
+	depends on MWINCHIP3D || MWINCHIP2 || MCRUSOE || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2
 	default y
 
 config X86_GOOD_APIC
@@ -345,7 +356,7 @@
 
 config X86_USE_PPRO_CHECKSUM
 	bool
-	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || MK8
+	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2
 	default y
 
 config X86_USE_3DNOW
@@ -360,7 +371,7 @@
 
 config X86_PREFETCH
 	bool
-	depends on MPENTIUMIII || MPENTIUM4
+	depends on MPENTIUMIII || MPENTIUM4 || MVIAC3_2
 	default y
 
 config X86_SSE2
@@ -1000,6 +1011,16 @@
 	help
 	  This adds the CPUFreq driver for mobile AMD K6-2+ and mobile
 	  AMD K6-3+ processors.
+
+	  For details, take a look at linux/Documentation/cpufreq. 
+
+	  If in doubt, say N.
+
+config X86_POWERNOW_K7
+	tristate "AMD Mobile Athlon/Duron PowerNow!"
+	depends on CPU_FREQ
+	help
+	  This adds the CPUFreq driver for mobile AMD K7 mobile processors.
 
 	  For details, take a look at linux/Documentation/cpufreq. 
 
diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile
--- a/arch/i386/Makefile	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/Makefile	Fri Feb 14 15:53:09 2003
@@ -46,6 +46,7 @@
 cflags-$(CONFIG_MCYRIXIII)	+= $(call check_gcc,-march=c3,-march=i486)
 # The alignment flags change with gcc 3.2
 cflags-$(CONFIG_MCYRIXIII)	+= $(call check_gcc,-falign-functions=0 -falign-jumps=0 -falign-loops=0,-malign-functions=0 -malign-jumps=0 -malign-loops=0)
+cflags-$(CONFIG_MVIAC3_2)	+= $(call check_gcc,-march=c3-2,-march=i686)
 
 CFLAGS += $(cflags-y)
 
diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
--- a/arch/i386/kernel/Makefile	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/kernel/Makefile	Fri Feb 14 15:53:09 2003
@@ -10,14 +10,13 @@
 
 obj-y				+= cpu/
 obj-y				+= timers/
+obj-$(CONFIG_ACPI)		+= acpi/
 obj-$(CONFIG_X86_BIOS_REBOOT)	+= reboot.o
 obj-$(CONFIG_MCA)		+= mca.o
 obj-$(CONFIG_X86_MSR)		+= msr.o
 obj-$(CONFIG_X86_CPUID)		+= cpuid.o
 obj-$(CONFIG_MICROCODE)		+= microcode.o
 obj-$(CONFIG_APM)		+= apm.o
-obj-$(CONFIG_ACPI)		+= acpi.o
-obj-$(CONFIG_ACPI_SLEEP)	+= acpi_wakeup.o
 obj-$(CONFIG_X86_SMP)		+= smp.o smpboot.o
 obj-$(CONFIG_X86_TRAMPOLINE)	+= trampoline.o
 obj-$(CONFIG_X86_MPPARSE)	+= mpparse.o
diff -Nru a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/kernel/acpi/Makefile	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,3 @@
+obj-$(CONFIG_ACPI_BOOT)		:= boot.o
+obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o wakeup.o
+
diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/kernel/acpi/boot.c	Fri Feb 14 15:53:12 2003
@@ -0,0 +1,429 @@
+/*
+ *  boot.c - Architecture-Specific Low-Level ACPI Boot Support
+ *
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <asm/pgalloc.h>
+#include <asm/apic.h>
+#include <asm/mpspec.h>
+
+#if defined (CONFIG_X86_LOCAL_APIC)
+#include <mach_apic.h>
+#include <mach_mpparse.h>
+#endif
+
+#define PREFIX			"ACPI: "
+
+extern int acpi_disabled;
+
+/* --------------------------------------------------------------------------
+                              Boot-time Configuration
+   -------------------------------------------------------------------------- */
+
+enum acpi_irq_model_id		acpi_irq_model;
+
+/*
+ * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
+ * to map the target physical address. The problem is that set_fixmap()
+ * provides a single page, and it is possible that the page is not
+ * sufficient.
+ * By using this area, we can map up to MAX_IO_APICS pages temporarily,
+ * i.e. until the next __va_range() call.
+ *
+ * Important Safety Note:  The fixed I/O APIC page numbers are *subtracted*
+ * from the fixed base.  That's why we start at FIX_IO_APIC_BASE_END and
+ * count idx down while incrementing the phys address.
+ */
+char *__acpi_map_table(unsigned long phys, unsigned long size)
+{
+	unsigned long base, offset, mapped_size;
+	int idx;
+
+	if (phys + size < 8*1024*1024) 
+		return __va(phys); 
+
+	offset = phys & (PAGE_SIZE - 1);
+	mapped_size = PAGE_SIZE - offset;
+	set_fixmap(FIX_ACPI_END, phys);
+	base = fix_to_virt(FIX_ACPI_END);
+
+	/*
+	 * Most cases can be covered by the below.
+	 */
+	idx = FIX_ACPI_END;
+	while (mapped_size < size) {
+		if (--idx < FIX_ACPI_BEGIN)
+			return 0;	/* cannot handle this */
+		phys += PAGE_SIZE;
+		set_fixmap(idx, phys);
+		mapped_size += PAGE_SIZE;
+	}
+
+	return ((unsigned char *) base + offset);
+}
+
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+int acpi_lapic;
+
+static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
+
+
+static int __init
+acpi_parse_madt (
+	unsigned long		phys_addr,
+	unsigned long		size)
+{
+	struct acpi_table_madt	*madt = NULL;
+
+	if (!phys_addr || !size)
+		return -EINVAL;
+
+	madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size);
+	if (!madt) {
+		printk(KERN_WARNING PREFIX "Unable to map MADT\n");
+		return -ENODEV;
+	}
+
+	if (madt->lapic_address)
+		acpi_lapic_addr = (u64) madt->lapic_address;
+
+	printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n",
+		madt->lapic_address);
+
+	acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id);
+	
+	return 0;
+}
+
+
+static int __init
+acpi_parse_lapic (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_lapic	*processor = NULL;
+
+	processor = (struct acpi_table_lapic*) header;
+	if (!processor)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	mp_register_lapic (
+		processor->id,					   /* APIC ID */
+		processor->flags.enabled);			  /* Enabled? */
+
+	return 0;
+}
+
+
+static int __init
+acpi_parse_lapic_addr_ovr (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL;
+
+	lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header;
+	if (!lapic_addr_ovr)
+		return -EINVAL;
+
+	acpi_lapic_addr = lapic_addr_ovr->address;
+
+	return 0;
+}
+
+#ifndef CONFIG_ACPI_HT_ONLY
+
+static int __init
+acpi_parse_lapic_nmi (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_lapic_nmi *lapic_nmi = NULL;
+
+	lapic_nmi = (struct acpi_table_lapic_nmi*) header;
+	if (!lapic_nmi)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	if (lapic_nmi->lint != 1)
+		printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n");
+
+	return 0;
+}
+
+#endif /*CONFIG_ACPI_HT_ONLY*/
+
+#endif /*CONFIG_X86_LOCAL_APIC*/
+
+#ifdef CONFIG_X86_IO_APIC
+
+int acpi_ioapic;
+
+#ifndef CONFIG_ACPI_HT_ONLY
+
+static int __init
+acpi_parse_ioapic (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_ioapic *ioapic = NULL;
+
+	ioapic = (struct acpi_table_ioapic*) header;
+	if (!ioapic)
+		return -EINVAL;
+ 
+	acpi_table_print_madt_entry(header);
+
+	mp_register_ioapic (
+		ioapic->id,
+		ioapic->address,
+		ioapic->global_irq_base);
+ 
+	return 0;
+}
+
+
+static int __init
+acpi_parse_int_src_ovr (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_int_src_ovr *intsrc = NULL;
+
+	intsrc = (struct acpi_table_int_src_ovr*) header;
+	if (!intsrc)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	mp_override_legacy_irq (
+		intsrc->bus_irq,
+		intsrc->flags.polarity,
+		intsrc->flags.trigger,
+		intsrc->global_irq);
+
+	return 0;
+}
+
+
+static int __init
+acpi_parse_nmi_src (
+	acpi_table_entry_header *header)
+{
+	struct acpi_table_nmi_src *nmi_src = NULL;
+
+	nmi_src = (struct acpi_table_nmi_src*) header;
+	if (!nmi_src)
+		return -EINVAL;
+
+	acpi_table_print_madt_entry(header);
+
+	/* TBD: Support nimsrc entries? */
+
+	return 0;
+}
+
+#endif /*!CONFIG_ACPI_HT_ONLY*/ 
+#endif /*CONFIG_X86_IO_APIC*/
+
+
+static unsigned long __init
+acpi_scan_rsdp (
+	unsigned long		start,
+	unsigned long		length)
+{
+	unsigned long		offset = 0;
+	unsigned long		sig_len = sizeof("RSD PTR ") - 1;
+
+	/*
+	 * Scan all 16-byte boundaries of the physical memory region for the
+	 * RSDP signature.
+	 */
+	for (offset = 0; offset < length; offset += 16) {
+		if (strncmp((char *) (start + offset), "RSD PTR ", sig_len))
+			continue;
+		return (start + offset);
+	}
+
+	return 0;
+}
+
+
+unsigned long __init
+acpi_find_rsdp (void)
+{
+	unsigned long		rsdp_phys = 0;
+
+	/*
+	 * Scan memory looking for the RSDP signature. First search EBDA (low
+	 * memory) paragraphs and then search upper memory (E0000-FFFFF).
+	 */
+	rsdp_phys = acpi_scan_rsdp (0, 0x400);
+	if (!rsdp_phys)
+		rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF);
+
+	return rsdp_phys;
+}
+
+
+int __init
+acpi_boot_init (void)
+{
+	int			result = 0;
+
+	/*
+	 * The default interrupt routing model is PIC (8259).  This gets
+	 * overriden if IOAPICs are enumerated (below).
+	 */
+	acpi_irq_model = ACPI_IRQ_MODEL_PIC;
+
+	/* 
+	 * Initialize the ACPI boot-time table parser.
+	 */
+	result = acpi_table_init();
+	if (result)
+		return result;
+
+	result = acpi_blacklisted();
+	if (result) {
+		acpi_disabled = 1;
+		return result;
+	}
+	else
+		printk(KERN_NOTICE PREFIX "BIOS passes blacklist\n");
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+	/* 
+	 * MADT
+	 * ----
+	 * Parse the Multiple APIC Description Table (MADT), if exists.
+	 * Note that this table provides platform SMP configuration 
+	 * information -- the successor to MPS tables.
+	 */
+
+	result = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
+	if (!result) {
+		printk(KERN_WARNING PREFIX "MADT not present\n");
+		return 0;
+	}
+	else if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing MADT\n");
+		return result;
+	}
+	else if (result > 1) 
+		printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n");
+
+	/* 
+	 * Local APIC
+	 * ----------
+	 * Note that the LAPIC address is obtained from the MADT (32-bit value)
+	 * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
+	 */
+
+	result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr);
+	if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
+		return result;
+	}
+
+	mp_register_lapic_address(acpi_lapic_addr);
+
+	result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic);
+	if (!result) { 
+		printk(KERN_ERR PREFIX "No LAPIC entries present\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return -ENODEV;
+	}
+	else if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return result;
+	}
+
+#ifndef CONFIG_ACPI_HT_ONLY
+	result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi);
+	if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return result;
+	}
+#endif /*!CONFIG_ACPI_HT_ONLY*/
+
+	acpi_lapic = 1;
+
+#endif /*CONFIG_X86_LOCAL_APIC*/
+
+#ifdef CONFIG_X86_IO_APIC
+#ifndef CONFIG_ACPI_HT_ONLY
+
+	/* 
+	 * I/O APIC 
+	 * --------
+	 */
+
+	result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic);
+	if (!result) { 
+		printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
+		return -ENODEV;
+	}
+	else if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n");
+		return result;
+	}
+
+	/* Build a default routing table for legacy (ISA) interrupts. */
+	mp_config_acpi_legacy_irqs();
+
+	result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr);
+	if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return result;
+	}
+
+	result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src);
+	if (result < 0) {
+		printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
+		/* TBD: Cleanup to allow fallback to MPS */
+		return result;
+	}
+
+	acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
+
+	acpi_ioapic = 1;
+
+#endif /*!CONFIG_ACPI_HT_ONLY*/
+#endif /*CONFIG_X86_IO_APIC*/
+
+#ifdef CONFIG_X86_LOCAL_APIC
+	if (acpi_lapic && acpi_ioapic) {
+		smp_found_config = 1;
+		clustered_apic_check();
+	}
+#endif
+
+	return 0;
+}
diff -Nru a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/kernel/acpi/sleep.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,96 @@
+/*
+ * sleep.c - x86-specific ACPI sleep support.
+ *
+ *  Copyright (C) 2001-2003 Patrick Mochel
+ */
+
+#include <linux/acpi.h>
+#include <linux/bootmem.h>
+#include <asm/smp.h>
+
+
+/* address in low memory of the wakeup routine. */
+unsigned long acpi_wakeup_address = 0;
+unsigned long acpi_video_flags;
+extern char wakeup_start, wakeup_end;
+
+extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
+
+static void init_low_mapping(pgd_t *pgd, int pgd_limit)
+{
+	int pgd_ofs = 0;
+
+	while ((pgd_ofs < pgd_limit) && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) {
+		set_pgd(pgd, *(pgd+USER_PTRS_PER_PGD));
+		pgd_ofs++, pgd++;
+	}
+}
+
+/**
+ * acpi_save_state_mem - save kernel state
+ *
+ * Create an identity mapped page table and copy the wakeup routine to
+ * low memory.
+ */
+int acpi_save_state_mem (void)
+{
+#if CONFIG_X86_PAE
+	panic("S3 and PAE do not like each other for now.");
+	return 1;
+#endif
+	init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD);
+	memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start);
+	acpi_copy_wakeup_routine(acpi_wakeup_address);
+
+	return 0;
+}
+
+/**
+ * acpi_save_state_disk - save kernel state to disk
+ *
+ */
+int acpi_save_state_disk (void)
+{
+	return 1;
+}
+
+/*
+ * acpi_restore_state
+ */
+void acpi_restore_state_mem (void)
+{
+	zap_low_mappings();
+}
+
+/**
+ * acpi_reserve_bootmem - do _very_ early ACPI initialisation
+ *
+ * We allocate a page in low memory for the wakeup
+ * routine for when we come back from a sleep state. The
+ * runtime allocator allows specification of <16M pages, but not
+ * <1M pages.
+ */
+void __init acpi_reserve_bootmem(void)
+{
+	acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
+	if ((&wakeup_end - &wakeup_start) > PAGE_SIZE)
+		printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n");
+	printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
+}
+
+static int __init acpi_sleep_setup(char *str)
+{
+	while ((str != NULL) && (*str != '\0')) {
+		if (strncmp(str, "s3_bios", 7) == 0)
+			acpi_video_flags = 1;
+		if (strncmp(str, "s3_mode", 7) == 0)
+			acpi_video_flags |= 2;
+		str = strchr(str, ',');
+		if (str != NULL)
+			str += strspn(str, ", \t");
+	}
+	return 1;
+}
+
+
+__setup("acpi_sleep=", acpi_sleep_setup);
diff -Nru a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/kernel/acpi/wakeup.S	Fri Feb 14 15:53:09 2003
@@ -0,0 +1,325 @@
+.text
+#include <linux/linkage.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+
+#
+# wakeup_code runs in real mode, and at unknown address (determined at run-time).
+# Therefore it must only use relative jumps/calls. 
+#
+# Do we need to deal with A20? It is okay: ACPI specs says A20 must be enabled
+#
+# If physical address of wakeup_code is 0x12345, BIOS should call us with
+# cs = 0x1234, eip = 0x05
+# 
+
+ALIGN
+	.align	4096
+ENTRY(wakeup_start)
+wakeup_code:
+	wakeup_code_start = .
+	.code16
+
+ 	movw	$0xb800, %ax
+	movw	%ax,%fs
+	movw	$0x0e00 + 'L', %fs:(0x10)
+
+	cli
+	cld
+
+	# setup data segment
+	movw	%cs, %ax
+	movw	%ax, %ds					# Make ds:0 point to wakeup_start
+	movw	%ax, %ss
+	mov	$(wakeup_stack - wakeup_code), %sp		# Private stack is needed for ASUS board
+	movw	$0x0e00 + 'S', %fs:(0x12)
+
+	pushl	$0						# Kill any dangerous flags
+	popfl
+
+	movl	real_magic - wakeup_code, %eax
+	cmpl	$0x12345678, %eax
+	jne	bogus_real_magic
+
+	testl	$1, video_flags - wakeup_code
+	jz	1f
+	lcall   $0xc000,$3
+1:
+
+	testl	$2, video_flags - wakeup_code
+	jz	1f
+	mov	video_mode - wakeup_code, %ax
+	call	mode_set
+1:
+
+	# set up page table
+	movl	$swapper_pg_dir-__PAGE_OFFSET, %eax
+	movl	%eax, %cr3
+
+	# make sure %cr4 is set correctly (features, etc)
+	movl	real_save_cr4 - wakeup_code, %eax
+	movl	%eax, %cr4
+	movw	$0xb800, %ax
+	movw	%ax,%fs
+	movw	$0x0e00 + 'i', %fs:(0x12)
+	
+	# need a gdt
+	lgdt	real_save_gdt - wakeup_code
+
+	movl	real_save_cr0 - wakeup_code, %eax
+	movl	%eax, %cr0
+	jmp 1f
+1:
+	movw	$0x0e00 + 'n', %fs:(0x14)
+
+	movl	real_magic - wakeup_code, %eax
+	cmpl	$0x12345678, %eax
+	jne	bogus_real_magic
+
+	ljmpl	$__KERNEL_CS,$wakeup_pmode_return
+
+real_save_gdt:	.word 0
+		.long 0
+real_save_cr0:	.long 0
+real_save_cr3:	.long 0
+real_save_cr4:	.long 0
+real_magic:	.long 0
+video_mode:	.long 0
+video_flags:	.long 0
+
+bogus_real_magic:
+	movw	$0x0e00 + 'B', %fs:(0x12)
+	jmp bogus_real_magic
+
+/* This code uses an extended set of video mode numbers. These include:
+ * Aliases for standard modes
+ *	NORMAL_VGA (-1)
+ *	EXTENDED_VGA (-2)
+ *	ASK_VGA (-3)
+ * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
+ * of compatibility when extending the table. These are between 0x00 and 0xff.
+ */
+#define VIDEO_FIRST_MENU 0x0000
+
+/* Standard BIOS video modes (BIOS number + 0x0100) */
+#define VIDEO_FIRST_BIOS 0x0100
+
+/* VESA BIOS video modes (VESA number + 0x0200) */
+#define VIDEO_FIRST_VESA 0x0200
+
+/* Video7 special modes (BIOS number + 0x0900) */
+#define VIDEO_FIRST_V7 0x0900
+
+# Setting of user mode (AX=mode ID) => CF=success
+mode_set:
+	movw	%ax, %bx
+#if 0
+	cmpb	$0xff, %ah
+	jz	setalias
+
+	testb	$VIDEO_RECALC>>8, %ah
+	jnz	_setrec
+
+	cmpb	$VIDEO_FIRST_RESOLUTION>>8, %ah
+	jnc	setres
+	
+	cmpb	$VIDEO_FIRST_SPECIAL>>8, %ah
+	jz	setspc
+
+	cmpb	$VIDEO_FIRST_V7>>8, %ah
+	jz	setv7
+#endif
+	
+	cmpb	$VIDEO_FIRST_VESA>>8, %ah
+	jnc	check_vesa
+#if 0	
+	orb	%ah, %ah
+	jz	setmenu
+#endif
+	
+	decb	%ah
+#	jz	setbios				  Add bios modes later
+
+setbad:	clc
+	ret
+
+check_vesa:
+	subb	$VIDEO_FIRST_VESA>>8, %bh
+	orw	$0x4000, %bx			# Use linear frame buffer
+	movw	$0x4f02, %ax			# VESA BIOS mode set call
+	int	$0x10
+	cmpw	$0x004f, %ax			# AL=4f if implemented
+	jnz	_setbad				# AH=0 if OK
+
+	stc
+	ret
+
+_setbad: jmp setbad
+
+	.code32
+	ALIGN
+
+.org	0x800
+wakeup_stack_begin:	# Stack grows down
+
+.org	0xff0		# Just below end of page
+wakeup_stack:
+ENTRY(wakeup_end)
+	
+.org	0x1000
+
+wakeup_pmode_return:
+	movl	$__KERNEL_DS, %eax
+	movl	%eax, %ds
+	movw	$0x0e00 + 'u', %ds:(0xb8016)
+
+	# restore other segment registers
+	xorl	%eax, %eax
+	movw	%ax, %fs
+	movw	%ax, %gs
+
+	# reload the gdt, as we need the full 32 bit address
+	lgdt	saved_gdt
+	lidt	saved_idt
+	lldt	saved_ldt
+	ljmp	$(__KERNEL_CS),$1f
+1:
+	movl	%cr3, %eax
+	movl	%eax, %cr3
+	wbinvd
+
+	# and restore the stack ... but you need gdt for this to work
+	movl	$__KERNEL_DS, %eax
+	movw	%ax, %ss
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movl	saved_esp, %esp
+
+	movw	$0x0e00 + 'W', %ds:(0xb8018)
+	movl	$(1024*1024*3), %ecx
+	movl	$0, %esi
+	rep	lodsb
+	movw	$0x0e00 + 'O', %ds:(0xb8018)
+
+	movl	%cs:saved_magic, %eax
+	cmpl	$0x12345678, %eax
+	jne	bogus_magic
+
+	# restore the other general registers
+	movl	saved_ebx, %ebx
+	movl	saved_edi, %edi
+	movl	saved_esi, %esi
+	movl	saved_ebp, %ebp
+
+	# jump to place where we left off
+	movl	saved_eip,%eax
+	movw	$0x0e00 + 'x', %ds:(0xb8018)
+	pushl	%eax
+	popl	%eax
+	movw	$0x0e00 + '!', %ds:(0xb801a)
+	jmp	*%eax
+
+bogus_magic:
+	movw	$0x0e00 + 'B', %ds:(0xb8018)
+	jmp bogus_magic
+
+bogus_magic2:
+	movw	$0x0e00 + '2', %ds:(0xb8018)
+	jmp bogus_magic2
+		
+##
+# acpi_copy_wakeup_routine
+#
+# Copy the above routine to low memory.
+#
+# Parameters:
+# %eax:	place to copy wakeup routine to
+#
+# Returned address is location of code in low memory (past data and stack)
+#
+ENTRY(acpi_copy_wakeup_routine)
+
+	sgdt	saved_gdt
+	sidt	saved_idt
+	sldt	saved_ldt
+	str	saved_tss
+
+	movl    %cr3, %edx
+	movl    %edx, real_save_cr3 - wakeup_start (%eax)
+	movl    %cr4, %edx
+	movl    %edx, real_save_cr4 - wakeup_start (%eax)
+	movl	%cr0, %edx
+	movl	%edx, real_save_cr0 - wakeup_start (%eax)
+	sgdt    real_save_gdt - wakeup_start (%eax)
+
+	movl	saved_videomode, %edx
+	movl	%edx, video_mode - wakeup_start (%eax)
+	movl	acpi_video_flags, %edx
+	movl	%edx, video_flags - wakeup_start (%eax)
+	movl	$0x12345678, real_magic - wakeup_start (%eax)
+	movl	$0x12345678, saved_magic
+	ret
+
+.data
+ALIGN
+ENTRY(saved_ebp)	.long	0
+ENTRY(saved_esi)	.long	0
+ENTRY(saved_edi)	.long	0
+ENTRY(saved_ebx)	.long	0
+
+ENTRY(saved_eip)	.long	0
+ENTRY(saved_esp)	.long	0
+
+ENTRY(saved_magic)	.long	0
+
+ENTRY(do_suspend_lowlevel)
+	cmpl $0,4(%esp)
+	jne ret_point
+	call save_processor_state
+
+	movl %esp, saved_context_esp
+	movl %eax, saved_context_eax
+	movl %ebx, saved_context_ebx
+	movl %ecx, saved_context_ecx
+	movl %edx, saved_context_edx
+	movl %ebp, saved_context_ebp
+	movl %esi, saved_context_esi
+	movl %edi, saved_context_edi
+	pushfl ; popl saved_context_eflags
+
+	movl $ret_point,saved_eip
+	movl %esp,saved_esp
+	movl %ebp,saved_ebp
+	movl %ebx,saved_ebx
+	movl %edi,saved_edi
+	movl %esi,saved_esi
+
+	pushl $3
+	call acpi_enter_sleep_state
+	addl $4,%esp
+	ret
+	.p2align 4,,7
+ret_point:
+	movl $__KERNEL_DS,%eax
+	movw %ax, %ds
+	movl saved_context_esp, %esp
+	movl saved_context_ebp, %ebp
+	movl saved_context_eax, %eax
+	movl saved_context_ebx, %ebx
+	movl saved_context_ecx, %ecx
+	movl saved_context_edx, %edx
+	movl saved_context_esi, %esi
+	movl saved_context_edi, %edi
+	call restore_processor_state
+	pushl saved_context_eflags ; popfl
+	ret
+
+ALIGN
+# saved registers
+saved_gdt:	.long	0,0
+saved_idt:	.long	0,0
+saved_ldt:	.long	0
+saved_tss:	.long	0
+
diff -Nru a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c
--- a/arch/i386/kernel/acpi.c	Fri Feb 14 15:53:12 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,539 +0,0 @@
-/*
- *  acpi.c - Architecture-Specific Low-Level ACPI Support
- *
- *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
- *  Copyright (C) 2001 Patrick Mochel <mochel@osdl.org>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/stddef.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/bootmem.h>
-#include <linux/irq.h>
-#include <linux/acpi.h>
-#include <asm/mpspec.h>
-#include <asm/io.h>
-#include <asm/apic.h>
-#include <asm/apicdef.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/pgalloc.h>
-#include <asm/io_apic.h>
-#include <asm/tlbflush.h>
-
-#include <mach_apic.h>
-#include <mach_mpparse.h>
-
-#define PREFIX			"ACPI: "
-
-extern int acpi_disabled;
-
-/* --------------------------------------------------------------------------
-                              Boot-time Configuration
-   -------------------------------------------------------------------------- */
-
-enum acpi_irq_model_id		acpi_irq_model;
-
-#ifdef CONFIG_ACPI_BOOT
-/*
- * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
- * to map the target physical address. The problem is that set_fixmap()
- * provides a single page, and it is possible that the page is not
- * sufficient.
- * By using this area, we can map up to MAX_IO_APICS pages temporarily,
- * i.e. until the next __va_range() call.
- *
- * Important Safety Note:  The fixed I/O APIC page numbers are *subtracted*
- * from the fixed base.  That's why we start at FIX_IO_APIC_BASE_END and
- * count idx down while incrementing the phys address.
- */
-char *__acpi_map_table(unsigned long phys, unsigned long size)
-{
-	unsigned long base, offset, mapped_size;
-	int idx;
-
-	if (phys + size < 8*1024*1024) 
-		return __va(phys); 
-
-	offset = phys & (PAGE_SIZE - 1);
-	mapped_size = PAGE_SIZE - offset;
-	set_fixmap(FIX_ACPI_END, phys);
-	base = fix_to_virt(FIX_ACPI_END);
-
-	/*
-	 * Most cases can be covered by the below.
-	 */
-	idx = FIX_ACPI_END;
-	while (mapped_size < size) {
-		if (--idx < FIX_ACPI_BEGIN)
-			return 0;	/* cannot handle this */
-		phys += PAGE_SIZE;
-		set_fixmap(idx, phys);
-		mapped_size += PAGE_SIZE;
-	}
-
-	return ((unsigned char *) base + offset);
-}
-
-
-#ifdef CONFIG_X86_LOCAL_APIC
-
-int acpi_lapic;
-
-static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
-
-
-static int __init
-acpi_parse_madt (
-	unsigned long		phys_addr,
-	unsigned long		size)
-{
-	struct acpi_table_madt	*madt = NULL;
-
-	if (!phys_addr || !size)
-		return -EINVAL;
-
-	madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size);
-	if (!madt) {
-		printk(KERN_WARNING PREFIX "Unable to map MADT\n");
-		return -ENODEV;
-	}
-
-	if (madt->lapic_address)
-		acpi_lapic_addr = (u64) madt->lapic_address;
-
-	printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n",
-		madt->lapic_address);
-
-	acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id);
-	
-	return 0;
-}
-
-
-static int __init
-acpi_parse_lapic (
-	acpi_table_entry_header *header)
-{
-	struct acpi_table_lapic	*processor = NULL;
-
-	processor = (struct acpi_table_lapic*) header;
-	if (!processor)
-		return -EINVAL;
-
-	acpi_table_print_madt_entry(header);
-
-	mp_register_lapic (
-		processor->id,					   /* APIC ID */
-		processor->flags.enabled);			  /* Enabled? */
-
-	return 0;
-}
-
-
-static int __init
-acpi_parse_lapic_addr_ovr (
-	acpi_table_entry_header *header)
-{
-	struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL;
-
-	lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr*) header;
-	if (!lapic_addr_ovr)
-		return -EINVAL;
-
-	acpi_lapic_addr = lapic_addr_ovr->address;
-
-	return 0;
-}
-
-#ifndef CONFIG_ACPI_HT_ONLY
-
-static int __init
-acpi_parse_lapic_nmi (
-	acpi_table_entry_header *header)
-{
-	struct acpi_table_lapic_nmi *lapic_nmi = NULL;
-
-	lapic_nmi = (struct acpi_table_lapic_nmi*) header;
-	if (!lapic_nmi)
-		return -EINVAL;
-
-	acpi_table_print_madt_entry(header);
-
-	if (lapic_nmi->lint != 1)
-		printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n");
-
-	return 0;
-}
-
-#endif /*CONFIG_ACPI_HT_ONLY*/
-
-#endif /*CONFIG_X86_LOCAL_APIC*/
-
-#ifdef CONFIG_X86_IO_APIC
-
-int acpi_ioapic;
-
-#ifndef CONFIG_ACPI_HT_ONLY
-
-static int __init
-acpi_parse_ioapic (
-	acpi_table_entry_header *header)
-{
-	struct acpi_table_ioapic *ioapic = NULL;
-
-	ioapic = (struct acpi_table_ioapic*) header;
-	if (!ioapic)
-		return -EINVAL;
- 
-	acpi_table_print_madt_entry(header);
-
-	mp_register_ioapic (
-		ioapic->id,
-		ioapic->address,
-		ioapic->global_irq_base);
- 
-	return 0;
-}
-
-
-static int __init
-acpi_parse_int_src_ovr (
-	acpi_table_entry_header *header)
-{
-	struct acpi_table_int_src_ovr *intsrc = NULL;
-
-	intsrc = (struct acpi_table_int_src_ovr*) header;
-	if (!intsrc)
-		return -EINVAL;
-
-	acpi_table_print_madt_entry(header);
-
-	mp_override_legacy_irq (
-		intsrc->bus_irq,
-		intsrc->flags.polarity,
-		intsrc->flags.trigger,
-		intsrc->global_irq);
-
-	return 0;
-}
-
-
-static int __init
-acpi_parse_nmi_src (
-	acpi_table_entry_header *header)
-{
-	struct acpi_table_nmi_src *nmi_src = NULL;
-
-	nmi_src = (struct acpi_table_nmi_src*) header;
-	if (!nmi_src)
-		return -EINVAL;
-
-	acpi_table_print_madt_entry(header);
-
-	/* TBD: Support nimsrc entries? */
-
-	return 0;
-}
-
-#endif /*!CONFIG_ACPI_HT_ONLY*/ 
-#endif /*CONFIG_X86_IO_APIC*/
-
-
-static unsigned long __init
-acpi_scan_rsdp (
-	unsigned long		start,
-	unsigned long		length)
-{
-	unsigned long		offset = 0;
-	unsigned long		sig_len = sizeof("RSD PTR ") - 1;
-
-	/*
-	 * Scan all 16-byte boundaries of the physical memory region for the
-	 * RSDP signature.
-	 */
-	for (offset = 0; offset < length; offset += 16) {
-		if (strncmp((char *) (start + offset), "RSD PTR ", sig_len))
-			continue;
-		return (start + offset);
-	}
-
-	return 0;
-}
-
-
-unsigned long __init
-acpi_find_rsdp (void)
-{
-	unsigned long		rsdp_phys = 0;
-
-	/*
-	 * Scan memory looking for the RSDP signature. First search EBDA (low
-	 * memory) paragraphs and then search upper memory (E0000-FFFFF).
-	 */
-	rsdp_phys = acpi_scan_rsdp (0, 0x400);
-	if (!rsdp_phys)
-		rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF);
-
-	return rsdp_phys;
-}
-
-
-int __init
-acpi_boot_init (void)
-{
-	int			result = 0;
-
-	/*
-	 * The default interrupt routing model is PIC (8259).  This gets
-	 * overriden if IOAPICs are enumerated (below).
-	 */
-	acpi_irq_model = ACPI_IRQ_MODEL_PIC;
-
-	/* 
-	 * Initialize the ACPI boot-time table parser.
-	 */
-	result = acpi_table_init();
-	if (result)
-		return result;
-
-	result = acpi_blacklisted();
-	if (result) {
-		acpi_disabled = 1;
-		return result;
-	}
-	else
-		printk(KERN_NOTICE PREFIX "BIOS passes blacklist\n");
-
-#ifdef CONFIG_X86_LOCAL_APIC
-
-	/* 
-	 * MADT
-	 * ----
-	 * Parse the Multiple APIC Description Table (MADT), if exists.
-	 * Note that this table provides platform SMP configuration 
-	 * information -- the successor to MPS tables.
-	 */
-
-	result = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
-	if (!result) {
-		printk(KERN_WARNING PREFIX "MADT not present\n");
-		return 0;
-	}
-	else if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing MADT\n");
-		return result;
-	}
-	else if (result > 1) 
-		printk(KERN_WARNING PREFIX "Multiple MADT tables exist\n");
-
-	/* 
-	 * Local APIC
-	 * ----------
-	 * Note that the LAPIC address is obtained from the MADT (32-bit value)
-	 * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
-	 */
-
-	result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr);
-	if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
-		return result;
-	}
-
-	mp_register_lapic_address(acpi_lapic_addr);
-
-	result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic);
-	if (!result) { 
-		printk(KERN_ERR PREFIX "No LAPIC entries present\n");
-		/* TBD: Cleanup to allow fallback to MPS */
-		return -ENODEV;
-	}
-	else if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
-		/* TBD: Cleanup to allow fallback to MPS */
-		return result;
-	}
-
-#ifndef CONFIG_ACPI_HT_ONLY
-	result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi);
-	if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
-		/* TBD: Cleanup to allow fallback to MPS */
-		return result;
-	}
-#endif /*!CONFIG_ACPI_HT_ONLY*/
-
-	acpi_lapic = 1;
-
-#endif /*CONFIG_X86_LOCAL_APIC*/
-
-#ifdef CONFIG_X86_IO_APIC
-#ifndef CONFIG_ACPI_HT_ONLY
-
-	/* 
-	 * I/O APIC 
-	 * --------
-	 */
-
-	result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic);
-	if (!result) { 
-		printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
-		return -ENODEV;
-	}
-	else if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n");
-		return result;
-	}
-
-	/* Build a default routing table for legacy (ISA) interrupts. */
-	mp_config_acpi_legacy_irqs();
-
-	result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr);
-	if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
-		/* TBD: Cleanup to allow fallback to MPS */
-		return result;
-	}
-
-	result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src);
-	if (result < 0) {
-		printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
-		/* TBD: Cleanup to allow fallback to MPS */
-		return result;
-	}
-
-	acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
-
-	acpi_ioapic = 1;
-
-#endif /*!CONFIG_ACPI_HT_ONLY*/
-#endif /*CONFIG_X86_IO_APIC*/
-
-#ifdef CONFIG_X86_LOCAL_APIC
-	if (acpi_lapic && acpi_ioapic) {
-		smp_found_config = 1;
-		clustered_apic_check();
-	}
-#endif
-
-	return 0;
-}
-
-#endif /*CONFIG_ACPI_BOOT*/
-
-
-/* --------------------------------------------------------------------------
-                              Low-Level Sleep Support
-   -------------------------------------------------------------------------- */
-
-#ifdef CONFIG_ACPI_SLEEP
-
-/* address in low memory of the wakeup routine. */
-unsigned long acpi_wakeup_address = 0;
-unsigned long acpi_video_flags;
-extern char wakeup_start, wakeup_end;
-
-extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
-
-static void init_low_mapping(pgd_t *pgd, int pgd_limit)
-{
-	int pgd_ofs = 0;
-
-	while ((pgd_ofs < pgd_limit) && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) {
-		set_pgd(pgd, *(pgd+USER_PTRS_PER_PGD));
-		pgd_ofs++, pgd++;
-	}
-}
-
-/**
- * acpi_save_state_mem - save kernel state
- *
- * Create an identity mapped page table and copy the wakeup routine to
- * low memory.
- */
-int acpi_save_state_mem (void)
-{
-#if CONFIG_X86_PAE
-	panic("S3 and PAE do not like each other for now.");
-	return 1;
-#endif
-	init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD);
-	memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start);
-	acpi_copy_wakeup_routine(acpi_wakeup_address);
-
-	return 0;
-}
-
-/**
- * acpi_save_state_disk - save kernel state to disk
- *
- */
-int acpi_save_state_disk (void)
-{
-	return 1;
-}
-
-/*
- * acpi_restore_state
- */
-void acpi_restore_state_mem (void)
-{
-	zap_low_mappings();
-}
-
-/**
- * acpi_reserve_bootmem - do _very_ early ACPI initialisation
- *
- * We allocate a page in low memory for the wakeup
- * routine for when we come back from a sleep state. The
- * runtime allocator allows specification of <16M pages, but not
- * <1M pages.
- */
-void __init acpi_reserve_bootmem(void)
-{
-	acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
-	if ((&wakeup_end - &wakeup_start) > PAGE_SIZE)
-		printk(KERN_CRIT "ACPI: Wakeup code way too big, will crash on attempt to suspend\n");
-	printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
-}
-
-static int __init acpi_sleep_setup(char *str)
-{
-	while ((str != NULL) && (*str != '\0')) {
-		if (strncmp(str, "s3_bios", 7) == 0)
-			acpi_video_flags = 1;
-		if (strncmp(str, "s3_mode", 7) == 0)
-			acpi_video_flags |= 2;
-		str = strchr(str, ',');
-		if (str != NULL)
-			str += strspn(str, ", \t");
-	}
-	return 1;
-}
-
-
-__setup("acpi_sleep=", acpi_sleep_setup);
-#endif /*CONFIG_ACPI_SLEEP*/
diff -Nru a/arch/i386/kernel/acpi_wakeup.S b/arch/i386/kernel/acpi_wakeup.S
--- a/arch/i386/kernel/acpi_wakeup.S	Fri Feb 14 15:53:09 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,323 +0,0 @@
-.text
-#include <linux/linkage.h>
-#include <asm/segment.h>
-#include <asm/page.h>
-
-#
-# wakeup_code runs in real mode, and at unknown address (determined at run-time).
-# Therefore it must only use relative jumps/calls. 
-#
-# Do we need to deal with A20? It is okay: ACPI specs says A20 must be enabled
-#
-# If physical address of wakeup_code is 0x12345, BIOS should call us with
-# cs = 0x1234, eip = 0x05
-# 
-
-ALIGN
-	.align	4096
-ENTRY(wakeup_start)
-wakeup_code:
-	wakeup_code_start = .
-	.code16
-
- 	movw	$0xb800, %ax
-	movw	%ax,%fs
-	movw	$0x0e00 + 'L', %fs:(0x10)
-
-	cli
-	cld
-
-	# setup data segment
-	movw	%cs, %ax
-	movw	%ax, %ds					# Make ds:0 point to wakeup_start
-	movw	%ax, %ss
-	mov	wakeup_stack - wakeup_code, %sp			# Private stack is needed for ASUS board
-	movw	$0x0e00 + 'S', %fs:(0x12)
-
-	pushl	$0						# Kill any dangerous flags
-	popfl
-
-	movl	real_magic - wakeup_code, %eax
-	cmpl	$0x12345678, %eax
-	jne	bogus_real_magic
-
-	testl	$1, video_flags - wakeup_code
-	jz	1f
-	lcall   $0xc000,$3
-1:
-
-	testl	$2, video_flags - wakeup_code
-	jz	1f
-	mov	video_mode - wakeup_code, %ax
-	call	mode_set
-1:
-
-	# set up page table
-	movl	$swapper_pg_dir-__PAGE_OFFSET, %eax
-	movl	%eax, %cr3
-
-	# make sure %cr4 is set correctly (features, etc)
-	movl	real_save_cr4 - wakeup_code, %eax
-	movl	%eax, %cr4
-	movw	$0xb800, %ax
-	movw	%ax,%fs
-	movw	$0x0e00 + 'i', %fs:(0x12)
-	
-	# need a gdt
-	lgdt	real_save_gdt - wakeup_code
-
-	movl	real_save_cr0 - wakeup_code, %eax
-	movl	%eax, %cr0
-	jmp 1f
-1:
-	movw	$0x0e00 + 'n', %fs:(0x14)
-
-	movl	real_magic - wakeup_code, %eax
-	cmpl	$0x12345678, %eax
-	jne	bogus_real_magic
-
-	ljmpl	$__KERNEL_CS,$wakeup_pmode_return
-
-real_save_gdt:	.word 0
-		.long 0
-real_save_cr0:	.long 0
-real_save_cr3:	.long 0
-real_save_cr4:	.long 0
-real_magic:	.long 0
-video_mode:	.long 0
-video_flags:	.long 0
-
-bogus_real_magic:
-	movw	$0x0e00 + 'B', %fs:(0x12)
-	jmp bogus_real_magic
-
-/* This code uses an extended set of video mode numbers. These include:
- * Aliases for standard modes
- *	NORMAL_VGA (-1)
- *	EXTENDED_VGA (-2)
- *	ASK_VGA (-3)
- * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
- * of compatibility when extending the table. These are between 0x00 and 0xff.
- */
-#define VIDEO_FIRST_MENU 0x0000
-
-/* Standard BIOS video modes (BIOS number + 0x0100) */
-#define VIDEO_FIRST_BIOS 0x0100
-
-/* VESA BIOS video modes (VESA number + 0x0200) */
-#define VIDEO_FIRST_VESA 0x0200
-
-/* Video7 special modes (BIOS number + 0x0900) */
-#define VIDEO_FIRST_V7 0x0900
-
-# Setting of user mode (AX=mode ID) => CF=success
-mode_set:
-	movw	%ax, %bx
-#if 0
-	cmpb	$0xff, %ah
-	jz	setalias
-
-	testb	$VIDEO_RECALC>>8, %ah
-	jnz	_setrec
-
-	cmpb	$VIDEO_FIRST_RESOLUTION>>8, %ah
-	jnc	setres
-	
-	cmpb	$VIDEO_FIRST_SPECIAL>>8, %ah
-	jz	setspc
-
-	cmpb	$VIDEO_FIRST_V7>>8, %ah
-	jz	setv7
-#endif
-	
-	cmpb	$VIDEO_FIRST_VESA>>8, %ah
-	jnc	check_vesa
-#if 0	
-	orb	%ah, %ah
-	jz	setmenu
-#endif
-	
-	decb	%ah
-#	jz	setbios				  Add bios modes later
-
-setbad:	clc
-	ret
-
-check_vesa:
-	subb	$VIDEO_FIRST_VESA>>8, %bh
-	orw	$0x4000, %bx			# Use linear frame buffer
-	movw	$0x4f02, %ax			# VESA BIOS mode set call
-	int	$0x10
-	cmpw	$0x004f, %ax			# AL=4f if implemented
-	jnz	_setbad				# AH=0 if OK
-
-	stc
-	ret
-
-_setbad: jmp setbad
-
-	.code32
-	ALIGN
-
-
-.org	0x2000
-wakeup_stack:
-.org	0x3000
-ENTRY(wakeup_end)
-.org	0x4000
-
-wakeup_pmode_return:
-	movl	$__KERNEL_DS, %eax
-	movl	%eax, %ds
-	movw	$0x0e00 + 'u', %ds:(0xb8016)
-
-	# restore other segment registers
-	xorl	%eax, %eax
-	movw	%ax, %fs
-	movw	%ax, %gs
-
-	# reload the gdt, as we need the full 32 bit address
-	lgdt	saved_gdt
-	lidt	saved_idt
-	lldt	saved_ldt
-	ljmp	$(__KERNEL_CS),$1f
-1:
-	movl	%cr3, %eax
-	movl	%eax, %cr3
-	wbinvd
-
-	# and restore the stack ... but you need gdt for this to work
-	movl	$__KERNEL_DS, %eax
-	movw	%ax, %ss
-	movw	%ax, %ds
-	movw	%ax, %es
-	movw	%ax, %fs
-	movw	%ax, %gs
-	movl	saved_esp, %esp
-
-	movw	$0x0e00 + 'W', %ds:(0xb8018)
-	movl	$(1024*1024*3), %ecx
-	movl	$0, %esi
-	rep	lodsb
-	movw	$0x0e00 + 'O', %ds:(0xb8018)
-
-	movl	%cs:saved_magic, %eax
-	cmpl	$0x12345678, %eax
-	jne	bogus_magic
-
-	# restore the other general registers
-	movl	saved_ebx, %ebx
-	movl	saved_edi, %edi
-	movl	saved_esi, %esi
-	movl	saved_ebp, %ebp
-
-	# jump to place where we left off
-	movl	saved_eip,%eax
-	movw	$0x0e00 + 'x', %ds:(0xb8018)
-	pushl	%eax
-	popl	%eax
-	movw	$0x0e00 + '!', %ds:(0xb801a)
-	jmp	*%eax
-
-bogus_magic:
-	movw	$0x0e00 + 'B', %ds:(0xb8018)
-	jmp bogus_magic
-
-bogus_magic2:
-	movw	$0x0e00 + '2', %ds:(0xb8018)
-	jmp bogus_magic2
-		
-##
-# acpi_copy_wakeup_routine
-#
-# Copy the above routine to low memory.
-#
-# Parameters:
-# %eax:	place to copy wakeup routine to
-#
-# Returned address is location of code in low memory (past data and stack)
-#
-ENTRY(acpi_copy_wakeup_routine)
-
-	sgdt	saved_gdt
-	sidt	saved_idt
-	sldt	saved_ldt
-	str	saved_tss
-
-	movl    %cr3, %edx
-	movl    %edx, real_save_cr3 - wakeup_start (%eax)
-	movl    %cr4, %edx
-	movl    %edx, real_save_cr4 - wakeup_start (%eax)
-	movl	%cr0, %edx
-	movl	%edx, real_save_cr0 - wakeup_start (%eax)
-	sgdt    real_save_gdt - wakeup_start (%eax)
-
-	movl	saved_videomode, %edx
-	movl	%edx, video_mode - wakeup_start (%eax)
-	movl	acpi_video_flags, %edx
-	movl	%edx, video_flags - wakeup_start (%eax)
-	movl	$0x12345678, real_magic - wakeup_start (%eax)
-	movl	$0x12345678, saved_magic
-	ret
-
-.data
-ALIGN
-ENTRY(saved_ebp)	.long	0
-ENTRY(saved_esi)	.long	0
-ENTRY(saved_edi)	.long	0
-ENTRY(saved_ebx)	.long	0
-
-ENTRY(saved_eip)	.long	0
-ENTRY(saved_esp)	.long	0
-
-ENTRY(saved_magic)	.long	0
-
-ENTRY(do_suspend_lowlevel)
-	cmpl $0,4(%esp)
-	jne .L1432
-	call save_processor_state
-
-	movl %esp, saved_context_esp
-	movl %eax, saved_context_eax
-	movl %ebx, saved_context_ebx
-	movl %ecx, saved_context_ecx
-	movl %edx, saved_context_edx
-	movl %ebp, saved_context_ebp
-	movl %esi, saved_context_esi
-	movl %edi, saved_context_edi
-	pushfl ; popl saved_context_eflags
-
-	movl $.L1432,saved_eip
-	movl %esp,saved_esp
-	movl %ebp,saved_ebp
-	movl %ebx,saved_ebx
-	movl %edi,saved_edi
-	movl %esi,saved_esi
-
-	pushl $3
-	call acpi_enter_sleep_state
-	addl $4,%esp
-	ret
-	.p2align 4,,7
-.L1432:
-	movl $__KERNEL_DS,%eax
-	movw %ax, %ds
-	movl saved_context_esp, %esp
-	movl saved_context_ebp, %ebp
-	movl saved_context_eax, %eax
-	movl saved_context_ebx, %ebx
-	movl saved_context_ecx, %ecx
-	movl saved_context_edx, %edx
-	movl saved_context_esi, %esi
-	movl saved_context_edi, %edi
-	call restore_processor_state
-	pushl saved_context_eflags ; popfl
-	ret
-
-ALIGN
-# saved registers
-saved_gdt:	.long	0,0
-saved_idt:	.long	0,0
-saved_ldt:	.long	0
-saved_tss:	.long	0
-
diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
--- a/arch/i386/kernel/apic.c	Fri Feb 14 15:53:12 2003
+++ b/arch/i386/kernel/apic.c	Fri Feb 14 15:53:12 2003
@@ -52,7 +52,7 @@
 
 int prof_multiplier[NR_CPUS] = { 1, };
 int prof_old_multiplier[NR_CPUS] = { 1, };
-int prof_counter[NR_CPUS] = { 1, };
+DEFINE_PER_CPU(int, prof_counter) = 1;
 
 int get_maxlvt(void)
 {
@@ -997,7 +997,7 @@
 
 	x86_do_profile(regs);
 
-	if (--prof_counter[cpu] <= 0) {
+	if (--per_cpu(prof_counter, cpu) <= 0) {
 		/*
 		 * The multiplier may have changed since the last time we got
 		 * to this point as a result of the user writing to
@@ -1006,10 +1006,12 @@
 		 *
 		 * Interrupts are already masked off at this point.
 		 */
-		prof_counter[cpu] = prof_multiplier[cpu];
-		if (prof_counter[cpu] != prof_old_multiplier[cpu]) {
-			__setup_APIC_LVTT(calibration_result/prof_counter[cpu]);
-			prof_old_multiplier[cpu] = prof_counter[cpu];
+		per_cpu(prof_counter, cpu) = prof_multiplier[cpu];
+		if (per_cpu(prof_counter, cpu) != prof_old_multiplier[cpu]) {
+			__setup_APIC_LVTT(
+					calibration_result/
+					per_cpu(prof_counter, cpu));
+			prof_old_multiplier[cpu] = per_cpu(prof_counter, cpu);
 		}
 
 #ifdef CONFIG_SMP
diff -Nru a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
--- a/arch/i386/kernel/apm.c	Fri Feb 14 15:53:08 2003
+++ b/arch/i386/kernel/apm.c	Fri Feb 14 15:53:08 2003
@@ -226,8 +226,6 @@
 #include <asm/uaccess.h>
 #include <asm/desc.h>
 
-#include <linux/sysrq.h>
-
 extern spinlock_t i8253_lock;
 extern unsigned long get_cmos_time(void);
 extern void machine_real_restart(unsigned char *, int);
@@ -972,30 +970,6 @@
 		(void) set_system_power_state(APM_STATE_OFF);
 }
 
-/**
- * handle_poweroff	-	sysrq callback for power down
- * @key: key pressed (unused)
- * @pt_regs: register state (unused)
- * @kbd: keyboard state (unused)
- * @tty: tty involved (unused)
- *
- * When the user hits Sys-Rq o to power down the machine this is the
- * callback we use.
- */
-
-static void handle_poweroff (int key, struct pt_regs *pt_regs,
-			     struct tty_struct *tty)
-{
-        apm_power_off();
-}
-
-static struct sysrq_key_op	sysrq_poweroff_op = {
-	.handler        = handle_poweroff,
-	.help_msg       = "Off",
-	.action_msg     = "Power Off\n"
-};
-
-
 #ifdef CONFIG_APM_DO_ENABLE
 
 /**
@@ -1742,11 +1716,9 @@
 
 	kapmd_running = 1;
 
-	daemonize();
+	daemonize("kapmd");
 
-	strcpy(current->comm, "kapmd");
 	current->flags |= PF_IOTHREAD;
-	sigfillset(&current->blocked);
 
 #ifdef CONFIG_SMP
 	/* 2002/08/01 - WT
@@ -1850,7 +1822,6 @@
 	/* Install our power off handler.. */
 	if (power_off)
 		pm_power_off = apm_power_off;
-	register_sysrq_key('o', &sysrq_poweroff_op);
 
 	if (num_online_cpus() == 1 || smp) {
 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
@@ -2098,7 +2069,6 @@
 	}
 	misc_deregister(&apm_device);
 	remove_proc_entry("apm", NULL);
-	unregister_sysrq_key('o',&sysrq_poweroff_op);
 	if (power_off)
 		pm_power_off = NULL;
 	exit_kapmd = 1;
diff -Nru a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c
--- a/arch/i386/kernel/cpu/centaur.c	Fri Feb 14 15:53:11 2003
+++ b/arch/i386/kernel/cpu/centaur.c	Fri Feb 14 15:53:11 2003
@@ -395,6 +395,8 @@
 					set_bit(X86_FEATURE_CX8, c->x86_capability);
 					set_bit(X86_FEATURE_3DNOW, c->x86_capability);
 
+				case 9:	/* Nehemiah */
+				default:
 					get_model_name(c);
 					display_cacheinfo(c);
 					break;
@@ -408,6 +410,12 @@
 	/* VIA C3 CPUs (670-68F) need further shifting. */
 	if ((c->x86 == 6) && ((c->x86_model == 7) || (c->x86_model == 8)))
 		size >>= 8;
+
+	/* VIA also screwed up Nehemiah stepping 1, and made
+	   it return '65KB' instead of '64KB' */
+	if ((c->x86==6) && (c->x86_model==9) && (c->x86_mask==1))
+		size -=1;
+
 	return size;
 }
 
diff -Nru a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/i386/kernel/cpu/cpufreq/Makefile
--- a/arch/i386/kernel/cpu/cpufreq/Makefile	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/kernel/cpu/cpufreq/Makefile	Fri Feb 14 15:53:09 2003
@@ -1,4 +1,5 @@
 obj-$(CONFIG_X86_POWERNOW_K6)	+= powernow-k6.o
+obj-$(CONFIG_X86_POWERNOW_K7)	+= powernow-k7.o
 obj-$(CONFIG_X86_LONGHAUL)	+= longhaul.o
 obj-$(CONFIG_X86_SPEEDSTEP)	+= speedstep.o
 obj-$(CONFIG_X86_P4_CLOCKMOD)	+= p4-clockmod.o
diff -Nru a/arch/i386/kernel/cpu/cpufreq/elanfreq.c b/arch/i386/kernel/cpu/cpufreq/elanfreq.c
--- a/arch/i386/kernel/cpu/cpufreq/elanfreq.c	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/kernel/cpu/cpufreq/elanfreq.c	Fri Feb 14 15:53:09 2003
@@ -242,6 +242,8 @@
 			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
 	if (!driver)
 		return -ENOMEM;
+	memset(driver, 0, sizeof(struct cpufreq_driver) +
+			NR_CPUS * sizeof(struct cpufreq_policy));
 
 	driver->policy = (struct cpufreq_policy *) (driver + 1);
 
@@ -260,8 +262,6 @@
 
 	driver->verify        = &elanfreq_verify;
 	driver->setpolicy     = &elanfreq_setpolicy;
-	driver->init = NULL;
-	driver->exit = NULL;
 	strncpy(driver->name, "elanfreq", CPUFREQ_NAME_LEN);
 
 	driver->policy[0].cpu    = 0;
diff -Nru a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
--- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c	Fri Feb 14 15:53:09 2003
@@ -431,11 +431,15 @@
 	driver = kmalloc(sizeof(struct cpufreq_driver) + NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
 	if (driver == NULL) 
 		return -ENOMEM;
+	memset(driver, 0, sizeof(struct cpufreq_driver) +
+			NR_CPUS * sizeof(struct cpufreq_policy));
+
 	params = kmalloc(sizeof(struct gxfreq_params), GFP_KERNEL);
 	if (params == NULL) {
 		kfree(driver);
 		return -ENOMEM;
 	}
+	memset(params, 0, sizeof(struct gxfreq_params));
 
 	driver->policy = (struct cpufreq_policy *)(driver + 1);
 	params->cs55x0 = gx_pci;
diff -Nru a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c	Fri Feb 14 15:53:08 2003
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c	Fri Feb 14 15:53:08 2003
@@ -762,6 +762,8 @@
 			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
 	if (!driver)
 		return -ENOMEM;
+	memset(driver, 0, sizeof(struct cpufreq_driver) +
+			NR_CPUS * sizeof(struct cpufreq_policy));
 
 	driver->policy = (struct cpufreq_policy *) (driver + 1);
 
@@ -771,8 +773,7 @@
 
 	driver->verify    = &longhaul_verify;
 	driver->setpolicy = &longhaul_setpolicy;
-	driver->init = NULL;
-	driver->exit = NULL;
+
 	strncpy(driver->name, "longhaul", CPUFREQ_NAME_LEN);
 
 	driver->policy[0].cpu = 0;
diff -Nru a/arch/i386/kernel/cpu/cpufreq/longrun.c b/arch/i386/kernel/cpu/cpufreq/longrun.c
--- a/arch/i386/kernel/cpu/cpufreq/longrun.c	Fri Feb 14 15:53:12 2003
+++ b/arch/i386/kernel/cpu/cpufreq/longrun.c	Fri Feb 14 15:53:12 2003
@@ -54,7 +54,7 @@
 
 	policy->min = longrun_low_freq + msr_lo * 
 		((longrun_high_freq - longrun_low_freq) / 100);
-	policy->min = longrun_low_freq + msr_hi * 
+	policy->max = longrun_low_freq + msr_hi * 
 		((longrun_high_freq - longrun_low_freq) / 100);
 	policy->cpu = 0;
 }
@@ -241,6 +241,8 @@
 			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
 	if (!driver)
 		return -ENOMEM;
+	memset(driver, 0, sizeof(struct cpufreq_driver) +
+			NR_CPUS * sizeof(struct cpufreq_policy));
 
 	driver->policy = (struct cpufreq_policy *) (driver + 1);
 
@@ -251,8 +253,7 @@
 	driver->policy[0].cpuinfo.min_freq = longrun_low_freq;
 	driver->policy[0].cpuinfo.max_freq = longrun_high_freq;
 	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-	driver->init = NULL;
-	driver->exit = NULL;
+
 	strncpy(driver->name, "longrun", CPUFREQ_NAME_LEN);
 
 	longrun_get_policy(&driver->policy[0]);
diff -Nru a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
--- a/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	Fri Feb 14 15:53:12 2003
+++ b/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c	Fri Feb 14 15:53:12 2003
@@ -220,6 +220,8 @@
 			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
 	if (!driver)
 		return -ENOMEM;
+	memset(driver, 0, sizeof(struct cpufreq_driver) +
+			NR_CPUS * sizeof(struct cpufreq_policy));
 
 	driver->policy = (struct cpufreq_policy *) (driver + 1);
 
@@ -240,8 +242,6 @@
 
 	driver->verify        = &cpufreq_p4_verify;
 	driver->setpolicy     = &cpufreq_p4_setpolicy;
-	driver->init = NULL;
-	driver->exit = NULL;
 	strncpy(driver->name, "p4-clockmod", CPUFREQ_NAME_LEN);
 
 	for (i=0;i<NR_CPUS;i++) {
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k6.c	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k6.c	Fri Feb 14 15:53:09 2003
@@ -172,6 +172,8 @@
 		release_region (POWERNOW_IOPORT, 16);
 		return -ENOMEM;
 	}
+	memset(driver, 0, sizeof(struct cpufreq_driver) +
+			NR_CPUS * sizeof(struct cpufreq_policy));
 	driver->policy = (struct cpufreq_policy *) (driver + 1);
 
 	/* table init */
@@ -184,8 +186,6 @@
 
 	driver->verify        = &powernow_k6_verify;
 	driver->setpolicy     = &powernow_k6_setpolicy;
-	driver->init = NULL;
-	driver->exit = NULL;
 	strncpy(driver->name, "powernow-k6", CPUFREQ_NAME_LEN);
 
 	/* cpuinfo and default policy values */
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,408 @@
+/*
+ *  $Id: powernow-k7.c,v 1.31 2003/02/12 21:16:35 davej Exp $
+ *
+ *  (C) 2003 Dave Jones <davej@suse.de>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *  Based upon datasheets & sample CPUs kindly provided by AMD.
+ *
+ *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
+ *
+ * Errata 5: Processor may fail to execute a FID/VID change in presence of interrupt.
+ * - We cli/sti on stepping A0 CPUs around the FID/VID transition.
+ * Errata 15: Processors with half frequency multipliers may hang upon wakeup from disconnect.
+ * - We disable half multipliers if ACPI is used on A0 stepping CPUs.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h> 
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <asm/msr.h>
+#include <asm/timex.h>
+#include <asm/io.h>
+
+#include "powernow-k7.h"
+
+#define DEBUG
+
+#ifdef DEBUG
+#define dprintk(msg...) printk(msg)
+#else
+#define dprintk(msg...) do { } while(0);
+#endif
+
+#define PFX "powernow: "
+
+
+struct psb_s {
+	u8 signature[10];
+	u8 tableversion;
+	u8 flags;
+	u16 settlingtime;
+	u8 reserved1;
+	u8 numpst;
+};
+
+struct pst_s {
+	u32 cpuid;
+	u8 fsbspeed;
+	u8 maxfid;
+	u8 startvid;
+	u8 numpstates;
+};
+
+
+/* divide by 1000 to get VID. */
+static int mobile_vid_table[32] = {
+    2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
+    1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
+    1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
+    1075, 1050, 1024, 1000, 975, 950, 925, 0,
+};
+
+/* divide by 10 to get FID. */
+static int fid_codes[32] = {
+    110, 115, 120, 125, 50, 55, 60, 65,
+    70, 75, 80, 85, 90, 95, 100, 105, 
+    30, 190, 40, 200, 130, 135, 140, 210,
+    150, 225, 160, 165, 170, 180, -1, -1,
+};
+
+static struct cpufreq_driver powernow_driver;
+
+static struct cpufreq_frequency_table *powernow_table;
+
+static unsigned int can_scale_bus;
+static unsigned int can_scale_vid;
+static unsigned int minimum_speed=-1;
+static unsigned int maximum_speed;
+static unsigned int number_scales;
+static unsigned int fsb;
+static unsigned int latency;
+static char have_a0;
+
+
+#ifndef rdmsrl
+#define rdmsrl(msr,val) do {unsigned long l__,h__; \
+	rdmsr (msr, l__, h__);	\
+	val = l__;	\
+	val |= ((u64)h__<<32);	\
+} while(0);
+#endif
+
+#ifndef wrmsrl
+static void wrmsrl (u32 msr, u64 val)
+{
+	u32 lo, hi;
+
+	lo = (u32) val;
+	hi = val >> 32;
+	wrmsr (msr, lo, hi);
+}
+#endif
+
+
+
+static int check_powernow(void)
+{
+	struct cpuinfo_x86 *c = cpu_data;
+	unsigned int maxei, eax, ebx, ecx, edx;
+
+	if (c->x86_vendor != X86_VENDOR_AMD) {
+		printk (KERN_INFO PFX "AMD processor not detected.\n");
+		return 0;
+	}
+
+	if (c->x86 !=6) {
+		printk (KERN_INFO PFX "This module only works with AMD K7 CPUs\n");
+		return 0;
+	}
+
+	printk (KERN_INFO PFX "AMD K7 CPU detected.\n");
+
+	if ((c->x86_model == 6) && (c->x86_mask == 0)) {
+		printk (KERN_INFO PFX "K7 660[A0] core detected, enabling errata workarounds\n");
+		have_a0 = 1;
+	}
+
+	/* Get maximum capabilities */
+	maxei = cpuid_eax (0x80000000);
+	if (maxei < 0x80000007) {	/* Any powernow info ? */
+		printk (KERN_INFO PFX "No powernow capabilities detected\n");
+		return 0;
+	}
+
+	cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
+	printk (KERN_INFO PFX "PowerNOW! Technology present. Can scale: ");
+
+	if (edx & 1 << 1) {
+		printk ("frequency");
+		can_scale_bus=1;
+	}
+
+	if ((edx & (1 << 1 | 1 << 2)) == 0x6)
+		printk (" and ");
+
+	if (edx & 1 << 2) {
+		printk ("voltage");
+		can_scale_vid=1;
+	}
+
+	if (!(edx & (1 << 1 | 1 << 2))) {
+		printk (" nothing.\n");
+		return 0;
+	}
+
+	printk (".\n");
+	return 1;
+}
+
+
+static int get_ranges (unsigned char *pst)
+{
+	int j;
+	u8 fid, vid;
+	unsigned int speed;
+
+	powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
+	if (!powernow_table)
+		return -ENOMEM;
+	memset(powernow_table, 0, (sizeof(struct cpufreq_frequency_table) * (number_scales + 1)));
+
+	for (j=0 ; j < number_scales; j++) {
+		fid = *pst++;
+
+		powernow_table[j].frequency = fsb * fid_codes[fid] * 100;
+		powernow_table[j].index = fid; /* lower 8 bits */
+
+		speed = fsb * (fid_codes[fid]/10);
+		if ((fid_codes[fid] % 10)==5) {
+			speed += fsb/2;
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
+			if (have_a0 == 1)
+				powernow_table[j].frequency = CPUFREQ_ENTRY_INVALID;
+#endif
+		}
+
+		dprintk (KERN_INFO PFX "   FID: 0x%x (%d.%dx [%dMHz])\t", fid,
+			fid_codes[fid] / 10, fid_codes[fid] % 10, speed);
+
+		if (speed < minimum_speed)
+			minimum_speed = speed;
+		if (speed > maximum_speed)
+			maximum_speed = speed;
+
+		vid = *pst++;
+		powernow_table[j].index |= (vid << 8); /* upper 8 bits */
+		dprintk ("VID: 0x%x (%d.%03dV)\n", vid,	mobile_vid_table[vid]/1000,
+			mobile_vid_table[vid]%1000);
+	}
+	dprintk ("\n");
+
+	powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
+	powernow_table[number_scales].index = 0;
+
+	return 0;
+}
+
+
+static void change_speed (unsigned int index)
+{
+	u8 fid, vid;
+	struct cpufreq_freqs freqs;
+	union msr_fidvidstatus fidvidstatus;
+	union msr_fidvidctl fidvidctl;
+
+
+	/* fid are the lower 8 bits of the index we stored into
+	 * the cpufreq frequency table in powernow_decode_bios,
+	 * vid are the upper 8 bits.
+	 */
+
+	fid = powernow_table[index].index & 0xFF;
+	vid = (powernow_table[index].index & 0xFF00) >> 8;
+
+	freqs.cpu = 0;
+
+	rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
+	freqs.old = fsb * fid_codes[fidvidstatus.bits.CFID] * 100;
+
+	freqs.new = powernow_table[index].frequency;
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	/* Now do the magic poking into the MSRs.  */
+
+	if (have_a0 == 1)	/* A0 errata 5 */
+		__asm__("\tcli\n");
+	rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+	fidvidctl.bits.SGTC = latency;	/* Stop grant timeout counter */
+	fidvidctl.bits.FID = fid;
+	fidvidctl.bits.VID = vid;
+	/* Note, we could set these lazily. Ie, only do voltage transition
+	   if its changed since last time (Some speeds have the same voltage) */
+	fidvidctl.bits.FIDC = 1;
+	fidvidctl.bits.VIDC = 1;
+	wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+	if (have_a0 == 1)
+		__asm__("\tsti\n");
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+}
+
+
+int powernow_decode_bios (int maxfid, int startvid)
+{
+	struct psb_s *psb;
+	struct pst_s *pst;
+	struct cpuinfo_x86 *c = cpu_data;
+	unsigned int i, j;
+	unsigned char *p;
+	unsigned int etuple;
+	unsigned int ret;
+
+	etuple = cpuid_eax(0x80000001);
+	etuple &= 0xf00;
+	etuple |= (c->x86_model<<4)|(c->x86_mask);
+
+	for (i=0xC0000; i < 0xffff0 ; i+=16) {
+
+		p = phys_to_virt(i);
+
+		if (memcmp(p, "AMDK7PNOW!",  10) == 0){
+			dprintk (KERN_INFO PFX "Found PSB header at %p\n", p);
+			psb = (struct psb_s *) p;
+			dprintk (KERN_INFO PFX "Table version: 0x%x\n", psb->tableversion);
+			if (psb->tableversion != 0x12) {
+				printk (KERN_INFO PFX "Sorry, only v1.2 tables supported right now\n");
+				return -ENODEV;
+			}
+
+			dprintk (KERN_INFO PFX "Flags: 0x%x (", psb->flags);
+			if ((psb->flags & 1)==0) {
+				dprintk ("Mobile");
+			} else {
+				dprintk ("Desktop");
+			}
+			dprintk (" voltage regulator)\n");
+
+			latency = psb->settlingtime;
+			dprintk (KERN_INFO PFX "Settling Time: %d microseconds.\n", psb->settlingtime);
+			dprintk (KERN_INFO PFX "Has %d PST tables. (Only dumping ones relevant to this CPU).\n", psb->numpst);
+
+			p += sizeof (struct psb_s);
+
+			pst = (struct pst_s *) p;
+
+			for (i = 0 ; i <psb->numpst; i++) {
+				pst = (struct pst_s *) p;
+				number_scales = pst->numpstates;
+
+				if ((etuple == pst->cpuid) && (maxfid==pst->maxfid) && (startvid==pst->startvid))
+				{
+					dprintk (KERN_INFO PFX "PST:%d (@%p)\n", i, pst);
+					dprintk (KERN_INFO PFX " cpuid: 0x%x\t", pst->cpuid);
+					dprintk ("fsb: %d\t", pst->fsbspeed);
+					dprintk ("maxFID: 0x%x\t", pst->maxfid);
+					dprintk ("startvid: 0x%x\n", pst->startvid);
+
+					fsb = pst->fsbspeed;
+					ret = get_ranges ((char *) pst + sizeof (struct pst_s));
+					return ret;
+
+				} else {
+					p = (char *) pst + sizeof (struct pst_s);
+					for (j=0 ; j < number_scales; j++)
+						p+=2;
+				}
+			}
+			return -EINVAL;
+		}
+		p++;
+	}
+
+	return -ENODEV;
+}
+
+
+static int powernow_target (struct cpufreq_policy *policy,
+			    unsigned int target_freq,
+			    unsigned int relation)
+{
+	unsigned int newstate;
+
+	if (cpufreq_frequency_table_target(policy, powernow_table, target_freq, relation, &newstate))
+		return -EINVAL;
+
+	change_speed(newstate);
+
+	return 0;
+}
+
+
+static int powernow_verify (struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, powernow_table);
+}
+
+
+static int __init powernow_cpu_init (struct cpufreq_policy *policy)
+{
+	union msr_fidvidstatus fidvidstatus;
+	int result;
+
+	if (policy->cpu != 0)
+		return -ENODEV;
+
+	rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
+
+	result = powernow_decode_bios(fidvidstatus.bits.MFID, fidvidstatus.bits.SVID);
+	if (result)
+		return result;
+
+	printk (KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n",
+				minimum_speed, maximum_speed);
+
+	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+	policy->cpuinfo.transition_latency = latency;
+#ifdef CONFIG_CPU_FREQ_24_API
+	powernow_driver.cpu_cur_freq[policy->cpu] = maximum_speed;
+#endif
+
+	return cpufreq_frequency_table_cpuinfo(policy, powernow_table);
+}
+
+static int __init powernow_init (void)
+{
+	if (check_powernow()==0)
+		return -ENODEV;
+	return cpufreq_register_driver(&powernow_driver);
+}
+
+
+static void __exit powernow_exit (void)
+{
+	cpufreq_unregister_driver(&powernow_driver);
+	if (powernow_table)
+		kfree(powernow_table);
+}
+
+static struct cpufreq_driver powernow_driver = {
+	.verify 	= powernow_verify,
+	.target 	= powernow_target,
+	.init		= powernow_cpu_init,
+	.name		= "powernow-k7",
+};
+
+
+MODULE_AUTHOR ("Dave Jones <davej@suse.de>");
+MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
+MODULE_LICENSE ("GPL");
+
+module_init(powernow_init);
+module_exit(powernow_exit);
+
diff -Nru a/arch/i386/kernel/cpu/cpufreq/powernow-k7.h b/arch/i386/kernel/cpu/cpufreq/powernow-k7.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.h	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,52 @@
+/*
+ *  $Id: powernow-k7.h,v 1.2 2003/02/10 18:26:01 davej Exp $
+ *  (C) 2003 Dave Jones.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  AMD-specific information
+ *
+ */
+
+#ifndef MSR_K7_FID_VID_CTL
+#define MSR_K7_FID_VID_CTL		0xc0010041
+#endif
+#ifndef MSR_K7_FID_VID_STATUS
+#define MSR_K7_FID_VID_STATUS	0xc0010042
+#endif
+
+
+union msr_fidvidctl {
+	struct {
+		unsigned FID:5,			// 4:0
+		reserved1:3,	// 7:5
+		VID:5,			// 12:8
+		reserved2:3,	// 15:13
+		FIDC:1,			// 16
+		VIDC:1,			// 17
+		reserved3:2,	// 19:18
+		FIDCHGRATIO:1,	// 20
+		reserved4:11,	// 31-21
+		SGTC:20,		// 32:51
+		reserved5:12;	// 63:52
+	} bits;
+	unsigned long long val;
+};
+
+union msr_fidvidstatus {
+	struct {
+		unsigned CFID:5,			// 4:0
+		reserved1:3,	// 7:5
+		SFID:5,			// 12:8
+		reserved2:3,	// 15:13
+		MFID:5,			// 20:16
+		reserved3:11,	// 31:21
+		CVID:5,			// 36:32
+		reserved4:3,	// 39:37
+		SVID:5,			// 44:40
+		reserved5:3,	// 47:45
+		MVID:5,			// 52:48
+		reserved6:11;	// 63:53
+	} bits;
+	unsigned long long val;
+};
diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep.c b/arch/i386/kernel/cpu/cpufreq/speedstep.c
--- a/arch/i386/kernel/cpu/cpufreq/speedstep.c	Fri Feb 14 15:53:08 2003
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep.c	Fri Feb 14 15:53:08 2003
@@ -674,6 +674,8 @@
 			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
 	if (!driver)
 		return -ENOMEM;
+	memset(driver, 0, sizeof(struct cpufreq_driver) +
+			NR_CPUS * sizeof(struct cpufreq_policy));
 
 	driver->policy = (struct cpufreq_policy *) (driver + 1);
 
@@ -690,8 +692,6 @@
 
 	driver->verify      = &speedstep_verify;
 	driver->setpolicy   = &speedstep_setpolicy;
-	driver->init = NULL;
-	driver->exit = NULL;
 	strncpy(driver->name, "speedstep", CPUFREQ_NAME_LEN);
 
 	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;
diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/kernel/io_apic.c	Fri Feb 14 15:53:09 2003
@@ -510,9 +510,8 @@
 	int i;
 	unsigned long prev_balance_time = jiffies;
 	long time_remaining = balanced_irq_interval;
-	daemonize();
-	sigfillset(&current->blocked);
-	sprintf(current->comm, "kirqd");
+
+	daemonize("kirqd");
 	
 	/* push everything to CPU 0 to give us a starting point.  */
 	for (i = 0 ; i < NR_IRQS ; i++)
@@ -1440,7 +1439,8 @@
  * by Matt Domsch <Matt_Domsch@dell.com>  Tue Dec 21 12:25:05 CST 1999
  */
 
-static void __init setup_ioapic_ids_from_mpc (void)
+#ifndef CONFIG_X86_NUMAQ
+static void __init setup_ioapic_ids_from_mpc(void)
 {
 	struct IO_APIC_reg_00 reg_00;
 	unsigned long phys_id_present_map;
@@ -1533,6 +1533,9 @@
 			printk(" ok.\n");
 	}
 }
+#else
+static void __init setup_ioapic_ids_from_mpc(void) { }
+#endif
 
 /*
  * There is a nasty bug in some older SMP boards, their mptable lies
diff -Nru a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
--- a/arch/i386/kernel/nmi.c	Fri Feb 14 15:53:10 2003
+++ b/arch/i386/kernel/nmi.c	Fri Feb 14 15:53:10 2003
@@ -63,8 +63,6 @@
    CRU_ESCR0 (with any non-null event selector) through a complemented
    max threshold. [IA32-Vol3, Section 14.9.9] */
 #define MSR_P4_IQ_COUNTER0	0x30C
-#define MSR_P4_IQ_CCCR0		0x36C
-#define MSR_P4_CRU_ESCR0	0x3B8
 #define P4_NMI_CRU_ESCR0	(P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR)
 #define P4_NMI_IQ_CCCR0	\
 	(P4_CCCR_OVF_PMI|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT|	\
diff -Nru a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
--- a/arch/i386/kernel/ptrace.c	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/kernel/ptrace.c	Fri Feb 14 15:53:09 2003
@@ -530,11 +530,9 @@
 		return;
 	/* the 0x80 provides a way for the tracing parent to distinguish
 	   between a syscall stop and SIGTRAP delivery */
-	current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-					? 0x80 : 0);
-	current->state = TASK_STOPPED;
-	notify_parent(current, SIGCHLD);
-	schedule();
+	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+				 ? 0x80 : 0));
+
 	/*
 	 * this isn't the same as continuing with a signal, but it will do
 	 * for normal use.  strace only continues with a signal if the
diff -Nru a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
--- a/arch/i386/kernel/signal.c	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/kernel/signal.c	Fri Feb 14 15:53:09 2003
@@ -582,7 +582,7 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		/* Reenable any watchpoints before delivering the
 		 * signal to user space. The processor register will
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/kernel/smpboot.c	Fri Feb 14 15:53:09 2003
@@ -160,7 +160,6 @@
 				goto valid_k7;
 
 		/* If we get here, it's not a certified SMP capable AMD system. */
-		printk (KERN_INFO "WARNING: This combination of AMD processors is not suitable for SMP.\n");
 		tainted |= TAINT_UNSAFE_SMP;
 	}
 
@@ -182,8 +181,6 @@
 
 #define NR_LOOPS 5
 
-extern unsigned long fast_gettimeoffset_quotient;
-
 /*
  * accurate 64-bit/32-bit division, expanded to 32-bit divisions and 64-bit
  * multiplication. Not terribly optimized but we need it at boot time only
@@ -223,7 +220,8 @@
 
 	printk("checking TSC synchronization across %u CPUs: ", num_booting_cpus());
 
-	one_usec = ((1<<30)/fast_gettimeoffset_quotient)*(1<<2);
+	/* convert from kcyc/sec to cyc/usec */
+	one_usec = cpu_khz / 1000;
 
 	atomic_set(&tsc_start_flag, 1);
 	wmb();
@@ -935,10 +933,6 @@
  * Cycle through the processors sending APIC IPIs to boot each.
  */
 
-extern int prof_multiplier[NR_CPUS];
-extern int prof_old_multiplier[NR_CPUS];
-extern int prof_counter[NR_CPUS];
-
 static int boot_cpu_logical_apicid;
 /* Where the IO area was mapped on multiquad, always 0 otherwise */
 void *xquad_portio;
@@ -950,17 +944,6 @@
 	int apicid, cpu, bit;
 
 	/*
-	 * Initialize the logical to physical CPU number mapping
-	 * and the per-CPU profiling counter/multiplier
-	 */
-
-	for (cpu = 0; cpu < NR_CPUS; cpu++) {
-		prof_counter[cpu] = 1;
-		prof_old_multiplier[cpu] = 1;
-		prof_multiplier[cpu] = 1;
-	}
-
-	/*
 	 * Setup boot CPU information
 	 */
 	smp_store_cpu_info(0); /* Final full version of the data */
@@ -1084,6 +1067,15 @@
 
 	if (smp_b_stepping)
 		printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n");
+
+	/* Don't taint if we are running SMP kernel on a single non-MP approved Athlon  */
+	if (tainted & TAINT_UNSAFE_SMP) {
+		if (cpucount)
+			printk (KERN_INFO "WARNING: This combination of AMD processors is not suitable for SMP.\n");
+		else
+			tainted &= ~TAINT_UNSAFE_SMP;
+	}
+
 	Dprintk("Boot done.\n");
 
 	/*
diff -Nru a/arch/i386/kernel/suspend.c b/arch/i386/kernel/suspend.c
--- a/arch/i386/kernel/suspend.c	Fri Feb 14 15:53:12 2003
+++ b/arch/i386/kernel/suspend.c	Fri Feb 14 15:53:12 2003
@@ -32,6 +32,8 @@
 unsigned long saved_context_esp, saved_context_ebp, saved_context_esi, saved_context_edi;
 unsigned long saved_context_eflags;
 
+extern void enable_sep_cpu(void *);
+
 void save_processor_state(void)
 {
 	kernel_fpu_begin();
@@ -95,6 +97,12 @@
 	asm volatile ("lgdt %0" :: "m" (saved_context.gdt_limit));
 	asm volatile ("lidt %0" :: "m" (saved_context.idt_limit));
 	asm volatile ("lldt %0" :: "m" (saved_context.ldt));
+
+	/*
+	 * sysenter MSRs
+	 */
+	if (boot_cpu_has(X86_FEATURE_SEP))
+		enable_sep_cpu(NULL);
 
 	fix_processor_context();
 	do_fpu_end();
diff -Nru a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c
--- a/arch/i386/kernel/sysenter.c	Fri Feb 14 15:53:12 2003
+++ b/arch/i386/kernel/sysenter.c	Fri Feb 14 15:53:12 2003
@@ -35,7 +35,7 @@
 	unsigned char stack[0];
 } __attribute__((aligned(8192)));
 	
-static void __init enable_sep_cpu(void *info)
+void enable_sep_cpu(void *info)
 {
 	int cpu = get_cpu();
 	struct tss_struct *tss = init_tss + cpu;
diff -Nru a/arch/i386/kernel/timers/Makefile b/arch/i386/kernel/timers/Makefile
--- a/arch/i386/kernel/timers/Makefile	Fri Feb 14 15:53:08 2003
+++ b/arch/i386/kernel/timers/Makefile	Fri Feb 14 15:53:08 2003
@@ -4,4 +4,4 @@
 
 obj-y := timer.o timer_none.o timer_tsc.o timer_pit.o
 
-obj-$(CONFIG_X86_CYCLONE)	+= timer_cyclone.o
+obj-$(CONFIG_X86_SUMMIT)	+= timer_cyclone.o
diff -Nru a/arch/i386/kernel/timers/timer.c b/arch/i386/kernel/timers/timer.c
--- a/arch/i386/kernel/timers/timer.c	Fri Feb 14 15:53:12 2003
+++ b/arch/i386/kernel/timers/timer.c	Fri Feb 14 15:53:12 2003
@@ -4,9 +4,14 @@
 /* list of externed timers */
 extern struct timer_opts timer_pit;
 extern struct timer_opts timer_tsc;
-
+#ifdef CONFIG_X86_SUMMIT
+extern struct timer_opts timer_cyclone;
+#endif
 /* list of timers, ordered by preference, NULL terminated */
 static struct timer_opts* timers[] = {
+#ifdef CONFIG_X86_SUMMIT
+	&timer_cyclone,
+#endif
 	&timer_tsc,
 	&timer_pit,
 	NULL,
diff -Nru a/arch/i386/kernel/timers/timer_cyclone.c b/arch/i386/kernel/timers/timer_cyclone.c
--- a/arch/i386/kernel/timers/timer_cyclone.c	Fri Feb 14 15:53:12 2003
+++ b/arch/i386/kernel/timers/timer_cyclone.c	Fri Feb 14 15:53:12 2003
@@ -17,6 +17,7 @@
 #include <asm/fixmap.h>
 
 extern spinlock_t i8253_lock;
+extern unsigned long calibrate_tsc(void);
 
 /* Number of usecs that the last interrupt was delayed */
 static int delay_at_last_interrupt;
@@ -142,6 +143,27 @@
 			printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n");
 			cyclone_timer = 0;
 			return -ENODEV;
+		}
+	}
+
+	/* init cpu_khz.
+	 * XXX - This should really be done elsewhere, 
+	 * 		and in a more generic fashion. -johnstul@us.ibm.com
+	 */
+	if (cpu_has_tsc) {
+		unsigned long tsc_quotient = calibrate_tsc();
+		if (tsc_quotient) {
+			/* report CPU clock rate in Hz.
+			 * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
+			 * clock/second. Our precision is about 100 ppm.
+			 */
+			{	unsigned long eax=0, edx=1000;
+				__asm__("divl %2"
+		       		:"=a" (cpu_khz), "=d" (edx)
+        	       		:"r" (tsc_quotient),
+	                	"0" (eax), "1" (edx));
+				printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000);
+			}
 		}
 	}
 
diff -Nru a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
--- a/arch/i386/kernel/timers/timer_tsc.c	Fri Feb 14 15:53:11 2003
+++ b/arch/i386/kernel/timers/timer_tsc.c	Fri Feb 14 15:53:11 2003
@@ -29,7 +29,7 @@
  * Equal to 2^32 * (1 / (clocks per usec) ).
  * Initialized in time_init.
  */
-unsigned long fast_gettimeoffset_quotient;
+static unsigned long fast_gettimeoffset_quotient;
 
 static unsigned long get_offset_tsc(void)
 {
@@ -130,7 +130,7 @@
 #define CALIBRATE_LATCH	(5 * LATCH)
 #define CALIBRATE_TIME	(5 * 1000020/HZ)
 
-static unsigned long __init calibrate_tsc(void)
+unsigned long __init calibrate_tsc(void)
 {
        /* Set the Gate high, disable speaker */
 	outb((inb(0x61) & ~0x02) | 0x01, 0x61);
diff -Nru a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
--- a/arch/i386/mach-voyager/voyager_smp.c	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/mach-voyager/voyager_smp.c	Fri Feb 14 15:53:09 2003
@@ -236,7 +236,7 @@
 /* The per cpu profile stuff - used in smp_local_timer_interrupt */
 static unsigned int prof_multiplier[NR_CPUS] __cacheline_aligned = { 1, };
 static unsigned int prof_old_multiplier[NR_CPUS] __cacheline_aligned = { 1, };
-static unsigned int prof_counter[NR_CPUS] __cacheline_aligned = { 1, };
+static DEFINE_PER_CPU(unsigned int, prof_counter) =  1;
 
 /* the map used to check if a CPU has booted */
 static __u32 cpu_booted_map;
@@ -393,9 +393,6 @@
 
 	/* initialize the CPU structures (moved from smp_boot_cpus) */
 	for(i=0; i<NR_CPUS; i++) {
-		prof_counter[i] = 1;
-		prof_old_multiplier[i] = 1;
-		prof_multiplier[i] = 1;
 		cpu_irq_affinity[i] = ~0;
 	}
 	cpu_online_map = (1<<boot_cpu_id);
@@ -1312,7 +1309,7 @@
 
 	x86_do_profile(regs);
 
-	if (--prof_counter[cpu] <= 0) {
+	if (--per_cpu(prof_counter, cpu) <= 0) {
 		/*
 		 * The multiplier may have changed since the last time we got
 		 * to this point as a result of the user writing to
@@ -1321,10 +1318,10 @@
 		 *
 		 * Interrupts are already masked off at this point.
 		 */
-		prof_counter[cpu] = prof_multiplier[cpu];
-		if (prof_counter[cpu] != prof_old_multiplier[cpu]) {
+		per_cpu(prof_counter,cpu) = prof_multiplier[cpu];
+		if (per_cpu(prof_counter, cpu) != prof_old_multiplier[cpu]) {
 			/* FIXME: need to update the vic timer tick here */
-			prof_old_multiplier[cpu] = prof_counter[cpu];
+			prof_old_multiplier[cpu] = per_cpu(prof_counter, cpu);
 		}
 
 		update_process_times(user_mode(regs));
diff -Nru a/arch/i386/mach-voyager/voyager_thread.c b/arch/i386/mach-voyager/voyager_thread.c
--- a/arch/i386/mach-voyager/voyager_thread.c	Fri Feb 14 15:53:11 2003
+++ b/arch/i386/mach-voyager/voyager_thread.c	Fri Feb 14 15:53:11 2003
@@ -137,13 +137,12 @@
 	kvoyagerd_running = 1;
 
 	reparent_to_init();
-	daemonize();
+	daemonize(THREAD_NAME);
 
 	set_timeout = 0;
 
 	init_timer(&wakeup_timer);
 
-	strcpy(current->comm, THREAD_NAME);
 	sigfillset(&current->blocked);
 	current->tty = NULL;	/* get rid of controlling tty */
 
diff -Nru a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c
--- a/arch/i386/mm/hugetlbpage.c	Fri Feb 14 15:53:12 2003
+++ b/arch/i386/mm/hugetlbpage.c	Fri Feb 14 15:53:12 2003
@@ -88,6 +88,18 @@
 	set_pte(page_table, entry);
 }
 
+/*
+ * This function checks for proper alignment of input addr and len parameters.
+ */
+int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
+{
+	if (len & ~HPAGE_MASK)
+		return -EINVAL;
+	if (addr & ~HPAGE_MASK)
+		return -EINVAL;
+	return 0;
+}
+
 int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			struct vm_area_struct *vma)
 {
@@ -284,7 +296,6 @@
 int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
 {
 	struct mm_struct *mm = current->mm;
-	struct inode *inode = mapping->host;
 	unsigned long addr;
 	int ret = 0;
 
@@ -308,7 +319,6 @@
 			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
 		page = find_get_page(mapping, idx);
 		if (!page) {
-			loff_t i_size;
 			page = alloc_hugetlb_page();
 			if (!page) {
 				ret = -ENOMEM;
@@ -320,9 +330,6 @@
 				free_huge_page(page);
 				goto out;
 			}
-			i_size = (loff_t)(idx + 1) * HPAGE_SIZE;
-			if (i_size > inode->i_size)
-				inode->i_size = i_size;
 		}
 		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
 	}
diff -Nru a/arch/i386/oprofile/Makefile b/arch/i386/oprofile/Makefile
--- a/arch/i386/oprofile/Makefile	Fri Feb 14 15:53:12 2003
+++ b/arch/i386/oprofile/Makefile	Fri Feb 14 15:53:12 2003
@@ -7,4 +7,4 @@
 
 oprofile-y				:= $(DRIVER_OBJS) init.o timer_int.o
 oprofile-$(CONFIG_X86_LOCAL_APIC) 	+= nmi_int.o op_model_athlon.o \
-					   op_model_ppro.o
+					   op_model_ppro.o op_model_p4.o
diff -Nru a/arch/i386/oprofile/init.c b/arch/i386/oprofile/init.c
--- a/arch/i386/oprofile/init.c	Fri Feb 14 15:53:10 2003
+++ b/arch/i386/oprofile/init.c	Fri Feb 14 15:53:10 2003
@@ -16,14 +16,14 @@
  * code unlike the NMI-based code.
  */
  
-extern int nmi_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu);
-extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu);
+extern int nmi_init(struct oprofile_operations ** ops);
+extern void timer_init(struct oprofile_operations ** ops);
 
-int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+int __init oprofile_arch_init(struct oprofile_operations ** ops)
 {
 #ifdef CONFIG_X86_LOCAL_APIC
-	if (!nmi_init(ops, cpu))
+	if (!nmi_init(ops))
 #endif
-		timer_init(ops, cpu);
+		timer_init(ops);
 	return 0;
 }
diff -Nru a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
--- a/arch/i386/oprofile/nmi_int.c	Fri Feb 14 15:53:12 2003
+++ b/arch/i386/oprofile/nmi_int.c	Fri Feb 14 15:53:12 2003
@@ -214,12 +214,62 @@
 	.stop		= nmi_stop
 };
  
+
+#if !defined(CONFIG_X86_64)
+
+static int __init p4_init(void)
+{
+	__u8 cpu_model = current_cpu_data.x86_model;
+
+	if (cpu_model > 3)
+		return 0;
+
+#ifndef CONFIG_SMP
+	nmi_ops.cpu_type = "i386/p4";
+	model = &op_p4_spec;
+	return 1;
+#else
+	switch (smp_num_siblings) {
+		case 1:
+			nmi_ops.cpu_type = "i386/p4";
+			model = &op_p4_spec;
+			return 1;
+
+		case 2:
+			nmi_ops.cpu_type = "i386/p4-ht";
+			model = &op_p4_ht2_spec;
+			return 1;
+	}
+#endif
+
+	printk(KERN_INFO "oprofile: P4 HyperThreading detected with > 2 threads\n");
+	printk(KERN_INFO "oprofile: Reverting to timer mode.\n");
+	return 0;
+}
+
+
+static int __init ppro_init(void)
+{
+	__u8 cpu_model = current_cpu_data.x86_model;
+
+	if (cpu_model > 5) {
+		nmi_ops.cpu_type = "i386/piii";
+	} else if (cpu_model > 2) {
+		nmi_ops.cpu_type = "i386/pii";
+	} else {
+		nmi_ops.cpu_type = "i386/ppro";
+	}
+
+	model = &op_ppro_spec;
+	return 1;
+}
+
+#endif /* !CONFIG_X86_64 */
  
-int __init nmi_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+int __init nmi_init(struct oprofile_operations ** ops)
 {
 	__u8 vendor = current_cpu_data.x86_vendor;
 	__u8 family = current_cpu_data.x86;
-	__u8 cpu_model = current_cpu_data.x86_model;
  
 	if (!cpu_has_apic)
 		return 0;
@@ -230,26 +280,29 @@
 			if (family < 6)
 				return 0;
 			model = &op_athlon_spec;
-			*cpu = OPROFILE_CPU_ATHLON;
+			nmi_ops.cpu_type = "i386/athlon";
 			break;
  
-#ifndef CONFIG_X86_64
+#if !defined(CONFIG_X86_64)
 		case X86_VENDOR_INTEL:
-			/* Less than a P6-class processor */
-			if (family != 6)
-				return 0;
-	 
-			if (cpu_model > 5) {
-				*cpu = OPROFILE_CPU_PIII;
-			} else if (cpu_model > 2) {
-				*cpu = OPROFILE_CPU_PII;
-			} else {
-				*cpu = OPROFILE_CPU_PPRO;
+			switch (family) {
+				/* Pentium IV */
+				case 0xf:
+					if (!p4_init())
+						return 0;
+					break;
+
+				/* A P6-class processor */
+				case 6:
+					if (!ppro_init())
+						return 0;
+					break;
+
+				default:
+					return 0;
 			}
- 
-			model = &op_ppro_spec;
 			break;
-#endif
+#endif /* !CONFIG_X86_64 */
 
 		default:
 			return 0;
diff -Nru a/arch/i386/oprofile/op_counter.h b/arch/i386/oprofile/op_counter.h
--- a/arch/i386/oprofile/op_counter.h	Fri Feb 14 15:53:10 2003
+++ b/arch/i386/oprofile/op_counter.h	Fri Feb 14 15:53:10 2003
@@ -10,7 +10,7 @@
 #ifndef OP_COUNTER_H
 #define OP_COUNTER_H
  
-#define OP_MAX_COUNTER 4
+#define OP_MAX_COUNTER 8
  
 /* Per-perfctr configuration as set via
  * oprofilefs.
diff -Nru a/arch/i386/oprofile/op_model_athlon.c b/arch/i386/oprofile/op_model_athlon.c
--- a/arch/i386/oprofile/op_model_athlon.c	Fri Feb 14 15:53:12 2003
+++ b/arch/i386/oprofile/op_model_athlon.c	Fri Feb 14 15:53:12 2003
@@ -96,10 +96,13 @@
 {
 	unsigned int low, high;
 	int i;
+	unsigned long eip = instruction_pointer(regs);
+	int is_kernel = !user_mode(regs);
+
 	for (i = 0 ; i < NUM_COUNTERS; ++i) {
 		CTR_READ(low, high, msrs, i);
 		if (CTR_OVERFLOWED(low)) {
-			oprofile_add_sample(instruction_pointer(regs), i, cpu);
+			oprofile_add_sample(eip, is_kernel, i, cpu);
 			CTR_WRITE(reset_value[i], msrs, i);
 			return 1;
 		}
diff -Nru a/arch/i386/oprofile/op_model_p4.c b/arch/i386/oprofile/op_model_p4.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/oprofile/op_model_p4.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,673 @@
+/**
+ * @file op_model_p4.c
+ * P4 model-specific MSR operations
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author Graydon Hoare
+ */
+
+#include <linux/oprofile.h>
+#include <linux/smp.h>
+#include <asm/msr.h>
+#include <asm/ptrace.h>
+#include <asm/fixmap.h>
+#include <asm/apic.h>
+
+#include "op_x86_model.h"
+#include "op_counter.h"
+
+#define NUM_EVENTS 39
+
+#define NUM_COUNTERS_NON_HT 8
+#define NUM_ESCRS_NON_HT 45
+#define NUM_CCCRS_NON_HT 18
+#define NUM_CONTROLS_NON_HT (NUM_ESCRS_NON_HT + NUM_CCCRS_NON_HT)
+
+#define NUM_COUNTERS_HT2 4
+#define NUM_ESCRS_HT2 23
+#define NUM_CCCRS_HT2 9
+#define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2)
+
+static unsigned int num_counters = NUM_COUNTERS_NON_HT;
+static unsigned int num_cccrs = NUM_CCCRS_NON_HT;
+
+
+/* this has to be checked dynamically since the
+   hyper-threadedness of a chip is discovered at
+   kernel boot-time. */
+static inline void setup_num_counters(void)
+{
+#ifdef CONFIG_SMP
+	if (smp_num_siblings == 2) {		
+		num_counters = NUM_COUNTERS_HT2;
+		num_cccrs = NUM_CCCRS_HT2;
+	}
+#endif
+}
+
+
+/* tables to simulate simplified hardware view of p4 registers */
+struct p4_counter_binding {
+	int virt_counter;
+	int counter_address;
+	int cccr_address;
+};
+
+struct p4_event_binding {
+	int escr_select;  /* value to put in CCCR */
+	int event_select; /* value to put in ESCR */
+	struct {
+		int virt_counter; /* for this counter... */
+		int escr_address; /* use this ESCR       */
+	} bindings[2];
+};
+
+/* nb: these CTR_* defines are a duplicate of defines in
+   libop/op_events.c. */
+
+
+#define CTR_BPU_0      (1 << 0)
+#define CTR_MS_0       (1 << 1)
+#define CTR_FLAME_0    (1 << 2)
+#define CTR_IQ_4       (1 << 3)
+#define CTR_BPU_2      (1 << 4)
+#define CTR_MS_2       (1 << 5)
+#define CTR_FLAME_2    (1 << 6)
+#define CTR_IQ_5       (1 << 7)
+
+static struct p4_counter_binding p4_counters [NUM_COUNTERS_NON_HT] = {
+	{ CTR_BPU_0,   MSR_P4_BPU_PERFCTR0,   MSR_P4_BPU_CCCR0 },
+	{ CTR_MS_0,    MSR_P4_MS_PERFCTR0,    MSR_P4_MS_CCCR0 },
+	{ CTR_FLAME_0, MSR_P4_FLAME_PERFCTR0, MSR_P4_FLAME_CCCR0 },
+	{ CTR_IQ_4,    MSR_P4_IQ_PERFCTR4,    MSR_P4_IQ_CCCR4 },
+	{ CTR_BPU_2,   MSR_P4_BPU_PERFCTR2,   MSR_P4_BPU_CCCR2 },
+	{ CTR_MS_2,    MSR_P4_MS_PERFCTR2,    MSR_P4_MS_CCCR2 },
+	{ CTR_FLAME_2, MSR_P4_FLAME_PERFCTR2, MSR_P4_FLAME_CCCR2 },
+	{ CTR_IQ_5,    MSR_P4_IQ_PERFCTR5,    MSR_P4_IQ_CCCR5 }
+};
+
+/* p4 event codes in libop/op_event.h are indices into this table. */
+
+static struct p4_event_binding p4_events[NUM_EVENTS] = {
+	
+	{ /* BRANCH_RETIRED */
+		0x05, 0x06, 
+		{ {CTR_IQ_4, MSR_P4_CRU_ESCR2},
+		  {CTR_IQ_5, MSR_P4_CRU_ESCR3} }
+	},
+	
+	{ /* MISPRED_BRANCH_RETIRED */
+		0x04, 0x03, 
+		{ { CTR_IQ_4, MSR_P4_CRU_ESCR0},
+		  { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
+	},
+	
+	{ /* TC_DELIVER_MODE */
+		0x01, 0x01,
+		{ { CTR_MS_0, MSR_P4_TC_ESCR0},  
+		  { CTR_MS_2, MSR_P4_TC_ESCR1} }
+	},
+	
+	{ /* BPU_FETCH_REQUEST */
+		0x00, 0x03, 
+		{ { CTR_BPU_0, MSR_P4_BPU_ESCR0},
+		  { CTR_BPU_2, MSR_P4_BPU_ESCR1} }
+	},
+
+	{ /* ITLB_REFERENCE */
+		0x03, 0x18,
+		{ { CTR_BPU_0, MSR_P4_ITLB_ESCR0},
+		  { CTR_BPU_2, MSR_P4_ITLB_ESCR1} }
+	},
+
+	{ /* MEMORY_CANCEL */
+		0x05, 0x02,
+		{ { CTR_FLAME_0, MSR_P4_DAC_ESCR0},
+		  { CTR_FLAME_2, MSR_P4_DAC_ESCR1} }
+	},
+
+	{ /* MEMORY_COMPLETE */
+		0x02, 0x08,
+		{ { CTR_FLAME_0, MSR_P4_SAAT_ESCR0},
+		  { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} }
+	},
+
+	{ /* LOAD_PORT_REPLAY */
+		0x02, 0x04, 
+		{ { CTR_FLAME_0, MSR_P4_SAAT_ESCR0},
+		  { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} }
+	},
+
+	{ /* STORE_PORT_REPLAY */
+		0x02, 0x05,
+		{ { CTR_FLAME_0, MSR_P4_SAAT_ESCR0},
+		  { CTR_FLAME_2, MSR_P4_SAAT_ESCR1} }
+	},
+
+	{ /* MOB_LOAD_REPLAY */
+		0x02, 0x03,
+		{ { CTR_BPU_0, MSR_P4_MOB_ESCR0},
+		  { CTR_BPU_2, MSR_P4_MOB_ESCR1} }
+	},
+
+	{ /* PAGE_WALK_TYPE */
+		0x04, 0x01,
+		{ { CTR_BPU_0, MSR_P4_PMH_ESCR0},
+		  { CTR_BPU_2, MSR_P4_PMH_ESCR1} }
+	},
+
+	{ /* BSQ_CACHE_REFERENCE */
+		0x07, 0x0c, 
+		{ { CTR_BPU_0, MSR_P4_BSU_ESCR0},
+		  { CTR_BPU_2, MSR_P4_BSU_ESCR1} }
+	},
+
+	{ /* IOQ_ALLOCATION */
+		0x06, 0x03, 
+		{ { CTR_BPU_0, MSR_P4_FSB_ESCR0},
+		  {-1,-1} }
+	},
+
+	{ /* IOQ_ACTIVE_ENTRIES */
+		0x06, 0x1a, 
+		{ { CTR_BPU_2, MSR_P4_FSB_ESCR1},
+		  {-1,-1} }
+	},
+
+	{ /* FSB_DATA_ACTIVITY */
+		0x06, 0x17, 
+		{ { CTR_BPU_0, MSR_P4_FSB_ESCR0},
+		  { CTR_BPU_2, MSR_P4_FSB_ESCR1} }
+	},
+
+	{ /* BSQ_ALLOCATION */
+		0x07, 0x05, 
+		{ { CTR_BPU_0, MSR_P4_BSU_ESCR0},
+		  {-1,-1} }
+	},
+
+	{ /* BSQ_ACTIVE_ENTRIES */
+		0x07, 0x06,
+		{ { CTR_BPU_2, MSR_P4_BSU_ESCR1 /* guess */},  
+		  {-1,-1} }
+	},
+
+	{ /* X87_ASSIST */
+		0x05, 0x03, 
+		{ { CTR_IQ_4, MSR_P4_CRU_ESCR2},
+		  { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
+	},
+
+	{ /* SSE_INPUT_ASSIST */
+		0x01, 0x34,
+		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
+		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
+	},
+  
+	{ /* PACKED_SP_UOP */
+		0x01, 0x08, 
+		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
+		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
+	},
+  
+	{ /* PACKED_DP_UOP */
+		0x01, 0x0c, 
+		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
+		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
+	},
+
+	{ /* SCALAR_SP_UOP */
+		0x01, 0x0a, 
+		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
+		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
+	},
+
+	{ /* SCALAR_DP_UOP */
+		0x01, 0x0e,
+		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
+		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
+	},
+
+	{ /* 64BIT_MMX_UOP */
+		0x01, 0x02, 
+		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
+		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
+	},
+  
+	{ /* 128BIT_MMX_UOP */
+		0x01, 0x1a, 
+		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
+		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
+	},
+
+	{ /* X87_FP_UOP */
+		0x01, 0x04, 
+		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
+		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
+	},
+  
+	{ /* X87_SIMD_MOVES_UOP */
+		0x01, 0x2e, 
+		{ { CTR_FLAME_0, MSR_P4_FIRM_ESCR0},
+		  { CTR_FLAME_2, MSR_P4_FIRM_ESCR1} }
+	},
+  
+	{ /* MACHINE_CLEAR */
+		0x05, 0x02, 
+		{ { CTR_IQ_4, MSR_P4_CRU_ESCR2},
+		  { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
+	},
+
+	{ /* GLOBAL_POWER_EVENTS */
+		0x06, 0x13 /* manual says 0x05 */, 
+		{ { CTR_BPU_0, MSR_P4_FSB_ESCR0},
+		  { CTR_BPU_2, MSR_P4_FSB_ESCR1} }
+	},
+  
+	{ /* TC_MS_XFER */
+		0x00, 0x05, 
+		{ { CTR_MS_0, MSR_P4_MS_ESCR0},
+		  { CTR_MS_2, MSR_P4_MS_ESCR1} }
+	},
+
+	{ /* UOP_QUEUE_WRITES */
+		0x00, 0x09,
+		{ { CTR_MS_0, MSR_P4_MS_ESCR0},
+		  { CTR_MS_2, MSR_P4_MS_ESCR1} }
+	},
+
+	{ /* FRONT_END_EVENT */
+		0x05, 0x08,
+		{ { CTR_IQ_4, MSR_P4_CRU_ESCR2},
+		  { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
+	},
+
+	{ /* EXECUTION_EVENT */
+		0x05, 0x0c,
+		{ { CTR_IQ_4, MSR_P4_CRU_ESCR2},
+		  { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
+	},
+
+	{ /* REPLAY_EVENT */
+		0x05, 0x09,
+		{ { CTR_IQ_4, MSR_P4_CRU_ESCR2},
+		  { CTR_IQ_5, MSR_P4_CRU_ESCR3} }
+	},
+
+	{ /* INSTR_RETIRED */
+		0x04, 0x02, 
+		{ { CTR_IQ_4, MSR_P4_CRU_ESCR0},
+		  { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
+	},
+
+	{ /* UOPS_RETIRED */
+		0x04, 0x01,
+		{ { CTR_IQ_4, MSR_P4_CRU_ESCR0},
+		  { CTR_IQ_5, MSR_P4_CRU_ESCR1} }
+	},
+
+	{ /* UOP_TYPE */    
+		0x02, 0x02, 
+		{ { CTR_IQ_4, MSR_P4_RAT_ESCR0},
+		  { CTR_IQ_5, MSR_P4_RAT_ESCR1} }
+	},
+
+	{ /* RETIRED_MISPRED_BRANCH_TYPE */
+		0x02, 0x05, 
+		{ { CTR_MS_0, MSR_P4_TBPU_ESCR0},
+		  { CTR_MS_2, MSR_P4_TBPU_ESCR1} }
+	},
+
+	{ /* RETIRED_BRANCH_TYPE */
+		0x02, 0x04,
+		{ { CTR_MS_0, MSR_P4_TBPU_ESCR0},
+		  { CTR_MS_2, MSR_P4_TBPU_ESCR1} }
+	}
+};
+
+
+#define MISC_PMC_ENABLED_P(x) ((x) & 1 << 7)
+
+#define ESCR_RESERVED_BITS 0x80000003
+#define ESCR_CLEAR(escr) ((escr) &= ESCR_RESERVED_BITS)
+#define ESCR_SET_USR_0(escr, usr) ((escr) |= (((usr) & 1) << 2))
+#define ESCR_SET_OS_0(escr, os) ((escr) |= (((os) & 1) << 3))
+#define ESCR_SET_USR_1(escr, usr) ((escr) |= (((usr) & 1)))
+#define ESCR_SET_OS_1(escr, os) ((escr) |= (((os) & 1) << 1))
+#define ESCR_SET_EVENT_SELECT(escr, sel) ((escr) |= (((sel) & 0x1f) << 25))
+#define ESCR_SET_EVENT_MASK(escr, mask) ((escr) |= (((mask) & 0xffff) << 9))
+#define ESCR_READ(escr,high,ev,i) do {rdmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0);
+#define ESCR_WRITE(escr,high,ev,i) do {wrmsr(ev->bindings[(i)].escr_address, (escr), (high));} while (0);
+
+#define CCCR_RESERVED_BITS 0x38030FFF
+#define CCCR_CLEAR(cccr) ((cccr) &= CCCR_RESERVED_BITS)
+#define CCCR_SET_REQUIRED_BITS(cccr) ((cccr) |= 0x00030000)
+#define CCCR_SET_ESCR_SELECT(cccr, sel) ((cccr) |= (((sel) & 0x07) << 13))
+#define CCCR_SET_PMI_OVF_0(cccr) ((cccr) |= (1<<26))
+#define CCCR_SET_PMI_OVF_1(cccr) ((cccr) |= (1<<27))
+#define CCCR_SET_ENABLE(cccr) ((cccr) |= (1<<12))
+#define CCCR_SET_DISABLE(cccr) ((cccr) &= ~(1<<12))
+#define CCCR_READ(low, high, i) do {rdmsr (p4_counters[(i)].cccr_address, (low), (high));} while (0);
+#define CCCR_WRITE(low, high, i) do {wrmsr (p4_counters[(i)].cccr_address, (low), (high));} while (0);
+#define CCCR_OVF_P(cccr) ((cccr) & (1U<<31))
+#define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31)))
+
+#define CTR_READ(l,h,i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h));} while (0);
+#define CTR_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (0);
+#define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000))
+
+/* these access the underlying cccrs 1-18, not the subset of 8 bound to "virtual counters" */
+#define RAW_CCCR_READ(low, high, i) do {rdmsr (MSR_P4_BPU_CCCR0 + (i), (low), (high));} while (0);
+#define RAW_CCCR_WRITE(low, high, i) do {wrmsr (MSR_P4_BPU_CCCR0 + (i), (low), (high));} while (0);
+
+
+/* this assigns a "stagger" to the current CPU, which is used throughout
+   the code in this module as an extra array offset, to select the "even"
+   or "odd" part of all the divided resources. */
+static inline unsigned int get_stagger(void)
+{
+#ifdef CONFIG_SMP
+	int cpu;
+	if (smp_num_siblings > 1) {
+		cpu = smp_processor_id();
+		return (cpu_sibling_map[cpu] > cpu) ? 0 : 1;
+	}
+#endif	
+	return 0;
+}
+
+
+/* finally, mediate access to a real hardware counter
+   by passing a "virtual" counter numer to this macro,
+   along with your stagger setting. */
+#define VIRT_CTR(stagger, i) ((i) + ((num_counters) * (stagger)))
+
+static unsigned long reset_value[NUM_COUNTERS_NON_HT];
+
+
+static void p4_fill_in_addresses(struct op_msrs * const msrs)
+{
+	int i; 
+	unsigned int addr, stag;
+
+	setup_num_counters();
+	stag = get_stagger();
+
+	/* the 8 counter registers we pay attention to */
+	for (i = 0; i < num_counters; ++i)
+		msrs->counters.addrs[i] = 
+			p4_counters[VIRT_CTR(stag, i)].counter_address;
+
+	/* 18 CCCR registers */
+	for (i=stag, addr = MSR_P4_BPU_CCCR0;
+	     addr <= MSR_P4_IQ_CCCR5; ++i, addr += (1 + stag)) 
+		msrs->controls.addrs[i] = addr;
+	
+	/* 43 ESCR registers */
+	for (addr = MSR_P4_BSU_ESCR0;
+	     addr <= MSR_P4_SSU_ESCR0; ++i, addr += (1 + stag)){ 
+		msrs->controls.addrs[i] = addr;
+	}
+	
+	for (addr = MSR_P4_MS_ESCR0;
+	     addr <= MSR_P4_TC_ESCR1; ++i, addr += (1 + stag)){ 
+		msrs->controls.addrs[i] = addr;
+	}
+	
+	for (addr = MSR_P4_IX_ESCR0;
+	     addr <= MSR_P4_CRU_ESCR3; ++i, addr += (1 + stag)){ 
+		msrs->controls.addrs[i] = addr;
+	}
+
+	/* there are 2 remaining non-contiguously located ESCRs */
+
+	if (num_counters == NUM_COUNTERS_NON_HT) {		
+		/* standard non-HT CPUs handle both remaining ESCRs*/
+		msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR5;
+		msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR4;
+
+	} else if (stag == 0) {
+		/* HT CPUs give the first remainder to the even thread, as
+		   the 32nd control register */
+		msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR4;
+
+	} else {
+		/* and two copies of the second to the odd thread,
+		   for the 31st and 32nd control registers */
+		msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR5;
+		msrs->controls.addrs[i++] = MSR_P4_CRU_ESCR5;
+	}
+}
+
+
+static void pmc_setup_one_p4_counter(unsigned int ctr)
+{
+	int i;
+	int const maxbind = 2;
+	unsigned int cccr = 0;
+	unsigned int escr = 0;
+	unsigned int high = 0;
+	unsigned int counter_bit;
+	struct p4_event_binding * ev = 0;
+	unsigned int stag;
+
+	stag = get_stagger();
+	
+	/* convert from counter *number* to counter *bit* */
+	counter_bit = 1 << ctr;
+	
+	/* find our event binding structure. */
+	if (counter_config[ctr].event <= 0 || counter_config[ctr].event > NUM_EVENTS) {
+		printk(KERN_ERR 
+		       "oprofile: P4 event code 0x%lx out of range\n", 
+		       counter_config[ctr].event);
+		return;
+	}
+	
+	ev = &(p4_events[counter_config[ctr].event - 1]);
+	
+	for (i = 0; i < maxbind; i++) {
+		if (ev->bindings[i].virt_counter & counter_bit) {
+			
+			/* modify ESCR */
+			ESCR_READ(escr, high, ev, i);
+			ESCR_CLEAR(escr);
+			if (stag == 0) {
+				ESCR_SET_USR_0(escr, counter_config[ctr].user);
+				ESCR_SET_OS_0(escr, counter_config[ctr].kernel);
+			} else {
+				ESCR_SET_USR_1(escr, counter_config[ctr].user);
+				ESCR_SET_OS_1(escr, counter_config[ctr].kernel);
+			}
+			ESCR_SET_EVENT_SELECT(escr, ev->event_select);
+			ESCR_SET_EVENT_MASK(escr, counter_config[ctr].unit_mask);			
+			ESCR_WRITE(escr, high, ev, i);
+		       
+			/* modify CCCR */
+			CCCR_READ(cccr, high, VIRT_CTR(stag, ctr));
+			CCCR_CLEAR(cccr);
+			CCCR_SET_REQUIRED_BITS(cccr);
+			CCCR_SET_ESCR_SELECT(cccr, ev->escr_select);
+			if (stag == 0) {
+				CCCR_SET_PMI_OVF_0(cccr);
+			} else {
+				CCCR_SET_PMI_OVF_1(cccr);
+			}
+			CCCR_WRITE(cccr, high, VIRT_CTR(stag, ctr));
+			return;
+		}
+	}
+}
+
+
+static void p4_setup_ctrs(struct op_msrs const * const msrs)
+{
+	unsigned int i;
+	unsigned int low, high;
+	unsigned int addr;
+	unsigned int stag;
+
+	stag = get_stagger();
+
+	rdmsr(MSR_IA32_MISC_ENABLE, low, high);
+	if (! MISC_PMC_ENABLED_P(low)) {
+		printk(KERN_ERR "oprofile: P4 PMC not available\n");
+		return;
+	}
+
+	/* clear all cccrs (including those outside our concern) */
+	for (i = stag ; i < num_cccrs ; i += (1 + stag)) {
+		RAW_CCCR_READ(low, high, i);
+		CCCR_CLEAR(low);
+		CCCR_SET_REQUIRED_BITS(low);
+		RAW_CCCR_WRITE(low, high, i);
+	}
+
+	/* clear all escrs (including those outside out concern) */
+	for (addr = MSR_P4_BSU_ESCR0 + stag;
+	     addr <= MSR_P4_SSU_ESCR0; addr += (1 + stag)){ 
+		wrmsr(addr, 0, 0);
+	}
+	
+	for (addr = MSR_P4_MS_ESCR0 + stag;
+	     addr <= MSR_P4_TC_ESCR1; addr += (1 + stag)){ 
+		wrmsr(addr, 0, 0);
+	}
+	
+	for (addr = MSR_P4_IX_ESCR0 + stag;
+	     addr <= MSR_P4_CRU_ESCR3; addr += (1 + stag)){ 
+		wrmsr(addr, 0, 0);
+	}
+
+	if (num_counters == NUM_COUNTERS_NON_HT) {		
+		wrmsr(MSR_P4_CRU_ESCR4, 0, 0);
+		wrmsr(MSR_P4_CRU_ESCR5, 0, 0);
+	} else if (stag == 0) {
+		wrmsr(MSR_P4_CRU_ESCR4, 0, 0);
+	} else {
+		wrmsr(MSR_P4_CRU_ESCR5, 0, 0);
+	}		
+	
+	/* setup all counters */
+	for (i = 0 ; i < num_counters ; ++i) {
+		if (counter_config[i].event) {
+			reset_value[i] = counter_config[i].count;
+			pmc_setup_one_p4_counter(i);
+			CTR_WRITE(counter_config[i].count, VIRT_CTR(stag, i));
+		} else {
+			reset_value[i] = 0;
+		}
+	}
+}
+
+
+static int p4_check_ctrs(unsigned int const cpu, 
+			  struct op_msrs const * const msrs,
+			  struct pt_regs * const regs)
+{
+	unsigned long ctr, low, high, stag, real;
+	int i;
+	unsigned long eip = instruction_pointer(regs);
+	int is_kernel = !user_mode(regs);
+
+	stag = get_stagger();
+
+	for (i = 0; i < num_counters; ++i) {
+		
+		if (!counter_config[i].event) 
+			continue;
+
+		/* 
+		 * there is some eccentricity in the hardware which
+		 * requires that we perform 2 extra corrections:
+		 *
+		 * - check both the CCCR:OVF flag for overflow and the
+		 *   counter high bit for un-flagged overflows.
+		 *
+		 * - write the counter back twice to ensure it gets
+		 *   updated properly.
+		 * 
+		 * the former seems to be related to extra NMIs happening
+		 * during the current NMI; the latter is reported as errata
+		 * N15 in intel doc 249199-029, pentium 4 specification
+		 * update, though their suggested work-around does not
+		 * appear to solve the problem.
+		 */
+		
+		real = VIRT_CTR(stag, i);
+
+		CCCR_READ(low, high, real);
+ 		CTR_READ(ctr, high, real);
+		if (CCCR_OVF_P(low) || CTR_OVERFLOW_P(ctr)) {
+			oprofile_add_sample(eip, is_kernel, i, cpu);
+ 			CTR_WRITE(reset_value[i], real);
+			CCCR_CLEAR_OVF(low);
+			CCCR_WRITE(low, high, real);
+ 			CTR_WRITE(reset_value[i], real);
+			/* P4 quirk: you have to re-unmask the apic vector */
+			apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);
+			return 1;
+		}
+	}
+
+	/* P4 quirk: you have to re-unmask the apic vector */
+	apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);
+	return 0;
+}
+
+
+static void p4_start(struct op_msrs const * const msrs)
+{
+	unsigned int low, high, stag;
+	int i;
+
+	stag = get_stagger();
+
+	for (i = 0; i < num_counters; ++i) {
+		if (!reset_value[i])
+			continue;
+		CCCR_READ(low, high, VIRT_CTR(stag, i));
+		CCCR_SET_ENABLE(low);
+		CCCR_WRITE(low, high, VIRT_CTR(stag, i));
+	}
+}
+
+
+static void p4_stop(struct op_msrs const * const msrs)
+{
+	unsigned int low, high, stag;
+	int i;
+
+	stag = get_stagger();
+
+	for (i = 0; i < num_counters; ++i) {
+		CCCR_READ(low, high, VIRT_CTR(stag, i));
+		CCCR_SET_DISABLE(low);
+		CCCR_WRITE(low, high, VIRT_CTR(stag, i));
+	}
+}
+
+
+#ifdef CONFIG_SMP
+struct op_x86_model_spec const op_p4_ht2_spec = {
+	.num_counters = NUM_COUNTERS_HT2,
+	.num_controls = NUM_CONTROLS_HT2,
+	.fill_in_addresses = &p4_fill_in_addresses,
+	.setup_ctrs = &p4_setup_ctrs,
+	.check_ctrs = &p4_check_ctrs,
+	.start = &p4_start,
+	.stop = &p4_stop
+};
+#endif
+
+struct op_x86_model_spec const op_p4_spec = {
+	.num_counters = NUM_COUNTERS_NON_HT,
+	.num_controls = NUM_CONTROLS_NON_HT,
+	.fill_in_addresses = &p4_fill_in_addresses,
+	.setup_ctrs = &p4_setup_ctrs,
+	.check_ctrs = &p4_check_ctrs,
+	.start = &p4_start,
+	.stop = &p4_stop
+};
diff -Nru a/arch/i386/oprofile/op_model_ppro.c b/arch/i386/oprofile/op_model_ppro.c
--- a/arch/i386/oprofile/op_model_ppro.c	Fri Feb 14 15:53:11 2003
+++ b/arch/i386/oprofile/op_model_ppro.c	Fri Feb 14 15:53:11 2003
@@ -90,11 +90,13 @@
 {
 	unsigned int low, high;
 	int i;
+	unsigned long eip = instruction_pointer(regs);
+	int is_kernel = !user_mode(regs);
  
 	for (i = 0 ; i < NUM_COUNTERS; ++i) {
 		CTR_READ(low, high, msrs, i);
 		if (CTR_OVERFLOWED(low)) {
-			oprofile_add_sample(instruction_pointer(regs), i, cpu);
+			oprofile_add_sample(eip, is_kernel, i, cpu);
 			CTR_WRITE(reset_value[i], msrs, i);
 			return 1;
 		}
diff -Nru a/arch/i386/oprofile/op_x86_model.h b/arch/i386/oprofile/op_x86_model.h
--- a/arch/i386/oprofile/op_x86_model.h	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/oprofile/op_x86_model.h	Fri Feb 14 15:53:09 2003
@@ -11,8 +11,8 @@
 #ifndef OP_X86_MODEL_H
 #define OP_X86_MODEL_H
 
-/* will need re-working for Pentium IV */
-#define MAX_MSR 4
+/* Pentium IV needs all these */
+#define MAX_MSR 63
  
 struct op_saved_msr {
 	unsigned int high;
@@ -47,6 +47,8 @@
 };
 
 extern struct op_x86_model_spec const op_ppro_spec;
+extern struct op_x86_model_spec const op_p4_spec;
+extern struct op_x86_model_spec const op_p4_ht2_spec;
 extern struct op_x86_model_spec const op_athlon_spec;
 
 #endif /* OP_X86_MODEL_H */
diff -Nru a/arch/i386/oprofile/timer_int.c b/arch/i386/oprofile/timer_int.c
--- a/arch/i386/oprofile/timer_int.c	Fri Feb 14 15:53:09 2003
+++ b/arch/i386/oprofile/timer_int.c	Fri Feb 14 15:53:09 2003
@@ -20,8 +20,9 @@
 {
 	struct pt_regs * regs = (struct pt_regs *)data;
 	int cpu = smp_processor_id();
+	unsigned long eip = instruction_pointer(regs);
  
-	oprofile_add_sample(instruction_pointer(regs), 0, cpu);
+	oprofile_add_sample(eip, !user_mode(regs), 0, cpu);
 	return 0;
 }
  
@@ -45,13 +46,13 @@
 
 static struct oprofile_operations timer_ops = {
 	.start	= timer_start,
-	.stop	= timer_stop
+	.stop	= timer_stop,
+	.cpu_type = "timer"
 };
 
  
-void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+void __init timer_init(struct oprofile_operations ** ops)
 {
 	*ops = &timer_ops;
-	*cpu = OPROFILE_CPU_TIMER;
 	printk(KERN_INFO "oprofile: using timer interrupt.\n");
 }
diff -Nru a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
--- a/arch/ia64/kernel/signal.c	Fri Feb 14 15:53:10 2003
+++ b/arch/ia64/kernel/signal.c	Fri Feb 14 15:53:10 2003
@@ -517,7 +517,7 @@
 		restart = 0;
 
 	while (1) {
-		int signr = get_signal_to_deliver(&info, &scr->pt);
+		int signr = get_signal_to_deliver(&info, &scr->pt, NULL);
 
 		if (signr <= 0)
 			break;
diff -Nru a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
--- a/arch/ia64/mm/hugetlbpage.c	Fri Feb 14 15:53:10 2003
+++ b/arch/ia64/mm/hugetlbpage.c	Fri Feb 14 15:53:10 2003
@@ -96,6 +96,18 @@
 	return;
 }
 
+/*
+ * This function checks for proper alignment of input addr and len parameters.
+ */
+int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
+{
+	if (len & ~HPAGE_MASK)
+		return -EINVAL;
+	if (addr & ~HPAGE_MASK)
+		return -EINVAL;
+	return 0;
+}
+
 int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			struct vm_area_struct *vma)
 {
diff -Nru a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
--- a/arch/m68k/kernel/signal.c	Fri Feb 14 15:53:12 2003
+++ b/arch/m68k/kernel/signal.c	Fri Feb 14 15:53:12 2003
@@ -1004,7 +1004,7 @@
 	for (;;) {
 		int signr;
 
-		signr = dequeue_signal(&current->blocked, &info);
+		signr = dequeue_signal(current, &current->blocked, &info);
 
 		if (!signr)
 			break;
diff -Nru a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c
--- a/arch/m68knommu/kernel/signal.c	Fri Feb 14 15:53:11 2003
+++ b/arch/m68knommu/kernel/signal.c	Fri Feb 14 15:53:11 2003
@@ -768,7 +768,7 @@
 	for (;;) {
 		int signr;
 
-		signr = get_signal_to_deliver(&info, regs);
+		signr = get_signal_to_deliver(&info, regs, NULL);
 
 		if (!signr)
 			break;
diff -Nru a/arch/mips/baget/vacserial.c b/arch/mips/baget/vacserial.c
--- a/arch/mips/baget/vacserial.c	Fri Feb 14 15:53:11 2003
+++ b/arch/mips/baget/vacserial.c	Fri Feb 14 15:53:11 2003
@@ -1785,7 +1785,7 @@
 		schedule_timeout(char_time);
 		if (signal_pending(current))
 			break;
-		if (timeout && ((orig_jiffies + timeout) < jiffies))
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
 			break;
 	}
 	current->state = TASK_RUNNING;
diff -Nru a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
--- a/arch/mips/kernel/irixsig.c	Fri Feb 14 15:53:12 2003
+++ b/arch/mips/kernel/irixsig.c	Fri Feb 14 15:53:12 2003
@@ -183,7 +183,7 @@
 		unsigned long signr;
 
 		spin_lock_irq(&current->sigmask_lock);
-		signr = dequeue_signal(&current->blocked, &info);
+		signr = dequeue_signal(current, &current->blocked, &info);
 		spin_unlock_irq(&current->sigmask_lock);
 
 		if (!signr)
diff -Nru a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
--- a/arch/mips/kernel/signal.c	Fri Feb 14 15:53:12 2003
+++ b/arch/mips/kernel/signal.c	Fri Feb 14 15:53:12 2003
@@ -544,7 +544,7 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		if (regs->regs[0])
 			syscall_restart(regs, ka);
diff -Nru a/arch/mips64/kernel/signal.c b/arch/mips64/kernel/signal.c
--- a/arch/mips64/kernel/signal.c	Fri Feb 14 15:53:09 2003
+++ b/arch/mips64/kernel/signal.c	Fri Feb 14 15:53:09 2003
@@ -602,7 +602,7 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		if (regs->regs[0])
 			syscall_restart(regs, ka);
diff -Nru a/arch/mips64/kernel/signal32.c b/arch/mips64/kernel/signal32.c
--- a/arch/mips64/kernel/signal32.c	Fri Feb 14 15:53:10 2003
+++ b/arch/mips64/kernel/signal32.c	Fri Feb 14 15:53:10 2003
@@ -676,7 +676,7 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		if (regs->regs[0])
 			syscall_restart(regs, ka);
diff -Nru a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c
--- a/arch/parisc/kernel/binfmt_elf32.c	Fri Feb 14 15:53:09 2003
+++ b/arch/parisc/kernel/binfmt_elf32.c	Fri Feb 14 15:53:09 2003
@@ -19,7 +19,7 @@
 #include <linux/module.h>
 #include <linux/config.h>
 #include <linux/elfcore.h>
-#include <linux/compat.h>
+#include <linux/compat.h>		/* struct compat_timeval */
 
 #define elf_prstatus elf_prstatus32
 struct elf_prstatus32
diff -Nru a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
--- a/arch/parisc/kernel/signal.c	Fri Feb 14 15:53:12 2003
+++ b/arch/parisc/kernel/signal.c	Fri Feb 14 15:53:12 2003
@@ -25,6 +25,7 @@
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
+#include <linux/compat.h>
 #include <asm/ucontext.h>
 #include <asm/rt_sigframe.h>
 #include <asm/uaccess.h>
@@ -97,13 +98,13 @@
 	sigset_t saveset, newset;
 #ifdef __LP64__
 	/* XXX FIXME -- assumes 32-bit user app! */
-	sigset_t32 newset32;
+	compat_sigset_t newset32;
 
 	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset_t32))
+	if (sigsetsize != sizeof(compat_sigset_t))
 		return -EINVAL;
 
-	if (copy_from_user(&newset32, (sigset_t32 *)unewset, sizeof(newset32)))
+	if (copy_from_user(&newset32, (compat_sigset_t *)unewset, sizeof(newset32)))
 		return -EFAULT;
 
 	newset.sig[0] = newset32.sig[0] | ((unsigned long)newset32.sig[1] << 32);
diff -Nru a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
--- a/arch/parisc/kernel/signal32.c	Fri Feb 14 15:53:09 2003
+++ b/arch/parisc/kernel/signal32.c	Fri Feb 14 15:53:09 2003
@@ -18,22 +18,22 @@
 };
 
 static inline void
-sigset_32to64(sigset_t *s64, sigset_t32 *s32)
+sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
 {
 	s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
 }
 
 static inline void
-sigset_64to32(sigset_t32 *s32, sigset_t *s64)
+sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
 {
 	s32->sig[0] = s64->sig[0] & 0xffffffffUL;
 	s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
 }
 
 static int
-put_sigset32(sigset_t32 *up, sigset_t *set, size_t sz)
+put_sigset32(compat_sigset_t *up, sigset_t *set, size_t sz)
 {
-	sigset_t32 s;
+	compat_sigset_t s;
 
 	if (sz != sizeof *set) panic("put_sigset32()");
 	sigset_64to32(&s, set);
@@ -42,9 +42,9 @@
 }
 
 static int
-get_sigset32(sigset_t32 *up, sigset_t *set, size_t sz)
+get_sigset32(compat_sigset_t *up, sigset_t *set, size_t sz)
 {
-	sigset_t32 s;
+	compat_sigset_t s;
 	int r;
 
 	if (sz != sizeof *set) panic("put_sigset32()");
@@ -56,7 +56,7 @@
 	return r;
 }
 
-int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset,
+int sys32_rt_sigprocmask(int how, compat_sigset_t *set, compat_sigset_t *oset,
 				    unsigned int sigsetsize)
 {
 	extern long sys_rt_sigprocmask(int how,
@@ -78,7 +78,7 @@
 }
 
 
-int sys32_rt_sigpending(sigset_t32 *uset, unsigned int sigsetsize)
+int sys32_rt_sigpending(compat_sigset_t *uset, unsigned int sigsetsize)
 {
 	int ret;
 	sigset_t set;
diff -Nru a/arch/parisc/kernel/sys32.h b/arch/parisc/kernel/sys32.h
--- a/arch/parisc/kernel/sys32.h	Fri Feb 14 15:53:11 2003
+++ b/arch/parisc/kernel/sys32.h	Fri Feb 14 15:53:11 2003
@@ -14,15 +14,10 @@
 
 typedef __u32 __sighandler_t32;
 
-#include <linux/signal.h>
-typedef struct {
-	unsigned int sig[_NSIG_WORDS * 2];
-} sigset_t32;
-
 struct sigaction32 {
 	__sighandler_t32 sa_handler;
 	unsigned int sa_flags;
-	sigset_t32 sa_mask;		/* mask last for extensibility */
+	compat_sigset_t sa_mask;		/* mask last for extensibility */
 };
 
 #endif
diff -Nru a/arch/parisc/oprofile/init.c b/arch/parisc/oprofile/init.c
--- a/arch/parisc/oprofile/init.c	Fri Feb 14 15:53:10 2003
+++ b/arch/parisc/oprofile/init.c	Fri Feb 14 15:53:10 2003
@@ -11,10 +11,10 @@
 #include <linux/oprofile.h>
 #include <linux/init.h>
  
-extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu);
+extern void timer_init(struct oprofile_operations ** ops);
 
-int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+int __init oprofile_arch_init(struct oprofile_operations ** ops)
 {
-	timer_init(ops, cpu);
+	timer_init(ops);
 	return 0;
 }
diff -Nru a/arch/parisc/oprofile/timer_int.c b/arch/parisc/oprofile/timer_int.c
--- a/arch/parisc/oprofile/timer_int.c	Fri Feb 14 15:53:08 2003
+++ b/arch/parisc/oprofile/timer_int.c	Fri Feb 14 15:53:08 2003
@@ -19,8 +19,10 @@
 {
 	struct pt_regs * regs = (struct pt_regs *)data;
 	int cpu = smp_processor_id();
+	unsigned long pc = regs->iaoq[0];
+	int is_kernel = !user_mode(regs);
  
-	oprofile_add_sample(regs->iaoq[0], 0, cpu);
+	oprofile_add_sample(pc, is_kernel, 0, cpu);
 	return 0;
 }
  
@@ -44,13 +46,13 @@
 
 static struct oprofile_operations timer_ops = {
 	.start	= timer_start,
-	.stop	= timer_stop
+	.stop	= timer_stop,
+	.cpu_type = "timer"
 };
 
  
-void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+void __init timer_init(struct oprofile_operations ** ops)
 {
 	*ops = &timer_ops;
-	*cpu = OPROFILE_CPU_TIMER;
 	printk(KERN_INFO "oprofile: using timer interrupt.\n");
 }
diff -Nru a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
--- a/arch/ppc/kernel/signal.c	Fri Feb 14 15:53:12 2003
+++ b/arch/ppc/kernel/signal.c	Fri Feb 14 15:53:12 2003
@@ -484,7 +484,7 @@
 
 	newsp = frame = 0;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		ka = &current->sig->action[signr-1];
 		if ( (ka->sa.sa_flags & SA_ONSTACK)
diff -Nru a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c
--- a/arch/ppc64/kernel/rtasd.c	Fri Feb 14 15:53:09 2003
+++ b/arch/ppc64/kernel/rtasd.c	Fri Feb 14 15:53:09 2003
@@ -211,9 +211,7 @@
 
 	DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2);
 
-	daemonize();
-	sigfillset(&current->blocked);
-	sprintf(current->comm, "rtasd");
+	daemonize("rtasd");
 
 #if 0
 	/* Rusty unreal time task */
diff -Nru a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c
--- a/arch/ppc64/kernel/signal.c	Fri Feb 14 15:53:08 2003
+++ b/arch/ppc64/kernel/signal.c	Fri Feb 14 15:53:08 2003
@@ -551,7 +551,7 @@
 
 	newsp = frame = 0;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		ka = &current->sighand->action[signr-1];
 		if ((ka->sa.sa_flags & SA_ONSTACK)
diff -Nru a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c
--- a/arch/ppc64/kernel/signal32.c	Fri Feb 14 15:53:12 2003
+++ b/arch/ppc64/kernel/signal32.c	Fri Feb 14 15:53:12 2003
@@ -1063,7 +1063,7 @@
 
 	newsp = frame = 0;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		ka = &current->sighand->action[signr-1];
 		if ((ka->sa.sa_flags & SA_ONSTACK)
diff -Nru a/arch/ppc64/oprofile/init.c b/arch/ppc64/oprofile/init.c
--- a/arch/ppc64/oprofile/init.c	Fri Feb 14 15:53:11 2003
+++ b/arch/ppc64/oprofile/init.c	Fri Feb 14 15:53:11 2003
@@ -11,10 +11,10 @@
 #include <linux/oprofile.h>
 #include <linux/init.h>
  
-extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu);
+extern void timer_init(struct oprofile_operations ** ops);
 
-int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+int __init oprofile_arch_init(struct oprofile_operations ** ops)
 {
-	timer_init(ops, cpu);
+	timer_init(ops);
 	return 0;
 }
diff -Nru a/arch/ppc64/oprofile/timer_int.c b/arch/ppc64/oprofile/timer_int.c
--- a/arch/ppc64/oprofile/timer_int.c	Fri Feb 14 15:53:12 2003
+++ b/arch/ppc64/oprofile/timer_int.c	Fri Feb 14 15:53:12 2003
@@ -19,8 +19,10 @@
 {
 	struct pt_regs * regs = (struct pt_regs *)data;
 	int cpu = smp_processor_id();
+	unsigned long pc = instruction_pointer(regs);
+	int is_kernel = !user_mode(regs);
  
-	oprofile_add_sample(instruction_pointer(regs), 0, cpu);
+	oprofile_add_sample(pc, is_kernel, 0, cpu);
 	return 0;
 }
  
@@ -44,13 +46,13 @@
 
 static struct oprofile_operations timer_ops = {
 	.start	= timer_start,
-	.stop	= timer_stop
+	.stop	= timer_stop,
+	.cpu_type = "timer"
 };
 
  
-void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+void __init timer_init(struct oprofile_operations ** ops)
 {
 	*ops = &timer_ops;
-	*cpu = OPROFILE_CPU_TIMER;
 	printk(KERN_INFO "oprofile: using timer interrupt.\n");
 }
diff -Nru a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
--- a/arch/s390/kernel/signal.c	Fri Feb 14 15:53:12 2003
+++ b/arch/s390/kernel/signal.c	Fri Feb 14 15:53:12 2003
@@ -461,7 +461,7 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &info, oldset, regs);
diff -Nru a/arch/s390x/kernel/linux32.c b/arch/s390x/kernel/linux32.c
--- a/arch/s390x/kernel/linux32.c	Fri Feb 14 15:53:12 2003
+++ b/arch/s390x/kernel/linux32.c	Fri Feb 14 15:53:12 2003
@@ -1726,7 +1726,7 @@
 	}
 
 	spin_lock_irq(&current->sighand->siglock);
-	sig = dequeue_signal(&these, &info);
+	sig = dequeue_signal(current, &these, &info);
 	if (!sig) {
 		/* None ready -- temporarily unblock those we're interested
 		   in so that we'll be awakened when they arrive.  */
@@ -1744,7 +1744,7 @@
 		timeout = schedule_timeout(timeout);
 
 		spin_lock_irq(&current->sighand->siglock);
-		sig = dequeue_signal(&these, &info);
+		sig = dequeue_signal(current, &these, &info);
 		current->blocked = current->real_blocked;
 		siginitset(&current->real_blocked, 0);
 		recalc_sigpending();
diff -Nru a/arch/s390x/kernel/signal.c b/arch/s390x/kernel/signal.c
--- a/arch/s390x/kernel/signal.c	Fri Feb 14 15:53:11 2003
+++ b/arch/s390x/kernel/signal.c	Fri Feb 14 15:53:11 2003
@@ -461,7 +461,7 @@
         }
 #endif 
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &info, oldset, regs);
diff -Nru a/arch/s390x/kernel/signal32.c b/arch/s390x/kernel/signal32.c
--- a/arch/s390x/kernel/signal32.c	Fri Feb 14 15:53:09 2003
+++ b/arch/s390x/kernel/signal32.c	Fri Feb 14 15:53:09 2003
@@ -622,7 +622,7 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal32(signr, &info, oldset, regs);
diff -Nru a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
--- a/arch/sh/kernel/signal.c	Fri Feb 14 15:53:12 2003
+++ b/arch/sh/kernel/signal.c	Fri Feb 14 15:53:12 2003
@@ -556,7 +556,7 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &info, oldset, regs);
diff -Nru a/arch/sparc/Makefile b/arch/sparc/Makefile
--- a/arch/sparc/Makefile	Fri Feb 14 15:53:09 2003
+++ b/arch/sparc/Makefile	Fri Feb 14 15:53:09 2003
@@ -38,7 +38,7 @@
 LDFLAGS_vmlinux = -r
 
 head-y := arch/sparc/kernel/head.o arch/sparc/kernel/init_task.o
-HEAD := $(head-y)
+HEAD_Y := $(head-y)
 
 core-y += arch/sparc/kernel/ arch/sparc/mm/ arch/sparc/math-emu/
 libs-y += arch/sparc/prom/ arch/sparc/lib/
@@ -52,7 +52,7 @@
 DRIVERS_Y	:= $(patsubst %/, %/built-in.o, $(drivers-y))
 NET_Y		:= $(patsubst %/, %/built-in.o, $(net-y))
 LIBS_Y		:= $(patsubst %/, %/lib.a, $(libs-y))
-export INIT_Y CORE_Y DRIVERS_Y NET_Y LIBS_Y HEAD
+export INIT_Y CORE_Y DRIVERS_Y NET_Y LIBS_Y HEAD_Y
 
 makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/$(ARCH)/boot $(1)
 
diff -Nru a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile
--- a/arch/sparc/boot/Makefile	Fri Feb 14 15:53:12 2003
+++ b/arch/sparc/boot/Makefile	Fri Feb 14 15:53:12 2003
@@ -17,7 +17,7 @@
 quiet_cmd_btfix		= BTFIX $@
       cmd_btfix		= $(OBJDUMP) -x vmlinux | $(obj)/btfixupprep > $@
 
-BTOBJS := $(HEAD) $(INIT_Y)
+BTOBJS := $(HEAD_Y) $(INIT_Y)
 BTLIBS := $(CORE_Y) $(LIBS_Y) $(DRIVERS_Y) $(NET_Y)
 LDFLAGS_image := -T arch/sparc/vmlinux.lds.s $(BTOBJS) --start-group $(BTLIBS) --end-group
 
diff -Nru a/arch/sparc/kernel/init_task.c b/arch/sparc/kernel/init_task.c
--- a/arch/sparc/kernel/init_task.c	Fri Feb 14 15:53:11 2003
+++ b/arch/sparc/kernel/init_task.c	Fri Feb 14 15:53:11 2003
@@ -8,6 +8,7 @@
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
 struct mm_struct init_mm = INIT_MM(init_mm);
 struct task_struct init_task = INIT_TASK(init_task);
 
diff -Nru a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
--- a/arch/sparc/kernel/signal.c	Fri Feb 14 15:53:12 2003
+++ b/arch/sparc/kernel/signal.c	Fri Feb 14 15:53:12 2003
@@ -1045,8 +1045,9 @@
 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
 			 unsigned long orig_i0, int restart_syscall)
 {
-	struct k_sigaction *ka;
 	siginfo_t info;
+	struct sparc_deliver_cookie cookie;
+	int signr;
 
 	/*
 	 * XXX Disable svr4 signal handling until solaris emulation works.
@@ -1059,142 +1060,32 @@
 	int svr4_signal = current->personality == PER_SVR4;
 #endif
 
+	cookie.restart_syscall = restart_syscall;
+	cookie.orig_i0 = orig_i0;
+
 	if (!oldset)
 		oldset = &current->blocked;
 
-	for (;;) {
-		sigset_t *mask = &current->blocked;
-		unsigned long signr = 0;
-
-		spin_lock_irq(&current->sighand->siglock);
-		signr = dequeue_signal(mask, &info);
-		spin_unlock_irq(&current->sighand->siglock);
-
-		if (!signr)
-			break;
-
-		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
-			/* Do the syscall restart before we let the debugger
-			 * look at the child registers.
-			 */
-			if (restart_syscall &&
-			    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-			     regs->u_regs[UREG_I0] == ERESTARTSYS ||
-			     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
-				/* replay the system call when we are done */
-				regs->u_regs[UREG_I0] = orig_i0;
-				regs->pc -= 4;
-				regs->npc -= 4;
-				restart_syscall = 0;
-			}
-			if (restart_syscall &&
-			    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
-				regs->u_regs[UREG_G1] = __NR_restart_syscall;
-				regs->pc -= 4;
-				regs->npc -= 4;
-				restart_syscall = 0;
-			}
-			current->exit_code = signr;
-			set_current_state(TASK_STOPPED);
-
-			/* This happens to be SMP safe so no need to
-			 * grab master kernel lock even in this case.
-			 */
-			notify_parent(current, SIGCHLD);
-			schedule();
-			if (!(signr = current->exit_code))
-				continue;
-			current->exit_code = 0;
-			if (signr == SIGSTOP)
-				continue;
-
-			/* Update the siginfo structure.  Is this good?  */
-			if (signr != info.si_signo) {
-				info.si_signo = signr;
-				info.si_errno = 0;
-				info.si_code = SI_USER;
-				info.si_pid = current->parent->pid;
-				info.si_uid = current->parent->uid;
-			}
-
-			/* If the (new) signal is now blocked, requeue it.  */
-			if (sigismember(&current->blocked, signr)) {
-				send_sig_info(signr, &info, current);
-				continue;
-			}
-		}
-
-		ka = &current->sig->action[signr-1];
-
-		if (ka->sa.sa_handler == SIG_IGN) {
-			if (signr != SIGCHLD)
-				continue;
-
-			/* sys_wait4() grabs the master kernel lock, so
-			 * we need not do so, that sucker should be
-			 * threaded and would not be that difficult to
-			 * do anyways.
-			 */
-			while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
-				;
-			continue;
-		}
-		if (ka->sa.sa_handler == SIG_DFL) {
-			unsigned long exit_code = signr;
-
-			if (current->pid == 1)
-				continue;
-			switch (signr) {
-			case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
-				continue;
-
-			case SIGTSTP: case SIGTTIN: case SIGTTOU:
-				/* The operations performed by
-				 * is_orphaned_pgrp() are protected by
-				 * the tasklist_lock.
-				 */
-				if (is_orphaned_pgrp(current->pgrp))
-					continue;
-
-			case SIGSTOP: {
-				struct signal_struct *sig;
-				set_current_state(TASK_STOPPED);
-				current->exit_code = signr;
-				sig = current->parent->sig;
-				if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
-				      SA_NOCLDSTOP))
-					notify_parent(current, SIGCHLD);
-				schedule();
-				continue;
-			}
-
-			case SIGQUIT: case SIGILL: case SIGTRAP:
-			case SIGABRT: case SIGFPE: case SIGSEGV:
-			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
-				if (do_coredump(signr, exit_code, regs))
-					exit_code |= 0x80;
-				/* FALLTHRU */
-
-			default:
-				sig_exit(signr, exit_code, &info);
-				/* NOT REACHED */
-			}
-		}
-		if (restart_syscall)
-			syscall_restart(orig_i0, regs, &ka->sa);
+	signr = get_signal_to_deliver(&info, regs, &cookie);
+	if (signr > 0) {
+		struct k_sigaction *ka;
+		
+		ka = &current->sighand->action[signr-1];
+		if (cookie.restart_syscall)
+			syscall_restart(cookie.orig_i0, regs, &ka->sa);
 		handle_signal(signr, ka, &info, oldset, regs, svr4_signal);
 		return 1;
 	}
-	if (restart_syscall &&
+	if (cookie.restart_syscall &&
 	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
 	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
 	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
-		regs->u_regs[UREG_I0] = orig_i0;
+		regs->u_regs[UREG_I0] = cookie.orig_i0;
 		regs->pc -= 4;
 		regs->npc -= 4;
 	}
-	if (restart_syscall &&
+	if (cookie.restart_syscall &&
 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->pc -= 4;
diff -Nru a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
--- a/arch/sparc/mm/init.c	Fri Feb 14 15:53:09 2003
+++ b/arch/sparc/mm/init.c	Fri Feb 14 15:53:09 2003
@@ -525,7 +525,7 @@
 }
 #endif
 
-void flush_page_to_ram(struct page *page)
+void sparc_flush_page_to_ram(struct page *page)
 {
 	unsigned long vaddr = (unsigned long)page_address(page);
 
diff -Nru a/arch/sparc64/kernel/init_task.c b/arch/sparc64/kernel/init_task.c
--- a/arch/sparc64/kernel/init_task.c	Fri Feb 14 15:53:12 2003
+++ b/arch/sparc64/kernel/init_task.c	Fri Feb 14 15:53:12 2003
@@ -9,6 +9,7 @@
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
 struct mm_struct init_mm = INIT_MM(init_mm);
 
 /* .text section in head.S is aligned at 2 page boundry and this gets linked
diff -Nru a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
--- a/arch/sparc64/kernel/ioctl32.c	Fri Feb 14 15:53:12 2003
+++ b/arch/sparc64/kernel/ioctl32.c	Fri Feb 14 15:53:12 2003
@@ -4285,6 +4285,7 @@
 COMPATIBLE_IOCTL(TCSETAW)
 COMPATIBLE_IOCTL(TCSETAF)
 COMPATIBLE_IOCTL(TCSBRK)
+COMPATIBLE_IOCTL(TCSBRKP)
 COMPATIBLE_IOCTL(TCXONC)
 COMPATIBLE_IOCTL(TCFLSH)
 COMPATIBLE_IOCTL(TCGETS)
diff -Nru a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
--- a/arch/sparc64/kernel/irq.c	Fri Feb 14 15:53:12 2003
+++ b/arch/sparc64/kernel/irq.c	Fri Feb 14 15:53:12 2003
@@ -740,9 +740,6 @@
 	irq_enter();
 	kstat_cpu(cpu).irqs[irq]++;
 
-	if (irq == 9)
-		kbd_pt_regs = regs;
-
 	/* Sliiiick... */
 #ifndef CONFIG_SMP
 	bp = ((irq != 0) ?
diff -Nru a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
--- a/arch/sparc64/kernel/power.c	Fri Feb 14 15:53:12 2003
+++ b/arch/sparc64/kernel/power.c	Fri Feb 14 15:53:12 2003
@@ -65,14 +65,11 @@
 	static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
 	char *argv[] = { "/sbin/shutdown", "-h", "now", NULL };
 
-	daemonize();
-	sprintf(current->comm, "powerd");
+	daemonize("powerd");
 
 again:
 	while (button_pressed == 0) {
-		spin_lock_irq(&current->sighand->siglock);
 		flush_signals(current);
-		spin_unlock_irq(&current->sighand->siglock);
 		interruptible_sleep_on(&powerd_wait);
 	}
 
diff -Nru a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
--- a/arch/sparc64/kernel/signal.c	Fri Feb 14 15:53:10 2003
+++ b/arch/sparc64/kernel/signal.c	Fri Feb 14 15:53:10 2003
@@ -603,8 +603,12 @@
 		     unsigned long orig_i0, int restart_syscall)
 {
 	siginfo_t info;
-	struct k_sigaction *ka;
+	struct signal_deliver_cookie cookie;
+	int signr;
 	
+	cookie.restart_syscall = restart_syscall;
+	cookie.orig_i0 = orig_i0;
+
 	if (!oldset)
 		oldset = &current->blocked;
 
@@ -612,135 +616,31 @@
 	if (test_thread_flag(TIF_32BIT)) {
 		extern int do_signal32(sigset_t *, struct pt_regs *,
 				       unsigned long, int);
-		return do_signal32(oldset, regs, orig_i0, restart_syscall);
+		return do_signal32(oldset, regs, orig_i0,
+				   cookie.restart_syscall);
 	}
 #endif	
-	for (;;) {
-		sigset_t *mask = &current->blocked;
-		unsigned long signr = 0;
-
-		spin_lock_irq(&current->sighand->siglock);
-		signr = dequeue_signal(mask, &info);
-		spin_unlock_irq(&current->sighand->siglock);
-		
-		if (!signr)
-			break;
-
-		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
-			/* Do the syscall restart before we let the debugger
-			 * look at the child registers.
-			 */
-			if (restart_syscall &&
-			    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-			     regs->u_regs[UREG_I0] == ERESTARTSYS ||
-			     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
-				/* replay the system call when we are done */
-				regs->u_regs[UREG_I0] = orig_i0;
-				regs->tpc -= 4;
-				regs->tnpc -= 4;
-				restart_syscall = 0;
-			}
-			if (restart_syscall &&
-			    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
-				regs->u_regs[UREG_G1] = __NR_restart_syscall;
-				regs->tpc -= 4;
-				regs->tnpc -= 4;
-				restart_syscall = 0;
-			}
-
-			current->exit_code = signr;
-			set_current_state(TASK_STOPPED);
-			notify_parent(current, SIGCHLD);
-			schedule();
-			if (!(signr = current->exit_code))
-				continue;
-			current->exit_code = 0;
-			if (signr == SIGSTOP)
-				continue;
-
-			/* Update the siginfo structure.  Is this good?  */
-			if (signr != info.si_signo) {
-				info.si_signo = signr;
-				info.si_errno = 0;
-				info.si_code = SI_USER;
-				info.si_pid = current->parent->pid;
-				info.si_uid = current->parent->uid;
-			}
-
-			/* If the (new) signal is now blocked, requeue it.  */
-			if (sigismember(&current->blocked, signr)) {
-				send_sig_info(signr, &info, current);
-				continue;
-			}
-		}
-		
-		ka = &current->sig->action[signr-1];
-		
-		if (ka->sa.sa_handler == SIG_IGN) {
-			if (signr != SIGCHLD)
-				continue;
-
-                        /* sys_wait4() grabs the master kernel lock, so
-                         * we need not do so, that sucker should be
-                         * threaded and would not be that difficult to
-                         * do anyways.
-                         */
-                        while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
-                                ;
-			continue;
-		}
-		if (ka->sa.sa_handler == SIG_DFL) {
-			unsigned long exit_code = signr;
-			
-			if (current->pid == 1)
-				continue;
-			switch (signr) {
-			case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
-				continue;
-
-			case SIGTSTP: case SIGTTIN: case SIGTTOU:
-				if (is_orphaned_pgrp(current->pgrp))
-					continue;
-
-			case SIGSTOP: {
-				struct signal_struct *sig;
-				set_current_state(TASK_STOPPED);
-				current->exit_code = signr;
-				sig = current->parent->sig;
-				if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
-				      SA_NOCLDSTOP))
-					notify_parent(current, SIGCHLD);
-				schedule();
-				continue;
-			}
 
-			case SIGQUIT: case SIGILL: case SIGTRAP:
-			case SIGABRT: case SIGFPE: case SIGSEGV:
-			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
-				if (do_coredump(signr, exit_code, regs))
-					exit_code |= 0x80;
-				/* FALLTHRU */
+	signr = get_signal_to_deliver(&info, regs, &cookie);
+	if (signr > 0) {
+		struct k_sigaction *ka;
 
-			default:
-				sig_exit(signr, exit_code, &info);
-				/* NOT REACHED */
-			}
-		}
-		if (restart_syscall)
+		ka = &current->sighand->action[signr-1];
+		if (cookie.restart_syscall)
 			syscall_restart(orig_i0, regs, &ka->sa);
 		handle_signal(signr, ka, &info, oldset, regs);
 		return 1;
 	}
-	if (restart_syscall &&
+	if (cookie.restart_syscall &&
 	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
 	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
 	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
-		regs->u_regs[UREG_I0] = orig_i0;
+		regs->u_regs[UREG_I0] = cookie.orig_i0;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
 	}
-	if (restart_syscall &&
+	if (cookie.restart_syscall &&
 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->tpc -= 4;
diff -Nru a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
--- a/arch/sparc64/kernel/signal32.c	Fri Feb 14 15:53:08 2003
+++ b/arch/sparc64/kernel/signal32.c	Fri Feb 14 15:53:08 2003
@@ -1279,136 +1279,34 @@
 int do_signal32(sigset_t *oldset, struct pt_regs * regs,
 		unsigned long orig_i0, int restart_syscall)
 {
-	struct k_sigaction *ka;
 	siginfo_t info;
-	
+	struct signal_deliver_cookie cookie;
+	int signr;
 	int svr4_signal = current->personality == PER_SVR4;
 	
-	for (;;) {
-		sigset_t *mask = &current->blocked;
-		unsigned long signr = 0;
-
-		spin_lock_irq(&current->sighand->siglock);
-		signr = dequeue_signal(mask, &info);
-		spin_unlock_irq(&current->sighand->siglock);
-		
-		if (!signr)
-			break;
-
-		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
-			/* Do the syscall restart before we let the debugger
-			 * look at the child registers.
-			 */
-			if (restart_syscall &&
-			    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-			     regs->u_regs[UREG_I0] == ERESTARTSYS ||
-			     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
-				/* replay the system call when we are done */
-				regs->u_regs[UREG_I0] = orig_i0;
-				regs->tpc -= 4;
-				regs->tnpc -= 4;
-				restart_syscall = 0;
-			}
-			if (restart_syscall &&
-			    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
-				regs->u_regs[UREG_G1] = __NR_restart_syscall;
-				regs->tpc -= 4;
-				regs->tnpc -= 4;
-				restart_syscall = 0;
-			}
-
-			current->exit_code = signr;
-			set_current_state(TASK_STOPPED);
-			notify_parent(current, SIGCHLD);
-			schedule();
-			if (!(signr = current->exit_code))
-				continue;
-			current->exit_code = 0;
-			if (signr == SIGSTOP)
-				continue;
-
-			/* Update the siginfo structure.  Is this good?  */
-			if (signr != info.si_signo) {
-				info.si_signo = signr;
-				info.si_errno = 0;
-				info.si_code = SI_USER;
-				info.si_pid = current->parent->pid;
-				info.si_uid = current->parent->uid;
-			}
-
-			/* If the (new) signal is now blocked, requeue it.  */
-			if (sigismember(&current->blocked, signr)) {
-				send_sig_info(signr, &info, current);
-				continue;
-			}
-		}
-		
-		ka = &current->sig->action[signr-1];
-		
-		if (ka->sa.sa_handler == SIG_IGN) {
-			if (signr != SIGCHLD)
-				continue;
-
-			/* sys_wait4() grabs the master kernel lock, so
-			 * we need not do so, that sucker should be
-			 * threaded and would not be that difficult to
-			 * do anyways.
-			 */
-			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
-				;
-			continue;
-		}
-		if (ka->sa.sa_handler == SIG_DFL) {
-			unsigned long exit_code = signr;
-			
-			if (current->pid == 1)
-				continue;
-			switch (signr) {
-			case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
-				continue;
-
-			case SIGTSTP: case SIGTTIN: case SIGTTOU:
-				if (is_orphaned_pgrp(current->pgrp))
-					continue;
+	cookie.restart_syscall = restart_syscall;
+	cookie.orig_i0 = orig_i0;
 
-			case SIGSTOP: {
-				struct signal_struct *sig;
-				set_current_state(TASK_STOPPED);
-				current->exit_code = signr;
-				sig = current->parent->sig;
-				if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
-				      SA_NOCLDSTOP))
-					notify_parent(current, SIGCHLD);
-				schedule();
-				continue;
-			}
-			case SIGQUIT: case SIGILL: case SIGTRAP:
-			case SIGABRT: case SIGFPE: case SIGSEGV:
-			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
-				if (do_coredump(signr, exit_code, regs))
-					exit_code |= 0x80;
-				/* FALLTHRU */
+	signr = get_signal_to_deliver(&info, regs, &cookie);
+	if (signr > 0) {
+		struct k_sigaction *ka;
 
-			default:
-				sig_exit(signr, exit_code, &info);
-				/* NOT REACHED */
-			}
-		}
-		if (restart_syscall)
+		ka = &current->sighand->action[signr-1];
+		if (cookie.restart_syscall)
 			syscall_restart32(orig_i0, regs, &ka->sa);
 		handle_signal32(signr, ka, &info, oldset, regs, svr4_signal);
 		return 1;
 	}
-	if (restart_syscall &&
+	if (cookie.restart_syscall &&
 	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
 	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
 	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
-		regs->u_regs[UREG_I0] = orig_i0;
+		regs->u_regs[UREG_I0] = cookie.orig_i0;
 		regs->tpc -= 4;
 		regs->tnpc -= 4;
 	}
-	if (restart_syscall &&
+	if (cookie.restart_syscall &&
 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
 		regs->tpc -= 4;
diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
--- a/arch/sparc64/kernel/sys_sparc32.c	Fri Feb 14 15:53:11 2003
+++ b/arch/sparc64/kernel/sys_sparc32.c	Fri Feb 14 15:53:11 2003
@@ -1679,23 +1679,6 @@
 	return ret;
 }
 
-extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
-
-asmlinkage int sys32_sigprocmask(int how, compat_old_sigset_t *set, compat_old_sigset_t *oset)
-{
-	old_sigset_t s;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-	
-	if (set && get_user (s, set)) return -EFAULT;
-	set_fs (KERNEL_DS);
-	ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
-	set_fs (old_fs);
-	if (ret) return ret;
-	if (oset && put_user (s, oset)) return -EFAULT;
-	return 0;
-}
-
 extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);
 
 asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set, compat_sigset_t *oset, compat_size_t sigsetsize)
@@ -1732,21 +1715,6 @@
 	return 0;
 }
 
-extern asmlinkage int sys_sigpending(old_sigset_t *set);
-
-asmlinkage int sys32_sigpending(compat_old_sigset_t *set)
-{
-	old_sigset_t s;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-		
-	set_fs (KERNEL_DS);
-	ret = sys_sigpending(&s);
-	set_fs (old_fs);
-	if (put_user (s, set)) return -EFAULT;
-	return ret;
-}
-
 extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
 
 asmlinkage int sys32_rt_sigpending(compat_sigset_t *set, compat_size_t sigsetsize)
@@ -1813,7 +1781,7 @@
 	}
 
 	spin_lock_irq(&current->sighand->siglock);
-	sig = dequeue_signal(&these, &info);
+	sig = dequeue_signal(current, &these, &info);
 	if (!sig) {
 		timeout = MAX_SCHEDULE_TIMEOUT;
 		if (uts)
@@ -1833,7 +1801,7 @@
 			timeout = schedule_timeout(timeout);
 
 			spin_lock_irq(&current->sighand->siglock);
-			sig = dequeue_signal(&these, &info);
+			sig = dequeue_signal(current, &these, &info);
 			current->blocked = current->real_blocked;
 			siginitset(&current->real_blocked, 0);
 			recalc_sigpending();
diff -Nru a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
--- a/arch/sparc64/kernel/systbls.S	Fri Feb 14 15:53:09 2003
+++ b/arch/sparc64/kernel/systbls.S	Fri Feb 14 15:53:09 2003
@@ -55,7 +55,7 @@
 	.word sys_quotactl, sys_set_tid_address, sys32_mount, sys_ustat, sys_setxattr
 /*170*/	.word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents
 	.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
-/*180*/	.word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys_ni_syscall
+/*180*/	.word sys_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall
 	.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname
 /*190*/	.word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl
 	.word sys_epoll_wait, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
@@ -63,7 +63,7 @@
 	.word sys32_readahead, sys32_socketcall, sys_syslog, sys32_lookup_dcookie, sys_nis_syscall
 /*210*/	.word sys_nis_syscall, sys_nis_syscall, sys_waitpid, sys_swapoff, sys32_sysinfo
 	.word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex
-/*220*/	.word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys_getpgid
+/*220*/	.word compat_sys_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys_getpgid
 	.word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16
 /*230*/	.word sys32_select, sys_time, sys_nis_syscall, sys_stime, sys_ni_syscall
 	.word sys_ni_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
@@ -203,7 +203,7 @@
 	.word sunos_nosys, sunos_getdents, sys_setsid
 	.word sys_fchdir, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
-	.word sunos_nosys, sys32_sigpending, sunos_nosys
+	.word sunos_nosys, compat_sys_sigpending, sunos_nosys
 	.word sys_setpgid, sunos_pathconf, sunos_fpathconf
 	.word sunos_sysconf, sunos_uname, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
diff -Nru a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c
--- a/arch/sparc64/mm/hugetlbpage.c	Fri Feb 14 15:53:11 2003
+++ b/arch/sparc64/mm/hugetlbpage.c	Fri Feb 14 15:53:11 2003
@@ -232,6 +232,18 @@
 	return -1;
 }
 
+/*
+ * This function checks for proper alignment of input addr and len parameters.
+ */
+int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
+{
+	if (len & ~HPAGE_MASK)
+		return -EINVAL;
+	if (addr & ~HPAGE_MASK)
+		return -EINVAL;
+	return 0;
+}
+
 int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			    struct vm_area_struct *vma)
 {
diff -Nru a/arch/sparc64/oprofile/init.c b/arch/sparc64/oprofile/init.c
--- a/arch/sparc64/oprofile/init.c	Fri Feb 14 15:53:11 2003
+++ b/arch/sparc64/oprofile/init.c	Fri Feb 14 15:53:11 2003
@@ -11,10 +11,10 @@
 #include <linux/oprofile.h>
 #include <linux/init.h>
  
-extern void timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu);
+extern void timer_init(struct oprofile_operations ** ops);
 
-int __init oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+int __init oprofile_arch_init(struct oprofile_operations ** ops)
 {
-	timer_init(ops, cpu);
+	timer_init(ops);
 	return 0;
 }
diff -Nru a/arch/sparc64/oprofile/timer_int.c b/arch/sparc64/oprofile/timer_int.c
--- a/arch/sparc64/oprofile/timer_int.c	Fri Feb 14 15:53:12 2003
+++ b/arch/sparc64/oprofile/timer_int.c	Fri Feb 14 15:53:12 2003
@@ -19,8 +19,10 @@
 {
 	struct pt_regs * regs = (struct pt_regs *)data;
 	int cpu = smp_processor_id();
+	unsigned long pc = instruction_pointer(regs);
+	int is_kernel = !user_mode(regs);
  
-	oprofile_add_sample(instruction_pointer(regs), 0, cpu);
+	oprofile_add_sample(pc, is_kernel, 0, cpu);
 	return 0;
 }
  
@@ -44,13 +46,13 @@
 
 static struct oprofile_operations timer_ops = {
 	.start	= timer_start,
-	.stop	= timer_stop
+	.stop	= timer_stop,
+	.cpu_type = "timer"
 };
 
  
-void __init timer_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu)
+void __init timer_init(struct oprofile_operations ** ops)
 {
 	*ops = &timer_ops;
-	*cpu = OPROFILE_CPU_TIMER;
 	printk(KERN_INFO "oprofile: using timer interrupt.\n");
 }
diff -Nru a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
--- a/arch/um/kernel/signal_kern.c	Fri Feb 14 15:53:10 2003
+++ b/arch/um/kernel/signal_kern.c	Fri Feb 14 15:53:10 2003
@@ -136,7 +136,7 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	sig = get_signal_to_deliver(&info, regs);
+	sig = get_signal_to_deliver(&info, regs, NULL);
 	if(sig == 0)
 		return(0);
 
diff -Nru a/arch/v850/kernel/signal.c b/arch/v850/kernel/signal.c
--- a/arch/v850/kernel/signal.c	Fri Feb 14 15:53:12 2003
+++ b/arch/v850/kernel/signal.c	Fri Feb 14 15:53:12 2003
@@ -506,7 +506,7 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
 		handle_signal(signr, &info, oldset, regs);
diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
--- a/arch/x86_64/Kconfig	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/Kconfig	Fri Feb 14 15:53:12 2003
@@ -19,11 +19,6 @@
 config X86
 	bool
 	default y
-	help
-	  This is Linux's home port.  Linux was originally native to the Intel
-	  386, and runs on all the later x86 processors including the Intel
-	  486, 586, Pentiums, and various instruction-set-compatible chips by
-	  AMD, Cyrix, and others.
 
 config MMU
 	bool
@@ -35,20 +30,10 @@
 
 config ISA
 	bool
-	help
-	  Find out whether you have ISA slots on your motherboard.  ISA is the
-	  name of a bus system, i.e. the way the CPU talks to the other stuff
-	  inside your box.  Other bus systems are PCI, EISA, MicroChannel
-	  (MCA) or VESA.  ISA is an older system, now being displaced by PCI;
-	  newer boards don't support it.  If you have ISA, say Y, otherwise N.
 
 config SBUS
 	bool
 
-config UID16
-	bool
-	default y
-
 config RWSEM_GENERIC_SPINLOCK
 	bool
 	default y
@@ -86,14 +71,14 @@
 	default MK8
 
 config MK8
-	bool "AMD-Hammer"
+	bool "AMD-Opteron/Athlon64"
 	help
-	  Support for AMD Clawhammer/Sledgehammer CPUs. Only choice for x86-64
-	  currently so you should choose this if you want a x86-64 kernel. In fact
-	  you will have no other choice than to choose this.
+	  Optimize for AMD Opteron/Athlon64/Hammer/K8 CPUs. 
 
 config GENERIC_CPU
 	bool "Generic-x86-64"
+	help
+	  Generic x86-64 CPU.
 
 endchoice
 
@@ -196,25 +181,12 @@
 	  singleprocessor machines. On a singleprocessor machine, the kernel
 	  will run faster if you say N here.
 
-	  Note that if you say Y here and choose architecture "586" or
-	  "Pentium" under "Processor family", the kernel will not work on 486
-	  architectures. Similarly, multiprocessor kernels for the "PPro"
-	  architecture may not work on all Pentium based boards.
-
-	  People using multiprocessor machines who say Y here should also say
-	  Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
-	  Management" code will be disabled if you say Y here.
-
-	  See also the <file:Documentation/smp.tex>,
-	  <file:Documentation/smp.txt>, <file:Documentation/i386/IO-APIC.txt>,
-	  <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
-	  <http://www.tldp.org/docs.html#howto>.
-
 	  If you don't know what to do here, say N.
 
+# broken currently
 config PREEMPT
+	depends on NOT_WORKING
 	bool "Preemptible Kernel"
-	depends on !SMP
 	---help---
 	  This option reduces the latency of the kernel when reacting to
 	  real-time or interactive events by allowing a low priority process to
@@ -229,6 +201,28 @@
 	  Say Y here if you are feeling brave and building a kernel for a 
 	  desktop, embedded or real-time system.  Say N if you are unsure. 
 
+# someone write a better help text please.
+config K8_NUMA
+       bool "K8 NUMA support"
+       depends on SMP
+       help
+	  Enable NUMA (Non Unified Memory Architecture) support for
+	  AMD Opteron Multiprocessor systems. The kernel will try to allocate
+	  memory used by a CPU on the local memory controller of the CPU
+	  and in the future do more optimizations. This may improve performance 
+	  or it may not. Code is still experimental.
+	  Say N if unsure.
+
+config DISCONTIGMEM
+       bool
+       depends on K8_NUMA
+       default y
+
+config NUMA
+       bool
+       depends on K8_NUMA
+       default y
+
 config HAVE_DEC_LOCK
 	bool
 	depends on SMP
@@ -245,15 +239,17 @@
 	  kernel will support.  The maximum supported value is 32 and the
 	  minimum value which makes sense is 2.
 
-	  This is purely to save memory - each supported CPU adds
-	  approximately eight kilobytes to the kernel image.
+	  This is purely to save memory - each supported CPU requires
+	  memory in the static kernel configuration.
 
 config GART_IOMMU
 	bool "IOMMU support"
 	help
 	  Support the K8 IOMMU. Needed to run systems with more than 4GB of memory
-	  properly with 32-bit devices. You should probably turn this on.
-	  The iommu can be turned off at runtime with the iommu=off parameter.
+	  properly with 32-bit PCI devices that do not support DAC (Double Address
+	  Cycle). The IOMMU can be turned off at runtime with the iommu=off parameter.
+	  Normally the kernel will take the right choice by itself.
+	  If unsure say Y 
 
 config DUMMY_IOMMU
 	bool
@@ -291,7 +287,8 @@
 
 	  Note that, even if you say N here, Linux on the x86 architecture
 	  will issue the hlt instruction if nothing is to be done, thereby
-	  sending the processor to sleep and saving power.
+	  sending the processor to limited sleep and saving power. However
+	  using ACPI will likely save more power.
 
 config SOFTWARE_SUSPEND
 	bool "Software Suspend (EXPERIMENTAL)"
@@ -331,16 +328,6 @@
 
 config PCI
 	bool "PCI support"
-	help
-	  Find out whether you have a PCI motherboard. PCI is the name of a
-	  bus system, i.e. the way the CPU talks to the other stuff inside
-	  your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
-	  VESA. If you have PCI, say Y, otherwise N.
-
-	  The PCI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>, contains valuable
-	  information about which PCI hardware does work under Linux and which
-	  doesn't.
 
 # x86-64 doesn't support PCI BIOS access from long mode so always go direct. 
 config PCI_DIRECT
@@ -381,54 +368,10 @@
 	bool
 	depends on PROC_FS
 	default y
-	---help---
-	  If you enabled support for /proc file system then the file
-	  /proc/kcore will contain the kernel core image. This can be used
-	  in gdb:
-
-	  $ cd /usr/src/linux ; gdb vmlinux /proc/kcore
-
-	  You have two choices here: ELF and A.OUT. Selecting ELF will make
-	  /proc/kcore appear in ELF core format as defined by the Executable
-	  and Linkable Format specification. Selecting A.OUT will choose the
-	  old "a.out" format which may be necessary for some old versions
-	  of binutils or on some architectures.
-
-	  This is especially useful if you have compiled the kernel with the
-	  "-g" option to preserve debugging information. It is mainly used
-	  for examining kernel data structures on the live kernel so if you
-	  don't understand what this means or are not a kernel hacker, just
-	  leave it at its default value ELF.
 
-#tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
 config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
+	bool
+	default y
 
 config BINFMT_MISC
 	tristate "Kernel support for MISC binaries"
@@ -436,12 +379,9 @@
 	  If you say Y here, it will be possible to plug wrapper-driven binary
 	  formats into the kernel. You will like this especially when you use
 	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
+	  Emacs-Lisp. Once you have registered such a binary class with the kernel, 
+	  you can start one of those programs simply by typing in its name at a shell 
+	  prompt; Linux will automatically feed it to the correct interpreter.
 
 	  You can do other nice things, too. Read the file
 	  <file:Documentation/binfmt_misc.txt> to learn how to use this
@@ -467,6 +407,12 @@
 	depends on IA32_EMULATION
 	default y
 
+
+config UID16
+	bool
+	depends on IA32_EMULATION
+	default y
+
 endmenu
 
 source "drivers/mtd/Kconfig"
@@ -672,9 +618,11 @@
 	  best used in conjunction with the NMI watchdog so that spinlock
 	  deadlocks are also debuggable.
 
+# !SMP for now because the context switch early causes GPF in segment reloading
+# and the GS base checking does the wrong thing then, causing a hang.
 config CHECKING
 	bool "Additional run-time checks"
-	depends on DEBUG_KERNEL
+	depends on DEBUG_KERNEL && !SMP
 	help
 	  Enables some internal consistency checks for kernel debugging.
 	  You should normally say N.
@@ -683,7 +631,8 @@
 	bool "Debug __init statements"
 	depends on DEBUG_KERNEL
 	help
-	  Fill __init and __initdata at the end of boot. This is only for debugging.
+	  Fill __init and __initdata at the end of boot. This helps debugging
+	  illegal uses of __init and __initdata after initialization.	  
 
 config KALLSYMS
 	bool "Load all symbols for debugging/kksymoops"
@@ -696,11 +645,11 @@
        bool "Compile the kernel with frame pointers"
        depends on DEBUG_KERNEL	
        help
-         If you say Y here the resulting kernel image will be slightly larger
-         and slower, but it will give very useful debugging information.
-         If you don't debug the kernel, you can say N, but we may not be able
-         to solve problems without frame pointers.
-	 Note this is normally not needed on x86-64.
+	 Compile the kernel with frame pointers. This may help for some 
+	 debugging with external debuggers. Note the standard oops backtracer 
+	 doesn't make use of it and the x86-64 kernel doesn't ensure an consistent
+	 frame pointer through inline assembly (semaphores etc.)
+	 Normally you should say N.
 
 endmenu
 
diff -Nru a/arch/x86_64/Makefile b/arch/x86_64/Makefile
--- a/arch/x86_64/Makefile	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/Makefile	Fri Feb 14 15:53:12 2003
@@ -58,7 +58,8 @@
 
 boot := arch/x86_64/boot
 
-.PHONY: bzImage bzlilo bzdisk install archmrproper
+.PHONY: bzImage bzlilo install archmrproper \
+	fdimage fdimage144 fdimage288 archclean
 
 #Default target when executing "make"
 all: bzImage
@@ -74,7 +75,7 @@
 bzdisk: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zdisk
 
-install: vmlinux
+install fdimage fdimage144 fdimage288: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
 
 archclean:
@@ -102,4 +103,7 @@
   echo  '                  (distribution) /sbin/installkernel or'
   echo  '        	  install to $$(INSTALL_PATH) and run lilo'
 endef
+
+CLEAN_FILES += arch/$(ARCH)/boot/fdimage arch/$(ARCH)/boot/mtools.conf
+
 
diff -Nru a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile
--- a/arch/x86_64/boot/Makefile	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/boot/Makefile	Fri Feb 14 15:53:09 2003
@@ -59,8 +59,36 @@
 $(obj)/compressed/vmlinux: FORCE
 	$(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
 
-zdisk: $(BOOTIMAGE)
-	dd bs=8192 if=$(BOOTIMAGE) of=/dev/fd0
+# Set this if you want to pass append arguments to the zdisk/fdimage kernel
+FDARGS = 
+
+$(obj)/mtools.conf: $(obj)/mtools.conf.in
+	sed -e 's|@OBJ@|$(obj)|g' < $< > $@
+
+# This requires write access to /dev/fd0
+zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
+	MTOOLSRC=$(src)/mtools.conf mformat a:			; sync
+	syslinux /dev/fd0					; sync
+	echo 'default linux $(FDARGS)' | \
+		MTOOLSRC=$(src)/mtools.conf mcopy - a:syslinux.cfg
+	MTOOLSRC=$(src)/mtools.conf mcopy $(BOOTIMAGE) a:linux	; sync
+
+# These require being root or having syslinux run setuid
+fdimage fdimage144: $(BOOTIMAGE) $(src)/mtools.conf
+	dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440
+	MTOOLSRC=$(src)/mtools.conf mformat v:			; sync
+	syslinux $(obj)/fdimage					; sync
+	echo 'default linux $(FDARGS)' | \
+		MTOOLSRC=$(src)/mtools.conf mcopy - v:syslinux.cfg
+	MTOOLSRC=$(src)/mtools.conf mcopy $(BOOTIMAGE) v:linux	; sync
+
+fdimage288: $(BOOTIMAGE) $(src)/mtools.conf
+	dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880
+	MTOOLSRC=$(src)/mtools.conf mformat w:			; sync
+	syslinux $(obj)/fdimage					; sync
+	echo 'default linux $(FDARGS)' | \
+		MTOOLSRC=$(src)/mtools.conf mcopy - w:syslinux.cfg
+	MTOOLSRC=$(src)/mtools.conf mcopy $(BOOTIMAGE) w:linux	; sync
 
 zlilo: $(BOOTIMAGE)
 	if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
diff -Nru a/arch/x86_64/boot/bootsect.S b/arch/x86_64/boot/bootsect.S
--- a/arch/x86_64/boot/bootsect.S	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/boot/bootsect.S	Fri Feb 14 15:53:12 2003
@@ -4,29 +4,13 @@
  *	modified by Drew Eckhardt
  *	modified by Bruce Evans (bde)
  *	modified by Chris Noe (May 1999) (as86 -> gas)
- *
- * 360k/720k disk support: Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
+ *	gutted by H. Peter Anvin (Jan 2003)
  *
  * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
  * addresses must be multiplied by 16 to obtain their respective linear
  * addresses. To avoid confusion, linear addresses are written using leading
  * hex while segment addresses are written as segment:offset.
  *
- * bde - should not jump blindly, there may be systems with only 512K low
- * memory.  Use int 0x12 to get the top of memory, etc.
- *
- * It then loads 'setup' directly after itself (0x90200), and the system
- * at 0x10000, using BIOS interrupts. 
- *
- * NOTE! currently system is at most (8*65536-4096) bytes long. This should 
- * be no problem, even in the future. I want to keep it simple. This 508 kB
- * kernel size should be enough, especially as this doesn't contain the
- * buffer cache as in minix (and especially now that the kernel is 
- * compressed :-)
- *
- * The loader has been made as simple as possible, and continuous
- * read errors will result in a unbreakable loop. Reboot by hand. It
- * loads pretty fast by getting whole tracks at a time whenever possible.
  */
 
 #include <asm/boot.h>
@@ -59,353 +43,51 @@
 .global _start
 _start:
 
-# First things first. Move ourself from 0x7C00 -> 0x90000 and jump there.
+	# Normalize the start address
+	jmpl	$BOOTSEG, $start2
 
-	movw	$BOOTSEG, %ax
-	movw	%ax, %ds		# %ds = BOOTSEG
-	movw	$INITSEG, %ax
-	movw	%ax, %es		# %ax = %es = INITSEG
-	movw	$256, %cx
-	subw	%si, %si
-	subw	%di, %di
-	cld
-	rep
-	movsw
-	ljmp	$INITSEG, $go
-
-# bde - changed 0xff00 to 0x4000 to use debugger at 0x6400 up (bde).  We
-# wouldn't have to worry about this if we checked the top of memory.  Also
-# my BIOS can be configured to put the wini drive tables in high memory
-# instead of in the vector table.  The old stack might have clobbered the
-# drive table.
-
-go:	movw	$0x4000-12, %di		# 0x4000 is an arbitrary value >=
-					# length of bootsect + length of
-					# setup + room for stack;
-					# 12 is disk parm size.
-	movw	%ax, %ds		# %ax and %es already contain INITSEG
+start2:
+	movw	%cs, %ax
+	movw	%ax, %ds
+	movw	%ax, %es
 	movw	%ax, %ss
-	movw	%di, %sp		# put stack at INITSEG:0x4000-12.
+	movw	$0x7c00, %sp
+	sti
+	cld
 
-# Many BIOS's default disk parameter tables will not recognize
-# multi-sector reads beyond the maximum sector number specified
-# in the default diskette parameter tables - this may mean 7
-# sectors in some cases.
-#
-# Since single sector reads are slow and out of the question,
-# we must take care of this by creating new parameter tables
-# (for the first disk) in RAM.  We will set the maximum sector
-# count to 36 - the most we will encounter on an ED 2.88.  
-#
-# High doesn't hurt.  Low does.
-#
-# Segments are as follows: %cs = %ds = %es = %ss = INITSEG, %fs = 0,
-# and %gs is unused.
-
-	movw	%cx, %fs		# %fs = 0
-	movw	$0x78, %bx		# %fs:%bx is parameter table address
-	pushw	%ds
-	ldsw	%fs:(%bx), %si		# %ds:%si is source
-	movb	$6, %cl			# copy 12 bytes
-	pushw	%di			# %di = 0x4000-12.
-	rep				# don't worry about cld
-	movsw				# already done above
-	popw	%di
-	popw	%ds
-	movb	$36, 0x4(%di)		# patch sector count
-	movw	%di, %fs:(%bx)
-	movw	%es, %fs:2(%bx)
-
-# Get disk drive parameters, specifically number of sectors/track.
-
-# It seems that there is no BIOS call to get the number of sectors.
-# Guess 36 sectors if sector 36 can be read, 18 sectors if sector 18
-# can be read, 15 if sector 15 can be read.  Otherwise guess 9.
-# Note that %cx = 0 from rep movsw above.
+	movw	$bugger_off_msg, %si
 
-	movw	$disksizes, %si		# table of sizes to try
-probe_loop:
+msg_loop:
 	lodsb
-	cbtw				# extend to word
-	movw	%ax, sectors
-	cmpw	$disksizes+4, %si
-	jae	got_sectors		# If all else fails, try 9
-
-	xchgw	%cx, %ax		# %cx = track and sector
-	xorw	%dx, %dx		# drive 0, head 0
-	movw	$0x0200, %bx		# address = 512, in INITSEG (%es = %cs)
-	movw	$0x0201, %ax		# service 2, 1 sector
-	int	$0x13
-	jc	probe_loop		# try next value
-
-got_sectors:
-	movb	$0x03, %ah		# read cursor pos
-	xorb	%bh, %bh
-	int	$0x10
-	movw	$9, %cx
-	movb	$0x07, %bl		# page 0, attribute 7 (normal)
-					# %bh is set above; int10 doesn't
-					# modify it
-	movw	$msg1, %bp
-	movw	$0x1301, %ax		# write string, move cursor
-	int	$0x10			# tell the user we're loading..
-
-# Load the setup-sectors directly after the moved bootblock (at 0x90200).
-# We should know the drive geometry to do it, as setup may exceed first
-# cylinder (for 9-sector 360K and 720K floppies).
-
-	movw	$0x0001, %ax		# set sread (sector-to-read) to 1 as
-	movw	$sread, %si		# the boot sector has already been read
-	movw	%ax, (%si)
-
-	call	kill_motor		# reset FDC
-	movw	$0x0200, %bx		# address = 512, in INITSEG
-next_step:
-	movb	setup_sects, %al
-	movw	sectors, %cx
-	subw	(%si), %cx		# (%si) = sread
-	cmpb	%cl, %al
-	jbe	no_cyl_crossing
-	movw	sectors, %ax
-	subw	(%si), %ax		# (%si) = sread
-no_cyl_crossing:
-	call	read_track
-	pushw	%ax			# save it
-	call	set_next		# set %bx properly; it uses %ax,%cx,%dx
-	popw	%ax			# restore
-	subb	%al, setup_sects	# rest - for next step
-	jnz	next_step
-
-	pushw	$SYSSEG
-	popw	%es			# %es = SYSSEG
-	call	read_it
-	call	kill_motor
-	call	print_nl
-
-# After that we check which root-device to use. If the device is
-# defined (!= 0), nothing is done and the given device is used.
-# Otherwise, one of /dev/fd0H2880 (2,32) or /dev/PS0 (2,28) or /dev/at0 (2,8)
-# depending on the number of sectors we pretend to know we have.
-
-# Segments are as follows: %cs = %ds = %ss = INITSEG,
-#	%es = SYSSEG, %fs = 0, %gs is unused.
-
-	movw	root_dev, %ax
-	orw	%ax, %ax
-	jne	root_defined
-
-	movw	sectors, %bx
-	movw	$0x0208, %ax		# /dev/ps0 - 1.2Mb
-	cmpw	$15, %bx
-	je	root_defined
-
-	movb	$0x1c, %al		# /dev/PS0 - 1.44Mb
-	cmpw	$18, %bx
-	je	root_defined
-
-	movb	$0x20, %al		# /dev/fd0H2880 - 2.88Mb
-	cmpw	$36, %bx
-	je	root_defined
-
-	movb	$0, %al			# /dev/fd0 - autodetect
-root_defined:
-	movw	%ax, root_dev
-
-# After that (everything loaded), we jump to the setup-routine
-# loaded directly after the bootblock:
-
-	ljmp	$SETUPSEG, $0
-
-# These variables are addressed via %si register as it gives shorter code.
-
-sread:	.word 0				# sectors read of current track
-head:	.word 0				# current head
-track:	.word 0				# current track
-
-# This routine loads the system at address SYSSEG, making sure
-# no 64kB boundaries are crossed. We try to load it as fast as
-# possible, loading whole tracks whenever we can.
-
-read_it:
-	movw	%es, %ax		# %es = SYSSEG when called
-	testw	$0x0fff, %ax
-die:	jne	die			# %es must be at 64kB boundary
-	xorw	%bx, %bx		# %bx is starting address within segment
-rp_read:
-#ifdef __BIG_KERNEL__			# look in setup.S for bootsect_kludge
-	bootsect_kludge = 0x220		# 0x200 + 0x20 which is the size of the
-	lcall	*bootsect_kludge	# bootsector + bootsect_kludge offset
-#else
-	movw	%es, %ax
-	subw	$SYSSEG, %ax
-	movw	%bx, %cx
-	shr	$4, %cx
-	add	%cx, %ax		# check offset
-#endif
-	cmpw	syssize, %ax		# have we loaded everything yet?
-	jbe	ok1_read
-
-	ret
-
-ok1_read:
-	movw	sectors, %ax
-	subw	(%si), %ax		# (%si) = sread
-	movw	%ax, %cx
-	shlw	$9, %cx
-	addw	%bx, %cx
-	jnc	ok2_read
-
-	je	ok2_read
-
-	xorw	%ax, %ax
-	subw	%bx, %ax
-	shrw	$9, %ax
-ok2_read:
-	call	read_track
-	call	set_next
-	jmp	rp_read
-
-read_track:
-	pusha
-	pusha	
-	movw	$0xe2e, %ax 		# loading... message 2e = .
+	andb	%al, %al
+	jz	die
+	movb	$0xe, %ah
 	movw	$7, %bx
  	int	$0x10
-	popa		
-
-# Accessing head, track, sread via %si gives shorter code.
+	jmp	msg_loop
 
-	movw	4(%si), %dx		# 4(%si) = track
-	movw	(%si), %cx		# (%si)  = sread
-	incw	%cx
-	movb	%dl, %ch
-	movw	2(%si), %dx		# 2(%si) = head
-	movb	%dl, %dh
-	andw	$0x0100, %dx
-	movb	$2, %ah
-	pushw	%dx			# save for error dump
-	pushw	%cx
-	pushw	%bx
-	pushw	%ax
-	int	$0x13
-	jc	bad_rt
-
-	addw	$8, %sp
-	popa
-	ret
-
-set_next:
-	movw	%ax, %cx
-	addw	(%si), %ax		# (%si) = sread
-	cmp	sectors, %ax
-	jne	ok3_set
-	movw	$0x0001, %ax
-	xorw	%ax, 2(%si)		# change head
-	jne	ok4_set
-	incw	4(%si)			# next track
-ok4_set:
+die:
+	# Allow the user to press a key, then reboot
 	xorw	%ax, %ax
-ok3_set:
-	movw	%ax, (%si)		# set sread
-	shlw	$9, %cx
-	addw	%cx, %bx
-	jnc	set_next_fin
-	movw	%es, %ax
-	addb	$0x10, %ah
-	movw	%ax, %es
-	xorw	%bx, %bx
-set_next_fin:
-	ret
-
-bad_rt:
-	pushw	%ax			# save error code
-	call	print_all		# %ah = error, %al = read
-	xorb	%ah, %ah
-	xorb	%dl, %dl
-	int	$0x13
-	addw	$10, %sp
-	popa
-	jmp read_track
-
-# print_all is for debugging purposes.  
-#
-# it will print out all of the registers.  The assumption is that this is
-# called from a routine, with a stack frame like
-#
-#	%dx 
-#	%cx
-#	%bx
-#	%ax
-#	(error)
-#	ret <- %sp
- 
-print_all:
-	movw	$5, %cx			# error code + 4 registers
-	movw	%sp, %bp
-print_loop:
-	pushw	%cx			# save count remaining
-	call	print_nl		# <-- for readability
-	cmpb	$5, %cl
-	jae	no_reg			# see if register name is needed
+	int	$0x16
+	int	$0x19
 	
-	movw	$0xe05 + 'A' - 1, %ax
-	subb	%cl, %al
-	int	$0x10
-	movb	$'X', %al
-	int	$0x10
-	movb	$':', %al
-	int	$0x10
-no_reg:
-	addw	$2, %bp			# next register
-	call	print_hex		# print it
-	popw	%cx
-	loop	print_loop
-	ret
-
-print_nl:
-	movw	$0xe0d, %ax		# CR
-	int	$0x10
-	movb	$0xa, %al		# LF
-	int 	$0x10
-	ret
-
-# print_hex is for debugging purposes, and prints the word
-# pointed to by %ss:%bp in hexadecimal.
-
-print_hex:
-	movw	$4, %cx			# 4 hex digits
-	movw	(%bp), %dx		# load word into %dx
-print_digit:
-	rolw	$4, %dx			# rotate to use low 4 bits
-	movw	$0xe0f, %ax		# %ah = request
-	andb	%dl, %al		# %al = mask for nybble
-	addb	$0x90, %al		# convert %al to ascii hex
-	daa				# in only four instructions!
-	adc	$0x40, %al
-	daa
-	int	$0x10
-	loop	print_digit
-	ret
-
-# This procedure turns off the floppy drive motor, so
-# that we enter the kernel in a known state, and
-# don't have to worry about it later.
-# NOTE: Doesn't save %ax or %dx; do it yourself if you need to.
-
-kill_motor:
-	movw	$0x3f2, %dx
-	xorb	%al, %al
-	outb	%al, %dx
-	ret
-
-sectors:	.word 0
-disksizes:	.byte 36, 18, 15, 9
-msg1:		.byte 13, 10
-		.ascii "Loading"
+	# int 0x19 should never return.  In case it does anyway,
+	# invoke the BIOS reset code...
+	ljmp	$0xf000,$0xfff0
+
+
+bugger_off_msg:
+	.ascii	"Direct booting from floppy is no longer supported.\r\n"
+	.ascii	"Please use a boot loader program instead.\r\n"
+	.ascii	"\n"
+	.ascii	"Remove disk and press any key to reboot . . .\r\n"
+	.byte	0
+
 
-# XXX: This is a fairly snug fit.
+	# Kernel attributes; used by setup
 
-.org 497
+	.org 497
 setup_sects:	.byte SETUPSECTS
 root_flags:	.word ROOT_RDONLY
 syssize:	.word SYSSIZE
diff -Nru a/arch/x86_64/boot/mtools.conf.in b/arch/x86_64/boot/mtools.conf.in
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/boot/mtools.conf.in	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,17 @@
+#
+# mtools configuration file for "make (b)zdisk"
+#
+
+# Actual floppy drive
+drive a:
+  file="/dev/fd0"
+
+# 1.44 MB floppy disk image
+drive v:
+  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=18 filter
+
+# 2.88 MB floppy disk image (mostly for virtual uses)
+drive w:
+  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=36 filter
+
+
diff -Nru a/arch/x86_64/boot/tools/build.c b/arch/x86_64/boot/tools/build.c
--- a/arch/x86_64/boot/tools/build.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/boot/tools/build.c	Fri Feb 14 15:53:09 2003
@@ -150,13 +150,10 @@
 	sz = sb.st_size;
 	fprintf (stderr, "System is %d kB\n", sz/1024);
 	sys_size = (sz + 15) / 16;
-	/* 0x28000*16 = 2.5 MB, conservative estimate for the current maximum */
-	if (sys_size > (is_big_kernel ? 0x28000 : DEF_SYSSIZE))
+	/* 0x40000*16 = 4.0 MB, reasonable estimate for the current maximum */
+	if (sys_size > (is_big_kernel ? 0x40000 : DEF_SYSSIZE))
 		die("System is too big. Try using %smodules.",
 			is_big_kernel ? "" : "bzImage or ");
-	if (sys_size > 0xefff)
-		fprintf(stderr,"warning: kernel is too big for standalone boot "
-		    "from floppy\n");
 	while (sz > 0) {
 		int l, n;
 
diff -Nru a/arch/x86_64/defconfig b/arch/x86_64/defconfig
--- a/arch/x86_64/defconfig	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/defconfig	Fri Feb 14 15:53:12 2003
@@ -5,7 +5,6 @@
 CONFIG_X86=y
 CONFIG_MMU=y
 CONFIG_SWAP=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_X86_CMPXCHG=y
 CONFIG_EARLY_PRINTK=y
@@ -22,12 +21,6 @@
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-# CONFIG_LOG_BUF_SHIFT_17 is not set
-CONFIG_LOG_BUF_SHIFT_16=y
-# CONFIG_LOG_BUF_SHIFT_15 is not set
-# CONFIG_LOG_BUF_SHIFT_14 is not set
-# CONFIG_LOG_BUF_SHIFT_13 is not set
-# CONFIG_LOG_BUF_SHIFT_12 is not set
 CONFIG_LOG_BUF_SHIFT=16
 
 #
@@ -37,6 +30,7 @@
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
 # CONFIG_KMOD is not set
 
 #
@@ -103,6 +97,7 @@
 # CONFIG_BINFMT_MISC is not set
 CONFIG_IA32_EMULATION=y
 CONFIG_COMPAT=y
+CONFIG_UID16=y
 
 #
 # Memory Technology Devices (MTD)
@@ -290,6 +285,7 @@
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
@@ -490,6 +486,7 @@
 # CONFIG_DRM is not set
 # CONFIG_MWAVE is not set
 CONFIG_RAW_DRIVER=y
+# CONFIG_HANGCHECK_TIMER is not set
 
 #
 # Misc devices
@@ -615,7 +612,6 @@
 # CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_CHECKING=y
 # CONFIG_INIT_DEBUG is not set
 CONFIG_KALLSYMS=y
 # CONFIG_FRAME_POINTER is not set
diff -Nru a/arch/x86_64/ia32/fpu32.c b/arch/x86_64/ia32/fpu32.c
--- a/arch/x86_64/ia32/fpu32.c	Fri Feb 14 15:53:08 2003
+++ b/arch/x86_64/ia32/fpu32.c	Fri Feb 14 15:53:08 2003
@@ -146,6 +146,7 @@
 			return -1;
 	} 
 	tsk->thread.i387.fxsave.mxcsr &= 0xffbf;
+	current->used_math = 1;
 	return convert_fxsr_from_user(&tsk->thread.i387.fxsave, buf);
 }  
 
diff -Nru a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
--- a/arch/x86_64/ia32/ia32_signal.c	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/ia32/ia32_signal.c	Fri Feb 14 15:53:12 2003
@@ -22,6 +22,7 @@
 #include <linux/unistd.h>
 #include <linux/stddef.h>
 #include <linux/personality.h>
+#include <linux/compat.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include <asm/i387.h>
@@ -134,7 +135,7 @@
 	int sig;
 	struct sigcontext_ia32 sc;
 	struct _fpstate_ia32 fpstate;
-	unsigned int extramask[_IA32_NSIG_WORDS-1];
+	unsigned int extramask[_COMPAT_NSIG_WORDS-1];
 	char retcode[8];
 };
 
@@ -237,7 +238,7 @@
 	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
 		goto badframe;
 	if (__get_user(set.sig[0], &frame->sc.oldmask)
-	    || (_IA32_NSIG_WORDS > 1
+	    || (_COMPAT_NSIG_WORDS > 1
 		&& __copy_from_user((((char *) &set.sig) + 4), &frame->extramask,
 				    sizeof(frame->extramask))))
 		goto badframe;
@@ -373,7 +374,7 @@
 }
 
 void ia32_setup_frame(int sig, struct k_sigaction *ka,
-			sigset32_t *set, struct pt_regs * regs)
+			compat_sigset_t *set, struct pt_regs * regs)
 {
 	struct sigframe *frame;
 	int err = 0;
@@ -399,7 +400,7 @@
 	if (err)
 		goto give_sigsegv;
 
-	if (_IA32_NSIG_WORDS > 1) {
+	if (_COMPAT_NSIG_WORDS > 1) {
 		err |= __copy_to_user(frame->extramask, &set->sig[1],
 				      sizeof(frame->extramask));
 	}
@@ -460,7 +461,7 @@
 }
 
 void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-			   sigset32_t *set, struct pt_regs * regs)
+			   compat_sigset_t *set, struct pt_regs * regs)
 {
 	struct rt_sigframe *frame;
 	int err = 0;
diff -Nru a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
--- a/arch/x86_64/ia32/ia32entry.S	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/ia32/ia32entry.S	Fri Feb 14 15:53:09 2003
@@ -273,7 +273,7 @@
 	.quad sys_setreuid16	/* 70 */
 	.quad sys_setregid16
 	.quad stub32_sigsuspend
-	.quad sys32_sigpending
+	.quad compat_sys_sigpending
 	.quad sys_sethostname
 	.quad sys32_setrlimit	/* 75 */
 	.quad sys32_old_getrlimit	/* old_getrlimit */
@@ -326,7 +326,7 @@
 	.quad sys32_modify_ldt
 	.quad sys32_adjtimex
 	.quad sys32_mprotect		/* 125 */
-	.quad sys32_sigprocmask
+	.quad compat_sys_sigprocmask
 	.quad sys32_module_warning	/* create_module */
 	.quad sys_init_module
 	.quad sys_delete_module
@@ -450,7 +450,7 @@
 	.quad sys32_io_getevents
 	.quad sys32_io_submit
 	.quad sys_io_cancel
-	.quad sys_ni_syscall /* 250 alloc_huge_pages */
+	.quad sys_fadvise64
 	.quad sys_ni_syscall /* free_huge_pages */
 	.quad sys_exit_group /* exit_group */
 	.quad sys_lookup_dcookie
diff -Nru a/arch/x86_64/ia32/ipc32.c b/arch/x86_64/ia32/ipc32.c
--- a/arch/x86_64/ia32/ipc32.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/ia32/ipc32.c	Fri Feb 14 15:53:09 2003
@@ -626,9 +626,7 @@
 		return -E2BIG;
 	if (!access_ok(VERIFY_READ, sb, nsops * sizeof(struct sembuf)))
 		return -EFAULT; 
-	if (ts32 && 
-	    (get_user(ts.tv_sec, &ts32->tv_sec)  || 
-	     __get_user(ts.tv_nsec, &ts32->tv_nsec)))
+	if (ts32 && get_compat_timespec(&ts, ts32))
 		return -EFAULT;
 
 	set_fs(KERNEL_DS);  
diff -Nru a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
--- a/arch/x86_64/ia32/sys_ia32.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/ia32/sys_ia32.c	Fri Feb 14 15:53:09 2003
@@ -276,10 +276,10 @@
 {
 	struct k_sigaction new_ka, old_ka;
 	int ret;
-	sigset32_t set32;
+	compat_sigset_t set32;
 
 	/* XXX: Don't preclude handling different sized sigset_t's.  */
-	if (sigsetsize != sizeof(sigset32_t))
+	if (sigsetsize != sizeof(compat_sigset_t))
 		return -EINVAL;
 
 	if (act) {
@@ -287,10 +287,10 @@
 		    __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) ||
 		    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
 		    __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer)||
-		    __copy_from_user(&set32, &act->sa_mask, sizeof(sigset32_t)))
+		    __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t)))
 			return -EFAULT;
 
-		/* FIXME: here we rely on _IA32_NSIG_WORS to be >= than _NSIG_WORDS << 1 */
+		/* FIXME: here we rely on _COMPAT_NSIG_WORS to be >= than _NSIG_WORDS << 1 */
 		switch (_NSIG_WORDS) {
 		case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
 				| (((long)set32.sig[7]) << 32);
@@ -306,7 +306,7 @@
 	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 
 	if (!ret && oact) {
-		/* FIXME: here we rely on _IA32_NSIG_WORS to be >= than _NSIG_WORDS << 1 */
+		/* FIXME: here we rely on _COMPAT_NSIG_WORS to be >= than _NSIG_WORDS << 1 */
 		switch (_NSIG_WORDS) {
 		case 4:
 			set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32);
@@ -325,7 +325,7 @@
 		    __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
 		    __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
 		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
-		    __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset32_t)))
+		    __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t)))
 			return -EFAULT;
 	}
 
@@ -339,7 +339,7 @@
         int ret;
 
         if (act) {
-		old_sigset32_t mask;
+		compat_old_sigset_t mask;
 
 		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
 		    __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) ||
@@ -368,16 +368,16 @@
 					  size_t sigsetsize);
 
 asmlinkage long
-sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset,
+sys32_rt_sigprocmask(int how, compat_sigset_t *set, compat_sigset_t *oset,
 		     unsigned int sigsetsize)
 {
 	sigset_t s;
-	sigset32_t s32;
+	compat_sigset_t s32;
 	int ret;
 	mm_segment_t old_fs = get_fs();
 	
 	if (set) {
-		if (copy_from_user (&s32, set, sizeof(sigset32_t)))
+		if (copy_from_user (&s32, set, sizeof(compat_sigset_t)))
 			return -EFAULT;
 		switch (_NSIG_WORDS) {
 		case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
@@ -398,7 +398,7 @@
 		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
 		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
 		}
-		if (copy_to_user (oset, &s32, sizeof(sigset32_t)))
+		if (copy_to_user (oset, &s32, sizeof(compat_sigset_t)))
 			return -EFAULT;
 	}
 	return 0;
@@ -1219,55 +1219,18 @@
 	set_fs (KERNEL_DS);
 	ret = sys_sched_rr_get_interval(pid, &t);
 	set_fs (old_fs);
-	if (verify_area(VERIFY_WRITE, interval, sizeof(struct compat_timespec)) ||
-	    __put_user (t.tv_sec, &interval->tv_sec) ||
-	    __put_user (t.tv_nsec, &interval->tv_nsec))
+	if (put_compat_timespec(&t, interval))
 		return -EFAULT;
 	return ret;
 }
 
-extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set,
-				      old_sigset_t *oset);
-
-asmlinkage long
-sys32_sigprocmask(int how, old_sigset32_t *set, old_sigset32_t *oset)
-{
-	old_sigset_t s;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-	
-	if (set && get_user (s, set)) return -EFAULT;
-	set_fs (KERNEL_DS);
-	ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
-	set_fs (old_fs);
-	if (ret) return ret;
-	if (oset && put_user (s, oset)) return -EFAULT;
-	return 0;
-}
-
-extern asmlinkage long sys_sigpending(old_sigset_t *set);
-
-asmlinkage long
-sys32_sigpending(old_sigset32_t *set)
-{
-	old_sigset_t s;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-		
-	set_fs (KERNEL_DS);
-	ret = sys_sigpending(&s);
-	set_fs (old_fs);
-	if (put_user (s, set)) return -EFAULT;
-	return ret;
-}
-
 extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
 
 asmlinkage long
-sys32_rt_sigpending(sigset32_t *set, compat_size_t sigsetsize)
+sys32_rt_sigpending(compat_sigset_t *set, compat_size_t sigsetsize)
 {
 	sigset_t s;
-	sigset32_t s32;
+	compat_sigset_t s32;
 	int ret;
 	mm_segment_t old_fs = get_fs();
 		
@@ -1281,7 +1244,7 @@
 		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
 		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
 		}
-		if (copy_to_user (set, &s32, sizeof(sigset32_t)))
+		if (copy_to_user (set, &s32, sizeof(compat_sigset_t)))
 			return -EFAULT;
 	}
 	return ret;
@@ -1369,18 +1332,18 @@
 		    const struct timespec *uts, size_t sigsetsize);
 
 asmlinkage long
-sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
+sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo,
 		      struct compat_timespec *uts, compat_size_t sigsetsize)
 {
 	sigset_t s;
-	sigset32_t s32;
+	compat_sigset_t s32;
 	struct timespec t;
 	int ret;
 	mm_segment_t old_fs = get_fs();
 	siginfo_t info;
 	siginfo_t32 info32;
 		
-	if (copy_from_user (&s32, uthese, sizeof(sigset32_t)))
+	if (copy_from_user (&s32, uthese, sizeof(compat_sigset_t)))
 		return -EFAULT;
 	switch (_NSIG_WORDS) {
 	case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
@@ -1388,14 +1351,11 @@
 	case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
 	case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
 	}
-	if (uts) {
-		if (verify_area(VERIFY_READ, uts, sizeof(struct compat_timespec)) ||
-		    __get_user (t.tv_sec, &uts->tv_sec) ||
-		    __get_user (t.tv_nsec, &uts->tv_nsec))
-			return -EFAULT;
-	}
+	if (uts && get_compat_timespec(&t, uts))
+		return -EFAULT;
 	set_fs (KERNEL_DS);
-	ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize);
+	ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL,
+			sigsetsize);
 	set_fs (old_fs);
 	if (ret >= 0 && uinfo) {
 		if (copy_to_user (uinfo, siginfo64to32(&info32, &info),
@@ -2248,20 +2208,13 @@
 	mm_segment_t oldfs = get_fs(); 
 	int err;
 
-	if (utime32) {
-		if (verify_area(VERIFY_READ, utime32, sizeof(*utime32)))
-			return -EFAULT;
-
-		if (__get_user(t.tv_sec, &utime32->tv_sec) ||
-		    __get_user(t.tv_nsec, &utime32->tv_nsec))
-			return -EFAULT;
-		
-	}
+	if (utime32 && get_compat_timespec(&t, utime32))
+		return -EFAULT;
 
 	/* the set_fs is safe because futex doesn't use the seg limit 
 	   for valid page checking of uaddr. */ 
 	set_fs(KERNEL_DS); 
-	err = sys_futex(uaddr, op, val, &t);
+	err = sys_futex(uaddr, op, val, utime32 ? &t : NULL);
 	set_fs(oldfs); 
 	return err; 
 }
@@ -2340,22 +2293,18 @@
 { 	
 	long ret;
 	mm_segment_t oldfs; 
-	struct timespec t32;
+	struct timespec t;
 	/* Harden against bogus ptrace */
 	if (nr >= 0xffffffff || 
 	    !access_ok(VERIFY_WRITE, events, nr * sizeof(struct io_event)))
 		return -EFAULT;
-	if (timeout && 
-	    (get_user(t32.tv_sec, &timeout->tv_sec)  || 
-	     __get_user(t32.tv_nsec, &timeout->tv_nsec)))
+	if (timeout && get_compat_timespec(&t, timeout))
 		return -EFAULT; 
 	oldfs = get_fs();
 	set_fs(KERNEL_DS); 
-	ret = sys_io_getevents(ctx_id,min_nr,nr,events,timeout ? &t32 : NULL); 
+	ret = sys_io_getevents(ctx_id,min_nr,nr,events,timeout ? &t : NULL); 
 	set_fs(oldfs); 
-	if (timeout && 
-	    (__put_user(t32.tv_sec, &timeout->tv_sec) || 
-	     __put_user(t32.tv_nsec, &timeout->tv_nsec)))
+	if (timeout && put_compat_timespec(&t, timeout))
 		return -EFAULT; 		
 	return ret;
 } 
diff -Nru a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
--- a/arch/x86_64/kernel/Makefile	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/kernel/Makefile	Fri Feb 14 15:53:12 2003
@@ -17,7 +17,7 @@
 obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o mpparse.o
 obj-$(CONFIG_SOFTWARE_SUSPEND)	+= suspend.o suspend_asm.o
 obj-$(CONFIG_ACPI)             += acpi.o
-#obj-$(CONFIG_ACPI_SLEEP)       += acpi_wakeup.o
+obj-$(CONFIG_ACPI_SLEEP)       += wakeup.o
 obj-$(CONFIG_EARLY_PRINTK)    += early_printk.o
 obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o
 obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o
diff -Nru a/arch/x86_64/kernel/acpi.c b/arch/x86_64/kernel/acpi.c
--- a/arch/x86_64/kernel/acpi.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/kernel/acpi.c	Fri Feb 14 15:53:09 2003
@@ -44,6 +44,9 @@
 #include <asm/pgalloc.h>
 #include <asm/io_apic.h>
 #include <asm/proto.h>
+#include <asm/desc.h>
+#include <asm/system.h>
+#include <asm/segment.h>
 
 extern int acpi_disabled;
 
@@ -70,7 +73,6 @@
 	if (phys_addr < (end_pfn_map << PAGE_SHIFT)) 
 		return __va(phys_addr); 
 
-	printk("acpi mapping beyond end_pfn: %lx > %lx\n", phys_addr, end_pfn<<PAGE_SHIFT);
 	return NULL; 
 } 	      
 
@@ -292,8 +294,7 @@
 
 
 int __init
-acpi_boot_init (
-	char			*cmdline)
+acpi_boot_init (void)
 {
 	int			result = 0;
 
@@ -306,7 +307,7 @@
 	/* 
 	 * Initialize the ACPI boot-time table parser.
 	 */
-	result = acpi_table_init(cmdline);
+	result = acpi_table_init();
 	if (result)
 		return result;
 
@@ -441,95 +442,41 @@
 
 #ifdef CONFIG_ACPI_SLEEP
 
-#error not ported to x86-64 yet
-
-#ifdef DEBUG
-#include <linux/serial.h>
-#endif
+extern void acpi_prepare_wakeup(void);
+extern unsigned char acpi_wakeup[], acpi_wakeup_end[], s3_prot16[];
 
 /* address in low memory of the wakeup routine. */
-unsigned long acpi_wakeup_address = 0;
-
-/* new page directory that we will be using */
-static pmd_t *pmd;
-
-/* saved page directory */
-static pmd_t saved_pmd;
-
-/* page which we'll use for the new page directory */
-static pte_t *ptep;
-
-extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
-
-/*
- * acpi_create_identity_pmd
- *
- * Create a new, identity mapped pmd.
- *
- * Do this by creating new page directory, and marking all the pages as R/W
- * Then set it as the new Page Middle Directory.
- * And, of course, flush the TLB so it takes effect.
- *
- * We save the address of the old one, for later restoration.
- */
-static void acpi_create_identity_pmd (void)
-{
-	pgd_t *pgd;
-	int i;
-
-	ptep = (pte_t*)__get_free_page(GFP_KERNEL);
-
-	/* fill page with low mapping */
-	for (i = 0; i < PTRS_PER_PTE; i++)
-		set_pte(ptep + i, mk_pte_phys(i << PAGE_SHIFT, PAGE_SHARED));
-
-	pgd = pgd_offset(current->active_mm, 0);
-	pmd = pmd_alloc(current->mm,pgd, 0);
-
-	/* save the old pmd */
-	saved_pmd = *pmd;
-
-	/* set the new one */
-	set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(ptep)));
-
-	/* flush the TLB */
-	local_flush_tlb();
-}
-
-/*
- * acpi_restore_pmd
- *
- * Restore the old pmd saved by acpi_create_identity_pmd and
- * free the page that said function alloc'd
- */
-static void acpi_restore_pmd (void)
-{
-	set_pmd(pmd, saved_pmd);
-	local_flush_tlb();
-	free_page((unsigned long)ptep);
-}
+unsigned long acpi_wakeup_address;
 
 /**
  * acpi_save_state_mem - save kernel state
- *
- * Create an identity mapped page table and copy the wakeup routine to
- * low memory.
  */
 int acpi_save_state_mem (void)
 {
-	acpi_create_identity_pmd();
-	acpi_copy_wakeup_routine(acpi_wakeup_address);
+	if (!acpi_wakeup_address)
+		return -1;
 
+	memcpy((void*)acpi_wakeup_address, acpi_wakeup, acpi_wakeup_end - acpi_wakeup); 
 	return 0;
 }
 
 /**
  * acpi_save_state_disk - save kernel state to disk
  *
+ * Assume preemption/interrupts are already turned off and that we're running
+ * on the BP (note this doesn't imply SMP is handled correctly)
  */
 int acpi_save_state_disk (void)
 {
+	unsigned long pbase = read_cr3() & PAGE_MASK; 
+	if (pbase >= 0xffffffffUL) {
+		printk(KERN_ERR "ACPI: High page table. Suspend disabled.\n");
 	return 1;
+	} 
+	set_seg_base(smp_processor_id(), GDT_ENTRY_KERNELCS16, s3_prot16); 
+	swap_low_mappings();
+	acpi_prepare_wakeup();
+	return 0;
 }
 
 /*
@@ -537,13 +484,13 @@
  */
 void acpi_restore_state_mem (void)
 {
-	acpi_restore_pmd();
+	swap_low_mappings();
 }
 
 /**
  * acpi_reserve_bootmem - do _very_ early ACPI initialisation
  *
- * We allocate a page in low memory for the wakeup
+ * We allocate a page in 1MB low memory for the real-mode wakeup
  * routine for when we come back from a sleep state. The
  * runtime allocator allows specification of <16M pages, but not
  * <1M pages.
@@ -551,7 +498,10 @@
 void __init acpi_reserve_bootmem(void)
 {
 	acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE);
-	printk(KERN_DEBUG "ACPI: have wakeup address 0x%8.8lx\n", acpi_wakeup_address);
+	if (!acpi_wakeup_address) { 
+		printk(KERN_ERR "ACPI: Cannot allocate lowmem. S3 disabled.\n");
+		return;
+	} 
 }
 
 #endif /*CONFIG_ACPI_SLEEP*/
diff -Nru a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
--- a/arch/x86_64/kernel/aperture.c	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/kernel/aperture.c	Fri Feb 14 15:53:12 2003
@@ -57,7 +57,7 @@
 		printk("Cannot allocate aperture memory hole (%p,%uK)\n",
 		       p, aper_size>>10);
 		if (p)
-			free_bootmem((unsigned long)p, aper_size); 
+			free_bootmem_node(nd0, (unsigned long)p, aper_size); 
 		return 0;
 	}
 	printk("Mapping aperture over %d KB of RAM @ %lx\n",  
diff -Nru a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
--- a/arch/x86_64/kernel/apic.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/kernel/apic.c	Fri Feb 14 15:53:09 2003
@@ -1026,7 +1026,7 @@
 	irq_exit();
 }
 
-int disable_apic __initdata; 
+int disable_apic; 
 
 /*
  * This initializes the IO-APIC and APIC hardware if this is
@@ -1038,8 +1038,10 @@
 		printk(KERN_INFO "Apic disabled\n");
 		return -1; 
 	}
-	if (!smp_found_config && !cpu_has_apic)
+	if (!smp_found_config && !cpu_has_apic) { 
+		disable_apic = 1;
 		return -1;
+	} 
 
 	/*
 	 * Complain if the BIOS pretends there is one.
@@ -1047,6 +1049,7 @@
 	if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_id])) {
 		printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
 			boot_cpu_id);
+		disable_apic = 1;
 		return -1;
 	}
 
diff -Nru a/arch/x86_64/kernel/bluesmoke.c b/arch/x86_64/kernel/bluesmoke.c
--- a/arch/x86_64/kernel/bluesmoke.c	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/kernel/bluesmoke.c	Fri Feb 14 15:53:12 2003
@@ -1,5 +1,9 @@
 /*
  * arch/x86_64/kernel/bluesmoke.c - x86-64 Machine Check Exception Reporting
+ * 
+
+RED-PEN: need to add power management to restore after S3 wakeup. 
+
  */
 
 #include <linux/init.h>
diff -Nru a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
--- a/arch/x86_64/kernel/e820.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/kernel/e820.c	Fri Feb 14 15:53:09 2003
@@ -19,13 +19,17 @@
 #include <asm/proto.h>
 #include <asm/bootsetup.h>
 
-extern unsigned long table_start, table_end;
 extern char _end[];
 
 /* 
+ * PFN of last memory page.
+ */
+unsigned long end_pfn; 
+
+/* 
  * end_pfn only includes RAM, while end_pfn_map includes all e820 entries.
  * The direct mapping extends to end_pfn_map, so that we can directly access
- * ACPI and other tables without having to play with fixmaps.
+ * apertures, ACPI and other tables without having to play with fixmaps.
  */ 
 unsigned long end_pfn_map; 
 
@@ -42,18 +46,16 @@
 	unsigned long addr = *addrp, last = addr + size; 
 
 	/* various gunk below that needed for SMP startup */
-	if (addr < 7*PAGE_SIZE) { 
-		*addrp = 7*PAGE_SIZE; 
+	if (addr < 0x8000) { 
+		*addrp = 0x8000;
 		return 1; 
 	}
 
-#if 0
 	/* direct mapping tables of the kernel */
 	if (last >= table_start<<PAGE_SHIFT && addr < table_end<<PAGE_SHIFT) { 
 		*addrp = table_end << PAGE_SHIFT; 
 		return 1;
 	} 
-#endif
 
 	/* initrd */ 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -145,10 +147,10 @@
 /*
  * Find the highest page frame number we have available
  */
-void __init e820_end_of_ram(void)
+unsigned long __init e820_end_of_ram(void)
 {
 	int i;
-	end_pfn = 0;
+	unsigned long end_pfn = 0;
 	
 	for (i = 0; i < e820.nr_map; i++) {
 		struct e820entry *ei = &e820.map[i]; 
@@ -175,6 +177,8 @@
 		end_pfn = end_user_pfn;
 	if (end_pfn > end_pfn_map) 
 		end_pfn = end_pfn_map; 
+
+	return end_pfn;	
 }
 
 /* 
diff -Nru a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
--- a/arch/x86_64/kernel/early_printk.c	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/kernel/early_printk.c	Fri Feb 14 15:53:12 2003
@@ -3,6 +3,7 @@
 #include <linux/init.h>
 #include <linux/string.h>
 #include <asm/io.h>
+#include <asm/processor.h>
 
 /* Simple VGA output */
 
@@ -104,9 +105,9 @@
 	s = strsep(&opt, ","); 
 	if (s != NULL) { 
 		unsigned port; 
-		if (!strncmp(s,"0x",2))
+		if (!strncmp(s,"0x",2)) {
 			early_serial_base = simple_strtoul(s, &e, 16);
-		else {	
+		} else {
 			static int bases[] = { 0x3f8, 0x2f8 };
 		if (!strncmp(s,"ttyS",4)) 
 			s+=4; 
diff -Nru a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
--- a/arch/x86_64/kernel/entry.S	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/kernel/entry.S	Fri Feb 14 15:53:09 2003
@@ -512,8 +512,7 @@
  * Exception entry point. This expects an error code/orig_rax on the stack
  * and the exception handler in %rax.	
  */ 		  				
- 	ALIGN
-error_entry:
+ENTRY(error_entry)
 	/* rdi slot contains rax, oldrax contains error code */
 	pushq %rsi
 	movq  8(%rsp),%rsi	/* load rax */
@@ -532,10 +531,7 @@
 	xorl %ebx,%ebx	
 	swapgs
 error_sti:	
-	bt $9,EFLAGS(%rsp)
-	jnc 1f
-	sti
-1:	movq %rdi,RDI(%rsp) 	
+	movq %rdi,RDI(%rsp) 	
 	movq %rsp,%rdi
 	movq ORIG_RAX(%rsp),%rsi	/* get error code */ 
 	movq $-1,ORIG_RAX(%rsp)
@@ -573,7 +569,8 @@
         swapgs
 gs_change:     
         movl %edi,%gs   
-2:      swapgs
+2:	sfence		/* workaround */
+	swapgs
         popf
         ret
        
diff -Nru a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S
--- a/arch/x86_64/kernel/head.S	Fri Feb 14 15:53:11 2003
+++ b/arch/x86_64/kernel/head.S	Fri Feb 14 15:53:11 2003
@@ -72,8 +72,7 @@
 	/* Setup EFER (Extended Feature Enable Register) */
 	movl	$MSR_EFER, %ecx
 	rdmsr
-	/* Fool rdmsr and reset %eax to avoid dependences */
-	xorl	%eax, %eax
+
 	/* Enable Long Mode */
 	btsl	$_EFER_LME, %eax
 	/* Enable System Call */
@@ -112,7 +111,6 @@
 	jnz   second	
 	
 	/* Load new GDT with the 64bit segment using 32bit descriptor */
-	/* to avoid 32bit relocations we use fixed adresses here */
 	movl	$(pGDT32 - __START_KERNEL_map), %eax
 	lgdt	(%eax)
 
@@ -349,17 +347,14 @@
 	.quad	0x00cffe000000ffff	/* __USER32_CS */
 	.quad	0x00cff2000000ffff	/* __USER_DS, __USER32_DS  */		
 	.quad	0x00affa000000ffff	/* __USER_CS */
-	.word	0xFFFF				# 4Gb - (0x100000*0x1000 = 4Gb)
-	.word	0				# base address = 0
-	.word	0x9A00				# code read/exec
-	.word	0x00CF				# granularity = 4096, 386
-						#  (+5th nibble of limit)
-					/* __KERNEL32_CS */
+	.quad	0x00cf9a000000ffff	/* __KERNEL32_CS */
 	.quad	0,0			/* TSS */
 	.quad	0			/* LDT */
 	.quad   0,0,0			/* three TLS descriptors */ 
-	.quad	0x00cff2000000ffff	/* dummy descriptor for long base */
-	.quad	0			/* pad to cache line boundary */
+	.quad	0			/* unused now */
+	.quad	0x00009a000000ffff	/* __KERNEL16_CS - 16bit PM for S3 wakeup. */
+					/* base must be patched for real base address. */
+	/* This should be a multiple of the cache line size */
 gdt_end:	
 	.globl gdt_end
 
diff -Nru a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
--- a/arch/x86_64/kernel/head64.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/kernel/head64.c	Fri Feb 14 15:53:09 2003
@@ -13,6 +13,8 @@
 #include <linux/string.h>
 
 #include <asm/processor.h>
+#include <asm/proto.h>
+#include <asm/smp.h>
 
 /* Don't add a printk in there. printk relies on the PDA which is not initialized 
    yet. */
@@ -70,9 +72,6 @@
 	boot_cpu_data.x86_mask = eax & 0xf;
 }
 
-extern void start_kernel(void), pda_init(int), setup_early_printk(char *); 
-extern int disable_apic;
-
 void __init x86_64_start_kernel(char * real_mode_data)
 {
 	char *s;
@@ -83,6 +82,11 @@
 	s = strstr(saved_command_line, "earlyprintk="); 
 	if (s != NULL)
 		setup_early_printk(s+12); 
+#ifdef CONFIG_DISCONTIGMEM
+	s = strstr(saved_command_line, "numa=");
+	if (s != NULL)
+		numa_setup(s+5);
+#endif
 #ifdef CONFIG_X86_IO_APIC
 	if (strstr(saved_command_line, "disableapic"))
 		disable_apic = 1;
diff -Nru a/arch/x86_64/kernel/init_task.c b/arch/x86_64/kernel/init_task.c
--- a/arch/x86_64/kernel/init_task.c	Fri Feb 14 15:53:10 2003
+++ b/arch/x86_64/kernel/init_task.c	Fri Feb 14 15:53:10 2003
@@ -11,6 +11,7 @@
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
 struct mm_struct init_mm = INIT_MM(init_mm);
 
 /*
diff -Nru a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
--- a/arch/x86_64/kernel/irq.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/kernel/irq.c	Fri Feb 14 15:53:09 2003
@@ -137,7 +137,8 @@
 	struct irqaction * action;
 
 	seq_printf(p, "           ");
-	for_each_cpu(j) 
+	for (j=0; j<NR_CPUS; j++)
+		if (cpu_online(j))
 		seq_printf(p, "CPU%d       ",j);
 	seq_putc(p, '\n');
 
@@ -149,7 +150,8 @@
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
-		for_each_cpu(j) 
+		for (j=0; j<NR_CPUS; j++)
+			if (cpu_online(j))
 			seq_printf(p, "%10u ",
 				kstat_cpu(j).irqs[i]);
 #endif
@@ -161,12 +163,14 @@
 		seq_putc(p, '\n');
 	}
 	seq_printf(p, "NMI: ");
-	for_each_cpu(j)
+	for (j = 0; j < NR_CPUS; j++)
+		if (cpu_online(j))
 		seq_printf(p, "%10u ", cpu_pda[j].__nmi_count);
 	seq_putc(p, '\n');
 #if CONFIG_X86_LOCAL_APIC
 	seq_printf(p, "LOC: ");
-	for_each_cpu(j)
+	for (j = 0; j < NR_CPUS; j++)
+		if (cpu_online(j))
 		seq_printf(p, "%10u ", cpu_pda[j].apic_timer_irqs);
 	seq_putc(p, '\n');
 #endif
diff -Nru a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c
--- a/arch/x86_64/kernel/module.c	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/kernel/module.c	Fri Feb 14 15:53:12 2003
@@ -31,6 +31,11 @@
 
 #define DEBUGP(fmt...) 
  
+/* TODO this should be in vmlist, but we must fix get_vm_area first to 
+   handle out of bounds entries properly. 
+   Also need to fix /proc/kcore, /dev/kmem */
+static struct vm_struct *mod_vmlist;
+
 void module_free(struct module *mod, void *module_region)
 {
 	struct vm_struct **prevp, *map;
@@ -40,7 +45,7 @@
 	if (!addr)
 		return;
 	write_lock(&vmlist_lock); 
-	for (prevp = &vmlist ; (map = *prevp) ; prevp = &map->next) {
+	for (prevp = &mod_vmlist ; (map = *prevp) ; prevp = &map->next) {
 		if ((unsigned long)map->addr == addr) {
 			*prevp = map->next;
 			write_unlock(&vmlist_lock); 
@@ -81,7 +86,7 @@
 
 	write_lock(&vmlist_lock);
 	addr = (void *) MODULES_VADDR;
-	for (p = &vmlist; (tmp = *p); p = &tmp->next) {
+	for (p = &mod_vmlist; (tmp = *p); p = &tmp->next) {
 		void *next; 
 		DEBUGP("vmlist %p %lu addr %p\n", tmp->addr, tmp->size, addr);
 		if (size + (unsigned long) addr + PAGE_SIZE < (unsigned long) tmp->addr)
diff -Nru a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
--- a/arch/x86_64/kernel/mpparse.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/kernel/mpparse.c	Fri Feb 14 15:53:09 2003
@@ -29,6 +29,7 @@
 #include <asm/mpspec.h>
 #include <asm/pgalloc.h>
 #include <asm/io_apic.h>
+#include <asm/proto.h>
 
 /* Have we found an MP table */
 int smp_found_config;
@@ -83,7 +84,6 @@
  * Intel MP BIOS table parsing routines:
  */
 
-#ifndef CONFIG_X86_VISWS_APIC
 /*
  * Checksum an MP configuration block.
  */
@@ -582,9 +582,9 @@
 			smp_found_config = 1;
 			printk("found SMP MP-table at %08lx\n",
 						virt_to_phys(mpf));
-			reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE);
+			reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE);
 			if (mpf->mpf_physptr)
-				reserve_bootmem(mpf->mpf_physptr, PAGE_SIZE);
+				reserve_bootmem_generic(mpf->mpf_physptr, PAGE_SIZE);
 			mpf_found = mpf;
 			return 1;
 		}
@@ -632,37 +632,13 @@
 		printk(KERN_WARNING "WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.kernel.org if you experience SMP problems!\n");
 }
 
-#else
-
-/*
- * The Visual Workstation is Intel MP compliant in the hardware
- * sense, but it doesnt have a BIOS(-configuration table).
- * No problem for Linux.
- */
-void __init find_visws_smp(void)
-{
-	smp_found_config = 1;
-
-	phys_cpu_present_map |= 2; /* or in id 1 */
-	apic_version[1] |= 0x10; /* integrated APIC */
-	apic_version[0] |= 0x10;
-
-	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-}
-
-#endif
-
 /*
  * - Intel MP Configuration Table
- * - or SGI Visual Workstation configuration
  */
 void __init find_smp_config (void)
 {
 #ifdef CONFIG_X86_LOCAL_APIC
 	find_intel_smp();
-#endif
-#ifdef CONFIG_VISWS
-	find_visws_smp();
 #endif
 }
 
diff -Nru a/arch/x86_64/kernel/msr.c b/arch/x86_64/kernel/msr.c
--- a/arch/x86_64/kernel/msr.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/kernel/msr.c	Fri Feb 14 15:53:09 2003
@@ -22,6 +22,9 @@
  *
  * This driver uses /dev/cpu/%d/msr where %d is the minor number, and on
  * an SMP box will direct the access to CPU %d.
+
+RED-PEN: need to get power management for S3 restore
+
  */
 
 #include <linux/module.h>
diff -Nru a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
--- a/arch/x86_64/kernel/nmi.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/kernel/nmi.c	Fri Feb 14 15:53:09 2003
@@ -24,6 +24,7 @@
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
 #include <asm/nmi.h>
+#include <asm/msr.h>
 
 extern void default_do_nmi(struct pt_regs *);
 
@@ -71,13 +72,14 @@
 
 	printk(KERN_INFO "testing NMI watchdog ... ");
 
-	for_each_cpu(cpu) { 
+	for (cpu = 0; cpu < NR_CPUS; cpu++)
 		counts[cpu] = cpu_pda[cpu].__nmi_count; 
-	}
 	local_irq_enable();
 	mdelay((10*1000)/nmi_hz); // wait 10 ticks
 
-	for_each_cpu(cpu) { 
+	for (cpu = 0; cpu < NR_CPUS; cpu++) {
+		if (!cpu_online(cpu))
+			continue;
 		if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) {
 			printk("CPU#%d: NMI appears to be stuck (%d)!\n", 
 			       cpu,
@@ -173,7 +175,7 @@
  * Original code written by Keith Owens.
  */
 
-static void __pminit setup_k7_watchdog(void)
+static void setup_k7_watchdog(void)
 {
 	int i;
 	unsigned int evntsel;
@@ -183,8 +185,10 @@
 	nmi_perfctr_msr = MSR_K7_PERFCTR0;
 
 	for(i = 0; i < 4; ++i) {
-		wrmsr(MSR_K7_EVNTSEL0+i, 0, 0);
-		wrmsr(MSR_K7_PERFCTR0+i, 0, 0);
+		/* Simulator may not support it */
+		if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL))
+			return;
+		wrmsrl(MSR_K7_PERFCTR0+i, 0UL);
 	}
 
 	evntsel = K7_EVNTSEL_INT
@@ -200,15 +204,11 @@
 	wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
 }
 
-void __pminit setup_apic_nmi_watchdog (void)
+void setup_apic_nmi_watchdog (void)
 {
 	switch (boot_cpu_data.x86_vendor) {
 	case X86_VENDOR_AMD:
 		if (boot_cpu_data.x86 < 6)
-			return;
-		/* Simics masquerades as AMD, but does not support 
-		   performance counters */
-		if (strstr(boot_cpu_data.x86_model_id, "Screwdriver"))
 			return;
 		setup_k7_watchdog();
 		break;
diff -Nru a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
--- a/arch/x86_64/kernel/process.c	Fri Feb 14 15:53:08 2003
+++ b/arch/x86_64/kernel/process.c	Fri Feb 14 15:53:08 2003
@@ -366,12 +366,15 @@
 		   also reload when it has changed. 
 		   when prev process used 64bit base always reload
 		   to avoid an information leak. */
-		if (unlikely((fsindex | next->fsindex) || prev->fs))
+		if (unlikely(fsindex | next->fsindex | prev->fs)) {
 			loadsegment(fs, next->fsindex);
-		/* check if the user changed the selector
-		   if yes clear 64bit base. */
-		if (unlikely(fsindex != prev->fsindex))
+			/* check if the user used a selector != 0
+	                 * if yes clear 64bit base, since overloaded base
+                         * is always mapped to the Null selector
+                         */
+			if (fsindex)
 			prev->fs = 0;				
+		}
 		/* when next process has a 64bit base use it */
 		if (next->fs) 
 			wrmsrl(MSR_FS_BASE, next->fs); 
@@ -380,10 +383,11 @@
 	{ 
 		unsigned gsindex;
 		asm volatile("movl %%gs,%0" : "=g" (gsindex)); 
-		if (unlikely((gsindex | next->gsindex) || prev->gs))
+		if (unlikely(gsindex | next->gsindex | prev->gs)) {
 			load_gs_index(next->gsindex);
-		if (unlikely(gsindex != prev->gsindex)) 
+			if (gsindex)
 			prev->gs = 0;				
+		}
 		if (next->gs)
 			wrmsrl(MSR_KERNEL_GS_BASE, next->gs); 
 		prev->gsindex = gsindex;
@@ -537,29 +541,23 @@
 
 	switch (code) { 
 	case ARCH_SET_GS:
-#if 1
-		/* For now. We still have one unsolved bug in long gs base context
-		   switch handling. */
-		return -EINVAL; 
-#else
 		if (addr >= TASK_SIZE) 
 			return -EPERM; 
 		get_cpu();
-		load_gs_index(__USER_LONGBASE);
-		current->thread.gsindex = __USER_LONGBASE;
+		load_gs_index(0);
+		current->thread.gsindex = 0;
 		current->thread.gs = addr;
 		ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); 
 		put_cpu();
 		break;
-#endif
 	case ARCH_SET_FS:
 		/* Not strictly needed for fs, but do it for symmetry
 		   with gs */
 		if (addr >= TASK_SIZE)
 			return -EPERM; 
 		get_cpu();
-		asm volatile("movl %0,%%fs" :: "r" (__USER_LONGBASE));
-		current->thread.fsindex = __USER_LONGBASE;
+		asm volatile("movl %0,%%fs" :: "r" (0));
+		current->thread.fsindex = 0;
 		current->thread.fs = addr;
 		ret = checking_wrmsrl(MSR_FS_BASE, addr); 
 		put_cpu();
diff -Nru a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
--- a/arch/x86_64/kernel/setup.c	Fri Feb 14 15:53:08 2003
+++ b/arch/x86_64/kernel/setup.c	Fri Feb 14 15:53:08 2003
@@ -38,6 +38,7 @@
 #include <linux/seq_file.h>
 #include <linux/root_dev.h>
 #include <linux/pci.h>
+#include <linux/acpi.h>
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -53,6 +54,8 @@
 #include <asm/smp.h>
 #include <asm/proto.h>
 
+#define Dprintk(x...) printk(x)
+
 /*
  * Machine setup..
  */
@@ -236,6 +239,8 @@
 {
 	int i;
 
+	Dprintk("setup_arch\n");
+
  	ROOT_DEV = ORIG_ROOT_DEV;
  	drive_info = DRIVE_INFO;
  	screen_info = SCREEN_INFO;
@@ -263,34 +268,34 @@
 
 	parse_cmdline_early(cmdline_p);
 
-#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
-
-#define MAXMEM		(120UL * 1024 * 1024 * 1024 * 1024)  /* 120TB */ 
-#define MAXMEM_PFN	PFN_DOWN(MAXMEM)
-#define MAX_NONPAE_PFN	(1 << 20)
-
 	/*
 	 * partially used pages are not usable - thus
 	 * we are rounding upwards:
 	 */
-	start_pfn = PFN_UP(__pa_symbol(&_end));
-
-	e820_end_of_ram();
+	end_pfn = e820_end_of_ram();
 
 	init_memory_mapping(); 
 
+#ifdef CONFIG_DISCONTIGMEM
+	numa_initmem_init(0, end_pfn); 
+#else
 	contig_initmem_init(); 
+#endif
+
+	/* Reserve direct mapping */
+	reserve_bootmem_generic(table_start << PAGE_SHIFT, 
+				(table_end - table_start) << PAGE_SHIFT);
 
 	/* reserve kernel */
-	reserve_bootmem(HIGH_MEMORY, PFN_PHYS(start_pfn) - HIGH_MEMORY); 
+	unsigned long kernel_end;
+	kernel_end = round_up(__pa_symbol(&_end),PAGE_SIZE);
+	reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY);
 
 	/*
 	 * reserve physical page 0 - it's a special BIOS page on many boxes,
 	 * enabling clean reboots, SMP operation, laptop functions.
 	 */
-	reserve_bootmem(0, PAGE_SIZE);
+	reserve_bootmem_generic(0, PAGE_SIZE);
 
 #ifdef CONFIG_SMP
 	/*
@@ -298,8 +303,12 @@
 	 * FIXME: Don't need the extra page at 4K, but need to fix
 	 * trampoline before removing it. (see the GDT stuff)
 	 */
-	reserve_bootmem(PAGE_SIZE, PAGE_SIZE);
+	reserve_bootmem_generic(PAGE_SIZE, PAGE_SIZE);
+
+	/* Reserve SMP trampoline */
+	reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, PAGE_SIZE);
 #endif
+
 #ifdef CONFIG_ACPI_SLEEP
        /*
         * Reserve low memory region for sleep support.
@@ -315,7 +324,7 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (LOADER_TYPE && INITRD_START) {
 		if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) {
-			reserve_bootmem(INITRD_START, INITRD_SIZE);
+			reserve_bootmem_generic(INITRD_START, INITRD_SIZE);
 			initrd_start =
 				INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
 			initrd_end = initrd_start+INITRD_SIZE;
@@ -330,14 +339,6 @@
 	}
 #endif
 
-	/*
-	 * NOTE: before this point _nobody_ is allowed to allocate
-	 * any memory using the bootmem allocator.
-	 */
-
-#ifdef CONFIG_SMP
-	smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
-#endif
 	paging_init();
 #ifdef CONFIG_ACPI_BOOT
        /*
@@ -347,7 +348,7 @@
         * of MADT).
         */
 	if (!acpi_disabled)
-       acpi_boot_init(*cmdline_p);
+		acpi_boot_init();
 #endif
 #ifdef CONFIG_X86_LOCAL_APIC
 	/*
diff -Nru a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
--- a/arch/x86_64/kernel/setup64.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/kernel/setup64.c	Fri Feb 14 15:53:09 2003
@@ -1,7 +1,7 @@
 /* 
  * X86-64 specific CPU setup.
  * Copyright (C) 1995  Linus Torvalds
- * Copyright 2001, 2002 SuSE Labs / Andi Kleen.
+ * Copyright 2001, 2002, 2003 SuSE Labs / Andi Kleen.
  * See setup.c for older changelog.
  * $Id: setup64.c,v 1.12 2002/03/21 10:09:17 ak Exp $
  */ 
@@ -90,6 +90,17 @@
         pml4_t *level4;
 	struct x8664_pda *pda = &cpu_pda[cpu];
 
+	/* Setup up data that may be needed in __get_free_pages early */
+	asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0)); 
+	wrmsrl(MSR_GS_BASE, cpu_pda + cpu);
+
+	pda->me = pda;
+	pda->cpunumber = cpu; 
+	pda->irqcount = -1;
+	pda->cpudata_offset = 0;
+	pda->kernelstack = 
+		(unsigned long)current_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; 
+
 	if (cpu == 0) {
 		/* others are initialized in smpboot.c */
 		pda->pcurrent = &init_task;
@@ -112,18 +123,8 @@
 	asm volatile("movq %0,%%cr3" :: "r" (__pa(level4))); 
 
 	pda->irqstackptr += IRQSTACKSIZE-64;
-	pda->cpunumber = cpu; 
-	pda->irqcount = -1;
-	pda->kernelstack = 
-		(unsigned long)stack_thread_info() - PDA_STACKOFFSET + THREAD_SIZE; 
-	pda->me = pda;
-	pda->cpudata_offset = 0;
-
 	pda->active_mm = &init_mm;
 	pda->mmu_state = 0;
-	
-	asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0)); 
-	wrmsrl(MSR_GS_BASE, cpu_pda + cpu);
 } 
 
 #define EXCEPTION_STK_ORDER 0 /* >= N_EXCEPTION_STACKS*EXCEPTION_STKSZ */
@@ -150,10 +151,10 @@
 
 	/* CPU 0 is initialised in head64.c */
 	if (cpu != 0) {
+		pda_init(cpu);
 		estacks = (char *)__get_free_pages(GFP_ATOMIC, 0); 
 		if (!estacks)
 			panic("Can't allocate exception stacks for CPU %d\n",cpu);
-		pda_init(cpu);  
 	} else 
 		estacks = boot_exception_stacks; 
 
diff -Nru a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
--- a/arch/x86_64/kernel/signal.c	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/kernel/signal.c	Fri Feb 14 15:53:12 2003
@@ -353,7 +353,7 @@
 handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
 	struct pt_regs * regs)
 {
-	struct k_sigaction *ka = &current->sig->action[sig-1];
+	struct k_sigaction *ka = &current->sighand->action[sig-1];
 
 #if DEBUG_SIG
 	printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n", current->pid, sig, 
@@ -437,7 +437,7 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, regs);
+	signr = get_signal_to_deliver(&info, regs, NULL);
 	if (signr > 0) {
 		/* Reenable any watchpoints before delivering the
 		 * signal to user space. The processor register will
diff -Nru a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
--- a/arch/x86_64/kernel/smp.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/kernel/smp.c	Fri Feb 14 15:53:09 2003
@@ -3,6 +3,7 @@
  *
  *	(c) 1995 Alan Cox, Building #3 <alan@redhat.com>
  *	(c) 1998-99, 2000 Ingo Molnar <mingo@redhat.com>
+ *      (c) 2002,2003 Andi Kleen, SuSE Labs.
  *
  *	This code is released under the GNU General Public License version 2 or
  *	later.
@@ -491,3 +492,24 @@
 	}
 }
 
+
+/* Slow. Should be only used for debugging. */
+int slow_smp_processor_id(void)
+{ 
+	int stack_location;
+	unsigned long sp = (unsigned long)&stack_location; 
+	int cpu;
+	unsigned long mask;
+
+	for_each_cpu(cpu, mask) { 
+		if (sp >= (u64)cpu_pda[cpu].irqstackptr - IRQSTACKSIZE && 
+		    sp <= (u64)cpu_pda[cpu].irqstackptr)
+			return cpu;
+
+		unsigned long estack = init_tss[cpu].ist[0] - EXCEPTION_STKSZ;
+		if (sp >= estack && sp <= estack+(1<<(PAGE_SHIFT+EXCEPTION_STK_ORDER)))
+			return cpu;			
+	}
+
+	return stack_smp_processor_id();
+} 
diff -Nru a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
--- a/arch/x86_64/kernel/smpboot.c	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/kernel/smpboot.c	Fri Feb 14 15:53:12 2003
@@ -51,13 +51,10 @@
 #include <asm/kdebug.h>
 #include <asm/tlbflush.h>
 
-/* Bitmask of currently online CPUs */
-unsigned long cpu_online_map;
+extern int disable_apic;
 
-/* which CPU (physical APIC ID) maps to which logical CPU number */
-volatile int x86_apicid_to_cpu[NR_CPUS];
-/* which logical CPU number maps to which CPU (physical APIC ID) */
-volatile int x86_cpu_to_apicid[NR_CPUS];
+/* Bitmask of currently online CPUs */
+unsigned long cpu_online_map = 1;
 
 static volatile unsigned long cpu_callin_map;
 volatile unsigned long cpu_callout_map;
@@ -75,7 +72,6 @@
 
 extern unsigned char trampoline_data [];
 extern unsigned char trampoline_end  [];
-static unsigned char *trampoline_base;
 
 /*
  * Currently trivial. Write the real->protected mode
@@ -85,25 +81,11 @@
 
 static unsigned long __init setup_trampoline(void)
 {
+	void *tramp = __va(SMP_TRAMPOLINE_BASE); 
 	extern volatile __u32 tramp_gdt_ptr; 
 	tramp_gdt_ptr = __pa_symbol(&cpu_gdt_table); 
-	memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data);
-	return virt_to_phys(trampoline_base);
-}
-
-/*
- * We are called very early to get the low memory for the
- * SMP bootup trampoline page.
- */
-void __init smp_alloc_memory(void)
-{
-	trampoline_base = (void *) alloc_bootmem_low_pages(PAGE_SIZE);
-	/*
-	 * Has to be in very low memory so we can execute
-	 * real-mode AP code.
-	 */
-	if (__pa(trampoline_base) >= 0x9F000)
-		BUG();
+	memcpy(tramp, trampoline_data, trampoline_end - trampoline_data);
+	return virt_to_phys(tramp);
 }
 
 /*
@@ -174,6 +156,7 @@
 		 */
 		atomic_inc(&tsc_count_start);
 
+		sync_core();
 		rdtscll(tsc_values[smp_processor_id()]);
 		/*
 		 * We clear the TSC in the last loop:
@@ -245,6 +228,7 @@
 		atomic_inc(&tsc_count_start);
 		while (atomic_read(&tsc_count_start) != num_booting_cpus()) mb();
 
+		sync_core();
 		rdtscll(tsc_values[smp_processor_id()]);
 		if (i == NR_LOOPS-1)
 			write_tsc(0, 0);
@@ -369,6 +353,9 @@
 	cpu_init();
 	smp_callin();
 
+	/* otherwise gcc will move up the smp_processor_id before the cpu_init */
+	barrier();
+
 	Dprintk("cpu %d: waiting for commence\n", smp_processor_id()); 
 	while (!test_bit(smp_processor_id(), &smp_commenced_mask))
 		rep_nop();
@@ -620,8 +607,6 @@
 	 */
 	init_idle(idle,cpu);
 
-	x86_cpu_to_apicid[cpu] = apicid;
-	x86_apicid_to_cpu[apicid] = cpu;
 	idle->thread.rip = (unsigned long)start_secondary;
 //	idle->thread.rsp = (unsigned long)idle->thread_info + THREAD_SIZE - 512;
 
@@ -713,8 +698,6 @@
 		}
 	}
 	if (boot_error) {
-		x86_cpu_to_apicid[cpu] = -1;
-		x86_apicid_to_cpu[apicid] = -1;
 		clear_bit(cpu, &cpu_callout_map); /* was set here (do_boot_cpu()) */
 		clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
 		cpucount--;
@@ -777,22 +760,12 @@
 	int apicid, cpu;
 
 	/*
-	 * Initialize the logical to physical CPU number mapping
-	 */
-
-	for (apicid = 0; apicid < NR_CPUS; apicid++) {
-		x86_apicid_to_cpu[apicid] = -1;
-	}
-
-	/*
 	 * Setup boot CPU information
 	 */
 	smp_store_cpu_info(0); /* Final full version of the data */
 	printk("CPU%d: ", 0);
 	print_cpu_info(&cpu_data[0]);
 
-	x86_apicid_to_cpu[boot_cpu_id] = 0;
-	x86_cpu_to_apicid[0] = boot_cpu_id;
 	current_thread_info()->cpu = 0;
 	smp_tune_scheduling();
 
@@ -837,6 +810,7 @@
 		io_apic_irqs = 0;
 		cpu_online_map = phys_cpu_present_map = 1;
 		phys_cpu_present_map = 1;
+		disable_apic = 1;
 		return;
 	}
 
@@ -851,6 +825,7 @@
 		io_apic_irqs = 0;
 		cpu_online_map = phys_cpu_present_map = 1;
 		phys_cpu_present_map = 1;
+		disable_apic = 1;
 		return;
 	}
 
@@ -878,13 +853,6 @@
 			continue;
 
 		do_boot_cpu(apicid);
-
-		/*
-		 * Make sure we unmap all failed CPUs
-		 */
-		if ((x86_apicid_to_cpu[apicid] == -1) &&
-				(phys_cpu_present_map & (1 << apicid)))
-			printk("phys CPU #%d not responding - cannot use it.\n",apicid);
 	}
 
 	/*
diff -Nru a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
--- a/arch/x86_64/kernel/sys_x86_64.c	Fri Feb 14 15:53:11 2003
+++ b/arch/x86_64/kernel/sys_x86_64.c	Fri Feb 14 15:53:11 2003
@@ -55,7 +55,6 @@
 		if (!file)
 			goto out;
 	}
-
 	down_write(&current->mm->mmap_sem);
 	error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT);
 	up_write(&current->mm->mmap_sem);
diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
--- a/arch/x86_64/kernel/time.c	Fri Feb 14 15:53:11 2003
+++ b/arch/x86_64/kernel/time.c	Fri Feb 14 15:53:11 2003
@@ -9,6 +9,7 @@
  *  Copyright (c) 1996  Ingo Molnar
  *  Copyright (c) 1998  Andrea Arcangeli
  *  Copyright (c) 2002  Vojtech Pavlik
+ *  Copyright (c) 2003  Andi Kleen
  *
  */
 
@@ -25,9 +26,14 @@
 #include <linux/bcd.h>
 #include <asm/vsyscall.h>
 #include <asm/timex.h>
+#ifdef CONFIG_X86_LOCAL_APIC
+#include <asm/apic.h>
+#endif
 
 u64 jiffies_64; 
 
+extern int using_apic_timer;
+
 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
 
 extern int using_apic_timer;
@@ -56,12 +62,10 @@
  * together by xtime_lock.
          */
 
-static spinlock_t time_offset_lock = SPIN_LOCK_UNLOCKED;
-static unsigned long timeoffset = 0;
-
 inline unsigned int do_gettimeoffset(void)
 {
 	unsigned long t;
+	sync_core();
 	rdtscll(t);	
 	return (t  - hpet.last_tsc) * (1000000L / HZ) / hpet.ticks + hpet.offset;
 }
@@ -74,10 +78,9 @@
 
 void do_gettimeofday(struct timeval *tv)
 {
-	unsigned long flags, t, seq;
+	unsigned long seq, t;
  	unsigned int sec, usec;
 
-	spin_lock_irqsave(&time_offset_lock, flags);
 	do {
 		seq = read_seqbegin(&xtime_lock);
 
@@ -85,11 +88,9 @@
 		usec = xtime.tv_nsec / 1000;
 
 		t = (jiffies - wall_jiffies) * (1000000L / HZ) + do_gettimeoffset();
-		if (t > timeoffset) timeoffset = t;
-		usec += timeoffset;
+		usec += t;
 
 	} while (read_seqretry(&xtime_lock, seq));
-	spin_unlock_irqrestore(&time_offset_lock, flags);
 
 	tv->tv_sec = sec + usec / 1000000;
 	tv->tv_usec = usec % 1000000;
@@ -104,7 +105,6 @@
 void do_settimeofday(struct timeval *tv)
 {
 	write_seqlock_irq(&xtime_lock);
-	vxtime_lock();
 
 	tv->tv_usec -= do_gettimeoffset() +
 		(jiffies - wall_jiffies) * tick_usec;
@@ -116,7 +116,6 @@
 
 	xtime.tv_sec = tv->tv_sec;
 	xtime.tv_nsec = (tv->tv_usec * 1000);
-	vxtime_unlock();
 
 	time_adjust = 0;		/* stop active adjtime() */
 	time_status |= STA_UNSYNC;
@@ -207,11 +206,11 @@
 	 */
 
 	write_seqlock(&xtime_lock);
-	vxtime_lock();
 
 	{
 		unsigned long t;
 
+		sync_core();
 		rdtscll(t);
 		hpet.offset = (t  - hpet.last_tsc) * (1000000L / HZ) / hpet.ticks + hpet.offset - 1000000L / HZ;
 		if (hpet.offset >= 1000000L / HZ)
@@ -219,7 +218,6 @@
 		hpet.ticks = min_t(long, max_t(long, (t  - hpet.last_tsc) * (1000000L / HZ) / (1000000L / HZ - hpet.offset),
 				cpu_khz * 1000/HZ * 15 / 16), cpu_khz * 1000/HZ * 16 / 15); 
 		hpet.last_tsc = t;
-		timeoffset = 0;
 	}
 
 /*
@@ -255,7 +253,6 @@
 		rtc_update = xtime.tv_sec + 660;
 	}
  
-	vxtime_unlock();
 	write_sequnlock(&xtime_lock);
 }
 
@@ -348,8 +345,9 @@
 	outb((1193182 / (1000 / 50)) & 0xff, 0x42);
 	outb((1193182 / (1000 / 50)) >> 8, 0x42);
 	rdtscll(start);
-      	
+	sync_core();
 	while ((inb(0x61) & 0x20) == 0);
+	sync_core();
 	rdtscll(end);
 
 
@@ -382,12 +380,12 @@
 
 	pit_init();
 	printk(KERN_INFO "time.c: Using 1.1931816 MHz PIT timer.\n");
-	setup_irq(0, &irq0);
 	cpu_khz = pit_calibrate_tsc();
 	printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
 		cpu_khz / 1000, cpu_khz % 1000);
 	hpet.ticks = cpu_khz * (1000 / HZ);
 	rdtscll(hpet.last_tsc);
+	setup_irq(0, &irq0);
 }
 
 __setup("report_lost_ticks", time_setup);
diff -Nru a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
--- a/arch/x86_64/kernel/traps.c	Fri Feb 14 15:53:08 2003
+++ b/arch/x86_64/kernel/traps.c	Fri Feb 14 15:53:08 2003
@@ -77,6 +77,12 @@
 
 struct notifier_block *die_chain;
 
+static inline void conditional_sti(struct pt_regs *regs)
+{
+	if (regs->eflags & X86_EFLAGS_IF)
+		local_irq_enable();
+}
+
 static int kstack_depth_to_print = 10;
 
 #ifdef CONFIG_KALLSYMS
@@ -128,8 +134,7 @@
 {
 	unsigned long addr;
 	unsigned long *irqstack, *irqstack_end, *estack_end;
-	/* FIXME: should read the cpuid from the APIC; to still work with bogus %gs */
-	const int cpu = smp_processor_id();
+	const int cpu = safe_smp_processor_id();
 	int i;
 
 	printk("\nCall Trace:");
@@ -210,7 +215,7 @@
 {
 	unsigned long *stack;
 	int i;
-	const int cpu = smp_processor_id();
+	const int cpu = safe_smp_processor_id();
 	unsigned long *irqstack_end = (unsigned long *) (cpu_pda[cpu].irqstackptr);
 	unsigned long *irqstack = (unsigned long *) (cpu_pda[cpu].irqstackptr - IRQSTACKSIZE);    
 
@@ -252,12 +257,7 @@
 	int i;
 	int in_kernel = (regs->cs & 3) == 0;
 	unsigned long rsp;
-#ifdef CONFIG_SMP
-	/* For SMP should get the APIC id here, just to protect against corrupted GS */ 
-	const int cpu = smp_processor_id(); 
-#else
-	const int cpu = 0;
-#endif	
+	const int cpu = safe_smp_processor_id(); 
 	struct task_struct *cur = cpu_pda[cpu].pcurrent; 
 
 		rsp = regs->rsp;
@@ -330,7 +330,7 @@
 	bust_spinlocks(1);
 	handle_BUG(regs); 
 	printk("%s: %04lx\n", str, err & 0xffff);
-	cpu = smp_processor_id(); 
+	cpu = safe_smp_processor_id(); 
 	/* racy, but better than risking deadlock. */ 
 	local_irq_disable();
 	if (!spin_trylock(&die_lock)) { 
@@ -365,10 +365,12 @@
 static void do_trap(int trapnr, int signr, char *str, 
 			   struct pt_regs * regs, long error_code, siginfo_t *info)
 {
+	conditional_sti(regs);
+
 #ifdef CONFIG_CHECKING
        { 
                unsigned long gs; 
-               struct x8664_pda *pda = cpu_pda + stack_smp_processor_id(); 
+               struct x8664_pda *pda = cpu_pda + safe_smp_processor_id(); 
                rdmsrl(MSR_GS_BASE, gs); 
                if (gs != (unsigned long)pda) { 
                        wrmsrl(MSR_GS_BASE, pda); 
@@ -454,10 +456,12 @@
 
 asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
 {
+	conditional_sti(regs);
+
 #ifdef CONFIG_CHECKING
        { 
                unsigned long gs; 
-               struct x8664_pda *pda = cpu_pda + hard_smp_processor_id(); 
+               struct x8664_pda *pda = cpu_pda + safe_smp_processor_id(); 
                rdmsrl(MSR_GS_BASE, gs); 
                if (gs != (unsigned long)pda) { 
                        wrmsrl(MSR_GS_BASE, pda); 
@@ -565,7 +569,7 @@
 #ifdef CONFIG_CHECKING
        { 
                unsigned long gs; 
-               struct x8664_pda *pda = cpu_pda + stack_smp_processor_id(); 
+               struct x8664_pda *pda = cpu_pda + safe_smp_processor_id(); 
                rdmsrl(MSR_GS_BASE, gs); 
                if (gs != (unsigned long)pda) { 
                        wrmsrl(MSR_GS_BASE, pda); 
@@ -576,6 +580,8 @@
 
 	asm("movq %%db6,%0" : "=r" (condition));
 
+	conditional_sti(regs);
+
 	if (notify_die(DIE_DEBUG, "debug", regs, error_code) == NOTIFY_BAD)
 		return; 
 
@@ -636,7 +642,6 @@
 	struct task_struct * task;
 	siginfo_t info;
 	unsigned short cwd, swd;
-
 	/*
 	 * Save the info for the exception handler and clear the error.
 	 */
@@ -688,6 +693,7 @@
 
 asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
 {
+	conditional_sti(regs);
 	math_error((void *)regs->rip);
 }
 
@@ -747,6 +753,7 @@
 asmlinkage void do_simd_coprocessor_error(struct pt_regs * regs,
 					  long error_code)
 {
+	conditional_sti(regs);
 		simd_math_error((void *)regs->rip);
 }
 
diff -Nru a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
--- a/arch/x86_64/kernel/vsyscall.c	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/kernel/vsyscall.c	Fri Feb 14 15:53:12 2003
@@ -2,6 +2,7 @@
  *  linux/arch/x86_64/kernel/vsyscall.c
  *
  *  Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
+ *  Copyright 2003 Andi Kleen, SuSE Labs.
  *
  *  Thanks to hpa@transmeta.com for some useful hint.
  *  Special thanks to Ingo Molnar for his early experience with
@@ -12,7 +13,8 @@
  *  vsyscalls. One vsyscall can reserve more than 1 slot to avoid
  *  jumping out of line if necessary.
  *
- *  $Id: vsyscall.c,v 1.9 2002/03/21 13:42:58 ak Exp $
+ *  Note: the concept clashes with user mode linux. If you use UML just
+ *  set the kernel.vsyscall sysctl to 0.
  */
 
 /*
@@ -29,6 +31,9 @@
  *    broken programs will segfault and there's no security risk until we choose to
  *    fix it.
  *
+ * Add HPET support (port from 2.4). Still needed?
+ * Nop out vsyscall syscall to avoid anchor for buffer overflows when sysctl off.
+ * 
  * These are not urgent things that we need to address only before shipping the first
  * production binary kernels.
  */
@@ -37,6 +42,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/timer.h>
+#include <linux/seqlock.h>
 
 #include <asm/vsyscall.h>
 #include <asm/pgtable.h>
@@ -44,19 +50,13 @@
 #include <asm/fixmap.h>
 #include <asm/errno.h>
 
-
 #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
 
-#define NO_VSYSCALL 1
+int __sysctl_vsyscall __section_sysctl_vsyscall = 1;
+seqlock_t __xtime_lock __section_xtime_lock = SEQLOCK_UNLOCKED;
 
-#ifdef NO_VSYSCALL
 #include <asm/unistd.h>
 
-static int errno __section_vxtime_sequence; 
-
-static inline _syscall2(int,gettimeofday,struct timeval *,tv,struct timezone *,tz)
-
-#else
 static inline void timeval_normalize(struct timeval * tv)
 {
 	time_t __sec;
@@ -69,63 +69,60 @@
 	}
 }
 
-long __vxtime_sequence[2] __section_vxtime_sequence;
-
-
 static inline void do_vgettimeofday(struct timeval * tv)
 {
 	long sequence, t;
 	unsigned long sec, usec;
 
 	do {
-		sequence = __vxtime_sequence[1];
-		rmb();
+		sequence = read_seqbegin(&__xtime_lock);
 		
+		sync_core();
 		rdtscll(t);
 		sec = __xtime.tv_sec;
-		usec = __xtime.tv_usec +
+		usec = (__xtime.tv_nsec * 1000) +
 			(__jiffies - __wall_jiffies) * (1000000 / HZ) +
 			(t  - __hpet.last_tsc) * (1000000 / HZ) / __hpet.ticks + __hpet.offset;
 
-		rmb();
-	} while (sequence != __vxtime_sequence[0]);
+	} while (read_seqretry(&__xtime_lock, sequence));
 
 	tv->tv_sec = sec + usec / 1000000;
 	tv->tv_usec = usec % 1000000;
 }
 
+/* RED-PEN may want to readd seq locking, but then the variable should be write-once. */
 static inline void do_get_tz(struct timezone * tz)
 {
-	long sequence;
-
-	do {
-		sequence = __vxtime_sequence[1];
-		rmb();
-
 		*tz = __sys_tz;
+}
 
-		rmb();
-	} while (sequence != __vxtime_sequence[0]);
+static inline int gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+	int ret;
+	asm volatile("syscall" 
+		: "=a" (ret)
+		: "0" (__NR_gettimeofday),"D" (tv),"S" (tz) : __syscall_clobber );
+	return ret;
 }
-#endif
 
 static int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz)
 {
-#ifdef NO_VSYSCALL
+	if (unlikely(!__sysctl_vsyscall))
 	return gettimeofday(tv,tz); 
-#else
 	if (tv)
 		do_vgettimeofday(tv);
 	if (tz)
 		do_get_tz(tz);
 	return 0;
-#endif
 }
 
 static time_t __vsyscall(1) vtime(time_t * t)
 {
 	struct timeval tv; 
-	vgettimeofday(&tv,NULL); 
+	if (unlikely(!__sysctl_vsyscall))
+		gettimeofday(&tv, NULL);
+	else
+		do_vgettimeofday(&tv);
 	if (t)
 		*t = tv.tv_sec; 
 	return tv.tv_sec;
@@ -139,12 +136,13 @@
 static long __vsyscall(3) venosys_1(void)
 {
 	return -ENOSYS;
+
 }
 
 static void __init map_vsyscall(void)
 {
 	extern char __vsyscall_0;
-	unsigned long physaddr_page0 = (unsigned long) &__vsyscall_0 - __START_KERNEL_map;
+	unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0);
 
 	__set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_page0, PAGE_KERNEL_VSYSCALL);
 }
diff -Nru a/arch/x86_64/kernel/wakeup.S b/arch/x86_64/kernel/wakeup.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/kernel/wakeup.S	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,306 @@
+/*
+ * ACPI S3 entry/exit handling.
+ *		
+ * Notes:
+ * Relies on kernel being loaded below 4GB.
+ * Needs restore_low_mappings called before.
+ *			
+ * Copyright 2003 by Andi Kleen, SuSE Labs.
+ *	
+ * Long mode entry losely based on example code in chapter 14 of the x86-64 system 
+ * programmer's manual.
+ * 
+ * Notebook:	
+
+ FIXME need to interface with suspend.c properly. do_magic. check i386. rename to suspend64.S
+		
+ Need to fix vgacon,mtrr,bluesmoke to do resume
+ 	
+ Interrupts should be off until the io-apic code has reinited the APIC.
+ Need support for that in the pm frame work or a special hack?
+
+ SMP support is non existent. Need to somehow restart the other CPUs again.
+ If CPU hotplug was working it could be used. Save/Restore needs to run on the same CPU.
+
+ Should check magic like i386 code
+	
+ suspend code copies something. check what it is.		
+ */
+	
+#include <linux/linkage.h>
+	
+#include <asm/msr.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+			
+#define O(x) (x-acpi_wakeup)
+		
+	.text
+	.code16
+ENTRY(acpi_wakeup)
+	/* 16bit real mode entered from ACPI BIOS */
+	/* The machine is just through BIOS setup after power down and everything set up
+	   by Linux needs to be restored. */
+	/* The code here needs to be position independent or manually relocated,
+	   because it is copied to a <1MB page for real mode execution */
+	
+	/* A20 enabled (according to ACPI spec) */
+	/* cs = acpi_wakeup >> 4 ;  eip = acpi_wakeup & 0xF */
+		
+	movw %cs,%ax
+	movw %ax,%ds	/* make %ds point to acpi_wakeup */
+	movw %ax,%ss
+	movw $O(wakeup_stack),%sp	/* setup stack */
+
+	pushl $0
+	popfl			/* clear EFLAGS */
+	
+	lgdt %ds:O(pGDT)	/* load kernel GDT */
+	
+	movl $0x1,%eax		/* enable protected mode */
+	movl %eax,%cr0
+
+	movl %ds:O(wakeup_page_table),%edi
+	ljmpl  $__KERNEL16_CS,$0   /* -> s3_prot16 (filled in earlier by caller) */
+	
+	/* patched by s3_restore_state below */
+pGDT:
+	.short 0
+	.quad  0
+
+	.align 4
+	.globl wakeup_page_table
+wakeup_page_table:	
+	.long 0	
+	
+	.align 8
+wakeup_stack:
+	.fill 128,1,0
+	.globl acpi_wakeup_end
+acpi_wakeup_end:
+	/* end of real mode trampoline */
+		
+	/* pointed to by __KERNEL16_CS:0 */	
+	.code16	
+ENTRY(s3_prot16)
+	/* Now in 16bit protected mode, still no paging, stack/data segments invalid */
+
+	/* Prepare everything for 64bit paging, but still keep it turned off */
+	movl %cr4,%eax
+	bts  $5,%eax	/* set PAE bit */
+	movl %eax,%cr4
+	
+	movl %edi,%cr3	/* load kernel page table */
+
+	movl $0x80000001,%eax	
+	cpuid		/* no execute supported ? */
+	movl %edx,%esi	
+	
+	movl $MSR_EFER,%ecx
+	rdmsr 
+	bts $8,%eax	/* long mode */
+	bt  $20,%esi	/* NX supported ? */
+	jnc 1f
+	bt  $_EFER_NX,%eax
+1:	
+	wrmsr		/* set temporary efer - real one is restored a bit later */
+	
+	movl %cr0,%eax
+	bts  $31,%eax	/* paging */
+	movl %eax,%cr0
+
+	/* running in identity mapping now */
+
+	/* go to 64bit code segment */
+	ljmpl $__KERNEL_CS,$s3_restore_state-__START_KERNEL_map
+
+	.code64			
+	.macro	SAVEMSR msr,target
+	movl	$\msr,%ecx
+	rdmsr
+	shlq	$32,%rdx
+	orq	%rax,%rdx
+	movq	%rdx,\target(%rip)
+	.endm
+
+	.macro RESTMSR msr,src
+	movl	$\msr,%ecx
+	movq	\src(%rip),%rax
+	movq	%rax,%rdx
+	shrq	$32,%rdx
+	wrmsr
+	.endm
+	
+	.macro	SAVECTL reg
+	movq	%\reg,%rax
+	movq	%rax,saved_\reg(%rip)
+	.endm
+	
+	.macro	RESTCTL reg
+	movq	saved_\reg(%rip),%rax
+	movq	%rax,%\reg
+	.endm
+
+	/* Running in identity mapping, long mode */
+s3_restore_state_low:
+	movq	$s3_restore_state,%rax
+	jmpq	*%rax	
+
+	/* Running in real kernel mapping now */
+s3_restore_state:
+	xorl	%eax,%eax
+	movl	%eax,%ds
+	movq	saved_rsp(%rip),%rsp
+	movw	saved_ss(%rip),%ss
+	movw	saved_fs(%rip),%fs
+	movw	saved_gs(%rip),%gs
+	movw	saved_es(%rip),%es
+	movw	saved_ds(%rip),%ds
+
+	lidt	saved_idt
+	ltr	saved_tr
+	lldt	saved_ldt	
+	/* gdt is already loaded */
+	
+	RESTCTL	cr0
+	RESTCTL	cr4
+	/* cr3 is already loaded */	
+	
+	RESTMSR MSR_EFER,saved_efer
+	RESTMSR MSR_LSTAR,saved_lstar
+	RESTMSR MSR_CSTAR,saved_cstar
+	RESTMSR MSR_FS_BASE,saved_fs_base
+	RESTMSR MSR_GS_BASE,saved_gs_base
+	RESTMSR MSR_KERNEL_GS_BASE,saved_kernel_gs_base
+	RESTMSR MSR_SYSCALL_MASK,saved_syscall_mask
+				
+	fxrstor	fpustate(%rip)
+
+	RESTCTL	dr0
+	RESTCTL	dr1
+	RESTCTL	dr2
+	RESTCTL	dr3
+	RESTCTL	dr6
+	RESTCTL	dr7
+
+	movq	saved_rflags(%rip),%rax
+	pushq	%rax
+	popfq
+								
+	movq	saved_rbp(%rip),%rbp
+	movq	saved_rbx(%rip),%rbx
+	movq	saved_r12(%rip),%r12
+	movq	saved_r13(%rip),%r13
+	movq	saved_r14(%rip),%r14
+	movq	saved_r15(%rip),%r15		
+	ret
+		
+ENTRY(acpi_prepare_wakeup)
+	sgdt	saved_gdt
+	
+	/* copy gdt descr and page table to low level wakeup code so that it can 
+	   reload them early. */
+	movq	acpi_wakeup_address(%rip),%rax	
+	movw	saved_gdt+8(%rip),%cx
+	movw	%cx,O(pGDT)+8(%rax)	
+	movq	saved_gdt(%rip),%rcx
+	movq	%rcx,O(pGDT)(%rax)
+	
+	movq	%cr3,%rdi
+	movl	%edi,O(wakeup_page_table)(%rax)
+	ret
+
+	/* Save CPU state. */
+	/* Everything saved here needs to be restored above. */
+ENTRY(do_suspend_lowlevel)
+	testl	%edi,%edi
+	jnz	s3_restore_state
+		
+	SAVECTL	cr0
+	SAVECTL	cr4
+	SAVECTL	cr3
+		
+	str	saved_tr
+	sidt	saved_idt		
+	sgdt	saved_gdt
+	sldt	saved_ldt
+			
+	SAVEMSR MSR_EFER,saved_efer
+	SAVEMSR MSR_LSTAR,saved_lstar
+	SAVEMSR MSR_CSTAR,saved_cstar
+	SAVEMSR MSR_FS_BASE,saved_fs_base
+	SAVEMSR MSR_GS_BASE,saved_gs_base
+	SAVEMSR MSR_KERNEL_GS_BASE,saved_kernel_gs_base
+	SAVEMSR MSR_SYSCALL_MASK,saved_syscall_mask
+
+	movw	%ds,saved_ds(%rip)
+	movw	%es,saved_es(%rip)
+	movw	%fs,saved_fs(%rip)
+	movw	%gs,saved_gs(%rip)
+	movw	%ss,saved_ss(%rip)
+	movq	%rsp,saved_rsp(%rip)
+	
+	pushfq
+	popq	%rax
+	movq	%rax,saved_rflags(%rip)
+
+	SAVECTL  dr0
+	SAVECTL  dr1
+	SAVECTL  dr2
+	SAVECTL  dr3
+	SAVECTL  dr6
+	SAVECTL  dr7
+	
+	fxsave	fpustate(%rip) 
+	
+	/* finally save callee saved registers */
+	movq	%rbp,saved_rbp(%rip)
+	movq	%rbx,saved_rbx(%rip)
+	movq	%r12,saved_r12(%rip)
+	movq	%r13,saved_r13(%rip)
+	movq	%r14,saved_r14(%rip)
+	movq	%r15,saved_r15(%rip)
+	movq	$3,%rdi		
+	call	acpi_enter_sleep_state
+	ret	/* should not happen */
+
+	.data
+	.align 8
+saved_efer:	.quad 0
+saved_lstar:	.quad 0
+saved_cstar:	.quad 0
+saved_cr4:	.quad 0
+saved_cr3:	.quad 0
+saved_cr0:	.quad 0	
+saved_rbp:	.quad 0
+saved_rbx:	.quad 0
+saved_rsp:	.quad 0
+saved_r12:	.quad 0
+saved_r13:	.quad 0
+saved_r14:	.quad 0
+saved_r15:	.quad 0
+saved_rflags:	.quad 0
+saved_gs_base:	.quad 0
+saved_fs_base:	.quad 0
+saved_kernel_gs_base:	.quad 0
+saved_syscall_mask:	.quad 0
+saved_dr0:	.quad 0	
+saved_dr1:	.quad 0	
+saved_dr2:	.quad 0	
+saved_dr3:	.quad 0	
+saved_dr6:	.quad 0	
+saved_dr7:	.quad 0	
+saved_ds:	.short 0
+saved_fs:	.short 0
+saved_gs:	.short 0
+saved_es:	.short 0
+saved_ss:	.short 0	
+saved_idt:	.short 0
+		.quad 0
+saved_ldt:	.short 0
+saved_gdt:	.short 0
+		.quad 0		
+saved_tr:	.short 0
+			
+		.align 16
+fpustate:	.fill  512,1,0				
diff -Nru a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile
--- a/arch/x86_64/mm/Makefile	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/mm/Makefile	Fri Feb 14 15:53:12 2003
@@ -1,6 +1,8 @@
 #
-# Makefile for the linux i386-specific parts of the memory manager.
+# Makefile for the linux x86_64-specific parts of the memory manager.
 #
 
 obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+obj-$(CONFIG_DISCONTIGMEM) += numa.o
+obj-$(CONFIG_K8_NUMA) += k8topology.o
diff -Nru a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
--- a/arch/x86_64/mm/fault.c	Fri Feb 14 15:53:08 2003
+++ b/arch/x86_64/mm/fault.c	Fri Feb 14 15:53:08 2003
@@ -121,7 +121,10 @@
 	/* get the address */
 	__asm__("movq %%cr2,%0":"=r" (address));
 
-	if (page_fault_trace) 
+	if (likely(regs->eflags & X86_EFLAGS_IF))
+		local_irq_enable();
+
+	if (unlikely(page_fault_trace))
 		printk("pagefault rip:%lx rsp:%lx cs:%lu ss:%lu address %lx error %lx\n",
 		       regs->rip,regs->rsp,regs->cs,regs->ss,address,error_code); 
 
@@ -139,7 +142,7 @@
 	 * If we're in an interrupt or have no user
 	 * context, we must not take the fault..
 	 */
-	if (in_atomic() || !mm)
+	if (unlikely(in_atomic() || !mm))
 		goto no_context;
 
  again:
@@ -148,7 +151,7 @@
 	vma = find_vma(mm, address);
 	if (!vma)
 		goto bad_area;
-	if (vma->vm_start <= address)
+	if (likely(vma->vm_start <= address))
 		goto good_area;
 	if (!(vma->vm_flags & VM_GROWSDOWN))
 		goto bad_area;
@@ -222,7 +225,8 @@
 			return;
 		} 			
 #endif
-		printk("%s[%d] segfault at rip:%lx rsp:%lx adr:%lx err:%lx\n",
+		printk(KERN_INFO 
+		       "%s[%d] segfault at rip:%lx rsp:%lx adr:%lx err:%lx\n",
 		       tsk->comm, tsk->pid, regs->rip, regs->rsp, address, 
 		       error_code);
        
diff -Nru a/arch/x86_64/mm/hugetlbpage.c b/arch/x86_64/mm/hugetlbpage.c
--- a/arch/x86_64/mm/hugetlbpage.c	Fri Feb 14 15:53:10 2003
+++ b/arch/x86_64/mm/hugetlbpage.c	Fri Feb 14 15:53:10 2003
@@ -86,6 +86,18 @@
 	set_pte(page_table, entry);
 }
 
+/*
+ * This function checks for proper alignment of input addr and len parameters.
+ */
+int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
+{
+	if (len & ~HPAGE_MASK)
+		return -EINVAL;
+	if (addr & ~HPAGE_MASK)
+		return -EINVAL;
+	return 0;
+}
+
 int
 copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			struct vm_area_struct *vma)
@@ -150,6 +162,37 @@
 	return i;
 }
 
+struct page *
+follow_huge_addr(struct mm_struct *mm,
+	struct vm_area_struct *vma, unsigned long address, int write)
+{
+	return NULL;
+}
+
+struct vm_area_struct *hugepage_vma(struct mm_struct *mm, unsigned long addr)
+{
+	return NULL;
+}
+
+int pmd_huge(pmd_t pmd)
+{
+	return !!(pmd_val(pmd) & _PAGE_PSE);
+}
+
+struct page *
+follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+		pmd_t *pmd, int write)
+{
+	struct page *page;
+
+	page = pte_page(*(pte_t *)pmd);
+	if (page) {
+		page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT);
+		get_page(page);
+	}
+	return page;
+}
+
 void free_huge_page(struct page *page)
 {
 	BUG_ON(page_count(page));
@@ -181,8 +224,6 @@
 	BUG_ON(start & (HPAGE_SIZE - 1));
 	BUG_ON(end & (HPAGE_SIZE - 1));
 
-	spin_lock(&htlbpage_lock);
-	spin_unlock(&htlbpage_lock);
 	for (address = start; address < end; address += HPAGE_SIZE) {
 		pte = huge_pte_offset(mm, address);
 		page = pte_page(*pte);
@@ -204,7 +245,6 @@
 int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
 {
 	struct mm_struct *mm = current->mm;
-	struct inode = mapping->host;
 	unsigned long addr;
 	int ret = 0;
 
@@ -228,7 +268,6 @@
 			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
 		page = find_get_page(mapping, idx);
 		if (!page) {
-			loff_t i_size;
 
 			page = alloc_hugetlb_page();
 			if (!page) {
@@ -241,9 +280,6 @@
 				free_huge_page(page);
 				goto out;
 			}
-			i_size = (loff_t)(idx + 1) * HPAGE_SIZE;
-			if (i_size > inode->i_size)
-				inode->i_size = i_size;
 		}
 		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
 	}
diff -Nru a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
--- a/arch/x86_64/mm/init.c	Fri Feb 14 15:53:09 2003
+++ b/arch/x86_64/mm/init.c	Fri Feb 14 15:53:09 2003
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 1995  Linus Torvalds
  *  Copyright (C) 2000  Pavel Machek <pavel@suse.cz>
- *  Copyright (C) 2002  Andi Kleen <ak@suse.de>
+ *  Copyright (C) 2002,2003 Andi Kleen <ak@suse.de>
  */
 
 #include <linux/config.h>
@@ -37,8 +37,9 @@
 #include <asm/tlb.h>
 #include <asm/mmu_context.h>
 #include <asm/proto.h>
+#include <asm/smp.h>
 
-unsigned long start_pfn, end_pfn;
+#define Dprintk(x...) printk(x)
 
 struct mmu_gather mmu_gathers[NR_CPUS];
 
@@ -90,9 +91,11 @@
 	if (after_bootmem)
 		ptr = (void *) get_zeroed_page(GFP_ATOMIC); 
 	else
-		ptr = alloc_bootmem_low(PAGE_SIZE); 
-	if (!ptr)
+		ptr = alloc_bootmem_pages(PAGE_SIZE);
+	if (!ptr || ((unsigned long)ptr & ~PAGE_MASK))
 		panic("set_pte_phys: cannot allocate page data %s\n", after_bootmem?"after bootmem":"");
+
+	Dprintk("spp_getpage %p\n", ptr);
 	return ptr;
 } 
 
@@ -104,6 +107,8 @@
 	pmd_t *pmd;
 	pte_t *pte;
 
+	Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
+
 	level4 = pml4_offset_k(vaddr);
 	if (pml4_none(*level4)) {
 		printk("PML4 FIXMAP MISSING, it should be setup in head.S!\n");
@@ -114,7 +119,7 @@
 		pmd = (pmd_t *) spp_getpage(); 
 		set_pgd(pgd, __pgd(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
 		if (pmd != pmd_offset(pgd, 0)) {
-			printk("PAGETABLE BUG #01!\n");
+			printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pgd,0));
 			return;
 		}
 	}
@@ -128,6 +133,7 @@
 		}
 	}
 	pte = pte_offset_kernel(pmd, vaddr);
+	/* CHECKME: */
 	if (pte_val(*pte))
 		pte_ERROR(*pte);
 	set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
@@ -151,7 +157,8 @@
 	set_pte_phys(address, phys, prot);
 }
 
-extern unsigned long start_pfn, end_pfn; 
+unsigned long __initdata table_start, table_end; 
+
 extern pmd_t temp_boot_pmds[]; 
 
 static  struct temp_map { 
@@ -168,21 +175,21 @@
 { 
 	struct temp_map *ti;
 	int i; 
-	unsigned long pfn = start_pfn++, paddr; 
+	unsigned long pfn = table_end++, paddr; 
 	void *adr;
 
-	if (pfn >= end_pfn_map) 
+	if (pfn >= end_pfn) 
 		panic("alloc_low_page: ran out of memory"); 
 	for (i = 0; temp_mappings[i].allocated; i++) {
 		if (!temp_mappings[i].pmd) 
 			panic("alloc_low_page: ran out of temp mappings"); 
 	} 
 	ti = &temp_mappings[i];
-	paddr = (pfn & (~511)) << PAGE_SHIFT; 
+	paddr = (pfn << PAGE_SHIFT) & PMD_MASK; 
 	set_pmd(ti->pmd, __pmd(paddr | _KERNPG_TABLE | _PAGE_PSE)); 
 	ti->allocated = 1; 
 	__flush_tlb(); 	       
-	adr = ti->address + (pfn & 511)*PAGE_SIZE; 
+	adr = ti->address + ((pfn << PAGE_SHIFT) & ~PMD_MASK); 
 	*index = i; 
 	*phys  = pfn * PAGE_SIZE;  
 	return adr; 
@@ -203,20 +210,26 @@
 	pgd = pgd + i;
 	for (; i < PTRS_PER_PGD; pgd++, i++) {
 		int map; 
-		unsigned long paddr = i*PGDIR_SIZE, pmd_phys;
+		unsigned long paddr, pmd_phys;
 		pmd_t *pmd;
 
+		paddr = (address & PML4_MASK) + i*PGDIR_SIZE;
 		if (paddr >= end) { 
 			for (; i < PTRS_PER_PGD; i++, pgd++) 
 				set_pgd(pgd, __pgd(0)); 
 			break;
 		} 
+
+		if (!e820_mapped(paddr, paddr+PGDIR_SIZE, 0)) { 
+			set_pgd(pgd, __pgd(0)); 
+			continue;
+		} 
+
 		pmd = alloc_low_page(&map, &pmd_phys);
 		set_pgd(pgd, __pgd(pmd_phys | _KERNPG_TABLE));
-		for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
+		for (j = 0; j < PTRS_PER_PMD; pmd++, j++, paddr += PMD_SIZE) {
 			unsigned long pe;
 
-			paddr = i*PGDIR_SIZE + j*PMD_SIZE;
 			if (paddr >= end) { 
 				for (; j < PTRS_PER_PMD; j++, pmd++)
 					set_pmd(pmd,  __pmd(0)); 
@@ -239,13 +252,37 @@
 	unsigned long adr;	       
 	unsigned long end;
 	unsigned long next; 
+	unsigned long pgds, pmds, tables; 
+
+	Dprintk("init_memory_mapping\n");
+
+	end = end_pfn_map << PAGE_SHIFT;
+
+	/* 
+	 * Find space for the kernel direct mapping tables.
+	 * Later we should allocate these tables in the local node of the memory
+	 * mapped.  Unfortunately this is done currently before the nodes are 
+	 * discovered.
+	 */
+
+	pgds = (end + PGDIR_SIZE - 1) >> PGDIR_SHIFT;
+	pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; 
+	tables = round_up(pgds*8, PAGE_SIZE) + round_up(pmds * 8, PAGE_SIZE); 
+
+	table_start = find_e820_area(0x8000, __pa_symbol(&_text), tables); 
+	if (table_start == -1UL) 
+		panic("Cannot find space for the kernel page tables"); 
+
+	table_start >>= PAGE_SHIFT; 
+	table_end = table_start;
+       
+	end += __PAGE_OFFSET; /* turn virtual */  	
 
-	end = PAGE_OFFSET + (end_pfn_map * PAGE_SIZE); 
 	for (adr = PAGE_OFFSET; adr < end; adr = next) { 
 		int map;
 		unsigned long pgd_phys; 
 		pgd_t *pgd = alloc_low_page(&map, &pgd_phys);
-		next = adr + (512UL * 1024 * 1024 * 1024);
+		next = adr + PML4_SIZE;
 		if (next > end) 
 			next = end; 
 		phys_pgd_init(pgd, adr-PAGE_OFFSET, next-PAGE_OFFSET); 
@@ -254,20 +291,35 @@
 	} 
 	asm volatile("movq %%cr4,%0" : "=r" (mmu_cr4_features));
 	__flush_tlb_all();
+	early_printk("kernel direct mapping tables upto %lx @ %lx-%lx\n", end, 
+	       table_start<<PAGE_SHIFT, 
+	       table_end<<PAGE_SHIFT);
 }
 
 extern struct x8664_pda cpu_pda[NR_CPUS];
 
-void __init zap_low_mappings (void)
+static unsigned long low_pml4[NR_CPUS];
+
+void swap_low_mappings(void)
 {
 	int i;
 	for (i = 0; i < NR_CPUS; i++) {
-		if (cpu_pda[i].level4_pgt) 
-			cpu_pda[i].level4_pgt[0] = 0; 
+	        unsigned long t;
+		if (!cpu_pda[i].level4_pgt) 
+			continue;
+		t = cpu_pda[i].level4_pgt[0];
+		cpu_pda[i].level4_pgt[0] = low_pml4[i];
+		low_pml4[i] = t;
 	}
 	flush_tlb_all();
 }
 
+void zap_low_mappings(void)
+{
+	swap_low_mappings();
+}
+
+#ifndef CONFIG_DISCONTIGMEM
 void __init paging_init(void)
 {
 	{
@@ -286,7 +338,7 @@
 	}
 	return;
 }
-
+#endif
 
 static inline int page_is_ram (unsigned long pagenr)
 {
@@ -315,36 +367,45 @@
 	int codesize, reservedpages, datasize, initsize;
 	int tmp;
 
-	if (!mem_map)
-		BUG();
-
+	/* How many end-of-memory variables you have, grandma! */
 	max_low_pfn = end_pfn;
 	max_pfn = end_pfn;
-	max_mapnr = num_physpages = end_pfn;
+	num_physpages = end_pfn;
 	high_memory = (void *) __va(end_pfn * PAGE_SIZE);
 
 	/* clear the zero-page */
 	memset(empty_zero_page, 0, PAGE_SIZE);
 
+	reservedpages = 0;
+
 	/* this will put all low memory onto the freelists */
-	totalram_pages += free_all_bootmem();
+#ifdef CONFIG_DISCONTIGMEM
+	totalram_pages += numa_free_all_bootmem();
+	tmp = 0;
+	/* should count reserved pages here for all nodes */ 
+#else
+	max_mapnr = end_pfn;
+	if (!mem_map) BUG();
 
-	after_bootmem = 1;
+	totalram_pages += free_all_bootmem();
 
-	reservedpages = 0;
 	for (tmp = 0; tmp < end_pfn; tmp++)
 		/*
 		 * Only count reserved RAM pages
 		 */
 		if (page_is_ram(tmp) && PageReserved(mem_map+tmp))
 			reservedpages++;
+#endif
+
+	after_bootmem = 1;
+
 	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
 	printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
 		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
-		max_mapnr << (PAGE_SHIFT-10),
+		end_pfn << (PAGE_SHIFT-10),
 		codesize >> 10,
 		reservedpages << (PAGE_SHIFT-10),
 		datasize >> 10,
@@ -392,3 +453,16 @@
 	}
 }
 #endif
+
+void __init reserve_bootmem_generic(unsigned long phys, unsigned len) 
+{ 
+	/* Should check here against the e820 map to avoid double free */ 
+#ifdef CONFIG_DISCONTIGMEM
+	int nid = phys_to_nid(phys);
+	if (phys < HIGH_MEMORY && nid) 
+		panic("reserve of %lx at node %d", phys, nid);
+	reserve_bootmem_node(NODE_DATA(nid), phys, len);
+#else       		
+	reserve_bootmem(phys, len);    
+#endif
+}
diff -Nru a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
--- a/arch/x86_64/mm/ioremap.c	Fri Feb 14 15:53:12 2003
+++ b/arch/x86_64/mm/ioremap.c	Fri Feb 14 15:53:12 2003
@@ -133,14 +133,16 @@
 	 */
 	if (phys_addr < virt_to_phys(high_memory)) {
 		char *t_addr, *t_end;
-		struct page *page;
 
 		t_addr = __va(phys_addr);
 		t_end = t_addr + (size - 1);
 	   
+#ifndef CONFIG_DISCONTIGMEM	 
+ 		struct page *page;
 		for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
 			if(!PageReserved(page))
 				return NULL;
+#endif
 	}
 
 	/*
diff -Nru a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/mm/k8topology.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,141 @@
+/* 
+ * AMD K8 NUMA support.
+ * Discover the memory map and associated nodes.
+ * 
+ * Doesn't use the ACPI SRAT table because it has a questionable license.
+ * Instead the northbridge registers are read directly. 
+ * XXX in 2.5 we could use the generic SRAT code
+ * 
+ * Copyright 2002,2003 Andi Kleen, SuSE Labs.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <linux/pci_ids.h>
+#include <asm/types.h>
+#include <asm/mmzone.h>
+#include <asm/proto.h>
+#include <asm/e820.h>
+#include <asm/pci-direct.h>
+#include <asm/numa.h>
+
+static int find_northbridge(void)
+{
+	int num; 
+
+	for (num = 0; num < 32; num++) { 
+		u32 header;
+		
+		header = read_pci_config(0, num, 0, 0x00);  
+		if (header != (PCI_VENDOR_ID_AMD | (0x1100<<16)))
+			continue; 	
+
+		header = read_pci_config(0, num, 1, 0x00); 
+		if (header != (PCI_VENDOR_ID_AMD | (0x1101<<16)))
+			continue;	
+		return num; 
+	} 
+
+	return -1; 	
+}
+
+int __init k8_scan_nodes(unsigned long start, unsigned long end)
+{ 
+	unsigned long prevbase;
+	struct node nodes[MAXNODE];
+	int nodeid, numnodes, maxnode, i, nb; 
+
+	nb = find_northbridge(); 
+	if (nb < 0) 
+		return nb;
+
+	printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb); 
+
+	numnodes = (read_pci_config(0, nb, 0, 0x60 ) >> 4) & 3; 
+
+	memset(&nodes,0,sizeof(nodes)); 
+	prevbase = 0;
+	maxnode = -1; 
+	for (i = 0; i < MAXNODE; i++) { 
+		unsigned long base,limit; 
+
+		base = read_pci_config(0, nb, 1, 0x40 + i*8);
+		limit = read_pci_config(0, nb, 1, 0x44 + i*8);
+
+		nodeid = limit & 3; 
+		if (!limit) { 
+			printk(KERN_INFO "Skipping node entry %d (base %lx)\n", i,			       base);
+			continue;
+		}
+		if ((base >> 8) & 3 || (limit >> 8) & 3) {
+			printk(KERN_ERR "Node %d using interleaving mode %lx/%lx\n", 
+			       nodeid, (base>>8)&3, (limit>>8) & 3); 
+			return -1; 
+		}	
+		if (nodeid > maxnode) 
+			maxnode = nodeid; 
+		if ((1UL << nodeid) & nodes_present) { 
+			printk("Node %d already present. Skipping\n", nodeid);
+			continue;
+		}
+
+		limit >>= 16; 
+		limit <<= 24; 
+
+		if (limit > end_pfn_map << PAGE_SHIFT) 
+			limit = end_pfn_map << PAGE_SHIFT; 
+		if (limit <= base) { 
+			printk(KERN_INFO "Node %d beyond memory map\n", nodeid);
+			continue; 
+		} 
+			
+		base >>= 16;
+		base <<= 24; 
+
+		if (base < start) 
+			base = start; 
+		if (limit > end) 
+			limit = end; 
+		if (limit == base) 
+			continue; 
+		if (limit < base) { 
+			printk(KERN_INFO"Node %d bogus settings %lx-%lx. Ignored.\n",
+			       nodeid, base, limit); 			       
+			continue; 
+		} 
+		
+		/* Could sort here, but pun for now. Should not happen anyroads. */
+		if (prevbase > base) { 
+			printk(KERN_INFO "Node map not sorted %lx,%lx\n",
+			       prevbase,base);
+			return -1;
+		}
+			
+		printk(KERN_INFO "Node %d MemBase %016lx Limit %016lx\n", 
+		       nodeid, base, limit); 
+		
+		nodes[nodeid].start = base; 
+		nodes[nodeid].end = limit;
+
+		prevbase = base;
+	} 
+
+	if (maxnode <= 0)
+		return -1; 
+
+	memnode_shift = compute_hash_shift(nodes,maxnode,end);
+	if (memnode_shift < 0) { 
+		printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n"); 
+		return -1; 
+	} 
+	printk(KERN_INFO "Using node hash shift of %d\n", memnode_shift); 
+
+	early_for_all_nodes(i) { 
+		setup_node_bootmem(i, nodes[i].start, nodes[i].end); 
+	} 
+
+	return 0;
+} 
+
diff -Nru a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/x86_64/mm/numa.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,207 @@
+/* 
+ * Generic VM initialization for x86-64 NUMA setups.
+ * Copyright 2002,2003 Andi Kleen, SuSE Labs.
+ */ 
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mmzone.h>
+#include <linux/blk.h>
+#include <linux/ctype.h>
+#include <asm/e820.h>
+#include <asm/proto.h>
+#include <asm/dma.h>
+#include <asm/numa.h>
+
+#define Dprintk(x...) printk(x)
+
+struct pglist_data *node_data[MAXNODE];
+bootmem_data_t plat_node_bdata[MAX_NUMNODES];
+
+int memnode_shift;
+u8  memnodemap[NODEMAPSIZE];
+
+static int numa_off __initdata; 
+
+unsigned long nodes_present; 
+int maxnode;
+
+static int emunodes __initdata;
+
+int compute_hash_shift(struct node *nodes, int numnodes, u64 maxmem)
+{
+	int i; 
+	int shift = 24;
+	u64 addr;
+	
+	/* When in doubt use brute force. */
+	while (shift < 48) { 
+		memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); 
+		early_for_all_nodes (i) { 
+			for (addr = nodes[i].start; 
+			     addr < nodes[i].end; 
+			     addr += (1UL << shift)) {
+				if (memnodemap[addr >> shift] != 0xff) { 
+					printk("node %d shift %d addr %Lx conflict %d\n", 
+					       i, shift, addr, memnodemap[addr>>shift]);
+					goto next; 
+				} 
+				memnodemap[addr >> shift] = i; 
+			} 
+		} 
+		return shift; 
+	next:
+		shift++; 
+	} 
+	memset(memnodemap,0,sizeof(*memnodemap) * NODEMAPSIZE); 
+	return -1; 
+}
+
+/* Initialize bootmem allocator for a node */
+void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
+{ 
+	unsigned long start_pfn, end_pfn, bootmap_pages, bootmap_size, bootmap_start; 
+	unsigned long nodedata_phys;
+	const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE);
+
+	start = round_up(start, ZONE_ALIGN); 
+
+	printk("Bootmem setup node %d %016lx-%016lx\n", nodeid, start, end);
+
+	start_pfn = start >> PAGE_SHIFT;
+	end_pfn = end >> PAGE_SHIFT;
+
+	nodedata_phys = find_e820_area(start, end, pgdat_size); 
+	if (nodedata_phys == -1L) 
+		panic("Cannot find memory pgdat in node %d\n", nodeid);
+
+	Dprintk("nodedata_phys %lx\n", nodedata_phys); 
+
+	node_data[nodeid] = phys_to_virt(nodedata_phys);
+	memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t));
+	NODE_DATA(nodeid)->bdata = &plat_node_bdata[nodeid];
+	NODE_DATA(nodeid)->node_start_pfn = start_pfn;
+	NODE_DATA(nodeid)->node_size = end_pfn - start_pfn;
+
+	/* Find a place for the bootmem map */
+	bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); 
+	bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE);
+	bootmap_start = find_e820_area(bootmap_start, end, bootmap_pages<<PAGE_SHIFT);
+	if (bootmap_start == -1L) 
+		panic("Not enough continuous space for bootmap on node %d", nodeid); 
+	Dprintk("bootmap start %lu pages %lu\n", bootmap_start, bootmap_pages); 
+	
+	bootmap_size = init_bootmem_node(NODE_DATA(nodeid),
+					 bootmap_start >> PAGE_SHIFT, 
+					 start_pfn, end_pfn); 
+
+	e820_bootmem_free(NODE_DATA(nodeid), start, end);
+
+	reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); 
+	reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT);
+
+	if (nodeid > maxnode) 
+		maxnode = nodeid;
+	nodes_present |= (1UL << nodeid); 
+} 
+
+/* Initialize final allocator for a zone */
+void __init setup_node_zones(int nodeid)
+{ 
+	unsigned long start_pfn, end_pfn; 
+	unsigned long zones[MAX_NR_ZONES];
+	unsigned long dma_end_pfn;
+
+	memset(zones, 0, sizeof(unsigned long) * MAX_NR_ZONES); 
+
+	start_pfn = node_start_pfn(nodeid);
+	end_pfn = node_end_pfn(nodeid);
+
+	printk("setting up node %d %lx-%lx\n", nodeid, start_pfn, end_pfn); 
+	
+	/* All nodes > 0 have a zero length zone DMA */ 
+	dma_end_pfn = __pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT; 
+	if (start_pfn < dma_end_pfn) { 
+		zones[ZONE_DMA] = dma_end_pfn - start_pfn;
+		zones[ZONE_NORMAL] = end_pfn - dma_end_pfn; 
+	} else { 
+		zones[ZONE_NORMAL] = end_pfn - start_pfn; 
+	} 
+    
+	free_area_init_node(nodeid, NODE_DATA(nodeid), NULL, zones, 
+			    start_pfn, NULL); 
+} 
+
+int fake_node;
+
+int __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
+{ 
+#ifdef CONFIG_K8_NUMA
+	if (!numa_off && !k8_scan_nodes(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT))
+		return 0; 
+#endif
+	printk(KERN_INFO "%s\n",
+	       numa_off ? "NUMA turned off" : "No NUMA configuration found");
+
+	if (!numa_off && emunodes > 0) { 
+		struct node nodes[MAXNODE]; 
+		unsigned long nodesize = (end_pfn << PAGE_SHIFT) / emunodes;
+		int i;
+		if (emunodes > MAXNODE) 
+			emunodes = MAXNODE; 
+		printk(KERN_INFO "Faking %d nodes of size %ld MB\n", emunodes, nodesize>>20); 
+		for (i = 0; i < emunodes; i++) { 
+			unsigned long end = (i+1)*nodesize; 
+			if (i == emunodes-1) 
+				end = end_pfn << PAGE_SHIFT;
+			nodes[i].start = i * nodesize;
+			nodes[i].end = end; 
+			setup_node_bootmem(i, nodes[i].start, nodes[i].end);
+		}
+		memnode_shift = compute_hash_shift(nodes, emunodes, nodes[i-1].end); 
+		return 0;
+	} 
+
+	printk(KERN_INFO "Faking a node at %016lx-%016lx\n", 
+	       start_pfn << PAGE_SHIFT,
+	       end_pfn << PAGE_SHIFT); 
+		/* setup dummy node covering all memory */ 
+	fake_node = 1; 	
+	memnode_shift = 63; 
+	memnodemap[0] = 0;
+	setup_node_bootmem(0, start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
+	return -1; 
+} 
+
+unsigned long __init numa_free_all_bootmem(void) 
+{ 
+	int i;
+	unsigned long pages = 0;
+	for_all_nodes(i) {
+		pages += free_all_bootmem_node(NODE_DATA(i));
+	}
+	return pages;
+} 
+
+void __init paging_init(void)
+{ 
+	int i;
+	for_all_nodes(i) { 
+		setup_node_zones(i); 
+	}
+} 
+
+/* [numa=off] */
+/* [numa=emunodes] */
+__init int numa_setup(char *opt) 
+{ 
+	if (!strncmp(opt,"off",3))
+		numa_off = 1;
+	if (isdigit(opt[0]))
+		emunodes = simple_strtoul(opt, NULL, 10); 
+	return 1;
+} 
+
+
diff -Nru a/arch/x86_64/vmlinux.lds.S b/arch/x86_64/vmlinux.lds.S
--- a/arch/x86_64/vmlinux.lds.S	Fri Feb 14 15:53:08 2003
+++ b/arch/x86_64/vmlinux.lds.S	Fri Feb 14 15:53:08 2003
@@ -47,10 +47,10 @@
   .vsyscall_0 -10*1024*1024: AT ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) { *(.vsyscall_0) }
   __vsyscall_0 = LOADADDR(.vsyscall_0);
   . = ALIGN(64);
-  .vxtime_sequence : AT ((LOADADDR(.vsyscall_0) + SIZEOF(.vsyscall_0) + 63) & ~(63)) { *(.vxtime_sequence) }
-  vxtime_sequence = LOADADDR(.vxtime_sequence);
+  .xtime_lock : AT ((LOADADDR(.vsyscall_0) + SIZEOF(.vsyscall_0) + 63) & ~(63)) { *(.xtime_lock) }
+  xtime_lock = LOADADDR(.xtime_lock);
   . = ALIGN(16);
-  .hpet : AT ((LOADADDR(.vxtime_sequence) + SIZEOF(.vxtime_sequence) + 15) & ~(15)) { *(.hpet) }
+  .hpet : AT ((LOADADDR(.xtime_lock) + SIZEOF(.xtime_lock) + 15) & ~(15)) { *(.hpet) }
   hpet = LOADADDR(.hpet);
   . = ALIGN(16);
   .wall_jiffies : AT ((LOADADDR(.hpet) + SIZEOF(.hpet) + 15) & ~(15)) { *(.wall_jiffies) }
@@ -59,7 +59,10 @@
   .sys_tz : AT ((LOADADDR(.wall_jiffies) + SIZEOF(.wall_jiffies) + 15) & ~(15)) { *(.sys_tz) }
   sys_tz = LOADADDR(.sys_tz);
   . = ALIGN(16);
-  .jiffies : AT ((LOADADDR(.sys_tz) + SIZEOF(.sys_tz) + 15) & ~(15)) { *(.jiffies) }
+  .sysctl_vsyscall : AT ((LOADADDR(.sys_tz) + SIZEOF(.sys_tz) + 15) & ~(15)) { *(.sysctl_vsyscall) }
+  sysctl_vsyscall = LOADADDR(.sysctl_vsyscall);
+  . = ALIGN(16);
+  .jiffies : AT ((LOADADDR(.sysctl_vsyscall) + SIZEOF(.sysctl_vsyscall) + 15) & ~(15)) { *(.jiffies) }
   jiffies = LOADADDR(.jiffies);
   . = ALIGN(16);
   .xtime : AT ((LOADADDR(.jiffies) + SIZEOF(.jiffies) + 15) & ~(15)) { *(.xtime) }
diff -Nru a/drivers/acorn/char/keyb_arc.c b/drivers/acorn/char/keyb_arc.c
--- a/drivers/acorn/char/keyb_arc.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acorn/char/keyb_arc.c	Fri Feb 14 15:53:09 2003
@@ -406,7 +406,6 @@
 
 static void a5kkbd_rx(int irq, void *dev_id, struct pt_regs *regs)
 {
-	kbd_pt_regs = regs;
 	if (handle_rawcode(ioc_readb(IOC_KARTRX)))
 		tasklet_schedule(&keyboard_tasklet);
 }
diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/Kconfig	Fri Feb 14 15:53:12 2003
@@ -75,6 +75,11 @@
 	  This option is not recommended for anyone except those doing driver
 	  power management development.
 
+config ACPI_SLEEP_PROC_FS
+	bool
+	depends on ACPI_SLEEP && PROC_FS
+	default y
+
 config ACPI_AC
 	tristate "AC Adapter"
 	depends on X86 && ACPI && !ACPI_HT_ONLY
diff -Nru a/drivers/acpi/Makefile b/drivers/acpi/Makefile
--- a/drivers/acpi/Makefile	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/Makefile	Fri Feb 14 15:53:12 2003
@@ -4,7 +4,7 @@
 
 export ACPI_CFLAGS
 
-ACPI_CFLAGS	:= -D_LINUX -Os -Iinclude/acpi
+ACPI_CFLAGS	:= -Os
 
 ifdef CONFIG_ACPI_DEBUG
   ACPI_CFLAGS	+= -DACPI_DEBUG_OUTPUT
@@ -30,6 +30,7 @@
 #
 # ACPI Bus and Device Drivers
 #
+obj-$(CONFIG_ACPI_BUS)		+= sleep/
 obj-$(CONFIG_ACPI_BUS)		+= bus.o
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
@@ -42,7 +43,6 @@
 obj-$(CONFIG_ACPI_THERMAL)	+= thermal.o
 obj-$(CONFIG_ACPI_SYSTEM)	+= system.o event.o
 obj-$(CONFIG_ACPI_DEBUG)	+= debug.o
-obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o
 obj-$(CONFIG_ACPI_NUMA)		+= numa.o
 obj-$(CONFIG_ACPI_TOSHIBA)	+= toshiba_acpi.o
 obj-$(CONFIG_ACPI_BUS)		+= scan.o 
diff -Nru a/drivers/acpi/ac.c b/drivers/acpi/ac.c
--- a/drivers/acpi/ac.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/ac.c	Fri Feb 14 15:53:09 2003
@@ -29,8 +29,8 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
 
 
 #define ACPI_AC_COMPONENT		0x00020000
diff -Nru a/drivers/acpi/acpi_ksyms.c b/drivers/acpi/acpi_ksyms.c
--- a/drivers/acpi/acpi_ksyms.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/acpi_ksyms.c	Fri Feb 14 15:53:09 2003
@@ -26,7 +26,7 @@
 #include <linux/module.h>
 #include <linux/acpi.h>
 #include <acpi/acpi.h>
-#include "acpi_bus.h"
+#include <acpi/acpi_bus.h>
 
 
 #ifdef CONFIG_ACPI_INTERPRETER
diff -Nru a/drivers/acpi/battery.c b/drivers/acpi/battery.c
--- a/drivers/acpi/battery.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/battery.c	Fri Feb 14 15:53:12 2003
@@ -28,8 +28,8 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
 
 
 #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
diff -Nru a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
--- a/drivers/acpi/blacklist.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/blacklist.c	Fri Feb 14 15:53:08 2003
@@ -29,7 +29,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/acpi.h>
-#include "acpi_bus.h"
+#include <acpi/acpi_bus.h>
 
 enum acpi_blacklist_predicates
 {
diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c
--- a/drivers/acpi/bus.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/bus.c	Fri Feb 14 15:53:11 2003
@@ -32,8 +32,8 @@
 #ifdef CONFIG_X86
 #include <asm/mpspec.h>
 #endif
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
 
 
 #define _COMPONENT		ACPI_BUS_COMPONENT
diff -Nru a/drivers/acpi/button.c b/drivers/acpi/button.c
--- a/drivers/acpi/button.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/button.c	Fri Feb 14 15:53:08 2003
@@ -29,8 +29,8 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
 
 
 #define ACPI_BUTTON_COMPONENT		0x00080000
diff -Nru a/drivers/acpi/debug.c b/drivers/acpi/debug.c
--- a/drivers/acpi/debug.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/debug.c	Fri Feb 14 15:53:12 2003
@@ -5,7 +5,7 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
-#include "acpi_drivers.h"
+#include <acpi/acpi_drivers.h>
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME		("debug")
diff -Nru a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c
--- a/drivers/acpi/dispatcher/dsfield.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/dispatcher/dsfield.c	Fri Feb 14 15:53:08 2003
@@ -23,12 +23,12 @@
  */
 
 
-#include "acpi.h"
-#include "amlcode.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "acparser.h"
+#include <acpi/acpi.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
 
 
 #define _COMPONENT          ACPI_DISPATCHER
diff -Nru a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
--- a/drivers/acpi/dispatcher/dsinit.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/dispatcher/dsinit.c	Fri Feb 14 15:53:12 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acdispat.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acdispat.h>
+#include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dsinit")
diff -Nru a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
--- a/drivers/acpi/dispatcher/dsmethod.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/dispatcher/dsmethod.c	Fri Feb 14 15:53:10 2003
@@ -23,12 +23,12 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "amlcode.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_DISPATCHER
diff -Nru a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
--- a/drivers/acpi/dispatcher/dsmthdat.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/dispatcher/dsmthdat.c	Fri Feb 14 15:53:09 2003
@@ -23,11 +23,11 @@
  */
 
 
-#include "acpi.h"
-#include "acdispat.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acdispat.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
 
 
 #define _COMPONENT          ACPI_DISPATCHER
diff -Nru a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
--- a/drivers/acpi/dispatcher/dsobject.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/dispatcher/dsobject.c	Fri Feb 14 15:53:08 2003
@@ -23,12 +23,12 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "amlcode.h"
-#include "acdispat.h"
-#include "acnamesp.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
 
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dsobject")
diff -Nru a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
--- a/drivers/acpi/dispatcher/dsopcode.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/dispatcher/dsopcode.c	Fri Feb 14 15:53:12 2003
@@ -24,13 +24,13 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "amlcode.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "acevents.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
 
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dsopcode")
diff -Nru a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
--- a/drivers/acpi/dispatcher/dsutils.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/dispatcher/dsutils.c	Fri Feb 14 15:53:09 2003
@@ -23,13 +23,13 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "amlcode.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "acdebug.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acdebug.h>
 
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dsutils")
diff -Nru a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
--- a/drivers/acpi/dispatcher/dswexec.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/dispatcher/dswexec.c	Fri Feb 14 15:53:12 2003
@@ -24,13 +24,13 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "amlcode.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "acdebug.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acdebug.h>
 
 
 #define _COMPONENT          ACPI_DISPATCHER
diff -Nru a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
--- a/drivers/acpi/dispatcher/dswload.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/dispatcher/dswload.c	Fri Feb 14 15:53:08 2003
@@ -23,13 +23,13 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "amlcode.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
-#include "acevents.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
 
 
 #define _COMPONENT          ACPI_DISPATCHER
diff -Nru a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c
--- a/drivers/acpi/dispatcher/dswscope.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/dispatcher/dswscope.c	Fri Feb 14 15:53:12 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acdispat.h"
+#include <acpi/acpi.h>
+#include <acpi/acdispat.h>
 
 
 #define _COMPONENT          ACPI_DISPATCHER
diff -Nru a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
--- a/drivers/acpi/dispatcher/dswstate.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/dispatcher/dswstate.c	Fri Feb 14 15:53:12 2003
@@ -23,10 +23,10 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "acdispat.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
+#include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dswstate")
diff -Nru a/drivers/acpi/ec.c b/drivers/acpi/ec.c
--- a/drivers/acpi/ec.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/acpi/ec.c	Fri Feb 14 15:53:10 2003
@@ -30,8 +30,8 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <asm/io.h>
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
 
 
 #define _COMPONENT		ACPI_EC_COMPONENT
diff -Nru a/drivers/acpi/event.c b/drivers/acpi/event.c
--- a/drivers/acpi/event.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/event.c	Fri Feb 14 15:53:08 2003
@@ -10,7 +10,7 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/poll.h>
-#include "acpi_drivers.h"
+#include <acpi/acpi_drivers.h>
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME		("event")
diff -Nru a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
--- a/drivers/acpi/events/evevent.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/events/evevent.c	Fri Feb 14 15:53:12 2003
@@ -22,8 +22,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "acpi.h"
-#include "acevents.h"
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
 
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evevent")
diff -Nru a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
--- a/drivers/acpi/events/evgpe.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/events/evgpe.c	Fri Feb 14 15:53:11 2003
@@ -22,9 +22,9 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "acpi.h"
-#include "acevents.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evgpe")
diff -Nru a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
--- a/drivers/acpi/events/evmisc.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/events/evmisc.c	Fri Feb 14 15:53:11 2003
@@ -22,10 +22,10 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "acpi.h"
-#include "acevents.h"
-#include "acnamesp.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
 
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evmisc")
diff -Nru a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
--- a/drivers/acpi/events/evregion.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/events/evregion.c	Fri Feb 14 15:53:08 2003
@@ -23,10 +23,10 @@
  */
 
 
-#include "acpi.h"
-#include "acevents.h"
-#include "acnamesp.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
 
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evregion")
diff -Nru a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
--- a/drivers/acpi/events/evrgnini.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/events/evrgnini.c	Fri Feb 14 15:53:08 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acevents.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evrgnini")
diff -Nru a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c
--- a/drivers/acpi/events/evsci.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/events/evsci.c	Fri Feb 14 15:53:11 2003
@@ -23,8 +23,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "acpi.h"
-#include "acevents.h"
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
 
 
 #define _COMPONENT          ACPI_EVENTS
diff -Nru a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
--- a/drivers/acpi/events/evxface.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/events/evxface.c	Fri Feb 14 15:53:11 2003
@@ -23,10 +23,10 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
-#include "acevents.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+#include <acpi/acinterp.h>
 
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evxface")
diff -Nru a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
--- a/drivers/acpi/events/evxfevnt.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/events/evxfevnt.c	Fri Feb 14 15:53:09 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acevents.h"
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
 
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evxfevnt")
diff -Nru a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
--- a/drivers/acpi/events/evxfregn.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/events/evxfregn.c	Fri Feb 14 15:53:09 2003
@@ -24,10 +24,10 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
-#include "acevents.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+#include <acpi/acinterp.h>
 
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evxfregn")
diff -Nru a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
--- a/drivers/acpi/executer/exconfig.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/executer/exconfig.c	Fri Feb 14 15:53:11 2003
@@ -23,12 +23,12 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "acevents.h"
-#include "actables.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+#include <acpi/actables.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
--- a/drivers/acpi/executer/exconvrt.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/executer/exconvrt.c	Fri Feb 14 15:53:08 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
-#include "amlcode.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
--- a/drivers/acpi/executer/excreate.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/executer/excreate.c	Fri Feb 14 15:53:12 2003
@@ -23,12 +23,12 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "acevents.h"
-#include "actables.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
+#include <acpi/actables.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
--- a/drivers/acpi/executer/exdump.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/executer/exdump.c	Fri Feb 14 15:53:08 2003
@@ -23,11 +23,11 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "acparser.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exdump")
diff -Nru a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
--- a/drivers/acpi/executer/exfield.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/executer/exfield.c	Fri Feb 14 15:53:08 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acdispat.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
--- a/drivers/acpi/executer/exfldio.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/executer/exfldio.c	Fri Feb 14 15:53:09 2003
@@ -23,11 +23,11 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acevents.h"
-#include "acdispat.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acevents.h>
+#include <acpi/acdispat.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
--- a/drivers/acpi/executer/exmisc.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/executer/exmisc.c	Fri Feb 14 15:53:12 2003
@@ -24,9 +24,9 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
-#include "amlcode.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
--- a/drivers/acpi/executer/exmutex.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/executer/exmutex.c	Fri Feb 14 15:53:12 2003
@@ -24,8 +24,8 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exmutex")
diff -Nru a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c
--- a/drivers/acpi/executer/exnames.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/executer/exnames.c	Fri Feb 14 15:53:09 2003
@@ -24,9 +24,9 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
-#include "amlcode.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exnames")
diff -Nru a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
--- a/drivers/acpi/executer/exoparg1.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/executer/exoparg1.c	Fri Feb 14 15:53:12 2003
@@ -24,12 +24,12 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
--- a/drivers/acpi/executer/exoparg2.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/acpi/executer/exoparg2.c	Fri Feb 14 15:53:10 2003
@@ -23,11 +23,11 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "acinterp.h"
-#include "acevents.h"
-#include "amlcode.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acinterp.h>
+#include <acpi/acevents.h>
+#include <acpi/amlcode.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c
--- a/drivers/acpi/executer/exoparg3.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/executer/exoparg3.c	Fri Feb 14 15:53:08 2003
@@ -24,10 +24,10 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
-#include "acparser.h"
-#include "amlcode.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c
--- a/drivers/acpi/executer/exoparg6.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/executer/exoparg6.c	Fri Feb 14 15:53:12 2003
@@ -24,10 +24,10 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
-#include "acparser.h"
-#include "amlcode.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c
--- a/drivers/acpi/executer/exprep.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/executer/exprep.c	Fri Feb 14 15:53:09 2003
@@ -24,10 +24,10 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
--- a/drivers/acpi/executer/exregion.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/executer/exregion.c	Fri Feb 14 15:53:09 2003
@@ -24,8 +24,8 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c
--- a/drivers/acpi/executer/exresnte.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/executer/exresnte.c	Fri Feb 14 15:53:09 2003
@@ -24,10 +24,10 @@
  */
 
 
-#include "acpi.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
--- a/drivers/acpi/executer/exresolv.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/executer/exresolv.c	Fri Feb 14 15:53:09 2003
@@ -24,11 +24,11 @@
  */
 
 
-#include "acpi.h"
-#include "amlcode.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/amlcode.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
--- a/drivers/acpi/executer/exresop.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/executer/exresop.c	Fri Feb 14 15:53:12 2003
@@ -24,10 +24,10 @@
  */
 
 
-#include "acpi.h"
-#include "amlcode.h"
-#include "acparser.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/amlcode.h>
+#include <acpi/acparser.h>
+#include <acpi/acinterp.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
--- a/drivers/acpi/executer/exstore.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/executer/exstore.c	Fri Feb 14 15:53:09 2003
@@ -24,11 +24,11 @@
  */
 
 
-#include "acpi.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
--- a/drivers/acpi/executer/exstoren.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/executer/exstoren.c	Fri Feb 14 15:53:08 2003
@@ -25,8 +25,8 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
--- a/drivers/acpi/executer/exstorob.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/executer/exstorob.c	Fri Feb 14 15:53:12 2003
@@ -24,8 +24,8 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
diff -Nru a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
--- a/drivers/acpi/executer/exsystem.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/executer/exsystem.c	Fri Feb 14 15:53:11 2003
@@ -24,9 +24,9 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
-#include "acevents.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/acevents.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exsystem")
diff -Nru a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
--- a/drivers/acpi/executer/exutils.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/executer/exutils.c	Fri Feb 14 15:53:09 2003
@@ -40,10 +40,10 @@
 
 #define DEFINE_AML_GLOBALS
 
-#include "acpi.h"
-#include "acinterp.h"
-#include "amlcode.h"
-#include "acevents.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
+#include <acpi/acevents.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exutils")
diff -Nru a/drivers/acpi/fan.c b/drivers/acpi/fan.c
--- a/drivers/acpi/fan.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/fan.c	Fri Feb 14 15:53:08 2003
@@ -28,8 +28,8 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
 
 
 #define ACPI_FAN_COMPONENT		0x00200000
diff -Nru a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c
--- a/drivers/acpi/hardware/hwacpi.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/hardware/hwacpi.c	Fri Feb 14 15:53:08 2003
@@ -24,7 +24,7 @@
  */
 
 
-#include "acpi.h"
+#include <acpi/acpi.h>
 
 
 #define _COMPONENT          ACPI_HARDWARE
diff -Nru a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
--- a/drivers/acpi/hardware/hwgpe.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/hardware/hwgpe.c	Fri Feb 14 15:53:08 2003
@@ -23,8 +23,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "acpi.h"
-#include "acevents.h"
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
 
 #define _COMPONENT          ACPI_HARDWARE
 	 ACPI_MODULE_NAME    ("hwgpe")
diff -Nru a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
--- a/drivers/acpi/hardware/hwregs.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/hardware/hwregs.c	Fri Feb 14 15:53:12 2003
@@ -25,8 +25,8 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_HARDWARE
 	 ACPI_MODULE_NAME    ("hwregs")
diff -Nru a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
--- a/drivers/acpi/hardware/hwsleep.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/hardware/hwsleep.c	Fri Feb 14 15:53:08 2003
@@ -23,7 +23,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "acpi.h"
+#include <acpi/acpi.h>
 
 #define _COMPONENT          ACPI_HARDWARE
 	 ACPI_MODULE_NAME    ("hwsleep")
diff -Nru a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
--- a/drivers/acpi/hardware/hwtimer.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/hardware/hwtimer.c	Fri Feb 14 15:53:08 2003
@@ -23,7 +23,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "acpi.h"
+#include <acpi/acpi.h>
 
 #define _COMPONENT          ACPI_HARDWARE
 	 ACPI_MODULE_NAME    ("hwtimer")
diff -Nru a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
--- a/drivers/acpi/namespace/nsaccess.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/namespace/nsaccess.c	Fri Feb 14 15:53:12 2003
@@ -23,10 +23,10 @@
  */
 
 
-#include "acpi.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "acdispat.h"
+#include <acpi/acpi.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acdispat.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
--- a/drivers/acpi/namespace/nsalloc.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/acpi/namespace/nsalloc.c	Fri Feb 14 15:53:10 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
--- a/drivers/acpi/namespace/nsdump.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/namespace/nsdump.c	Fri Feb 14 15:53:12 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
-#include "acparser.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c
--- a/drivers/acpi/namespace/nsdumpdv.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/namespace/nsdumpdv.c	Fri Feb 14 15:53:08 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
--- a/drivers/acpi/namespace/nseval.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/namespace/nseval.c	Fri Feb 14 15:53:09 2003
@@ -24,10 +24,10 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "acinterp.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
--- a/drivers/acpi/namespace/nsinit.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/namespace/nsinit.c	Fri Feb 14 15:53:09 2003
@@ -23,10 +23,10 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
-#include "acdispat.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
 
 #define _COMPONENT          ACPI_NAMESPACE
 	 ACPI_MODULE_NAME    ("nsinit")
diff -Nru a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
--- a/drivers/acpi/namespace/nsload.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/namespace/nsload.c	Fri Feb 14 15:53:12 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
-#include "acdispat.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acdispat.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
--- a/drivers/acpi/namespace/nsnames.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/namespace/nsnames.c	Fri Feb 14 15:53:12 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "amlcode.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c
--- a/drivers/acpi/namespace/nsobject.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/namespace/nsobject.c	Fri Feb 14 15:53:09 2003
@@ -24,8 +24,8 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c
--- a/drivers/acpi/namespace/nsparse.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/namespace/nsparse.c	Fri Feb 14 15:53:08 2003
@@ -23,10 +23,10 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
-#include "acparser.h"
-#include "acdispat.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
--- a/drivers/acpi/namespace/nssearch.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/namespace/nssearch.c	Fri Feb 14 15:53:12 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
--- a/drivers/acpi/namespace/nsutils.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/acpi/namespace/nsutils.c	Fri Feb 14 15:53:10 2003
@@ -24,10 +24,10 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
-#include "amlcode.h"
-#include "actables.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/amlcode.h>
+#include <acpi/actables.h>
 
 #define _COMPONENT          ACPI_NAMESPACE
 	 ACPI_MODULE_NAME    ("nsutils")
diff -Nru a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c
--- a/drivers/acpi/namespace/nswalk.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/namespace/nswalk.c	Fri Feb 14 15:53:12 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
--- a/drivers/acpi/namespace/nsxfeval.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/namespace/nsxfeval.c	Fri Feb 14 15:53:12 2003
@@ -24,8 +24,8 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
--- a/drivers/acpi/namespace/nsxfname.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/namespace/nsxfname.c	Fri Feb 14 15:53:09 2003
@@ -24,8 +24,8 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c
--- a/drivers/acpi/namespace/nsxfobj.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/namespace/nsxfobj.c	Fri Feb 14 15:53:08 2003
@@ -24,8 +24,8 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_NAMESPACE
diff -Nru a/drivers/acpi/numa.c b/drivers/acpi/numa.c
--- a/drivers/acpi/numa.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/numa.c	Fri Feb 14 15:53:12 2003
@@ -29,7 +29,7 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/acpi.h>
-#include "acpi_bus.h"
+#include <acpi/acpi_bus.h>
 
 extern int __init acpi_table_parse_madt_family (enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler);
 
diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c
--- a/drivers/acpi/osl.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/osl.c	Fri Feb 14 15:53:12 2003
@@ -37,7 +37,7 @@
 #include <linux/workqueue.h>
 #include <acpi/acpi.h>
 #include <asm/io.h>
-#include "acpi_bus.h"
+#include <acpi/acpi_bus.h>
 
 #ifdef CONFIG_ACPI_EFI
 #include <linux/efi.h>
@@ -143,9 +143,9 @@
 #ifdef CONFIG_ACPI_EFI
 	addr->pointer_type = ACPI_PHYSICAL_POINTER;
 	if (efi.acpi20)
-		addr->pointer.physical = (ACPI_PHYSICAL_ADDRESS) virt_to_phys(efi.acpi20);
+		addr->pointer.physical = (acpi_physical_address) virt_to_phys(efi.acpi20);
 	else if (efi.acpi)
-		addr->pointer.physical = (ACPI_PHYSICAL_ADDRESS) virt_to_phys(efi.acpi);
+		addr->pointer.physical = (acpi_physical_address) virt_to_phys(efi.acpi);
 	else {
 		printk(KERN_ERR PREFIX "System description tables not found\n");
 		return AE_NOT_FOUND;
diff -Nru a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
--- a/drivers/acpi/parser/psargs.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/parser/psargs.c	Fri Feb 14 15:53:09 2003
@@ -23,10 +23,10 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "amlcode.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_PARSER
 	 ACPI_MODULE_NAME    ("psargs")
diff -Nru a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
--- a/drivers/acpi/parser/psopcode.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/parser/psopcode.c	Fri Feb 14 15:53:09 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "amlcode.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
 
 
 #define _COMPONENT          ACPI_PARSER
diff -Nru a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
--- a/drivers/acpi/parser/psparse.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/parser/psparse.c	Fri Feb 14 15:53:09 2003
@@ -32,12 +32,12 @@
  * templates in aml_op_info[]
  */
 
-#include "acpi.h"
-#include "acparser.h"
-#include "acdispat.h"
-#include "amlcode.h"
-#include "acnamesp.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
 
 #define _COMPONENT          ACPI_PARSER
 	 ACPI_MODULE_NAME    ("psparse")
diff -Nru a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c
--- a/drivers/acpi/parser/psscope.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/parser/psscope.c	Fri Feb 14 15:53:08 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
 
 #define _COMPONENT          ACPI_PARSER
 	 ACPI_MODULE_NAME    ("psscope")
diff -Nru a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c
--- a/drivers/acpi/parser/pstree.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/parser/pstree.c	Fri Feb 14 15:53:09 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "amlcode.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
 
 #define _COMPONENT          ACPI_PARSER
 	 ACPI_MODULE_NAME    ("pstree")
diff -Nru a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
--- a/drivers/acpi/parser/psutils.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/parser/psutils.c	Fri Feb 14 15:53:11 2003
@@ -23,10 +23,10 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "amlcode.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_PARSER
 	 ACPI_MODULE_NAME    ("psutils")
diff -Nru a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c
--- a/drivers/acpi/parser/pswalk.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/parser/pswalk.c	Fri Feb 14 15:53:12 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "acdispat.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
 
 #define _COMPONENT          ACPI_PARSER
 	 ACPI_MODULE_NAME    ("pswalk")
diff -Nru a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
--- a/drivers/acpi/parser/psxface.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/parser/psxface.c	Fri Feb 14 15:53:12 2003
@@ -23,11 +23,11 @@
  */
 
 
-#include "acpi.h"
-#include "acparser.h"
-#include "acdispat.h"
-#include "acinterp.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_PARSER
diff -Nru a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
--- a/drivers/acpi/pci_bind.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/pci_bind.c	Fri Feb 14 15:53:12 2003
@@ -32,8 +32,8 @@
 #include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/acpi.h>
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
 
 
 #define _COMPONENT		ACPI_PCI_COMPONENT
@@ -185,7 +185,7 @@
 	 */
 	data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function));
 	if (!data->dev) {
-		ACPI_DEBUG_PRINT((ACPI_DB_WARN, 
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 			"Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
 			data->id.segment, data->id.bus, 
 			data->id.device, data->id.function));
diff -Nru a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
--- a/drivers/acpi/pci_irq.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/pci_irq.c	Fri Feb 14 15:53:09 2003
@@ -36,8 +36,8 @@
 #ifdef CONFIG_X86_IO_APIC
 #include <asm/mpspec.h>
 #endif
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
 
 
 #define _COMPONENT		ACPI_PCI_COMPONENT
diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
--- a/drivers/acpi/pci_link.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/pci_link.c	Fri Feb 14 15:53:08 2003
@@ -38,8 +38,8 @@
 #include <linux/pm.h>
 #include <linux/pci.h>
 
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
 
 
 #define _COMPONENT		ACPI_PCI_COMPONENT
diff -Nru a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
--- a/drivers/acpi/pci_root.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/pci_root.c	Fri Feb 14 15:53:09 2003
@@ -32,8 +32,8 @@
 #include <linux/pm.h>
 #include <linux/pci.h>
 #include <linux/acpi.h>
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
 
 
 #define _COMPONENT		ACPI_PCI_COMPONENT
diff -Nru a/drivers/acpi/power.c b/drivers/acpi/power.c
--- a/drivers/acpi/power.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/acpi/power.c	Fri Feb 14 15:53:10 2003
@@ -29,8 +29,8 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
 
 
 #define _COMPONENT		ACPI_POWER_COMPONENT
diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c
--- a/drivers/acpi/processor.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/processor.c	Fri Feb 14 15:53:11 2003
@@ -44,9 +44,9 @@
 #include <asm/system.h>
 #include <asm/delay.h>
 
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
-#include "processor.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/processor.h>
 
 
 #define ACPI_PROCESSOR_COMPONENT	0x01000000
diff -Nru a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
--- a/drivers/acpi/resources/rsaddr.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/acpi/resources/rsaddr.c	Fri Feb 14 15:53:10 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acresrc.h"
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
 
 #define _COMPONENT          ACPI_RESOURCES
 	 ACPI_MODULE_NAME    ("rsaddr")
diff -Nru a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
--- a/drivers/acpi/resources/rscalc.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/acpi/resources/rscalc.c	Fri Feb 14 15:53:10 2003
@@ -23,10 +23,10 @@
  */
 
 
-#include "acpi.h"
-#include "acresrc.h"
-#include "amlcode.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_RESOURCES
 	 ACPI_MODULE_NAME    ("rscalc")
diff -Nru a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
--- a/drivers/acpi/resources/rscreate.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/resources/rscreate.c	Fri Feb 14 15:53:09 2003
@@ -23,10 +23,10 @@
  */
 
 
-#include "acpi.h"
-#include "acresrc.h"
-#include "amlcode.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
+#include <acpi/amlcode.h>
+#include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_RESOURCES
 	 ACPI_MODULE_NAME    ("rscreate")
diff -Nru a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c
--- a/drivers/acpi/resources/rsdump.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/acpi/resources/rsdump.c	Fri Feb 14 15:53:10 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acresrc.h"
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
 
 #define _COMPONENT          ACPI_RESOURCES
 	 ACPI_MODULE_NAME    ("rsdump")
diff -Nru a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c
--- a/drivers/acpi/resources/rsio.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/resources/rsio.c	Fri Feb 14 15:53:08 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acresrc.h"
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
 
 #define _COMPONENT          ACPI_RESOURCES
 	 ACPI_MODULE_NAME    ("rsio")
diff -Nru a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c
--- a/drivers/acpi/resources/rsirq.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/resources/rsirq.c	Fri Feb 14 15:53:12 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acresrc.h"
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
 
 #define _COMPONENT          ACPI_RESOURCES
 	 ACPI_MODULE_NAME    ("rsirq")
diff -Nru a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
--- a/drivers/acpi/resources/rslist.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/resources/rslist.c	Fri Feb 14 15:53:12 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acresrc.h"
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
 
 #define _COMPONENT          ACPI_RESOURCES
 	 ACPI_MODULE_NAME    ("rslist")
diff -Nru a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c
--- a/drivers/acpi/resources/rsmemory.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/resources/rsmemory.c	Fri Feb 14 15:53:12 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acresrc.h"
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
 
 #define _COMPONENT          ACPI_RESOURCES
 	 ACPI_MODULE_NAME    ("rsmemory")
diff -Nru a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c
--- a/drivers/acpi/resources/rsmisc.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/resources/rsmisc.c	Fri Feb 14 15:53:09 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acresrc.h"
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
 
 #define _COMPONENT          ACPI_RESOURCES
 	 ACPI_MODULE_NAME    ("rsmisc")
diff -Nru a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
--- a/drivers/acpi/resources/rsutils.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/resources/rsutils.c	Fri Feb 14 15:53:08 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
-#include "acresrc.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acresrc.h>
 
 
 #define _COMPONENT          ACPI_RESOURCES
diff -Nru a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
--- a/drivers/acpi/resources/rsxface.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/resources/rsxface.c	Fri Feb 14 15:53:12 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acresrc.h"
+#include <acpi/acpi.h>
+#include <acpi/acresrc.h>
 
 #define _COMPONENT          ACPI_RESOURCES
 	 ACPI_MODULE_NAME    ("rsxface")
diff -Nru a/drivers/acpi/scan.c b/drivers/acpi/scan.c
--- a/drivers/acpi/scan.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/scan.c	Fri Feb 14 15:53:09 2003
@@ -5,7 +5,7 @@
 #include <linux/init.h>
 #include <linux/acpi.h>
 
-#include "acpi_drivers.h"
+#include <acpi/acpi_drivers.h>
 #include <acpi/acinterp.h>	/* for acpi_ex_eisa_id_to_string() */
 
 
@@ -295,15 +295,15 @@
 	ACPI_FUNCTION_TRACE("acpi_driver_attach");
 
 	spin_lock(&acpi_device_lock);
-	list_for_each_safe(node,next,&acpi_device_list) {
-		struct acpi_device * dev = container_of(node,struct acpi_device,g_list);
+	list_for_each_safe(node, next, &acpi_device_list) {
+		struct acpi_device * dev = container_of(node, struct acpi_device, g_list);
 
 		if (dev->driver || !dev->status.present)
 			continue;
 		spin_unlock(&acpi_device_lock);
 
-		if (!acpi_bus_match(dev,drv)) {
-			if (!acpi_bus_driver_init(dev,drv)) {
+		if (!acpi_bus_match(dev, drv)) {
+			if (!acpi_bus_driver_init(dev, drv)) {
 				atomic_inc(&drv->references);
 				ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
 						  drv->name, dev->pnp.bus_id));
diff -Nru a/drivers/acpi/sleep/Makefile b/drivers/acpi/sleep/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/acpi/sleep/Makefile	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,5 @@
+obj-y					:= poweroff.o
+obj-$(CONFIG_ACPI_SLEEP)		+= main.o
+obj-$(CONFIG_ACPI_SLEEP_PROC_FS)	+= proc.o
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff -Nru a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/acpi/sleep/main.c	Fri Feb 14 15:53:08 2003
@@ -0,0 +1,277 @@
+/*
+ * sleep.c - ACPI sleep support.
+ * 
+ *  Copyright (c) 2000-2003 Patrick Mochel
+ *
+ *  Portions are
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/device.h>
+#include <linux/suspend.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include "sleep.h"
+
+#define _COMPONENT		ACPI_SYSTEM_COMPONENT
+ACPI_MODULE_NAME		("sleep")
+
+u8 sleep_states[ACPI_S_STATE_COUNT];
+
+/**
+ * acpi_system_restore_state - OS-specific restoration of state
+ * @state:	sleep state we're exiting
+ *
+ * Note that if we're coming back from S4, the memory image should have already
+ * been loaded from the disk and is already in place. (Otherwise how else would we
+ * be here?).
+ */
+acpi_status
+acpi_system_restore_state (
+	u32			state)
+{
+	/* restore processor state
+	 * We should only be here if we're coming back from STR or STD.
+	 * And, in the case of the latter, the memory image should have already
+	 * been loaded from disk.
+	 */
+	if (state > ACPI_STATE_S1)
+		acpi_restore_state_mem();
+
+	/* wait for power to come back */
+	mdelay(10);
+
+	/* turn all the devices back on */
+	device_resume(RESUME_POWER_ON);
+
+	/* enable interrupts once again */
+	ACPI_ENABLE_IRQS();
+
+	/* restore device context */
+	device_resume(RESUME_RESTORE_STATE);
+
+	if (dmi_broken & BROKEN_INIT_AFTER_S1) {
+		printk("Broken toshiba laptop -> kicking interrupts\n");
+		init_8259A(0);
+	}
+
+	return AE_OK;
+}
+
+/**
+ * acpi_system_save_state - save OS specific state and power down devices
+ * @state:	sleep state we're entering.
+ *
+ * This handles saving all context to memory, and possibly disk.
+ * First, we call to the device driver layer to save device state.
+ * Once we have that, we save whatevery processor and kernel state we
+ * need to memory.
+ * If we're entering S4, we then write the memory image to disk.
+ *
+ * Only then is it safe for us to power down devices, since we may need
+ * the disks and upstream buses to write to.
+ */
+acpi_status
+acpi_system_save_state(
+	u32			state)
+{
+	int			error = 0;
+
+	/* Send notification to devices that they will be suspended.
+	 * If any device or driver cannot make the transition, either up
+	 * or down, we'll get an error back.
+	 */
+	error = device_suspend(state, SUSPEND_NOTIFY);
+	if (error)
+		return AE_ERROR;
+
+	if (state < ACPI_STATE_S5) {
+
+		/* Tell devices to stop I/O and actually save their state.
+		 * It is theoretically possible that something could fail,
+		 * so handle that gracefully..
+		 */
+		error = device_suspend(state, SUSPEND_SAVE_STATE);
+		if (error) {
+			/* tell devices to restore state if they have
+			 * it saved and to start taking I/O requests.
+			 */
+			device_resume(RESUME_RESTORE_STATE);
+			return error;
+		}
+
+		/* flush caches */
+		ACPI_FLUSH_CPU_CACHE();
+
+		/* Do arch specific saving of state. */
+		if (state > ACPI_STATE_S1) {
+			error = acpi_save_state_mem();
+
+			if (!error && (state == ACPI_STATE_S4))
+				error = acpi_save_state_disk();
+
+			if (error) {
+				device_resume(RESUME_RESTORE_STATE);
+				return error;
+			}
+		}
+	}
+
+	/* disable interrupts
+	 * Note that acpi_suspend -- our caller -- will do this once we return.
+	 * But, we want it done early, so we don't get any suprises during
+	 * the device suspend sequence.
+	 */
+	ACPI_DISABLE_IRQS();
+
+	/* Unconditionally turn off devices.
+	 * Obvious if we enter a sleep state.
+	 * If entering S5 (soft off), this should put devices in a
+	 * quiescent state.
+	 */
+	error = device_suspend(state, SUSPEND_POWER_DOWN);
+
+	/* We're pretty screwed if we got an error from this.
+	 * We try to recover by simply calling our own restore_state
+	 * function; see above for definition.
+	 *
+	 * If it's S5 though, go through with it anyway..
+	 */
+	if (error && state != ACPI_STATE_S5)
+		acpi_system_restore_state(state);
+
+	return error ? AE_ERROR : AE_OK;
+}
+
+
+/****************************************************************************
+ *
+ * FUNCTION:    acpi_system_suspend
+ *
+ * PARAMETERS:  %state: Sleep state to enter.
+ *
+ * RETURN:      acpi_status, whether or not we successfully entered and
+ *              exited sleep.
+ *
+ * DESCRIPTION: Perform OS-specific action to enter sleep state.
+ *              This is the final step in going to sleep, per spec.  If we
+ *              know we're coming back (i.e. not entering S5), we save the
+ *              processor flags. [ We'll have to save and restore them anyway,
+ *              so we use the arch-agnostic save_flags and restore_flags
+ *              here.]  We then set the place to return to in arch-specific
+ *              globals using arch_set_return_point. Finally, we call the
+ *              ACPI function to write the proper values to I/O ports.
+ *
+ ****************************************************************************/
+
+acpi_status
+acpi_system_suspend(
+	u32			state)
+{
+	acpi_status		status = AE_ERROR;
+	unsigned long		flags = 0;
+
+	local_irq_save(flags);
+	
+	switch (state)
+	{
+	case ACPI_STATE_S1:
+		barrier();
+		status = acpi_enter_sleep_state(state);
+		break;
+
+	case ACPI_STATE_S2:
+#ifdef CONFIG_SOFTWARE_SUSPEND
+	case ACPI_STATE_S3:
+		do_suspend_lowlevel(0);
+#endif
+		break;
+	}
+	local_irq_restore(flags);
+
+	return status;
+}
+
+
+/**
+ * acpi_suspend - OS-agnostic system suspend/resume support (S? states)
+ * @state:	state we're entering
+ *
+ */
+acpi_status
+acpi_suspend (
+	u32			state)
+{
+	acpi_status status;
+
+	/* get out if state is invalid */
+	if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5)
+		return AE_ERROR;
+
+	freeze_processes();		/* device_suspend needs processes to be stopped */
+
+	/* do we have a wakeup address for S2 and S3? */
+	if (state == ACPI_STATE_S2 || state == ACPI_STATE_S3) {
+		if (!acpi_wakeup_address)
+			return AE_ERROR;
+		acpi_set_firmware_waking_vector((acpi_physical_address) acpi_wakeup_address);
+	}
+
+	acpi_enter_sleep_state_prep(state);
+
+	status = acpi_system_save_state(state);
+	if (!ACPI_SUCCESS(status))
+		return status;
+
+	/* disable interrupts and flush caches */
+	ACPI_DISABLE_IRQS();
+	ACPI_FLUSH_CPU_CACHE();
+
+	/* perform OS-specific sleep actions */
+	status = acpi_system_suspend(state);
+
+	/* Even if we failed to go to sleep, all of the devices are in an suspended
+	 * mode. So, we run these unconditionaly to make sure we have a usable system
+	 * no matter what.
+	 */
+	acpi_system_restore_state(state);
+	acpi_leave_sleep_state(state);
+
+	/* make sure interrupts are enabled */
+	ACPI_ENABLE_IRQS();
+
+	/* reset firmware waking vector */
+	acpi_set_firmware_waking_vector((acpi_physical_address) 0);
+	thaw_processes();
+
+	return status;
+}
+
+static int __init acpi_sleep_init(void)
+{
+	int			i = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_system_add_fs");
+
+	if (acpi_disabled)
+		return_VALUE(0);
+
+	printk(KERN_INFO PREFIX "(supports");
+	for (i=0; i<ACPI_S_STATE_COUNT; i++) {
+		acpi_status status;
+		u8 type_a, type_b;
+		status = acpi_get_sleep_type_data(i, &type_a, &type_b);
+		if (ACPI_SUCCESS(status)) {
+			sleep_states[i] = 1;
+			printk(" S%d", i);
+		}
+	}
+	printk(")\n");
+
+	return_VALUE(0);
+}
+
+late_initcall(acpi_sleep_init);
diff -Nru a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/acpi/sleep/poweroff.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,34 @@
+/*
+ * poweroff.c - ACPI handler for powering off the system.
+ *
+ * AKA S5, but it is independent of whether or not the kernel supports
+ * any other sleep support in the system.
+ */
+
+#include <linux/pm.h>
+#include <linux/init.h>
+#include <acpi/acpi_bus.h>
+
+static void
+acpi_power_off (void)
+{
+	printk("%s called\n",__FUNCTION__);
+	acpi_enter_sleep_state_prep(ACPI_STATE_S5);
+	ACPI_DISABLE_IRQS();
+	acpi_enter_sleep_state(ACPI_STATE_S5);
+}
+
+static int acpi_poweroff_init(void)
+{
+	if (!acpi_disabled) {
+		u8 type_a, type_b;
+		acpi_status status;
+
+		status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
+		if (ACPI_SUCCESS(status))
+			pm_power_off = acpi_power_off;
+	}
+	return 0;
+}
+
+late_initcall(acpi_poweroff_init);
diff -Nru a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/acpi/sleep/proc.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,397 @@
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/suspend.h>
+#include <linux/bcd.h>
+#include <asm/uaccess.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#ifdef CONFIG_X86
+#include <linux/mc146818rtc.h>
+#endif
+
+#include "sleep.h"
+
+#define ACPI_SYSTEM_FILE_SLEEP		"sleep"
+#define ACPI_SYSTEM_FILE_ALARM		"alarm"
+
+#define _COMPONENT		ACPI_SYSTEM_COMPONENT
+ACPI_MODULE_NAME		("sleep")
+
+
+static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
+{
+	int			i;
+
+	ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show");
+
+	for (i = 0; i <= ACPI_STATE_S5; i++) {
+		if (sleep_states[i])
+			seq_printf(seq,"S%d ", i);
+	}
+
+	seq_puts(seq, "\n");
+
+	return 0;
+}
+
+static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data);
+}
+
+static int
+acpi_system_write_sleep (
+	struct file		*file,
+	const char		*buffer,
+	size_t			count,
+	loff_t			*ppos)
+{
+	acpi_status		status = AE_ERROR;
+	char			state_string[12] = {'\0'};
+	u32			state = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_system_write_sleep");
+
+	if (count > sizeof(state_string) - 1)
+		goto Done;
+
+	if (copy_from_user(state_string, buffer, count))
+		return_VALUE(-EFAULT);
+	
+	state_string[count] = '\0';
+	
+	state = simple_strtoul(state_string, NULL, 0);
+
+	if (state < 1 || state > 4)
+		goto Done;
+
+	if (!sleep_states[state]) 
+		goto Done;
+
+#ifdef CONFIG_SOFTWARE_SUSPEND
+	if (state == 4) {
+		software_suspend();
+		goto Done;
+	}
+#endif
+	status = acpi_suspend(state);
+ Done:
+	if (ACPI_FAILURE(status))
+		return_VALUE(-EINVAL);
+	else
+		return_VALUE(count);
+}
+
+static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
+{
+	u32			sec, min, hr;
+	u32			day, mo, yr;
+
+	ACPI_FUNCTION_TRACE("acpi_system_alarm_seq_show");
+
+	spin_lock(&rtc_lock);
+
+	sec = CMOS_READ(RTC_SECONDS_ALARM);
+	min = CMOS_READ(RTC_MINUTES_ALARM);
+	hr = CMOS_READ(RTC_HOURS_ALARM);
+
+#if 0	/* If we ever get an FACP with proper values... */
+	if (acpi_gbl_FADT->day_alrm)
+		day = CMOS_READ(acpi_gbl_FADT->day_alrm);
+	else
+		day =  CMOS_READ(RTC_DAY_OF_MONTH);
+	if (acpi_gbl_FADT->mon_alrm)
+		mo = CMOS_READ(acpi_gbl_FADT->mon_alrm);
+	else
+		mo = CMOS_READ(RTC_MONTH);;
+	if (acpi_gbl_FADT->century)
+		yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR);
+	else
+		yr = CMOS_READ(RTC_YEAR);
+#else
+	day = CMOS_READ(RTC_DAY_OF_MONTH);
+	mo = CMOS_READ(RTC_MONTH);
+	yr = CMOS_READ(RTC_YEAR);
+#endif
+
+	spin_unlock(&rtc_lock);
+
+	BCD_TO_BIN(sec);
+	BCD_TO_BIN(min);
+	BCD_TO_BIN(hr);
+	BCD_TO_BIN(day);
+	BCD_TO_BIN(mo);
+	BCD_TO_BIN(yr);
+
+#if 0
+	/* we're trusting the FADT (see above)*/
+#else
+	/* If we're not trusting the FADT, we should at least make it
+	 * right for _this_ century... ehm, what is _this_ century?
+	 *
+	 * TBD:
+	 *  ASAP: find piece of code in the kernel, e.g. star tracker driver,
+	 *        which we can trust to determine the century correctly. Atom
+	 *        watch driver would be nice, too...
+	 *
+	 *  if that has not happened, change for first release in 2050:
+ 	 *        if (yr<50)
+	 *                yr += 2100;
+	 *        else
+	 *                yr += 2000;   // current line of code
+	 *
+	 *  if that has not happened either, please do on 2099/12/31:23:59:59
+	 *        s/2000/2100
+	 *
+	 */
+	yr += 2000;
+#endif
+
+	seq_printf(seq,"%4.4u-", yr);
+	(mo > 12)  ? seq_puts(seq, "**-")  : seq_printf(seq, "%2.2u-", mo);
+	(day > 31) ? seq_puts(seq, "** ")  : seq_printf(seq, "%2.2u ", day);
+	(hr > 23)  ? seq_puts(seq, "**:")  : seq_printf(seq, "%2.2u:", hr);
+	(min > 59) ? seq_puts(seq, "**:")  : seq_printf(seq, "%2.2u:", min);
+	(sec > 59) ? seq_puts(seq, "**\n") : seq_printf(seq, "%2.2u\n", sec);
+
+	return 0;
+}
+
+static int acpi_system_alarm_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_system_alarm_seq_show, PDE(inode)->data);
+}
+
+
+static int
+get_date_field (
+	char			**p,
+	u32			*value)
+{
+	char			*next = NULL;
+	char			*string_end = NULL;
+	int			result = -EINVAL;
+
+	/*
+	 * Try to find delimeter, only to insert null.  The end of the
+	 * string won't have one, but is still valid.
+	 */
+	next = strpbrk(*p, "- :");
+	if (next)
+		*next++ = '\0';
+
+	*value = simple_strtoul(*p, &string_end, 10);
+
+	/* Signal success if we got a good digit */
+	if (string_end != *p)
+		result = 0;
+
+	if (next)
+		*p = next;
+
+	return result;
+}
+
+
+static int
+acpi_system_write_alarm (
+	struct file		*file,
+	const char		*buffer,
+	size_t			count,
+	loff_t			*ppos)
+{
+	int			result = 0;
+	char			alarm_string[30] = {'\0'};
+	char			*p = alarm_string;
+	u32			sec, min, hr, day, mo, yr;
+	int			adjust = 0;
+	unsigned char		rtc_control = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_system_write_alarm");
+
+	if (count > sizeof(alarm_string) - 1)
+		return_VALUE(-EINVAL);
+	
+	if (copy_from_user(alarm_string, buffer, count))
+		return_VALUE(-EFAULT);
+
+	alarm_string[count] = '\0';
+
+	/* check for time adjustment */
+	if (alarm_string[0] == '+') {
+		p++;
+		adjust = 1;
+	}
+
+	if ((result = get_date_field(&p, &yr)))
+		goto end;
+	if ((result = get_date_field(&p, &mo)))
+		goto end;
+	if ((result = get_date_field(&p, &day)))
+		goto end;
+	if ((result = get_date_field(&p, &hr)))
+		goto end;
+	if ((result = get_date_field(&p, &min)))
+		goto end;
+	if ((result = get_date_field(&p, &sec)))
+		goto end;
+
+	if (sec > 59) {
+		min += 1;
+		sec -= 60;
+	}
+	if (min > 59) {
+		hr += 1;
+		min -= 60;
+	}
+	if (hr > 23) {
+		day += 1;
+		hr -= 24;
+	}
+	if (day > 31) {
+		mo += 1;
+		day -= 31;
+	}
+	if (mo > 12) {
+		yr += 1;
+		mo -= 12;
+	}
+
+	spin_lock_irq(&rtc_lock);
+
+	rtc_control = CMOS_READ(RTC_CONTROL);
+	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		BIN_TO_BCD(yr);
+		BIN_TO_BCD(mo);
+		BIN_TO_BCD(day);
+		BIN_TO_BCD(hr);
+		BIN_TO_BCD(min);
+		BIN_TO_BCD(sec);
+	}
+
+	if (adjust) {
+		yr  += CMOS_READ(RTC_YEAR);
+		mo  += CMOS_READ(RTC_MONTH);
+		day += CMOS_READ(RTC_DAY_OF_MONTH);
+		hr  += CMOS_READ(RTC_HOURS);
+		min += CMOS_READ(RTC_MINUTES);
+		sec += CMOS_READ(RTC_SECONDS);
+	}
+
+	spin_unlock_irq(&rtc_lock);
+
+	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		BCD_TO_BIN(yr);
+		BCD_TO_BIN(mo);
+		BCD_TO_BIN(day);
+		BCD_TO_BIN(hr);
+		BCD_TO_BIN(min);
+		BCD_TO_BIN(sec);
+	}
+
+	if (sec > 59) {
+		min++;
+		sec -= 60;
+	}
+	if (min > 59) {
+		hr++;
+		min -= 60;
+	}
+	if (hr > 23) {
+		day++;
+		hr -= 24;
+	}
+	if (day > 31) {
+		mo++;
+		day -= 31;
+	}
+	if (mo > 12) {
+		yr++;
+		mo -= 12;
+	}
+	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+		BIN_TO_BCD(yr);
+		BIN_TO_BCD(mo);
+		BIN_TO_BCD(day);
+		BIN_TO_BCD(hr);
+		BIN_TO_BCD(min);
+		BIN_TO_BCD(sec);
+	}
+
+	spin_lock_irq(&rtc_lock);
+
+	/* write the fields the rtc knows about */
+	CMOS_WRITE(hr, RTC_HOURS_ALARM);
+	CMOS_WRITE(min, RTC_MINUTES_ALARM);
+	CMOS_WRITE(sec, RTC_SECONDS_ALARM);
+
+	/*
+	 * If the system supports an enhanced alarm it will have non-zero
+	 * offsets into the CMOS RAM here -- which for some reason are pointing
+	 * to the RTC area of memory.
+	 */
+#if 0
+	if (acpi_gbl_FADT->day_alrm)
+		CMOS_WRITE(day, acpi_gbl_FADT->day_alrm);
+	if (acpi_gbl_FADT->mon_alrm)
+		CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm);
+	if (acpi_gbl_FADT->century)
+		CMOS_WRITE(yr/100, acpi_gbl_FADT->century);
+#endif
+	/* enable the rtc alarm interrupt */
+	if (!(rtc_control & RTC_AIE)) {
+		rtc_control |= RTC_AIE;
+		CMOS_WRITE(rtc_control,RTC_CONTROL);
+		CMOS_READ(RTC_INTR_FLAGS);
+	}
+
+	spin_unlock_irq(&rtc_lock);
+
+	acpi_set_register(ACPI_BITREG_RT_CLOCK_ENABLE, 1, ACPI_MTX_LOCK);
+
+	file->f_pos += count;
+
+	result = 0;
+end:
+	return_VALUE(result ? result : count);
+}
+
+
+static struct file_operations acpi_system_sleep_fops = {
+	.open		= acpi_system_sleep_open_fs,
+	.read		= seq_read,
+	.write		= acpi_system_write_sleep,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static struct file_operations acpi_system_alarm_fops = {
+	.open		= acpi_system_alarm_open_fs,
+	.read		= seq_read,
+	.write		= acpi_system_write_alarm,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+
+static int acpi_sleep_proc_init(void)
+{
+	struct proc_dir_entry	*entry = NULL;
+
+	/* 'sleep' [R/W]*/
+	entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP,
+				  S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
+	if (entry)
+		entry->proc_fops = &acpi_system_sleep_fops;
+
+	/* 'alarm' [R/W] */
+	entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM,
+		S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
+	if (entry)
+		entry->proc_fops = &acpi_system_alarm_fops;
+	return 0;
+}
+
+late_initcall(acpi_sleep_proc_init);
diff -Nru a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/acpi/sleep/sleep.h	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,5 @@
+
+extern u8 sleep_states[];
+
+extern acpi_status acpi_suspend (u32 state);
+
diff -Nru a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
--- a/drivers/acpi/sleep.c	Fri Feb 14 15:53:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,707 +0,0 @@
-/*
- * sleep.c - ACPI sleep support.
- * 
- *  Copyright (c) 2000-2002 Patrick Mochel
- *
- *  Portions are
- *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
- *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- */
-
-#include <linux/proc_fs.h>
-#include <linux/sysrq.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/pm.h>
-#include <linux/device.h>
-#include <linux/suspend.h>
-#include <linux/seq_file.h>
-#include <linux/bcd.h>
-
-#include <asm/uaccess.h>
-#include <asm/acpi.h>
-
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
-
-#ifdef CONFIG_X86
-#include <linux/mc146818rtc.h>
-#endif
-
-#define _COMPONENT		ACPI_SYSTEM_COMPONENT
-ACPI_MODULE_NAME		("sleep")
-
-#define ACPI_SYSTEM_FILE_SLEEP		"sleep"
-#define ACPI_SYSTEM_FILE_ALARM		"alarm"
-
-static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file);
-static int acpi_system_alarm_open_fs(struct inode *inode, struct file *file);
-
-static u8 sleep_states[ACPI_S_STATE_COUNT];
-
-static struct file_operations acpi_system_sleep_fops = {
-	.open		= acpi_system_sleep_open_fs,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static struct file_operations acpi_system_alarm_fops = {
-	.open		= acpi_system_alarm_open_fs,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static void
-acpi_power_off (void)
-{
-	acpi_enter_sleep_state_prep(ACPI_STATE_S5);
-	ACPI_DISABLE_IRQS();
-	acpi_enter_sleep_state(ACPI_STATE_S5);
-}
-
-/**
- * acpi_system_restore_state - OS-specific restoration of state
- * @state:	sleep state we're exiting
- *
- * Note that if we're coming back from S4, the memory image should have already
- * been loaded from the disk and is already in place. (Otherwise how else would we
- * be here?).
- */
-acpi_status
-acpi_system_restore_state (
-	u32			state)
-{
-	/* restore processor state
-	 * We should only be here if we're coming back from STR or STD.
-	 * And, in the case of the latter, the memory image should have already
-	 * been loaded from disk.
-	 */
-	if (state > ACPI_STATE_S1)
-		acpi_restore_state_mem();
-
-	/* wait for power to come back */
-	mdelay(10);
-
-	/* turn all the devices back on */
-	device_resume(RESUME_POWER_ON);
-
-	/* enable interrupts once again */
-	ACPI_ENABLE_IRQS();
-
-	/* restore device context */
-	device_resume(RESUME_RESTORE_STATE);
-
-	if (dmi_broken & BROKEN_INIT_AFTER_S1) {
-		printk("Broken toshiba laptop -> kicking interrupts\n");
-		init_8259A(0);
-	}
-
-	return AE_OK;
-}
-
-/**
- * acpi_system_save_state - save OS specific state and power down devices
- * @state:	sleep state we're entering.
- *
- * This handles saving all context to memory, and possibly disk.
- * First, we call to the device driver layer to save device state.
- * Once we have that, we save whatevery processor and kernel state we
- * need to memory.
- * If we're entering S4, we then write the memory image to disk.
- *
- * Only then is it safe for us to power down devices, since we may need
- * the disks and upstream buses to write to.
- */
-acpi_status
-acpi_system_save_state(
-	u32			state)
-{
-	int			error = 0;
-
-	/* Send notification to devices that they will be suspended.
-	 * If any device or driver cannot make the transition, either up
-	 * or down, we'll get an error back.
-	 */
-	error = device_suspend(state, SUSPEND_NOTIFY);
-	if (error)
-		return AE_ERROR;
-
-	if (state < ACPI_STATE_S5) {
-
-		/* Tell devices to stop I/O and actually save their state.
-		 * It is theoretically possible that something could fail,
-		 * so handle that gracefully..
-		 */
-		error = device_suspend(state, SUSPEND_SAVE_STATE);
-		if (error) {
-			/* tell devices to restore state if they have
-			 * it saved and to start taking I/O requests.
-			 */
-			device_resume(RESUME_RESTORE_STATE);
-			return error;
-		}
-
-		/* flush caches */
-		ACPI_FLUSH_CPU_CACHE();
-
-		/* Do arch specific saving of state. */
-		if (state > ACPI_STATE_S1) {
-			error = acpi_save_state_mem();
-
-			if (!error && (state == ACPI_STATE_S4))
-				error = acpi_save_state_disk();
-
-			if (error) {
-				device_resume(RESUME_RESTORE_STATE);
-				return error;
-			}
-		}
-	}
-
-	/* disable interrupts
-	 * Note that acpi_suspend -- our caller -- will do this once we return.
-	 * But, we want it done early, so we don't get any suprises during
-	 * the device suspend sequence.
-	 */
-	ACPI_DISABLE_IRQS();
-
-	/* Unconditionally turn off devices.
-	 * Obvious if we enter a sleep state.
-	 * If entering S5 (soft off), this should put devices in a
-	 * quiescent state.
-	 */
-	error = device_suspend(state, SUSPEND_POWER_DOWN);
-
-	/* We're pretty screwed if we got an error from this.
-	 * We try to recover by simply calling our own restore_state
-	 * function; see above for definition.
-	 *
-	 * If it's S5 though, go through with it anyway..
-	 */
-	if (error && state != ACPI_STATE_S5)
-		acpi_system_restore_state(state);
-
-	return error ? AE_ERROR : AE_OK;
-}
-
-
-/****************************************************************************
- *
- * FUNCTION:    acpi_system_suspend
- *
- * PARAMETERS:  %state: Sleep state to enter.
- *
- * RETURN:      acpi_status, whether or not we successfully entered and
- *              exited sleep.
- *
- * DESCRIPTION: Perform OS-specific action to enter sleep state.
- *              This is the final step in going to sleep, per spec.  If we
- *              know we're coming back (i.e. not entering S5), we save the
- *              processor flags. [ We'll have to save and restore them anyway,
- *              so we use the arch-agnostic save_flags and restore_flags
- *              here.]  We then set the place to return to in arch-specific
- *              globals using arch_set_return_point. Finally, we call the
- *              ACPI function to write the proper values to I/O ports.
- *
- ****************************************************************************/
-
-acpi_status
-acpi_system_suspend(
-	u32			state)
-{
-	acpi_status		status = AE_ERROR;
-	unsigned long		flags = 0;
-
-	local_irq_save(flags);
-	
-	switch (state)
-	{
-	case ACPI_STATE_S1:
-		barrier();
-		status = acpi_enter_sleep_state(state);
-		break;
-
-	case ACPI_STATE_S2:
-#ifdef CONFIG_SOFTWARE_SUSPEND
-	case ACPI_STATE_S3:
-		do_suspend_lowlevel(0);
-#endif
-		break;
-	}
-	local_irq_restore(flags);
-
-	return status;
-}
-
-
-/**
- * acpi_suspend - OS-agnostic system suspend/resume support (S? states)
- * @state:	state we're entering
- *
- */
-acpi_status
-acpi_suspend (
-	u32			state)
-{
-	acpi_status status;
-
-	/* get out if state is invalid */
-	if (state < ACPI_STATE_S1 || state > ACPI_STATE_S5)
-		return AE_ERROR;
-
-	freeze_processes();		/* device_suspend needs processes to be stopped */
-
-	/* do we have a wakeup address for S2 and S3? */
-	if (state == ACPI_STATE_S2 || state == ACPI_STATE_S3) {
-		if (!acpi_wakeup_address)
-			return AE_ERROR;
-		acpi_set_firmware_waking_vector((acpi_physical_address) acpi_wakeup_address);
-	}
-
-	acpi_enter_sleep_state_prep(state);
-
-	status = acpi_system_save_state(state);
-	if (!ACPI_SUCCESS(status))
-		return status;
-
-	/* disable interrupts and flush caches */
-	ACPI_DISABLE_IRQS();
-	ACPI_FLUSH_CPU_CACHE();
-
-	/* perform OS-specific sleep actions */
-	status = acpi_system_suspend(state);
-
-	/* Even if we failed to go to sleep, all of the devices are in an suspended
-	 * mode. So, we run these unconditionaly to make sure we have a usable system
-	 * no matter what.
-	 */
-	acpi_system_restore_state(state);
-	acpi_leave_sleep_state(state);
-
-	/* make sure interrupts are enabled */
-	ACPI_ENABLE_IRQS();
-
-	/* reset firmware waking vector */
-	acpi_set_firmware_waking_vector((acpi_physical_address) 0);
-	thaw_processes();
-
-	return status;
-}
-
-static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
-{
-	int			i;
-
-	ACPI_FUNCTION_TRACE("acpi_system_sleep_seq_show");
-
-	for (i = 0; i <= ACPI_STATE_S5; i++) {
-		if (sleep_states[i])
-			seq_printf(seq,"S%d ", i);
-	}
-
-	seq_puts(seq, "\n");
-
-	return 0;
-}
-
-static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data);
-}
-
-static int
-acpi_system_write_sleep (
-	struct file		*file,
-	const char		*buffer,
-	size_t			count,
-	loff_t			*ppos)
-{
-	acpi_status		status = AE_OK;
-	char			state_string[12] = {'\0'};
-	u32			state = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_system_write_sleep");
-
-	if (count > sizeof(state_string) - 1)
-		return_VALUE(-EINVAL);
-
-	if (copy_from_user(state_string, buffer, count))
-		return_VALUE(-EFAULT);
-	
-	state_string[count] = '\0';
-	
-	state = simple_strtoul(state_string, NULL, 0);
-	
-	if (!sleep_states[state])
-		return_VALUE(-ENODEV);
-
-#ifdef CONFIG_SOFTWARE_SUSPEND
-	if (state == 4) {
-		software_suspend();
-		return_VALUE(count);
-	}
-#endif
-	status = acpi_suspend(state);
-
-	if (ACPI_FAILURE(status))
-		return_VALUE(-ENODEV);
-	
-	return_VALUE(count);
-}
-
-static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
-{
-	u32			sec, min, hr;
-	u32			day, mo, yr;
-
-	ACPI_FUNCTION_TRACE("acpi_system_alarm_seq_show");
-
-	spin_lock(&rtc_lock);
-
-	sec = CMOS_READ(RTC_SECONDS_ALARM);
-	min = CMOS_READ(RTC_MINUTES_ALARM);
-	hr = CMOS_READ(RTC_HOURS_ALARM);
-
-#if 0	/* If we ever get an FACP with proper values... */
-	if (acpi_gbl_FADT->day_alrm)
-		day = CMOS_READ(acpi_gbl_FADT->day_alrm);
-	else
-		day =  CMOS_READ(RTC_DAY_OF_MONTH);
-	if (acpi_gbl_FADT->mon_alrm)
-		mo = CMOS_READ(acpi_gbl_FADT->mon_alrm);
-	else
-		mo = CMOS_READ(RTC_MONTH);;
-	if (acpi_gbl_FADT->century)
-		yr = CMOS_READ(acpi_gbl_FADT->century) * 100 + CMOS_READ(RTC_YEAR);
-	else
-		yr = CMOS_READ(RTC_YEAR);
-#else
-	day = CMOS_READ(RTC_DAY_OF_MONTH);
-	mo = CMOS_READ(RTC_MONTH);
-	yr = CMOS_READ(RTC_YEAR);
-#endif
-
-	spin_unlock(&rtc_lock);
-
-	BCD_TO_BIN(sec);
-	BCD_TO_BIN(min);
-	BCD_TO_BIN(hr);
-	BCD_TO_BIN(day);
-	BCD_TO_BIN(mo);
-	BCD_TO_BIN(yr);
-
-#if 0
-	/* we're trusting the FADT (see above)*/
-#else
-	/* If we're not trusting the FADT, we should at least make it
-	 * right for _this_ century... ehm, what is _this_ century?
-	 *
-	 * TBD:
-	 *  ASAP: find piece of code in the kernel, e.g. star tracker driver,
-	 *        which we can trust to determine the century correctly. Atom
-	 *        watch driver would be nice, too...
-	 *
-	 *  if that has not happened, change for first release in 2050:
- 	 *        if (yr<50)
-	 *                yr += 2100;
-	 *        else
-	 *                yr += 2000;   // current line of code
-	 *
-	 *  if that has not happened either, please do on 2099/12/31:23:59:59
-	 *        s/2000/2100
-	 *
-	 */
-	yr += 2000;
-#endif
-
-	seq_printf(seq,"%4.4u-", yr);
-	(mo > 12)  ? seq_puts(seq, "**-")  : seq_printf(seq, "%2.2u-", mo);
-	(day > 31) ? seq_puts(seq, "** ")  : seq_printf(seq, "%2.2u ", day);
-	(hr > 23)  ? seq_puts(seq, "**:")  : seq_printf(seq, "%2.2u:", hr);
-	(min > 59) ? seq_puts(seq, "**:")  : seq_printf(seq, "%2.2u:", min);
-	(sec > 59) ? seq_puts(seq, "**\n") : seq_printf(seq, "%2.2u\n", sec);
-
-	return 0;
-}
-
-static int acpi_system_alarm_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_system_alarm_seq_show, PDE(inode)->data);
-}
-
-
-static int
-get_date_field (
-	char			**p,
-	u32			*value)
-{
-	char			*next = NULL;
-	char			*string_end = NULL;
-	int			result = -EINVAL;
-
-	/*
-	 * Try to find delimeter, only to insert null.  The end of the
-	 * string won't have one, but is still valid.
-	 */
-	next = strpbrk(*p, "- :");
-	if (next)
-		*next++ = '\0';
-
-	*value = simple_strtoul(*p, &string_end, 10);
-
-	/* Signal success if we got a good digit */
-	if (string_end != *p)
-		result = 0;
-
-	if (next)
-		*p = next;
-
-	return result;
-}
-
-
-static int
-acpi_system_write_alarm (
-	struct file		*file,
-	const char		*buffer,
-	size_t			count,
-	loff_t			*ppos)
-{
-	int			result = 0;
-	char			alarm_string[30] = {'\0'};
-	char			*p = alarm_string;
-	u32			sec, min, hr, day, mo, yr;
-	int			adjust = 0;
-	unsigned char		rtc_control = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_system_write_alarm");
-
-	if (count > sizeof(alarm_string) - 1)
-		return_VALUE(-EINVAL);
-	
-	if (copy_from_user(alarm_string, buffer, count))
-		return_VALUE(-EFAULT);
-
-	alarm_string[count] = '\0';
-
-	/* check for time adjustment */
-	if (alarm_string[0] == '+') {
-		p++;
-		adjust = 1;
-	}
-
-	if ((result = get_date_field(&p, &yr)))
-		goto end;
-	if ((result = get_date_field(&p, &mo)))
-		goto end;
-	if ((result = get_date_field(&p, &day)))
-		goto end;
-	if ((result = get_date_field(&p, &hr)))
-		goto end;
-	if ((result = get_date_field(&p, &min)))
-		goto end;
-	if ((result = get_date_field(&p, &sec)))
-		goto end;
-
-	if (sec > 59) {
-		min += 1;
-		sec -= 60;
-	}
-	if (min > 59) {
-		hr += 1;
-		min -= 60;
-	}
-	if (hr > 23) {
-		day += 1;
-		hr -= 24;
-	}
-	if (day > 31) {
-		mo += 1;
-		day -= 31;
-	}
-	if (mo > 12) {
-		yr += 1;
-		mo -= 12;
-	}
-
-	spin_lock_irq(&rtc_lock);
-
-	rtc_control = CMOS_READ(RTC_CONTROL);
-	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-		BIN_TO_BCD(yr);
-		BIN_TO_BCD(mo);
-		BIN_TO_BCD(day);
-		BIN_TO_BCD(hr);
-		BIN_TO_BCD(min);
-		BIN_TO_BCD(sec);
-	}
-
-	if (adjust) {
-		yr  += CMOS_READ(RTC_YEAR);
-		mo  += CMOS_READ(RTC_MONTH);
-		day += CMOS_READ(RTC_DAY_OF_MONTH);
-		hr  += CMOS_READ(RTC_HOURS);
-		min += CMOS_READ(RTC_MINUTES);
-		sec += CMOS_READ(RTC_SECONDS);
-	}
-
-	spin_unlock_irq(&rtc_lock);
-
-	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-		BCD_TO_BIN(yr);
-		BCD_TO_BIN(mo);
-		BCD_TO_BIN(day);
-		BCD_TO_BIN(hr);
-		BCD_TO_BIN(min);
-		BCD_TO_BIN(sec);
-	}
-
-	if (sec > 59) {
-		min++;
-		sec -= 60;
-	}
-	if (min > 59) {
-		hr++;
-		min -= 60;
-	}
-	if (hr > 23) {
-		day++;
-		hr -= 24;
-	}
-	if (day > 31) {
-		mo++;
-		day -= 31;
-	}
-	if (mo > 12) {
-		yr++;
-		mo -= 12;
-	}
-	if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-		BIN_TO_BCD(yr);
-		BIN_TO_BCD(mo);
-		BIN_TO_BCD(day);
-		BIN_TO_BCD(hr);
-		BIN_TO_BCD(min);
-		BIN_TO_BCD(sec);
-	}
-
-	spin_lock_irq(&rtc_lock);
-
-	/* write the fields the rtc knows about */
-	CMOS_WRITE(hr, RTC_HOURS_ALARM);
-	CMOS_WRITE(min, RTC_MINUTES_ALARM);
-	CMOS_WRITE(sec, RTC_SECONDS_ALARM);
-
-	/*
-	 * If the system supports an enhanced alarm it will have non-zero
-	 * offsets into the CMOS RAM here -- which for some reason are pointing
-	 * to the RTC area of memory.
-	 */
-#if 0
-	if (acpi_gbl_FADT->day_alrm)
-		CMOS_WRITE(day, acpi_gbl_FADT->day_alrm);
-	if (acpi_gbl_FADT->mon_alrm)
-		CMOS_WRITE(mo, acpi_gbl_FADT->mon_alrm);
-	if (acpi_gbl_FADT->century)
-		CMOS_WRITE(yr/100, acpi_gbl_FADT->century);
-#endif
-	/* enable the rtc alarm interrupt */
-	if (!(rtc_control & RTC_AIE)) {
-		rtc_control |= RTC_AIE;
-		CMOS_WRITE(rtc_control,RTC_CONTROL);
-		CMOS_READ(RTC_INTR_FLAGS);
-	}
-
-	spin_unlock_irq(&rtc_lock);
-
-	acpi_set_register(ACPI_BITREG_RT_CLOCK_ENABLE, 1, ACPI_MTX_LOCK);
-
-	file->f_pos += count;
-
-	result = 0;
-end:
-	return_VALUE(result ? result : count);
-}
-
-
-#if defined(CONFIG_MAGIC_SYSRQ) && defined(CONFIG_PM)
-
-/* Simple wrapper calling power down function. */
-static void acpi_sysrq_power_off(int key, struct pt_regs *pt_regs,
-	struct tty_struct *tty)
-{
-	acpi_power_off();
-}
-
-struct sysrq_key_op sysrq_acpi_poweroff_op = {
-	.handler =	&acpi_sysrq_power_off,
-	.help_msg =	"Off",
-	.action_msg =	"Power Off\n"
-};
-
-#endif  /* CONFIG_MAGIC_SYSRQ */
-
-static int __init acpi_sleep_init(void)
-{
-	struct proc_dir_entry	*entry = NULL;
-	acpi_status		status = AE_OK;
-	int			i = 0;
-
-	ACPI_FUNCTION_TRACE("acpi_system_add_fs");
-
-	if (acpi_disabled)
-		return_VALUE(0);
-
-	printk(KERN_INFO PREFIX "(supports");
-	for (i=0; i<ACPI_S_STATE_COUNT; i++) {
-		u8 type_a, type_b;
-		status = acpi_get_sleep_type_data(i, &type_a, &type_b);
-		if (ACPI_SUCCESS(status)) {
-			sleep_states[i] = 1;
-			printk(" S%d", i);
-		}
-	}
-	printk(")\n");
-
-
-	/* 'sleep' [R/W]*/
-	entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP,
-		S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
-	if (!entry)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Unable to create '%s' fs entry\n",
-			ACPI_SYSTEM_FILE_SLEEP));
-	else {
-		entry->proc_fops = &acpi_system_sleep_fops;
-		entry->proc_fops->write = acpi_system_write_sleep;
-	}
-
-	/* 'alarm' [R/W] */
-	entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM,
-		S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
-	if (!entry)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Unable to create '%s' fs entry\n",
-			ACPI_SYSTEM_FILE_ALARM));
-	else {
-		entry->proc_fops = &acpi_system_alarm_fops;
-		entry->proc_fops->write = acpi_system_write_alarm;
-	}
-
-	/* Install the soft-off (S5) handler. */
-	if (sleep_states[ACPI_STATE_S5]) {
-		pm_power_off = acpi_power_off;
-		register_sysrq_key('o', &sysrq_acpi_poweroff_op);
-
-		/* workaround: some systems don't claim S4 support, but they
-                   do support S5 (power-down). That is all we need, so
-		   indicate support. */
-		sleep_states[ACPI_STATE_S4] = 1;
-	}
-
-	return_VALUE(0);
-}
-
-subsys_initcall(acpi_sleep_init);
diff -Nru a/drivers/acpi/system.c b/drivers/acpi/system.c
--- a/drivers/acpi/system.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/system.c	Fri Feb 14 15:53:11 2003
@@ -27,7 +27,7 @@
 #include <linux/init.h>
 #include <asm/uaccess.h>
 
-#include "acpi_drivers.h"
+#include <acpi/acpi_drivers.h>
 
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
diff -Nru a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
--- a/drivers/acpi/tables/tbconvrt.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/tables/tbconvrt.c	Fri Feb 14 15:53:09 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "actables.h"
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
 
 
 #define _COMPONENT          ACPI_TABLES
diff -Nru a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
--- a/drivers/acpi/tables/tbget.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/tables/tbget.c	Fri Feb 14 15:53:11 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "actables.h"
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
 
 
 #define _COMPONENT          ACPI_TABLES
diff -Nru a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c
--- a/drivers/acpi/tables/tbgetall.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/tables/tbgetall.c	Fri Feb 14 15:53:12 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "actables.h"
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
 
 
 #define _COMPONENT          ACPI_TABLES
diff -Nru a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
--- a/drivers/acpi/tables/tbinstal.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/tables/tbinstal.c	Fri Feb 14 15:53:09 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "actables.h"
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
 
 
 #define _COMPONENT          ACPI_TABLES
diff -Nru a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
--- a/drivers/acpi/tables/tbrsdt.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/tables/tbrsdt.c	Fri Feb 14 15:53:11 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "actables.h"
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
 
 
 #define _COMPONENT          ACPI_TABLES
diff -Nru a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
--- a/drivers/acpi/tables/tbutils.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/tables/tbutils.c	Fri Feb 14 15:53:12 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "actables.h"
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
 
 
 #define _COMPONENT          ACPI_TABLES
diff -Nru a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
--- a/drivers/acpi/tables/tbxface.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/tables/tbxface.c	Fri Feb 14 15:53:12 2003
@@ -24,9 +24,9 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
-#include "actables.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/actables.h>
 
 
 #define _COMPONENT          ACPI_TABLES
diff -Nru a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
--- a/drivers/acpi/tables/tbxfroot.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/tables/tbxfroot.c	Fri Feb 14 15:53:12 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "actables.h"
+#include <acpi/acpi.h>
+#include <acpi/actables.h>
 
 
 #define _COMPONENT          ACPI_TABLES
diff -Nru a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
--- a/drivers/acpi/thermal.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/thermal.c	Fri Feb 14 15:53:12 2003
@@ -39,8 +39,8 @@
 #include <linux/sched.h>
 #include <linux/kmod.h>
 #include <linux/seq_file.h>
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
 
 #define ACPI_THERMAL_COMPONENT		0x04000000
 #define ACPI_THERMAL_CLASS		"thermal_zone"
@@ -82,8 +82,11 @@
 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
+static int acpi_thermal_write_trip_points (struct file*,const char *,size_t,loff_t *);
 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
+static int acpi_thermal_write_cooling_mode (struct file*,const char *,size_t,loff_t *);
 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
+static int acpi_thermal_write_polling(struct file*,const char *,size_t,loff_t *);
 
 static struct acpi_driver acpi_thermal_driver = {
 	.name =		ACPI_THERMAL_DRIVER_NAME,
@@ -179,6 +182,7 @@
 static struct file_operations acpi_thermal_trip_fops = {
 	.open		= acpi_thermal_trip_open_fs,
 	.read		= seq_read,
+	.write		= acpi_thermal_write_trip_points,
 	.llseek		= seq_lseek,
 	.release	= single_release,
 };
@@ -186,6 +190,7 @@
 static struct file_operations acpi_thermal_cooling_fops = {
 	.open		= acpi_thermal_cooling_open_fs,
 	.read		= seq_read,
+	.write		= acpi_thermal_write_cooling_mode,
 	.llseek		= seq_lseek,
 	.release	= single_release,
 };
@@ -193,6 +198,7 @@
 static struct file_operations acpi_thermal_polling_fops = {
 	.open		= acpi_thermal_polling_open_fs,
 	.read		= seq_read,
+	.write		= acpi_thermal_write_polling,
 	.llseek		= seq_lseek,
 	.release	= single_release,
 };
@@ -947,10 +953,11 @@
 	struct file		*file,
 	const char		*buffer,
 	size_t			count,
-	loff_t			*data)
+	loff_t			*ppos)
 {
+	struct seq_file		*m = (struct seq_file *)file->private_data;
+	struct acpi_thermal	*tz = (struct acpi_thermal *)m->private;
 	int			result = 0;
-	struct acpi_thermal	*tz = (struct acpi_thermal *) data;
 	char			mode_string[12] = {'\0'};
 
 	ACPI_FUNCTION_TRACE("acpi_thermal_write_cooling_mode");
@@ -1007,10 +1014,11 @@
 	struct file		*file,
 	const char		*buffer,
 	size_t			count,
-	loff_t			*data)
+	loff_t			*ppos)
 {
+	struct seq_file		*m = (struct seq_file *)file->private_data;
+	struct acpi_thermal	*tz = (struct acpi_thermal *)m->private;
 	int			result = 0;
-	struct acpi_thermal	*tz = (struct acpi_thermal *) data;
 	char			polling_string[12] = {'\0'};
 	int			seconds = 0;
 
@@ -1084,7 +1092,6 @@
 			ACPI_THERMAL_FILE_TRIP_POINTS));
 	else {
 		entry->proc_fops = &acpi_thermal_trip_fops;
-		entry->proc_fops->write = acpi_thermal_write_trip_points;
 		entry->data = acpi_driver_data(device);
 	}
 
@@ -1097,7 +1104,6 @@
 			ACPI_THERMAL_FILE_COOLING_MODE));
 	else {
 		entry->proc_fops = &acpi_thermal_cooling_fops;
-		entry->proc_fops->write = acpi_thermal_write_cooling_mode;
 		entry->data = acpi_driver_data(device);
 	}
 
@@ -1110,7 +1116,6 @@
 			ACPI_THERMAL_FILE_POLLING_FREQ));
 	else {
 		entry->proc_fops = &acpi_thermal_polling_fops;
-		entry->proc_fops->write = acpi_thermal_write_polling;
 		entry->data = acpi_driver_data(device);
 	}
 
diff -Nru a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
--- a/drivers/acpi/toshiba_acpi.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/toshiba_acpi.c	Fri Feb 14 15:53:08 2003
@@ -44,7 +44,7 @@
 #include <linux/seq_file.h>
 #include <linux/version.h>
 
-#include <acconfig.h>
+#include <acpi/acconfig.h>
 #define OLD_ACPI_INTERFACE (ACPI_CA_VERSION < 0x20020000)
 
 #if OLD_ACPI_INTERFACE
@@ -52,7 +52,7 @@
 extern struct proc_dir_entry* bm_proc_root;
 #define acpi_root_dir bm_proc_root
 #else
-#include "acpi_drivers.h"
+#include <acpi/acpi_drivers.h>
 #endif
 
 MODULE_AUTHOR("John Belmonte");
diff -Nru a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
--- a/drivers/acpi/utilities/utalloc.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/utilities/utalloc.c	Fri Feb 14 15:53:09 2003
@@ -23,7 +23,7 @@
  */
 
 
-#include "acpi.h"
+#include <acpi/acpi.h>
 
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("utalloc")
diff -Nru a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
--- a/drivers/acpi/utilities/utcopy.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/utilities/utcopy.c	Fri Feb 14 15:53:09 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "amlcode.h"
+#include <acpi/acpi.h>
+#include <acpi/amlcode.h>
 
 
 #define _COMPONENT          ACPI_UTILITIES
diff -Nru a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
--- a/drivers/acpi/utilities/utdebug.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/utilities/utdebug.c	Fri Feb 14 15:53:11 2003
@@ -23,7 +23,7 @@
  */
 
 
-#include "acpi.h"
+#include <acpi/acpi.h>
 
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("utdebug")
diff -Nru a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
--- a/drivers/acpi/utilities/utdelete.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/utilities/utdelete.c	Fri Feb 14 15:53:09 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acinterp.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acinterp.h>
+#include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("utdelete")
diff -Nru a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
--- a/drivers/acpi/utilities/uteval.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/utilities/uteval.c	Fri Feb 14 15:53:08 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acinterp.h>
 
 
 #define _COMPONENT          ACPI_UTILITIES
diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
--- a/drivers/acpi/utilities/utglobal.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/utilities/utglobal.c	Fri Feb 14 15:53:08 2003
@@ -24,8 +24,8 @@
 
 #define DEFINE_ACPI_GLOBALS
 
-#include "acpi.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("utglobal")
diff -Nru a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c
--- a/drivers/acpi/utilities/utinit.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/utilities/utinit.c	Fri Feb 14 15:53:11 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
-#include "acevents.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acevents.h>
 
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("utinit")
diff -Nru a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c
--- a/drivers/acpi/utilities/utmath.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/utilities/utmath.c	Fri Feb 14 15:53:12 2003
@@ -23,7 +23,7 @@
  */
 
 
-#include "acpi.h"
+#include <acpi/acpi.h>
 
 
 #define _COMPONENT          ACPI_UTILITIES
diff -Nru a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
--- a/drivers/acpi/utilities/utmisc.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/acpi/utilities/utmisc.c	Fri Feb 14 15:53:08 2003
@@ -23,8 +23,8 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
 
 
 #define _COMPONENT          ACPI_UTILITIES
diff -Nru a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
--- a/drivers/acpi/utilities/utobject.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/acpi/utilities/utobject.c	Fri Feb 14 15:53:11 2003
@@ -23,9 +23,9 @@
  */
 
 
-#include "acpi.h"
-#include "acnamesp.h"
-#include "amlcode.h"
+#include <acpi/acpi.h>
+#include <acpi/acnamesp.h>
+#include <acpi/amlcode.h>
 
 
 #define _COMPONENT          ACPI_UTILITIES
diff -Nru a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
--- a/drivers/acpi/utilities/utxface.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/acpi/utilities/utxface.c	Fri Feb 14 15:53:09 2003
@@ -23,12 +23,12 @@
  */
 
 
-#include "acpi.h"
-#include "acevents.h"
-#include "acnamesp.h"
-#include "acparser.h"
-#include "acdispat.h"
-#include "acdebug.h"
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
+#include <acpi/acdispat.h>
+#include <acpi/acdebug.h>
 
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("utxface")
diff -Nru a/drivers/acpi/utils.c b/drivers/acpi/utils.c
--- a/drivers/acpi/utils.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/acpi/utils.c	Fri Feb 14 15:53:12 2003
@@ -27,8 +27,8 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include "acpi_bus.h"
-#include "acpi_drivers.h"
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
 
 
 #define _COMPONENT		ACPI_BUS_COMPONENT
diff -Nru a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
--- a/drivers/atm/nicstar.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/atm/nicstar.c	Fri Feb 14 15:53:09 2003
@@ -1538,7 +1538,7 @@
          
 	 fill_tst(card, n, vc);
       }
-      else /* not CBR */
+      else if (vcc->qos.txtp.traffic_class == ATM_UBR)
       {
          vc->cbr_scd = 0x00000000;
 	 vc->scq = card->scq0;
diff -Nru a/drivers/block/DAC960.c b/drivers/block/DAC960.c
--- a/drivers/block/DAC960.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/block/DAC960.c	Fri Feb 14 15:53:12 2003
@@ -1731,12 +1731,17 @@
       if (!DAC960_V2_NewLogicalDeviceInfo(Controller, LogicalDeviceNumber))
 	break;
       LogicalDeviceNumber = NewLogicalDeviceInfo->LogicalDeviceNumber;
-      if (LogicalDeviceNumber > DAC960_MaxLogicalDrives)
-	panic("DAC960: Logical Drive Number %d not supported\n",
-		       LogicalDeviceNumber);
-      if (NewLogicalDeviceInfo->DeviceBlockSizeInBytes != DAC960_BlockSize)
-	panic("DAC960: Logical Drive Block Size %d not supported\n",
-	      NewLogicalDeviceInfo->DeviceBlockSizeInBytes);
+      if (LogicalDeviceNumber >= DAC960_MaxLogicalDrives) {
+	DAC960_Error("DAC960: Logical Drive Number %d not supported\n",
+		       Controller, LogicalDeviceNumber);
+		break;
+      }
+      if (NewLogicalDeviceInfo->DeviceBlockSizeInBytes != DAC960_BlockSize) {
+	DAC960_Error("DAC960: Logical Drive Block Size %d not supported\n",
+	      Controller, NewLogicalDeviceInfo->DeviceBlockSizeInBytes);
+        LogicalDeviceNumber++;
+        continue;
+      }
       PhysicalDevice.Controller = 0;
       PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
       PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
diff -Nru a/drivers/block/cciss.c b/drivers/block/cciss.c
--- a/drivers/block/cciss.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/block/cciss.c	Fri Feb 14 15:53:12 2003
@@ -345,7 +345,7 @@
 	printk(KERN_DEBUG "cciss_open %x (%x:%x)\n", inode->i_rdev, ctlr, dsk);
 #endif /* CCISS_DEBUG */ 
 
-	if (ctlr > MAX_CTLR || hba[ctlr] == NULL)
+	if (ctlr >= MAX_CTLR || hba[ctlr] == NULL)
 		return -ENXIO;
 	/*
 	 * Root is allowed to open raw volume zero even if its not configured
diff -Nru a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
--- a/drivers/block/cciss_scsi.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/block/cciss_scsi.c	Fri Feb 14 15:53:09 2003
@@ -1379,10 +1379,10 @@
 
 	// Get the ptr to our adapter structure (hba[i]) out of cmd->host.
 	// We violate cmd->host privacy here.  (Is there another way?)
-	c = (ctlr_info_t **) &cmd->host->hostdata[0];	
+	c = (ctlr_info_t **) &cmd->device->host->hostdata[0];
 	ctlr = (*c)->ctlr;
 
-	rc = lookup_scsi3addr(ctlr, cmd->channel, cmd->target, cmd->lun, 
+	rc = lookup_scsi3addr(ctlr, cmd->device->channel, cmd->device->id, cmd->device->lun, 
 			scsi3addr);
 	if (rc != 0) {
 		/* the scsi nexus does not match any that we presented... */
diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c
--- a/drivers/block/genhd.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/block/genhd.c	Fri Feb 14 15:53:09 2003
@@ -74,7 +74,7 @@
 	down_write(&block_subsys.rwsem);
 	for (s = &probes[index]; *s; s = &(*s)->next) {
 		struct blk_probe *p = *s;
-		if (p->dev == dev || p->range == range) {
+		if (p->dev == dev && p->range == range) {
 			*s = p->next;
 			kfree(p);
 			break;
@@ -299,7 +299,7 @@
 static ssize_t disk_dev_read(struct gendisk * disk, char *page)
 {
 	dev_t base = MKDEV(disk->major, disk->first_minor); 
-	return sprintf(page, "%04x\n",base);
+	return sprintf(page, "%04x\n", (unsigned)base);
 }
 static ssize_t disk_range_read(struct gendisk * disk, char *page)
 {
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/block/ll_rw_blk.c	Fri Feb 14 15:53:08 2003
@@ -28,6 +28,7 @@
 #include <linux/slab.h>
 
 static void blk_unplug_work(void *data);
+static void blk_unplug_timeout(unsigned long data);
 
 /*
  * For the allocated request tables
@@ -247,6 +248,9 @@
 	init_timer(&q->unplug_timer);
 	INIT_WORK(&q->unplug_work, blk_unplug_work, q);
 
+	q->unplug_timer.function = blk_unplug_timeout;
+	q->unplug_timer.data = (unsigned long)q;
+
 	/*
 	 * by default assume old behaviour and bounce for any highmem page
 	 */
@@ -677,7 +681,7 @@
 	"REQ_SENSE",
 	"REQ_FAILED",
 	"REQ_QUIET",
-	"REQ_SPECIAL"
+	"REQ_SPECIAL",
 	"REQ_DRIVE_CMD",
 	"REQ_DRIVE_TASK",
 	"REQ_DRIVE_TASKFILE",
@@ -1297,9 +1301,6 @@
 
 	blk_queue_make_request(q, __make_request);
 	blk_queue_max_segment_size(q, MAX_SEGMENT_SIZE);
-
-	q->unplug_timer.function = blk_unplug_timeout;
-	q->unplug_timer.data = (unsigned long)q;
 
 	blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS);
 	blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS);
diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c
--- a/drivers/block/loop.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/block/loop.c	Fri Feb 14 15:53:10 2003
@@ -577,17 +577,11 @@
 	struct loop_device *lo = data;
 	struct bio *bio;
 
-	daemonize();
+	daemonize("loop%d", lo->lo_number);
 
-	sprintf(current->comm, "loop%d", lo->lo_number);
 	current->flags |= PF_IOTHREAD;	/* loop can be used in an encrypted device
 					   hence, it mustn't be stopped at all because it could
 					   be indirectly used during suspension */
-
-	spin_lock_irq(&current->sighand->siglock);
-	sigfillset(&current->blocked);
-	flush_signals(current);
-	spin_unlock_irq(&current->sighand->siglock);
 
 	set_user_nice(current, -20);
 
diff -Nru a/drivers/block/nbd.c b/drivers/block/nbd.c
--- a/drivers/block/nbd.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/block/nbd.c	Fri Feb 14 15:53:09 2003
@@ -149,7 +149,7 @@
 			spin_lock_irqsave(&current->sighand->siglock, flags);
 			printk(KERN_WARNING "NBD (pid %d: %s) got signal %d\n",
 				current->pid, current->comm, 
-				dequeue_signal(&current->blocked, &info));
+				dequeue_signal(current, &current->blocked, &info));
 			spin_unlock_irqrestore(&current->sighand->siglock, flags);
 			result = -EINTR;
 			break;
diff -Nru a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
--- a/drivers/char/agp/Kconfig	Fri Feb 14 15:53:10 2003
+++ b/drivers/char/agp/Kconfig	Fri Feb 14 15:53:10 2003
@@ -61,16 +61,6 @@
 	  You should say Y here if you use XFree86 3.3.6 or 4.x and want to
 	  use GLX or DRI.  If unsure, say N.
 
-config AGP_VIA_KT400
-	tristate "VIA KT400 chipset support"
-	depends on AGP3
-	help
-	  This option gives you AGP support for the GLX component of the
-	  XFree86 4.x on VIA KT400 AGP 3.0 chipsets.
-
-	  You should say Y here if you use XFree86 3.3.6 or 4.x and want to
-	  use GLX or DRI.  If unsure, say N.
-
 config AGP_AMD
 	tristate "AMD Irongate, 761, and 762 support"
 	depends on AGP
@@ -140,6 +130,11 @@
 	help
 	  This option gives you AGP GART support for the HP ZX1 chipset
 	  for IA64 processors.
+
+config AGP_ALPHA_CORE
+	tristate
+	depends on AGP && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL)
+	default AGP
 
 # Put AGP 3.0 entries below here.
 
diff -Nru a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile
--- a/drivers/char/agp/Makefile	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/agp/Makefile	Fri Feb 14 15:53:09 2003
@@ -10,7 +10,6 @@
 
 obj-$(CONFIG_AGP_INTEL)		+= intel-agp.o
 obj-$(CONFIG_AGP_VIA)		+= via-agp.o
-obj-$(CONFIG_AGP_VIA_KT400)	+= via-kt400.o
 obj-$(CONFIG_AGP_AMD)		+= amd-k7-agp.o
 obj-$(CONFIG_AGP_SIS)		+= sis-agp.o
 obj-$(CONFIG_AGP_ALI)		+= ali-agp.o
@@ -18,6 +17,7 @@
 obj-$(CONFIG_AGP_I460)		+= i460-agp.o
 obj-$(CONFIG_AGP_HP_ZX1)	+= hp-agp.o
 obj-$(CONFIG_AGP_AMD_8151)	+= amd-k8-agp.o
+obj-$(CONFIG_AGP_ALPHA_CORE)	+= alpha-agp.o
 
 obj-$(CONFIG_AGP_I7x05)		+= i7x05-agp.o
 
diff -Nru a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
--- a/drivers/char/agp/agp.h	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/agp/agp.h	Fri Feb 14 15:53:09 2003
@@ -30,7 +30,7 @@
 
 #include <asm/agp.h>	/* for flush_agp_cache() */
 
-extern struct agp_bridge_data agp_bridge;
+extern struct agp_bridge_data *agp_bridge;
 
 #define PFX "agpgart: "
 
@@ -128,6 +128,7 @@
 	int num_aperture_sizes;
 	int capndx;
 	int cant_use_aperture;
+	struct vm_operations_struct *vm_ops;
 
 	/* Links to driver specific functions */
 
@@ -165,20 +166,20 @@
 #define MB(x)	(KB (KB (x)))
 #define GB(x)	(MB (KB (x)))
 
-#define CACHE_FLUSH	agp_bridge.cache_flush
+#define CACHE_FLUSH	agp_bridge->cache_flush
 #define A_SIZE_8(x)	((struct aper_size_info_8 *) x)
 #define A_SIZE_16(x)	((struct aper_size_info_16 *) x)
 #define A_SIZE_32(x)	((struct aper_size_info_32 *) x)
 #define A_SIZE_LVL2(x)	((struct aper_size_info_lvl2 *) x)
 #define A_SIZE_FIX(x)	((struct aper_size_info_fixed *) x)
-#define A_IDX8()	(A_SIZE_8(agp_bridge.aperture_sizes) + i)
-#define A_IDX16()	(A_SIZE_16(agp_bridge.aperture_sizes) + i)
-#define A_IDX32()	(A_SIZE_32(agp_bridge.aperture_sizes) + i)
-#define A_IDXLVL2()	(A_SIZE_LVL2(agp_bridge.aperture_sizes) + i)
-#define A_IDXFIX()	(A_SIZE_FIX(agp_bridge.aperture_sizes) + i)
+#define A_IDX8()	(A_SIZE_8(agp_bridge->aperture_sizes) + i)
+#define A_IDX16()	(A_SIZE_16(agp_bridge->aperture_sizes) + i)
+#define A_IDX32()	(A_SIZE_32(agp_bridge->aperture_sizes) + i)
+#define A_IDXLVL2()	(A_SIZE_LVL2(agp_bridge->aperture_sizes) + i)
+#define A_IDXFIX()	(A_SIZE_FIX(agp_bridge->aperture_sizes) + i)
 #define MAXKEY		(4096 * 32)
 
-#define PGE_EMPTY(p)	(!(p) || (p) == (unsigned long) agp_bridge.scratch_page)
+#define PGE_EMPTY(p)	(!(p) || (p) == (unsigned long) agp_bridge->scratch_page)
 
 /* intel register */
 #define INTEL_APBASE	0x10
@@ -366,7 +367,7 @@
 
 /* Generic routines. */
 void agp_generic_agp_enable(u32 mode);
-int agp_generic_agp_3_0_enable(u32 mode);
+void agp_generic_agp_3_0_enable(u32 mode);
 int agp_generic_create_gatt_table(void);
 int agp_generic_free_gatt_table(void);
 agp_memory *agp_create_memory(int scratch_pages);
diff -Nru a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
--- a/drivers/char/agp/ali-agp.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/char/agp/ali-agp.c	Fri Feb 14 15:53:11 2003
@@ -17,15 +17,15 @@
 	u32 temp;
 	struct aper_size_info_32 *values;
 
-	pci_read_config_dword(agp_bridge.dev, ALI_ATTBASE, &temp);
+	pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp);
 	temp &= ~(0xfffffff0);
-	values = A_SIZE_32(agp_bridge.aperture_sizes);
+	values = A_SIZE_32(agp_bridge->aperture_sizes);
 
-	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+	for (i = 0; i < agp_bridge->num_aperture_sizes; i++) {
 		if (temp == values[i].size_value) {
-			agp_bridge.previous_size =
-			    agp_bridge.current_size = (void *) (values + i);
-			agp_bridge.aperture_size_idx = i;
+			agp_bridge->previous_size =
+			    agp_bridge->current_size = (void *) (values + i);
+			agp_bridge->aperture_size_idx = i;
 			return values[i].size;
 		}
 	}
@@ -37,9 +37,9 @@
 {
 	u32 temp;
 
-	pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
+	pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp);
 // clear tag
-	pci_write_config_dword(agp_bridge.dev, ALI_TAGCTRL,
+	pci_write_config_dword(agp_bridge->dev, ALI_TAGCTRL,
 			((temp & 0xfffffff0) | 0x00000001|0x00000002));
 }
 
@@ -48,15 +48,15 @@
 	struct aper_size_info_32 *previous_size;
 	u32 temp;
 
-	previous_size = A_SIZE_32(agp_bridge.previous_size);
+	previous_size = A_SIZE_32(agp_bridge->previous_size);
 
-	pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
+	pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp);
 // clear tag
-	pci_write_config_dword(agp_bridge.dev, ALI_TAGCTRL,
+	pci_write_config_dword(agp_bridge->dev, ALI_TAGCTRL,
 			((temp & 0xffffff00) | 0x00000001|0x00000002));
 
-	pci_read_config_dword(agp_bridge.dev,  ALI_ATTBASE, &temp);
-	pci_write_config_dword(agp_bridge.dev, ALI_ATTBASE,
+	pci_read_config_dword(agp_bridge->dev,  ALI_ATTBASE, &temp);
+	pci_write_config_dword(agp_bridge->dev, ALI_ATTBASE,
 			((temp & 0x00000ff0) | previous_size->size_value));
 }
 
@@ -65,24 +65,24 @@
 	u32 temp;
 	struct aper_size_info_32 *current_size;
 
-	current_size = A_SIZE_32(agp_bridge.current_size);
+	current_size = A_SIZE_32(agp_bridge->current_size);
 
 	/* aperture size and gatt addr */
-	pci_read_config_dword(agp_bridge.dev, ALI_ATTBASE, &temp);
-	temp = (((temp & 0x00000ff0) | (agp_bridge.gatt_bus_addr & 0xfffff000))
+	pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp);
+	temp = (((temp & 0x00000ff0) | (agp_bridge->gatt_bus_addr & 0xfffff000))
 			| (current_size->size_value & 0xf));
-	pci_write_config_dword(agp_bridge.dev, ALI_ATTBASE, temp);
+	pci_write_config_dword(agp_bridge->dev, ALI_ATTBASE, temp);
 
 	/* tlb control */
-	pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
-	pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL, ((temp & 0xffffff00) | 0x00000010));
+	pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp);
+	pci_write_config_dword(agp_bridge->dev, ALI_TLBCTRL, ((temp & 0xffffff00) | 0x00000010));
 
 	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, ALI_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_read_config_dword(agp_bridge->dev, ALI_APBASE, &temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 #if 0
-	if (agp_bridge.type == ALI_M1541) {
+	if (agp_bridge->type == ALI_M1541) {
 		u32 nlvm_addr = 0;
 
 		switch (current_size->size_value) {
@@ -101,15 +101,15 @@
 		nlvm_addr--;
 		nlvm_addr&=0xfff00000;
 
-		nlvm_addr+= agp_bridge.gart_bus_addr;
-		nlvm_addr|=(agp_bridge.gart_bus_addr>>12);
+		nlvm_addr+= agp_bridge->gart_bus_addr;
+		nlvm_addr|=(agp_bridge->gart_bus_addr>>12);
 		printk(KERN_INFO PFX "nlvm top &base = %8x\n",nlvm_addr);
 	}
 #endif
 
-	pci_read_config_dword(agp_bridge.dev, ALI_TLBCTRL, &temp);
+	pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp);
 	temp &= 0xffffff7f;		//enable TLB
-	pci_write_config_dword(agp_bridge.dev, ALI_TLBCTRL, temp);
+	pci_write_config_dword(agp_bridge->dev, ALI_TLBCTRL, temp);
 
 	return 0;
 }
@@ -118,23 +118,23 @@
 {
 	/* Memory type is ignored */
 
-	return addr | agp_bridge.masks[0].mask;
+	return addr | agp_bridge->masks[0].mask;
 }
 
 static void ali_cache_flush(void)
 {
 	global_cache_flush();
 
-	if (agp_bridge.type == ALI_M1541) {
+	if (agp_bridge->type == ALI_M1541) {
 		int i, page_count;
 		u32 temp;
 
-		page_count = 1 << A_SIZE_32(agp_bridge.current_size)->page_order;
+		page_count = 1 << A_SIZE_32(agp_bridge->current_size)->page_order;
 		for (i = 0; i < PAGE_SIZE * page_count; i += PAGE_SIZE) {
-			pci_read_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL, &temp);
-			pci_write_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL,
+			pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
+			pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
 					(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
-					  (agp_bridge.gatt_bus_addr + i)) |
+					  (agp_bridge->gatt_bus_addr + i)) |
 					    ALI_CACHE_FLUSH_EN));
 		}
 	}
@@ -148,9 +148,9 @@
 	if (adr == 0)
 		return 0;
 
-	if (agp_bridge.type == ALI_M1541) {
-		pci_read_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL, &temp);
-		pci_write_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL,
+	if (agp_bridge->type == ALI_M1541) {
+		pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
+		pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
 				(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
 				  virt_to_phys(adr)) |
 				    ALI_CACHE_FLUSH_EN ));
@@ -167,9 +167,9 @@
 
 	global_cache_flush();
 
-	if (agp_bridge.type == ALI_M1541) {
-		pci_read_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL, &temp);
-		pci_write_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL,
+	if (agp_bridge->type == ALI_M1541) {
+		pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
+		pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
 				(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
 				  virt_to_phys(addr)) |
 				    ALI_CACHE_FLUSH_EN));
@@ -197,30 +197,30 @@
 
 static int __init ali_generic_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = ali_generic_masks;
-	agp_bridge.aperture_sizes = (void *) ali_generic_sizes;
-	agp_bridge.size_type = U32_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = ali_configure;
-	agp_bridge.fetch_size = ali_fetch_size;
-	agp_bridge.cleanup = ali_cleanup;
-	agp_bridge.tlb_flush = ali_tlbflush;
-	agp_bridge.mask_memory = ali_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = ali_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = ali_alloc_page;
-	agp_bridge.agp_destroy_page = ali_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = ali_generic_masks;
+	agp_bridge->aperture_sizes = (void *) ali_generic_sizes;
+	agp_bridge->size_type = U32_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 7;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = ali_configure;
+	agp_bridge->fetch_size = ali_fetch_size;
+	agp_bridge->cleanup = ali_cleanup;
+	agp_bridge->tlb_flush = ali_tlbflush;
+	agp_bridge->mask_memory = ali_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = ali_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = agp_generic_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = ali_alloc_page;
+	agp_bridge->agp_destroy_page = ali_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 	return 0;
 }
 
@@ -313,7 +313,7 @@
 
 			printk (KERN_INFO PFX "Detected ALi %s chipset\n",
 				devs[j].chipset_name);
-			agp_bridge.type = devs[j].chipset;
+			agp_bridge->type = devs[j].chipset;
 
 			if (devs[j].chipset_setup != NULL)
 				return devs[j].chipset_setup(pdev);
@@ -327,7 +327,7 @@
 	if (agp_try_unsupported) {
 		printk(KERN_WARNING PFX "Trying generic ALi routines"
 		       " for device id: %04x\n", pdev->device);
-		agp_bridge.type = ALI_GENERIC;
+		agp_bridge->type = ALI_GENERIC;
 		return ali_generic_setup(pdev);
 	}
 
@@ -350,10 +350,10 @@
 
 	/* probe for known chipsets */
 	if (agp_lookup_host_bridge(dev) != -ENODEV) {
-		agp_bridge.dev = dev;
-		agp_bridge.capndx = cap_ptr;
+		agp_bridge->dev = dev;
+		agp_bridge->capndx = cap_ptr;
 		/* Fill in the mode register */
-		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
+		pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode);
 		ali_agp_driver.dev = dev;
 		agp_register_driver(&ali_agp_driver);
 		return 0;
@@ -387,7 +387,7 @@
 
 	ret_val = pci_module_init(&agp_ali_pci_driver);
 	if (ret_val)
-		agp_bridge.type = NOT_SUPPORTED;
+		agp_bridge->type = NOT_SUPPORTED;
 
 	return ret_val;
 }
diff -Nru a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/agp/alpha-agp.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,217 @@
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/agp_backend.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+
+#include <asm/machvec.h>
+#include <asm/agp_backend.h>
+#include "../../../arch/alpha/kernel/pci_impl.h"
+
+#include "agp.h"
+
+static struct page *alpha_core_agp_vm_nopage(struct vm_area_struct *vma,
+					     unsigned long address,
+					     int write_access)
+{
+	alpha_agp_info *agp = agp_bridge->dev_private_data;
+	dma_addr_t dma_addr;
+	unsigned long pa;
+	struct page *page;
+
+	dma_addr = address - vma->vm_start + agp->aperture.bus_base;
+	pa = agp->ops->translate(agp, dma_addr);
+
+	if (pa == (unsigned long)-EINVAL) return NULL;	/* no translation */
+	
+	/*
+	 * Get the page, inc the use count, and return it
+	 */
+	page = virt_to_page(__va(pa));
+	get_page(page);
+	return page;
+}
+
+static struct aper_size_info_fixed alpha_core_agp_sizes[] =
+{
+	{ 0, 0, 0 }, /* filled in by alpha_core_agp_setup */
+};
+
+static struct gatt_mask alpha_core_agp_masks[] = {
+	{ .mask = 0, .type = 0 },
+};
+
+struct vm_operations_struct alpha_core_agp_vm_ops = {
+	.nopage = alpha_core_agp_vm_nopage,
+};
+
+
+static int alpha_core_agp_nop(void)
+{
+	/* just return success */
+	return 0;
+}
+
+static int alpha_core_agp_fetch_size(void)
+{
+	return alpha_core_agp_sizes[0].size;
+}
+
+static int alpha_core_agp_configure(void)
+{
+	alpha_agp_info *agp = agp_bridge->dev_private_data;
+	agp_bridge->gart_bus_addr = agp->aperture.bus_base;
+	return 0;
+}
+
+static void alpha_core_agp_cleanup(void)
+{
+	alpha_agp_info *agp = agp_bridge->dev_private_data;
+
+	agp->ops->cleanup(agp);
+}
+
+static void alpha_core_agp_tlbflush(agp_memory *mem)
+{
+	alpha_agp_info *agp = agp_bridge->dev_private_data;
+	alpha_mv.mv_pci_tbi(agp->hose, 0, -1);
+}
+
+static unsigned long alpha_core_agp_mask_memory(unsigned long addr, int type)
+{
+	/* Memory type is ignored */
+	return addr | agp_bridge->masks[0].mask;
+}
+
+static void alpha_core_agp_enable(u32 mode)
+{
+	alpha_agp_info *agp = agp_bridge->dev_private_data;
+
+	agp->mode.lw = agp_collect_device_status(mode, agp->capability.lw);
+
+	agp->mode.bits.enable = 1;
+	agp->ops->configure(agp);
+
+	agp_device_command(agp->mode.lw, 0);
+}
+
+static int alpha_core_agp_insert_memory(agp_memory *mem, off_t pg_start, 
+					int type)
+{
+	alpha_agp_info *agp = agp_bridge->dev_private_data;
+	int num_entries, status;
+	void *temp;
+
+	temp = agp_bridge->current_size;
+	num_entries = A_SIZE_FIX(temp)->num_entries;
+	if ((pg_start + mem->page_count) > num_entries) return -EINVAL;
+
+	status = agp->ops->bind(agp, pg_start, mem);
+	mb();
+	agp_bridge->tlb_flush(mem);
+
+	return status;
+}
+
+static int alpha_core_agp_remove_memory(agp_memory *mem, off_t pg_start, 
+					int type)
+{
+	alpha_agp_info *agp = agp_bridge->dev_private_data;
+	int status;
+
+	status = agp->ops->unbind(agp, pg_start, mem);
+	agp_bridge->tlb_flush(mem);
+	return status;
+}
+
+
+static struct agp_driver alpha_core_agp_driver = {
+	.owner = THIS_MODULE,
+};
+
+int __init
+alpha_core_agp_setup(void)
+{
+	alpha_agp_info *agp = alpha_mv.agp_info();
+	struct aper_size_info_fixed *aper_size;
+
+	if (!agp) return -ENODEV;
+	if (agp->ops->setup(agp)) return -ENODEV;
+
+	/*
+	 * Build the aperture size descriptor
+	 */
+	aper_size = alpha_core_agp_sizes;
+	if (!aper_size) return -ENOMEM;
+	aper_size->size = agp->aperture.size / (1024 * 1024);
+	aper_size->num_entries = agp->aperture.size / PAGE_SIZE;
+	aper_size->page_order = ffs(aper_size->num_entries / 1024) - 1;
+
+	/*
+	 * Build a fake pci_dev struct
+	 */
+	if (!(agp_bridge->dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL))) {
+		return -ENOMEM;
+	}
+	agp_bridge->dev->vendor = 0xffff;
+	agp_bridge->dev->device = 0xffff;
+	agp_bridge->dev->sysdata = agp->hose;
+
+	/*
+	 * Fill in the rest of the agp_bridge struct
+	 */
+	agp_bridge->masks = alpha_core_agp_masks;
+	agp_bridge->aperture_sizes = aper_size;
+	agp_bridge->current_size = aper_size;	/* only one entry */
+	agp_bridge->size_type = FIXED_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 1;
+	agp_bridge->dev_private_data = agp;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = alpha_core_agp_configure;
+	agp_bridge->fetch_size = alpha_core_agp_fetch_size;
+	agp_bridge->cleanup = alpha_core_agp_cleanup;
+	agp_bridge->tlb_flush = alpha_core_agp_tlbflush;
+	agp_bridge->mask_memory = alpha_core_agp_mask_memory;
+	agp_bridge->agp_enable = alpha_core_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = alpha_core_agp_nop;
+	agp_bridge->free_gatt_table = alpha_core_agp_nop;
+	agp_bridge->insert_memory = alpha_core_agp_insert_memory;
+	agp_bridge->remove_memory = alpha_core_agp_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->mode = agp->capability.lw;
+	agp_bridge->cant_use_aperture = 1;
+	agp_bridgevm_ops =  &alpha_core_agp_vm_ops;
+
+	alpha_core_agp_driver.dev = agp_bridge->dev;
+	agp_register_driver(&alpha_core_agp_driver);
+	printk(KERN_INFO "Detected AGP on hose %d\n", agp->hose->index);
+	return 0;
+}
+
+static int __init agp_alpha_core_init(void)
+{
+	int ret_val = -ENODEV;
+	if (alpha_mv.agp_info) {
+		agp_bridge->type = ALPHA_CORE_AGP;
+		ret_val = alpha_core_agp_setup();
+	}
+
+	return ret_val;
+}
+
+static void __exit agp_alpha_core_cleanup(void)
+{
+	agp_unregister_driver(&alpha_core_agp_driver);
+	/* no pci driver for core */
+}
+
+module_init(agp_alpha_core_init);
+module_exit(agp_alpha_core_cleanup);
+
+MODULE_AUTHOR("Jeff Wiedemeier <Jeff.Wiedemeier@hp.com>");
+MODULE_LICENSE("GPL and additional rights");
diff -Nru a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
--- a/drivers/char/agp/amd-k7-agp.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/agp/amd-k7-agp.c	Fri Feb 14 15:53:12 2003
@@ -45,7 +45,7 @@
 	CACHE_FLUSH();
 
 	for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
-		page_map->remapped[i] = agp_bridge.scratch_page;
+		page_map->remapped[i] = agp_bridge->scratch_page;
 	}
 
 	return 0;
@@ -115,7 +115,7 @@
 
 #define GET_PAGE_DIR_OFF(addr) (addr >> 22)
 #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
-	GET_PAGE_DIR_OFF(agp_bridge.gart_bus_addr))
+	GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr))
 #define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12) 
 #define GET_GATT(addr) (amd_irongate_private.gatt_pages[\
 	GET_PAGE_DIR_IDX(addr)]->remapped)
@@ -129,7 +129,7 @@
 	u32 temp;
 	int i;
 
-	value = A_SIZE_LVL2(agp_bridge.current_size);
+	value = A_SIZE_LVL2(agp_bridge->current_size);
 	retval = amd_create_page_map(&page_dir);
 	if (retval != 0) {
 		return retval;
@@ -141,18 +141,18 @@
 		return retval;
 	}
 
-	agp_bridge.gatt_table_real = (u32 *)page_dir.real;
-	agp_bridge.gatt_table = (u32 *)page_dir.remapped;
-	agp_bridge.gatt_bus_addr = virt_to_phys(page_dir.real);
+	agp_bridge->gatt_table_real = (u32 *)page_dir.real;
+	agp_bridge->gatt_table = (u32 *)page_dir.remapped;
+	agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
 
 	/* Get the address for the gart region.
 	 * This is a bus address even on the alpha, b/c its
 	 * used to program the agp master not the cpu
 	 */
 
-	pci_read_config_dword(agp_bridge.dev, AMD_APBASE, &temp);
+	pci_read_config_dword(agp_bridge->dev, AMD_APBASE, &temp);
 	addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-	agp_bridge.gart_bus_addr = addr;
+	agp_bridge->gart_bus_addr = addr;
 
 	/* Calculate the agp offset */
 	for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
@@ -168,8 +168,8 @@
 {
 	struct amd_page_map page_dir;
    
-	page_dir.real = (unsigned long *)agp_bridge.gatt_table_real;
-	page_dir.remapped = (unsigned long *)agp_bridge.gatt_table;
+	page_dir.real = (unsigned long *)agp_bridge->gatt_table_real;
+	page_dir.remapped = (unsigned long *)agp_bridge->gatt_table;
 
 	amd_free_gatt_pages();
 	amd_free_page_map(&page_dir);
@@ -182,15 +182,15 @@
 	u32 temp;
 	struct aper_size_info_lvl2 *values;
 
-	pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
+	pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp);
 	temp = (temp & 0x0000000e);
-	values = A_SIZE_LVL2(agp_bridge.aperture_sizes);
-	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+	values = A_SIZE_LVL2(agp_bridge->aperture_sizes);
+	for (i = 0; i < agp_bridge->num_aperture_sizes; i++) {
 		if (temp == values[i].size_value) {
-			agp_bridge.previous_size =
-			    agp_bridge.current_size = (void *) (values + i);
+			agp_bridge->previous_size =
+			    agp_bridge->current_size = (void *) (values + i);
 
-			agp_bridge.aperture_size_idx = i;
+			agp_bridge->aperture_size_idx = i;
 			return values[i].size;
 		}
 	}
@@ -204,22 +204,22 @@
 	u32 temp;
 	u16 enable_reg;
 
-	current_size = A_SIZE_LVL2(agp_bridge.current_size);
+	current_size = A_SIZE_LVL2(agp_bridge->current_size);
 
 	/* Get the memory mapped registers */
-	pci_read_config_dword(agp_bridge.dev, AMD_MMBASE, &temp);
+	pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp);
 	temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 	amd_irongate_private.registers = (volatile u8 *) ioremap(temp, 4096);
 
 	/* Write out the address of the gatt table */
 	OUTREG32(amd_irongate_private.registers, AMD_ATTBASE,
-		 agp_bridge.gatt_bus_addr);
+		 agp_bridge->gatt_bus_addr);
 
 	/* Write the Sync register */
-	pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL, 0x80);
+	pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL, 0x80);
    
    	/* Set indexing mode */
-   	pci_write_config_byte(agp_bridge.dev, AMD_MODECNTL2, 0x00);
+   	pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL2, 0x00);
 
 	/* Write the enable register */
 	enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
@@ -227,10 +227,10 @@
 	OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
 
 	/* Write out the size register */
-	pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
+	pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp);
 	temp = (((temp & ~(0x0000000e)) | current_size->size_value)
 		| 0x00000001);
-	pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp);
+	pci_write_config_dword(agp_bridge->dev, AMD_APSIZE, temp);
 
 	/* Flush the tlb */
 	OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
@@ -244,16 +244,16 @@
 	u32 temp;
 	u16 enable_reg;
 
-	previous_size = A_SIZE_LVL2(agp_bridge.previous_size);
+	previous_size = A_SIZE_LVL2(agp_bridge->previous_size);
 
 	enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
 	enable_reg = (enable_reg & ~(0x0004));
 	OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
 
 	/* Write back the previous size and disable gart translation */
-	pci_read_config_dword(agp_bridge.dev, AMD_APSIZE, &temp);
+	pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp);
 	temp = ((temp & ~(0x0000000f)) | previous_size->size_value);
-	pci_write_config_dword(agp_bridge.dev, AMD_APSIZE, temp);
+	pci_write_config_dword(agp_bridge->dev, AMD_APSIZE, temp);
 	iounmap((void *) amd_irongate_private.registers);
 }
 
@@ -274,7 +274,7 @@
 {
 	/* Only type 0 is supported by the irongate */
 
-	return addr | agp_bridge.masks[0].mask;
+	return addr | agp_bridge->masks[0].mask;
 }
 
 static int amd_insert_memory(agp_memory * mem,
@@ -284,7 +284,7 @@
 	unsigned long *cur_gatt;
 	unsigned long addr;
 
-	num_entries = A_SIZE_LVL2(agp_bridge.current_size)->num_entries;
+	num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;
 
 	if (type != 0 || mem->type != 0) {
 		return -EINVAL;
@@ -295,7 +295,7 @@
 
 	j = pg_start;
 	while (j < (pg_start + mem->page_count)) {
-		addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr;
+		addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
 		cur_gatt = GET_GATT(addr);
 		if (!PGE_EMPTY(cur_gatt[GET_GATT_OFF(addr)])) {
 			return -EBUSY;
@@ -309,12 +309,12 @@
 	}
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr;
+		addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
 		cur_gatt = GET_GATT(addr);
 		cur_gatt[GET_GATT_OFF(addr)] =
-			agp_bridge.mask_memory(mem->memory[i], mem->type);
+			agp_bridge->mask_memory(mem->memory[i], mem->type);
 	}
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 	return 0;
 }
 
@@ -329,13 +329,13 @@
 		return -EINVAL;
 	}
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-		addr = (i * PAGE_SIZE) + agp_bridge.gart_bus_addr;
+		addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
 		cur_gatt = GET_GATT(addr);
 		cur_gatt[GET_GATT_OFF(addr)] = 
-			(unsigned long) agp_bridge.scratch_page;
+			(unsigned long) agp_bridge->scratch_page;
 	}
 
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 	return 0;
 }
 
@@ -357,30 +357,30 @@
 
 static int __init amd_irongate_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = amd_irongate_masks;
-	agp_bridge.aperture_sizes = (void *) amd_irongate_sizes;
-	agp_bridge.size_type = LVL2_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = (void *) &amd_irongate_private;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = amd_irongate_configure;
-	agp_bridge.fetch_size = amd_irongate_fetch_size;
-	agp_bridge.cleanup = amd_irongate_cleanup;
-	agp_bridge.tlb_flush = amd_irongate_tlbflush;
-	agp_bridge.mask_memory = amd_irongate_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = amd_create_gatt_table;
-	agp_bridge.free_gatt_table = amd_free_gatt_table;
-	agp_bridge.insert_memory = amd_insert_memory;
-	agp_bridge.remove_memory = amd_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = amd_irongate_masks;
+	agp_bridge->aperture_sizes = (void *) amd_irongate_sizes;
+	agp_bridge->size_type = LVL2_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 7;
+	agp_bridge->dev_private_data = (void *) &amd_irongate_private;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = amd_irongate_configure;
+	agp_bridge->fetch_size = amd_irongate_fetch_size;
+	agp_bridge->cleanup = amd_irongate_cleanup;
+	agp_bridge->tlb_flush = amd_irongate_tlbflush;
+	agp_bridge->mask_memory = amd_irongate_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = amd_create_gatt_table;
+	agp_bridge->free_gatt_table = amd_free_gatt_table;
+	agp_bridge->insert_memory = amd_insert_memory;
+	agp_bridge->remove_memory = amd_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 	return 0;
 }
 
@@ -416,7 +416,7 @@
 	while (devs[j].chipset_name != NULL) {
 		if (pdev->device == devs[j].device_id) {
 			printk (KERN_INFO PFX "Detected AMD %s chipset\n", devs[j].chipset_name);
-			agp_bridge.type = devs[j].chipset;
+			agp_bridge->type = devs[j].chipset;
 
 			if (devs[j].chipset_setup != NULL)
 				return devs[j].chipset_setup(pdev);
@@ -430,7 +430,7 @@
 	if (agp_try_unsupported) {
 		printk(KERN_WARNING PFX "Trying generic AMD routines"
 		       " for device id: %04x\n", pdev->device);
-		agp_bridge.type = AMD_GENERIC;
+		agp_bridge->type = AMD_GENERIC;
 		return amd_irongate_setup(pdev);
 	}
 
@@ -455,10 +455,10 @@
 		return -ENODEV;
 
 	if (agp_lookup_host_bridge(dev) != -ENODEV) {
-		agp_bridge.dev = dev;
-		agp_bridge.capndx = cap_ptr;
+		agp_bridge->dev = dev;
+		agp_bridge->capndx = cap_ptr;
 		/* Fill in the mode register */
-		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
+		pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode);
 		amd_k7_agp_driver.dev = dev;
 		agp_register_driver(&amd_k7_agp_driver);
 		return 0;
@@ -492,7 +492,7 @@
 
 	ret_val = pci_module_init(&agp_amdk7_pci_driver);
 	if (ret_val)
-		agp_bridge.type = NOT_SUPPORTED;
+		agp_bridge->type = NOT_SUPPORTED;
 
 	return ret_val;
 }
diff -Nru a/drivers/char/agp/amd-k8-agp.c b/drivers/char/agp/amd-k8-agp.c
--- a/drivers/char/agp/amd-k8-agp.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/char/agp/amd-k8-agp.c	Fri Feb 14 15:53:11 2003
@@ -20,34 +20,14 @@
 #include <linux/agp_backend.h>
 #include "agp.h"
 
-static u_int64_t pci_read64 (struct pci_dev *dev, int reg)
-{
-	union {
-		u64 full;
-		struct {
-			u32 high;
-			u32 low;
-		} split;
-	} tmp;
-	pci_read_config_dword(dev, reg, &tmp.split.high);
-	pci_read_config_dword(dev, reg+4, &tmp.split.low);
-	return tmp.full;
-}
-
-static void pci_write64 (struct pci_dev *dev, int reg, u64 value)
-{
-	union {
-		u64 full;
-		struct {
-			u32 high;
-			u32 low;
-		} split;
-	} tmp;
-	tmp.full = value;
-	pci_write_config_dword(dev, reg, tmp.split.high);
-	pci_write_config_dword(dev, reg+4, tmp.split.low);
-}
+/* Will need to be increased if hammer ever goes >8-way. */
+#define MAX_HAMMER_GARTS   8
+
+static int nr_garts;
+static struct pci_dev * hammers[MAX_HAMMER_GARTS];
 
+static int gart_iterator;
+#define for_each_nb() for(gart_iterator=0;gart_iterator<nr_garts;gart_iterator++)
 
 static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type)
 {
@@ -70,7 +50,7 @@
 
 	/* gatt table should be empty. */
 	while (j < (pg_start + mem->page_count)) {
-		if (!PGE_EMPTY(agp_bridge.gatt_table[j]))
+		if (!PGE_EMPTY(agp_bridge->gatt_table[j]))
 			return -EBUSY;
 		j++;
 	}
@@ -81,7 +61,7 @@
 	}
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		addr = agp_bridge.mask_memory(mem->memory[i], mem->type);
+		addr = agp_bridge->mask_memory(mem->memory[i], mem->type);
 
 		tmp = addr;
 		BUG_ON(tmp & 0xffffff0000000ffc);
@@ -89,9 +69,9 @@
 		pte |=(tmp & 0x00000000fffff000);
 		pte |= 1<<1|1<<0;
 
-		agp_bridge.gatt_table[j] = pte;
+		agp_bridge->gatt_table[j] = pte;
 	}
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 	return 0;
 }
 
@@ -125,27 +105,23 @@
 	u32 temp;
 	struct aper_size_info_32 *values;
 
-	pci_for_each_dev(dev) {
-		if (dev->bus->number==0 &&
-			PCI_FUNC(dev->devfn)==3 &&
-			PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) {
-
-			pci_read_config_dword(dev, AMD_X86_64_GARTAPERTURECTL, &temp);
-			temp = (temp & 0xe);
-			values = A_SIZE_32(x86_64_aperture_sizes);
-
-			for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
-				if (temp == values[i].size_value) {
-					agp_bridge.previous_size =
-					    agp_bridge.current_size = (void *) (values + i);
-
-					agp_bridge.aperture_size_idx = i;
-					return values[i].size;
-				}
-			}
+	dev = hammers[0];
+	if (dev==NULL)
+		return 0;
+
+	pci_read_config_dword(dev, AMD_X86_64_GARTAPERTURECTL, &temp);
+	temp = (temp & 0xe);
+	values = A_SIZE_32(x86_64_aperture_sizes);
+
+	for (i = 0; i < agp_bridge->num_aperture_sizes; i++) {
+		if (temp == values[i].size_value) {
+			agp_bridge->previous_size =
+			    agp_bridge->current_size = (void *) (values + i);
+
+			agp_bridge->aperture_size_idx = i;
+			return values[i].size;
 		}
 	}
-	/* erk, couldn't find an x86-64 ? */
 	return 0;
 }
 
@@ -162,13 +138,8 @@
 
 static void amd_x86_64_tlbflush(agp_memory * temp)
 {
-	struct pci_dev *dev;
-
-	pci_for_each_dev(dev) {
-		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
-		    PCI_SLOT(dev->devfn) >=24 && PCI_SLOT(dev->devfn) <=31) {
-			flush_x86_64_tlb (dev);
-		}
+	for_each_nb() {
+		flush_x86_64_tlb (hammers[gart_iterator]);
 	}
 }
 
@@ -221,101 +192,33 @@
 
 static int amd_8151_configure(void)
 {
-	struct pci_dev *dev, *hammer=NULL;
-	int current_size;
-	int tmp, tmp2, i;
-	u64 aperbar;
-	unsigned long gatt_bus = virt_to_phys(agp_bridge.gatt_table_real);
+	unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real);
 
 	/* Configure AGP regs in each x86-64 host bridge. */
-	pci_for_each_dev(dev) {
-		if (dev->bus->number==0 &&
-			PCI_FUNC(dev->devfn)==3 &&
-			PCI_SLOT(dev->devfn)>=24 && PCI_SLOT(dev->devfn)<=31) {
-			agp_bridge.gart_bus_addr = amd_x86_64_configure(dev,gatt_bus);
-			hammer = dev;
-
-			/*
-			 * TODO: Cache pci_dev's of x86-64's in private struct to save us
-			 * having to scan the pci list each time.
-			 */
-		}
-	}
-
-	if (hammer == NULL) {
-		return -ENODEV;
-	}
-
-	/* Shadow x86-64 registers into 8151 registers. */
-
-	dev = agp_bridge.dev;
-	if (!dev) 
-		return -ENODEV;
-
-	current_size = amd_x86_64_fetch_size();
-
-	pci_read_config_dword(dev, AMD_8151_APERTURESIZE, &tmp);
-	tmp &= ~(0xfff);
-
-	/* translate x86-64 size bits to 8151 size bits*/
-	for (i=0 ; i<7; i++) {
-		if (amd_8151_sizes[i].size == current_size)
-			tmp |= (amd_8151_sizes[i].size_value) << 3;
+	for_each_nb() {
+		agp_bridge->gart_bus_addr =
+				amd_x86_64_configure(hammers[gart_iterator],gatt_bus);
 	}
-	pci_write_config_dword(dev, AMD_8151_APERTURESIZE, tmp);
-
-	pci_read_config_dword (hammer, AMD_X86_64_GARTAPERTUREBASE, &tmp);
-	aperbar = pci_read64 (dev, AMD_8151_VMAPERTURE);
-	aperbar |= (tmp & 0x7fff) <<25;
-	aperbar &= 0x000000ffffffffff;
-	aperbar |= 1<<2;	/* This address is a 64bit ptr FIXME: Make conditional in 32bit mode */
-	pci_write64 (dev, AMD_8151_VMAPERTURE, aperbar);
-
-	pci_read_config_dword(dev, AMD_8151_AGP_CTL , &tmp);
-	tmp &= ~(AMD_8151_GTLBEN | AMD_8151_APEREN);
-	
-	pci_read_config_dword(hammer, AMD_X86_64_GARTAPERTURECTL, &tmp2);
-	if (tmp2 & AMD_X86_64_GARTEN)
-		tmp |= AMD_8151_APEREN;
-	// FIXME: bit 7 of AMD_8151_AGP_CTL (GTLBEN) must be copied if set.
-	// But where is it set ?
-	pci_write_config_dword(dev, AMD_8151_AGP_CTL, tmp);
-
 	return 0;
 }
 
 
 static void amd_8151_cleanup(void)
 {
-	struct pci_dev *dev;
 	u32 tmp;
 
-	pci_for_each_dev(dev) {
+	for_each_nb() {
 		/* disable gart translation */
-		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
-		    (PCI_SLOT(dev->devfn) >=24) && (PCI_SLOT(dev->devfn) <=31)) {
-
-			pci_read_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, &tmp);
-			tmp &= ~(AMD_X86_64_GARTEN);
-			pci_write_config_dword (dev, AMD_X86_64_GARTAPERTURECTL, tmp);
-		}
-
-		/* Now shadow the disable in the 8151 */
-		if (dev->vendor == PCI_VENDOR_ID_AMD &&
-			dev->device == PCI_DEVICE_ID_AMD_8151_0) {
-
-			pci_read_config_dword (dev, AMD_8151_AGP_CTL, &tmp);
-			tmp &= ~(AMD_8151_APEREN);	
-			pci_write_config_dword (dev, AMD_8151_AGP_CTL, tmp);
-		}
+		pci_read_config_dword (hammers[gart_iterator], AMD_X86_64_GARTAPERTURECTL, &tmp);
+		tmp &= ~(AMD_X86_64_GARTEN);
+		pci_write_config_dword (hammers[gart_iterator], AMD_X86_64_GARTAPERTURECTL, tmp);
 	}
 }
 
 
-
 static unsigned long amd_8151_mask_memory(unsigned long addr, int type)
 {
-	return addr | agp_bridge.masks[0].mask;
+	return addr | agp_bridge->masks[0].mask;
 }
 
 
@@ -368,12 +271,12 @@
 	}
 
 
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &command);
+	pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &command);
 
 	command = agp_collect_device_status(mode, command);
 	command |= 0x100;
 
-	pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_COMMAND, command);
+	pci_write_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_COMMAND, command);
 
 	agp_device_command(command, 1);
 }
@@ -381,30 +284,47 @@
 
 static int __init amd_8151_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = amd_8151_masks;
-	agp_bridge.aperture_sizes = (void *) amd_8151_sizes;
-	agp_bridge.size_type = U32_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = amd_8151_configure;
-	agp_bridge.fetch_size = amd_x86_64_fetch_size;
-	agp_bridge.cleanup = amd_8151_cleanup;
-	agp_bridge.tlb_flush = amd_x86_64_tlbflush;
-	agp_bridge.mask_memory = amd_8151_mask_memory;
-	agp_bridge.agp_enable = agp_x86_64_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = x86_64_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	struct pci_dev *dev;
+	int i=0;
+
+	agp_bridge->masks = amd_8151_masks;
+	agp_bridge->aperture_sizes = (void *) amd_8151_sizes;
+	agp_bridge->size_type = U32_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 7;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = amd_8151_configure;
+	agp_bridge->fetch_size = amd_x86_64_fetch_size;
+	agp_bridge->cleanup = amd_8151_cleanup;
+	agp_bridge->tlb_flush = amd_x86_64_tlbflush;
+	agp_bridge->mask_memory = amd_8151_mask_memory;
+	agp_bridge->agp_enable = agp_x86_64_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = x86_64_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
+
+
+	/* cache pci_devs of northbridges. */
+	pci_for_each_dev(dev) {
+		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&
+			(PCI_SLOT(dev->devfn) >=24) && (PCI_SLOT(dev->devfn) <=31)) {
+
+			hammers[i++] = dev;
+			nr_garts = i;
+			if (i==MAX_HAMMER_GARTS)
+				return 0;
+		}
+	}
+
 	return 0;
 }
 
@@ -420,11 +340,11 @@
 	if (cap_ptr == 0)
 		return -ENODEV;
 
-	agp_bridge.dev = dev;
-	agp_bridge.capndx = cap_ptr;
+	agp_bridge->dev = dev;
+	agp_bridge->capndx = cap_ptr;
 
 	/* Fill in the mode register */
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
+	pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode);
 	amd_8151_setup(dev);
 	amd_k8_agp_driver.dev = dev;
 	agp_register_driver(&amd_k8_agp_driver);
@@ -458,9 +378,9 @@
 
 	ret_val = pci_module_init(&agp_amdk8_pci_driver);
 	if (ret_val)
-		agp_bridge.type = NOT_SUPPORTED;
+		agp_bridge->type = NOT_SUPPORTED;
 
-	agp_bridge.type = AMD_8151;
+	agp_bridge->type = AMD_8151;
 
 	return ret_val;
 }
diff -Nru a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
--- a/drivers/char/agp/backend.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/agp/backend.c	Fri Feb 14 15:53:12 2003
@@ -44,26 +44,27 @@
 #define AGPGART_VERSION_MAJOR 0
 #define AGPGART_VERSION_MINOR 100
 
-struct agp_bridge_data agp_bridge = { .type = NOT_SUPPORTED };
+struct agp_bridge_data agp_bridge_dummy = { .type = NOT_SUPPORTED };
+struct agp_bridge_data *agp_bridge = &agp_bridge_dummy;
 
 int agp_backend_acquire(void)
 {
-	if (agp_bridge.type == NOT_SUPPORTED)
+	if (agp_bridge->type == NOT_SUPPORTED)
 		return -EINVAL;
 
-	if (atomic_read(&agp_bridge.agp_in_use) != 0)
+	if (atomic_read(&agp_bridge->agp_in_use) != 0)
 		return -EBUSY;
 
-	atomic_inc(&agp_bridge.agp_in_use);
+	atomic_inc(&agp_bridge->agp_in_use);
 	return 0;
 }
 
 void agp_backend_release(void)
 {
-	if (agp_bridge.type == NOT_SUPPORTED)
+	if (agp_bridge->type == NOT_SUPPORTED)
 		return;
 
-	atomic_dec(&agp_bridge.agp_in_use);
+	atomic_dec(&agp_bridge->agp_in_use);
 }
 
 struct agp_max_table {
@@ -114,38 +115,38 @@
 {
 	int size_value, rc, got_gatt=0, got_keylist=0;
 
-	agp_bridge.max_memory_agp = agp_find_max();
-	agp_bridge.version = &agp_current_version;
+	agp_bridge->max_memory_agp = agp_find_max();
+	agp_bridge->version = &agp_current_version;
 
-	if (agp_bridge.needs_scratch_page == TRUE) {
+	if (agp_bridge->needs_scratch_page == TRUE) {
 		void *addr;
-		addr = agp_bridge.agp_alloc_page();
+		addr = agp_bridge->agp_alloc_page();
 
 		if (addr == NULL) {
 			printk(KERN_ERR PFX "unable to get memory for scratch page.\n");
 			return -ENOMEM;
 		}
-		agp_bridge.scratch_page_real = virt_to_phys(addr);
-		agp_bridge.scratch_page =
-			agp_bridge.mask_memory(agp_bridge.scratch_page_real, 0);
+		agp_bridge->scratch_page_real = virt_to_phys(addr);
+		agp_bridge->scratch_page =
+			agp_bridge->mask_memory(agp_bridge->scratch_page_real, 0);
 	}
 
-	size_value = agp_bridge.fetch_size();
+	size_value = agp_bridge->fetch_size();
 
 	if (size_value == 0) {
 		printk(KERN_ERR PFX "unable to determine aperture size.\n");
 		rc = -EINVAL;
 		goto err_out;
 	}
-	if (agp_bridge.create_gatt_table()) {
+	if (agp_bridge->create_gatt_table()) {
 		printk(KERN_ERR PFX "unable to get memory for graphics translation table.\n");
 		rc = -ENOMEM;
 		goto err_out;
 	}
 	got_gatt = 1;
 	
-	agp_bridge.key_list = vmalloc(PAGE_SIZE * 4);
-	if (agp_bridge.key_list == NULL) {
+	agp_bridge->key_list = vmalloc(PAGE_SIZE * 4);
+	if (agp_bridge->key_list == NULL) {
 		printk(KERN_ERR PFX "error allocating memory for key lists.\n");
 		rc = -ENOMEM;
 		goto err_out;
@@ -153,27 +154,27 @@
 	got_keylist = 1;
 	
 	/* FIXME vmalloc'd memory not guaranteed contiguous */
-	memset(agp_bridge.key_list, 0, PAGE_SIZE * 4);
+	memset(agp_bridge->key_list, 0, PAGE_SIZE * 4);
 
-	if (agp_bridge.configure()) {
+	if (agp_bridge->configure()) {
 		printk(KERN_ERR PFX "error configuring host chipset.\n");
 		rc = -EINVAL;
 		goto err_out;
 	}
 
 	printk(KERN_INFO PFX "AGP aperture is %dM @ 0x%lx\n",
-	       size_value, agp_bridge.gart_bus_addr);
+	       size_value, agp_bridge->gart_bus_addr);
 
 	return 0;
 
 err_out:
-	if (agp_bridge.needs_scratch_page == TRUE) {
-		agp_bridge.agp_destroy_page(phys_to_virt(agp_bridge.scratch_page_real));
+	if (agp_bridge->needs_scratch_page == TRUE) {
+		agp_bridge->agp_destroy_page(phys_to_virt(agp_bridge->scratch_page_real));
 	}
 	if (got_gatt)
-		agp_bridge.free_gatt_table();
+		agp_bridge->free_gatt_table();
 	if (got_keylist)
-		vfree(agp_bridge.key_list);
+		vfree(agp_bridge->key_list);
 	return rc;
 }
 
@@ -181,13 +182,16 @@
 /* cannot be __exit b/c as it could be called from __init code */
 static void agp_backend_cleanup(void)
 {
-	agp_bridge.cleanup();
-	agp_bridge.free_gatt_table();
-	vfree(agp_bridge.key_list);
-
-	if (agp_bridge.needs_scratch_page == TRUE) {
-		agp_bridge.agp_destroy_page(phys_to_virt(agp_bridge.scratch_page_real));
-	}
+	if (agp_bridge->cleanup != NULL)
+		agp_bridge->cleanup();
+	if (agp_bridge->free_gatt_table != NULL)
+		agp_bridge->free_gatt_table();
+	if (agp_bridge->key_list)
+		vfree(agp_bridge->key_list);
+
+	if ((agp_bridge->agp_destroy_page!=NULL) &&
+			(agp_bridge->needs_scratch_page == TRUE))
+		agp_bridge->agp_destroy_page(phys_to_virt(agp_bridge->scratch_page_real));
 }
 
 static int agp_power(struct pm_dev *dev, pm_request_t rq, void *data)
@@ -195,9 +199,9 @@
 	switch(rq)
 	{
 		case PM_SUSPEND:
-			return agp_bridge.suspend();
+			return agp_bridge->suspend();
 		case PM_RESUME:
-			agp_bridge.resume();
+			agp_bridge->resume();
 			return 0;
 	}		
 	return 0;
@@ -248,21 +252,25 @@
 	/* FIXME: What to do with this? */
 	inter_module_register("drm_agp", THIS_MODULE, &drm_agp);
 
-	pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge.dev), agp_power);
+	pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge->dev), agp_power);
 	agp_count++;
 	return 0;
 
 frontend_err:
 	agp_backend_cleanup();
 err_out:
-	agp_bridge.type = NOT_SUPPORTED;
+	agp_bridge->type = NOT_SUPPORTED;
 	module_put(drv->owner);
+	drv->dev = NULL;
 	return ret_val;
 }
 
 int agp_unregister_driver(struct agp_driver *drv)
 {
-	agp_bridge.type = NOT_SUPPORTED;
+	if (drv->dev==NULL)
+		return -ENODEV;
+
+	agp_bridge->type = NOT_SUPPORTED;
 	pm_unregister_all(agp_power);
 	agp_frontend_cleanup();
 	agp_backend_cleanup();
@@ -282,8 +290,8 @@
 
 	already_initialised = 1;
 
-	memset(&agp_bridge, 0, sizeof(struct agp_bridge_data));
-	agp_bridge.type = NOT_SUPPORTED;
+	memset(agp_bridge, 0, sizeof(struct agp_bridge_data));
+	agp_bridge->type = NOT_SUPPORTED;
 
 	printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Dave Jones\n",
 	       AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
diff -Nru a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
--- a/drivers/char/agp/frontend.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/agp/frontend.c	Fri Feb 14 15:53:09 2003
@@ -97,7 +97,9 @@
 					    int size, pgprot_t page_prot)
 {
 	agp_segment_priv *seg;
-	int num_segments, pg_start, pg_count, i;
+	int num_segments, i;
+	off_t pg_start;
+	size_t pg_count;
 
 	pg_start = offset / 4096;
 	pg_count = size / 4096;
@@ -174,7 +176,7 @@
 	agp_segment_priv **ret_seg;
 	agp_segment_priv *seg;
 	agp_segment *user_seg;
-	int i;
+	size_t i;
 
 	seg = kmalloc((sizeof(agp_segment_priv) * region->seg_count), GFP_KERNEL);
 	if (seg == NULL) {
@@ -578,8 +580,7 @@
 
 static int agp_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	int size;
-	int current_size;
+	unsigned int size, current_size;
 	unsigned long offset;
 	agp_client *client;
 	agp_file_private *priv = (agp_file_private *) file->private_data;
@@ -611,8 +612,11 @@
 		if (!agp_find_seg_in_client(client, offset, size, vma->vm_page_prot))
 			goto out_inval;
 
-		if (remap_page_range(vma, vma->vm_start, (kerninfo.aper_base + offset),
-				     size, vma->vm_page_prot)) {
+		if (kerninfo.vm_ops) {
+			vma->vm_ops = kerninfo.vm_ops;
+		} else if (remap_page_range(vma, vma->vm_start, 
+					    (kerninfo.aper_base + offset),
+					    size, vma->vm_page_prot)) {
 			goto out_again;
 		}
 		AGP_UNLOCK();
@@ -623,8 +627,11 @@
 		if (size != current_size)
 			goto out_inval;
 
-		if (remap_page_range(vma, vma->vm_start, kerninfo.aper_base,
-				     size, vma->vm_page_prot)) {
+		if (kerninfo.vm_ops) {
+			vma->vm_ops = kerninfo.vm_ops;
+		} else if (remap_page_range(vma, vma->vm_start, 
+					    kerninfo.aper_base,
+					    size, vma->vm_page_prot)) {
 			goto out_again;
 		}
 		AGP_UNLOCK();
diff -Nru a/drivers/char/agp/generic-3.0.c b/drivers/char/agp/generic-3.0.c
--- a/drivers/char/agp/generic-3.0.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/agp/generic-3.0.c	Fri Feb 14 15:53:09 2003
@@ -77,7 +77,7 @@
 		struct agp_3_0_dev *dev;
 	};
 
-	struct pci_dev *td = agp_bridge.dev, *dev;
+	struct pci_dev *td = agp_bridge->dev, *dev;
 	struct list_head *head = &dev_list->list, *pos;
 	struct agp_3_0_dev *cur;
 	struct isoch_data *master, target;
@@ -117,8 +117,8 @@
 	if((ret = agp_3_0_dev_list_sort(dev_list, ndevs)) != 0)
 		goto free_and_exit;
 
-	pci_read_config_dword(td, agp_bridge.capndx + 0x0c, &tnistat);
-	pci_read_config_dword(td, agp_bridge.capndx + 0x04, &tstatus);
+	pci_read_config_dword(td, agp_bridge->capndx + 0x0c, &tnistat);
+	pci_read_config_dword(td, agp_bridge->capndx + 0x04, &tstatus);
 
 	/* Extract power-on defaults from the target */
 	target.maxbw = (tnistat >> 16) & 0xff;
@@ -170,13 +170,13 @@
 	 * in the target's NISTAT register, so we need to do this now
 	 * to get an accurate value for ISOCH_N later.
 	 */
-	pci_read_config_word(td, agp_bridge.capndx + 0x20, &tnicmd);
+	pci_read_config_word(td, agp_bridge->capndx + 0x20, &tnicmd);
 	tnicmd &= ~(0x3 << 6);
 	tnicmd |= target.y << 6;
-	pci_write_config_word(td, agp_bridge.capndx + 0x20, tnicmd);
+	pci_write_config_word(td, agp_bridge->capndx + 0x20, tnicmd);
 
 	/* Reread the target's ISOCH_N */
-	pci_read_config_dword(td, agp_bridge.capndx + 0x0c, &tnistat);
+	pci_read_config_dword(td, agp_bridge->capndx + 0x0c, &tnistat);
 	target.n = (tnistat >> 8) & 0xff;
 
 	/* Calculate the minimum ISOCH_N needed by each master */
@@ -296,7 +296,7 @@
 	u32 trq, mrq, rem;
 	unsigned int cdev = 0;
 
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 0x04, &tstatus);
+	pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + 0x04, &tstatus);
 
 	trq = (tstatus >> 24) & 0xff;
 	mrq = trq / ndevs;
@@ -321,7 +321,7 @@
  */
 static int agp_3_0_node_enable(u32 mode, u32 minor)
 {
-	struct pci_dev *td = agp_bridge.dev, *dev;
+	struct pci_dev *td = agp_bridge->dev, *dev;
 	u8 bus_num, mcapndx;
 	u32 isoch, arqsz, cal_cycle, tmp, rate;
 	u32 tstatus, tcmd, mcmd, mstatus, ncapid;
@@ -364,7 +364,7 @@
 	}
 
 	/* Extract some power-on defaults from the target */
-	pci_read_config_dword(td, agp_bridge.capndx + 0x04, &tstatus);
+	pci_read_config_dword(td, agp_bridge->capndx + 0x04, &tstatus);
 	isoch     = (tstatus >> 17) & 0x1;
 	arqsz     = (tstatus >> 13) & 0x7;
 	cal_cycle = (tstatus >> 10) & 0x7;
@@ -470,7 +470,7 @@
 	 * Also set the AGP_ENABLE bit, effectively 'turning on' the
 	 * target (this has to be done _before_ turning on the masters).
 	 */
-	pci_read_config_dword(td, agp_bridge.capndx + 0x08, &tcmd);
+	pci_read_config_dword(td, agp_bridge->capndx + 0x08, &tcmd);
 
 	tcmd &= ~(0x7 << 10);
 	tcmd &= ~0x7;
@@ -479,7 +479,7 @@
 	tcmd |= 0x1 << 8;
 	tcmd |= rate;
 
-	pci_write_config_dword(td, agp_bridge.capndx + 0x08, tcmd);
+	pci_write_config_dword(td, agp_bridge->capndx + 0x08, tcmd);
 
 	/*
 	 * Set the target's advertised arqsz value, the minimum supported
@@ -525,11 +525,11 @@
  * (AGP 3.0 devices are required to operate as AGP 2.0 devices 
  * when not using 3.0 electricals.
  */
-int agp_generic_agp_3_0_enable(u32 mode)
+void agp_generic_agp_3_0_enable(u32 mode)
 {
 	u32 ncapid, major, minor, agp_3_0;
 
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx, &ncapid);
+	pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx, &ncapid);
 
 	major = (ncapid >> 20) & 0xf;
 	minor = (ncapid >> 16) & 0xf;
@@ -537,16 +537,13 @@
 	printk(KERN_INFO PFX "Found an AGP %d.%d compliant device.\n",major, minor);
 
 	if(major >= 3) {
-		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 0x4, &agp_3_0);
+		pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + 0x4, &agp_3_0);
 		/* 
 		 * Check to see if we are operating in 3.0 mode 
 		 */
-		if((agp_3_0 >> 3) & 0x1) {
+		if((agp_3_0 >> 3) & 0x1)
 			agp_3_0_node_enable(mode, minor);
-			return TRUE;
-		}
 	}
-	return FALSE;
 }
 
 EXPORT_SYMBOL(agp_generic_agp_3_0_enable);
diff -Nru a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
--- a/drivers/char/agp/generic.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/agp/generic.c	Fri Feb 14 15:53:09 2003
@@ -52,16 +52,16 @@
 		return;
 
 	if (key < MAXKEY)
-		clear_bit(key, agp_bridge.key_list);
+		clear_bit(key, agp_bridge->key_list);
 }
 
 static int agp_get_key(void)
 {
 	int bit;
 
-	bit = find_first_zero_bit(agp_bridge.key_list, MAXKEY);
+	bit = find_first_zero_bit(agp_bridge->key_list, MAXKEY);
 	if (bit < MAXKEY) {
-		set_bit(bit, agp_bridge.key_list);
+		set_bit(bit, agp_bridge->key_list);
 		return bit;
 	}
 	return -1;
@@ -96,21 +96,21 @@
 
 void agp_free_memory(agp_memory * curr)
 {
-	int i;
+	size_t i;
 
-	if ((agp_bridge.type == NOT_SUPPORTED) || (curr == NULL))
+	if ((agp_bridge->type == NOT_SUPPORTED) || (curr == NULL))
 		return;
 
 	if (curr->is_bound == TRUE)
 		agp_unbind_memory(curr);
 
 	if (curr->type != 0) {
-		agp_bridge.free_by_type(curr);
+		agp_bridge->free_by_type(curr);
 		return;
 	}
 	if (curr->page_count != 0) {
 		for (i = 0; i < curr->page_count; i++) {
-			agp_bridge.agp_destroy_page(phys_to_virt(curr->memory[i]));
+			agp_bridge->agp_destroy_page(phys_to_virt(curr->memory[i]));
 		}
 	}
 	agp_free_key(curr->key);
@@ -124,16 +124,16 @@
 {
 	int scratch_pages;
 	agp_memory *new;
-	int i;
+	size_t i;
 
-	if (agp_bridge.type == NOT_SUPPORTED)
+	if (agp_bridge->type == NOT_SUPPORTED)
 		return NULL;
 
-	if ((atomic_read(&agp_bridge.current_memory_agp) + page_count) > agp_bridge.max_memory_agp)
+	if ((atomic_read(&agp_bridge->current_memory_agp) + page_count) > agp_bridge->max_memory_agp)
 		return NULL;
 
 	if (type != 0) {
-		new = agp_bridge.alloc_by_type(page_count, type);
+		new = agp_bridge->alloc_by_type(page_count, type);
 		return new;
 	}
 
@@ -145,7 +145,7 @@
 		return NULL;
 
 	for (i = 0; i < page_count; i++) {
-		void *addr = agp_bridge.agp_alloc_page();
+		void *addr = agp_bridge->agp_alloc_page();
 
 		if (addr == NULL) {
 			agp_free_memory(new);
@@ -167,9 +167,9 @@
 	int current_size;
 	void *temp;
 
-	temp = agp_bridge.current_size;
+	temp = agp_bridge->current_size;
 
-	switch (agp_bridge.size_type) {
+	switch (agp_bridge->size_type) {
 	case U8_APER_SIZE:
 		current_size = A_SIZE_8(temp)->size;
 		break;
@@ -201,9 +201,9 @@
 	int num_entries;
 	void *temp;
 
-	temp = agp_bridge.current_size;
+	temp = agp_bridge->current_size;
 
-	switch (agp_bridge.size_type) {
+	switch (agp_bridge->size_type) {
 	case U8_APER_SIZE:
 		num_entries = A_SIZE_8(temp)->num_entries;
 		break;
@@ -235,20 +235,21 @@
 int agp_copy_info(agp_kern_info * info)
 {
 	memset(info, 0, sizeof(agp_kern_info));
-	if (agp_bridge.type == NOT_SUPPORTED) {
-		info->chipset = agp_bridge.type;
+	if (agp_bridge->type == NOT_SUPPORTED) {
+		info->chipset = agp_bridge->type;
 		return -EIO;
 	}
-	info->version.major = agp_bridge.version->major;
-	info->version.minor = agp_bridge.version->minor;
-	info->device = agp_bridge.dev;
-	info->chipset = agp_bridge.type;
-	info->mode = agp_bridge.mode;
-	info->aper_base = agp_bridge.gart_bus_addr;
+	info->version.major = agp_bridge->version->major;
+	info->version.minor = agp_bridge->version->minor;
+	info->device = agp_bridge->dev;
+	info->chipset = agp_bridge->type;
+	info->mode = agp_bridge->mode;
+	info->aper_base = agp_bridge->gart_bus_addr;
 	info->aper_size = agp_return_size();
-	info->max_memory = agp_bridge.max_memory_agp;
-	info->current_memory = atomic_read(&agp_bridge.current_memory_agp);
-	info->cant_use_aperture = agp_bridge.cant_use_aperture;
+	info->max_memory = agp_bridge->max_memory_agp;
+	info->current_memory = atomic_read(&agp_bridge->current_memory_agp);
+	info->cant_use_aperture = agp_bridge->cant_use_aperture;
+	info->vm_ops = agp_bridge->vm_ops;
 	info->page_mask = ~0UL;
 	return 0;
 }
@@ -265,7 +266,7 @@
 {
 	int ret_val;
 
-	if ((agp_bridge.type == NOT_SUPPORTED) ||
+	if ((agp_bridge->type == NOT_SUPPORTED) ||
 	    (curr == NULL) || (curr->is_bound == TRUE)) {
 		return -EINVAL;
 	}
@@ -273,7 +274,7 @@
 		CACHE_FLUSH();
 		curr->is_flushed = TRUE;
 	}
-	ret_val = agp_bridge.insert_memory(curr, pg_start, curr->type);
+	ret_val = agp_bridge->insert_memory(curr, pg_start, curr->type);
 
 	if (ret_val != 0)
 		return ret_val;
@@ -287,13 +288,13 @@
 {
 	int ret_val;
 
-	if ((agp_bridge.type == NOT_SUPPORTED) || (curr == NULL))
+	if ((agp_bridge->type == NOT_SUPPORTED) || (curr == NULL))
 		return -EINVAL;
 
 	if (curr->is_bound != TRUE)
 		return -EINVAL;
 
-	ret_val = agp_bridge.remove_memory(curr, curr->pg_start, curr->type);
+	ret_val = agp_bridge->remove_memory(curr, curr->pg_start, curr->type);
 
 	if (ret_val != 0)
 		return ret_val;
@@ -395,15 +396,15 @@
 {
 	u32 command;
 
-	pci_read_config_dword(agp_bridge.dev,
-			      agp_bridge.capndx + PCI_AGP_STATUS,
+	pci_read_config_dword(agp_bridge->dev,
+			      agp_bridge->capndx + PCI_AGP_STATUS,
 			      &command);
 
 	command = agp_collect_device_status(mode, command);
 	command |= 0x100;
 
-	pci_write_config_dword(agp_bridge.dev,
-			       agp_bridge.capndx + PCI_AGP_COMMAND,
+	pci_write_config_dword(agp_bridge->dev,
+			       agp_bridge->capndx + PCI_AGP_COMMAND,
 			       command);
 
 	agp_device_command(command, 0);
@@ -421,17 +422,17 @@
 	struct page *page;
 
 	/* The generic routines can't handle 2 level gatt's */
-	if (agp_bridge.size_type == LVL2_APER_SIZE)
+	if (agp_bridge->size_type == LVL2_APER_SIZE)
 		return -EINVAL;
 
 	table = NULL;
-	i = agp_bridge.aperture_size_idx;
-	temp = agp_bridge.current_size;
+	i = agp_bridge->aperture_size_idx;
+	temp = agp_bridge->current_size;
 	size = page_order = num_entries = 0;
 
-	if (agp_bridge.size_type != FIXED_APER_SIZE) {
+	if (agp_bridge->size_type != FIXED_APER_SIZE) {
 		do {
-			switch (agp_bridge.size_type) {
+			switch (agp_bridge->size_type) {
 			case U8_APER_SIZE:
 				size = A_SIZE_8(temp)->size;
 				page_order =
@@ -462,15 +463,15 @@
 
 			if (table == NULL) {
 				i++;
-				switch (agp_bridge.size_type) {
+				switch (agp_bridge->size_type) {
 				case U8_APER_SIZE:
-					agp_bridge.current_size = A_IDX8();
+					agp_bridge->current_size = A_IDX8();
 					break;
 				case U16_APER_SIZE:
-					agp_bridge.current_size = A_IDX16();
+					agp_bridge->current_size = A_IDX16();
 					break;
 				case U32_APER_SIZE:
-					agp_bridge.current_size = A_IDX32();
+					agp_bridge->current_size = A_IDX32();
 					break;
 					/* This case will never really 
 					 * happen. 
@@ -478,15 +479,15 @@
 				case FIXED_APER_SIZE:
 				case LVL2_APER_SIZE:
 				default:
-					agp_bridge.current_size =
-					    agp_bridge.current_size;
+					agp_bridge->current_size =
+					    agp_bridge->current_size;
 					break;
 				}
-				temp = agp_bridge.current_size;	
+				temp = agp_bridge->current_size;	
 			} else {
-				agp_bridge.aperture_size_idx = i;
+				agp_bridge->aperture_size_idx = i;
 			}
-		} while ((table == NULL) && (i < agp_bridge.num_aperture_sizes));
+		} while ((table == NULL) && (i < agp_bridge->num_aperture_sizes));
 	} else {
 		size = ((struct aper_size_info_fixed *) temp)->size;
 		page_order = ((struct aper_size_info_fixed *) temp)->page_order;
@@ -502,14 +503,14 @@
 	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
 		SetPageReserved(page);
 
-	agp_bridge.gatt_table_real = (u32 *) table;
+	agp_bridge->gatt_table_real = (u32 *) table;
 	agp_gatt_table = (void *)table; 
 	CACHE_FLUSH();
-	agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table),
+	agp_bridge->gatt_table = ioremap_nocache(virt_to_phys(table),
 					(PAGE_SIZE * (1 << page_order)));
 	CACHE_FLUSH();
 
-	if (agp_bridge.gatt_table == NULL) {
+	if (agp_bridge->gatt_table == NULL) {
 		for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
 			ClearPageReserved(page);
 
@@ -517,11 +518,11 @@
 
 		return -ENOMEM;
 	}
-	agp_bridge.gatt_bus_addr = virt_to_phys(agp_bridge.gatt_table_real);
+	agp_bridge->gatt_bus_addr = virt_to_phys(agp_bridge->gatt_table_real);
 
 	/* AK: bogus, should encode addresses > 4GB */
 	for (i = 0; i < num_entries; i++)
-		agp_bridge.gatt_table[i] = (unsigned long) agp_bridge.scratch_page;
+		agp_bridge->gatt_table[i] = (unsigned long) agp_bridge->scratch_page;
 
 	return 0;
 }
@@ -543,9 +544,9 @@
 	void *temp;
 	struct page *page;
 
-	temp = agp_bridge.current_size;
+	temp = agp_bridge->current_size;
 
-	switch (agp_bridge.size_type) {
+	switch (agp_bridge->size_type) {
 	case U8_APER_SIZE:
 		page_order = A_SIZE_8(temp)->page_order;
 		break;
@@ -572,25 +573,27 @@
 	 * from the table.
 	 */
 
-	iounmap(agp_bridge.gatt_table);
-	table = (char *) agp_bridge.gatt_table_real;
+	iounmap(agp_bridge->gatt_table);
+	table = (char *) agp_bridge->gatt_table_real;
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 
 	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
 		ClearPageReserved(page);
 
-	free_pages((unsigned long) agp_bridge.gatt_table_real, page_order);
+	free_pages((unsigned long) agp_bridge->gatt_table_real, page_order);
 	return 0;
 }
 
 int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type)
 {
-	int i, j, num_entries;
+	int num_entries;
+	size_t i;
+	off_t j;
 	void *temp;
 
-	temp = agp_bridge.current_size;
+	temp = agp_bridge->current_size;
 
-	switch (agp_bridge.size_type) {
+	switch (agp_bridge->size_type) {
 	case U8_APER_SIZE:
 		num_entries = A_SIZE_8(temp)->num_entries;
 		break;
@@ -627,7 +630,7 @@
 	j = pg_start;
 
 	while (j < (pg_start + mem->page_count)) {
-		if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
+		if (!PGE_EMPTY(agp_bridge->gatt_table[j])) {
 			return -EBUSY;
 		}
 		j++;
@@ -639,16 +642,16 @@
 	}
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
-		agp_bridge.gatt_table[j] =
-				agp_bridge.mask_memory(mem->memory[i], mem->type);
+		agp_bridge->gatt_table[j] =
+				agp_bridge->mask_memory(mem->memory[i], mem->type);
 
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 	return 0;
 }
 
 int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type)
 {
-	int i;
+	size_t i;
 
 	if (type != 0 || mem->type != 0) {
 		/* The generic routines know nothing of memory types */
@@ -657,11 +660,11 @@
 
 	/* AK: bogus, should encode addresses > 4GB */
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-		agp_bridge.gatt_table[i] =
-		    (unsigned long) agp_bridge.scratch_page;
+		agp_bridge->gatt_table[i] =
+		    (unsigned long) agp_bridge->scratch_page;
 	}
 
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 	return 0;
 }
 
@@ -700,7 +703,7 @@
 
 	get_page(page);
 	SetPageLocked(page);
-	atomic_inc(&agp_bridge.current_memory_agp);
+	atomic_inc(&agp_bridge->current_memory_agp);
 	return page_address(page);
 }
 
@@ -716,16 +719,16 @@
 	put_page(page);
 	unlock_page(page);
 	free_page((unsigned long)addr);
-	atomic_dec(&agp_bridge.current_memory_agp);
+	atomic_dec(&agp_bridge->current_memory_agp);
 }
 
 /* End Basic Page Allocation Routines */
 
 void agp_enable(u32 mode)
 {
-	if (agp_bridge.type == NOT_SUPPORTED)
+	if (agp_bridge->type == NOT_SUPPORTED)
 		return;
-	agp_bridge.agp_enable(mode);
+	agp_bridge->agp_enable(mode);
 }
 
 EXPORT_SYMBOL(agp_free_memory);
@@ -750,6 +753,9 @@
 EXPORT_SYMBOL(agp_generic_alloc_by_type);
 EXPORT_SYMBOL(agp_generic_free_by_type);
 EXPORT_SYMBOL(global_cache_flush);
+
+EXPORT_SYMBOL(agp_device_command);
+EXPORT_SYMBOL(agp_collect_device_status);
 
 EXPORT_SYMBOL_GPL(agp_num_entries);
 
diff -Nru a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
--- a/drivers/char/agp/hp-agp.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/agp/hp-agp.c	Fri Feb 14 15:53:12 2003
@@ -176,7 +176,7 @@
 
 	size = hp_private.gart_size / MB(1);
 	hp_zx1_sizes[0].size = size;
-	agp_bridge.current_size = (void *) &hp_zx1_sizes[0];
+	agp_bridge->current_size = (void *) &hp_zx1_sizes[0];
 	return size;
 }
 
@@ -184,10 +184,10 @@
 {
 	struct _hp_private *hp = &hp_private;
 
-	agp_bridge.gart_bus_addr = hp->gart_base;
-	agp_bridge.capndx = pci_find_capability(agp_bridge.dev, PCI_CAP_ID_AGP);
-	pci_read_config_dword(agp_bridge.dev,
-		agp_bridge.capndx + PCI_AGP_STATUS, &agp_bridge.mode);
+	agp_bridge->gart_bus_addr = hp->gart_base;
+	agp_bridge->capndx = pci_find_capability(agp_bridge->dev, PCI_CAP_ID_AGP);
+	pci_read_config_dword(agp_bridge->dev,
+		agp_bridge->capndx + PCI_AGP_STATUS, &agp_bridge->mode);
 
 	if (hp->io_pdir_owner) {
 		OUTREG64(hp->registers, HP_ZX1_PDIR_BASE,
@@ -241,7 +241,7 @@
 	}
 
 	for (i = 0; i < hp->gatt_entries; i++) {
-		hp->gatt[i] = (unsigned long) agp_bridge.scratch_page;
+		hp->gatt[i] = (unsigned long) agp_bridge->scratch_page;
 	}
 
 	return 0;
@@ -296,11 +296,11 @@
 		for (k = 0;
 		     k < hp->io_pages_per_kpage;
 		     k++, j++, paddr += hp->io_page_size) {
-			hp->gatt[j] = agp_bridge.mask_memory(paddr, type);
+			hp->gatt[j] = agp_bridge->mask_memory(paddr, type);
 		}
 	}
 
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 	return 0;
 }
 
@@ -316,10 +316,10 @@
 	io_pg_start = hp->io_pages_per_kpage * pg_start;
 	io_pg_count = hp->io_pages_per_kpage * mem->page_count;
 	for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) {
-		hp->gatt[i] = agp_bridge.scratch_page;
+		hp->gatt[i] = agp_bridge->scratch_page;
 	}
 
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 	return 0;
 }
 
@@ -330,39 +330,39 @@
 
 static int __init hp_zx1_setup (struct pci_dev *pdev __attribute__((unused)))
 {
-	agp_bridge.masks = hp_zx1_masks;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.size_type = FIXED_APER_SIZE;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = hp_zx1_configure;
-	agp_bridge.fetch_size = hp_zx1_fetch_size;
-	agp_bridge.cleanup = hp_zx1_cleanup;
-	agp_bridge.tlb_flush = hp_zx1_tlbflush;
-	agp_bridge.mask_memory = hp_zx1_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = hp_zx1_create_gatt_table;
-	agp_bridge.free_gatt_table = hp_zx1_free_gatt_table;
-	agp_bridge.insert_memory = hp_zx1_insert_memory;
-	agp_bridge.remove_memory = hp_zx1_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.cant_use_aperture = 1;
+	agp_bridge->masks = hp_zx1_masks;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->size_type = FIXED_APER_SIZE;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = hp_zx1_configure;
+	agp_bridge->fetch_size = hp_zx1_fetch_size;
+	agp_bridge->cleanup = hp_zx1_cleanup;
+	agp_bridge->tlb_flush = hp_zx1_tlbflush;
+	agp_bridge->mask_memory = hp_zx1_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = hp_zx1_create_gatt_table;
+	agp_bridge->free_gatt_table = hp_zx1_free_gatt_table;
+	agp_bridge->insert_memory = hp_zx1_insert_memory;
+	agp_bridge->remove_memory = hp_zx1_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->cant_use_aperture = 1;
 	return hp_zx1_ioc_init();
 }
 
 static int __init agp_find_supported_device(struct pci_dev *dev)
 {
-	agp_bridge.dev = dev;
+	agp_bridge->dev = dev;
 
 	/* ZX1 LBAs can be either PCI or AGP bridges */
 	if (pci_find_capability(dev, PCI_CAP_ID_AGP)) {
 		printk(KERN_INFO PFX "Detected HP ZX1 AGP chipset at %s\n",
 			dev->slot_name);
-		agp_bridge.type = HP_ZX1;
-		agp_bridge.dev = dev;
+		agp_bridge->type = HP_ZX1;
+		agp_bridge->dev = dev;
 		return hp_zx1_setup(dev);
 	}
 	return -ENODEV;
@@ -408,7 +408,7 @@
 
 	ret_val = pci_module_init(&agp_hp_pci_driver);
 	if (ret_val)
-		agp_bridge.type = NOT_SUPPORTED;
+		agp_bridge->type = NOT_SUPPORTED;
 
 	return ret_val;
 }
diff -Nru a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
--- a/drivers/char/agp/i460-agp.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/char/agp/i460-agp.c	Fri Feb 14 15:53:11 2003
@@ -96,7 +96,7 @@
 	struct aper_size_info_8 *values;
 
 	/* Determine the GART page size */
-	pci_read_config_byte(agp_bridge.dev, INTEL_I460_GXBCTL, &temp);
+	pci_read_config_byte(agp_bridge->dev, INTEL_I460_GXBCTL, &temp);
 	i460.io_page_shift = (temp & I460_4M_PS) ? 22 : 12;
 	pr_debug("i460_fetch_size: io_page_shift=%d\n", i460.io_page_shift);
 
@@ -107,9 +107,9 @@
 		return 0;
 	}
 
-	values = A_SIZE_8(agp_bridge.aperture_sizes);
+	values = A_SIZE_8(agp_bridge->aperture_sizes);
 
-	pci_read_config_byte(agp_bridge.dev, INTEL_I460_AGPSIZ, &temp);
+	pci_read_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ, &temp);
 
 	/* Exit now if the IO drivers for the GART SRAMS are turned off */
 	if (temp & I460_SRAM_IO_DISABLE) {
@@ -130,7 +130,7 @@
 	else
 		i460.dynamic_apbase = INTEL_I460_APBASE;
 
-	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+	for (i = 0; i < agp_bridge->num_aperture_sizes; i++) {
 		/*
 		 * Dynamically calculate the proper num_entries and page_order values for
 		 * the define aperture sizes. Take care not to shift off the end of
@@ -140,11 +140,11 @@
 		values[i].page_order = log2((sizeof(u32)*values[i].num_entries) >> PAGE_SHIFT);
 	}
 
-	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+	for (i = 0; i < agp_bridge->num_aperture_sizes; i++) {
 		/* Neglect control bits when matching up size_value */
 		if ((temp & I460_AGPSIZ_MASK) == values[i].size_value) {
-			agp_bridge.previous_size = agp_bridge.current_size = (void *) (values + i);
-			agp_bridge.aperture_size_idx = i;
+			agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i);
+			agp_bridge->aperture_size_idx = i;
 			return values[i].size;
 		}
 	}
@@ -166,8 +166,8 @@
 {
 	u8 temp;
 
-	pci_read_config_byte(agp_bridge.dev, INTEL_I460_AGPSIZ, &temp);
-	pci_write_config_byte(agp_bridge.dev, INTEL_I460_AGPSIZ,
+	pci_read_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ, &temp);
+	pci_write_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ,
 			      ((temp & ~I460_AGPSIZ_MASK) | size_value));
 }
 
@@ -175,7 +175,7 @@
 {
 	struct aper_size_info_8 *previous_size;
 
-	previous_size = A_SIZE_8(agp_bridge.previous_size);
+	previous_size = A_SIZE_8(agp_bridge->previous_size);
 	i460_write_agpsiz(previous_size->size_value);
 
 	if (I460_IO_PAGE_SHIFT > PAGE_SHIFT)
@@ -194,7 +194,7 @@
 
 	temp.large = 0;
 
-	current_size = A_SIZE_8(agp_bridge.current_size);
+	current_size = A_SIZE_8(agp_bridge->current_size);
 	i460_write_agpsiz(current_size->size_value);
 
 	/*
@@ -202,14 +202,14 @@
 	 * This has to be done since the AGP aperture can be above 4GB on
 	 * 460 based systems.
 	 */
-	pci_read_config_dword(agp_bridge.dev, i460.dynamic_apbase, &(temp.small[0]));
-	pci_read_config_dword(agp_bridge.dev, i460.dynamic_apbase + 4, &(temp.small[1]));
+	pci_read_config_dword(agp_bridge->dev, i460.dynamic_apbase, &(temp.small[0]));
+	pci_read_config_dword(agp_bridge->dev, i460.dynamic_apbase + 4, &(temp.small[1]));
 
 	/* Clear BAR control bits */
-	agp_bridge.gart_bus_addr = temp.large & ~((1UL << 3) - 1);
+	agp_bridge->gart_bus_addr = temp.large & ~((1UL << 3) - 1);
 
-	pci_read_config_byte(agp_bridge.dev, INTEL_I460_GXBCTL, &scratch);
-	pci_write_config_byte(agp_bridge.dev, INTEL_I460_GXBCTL,
+	pci_read_config_byte(agp_bridge->dev, INTEL_I460_GXBCTL, &scratch);
+	pci_write_config_byte(agp_bridge->dev, INTEL_I460_GXBCTL,
 			      (scratch & 0x02) | I460_GXBCTL_OOG | I460_GXBCTL_BWC);
 
 	/*
@@ -234,16 +234,16 @@
 	/*
 	 * Load up the fixed address of the GART SRAMS which hold our GATT table.
 	 */
-	temp = agp_bridge.current_size;
+	temp = agp_bridge->current_size;
 	page_order = A_SIZE_8(temp)->page_order;
 	num_entries = A_SIZE_8(temp)->num_entries;
 
 	i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order);
 
 	/* These are no good, the should be removed from the agp_bridge strucure... */
-	agp_bridge.gatt_table_real = NULL;
-	agp_bridge.gatt_table = NULL;
-	agp_bridge.gatt_bus_addr = 0;
+	agp_bridge->gatt_table_real = NULL;
+	agp_bridge->gatt_table = NULL;
+	agp_bridge->gatt_bus_addr = 0;
 
 	for (i = 0; i < num_entries; ++i)
 		WR_GATT(i, 0);
@@ -256,7 +256,7 @@
 	int num_entries, i;
 	void *temp;
 
-	temp = agp_bridge.current_size;
+	temp = agp_bridge->current_size;
 
 	num_entries = A_SIZE_8(temp)->num_entries;
 
@@ -284,7 +284,7 @@
 
 	io_pg_start = I460_IOPAGES_PER_KPAGE * pg_start;
 
-	temp = agp_bridge.current_size;
+	temp = agp_bridge->current_size;
 	num_entries = A_SIZE_8(temp)->num_entries;
 
 	if ((io_pg_start + I460_IOPAGES_PER_KPAGE * mem->page_count) > num_entries) {
@@ -306,7 +306,7 @@
 	for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
 		paddr = mem->memory[i];
 		for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size)
-			WR_GATT(j, agp_bridge.mask_memory(paddr, mem->type));
+			WR_GATT(j, agp_bridge->mask_memory(paddr, mem->type));
 	}
 	WR_FLUSH_GATT(j - 1);
 	return 0;
@@ -364,7 +364,7 @@
 
 	lp->paddr = virt_to_phys(lpage);
 	lp->refcount = 0;
-	atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge.current_memory_agp);
+	atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
 	return 0;
 }
 
@@ -374,7 +374,7 @@
 	lp->alloced_map = NULL;
 
 	free_pages((unsigned long) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT);
-	atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge.current_memory_agp);
+	atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
 }
 
 static int i460_insert_memory_large_io_page (agp_memory * mem, off_t pg_start, int type)
@@ -383,7 +383,7 @@
 	struct lp_desc *start, *end, *lp;
 	void *temp;
 
-	temp = agp_bridge.current_size;
+	temp = agp_bridge->current_size;
 	num_entries = A_SIZE_8(temp)->num_entries;
 
 	/* Figure out what pg_start means in terms of our large GART pages */
@@ -417,7 +417,7 @@
 			if (i460_alloc_large_page(lp) < 0)
 				return -ENOMEM;
 			pg = lp - i460.lp_desc;
-			WR_GATT(pg, agp_bridge.mask_memory(lp->paddr, 0));
+			WR_GATT(pg, agp_bridge->mask_memory(lp->paddr, 0));
 			WR_FLUSH_GATT(pg);
 		}
 
@@ -439,7 +439,7 @@
 	struct lp_desc *start, *end, *lp;
 	void *temp;
 
-	temp = agp_bridge.current_size;
+	temp = agp_bridge->current_size;
 	num_entries = A_SIZE_8(temp)->num_entries;
 
 	/* Figure out what pg_start means in terms of our large GART pages */
@@ -519,43 +519,43 @@
 static unsigned long i460_mask_memory (unsigned long addr, int type)
 {
 	/* Make sure the returned address is a valid GATT entry */
-	return (agp_bridge.masks[0].mask
+	return (agp_bridge->masks[0].mask
 		| (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12));
 }
 
 static int __init intel_i460_setup (struct pci_dev *pdev __attribute__((unused)))
 {
-	agp_bridge.masks = i460_masks;
-	agp_bridge.aperture_sizes = (void *) i460_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 3;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = i460_configure;
-	agp_bridge.fetch_size = i460_fetch_size;
-	agp_bridge.cleanup = i460_cleanup;
-	agp_bridge.tlb_flush = i460_tlb_flush;
-	agp_bridge.mask_memory = i460_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = i460_create_gatt_table;
-	agp_bridge.free_gatt_table = i460_free_gatt_table;
+	agp_bridge->masks = i460_masks;
+	agp_bridge->aperture_sizes = (void *) i460_sizes;
+	agp_bridge->size_type = U8_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 3;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = i460_configure;
+	agp_bridge->fetch_size = i460_fetch_size;
+	agp_bridge->cleanup = i460_cleanup;
+	agp_bridge->tlb_flush = i460_tlb_flush;
+	agp_bridge->mask_memory = i460_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = i460_create_gatt_table;
+	agp_bridge->free_gatt_table = i460_free_gatt_table;
 #if I460_LARGE_IO_PAGES
-	agp_bridge.insert_memory = i460_insert_memory;
-	agp_bridge.remove_memory = i460_remove_memory;
-	agp_bridge.agp_alloc_page = i460_alloc_page;
-	agp_bridge.agp_destroy_page = i460_destroy_page;
+	agp_bridge->insert_memory = i460_insert_memory;
+	agp_bridge->remove_memory = i460_remove_memory;
+	agp_bridge->agp_alloc_page = i460_alloc_page;
+	agp_bridge->agp_destroy_page = i460_destroy_page;
 #else
-	agp_bridge.insert_memory = i460_insert_memory_small_io_page;
-	agp_bridge.remove_memory = i460_remove_memory_small_io_page;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->insert_memory = i460_insert_memory_small_io_page;
+	agp_bridge->remove_memory = i460_remove_memory_small_io_page;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
 #endif
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 1;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 1;
 	return 0;
 }
 
@@ -571,8 +571,8 @@
 	if (cap_ptr == 0)
 		return -ENODEV;
 
-	agp_bridge.dev = dev;
-	agp_bridge.capndx = cap_ptr;
+	agp_bridge->dev = dev;
+	agp_bridge->capndx = cap_ptr;
 	intel_i460_setup(dev);
 	i460_agp_driver.dev = dev;
 	agp_register_driver(&i460_agp_driver);
@@ -605,7 +605,7 @@
 
 	ret_val = pci_module_init(&agp_intel_i460_pci_driver);
 	if (ret_val)
-		agp_bridge.type = NOT_SUPPORTED;
+		agp_bridge->type = NOT_SUPPORTED;
 
 	return ret_val;
 }
diff -Nru a/drivers/char/agp/i7x05-agp.c b/drivers/char/agp/i7x05-agp.c
--- a/drivers/char/agp/i7x05-agp.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/char/agp/i7x05-agp.c	Fri Feb 14 15:53:08 2003
@@ -13,16 +13,16 @@
 	/* 
 	 * For AGP 3.0 APSIZE is now 16 bits
 	 */
-	pci_read_config_word (agp_bridge.dev, INTEL_I7505_APSIZE, &tmp);
+	pci_read_config_word (agp_bridge->dev, INTEL_I7505_APSIZE, &tmp);
 	tmp = (tmp & 0xfff);
 	
-	values = A_SIZE_16(agp_bridge.aperture_sizes);
+	values = A_SIZE_16(agp_bridge->aperture_sizes);
 
-	for (i=0; i < agp_bridge.num_aperture_sizes; i++) {
+	for (i=0; i < agp_bridge->num_aperture_sizes; i++) {
 		if (tmp == values[i].size_value) {
-			agp_bridge.previous_size = agp_bridge.current_size =
+			agp_bridge->previous_size = agp_bridge->current_size =
 					(void *)(values + i);
-			agp_bridge.aperture_size_idx = i;
+			agp_bridge->aperture_size_idx = i;
 			return values[i].size;
 		}
 	}
@@ -33,18 +33,18 @@
 static void intel_7505_tlbflush(agp_memory *mem)
 {
 	u32 temp;
-	pci_read_config_dword(agp_bridge.dev, INTEL_I7505_AGPCTRL, &temp);
-	pci_write_config_dword(agp_bridge.dev, INTEL_I7505_AGPCTRL, temp & ~(1 << 7));
-	pci_read_config_dword(agp_bridge.dev, INTEL_I7505_AGPCTRL, &temp);
-	pci_write_config_dword(agp_bridge.dev, INTEL_I7505_AGPCTRL, temp | (1 << 7));
+	pci_read_config_dword(agp_bridge->dev, INTEL_I7505_AGPCTRL, &temp);
+	pci_write_config_dword(agp_bridge->dev, INTEL_I7505_AGPCTRL, temp & ~(1 << 7));
+	pci_read_config_dword(agp_bridge->dev, INTEL_I7505_AGPCTRL, &temp);
+	pci_write_config_dword(agp_bridge->dev, INTEL_I7505_AGPCTRL, temp | (1 << 7));
 }
 
 static void intel_7505_cleanup(void)
 {
 	aper_size_info_16 *previous_size;
 
-	previous_size = A_SIZE_16(agp_bridge.previous_size);
-	pci_write_config_byte(agp_bridge.dev, INTEL_I7505_APSIZE,
+	previous_size = A_SIZE_16(agp_bridge->previous_size);
+	pci_write_config_byte(agp_bridge->dev, INTEL_I7505_APSIZE,
 			      previous_size->size_value);
 }
 
@@ -54,25 +54,25 @@
 	u32 temp;
 	aper_size_info_16 *current_size;
 	
-	current_size = A_SIZE_16(agp_bridge.current_size);
+	current_size = A_SIZE_16(agp_bridge->current_size);
 
 	/* aperture size */
-	pci_write_config_word(agp_bridge.dev, INTEL_I7505_APSIZE,
+	pci_write_config_word(agp_bridge->dev, INTEL_I7505_APSIZE,
 			      current_size->size_value);
 
 	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_I7505_NAPBASELO, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_read_config_dword(agp_bridge->dev, INTEL_I7505_NAPBASELO, &temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 	/* attbase */ 
-	pci_write_config_dword(agp_bridge.dev, INTEL_I7505_ATTBASE,
-			       agp_bridge.gatt_bus_addr);
+	pci_write_config_dword(agp_bridge->dev, INTEL_I7505_ATTBASE,
+			       agp_bridge->gatt_bus_addr);
 
 	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_I7505_AGPCTRL, 0x0000);
+	pci_write_config_dword(agp_bridge->dev, INTEL_I7505_AGPCTRL, 0x0000);
 
 	/* clear error registers */
-	pci_write_config_byte(agp_bridge.dev, INTEL_I7505_ERRSTS, 0xff);
+	pci_write_config_byte(agp_bridge->dev, INTEL_I7505_ERRSTS, 0xff);
 	return 0;
 }
 
@@ -95,30 +95,30 @@
 
 static int __init intel_7505_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.aperture_sizes = (void *) intel_7505_sizes;
-	agp_bridge.size_type = U16_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_7505_configure;
-	agp_bridge.fetch_size = intel_7505_fetch_size;
-	agp_bridge.cleanup = intel_7505_cleanup;
-	agp_bridge.tlb_flush = intel_7505_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = i7505_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = intel_generic_masks;
+	agp_bridge->aperture_sizes = (void *) intel_7505_sizes;
+	agp_bridge->size_type = U16_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 7;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = intel_7505_configure;
+	agp_bridge->fetch_size = intel_7505_fetch_size;
+	agp_bridge->cleanup = intel_7505_cleanup;
+	agp_bridge->tlb_flush = intel_7505_tlbflush;
+	agp_bridge->mask_memory = intel_mask_memory;
+	agp_bridge->agp_enable = i7505_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = agp_generic_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 	return 0;
 }
 
@@ -149,7 +149,7 @@
 		if (pdev->device == devs[j].device_id) {
 			printk (KERN_INFO PFX "Detected Intel %s chipset\n",
 				devs[j].chipset_name);
-			agp_bridge.type = devs[j].chipset;
+			agp_bridge->type = devs[j].chipset;
 
 			if (devs[j].chipset_setup != NULL)
 				return devs[j].chipset_setup(pdev);
@@ -177,10 +177,10 @@
 		return -ENODEV;
 
 	if (agp_lookup_host_bridge(dev) != -ENODEV) {
-		agp_bridge.dev = dev;
-		agp_bridge.capndx = cap_ptr;
+		agp_bridge->dev = dev;
+		agp_bridge->capndx = cap_ptr;
 		/* Fill in the mode register */
-		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode)
+		pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode)
 		i7x05_agp_driver.dev = dev;
 		agp_register_driver(&i7x05_agp_driver);
 		return 0;
@@ -215,7 +215,7 @@
 
 	ret_val = pci_module_init(&agp_i7x05_pci_driver);
 	if (ret_val)
-		agp_bridge.type = NOT_SUPPORTED;
+		agp_bridge->type = NOT_SUPPORTED;
 
 	return ret_val;
 }
diff -Nru a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
--- a/drivers/char/agp/intel-agp.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/agp/intel-agp.c	Fri Feb 14 15:53:09 2003
@@ -39,22 +39,22 @@
 	u32 smram_miscc;
 	struct aper_size_info_fixed *values;
 
-	pci_read_config_dword(agp_bridge.dev, I810_SMRAM_MISCC, &smram_miscc);
-	values = A_SIZE_FIX(agp_bridge.aperture_sizes);
+	pci_read_config_dword(agp_bridge->dev, I810_SMRAM_MISCC, &smram_miscc);
+	values = A_SIZE_FIX(agp_bridge->aperture_sizes);
 
 	if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) {
 		printk(KERN_WARNING PFX "i810 is disabled\n");
 		return 0;
 	}
 	if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) {
-		agp_bridge.previous_size =
-			agp_bridge.current_size = (void *) (values + 1);
-		agp_bridge.aperture_size_idx = 1;
+		agp_bridge->previous_size =
+			agp_bridge->current_size = (void *) (values + 1);
+		agp_bridge->aperture_size_idx = 1;
 		return values[1].size;
 	} else {
-		agp_bridge.previous_size =
-			agp_bridge.current_size = (void *) (values);
-		agp_bridge.aperture_size_idx = 0;
+		agp_bridge->previous_size =
+			agp_bridge->current_size = (void *) (values);
+		agp_bridge->aperture_size_idx = 0;
 		return values[0].size;
 	}
 
@@ -67,7 +67,7 @@
 	u32 temp;
 	int i;
 
-	current_size = A_SIZE_FIX(agp_bridge.current_size);
+	current_size = A_SIZE_FIX(agp_bridge->current_size);
 
 	pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
 	temp &= 0xfff80000;
@@ -81,16 +81,16 @@
 		intel_i810_private.num_dcache_entries = 1024;
 	}
 	pci_read_config_dword(intel_i810_private.i810_dev, I810_GMADDR, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 	OUTREG32(intel_i810_private.registers, I810_PGETBL_CTL,
-		 agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED);
+		 agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED);
 	CACHE_FLUSH();
 
-	if (agp_bridge.needs_scratch_page == TRUE) {
+	if (agp_bridge->needs_scratch_page == TRUE) {
 		for (i = 0; i < current_size->num_entries; i++) {
 			OUTREG32(intel_i810_private.registers,
 				 I810_PTE_BASE + (i * 4),
-				 agp_bridge.scratch_page);
+				 agp_bridge->scratch_page);
 		}
 	}
 	return 0;
@@ -118,14 +118,14 @@
 	int i, j, num_entries;
 	void *temp;
 
-	temp = agp_bridge.current_size;
+	temp = agp_bridge->current_size;
 	num_entries = A_SIZE_FIX(temp)->num_entries;
 
 	if ((pg_start + mem->page_count) > num_entries) {
 		return -EINVAL;
 	}
 	for (j = pg_start; j < (pg_start + mem->page_count); j++) {
-		if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
+		if (!PGE_EMPTY(agp_bridge->gatt_table[j])) {
 			return -EBUSY;
 		}
 	}
@@ -141,7 +141,7 @@
 					 I810_PTE_VALID);
 			}
 			CACHE_FLUSH();
-			agp_bridge.tlb_flush(mem);
+			agp_bridge->tlb_flush(mem);
 			return 0;
 		}
 		if((type == AGP_PHYS_MEMORY) && (mem->type == AGP_PHYS_MEMORY))
@@ -154,11 +154,11 @@
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		OUTREG32(intel_i810_private.registers,
 			I810_PTE_BASE + (j * 4),
-			agp_bridge.mask_memory(mem->memory[i], mem->type));
+			agp_bridge->mask_memory(mem->memory[i], mem->type));
 	}
 	CACHE_FLUSH();
 
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 	return 0;
 }
 
@@ -170,11 +170,11 @@
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
 		OUTREG32(intel_i810_private.registers,
 			 I810_PTE_BASE + (i * 4),
-			 agp_bridge.scratch_page);
+			 agp_bridge->scratch_page);
 	}
 
 	CACHE_FLUSH();
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 	return 0;
 }
 
@@ -211,7 +211,7 @@
 		if (new == NULL)
 			return NULL;
 
-		addr = agp_bridge.agp_alloc_page();
+		addr = agp_bridge->agp_alloc_page();
 
 		if (addr == NULL) {
 			/* Free this structure */
@@ -232,7 +232,7 @@
 {
 	agp_free_key(curr->key);
 	if(curr->type == AGP_PHYS_MEMORY) {
-		agp_bridge.agp_destroy_page(phys_to_virt(curr->memory[0]));
+		agp_bridge->agp_destroy_page(phys_to_virt(curr->memory[0]));
 		vfree(curr->memory);
 	}
 	kfree(curr);
@@ -241,37 +241,37 @@
 static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
 {
 	/* Type checking must be done elsewhere */
-	return addr | agp_bridge.masks[type].mask;
+	return addr | agp_bridge->masks[type].mask;
 }
 
 static int __init intel_i810_setup(struct pci_dev *i810_dev)
 {
 	intel_i810_private.i810_dev = i810_dev;
 
-	agp_bridge.masks = intel_i810_masks;
-	agp_bridge.aperture_sizes = (void *) intel_i810_sizes;
-	agp_bridge.size_type = FIXED_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 2;
-	agp_bridge.dev_private_data = (void *) &intel_i810_private;
-	agp_bridge.needs_scratch_page = TRUE;
-	agp_bridge.configure = intel_i810_configure;
-	agp_bridge.fetch_size = intel_i810_fetch_size;
-	agp_bridge.cleanup = intel_i810_cleanup;
-	agp_bridge.tlb_flush = intel_i810_tlbflush;
-	agp_bridge.mask_memory = intel_i810_mask_memory;
-	agp_bridge.agp_enable = intel_i810_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = intel_i810_insert_entries;
-	agp_bridge.remove_memory = intel_i810_remove_entries;
-	agp_bridge.alloc_by_type = intel_i810_alloc_by_type;
-	agp_bridge.free_by_type = intel_i810_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = intel_i810_masks;
+	agp_bridge->aperture_sizes = (void *) intel_i810_sizes;
+	agp_bridge->size_type = FIXED_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 2;
+	agp_bridge->dev_private_data = (void *) &intel_i810_private;
+	agp_bridge->needs_scratch_page = TRUE;
+	agp_bridge->configure = intel_i810_configure;
+	agp_bridge->fetch_size = intel_i810_fetch_size;
+	agp_bridge->cleanup = intel_i810_cleanup;
+	agp_bridge->tlb_flush = intel_i810_tlbflush;
+	agp_bridge->mask_memory = intel_i810_mask_memory;
+	agp_bridge->agp_enable = intel_i810_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = intel_i810_insert_entries;
+	agp_bridge->remove_memory = intel_i810_remove_entries;
+	agp_bridge->alloc_by_type = intel_i810_alloc_by_type;
+	agp_bridge->free_by_type = intel_i810_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 
 	return 0;
 }
@@ -296,7 +296,7 @@
 	u8 rdct;
 	static const int ddt[4] = { 0, 16, 32, 64 };
 
-	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
+	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
 
 	switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
 	case I830_GMCH_GMS_STOLEN_512:
@@ -337,10 +337,10 @@
 	int num_entries;
 	u32 temp;
 
-	size = agp_bridge.current_size;
+	size = agp_bridge->current_size;
 	page_order = size->page_order;
 	num_entries = size->num_entries;
-	agp_bridge.gatt_table_real = 0;
+	agp_bridge->gatt_table_real = 0;
 
 	pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
 	temp &= 0xfff80000;
@@ -354,9 +354,9 @@
 	/* we have to call this as early as possible after the MMIO base address is known */
 	intel_i830_init_gtt_entries();
 
-	agp_bridge.gatt_table = NULL;
+	agp_bridge->gatt_table = NULL;
 
-	agp_bridge.gatt_bus_addr = temp;
+	agp_bridge->gatt_bus_addr = temp;
 
 	return(0);
 }
@@ -374,16 +374,16 @@
 	u16 gmch_ctrl;
 	struct aper_size_info_fixed *values;
 
-	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
-	values = A_SIZE_FIX(agp_bridge.aperture_sizes);
+	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
+	values = A_SIZE_FIX(agp_bridge->aperture_sizes);
 
 	if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
-		agp_bridge.previous_size = agp_bridge.current_size = (void *) values;
-		agp_bridge.aperture_size_idx = 0;
+		agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
+		agp_bridge->aperture_size_idx = 0;
 		return(values[0].size);
 	} else {
-		agp_bridge.previous_size = agp_bridge.current_size = (void *) values;
-		agp_bridge.aperture_size_idx = 1;
+		agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
+		agp_bridge->aperture_size_idx = 1;
 		return(values[1].size);
 	}
 
@@ -397,21 +397,21 @@
 	u16 gmch_ctrl;
 	int i;
 
-	current_size = A_SIZE_FIX(agp_bridge.current_size);
+	current_size = A_SIZE_FIX(agp_bridge->current_size);
 
 	pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
-	pci_read_config_word(agp_bridge.dev,I830_GMCH_CTRL,&gmch_ctrl);
+	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
 	gmch_ctrl |= I830_GMCH_ENABLED;
-	pci_write_config_word(agp_bridge.dev,I830_GMCH_CTRL,gmch_ctrl);
+	pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
 
-	OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge.gatt_bus_addr | I810_PGETBL_ENABLED);
+	OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED);
 	CACHE_FLUSH();
 
-	if (agp_bridge.needs_scratch_page == TRUE)
+	if (agp_bridge->needs_scratch_page == TRUE)
 		for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
-			OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
+			OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page);
 
 	return (0);
 }
@@ -426,7 +426,7 @@
 	int i,j,num_entries;
 	void *temp;
 
-	temp = agp_bridge.current_size;
+	temp = agp_bridge->current_size;
 	num_entries = A_SIZE_FIX(temp)->num_entries;
 
 	if (pg_start < intel_i830_private.gtt_entries) {
@@ -452,11 +452,11 @@
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
 		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4),
-			agp_bridge.mask_memory(mem->memory[i], mem->type));
+			agp_bridge->mask_memory(mem->memory[i], mem->type));
 
 	CACHE_FLUSH();
 
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 
 	return(0);
 }
@@ -473,11 +473,11 @@
 	}
 
 	for (i = pg_start; i < (mem->page_count + pg_start); i++)
-		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge.scratch_page);
+		OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page);
 
 	CACHE_FLUSH();
 
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 
 	return (0);
 }
@@ -504,7 +504,7 @@
 
 		if (nw == NULL) return(NULL);
 
-		addr = agp_bridge.agp_alloc_page();
+		addr = agp_bridge->agp_alloc_page();
 		if (addr == NULL) {
 			/* free this structure */
 			agp_free_memory(nw);
@@ -526,35 +526,35 @@
 {
 	intel_i830_private.i830_dev = i830_dev;
 
-	agp_bridge.masks = intel_i810_masks;
-	agp_bridge.aperture_sizes = (void *) intel_i830_sizes;
-	agp_bridge.size_type = FIXED_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 2;
-
-	agp_bridge.dev_private_data = (void *) &intel_i830_private;
-	agp_bridge.needs_scratch_page = TRUE;
-
-	agp_bridge.configure = intel_i830_configure;
-	agp_bridge.fetch_size = intel_i830_fetch_size;
-	agp_bridge.cleanup = intel_i830_cleanup;
-	agp_bridge.tlb_flush = intel_i810_tlbflush;
-	agp_bridge.mask_memory = intel_i810_mask_memory;
-	agp_bridge.agp_enable = intel_i810_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-
-	agp_bridge.create_gatt_table = intel_i830_create_gatt_table;
-	agp_bridge.free_gatt_table = intel_i830_free_gatt_table;
-
-	agp_bridge.insert_memory = intel_i830_insert_entries;
-	agp_bridge.remove_memory = intel_i830_remove_entries;
-	agp_bridge.alloc_by_type = intel_i830_alloc_by_type;
-	agp_bridge.free_by_type = intel_i810_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = intel_i810_masks;
+	agp_bridge->aperture_sizes = (void *) intel_i830_sizes;
+	agp_bridge->size_type = FIXED_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 2;
+
+	agp_bridge->dev_private_data = (void *) &intel_i830_private;
+	agp_bridge->needs_scratch_page = TRUE;
+
+	agp_bridge->configure = intel_i830_configure;
+	agp_bridge->fetch_size = intel_i830_fetch_size;
+	agp_bridge->cleanup = intel_i830_cleanup;
+	agp_bridge->tlb_flush = intel_i810_tlbflush;
+	agp_bridge->mask_memory = intel_i810_mask_memory;
+	agp_bridge->agp_enable = intel_i810_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+
+	agp_bridge->create_gatt_table = intel_i830_create_gatt_table;
+	agp_bridge->free_gatt_table = intel_i830_free_gatt_table;
+
+	agp_bridge->insert_memory = intel_i830_insert_entries;
+	agp_bridge->remove_memory = intel_i830_remove_entries;
+	agp_bridge->alloc_by_type = intel_i830_alloc_by_type;
+	agp_bridge->free_by_type = intel_i810_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 
 	return(0);
 }
@@ -564,13 +564,13 @@
 	u16 temp;
 	struct aper_size_info_16 *values;
 
-	pci_read_config_word(agp_bridge.dev, INTEL_APSIZE, &temp);
-	values = A_SIZE_16(agp_bridge.aperture_sizes);
+	pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp);
+	values = A_SIZE_16(agp_bridge->aperture_sizes);
 
-	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+	for (i = 0; i < agp_bridge->num_aperture_sizes; i++) {
 		if (temp == values[i].size_value) {
-			agp_bridge.previous_size = agp_bridge.current_size = (void *) (values + i);
-			agp_bridge.aperture_size_idx = i;
+			agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i);
+			agp_bridge->aperture_size_idx = i;
 			return values[i].size;
 		}
 	}
@@ -584,20 +584,20 @@
 	u8 temp;
 	struct aper_size_info_8 *values;
 
-	pci_read_config_byte(agp_bridge.dev, INTEL_APSIZE, &temp);
+	pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
 
 	/* Intel 815 chipsets have a _weird_ APSIZE register with only
 	 * one non-reserved bit, so mask the others out ... */
-	if (agp_bridge.type == INTEL_I815)
+	if (agp_bridge->type == INTEL_I815)
 		temp &= (1 << 3);
 
-	values = A_SIZE_8(agp_bridge.aperture_sizes);
+	values = A_SIZE_8(agp_bridge->aperture_sizes);
 
-	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+	for (i = 0; i < agp_bridge->num_aperture_sizes; i++) {
 		if (temp == values[i].size_value) {
-			agp_bridge.previous_size =
-				agp_bridge.current_size = (void *) (values + i);
-			agp_bridge.aperture_size_idx = i;
+			agp_bridge->previous_size =
+				agp_bridge->current_size = (void *) (values + i);
+			agp_bridge->aperture_size_idx = i;
 			return values[i].size;
 		}
 	}
@@ -607,18 +607,18 @@
 
 static void intel_tlbflush(agp_memory * mem)
 {
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2200);
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
+	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2200);
+	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
 }
 
 
 static void intel_8xx_tlbflush(agp_memory * mem)
 {
 	u32 temp;
-	pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp);
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp & ~(1 << 7));
-	pci_read_config_dword(agp_bridge.dev, INTEL_AGPCTRL, &temp);
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, temp | (1 << 7));
+	pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
+	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp & ~(1 << 7));
+	pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
+	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp | (1 << 7));
 }
 
 
@@ -627,10 +627,10 @@
 	u16 temp;
 	struct aper_size_info_16 *previous_size;
 
-	previous_size = A_SIZE_16(agp_bridge.previous_size);
-	pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp);
-	pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9));
-	pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, previous_size->size_value);
+	previous_size = A_SIZE_16(agp_bridge->previous_size);
+	pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
+	pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
+	pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
 }
 
 
@@ -639,10 +639,10 @@
 	u16 temp;
 	struct aper_size_info_8 *previous_size;
 
-	previous_size = A_SIZE_8(agp_bridge.previous_size);
-	pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp);
-	pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp & ~(1 << 9));
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, previous_size->size_value);
+	previous_size = A_SIZE_8(agp_bridge->previous_size);
+	pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
+	pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
+	pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
 }
 
 
@@ -652,27 +652,27 @@
 	u16 temp2;
 	struct aper_size_info_16 *current_size;
 
-	current_size = A_SIZE_16(agp_bridge.current_size);
+	current_size = A_SIZE_16(agp_bridge->current_size);
 
 	/* aperture size */
-	pci_write_config_word(agp_bridge.dev, INTEL_APSIZE, current_size->size_value);
+	pci_write_config_word(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 
 	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr);
+	pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
 
 	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x2280);
+	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
 
 	/* paccfg/nbxcfg */
-	pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2);
-	pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG,
+	pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
+	pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG,
 			(temp2 & ~(1 << 10)) | (1 << 9));
 	/* clear any possible error conditions */
-	pci_write_config_byte(agp_bridge.dev, INTEL_ERRSTS + 1, 7);
+	pci_write_config_byte(agp_bridge->dev, INTEL_ERRSTS + 1, 7);
 	return 0;
 }
 
@@ -682,32 +682,35 @@
 	u8 temp2;
 	struct aper_size_info_8 *current_size;
 
-	current_size = A_SIZE_8(agp_bridge.current_size);
+	/* attbase - aperture base */
+	/* the Intel 815 chipset spec. says that bits 29-31 in the
+	* ATTBASE register are reserved -> try not to write them */
+	if (agp_bridge->gatt_bus_addr & INTEL_815_ATTBASE_MASK) {
+		printk (KERN_EMERG "gatt bus addr too high");
+		return -EINVAL;
+	}
+
+	current_size = A_SIZE_8(agp_bridge->current_size);
 
 	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
+	pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
 			current_size->size_value); 
 
 	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
-	/* attbase - aperture base */
-	/* the Intel 815 chipset spec. says that bits 29-31 in the
-	* ATTBASE register are reserved -> try not to write them */
-	if (agp_bridge.gatt_bus_addr & INTEL_815_ATTBASE_MASK)
-		panic("gatt bus addr too high");
-	pci_read_config_dword(agp_bridge.dev, INTEL_ATTBASE, &addr);
+	pci_read_config_dword(agp_bridge->dev, INTEL_ATTBASE, &addr);
 	addr &= INTEL_815_ATTBASE_MASK;
-	addr |= agp_bridge.gatt_bus_addr;
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, addr);
+	addr |= agp_bridge->gatt_bus_addr;
+	pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, addr);
 
 	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
+	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000); 
 
 	/* apcont */
-	pci_read_config_byte(agp_bridge.dev, INTEL_815_APCONT, &temp2);
-	pci_write_config_byte(agp_bridge.dev, INTEL_815_APCONT, temp2 | (1 << 1));
+	pci_read_config_byte(agp_bridge->dev, INTEL_815_APCONT, &temp2);
+	pci_write_config_byte(agp_bridge->dev, INTEL_815_APCONT, temp2 | (1 << 1));
 
 	/* clear any possible error conditions */
 	/* Oddness : this chipset seems to have no ERRSTS register ! */
@@ -724,11 +727,11 @@
 	u8 temp;
 	struct aper_size_info_8 *previous_size;
 
-	previous_size = A_SIZE_8(agp_bridge.previous_size);
-	pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp);
-	pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR, 
+	previous_size = A_SIZE_8(agp_bridge->previous_size);
+	pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp);
+	pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR, 
 			temp & ~(1 << 1));
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE,
+	pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE,
 			previous_size->size_value);
 }
 
@@ -739,28 +742,28 @@
  	u8 temp2; 
 	struct aper_size_info_8 *current_size;
 
-	current_size = A_SIZE_8(agp_bridge.current_size);
+	current_size = A_SIZE_8(agp_bridge->current_size);
 
 	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); 
+	pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); 
 
 	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); 
+	pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); 
 
 	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
+	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000); 
 
 	/* global enable aperture access */
 	/* This flag is not accessed through MCHCFG register as in */
 	/* i850 chipset. */
-	pci_read_config_byte(agp_bridge.dev, INTEL_I820_RDCR, &temp2);
-	pci_write_config_byte(agp_bridge.dev, INTEL_I820_RDCR, temp2 | (1 << 1));
+	pci_read_config_byte(agp_bridge->dev, INTEL_I820_RDCR, &temp2);
+	pci_write_config_byte(agp_bridge->dev, INTEL_I820_RDCR, temp2 | (1 << 1));
 	/* clear any possible AGP-related error conditions */
-	pci_write_config_word(agp_bridge.dev, INTEL_I820_ERRSTS, 0x001c); 
+	pci_write_config_word(agp_bridge->dev, INTEL_I820_ERRSTS, 0x001c); 
 	return 0;
 }
 
@@ -770,26 +773,26 @@
 	u16 temp2;
 	struct aper_size_info_8 *current_size;
 
-	current_size = A_SIZE_8(agp_bridge.current_size);
+	current_size = A_SIZE_8(agp_bridge->current_size);
 
 	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); 
+	pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); 
 
 	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); 
+	pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); 
 
 	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
+	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000); 
 
 	/* mcgcfg */
-	pci_read_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, &temp2);
-	pci_write_config_word(agp_bridge.dev, INTEL_I840_MCHCFG, temp2 | (1 << 9));
+	pci_read_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, &temp2);
+	pci_write_config_word(agp_bridge->dev, INTEL_I840_MCHCFG, temp2 | (1 << 9));
 	/* clear any possible error conditions */
-	pci_write_config_word(agp_bridge.dev, INTEL_I840_ERRSTS, 0xc000); 
+	pci_write_config_word(agp_bridge->dev, INTEL_I840_ERRSTS, 0xc000); 
 	return 0;
 }
 
@@ -799,26 +802,26 @@
 	u8 temp2;
 	struct aper_size_info_8 *current_size;
 
-	current_size = A_SIZE_8(agp_bridge.current_size);
+	current_size = A_SIZE_8(agp_bridge->current_size);
 
 	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); 
+	pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); 
 
 	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); 
+	pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); 
 
 	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
+	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000); 
 
 	/* agpm */
-	pci_read_config_byte(agp_bridge.dev, INTEL_I845_AGPM, &temp2);
-	pci_write_config_byte(agp_bridge.dev, INTEL_I845_AGPM, temp2 | (1 << 1));
+	pci_read_config_byte(agp_bridge->dev, INTEL_I845_AGPM, &temp2);
+	pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
 	/* clear any possible error conditions */
-	pci_write_config_word(agp_bridge.dev, INTEL_I845_ERRSTS, 0x001c); 
+	pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c); 
 	return 0;
 }
 
@@ -833,26 +836,26 @@
 	u16 temp2;
 	struct aper_size_info_8 *current_size;
 
-	current_size = A_SIZE_8(agp_bridge.current_size);
+	current_size = A_SIZE_8(agp_bridge->current_size);
 
 	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value); 
+	pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); 
 
 	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr); 
+	pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); 
 
 	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000); 
+	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000); 
 
 	/* mcgcfg */
-	pci_read_config_word(agp_bridge.dev, INTEL_I850_MCHCFG, &temp2);
-	pci_write_config_word(agp_bridge.dev, INTEL_I850_MCHCFG, temp2 | (1 << 9));
+	pci_read_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, &temp2);
+	pci_write_config_word(agp_bridge->dev, INTEL_I850_MCHCFG, temp2 | (1 << 9));
 	/* clear any possible AGP-related error conditions */
-	pci_write_config_word(agp_bridge.dev, INTEL_I850_ERRSTS, 0x001c); 
+	pci_write_config_word(agp_bridge->dev, INTEL_I850_ERRSTS, 0x001c); 
 	return 0;
 }
 
@@ -862,26 +865,26 @@
 	u16 temp2;
 	struct aper_size_info_8 *current_size;
 
-	current_size = A_SIZE_8(agp_bridge.current_size);
+	current_size = A_SIZE_8(agp_bridge->current_size);
 
 	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value);
+	pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 
 	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr);
+	pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
 
 	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
+	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
 
 	/* mcgcfg */
-	pci_read_config_word(agp_bridge.dev, INTEL_I860_MCHCFG, &temp2);
-	pci_write_config_word(agp_bridge.dev, INTEL_I860_MCHCFG, temp2 | (1 << 9));
+	pci_read_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, &temp2);
+	pci_write_config_word(agp_bridge->dev, INTEL_I860_MCHCFG, temp2 | (1 << 9));
 	/* clear any possible AGP-related error conditions */
-	pci_write_config_word(agp_bridge.dev, INTEL_I860_ERRSTS, 0xf700);
+	pci_write_config_word(agp_bridge->dev, INTEL_I860_ERRSTS, 0xf700);
 	return 0;
 }
 
@@ -891,33 +894,33 @@
 	u16 temp2;
 	struct aper_size_info_8 *current_size;
 
-	current_size = A_SIZE_8(agp_bridge.current_size);
+	current_size = A_SIZE_8(agp_bridge->current_size);
 
 	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, INTEL_APSIZE, current_size->size_value);
+	pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 
 	/* address to map to */
-	pci_read_config_dword(agp_bridge.dev, INTEL_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_read_config_dword(agp_bridge->dev, INTEL_APBASE, &temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 	/* attbase - aperture base */
-	pci_write_config_dword(agp_bridge.dev, INTEL_ATTBASE, agp_bridge.gatt_bus_addr);
+	pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
 
 	/* agpctrl */
-	pci_write_config_dword(agp_bridge.dev, INTEL_AGPCTRL, 0x0000);
+	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
 
 	/* gmch */
-	pci_read_config_word(agp_bridge.dev, INTEL_NBXCFG, &temp2);
-	pci_write_config_word(agp_bridge.dev, INTEL_NBXCFG, temp2 | (1 << 9));
+	pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
+	pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp2 | (1 << 9));
 	/* clear any possible AGP-related error conditions */
-	pci_write_config_word(agp_bridge.dev, INTEL_I830_ERRSTS, 0x1c);
+	pci_write_config_word(agp_bridge->dev, INTEL_I830_ERRSTS, 0x1c);
 	return 0;
 }
 
 static unsigned long intel_mask_memory(unsigned long addr, int type)
 {
 	/* Memory type is ignored */
-	return addr | agp_bridge.masks[0].mask;
+	return addr | agp_bridge->masks[0].mask;
 }
 
 static void intel_resume(void)
@@ -969,234 +972,234 @@
 
 static int __init intel_generic_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.aperture_sizes = (void *) intel_generic_sizes;
-	agp_bridge.size_type = U16_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_configure;
-	agp_bridge.fetch_size = intel_fetch_size;
-	agp_bridge.cleanup = intel_cleanup;
-	agp_bridge.tlb_flush = intel_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = intel_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = intel_generic_masks;
+	agp_bridge->aperture_sizes = (void *) intel_generic_sizes;
+	agp_bridge->size_type = U16_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 7;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = intel_configure;
+	agp_bridge->fetch_size = intel_fetch_size;
+	agp_bridge->cleanup = intel_cleanup;
+	agp_bridge->tlb_flush = intel_tlbflush;
+	agp_bridge->mask_memory = intel_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = agp_generic_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = intel_resume;
+	agp_bridge->cant_use_aperture = 0;
 	return 0;
 }
 
 static int __init intel_815_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.aperture_sizes = (void *) intel_815_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 2;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_815_configure;
-	agp_bridge.fetch_size = intel_8xx_fetch_size;
-	agp_bridge.cleanup = intel_8xx_cleanup;
-	agp_bridge.tlb_flush = intel_8xx_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = intel_generic_masks;
+	agp_bridge->aperture_sizes = (void *) intel_815_sizes;
+	agp_bridge->size_type = U8_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 2;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = intel_815_configure;
+	agp_bridge->fetch_size = intel_8xx_fetch_size;
+	agp_bridge->cleanup = intel_8xx_cleanup;
+	agp_bridge->tlb_flush = intel_8xx_tlbflush;
+	agp_bridge->mask_memory = intel_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = agp_generic_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 	return 0;
 }
 
 
 static int __init intel_820_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_820_configure;
-	agp_bridge.fetch_size = intel_8xx_fetch_size;
-	agp_bridge.cleanup = intel_820_cleanup;
-	agp_bridge.tlb_flush = intel_820_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = intel_generic_masks;
+	agp_bridge->aperture_sizes = (void *) intel_8xx_sizes;
+	agp_bridge->size_type = U8_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 7;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = intel_820_configure;
+	agp_bridge->fetch_size = intel_8xx_fetch_size;
+	agp_bridge->cleanup = intel_820_cleanup;
+	agp_bridge->tlb_flush = intel_820_tlbflush;
+	agp_bridge->mask_memory = intel_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = agp_generic_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 	return 0;
 }
 
 static int __init intel_830mp_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.aperture_sizes = (void *) intel_830mp_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 4;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_830mp_configure;
-	agp_bridge.fetch_size = intel_8xx_fetch_size;
-	agp_bridge.cleanup = intel_8xx_cleanup;
-	agp_bridge.tlb_flush = intel_8xx_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = intel_generic_masks;
+	agp_bridge->aperture_sizes = (void *) intel_830mp_sizes;
+	agp_bridge->size_type = U8_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 4;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = intel_830mp_configure;
+	agp_bridge->fetch_size = intel_8xx_fetch_size;
+	agp_bridge->cleanup = intel_8xx_cleanup;
+	agp_bridge->tlb_flush = intel_8xx_tlbflush;
+	agp_bridge->mask_memory = intel_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = agp_generic_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 	return 0;
 }
 
 static int __init intel_840_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_840_configure;
-	agp_bridge.fetch_size = intel_8xx_fetch_size;
-	agp_bridge.cleanup = intel_8xx_cleanup;
-	agp_bridge.tlb_flush = intel_8xx_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = intel_generic_masks;
+	agp_bridge->aperture_sizes = (void *) intel_8xx_sizes;
+	agp_bridge->size_type = U8_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 7;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = intel_840_configure;
+	agp_bridge->fetch_size = intel_8xx_fetch_size;
+	agp_bridge->cleanup = intel_8xx_cleanup;
+	agp_bridge->tlb_flush = intel_8xx_tlbflush;
+	agp_bridge->mask_memory = intel_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = agp_generic_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 	return 0;
 }
 
 static int __init intel_845_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_845_configure;
-	agp_bridge.fetch_size = intel_8xx_fetch_size;
-	agp_bridge.cleanup = intel_8xx_cleanup;
-	agp_bridge.tlb_flush = intel_8xx_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = intel_845_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = intel_generic_masks;
+	agp_bridge->aperture_sizes = (void *) intel_8xx_sizes;
+	agp_bridge->size_type = U8_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 7;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = intel_845_configure;
+	agp_bridge->fetch_size = intel_8xx_fetch_size;
+	agp_bridge->cleanup = intel_8xx_cleanup;
+	agp_bridge->tlb_flush = intel_8xx_tlbflush;
+	agp_bridge->mask_memory = intel_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = agp_generic_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = intel_845_resume;
+	agp_bridge->cant_use_aperture = 0;
 	return 0;
 }
 
 static int __init intel_850_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_850_configure;
-	agp_bridge.fetch_size = intel_8xx_fetch_size;
-	agp_bridge.cleanup = intel_8xx_cleanup;
-	agp_bridge.tlb_flush = intel_8xx_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = intel_generic_masks;
+	agp_bridge->aperture_sizes = (void *) intel_8xx_sizes;
+	agp_bridge->size_type = U8_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 7;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = intel_850_configure;
+	agp_bridge->fetch_size = intel_8xx_fetch_size;
+	agp_bridge->cleanup = intel_8xx_cleanup;
+	agp_bridge->tlb_flush = intel_8xx_tlbflush;
+	agp_bridge->mask_memory = intel_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = agp_generic_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 	return 0;
 }
 
 static int __init intel_860_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = intel_generic_masks;
-	agp_bridge.aperture_sizes = (void *) intel_8xx_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = intel_860_configure;
-	agp_bridge.fetch_size = intel_8xx_fetch_size;
-	agp_bridge.cleanup = intel_8xx_cleanup;
-	agp_bridge.tlb_flush = intel_8xx_tlbflush;
-	agp_bridge.mask_memory = intel_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = intel_generic_masks;
+	agp_bridge->aperture_sizes = (void *) intel_8xx_sizes;
+	agp_bridge->size_type = U8_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 7;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = intel_860_configure;
+	agp_bridge->fetch_size = intel_8xx_fetch_size;
+	agp_bridge->cleanup = intel_8xx_cleanup;
+	agp_bridge->tlb_flush = intel_8xx_tlbflush;
+	agp_bridge->mask_memory = intel_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = agp_generic_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 	return 0;
 }
 
@@ -1287,7 +1290,7 @@
 		if (pdev->device == devs[j].device_id) {
 			printk (KERN_INFO PFX "Detected Intel %s chipset\n",
 				devs[j].chipset_name);
-			agp_bridge.type = devs[j].chipset;
+			agp_bridge->type = devs[j].chipset;
 
 			if (devs[j].chipset_setup != NULL)
 				return devs[j].chipset_setup(pdev);
@@ -1302,7 +1305,7 @@
 	if (agp_try_unsupported) {
 		printk(KERN_WARNING PFX "Trying generic Intel routines"
 			" for device id: %04x\n", pdev->device);
-		agp_bridge.type = INTEL_GENERIC;
+		agp_bridge->type = INTEL_GENERIC;
 		return intel_generic_setup(pdev);
 	}
 
@@ -1319,7 +1322,7 @@
 	struct pci_dev *i810_dev;
 	u8 cap_ptr = 0;
 
-	agp_bridge.dev = dev;
+	agp_bridge->dev = dev;
 
 	/* This shit needs moving into tables/init-routines. */
 	switch (dev->device) {
@@ -1331,7 +1334,7 @@
 			return -ENODEV;
 		}
 		printk(KERN_INFO PFX "Detected an Intel i810 Chipset.\n");
-		agp_bridge.type = INTEL_I810;
+		agp_bridge->type = INTEL_I810;
 		return intel_i810_setup (i810_dev);
 
 	case PCI_DEVICE_ID_INTEL_82810_MC3:
@@ -1342,7 +1345,7 @@
 			return -ENODEV;
 		}
 		printk(KERN_INFO PFX "Detected an Intel i810 DC100 Chipset.\n");
-		agp_bridge.type = INTEL_I810;
+		agp_bridge->type = INTEL_I810;
 		return intel_i810_setup(i810_dev);
 
 	case PCI_DEVICE_ID_INTEL_82810E_MC:
@@ -1353,7 +1356,7 @@
 			return -ENODEV;
 		}
 		printk(KERN_INFO PFX "Detected an Intel i810 E Chipset.\n");
-		agp_bridge.type = INTEL_I810;
+		agp_bridge->type = INTEL_I810;
 		return intel_i810_setup(i810_dev);
 
 	 case PCI_DEVICE_ID_INTEL_82815_MC:
@@ -1371,7 +1374,7 @@
 			break;
 		}
 		printk(KERN_INFO PFX "agpgart: Detected an Intel i815 Chipset.\n");
-		agp_bridge.type = INTEL_I810;
+		agp_bridge->type = INTEL_I810;
 		return intel_i810_setup(i810_dev);
 
 	case PCI_DEVICE_ID_INTEL_82845G_HB:
@@ -1387,11 +1390,11 @@
 			 * We probably have a I845MP chipset with an external graphics
 			 * card. It will be initialized later 
 			 */
-			agp_bridge.type = INTEL_I845_G;
+			agp_bridge->type = INTEL_I845_G;
 			break;
 		}
 		printk(KERN_INFO PFX "Detected an Intel 845G Chipset.\n");
-		agp_bridge.type = INTEL_I810;
+		agp_bridge->type = INTEL_I810;
 		return intel_i830_setup(i810_dev);
 
 	case PCI_DEVICE_ID_INTEL_82830_HB:
@@ -1402,11 +1405,11 @@
 		if (i810_dev == NULL) {
 			/* Intel 830MP with external graphic card */
 			/* It will be initialized later */
-			agp_bridge.type = INTEL_I830_M;
+			agp_bridge->type = INTEL_I830_M;
 			break;
 		}
 		printk(KERN_INFO PFX "Detected an Intel 830M Chipset.\n");
-		agp_bridge.type = INTEL_I810;
+		agp_bridge->type = INTEL_I810;
 		return intel_i830_setup(i810_dev);
 
 	default:
@@ -1416,10 +1419,10 @@
 	cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
 	if (cap_ptr == 0)
 		return -ENODEV;
-	agp_bridge.capndx = cap_ptr;
+	agp_bridge->capndx = cap_ptr;
 
 	/* Fill in the mode register */
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
+	pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode);
 
 	/* probe for known chipsets */
 	return agp_lookup_host_bridge(dev);
@@ -1472,7 +1475,7 @@
 
 	ret_val = pci_module_init(&agp_intel_pci_driver);
 	if (ret_val)
-		agp_bridge.type = NOT_SUPPORTED;
+		agp_bridge->type = NOT_SUPPORTED;
 
 	return ret_val;
 }
diff -Nru a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
--- a/drivers/char/agp/sis-agp.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/char/agp/sis-agp.c	Fri Feb 14 15:53:08 2003
@@ -16,16 +16,16 @@
 	int i;
 	struct aper_size_info_8 *values;
 
-	pci_read_config_byte(agp_bridge.dev, SIS_APSIZE, &temp_size);
-	values = A_SIZE_8(agp_bridge.aperture_sizes);
-	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+	pci_read_config_byte(agp_bridge->dev, SIS_APSIZE, &temp_size);
+	values = A_SIZE_8(agp_bridge->aperture_sizes);
+	for (i = 0; i < agp_bridge->num_aperture_sizes; i++) {
 		if ((temp_size == values[i].size_value) ||
 		    ((temp_size & ~(0x03)) ==
 		     (values[i].size_value & ~(0x03)))) {
-			agp_bridge.previous_size =
-			    agp_bridge.current_size = (void *) (values + i);
+			agp_bridge->previous_size =
+			    agp_bridge->current_size = (void *) (values + i);
 
-			agp_bridge.aperture_size_idx = i;
+			agp_bridge->aperture_size_idx = i;
 			return values[i].size;
 		}
 	}
@@ -35,7 +35,7 @@
 
 static void sis_tlbflush(agp_memory * mem)
 {
-	pci_write_config_byte(agp_bridge.dev, SIS_TLBFLUSH, 0x02);
+	pci_write_config_byte(agp_bridge->dev, SIS_TLBFLUSH, 0x02);
 }
 
 static int sis_configure(void)
@@ -43,13 +43,13 @@
 	u32 temp;
 	struct aper_size_info_8 *current_size;
 
-	current_size = A_SIZE_8(agp_bridge.current_size);
-	pci_write_config_byte(agp_bridge.dev, SIS_TLBCNTRL, 0x05);
-	pci_read_config_dword(agp_bridge.dev, SIS_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-	pci_write_config_dword(agp_bridge.dev, SIS_ATTBASE,
-			       agp_bridge.gatt_bus_addr);
-	pci_write_config_byte(agp_bridge.dev, SIS_APSIZE,
+	current_size = A_SIZE_8(agp_bridge->current_size);
+	pci_write_config_byte(agp_bridge->dev, SIS_TLBCNTRL, 0x05);
+	pci_read_config_dword(agp_bridge->dev, SIS_APBASE, &temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_write_config_dword(agp_bridge->dev, SIS_ATTBASE,
+			       agp_bridge->gatt_bus_addr);
+	pci_write_config_byte(agp_bridge->dev, SIS_APSIZE,
 			      current_size->size_value);
 	return 0;
 }
@@ -58,8 +58,8 @@
 {
 	struct aper_size_info_8 *previous_size;
 
-	previous_size = A_SIZE_8(agp_bridge.previous_size);
-	pci_write_config_byte(agp_bridge.dev, SIS_APSIZE,
+	previous_size = A_SIZE_8(agp_bridge->previous_size);
+	pci_write_config_byte(agp_bridge->dev, SIS_APSIZE,
 			      (previous_size->size_value & ~(0x03)));
 }
 
@@ -67,7 +67,7 @@
 {
 	/* Memory type is ignored */
 
-	return addr | agp_bridge.masks[0].mask;
+	return addr | agp_bridge->masks[0].mask;
 }
 
 static struct aper_size_info_8 sis_generic_sizes[7] =
@@ -88,30 +88,30 @@
 
 static int __init sis_generic_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = sis_generic_masks;
-	agp_bridge.aperture_sizes = (void *) sis_generic_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = sis_configure;
-	agp_bridge.fetch_size = sis_fetch_size;
-	agp_bridge.cleanup = sis_cleanup;
-	agp_bridge.tlb_flush = sis_tlbflush;
-	agp_bridge.mask_memory = sis_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = sis_generic_masks;
+	agp_bridge->aperture_sizes = (void *) sis_generic_sizes;
+	agp_bridge->size_type = U8_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 7;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = sis_configure;
+	agp_bridge->fetch_size = sis_fetch_size;
+	agp_bridge->cleanup = sis_cleanup;
+	agp_bridge->tlb_flush = sis_tlbflush;
+	agp_bridge->mask_memory = sis_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = agp_generic_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 
 	return 0;
 }
@@ -198,7 +198,7 @@
 		if (pdev->device == devs[j].device_id) {
 			printk (KERN_INFO PFX "Detected SiS %s chipset\n",
 				devs[j].chipset_name);
-			agp_bridge.type = devs[j].chipset;
+			agp_bridge->type = devs[j].chipset;
 
 			if (devs[j].chipset_setup != NULL)
 				return devs[j].chipset_setup(pdev);
@@ -212,7 +212,7 @@
 	if (agp_try_unsupported) {
 		printk(KERN_WARNING PFX "Trying generic SiS routines"
 		       " for device id: %04x\n", pdev->device);
-		agp_bridge.type = SIS_GENERIC;
+		agp_bridge->type = SIS_GENERIC;
 		return sis_generic_setup(pdev);
 	}
 
@@ -235,10 +235,10 @@
 
 	/* probe for known chipsets */
 	if (agp_lookup_host_bridge(dev) != -ENODEV) {
-		agp_bridge.dev = dev;
-		agp_bridge.capndx = cap_ptr;
+		agp_bridge->dev = dev;
+		agp_bridge->capndx = cap_ptr;
 		/* Fill in the mode register */
-		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
+		pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode);
 		sis_agp_driver.dev = dev;
 		agp_register_driver(&sis_agp_driver);
 		return 0;
@@ -272,7 +272,7 @@
 
 	ret_val = pci_module_init(&agp_sis_pci_driver);
 	if (ret_val)
-		agp_bridge.type = NOT_SUPPORTED;
+		agp_bridge->type = NOT_SUPPORTED;
 
 	return ret_val;
 }
diff -Nru a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
--- a/drivers/char/agp/sworks-agp.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/agp/sworks-agp.c	Fri Feb 14 15:53:09 2003
@@ -47,7 +47,7 @@
 	CACHE_FLUSH();
 
 	for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
-		page_map->remapped[i] = agp_bridge.scratch_page;
+		page_map->remapped[i] = agp_bridge->scratch_page;
 	}
 
 	return 0;
@@ -120,7 +120,7 @@
 
 #ifndef GET_PAGE_DIR_IDX
 #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
-	GET_PAGE_DIR_OFF(agp_bridge.gart_bus_addr))
+	GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr))
 #endif
 
 #ifndef GET_GATT_OFF
@@ -135,7 +135,7 @@
 	u32 temp;
 	int i;
 
-	value = A_SIZE_LVL2(agp_bridge.current_size);
+	value = A_SIZE_LVL2(agp_bridge->current_size);
 	retval = serverworks_create_page_map(&page_dir);
 	if (retval != 0) {
 		return retval;
@@ -147,7 +147,7 @@
 	}
 	/* Create a fake scratch directory */
 	for(i = 0; i < 1024; i++) {
-		serverworks_private.scratch_dir.remapped[i] = (unsigned long) agp_bridge.scratch_page;
+		serverworks_private.scratch_dir.remapped[i] = (unsigned long) agp_bridge->scratch_page;
 		page_dir.remapped[i] =
 			virt_to_phys(serverworks_private.scratch_dir.real);
 		page_dir.remapped[i] |= 0x00000001;
@@ -160,17 +160,17 @@
 		return retval;
 	}
 
-	agp_bridge.gatt_table_real = (u32 *)page_dir.real;
-	agp_bridge.gatt_table = (u32 *)page_dir.remapped;
-	agp_bridge.gatt_bus_addr = virt_to_phys(page_dir.real);
+	agp_bridge->gatt_table_real = (u32 *)page_dir.real;
+	agp_bridge->gatt_table = (u32 *)page_dir.remapped;
+	agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
 
 	/* Get the address for the gart region.
 	 * This is a bus address even on the alpha, b/c its
 	 * used to program the agp master not the cpu
 	 */
 
-	pci_read_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,&temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 	/* Calculate the agp offset */	
 
@@ -187,8 +187,8 @@
 {
 	struct serverworks_page_map page_dir;
    
-	page_dir.real = (unsigned long *)agp_bridge.gatt_table_real;
-	page_dir.remapped = (unsigned long *)agp_bridge.gatt_table;
+	page_dir.real = (unsigned long *)agp_bridge->gatt_table_real;
+	page_dir.remapped = (unsigned long *)agp_bridge->gatt_table;
 
 	serverworks_free_gatt_pages();
 	serverworks_free_page_map(&page_dir);
@@ -203,20 +203,20 @@
 	u32 temp2;
 	struct aper_size_info_lvl2 *values;
 
-	values = A_SIZE_LVL2(agp_bridge.aperture_sizes);
-	pci_read_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,&temp);
-	pci_write_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,
+	values = A_SIZE_LVL2(agp_bridge->aperture_sizes);
+	pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp);
+	pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,
 					SVWRKS_SIZE_MASK);
-	pci_read_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,&temp2);
-	pci_write_config_dword(agp_bridge.dev,serverworks_private.gart_addr_ofs,temp);
+	pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp2);
+	pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,temp);
 	temp2 &= SVWRKS_SIZE_MASK;
 
-	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+	for (i = 0; i < agp_bridge->num_aperture_sizes; i++) {
 		if (temp2 == values[i].size_value) {
-			agp_bridge.previous_size =
-			    agp_bridge.current_size = (void *) (values + i);
+			agp_bridge->previous_size =
+			    agp_bridge->current_size = (void *) (values + i);
 
-			agp_bridge.aperture_size_idx = i;
+			agp_bridge->aperture_size_idx = i;
 			return values[i].size;
 		}
 	}
@@ -231,17 +231,17 @@
 	u8 enable_reg;
 	u16 cap_reg;
 
-	current_size = A_SIZE_LVL2(agp_bridge.current_size);
+	current_size = A_SIZE_LVL2(agp_bridge->current_size);
 
 	/* Get the memory mapped registers */
-	pci_read_config_dword(agp_bridge.dev, serverworks_private.mm_addr_ofs, &temp);
+	pci_read_config_dword(agp_bridge->dev, serverworks_private.mm_addr_ofs, &temp);
 	temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 	serverworks_private.registers = (volatile u8 *) ioremap(temp, 4096);
 
 	OUTREG8(serverworks_private.registers, SVWRKS_GART_CACHE, 0x0a);
 
 	OUTREG32(serverworks_private.registers, SVWRKS_GATTBASE, 
-		 agp_bridge.gatt_bus_addr);
+		 agp_bridge->gatt_bus_addr);
 
 	cap_reg = INREG16(serverworks_private.registers, SVWRKS_COMMAND);
 	cap_reg &= ~0x0007;
@@ -253,21 +253,21 @@
 	enable_reg |= 0x1; /* Agp Enable bit */
 	pci_write_config_byte(serverworks_private.svrwrks_dev,
 			      SVWRKS_AGP_ENABLE, enable_reg);
-	agp_bridge.tlb_flush(NULL);
+	agp_bridge->tlb_flush(NULL);
 
-	agp_bridge.capndx = pci_find_capability(serverworks_private.svrwrks_dev, PCI_CAP_ID_AGP);
+	agp_bridge->capndx = pci_find_capability(serverworks_private.svrwrks_dev, PCI_CAP_ID_AGP);
 
 	/* Fill in the mode register */
 	pci_read_config_dword(serverworks_private.svrwrks_dev,
-			      agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
+			      agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode);
 
-	pci_read_config_byte(agp_bridge.dev, SVWRKS_CACHING, &enable_reg);
+	pci_read_config_byte(agp_bridge->dev, SVWRKS_CACHING, &enable_reg);
 	enable_reg &= ~0x3;
-	pci_write_config_byte(agp_bridge.dev, SVWRKS_CACHING, enable_reg);
+	pci_write_config_byte(agp_bridge->dev, SVWRKS_CACHING, enable_reg);
 
-	pci_read_config_byte(agp_bridge.dev, SVWRKS_FEATURE, &enable_reg);
+	pci_read_config_byte(agp_bridge->dev, SVWRKS_FEATURE, &enable_reg);
 	enable_reg |= (1<<6);
-	pci_write_config_byte(agp_bridge.dev,SVWRKS_FEATURE, enable_reg);
+	pci_write_config_byte(agp_bridge->dev,SVWRKS_FEATURE, enable_reg);
 
 	return 0;
 }
@@ -313,7 +313,7 @@
 {
 	/* Only type 0 is supported by the serverworks chipsets */
 
-	return addr | agp_bridge.masks[0].mask;
+	return addr | agp_bridge->masks[0].mask;
 }
 
 static int serverworks_insert_memory(agp_memory * mem,
@@ -323,7 +323,7 @@
 	unsigned long *cur_gatt;
 	unsigned long addr;
 
-	num_entries = A_SIZE_LVL2(agp_bridge.current_size)->num_entries;
+	num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;
 
 	if (type != 0 || mem->type != 0) {
 		return -EINVAL;
@@ -334,7 +334,7 @@
 
 	j = pg_start;
 	while (j < (pg_start + mem->page_count)) {
-		addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr;
+		addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
 		cur_gatt = SVRWRKS_GET_GATT(addr);
 		if (!PGE_EMPTY(cur_gatt[GET_GATT_OFF(addr)])) {
 			return -EBUSY;
@@ -348,12 +348,12 @@
 	}
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		addr = (j * PAGE_SIZE) + agp_bridge.gart_bus_addr;
+		addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
 		cur_gatt = SVRWRKS_GET_GATT(addr);
 		cur_gatt[GET_GATT_OFF(addr)] =
-			agp_bridge.mask_memory(mem->memory[i], mem->type);
+			agp_bridge->mask_memory(mem->memory[i], mem->type);
 	}
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 	return 0;
 }
 
@@ -369,16 +369,16 @@
 	}
 
 	CACHE_FLUSH();
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 
 	for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-		addr = (i * PAGE_SIZE) + agp_bridge.gart_bus_addr;
+		addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
 		cur_gatt = SVRWRKS_GET_GATT(addr);
 		cur_gatt[GET_GATT_OFF(addr)] = 
-			(unsigned long) agp_bridge.scratch_page;
+			(unsigned long) agp_bridge->scratch_page;
 	}
 
-	agp_bridge.tlb_flush(mem);
+	agp_bridge->tlb_flush(mem);
 	return 0;
 }
 
@@ -403,7 +403,7 @@
 	u32 command;
 
 	pci_read_config_dword(serverworks_private.svrwrks_dev,
-			      agp_bridge.capndx + PCI_AGP_STATUS,
+			      agp_bridge->capndx + PCI_AGP_STATUS,
 			      &command);
 
 	command = agp_collect_device_status(mode, command);
@@ -414,7 +414,7 @@
 	command |= 0x100;
 
 	pci_write_config_dword(serverworks_private.svrwrks_dev,
-			       agp_bridge.capndx + PCI_AGP_COMMAND,
+			       agp_bridge->capndx + PCI_AGP_COMMAND,
 			       command);
 
 	agp_device_command(command, 0);
@@ -427,39 +427,39 @@
 
 	serverworks_private.svrwrks_dev = pdev;
 
-	agp_bridge.masks = serverworks_masks;
-	agp_bridge.aperture_sizes = (void *) serverworks_sizes;
-	agp_bridge.size_type = LVL2_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = (void *) &serverworks_private;
-	agp_bridge.needs_scratch_page = TRUE;
-	agp_bridge.configure = serverworks_configure;
-	agp_bridge.fetch_size = serverworks_fetch_size;
-	agp_bridge.cleanup = serverworks_cleanup;
-	agp_bridge.tlb_flush = serverworks_tlbflush;
-	agp_bridge.mask_memory = serverworks_mask_memory;
-	agp_bridge.agp_enable = serverworks_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = serverworks_create_gatt_table;
-	agp_bridge.free_gatt_table = serverworks_free_gatt_table;
-	agp_bridge.insert_memory = serverworks_insert_memory;
-	agp_bridge.remove_memory = serverworks_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+	agp_bridge->masks = serverworks_masks;
+	agp_bridge->aperture_sizes = (void *) serverworks_sizes;
+	agp_bridge->size_type = LVL2_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 7;
+	agp_bridge->dev_private_data = (void *) &serverworks_private;
+	agp_bridge->needs_scratch_page = TRUE;
+	agp_bridge->configure = serverworks_configure;
+	agp_bridge->fetch_size = serverworks_fetch_size;
+	agp_bridge->cleanup = serverworks_cleanup;
+	agp_bridge->tlb_flush = serverworks_tlbflush;
+	agp_bridge->mask_memory = serverworks_mask_memory;
+	agp_bridge->agp_enable = serverworks_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = serverworks_create_gatt_table;
+	agp_bridge->free_gatt_table = serverworks_free_gatt_table;
+	agp_bridge->insert_memory = serverworks_insert_memory;
+	agp_bridge->remove_memory = serverworks_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 
-	pci_read_config_dword(agp_bridge.dev,
+	pci_read_config_dword(agp_bridge->dev,
 			      SVWRKS_APSIZE,
 			      &temp);
 
 	serverworks_private.gart_addr_ofs = 0x10;
 
 	if(temp & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-		pci_read_config_dword(agp_bridge.dev,
+		pci_read_config_dword(agp_bridge->dev,
 				      SVWRKS_APSIZE + 4,
 				      &temp2);
 		if(temp2 != 0) {
@@ -472,11 +472,11 @@
 		serverworks_private.mm_addr_ofs = 0x14;
 	}
 
-	pci_read_config_dword(agp_bridge.dev,
+	pci_read_config_dword(agp_bridge->dev,
 			      serverworks_private.mm_addr_ofs,
 			      &temp);
 	if(temp & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-		pci_read_config_dword(agp_bridge.dev,
+		pci_read_config_dword(agp_bridge->dev,
 				      serverworks_private.mm_addr_ofs + 4,
 				      &temp2);
 		if(temp2 != 0) {
@@ -503,21 +503,21 @@
 		return -ENODEV;
 	}
 
-	agp_bridge.dev = dev;
+	agp_bridge->dev = dev;
 
 	switch (dev->device) {
 	case PCI_DEVICE_ID_SERVERWORKS_HE:
-		agp_bridge.type = SVWRKS_HE;
+		agp_bridge->type = SVWRKS_HE;
 		return serverworks_setup(bridge_dev);
 
 	case PCI_DEVICE_ID_SERVERWORKS_LE:
 	case 0x0007:
-		agp_bridge.type = SVWRKS_LE;
+		agp_bridge->type = SVWRKS_LE;
 		return serverworks_setup(bridge_dev);
 
 	default:
 		if(agp_try_unsupported) {
-			agp_bridge.type = SVWRKS_GENERIC;
+			agp_bridge->type = SVWRKS_GENERIC;
 			return serverworks_setup(bridge_dev);
 		}
 		break;
@@ -565,7 +565,7 @@
 
 	ret_val = pci_module_init(&agp_serverworks_pci_driver);
 	if (ret_val)
-		agp_bridge.type = NOT_SUPPORTED;
+		agp_bridge->type = NOT_SUPPORTED;
 
 	return ret_val;
 }
diff -Nru a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
--- a/drivers/char/agp/via-agp.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/agp/via-agp.c	Fri Feb 14 15:53:12 2003
@@ -11,73 +11,78 @@
 
 static int agp_try_unsupported __initdata = 0;
 
+
 static int via_fetch_size(void)
 {
 	int i;
 	u8 temp;
 	struct aper_size_info_8 *values;
 
-	values = A_SIZE_8(agp_bridge.aperture_sizes);
-	pci_read_config_byte(agp_bridge.dev, VIA_APSIZE, &temp);
-	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+	values = A_SIZE_8(agp_bridge->aperture_sizes);
+	pci_read_config_byte(agp_bridge->dev, VIA_APSIZE, &temp);
+	for (i = 0; i < agp_bridge->num_aperture_sizes; i++) {
 		if (temp == values[i].size_value) {
-			agp_bridge.previous_size =
-			    agp_bridge.current_size = (void *) (values + i);
-			agp_bridge.aperture_size_idx = i;
+			agp_bridge->previous_size =
+			    agp_bridge->current_size = (void *) (values + i);
+			agp_bridge->aperture_size_idx = i;
 			return values[i].size;
 		}
 	}
-
 	return 0;
 }
 
+
 static int via_configure(void)
 {
 	u32 temp;
 	struct aper_size_info_8 *current_size;
 
-	current_size = A_SIZE_8(agp_bridge.current_size);
+	current_size = A_SIZE_8(agp_bridge->current_size);
 	/* aperture size */
-	pci_write_config_byte(agp_bridge.dev, VIA_APSIZE,
+	pci_write_config_byte(agp_bridge->dev, VIA_APSIZE,
 			      current_size->size_value);
 	/* address to map too */
-	pci_read_config_dword(agp_bridge.dev, VIA_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	pci_read_config_dword(agp_bridge->dev, VIA_APBASE, &temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
 
 	/* GART control register */
-	pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000000f);
+	pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, 0x0000000f);
 
 	/* attbase - aperture GATT base */
-	pci_write_config_dword(agp_bridge.dev, VIA_ATTBASE,
-			    (agp_bridge.gatt_bus_addr & 0xfffff000) | 3);
+	pci_write_config_dword(agp_bridge->dev, VIA_ATTBASE,
+			    (agp_bridge->gatt_bus_addr & 0xfffff000) | 3);
 	return 0;
 }
 
+
 static void via_cleanup(void)
 {
 	struct aper_size_info_8 *previous_size;
 
-	previous_size = A_SIZE_8(agp_bridge.previous_size);
-	pci_write_config_byte(agp_bridge.dev, VIA_APSIZE,
+	previous_size = A_SIZE_8(agp_bridge->previous_size);
+	pci_write_config_byte(agp_bridge->dev, VIA_APSIZE,
 			      previous_size->size_value);
 	/* Do not disable by writing 0 to VIA_ATTBASE, it screws things up
 	 * during reinitialization.
 	 */
 }
 
+
 static void via_tlbflush(agp_memory * mem)
 {
-	pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000008f);
-	pci_write_config_dword(agp_bridge.dev, VIA_GARTCTRL, 0x0000000f);
+	pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, 0x0000008f);
+	pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, 0x0000000f);
 }
 
+
 static unsigned long via_mask_memory(unsigned long addr, int type)
 {
 	/* Memory type is ignored */
 
-	return addr | agp_bridge.masks[0].mask;
+	return addr | agp_bridge->masks[0].mask;
 }
 
+
 static struct aper_size_info_8 via_generic_sizes[7] =
 {
 	{256, 65536, 6, 0},
@@ -89,123 +94,327 @@
 	{4, 1024, 0, 252}
 };
 
+
 static struct gatt_mask via_generic_masks[] =
 {
 	{.mask = 0x00000000, .type = 0}
 };
 
+
+#ifdef CONFIG_AGP3
+static int via_fetch_size_agp3(void)
+{
+	int i;
+	u16 temp;
+	struct aper_size_info_16 *values;
+
+	values = A_SIZE_16(agp_bridge->aperture_sizes);
+	pci_read_config_word(agp_bridge->dev, VIA_AGP3_APSIZE, &temp);
+	temp &= 0xfff;
+
+	for (i = 0; i < agp_bridge->num_aperture_sizes; i++) {
+		if (temp == values[i].size_value) {
+			agp_bridge->previous_size =
+				agp_bridge->current_size = (void *) (values + i);
+			agp_bridge->aperture_size_idx = i;
+			return values[i].size;
+		}
+	}
+	return 0;
+}
+
+
+static int via_configure_agp3(void)
+{
+	u32 temp;
+	struct aper_size_info_16 *current_size;
+    
+	current_size = A_SIZE_16(agp_bridge->current_size);
+
+	/* address to map too */
+	pci_read_config_dword(agp_bridge->dev, VIA_APBASE, &temp);
+	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* attbase - aperture GATT base */
+	pci_write_config_dword(agp_bridge->dev, VIA_AGP3_ATTBASE,
+		agp_bridge->gatt_bus_addr & 0xfffff000);
+	return 0;
+}
+
+
+static void via_cleanup_agp3(void)
+{
+	struct aper_size_info_16 *previous_size;
+
+	previous_size = A_SIZE_16(agp_bridge->previous_size);
+	pci_write_config_byte(agp_bridge->dev, VIA_APSIZE, previous_size->size_value);
+}
+
+
+static void via_tlbflush_agp3(agp_memory * mem)
+{
+	u32 temp;
+
+	pci_read_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, &temp);
+	pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp & ~(1<<7));
+	pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp);
+}
+
+
+static struct aper_size_info_16 via_generic_agp3_sizes[11] =
+{
+	{ 4,     1024,  0, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3|1<<2|1<<1|1<<0 },
+	{ 8,     2048,  1, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3|1<<2|1<<1},
+	{ 16,    4096,  2, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3|1<<2},
+	{ 32,    8192,  3, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3},
+	{ 64,   16384,  4, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4},
+	{ 128,  32768,  5, 1<<11|1<<10|1<<9|1<<8|1<<5},
+	{ 256,  65536,  6, 1<<11|1<<10|1<<9|1<<8},
+	{ 512,  131072, 7, 1<<11|1<<10|1<<9},
+	{ 1024, 262144, 8, 1<<11|1<<10},
+	{ 2048, 524288, 9, 1<<11}	/* 2GB <- Max supported */
+};
+
+
+static int __init via_generic_agp3_setup (struct pci_dev *pdev)
+{
+	agp_bridge->dev = pdev;
+	agp_bridge->type = VIA_GENERIC;
+	agp_bridge->masks = via_generic_masks;
+	agp_bridge->aperture_sizes = (void *) via_generic_agp3_sizes;
+	agp_bridge->size_type = U16_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 10;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->agp_enable = agp_generic_agp_3_0_enable;
+	agp_bridge->configure = via_configure_agp3;
+	agp_bridge->fetch_size = via_fetch_size_agp3;
+	agp_bridge->cleanup = via_cleanup_agp3;
+	agp_bridge->tlb_flush = via_tlbflush_agp3;
+	agp_bridge->mask_memory = via_mask_memory;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = agp_generic_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
+	return 0;
+}
+#else
+static int __init via_generic_agp3_setup (struct pci_dev *pdev)
+{
+	printk (KERN_INFO PFX "Bridge in AGP3 mode, but CONFIG_AGP3=n\n");
+	return -ENODEV;
+}
+#endif	/* CONFIG_AGP3 */
+
+
 static int __init via_generic_setup (struct pci_dev *pdev)
 {
-	agp_bridge.masks = via_generic_masks;
-	agp_bridge.aperture_sizes = (void *) via_generic_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.configure = via_configure;
-	agp_bridge.fetch_size = via_fetch_size;
-	agp_bridge.cleanup = via_cleanup;
-	agp_bridge.tlb_flush = via_tlbflush;
-	agp_bridge.mask_memory = via_mask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
+#ifdef CONFIG_AGP3
+	/* Garg, there are KT400s with KT266 IDs. */
+	if (pdev->device == PCI_DEVICE_ID_VIA_8367_0) {
+
+		/* Is there a KT400 subsystem ? */
+		if (pdev->subsystem_device==PCI_DEVICE_ID_VIA_8377_0) {
+			u8 reg;
+
+			printk (KERN_INFO PFX "Found KT400 in disguise as a KT266.\n");
+
+			/* Check AGP compatability mode. */
+			pci_read_config_byte(pdev, VIA_AGPSEL, &reg);
+			if ((reg & (1<<1))==0)
+				return via_generic_agp3_setup(pdev);
+
+			/* Its in 2.0 mode, drop through. */
+		}
+	}
+#endif
+
+	agp_bridge->masks = via_generic_masks;
+	agp_bridge->aperture_sizes = (void *) via_generic_sizes;
+	agp_bridge->size_type = U8_APER_SIZE;
+	agp_bridge->num_aperture_sizes = 7;
+	agp_bridge->dev_private_data = NULL;
+	agp_bridge->needs_scratch_page = FALSE;
+	agp_bridge->configure = via_configure;
+	agp_bridge->fetch_size = via_fetch_size;
+	agp_bridge->cleanup = via_cleanup;
+	agp_bridge->tlb_flush = via_tlbflush;
+	agp_bridge->mask_memory = via_mask_memory;
+	agp_bridge->agp_enable = agp_generic_agp_enable;
+	agp_bridge->cache_flush = global_cache_flush;
+	agp_bridge->create_gatt_table = agp_generic_create_gatt_table;
+	agp_bridge->free_gatt_table = agp_generic_free_gatt_table;
+	agp_bridge->insert_memory = agp_generic_insert_memory;
+	agp_bridge->remove_memory = agp_generic_remove_memory;
+	agp_bridge->alloc_by_type = agp_generic_alloc_by_type;
+	agp_bridge->free_by_type = agp_generic_free_by_type;
+	agp_bridge->agp_alloc_page = agp_generic_alloc_page;
+	agp_bridge->agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge->suspend = agp_generic_suspend;
+	agp_bridge->resume = agp_generic_resume;
+	agp_bridge->cant_use_aperture = 0;
 	return 0;
 }
 
-/*
- * The KT400 does magick to put the AGP bridge compliant with the same
- * standards version as the graphics card. If we haven't fallen into
- * 2.0 compatability mode, we abort, as this gets picked up by
- * via-agp3.o
- */
 
+/* The KT400 does magick to put the AGP bridge compliant with the same
+ * standards version as the graphics card. */
 static int __init via_kt400_setup(struct pci_dev *pdev)
 {
 	u8 reg;
 	pci_read_config_byte(pdev, VIA_AGPSEL, &reg);
 	/* Check AGP 2.0 compatability mode. */
-	if ((reg & (1<<1))==1) {
-		via_generic_setup(pdev);
-		return 0;
-	}
-	return -ENODEV;
+	if ((reg & (1<<1))==0)
+		return via_generic_agp3_setup(pdev);
+	return via_generic_setup(pdev);
 }
 
+
 static struct agp_device_ids via_agp_device_ids[] __initdata =
 {
 	{
 		.device_id	= PCI_DEVICE_ID_VIA_82C597_0,
-		.chipset	= VIA_VP3,
 		.chipset_name	= "VP3",
 	},
+
 	{
 		.device_id	= PCI_DEVICE_ID_VIA_82C598_0,
-		.chipset	= VIA_MVP3,
 		.chipset_name	= "MVP3",
 	},
+
 	{
 		.device_id	= PCI_DEVICE_ID_VIA_8501_0,
-		.chipset	= VIA_MVP4,
 		.chipset_name	= "MVP4",
 	},
+
+	/* VT8601 */
+	{
+		.device_id	= PCI_DEVICE_ID_VIA_8601_0,
+		.chipset_name	= "PLE133 ProMedia",
+	},
+
+	/* VT82C693A / VT28C694T */
 	{
 		.device_id	= PCI_DEVICE_ID_VIA_82C691,
-		.chipset	= VIA_APOLLO_PRO,
-		.chipset_name	= "Apollo Pro",
+		.chipset_name	= "Apollo Pro 133",
 	},
+
 	{
 		.device_id	= PCI_DEVICE_ID_VIA_8371_0,
-		.chipset	= VIA_APOLLO_KX133,
 		.chipset_name	= "Apollo Pro KX133",
 	},
+
+	/* VT8633 */
 	{
 		.device_id	= PCI_DEVICE_ID_VIA_8633_0,
-		.chipset	= VIA_APOLLO_PRO_266,
 		.chipset_name	= "Apollo Pro 266",
 	},
+
+	/* VT8361 */
+/*	{
+		.device_id	= PCI_DEVICE_ID_VIA_8361,	// 0x3112
+		.chipset_name	= "Apollo KLE133",
+	}, */
+
+	/* VT8365 / VT8362 */
 	{
 		.device_id	= PCI_DEVICE_ID_VIA_8363_0,
-		.chipset	= VIA_APOLLO_KT133,
-		.chipset_name	= "Apollo Pro KT133",
+		.chipset_name	= "Apollo Pro KT133/KM133/TwisterK",
 	},
+
+	/* VT8753A */
+/*	{
+		.device_id	= PCI_DEVICE_ID_VIA_8753_0,	// 0x3128
+		.chipset_name	= "P4X266",
+	},	*/	
+
+	/* VT8366 */
 	{
 		.device_id	= PCI_DEVICE_ID_VIA_8367_0,
-		.chipset	= VIA_APOLLO_KT133,
-		.chipset_name	= "Apollo Pro KT266",
+		.chipset_name	= "Apollo Pro KT266/KT333",
 	},
+
+	/* VT8633 (for CuMine/ Celeron) */
 	{
 		.device_id	= PCI_DEVICE_ID_VIA_8653_0,
-		.chipset	= VIA_APOLLO_PRO,
 		.chipset_name	= "Apollo Pro 266T",
 	},
+
+	/* KM266 / PM266 */
+/*	{
+		.device_id	= PCI_DEVICE_ID_VIA_KM266,	// 0x3116
+		.chipset_name	= "KM266/PM266",
+	},	*/
+
+	/* CLE266 */
+/*	{
+		.device_id	= PCI_DEVICE_ID_VIA_CLE266,	// 0x3123
+		.chipset_name	= "CLE266",
+	},	*/
+
 	{
 		.device_id	= PCI_DEVICE_ID_VIA_8377_0,
-		.chipset	= VIA_APOLLO_KT400,
 		.chipset_name	= "Apollo Pro KT400",
 		.chipset_setup	= via_kt400_setup,
 	},
+
+	/* VT8604 / VT8605 / VT8603 / TwisterT
+	 * (Apollo Pro133A chipset with S3 Savage4) */
 	{
-		/* VIA ProSavage PM133 (Apollo Pro133A chipset with S3 Savage4) */
 		.device_id	= PCI_DEVICE_ID_VIA_82C694X_0,
-		.chipset	= VIA_VT8605,
-		.chipset_name	= "Apollo ProSavage PM133"
+		.chipset_name	= "Apollo ProSavage PM133/PL133/PN133/Twister"
 	},
+
+	/* VT8752*/
+/*	{
+		.device_id	= PCI_DEVICE_ID_VIA_8752,	// 0x3148
+		.chipset_name	= "ProSavage DDR P4M266",
+	},	*/
+
+	/* KN266/PN266 */
+/*	{
+		.device_id	= PCI_DEVICE_ID_KN266,	// 0x3156
+		.chipset_name	= "KN266/PN266",
+	},	*/
+
+	/* VT8754 */
 	{
 		.device_id	= PCI_DEVICE_ID_VIA_8754,
-		.chipset	= VIA_P4X,
 		.chipset_name	= "Apollo P4X333/P4X400"
 	},
+
+	/* P4N333 */
+/*	{
+		.device_id	= PCI_DEVICE_ID_VIA_P4N333,	// 0x3178
+		.chipset_name	= "P4N333",
+	}, */
+
+	/* P4X600 */
+/*	{
+		.device_id	= PCI_DEVICE_ID_VIA_P4X600,	// 0x0198
+		.chipset_name	= "P4X600",
+	},	*/
+
+	/* KM400 */
+/*	{
+		.device_id	= PCI_DEVICE_ID_VIA_KM400,	// 0x3205
+		.chipset_name	= "KM400",
+	},	*/
+
+	/* P4M400 */
+/*	{
+		.device_id	= PCI_DEVICE_ID_VIA_P4M400,	// 0x3209
+		.chipset_name	= "PM400",
+	},	*/
+
 	{ }, /* dummy final entry, always present */
 };
 
@@ -221,7 +430,7 @@
 	while (devs[j].chipset_name != NULL) {
 		if (pdev->device == devs[j].device_id) {
 			printk (KERN_INFO PFX "Detected VIA %s chipset\n", devs[j].chipset_name);
-			agp_bridge.type = devs[j].chipset;
+			agp_bridge->type = VIA_GENERIC;
 
 			if (devs[j].chipset_setup != NULL)
 				return devs[j].chipset_setup(pdev);
@@ -235,7 +444,7 @@
 	if (agp_try_unsupported) {
 		printk(KERN_WARNING PFX "Trying generic VIA routines"
 		       " for device id: %04x\n", pdev->device);
-		agp_bridge.type = VIA_GENERIC;
+		agp_bridge->type = VIA_GENERIC;
 		return via_generic_setup(pdev);
 	}
 
@@ -244,10 +453,12 @@
 	return -ENODEV;
 }
 
+
 static struct agp_driver via_agp_driver = {
 	.owner = THIS_MODULE,
 };
 
+
 static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
 	u8 cap_ptr = 0;
@@ -258,10 +469,10 @@
 
 	/* probe for known chipsets */
 	if (agp_lookup_host_bridge (dev) != -ENODEV) {
-		agp_bridge.dev = dev;
-		agp_bridge.capndx = cap_ptr;
+		agp_bridge->dev = dev;
+		agp_bridge->capndx = cap_ptr;
 		/* Fill in the mode register */
-		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
+		pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode);
 		via_agp_driver.dev = dev;
 		agp_register_driver(&via_agp_driver);
 		return 0;
@@ -269,6 +480,7 @@
 	return -ENODEV;	
 }
 
+
 static struct pci_device_id agp_via_pci_table[] __initdata = {
 	{
 	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
@@ -283,31 +495,36 @@
 
 MODULE_DEVICE_TABLE(pci, agp_via_pci_table);
 
+
 static struct __initdata pci_driver agp_via_pci_driver = {
 	.name		= "agpgart-via",
 	.id_table	= agp_via_pci_table,
 	.probe		= agp_via_probe,
 };
 
+
 static int __init agp_via_init(void)
 {
 	int ret_val;
 
 	ret_val = pci_module_init(&agp_via_pci_driver);
 	if (ret_val)
-		agp_bridge.type = NOT_SUPPORTED;
+		agp_bridge->type = NOT_SUPPORTED;
 
 	return ret_val;
 }
 
+
 static void __exit agp_via_cleanup(void)
 {
 	agp_unregister_driver(&via_agp_driver);
 	pci_unregister_driver(&agp_via_pci_driver);
 }
 
+
 module_init(agp_via_init);
 module_exit(agp_via_cleanup);
 
 MODULE_PARM(agp_try_unsupported, "1i");
 MODULE_LICENSE("GPL and additional rights");
+MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
diff -Nru a/drivers/char/agp/via-kt400.c b/drivers/char/agp/via-kt400.c
--- a/drivers/char/agp/via-kt400.c	Fri Feb 14 15:53:12 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,202 +0,0 @@
-/*
- * VIA KT400 AGPGART routines. 
- *
- * The KT400 does magick to put the AGP bridge compliant with the same
- * standards version as the graphics card. If we haven't fallen into
- * 2.0 compatability mode, we run this code. Otherwise, we run the
- * code in via-agp.c
- */
-
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/agp_backend.h>
-#include "agp.h"
-
-static int via_fetch_size(void)
-{
-	int i;
-	u8 temp;
-	struct aper_size_info_16 *values;
-
-	values = A_SIZE_16(agp_bridge.aperture_sizes);
-	pci_read_config_byte(agp_bridge.dev, VIA_AGP3_APSIZE, &temp);
-	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
-		if (temp == values[i].size_value) {
-			agp_bridge.previous_size =
-			agp_bridge.current_size = (void *) (values + i);
-			agp_bridge.aperture_size_idx = i;
-			return values[i].size;
-		}
-	}
-	return 0;
-}
-
-static int via_configure(void)
-{
-	u32 temp;
-	struct aper_size_info_16 *current_size;
-    
-	current_size = A_SIZE_16(agp_bridge.current_size);
-
-	/* address to map too */
-	pci_read_config_dword(agp_bridge.dev, VIA_APBASE, &temp);
-	agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
-
-	/* attbase - aperture GATT base */
-	pci_write_config_dword(agp_bridge.dev, VIA_AGP3_ATTBASE,
-		agp_bridge.gatt_bus_addr & 0xfffff000);
-	return 0;
-}
-
-static void via_cleanup(void)
-{
-	struct aper_size_info_16 *previous_size;
-
-	previous_size = A_SIZE_16(agp_bridge.previous_size);
-	pci_write_config_byte(agp_bridge.dev, VIA_APSIZE, previous_size->size_value);
-}
-
-static void via_tlbflush(agp_memory * mem)
-{
-	u32 temp;
-
-	pci_read_config_dword(agp_bridge.dev, VIA_AGP3_GARTCTRL, &temp);
-	pci_write_config_dword(agp_bridge.dev, VIA_AGP3_GARTCTRL, temp & ~(1<<7));
-	pci_write_config_dword(agp_bridge.dev, VIA_AGP3_GARTCTRL, temp);
-}
-
-static unsigned long via_mask_memory(unsigned long addr, int type)
-{
-	/* Memory type is ignored */
-
-	return addr | agp_bridge.masks[0].mask;
-}
-
-static struct aper_size_info_16 via_generic_sizes[11] =
-{
-	{ 4,     1024,  0, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3|1<<2|1<<1|1<<0 },
-	{ 8,     2048,  1, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3|1<<2|1<<1},
-	{ 16,    4096,  2, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3|1<<2},
-	{ 32,    8192,  3, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4|1<<3},
-	{ 64,   16384,  4, 1<<11|1<<10|1<<9|1<<8|1<<5|1<<4},
-	{ 128,  32768,  5, 1<<11|1<<10|1<<9|1<<8|1<<5},
-	{ 256,  65536,  6, 1<<11|1<<10|1<<9|1<<8},
-	{ 512,  131072, 7, 1<<11|1<<10|1<<9},
-	{ 1024, 262144, 8, 1<<11|1<<10},
-	{ 2048, 524288, 9, 1<<11}	/* 2GB <- Max supported */
-};
-
-static struct gatt_mask via_generic_masks[] =
-{
-	{.mask = 0x00000000, .type = 0}
-};
-
-
-static void __init via_kt400_enable(u32 mode)
-{
-	if ((agp_generic_agp_3_0_enable(mode))==FALSE)
-		printk (KERN_INFO PFX "agp_generic_agp_3_0_enable() failed\n");
-}
-
-static struct agp_driver via_kt400_agp_driver = {
-	.owner = THIS_MODULE,
-};
-
-static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent)
-{
-	u8 reg;
-	u8 cap_ptr = 0;
-
-	cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
-	if (cap_ptr == 0)
-		return -ENODEV;
-
-	pci_read_config_byte(dev, VIA_AGPSEL, &reg);
-	/* Check if we are in AGP 2.0 compatability mode, if so it
-	 * will be picked up by via-agp.o */
-	if ((reg & (1<<1))==1)
-		return -ENODEV;
-
-	printk (KERN_INFO PFX "Detected VIA KT400 AGP3 chipset\n");
-
-	agp_bridge.dev = dev;
-	agp_bridge.type = VIA_APOLLO_KT400_3;
-	agp_bridge.capndx = cap_ptr;
-	agp_bridge.masks = via_generic_masks;
-	agp_bridge.aperture_sizes = (void *) via_generic_sizes;
-	agp_bridge.size_type = U8_APER_SIZE;
-	agp_bridge.num_aperture_sizes = 7;
-	agp_bridge.dev_private_data = NULL;
-	agp_bridge.needs_scratch_page = FALSE;
-	agp_bridge.agp_enable = via_kt400_enable;
-	agp_bridge.configure = via_configure;
-	agp_bridge.fetch_size = via_fetch_size;
-	agp_bridge.cleanup = via_cleanup;
-	agp_bridge.tlb_flush = via_tlbflush;
-	agp_bridge.mask_memory = via_mask_memory;
-	agp_bridge.cache_flush = global_cache_flush;
-	agp_bridge.create_gatt_table = agp_generic_create_gatt_table;
-	agp_bridge.free_gatt_table = agp_generic_free_gatt_table;
-	agp_bridge.insert_memory = agp_generic_insert_memory;
-	agp_bridge.remove_memory = agp_generic_remove_memory;
-	agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
-	agp_bridge.free_by_type = agp_generic_free_by_type;
-	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
-	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
-	agp_bridge.suspend = agp_generic_suspend;
-	agp_bridge.resume = agp_generic_resume;
-	agp_bridge.cant_use_aperture = 0;
-
-	/* Fill in the mode register */
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
-
-	via_kt400_agp_driver.dev = dev;
-	agp_register_driver(&via_kt400_agp_driver);
-	return 0;
-}
-
-static struct pci_device_id agp_via_pci_table[] __initdata = {
-	{
-	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
-	.class_mask	= ~0,
-	.vendor		= PCI_VENDOR_ID_VIA,
-	.device		= PCI_DEVICE_ID_VIA_8377_0,
-	.subvendor	= PCI_ANY_ID,
-	.subdevice	= PCI_ANY_ID,
-	},
-	{ }
-};
-
-MODULE_DEVICE_TABLE(pci, agp_via_pci_table);
-
-static struct __initdata pci_driver agp_via_pci_driver = {
-	.name		= "agpgart-via",
-	.id_table	= agp_via_pci_table,
-	.probe		= agp_via_probe,
-};
-
-static int __init agp_via_init(void)
-{
-	int ret_val;
-
-	ret_val = pci_module_init(&agp_via_pci_driver);
-	if (ret_val)
-		agp_bridge.type = NOT_SUPPORTED;
-
-	return ret_val;
-}
-
-static void __exit agp_via_cleanup(void)
-{
-	agp_unregister_driver(&via_kt400_agp_driver);
-	pci_unregister_driver(&agp_via_pci_driver);
-}
-
-module_init(agp_via_init);
-module_exit(agp_via_cleanup);
-
-MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
-MODULE_LICENSE("GPL and additional rights");
-
diff -Nru a/drivers/char/ec3104_keyb.c b/drivers/char/ec3104_keyb.c
--- a/drivers/char/ec3104_keyb.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/ec3104_keyb.c	Fri Feb 14 15:53:09 2003
@@ -376,8 +376,6 @@
 	struct e5_struct *k = &ec3104_keyb;
 	u8 msr, lsr;
 
-	kbd_pt_regs = regs;
-
 	msr = ctrl_inb(EC3104_SER4_MSR);
 	
 	if ((msr & MSR_CTS) && !(k->last_msr & MSR_CTS)) {
diff -Nru a/drivers/char/ftape/lowlevel/ftape-read.c b/drivers/char/ftape/lowlevel/ftape-read.c
--- a/drivers/char/ftape/lowlevel/ftape-read.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/char/ftape/lowlevel/ftape-read.c	Fri Feb 14 15:53:08 2003
@@ -589,6 +589,8 @@
 		(max_floppy_track != 254 || max_floppy_sector != 128))
 #endif
 	   ) {
+		char segperheadz = ftape_segments_per_head ? ' ' : '?';
+		char segpercylz  = ftape_segments_per_cylinder ? ' ' : '?';
 		TRACE(ft_t_err,"Tape parameters inconsistency, please report");
 		TRACE(ft_t_err, "reported = %d/%d/%d/%d/%d/%d",
 		      ft_format_code,
@@ -597,14 +599,20 @@
 		      max_floppy_side,
 		      max_floppy_track,
 		      max_floppy_sector);
-		TRACE(ft_t_err, "required = %d/%d/%d/%d/%d/%d",
+		TRACE(ft_t_err, "required = %d/%d/%d/%d%c/%d%c/%d",
 		      ft_format_code,
 		      ft_segments_per_track,
 		      ft_tracks_per_tape,
+		      ftape_segments_per_head ?
 		      ((ft_segments_per_track * ft_tracks_per_tape -1) / 
-		       ftape_segments_per_head ),
+		       ftape_segments_per_head ) :
+			(ft_segments_per_track * ft_tracks_per_tape -1),
+			segperheadz,
+		      ftape_segments_per_cylinder ?
 		      (ftape_segments_per_head / 
-		       ftape_segments_per_cylinder - 1 ),
+		       ftape_segments_per_cylinder - 1 ) :
+			ftape_segments_per_head - 1,
+			segpercylz,
 		      (ftape_segments_per_cylinder * FT_SECTORS_PER_SEGMENT));
 		TRACE_EXIT -EIO;
 	}
diff -Nru a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
--- a/drivers/char/hvc_console.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/hvc_console.c	Fri Feb 14 15:53:12 2003
@@ -233,9 +233,7 @@
 {
 	int i;
 
-	daemonize();
-	strcpy(current->comm, "khvcd");
-	sigfillset(&current->blocked);
+	daemonize("khvcd");
 
 	for (;;) {
 		if (!cpus_in_xmon) {
diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- a/drivers/char/keyboard.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/keyboard.c	Fri Feb 14 15:53:09 2003
@@ -48,24 +48,22 @@
  * Exported functions/variables
  */
 
-#ifndef KBD_DEFMODE
 #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
-#endif
 
-#ifndef KBD_DEFLEDS
 /*
  * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
- * This seems a good reason to start with NumLock off.
+ * This seems a good reason to start with NumLock off. On PC9800 however there
+ * is no NumLock key and everyone expects the keypad to be used for numbers.
  */
+
+#ifdef CONFIG_X86_PC9800
+#define KBD_DEFLEDS (1 << VC_NUMLOCK)
+#else
 #define KBD_DEFLEDS 0
 #endif
 
-#ifndef KBD_DEFLOCK
 #define KBD_DEFLOCK 0
-#endif
 
-struct pt_regs *kbd_pt_regs;
-EXPORT_SYMBOL(kbd_pt_regs);
 void compute_shiftstate(void);
 
 /*
@@ -79,7 +77,7 @@
 	k_slock,	k_dead2,	k_ignore,	k_ignore
 
 typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value, 
-			    char up_flag);
+			    char up_flag, struct pt_regs *regs);
 static k_handler_fn K_HANDLERS;
 static k_handler_fn *k_handler[16] = { K_HANDLERS };
 
@@ -90,7 +88,7 @@
 	fn_boot_it, 	fn_caps_on, 	fn_compose,	fn_SAK,\
 	fn_dec_console, fn_inc_console, fn_spawn_con, 	fn_bare_num
 
-typedef void (fn_handler_fn)(struct vc_data *vc);
+typedef void (fn_handler_fn)(struct vc_data *vc, struct pt_regs *regs);
 static fn_handler_fn FN_HANDLERS;
 static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
 
@@ -422,7 +420,7 @@
 /*
  * Special function handlers
  */
-static void fn_enter(struct vc_data *vc)
+static void fn_enter(struct vc_data *vc, struct pt_regs *regs)
 {
 	if (diacr) {
 		put_queue(vc, diacr);
@@ -433,27 +431,27 @@
 		put_queue(vc, 10);
 }
 
-static void fn_caps_toggle(struct vc_data *vc)
+static void fn_caps_toggle(struct vc_data *vc, struct pt_regs *regs)
 {
 	if (rep)
 		return;
 	chg_vc_kbd_led(kbd, VC_CAPSLOCK);
 }
 
-static void fn_caps_on(struct vc_data *vc)
+static void fn_caps_on(struct vc_data *vc, struct pt_regs *regs)
 {
 	if (rep)
 		return;
 	set_vc_kbd_led(kbd, VC_CAPSLOCK);
 }
 
-static void fn_show_ptregs(struct vc_data *vc)
+static void fn_show_ptregs(struct vc_data *vc, struct pt_regs *regs)
 {
-	if (kbd_pt_regs)
-		show_regs(kbd_pt_regs);
+	if (regs)
+		show_regs(regs);
 }
 
-static void fn_hold(struct vc_data *vc)
+static void fn_hold(struct vc_data *vc, struct pt_regs *regs)
 {
 	struct tty_struct *tty = vc->vc_tty;
 
@@ -471,12 +469,12 @@
 		stop_tty(tty);
 }
 
-static void fn_num(struct vc_data *vc)
+static void fn_num(struct vc_data *vc, struct pt_regs *regs)
 {
 	if (vc_kbd_mode(kbd,VC_APPLIC))
 		applkey(vc, 'P', 1);
 	else
-		fn_bare_num(vc);
+		fn_bare_num(vc, regs);
 }
 
 /*
@@ -485,19 +483,19 @@
  * Bind this to NumLock if you prefer that the NumLock key always
  * changes the NumLock flag.
  */
-static void fn_bare_num(struct vc_data *vc)
+static void fn_bare_num(struct vc_data *vc, struct pt_regs *regs)
 {
 	if (!rep)
 		chg_vc_kbd_led(kbd, VC_NUMLOCK);
 }
 
-static void fn_lastcons(struct vc_data *vc)
+static void fn_lastcons(struct vc_data *vc, struct pt_regs *regs)
 {
 	/* switch to the last used console, ChN */
 	set_console(last_console);
 }
 
-static void fn_dec_console(struct vc_data *vc)
+static void fn_dec_console(struct vc_data *vc, struct pt_regs *regs)
 {
 	int i;
  
@@ -510,7 +508,7 @@
 	set_console(i);
 }
 
-static void fn_inc_console(struct vc_data *vc)
+static void fn_inc_console(struct vc_data *vc, struct pt_regs *regs)
 {
 	int i;
 
@@ -523,7 +521,7 @@
 	set_console(i);
 }
 
-static void fn_send_intr(struct vc_data *vc)
+static void fn_send_intr(struct vc_data *vc, struct pt_regs *regs)
 {
 	struct tty_struct *tty = vc->vc_tty;
 
@@ -533,44 +531,44 @@
 	con_schedule_flip(tty);
 }
 
-static void fn_scroll_forw(struct vc_data *vc)
+static void fn_scroll_forw(struct vc_data *vc, struct pt_regs *regs)
 {
 	scrollfront(0);
 }
 
-static void fn_scroll_back(struct vc_data *vc)
+static void fn_scroll_back(struct vc_data *vc, struct pt_regs *regs)
 {
 	scrollback(0);
 }
 
-static void fn_show_mem(struct vc_data *vc)
+static void fn_show_mem(struct vc_data *vc, struct pt_regs *regs)
 {
 	show_mem();
 }
 
-static void fn_show_state(struct vc_data *vc)
+static void fn_show_state(struct vc_data *vc, struct pt_regs *regs)
 {
 	show_state();
 }
 
-static void fn_boot_it(struct vc_data *vc)
+static void fn_boot_it(struct vc_data *vc, struct pt_regs *regs)
 {
 	ctrl_alt_del();
 }
 
-static void fn_compose(struct vc_data *vc)
+static void fn_compose(struct vc_data *vc, struct pt_regs *regs)
 {
 	dead_key_next = 1;
 }
 
-static void fn_spawn_con(struct vc_data *vc)
+static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs)
 {
         if (spawnpid)
 	   if(kill_proc(spawnpid, spawnsig, 1))
 	     spawnpid = 0;
 }
 
-static void fn_SAK(struct vc_data *vc)
+static void fn_SAK(struct vc_data *vc, struct pt_regs *regs)
 {
 	struct tty_struct *tty = vc->vc_tty;
 
@@ -583,7 +581,7 @@
 	reset_vc(fg_console);
 }
 
-static void fn_null(struct vc_data *vc)
+static void fn_null(struct vc_data *vc, struct pt_regs *regs)
 {
 	compute_shiftstate();
 }
@@ -591,11 +589,11 @@
 /*
  * Special key handlers
  */
-static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 }
 
-static void k_spec(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_spec(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 	if (up_flag)
 		return;
@@ -605,15 +603,15 @@
 	     kbd->kbdmode == VC_MEDIUMRAW) && 
 	     value != K_SAK)
 		return;		/* SAK is allowed even in raw mode */
-	fn_handler[value](vc);
+	fn_handler[value](vc, regs);
 }
 
-static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 	printk(KERN_ERR "keyboard.c: k_lowercase was called - impossible\n");
 }
 
-static void k_self(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 	if (up_flag)
 		return;		/* no action, if this is a key release */
@@ -634,7 +632,7 @@
  * dead keys modifying the same character. Very useful
  * for Vietnamese.
  */
-static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 	if (up_flag)
 		return;
@@ -644,21 +642,21 @@
 /*
  * Obsolete - for backwards compatibility only
  */
-static void k_dead(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_dead(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 	static unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' };
 	value = ret_diacr[value];
-	k_dead2(vc, value, up_flag);
+	k_dead2(vc, value, up_flag, regs);
 }
 
-static void k_cons(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_cons(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 	if (up_flag)
 		return;
 	set_console(value);
 }
 
-static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_fn(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 	if (up_flag)
 		return;
@@ -669,7 +667,7 @@
 		printk(KERN_ERR "k_fn called with value=%d\n", value);
 }
 
-static void k_cur(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_cur(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 	static const char *cur_chars = "BDCA";
 
@@ -678,7 +676,7 @@
 	applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));
 }
 
-static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_pad(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 	static const char *pad_chars = "0123456789+-*/\015,.?()#";
 	static const char *app_map = "pqrstuvwxylSRQMnnmPQS";
@@ -696,34 +694,34 @@
 		switch (value) {
 			case KVAL(K_PCOMMA):
 			case KVAL(K_PDOT):
-				k_fn(vc, KVAL(K_REMOVE), 0);
+				k_fn(vc, KVAL(K_REMOVE), 0, regs);
 				return;
 			case KVAL(K_P0):
-				k_fn(vc, KVAL(K_INSERT), 0);
+				k_fn(vc, KVAL(K_INSERT), 0, regs);
 				return;
 			case KVAL(K_P1):
-				k_fn(vc, KVAL(K_SELECT), 0);
+				k_fn(vc, KVAL(K_SELECT), 0, regs);
 				return;
 			case KVAL(K_P2):
-				k_cur(vc, KVAL(K_DOWN), 0);
+				k_cur(vc, KVAL(K_DOWN), 0, regs);
 				return;
 			case KVAL(K_P3):
-				k_fn(vc, KVAL(K_PGDN), 0);
+				k_fn(vc, KVAL(K_PGDN), 0, regs);
 				return;
 			case KVAL(K_P4):
-				k_cur(vc, KVAL(K_LEFT), 0);
+				k_cur(vc, KVAL(K_LEFT), 0, regs);
 				return;
 			case KVAL(K_P6):
-				k_cur(vc, KVAL(K_RIGHT), 0);
+				k_cur(vc, KVAL(K_RIGHT), 0, regs);
 				return;
 			case KVAL(K_P7):
-				k_fn(vc, KVAL(K_FIND), 0);
+				k_fn(vc, KVAL(K_FIND), 0, regs);
 				return;
 			case KVAL(K_P8):
-				k_cur(vc, KVAL(K_UP), 0);
+				k_cur(vc, KVAL(K_UP), 0, regs);
 				return;
 			case KVAL(K_P9):
-				k_fn(vc, KVAL(K_PGUP), 0);
+				k_fn(vc, KVAL(K_PGUP), 0, regs);
 				return;
 			case KVAL(K_P5):
 				applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC));
@@ -735,7 +733,7 @@
 		put_queue(vc, 10);
 }
 
-static void k_shift(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_shift(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 	int old_state = shift_state;
 
@@ -776,7 +774,7 @@
 	}
 }
 
-static void k_meta(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_meta(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 	if (up_flag)
 		return;
@@ -788,7 +786,7 @@
 		put_queue(vc, value | 0x80);
 }
 
-static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 	int base;
 
@@ -810,16 +808,16 @@
 		npadch = npadch * base + value;
 }
 
-static void k_lock(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_lock(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
 	if (up_flag || rep)
 		return;
 	chg_vc_kbd_lock(kbd, value);
 }
 
-static void k_slock(struct vc_data *vc, unsigned char value, char up_flag)
+static void k_slock(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
 {
-	k_shift(vc, value, up_flag);
+	k_shift(vc, value, up_flag, regs);
 	if (up_flag || rep)
 		return;
 	chg_vc_kbd_slock(kbd, value);
@@ -894,9 +892,9 @@
  * Aside from timing (which isn't really that important for
  * keyboard interrupts as they happen often), using the software
  * interrupt routines for this thing allows us to easily mask
- * this when we don't want any of the above to happen. Not yet
- * used, but this allows for easy and efficient race-condition
- * prevention later on.
+ * this when we don't want any of the above to happen.
+ * This allows for easy and efficient race-condition prevention
+ * for kbd_refresh_leds => input_event(dev, EV_LED, ...) => ...
  */
 
 static void kbd_bh(unsigned long dummy)
@@ -910,6 +908,7 @@
 			input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
 			input_event(handle->dev, EV_LED, LED_NUML,    !!(leds & 0x02));
 			input_event(handle->dev, EV_LED, LED_CAPSL,   !!(leds & 0x04));
+			input_sync(handle->dev);
 		}
 	}
 
@@ -918,6 +917,23 @@
 
 DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
 
+/*
+ * This allows a newly plugged keyboard to pick the LED state.
+ */
+void kbd_refresh_leds(struct input_handle *handle)
+{
+	unsigned char leds = ledstate;
+
+	tasklet_disable(&keyboard_tasklet);
+	if (leds != 0xff) {
+		input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
+		input_event(handle->dev, EV_LED, LED_NUML,    !!(leds & 0x02));
+		input_event(handle->dev, EV_LED, LED_CAPSL,   !!(leds & 0x04));
+		input_sync(handle->dev);
+	}
+	tasklet_enable(&keyboard_tasklet);
+}
+
 #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) || defined(CONFIG_PARISC)
 
 static unsigned short x86_keycodes[256] =
@@ -996,7 +1012,7 @@
 }
 #endif
 
-void kbd_keycode(unsigned int keycode, int down)
+void kbd_keycode(unsigned int keycode, int down, struct pt_regs *regs)
 {
 	struct vc_data *vc = vc_cons[fg_console].d;
 	unsigned short keysym, *key_map;
@@ -1027,7 +1043,8 @@
 
 	if ((raw_mode = (kbd->kbdmode == VC_RAW)))
 		if (emulate_raw(vc, keycode, !down << 7))
-			printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
+			if (keycode < BTN_MISC)
+				printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
 
 #ifdef CONFIG_MAGIC_SYSRQ	       /* Handle the SysRq Hack */
 	if (keycode == KEY_SYSRQ && !rep) {
@@ -1035,7 +1052,7 @@
 		return;
 	}
 	if (sysrq_down && down && !rep) {
-		handle_sysrq(kbd_sysrq_xlate[keycode], kbd_pt_regs, tty);
+		handle_sysrq(kbd_sysrq_xlate[keycode], regs, tty);
 		return;
 	}
 #endif
@@ -1112,7 +1129,7 @@
 		}
 	}
 
-	(*k_handler[type])(vc, keysym & 0xff, !down);
+	(*k_handler[type])(vc, keysym & 0xff, !down, regs);
 
 	if (type != KT_SLOCK)
 		kbd->slockstate = 0;
@@ -1123,7 +1140,7 @@
 {
 	if (event_type != EV_KEY)
 		return;
-	kbd_keycode(keycode, down);
+	kbd_keycode(keycode, down, handle->dev->regs);
 	tasklet_schedule(&keyboard_tasklet);
 	do_poke_blanked_console = 1;
 	schedule_console_callback();
@@ -1159,6 +1176,7 @@
 	handle->name = kbd_name;
 
 	input_open_device(handle);
+	kbd_refresh_leds(handle);
 
 	return handle;
 }
diff -Nru a/drivers/char/misc.c b/drivers/char/misc.c
--- a/drivers/char/misc.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/misc.c	Fri Feb 14 15:53:12 2003
@@ -50,8 +50,6 @@
 #include <linux/tty.h>
 #include <linux/kmod.h>
 
-#include "busmouse.h"
-
 /*
  * Head entry for the doubly linked miscdevice list
  */
@@ -64,7 +62,6 @@
 #define DYNAMIC_MINORS 64 /* like dynamic majors */
 static unsigned char misc_minors[DYNAMIC_MINORS / 8];
 
-extern int psaux_init(void);
 #ifdef CONFIG_SGI_NEWPORT_GFX
 extern void gfx_register(void);
 #endif
diff -Nru a/drivers/char/moxa.c b/drivers/char/moxa.c
--- a/drivers/char/moxa.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/moxa.c	Fri Feb 14 15:53:12 2003
@@ -2832,7 +2832,7 @@
 
 	st = jiffies;
 	et = st + tick;
-	while (jiffies < et);
+	while (time_before(jiffies, et));
 }
 
 static void moxafunc(unsigned long ofsAddr, int cmd, ushort arg)
diff -Nru a/drivers/char/mxser.c b/drivers/char/mxser.c
--- a/drivers/char/mxser.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/mxser.c	Fri Feb 14 15:53:12 2003
@@ -857,7 +857,7 @@
 		while (!(inb(info->base + UART_LSR) & UART_LSR_TEMT)) {
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(5);
-			if (jiffies > timeout)
+			if (time_after(jiffies, timeout))
 				break;
 		}
 	}
diff -Nru a/drivers/char/n_tty.c b/drivers/char/n_tty.c
--- a/drivers/char/n_tty.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/char/n_tty.c	Fri Feb 14 15:53:08 2003
@@ -23,6 +23,11 @@
  * 2000/01/20   Fixed SMP locking on put_tty_queue using bits of 
  *		the patch by Andrew J. Kroll <ag784@freenet.buffalo.edu>
  *		who actually finally proved there really was a race.
+ *
+ * 2002/03/18   Implemented n_tty_wakeup to send SIGIO POLL_OUTs to
+ *		waiting writing processes-Sapan Bhatia <sapan@corewars.org>.
+ *		Also fixed a bug in BLOCKING mode where write_chan returns
+ *		EAGAIN
  */
 
 #include <linux/types.h>
@@ -707,6 +712,22 @@
 	return 0;
 }
 
+/*
+ * Required for the ptys, serial driver etc. since processes
+ * that attach themselves to the master and rely on ASYNC
+ * IO must be woken up
+ */
+
+static void n_tty_write_wakeup(struct tty_struct *tty)
+{
+	if (tty->fasync)
+	{
+ 		set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+		kill_fasync(&tty->fasync, SIGIO, POLL_OUT);
+	}
+	return;
+}
+
 static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
 			      char *fp, int count)
 {
@@ -1156,6 +1177,8 @@
 			while (nr > 0) {
 				ssize_t num = opost_block(tty, b, nr);
 				if (num < 0) {
+					if (num == -EAGAIN)
+						break;
 					retval = num;
 					goto break_out;
 				}
@@ -1235,6 +1258,6 @@
 	normal_poll,		/* poll */
 	n_tty_receive_buf,	/* receive_buf */
 	n_tty_receive_room,	/* receive_room */
-	0			/* write_wakeup */
+	n_tty_write_wakeup	/* write_wakeup */
 };
 
diff -Nru a/drivers/char/nvram.c b/drivers/char/nvram.c
--- a/drivers/char/nvram.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/nvram.c	Fri Feb 14 15:53:09 2003
@@ -231,8 +231,7 @@
  * The are the file operation function for user access to /dev/nvram
  */
 
-static long long
-nvram_llseek(struct file *file, loff_t offset, int origin)
+static loff_t nvram_llseek(struct file *file,loff_t offset, int origin )
 {
 	lock_kernel();
 	switch (origin) {
diff -Nru a/drivers/char/nwflash.c b/drivers/char/nwflash.c
--- a/drivers/char/nwflash.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/nwflash.c	Fri Feb 14 15:53:12 2003
@@ -47,7 +47,7 @@
 static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg);
 static ssize_t flash_read(struct file *file, char *buf, size_t count, loff_t * ppos);
 static ssize_t flash_write(struct file *file, const char *buf, size_t count, loff_t * ppos);
-static long long flash_llseek(struct file *file, long long offset, int orig);
+static loff_t flash_llseek(struct file *file, loff_t offset, int orig);
 
 #define KFLASH_SIZE	1024*1024	//1 Meg
 #define KFLASH_SIZE4	4*1024*1024	//4 Meg
@@ -301,9 +301,9 @@
  * also note that seeking relative to the "end of file" isn't supported:
  * it has no meaning, so it returns -EINVAL.
  */
-static long long flash_llseek(struct file *file, long long offset, int orig)
+static loff_t flash_llseek(struct file *file, loff_t offset, int orig)
 {
-	long long ret;
+	loff_t ret;
 
 	lock_kernel();
 	if (flashdebug)
diff -Nru a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c
--- a/drivers/char/rio/rioroute.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/char/rio/rioroute.c	Fri Feb 14 15:53:10 2003
@@ -763,7 +763,7 @@
 #endif
 	UnitId--;		/* this trick relies on the Unit Id being UNSIGNED! */
 
-	if ( UnitId > MAX_RUP )		/* dontcha just lurv unsigned maths! */
+	if ( UnitId >= MAX_RUP )	/* dontcha just lurv unsigned maths! */
 		return(0);
 
 	if ( HostP->Mapping[UnitId].Flags & BEEN_HERE )
diff -Nru a/drivers/char/riscom8.c b/drivers/char/riscom8.c
--- a/drivers/char/riscom8.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/riscom8.c	Fri Feb 14 15:53:09 2003
@@ -1090,7 +1090,7 @@
 	unsigned long flags;
 	
 	board = RC_BOARD(minor(tty->device));
-	if (board > RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT))
+	if (board >= RC_NBOARD || !(rc_board[board].flags & RC_BOARD_PRESENT))
 		return -ENODEV;
 	
 	bp = &rc_board[board];
diff -Nru a/drivers/char/specialix.c b/drivers/char/specialix.c
--- a/drivers/char/specialix.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/specialix.c	Fri Feb 14 15:53:12 2003
@@ -1456,7 +1456,7 @@
 	
 	board = SX_BOARD(minor(tty->device));
 
-	if (board > SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT))
+	if (board >= SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT))
 		return -ENODEV;
 	
 	bp = &sx_board[board];
@@ -2363,7 +2363,7 @@
 		struct pci_dev *pdev = NULL;
 
 		i=0;
-		while (i <= SX_NBOARD) {
+		while (i < SX_NBOARD) {
 			if (sx_board[i].flags & SX_BOARD_PRESENT) {
 				i++;
 				continue;
diff -Nru a/drivers/char/sx.c b/drivers/char/sx.c
--- a/drivers/char/sx.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/sx.c	Fri Feb 14 15:53:09 2003
@@ -1689,7 +1689,7 @@
 	switch (cmd) {
 	case SXIO_SET_BOARD:
 		sx_dprintk (SX_DEBUG_FIRMWARE, "set board to %ld\n", arg);
-		if (arg > SX_NBOARDS) return -EIO;
+		if (arg >= SX_NBOARDS) return -EIO;
 		sx_dprintk (SX_DEBUG_FIRMWARE, "not out of range\n");
 		if (!(boards[arg].flags	& SX_BOARD_PRESENT)) return -EIO;
 		sx_dprintk (SX_DEBUG_FIRMWARE, ".. and present!\n");
diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c
--- a/drivers/char/tty_io.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/char/tty_io.c	Fri Feb 14 15:53:11 2003
@@ -578,7 +578,7 @@
  */
 void disassociate_ctty(int on_exit)
 {
-	struct tty_struct *tty = current->tty;
+	struct tty_struct *tty;
 	struct task_struct *p;
 	struct list_head *l;
 	struct pid *pid;
@@ -586,6 +586,7 @@
 
 	lock_kernel();
 
+	tty = current->tty;
 	if (tty) {
 		tty_pgrp = tty->pgrp;
 		if (on_exit && tty->driver.type != TTY_DRIVER_TYPE_PTY)
diff -Nru a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
--- a/drivers/char/watchdog/Kconfig	Fri Feb 14 15:53:11 2003
+++ b/drivers/char/watchdog/Kconfig	Fri Feb 14 15:53:11 2003
@@ -354,4 +354,14 @@
 	  Documentation/modules.txt. The module will be called
 	  wafer5823wdt.o
 
+config CPU5_WDT
+	tristate "SMA CPU5 Watchdog"
+	depends on WATCHDOG
+	---help---
+	  TBD.
+	  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 is called cpu5wdt.o.  If you want to compile it as a
+	  module, say M here and read <file:Documentation/modules.txt>.
+
 endmenu
diff -Nru a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
--- a/drivers/char/watchdog/Makefile	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/watchdog/Makefile	Fri Feb 14 15:53:12 2003
@@ -29,3 +29,4 @@
 obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
 obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
 obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
+obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o
diff -Nru a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c
--- a/drivers/char/watchdog/acquirewdt.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/char/watchdog/acquirewdt.c	Fri Feb 14 15:53:11 2003
@@ -220,7 +220,7 @@
 
 static int __init acq_init(void)
 {
-	printk("WDT driver for Acquire single board computer initialising.\n");
+	printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n");
 
 	spin_lock_init(&acq_lock);
 	if (misc_register(&acq_miscdev))
diff -Nru a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c
--- a/drivers/char/watchdog/alim7101_wdt.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/watchdog/alim7101_wdt.c	Fri Feb 14 15:53:12 2003
@@ -100,7 +100,7 @@
 		pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp & ~ALI_WDT_ARM));
 		pci_write_config_byte(alim7101_pmu, ALI_7101_WDT, (tmp | ALI_WDT_ARM));
 	} else {
-		printk(OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n");
+		printk(KERN_INFO OUR_NAME ": Heartbeat lost! Will not ping the watchdog\n");
 	}
 	/* Re-set the timer interval */
 	timer.expires = jiffies + WDT_INTERVAL;
@@ -136,7 +136,7 @@
 	add_timer(&timer);
 
 
-	printk(OUR_NAME ": Watchdog timer is now enabled.\n");  
+	printk(KERN_INFO OUR_NAME ": Watchdog timer is now enabled.\n");  
 }
 
 static void wdt_turnoff(void)
@@ -144,7 +144,7 @@
 	/* Stop the timer */
 	del_timer_sync(&timer);
 	wdt_change(WDT_DISABLE);
-	printk(OUR_NAME ": Watchdog timer is now disabled...\n");
+	printk(KERN_INFO OUR_NAME ": Watchdog timer is now disabled...\n");
 }
 
 /*
@@ -203,7 +203,7 @@
 	if(wdt_expect_close)
 		wdt_turnoff();
 	else
-		printk(OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n");
+		printk(KERN_INFO OUR_NAME ": device file closed unexpectedly. Will not stop the WDT!\n");
 
 	clear_bit(0, &wdt_is_open);
 	return 0;
@@ -262,7 +262,7 @@
 		 * reboot with no heartbeat
 		 */
 		wdt_change(WDT_ENABLE);
-		printk(OUR_NAME ": Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n");
+		printk(KERN_INFO OUR_NAME ": Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second.\n");
 	}
 	return NOTIFY_DONE;
 }
diff -Nru a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/watchdog/cpu5wdt.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,312 @@
+/*
+ * sma cpu5 watchdog driver
+ *
+ * Copyright (C) 2003 Heiko Ronsdorf <hero@ihg.uni-duisburg.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/types.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <linux/watchdog.h>
+
+/* adjustable parameters */
+
+static int verbose = 0;
+static int port = 0x91;
+static volatile int ticks = 10000;
+
+#define PFX			"cpu5wdt: "
+
+#define CPU5WDT_EXTENT          0x0A
+
+#define CPU5WDT_STATUS_REG      0x00
+#define CPU5WDT_TIME_A_REG      0x02
+#define CPU5WDT_TIME_B_REG      0x03
+#define CPU5WDT_MODE_REG        0x04
+#define CPU5WDT_TRIGGER_REG     0x07
+#define CPU5WDT_ENABLE_REG      0x08
+#define CPU5WDT_RESET_REG       0x09
+
+#define CPU5WDT_INTERVAL	(HZ/10+1)
+
+/* some device data */
+
+static struct {
+	struct semaphore stop;
+	volatile int running;
+	struct timer_list timer;
+	volatile int queue;
+	int default_ticks;
+	int min_ticks;
+	unsigned long inuse;
+} cpu5wdt_device;
+
+/* generic helper functions */
+
+static void cpu5wdt_trigger(unsigned long unused)
+{
+	if ( verbose > 2 )
+		printk(KERN_DEBUG PFX "trigger at %i ticks\n", ticks);
+
+	if( cpu5wdt_device.running )
+		ticks--;
+
+	/* keep watchdog alive */
+	outb(1, port + CPU5WDT_TRIGGER_REG);
+
+	/* requeue?? */
+	if( cpu5wdt_device.queue && ticks ) {
+		cpu5wdt_device.timer.expires = jiffies + CPU5WDT_INTERVAL;
+		add_timer(&cpu5wdt_device.timer);
+	}
+	else {
+		/* ticks doesn't matter anyway */
+		up(&cpu5wdt_device.stop);
+	}
+
+}
+
+static void cpu5wdt_reset(void)
+{
+	if ( ticks < cpu5wdt_device.min_ticks )
+		cpu5wdt_device.min_ticks = ticks;
+
+	ticks = cpu5wdt_device.default_ticks;
+
+	if ( verbose )
+		printk(KERN_DEBUG PFX "reset (%i ticks)\n", (int) ticks);
+
+}
+
+static void cpu5wdt_start(void)
+{
+	if ( !cpu5wdt_device.queue ) {
+		cpu5wdt_device.queue = 1;
+		outb(0, port + CPU5WDT_TIME_A_REG);  
+		outb(0, port + CPU5WDT_TIME_B_REG);  
+		outb(1, port + CPU5WDT_MODE_REG);
+		outb(0, port + CPU5WDT_RESET_REG);
+		outb(0, port + CPU5WDT_ENABLE_REG);
+		cpu5wdt_device.timer.expires = jiffies + CPU5WDT_INTERVAL;
+		add_timer(&cpu5wdt_device.timer);
+	}
+	/* if process dies, counter is not decremented */
+	cpu5wdt_device.running++;
+}
+
+static int cpu5wdt_stop(void)
+{
+	if ( cpu5wdt_device.running )
+		cpu5wdt_device.running = 0;
+
+	ticks = cpu5wdt_device.default_ticks;
+
+	if ( verbose )
+		printk(KERN_CRIT PFX "stop not possible\n");
+
+	return -EIO;
+}
+
+/* filesystem operations */
+
+static int cpu5wdt_open(struct inode *inode, struct file *file)
+{
+	switch(minor(inode->i_rdev)) {
+		case WATCHDOG_MINOR:
+			if ( test_and_set_bit(0, &cpu5wdt_device.inuse) )
+				return -EBUSY;
+			break;
+		default:
+			return -ENODEV;
+	}
+	return 0;
+
+}
+
+static int cpu5wdt_release(struct inode *inode, struct file *file)
+{
+	if(minor(inode->i_rdev)==WATCHDOG_MINOR) {
+		clear_bit(0, &cpu5wdt_device.inuse);
+	}
+	return 0;
+}
+
+static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	unsigned int value;
+	static struct watchdog_info ident =
+	{
+		.options = WDIOF_CARDRESET,
+		.identity = "CPU5 WDT"
+	};
+  
+	switch(cmd) {
+		case WDIOC_KEEPALIVE:
+			cpu5wdt_reset();
+			break;
+		case WDIOC_GETSTATUS:    
+			value = inb(port + CPU5WDT_STATUS_REG); 
+			value = (value >> 2) & 1;
+			if ( copy_to_user((int *)arg, (int *)&value, sizeof(int)) )
+				return -EFAULT;
+			break;
+		case WDIOC_GETSUPPORT:
+			if ( copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)) )
+				return -EFAULT;
+			break;
+		case WDIOC_SETOPTIONS:
+			if ( copy_from_user(&value, (int *)arg, sizeof(int)) )
+				return -EFAULT;
+			switch(value) {
+				case WDIOS_ENABLECARD:
+					cpu5wdt_start();
+					break;
+				case WDIOS_DISABLECARD:
+					return cpu5wdt_stop();
+				default:
+					return -EINVAL;
+			}
+			break;
+		default:
+    			return -EINVAL;
+	}
+	return 0;
+}
+
+static ssize_t cpu5wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+	if ( !count )
+		return -EIO;
+	
+	cpu5wdt_reset();
+	return count;
+
+}
+
+static struct file_operations cpu5wdt_fops = {
+	.owner		= THIS_MODULE,
+	.ioctl		= cpu5wdt_ioctl,
+	.open		= cpu5wdt_open,
+	.write		= cpu5wdt_write,
+	.release	= cpu5wdt_release,
+};
+
+static struct miscdevice cpu5wdt_misc = {
+	.minor	= WATCHDOG_MINOR,
+	.name	= "watchdog",
+	.fops	= &cpu5wdt_fops
+};
+
+/* init/exit function */
+
+static int __devinit cpu5wdt_init(void)
+{
+	unsigned int val;
+	int err;
+
+	if ( verbose )
+		printk(KERN_DEBUG PFX "port=0x%x, verbose=%i\n", port, verbose);
+
+	if ( (err = misc_register(&cpu5wdt_misc)) < 0 ) {
+		printk(KERN_ERR PFX "misc_register failed\n");
+		goto no_misc;
+	}
+
+	if ( !request_region(port, CPU5WDT_EXTENT, PFX) ) {
+		printk(KERN_ERR PFX "request_region failed\n");
+		err = -EBUSY;
+		goto no_port;
+	}
+
+	/* watchdog reboot? */
+	val = inb(port + CPU5WDT_STATUS_REG); 
+	val = (val >> 2) & 1;
+	if ( !val )
+		printk(KERN_INFO PFX "sorry, was my fault\n");
+
+	init_MUTEX_LOCKED(&cpu5wdt_device.stop);
+	cpu5wdt_device.queue = 0;
+	cpu5wdt_device.min_ticks = ticks;
+
+	clear_bit(0, &cpu5wdt_device.inuse);
+
+	init_timer(&cpu5wdt_device.timer);
+	cpu5wdt_device.timer.function = cpu5wdt_trigger;
+	cpu5wdt_device.timer.data = 0;
+
+	cpu5wdt_device.default_ticks = ticks;
+
+	printk(KERN_INFO PFX "init success\n");
+
+	return 0;
+
+no_port:
+	misc_deregister(&cpu5wdt_misc);
+no_misc:
+	return err;
+}
+
+static int __devinit cpu5wdt_init_module(void)
+{
+	return cpu5wdt_init();
+}
+
+static void __devexit cpu5wdt_exit(void)
+{
+	if ( cpu5wdt_device.queue ) {
+		cpu5wdt_device.queue = 0;
+		down(&cpu5wdt_device.stop);
+	}
+
+	misc_deregister(&cpu5wdt_misc);
+
+	release_region(port, CPU5WDT_EXTENT);
+
+}
+
+static void __devexit cpu5wdt_exit_module(void)
+{
+	cpu5wdt_exit();
+}
+
+/* module entry points */
+
+module_init(cpu5wdt_init_module);
+module_exit(cpu5wdt_exit_module);
+
+MODULE_AUTHOR("Heiko Ronsdorf <hero@ihg.uni-duisburg.de>");
+MODULE_DESCRIPTION("sma cpu5 watchdog driver");
+MODULE_SUPPORTED_DEVICE("sma cpu5 watchdog");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(port, "i");
+MODULE_PARM_DESC(port, "base address of watchdog card, default is 0x91");
+
+MODULE_PARM(verbose, "i");
+MODULE_PARM_DESC(verbose, "be verbose, default is 0 (no)");
+
+MODULE_PARM(ticks, "i");
+MODULE_PARM_DESC(ticks, "count down ticks, default is 10000");
diff -Nru a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
--- a/drivers/char/watchdog/machzwd.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/watchdog/machzwd.c	Fri Feb 14 15:53:09 2003
@@ -453,9 +453,9 @@
 };
 
 static struct miscdevice zf_miscdev = {
-	WATCHDOG_MINOR,
-	"watchdog",
-	&zf_fops
+	.minor = WATCHDOG_MINOR,
+	.name = "watchdog",
+	.fops = &zf_fops
 };
                                                                         
 
@@ -464,9 +464,9 @@
  * turn the timebomb registers off.
  */
 static struct notifier_block zf_notifier = {
-	zf_notify_sys,
-	NULL,
-	0
+	.notifier_call = zf_notify_sys,
+	.next = NULL,
+	.priority = 0
 };
 
 static void __init zf_show_action(int act)
diff -Nru a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
--- a/drivers/char/watchdog/pcwd.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/char/watchdog/pcwd.c	Fri Feb 14 15:53:08 2003
@@ -56,6 +56,7 @@
 #include <linux/watchdog.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/reboot.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -197,28 +198,30 @@
 
 	if (revision == PCWD_REVISION_A) {
 		if (card_status & WD_WDRST)
-			printk("pcwd: Previous reboot was caused by the card.\n");
+			printk(KERN_INFO "pcwd: Previous reboot was caused by the card.\n");
 
 		if (card_status & WD_T110) {
-			printk("pcwd: Card senses a CPU Overheat.  Panicking!\n");
-			panic("pcwd: CPU Overheat.\n");
+			printk(KERN_EMERG "pcwd: Card senses a CPU Overheat.  Panicking!\n");
+			printk(KERN_EMERG "pcwd: CPU Overheat.\n");
+			machine_power_off();
 		}
 
 		if ((!(card_status & WD_WDRST)) &&
 		    (!(card_status & WD_T110)))
-			printk("pcwd: Cold boot sense.\n");
+			printk(KERN_INFO "pcwd: Cold boot sense.\n");
 	} else {
 		if (card_status & 0x01)
-			printk("pcwd: Previous reboot was caused by the card.\n");
+			printk(KERN_INFO "pcwd: Previous reboot was caused by the card.\n");
 
 		if (card_status & 0x04) {
-			printk("pcwd: Card senses a CPU Overheat.  Panicking!\n");
-			panic("pcwd: CPU Overheat.\n");
+			printk(KERN_EMERG "pcwd: Card senses a CPU Overheat.  Panicking!\n");
+			printk(KERN_EMERG "pcwd: CPU Overheat.\n");
+			machine_power_off();
 		}
 
 		if ((!(card_status & 0x01)) &&
 		    (!(card_status & 0x04)))
-			printk("pcwd: Cold boot sense.\n");
+			printk(KERN_INFO "pcwd: Cold boot sense.\n");
 	}
 }
 
@@ -275,8 +278,10 @@
 			{
 				rv |= WDIOF_OVERHEAT;
 
-				if (temp_panic)
-					panic("pcwd: Temperature overheat trip!\n");
+				if (temp_panic) {
+					printk (KERN_INFO "pcwd: Temperature overheat trip!\n");
+					machine_power_off();
+				}
 			}
 		}
 		else 
@@ -288,8 +293,10 @@
 			{
 				rv |= WDIOF_OVERHEAT;
 
-				if (temp_panic)
-					panic("pcwd: Temperature overheat trip!\n");
+				if (temp_panic) {
+					printk (KERN_INFO "pcwd: Temperature overheat trip!\n");
+					machine_power_off();
+				}
 			}
 		}
 
@@ -350,7 +357,7 @@
 				spin_unlock(&io_lock);
 				if ((cdat & 0x10) == 0) 
 				{
-					printk("pcwd: Could not disable card.\n");
+					printk(KERN_INFO "pcwd: Could not disable card.\n");
 					return -EIO;
 				}
 
@@ -365,7 +372,7 @@
 				spin_unlock(&io_lock);
 				if (cdat & 0x10) 
 				{
-					printk("pcwd: Could not enable card.\n");
+					printk(KERN_INFO "pcwd: Could not enable card.\n");
 					return -EIO;
 				}
 				return 0;
@@ -592,7 +599,7 @@
 	
 	revision = PCWD_REVISION_A;
 
-	printk("pcwd: v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER);
+	printk(KERN_INFO "pcwd: v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER);
 
 	/* Initial variables */
 	supports_temp = 0;
@@ -611,7 +618,7 @@
 	}
 
 	if (!found) {
-		printk("pcwd: No card detected, or port not available.\n");
+		printk(KERN_INFO "pcwd: No card detected, or port not available.\n");
 		return(-EIO);
 	}
 #endif
@@ -624,9 +631,9 @@
 	revision = get_revision();
 
 	if (revision == PCWD_REVISION_A)
-		printk("pcwd: PC Watchdog (REV.A) detected at port 0x%03x\n", current_readport);
+		printk(KERN_INFO "pcwd: PC Watchdog (REV.A) detected at port 0x%03x\n", current_readport);
 	else if (revision == PCWD_REVISION_C)
-		printk("pcwd: PC Watchdog (REV.C) detected at port 0x%03x (Firmware version: %s)\n",
+		printk(KERN_INFO "pcwd: PC Watchdog (REV.C) detected at port 0x%03x (Firmware version: %s)\n",
 			current_readport, get_firmware());
 	else {
 		/* Should NEVER happen, unless get_revision() fails. */
@@ -635,7 +642,7 @@
 	}
 
 	if (supports_temp)
-		printk("pcwd: Temperature Option Detected.\n");
+		printk(KERN_INFO "pcwd: Temperature Option Detected.\n");
 
 	debug_off();
 
diff -Nru a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c
--- a/drivers/char/watchdog/sbc60xxwdt.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/watchdog/sbc60xxwdt.c	Fri Feb 14 15:53:12 2003
@@ -267,9 +267,9 @@
 };
 
 static struct miscdevice wdt_miscdev = {
-	WATCHDOG_MINOR,
-	"watchdog",
-	&wdt_fops
+	.minor = WATCHDOG_MINOR,
+	.name = "watchdog",
+	.fops = &wdt_fops
 };
 
 /*
@@ -291,9 +291,9 @@
  
 static struct notifier_block wdt_notifier=
 {
-	wdt_notify_sys,
-	0,
-	0
+	.notifier_call = wdt_notify_sys,
+	.next = NULL,
+	.priority = 0
 };
 
 static void __exit sbc60xxwdt_unload(void)
diff -Nru a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c
--- a/drivers/char/watchdog/sc1200wdt.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/watchdog/sc1200wdt.c	Fri Feb 14 15:53:09 2003
@@ -23,6 +23,7 @@
  *					Add WDIOC_GETBOOTSTATUS and WDIOC_SETOPTIONS ioctls
  *					Fix CONFIG_WATCHDOG_NOWAYOUT
  *	20020530 Joel Becker		Add Matt Domsch's nowayout module option
+ *	20030116 Adam Belay		Updated to the latest pnp code
  *
  */
 
@@ -35,7 +36,7 @@
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
-#include <linux/isapnp.h>
+#include <linux/pnp.h>
 #include <linux/pci.h>
 
 #include <asm/semaphore.h>
@@ -75,9 +76,9 @@
 static char expect_close;
 spinlock_t sc1200wdt_lock;	/* io port access serialisation */
 
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#if defined CONFIG_PNP
 static int isapnp = 1;
-static struct pci_dev *wdt_dev;
+static struct pnp_dev *wdt_dev;
 
 MODULE_PARM(isapnp, "i");
 MODULE_PARM_DESC(isapnp, "When set to 0 driver ISA PnP support will be disabled");
@@ -296,18 +297,18 @@
 
 static struct file_operations sc1200wdt_fops =
 {
-	owner:		THIS_MODULE,
-	write:		sc1200wdt_write,
-	ioctl:		sc1200wdt_ioctl,
-	open:		sc1200wdt_open,
-	release:	sc1200wdt_release
+	.owner		= THIS_MODULE,
+	.write		= sc1200wdt_write,
+	.ioctl		= sc1200wdt_ioctl,
+	.open		= sc1200wdt_open,
+	.release	= sc1200wdt_release
 };
 
 static struct miscdevice sc1200wdt_miscdev =
 {
-	minor:		WATCHDOG_MINOR,
-	name:		"watchdog",
-	fops:		&sc1200wdt_fops,
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &sc1200wdt_fops,
 };
 
 
@@ -328,40 +329,49 @@
 }
 
 
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#if defined CONFIG_PNP
 
-static int __init sc1200wdt_isapnp_probe(void)
+struct pnp_device_id scl200wdt_pnp_devices[] = {
+	/* National Semiconductor PC87307/PC97307 watchdog component */
+	{.id = "NSC0800", .driver_data = 0},
+	{.id = ""}
+};
+
+static int scl200wdt_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
 {
-	int ret;
+	/* this driver only supports one card at a time */
+	if (wdt_dev || !isapnp)
+		return -EBUSY;
 
-	/* The WDT is logical device 8 on the main device */
-	wdt_dev = isapnp_find_dev(NULL, ISAPNP_VENDOR('N','S','C'), ISAPNP_FUNCTION(0x08), NULL);
-	if (!wdt_dev)
-		return -ENODEV;
-	
-	if (wdt_dev->prepare(wdt_dev) < 0) {
-		printk(KERN_ERR PFX "ISA PnP found device that could not be autoconfigured\n");
-		return -EAGAIN;
-	}
+	wdt_dev = dev;
+	io = pnp_port_start(wdt_dev, 0);
+	io_len = pnp_port_len(wdt_dev, 0);
 
-	if (!(pci_resource_flags(wdt_dev, 0) & IORESOURCE_IO)) {
-		printk(KERN_ERR PFX "ISA PnP could not find io ports\n");
-		return -ENODEV;
+	if (!request_region(io, io_len, SC1200_MODULE_NAME)) {
+		printk(KERN_ERR PFX "Unable to register IO port %#x\n", io);
+		return -EBUSY;
 	}
 
-	ret = wdt_dev->activate(wdt_dev);
-	if (ret && (ret != -EBUSY))
-		return -ENOMEM;
-
-	/* io port resource overriding support? */
-	io = pci_resource_start(wdt_dev, 0);
-	io_len = pci_resource_len(wdt_dev, 0);
-
-	printk(KERN_DEBUG PFX "ISA PnP found device at io port %#x/%d\n", io, io_len);
+	printk(KERN_INFO "scl200wdt: PnP device found at io port %#x/%d\n", io, io_len);
 	return 0;
 }
 
-#endif /* CONFIG_ISAPNP */
+static void scl200wdt_pnp_remove(struct pnp_dev * dev)
+{
+	if (wdt_dev){
+		release_region(io, io_len);
+		wdt_dev = NULL;
+	}
+}
+
+static struct pnp_driver scl200wdt_pnp_driver = {
+	.name		= "scl200wdt",
+	.id_table	= scl200wdt_pnp_devices,
+	.probe		= scl200wdt_pnp_probe,
+	.remove		= scl200wdt_pnp_remove,
+};
+
+#endif /* CONFIG_PNP */
 
 
 static int __init sc1200wdt_init(void)
@@ -373,9 +383,9 @@
 	spin_lock_init(&sc1200wdt_lock);
 	sema_init(&open_sem, 1);
 
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#if defined CONFIG_PNP
 	if (isapnp) {
-		ret = sc1200wdt_isapnp_probe();
+		ret = pnp_register_driver(&scl200wdt_pnp_driver);
 		if (ret)
 			goto out_clean;
 	}
@@ -387,12 +397,19 @@
 		goto out_clean;
 	}
 
+#if defined CONFIG_PNP
+	/* now that the user has specified an IO port and we haven't detected
+	 * any devices, disable pnp support */
+	isapnp = 0;
+	pnp_unregister_driver(&scl200wdt_pnp_driver);
+#endif
+
 	if (!request_region(io, io_len, SC1200_MODULE_NAME)) {
 		printk(KERN_ERR PFX "Unable to register IO port %#x\n", io);
 		ret = -EBUSY;
-		goto out_pnp;
+		goto out_clean;
 	}
-
+	
 	ret = sc1200wdt_probe();
 	if (ret)
 		goto out_io;
@@ -420,11 +437,6 @@
 out_io:
 	release_region(io, io_len);
 
-out_pnp:
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
-	if (isapnp && wdt_dev)
-		wdt_dev->deactivate(wdt_dev);
-#endif
 	goto out_clean;
 }	
 
@@ -434,11 +446,11 @@
 	misc_deregister(&sc1200wdt_miscdev);
 	unregister_reboot_notifier(&sc1200wdt_notifier);
 
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
-	if(isapnp && wdt_dev)
-		wdt_dev->deactivate(wdt_dev);
+#if defined CONFIG_PNP
+	if(isapnp)
+		pnp_unregister_driver(&scl200wdt_pnp_driver);
+	else
 #endif
-
 	release_region(io, io_len);
 }
 
@@ -455,7 +467,7 @@
 		if (ints[0] > 1)
 			timeout = ints[2];
 
-#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+#if defined CONFIG_PNP
 		if (ints[0] > 2)
 			isapnp = ints[3];
 #endif
@@ -474,5 +486,3 @@
 MODULE_AUTHOR("Zwane Mwaikambo <zwane@commfireservices.com>");
 MODULE_DESCRIPTION("Driver for National Semiconductor PC87307/PC97307 watchdog component");
 MODULE_LICENSE("GPL");
-EXPORT_NO_SYMBOLS;
-
diff -Nru a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
--- a/drivers/char/watchdog/sc520_wdt.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/char/watchdog/sc520_wdt.c	Fri Feb 14 15:53:09 2003
@@ -281,18 +281,18 @@
 }
 
 static struct file_operations wdt_fops = {
-	owner:		THIS_MODULE,
-	llseek:		fop_llseek,
-	write:		fop_write,
-	open:		fop_open,
-	release:	fop_close,
-	ioctl:		fop_ioctl
+	.owner		= THIS_MODULE,
+	.llseek		= fop_llseek,
+	.write		= fop_write,
+	.open		= fop_open,
+	.release	= fop_close,
+	.ioctl		= fop_ioctl
 };
 
 static struct miscdevice wdt_miscdev = {
-	WATCHDOG_MINOR,
-	"watchdog",
-	&wdt_fops
+	.minor	= WATCHDOG_MINOR,
+	.name	= "watchdog",
+	.fops	= &wdt_fops
 };
 
 /*
@@ -314,9 +314,9 @@
  
 static struct notifier_block wdt_notifier=
 {
-	wdt_notify_sys,
-	0,
-	0
+	.notifier_call = wdt_notify_sys,
+	.next = NULL,
+	.priority = 0
 };
 
 static void __exit sc520_wdt_unload(void)
diff -Nru a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c
--- a/drivers/char/watchdog/w83877f_wdt.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/char/watchdog/w83877f_wdt.c	Fri Feb 14 15:53:11 2003
@@ -275,9 +275,9 @@
 };
 
 static struct miscdevice wdt_miscdev = {
-	WATCHDOG_MINOR,
-	"watchdog",
-	&wdt_fops
+	.minor	= WATCHDOG_MINOR,
+	.name	= "watchdog",
+	.fops	= &wdt_fops
 };
 
 /*
@@ -299,9 +299,9 @@
  
 static struct notifier_block wdt_notifier=
 {
-	wdt_notify_sys,
-	0,
-	0
+	.notifier_call = wdt_notify_sys,
+	.next = NULL,
+	.priority = 0
 };
 
 static void __exit w83877f_wdt_unload(void)
diff -Nru a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c
--- a/drivers/char/watchdog/wafer5823wdt.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/watchdog/wafer5823wdt.c	Fri Feb 14 15:53:12 2003
@@ -198,17 +198,17 @@
  */
 
 static struct file_operations wafwdt_fops = {
-	owner:THIS_MODULE,
-	write:wafwdt_write,
-	ioctl:wafwdt_ioctl,
-	open:wafwdt_open,
-	release:wafwdt_close,
+	.owner		= THIS_MODULE,
+	.write		= wafwdt_write,
+	.ioctl		= wafwdt_ioctl,
+	.open		= wafwdt_open,
+	.release	= wafwdt_close,
 };
 
 static struct miscdevice wafwdt_miscdev = {
-	WATCHDOG_MINOR,
-	"watchdog",
-	&wafwdt_fops
+	.minor	= WATCHDOG_MINOR,
+	.name	= "watchdog",
+	.fops	= &wafwdt_fops
 };
 
 /*
@@ -217,9 +217,9 @@
  */
 
 static struct notifier_block wafwdt_notifier = {
-	wafwdt_notify_sys,
-	NULL,
-	0
+	.notifier_call = wafwdt_notify_sys,
+	.next = NULL,
+	.priority = 0
 };
 
 static int __init wafwdt_init(void)
diff -Nru a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c
--- a/drivers/char/watchdog/wdt.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/char/watchdog/wdt.c	Fri Feb 14 15:53:10 2003
@@ -465,17 +465,17 @@
 
 static struct miscdevice wdt_miscdev=
 {
-	WATCHDOG_MINOR,
-	"watchdog",
-	&wdt_fops
+	.minor	= WATCHDOG_MINOR,
+	.name	= "watchdog",
+	.fops	= &wdt_fops
 };
 
 #ifdef CONFIG_WDT_501
 static struct miscdevice temp_miscdev=
 {
-	TEMP_MINOR,
-	"temperature",
-	&wdt_fops
+	.minor	= TEMP_MINOR,
+	.name	= "temperature",
+	.fops	= &wdt_fops
 };
 #endif
 
@@ -486,9 +486,9 @@
  
 static struct notifier_block wdt_notifier=
 {
-	wdt_notify_sys,
-	NULL,
-	0
+	.notifier_call = wdt_notify_sys,
+	.next = NULL,
+	.priority = 0
 };
 
 /**
diff -Nru a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c
--- a/drivers/char/watchdog/wdt977.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/char/watchdog/wdt977.c	Fri Feb 14 15:53:12 2003
@@ -258,7 +258,7 @@
          unsigned int cmd, unsigned long arg)
 {
 static struct watchdog_info ident = {
-	identity	: "Winbond 83977"
+	.identity = "Winbond 83977"
 };
 
 int temp;
diff -Nru a/drivers/hotplug/cpci_hotplug_core.c b/drivers/hotplug/cpci_hotplug_core.c
--- a/drivers/hotplug/cpci_hotplug_core.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/hotplug/cpci_hotplug_core.c	Fri Feb 14 15:53:09 2003
@@ -622,8 +622,7 @@
 	struct list_head *tmp;
 
 	lock_kernel();
-	daemonize();
-	strcpy(current->comm, "cpci_hp_eventd");
+	daemonize("cpci_hp_eventd");
 	unlock_kernel();
 
 	dbg("%s - event thread started", __FUNCTION__);
@@ -682,8 +681,7 @@
 	struct list_head *tmp;
 
 	lock_kernel();
-	daemonize();
-	strcpy(current->comm, "cpci_hp_polld");
+	daemonize("cpci_hp_polld");
 	unlock_kernel();
 
 	while(1) {
diff -Nru a/drivers/hotplug/cpqphp_ctrl.c b/drivers/hotplug/cpqphp_ctrl.c
--- a/drivers/hotplug/cpqphp_ctrl.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/hotplug/cpqphp_ctrl.c	Fri Feb 14 15:53:09 2003
@@ -1709,10 +1709,7 @@
 {
 	struct controller *ctrl;
 	lock_kernel();
-	daemonize();
-	
-	//  New name
-	strcpy(current->comm, "phpd_event");
+	daemonize("phpd_event");
 	
 	unlock_kernel();
 
diff -Nru a/drivers/hotplug/ibmphp_hpc.c b/drivers/hotplug/ibmphp_hpc.c
--- a/drivers/hotplug/ibmphp_hpc.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/hotplug/ibmphp_hpc.c	Fri Feb 14 15:53:09 2003
@@ -1125,13 +1125,9 @@
 static int hpc_poll_thread (void *data)
 {
 	debug ("%s - Entry\n", __FUNCTION__);
-	lock_kernel ();
-	daemonize ();
 
-	//  New name
-	strcpy (current->comm, "hpc_poll");
-
-	unlock_kernel ();
+	daemonize("hpc_poll");
+	allow_signal(SIGKILL);
 
 	poll_hpc ();
 
diff -Nru a/drivers/i2c/i2c-adap-ite.c b/drivers/i2c/i2c-adap-ite.c
--- a/drivers/i2c/i2c-adap-ite.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/i2c/i2c-adap-ite.c	Fri Feb 14 15:53:09 2003
@@ -78,7 +78,7 @@
         unsigned long j = jiffies + 10;
 
 	DEB3(printk(" Write 0x%02x to 0x%x\n",(unsigned short)val, ctl&0xff));
-	DEB3({while (jiffies < j) schedule();}) 
+	DEB3({while (time_before(jiffies, j)) schedule();})
 	outw(val,ctl);
 }
 
diff -Nru a/drivers/i2c/i2c-algo-ibm_ocp.c b/drivers/i2c/i2c-algo-ibm_ocp.c
--- a/drivers/i2c/i2c-algo-ibm_ocp.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/i2c/i2c-algo-ibm_ocp.c	Fri Feb 14 15:53:11 2003
@@ -84,7 +84,7 @@
 /* respectively. This makes sure that the algorithm works. Some chips   */
 /* might not like this, as they have an internal timeout of some mils	*/
 /*
-#define SLO_IO      jif=jiffies;while(jiffies<=jif+i2c_table[minor].veryslow)\
+#define SLO_IO      jif=jiffies;while(time_before_eq(jiffies,jif+i2c_table[minor].veryslow))\
                         if (need_resched) schedule();
 */
 
diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
--- a/drivers/i2c/i2c-core.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/i2c/i2c-core.c	Fri Feb 14 15:53:09 2003
@@ -56,7 +56,7 @@
 /* ----- global variables -------------------------------------------------- */
 
 /**** lock for writing to global variables: the adapter & driver list */
-DECLARE_MUTEX(adap_lock);
+static DECLARE_MUTEX(adap_lock);
 static DECLARE_MUTEX(driver_lock);
 
 /**** adapter list */
diff -Nru a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
--- a/drivers/ide/pci/amd74xx.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/ide/pci/amd74xx.c	Fri Feb 14 15:53:12 2003
@@ -60,7 +60,7 @@
 	{ PCI_DEVICE_ID_AMD_OPUS_7441, 0x00, 0x40, AMD_UDMA_100 },			/* AMD-768 Opus */
 	{ PCI_DEVICE_ID_AMD_8111_IDE,  0x00, 0x40, AMD_UDMA_100 },			/* AMD-8111 */
         { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x00, 0x50, AMD_UDMA_100 },                  /* nVidia nForce */
-
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, 0x00, 0x50, AMD_UDMA_100 },			/* nVidia nForce 2 */
 	{ 0 }
 };
 
@@ -446,6 +446,7 @@
 	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
 	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, 	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
 	{ 0, },
 };
 
diff -Nru a/drivers/ide/pci/amd74xx.h b/drivers/ide/pci/amd74xx.h
--- a/drivers/ide/pci/amd74xx.h	Fri Feb 14 15:53:08 2003
+++ b/drivers/ide/pci/amd74xx.h	Fri Feb 14 15:53:08 2003
@@ -110,6 +110,20 @@
 		.bootable	= ON_BOARD,
 		.extra		= 0,
 	},
+	{	/* 6 */
+		.vendor		= PCI_VENDOR_ID_NVIDIA,
+		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE,
+		.name		= "NFORCE2",
+		.init_chipset	= init_chipset_amd74xx,
+		.init_iops	= NULL,
+		.init_hwif	= init_hwif_amd74xx,
+		.init_dma	= init_dma_amd74xx,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.enablebits	= {{0x50,0x01,0x01}, {0x50,0x02,0x02}},
+		.bootable	= ON_BOARD,
+		.extra		= 0,
+	},
 	{
 		.vendor		= 0,
 		.device		= 0,
diff -Nru a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
--- a/drivers/ieee1394/nodemgr.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/ieee1394/nodemgr.c	Fri Feb 14 15:53:11 2003
@@ -1216,10 +1216,9 @@
 	struct host_info *hi = (struct host_info *)__hi;
 
 	/* No userlevel access needed */
-	daemonize();
+	daemonize("knodemgrd");
+	allow_signal(SIGTERM);
 
-	strcpy(current->comm, "knodemgrd");
-	
 	/* Sit and wait for a signal to probe the nodes on the bus. This
 	 * happens when we get a bus reset. */
 	while (!down_interruptible(&hi->reset_sem) &&
diff -Nru a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c
--- a/drivers/input/gameport/ns558.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/input/gameport/ns558.c	Fri Feb 14 15:53:12 2003
@@ -46,7 +46,7 @@
 #define NS558_ISA	1
 #define NS558_PNP	2
 
-static int ns558_isa_portlist[] = { 0x200, 0x201, 0x202, 0x203, 0x204, 0x205, 0x207, 0x209,
+static int ns558_isa_portlist[] = { 0x201, 0x200, 0x202, 0x203, 0x204, 0x205, 0x207, 0x209,
 				    0x20b, 0x20c, 0x20e, 0x20f, 0x211, 0x219, 0x101, 0 };
 
 struct ns558 {
@@ -140,7 +140,7 @@
 	
 	port->type = NS558_ISA;
 	port->size = (1 << i);
-	port->gameport.io = io & (-1 << i);
+	port->gameport.io = io;
 	port->gameport.phys = port->phys;
 	port->gameport.name = port->name;
 	port->gameport.id.bustype = BUS_ISA;
@@ -148,7 +148,7 @@
 	sprintf(port->phys, "isa%04x/gameport0", io & (-1 << i));
 	sprintf(port->name, "NS558 ISA");
 
-	request_region(port->gameport.io, (1 << i), "ns558-isa");
+	request_region(io & (-1 << i), (1 << i), "ns558-isa");
 
 	gameport_register_port(&port->gameport);
 
@@ -275,7 +275,7 @@
 				/* fall through */
 #endif
 			case NS558_ISA:
-				release_region(port->gameport.io, port->size);
+				release_region(port->gameport.io & ~(port->size - 1), port->size);
 				break;
 		
 			default:
diff -Nru a/drivers/input/joydev.c b/drivers/input/joydev.c
--- a/drivers/input/joydev.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/input/joydev.c	Fri Feb 14 15:53:10 2003
@@ -340,7 +340,7 @@
 		case JSIOCSBTNMAP:
 			if (copy_from_user(joydev->keypam, (__u16 *) arg, sizeof(__u16) * (KEY_MAX - BTN_MISC)))
 				return -EFAULT;
-			for (i = 0; i < joydev->nkey; i++); {
+			for (i = 0; i < joydev->nkey; i++) {
 				if (joydev->keypam[i] > KEY_MAX || joydev->keypam[i] < BTN_MISC) return -EINVAL;
 				joydev->keymap[joydev->keypam[i] - BTN_MISC] = i;
 			}
@@ -377,7 +377,8 @@
 	struct joydev *joydev;
 	int i, j, t, minor;
 
-        if (test_bit(BTN_TOUCH, dev->keybit))
+	/* Avoid tablets */
+        if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
 		return NULL;
 
 	for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
@@ -463,18 +464,18 @@
 
 static struct input_device_id joydev_ids[] = {
 	{
-		.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
-		.evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+		.evbit = { BIT(EV_ABS) },
 		.absbit = { BIT(ABS_X) },
 	},
 	{
-		.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
-		.evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+		.evbit = { BIT(EV_ABS) },
 		.absbit = { BIT(ABS_WHEEL) },
 	},
 	{
-		.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
-		.evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
+		.evbit = { BIT(EV_ABS) },
 		.absbit = { BIT(ABS_THROTTLE) },
 	},
 	{ }, 	/* Terminating entry */
diff -Nru a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
--- a/drivers/input/joystick/amijoy.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/input/joystick/amijoy.c	Fri Feb 14 15:53:11 2003
@@ -64,6 +64,8 @@
 				case 1: data = ~custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break;
 			}
 
+			input_regs(amijoy_dev + i, fp);
+
 			input_report_key(amijoy_dev + i, BTN_TRIGGER, button);
 
 			input_report_abs(amijoy_dev + i, ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
diff -Nru a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
--- a/drivers/input/joystick/iforce/iforce-packets.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/input/joystick/iforce/iforce-packets.c	Fri Feb 14 15:53:10 2003
@@ -151,7 +151,7 @@
 	return -1;
 }
 
-void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
+void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs)
 {
 	struct input_dev *dev = &iforce->dev;
 	int i;
@@ -181,6 +181,8 @@
 		case 0x01:	/* joystick position data */
 		case 0x03:	/* wheel position data */
 
+			input_regs(dev, regs);
+
 			if (HI(cmd) == 1) {
 				input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
 				input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
@@ -219,6 +221,7 @@
 			break;
 
 		case 0x02:	/* status report */
+			input_regs(dev, regs);
 			input_report_key(dev, BTN_DEAD, data[0] & 0x02);
 			input_sync(dev);
 
diff -Nru a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
--- a/drivers/input/joystick/iforce/iforce-serio.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/input/joystick/iforce/iforce-serio.c	Fri Feb 14 15:53:08 2003
@@ -78,7 +78,7 @@
 	iforce_serial_xmit((struct iforce *)serio->private);
 }
 
-static void iforce_serio_irq(struct serio *serio, unsigned char data, unsigned int flags)
+static void iforce_serio_irq(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct iforce* iforce = serio->private;
 
@@ -115,7 +115,7 @@
 	}
 
 	if (iforce->idx == iforce->len) {
-		iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data);
+		iforce_process_packet(iforce, (iforce->id << 8) | iforce->idx, iforce->data, regs);
 		iforce->pkt = 0;
 		iforce->id  = 0;
 		iforce->len = 0;
diff -Nru a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
--- a/drivers/input/joystick/iforce/iforce-usb.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/input/joystick/iforce/iforce-usb.c	Fri Feb 14 15:53:12 2003
@@ -74,7 +74,7 @@
 	spin_unlock_irqrestore(&iforce->xmit_lock, flags);
 }
 
-static void iforce_usb_irq(struct urb *urb)
+static void iforce_usb_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct iforce *iforce = urb->context;
 	int status;
@@ -96,7 +96,7 @@
 	}
 
 	iforce_process_packet(iforce,
-		(iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1);
+		(iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1, regs);
 
 exit:
 	status = usb_submit_urb (urb, GFP_ATOMIC);
@@ -105,7 +105,7 @@
 		     __FUNCTION__, status);
 }
 
-static void iforce_usb_out(struct urb *urb)
+static void iforce_usb_out(struct urb *urb, struct pt_regs *regs)
 {
 	struct iforce *iforce = urb->context;
 
@@ -120,7 +120,7 @@
 		wake_up(&iforce->wait);
 }
 
-static void iforce_usb_ctrl(struct urb *urb)
+static void iforce_usb_ctrl(struct urb *urb, struct pt_regs *regs)
 {
 	struct iforce *iforce = urb->context;
 	if (urb->status) return;
@@ -133,11 +133,14 @@
 				const struct usb_device_id *id)
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
+	struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *epirq, *epout;
 	struct iforce *iforce;
 
-	epirq = intf->altsetting[0].endpoint + 0;
-	epout = intf->altsetting[0].endpoint + 1;
+	interface = &intf->altsetting[intf->act_altsetting];
+
+	epirq = &interface->endpoint[0].desc;
+	epout = &interface->endpoint[1].desc;
 
 	if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL)))
 		goto fail;
diff -Nru a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
--- a/drivers/input/joystick/iforce/iforce.h	Fri Feb 14 15:53:09 2003
+++ b/drivers/input/joystick/iforce/iforce.h	Fri Feb 14 15:53:09 2003
@@ -176,7 +176,7 @@
 
 /* iforce-packets.c */
 int iforce_control_playback(struct iforce*, u16 id, unsigned int);
-void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data);
+void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs);
 int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data);
 void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) ;
 int iforce_get_id_packet(struct iforce *iforce, char *packet);
diff -Nru a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
--- a/drivers/input/joystick/magellan.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/input/joystick/magellan.c	Fri Feb 14 15:53:08 2003
@@ -81,7 +81,7 @@
 	return 0;
 }
 
-static void magellan_process_packet(struct magellan* magellan)
+static void magellan_process_packet(struct magellan* magellan, struct pt_regs *regs)
 {
 	struct input_dev *dev = &magellan->dev;
 	unsigned char *data = magellan->data;
@@ -89,6 +89,8 @@
 
 	if (!magellan->idx) return;
 
+	input_regs(dev, regs);
+
 	switch (magellan->data[0]) {
 
 		case 'd':				/* Axis data */
@@ -111,12 +113,12 @@
 	input_sync(dev);
 }
 
-static void magellan_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void magellan_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct magellan* magellan = serio->private;
 
 	if (data == '\r') {
-		magellan_process_packet(magellan);
+		magellan_process_packet(magellan, regs);
 		magellan->idx = 0;
 	} else {
 		if (magellan->idx < MAGELLAN_MAX_LENGTH)
diff -Nru a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
--- a/drivers/input/joystick/spaceball.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/input/joystick/spaceball.c	Fri Feb 14 15:53:08 2003
@@ -81,7 +81,7 @@
  * SpaceBall.
  */
 
-static void spaceball_process_packet(struct spaceball* spaceball)
+static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs *regs)
 {
 	struct input_dev *dev = &spaceball->dev;
 	unsigned char *data = spaceball->data;
@@ -89,6 +89,8 @@
 
 	if (spaceball->idx < 2) return;
 
+	input_regs(dev, regs);
+
 	switch (spaceball->data[0]) {
 
 		case 'D':					/* Ball data */
@@ -147,13 +149,13 @@
  * can occur in the axis values.
  */
 
-static void spaceball_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void spaceball_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct spaceball *spaceball = serio->private;
 
 	switch (data) {
 		case 0xd:
-			spaceball_process_packet(spaceball);
+			spaceball_process_packet(spaceball, regs);
 			spaceball->idx = 0;
 			spaceball->escape = 0;
 			return;
diff -Nru a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
--- a/drivers/input/joystick/spaceorb.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/input/joystick/spaceorb.c	Fri Feb 14 15:53:09 2003
@@ -74,7 +74,7 @@
  * SpaceOrb.
  */
 
-static void spaceorb_process_packet(struct spaceorb *spaceorb)
+static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *regs)
 {
 	struct input_dev *dev = &spaceorb->dev;
 	unsigned char *data = spaceorb->data;
@@ -86,6 +86,8 @@
 	for (i = 0; i < spaceorb->idx; i++) c ^= data[i];
 	if (c) return;
 
+	input_regs(dev, regs);
+
 	switch (data[0]) {
 
 		case 'R':				/* Reset packet */
@@ -128,12 +130,12 @@
 	input_sync(dev);
 }
 
-static void spaceorb_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void spaceorb_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct spaceorb* spaceorb = serio->private;
 
 	if (~data & 0x80) {
-		if (spaceorb->idx) spaceorb_process_packet(spaceorb);
+		if (spaceorb->idx) spaceorb_process_packet(spaceorb, regs);
 		spaceorb->idx = 0;
 	}
 	if (spaceorb->idx < SPACEORB_MAX_LENGTH)
diff -Nru a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
--- a/drivers/input/joystick/stinger.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/input/joystick/stinger.c	Fri Feb 14 15:53:08 2003
@@ -64,13 +64,15 @@
  * Stinger. It updates the data accordingly.
  */
 
-static void stinger_process_packet(struct stinger *stinger)
+static void stinger_process_packet(struct stinger *stinger, struct pt_regs *regs)
 {
 	struct input_dev *dev = &stinger->dev;
 	unsigned char *data = stinger->data;
 
 	if (!stinger->idx) return;
 
+	input_regs(dev, regs);
+
 	input_report_key(dev, BTN_A,	  ((data[0] & 0x20) >> 5));
 	input_report_key(dev, BTN_B,	  ((data[0] & 0x10) >> 4));
 	input_report_key(dev, BTN_C,	  ((data[0] & 0x08) >> 3));
@@ -96,7 +98,7 @@
  * packet processing routine.
  */
 
-static void stinger_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void stinger_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct stinger* stinger = serio->private;
 
@@ -106,7 +108,7 @@
 		stinger->data[stinger->idx++] = data;
 
 	if (stinger->idx == 4) {
-		stinger_process_packet(stinger);
+		stinger_process_packet(stinger, regs);
 		stinger->idx = 0;
 	}
 
diff -Nru a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
--- a/drivers/input/joystick/twidjoy.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/input/joystick/twidjoy.c	Fri Feb 14 15:53:08 2003
@@ -101,7 +101,7 @@
  * Twiddler. It updates the data accordingly.
  */
 
-static void twidjoy_process_packet(struct twidjoy *twidjoy)
+static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs)
 {
 	if (twidjoy->idx == TWIDJOY_MAX_LENGTH) {
 		struct input_dev *dev = &twidjoy->dev;
@@ -111,6 +111,8 @@
 
 		button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
 
+		input_regs(dev, regs);
+
 		for (bp = twidjoy_buttons; bp->bitmask; bp++) {
 			int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
 			int i;
@@ -140,7 +142,7 @@
  * packet processing routine.
  */
 
-static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struc pt_regs *regs)
 {
 	struct twidjoy *twidjoy = serio->private;
 
@@ -157,7 +159,7 @@
 		twidjoy->data[twidjoy->idx++] = data;
 
 	if (twidjoy->idx == TWIDJOY_MAX_LENGTH) {
-		twidjoy_process_packet(twidjoy);
+		twidjoy_process_packet(twidjoy, regs);
 		twidjoy->idx = 0;
 	}
 
diff -Nru a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
--- a/drivers/input/joystick/warrior.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/input/joystick/warrior.c	Fri Feb 14 15:53:12 2003
@@ -63,13 +63,15 @@
  * Warrior. It updates the data accordingly.
  */
 
-static void warrior_process_packet(struct warrior *warrior)
+static void warrior_process_packet(struct warrior *warrior, struct pt_regs *regs)
 {
 	struct input_dev *dev = &warrior->dev;
 	unsigned char *data = warrior->data;
 
 	if (!warrior->idx) return;
 
+	input_regs(dev, regs);
+
 	switch ((data[0] >> 4) & 7) {
 		case 1:					/* Button data */
 			input_report_key(dev, BTN_TRIGGER,  data[3]       & 1);
@@ -97,12 +99,12 @@
  * packet processing routine.
  */
 
-static void warrior_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void warrior_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct warrior* warrior = serio->private;
 
 	if (data & 0x80) {
-		if (warrior->idx) warrior_process_packet(warrior);
+		if (warrior->idx) warrior_process_packet(warrior, regs);
 		warrior->idx = 0;
 		warrior->len = warrior_lengths[(data >> 4) & 7];
 	}
@@ -111,7 +113,7 @@
 		warrior->data[warrior->idx++] = data;
 
 	if (warrior->idx == warrior->len) {
-		if (warrior->idx) warrior_process_packet(warrior);	
+		if (warrior->idx) warrior_process_packet(warrior, regs);	
 		warrior->idx = 0;
 		warrior->len = 0;
 	}
diff -Nru a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
--- a/drivers/input/keyboard/amikbd.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/input/keyboard/amikbd.c	Fri Feb 14 15:53:12 2003
@@ -87,6 +87,8 @@
 
 		scancode = amikbd_keycode[scancode];
 
+		input_regs(&amikbd_dev, fp);
+
 		if (scancode == KEY_CAPSLOCK) {	/* CapsLock is a toggle switch key on Amiga */
 			input_report_key(&amikbd_dev, scancode, 1);
 			input_report_key(&amikbd_dev, scancode, 0);
diff -Nru a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/input/keyboard/atkbd.c	Fri Feb 14 15:53:12 2003
@@ -86,8 +86,7 @@
 #define ATKBD_CMD_SETLEDS	0x10ed
 #define ATKBD_CMD_GSCANSET	0x11f0
 #define ATKBD_CMD_SSCANSET	0x10f0
-#define ATKBD_CMD_GETID		0x01f2
-#define ATKBD_CMD_GETID2	0x0100
+#define ATKBD_CMD_GETID		0x02f2
 #define ATKBD_CMD_ENABLE	0x00f4
 #define ATKBD_CMD_RESET_DIS	0x00f5
 #define ATKBD_CMD_RESET_BAT	0x01ff
@@ -120,12 +119,12 @@
 	unsigned char cmdbuf[4];
 	unsigned char cmdcnt;
 	unsigned char set;
-	unsigned char oldset;
 	unsigned char release;
-	signed char ack;
+	volatile signed char ack;
 	unsigned char emul;
 	unsigned short id;
 	unsigned char write;
+	unsigned char resend;
 };
 
 /*
@@ -133,7 +132,7 @@
  * the keyboard into events.
  */
 
-static void atkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void atkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct atkbd *atkbd = serio->private;
 	int code = data;
@@ -142,11 +141,15 @@
 	printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
 #endif
 
-	if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && atkbd->write) {
+	if ((flags & (SERIO_FRAME | SERIO_PARITY)) && (~flags & SERIO_TIMEOUT) && !atkbd->resend && atkbd->write) {
 		printk("atkbd.c: frame/parity error: %02x\n", flags);
 		serio_write(serio, ATKBD_CMD_RESEND);
+		atkbd->resend = 1;
 		return;
 	}
+	
+	if (!flags)
+		atkbd->resend = 0;
 
 	switch (code) {
 		case ATKBD_RET_ACK:
@@ -190,6 +193,7 @@
 				atkbd->set, code, serio->phys, atkbd->release ? "released" : "pressed");
 			break;
 		default:
+			input_regs(&atkbd->dev, regs);
 			input_report_key(&atkbd->dev, atkbd->keycode[code], !atkbd->release);
 			input_sync(&atkbd->dev);
 	}
@@ -227,12 +231,15 @@
 
 static int atkbd_command(struct atkbd *atkbd, unsigned char *param, int command)
 {
-	int timeout = 50000; /* 500 msec */
+	int timeout = 500000; /* 500 msec */
 	int send = (command >> 12) & 0xf;
 	int receive = (command >> 8) & 0xf;
 	int i;
 
 	atkbd->cmdcnt = receive;
+
+	if (command == ATKBD_CMD_RESET_BAT)
+		timeout = 2000000; /* 2 sec */
 	
 	if (command & 0xff)
 		if (atkbd_sendbyte(atkbd, command & 0xff))
@@ -242,14 +249,28 @@
 		if (atkbd_sendbyte(atkbd, param[i]))
 			return (atkbd->cmdcnt = 0) - 1;
 
-	while (atkbd->cmdcnt && timeout--) udelay(10);
+	while (atkbd->cmdcnt && timeout--) {
+
+		if (atkbd->cmdcnt == 1 && command == ATKBD_CMD_RESET_BAT)
+			timeout = 100000;
+
+		if (atkbd->cmdcnt == 1 && command == ATKBD_CMD_GETID &&
+		    atkbd->cmdbuf[1] != 0xab && atkbd->cmdbuf[1] != 0xac) {
+			atkbd->cmdcnt = 0;
+			break;
+		}
+	
+		udelay(1);
+	}
 
 	if (param)
 		for (i = 0; i < receive; i++)
 			param[i] = atkbd->cmdbuf[(receive - 1) - i];
 
-	if (atkbd->cmdcnt) 
-		return (atkbd->cmdcnt = 0) - 1;
+	if (atkbd->cmdcnt) {
+		atkbd->cmdcnt = 0;
+		return -1;
+	}
 
 	return 0;
 }
@@ -303,13 +324,6 @@
 	unsigned char param[2];
 
 /*
- * Remember original scancode set value, so that we can restore it on exit.
- */
-
-	if (atkbd_command(atkbd, &atkbd->oldset, ATKBD_CMD_GSCANSET))
-		atkbd->oldset = 2;
-
-/*
  * For known special keyboards we can go ahead and set the correct set.
  * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and
  * IBM RapidAccess / IBM EzButton / Chicony KBP-8993 keyboards.
@@ -376,8 +390,8 @@
  */
 
 	if (atkbd_reset)
-		if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT))
-			printk(KERN_WARNING "atkbd.c: keyboard reset failed\n");
+		if (atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT)) 
+			printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", atkbd->serio->phys);
 
 /*
  * Then we check the keyboard ID. We should get 0xab83 under normal conditions.
@@ -401,10 +415,7 @@
 
 	if (param[0] != 0xab && param[0] != 0xac)
 		return -1;
-	atkbd->id = param[0] << 8;
-	if (atkbd_command(atkbd, param, ATKBD_CMD_GETID2))
-		return -1;
-	atkbd->id |= param[0];
+	atkbd->id = (param[0] << 8) | param[1];
 
 /*
  * Set the LEDs to a defined state.
@@ -442,7 +453,7 @@
 static void atkbd_cleanup(struct serio *serio)
 {
 	struct atkbd *atkbd = serio->private;
-	atkbd_command(atkbd, &atkbd->oldset, ATKBD_CMD_SSCANSET);
+	atkbd_command(atkbd, NULL, ATKBD_CMD_RESET_BAT);
 }
 
 /*
diff -Nru a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
--- a/drivers/input/keyboard/newtonkbd.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/input/keyboard/newtonkbd.c	Fri Feb 14 15:53:08 2003
@@ -62,18 +62,20 @@
 	char phys[32];
 };
 
-void nkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+void nkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct nkbd *nkbd = serio->private;
 
 	/* invalid scan codes are probably the init sequence, so we ignore them */
-	if (nkbd->keycode[data & NKBD_KEY])
+	if (nkbd->keycode[data & NKBD_KEY]) {
+		input_regs(&nkbd->dev, regs);
 		input_report_key(&nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
+		input_sync(&nkbd->dev);
+	}
 
 	else if (data == 0xe7) /* end of init sequence */
 		printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
 
-	input_sync(&nkbd->dev);
 }
 
 void nkbd_connect(struct serio *serio, struct serio_dev *dev)
diff -Nru a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
--- a/drivers/input/keyboard/sunkbd.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/input/keyboard/sunkbd.c	Fri Feb 14 15:53:08 2003
@@ -89,7 +89,7 @@
  * is received.
  */
 
-static void sunkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void sunkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct sunkbd* sunkbd = serio->private;
 
@@ -119,6 +119,7 @@
 
 		default:
 			if (sunkbd->keycode[data & SUNKBD_KEY]) {
+				input_regs(&sunkbd->dev, regs);
                                 input_report_key(&sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE));
 				input_sync(&sunkbd->dev);
                         } else {
@@ -267,7 +268,7 @@
 	sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type);
 
 	memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode));
-	for (i = 0; i < 255; i++)
+	for (i = 0; i < 127; i++)
 		set_bit(sunkbd->keycode[i], sunkbd->dev.keybit);
 	clear_bit(0, sunkbd->dev.keybit);
 
diff -Nru a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
--- a/drivers/input/keyboard/xtkbd.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/input/keyboard/xtkbd.c	Fri Feb 14 15:53:10 2003
@@ -63,7 +63,7 @@
 	char phys[32];
 };
 
-void xtkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+void xtkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct xtkbd *xtkbd = serio->private;
 
@@ -74,6 +74,7 @@
 		default:
 
 			if (xtkbd->keycode[data & XTKBD_KEY]) {
+				input_regs(&xtkbd->dev, regs);
 				input_report_key(&xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE));
 				input_sync(&xtkbd->dev);
 			} else {
diff -Nru a/drivers/input/misc/98spkr.c b/drivers/input/misc/98spkr.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/input/misc/98spkr.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,95 @@
+/*
+ *  PC-9800 Speaker beeper driver for Linux
+ *
+ *  Copyright (c) 2002 Osamu Tomita
+ *  Copyright (c) 2002 Vojtech Pavlik
+ *  Copyright (c) 1992 Orest Zborowski
+ *
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <asm/io.h>
+
+MODULE_AUTHOR("Osamu Tomita <tomita@cinet.co.jp>");
+MODULE_DESCRIPTION("PC-9800 Speaker beeper driver");
+MODULE_LICENSE("GPL");
+
+static char spkr98_name[] = "PC-9801 Speaker";
+static char spkr98_phys[] = "isa3fdb/input0";
+static struct input_dev spkr98_dev;
+
+spinlock_t i8253_beep_lock = SPIN_LOCK_UNLOCKED;
+
+static int spkr98_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+{
+	unsigned int count = 0;
+	unsigned long flags;
+
+	if (type != EV_SND)
+		return -1;
+
+	switch (code) {
+		case SND_BELL: if (value) value = 1000;
+		case SND_TONE: break;
+		default: return -1;
+	} 
+
+	if (value > 20 && value < 32767)
+		count = CLOCK_TICK_RATE / value;
+	
+	spin_lock_irqsave(&i8253_beep_lock, flags);
+
+	if (count) {
+		outb(0x76, 0x3fdf);
+		outb(0, 0x5f);
+		outb(count & 0xff, 0x3fdb);
+		outb(0, 0x5f);
+		outb((count >> 8) & 0xff, 0x3fdb);
+		/* beep on */
+		outb(6, 0x37);
+	} else {
+		/* beep off */
+		outb(7, 0x37);
+	}
+
+	spin_unlock_irqrestore(&i8253_beep_lock, flags);
+
+	return 0;
+}
+
+static int __init spkr98_init(void)
+{
+	spkr98_dev.evbit[0] = BIT(EV_SND);
+	spkr98_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+	spkr98_dev.event = spkr98_event;
+
+	spkr98_dev.name = spkr98_name;
+	spkr98_dev.phys = spkr98_phys;
+	spkr98_dev.id.bustype = BUS_ISA;
+	spkr98_dev.id.vendor = 0x001f;
+	spkr98_dev.id.product = 0x0001;
+	spkr98_dev.id.version = 0x0100;
+
+	input_register_device(&spkr98_dev);
+
+        printk(KERN_INFO "input: %s\n", spkr98_name);
+
+	return 0;
+}
+
+static void __exit spkr98_exit(void)
+{
+        input_unregister_device(&spkr98_dev);
+}
+
+module_init(spkr98_init);
+module_exit(spkr98_exit);
diff -Nru a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
--- a/drivers/input/misc/Kconfig	Fri Feb 14 15:53:09 2003
+++ b/drivers/input/misc/Kconfig	Fri Feb 14 15:53:09 2003
@@ -44,6 +44,10 @@
 	tristate "M68k Beeper support"
 	depends on M68K && INPUT && INPUT_MISC
 
+config INPUT_98SPKR
+	tristate "PC-9800 Speaker support"
+	depends on X86_PC9800 && INPUT && INPUT_MISC
+
 config INPUT_UINPUT
 	tristate "User level driver support"
 	depends on INPUT && INPUT_MISC
diff -Nru a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
--- a/drivers/input/misc/Makefile	Fri Feb 14 15:53:11 2003
+++ b/drivers/input/misc/Makefile	Fri Feb 14 15:53:11 2003
@@ -7,5 +7,6 @@
 obj-$(CONFIG_INPUT_SPARCSPKR)		+= sparcspkr.o
 obj-$(CONFIG_INPUT_PCSPKR)		+= pcspkr.o
 obj-$(CONFIG_INPUT_M68K_BEEP)		+= m68kspkr.o
+obj-$(CONFIG_INPUT_98SPKR)		+= 98spkr.o
 obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
 obj-$(CONFIG_INPUT_GSC)			+= gsc_ps2.o
diff -Nru a/drivers/input/misc/gsc_ps2.c b/drivers/input/misc/gsc_ps2.c
--- a/drivers/input/misc/gsc_ps2.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/input/misc/gsc_ps2.c	Fri Feb 14 15:53:09 2003
@@ -305,7 +305,7 @@
  * Receives a keyboard scancode, analyses it and sends it to the input layer.
  */
 
-static void gscps2_kbd_docode(void)
+static void gscps2_kbd_docode(struct pt_regs *regs)
 {
 	int scancode = gscps2_readb_input(hpkeyb.addr);
 	DPRINTK("rel=%d scancode=%d, esc=%d ", hpkeyb.released, scancode, hpkeyb.escaped);
@@ -341,6 +341,7 @@
 		default:
 			hpkeyb.scancode = scancode;
 			DPRINTK("sent=%d, rel=%d\n",hpkeyb.scancode, hpkeyb.released);
+			input_regs(regs);
 			input_report_key(&hpkeyb.dev, hpkeyb_keycode[hpkeyb.scancode], !hpkeyb.released);
 			input_sync(&hpkeyb.dev);
 			if (hpkeyb.escaped)
@@ -359,7 +360,7 @@
  * correct events to the input layer.
  */
 
-static void gscps2_mouse_docode(void)
+static void gscps2_mouse_docode(struct pt_regs *regs)
 {
 	int xrel, yrel;
 
@@ -368,7 +369,7 @@
 		hpmouse.nbread--;
 
 	/* stolen from psmouse.c */
-	if (hpmouse.nbread && time_after(jiffies, hpmouse.last + HZ/20)) {
+	if (hpmouse.nbread && time_after(jiffies, hpmouse.last + HZ/2)) {
 		printk(KERN_DEBUG "%s:%d : Lost mouse synchronization, throwing %d bytes away.\n", __FILE__, __LINE__,
 				hpmouse.nbread);
 		hpmouse.nbread = 0;
@@ -387,6 +388,8 @@
 		if ((hpmouse.bytes[PACKET_CTRL] & (MOUSE_XOVFLOW | MOUSE_YOVFLOW)))
 			DPRINTK("Mouse: position overflow\n");
 		
+		input_regs(regs);
+
 		input_report_key(&hpmouse.dev, BTN_LEFT, hpmouse.bytes[PACKET_CTRL] & MOUSE_LEFTBTN);
 		input_report_key(&hpmouse.dev, BTN_MIDDLE, hpmouse.bytes[PACKET_CTRL] & MOUSE_MIDBTN);
 		input_report_key(&hpmouse.dev, BTN_RIGHT, hpmouse.bytes[PACKET_CTRL] & MOUSE_RIGHTBTN);
@@ -421,11 +424,11 @@
 {
 	/* process mouse actions */
 	while (gscps2_readb_status(hpmouse.addr) & GSC_STAT_RBNE)
-		gscps2_mouse_docode();
+		gscps2_mouse_docode(reg);
 	
 	/* process keyboard scancode */
 	while (gscps2_readb_status(hpkeyb.addr) & GSC_STAT_RBNE)
-		gscps2_kbd_docode();
+		gscps2_kbd_docode(reg);
 }
 
 
diff -Nru a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c
--- a/drivers/input/mouse/amimouse.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/input/mouse/amimouse.c	Fri Feb 14 15:53:09 2003
@@ -63,6 +63,8 @@
 
 	potgor = custom.potgor;
 
+	input_regs(&amimouse_dev, fp);
+
 	input_report_rel(&amimouse_dev, REL_X, dx);
 	input_report_rel(&amimouse_dev, REL_Y, dy);
 
diff -Nru a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c
--- a/drivers/input/mouse/inport.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/input/mouse/inport.c	Fri Feb 14 15:53:10 2003
@@ -131,6 +131,8 @@
 	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
 	outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
 
+	input_regs(&inport_dev, regs);
+
 	outb(INPORT_REG_X, INPORT_CONTROL_PORT);
 	input_report_rel(&inport_dev, REL_X, inb(INPORT_DATA_PORT));
 
diff -Nru a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c
--- a/drivers/input/mouse/logibm.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/input/mouse/logibm.c	Fri Feb 14 15:53:10 2003
@@ -130,6 +130,7 @@
 	dy |= (buttons & 0xf) << 4;
 	buttons = ~buttons >> 5;
 
+	input_regs(&logibm_dev, regs);
 	input_report_rel(&logibm_dev, REL_X, dx);
 	input_report_rel(&logibm_dev, REL_Y, dy);
 	input_report_key(&logibm_dev, BTN_RIGHT,  buttons & 1);
diff -Nru a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c
--- a/drivers/input/mouse/pc110pad.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/input/mouse/pc110pad.c	Fri Feb 14 15:53:09 2003
@@ -73,6 +73,7 @@
 
 	if (pc110pad_count < 3) return;
 	
+	input_regs(&pc110pad_dev, regs);
 	input_report_key(&pc110pad_dev, BTN_TOUCH,
 		pc110pad_data[0] & 0x01);
 	input_report_abs(&pc110pad_dev, ABS_X,
diff -Nru a/drivers/input/mouse/psmouse.c b/drivers/input/mouse/psmouse.c
--- a/drivers/input/mouse/psmouse.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/input/mouse/psmouse.c	Fri Feb 14 15:53:09 2003
@@ -30,8 +30,7 @@
 #define PSMOUSE_CMD_GETINFO	0x03e9
 #define PSMOUSE_CMD_SETSTREAM	0x00ea
 #define PSMOUSE_CMD_POLL	0x03eb	
-#define PSMOUSE_CMD_GETID	0x01f2
-#define PSMOUSE_CMD_GETID2	0x0100
+#define PSMOUSE_CMD_GETID	0x02f2
 #define PSMOUSE_CMD_SETRATE	0x10f3
 #define PSMOUSE_CMD_ENABLE	0x00f4
 #define PSMOUSE_CMD_RESET_DIS	0x00f6
@@ -54,7 +53,7 @@
 	unsigned char model;
 	unsigned long last;
 	char acking;
-	char ack;
+	volatile char ack;
 	char error;
 	char devname[64];
 	char phys[32];
@@ -74,20 +73,22 @@
  * reports relevant events to the input module.
  */
 
-static void psmouse_process_packet(struct psmouse *psmouse)
+static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
 {
 	struct input_dev *dev = &psmouse->dev;
 	unsigned char *packet = psmouse->packet;
 
+	input_regs(dev, regs);
+
 /*
  * The PS2++ protocol is a little bit complex
  */
 
 	if (psmouse->type == PSMOUSE_PS2PP || psmouse->type == PSMOUSE_PS2TPP) {
 
-		if ((packet[0] & 0x40) == 0x40 && (int) packet[1] - (int) ((packet[0] & 0x10) << 4) > 191 ) {
+		if ((packet[0] & 0x40) == 0x40 && abs((int)packet[1] - (((int)packet[0] & 0x10) << 4)) > 191 ) {
 
-			switch (((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0xc0)) {
+			switch (((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c)) {
 
 			case 1: /* Mouse extra info */
 
@@ -106,10 +107,11 @@
 
 				break;
 
+#ifdef DEBUG
 			default:
-
 				printk(KERN_WARNING "psmouse.c: Received PS2++ packet #%x, but don't know how to handle.\n",
-					((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0xc0));
+					((packet[1] >> 4) & 0x03) | ((packet[0] >> 2) & 0x0c));
+#endif
 
 			}
 
@@ -165,7 +167,7 @@
  * packets or passing them to the command routine as command output.
  */
 
-static void psmouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void psmouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct psmouse *psmouse = serio->private;
 
@@ -201,7 +203,7 @@
 	psmouse->packet[psmouse->pktcnt++] = data;
 
 	if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) {
-		psmouse_process_packet(psmouse);
+		psmouse_process_packet(psmouse, regs);
 		psmouse->pktcnt = 0;
 		return;
 	}
@@ -248,6 +250,9 @@
 
 	psmouse->cmdcnt = receive;
 
+	if (command == PSMOUSE_CMD_RESET_BAT)
+                timeout = 2000000; /* 2 sec */
+
 	if (command & 0xff)
 		if (psmouse_sendbyte(psmouse, command & 0xff))
 			return (psmouse->cmdcnt = 0) - 1;
@@ -256,7 +261,19 @@
 		if (psmouse_sendbyte(psmouse, param[i]))
 			return (psmouse->cmdcnt = 0) - 1;
 
-	while (psmouse->cmdcnt && timeout--) udelay(1);
+	while (psmouse->cmdcnt && timeout--) {
+	
+		if (psmouse->cmdcnt == 1 && command == PSMOUSE_CMD_RESET_BAT)
+			timeout = 100000;
+
+		if (psmouse->cmdcnt == 1 && command == PSMOUSE_CMD_GETID &&
+		    psmouse->cmdbuf[1] != 0xab && psmouse->cmdbuf[1] != 0xac) {
+			psmouse->cmdcnt = 0;
+			break;
+		}
+
+		udelay(1);
+	}
 
 	for (i = 0; i < receive; i++)
 		param[i] = psmouse->cmdbuf[(receive - 1) - i];
@@ -497,11 +514,6 @@
 
 	if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETID))
 		return -1;
-
-	if (param[0] == 0xab || param[0] == 0xac) {
-		psmouse_command(psmouse, param, PSMOUSE_CMD_GETID2);
-		return -1;
-	}
 
 	if (param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04)
 		return -1;
diff -Nru a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c
--- a/drivers/input/mouse/rpcmouse.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/input/mouse/rpcmouse.c	Fri Feb 14 15:53:09 2003
@@ -64,6 +64,8 @@
 	rpcmouse_lastx = x;
 	rpcmouse_lasty = y;
 
+	input_regs(dev, regs);
+
 	input_report_rel(dev, REL_X, dx);
 	input_report_rel(dev, REL_Y, -dy);
 
diff -Nru a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
--- a/drivers/input/mouse/sermouse.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/input/mouse/sermouse.c	Fri Feb 14 15:53:12 2003
@@ -60,11 +60,13 @@
  * second, which is as good as a PS/2 or USB mouse.
  */
 
-static void sermouse_process_msc(struct sermouse *sermouse, signed char data)
+static void sermouse_process_msc(struct sermouse *sermouse, signed char data, struct pt_regs *regs)
 {
 	struct input_dev *dev = &sermouse->dev;
 	signed char *buf = sermouse->buf;
 
+	input_regs(dev, regs);
+
 	switch (sermouse->count) {
 
 		case 0:
@@ -101,13 +103,15 @@
  * standard 3-byte packets and 1200 bps.
  */
 
-static void sermouse_process_ms(struct sermouse *sermouse, signed char data)
+static void sermouse_process_ms(struct sermouse *sermouse, signed char data, struct pt_regs *regs)
 {
 	struct input_dev *dev = &sermouse->dev;
 	signed char *buf = sermouse->buf;
 
 	if (data & 0x40) sermouse->count = 0;
 
+	input_regs(dev, regs);
+
 	switch (sermouse->count) {
 
 		case 0:
@@ -200,7 +204,7 @@
  * packets or passing them to the command routine as command output.
  */
 
-static void sermouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void sermouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct sermouse *sermouse = serio->private;
 
@@ -208,9 +212,9 @@
 	sermouse->last = jiffies;
 
 	if (sermouse->type > SERIO_SUN)
-		sermouse_process_ms(sermouse, data);
+		sermouse_process_ms(sermouse, data, regs);
 	else
-		sermouse_process_msc(sermouse, data);
+		sermouse_process_msc(sermouse, data, regs);
 }
 
 /*
diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c
--- a/drivers/input/mousedev.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/input/mousedev.c	Fri Feb 14 15:53:12 2003
@@ -454,7 +454,11 @@
 		.keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) },
 		.relbit = { BIT(REL_X) | BIT(REL_Y) },
 	},	/* A mouse like device, at least one button, two relative axes */
-
+	{
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_RELBIT,
+		.evbit = { BIT(EV_KEY) | BIT(EV_REL) },
+		.relbit = { BIT(REL_WHEEL) },
+	},	/* A separate scrollwheel */
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
 		.evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
diff -Nru a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
--- a/drivers/input/serio/ambakmi.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/input/serio/ambakmi.c	Fri Feb 14 15:53:11 2003
@@ -23,8 +23,6 @@
 #include <asm/irq.h>
 #include <asm/hardware/amba_kmi.h>
 
-extern struct pt_regs *kbd_pt_regs;
-
 #define KMI_BASE	(kmi->base)
 
 struct amba_kmi_port {
@@ -42,10 +40,8 @@
 	struct amba_kmi_port *kmi = dev_id;
 	unsigned int status = __raw_readb(KMIIR);
 
-	kbd_pt_regs = regs;
-
 	while (status & KMIIR_RXINTR) {
-		serio_interrupt(&kmi->io, __raw_readb(KMIDATA), 0);
+		serio_interrupt(&kmi->io, __raw_readb(KMIDATA), 0, regs);
 		status = __raw_readb(KMIIR);
 	}
 }
diff -Nru a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
--- a/drivers/input/serio/ct82c710.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/input/serio/ct82c710.c	Fri Feb 14 15:53:08 2003
@@ -156,7 +156,7 @@
 
 static void ct82c710_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
 {
-	serio_interrupt(&ct82c710_port, inb(ct82c710_data), 0);
+	serio_interrupt(&ct82c710_port, inb(ct82c710_data), 0, regs);
 }
 
 /*
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/input/serio/i8042.c	Fri Feb 14 15:53:08 2003
@@ -62,8 +62,6 @@
 static unsigned char i8042_mux_open;
 struct timer_list i8042_timer;
 
-extern struct pt_regs *kbd_pt_regs;
-
 static unsigned long i8042_unxlate_seen[256 / BITS_PER_LONG];
 static unsigned char i8042_unxlate_table[128] = {
 	  0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
@@ -345,10 +343,6 @@
 	} buffer[I8042_BUFFER_SIZE];
 	int i, j = 0;
 
-#ifdef CONFIG_VT
-	kbd_pt_regs = regs;
-#endif
-
 	spin_lock_irqsave(&i8042_lock, flags);
 
 	while (j < I8042_BUFFER_SIZE && 
@@ -381,7 +375,7 @@
 				dfl & SERIO_PARITY ? ", bad parity" : "",
 				dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
-			serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl);
+			serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl, regs);
 			continue;
 		}
 
@@ -391,7 +385,7 @@
 			dfl & SERIO_TIMEOUT ? ", timeout" : "");
 
 		if (i8042_aux_values.exists && (str & I8042_STR_AUXDATA)) {
-			serio_interrupt(&i8042_aux_port, data, dfl);
+			serio_interrupt(&i8042_aux_port, data, dfl, regs);
 			continue;
 		}
 
@@ -399,7 +393,7 @@
 			continue;
 
 		if (i8042_direct) {
-			serio_interrupt(&i8042_kbd_port, data, dfl);
+			serio_interrupt(&i8042_kbd_port, data, dfl, regs);
 			continue;
 		}
 
@@ -408,7 +402,7 @@
 			if (index == 0xaa || index == 0xb6)
 				set_bit(index, i8042_unxlate_seen);
 			if (test_and_clear_bit(index, i8042_unxlate_seen)) {
-				serio_interrupt(&i8042_kbd_port, 0xf0, dfl);
+				serio_interrupt(&i8042_kbd_port, 0xf0, dfl, regs);
 				data = i8042_unxlate_table[data & 0x7f];
 			}
 		} else {
@@ -418,7 +412,7 @@
 
 		i8042_last_e0 = (data == 0xe0);
 
-		serio_interrupt(&i8042_kbd_port, data, dfl);
+		serio_interrupt(&i8042_kbd_port, data, dfl, regs);
 	}
 
 }
diff -Nru a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c
--- a/drivers/input/serio/parkbd.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/input/serio/parkbd.c	Fri Feb 14 15:53:08 2003
@@ -136,7 +136,7 @@
 		parkbd_buffer |= (parkbd_readlines() >> 1) << parkbd_counter++;
 
 		if (parkbd_counter == parkbd_mode + 10)
-			serio_interrupt(&parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0);
+			serio_interrupt(&parkbd_port, (parkbd_buffer >> (2 - parkbd_mode)) & 0xff, 0, regs);
 	}
 
 	parkbd_last = jiffies;
diff -Nru a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
--- a/drivers/input/serio/q40kbd.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/input/serio/q40kbd.c	Fri Feb 14 15:53:09 2003
@@ -69,8 +69,7 @@
 static void q40kbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))
-		if (q40kbd_port.dev)
-                         q40kbd_port.dev->interrupt(&q40kbd_port, master_inb(KEYCODE_REG), 0);
+		serio_interrupt(&q40kbd_port, master_inb(KEYCODE_REG), 0, regs);
 
 	master_outb(-1, KEYBOARD_UNLOCK_REG);
 }
diff -Nru a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
--- a/drivers/input/serio/rpckbd.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/input/serio/rpckbd.c	Fri Feb 14 15:53:08 2003
@@ -44,8 +44,6 @@
 MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver");
 MODULE_LICENSE("GPL");
 
-extern struct pt_regs *kbd_pt_regs;
-
 static int rpckbd_write(struct serio *port, unsigned char val)
 {
 	while (!(iomd_readb(IOMD_KCTRL) & (1 << 7)))
@@ -60,12 +58,11 @@
 {
 	struct serio *port = dev_id;
 	unsigned int byte;
-	kbd_pt_regs = regs;
 
 	while (iomd_readb(IOMD_KCTRL) & (1 << 5)) {
 		byte = iomd_readb(IOMD_KARTRX);
 
-		serio_interrupt(port, byte, 0);
+		serio_interrupt(port, byte, 0, regs);
 	}
 }
 
diff -Nru a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
--- a/drivers/input/serio/sa1111ps2.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/input/serio/sa1111ps2.c	Fri Feb 14 15:53:09 2003
@@ -24,8 +24,6 @@
 
 #include <asm/hardware/sa1111.h>
 
-extern struct pt_regs *kbd_pt_regs;
-
 struct ps2if {
 	struct serio		io;
 	struct sa1111_dev	*dev;
@@ -47,8 +45,6 @@
 	struct ps2if *ps2if = dev_id;
 	unsigned int scancode, flag, status;
 
-	kbd_pt_regs = regs;
-
 	status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
 	while (status & PS2STAT_RXF) {
 		if (status & PS2STAT_STP)
@@ -62,7 +58,7 @@
 		if (hweight8(scancode) & 1)
 			flag ^= SERIO_PARITY;
 
-		serio_interrupt(&ps2if->io, scancode, flag);
+		serio_interrupt(&ps2if->io, scancode, flag, regs);
 
                	status = sa1111_readl(ps2if->base + SA1111_PS2STAT);
         }
diff -Nru a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/input/serio/serio.c	Fri Feb 14 15:53:08 2003
@@ -105,8 +105,8 @@
 static int serio_thread(void *nothing)
 {
 	lock_kernel();
-	daemonize();
-	strcpy(current->comm, "kseriod");
+	daemonize("kseriod");
+	allow_signal(SIGTERM);
 
 	do {
 		serio_handle_events();
@@ -135,10 +135,10 @@
 	wake_up(&serio_wait);
 }
 
-void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {       
         if (serio->dev && serio->dev->interrupt) 
-                serio->dev->interrupt(serio, data, flags);
+                serio->dev->interrupt(serio, data, flags, regs);
 	else 
 		if (!flags)
 			serio_rescan(serio);
diff -Nru a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
--- a/drivers/input/serio/serport.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/input/serio/serport.c	Fri Feb 14 15:53:12 2003
@@ -114,6 +114,9 @@
  * serport_ldisc_receive() is called by the low level tty driver when characters
  * are ready for us. We forward the characters, one by one to the 'interrupt'
  * routine.
+ *
+ * FIXME: We should get pt_regs from the tty layer and forward them to
+ *	  serio_interrupt here.
  */
 
 static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
@@ -121,7 +124,7 @@
 	struct serport *serport = (struct serport*) tty->disc_data;
 	int i;
 	for (i = 0; i < count; i++)
-		serio_interrupt(&serport->serio, cp[i], 0);
+		serio_interrupt(&serport->serio, cp[i], 0, NULL);
 }
 
 /*
diff -Nru a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
--- a/drivers/input/touchscreen/gunze.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/input/touchscreen/gunze.c	Fri Feb 14 15:53:09 2003
@@ -60,7 +60,7 @@
 	char phys[32];
 };
 
-static void gunze_process_packet(struct gunze* gunze)
+static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs)
 {
 	struct input_dev *dev = &gunze->dev;
 
@@ -71,18 +71,19 @@
 		return;
 	}
 
+	input_regs(dev, regs);
 	input_report_abs(dev, ABS_X, simple_strtoul(gunze->data + 1, NULL, 10) * 4);
 	input_report_abs(dev, ABS_Y, 3072 - simple_strtoul(gunze->data + 6, NULL, 10) * 3);
 	input_report_key(dev, BTN_TOUCH, gunze->data[0] == 'T');
 	input_sync(dev);
 }
 
-static void gunze_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+static void gunze_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct gunze* gunze = serio->private;
 
 	if (data == '\r') {
-		gunze_process_packet(gunze);
+		gunze_process_packet(gunze, regs);
 		gunze->idx = 0;
 	} else {
 		if (gunze->idx < GUNZE_MAX_LENGTH)
diff -Nru a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
--- a/drivers/input/touchscreen/h3600_ts_input.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/input/touchscreen/h3600_ts_input.c	Fri Feb 14 15:53:12 2003
@@ -108,6 +108,7 @@
         int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1;
 	struct input_dev *dev = (struct input_dev *) dev_id;
 
+	input_regs(dev, regs);
 	input_report_key(dev, KEY_ENTER, down);
 	input_sync(dev);
 }
@@ -121,6 +122,7 @@
 	 * This interrupt is only called when we release the key. So we have 
 	 * to fake a key press.
 	 */ 	
+	input_regs(dev, regs);
 	input_report_key(dev, KEY_SUSPEND, 1);
 	input_report_key(dev, KEY_SUSPEND, down); 	
 	input_sync(dev);
@@ -183,11 +185,13 @@
  * packets. Some packets coming from serial are not touchscreen related. In
  * this case we send them off to be processed elsewhere. 
  */
-static void h3600ts_process_packet(struct h3600_dev *ts)
+static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
 {
         struct input_dev *dev = &ts->dev;
 	static int touched = 0;
 	int key, down = 0;
+
+	input_regs(dev, regs);
 
         switch (ts->event) {
                 /*
diff -Nru a/drivers/isdn/hardware/eicon/diva.c b/drivers/isdn/hardware/eicon/diva.c
--- a/drivers/isdn/hardware/eicon/diva.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/isdn/hardware/eicon/diva.c	Fri Feb 14 15:53:12 2003
@@ -563,10 +563,11 @@
 	Requests[31] = DivaIdiRequest31;
 }
 
+/* card:  1-based card number */
 void diva_xdi_display_adapter_features(int card)
 {
 	dword features;
-	if (!card || ((card - 1) > MAX_ADAPTER) || !IoAdapters[card - 1]) {
+	if (!card || ((card - 1) >= MAX_ADAPTER) || !IoAdapters[card - 1]) {
 		return;
 	}
 	card--;
diff -Nru a/drivers/isdn/hardware/eicon/i4l_idi.c b/drivers/isdn/hardware/eicon/i4l_idi.c
--- a/drivers/isdn/hardware/eicon/i4l_idi.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/isdn/hardware/eicon/i4l_idi.c	Fri Feb 14 15:53:10 2003
@@ -3057,7 +3057,7 @@
 		}
 
 	        timeout = jiffies + 50;
-        	while (timeout > jiffies) {
+        	while (time_before(jiffies, timeout)) {
 	                if (chan->e.B2Id) break;
         	        SLEEP(10);
 	        }
@@ -3119,7 +3119,7 @@
         eicon_tx_request(card);
 
         timeout = jiffies + 50;
-        while (timeout > jiffies) {
+        while (time_before(jiffies, timeout)) {
                 if (chan->fsm_state) break;
                 SLEEP(10);
         }
diff -Nru a/drivers/isdn/hardware/eicon/i4lididrv.c b/drivers/isdn/hardware/eicon/i4lididrv.c
--- a/drivers/isdn/hardware/eicon/i4lididrv.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/isdn/hardware/eicon/i4lididrv.c	Fri Feb 14 15:53:12 2003
@@ -326,10 +326,7 @@
     if(!(atomic_read(&thread_running)))
       break;
     if(signal_pending(current)) {
-         /* we may want to do something on signals here */
-         spin_lock_irq(&current->sigmask_lock);
          flush_signals(current);
-         spin_unlock_irq(&current->sigmask_lock);
     } else {
          run_task_queue(&tq_divad);
     }
diff -Nru a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
--- a/drivers/macintosh/adb.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/macintosh/adb.c	Fri Feb 14 15:53:12 2003
@@ -244,12 +244,13 @@
 static int
 adb_probe_task(void *x)
 {
+	sigset_t blocked;
+
 	strcpy(current->comm, "kadbprobe");
-	
-	spin_lock_irq(&current->sighand->siglock);
-	sigfillset(&current->blocked);
+
+	sigfillset(&blocked);
+	sicprocmask(SIG_BLOCK, &blocked, NULL);	
 	flush_signals(current);
-	spin_unlock_irq(&current->sighand->siglock);
 
 	printk(KERN_INFO "adb: starting probe task...\n");
 	do_adb_reset_bus();
diff -Nru a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
--- a/drivers/macintosh/adbhid.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/macintosh/adbhid.c	Fri Feb 14 15:53:12 2003
@@ -52,8 +52,6 @@
 #define KEYB_LEDREG	2	/* register # for leds on ADB keyboard */
 #define MOUSE_DATAREG	0	/* reg# for movement/button codes from mouse */
 
-extern struct pt_regs *kbd_pt_regs;
-
 static int adb_message_handler(struct notifier_block *, unsigned long, void *);
 static struct notifier_block adbhid_adb_notifier = {
 	.notifier_call	= adb_message_handler,
@@ -136,14 +134,13 @@
 	/* first check this is from register 0 */
 	if (nb != 3 || (data[0] & 3) != KEYB_KEYREG)
 		return;		/* ignore it */
-	kbd_pt_regs = regs;
-	adbhid_input_keycode(id, data[1], 0);
+	adbhid_input_keycode(id, data[1], 0, regs);
 	if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f)))
-		adbhid_input_keycode(id, data[2], 0);
+		adbhid_input_keycode(id, data[2], 0, regs);
 }
 
 static void
-adbhid_input_keycode(int id, int keycode, int repeat)
+adbhid_input_keycode(int id, int keycode, int repeat, pt_regs *regs)
 {
 	int up_flag;
 
@@ -152,21 +149,24 @@
 
 	switch (keycode) {
 	case 0x39: /* Generate down/up events for CapsLock everytime. */
+		input_regs(&adbhid[id]->input, regs);
 		input_report_key(&adbhid[id]->input, KEY_CAPSLOCK, 1);
 		input_report_key(&adbhid[id]->input, KEY_CAPSLOCK, 0);
+		input_sync(&adbhid[id]->input);
 		return;
 	case 0x3f: /* ignore Powerbook Fn key */
 		return;
 	}
 
-	if (adbhid[id]->keycode[keycode])
+	if (adbhid[id]->keycode[keycode]) {
+		input_regs(&adbhid[id]->input, regs);
 		input_report_key(&adbhid[id]->input,
 				 adbhid[id]->keycode[keycode], !up_flag);
-	else
+		input_sync(&adbhid[id]->input);
+	} else
 		printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode,
 		       up_flag ? "released" : "pressed");
 
-	input_sync(&adbhid[id]->input);
 }
 
 static void
@@ -253,6 +253,8 @@
                 break;
 	}
 
+	input_regs(&adbhid[id]->input, regs);
+
 	input_report_key(&adbhid[id]->input, BTN_LEFT,   !((data[1] >> 7) & 1));
 	input_report_key(&adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1));
 
@@ -276,6 +278,8 @@
 		printk(KERN_ERR "ADB HID on ID %d not yet registered\n", id);
 		return;
 	}
+
+	input_regs(&adbhid[id]->input, regs);
 
 	switch (adbhid[id]->original_handler_id) {
 	default:
diff -Nru a/drivers/md/md.c b/drivers/md/md.c
--- a/drivers/md/md.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/md/md.c	Fri Feb 14 15:53:09 2003
@@ -2444,9 +2444,7 @@
 
 static inline void flush_curr_signals(void)
 {
-	spin_lock(&current->sighand->siglock);
 	flush_signals(current);
-	spin_unlock(&current->sighand->siglock);
 }
 
 int md_thread(void * arg)
@@ -2459,12 +2457,10 @@
 	 * Detach thread
 	 */
 
-	daemonize();
+	daemonize(thread->name);
 
-	sprintf(current->comm, thread->name);
 	current->exit_signal = SIGCHLD;
-	siginitsetinv(&current->blocked, sigmask(SIGKILL));
-	flush_curr_signals();
+	allow_signal(SIGKILL);
 	thread->tsk = current;
 
 	/*
diff -Nru a/drivers/media/dvb/av7110/av7110.c b/drivers/media/dvb/av7110/av7110.c
--- a/drivers/media/dvb/av7110/av7110.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/media/dvb/av7110/av7110.c	Fri Feb 14 15:53:08 2003
@@ -349,13 +349,13 @@
     
 	lock_kernel();
 #if 0
-	daemonize();
+	daemonize("arm_mon");
 #else
         exit_mm(current);
         current->session=current->pgrp=1;
-#endif
 	sigfillset(&current->blocked);
 	strcpy(current->comm, "arm_mon");
+#endif
 	av7110->arm_thread = current;
 	unlock_kernel();
 
@@ -3243,7 +3243,7 @@
         u16 handle;
                 
         handle=dvbdmxfilter->hw_handle;
-        if (handle>32) {
+        if (handle >= MAXFILT) {
                 dprintk("dvb: StopHWFilter tried to stop invalid filter %d.\n",
                        handle);
                 dprintk("dvb: filter type = %d\n",  dvbdmxfilter->type);
@@ -4408,7 +4408,7 @@
         dvbdemux->priv=(void *) av7110;
 
         if (av7110->saa->card_type==DVB_CARD_TT_SIEMENS) {
-                for (i=0; i<32; i++)
+                for (i = 0; i < MAXFILT; i++)
                         av7110->handle2filter[i]=NULL;
 
                 dvbdemux->filternum=32;
diff -Nru a/drivers/media/dvb/av7110/av7110.h b/drivers/media/dvb/av7110/av7110.h
--- a/drivers/media/dvb/av7110/av7110.h	Fri Feb 14 15:53:12 2003
+++ b/drivers/media/dvb/av7110/av7110.h	Fri Feb 14 15:53:12 2003
@@ -580,7 +580,7 @@
 #define TRICK_FREEZE 3
         struct audio_status      audiostate;
 
-        struct dvb_demux_filter     *handle2filter[32];
+        struct dvb_demux_filter     *handle2filter[MAXFILT];
         p2t_t                   p2t_filter[MAXFILT];
         dvb_filter_pes2ts_t     p2t[2];
         struct ipack_s          ipack[2];
diff -Nru a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c	Fri Feb 14 15:53:09 2003
@@ -482,9 +482,7 @@
 	dprintk ("%s\n", __FUNCTION__);
 
 	lock_kernel ();
-	daemonize ();
-	sigfillset (&current->blocked);
-	strncpy (current->comm, "kdvb-fe", sizeof (current->comm));
+	daemonize("kdvb-fe");
 	fe->thread = current;
 	unlock_kernel ();
 
diff -Nru a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
--- a/drivers/media/video/bttv-cards.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/media/video/bttv-cards.c	Fri Feb 14 15:53:09 2003
@@ -2172,8 +2172,9 @@
 	tuner = eeprom_data[9];
 	radio = eeprom_data[blk2-1] & 0x01;
 	
-        if (tuner < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER))
-                btv->tuner_type = hauppauge_tuner[tuner].id;
+        if (tuner >= ARRAY_SIZE(hauppauge_tuner))
+		tuner = 0;
+	btv->tuner_type = hauppauge_tuner[tuner].id;
 	if (radio)
 		btv->has_radio = 1;
 	
diff -Nru a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
--- a/drivers/media/video/msp3400.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/media/video/msp3400.c	Fri Feb 14 15:53:11 2003
@@ -755,9 +755,7 @@
 	lock_kernel();
 #endif
 	
-	daemonize();
-	sigfillset(&current->blocked);
-	strcpy(current->comm,"msp3400");
+	daemonize("msp3400");
 
 	msp->thread = current;
 
@@ -1011,9 +1009,7 @@
 	lock_kernel();
 #endif
     
-	daemonize();
-	sigfillset(&current->blocked);
-	strcpy(current->comm,"msp3410 [auto]");
+	daemonize("msp3410 [auto]");
 
 	msp->thread = current;
 
diff -Nru a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
--- a/drivers/media/video/saa5249.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/media/video/saa5249.c	Fri Feb 14 15:53:12 2003
@@ -254,21 +254,19 @@
 
 static struct i2c_driver i2c_driver_videotext = 
 {
-	IF_NAME,		/* name */
-	I2C_DRIVERID_SAA5249, /* in i2c.h */
-	I2C_DF_NOTIFY,
-	saa5249_probe,
-	saa5249_detach,
-	saa5249_command
+	.owner 		= THIS_MODULE,
+	.name 		= IF_NAME,		/* name */
+	.id 		= I2C_DRIVERID_SAA5249, /* in i2c.h */
+	.flags 		= I2C_DF_NOTIFY,
+	.attach_adapter = saa5249_probe,
+	.detach_client  = saa5249_detach,
+	.command 	= saa5249_command
 };
 
 static struct i2c_client client_template = {
-	"(unset)",
-	-1,
-	0,
-	0,
-	NULL,
-	&i2c_driver_videotext
+	.name 		= "(unset)",
+	.id 		= -1,
+	.driver 	= &i2c_driver_videotext
 };
 
 /*
diff -Nru a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
--- a/drivers/media/video/saa7110.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/media/video/saa7110.c	Fri Feb 14 15:53:08 2003
@@ -381,20 +381,18 @@
 
 static struct i2c_driver i2c_driver_saa7110 =
 {
-	IF_NAME,			/* name */
-	I2C_DRIVERID_SAA7110,	/* in i2c.h */
-	I2C_DF_NOTIFY,	/* Addr range */
-	saa7110_probe,
-	saa7110_detach,
-	saa7110_command
+	.owner 		= THIS_MODULE,
+	.name 		= IF_NAME,			/* name */
+	.id  		= I2C_DRIVERID_SAA7110,	/* in i2c.h */
+	.flags 		= I2C_DF_NOTIFY,	/* Addr range */
+	.attach_adapter = saa7110_probe,
+	.detach_client 	= saa7110_detach,
+	.command 	= saa7110_command
 };
 static struct i2c_client client_template = {
-	"saa7110_client",
-	-1,
-	0,
-	0,
-	NULL,
-	&i2c_driver_saa7110
+	.name 		= "saa7110_client",
+	.id 		= -1,
+	.driver 	= &i2c_driver_saa7110
 };
 
 static int saa7110_init(void)
diff -Nru a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c	Fri Feb 14 15:53:08 2003
@@ -393,9 +393,7 @@
 	int i,max,carrier,audio;
 
 	lock_kernel();
-	daemonize();
-	sigfillset(&current->blocked);
-	sprintf(current->comm, "%s", dev->name);
+	daemonize("%s", dev->name);
 	dev->thread.task = current;
 	unlock_kernel();
 	if (dev->thread.notify != NULL)
diff -Nru a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c
--- a/drivers/media/video/tuner-3036.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/media/video/tuner-3036.c	Fri Feb 14 15:53:09 2003
@@ -185,22 +185,20 @@
 static struct i2c_driver 
 i2c_driver_tuner = 
 {
-	"sab3036",		/* name       */
-	I2C_DRIVERID_SAB3036,	/* ID         */
-        I2C_DF_NOTIFY,
-	tuner_probe,
-	tuner_detach,
-	tuner_command
+	.owner		=	THIS_MODULE,
+	.name		=	"sab3036",
+	.id		=	I2C_DRIVERID_SAB3036,
+        .flags		=	I2C_DF_NOTIFY,
+	.attach_adapter =	tuner_probe,
+	.detach_client  =	tuner_detach,
+	.command	=	tuner_command
 };
 
 static struct i2c_client client_template =
 {
-        "SAB3036",		/* name       */
-        -1,
-        0,
-        0,
-        NULL,
-        &i2c_driver_tuner
+        .name 		= "SAB3036",
+        .id 		= -1,
+        .driver		= &i2c_driver_tuner
 };
 
 int __init
diff -Nru a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
--- a/drivers/media/video/tvaudio.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/media/video/tvaudio.c	Fri Feb 14 15:53:09 2003
@@ -272,9 +272,7 @@
 #ifdef CONFIG_SMP
 	lock_kernel();
 #endif
-	daemonize();
-	sigfillset(&current->blocked);
-	strcpy(current->comm,chip->c.name);
+	daemonize("%s", chip->c.name);
 	chip->thread = current;
 #ifdef CONFIG_SMP
 	unlock_kernel();
diff -Nru a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig
--- a/drivers/message/i2o/Kconfig	Fri Feb 14 15:53:08 2003
+++ b/drivers/message/i2o/Kconfig	Fri Feb 14 15:53:08 2003
@@ -50,19 +50,6 @@
 	  whenever you want). If you want to compile it as a module, say M
 	  here and read <file:Documentation/modules.txt>.
 
-config I2O_LAN
-	tristate "I2O LAN OSM"
-	depends on NET && I2O
-	help
-	  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.
-
-	  This support is also available as a module called i2o_lan ( = 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 <file:Documentation/modules.txt>.
-
 config I2O_SCSI
 	tristate "I2O SCSI OSM"
 	depends on I2O && SCSI
diff -Nru a/drivers/message/i2o/Makefile b/drivers/message/i2o/Makefile
--- a/drivers/message/i2o/Makefile	Fri Feb 14 15:53:12 2003
+++ b/drivers/message/i2o/Makefile	Fri Feb 14 15:53:12 2003
@@ -8,6 +8,5 @@
 obj-$(CONFIG_I2O_PCI)	+= i2o_pci.o
 obj-$(CONFIG_I2O)	+= i2o_core.o i2o_config.o
 obj-$(CONFIG_I2O_BLOCK)	+= i2o_block.o
-obj-$(CONFIG_I2O_LAN)	+= i2o_lan.o
 obj-$(CONFIG_I2O_SCSI)	+= i2o_scsi.o
 obj-$(CONFIG_I2O_PROC)	+= i2o_proc.o
diff -Nru a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
--- a/drivers/message/i2o/i2o_block.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/message/i2o/i2o_block.c	Fri Feb 14 15:53:12 2003
@@ -629,11 +629,9 @@
 		u8 data[16];
 		} *evt_local;
 
-	lock_kernel();
-	daemonize();
-	unlock_kernel();
+	daemonize("i2oblock");
+	allow_signal(SIGKILL);
 
-	strcpy(current->comm, "i2oblock");
 	evt_running = 1;
 
 	while(1)
diff -Nru a/drivers/message/i2o/i2o_core.c b/drivers/message/i2o/i2o_core.c
--- a/drivers/message/i2o/i2o_core.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/message/i2o/i2o_core.c	Fri Feb 14 15:53:11 2003
@@ -879,11 +879,9 @@
 	struct i2o_controller *c = NULL;
 	unsigned long flags;
 
-	lock_kernel();
-	daemonize();
-	unlock_kernel();
+	daemonize("i2oevtd");
+	allow_signal(SIGKILL);
 
-	strcpy(current->comm, "i2oevtd");
 	evt_running = 1;
 
 	while(1)
@@ -1047,15 +1045,10 @@
 	int found = 0;
 	int entries;
 	void *tmp;
-	char name[16];
 
-	lock_kernel();
-	daemonize();
-	unlock_kernel();
+	daemonize("iop%d_lctd", c->unit);
+	allow_signal(SIGKILL);
 
-	sprintf(name, "iop%d_lctd", c->unit);
-	strcpy(current->comm, name);	
-	
 	c->lct_running = 1;
 
 	while(1)
@@ -3060,7 +3053,7 @@
 		"PROGRESS_REPORT"	
 	};
 
-	if (req_status > I2O_REPLY_STATUS_PROGRESS_REPORT)
+	if (req_status >= ARRAY_SIZE(REPLY_STATUS))
 		printk("RequestStatus = %0#2x", req_status);
 	else
 		printk("%s", REPLY_STATUS[req_status]);
diff -Nru a/drivers/message/i2o/i2o_lan.c b/drivers/message/i2o/i2o_lan.c
--- a/drivers/message/i2o/i2o_lan.c	Fri Feb 14 15:53:09 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1575 +0,0 @@
-/*
- *	drivers/i2o/i2o_lan.c
- *
- * 	I2O LAN CLASS OSM 		May 26th 2000
- *
- *	(C) Copyright 1999, 2000 	University of Helsinki,
- *		      			Department of Computer Science
- *
- * 	This code is still under development / test.
- *
- *	This program is free software; you can redistribute it and/or
- *	modify it under the terms of the GNU General Public License
- *	as published by the Free Software Foundation; either version
- *	2 of the License, or (at your option) any later version.
- *
- *	Authors: 	Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
- *	Fixes:		Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
- *	 		Taneli Vähäkangas <Taneli.Vahakangas@cs.Helsinki.FI>
- *			Deepak Saxena <deepak@plexity.net>
- *
- *	Tested:		in FDDI environment (using SysKonnect's DDM)
- *			in Gigabit Eth environment (using SysKonnect's DDM)
- *			in Fast Ethernet environment (using Intel 82558 DDM)
- *
- *	TODO:		tests for other LAN classes (Token Ring, Fibre Channel)
- */
-
-#error Please convert me to Documentation/DMA-mapping.txt
-
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/pci.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/fddidevice.h>
-#include <linux/trdevice.h>
-#include <linux/fcdevice.h>
-
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include <asm/io.h>
-
-#include <linux/errno.h>
-
-#include <linux/i2o.h>
-#include "i2o_lan.h"
-
-//#define DRIVERDEBUG
-#ifdef DRIVERDEBUG
-#define dprintk(s, args...) printk(s, ## args)
-#else
-#define dprintk(s, args...)
-#endif
-
-/* The following module parameters are used as default values
- * for per interface values located in the net_device private area.
- * Private values are changed via /proc filesystem.
- */
-static u32 max_buckets_out = I2O_LAN_MAX_BUCKETS_OUT;
-static u32 bucket_thresh   = I2O_LAN_BUCKET_THRESH;
-static u32 rx_copybreak    = I2O_LAN_RX_COPYBREAK;
-static u8  tx_batch_mode   = I2O_LAN_TX_BATCH_MODE;
-static u32 i2o_event_mask  = I2O_LAN_EVENT_MASK;
-
-#define MAX_LAN_CARDS 16
-static struct net_device *i2o_landevs[MAX_LAN_CARDS+1];
-static int unit = -1; 	  /* device unit number */
-
-static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m);
-static void i2o_lan_send_post_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m);
-static int i2o_lan_receive_post(struct net_device *dev);
-static void i2o_lan_receive_post_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m);
-static void i2o_lan_release_buckets(struct net_device *dev, u32 *msg);
-
-static int i2o_lan_reset(struct net_device *dev);
-static void i2o_lan_handle_event(struct net_device *dev, u32 *msg);
-
-/* Structures to register handlers for the incoming replies. */
-
-static struct i2o_handler i2o_lan_send_handler = {
-	i2o_lan_send_post_reply, 	// For send replies
-	NULL,
-	NULL,
-	NULL,
-	"I2O LAN OSM send",
-	-1,
-	I2O_CLASS_LAN
-};
-static int lan_send_context;
-
-static struct i2o_handler i2o_lan_receive_handler = {
-	i2o_lan_receive_post_reply,	// For receive replies
-	NULL,
-	NULL,
-	NULL,
-	"I2O LAN OSM receive",
-	-1,
-	I2O_CLASS_LAN
-};
-static int lan_receive_context;
-
-static struct i2o_handler i2o_lan_handler = {
-	i2o_lan_reply,			// For other replies
-	NULL,
-	NULL,
-	NULL,
-	"I2O LAN OSM",
-	-1,
-	I2O_CLASS_LAN
-};
-static int lan_context;
-
-struct DECLARE_WORK(run_i2o_post_buckets_task,
-			(void (*)(void *)) run_task_queue, NULL);
-
-/* Functions to handle message failures and transaction errors:
-==============================================================*/
-
-/*
- * i2o_lan_handle_failure(): Fail bit has been set since IOP's message
- * layer cannot deliver the request to the target, or the target cannot
- * process the request.
- */
-static void i2o_lan_handle_failure(struct net_device *dev, u32 *msg)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	struct i2o_controller *iop = i2o_dev->controller;
-
-	u32 *preserved_msg = (u32*)(iop->mem_offset + msg[7]);
-	u32 *sgl_elem = &preserved_msg[4];
-	struct sk_buff *skb = NULL;
-	u8 le_flag;
-
-	i2o_report_status(KERN_INFO, dev->name, msg);
-
-	/* If PacketSend failed, free sk_buffs reserved by upper layers */
-
-	if (msg[1] >> 24 == LAN_PACKET_SEND) {
-		do {
-			skb = (struct sk_buff *)(sgl_elem[1]);
-			dev_kfree_skb_irq(skb);
-
-			atomic_dec(&priv->tx_out);
-
-			le_flag = *sgl_elem >> 31;
-			sgl_elem +=3;
-		} while (le_flag == 0); /* Last element flag not set */
-
-		if (netif_queue_stopped(dev))
-			netif_wake_queue(dev);
-	}
-
-	/* If ReceivePost failed, free sk_buffs we have reserved */
-
-	if (msg[1] >> 24 == LAN_RECEIVE_POST) {
-		do {
-			skb = (struct sk_buff *)(sgl_elem[1]);
-			dev_kfree_skb_irq(skb);
-
-			atomic_dec(&priv->buckets_out);
-
-			le_flag = *sgl_elem >> 31;
-			sgl_elem +=3;
-		} while (le_flag == 0); /* Last element flag not set */
-	}
-
-	/* Release the preserved msg frame by resubmitting it as a NOP */
-
-	preserved_msg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
-	preserved_msg[1] = I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0;
-	preserved_msg[2] = 0;
-	i2o_post_message(iop, msg[7]);
-}
-/*
- * i2o_lan_handle_transaction_error(): IOP or DDM has rejected the request
- * for general cause (format error, bad function code, insufficient resources,
- * etc.). We get one transaction_error for each failed transaction.
- */
-static void i2o_lan_handle_transaction_error(struct net_device *dev, u32 *msg)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct sk_buff *skb;
-
-	i2o_report_status(KERN_INFO, dev->name, msg);
-
-	/* If PacketSend was rejected, free sk_buff reserved by upper layers */
-
-	if (msg[1] >> 24 == LAN_PACKET_SEND) {
-		skb = (struct sk_buff *)(msg[3]); // TransactionContext
-		dev_kfree_skb_irq(skb);
-		atomic_dec(&priv->tx_out);
-
-		if (netif_queue_stopped(dev))
-			netif_wake_queue(dev);
- 	}
-
-	/* If ReceivePost was rejected, free sk_buff we have reserved */
-
-	if (msg[1] >> 24 == LAN_RECEIVE_POST) {
-		skb = (struct sk_buff *)(msg[3]);
-		dev_kfree_skb_irq(skb);
-		atomic_dec(&priv->buckets_out);
-	}
-}
-
-/*
- * i2o_lan_handle_status(): Common parts of handling a not succeeded request
- * (status != SUCCESS).
- */
-static int i2o_lan_handle_status(struct net_device *dev, u32 *msg)
-{
-	/* Fail bit set? */
-
-	if (msg[0] & MSG_FAIL) {
-		i2o_lan_handle_failure(dev, msg);
-		return -1;
-	}
-
-	/* Message rejected for general cause? */
-
-	if ((msg[4]>>24) == I2O_REPLY_STATUS_TRANSACTION_ERROR) {
-		i2o_lan_handle_transaction_error(dev, msg);
-		return -1;
-	}
-
-	/* Else have to handle it in the callback function */
-
-	return 0;
-}
-
-/* Callback functions called from the interrupt routine:
-=======================================================*/
-
-/*
- * i2o_lan_send_post_reply(): Callback function to handle PostSend replies.
- */
-static void i2o_lan_send_post_reply(struct i2o_handler *h,
-			struct i2o_controller *iop, struct i2o_message *m)
-{
-	u32 *msg = (u32 *)m;
-	u8 unit  = (u8)(msg[2]>>16); // InitiatorContext
-	struct net_device *dev = i2o_landevs[unit];
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	u8 trl_count  = msg[3] & 0x000000FF;
-
-	if ((msg[4] >> 24) != I2O_REPLY_STATUS_SUCCESS) {
-		if (i2o_lan_handle_status(dev, msg))
-			return;
-	}
-
-#ifdef DRIVERDEBUG
-	i2o_report_status(KERN_INFO, dev->name, msg);
-#endif
-
-	/* DDM has handled transmit request(s), free sk_buffs.
-	 * We get similar single transaction reply also in error cases 
-	 * (except if msg failure or transaction error).
-	 */
-	while (trl_count) {
-		dev_kfree_skb_irq((struct sk_buff *)msg[4 + trl_count]);
-		dprintk(KERN_INFO "%s: tx skb freed (trl_count=%d).\n",
-			dev->name, trl_count);
-		atomic_dec(&priv->tx_out);
-		trl_count--;
-	}
-
-	/* If priv->tx_out had reached tx_max_out, the queue was stopped */
-
-	if (netif_queue_stopped(dev))
- 		netif_wake_queue(dev);
-}
-
-/*
- * i2o_lan_receive_post_reply(): Callback function to process incoming packets.
- */
-static void i2o_lan_receive_post_reply(struct i2o_handler *h,
-			struct i2o_controller *iop, struct i2o_message *m)
-{
-	u32 *msg = (u32 *)m;
-	u8 unit  = (u8)(msg[2]>>16); // InitiatorContext
-	struct net_device *dev = i2o_landevs[unit];
-
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_bucket_descriptor *bucket = (struct i2o_bucket_descriptor *)&msg[6];
-	struct i2o_packet_info *packet;
-	u8 trl_count = msg[3] & 0x000000FF;
-	struct sk_buff *skb, *old_skb;
-	unsigned long flags = 0;
-
-	if ((msg[4] >> 24) != I2O_REPLY_STATUS_SUCCESS) {
-		if (i2o_lan_handle_status(dev, msg))
-			return;
-
-		i2o_lan_release_buckets(dev, msg);
-		return;
-	}
-
-#ifdef DRIVERDEBUG
-	i2o_report_status(KERN_INFO, dev->name, msg);
-#endif
-
-	/* Else we are receiving incoming post. */
-
-	while (trl_count--) {
-		skb = (struct sk_buff *)bucket->context;
-		packet = (struct i2o_packet_info *)bucket->packet_info;
-		atomic_dec(&priv->buckets_out);
-
-		/* Sanity checks: Any weird characteristics in bucket? */
-
-		if (packet->flags & 0x0f || ! packet->flags & 0x40) {
-			if (packet->flags & 0x01)
-				printk(KERN_WARNING "%s: packet with errors, error code=0x%02x.\n",
-					dev->name, packet->status & 0xff);
-
-			/* The following shouldn't happen, unless parameters in
-			 * LAN_OPERATION group are changed during the run time.
-			 */
-			 if (packet->flags & 0x0c)
-				printk(KERN_DEBUG "%s: multi-bucket packets not supported!\n", 
-					dev->name);
-					
-			if (! packet->flags & 0x40)
-				printk(KERN_DEBUG "%s: multiple packets in a bucket not supported!\n", 
-					dev->name);
-
-			dev_kfree_skb_irq(skb);
-
-			bucket++;
-			continue;
-		}
-
-		/* Copy short packet to a new skb */
-		
-		if (packet->len < priv->rx_copybreak) {
-			old_skb = skb;
-			skb = (struct sk_buff *)dev_alloc_skb(packet->len+2);
-			if (skb == NULL) {
-				printk(KERN_ERR "%s: Can't allocate skb.\n", dev->name);
-				return;
-			}
-			skb_reserve(skb, 2);
-			memcpy(skb_put(skb, packet->len), old_skb->data, packet->len);
-
-			spin_lock_irqsave(&priv->fbl_lock, flags);
-			if (priv->i2o_fbl_tail < I2O_LAN_MAX_BUCKETS_OUT)
-				priv->i2o_fbl[++priv->i2o_fbl_tail] = old_skb;
-			else
-				dev_kfree_skb_irq(old_skb);
-
-			spin_unlock_irqrestore(&priv->fbl_lock, flags);
-		} else
-			skb_put(skb, packet->len);
-
-		/* Deliver to upper layers */
-
-		skb->dev = dev;
-		skb->protocol = priv->type_trans(skb, dev);
-		netif_rx(skb);
-
-		dev->last_rx = jiffies;
-
-		dprintk(KERN_INFO "%s: Incoming packet (%d bytes) delivered "
-			"to upper level.\n", dev->name, packet->len);
-
-		bucket++; // to next Packet Descriptor Block
-	}
-
-#ifdef DRIVERDEBUG
-	if (msg[5] == 0)
-		printk(KERN_INFO "%s: DDM out of buckets (priv->count = %d)!\n",
-		       dev->name, atomic_read(&priv->buckets_out));
-#endif
-
-	/* If DDM has already consumed bucket_thresh buckets, post new ones */
-
-	if (atomic_read(&priv->buckets_out) <= priv->max_buckets_out - priv->bucket_thresh) {
-		run_i2o_post_buckets_task.data = (void *)dev;
-		schedule_work(&run_i2o_post_buckets_task);
-	}
-
-	return;
-}
-
-/*
- * i2o_lan_reply(): Callback function to handle other incoming messages
- * except SendPost and ReceivePost.
- */
-static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop,
-			  struct i2o_message *m)
-{
-	u32 *msg = (u32 *)m;
-	u8 unit  = (u8)(msg[2]>>16); // InitiatorContext
-	struct net_device *dev = i2o_landevs[unit];
-
-	if ((msg[4] >> 24) != I2O_REPLY_STATUS_SUCCESS) {
-		if (i2o_lan_handle_status(dev, msg))
-			return;
-
-		/* In other error cases just report and continue */
-
-		i2o_report_status(KERN_INFO, dev->name, msg);
-	}
-
-#ifdef DRIVERDEBUG
-	i2o_report_status(KERN_INFO, dev->name, msg);
-#endif
-	switch (msg[1] >> 24) {
-		case LAN_RESET:
-		case LAN_SUSPEND:
-			/* default reply without payload */
-		break;
-
-		case I2O_CMD_UTIL_EVT_REGISTER: 
-		case I2O_CMD_UTIL_EVT_ACK:
-			i2o_lan_handle_event(dev, msg);
-		break;
-
-		case I2O_CMD_UTIL_PARAMS_SET:
-			/* default reply, results in ReplyPayload (not examined) */
-			switch (msg[3] >> 16) {
-			    case 1: dprintk(KERN_INFO "%s: Reply to set MAC filter mask.\n",
-					dev->name);
-			    break;
-			    case 2: dprintk(KERN_INFO "%s: Reply to set MAC table.\n", 
-					dev->name);
-			    break;
-			    default: printk(KERN_WARNING "%s: Bad group 0x%04X\n",
-			 		dev->name,msg[3] >> 16);
-			}
-		break;
-
-		default:
-			printk(KERN_ERR "%s: No handler for the reply.\n",
-		       		dev->name);
-			i2o_report_status(KERN_INFO, dev->name, msg);
-	}
-}
-
-/* Functions used by the above callback functions:
-=================================================*/
-/*
- * i2o_lan_release_buckets(): Free unused buckets (sk_buffs).
- */
-static void i2o_lan_release_buckets(struct net_device *dev, u32 *msg)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	u8 trl_elem_size = (u8)(msg[3]>>8 & 0x000000FF);
-	u8 trl_count = (u8)(msg[3] & 0x000000FF);
-	u32 *pskb = &msg[6];
-
-	while (trl_count--) {
-		dprintk(KERN_DEBUG "%s: Releasing unused rx skb %p (trl_count=%d).\n",
-			dev->name, (struct sk_buff*)(*pskb),trl_count+1);
-		dev_kfree_skb_irq((struct sk_buff *)(*pskb));
-		pskb += 1 + trl_elem_size;
-		atomic_dec(&priv->buckets_out);
-	}
-}
-
-/*
- * i2o_lan_event_reply(): Handle events.
- */
-static void i2o_lan_handle_event(struct net_device *dev, u32 *msg)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	struct i2o_controller *iop = i2o_dev->controller;
-	u32 max_evt_data_size =iop->status_block->inbound_frame_size-5;
-	struct i2o_reply {
-		u32 header[4];
-		u32 evt_indicator;
-		u32 data[max_evt_data_size];
-	} *evt = (struct i2o_reply *)msg;
-	int evt_data_len = ((msg[0]>>16) - 5) * 4; /* real size*/
-
-	printk(KERN_INFO "%s: I2O event - ", dev->name);
-
-	if (msg[1]>>24 == I2O_CMD_UTIL_EVT_ACK) {
-		printk("Event acknowledgement reply.\n");
-		return;
-	}
-
-	/* Else evt->function == I2O_CMD_UTIL_EVT_REGISTER) */
-
-	switch (evt->evt_indicator) {
-	case I2O_EVT_IND_STATE_CHANGE:  {
-		struct state_data {
-			u16 status;
-			u8 state;
-			u8 data;
-		} *evt_data = (struct state_data *)(evt->data[0]);
-
-		printk("State chance 0x%08x.\n", evt->data[0]);
-
-		/* If the DDM is in error state, recovery may be
-		 * possible if status = Transmit or Receive Control
-		 * Unit Inoperable.
-		 */
-		if (evt_data->state==0x05 && evt_data->status==0x0003)
-			i2o_lan_reset(dev);
-		break;
-	}
-
-	case I2O_EVT_IND_FIELD_MODIFIED: {
-		u16 *work16 = (u16 *)evt->data;
-		printk("Group 0x%04x, field %d changed.\n", work16[0], work16[1]);
-		break;
-	}
-
-	case I2O_EVT_IND_VENDOR_EVT: {
-		int i;
-		printk("Vendor event:\n");
-		for (i = 0; i < evt_data_len / 4; i++)
-			printk("   0x%08x\n", evt->data[i]);
-		break;
-	}
-
-	case I2O_EVT_IND_DEVICE_RESET:
-		/* Spec 2.0 p. 6-121:
-		 * The event of _DEVICE_RESET should also be responded
-		 */
-		printk("Device reset.\n");
-		if (i2o_event_ack(iop, msg) < 0)
-			printk("%s: Event Acknowledge timeout.\n", dev->name);
-		break;
-
-#if 0
-	case I2O_EVT_IND_EVT_MASK_MODIFIED:
-		printk("Event mask modified, 0x%08x.\n", evt->data[0]);
-		break;
-
-	case I2O_EVT_IND_GENERAL_WARNING:
-		printk("General warning 0x%04x.\n", evt->data[0]);
-		break;
-
-	case I2O_EVT_IND_CONFIGURATION_FLAG:
-		printk("Configuration requested.\n");
-		break;
-
-	case I2O_EVT_IND_CAPABILITY_CHANGE:
-		printk("Capability change 0x%04x.\n", evt->data[0]);
-		break;
-
-	case I2O_EVT_IND_DEVICE_STATE:
-		printk("Device state changed 0x%08x.\n", evt->data[0]);
-		break;
-#endif
-	case I2O_LAN_EVT_LINK_DOWN:
-		netif_carrier_off(dev); 
-		printk("Link to the physical device is lost.\n");
-		break;
-
-	case I2O_LAN_EVT_LINK_UP:
-		netif_carrier_on(dev); 
-		printk("Link to the physical device is (re)established.\n");
-		break;
-
-	case I2O_LAN_EVT_MEDIA_CHANGE:
-		printk("Media change.\n");
-		break;
-	default:
-		printk("0x%08x. No handler.\n", evt->evt_indicator);
-	}
-}
-
-/*
- * i2o_lan_receive_post(): Post buckets to receive packets.
- */
-static int i2o_lan_receive_post(struct net_device *dev)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	struct i2o_controller *iop = i2o_dev->controller;
-	struct sk_buff *skb;
-	u32 m, *msg;
-	u32 bucket_len = (dev->mtu + dev->hard_header_len);
-	u32 total = priv->max_buckets_out - atomic_read(&priv->buckets_out);
-	u32 bucket_count;
-	u32 *sgl_elem;
-	unsigned long flags;
-
-	/* Send (total/bucket_count) separate I2O requests */
-
-	while (total) {
-		m = I2O_POST_READ32(iop);
-		if (m == 0xFFFFFFFF)
-			return -ETIMEDOUT;
-		msg = (u32 *)(iop->mem_offset + m);
-
-		bucket_count = (total >= priv->sgl_max) ? priv->sgl_max : total;
-		total -= bucket_count;
-		atomic_add(bucket_count, &priv->buckets_out);
-
-		dprintk(KERN_INFO "%s: Sending %d buckets (size %d) to LAN DDM.\n",
-			dev->name, bucket_count, bucket_len);
-
-		/* Fill in the header */
-
-		__raw_writel(I2O_MESSAGE_SIZE(4 + 3 * bucket_count) | SGL_OFFSET_4, msg);
-		__raw_writel(LAN_RECEIVE_POST<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid, msg+1);
-		__raw_writel(priv->unit << 16 | lan_receive_context, msg+2);
-		__raw_writel(bucket_count, msg+3);
-		sgl_elem = &msg[4];
-
-		/* Fill in the payload - contains bucket_count SGL elements */
-
-		while (bucket_count--) {
-			spin_lock_irqsave(&priv->fbl_lock, flags);
-			if (priv->i2o_fbl_tail >= 0)
-				skb = priv->i2o_fbl[priv->i2o_fbl_tail--];
-			else {
-				skb = dev_alloc_skb(bucket_len + 2);
-				if (skb == NULL) {
-					spin_unlock_irqrestore(&priv->fbl_lock, flags);
-					return -ENOMEM;
-				}
-				skb_reserve(skb, 2);
-			}
-			spin_unlock_irqrestore(&priv->fbl_lock, flags);
-
-			__raw_writel(0x51000000 | bucket_len, sgl_elem);
-			__raw_writel((u32)skb,		      sgl_elem+1);
-			__raw_writel(virt_to_bus(skb->data),  sgl_elem+2);
-			sgl_elem += 3;
-		}
-
-		/* set LE flag and post  */
-		__raw_writel(__raw_readl(sgl_elem-3) | 0x80000000, (sgl_elem-3));
-		i2o_post_message(iop, m);
-	}
-
-	return 0;
-}
-
-/* Functions called from the network stack, and functions called by them:
-========================================================================*/
-
-/*
- * i2o_lan_reset(): Reset the LAN adapter into the operational state and
- * 	restore it to full operation.
- */
-static int i2o_lan_reset(struct net_device *dev)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	struct i2o_controller *iop = i2o_dev->controller;
-	u32 msg[5];
-
-	dprintk(KERN_INFO "%s: LAN RESET MESSAGE.\n", dev->name);
-	msg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
-	msg[1] = LAN_RESET<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid;
-	msg[2] = priv->unit << 16 | lan_context; // InitiatorContext
-	msg[3] = 0; 				 // TransactionContext
-	msg[4] = 0;				 // Keep posted buckets
-
-	if (i2o_post_this(iop, msg, sizeof(msg)) < 0)
-		return -ETIMEDOUT;
-
-	return 0;
-}
-
-/*
- * i2o_lan_suspend(): Put LAN adapter into a safe, non-active state.
- * 	IOP replies to any LAN class message with status error_no_data_transfer
- *	/ suspended.
- */
-static int i2o_lan_suspend(struct net_device *dev)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	struct i2o_controller *iop = i2o_dev->controller;
-	u32 msg[5];
-
-	dprintk(KERN_INFO "%s: LAN SUSPEND MESSAGE.\n", dev->name);
-	msg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
-	msg[1] = LAN_SUSPEND<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid;
-	msg[2] = priv->unit << 16 | lan_context; // InitiatorContext
-	msg[3] = 0; 				 // TransactionContext
-	msg[4] = 1 << 16; 			 // return posted buckets
-
-	if (i2o_post_this(iop, msg, sizeof(msg)) < 0)
-		return -ETIMEDOUT;
-
-	return 0;
-}
-
-/*
- * i2o_set_ddm_parameters:
- * These settings are done to ensure proper initial values for DDM.
- * They can be changed via proc file system or vai configuration utility.
- */
-static void i2o_set_ddm_parameters(struct net_device *dev)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	struct i2o_controller *iop = i2o_dev->controller;
-	u32 val;
-
-	/*
-	 * When PacketOrphanlimit is set to the maximum packet length,
-	 * the packets will never be split into two separate buckets
-	 */
-	val = dev->mtu + dev->hard_header_len;
-	if (i2o_set_scalar(iop, i2o_dev->lct_data.tid, 0x0004, 2, &val, sizeof(val)) < 0)
-		printk(KERN_WARNING "%s: Unable to set PacketOrphanLimit.\n",
-		       dev->name);
-	else
-		dprintk(KERN_INFO "%s: PacketOrphanLimit set to %d.\n",
-			dev->name, val);
-
-	/* When RxMaxPacketsBucket = 1, DDM puts only one packet into bucket */
-
-	val = 1;
-	if (i2o_set_scalar(iop, i2o_dev->lct_data.tid, 0x0008, 4, &val, sizeof(val)) <0)
-		printk(KERN_WARNING "%s: Unable to set RxMaxPacketsBucket.\n",
-		       dev->name);
-	else
-		dprintk(KERN_INFO "%s: RxMaxPacketsBucket set to %d.\n", 
-			dev->name, val);
-	return;
-}
-
-/* Functions called from the network stack:
-==========================================*/
-
-/*
- * i2o_lan_open(): Open the device to send/receive packets via
- * the network device.
- */
-static int i2o_lan_open(struct net_device *dev)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	struct i2o_controller *iop = i2o_dev->controller;
-	u32 mc_addr_group[64];
-
-	MOD_INC_USE_COUNT;
-
-	if (i2o_claim_device(i2o_dev, &i2o_lan_handler)) {
-		printk(KERN_WARNING "%s: Unable to claim the I2O LAN device.\n", dev->name);
-		MOD_DEC_USE_COUNT;
-		return -EAGAIN;
-	}
-	dprintk(KERN_INFO "%s: I2O LAN device (tid=%d) claimed by LAN OSM.\n",
-		dev->name, i2o_dev->lct_data.tid);
-
-	if (i2o_event_register(iop, i2o_dev->lct_data.tid,
-			       priv->unit << 16 | lan_context, 0, priv->i2o_event_mask) < 0)
-		printk(KERN_WARNING "%s: Unable to set the event mask.\n", dev->name);
-
-	i2o_lan_reset(dev);
-
-	/* Get the max number of multicast addresses */
-
-	if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0001, -1,
-			     &mc_addr_group, sizeof(mc_addr_group)) < 0 ) {
-		printk(KERN_WARNING "%s: Unable to query LAN_MAC_ADDRESS group.\n", dev->name);
-		MOD_DEC_USE_COUNT;
-		return -EAGAIN;
-	}
-	priv->max_size_mc_table = mc_addr_group[8];
-
-	/* Malloc space for free bucket list to resuse reveive post buckets */
-
-	priv->i2o_fbl = kmalloc(priv->max_buckets_out * sizeof(struct sk_buff *),
-				GFP_KERNEL);
-	if (priv->i2o_fbl == NULL) {
-		MOD_DEC_USE_COUNT;
-		return -ENOMEM;
-	}
-	priv->i2o_fbl_tail = -1;
-	priv->send_active = 0;
-
-	i2o_set_ddm_parameters(dev);
-	i2o_lan_receive_post(dev);
-
-	netif_start_queue(dev);
-
-	return 0;
-}
-
-/*
- * i2o_lan_close(): End the transfering.
- */
-static int i2o_lan_close(struct net_device *dev)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	struct i2o_controller *iop = i2o_dev->controller;
-	int ret = 0;
-
-	netif_stop_queue(dev);
-	i2o_lan_suspend(dev);
-
-	if (i2o_event_register(iop, i2o_dev->lct_data.tid,
-			       priv->unit << 16 | lan_context, 0, 0) < 0)
-		printk(KERN_WARNING "%s: Unable to clear the event mask.\n",
-		       dev->name);
-
-	while (priv->i2o_fbl_tail >= 0)
-		dev_kfree_skb(priv->i2o_fbl[priv->i2o_fbl_tail--]);
-
-	kfree(priv->i2o_fbl);
-
-	if (i2o_release_device(i2o_dev, &i2o_lan_handler)) {
-		printk(KERN_WARNING "%s: Unable to unclaim I2O LAN device "
-		       "(tid=%d).\n", dev->name, i2o_dev->lct_data.tid);
-		ret = -EBUSY;
-	}
-
-	MOD_DEC_USE_COUNT;
-
-	return ret;
-}
-
-/*
- * i2o_lan_tx_timeout(): Tx timeout handler.
- */
-static void i2o_lan_tx_timeout(struct net_device *dev)
-{
- 	if (!netif_queue_stopped(dev))
-		netif_start_queue(dev);
-}
-
-/*
- * i2o_lan_batch_send(): Send packets in batch. 
- * Both i2o_lan_sdu_send and i2o_lan_packet_send use this.
- */
-static void i2o_lan_batch_send(struct net_device *dev)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_controller *iop = priv->i2o_dev->controller;
-
-	spin_lock_irq(&priv->tx_lock);
-	if (priv->tx_count != 0) {
-		dev->trans_start = jiffies;
-		i2o_post_message(iop, priv->m);
-		dprintk(KERN_DEBUG "%s: %d packets sent.\n", dev->name, priv->tx_count);
-		priv->tx_count = 0;
-	}
-	priv->send_active = 0;
-	spin_unlock_irq(&priv->tx_lock);
-	MOD_DEC_USE_COUNT;
-}
-
-#ifdef CONFIG_NET_FC
-/*
- * i2o_lan_sdu_send(): Send a packet, MAC header added by the DDM.
- * Must be supported by Fibre Channel, optional for Ethernet/802.3,
- * Token Ring, FDDI
- */
-static int i2o_lan_sdu_send(struct sk_buff *skb, struct net_device *dev)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	struct i2o_controller *iop = i2o_dev->controller;
-	int tickssofar = jiffies - dev->trans_start;
-	u32 m, *msg;
-	u32 *sgl_elem;
-
-	spin_lock_irq(&priv->tx_lock);
-
-	priv->tx_count++;
-	atomic_inc(&priv->tx_out);
-
-	/* 
-	 * If tx_batch_mode = 0x00 forced to immediate mode
-	 * If tx_batch_mode = 0x01 forced to batch mode
-	 * If tx_batch_mode = 0x10 switch automatically, current mode immediate
-	 * If tx_batch_mode = 0x11 switch automatically, current mode batch
-	 *	If gap between two packets is > 0 ticks, switch to immediate
-	 */
-	if (priv->tx_batch_mode >> 1) // switch automatically
-		priv->tx_batch_mode = tickssofar ? 0x02 : 0x03;
-
-	if (priv->tx_count == 1) {
-		m = I2O_POST_READ32(iop);
-		if (m == 0xFFFFFFFF) {
-			spin_unlock_irq(&priv->tx_lock);
-			return 1;
-		}
-		msg = (u32 *)(iop->mem_offset + m);
-		priv->m = m;
-
-		__raw_writel(NINE_WORD_MSG_SIZE | 1<<12 | SGL_OFFSET_4, msg);
-		__raw_writel(LAN_PACKET_SEND<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid, msg+1);
-		__raw_writel(priv->unit << 16 | lan_send_context, msg+2); // InitiatorContext
-		__raw_writel(1 << 30 | 1 << 3, msg+3); 		 	  // TransmitControlWord
-
-		__raw_writel(0xD7000000 | skb->len, msg+4);  	     // MAC hdr included
-		__raw_writel((u32)skb, msg+5);  		     // TransactionContext
-		__raw_writel(virt_to_bus(skb->data), msg+6);
-		__raw_writel((u32)skb->mac.raw, msg+7);
-		__raw_writel((u32)skb->mac.raw+4, msg+8);
-
-		if ((priv->tx_batch_mode & 0x01) && !priv->send_active) {
-			priv->send_active = 1;
-			MOD_INC_USE_COUNT;
-			if (schedule_work(&priv->i2o_batch_send_task) == 0)
-				MOD_DEC_USE_COUNT;
-		}
-	} else {  /* Add new SGL element to the previous message frame */
-
-		msg = (u32 *)(iop->mem_offset + priv->m);
-		sgl_elem = &msg[priv->tx_count * 5 + 1];
-
-		__raw_writel(I2O_MESSAGE_SIZE((__raw_readl(msg)>>16) + 5) | 1<<12 | SGL_OFFSET_4, msg);
-		__raw_writel(__raw_readl(sgl_elem-5) & 0x7FFFFFFF, sgl_elem-5); /* clear LE flag */
-		__raw_writel(0xD5000000 | skb->len, sgl_elem);
-		__raw_writel((u32)skb, sgl_elem+1);
-		__raw_writel(virt_to_bus(skb->data), sgl_elem+2);
-		__raw_writel((u32)(skb->mac.raw), sgl_elem+3);
-		__raw_writel((u32)(skb->mac.raw)+1, sgl_elem+4);
-	}
-
-	/* If tx not in batch mode or frame is full, send immediatelly */
-
-	if (!(priv->tx_batch_mode & 0x01) || priv->tx_count == priv->sgl_max) {
-		dev->trans_start = jiffies;
-		i2o_post_message(iop, priv->m);
-		dprintk(KERN_DEBUG "%s: %d packets sent.\n", dev->name, priv->tx_count);
-		priv->tx_count = 0;
-	}
-
-	/* If DDMs TxMaxPktOut reached, stop queueing layer to send more */
-
-	if (atomic_read(&priv->tx_out) >= priv->tx_max_out)
-		netif_stop_queue(dev);
-
-	spin_unlock_irq(&priv->tx_lock);
-	return 0;
-}
-#endif /* CONFIG_NET_FC */
-
-/*
- * i2o_lan_packet_send(): Send a packet as is, including the MAC header.
- *
- * Must be supported by Ethernet/802.3, Token Ring, FDDI, optional for
- * Fibre Channel
- */
-static int i2o_lan_packet_send(struct sk_buff *skb, struct net_device *dev)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	struct i2o_controller *iop = i2o_dev->controller;
-	int tickssofar = jiffies - dev->trans_start;
-	u32 m, *msg;
-	u32 *sgl_elem;
-
-	spin_lock_irq(&priv->tx_lock);
-
-	priv->tx_count++;
-	atomic_inc(&priv->tx_out);
-
-	/* 
-	 * If tx_batch_mode = 0x00 forced to immediate mode
-	 * If tx_batch_mode = 0x01 forced to batch mode
-	 * If tx_batch_mode = 0x10 switch automatically, current mode immediate
-	 * If tx_batch_mode = 0x11 switch automatically, current mode batch
-	 *	If gap between two packets is > 0 ticks, switch to immediate
-	 */
-	if (priv->tx_batch_mode >> 1) // switch automatically
-		priv->tx_batch_mode = tickssofar ? 0x02 : 0x03;
-
-	if (priv->tx_count == 1) {
-		m = I2O_POST_READ32(iop);
-		if (m == 0xFFFFFFFF) {
-			spin_unlock_irq(&priv->tx_lock);
-			return 1;
-		}
-		msg = (u32 *)(iop->mem_offset + m);
-		priv->m = m;
-
-		__raw_writel(SEVEN_WORD_MSG_SIZE | 1<<12 | SGL_OFFSET_4, msg);
-		__raw_writel(LAN_PACKET_SEND<<24 | HOST_TID<<12 | i2o_dev->lct_data.tid, msg+1);
-		__raw_writel(priv->unit << 16 | lan_send_context, msg+2); // InitiatorContext
-		__raw_writel(1 << 30 | 1 << 3, msg+3); 		 	  // TransmitControlWord
-			// bit 30: reply as soon as transmission attempt is complete
-			// bit 3: Suppress CRC generation
-		__raw_writel(0xD5000000 | skb->len, msg+4);  	     // MAC hdr included
-		__raw_writel((u32)skb, msg+5);  		     // TransactionContext
-		__raw_writel(virt_to_bus(skb->data), msg+6);
-
-		if ((priv->tx_batch_mode & 0x01) && !priv->send_active) {
-			priv->send_active = 1;
-			MOD_INC_USE_COUNT;
-			if (schedule_work(&priv->i2o_batch_send_task) == 0)
-				MOD_DEC_USE_COUNT;
-		}
-	} else {  /* Add new SGL element to the previous message frame */
-
-		msg = (u32 *)(iop->mem_offset + priv->m);
-		sgl_elem = &msg[priv->tx_count * 3 + 1];
-
-		__raw_writel(I2O_MESSAGE_SIZE((__raw_readl(msg)>>16) + 3) | 1<<12 | SGL_OFFSET_4, msg);
-		__raw_writel(__raw_readl(sgl_elem-3) & 0x7FFFFFFF, sgl_elem-3); /* clear LE flag */
-		__raw_writel(0xD5000000 | skb->len, sgl_elem);
-		__raw_writel((u32)skb, sgl_elem+1);
-		__raw_writel(virt_to_bus(skb->data), sgl_elem+2);
-	}
-
-	/* If tx is in immediate mode or frame is full, send now */
-
-	if (!(priv->tx_batch_mode & 0x01) || priv->tx_count == priv->sgl_max) {
-		dev->trans_start = jiffies;
-		i2o_post_message(iop, priv->m);
-		dprintk(KERN_DEBUG "%s: %d packets sent.\n", dev->name, priv->tx_count);
-		priv->tx_count = 0;
-	}
-
-	/* If DDMs TxMaxPktOut reached, stop queueing layer to send more */
-
-	if (atomic_read(&priv->tx_out) >= priv->tx_max_out)
-		netif_stop_queue(dev);
-
-	spin_unlock_irq(&priv->tx_lock);
-	return 0;
-}
-
-/*
- * i2o_lan_get_stats(): Fill in the statistics.
- */
-static struct net_device_stats *i2o_lan_get_stats(struct net_device *dev)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	struct i2o_controller *iop = i2o_dev->controller;
-	u64 val64[16];
-	u64 supported_group[4] = { 0, 0, 0, 0 };
-
-	if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0100, -1, val64,
-			     sizeof(val64)) < 0)
-		printk(KERN_INFO "%s: Unable to query LAN_HISTORICAL_STATS.\n", dev->name);
-	else {
-		dprintk(KERN_DEBUG "%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];
-	}
-
-	if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0180, -1,
-			     &supported_group, sizeof(supported_group)) < 0)
-		printk(KERN_INFO "%s: Unable to query LAN_SUPPORTED_OPTIONAL_HISTORICAL_STATS.\n", dev->name);
-
-	if (supported_group[2]) {
-		if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0183, -1,
-				     val64, sizeof(val64)) < 0)
-			printk(KERN_INFO "%s: Unable to query LAN_OPTIONAL_RX_HISTORICAL_STATS.\n", dev->name);
-		else {
-			dprintk(KERN_DEBUG "%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->lct_data.sub_class == I2O_LAN_ETHERNET) {
-		u64 supported_stats = 0;
-		if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0200, -1,
-				     val64, sizeof(val64)) < 0)
-			printk(KERN_INFO "%s: Unable to query LAN_802_3_HISTORICAL_STATS.\n", dev->name);
-		else {
-			dprintk(KERN_DEBUG "%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];
-		}
-
-		if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0280, -1,
-				     &supported_stats, sizeof(supported_stats)) < 0)
-			printk(KERN_INFO "%s: Unable to query LAN_SUPPORTED_802_3_HISTORICAL_STATS.\n", dev->name);
-
-		if (supported_stats != 0) {
-			if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0281, -1,
-					     val64, sizeof(val64)) < 0)
-				printk(KERN_INFO "%s: Unable to query LAN_OPTIONAL_802_3_HISTORICAL_STATS.\n", dev->name);
-			else {
-				dprintk(KERN_DEBUG "%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->lct_data.sub_class == I2O_LAN_TR) {
-		if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0300, -1,
-				     val64, sizeof(val64)) < 0)
-			printk(KERN_INFO "%s: Unable to query LAN_802_5_HISTORICAL_STATS.\n", dev->name);
-		else {
-			struct tr_statistics *stats =
-				(struct tr_statistics *)&priv->stats;
-			dprintk(KERN_DEBUG "%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->lct_data.sub_class == I2O_LAN_FDDI) {
-		if (i2o_query_scalar(iop, i2o_dev->lct_data.tid, 0x0400, -1,
-				     val64, sizeof(val64)) < 0)
-			printk(KERN_INFO "%s: Unable to query LAN_FDDI_HISTORICAL_STATS.\n", dev->name);
-		else {
-			dprintk(KERN_DEBUG "%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
-
-#ifdef CONFIG_NET_FC
-	/* Fibre Channel Statistics not yet defined in 1.53 nor 2.0 */
-#endif
-
-	return (struct net_device_stats *)&priv->stats;
-}
-
-/* 
- * i2o_lan_set_mc_filter(): Post a request to set multicast filter.
- */
-int i2o_lan_set_mc_filter(struct net_device *dev, u32 filter_mask)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;	
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	struct i2o_controller *iop = i2o_dev->controller;
-	u32 msg[10]; 
-
-	msg[0] = TEN_WORD_MSG_SIZE | SGL_OFFSET_5;
-	msg[1] = I2O_CMD_UTIL_PARAMS_SET << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid;
-	msg[2] = priv->unit << 16 | lan_context;
-	msg[3] = 0x0001 << 16 | 3 ;	// TransactionContext: group&field
-	msg[4] = 0;
-	msg[5] = 0xCC000000 | 16; 			// Immediate data SGL
-	msg[6] = 1;					// OperationCount
-	msg[7] = 0x0001<<16 | I2O_PARAMS_FIELD_SET;	// Group, Operation
-	msg[8] = 3 << 16 | 1; 				// FieldIndex, FieldCount 
-	msg[9] = filter_mask;				// Value
-
-	return i2o_post_this(iop, msg, sizeof(msg));
-}
-
-/* 
- * i2o_lan_set_mc_table(): Post a request to set LAN_MULTICAST_MAC_ADDRESS table.
- */
-int i2o_lan_set_mc_table(struct net_device *dev)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;	
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	struct i2o_controller *iop = i2o_dev->controller;
-	struct dev_mc_list *mc;
-	u32 msg[10 + 2 * dev->mc_count]; 
-	u8 *work8 = (u8 *)(msg + 10);
-
-	msg[0] = I2O_MESSAGE_SIZE(10 + 2 * dev->mc_count) | SGL_OFFSET_5;
-	msg[1] = I2O_CMD_UTIL_PARAMS_SET << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid;
-	msg[2] = priv->unit << 16 | lan_context;	// InitiatorContext
-	msg[3] = 0x0002 << 16 | (u16)-1;		// TransactionContext
-	msg[4] = 0;					// OperationFlags
-	msg[5] = 0xCC000000 | (16 + 8 * dev->mc_count);	// Immediate data SGL
-	msg[6] = 2;					// OperationCount
-	msg[7] = 0x0002 << 16 | I2O_PARAMS_TABLE_CLEAR;	// Group, Operation
-	msg[8] = 0x0002 << 16 | I2O_PARAMS_ROW_ADD;     // Group, Operation
-	msg[9] = dev->mc_count << 16 | (u16)-1; 	// RowCount, FieldCount
-
-        for (mc = dev->mc_list; mc ; mc = mc->next, work8 += 8) {
-		  memset(work8, 0, 8);
-                  memcpy(work8, mc->dmi_addr, mc->dmi_addrlen); // Values
-	}
-
-	return i2o_post_this(iop, msg, sizeof(msg));
-}
-
-/*
- * i2o_lan_set_multicast_list(): Enable a network device to receive packets
- *      not send to the protocol address.
- */
-static void i2o_lan_set_multicast_list(struct net_device *dev)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	u32 filter_mask;
-
-	if (dev->flags & IFF_PROMISC) {
-		filter_mask = 0x00000002;
-		dprintk(KERN_INFO "%s: Enabling promiscuous mode...\n", dev->name);
-	} else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > priv->max_size_mc_table) {
-		filter_mask = 0x00000004;
-		dprintk(KERN_INFO "%s: Enabling all multicast mode...\n", dev->name);
-	} else if (dev->mc_count) {
-		filter_mask = 0x00000000;
-		dprintk(KERN_INFO "%s: Enabling multicast mode...\n", dev->name);
-		if (i2o_lan_set_mc_table(dev) < 0)
-			printk(KERN_WARNING "%s: Unable to send MAC table.\n", dev->name);
-	} else {
-		filter_mask = 0x00000300; // Broadcast, Multicast disabled
-		dprintk(KERN_INFO "%s: Enabling unicast mode...\n", dev->name);
-	}
-
-	/* Finally copy new FilterMask to DDM */
-
-	if (i2o_lan_set_mc_filter(dev, filter_mask) < 0)
-		printk(KERN_WARNING "%s: Unable to send MAC FilterMask.\n", dev->name);
-}
-
-/*
- * i2o_lan_change_mtu(): Change maximum transfer unit size.
- */
-static int i2o_lan_change_mtu(struct net_device *dev, int new_mtu)
-{
-	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-	struct i2o_device *i2o_dev = priv->i2o_dev;
-	u32 max_pkt_size;
-
-	if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data.tid,
-		 	     0x0000, 6, &max_pkt_size, 4) < 0)
-		return -EFAULT;
-
-	if (new_mtu < 68 || new_mtu > 9000 || new_mtu > max_pkt_size)
-		return -EINVAL;
-
-	dev->mtu = new_mtu;
-
-	i2o_lan_suspend(dev);   	// to SUSPENDED state, return buckets
-
-	while (priv->i2o_fbl_tail >= 0) // free buffered buckets
-		dev_kfree_skb(priv->i2o_fbl[priv->i2o_fbl_tail--]);
-
-	i2o_lan_reset(dev);		// to OPERATIONAL state
-	i2o_set_ddm_parameters(dev); 	// reset some parameters
-	i2o_lan_receive_post(dev); 	// post new buckets (new size)
-
-	return 0;
-}
-
-/* Functions to initialize I2O LAN OSM:
-======================================*/
-
-/*
- * i2o_lan_register_device(): Register LAN class device to kernel.
- */
-struct net_device *i2o_lan_register_device(struct i2o_device *i2o_dev)
-{
-	struct net_device *dev = NULL;
-	struct i2o_lan_local *priv = NULL;
-	u8 hw_addr[8];
-	u32 tx_max_out = 0;
-	unsigned short (*type_trans)(struct sk_buff *, struct net_device *);
-	void (*unregister_dev)(struct net_device *dev);
-
-	switch (i2o_dev->lct_data.sub_class) {
-	case I2O_LAN_ETHERNET:
-		dev = init_etherdev(NULL, sizeof(struct i2o_lan_local));
-		if (dev == NULL)
-			return NULL;
-		type_trans = eth_type_trans;
-		unregister_dev = unregister_netdev;
-		break;
-
-#ifdef CONFIG_ANYLAN
-	case I2O_LAN_100VG:
-		printk(KERN_ERR "i2o_lan: 100base VG not yet supported.\n");
-		return NULL;
-		break;
-#endif
-
-#ifdef CONFIG_TR
-	case I2O_LAN_TR:
-		dev = init_trdev(NULL, sizeof(struct i2o_lan_local));
-		if (dev==NULL)
-			return NULL;
-		type_trans = tr_type_trans;
-		unregister_dev = unregister_trdev;
-		break;
-#endif
-
-#ifdef CONFIG_FDDI
-	case I2O_LAN_FDDI:
-	{
-		int size = sizeof(struct net_device) + sizeof(struct i2o_lan_local);
-
-		dev = (struct net_device *) kmalloc(size, GFP_KERNEL);
-		if (dev == NULL)
-			return NULL;
-		memset((char *)dev, 0, size);
-	    	dev->priv = (void *)(dev + 1);
-
-		if (dev_alloc_name(dev, "fddi%d") < 0) {
-			printk(KERN_WARNING "i2o_lan: Too many FDDI devices.\n");
-			kfree(dev);
-			return NULL;
-		}
-		type_trans = fddi_type_trans;
-		unregister_dev = (void *)unregister_netdevice;
-
-		fddi_setup(dev);
-		register_netdev(dev);
-	}
-	break;
-#endif
-
-#ifdef CONFIG_NET_FC
-	case I2O_LAN_FIBRE_CHANNEL:
-		dev = init_fcdev(NULL, sizeof(struct i2o_lan_local));
-		if (dev == NULL)
-			return NULL;
-		type_trans = NULL;
-/* FIXME: Move fc_type_trans() from drivers/net/fc/iph5526.c to net/802/fc.c
- * and export it in include/linux/fcdevice.h
- *		type_trans = fc_type_trans;
- */
-		unregister_dev = (void *)unregister_fcdev;
-		break;
-#endif
-
-	case I2O_LAN_UNKNOWN:
-	default:
-		printk(KERN_ERR "i2o_lan: LAN type 0x%04x not supported.\n",
-		       i2o_dev->lct_data.sub_class);
-		return NULL;
-	}
-
-	priv = (struct i2o_lan_local *)dev->priv;
-	priv->i2o_dev = i2o_dev;
-	priv->type_trans = type_trans;
-	priv->sgl_max = (i2o_dev->controller->status_block->inbound_frame_size - 4) / 3;
-	atomic_set(&priv->buckets_out, 0);
-
-	/* Set default values for user configurable parameters */
-	/* Private values are changed via /proc file system */
-
-	priv->max_buckets_out = max_buckets_out;
-	priv->bucket_thresh   = bucket_thresh;
-	priv->rx_copybreak    = rx_copybreak;
-	priv->tx_batch_mode   = tx_batch_mode & 0x03;
-	priv->i2o_event_mask  = i2o_event_mask;
-
-	priv->tx_lock	      = SPIN_LOCK_UNLOCKED;
-	priv->fbl_lock	      = SPIN_LOCK_UNLOCKED;
-
-	unit++;
-	i2o_landevs[unit] = dev;
-	priv->unit = unit;
-
-	if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data.tid,
-			     0x0001, 0, &hw_addr, sizeof(hw_addr)) < 0) {
-		printk(KERN_ERR "%s: Unable to query hardware address.\n", dev->name);
-		unit--;
-		unregister_dev(dev);
-		kfree(dev);
-		return NULL;
-	}
-	dprintk(KERN_DEBUG "%s: hwaddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
- 		dev->name, hw_addr[0], hw_addr[1], hw_addr[2], hw_addr[3],
-		hw_addr[4], hw_addr[5]);
-
-	dev->addr_len = 6;
-	memcpy(dev->dev_addr, hw_addr, 6);
-
-	if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data.tid,
-			     0x0007, 2, &tx_max_out, sizeof(tx_max_out)) < 0) {
-		printk(KERN_ERR "%s: Unable to query max TX queue.\n", dev->name);
-		unit--;
-		unregister_dev(dev);
-		kfree(dev);
-		return NULL;
-	}
-	dprintk(KERN_INFO "%s: Max TX Outstanding = %d.\n", dev->name, tx_max_out);
-	priv->tx_max_out = tx_max_out;
-	atomic_set(&priv->tx_out, 0);
-	priv->tx_count = 0;
-
-	INIT_LIST_HEAD(&priv->i2o_batch_send_task.list);
-	priv->i2o_batch_send_task.sync    = 0;
-	INIT_WORK(&priv->i2o_batch_send_task, (void *)i2o_lan_batch_send,
-			(void *)dev);
-
-	dev->open		= i2o_lan_open;
-	dev->stop		= i2o_lan_close;
-	dev->get_stats		= i2o_lan_get_stats;
-	dev->set_multicast_list = i2o_lan_set_multicast_list;
-	dev->tx_timeout		= i2o_lan_tx_timeout;
-	dev->watchdog_timeo	= I2O_LAN_TX_TIMEOUT;
-
-#ifdef CONFIG_NET_FC
-	if (i2o_dev->lct_data.sub_class == I2O_LAN_FIBRE_CHANNEL)
-		dev->hard_start_xmit = i2o_lan_sdu_send;
-	else
-#endif
-		dev->hard_start_xmit = i2o_lan_packet_send;
-
-	if (i2o_dev->lct_data.sub_class == I2O_LAN_ETHERNET)
-		dev->change_mtu	= i2o_lan_change_mtu;
-
-	return dev;
-}
-
-#ifdef MODULE
-#define i2o_lan_init	init_module
-#endif
-
-int __init i2o_lan_init(void)
-{
-	struct net_device *dev;
-	int i;
-
-	printk(KERN_INFO "I2O LAN OSM (C) 1999 University of Helsinki.\n");
-
-	/* Module params are used as global defaults for private values */
-
-	if (max_buckets_out > I2O_LAN_MAX_BUCKETS_OUT)
-		max_buckets_out = I2O_LAN_MAX_BUCKETS_OUT;
-	if (bucket_thresh > max_buckets_out)
-		bucket_thresh = max_buckets_out;
-
-	/* Install handlers for incoming replies */
-
-	if (i2o_install_handler(&i2o_lan_send_handler) < 0) {
- 		printk(KERN_ERR "i2o_lan: Unable to register I2O LAN OSM.\n");
-		return -EINVAL;
-	}
-	lan_send_context = i2o_lan_send_handler.context;
-
-	if (i2o_install_handler(&i2o_lan_receive_handler) < 0) {
- 		printk(KERN_ERR "i2o_lan: Unable to register I2O LAN OSM.\n");
-		return -EINVAL;
-	}
-	lan_receive_context = i2o_lan_receive_handler.context;
-
-	if (i2o_install_handler(&i2o_lan_handler) < 0) {
- 		printk(KERN_ERR "i2o_lan: Unable to register I2O LAN OSM.\n");
-		return -EINVAL;
-	}
-	lan_context = i2o_lan_handler.context;
-
-	for(i=0; i <= MAX_LAN_CARDS; i++)
-		i2o_landevs[i] = NULL;
-
-	for (i=0; i < MAX_I2O_CONTROLLERS; i++) {
-		struct i2o_controller *iop = i2o_find_controller(i);
-		struct i2o_device *i2o_dev;
-
-		if (iop==NULL)
-			continue;
-
-		for (i2o_dev=iop->devices;i2o_dev != NULL;i2o_dev=i2o_dev->next) {
-
-			if (i2o_dev->lct_data.class_id != I2O_CLASS_LAN)
-				continue;
-
-			/* Make sure device not already claimed by an ISM */
-			if (i2o_dev->lct_data.user_tid != 0xFFF)
-				continue;
-
-			if (unit == MAX_LAN_CARDS) {
-				i2o_unlock_controller(iop);
-				printk(KERN_WARNING "i2o_lan: Too many I2O LAN devices.\n");
-				return -EINVAL;
-			}
-
-			dev = i2o_lan_register_device(i2o_dev);
- 			if (dev == NULL) {
-				printk(KERN_ERR "i2o_lan: Unable to register I2O LAN device 0x%04x.\n",
-				       i2o_dev->lct_data.sub_class);
-				continue;
-			}
-
-			printk(KERN_INFO "%s: I2O LAN device registered, "
-				"subclass = 0x%04x, unit = %d, tid = %d.\n",
-				dev->name, i2o_dev->lct_data.sub_class,
-				((struct i2o_lan_local *)dev->priv)->unit,
-				i2o_dev->lct_data.tid);
-		}
-
-		i2o_unlock_controller(iop);
-	}
-
-	dprintk(KERN_INFO "%d I2O LAN devices found and registered.\n", unit+1);
-
-	return 0;
-}
-
-#ifdef MODULE
-
-void cleanup_module(void)
-{
-	int i;
-
-	for (i = 0; i <= unit; i++) {
-		struct net_device *dev = i2o_landevs[i];
-		struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;
-		struct i2o_device *i2o_dev = priv->i2o_dev;
-
-		switch (i2o_dev->lct_data.sub_class) {
-		case I2O_LAN_ETHERNET:
-			unregister_netdev(dev);
-			break;
-#ifdef CONFIG_FDDI
-		case I2O_LAN_FDDI:
-			unregister_netdevice(dev);
-			break;
-#endif
-#ifdef CONFIG_TR
-		case I2O_LAN_TR:
-			unregister_trdev(dev);
-			break;
-#endif
-#ifdef CONFIG_NET_FC
-		case I2O_LAN_FIBRE_CHANNEL:
-			unregister_fcdev(dev);
-			break;
-#endif
-		default:
-			printk(KERN_WARNING "%s: Spurious I2O LAN subclass 0x%08x.\n",
-			       dev->name, i2o_dev->lct_data.sub_class);
-		}
-
-		dprintk(KERN_INFO "%s: I2O LAN device unregistered.\n",
-			dev->name);
-		kfree(dev);
-	}
-
-	i2o_remove_handler(&i2o_lan_handler);
-	i2o_remove_handler(&i2o_lan_send_handler);
-	i2o_remove_handler(&i2o_lan_receive_handler);
-}
-
-MODULE_AUTHOR("University of Helsinki, Department of Computer Science");
-MODULE_DESCRIPTION("I2O Lan OSM");
-MODULE_LICENSE("GPL");
-
-
-MODULE_PARM(max_buckets_out, "1-" __MODULE_STRING(I2O_LAN_MAX_BUCKETS_OUT) "i");
-MODULE_PARM_DESC(max_buckets_out, "Total number of buckets to post (1-)");
-MODULE_PARM(bucket_thresh, "1-" __MODULE_STRING(I2O_LAN_MAX_BUCKETS_OUT) "i");
-MODULE_PARM_DESC(bucket_thresh, "Bucket post threshold (1-)");
-MODULE_PARM(rx_copybreak, "1-" "i");
-MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy only small frames (1-)");
-MODULE_PARM(tx_batch_mode, "0-2" "i");
-MODULE_PARM_DESC(tx_batch_mode, "0=Send immediatelly, 1=Send in batches, 2=Switch automatically");
-
-#endif
diff -Nru a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
--- a/drivers/message/i2o/i2o_scsi.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/message/i2o/i2o_scsi.c	Fri Feb 14 15:53:12 2003
@@ -224,7 +224,7 @@
 			spin_unlock_irqrestore(&retry_lock, flags);
 			/* Create a scsi error for this */
 			current_command = (Scsi_Cmnd *)m[3];
-			lock = current_command->host->host_lock;
+			lock = current_command->device->host->host_lock;
 			printk("Aborted %ld\n", current_command->serial_number);
 
 			spin_lock_irqsave(lock, flags);
@@ -328,7 +328,7 @@
 	else if (current_command->request_bufflen)
 		pci_unmap_single(c->pdev, (dma_addr_t)((long)current_command->SCp.ptr), current_command->request_bufflen, scsi_to_pci_dma_dir(current_command->sc_data_direction));
 
-	lock = current_command->host->host_lock;
+	lock = current_command->device->host->host_lock;
 	spin_lock_irqsave(lock, flags);
 	current_command->scsi_done(current_command);
 	spin_unlock_irqrestore(lock, flags);
@@ -606,7 +606,7 @@
 	 *	Do the incoming paperwork
 	 */
 	 
-	host = SCpnt->host;
+	host = SCpnt->device->host;
 	hostdata = (struct i2o_scsi_host *)host->hostdata;
 	 
 	c = hostdata->controller;
@@ -615,13 +615,13 @@
 
 	SCpnt->scsi_done = done;
 	
-	if(SCpnt->target > 15)
+	if(SCpnt->device->id > 15)
 	{
-		printk(KERN_ERR "i2o_scsi: Wild target %d.\n", SCpnt->target);
+		printk(KERN_ERR "i2o_scsi: Wild target %d.\n", SCpnt->device->id);
 		return -1;
 	}
 	
-	tid = hostdata->task[SCpnt->target][SCpnt->lun];
+	tid = hostdata->task[SCpnt->device->id][SCpnt->device->lun];
 	
 	dprintk(("qcmd: Tid = %d\n", tid));
 	
@@ -712,10 +712,10 @@
 		 *	with tagged queueing. We throw in the odd ordered
 		 *	tag to stop them starving themselves.
 		 */
-		if((jiffies - hostdata->tagclock[SCpnt->target][SCpnt->lun]) > (5*HZ))
+		if((jiffies - hostdata->tagclock[SCpnt->device->id][SCpnt->device->lun]) > (5*HZ))
 		{
 			tag=0x01800000;		/* ORDERED! */
-			hostdata->tagclock[SCpnt->target][SCpnt->lun]=jiffies;
+			hostdata->tagclock[SCpnt->device->id][SCpnt->device->lun]=jiffies;
 		}
 		else
 		{
@@ -916,9 +916,9 @@
 	
 	printk(KERN_WARNING "i2o_scsi: Aborting command block.\n");
 	
-	host = SCpnt->host;
+	host = SCpnt->device->host;
 	hostdata = (struct i2o_scsi_host *)host->hostdata;
-	tid = hostdata->task[SCpnt->target][SCpnt->lun];
+	tid = hostdata->task[SCpnt->device->id][SCpnt->device->lun];
 	if(tid==-1)
 	{
 		printk(KERN_ERR "i2o_scsi: Impossible command to abort!\n");
@@ -982,7 +982,7 @@
 	 */
 
 	
-	host = SCpnt->host;
+	host = SCpnt->device->host;
 
 	spin_unlock_irq(host->host_lock);
 
diff -Nru a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
--- a/drivers/mtd/devices/blkmtd.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/mtd/devices/blkmtd.c	Fri Feb 14 15:53:08 2003
@@ -303,12 +303,7 @@
 
   DECLARE_WAITQUEUE(wait, tsk);
   DEBUG(1, "blkmtd: writetask: starting (pid = %d)\n", tsk->pid);
-  daemonize();
-  strcpy(tsk->comm, "blkmtdd");
-  spin_lock_irq(&tsk->sighand->siglock);
-  sigfillset(&tsk->blocked);
-  recalc_sigpending();
-  spin_unlock_irq(&tsk->sighand->siglock);
+  daemonize("blkmtdd");
 
   if(alloc_kiovec(1, &iobuf)) {
     printk("blkmtd: write_queue_task cant allocate kiobuf\n");
diff -Nru a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
--- a/drivers/mtd/mtdblock.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/mtd/mtdblock.c	Fri Feb 14 15:53:09 2003
@@ -452,12 +452,7 @@
 
 	/* we might get involved when memory gets low, so use PF_MEMALLOC */
 	tsk->flags |= PF_MEMALLOC;
-	strcpy(tsk->comm, "mtdblockd");
-	spin_lock_irq(&tsk->sighand->siglock);
-	sigfillset(&tsk->blocked);
-	recalc_sigpending();
-	spin_unlock_irq(&tsk->sighand->siglock);
-	daemonize();
+	daemonize("mtdblockd");
 
 	while (!leaving) {
 		add_wait_queue(&thr_wq, &wait);
diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c
--- a/drivers/net/3c509.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/net/3c509.c	Fri Feb 14 15:53:08 2003
@@ -338,16 +338,6 @@
 	dev->watchdog_timeo = TX_TIMEOUT;
 	dev->do_ioctl = netdev_ioctl;
 
-#ifdef CONFIG_PM
-	/* register power management */
-	lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
-	if (lp->pmdev) {
-		struct pm_dev *p;
-		p = lp->pmdev;
-		p->data = (struct net_device *)dev;
-	}
-#endif
-
 	return 0;
 }
 
@@ -417,6 +407,13 @@
 					phys_addr[j] =
 						htons(read_eeprom(ioaddr, j));
 			if_port = read_eeprom(ioaddr, 8) >> 14;
+			if (!(dev = init_etherdev(NULL, sizeof(struct el3_private)))) {
+					release_region(ioaddr, EL3_IO_EXTENT);
+					pnp_device_detach(idev);
+					return -ENOMEM;
+			}
+
+			SET_MODULE_OWNER(dev);
 			pnp_cards++;
 			goto found;
 		}
@@ -497,24 +494,29 @@
 	}
 	irq = id_read_eeprom(9) >> 12;
 
-#if 0							/* Huh ?
-								   Can someone explain what is this for ? */
-	if (dev) {					/* Set passed-in IRQ or I/O Addr. */
-		if (dev->irq > 1  &&  dev->irq < 16)
+	if (!(dev = init_etherdev(NULL, sizeof(struct el3_private))))
+			return -ENOMEM;
+
+	SET_MODULE_OWNER(dev);
+	
+	/* Set passed-in IRQ or I/O Addr. */
+	if (dev->irq > 1  &&  dev->irq < 16)
 			irq = dev->irq;
 
-		if (dev->base_addr) {
+	if (dev->base_addr) {
 			if (dev->mem_end == 0x3c509 			/* Magic key */
 				&& dev->base_addr >= 0x200  &&  dev->base_addr <= 0x3e0)
-				ioaddr = dev->base_addr & 0x3f0;
-			else if (dev->base_addr != ioaddr)
-				return -ENODEV;
-		}
+					ioaddr = dev->base_addr & 0x3f0;
+			else if (dev->base_addr != ioaddr) {
+					unregister_netdev (dev);
+					return -ENODEV;
+			}
 	}
-#endif
 
-	if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509"))
-		return -EBUSY;
+	if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) {
+			unregister_netdev (dev);
+			return -EBUSY;
+	}
 
 	/* Set the adaptor tag so that the next card can be found. */
 	outb(0xd0 + ++current_tag, id_port);
@@ -524,6 +526,7 @@
 
 	EL3WINDOW(0);
 	if (inw(ioaddr) != 0x6d50) {
+		unregister_netdev (dev);
 		release_region(ioaddr, EL3_IO_EXTENT);
 		return -ENODEV;
 	}
@@ -531,12 +534,9 @@
 	/* Free the interrupt so that some other card can use it. */
 	outw(0x0f00, ioaddr + WN0_IRQ);
 
-	dev = init_etherdev(NULL, sizeof(struct el3_private));
-	if (dev == NULL) {
-	    release_region(ioaddr, EL3_IO_EXTENT);
-		return -ENOMEM;
-	}
-	SET_MODULE_OWNER(dev);
+#ifdef __ISAPNP__	
+ found:							/* PNP jumps here... */
+#endif /* __ISAPNP__ */
 
 	memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
 	dev->base_addr = ioaddr;
@@ -547,6 +547,16 @@
 	lp->dev = &idev->dev;
 #endif
 
+#ifdef CONFIG_PM
+	/* register power management */
+	lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
+	if (lp->pmdev) {
+		struct pm_dev *p;
+		p = lp->pmdev;
+		p->data = (struct net_device *)dev;
+	}
+#endif
+
 	return el3_common_init (dev);
 }
 
@@ -667,6 +677,7 @@
 }
 #endif
 
+#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
 /* This remove works for all device types.
  *
  * The net dev must be stored in the driver_data field */
@@ -679,6 +690,7 @@
 		el3_common_remove (dev);
 		return 0;
 }
+#endif
 
 /* Read a word from the EEPROM using the regular EEPROM access register.
    Assume that we are in register window zero.
diff -Nru a/drivers/net/3c59x.c b/drivers/net/3c59x.c
--- a/drivers/net/3c59x.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/net/3c59x.c	Fri Feb 14 15:53:08 2003
@@ -181,7 +181,7 @@
     - See http://www.zip.com.au/~akpm/linux/#3c59x-2.3 for more details.
     - Also see Documentation/networking/vortex.txt
 
-   LK1.1.19 10Nov09 Marc Zyngier <maz@wild-wind.fr.eu.org>
+   LK1.1.19 10Nov02 Marc Zyngier <maz@wild-wind.fr.eu.org>
     - EISA sysfs integration.
 */
 
@@ -817,7 +817,11 @@
 	u32 power_state[16];
 };
 
+#ifdef CONFIG_PCI
 #define DEVICE_PCI(dev) (((dev)->bus == &pci_bus_type) ? to_pci_dev((dev)) : NULL)
+#else
+#define DEVICE_PCI(dev) NULL
+#endif
 
 #define VORTEX_PCI(vp) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL)
 
@@ -1768,10 +1772,12 @@
 			if (vortex_debug > 1)
 				printk(KERN_DEBUG "%s: Media %s has link beat, %x.\n",
 					   dev->name, media_tbl[dev->if_port].name, media_status);
-		} else if (vortex_debug > 1) {
+		} else {
 			netif_carrier_off(dev);
-			printk(KERN_DEBUG "%s: Media %s has no link beat, %x.\n",
-				   dev->name, media_tbl[dev->if_port].name, media_status);
+			if (vortex_debug > 1) {
+				printk(KERN_DEBUG "%s: Media %s has no link beat, %x.\n",
+					   dev->name, media_tbl[dev->if_port].name, media_status);
+			}
 		}
 		break;
 	case XCVR_MII: case XCVR_NWAY:
diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/net/8139too.c	Fri Feb 14 15:53:08 2003
@@ -1588,14 +1588,8 @@
 	struct rtl8139_private *tp = dev->priv;
 	unsigned long timeout;
 
-	daemonize();
-	spin_lock_irq(&current->sighand->siglock);
-	sigemptyset(&current->blocked);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	strncpy (current->comm, dev->name, sizeof(current->comm) - 1);
-	current->comm[sizeof(current->comm) - 1] = '\0';
+	daemonize("%s", dev->name);
+	allow_signal(SIGKILL);
 
 	while (1) {
 		timeout = next_tick;
@@ -1604,9 +1598,7 @@
 		} while (!signal_pending (current) && (timeout > 0));
 
 		if (signal_pending (current)) {
-			spin_lock_irq(&current->sighand->siglock);
 			flush_signals(current);
-			spin_unlock_irq(&current->sighand->siglock);
 		}
 
 		if (tp->time_to_die)
diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	Fri Feb 14 15:53:12 2003
+++ b/drivers/net/Kconfig	Fri Feb 14 15:53:12 2003
@@ -745,6 +745,26 @@
 	  say M here and read <file:Documentation/modules.txt> as well as
 	  <file:Documentation/networking/net-modules.txt>.
 
+config TYPHOON
+	tristate "3cr990 series \"Typhoon\" support"
+	depends on NET_VENDOR_3COM && PCI
+	---help---
+	  This option enables driver support for the 3cr990 series of cards:
+
+	  3C990-TX, 3CR990-TX-95, 3CR990-TX-97, 3CR990-FX-95, 3CR990-FX-97,
+	  3CR990SVR, 3CR990SVR95, 3CR990SVR97, 3CR990-FX-95 Server,
+	  3CR990-FX-97 Server, 3C990B-TX-M, 3C990BSVR
+
+	  If you have a network (Ethernet) card of this type, say Y and read
+	  the Ethernet-HOWTO, available from
+	  <http://www.linuxdoc.org/docs.html#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 be called typhoon.o.  If you want to compile it as a
+	  module, say M here and read <file:Documentation/modules.txt> as well
+	  as <file:Documentation/networking/net-modules.txt>.
+
 config LANCE
 	tristate "AMD LANCE and PCnet (AT1500 and NE2100) support"
 	depends on NET_ETHERNET && ISA
@@ -1258,6 +1278,18 @@
 	  say M here and read <file:Documentation/modules.txt>.  This is
 	  recommended.  The module will be called starfire.
 
+config ADAPTEC_STARFIRE_NAPI
+	bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
+	depends on ADAPTEC_STARFIRE && EXPERIMENTAL
+	help
+	  NAPI is a new driver API designed to reduce CPU and interrupt load
+	  when the driver is receiving lots of packets from the card. It is
+	  still somewhat experimental and thus not yet enabled by default.
+
+	  If your estimated Rx load is 10kpps or more, or if the card will be
+	  deployed on potentially unfriendly networks (e.g. in a firewall),
+	  then say Y here.
+
 config AC3200
 	tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)"
 	depends on NET_PCI && (ISA || EISA) && EXPERIMENTAL
@@ -1346,6 +1378,17 @@
 	  The module will be called eepro100.  If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt> as
 	  well as <file:Documentation/networking/net-modules.txt>.
+
+
+config EEPRO100_PIO
+	bool "Use PIO instead of MMIO" if !X86_VISWS
+	depends on EEPRO100
+	default y if X86_VISWS
+	help
+	  This instructs the driver to use programmed I/O ports (PIO) instead
+	  of PCI shared memory (MMIO).  This can possibly solve some problems
+	  in case your mainboard has memory consistency issues.  If unsure,
+	  say N.
 
 config E100
 	tristate "EtherExpressPro/100 support (e100, Alternate Intel driver)"
diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile
--- a/drivers/net/Makefile	Fri Feb 14 15:53:09 2003
+++ b/drivers/net/Makefile	Fri Feb 14 15:53:09 2003
@@ -33,6 +33,7 @@
 obj-$(CONFIG_DGRS) += dgrs.o
 obj-$(CONFIG_RCPCI) += rcpci.o
 obj-$(CONFIG_VORTEX) += 3c59x.o
+obj-$(CONFIG_TYPHOON) += typhoon.o
 obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o
 obj-$(CONFIG_PCNET32) += pcnet32.o mii.o
 obj-$(CONFIG_EEPRO100) += eepro100.o mii.o
diff -Nru a/drivers/net/Makefile.lib b/drivers/net/Makefile.lib
--- a/drivers/net/Makefile.lib	Fri Feb 14 15:53:12 2003
+++ b/drivers/net/Makefile.lib	Fri Feb 14 15:53:12 2003
@@ -33,6 +33,7 @@
 obj-$(CONFIG_SUNLANCE)		+= crc32.o
 obj-$(CONFIG_SUNQE)		+= crc32.o
 obj-$(CONFIG_TULIP)		+= crc32.o
+obj-$(CONFIG_TYPHOON)		+= crc32.o
 obj-$(CONFIG_VIA_RHINE)		+= crc32.o
 obj-$(CONFIG_YELLOWFIN)		+= crc32.o
 obj-$(CONFIG_WINBOND_840)	+= crc32.o
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/net/Space.c	Fri Feb 14 15:53:08 2003
@@ -224,9 +224,6 @@
 #ifdef CONFIG_EL2 		/* 3c503 */
 	{el2_probe, 0},
 #endif
-#ifdef CONFIG_EL3
-	{el3_probe, 0},
-#endif
 #ifdef CONFIG_HPLAN
 	{hp_probe, 0},
 #endif
@@ -554,6 +551,8 @@
 #ifdef CONFIG_TR
 /* Token-ring device probe */
 extern int ibmtr_probe(struct net_device *);
+extern int sk_isa_probe(struct net_device *);
+extern int proteon_probe(struct net_device *);
 extern int smctr_probe(struct net_device *);
 
 static int
@@ -562,6 +561,12 @@
     if (1
 #ifdef CONFIG_IBMTR
 	&& ibmtr_probe(dev)
+#endif
+#ifdef CONFIG_SKISA
+	&& sk_isa_probe(dev)
+#endif
+#ifdef CONFIG_PROTEON
+	&& proteon_probe(dev)
 #endif
 #ifdef CONFIG_SMCTR
 	&& smctr_probe(dev)
diff -Nru a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
--- a/drivers/net/amd8111e.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/net/amd8111e.c	Fri Feb 14 15:53:10 2003
@@ -953,7 +953,7 @@
      	reg_buff = kmalloc( AMD8111E_REG_DUMP_LEN,GFP_KERNEL);
 	if(NULL == reg_buff)
 		return NULL;
-    	for( i=0; i< AMD8111E_REG_DUMP_LEN;i+=4);
+    	for (i=0; i < AMD8111E_REG_DUMP_LEN; i+=4)
 		reg_buff[i]= readl(mmio + i);	
 	return reg_buff;
 }
diff -Nru a/drivers/net/arlan.c b/drivers/net/arlan.c
--- a/drivers/net/arlan.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/net/arlan.c	Fri Feb 14 15:53:11 2003
@@ -1124,24 +1124,6 @@
 	return -ENODEV;
 }
 
-static int __init arlan_find_devices(void)
-{
-	int m;
-	int found = 0;
-
-	ARLAN_DEBUG_ENTRY("arlan_find_devices");
-	if (mem != 0 && numDevices == 1)	/* Check a single specified location. */
-		return 1;
-	for (m =(int) phys_to_virt(0xc0000); m <=(int) phys_to_virt(0xDE000); m += 0x2000)
-	{
-		if (arlan_check_fingerprint(m) == 0)
-			found++;
-	}
-	ARLAN_DEBUG_EXIT("arlan_find_devices");
-
-	return found;
-}
-
 
 static int arlan_change_mtu(struct net_device *dev, int new_mtu)
 {
@@ -1199,7 +1181,7 @@
 			return 0;
 		}
 		ap = dev->priv;
-		ap->config = dev->priv + sizeof(struct arlan_private);
+		ap->conf = dev->priv + sizeof(struct arlan_private);
 		ap->init_etherdev_alloc = 1;
 	} else {
 		dev = devs;
@@ -1209,7 +1191,7 @@
 			return 0;
 		}
 		ap = dev->priv;
-		ap->config = dev->priv + sizeof(struct arlan_private);
+		ap->conf = dev->priv + sizeof(struct arlan_private);
 		memset(ap, 0, sizeof(*ap));
 	}
 
@@ -2007,6 +1989,24 @@
 
 #ifdef  MODULE
 
+static int __init arlan_find_devices(void)
+{
+	int m;
+	int found = 0;
+
+	ARLAN_DEBUG_ENTRY("arlan_find_devices");
+	if (mem != 0 && numDevices == 1)	/* Check a single specified location. */
+		return 1;
+	for (m =(int) phys_to_virt(0xc0000); m <=(int) phys_to_virt(0xDE000); m += 0x2000)
+	{
+		if (arlan_check_fingerprint(m) == 0)
+			found++;
+	}
+	ARLAN_DEBUG_EXIT("arlan_find_devices");
+
+	return found;
+}
+
 int init_module(void)
 {
 	int i = 0;
@@ -2045,7 +2045,7 @@
 void cleanup_module(void)
 {
 	int i = 0;
-	struct arlan_private ap;
+	struct arlan_private *ap;
 
 	ARLAN_DEBUG_ENTRY("cleanup_module");
 
diff -Nru a/drivers/net/bmac.c b/drivers/net/bmac.c
--- a/drivers/net/bmac.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/net/bmac.c	Fri Feb 14 15:53:08 2003
@@ -1401,8 +1401,6 @@
 	bp->queue = (struct sk_buff_head *)(bp->rx_cmds + N_RX_RING + 1);
 	skb_queue_head_init(bp->queue);
 
-	memset((char *) bp->tx_cmds, 0,
-	       (N_TX_RING + N_RX_RING + 2) * sizeof(struct dbdma_cmd));
 	init_timer(&bp->tx_timeout);
 	/*     bp->timeout_active = 0; */
 
diff -Nru a/drivers/net/depca.c b/drivers/net/depca.c
--- a/drivers/net/depca.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/net/depca.c	Fri Feb 14 15:53:10 2003
@@ -252,6 +252,7 @@
 #include <linux/types.h>
 #include <linux/unistd.h>
 #include <linux/ctype.h>
+#include <linux/mca-legacy.h>
 
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
diff -Nru a/drivers/net/eepro100.c b/drivers/net/eepro100.c
--- a/drivers/net/eepro100.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/net/eepro100.c	Fri Feb 14 15:53:11 2003
@@ -120,6 +120,11 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 
+/* enable PIO instead of MMIO, if CONFIG_EEPRO100_PIO is selected */
+#ifdef CONFIG_EEPRO100_PIO
+#define USE_IO 1
+#endif
+
 static int debug = -1;
 #define DEBUG_DEFAULT		(NETIF_MSG_DRV		| \
 				 NETIF_MSG_HW		| \
diff -Nru a/drivers/net/eexpress.c b/drivers/net/eexpress.c
--- a/drivers/net/eexpress.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/net/eexpress.c	Fri Feb 14 15:53:08 2003
@@ -114,6 +114,7 @@
 #include <linux/skbuff.h>
 #include <linux/slab.h>
 #include <linux/mca.h>
+#include <linux/mca-legacy.h>
 #include <linux/spinlock.h>
 
 #include <asm/system.h>
diff -Nru a/drivers/net/fc/iph5526.c b/drivers/net/fc/iph5526.c
--- a/drivers/net/fc/iph5526.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/net/fc/iph5526.c	Fri Feb 14 15:53:09 2003
@@ -3769,7 +3769,7 @@
 	for (i = 0; i <= MAX_FC_CARDS; i++) 
 		fc[i] = NULL;
 
-	for (i = 0; i < clone_list[i].vendor_id != 0; i++)
+	for (i = 0; clone_list[i].vendor_id != 0; i++)
 	while ((pdev = pci_find_device(clone_list[i].vendor_id, clone_list[i].device_id, pdev))) {
 		unsigned short pci_command;
 		if (pci_enable_device(pdev))
@@ -3913,9 +3913,9 @@
 int int_required = 0;
 u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_COMMAND;
 u_int type = TYPE_FCP | SEQUENCE_INITIATIVE;
-u_int frame_class = Cmnd->target;
+u_int frame_class = Cmnd->device->id;
 u_short ox_id = OX_ID_FIRST_SEQUENCE;
-struct Scsi_Host *host = Cmnd->host;
+struct Scsi_Host *host = Cmnd->device->host;
 struct iph5526_hostdata *hostdata = (struct iph5526_hostdata*)host->hostdata;
 struct fc_info *fi = hostdata->fi;
 struct fc_node_info *q;
@@ -3937,9 +3937,9 @@
 				hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_ORDERED;
 				break;
 			default:
-				if ((jiffies - hostdata->tag_ages[Cmnd->target]) > (5 * HZ)) {
+				if ((jiffies - hostdata->tag_ages[Cmnd->device->id]) > (5 * HZ)) {
 					hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_ORDERED;
-					hostdata->tag_ages[Cmnd->target] = jiffies;
+					hostdata->tag_ages[Cmnd->device->id] = jiffies;
 				}
 				else
 					hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_SIMPLE;
@@ -3953,7 +3953,7 @@
 	hostdata->cmnd.fcp_addr[3] = 0;
 	hostdata->cmnd.fcp_addr[2] = 0;
 	hostdata->cmnd.fcp_addr[1] = 0;
-	hostdata->cmnd.fcp_addr[0] = htons(Cmnd->lun);
+	hostdata->cmnd.fcp_addr[0] = htons(Cmnd->device->lun);
 
 	memcpy(&hostdata->cmnd.fcp_cdb, Cmnd->cmnd, Cmnd->cmd_len);
 	hostdata->cmnd.fcp_data_len = htonl(Cmnd->request_bufflen);
@@ -3985,7 +3985,7 @@
 	
 	memcpy(fi->q.ptr_fcp_cmnd[fi->q.fcp_cmnd_indx], &(hostdata->cmnd), sizeof(fcp_cmd));	
 	
-	q = resolve_target(fi, Cmnd->target);
+	q = resolve_target(fi, Cmnd->device->id);
 
 	if (q == NULL) {
 	u_int bad_id = fi->g.my_ddaa | 0xFE;
@@ -4022,7 +4022,7 @@
 
 int iph5526_abort(Scsi_Cmnd *Cmnd)
 {
-struct Scsi_Host *host = Cmnd->host;
+struct Scsi_Host *host = Cmnd->device->host;
 struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
 struct fc_info *fi = hostdata->fi;
 struct fc_node_info *q;
@@ -4036,7 +4036,7 @@
 	
 	spin_lock_irqsave(&fi->fc_lock, flags);
 	
-	q = resolve_target(fi, Cmnd->target);
+	q = resolve_target(fi, Cmnd->device->id);
 	if (q == NULL) {
 	u_int bad_id = fi->g.my_ddaa | 0xFE;
 		/* This should not happen as we should always be able to
diff -Nru a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
--- a/drivers/net/hamradio/scc.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/net/hamradio/scc.c	Fri Feb 14 15:53:12 2003
@@ -1763,7 +1763,7 @@
 
 			if (hwcfg.irq == 2) hwcfg.irq = 9;
 
-			if (hwcfg.irq <0 || hwcfg.irq > NR_IRQS)
+			if (hwcfg.irq < 0 || hwcfg.irq >= NR_IRQS)
 				return -EINVAL;
 				
 			if (!Ivec[hwcfg.irq].used && hwcfg.irq)
diff -Nru a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
--- a/drivers/net/hamradio/yam.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/net/hamradio/yam.c	Fri Feb 14 15:53:12 2003
@@ -350,7 +350,7 @@
 		wrd <<= 1;
 		outb(0xfc, THR(iobase));
 		while ((inb(LSR(iobase)) & LSR_TSRE) == 0)
-			if (jiffies > timeout)
+			if (time_after(jiffies, timeout))
 				return -1;
 	}
 
diff -Nru a/drivers/net/irda/sir_kthread.c b/drivers/net/irda/sir_kthread.c
--- a/drivers/net/irda/sir_kthread.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/net/irda/sir_kthread.c	Fri Feb 14 15:53:12 2003
@@ -113,13 +113,7 @@
 {
 	DECLARE_WAITQUEUE(wait, current);
 
-	daemonize();
-	strcpy(current->comm, "kIrDAd");
-
-	spin_lock_irq(&current->sighand->siglock);
-	sigfillset(&current->blocked);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	daemonize("kIrDAd");
 
 	set_fs(KERNEL_DS);
 
diff -Nru a/drivers/net/irda/smc-ircc.c b/drivers/net/irda/smc-ircc.c
--- a/drivers/net/irda/smc-ircc.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/net/irda/smc-ircc.c	Fri Feb 14 15:53:08 2003
@@ -469,7 +469,7 @@
 		"firport 0x%03x, sirport 0x%03x dma=%d, irq=%d\n",
 		chip & 0x0f, version, fir_base, sir_base, dma, irq);
 
-	if (dev_count>DIM(dev_self)) {
+	if (dev_count >= DIM(dev_self)) {
 	        IRDA_DEBUG(0, 
 			   "%s(), to many devices!\n", __FUNCTION__ );
 		return -ENOMEM;
diff -Nru a/drivers/net/ns83820.c b/drivers/net/ns83820.c
--- a/drivers/net/ns83820.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/net/ns83820.c	Fri Feb 14 15:53:12 2003
@@ -500,9 +500,9 @@
 {
 	desc_addr_set(desc + DESC_LINK, link);
 	desc_addr_set(desc + DESC_BUFPTR, buf);
-	desc[DESC_EXTSTS] = extsts;
+	desc[DESC_EXTSTS] = cpu_to_le32(extsts);
 	mb();
-	desc[DESC_CMDSTS] = cmdsts;
+	desc[DESC_CMDSTS] = cpu_to_le32(cmdsts);
 }
 
 #define nr_rx_empty(dev) ((NR_RX_DESC-2 + dev->rx_info.next_rx - dev->rx_info.next_empty) % NR_RX_DESC)
diff -Nru a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
--- a/drivers/net/pcmcia/xirc2ps_cs.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/net/pcmcia/xirc2ps_cs.c	Fri Feb 14 15:53:09 2003
@@ -447,7 +447,7 @@
 	u_long flags;
 	save_flags(flags);
 	sti();
-	while (timeout >= jiffies)
+	while (time_before_eq(jiffies, timeout))
 	    ;
 	restore_flags(flags);
     } else {
diff -Nru a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
--- a/drivers/net/pcnet32.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/net/pcnet32.c	Fri Feb 14 15:53:09 2003
@@ -1483,7 +1483,9 @@
 	
 	crc = ether_crc_le(6, addrs);
 	crc = crc >> 26;
-	mcast_table [crc >> 4] |= 1 << (crc & 0xf);
+	mcast_table [crc >> 4] = le16_to_cpu(
+		le16_to_cpu(mcast_table [crc >> 4]) | (1 << (crc & 0xf))
+	);
     }
     return;
 }
diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/net/sis900.c	Fri Feb 14 15:53:09 2003
@@ -591,7 +591,7 @@
 			yield();
 
 			poll_bit ^= (mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS) & poll_bit);
-			if (jiffies >= timeout) {
+			if (time_after_eq(jiffies, timeout)) {
 				printk(KERN_WARNING "%s: reset phy and link down now\n", net_dev->name);
 				return -ETIME;
 			}
diff -Nru a/drivers/net/starfire.c b/drivers/net/starfire.c
--- a/drivers/net/starfire.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/net/starfire.c	Fri Feb 14 15:53:09 2003
@@ -4,7 +4,7 @@
 
 	Current maintainer is Ion Badulescu <ionut@cs.columbia.edu>. Please
 	send all bug reports to me, and not to Donald Becker, as this code
-	has been modified quite a bit from Donald's original version.
+	has been heavily modified from Donald's original version.
 
 	This software may be used and distributed according to the terms of
 	the GNU General Public License (GPL), incorporated herein by reference.
@@ -13,6 +13,8 @@
 	a complete program and may only be used when the entire operating
 	system is licensed under the GPL.
 
+	The information below comes from Donald Becker's original driver:
+
 	The author may be reached as becker@scyld.com, or C/O
 	Scyld Computing Corporation
 	410 Severn Ave., Suite 210
@@ -101,15 +103,40 @@
 	- Better stats and error handling (Ion Badulescu)
 	- Use new pci_set_mwi() PCI API function (jgarzik)
 
-TODO:
-	- implement tx_timeout() properly
+	LK1.3.7 (Ion Badulescu)
+	- minimal implementation of tx_timeout()
+	- correctly shutdown the Rx/Tx engines in netdev_close()
+	- added calls to netif_carrier_on/off
+	(patch from Stefan Rompf <srompf@isg.de>)
 	- VLAN support
+
+	LK1.3.8 (Ion Badulescu)
+	- adjust DMA burst size on sparc64
+	- 64-bit support
+	- reworked zerocopy support for 64-bit buffers
+	- working and usable interrupt mitigation/latency
+	- reduced Tx interrupt frequency for lower interrupt overhead
+
+	LK1.3.9 (Ion Badulescu)
+	- bugfix for mcast filter
+	- enable the right kind of Tx interrupts (TxDMADone, not TxDone)
+
+	LK1.4.0 (Ion Badulescu)
+	- NAPI support
+
+	LK1.4.1 (Ion Badulescu)
+	- flush PCI posting buffers after disabling Rx interrupts
+	- put the chip to a D3 slumber on driver unload
+	- added config option to enable/disable NAPI
+
+TODO:	bugfixes (no bugs known as of right now)
 */
 
 #define DRV_NAME	"starfire"
-#define DRV_VERSION	"1.03+LK1.3.6"
-#define DRV_RELDATE	"March 7, 2002"
+#define DRV_VERSION	"1.03+LK1.4.1"
+#define DRV_RELDATE	"February 10, 2002"
 
+#include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -118,27 +145,23 @@
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/crc32.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
 /*
- * Adaptec's license for their Novell drivers (which is where I got the
+ * Adaptec's license for their drivers (which is where I got the
  * firmware files) does not allow one to redistribute them. Thus, we can't
  * include the firmware with this driver.
  *
- * However, an end-user is allowed to download and use it, after
- * converting it to C header files using starfire_firmware.pl.
+ * However, should a legal-to-distribute firmware become available,
+ * the driver developer would need only to obtain the firmware in the
+ * form of a C header file.
  * Once that's done, the #undef below must be changed into a #define
  * for this driver to really use the firmware. Note that Rx/Tx
  * hardware TCP checksumming is not possible without the firmware.
  *
- * If Adaptec could allow redistribution of the firmware (even in binary
- * format), life would become a lot easier. Unfortunately, I've lost my
- * Adaptec contacts, so progress on this front is rather unlikely to
- * occur. If anybody from Adaptec reads this and can help with this matter,
- * please let me know...
+ * WANTED: legal firmware to include with this GPL'd driver.
  */
 #undef HAS_FIRMWARE
 /*
@@ -157,11 +180,20 @@
 #include "starfire_firmware.h"
 #endif /* HAS_FIRMWARE */
 
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#define VLAN_SUPPORT
+#endif
+
+#ifndef CONFIG_ADAPTEC_STARFIRE_NAPI
+#undef HAVE_NETDEV_POLL
+#endif
+
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
 
 /* Used for tuning interrupt latency vs. overhead. */
-static int interrupt_mitigation;
+static int intr_latency;
+static int small_frames;
 
 static int debug = 1;			/* 1 normal messages, 0 quiet .. 7 verbose. */
 static int max_interrupt_work = 20;
@@ -169,6 +201,12 @@
 /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
    The Starfire has a 512 element hash table based on the Ethernet CRC. */
 static int multicast_filter_limit = 512;
+/* Whether to do TCP/UDP checksums in hardware */
+#ifdef HAS_FIRMWARE
+static int enable_hw_cksum = 1;
+#else
+static int enable_hw_cksum = 0;
+#endif
 
 #define PKT_BUF_SZ	1536		/* Size of each temporary Rx buffer.*/
 /*
@@ -181,7 +219,9 @@
  * packets as the starfire doesn't allow for misaligned DMAs ;-(
  * 23/10/2000 - Jes
  *
- * The Alpha and the Sparc don't allow unaligned loads, either. -Ion
+ * The Alpha and the Sparc don't like unaligned loads, either. On Sparc64,
+ * at least, having unaligned frames leads to a rather serious performance
+ * penalty. -Ion
  */
 #if defined(__ia64__) || defined(__alpha__) || defined(__sparc__)
 static int rx_copybreak = PKT_BUF_SZ;
@@ -189,9 +229,17 @@
 static int rx_copybreak /* = 0 */;
 #endif
 
+/* PCI DMA burst size -- on sparc64 we want to force it to 64 bytes, on the others the default of 128 is fine. */
+#ifdef __sparc__
+#define DMA_BURST_SIZE 64
+#else
+#define DMA_BURST_SIZE 128
+#endif
+
 /* Used to pass the media type, etc.
    Both 'options[]' and 'full_duplex[]' exist for driver interoperability.
    The media type is usually passed in 'options[]'.
+   These variables are deprecated, use ethtool instead. -Ion
 */
 #define MAX_UNITS 8		/* More are supported, limit only on options */
 static int options[MAX_UNITS] = {0, };
@@ -201,33 +249,55 @@
 
 /* The "native" ring sizes are either 256 or 2048.
    However in some modes a descriptor may be marked to wrap the ring earlier.
-   The driver allocates a single page for each descriptor ring, constraining
-   the maximum size in an architecture-dependent way.
 */
 #define RX_RING_SIZE	256
 #define TX_RING_SIZE	32
 /* The completion queues are fixed at 1024 entries i.e. 4K or 8KB. */
 #define DONE_Q_SIZE	1024
+/* All queues must be aligned on a 256-byte boundary */
+#define QUEUE_ALIGN	256
+
+#if RX_RING_SIZE > 256
+#define RX_Q_ENTRIES Rx2048QEntries
+#else
+#define RX_Q_ENTRIES Rx256QEntries
+#endif
 
 /* Operational parameters that usually are not changed. */
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT	(2 * HZ)
 
-#ifdef ZEROCOPY
-#if MAX_SKB_FRAGS <= 6
-#define MAX_STARFIRE_FRAGS 6
-#else  /* MAX_STARFIRE_FRAGS > 6 */
-#warning This driver will not work with more than 6 skb fragments.
-#warning Turning off zerocopy support.
-#undef ZEROCOPY
-#endif /* MAX_STARFIRE_FRAGS > 6 */
-#endif /* ZEROCOPY */
+/*
+ * This SUCKS.
+ * We need a much better method to determine if dma_addr_t is 64-bit.
+ */
+#if (defined(__i386__) && defined(CONFIG_HIGHMEM) && (LINUX_VERSION_CODE > 0x20500 || defined(CONFIG_HIGHMEM64G))) || defined(__x86_64__) || defined (__ia64__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR))
+/* 64-bit dma_addr_t */
+#define ADDR_64BITS	/* This chip uses 64 bit addresses. */
+#define cpu_to_dma(x) cpu_to_le64(x)
+#define dma_to_cpu(x) le64_to_cpu(x)
+#define RX_DESC_Q_ADDR_SIZE RxDescQAddr64bit
+#define TX_DESC_Q_ADDR_SIZE TxDescQAddr64bit
+#define RX_COMPL_Q_ADDR_SIZE RxComplQAddr64bit
+#define TX_COMPL_Q_ADDR_SIZE TxComplQAddr64bit
+#define RX_DESC_ADDR_SIZE RxDescAddr64bit
+#else  /* 32-bit dma_addr_t */
+#define cpu_to_dma(x) cpu_to_le32(x)
+#define dma_to_cpu(x) le32_to_cpu(x)
+#define RX_DESC_Q_ADDR_SIZE RxDescQAddr32bit
+#define TX_DESC_Q_ADDR_SIZE TxDescQAddr32bit
+#define RX_COMPL_Q_ADDR_SIZE RxComplQAddr32bit
+#define TX_COMPL_Q_ADDR_SIZE TxComplQAddr32bit
+#define RX_DESC_ADDR_SIZE RxDescAddr32bit
+#endif
 
-#ifdef ZEROCOPY
+#ifdef MAX_SKB_FRAGS
 #define skb_first_frag_len(skb)	skb_headlen(skb)
-#else  /* not ZEROCOPY */
+#define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1)
+#else  /* not MAX_SKB_FRAGS */
 #define skb_first_frag_len(skb)	(skb->len)
-#endif /* not ZEROCOPY */
+#define skb_num_frags(skb) 1
+#endif /* not MAX_SKB_FRAGS */
 
 /* 2.2.x compatibility code */
 #if LINUX_VERSION_CODE < 0x20300
@@ -236,9 +306,12 @@
 
 #else  /* LINUX_VERSION_CODE > 0x20300 */
 
+#include <linux/crc32.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 
+#include <linux/if_vlan.h>
+
 #define COMPAT_MOD_INC_USE_COUNT
 #define COMPAT_MOD_DEC_USE_COUNT
 
@@ -253,6 +326,43 @@
 #define PCI_SLOT_NAME(pci_dev)	(pci_dev)->slot_name
 
 #endif /* LINUX_VERSION_CODE > 0x20300 */
+
+#ifdef HAVE_NETDEV_POLL
+#define init_poll(dev) \
+	dev->poll = &netdev_poll; \
+	dev->weight = max_interrupt_work;
+#define netdev_rx(dev, ioaddr) \
+do { \
+	u32 intr_enable; \
+	if (netif_rx_schedule_prep(dev)) { \
+		__netif_rx_schedule(dev); \
+		intr_enable = readl(ioaddr + IntrEnable); \
+		intr_enable &= ~(IntrRxDone | IntrRxEmpty); \
+		writel(intr_enable, ioaddr + IntrEnable); \
+		readl(ioaddr + IntrEnable); /* flush PCI posting buffers */ \
+	} else { \
+		/* Paranoia check */ \
+		intr_enable = readl(ioaddr + IntrEnable); \
+		if (intr_enable & (IntrRxDone | IntrRxEmpty)) { \
+			printk("%s: interrupt while in polling mode!\n", dev->name); \
+			intr_enable &= ~(IntrRxDone | IntrRxEmpty); \
+			writel(intr_enable, ioaddr + IntrEnable); \
+		} \
+	} \
+} while (0)
+#define netdev_receive_skb(skb) netif_receive_skb(skb)
+#define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_receive_skb(skb, vlgrp, vlid)
+static int	netdev_poll(struct net_device *dev, int *budget);
+#else  /* not HAVE_NETDEV_POLL */
+#define init_poll(dev)
+#define netdev_receive_skb(skb) netif_rx(skb)
+#define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_rx(skb, vlgrp, vlid)
+#define netdev_rx(dev, ioaddr) \
+do { \
+	int quota = np->dirty_rx + RX_RING_SIZE - np->cur_rx; \
+	__netdev_rx(dev, &quota);\
+} while (0)
+#endif /* not HAVE_NETDEV_POLL */
 /* end of compatibility code */
 
 
@@ -269,15 +379,20 @@
 MODULE_PARM(mtu, "i");
 MODULE_PARM(debug, "i");
 MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(interrupt_mitigation, "i");
+MODULE_PARM(intr_latency, "i");
+MODULE_PARM(small_frames, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM_DESC(max_interrupt_work, "Starfire maximum events handled per interrupt");
-MODULE_PARM_DESC(mtu, "Starfire MTU (all boards)");
-MODULE_PARM_DESC(debug, "Starfire debug level (0-6)");
-MODULE_PARM_DESC(rx_copybreak, "Starfire copy breakpoint for copy-only-tiny-frames");
-MODULE_PARM_DESC(options, "Starfire: Bits 0-3: media type, bit 17: full duplex");
-MODULE_PARM_DESC(full_duplex, "Starfire full duplex setting(s) (1)");
+MODULE_PARM(enable_hw_cksum, "i");
+MODULE_PARM_DESC(max_interrupt_work, "Maximum events handled per interrupt");
+MODULE_PARM_DESC(mtu, "MTU (all boards)");
+MODULE_PARM_DESC(debug, "Debug level (0-6)");
+MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(intr_latency, "Maximum interrupt latency, in microseconds");
+MODULE_PARM_DESC(small_frames, "Maximum size of receive frames that bypass interrupt latency (0,64,128,256,512)");
+MODULE_PARM_DESC(options, "Deprecated: Bits 0-3: media type, bit 17: full duplex");
+MODULE_PARM_DESC(full_duplex, "Deprecated: Forced full-duplex setting (0/1)");
+MODULE_PARM_DESC(enable_hw_cksum, "Enable/disable hardware cksum support (0/1)");
 
 /*
 				Theory of Operation
@@ -306,14 +421,14 @@
 IIIb/c. Transmit/Receive Structure
 
 See the Adaptec manual for the many possible structures, and options for
-each structure.  There are far too many to document here.
+each structure.  There are far too many to document all of them here.
 
 For transmit this driver uses type 0/1 transmit descriptors (depending
-on the presence of the zerocopy infrastructure), and relies on automatic
+on the 32/64 bitness of the architecture), and relies on automatic
 minimum-length padding.  It does not use the completion queue
 consumer index, but instead checks for non-zero status entries.
 
-For receive this driver uses type 0 receive descriptors.  The driver
+For receive this driver uses type 0/1/2/3 receive descriptors.  The driver
 allocates full frame size skbuffs for the Rx ring buffers, so all frames
 should fit in a single descriptor.  The driver does not use the completion
 queue consumer index, but instead checks for non-zero status entries.
@@ -338,15 +453,15 @@
 dev->tbusy flag.  The other thread is the interrupt handler, which is single
 threaded by the hardware and interrupt handling software.
 
-The send packet thread has partial control over the Tx ring and 'dev->tbusy'
-flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the next
-queue slot is empty, it clears the tbusy flag when finished otherwise it sets
-the 'lp->tx_full' flag.
+The send packet thread has partial control over the Tx ring and the netif_queue
+status. If the number of free Tx slots in the ring falls below a certain number
+(currently hardcoded to 4), it signals the upper layer to stop the queue.
 
 The interrupt handler has exclusive control over the Rx ring and records stats
 from the Tx ring.  After reaping the stats, it marks the Tx queue entry as
-empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it
-clears both the tx_full and tbusy flags.
+empty by incrementing the dirty_tx mark. Iff the netif_queue is stopped and the
+number of free Tx slow is above the threshold, it signals the upper layer to
+restart the queue.
 
 IV. Notes
 
@@ -358,18 +473,15 @@
 
 IVc. Errata
 
+- StopOnPerr is broken, don't enable
+- Hardware ethernet padding exposes random data, perform software padding
+  instead (unverified -- works correctly for all the hardware I have)
+
 */
 
 
 
 enum chip_capability_flags {CanHaveMII=1, };
-#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR0)
-
-#if 0
-#define ADDR_64BITS 1			/* This chip uses 64 bit addresses. */
-#endif
-
-#define HAS_IP_COPYSUM 1
 
 enum chipset {
 	CH_6915 = 0,
@@ -401,7 +513,7 @@
 enum register_offsets {
 	PCIDeviceConfig=0x50040, GenCtrl=0x50070, IntrTimerCtrl=0x50074,
 	IntrClear=0x50080, IntrStatus=0x50084, IntrEnable=0x50088,
-	MIICtrl=0x52000, StationAddr=0x50120, EEPROMCtrl=0x51000,
+	MIICtrl=0x52000, TxStationAddr=0x50120, EEPROMCtrl=0x51000,
 	GPIOCtrl=0x5008C, TxDescCtrl=0x50090,
 	TxRingPtr=0x50098, HiPriTxRingPtr=0x50094, /* Low and High priority. */
 	TxRingHiAddr=0x5009C,		/* 64 bit address extension. */
@@ -412,11 +524,16 @@
 	CompletionQConsumerIdx=0x500C4, RxDMACtrl=0x500D0,
 	RxDescQCtrl=0x500D4, RxDescQHiAddr=0x500DC, RxDescQAddr=0x500E0,
 	RxDescQIdx=0x500E8, RxDMAStatus=0x500F0, RxFilterMode=0x500F4,
-	TxMode=0x55000, PerfFilterTable=0x56000, HashTable=0x56100,
+	TxMode=0x55000, VlanType=0x55064,
+	PerfFilterTable=0x56000, HashTable=0x56100,
 	TxGfpMem=0x58000, RxGfpMem=0x5a000,
 };
 
-/* Bits in the interrupt status/mask registers. */
+/*
+ * Bits in the interrupt status/mask registers.
+ * Warning: setting Intr[Ab]NormalSummary in the IntrEnable register
+ * enables all the interrupt sources that are or'ed into those status bits.
+ */
 enum intr_status_bits {
 	IntrLinkChange=0xf0000000, IntrStatsMax=0x08000000,
 	IntrAbnormalSummary=0x02000000, IntrGeneralTimer=0x01000000,
@@ -441,7 +558,16 @@
 /* Bits in the RxFilterMode register. */
 enum rx_mode_bits {
 	AcceptBroadcast=0x04, AcceptAllMulticast=0x02, AcceptAll=0x01,
-	AcceptMulticast=0x10, AcceptMyPhys=0xE040,
+	AcceptMulticast=0x10, PerfectFilter=0x40, HashFilter=0x30,
+	PerfectFilterVlan=0x80, MinVLANPrio=0xE000, VlanMode=0x0200,
+	WakeupOnGFP=0x0800,
+};
+
+/* Bits in the TxMode register */
+enum tx_mode_bits {
+	MiiSoftReset=0x8000, MIILoopback=0x4000,
+	TxFlowEnable=0x0800, RxFlowEnable=0x0400,
+	PadEnable=0x04, FullDuplex=0x02, HugeFrame=0x01,
 };
 
 /* Bits in the TxDescCtrl register. */
@@ -450,7 +576,8 @@
 	TxDescSpace128=0x30, TxDescSpace256=0x40,
 	TxDescType0=0x00, TxDescType1=0x01, TxDescType2=0x02,
 	TxDescType3=0x03, TxDescType4=0x04,
-	TxNoDMACompletion=0x08, TxDescQ64bit=0x80,
+	TxNoDMACompletion=0x08,
+	TxDescQAddr64bit=0x80, TxDescQAddr32bit=0,
 	TxHiPriFIFOThreshShift=24, TxPadLenShift=16,
 	TxDMABurstSizeShift=8,
 };
@@ -458,81 +585,144 @@
 /* Bits in the RxDescQCtrl register. */
 enum rx_ctrl_bits {
 	RxBufferLenShift=16, RxMinDescrThreshShift=0,
-	RxPrefetchMode=0x8000, Rx2048QEntries=0x4000,
-	RxVariableQ=0x2000, RxDesc64bit=0x1000,
-	RxDescQAddr64bit=0x0100,
+	RxPrefetchMode=0x8000, RxVariableQ=0x2000,
+	Rx2048QEntries=0x4000, Rx256QEntries=0,
+	RxDescAddr64bit=0x1000, RxDescAddr32bit=0,
+	RxDescQAddr64bit=0x0100, RxDescQAddr32bit=0,
 	RxDescSpace4=0x000, RxDescSpace8=0x100,
 	RxDescSpace16=0x200, RxDescSpace32=0x300,
 	RxDescSpace64=0x400, RxDescSpace128=0x500,
 	RxConsumerWrEn=0x80,
 };
 
+/* Bits in the RxDMACtrl register. */
+enum rx_dmactrl_bits {
+	RxReportBadFrames=0x80000000, RxDMAShortFrames=0x40000000,
+	RxDMABadFrames=0x20000000, RxDMACrcErrorFrames=0x10000000,
+	RxDMAControlFrame=0x08000000, RxDMAPauseFrame=0x04000000,
+	RxChecksumIgnore=0, RxChecksumRejectTCPUDP=0x02000000,
+	RxChecksumRejectTCPOnly=0x01000000,
+	RxCompletionQ2Enable=0x800000,
+	RxDMAQ2Disable=0, RxDMAQ2FPOnly=0x100000,
+	RxDMAQ2SmallPkt=0x200000, RxDMAQ2HighPrio=0x300000,
+	RxDMAQ2NonIP=0x400000,
+	RxUseBackupQueue=0x080000, RxDMACRC=0x040000,
+	RxEarlyIntThreshShift=12, RxHighPrioThreshShift=8,
+	RxBurstSizeShift=0,
+};
+
 /* Bits in the RxCompletionAddr register */
 enum rx_compl_bits {
-	RxComplQAddr64bit=0x80, TxComplProducerWrEn=0x40,
+	RxComplQAddr64bit=0x80, RxComplQAddr32bit=0,
+	RxComplProducerWrEn=0x40,
 	RxComplType0=0x00, RxComplType1=0x10,
 	RxComplType2=0x20, RxComplType3=0x30,
 	RxComplThreshShift=0,
 };
 
+/* Bits in the TxCompletionAddr register */
+enum tx_compl_bits {
+	TxComplQAddr64bit=0x80, TxComplQAddr32bit=0,
+	TxComplProducerWrEn=0x40,
+	TxComplIntrStatus=0x20,
+	CommonQueueMode=0x10,
+	TxComplThreshShift=0,
+};
+
+/* Bits in the GenCtrl register */
+enum gen_ctrl_bits {
+	RxEnable=0x05, TxEnable=0x0a,
+	RxGFPEnable=0x10, TxGFPEnable=0x20,
+};
+
+/* Bits in the IntrTimerCtrl register */
+enum intr_ctrl_bits {
+	Timer10X=0x800, EnableIntrMasking=0x60, SmallFrameBypass=0x100,
+	SmallFrame64=0, SmallFrame128=0x200, SmallFrame256=0x400, SmallFrame512=0x600,
+	IntrLatencyMask=0x1f,
+};
+
 /* The Rx and Tx buffer descriptors. */
 struct starfire_rx_desc {
-	u32 rxaddr;			/* Optionally 64 bits. */
+	dma_addr_t rxaddr;
 };
 enum rx_desc_bits {
 	RxDescValid=1, RxDescEndRing=2,
 };
 
-/* Completion queue entry.
-   You must update the page allocation, init_ring and the shift count in rx()
-   if using a larger format. */
-#ifdef HAS_FIRMWARE
-#define csum_rx_status
-#endif /* HAS_FIRMWARE */
-struct rx_done_desc {
+/* Completion queue entry. */
+struct short_rx_done_desc {
+	u32 status;			/* Low 16 bits is length. */
+};
+struct basic_rx_done_desc {
 	u32 status;			/* Low 16 bits is length. */
-#ifdef csum_rx_status
-	u32 status2;			/* Low 16 bits is csum */
-#endif /* csum_rx_status */
-#ifdef full_rx_status
-	u32 status2;
+	u16 vlanid;
+	u16 status2;
+};
+struct csum_rx_done_desc {
+	u32 status;			/* Low 16 bits is length. */
+	u16 csum;			/* Partial checksum */
+	u16 status2;
+};
+struct full_rx_done_desc {
+	u32 status;			/* Low 16 bits is length. */
+	u16 status3;
+	u16 status2;
 	u16 vlanid;
 	u16 csum;			/* partial checksum */
 	u32 timestamp;
-#endif /* full_rx_status */
 };
+/* XXX: this is ugly and I'm not sure it's worth the trouble -Ion */
+#ifdef HAS_FIRMWARE
+#ifdef VLAN_SUPPORT
+typedef struct full_rx_done_desc rx_done_desc;
+#define RxComplType RxComplType3
+#else  /* not VLAN_SUPPORT */
+typedef struct csum_rx_done_desc rx_done_desc;
+#define RxComplType RxComplType2
+#endif /* not VLAN_SUPPORT */
+#else  /* not HAS_FIRMWARE */
+#ifdef VLAN_SUPPORT
+typedef struct basic_rx_done_desc rx_done_desc;
+#define RxComplType RxComplType1
+#else  /* not VLAN_SUPPORT */
+typedef struct short_rx_done_desc rx_done_desc;
+#define RxComplType RxComplType0
+#endif /* not VLAN_SUPPORT */
+#endif /* not HAS_FIRMWARE */
+
 enum rx_done_bits {
 	RxOK=0x20000000, RxFIFOErr=0x10000000, RxBufQ2=0x08000000,
 };
 
-#ifdef ZEROCOPY
-/* Type 0 Tx descriptor. */
-/* If more fragments are needed, don't forget to change the
-   descriptor spacing as well! */
-struct starfire_tx_desc {
-	u32 status;
-	u32 nbufs;
-	u32 first_addr;
-	u16 first_len;
-	u16 total_len;
-	struct {
-		u32 addr;
-		u32 len;
-	} frag[MAX_STARFIRE_FRAGS];
-};
-#else  /* not ZEROCOPY */
 /* Type 1 Tx descriptor. */
-struct starfire_tx_desc {
+struct starfire_tx_desc_1 {
 	u32 status;			/* Upper bits are status, lower 16 length. */
-	u32 first_addr;
+	u32 addr;
 };
-#endif /* not ZEROCOPY */
+
+/* Type 2 Tx descriptor. */
+struct starfire_tx_desc_2 {
+	u32 status;			/* Upper bits are status, lower 16 length. */
+	u32 reserved;
+	u64 addr;
+};
+
+#ifdef ADDR_64BITS
+typedef struct starfire_tx_desc_2 starfire_tx_desc;
+#define TX_DESC_TYPE TxDescType2
+#else  /* not ADDR_64BITS */
+typedef struct starfire_tx_desc_1 starfire_tx_desc;
+#define TX_DESC_TYPE TxDescType1
+#endif /* not ADDR_64BITS */
+#define TX_DESC_SPACING TxDescSpaceUnlim
+
 enum tx_desc_bits {
 	TxDescID=0xB0000000,
 	TxCRCEn=0x01000000, TxDescIntr=0x08000000,
 	TxRingWrap=0x04000000, TxCalTCP=0x02000000,
 };
-struct tx_done_report {
+struct tx_done_desc {
 	u32 status;			/* timestamp, index. */
 #if 0
 	u32 intrstatus;			/* interrupt status */
@@ -545,41 +735,45 @@
 };
 struct tx_ring_info {
 	struct sk_buff *skb;
-	dma_addr_t first_mapping;
-#ifdef ZEROCOPY
-	dma_addr_t frag_mapping[MAX_STARFIRE_FRAGS];
-#endif /* ZEROCOPY */
+	dma_addr_t mapping;
+	unsigned int used_slots;
 };
 
 #define PHY_CNT		2
 struct netdev_private {
 	/* Descriptor rings first for alignment. */
 	struct starfire_rx_desc *rx_ring;
-	struct starfire_tx_desc *tx_ring;
+	starfire_tx_desc *tx_ring;
 	dma_addr_t rx_ring_dma;
 	dma_addr_t tx_ring_dma;
 	/* The addresses of rx/tx-in-place skbuffs. */
 	struct rx_ring_info rx_info[RX_RING_SIZE];
 	struct tx_ring_info tx_info[TX_RING_SIZE];
 	/* Pointers to completion queues (full pages). */
-	struct rx_done_desc *rx_done_q;
+	rx_done_desc *rx_done_q;
 	dma_addr_t rx_done_q_dma;
 	unsigned int rx_done;
-	struct tx_done_report *tx_done_q;
+	struct tx_done_desc *tx_done_q;
 	dma_addr_t tx_done_q_dma;
 	unsigned int tx_done;
 	struct net_device_stats stats;
 	struct pci_dev *pci_dev;
+#ifdef VLAN_SUPPORT
+	struct vlan_group *vlgrp;
+#endif
+	void *queue_mem;
+	dma_addr_t queue_mem_dma;
+	size_t queue_mem_size;
+
 	/* Frequently used values: keep some adjacent for cache effect. */
 	spinlock_t lock;
 	unsigned int cur_rx, dirty_rx;	/* Producer/consumer ring indices */
-	unsigned int cur_tx, dirty_tx;
+	unsigned int cur_tx, dirty_tx, reap_tx;
 	unsigned int rx_buf_sz;		/* Based on MTU+slack. */
-	unsigned int tx_full:1,		/* The Tx queue is full. */
 	/* These values keep track of the transceiver/media in use. */
-		speed100:1;		/* Set if speed == 100MBit. */
-	unsigned int intr_mitigation;
+	int speed100;			/* Set if speed == 100MBit. */
 	u32 tx_mode;
+	u32 intr_timer_ctrl;
 	u8 tx_threshold;
 	/* MII transceiver section. */
 	struct mii_if_info mii_if;		/* MII lib hooks/info */
@@ -597,7 +791,8 @@
 static int	start_tx(struct sk_buff *skb, struct net_device *dev);
 static void	intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
 static void	netdev_error(struct net_device *dev, int intr_status);
-static int	netdev_rx(struct net_device *dev);
+static int	__netdev_rx(struct net_device *dev, int *quota);
+static void	refill_rx_ring(struct net_device *dev);
 static void	netdev_error(struct net_device *dev, int intr_status);
 static void	set_rx_mode(struct net_device *dev);
 static struct net_device_stats *get_stats(struct net_device *dev);
@@ -606,6 +801,44 @@
 static void	netdev_media_change(struct net_device *dev);
 
 
+#ifdef VLAN_SUPPORT
+static void netdev_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+        struct netdev_private *np = dev->priv;
+
+        spin_lock(&np->lock);
+	if (debug > 2)
+		printk("%s: Setting vlgrp to %p\n", dev->name, grp);
+        np->vlgrp = grp;
+	set_rx_mode(dev);
+        spin_unlock(&np->lock);
+}
+
+static void netdev_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
+{
+	struct netdev_private *np = dev->priv;
+
+	spin_lock(&np->lock);
+	if (debug > 1)
+		printk("%s: Adding vlanid %d to vlan filter\n", dev->name, vid);
+	set_rx_mode(dev);
+	spin_unlock(&np->lock);
+}
+
+static void netdev_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+	struct netdev_private *np = dev->priv;
+
+	spin_lock(&np->lock);
+	if (debug > 1)
+		printk("%s: removing vlanid %d from vlan filter\n", dev->name, vid);
+	if (np->vlgrp)
+		np->vlgrp->vlan_devices[vid] = NULL;
+	set_rx_mode(dev);
+	spin_unlock(&np->lock);
+}
+#endif /* VLAN_SUPPORT */
+
 
 static int __devinit starfire_init_one(struct pci_dev *pdev,
 				       const struct pci_device_id *ent)
@@ -617,10 +850,6 @@
 	long ioaddr;
 	int drv_flags, io_size;
 	int boguscnt;
-#ifndef HAVE_PCI_SET_MWI
-	u16 cmd;
-	u8 cache;
-#endif
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -637,13 +866,13 @@
 	ioaddr = pci_resource_start(pdev, 0);
 	io_size = pci_resource_len(pdev, 0);
 	if (!ioaddr || ((pci_resource_flags(pdev, 0) & IORESOURCE_MEM) == 0)) {
-		printk (KERN_ERR DRV_NAME " %d: no PCI MEM resources, aborting\n", card_idx);
+		printk(KERN_ERR DRV_NAME " %d: no PCI MEM resources, aborting\n", card_idx);
 		return -ENODEV;
 	}
 
 	dev = alloc_etherdev(sizeof(*np));
 	if (!dev) {
-		printk (KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx);
+		printk(KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx);
 		return -ENOMEM;
 	}
 	SET_MODULE_OWNER(dev);
@@ -651,7 +880,7 @@
 	irq = pdev->irq;
 
 	if (pci_request_regions (pdev, dev->name)) {
-		printk (KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx);
+		printk(KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx);
 		goto err_out_free_netdev;
 	}
 
@@ -659,7 +888,7 @@
 #if !defined(CONFIG_SPARC64) || LINUX_VERSION_CODE > 0x20300
 	ioaddr = (long) ioremap(ioaddr, io_size);
 	if (!ioaddr) {
-		printk (KERN_ERR DRV_NAME " %d: cannot remap 0x%x @ 0x%lx, aborting\n",
+		printk(KERN_ERR DRV_NAME " %d: cannot remap %#x @ %#lx, aborting\n",
 			card_idx, io_size, ioaddr);
 		goto err_out_free_res;
 	}
@@ -667,29 +896,26 @@
 
 	pci_set_master(pdev);
 
-#ifdef HAVE_PCI_SET_MWI
-	pci_set_mwi(pdev);
-#else
 	/* enable MWI -- it vastly improves Rx performance on sparc64 */
-	pci_read_config_word(pdev, PCI_COMMAND, &cmd);
-	cmd |= PCI_COMMAND_INVALIDATE;
-	pci_write_config_word(pdev, PCI_COMMAND, cmd);
-
-	/* set PCI cache size */
-	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache);
-	if ((cache << 2) != SMP_CACHE_BYTES) {
-		printk(KERN_INFO "  PCI cache line size set incorrectly "
-		       "(%i bytes) by BIOS/FW, correcting to %i\n",
-		       (cache << 2), SMP_CACHE_BYTES);
-		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
-				      SMP_CACHE_BYTES >> 2);
-	}
-#endif
+	pci_set_mwi(pdev);
 
+#ifdef MAX_SKB_FRAGS
+	dev->features |= NETIF_F_SG;
+#endif /* MAX_SKB_FRAGS */
 #ifdef ZEROCOPY
-	/* Starfire can do SG and TCP/UDP checksumming */
-	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+	/* Starfire can do TCP/UDP checksumming */
+	if (enable_hw_cksum)
+		dev->features |= NETIF_F_IP_CSUM;
 #endif /* ZEROCOPY */
+#ifdef VLAN_SUPPORT
+	dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
+	dev->vlan_rx_register = netdev_vlan_rx_register;
+	dev->vlan_rx_add_vid = netdev_vlan_rx_add_vid;
+	dev->vlan_rx_kill_vid = netdev_vlan_rx_kill_vid;
+#endif /* VLAN_RX_KILL_VID */
+#ifdef ADDR_64BITS
+	dev->features |= NETIF_F_HIGHDMA;
+#endif /* ADDR_64BITS */
 
 	/* Serial EEPROM reads are hidden by the hardware. */
 	for (i = 0; i < 6; i++)
@@ -704,7 +930,7 @@
 #endif
 
 	/* Issue soft reset */
-	writel(0x8000, ioaddr + TxMode);
+	writel(MiiSoftReset, ioaddr + TxMode);
 	udelay(1000);
 	writel(0, ioaddr + TxMode);
 
@@ -750,15 +976,40 @@
 		np->mii_if.full_duplex = 1;
 
 	if (np->mii_if.full_duplex)
-		np->mii_if.force_media = 0;
-	else
 		np->mii_if.force_media = 1;
+	else
+		np->mii_if.force_media = 0;
 	np->speed100 = 1;
 
+	/* timer resolution is 128 * 0.8us */
+	np->intr_timer_ctrl = (((intr_latency * 10) / 1024) & IntrLatencyMask) |
+		Timer10X | EnableIntrMasking;
+
+	if (small_frames > 0) {
+		np->intr_timer_ctrl |= SmallFrameBypass;
+		switch (small_frames) {
+		case 1 ... 64:
+			np->intr_timer_ctrl |= SmallFrame64;
+			break;
+		case 65 ... 128:
+			np->intr_timer_ctrl |= SmallFrame128;
+			break;
+		case 129 ... 256:
+			np->intr_timer_ctrl |= SmallFrame256;
+			break;
+		default:
+			np->intr_timer_ctrl |= SmallFrame512;
+			if (small_frames > 512)
+				printk("Adjusting small_frames down to 512\n");
+			break;
+		}
+	}
+
 	/* The chip-specific entries in the device structure. */
 	dev->open = &netdev_open;
 	dev->hard_start_xmit = &start_tx;
 	init_tx_timer(dev, tx_timeout, TX_TIMEOUT);
+	init_poll(dev);
 	dev->stop = &netdev_close;
 	dev->get_stats = &get_stats;
 	dev->set_multicast_list = &set_rx_mode;
@@ -767,11 +1018,10 @@
 	if (mtu)
 		dev->mtu = mtu;
 
-	i = register_netdev(dev);
-	if (i)
+	if (register_netdev(dev))
 		goto err_out_cleardev;
 
-	printk(KERN_INFO "%s: %s at 0x%lx, ",
+	printk(KERN_INFO "%s: %s at %#lx, ",
 		   dev->name, netdrv_tbl[chip_idx].name, ioaddr);
 	for (i = 0; i < 5; i++)
 		printk("%2.2x:", dev->dev_addr[i]);
@@ -796,7 +1046,7 @@
 				np->phys[phy_idx++] = phy;
 				np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
 				printk(KERN_INFO "%s: MII PHY found at address %d, status "
-					   "0x%4.4x advertising %4.4x.\n",
+					   "%#4.4x advertising %#4.4x.\n",
 					   dev->name, phy, mii_status, np->mii_if.advertising);
 				/* there can be only one PHY on-board */
 				break;
@@ -809,14 +1059,8 @@
 			memset(&np->mii_if, 0, sizeof(np->mii_if));
 	}
 
-#ifdef ZEROCOPY
-	printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming enabled.\n",
-	       dev->name);
-#else  /* not ZEROCOPY */
-	printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming disabled.\n",
-	       dev->name);
-#endif /* not ZEROCOPY */
-
+	printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming %s.\n",
+	       dev->name, enable_hw_cksum ? "enabled" : "disabled");
 	return 0;
 
 err_out_cleardev:
@@ -825,7 +1069,6 @@
 err_out_free_res:
 	pci_release_regions (pdev);
 err_out_free_netdev:
-	unregister_netdev(dev);
 	kfree(dev);
 	return -ENODEV;
 }
@@ -861,6 +1104,7 @@
 	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
 	int i, retval;
+	size_t tx_done_q_size, rx_done_q_size, tx_ring_size, rx_ring_size;
 
 	/* Do we ever need to reset the chip??? */
 
@@ -878,62 +1122,61 @@
 	if (debug > 1)
 		printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
 		       dev->name, dev->irq);
-	/* Allocate the various queues, failing gracefully. */
-	if (np->tx_done_q == 0)
-		np->tx_done_q = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_done_q_dma);
-	if (np->rx_done_q == 0)
-		np->rx_done_q = pci_alloc_consistent(np->pci_dev, sizeof(struct rx_done_desc) * DONE_Q_SIZE, &np->rx_done_q_dma);
-	if (np->tx_ring == 0)
-		np->tx_ring = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_ring_dma);
-	if (np->rx_ring == 0)
-		np->rx_ring = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->rx_ring_dma);
-	if (np->tx_done_q == 0 || np->rx_done_q == 0
-		|| np->rx_ring == 0 || np->tx_ring == 0) {
-		if (np->tx_done_q)
-			pci_free_consistent(np->pci_dev, PAGE_SIZE,
-					    np->tx_done_q, np->tx_done_q_dma);
-		if (np->rx_done_q)
-			pci_free_consistent(np->pci_dev, sizeof(struct rx_done_desc) * DONE_Q_SIZE,
-					    np->rx_done_q, np->rx_done_q_dma);
-		if (np->tx_ring)
-			pci_free_consistent(np->pci_dev, PAGE_SIZE,
-					    np->tx_ring, np->tx_ring_dma);
-		if (np->rx_ring)
-			pci_free_consistent(np->pci_dev, PAGE_SIZE,
-					    np->rx_ring, np->rx_ring_dma);
-		COMPAT_MOD_DEC_USE_COUNT;
-		return -ENOMEM;
+
+	/* Allocate the various queues. */
+	if (np->queue_mem == 0) {
+		tx_done_q_size = ((sizeof(struct tx_done_desc) * DONE_Q_SIZE + QUEUE_ALIGN - 1) / QUEUE_ALIGN) * QUEUE_ALIGN;
+		rx_done_q_size = ((sizeof(rx_done_desc) * DONE_Q_SIZE + QUEUE_ALIGN - 1) / QUEUE_ALIGN) * QUEUE_ALIGN;
+		tx_ring_size = ((sizeof(starfire_tx_desc) * TX_RING_SIZE + QUEUE_ALIGN - 1) / QUEUE_ALIGN) * QUEUE_ALIGN;
+		rx_ring_size = sizeof(struct starfire_rx_desc) * RX_RING_SIZE;
+		np->queue_mem_size = tx_done_q_size + rx_done_q_size + tx_ring_size + rx_ring_size;
+		np->queue_mem = pci_alloc_consistent(np->pci_dev, np->queue_mem_size, &np->queue_mem_dma);
+		if (np->queue_mem == 0) {
+			COMPAT_MOD_DEC_USE_COUNT;
+			return -ENOMEM;
+		}
+
+		np->tx_done_q     = np->queue_mem;
+		np->tx_done_q_dma = np->queue_mem_dma;
+		np->rx_done_q     = (void *) np->tx_done_q + tx_done_q_size;
+		np->rx_done_q_dma = np->tx_done_q_dma + tx_done_q_size;
+		np->tx_ring       = (void *) np->rx_done_q + rx_done_q_size;
+		np->tx_ring_dma   = np->rx_done_q_dma + rx_done_q_size;
+		np->rx_ring       = (void *) np->tx_ring + tx_ring_size;
+		np->rx_ring_dma   = np->tx_ring_dma + tx_ring_size;
 	}
 
+	/* Start with no carrier, it gets adjusted later */
 	netif_carrier_off(dev);
 	init_ring(dev);
 	/* Set the size of the Rx buffers. */
 	writel((np->rx_buf_sz << RxBufferLenShift) |
 	       (0 << RxMinDescrThreshShift) |
 	       RxPrefetchMode | RxVariableQ |
+	       RX_Q_ENTRIES |
+	       RX_DESC_Q_ADDR_SIZE | RX_DESC_ADDR_SIZE |
 	       RxDescSpace4,
 	       ioaddr + RxDescQCtrl);
 
-#ifdef ZEROCOPY
-	/* Set Tx descriptor to type 0 and spacing to 64 bytes. */
-	writel((2 << TxHiPriFIFOThreshShift) |
-	       (0 << TxPadLenShift) |
-	       (4 << TxDMABurstSizeShift) |
-	       TxDescSpace64 | TxDescType0,
-	       ioaddr + TxDescCtrl);
-#else  /* not ZEROCOPY */
-	/* Set Tx descriptor to type 1 and padding to 0 bytes. */
+	/* Set up the Rx DMA controller. */
+	writel(RxChecksumIgnore |
+	       (0 << RxEarlyIntThreshShift) |
+	       (6 << RxHighPrioThreshShift) |
+	       ((DMA_BURST_SIZE / 32) << RxBurstSizeShift),
+	       ioaddr + RxDMACtrl);
+
+	/* Set Tx descriptor */
 	writel((2 << TxHiPriFIFOThreshShift) |
 	       (0 << TxPadLenShift) |
-	       (4 << TxDMABurstSizeShift) |
-	       TxDescSpaceUnlim | TxDescType1,
+	       ((DMA_BURST_SIZE / 32) << TxDMABurstSizeShift) |
+	       TX_DESC_Q_ADDR_SIZE |
+	       TX_DESC_SPACING | TX_DESC_TYPE,
 	       ioaddr + TxDescCtrl);
-#endif /* not ZEROCOPY */
 
-#if defined(ADDR_64BITS) && defined(__alpha__)
-	/* XXX We really need a 64-bit PCI dma interfaces too... -DaveM */
-	writel(np->rx_ring_dma >> 32, ioaddr + RxDescQHiAddr);
-	writel(np->tx_ring_dma >> 32, ioaddr + TxRingHiAddr);
+#if defined(ADDR_64BITS)
+	writel(np->queue_mem_dma >> 32, ioaddr + RxDescQHiAddr);
+	writel(np->queue_mem_dma >> 32, ioaddr + TxRingHiAddr);
+	writel(np->queue_mem_dma >> 32, ioaddr + CompletionHiAddr);
 #else
 	writel(0, ioaddr + RxDescQHiAddr);
 	writel(0, ioaddr + TxRingHiAddr);
@@ -943,32 +1186,23 @@
 	writel(np->tx_ring_dma, ioaddr + TxRingPtr);
 
 	writel(np->tx_done_q_dma, ioaddr + TxCompletionAddr);
-#ifdef full_rx_status
 	writel(np->rx_done_q_dma |
-	       RxComplType3 |
+	       RxComplType |
 	       (0 << RxComplThreshShift),
 	       ioaddr + RxCompletionAddr);
-#else  /* not full_rx_status */
-#ifdef csum_rx_status
-	writel(np->rx_done_q_dma |
-	       RxComplType2 |
-	       (0 << RxComplThreshShift),
-	       ioaddr + RxCompletionAddr);
-#else  /* not csum_rx_status */
-	writel(np->rx_done_q_dma |
-	       RxComplType0 |
-	       (0 << RxComplThreshShift),
-	       ioaddr + RxCompletionAddr);
-#endif /* not csum_rx_status */
-#endif /* not full_rx_status */
 
 	if (debug > 1)
 		printk(KERN_DEBUG "%s: Filling in the station address.\n", dev->name);
 
-	/* Fill both the unused Tx SA register and the Rx perfect filter. */
+	/* Fill both the Tx SA register and the Rx perfect filter. */
 	for (i = 0; i < 6; i++)
-		writeb(dev->dev_addr[i], ioaddr + StationAddr + 5 - i);
-	for (i = 0; i < 16; i++) {
+		writeb(dev->dev_addr[i], ioaddr + TxStationAddr + 5 - i);
+	/* The first entry is special because it bypasses the VLAN filter.
+	   Don't use it. */
+	writew(0, ioaddr + PerfFilterTable);
+	writew(0, ioaddr + PerfFilterTable + 4);
+	writew(0, ioaddr + PerfFilterTable + 8);
+	for (i = 1; i < 16; i++) {
 		u16 *eaddrs = (u16 *)dev->dev_addr;
 		long setup_frm = ioaddr + PerfFilterTable + i * 16;
 		writew(cpu_to_be16(eaddrs[2]), setup_frm); setup_frm += 4;
@@ -978,16 +1212,14 @@
 
 	/* Initialize other registers. */
 	/* Configure the PCI bus bursts and FIFO thresholds. */
-	np->tx_mode = 0x0C04;		/* modified when link is up. */
-	writel(0x8000 | np->tx_mode, ioaddr + TxMode);
+	np->tx_mode = TxFlowEnable|RxFlowEnable|PadEnable;	/* modified when link is up. */
+	writel(MiiSoftReset | np->tx_mode, ioaddr + TxMode);
 	udelay(1000);
 	writel(np->tx_mode, ioaddr + TxMode);
 	np->tx_threshold = 4;
 	writel(np->tx_threshold, ioaddr + TxThreshold);
 
-	interrupt_mitigation &= 0x1f;
-	np->intr_mitigation = interrupt_mitigation;
-	writel(np->intr_mitigation, ioaddr + IntrTimerCtrl);
+	writel(np->intr_timer_ctrl, ioaddr + IntrTimerCtrl);
 
 	netif_start_if(dev);
 	netif_start_queue(dev);
@@ -1002,29 +1234,35 @@
 	/* Enable GPIO interrupts on link change */
 	writel(0x0f00ff00, ioaddr + GPIOCtrl);
 
-	/* Set the interrupt mask and enable PCI interrupts. */
+	/* Set the interrupt mask */
 	writel(IntrRxDone | IntrRxEmpty | IntrDMAErr |
-	       IntrTxDone | IntrStatsMax | IntrLinkChange |
-	       IntrNormalSummary | IntrAbnormalSummary |
+	       IntrTxDMADone | IntrStatsMax | IntrLinkChange |
 	       IntrRxGFPDead | IntrNoTxCsum | IntrTxBadID,
 	       ioaddr + IntrEnable);
+	/* Enable PCI interrupts. */
 	writel(0x00800000 | readl(ioaddr + PCIDeviceConfig),
 	       ioaddr + PCIDeviceConfig);
 
+#ifdef VLAN_SUPPORT
+	/* Set VLAN type to 802.1q */
+	writel(ETH_P_8021Q, ioaddr + VlanType);
+#endif /* VLAN_SUPPORT */
+
 #ifdef HAS_FIRMWARE
 	/* Load Rx/Tx firmware into the frame processors */
 	for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++)
 		writel(firmware_rx[i], ioaddr + RxGfpMem + i * 4);
 	for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++)
 		writel(firmware_tx[i], ioaddr + TxGfpMem + i * 4);
-	/* Enable the Rx and Tx units, and the Rx/Tx frame processors. */
-	writel(0x003F, ioaddr + GenCtrl);
-#else  /* not HAS_FIRMWARE */
-	/* Enable the Rx and Tx units only. */
-	writel(0x000F, ioaddr + GenCtrl);
-#endif /* not HAS_FIRMWARE */
+#endif /* HAS_FIRMWARE */
+	if (enable_hw_cksum)
+		/* Enable the Rx and Tx units, and the Rx/Tx frame processors. */
+		writel(TxEnable|TxGFPEnable|RxEnable|RxGFPEnable, ioaddr + GenCtrl);
+	else
+		/* Enable the Rx and Tx units only. */
+		writel(TxEnable|RxEnable, ioaddr + GenCtrl);
 
-	if (debug > 2)
+	if (debug > 1)
 		printk(KERN_DEBUG "%s: Done netdev_open().\n",
 		       dev->name);
 
@@ -1036,11 +1274,17 @@
 {
 	struct netdev_private *np = dev->priv;
 	u16 reg0;
+	int silly_count = 1000;
 
 	mdio_write(dev, np->phys[0], MII_ADVERTISE, np->mii_if.advertising);
 	mdio_write(dev, np->phys[0], MII_BMCR, BMCR_RESET);
 	udelay(500);
-	while (mdio_read(dev, np->phys[0], MII_BMCR) & BMCR_RESET);
+	while (--silly_count && mdio_read(dev, np->phys[0], MII_BMCR) & BMCR_RESET)
+		/* do nothing */;
+	if (!silly_count) {
+		printk("%s: MII reset failed!\n", dev->name);
+		return;
+	}
 
 	reg0 = mdio_read(dev, np->phys[0], MII_BMCR);
 
@@ -1065,25 +1309,22 @@
 {
 	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
+	int old_debug;
 
-	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
-	       " resetting...\n", dev->name, (int)readl(ioaddr + IntrStatus));
-
-#ifndef __alpha__
-	{
-		int i;
-		printk(KERN_DEBUG "  Rx ring %p: ", np->rx_ring);
-		for (i = 0; i < RX_RING_SIZE; i++)
-			printk(" %8.8x", (unsigned int)le32_to_cpu(np->rx_ring[i].rxaddr));
-		printk("\n"KERN_DEBUG"  Tx ring %p: ", np->tx_ring);
-		for (i = 0; i < TX_RING_SIZE; i++)
-			printk(" %4.4x", le32_to_cpu(np->tx_ring[i].status));
-		printk("\n");
-	}
-#endif
+	printk(KERN_WARNING "%s: Transmit timed out, status %#8.8x, "
+	       "resetting...\n", dev->name, (int) readl(ioaddr + IntrStatus));
 
 	/* Perhaps we should reinitialize the hardware here. */
-	/* Stop and restart the chip's Tx processes . */
+
+	/*
+	 * Stop and restart the interface.
+	 * Cheat and increase the debug level temporarily.
+	 */
+	old_debug = debug;
+	debug = 2;
+	netdev_close(dev);
+	netdev_open(dev);
+	debug = old_debug;
 
 	/* Trigger an immediate transmit demand. */
 
@@ -1099,9 +1340,8 @@
 	struct netdev_private *np = dev->priv;
 	int i;
 
-	np->tx_full = 0;
-	np->cur_rx = np->cur_tx = 0;
-	np->dirty_rx = np->rx_done = np->dirty_tx = np->tx_done = 0;
+	np->cur_rx = np->cur_tx = np->reap_tx = 0;
+	np->dirty_rx = np->dirty_tx = np->rx_done = np->tx_done = 0;
 
 	np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
 
@@ -1114,7 +1354,7 @@
 		np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		skb->dev = dev;			/* Mark as being used by this device. */
 		/* Grrr, we cannot offset to correctly align the IP header. */
-		np->rx_ring[i].rxaddr = cpu_to_le32(np->rx_info[i].mapping | RxDescValid);
+		np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid);
 	}
 	writew(i - 1, dev->base_addr + RxDescQIdx);
 	np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
@@ -1126,7 +1366,7 @@
 		np->rx_info[i].mapping = 0;
 	}
 	/* Mark the last entry as wrapping the ring. */
-	np->rx_ring[i-1].rxaddr |= cpu_to_le32(RxDescEndRing);
+	np->rx_ring[RX_RING_SIZE - 1].rxaddr |= cpu_to_dma(RxDescEndRing);
 
 	/* Clear the completion rings. */
 	for (i = 0; i < DONE_Q_SIZE; i++) {
@@ -1134,18 +1374,9 @@
 		np->tx_done_q[i].status = 0;
 	}
 
-	for (i = 0; i < TX_RING_SIZE; i++) {
-		np->tx_info[i].skb = NULL;
-		np->tx_info[i].first_mapping = 0;
-#ifdef ZEROCOPY
-		{
-			int j;
-			for (j = 0; j < MAX_STARFIRE_FRAGS; j++)
-				np->tx_info[i].frag_mapping[j] = 0;
-		}
-#endif /* ZEROCOPY */
-		np->tx_ring[i].status = 0;
-	}
+	for (i = 0; i < TX_RING_SIZE; i++)
+		memset(&np->tx_info[i], 0, sizeof(np->tx_info[i]));
+
 	return;
 }
 
@@ -1154,19 +1385,21 @@
 {
 	struct netdev_private *np = dev->priv;
 	unsigned int entry;
-#ifdef ZEROCOPY
+	u32 status;
 	int i;
-#endif
 
 	kick_tx_timer(dev, tx_timeout, TX_TIMEOUT);
 
-	/* Caution: the write order is important here, set the field
-	   with the "ownership" bits last. */
-
-	/* Calculate the next Tx descriptor entry. */
-	entry = np->cur_tx % TX_RING_SIZE;
+	/*
+	 * be cautious here, wrapping the queue has weird semantics
+	 * and we may not have enough slots even when it seems we do.
+	 */
+	if ((np->cur_tx - np->dirty_tx) + skb_num_frags(skb) * 2 > TX_RING_SIZE) {
+		netif_stop_queue(dev);
+		return 1;
+	}
 
-#if defined(ZEROCOPY) && defined(HAS_FIRMWARE) && defined(HAS_BROKEN_FIRMWARE)
+#if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE)
 	{
 		int has_bad_length = 0;
 
@@ -1183,85 +1416,72 @@
 		if (has_bad_length)
 			skb_checksum_help(skb);
 	}
-#endif /* ZEROCOPY && HAS_FIRMWARE && HAS_BROKEN_FIRMWARE */
-
-	np->tx_info[entry].skb = skb;
-	np->tx_info[entry].first_mapping =
-		pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE);
-
-	np->tx_ring[entry].first_addr = cpu_to_le32(np->tx_info[entry].first_mapping);
-#ifdef ZEROCOPY
-	np->tx_ring[entry].first_len = cpu_to_le16(skb_first_frag_len(skb));
-	np->tx_ring[entry].total_len = cpu_to_le16(skb->len);
-	/* Add "| TxDescIntr" to generate Tx-done interrupts. */
-	np->tx_ring[entry].status = cpu_to_le32(TxDescID | TxCRCEn);
-	np->tx_ring[entry].nbufs = cpu_to_le32(skb_shinfo(skb)->nr_frags + 1);
-#else  /* not ZEROCOPY */
-	/* Add "| TxDescIntr" to generate Tx-done interrupts. */
-	np->tx_ring[entry].status = cpu_to_le32(skb->len | TxDescID | TxCRCEn | 1 << 16);
-#endif /* not ZEROCOPY */
+#endif /* ZEROCOPY && HAS_BROKEN_FIRMWARE */
 
-	if (entry >= TX_RING_SIZE-1)		 /* Wrap ring */
-		np->tx_ring[entry].status |= cpu_to_le32(TxRingWrap | TxDescIntr);
-
-#ifdef ZEROCOPY
-	if (skb->ip_summed == CHECKSUM_HW) {
-		np->tx_ring[entry].status |= cpu_to_le32(TxCalTCP);
-		np->stats.tx_compressed++;
-	}
-#endif /* ZEROCOPY */
+	entry = np->cur_tx % TX_RING_SIZE;
+	for (i = 0; i < skb_num_frags(skb); i++) {
+		int wrap_ring = 0;
+		status = TxDescID;
+
+		if (i == 0) {
+			np->tx_info[entry].skb = skb;
+			status |= TxCRCEn;
+			if (entry >= TX_RING_SIZE - skb_num_frags(skb)) {
+				status |= TxRingWrap;
+				wrap_ring = 1;
+			}
+			if (np->reap_tx) {
+				status |= TxDescIntr;
+				np->reap_tx = 0;
+			}
+			if (skb->ip_summed == CHECKSUM_HW) {
+				status |= TxCalTCP;
+				np->stats.tx_compressed++;
+			}
+			status |= skb_first_frag_len(skb) | (skb_num_frags(skb) << 16);
 
-	if (debug > 5) {
-#ifdef ZEROCOPY
-		printk(KERN_DEBUG "%s: Tx #%d slot %d status %8.8x nbufs %d len %4.4x/%4.4x.\n",
-		       dev->name, np->cur_tx, entry,
-		       le32_to_cpu(np->tx_ring[entry].status),
-		       le32_to_cpu(np->tx_ring[entry].nbufs),
-		       le32_to_cpu(np->tx_ring[entry].first_len),
-		       le32_to_cpu(np->tx_ring[entry].total_len));
-#else  /* not ZEROCOPY */
-		printk(KERN_DEBUG "%s: Tx #%d slot %d status %8.8x.\n",
-		       dev->name, np->cur_tx, entry,
-		       le32_to_cpu(np->tx_ring[entry].status));
-#endif /* not ZEROCOPY */
+			np->tx_info[entry].mapping =
+				pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE);
+		} else {
+#ifdef MAX_SKB_FRAGS
+			skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i - 1];
+			status |= this_frag->size;
+			np->tx_info[entry].mapping =
+				pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE);
+#endif /* MAX_SKB_FRAGS */
+		}
+
+		np->tx_ring[entry].addr = cpu_to_dma(np->tx_info[entry].mapping);
+		np->tx_ring[entry].status = cpu_to_le32(status);
+		if (debug > 3)
+			printk(KERN_DEBUG "%s: Tx #%d/#%d slot %d status %#8.8x.\n",
+			       dev->name, np->cur_tx, np->dirty_tx,
+			       entry, status);
+		if (wrap_ring) {
+			np->tx_info[entry].used_slots = TX_RING_SIZE - entry;
+			np->cur_tx += np->tx_info[entry].used_slots;
+			entry = 0;
+		} else {
+			np->tx_info[entry].used_slots = 1;
+			np->cur_tx += np->tx_info[entry].used_slots;
+			entry++;
+		}
+		/* scavenge the tx descriptors twice per TX_RING_SIZE */
+		if (np->cur_tx % (TX_RING_SIZE / 2) == 0)
+			np->reap_tx = 1;
 	}
 
-#ifdef ZEROCOPY
-	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-		skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i];
-
-		/* we already have the proper value in entry */
-		np->tx_info[entry].frag_mapping[i] =
-			pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE);
-
-		np->tx_ring[entry].frag[i].addr = cpu_to_le32(np->tx_info[entry].frag_mapping[i]);
-		np->tx_ring[entry].frag[i].len = cpu_to_le32(this_frag->size);
-		if (debug > 5) {
-			printk(KERN_DEBUG "%s: Tx #%d frag %d len %4.4x.\n",
-			       dev->name, np->cur_tx, i,
-			       le32_to_cpu(np->tx_ring[entry].frag[i].len));
-		}
-	}
-#endif /* ZEROCOPY */
-
-	np->cur_tx++;
-
-	if (entry >= TX_RING_SIZE-1)		 /* Wrap ring */
-		entry = -1;
-	entry++;
-
 	/* Non-x86: explicitly flush descriptor cache lines here. */
-	/* Ensure everything is written back above before the transmit is
+	/* Ensure all descriptors are written back before the transmit is
 	   initiated. - Jes */
 	wmb();
 
 	/* Update the producer index. */
-	writel(entry * (sizeof(struct starfire_tx_desc) / 8), dev->base_addr + TxProducerIdx);
+	writel(entry * (sizeof(starfire_tx_desc) / 8), dev->base_addr + TxProducerIdx);
 
-	if (np->cur_tx - np->dirty_tx >= TX_RING_SIZE - 1) {
-		np->tx_full = 1;
+	/* 4 is arbitrary, but should be ok */
+	if ((np->cur_tx - np->dirty_tx) + 4 > TX_RING_SIZE)
 		netif_stop_queue(dev);
-	}
 
 	dev->trans_start = jiffies;
 
@@ -1273,20 +1493,13 @@
    after the Tx thread. */
 static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
 {
-	struct net_device *dev = (struct net_device *)dev_instance;
+	struct net_device *dev = dev_instance;
 	struct netdev_private *np;
 	long ioaddr;
 	int boguscnt = max_interrupt_work;
 	int consumer;
 	int tx_status;
 
-#ifndef final_version			/* Can never occur. */
-	if (dev == NULL) {
-		printk (KERN_ERR "Netdev interrupt handler(): IRQ %d for unknown device.\n", irq);
-		return;
-	}
-#endif
-
 	ioaddr = dev->base_addr;
 	np = dev->priv;
 
@@ -1294,83 +1507,69 @@
 		u32 intr_status = readl(ioaddr + IntrClear);
 
 		if (debug > 4)
-			printk(KERN_DEBUG "%s: Interrupt status %4.4x.\n",
+			printk(KERN_DEBUG "%s: Interrupt status %#8.8x.\n",
 			       dev->name, intr_status);
 
-		if (intr_status == 0)
+		if (intr_status == 0 || intr_status == (u32) -1)
 			break;
 
-		if (intr_status & IntrRxDone)
-			netdev_rx(dev);
+		if (intr_status & (IntrRxDone | IntrRxEmpty))
+			netdev_rx(dev, ioaddr);
 
 		/* Scavenge the skbuff list based on the Tx-done queue.
 		   There are redundant checks here that may be cleaned up
 		   after the driver has proven to be reliable. */
 		consumer = readl(ioaddr + TxConsumerIdx);
-		if (debug > 4)
+		if (debug > 3)
 			printk(KERN_DEBUG "%s: Tx Consumer index is %d.\n",
 			       dev->name, consumer);
-#if 0
-		if (np->tx_done >= 250 || np->tx_done == 0)
-			printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x, %d is %8.8x.\n",
-			       dev->name, np->tx_done,
-			       le32_to_cpu(np->tx_done_q[np->tx_done].status),
-			       (np->tx_done+1) & (DONE_Q_SIZE-1),
-			       le32_to_cpu(np->tx_done_q[(np->tx_done+1)&(DONE_Q_SIZE-1)].status));
-#endif
 
 		while ((tx_status = le32_to_cpu(np->tx_done_q[np->tx_done].status)) != 0) {
-			if (debug > 4)
-				printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x.\n",
-				       dev->name, np->tx_done, tx_status);
+			if (debug > 3)
+				printk(KERN_DEBUG "%s: Tx completion #%d entry %d is %#8.8x.\n",
+				       dev->name, np->dirty_tx, np->tx_done, tx_status);
 			if ((tx_status & 0xe0000000) == 0xa0000000) {
 				np->stats.tx_packets++;
 			} else if ((tx_status & 0xe0000000) == 0x80000000) {
-				struct sk_buff *skb;
-#ifdef ZEROCOPY
-				int i;
-#endif /* ZEROCOPY */
-				u16 entry = tx_status;		/* Implicit truncate */
-				entry /= sizeof(struct starfire_tx_desc);
-
-				skb = np->tx_info[entry].skb;
+				u16 entry = (tx_status & 0x7fff) / sizeof(starfire_tx_desc);
+				struct sk_buff *skb = np->tx_info[entry].skb;
 				np->tx_info[entry].skb = NULL;
 				pci_unmap_single(np->pci_dev,
-						 np->tx_info[entry].first_mapping,
+						 np->tx_info[entry].mapping,
 						 skb_first_frag_len(skb),
 						 PCI_DMA_TODEVICE);
-				np->tx_info[entry].first_mapping = 0;
-
-#ifdef ZEROCOPY
-				for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-					pci_unmap_single(np->pci_dev,
-							 np->tx_info[entry].frag_mapping[i],
-							 skb_shinfo(skb)->frags[i].size,
-							 PCI_DMA_TODEVICE);
-					np->tx_info[entry].frag_mapping[i] = 0;
+				np->tx_info[entry].mapping = 0;
+				np->dirty_tx += np->tx_info[entry].used_slots;
+				entry = (entry + np->tx_info[entry].used_slots) % TX_RING_SIZE;
+#ifdef MAX_SKB_FRAGS
+				{
+					int i;
+					for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+						pci_unmap_single(np->pci_dev,
+								 np->tx_info[entry].mapping,
+								 skb_shinfo(skb)->frags[i].size,
+								 PCI_DMA_TODEVICE);
+						np->dirty_tx++;
+						entry++;
+					}
 				}
-#endif /* ZEROCOPY */
-
-				/* Scavenge the descriptor. */
+#endif /* MAX_SKB_FRAGS */
 				dev_kfree_skb_irq(skb);
-
-				np->dirty_tx++;
 			}
 			np->tx_done_q[np->tx_done].status = 0;
-			np->tx_done = (np->tx_done+1) & (DONE_Q_SIZE-1);
+			np->tx_done = (np->tx_done + 1) % DONE_Q_SIZE;
 		}
 		writew(np->tx_done, ioaddr + CompletionQConsumerIdx + 2);
 
-		if (np->tx_full && np->cur_tx - np->dirty_tx < TX_RING_SIZE - 4) {
+		if (netif_queue_stopped(dev) &&
+		    (np->cur_tx - np->dirty_tx + 4 < TX_RING_SIZE)) {
 			/* The ring is no longer full, wake the queue. */
-			np->tx_full = 0;
 			netif_wake_queue(dev);
 		}
 
 		/* Stats overflow */
-		if (intr_status & IntrStatsMax) {
+		if (intr_status & IntrStatsMax)
 			get_stats(dev);
-		}
 
 		/* Media change interrupt. */
 		if (intr_status & IntrLinkChange)
@@ -1381,72 +1580,58 @@
 			netdev_error(dev, intr_status);
 
 		if (--boguscnt < 0) {
-			printk(KERN_WARNING "%s: Too much work at interrupt, "
-			       "status=0x%4.4x.\n",
-			       dev->name, intr_status);
+			if (debug > 1)
+				printk(KERN_WARNING "%s: Too much work at interrupt, "
+				       "status=%#8.8x.\n",
+				       dev->name, intr_status);
 			break;
 		}
 	} while (1);
 
 	if (debug > 4)
-		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
-		       dev->name, (int)readl(ioaddr + IntrStatus));
-
-#ifndef final_version
-	/* Code that should never be run!  Remove after testing.. */
-	{
-		static int stopit = 10;
-		if (!netif_running(dev) && --stopit < 0) {
-			printk(KERN_ERR "%s: Emergency stop, looping startup interrupt.\n",
-			       dev->name);
-			free_irq(irq, dev);
-		}
-	}
-#endif
+		printk(KERN_DEBUG "%s: exiting interrupt, status=%#8.8x.\n",
+		       dev->name, (int) readl(ioaddr + IntrStatus));
 }
 
 
-/* This routine is logically part of the interrupt handler, but separated
-   for clarity and better register allocation. */
-static int netdev_rx(struct net_device *dev)
+/* This routine is logically part of the interrupt/poll handler, but separated
+   for clarity, code sharing between NAPI/non-NAPI, and better register allocation. */
+static int __netdev_rx(struct net_device *dev, int *quota)
 {
 	struct netdev_private *np = dev->priv;
-	int boguscnt = np->dirty_rx + RX_RING_SIZE - np->cur_rx;
 	u32 desc_status;
-
-	if (np->rx_done_q == 0) {
-		printk(KERN_ERR "%s:  rx_done_q is NULL!  rx_done is %d. %p.\n",
-		       dev->name, np->rx_done, np->tx_done_q);
-		return 0;
-	}
+	int retcode = 0;
 
 	/* If EOP is set on the next entry, it's a new packet. Send it up. */
 	while ((desc_status = le32_to_cpu(np->rx_done_q[np->rx_done].status)) != 0) {
 		struct sk_buff *skb;
 		u16 pkt_len;
 		int entry;
+		rx_done_desc *desc = &np->rx_done_q[np->rx_done];
 
 		if (debug > 4)
-			printk(KERN_DEBUG "  netdev_rx() status of %d was %8.8x.\n", np->rx_done, desc_status);
-		if (--boguscnt < 0)
-			break;
-		if ( ! (desc_status & RxOK)) {
+			printk(KERN_DEBUG "  netdev_rx() status of %d was %#8.8x.\n", np->rx_done, desc_status);
+		if (!(desc_status & RxOK)) {
 			/* There was a error. */
 			if (debug > 2)
-				printk(KERN_DEBUG "  netdev_rx() Rx error was %8.8x.\n", desc_status);
+				printk(KERN_DEBUG "  netdev_rx() Rx error was %#8.8x.\n", desc_status);
 			np->stats.rx_errors++;
 			if (desc_status & RxFIFOErr)
 				np->stats.rx_fifo_errors++;
 			goto next_rx;
 		}
 
+		if (*quota <= 0) {	/* out of rx quota */
+			retcode = 1;
+			goto out;
+		}
+		(*quota)--;
+
 		pkt_len = desc_status;	/* Implicitly Truncate */
 		entry = (desc_status >> 16) & 0x7ff;
 
-#ifndef final_version
 		if (debug > 4)
-			printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d, bogus_cnt %d.\n", pkt_len, boguscnt);
-#endif
+			printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d, quota %d.\n", pkt_len, *quota);
 		/* Check if the packet is long enough to accept without copying
 		   to a minimally-sized skbuff. */
 		if (pkt_len < rx_copybreak
@@ -1456,12 +1641,8 @@
 			pci_dma_sync_single(np->pci_dev,
 					    np->rx_info[entry].mapping,
 					    pkt_len, PCI_DMA_FROMDEVICE);
-#if HAS_IP_COPYSUM			/* Call copy + cksum if available. */
 			eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0);
 			skb_put(skb, pkt_len);
-#else
-			memcpy(skb_put(skb, pkt_len), np->rx_info[entry].skb->tail, pkt_len);
-#endif
 		} else {
 			pci_unmap_single(np->pci_dev, np->rx_info[entry].mapping, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 			skb = np->rx_info[entry].skb;
@@ -1473,51 +1654,109 @@
 		/* You will want this info for the initial debug. */
 		if (debug > 5)
 			printk(KERN_DEBUG "  Rx data %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:"
-			       "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x "
-			       "%d.%d.%d.%d.\n",
+			       "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x.\n",
 			       skb->data[0], skb->data[1], skb->data[2], skb->data[3],
 			       skb->data[4], skb->data[5], skb->data[6], skb->data[7],
 			       skb->data[8], skb->data[9], skb->data[10],
-			       skb->data[11], skb->data[12], skb->data[13],
-			       skb->data[14], skb->data[15], skb->data[16],
-			       skb->data[17]);
+			       skb->data[11], skb->data[12], skb->data[13]);
 #endif
+
 		skb->protocol = eth_type_trans(skb, dev);
-#if defined(full_rx_status) || defined(csum_rx_status)
-		if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000) {
+#if defined(HAS_FIRMWARE) || defined(VLAN_SUPPORT)
+		if (debug > 4)
+			printk(KERN_DEBUG "  netdev_rx() status2 of %d was %#4.4x.\n", np->rx_done, le16_to_cpu(desc->status2));
+#endif
+#ifdef HAS_FIRMWARE
+		if (le16_to_cpu(desc->status2) & 0x0100) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 			np->stats.rx_compressed++;
 		}
 		/*
 		 * This feature doesn't seem to be working, at least
 		 * with the two firmware versions I have. If the GFP sees
-		 * a fragment, it either ignores it completely, or reports
+		 * an IP fragment, it either ignores it completely, or reports
 		 * "bad checksum" on it.
 		 *
 		 * Maybe I missed something -- corrections are welcome.
 		 * Until then, the printk stays. :-) -Ion
 		 */
-		else if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x00400000) {
+		else if (le16_to_cpu(desc->status2) & 0x0040) {
 			skb->ip_summed = CHECKSUM_HW;
-			skb->csum = le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0xffff;
-			printk(KERN_DEBUG "%s: checksum_hw, status2 = %x\n", dev->name, np->rx_done_q[np->rx_done].status2);
+			skb->csum = le16_to_cpu(desc->csum);
+			printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2));
 		}
-#endif
-		netif_rx(skb);
+#endif /* HAS_FIRMWARE */
+#ifdef VLAN_SUPPORT
+		if (np->vlgrp && le16_to_cpu(desc->status2) & 0x0200) {
+			if (debug > 4)
+				printk(KERN_DEBUG "  netdev_rx() vlanid = %d\n", le16_to_cpu(desc->vlanid));
+			/* vlan_netdev_receive_skb() expects a packet with the VLAN tag stripped out */
+			vlan_netdev_receive_skb(skb, np->vlgrp, le16_to_cpu(desc->vlanid) & VLAN_VID_MASK);
+		} else
+#endif /* VLAN_SUPPORT */
+			netdev_receive_skb(skb);
 		dev->last_rx = jiffies;
 		np->stats.rx_packets++;
 
-next_rx:
+	next_rx:
 		np->cur_rx++;
-		np->rx_done_q[np->rx_done].status = 0;
-		np->rx_done = (np->rx_done + 1) & (DONE_Q_SIZE-1);
+		desc->status = 0;
+		np->rx_done = (np->rx_done + 1) % DONE_Q_SIZE;
 	}
 	writew(np->rx_done, dev->base_addr + CompletionQConsumerIdx);
 
+ out:
+	refill_rx_ring(dev);
+	if (debug > 5)
+		printk(KERN_DEBUG "  exiting netdev_rx(): %d, status of %d was %#8.8x.\n",
+		       retcode, np->rx_done, desc_status);
+	return retcode;
+}
+
+
+#ifdef HAVE_NETDEV_POLL
+static int netdev_poll(struct net_device *dev, int *budget)
+{
+	u32 intr_status;
+	long ioaddr = dev->base_addr;
+	int retcode = 0, quota = dev->quota;
+
+	do {
+		writel(IntrRxDone | IntrRxEmpty, ioaddr + IntrClear);
+
+		retcode = __netdev_rx(dev, &quota);
+		*budget -= (dev->quota - quota);
+		dev->quota = quota;
+		if (retcode)
+			goto out;
+
+		intr_status = readl(ioaddr + IntrStatus);
+	} while (intr_status & (IntrRxDone | IntrRxEmpty));
+
+	netif_rx_complete(dev);
+	intr_status = readl(ioaddr + IntrEnable);
+	intr_status |= IntrRxDone | IntrRxEmpty;
+	writel(intr_status, ioaddr + IntrEnable);
+
+ out:
+	if (debug > 5)
+		printk(KERN_DEBUG "  exiting netdev_poll(): %d.\n", retcode);
+
+	/* Restart Rx engine if stopped. */
+	return retcode;
+}
+#endif /* HAVE_NETDEV_POLL */
+
+
+static void refill_rx_ring(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+	struct sk_buff *skb;
+	int entry = -1;
+
 	/* Refill the Rx ring buffers. */
 	for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) {
-		struct sk_buff *skb;
-		int entry = np->dirty_rx % RX_RING_SIZE;
+		entry = np->dirty_rx % RX_RING_SIZE;
 		if (np->rx_info[entry].skb == NULL) {
 			skb = dev_alloc_skb(np->rx_buf_sz);
 			np->rx_info[entry].skb = skb;
@@ -1527,20 +1766,13 @@
 				pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 			skb->dev = dev;	/* Mark as being used by this device. */
 			np->rx_ring[entry].rxaddr =
-				cpu_to_le32(np->rx_info[entry].mapping | RxDescValid);
+				cpu_to_dma(np->rx_info[entry].mapping | RxDescValid);
 		}
 		if (entry == RX_RING_SIZE - 1)
-			np->rx_ring[entry].rxaddr |= cpu_to_le32(RxDescEndRing);
-		/* We could defer this until later... */
-		writew(entry, dev->base_addr + RxDescQIdx);
+			np->rx_ring[entry].rxaddr |= cpu_to_dma(RxDescEndRing);
 	}
-
-	if (debug > 5)
-		printk(KERN_DEBUG "  exiting netdev_rx() status of %d was %8.8x.\n",
-		       np->rx_done, desc_status);
-
-	/* Restart Rx engine if stopped. */
-	return 0;
+	if (entry >= 0)
+		writew(entry, dev->base_addr + RxDescQIdx);
 }
 
 
@@ -1550,6 +1782,7 @@
 	long ioaddr = dev->base_addr;
 	u16 reg0, reg1, reg4, reg5;
 	u32 new_tx_mode;
+	u32 new_intr_timer_ctrl;
 
 	/* reset status first */
 	mdio_read(dev, np->phys[0], MII_BMCR);
@@ -1594,15 +1827,23 @@
 		       np->speed100 ? "100" : "10",
 		       np->mii_if.full_duplex ? "full" : "half");
 
-		new_tx_mode = np->tx_mode & ~0x2;	/* duplex setting */
+		new_tx_mode = np->tx_mode & ~FullDuplex;	/* duplex setting */
 		if (np->mii_if.full_duplex)
-			new_tx_mode |= 2;
+			new_tx_mode |= FullDuplex;
 		if (np->tx_mode != new_tx_mode) {
 			np->tx_mode = new_tx_mode;
-			writel(np->tx_mode | 0x8000, ioaddr + TxMode);
+			writel(np->tx_mode | MiiSoftReset, ioaddr + TxMode);
 			udelay(1000);
 			writel(np->tx_mode, ioaddr + TxMode);
 		}
+
+		new_intr_timer_ctrl = np->intr_timer_ctrl & ~Timer10X;
+		if (np->speed100)
+			new_intr_timer_ctrl |= Timer10X;
+		if (np->intr_timer_ctrl != new_intr_timer_ctrl) {
+			np->intr_timer_ctrl = new_intr_timer_ctrl;
+			writel(new_intr_timer_ctrl, ioaddr + IntrTimerCtrl);
+		}
 	} else {
 		netif_carrier_off(dev);
 		printk(KERN_DEBUG "%s: Link is down\n", dev->name);
@@ -1616,9 +1857,12 @@
 
 	/* Came close to underrunning the Tx FIFO, increase threshold. */
 	if (intr_status & IntrTxDataLow) {
-		writel(++np->tx_threshold, dev->base_addr + TxThreshold);
-		printk(KERN_NOTICE "%s: Increasing Tx FIFO threshold to %d bytes\n",
-		       dev->name, np->tx_threshold * 16);
+		if (np->tx_threshold <= PKT_BUF_SZ / 16) {
+			writel(++np->tx_threshold, dev->base_addr + TxThreshold);
+			printk(KERN_NOTICE "%s: PCI bus congestion, increasing Tx FIFO threshold to %d bytes\n",
+			       dev->name, np->tx_threshold * 16);
+		} else
+			printk(KERN_WARNING "%s: PCI Tx underflow -- adapter is probably malfunctioning\n", dev->name);
 	}
 	if (intr_status & IntrRxGFPDead) {
 		np->stats.rx_fifo_errors++;
@@ -1629,7 +1873,7 @@
 		np->stats.tx_errors++;
 	}
 	if ((intr_status & ~(IntrNormalMask | IntrAbnormalSummary | IntrLinkChange | IntrStatsMax | IntrTxDataLow | IntrRxGFPDead | IntrNoTxCsum | IntrPCIPad)) && debug)
-		printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
+		printk(KERN_ERR "%s: Something Wicked happened! %#8.8x.\n",
 		       dev->name, intr_status);
 }
 
@@ -1664,39 +1908,67 @@
 /* Chips may use the upper or lower CRC bits, and may reverse and/or invert
    them.  Select the endian-ness that results in minimal calculations.
 */
-
 static void set_rx_mode(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
-	u32 rx_mode;
+	u32 rx_mode = MinVLANPrio;
 	struct dev_mc_list *mclist;
 	int i;
+#ifdef VLAN_SUPPORT
+	struct netdev_private *np = dev->priv;
+
+	rx_mode |= VlanMode;
+	if (np->vlgrp) {
+		int vlan_count = 0;
+		long filter_addr = ioaddr + HashTable + 8;
+		for (i = 0; i < VLAN_VID_MASK; i++) {
+			if (np->vlgrp->vlan_devices[i]) {
+				if (vlan_count >= 32)
+					break;
+				writew(cpu_to_be16(i), filter_addr);
+				filter_addr += 16;
+				vlan_count++;
+			}
+		}
+		if (i == VLAN_VID_MASK) {
+			rx_mode |= PerfectFilterVlan;
+			while (vlan_count < 32) {
+				writew(0, filter_addr);
+				filter_addr += 16;
+				vlan_count++;
+			}
+		}
+	}
+#endif /* VLAN_SUPPORT */
 
 	if (dev->flags & IFF_PROMISC) {	/* Set promiscuous. */
-		rx_mode = AcceptBroadcast|AcceptAllMulticast|AcceptAll|AcceptMyPhys;
+		rx_mode |= AcceptAll;
 	} else if ((dev->mc_count > multicast_filter_limit)
 		   || (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
-		rx_mode = AcceptBroadcast|AcceptAllMulticast|AcceptMyPhys;
-	} else if (dev->mc_count <= 15) {
-		/* Use the 16 element perfect filter, skip first entry. */
-		long filter_addr = ioaddr + PerfFilterTable + 1 * 16;
-		for (i = 1, mclist = dev->mc_list; mclist && i <= dev->mc_count;
+		rx_mode |= AcceptBroadcast|AcceptAllMulticast|PerfectFilter;
+	} else if (dev->mc_count <= 14) {
+		/* Use the 16 element perfect filter, skip first two entries. */
+		long filter_addr = ioaddr + PerfFilterTable + 2 * 16;
+		u16 *eaddrs;
+		for (i = 2, mclist = dev->mc_list; mclist && i < dev->mc_count + 2;
 		     i++, mclist = mclist->next) {
-			u16 *eaddrs = (u16 *)mclist->dmi_addr;
+			eaddrs = (u16 *)mclist->dmi_addr;
 			writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 4;
 			writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4;
 			writew(cpu_to_be16(eaddrs[0]), filter_addr); filter_addr += 8;
 		}
+		eaddrs = (u16 *)dev->dev_addr;
 		while (i++ < 16) {
-			writew(0xffff, filter_addr); filter_addr += 4;
-			writew(0xffff, filter_addr); filter_addr += 4;
-			writew(0xffff, filter_addr); filter_addr += 8;
+			writew(cpu_to_be16(eaddrs[0]), filter_addr); filter_addr += 4;
+			writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4;
+			writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 8;
 		}
-		rx_mode = AcceptBroadcast | AcceptMyPhys;
+		rx_mode |= AcceptBroadcast|PerfectFilter;
 	} else {
 		/* Must use a multicast hash table. */
 		long filter_addr;
+		u16 *eaddrs;
 		u16 mc_filter[32] __attribute__ ((aligned(sizeof(long))));	/* Multicast hash filter */
 
 		memset(mc_filter, 0, sizeof(mc_filter));
@@ -1707,16 +1979,17 @@
 
 			*fptr |= cpu_to_le32(1 << (bit_nr & 31));
 		}
-		/* Clear the perfect filter list, skip first entry. */
-		filter_addr = ioaddr + PerfFilterTable + 1 * 16;
-		for (i = 1; i < 16; i++) {
-			writew(0xffff, filter_addr); filter_addr += 4;
-			writew(0xffff, filter_addr); filter_addr += 4;
-			writew(0xffff, filter_addr); filter_addr += 8;
+		/* Clear the perfect filter list, skip first two entries. */
+		filter_addr = ioaddr + PerfFilterTable + 2 * 16;
+		eaddrs = (u16 *)dev->dev_addr;
+		for (i = 2; i < 16; i++) {
+			writew(cpu_to_be16(eaddrs[0]), filter_addr); filter_addr += 4;
+			writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4;
+			writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 8;
 		}
-		for (filter_addr = ioaddr + HashTable, i=0; i < 32; filter_addr+= 16, i++)
+		for (filter_addr = ioaddr + HashTable, i = 0; i < 32; filter_addr+= 16, i++)
 			writew(mc_filter[i], filter_addr);
-		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+		rx_mode |= AcceptBroadcast|PerfectFilter|HashFilter;
 	}
 	writel(rx_mode, ioaddr + RxFilterMode);
 }
@@ -1763,6 +2036,7 @@
 		spin_lock_irq(&np->lock);
 		r = mii_ethtool_sset(&np->mii_if, &ecmd);
 		spin_unlock_irq(&np->lock);
+		check_duplex(dev);
 		return r;
 	}
 	/* restart autonegotiation */
@@ -1816,7 +2090,7 @@
 		spin_lock_irq(&np->lock);
 		rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL);
 		spin_unlock_irq(&np->lock);
-		
+
 		if ((cmd == SIOCSMIIREG) && (data->phy_id == np->phys[0]))
 			check_duplex(dev);
 	}
@@ -1834,41 +2108,42 @@
 	netif_stop_if(dev);
 
 	if (debug > 1) {
-		printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %4.4x.\n",
-			   dev->name, (int)readl(ioaddr + IntrStatus));
-		printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d,  Rx %d / %d.\n",
-			   dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx);
+		printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %#8.8x.\n",
+			   dev->name, (int) readl(ioaddr + IntrStatus));
+		printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n",
+		       dev->name, np->cur_tx, np->dirty_tx,
+		       np->cur_rx, np->dirty_rx);
 	}
 
 	/* Disable interrupts by clearing the interrupt mask. */
 	writel(0, ioaddr + IntrEnable);
 
 	/* Stop the chip's Tx and Rx processes. */
+	writel(0, ioaddr + GenCtrl);
+	readl(ioaddr + GenCtrl);
 
-#ifdef __i386__
-	if (debug > 2) {
-		printk("\n"KERN_DEBUG"  Tx ring at %9.9Lx:\n",
-			   (u64) np->tx_ring_dma);
+	if (debug > 5) {
+		printk(KERN_DEBUG"  Tx ring at %#llx:\n",
+		       (long long) np->tx_ring_dma);
 		for (i = 0; i < 8 /* TX_RING_SIZE is huge! */; i++)
-			printk(KERN_DEBUG " #%d desc. %8.8x %8.8x -> %8.8x.\n",
+			printk(KERN_DEBUG " #%d desc. %#8.8x %#llx -> %#8.8x.\n",
 			       i, le32_to_cpu(np->tx_ring[i].status),
-			       le32_to_cpu(np->tx_ring[i].first_addr),
+			       (long long) dma_to_cpu(np->tx_ring[i].addr),
 			       le32_to_cpu(np->tx_done_q[i].status));
-		printk(KERN_DEBUG "  Rx ring at %9.9Lx -> %p:\n",
-		       (u64) np->rx_ring_dma, np->rx_done_q);
+		printk(KERN_DEBUG "  Rx ring at %#llx -> %p:\n",
+		       (long long) np->rx_ring_dma, np->rx_done_q);
 		if (np->rx_done_q)
 			for (i = 0; i < 8 /* RX_RING_SIZE */; i++) {
-				printk(KERN_DEBUG " #%d desc. %8.8x -> %8.8x\n",
-				       i, le32_to_cpu(np->rx_ring[i].rxaddr), le32_to_cpu(np->rx_done_q[i].status));
+				printk(KERN_DEBUG " #%d desc. %#llx -> %#8.8x\n",
+				       i, (long long) dma_to_cpu(np->rx_ring[i].rxaddr), le32_to_cpu(np->rx_done_q[i].status));
 		}
 	}
-#endif /* __i386__ debugging only */
 
 	free_irq(dev->irq, dev);
 
 	/* Free all the skbuffs in the Rx queue. */
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		np->rx_ring[i].rxaddr = cpu_to_le32(0xBADF00D0); /* An invalid address. */
+		np->rx_ring[i].rxaddr = cpu_to_dma(0xBADF00D0); /* An invalid address. */
 		if (np->rx_info[i].skb != NULL) {
 			pci_unmap_single(np->pci_dev, np->rx_info[i].mapping, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 			dev_kfree_skb(np->rx_info[i].skb);
@@ -1878,28 +2153,14 @@
 	}
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		struct sk_buff *skb = np->tx_info[i].skb;
-#ifdef ZEROCOPY
-		int j;
-#endif /* ZEROCOPY */
 		if (skb == NULL)
 			continue;
 		pci_unmap_single(np->pci_dev,
-				 np->tx_info[i].first_mapping,
+				 np->tx_info[i].mapping,
 				 skb_first_frag_len(skb), PCI_DMA_TODEVICE);
-		np->tx_info[i].first_mapping = 0;
+		np->tx_info[i].mapping = 0;
 		dev_kfree_skb(skb);
 		np->tx_info[i].skb = NULL;
-#ifdef ZEROCOPY
-		for (j = 0; j < MAX_STARFIRE_FRAGS; j++)
-			if (np->tx_info[i].frag_mapping[j]) {
-				pci_unmap_single(np->pci_dev,
-						 np->tx_info[i].frag_mapping[j],
-						 skb_shinfo(skb)->frags[j].size,
-						 PCI_DMA_TODEVICE);
-				np->tx_info[i].frag_mapping[j] = 0;
-			} else
-				break;
-#endif /* ZEROCOPY */
 	}
 
 	COMPAT_MOD_DEC_USE_COUNT;
@@ -1917,21 +2178,15 @@
 		BUG();
 
 	np = dev->priv;
-	if (np->tx_done_q)
-		pci_free_consistent(pdev, PAGE_SIZE,
-				    np->tx_done_q, np->tx_done_q_dma);
-	if (np->rx_done_q)
-		pci_free_consistent(pdev,
-				    sizeof(struct rx_done_desc) * DONE_Q_SIZE,
-				    np->rx_done_q, np->rx_done_q_dma);
-	if (np->tx_ring)
-		pci_free_consistent(pdev, PAGE_SIZE,
-				    np->tx_ring, np->tx_ring_dma);
-	if (np->rx_ring)
-		pci_free_consistent(pdev, PAGE_SIZE,
-				    np->rx_ring, np->rx_ring_dma);
+	if (np->queue_mem)
+		pci_free_consistent(pdev, np->queue_mem_size, np->queue_mem, np->queue_mem_dma);
 
 	unregister_netdev(dev);
+
+	/* XXX: add wakeup code -- requires firmware for MagicPacket */
+	pci_set_power_state(pdev, 3);	/* go to sleep in D3 mode */
+	pci_disable_device(pdev);
+
 	iounmap((char *)dev->base_addr);
 	pci_release_regions(pdev);
 
@@ -1954,6 +2209,17 @@
 #ifdef MODULE
 	printk(version);
 #endif
+#ifndef ADDR_64BITS
+	/* we can do this test only at run-time... sigh */
+	if (sizeof(dma_addr_t) == sizeof(u64)) {
+		printk("This driver has not been ported to this 64-bit architecture yet\n");
+		return -ENODEV;
+	}
+#endif /* not ADDR_64BITS */
+#ifndef HAS_FIRMWARE
+	/* unconditionally disable hw cksums if firmware is not present */
+	enable_hw_cksum = 0;
+#endif /* not HAS_FIRMWARE */
 	return pci_module_init (&starfire_driver);
 }
 
@@ -1970,8 +2236,6 @@
 
 /*
  * Local variables:
- *  compile-command: "gcc -DMODULE -Wall -Wstrict-prototypes -O2 -c starfire.c"
- *  simple-compile-command: "gcc -DMODULE -O2 -c starfire.c"
  *  c-basic-offset: 8
  *  tab-width: 8
  * End:
diff -Nru a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
--- a/drivers/net/sunbmac.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/net/sunbmac.c	Fri Feb 14 15:53:10 2003
@@ -1033,8 +1033,9 @@
 	sbus_writel(tmp, bregs + BMAC_RXCFG);
 }
 
-static int __init bigmac_ether_init(struct net_device *dev, struct sbus_dev *qec_sdev)
+static int __init bigmac_ether_init(struct sbus_dev *qec_sdev)
 {
+	struct net_device *dev;
 	static int version_printed;
 	struct bigmac *bp;
 	u8 bsizes, bsizes_more;
@@ -1049,9 +1050,6 @@
 	if (version_printed++ == 0)
 		printk(KERN_INFO "%s", version);
 
-	if (!dev)
-		return -ENOMEM;
-
 	/* Report what we have found to the user. */
 	printk(KERN_INFO "%s: BigMAC 100baseT Ethernet ", dev->name);
 	dev->base_addr = (long) qec_sdev;
@@ -1180,7 +1178,6 @@
 	/* Finish net device registration. */
 	dev->irq = bp->bigmac_sdev->irqs[0];
 	dev->dma = 0;
-	ether_setup(dev);
 
 	/* Put us into the list of instances attached for later driver
 	 * exit.
@@ -1235,7 +1232,6 @@
 
 static int __init bigmac_probe(void)
 {
-	struct net_device *dev = NULL;
 	struct sbus_bus *sbus;
 	struct sbus_dev *sdev = 0;
 	static int called;
@@ -1249,12 +1245,9 @@
 
 	for_each_sbus(sbus) {
 		for_each_sbusdev(sdev, sbus) {
-			if (cards)
-				dev = NULL;
-
 			if (bigmac_match(sdev)) {
 				cards++;
-				if ((v = bigmac_ether_init(dev, sdev)))
+				if ((v = bigmac_ether_init(sdev)))
 					return v;
 			}
 		}
diff -Nru a/drivers/net/sungem.c b/drivers/net/sungem.c
--- a/drivers/net/sungem.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/net/sungem.c	Fri Feb 14 15:53:12 2003
@@ -397,6 +397,10 @@
 			gp->dev->name, rxmac_stat);
 
 	if (rxmac_stat & MAC_RXSTAT_OFLW) {
+		u32 smac = readl(gp->regs + MAC_SMACHINE);
+
+		printk(KERN_ERR "%s: RX MAC fifo overflow smac[%08x].\n",
+				dev->name, smac);
 		gp->net_stats.rx_over_errors++;
 		gp->net_stats.rx_fifo_errors++;
 
diff -Nru a/drivers/net/sunqe.c b/drivers/net/sunqe.c
--- a/drivers/net/sunqe.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/net/sunqe.c	Fri Feb 14 15:53:09 2003
@@ -924,7 +924,6 @@
 							     sizeof(struct sunqe_buffers),
 							     qe->buffers,
 							     qe->buffers_dvma);
-				kfree(qe_devs[i]->priv);
 			}
 			kfree(qe_devs[i]);
 		}
diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c
--- a/drivers/net/tg3.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/net/tg3.c	Fri Feb 14 15:53:10 2003
@@ -6479,8 +6479,11 @@
 	}
 #endif
 
-	/* Remove this if it causes problems for some boards. */
-	tp->dma_rwctrl |= DMA_RWCTRL_USE_MEM_READ_MULT;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
+		/* Remove this if it causes problems for some boards. */
+		tp->dma_rwctrl |= DMA_RWCTRL_USE_MEM_READ_MULT;
+	}
 
 	tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
 
diff -Nru a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig
--- a/drivers/net/tokenring/Kconfig	Fri Feb 14 15:53:09 2003
+++ b/drivers/net/tokenring/Kconfig	Fri Feb 14 15:53:09 2003
@@ -131,18 +131,33 @@
 	  The module will be called tmspci. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
-config TMSISA
-	tristate "Generic TMS380 ISA support"
+config SKISA
+	tristate "SysKonnect TR4/16 ISA support"
 	depends on TR && TMS380TR!=n && ISA
 	help
-	  This tms380 module supports generic TMS380-based ISA cards.
+	  This tms380 module supports SysKonnect TR4/16 ISA cards.
 
 	  These cards are known to work:
 	  - SysKonnect TR4/16 ISA (SK-4190)
 
 	  This driver is available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called tmsisa. If you want to compile it
+	  The module will be called skisa. If you want to compile it
+	  as a module, say M here and read <file:Documentation/modules.txt>.
+
+config PROTEON
+	tristate "Proteon ISA support"
+	depends on TR && TMS380TR!=n && ISA
+	help
+	  This tms380 module supports Proteon ISA cards.
+
+	  These cards are known to work:
+	  - Proteon 1392
+	  - Proteon 1392 plus
+
+	  This driver is available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called proteon. If you want to compile it
 	  as a module, say M here and read <file:Documentation/modules.txt>.
 
 config ABYSS
diff -Nru a/drivers/net/tokenring/Makefile b/drivers/net/tokenring/Makefile
--- a/drivers/net/tokenring/Makefile	Fri Feb 14 15:53:09 2003
+++ b/drivers/net/tokenring/Makefile	Fri Feb 14 15:53:09 2003
@@ -8,7 +8,8 @@
 obj-$(CONFIG_TMS380TR) 	+= tms380tr.o
 obj-$(CONFIG_ABYSS) 	+= abyss.o
 obj-$(CONFIG_MADGEMC) 	+= madgemc.o
+obj-$(CONFIG_PROTEON) 	+= proteon.o
 obj-$(CONFIG_TMSPCI) 	+= tmspci.o
-obj-$(CONFIG_TMSISA) 	+= tmsisa.o
+obj-$(CONFIG_SKISA) 	+= skisa.o
 obj-$(CONFIG_SMCTR) 	+= smctr.o
 obj-$(CONFIG_3C359)	+= 3c359.o
diff -Nru a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
--- a/drivers/net/tokenring/madgemc.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/net/tokenring/madgemc.c	Fri Feb 14 15:53:12 2003
@@ -163,7 +163,7 @@
 
 	if (!MCA_bus)
 		return -1;	
-       
+ 
 	while (slot != MCA_NOTFOUND) {
 		/*
 		 * Currently we only support the MC16/32 (MCA ID 002d)
@@ -180,8 +180,11 @@
 
 		if ((dev = init_trdev(NULL, 0))==NULL) {
 			printk("madgemc: unable to allocate dev space\n");
+			if (madgemc_card_list)
+				return 0;
 			return -1;
 		}
+		SET_MODULE_OWNER(dev);
 		dev->dma = 0;
 
 		/*
@@ -193,6 +196,9 @@
 		card = kmalloc(sizeof(struct madgemc_card), GFP_KERNEL);
 		if (card==NULL) {
 			printk("madgemc: unable to allocate card struct\n");
+			kfree(dev); /* release_trdev? */
+			if (madgemc_card_list)
+				return 0;
 			return -1;
 		}
 		card->dev = dev;
@@ -223,14 +229,14 @@
 
 		if (dev->irq == 0) {
 			printk("%s: invalid IRQ\n", dev->name);
-			goto getout;
+			goto getout1;
 		}
 
 		if (!request_region(dev->base_addr, MADGEMC_IO_EXTENT, 
 				   "madgemc")) {
 			printk(KERN_INFO "madgemc: unable to setup Smart MC in slot %d because of I/O base conflict at 0x%04lx\n", slot, dev->base_addr);
 			dev->base_addr += MADGEMC_SIF_OFFSET;
-			goto getout;
+			goto getout1;
 		}
 		dev->base_addr += MADGEMC_SIF_OFFSET;
 		
@@ -348,6 +354,14 @@
 		if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL)) {
 			printk("%s: unable to get memory for dev->priv.\n", 
 			       dev->name);
+			release_region(dev->base_addr-MADGEMC_SIF_OFFSET, 
+			       MADGEMC_IO_EXTENT); 
+			
+			kfree(card);
+			tmsdev_term(dev);
+			kfree(dev);
+			if (madgemc_card_list)
+				return 0;
 			return -1;
 		}
 		tp = (struct net_local *)dev->priv;
@@ -376,10 +390,14 @@
 			madgemc_card_list = card;
 		} else {
 			printk("madgemc: register_trdev() returned non-zero.\n");
+			release_region(dev->base_addr-MADGEMC_SIF_OFFSET, 
+			       MADGEMC_IO_EXTENT); 
 			
 			kfree(card);
 			tmsdev_term(dev);
 			kfree(dev);
+			if (madgemc_card_list)
+				return 0;
 			return -1;
 		}
 
@@ -389,6 +407,7 @@
 	getout:
 		release_region(dev->base_addr-MADGEMC_SIF_OFFSET, 
 			       MADGEMC_IO_EXTENT); 
+	getout1:
 		kfree(card);
 		kfree(dev); /* release_trdev? */
 		slot++;
@@ -696,7 +715,6 @@
 	 */
 	madgemc_chipset_init(dev);
 	tms380tr_open(dev);
-	MOD_INC_USE_COUNT;
 	return 0;
 }
 
@@ -704,7 +722,6 @@
 {
 	tms380tr_close(dev);
 	madgemc_chipset_close(dev);
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
diff -Nru a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/tokenring/proteon.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,503 @@
+/*
+ *  proteon.c: A network driver for Proteon ISA token ring cards.
+ *
+ *  Based on tmspci written 1999 by Adam Fritzler
+ *  
+ *  Written 2003 by Jochen Friedrich
+ *
+ *  This software may be used and distributed according to the terms
+ *  of the GNU General Public License, incorporated herein by reference.
+ *
+ *  This driver module supports the following cards:
+ *	- Proteon 1392, 1392+
+ *
+ *  Maintainer(s):
+ *    AF        Adam Fritzler           mid@auk.cx
+ *    JF	Jochen Friedrich	jochen@scram.de
+ *
+ *  Modification History:
+ *	02-Jan-03	JF	Created
+ *
+ */
+static const char version[] = "proteon.c: v1.00 02/01/2003 by Jochen Friedrich\n";
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/trdevice.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/dma.h>
+
+#include "tms380tr.h"
+
+#define PROTEON_IO_EXTENT 32
+
+/* A zero-terminated list of I/O addresses to be probed. */
+static unsigned int portlist[] __initdata = {
+	0x0A20, 0x0E20, 0x1A20, 0x1E20, 0x2A20, 0x2E20, 0x3A20, 0x3E20,// Prot.
+	0x4A20, 0x4E20, 0x5A20, 0x5E20, 0x6A20, 0x6E20, 0x7A20, 0x7E20,// Prot.
+	0x8A20, 0x8E20, 0x9A20, 0x9E20, 0xAA20, 0xAE20, 0xBA20, 0xBE20,// Prot.
+	0xCA20, 0xCE20, 0xDA20, 0xDE20, 0xEA20, 0xEE20, 0xFA20, 0xFE20,// Prot.
+	0
+};
+
+/* A zero-terminated list of IRQs to be probed. */
+static unsigned short irqlist[] = {
+	7, 6, 5, 4, 3, 12, 11, 10, 9,
+	0
+};
+
+/* A zero-terminated list of DMAs to be probed. */
+static int dmalist[] __initdata = {
+	5, 6, 7,
+	0
+};
+
+static char cardname[] = "Proteon 1392\0";
+
+int proteon_probe(struct net_device *dev);
+static int proteon_open(struct net_device *dev);
+static int proteon_close(struct net_device *dev);
+static void proteon_read_eeprom(struct net_device *dev);
+static unsigned short proteon_setnselout_pins(struct net_device *dev);
+
+static unsigned short proteon_sifreadb(struct net_device *dev, unsigned short reg)
+{
+	return inb(dev->base_addr + reg);
+}
+
+static unsigned short proteon_sifreadw(struct net_device *dev, unsigned short reg)
+{
+	return inw(dev->base_addr + reg);
+}
+
+static void proteon_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
+{
+	outb(val, dev->base_addr + reg);
+}
+
+static void proteon_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
+{
+	outw(val, dev->base_addr + reg);
+}
+
+struct proteon_card {
+	struct net_device *dev;
+	struct proteon_card *next;
+};
+
+static struct proteon_card *proteon_card_list;
+
+static int __init proteon_probe1(int ioaddr)
+{
+	unsigned char chk1, chk2;
+	int i;
+
+	chk1 = inb(ioaddr + 0x1f);      /* Get Proteon ID reg 1 */
+	if (chk1 != 0x1f)
+		return (-1);
+	chk1 = inb(ioaddr + 0x1e) & 0x07;       /* Get Proteon ID reg 0 */
+	for (i=0; i<16; i++) {
+		chk2 = inb(ioaddr + 0x1e) & 0x07;
+		if (((chk1 + 1) & 0x07) != chk2)
+			return (-1);
+		chk1 = chk2;
+	}
+	return (0);
+}
+
+int __init proteon_probe(struct net_device *dev)
+{
+        static int versionprinted;
+	struct net_local *tp;
+	int i,j;
+	struct proteon_card *card;
+
+	SET_MODULE_OWNER(dev);
+	if (!dev->base_addr)
+	{
+		for(i = 0; portlist[i]; i++)
+		{
+			if (!request_region(portlist[i], PROTEON_IO_EXTENT, cardname))
+				continue;
+
+			if(proteon_probe1(portlist[i]))
+			{
+				release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+				continue;
+			}
+
+			dev->base_addr = portlist[i];
+			break;
+		}
+		if(!dev->base_addr)
+			return -1;
+	}
+	else
+	{
+		if (!request_region(dev->base_addr, PROTEON_IO_EXTENT, cardname))
+			return -1;
+
+		if(proteon_probe1(dev->base_addr))
+		{
+			release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+			return -1;
+  		}
+	} 
+
+	/* At this point we have found a valid card. */
+
+	if (versionprinted++ == 0)
+		printk(KERN_DEBUG "%s", version);
+
+#ifndef MODULE
+	dev = init_trdev(dev, 0);
+	if (!dev)
+	{
+		release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+		return -1;
+	}
+#endif
+
+	if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL))
+       	{
+		release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+		return -1;
+	}
+
+	dev->base_addr &= ~3; 
+		
+	proteon_read_eeprom(dev);
+
+	printk(KERN_DEBUG "%s:    Ring Station Address: ", dev->name);
+	printk("%2.2x", dev->dev_addr[0]);
+	for (j = 1; j < 6; j++)
+		printk(":%2.2x", dev->dev_addr[j]);
+	printk("\n");
+		
+	tp = (struct net_local *)dev->priv;
+	tp->setnselout = proteon_setnselout_pins;
+		
+	tp->sifreadb = proteon_sifreadb;
+	tp->sifreadw = proteon_sifreadw;
+	tp->sifwriteb = proteon_sifwriteb;
+	tp->sifwritew = proteon_sifwritew;
+	
+	memcpy(tp->ProductID, cardname, PROD_ID_SIZE + 1);
+
+	tp->tmspriv = NULL;
+
+	dev->open = proteon_open;
+	dev->stop = proteon_close;
+
+	if (dev->irq == 0)
+	{
+		for(j = 0; irqlist[j] != 0; j++)
+		{
+			dev->irq = irqlist[j];
+			if (!request_irq(dev->irq, tms380tr_interrupt, 0, 
+				cardname, dev))
+				break;
+                }
+		
+                if(irqlist[j] == 0)
+                {
+                        printk(KERN_INFO "%s: AutoSelect no IRQ available\n", dev->name);
+			release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+			tmsdev_term(dev);
+			return -1;
+		}
+	}
+	else
+	{
+		for(j = 0; irqlist[j] != 0; j++)
+			if (irqlist[j] == dev->irq)
+				break;
+		if (irqlist[j] == 0)
+		{
+			printk(KERN_INFO "%s: Illegal IRQ %d specified\n",
+				dev->name, dev->irq);
+			release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+			tmsdev_term(dev);
+			return -1;
+		}
+		if (request_irq(dev->irq, tms380tr_interrupt, 0, 
+			cardname, dev))
+		{
+                        printk(KERN_INFO "%s: Selected IRQ %d not available\n", 
+				dev->name, dev->irq);
+			release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+			tmsdev_term(dev);
+			return -1;
+		}
+	}
+
+	if (dev->dma == 0)
+	{
+		for(j = 0; dmalist[j] != 0; j++)
+		{
+			dev->dma = dmalist[j];
+                        if (!request_dma(dev->dma, cardname))
+				break;
+		}
+
+		if(dmalist[j] == 0)
+		{
+			printk(KERN_INFO "%s: AutoSelect no DMA available\n", dev->name);
+			release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+			free_irq(dev->irq, dev);
+			tmsdev_term(dev);
+			return -1;
+		}
+	}
+	else
+	{
+		for(j = 0; dmalist[j] != 0; j++)
+			if (dmalist[j] == dev->dma)
+				break;
+		if (dmalist[j] == 0)
+		{
+                        printk(KERN_INFO "%s: Illegal DMA %d specified\n", 
+				dev->name, dev->dma);
+			release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+			free_irq(dev->irq, dev);
+			tmsdev_term(dev);
+			return -1;
+		}
+		if (request_dma(dev->dma, cardname))
+		{
+                        printk(KERN_INFO "%s: Selected DMA %d not available\n", 
+				dev->name, dev->dma);
+			release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+			free_irq(dev->irq, dev);
+			tmsdev_term(dev);
+			return -1;
+		}
+	}
+
+	printk(KERN_DEBUG "%s:    IO: %#4lx  IRQ: %d  DMA: %d\n",
+	       dev->name, dev->base_addr, dev->irq, dev->dma);
+		
+	if (register_trdev(dev) == 0) 
+	{
+		/* Enlist in the card list */
+		card = kmalloc(sizeof(struct proteon_card), GFP_KERNEL);
+		if (!card) {
+			unregister_trdev(dev);
+			release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+			free_irq(dev->irq, dev);
+			free_dma(dev->dma);
+			tmsdev_term(dev);
+			return -1;
+		}
+		card->next = proteon_card_list;
+		proteon_card_list = card;
+		card->dev = dev;
+	} 
+	else 
+	{
+		printk("KERN_INFO %s: register_trdev() returned non-zero.\n", dev->name);
+		release_region(dev->base_addr, PROTEON_IO_EXTENT); 
+		free_irq(dev->irq, dev);
+		free_dma(dev->dma);
+		tmsdev_term(dev);
+		return -1;
+	}
+	
+	return 0;
+}
+
+/*
+ * Reads MAC address from adapter RAM, which should've read it from
+ * the onboard ROM.  
+ *
+ * Calling this on a board that does not support it can be a very
+ * dangerous thing.  The Madge board, for instance, will lock your
+ * machine hard when this is called.  Luckily, its supported in a
+ * seperate driver.  --ASF
+ */
+static void proteon_read_eeprom(struct net_device *dev)
+{
+	int i;
+	
+	/* Address: 0000:0000 */
+	proteon_sifwritew(dev, 0, SIFADX);
+	proteon_sifwritew(dev, 0, SIFADR);	
+	
+	/* Read six byte MAC address data */
+	dev->addr_len = 6;
+	for(i = 0; i < 6; i++)
+		dev->dev_addr[i] = proteon_sifreadw(dev, SIFINC) >> 8;
+}
+
+unsigned short proteon_setnselout_pins(struct net_device *dev)
+{
+	return 0;
+}
+
+static int proteon_open(struct net_device *dev)
+{  
+	struct net_local *tp = (struct net_local *)dev->priv;
+	unsigned short val = 0;
+	int i;
+
+	/* Proteon reset sequence */
+	outb(0, dev->base_addr + 0x11);
+	mdelay(20);
+	outb(0x04, dev->base_addr + 0x11);
+	mdelay(20);
+	outb(0, dev->base_addr + 0x11);
+	mdelay(100);
+
+	/* set control/status reg */
+	val = inb(dev->base_addr + 0x11);
+	val |= 0x78;
+	val &= 0xf9;
+	if(tp->DataRate == SPEED_4)
+		val |= 0x20;
+	else
+		val &= ~0x20;
+
+	outb(val, dev->base_addr + 0x11);
+	outb(0xff, dev->base_addr + 0x12);
+	for(i = 0; irqlist[i] != 0; i++)
+	{
+		if(irqlist[i] == dev->irq)
+			break;
+	}
+	val = i;
+	i = (7 - dev->dma) << 4;
+	val |= i;
+	outb(val, dev->base_addr + 0x13);
+
+	tms380tr_open(dev);
+	return 0;
+}
+
+static int proteon_close(struct net_device *dev)
+{
+	tms380tr_close(dev);
+	return 0;
+}
+
+#ifdef MODULE
+
+#define ISATR_MAX_ADAPTERS 3
+
+static int io[ISATR_MAX_ADAPTERS];
+static int irq[ISATR_MAX_ADAPTERS];
+static int dma[ISATR_MAX_ADAPTERS];
+
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(io, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
+MODULE_PARM(dma, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
+
+int init_module(void)
+{
+	int i, num;
+	struct net_device *dev;
+
+	num = 0;
+	if (io[0]) 
+	{ /* Only probe addresses from command line */
+		dev = init_trdev(NULL, 0);
+		if (!dev)
+			return (-ENOMEM);
+		for (i = 0; i < ISATR_MAX_ADAPTERS; i++)
+	       	{
+			if (io[i] == 0)
+				continue;
+		
+			dev->base_addr = io[i];
+			dev->irq       = irq[i];
+			dev->dma       = dma[i];
+
+			if (!proteon_probe(dev))
+			{
+				num++;
+				dev = init_trdev(NULL, 0);
+				if (!dev)
+					goto partial;
+			}
+		}
+		unregister_netdev(dev);
+		kfree(dev);
+	}
+       	else
+       	{
+		dev = init_trdev(NULL, 0);
+		if (!dev)
+			return (-ENOMEM);
+
+		for(i = 0; portlist[i]; i++)
+		{
+			if (num >= ISATR_MAX_ADAPTERS)
+				continue;
+		
+			dev->base_addr = portlist[i];
+			dev->irq       = irq[num];
+			dev->dma       = dma[num];
+
+			if (!proteon_probe(dev))
+			{
+				num++;
+				dev = init_trdev(NULL, 0);
+				if (!dev)
+					goto partial;
+			}
+		}
+		unregister_netdev(dev);
+		kfree(dev);
+	}
+partial:
+	printk(KERN_NOTICE "proteon.c: %d cards found.\n", num);
+	/* Probe for cards. */
+	if (num == 0) {
+		printk(KERN_NOTICE "proteon.c: No cards found.\n");
+		return (-ENODEV);
+	}
+	return (0);
+}
+
+void cleanup_module(void)
+{
+	struct net_device *dev;
+	struct proteon_card *this_card;
+
+	while (proteon_card_list) {
+		dev = proteon_card_list->dev;
+		
+		unregister_netdev(dev);
+		release_region(dev->base_addr, PROTEON_IO_EXTENT);
+		free_irq(dev->irq, dev);
+		free_dma(dev->dma);
+		tmsdev_term(dev);
+		kfree(dev);
+		this_card = proteon_card_list;
+		proteon_card_list = this_card->next;
+		kfree(this_card);
+	}
+}
+#endif /* MODULE */
+
+
+/*
+ * Local variables:
+ *  compile-command: "gcc -DMODVERSIONS  -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c proteon.c"
+ *  alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c proteon.c"
+ *  c-set-style "K&R"
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -Nru a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/tokenring/skisa.c	Fri Feb 14 15:53:08 2003
@@ -0,0 +1,516 @@
+/*
+ *  skisa.c: A network driver for SK-NET TMS380-based ISA token ring cards.
+ *
+ *  Based on tmspci written 1999 by Adam Fritzler
+ *  
+ *  Written 2000 by Jochen Friedrich
+ *  Dedicated to my girlfriend Steffi Bopp
+ *
+ *  This software may be used and distributed according to the terms
+ *  of the GNU General Public License, incorporated herein by reference.
+ *
+ *  This driver module supports the following cards:
+ *	- SysKonnect TR4/16(+) ISA	(SK-4190)
+ *
+ *  Maintainer(s):
+ *    AF        Adam Fritzler           mid@auk.cx
+ *    JF	Jochen Friedrich	jochen@scram.de
+ *
+ *  Modification History:
+ *	14-Jan-01	JF	Created
+ *	28-Oct-02	JF	Fixed probe of card for static compilation.
+ *				Fixed module init to not make hotplug go wild.
+ *	09-Nov-02	JF	Fixed early bail out on out of memory
+ *				situations if multiple cards are found.
+ *				Cleaned up some unnecessary console SPAM.
+ *	09-Dec-02	JF	Fixed module reference counting.
+ *	02-Jan-03	JF	Renamed to skisa.c
+ *
+ */
+static const char version[] = "skisa.c: v1.03 09/12/2002 by Jochen Friedrich\n";
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/trdevice.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/dma.h>
+
+#include "tms380tr.h"
+
+#define SK_ISA_IO_EXTENT 32
+
+/* A zero-terminated list of I/O addresses to be probed. */
+static unsigned int portlist[] __initdata = {
+	0x0A20, 0x1A20, 0x0B20, 0x1B20, 0x0980, 0x1980, 0x0900, 0x1900,// SK
+	0
+};
+
+/* A zero-terminated list of IRQs to be probed. 
+ * Used again after initial probe for sktr_chipset_init, called from sktr_open.
+ */
+static unsigned short irqlist[] = {
+	3, 5, 9, 10, 11, 12, 15,
+	0
+};
+
+/* A zero-terminated list of DMAs to be probed. */
+static int dmalist[] __initdata = {
+	5, 6, 7,
+	0
+};
+
+static char isa_cardname[] = "SK NET TR 4/16 ISA\0";
+
+int sk_isa_probe(struct net_device *dev);
+static int sk_isa_open(struct net_device *dev);
+static int sk_isa_close(struct net_device *dev);
+static void sk_isa_read_eeprom(struct net_device *dev);
+static unsigned short sk_isa_setnselout_pins(struct net_device *dev);
+
+static unsigned short sk_isa_sifreadb(struct net_device *dev, unsigned short reg)
+{
+	return inb(dev->base_addr + reg);
+}
+
+static unsigned short sk_isa_sifreadw(struct net_device *dev, unsigned short reg)
+{
+	return inw(dev->base_addr + reg);
+}
+
+static void sk_isa_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
+{
+	outb(val, dev->base_addr + reg);
+}
+
+static void sk_isa_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
+{
+	outw(val, dev->base_addr + reg);
+}
+
+struct sk_isa_card {
+	struct net_device *dev;
+	struct sk_isa_card *next;
+};
+
+static struct sk_isa_card *sk_isa_card_list;
+
+static int __init sk_isa_probe1(int ioaddr)
+{
+	unsigned char old, chk1, chk2;
+
+	old = inb(ioaddr + SIFADR);	/* Get the old SIFADR value */
+
+	chk1 = 0;	/* Begin with check value 0 */
+	do {
+		/* Write new SIFADR value */
+		outb(chk1, ioaddr + SIFADR);
+
+		/* Read, invert and write */
+		chk2 = inb(ioaddr + SIFADD);
+		chk2 ^= 0x0FE;
+		outb(chk2, ioaddr + SIFADR);
+
+		/* Read, invert and compare */
+		chk2 = inb(ioaddr + SIFADD);
+		chk2 ^= 0x0FE;
+
+		if(chk1 != chk2)
+			return (-1);	/* No adapter */
+
+		chk1 -= 2;
+	} while(chk1 != 0);	/* Repeat 128 times (all byte values) */
+
+    	/* Restore the SIFADR value */
+	outb(old, ioaddr + SIFADR);
+
+	return (0);
+}
+
+int __init sk_isa_probe(struct net_device *dev)
+{
+        static int versionprinted;
+	struct net_local *tp;
+	int i,j;
+	struct sk_isa_card *card;
+
+	SET_MODULE_OWNER(dev);
+	if (!dev->base_addr)
+	{
+		for(i = 0; portlist[i]; i++)
+		{
+			if (!request_region(portlist[i], SK_ISA_IO_EXTENT, isa_cardname))
+				continue;
+
+			if(sk_isa_probe1(portlist[i]))
+			{
+				release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+				continue;
+			}
+
+			dev->base_addr = portlist[i];
+			break;
+		}
+		if(!dev->base_addr)
+			return -1;
+	}
+	else
+	{
+		if (!request_region(dev->base_addr, SK_ISA_IO_EXTENT, isa_cardname))
+			return -1;
+
+		if(sk_isa_probe1(dev->base_addr))
+		{
+			release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+			return -1;
+  		}
+	} 
+
+	/* At this point we have found a valid card. */
+
+	if (versionprinted++ == 0)
+		printk(KERN_DEBUG "%s", version);
+
+#ifndef MODULE
+	dev = init_trdev(dev, 0);
+	if (!dev)
+	{
+		release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+		return -1;
+	}
+#endif
+
+	if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL))
+       	{
+		release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+		return -1;
+	}
+
+	dev->base_addr &= ~3; 
+		
+	sk_isa_read_eeprom(dev);
+
+	printk(KERN_DEBUG "%s:    Ring Station Address: ", dev->name);
+	printk("%2.2x", dev->dev_addr[0]);
+	for (j = 1; j < 6; j++)
+		printk(":%2.2x", dev->dev_addr[j]);
+	printk("\n");
+		
+	tp = (struct net_local *)dev->priv;
+	tp->setnselout = sk_isa_setnselout_pins;
+		
+	tp->sifreadb = sk_isa_sifreadb;
+	tp->sifreadw = sk_isa_sifreadw;
+	tp->sifwriteb = sk_isa_sifwriteb;
+	tp->sifwritew = sk_isa_sifwritew;
+	
+	memcpy(tp->ProductID, isa_cardname, PROD_ID_SIZE + 1);
+
+	tp->tmspriv = NULL;
+
+	dev->open = sk_isa_open;
+	dev->stop = sk_isa_close;
+
+	if (dev->irq == 0)
+	{
+		for(j = 0; irqlist[j] != 0; j++)
+		{
+			dev->irq = irqlist[j];
+			if (!request_irq(dev->irq, tms380tr_interrupt, 0, 
+				isa_cardname, dev))
+				break;
+                }
+		
+                if(irqlist[j] == 0)
+                {
+                        printk(KERN_INFO "%s: AutoSelect no IRQ available\n", dev->name);
+			release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+			tmsdev_term(dev);
+			return -1;
+		}
+	}
+	else
+	{
+		for(j = 0; irqlist[j] != 0; j++)
+			if (irqlist[j] == dev->irq)
+				break;
+		if (irqlist[j] == 0)
+		{
+			printk(KERN_INFO "%s: Illegal IRQ %d specified\n",
+				dev->name, dev->irq);
+			release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+			tmsdev_term(dev);
+			return -1;
+		}
+		if (request_irq(dev->irq, tms380tr_interrupt, 0, 
+			isa_cardname, dev))
+		{
+                        printk(KERN_INFO "%s: Selected IRQ %d not available\n", 
+				dev->name, dev->irq);
+			release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+			tmsdev_term(dev);
+			return -1;
+		}
+	}
+
+	if (dev->dma == 0)
+	{
+		for(j = 0; dmalist[j] != 0; j++)
+		{
+			dev->dma = dmalist[j];
+                        if (!request_dma(dev->dma, isa_cardname))
+				break;
+		}
+
+		if(dmalist[j] == 0)
+		{
+			printk(KERN_INFO "%s: AutoSelect no DMA available\n", dev->name);
+			release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+			free_irq(dev->irq, dev);
+			tmsdev_term(dev);
+			return -1;
+		}
+	}
+	else
+	{
+		for(j = 0; dmalist[j] != 0; j++)
+			if (dmalist[j] == dev->dma)
+				break;
+		if (dmalist[j] == 0)
+		{
+                        printk(KERN_INFO "%s: Illegal DMA %d specified\n", 
+				dev->name, dev->dma);
+			release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+			free_irq(dev->irq, dev);
+			tmsdev_term(dev);
+			return -1;
+		}
+		if (request_dma(dev->dma, isa_cardname))
+		{
+                        printk(KERN_INFO "%s: Selected DMA %d not available\n", 
+				dev->name, dev->dma);
+			release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+			free_irq(dev->irq, dev);
+			tmsdev_term(dev);
+			return -1;
+		}
+	}
+
+	printk(KERN_DEBUG "%s:    IO: %#4lx  IRQ: %d  DMA: %d\n",
+	       dev->name, dev->base_addr, dev->irq, dev->dma);
+		
+	if (register_trdev(dev) == 0) 
+	{
+		/* Enlist in the card list */
+		card = kmalloc(sizeof(struct sk_isa_card), GFP_KERNEL);
+		if (!card) {
+			unregister_trdev(dev);
+			release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+			free_irq(dev->irq, dev);
+			free_dma(dev->dma);
+			tmsdev_term(dev);
+			return -1;
+		}
+		card->next = sk_isa_card_list;
+		sk_isa_card_list = card;
+		card->dev = dev;
+	} 
+	else 
+	{
+		printk("KERN_INFO %s: register_trdev() returned non-zero.\n", dev->name);
+		release_region(dev->base_addr, SK_ISA_IO_EXTENT); 
+		free_irq(dev->irq, dev);
+		free_dma(dev->dma);
+		tmsdev_term(dev);
+		return -1;
+	}
+	
+	return 0;
+}
+
+/*
+ * Reads MAC address from adapter RAM, which should've read it from
+ * the onboard ROM.  
+ *
+ * Calling this on a board that does not support it can be a very
+ * dangerous thing.  The Madge board, for instance, will lock your
+ * machine hard when this is called.  Luckily, its supported in a
+ * separate driver.  --ASF
+ */
+static void sk_isa_read_eeprom(struct net_device *dev)
+{
+	int i;
+	
+	/* Address: 0000:0000 */
+	sk_isa_sifwritew(dev, 0, SIFADX);
+	sk_isa_sifwritew(dev, 0, SIFADR);	
+	
+	/* Read six byte MAC address data */
+	dev->addr_len = 6;
+	for(i = 0; i < 6; i++)
+		dev->dev_addr[i] = sk_isa_sifreadw(dev, SIFINC) >> 8;
+}
+
+unsigned short sk_isa_setnselout_pins(struct net_device *dev)
+{
+	return 0;
+}
+
+static int sk_isa_open(struct net_device *dev)
+{  
+	struct net_local *tp = (struct net_local *)dev->priv;
+	unsigned short val = 0;
+	unsigned short oldval;
+	int i;
+
+	val = 0;
+	for(i = 0; irqlist[i] != 0; i++)
+	{
+		if(irqlist[i] == dev->irq)
+			break;
+	}
+
+	val |= CYCLE_TIME << 2;
+	val |= i << 4;
+	i = dev->dma - 5;
+	val |= i;
+	if(tp->DataRate == SPEED_4)
+		val |= LINE_SPEED_BIT;
+	else
+		val &= ~LINE_SPEED_BIT;
+	oldval = sk_isa_sifreadb(dev, POSREG);
+	/* Leave cycle bits alone */
+	oldval |= 0xf3;
+	val &= oldval;
+	sk_isa_sifwriteb(dev, val, POSREG);
+
+	tms380tr_open(dev);
+	return 0;
+}
+
+static int sk_isa_close(struct net_device *dev)
+{
+	tms380tr_close(dev);
+	return 0;
+}
+
+#ifdef MODULE
+
+#define ISATR_MAX_ADAPTERS 3
+
+static int io[ISATR_MAX_ADAPTERS];
+static int irq[ISATR_MAX_ADAPTERS];
+static int dma[ISATR_MAX_ADAPTERS];
+
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(io, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
+MODULE_PARM(dma, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
+
+int init_module(void)
+{
+	int i, num;
+	struct net_device *dev;
+
+	num = 0;
+	if (io[0]) 
+	{ /* Only probe addresses from command line */
+		dev = init_trdev(NULL, 0);
+		if (!dev)
+			return (-ENOMEM);
+		for (i = 0; i < ISATR_MAX_ADAPTERS; i++)
+	       	{
+			if (io[i] == 0)
+				continue;
+		
+			dev->base_addr = io[i];
+			dev->irq       = irq[i];
+			dev->dma       = dma[i];
+
+			if (!sk_isa_probe(dev))
+			{
+				num++;
+				dev = init_trdev(NULL, 0);
+				if (!dev)
+					goto partial;
+			}
+		}
+		unregister_netdev(dev);
+		kfree(dev);
+	}
+       	else
+       	{
+		dev = init_trdev(NULL, 0);
+		if (!dev)
+			return (-ENOMEM);
+
+		for(i = 0; portlist[i]; i++)
+		{
+			if (num >= ISATR_MAX_ADAPTERS)
+				continue;
+		
+			dev->base_addr = portlist[i];
+			dev->irq       = irq[num];
+			dev->dma       = dma[num];
+
+			if (!sk_isa_probe(dev))
+			{
+				num++;
+				dev = init_trdev(NULL, 0);
+				if (!dev)
+					goto partial;
+			}
+		}
+		unregister_netdev(dev);
+		kfree(dev);
+	}
+partial:
+	printk(KERN_NOTICE "skisa.c: %d cards found.\n", num);
+	/* Probe for cards. */
+	if (num == 0) {
+		printk(KERN_NOTICE "skisa.c: No cards found.\n");
+		return (-ENODEV);
+	}
+	return (0);
+}
+
+void cleanup_module(void)
+{
+	struct net_device *dev;
+	struct sk_isa_card *this_card;
+
+	while (sk_isa_card_list) {
+		dev = sk_isa_card_list->dev;
+		
+		unregister_netdev(dev);
+		release_region(dev->base_addr, SK_ISA_IO_EXTENT);
+		free_irq(dev->irq, dev);
+		free_dma(dev->dma);
+		tmsdev_term(dev);
+		kfree(dev);
+		this_card = sk_isa_card_list;
+		sk_isa_card_list = this_card->next;
+		kfree(this_card);
+	}
+}
+#endif /* MODULE */
+
+
+/*
+ * Local variables:
+ *  compile-command: "gcc -DMODVERSIONS  -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c skisa.c"
+ *  alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c skisa.c"
+ *  c-set-style "K&R"
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -Nru a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
--- a/drivers/net/tokenring/smctr.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/net/tokenring/smctr.c	Fri Feb 14 15:53:10 2003
@@ -3063,28 +3063,12 @@
         unsigned int i;
         __u8 r;
 
-        /* Check if node address has been specified by user. (non-0) */
-        for(i = 0; ((i < 6) && (dev->dev_addr[i] == 0)); i++);
+        for(i = 0; i < 6; i++)
         {
-                if(i != 6)
-                {
-                        for(i = 0; i < 6; i++)
-                        {
-                                r = inb(ioaddr + LAR0 + i);
-                                dev->dev_addr[i] = (char)r;
-                        }
-                        dev->addr_len = 6;
-                }
-                else    /* Node addr. not given by user, read it from board. */
-                {
-                        for(i = 0; i < 6; i++)
-                        {
-                                r = inb(ioaddr + LAR0 + i);
-                                dev->dev_addr[i] = (char)r;
-                        }
-                        dev->addr_len = 6;
-                }
+                r = inb(ioaddr + LAR0 + i);
+                dev->dev_addr[i] = (char)r;
         }
+        dev->addr_len = 6;
 
         return (0);
 }
diff -Nru a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
--- a/drivers/net/tokenring/tms380tr.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/net/tokenring/tms380tr.c	Fri Feb 14 15:53:10 2003
@@ -57,6 +57,11 @@
  *				as well.
  *      14-Jan-01	JF	Fix DMA on ifdown/ifup sequences. Some 
  *      			cleanup.
+ *	13-Jan-02	JF	Add spinlock to fix race condition.
+ *	09-Nov-02	JF	Fixed printks to not SPAM the console during
+ *				normal operation.
+ *	30-Dec-02	JF	Removed incorrect __init from 
+ *				tms380tr_init_card.
  *      			
  *  To do:
  *    1. Multi/Broadcast packet handling (this may have fixed itself)
@@ -68,7 +73,7 @@
  */
 
 #ifdef MODULE
-static const char version[] = "tms380tr.c: v1.08 14/01/2001 by Christoph Goos, Adam Fritzler\n";
+static const char version[] = "tms380tr.c: v1.10 30/12/2002 by Christoph Goos, Adam Fritzler\n";
 #endif
 
 #include <linux/module.h>
@@ -230,10 +235,10 @@
 #endif
 
 /* Dummy function */
-static int __init tms380tr_init_card(struct net_device *dev)
+static int tms380tr_init_card(struct net_device *dev)
 {
 	if(tms380tr_debug > 3)
-		printk("%s: tms380tr_init_card\n", dev->name);
+		printk(KERN_DEBUG "%s: tms380tr_init_card\n", dev->name);
 
 	return (0);
 }
@@ -251,6 +256,9 @@
 	struct net_local *tp = (struct net_local *)dev->priv;
 	int err;
 	
+	/* init the spinlock */
+	spin_lock_init(tp->lock);
+
 	/* Reset the hardware here. Don't forget to set the station address. */
 
 	if(dev->dma > 0) 
@@ -276,7 +284,7 @@
 	tp->timer.data		= (unsigned long)dev;
 	add_timer(&tp->timer);
 
-	printk(KERN_INFO "%s: Adapter RAM size: %dK\n", 
+	printk(KERN_DEBUG "%s: Adapter RAM size: %dK\n", 
 	       dev->name, tms380tr_read_ptr(dev));
 
 	tms380tr_enable_interrupts(dev);
@@ -339,25 +347,25 @@
 	tms380tr_init_net_local(dev);
 
 	if(tms380tr_debug > 3)
-		printk(KERN_INFO "%s: Resetting adapter...\n", dev->name);
+		printk(KERN_DEBUG "%s: Resetting adapter...\n", dev->name);
 	err = tms380tr_reset_adapter(dev);
 	if(err < 0)
 		return (-1);
 
 	if(tms380tr_debug > 3)
-		printk(KERN_INFO "%s: Bringup diags...\n", dev->name);
+		printk(KERN_DEBUG "%s: Bringup diags...\n", dev->name);
 	err = tms380tr_bringup_diags(dev);
 	if(err < 0)
 		return (-1);
 
 	if(tms380tr_debug > 3)
-		printk(KERN_INFO "%s: Init adapter...\n", dev->name);
+		printk(KERN_DEBUG "%s: Init adapter...\n", dev->name);
 	err = tms380tr_init_adapter(dev);
 	if(err < 0)
 		return (-1);
 
 	if(tms380tr_debug > 3)
-		printk(KERN_INFO "%s: Done!\n", dev->name);
+		printk(KERN_DEBUG "%s: Done!\n", dev->name);
 	return (0);
 }
 
@@ -628,6 +636,7 @@
 	TPL *tpl;
 	short length;
 	unsigned char *buf;
+	unsigned long flags;
 	struct sk_buff *skb;
 	int i;
 	dma_addr_t dmabuf, newbuf;
@@ -639,18 +648,22 @@
 		 * NOTE: We *must* always leave one unused TPL in the chain, 
 		 * because otherwise the adapter might send frames twice.
 		 */
+		spin_lock_irqsave(&tp->lock, flags);
 		if(tp->TplFree->NextTPLPtr->BusyFlag)	/* No free TPL */
 		{
 			if (tms380tr_debug > 0)
-				printk(KERN_INFO "%s: No free TPL\n", dev->name);
+				printk(KERN_DEBUG "%s: No free TPL\n", dev->name);
+				spin_unlock_irqrestore(&tp->lock, flags);
 			return;
 		}
 
 		/* Send first buffer from queue */
 		skb = skb_dequeue(&tp->SendSkbQueue);
 		if(skb == NULL)
+		{
+			spin_unlock_irqrestore(&tp->lock, flags);
 			return;
-
+		}
 		tp->QueueSkb++;
 		dmabuf = 0;
 
@@ -698,6 +711,7 @@
 
 		/* Let adapter send the frame. */
 		tms380tr_exec_sifcmd(dev, CMD_TX_VALID);
+		spin_unlock_irqrestore(&tp->lock, flags);
 	}
 
 	return;
@@ -773,7 +787,7 @@
 	unsigned short irq_type;
 
 	if(dev == NULL) {
-		printk("%s: irq %d for unknown device.\n", dev->name, irq);
+		printk(KERN_INFO "%s: irq %d for unknown device.\n", dev->name, irq);
 		return;
 	}
 
@@ -785,7 +799,7 @@
 		irq_type &= STS_IRQ_MASK;
 
 		if(!tms380tr_chk_ssb(tp, irq_type)) {
-			printk(KERN_INFO "%s: DATA LATE occurred\n", dev->name);
+			printk(KERN_DEBUG "%s: DATA LATE occurred\n", dev->name);
 			break;
 		}
 
@@ -843,7 +857,7 @@
 			break;
 			
 		default:
-			printk(KERN_INFO "Unknown Token Ring IRQ (0x%04x)\n", irq_type);
+			printk(KERN_DEBUG "Unknown Token Ring IRQ (0x%04x)\n", irq_type);
 			break;
 		}
 
@@ -1377,7 +1391,7 @@
 	do {
 		retry_cnt--;
 		if(tms380tr_debug > 3)
-			printk(KERN_INFO "BUD-Status: ");
+			printk(KERN_DEBUG "BUD-Status: ");
 		loop_cnt = BUD_MAX_LOOPCNT;	/* maximum: three seconds*/
 		do {			/* Inspect BUD results */
 			loop_cnt--;
@@ -1386,7 +1400,7 @@
 			Status &= STS_MASK;
 
 			if(tms380tr_debug > 3)
-				printk(KERN_INFO " %04X \n", Status);
+				printk(KERN_DEBUG " %04X \n", Status);
 			/* BUD successfully completed */
 			if(Status == STS_INITIALIZE)
 				return (1);
@@ -1443,10 +1457,10 @@
 
 	if(tms380tr_debug > 3)
 	{
-		printk(KERN_INFO "%s: buffer (real): %lx\n", dev->name, (long) &tp->scb);
-		printk(KERN_INFO "%s: buffer (virt): %lx\n", dev->name, (long) ((char *)&tp->scb - (char *)tp) + tp->dmabuffer);
-		printk(KERN_INFO "%s: buffer (DMA) : %lx\n", dev->name, (long) tp->dmabuffer);
-		printk(KERN_INFO "%s: buffer (tp)  : %lx\n", dev->name, (long) tp);
+		printk(KERN_DEBUG "%s: buffer (real): %lx\n", dev->name, (long) &tp->scb);
+		printk(KERN_DEBUG "%s: buffer (virt): %lx\n", dev->name, (long) ((char *)&tp->scb - (char *)tp) + tp->dmabuffer);
+		printk(KERN_DEBUG "%s: buffer (DMA) : %lx\n", dev->name, (long) tp->dmabuffer);
+		printk(KERN_DEBUG "%s: buffer (tp)  : %lx\n", dev->name, (long) tp);
 	}
 	/* Maximum: three initialization retries */
 	retry_cnt = INIT_MAX_RETRIES;
@@ -1797,7 +1811,7 @@
 
 	if(tms380tr_debug > 3)
 	{
-		printk("%s: AdapterCheckBlock: ", dev->name);
+		printk(KERN_DEBUG "%s: AdapterCheckBlock: ", dev->name);
 		for (i = 0; i < 4; i++)
 			printk("%04X", AdapterCheckBlock[i]);
 		printk("\n");
@@ -1874,52 +1888,52 @@
 			break;
 
 		case ILLEGAL_OP_CODE:
-			printk("%s: Illegal operation code in firmware\n",
+			printk(KERN_INFO "%s: Illegal operation code in firmware\n",
 				dev->name);
 			/* Parm[0-3]: adapter internal register R13-R15 */
 			break;
 
 		case PARITY_ERRORS:
-			printk("%s: Adapter internal bus parity error\n",
+			printk(KERN_INFO "%s: Adapter internal bus parity error\n",
 				dev->name);
 			/* Parm[0-3]: adapter internal register R13-R15 */
 			break;
 
 		case RAM_DATA_ERROR:
-			printk("%s: RAM data error\n", dev->name);
+			printk(KERN_INFO "%s: RAM data error\n", dev->name);
 			/* Parm[0-1]: MSW/LSW address of RAM location. */
 			break;
 
 		case RAM_PARITY_ERROR:
-			printk("%s: RAM parity error\n", dev->name);
+			printk(KERN_INFO "%s: RAM parity error\n", dev->name);
 			/* Parm[0-1]: MSW/LSW address of RAM location. */
 			break;
 
 		case RING_UNDERRUN:
-			printk("%s: Internal DMA underrun detected\n",
+			printk(KERN_INFO "%s: Internal DMA underrun detected\n",
 				dev->name);
 			break;
 
 		case INVALID_IRQ:
-			printk("%s: Unrecognized interrupt detected\n",
+			printk(KERN_INFO "%s: Unrecognized interrupt detected\n",
 				dev->name);
 			/* Parm[0-3]: adapter internal register R13-R15 */
 			break;
 
 		case INVALID_ERROR_IRQ:
-			printk("%s: Unrecognized error interrupt detected\n",
+			printk(KERN_INFO "%s: Unrecognized error interrupt detected\n",
 				dev->name);
 			/* Parm[0-3]: adapter internal register R13-R15 */
 			break;
 
 		case INVALID_XOP:
-			printk("%s: Unrecognized XOP request detected\n",
+			printk(KERN_INFO "%s: Unrecognized XOP request detected\n",
 				dev->name);
 			/* Parm[0-3]: adapter internal register R13-R15 */
 			break;
 
 		default:
-			printk("%s: Unknown status", dev->name);
+			printk(KERN_INFO "%s: Unknown status", dev->name);
 			break;
 	}
 
@@ -2070,14 +2084,14 @@
 
 			if((HighAc != LowAc) || (HighAc == AC_NOT_RECOGNIZED))
 			{
-				printk(KERN_INFO "%s: (DA=%08lX not recognized)",
+				printk(KERN_DEBUG "%s: (DA=%08lX not recognized)\n",
 					dev->name,
 					*(unsigned long *)&tpl->MData[2+2]);
 			}
 			else
 			{
 				if(tms380tr_debug > 3)
-					printk("%s: Directed frame tx'd\n", 
+					printk(KERN_DEBUG "%s: Directed frame tx'd\n", 
 						dev->name);
 			}
 		}
@@ -2086,7 +2100,7 @@
 			if(!DIRECTED_FRAME(tpl))
 			{
 				if(tms380tr_debug > 3)
-					printk("%s: Broadcast frame tx'd\n",
+					printk(KERN_DEBUG "%s: Broadcast frame tx'd\n",
 						dev->name);
 			}
 		}
@@ -2163,7 +2177,7 @@
 			tms380tr_update_rcv_stats(tp,ReceiveDataPtr,Length);
 			  
 			if(tms380tr_debug > 3)
-				printk("%s: Packet Length %04X (%d)\n",
+				printk(KERN_DEBUG "%s: Packet Length %04X (%d)\n",
 					dev->name, Length, Length);
 			  
 			/* Indicate the received frame to system the
@@ -2347,12 +2361,11 @@
 	if (dev->priv == NULL)
 	{
 		struct net_local *tms_local;
-		dma_addr_t buffer;
 		
 		dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL | GFP_DMA);
 		if (dev->priv == NULL)
 		{
-                        printk("%s: Out of memory for DMA\n",
+                        printk(KERN_INFO "%s: Out of memory for DMA\n",
                                 dev->name);
 			return -ENOMEM;
 		}
@@ -2361,16 +2374,15 @@
 		init_waitqueue_head(&tms_local->wait_for_tok_int);
 		tms_local->dmalimit = dmalimit;
 		tms_local->pdev = pdev;
-                buffer = pci_map_single(pdev, (void *)tms_local,
+                tms_local->dmabuffer = pci_map_single(pdev, (void *)tms_local,
                         sizeof(struct net_local), PCI_DMA_BIDIRECTIONAL);
-                if (buffer + sizeof(struct net_local) > dmalimit)
+                if (tms_local->dmabuffer + sizeof(struct net_local) > dmalimit)
                 {
-			printk("%s: Memory not accessible for DMA\n",
+			printk(KERN_INFO "%s: Memory not accessible for DMA\n",
 				dev->name);
 			tmsdev_term(dev);
 			return -ENOMEM;
 		}
-		tms_local->dmabuffer = buffer;
 	}
 	
 	/* These can be overridden by the card driver if needed */
@@ -2401,7 +2413,7 @@
 
 int init_module(void)
 {
-	printk("%s", version);
+	printk(KERN_DEBUG "%s", version);
 	
 	TMS380_module = &__this_module;
 	return 0;
diff -Nru a/drivers/net/tokenring/tms380tr.h b/drivers/net/tokenring/tms380tr.h
--- a/drivers/net/tokenring/tms380tr.h	Fri Feb 14 15:53:12 2003
+++ b/drivers/net/tokenring/tms380tr.h	Fri Feb 14 15:53:12 2003
@@ -1135,6 +1135,7 @@
 	unsigned short (*sifreadw)(struct net_device *, unsigned short);
 	void (*sifwritew)(struct net_device *, unsigned short, unsigned short);
 
+	spinlock_t lock;                /* SMP protection */
 	void *tmspriv;
 } NET_LOCAL;
 
diff -Nru a/drivers/net/tokenring/tmsisa.c b/drivers/net/tokenring/tmsisa.c
--- a/drivers/net/tokenring/tmsisa.c	Fri Feb 14 15:53:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,473 +0,0 @@
-/*
- *  tmsisa.c: A generic network driver for TMS380-based ISA token ring cards.
- *
- *  Based on tmspci written 1999 by Adam Fritzler
- *  
- *  Written 2000 by Jochen Friedrich
- *  Dedicated to my girlfriend Steffi Bopp
- *
- *  This software may be used and distributed according to the terms
- *  of the GNU General Public License, incorporated herein by reference.
- *
- *  This driver module supports the following cards:
- *	- SysKonnect TR4/16(+) ISA	(SK-4190)
- *
- *  Maintainer(s):
- *    AF        Adam Fritzler           mid@auk.cx
- *    JF	Jochen Friedrich	jochen@scram.de
- *
- *  TODO:
- *	1. Add support for Proteon TR ISA adapters (1392, 1392+)
- */
-static const char version[] = "tmsisa.c: v1.00 14/01/2001 by Jochen Friedrich\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/trdevice.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/pci.h>
-#include <asm/dma.h>
-
-#include "tms380tr.h"
-
-#define TMS_ISA_IO_EXTENT 32
-
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int portlist[] __initdata = {
-	0x0A20, 0x1A20, 0x0B20, 0x1B20, 0x0980, 0x1980, 0x0900, 0x1900,// SK
-	0
-};
-
-/* A zero-terminated list of IRQs to be probed. 
- * Used again after initial probe for sktr_chipset_init, called from sktr_open.
- */
-static unsigned short irqlist[] = {
-	3, 5, 9, 10, 11, 12, 15,
-	0
-};
-
-/* A zero-terminated list of DMAs to be probed. */
-static int dmalist[] __initdata = {
-	5, 6, 7,
-	0
-};
-
-static char isa_cardname[] = "SK NET TR 4/16 ISA\0";
-
-int tms_isa_probe(struct net_device *dev);
-static int tms_isa_open(struct net_device *dev);
-static int tms_isa_close(struct net_device *dev);
-static void tms_isa_read_eeprom(struct net_device *dev);
-static unsigned short tms_isa_setnselout_pins(struct net_device *dev);
-
-static unsigned short tms_isa_sifreadb(struct net_device *dev, unsigned short reg)
-{
-	return inb(dev->base_addr + reg);
-}
-
-static unsigned short tms_isa_sifreadw(struct net_device *dev, unsigned short reg)
-{
-	return inw(dev->base_addr + reg);
-}
-
-static void tms_isa_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
-{
-	outb(val, dev->base_addr + reg);
-}
-
-static void tms_isa_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
-{
-	outw(val, dev->base_addr + reg);
-}
-
-struct tms_isa_card {
-	struct net_device *dev;
-	struct tms_isa_card *next;
-};
-
-static struct tms_isa_card *tms_isa_card_list;
-
-static int __init tms_isa_probe1(int ioaddr)
-{
-	unsigned char old, chk1, chk2;
-
-	old = inb(ioaddr + SIFADR);	/* Get the old SIFADR value */
-
-	chk1 = 0;	/* Begin with check value 0 */
-	do {
-		/* Write new SIFADR value */
-		outb(chk1, ioaddr + SIFADR);
-
-		/* Read, invert and write */
-		chk2 = inb(ioaddr + SIFADD);
-		chk2 ^= 0x0FE;
-		outb(chk2, ioaddr + SIFADR);
-
-		/* Read, invert and compare */
-		chk2 = inb(ioaddr + SIFADD);
-		chk2 ^= 0x0FE;
-
-		if(chk1 != chk2)
-			return (-1);	/* No adapter */
-
-		chk1 -= 2;
-	} while(chk1 != 0);	/* Repeat 128 times (all byte values) */
-
-    	/* Restore the SIFADR value */
-	outb(old, ioaddr + SIFADR);
-
-	return (0);
-}
-
-int __init tms_isa_probe(struct net_device *dev)
-{
-        static int versionprinted;
-	struct net_local *tp;
-	int j;
-	struct tms_isa_card *card;
-
-	if(check_region(dev->base_addr, TMS_ISA_IO_EXTENT))
-		return -1;
-
-	if(tms_isa_probe1(dev->base_addr))
-		return -1;
-   
-	if (versionprinted++ == 0)
-		printk("%s", version);
- 
-	/* At this point we have found a valid card. */
-    
-	if (!request_region(dev->base_addr, TMS_ISA_IO_EXTENT, isa_cardname))
-		return -1;
-
-	if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL))
-       	{
-		release_region(dev->base_addr, TMS_ISA_IO_EXTENT); 
-		return -1;
-	}
-
-	dev->base_addr &= ~3; 
-		
-	tms_isa_read_eeprom(dev);
-
-	printk("%s:    Ring Station Address: ", dev->name);
-	printk("%2.2x", dev->dev_addr[0]);
-	for (j = 1; j < 6; j++)
-		printk(":%2.2x", dev->dev_addr[j]);
-	printk("\n");
-		
-	tp = (struct net_local *)dev->priv;
-	tp->setnselout = tms_isa_setnselout_pins;
-		
-	tp->sifreadb = tms_isa_sifreadb;
-	tp->sifreadw = tms_isa_sifreadw;
-	tp->sifwriteb = tms_isa_sifwriteb;
-	tp->sifwritew = tms_isa_sifwritew;
-	
-	memcpy(tp->ProductID, isa_cardname, PROD_ID_SIZE + 1);
-
-	tp->tmspriv = NULL;
-
-	dev->open = tms_isa_open;
-	dev->stop = tms_isa_close;
-
-	if (dev->irq == 0)
-	{
-		for(j = 0; irqlist[j] != 0; j++)
-		{
-			dev->irq = irqlist[j];
-			if (!request_irq(dev->irq, tms380tr_interrupt, 0, 
-				isa_cardname, dev))
-				break;
-                }
-		
-                if(irqlist[j] == 0)
-                {
-                        printk("%s: AutoSelect no IRQ available\n", dev->name);
-			release_region(dev->base_addr, TMS_ISA_IO_EXTENT); 
-			tmsdev_term(dev);
-			return -1;
-		}
-	}
-	else
-	{
-		for(j = 0; irqlist[j] != 0; j++)
-			if (irqlist[j] == dev->irq)
-				break;
-		if (irqlist[j] == 0)
-		{
-			printk("%s: Illegal IRQ %d specified\n",
-				dev->name, dev->irq);
-			release_region(dev->base_addr, TMS_ISA_IO_EXTENT); 
-			tmsdev_term(dev);
-			return -1;
-		}
-		if (request_irq(dev->irq, tms380tr_interrupt, 0, 
-			isa_cardname, dev))
-		{
-                        printk("%s: Selected IRQ %d not available\n", 
-				dev->name, dev->irq);
-			release_region(dev->base_addr, TMS_ISA_IO_EXTENT); 
-			tmsdev_term(dev);
-			return -1;
-		}
-	}
-
-	if (dev->dma == 0)
-	{
-		for(j = 0; dmalist[j] != 0; j++)
-		{
-			dev->dma = dmalist[j];
-                        if (!request_dma(dev->dma, isa_cardname))
-				break;
-		}
-
-		if(dmalist[j] == 0)
-		{
-			printk("%s: AutoSelect no DMA available\n", dev->name);
-			release_region(dev->base_addr, TMS_ISA_IO_EXTENT); 
-			free_irq(dev->irq, dev);
-			tmsdev_term(dev);
-			return -1;
-		}
-	}
-	else
-	{
-		for(j = 0; dmalist[j] != 0; j++)
-			if (dmalist[j] == dev->dma)
-				break;
-		if (dmalist[j] == 0)
-		{
-                        printk("%s: Illegal DMA %d specified\n", 
-				dev->name, dev->dma);
-			release_region(dev->base_addr, TMS_ISA_IO_EXTENT); 
-			free_irq(dev->irq, dev);
-			tmsdev_term(dev);
-			return -1;
-		}
-		if (request_dma(dev->dma, isa_cardname))
-		{
-                        printk("%s: Selected DMA %d not available\n", 
-				dev->name, dev->dma);
-			release_region(dev->base_addr, TMS_ISA_IO_EXTENT); 
-			free_irq(dev->irq, dev);
-			tmsdev_term(dev);
-			return -1;
-		}
-	}
-
-	printk("%s:    IO: %#4lx  IRQ: %d  DMA: %d\n",
-	       dev->name, dev->base_addr, dev->irq, dev->dma);
-		
-	if (register_trdev(dev) == 0) 
-	{
-		/* Enlist in the card list */
-		card = kmalloc(sizeof(struct tms_isa_card), GFP_KERNEL);
-		if (!card) {
-			unregister_trdev(dev);
-			release_region(dev->base_addr, TMS_ISA_IO_EXTENT); 
-			free_irq(dev->irq, dev);
-			free_dma(dev->dma);
-			tmsdev_term(dev);
-			return -1;
-		}
-		card->next = tms_isa_card_list;
-		tms_isa_card_list = card;
-		card->dev = dev;
-	} 
-	else 
-	{
-		printk("%s: register_trdev() returned non-zero.\n", dev->name);
-		release_region(dev->base_addr, TMS_ISA_IO_EXTENT); 
-		free_irq(dev->irq, dev);
-		free_dma(dev->dma);
-		tmsdev_term(dev);
-		return -1;
-	}
-	
-	return 0;
-}
-
-/*
- * Reads MAC address from adapter RAM, which should've read it from
- * the onboard ROM.  
- *
- * Calling this on a board that does not support it can be a very
- * dangerous thing.  The Madge board, for instance, will lock your
- * machine hard when this is called.  Luckily, its supported in a
- * separate driver.  --ASF
- */
-static void tms_isa_read_eeprom(struct net_device *dev)
-{
-	int i;
-	
-	/* Address: 0000:0000 */
-	tms_isa_sifwritew(dev, 0, SIFADX);
-	tms_isa_sifwritew(dev, 0, SIFADR);	
-	
-	/* Read six byte MAC address data */
-	dev->addr_len = 6;
-	for(i = 0; i < 6; i++)
-		dev->dev_addr[i] = tms_isa_sifreadw(dev, SIFINC) >> 8;
-}
-
-unsigned short tms_isa_setnselout_pins(struct net_device *dev)
-{
-	return 0;
-}
-
-static int tms_isa_open(struct net_device *dev)
-{  
-	struct net_local *tp = (struct net_local *)dev->priv;
-	unsigned short val = 0;
-	unsigned short oldval;
-	int i;
-
-	val = 0;
-	for(i = 0; irqlist[i] != 0; i++)
-	{
-		if(irqlist[i] == dev->irq)
-			break;
-	}
-
-	val |= CYCLE_TIME << 2;
-	val |= i << 4;
-	i = dev->dma - 5;
-	val |= i;
-	if(tp->DataRate == SPEED_4)
-		val |= LINE_SPEED_BIT;
-	else
-		val &= ~LINE_SPEED_BIT;
-	oldval = tms_isa_sifreadb(dev, POSREG);
-	/* Leave cycle bits alone */
-	oldval |= 0xf3;
-	val &= oldval;
-	tms_isa_sifwriteb(dev, val, POSREG);
-
-	tms380tr_open(dev);
-	MOD_INC_USE_COUNT;
-	return 0;
-}
-
-static int tms_isa_close(struct net_device *dev)
-{
-	tms380tr_close(dev);
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
-
-#ifdef MODULE
-
-#define ISATR_MAX_ADAPTERS 3
-
-static int io[ISATR_MAX_ADAPTERS];
-static int irq[ISATR_MAX_ADAPTERS];
-static int dma[ISATR_MAX_ADAPTERS];
-
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(io, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
-MODULE_PARM(dma, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
-
-int init_module(void)
-{
-	int i, num;
-	struct net_device *dev;
-
-	num = 0;
-	if (io[0]) 
-	{ /* Only probe addresses from command line */
-		for (i = 0; i < ISATR_MAX_ADAPTERS; i++)
-	       	{
-			if (io[i] == 0)
-				continue;
-
-			dev = init_trdev(NULL, 0);
-			if (!dev)
-				return (-ENOMEM);
-		
-			dev->base_addr = io[i];
-			dev->irq       = irq[i];
-			dev->dma       = dma[i];
-
-			if (tms_isa_probe(dev))
-			{
-				unregister_netdev(dev);
-				kfree(dev);
-			}
-			else
-				num++;
-		}
-	}
-       	else
-       	{
-		for(i = 0; portlist[i]; i++)
-		{
-			if (num >= ISATR_MAX_ADAPTERS)
-				continue;
-
-			dev = init_trdev(NULL, 0);
-			if (!dev)
-				return (-ENOMEM);
-		
-			dev->base_addr = portlist[i];
-			dev->irq       = irq[num];
-			dev->dma       = dma[num];
-
-			if (tms_isa_probe(dev))
-			{
-				unregister_netdev(dev);
-				kfree(dev);
-			}
-			else
-				num++;
-		}
-	}
-	printk(KERN_NOTICE "tmsisa.c: %d cards found.\n", num);
-	/* Probe for cards. */
-	if (num == 0) {
-		printk(KERN_NOTICE "tmsisa.c: No cards found.\n");
-	}
-	return (0);
-}
-
-void cleanup_module(void)
-{
-	struct net_device *dev;
-	struct tms_isa_card *this_card;
-
-	while (tms_isa_card_list) {
-		dev = tms_isa_card_list->dev;
-		
-		unregister_netdev(dev);
-		release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
-		free_irq(dev->irq, dev);
-		free_dma(dev->dma);
-		tmsdev_term(dev);
-		kfree(dev);
-		this_card = tms_isa_card_list;
-		tms_isa_card_list = this_card->next;
-		kfree(this_card);
-	}
-}
-#endif /* MODULE */
-
-
-/*
- * Local variables:
- *  compile-command: "gcc -DMODVERSIONS  -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tmsisa.c"
- *  alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tmsisa.c"
- *  c-set-style "K&R"
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
diff -Nru a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
--- a/drivers/net/tulip/de4x5.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/net/tulip/de4x5.c	Fri Feb 14 15:53:08 2003
@@ -440,8 +440,6 @@
     =========================================================================
 */
 
-static char version[] __initdata = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -476,6 +474,8 @@
 #endif /* CONFIG_PPC */
 
 #include "de4x5.h"
+
+static char version[] __initdata = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
 
 #define c_char const char
 #define TWIDDLE(a) (u_short)le16_to_cpu(get_unaligned((u_short *)(a)))
diff -Nru a/drivers/net/typhoon-firmware.h b/drivers/net/typhoon-firmware.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/typhoon-firmware.h	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,4108 @@
+/*
+ * Copyright 1999-2002 3Com Corporation.  All Rights Reserved.    
+ *
+ * Redistribution and use in source and binary forms of the 3CR990img.h
+ * microcode software are permitted provided that the following conditions
+ * are met:
+ * 1. Redistribution of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistribution in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of 3Com may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY 3COM ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * USER ACKNOWLEDGES AND AGREES THAT PURCHASE OR USE OF THE 3CR990img.h
+ * MICROCODE SOFTWARE WILL NOT CREATE OR GIVE GROUNDS FOR A LICENSE BY
+ * IMPLICATION, ESTOPPEL, OR OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS
+ * (PATENT, COPYRIGHT, TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT)
+ * EMBODIED IN ANY OTHER 3COM HARDWARE OR SOFTWARE EITHER SOLELY OR IN
+ * COMBINATION WITH THE 3CR990img.h microcode SOFTWARE
+ */ 
+const u8 typhoon_firmware_image[] = {
+0x54, 0x59, 0x50, 0x48, 0x4f, 0x4f, 0x4e, 0x00, 0x02, 0x00, 0x00, 0x00, 
+0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x40, 0x01, 0x00, 0x00, 
+0x6c, 0xef, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x39, 0x00, 0x00, 0xea, 
+0x05, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 
+0x02, 0x00, 0x00, 0xea, 0x01, 0x00, 0x00, 0xea, 0x32, 0x02, 0x00, 0xea, 
+0xa5, 0x14, 0x00, 0xea, 0x07, 0x00, 0x2d, 0xe9, 0x0e, 0x00, 0xa0, 0xe1, 
+0x00, 0x10, 0x0f, 0xe1, 0xd0, 0x20, 0x9f, 0xe5, 0x12, 0xff, 0x2f, 0xe1, 
+0xfe, 0xff, 0xff, 0xea, 0x01, 0x00, 0x80, 0xe0, 0x04, 0x20, 0x81, 0xe4, 
+0x01, 0x00, 0x50, 0xe1, 0xfc, 0xff, 0xff, 0x1a, 0x0e, 0xf0, 0xa0, 0xe1, 
+0x00, 0xa0, 0xa0, 0xe1, 0x0e, 0xb0, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 
+0xa8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x81, 0xe5, 0xa4, 0x10, 0x9f, 0xe5, 
+0x00, 0x00, 0x81, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 0x00, 0x00, 0x91, 0xe5, 
+0x01, 0x00, 0x80, 0xe3, 0x00, 0x00, 0x81, 0xe5, 0xd7, 0x00, 0xa0, 0xe3, 
+0x00, 0xf0, 0x21, 0xe1, 0x88, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3, 
+0x00, 0xf0, 0x21, 0xe1, 0x7c, 0xd0, 0x9f, 0xe5, 0xd2, 0x00, 0xa0, 0xe3, 
+0x00, 0xf0, 0x21, 0xe1, 0x74, 0xd0, 0x9f, 0xe5, 0xd1, 0x00, 0xa0, 0xe3, 
+0x00, 0xf0, 0x21, 0xe1, 0x6c, 0xd0, 0x9f, 0xe5, 0x7b, 0x14, 0x00, 0xeb, 
+0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x60, 0xd0, 0x9f, 0xe5, 
+0x60, 0x00, 0x9f, 0xe5, 0x60, 0x10, 0x9f, 0xe5, 0x60, 0x20, 0x9f, 0xe5, 
+0xdb, 0xff, 0xff, 0xeb, 0x5c, 0x00, 0x9f, 0xe5, 0x5c, 0x10, 0x9f, 0xe5, 
+0x00, 0x20, 0xa0, 0xe3, 0xd7, 0xff, 0xff, 0xeb, 0x54, 0x00, 0x9f, 0xe5, 
+0x54, 0x10, 0x9f, 0xe5, 0xd4, 0xff, 0xff, 0xeb, 0x0a, 0x00, 0xa0, 0xe1, 
+0x0b, 0xf0, 0xa0, 0xe1, 0xd3, 0x10, 0xa0, 0xe3, 0x01, 0xf0, 0x21, 0xe1, 
+0xd4, 0xff, 0xff, 0xeb, 0x3c, 0xa0, 0x9f, 0xe5, 0x1a, 0xff, 0x2f, 0xe1, 
+0xc6, 0xff, 0xff, 0xea, 0xbd, 0x20, 0xff, 0xff, 0x0c, 0x00, 0x10, 0x00, 
+0x1c, 0x00, 0x10, 0x00, 0x3c, 0x38, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80, 
+0xfc, 0x3f, 0x00, 0x80, 0x7c, 0x34, 0x00, 0x80, 0x80, 0x0f, 0x00, 0x00, 
+0x80, 0x30, 0x00, 0x80, 0xad, 0xde, 0xad, 0xde, 0xa8, 0xbc, 0x00, 0x00, 
+0x24, 0xab, 0x20, 0x40, 0x34, 0x29, 0x00, 0x00, 0xa8, 0x04, 0x00, 0x80, 
+0x6d, 0xc8, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0xd8, 0x56, 0x00, 0x00, 0x06, 0x24, 0x00, 0x00, 
+0x60, 0x01, 0xff, 0xff, 0xb0, 0xb5, 0x07, 0x1c, 0x12, 0x4c, 0x00, 0x25, 
+0xe0, 0x6b, 0x00, 0x28, 0x1d, 0xd0, 0x38, 0x1c, 0x10, 0x49, 0x04, 0xf0, 
+0x37, 0xfd, 0xe1, 0x6b, 0xc0, 0x46, 0x08, 0x60, 0x00, 0x28, 0x14, 0xd0, 
+0x38, 0x01, 0x0d, 0x49, 0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 
+0x41, 0x6b, 0x80, 0x29, 0x0b, 0xd2, 0x01, 0x31, 0x41, 0x63, 0xe0, 0x6b, 
+0xc1, 0x69, 0xc0, 0x46, 0xe1, 0x63, 0x39, 0x07, 0x41, 0x60, 0xc7, 0x62, 
+0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x28, 0x1c, 0xfa, 0xe7, 0x00, 0x00, 
+0x28, 0x17, 0x00, 0x80, 0xee, 0x05, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x80, 
+0x02, 0x49, 0xca, 0x6b, 0xc0, 0x46, 0xc2, 0x61, 0xc8, 0x63, 0x70, 0x47, 
+0x28, 0x17, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 
+0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe1, 
+0x00, 0x10, 0xa0, 0xe1, 0xc0, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x21, 0xe1, 
+0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 
+0x00, 0x00, 0x0f, 0xe1, 0xc0, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 
+0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 0xc0, 0x00, 0xc0, 0xe3, 
+0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 
+0x40, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 
+0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0x10, 0xe3, 0x80, 0x00, 0x80, 0xe3, 
+0x00, 0xf0, 0x21, 0xe1, 0x00, 0x00, 0x00, 0x12, 0x1e, 0xff, 0x2f, 0xe1, 
+0x00, 0x00, 0x50, 0xe3, 0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0x13, 
+0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 
+0x80, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 
+0x91, 0x00, 0x00, 0xe0, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x20, 0x80, 0xe0, 
+0x01, 0x00, 0x80, 0xe0, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x08, 0x4f, 
+0x64, 0x28, 0x04, 0xd3, 0x64, 0x20, 0x38, 0x63, 0x00, 0x20, 0xc0, 0x43, 
+0x03, 0xe0, 0x38, 0x63, 0x04, 0x49, 0x05, 0xf0, 0xc1, 0xfa, 0x78, 0x63, 
+0xb8, 0x63, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
+0x88, 0x13, 0x00, 0x00, 0x80, 0xb4, 0x10, 0x4b, 0x00, 0x22, 0x1f, 0x6b, 
+0x64, 0x2f, 0x03, 0xd2, 0x09, 0x68, 0x09, 0x68, 0x49, 0x08, 0x02, 0xd2, 
+0x10, 0x1c, 0x80, 0xbc, 0x70, 0x47, 0x19, 0x1c, 0xdb, 0x6b, 0x4f, 0x6b, 
+0xbb, 0x42, 0x05, 0xd2, 0x40, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x18, 0x18, 
+0xc8, 0x63, 0xf1, 0xe7, 0x41, 0x68, 0x05, 0x4b, 0x19, 0x43, 0x41, 0x60, 
+0x04, 0x48, 0xc1, 0x6b, 0x01, 0x31, 0xc1, 0x63, 0x02, 0x20, 0xe8, 0xe7, 
+0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, 
+0x90, 0xb5, 0x07, 0x1c, 0x15, 0x4c, 0x00, 0x20, 0x21, 0x6b, 0x64, 0x29, 
+0x0b, 0xd2, 0xb9, 0x6e, 0x49, 0x08, 0x08, 0xd3, 0x21, 0x6c, 0xa2, 0x6b, 
+0x91, 0x42, 0x07, 0xd2, 0xfa, 0x1d, 0x39, 0x32, 0x52, 0x8b, 0x89, 0x18, 
+0x21, 0x64, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x6a, 0x39, 0x6b, 
+0xc0, 0x46, 0x48, 0x62, 0x38, 0x6b, 0x02, 0xf0, 0xe7, 0xfd, 0x38, 0x1c, 
+0x02, 0xf0, 0xa4, 0xfa, 0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xe1, 0x18, 
+0xc8, 0x72, 0x05, 0x49, 0x0a, 0x6c, 0x12, 0x18, 0x0a, 0x64, 0x04, 0x49, 
+0x8a, 0x6d, 0x12, 0x18, 0x8a, 0x65, 0xe4, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 
+0x78, 0x2a, 0x00, 0x80, 0x10, 0x2a, 0x00, 0x80, 0x80, 0xb4, 0x0a, 0x48, 
+0xc0, 0x6d, 0x02, 0x23, 0x18, 0x40, 0x09, 0x4a, 0x00, 0x21, 0x00, 0x28, 
+0x03, 0xd0, 0xd1, 0x63, 0x11, 0x64, 0x80, 0xbc, 0x70, 0x47, 0x06, 0x48, 
+0x07, 0x68, 0x7b, 0x1c, 0x03, 0x60, 0x0a, 0x2f, 0xf7, 0xd3, 0x01, 0x60, 
+0xf3, 0xe7, 0x00, 0x00, 0x10, 0x2a, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 
+0x60, 0x01, 0x00, 0x80, 0x70, 0x47, 0x02, 0x04, 0x12, 0x0c, 0x00, 0x0c, 
+0x10, 0x18, 0x0a, 0x04, 0x12, 0x0c, 0x09, 0x0c, 0x51, 0x18, 0x08, 0x18, 
+0x01, 0x0c, 0x05, 0xd0, 0x01, 0x04, 0x09, 0x0c, 0x00, 0x0c, 0x08, 0x18, 
+0x01, 0x0c, 0xf9, 0xd1, 0x00, 0x04, 0x00, 0x0c, 0x70, 0x47, 0x80, 0xb4, 
+0x00, 0x22, 0x00, 0x29, 0x18, 0xd0, 0x4f, 0x08, 0x7b, 0x1e, 0x00, 0x2f, 
+0x06, 0xd0, 0x07, 0x88, 0xba, 0x18, 0x02, 0x30, 0x1f, 0x1c, 0x01, 0x3b, 
+0x00, 0x2f, 0xf8, 0xd1, 0x49, 0x08, 0x03, 0xd3, 
+0x00, 0x88, 0x00, 0x06, 0x00, 0x0e, 0x82, 0x18, 0x10, 0x0c, 0x05, 0xd0, 
+0x10, 0x04, 0x00, 0x0c, 0x11, 0x0c, 0x42, 0x18, 0x10, 0x0c, 0xf9, 0xd1, 
+0x10, 0x04, 0x00, 0x0c, 0x80, 0xbc, 0x70, 0x47, 0x80, 0xb5, 0x83, 0x89, 
+0xc7, 0x89, 0xfb, 0x18, 0x07, 0x8a, 0xfb, 0x18, 0x47, 0x8a, 0xfb, 0x18, 
+0x40, 0x7a, 0x00, 0x02, 0xc7, 0x18, 0x38, 0x0c, 0x05, 0xd0, 0x38, 0x04, 
+0x00, 0x0c, 0x3b, 0x0c, 0xc7, 0x18, 0x38, 0x0c, 0xf9, 0xd1, 0x08, 0x1c, 
+0x11, 0x1c, 0xff, 0xf7, 0xc8, 0xff, 0x01, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 
+0xb0, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x02, 0x23, 
+0x82, 0x68, 0x1a, 0x40, 0x00, 0x27, 0x00, 0x2a, 0x0f, 0xd0, 0x0a, 0x4a, 
+0x93, 0x69, 0x01, 0x33, 0x93, 0x61, 0x0a, 0x68, 0x8b, 0x68, 0x9a, 0x18, 
+0x00, 0x68, 0x1c, 0x18, 0x57, 0x81, 0x09, 0x69, 0x10, 0x1c, 0xff, 0xf7, 
+0xac, 0xff, 0xc0, 0x43, 0x60, 0x81, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x23, 
+0x82, 0x68, 0x1a, 0x40, 0x00, 0x27, 0x00, 0x2a, 0x11, 0xd0, 0x4a, 0x68, 
+0x52, 0x09, 0x0e, 0xd3, 0x09, 0x4a, 0x13, 0x6a, 0x01, 0x33, 0x13, 0x62, 
+0xcb, 0x68, 0x02, 0x68, 0x9c, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x3a, 
+0x1a, 0x43, 0x12, 0x68, 0x00, 0xf0, 0x2e, 0xf8, 0x20, 0x82, 0x38, 0x1c, 
+0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 
+0x90, 0xb5, 0x80, 0x23, 0x82, 0x68, 0x1a, 0x40, 0x00, 0x24, 0x00, 0x2a, 
+0x15, 0xd0, 0x4a, 0x68, 0x92, 0x09, 0x12, 0xd3, 0x0b, 0x4a, 0xd3, 0x69, 
+0x01, 0x33, 0xd3, 0x61, 0xcb, 0x68, 0x02, 0x68, 0x9f, 0x18, 0x01, 0x23, 
+0x9b, 0x07, 0x08, 0x3a, 0x1a, 0x43, 0x12, 0x68, 0x00, 0xf0, 0x0e, 0xf8, 
+0x00, 0x28, 0x00, 0xd1, 0x04, 0x48, 0xc0, 0x46, 0xf8, 0x80, 0x20, 0x1c, 
+0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 
+0xff, 0xff, 0x00, 0x00, 0xb0, 0xb5, 0x14, 0x1c, 0x05, 0x1c, 0x0f, 0x1c, 
+0x38, 0x69, 0xb9, 0x68, 0x41, 0x18, 0x38, 0x68, 0xff, 0xf7, 0x53, 0xff, 
+0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 0x39, 0xff, 
+0x04, 0x1c, 0xb8, 0x68, 0x79, 0x69, 0x40, 0x18, 0x69, 0x68, 0x88, 0x42, 
+0x0c, 0xd2, 0x2a, 0x68, 0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, 
+0x05, 0xf9, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 
+0x26, 0xff, 0x04, 0x1c, 0xe0, 0x43, 0x00, 0x04, 0x00, 0x0c, 0xb0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0xc0, 0x08, 
+0x1a, 0xd3, 0xb8, 0x6a, 0xf9, 0x6b, 0x40, 0x18, 0x79, 0x6c, 0x00, 0xf0, 
+0xed, 0xf8, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x0a, 0x48, 0x07, 0xd0, 
+0x20, 0x23, 0xb9, 0x69, 0x19, 0x43, 0xb9, 0x61, 0x01, 0x6b, 0x01, 0x31, 
+0x01, 0x63, 0x07, 0xe0, 0xff, 0x23, 0x01, 0x33, 0xb9, 0x69, 0x19, 0x43, 
+0xb9, 0x61, 0x41, 0x6a, 0x01, 0x31, 0x41, 0x62, 0x00, 0x20, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, 
+0xb8, 0x6b, 0x41, 0x09, 0x1c, 0xd3, 0xc0, 0x08, 0x1a, 0xd3, 0xf8, 0x1d, 
+0x39, 0x30, 0x00, 0x7b, 0x06, 0x28, 0x15, 0xd1, 0x38, 0x1c, 0x00, 0xf0, 
+0x53, 0xf8, 0x01, 0x1c, 0x0a, 0x48, 0x07, 0xd0, 0x40, 0x23, 0xb9, 0x69, 
+0x19, 0x43, 0xb9, 0x61, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, 0x07, 0xe0, 
+0x01, 0x23, 0x9b, 0x02, 0xb9, 0x69, 0x19, 0x43, 
+0xb9, 0x61, 0xc1, 0x6a, 0x01, 0x31, 0xc1, 0x62, 0x00, 0x20, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0xb0, 0xb5, 0x07, 0x1c, 
+0xb8, 0x6b, 0x81, 0x09, 0x2c, 0xd3, 0xc0, 0x08, 0x2a, 0xd3, 0xf8, 0x1d, 
+0x39, 0x30, 0x00, 0x7b, 0x11, 0x28, 0x25, 0xd1, 0xb8, 0x6a, 0x39, 0x6c, 
+0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x06, 0x30, 0x18, 0x43, 0x00, 0x68, 
+0x05, 0x04, 0x2d, 0x0c, 0x0f, 0x4c, 0x11, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 
+0x1f, 0xf8, 0x00, 0x28, 0x0c, 0xd0, 0xa8, 0x42, 0x02, 0xd1, 0x0c, 0x4b, 
+0x98, 0x42, 0x07, 0xd0, 0x80, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 
+0x60, 0x6b, 0x01, 0x30, 0x60, 0x63, 0x07, 0xe0, 0x01, 0x23, 0x5b, 0x02, 
+0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 0xa0, 0x6a, 0x01, 0x30, 0xa0, 0x62, 
+0x00, 0x20, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 
+0xff, 0xff, 0x00, 0x00, 0xf0, 0xb5, 0xff, 0xb0, 0x99, 0xb0, 0x04, 0x1c, 
+0xe0, 0x6b, 0x61, 0x6c, 0x09, 0x18, 0x03, 0xaa, 0x85, 0x18, 0xa3, 0x6a, 
+0x00, 0x20, 0x8a, 0x08, 0x01, 0x32, 0x97, 0x92, 0x07, 0xd0, 0x82, 0x00, 
+0x9f, 0x58, 0x03, 0xae, 0xb7, 0x50, 0x97, 0x9a, 0x01, 0x30, 0x82, 0x42, 
+0xf7, 0xd8, 0x60, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0x04, 0x30, 0x18, 0x43, 
+0x00, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x02, 0xaf, 0x3f, 0x88, 0x03, 0xa8, 
+0xff, 0xf7, 0x87, 0xfe, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 
+0xff, 0xf7, 0x6d, 0xfe, 0x07, 0x1c, 0xe0, 0x6b, 0xa1, 0x6c, 0x40, 0x18, 
+0x61, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x31, 0x19, 0x43, 0x09, 0x68, 
+0xc0, 0x46, 0x01, 0x91, 0x01, 0xa9, 0x09, 0x88, 0x01, 0x31, 0x88, 0x42, 
+0x0c, 0xd2, 0xa2, 0x6a, 0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, 
+0x2f, 0xf8, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xff, 0xf7, 
+0x50, 0xfe, 0x07, 0x1c, 0xa8, 0x89, 0xe9, 0x89, 0x08, 0x18, 0x29, 0x8a, 
+0x08, 0x18, 0x69, 0x8a, 0x08, 0x18, 0x69, 0x7a, 0x09, 0x02, 0x08, 0x18, 
+0xa1, 0x6c, 0x62, 0x6c, 0x89, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, 
+0x12, 0x0a, 0x11, 0x43, 0x09, 0x04, 0x09, 0x0c, 0x09, 0x18, 0x08, 0x0c, 
+0x05, 0xd0, 0x08, 0x04, 0x00, 0x0c, 0x09, 0x0c, 0x41, 0x18, 0x08, 0x0c, 
+0xf9, 0xd1, 0x38, 0x1c, 0xff, 0xf7, 0x2f, 0xfe, 0xc0, 0x43, 0x00, 0x04, 
+0x00, 0x0c, 0x7f, 0xb0, 0x19, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0xb0, 0xb4, 0x00, 0x22, 0x00, 0x29, 0x2e, 0xd0, 0x83, 0x07, 0x9b, 0x0f, 
+0xdc, 0x00, 0x47, 0x18, 0x04, 0x25, 0xef, 0x1b, 0xbf, 0x07, 0xbf, 0x0f, 
+0xff, 0x00, 0x80, 0x08, 0x80, 0x00, 0x59, 0x18, 0x03, 0x31, 0x89, 0x08, 
+0x4d, 0x1e, 0x02, 0xc8, 0xe1, 0x40, 0xa1, 0x40, 0x6b, 0x1e, 0x00, 0x2d, 
+0x09, 0xd0, 0x0c, 0x04, 0x24, 0x0c, 0xa2, 0x18, 0x09, 0x0c, 0x8a, 0x18, 
+0x02, 0xc8, 0x1c, 0x1c, 0x01, 0x3b, 0x00, 0x2c, 0xf5, 0xd1, 0xb9, 0x40, 
+0x08, 0x1c, 0xf8, 0x40, 0x01, 0x04, 0x09, 0x0c, 0x89, 0x18, 0x00, 0x0c, 
+0x42, 0x18, 0x10, 0x0c, 0x05, 0xd0, 0x10, 0x04, 0x00, 0x0c, 0x11, 0x0c, 
+0x42, 0x18, 0x10, 0x0c, 0xf9, 0xd1, 0x10, 0x04, 0x00, 0x0c, 0xb0, 0xbc, 
+0x70, 0x47, 0x00, 0x00, 0x90, 0xb4, 0x00, 0x20, 0x01, 0x27, 0x11, 0x49, 
+0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x53, 0x18, 0x9c, 0x68, 0x01, 0x23, 
+0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x03, 0x1b, 0x0b, 0x8a, 0x58, 
+0x12, 0x03, 0x12, 0x0b, 0x93, 0x42, 0x0c, 0xd1, 
+0x01, 0x30, 0x04, 0x28, 0xec, 0xd3, 0x08, 0x48, 0xc0, 0x6a, 0x01, 0x03, 
+0x09, 0x0b, 0x07, 0x48, 0x00, 0x6f, 0x00, 0x03, 0x00, 0x0b, 0x81, 0x42, 
+0x02, 0xd0, 0x38, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 
+0x28, 0x03, 0x00, 0x80, 0x00, 0x40, 0x14, 0x40, 0xe8, 0x0d, 0x00, 0x80, 
+0x98, 0xb4, 0x14, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x83, 0x00, 0x13, 0x48, 
+0xc0, 0x58, 0x07, 0x03, 0x3f, 0x0b, 0x12, 0x48, 0xc0, 0x58, 0x02, 0x03, 
+0x12, 0x0b, 0x11, 0x48, 0xc0, 0x58, 0x00, 0x03, 0x00, 0x0b, 0x10, 0x4c, 
+0xe4, 0x58, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x9b, 0x00, 
+0xcc, 0x00, 0x01, 0x21, 0x98, 0x42, 0x01, 0xd1, 0x08, 0x1c, 0x09, 0xe0, 
+0x98, 0x42, 0x03, 0xd9, 0x10, 0x1a, 0xda, 0x1b, 0x80, 0x18, 0x00, 0xe0, 
+0x18, 0x1a, 0x84, 0x42, 0xf4, 0xd3, 0x00, 0x20, 0x98, 0xbc, 0x70, 0x47, 
+0x55, 0x55, 0x55, 0x55, 0xa0, 0x03, 0x00, 0x80, 0xa8, 0x03, 0x00, 0x80, 
+0x88, 0x03, 0x00, 0x80, 0x98, 0x03, 0x00, 0x80, 0x80, 0xb4, 0x13, 0x04, 
+0x00, 0xd0, 0x01, 0x3a, 0x80, 0x00, 0x0b, 0x1c, 0x13, 0x49, 0x0f, 0x58, 
+0xc0, 0x46, 0x3b, 0x60, 0x0b, 0x58, 0xc0, 0x46, 0x5a, 0x60, 0x0a, 0x58, 
+0x08, 0x32, 0x10, 0x4b, 0x1b, 0x58, 0x9a, 0x42, 0x01, 0xd3, 0x0f, 0x4a, 
+0x12, 0x58, 0x0f, 0x4b, 0x1f, 0x58, 0x01, 0x23, 0x9b, 0x07, 0x3b, 0x43, 
+0x1b, 0x68, 0x9b, 0x00, 0x17, 0x03, 0x3f, 0x0b, 0x9f, 0x42, 0x06, 0xd1, 
+0x0a, 0x48, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, 0x01, 0x20, 0x80, 0xbc, 
+0x70, 0x47, 0x08, 0x4b, 0x1b, 0x58, 0xc0, 0x46, 0x1a, 0x60, 0x0a, 0x50, 
+0x00, 0x20, 0xf6, 0xe7, 0x88, 0x03, 0x00, 0x80, 0xa8, 0x03, 0x00, 0x80, 
+0xa0, 0x03, 0x00, 0x80, 0x98, 0x03, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
+0x90, 0x03, 0x00, 0x80, 0xff, 0x5f, 0x2d, 0xe9, 0x48, 0xfe, 0xff, 0xeb, 
+0x01, 0xb6, 0xa0, 0xe3, 0x01, 0xb1, 0x8b, 0xe2, 0x02, 0x8a, 0xa0, 0xe3, 
+0x01, 0x7a, 0xa0, 0xe3, 0x01, 0xa9, 0xa0, 0xe3, 0x01, 0x56, 0xa0, 0xe3, 
+0xc8, 0x60, 0x9f, 0xe5, 0xc8, 0x90, 0x9f, 0xe5, 0x14, 0x40, 0x9b, 0xe5, 
+0x00, 0x00, 0x54, 0xe3, 0x2c, 0x00, 0x00, 0x0a, 0x03, 0x0a, 0x14, 0xe3, 
+0x11, 0x00, 0x00, 0x0a, 0x0c, 0x00, 0x96, 0xe5, 0x00, 0x00, 0x50, 0xe3, 
+0x21, 0x00, 0x00, 0x0a, 0x01, 0x0a, 0x14, 0xe3, 0x05, 0x00, 0x00, 0x0a, 
+0x1c, 0x00, 0x96, 0xe5, 0x01, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 
+0x1c, 0x00, 0x85, 0xe5, 0x14, 0x70, 0x85, 0xe5, 0x06, 0x00, 0x00, 0xea, 
+0x02, 0x0a, 0x14, 0xe3, 0x04, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5, 
+0x02, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, 
+0x14, 0x80, 0x85, 0xe5, 0x01, 0x09, 0x14, 0xe3, 0x04, 0x00, 0x00, 0x0a, 
+0x1c, 0x00, 0x96, 0xe5, 0x01, 0x09, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 
+0x1c, 0x00, 0x85, 0xe5, 0x14, 0xa0, 0x85, 0xe5, 0x02, 0x00, 0x14, 0xe3, 
+0x40, 0x00, 0x00, 0x1b, 0x01, 0x00, 0x14, 0xe3, 0x54, 0x00, 0x00, 0x1b, 
+0x02, 0x0b, 0x14, 0xe3, 0x67, 0x00, 0x00, 0x1b, 0x01, 0x0b, 0x14, 0xe3, 
+0x20, 0x00, 0x00, 0x1b, 0x18, 0x00, 0x99, 0xe5, 0x01, 0x00, 0x80, 0xe2, 
+0x18, 0x00, 0x89, 0xe5, 0xd5, 0xff, 0xff, 0xea, 0x1c, 0x00, 0x96, 0xe5, 
+0x01, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, 
+0x14, 0x70, 0x85, 0xe5, 0xe1, 0xff, 0xff, 0xea, 0xff, 0x5f, 0xbd, 0xe8, 
+0x04, 0xf0, 0x5e, 0xe2, 0xe8, 0x0d, 0x00, 0x80, 
+0x08, 0x83, 0x20, 0x40, 0x10, 0x10, 0x1f, 0xe5, 0x14, 0x30, 0x91, 0xe5, 
+0x00, 0x20, 0xc3, 0xe1, 0x14, 0x20, 0x81, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 
+0x0c, 0x20, 0x81, 0xe5, 0x0b, 0x12, 0xa0, 0xe3, 0x00, 0x00, 0x81, 0xe5, 
+0x18, 0x10, 0x9f, 0xe5, 0xb0, 0x24, 0xd1, 0xe1, 0x01, 0x20, 0x82, 0xe2, 
+0xb0, 0x24, 0xc1, 0xe1, 0x3c, 0x20, 0x91, 0xe5, 0x00, 0x00, 0x82, 0xe1, 
+0x3c, 0x00, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xa0, 0x82, 0x20, 0x40, 
+0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x01, 0x0b, 0xa0, 0xe3, 
+0x01, 0x16, 0xa0, 0xe3, 0x14, 0x00, 0x81, 0xe5, 0x00, 0x1a, 0x81, 0xe1, 
+0x24, 0x20, 0x91, 0xe5, 0x70, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 
+0x24, 0x20, 0x80, 0xe5, 0x28, 0x10, 0x91, 0xe5, 0x00, 0x00, 0x00, 0x00, 
+0x28, 0x10, 0x80, 0xe5, 0x2c, 0x20, 0x90, 0xe5, 0x01, 0x20, 0x82, 0xe2, 
+0x2c, 0x20, 0x80, 0xe5, 0x3f, 0x00, 0x01, 0xe2, 0x3f, 0x00, 0x50, 0xe3, 
+0x1e, 0xff, 0x2f, 0x11, 0x18, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 
+0x01, 0x10, 0x81, 0xe2, 0x00, 0x10, 0x80, 0xe5, 0x02, 0x18, 0xa0, 0xe3, 
+0x0b, 0x02, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
+0xb0, 0x03, 0x00, 0x80, 0x01, 0x06, 0xa0, 0xe3, 0x01, 0x01, 0x80, 0xe2, 
+0x00, 0x10, 0x90, 0xe5, 0x01, 0x08, 0x11, 0xe3, 0x0b, 0x10, 0xa0, 0xe3, 
+0x02, 0x19, 0x81, 0xe2, 0x05, 0x00, 0x00, 0x1a, 0x00, 0x20, 0x90, 0xe5, 
+0x42, 0x28, 0xb0, 0xe1, 0x05, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x90, 0xe5, 
+0x02, 0x0c, 0x10, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x06, 0x07, 0xa0, 0xe3, 
+0x4c, 0x11, 0x80, 0xe5, 0x03, 0x00, 0x00, 0xea, 0x0c, 0x00, 0x9f, 0xe5, 
+0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x80, 0xe5, 0xff, 0xff, 0xff, 0xea, 
+0xfe, 0xff, 0xff, 0xea, 0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0xa0, 0xe3, 
+0x01, 0x01, 0x80, 0xe2, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x08, 0x11, 0xe3, 
+0x0c, 0x10, 0xa0, 0xe3, 0x02, 0x19, 0x81, 0xe2, 0x05, 0x00, 0x00, 0x1a, 
+0x00, 0x20, 0x90, 0xe5, 0x42, 0x28, 0xb0, 0xe1, 0x05, 0x00, 0x00, 0x1a, 
+0x00, 0x00, 0x90, 0xe5, 0x02, 0x0c, 0x10, 0xe3, 0x02, 0x00, 0x00, 0x0a, 
+0x06, 0x07, 0xa0, 0xe3, 0x4c, 0x11, 0x80, 0xe5, 0x03, 0x00, 0x00, 0xea, 
+0x4c, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x80, 0xe5, 
+0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x02, 0x1b, 0xa0, 0xe3, 
+0x01, 0x06, 0xa0, 0xe3, 0x14, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
+0x80, 0x21, 0x1f, 0xe5, 0x14, 0x30, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x30, 0x80, 0xe5, 0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x81, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x14, 0x10, 0x82, 0xe5, 
+0x01, 0x06, 0xa0, 0xe3, 0x1c, 0x10, 0x82, 0xe5, 0x0c, 0x10, 0x80, 0xe5, 
+0x1c, 0x10, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x80, 0xe5, 
+0x1e, 0xff, 0x2f, 0xe1, 0xc0, 0x21, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 
+0x1c, 0x10, 0x82, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 0x14, 0x00, 0x82, 0xe5, 
+0x0c, 0x00, 0x81, 0xe5, 0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 
+0x1c, 0x00, 0x81, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x0f, 0x1c, 
+0x38, 0x1c, 0x00, 0xf0, 0x17, 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c, 
+0x00, 0xf0, 0x76, 0xf8, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x80, 0xb5, 0x0f, 0x1c, 0x38, 0x1c, 0x00, 0xf0, 
+0x09, 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x68, 0xf8, 
+0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb4, 0x07, 0x68, 
+0x3a, 0x78, 0xd2, 0x07, 0xd2, 0x0f, 0x00, 0x24, 0x00, 0x2a, 0x03, 0xd0, 
+0xff, 0x22, 0x01, 0x32, 0x42, 0x60, 0x00, 0xe0, 0x44, 0x60, 0x3a, 0x7b, 
+0x7b, 0x7b, 0x1b, 0x02, 0x1a, 0x43, 0x81, 0x2a, 0x08, 0xd1, 0x01, 0x23, 
+0x5b, 0x02, 0x42, 0x68, 0x1a, 0x43, 0x42, 0x60, 0x04, 0x22, 0xbf, 0x18, 
+0x82, 0x60, 0x00, 0xe0, 0x84, 0x60, 0x3a, 0x7b, 0x7b, 0x7b, 0x1b, 0x02, 
+0x1a, 0x43, 0x08, 0x2a, 0x06, 0xd1, 0x06, 0x23, 0x41, 0x68, 0x19, 0x43, 
+0x41, 0x60, 0x81, 0x68, 0x0e, 0x31, 0x2c, 0xe0, 0x13, 0x02, 0x12, 0x0a, 
+0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x2e, 0x3a, 
+0x16, 0x4b, 0x9a, 0x42, 0x24, 0xd8, 0x01, 0x25, 0x42, 0x68, 0x15, 0x43, 
+0x45, 0x60, 0xba, 0x7b, 0xfb, 0x7b, 0x1b, 0x02, 0x1a, 0x43, 0x12, 0x4b, 
+0x9a, 0x42, 0x19, 0xd1, 0xfb, 0x1d, 0x09, 0x33, 0x44, 0xcb, 0x9b, 0x07, 
+0xdb, 0x0e, 0xda, 0x40, 0x5b, 0x42, 0x20, 0x33, 0x9e, 0x40, 0x16, 0x43, 
+0x03, 0x2e, 0x0f, 0xd1, 0x39, 0x7d, 0x7b, 0x7d, 0x1b, 0x02, 0x19, 0x43, 
+0x08, 0x29, 0x07, 0xd1, 0x04, 0x21, 0x29, 0x43, 0x41, 0x60, 0x81, 0x68, 
+0x16, 0x31, 0x81, 0x60, 0x01, 0x21, 0x01, 0xe0, 0x00, 0x21, 0x84, 0x60, 
+0x08, 0x1c, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xae, 0x05, 0x00, 0x00, 
+0xaa, 0xaa, 0x00, 0x00, 0x80, 0xb4, 0x42, 0x68, 0xd1, 0x08, 0x3f, 0xd3, 
+0x01, 0x68, 0x83, 0x68, 0x59, 0x18, 0x02, 0x39, 0x8f, 0x78, 0x3f, 0x07, 
+0x3f, 0x0f, 0x05, 0x2f, 0x03, 0xd1, 0xda, 0x1d, 0x0d, 0x32, 0xc2, 0x60, 
+0x05, 0xe0, 0xbf, 0x00, 0xdb, 0x19, 0xc3, 0x60, 0x08, 0x23, 0x1a, 0x43, 
+0x42, 0x60, 0x8a, 0x78, 0x12, 0x07, 0x12, 0x0f, 0x92, 0x00, 0x02, 0x61, 
+0x0a, 0x79, 0x4b, 0x79, 0x1b, 0x02, 0x1a, 0x43, 0x13, 0x02, 0x12, 0x0a, 
+0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x42, 0x61, 
+0xca, 0x7a, 0x06, 0x2a, 0x03, 0xd1, 0x10, 0x23, 0x42, 0x68, 0x1a, 0x43, 
+0x10, 0xe0, 0x11, 0x2a, 0x03, 0xd1, 0x20, 0x23, 0x42, 0x68, 0x1a, 0x43, 
+0x0a, 0xe0, 0x33, 0x2a, 0x03, 0xd1, 0x40, 0x23, 0x42, 0x68, 0x1a, 0x43, 
+0x04, 0xe0, 0x32, 0x2a, 0x03, 0xd1, 0x80, 0x23, 0x42, 0x68, 0x1a, 0x43, 
+0x42, 0x60, 0xc9, 0x7a, 0xc0, 0x46, 0x01, 0x76, 0x80, 0xbc, 0x70, 0x47, 
+0x0a, 0x78, 0xc0, 0x46, 0x02, 0x60, 0x4b, 0x78, 0x1b, 0x02, 0x1a, 0x43, 
+0x02, 0x60, 0x8b, 0x78, 0x1b, 0x04, 0x1a, 0x43, 0x02, 0x60, 0xc9, 0x78, 
+0x09, 0x06, 0x11, 0x43, 0x01, 0x60, 0x70, 0x47, 0x80, 0xb5, 0x07, 0x1c, 
+0x48, 0x68, 0x80, 0x09, 0x26, 0xd3, 0xb8, 0x6a, 0xc9, 0x68, 0x40, 0x18, 
+0x01, 0x23, 0x9b, 0x07, 0x02, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 
+0x00, 0x0c, 0x11, 0x23, 0x9b, 0x02, 0x98, 0x42, 0x18, 0xd1, 0x78, 0x6a, 
+0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62, 0x38, 0x6b, 0x02, 0xf0, 0xb0, 0xf8, 
+0x38, 0x1c, 0x01, 0xf0, 0x6d, 0xfd, 0x01, 0x20, 0x07, 0x49, 0xc0, 0x46, 
+0xc8, 0x72, 0x07, 0x49, 0x4a, 0x6c, 0x12, 0x18, 0x4a, 0x64, 0x06, 0x49, 
+0x8a, 0x6d, 0x12, 0x18, 0x8a, 0x65, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0x20, 0xfa, 0xe7, 0x98, 0x19, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, 
+0x10, 0x2a, 0x00, 0x80, 0x81, 0x07, 0x19, 0xd0, 0x80, 0x08, 0x80, 0x00, 
+0x01, 0x23, 0x9b, 0x07, 0x01, 0x1d, 0x18, 0x43, 
+0x00, 0x68, 0x19, 0x43, 0x09, 0x68, 0x02, 0x02, 0x12, 0x0e, 0x12, 0x06, 
+0x00, 0x0a, 0xff, 0x23, 0x1b, 0x04, 0x18, 0x40, 0x10, 0x43, 0x0a, 0x0a, 
+0x12, 0x06, 0x12, 0x0e, 0x10, 0x43, 0x09, 0x02, 0x1b, 0x0a, 0x19, 0x40, 
+0x08, 0x43, 0x70, 0x47, 0x01, 0x23, 0x9b, 0x07, 0x18, 0x43, 0x00, 0x68, 
+0x01, 0x06, 0x02, 0x02, 0xff, 0x23, 0x1b, 0x04, 0x1a, 0x40, 0x11, 0x43, 
+0x02, 0x0a, 0x1b, 0x0a, 0x1a, 0x40, 0x11, 0x43, 0x00, 0x0e, 0x08, 0x43, 
+0xed, 0xe7, 0x00, 0x00, 0xf0, 0xb5, 0x04, 0x23, 0x81, 0x6b, 0x19, 0x40, 
+0x00, 0x22, 0x00, 0x29, 0x46, 0xd0, 0xc7, 0x1d, 0x39, 0x37, 0x39, 0x7b, 
+0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x3f, 0xd1, 0x01, 0x6b, 0xc0, 0x46, 
+0x4a, 0x65, 0xc4, 0x1d, 0x2d, 0x34, 0xcd, 0x1d, 0x2d, 0x35, 0x00, 0x22, 
+0x93, 0x00, 0xe6, 0x58, 0xc0, 0x46, 0xee, 0x50, 0x01, 0x32, 0x07, 0x2a, 
+0xf8, 0xd3, 0x82, 0x6a, 0xc0, 0x46, 0x4a, 0x63, 0x82, 0x6a, 0xc0, 0x46, 
+0x8a, 0x62, 0x7a, 0x8b, 0xcb, 0x1d, 0x39, 0x33, 0x5a, 0x83, 0x40, 0x6a, 
+0xc0, 0x46, 0x48, 0x62, 0x12, 0x48, 0x01, 0x27, 0x42, 0x68, 0x00, 0x2a, 
+0x10, 0xd1, 0xc2, 0x68, 0x00, 0x2a, 0x13, 0xd1, 0x42, 0x69, 0x00, 0x2a, 
+0x0d, 0xd1, 0x01, 0x61, 0xc1, 0x60, 0x01, 0x6a, 0x02, 0x29, 0x02, 0xd3, 
+0x20, 0x30, 0x07, 0x71, 0x0c, 0xe0, 0x00, 0xf0, 0x13, 0xf8, 0x09, 0xe0, 
+0xc2, 0x68, 0x00, 0x2a, 0x02, 0xd1, 0x01, 0x61, 0xc1, 0x60, 0x03, 0xe0, 
+0x02, 0x69, 0xc0, 0x46, 0x51, 0x65, 0x01, 0x61, 0x38, 0x1c, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x10, 0x1c, 0xfa, 0xe7, 0xec, 0x05, 0x00, 0x80, 
+0x80, 0xb5, 0x1e, 0x49, 0x00, 0x22, 0xcb, 0x68, 0x00, 0x2b, 0x34, 0xd0, 
+0xc8, 0x1d, 0xf9, 0x30, 0x83, 0x62, 0xcb, 0x68, 0x9b, 0x6a, 0xc0, 0x46, 
+0xc3, 0x62, 0xcf, 0x69, 0x7b, 0x00, 0xdf, 0x19, 0x7f, 0x02, 0x17, 0x4b, 
+0xff, 0x18, 0xff, 0x37, 0x65, 0x37, 0x83, 0x63, 0x07, 0x63, 0xcb, 0x1d, 
+0xff, 0x33, 0x5a, 0x33, 0x1a, 0x72, 0xcb, 0x69, 0x00, 0x2b, 0x01, 0xd0, 
+0xca, 0x61, 0x01, 0xe0, 0x01, 0x23, 0xcb, 0x61, 0x0f, 0x1c, 0xc9, 0x68, 
+0x49, 0x6a, 0x09, 0x89, 0x01, 0x31, 0x41, 0x63, 0xf8, 0x1d, 0xff, 0x30, 
+0x3a, 0x30, 0x42, 0x60, 0x02, 0x82, 0x82, 0x60, 0xc2, 0x60, 0x38, 0x1c, 
+0x00, 0xf0, 0xc4, 0xfa, 0x38, 0x6a, 0x01, 0x30, 0x38, 0x62, 0x38, 0x1c, 
+0x00, 0xf0, 0x0a, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x10, 0x1c, 
+0xfa, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0x1c, 0xad, 0x20, 0x40, 
+0xf0, 0xb5, 0x07, 0x1c, 0xf9, 0x1d, 0xf9, 0x31, 0x88, 0x6a, 0xc2, 0x1d, 
+0x2d, 0x32, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x32, 0x1a, 0x43, 0xc8, 0x6a, 
+0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x80, 0x18, 0x82, 0x79, 0xc3, 0x79, 
+0x1b, 0x02, 0x1a, 0x43, 0x13, 0x02, 0x12, 0x0a, 0x12, 0x06, 0x12, 0x0e, 
+0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x02, 0x38, 0x92, 0x04, 0x92, 0x0c, 
+0x00, 0x26, 0x25, 0x4d, 0xec, 0x1d, 0xff, 0x34, 0x3a, 0x34, 0x00, 0x2a, 
+0x04, 0xd0, 0x20, 0x8a, 0x01, 0x23, 0x9b, 0x02, 0x18, 0x43, 0x2b, 0xe0, 
+0x01, 0x23, 0x9b, 0x07, 0xc2, 0x1d, 0x0d, 0x32, 0x1a, 0x43, 0x12, 0x68, 
+0x12, 0x04, 0x12, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 
+0x10, 0x43, 0x03, 0x1c, 0xf8, 0x1d, 0xff, 0x30, 0x4a, 0x30, 0x82, 0x78, 
+0xc8, 0x6b, 0x19, 0x1c, 0x01, 0xf0, 0xd8, 0xff, 0x00, 0x28, 0x04, 0xda, 
+0x20, 0x8a, 0xff, 0x23, 0x01, 0x33, 0x18, 0x43, 
+0x0e, 0xe0, 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x08, 0x60, 0x01, 0x04, 
+0x09, 0x0c, 0x38, 0x1c, 0x00, 0xf0, 0x1c, 0xf8, 0x00, 0x28, 0x14, 0xd1, 
+0x20, 0x8a, 0x01, 0x23, 0x5b, 0x02, 0x18, 0x43, 0x20, 0x82, 0x21, 0x8a, 
+0x38, 0x1c, 0x00, 0xf0, 0x98, 0xfb, 0xe8, 0x68, 0x01, 0x23, 0x9b, 0x07, 
+0x54, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xe8, 0x60, 0x30, 0x1c, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 0xfa, 0xe7, 0x00, 0x00, 
+0xec, 0x05, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c, 0xfc, 0x1d, 0xf9, 0x34, 
+0xa0, 0x6b, 0xa6, 0x6a, 0xc5, 0x1d, 0x0d, 0x35, 0x33, 0x48, 0xc0, 0x6a, 
+0x4b, 0x00, 0x59, 0x18, 0x49, 0x01, 0x42, 0x18, 0x01, 0x20, 0x80, 0x07, 
+0x10, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x90, 0x01, 0x23, 
+0x9b, 0x07, 0xd0, 0x1d, 0x05, 0x30, 0x18, 0x43, 0x00, 0x68, 0x38, 0x1c, 
+0x29, 0x1c, 0x00, 0xf0, 0xb8, 0xfa, 0xa8, 0x88, 0x40, 0x07, 0x01, 0xd0, 
+0x00, 0x20, 0x47, 0xe0, 0x00, 0x98, 0x01, 0x28, 0x25, 0xd1, 0xe0, 0x6a, 
+0xf1, 0x6b, 0x40, 0x18, 0x71, 0x6c, 0xfa, 0x1d, 0xcd, 0x32, 0x01, 0xf0, 
+0x2b, 0xf9, 0xfa, 0x1d, 0xff, 0x32, 0x3a, 0x32, 0xe0, 0x6a, 0x51, 0x69, 
+0x40, 0x18, 0xc3, 0x1d, 0x03, 0x33, 0x00, 0x20, 0x81, 0x00, 0x5e, 0x58, 
+0xc9, 0x19, 0xff, 0x31, 0x01, 0x31, 0x4e, 0x61, 0x01, 0x30, 0x04, 0x28, 
+0xf6, 0xd3, 0xe0, 0x6a, 0x51, 0x69, 0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, 
+0x00, 0x20, 0x00, 0x22, 0x43, 0x00, 0xca, 0x52, 0x01, 0x30, 0x06, 0x28, 
+0xfa, 0xd3, 0x29, 0x1c, 0x11, 0x4a, 0x00, 0x20, 0xff, 0xf7, 0xd4, 0xfb, 
+0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43, 0x01, 0x20, 0x21, 0x6b, 
+0xff, 0xf7, 0xcc, 0xfb, 0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43, 
+0x00, 0x20, 0xe1, 0x6a, 0xff, 0xf7, 0xc4, 0xfb, 0xa1, 0x6b, 0x08, 0x4a, 
+0x01, 0x20, 0xff, 0xf7, 0xbf, 0xfb, 0x03, 0x20, 0x06, 0x49, 0xc0, 0x46, 
+0x48, 0x62, 0x01, 0x20, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xc8, 0x29, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00, 0x14, 0x00, 0x0f, 0x00, 
+0xec, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x8d, 0xb0, 0x00, 0x20, 0xb5, 0x4a, 
+0xd5, 0x1d, 0xf9, 0x35, 0x68, 0x62, 0x01, 0x20, 0x00, 0x05, 0xb3, 0x49, 
+0xc0, 0x46, 0x08, 0x60, 0xa8, 0x6a, 0xc4, 0x1d, 0x2d, 0x34, 0xb1, 0x48, 
+0xc0, 0x6a, 0xd7, 0x1d, 0xff, 0x37, 0x3a, 0x37, 0x39, 0x68, 0x4b, 0x00, 
+0x59, 0x18, 0x49, 0x01, 0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 
+0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x08, 0x30, 0x18, 0x43, 0x00, 0x68, 
+0xc0, 0x46, 0x09, 0x90, 0xff, 0x23, 0x1b, 0x02, 0x18, 0x40, 0x00, 0x0a, 
+0x0a, 0x90, 0x0a, 0x98, 0xa4, 0x4e, 0x01, 0x28, 0x59, 0xd1, 0x28, 0x6b, 
+0xa2, 0x68, 0x80, 0x18, 0xa2, 0x4a, 0x21, 0x69, 0x09, 0x04, 0x09, 0x0c, 
+0x01, 0xf0, 0x1e, 0xf9, 0x28, 0x6b, 0x79, 0x69, 0x40, 0x18, 0xc1, 0x1d, 
+0x05, 0x31, 0x00, 0x20, 0x82, 0x00, 0x98, 0x4b, 0xd3, 0x18, 0xff, 0x33, 
+0x01, 0x33, 0x5b, 0x69, 0xc0, 0x46, 0x8b, 0x50, 0x01, 0x30, 0x04, 0x28, 
+0xf4, 0xd3, 0x00, 0x20, 0x31, 0x1c, 0x82, 0x00, 0x56, 0x18, 0x01, 0x23, 
+0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x04, 0xae, 0xb3, 0x50, 0x01, 0x30, 
+0x03, 0x28, 0xf4, 0xd3, 0x00, 0x20, 0x08, 0x90, 0x90, 0x49, 0x42, 0x00, 
+0x8b, 0x5a, 0xb2, 0x5a, 0x93, 0x42, 0x13, 0xd0, 0x8e, 0x48, 0xc1, 0x89, 
+0x01, 0x31, 0xc1, 0x81, 0xb8, 0x68, 0x00, 0x28, 
+0x03, 0xd1, 0x38, 0x8a, 0x10, 0x23, 0x18, 0x43, 0x71, 0xe0, 0x38, 0x8a, 
+0x40, 0x23, 0x18, 0x43, 0x6d, 0xe0, 0x00, 0xf0, 0x11, 0xf9, 0x01, 0xf0, 
+0x47, 0xff, 0xf5, 0xe0, 0x01, 0x30, 0x06, 0x28, 0xe3, 0xd3, 0x08, 0x98, 
+0x00, 0x28, 0x0c, 0xd1, 0xb8, 0x68, 0x41, 0x1c, 0xb9, 0x60, 0x00, 0x28, 
+0x03, 0xd1, 0x38, 0x8a, 0x01, 0x23, 0x18, 0x43, 0x02, 0xe0, 0x38, 0x8a, 
+0x04, 0x23, 0x18, 0x43, 0x38, 0x82, 0x78, 0x68, 0x01, 0x30, 0x78, 0x60, 
+0x62, 0xe0, 0x0a, 0x98, 0x02, 0x28, 0x5f, 0xd1, 0x09, 0x98, 0x40, 0x0c, 
+0x73, 0xd3, 0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x01, 0x30, 0x18, 0x43, 
+0x00, 0x68, 0xe1, 0x1d, 0x0d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x40, 0x18, 
+0x0c, 0x38, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x21, 0x8a, 0x00, 0x6b, 0x4b, 
+0xd6, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x04, 0xae, 
+0xb3, 0x50, 0x01, 0x31, 0x03, 0x29, 0xf3, 0xd3, 0x00, 0x21, 0x83, 0x1e, 
+0x0c, 0x93, 0x68, 0x4a, 0x16, 0x6b, 0xc0, 0x46, 0x0b, 0x96, 0x8a, 0x00, 
+0x0c, 0x9b, 0x9b, 0x18, 0x0b, 0x9e, 0x9e, 0x19, 0x01, 0x23, 0x9b, 0x07, 
+0x33, 0x43, 0x1b, 0x68, 0x6e, 0x46, 0xb3, 0x50, 0x01, 0x31, 0x04, 0x29, 
+0xf1, 0xd3, 0x69, 0x46, 0x8b, 0x1c, 0x07, 0x93, 0x00, 0x21, 0x08, 0x91, 
+0x04, 0xae, 0x4a, 0x00, 0x07, 0x9b, 0x9b, 0x5a, 0xb2, 0x5a, 0x93, 0x42, 
+0x11, 0xd0, 0x58, 0x48, 0xc1, 0x89, 0x01, 0x31, 0xc1, 0x81, 0xf8, 0x68, 
+0x41, 0x1c, 0xf9, 0x60, 0x00, 0x28, 0x03, 0xd1, 0x38, 0x8a, 0x20, 0x23, 
+0x18, 0x43, 0x02, 0xe0, 0x38, 0x8a, 0x80, 0x23, 0x18, 0x43, 0x38, 0x82, 
+0x8f, 0xe7, 0x01, 0x31, 0x06, 0x29, 0xe4, 0xd3, 0x08, 0x99, 0x00, 0x29, 
+0x0d, 0xd1, 0xf9, 0x68, 0x4a, 0x1c, 0xfa, 0x60, 0x00, 0x29, 0x04, 0xd1, 
+0x39, 0x8a, 0x02, 0x23, 0x19, 0x43, 0x03, 0xe0, 0x0c, 0xe0, 0x39, 0x8a, 
+0x08, 0x23, 0x19, 0x43, 0x39, 0x82, 0x29, 0x6b, 0x08, 0x18, 0x01, 0x23, 
+0x9b, 0x07, 0x01, 0x38, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0x20, 0x76, 
+0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x11, 0x30, 0x18, 0x43, 0x00, 0x68, 
+0x01, 0x06, 0x09, 0x0e, 0x00, 0xe0, 0x19, 0xe0, 0x35, 0x48, 0x2a, 0x6b, 
+0xc0, 0x46, 0xea, 0x62, 0x04, 0x29, 0x4f, 0xd1, 0x01, 0x21, 0xc6, 0x1d, 
+0xff, 0x36, 0x5a, 0x36, 0x31, 0x72, 0x0a, 0x99, 0x02, 0x29, 0x1e, 0xd1, 
+0x09, 0x99, 0x09, 0x0e, 0x49, 0x06, 0x1a, 0xd1, 0xe1, 0x1d, 0x05, 0x31, 
+0x19, 0x43, 0x09, 0x68, 0x09, 0x06, 0x09, 0x0e, 0x08, 0x39, 0x1a, 0xe0, 
+0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x01, 0x30, 0x18, 0x43, 0x00, 0x68, 
+0xe1, 0x1d, 0x0d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x40, 0x18, 0x00, 0x04, 
+0x00, 0x0c, 0xf9, 0x68, 0x4a, 0x1c, 0xfa, 0x60, 0x00, 0x29, 0xbc, 0xd1, 
+0xb6, 0xe7, 0x01, 0x23, 0x9b, 0x07, 0xe1, 0x1d, 0x05, 0x31, 0x19, 0x43, 
+0x09, 0x68, 0x09, 0x06, 0x09, 0x0e, 0xa1, 0x60, 0xe8, 0x6a, 0xc0, 0x46, 
+0x20, 0x60, 0x20, 0x1c, 0xff, 0xf7, 0x92, 0xfc, 0x20, 0x7e, 0x33, 0x28, 
+0x01, 0xd0, 0x32, 0x28, 0x11, 0xd1, 0x01, 0x21, 0x14, 0x4c, 0xc0, 0x46, 
+0xf9, 0x60, 0xb9, 0x60, 0x20, 0x1c, 0x00, 0xf0, 0x85, 0xf8, 0x28, 0x6b, 
+0xa9, 0x6a, 0xc0, 0x46, 0x88, 0x62, 0x20, 0x1c, 0xff, 0xf7, 0xca, 0xfd, 
+0x00, 0x28, 0x11, 0xd1, 0x0e, 0xe0, 0x00, 0x20, 0x30, 0x72, 0x11, 0xe0, 
+0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x0d, 0xd1, 0x07, 0x1c, 0x00, 0xf0, 
+0x71, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0xba, 0xfd, 
+0x00, 0x28, 0x01, 0xd1, 0x01, 0xf0, 0x50, 0xfe, 0x0d, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0xf0, 0x12, 0xf8, 0xf6, 0xe7, 0x00, 0x00, 
+0xec, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0xc8, 0x29, 0x00, 0x80, 
+0x1c, 0xad, 0x20, 0x40, 0xc0, 0x06, 0x00, 0x80, 0x02, 0x07, 0x00, 0x80, 
+0x78, 0x2a, 0x00, 0x80, 0xec, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x25, 0x48, 
+0x41, 0x68, 0x01, 0x31, 0x41, 0x60, 0x24, 0x4f, 0xf9, 0x1d, 0xf9, 0x31, 
+0x00, 0x24, 0x88, 0x6a, 0xfa, 0x68, 0xc0, 0x46, 0x94, 0x61, 0x04, 0x22, 
+0xfb, 0x68, 0xc0, 0x46, 0xda, 0x60, 0x10, 0x22, 0xfb, 0x68, 0xc0, 0x46, 
+0x9a, 0x61, 0xfa, 0x1d, 0xff, 0x32, 0x5a, 0x32, 0x13, 0x7a, 0x1b, 0x4a, 
+0x00, 0x2b, 0x0b, 0xd0, 0x15, 0x8a, 0x2e, 0x0a, 0x36, 0x02, 0x33, 0x23, 
+0x2b, 0x40, 0x9b, 0x00, 0x1e, 0x43, 0xcc, 0x23, 0x2b, 0x40, 0x9b, 0x08, 
+0x33, 0x43, 0x13, 0x82, 0x12, 0x8a, 0xfb, 0x68, 0xc0, 0x46, 0xda, 0x83, 
+0x4a, 0x6b, 0xfb, 0x68, 0xc0, 0x46, 0xda, 0x81, 0x0a, 0x6b, 0xc0, 0x46, 
+0x82, 0x62, 0xc4, 0x62, 0xc3, 0x1d, 0x39, 0x33, 0x4a, 0x6b, 0xc0, 0x46, 
+0x5a, 0x83, 0x04, 0x23, 0x02, 0x68, 0x1a, 0x43, 0x02, 0x60, 0x88, 0x6a, 
+0x01, 0xf0, 0x14, 0xfa, 0xf8, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x54, 0x30, 
+0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xf8, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 
+0x2c, 0x07, 0x00, 0x80, 0x80, 0xb5, 0xc1, 0x1d, 0xf9, 0x31, 0x8a, 0x6a, 
+0x01, 0x23, 0x9b, 0x07, 0xd1, 0x1d, 0x45, 0x31, 0x19, 0x43, 0x09, 0x68, 
+0x0b, 0x06, 0x1b, 0x0e, 0x01, 0x27, 0xc1, 0x1d, 0xff, 0x31, 0x4a, 0x31, 
+0x33, 0x2b, 0x05, 0xd1, 0x8b, 0x70, 0x01, 0x1c, 0x10, 0x1c, 0x00, 0xf0, 
+0x0f, 0xf8, 0x06, 0xe0, 0x32, 0x2b, 0x08, 0xd1, 0x8b, 0x70, 0x01, 0x1c, 
+0x10, 0x1c, 0x00, 0xf0, 0x3c, 0xf8, 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x20, 0x88, 0x70, 0xf9, 0xe7, 0x90, 0xb4, 0xca, 0x1d, 
+0xf9, 0x32, 0x33, 0x27, 0xcc, 0x1d, 0xff, 0x34, 0x4a, 0x34, 0xd3, 0x6a, 
+0xc0, 0x46, 0xa7, 0x70, 0xff, 0x31, 0x41, 0x31, 0x07, 0x6c, 0xc0, 0x46, 
+0x4f, 0x61, 0xfb, 0x18, 0x39, 0x1c, 0x9f, 0x1e, 0x01, 0x23, 0x9b, 0x07, 
+0xfc, 0x1c, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x9b, 0x00, 
+0x1b, 0x04, 0x1b, 0x0c, 0xc9, 0x18, 0x08, 0x31, 0x01, 0x64, 0x01, 0x23, 
+0x9b, 0x07, 0xb9, 0x1c, 0x19, 0x43, 0x09, 0x68, 0x34, 0x30, 0x01, 0x76, 
+0xf8, 0x1d, 0x01, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0xb9, 0x1d, 
+0x19, 0x43, 0xd0, 0x63, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x43, 
+0xd0, 0x63, 0x90, 0xbc, 0x70, 0x47, 0xb0, 0xb5, 0xca, 0x1d, 0xf9, 0x32, 
+0xc5, 0x1d, 0x2d, 0x35, 0x32, 0x20, 0xcf, 0x1d, 0xff, 0x37, 0x4a, 0x37, 
+0xd3, 0x6a, 0xc0, 0x46, 0xb8, 0x70, 0xcc, 0x1d, 0xff, 0x34, 0x3a, 0x34, 
+0xe8, 0x68, 0xc0, 0x46, 0x60, 0x61, 0x10, 0x30, 0xe8, 0x60, 0x60, 0x69, 
+0xc0, 0x18, 0x87, 0x1e, 0x01, 0x23, 0x9b, 0x07, 0x38, 0x1d, 0x18, 0x43, 
+0x00, 0x68, 0x00, 0x04, 0xb9, 0x1c, 0x19, 0x43, 0xd0, 0x63, 0x09, 0x68, 
+0x09, 0x04, 0x09, 0x0c, 0x08, 0x43, 0xd0, 0x63, 0xf8, 0x1d, 0x03, 0x30, 
+0xff, 0xf7, 0x06, 0xfc, 0x20, 0x62, 0xf8, 0x1d, 0x07, 0x30, 0xff, 0xf7, 
+0x01, 0xfc, 0x60, 0x62, 0x00, 0x20, 0x28, 0x76, 0xb0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0xf7, 0xb5, 0x81, 0xb0, 0x01, 0x98, 
+0xc7, 0x1d, 0xf9, 0x37, 0xb8, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 
+0x05, 0x34, 0x23, 0x43, 0x1c, 0x68, 0xff, 0x23, 0xfe, 0x33, 0x23, 0x40, 
+0x7f, 0x6b, 0x3f, 0x04, 0x3b, 0x43, 0x0b, 0x60, 0x34, 0x30, 0x1c, 0x1c, 
+0x80, 0x23, 0x23, 0x40, 0x01, 0x9f, 0xff, 0x37, 0x41, 0x37, 0x00, 0x2b, 
+0x3c, 0xd0, 0x0c, 0x23, 0x00, 0x93, 0x00, 0x23, 0x9d, 0x00, 0xae, 0x18, 
+0x36, 0x69, 0x6d, 0x18, 0x6e, 0x61, 0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3, 
+0x00, 0x23, 0x9d, 0x00, 0xae, 0x18, 0x76, 0x6a, 0x6d, 0x18, 0xae, 0x62, 
+0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3, 0x01, 0x9b, 0xff, 0x33, 0x51, 0x33, 
+0x9b, 0x78, 0x33, 0x2b, 0x0e, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0xc5, 0x1d, 
+0x01, 0x35, 0x2b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x4b, 0x81, 0x01, 0x23, 
+0x9b, 0x07, 0xc5, 0x1d, 0x0d, 0x35, 0x2b, 0x43, 0x1b, 0x68, 0x16, 0xe0, 
+0x7b, 0x69, 0xc0, 0x46, 0x4b, 0x81, 0x01, 0x23, 0x9b, 0x07, 0xc5, 0x1d, 
+0x0d, 0x35, 0x2b, 0x43, 0x1b, 0x68, 0x7d, 0x69, 0x5d, 0x1b, 0x01, 0x23, 
+0x9b, 0x07, 0xc6, 0x1d, 0x01, 0x36, 0x33, 0x43, 0x1b, 0x68, 0xeb, 0x18, 
+0x0c, 0x3b, 0x02, 0xe0, 0x00, 0x23, 0x00, 0x93, 0x4b, 0x81, 0xcb, 0x80, 
+0x63, 0x09, 0x49, 0xd3, 0x01, 0x23, 0x9b, 0x07, 0xc4, 0x1d, 0x05, 0x34, 
+0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x0b, 0x81, 0x01, 0x23, 0x9b, 0x07, 
+0xc4, 0x1d, 0x0d, 0x34, 0x23, 0x43, 0x1b, 0x68, 0x0c, 0x89, 0x1b, 0x1b, 
+0x00, 0x9c, 0x1c, 0x1b, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x30, 0x18, 0x43, 
+0x00, 0x68, 0x20, 0x18, 0x88, 0x80, 0x38, 0x6a, 0x04, 0x0e, 0xff, 0x23, 
+0x1b, 0x04, 0x03, 0x40, 0x1b, 0x0a, 0x1c, 0x43, 0xff, 0x23, 0x1b, 0x02, 
+0x03, 0x40, 0x1b, 0x02, 0x23, 0x43, 0x00, 0x06, 0x18, 0x43, 0xc8, 0x60, 
+0x78, 0x6a, 0x07, 0x0e, 0xff, 0x23, 0x1b, 0x04, 0x03, 0x40, 0x1b, 0x0a, 
+0x1f, 0x43, 0xff, 0x23, 0x1b, 0x02, 0x03, 0x40, 0x1b, 0x02, 0x3b, 0x43, 
+0x00, 0x06, 0x18, 0x43, 0x08, 0x61, 0xd0, 0x6b, 0xc0, 0x46, 0xc8, 0x63, 
+0x90, 0x6b, 0xc0, 0x46, 0x08, 0x64, 0x50, 0x6c, 0xc0, 0x46, 0x48, 0x64, 
+0x10, 0x6c, 0xc0, 0x46, 0x88, 0x64, 0xd0, 0x6c, 0xc0, 0x46, 0xc8, 0x64, 
+0x90, 0x6c, 0xc0, 0x46, 0x08, 0x65, 0x02, 0xe0, 0x00, 0x23, 0x0b, 0x81, 
+0x8b, 0x80, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
+0x0f, 0x4a, 0x93, 0x89, 0x01, 0x33, 0x93, 0x81, 0xc2, 0x1d, 0xf9, 0x32, 
+0x04, 0x23, 0x90, 0x6a, 0xc0, 0x46, 0xc3, 0x60, 0x10, 0x23, 0x83, 0x61, 
+0xcb, 0x0a, 0x01, 0xd3, 0x18, 0x23, 0x83, 0x61, 0xc1, 0x83, 0x51, 0x6b, 
+0xc0, 0x46, 0xc1, 0x81, 0x51, 0x6b, 0xc2, 0x1d, 0x39, 0x32, 0x51, 0x83, 
+0x04, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x01, 0xf0, 0xa4, 0xf8, 
+0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0xb0, 0xb5, 0x1b, 0x4c, 
+0x20, 0x6a, 0x02, 0x28, 0x1b, 0xd2, 0x00, 0x20, 0xe7, 0x1d, 0x19, 0x37, 
+0x38, 0x71, 0xe1, 0x68, 0xe0, 0x1d, 0xf9, 0x30, 0x00, 0x29, 0x15, 0xd0, 
+0x42, 0x6a, 0x00, 0x2a, 0x12, 0xd1, 0x01, 0x25, 0x0a, 0xe0, 0xff, 0xf7, 
+0x93, 0xfb, 0x00, 0x28, 0x09, 0xd1, 0x20, 0x6a, 0x02, 0x28, 0x00, 0xd3, 
+0x3d, 0x71, 0xe0, 0x68, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x79, 0x00, 0x28, 
+0xf1, 0xd0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x6a, 0x00, 0x28, 
+0xf9, 0xd1, 0x00, 0x29, 0xf7, 0xd1, 0x60, 0x69, 0x00, 0x28, 0x04, 0xd0, 
+0x06, 0x48, 0x00, 0x68, 0x03, 0xf0, 0x8e, 0xfc, 
+0xef, 0xe7, 0x60, 0x68, 0x00, 0x28, 0xec, 0xd0, 0x00, 0xf0, 0x50, 0xf8, 
+0xe9, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0xb4, 0x03, 0x00, 0x80, 
+0xb0, 0xb5, 0x07, 0x1c, 0x20, 0x23, 0xb8, 0x68, 0x18, 0x40, 0x00, 0x25, 
+0x00, 0x28, 0x03, 0xd1, 0x28, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0xc4, 0x23, 0x48, 0x68, 0x18, 0x40, 0x01, 0x24, 0x00, 0x28, 0x03, 0xd1, 
+0x38, 0x6a, 0x00, 0xf0, 0x0d, 0xfc, 0x2f, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 
+0x1d, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 0x7e, 0xfa, 0xb8, 0x68, 0xc0, 0x08, 
+0x02, 0xd3, 0x38, 0x6a, 0x00, 0xf0, 0xd2, 0xfb, 0xb8, 0x68, 0x39, 0x6a, 
+0xc0, 0x46, 0x88, 0x60, 0x38, 0x6a, 0xc0, 0x46, 0xc5, 0x60, 0x0f, 0x48, 
+0x41, 0x68, 0x00, 0x29, 0x11, 0xd1, 0xc1, 0x68, 0x00, 0x29, 0x09, 0xd1, 
+0x41, 0x69, 0x00, 0x29, 0x06, 0xd1, 0x39, 0x6a, 0xc0, 0x46, 0x81, 0x60, 
+0x41, 0x60, 0x00, 0xf0, 0x11, 0xf8, 0x0b, 0xe0, 0x39, 0x6a, 0xc0, 0x46, 
+0x81, 0x60, 0x41, 0x60, 0x06, 0xe0, 0x39, 0x6a, 0x82, 0x68, 0xc0, 0x46, 
+0xd1, 0x60, 0x39, 0x6a, 0xc0, 0x46, 0x81, 0x60, 0x20, 0x1c, 0xc0, 0xe7, 
+0xec, 0x05, 0x00, 0x80, 0x90, 0xb5, 0x0b, 0x4c, 0x67, 0x68, 0x00, 0x2f, 
+0x0f, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x12, 0xf8, 0x00, 0x28, 0x0a, 0xd1, 
+0x60, 0x68, 0xc0, 0x68, 0xc0, 0x46, 0x60, 0x60, 0x38, 0x1c, 0x00, 0xf0, 
+0xc7, 0xfb, 0x00, 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 
+0xfa, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c, 
+0xfe, 0x1d, 0x49, 0x36, 0x30, 0x78, 0x40, 0x00, 0xc0, 0x19, 0x85, 0x8b, 
+0x2d, 0x4b, 0x9d, 0x42, 0x56, 0xd0, 0x2d, 0x4c, 0x38, 0x1c, 0x21, 0x1c, 
+0x2a, 0x1c, 0x00, 0xf0, 0x23, 0xf9, 0xa0, 0x88, 0x40, 0x07, 0x4d, 0xd1, 
+0x29, 0x48, 0x80, 0x6a, 0x58, 0x21, 0x69, 0x43, 0x40, 0x18, 0x01, 0x23, 
+0x9b, 0x07, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x25, 0x4d, 
+0x01, 0x28, 0x1a, 0xd1, 0x30, 0x78, 0xc0, 0x19, 0xc1, 0x1d, 0x19, 0x31, 
+0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, 0x09, 0x7b, 0xea, 0x1d, 0x21, 0x32, 
+0x00, 0xf0, 0xe2, 0xfc, 0x30, 0x78, 0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, 
+0x39, 0x68, 0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20, 0x00, 0x22, 
+0x43, 0x00, 0xca, 0x52, 0x01, 0x30, 0x06, 0x28, 0xfa, 0xd3, 0x21, 0x1c, 
+0x16, 0x4a, 0x00, 0x20, 0xfe, 0xf7, 0x9a, 0xff, 0x01, 0x22, 0x52, 0x04, 
+0x78, 0x68, 0x02, 0x43, 0x01, 0x20, 0x39, 0x68, 0xfe, 0xf7, 0x92, 0xff, 
+0x01, 0x22, 0x52, 0x04, 0x78, 0x68, 0x02, 0x43, 0x00, 0x20, 0x39, 0x68, 
+0xfe, 0xf7, 0x8a, 0xff, 0x0d, 0x49, 0x0e, 0x4a, 0x01, 0x20, 0xfe, 0xf7, 
+0x85, 0xff, 0x01, 0x20, 0xe9, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x02, 0x21, 
+0xea, 0x1d, 0xf9, 0x32, 0x51, 0x62, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0x20, 0xfa, 0xe7, 0xff, 0xff, 0x00, 0x00, 0x98, 0xad, 0x20, 0x40, 
+0xc8, 0x29, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00, 
+0x84, 0xad, 0x20, 0x40, 0x14, 0x00, 0x07, 0x00, 0xf0, 0xb5, 0x83, 0xb0, 
+0x00, 0x21, 0x58, 0x48, 0xc2, 0x1d, 0xf9, 0x32, 0x51, 0x62, 0x01, 0x21, 
+0xc9, 0x04, 0x56, 0x4a, 0xc0, 0x46, 0x11, 0x60, 0xc1, 0x1d, 0x19, 0x31, 
+0x49, 0x79, 0x00, 0x29, 0x04, 0xd1, 0x53, 0x48, 0x00, 0x68, 0x03, 0xf0, 
+0x97, 0xfb, 0x98, 0xe0, 0x4e, 0x48, 0x47, 0x68, 0xfc, 0x1d, 0x49, 0x34, 
+0x22, 0x78, 0x50, 0x00, 0xc0, 0x19, 0x80, 0x8b, 
+0x4d, 0x49, 0x89, 0x6a, 0x58, 0x23, 0x58, 0x43, 0x0d, 0x18, 0x01, 0x23, 
+0x9b, 0x07, 0xe9, 0x1d, 0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x08, 0x35, 
+0x2b, 0x43, 0x1d, 0x68, 0xff, 0x23, 0x1b, 0x02, 0x2b, 0x40, 0x1b, 0x0a, 
+0x45, 0x4d, 0x01, 0x2b, 0x24, 0xd1, 0xd0, 0x19, 0xc1, 0x1d, 0x19, 0x31, 
+0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, 0x42, 0x4a, 0x09, 0x7b, 0x00, 0xf0, 
+0xd3, 0xfc, 0x20, 0x78, 0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, 0x39, 0x68, 
+0x41, 0x18, 0x00, 0x20, 0x82, 0x00, 0x53, 0x19, 0x9b, 0x6e, 0x6e, 0x46, 
+0xb3, 0x50, 0x01, 0x30, 0x03, 0x28, 0xf7, 0xd3, 0xca, 0x1d, 0x05, 0x32, 
+0x69, 0x46, 0x00, 0x20, 0x43, 0x00, 0xcd, 0x5a, 0xc0, 0x46, 0xd5, 0x52, 
+0x01, 0x30, 0x06, 0x28, 0xf8, 0xd3, 0x3e, 0xe0, 0x02, 0x2b, 0x3c, 0xd1, 
+0x09, 0x0a, 0x3a, 0xd3, 0x00, 0x21, 0x8a, 0x00, 0x53, 0x19, 0x9b, 0x6e, 
+0x6e, 0x46, 0xb3, 0x50, 0x01, 0x31, 0x03, 0x29, 0xf7, 0xd3, 0x21, 0x78, 
+0x49, 0x00, 0xc9, 0x19, 0x09, 0x8f, 0x3a, 0x68, 0x8b, 0x18, 0x6a, 0x46, 
+0x00, 0x21, 0x4d, 0x00, 0x56, 0x5b, 0xc0, 0x46, 0x5e, 0x53, 0x01, 0x31, 
+0x06, 0x29, 0xf8, 0xd3, 0x22, 0x49, 0x8a, 0x6a, 0x12, 0x18, 0x01, 0x23, 
+0x9b, 0x07, 0xd5, 0x1d, 0x49, 0x35, 0x2b, 0x43, 0x6e, 0x46, 0x1d, 0x68, 
+0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x6b, 0x40, 0x1e, 0x4d, 
+0xee, 0x68, 0x73, 0x40, 0x13, 0x65, 0x89, 0x6a, 0x08, 0x18, 0x01, 0x23, 
+0x9b, 0x07, 0xc1, 0x1d, 0x4d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x6a, 0x46, 
+0x08, 0x32, 0x1a, 0x43, 0x12, 0x68, 0x51, 0x40, 0xaa, 0x69, 0x51, 0x40, 
+0x41, 0x65, 0x20, 0x78, 0x41, 0x1e, 0x21, 0x70, 0x00, 0x28, 0x0d, 0xd0, 
+0x38, 0x1c, 0xff, 0xf7, 0xef, 0xfe, 0x00, 0x28, 0x0d, 0xd1, 0x09, 0x4a, 
+0x50, 0x68, 0xc0, 0x68, 0xc0, 0x46, 0x50, 0x60, 0x38, 0x1c, 0x00, 0xf0, 
+0xa3, 0xfa, 0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 0x72, 0xfa, 0x01, 0xf0, 
+0xc3, 0xfa, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xec, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0xb8, 0x03, 0x00, 0x80, 
+0xc8, 0x29, 0x00, 0x80, 0x1c, 0xad, 0x20, 0x40, 0x14, 0x06, 0x00, 0x80, 
+0x08, 0x83, 0x20, 0x40, 0xf0, 0xb5, 0x82, 0xb0, 0x69, 0x4b, 0x9f, 0x6a, 
+0x58, 0x23, 0x5a, 0x43, 0xba, 0x18, 0xc3, 0x1d, 0x49, 0x33, 0x1f, 0x78, 
+0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x01, 0x34, 0x23, 0x43, 0x1d, 0x68, 
+0x43, 0x68, 0x1c, 0x04, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x05, 0x36, 
+0x33, 0x43, 0x1b, 0x68, 0x1c, 0x43, 0x42, 0x23, 0x1c, 0x43, 0x0c, 0x60, 
+0xff, 0x26, 0x36, 0x02, 0x2e, 0x40, 0x01, 0x23, 0x5b, 0x02, 0x9e, 0x42, 
+0x74, 0xd1, 0x6b, 0x0c, 0x2b, 0xd3, 0xc3, 0x19, 0x20, 0x33, 0x1b, 0x79, 
+0xc0, 0x46, 0x4b, 0x81, 0x7b, 0x00, 0x1b, 0x18, 0x1b, 0x8f, 0x4c, 0x89, 
+0x1b, 0x1b, 0xcb, 0x80, 0x00, 0x24, 0xa6, 0x00, 0x01, 0x96, 0xb3, 0x18, 
+0xde, 0x1d, 0x09, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 
+0x01, 0x9e, 0x76, 0x18, 0x73, 0x61, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3, 
+0x00, 0x24, 0xa6, 0x00, 0x00, 0x96, 0xb3, 0x18, 0xde, 0x1d, 0x1d, 0x36, 
+0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x00, 0x9e, 0x76, 0x18, 
+0xb3, 0x62, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3, 0x06, 0xe0, 0x00, 0x23, 
+0x4b, 0x81, 0xcb, 0x80, 0x40, 0x23, 0x9c, 0x43, 0x0c, 0x60, 0x23, 0x1c, 
+0x6b, 0x0e, 0x4a, 0xd3, 0xc3, 0x19, 0x20, 0x33, 
+0x1b, 0x79, 0x10, 0x33, 0x0b, 0x81, 0x7b, 0x00, 0x1b, 0x18, 0x1b, 0x8f, 
+0x0f, 0x89, 0xdb, 0x1b, 0x8b, 0x80, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 
+0x35, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x63, 0x01, 0x23, 
+0x9b, 0x07, 0xd4, 0x1d, 0x31, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 
+0x0b, 0x64, 0xab, 0x0e, 0x21, 0xd2, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 
+0x3d, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x4b, 0x64, 0x01, 0x23, 
+0x9b, 0x07, 0xd4, 0x1d, 0x39, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 
+0x8b, 0x64, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x45, 0x34, 0x23, 0x43, 
+0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x64, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 
+0x41, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x0b, 0x65, 0x00, 0xe0, 
+0x0f, 0xe0, 0xfb, 0x1f, 0x01, 0x3b, 0x1b, 0x04, 0x1b, 0x0c, 0x07, 0x68, 
+0xff, 0x18, 0x03, 0x69, 0x08, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x34, 0xf8, 
+0x2c, 0xe0, 0x00, 0x23, 0x0b, 0x81, 0x8b, 0x80, 0x28, 0xe0, 0x00, 0x23, 
+0x8b, 0x80, 0x0b, 0x81, 0xc3, 0x19, 0x20, 0x33, 0x1b, 0x7a, 0xc0, 0x46, 
+0x4b, 0x81, 0x7b, 0x00, 0x18, 0x18, 0x00, 0x8e, 0xc0, 0x46, 0xc8, 0x80, 
+0x00, 0x20, 0x87, 0x00, 0xbb, 0x18, 0xdc, 0x1d, 0x09, 0x34, 0x01, 0x23, 
+0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x7f, 0x18, 0x7b, 0x61, 0x01, 0x30, 
+0x05, 0x28, 0xf2, 0xd3, 0x00, 0x20, 0x87, 0x00, 0xbb, 0x18, 0xdc, 0x1d, 
+0x1d, 0x34, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x7f, 0x18, 
+0xbb, 0x62, 0x01, 0x30, 0x05, 0x28, 0xf2, 0xd3, 0x02, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xc8, 0x29, 0x00, 0x80, 0x80, 0xb4, 0x1f, 0x1c, 
+0x3b, 0x0c, 0x18, 0xd2, 0x17, 0x6d, 0x11, 0x4b, 0xc0, 0x46, 0xdf, 0x60, 
+0x52, 0x6d, 0xc0, 0x46, 0x1a, 0x61, 0xc7, 0x60, 0x1a, 0x69, 0xc0, 0x46, 
+0x02, 0x61, 0xd8, 0x68, 0xc0, 0x46, 0x08, 0x80, 0xd8, 0x68, 0x00, 0x0c, 
+0x48, 0x80, 0x18, 0x69, 0xc0, 0x46, 0x88, 0x80, 0x18, 0x69, 0x00, 0x0c, 
+0xc8, 0x80, 0x80, 0xbc, 0x70, 0x47, 0x4a, 0x88, 0x12, 0x04, 0x0b, 0x88, 
+0x1a, 0x43, 0xc2, 0x60, 0x8a, 0x88, 0xc9, 0x88, 0x09, 0x04, 0x11, 0x43, 
+0x01, 0x61, 0xf2, 0xe7, 0xac, 0x06, 0x00, 0x80, 0xf1, 0xb5, 0x88, 0xb0, 
+0x00, 0x22, 0x08, 0x98, 0x00, 0x6a, 0x08, 0x9b, 0x99, 0x68, 0x49, 0x0a, 
+0x02, 0xd3, 0x01, 0x27, 0xff, 0x03, 0x00, 0xe0, 0x00, 0x27, 0x03, 0x8b, 
+0x00, 0x2b, 0x19, 0xd0, 0xa2, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, 
+0x63, 0x43, 0xc9, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, 0x19, 0x43, 
+0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x02, 0x29, 0x02, 0xd1, 0x08, 0x23, 
+0x1f, 0x43, 0x07, 0xe0, 0x41, 0x8b, 0x00, 0x29, 0x02, 0xd0, 0x0c, 0x23, 
+0x1f, 0x43, 0x01, 0xe0, 0x04, 0x23, 0x1f, 0x43, 0x83, 0x8a, 0x00, 0x2b, 
+0x18, 0xd0, 0x94, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, 0x63, 0x43, 
+0xc9, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, 0x19, 0x43, 0x09, 0x68, 
+0x09, 0x04, 0x09, 0x0c, 0x02, 0x29, 0x01, 0xd1, 0x0f, 0x43, 0x07, 0xe0, 
+0xc1, 0x8a, 0x00, 0x29, 0x02, 0xd0, 0x03, 0x23, 0x1f, 0x43, 0x01, 0xe0, 
+0x01, 0x23, 0x1f, 0x43, 0xc1, 0x1d, 0x39, 0x31, 0x07, 0x91, 0x4b, 0x89, 
+0x0c, 0x89, 0x1c, 0x19, 0x24, 0x04, 0x24, 0x0c, 0x08, 0x9d, 0x2d, 0x68, 
+0xc0, 0x46, 0x01, 0x95, 0xc9, 0x88, 0x7d, 0x08, 0x1a, 0xd3, 0x1a, 0x1c, 
+0xc3, 0x1d, 0x19, 0x33, 0x1a, 0x72, 0x07, 0x9a, 
+0x92, 0x89, 0xc0, 0x46, 0x1a, 0x73, 0x07, 0x9a, 0x12, 0x89, 0xc0, 0x46, 
+0x02, 0x86, 0x04, 0x87, 0x82, 0x8a, 0x01, 0x3a, 0x82, 0x83, 0x01, 0x22, 
+0x19, 0x71, 0x08, 0x9b, 0x1b, 0x68, 0x5b, 0x18, 0x5b, 0x78, 0x9b, 0x00, 
+0x1b, 0x04, 0x1b, 0x0c, 0x08, 0x33, 0x59, 0x18, 0xbb, 0x08, 0x47, 0xd3, 
+0x07, 0x9b, 0x5b, 0x89, 0x85, 0x18, 0x06, 0x95, 0x20, 0x35, 0x2b, 0x72, 
+0x07, 0x9b, 0x9b, 0x89, 0xc0, 0x46, 0x2b, 0x73, 0x07, 0x9b, 0x1b, 0x89, 
+0x2e, 0x1c, 0x55, 0x00, 0x2d, 0x18, 0x05, 0x95, 0x2b, 0x86, 0x00, 0x2a, 
+0x01, 0xd0, 0xc3, 0x8a, 0x00, 0xe0, 0x83, 0x8a, 0x01, 0x3b, 0x05, 0x9d, 
+0xc0, 0x46, 0xab, 0x83, 0x31, 0x71, 0x64, 0x4b, 0x9d, 0x6a, 0x05, 0x9b, 
+0x9e, 0x8b, 0x58, 0x23, 0x73, 0x43, 0xeb, 0x18, 0xdd, 0x1d, 0x01, 0x35, 
+0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1d, 0x68, 0x2b, 0x0e, 0x5b, 0x06, 
+0x01, 0xd1, 0x08, 0x31, 0x00, 0xe0, 0x10, 0x31, 0x81, 0x23, 0x5b, 0x02, 
+0x1d, 0x40, 0x9d, 0x42, 0x03, 0xd1, 0xe3, 0x1f, 0x05, 0x3b, 0x1c, 0x04, 
+0x24, 0x0c, 0x05, 0x9b, 0xc0, 0x46, 0x1c, 0x87, 0x08, 0x9b, 0x1b, 0x68, 
+0x1b, 0x19, 0x10, 0x3b, 0x9b, 0x7b, 0x06, 0x9d, 0x40, 0x35, 0x2b, 0x70, 
+0x2b, 0x78, 0x02, 0x33, 0xe3, 0x1a, 0x1c, 0x04, 0x24, 0x0c, 0x01, 0x32, 
+0xbb, 0x08, 0x9b, 0x07, 0x6b, 0xd0, 0x83, 0x18, 0x20, 0x33, 0x04, 0x93, 
+0x19, 0x72, 0x01, 0x9b, 0x5d, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 
+0x1b, 0x68, 0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 0x04, 0x9e, 0xc0, 0x46, 
+0x33, 0x73, 0x00, 0x95, 0x2b, 0x78, 0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 
+0x04, 0x9d, 0xc0, 0x46, 0x2b, 0x73, 0x00, 0x9d, 0xeb, 0x78, 0xad, 0x78, 
+0x1b, 0x02, 0x1d, 0x43, 0x2b, 0x02, 0x2d, 0x0a, 0x2d, 0x06, 0x2d, 0x0e, 
+0x2b, 0x43, 0x55, 0x00, 0x2d, 0x18, 0x2b, 0x86, 0x04, 0x9b, 0xc0, 0x46, 
+0x59, 0x72, 0x04, 0x9b, 0x1b, 0x7b, 0x2e, 0x1c, 0x04, 0x9d, 0xc0, 0x46, 
+0x6b, 0x73, 0x33, 0x8e, 0xc0, 0x46, 0x73, 0x86, 0x00, 0x9d, 0x2b, 0x78, 
+0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 0x59, 0x18, 0x04, 0x25, 0x3d, 0x40, 
+0x0e, 0xd0, 0x34, 0x87, 0x03, 0x8b, 0x01, 0x3b, 0xb3, 0x83, 0x13, 0x1c, 
+0x1b, 0x18, 0x20, 0x33, 0x19, 0x71, 0x01, 0x9b, 0x5b, 0x18, 0x5b, 0x78, 
+0x9b, 0x00, 0x59, 0x18, 0x08, 0x31, 0x01, 0x32, 0x3b, 0x09, 0x37, 0xd3, 
+0x00, 0x2d, 0x01, 0xd0, 0x43, 0x8b, 0x00, 0xe0, 0x03, 0x8b, 0x55, 0x00, 
+0x2d, 0x18, 0x01, 0x3b, 0xab, 0x83, 0x83, 0x18, 0x03, 0x93, 0x20, 0x33, 
+0x19, 0x71, 0x20, 0x4b, 0x9d, 0x6a, 0x53, 0x00, 0x1b, 0x18, 0x02, 0x93, 
+0x9e, 0x8b, 0x58, 0x23, 0x73, 0x43, 0xeb, 0x18, 0xdd, 0x1d, 0x01, 0x35, 
+0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1d, 0x68, 0x2b, 0x0e, 0x5b, 0x06, 
+0x02, 0xd1, 0x08, 0x31, 0x01, 0xe0, 0x15, 0xe0, 0x10, 0x31, 0x81, 0x23, 
+0x5b, 0x02, 0x1d, 0x40, 0x9d, 0x42, 0x03, 0xd1, 0xe3, 0x1f, 0x05, 0x3b, 
+0x1c, 0x04, 0x24, 0x0c, 0x02, 0x9b, 0xc0, 0x46, 0x1c, 0x87, 0x08, 0x9b, 
+0x1b, 0x68, 0x1b, 0x19, 0x10, 0x3b, 0x9b, 0x7b, 0x03, 0x9c, 0x40, 0x34, 
+0x23, 0x70, 0x01, 0x32, 0x07, 0x9b, 0xc0, 0x46, 0xd9, 0x80, 0x51, 0x1e, 
+0xc3, 0x1d, 0x49, 0x33, 0x19, 0x70, 0x07, 0x61, 0x04, 0x2a, 0x06, 0xd2, 
+0x06, 0x49, 0x53, 0x00, 0x1b, 0x18, 0x99, 0x83, 0x01, 0x32, 0x04, 0x2a, 
+0xf9, 0xd3, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xc8, 0x29, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 
+0x70, 0x47, 0x80, 0xb5, 0x8c, 0xb0, 0x07, 0x1c, 0x12, 0x48, 0x01, 0x68, 
+0x01, 0x31, 0x01, 0x60, 0x38, 0x68, 0xc0, 0x46, 0x00, 0x90, 0x78, 0x68, 
+0xc0, 0x46, 0x01, 0x90, 0xb8, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x0d, 0x48, 
+0x41, 0x68, 0xc9, 0x68, 0xc0, 0x46, 0x41, 0x60, 0x38, 0x1c, 0x00, 0xf0, 
+0x4f, 0xf8, 0xb8, 0x68, 0x40, 0x09, 0x06, 0xd3, 0x10, 0x23, 0x02, 0x98, 
+0x18, 0x43, 0x02, 0x90, 0x68, 0x46, 0x02, 0xf0, 0xcd, 0xff, 0x68, 0x46, 
+0x02, 0xf0, 0x82, 0xfe, 0x0c, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x78, 0x2a, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x00, 0xb5, 0x8c, 0xb0, 
+0x01, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x68, 0x05, 0x4b, 0x19, 0x43, 
+0x01, 0x91, 0x00, 0xf0, 0x2f, 0xf8, 0x68, 0x46, 0x02, 0xf0, 0x6c, 0xfe, 
+0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 
+0x02, 0x6a, 0x03, 0x68, 0xc0, 0x46, 0x13, 0x60, 0x40, 0x68, 0xc0, 0x46, 
+0x50, 0x60, 0x40, 0x32, 0x48, 0x68, 0xc0, 0x46, 0x90, 0x80, 0xc8, 0x68, 
+0xc0, 0x46, 0xd0, 0x80, 0x48, 0x69, 0xc0, 0x46, 0x10, 0x81, 0x88, 0x68, 
+0xc0, 0x46, 0x50, 0x81, 0x08, 0x7e, 0xc0, 0x46, 0x90, 0x73, 0x08, 0x69, 
+0xc0, 0x46, 0x90, 0x81, 0x70, 0x47, 0x04, 0x49, 0x08, 0x68, 0x00, 0x28, 
+0x00, 0xd1, 0x70, 0x47, 0xc2, 0x68, 0xc0, 0x46, 0x0a, 0x60, 0xfa, 0xe7, 
+0xec, 0x05, 0x00, 0x80, 0x02, 0x49, 0x0a, 0x68, 0xc0, 0x46, 0xc2, 0x60, 
+0x08, 0x60, 0x70, 0x47, 0xec, 0x05, 0x00, 0x80, 0xb0, 0xb4, 0x00, 0x22, 
+0x12, 0x4f, 0x3b, 0x7f, 0x01, 0x33, 0x3b, 0x77, 0x03, 0x23, 0xfc, 0x1d, 
+0x19, 0x34, 0x38, 0x62, 0x79, 0x62, 0x23, 0x72, 0x0e, 0x4c, 0x25, 0x68, 
+0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, 0x1b, 0x0c, 0x10, 0xd1, 0x24, 0x68, 
+0xa3, 0x0a, 0x0d, 0xd3, 0x01, 0x23, 0x0a, 0x4f, 0xc0, 0x46, 0xfb, 0x62, 
+0x09, 0x4f, 0x0a, 0x4b, 0xc0, 0x46, 0xdf, 0x60, 0x99, 0x60, 0x58, 0x60, 
+0x10, 0x1c, 0x18, 0x60, 0x01, 0x32, 0xfb, 0xe7, 0x10, 0x1c, 0x38, 0x64, 
+0x01, 0x32, 0xfb, 0xe7, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 
+0xc0, 0x00, 0x18, 0x00, 0x02, 0x81, 0x00, 0x00, 0x40, 0x01, 0x18, 0x00, 
+0xf0, 0xb5, 0x47, 0x4f, 0x38, 0x68, 0x47, 0x4e, 0x47, 0x4d, 0x07, 0x23, 
+0x5b, 0x02, 0xec, 0x18, 0x00, 0x28, 0x1d, 0xd1, 0xe0, 0x6a, 0x01, 0x30, 
+0xe0, 0x62, 0x44, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x43, 0x48, 0x41, 0x69, 
+0x00, 0x29, 0x13, 0xd0, 0xc1, 0x1d, 0x69, 0x31, 0x09, 0x7b, 0x00, 0x29, 
+0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, 0x01, 0x6d, 0x19, 0x43, 0x09, 0x68, 
+0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, 0x91, 0x42, 0x04, 0xd0, 0xf1, 0x6c, 
+0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, 0x3a, 0xfe, 0x38, 0x68, 0x01, 0x28, 
+0x17, 0xd1, 0x37, 0x48, 0x41, 0x69, 0x00, 0x29, 0x13, 0xd0, 0xc1, 0x1d, 
+0x69, 0x31, 0x09, 0x7b, 0x00, 0x29, 0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, 
+0x01, 0x6d, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, 
+0x91, 0x42, 0x04, 0xd0, 0xf1, 0x6c, 0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, 
+0x1f, 0xfe, 0x38, 0x68, 0x02, 0x28, 0x2f, 0xd1, 0xbb, 0x23, 0x1b, 0x01, 
+0xee, 0x18, 0x70, 0x7a, 0x00, 0x28, 0x03, 0xd0, 0x00, 0x20, 0x70, 0x72, 
+0x00, 0xf0, 0x30, 0xfd, 0x30, 0x7a, 0x00, 0x28, 0x02, 0xd0, 0x78, 0x68, 
+0x02, 0xf0, 0x96, 0xff, 0x1b, 0x23, 0xdb, 0x01, 0xe8, 0x18, 0x40, 0x8b, 
+0x04, 0x26, 0x06, 0x40, 0xa0, 0x6a, 0xb0, 0x42, 
+0x14, 0xd0, 0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 0x19, 0x28, 0x11, 0xd3, 
+0x1b, 0x48, 0x01, 0x7b, 0x00, 0x29, 0x0d, 0xd1, 0xff, 0x30, 0x41, 0x30, 
+0x40, 0x78, 0x00, 0x28, 0x08, 0xd1, 0xb8, 0x68, 0x02, 0xf0, 0x7c, 0xff, 
+0x00, 0x20, 0xf8, 0x60, 0xa6, 0x62, 0x01, 0xe0, 0x00, 0x20, 0xf8, 0x60, 
+0x38, 0x68, 0x03, 0x28, 0x0b, 0xd1, 0xec, 0x1d, 0x79, 0x34, 0xa0, 0x6b, 
+0x80, 0x08, 0x02, 0xd3, 0x02, 0x20, 0x02, 0xf0, 0xef, 0xfb, 0x02, 0x23, 
+0xa0, 0x6b, 0x98, 0x43, 0xa0, 0x63, 0x38, 0x68, 0x01, 0x30, 0x38, 0x60, 
+0x03, 0x28, 0x01, 0xd9, 0x00, 0x20, 0x38, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xbc, 0x03, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
+0xe8, 0x0d, 0x00, 0x80, 0x40, 0x01, 0x18, 0x00, 0xd0, 0x2c, 0x00, 0x80, 
+0x50, 0x2c, 0x00, 0x80, 0xa8, 0x04, 0x00, 0x80, 0x90, 0xb4, 0x1c, 0x48, 
+0x02, 0x8a, 0x1c, 0x49, 0x0f, 0x8a, 0x01, 0x23, 0xba, 0x42, 0x03, 0xd1, 
+0xc2, 0x89, 0x4f, 0x8a, 0xba, 0x42, 0x10, 0xd0, 0x02, 0x7b, 0x00, 0x2a, 
+0x0d, 0xd0, 0x42, 0x7b, 0x00, 0x2a, 0x0a, 0xd0, 0xc7, 0x8a, 0x8a, 0x8a, 
+0x97, 0x42, 0x04, 0xdc, 0x13, 0x4a, 0xc0, 0x46, 0x53, 0x60, 0x8b, 0x82, 
+0x01, 0xe0, 0x01, 0x32, 0x8a, 0x82, 0x42, 0x8b, 0x57, 0x1c, 0x47, 0x83, 
+0x07, 0x8b, 0xba, 0x42, 0x0e, 0xdb, 0x07, 0x8a, 0x84, 0x8a, 0x00, 0x22, 
+0xa7, 0x42, 0x05, 0xda, 0xc7, 0x89, 0x44, 0x8a, 0xa7, 0x42, 0x01, 0xda, 
+0x42, 0x73, 0x00, 0xe0, 0x43, 0x73, 0xc2, 0x81, 0x02, 0x82, 0x42, 0x83, 
+0xc2, 0x89, 0xc0, 0x46, 0x4a, 0x82, 0x00, 0x8a, 0xc0, 0x46, 0x08, 0x82, 
+0x90, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xbc, 0x03, 0x00, 0x80, 
+0x40, 0x01, 0x18, 0x00, 0xf7, 0xb5, 0x91, 0xb0, 0x6b, 0x46, 0x84, 0x1e, 
+0x12, 0x99, 0x14, 0x29, 0x1a, 0xd9, 0x00, 0x20, 0x81, 0x00, 0x67, 0x58, 
+0xc0, 0x46, 0x57, 0x50, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0x28, 
+0xf6, 0xd3, 0x00, 0x21, 0x05, 0x20, 0x87, 0x00, 0xd6, 0x59, 0x4f, 0x1c, 
+0x3d, 0x06, 0x2d, 0x0e, 0x0f, 0x1c, 0xbf, 0x00, 0xde, 0x51, 0x29, 0x1c, 
+0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0x28, 0xf1, 0xd3, 0x09, 0xe0, 
+0x00, 0x20, 0x81, 0x00, 0x63, 0x58, 0xc0, 0x46, 0x53, 0x50, 0x01, 0x30, 
+0x00, 0x06, 0x00, 0x0e, 0x06, 0x28, 0xf6, 0xd3, 0x00, 0x20, 0xe0, 0x70, 
+0x20, 0x72, 0x60, 0x72, 0xa0, 0x72, 0x20, 0x73, 0x60, 0x73, 0x12, 0x99, 
+0x14, 0x29, 0x37, 0xd9, 0x69, 0x46, 0x8e, 0x1c, 0x91, 0x78, 0x09, 0x07, 
+0x09, 0x0f, 0x89, 0x00, 0x14, 0x39, 0x0d, 0x06, 0x2d, 0x16, 0x00, 0x27, 
+0x00, 0x2d, 0x1b, 0xdd, 0xf0, 0x19, 0x10, 0xa9, 0x00, 0xf0, 0x3d, 0xf8, 
+0x00, 0x28, 0x0e, 0xd0, 0x00, 0x20, 0x10, 0xa9, 0x09, 0x78, 0x00, 0x29, 
+0x09, 0xdd, 0x00, 0x22, 0x39, 0x18, 0x72, 0x54, 0x01, 0x30, 0x00, 0x06, 
+0x00, 0x0e, 0x10, 0xa9, 0x09, 0x78, 0x88, 0x42, 0xf6, 0xdb, 0x10, 0xa8, 
+0x00, 0x78, 0x38, 0x18, 0x07, 0x06, 0x3f, 0x0e, 0xaf, 0x42, 0xe3, 0xdb, 
+0x68, 0x46, 0xe2, 0x1d, 0x0d, 0x32, 0x00, 0x21, 0xab, 0x08, 0x5f, 0x1c, 
+0x08, 0xd0, 0x8b, 0x00, 0xc4, 0x58, 0xc0, 0x46, 0xd4, 0x50, 0x01, 0x31, 
+0x09, 0x06, 0x09, 0x0e, 0x8f, 0x42, 0xf6, 0xd8, 0x14, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x90, 0xb4, 0x87, 0x1e, 0x00, 0x20, 0x89, 0x08, 
+0x4b, 0x1c, 0x08, 0xd0, 0x81, 0x00, 0x54, 0x58, 0xc0, 0x46, 0x7c, 0x50, 
+0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x83, 0x42, 
+0xf6, 0xd8, 0x90, 0xbc, 0x70, 0x47, 0x80, 0xb4, 0x02, 0x78, 0xd2, 0x06, 
+0xd2, 0x0e, 0x00, 0x23, 0x01, 0x27, 0x01, 0x2a, 0x01, 0xdc, 0x0f, 0x70, 
+0x11, 0xe0, 0x40, 0x78, 0xc0, 0x46, 0x08, 0x70, 0x14, 0x2a, 0x04, 0xd1, 
+0x08, 0x48, 0x01, 0x7a, 0x01, 0x31, 0x01, 0x72, 0x07, 0xe0, 0x02, 0x2a, 
+0x05, 0xd0, 0x05, 0x2a, 0x03, 0xd0, 0x06, 0x2a, 0x01, 0xd0, 0x15, 0x2a, 
+0x02, 0xd1, 0x18, 0x1c, 0x80, 0xbc, 0x70, 0x47, 0x38, 0x1c, 0xfb, 0xe7, 
+0xe0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x0f, 0x48, 0x01, 0x23, 0x1b, 0x06, 
+0x41, 0x69, 0x99, 0x43, 0x1a, 0x09, 0x41, 0x61, 0xd1, 0x60, 0x00, 0x21, 
+0xa1, 0x22, 0x52, 0x03, 0x91, 0x61, 0x19, 0x1c, 0x09, 0x4a, 0xc0, 0x46, 
+0x11, 0x60, 0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x40, 0x69, 0x00, 0x28, 
+0x03, 0xd0, 0x02, 0xf0, 0x4f, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x04, 0x48, 
+0x41, 0x88, 0x01, 0x31, 0x41, 0x80, 0xf8, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 
+0x00, 0x00, 0x00, 0xb0, 0xe0, 0x82, 0x20, 0x40, 0x70, 0x47, 0x00, 0x00, 
+0xf0, 0xb5, 0x85, 0xb0, 0x94, 0x49, 0xc8, 0x68, 0xcf, 0x1d, 0x79, 0x37, 
+0x01, 0x28, 0x0b, 0xd1, 0xb8, 0x88, 0x00, 0x28, 0x08, 0xd1, 0xc3, 0x1e, 
+0xca, 0x6f, 0x1a, 0x40, 0xca, 0x67, 0x8f, 0x48, 0xc0, 0x46, 0x02, 0x60, 
+0x14, 0x20, 0xb8, 0x80, 0x8d, 0x4c, 0x62, 0x6a, 0x8d, 0x48, 0xc3, 0x6b, 
+0x9a, 0x18, 0xc2, 0x63, 0xa0, 0x6a, 0x19, 0x23, 0xdb, 0x01, 0xcc, 0x18, 
+0x60, 0x62, 0xe2, 0x69, 0x12, 0x03, 0x12, 0x0b, 0x82, 0x42, 0x05, 0xd1, 
+0x01, 0x20, 0x40, 0x04, 0x86, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xef, 0xe0, 
+0x3b, 0x8a, 0x58, 0x1c, 0x38, 0x82, 0xbd, 0x8a, 0x01, 0x20, 0x00, 0x22, 
+0xab, 0x42, 0x02, 0xdb, 0x78, 0x73, 0x3a, 0x82, 0x7a, 0x83, 0x33, 0x23, 
+0x9b, 0x01, 0xcb, 0x18, 0x04, 0x93, 0x1b, 0x69, 0x0f, 0x2b, 0x73, 0xd2, 
+0x00, 0x22, 0x2f, 0x23, 0x9b, 0x01, 0xcf, 0x18, 0xfa, 0x60, 0xe1, 0x69, 
+0x8a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x4b, 0x68, 0x1e, 0x0c, 0x36, 0x04, 
+0x76, 0x4d, 0x05, 0xd1, 0x3b, 0x2a, 0x03, 0xd3, 0x01, 0x23, 0xdb, 0x02, 
+0x9a, 0x42, 0x01, 0xd9, 0xa8, 0x72, 0xc7, 0xe0, 0x01, 0x23, 0x9b, 0x07, 
+0x08, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x03, 0x91, 0x03, 0xa9, 
+0x09, 0x88, 0x01, 0x31, 0x09, 0x04, 0x09, 0x0c, 0xf9, 0x81, 0x49, 0x09, 
+0x05, 0x31, 0x09, 0x06, 0x09, 0x0e, 0x6a, 0x4a, 0xc0, 0x46, 0x02, 0x92, 
+0x06, 0x1c, 0x69, 0x48, 0x43, 0x6a, 0xc0, 0x46, 0x01, 0x93, 0x83, 0x6a, 
+0xc0, 0x46, 0x00, 0x93, 0xc2, 0x1d, 0x11, 0x32, 0x80, 0x69, 0x00, 0x03, 
+0x00, 0x0b, 0x92, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x1a, 0x43, 0x12, 0x68, 
+0x90, 0x42, 0x01, 0xd1, 0x30, 0x1c, 0x0d, 0xe0, 0x90, 0x42, 0x05, 0xd9, 
+0x00, 0x9b, 0x18, 0x1a, 0x01, 0x9b, 0xd2, 0x1a, 0x82, 0x18, 0x00, 0xe0, 
+0x12, 0x1a, 0x01, 0x20, 0x09, 0x01, 0x91, 0x42, 0x00, 0xd3, 0x00, 0x20, 
+0x01, 0x28, 0x62, 0xd1, 0xe0, 0x68, 0x00, 0x28, 0x60, 0xd0, 0x04, 0x99, 
+0x08, 0x69, 0x01, 0x30, 0x08, 0x61, 0x02, 0x20, 0xe1, 0x69, 0xc0, 0x46, 
+0x08, 0x60, 0x00, 0xf0, 0x8f, 0xfc, 0x38, 0x63, 0x4e, 0x49, 0xc0, 0x46, 
+0x79, 0x60, 0xe1, 0x69, 0x62, 0x6b, 0x8a, 0x18, 0x23, 0x6b, 0x9a, 0x42, 
+0x00, 0xd9, 0xe1, 0x6a, 0xc0, 0x46, 0x79, 0x62, 0x79, 0x6a, 0x0c, 0x31, 
+0xb9, 0x62, 0x00, 0x21, 0xb9, 0x61, 0x03, 0xa9, 0x49, 0x88, 0xc9, 0x09, 
+0x03, 0xd3, 0x00, 0xe0, 0x78, 0xe0, 0x31, 0x1c, 
+0x00, 0xe0, 0x00, 0x21, 0x39, 0x60, 0x39, 0x68, 0xc0, 0x46, 0x01, 0x60, 
+0xf8, 0x89, 0x41, 0x4e, 0x60, 0x28, 0x04, 0xdc, 0x30, 0x83, 0xf8, 0x89, 
+0xc0, 0x46, 0x70, 0x83, 0x08, 0xe0, 0x60, 0x20, 0x30, 0x83, 0xf9, 0x89, 
+0xb8, 0x6a, 0x42, 0x18, 0x23, 0x6b, 0x9a, 0x42, 0x03, 0xd8, 0x71, 0x83, 
+0x00, 0x21, 0xf9, 0x62, 0x05, 0xe0, 0xe1, 0x6a, 0xc0, 0x46, 0xf9, 0x62, 
+0x21, 0x6b, 0x08, 0x1a, 0x70, 0x83, 0x38, 0x6b, 0x41, 0x68, 0xc0, 0x46, 
+0x79, 0x60, 0x81, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0x01, 0x69, 0xc0, 0x46, 
+0x39, 0x61, 0x40, 0x69, 0xc0, 0x46, 0x78, 0x61, 0x38, 0x1c, 0x00, 0xf0, 
+0x23, 0xf9, 0x38, 0x1c, 0x00, 0xf0, 0x88, 0xf8, 0x00, 0xf0, 0xe0, 0xfa, 
+0xf8, 0x89, 0x71, 0x8b, 0x88, 0x42, 0x04, 0xd1, 0xb9, 0x6a, 0x08, 0x18, 
+0x04, 0xe0, 0x38, 0xe0, 0x32, 0xe0, 0xfa, 0x6a, 0x10, 0x18, 0x40, 0x1a, 
+0x81, 0x07, 0x02, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x21, 0x6b, 
+0x09, 0x1a, 0x62, 0x6b, 0x91, 0x42, 0x00, 0xd2, 0xe0, 0x6a, 0xc0, 0x46, 
+0xe0, 0x61, 0xe8, 0x7a, 0x00, 0x28, 0x08, 0xd0, 0x00, 0x21, 0xe9, 0x72, 
+0x04, 0x99, 0x08, 0x69, 0x01, 0x38, 0x08, 0x61, 0x38, 0x6b, 0x00, 0xf0, 
+0x5d, 0xfa, 0x18, 0x48, 0x80, 0x6a, 0x80, 0x06, 0x80, 0x0e, 0x01, 0x28, 
+0x0a, 0xd1, 0xe0, 0x69, 0x00, 0x03, 0x00, 0x0b, 0x0c, 0x4c, 0xa1, 0x6a, 
+0x88, 0x42, 0x03, 0xd0, 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x01, 0x20, 0x40, 0x04, 0x09, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x05, 0xe0, 
+0xa0, 0x68, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0x9f, 0xfa, 0xae, 0x72, 
+0xee, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 
+0x00, 0x40, 0x14, 0x40, 0x10, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 
+0x98, 0x19, 0x00, 0x80, 0x55, 0x55, 0x55, 0x55, 0x28, 0x03, 0x00, 0x80, 
+0xe8, 0x19, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 0x80, 0xb5, 0x07, 0x1c, 
+0x78, 0x6a, 0x40, 0x89, 0xff, 0x21, 0x01, 0x31, 0x01, 0x40, 0x10, 0x48, 
+0x02, 0xd1, 0x81, 0x6c, 0x01, 0x31, 0x81, 0x64, 0x79, 0x6a, 0x49, 0x89, 
+0x49, 0x0b, 0x02, 0xd2, 0x41, 0x6c, 0x01, 0x31, 0x41, 0x64, 0x0b, 0x48, 
+0x41, 0x6a, 0x01, 0x31, 0x41, 0x62, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, 
+0x48, 0x62, 0x38, 0x6b, 0x00, 0xf0, 0xe2, 0xfb, 0x38, 0x1c, 0x00, 0xf0, 
+0x9f, 0xf8, 0x01, 0x20, 0x04, 0x49, 0xc0, 0x46, 0xc8, 0x72, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x10, 0x2a, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
+0x98, 0x19, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c, 0x00, 0x22, 0xf9, 0x1d, 
+0x61, 0x31, 0x0d, 0x1c, 0x78, 0x6a, 0xc0, 0x46, 0x00, 0x90, 0x40, 0x89, 
+0x03, 0x0c, 0x01, 0xd2, 0x40, 0x0a, 0x03, 0xd2, 0x38, 0x1c, 0xff, 0xf7, 
+0xc1, 0xff, 0x54, 0xe0, 0x2b, 0x48, 0x80, 0x6b, 0x00, 0x09, 0x1f, 0xd3, 
+0x08, 0x78, 0x40, 0x08, 0x1c, 0xd2, 0x00, 0x20, 0x43, 0x00, 0xcc, 0x5a, 
+0x27, 0x4e, 0x9e, 0x19, 0x65, 0x23, 0x5b, 0x01, 0xf3, 0x18, 0x9b, 0x8b, 
+0x9c, 0x42, 0x0e, 0xd0, 0xb8, 0x69, 0x39, 0x6b, 0xc0, 0x46, 0x88, 0x61, 
+0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 0x38, 0x1c, 0x00, 0xf0, 
+0x13, 0xf9, 0x38, 0x1c, 0x00, 0xf0, 0x60, 0xf8, 0x33, 0xe0, 0x01, 0x30, 
+0x03, 0x28, 0xe3, 0xd3, 0x1a, 0x48, 0x0b, 0x23, 0x1b, 0x02, 0xc1, 0x18, 
+0x09, 0x69, 0x00, 0x29, 0x24, 0xd0, 0x7d, 0x63, 0x00, 0x99, 0x49, 0x89, 
+0x09, 0x0c, 0x1f, 0xd2, 0x00, 0x24, 0x2d, 0x23, 
+0x9b, 0x01, 0xc1, 0x18, 0x89, 0x6b, 0x00, 0x29, 0x18, 0xd0, 0x05, 0x1c, 
+0xfe, 0x1d, 0x2d, 0x36, 0xa2, 0x00, 0x52, 0x19, 0x2d, 0x23, 0x9b, 0x01, 
+0xd2, 0x18, 0x92, 0x6b, 0x38, 0x1c, 0x31, 0x1c, 0x02, 0xf0, 0x7e, 0xfc, 
+0x01, 0x28, 0x0e, 0xd0, 0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, 0x2d, 0x23, 
+0x9b, 0x01, 0xc0, 0x18, 0x80, 0x6b, 0x00, 0x28, 0xea, 0xd1, 0x01, 0xe0, 
+0x01, 0x2a, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x07, 0xf8, 0xf8, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x68, 0x1a, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 
+0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x69, 0x39, 0x6b, 0xc0, 0x46, 0x88, 0x61, 
+0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 0x78, 0x6a, 0x40, 0x89, 
+0x01, 0x0c, 0x0e, 0xd2, 0x40, 0x0a, 0x0c, 0xd3, 0x38, 0x68, 0x40, 0x08, 
+0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x10, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 
+0xbb, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0x08, 0xf8, 0x02, 0xe0, 0x38, 0x1c, 
+0xff, 0xf7, 0x44, 0xff, 0x01, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x01, 0x21, 0x00, 0x6b, 0x40, 0x6a, 0xc0, 0x46, 0x01, 0x60, 0x70, 0x47, 
+0xb0, 0xb4, 0xc1, 0x1d, 0x39, 0x31, 0x09, 0x8b, 0x89, 0x08, 0x09, 0x04, 
+0x09, 0x0c, 0x84, 0x6a, 0xc2, 0x1d, 0x61, 0x32, 0x00, 0x20, 0x00, 0x29, 
+0x0c, 0xdd, 0x87, 0x00, 0x3d, 0x19, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 
+0x1b, 0x68, 0xc0, 0x46, 0xd3, 0x51, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 
+0x88, 0x42, 0xf2, 0xdb, 0xb0, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0xa0, 0xb0, 
+0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x21, 0x31, 0x19, 0x43, 0x09, 0x68, 
+0xc0, 0x46, 0x0b, 0x91, 0xc1, 0x1d, 0x53, 0x31, 0x19, 0x43, 0x1f, 0x91, 
+0x09, 0x68, 0x01, 0xaf, 0xfa, 0x1d, 0x39, 0x32, 0x1e, 0x92, 0x17, 0xab, 
+0x59, 0x80, 0x3a, 0x49, 0x01, 0x23, 0x9b, 0x07, 0x0a, 0x6a, 0x13, 0x43, 
+0xcc, 0x1d, 0x11, 0x34, 0x89, 0x69, 0x09, 0x03, 0x09, 0x0b, 0x22, 0x69, 
+0xe5, 0x68, 0xc0, 0x46, 0x1d, 0x95, 0xfc, 0x1d, 0x39, 0x34, 0x64, 0x8b, 
+0x64, 0x09, 0x05, 0x34, 0x24, 0x06, 0x24, 0x0e, 0x1c, 0x94, 0x56, 0x1a, 
+0x1b, 0x96, 0x1c, 0x9c, 0x2e, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x26, 
+0x1d, 0x9d, 0x1a, 0x68, 0x91, 0x42, 0x01, 0xd1, 0x32, 0x1c, 0x0b, 0xe0, 
+0x91, 0x42, 0x03, 0xd9, 0x52, 0x1b, 0x1b, 0x9e, 0xb5, 0x18, 0x00, 0xe0, 
+0x55, 0x1a, 0x01, 0x22, 0x24, 0x01, 0xac, 0x42, 0x00, 0xd3, 0x00, 0x22, 
+0x01, 0x2a, 0xe6, 0xd1, 0x91, 0x07, 0x01, 0x43, 0x09, 0x68, 0xc0, 0x46, 
+0x39, 0x60, 0x93, 0x07, 0x01, 0x1d, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 
+0x79, 0x60, 0xc1, 0x1d, 0x01, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 
+0xb9, 0x60, 0x1f, 0x99, 0x09, 0x68, 0x1e, 0x9a, 0xc0, 0x46, 0x51, 0x83, 
+0xc1, 0x1d, 0x1d, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x38, 0x63, 
+0x79, 0x62, 0xc1, 0x1d, 0x11, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 
+0xb9, 0x61, 0xc1, 0x1d, 0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 
+0xf9, 0x60, 0xc1, 0x1d, 0x17, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 
+0xf9, 0x83, 0x0e, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xf8, 0x81, 
+0x38, 0x68, 0x40, 0x08, 0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x60, 0xfb, 
+0x38, 0x1c, 0x00, 0xf0, 0x0b, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0x58, 0xff, 
+0x20, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x28, 0x03, 0x00, 0x80, 
+0x55, 0x55, 0x55, 0x55, 0xf8, 0xb5, 0x07, 0x1c, 
+0xf8, 0x1d, 0x39, 0x30, 0x41, 0x8b, 0x38, 0x4a, 0x91, 0x42, 0x00, 0xdd, 
+0x42, 0x83, 0x42, 0x8b, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x20, 0x3a, 0x1d, 
+0x06, 0xca, 0xbb, 0x6a, 0x02, 0xf0, 0x12, 0xff, 0x32, 0x4a, 0xc0, 0x46, 
+0x00, 0x92, 0x32, 0x4e, 0x30, 0x6a, 0x32, 0x4c, 0xe1, 0x6d, 0x41, 0x18, 
+0x38, 0x6b, 0xc3, 0x1d, 0x05, 0x33, 0x01, 0x20, 0x72, 0x6a, 0x02, 0xf0, 
+0xff, 0xfe, 0xe0, 0x6d, 0x18, 0x30, 0xb1, 0x6a, 0x81, 0x42, 0x00, 0xd8, 
+0x00, 0x20, 0xe0, 0x65, 0x17, 0x23, 0xdb, 0x01, 0x20, 0x1c, 0xe1, 0x6d, 
+0xe4, 0x18, 0xe2, 0x6b, 0x92, 0x00, 0x27, 0x4b, 0xc0, 0x46, 0x99, 0x50, 
+0x26, 0x4d, 0xa8, 0x6b, 0x41, 0x08, 0x05, 0xd3, 0x40, 0x08, 0x40, 0x00, 
+0xa8, 0x63, 0x01, 0x20, 0x01, 0xf0, 0xd8, 0xff, 0x22, 0x4a, 0x1f, 0x48, 
+0x29, 0x7b, 0x00, 0x29, 0x02, 0xd0, 0x69, 0x7b, 0x00, 0x29, 0x00, 0xd1, 
+0x1f, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x05, 0x1c, 0xe0, 0x6b, 0x80, 0x00, 
+0x19, 0x4b, 0xc3, 0x18, 0x05, 0xce, 0xc1, 0x1d, 0x11, 0x31, 0x01, 0x20, 
+0x02, 0xf0, 0xce, 0xfe, 0xe0, 0x6b, 0x01, 0x30, 0xe0, 0x63, 0x17, 0x28, 
+0x01, 0xd3, 0x00, 0x20, 0xe0, 0x63, 0x00, 0x20, 0x39, 0x6b, 0xc0, 0x46, 
+0x08, 0x65, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62, 0x33, 0x23, 
+0x9b, 0x01, 0xe8, 0x18, 0x41, 0x68, 0x00, 0x29, 0x03, 0xd1, 0x39, 0x6b, 
+0xc0, 0x46, 0x41, 0x60, 0x04, 0xe0, 0x39, 0x6b, 0x82, 0x68, 0xc0, 0x46, 
+0x11, 0x65, 0x39, 0x6b, 0xc0, 0x46, 0x81, 0x60, 0xf8, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xea, 0x05, 0x00, 0x00, 0x18, 0x00, 0x14, 0x02, 
+0xf8, 0x28, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 0x44, 0x82, 0x20, 0x40, 
+0x68, 0x0e, 0x00, 0x80, 0x04, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x03, 
+0xf0, 0xb5, 0x11, 0x4e, 0xff, 0x25, 0x01, 0x35, 0x10, 0x4f, 0xc0, 0x46, 
+0x35, 0x60, 0x38, 0x69, 0x01, 0x38, 0x38, 0x61, 0x7c, 0x68, 0x00, 0x2c, 
+0x10, 0xd0, 0x20, 0x6d, 0xc0, 0x46, 0x78, 0x60, 0x20, 0x1c, 0x00, 0xf0, 
+0x21, 0xf8, 0x20, 0x1c, 0x00, 0xf0, 0x04, 0xfa, 0x08, 0x48, 0x80, 0x6a, 
+0x00, 0x0c, 0x00, 0x07, 0xe9, 0xd1, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x05, 0x48, 0xc1, 0x79, 0x01, 0x31, 0xc1, 0x71, 0xf7, 0xe7, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xb0, 0xa8, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 
+0xa0, 0x82, 0x20, 0x40, 0x01, 0x20, 0x80, 0x03, 0x01, 0x49, 0xc0, 0x46, 
+0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0x00, 0xb0, 0x90, 0xb5, 0x07, 0x1c, 
+0x38, 0x68, 0xc0, 0x08, 0x09, 0xd3, 0x1d, 0x48, 0x01, 0x6a, 0x01, 0x39, 
+0x01, 0x62, 0x20, 0x30, 0x00, 0x79, 0x00, 0x28, 0x01, 0xd0, 0xfe, 0xf7, 
+0x09, 0xfe, 0x01, 0x23, 0x9b, 0x07, 0xf8, 0x1d, 0x1d, 0x30, 0x18, 0x43, 
+0x00, 0x68, 0x16, 0x4c, 0x21, 0x6a, 0x81, 0x42, 0x21, 0xd1, 0x01, 0x1c, 
+0x19, 0x43, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x01, 0x29, 0x1a, 0xd1, 
+0x00, 0xf0, 0x22, 0xf8, 0x20, 0x62, 0x20, 0x6a, 0xe1, 0x69, 0x88, 0x42, 
+0x05, 0xd0, 0x01, 0x21, 0x89, 0x07, 0x01, 0x43, 0x09, 0x68, 0x09, 0x04, 
+0xf2, 0xd0, 0x51, 0x21, 0x89, 0x03, 0x22, 0x6a, 0xe3, 0x6a, 0x9a, 0x42, 
+0x02, 0xd1, 0x20, 0x6b, 0x62, 0x6b, 0x80, 0x1a, 0x04, 0x38, 0xc8, 0x60, 
+0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x79, 0x6a, 0xc0, 0x46, 
+0x08, 0x60, 0xf7, 0xe7, 0xec, 0x05, 0x00, 0x80, 0x68, 0x1a, 0x00, 0x80, 
+0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x01, 0x31, 
+0x19, 0x43, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x18, 0x0d, 0x30, 
+0x81, 0x07, 0x02, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x04, 0x49, 
+0x4a, 0x6b, 0x12, 0x18, 0x0b, 0x6b, 0x9a, 0x42, 0x00, 0xd9, 0xc8, 0x6a, 
+0x70, 0x47, 0x00, 0x00, 0x68, 0x1a, 0x00, 0x80, 0x00, 0xb5, 0x04, 0x48, 
+0x80, 0x68, 0x10, 0x28, 0x01, 0xd3, 0x00, 0xf0, 0x05, 0xf8, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x68, 0x1a, 0x00, 0x80, 0x88, 0xb5, 0x0c, 0x4f, 
+0x38, 0x78, 0x00, 0x28, 0x11, 0xd1, 0x0b, 0x49, 0x10, 0x20, 0x02, 0xf0, 
+0xfb, 0xfd, 0x00, 0x28, 0x0b, 0xd0, 0x01, 0x20, 0x38, 0x70, 0x08, 0x4a, 
+0xc0, 0x46, 0x00, 0x92, 0x07, 0x48, 0x42, 0x68, 0x07, 0x4b, 0x01, 0x68, 
+0x00, 0x20, 0x02, 0xf0, 0xe5, 0xfd, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x78, 0x1a, 0x00, 0x80, 0x69, 0x2c, 0xff, 0xff, 0x10, 0x00, 0x35, 0x02, 
+0xf8, 0x28, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, 0x90, 0xb5, 0x01, 0x20, 
+0x40, 0x02, 0x10, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x0f, 0x4f, 0x10, 0x21, 
+0xf8, 0x1d, 0x3d, 0x30, 0x02, 0xf0, 0x52, 0xfc, 0x19, 0x23, 0xdb, 0x01, 
+0xfc, 0x18, 0xa0, 0x68, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xf0, 0x14, 0xf8, 
+0x00, 0x20, 0xc9, 0x23, 0x1b, 0x01, 0xf9, 0x18, 0x08, 0x70, 0xa0, 0x68, 
+0x10, 0x28, 0x04, 0xd3, 0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xf9, 0x18, 
+0x48, 0x72, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 
+0xe8, 0x0d, 0x00, 0x80, 0xf8, 0xb5, 0x37, 0x48, 0x19, 0x23, 0xdb, 0x01, 
+0xc1, 0x18, 0x89, 0x68, 0x35, 0x4d, 0x10, 0x29, 0x00, 0xd9, 0x10, 0x21, 
+0x29, 0x62, 0x32, 0x48, 0xc1, 0x6c, 0x00, 0x6e, 0x81, 0x42, 0x07, 0xd9, 
+0x08, 0x1a, 0x07, 0x09, 0x00, 0x24, 0x28, 0x6a, 0xb8, 0x42, 0x12, 0xd2, 
+0x07, 0x1c, 0x10, 0xe0, 0x81, 0x42, 0x2a, 0xd2, 0x2c, 0x4a, 0x52, 0x6b, 
+0x10, 0x1a, 0x07, 0x09, 0x28, 0x6a, 0xb8, 0x42, 0x05, 0xd9, 0x0c, 0x09, 
+0x39, 0x19, 0x88, 0x42, 0x03, 0xd2, 0xc4, 0x1b, 0x01, 0xe0, 0x00, 0x24, 
+0x07, 0x1c, 0x3e, 0x19, 0x30, 0x01, 0x25, 0x49, 0x02, 0xf0, 0x8a, 0xfd, 
+0x00, 0x28, 0x3d, 0xd0, 0x23, 0x48, 0x00, 0x2c, 0x1a, 0xd1, 0x1e, 0x49, 
+0x3a, 0x01, 0x2f, 0x62, 0x09, 0x6e, 0x8c, 0x18, 0x1d, 0x4d, 0x6b, 0x6b, 
+0xa3, 0x42, 0x00, 0xd8, 0xe4, 0x1a, 0x1e, 0x4b, 0x1a, 0x43, 0x00, 0x92, 
+0xea, 0x6a, 0x51, 0x18, 0x2a, 0x6b, 0x03, 0x1c, 0x20, 0xe0, 0x1b, 0x48, 
+0x01, 0x6b, 0x01, 0x31, 0x01, 0x63, 0x00, 0x20, 0x28, 0x62, 0xf8, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x10, 0x49, 0x24, 0x01, 0x3f, 0x01, 0x11, 0x22, 
+0x52, 0x05, 0x3a, 0x43, 0x2e, 0x62, 0x00, 0x92, 0x0e, 0x4d, 0xea, 0x6a, 
+0x09, 0x6e, 0x51, 0x18, 0x03, 0x1c, 0x06, 0x1c, 0x00, 0x20, 0x2a, 0x6b, 
+0x02, 0xf0, 0x50, 0xfd, 0x0c, 0x4a, 0x22, 0x43, 0x00, 0x92, 0xbb, 0x19, 
+0xe9, 0x6a, 0x2a, 0x6b, 0x00, 0x20, 0x02, 0xf0, 0x47, 0xfd, 0x03, 0x48, 
+0xc0, 0x46, 0x04, 0x66, 0x00, 0xf0, 0x10, 0xf8, 0x01, 0x20, 0xda, 0xe7, 
+0xe8, 0x0d, 0x00, 0x80, 0xa8, 0x1a, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 
+0xd1, 0x2d, 0xff, 0xff, 0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x36, 0x02, 
+0xa0, 0x82, 0x20, 0x40, 0x04, 0x48, 0x01, 0x6e, 0x04, 0x4a, 0x80, 0x30, 
+0xd1, 0x60, 0x02, 0x23, 0x81, 0x6b, 0x19, 0x43, 0x81, 0x63, 0x70, 0x47, 
+0xe8, 0x0d, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, 
+0x01, 0x20, 0x80, 0x02, 0x1c, 0x49, 0xc0, 0x46, 
+0x08, 0x60, 0x00, 0x27, 0x1b, 0x4e, 0x33, 0x23, 0x9b, 0x01, 0xf5, 0x18, 
+0x28, 0x6a, 0x00, 0x28, 0x1d, 0xd9, 0x19, 0x4c, 0x68, 0x46, 0x10, 0x21, 
+0x02, 0xf0, 0x96, 0xfb, 0x68, 0x46, 0x00, 0xf0, 0x33, 0xf8, 0x00, 0x28, 
+0x04, 0xd0, 0x15, 0x49, 0x48, 0x69, 0x01, 0x30, 0x48, 0x61, 0x0a, 0xe0, 
+0x13, 0x49, 0x60, 0x7b, 0x01, 0x30, 0x60, 0x73, 0x88, 0x79, 0x01, 0x30, 
+0x88, 0x71, 0x11, 0x48, 0x00, 0x68, 0x02, 0xf0, 0x6b, 0xf9, 0x28, 0x6a, 
+0x01, 0x37, 0xb8, 0x42, 0xe2, 0xd8, 0xbb, 0x23, 0x1b, 0x01, 0xf0, 0x18, 
+0x81, 0x7a, 0x00, 0x29, 0x03, 0xd0, 0x00, 0x21, 0x81, 0x72, 0xff, 0xf7, 
+0x1d, 0xfb, 0xff, 0xf7, 0xe3, 0xfe, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xe8, 0x0d, 0x00, 0x80, 
+0xb0, 0x82, 0x20, 0x40, 0x08, 0x83, 0x20, 0x40, 0xa0, 0x82, 0x20, 0x40, 
+0xd8, 0x03, 0x00, 0x80, 0x90, 0xb4, 0x17, 0x4f, 0x19, 0x23, 0xdb, 0x01, 
+0xf9, 0x18, 0x00, 0x22, 0x8b, 0x68, 0x00, 0x2b, 0x23, 0xd0, 0x01, 0x3b, 
+0x8b, 0x60, 0x33, 0x23, 0x9b, 0x01, 0xff, 0x18, 0x7b, 0x69, 0x1c, 0x6d, 
+0xc0, 0x46, 0x7c, 0x61, 0x04, 0x68, 0xc0, 0x46, 0x5c, 0x60, 0x44, 0x68, 
+0xc0, 0x46, 0x9c, 0x60, 0x84, 0x68, 0xc0, 0x46, 0x1c, 0x61, 0xc0, 0x68, 
+0xc0, 0x46, 0x58, 0x61, 0x1a, 0x65, 0xc8, 0x68, 0x42, 0x1c, 0xca, 0x60, 
+0x00, 0x28, 0x03, 0xd0, 0xf8, 0x69, 0xc0, 0x46, 0x03, 0x65, 0x00, 0xe0, 
+0xbb, 0x61, 0xfb, 0x61, 0x18, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0x10, 0x1c, 
+0xfb, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x0a, 0x4a, 0x33, 0x23, 
+0x9b, 0x01, 0xd1, 0x18, 0x88, 0x69, 0x19, 0x23, 0xdb, 0x01, 0xd2, 0x18, 
+0xd3, 0x68, 0x00, 0x2b, 0x06, 0xd0, 0x01, 0x3b, 0xd3, 0x60, 0x8a, 0x69, 
+0x12, 0x6d, 0xc0, 0x46, 0x8a, 0x61, 0x70, 0x47, 0x00, 0x21, 0xd1, 0x60, 
+0xfb, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x06, 0x4a, 0xd1, 0x68, 
+0x4b, 0x1c, 0xd3, 0x60, 0x40, 0x32, 0x00, 0x29, 0x01, 0xd0, 0x91, 0x69, 
+0x00, 0xe0, 0x00, 0x21, 0x01, 0x65, 0x90, 0x61, 0x70, 0x47, 0x00, 0x00, 
+0x68, 0x1a, 0x00, 0x80, 0x06, 0x4a, 0x91, 0x68, 0x4b, 0x1c, 0x93, 0x60, 
+0x40, 0x32, 0x00, 0x29, 0x01, 0xd0, 0x51, 0x69, 0x00, 0xe0, 0x00, 0x21, 
+0x01, 0x65, 0x50, 0x61, 0x70, 0x47, 0x00, 0x00, 0x68, 0x1a, 0x00, 0x80, 
+0x90, 0xb4, 0x00, 0x21, 0x0f, 0x4a, 0x97, 0x89, 0x92, 0x6a, 0x4b, 0x00, 
+0x1b, 0x18, 0x9b, 0x8a, 0x00, 0x2b, 0x12, 0xd0, 0xbb, 0x42, 0x10, 0xdc, 
+0x1c, 0x1c, 0x58, 0x23, 0x63, 0x43, 0xd3, 0x18, 0xdc, 0x1f, 0x49, 0x3c, 
+0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 
+0x03, 0x2b, 0x02, 0xd0, 0x00, 0x20, 0x90, 0xbc, 0x70, 0x47, 0x01, 0x31, 
+0x04, 0x29, 0xe4, 0xd3, 0x01, 0x20, 0xf8, 0xe7, 0xc8, 0x29, 0x00, 0x80, 
+0xf7, 0xb5, 0x86, 0xb0, 0x3d, 0x4a, 0x07, 0x1c, 0xd1, 0x69, 0x8f, 0x40, 
+0x03, 0x1c, 0x14, 0x6a, 0xe3, 0x40, 0x5f, 0x40, 0x07, 0x9e, 0x8e, 0x40, 
+0x77, 0x40, 0xcf, 0x40, 0x94, 0x69, 0xc0, 0x46, 0x05, 0x94, 0x03, 0x1c, 
+0xa3, 0x40, 0x00, 0x25, 0x14, 0x69, 0xc0, 0x46, 0x04, 0x94, 0x00, 0x2c, 
+0x5d, 0xd9, 0x1c, 0x1c, 0x32, 0x4e, 0x26, 0x43, 0x94, 0x69, 0xe6, 0x40, 
+0x33, 0x1c, 0x03, 0x96, 0x53, 0x6a, 0xc0, 0x46, 0x02, 0x93, 0xd2, 0x6a, 
+0xc0, 0x46, 0x01, 0x92, 0xbb, 0x00, 0x02, 0x9a, 0xd2, 0x58, 0x13, 0x1c, 
+0x05, 0x9c, 0xe3, 0x40, 0x03, 0x9c, 0xa3, 0x42, 
+0x3e, 0xd1, 0x8a, 0x40, 0xca, 0x40, 0x14, 0x1c, 0x63, 0x00, 0x1b, 0x19, 
+0x5b, 0x01, 0x01, 0x9a, 0xd2, 0x18, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 
+0x01, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x03, 0x2b, 
+0x2c, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x51, 0x36, 0x33, 0x43, 
+0x1b, 0x68, 0x07, 0x9e, 0x1e, 0x40, 0x00, 0x96, 0x01, 0x23, 0x9b, 0x07, 
+0xd6, 0x1d, 0x49, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x83, 0x42, 0x1b, 0xd1, 
+0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x4d, 0x36, 0x33, 0x43, 0x1b, 0x68, 
+0x00, 0x9e, 0xb3, 0x42, 0x12, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0x1a, 0x43, 
+0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x08, 0x9b, 0x32, 0x2b, 0x04, 0xd1, 
+0x02, 0x2a, 0x07, 0xd1, 0x20, 0x04, 0x00, 0x14, 0x0f, 0xe0, 0x08, 0x9b, 
+0x33, 0x2b, 0x01, 0xd1, 0x01, 0x2a, 0xf7, 0xd0, 0x04, 0x9a, 0x01, 0x37, 
+0x97, 0x42, 0x00, 0xd3, 0x00, 0x27, 0x04, 0x9a, 0x01, 0x35, 0xaa, 0x42, 
+0xae, 0xd8, 0x00, 0x20, 0xc0, 0x43, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xc8, 0x29, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 
+0xf0, 0xb5, 0x27, 0x4d, 0x68, 0x69, 0x00, 0x28, 0x06, 0xd0, 0x26, 0x48, 
+0x00, 0x68, 0x02, 0xf0, 0x31, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x23, 0x4c, 0x00, 0x26, 0xa0, 0x68, 0x23, 0x4f, 0x00, 0x28, 0x16, 0xd0, 
+0x0f, 0xe0, 0x28, 0x6a, 0x02, 0x28, 0x02, 0xd3, 0x01, 0x20, 0x38, 0x71, 
+0x0f, 0xe0, 0xa6, 0x60, 0xfd, 0xf7, 0x08, 0xff, 0x00, 0x28, 0xea, 0xd1, 
+0x28, 0x6a, 0x02, 0x28, 0x01, 0xd3, 0x01, 0x20, 0x38, 0x71, 0xe8, 0x68, 
+0x00, 0x28, 0x02, 0xd0, 0x38, 0x79, 0x00, 0x28, 0xe9, 0xd0, 0x68, 0x68, 
+0x00, 0x28, 0x1b, 0xd0, 0x01, 0x20, 0xa0, 0x60, 0xfe, 0xf7, 0xd2, 0xfb, 
+0x00, 0x28, 0xd6, 0xd1, 0x68, 0x68, 0x00, 0x28, 0xf6, 0xd1, 0x11, 0xe0, 
+0x00, 0x28, 0xd0, 0xd1, 0x28, 0x6a, 0x02, 0x28, 0x02, 0xd3, 0x01, 0x20, 
+0x38, 0x71, 0xca, 0xe7, 0xa6, 0x60, 0xfd, 0xf7, 0xe3, 0xfe, 0x00, 0x28, 
+0xc5, 0xd1, 0x28, 0x6a, 0x02, 0x28, 0x01, 0xd3, 0x01, 0x20, 0x38, 0x71, 
+0xe8, 0x68, 0x00, 0x28, 0xbd, 0xd0, 0x38, 0x79, 0x00, 0x28, 0xe7, 0xd0, 
+0xb9, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0xdc, 0x03, 0x00, 0x80, 
+0xc8, 0x29, 0x00, 0x80, 0x0c, 0x06, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, 
+0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 0x90, 0xb5, 0x40, 0x20, 
+0x1d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x01, 0xf0, 0x9f, 0xfc, 0x03, 0x23, 
+0x1b, 0x07, 0x41, 0x68, 0x19, 0x40, 0x0c, 0x0f, 0x61, 0x01, 0x09, 0x1b, 
+0x89, 0x00, 0x18, 0x4a, 0x8f, 0x18, 0x01, 0x21, 0x39, 0x80, 0x81, 0x6a, 
+0xc0, 0x46, 0x79, 0x65, 0x41, 0x6a, 0xc0, 0x46, 0x79, 0x67, 0xb9, 0x6c, 
+0xfa, 0x6c, 0x89, 0x18, 0xb9, 0x64, 0x00, 0x21, 0xf9, 0x64, 0xba, 0x6b, 
+0x3b, 0x6d, 0xd2, 0x18, 0xba, 0x63, 0x39, 0x65, 0x42, 0x6a, 0x20, 0x32, 
+0x51, 0x71, 0x79, 0x6d, 0x7a, 0x6f, 0xd2, 0x6d, 0xc0, 0x46, 0x11, 0x60, 
+0xfd, 0xf7, 0x10, 0xf8, 0x20, 0x01, 0x09, 0x49, 0x40, 0x18, 0x19, 0x23, 
+0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0x78, 0x6f, 
+0x01, 0xf0, 0xc8, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 0x1c, 0x1c, 0x00, 0x80, 
+0xf0, 0xb5, 0x40, 0x20, 0x12, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x01, 0xf0, 
+0x5b, 0xfc, 0x07, 0x1c, 0x40, 0x68, 0x03, 0x23, 
+0x1b, 0x07, 0x18, 0x40, 0x06, 0x0f, 0x70, 0x01, 0x80, 0x1b, 0x80, 0x00, 
+0x0c, 0x49, 0x44, 0x18, 0xb8, 0x6a, 0xc0, 0x46, 0x60, 0x65, 0x78, 0x6a, 
+0xc0, 0x46, 0x60, 0x67, 0x80, 0x6f, 0x05, 0x1d, 0xe5, 0x63, 0xb9, 0x69, 
+0x28, 0x1c, 0x02, 0xf0, 0x8f, 0xf9, 0x38, 0x1c, 0x21, 0x1c, 0x32, 0x1c, 
+0x2b, 0x1c, 0x00, 0xf0, 0x20, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 0xf0, 0xb5, 0x4b, 0x6f, 
+0x9b, 0x6f, 0x1f, 0x1d, 0xcf, 0x63, 0x05, 0x68, 0x00, 0x23, 0x84, 0x69, 
+0xa4, 0x08, 0x08, 0xd0, 0x9c, 0x00, 0x2e, 0x59, 0xc0, 0x46, 0x3e, 0x51, 
+0x84, 0x69, 0xa4, 0x08, 0x01, 0x33, 0x9c, 0x42, 0xf6, 0xd8, 0x3b, 0x1c, 
+0x00, 0xf0, 0x03, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xb5, 
+0x81, 0xb0, 0x04, 0x1c, 0x1d, 0x1c, 0x0f, 0x1c, 0x46, 0x48, 0x01, 0x69, 
+0x01, 0x31, 0x01, 0x61, 0xf9, 0x1d, 0x51, 0x31, 0xbd, 0x65, 0x00, 0x91, 
+0x20, 0x1c, 0xfd, 0xf7, 0xa3, 0xfc, 0xf8, 0x6d, 0x40, 0x09, 0x36, 0xd2, 
+0xb8, 0x6d, 0x06, 0x7b, 0x43, 0x7b, 0x1b, 0x02, 0x1e, 0x43, 0x17, 0x21, 
+0x49, 0x02, 0x01, 0x73, 0x0b, 0x0a, 0x43, 0x73, 0x00, 0x99, 0x20, 0x1c, 
+0xfd, 0xf7, 0x92, 0xfc, 0xb8, 0x6d, 0xc0, 0x46, 0x06, 0x73, 0x33, 0x0a, 
+0x43, 0x73, 0xf8, 0x6d, 0x40, 0x09, 0x20, 0xd2, 0x60, 0x68, 0x01, 0x04, 
+0x09, 0x0c, 0x03, 0x98, 0x01, 0xf0, 0xce, 0xfc, 0x60, 0x68, 0x32, 0x4b, 
+0x18, 0x43, 0x60, 0x60, 0x20, 0x1c, 0x01, 0xf0, 0x37, 0xfd, 0x00, 0x25, 
+0x7d, 0x60, 0xbd, 0x60, 0x3d, 0x64, 0x7d, 0x64, 0x20, 0x1c, 0xfc, 0xf7, 
+0x77, 0xff, 0x38, 0x88, 0x40, 0x23, 0x18, 0x43, 0x38, 0x80, 0x7d, 0x62, 
+0x29, 0x48, 0xc0, 0x46, 0xb8, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0xa0, 0xfb, 
+0x44, 0xe0, 0x20, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, 
+0x00, 0x68, 0xc0, 0x46, 0x78, 0x64, 0x60, 0x68, 0x02, 0x04, 0x12, 0x0c, 
+0x78, 0x6e, 0x01, 0x26, 0xc1, 0x1d, 0x0d, 0x31, 0x8a, 0x42, 0x02, 0xd2, 
+0x3a, 0x64, 0x08, 0x1c, 0x0e, 0xe0, 0x41, 0x19, 0x89, 0x89, 0xf0, 0x23, 
+0x19, 0x40, 0x09, 0x09, 0x89, 0x00, 0x40, 0x18, 0xf8, 0x60, 0xf9, 0x61, 
+0x61, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x81, 0x42, 0x16, 0xd2, 0x39, 0x64, 
+0x63, 0x68, 0x19, 0x04, 0x09, 0x0c, 0x40, 0x1a, 0x03, 0x30, 0x80, 0x08, 
+0x82, 0x00, 0xa0, 0x61, 0x20, 0x68, 0x09, 0x18, 0x9b, 0x18, 0x63, 0x60, 
+0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x00, 0xf0, 0xb6, 0xfa, 0x7e, 0x80, 
+0x20, 0x1c, 0x00, 0xf0, 0xbf, 0xfb, 0x0b, 0xe0, 0xb9, 0x68, 0x08, 0x1a, 
+0x00, 0x25, 0x78, 0x62, 0xbd, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0x3c, 0xfc, 
+0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x64, 0xf8, 0x05, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 
+0x01, 0x00, 0x00, 0xc0, 0xf0, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x38, 0x6c, 
+0xf9, 0x6b, 0x0d, 0x18, 0x21, 0x68, 0x41, 0x18, 0x00, 0x20, 0xa2, 0x69, 
+0x00, 0x2a, 0x0b, 0xd9, 0x82, 0x00, 0x56, 0x18, 0x01, 0x23, 0x9b, 0x07, 
+0x33, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xab, 0x50, 0xa2, 0x69, 0x01, 0x30, 
+0x82, 0x42, 0xf3, 0xd8, 0x78, 0x6e, 0xf9, 0x6b, 0x09, 0x18, 0x89, 0x89, 
+0xf0, 0x23, 0x19, 0x40, 0x09, 0x09, 0x89, 0x00, 0x40, 0x18, 0xf8, 0x60, 
+0xf9, 0x61, 0x20, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, 
+0x01, 0x68, 0x78, 0x6c, 0xfc, 0xf7, 0xdb, 0xff, 
+0x78, 0x64, 0x60, 0x68, 0x01, 0x04, 0x09, 0x0c, 0xf8, 0x68, 0x81, 0x42, 
+0x19, 0xd2, 0x39, 0x64, 0x63, 0x68, 0x19, 0x04, 0x09, 0x0c, 0x40, 0x1a, 
+0x03, 0x30, 0x80, 0x08, 0x82, 0x00, 0xa0, 0x61, 0x20, 0x68, 0x09, 0x18, 
+0x9b, 0x18, 0x63, 0x60, 0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x00, 0xf0, 
+0x56, 0xfa, 0x01, 0x20, 0x78, 0x80, 0x20, 0x1c, 0x00, 0xf0, 0x5e, 0xfb, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb9, 0x68, 0x08, 0x1a, 0x78, 0x62, 
+0x00, 0x20, 0xb8, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0xd9, 0xfb, 0x20, 0x1c, 
+0x39, 0x1c, 0x00, 0xf0, 0x01, 0xf8, 0xef, 0xe7, 0xf0, 0xb5, 0x84, 0xb0, 
+0x04, 0x1c, 0x0f, 0x1c, 0x8e, 0x48, 0x41, 0x69, 0x01, 0x31, 0x41, 0x61, 
+0x03, 0x20, 0x00, 0x07, 0x61, 0x68, 0x08, 0x40, 0x06, 0x0f, 0x0a, 0x04, 
+0x12, 0x0c, 0x20, 0x68, 0x11, 0x18, 0xfb, 0x68, 0xd2, 0x1a, 0x7b, 0x68, 
+0x9d, 0x1a, 0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, 
+0x26, 0xfa, 0x00, 0x20, 0x78, 0x80, 0x20, 0x1c, 0x00, 0xf0, 0x2e, 0xfb, 
+0x60, 0x68, 0x40, 0x19, 0x01, 0x04, 0x09, 0x0c, 0x60, 0x60, 0x30, 0x1c, 
+0x01, 0xf0, 0xe2, 0xfb, 0x7d, 0x4e, 0x0b, 0x23, 0x1b, 0x02, 0xf0, 0x18, 
+0xc0, 0x68, 0x00, 0x28, 0x19, 0xd0, 0x00, 0x25, 0x2d, 0x23, 0x9b, 0x01, 
+0xf0, 0x18, 0x80, 0x68, 0x00, 0x28, 0x12, 0xd0, 0xaa, 0x00, 0x92, 0x19, 
+0x2d, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0x92, 0x68, 0x20, 0x1c, 0x39, 0x1c, 
+0x01, 0xf0, 0x22, 0xfe, 0x01, 0x35, 0xa8, 0x00, 0x80, 0x19, 0x2d, 0x23, 
+0x9b, 0x01, 0xc0, 0x18, 0x80, 0x68, 0x00, 0x28, 0xec, 0xd1, 0xf8, 0x6b, 
+0x01, 0x1f, 0x8a, 0x1c, 0xfa, 0x63, 0xfa, 0x68, 0x7d, 0x6c, 0x00, 0xf0, 
+0xbb, 0xf9, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x28, 0x1c, 0xfc, 0xf7, 
+0x56, 0xff, 0x03, 0x90, 0xf9, 0x6b, 0x3a, 0x6e, 0x8e, 0x18, 0x20, 0x68, 
+0x12, 0x18, 0x01, 0x92, 0x7a, 0x6e, 0x8d, 0x18, 0x11, 0x18, 0x02, 0x91, 
+0xc8, 0x1d, 0x09, 0x30, 0xe0, 0x60, 0xb1, 0x88, 0x08, 0x02, 0x09, 0x0a, 
+0x09, 0x06, 0x09, 0x0e, 0x08, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x78, 0x61, 
+0x68, 0x68, 0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 
+0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 
+0x00, 0x06, 0x08, 0x43, 0x38, 0x61, 0xa8, 0x89, 0x09, 0x23, 0x1b, 0x02, 
+0x18, 0x40, 0xb8, 0x61, 0xa8, 0x89, 0x98, 0x43, 0xa8, 0x81, 0xa8, 0x89, 
+0x02, 0x99, 0xc0, 0x46, 0x88, 0x81, 0x00, 0x20, 0x70, 0x80, 0xb0, 0x80, 
+0x70, 0x81, 0x68, 0x60, 0x28, 0x82, 0xb9, 0x6e, 0x30, 0x1c, 0xfc, 0xf7, 
+0x2e, 0xff, 0x38, 0x86, 0xfa, 0x69, 0x30, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 
+0x49, 0xff, 0x78, 0x86, 0x3d, 0x8e, 0x78, 0x8e, 0x03, 0x99, 0xfc, 0xf7, 
+0x0e, 0xff, 0x00, 0x90, 0x60, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x39, 0x6e, 
+0x41, 0x1a, 0x09, 0x04, 0x09, 0x0c, 0x7a, 0x6e, 0x82, 0x1a, 0x13, 0x04, 
+0x1b, 0x0c, 0x1a, 0x02, 0x1b, 0x0a, 0x1a, 0x43, 0x16, 0x04, 0x36, 0x0c, 
+0xba, 0x68, 0x82, 0x42, 0x01, 0xd2, 0x00, 0x20, 0x00, 0xe0, 0x10, 0x1a, 
+0xb8, 0x60, 0x08, 0x02, 0x09, 0x12, 0x09, 0x06, 0x09, 0x0e, 0x08, 0x43, 
+0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, 0x41, 0x80, 0x28, 0x1c, 
+0xfc, 0xf7, 0xe9, 0xfe, 0x05, 0x1c, 0x00, 0x98, 0x31, 0x1c, 0xfc, 0xf7, 
+0xe4, 0xfe, 0x06, 0x1c, 0x78, 0x69, 0x00, 0x04, 0x00, 0x0c, 0x01, 0x02, 
+0x00, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 
+0x01, 0x98, 0xc0, 0x46, 0x81, 0x80, 0x28, 0x1c, 0xfc, 0xf7, 0xd5, 0xfe, 
+0x79, 0x69, 0x01, 0x31, 0xc0, 0x43, 0x79, 0x61, 0x01, 0x9a, 0xc0, 0x46, 
+0x50, 0x81, 0x38, 0x69, 0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 
+0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 
+0x11, 0x43, 0x00, 0x06, 0x01, 0x43, 0x30, 0x1c, 0xfc, 0xf7, 0xbd, 0xfe, 
+0x39, 0x69, 0x7a, 0x68, 0x89, 0x18, 0x39, 0x61, 0xb9, 0x68, 0x00, 0x29, 
+0x09, 0xd1, 0x02, 0x99, 0x89, 0x89, 0xba, 0x69, 0x11, 0x43, 0x02, 0x9a, 
+0xc0, 0x46, 0x91, 0x81, 0xb9, 0x69, 0xfc, 0xf7, 0xac, 0xfe, 0x20, 0x82, 
+0x00, 0x20, 0x60, 0x82, 0xf8, 0x6d, 0x41, 0x08, 0x16, 0xd3, 0x80, 0x0a, 
+0x0a, 0xd3, 0x60, 0x68, 0x10, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 
+0x09, 0x0a, 0x08, 0x43, 0x21, 0x68, 0xc0, 0x46, 0x08, 0x82, 0x09, 0xe0, 
+0x60, 0x68, 0x0c, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 
+0x08, 0x43, 0x21, 0x68, 0xc0, 0x46, 0x88, 0x81, 0x04, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x78, 0x2a, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 
+0xf1, 0xb5, 0x84, 0xb0, 0x6e, 0x4d, 0x28, 0x69, 0x01, 0x22, 0x04, 0x99, 
+0x8a, 0x40, 0x90, 0x43, 0x28, 0x61, 0x04, 0x98, 0x43, 0x01, 0x18, 0x1a, 
+0x80, 0x00, 0x16, 0x1c, 0x69, 0x49, 0x44, 0x18, 0xe0, 0x6b, 0xc0, 0x46, 
+0x00, 0x90, 0xa0, 0x68, 0x00, 0x28, 0x01, 0xd1, 0x00, 0x26, 0x26, 0xe0, 
+0x65, 0x48, 0x41, 0x69, 0x01, 0x31, 0x41, 0x61, 0x04, 0x98, 0xfc, 0xf7, 
+0x4f, 0xfd, 0x07, 0x1c, 0x03, 0xd1, 0x28, 0x69, 0x30, 0x43, 0x28, 0x61, 
+0xb5, 0xe0, 0xa0, 0x68, 0x65, 0x68, 0xa8, 0x42, 0x00, 0xd2, 0x05, 0x1c, 
+0xa1, 0x6c, 0xa9, 0x42, 0x16, 0xd2, 0x40, 0x1a, 0x62, 0x6a, 0x10, 0x1a, 
+0x00, 0x26, 0x60, 0x62, 0xa6, 0x60, 0xa6, 0x62, 0x20, 0x88, 0x48, 0x23, 
+0x18, 0x43, 0x20, 0x80, 0x0d, 0x1c, 0x09, 0xd1, 0x38, 0x1c, 0xfc, 0xf7, 
+0x5f, 0xfd, 0x03, 0x20, 0x60, 0x80, 0x66, 0x60, 0x20, 0x1c, 0x00, 0xf0, 
+0x8d, 0xf9, 0x96, 0xe0, 0xe1, 0x68, 0x38, 0x68, 0x09, 0x18, 0xc3, 0x1f, 
+0x05, 0x3b, 0x20, 0x1c, 0x02, 0x39, 0x2a, 0x1c, 0x00, 0xf0, 0xcd, 0xf8, 
+0x38, 0x1c, 0x00, 0xf0, 0xd7, 0xf9, 0xe0, 0x68, 0x46, 0x19, 0x78, 0x68, 
+0x30, 0x43, 0x78, 0x60, 0x04, 0x98, 0x31, 0x1c, 0x01, 0xf0, 0x8a, 0xfa, 
+0x21, 0x6e, 0x00, 0x98, 0x08, 0x18, 0x01, 0x90, 0x70, 0x1a, 0x00, 0x04, 
+0x00, 0x0c, 0x61, 0x6e, 0x71, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, 
+0x12, 0x0a, 0x11, 0x43, 0x09, 0x04, 0x09, 0x0c, 0x02, 0x91, 0x01, 0x02, 
+0x00, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, 
+0x41, 0x80, 0x20, 0x8e, 0xfc, 0xf7, 0x11, 0xfe, 0x06, 0x1c, 0x60, 0x8e, 
+0x02, 0x99, 0xfc, 0xf7, 0x0c, 0xfe, 0x03, 0x90, 0x60, 0x69, 0x01, 0x04, 
+0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 
+0x01, 0x98, 0xc0, 0x46, 0x81, 0x80, 0x30, 0x1c, 0xfc, 0xf7, 0xfd, 0xfd, 
+0x61, 0x69, 0x01, 0x31, 0xc0, 0x43, 0x61, 0x61, 0x01, 0x99, 0xc0, 0x46, 
+0x48, 0x81, 0x60, 0x6e, 0x00, 0x99, 0x46, 0x18, 0x20, 0x69, 0x01, 0x0e, 
+0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 
+0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x01, 0x43, 
+0x71, 0x60, 0x03, 0x98, 0xfc, 0xf7, 0xe1, 0xfd, 0x21, 0x69, 0x49, 0x19, 
+0x21, 0x61, 0xa1, 0x68, 0x49, 0x1b, 0xa1, 0x60, 
+0x06, 0xd1, 0xb1, 0x89, 0xa2, 0x69, 0x11, 0x43, 0xb1, 0x81, 0xa1, 0x69, 
+0xfc, 0xf7, 0xd3, 0xfd, 0x38, 0x82, 0x61, 0x6e, 0x38, 0x68, 0x09, 0x18, 
+0x0e, 0x31, 0xf9, 0x60, 0xe2, 0x68, 0x00, 0x99, 0x04, 0x38, 0x00, 0xf0, 
+0x4c, 0xf8, 0x02, 0x20, 0x78, 0x82, 0xe0, 0x6d, 0x41, 0x08, 0x16, 0xd3, 
+0x80, 0x0a, 0x0a, 0xd3, 0x78, 0x68, 0x10, 0x38, 0x01, 0x04, 0x09, 0x0c, 
+0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x39, 0x68, 0xc0, 0x46, 0xc8, 0x81, 
+0x09, 0xe0, 0x78, 0x68, 0x0c, 0x38, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 
+0x09, 0x0a, 0x08, 0x43, 0x39, 0x68, 0xc0, 0x46, 0x48, 0x81, 0x05, 0xb0, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x3c, 0x2c, 0x00, 0x80, 
+0xc8, 0x2a, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, 0xf7, 0xb5, 0x03, 0x1c, 
+0x0f, 0x1c, 0x00, 0x20, 0x1c, 0x68, 0x26, 0x04, 0x31, 0x1c, 0x1d, 0x1d, 
+0xfc, 0xf7, 0x97, 0xfd, 0x40, 0xc7, 0x02, 0x9a, 0xd1, 0x1c, 0x89, 0x08, 
+0x01, 0x39, 0x4a, 0x1e, 0x02, 0x92, 0x00, 0x29, 0x0d, 0xd0, 0x21, 0x0c, 
+0x10, 0xcd, 0x22, 0x04, 0x0a, 0x43, 0x11, 0x1c, 0x16, 0x1c, 0xfc, 0xf7, 
+0x86, 0xfd, 0x40, 0xc7, 0x02, 0x99, 0x4a, 0x1e, 0x02, 0x92, 0x00, 0x29, 
+0xf1, 0xd1, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0x08, 
+0x80, 0x00, 0x89, 0x08, 0x89, 0x00, 0x03, 0x32, 0x93, 0x08, 0x5a, 0x1e, 
+0x00, 0x2b, 0x05, 0xd0, 0x08, 0xc9, 0x08, 0xc0, 0x13, 0x1c, 0x01, 0x3a, 
+0x00, 0x2b, 0xf9, 0xd1, 0x70, 0x47, 0xff, 0xb5, 0x86, 0xb0, 0x17, 0x1c, 
+0x00, 0x26, 0x06, 0x98, 0x80, 0x6c, 0xc0, 0x1b, 0x06, 0x99, 0xc0, 0x46, 
+0x88, 0x64, 0x01, 0x20, 0xc0, 0x05, 0x06, 0x99, 0x89, 0x6b, 0xc0, 0x46, 
+0x01, 0x91, 0x06, 0x99, 0x4c, 0x6b, 0x67, 0xe0, 0x21, 0x68, 0xc0, 0x46, 
+0x02, 0x91, 0x61, 0x68, 0xc0, 0x46, 0x03, 0x91, 0xa1, 0x68, 0xc0, 0x46, 
+0x04, 0x91, 0x02, 0xa9, 0x49, 0x88, 0xb9, 0x42, 0x08, 0xd2, 0x02, 0xad, 
+0x6d, 0x88, 0x02, 0xa9, 0x49, 0x88, 0x7f, 0x1a, 0x00, 0x21, 0x02, 0xab, 
+0x59, 0x80, 0x19, 0xe0, 0x02, 0xa9, 0x49, 0x88, 0xc9, 0x1b, 0x02, 0xab, 
+0x59, 0x80, 0x3d, 0x1c, 0x00, 0x27, 0x01, 0x21, 0x49, 0x06, 0x07, 0x9b, 
+0x9a, 0x07, 0x92, 0x0f, 0x0d, 0xd0, 0xeb, 0x06, 0xdb, 0x0e, 0x08, 0xd0, 
+0x1e, 0x2b, 0x08, 0xd3, 0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x2a, 0x04, 0xd1, 
+0x01, 0xe0, 0x02, 0x2a, 0x01, 0xd3, 0x01, 0x26, 0x00, 0x21, 0x29, 0x43, 
+0x01, 0x43, 0x0a, 0x1c, 0x00, 0x91, 0x00, 0x20, 0x03, 0x99, 0x04, 0x9a, 
+0x07, 0x9b, 0x01, 0xf0, 0x61, 0xff, 0x07, 0x99, 0x49, 0x19, 0x07, 0x91, 
+0x00, 0x2e, 0x0a, 0xd0, 0x1d, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x1d, 0x48, 
+0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x07, 0x9b, 0x01, 0xf0, 0x52, 0xff, 
+0x00, 0x26, 0x02, 0xa8, 0x40, 0x88, 0x00, 0x28, 0x0c, 0xd0, 0x03, 0x98, 
+0x40, 0x19, 0x03, 0x90, 0x02, 0x98, 0xc0, 0x46, 0x20, 0x60, 0x03, 0x98, 
+0xc0, 0x46, 0x60, 0x60, 0x04, 0x98, 0xc0, 0x46, 0xa0, 0x60, 0x03, 0xe0, 
+0x01, 0x98, 0x01, 0x38, 0x01, 0x90, 0x10, 0x34, 0x06, 0x98, 0xc0, 0x46, 
+0x44, 0x63, 0x01, 0x98, 0x06, 0x99, 0xc0, 0x46, 0x88, 0x63, 0x00, 0x20, 
+0x00, 0x2f, 0x02, 0xd0, 0x01, 0x99, 0x00, 0x29, 0x92, 0xd1, 0x09, 0x4a, 
+0xc0, 0x46, 0x00, 0x92, 0x06, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 
+0x09, 0x9b, 0x01, 0xf0, 0x25, 0xff, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 
+0xf8, 0x28, 0x00, 0x80, 0x04, 0x00, 0x53, 0x02, 0x90, 0xb5, 0x0c, 0x1c, 
+0x07, 0x1c, 0x38, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, 
+0x01, 0x68, 0x38, 0x8a, 0xfc, 0xf7, 0xcb, 0xfc, 0xc0, 0x43, 0xf9, 0x68, 
+0xc0, 0x46, 0x08, 0x80, 0x78, 0x8a, 0x39, 0x68, 0x08, 0x1a, 0x38, 0x60, 
+0x38, 0x1c, 0x01, 0xf0, 0x8d, 0xf9, 0x38, 0x1c, 0xfc, 0xf7, 0xd2, 0xfb, 
+0x20, 0x1c, 0xff, 0xf7, 0x33, 0xfe, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x80, 0xb5, 0x01, 0x88, 0x8a, 0x09, 0x21, 0xd3, 0xca, 0x09, 0x1f, 0xd2, 
+0x8a, 0x08, 0x1d, 0xd3, 0x00, 0x21, 0x01, 0x80, 0x41, 0x80, 0x47, 0x6f, 
+0x40, 0x6d, 0xfa, 0x1d, 0x19, 0x32, 0x51, 0x71, 0xfa, 0x6d, 0xc0, 0x46, 
+0x10, 0x60, 0x3a, 0x6e, 0xc0, 0x46, 0x10, 0x60, 0x0c, 0x48, 0xc0, 0x46, 
+0x41, 0x63, 0x81, 0x6b, 0x49, 0x08, 0x49, 0x00, 0x81, 0x63, 0x01, 0x20, 
+0x00, 0xf0, 0xce, 0xff, 0x38, 0x1c, 0x00, 0xf0, 0x6d, 0xff, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x80, 0x23, 0x19, 0x43, 0x01, 0x80, 0x01, 0x88, 
+0x49, 0x09, 0xf6, 0xd2, 0x00, 0xf0, 0xb0, 0xf8, 0xf3, 0xe7, 0x00, 0x00, 
+0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c, 0x10, 0x1c, 0x0d, 0x1c, 
+0x00, 0x24, 0x5e, 0x1e, 0x00, 0x2b, 0x19, 0xd0, 0x01, 0x68, 0xc0, 0x46, 
+0x39, 0x60, 0x41, 0x88, 0x0c, 0x19, 0x41, 0x68, 0xc0, 0x46, 0x79, 0x60, 
+0x81, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0xc1, 0x68, 0xc0, 0x46, 0xf9, 0x60, 
+0x10, 0x30, 0x10, 0x37, 0xe9, 0x6a, 0x81, 0x42, 0x02, 0xd8, 0x28, 0x1c, 
+0x00, 0xf0, 0xee, 0xff, 0x31, 0x1c, 0x01, 0x3e, 0x00, 0x29, 0xe5, 0xd1, 
+0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, 0xc1, 0x61, 
+0x05, 0x49, 0x0a, 0x68, 0x00, 0x2a, 0x01, 0xd1, 0x08, 0x60, 0x02, 0xe0, 
+0x4a, 0x68, 0xc0, 0x46, 0xd0, 0x61, 0x48, 0x60, 0x70, 0x47, 0x00, 0x00, 
+0x3c, 0x2c, 0x00, 0x80, 0x03, 0x49, 0x08, 0x68, 0x00, 0x28, 0x02, 0xd0, 
+0xc2, 0x69, 0xc0, 0x46, 0x0a, 0x60, 0x70, 0x47, 0x3c, 0x2c, 0x00, 0x80, 
+0x00, 0x21, 0x81, 0x67, 0x05, 0x49, 0x8a, 0x68, 0x00, 0x2a, 0x01, 0xd1, 
+0x88, 0x60, 0x02, 0xe0, 0xca, 0x68, 0xc0, 0x46, 0x90, 0x67, 0xc8, 0x60, 
+0x70, 0x47, 0x00, 0x00, 0x3c, 0x2c, 0x00, 0x80, 0x03, 0x49, 0x88, 0x68, 
+0x00, 0x28, 0x02, 0xd0, 0x82, 0x6f, 0xc0, 0x46, 0x8a, 0x60, 0x70, 0x47, 
+0x3c, 0x2c, 0x00, 0x80, 0x00, 0xb5, 0x80, 0x20, 0x13, 0x49, 0xc0, 0x46, 
+0x08, 0x60, 0xff, 0xf7, 0xd5, 0xff, 0x00, 0x28, 0x1b, 0xd0, 0x03, 0x23, 
+0x1b, 0x07, 0x41, 0x68, 0x19, 0x40, 0x0a, 0x0f, 0x51, 0x01, 0x89, 0x1a, 
+0x89, 0x00, 0x0d, 0x4b, 0xc9, 0x18, 0x4b, 0x88, 0x00, 0x2b, 0x04, 0xd1, 
+0x11, 0x1c, 0xff, 0xf7, 0x3b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x2b, 
+0x02, 0xd1, 0xff, 0xf7, 0x05, 0xfc, 0xf8, 0xe7, 0x02, 0x2b, 0xf6, 0xd1, 
+0xff, 0xf7, 0x4e, 0xfb, 0xf3, 0xe7, 0x04, 0x48, 0x01, 0x6d, 0x01, 0x31, 
+0x01, 0x65, 0xee, 0xe7, 0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 
+0xa0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x20, 0x20, 0x0d, 0x49, 0xc0, 0x46, 
+0x08, 0x60, 0xff, 0xf7, 0xbf, 0xff, 0x00, 0x28, 0x0e, 0xd0, 0x01, 0x88, 
+0x20, 0x23, 0x19, 0x43, 0x01, 0x80, 0x01, 0x88, 0x10, 0x23, 0x99, 0x43, 
+0x01, 0x80, 0x01, 0x88, 0x09, 0x0a, 0x01, 0xd3, 0xff, 0xf7, 0x2e, 0xff, 
+0x08, 0xbc, 0x18, 0x47, 0x03, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, 
+0xf8, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 
+0xa0, 0x82, 0x20, 0x40, 0x98, 0xb5, 0x07, 0x1c, 0x22, 0x48, 0xc0, 0x46, 
+0x00, 0x90, 0x22, 0x48, 0xc3, 0x1d, 0x41, 0x33, 0x41, 0x6d, 0x82, 0x6d, 
+0x80, 0x6c, 0x00, 0x03, 0x00, 0x0b, 0x9c, 0x68, 0x01, 0x23, 0x9b, 0x07, 
+0x23, 0x43, 0x1b, 0x68, 0x98, 0x42, 0x00, 0xd1, 0x0c, 0xe0, 0x98, 0x42, 
+0x03, 0xd9, 0x10, 0x1a, 0x59, 0x1a, 0x41, 0x18, 0x00, 0xe0, 0x19, 0x1a, 
+0x01, 0x20, 0x10, 0x29, 0x00, 0xd8, 0x00, 0x20, 0x00, 0x28, 0x1f, 0xd0, 
+0x78, 0x6a, 0xf9, 0x6a, 0xc0, 0x46, 0x08, 0x60, 0xb8, 0x6a, 0xf9, 0x6a, 
+0xc0, 0x46, 0x48, 0x60, 0x10, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0xfb, 0x6a, 
+0x0f, 0x48, 0x42, 0x6d, 0x03, 0x20, 0x39, 0x6a, 0x01, 0xf0, 0xe8, 0xfd, 
+0x38, 0x88, 0x10, 0x23, 0x18, 0x43, 0x38, 0x80, 0x38, 0x88, 0x40, 0x23, 
+0x98, 0x43, 0x38, 0x80, 0x38, 0x1c, 0xff, 0xf7, 0x55, 0xff, 0x98, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x38, 0x88, 0x40, 0x23, 0x18, 0x43, 0x38, 0x80, 
+0xf7, 0xe7, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55, 0x28, 0x03, 0x00, 0x80, 
+0x08, 0x00, 0x11, 0x02, 0xf8, 0x28, 0x00, 0x80, 0xb0, 0xb5, 0x40, 0x20, 
+0x2c, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0, 0xff, 0xfe, 0x07, 0x1c, 
+0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 0x18, 0x40, 0x05, 0x0f, 0x68, 0x01, 
+0x40, 0x1b, 0x80, 0x00, 0x26, 0x49, 0x44, 0x18, 0x20, 0x88, 0x02, 0x23, 
+0x18, 0x43, 0x20, 0x80, 0x20, 0x88, 0x41, 0x08, 0x34, 0xd3, 0x40, 0x08, 
+0x40, 0x00, 0x20, 0x80, 0xa0, 0x6c, 0xe1, 0x6c, 0x40, 0x18, 0xa0, 0x64, 
+0x00, 0x20, 0xe0, 0x64, 0xa1, 0x6b, 0x22, 0x6d, 0x89, 0x18, 0xa1, 0x63, 
+0x20, 0x65, 0xb8, 0x6a, 0xc0, 0x46, 0x60, 0x65, 0x03, 0x23, 0x1b, 0x07, 
+0x78, 0x68, 0x18, 0x40, 0x78, 0x60, 0x61, 0x68, 0x36, 0x31, 0x94, 0x29, 
+0x04, 0xd8, 0x38, 0x23, 0x18, 0x43, 0x78, 0x60, 0x38, 0x20, 0x03, 0xe0, 
+0x94, 0x23, 0x18, 0x43, 0x78, 0x60, 0x94, 0x20, 0xb8, 0x61, 0x39, 0x68, 
+0x78, 0x68, 0x02, 0x04, 0x12, 0x0c, 0x20, 0x1c, 0xcb, 0x1f, 0x05, 0x3b, 
+0xff, 0xf7, 0xd7, 0xfd, 0x02, 0x20, 0x60, 0x80, 0x38, 0x1c, 0xff, 0xf7, 
+0xdf, 0xfe, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xfc, 0xf7, 
+0x4d, 0xfa, 0x28, 0x01, 0x06, 0x49, 0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 
+0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0xef, 0xe7, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xb0, 0xc8, 0x2a, 0x00, 0x80, 0x1c, 0x1c, 0x00, 0x80, 
+0x90, 0xb5, 0x00, 0x27, 0x0f, 0x4c, 0x0d, 0xe0, 0x02, 0x6b, 0x01, 0x3a, 
+0x02, 0x63, 0x00, 0x2a, 0x05, 0xdc, 0xc2, 0x6a, 0xc0, 0x46, 0x02, 0x63, 
+0x80, 0x6a, 0x01, 0xf0, 0xcc, 0xf9, 0x01, 0x37, 0x0b, 0x2f, 0x07, 0xd2, 
+0x38, 0x01, 0x00, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x41, 0x6a, 
+0x00, 0x29, 0xe9, 0xd1, 0x01, 0x20, 0x40, 0x06, 0x03, 0x49, 0xc0, 0x46, 
+0x08, 0x60, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
+0x00, 0x00, 0x00, 0xb0, 0x11, 0x48, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, 
+0x10, 0x49, 0xc8, 0x68, 0x01, 0x28, 0x19, 0xd1, 0xc8, 0x1d, 0x79, 0x30, 
+0x82, 0x88, 0x00, 0x2a, 0x14, 0xd0, 0x01, 0x3a, 0x82, 0x80, 0x82, 0x88, 
+0x00, 0x2a, 0x0f, 0xd1, 0xc2, 0x88, 0x00, 0x2a, 0x0a, 0xd1, 0x02, 0x23, 
+0xca, 0x6f, 0x1a, 0x43, 0xca, 0x67, 0x07, 0x49, 0xc0, 0x46, 0x0a, 0x60, 
+0x04, 0x21, 0x81, 0x80, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0xc1, 0x80, 
+0x70, 0x47, 0x00, 0x00, 0x08, 0x83, 0x20, 0x40, 
+0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 0xb0, 0xb5, 0x07, 0x1c, 
+0x01, 0x23, 0xf8, 0x1d, 0x69, 0x30, 0x03, 0x73, 0x1d, 0x49, 0xca, 0x1d, 
+0x79, 0x32, 0xd4, 0x89, 0x60, 0x1c, 0xd0, 0x81, 0x55, 0x8a, 0x00, 0x20, 
+0xac, 0x42, 0x02, 0xdb, 0x53, 0x73, 0xd0, 0x81, 0x50, 0x83, 0x01, 0x23, 
+0x9b, 0x07, 0x3a, 0x6d, 0x1a, 0x43, 0x12, 0x68, 0xc0, 0x46, 0xba, 0x61, 
+0xfb, 0x69, 0x9a, 0x42, 0x06, 0xd1, 0xf8, 0x6c, 0x12, 0x49, 0xc0, 0x46, 
+0x08, 0x60, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x78, 0x61, 0x48, 0x69, 
+0xfa, 0x6c, 0x90, 0x43, 0x48, 0x61, 0x01, 0x21, 0x09, 0x05, 0xc8, 0x60, 
+0x38, 0x69, 0x02, 0x28, 0xf1, 0xd0, 0xb8, 0x69, 0xf9, 0x69, 0x41, 0x1a, 
+0x01, 0xd5, 0x78, 0x6d, 0x41, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8, 
+0xf9, 0x69, 0x09, 0x18, 0xf9, 0x61, 0x78, 0x6d, 0x81, 0x42, 0xe2, 0xd3, 
+0x08, 0x1a, 0xf8, 0x61, 0xdf, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
+0x00, 0x00, 0x00, 0xb0, 0xf8, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0xff, 0x23, 
+0x21, 0x33, 0x9f, 0x42, 0x01, 0xd9, 0xff, 0x27, 0x21, 0x37, 0xe1, 0x6e, 
+0x38, 0x1c, 0x01, 0xf0, 0xcf, 0xfc, 0x2d, 0x4d, 0x00, 0x28, 0x13, 0xd1, 
+0xe0, 0x1d, 0x49, 0x30, 0x01, 0x7a, 0x01, 0x23, 0x19, 0x43, 0x01, 0x72, 
+0x29, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x29, 0x48, 0x01, 0x6d, 0x42, 0x6d, 
+0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0xb4, 0xfc, 0x00, 0x20, 0xf8, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x20, 0x69, 0x01, 0x30, 0x20, 0x61, 0x23, 0x49, 
+0xc8, 0x1d, 0xb9, 0x30, 0xc2, 0x6a, 0x92, 0x00, 0x51, 0x18, 0xc0, 0x31, 
+0xcf, 0x60, 0xc1, 0x6a, 0x01, 0x31, 0x89, 0x07, 0x89, 0x0f, 0xc1, 0x62, 
+0x20, 0x6b, 0xc2, 0x19, 0x61, 0x6d, 0x8a, 0x42, 0x03, 0xd8, 0x23, 0x22, 
+0x12, 0x05, 0x3a, 0x43, 0x05, 0xe0, 0x09, 0x1a, 0x7e, 0x1a, 0x07, 0xd1, 
+0x23, 0x22, 0x12, 0x05, 0x0a, 0x43, 0x00, 0x92, 0x61, 0x6e, 0x09, 0x18, 
+0xa2, 0x6e, 0x10, 0xe0, 0x11, 0x22, 0x52, 0x05, 0x0a, 0x43, 0x00, 0x92, 
+0x61, 0x6e, 0x09, 0x18, 0x00, 0x20, 0xa2, 0x6e, 0x2b, 0x1c, 0x01, 0xf0, 
+0x81, 0xfc, 0x23, 0x22, 0x12, 0x05, 0x32, 0x43, 0x00, 0x92, 0x61, 0x6e, 
+0xa2, 0x6e, 0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0x77, 0xfc, 0x20, 0x6b, 
+0xc0, 0x19, 0x00, 0x09, 0x00, 0x01, 0x61, 0x6d, 0x81, 0x42, 0x00, 0xd8, 
+0x40, 0x1a, 0x20, 0x63, 0x38, 0x1c, 0xb8, 0xe7, 0x44, 0x80, 0x20, 0x40, 
+0x04, 0x00, 0x1b, 0x02, 0xf8, 0x28, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 
+0x80, 0xb5, 0x01, 0x20, 0xc0, 0x03, 0x0d, 0x49, 0xc0, 0x46, 0x08, 0x60, 
+0x0c, 0x49, 0xc8, 0x1d, 0x49, 0x30, 0x02, 0x7a, 0x00, 0x27, 0x00, 0x2a, 
+0x03, 0xd0, 0x07, 0x72, 0x08, 0x1c, 0xff, 0xf7, 0x39, 0xff, 0x08, 0x49, 
+0xc8, 0x1d, 0x49, 0x30, 0x02, 0x7a, 0x00, 0x2a, 0x03, 0xd0, 0x07, 0x72, 
+0x08, 0x1c, 0xff, 0xf7, 0x2f, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0x00, 0x00, 0xb0, 0xd0, 0x2c, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, 
+0x90, 0xb5, 0x07, 0x1c, 0x10, 0x20, 0x18, 0x49, 0xc0, 0x46, 0x08, 0x60, 
+0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 0x16, 0x48, 0xc4, 0x1d, 0xb9, 0x34, 
+0x21, 0x6b, 0x89, 0x00, 0x09, 0x18, 0xc0, 0x31, 0xc9, 0x68, 0x7a, 0x68, 
+0x92, 0x00, 0xd2, 0x19, 0x51, 0x64, 0x21, 0x6b, 0x89, 0x00, 0x08, 0x18, 
+0xc0, 0x30, 0xc1, 0x68, 0x78, 0x68, 0x80, 0x00, 0xc0, 0x19, 0xc0, 0x6b, 
+0x01, 0xf0, 0xa6, 0xfa, 0x01, 0x23, 0x78, 0x68, 
+0x58, 0x40, 0x78, 0x60, 0x20, 0x6b, 0x01, 0x30, 0x80, 0x07, 0x80, 0x0f, 
+0x20, 0x63, 0xf8, 0x1d, 0x19, 0x30, 0x40, 0x79, 0x00, 0x28, 0x02, 0xd1, 
+0x38, 0x1c, 0x00, 0xf0, 0x07, 0xf8, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0x00, 0x00, 0xb0, 0xe8, 0x0d, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c, 
+0x39, 0x48, 0x80, 0x68, 0x00, 0x28, 0x05, 0xd0, 0xb8, 0x6a, 0xc0, 0x68, 
+0x80, 0x09, 0x01, 0xd3, 0x02, 0x20, 0x00, 0xe0, 0x78, 0x6f, 0xfc, 0xf7, 
+0x9d, 0xf8, 0x04, 0x1c, 0x06, 0xd1, 0x01, 0x20, 0xf9, 0x1d, 0x19, 0x31, 
+0x08, 0x71, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf8, 0x6c, 0x2f, 0x49, 
+0xc0, 0x46, 0x08, 0x60, 0xba, 0x6a, 0x38, 0x1c, 0x21, 0x1c, 0x00, 0xf0, 
+0x59, 0xf8, 0x67, 0x62, 0x00, 0x28, 0x03, 0xd1, 0x20, 0x1c, 0x00, 0xf0, 
+0x0b, 0xfd, 0xec, 0xe7, 0xf9, 0x6d, 0x09, 0x68, 0x09, 0x18, 0x09, 0x09, 
+0x09, 0x01, 0x7a, 0x6d, 0x8a, 0x42, 0x00, 0xd8, 0x89, 0x1a, 0xa1, 0x62, 
+0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x4a, 0x6c, 0x00, 0x2a, 0x07, 0xd0, 
+0x4a, 0x6c, 0x12, 0x1a, 0x4a, 0x64, 0x80, 0x08, 0x80, 0x00, 0xb9, 0x6a, 
+0x08, 0x18, 0xb8, 0x62, 0x38, 0x68, 0xb9, 0x6a, 0x80, 0x00, 0xc0, 0x19, 
+0x42, 0x6b, 0x91, 0x42, 0x0e, 0xd3, 0x00, 0x21, 0x41, 0x64, 0xb8, 0x6a, 
+0x39, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x49, 0x6b, 0x40, 0x1a, 0xb8, 0x62, 
+0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0xc9, 0x6b, 0x40, 0x18, 0xb8, 0x62, 
+0xb8, 0x68, 0x81, 0x00, 0xc9, 0x19, 0x49, 0x6c, 0x00, 0x29, 0xb8, 0xd1, 
+0xb9, 0x6a, 0xfa, 0x6b, 0x91, 0x42, 0xb4, 0xd0, 0x3a, 0x6c, 0x91, 0x42, 
+0xb1, 0xd0, 0x01, 0x23, 0x58, 0x40, 0xb8, 0x60, 0x80, 0x00, 0xc0, 0x19, 
+0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf8, 0x68, 0x00, 0x28, 0x01, 0xd0, 
+0x01, 0x38, 0xf8, 0x60, 0x38, 0x69, 0x00, 0x28, 0xa1, 0xd0, 0x01, 0x38, 
+0x38, 0x61, 0x9e, 0xe7, 0xe8, 0x18, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 
+0xf7, 0xb5, 0x90, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, 0x00, 0x20, 0x05, 0x90, 
+0x02, 0x90, 0x00, 0x22, 0x01, 0x92, 0xf9, 0x48, 0x80, 0x6a, 0xc0, 0x46, 
+0xa8, 0x61, 0xa0, 0x68, 0x81, 0x00, 0x09, 0x19, 0x49, 0x6b, 0xc0, 0x46, 
+0x20, 0x60, 0xe1, 0x62, 0x12, 0x9a, 0xd0, 0x68, 0xc0, 0x46, 0xa8, 0x60, 
+0x12, 0x9a, 0x51, 0x78, 0xc0, 0x46, 0x0c, 0x91, 0xf0, 0x48, 0xc0, 0x46, 
+0x03, 0x90, 0xd7, 0x1d, 0x09, 0x37, 0xe0, 0x6a, 0xc1, 0x1b, 0x09, 0x09, 
+0xe3, 0x1d, 0x19, 0x33, 0x0c, 0x9a, 0xc0, 0x46, 0x0f, 0x93, 0xeb, 0x4b, 
+0xc0, 0x46, 0x0e, 0x93, 0x91, 0x42, 0x01, 0xd3, 0xb8, 0x42, 0x21, 0xd8, 
+0xe1, 0x68, 0x02, 0x29, 0x1e, 0xd2, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 
+0x48, 0x71, 0x00, 0x20, 0x03, 0x99, 0x01, 0xf0, 0x5b, 0xfb, 0x00, 0x28, 
+0x03, 0xd1, 0x0e, 0x9b, 0x98, 0x6b, 0x01, 0x30, 0x98, 0x63, 0x01, 0x20, 
+0x80, 0x06, 0x00, 0x27, 0x68, 0x60, 0xaf, 0x61, 0xdd, 0x4a, 0xc0, 0x46, 
+0x00, 0x92, 0xdd, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0xdc, 0x4b, 0x00, 0x20, 
+0x01, 0xf0, 0x3e, 0xfb, 0x38, 0x1c, 0x5c, 0xe3, 0xb8, 0x42, 0x03, 0xd8, 
+0x20, 0x1c, 0x00, 0xf0, 0x7b, 0xfc, 0x07, 0x1c, 0xd7, 0x48, 0x80, 0x68, 
+0x00, 0x28, 0x64, 0xd0, 0x38, 0x78, 0x40, 0x07, 0x40, 0x0f, 0x03, 0x28, 
+0x60, 0xd1, 0x05, 0x98, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x05, 0x90, 
+0x38, 0x78, 0xf0, 0x23, 0x18, 0x40, 0x58, 0xd1, 0xe0, 0x6a, 0xc0, 0x1b, 
+0x00, 0x09, 0x0c, 0x99, 0x88, 0x42, 0x02, 0xd2, 
+0xe0, 0x68, 0x02, 0x28, 0x05, 0xd3, 0xcb, 0x49, 0x88, 0x68, 0x00, 0xf0, 
+0x87, 0xff, 0x06, 0x1c, 0x06, 0xd1, 0x03, 0x9b, 0x28, 0x1c, 0x39, 0x1c, 
+0x22, 0x1c, 0x00, 0xf0, 0x8b, 0xfc, 0x16, 0xe1, 0x2e, 0x62, 0xf8, 0x68, 
+0x00, 0x28, 0x0d, 0xd0, 0xb8, 0x89, 0x00, 0x28, 0x03, 0xd0, 0xc1, 0x49, 
+0xc9, 0x68, 0x00, 0xf0, 0x74, 0xff, 0xf8, 0x89, 0x00, 0x28, 0x03, 0xd0, 
+0xbd, 0x49, 0xc9, 0x68, 0x00, 0xf0, 0x6d, 0xff, 0x7a, 0x68, 0xc0, 0x46, 
+0x72, 0x61, 0xb9, 0x68, 0xc0, 0x46, 0xb1, 0x61, 0x30, 0x1c, 0xb8, 0x49, 
+0x09, 0x68, 0x00, 0xf0, 0x62, 0xff, 0x00, 0x28, 0x17, 0xd1, 0x30, 0x1c, 
+0xb4, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x5b, 0xff, 0x10, 0x37, 0xe0, 0x6a, 
+0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x27, 0xfc, 0x07, 0x1c, 
+0x68, 0x68, 0xaf, 0x4b, 0x18, 0x43, 0x68, 0x60, 0x00, 0x20, 0xa8, 0x61, 
+0xac, 0x23, 0xa8, 0x68, 0x98, 0x43, 0xa8, 0x60, 0xb0, 0xe0, 0xa8, 0x69, 
+0xa8, 0x28, 0x01, 0xd2, 0xa8, 0x20, 0xa8, 0x61, 0x10, 0x37, 0xe0, 0x6a, 
+0xb8, 0x42, 0x6c, 0xd8, 0x9c, 0xe0, 0xa5, 0xe0, 0xa4, 0xe0, 0x10, 0x28, 
+0x68, 0xd1, 0x03, 0x23, 0x1b, 0x07, 0x68, 0x68, 0x18, 0x40, 0x01, 0x0f, 
+0x48, 0x01, 0x40, 0x1a, 0x80, 0x00, 0xa0, 0x4a, 0x82, 0x18, 0x01, 0x92, 
+0x78, 0x88, 0x42, 0x0b, 0x31, 0xd3, 0x82, 0x0b, 0x2f, 0xd3, 0x9d, 0x48, 
+0xc0, 0x46, 0x03, 0x90, 0x02, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x10, 0x80, 
+0x78, 0x88, 0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x60, 
+0xb8, 0x68, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, 0x01, 0x9a, 
+0xc0, 0x46, 0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, 
+0x01, 0x9a, 0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x8f, 0x49, 0x40, 0x18, 
+0x01, 0x9a, 0xc0, 0x46, 0x50, 0x63, 0x01, 0x9a, 0x50, 0x68, 0x36, 0x30, 
+0x94, 0x28, 0x01, 0xd8, 0x38, 0x20, 0x00, 0xe0, 0x94, 0x20, 0xa8, 0x61, 
+0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x28, 0xd8, 0x58, 0xe0, 0x7a, 0x88, 
+0x92, 0x0b, 0x03, 0xd3, 0x85, 0x48, 0xc0, 0x46, 0x03, 0x90, 0x23, 0xe0, 
+0x01, 0x22, 0x12, 0x03, 0x02, 0x40, 0x83, 0x4b, 0x1d, 0xd0, 0x03, 0x93, 
+0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x60, 0xb8, 0x68, 
+0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, 0x01, 0x9a, 0xc0, 0x46, 
+0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, 0x01, 0x9a, 
+0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x75, 0x49, 0x40, 0x18, 0x01, 0x9a, 
+0xc0, 0x46, 0x50, 0x63, 0x02, 0xe0, 0x33, 0xe0, 0x2a, 0xe0, 0x03, 0x93, 
+0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71, 0x12, 0x9a, 0x50, 0x78, 
+0x05, 0x99, 0x43, 0x1a, 0x0b, 0x93, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 
+0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x92, 0xfb, 0x07, 0x1c, 0x01, 0x9a, 
+0x50, 0x6b, 0x91, 0x6b, 0x09, 0x01, 0x40, 0x18, 0x0b, 0x9b, 0x21, 0x1c, 
+0x3a, 0x1c, 0xff, 0xf7, 0x7b, 0xfb, 0x01, 0x9a, 0xc0, 0x46, 0xd0, 0x64, 
+0x01, 0x9a, 0x0b, 0x9b, 0xc0, 0x46, 0x13, 0x65, 0x01, 0x23, 0x5b, 0x06, 
+0x68, 0x68, 0x18, 0x43, 0x68, 0x60, 0x00, 0x20, 0xa8, 0x61, 0x0d, 0xe0, 
+0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 
+0x71, 0xfb, 0x07, 0x1c, 0x38, 0x78, 0x40, 0x07, 0x40, 0x0f, 0x03, 0x28, 
+0x00, 0xd1, 0xf8, 0xe6, 0xa8, 0x69, 0x03, 0x99, 0x01, 0xf0, 0x2a, 0xfa, 
+0x00, 0x28, 0x2a, 0xd1, 0x38, 0x1c, 0x21, 0x1c, 
+0x00, 0xf0, 0x79, 0xfb, 0xa8, 0x68, 0x80, 0x09, 0x04, 0xd3, 0x30, 0x1c, 
+0x49, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x85, 0xfe, 0x41, 0x49, 0x00, 0x20, 
+0x01, 0xf0, 0x18, 0xfa, 0x00, 0x28, 0x04, 0xd1, 0x0e, 0x9b, 0x98, 0x6b, 
+0x01, 0x30, 0x98, 0x63, 0x11, 0xe0, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 
+0x48, 0x71, 0x80, 0x06, 0x00, 0x27, 0x68, 0x60, 0xaf, 0x61, 0x3a, 0x4a, 
+0xc0, 0x46, 0x00, 0x92, 0x39, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x39, 0x4b, 
+0x00, 0x20, 0x01, 0xf0, 0xf7, 0xf9, 0x00, 0x20, 0x15, 0xe2, 0x05, 0x98, 
+0x0c, 0x99, 0x08, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x0c, 0x90, 0x0b, 0x90, 
+0x0c, 0x98, 0x00, 0x28, 0x03, 0xd0, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 
+0x48, 0x71, 0x28, 0x68, 0xc0, 0x46, 0x04, 0x90, 0x00, 0x26, 0x00, 0x20, 
+0x08, 0x90, 0x00, 0x22, 0x0a, 0x92, 0x0c, 0x98, 0x01, 0x38, 0x0d, 0x90, 
+0xa3, 0xe0, 0x78, 0x88, 0x8a, 0x1b, 0x12, 0x04, 0x12, 0x0c, 0x90, 0x42, 
+0x05, 0xdd, 0x07, 0x92, 0x80, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x08, 0x90, 
+0x00, 0xe0, 0x07, 0x90, 0x08, 0x98, 0x00, 0x28, 0x07, 0xd1, 0x0d, 0x98, 
+0x0a, 0x9a, 0x90, 0x42, 0x07, 0xdd, 0x07, 0x98, 0x30, 0x18, 0x88, 0x42, 
+0x03, 0xd8, 0x01, 0x20, 0x40, 0x05, 0x06, 0x90, 0x1c, 0xe0, 0x11, 0x20, 
+0x40, 0x05, 0x06, 0x90, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd1, 
+0x20, 0x48, 0xc0, 0x46, 0x06, 0x90, 0xb1, 0x07, 0x89, 0x0f, 0x0f, 0xd0, 
+0x07, 0x98, 0xc0, 0x06, 0xc0, 0x0e, 0x08, 0xd0, 0x1e, 0x28, 0x09, 0xdb, 
+0x1e, 0x28, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, 0x01, 0xe0, 0x02, 0x29, 
+0x02, 0xd3, 0x01, 0x20, 0x02, 0x90, 0xde, 0xe7, 0x0a, 0x9a, 0x00, 0x2a, 
+0x04, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x06, 0x98, 0x18, 0x43, 0x06, 0x90, 
+0x07, 0x98, 0x06, 0x99, 0x08, 0x43, 0x02, 0x1c, 0x00, 0x90, 0x04, 0x98, 
+0x83, 0x19, 0x1d, 0xe0, 0x68, 0x0e, 0x00, 0x80, 0x79, 0x48, 0xff, 0xff, 
+0xa8, 0x0e, 0x00, 0x80, 0x04, 0x00, 0x12, 0x02, 0xf8, 0x28, 0x00, 0x80, 
+0x44, 0x80, 0x20, 0x40, 0xe8, 0x18, 0x00, 0x80, 0xe0, 0x03, 0x00, 0x80, 
+0x00, 0x00, 0x00, 0x80, 0xc8, 0x2a, 0x00, 0x80, 0xc9, 0x31, 0xff, 0xff, 
+0x58, 0x5f, 0x21, 0x40, 0x81, 0x3c, 0xff, 0xff, 0x41, 0x31, 0xff, 0xff, 
+0x00, 0x00, 0x32, 0x02, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, 
+0x6f, 0xf9, 0x07, 0x98, 0x36, 0x18, 0x02, 0x98, 0x00, 0x28, 0x16, 0xd0, 
+0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x04, 0xd1, 0x09, 0x23, 0x5b, 0x04, 
+0x06, 0x98, 0x18, 0x43, 0x06, 0x90, 0x06, 0x98, 0xc2, 0x4a, 0x02, 0x43, 
+0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0xc1, 0x48, 0x01, 0x6d, 0x42, 0x6d, 
+0x00, 0x20, 0x01, 0xf0, 0x55, 0xf9, 0x00, 0x20, 0x02, 0x90, 0x08, 0x98, 
+0x00, 0x28, 0x0b, 0xd1, 0x0b, 0x9b, 0x01, 0x3b, 0x0b, 0x93, 0x10, 0x37, 
+0xe0, 0x6a, 0xb8, 0x42, 0x0c, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x8a, 0xfa, 
+0x07, 0x1c, 0x07, 0xe0, 0x78, 0x68, 0x07, 0x9a, 0x80, 0x18, 0x78, 0x60, 
+0x78, 0x88, 0x07, 0x9a, 0x80, 0x1a, 0x78, 0x80, 0x0a, 0x9a, 0x50, 0x1c, 
+0x02, 0x04, 0x12, 0x0c, 0x0a, 0x92, 0x0c, 0x98, 0x0a, 0x9a, 0x82, 0x42, 
+0x03, 0xda, 0xa9, 0x69, 0xb1, 0x42, 0x00, 0xd9, 0x53, 0xe7, 0xa8, 0x69, 
+0xb0, 0x42, 0x6b, 0xd1, 0xa8, 0x68, 0x01, 0x09, 0x69, 0xd2, 0x08, 0x9a, 
+0x00, 0x2a, 0x56, 0xd0, 0x0c, 0x99, 0x0a, 0x9a, 0x8a, 0x42, 0x3e, 0xdb, 
+0xb1, 0x07, 0x89, 0x0f, 0x0c, 0xd0, 0x08, 0x9a, 
+0xd2, 0x06, 0xd2, 0x0e, 0x0b, 0xd0, 0x1e, 0x2a, 0x06, 0xdb, 0x1e, 0x2a, 
+0x02, 0xd1, 0x03, 0x29, 0x05, 0xd0, 0x01, 0xe0, 0x02, 0x29, 0x02, 0xd2, 
+0x02, 0x99, 0x00, 0x29, 0x21, 0xd0, 0x08, 0x9a, 0xc0, 0x46, 0x00, 0x92, 
+0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, 
+0x05, 0xf9, 0x08, 0x98, 0x36, 0x18, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 
+0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, 0x00, 0xe0, 0x92, 0x48, 0x01, 0x22, 
+0x02, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x8e, 0x48, 0x01, 0x6d, 
+0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0xf0, 0xf8, 0x00, 0x20, 0x02, 0x90, 
+0x15, 0xe0, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, 
+0x00, 0xe0, 0x88, 0x48, 0x08, 0x9a, 0x02, 0x43, 0x00, 0xe0, 0x08, 0x9a, 
+0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 
+0x06, 0xca, 0x01, 0xf0, 0xd9, 0xf8, 0x08, 0x98, 0x36, 0x18, 0x10, 0x37, 
+0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x14, 0xfa, 
+0x07, 0x1c, 0x68, 0x68, 0x80, 0x0e, 0x6b, 0xd2, 0x0a, 0x98, 0xc0, 0x46, 
+0x09, 0x90, 0x0c, 0x99, 0x88, 0x42, 0x5c, 0xda, 0x0d, 0x98, 0x09, 0x99, 
+0x88, 0x42, 0x03, 0xd0, 0x7a, 0x88, 0x1e, 0xe0, 0x5f, 0xe0, 0x5e, 0xe0, 
+0x78, 0x88, 0x01, 0x22, 0x52, 0x06, 0x02, 0x43, 0xa9, 0x68, 0x8c, 0x23, 
+0x19, 0x40, 0x02, 0xd1, 0x09, 0x23, 0x5b, 0x04, 0x1a, 0x43, 0xb1, 0x07, 
+0x89, 0x0f, 0x0e, 0xd0, 0xc3, 0x06, 0xdb, 0x0e, 0x08, 0xd0, 0x1e, 0x2b, 
+0x09, 0xdb, 0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, 0x01, 0xe0, 
+0x02, 0x29, 0x02, 0xd3, 0x01, 0x21, 0x02, 0x91, 0x02, 0x1c, 0x09, 0x98, 
+0x00, 0x28, 0x02, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x1a, 0x43, 0x00, 0x92, 
+0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0, 
+0x93, 0xf8, 0x78, 0x88, 0x86, 0x19, 0x10, 0x37, 0x02, 0x98, 0x00, 0x28, 
+0x14, 0xd0, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20, 
+0x40, 0x06, 0x00, 0xe0, 0x57, 0x48, 0x01, 0x22, 0x02, 0x43, 0x00, 0x92, 
+0x04, 0x98, 0x83, 0x19, 0x53, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 
+0x01, 0xf0, 0x7a, 0xf8, 0x00, 0x20, 0x02, 0x90, 0xe0, 0x6a, 0xb8, 0x42, 
+0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0xb6, 0xf9, 0x07, 0x1c, 0x09, 0x98, 
+0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x09, 0x90, 0x0c, 0x99, 0x88, 0x42, 
+0xa2, 0xdb, 0x68, 0x68, 0x30, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x68, 0x60, 
+0xe8, 0x6a, 0x00, 0xf0, 0x7b, 0xfa, 0x28, 0xe0, 0x27, 0xe0, 0xa8, 0x68, 
+0x00, 0x09, 0x14, 0xd3, 0x68, 0x68, 0x80, 0x0e, 0x15, 0xd2, 0x01, 0x9a, 
+0x00, 0x2a, 0x12, 0xd0, 0x01, 0x9a, 0x50, 0x6b, 0x0b, 0x9b, 0x21, 0x1c, 
+0x3a, 0x1c, 0xff, 0xf7, 0x87, 0xf9, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64, 
+0x01, 0x9a, 0x0b, 0x9b, 0xc0, 0x46, 0x93, 0x63, 0x03, 0xe0, 0xe8, 0x6a, 
+0x31, 0x1c, 0x00, 0xf0, 0x5d, 0xfa, 0x68, 0x68, 0x30, 0x43, 0x68, 0x60, 
+0xa8, 0x69, 0xb0, 0x42, 0x05, 0xd9, 0x00, 0x04, 0x00, 0x0c, 0x80, 0x1b, 
+0x00, 0xf0, 0xee, 0xf9, 0xae, 0x61, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 
+0x0b, 0xd0, 0x2f, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0xc3, 0x1f, 
+0x05, 0x3b, 0x2a, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 
+0x27, 0xf8, 0x01, 0x23, 0x9b, 0x07, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, 
+0xc0, 0x46, 0xa0, 0x61, 0xe1, 0x69, 0x81, 0x42, 
+0x12, 0xd0, 0x22, 0x69, 0x02, 0x2a, 0x0f, 0xd2, 0x41, 0x1a, 0x01, 0xd5, 
+0x60, 0x6d, 0x41, 0x18, 0x20, 0x1c, 0xff, 0xf7, 0x3f, 0xfb, 0xe1, 0x69, 
+0x40, 0x18, 0xe0, 0x61, 0x61, 0x6d, 0x88, 0x42, 0x24, 0xd3, 0x40, 0x1a, 
+0xe0, 0x61, 0x21, 0xe0, 0x81, 0x42, 0x1f, 0xd1, 0x20, 0x69, 0x02, 0x28, 
+0x1c, 0xd2, 0x01, 0x20, 0x60, 0x61, 0x18, 0x48, 0x41, 0x69, 0xe2, 0x6c, 
+0x0a, 0x43, 0x42, 0x61, 0x81, 0x69, 0xe3, 0x6c, 0x99, 0x43, 0x81, 0x61, 
+0x01, 0x21, 0x09, 0x05, 0xca, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x08, 0x61, 
+0x8b, 0x02, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xa0, 0x61, 
+0xe1, 0x69, 0x81, 0x42, 0x02, 0xd0, 0x20, 0x1c, 0xff, 0xf7, 0xce, 0xfa, 
+0x28, 0x1c, 0x00, 0xf0, 0x0f, 0xf9, 0x0c, 0x98, 0x05, 0x99, 0x40, 0x18, 
+0x00, 0x01, 0x10, 0x30, 0x68, 0x61, 0x13, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xf8, 0x28, 0x00, 0x80, 
+0x00, 0x00, 0x12, 0x02, 0x04, 0x00, 0x52, 0x02, 0xe8, 0x0d, 0x00, 0x80, 
+0xf0, 0xb5, 0x40, 0x20, 0x2d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0, 
+0x03, 0xf9, 0x07, 0x1c, 0x81, 0x69, 0x44, 0x6a, 0xa0, 0x6f, 0x00, 0xf0, 
+0x49, 0xfe, 0x00, 0x20, 0xe1, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x79, 0x68, 
+0xc9, 0x0e, 0x09, 0xd3, 0xf8, 0x6a, 0x00, 0x01, 0x24, 0x49, 0x40, 0x18, 
+0x24, 0x4b, 0xc0, 0x18, 0x01, 0x68, 0x01, 0x39, 0x01, 0x60, 0x36, 0xe0, 
+0xe1, 0x6d, 0x09, 0x68, 0x22, 0x6e, 0xc0, 0x46, 0x11, 0x60, 0x20, 0x4e, 
+0xf5, 0x1d, 0x79, 0x35, 0x01, 0x23, 0xa9, 0x6b, 0x19, 0x43, 0xa9, 0x63, 
+0xb9, 0x6a, 0xe2, 0x6d, 0xc0, 0x46, 0x11, 0x60, 0xb9, 0x6a, 0x22, 0x6e, 
+0xc0, 0x46, 0x11, 0x60, 0x61, 0x69, 0x00, 0x29, 0x04, 0xd1, 0x69, 0x6b, 
+0x01, 0x31, 0x69, 0x63, 0x08, 0x29, 0x07, 0xd3, 0x68, 0x63, 0x01, 0x20, 
+0x00, 0xf0, 0x86, 0xf8, 0xa8, 0x6b, 0x40, 0x08, 0x40, 0x00, 0xa8, 0x63, 
+0x78, 0x68, 0x81, 0x0e, 0x0f, 0xd2, 0x0b, 0x23, 0x1b, 0x02, 0xf1, 0x18, 
+0x89, 0x68, 0x00, 0x29, 0x06, 0xd0, 0x00, 0x08, 0x04, 0xd2, 0x20, 0x1c, 
+0x39, 0x1c, 0x00, 0xf0, 0x43, 0xf8, 0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 
+0x05, 0xfa, 0x38, 0x1c, 0xfb, 0xf7, 0x4a, 0xfc, 0x20, 0x1c, 0x00, 0xf0, 
+0x0b, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 
+0x1c, 0x1c, 0x00, 0x80, 0xb4, 0x0c, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
+0x80, 0xb5, 0x07, 0x1c, 0xf8, 0x1d, 0x19, 0x30, 0x01, 0x79, 0x00, 0x29, 
+0x04, 0xd0, 0x00, 0x21, 0x01, 0x71, 0x38, 0x1c, 0xff, 0xf7, 0x56, 0xfb, 
+0xf8, 0x68, 0x02, 0x28, 0x0d, 0xd0, 0xb8, 0x68, 0x80, 0x00, 0xc2, 0x19, 
+0x50, 0x6c, 0x00, 0x28, 0x11, 0xd0, 0xb8, 0x6a, 0x41, 0x78, 0x09, 0x01, 
+0x10, 0x31, 0x52, 0x6b, 0x10, 0x1a, 0x88, 0x42, 0x05, 0xd3, 0x38, 0x1c, 
+0xff, 0xf7, 0x42, 0xfb, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 
+0xff, 0xf7, 0x2a, 0xfa, 0xf8, 0xe7, 0x78, 0x68, 0x80, 0x00, 0xc0, 0x19, 
+0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf1, 0xe7, 0xb0, 0xb5, 0x87, 0xb0, 
+0x0f, 0x1c, 0x80, 0x6f, 0xc0, 0x46, 0x00, 0x90, 0x00, 0x24, 0x13, 0x4d, 
+0x0b, 0x23, 0x1b, 0x02, 0xe8, 0x18, 0x40, 0x69, 0x00, 0x28, 0x17, 0xd0, 
+0x69, 0x46, 0xa2, 0x00, 0x52, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xd2, 0x18, 
+0x52, 0x69, 0x38, 0x1c, 0x00, 0xf0, 0x96, 0xfb, 0x00, 0x28, 0x09, 0xd1, 
+0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, 0x0b, 0x23, 
+0x1b, 0x02, 0xc0, 0x18, 0x40, 0x69, 0x00, 0x28, 0xea, 0xd1, 0x01, 0xe0, 
+0x01, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x9d, 0xf9, 0x07, 0xb0, 
+0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
+0xb8, 0xb5, 0xc2, 0x07, 0xd2, 0x0f, 0x16, 0x4c, 0x16, 0x49, 0x01, 0xd0, 
+0x08, 0x22, 0x08, 0xe0, 0x82, 0x08, 0x05, 0xd3, 0x0c, 0x22, 0xa4, 0x18, 
+0x0b, 0x68, 0xdf, 0x1d, 0x15, 0x37, 0x03, 0xe0, 0x1c, 0x22, 0x0b, 0x68, 
+0xdf, 0x1d, 0x09, 0x37, 0x0f, 0x4b, 0x1d, 0x7b, 0x00, 0x2d, 0x13, 0xd0, 
+0x5b, 0x7b, 0x00, 0x2b, 0x10, 0xd0, 0x01, 0x23, 0x5b, 0x06, 0x1a, 0x43, 
+0x00, 0x28, 0x01, 0xd1, 0x5b, 0x08, 0x1a, 0x43, 0x00, 0x92, 0x4a, 0x68, 
+0x01, 0x20, 0x39, 0x1c, 0x23, 0x1c, 0x00, 0xf0, 0xe3, 0xfe, 0xb8, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x03, 0x23, 0x1b, 0x06, 0x1a, 0x43, 0xf1, 0xe7, 
+0x3c, 0xef, 0x20, 0x40, 0xf8, 0x28, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, 
+0x00, 0x21, 0xc1, 0x61, 0x05, 0x49, 0x4a, 0x68, 0x00, 0x2a, 0x01, 0xd1, 
+0x48, 0x60, 0x02, 0xe0, 0x8a, 0x68, 0xc0, 0x46, 0xd0, 0x61, 0x88, 0x60, 
+0x70, 0x47, 0x00, 0x00, 0xa8, 0x0e, 0x00, 0x80, 0x03, 0x49, 0x48, 0x68, 
+0x00, 0x28, 0x02, 0xd0, 0xc2, 0x69, 0xc0, 0x46, 0x4a, 0x60, 0x70, 0x47, 
+0xa8, 0x0e, 0x00, 0x80, 0x01, 0x1c, 0x01, 0x23, 0x88, 0x68, 0x58, 0x40, 
+0x88, 0x60, 0xca, 0x68, 0x01, 0x3a, 0xca, 0x60, 0x0a, 0x69, 0x01, 0x3a, 
+0x80, 0x00, 0x0a, 0x61, 0x42, 0x18, 0xd0, 0x6b, 0x53, 0x6b, 0xc0, 0x46, 
+0xcb, 0x62, 0x0b, 0x68, 0x9b, 0x00, 0x59, 0x18, 0x49, 0x6c, 0x53, 0x6c, 
+0xc9, 0x18, 0x51, 0x64, 0x70, 0x47, 0x8a, 0x68, 0x92, 0x00, 0x52, 0x18, 
+0xd3, 0x6b, 0x83, 0x42, 0x17, 0xd1, 0xd0, 0x1d, 0x3d, 0x30, 0x0a, 0x68, 
+0x92, 0x00, 0x52, 0x18, 0x52, 0x6c, 0x03, 0x68, 0x9a, 0x1a, 0x02, 0x60, 
+0x01, 0x23, 0x88, 0x68, 0x58, 0x40, 0x88, 0x60, 0xca, 0x68, 0x01, 0x32, 
+0xca, 0x60, 0x0a, 0x69, 0x01, 0x32, 0x80, 0x00, 0x40, 0x18, 0x0a, 0x61, 
+0x40, 0x6b, 0xc0, 0x46, 0xc8, 0x62, 0x70, 0x47, 0xb8, 0xb5, 0x04, 0x1c, 
+0x1d, 0x1c, 0x17, 0x1c, 0x08, 0x1c, 0x39, 0x1c, 0xff, 0xf7, 0xd9, 0xff, 
+0x00, 0x20, 0x29, 0x1c, 0x00, 0xf0, 0x80, 0xfe, 0x01, 0x20, 0xf9, 0x1d, 
+0x19, 0x31, 0x48, 0x71, 0x80, 0x06, 0x60, 0x60, 0x00, 0x20, 0xa0, 0x61, 
+0x06, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x06, 0x48, 0x01, 0x6d, 0x42, 0x6d, 
+0x05, 0x4b, 0x00, 0x20, 0x00, 0xf0, 0x66, 0xfe, 0xb8, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x04, 0x00, 0x12, 0x02, 0xf8, 0x28, 0x00, 0x80, 
+0x44, 0x80, 0x20, 0x40, 0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 
+0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, 
+0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0x00, 0x00, 0x50, 0x2d, 0x00, 0x80, 
+0xa0, 0x82, 0x20, 0x40, 0x80, 0x08, 0x80, 0x00, 0x06, 0x49, 0x0a, 0x68, 
+0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, 
+0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0x00, 0x00, 
+0x50, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x03, 0x30, 0x80, 0x08, 
+0x80, 0x00, 0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 
+0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 
+0x0a, 0x71, 0x70, 0x47, 0x50, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
+0x02, 0x48, 0x41, 0x79, 0x01, 0x31, 0x41, 0x71, 
+0x70, 0x47, 0x00, 0x00, 0xa0, 0x82, 0x20, 0x40, 0x90, 0xb4, 0x82, 0x00, 
+0x17, 0x4b, 0x9a, 0x58, 0x8b, 0x07, 0x02, 0xd0, 0x89, 0x08, 0x0b, 0x1d, 
+0x01, 0xe0, 0x89, 0x08, 0xcb, 0x1c, 0x11, 0x69, 0xd7, 0x68, 0x12, 0x4c, 
+0x80, 0x00, 0x20, 0x58, 0x40, 0x68, 0xb9, 0x42, 0x03, 0xd1, 0x81, 0x42, 
+0x19, 0xd9, 0x11, 0x68, 0x17, 0xe0, 0x00, 0x24, 0xb9, 0x42, 0x09, 0xd9, 
+0x81, 0x42, 0x12, 0xd9, 0x11, 0x68, 0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30, 
+0x80, 0x10, 0x98, 0x42, 0x0b, 0xd8, 0x07, 0xe0, 0x81, 0x42, 0x05, 0xd8, 
+0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30, 0x80, 0x10, 0x98, 0x42, 0x02, 0xd8, 
+0x20, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0xc8, 0x1d, 0x05, 0x30, 0xfa, 0xe7, 
+0xf0, 0x03, 0x00, 0x80, 0x80, 0xb5, 0x80, 0x00, 0x0f, 0x4a, 0x17, 0x58, 
+0x88, 0x07, 0x02, 0xd0, 0x88, 0x08, 0x04, 0x30, 0x01, 0xe0, 0x88, 0x08, 
+0x03, 0x30, 0x39, 0x69, 0x7a, 0x68, 0x91, 0x42, 0x09, 0xd9, 0x39, 0x68, 
+0xc0, 0x46, 0x39, 0x61, 0xf9, 0x68, 0x7a, 0x68, 0x91, 0x42, 0x02, 0xd9, 
+0x39, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x81, 0x00, 0x38, 0x69, 0x00, 0xf0, 
+0xd5, 0xfd, 0x38, 0x61, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xf0, 0x03, 0x00, 0x80, 0x90, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x01, 0x40, 
+0x0c, 0x0f, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x22, 0x92, 0x07, 0x02, 0x40, 
+0xa3, 0x00, 0x1c, 0x4f, 0xff, 0x58, 0x89, 0x07, 0x89, 0x0f, 0x00, 0x04, 
+0x00, 0x0c, 0x80, 0x08, 0x00, 0x29, 0x00, 0xd0, 0x01, 0x30, 0x00, 0x2a, 
+0x01, 0xd0, 0x02, 0x30, 0x00, 0xe0, 0x03, 0x30, 0xf9, 0x68, 0x7a, 0x68, 
+0x91, 0x42, 0x02, 0xd9, 0x39, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x81, 0x00, 
+0xf8, 0x68, 0x00, 0xf0, 0xa9, 0xfd, 0xf8, 0x60, 0x0f, 0x48, 0x00, 0x69, 
+0x00, 0x28, 0x05, 0xd0, 0x01, 0x20, 0xa0, 0x40, 0x02, 0xd0, 0x20, 0x1c, 
+0xfe, 0xf7, 0xc8, 0xfc, 0x0b, 0x49, 0xc8, 0x1d, 0x19, 0x30, 0x03, 0x79, 
+0x00, 0x22, 0x00, 0x2b, 0x05, 0xd1, 0x09, 0x49, 0xc8, 0x1d, 0x19, 0x30, 
+0x03, 0x79, 0x00, 0x2b, 0x03, 0xd0, 0x02, 0x71, 0x08, 0x1c, 0xff, 0xf7, 
+0x79, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0x03, 0x00, 0x80, 
+0x3c, 0x2c, 0x00, 0x80, 0xd0, 0x2c, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, 
+0xb0, 0xb5, 0x2b, 0x49, 0x09, 0x78, 0x00, 0x29, 0x03, 0xd1, 0x41, 0x68, 
+0x29, 0x4b, 0x19, 0x43, 0x41, 0x60, 0x81, 0x68, 0x49, 0x08, 0x02, 0xd3, 
+0x09, 0x21, 0x09, 0x04, 0x01, 0xe0, 0x0d, 0x21, 0x09, 0x04, 0x0c, 0xc8, 
+0x08, 0x38, 0x19, 0x43, 0x87, 0x68, 0xbb, 0x0a, 0x03, 0xd3, 0x43, 0x68, 
+0x5b, 0x08, 0x00, 0xd3, 0x01, 0x31, 0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 
+0x18, 0x40, 0x07, 0x0f, 0xf8, 0x00, 0x1d, 0x4c, 0x00, 0x19, 0x23, 0x68, 
+0xc0, 0x18, 0x50, 0x30, 0x00, 0x79, 0x01, 0x28, 0x10, 0xd1, 0x60, 0x68, 
+0x01, 0x28, 0x0d, 0xd0, 0x10, 0x1c, 0x00, 0xf0, 0x71, 0xf8, 0x38, 0x01, 
+0x00, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 
+0x41, 0x63, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x01, 0x00, 0x19, 
+0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x03, 0x6b, 0x5d, 0x1c, 0x05, 0x63, 
+0xbd, 0x02, 0x2d, 0x19, 0xdb, 0x00, 0xeb, 0x18, 0x80, 0x33, 0x19, 0x63, 
+0xda, 0x62, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, 0x01, 0x21, 0xb9, 0x40, 
+0x22, 0x68, 0x11, 0x43, 0x21, 0x60, 0x01, 0x6b, 0x80, 0x29, 0xe2, 0xd3, 
+0x00, 0x21, 0x01, 0x63, 0xdf, 0xe7, 0x00, 0x00, 
+0xa8, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x1c, 0x1c, 0x00, 0x80, 
+0xf0, 0xb5, 0x1f, 0x4e, 0x70, 0x68, 0x00, 0x28, 0x36, 0xd1, 0x00, 0x24, 
+0xb1, 0x68, 0x48, 0x1c, 0xc9, 0x00, 0x89, 0x19, 0xb0, 0x60, 0x32, 0x68, 
+0x89, 0x18, 0x60, 0x31, 0x0d, 0x7b, 0x08, 0x28, 0x00, 0xd3, 0xb4, 0x60, 
+0x28, 0x01, 0x80, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x87, 0x6b, 
+0x00, 0x2f, 0x21, 0xd0, 0xc1, 0x6a, 0x4b, 0x1c, 0xaa, 0x02, 0x92, 0x19, 
+0xc9, 0x00, 0x51, 0x18, 0x80, 0x31, 0xc3, 0x62, 0xca, 0x6a, 0x09, 0x6b, 
+0x01, 0x3f, 0x87, 0x63, 0x80, 0x2b, 0x00, 0xd3, 0xc4, 0x62, 0x00, 0x2f, 
+0x06, 0xd1, 0x01, 0x27, 0xaf, 0x40, 0x3b, 0x1c, 0xdb, 0x43, 0x37, 0x68, 
+0x3b, 0x40, 0x33, 0x60, 0x43, 0x6b, 0x01, 0x3b, 0x43, 0x63, 0x10, 0x1c, 
+0x37, 0x1c, 0x00, 0xf0, 0x09, 0xf8, 0x78, 0x68, 0x00, 0x28, 0xc9, 0xd0, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x80, 
+0xf0, 0xb5, 0xcd, 0x0f, 0xed, 0x07, 0x01, 0x24, 0x00, 0x27, 0x2f, 0x4b, 
+0x2f, 0x4a, 0x00, 0x2d, 0x1d, 0xd0, 0xd8, 0x6a, 0x01, 0x30, 0xd8, 0x62, 
+0x10, 0x1c, 0x52, 0x69, 0x00, 0x2a, 0x12, 0xd0, 0x02, 0x69, 0x53, 0x1c, 
+0x92, 0x00, 0x12, 0x18, 0x03, 0x61, 0x91, 0x61, 0x41, 0x69, 0x01, 0x31, 
+0x41, 0x61, 0x02, 0x69, 0x0f, 0x2a, 0x00, 0xd3, 0x07, 0x61, 0x0f, 0x29, 
+0x00, 0xd3, 0x44, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x08, 0x1c, 
+0xff, 0xf7, 0xee, 0xfe, 0xf8, 0xe7, 0x15, 0x69, 0x6e, 0x1c, 0xad, 0x00, 
+0xad, 0x18, 0x16, 0x61, 0xa9, 0x61, 0x55, 0x69, 0x01, 0x35, 0x55, 0x61, 
+0x16, 0x69, 0x0f, 0x2e, 0x00, 0xd3, 0x17, 0x61, 0x0f, 0x2d, 0x00, 0xd3, 
+0x54, 0x60, 0x8c, 0x02, 0xa4, 0x0a, 0x17, 0x4f, 0x3a, 0x6f, 0xfd, 0x68, 
+0xf9, 0x1d, 0x79, 0x31, 0x01, 0x2d, 0x0e, 0xd1, 0xdb, 0x6d, 0x5b, 0x08, 
+0x0b, 0xd3, 0x8b, 0x88, 0x00, 0x2b, 0x08, 0xd1, 0x03, 0x3b, 0xfd, 0x6f, 
+0x2b, 0x40, 0xfb, 0x67, 0x0f, 0x4d, 0xc0, 0x46, 0x2b, 0x60, 0x14, 0x23, 
+0x8b, 0x80, 0x10, 0x60, 0x80, 0x07, 0x80, 0x0a, 0x20, 0x43, 0x03, 0x04, 
+0x00, 0xd0, 0x01, 0x38, 0x50, 0x60, 0xc9, 0x69, 0x08, 0x32, 0x91, 0x42, 
+0x00, 0xd8, 0x08, 0x4a, 0x00, 0x0d, 0x02, 0xd3, 0x51, 0x20, 0x80, 0x03, 
+0x82, 0x61, 0x3a, 0x67, 0xbc, 0xe7, 0x00, 0x00, 0x10, 0x2a, 0x00, 0x80, 
+0x1c, 0x1c, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 
+0x24, 0xa7, 0x20, 0x40, 0xb0, 0xb5, 0x00, 0x28, 0x04, 0xd1, 0x01, 0x20, 
+0xc0, 0x05, 0x16, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x15, 0x4c, 0x00, 0x25, 
+0x67, 0x69, 0x00, 0x2f, 0x16, 0xd0, 0xe0, 0x68, 0x41, 0x1c, 0x80, 0x00, 
+0x00, 0x19, 0xe1, 0x60, 0x80, 0x69, 0x01, 0x3f, 0xff, 0xf7, 0x90, 0xfe, 
+0xe0, 0x68, 0x0f, 0x28, 0x00, 0xd3, 0xe5, 0x60, 0xe0, 0x68, 0x80, 0x00, 
+0x00, 0x19, 0x80, 0x69, 0x00, 0x08, 0x01, 0xd3, 0x00, 0x2f, 0xea, 0xd1, 
+0x67, 0x61, 0x03, 0xe0, 0x08, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, 
+0x65, 0x60, 0x20, 0x68, 0x00, 0x28, 0x01, 0xd0, 0xff, 0xf7, 0x22, 0xff, 
+0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 
+0x1c, 0x1c, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x00, 0x20, 0x70, 0x47, 
+0xb0, 0xb4, 0x10, 0x23, 0x82, 0x68, 0x13, 0x40, 0x00, 0x21, 0x00, 0x2b, 
+0x15, 0xd0, 0x0c, 0x4b, 0x1a, 0x40, 0x12, 0x01, 0x81, 0x24, 0x14, 0x43, 
+0x02, 0x68, 0x15, 0x68, 0x13, 0x1d, 0x80, 0xcb, 
+0x1b, 0x68, 0x04, 0x3a, 0x02, 0x60, 0x20, 0xc2, 0x80, 0xc2, 0x08, 0xc2, 
+0x14, 0x60, 0x42, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x04, 0x32, 0x1a, 0x43, 
+0x42, 0x60, 0x08, 0x1c, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0xf0, 0xff, 0x0f, 
+0xf0, 0xb4, 0x82, 0x68, 0x53, 0x09, 0x34, 0xd3, 0x1b, 0x4b, 0x1a, 0x40, 
+0x12, 0x01, 0x81, 0x26, 0x16, 0x43, 0x03, 0x68, 0x1d, 0x68, 0x1f, 0x1d, 
+0x10, 0xcf, 0x3f, 0x68, 0x04, 0x3b, 0x03, 0x60, 0x20, 0xc3, 0x10, 0xc3, 
+0x80, 0xc3, 0x1e, 0x60, 0x43, 0x68, 0x1f, 0x1d, 0x01, 0x23, 0x9b, 0x07, 
+0x3b, 0x43, 0x43, 0x60, 0xcb, 0x6b, 0x18, 0x1f, 0xc8, 0x63, 0x80, 0xcb, 
+0x80, 0xc0, 0x1c, 0x68, 0x1f, 0x1d, 0x03, 0x1d, 0x04, 0x60, 0x38, 0x1c, 
+0x3f, 0x68, 0xc0, 0x46, 0x1f, 0x60, 0x1f, 0x1d, 0x43, 0x68, 0x1c, 0x04, 
+0x24, 0x0c, 0x81, 0x23, 0x23, 0x43, 0x3b, 0x60, 0x40, 0x68, 0x00, 0x0c, 
+0x00, 0x04, 0x10, 0x43, 0x78, 0x60, 0x08, 0x6e, 0x04, 0x30, 0x08, 0x66, 
+0x48, 0x6e, 0x04, 0x30, 0x48, 0x66, 0x00, 0x20, 0xf0, 0xbc, 0x70, 0x47, 
+0x00, 0xf0, 0xff, 0x0f, 0x80, 0xb4, 0x81, 0x6a, 0x01, 0x23, 0x9b, 0x07, 
+0xca, 0x1d, 0x05, 0x32, 0x1a, 0x43, 0x12, 0x68, 0xcf, 0x1d, 0x01, 0x37, 
+0x3b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x60, 0x01, 0x23, 0x9b, 0x07, 
+0x0f, 0x1d, 0x3b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x8b, 0x60, 0x01, 0x23, 
+0x9b, 0x07, 0x0b, 0x43, 0x1b, 0x68, 0x0c, 0xc1, 0x02, 0x62, 0x01, 0x6b, 
+0xc0, 0x46, 0x0a, 0x62, 0x04, 0x23, 0x81, 0x69, 0x19, 0x43, 0x81, 0x61, 
+0x02, 0x6b, 0xc0, 0x46, 0x91, 0x61, 0x81, 0x6a, 0x04, 0x31, 0x81, 0x62, 
+0x02, 0x6b, 0xc0, 0x46, 0x91, 0x62, 0xc1, 0x1d, 0x39, 0x31, 0x4a, 0x8b, 
+0x04, 0x3a, 0x4a, 0x83, 0x49, 0x8b, 0x02, 0x6b, 0x40, 0x32, 0x51, 0x83, 
+0xc1, 0x89, 0x04, 0x39, 0xc1, 0x81, 0xc1, 0x68, 0x00, 0x6b, 0xc0, 0x46, 
+0xc1, 0x60, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x47, 0x08, 0x47, 
+0x10, 0x47, 0x18, 0x47, 0x20, 0x47, 0x28, 0x47, 0x30, 0x47, 0x38, 0x47, 
+0x30, 0x40, 0x2d, 0xe9, 0x0c, 0xc0, 0x9d, 0xe5, 0x0c, 0x48, 0xa0, 0xe1, 
+0x24, 0x48, 0xb0, 0xe1, 0x1e, 0x00, 0x00, 0x0a, 0x01, 0xc0, 0x4c, 0xe2, 
+0x18, 0x40, 0xa0, 0xe3, 0x64, 0x51, 0x9f, 0xe5, 0x94, 0x50, 0x20, 0xe0, 
+0x00, 0x50, 0x90, 0xe5, 0x14, 0x40, 0x90, 0xe5, 0x00, 0x30, 0x85, 0xe5, 
+0x04, 0xc0, 0x85, 0xe5, 0x08, 0x10, 0x85, 0xe5, 0x0c, 0x20, 0x85, 0xe5, 
+0x10, 0x10, 0x90, 0xe5, 0x10, 0x50, 0x85, 0xe2, 0x01, 0x00, 0x55, 0xe1, 
+0x0c, 0x50, 0x90, 0x55, 0x04, 0x00, 0x55, 0xe1, 0x05, 0x00, 0x00, 0x0a, 
+0x04, 0x10, 0x90, 0xe5, 0x00, 0x50, 0x80, 0xe5, 0x00, 0x50, 0x81, 0xe5, 
+0x00, 0x00, 0xa0, 0xe3, 0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 
+0x00, 0x30, 0x93, 0xe5, 0x08, 0x20, 0x90, 0xe5, 0x01, 0x31, 0x83, 0xe3, 
+0x02, 0x36, 0x83, 0xe3, 0x03, 0x00, 0x55, 0xe1, 0x14, 0x30, 0x80, 0xe5, 
+0xf2, 0xff, 0xff, 0x1a, 0x01, 0x00, 0xa0, 0xe3, 0xf4, 0xff, 0xff, 0xea, 
+0x01, 0x06, 0x1c, 0xe3, 0xf1, 0xff, 0xff, 0x0a, 0xec, 0x10, 0x9f, 0xe5, 
+0x02, 0xc6, 0xcc, 0xe3, 0x54, 0x20, 0x91, 0xe5, 0xe4, 0x30, 0x9f, 0xe5, 
+0x50, 0x10, 0x91, 0xe5, 0xd9, 0xff, 0xff, 0xea, 0xf0, 0x47, 0x2d, 0xe9, 
+0x20, 0xc0, 0x9d, 0xe5, 0x0c, 0x68, 0xa0, 0xe1, 0x26, 0x68, 0xb0, 0xe1, 
+0x25, 0x00, 0x00, 0x0a, 0x18, 0x40, 0xa0, 0xe3, 0xb8, 0x50, 0x9f, 0xe5, 
+0x94, 0x00, 0x00, 0xe0, 0x05, 0x00, 0x80, 0xe0, 
+0x08, 0x40, 0x90, 0xe5, 0x04, 0x80, 0x90, 0xe5, 0x00, 0x70, 0xa0, 0xe3, 
+0x1f, 0xc0, 0xa0, 0xe3, 0x02, 0xc4, 0x8c, 0xe3, 0x00, 0x50, 0x90, 0xe5, 
+0x10, 0x90, 0x90, 0xe5, 0x14, 0xa0, 0x90, 0xe5, 0x00, 0x30, 0x85, 0xe5, 
+0x04, 0xc0, 0x85, 0xe5, 0x08, 0x10, 0x85, 0xe5, 0x0c, 0x20, 0x85, 0xe5, 
+0x10, 0x50, 0x85, 0xe2, 0x09, 0x00, 0x55, 0xe1, 0x0c, 0x50, 0x90, 0x55, 
+0x0a, 0x00, 0x55, 0xe1, 0x15, 0x00, 0x00, 0x0a, 0x03, 0x70, 0x17, 0xe2, 
+0x20, 0x10, 0x81, 0xe2, 0x20, 0x30, 0x83, 0xe2, 0x0a, 0x00, 0x00, 0x0a, 
+0x00, 0x60, 0x96, 0xe2, 0x01, 0x70, 0x87, 0xe2, 0x09, 0x00, 0x00, 0x0a, 
+0x20, 0x60, 0x46, 0xe2, 0x20, 0x00, 0x56, 0xe3, 0xec, 0xff, 0xff, 0xca, 
+0x00, 0x70, 0xa0, 0xe3, 0x01, 0xc0, 0x46, 0xe2, 0x02, 0xc4, 0x8c, 0xe3, 
+0x00, 0x60, 0xa0, 0xe3, 0xe7, 0xff, 0xff, 0xea, 0x00, 0x50, 0x88, 0xe5, 
+0xf2, 0xff, 0xff, 0xea, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x50, 0x80, 0xe5, 
+0x01, 0x00, 0xa0, 0xe1, 0xf0, 0x47, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 
+0x00, 0xa0, 0x94, 0xe5, 0x0a, 0x00, 0x55, 0xe1, 0x14, 0xa0, 0x80, 0xe5, 
+0xe5, 0xff, 0xff, 0x1a, 0x01, 0x10, 0xa0, 0xe3, 0xf5, 0xff, 0xff, 0xea, 
+0x28, 0x03, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 0x00, 0x80, 0x20, 0x40, 
+0x68, 0x82, 0x9f, 0xe5, 0x0b, 0x92, 0xa0, 0xe3, 0x64, 0xa2, 0x9f, 0xe5, 
+0x58, 0xb0, 0x9a, 0xe5, 0x0e, 0xf0, 0xa0, 0xe1, 0x54, 0xb0, 0x9a, 0xe5, 
+0x1e, 0xff, 0x2f, 0xe1, 0x3f, 0x40, 0x2d, 0xe9, 0x00, 0x00, 0x4f, 0xe1, 
+0x1f, 0x00, 0x00, 0xe2, 0x12, 0x00, 0x50, 0xe3, 0x54, 0x00, 0x00, 0x0a, 
+0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 
+0x04, 0x50, 0xa0, 0xe3, 0x00, 0x40, 0x99, 0xe5, 0x09, 0x00, 0x00, 0xea, 
+0x02, 0x00, 0x14, 0xe3, 0x53, 0x00, 0x00, 0x1b, 0x80, 0x00, 0x14, 0xe3, 
+0x59, 0x00, 0x00, 0x1b, 0x20, 0x00, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 
+0x02, 0x07, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 0x01, 0x06, 0x14, 0xe3, 
+0x59, 0x00, 0x00, 0x1b, 0x08, 0x00, 0x14, 0xe3, 0x45, 0x00, 0x00, 0x1b, 
+0x02, 0x05, 0x14, 0xe3, 0x4a, 0x00, 0x00, 0x1b, 0x02, 0x08, 0x14, 0xe3, 
+0x4b, 0x00, 0x00, 0x1b, 0xe5, 0x0e, 0x14, 0xe3, 0x07, 0x00, 0x00, 0x0a, 
+0x04, 0x20, 0x98, 0xe5, 0x0c, 0x10, 0x98, 0xe5, 0x04, 0x30, 0x52, 0xe2, 
+0x3c, 0x30, 0xa0, 0xb3, 0x04, 0x30, 0x88, 0xe5, 0x02, 0x00, 0x91, 0xe7, 
+0x0f, 0xe0, 0xa0, 0xe1, 0x10, 0xff, 0x2f, 0xe1, 0x01, 0x50, 0x55, 0xe2, 
+0x03, 0x00, 0x00, 0x0a, 0x00, 0x40, 0x99, 0xe5, 0x0c, 0x00, 0x9a, 0xe5, 
+0x00, 0x00, 0x14, 0xe1, 0x1b, 0xff, 0x2f, 0x11, 0x08, 0x00, 0x9a, 0xe5, 
+0x00, 0x00, 0x14, 0xe1, 0x0b, 0x00, 0x00, 0x0a, 0x01, 0x0c, 0x14, 0xe3, 
+0x98, 0x01, 0x9f, 0x15, 0x0f, 0xe0, 0xa0, 0x11, 0x10, 0xff, 0x2f, 0x11, 
+0x02, 0x04, 0x14, 0xe3, 0x8c, 0x01, 0x9f, 0x15, 0x0f, 0xe0, 0xa0, 0x11, 
+0x10, 0xff, 0x2f, 0x11, 0x01, 0x09, 0x14, 0xe3, 0x80, 0x01, 0x9f, 0x15, 
+0x0f, 0xe0, 0xa0, 0x11, 0x10, 0xff, 0x2f, 0x11, 0x04, 0x00, 0x9a, 0xe5, 
+0x00, 0x00, 0x14, 0xe1, 0x16, 0x00, 0x00, 0x0a, 0x54, 0xe0, 0x8f, 0xe2, 
+0x04, 0x00, 0x14, 0xe3, 0x40, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 
+0x02, 0x0a, 0x14, 0xe3, 0x44, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 
+0x02, 0x09, 0x14, 0xe3, 0x48, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 
+0x01, 0x02, 0x14, 0xe3, 0x4c, 0x00, 0x9a, 0x15, 
+0x10, 0xff, 0x2f, 0x11, 0x01, 0x04, 0x14, 0xe3, 0x50, 0x00, 0x9a, 0x15, 
+0x10, 0xff, 0x2f, 0x11, 0x01, 0x0a, 0x14, 0xe3, 0x21, 0x00, 0x00, 0x1b, 
+0x02, 0x00, 0x14, 0xe3, 0x0e, 0x00, 0x00, 0x1b, 0x10, 0x00, 0x9a, 0xe5, 
+0x00, 0x00, 0x14, 0xe1, 0x1c, 0x00, 0x00, 0x1b, 0x00, 0x40, 0x99, 0xe5, 
+0x04, 0x50, 0xa0, 0xe3, 0x00, 0x40, 0x94, 0xe2, 0x1b, 0xff, 0x2f, 0x11, 
+0x3f, 0x40, 0xbd, 0xe8, 0x04, 0xf0, 0x5e, 0xe2, 0xc0, 0x00, 0x80, 0xe3, 
+0x00, 0xf0, 0x61, 0xe1, 0xfa, 0xff, 0xff, 0xea, 0x18, 0x00, 0x9a, 0xe5, 
+0x1c, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x54, 0xb0, 0x9a, 0xe5, 
+0x1c, 0x10, 0x9a, 0xe5, 0x14, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 
+0x20, 0x10, 0x9a, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 0x11, 0xff, 0x2f, 0xe1, 
+0x24, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x28, 0x10, 0x9a, 0xe5, 
+0x11, 0xff, 0x2f, 0xe1, 0x2c, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 
+0x30, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x34, 0x10, 0x9a, 0xe5, 
+0x11, 0xff, 0x2f, 0xe1, 0xfe, 0xff, 0xff, 0xea, 0x38, 0xe0, 0x9a, 0xe5, 
+0x3c, 0x10, 0x9a, 0xe5, 0x18, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 
+0x38, 0xe0, 0x9a, 0xe5, 0x3c, 0x10, 0x9a, 0xe5, 0x14, 0x00, 0x9a, 0xe5, 
+0x11, 0xff, 0x2f, 0xe1, 0x64, 0x20, 0x9f, 0xe5, 0x00, 0x30, 0x92, 0xe5, 
+0x00, 0x30, 0x53, 0xe0, 0x0a, 0x00, 0x00, 0xba, 0x00, 0x30, 0x82, 0xe5, 
+0x0c, 0x00, 0x92, 0xe5, 0x08, 0x30, 0x92, 0xe5, 0x00, 0x10, 0x91, 0xe2, 
+0x03, 0x00, 0x00, 0x0a, 0x03, 0x10, 0x80, 0xe7, 0x04, 0x30, 0x53, 0xe2, 
+0x3c, 0x30, 0xa0, 0xb3, 0x08, 0x30, 0x82, 0xe5, 0x01, 0x00, 0xa0, 0xe3, 
+0x1e, 0xff, 0x2f, 0xe1, 0x3c, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 
+0x01, 0x00, 0x80, 0xe2, 0x00, 0x00, 0x81, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 
+0xf8, 0xff, 0xff, 0xea, 0x10, 0x00, 0x9f, 0xe5, 0x08, 0x10, 0x90, 0xe5, 
+0x04, 0x10, 0x51, 0xe2, 0x3c, 0x10, 0xa0, 0xb3, 0x08, 0x10, 0x80, 0xe5, 
+0x1e, 0xff, 0x2f, 0xe1, 0x50, 0x2d, 0x00, 0x80, 0x4c, 0x04, 0x00, 0x80, 
+0xe5, 0x2a, 0xff, 0xff, 0x45, 0x3d, 0xff, 0xff, 0x3d, 0x2b, 0xff, 0xff, 
+0xa0, 0x82, 0x20, 0x40, 0xc9, 0x1c, 0x89, 0x08, 0x89, 0x00, 0x01, 0x23, 
+0x85, 0x4a, 0x5b, 0x07, 0x18, 0x43, 0x13, 0x68, 0x5b, 0x18, 0x13, 0x60, 
+0x00, 0x1f, 0x81, 0xa3, 0x5b, 0x1a, 0x18, 0x47, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 
+0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
+0x50, 0x2d, 0x00, 0x80, 0x98, 0x00, 0x9f, 0xe5, 0x98, 0x10, 0x9f, 0xe5, 
+0x01, 0x20, 0x40, 0xe0, 0x94, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 
+0x03, 0x00, 0x50, 0xe1, 0x03, 0x00, 0x00, 0x1a, 0x04, 0x10, 0x81, 0xe2, 
+0x04, 0x20, 0x52, 0xe2, 0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea, 
+0x78, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5, 0x74, 0x00, 0x9f, 0xe5, 
+0x74, 0x10, 0x9f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x60, 0x30, 0x9f, 0xe5, 
+0x00, 0x00, 0x91, 0xe5, 0x03, 0x00, 0x50, 0xe1, 0x03, 0x00, 0x00, 0x1a, 
+0x04, 0x10, 0x81, 0xe2, 0x04, 0x20, 0x52, 0xe2, 0x00, 0x00, 0x00, 0x0a, 
+0xf8, 0xff, 0xff, 0xea, 0x50, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5, 
+0x4c, 0x00, 0x9f, 0xe5, 0x4c, 0x10, 0x9f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 
+0x2c, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 0x03, 0x00, 0x50, 0xe1, 
+0x03, 0x00, 0x00, 0x1a, 0x04, 0x10, 0x81, 0xe2, 0x04, 0x20, 0x52, 0xe2, 
+0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea, 
+0x28, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
+0x7c, 0x34, 0x00, 0x80, 0x80, 0x30, 0x00, 0x80, 0xad, 0xde, 0xad, 0xde, 
+0x40, 0x04, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80, 0x80, 0x34, 0x00, 0x80, 
+0x44, 0x04, 0x00, 0x80, 0xfc, 0x3f, 0x00, 0x80, 0x40, 0x38, 0x00, 0x80, 
+0x48, 0x04, 0x00, 0x80, 0x78, 0x47, 0x00, 0x00, 0x91, 0xea, 0xff, 0xea, 
+0x78, 0x47, 0x00, 0x00, 0x39, 0xfe, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 
+0x63, 0xfe, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x1b, 0xff, 0xff, 0xea, 
+0x78, 0x47, 0x00, 0x00, 0x8b, 0xea, 0xff, 0xea, 0x00, 0x00, 0x00, 0x00, 
+0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x28, 0x04, 0x00, 0x00, 
+0x61, 0x6d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0xff, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0xb9, 0x0b, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
+0xd5, 0x0b, 0xff, 0xff, 0x03, 0xff, 0x06, 0x54, 0x03, 0x00, 0x00, 0x00, 
+0x75, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x05, 0xff, 0xff, 
+0x04, 0xff, 0x07, 0x54, 0x03, 0x00, 0x00, 0x00, 0xb5, 0x04, 0xff, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0xf1, 0x05, 0xff, 0xff, 0x05, 0xff, 0x05, 0x54, 
+0x03, 0x00, 0x00, 0x00, 0x39, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
+0x55, 0x05, 0xff, 0xff, 0x00, 0xff, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 
+0xf5, 0x17, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x29, 0x0e, 0xff, 0xff, 
+0x01, 0xff, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x02, 0xff, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0xf1, 0x02, 0xff, 0xff, 0xff, 0xff, 0x01, 0x44, 
+0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x65, 0x0d, 0xff, 0xff, 0x06, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0xbd, 0x4f, 0xff, 0xff, 0x01, 0x50, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
+0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x04, 0x00, 0x80, 
+0x19, 0x78, 0x21, 0x40, 0x23, 0x78, 0x21, 0x40, 0x39, 0x78, 0x21, 0x40, 
+0x51, 0x78, 0x21, 0x40, 0x5d, 0x78, 0x21, 0x40, 0x6b, 0x78, 0x21, 0x40, 
+0x85, 0x78, 0x21, 0x40, 0xb1, 0x78, 0x21, 0x40, 0x75, 0x79, 0x21, 0x40, 
+0xcd, 0x79, 0x21, 0x40, 0xdb, 0x79, 0x21, 0x40, 0xe5, 0x79, 0x21, 0x40, 
+0xef, 0x79, 0x21, 0x40, 0x81, 0x7a, 0x21, 0x40, 0x8f, 0x7a, 0x21, 0x40, 
+0x9d, 0x7a, 0x21, 0x40, 0x35, 0x7b, 0x21, 0x40, 0x03, 0x7f, 0x21, 0x40, 
+0x71, 0x7f, 0x21, 0x40, 0x19, 0x80, 0x21, 0x40, 0x4d, 0x81, 0x21, 0x40, 
+0x59, 0x81, 0x21, 0x40, 0xb9, 0x81, 0x21, 0x40, 0x1d, 0x82, 0x21, 0x40, 
+0x49, 0x82, 0x21, 0x40, 0x6d, 0x82, 0x21, 0x40, 0xad, 0x82, 0x21, 0x40, 
+0xd5, 0x82, 0x21, 0x40, 0x1d, 0x83, 0x21, 0x40, 0x2d, 0x83, 0x21, 0x40, 
+0x55, 0x83, 0x21, 0x40, 0x65, 0x83, 0x21, 0x40, 0xad, 0x83, 0x21, 0x40, 
+0xeb, 0x83, 0x21, 0x40, 0x41, 0x84, 0x21, 0x40, 0xa1, 0x84, 0x21, 0x40, 
+0xab, 0x84, 0x21, 0x40, 0xaf, 0x84, 0x21, 0x40, 0x1d, 0x85, 0x21, 0x40, 
+0x75, 0x85, 0x21, 0x40, 0xcd, 0x85, 0x21, 0x40, 
+0x09, 0x86, 0x21, 0x40, 0x6d, 0x86, 0x21, 0x40, 0xa5, 0x86, 0x21, 0x40, 
+0xb5, 0x86, 0x21, 0x40, 0xed, 0x86, 0x21, 0x40, 0xfd, 0x86, 0x21, 0x40, 
+0x11, 0x87, 0x21, 0x40, 0x39, 0x87, 0x21, 0x40, 0x43, 0x87, 0x21, 0x40, 
+0x4d, 0x87, 0x21, 0x40, 0x57, 0x87, 0x21, 0x40, 0xc1, 0x87, 0x21, 0x40, 
+0xcd, 0x87, 0x21, 0x40, 0x41, 0x88, 0x21, 0x40, 0x4b, 0x88, 0x21, 0x40, 
+0x55, 0x88, 0x21, 0x40, 0x5f, 0x88, 0x21, 0x40, 0x69, 0x88, 0x21, 0x40, 
+0x73, 0x88, 0x21, 0x40, 0x7d, 0x88, 0x21, 0x40, 0x87, 0x88, 0x21, 0x40, 
+0x91, 0x88, 0x21, 0x40, 0x9b, 0x88, 0x21, 0x40, 0xa5, 0x88, 0x21, 0x40, 
+0xaf, 0x88, 0x21, 0x40, 0xb9, 0x88, 0x21, 0x40, 0xc3, 0x88, 0x21, 0x40, 
+0xeb, 0x88, 0x21, 0x40, 0xf5, 0x88, 0x21, 0x40, 0x51, 0x89, 0x21, 0x40, 
+0x5b, 0x89, 0x21, 0x40, 0x65, 0x89, 0x21, 0x40, 0x6f, 0x89, 0x21, 0x40, 
+0x79, 0x89, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0x83, 0x89, 0x21, 0x40, 
+0xe9, 0x89, 0x21, 0x40, 0x35, 0x8a, 0x21, 0x40, 0x81, 0x8a, 0x21, 0x40, 
+0x91, 0x8a, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0xdd, 0x8a, 0x21, 0x40, 
+0xe1, 0x8a, 0x21, 0x40, 0xe5, 0x8a, 0x21, 0x40, 0x3d, 0x8b, 0x21, 0x40, 
+0x65, 0x8b, 0x21, 0x40, 0x71, 0x8b, 0x21, 0x40, 0x75, 0x8b, 0x21, 0x40, 
+0x79, 0x8b, 0x21, 0x40, 0xe9, 0x8b, 0x21, 0x40, 0xed, 0x8b, 0x21, 0x40, 
+0xf1, 0x8b, 0x21, 0x40, 0x7d, 0x8b, 0x21, 0x40, 0x05, 0x88, 0x21, 0x40, 
+0xa5, 0x77, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 0xf5, 0x8b, 0x21, 0x40, 
+0xe9, 0xc1, 0x21, 0x40, 0xe9, 0x77, 0x21, 0x40, 0xa5, 0x77, 0x21, 0x40, 
+0xa5, 0x77, 0x21, 0x40, 0xcd, 0xc2, 0x21, 0x40, 0x03, 0xc3, 0x21, 0x40, 
+0x35, 0xc3, 0x21, 0x40, 0x4d, 0x8c, 0x21, 0x40, 0x3f, 0x7b, 0x21, 0x40, 
+0x99, 0x7e, 0x21, 0x40, 0xd5, 0x7e, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x5c, 0x01, 0x18, 0x40, 0x58, 0x01, 0x18, 0x40, 0x24, 0xa3, 0x20, 0x40, 
+0x24, 0xa7, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x6c, 0x01, 0x18, 0x40, 0x68, 0x01, 0x18, 0x40, 0x24, 0x83, 0x20, 0x40, 
+0x24, 0xa3, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x7c, 0x01, 0x18, 0x40, 0x78, 0x01, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x8c, 0x01, 0x18, 0x40, 0x88, 0x01, 0x18, 0x40, 0x24, 0xa9, 0x20, 0x40, 
+0x24, 0xab, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x12, 0x00, 0x18, 0x00, 0x12, 0x00, 
+0x0c, 0x00, 0x12, 0x00, 0x1c, 0x00, 0x12, 0x00, 0x24, 0xa8, 0x20, 0x40, 
+0xa4, 0xa8, 0x20, 0x40, 0xa4, 0xa8, 0x20, 0x40, 0x24, 0xa9, 0x20, 0x40, 
+0x00, 0x00, 0x00, 0x00, 0x11, 0xb2, 0x21, 0x40, 0x6d, 0xb3, 0x21, 0x40, 
+0x00, 0x00, 0x00, 0x00, 0x91, 0x73, 0x21, 0x40, 0x89, 0xaa, 0x21, 0x40, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x67, 0x92, 0x21, 0x40, 0x11, 0xb2, 0x21, 0x40, 
+0x39, 0x2f, 0xff, 0xff, 0xad, 0x20, 0xff, 0xff, 0x97, 0x20, 0xff, 0xff, 
+0xe9, 0xb0, 0x21, 0x40, 0xa0, 0x2d, 0x00, 0x80, 0xb4, 0x2d, 0x00, 0x80, 
+0xc8, 0x2d, 0x00, 0x80, 0x30, 0x33, 0x3a, 0x31, 0x31, 0x3a, 0x31, 0x31, 
+0x00, 0x30, 0x37, 0x2f, 0x32, 0x33, 0x2f, 0x30, 
+0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x31, 0x35, 0x36, 0x39, 0x00, 0x43, 
+0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 
+0x20, 0x32, 0x30, 0x30, 0x31, 0x20, 0x33, 0x43, 0x6f, 0x6d, 0x20, 0x43, 
+0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x00, 
+0x17, 0x40, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x0c, 0x53, 0xff, 0xff, 0x27, 0xf0, 0x7d, 0xfd, 
+0x00, 0x01, 0x00, 0x02, 0xda, 0x0e, 0x82, 0x00, 0x01, 0x40, 0x64, 0x04, 
+0xd0, 0x2c, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, 0xe5, 0x3d, 0xff, 0xff, 
+0x49, 0x4f, 0xff, 0xff, 0x79, 0x24, 0xff, 0xff, 0x3d, 0x3b, 0xff, 0xff, 
+0x9d, 0x3b, 0xff, 0xff, 0xa1, 0x19, 0xff, 0xff, 0x19, 0x11, 0xff, 0xff, 
+0x4c, 0x53, 0xff, 0xff, 0x99, 0x3f, 0xff, 0xff, 0x91, 0x73, 0x21, 0x40, 
+0x51, 0x75, 0x21, 0x40, 0x51, 0x3f, 0xff, 0xff, 0x11, 0xa3, 0x21, 0x40, 
+0x29, 0x24, 0xff, 0xff, 0xe4, 0x52, 0xff, 0xff, 0x0c, 0x53, 0xff, 0xff, 
+0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0x30, 0x00, 0x80, 
+0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 
+0xb8, 0x60, 0x00, 0x00, 0x74, 0x6c, 0x00, 0x00, 0x00, 0x6e, 0x21, 0x40, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
+0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 
+0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
+0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 
+0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 
+0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 
+0xfd, 0x92, 0x21, 0x40, 0x9b, 0x92, 0x21, 0x40, 0xc1, 0x95, 0x21, 0x40, 
+0x21, 0x96, 0x21, 0x40, 0xe9, 0x96, 0x21, 0x40, 0xa7, 0x94, 0x21, 0x40, 
+0xc5, 0x97, 0x21, 0x40, 0x31, 0x98, 0x21, 0x40, 0x85, 0x94, 0x21, 0x40, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 
+0xb5, 0xce, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xc3, 0x21, 0x40, 
+0x45, 0xc5, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xcc, 0x21, 0x40, 
+0x59, 0xcd, 0x21, 0x40, 0xc5, 0xcd, 0x21, 0x40, 0x09, 0x29, 0x09, 0xd1, 
+0x20, 0x28, 0x07, 0xd2, 0x04, 0x48, 0x01, 0x78, 0x00, 0x29, 0x03, 0xd1, 
+0x01, 0x21, 0x01, 0x70, 0x02, 0x48, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 
+0x00, 0x6e, 0x21, 0x40, 0x24, 0xab, 0x20, 0x40, 0x03, 0x49, 0x88, 0x42, 
+0x03, 0xd1, 0x00, 0x20, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x70, 0x70, 0x47, 
+0x24, 0xab, 0x20, 0x40, 0x00, 0x6e, 0x21, 0x40, 
+0x00, 0xb5, 0x00, 0x20, 0x0b, 0x4a, 0x0b, 0x23, 0x1b, 0x02, 0xd1, 0x18, 
+0x2d, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x48, 0x61, 0x98, 0x60, 0x98, 0x63, 
+0x80, 0x32, 0x88, 0x60, 0xc8, 0x60, 0x08, 0x61, 0x90, 0x62, 0x05, 0x48, 
+0xc0, 0x46, 0x08, 0x60, 0x48, 0x60, 0x05, 0xf0, 0xc3, 0xf9, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0xfe, 0x03, 0x00, 0x00, 
+0xf0, 0xb5, 0x84, 0xb0, 0x0c, 0x1c, 0x05, 0x1c, 0x00, 0x23, 0x00, 0x93, 
+0xff, 0xf7, 0xda, 0xff, 0x68, 0x49, 0x0b, 0x23, 0x1b, 0x02, 0xcf, 0x18, 
+0x38, 0x68, 0x28, 0x40, 0x00, 0x22, 0xb8, 0x60, 0xfa, 0x60, 0x7a, 0x68, 
+0x22, 0x40, 0x3a, 0x61, 0x0c, 0x1c, 0x41, 0x09, 0x03, 0xd2, 0x51, 0x09, 
+0x01, 0xd2, 0x80, 0x0a, 0x02, 0xd3, 0x60, 0x48, 0x00, 0xf0, 0xc2, 0xf8, 
+0x01, 0x20, 0xb9, 0x68, 0x49, 0x09, 0x03, 0xd2, 0x39, 0x69, 0x49, 0x09, 
+0x00, 0xd2, 0x00, 0x20, 0x00, 0x06, 0x00, 0x0e, 0x03, 0xf0, 0xf8, 0xfd, 
+0xb8, 0x68, 0x00, 0x28, 0x70, 0xd0, 0x00, 0x23, 0x02, 0x93, 0x01, 0x93, 
+0x54, 0x4a, 0x01, 0x23, 0x18, 0x43, 0xb8, 0x60, 0x00, 0x20, 0xd5, 0x1d, 
+0x79, 0x35, 0x03, 0x95, 0x01, 0x24, 0x00, 0x21, 0x4f, 0x4d, 0xba, 0x68, 
+0x22, 0x40, 0x39, 0xd0, 0x8a, 0x00, 0x52, 0x18, 0x92, 0x00, 0x4e, 0x4b, 
+0x9b, 0x5c, 0x1e, 0x1c, 0x83, 0x42, 0x04, 0xd0, 0x4b, 0x4b, 0xd3, 0x18, 
+0x5b, 0x78, 0x83, 0x42, 0x2c, 0xd1, 0x49, 0x4b, 0xd2, 0x18, 0xd3, 0x78, 
+0x03, 0x9d, 0xad, 0x6a, 0xab, 0x42, 0x02, 0xd9, 0x03, 0x9d, 0xc0, 0x46, 
+0xab, 0x62, 0x53, 0x68, 0x5b, 0x08, 0x01, 0xd3, 0x01, 0x23, 0x00, 0x93, 
+0x86, 0x42, 0x0a, 0xd1, 0x95, 0x68, 0x02, 0x9b, 0x5e, 0x1c, 0x02, 0x96, 
+0x9b, 0x00, 0x3c, 0x4e, 0x9e, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xf3, 0x18, 
+0x5d, 0x61, 0x53, 0x78, 0x83, 0x42, 0x0d, 0xd1, 0xd2, 0x68, 0x01, 0x9b, 
+0x5d, 0x1c, 0x01, 0x95, 0x9b, 0x00, 0x35, 0x4d, 0x5d, 0x19, 0x2d, 0x23, 
+0x9b, 0x01, 0xeb, 0x18, 0x9a, 0x60, 0xfa, 0x68, 0x01, 0x32, 0xfa, 0x60, 
+0x64, 0x00, 0x01, 0x31, 0x0b, 0x29, 0xbd, 0xd3, 0x01, 0x30, 0x09, 0x28, 
+0xb8, 0xd3, 0x00, 0x20, 0x02, 0x9b, 0x99, 0x00, 0x2b, 0x4a, 0x89, 0x18, 
+0x0b, 0x23, 0x1b, 0x02, 0xc9, 0x18, 0x48, 0x61, 0x01, 0x9b, 0x99, 0x00, 
+0x89, 0x18, 0x2d, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0x88, 0x60, 0x00, 0x9b, 
+0x00, 0x2b, 0x0c, 0xd1, 0x81, 0x00, 0x89, 0x18, 0x0b, 0x23, 0x1b, 0x02, 
+0xc9, 0x18, 0x8b, 0x69, 0xc0, 0x46, 0x4b, 0x61, 0x01, 0x30, 0x0b, 0x28, 
+0xf4, 0xd3, 0x08, 0xe0, 0x07, 0xe0, 0x03, 0x9d, 0xa8, 0x6a, 0x30, 0x28, 
+0x03, 0xd2, 0x30, 0x20, 0x03, 0x9d, 0xc0, 0x46, 0xa8, 0x62, 0x19, 0x4a, 
+0x38, 0x69, 0x00, 0x28, 0x2a, 0xd0, 0x00, 0x21, 0x01, 0x23, 0x18, 0x43, 
+0x38, 0x61, 0x00, 0x20, 0x01, 0x24, 0x00, 0x22, 0x13, 0x4e, 0x3b, 0x69, 
+0x23, 0x40, 0x10, 0xd0, 0x93, 0x00, 0x9b, 0x18, 0x9b, 0x00, 0x12, 0x4d, 
+0x5b, 0x19, 0x9d, 0x78, 0x85, 0x42, 0x08, 0xd1, 0x1d, 0x69, 0x0b, 0x1c, 
+0x9b, 0x00, 0x9e, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xf3, 0x18, 0x9d, 0x63, 
+0x01, 0x31, 0x64, 0x00, 0x01, 0x32, 0x0b, 0x2a, 0xe6, 0xd3, 0x01, 0x30, 
+0x09, 0x28, 0xe1, 0xd3, 0x00, 0x20, 0x89, 0x00, 0x04, 0x4a, 0x89, 0x18, 
+0x2d, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0x88, 0x63, 0x04, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0xb0, 0x52, 0xff, 0xff, 
+0x80, 0x00, 0x00, 0x80, 0x00, 0x47, 0x08, 0x47, 
+0x10, 0x47, 0x18, 0x47, 0x78, 0x47, 0xc0, 0x46, 0x34, 0xc0, 0x9f, 0xe5, 
+0x1c, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0xc0, 0x46, 0x2c, 0xc0, 0x9f, 0xe5, 
+0x1c, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0xc0, 0x46, 0x24, 0xc0, 0x9f, 0xe5, 
+0x1c, 0xff, 0x2f, 0xe1, 0xc0, 0x46, 0xff, 0xb4, 0x75, 0x46, 0x20, 0xb4, 
+0x01, 0x21, 0x08, 0x43, 0x01, 0xa4, 0xa6, 0x46, 0x00, 0x47, 0xc0, 0x46, 
+0x20, 0xbc, 0xae, 0x46, 0xff, 0xbc, 0xf7, 0x46, 0xb8, 0x51, 0xff, 0xff, 
+0x08, 0x51, 0xff, 0xff, 0xd7, 0xb7, 0x21, 0x40, 0xf0, 0xb5, 0x04, 0x20, 
+0x1a, 0x49, 0x01, 0x25, 0x08, 0x60, 0x1a, 0x4f, 0xbb, 0x23, 0x1b, 0x01, 
+0xf8, 0x18, 0x05, 0x72, 0x18, 0x48, 0x41, 0x6b, 0x2c, 0x05, 0x00, 0x20, 
+0x7a, 0x6e, 0x17, 0x4b, 0x8a, 0x42, 0x1d, 0xd0, 0x19, 0x7b, 0x00, 0x29, 
+0x17, 0xd1, 0xd9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x49, 0x78, 0x1e, 0x1c, 
+0x00, 0x29, 0x10, 0xd1, 0xb0, 0x60, 0x10, 0x20, 0x70, 0x60, 0x10, 0x4a, 
+0x10, 0x49, 0xff, 0xf7, 0xb5, 0xff, 0x00, 0x28, 0x07, 0xd0, 0x35, 0x73, 
+0x04, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 0x20, 0x61, 0x00, 0xf0, 
+0x17, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x18, 0x73, 0x04, 0x23, 
+0xb8, 0x69, 0x98, 0x43, 0xb8, 0x61, 0x20, 0x61, 0xf5, 0xe7, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xb0, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x18, 0x40, 
+0xa8, 0x04, 0x00, 0x80, 0xa0, 0x54, 0xff, 0xff, 0x85, 0x74, 0x21, 0x40, 
+0xf8, 0xb5, 0x15, 0x4f, 0x39, 0x6c, 0x15, 0x48, 0x40, 0x6e, 0x0c, 0x1a, 
+0x14, 0x4e, 0x71, 0x68, 0x14, 0x4d, 0xa1, 0x42, 0x06, 0xd8, 0x14, 0x4a, 
+0x0a, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0x09, 0x18, 0xfa, 0x6b, 0x11, 0xe0, 
+0x11, 0x22, 0x52, 0x05, 0x22, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0x09, 0x18, 
+0x00, 0x20, 0xfa, 0x6b, 0x2b, 0x1c, 0xff, 0xf7, 0x7f, 0xff, 0x70, 0x68, 
+0x00, 0x1b, 0x0a, 0x4a, 0x02, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0xfa, 0x6b, 
+0x00, 0x20, 0x2b, 0x1c, 0xff, 0xf7, 0x74, 0xff, 0xf8, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xf8, 0x28, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 
+0xa8, 0x04, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x37, 0x02, 
+0xf0, 0xb5, 0x2b, 0x4f, 0xb8, 0x68, 0x79, 0x68, 0xc0, 0x19, 0x20, 0x30, 
+0x29, 0x4a, 0xff, 0xf7, 0x55, 0xff, 0x01, 0x20, 0xc0, 0x02, 0x28, 0x49, 
+0xc0, 0x46, 0x08, 0x60, 0xb9, 0x68, 0x38, 0x1c, 0x26, 0x4d, 0x00, 0x24, 
+0x26, 0x4e, 0xef, 0x1d, 0x79, 0x37, 0x00, 0x29, 0x31, 0xd1, 0x31, 0x68, 
+0x0a, 0x78, 0x12, 0x0a, 0x03, 0xd2, 0x04, 0x73, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x49, 0x78, 0x00, 0x29, 0x0c, 0xd1, 0x05, 0x1c, 0x40, 0x68, 
+0x00, 0xf0, 0x3e, 0xf9, 0x30, 0x68, 0x00, 0xf0, 0x67, 0xf8, 0x00, 0x28, 
+0x26, 0xd1, 0x2c, 0x73, 0xff, 0xf7, 0x58, 0xff, 0x22, 0xe0, 0x09, 0x01, 
+0x07, 0x1c, 0x41, 0x60, 0x08, 0x1c, 0x17, 0x4a, 0x17, 0x49, 0xff, 0xf7, 
+0x27, 0xff, 0x00, 0x28, 0x07, 0xd1, 0x3c, 0x73, 0x04, 0x23, 0xa8, 0x69, 
+0x98, 0x43, 0x99, 0x04, 0xa8, 0x61, 0x08, 0x61, 0xda, 0xe7, 0x10, 0x20, 
+0x00, 0xf0, 0x20, 0xf9, 0x10, 0x20, 0xb8, 0x60, 0xff, 0xf7, 0x82, 0xff, 
+0xd2, 0xe7, 0x05, 0x1c, 0x40, 0x68, 0x00, 0xf0, 0x17, 0xf9, 0x30, 0x68, 
+0x00, 0xf0, 0x40, 0xf8, 0x00, 0x28, 0xd8, 0xd0, 0x02, 0x23, 0xb8, 0x6b, 
+0x18, 0x43, 0xb8, 0x63, 0xc4, 0xe7, 0x00, 0x00, 0xa8, 0x04, 0x00, 0x80, 
+0x25, 0x55, 0xff, 0xff, 0x00, 0x00, 0x00, 0xb0, 
+0xe8, 0x0d, 0x00, 0x80, 0x64, 0x01, 0x00, 0x80, 0xa0, 0x54, 0xff, 0xff, 
+0x85, 0x74, 0x21, 0x40, 0x90, 0xb5, 0x01, 0x20, 0x40, 0x03, 0x10, 0x49, 
+0x00, 0x27, 0x08, 0x60, 0x0f, 0x4c, 0xe0, 0x1d, 0xff, 0x30, 0x3a, 0x30, 
+0x47, 0x70, 0xe0, 0x69, 0x80, 0x00, 0x00, 0x19, 0x00, 0x69, 0x00, 0xf0, 
+0xd7, 0xf8, 0xe0, 0x69, 0x00, 0x28, 0x01, 0xd0, 0xe7, 0x61, 0x01, 0xe0, 
+0x01, 0x20, 0xe0, 0x61, 0x07, 0x48, 0x02, 0x23, 0x81, 0x6b, 0x19, 0x43, 
+0x81, 0x63, 0x27, 0x73, 0xff, 0xf7, 0x00, 0xff, 0x90, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xa8, 0x04, 0x00, 0x80, 
+0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x78, 0x88, 
+0x6d, 0x28, 0x03, 0xdb, 0x38, 0x1c, 0x00, 0xf0, 0xf7, 0xf8, 0x17, 0xe0, 
+0x80, 0x00, 0x0d, 0x49, 0x09, 0x58, 0x38, 0x1c, 0xff, 0xf7, 0xbd, 0xfe, 
+0x00, 0x28, 0x0f, 0xd1, 0x39, 0x78, 0xc9, 0x09, 0x0c, 0xd3, 0x69, 0x46, 
+0x38, 0x1c, 0x00, 0xf0, 0xcf, 0xf8, 0x68, 0x46, 0x00, 0x21, 0x00, 0xf0, 
+0x0b, 0xf8, 0x00, 0x28, 0x01, 0xd1, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, 
+0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x01, 0x00, 0x80, 
+0xf0, 0xb5, 0x82, 0xb0, 0x02, 0x1c, 0x41, 0x4b, 0xdd, 0x1d, 0xff, 0x35, 
+0x3a, 0x35, 0x2f, 0x78, 0x00, 0x2f, 0x01, 0xd0, 0x00, 0x27, 0x00, 0xe0, 
+0x01, 0x27, 0x2f, 0x70, 0x2f, 0x78, 0xfb, 0x00, 0xdb, 0x19, 0x5b, 0x01, 
+0x3a, 0x4f, 0xdc, 0x19, 0x40, 0x78, 0x00, 0x01, 0xc7, 0x1d, 0x09, 0x37, 
+0x00, 0x20, 0x83, 0x00, 0xd6, 0x58, 0xc0, 0x46, 0xe6, 0x50, 0x01, 0x30, 
+0x04, 0x28, 0xf8, 0xd3, 0x00, 0x29, 0x0f, 0xd0, 0x00, 0x22, 0xbb, 0x08, 
+0x01, 0x93, 0x83, 0x42, 0x0b, 0xd9, 0x13, 0x1c, 0x9b, 0x00, 0xcb, 0x58, 
+0x86, 0x00, 0xa3, 0x51, 0x01, 0x9b, 0x01, 0x30, 0x01, 0x32, 0x83, 0x42, 
+0xf5, 0xd8, 0x00, 0xe0, 0x10, 0x27, 0x2b, 0x48, 0x02, 0x6d, 0x80, 0x6e, 
+0x2a, 0x49, 0x82, 0x42, 0x03, 0xd8, 0x82, 0x1a, 0xcb, 0x6c, 0x9a, 0x1a, 
+0x00, 0xe0, 0x12, 0x1a, 0xba, 0x42, 0x05, 0xd8, 0x26, 0x48, 0x81, 0x6b, 
+0x01, 0x31, 0x81, 0x63, 0x01, 0x20, 0x37, 0xe0, 0xc3, 0x19, 0xca, 0x6c, 
+0x93, 0x42, 0x08, 0xd8, 0x22, 0x4a, 0x3a, 0x43, 0x00, 0x92, 0x0a, 0x1c, 
+0x49, 0x6c, 0x09, 0x18, 0x92, 0x6c, 0x23, 0x1c, 0x12, 0xe0, 0x16, 0x1a, 
+0x00, 0x96, 0x1b, 0x49, 0x49, 0x6c, 0x09, 0x18, 0x19, 0x48, 0x82, 0x6c, 
+0x03, 0x20, 0x23, 0x1c, 0xff, 0xf7, 0x50, 0xfe, 0xb8, 0x1b, 0x18, 0x4a, 
+0x02, 0x43, 0x00, 0x92, 0xa3, 0x19, 0x14, 0x48, 0x82, 0x6c, 0x41, 0x6c, 
+0x03, 0x20, 0xff, 0xf7, 0x45, 0xfe, 0x01, 0x20, 0x0d, 0x49, 0xc0, 0x46, 
+0x68, 0x70, 0x8a, 0x69, 0x92, 0x00, 0x52, 0x18, 0x17, 0x61, 0x8a, 0x69, 
+0x00, 0x2a, 0x02, 0xd0, 0x00, 0x27, 0x8f, 0x61, 0x00, 0xe0, 0x88, 0x61, 
+0x0c, 0x48, 0x02, 0x23, 0x81, 0x6b, 0x19, 0x43, 0x81, 0x63, 0x00, 0x20, 
+0x01, 0x27, 0x0a, 0x49, 0xc0, 0x46, 0x4f, 0x72, 0x02, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xa8, 0x04, 0x00, 0x80, 0xfc, 0xba, 0x20, 0x40, 
+0xe8, 0x0d, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
+0x00, 0x00, 0x19, 0x02, 0x68, 0x0e, 0x00, 0x80, 0x98, 0x19, 0x00, 0x80, 
+0x07, 0x49, 0x8a, 0x6e, 0x10, 0x18, 0x07, 0x4a, 0xd2, 0x6c, 0x13, 0x04, 
+0x1b, 0x0c, 0x83, 0x42, 0x00, 0xd8, 0x80, 0x1a, 0x88, 0x66, 0x88, 0x6e, 
+0x03, 0x49, 0xc0, 0x46, 0x48, 0x61, 0x70, 0x47, 
+0xe8, 0x0d, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 
+0x06, 0x49, 0x4a, 0x6e, 0x10, 0x18, 0x06, 0x4a, 0x12, 0x6c, 0x82, 0x42, 
+0x00, 0xd8, 0x80, 0x1a, 0x48, 0x66, 0x48, 0x6e, 0x03, 0x49, 0xc0, 0x46, 
+0x08, 0x61, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0xf8, 0x28, 0x00, 0x80, 
+0x3c, 0xef, 0x20, 0x40, 0x05, 0x22, 0x0a, 0x60, 0x82, 0x88, 0xc0, 0x46, 
+0x8a, 0x80, 0x00, 0x22, 0x4a, 0x70, 0x40, 0x88, 0xc0, 0x46, 0x48, 0x80, 
+0xca, 0x80, 0x8a, 0x60, 0xca, 0x60, 0x70, 0x47, 0x05, 0x22, 0x02, 0x60, 
+0x00, 0x22, 0x82, 0x80, 0x42, 0x70, 0x41, 0x80, 0xc2, 0x80, 0x82, 0x60, 
+0xc2, 0x60, 0x70, 0x47, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x0e, 0x48, 
+0x41, 0x6b, 0x01, 0x31, 0x41, 0x63, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 
+0xdd, 0xff, 0x38, 0x68, 0xc0, 0x46, 0x00, 0x90, 0x45, 0x20, 0x00, 0xab, 
+0x18, 0x70, 0x01, 0x27, 0xdf, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 
+0x11, 0xff, 0x00, 0x28, 0x01, 0xd1, 0x38, 0x1c, 0x00, 0xe0, 0x00, 0x20, 
+0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xa0, 0x82, 0x20, 0x40, 
+0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x09, 0x4a, 0xc0, 0x46, 0x11, 0x81, 
+0x69, 0x46, 0xff, 0xf7, 0xbd, 0xff, 0x01, 0x20, 0x40, 0x02, 0x01, 0xab, 
+0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xf5, 0xfe, 0x01, 0x20, 
+0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 
+0x00, 0xb5, 0xff, 0xf7, 0xc3, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 
+0x03, 0x49, 0xc0, 0x46, 0x08, 0x70, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 
+0x00, 0x20, 0x70, 0x47, 0xa8, 0x0e, 0x00, 0x80, 0x00, 0x20, 0x04, 0x49, 
+0xc0, 0x46, 0x08, 0x70, 0xff, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x01, 0x31, 
+0x91, 0x60, 0x70, 0x47, 0xa8, 0x0e, 0x00, 0x80, 0x02, 0x20, 0xa1, 0x21, 
+0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 0x01, 0x20, 0x40, 0x02, 
+0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x88, 
+0xc0, 0x06, 0xc0, 0x0e, 0xa1, 0x21, 0x49, 0x03, 0x48, 0x61, 0x02, 0x49, 
+0xc0, 0x46, 0x88, 0x63, 0x00, 0x20, 0x70, 0x47, 0x68, 0x1a, 0x00, 0x80, 
+0x80, 0xb5, 0x84, 0xb0, 0x08, 0x49, 0x0f, 0x6b, 0x69, 0x46, 0xff, 0xf7, 
+0x71, 0xff, 0xf8, 0x06, 0xc0, 0x0e, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 
+0x00, 0x21, 0xff, 0xf7, 0xa9, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x80, 0x00, 0x14, 0x40, 0x80, 0xb5, 0x85, 0xb0, 
+0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 0x5b, 0xff, 0xf8, 0x88, 
+0x04, 0xa9, 0x04, 0xf0, 0xef, 0xfd, 0x01, 0xab, 0x58, 0x80, 0x01, 0xa8, 
+0x40, 0x88, 0x00, 0x28, 0x0f, 0xd0, 0x01, 0xa8, 0x40, 0x88, 0x80, 0x08, 
+0x03, 0x38, 0x80, 0x08, 0x01, 0x30, 0x04, 0x3b, 0x58, 0x70, 0x04, 0x98, 
+0x01, 0x68, 0xc0, 0x46, 0x02, 0x91, 0x40, 0x68, 0xc0, 0x46, 0x03, 0x90, 
+0x05, 0xe0, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 
+0x18, 0x70, 0x04, 0x98, 0xc1, 0x1d, 0x01, 0x31, 0x68, 0x46, 0xff, 0xf7, 
+0x75, 0xfe, 0x01, 0x20, 0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x90, 0xb5, 0x84, 0xb0, 0x14, 0x4f, 0x39, 0x7b, 0x00, 0x29, 0x20, 0xd1, 
+0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x49, 0x78, 0x00, 0x29, 0x1a, 0xd1, 
+0x10, 0x49, 0x05, 0x22, 0x00, 0x92, 0x08, 0x22, 0x00, 0xab, 0x5a, 0x80, 
+0x98, 0x80, 0x06, 0x20, 0x00, 0xab, 0x58, 0x70, 
+0x00, 0x24, 0xdc, 0x80, 0x08, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x48, 0x68, 
+0xc0, 0x46, 0x03, 0x90, 0x01, 0x20, 0x38, 0x73, 0x68, 0x46, 0x08, 0x31, 
+0xff, 0xf7, 0x4c, 0xfe, 0x00, 0x28, 0x00, 0xd0, 0x3c, 0x73, 0x04, 0xb0, 
+0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa8, 0x04, 0x00, 0x80, 
+0x10, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 
+0x38, 0x1c, 0xff, 0xf7, 0xf9, 0xfe, 0xba, 0x68, 0x0d, 0x4c, 0x0e, 0x48, 
+0x00, 0x2a, 0x05, 0xd1, 0x0d, 0x49, 0xff, 0xf7, 0xd6, 0xfc, 0x00, 0x28, 
+0x0c, 0xda, 0x05, 0xe0, 0xb9, 0x88, 0x0b, 0x4b, 0xff, 0xf7, 0xd1, 0xfc, 
+0x00, 0x28, 0x05, 0xda, 0x01, 0xab, 0x5c, 0x80, 0x68, 0x46, 0x00, 0x21, 
+0xff, 0xf7, 0x22, 0xfe, 0x00, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x15, 0x79, 0x21, 0x40, 
+0x59, 0xcd, 0x21, 0x40, 0xf1, 0xcc, 0x21, 0x40, 0x00, 0xb5, 0xc0, 0x88, 
+0x04, 0xf0, 0x54, 0xfd, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
+0xff, 0xf7, 0xe2, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 
+0xdd, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x01, 0x1c, 0x02, 0x20, 
+0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xc6, 0xb0, 
+0x04, 0x1c, 0x08, 0x1c, 0x69, 0x46, 0xff, 0xf7, 0xb5, 0xfe, 0x1b, 0x48, 
+0xff, 0xf7, 0x96, 0xfc, 0x07, 0x1c, 0x00, 0x21, 0x20, 0x1c, 0x03, 0xf0, 
+0x4f, 0xff, 0x00, 0x28, 0x1c, 0xd0, 0x20, 0x1c, 0x04, 0xa9, 0x03, 0xf0, 
+0x2d, 0xfe, 0x04, 0x98, 0x04, 0x28, 0x05, 0xd9, 0x04, 0x98, 0x80, 0x08, 
+0x03, 0x38, 0x80, 0x08, 0x01, 0x30, 0x00, 0xe0, 0x00, 0x20, 0x00, 0xab, 
+0x58, 0x70, 0x06, 0xa8, 0x00, 0x78, 0xc0, 0x46, 0xd8, 0x80, 0x04, 0x98, 
+0xc0, 0x46, 0x02, 0x90, 0x07, 0x98, 0xc0, 0x46, 0x03, 0x90, 0x04, 0x33, 
+0x08, 0xad, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x07, 0x49, 
+0x38, 0x1c, 0xff, 0xf7, 0x6c, 0xfc, 0x68, 0x46, 0x29, 0x1c, 0xff, 0xf7, 
+0xc3, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x01, 0x1c, 
+0x02, 0x20, 0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
+0x01, 0x1c, 0x01, 0x20, 0xff, 0xf7, 0xb2, 0xff, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0xb5, 0x01, 0x1c, 0x01, 0x20, 0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc, 
+0x18, 0x47, 0xf3, 0xb5, 0xc6, 0xb0, 0x0f, 0x1c, 0x69, 0x46, 0x38, 0x1c, 
+0xff, 0xf7, 0x5e, 0xfe, 0x1c, 0x48, 0xff, 0xf7, 0x3f, 0xfc, 0xba, 0x68, 
+0x04, 0x1c, 0xfc, 0x2a, 0x1f, 0xd8, 0xfd, 0x88, 0xf8, 0x68, 0xc0, 0x46, 
+0x04, 0x90, 0xf9, 0x1d, 0x09, 0x31, 0x05, 0xab, 0x00, 0x20, 0x7e, 0x78, 
+0x00, 0x2e, 0x0d, 0xdd, 0x40, 0xc9, 0x40, 0xc3, 0x40, 0xc9, 0x40, 0xc3, 
+0x40, 0xc9, 0x40, 0xc3, 0x40, 0xc9, 0x40, 0xc3, 0x01, 0x30, 0x00, 0x04, 
+0x00, 0x0c, 0x7e, 0x78, 0x86, 0x42, 0xf1, 0xdc, 0x46, 0x98, 0x04, 0xa9, 
+0x2b, 0x1c, 0xff, 0xf7, 0x2d, 0xfc, 0x00, 0x28, 0x05, 0xd0, 0x00, 0xa8, 
+0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x07, 0x49, 
+0x20, 0x1c, 0xff, 0xf7, 0x12, 0xfc, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 
+0x69, 0xfd, 0x01, 0x20, 0x48, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7, 
+0x35, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 
+0xc6, 0xb0, 0x07, 0x1c, 0xfc, 0x88, 0x25, 0x4d, 0x68, 0x68, 0x01, 0x30, 
+0x69, 0x46, 0x68, 0x60, 0x38, 0x1c, 0xff, 0xf7, 0x0f, 0xfe, 0x10, 0x2c, 
+0x08, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 
+0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x17, 0xe0, 0x78, 0x78, 0x82, 0x00, 
+0xfb, 0x1d, 0x09, 0x33, 0x00, 0x20, 0xb9, 0x68, 0x00, 0x2a, 0x15, 0xd9, 
+0x40, 0xcb, 0x0f, 0x1c, 0x01, 0x31, 0xbe, 0x42, 0x0d, 0xd0, 0x00, 0xaa, 
+0x12, 0x78, 0x40, 0x23, 0x1a, 0x43, 0x00, 0xab, 0x1a, 0x70, 0x04, 0x22, 
+0xda, 0x80, 0x02, 0x90, 0x03, 0x91, 0x04, 0x33, 0x68, 0x46, 0x00, 0x21, 
+0x15, 0xe0, 0x01, 0x30, 0x90, 0x42, 0xe9, 0xd3, 0x00, 0xab, 0x5c, 0x70, 
+0x02, 0x94, 0x69, 0x68, 0xc0, 0x46, 0x03, 0x91, 0xa2, 0x00, 0x00, 0x20, 
+0x10, 0x33, 0x00, 0x2a, 0x05, 0xd9, 0x0f, 0x1c, 0x80, 0xc3, 0x01, 0x30, 
+0x01, 0x31, 0x90, 0x42, 0xf9, 0xd3, 0x68, 0x46, 0x04, 0xa9, 0xff, 0xf7, 
+0x11, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x1c, 0x03, 0x00, 0x80, 0x90, 0xb4, 0x22, 0x48, 0x00, 0x68, 0x01, 0x21, 
+0x42, 0x09, 0x00, 0xd3, 0x00, 0x21, 0x00, 0x27, 0x3a, 0x1c, 0x43, 0x0b, 
+0x00, 0xd2, 0x02, 0x22, 0x11, 0x43, 0x1d, 0x4a, 0x20, 0x24, 0xd3, 0x68, 
+0x01, 0x2b, 0x2c, 0xd1, 0x80, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, 
+0x20, 0x1c, 0x1b, 0x23, 0xdb, 0x01, 0xd1, 0x18, 0x09, 0x8b, 0x09, 0x0b, 
+0x00, 0xd2, 0x04, 0x27, 0x38, 0x43, 0xd1, 0x6f, 0x09, 0x0a, 0x06, 0xd2, 
+0xd1, 0x1d, 0x79, 0x31, 0x09, 0x68, 0x09, 0x0a, 0x01, 0xd3, 0x08, 0x23, 
+0x18, 0x43, 0xe3, 0x23, 0x1b, 0x01, 0xd1, 0x18, 0x89, 0x78, 0x03, 0x29, 
+0x02, 0xd1, 0xff, 0x23, 0x01, 0x33, 0x18, 0x43, 0x0b, 0x49, 0x09, 0x6a, 
+0x10, 0x22, 0x4b, 0x0a, 0x00, 0xd2, 0x00, 0x22, 0x10, 0x43, 0x89, 0x07, 
+0x89, 0x0f, 0x89, 0x01, 0x08, 0x43, 0x90, 0xbc, 0x70, 0x47, 0x40, 0x0c, 
+0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, 0x20, 0x1c, 0xec, 0xe7, 0x00, 0x00, 
+0x00, 0x00, 0x10, 0x40, 0xe8, 0x0d, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x40, 
+0xf0, 0xb5, 0x33, 0x4d, 0x28, 0x1c, 0x05, 0xf0, 0x6b, 0xf8, 0x32, 0x49, 
+0xe3, 0x23, 0x1b, 0x01, 0xcf, 0x18, 0xba, 0x78, 0x30, 0x4e, 0x00, 0x20, 
+0xcc, 0x1d, 0x79, 0x34, 0x05, 0x2a, 0x53, 0xd2, 0x01, 0xa3, 0x9b, 0x5c, 
+0x5b, 0x00, 0x9f, 0x44, 0x02, 0x0e, 0x23, 0x3c, 0x3e, 0x00, 0x01, 0x21, 
+0xb9, 0x70, 0xb0, 0x60, 0xff, 0xf7, 0x98, 0xff, 0x04, 0x23, 0x98, 0x43, 
+0x00, 0xf0, 0x62, 0xf8, 0x14, 0x22, 0x28, 0x1c, 0x0e, 0xe0, 0xff, 0xf7, 
+0x8f, 0xff, 0xc0, 0x08, 0x06, 0xd3, 0xb1, 0x68, 0x48, 0x1c, 0xb0, 0x60, 
+0x0a, 0x29, 0x03, 0xd9, 0x04, 0x20, 0x00, 0xe0, 0x02, 0x20, 0xb8, 0x70, 
+0x02, 0x22, 0x28, 0x1c, 0x00, 0x21, 0x05, 0xf0, 0x07, 0xf8, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x80, 0x23, 0xc8, 0x6f, 0x18, 0x43, 0xc8, 0x67, 
+0x18, 0x4e, 0xc0, 0x46, 0x30, 0x60, 0x03, 0x20, 0xb8, 0x70, 0x28, 0x1c, 
+0x16, 0x4a, 0x00, 0x21, 0x04, 0xf0, 0xf6, 0xff, 0x11, 0x48, 0x04, 0x23, 
+0xc1, 0x6f, 0x99, 0x43, 0xc1, 0x67, 0x31, 0x60, 0x20, 0x68, 0x18, 0x43, 
+0x20, 0x60, 0x70, 0x60, 0xe3, 0xe7, 0x05, 0x21, 0xb9, 0x70, 0x51, 0x21, 
+0x89, 0x03, 0x08, 0x62, 0x04, 0x23, 0x20, 0x68, 0x98, 0x43, 0x20, 0x60, 
+0x09, 0x4e, 0xc0, 0x46, 0x70, 0x60, 0xff, 0xf7, 0x55, 0xff, 0x04, 0x23, 
+0x18, 0x43, 0x00, 0xf0, 0x1f, 0xf8, 0xd0, 0xe7, 
+0x06, 0x20, 0xb8, 0x70, 0xcd, 0xe7, 0x00, 0x00, 0x79, 0x7c, 0x21, 0x40, 
+0xe8, 0x0d, 0x00, 0x80, 0x1c, 0x03, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 
+0x88, 0x13, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x20, 0x04, 0x49, 0xc0, 0x46, 
+0x88, 0x70, 0x04, 0x48, 0x01, 0x22, 0x00, 0x21, 0x04, 0xf0, 0xc0, 0xff, 
+0x08, 0xbc, 0x18, 0x47, 0x18, 0x1c, 0x00, 0x80, 0x79, 0x7c, 0x21, 0x40, 
+0x90, 0xb5, 0x07, 0x1c, 0x30, 0x48, 0x00, 0x68, 0x01, 0x1c, 0x7a, 0x08, 
+0x02, 0xd3, 0x10, 0x23, 0x98, 0x43, 0x01, 0xe0, 0x10, 0x23, 0x18, 0x43, 
+0xba, 0x08, 0x03, 0xd3, 0x01, 0x23, 0x1b, 0x03, 0x98, 0x43, 0x02, 0xe0, 
+0x01, 0x23, 0x1b, 0x03, 0x18, 0x43, 0x88, 0x42, 0x02, 0xd0, 0x01, 0x21, 
+0x09, 0x05, 0x08, 0x60, 0x25, 0x4c, 0xe0, 0x68, 0x01, 0x28, 0x1e, 0xd1, 
+0x1b, 0x23, 0xdb, 0x01, 0xe0, 0x18, 0x00, 0x8b, 0xf9, 0x08, 0x04, 0xd3, 
+0x01, 0x23, 0xdb, 0x02, 0x01, 0x1c, 0x99, 0x43, 0x01, 0xe0, 0x01, 0x21, 
+0xc9, 0x02, 0x81, 0x42, 0x02, 0xd0, 0x00, 0x20, 0x02, 0xf0, 0x20, 0xfe, 
+0x08, 0x21, 0x39, 0x40, 0x1a, 0x48, 0x03, 0xd0, 0x80, 0x23, 0xe1, 0x6f, 
+0x99, 0x43, 0x02, 0xe0, 0x80, 0x23, 0xe1, 0x6f, 0x19, 0x43, 0xe1, 0x67, 
+0x01, 0x60, 0x16, 0x48, 0x01, 0x6a, 0x78, 0x09, 0x03, 0xd3, 0xff, 0x20, 
+0x01, 0x30, 0x08, 0x43, 0x03, 0xe0, 0xff, 0x23, 0x08, 0x1c, 0x01, 0x33, 
+0x98, 0x43, 0x80, 0x08, 0x80, 0x00, 0xba, 0x09, 0x92, 0x07, 0x92, 0x0f, 
+0x10, 0x43, 0x88, 0x42, 0x02, 0xd0, 0x0d, 0x49, 0xc0, 0x46, 0x08, 0x62, 
+0xe1, 0x68, 0x01, 0x29, 0x08, 0xd1, 0x79, 0x0a, 0x06, 0xd3, 0xff, 0x23, 
+0x04, 0x33, 0x18, 0x40, 0x03, 0x28, 0x01, 0xd1, 0xff, 0xf7, 0x90, 0xff, 
+0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 
+0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 0xc0, 0x00, 0x18, 0x40, 
+0xc0, 0x00, 0x18, 0x00, 0x80, 0xb5, 0xff, 0xf7, 0xc1, 0xfe, 0x80, 0x09, 
+0x12, 0xd2, 0x0b, 0x48, 0x41, 0x78, 0x00, 0x29, 0x0e, 0xd1, 0x01, 0x21, 
+0x41, 0x70, 0x00, 0x27, 0x08, 0x48, 0x06, 0xe0, 0x02, 0x20, 0x03, 0xf0, 
+0x03, 0xf8, 0x07, 0x20, 0x02, 0xf0, 0xd2, 0xff, 0x38, 0x1c, 0xff, 0xf7, 
+0x5b, 0xfa, 0xf5, 0xe7, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x18, 0x1c, 0x00, 0x80, 0xf4, 0x01, 0xff, 0xff, 0x00, 0xb5, 0x84, 0xb0, 
+0x69, 0x46, 0xff, 0xf7, 0x69, 0xfc, 0xff, 0xf7, 0x9d, 0xfe, 0x01, 0xab, 
+0x58, 0x80, 0x08, 0x48, 0x00, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x07, 0x48, 
+0x00, 0x6a, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 
+0x99, 0xfb, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x40, 0x80, 0xb5, 0x84, 0xb0, 
+0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 0x49, 0xfc, 0xf8, 0x88, 
+0xff, 0xf7, 0x4a, 0xff, 0xff, 0xf7, 0x7a, 0xfe, 0x01, 0xab, 0x58, 0x80, 
+0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x7e, 0xfb, 0x01, 0x20, 0x04, 0xb0, 
+0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xc6, 0xb0, 0xc7, 0x88, 
+0x69, 0x46, 0xff, 0xf7, 0x33, 0xfc, 0x01, 0x24, 0x63, 0x02, 0x9f, 0x42, 
+0x0a, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 
+0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 0x16, 0xe0, 
+0x0e, 0x48, 0xff, 0xf7, 0x05, 0xfa, 0x05, 0x1c, 0x38, 0x1c, 0x04, 0xa9, 
+0x03, 0xf0, 0xa2, 0xfb, 0x0b, 0x49, 0x28, 0x1c, 
+0xff, 0xf7, 0xfd, 0xf9, 0x10, 0x20, 0x00, 0xab, 0x58, 0x70, 0x04, 0x98, 
+0xc0, 0x46, 0x02, 0x90, 0x05, 0x98, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, 
+0x06, 0xa9, 0xff, 0xf7, 0x4b, 0xfb, 0x20, 0x1c, 0x46, 0xb0, 0xb0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 
+0xf0, 0xb5, 0xc6, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 
+0xfb, 0xfb, 0xfc, 0x88, 0x78, 0x78, 0x01, 0x25, 0x10, 0x28, 0x02, 0xd1, 
+0x43, 0x01, 0x9c, 0x42, 0x09, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 
+0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x04, 0x33, 
+0x2c, 0xe0, 0xb8, 0x68, 0xc0, 0x46, 0x04, 0x90, 0xf8, 0x68, 0xc0, 0x46, 
+0x05, 0x90, 0x06, 0xaa, 0xfb, 0x1d, 0x09, 0x33, 0x00, 0x21, 0x78, 0x78, 
+0x00, 0x28, 0x0d, 0xdd, 0x00, 0x20, 0x40, 0xcb, 0x40, 0xc2, 0x01, 0x30, 
+0x00, 0x04, 0x00, 0x0c, 0x04, 0x28, 0xf8, 0xdb, 0x48, 0x1c, 0x01, 0x04, 
+0x09, 0x0c, 0x78, 0x78, 0x88, 0x42, 0xf1, 0xdc, 0x0d, 0x48, 0xff, 0xf7, 
+0xaf, 0xf9, 0x06, 0x1c, 0x20, 0x1c, 0x04, 0xa9, 0x03, 0xf0, 0x76, 0xfb, 
+0x0a, 0x49, 0x30, 0x1c, 0xff, 0xf7, 0xa7, 0xf9, 0x38, 0x68, 0xc0, 0x46, 
+0x00, 0x90, 0x00, 0x20, 0x00, 0xab, 0x58, 0x70, 0x68, 0x46, 0x00, 0x21, 
+0xff, 0xf7, 0xf8, 0xfa, 0x28, 0x1c, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 
+0xf0, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x00, 0x27, 0xe6, 0x88, 0xa2, 0x68, 
+0x47, 0x49, 0x08, 0x79, 0x00, 0x28, 0x08, 0xd0, 0x00, 0x2e, 0x01, 0xd0, 
+0x01, 0x2e, 0x01, 0xd1, 0x01, 0x27, 0x01, 0xe0, 0x04, 0x2e, 0x00, 0xd1, 
+0x03, 0x26, 0x01, 0x25, 0x41, 0x48, 0x05, 0x2e, 0x66, 0xd2, 0x02, 0xa3, 
+0x9b, 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c, 0x03, 0x06, 0x08, 0x0c, 
+0x10, 0x00, 0x85, 0x83, 0x00, 0x23, 0x03, 0xe0, 0x85, 0x83, 0x05, 0xe0, 
+0x00, 0x23, 0x83, 0x83, 0xc3, 0x83, 0x06, 0xe0, 0x00, 0x23, 0x83, 0x83, 
+0xc5, 0x83, 0x02, 0xe0, 0xff, 0x23, 0x01, 0x33, 0x83, 0x83, 0xcb, 0x1d, 
+0x79, 0x33, 0x1e, 0x89, 0x01, 0x23, 0x5b, 0x02, 0x9e, 0x42, 0x02, 0xdb, 
+0xd2, 0x07, 0xd2, 0x0f, 0x00, 0xe0, 0x01, 0x22, 0x6d, 0x23, 0x5b, 0x01, 
+0xc9, 0x18, 0x09, 0x88, 0xff, 0x23, 0xe1, 0x33, 0x99, 0x43, 0x01, 0x23, 
+0x19, 0x43, 0x86, 0x8b, 0xff, 0x33, 0x9e, 0x42, 0x0d, 0xd1, 0xff, 0x20, 
+0xe1, 0x30, 0x08, 0x43, 0x00, 0x2a, 0x04, 0xd1, 0x01, 0x23, 0x9b, 0x02, 
+0x98, 0x43, 0x01, 0x1c, 0x20, 0xe0, 0x01, 0x21, 0x89, 0x02, 0x01, 0x43, 
+0x1c, 0xe0, 0x01, 0x2e, 0x0a, 0xd1, 0xc0, 0x8b, 0x01, 0x28, 0x04, 0xd1, 
+0x60, 0x23, 0x19, 0x43, 0x00, 0x2a, 0x13, 0xd0, 0x0c, 0xe0, 0x20, 0x23, 
+0x19, 0x43, 0x0f, 0xe0, 0x00, 0x2e, 0x0d, 0xd1, 0xc0, 0x8b, 0x01, 0x28, 
+0x08, 0xd1, 0xff, 0x23, 0x81, 0x33, 0x19, 0x43, 0x00, 0x2a, 0x05, 0xd0, 
+0x01, 0x23, 0x9b, 0x02, 0x19, 0x43, 0x01, 0xe0, 0x80, 0x23, 0x19, 0x43, 
+0x04, 0x20, 0x02, 0xf0, 0x8d, 0xfc, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 
+0x02, 0xf0, 0x88, 0xfc, 0x00, 0x2f, 0x02, 0xd1, 0x00, 0x20, 0x12, 0xe0, 
+0xff, 0xe7, 0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7, 0x2b, 0xfb, 0x00, 0xa8, 
+0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 
+0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 0x04, 0x33, 0xff, 0xf7, 0x5e, 0xfa, 
+0x28, 0x1c, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0xe8, 0x1b, 0x00, 0x80, 
+0xc0, 0x88, 0x51, 0x21, 0x89, 0x03, 0x08, 0x62, 0x00, 0x20, 0x70, 0x47, 
+0x80, 0xb5, 0x16, 0x4f, 0xf8, 0x68, 0x01, 0x28, 0x07, 0xd1, 0x37, 0x23, 
+0x9b, 0x01, 0xf8, 0x18, 0xc0, 0x89, 0x80, 0x21, 0x01, 0x43, 0x1b, 0x20, 
+0x07, 0xe0, 0x6d, 0x23, 0x5b, 0x01, 0xf8, 0x18, 0x00, 0x8b, 0x01, 0x21, 
+0x49, 0x03, 0x01, 0x43, 0x10, 0x20, 0x02, 0xf0, 0x4b, 0xfc, 0x01, 0x20, 
+0x07, 0x23, 0x5b, 0x02, 0xf9, 0x18, 0x88, 0x83, 0xc8, 0x83, 0x1b, 0x23, 
+0xdb, 0x01, 0xf8, 0x18, 0x00, 0x8b, 0x01, 0x23, 0x1b, 0x03, 0x98, 0x43, 
+0x41, 0x21, 0x09, 0x02, 0x01, 0x43, 0x00, 0x20, 0x02, 0xf0, 0x38, 0xfc, 
+0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
+0x80, 0xb5, 0x17, 0x4f, 0xf8, 0x68, 0x01, 0x28, 0x08, 0xd1, 0x37, 0x23, 
+0x9b, 0x01, 0xf8, 0x18, 0xc0, 0x89, 0x80, 0x23, 0x98, 0x43, 0x01, 0x1c, 
+0x1b, 0x20, 0x08, 0xe0, 0x6d, 0x23, 0x5b, 0x01, 0xf8, 0x18, 0x00, 0x8b, 
+0x01, 0x23, 0x5b, 0x03, 0x98, 0x43, 0x01, 0x1c, 0x10, 0x20, 0x02, 0xf0, 
+0x19, 0xfc, 0xff, 0x20, 0x07, 0x23, 0x5b, 0x02, 0xf9, 0x18, 0x01, 0x30, 
+0x88, 0x83, 0x1b, 0x23, 0xdb, 0x01, 0xf8, 0x18, 0x00, 0x8b, 0x41, 0x23, 
+0x1b, 0x02, 0x98, 0x43, 0x09, 0x21, 0x49, 0x02, 0x01, 0x43, 0x00, 0x20, 
+0x02, 0xf0, 0x06, 0xfc, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0xe8, 0x0d, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 0x08, 0x49, 0xcf, 0x6a, 
+0x69, 0x46, 0xff, 0xf7, 0xa5, 0xfa, 0xb8, 0x05, 0x80, 0x0d, 0x01, 0xab, 
+0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xdd, 0xf9, 0x01, 0x20, 
+0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, 
+0xc0, 0x88, 0x9f, 0x23, 0x18, 0x40, 0x05, 0x49, 0xc9, 0x6a, 0x1b, 0x23, 
+0x5b, 0x01, 0x19, 0x40, 0x08, 0x43, 0x03, 0x49, 0xc0, 0x46, 0xc8, 0x62, 
+0x00, 0x20, 0x70, 0x47, 0x40, 0x00, 0x14, 0x40, 0x40, 0x00, 0x14, 0x00, 
+0x80, 0xb5, 0x84, 0xb0, 0x0d, 0x49, 0x0f, 0x6a, 0x01, 0x2f, 0x01, 0xd1, 
+0xff, 0x03, 0x07, 0xe0, 0x02, 0x2f, 0x01, 0xd1, 0x3f, 0x03, 0x03, 0xe0, 
+0x00, 0x2f, 0x01, 0xd1, 0x01, 0x27, 0xff, 0x02, 0x69, 0x46, 0xff, 0xf7, 
+0x71, 0xfa, 0x01, 0xab, 0x5f, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 
+0xab, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0x20, 0x14, 0x40, 0xc2, 0x88, 0xa1, 0x20, 0x40, 0x03, 0x00, 0x21, 
+0x01, 0x23, 0x5b, 0x03, 0x9a, 0x42, 0x01, 0xd1, 0x02, 0x22, 0x04, 0xe0, 
+0x01, 0x23, 0xdb, 0x03, 0x9a, 0x42, 0x02, 0xd1, 0x01, 0x22, 0x02, 0x62, 
+0x00, 0xe0, 0x01, 0x62, 0x08, 0x1c, 0x70, 0x47, 0x90, 0xb5, 0x84, 0xb0, 
+0x07, 0x1c, 0x02, 0xf0, 0xb7, 0xfb, 0x69, 0x46, 0x04, 0x1c, 0x38, 0x1c, 
+0xff, 0xf7, 0x46, 0xfa, 0x01, 0xab, 0x5c, 0x80, 0x09, 0x4f, 0xf8, 0x6d, 
+0xc0, 0x46, 0x02, 0x90, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x7c, 0xf9, 
+0xf8, 0x6d, 0xc0, 0x07, 0xc0, 0x0f, 0x05, 0x49, 0xc0, 0x46, 0x88, 0x62, 
+0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x10, 0x2a, 0x00, 0x80, 0xe8, 0x1b, 0x00, 0x80, 0xc0, 0x88, 0x02, 0x49, 
+0xc0, 0x46, 0x48, 0x61, 0x00, 0x20, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, 
+0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xff, 0xf7, 0x1f, 0xfa, 0x06, 0x48, 
+0xc0, 0x68, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 
+0x00, 0x21, 0xff, 0xf7, 0x57, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, 
+0xc0, 0x46, 0xc8, 0x60, 0x00, 0x20, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, 
+0x80, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0x87, 0x68, 0xff, 0xf7, 0x02, 0xfa, 
+0x20, 0x2f, 0x07, 0xd2, 0x78, 0x00, 0x0c, 0x49, 0x40, 0x18, 0x1b, 0x23, 
+0xdb, 0x01, 0xc0, 0x18, 0x00, 0x8b, 0x06, 0xe0, 0x00, 0xa8, 0x00, 0x78, 
+0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0x01, 0xab, 
+0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x2b, 0xf9, 0x01, 0x20, 
+0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
+0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x82, 0x68, 0x20, 0x2a, 0x04, 0xd2, 
+0x10, 0x1c, 0x02, 0xf0, 0x2f, 0xfb, 0x00, 0x20, 0x10, 0xe0, 0x69, 0x46, 
+0xff, 0xf7, 0xd6, 0xf9, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 
+0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 
+0x04, 0x33, 0xff, 0xf7, 0x09, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 
+0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0xc7, 0x88, 0x69, 0x46, 0xff, 0xf7, 
+0xbf, 0xf9, 0x10, 0x48, 0xfe, 0xf7, 0xa0, 0xff, 0x02, 0x20, 0x39, 0x1c, 
+0x03, 0xf0, 0x5a, 0xfa, 0x00, 0x28, 0x06, 0xd0, 0x02, 0x20, 0x39, 0x1c, 
+0x03, 0xf0, 0x94, 0xf9, 0x01, 0xab, 0x58, 0x80, 0x02, 0xe0, 0x45, 0x20, 
+0x00, 0xab, 0x18, 0x70, 0x07, 0x49, 0x20, 0x1c, 0xfe, 0xf7, 0x8d, 0xff, 
+0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xe4, 0xf8, 0x01, 0x20, 0x04, 0xb0, 
+0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x24, 0x02, 0xff, 0xff, 
+0x3c, 0x02, 0xff, 0xff, 0xb0, 0xb5, 0x84, 0xb0, 0xc7, 0x88, 0x69, 0x46, 
+0x84, 0x68, 0xff, 0xf7, 0x93, 0xf9, 0x10, 0x48, 0xfe, 0xf7, 0x74, 0xff, 
+0x0f, 0x4a, 0x02, 0x20, 0x39, 0x1c, 0xfe, 0xf7, 0x71, 0xff, 0x00, 0x28, 
+0x06, 0xd0, 0x0d, 0x4b, 0x02, 0x20, 0x39, 0x1c, 0x22, 0x1c, 0xfe, 0xf7, 
+0x6a, 0xff, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x09, 0x49, 
+0x28, 0x1c, 0xfe, 0xf7, 0x60, 0xff, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 
+0xb7, 0xf8, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x24, 0x02, 0xff, 0xff, 0xb9, 0xb8, 0x21, 0x40, 0x7b, 0xb7, 0x21, 0x40, 
+0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7, 0x7f, 0xf9, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x80, 0xb4, 0xc2, 0x88, 0x19, 0x4b, 
+0xa1, 0x21, 0x49, 0x03, 0x00, 0x2a, 0x03, 0xd1, 0x18, 0x6b, 0x10, 0x23, 
+0x98, 0x43, 0x04, 0xe0, 0x01, 0x2a, 0x04, 0xd1, 0x18, 0x6b, 0x10, 0x23, 
+0x18, 0x43, 0x48, 0x61, 0x1f, 0xe0, 0x02, 0x2a, 0x1d, 0xd1, 0xc2, 0x68, 
+0x87, 0x68, 0x00, 0x20, 0x3b, 0x1c, 0xc3, 0x40, 0xdb, 0x07, 0xdb, 0x0f, 
+0x9b, 0x02, 0x03, 0x43, 0x0b, 0x61, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 
+0x20, 0x28, 0xf3, 0xdb, 0x00, 0x20, 0x13, 0x1c, 0xc3, 0x40, 0xdb, 0x07, 
+0xdb, 0x0f, 0x9b, 0x02, 0xc7, 0x1d, 0x19, 0x37, 0x3b, 0x43, 0x0b, 0x61, 
+0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x20, 0x28, 0xf1, 0xdb, 0x00, 0x20, 
+0x80, 0xbc, 0x70, 0x47, 0x80, 0x00, 0x14, 0x40, 0x90, 0xb4, 0xc2, 0x88, 
+0x81, 0x68, 0x10, 0x02, 0x12, 0x0a, 0x10, 0x43, 0x02, 0x04, 0x12, 0x0c, 
+0x0f, 0x48, 0xc0, 0x46, 0x02, 0x60, 0x0f, 0x4f, 0x65, 0x23, 0x5b, 0x01, 
+0xfb, 0x18, 0x9a, 0x83, 0x0a, 0x0c, 0x14, 0x02, 
+0x12, 0x12, 0x22, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x42, 0x60, 0xda, 0x83, 
+0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x0a, 0x11, 0x43, 0x09, 0x04, 
+0x09, 0x0c, 0x81, 0x60, 0x33, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x01, 0x80, 
+0x00, 0x20, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00, 
+0xe8, 0x0d, 0x00, 0x80, 0xb0, 0xb5, 0x84, 0xb0, 0x13, 0x49, 0x0a, 0x68, 
+0x12, 0x04, 0x12, 0x0c, 0x13, 0x02, 0x12, 0x12, 0x13, 0x43, 0x4a, 0x68, 
+0x12, 0x04, 0x12, 0x0c, 0x1f, 0x1c, 0x13, 0x02, 0x12, 0x12, 0x13, 0x43, 
+0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x12, 0x11, 0x43, 
+0x0c, 0x04, 0x24, 0x0c, 0x69, 0x46, 0x1d, 0x1c, 0xff, 0xf7, 0xe4, 0xf8, 
+0x01, 0xab, 0x5f, 0x80, 0x28, 0x04, 0x20, 0x43, 0x02, 0x90, 0x68, 0x46, 
+0x00, 0x21, 0xff, 0xf7, 0x1b, 0xf8, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, 0xc1, 0x88, 0x82, 0x68, 
+0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x0a, 0x49, 
+0xc0, 0x46, 0xc8, 0x60, 0x10, 0x0c, 0x03, 0x02, 0x00, 0x12, 0x18, 0x43, 
+0x00, 0x04, 0x00, 0x0c, 0x08, 0x61, 0x10, 0x04, 0x00, 0x0c, 0x02, 0x02, 
+0x00, 0x0a, 0x10, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x48, 0x61, 0x00, 0x20, 
+0x70, 0x47, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00, 0x90, 0xb5, 0x84, 0xb0, 
+0x16, 0x4b, 0xd9, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x12, 
+0x11, 0x43, 0x1a, 0x69, 0x12, 0x04, 0x12, 0x0c, 0x17, 0x02, 0x12, 0x12, 
+0x3a, 0x43, 0x5b, 0x69, 0x1b, 0x04, 0x1b, 0x0c, 0x1f, 0x02, 0x1b, 0x12, 
+0x3b, 0x43, 0x1f, 0x04, 0x3f, 0x0c, 0x05, 0x23, 0x00, 0x93, 0x84, 0x88, 
+0x01, 0xab, 0x1c, 0x80, 0x00, 0x24, 0x04, 0x3b, 0x5c, 0x70, 0x40, 0x88, 
+0x00, 0xab, 0x58, 0x80, 0xd9, 0x80, 0x10, 0x04, 0x38, 0x43, 0x02, 0x90, 
+0x03, 0x94, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xcb, 0xff, 0x01, 0x20, 
+0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40, 
+0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x8a, 0x6a, 0x05, 0x21, 0x00, 0x91, 
+0x81, 0x88, 0x01, 0xab, 0x19, 0x80, 0x00, 0x21, 0x04, 0x3b, 0x59, 0x70, 
+0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xda, 0x80, 0x02, 0x91, 0x03, 0x91, 
+0x68, 0x46, 0xfe, 0xf7, 0xaf, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, 
+0xc0, 0x46, 0x88, 0x62, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, 
+0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x0a, 0x6a, 0x05, 0x21, 0x00, 0x91, 
+0x81, 0x88, 0x01, 0xab, 0x19, 0x80, 0x00, 0x21, 0x04, 0x3b, 0x59, 0x70, 
+0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xda, 0x80, 0x02, 0x91, 0x03, 0x91, 
+0x68, 0x46, 0xfe, 0xf7, 0x8b, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x02, 0x49, 
+0xc0, 0x46, 0x08, 0x62, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00, 
+0x00, 0xb5, 0xc0, 0x88, 0x02, 0x49, 0xfe, 0xf7, 0x1c, 0xfe, 0x00, 0x20, 
+0x08, 0xbc, 0x18, 0x47, 0x75, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x84, 0xb0, 
+0x69, 0x46, 0xff, 0xf7, 0x2d, 0xf8, 0x06, 0x48, 0x00, 0x6b, 0x01, 0xab, 
+0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x65, 0xff, 0x01, 0x20, 
+0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
+0x00, 0xb5, 0xff, 0xf7, 0x33, 0xf8, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0x2e, 0xf8, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0xb5, 0xff, 0xf7, 0x29, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 
+0x01, 0x20, 0x14, 0x4f, 0x71, 0x23, 0x5b, 0x01, 0xf9, 0x18, 0x08, 0x71, 
+0x12, 0x48, 0xfe, 0xf7, 0xe9, 0xfd, 0x01, 0x20, 0x40, 0x02, 0xa1, 0x21, 
+0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0xf9, 0x1d, 0xb9, 0x31, 0x08, 0x70, 
+0x0d, 0x4a, 0x01, 0x23, 0x1b, 0x04, 0x11, 0x68, 0x0b, 0x40, 0x12, 0x21, 
+0x00, 0x2b, 0x05, 0xd1, 0x13, 0x68, 0x1b, 0x0c, 0x08, 0xd1, 0x12, 0x68, 
+0x92, 0x0a, 0x05, 0xd3, 0x07, 0x4a, 0xc0, 0x46, 0xd1, 0x60, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x05, 0x4a, 0xc0, 0x46, 0x11, 0x64, 0xf8, 0xe7, 
+0xe8, 0x0d, 0x00, 0x80, 0xa9, 0x9d, 0x21, 0x40, 0x00, 0x00, 0x10, 0x40, 
+0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x02, 0xf0, 
+0x83, 0xfb, 0x01, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0, 
+0x07, 0x1c, 0xf8, 0x88, 0x02, 0xf0, 0x88, 0xfc, 0x00, 0x28, 0x0c, 0xd1, 
+0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0xc8, 0xff, 0x06, 0x48, 0x01, 0xab, 
+0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x01, 0xff, 0x01, 0x20, 
+0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0xff, 0xff, 0x00, 0x00, 0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xfe, 0xf7, 
+0xb3, 0xff, 0x03, 0xf0, 0x71, 0xfe, 0x01, 0xab, 0x58, 0x80, 0x09, 0x48, 
+0x81, 0x89, 0x09, 0x04, 0xc2, 0x89, 0x11, 0x43, 0x02, 0x91, 0x81, 0x88, 
+0x09, 0x04, 0xc0, 0x88, 0x08, 0x43, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 
+0xfe, 0xf7, 0xe0, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 
+0xc8, 0x29, 0x00, 0x80, 0x00, 0xb5, 0xfe, 0xf7, 0xaf, 0xff, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xaa, 0xff, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0xb5, 0xfe, 0xf7, 0xa5, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
+0xfe, 0xf7, 0xa0, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 
+0x9b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x96, 0xff, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x91, 0xff, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x8c, 0xff, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0xb5, 0xfe, 0xf7, 0x87, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
+0xfe, 0xf7, 0x82, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 
+0x7d, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x78, 0xff, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x73, 0xff, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0xb5, 0x8c, 0xb0, 0x08, 0xa9, 0xfe, 0xf7, 0x54, 0xff, 
+0x69, 0x46, 0x08, 0xa8, 0x03, 0xf0, 0xba, 0xfe, 0x02, 0x20, 0x08, 0xab, 
+0x58, 0x70, 0x69, 0x46, 0x08, 0xa8, 0xfe, 0xf7, 0x89, 0xfe, 0x01, 0x20, 
+0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x5a, 0xff, 
+0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 
+0x38, 0x1c, 0xfe, 0xf7, 0x39, 0xff, 0xf9, 0x88, 0x10, 0x48, 0x01, 0x24, 
+0x00, 0x29, 0x0e, 0xd0, 0x04, 0x73, 0x44, 0x73, 0xb9, 0x68, 0x09, 0x0c, 
+0x41, 0x82, 0xb9, 0x68, 0xc0, 0x46, 0x81, 0x82, 0xf9, 0x68, 0x09, 0x0c, 
+0xc1, 0x82, 0xf9, 0x68, 0xc0, 0x46, 0x01, 0x83, 0x02, 0xe0, 0x00, 0x21, 
+0x01, 0x73, 0x41, 0x73, 0x06, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 
+0x00, 0x21, 0xfe, 0xf7, 0x5b, 0xfe, 0x20, 0x1c, 
+0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 
+0xff, 0xff, 0x00, 0x00, 0x00, 0xb5, 0xfe, 0xf7, 0x27, 0xff, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x22, 0xff, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0xb5, 0xfe, 0xf7, 0x1d, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 
+0xfe, 0xf7, 0x18, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 
+0x13, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 
+0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0xf2, 0xfe, 0xf8, 0x88, 0x03, 0x24, 
+0xe4, 0x04, 0x04, 0x43, 0x03, 0x23, 0xdb, 0x04, 0x9c, 0x42, 0x02, 0xd3, 
+0x0f, 0x4b, 0x9c, 0x42, 0x06, 0xd9, 0x0f, 0x48, 0x01, 0xab, 0x58, 0x80, 
+0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x20, 0xfe, 0x01, 0x20, 0x80, 0x07, 
+0x20, 0x43, 0x00, 0x68, 0x00, 0x21, 0x00, 0xab, 0x59, 0x70, 0xfa, 0x88, 
+0xc0, 0x46, 0xda, 0x80, 0x02, 0x90, 0x03, 0x91, 0x68, 0x46, 0x04, 0x33, 
+0xfe, 0xf7, 0x10, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xe0, 0x00, 0x18, 0x00, 0xff, 0xff, 0x00, 0x00, 
+0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 
+0xbf, 0xfe, 0xf8, 0x88, 0x03, 0x23, 0xdb, 0x04, 0x18, 0x43, 0x98, 0x42, 
+0x02, 0xd3, 0x0a, 0x4b, 0x98, 0x42, 0x08, 0xd9, 0x09, 0x48, 0x01, 0xab, 
+0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xef, 0xfd, 0x01, 0x20, 
+0x03, 0xe0, 0xb9, 0x68, 0xc0, 0x46, 0x01, 0x60, 0x00, 0x20, 0x04, 0xb0, 
+0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe0, 0x00, 0x18, 0x00, 
+0xff, 0xff, 0x00, 0x00, 0x80, 0xb5, 0x86, 0xb0, 0x07, 0x1c, 0x03, 0xf0, 
+0x5b, 0xfd, 0x38, 0x1c, 0x02, 0xa9, 0xfe, 0xf7, 0x97, 0xfe, 0x01, 0x27, 
+0x02, 0xab, 0x5f, 0x70, 0x00, 0x20, 0xd8, 0x80, 0x0a, 0x48, 0x01, 0x68, 
+0xc0, 0x46, 0x04, 0x91, 0x41, 0x68, 0xc0, 0x46, 0x05, 0x91, 0x81, 0x68, 
+0xc0, 0x46, 0x00, 0x91, 0x00, 0x69, 0xc0, 0x46, 0x01, 0x90, 0x69, 0x46, 
+0x02, 0xa8, 0xfe, 0xf7, 0xc1, 0xfd, 0x38, 0x1c, 0x06, 0xb0, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xe8, 0x18, 0x00, 0x80, 0x00, 0xb5, 0xc1, 0x68, 
+0x80, 0x68, 0xfe, 0xf7, 0x79, 0xfb, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0x20, 0x70, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x0f, 0x1c, 
+0x68, 0x46, 0x50, 0x21, 0xfe, 0xf7, 0x76, 0xfe, 0x01, 0xab, 0x5c, 0x80, 
+0x02, 0x97, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xa1, 0xfd, 0x04, 0xb0, 
+0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 
+0x68, 0x46, 0x51, 0x21, 0xfe, 0xf7, 0x64, 0xfe, 0x01, 0xab, 0x5f, 0x80, 
+0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x90, 0xfd, 0x04, 0xb0, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 
+0x90, 0xb5, 0x84, 0xb0, 0x00, 0x27, 0x12, 0x49, 0x09, 0x68, 0x12, 0x4a, 
+0x12, 0x6b, 0x10, 0x23, 0x1a, 0x40, 0x01, 0x24, 0x00, 0x2a, 0x00, 0xd0, 
+0x01, 0x27, 0x8a, 0x0c, 0x03, 0xd3, 0x3a, 0x04, 0x12, 0x0c, 0x02, 0x27, 
+0x17, 0x43, 0xc9, 0x0c, 0x03, 0xd3, 0x39, 0x04, 0x09, 0x0c, 0x04, 0x27, 
+0x0f, 0x43, 0x69, 0x46, 0xfe, 0xf7, 0x2c, 0xfe, 0x01, 0xab, 0x5f, 0x80, 
+0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x66, 0xfd, 0x20, 0x1c, 0x04, 0xb0, 
+0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 
+0xc0, 0x00, 0x18, 0x40, 0x00, 0xb5, 0x84, 0xb0, 
+0x69, 0x46, 0xfe, 0xf7, 0x17, 0xfe, 0x06, 0x48, 0xc0, 0x6d, 0x01, 0xab, 
+0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x4f, 0xfd, 0x01, 0x20, 
+0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x10, 0x2a, 0x00, 0x80, 
+0x00, 0xb5, 0xfe, 0xf7, 0x1d, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x70, 0x47, 
+0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 
+0x80, 0xb5, 0x01, 0x20, 0x14, 0x4f, 0x71, 0x23, 0x5b, 0x01, 0xf9, 0x18, 
+0x48, 0x71, 0x13, 0x48, 0xfe, 0xf7, 0xd6, 0xfb, 0x01, 0x20, 0x40, 0x02, 
+0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0xf9, 0x1d, 0xb9, 0x31, 
+0x08, 0x70, 0x0e, 0x4a, 0x01, 0x23, 0x1b, 0x04, 0x11, 0x68, 0x0b, 0x40, 
+0x15, 0x21, 0x00, 0x2b, 0x05, 0xd1, 0x13, 0x68, 0x1b, 0x0c, 0x08, 0xd1, 
+0x12, 0x68, 0x92, 0x0a, 0x05, 0xd3, 0x08, 0x4a, 0xc0, 0x46, 0xd1, 0x60, 
+0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x06, 0x4a, 0xc0, 0x46, 0x11, 0x64, 
+0xf8, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0xa9, 0x9d, 0x21, 0x40, 
+0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 
+0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 
+0x80, 0xb5, 0x85, 0xb0, 0x01, 0xa9, 0xfe, 0xf7, 0xbb, 0xfd, 0x00, 0x20, 
+0x01, 0xab, 0x58, 0x70, 0x10, 0x49, 0xc9, 0x68, 0x01, 0x27, 0x01, 0x29, 
+0x0a, 0xd1, 0x03, 0xf0, 0xb9, 0xfc, 0x03, 0x90, 0x04, 0x97, 0x03, 0x98, 
+0x00, 0x28, 0x06, 0xd0, 0x68, 0x46, 0x02, 0xf0, 0x15, 0xf8, 0x04, 0xe0, 
+0x03, 0x97, 0x04, 0x90, 0xf8, 0xe7, 0x00, 0x20, 0x00, 0x90, 0x02, 0xab, 
+0x00, 0x98, 0xc0, 0x46, 0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfe, 0xf7, 
+0xdb, 0xfc, 0x38, 0x1c, 0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0xe8, 0x0d, 0x00, 0x80, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 
+0x38, 0x1c, 0xfe, 0xf7, 0x8d, 0xfd, 0x00, 0x20, 0x00, 0xab, 0x58, 0x70, 
+0x01, 0x24, 0x20, 0x1c, 0x12, 0x49, 0xc9, 0x68, 0x01, 0x29, 0x00, 0xd0, 
+0x00, 0x20, 0x00, 0x06, 0x00, 0x0e, 0x13, 0xd0, 0xf8, 0x88, 0x0f, 0x4a, 
+0x90, 0x42, 0x02, 0xd0, 0x0e, 0x4b, 0x98, 0x42, 0x08, 0xd1, 0xb9, 0x68, 
+0x27, 0x1c, 0x90, 0x42, 0x00, 0xd0, 0x00, 0x27, 0x38, 0x06, 0x00, 0x0e, 
+0x03, 0xf0, 0xa0, 0xfc, 0x03, 0xf0, 0x76, 0xfc, 0x02, 0x90, 0x00, 0xe0, 
+0x02, 0x94, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xa7, 0xfc, 0x20, 0x1c, 
+0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
+0xed, 0xfe, 0x00, 0x00, 0xfe, 0xca, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c, 
+0x00, 0x24, 0x00, 0x2f, 0x04, 0xd3, 0x04, 0xf0, 0x9b, 0xf8, 0x01, 0x34, 
+0xbc, 0x42, 0xfa, 0xd9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 
+0x14, 0x1c, 0x0d, 0x1c, 0x06, 0x1c, 0x1f, 0x1c, 0x1b, 0x4b, 0x32, 0x04, 
+0x12, 0x0c, 0x3c, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x2a, 0xfb, 0x32, 0x0c, 
+0x17, 0x4b, 0x3e, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x24, 0xfb, 0x15, 0x4b, 
+0x2a, 0x04, 0x12, 0x0c, 0x40, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x1d, 0xfb, 
+0x2a, 0x0c, 0x11, 0x4b, 0x42, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0x17, 0xfb, 
+0x0e, 0x4b, 0x22, 0x04, 0x12, 0x0c, 0x44, 0x21, 0x02, 0x20, 0xfe, 0xf7, 
+0x10, 0xfb, 0x22, 0x0c, 0x0a, 0x4b, 0x46, 0x21, 0x02, 0x20, 0xfe, 0xf7, 
+0x0a, 0xfb, 0x08, 0x4b, 0x3a, 0x04, 0x12, 0x0c, 0x48, 0x21, 0x02, 0x20, 
+0xfe, 0xf7, 0x03, 0xfb, 0x3a, 0x0c, 0x04, 0x4b, 
+0x4a, 0x21, 0x02, 0x20, 0xfe, 0xf7, 0xfd, 0xfa, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x7b, 0xb7, 0x21, 0x40, 0x88, 0xb5, 0x11, 0x27, 
+0x3f, 0x04, 0x38, 0x62, 0x79, 0x62, 0xba, 0x62, 0xfb, 0x62, 0x04, 0x20, 
+0xff, 0xf7, 0xaa, 0xff, 0x07, 0x48, 0x40, 0x6b, 0xc0, 0x46, 0x00, 0x90, 
+0x00, 0x98, 0x80, 0x07, 0x80, 0x0f, 0x03, 0x28, 0x01, 0xd1, 0x01, 0x20, 
+0x00, 0xe0, 0x00, 0x20, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x00, 0x00, 0x11, 0x40, 0xf0, 0xb5, 0x8a, 0xb0, 0x00, 0x24, 0x05, 0x94, 
+0x69, 0x49, 0xc9, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x68, 0x4a, 0x11, 0x68, 
+0x01, 0x22, 0x12, 0x04, 0x0a, 0x40, 0x17, 0x21, 0x66, 0x4e, 0x00, 0x2a, 
+0x06, 0xd1, 0x64, 0x4a, 0x13, 0x68, 0x1b, 0x0c, 0x04, 0xd1, 0x12, 0x68, 
+0x92, 0x0a, 0x01, 0xd3, 0xf1, 0x60, 0x02, 0xe0, 0x61, 0x4a, 0xc0, 0x46, 
+0x11, 0x64, 0x61, 0x49, 0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x03, 0x29, 
+0x54, 0xd1, 0xe9, 0x21, 0x01, 0x91, 0x02, 0x99, 0xc0, 0x46, 0xb1, 0x60, 
+0x06, 0x94, 0x06, 0x99, 0x8a, 0x00, 0x5b, 0x49, 0x8a, 0x58, 0x00, 0x2a, 
+0x73, 0xd0, 0x80, 0x20, 0x02, 0x90, 0x06, 0x98, 0x81, 0x00, 0x57, 0x48, 
+0x41, 0x58, 0x02, 0x9a, 0x11, 0x43, 0x02, 0x91, 0x00, 0x24, 0x00, 0x27, 
+0x25, 0x02, 0x28, 0x1c, 0x38, 0x43, 0x09, 0x90, 0x09, 0x98, 0x00, 0x04, 
+0x51, 0x4b, 0x18, 0x43, 0x04, 0x90, 0x09, 0x98, 0xef, 0x23, 0xdb, 0x05, 
+0x18, 0x43, 0x03, 0x90, 0x06, 0x98, 0x80, 0x00, 0x4b, 0x49, 0x08, 0x58, 
+0x00, 0x04, 0x03, 0x99, 0x08, 0x43, 0x03, 0x90, 0x00, 0x2f, 0x02, 0xd1, 
+0x03, 0x98, 0xc0, 0x46, 0x70, 0x60, 0x01, 0x9b, 0x03, 0x9a, 0x02, 0x99, 
+0x04, 0x98, 0xff, 0xf7, 0x89, 0xff, 0x00, 0x28, 0x06, 0xd0, 0x02, 0x99, 
+0xc0, 0x46, 0xb1, 0x60, 0x03, 0x99, 0xc0, 0x46, 0x71, 0x60, 0x5c, 0xe0, 
+0x79, 0x1c, 0x0f, 0x04, 0x3f, 0x0c, 0x17, 0x2f, 0xd1, 0xdd, 0x61, 0x1c, 
+0x0c, 0x04, 0x24, 0x0c, 0x16, 0x2c, 0xca, 0xdd, 0x06, 0x99, 0x01, 0x31, 
+0x06, 0x91, 0x06, 0x99, 0x89, 0x00, 0x37, 0x4a, 0x51, 0x58, 0x00, 0x29, 
+0xb7, 0xd1, 0x48, 0xe0, 0xbf, 0x21, 0xc9, 0x43, 0x04, 0x91, 0xff, 0x21, 
+0x02, 0x91, 0x97, 0x21, 0x01, 0x91, 0x06, 0x94, 0x06, 0x99, 0x89, 0x00, 
+0x31, 0x4f, 0x79, 0x58, 0x00, 0x29, 0x1c, 0xd0, 0x09, 0x94, 0x08, 0x94, 
+0x06, 0x98, 0x80, 0x00, 0x38, 0x58, 0xc0, 0x46, 0x07, 0x90, 0x07, 0x98, 
+0x00, 0x04, 0x26, 0xe0, 0x05, 0x98, 0x15, 0x23, 0x1b, 0x06, 0x18, 0x43, 
+0x03, 0x90, 0x01, 0x9b, 0x03, 0x9a, 0x02, 0x99, 0x04, 0x98, 0xff, 0xf7, 
+0x49, 0xff, 0x00, 0x28, 0x23, 0xd1, 0x09, 0x99, 0x01, 0x31, 0x09, 0x91, 
+0x17, 0x29, 0x06, 0xd8, 0x00, 0xe0, 0x1c, 0xe0, 0x08, 0x98, 0x00, 0x02, 
+0x09, 0x99, 0x08, 0x43, 0x07, 0xe0, 0x08, 0x99, 0x01, 0x31, 0x08, 0x91, 
+0x17, 0x29, 0x0a, 0xd8, 0x09, 0x94, 0x08, 0x98, 0x00, 0x02, 0x07, 0x99, 
+0x09, 0x04, 0x08, 0x43, 0x15, 0x23, 0x1b, 0x06, 0x18, 0x43, 0x05, 0x90, 
+0xd6, 0xe7, 0x06, 0x99, 0x01, 0x31, 0x06, 0x91, 0x06, 0x99, 0x89, 0x00, 
+0x79, 0x58, 0x00, 0x29, 0xc4, 0xd1, 0x0c, 0x4a, 0x11, 0x68, 0x49, 0x0c, 
+0x05, 0xd2, 0x11, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x11, 0x68, 0x89, 0x0a, 
+0x03, 0xd3, 0x00, 0x99, 0xc0, 0x46, 0xf1, 0x60, 0x03, 0xe0, 0x00, 0x99, 
+0x06, 0x4a, 0xc0, 0x46, 0x11, 0x64, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x40, 0x01, 0x18, 0x40, 
+0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 
+0x00, 0x00, 0x18, 0x40, 0x30, 0x6e, 0x21, 0x40, 0x43, 0xff, 0x00, 0x00, 
+0x0c, 0x6e, 0x21, 0x40, 0x80, 0xb5, 0x82, 0xb0, 0x00, 0x20, 0x01, 0x90, 
+0x1e, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x1b, 0xd1, 0x40, 0x88, 0x00, 0x28, 
+0x18, 0xd1, 0x68, 0x46, 0x01, 0xf0, 0x6a, 0xfe, 0x00, 0x28, 0x13, 0xd1, 
+0xa8, 0x20, 0x01, 0xf0, 0xab, 0xfe, 0x18, 0x4f, 0x00, 0x28, 0x11, 0xd0, 
+0x04, 0x20, 0xff, 0xf7, 0x97, 0xfe, 0x78, 0x6b, 0xc0, 0x46, 0x01, 0x90, 
+0x01, 0x98, 0x80, 0x07, 0x80, 0x0f, 0x03, 0x28, 0x06, 0xd1, 0x00, 0x20, 
+0x01, 0xf0, 0x9a, 0xfe, 0x02, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x00, 0x23, 0x00, 0x22, 0x00, 0x21, 0x00, 0x20, 0xff, 0xf7, 0x8f, 0xfe, 
+0x00, 0x23, 0xdb, 0x43, 0x18, 0x1c, 0x19, 0x1c, 0x1a, 0x1c, 0xff, 0xf7, 
+0xc7, 0xfe, 0x00, 0x28, 0x03, 0xd1, 0xff, 0xf7, 0xdf, 0xfe, 0x00, 0x28, 
+0xe5, 0xd0, 0x38, 0x6a, 0x79, 0x6a, 0xba, 0x6a, 0xfb, 0x6a, 0xff, 0xf7, 
+0x7c, 0xfe, 0xde, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x11, 0x40, 
+0xff, 0xb5, 0x85, 0xb0, 0x14, 0x1c, 0x1f, 0x1c, 0x00, 0x20, 0x01, 0x90, 
+0x01, 0x23, 0x5b, 0x04, 0x9f, 0x42, 0x01, 0xd9, 0x0f, 0x20, 0x82, 0xe0, 
+0x26, 0x1c, 0x43, 0x4d, 0xaf, 0x42, 0x00, 0xd2, 0x3d, 0x1c, 0x21, 0x0d, 
+0x09, 0x05, 0x41, 0x48, 0x41, 0x4b, 0x99, 0x42, 0x04, 0xd0, 0x80, 0x25, 
+0x06, 0x1c, 0x80, 0x2f, 0x00, 0xd8, 0x3d, 0x1c, 0x3e, 0x4a, 0x51, 0x69, 
+0xc0, 0x46, 0x03, 0x91, 0x92, 0x69, 0xc0, 0x46, 0x02, 0x92, 0xff, 0x23, 
+0x01, 0x33, 0x19, 0x43, 0x39, 0x4b, 0xc0, 0x46, 0x59, 0x61, 0xff, 0x23, 
+0x01, 0x33, 0x9a, 0x43, 0x36, 0x4b, 0xc0, 0x46, 0x9a, 0x61, 0x01, 0x22, 
+0x12, 0x05, 0xd1, 0x60, 0x33, 0x4a, 0x91, 0x69, 0x01, 0x22, 0x12, 0x05, 
+0x11, 0x61, 0x31, 0x4a, 0xff, 0x23, 0x01, 0x33, 0x91, 0x69, 0x19, 0x43, 
+0x91, 0x61, 0x01, 0x22, 0x12, 0x05, 0x11, 0x61, 0x85, 0x21, 0x89, 0x04, 
+0x04, 0x91, 0x00, 0x2f, 0x34, 0xd0, 0x28, 0x48, 0x86, 0x42, 0x04, 0xd1, 
+0x30, 0x1c, 0x21, 0x1c, 0x2a, 0x1c, 0x03, 0xf0, 0xd5, 0xfe, 0x2a, 0x1c, 
+0x04, 0x98, 0x02, 0x43, 0x00, 0x92, 0x01, 0x20, 0x06, 0x99, 0x05, 0x9a, 
+0x33, 0x1c, 0xfe, 0xf7, 0x5d, 0xf9, 0x22, 0x48, 0x22, 0x49, 0x4a, 0x68, 
+0x52, 0x0a, 0x09, 0xd3, 0xff, 0x21, 0x01, 0x31, 0x20, 0x4a, 0xc0, 0x46, 
+0x11, 0x60, 0x00, 0x28, 0x05, 0xd1, 0x11, 0x20, 0x01, 0x90, 0x13, 0xe0, 
+0x01, 0x38, 0xf0, 0xd1, 0xf9, 0xe7, 0x7f, 0x1b, 0x0e, 0xd0, 0x15, 0x48, 
+0x86, 0x42, 0x01, 0xd1, 0x64, 0x19, 0x00, 0xe0, 0x76, 0x19, 0x06, 0x99, 
+0x49, 0x19, 0x06, 0x91, 0x38, 0x1c, 0xaf, 0x42, 0x00, 0xd3, 0x28, 0x1c, 
+0x05, 0x1c, 0xca, 0xe7, 0x0f, 0x48, 0x41, 0x69, 0x03, 0x9b, 0x19, 0x43, 
+0x41, 0x61, 0x82, 0x69, 0x03, 0x9b, 0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 
+0x12, 0x05, 0xd1, 0x60, 0x81, 0x69, 0xc0, 0x46, 0x11, 0x61, 0x81, 0x69, 
+0x02, 0x9b, 0x19, 0x43, 0x81, 0x61, 0x11, 0x61, 0x01, 0x98, 0x09, 0xb0, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 
+0x50, 0xab, 0x20, 0x40, 0x00, 0x00, 0x20, 0x40, 0xe8, 0x0d, 0x00, 0x80, 
+0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0xb0, 
+0xff, 0xb5, 0x85, 0xb0, 0x04, 0x1c, 0x1f, 0x1c, 0x00, 0x20, 0x01, 0x90, 
+0x01, 0x23, 0x5b, 0x04, 0x9f, 0x42, 0x01, 0xd9, 
+0x0f, 0x20, 0x7d, 0xe0, 0x26, 0x1c, 0x40, 0x4d, 0xaf, 0x42, 0x00, 0xd2, 
+0x3d, 0x1c, 0x21, 0x0d, 0x09, 0x05, 0x3e, 0x48, 0x3e, 0x4b, 0x99, 0x42, 
+0x04, 0xd0, 0x80, 0x25, 0x06, 0x1c, 0x80, 0x2f, 0x00, 0xd8, 0x3d, 0x1c, 
+0x3b, 0x4a, 0x51, 0x69, 0xc0, 0x46, 0x03, 0x91, 0x92, 0x69, 0xc0, 0x46, 
+0x02, 0x92, 0x10, 0x23, 0x19, 0x43, 0x37, 0x4b, 0xc0, 0x46, 0x59, 0x61, 
+0x10, 0x23, 0x9a, 0x43, 0x34, 0x4b, 0xc0, 0x46, 0x9a, 0x61, 0x01, 0x22, 
+0x12, 0x05, 0xd1, 0x60, 0x31, 0x4a, 0x91, 0x69, 0x01, 0x22, 0x12, 0x05, 
+0x11, 0x61, 0x2f, 0x4a, 0x10, 0x23, 0x91, 0x69, 0x19, 0x43, 0x91, 0x61, 
+0x1a, 0x04, 0x11, 0x61, 0x21, 0x21, 0x09, 0x05, 0x04, 0x91, 0x00, 0x2f, 
+0x33, 0xd0, 0x2a, 0x1c, 0x04, 0x98, 0x02, 0x43, 0x00, 0x92, 0x00, 0x20, 
+0x06, 0x99, 0x07, 0x9a, 0x33, 0x1c, 0xfe, 0xf7, 0xc7, 0xf8, 0x25, 0x48, 
+0x25, 0x49, 0x4a, 0x68, 0x52, 0x09, 0x08, 0xd3, 0x10, 0x21, 0x24, 0x4a, 
+0xc0, 0x46, 0x11, 0x60, 0x00, 0x28, 0x05, 0xd1, 0x11, 0x20, 0x01, 0x90, 
+0x1b, 0xe0, 0x01, 0x38, 0xf1, 0xd1, 0xf9, 0xe7, 0x19, 0x48, 0x86, 0x42, 
+0x04, 0xd1, 0x20, 0x1c, 0x31, 0x1c, 0x2a, 0x1c, 0x03, 0xf0, 0x1c, 0xfe, 
+0x7f, 0x1b, 0x0e, 0xd0, 0x14, 0x48, 0x86, 0x42, 0x01, 0xd0, 0x76, 0x19, 
+0x00, 0xe0, 0x64, 0x19, 0x06, 0x99, 0x49, 0x19, 0x06, 0x91, 0x38, 0x1c, 
+0xaf, 0x42, 0x00, 0xd3, 0x28, 0x1c, 0x05, 0x1c, 0xcb, 0xe7, 0x0f, 0x48, 
+0x41, 0x69, 0x03, 0x9b, 0x19, 0x43, 0x41, 0x61, 0x82, 0x69, 0x03, 0x9b, 
+0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, 0x81, 0x69, 
+0xc0, 0x46, 0x11, 0x61, 0x81, 0x69, 0x02, 0x9b, 0x19, 0x43, 0x81, 0x61, 
+0x11, 0x61, 0x01, 0x98, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0xf0, 0xff, 0x00, 0x00, 0x50, 0xab, 0x20, 0x40, 0x00, 0x00, 0x20, 0x40, 
+0xe8, 0x0d, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 
+0x00, 0x00, 0x00, 0xb0, 0x70, 0x47, 0x04, 0x49, 0x00, 0x20, 0x00, 0x22, 
+0x0a, 0x70, 0x01, 0x30, 0x01, 0x31, 0x68, 0x28, 0xfa, 0xd3, 0x70, 0x47, 
+0xa0, 0x82, 0x20, 0x40, 0x00, 0x22, 0x88, 0x42, 0x03, 0xd3, 0x40, 0x1a, 
+0x01, 0x32, 0x88, 0x42, 0xfb, 0xd2, 0x10, 0x1c, 0x70, 0x47, 0x88, 0x42, 
+0x02, 0xd3, 0x40, 0x1a, 0x88, 0x42, 0xfc, 0xd2, 0x70, 0x47, 0x90, 0xb4, 
+0x01, 0x1c, 0xff, 0x27, 0x04, 0x29, 0x27, 0xda, 0x00, 0x20, 0x14, 0x4a, 
+0x43, 0x00, 0x1b, 0x18, 0xdb, 0x00, 0xd4, 0x58, 0x63, 0x0c, 0x1a, 0xd2, 
+0x4b, 0x00, 0x59, 0x18, 0xc9, 0x00, 0x57, 0x58, 0x43, 0x00, 0x1b, 0x18, 
+0xdb, 0x00, 0xd7, 0x50, 0x89, 0x18, 0x9a, 0x18, 0x4f, 0x68, 0xc0, 0x46, 
+0x57, 0x60, 0x8b, 0x68, 0xc0, 0x46, 0x93, 0x60, 0x0b, 0x69, 0xc0, 0x46, 
+0x13, 0x61, 0x4b, 0x69, 0xc0, 0x46, 0x53, 0x61, 0xc9, 0x68, 0xc0, 0x46, 
+0xd1, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 
+0x04, 0x28, 0xd9, 0xdb, 0x38, 0x1c, 0xf6, 0xe7, 0xd0, 0xab, 0x20, 0x40, 
+0xf7, 0xb5, 0xc5, 0xb0, 0x14, 0x1c, 0x00, 0x20, 0x11, 0x21, 0x21, 0x40, 
+0x5f, 0xd0, 0x00, 0x27, 0x79, 0x00, 0xc9, 0x19, 0xc9, 0x00, 0x5b, 0x4a, 
+0x51, 0x58, 0x49, 0x0c, 0x03, 0xd2, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 
+0x04, 0xe0, 0x79, 0x1c, 0x0f, 0x06, 0x3f, 0x0e, 0x04, 0x2f, 0xef, 0xdb, 
+0x00, 0x28, 0x4c, 0xd0, 0x00, 0x22, 0x01, 0x92, 0x00, 0x92, 0x40, 0x23, 
+0x00, 0x21, 0x00, 0x20, 0x03, 0xaa, 0x00, 0xf0, 
+0x8f, 0xfa, 0x05, 0xa9, 0x00, 0x20, 0x82, 0x00, 0x8a, 0x58, 0x12, 0x06, 
+0x12, 0x0e, 0x45, 0x9b, 0x9a, 0x42, 0x05, 0xd1, 0x01, 0x9a, 0x01, 0x32, 
+0x12, 0x06, 0x12, 0x0e, 0x01, 0x92, 0x04, 0xe0, 0x01, 0x30, 0x00, 0x06, 
+0x00, 0x0e, 0x10, 0x28, 0xed, 0xdb, 0x01, 0x9a, 0x00, 0x2a, 0x4f, 0xd0, 
+0x45, 0x9b, 0x04, 0x2b, 0x3e, 0xd1, 0x80, 0x00, 0x08, 0x58, 0x40, 0x01, 
+0x80, 0x0d, 0x00, 0x22, 0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x03, 0xaa, 
+0x00, 0xf0, 0x6a, 0xfa, 0x00, 0x21, 0x01, 0x91, 0x03, 0xa8, 0x06, 0x99, 
+0x49, 0x0c, 0x89, 0x05, 0x2a, 0xd0, 0xc1, 0x68, 0x0a, 0x06, 0x12, 0x0e, 
+0x46, 0x9b, 0x9a, 0x42, 0x12, 0xd1, 0xc0, 0x68, 0x40, 0x01, 0x86, 0x0d, 
+0x00, 0x22, 0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x03, 0xaa, 
+0x00, 0xf0, 0x52, 0xfa, 0x01, 0x99, 0x03, 0x9d, 0x48, 0x1c, 0x01, 0x06, 
+0x09, 0x0e, 0x01, 0x91, 0x0f, 0xe0, 0x57, 0xe0, 0x48, 0x01, 0x86, 0x0d, 
+0x00, 0x22, 0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x03, 0xaa, 
+0x00, 0xf0, 0x40, 0xfa, 0x03, 0xa8, 0x06, 0x99, 0x49, 0x0c, 0x89, 0x05, 
+0xd7, 0xd1, 0x01, 0x99, 0x00, 0x29, 0x11, 0xd1, 0xff, 0x20, 0x3f, 0xe0, 
+0x80, 0x00, 0x08, 0x58, 0x40, 0x01, 0x86, 0x0d, 0x00, 0x22, 0x00, 0x92, 
+0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x03, 0xaa, 0x00, 0xf0, 0x2a, 0xfa, 
+0x03, 0x9d, 0x01, 0xe0, 0x20, 0x0a, 0xed, 0xd2, 0x01, 0x20, 0x00, 0x04, 
+0x20, 0x43, 0x79, 0x00, 0xc9, 0x19, 0xc9, 0x00, 0x17, 0x4a, 0xc0, 0x46, 
+0x50, 0x50, 0x30, 0x1c, 0x8e, 0x18, 0x70, 0x60, 0x10, 0x20, 0x45, 0x9b, 
+0x04, 0x2b, 0x00, 0xd0, 0x0c, 0x20, 0x02, 0x90, 0xb0, 0x60, 0x00, 0x20, 
+0x20, 0x21, 0x21, 0x40, 0x20, 0x29, 0x00, 0xd0, 0x28, 0x1c, 0x30, 0x61, 
+0x02, 0x98, 0x28, 0x18, 0xff, 0x21, 0xff, 0x30, 0x08, 0x30, 0x09, 0x31, 
+0xff, 0xf7, 0x12, 0xff, 0x43, 0x01, 0x18, 0x18, 0xc0, 0x00, 0x02, 0x99, 
+0x40, 0x1a, 0x70, 0x61, 0x00, 0x20, 0x50, 0x21, 0x21, 0x40, 0x50, 0x29, 
+0x00, 0xd1, 0x28, 0x1c, 0xf0, 0x60, 0x38, 0x1c, 0x48, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xff, 0x20, 0xf9, 0xe7, 0xd0, 0xab, 0x20, 0x40, 
+0x80, 0xb4, 0x00, 0x23, 0x00, 0x22, 0x00, 0x29, 0x06, 0xd9, 0x87, 0x5c, 
+0x7b, 0x40, 0x1b, 0x06, 0x1b, 0x0e, 0x01, 0x32, 0x8a, 0x42, 0xf8, 0xd3, 
+0xd8, 0x43, 0x00, 0x06, 0x00, 0x0e, 0x80, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 
+0xc6, 0xb0, 0x04, 0x28, 0x07, 0xda, 0x41, 0x00, 0x09, 0x18, 0xc9, 0x00, 
+0x45, 0x91, 0x41, 0x4a, 0x51, 0x58, 0x4b, 0x0c, 0x02, 0xd2, 0x00, 0x20, 
+0xc0, 0x43, 0x76, 0xe0, 0x01, 0x23, 0x5b, 0x04, 0x19, 0x40, 0x43, 0x00, 
+0x18, 0x18, 0xc0, 0x00, 0x3a, 0x4a, 0x14, 0x18, 0x00, 0x29, 0x61, 0xd0, 
+0x00, 0x21, 0x02, 0x91, 0x20, 0x69, 0xa1, 0x68, 0x45, 0x18, 0x30, 0xd0, 
+0xff, 0x21, 0x68, 0x1e, 0x09, 0x31, 0xff, 0xf7, 0xc7, 0xfe, 0x61, 0x68, 
+0x40, 0x18, 0x01, 0x90, 0x01, 0x98, 0x81, 0x42, 0x02, 0xd1, 0xa6, 0x68, 
+0xaf, 0x1b, 0x09, 0xe0, 0x00, 0x26, 0xff, 0x21, 0x28, 0x1c, 0x09, 0x31, 
+0xff, 0xf7, 0xc1, 0xfe, 0x07, 0x1c, 0x01, 0xd1, 0xff, 0x27, 0x09, 0x37, 
+0x00, 0x22, 0x00, 0x92, 0x01, 0x98, 0x31, 0x1c, 0x03, 0xaa, 0x3b, 0x1c, 
+0x00, 0xf0, 0x9e, 0xf9, 0x03, 0xa8, 0x39, 0x1c, 0xff, 0xf7, 0xac, 0xff, 
+0xc0, 0x43, 0x02, 0x99, 0x48, 0x40, 0x01, 0x06, 0x09, 0x0e, 0x02, 0x91, 
+0xed, 0x1b, 0xa0, 0x68, 0xa8, 0x42, 0x00, 0xd1, 
+0x00, 0x25, 0x00, 0x2d, 0xce, 0xd8, 0x02, 0x99, 0xcf, 0x43, 0x00, 0x22, 
+0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x60, 0x68, 0x03, 0xaa, 0x00, 0xf0, 
+0x83, 0xf9, 0x20, 0x69, 0xc0, 0x46, 0x03, 0x90, 0x05, 0x98, 0x00, 0x0a, 
+0x00, 0x02, 0x39, 0x06, 0x09, 0x0e, 0x08, 0x43, 0x05, 0x90, 0xff, 0x23, 
+0x1b, 0x02, 0x98, 0x43, 0x05, 0x90, 0x0c, 0x21, 0x03, 0xa8, 0xff, 0xf7, 
+0x83, 0xff, 0xff, 0x23, 0x1b, 0x02, 0x05, 0x99, 0x99, 0x43, 0x00, 0x06, 
+0x00, 0x0e, 0x00, 0x02, 0x08, 0x43, 0x05, 0x90, 0x0c, 0x23, 0x00, 0x21, 
+0x60, 0x68, 0x03, 0xaa, 0x00, 0xf0, 0xbb, 0xf9, 0x00, 0x20, 0x45, 0x99, 
+0x06, 0x4a, 0xc0, 0x46, 0x50, 0x50, 0xc1, 0x43, 0x61, 0x60, 0xa1, 0x60, 
+0xe1, 0x60, 0x21, 0x61, 0x61, 0x61, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 0xb0, 0xb4, 0x4c, 0x42, 
+0x00, 0x29, 0x00, 0xdb, 0x0c, 0x1c, 0x00, 0x27, 0xff, 0x43, 0x04, 0x28, 
+0x21, 0xda, 0x12, 0x4d, 0x43, 0x00, 0x18, 0x18, 0xc0, 0x00, 0x40, 0x19, 
+0x01, 0x2a, 0x05, 0xd0, 0x02, 0x2a, 0x09, 0xd0, 0x03, 0x2a, 0x16, 0xd1, 
+0x01, 0x69, 0x0b, 0xe0, 0x00, 0x29, 0x12, 0xdb, 0x02, 0x69, 0x8a, 0x42, 
+0x0f, 0xd3, 0x05, 0xe0, 0x00, 0x29, 0x07, 0xda, 0xc1, 0x68, 0xa1, 0x42, 
+0x09, 0xd3, 0x09, 0x1b, 0xc1, 0x60, 0xc0, 0x68, 0xb0, 0xbc, 0x70, 0x47, 
+0xc1, 0x68, 0x09, 0x19, 0x02, 0x69, 0x91, 0x42, 0xf6, 0xd9, 0x38, 0x1c, 
+0xf6, 0xe7, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, 
+0x17, 0x1c, 0x0d, 0x1c, 0x00, 0x21, 0x02, 0x91, 0x42, 0x00, 0x12, 0x18, 
+0xd2, 0x00, 0x2c, 0x49, 0x8b, 0x58, 0x1b, 0x06, 0x1b, 0x0e, 0x01, 0x93, 
+0x00, 0x23, 0xdb, 0x43, 0x04, 0x28, 0x02, 0xda, 0x01, 0x98, 0x40, 0x08, 
+0x01, 0xd2, 0x18, 0x1c, 0x46, 0xe0, 0x54, 0x18, 0xe0, 0x68, 0xc2, 0x19, 
+0x21, 0x69, 0x8a, 0x42, 0x00, 0xd9, 0x0f, 0x1a, 0x00, 0x2f, 0x3c, 0xd9, 
+0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 
+0x07, 0xfe, 0x61, 0x68, 0x46, 0x18, 0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 
+0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 0x07, 0xfe, 0xc2, 0x19, 0xff, 0x21, 
+0x09, 0x31, 0x8a, 0x42, 0x14, 0xd9, 0x01, 0x9a, 0xc0, 0x46, 0x00, 0x92, 
+0x0b, 0x1a, 0x03, 0x93, 0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, 
+0xe1, 0xf8, 0xe0, 0x68, 0x03, 0x9b, 0xc0, 0x18, 0xe0, 0x60, 0x03, 0x9b, 
+0x5d, 0x19, 0xff, 0x1a, 0x02, 0x98, 0x18, 0x18, 0x02, 0x90, 0x10, 0xe0, 
+0x01, 0x9a, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 
+0x3b, 0x1c, 0x00, 0xf0, 0xcd, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, 
+0xe0, 0x60, 0x02, 0x98, 0xc0, 0x19, 0x02, 0x90, 0x00, 0x27, 0x00, 0x2f, 
+0xc2, 0xd8, 0x02, 0x98, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0xd0, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x83, 0xb0, 0x17, 0x1c, 0x0d, 0x1c, 
+0x00, 0x21, 0x01, 0x91, 0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x02, 0x92, 
+0x30, 0x49, 0x8a, 0x58, 0x12, 0x06, 0x12, 0x0e, 0x00, 0x24, 0xe4, 0x43, 
+0x04, 0x28, 0x01, 0xda, 0x50, 0x09, 0x01, 0xd2, 0x20, 0x1c, 0x51, 0xe0, 
+0x02, 0x9a, 0x54, 0x18, 0xe0, 0x68, 0xc2, 0x19, 0x60, 0x69, 0x82, 0x42, 
+0x01, 0xd9, 0x22, 0x69, 0x87, 0x1a, 0x00, 0x2f, 0x45, 0xd9, 0x25, 0x4e, 
+0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 
+0xa1, 0xfd, 0x61, 0x68, 0x40, 0x18, 0x00, 0x90, 
+0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 
+0xa0, 0xfd, 0x02, 0x9a, 0xb1, 0x58, 0x01, 0x23, 0x5b, 0x04, 0x19, 0x43, 
+0xb1, 0x50, 0xc1, 0x19, 0xff, 0x22, 0x09, 0x32, 0x91, 0x42, 0x13, 0xd9, 
+0x13, 0x1a, 0x01, 0x1c, 0x00, 0x98, 0x2a, 0x1c, 0x1e, 0x1c, 0x00, 0xf0, 
+0xd0, 0xf8, 0xe0, 0x68, 0x80, 0x19, 0x75, 0x19, 0xe0, 0x60, 0x21, 0x69, 
+0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0xbf, 0x1b, 0x01, 0x98, 0x30, 0x18, 
+0x01, 0x90, 0x12, 0xe0, 0x01, 0x1c, 0x00, 0x9e, 0x30, 0x1c, 0x2a, 0x1c, 
+0x3b, 0x1c, 0x00, 0xf0, 0xbc, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, 
+0xe0, 0x60, 0x21, 0x69, 0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0x01, 0x98, 
+0xc0, 0x19, 0x01, 0x90, 0x00, 0x27, 0x00, 0x2f, 0xb9, 0xd8, 0x01, 0x98, 
+0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xd0, 0xab, 0x20, 0x40, 
+0xb0, 0xb5, 0xc3, 0xb0, 0x0c, 0x1c, 0x00, 0x27, 0xfa, 0x43, 0x04, 0x28, 
+0x06, 0xda, 0x41, 0x00, 0x09, 0x18, 0xc9, 0x00, 0x14, 0x48, 0x45, 0x58, 
+0x6b, 0x0c, 0x04, 0xd2, 0x10, 0x1c, 0x43, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x62, 0x09, 0x1b, 0xd3, 0x00, 0x22, 0x00, 0x92, 0x08, 0x18, 
+0x40, 0x68, 0x0c, 0x23, 0x00, 0x21, 0x01, 0xaa, 0x00, 0xf0, 0x30, 0xf8, 
+0x11, 0x2c, 0x0d, 0xd0, 0x12, 0x2c, 0x0d, 0xd0, 0x13, 0x2c, 0x05, 0xd0, 
+0x14, 0x2c, 0x0a, 0xd1, 0x03, 0x98, 0x00, 0x04, 0x07, 0x0e, 0x06, 0xe0, 
+0x03, 0x98, 0x07, 0x06, 0x3f, 0x0e, 0x02, 0xe0, 0x01, 0x9f, 0x00, 0xe0, 
+0x02, 0x9f, 0x38, 0x1c, 0xdb, 0xe7, 0x00, 0x00, 0xd0, 0xab, 0x20, 0x40, 
+0x03, 0x49, 0x00, 0x20, 0x00, 0x22, 0x0a, 0x54, 0x01, 0x30, 0x60, 0x28, 
+0xfb, 0xd3, 0x70, 0x47, 0xd0, 0xab, 0x20, 0x40, 0x00, 0xb5, 0x02, 0xf0, 
+0x9f, 0xf9, 0x57, 0x20, 0x02, 0xf0, 0xfc, 0xf8, 0x02, 0xf0, 0x70, 0xf8, 
+0x00, 0x0a, 0xfb, 0xd3, 0x02, 0xf0, 0x7e, 0xf9, 0x08, 0xbc, 0x18, 0x47, 
+0xf0, 0xb5, 0x82, 0xb0, 0x14, 0x1c, 0x07, 0x9a, 0x1f, 0x1c, 0xff, 0x23, 
+0x01, 0x33, 0x1a, 0x40, 0x40, 0x02, 0x08, 0x43, 0x05, 0x0a, 0x06, 0x1c, 
+0x00, 0x0c, 0x01, 0x90, 0x00, 0x2a, 0x20, 0xd0, 0x02, 0xf0, 0x82, 0xf9, 
+0x53, 0x20, 0x02, 0xf0, 0xdf, 0xf8, 0x01, 0x98, 0xc0, 0x46, 0x00, 0x90, 
+0x02, 0xf0, 0xda, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xd7, 0xf8, 0x30, 0x1c, 
+0x02, 0xf0, 0xd4, 0xf8, 0x02, 0xf0, 0x5a, 0xf9, 0xff, 0xf7, 0xce, 0xff, 
+0x02, 0xf0, 0x6e, 0xf9, 0x54, 0x20, 0x02, 0xf0, 0xcb, 0xf8, 0x00, 0x98, 
+0x02, 0xf0, 0xc8, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xc5, 0xf8, 0x30, 0x1c, 
+0x14, 0xe0, 0x02, 0xf0, 0x61, 0xf9, 0x52, 0x20, 0x02, 0xf0, 0xbe, 0xf8, 
+0x01, 0x98, 0x02, 0xf0, 0xbb, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 0xb8, 0xf8, 
+0x30, 0x1c, 0x02, 0xf0, 0xb5, 0xf8, 0x00, 0x20, 0x02, 0xf0, 0xb2, 0xf8, 
+0x00, 0x20, 0x02, 0xf0, 0xaf, 0xf8, 0x00, 0x20, 0x02, 0xf0, 0xac, 0xf8, 
+0x00, 0x20, 0x02, 0xf0, 0xa9, 0xf8, 0x00, 0x2f, 0x05, 0xd9, 0x02, 0xf0, 
+0x1b, 0xf8, 0x20, 0x70, 0x01, 0x34, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 
+0x27, 0xf9, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 
+0x82, 0xb0, 0x14, 0x1c, 0x1f, 0x1c, 0x40, 0x02, 0x08, 0x43, 0x05, 0x1c, 
+0x02, 0xf0, 0x32, 0xf9, 0x53, 0x20, 0x02, 0xf0, 0x8f, 0xf8, 0x28, 0x0c, 
+0x06, 0x1c, 0x02, 0xf0, 0x8b, 0xf8, 0x28, 0x0a, 0x01, 0x90, 0x00, 0x90, 
+0x02, 0xf0, 0x86, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 
+0x83, 0xf8, 0x02, 0xf0, 0x09, 0xf9, 0xff, 0xf7, 0x7d, 0xff, 0x02, 0xf0, 
+0x1d, 0xf9, 0x84, 0x20, 0x02, 0xf0, 0x7a, 0xf8, 0x30, 0x1c, 0x02, 0xf0, 
+0x77, 0xf8, 0x00, 0x98, 0x02, 0xf0, 0x74, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 
+0x71, 0xf8, 0x00, 0x2f, 0x05, 0xd9, 0x20, 0x78, 0x01, 0x34, 0x02, 0xf0, 
+0x6b, 0xf8, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 0xef, 0xf8, 0x02, 0xf0, 
+0x05, 0xf9, 0x83, 0x20, 0x02, 0xf0, 0x62, 0xf8, 0x30, 0x1c, 0x02, 0xf0, 
+0x5f, 0xf8, 0x01, 0x98, 0x02, 0xf0, 0x5c, 0xf8, 0x28, 0x1c, 0x02, 0xf0, 
+0x59, 0xf8, 0x02, 0xf0, 0xdf, 0xf8, 0xff, 0xf7, 0x53, 0xff, 0x02, 0xb0, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 
+0x80, 0xb5, 0x01, 0xf0, 0x89, 0xf8, 0x06, 0x4f, 0xc0, 0x46, 0xf8, 0x60, 
+0x01, 0xf0, 0xe4, 0xf8, 0x78, 0x80, 0x01, 0xf0, 0xa5, 0xf8, 0x38, 0x71, 
+0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
+0x00, 0xb5, 0x01, 0xf0, 0xf7, 0xf8, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x80, 
+0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x0b, 0x48, 0xc1, 0x68, 
+0x01, 0x29, 0x11, 0xd1, 0x02, 0x22, 0xc1, 0x6f, 0x0a, 0x43, 0xc2, 0x67, 
+0x08, 0x49, 0xc0, 0x46, 0x0a, 0x60, 0x80, 0x23, 0xc2, 0x6f, 0x1a, 0x43, 
+0xc2, 0x67, 0x0a, 0x60, 0x82, 0x22, 0x80, 0x30, 0x02, 0x60, 0x4a, 0x60, 
+0x00, 0x21, 0x81, 0x80, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
+0x00, 0x01, 0x11, 0x00, 0xf0, 0xb4, 0x49, 0x49, 0xca, 0x1d, 0x99, 0x32, 
+0x00, 0x20, 0x00, 0x27, 0x83, 0x00, 0xd7, 0x50, 0x01, 0x30, 0x17, 0x28, 
+0xfa, 0xd3, 0x45, 0x4c, 0x00, 0x20, 0x82, 0x00, 0xa7, 0x50, 0x01, 0x30, 
+0x20, 0x28, 0xfa, 0xd3, 0x42, 0x4a, 0x00, 0x20, 0x83, 0x00, 0xd7, 0x50, 
+0x01, 0x30, 0x20, 0x28, 0xfa, 0xd3, 0xa7, 0x61, 0x97, 0x61, 0x4f, 0x65, 
+0x8f, 0x65, 0x3e, 0x4d, 0xc0, 0x46, 0x2f, 0x60, 0x6f, 0x60, 0xaf, 0x60, 
+0xaf, 0x61, 0xef, 0x60, 0x2f, 0x61, 0x6f, 0x61, 0x00, 0x20, 0xc1, 0x00, 
+0x09, 0x18, 0x49, 0x01, 0x34, 0x4b, 0xc9, 0x18, 0x86, 0x00, 0xcb, 0x1d, 
+0xf5, 0x33, 0x33, 0x4c, 0x34, 0x19, 0xe3, 0x63, 0x87, 0x23, 0x9b, 0x00, 
+0xcb, 0x18, 0x63, 0x63, 0xcf, 0x23, 0x9b, 0x00, 0xcb, 0x18, 0xb4, 0x18, 
+0xe3, 0x63, 0x30, 0x4b, 0xc9, 0x18, 0x61, 0x63, 0x01, 0x30, 0x02, 0x28, 
+0xe5, 0xdb, 0x29, 0x48, 0xc1, 0x1d, 0xf5, 0x31, 0x28, 0x4c, 0xc0, 0x46, 
+0xa1, 0x62, 0x61, 0x6b, 0xcf, 0x23, 0x9b, 0x00, 0xe1, 0x62, 0xc1, 0x18, 
+0x91, 0x62, 0x51, 0x6b, 0xc0, 0x46, 0xd1, 0x62, 0x08, 0x21, 0xe1, 0x64, 
+0x25, 0x49, 0xc0, 0x46, 0x21, 0x65, 0x25, 0x49, 0x0b, 0x69, 0xc0, 0x46, 
+0x63, 0x65, 0xc3, 0x1d, 0x4d, 0x33, 0xe3, 0x65, 0x25, 0x66, 0x8b, 0x68, 
+0xc0, 0x46, 0x63, 0x66, 0xcb, 0x68, 0xc0, 0x46, 0xa3, 0x66, 0x1f, 0x4b, 
+0xc0, 0x46, 0xe3, 0x66, 0x27, 0x67, 0x67, 0x67, 0x1d, 0x4b, 0xc3, 0x18, 
+0x01, 0x26, 0xa3, 0x67, 0x66, 0x61, 0xe7, 0x61, 0xe3, 0x1d, 0x69, 0x33, 
+0x1f, 0x73, 0x02, 0x23, 0xd3, 0x64, 0x19, 0x4b, 0xc0, 0x46, 0x13, 0x65, 
+0xcb, 0x69, 0xc0, 0x46, 0x53, 0x65, 0xc3, 0x1d, 0x51, 0x33, 0xd3, 0x65, 
+0x2b, 0x1d, 0x13, 0x66, 0x4b, 0x69, 0xc0, 0x46, 0x53, 0x66, 0x89, 0x69, 
+0xc0, 0x46, 0x91, 0x66, 0x11, 0x49, 0xc0, 0x46, 0xd1, 0x66, 0x16, 0x67, 
+0x56, 0x67, 0x10, 0x4b, 0xc0, 0x18, 0x90, 0x67, 0x56, 0x61, 0xd7, 0x61, 
+0xd0, 0x1d, 0x69, 0x30, 0x07, 0x73, 0xf0, 0xbc, 
+0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x50, 0x2c, 0x00, 0x80, 
+0xd0, 0x2c, 0x00, 0x80, 0x3c, 0xef, 0x20, 0x40, 0x5c, 0x04, 0x00, 0x00, 
+0x30, 0x01, 0x18, 0x00, 0xf8, 0x28, 0x00, 0x80, 0x80, 0x54, 0xff, 0xff, 
+0x7c, 0x05, 0x00, 0x00, 0x38, 0x01, 0x18, 0x00, 0x90, 0x54, 0xff, 0xff, 
+0x7c, 0x07, 0x00, 0x00, 0x90, 0xb4, 0x00, 0x21, 0x1c, 0x4a, 0xbb, 0x23, 
+0x1b, 0x01, 0xd7, 0x18, 0xf9, 0x72, 0x19, 0x23, 0xdb, 0x01, 0xd0, 0x18, 
+0x33, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x81, 0x61, 0x59, 0x60, 0xb9, 0x72, 
+0x01, 0x27, 0x1f, 0x73, 0x19, 0x61, 0x17, 0x23, 0xdb, 0x01, 0xd3, 0x18, 
+0xd9, 0x63, 0x13, 0x4b, 0x51, 0x27, 0xbf, 0x03, 0xc3, 0x62, 0x3b, 0x60, 
+0x44, 0x69, 0xe4, 0x18, 0x04, 0x63, 0x04, 0x3c, 0x7c, 0x60, 0x01, 0x24, 
+0xe4, 0x02, 0x44, 0x63, 0x0d, 0x4c, 0xc0, 0x46, 0xbc, 0x60, 0xc4, 0x6a, 
+0xc0, 0x46, 0x04, 0x62, 0x44, 0x69, 0xe4, 0x18, 0x0a, 0x4b, 0xe3, 0x18, 
+0xfb, 0x60, 0xc3, 0x6a, 0xc0, 0x46, 0x43, 0x62, 0x03, 0x6a, 0xc0, 0x46, 
+0xc3, 0x61, 0x81, 0x63, 0x51, 0x64, 0x91, 0x64, 0xd1, 0x65, 0xd1, 0x66, 
+0x90, 0xbc, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, 
+0xfc, 0x07, 0x00, 0x00, 0xfc, 0xf7, 0xff, 0xff, 0x90, 0xb4, 0x00, 0x22, 
+0x1c, 0x49, 0xc9, 0x23, 0x1b, 0x01, 0xc8, 0x18, 0x02, 0x70, 0x01, 0x20, 
+0xbb, 0x23, 0x1b, 0x01, 0xcb, 0x18, 0x58, 0x72, 0x18, 0x48, 0x03, 0x1c, 
+0x00, 0x27, 0xdc, 0x1d, 0xc1, 0x34, 0x1c, 0x65, 0x23, 0x1c, 0x01, 0x37, 
+0x3f, 0x2f, 0xf8, 0xd3, 0x1a, 0x65, 0x19, 0x23, 0xdb, 0x01, 0xcf, 0x18, 
+0x33, 0x23, 0x9b, 0x01, 0xcc, 0x18, 0xfa, 0x60, 0x60, 0x61, 0x40, 0x20, 
+0xb8, 0x60, 0xa2, 0x61, 0xe2, 0x61, 0xca, 0x64, 0x0a, 0x66, 0x0d, 0x48, 
+0xc0, 0x46, 0xc2, 0x60, 0x0c, 0x48, 0x00, 0x6b, 0xc0, 0x06, 0xc0, 0x0e, 
+0xb8, 0x63, 0x0b, 0x48, 0x65, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x02, 0x68, 
+0xc0, 0x46, 0x8a, 0x83, 0x42, 0x68, 0xc0, 0x46, 0xca, 0x83, 0x80, 0x68, 
+0xc0, 0x46, 0x20, 0x80, 0x90, 0xbc, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
+0x3c, 0xbd, 0x20, 0x40, 0x3c, 0xef, 0x20, 0x40, 0x80, 0x00, 0x14, 0x40, 
+0x40, 0x00, 0x14, 0x40, 0x00, 0x20, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x73, 
+0xcb, 0x1d, 0xff, 0x33, 0x3a, 0x33, 0x88, 0x61, 0xc8, 0x61, 0x18, 0x70, 
+0x06, 0x4a, 0xc0, 0x46, 0x10, 0x65, 0x50, 0x66, 0x90, 0x66, 0x08, 0x70, 
+0x58, 0x70, 0xbb, 0x23, 0x1b, 0x01, 0xd1, 0x18, 0x08, 0x72, 0x70, 0x47, 
+0xa8, 0x04, 0x00, 0x80, 0xe8, 0x0d, 0x00, 0x80, 0xf0, 0xb4, 0x2f, 0x49, 
+0x2f, 0x4a, 0xc0, 0x46, 0x11, 0x61, 0x01, 0x23, 0x9b, 0x02, 0xc8, 0x18, 
+0x50, 0x61, 0x2d, 0x48, 0xc0, 0x46, 0x10, 0x62, 0xdb, 0x00, 0xc3, 0x18, 
+0x53, 0x62, 0x00, 0x23, 0x13, 0x63, 0x53, 0x63, 0x29, 0x4a, 0x2a, 0x4f, 
+0xd4, 0x1d, 0xff, 0x34, 0xfa, 0x34, 0x14, 0xc7, 0x08, 0x3f, 0x3b, 0x61, 
+0x1c, 0x1f, 0x7c, 0x61, 0x26, 0x4f, 0xc0, 0x46, 0x39, 0x60, 0xb8, 0x61, 
+0x79, 0x61, 0xf8, 0x62, 0x3b, 0x63, 0x7b, 0x64, 0xba, 0x64, 0xfa, 0x65, 
+0x22, 0x4f, 0xfe, 0x1d, 0xf9, 0x36, 0x22, 0x4d, 0xec, 0x1d, 0x79, 0x34, 
+0xe6, 0x61, 0x51, 0x26, 0xb6, 0x03, 0x37, 0x61, 0xe4, 0x69, 0xc0, 0x46, 
+0x74, 0x61, 0x2f, 0x67, 0x1d, 0x4d, 0x09, 0x27, 0x7f, 0x04, 0xec, 0x1d, 
+0x75, 0x34, 0x7c, 0x60, 0x3d, 0x60, 0x1b, 0x4c, 0xc0, 0x46, 0x3c, 0x61, 
+0xe6, 0x1d, 0x75, 0x36, 0x7e, 0x61, 0x19, 0x4f, 
+0xc0, 0x46, 0x7c, 0x60, 0x3d, 0x60, 0x0f, 0x1c, 0x00, 0x21, 0xff, 0x24, 
+0x01, 0x34, 0x1d, 0x1c, 0x8b, 0x00, 0xfd, 0x50, 0x01, 0x31, 0xa1, 0x42, 
+0xfa, 0xd3, 0x01, 0x1c, 0x00, 0x20, 0x01, 0x27, 0xff, 0x02, 0x83, 0x00, 
+0xcd, 0x50, 0x01, 0x30, 0xb8, 0x42, 0xfa, 0xd3, 0x00, 0x20, 0x81, 0x00, 
+0x55, 0x50, 0x01, 0x30, 0x80, 0x28, 0xfa, 0xd3, 0xf0, 0xbc, 0x70, 0x47, 
+0x24, 0xa3, 0x20, 0x40, 0x40, 0x01, 0x18, 0x00, 0x24, 0x83, 0x20, 0x40, 
+0x24, 0xa9, 0x20, 0x40, 0x80, 0x01, 0x18, 0x00, 0x28, 0x03, 0x00, 0x80, 
+0x24, 0xa7, 0x20, 0x40, 0xe8, 0x0d, 0x00, 0x80, 0x24, 0xa8, 0x20, 0x40, 
+0xa4, 0xa8, 0x20, 0x40, 0x88, 0x03, 0x00, 0x80, 0xb8, 0xb5, 0x2d, 0x48, 
+0xfd, 0xf7, 0xc6, 0xfa, 0x01, 0x20, 0x2c, 0x49, 0x0a, 0x68, 0x52, 0x0c, 
+0x06, 0xd2, 0x0a, 0x68, 0x12, 0x0c, 0x02, 0xd1, 0x0a, 0x68, 0x92, 0x0a, 
+0x00, 0xd2, 0x00, 0x20, 0x04, 0x06, 0x24, 0x0e, 0x26, 0x4a, 0xd7, 0x1d, 
+0x0d, 0x37, 0x00, 0x23, 0x00, 0x20, 0x9d, 0x00, 0x78, 0x51, 0x01, 0x33, 
+0x04, 0x2b, 0xfa, 0xd3, 0x01, 0x27, 0x3f, 0x05, 0x50, 0x61, 0xf8, 0x60, 
+0xd0, 0x61, 0xf8, 0x61, 0x00, 0x23, 0xdb, 0x43, 0x93, 0x61, 0x3b, 0x61, 
+0x13, 0x62, 0x3b, 0x62, 0x00, 0x27, 0x1c, 0x4b, 0x8d, 0x68, 0xc0, 0x46, 
+0x00, 0x95, 0x8d, 0x69, 0xc0, 0x46, 0x00, 0x95, 0x00, 0x2c, 0x0b, 0xd0, 
+0xdd, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x9d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 
+0x5d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x1d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 
+0x01, 0x37, 0x40, 0x2f, 0xe8, 0xd3, 0x00, 0x27, 0x6c, 0x46, 0x01, 0x23, 
+0x5b, 0x07, 0x1c, 0x43, 0x01, 0xe0, 0x20, 0x60, 0x01, 0x37, 0x0d, 0x68, 
+0x2b, 0x09, 0x02, 0xd2, 0x80, 0x2f, 0xf8, 0xd3, 0x01, 0xe0, 0x80, 0x2f, 
+0x03, 0xd3, 0x09, 0x49, 0x4b, 0x6e, 0x01, 0x33, 0x4b, 0x66, 0xd0, 0x62, 
+0x07, 0x48, 0xfd, 0xf7, 0x71, 0xfa, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0xf4, 0x01, 0xff, 0xff, 0x00, 0x00, 0x10, 0x40, 0xe8, 0x0d, 0x00, 0x80, 
+0x00, 0x01, 0x18, 0x40, 0xa0, 0x82, 0x20, 0x40, 0x04, 0x02, 0xff, 0xff, 
+0x90, 0xb4, 0x00, 0x21, 0x0e, 0x4f, 0x0f, 0x4a, 0x00, 0x20, 0x4c, 0x01, 
+0x64, 0x1a, 0xa4, 0x00, 0xa3, 0x18, 0x58, 0x60, 0x98, 0x60, 0x18, 0x64, 
+0x58, 0x64, 0x10, 0x53, 0x58, 0x80, 0xcc, 0x00, 0xe4, 0x19, 0x98, 0x67, 
+0xdc, 0x62, 0x01, 0x31, 0x03, 0x29, 0xee, 0xd3, 0x06, 0x49, 0xc0, 0x46, 
+0x08, 0x60, 0x48, 0x60, 0x88, 0x60, 0xc8, 0x60, 0x08, 0x61, 0x90, 0xbc, 
+0x70, 0x47, 0x00, 0x00, 0x58, 0x67, 0x21, 0x40, 0xc8, 0x2a, 0x00, 0x80, 
+0x3c, 0x2c, 0x00, 0x80, 0x00, 0xb5, 0x64, 0x21, 0x07, 0x48, 0xc0, 0x46, 
+0x01, 0x63, 0x00, 0x21, 0xc9, 0x43, 0x41, 0x63, 0x81, 0x63, 0x00, 0x21, 
+0xc1, 0x63, 0x01, 0x64, 0x03, 0x48, 0x28, 0x22, 0x02, 0xf0, 0x06, 0xff, 
+0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x59, 0x03, 0xff, 0xff, 
+0x80, 0xb4, 0x01, 0x20, 0x40, 0x02, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x60, 
+0x3c, 0x20, 0x48, 0x60, 0x88, 0x60, 0x08, 0x48, 0xc0, 0x46, 0xc8, 0x60, 
+0x00, 0x20, 0x07, 0x4a, 0x87, 0x00, 0xcb, 0x68, 0xc0, 0x46, 0xda, 0x51, 
+0x01, 0x30, 0x10, 0x28, 0xf8, 0xd3, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, 
+0x50, 0x2d, 0x00, 0x80, 0x60, 0x2d, 0x00, 0x80, 0xd5, 0x4b, 0xff, 0xff, 
+0x12, 0x49, 0x13, 0x48, 0x67, 0x23, 0x9b, 0x01, 0xca, 0x18, 0x06, 0xc0, 
+0x08, 0x38, 0x11, 0x4b, 0xca, 0x18, 0xc1, 0x60, 
+0x82, 0x60, 0x01, 0x61, 0x0f, 0x49, 0x10, 0x48, 0xa7, 0x23, 0x9b, 0x01, 
+0xca, 0x18, 0x06, 0xc0, 0x08, 0x38, 0x0e, 0x4b, 0xca, 0x18, 0xc1, 0x60, 
+0x82, 0x60, 0x01, 0x61, 0x0c, 0x48, 0x0d, 0x49, 0x67, 0x23, 0x9b, 0x01, 
+0xc2, 0x18, 0x05, 0xc1, 0x08, 0x39, 0x05, 0x4b, 0xc2, 0x18, 0xc8, 0x60, 
+0x8a, 0x60, 0x08, 0x61, 0x70, 0x47, 0x00, 0x00, 0x58, 0x1f, 0x21, 0x40, 
+0xb4, 0x2d, 0x00, 0x80, 0xfc, 0x1f, 0x00, 0x00, 0x58, 0xef, 0x20, 0x40, 
+0xa0, 0x2d, 0x00, 0x80, 0xfc, 0x2f, 0x00, 0x00, 0x58, 0x3f, 0x21, 0x40, 
+0xc8, 0x2d, 0x00, 0x80, 0x90, 0xb4, 0x00, 0x21, 0x40, 0x4c, 0x00, 0x20, 
+0x0a, 0x01, 0x12, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xd2, 0x18, 0xd0, 0x62, 
+0x10, 0x63, 0x50, 0x63, 0x90, 0x63, 0x01, 0x31, 0x03, 0x29, 0xf3, 0xd3, 
+0x3a, 0x49, 0xc0, 0x46, 0xc8, 0x62, 0x08, 0x63, 0x48, 0x63, 0x20, 0x60, 
+0x01, 0x21, 0xe3, 0x1d, 0x59, 0x33, 0x60, 0x60, 0x19, 0x71, 0x18, 0x72, 
+0x98, 0x71, 0x98, 0x72, 0x59, 0x71, 0x58, 0x72, 0xd8, 0x71, 0xd8, 0x72, 
+0xe2, 0x1d, 0x49, 0x32, 0x11, 0x73, 0x19, 0x70, 0x90, 0x73, 0x98, 0x70, 
+0x51, 0x73, 0x59, 0x70, 0xd0, 0x73, 0xd8, 0x70, 0x11, 0x71, 0x11, 0x72, 
+0x90, 0x71, 0x90, 0x72, 0x50, 0x71, 0x50, 0x72, 0xd0, 0x71, 0xd0, 0x72, 
+0x18, 0x73, 0x02, 0x22, 0xe7, 0x1d, 0x69, 0x37, 0x3a, 0x70, 0x99, 0x73, 
+0xba, 0x70, 0x58, 0x73, 0x78, 0x70, 0xd8, 0x73, 0xf8, 0x70, 0x39, 0x71, 
+0x3a, 0x72, 0xb9, 0x71, 0xb9, 0x72, 0x78, 0x71, 0x7a, 0x72, 0xf9, 0x71, 
+0xf9, 0x72, 0x39, 0x73, 0xe3, 0x1d, 0x79, 0x33, 0x1a, 0x70, 0xb9, 0x73, 
+0x99, 0x70, 0x78, 0x73, 0x5a, 0x70, 0xf9, 0x73, 0xd9, 0x70, 0x1a, 0x71, 
+0x1a, 0x72, 0x99, 0x71, 0x9a, 0x72, 0x58, 0x71, 0x5a, 0x72, 0xd9, 0x71, 
+0xda, 0x72, 0x19, 0x73, 0xe7, 0x1d, 0x89, 0x37, 0x3a, 0x70, 0x99, 0x73, 
+0xb9, 0x70, 0x58, 0x73, 0x7a, 0x70, 0xd9, 0x73, 0xf9, 0x70, 0x39, 0x71, 
+0x3a, 0x72, 0xb9, 0x71, 0xb9, 0x72, 0x78, 0x71, 0x7a, 0x72, 0xf9, 0x71, 
+0xf9, 0x72, 0x3a, 0x73, 0xe3, 0x1d, 0x99, 0x33, 0x1a, 0x70, 0xb9, 0x73, 
+0x9a, 0x70, 0x78, 0x73, 0x5a, 0x70, 0xf9, 0x73, 0xda, 0x70, 0x19, 0x71, 
+0x1a, 0x72, 0x99, 0x71, 0x99, 0x72, 0x58, 0x71, 0x5a, 0x72, 0xd9, 0x71, 
+0xd9, 0x72, 0x20, 0x61, 0xe0, 0x60, 0x60, 0x61, 0xa0, 0x60, 0x90, 0xbc, 
+0x70, 0x47, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x80, 0x68, 0x19, 0x00, 0x80, 
+0x81, 0x20, 0x00, 0x02, 0x01, 0x49, 0xc0, 0x46, 0x88, 0x62, 0x70, 0x47, 
+0xc0, 0x00, 0x14, 0x00, 0x0a, 0x49, 0x13, 0x23, 0xdb, 0x01, 0xc8, 0x18, 
+0x25, 0x23, 0x9b, 0x01, 0xc9, 0x18, 0xc8, 0x63, 0x00, 0x21, 0xc2, 0x1d, 
+0x29, 0x32, 0xc2, 0x61, 0x10, 0x1c, 0x01, 0x31, 0x08, 0x29, 0xf8, 0xd3, 
+0xc1, 0x1f, 0x29, 0x39, 0x00, 0x20, 0xc8, 0x61, 0x70, 0x47, 0x00, 0x00, 
+0xe8, 0x0d, 0x00, 0x80, 0x06, 0x48, 0x07, 0x49, 0xc0, 0x46, 0x08, 0x80, 
+0x48, 0x80, 0x00, 0x20, 0x88, 0x80, 0xc8, 0x80, 0x88, 0x60, 0x04, 0x49, 
+0xc0, 0x46, 0x48, 0x61, 0x88, 0x61, 0x70, 0x47, 0xff, 0xff, 0x00, 0x00, 
+0xc8, 0x29, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x00, 0x21, 0x06, 0x48, 
+0xc2, 0x1d, 0x19, 0x32, 0xc1, 0x60, 0x01, 0x61, 0xc1, 0x61, 0x01, 0x62, 
+0x11, 0x71, 0xff, 0x30, 0x01, 0x30, 0x41, 0x62, 0x70, 0x47, 0x00, 0x00, 
+0xec, 0x05, 0x00, 0x80, 0x09, 0x48, 0x0a, 0x4b, 0xc0, 0x46, 0x18, 0x60, 
+0x00, 0x21, 0xc2, 0x1d, 0x4d, 0x32, 0xc2, 0x60, 
+0x10, 0x1c, 0x01, 0x31, 0x14, 0x29, 0xf8, 0xd3, 0xc1, 0x1f, 0x4d, 0x39, 
+0x00, 0x20, 0xc8, 0x60, 0x58, 0x60, 0x98, 0x60, 0x70, 0x47, 0x00, 0x00, 
+0x58, 0x07, 0x00, 0x80, 0xec, 0x05, 0x00, 0x80, 0x00, 0xb5, 0x0c, 0x49, 
+0x0c, 0x48, 0xfd, 0xf7, 0xea, 0xf8, 0x0c, 0x48, 0x00, 0x6a, 0x01, 0x23, 
+0xdb, 0x03, 0x98, 0x43, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x62, 0x0a, 0x48, 
+0xc1, 0x68, 0x01, 0x29, 0x06, 0xd1, 0x80, 0x23, 0xc1, 0x6f, 0x19, 0x43, 
+0xc1, 0x67, 0x07, 0x48, 0xc0, 0x46, 0x01, 0x60, 0x08, 0xbc, 0x18, 0x47, 
+0x59, 0xcd, 0x21, 0x40, 0x61, 0xa1, 0x21, 0x40, 0xc0, 0x00, 0x18, 0x40, 
+0xc0, 0x00, 0x18, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x01, 0x11, 0x00, 
+0x00, 0xb5, 0x10, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x06, 0xd1, 0x80, 0x23, 
+0xc1, 0x6f, 0x99, 0x43, 0xc1, 0x67, 0x0d, 0x48, 0xc0, 0x46, 0x01, 0x60, 
+0x0c, 0x4b, 0x0d, 0x48, 0x0d, 0x4a, 0x00, 0x21, 0xfd, 0xf7, 0xb9, 0xf8, 
+0x0c, 0x48, 0x41, 0x8d, 0x01, 0x31, 0x41, 0x85, 0x00, 0x21, 0xc1, 0x85, 
+0x0a, 0x48, 0x00, 0x6a, 0x01, 0x23, 0xdb, 0x03, 0x18, 0x43, 0x09, 0x49, 
+0xc0, 0x46, 0x08, 0x62, 0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 
+0x00, 0x01, 0x11, 0x00, 0xf1, 0xcc, 0x21, 0x40, 0x61, 0xa1, 0x21, 0x40, 
+0xb8, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x40, 
+0xc0, 0x00, 0x18, 0x00, 0xf0, 0xb5, 0xfe, 0xf7, 0xa3, 0xfe, 0x19, 0x4c, 
+0x10, 0x26, 0xe0, 0x68, 0x01, 0x28, 0x05, 0xd1, 0x60, 0x88, 0x00, 0x28, 
+0x02, 0xd1, 0x19, 0x20, 0xa0, 0x67, 0x00, 0xe0, 0xa6, 0x67, 0x00, 0x20, 
+0x07, 0x23, 0x5b, 0x02, 0xe5, 0x18, 0xc1, 0x43, 0xa8, 0x61, 0x29, 0x62, 
+0x59, 0x08, 0xa1, 0x27, 0x7f, 0x03, 0x79, 0x60, 0x0f, 0x21, 0x79, 0x60, 
+0xe1, 0x1d, 0xb9, 0x31, 0x08, 0x70, 0x01, 0x20, 0xb8, 0x60, 0x40, 0x02, 
+0xb8, 0x60, 0x00, 0xf0, 0x47, 0xfa, 0x00, 0xf0, 0xd9, 0xfa, 0x04, 0x20, 
+0xb8, 0x60, 0x07, 0x20, 0x78, 0x61, 0x7e, 0x60, 0x1b, 0x23, 0xdb, 0x01, 
+0xe0, 0x18, 0x40, 0x8b, 0x04, 0x23, 0x18, 0x40, 0xa8, 0x62, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x80, 0xb4, 0x02, 0x1c, 
+0x00, 0x20, 0xff, 0x23, 0x01, 0x33, 0x9a, 0x42, 0x08, 0xd0, 0x01, 0x29, 
+0x00, 0xd1, 0x01, 0x20, 0x00, 0x2a, 0x01, 0xd1, 0x02, 0x23, 0x18, 0x43, 
+0x80, 0xbc, 0x70, 0x47, 0x18, 0x49, 0xca, 0x68, 0x18, 0x4b, 0x01, 0x2a, 
+0x0b, 0xd1, 0x4a, 0x88, 0x00, 0x2a, 0x08, 0xd1, 0xd9, 0x8a, 0x0a, 0x09, 
+0x00, 0xd3, 0x02, 0x20, 0x49, 0x09, 0xef, 0xd3, 0x01, 0x23, 0x18, 0x43, 
+0xec, 0xe7, 0x0a, 0x79, 0x00, 0x2a, 0x03, 0xd0, 0x18, 0x8a, 0x80, 0x07, 
+0x80, 0x0f, 0xe5, 0xe7, 0x6d, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x0a, 0x88, 
+0xff, 0x27, 0x01, 0x37, 0x17, 0x40, 0x0b, 0x49, 0x49, 0x88, 0x03, 0xd0, 
+0x4b, 0x0a, 0x01, 0xd3, 0x03, 0x20, 0xd7, 0xe7, 0x13, 0x0a, 0x03, 0xd3, 
+0x0b, 0x0a, 0x01, 0xd3, 0x02, 0x20, 0xd1, 0xe7, 0xd2, 0x09, 0xcf, 0xd3, 
+0xc9, 0x09, 0xcd, 0xd3, 0x01, 0x20, 0xcb, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 
+0xa8, 0x1b, 0x00, 0x80, 0x88, 0x1b, 0x00, 0x80, 0xf0, 0xb5, 0xc1, 0xb0, 
+0x01, 0x20, 0x00, 0x07, 0x52, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x52, 0x48, 
+0x42, 0x69, 0x40, 0x0d, 0xa1, 0x21, 0x49, 0x03, 0x48, 0x60, 0x50, 0x48, 
+0xc0, 0x6a, 0x50, 0x4b, 0x18, 0x43, 0x00, 0x21, 0x03, 0x03, 0x1b, 0x0b, 
+0x4e, 0x4c, 0x27, 0x6f, 0x3d, 0x03, 0x2d, 0x0b, 
+0xe7, 0x1d, 0x79, 0x37, 0xab, 0x42, 0x1c, 0xd0, 0xe3, 0x1d, 0x79, 0x33, 
+0xdb, 0x69, 0xc0, 0x46, 0x40, 0x93, 0x01, 0x23, 0x9b, 0x07, 0x03, 0x43, 
+0x1b, 0x68, 0xcc, 0x00, 0x6e, 0x46, 0x33, 0x51, 0x01, 0x23, 0x9b, 0x07, 
+0x06, 0x1d, 0x33, 0x43, 0x1b, 0x68, 0x6c, 0x44, 0x63, 0x60, 0x08, 0x30, 
+0x01, 0x31, 0x40, 0x9b, 0x83, 0x42, 0x00, 0xd8, 0x3f, 0x48, 0x03, 0x03, 
+0x1b, 0x0b, 0xab, 0x42, 0xe7, 0xd1, 0x00, 0x20, 0x01, 0x23, 0x1b, 0x03, 
+0x13, 0x40, 0x3c, 0x4c, 0x03, 0xd0, 0x63, 0x6a, 0x01, 0x33, 0x63, 0x62, 
+0x09, 0xe0, 0x13, 0x0b, 0x03, 0xd3, 0x23, 0x6a, 0x01, 0x33, 0x23, 0x62, 
+0x03, 0xe0, 0x37, 0x4b, 0x5c, 0x6d, 0x01, 0x34, 0x5c, 0x65, 0x00, 0x29, 
+0x09, 0xd0, 0x03, 0x1c, 0xdc, 0x00, 0x23, 0x1c, 0x6b, 0x44, 0x5c, 0x68, 
+0x01, 0x30, 0x23, 0x0d, 0x01, 0xd2, 0x88, 0x42, 0xf5, 0xd1, 0x30, 0x4c, 
+0x25, 0x68, 0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, 0x1b, 0x0c, 0x08, 0xd1, 
+0x24, 0x68, 0xa3, 0x0a, 0x05, 0xd3, 0x20, 0x24, 0x2b, 0x4b, 0xc0, 0x46, 
+0x5c, 0x62, 0x00, 0x24, 0x5c, 0x62, 0x25, 0x4b, 0x23, 0x4c, 0x51, 0x26, 
+0xb6, 0x03, 0x23, 0x67, 0x33, 0x61, 0xfd, 0x69, 0xc0, 0x46, 0x75, 0x61, 
+0x02, 0x25, 0xa1, 0x26, 0x76, 0x03, 0x75, 0x60, 0x01, 0x25, 0xb5, 0x60, 
+0xe6, 0x1d, 0xb9, 0x36, 0x35, 0x70, 0x88, 0x42, 0x21, 0xd0, 0x25, 0x1c, 
+0xc3, 0x00, 0x6c, 0x46, 0xe4, 0x58, 0x2e, 0x6f, 0x6b, 0x44, 0x34, 0x60, 
+0x5b, 0x68, 0x2c, 0x6f, 0xc0, 0x46, 0x63, 0x60, 0x2b, 0x6f, 0x08, 0x33, 
+0x2b, 0x67, 0xfc, 0x69, 0xa3, 0x42, 0x02, 0xd3, 0x12, 0x4b, 0xc0, 0x46, 
+0x2b, 0x67, 0x03, 0x1c, 0xdb, 0x00, 0x6b, 0x44, 0x5c, 0x68, 0x01, 0x30, 
+0x23, 0x0d, 0x04, 0xd3, 0x51, 0x24, 0xa4, 0x03, 0x2b, 0x6f, 0xc0, 0x46, 
+0xa3, 0x61, 0x88, 0x42, 0xde, 0xd1, 0x10, 0x0b, 0x03, 0xd3, 0x0e, 0x49, 
+0x01, 0x20, 0xfc, 0xf7, 0x72, 0xff, 0x41, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x01, 0x14, 0x40, 
+0x00, 0x40, 0x14, 0x40, 0x00, 0x00, 0x20, 0x40, 0xe8, 0x0d, 0x00, 0x80, 
+0x24, 0xa7, 0x20, 0x40, 0x10, 0x2a, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 
+0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x49, 0x4f, 0xff, 0xff, 
+0xf0, 0xb4, 0x00, 0x21, 0x00, 0x23, 0x07, 0x22, 0x06, 0x24, 0x47, 0x4f, 
+0xc0, 0x46, 0x3c, 0x61, 0x3a, 0x61, 0x01, 0x33, 0x20, 0x2b, 0xf9, 0xd3, 
+0x04, 0x25, 0x3d, 0x61, 0x05, 0x23, 0x3b, 0x61, 0x3c, 0x61, 0x3a, 0x61, 
+0x3c, 0x61, 0x3a, 0x61, 0x3d, 0x61, 0x3b, 0x61, 0x3f, 0x4d, 0xab, 0x6f, 
+0xde, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, 
+0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x9e, 0x08, 0x02, 0x23, 
+0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 
+0x3b, 0x61, 0xab, 0x6f, 0x5e, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, 
+0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x02, 0x23, 
+0xae, 0x6f, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 
+0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x5d, 0x00, 0x02, 0x23, 0x1d, 0x40, 
+0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 
+0xc5, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 
+0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x85, 0x08, 0x02, 0x23, 0x1d, 0x40, 
+0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 
+0x2b, 0x43, 0x3b, 0x61, 0x45, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 
+0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x02, 0x25, 
+0x05, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 
+0x3b, 0x61, 0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x04, 0x23, 0x03, 0x43, 
+0x3b, 0x61, 0x05, 0x23, 0x18, 0x43, 0x38, 0x61, 0x00, 0x25, 0x3d, 0x61, 
+0x01, 0x23, 0x3b, 0x61, 0x3d, 0x61, 0x3b, 0x61, 0x00, 0x20, 0x3d, 0x61, 
+0x0d, 0x4b, 0x1b, 0x69, 0x49, 0x00, 0x1e, 0x1c, 0x02, 0x23, 0x33, 0x40, 
+0x19, 0x43, 0x01, 0x23, 0x3b, 0x61, 0x01, 0x30, 0x10, 0x28, 0xf2, 0xd3, 
+0x02, 0x20, 0x38, 0x61, 0x03, 0x20, 0x38, 0x61, 0x3c, 0x61, 0x3a, 0x61, 
+0x3c, 0x61, 0x3a, 0x61, 0x38, 0x61, 0x48, 0x08, 0xf0, 0xbc, 0x70, 0x47, 
+0x80, 0x00, 0x14, 0x00, 0xe8, 0x0d, 0x00, 0x80, 0x80, 0x00, 0x14, 0x40, 
+0xf0, 0xb4, 0x00, 0x24, 0x07, 0x23, 0x06, 0x27, 0x44, 0x4a, 0xc0, 0x46, 
+0x17, 0x61, 0x13, 0x61, 0x01, 0x34, 0x20, 0x2c, 0xf9, 0xd3, 0x04, 0x26, 
+0x16, 0x61, 0x05, 0x24, 0x14, 0x61, 0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 
+0x16, 0x61, 0x14, 0x61, 0x17, 0x61, 0x13, 0x61, 0x3c, 0x4b, 0x9b, 0x6f, 
+0xdd, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 
+0x25, 0x43, 0x15, 0x61, 0x37, 0x4b, 0x9b, 0x6f, 0x9d, 0x08, 0x02, 0x23, 
+0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 
+0x32, 0x4b, 0x9b, 0x6f, 0x5d, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 
+0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x2d, 0x4b, 0x9d, 0x6f, 
+0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 
+0x15, 0x61, 0x29, 0x4b, 0x9b, 0x6f, 0x5d, 0x00, 0x02, 0x23, 0x1d, 0x40, 
+0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0xc5, 0x08, 
+0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 
+0x15, 0x61, 0x85, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 
+0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x45, 0x08, 0x02, 0x23, 0x1d, 0x40, 
+0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x02, 0x25, 
+0x05, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 
+0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x03, 0x1c, 0x33, 0x43, 0x13, 0x61, 
+0x20, 0x43, 0x10, 0x61, 0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 0x16, 0x61, 
+0x14, 0x61, 0x4c, 0x00, 0x00, 0x20, 0x0f, 0x21, 0x25, 0x1c, 0xcd, 0x40, 
+0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x13, 0x61, 0x05, 0x23, 
+0x2b, 0x43, 0x13, 0x61, 0x01, 0x30, 0x01, 0x39, 0x10, 0x28, 0xf1, 0xd3, 
+0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 0x17, 0x61, 0x13, 0x61, 0x03, 0x20, 
+0x10, 0x61, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x00, 
+0xe8, 0x0d, 0x00, 0x80, 0xf0, 0xb5, 0x47, 0x48, 0x01, 0x89, 0x47, 0x4d, 
+0x07, 0x23, 0x5b, 0x02, 0xef, 0x18, 0xb9, 0x83, 0x40, 0x8b, 0xc0, 0x46, 
+0xf8, 0x83, 0x28, 0x79, 0x00, 0x28, 0x01, 0xd0, 0x00, 0x20, 0xb8, 0x83, 
+0xe8, 0x68, 0x01, 0x28, 0x06, 0xd1, 0x68, 0x88, 0x00, 0x28, 0x03, 0xd1, 
+0xf9, 0x21, 0x12, 0x20, 0xff, 0xf7, 0x54, 0xff, 0x01, 0x21, 0xc9, 0x03, 
+0x00, 0x20, 0xff, 0xf7, 0x4f, 0xff, 0x00, 0x24, 0x7d, 0x26, 0xf6, 0x00, 
+0x00, 0xe0, 0x01, 0x34, 0x00, 0x20, 0xff, 0xf7, 0xad, 0xfe, 0x00, 0x0c, 
+0x01, 0xd3, 0xb4, 0x42, 0xf7, 0xd3, 0x00, 0x24, 
+0x05, 0xe0, 0x03, 0x21, 0x09, 0x03, 0x00, 0x20, 0xff, 0xf7, 0x3c, 0xff, 
+0x01, 0x34, 0x00, 0x20, 0xff, 0xf7, 0x9e, 0xfe, 0x40, 0x0b, 0x01, 0xd2, 
+0xb4, 0x42, 0xf2, 0xd3, 0x04, 0x20, 0xff, 0xf7, 0x97, 0xfe, 0xff, 0x23, 
+0xe1, 0x33, 0x98, 0x43, 0x01, 0x21, 0x01, 0x43, 0xb8, 0x8b, 0xff, 0x23, 
+0x01, 0x33, 0x98, 0x42, 0x03, 0xd1, 0x2f, 0x23, 0x5b, 0x01, 0x19, 0x43, 
+0x16, 0xe0, 0x01, 0x28, 0x09, 0xd1, 0xf8, 0x8b, 0x01, 0x28, 0x03, 0xd1, 
+0x23, 0x23, 0x5b, 0x01, 0x19, 0x43, 0x0d, 0xe0, 0x20, 0x23, 0x19, 0x43, 
+0x0a, 0xe0, 0x00, 0x28, 0x08, 0xd1, 0xf8, 0x8b, 0x01, 0x28, 0x03, 0xd1, 
+0x0b, 0x23, 0xdb, 0x01, 0x19, 0x43, 0x01, 0xe0, 0x80, 0x23, 0x19, 0x43, 
+0x04, 0x20, 0xff, 0xf7, 0x09, 0xff, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 
+0xff, 0xf7, 0x04, 0xff, 0xe8, 0x68, 0x00, 0x28, 0x0c, 0xd1, 0x00, 0x21, 
+0x1b, 0x20, 0xff, 0xf7, 0xfd, 0xfe, 0x1a, 0x20, 0xff, 0xf7, 0x60, 0xfe, 
+0x01, 0x21, 0xc9, 0x03, 0x01, 0x43, 0x1a, 0x20, 0xff, 0xf7, 0xf4, 0xfe, 
+0x00, 0x27, 0x03, 0xe0, 0x08, 0x2f, 0x01, 0xd3, 0x0f, 0x2f, 0x08, 0xd9, 
+0x38, 0x1c, 0xff, 0xf7, 0x51, 0xfe, 0x79, 0x00, 0x49, 0x19, 0x1b, 0x23, 
+0xdb, 0x01, 0xc9, 0x18, 0x08, 0x83, 0x01, 0x37, 0x20, 0x2f, 0xef, 0xd3, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x70, 0x67, 0x21, 0x40, 
+0xe8, 0x0d, 0x00, 0x80, 0x81, 0xb0, 0x13, 0x48, 0x01, 0x68, 0xc0, 0x46, 
+0x00, 0x91, 0x41, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x81, 0x68, 0xc0, 0x46, 
+0x00, 0x91, 0xc1, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x01, 0x69, 0xc0, 0x46, 
+0x00, 0x91, 0x41, 0x69, 0xc0, 0x46, 0x00, 0x91, 0x81, 0x69, 0xc0, 0x46, 
+0x00, 0x91, 0xc1, 0x69, 0xc0, 0x46, 0x00, 0x91, 0x01, 0x6a, 0xc0, 0x46, 
+0x00, 0x91, 0x41, 0x6a, 0xc0, 0x46, 0x00, 0x91, 0x81, 0x6a, 0xc0, 0x46, 
+0x00, 0x91, 0xc0, 0x6a, 0xc0, 0x46, 0x00, 0x90, 0x01, 0xb0, 0x70, 0x47, 
+0x00, 0x08, 0x14, 0x40, 0xf0, 0xb5, 0x83, 0xb0, 0x66, 0x4e, 0x1b, 0x23, 
+0xdb, 0x01, 0xf7, 0x18, 0x78, 0x8b, 0x04, 0x22, 0x02, 0x40, 0x02, 0x92, 
+0x07, 0x23, 0x5b, 0x02, 0xf4, 0x18, 0xa0, 0x8b, 0xc0, 0x46, 0x01, 0x90, 
+0xe0, 0x8b, 0xc0, 0x46, 0x00, 0x90, 0x00, 0x25, 0x03, 0xe0, 0x08, 0x2d, 
+0x01, 0xd3, 0x0f, 0x2d, 0x08, 0xd9, 0x28, 0x1c, 0xff, 0xf7, 0xfa, 0xfd, 
+0x69, 0x00, 0x89, 0x19, 0x1b, 0x23, 0xdb, 0x01, 0xc9, 0x18, 0x08, 0x83, 
+0x01, 0x35, 0x20, 0x2d, 0xef, 0xd3, 0xa0, 0x69, 0x00, 0x28, 0x15, 0xd0, 
+0x54, 0x4e, 0x20, 0x25, 0x01, 0x3d, 0x52, 0x49, 0xa0, 0x69, 0x30, 0x40, 
+0x0b, 0xd0, 0x68, 0x00, 0x40, 0x18, 0x37, 0x23, 0x9b, 0x01, 0xc0, 0x18, 
+0x01, 0x8b, 0x28, 0x1c, 0xff, 0xf7, 0x78, 0xfe, 0xa0, 0x69, 0xb0, 0x43, 
+0xa0, 0x61, 0x76, 0x08, 0x00, 0x2d, 0xeb, 0xd1, 0x01, 0x20, 0xff, 0xf7, 
+0xd5, 0xfd, 0x01, 0x1c, 0x46, 0x48, 0xc0, 0x46, 0x79, 0x83, 0x79, 0x8b, 
+0xca, 0x08, 0x22, 0xd3, 0xc2, 0x68, 0x01, 0x2a, 0x10, 0xd1, 0x40, 0x88, 
+0x00, 0x28, 0x1c, 0xd1, 0x01, 0x98, 0x42, 0x4a, 0x00, 0x28, 0x05, 0xd0, 
+0x01, 0x28, 0x16, 0xd1, 0xd0, 0x8a, 0xc0, 0x08, 0x13, 0xd2, 0x0f, 0xe0, 
+0xd0, 0x8a, 0x00, 0x09, 0x0f, 0xd2, 0x0b, 0xe0, 0x02, 0x79, 0x00, 0x2a, 
+0x0b, 0xd1, 0x6d, 0x23, 0x5b, 0x01, 0xc0, 0x18, 0x02, 0x88, 0x40, 0x88, 
+0x10, 0x40, 0x40, 0x09, 0x00, 0x07, 0x02, 0xd1, 0x04, 0x23, 0x99, 0x43, 
+0x79, 0x83, 0x78, 0x8b, 0x04, 0x21, 0x01, 0x40, 
+0x02, 0x9a, 0x1f, 0xd0, 0x39, 0x8b, 0x4a, 0x0b, 0x27, 0xd3, 0x80, 0x09, 
+0x25, 0xd3, 0xff, 0x23, 0x01, 0x98, 0x01, 0x33, 0x98, 0x42, 0x20, 0xd0, 
+0x00, 0x25, 0x00, 0x98, 0x01, 0x28, 0x00, 0xd1, 0x05, 0x02, 0x01, 0x98, 
+0x00, 0x28, 0x02, 0xd1, 0x01, 0x23, 0x5b, 0x03, 0x1d, 0x43, 0xa9, 0x42, 
+0x13, 0xd0, 0x00, 0x20, 0x29, 0x1c, 0xff, 0xf7, 0x25, 0xfe, 0x3d, 0x83, 
+0x00, 0x20, 0xc0, 0x43, 0x20, 0x62, 0x0a, 0xe0, 0x38, 0x8b, 0x40, 0x0b, 
+0x07, 0xd2, 0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 0xff, 0xf7, 0x18, 0xfe, 
+0x09, 0x20, 0x40, 0x02, 0x38, 0x83, 0x78, 0x8b, 0xc0, 0x08, 0x2d, 0xd3, 
+0x1b, 0x48, 0xc7, 0x6a, 0x01, 0x98, 0x00, 0x99, 0xff, 0xf7, 0x6a, 0xfc, 
+0xc2, 0x07, 0xd2, 0x0f, 0x18, 0x49, 0x03, 0xd0, 0x04, 0x23, 0xcd, 0x6d, 
+0x2b, 0x43, 0x03, 0xe0, 0x04, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 
+0xcb, 0x65, 0x83, 0x08, 0x03, 0xd3, 0x02, 0x23, 0xcd, 0x6d, 0x2b, 0x43, 
+0x03, 0xe0, 0x02, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 0xcb, 0x65, 
+0x21, 0x6a, 0x81, 0x42, 0x0c, 0xd0, 0x20, 0x62, 0x0c, 0x48, 0x00, 0x2a, 
+0x03, 0xd0, 0xff, 0x21, 0x21, 0x31, 0x39, 0x43, 0x03, 0xe0, 0xff, 0x23, 
+0x21, 0x33, 0x9f, 0x43, 0x39, 0x1c, 0xc1, 0x62, 0x03, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 
+0xa8, 0x1b, 0x00, 0x80, 0x40, 0x00, 0x14, 0x40, 0x10, 0x2a, 0x00, 0x80, 
+0x40, 0x00, 0x14, 0x00, 0x90, 0xb4, 0x01, 0x22, 0x20, 0x28, 0x0f, 0xd2, 
+0x43, 0x00, 0x0f, 0x1c, 0x07, 0x49, 0x5c, 0x18, 0x37, 0x23, 0x9b, 0x01, 
+0xe3, 0x18, 0x1f, 0x83, 0x82, 0x40, 0x07, 0x23, 0x5b, 0x02, 0xc9, 0x18, 
+0x10, 0x1c, 0x8a, 0x69, 0x10, 0x43, 0x88, 0x61, 0x90, 0xbc, 0x70, 0x47, 
+0xe8, 0x0d, 0x00, 0x80, 0x0b, 0x48, 0x40, 0x69, 0x0b, 0x49, 0x49, 0x8b, 
+0x04, 0x22, 0x0a, 0x40, 0x0a, 0x49, 0x06, 0xd0, 0x01, 0x23, 0xdb, 0x02, 
+0x98, 0x43, 0x01, 0x23, 0xca, 0x6d, 0x1a, 0x43, 0x05, 0xe0, 0x01, 0x23, 
+0xdb, 0x02, 0x18, 0x43, 0xca, 0x6d, 0x52, 0x08, 0x52, 0x00, 0xca, 0x65, 
+0x70, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40, 0x68, 0x1b, 0x00, 0x80, 
+0x10, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0x84, 0xb0, 0xff, 0xf7, 0xde, 0xff, 
+0x01, 0x1c, 0x05, 0x20, 0x00, 0x90, 0x00, 0x20, 0x01, 0xab, 0x18, 0x80, 
+0x04, 0x3b, 0x58, 0x70, 0x1b, 0x22, 0x00, 0xab, 0x5a, 0x80, 0xd9, 0x80, 
+0x05, 0x49, 0xc9, 0x6d, 0xc0, 0x46, 0x02, 0x91, 0x03, 0x90, 0x68, 0x46, 
+0x00, 0x21, 0xfc, 0xf7, 0x9d, 0xfd, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 
+0x10, 0x2a, 0x00, 0x80, 0x0d, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, 
+0x01, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, 
+0x09, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x01, 0xe0, 0x08, 0x48, 0x80, 0x6c, 
+0x00, 0x04, 0x00, 0x0c, 0x07, 0x4b, 0x98, 0x42, 0x02, 0xd0, 0x02, 0x33, 
+0x98, 0x42, 0x01, 0xd1, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 
+0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 
+0x04, 0x99, 0x00, 0x00, 0x90, 0xb4, 0x01, 0x24, 0x21, 0x1c, 0x17, 0x48, 
+0x02, 0x68, 0x52, 0x0c, 0x06, 0xd2, 0x02, 0x68, 0x12, 0x0c, 0x02, 0xd1, 
+0x00, 0x68, 0x80, 0x0a, 0x00, 0xd2, 0x00, 0x21, 0x09, 0x06, 0x09, 0x0e, 
+0x11, 0x4f, 0x12, 0x4a, 0x02, 0xd0, 0x38, 0x68, 0x00, 0x0c, 0x00, 0xe0, 
+0x90, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x0f, 0x4b, 
+0x98, 0x42, 0x05, 0xd0, 0x02, 0x33, 0x98, 0x42, 0x02, 0xd0, 0x0d, 0x4b, 
+0x98, 0x42, 0x0c, 0xd1, 0x00, 0x29, 0x02, 0xd0, 0xf8, 0x6a, 0x00, 0x0c, 
+0x00, 0xe0, 0xd0, 0x6c, 0x40, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x20, 0x06, 
+0x00, 0x0e, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0x00, 0x00, 
+0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 
+0x04, 0x99, 0x00, 0x00, 0x05, 0x99, 0x00, 0x00, 0x0c, 0x48, 0x01, 0x68, 
+0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, 0x05, 0xd1, 0x00, 0x68, 
+0x80, 0x0a, 0x02, 0xd3, 0x08, 0x48, 0x80, 0x68, 0x01, 0xe0, 0x08, 0x48, 
+0x40, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x21, 0x03, 0x28, 0x03, 0xd0, 
+0x40, 0x08, 0x01, 0xd3, 0x01, 0x20, 0x70, 0x47, 0x08, 0x1c, 0xfc, 0xe7, 
+0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 
+0xf0, 0xb5, 0x01, 0x27, 0x1a, 0x4c, 0x25, 0x68, 0xff, 0xf7, 0x7a, 0xff, 
+0x03, 0x1c, 0x19, 0x4a, 0x02, 0x21, 0x01, 0x26, 0x18, 0x48, 0x01, 0x2b, 
+0x1b, 0xd1, 0xcb, 0x04, 0x1e, 0x60, 0x55, 0x23, 0x03, 0x60, 0x00, 0x23, 
+0x43, 0x60, 0x06, 0x68, 0x55, 0x2e, 0x1b, 0xd1, 0xaa, 0x26, 0x06, 0x60, 
+0x43, 0x60, 0x03, 0x68, 0xaa, 0x2b, 0x15, 0xd1, 0x09, 0x23, 0x03, 0x60, 
+0x05, 0x23, 0x0f, 0x4f, 0xc0, 0x46, 0x3b, 0x60, 0x03, 0x23, 0x0e, 0x4f, 
+0xc0, 0x46, 0x3b, 0x60, 0x11, 0x60, 0x07, 0x68, 0x08, 0xe0, 0x08, 0x23, 
+0x23, 0x60, 0x04, 0x23, 0x0a, 0x4f, 0xc0, 0x46, 0x3b, 0x60, 0x11, 0x60, 
+0x06, 0x60, 0x27, 0x68, 0xc0, 0x46, 0x25, 0x60, 0x38, 0x1c, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0x24, 0x40, 
+0x00, 0x00, 0x22, 0x40, 0x00, 0x00, 0x2a, 0x40, 0x00, 0x00, 0x26, 0x40, 
+0x00, 0x00, 0x28, 0x40, 0x80, 0xb5, 0x07, 0x1c, 0xff, 0xf7, 0x38, 0xff, 
+0x01, 0x28, 0x05, 0xd1, 0x19, 0x48, 0x00, 0x68, 0x19, 0x49, 0x49, 0x6b, 
+0x08, 0x40, 0x22, 0xe0, 0x18, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, 
+0x01, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, 
+0x14, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x01, 0xe0, 0x13, 0x48, 0x80, 0x6c, 
+0x00, 0x04, 0x00, 0x0c, 0x12, 0x4b, 0xc0, 0x18, 0x08, 0x28, 0x0b, 0xd2, 
+0x01, 0xa3, 0x1b, 0x5c, 0x5b, 0x00, 0x9f, 0x44, 0x05, 0x03, 0x07, 0x03, 
+0x07, 0x07, 0x05, 0x03, 0x03, 0x20, 0x02, 0xe0, 0x01, 0x20, 0x00, 0xe0, 
+0x00, 0x20, 0x01, 0x21, 0x38, 0x60, 0x80, 0x07, 0x00, 0xd1, 0x00, 0x21, 
+0x08, 0x06, 0x00, 0x0e, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x98, 0x6e, 0x21, 0x40, 0x00, 0x00, 0x11, 0x40, 0x00, 0x00, 0x10, 0x40, 
+0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 0xfe, 0x66, 0xff, 0xff, 
+0xf0, 0xb5, 0x83, 0xb0, 0x07, 0x1c, 0x01, 0x20, 0x02, 0x90, 0x01, 0x25, 
+0x02, 0x24, 0x10, 0x26, 0x20, 0x21, 0x00, 0x91, 0xff, 0xf7, 0xea, 0xfe, 
+0x01, 0x28, 0x4d, 0xd1, 0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x3a, 0xd1, 
+0x2e, 0x4e, 0x3c, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, 0x1c, 0xfb, 
+0x3e, 0x21, 0x05, 0x1c, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, 0x16, 0xfb, 
+0x00, 0x04, 0x05, 0x43, 0x40, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, 
+0x0f, 0xfb, 0x01, 0x90, 0x42, 0x21, 0x02, 0x20, 0x32, 0x1c, 0xfc, 0xf7, 
+0x09, 0xfb, 0x00, 0x04, 0x01, 0x99, 0x08, 0x43, 0x06, 0x1c, 0xa8, 0x2f, 
+0x1b, 0xd1, 0x1f, 0x4a, 0x44, 0x21, 0x02, 0x20, 
+0xfc, 0xf7, 0xfe, 0xfa, 0x04, 0x1c, 0x1c, 0x4a, 0x46, 0x21, 0x02, 0x20, 
+0xfc, 0xf7, 0xf8, 0xfa, 0x00, 0x04, 0x04, 0x43, 0x18, 0x4a, 0x48, 0x21, 
+0x02, 0x20, 0xfc, 0xf7, 0xf1, 0xfa, 0x00, 0x90, 0x15, 0x4a, 0x4a, 0x21, 
+0x02, 0x20, 0xfc, 0xf7, 0xeb, 0xfa, 0x00, 0x04, 0x00, 0x99, 0x01, 0x43, 
+0x00, 0x91, 0x28, 0x1c, 0x30, 0x43, 0x20, 0x43, 0x00, 0x99, 0x08, 0x43, 
+0x00, 0xd1, 0x16, 0xe0, 0x11, 0x20, 0x00, 0x04, 0x05, 0x62, 0x46, 0x62, 
+0x84, 0x62, 0x00, 0x99, 0xc0, 0x46, 0xc1, 0x62, 0x00, 0x21, 0x0a, 0x48, 
+0xc0, 0x46, 0x01, 0x60, 0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x05, 0xd1, 
+0x01, 0x21, 0x01, 0x60, 0xa8, 0x2f, 0x01, 0xd1, 0x03, 0x21, 0x01, 0x60, 
+0x02, 0x98, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x39, 0xb7, 0x21, 0x40, 0x98, 0x6e, 0x21, 0x40, 0x80, 0xb5, 0x07, 0x1c, 
+0xff, 0xf7, 0x7e, 0xfe, 0x01, 0x28, 0x19, 0xd1, 0x01, 0x05, 0x11, 0x48, 
+0x00, 0x2f, 0x18, 0xd0, 0x0b, 0x0a, 0x02, 0x68, 0x9a, 0x43, 0x0a, 0x60, 
+0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, 0x0b, 0xd1, 
+0x00, 0x68, 0x80, 0x0a, 0x08, 0xd3, 0x0a, 0x48, 0x40, 0x6a, 0xff, 0x22, 
+0x01, 0x32, 0x02, 0x43, 0x08, 0x49, 0xc0, 0x46, 0x4a, 0x62, 0x48, 0x62, 
+0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x68, 0x01, 0x23, 0x1b, 0x03, 
+0x18, 0x43, 0x08, 0x60, 0xf6, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 
+0xc0, 0x00, 0x18, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x70, 0x47, 0x00, 0x00, 
+0x90, 0xb5, 0x07, 0x1c, 0x12, 0x4c, 0x21, 0x68, 0x12, 0x48, 0x81, 0x42, 
+0x0b, 0xd0, 0x00, 0x23, 0x21, 0x1c, 0xe2, 0x1d, 0x6d, 0x32, 0x00, 0xe0, 
+0x08, 0xc1, 0x91, 0x42, 0xfc, 0xd3, 0x20, 0x60, 0x74, 0x20, 0xa0, 0x80, 
+0x67, 0x72, 0x38, 0x01, 0x00, 0xf0, 0x18, 0xf8, 0x27, 0x72, 0x0a, 0x48, 
+0xc0, 0x46, 0xe0, 0x60, 0x08, 0x2f, 0x00, 0xdb, 0x00, 0x27, 0xe0, 0x19, 
+0x01, 0x7d, 0x01, 0x31, 0x01, 0x75, 0xe0, 0x88, 0x01, 0x30, 0xe0, 0x80, 
+0x01, 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x80, 
+0xfe, 0xca, 0x01, 0x20, 0x17, 0x40, 0x00, 0x02, 0x80, 0xb4, 0x08, 0x4a, 
+0xd1, 0x1d, 0x49, 0x31, 0x0b, 0x78, 0x20, 0x2b, 0x01, 0xd3, 0x00, 0x23, 
+0x0b, 0x70, 0x07, 0x1c, 0x08, 0x78, 0x43, 0x1c, 0x0b, 0x70, 0x80, 0x18, 
+0x50, 0x30, 0x47, 0x70, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x00, 0x80, 
+0x07, 0x49, 0x01, 0x22, 0x12, 0x04, 0x08, 0x68, 0x02, 0x40, 0x01, 0x20, 
+0x00, 0x2a, 0x06, 0xd1, 0x0a, 0x68, 0x12, 0x0c, 0x02, 0xd1, 0x09, 0x68, 
+0x89, 0x0a, 0x00, 0xd2, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x10, 0x40, 
+0x90, 0xb5, 0x07, 0x1c, 0x09, 0x4c, 0x38, 0x1c, 0x21, 0x1c, 0xfc, 0xf7, 
+0x4d, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8, 0x01, 0x23, 0xd8, 0x42, 
+0x01, 0xd1, 0x00, 0x0c, 0xe0, 0x80, 0x00, 0x21, 0x20, 0x1c, 0xfc, 0xf7, 
+0x81, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xbc, 0x67, 0x21, 0x40, 
+0xf8, 0xb5, 0x07, 0x1c, 0x79, 0x7a, 0x76, 0x48, 0x00, 0x23, 0x76, 0x4c, 
+0x01, 0x29, 0x5d, 0xd1, 0xa2, 0x88, 0xc0, 0x46, 0x00, 0x92, 0xa1, 0x89, 
+0x8a, 0x42, 0x74, 0xda, 0xfa, 0x7a, 0x00, 0x2a, 0x15, 0xd0, 0x7a, 0x6c, 
+0x00, 0x2a, 0x12, 0xd0, 0x8a, 0x42, 0x10, 0xd8, 0x00, 0x9a, 0x51, 0x1c, 
+0xa1, 0x80, 0xa1, 0x88, 0xc0, 0x46, 0x41, 0x81, 0x78, 0x6c, 0x6b, 0x4e, 
+0xc0, 0x46, 0xf0, 0x80, 0xa0, 0x6a, 0x58, 0x23, 
+0x79, 0x6c, 0x59, 0x43, 0x40, 0x18, 0xc1, 0x1a, 0x28, 0xe0, 0x22, 0x88, 
+0x01, 0x32, 0x12, 0x04, 0x12, 0x0c, 0x22, 0x80, 0x8a, 0x42, 0x00, 0xdb, 
+0x23, 0x80, 0x00, 0x22, 0x00, 0x29, 0x69, 0xdd, 0x5f, 0x4c, 0xa4, 0x6a, 
+0x5e, 0x4b, 0x1d, 0x88, 0x58, 0x23, 0x6b, 0x43, 0xe3, 0x18, 0xde, 0x1d, 
+0x01, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, 
+0x15, 0xd1, 0x58, 0x49, 0x00, 0x9a, 0x01, 0x32, 0x8a, 0x80, 0x8a, 0x88, 
+0xc0, 0x46, 0x42, 0x81, 0x08, 0x88, 0x01, 0x30, 0x54, 0x4e, 0xc0, 0x46, 
+0xf0, 0x80, 0x58, 0x20, 0x68, 0x43, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, 
+0x65, 0xfa, 0xf0, 0x88, 0x00, 0x04, 0x00, 0x14, 0x95, 0xe0, 0x4d, 0x4b, 
+0x01, 0x35, 0x2d, 0x04, 0x2d, 0x0c, 0x1d, 0x80, 0x8d, 0x42, 0x01, 0xdb, 
+0x00, 0x25, 0x1d, 0x80, 0x01, 0x32, 0x12, 0x04, 0x12, 0x14, 0x91, 0x42, 
+0xce, 0xdc, 0x81, 0xe0, 0xe1, 0x88, 0xe2, 0x89, 0x91, 0x42, 0x18, 0xda, 
+0xf9, 0x7a, 0x00, 0x29, 0x2f, 0xd0, 0x79, 0x6c, 0x49, 0x04, 0x49, 0x0c, 
+0x79, 0x64, 0x2a, 0xd0, 0xe2, 0x89, 0x91, 0x42, 0x27, 0xd8, 0xe1, 0x88, 
+0x01, 0x31, 0xe1, 0x80, 0xe1, 0x88, 0xc0, 0x46, 0x81, 0x81, 0x01, 0x23, 
+0xdb, 0x03, 0x78, 0x6c, 0x18, 0x43, 0x3a, 0x4e, 0xc0, 0x46, 0xf0, 0x80, 
+0x00, 0xe0, 0x63, 0xe0, 0xe0, 0x6a, 0x79, 0x6c, 0x4b, 0x00, 0x59, 0x18, 
+0x49, 0x01, 0x40, 0x18, 0xc1, 0x1f, 0x59, 0x39, 0x38, 0x1c, 0x00, 0xf0, 
+0x4b, 0xfa, 0xe0, 0x6a, 0x79, 0x6c, 0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, 
+0x80, 0x18, 0x01, 0x39, 0x09, 0x04, 0x09, 0x0c, 0x60, 0x38, 0x00, 0xf0, 
+0xc5, 0xfa, 0xb6, 0xe7, 0x4a, 0xe0, 0x61, 0x88, 0x01, 0x31, 0x09, 0x04, 
+0x09, 0x0c, 0x61, 0x80, 0xe2, 0x89, 0x91, 0x42, 0x00, 0xdb, 0x63, 0x80, 
+0x00, 0x21, 0x00, 0x2a, 0x3e, 0xdd, 0x24, 0x4c, 0xe4, 0x6a, 0x23, 0x4b, 
+0x5d, 0x88, 0x6b, 0x00, 0x5b, 0x19, 0x5b, 0x01, 0xe3, 0x18, 0xde, 0x1d, 
+0x01, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, 
+0x20, 0xd1, 0x1c, 0x4e, 0xf1, 0x88, 0x01, 0x31, 0xf1, 0x80, 0xf1, 0x88, 
+0xc0, 0x46, 0x81, 0x81, 0x70, 0x88, 0x01, 0x23, 0xdb, 0x03, 0x01, 0x30, 
+0x18, 0x43, 0x17, 0x49, 0xc0, 0x46, 0xc8, 0x80, 0x68, 0x00, 0x40, 0x19, 
+0x40, 0x01, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x0b, 0xfa, 0x71, 0x88, 
+0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, 0xf0, 0x6a, 0x80, 0x18, 0x00, 0xf0, 
+0x89, 0xfa, 0x0e, 0x49, 0xc8, 0x88, 0x79, 0xe7, 0x0b, 0x4b, 0x01, 0x35, 
+0x2d, 0x04, 0x2d, 0x0c, 0x5d, 0x80, 0x95, 0x42, 0x01, 0xdb, 0x00, 0x25, 
+0x5d, 0x80, 0x01, 0x31, 0x09, 0x04, 0x09, 0x14, 0x8a, 0x42, 0xc2, 0xdc, 
+0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 0x00, 0x20, 0xc0, 0x43, 0xf8, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xb8, 0x2a, 0x00, 0x80, 0xc8, 0x29, 0x00, 0x80, 
+0xbc, 0x67, 0x21, 0x40, 0xf0, 0xb4, 0x06, 0x1c, 0x01, 0x23, 0xdb, 0x03, 
+0x33, 0x40, 0x01, 0x24, 0x30, 0x4f, 0x00, 0x20, 0x30, 0x4a, 0x31, 0x4d, 
+0xd1, 0x1d, 0x39, 0x31, 0x00, 0x2b, 0x2f, 0xd0, 0xe3, 0x03, 0xf3, 0x1a, 
+0x51, 0xd0, 0xee, 0x89, 0x9e, 0x42, 0x4e, 0xd3, 0xee, 0x88, 0x00, 0x2e, 
+0x4b, 0xd0, 0xee, 0x6a, 0x5d, 0x1e, 0x6b, 0x00, 0x5d, 0x19, 0x6d, 0x01, 
+0x73, 0x19, 0x9e, 0x68, 0x36, 0x06, 0x36, 0x0e, 0x03, 0x2e, 0x02, 0xd0, 
+0xce, 0x89, 0x01, 0x36, 0xce, 0x81, 0x40, 0x33, 0x9b, 0x8b, 0x9b, 0x00, 
+0x21, 0x4e, 0x76, 0x6a, 0xc0, 0x46, 0xf0, 0x50, 
+0x53, 0x89, 0x01, 0x33, 0x53, 0x81, 0x1e, 0x4e, 0xf2, 0x6a, 0x52, 0x19, 
+0x90, 0x60, 0xf0, 0x88, 0x01, 0x38, 0xf0, 0x80, 0xf0, 0x88, 0xc0, 0x46, 
+0x88, 0x81, 0x19, 0x49, 0x00, 0x28, 0x23, 0xd1, 0x4f, 0x80, 0x21, 0xe0, 
+0x00, 0x2e, 0x22, 0xd9, 0xab, 0x89, 0xb3, 0x42, 0x1f, 0xd3, 0xab, 0x88, 
+0x00, 0x2b, 0x1c, 0xd0, 0x53, 0x89, 0x01, 0x33, 0x53, 0x81, 0x58, 0x23, 
+0x01, 0x3e, 0x73, 0x43, 0xaa, 0x6a, 0xd2, 0x18, 0x93, 0x68, 0x1b, 0x06, 
+0x1b, 0x0e, 0x03, 0x2b, 0x02, 0xd0, 0xcb, 0x89, 0x01, 0x33, 0xcb, 0x81, 
+0x90, 0x60, 0xa8, 0x88, 0x01, 0x38, 0xa8, 0x80, 0xa8, 0x88, 0xc0, 0x46, 
+0x48, 0x81, 0x00, 0x28, 0x00, 0xd1, 0x2f, 0x80, 0x20, 0x1c, 0xf0, 0xbc, 
+0x70, 0x47, 0xca, 0x89, 0x01, 0x32, 0xca, 0x81, 0xf9, 0xe7, 0x00, 0x00, 
+0xff, 0xff, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 0xc8, 0x29, 0x00, 0x80, 
+0x00, 0xb5, 0x00, 0x21, 0x41, 0x60, 0x10, 0x49, 0x4a, 0x68, 0x00, 0x2a, 
+0x10, 0xd1, 0xca, 0x68, 0x00, 0x2a, 0x04, 0xd0, 0xca, 0x1d, 0x19, 0x32, 
+0x12, 0x79, 0x00, 0x2a, 0x08, 0xd0, 0x4a, 0x69, 0x00, 0x2a, 0x0b, 0xd1, 
+0x88, 0x61, 0x48, 0x61, 0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 
+0x4a, 0x69, 0x00, 0x2a, 0x02, 0xd1, 0x88, 0x61, 0x48, 0x61, 0xf7, 0xe7, 
+0x8a, 0x69, 0xc0, 0x46, 0x50, 0x60, 0x88, 0x61, 0xf2, 0xe7, 0x00, 0x00, 
+0xec, 0x05, 0x00, 0x80, 0xb0, 0xb5, 0x2a, 0x48, 0x40, 0x69, 0x00, 0x28, 
+0x4c, 0xd0, 0x08, 0x22, 0xc1, 0x68, 0x0a, 0x40, 0x00, 0x27, 0x27, 0x4b, 
+0xd9, 0x1d, 0xb9, 0x31, 0x00, 0x2a, 0x11, 0xd0, 0x04, 0x22, 0x25, 0x4c, 
+0xc0, 0x46, 0x0c, 0x61, 0x24, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x24, 0x4c, 
+0xc0, 0x46, 0x8c, 0x62, 0x23, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x23, 0x4c, 
+0xc0, 0x46, 0x0c, 0x63, 0x4f, 0x63, 0x12, 0xe0, 0x05, 0x22, 0x21, 0x4c, 
+0xc0, 0x46, 0x0c, 0x61, 0x20, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x20, 0x4c, 
+0xc0, 0x46, 0x8c, 0x62, 0x1f, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x1f, 0x4c, 
+0xc0, 0x46, 0x0c, 0x63, 0x1e, 0x4c, 0xc0, 0x46, 0x4c, 0x63, 0x40, 0x24, 
+0xcc, 0x82, 0x4f, 0x83, 0x1c, 0x4f, 0x00, 0x21, 0x00, 0x2a, 0x0c, 0xd9, 
+0x8c, 0x00, 0x05, 0x19, 0x6d, 0x6a, 0x7d, 0x40, 0xe4, 0x18, 0xff, 0x34, 
+0x01, 0x34, 0x65, 0x62, 0x01, 0x31, 0x91, 0x42, 0xf4, 0xd3, 0x10, 0x29, 
+0x07, 0xd2, 0x8a, 0x00, 0xd2, 0x18, 0xff, 0x32, 0x01, 0x32, 0x57, 0x62, 
+0x01, 0x31, 0x10, 0x29, 0xf7, 0xd3, 0x11, 0x49, 0x00, 0xf0, 0x22, 0xf8, 
+0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 
+0x1c, 0xad, 0x20, 0x40, 0x28, 0x01, 0x40, 0x00, 0x01, 0x23, 0x45, 0x67, 
+0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 
+0x20, 0x01, 0x40, 0x00, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 
+0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0, 
+0x36, 0x36, 0x36, 0x36, 0x30, 0x80, 0x20, 0x40, 0xb0, 0xb5, 0x0f, 0x1c, 
+0x15, 0x4d, 0xe9, 0x1d, 0xc9, 0x31, 0x15, 0x4c, 0x23, 0x1c, 0x15, 0x4a, 
+0x00, 0x20, 0xfc, 0xf7, 0x1a, 0xf8, 0xe9, 0x1d, 0xff, 0x31, 0x1e, 0x31, 
+0x23, 0x1c, 0x0d, 0x1c, 0x11, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x11, 0xf8, 
+0x29, 0x1c, 0x23, 0x1c, 0x0e, 0x4a, 0x00, 0x20, 0xfc, 0xf7, 0x0b, 0xf8, 
+0x39, 0x1c, 0x23, 0x1c, 0x0c, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x05, 0xf8, 
+0x00, 0x21, 0x0b, 0x48, 0xc2, 0x1d, 0x19, 0x32, 
+0x51, 0x71, 0x01, 0x21, 0xff, 0x30, 0x01, 0x30, 0x41, 0x62, 0x08, 0x1c, 
+0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x1c, 0xad, 0x20, 0x40, 
+0x75, 0x08, 0xff, 0xff, 0x28, 0x00, 0x03, 0x00, 0x40, 0x00, 0x02, 0x00, 
+0x14, 0x00, 0x07, 0x00, 0xec, 0x05, 0x00, 0x80, 0xf0, 0xb5, 0x37, 0x4a, 
+0x50, 0x69, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x30, 0x18, 0x43, 0x00, 0x68, 
+0x01, 0x06, 0x09, 0x0e, 0x33, 0x4b, 0x01, 0x29, 0x49, 0xd1, 0x1f, 0x68, 
+0x19, 0x1c, 0x32, 0x4b, 0x9f, 0x42, 0x04, 0xd1, 0xff, 0xf7, 0x3e, 0xff, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x23, 0x9f, 0x00, 0xcc, 0x59, 
+0x55, 0x69, 0xef, 0x19, 0x3c, 0x61, 0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3, 
+0x00, 0x0a, 0x00, 0x02, 0x02, 0x23, 0x18, 0x43, 0x53, 0x69, 0xc0, 0x46, 
+0x98, 0x60, 0x50, 0x69, 0x08, 0x23, 0xc2, 0x68, 0x13, 0x40, 0x25, 0x4f, 
+0xfa, 0x1d, 0xb9, 0x32, 0x00, 0x2b, 0x02, 0xd0, 0x04, 0x23, 0x23, 0x4c, 
+0x01, 0xe0, 0x05, 0x23, 0x22, 0x4c, 0xc0, 0x46, 0x14, 0x61, 0x40, 0x24, 
+0xd4, 0x82, 0x00, 0x24, 0x54, 0x83, 0x20, 0x4c, 0x00, 0x22, 0x00, 0x2b, 
+0x0c, 0xd9, 0x95, 0x00, 0x46, 0x19, 0x76, 0x6a, 0x66, 0x40, 0xed, 0x19, 
+0xff, 0x35, 0x01, 0x35, 0x6e, 0x62, 0x01, 0x32, 0x9a, 0x42, 0xf4, 0xd3, 
+0x10, 0x2a, 0x07, 0xd2, 0x93, 0x00, 0xdb, 0x19, 0xff, 0x33, 0x01, 0x33, 
+0x5c, 0x62, 0x01, 0x32, 0x10, 0x2a, 0xf7, 0xd3, 0xff, 0xf7, 0x70, 0xff, 
+0xbc, 0xe7, 0x00, 0x21, 0x8f, 0x00, 0xdc, 0x59, 0x55, 0x69, 0xef, 0x19, 
+0x7c, 0x62, 0x01, 0x31, 0x05, 0x29, 0xf7, 0xd3, 0x00, 0x0a, 0x00, 0x02, 
+0x03, 0x23, 0x18, 0x43, 0x51, 0x69, 0xc0, 0x46, 0x88, 0x60, 0x50, 0x69, 
+0x40, 0x68, 0xc0, 0x46, 0x50, 0x61, 0x09, 0x48, 0xfb, 0xf7, 0x7a, 0xff, 
+0xa4, 0xe7, 0x00, 0x00, 0xec, 0x05, 0x00, 0x80, 0x30, 0x80, 0x20, 0x40, 
+0x67, 0x45, 0x23, 0x01, 0x1c, 0xad, 0x20, 0x40, 0x28, 0x01, 0x40, 0x00, 
+0x20, 0x01, 0x40, 0x00, 0x5c, 0x5c, 0x5c, 0x5c, 0x85, 0x30, 0xff, 0xff, 
+0x80, 0xb5, 0x0f, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x43, 0xf8, 0xb9, 0x6b, 
+0x0b, 0x48, 0xc2, 0x68, 0x12, 0x04, 0x51, 0x40, 0x82, 0x69, 0x51, 0x40, 
+0x39, 0x65, 0xf9, 0x6b, 0x82, 0x69, 0x12, 0x04, 0xd2, 0x43, 0x51, 0x40, 
+0xc0, 0x68, 0xc0, 0x43, 0x48, 0x40, 0x78, 0x65, 0x04, 0x48, 0x01, 0x89, 
+0x01, 0x31, 0x01, 0x81, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0x08, 0x83, 0x20, 0x40, 0x78, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c, 
+0x0f, 0x1c, 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x1f, 0xf8, 0xe0, 0x68, 
+0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 
+0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 
+0x08, 0x43, 0x38, 0x65, 0x20, 0x69, 0xc0, 0x46, 0x78, 0x65, 0x60, 0x69, 
+0xc0, 0x46, 0xb8, 0x65, 0x03, 0x48, 0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 
+0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x78, 0x2a, 0x00, 0x80, 
+0x90, 0xb5, 0x00, 0x22, 0x93, 0x00, 0x1f, 0x18, 0xbf, 0x69, 0x5b, 0x18, 
+0x5f, 0x62, 0x01, 0x32, 0x05, 0x2a, 0xf7, 0xd3, 0x07, 0x7a, 0xfb, 0x08, 
+0x03, 0xd3, 0x00, 0x23, 0x92, 0x00, 0x52, 0x18, 0x13, 0x62, 0x07, 0x6b, 
+0xc0, 0x46, 0x8f, 0x63, 0xc7, 0x6a, 0xc0, 0x46, 0xcf, 0x63, 0x87, 0x6b, 
+0xc0, 0x46, 0x0f, 0x64, 0x47, 0x6b, 0xc0, 0x46, 0x4f, 0x64, 0x07, 0x6c, 
+0xc0, 0x46, 0x8f, 0x64, 0xc2, 0x6b, 0xc0, 0x46, 
+0xca, 0x64, 0xc2, 0x88, 0xc0, 0x46, 0x0a, 0x80, 0x82, 0x7a, 0x12, 0x06, 
+0x03, 0x7a, 0x1b, 0x04, 0x1a, 0x43, 0xc3, 0x88, 0x1b, 0x02, 0x1a, 0x43, 
+0x43, 0x7a, 0xdb, 0x07, 0x1a, 0x43, 0x8a, 0x60, 0x17, 0x1c, 0x83, 0x7a, 
+0x5a, 0x08, 0x05, 0xd3, 0x14, 0x22, 0x1c, 0x1c, 0xa3, 0x08, 0x02, 0xd2, 
+0x15, 0x22, 0x00, 0xe0, 0x00, 0x22, 0x00, 0x7a, 0x43, 0x08, 0x10, 0xd3, 
+0xc0, 0x08, 0x02, 0xd3, 0x88, 0x20, 0x10, 0x43, 0x01, 0xe0, 0x80, 0x20, 
+0x10, 0x43, 0x3a, 0x0a, 0x12, 0x02, 0x01, 0x23, 0x1a, 0x43, 0xc8, 0x60, 
+0x8a, 0x60, 0x08, 0x1c, 0xff, 0xf7, 0x14, 0xfe, 0x05, 0xe0, 0x38, 0x0a, 
+0x00, 0x02, 0x03, 0x23, 0x18, 0x43, 0x88, 0x60, 0xca, 0x60, 0x03, 0x48, 
+0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x78, 0x2a, 0x00, 0x80, 0xf0, 0xb4, 0x02, 0x6d, 0x14, 0x4c, 0x15, 0x1c, 
+0xe7, 0x69, 0xbd, 0x40, 0x13, 0x1c, 0x26, 0x6a, 0xf3, 0x40, 0x5d, 0x40, 
+0x2e, 0x1c, 0x45, 0x6d, 0xbd, 0x40, 0x6e, 0x40, 0x2b, 0x1c, 0x35, 0x1c, 
+0xfd, 0x40, 0x2f, 0x1c, 0xbb, 0x00, 0x65, 0x6a, 0xeb, 0x58, 0x00, 0x2b, 
+0x08, 0xd0, 0x23, 0x69, 0x01, 0x37, 0x9f, 0x42, 0x00, 0xd3, 0x00, 0x27, 
+0xbe, 0x00, 0xae, 0x59, 0x00, 0x2e, 0xf7, 0xd1, 0xa4, 0x69, 0xa2, 0x40, 
+0x11, 0x43, 0x05, 0x4b, 0x19, 0x43, 0xba, 0x00, 0xa9, 0x50, 0x40, 0x30, 
+0x87, 0x83, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xc8, 0x29, 0x00, 0x80, 
+0x00, 0x00, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x00, 0xf0, 
+0xb1, 0xfa, 0x20, 0x1c, 0x00, 0xf0, 0x0e, 0xfa, 0x38, 0x0c, 0x00, 0xf0, 
+0x0b, 0xfa, 0x38, 0x0a, 0x00, 0xf0, 0x08, 0xfa, 0x38, 0x1c, 0x00, 0xf0, 
+0x05, 0xfa, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 
+0x00, 0xf0, 0x9e, 0xfa, 0x54, 0x20, 0x00, 0xf0, 0xfb, 0xf9, 0x38, 0x0c, 
+0x00, 0xf0, 0xf8, 0xf9, 0x38, 0x0a, 0x00, 0xf0, 0xf5, 0xf9, 0x38, 0x1c, 
+0x00, 0xf0, 0xf2, 0xf9, 0x00, 0x20, 0x00, 0xf0, 0xef, 0xf9, 0x80, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0, 0x89, 0xfa, 0x57, 0x20, 
+0x00, 0xf0, 0xe6, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, 0x81, 0xb0, 
+0x41, 0x02, 0x53, 0x20, 0xff, 0xf7, 0xc8, 0xff, 0x00, 0xf0, 0x64, 0xfa, 
+0x00, 0xf0, 0xf5, 0xf8, 0x00, 0x24, 0x00, 0x26, 0x00, 0x25, 0x00, 0x27, 
+0x30, 0x1c, 0x01, 0x36, 0xff, 0xf7, 0xd0, 0xff, 0x00, 0xf0, 0x46, 0xf9, 
+0x00, 0x90, 0x00, 0xf0, 0x55, 0xfa, 0xf8, 0x00, 0x00, 0x99, 0x81, 0x40, 
+0x0d, 0x43, 0x01, 0x34, 0x01, 0x37, 0x04, 0x2f, 0xee, 0xd3, 0x02, 0x99, 
+0x20, 0xc1, 0x02, 0x91, 0xff, 0x23, 0x09, 0x33, 0x9c, 0x42, 0xe5, 0xd3, 
+0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x04, 0x1c, 
+0x0f, 0x1c, 0x00, 0x26, 0x20, 0xcf, 0xb1, 0x00, 0x84, 0x20, 0xff, 0xf7, 
+0x9b, 0xff, 0x28, 0x1c, 0x00, 0xf0, 0xae, 0xf9, 0x28, 0x0a, 0x00, 0xf0, 
+0xab, 0xf9, 0x28, 0x0c, 0x00, 0xf0, 0xa8, 0xf9, 0x28, 0x0e, 0x00, 0xf0, 
+0xa5, 0xf9, 0x00, 0xf0, 0x2b, 0xfa, 0x01, 0x36, 0x42, 0x2e, 0xe9, 0xd3, 
+0x61, 0x02, 0x83, 0x20, 0xff, 0xf7, 0x86, 0xff, 0x00, 0xf0, 0x22, 0xfa, 
+0x00, 0xf0, 0xb3, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 
+0x41, 0x02, 0x60, 0x20, 0xff, 0xf7, 0x7a, 0xff, 0x00, 0xf0, 0x16, 0xfa, 
+0x00, 0xf0, 0xa7, 0xf8, 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x90, 0xb5, 0x0f, 0x1c, 0x41, 0x02, 0x53, 0x20, 
+0xff, 0xf7, 0x6c, 0xff, 0x00, 0xf0, 0x08, 0xfa, 0x00, 0xf0, 0x99, 0xf8, 
+0xf8, 0x1d, 0x05, 0x30, 0x44, 0x1c, 0xff, 0xf7, 0x77, 0xff, 0x00, 0xf0, 
+0xed, 0xf8, 0x07, 0x1c, 0x00, 0xf0, 0xfc, 0xf9, 0x20, 0x1c, 0xff, 0xf7, 
+0x6f, 0xff, 0x00, 0xf0, 0xe5, 0xf8, 0x04, 0x1c, 0x00, 0xf0, 0xf4, 0xf9, 
+0x20, 0x02, 0x38, 0x43, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 
+0xc2, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, 0x17, 0x1c, 0x61, 0x02, 0x53, 0x20, 
+0xff, 0xf7, 0x48, 0xff, 0x00, 0xf0, 0xe4, 0xf9, 0x00, 0xf0, 0x75, 0xf8, 
+0x68, 0x46, 0x00, 0xf0, 0x5c, 0xf8, 0x6a, 0x46, 0xe8, 0x1d, 0x05, 0x30, 
+0x17, 0x54, 0x39, 0x0a, 0x68, 0x44, 0x41, 0x70, 0x68, 0x46, 0x00, 0x99, 
+0x0c, 0x30, 0x00, 0xf0, 0x73, 0xf8, 0x02, 0xab, 0x18, 0x70, 0x00, 0x20, 
+0x58, 0x70, 0x68, 0x46, 0x0c, 0x21, 0x00, 0xf0, 0x6b, 0xf8, 0x02, 0xab, 
+0x58, 0x70, 0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7, 0x83, 0xff, 0x42, 0xb0, 
+0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0xc2, 0xb0, 0x04, 0x1c, 
+0x1f, 0x1c, 0x6b, 0x46, 0x00, 0x20, 0xc5, 0x43, 0x20, 0xc3, 0x01, 0x30, 
+0x42, 0x28, 0xfb, 0xd3, 0x68, 0x46, 0x0c, 0x30, 0x03, 0x1c, 0x00, 0x25, 
+0x00, 0x2a, 0x0a, 0xd9, 0x0e, 0x88, 0xc0, 0x46, 0x06, 0x70, 0x0e, 0x88, 
+0x36, 0x12, 0x46, 0x70, 0x02, 0x30, 0x02, 0x31, 0x02, 0x35, 0x95, 0x42, 
+0xf4, 0xd3, 0x00, 0x92, 0x18, 0x1c, 0x11, 0x1c, 0x00, 0xf0, 0x40, 0xf8, 
+0x00, 0x26, 0x01, 0x96, 0x02, 0xab, 0x18, 0x70, 0x5e, 0x70, 0x9e, 0x70, 
+0xde, 0x70, 0x05, 0x1c, 0x68, 0x46, 0x0c, 0x21, 0x00, 0xf0, 0x34, 0xf8, 
+0x02, 0xab, 0x58, 0x70, 0x38, 0x06, 0x00, 0x0e, 0x85, 0x42, 0x05, 0xd1, 
+0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7, 0x48, 0xff, 0x30, 0x1c, 0x00, 0xe0, 
+0x01, 0x20, 0x42, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 
+0x07, 0x1c, 0x00, 0x24, 0xff, 0x26, 0x09, 0x36, 0x20, 0x1c, 0xff, 0xf7, 
+0xf1, 0xfe, 0x00, 0xf0, 0x67, 0xf8, 0x05, 0x1c, 0x00, 0xf0, 0x76, 0xf9, 
+0x3d, 0x70, 0x28, 0x1c, 0x01, 0x37, 0x01, 0x34, 0xb4, 0x42, 0xf1, 0xd3, 
+0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0xff, 0xf7, 0xf6, 0xfe, 
+0x00, 0xf0, 0x56, 0xf8, 0x07, 0x1c, 0x00, 0xf0, 0x65, 0xf9, 0x38, 0x0a, 
+0xf6, 0xd3, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb4, 0x00, 0x22, 
+0x00, 0x23, 0x00, 0x29, 0x05, 0xd9, 0x07, 0x78, 0x7a, 0x40, 0x01, 0x30, 
+0x01, 0x33, 0x8b, 0x42, 0xf9, 0xd3, 0xd0, 0x43, 0x00, 0x06, 0x00, 0x0e, 
+0x80, 0xbc, 0x70, 0x47, 0xb0, 0xb5, 0xc2, 0xb0, 0x0f, 0x1c, 0x41, 0x02, 
+0x53, 0x20, 0xff, 0xf7, 0xab, 0xfe, 0x00, 0xf0, 0x47, 0xf9, 0xff, 0xf7, 
+0xd8, 0xff, 0x68, 0x46, 0xff, 0xf7, 0xbf, 0xff, 0x02, 0xad, 0x6d, 0x78, 
+0x00, 0x24, 0x02, 0xab, 0x5c, 0x70, 0x68, 0x46, 0x0c, 0x21, 0xff, 0xf7, 
+0xd9, 0xff, 0xa8, 0x42, 0x02, 0xd1, 0x00, 0x98, 0x87, 0x42, 0x01, 0xd3, 
+0x20, 0x1c, 0x00, 0xe0, 0x01, 0x20, 0x42, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x80, 0xb5, 0xc2, 0xb0, 0x69, 0x46, 0x02, 0x20, 0xff, 0xf7, 
+0xbb, 0xfe, 0x68, 0x46, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20, 0x07, 0x4a, 
+0x0f, 0x88, 0x43, 0x00, 0xd7, 0x52, 0x02, 0x31, 0x01, 0x30, 0x00, 0x04, 
+0x00, 0x0c, 0x25, 0x28, 0xf6, 0xdb, 0x42, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x70, 0x67, 0x21, 0x40, 0xfc, 0x46, 0x60, 0x47, 
+0x00, 0x00, 0xa0, 0xe3, 0xb4, 0x22, 0x9f, 0xe5, 
+0xb4, 0x32, 0x9f, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 0x81, 0x03, 0x80, 0xe1, 
+0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0x93, 0xe5, 0x01, 0x03, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 
+0x81, 0x02, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 0x01, 0x02, 0x80, 0xe1, 
+0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0x93, 0xe5, 0x81, 0x01, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 
+0x01, 0x01, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 0x81, 0x00, 0x80, 0xe1, 
+0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0x93, 0xe5, 0x01, 0x00, 0x80, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 
+0xfc, 0x46, 0x60, 0x47, 0xa4, 0x21, 0x9f, 0xe5, 0xa8, 0x31, 0x9f, 0xe5, 
+0xa0, 0x13, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x20, 0x13, 0xa0, 0xe1, 
+0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0x82, 0xe5, 0xa0, 0x12, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 
+0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
+0x20, 0x12, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0xa0, 0x11, 0xa0, 0xe1, 
+0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0x82, 0xe5, 0x20, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 
+0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
+0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
+0xa0, 0x10, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe1, 
+0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
+0xfc, 0x46, 0x60, 0x47, 0xa0, 0x30, 0x9f, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 
+0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 
+0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
+0xfc, 0x46, 0x60, 0x47, 0x70, 0x30, 0x9f, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 
+0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 
+0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 
+0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 
+0xfc, 0x46, 0x60, 0x47, 0x34, 0x20, 0x9f, 0xe5, 0x3c, 0x30, 0x9f, 0xe5, 
+0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 
+0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 
+0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 
+0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 
+0x1e, 0xff, 0x2f, 0xe1, 0xf8, 0x00, 0x18, 0x40, 0x04, 0x01, 0x18, 0x40, 
+0x00, 0x01, 0x18, 0x40, 0xfc, 0x00, 0x18, 0x40, 0x02, 0x1c, 0x00, 0x20, 
+0x00, 0x29, 0x07, 0xdd, 0x13, 0x78, 0xc0, 0x18, 0x00, 0x06, 0x00, 0x0e, 
+0x01, 0x32, 0x01, 0x39, 0x00, 0x29, 0xf7, 0xdc, 0x70, 0x47, 0x09, 0x4b, 
+0xc9, 0x18, 0x04, 0x29, 0x08, 0xd8, 0x8c, 0x22, 0x4a, 0x43, 0x07, 0x4b, 
+0xd2, 0x18, 0x13, 0x7a, 0x09, 0x06, 0x09, 0x0e, 0x8b, 0x42, 0x01, 0xd0, 
+0x14, 0x20, 0x70, 0x47, 0x02, 0x60, 0x00, 0x20, 0xfb, 0xe7, 0x00, 0x00, 
+0xf3, 0x0f, 0x01, 0x35, 0xb0, 0x6e, 0x21, 0x40, 0x01, 0x1c, 0x00, 0x22, 
+0x06, 0x48, 0x03, 0x7a, 0xff, 0x2b, 0x04, 0xd0, 0x8c, 0x30, 0x01, 0x32, 
+0x04, 0x2a, 0xf8, 0xd3, 0x01, 0xe0, 0x04, 0x2a, 0x00, 0xd3, 0x00, 0x20, 
+0x0a, 0x60, 0x70, 0x47, 0xb0, 0x6e, 0x21, 0x40, 0xf0, 0xb5, 0x07, 0x1c, 
+0x00, 0x24, 0x00, 0x2f, 0x21, 0xd0, 0x00, 0x26, 0xf8, 0x79, 0x00, 0x28, 
+0x1b, 0xdd, 0x30, 0x01, 0xc0, 0x19, 0xc5, 0x1d, 0x05, 0x35, 0x00, 0x7b, 
+0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0x92, 0xfb, 0x01, 0x1c, 0x8b, 0x68, 
+0x00, 0x2b, 0x08, 0xd0, 0x68, 0x68, 0x00, 0x28, 0x05, 0xd0, 0xca, 0x68, 
+0xa9, 0x68, 0xfb, 0xf7, 0x4a, 0xfb, 0x00, 0x20, 0x68, 0x60, 0x70, 0x1c, 
+0x06, 0x06, 0x36, 0x0e, 0xf8, 0x79, 0xb0, 0x42, 0xe3, 0xdc, 0xff, 0x20, 
+0x38, 0x72, 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, 
+0x81, 0xb0, 0x0f, 0x1c, 0x68, 0x46, 0xff, 0xf7, 0xbd, 0xff, 0x00, 0x28, 
+0x01, 0xd1, 0x0d, 0x20, 0x37, 0xe0, 0xb9, 0x88, 0xc0, 0x46, 0x01, 0x80, 
+0xf9, 0x88, 0xc0, 0x46, 0x41, 0x80, 0xb9, 0x7a, 0xc0, 0x46, 0x41, 0x71, 
+0xf9, 0x7a, 0xc0, 0x46, 0x81, 0x71, 0x8c, 0x21, 0x01, 0x71, 0x3d, 0x7e, 
+0x00, 0x21, 0x00, 0x23, 0x00, 0x2d, 0x1f, 0xdd, 0x1a, 0x01, 0xd2, 0x19, 
+0x1c, 0x32, 0x16, 0x78, 0x05, 0x2e, 0x0d, 0xdc, 0x0c, 0x01, 0x24, 0x18, 
+0x26, 0x73, 0x96, 0x68, 0xc0, 0x46, 0x66, 0x61, 0xd6, 0x68, 0xc0, 0x46, 
+0x26, 0x61, 0x00, 0x24, 0x01, 0x31, 0x09, 0x06, 0x09, 0x0e, 0xd4, 0x60, 
+0x5a, 0x1c, 0x13, 0x06, 0x1b, 0x0e, 0xab, 0x42, 0xe6, 0xdb, 0x00, 0x29, 
+0x04, 0xd0, 0xc1, 0x71, 0x00, 0x99, 0xc0, 0x46, 
+0x01, 0x72, 0x00, 0xe0, 0x00, 0x20, 0x01, 0x99, 0xc0, 0x46, 0x08, 0x60, 
+0x00, 0x20, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 
+0x07, 0x1c, 0x38, 0x7e, 0x00, 0x28, 0x28, 0xd0, 0x01, 0x38, 0x05, 0x06, 
+0x2d, 0x0e, 0x00, 0x26, 0xff, 0x2d, 0x21, 0xd0, 0x28, 0x01, 0xc0, 0x19, 
+0xc4, 0x1d, 0x15, 0x34, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 
+0x1f, 0xfb, 0x01, 0x1c, 0x11, 0xd0, 0x8a, 0x68, 0x00, 0x2a, 0x0c, 0xd0, 
+0xe0, 0x68, 0x00, 0x28, 0x09, 0xd0, 0x00, 0x23, 0xcb, 0x56, 0x05, 0x2b, 
+0x05, 0xdc, 0x13, 0x1c, 0xca, 0x68, 0xa1, 0x68, 0xfb, 0xf7, 0xd1, 0xfa, 
+0xe6, 0x60, 0xff, 0x20, 0x20, 0x70, 0x68, 0x1e, 0x05, 0x06, 0x2d, 0x0e, 
+0xff, 0x2d, 0xdd, 0xd1, 0x3e, 0x76, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x13, 0x20, 0x70, 0x47, 0xf0, 0xb5, 0x82, 0xb0, 0x07, 0x1c, 0xf8, 0x1d, 
+0xd5, 0x30, 0x39, 0x1c, 0xff, 0xf7, 0x7f, 0xff, 0x00, 0x90, 0x00, 0x98, 
+0x00, 0x28, 0x3b, 0xd1, 0x38, 0x7e, 0xc0, 0x46, 0x01, 0x90, 0x00, 0x26, 
+0x01, 0x98, 0x00, 0x28, 0x2d, 0xdd, 0x30, 0x01, 0xc0, 0x19, 0xc5, 0x1d, 
+0x15, 0x35, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0xe4, 0xfa, 
+0x04, 0x1c, 0x20, 0x69, 0x00, 0x28, 0x17, 0xd0, 0x28, 0x78, 0x05, 0x28, 
+0x0d, 0xdd, 0xe9, 0x68, 0xaa, 0x68, 0x60, 0x68, 0x40, 0x08, 0x40, 0x00, 
+0x01, 0xf0, 0x0e, 0xf8, 0x09, 0x22, 0xe8, 0x68, 0xa9, 0x68, 0xfb, 0xf7, 
+0x87, 0xf9, 0x00, 0x20, 0xe8, 0x60, 0x21, 0x69, 0x28, 0x1c, 0xfb, 0xf7, 
+0x8c, 0xfa, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x90, 0x00, 0x98, 0x00, 0x28, 
+0x0c, 0xd1, 0x70, 0x1c, 0x06, 0x06, 0x36, 0x0e, 0x01, 0x98, 0x86, 0x42, 
+0xd1, 0xdb, 0x00, 0x20, 0x38, 0x76, 0x00, 0x98, 0x02, 0xb0, 0xf0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x38, 0x1c, 0xff, 0xf7, 0x82, 0xff, 0xf6, 0xe7, 
+0xc1, 0x1d, 0x79, 0x31, 0x4a, 0x6b, 0xc0, 0x46, 0xca, 0x63, 0xc1, 0x1d, 
+0xb9, 0x31, 0x0a, 0x60, 0x00, 0x22, 0x8a, 0x60, 0x04, 0x4a, 0xc0, 0x46, 
+0x4a, 0x61, 0x8a, 0x61, 0x01, 0x21, 0xd0, 0x30, 0x41, 0x70, 0x08, 0x1c, 
+0x70, 0x47, 0x00, 0x00, 0xb9, 0xbd, 0x21, 0x40, 0xf8, 0xb5, 0x07, 0x1c, 
+0x00, 0x20, 0x00, 0x90, 0xfe, 0x1d, 0xc9, 0x36, 0x30, 0x78, 0x00, 0x01, 
+0xc0, 0x19, 0xc4, 0x1d, 0x15, 0x34, 0x80, 0x6a, 0x45, 0x08, 0x6d, 0x00, 
+0x04, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xb2, 0xfe, 0x31, 0x78, 0x40, 0x18, 
+0x01, 0x06, 0x09, 0x0e, 0x00, 0x20, 0xa2, 0x68, 0x00, 0x2a, 0x0a, 0xd9, 
+0x2a, 0x78, 0x4a, 0x40, 0x2a, 0x70, 0x01, 0x30, 0x09, 0x18, 0x09, 0x06, 
+0x09, 0x0e, 0xa2, 0x68, 0x01, 0x35, 0x82, 0x42, 0xf4, 0xd8, 0xe0, 0x68, 
+0xa1, 0x68, 0x40, 0x08, 0x40, 0x00, 0xff, 0xf7, 0x99, 0xfe, 0x61, 0x78, 
+0x81, 0x42, 0x0a, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x0f, 0xf8, 0xf8, 0x1d, 
+0x79, 0x30, 0x80, 0x6b, 0xf9, 0x1d, 0xb9, 0x31, 0xc8, 0x60, 0x0c, 0x20, 
+0x00, 0x90, 0x30, 0x78, 0x01, 0x30, 0x30, 0x70, 0x00, 0x98, 0xf8, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0xc2, 0x1d, 0xc9, 0x32, 0x11, 0x78, 0x09, 0x01, 
+0x09, 0x18, 0x09, 0x6a, 0xc3, 0x1d, 0x79, 0x33, 0xd9, 0x63, 0x13, 0x78, 
+0x1b, 0x01, 0x1b, 0x18, 0x5b, 0x6a, 0xcb, 0x18, 0xc1, 0x1d, 0xb9, 0x31, 
+0x0b, 0x60, 0x13, 0x78, 0x1b, 0x01, 0x1b, 0x18, 0x9b, 0x6a, 0xc0, 0x46, 
+0x8b, 0x60, 0x07, 0x4b, 0xc0, 0x46, 0x4b, 0x61, 0x12, 0x78, 0x00, 0x7e, 
+0x01, 0x32, 0x82, 0x42, 0x01, 0xdb, 0x04, 0x48, 
+0x00, 0xe0, 0x04, 0x48, 0xc0, 0x46, 0x88, 0x61, 0x00, 0x20, 0x70, 0x47, 
+0x81, 0xbe, 0x21, 0x40, 0x55, 0xbe, 0x21, 0x40, 0x01, 0xbf, 0x21, 0x40, 
+0xf8, 0xb5, 0x04, 0x1c, 0x00, 0x20, 0x00, 0x90, 0x25, 0x7e, 0x29, 0x01, 
+0xe0, 0x1d, 0x15, 0x30, 0xff, 0xf7, 0x4e, 0xfe, 0xa1, 0x7e, 0x81, 0x42, 
+0x0a, 0xd0, 0x20, 0x1c, 0x00, 0xf0, 0x61, 0xf8, 0xe0, 0x1d, 0x79, 0x30, 
+0x80, 0x6b, 0xe1, 0x1d, 0xb9, 0x31, 0xc8, 0x60, 0x0b, 0x20, 0x55, 0xe0, 
+0x00, 0x27, 0x00, 0x2d, 0x0f, 0xdd, 0x38, 0x01, 0x00, 0x19, 0x00, 0x7f, 
+0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 0x10, 0xfa, 0x00, 0x28, 0x01, 0xd1, 
+0x09, 0x20, 0x47, 0xe0, 0x78, 0x1c, 0x07, 0x06, 0x3f, 0x0e, 0xaf, 0x42, 
+0xef, 0xdb, 0x00, 0x26, 0x00, 0x2d, 0x38, 0xdd, 0x30, 0x01, 0x00, 0x19, 
+0xc7, 0x1d, 0x15, 0x37, 0x00, 0x7f, 0x00, 0x06, 0x00, 0x16, 0x00, 0xf0, 
+0xfb, 0xf9, 0x00, 0x23, 0xc1, 0x56, 0x05, 0x29, 0x0c, 0xdc, 0x42, 0x68, 
+0x00, 0x2a, 0x04, 0xd0, 0xc1, 0x68, 0xb8, 0x68, 0xfb, 0xf7, 0xb2, 0xf9, 
+0xf8, 0x60, 0xf8, 0x68, 0x00, 0x28, 0x1b, 0xd1, 0x0e, 0x20, 0x17, 0xe0, 
+0xc0, 0x68, 0x00, 0x28, 0x07, 0xd0, 0xfb, 0xf7, 0xa5, 0xf9, 0x00, 0x28, 
+0x05, 0xda, 0x40, 0x42, 0xb9, 0x68, 0x81, 0x42, 0x04, 0xd0, 0x05, 0x20, 
+0x0a, 0xe0, 0xb9, 0x68, 0x81, 0x42, 0xfa, 0xd8, 0x09, 0x21, 0xb8, 0x68, 
+0xfb, 0xf7, 0x7a, 0xf8, 0xf8, 0x60, 0x00, 0x28, 0x02, 0xd1, 0x06, 0x20, 
+0x00, 0x90, 0x07, 0xe0, 0x70, 0x1c, 0x06, 0x06, 0x36, 0x0e, 0xae, 0x42, 
+0xc6, 0xdb, 0x00, 0x98, 0x00, 0x28, 0x02, 0xd0, 0x20, 0x1c, 0xff, 0xf7, 
+0x92, 0xfe, 0x00, 0x98, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xc2, 0x1d, 
+0x79, 0x32, 0x41, 0x69, 0xc0, 0x46, 0xd1, 0x63, 0x02, 0x7e, 0x12, 0x01, 
+0x8a, 0x18, 0xc1, 0x1d, 0xb9, 0x31, 0x0a, 0x60, 0xc2, 0x1d, 0x15, 0x32, 
+0x8a, 0x60, 0x05, 0x4a, 0xc0, 0x46, 0x4a, 0x61, 0x04, 0x4a, 0xc0, 0x46, 
+0x8a, 0x61, 0x00, 0x21, 0xd0, 0x30, 0x01, 0x70, 0x08, 0x1c, 0x70, 0x47, 
+0x59, 0xbf, 0x21, 0x40, 0x01, 0xbf, 0x21, 0x40, 0x90, 0xb5, 0x07, 0x1c, 
+0x38, 0x68, 0x1d, 0x4b, 0x98, 0x42, 0x03, 0xd0, 0x03, 0x20, 0x90, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x1c, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xbc, 0xfd, 
+0xfc, 0x1d, 0x79, 0x34, 0x00, 0x28, 0x09, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 
+0x2d, 0xf8, 0xf9, 0x1d, 0xb9, 0x31, 0xa0, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 
+0x0a, 0x20, 0xea, 0xe7, 0x38, 0x7a, 0x1c, 0x28, 0x04, 0xd0, 0x78, 0x7a, 
+0x10, 0x28, 0x01, 0xd0, 0x04, 0x20, 0xe2, 0xe7, 0xb8, 0x7a, 0x01, 0x28, 
+0x01, 0xd0, 0x07, 0x20, 0xdd, 0xe7, 0x60, 0x6b, 0xf9, 0x68, 0x88, 0x42, 
+0x01, 0xd0, 0x05, 0x20, 0xd7, 0xe7, 0x38, 0x69, 0x00, 0x28, 0x04, 0xd0, 
+0x06, 0x4b, 0x98, 0x42, 0x01, 0xd0, 0x08, 0x20, 0xcf, 0xe7, 0x38, 0x7e, 
+0x08, 0x28, 0x01, 0xdd, 0x12, 0x20, 0xca, 0xe7, 0x00, 0x20, 0xc8, 0xe7, 
+0x73, 0x6e, 0x69, 0x70, 0x17, 0x40, 0x00, 0x02, 0xb8, 0xb5, 0x07, 0x1c, 
+0x38, 0x1c, 0xff, 0xf7, 0x2a, 0xfe, 0x00, 0x25, 0xf8, 0x1d, 0xc9, 0x30, 
+0x45, 0x70, 0xfc, 0x1d, 0xb9, 0x34, 0xe5, 0x61, 0x68, 0x46, 0xff, 0xf7, 
+0x9d, 0xfd, 0x00, 0x28, 0x01, 0xd1, 0x0d, 0x20, 0x0d, 0xe0, 0xf8, 0x1d, 
+0x79, 0x30, 0x85, 0x63, 0xc5, 0x63, 0x1b, 0x20, 0x20, 0x60, 0xa7, 0x60, 
+0x04, 0x48, 0xc0, 0x46, 0x60, 0x61, 0x04, 0x48, 0xc0, 0x46, 0xa0, 0x61, 
+0x28, 0x1c, 0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0x75, 0xc0, 0x21, 0x40, 0x3b, 0xc0, 0x21, 0x40, 0xf0, 0xb5, 0x82, 0xb0, 
+0x07, 0x1c, 0x00, 0x20, 0xfd, 0x1d, 0x79, 0x35, 0xfc, 0x1d, 0xb9, 0x34, 
+0xe9, 0x6a, 0xc0, 0x46, 0x61, 0x60, 0x62, 0x68, 0xe9, 0x6b, 0x8a, 0x42, 
+0x03, 0xd2, 0x61, 0x60, 0x2a, 0x6b, 0x91, 0x42, 0x34, 0xd2, 0x66, 0x68, 
+0xc0, 0x46, 0x01, 0x96, 0xe9, 0x6b, 0x73, 0x1a, 0xe9, 0x6a, 0x71, 0x1a, 
+0x26, 0x68, 0x2a, 0x6b, 0x96, 0x42, 0x00, 0xd2, 0x32, 0x1c, 0x01, 0x9e, 
+0x96, 0x1b, 0xa2, 0x68, 0xc0, 0x46, 0x00, 0x92, 0x00, 0x2a, 0x09, 0xd0, 
+0x28, 0x6a, 0x6a, 0x6a, 0x41, 0x18, 0x00, 0x98, 0xc0, 0x18, 0x33, 0x1c, 
+0xfc, 0xf7, 0xc4, 0xff, 0x00, 0x28, 0x1b, 0xd1, 0x61, 0x68, 0x89, 0x19, 
+0x61, 0x60, 0x22, 0x68, 0x91, 0x42, 0x0d, 0xd1, 0x61, 0x69, 0x38, 0x1c, 
+0xfb, 0xf7, 0xc1, 0xf8, 0x00, 0x06, 0x00, 0x0e, 0x0e, 0xd1, 0xa1, 0x69, 
+0x38, 0x1c, 0xfb, 0xf7, 0xba, 0xf8, 0x00, 0x06, 0x00, 0x0e, 0x07, 0xd1, 
+0x61, 0x68, 0x2a, 0x6b, 0x91, 0x42, 0xc2, 0xd3, 0xa9, 0x6b, 0xaa, 0x6a, 
+0x89, 0x18, 0xa9, 0x63, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0xb0, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfb, 0xf7, 
+0xbf, 0xfa, 0xfa, 0x1d, 0x09, 0x32, 0x32, 0x48, 0x00, 0x21, 0xc9, 0x43, 
+0xc4, 0x1d, 0xb9, 0x34, 0xe1, 0x60, 0xf9, 0x88, 0xc3, 0x1d, 0x89, 0x33, 
+0x19, 0x73, 0xc1, 0x1d, 0x79, 0x31, 0xbd, 0x68, 0xc0, 0x46, 0x0d, 0x62, 
+0xff, 0x68, 0xc0, 0x46, 0x4f, 0x62, 0x17, 0x68, 0xc0, 0x46, 0x8f, 0x62, 
+0x57, 0x68, 0xc0, 0x46, 0xcf, 0x62, 0x92, 0x68, 0xc0, 0x46, 0x4a, 0x63, 
+0xca, 0x6a, 0x8f, 0x6a, 0xd2, 0x19, 0x0a, 0x63, 0x1a, 0x7b, 0x01, 0x2a, 
+0x0d, 0xd0, 0x02, 0x2a, 0x1a, 0xd0, 0x03, 0x2a, 0x2e, 0xd1, 0xc2, 0x1d, 
+0xc9, 0x32, 0x52, 0x78, 0x00, 0x2a, 0x07, 0xd1, 0x10, 0x20, 0x89, 0x6b, 
+0xc0, 0x46, 0xe1, 0x60, 0x25, 0xe0, 0xff, 0xf7, 0x4d, 0xff, 0x22, 0xe0, 
+0xff, 0xf7, 0xac, 0xfd, 0x00, 0x28, 0x1e, 0xd1, 0xe1, 0x69, 0x00, 0x29, 
+0x1b, 0xd0, 0x09, 0x7a, 0x15, 0x4b, 0xc9, 0x18, 0x02, 0x91, 0x16, 0xe0, 
+0x8a, 0x6a, 0xcb, 0x6a, 0x9f, 0x18, 0x4d, 0x6b, 0xaf, 0x42, 0x05, 0xd8, 
+0x00, 0x2a, 0x03, 0xd0, 0x9f, 0x07, 0x01, 0xd1, 0x92, 0x07, 0x01, 0xd0, 
+0x0f, 0x20, 0x08, 0xe0, 0x89, 0x6b, 0x99, 0x42, 0x01, 0xd0, 0xe1, 0x60, 
+0xf8, 0xe7, 0xff, 0xf7, 0x53, 0xff, 0x00, 0xe0, 0x10, 0x20, 0x01, 0xab, 
+0x58, 0x80, 0xe0, 0x68, 0xc0, 0x46, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 
+0xfb, 0xf7, 0x9e, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x3c, 0xac, 0x20, 0x40, 0x0d, 0xf0, 0xfe, 0xca, 
+0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, 
+0x4d, 0xfa, 0x68, 0x46, 0xb9, 0x68, 0xff, 0xf7, 0xa0, 0xfc, 0x00, 0x28, 
+0x02, 0xd1, 0x00, 0x98, 0xff, 0xf7, 0xc4, 0xfc, 0x02, 0xab, 0x58, 0x80, 
+0x00, 0x21, 0x01, 0xa8, 0xfb, 0xf7, 0x7e, 0xf9, 0x01, 0x20, 0x05, 0xb0, 
+0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 
+0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, 0x32, 0xfa, 0x68, 0x46, 0xb9, 0x68, 
+0xff, 0xf7, 0x85, 0xfc, 0x00, 0x28, 0x00, 0xd1, 0x02, 0x20, 0x02, 0xab, 
+0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfb, 0xf7, 0x65, 0xf9, 0x01, 0x20, 
+0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x85, 0xb0, 
+0x07, 0x1c, 0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, 
+0x19, 0xfa, 0x3c, 0x69, 0x38, 0x1c, 0x01, 0xa9, 0xfb, 0xf7, 0x14, 0xfa, 
+0x68, 0x46, 0x21, 0x1c, 0xff, 0xf7, 0x67, 0xfc, 0x8c, 0x24, 0x00, 0x28, 
+0x0e, 0xd1, 0xb9, 0x68, 0x00, 0x29, 0x02, 0xd1, 0xfa, 0x68, 0x00, 0x2a, 
+0x08, 0xd0, 0xf8, 0x88, 0x23, 0x1c, 0x8c, 0x28, 0x00, 0xd8, 0x03, 0x1c, 
+0xf8, 0x68, 0x00, 0x9a, 0xfc, 0xf7, 0x38, 0xfe, 0x02, 0xab, 0x58, 0x80, 
+0x03, 0x94, 0x00, 0x21, 0x01, 0xa8, 0xfb, 0xf7, 0x37, 0xf9, 0x01, 0x20, 
+0x05, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x21, 0x04, 0x48, 
+0xff, 0x22, 0x02, 0x72, 0x8c, 0x30, 0x01, 0x31, 0x04, 0x29, 0xfa, 0xd3, 
+0x70, 0x47, 0x00, 0x00, 0xb0, 0x6e, 0x21, 0x40, 0x02, 0x48, 0x03, 0x49, 
+0x40, 0x1a, 0x40, 0x42, 0x70, 0x47, 0x00, 0x00, 0xb9, 0xce, 0x21, 0x40, 
+0xb5, 0xce, 0x21, 0x40, 0x00, 0x21, 0x08, 0x4a, 0x8b, 0x00, 0x5b, 0x18, 
+0x9b, 0x00, 0xd3, 0x56, 0x83, 0x42, 0x04, 0xd1, 0x88, 0x00, 0x40, 0x18, 
+0x80, 0x00, 0x80, 0x18, 0x70, 0x47, 0x01, 0x31, 0x01, 0x29, 0xf1, 0xd3, 
+0x00, 0x20, 0xf9, 0xe7, 0xe0, 0x70, 0x21, 0x40, 0x80, 0xb5, 0x00, 0xf0, 
+0x0c, 0xf8, 0x00, 0x27, 0x38, 0x1c, 0x00, 0xf0, 0x45, 0xf8, 0x78, 0x1c, 
+0x07, 0x04, 0x3f, 0x0c, 0x0c, 0x2f, 0xf7, 0xdd, 0x80, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x1c, 0x48, 0x02, 0x68, 0x1c, 0x49, 0x8b, 0x69, 0xd2, 0x18, 
+0x02, 0x60, 0x8a, 0x6a, 0x43, 0x68, 0x9b, 0x18, 0x43, 0x60, 0x93, 0x42, 
+0x02, 0xd2, 0x82, 0x68, 0x01, 0x32, 0x82, 0x60, 0xc2, 0x68, 0x0b, 0x6a, 
+0xd2, 0x18, 0xc2, 0x60, 0x42, 0x69, 0xcb, 0x68, 0xd2, 0x18, 0x42, 0x61, 
+0xc2, 0x69, 0x8b, 0x68, 0xd2, 0x18, 0xc2, 0x61, 0x02, 0x69, 0x0b, 0x69, 
+0xd2, 0x18, 0x02, 0x61, 0x82, 0x69, 0x0b, 0x68, 0xd2, 0x18, 0x82, 0x61, 
+0x02, 0x6b, 0xcb, 0x69, 0xd2, 0x18, 0x02, 0x63, 0x4a, 0x6a, 0x43, 0x6b, 
+0x9b, 0x18, 0x43, 0x63, 0x93, 0x42, 0x02, 0xd2, 0x82, 0x6b, 0x01, 0x32, 
+0x82, 0x63, 0xc2, 0x6b, 0x4b, 0x69, 0xd2, 0x18, 0xc2, 0x63, 0x02, 0x6c, 
+0xc9, 0x6a, 0x51, 0x18, 0x01, 0x64, 0x70, 0x47, 0x10, 0x2a, 0x00, 0x80, 
+0x00, 0x08, 0x14, 0x40, 0x88, 0xb5, 0x69, 0x46, 0x00, 0xf0, 0x17, 0xf8, 
+0x81, 0x08, 0x0a, 0xd0, 0x00, 0x20, 0x00, 0x29, 0x07, 0xd9, 0x00, 0x22, 
+0x83, 0x00, 0x00, 0x9f, 0xc0, 0x46, 0xfa, 0x50, 0x01, 0x30, 0x88, 0x42, 
+0xf8, 0xd3, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0, 
+0x04, 0xf8, 0x00, 0x04, 0x00, 0x0c, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x22, 
+0x00, 0x28, 0x0a, 0xd0, 0x01, 0x28, 0x0a, 0xd0, 0x02, 0x28, 0x0c, 0xd0, 
+0x03, 0x28, 0x02, 0xd1, 0x07, 0x48, 0x1c, 0x22, 0x08, 0x60, 0x10, 0x1c, 
+0x70, 0x47, 0x06, 0x48, 0x04, 0xe0, 0x06, 0x48, 0x50, 0x22, 0x08, 0x60, 
+0xf7, 0xe7, 0x05, 0x48, 0x68, 0x22, 0x08, 0x60, 0xf3, 0xe7, 0x00, 0x00, 
+0x08, 0x83, 0x20, 0x40, 0x10, 0x2a, 0x00, 0x80, 0x78, 0x2a, 0x00, 0x80, 
+0xa0, 0x82, 0x20, 0x40, 0x98, 0xb5, 0x00, 0x27, 0x68, 0x46, 0xfe, 0xf7, 
+0xa7, 0xfb, 0x10, 0x4c, 0x00, 0x28, 0x0b, 0xd0, 0x00, 0xf0, 0x3e, 0xf8, 
+0x00, 0x28, 0x07, 0xd0, 0x01, 0x27, 0x10, 0x23, 0x20, 0x68, 0x18, 0x43, 
+0x20, 0x60, 0x60, 0x68, 0x18, 0x43, 0x0b, 0xe0, 0x10, 0x23, 0xa0, 0x68, 
+0x98, 0x43, 0xa0, 0x60, 0x20, 0x69, 0x98, 0x43, 0x20, 0x61, 0x20, 0x68, 
+0x98, 0x43, 0x20, 0x60, 0x60, 0x68, 0x98, 0x43, 0x60, 0x60, 0x38, 0x1c, 
+0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 
+0xe8, 0x18, 0x00, 0x80, 0x00, 0xb5, 0x00, 0xf0, 0xb5, 0xfc, 0xfe, 0xf7, 
+0xc5, 0xfb, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x14, 0x24, 
+0x00, 0x25, 0x00, 0x27, 0x08, 0x4e, 0x02, 0x20, 0x21, 0x1c, 0x32, 0x1c, 
+0xfa, 0xf7, 0xec, 0xfe, 0x78, 0x40, 0x07, 0x04, 0x3f, 0x0c, 0x02, 0x34, 
+0x01, 0x35, 0x03, 0x2d, 0xf3, 0xd3, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x39, 0xb7, 0x21, 0x40, 0x90, 0xb5, 0x01, 0x24, 
+0x20, 0x1c, 0x10, 0x49, 0xc9, 0x68, 0x01, 0x29, 0x00, 0xd0, 0x00, 0x20, 
+0x00, 0x06, 0x00, 0x0e, 0x16, 0xd0, 0x0d, 0x4a, 0x3a, 0x21, 0x02, 0x20, 
+0xfa, 0xf7, 0xce, 0xfe, 0x07, 0x04, 0x3f, 0x0c, 0x03, 0xd1, 0x00, 0x20, 
+0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0xf7, 0xcf, 0xff, 0xc0, 0x43, 
+0x00, 0x04, 0x00, 0x0c, 0xb8, 0x42, 0x00, 0xd0, 0x00, 0x24, 0x20, 0x06, 
+0x00, 0x0e, 0xf1, 0xe7, 0x20, 0x1c, 0xef, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 
+0x39, 0xb7, 0x21, 0x40, 0xb0, 0xb5, 0x01, 0x27, 0x3a, 0x1c, 0x18, 0x4b, 
+0xdb, 0x68, 0x01, 0x2b, 0x00, 0xd0, 0x00, 0x22, 0x12, 0x06, 0x12, 0x0e, 
+0x00, 0x24, 0x00, 0x2a, 0x23, 0xd0, 0x14, 0x4a, 0x53, 0x68, 0x1b, 0x04, 
+0x1b, 0x0c, 0x1d, 0x02, 0x1b, 0x12, 0x2b, 0x43, 0x92, 0x68, 0x12, 0x04, 
+0x12, 0x0c, 0x15, 0x02, 0x12, 0x12, 0x2a, 0x43, 0x12, 0x04, 0x12, 0x0c, 
+0x1b, 0x04, 0x1a, 0x43, 0x51, 0x40, 0x01, 0x31, 0x0f, 0xd1, 0x00, 0x28, 
+0x02, 0xd0, 0xff, 0xf7, 0x9b, 0xff, 0xc4, 0x43, 0x22, 0x04, 0x12, 0x0c, 
+0x07, 0x4b, 0x3a, 0x21, 0x02, 0x20, 0xfa, 0xf7, 0x8a, 0xfe, 0x38, 0x1c, 
+0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x20, 0x1c, 0xfa, 0xe7, 0x00, 0x00, 
+0xe8, 0x0d, 0x00, 0x80, 0x40, 0x00, 0x14, 0x40, 0x7b, 0xb7, 0x21, 0x40, 
+0x80, 0xb4, 0x03, 0x22, 0xc2, 0x80, 0x15, 0x4a, 0xc0, 0x46, 0x82, 0x60, 
+0x14, 0x4a, 0x12, 0x88, 0x01, 0x32, 0xc2, 0x60, 0x00, 0x20, 0x13, 0x4a, 
+0x13, 0x5c, 0xc0, 0x46, 0x0b, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 
+0xf8, 0xd3, 0x20, 0x22, 0x0a, 0x70, 0x01, 0x31, 0x00, 0x20, 0x0e, 0x4b, 
+0x1f, 0x5c, 0xc0, 0x46, 0x0f, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 
+0xf8, 0xd3, 0x0a, 0x70, 0x01, 0x31, 0x00, 0x20, 0x09, 0x4a, 0x13, 0x5c, 
+0xc0, 0x46, 0x0b, 0x70, 0x01, 0x30, 0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, 
+0x00, 0x20, 0x08, 0x70, 0x80, 0xbc, 0x70, 0x47, 0x17, 0x40, 0x00, 0x02, 
+0xe8, 0x0d, 0x00, 0x80, 0xfc, 0x03, 0x00, 0x80, 0x05, 0x04, 0x00, 0x80, 
+0x0e, 0x04, 0x00, 0x80, 0xf0, 0xb5, 0x01, 0x21, 0x45, 0x4d, 0xe8, 0x1d, 
+0x79, 0x30, 0x41, 0x73, 0x01, 0x73, 0x64, 0x22, 0x42, 0x82, 0x82, 0x82, 
+0xc1, 0x82, 0x7d, 0x21, 0xc9, 0x00, 0x01, 0x83, 0x00, 0x21, 0x41, 0x83, 
+0x3f, 0x48, 0x01, 0x22, 0x00, 0xf0, 0x08, 0xfb, 0x00, 0x26, 0xf6, 0x43, 
+0x3d, 0x4c, 0xe7, 0x1d, 0x39, 0x37, 0xb0, 0x42, 0x07, 0xd1, 0xf8, 0x88, 
+0x01, 0x30, 0xf8, 0x80, 0xa0, 0x79, 0x01, 0x30, 0xa0, 0x71, 0xfc, 0xf7, 
+0xb3, 0xfd, 0x38, 0x48, 0x02, 0x22, 0x00, 0x21, 0x00, 0xf0, 0xf4, 0xfa, 
+0xb0, 0x42, 0x07, 0xd1, 0xf8, 0x88, 0x01, 0x30, 0xf8, 0x80, 0xa0, 0x79, 
+0x01, 0x30, 0xa0, 0x71, 0xfc, 0xf7, 0xa4, 0xfd, 0xe8, 0x68, 0x2f, 0x1c, 
+0x01, 0x28, 0x05, 0xd1, 0x2f, 0x48, 0x7d, 0x22, 0xd2, 0x00, 0x00, 0x21, 
+0x00, 0xf0, 0xe0, 0xfa, 0x2d, 0x4d, 0x28, 0x1c, 0xfa, 0xf7, 0x02, 0xfe, 
+0x2c, 0x48, 0xfa, 0xf7, 0xff, 0xfd, 0x2c, 0x48, 
+0xfa, 0xf7, 0xfc, 0xfd, 0x2b, 0x4e, 0x71, 0x23, 0x5b, 0x01, 0xfc, 0x18, 
+0x2a, 0x4f, 0x20, 0x79, 0x00, 0x28, 0x0f, 0xd0, 0x28, 0x1c, 0xfa, 0xf7, 
+0xf1, 0xfd, 0x38, 0x1c, 0xfa, 0xf7, 0xee, 0xfd, 0x00, 0x28, 0x04, 0xd0, 
+0x38, 0x1c, 0xfa, 0xf7, 0xe9, 0xfd, 0x00, 0x28, 0xfa, 0xd1, 0x30, 0x1c, 
+0xfa, 0xf7, 0xe4, 0xfd, 0x60, 0x79, 0x00, 0x28, 0x23, 0xd0, 0x28, 0x1c, 
+0xfa, 0xf7, 0xde, 0xfd, 0x38, 0x1c, 0xfa, 0xf7, 0xdb, 0xfd, 0x00, 0x28, 
+0x04, 0xd0, 0x38, 0x1c, 0xfa, 0xf7, 0xd6, 0xfd, 0x00, 0x28, 0xfa, 0xd1, 
+0x19, 0x49, 0x01, 0x22, 0x12, 0x04, 0x08, 0x68, 0x02, 0x40, 0x14, 0x20, 
+0x00, 0x2a, 0x05, 0xd1, 0x0a, 0x68, 0x12, 0x0c, 0x06, 0xd1, 0x09, 0x68, 
+0x89, 0x0a, 0x03, 0xd3, 0x13, 0x49, 0xc0, 0x46, 0xc8, 0x60, 0x03, 0xe0, 
+0x12, 0x49, 0xc0, 0x46, 0x08, 0x64, 0xff, 0xe7, 0xfe, 0xe7, 0xff, 0xf7, 
+0x1e, 0xfe, 0x10, 0x48, 0xfa, 0xf7, 0xb8, 0xfd, 0x0f, 0x48, 0xfa, 0xf7, 
+0xb5, 0xfd, 0xbc, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 0x5d, 0x22, 0xff, 0xff, 
+0xa0, 0x82, 0x20, 0x40, 0x21, 0x21, 0xff, 0xff, 0x59, 0x7e, 0x21, 0x40, 
+0xf4, 0x01, 0xff, 0xff, 0x09, 0x2c, 0xff, 0xff, 0x04, 0x02, 0xff, 0xff, 
+0x00, 0x00, 0xff, 0xff, 0xb5, 0x07, 0xff, 0xff, 0x00, 0x00, 0x10, 0x40, 
+0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x65, 0xa8, 0x21, 0x40, 
+0x48, 0x57, 0xff, 0xff, 0x00, 0xb5, 0x10, 0x20, 0x0f, 0x49, 0xc0, 0x46, 
+0x08, 0x60, 0x0f, 0x4a, 0x0f, 0x48, 0x64, 0x21, 0xfa, 0xf7, 0x8e, 0xfd, 
+0x0e, 0x48, 0x01, 0x22, 0x12, 0x04, 0x01, 0x68, 0x0a, 0x40, 0x08, 0x21, 
+0x00, 0x2a, 0x05, 0xd1, 0x02, 0x68, 0x12, 0x0c, 0x07, 0xd1, 0x00, 0x68, 
+0x80, 0x0a, 0x04, 0xd3, 0x08, 0x48, 0xc0, 0x46, 0xc1, 0x60, 0x08, 0xbc, 
+0x18, 0x47, 0x07, 0x48, 0xc0, 0x46, 0x01, 0x64, 0xf9, 0xe7, 0x00, 0x00, 
+0x00, 0x00, 0x00, 0xb0, 0x25, 0x55, 0xff, 0xff, 0xf8, 0x28, 0x00, 0x80, 
+0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 
+0xb0, 0xb5, 0x24, 0x4f, 0x01, 0x21, 0x09, 0x04, 0x38, 0x68, 0x01, 0x40, 
+0x06, 0x20, 0x22, 0x4d, 0x22, 0x4c, 0x00, 0x29, 0x05, 0xd1, 0x39, 0x68, 
+0x09, 0x0c, 0x04, 0xd1, 0x39, 0x68, 0x89, 0x0a, 0x01, 0xd3, 0xe8, 0x60, 
+0x00, 0xe0, 0x20, 0x64, 0x03, 0x20, 0xfe, 0xf7, 0xc5, 0xfa, 0xfb, 0xf7, 
+0xa1, 0xf9, 0x01, 0x23, 0x18, 0x43, 0xfb, 0xf7, 0x6b, 0xfa, 0x00, 0xf0, 
+0x31, 0xf8, 0x01, 0x21, 0x09, 0x04, 0x38, 0x68, 0x01, 0x40, 0x07, 0x20, 
+0x00, 0x29, 0x05, 0xd1, 0x39, 0x68, 0x09, 0x0c, 0x04, 0xd1, 0x39, 0x68, 
+0x89, 0x0a, 0x01, 0xd3, 0xe8, 0x60, 0x00, 0xe0, 0x20, 0x64, 0x00, 0xf0, 
+0x89, 0xf8, 0x00, 0xf0, 0x69, 0xf8, 0x00, 0xf0, 0xd3, 0xf8, 0x01, 0x21, 
+0x09, 0x04, 0x38, 0x68, 0x01, 0x40, 0x09, 0x20, 0x00, 0x29, 0x05, 0xd1, 
+0x39, 0x68, 0x09, 0x0c, 0x04, 0xd1, 0x39, 0x68, 0x89, 0x0a, 0x01, 0xd3, 
+0xe8, 0x60, 0x00, 0xe0, 0x20, 0x64, 0xff, 0xf7, 0xdf, 0xfe, 0xb0, 0xbc, 
+0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00, 
+0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x21, 0x48, 0xfa, 0xf7, 0x14, 0xfd, 
+0xfd, 0xf7, 0x4a, 0xf8, 0x00, 0xf0, 0xa6, 0xf8, 0xfd, 0xf7, 0x58, 0xf8, 
+0x00, 0xf0, 0xc0, 0xf8, 0xfc, 0xf7, 0x9f, 0xfc, 0xff, 0xf7, 0x5c, 0xfd, 
+0xfd, 0xf7, 0x3c, 0xfa, 0xfd, 0xf7, 0xc4, 0xf9, 0xfd, 0xf7, 0xdc, 0xfa, 
+0xfd, 0xf7, 0x60, 0xf9, 0xfd, 0xf7, 0x1a, 0xf9, 
+0xfd, 0xf7, 0xa2, 0xf9, 0x00, 0xf0, 0x8a, 0xf9, 0xfd, 0xf7, 0xb6, 0xfb, 
+0xfd, 0xf7, 0x24, 0xfb, 0xfd, 0xf7, 0xec, 0xfa, 0xfd, 0xf7, 0x46, 0xf8, 
+0xfa, 0xf7, 0xf2, 0xfb, 0xff, 0xf7, 0x18, 0xfd, 0x00, 0x20, 0xff, 0xf7, 
+0xef, 0xfd, 0x00, 0xf0, 0x29, 0xf8, 0x00, 0x20, 0x0a, 0x49, 0x71, 0x23, 
+0x5b, 0x01, 0xca, 0x18, 0x10, 0x71, 0x50, 0x71, 0x07, 0x23, 0x5b, 0x02, 
+0xc9, 0x18, 0xc8, 0x62, 0x06, 0x49, 0xc0, 0x46, 0x48, 0x62, 0x00, 0xf0, 
+0x87, 0xf9, 0x05, 0x48, 0xfa, 0xf7, 0xd6, 0xfc, 0x08, 0xbc, 0x18, 0x47, 
+0xff, 0xb8, 0x21, 0x40, 0xe8, 0x0d, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x00, 
+0x31, 0x98, 0x21, 0x40, 0x00, 0xb5, 0x04, 0x48, 0xfa, 0xf7, 0xc8, 0xfc, 
+0xfd, 0xf7, 0x7c, 0xfb, 0xfd, 0xf7, 0x34, 0xf8, 0x08, 0xbc, 0x18, 0x47, 
+0x11, 0xa2, 0x21, 0x40, 0x00, 0xb5, 0xfd, 0xf7, 0x81, 0xfa, 0x06, 0x48, 
+0xfa, 0xf7, 0xba, 0xfc, 0xfd, 0xf7, 0x56, 0xfa, 0xfd, 0xf7, 0x8c, 0xfb, 
+0xfd, 0xf7, 0x9e, 0xfb, 0xfd, 0xf7, 0xac, 0xfb, 0x08, 0xbc, 0x18, 0x47, 
+0x91, 0x03, 0xff, 0xff, 0xf8, 0xb5, 0x1a, 0x48, 0xc1, 0x6b, 0xff, 0x29, 
+0xfc, 0xd1, 0x81, 0x6b, 0x42, 0x6b, 0x0d, 0x1c, 0x16, 0x1c, 0x17, 0x4c, 
+0x10, 0x23, 0x60, 0x69, 0x18, 0x43, 0x60, 0x61, 0xa1, 0x69, 0x99, 0x43, 
+0x1f, 0x04, 0xa1, 0x61, 0xf8, 0x60, 0xa0, 0x69, 0xc0, 0x46, 0x38, 0x61, 
+0x11, 0x4a, 0x12, 0x49, 0x64, 0x20, 0xfa, 0xf7, 0x95, 0xfc, 0x11, 0x4a, 
+0xc0, 0x46, 0x00, 0x92, 0x10, 0x4b, 0x00, 0x20, 0x29, 0x1c, 0x32, 0x1c, 
+0xfa, 0xf7, 0x94, 0xfc, 0x0e, 0x48, 0xc1, 0x68, 0x08, 0x29, 0xfc, 0xd1, 
+0x10, 0x23, 0x60, 0x69, 0x98, 0x43, 0x60, 0x61, 0xf8, 0x60, 0x01, 0x20, 
+0xe3, 0x23, 0x1b, 0x01, 0xe1, 0x18, 0xc8, 0x70, 0xf8, 0xbc, 0x08, 0xbc, 
+0x18, 0x47, 0x00, 0x00, 0x00, 0x01, 0x18, 0x40, 0xe8, 0x0d, 0x00, 0x80, 
+0xa0, 0x54, 0xff, 0xff, 0x11, 0xc8, 0x21, 0x40, 0x64, 0x00, 0x30, 0x02, 
+0x44, 0x80, 0x20, 0x40, 0x40, 0x01, 0x18, 0x40, 0xfa, 0x21, 0x03, 0x48, 
+0xc0, 0x46, 0x41, 0x62, 0x40, 0x21, 0x41, 0x62, 0x70, 0x47, 0x00, 0x00, 
+0xc0, 0x00, 0x18, 0x00, 0x07, 0x48, 0x41, 0x69, 0x07, 0x4b, 0x19, 0x43, 
+0x41, 0x61, 0x82, 0x69, 0x9a, 0x43, 0x82, 0x61, 0x01, 0x22, 0x12, 0x05, 
+0xd1, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x10, 0x61, 0x70, 0x47, 0x00, 0x00, 
+0xe8, 0x0d, 0x00, 0x80, 0xfe, 0xaf, 0x9a, 0x10, 0xf0, 0xb4, 0x4b, 0x4a, 
+0x4b, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x4b, 0x4d, 0x4b, 0x4b, 0x98, 0x42, 
+0x02, 0xd0, 0x01, 0x33, 0x98, 0x42, 0x01, 0xd1, 0x01, 0x20, 0x28, 0x80, 
+0x01, 0x21, 0xc9, 0x03, 0x19, 0x23, 0xdb, 0x01, 0xec, 0x18, 0x61, 0x61, 
+0x28, 0x88, 0x40, 0x04, 0x44, 0x4b, 0xc0, 0x18, 0x87, 0x1a, 0x06, 0x20, 
+0xaf, 0x60, 0x43, 0x4e, 0xc0, 0x46, 0xb0, 0x61, 0x20, 0x20, 0xc8, 0x23, 
+0x43, 0x43, 0xbb, 0x42, 0x21, 0xd9, 0x41, 0x00, 0x3e, 0x4e, 0xc0, 0x46, 
+0x31, 0x61, 0xb6, 0x69, 0x20, 0x23, 0x9b, 0x1b, 0x3b, 0x4e, 0xc0, 0x46, 
+0xf3, 0x61, 0x10, 0x3b, 0x33, 0x62, 0x8b, 0x00, 0xff, 0x1a, 0x40, 0x08, 
+0x81, 0x42, 0x17, 0xd3, 0xb8, 0x23, 0x43, 0x43, 0xbb, 0x42, 0x08, 0xd9, 
+0x41, 0x1e, 0x34, 0x4b, 0xc0, 0x46, 0x99, 0x81, 0xd9, 0x81, 0x40, 0x00, 
+0x02, 0x38, 0x58, 0x61, 0x0a, 0xe0, 0x01, 0x30, 0x81, 0x42, 0xef, 0xd2, 
+0x06, 0xe0, 0x2e, 0x4e, 0xb3, 0x69, 0x01, 0x33, 0xb3, 0x61, 0x40, 0x00, 
+0x88, 0x42, 0xd2, 0xd9, 0x2b, 0x49, 0x00, 0x20, 
+0x63, 0x69, 0x9b, 0x08, 0x07, 0xd0, 0x2a, 0x4b, 0x87, 0x00, 0xcb, 0x51, 
+0x67, 0x69, 0xbf, 0x08, 0x01, 0x30, 0x87, 0x42, 0xf8, 0xd8, 0x24, 0x49, 
+0xc0, 0x46, 0x8a, 0x62, 0x8c, 0x89, 0x58, 0x20, 0x60, 0x43, 0x87, 0x18, 
+0x00, 0x20, 0x00, 0x22, 0x00, 0x2c, 0x0a, 0xdd, 0x58, 0x23, 0x43, 0x43, 
+0x8c, 0x6a, 0xe3, 0x18, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, 
+0x8b, 0x89, 0x83, 0x42, 0xf4, 0xdc, 0xcf, 0x62, 0xcc, 0x89, 0x60, 0x00, 
+0x00, 0x19, 0x40, 0x01, 0xc7, 0x19, 0x00, 0x20, 0x00, 0x2c, 0x0b, 0xdd, 
+0x43, 0x00, 0x1b, 0x18, 0x5b, 0x01, 0xcc, 0x6a, 0xe3, 0x18, 0x01, 0x30, 
+0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, 0xcb, 0x89, 0x83, 0x42, 0xf3, 0xdc, 
+0x4f, 0x62, 0x00, 0x20, 0x0b, 0x69, 0x00, 0x2b, 0x07, 0xd9, 0x87, 0x00, 
+0x4b, 0x6a, 0xc0, 0x46, 0xda, 0x51, 0x0b, 0x69, 0x01, 0x30, 0x83, 0x42, 
+0xf7, 0xd8, 0x49, 0x6a, 0x80, 0x00, 0x08, 0x18, 0x04, 0x38, 0x28, 0x61, 
+0xf0, 0xbc, 0x70, 0x47, 0xb8, 0xce, 0x21, 0x40, 0x00, 0x00, 0x18, 0x40, 
+0xe8, 0x0d, 0x00, 0x80, 0x02, 0x99, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 
+0xc8, 0x29, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, 0x00, 0xad, 0xde, 0x00, 
+0x0a, 0x48, 0x01, 0x23, 0x1b, 0x06, 0x41, 0x69, 0x99, 0x43, 0x1a, 0x09, 
+0x41, 0x61, 0xd1, 0x60, 0x00, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x91, 0x61, 
+0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x61, 0x01, 0x20, 0x00, 0x06, 
+0x59, 0x05, 0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
+0x80, 0xb4, 0x02, 0x1c, 0x0b, 0x48, 0x1b, 0x23, 0xdb, 0x01, 0xc3, 0x18, 
+0x5a, 0x61, 0x01, 0x23, 0x1b, 0x06, 0x42, 0x69, 0x1a, 0x43, 0x42, 0x61, 
+0x87, 0x69, 0x9f, 0x43, 0x01, 0x23, 0x1b, 0x05, 0x87, 0x61, 0xda, 0x60, 
+0x80, 0x69, 0xc0, 0x46, 0x18, 0x61, 0xa1, 0x20, 0x40, 0x03, 0x81, 0x61, 
+0x80, 0xbc, 0x70, 0x47, 0xe8, 0x0d, 0x00, 0x80, 0x80, 0xb5, 0xff, 0xf7, 
+0xc9, 0xff, 0x00, 0x20, 0x00, 0xf0, 0x20, 0xf8, 0x00, 0x20, 0x09, 0x49, 
+0x00, 0x22, 0x03, 0x01, 0x5f, 0x18, 0x33, 0x23, 0x9b, 0x01, 0xfb, 0x18, 
+0x5a, 0x62, 0x01, 0x30, 0x0b, 0x28, 0xf6, 0xd3, 0x04, 0x48, 0x01, 0x22, 
+0x00, 0x21, 0x00, 0xf0, 0x33, 0xf8, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 
+0xe8, 0x0d, 0x00, 0x80, 0x91, 0x3d, 0xff, 0xff, 0x00, 0xb5, 0x02, 0x48, 
+0x00, 0xf0, 0x04, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0xa8, 0x61, 0x00, 0x00, 
+0x80, 0xb4, 0x01, 0x22, 0x12, 0x05, 0x0f, 0x4b, 0xa1, 0x21, 0x49, 0x03, 
+0x00, 0x28, 0x0e, 0xd0, 0xc8, 0x61, 0x18, 0x1c, 0x59, 0x69, 0x53, 0x01, 
+0x19, 0x43, 0x41, 0x61, 0x87, 0x69, 0x9f, 0x43, 0x87, 0x61, 0xd1, 0x60, 
+0x80, 0x69, 0xc0, 0x46, 0x10, 0x61, 0x80, 0xbc, 0x70, 0x47, 0x18, 0x1c, 
+0x5f, 0x69, 0x01, 0x23, 0x5b, 0x06, 0x9f, 0x43, 0x47, 0x61, 0xd7, 0x60, 
+0x00, 0x20, 0xc8, 0x61, 0xf3, 0xe7, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
+0xb0, 0xb4, 0x07, 0x1c, 0x00, 0x20, 0x17, 0x4c, 0x03, 0x01, 0x1d, 0x19, 
+0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x5d, 0x6a, 0xbd, 0x42, 0x05, 0xd1, 
+0xdd, 0x6a, 0x95, 0x42, 0x02, 0xd1, 0x9b, 0x6a, 0x8b, 0x42, 0x1c, 0xd0, 
+0x01, 0x30, 0x0b, 0x28, 0xee, 0xd3, 0x00, 0x20, 0x03, 0x01, 0x1d, 0x19, 
+0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x5b, 0x6a, 0x00, 0x2b, 0x09, 0xd1, 
+0x03, 0x01, 0x1c, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xe3, 0x18, 0xda, 0x62, 
+0x99, 0x62, 0x1a, 0x63, 0x5f, 0x62, 0x02, 0xe0, 
+0x01, 0x30, 0x0b, 0x28, 0xea, 0xd3, 0x0b, 0x28, 0x01, 0xd1, 0x00, 0x20, 
+0xc0, 0x43, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x0d, 0x00, 0x80, 
+0x90, 0xb4, 0x01, 0x1c, 0x00, 0x22, 0x01, 0x20, 0x16, 0x4f, 0x01, 0xe0, 
+0x00, 0x2a, 0x07, 0xd1, 0x03, 0x01, 0xdc, 0x19, 0x33, 0x23, 0x9b, 0x01, 
+0xe3, 0x18, 0x5b, 0x69, 0x8b, 0x42, 0x11, 0xd1, 0x02, 0x01, 0xd2, 0x19, 
+0x33, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0x53, 0x6a, 0xc0, 0x46, 0x53, 0x61, 
+0x93, 0x6a, 0xc0, 0x46, 0x93, 0x61, 0xd3, 0x6a, 0xc0, 0x46, 0xd3, 0x61, 
+0x13, 0x6b, 0xc0, 0x46, 0x13, 0x62, 0x01, 0x22, 0x01, 0x30, 0x0b, 0x28, 
+0xe0, 0xd3, 0x07, 0x4b, 0x00, 0x2a, 0x02, 0xd1, 0x5a, 0x68, 0x8a, 0x42, 
+0x03, 0xd1, 0x00, 0x21, 0x59, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 
+0xc0, 0x43, 0xfa, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 0x68, 0x1b, 0x00, 0x80, 
+0x0b, 0x28, 0x17, 0xda, 0x0c, 0x49, 0x01, 0x23, 0x5b, 0x06, 0x8a, 0x69, 
+0x13, 0x43, 0x01, 0x22, 0x12, 0x05, 0x8b, 0x61, 0x13, 0x61, 0x00, 0x01, 
+0x40, 0x18, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0xc3, 0x6a, 0xc0, 0x46, 
+0x03, 0x63, 0x53, 0x01, 0x88, 0x69, 0x98, 0x43, 0x88, 0x61, 0x10, 0x61, 
+0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 0xe8, 0x0d, 0x00, 0x80, 
+0x90, 0xb4, 0x08, 0x4a, 0xd0, 0x69, 0x00, 0x21, 0x07, 0x4f, 0xd3, 0x69, 
+0x83, 0x42, 0x02, 0xd9, 0xfc, 0x1a, 0x20, 0x18, 0x00, 0xe0, 0xc0, 0x1a, 
+0x09, 0x18, 0x18, 0x1c, 0xb9, 0x42, 0xf4, 0xd9, 0x90, 0xbc, 0x70, 0x47, 
+0x00, 0x20, 0x14, 0x40, 0xa8, 0x61, 0x00, 0x00, 0x43, 0x1a, 0x93, 0x42, 
+0x30, 0xd3, 0x84, 0x46, 0x8b, 0x07, 0x07, 0xd0, 0x52, 0x1e, 0x29, 0xd3, 
+0x0b, 0x78, 0x03, 0x70, 0x40, 0x1c, 0x49, 0x1c, 0x8b, 0x07, 0xf7, 0xd1, 
+0x83, 0x07, 0x17, 0xd1, 0x10, 0x3a, 0x05, 0xd3, 0xb0, 0xb4, 0xb8, 0xc9, 
+0xb8, 0xc0, 0x10, 0x3a, 0xfb, 0xd2, 0xb0, 0xbc, 0x0c, 0x32, 0x0f, 0xd3, 
+0x08, 0xc9, 0x08, 0xc0, 0x12, 0x1f, 0xfb, 0xd2, 0x0a, 0xe0, 0x08, 0xc9, 
+0x03, 0x70, 0x1b, 0x0a, 0x43, 0x70, 0x1b, 0x0a, 0x83, 0x70, 0x1b, 0x0a, 
+0xc3, 0x70, 0x00, 0x1d, 0x12, 0x1f, 0xf4, 0xd2, 0xd2, 0x1c, 0x05, 0xd3, 
+0x0b, 0x78, 0x03, 0x70, 0x49, 0x1c, 0x40, 0x1c, 0x52, 0x1e, 0xf9, 0xd2, 
+0x60, 0x46, 0x70, 0x47, 0x03, 0x1c, 0x0b, 0x43, 0x13, 0x43, 0x9b, 0x07, 
+0x04, 0xd1, 0x12, 0x1f, 0x8b, 0x58, 0x83, 0x50, 0xfb, 0xd1, 0x70, 0x47, 
+0x52, 0x1e, 0x8b, 0x5c, 0x83, 0x54, 0xfb, 0xd1, 0x70, 0x47, 0x00, 0x00, 
+0x00, 0x20, 0x70, 0x47, 
+};
diff -Nru a/drivers/net/typhoon.c b/drivers/net/typhoon.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/typhoon.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,2505 @@
+/* typhoon.c: A Linux Ethernet device driver for 3Com 3CR990 family of NICs */
+/*
+	Written 2002-2003 by David Dillow <dave@thedillows.org>
+	Based on code written 1998-2000 by Donald Becker <becker@scyld.com> and
+	Linux 2.2.x driver by David P. McLean <davidpmclean@yahoo.com>.
+
+	This software may be used and distributed according to the terms of
+	the GNU General Public License (GPL), incorporated herein by reference.
+	Drivers based on or derived from this code fall under the GPL and must
+	retain the authorship, copyright and license notice.  This file is not
+	a complete program and may only be used when the entire operating
+	system is licensed under the GPL.
+
+	This software is available on a public web site. It may enable
+	cryptographic capabilities of the 3Com hardware, and may be
+	exported from the United States under License Exception "TSU"
+	pursuant to 15 C.F.R. Section 740.13(e).
+
+	This work was funded by the National Library of Medicine under
+	the Department of Energy project number 0274DD06D1 and NLM project
+	number Y1-LM-2015-01.
+
+	This driver is designed for the 3Com 3CR990 Family of cards with the
+	3XP Processor. It has been tested on x86 and sparc64.
+
+	KNOWN ISSUES:
+	*) The current firmware always strips the VLAN tag off, even if
+		we tell it not to. You should filter VLANs at the switch
+		as a workaround (good practice in any event) until we can
+		get this fixed.
+	*) Cannot DMA Rx packets to a 2 byte aligned address. Also firmware
+		issue. Hopefully 3Com will fix it.
+	*) Waiting for a command response takes 8ms due to non-preemptable
+		polling. Only significant for getting stats and creating
+		SAs, but an ugly wart never the less.
+	*) I've not tested multicast. I think it works, but reports welcome.
+	*) Doesn't do IPSEC offloading. Yet. Keep yer pants on, it's coming.
+*/
+
+/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
+ * Setting to > 1518 effectively disables this feature.
+ */
+static int rx_copybreak = 0;
+
+/* end user-configurable values */
+
+/* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
+ */
+static const int multicast_filter_limit = 32;
+
+/* Operational parameters that are set at compile time. */
+
+/* Keep the ring sizes a power of two for compile efficiency.
+ * The compiler will convert <unsigned>'%'<2^N> into a bit mask.
+ * Making the Tx ring too large decreases the effectiveness of channel
+ * bonding and packet priority.
+ * There are no ill effects from too-large receive rings.
+ *
+ * We don't currently use the Hi Tx ring so, don't make it very big.
+ *
+ * Beware that if we start using the Hi Tx ring, we will need to change
+ * typhoon_num_free_tx() and typhoon_tx_complete() to account for that.
+ */
+#define TXHI_ENTRIES		2
+#define TXLO_ENTRIES		128
+#define RX_ENTRIES		32
+#define COMMAND_ENTRIES		16
+#define RESPONSE_ENTRIES	32
+
+#define COMMAND_RING_SIZE	(COMMAND_ENTRIES * sizeof(struct cmd_desc))
+#define RESPONSE_RING_SIZE	(RESPONSE_ENTRIES * sizeof(struct resp_desc))
+
+/* The 3XP will preload and remove 64 entries from the free buffer
+ * list, and we need one entry to keep the ring from wrapping, so 
+ * to keep this a power of two, we use 128 entries.
+ */
+#define RXFREE_ENTRIES		128
+#define RXENT_ENTRIES		(RXFREE_ENTRIES - 1)
+
+/* Operational parameters that usually are not changed. */
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  (2*HZ)
+
+#define PKT_BUF_SZ		1536
+
+#define DRV_MODULE_NAME		"typhoon"
+#define DRV_MODULE_VERSION 	"1.0"
+#define DRV_MODULE_RELDATE	"03/02/14"
+#define PFX			DRV_MODULE_NAME ": "
+#define ERR_PFX			KERN_ERR PFX
+
+#if !defined(__OPTIMIZE__)  ||  !defined(__KERNEL__)
+#warning  You must compile this file with the correct options!
+#warning  See the last lines of the source file.
+#error  You must compile this driver with "-O".
+#endif
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/crc32.h>
+#include <asm/processor.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/in6.h>
+#include <asm/checksum.h>
+#include <linux/version.h>
+
+#include "typhoon.h"
+#include "typhoon-firmware.h"
+
+static char version[] __devinitdata =
+    "typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+
+MODULE_AUTHOR("David Dillow <dillowd@y12.doe.gov>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)");
+MODULE_PARM(rx_copybreak, "i");
+
+#if defined(NETIF_F_TSO) && MAX_SKB_FRAGS > 32
+#warning Typhoon only supports 32 entries in its SG list for TSO, disabling TSO
+#undef NETIF_F_TSO
+#endif
+
+#if TXLO_ENTRIES <= (2 * MAX_SKB_FRAGS)
+#error TX ring too small!
+#endif
+
+struct typhoon_card_info {
+	char *name;
+	int capabilities;
+};
+
+#define TYPHOON_CRYPTO_NONE		0
+#define TYPHOON_CRYPTO_DES		1
+#define TYPHOON_CRYPTO_3DES		2
+#define	TYPHOON_CRYPTO_VARIABLE		4
+#define TYPHOON_FIBER			5
+
+enum typhoon_cards {
+	TYPHOON_TX = 0, TYPHOON_TX95, TYPHOON_TX97, TYPHOON_SVR,
+	TYPHOON_SVR95, TYPHOON_SVR97, TYPHOON_TXM, TYPHOON_BSVR,
+	TYPHOON_FX95, TYPHOON_FX97, TYPHOON_FX95SVR, TYPHOON_FX97SVR,
+};
+
+/* directly indexed by enum typhoon_cards, above */
+static struct typhoon_card_info typhoon_card_info[] __devinitdata = {
+	{ "3Com Typhoon (3C990-TX)",
+		TYPHOON_CRYPTO_NONE},
+	{ "3Com Typhoon (3CR990-TX-95)",
+		TYPHOON_CRYPTO_DES},
+	{ "3Com Typhoon (3CR990-TX-97)",
+	 	TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES},
+	{ "3Com Typhoon (3C990SVR)",
+		TYPHOON_CRYPTO_NONE},
+	{ "3Com Typhoon (3CR990SVR95)",
+		TYPHOON_CRYPTO_DES},
+	{ "3Com Typhoon (3CR990SVR97)",
+	 	TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES},
+	{ "3Com Typhoon2 (3C990B-TX-M)",
+		TYPHOON_CRYPTO_VARIABLE},
+	{ "3Com Typhoon2 (3C990BSVR)",
+		TYPHOON_CRYPTO_VARIABLE},
+	{ "3Com Typhoon (3CR990-FX-95)",
+		TYPHOON_CRYPTO_DES | TYPHOON_FIBER},
+	{ "3Com Typhoon (3CR990-FX-97)",
+	 	TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES | TYPHOON_FIBER},
+	{ "3Com Typhoon (3CR990-FX-95 Server)",
+	 	TYPHOON_CRYPTO_DES | TYPHOON_FIBER},
+	{ "3Com Typhoon (3CR990-FX-97 Server)",
+	 	TYPHOON_CRYPTO_DES | TYPHOON_CRYPTO_3DES | TYPHOON_FIBER},
+};
+
+/* Notes on the new subsystem numbering scheme:
+ * bits 0-1 indicate crypto capabilites: (0) variable, (1) DES, or (2) 3DES
+ * bit 4 indicates if this card has secured firmware (we don't support it)
+ * bit 8 indicates if this is a (0) copper or (1) fiber card
+ * bits 12-16 indicate card type: (0) client and (1) server
+ */
+static struct pci_device_id typhoon_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0,TYPHOON_TX },
+	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_TX_95,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_TX95 },
+	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_TX_97,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_TX97 },
+	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990B,
+	  PCI_ANY_ID, 0x1000, 0, 0, TYPHOON_TXM },
+	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990B,
+	  PCI_ANY_ID, 0x2000, 0, 0, TYPHOON_BSVR },
+	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX,
+	  PCI_ANY_ID, 0x1101, 0, 0, TYPHOON_FX95 },
+	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX,
+	  PCI_ANY_ID, 0x1102, 0, 0, TYPHOON_FX97 },
+	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX,
+	  PCI_ANY_ID, 0x2101, 0, 0, TYPHOON_FX95SVR },
+	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990_FX,
+	  PCI_ANY_ID, 0x2102, 0, 0, TYPHOON_FX97SVR },
+	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990SVR95,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_SVR95 },
+	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990SVR97,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_SVR97 },
+	{ PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3CR990SVR,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPHOON_SVR },
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, typhoon_pci_tbl);
+
+/* Define the shared memory area
+ * Align everything the 3XP will normally be using.
+ * We'll need to move/align txHi if we start using that ring.
+ */
+#define __3xp_aligned	____cacheline_aligned
+struct typhoon_shared {
+	struct typhoon_interface	iface;
+	struct typhoon_indexes		indexes			__3xp_aligned;
+	struct tx_desc			txLo[TXLO_ENTRIES] 	__3xp_aligned;
+	struct rx_desc			rxLo[RX_ENTRIES]	__3xp_aligned;
+	struct rx_desc			rxHi[RX_ENTRIES]	__3xp_aligned;
+	struct cmd_desc			cmd[COMMAND_ENTRIES]	__3xp_aligned;
+	struct resp_desc		resp[RESPONSE_ENTRIES]	__3xp_aligned;
+	struct rx_free			rxBuff[RXFREE_ENTRIES]	__3xp_aligned;
+	u32				zeroWord;
+	struct tx_desc			txHi[TXHI_ENTRIES];
+} __attribute__ ((packed));
+
+struct rxbuff_ent {
+	struct sk_buff *skb;
+	dma_addr_t	dma_addr;
+};
+
+struct typhoon {
+	/* Tx cache line section */
+	struct transmit_ring 	txLoRing	____cacheline_aligned;	
+	struct pci_dev *	tx_pdev;
+	unsigned long		tx_ioaddr;
+	u32			txlo_dma_addr;
+
+	/* Irq/Rx cache line section */
+	unsigned long		ioaddr		____cacheline_aligned;
+	struct typhoon_indexes *indexes;
+	u8			awaiting_resp;
+	u8			duplex;
+	u8			speed;
+	u8			card_state;
+	struct basic_ring	rxLoRing;
+	struct pci_dev *	pdev;
+	struct net_device *	dev;
+	spinlock_t		state_lock;
+	struct vlan_group *	vlgrp;
+	struct basic_ring	rxHiRing;
+	struct basic_ring	rxBuffRing;
+	struct rxbuff_ent	rxbuffers[RXENT_ENTRIES];
+
+	/* general section */
+	spinlock_t		command_lock	____cacheline_aligned;
+	struct basic_ring	cmdRing;
+	struct basic_ring	respRing;
+	struct net_device_stats	stats;
+	struct net_device_stats	stats_saved;
+	const char *		name;
+	struct typhoon_shared *	shared;
+	dma_addr_t		shared_dma;
+	u16			xcvr_select;
+	u16			wol_events;
+	u32			offload;
+	u32			pci_state[16];
+
+	/* unused stuff (future use) */
+	int			capabilities;
+	struct transmit_ring 	txHiRing;
+};
+
+enum completion_wait_values {
+	NoWait = 0, WaitNoSleep, WaitSleep,
+};
+
+/* These are the values for the typhoon.card_state variable.
+ * These determine where the statistics will come from in get_stats().
+ * The sleep image does not support the statistics we need.
+ */
+enum state_values {
+	Sleeping = 0, Running,
+};
+
+/* PCI writes are not guaranteed to be posted in order, but outstanding writes
+ * cannot pass a read, so this forces current writes to post.
+ */
+#define typhoon_post_pci_writes(x) \
+	do { readl(x + TYPHOON_REG_HEARTBEAT); } while(0)
+
+/* We'll wait up to six seconds for a reset, and half a second normally.
+ */
+#define TYPHOON_UDELAY			50
+#define TYPHOON_RESET_TIMEOUT		(6 * HZ)
+#define TYPHOON_WAIT_TIMEOUT		((1000000 / 2) / TYPHOON_UDELAY)
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 28)
+#define typhoon_synchronize_irq(x) synchronize_irq()
+#else
+#define typhoon_synchronize_irq(x) synchronize_irq(x)
+#endif
+
+#if defined(NETIF_F_TSO)
+#define skb_tso_size(x)		(skb_shinfo(x)->tso_size)
+#define TSO_NUM_DESCRIPTORS	2
+#define TSO_OFFLOAD_ON		TYPHOON_OFFLOAD_TCP_SEGMENT
+#else
+#define NETIF_F_TSO 		0
+#define skb_tso_size(x) 	0
+#define TSO_NUM_DESCRIPTORS	0
+#define TSO_OFFLOAD_ON		0
+#endif
+
+static inline void
+typhoon_inc_index(u32 *index, const int count, const int num_entries)
+{
+	/* Increment a ring index -- we can use this for all rings execept
+	 * the Rx rings, as they use different size descriptors
+	 * otherwise, everything is the same size as a cmd_desc
+	 */
+	*index += count * sizeof(struct cmd_desc);
+	*index %= num_entries * sizeof(struct cmd_desc);
+}
+
+static inline void
+typhoon_inc_cmd_index(u32 *index, const int count)
+{
+	typhoon_inc_index(index, count, COMMAND_ENTRIES);
+}
+
+static inline void
+typhoon_inc_resp_index(u32 *index, const int count)
+{
+	typhoon_inc_index(index, count, RESPONSE_ENTRIES);
+}
+
+static inline void
+typhoon_inc_rxfree_index(u32 *index, const int count)
+{
+	typhoon_inc_index(index, count, RXFREE_ENTRIES);
+}
+
+static inline void
+typhoon_inc_tx_index(u32 *index, const int count)
+{
+	/* if we start using the Hi Tx ring, this needs updateing */
+	typhoon_inc_index(index, count, TXLO_ENTRIES);
+}
+
+static inline void
+typhoon_inc_rx_index(u32 *index, const int count)
+{
+	/* sizeof(struct rx_desc) != sizeof(struct cmd_desc) */
+	*index += count * sizeof(struct rx_desc);
+	*index %= RX_ENTRIES * sizeof(struct rx_desc);
+}
+
+static int
+typhoon_reset(unsigned long ioaddr, int wait_type)
+{
+	int i, err = 0;
+	int timeout = TYPHOON_RESET_TIMEOUT;
+
+	if(wait_type == WaitNoSleep)
+		timeout = (timeout * 1000000) / (HZ * TYPHOON_UDELAY);
+
+	writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
+	writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS);
+
+	writel(TYPHOON_RESET_ALL, ioaddr + TYPHOON_REG_SOFT_RESET);
+	typhoon_post_pci_writes(ioaddr);
+	udelay(1);
+	writel(TYPHOON_RESET_NONE, ioaddr + TYPHOON_REG_SOFT_RESET);
+
+	if(wait_type != NoWait) {
+		for(i = 0; i < timeout; i++) {
+			if(readl(ioaddr + TYPHOON_REG_STATUS) ==
+			   TYPHOON_STATUS_WAITING_FOR_HOST)
+				goto out;
+
+			if(wait_type == WaitSleep) {
+				set_current_state(TASK_UNINTERRUPTIBLE);
+				schedule_timeout(1);
+			} else
+				udelay(TYPHOON_UDELAY);
+		}
+
+		err = -ETIMEDOUT;
+	}
+
+out:
+	writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
+	writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_STATUS);
+	udelay(100);
+	return err;
+
+	/* The 3XP seems to need a little extra time to complete the load
+	 * of the sleep image before we can reliably boot it. Failure to
+	 * do this occasionally results in a hung adapter after boot in
+	 * typhoon_init_one() while trying to read the MAC address or
+	 * putting the card to sleep. 3Com's driver waits 5ms, but
+	 * that seems to be overkill -- with a 50usec delay, it survives
+	 * 35000 typhoon_init_one() calls, where it only make it 25-100
+	 * without it.
+	 *
+	 * As it turns out, still occasionally getting a hung adapter,
+	 * so I'm bumping it to 100us.
+	 */
+}
+
+static int
+typhoon_wait_status(unsigned long ioaddr, u32 wait_value)
+{
+	int i, err = 0;
+
+	for(i = 0; i < TYPHOON_WAIT_TIMEOUT; i++) {
+		if(readl(ioaddr + TYPHOON_REG_STATUS) == wait_value)
+			goto out;
+		udelay(TYPHOON_UDELAY);
+	}
+
+	err = -ETIMEDOUT;
+
+out:
+	return err;
+}
+
+static inline void
+typhoon_media_status(struct net_device *dev, struct resp_desc *resp)
+{
+	if(resp->parm1 & TYPHOON_MEDIA_STAT_NO_LINK)
+		netif_carrier_off(dev);
+	else
+		netif_carrier_on(dev);
+}
+
+static inline void
+typhoon_hello(struct typhoon *tp)
+{
+	struct basic_ring *ring = &tp->cmdRing;
+	struct cmd_desc *cmd;
+
+	/* We only get a hello request if we've not sent anything to the
+	 * card in a long while. If the lock is held, then we're in the
+	 * process of issuing a command, so we don't need to respond.
+	 */
+	if(spin_trylock(&tp->command_lock)) {
+		cmd = (struct cmd_desc *)(ring->ringBase + ring->lastWrite);
+		typhoon_inc_cmd_index(&ring->lastWrite, 1);
+
+		INIT_COMMAND_NO_RESPONSE(cmd, TYPHOON_CMD_HELLO_RESP);
+		smp_wmb();
+		writel(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY);
+		spin_unlock(&tp->command_lock);
+	}
+}
+
+static int
+typhoon_process_response(struct typhoon *tp, int resp_size,
+				struct resp_desc *resp_save)
+{
+	struct typhoon_indexes *indexes = tp->indexes;
+	struct resp_desc *resp;
+	u8 *base = tp->respRing.ringBase;
+	int count, len, wrap_len;
+	u32 cleared;
+	u32 ready;
+
+	cleared = le32_to_cpu(indexes->respCleared);
+	ready = le32_to_cpu(indexes->respReady);
+	while(cleared != ready) {
+		resp = (struct resp_desc *)(base + cleared);
+		count = resp->numDesc + 1;
+		if(resp_save && resp->seqNo) {
+			if(count > resp_size) {
+				resp_save->flags = TYPHOON_RESP_ERROR;
+				goto cleanup;
+			}
+
+			wrap_len = 0;
+			len = count * sizeof(*resp);
+			if(unlikely(cleared + len > RESPONSE_RING_SIZE)) {
+				wrap_len = cleared + len - RESPONSE_RING_SIZE;
+				len = RESPONSE_RING_SIZE - cleared;
+			}
+
+			memcpy(resp_save, resp, len);
+			if(unlikely(wrap_len)) {
+				resp_save += len / sizeof(*resp);
+				memcpy(resp_save, base, wrap_len);
+			}
+
+			resp_save = NULL;
+		} else if(resp->cmd == TYPHOON_CMD_READ_MEDIA_STATUS) {
+			typhoon_media_status(tp->dev, resp);
+		} else if(resp->cmd == TYPHOON_CMD_HELLO_RESP) {
+			typhoon_hello(tp);
+		} else {
+			printk(KERN_ERR "%s: dumping unexpected response "
+			       "0x%04x:%d:0x%02x:0x%04x:%08x:%08x\n",
+			       tp->name, le16_to_cpu(resp->cmd),
+			       resp->numDesc, resp->flags,
+			       le16_to_cpu(resp->parm1),
+			       le32_to_cpu(resp->parm2),
+			       le32_to_cpu(resp->parm3));
+		}
+
+cleanup:
+		typhoon_inc_resp_index(&cleared, count);
+	}
+
+	indexes->respCleared = cpu_to_le32(cleared);
+	wmb();
+	return (resp_save == NULL);
+}
+
+static inline int
+typhoon_num_free(int lastWrite, int lastRead, int ringSize)
+{
+	/* this works for all descriptors but rx_desc, as they are a
+	 * different size than the cmd_desc -- everyone else is the same
+	 */
+	lastWrite /= sizeof(struct cmd_desc);
+	lastRead /= sizeof(struct cmd_desc);
+	return (ringSize + lastRead - lastWrite - 1) % ringSize;
+}
+
+static inline int
+typhoon_num_free_cmd(struct typhoon *tp)
+{
+	int lastWrite = tp->cmdRing.lastWrite;
+	int cmdCleared = le32_to_cpu(tp->indexes->cmdCleared);
+
+	return typhoon_num_free(lastWrite, cmdCleared, COMMAND_ENTRIES);
+}
+
+static inline int
+typhoon_num_free_resp(struct typhoon *tp)
+{
+	int respReady = le32_to_cpu(tp->indexes->respReady);
+	int respCleared = le32_to_cpu(tp->indexes->respCleared);
+
+	return typhoon_num_free(respReady, respCleared, RESPONSE_ENTRIES);
+}
+
+static inline int
+typhoon_num_free_tx(struct transmit_ring *ring)
+{
+	/* if we start using the Hi Tx ring, this needs updating */
+	return typhoon_num_free(ring->lastWrite, ring->lastRead, TXLO_ENTRIES);
+}
+
+static int
+typhoon_issue_command(struct typhoon *tp, int num_cmd, struct cmd_desc *cmd,
+		      int num_resp, struct resp_desc *resp)
+{
+	struct typhoon_indexes *indexes = tp->indexes;
+	struct basic_ring *ring = &tp->cmdRing;
+	struct resp_desc local_resp;
+	int i, err = 0;
+	int got_resp;
+	int freeCmd, freeResp;
+	int len, wrap_len;
+
+	spin_lock(&tp->command_lock);
+
+	freeCmd = typhoon_num_free_cmd(tp);
+	freeResp = typhoon_num_free_resp(tp);
+
+	if(freeCmd < num_cmd || freeResp < num_resp) {
+		printk("%s: no descs for cmd, had (needed) %d (%d) cmd, "
+			"%d (%d) resp\n", tp->name, freeCmd, num_cmd,
+			freeResp, num_resp);
+		err = -ENOMEM;
+		goto out;
+	}
+
+	if(cmd->flags & TYPHOON_CMD_RESPOND) {
+		/* If we're expecting a response, but the caller hasn't given
+		 * us a place to put it, we'll provide one.
+		 */
+		tp->awaiting_resp = 1;
+		if(resp == NULL) {
+			resp = &local_resp;
+			num_resp = 1;
+		}
+	}
+
+	wrap_len = 0;
+	len = num_cmd * sizeof(*cmd);
+	if(unlikely(ring->lastWrite + len > COMMAND_RING_SIZE)) {
+		wrap_len = ring->lastWrite + len - COMMAND_RING_SIZE;
+		len = COMMAND_RING_SIZE - ring->lastWrite;
+	}
+
+	memcpy(ring->ringBase + ring->lastWrite, cmd, len);
+	if(unlikely(wrap_len)) {
+		struct cmd_desc *wrap_ptr = cmd;
+		wrap_ptr += len / sizeof(*cmd);
+		memcpy(ring->ringBase, wrap_ptr, wrap_len);
+	}
+
+	typhoon_inc_cmd_index(&ring->lastWrite, num_cmd);
+
+	/* "I feel a presence... another warrior is on the the mesa."
+	 */
+	wmb();
+	writel(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY);
+	typhoon_post_pci_writes(tp->ioaddr);
+
+	if((cmd->flags & TYPHOON_CMD_RESPOND) == 0)
+		goto out;
+
+	/* Ugh. We'll be here about 8ms, spinning our thumbs, unable to
+	 * preempt or do anything other than take interrupts. So, don't
+	 * wait for a response unless you have to.
+	 *
+	 * I've thought about trying to sleep here, but we're called
+	 * from many contexts that don't allow that. Also, given the way
+	 * 3Com has implemented irq coalescing, we would likely timeout --
+	 * this has been observed in real life!
+	 *
+	 * The big killer is we have to wait to get stats from the card,
+	 * though we could go to a periodic refresh of those if we don't
+	 * mind them getting somewhat stale. The rest of the waiting
+	 * commands occur during open/close/suspend/resume, so they aren't
+	 * time critical. Creating SAs in the future will also have to
+	 * wait here.
+	 */
+	got_resp = 0;
+	for(i = 0; i < TYPHOON_WAIT_TIMEOUT && !got_resp; i++) {
+		if(indexes->respCleared != indexes->respReady)
+			got_resp = typhoon_process_response(tp, num_resp,
+								resp);
+		udelay(TYPHOON_UDELAY);
+	}
+
+	if(!got_resp) {
+		err = -ETIMEDOUT;
+		goto out;
+	}
+
+	/* Collect the error response even if we don't care about the
+	 * rest of the response
+	 */
+	if(resp->flags & TYPHOON_RESP_ERROR)
+		err = -EIO;
+
+out:
+	if(tp->awaiting_resp) {
+		tp->awaiting_resp = 0;
+		smp_wmb();
+
+		/* Ugh. If a response was added to the ring between
+		 * the call to typhoon_process_response() and the clearing
+		 * of tp->awaiting_resp, we could have missed the interrupt
+		 * and it could hang in the ring an indeterminate amount of
+		 * time. So, check for it, and interrupt ourselves if this
+		 * is the case.
+		 */
+		if(indexes->respCleared != indexes->respReady)
+			writel(1, tp->ioaddr + TYPHOON_REG_SELF_INTERRUPT);
+	}
+
+	spin_unlock(&tp->command_lock);
+	return err;
+}
+
+static void
+typhoon_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+	struct typhoon *tp = (struct typhoon *) dev->priv;
+	struct cmd_desc xp_cmd;
+	int err;
+
+	spin_lock_bh(&tp->state_lock);
+	if(!tp->vlgrp != !grp) {
+		/* We've either been turned on for the first time, or we've
+		 * been turned off. Update the 3XP.
+		 */
+		if(grp)
+			tp->offload |= TYPHOON_OFFLOAD_VLAN;
+		else
+			tp->offload &= ~TYPHOON_OFFLOAD_VLAN;
+
+		/* If the interface is up, the runtime is running -- and we
+		 * must be up for the vlan core to call us.
+		 *
+		 * Do the command outside of the spin lock, as it is slow.
+		 */
+		INIT_COMMAND_WITH_RESPONSE(&xp_cmd,
+					TYPHOON_CMD_SET_OFFLOAD_TASKS);
+		xp_cmd.parm2 = tp->offload;
+		xp_cmd.parm3 = tp->offload;
+		spin_unlock_bh(&tp->state_lock);
+		err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+		if(err < 0)
+			printk("%s: vlan offload error %d\n", tp->name, -err);
+		spin_lock_bh(&tp->state_lock);
+	}
+
+	/* now make the change visible */
+	tp->vlgrp = grp;
+	spin_unlock_bh(&tp->state_lock);
+}
+
+static void
+typhoon_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+	struct typhoon *tp = (struct typhoon *) dev->priv;
+	spin_lock_bh(&tp->state_lock);
+	if(tp->vlgrp)
+		tp->vlgrp->vlan_devices[vid] = NULL;
+	spin_unlock_bh(&tp->state_lock);
+}
+
+static inline void
+typhoon_tso_fill(struct sk_buff *skb, struct transmit_ring *txRing,
+			u32 ring_dma)
+{
+	struct tcpopt_desc *tcpd;
+	u32 tcpd_offset = ring_dma;
+
+	tcpd = (struct tcpopt_desc *) (txRing->ringBase + txRing->lastWrite);
+	tcpd_offset += txRing->lastWrite;
+	tcpd_offset += offsetof(struct tcpopt_desc, bytesTx);
+	typhoon_inc_tx_index(&txRing->lastWrite, 1);
+
+	tcpd->flags = TYPHOON_OPT_DESC | TYPHOON_OPT_TCP_SEG;
+	tcpd->numDesc = 1;
+	tcpd->mss_flags = cpu_to_le16(skb_tso_size(skb));
+	tcpd->mss_flags |= TYPHOON_TSO_FIRST | TYPHOON_TSO_LAST;
+	tcpd->respAddrLo = cpu_to_le32(tcpd_offset);
+	tcpd->bytesTx = cpu_to_le32(skb->len);
+	tcpd->status = 0;
+}
+
+static int
+typhoon_start_tx(struct sk_buff *skb, struct net_device *dev)
+{
+	struct typhoon *tp = (struct typhoon *) dev->priv;
+	struct transmit_ring *txRing;
+	struct tx_desc *txd, *first_txd;
+	dma_addr_t skb_dma;
+	int numDesc;
+
+	/* we have two rings to choose from, but we only use txLo for now
+	 * If we start using the Hi ring as well, we'll need to update
+	 * typhoon_stop_runtime(), typhoon_interrupt(), typhoon_num_free_tx(),
+	 * and TXHI_ENTIRES to match, as well as update the TSO code below
+	 * to get the right DMA address
+	 */
+	txRing = &tp->txLoRing;
+
+	/* We need one descriptor for each fragment of the sk_buff, plus the
+	 * one for the ->data area of it.
+	 *
+	 * The docs say a maximum of 16 fragment descriptors per TCP option
+	 * descriptor, then make a new packet descriptor and option descriptor
+	 * for the next 16 fragments. The engineers say just an option
+	 * descriptor is needed. I've tested up to 26 fragments with a single
+	 * packet descriptor/option descriptor combo, so I use that for now.
+	 *
+	 * If problems develop with TSO, check this first.
+	 */
+	numDesc = skb_shinfo(skb)->nr_frags + 1;
+	if(skb_tso_size(skb))
+		numDesc++;
+
+	/* When checking for free space in the ring, we need to also
+	 * account for the initial Tx descriptor, and we always must leave
+	 * at least one descriptor unused in the ring so that it doesn't
+	 * wrap and look empty.
+	 *
+	 * The only time we should loop here is when we hit the race
+	 * between marking the queue awake and updating the cleared index.
+	 * Just loop and it will appear. This comes from the acenic driver.
+	 */
+	while(unlikely(typhoon_num_free_tx(txRing) < (numDesc + 2)))
+		smp_rmb();
+
+	first_txd = (struct tx_desc *) (txRing->ringBase + txRing->lastWrite);
+	typhoon_inc_tx_index(&txRing->lastWrite, 1);
+
+	first_txd->flags = TYPHOON_TX_DESC | TYPHOON_DESC_VALID;
+	first_txd->numDesc = 0;
+	first_txd->len = 0;
+	first_txd->addr = (u64)((unsigned long) skb) & 0xffffffff;
+	first_txd->addrHi = (u64)((unsigned long) skb) >> 32;
+	first_txd->processFlags = 0;
+
+	if(skb->ip_summed == CHECKSUM_HW) {
+		/* The 3XP will figure out if this is UDP/TCP */
+		first_txd->processFlags |= TYPHOON_TX_PF_TCP_CHKSUM;
+		first_txd->processFlags |= TYPHOON_TX_PF_UDP_CHKSUM;
+		first_txd->processFlags |= TYPHOON_TX_PF_IP_CHKSUM;
+	}
+
+	if(vlan_tx_tag_present(skb)) {
+		first_txd->processFlags |=
+		    TYPHOON_TX_PF_INSERT_VLAN | TYPHOON_TX_PF_VLAN_PRIORITY;
+		first_txd->processFlags |=
+		    cpu_to_le32(htons(vlan_tx_tag_get(skb)) <<
+				TYPHOON_TX_PF_VLAN_TAG_SHIFT);
+	}
+
+	if(skb_tso_size(skb)) {
+		first_txd->processFlags |= TYPHOON_TX_PF_TCP_SEGMENT;
+		first_txd->numDesc++;
+
+		typhoon_tso_fill(skb, txRing, tp->txlo_dma_addr);
+	}
+
+	txd = (struct tx_desc *) (txRing->ringBase + txRing->lastWrite);
+	typhoon_inc_tx_index(&txRing->lastWrite, 1);
+
+	/* No need to worry about padding packet -- the firmware pads
+	 * it with zeros to ETH_ZLEN for us.
+	 */
+	if(skb_shinfo(skb)->nr_frags == 0) {
+		skb_dma = pci_map_single(tp->tx_pdev, skb->data, skb->len,
+				       PCI_DMA_TODEVICE);
+		txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID;
+		txd->len = cpu_to_le16(skb->len);
+		txd->addr = cpu_to_le32(skb_dma);
+		txd->addrHi = 0;
+		first_txd->numDesc++;
+	} else {
+		int i, len;
+
+		len = skb->len - skb->data_len;
+		skb_dma = pci_map_single(tp->tx_pdev, skb->data, len,
+				         PCI_DMA_TODEVICE);
+		txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID;
+		txd->len = cpu_to_le16(len);
+		txd->addr = cpu_to_le32(skb_dma);
+		txd->addrHi = 0;
+		first_txd->numDesc++;
+
+		for(i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+			void *frag_addr;
+
+			txd = (struct tx_desc *) (txRing->ringBase +
+						txRing->lastWrite);
+			typhoon_inc_tx_index(&txRing->lastWrite, 1);
+
+			len = frag->size;
+			frag_addr = (void *) page_address(frag->page) +
+						frag->page_offset;
+			skb_dma = pci_map_single(tp->tx_pdev, frag_addr, len,
+					 PCI_DMA_TODEVICE);
+			txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID;
+			txd->len = cpu_to_le16(len);
+			txd->addr = cpu_to_le32(skb_dma);
+			txd->addrHi = 0;
+			first_txd->numDesc++;
+		}
+	}
+
+	/* Kick the 3XP
+	 */
+	wmb();
+	writel(txRing->lastWrite, tp->tx_ioaddr + txRing->writeRegister);
+
+	dev->trans_start = jiffies;
+
+	/* If we don't have room to put the worst case packet on the
+	 * queue, then we must stop the queue. We need 2 extra
+	 * descriptors -- one to prevent ring wrap, and one for the
+	 * Tx header.
+	 */
+	numDesc = MAX_SKB_FRAGS + TSO_NUM_DESCRIPTORS + 1;
+
+	if(typhoon_num_free_tx(txRing) < (numDesc + 2)) {
+		netif_stop_queue(dev);
+
+		/* A Tx complete IRQ could have gotten inbetween, making
+		 * the ring free again. Only need to recheck here, since
+		 * Tx is serialized.
+		 */
+		if(typhoon_num_free_tx(txRing) >= (numDesc + 2))
+			netif_wake_queue(dev);
+	}
+
+	return 0;
+}
+
+static void
+typhoon_set_rx_mode(struct net_device *dev)
+{
+	struct typhoon *tp = (struct typhoon *) dev->priv;
+	struct cmd_desc xp_cmd;
+	u32 mc_filter[2];
+	u16 filter;
+
+	filter = TYPHOON_RX_FILTER_DIRECTED | TYPHOON_RX_FILTER_BROADCAST;
+	if(dev->flags & IFF_PROMISC) {
+		printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n",
+		       dev->name);
+		filter |= TYPHOON_RX_FILTER_PROMISCOUS;
+	} else if((dev->mc_count > multicast_filter_limit) ||
+		  (dev->flags & IFF_ALLMULTI)) {
+		/* Too many to match, or accept all multicasts. */
+		filter |= TYPHOON_RX_FILTER_ALL_MCAST;
+	} else if(dev->mc_count) {
+		struct dev_mc_list *mclist;
+		int i;
+
+		memset(mc_filter, 0, sizeof(mc_filter));
+		for(i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+		    i++, mclist = mclist->next) {
+			int bit = ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3f;
+			mc_filter[bit >> 5] |= 1 << (bit & 0x1f);
+		}
+
+		INIT_COMMAND_NO_RESPONSE(&xp_cmd,
+					 TYPHOON_CMD_SET_MULTICAST_HASH);
+		xp_cmd.parm1 = TYPHOON_MCAST_HASH_SET;
+		xp_cmd.parm2 = cpu_to_le32(mc_filter[0]);
+		xp_cmd.parm3 = cpu_to_le32(mc_filter[1]);
+		typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+
+		filter |= TYPHOON_RX_FILTER_MCAST_HASH;
+	}
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_RX_FILTER);
+	xp_cmd.parm1 = filter;
+	typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+}
+
+static int
+typhoon_do_get_stats(struct typhoon *tp)
+{
+	struct net_device_stats *stats = &tp->stats;
+	struct net_device_stats *saved = &tp->stats_saved;
+	struct cmd_desc xp_cmd;
+	struct resp_desc xp_resp[7];
+	struct stats_resp *s = (struct stats_resp *) xp_resp;
+	int err;
+
+	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_STATS);
+	err = typhoon_issue_command(tp, 1, &xp_cmd, 7, xp_resp);
+	if(err < 0)
+		return err;
+
+	/* 3Com's Linux driver uses txMultipleCollisions as it's
+	 * collisions value, but there is some other collision info as well...
+	 */
+	stats->tx_packets = le32_to_cpu(s->txPackets);
+	stats->tx_bytes = le32_to_cpu(s->txBytes);
+	stats->tx_errors = le32_to_cpu(s->txCarrierLost);
+	stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost);
+	stats->collisions = le32_to_cpu(s->txMultipleCollisions);
+	stats->rx_packets = le32_to_cpu(s->rxPacketsGood);
+	stats->rx_bytes = le32_to_cpu(s->rxBytesGood);
+	stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns);
+	stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) +
+			le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors);
+	stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors);
+	stats->rx_length_errors = le32_to_cpu(s->rxOversized);
+	tp->speed = (s->linkStatus & TYPHOON_LINK_100MBPS) ?
+			SPEED_100 : SPEED_10;
+	tp->duplex = (s->linkStatus & TYPHOON_LINK_FULL_DUPLEX) ?
+			DUPLEX_FULL : DUPLEX_HALF;
+
+	/* add in the saved statistics
+	 */
+	stats->tx_packets += saved->tx_packets;
+	stats->tx_bytes += saved->tx_bytes;
+	stats->tx_errors += saved->tx_errors;
+	stats->collisions += saved->collisions;
+	stats->rx_packets += saved->rx_packets;
+	stats->rx_bytes += saved->rx_bytes;
+	stats->rx_fifo_errors += saved->rx_fifo_errors;
+	stats->rx_errors += saved->rx_errors;
+	stats->rx_crc_errors += saved->rx_crc_errors;
+	stats->rx_length_errors += saved->rx_length_errors;
+
+	return 0;
+}
+
+static struct net_device_stats *
+typhoon_get_stats(struct net_device *dev)
+{
+	struct typhoon *tp = (struct typhoon *) dev->priv;
+	struct net_device_stats *stats = &tp->stats;
+	struct net_device_stats *saved = &tp->stats_saved;
+
+	smp_rmb();
+	if(tp->card_state == Sleeping)
+		return saved;
+
+	if(typhoon_do_get_stats(tp) < 0) {
+		printk(KERN_ERR "%s: error getting stats\n", dev->name);
+		return saved;
+	}
+
+	return stats;
+}
+
+static int
+typhoon_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct sockaddr *saddr = (struct sockaddr *) addr;
+
+	if(netif_running(dev))
+		return -EBUSY;
+
+	memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len);
+	return 0;
+}
+
+static inline void
+typhoon_ethtool_gdrvinfo(struct typhoon *tp, struct ethtool_drvinfo *info)
+{
+	struct pci_dev *pci_dev = tp->pdev;
+	struct cmd_desc xp_cmd;
+	struct resp_desc xp_resp[3];
+
+	smp_rmb();
+	if(tp->card_state == Sleeping) {
+		strcpy(info->fw_version, "Sleep image");
+	} else {
+		INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_VERSIONS);
+		if(typhoon_issue_command(tp, 1, &xp_cmd, 3, xp_resp) < 0) {
+			strcpy(info->fw_version, "Unknown runtime");
+		} else {
+			strncpy(info->fw_version, (char *) &xp_resp[1], 32);
+			info->fw_version[31] = 0;
+		}
+	}
+
+	strcpy(info->driver, DRV_MODULE_NAME);
+	strcpy(info->version, DRV_MODULE_VERSION);
+	strcpy(info->bus_info, pci_dev->slot_name);
+}
+
+static inline void
+typhoon_ethtool_gset(struct typhoon *tp, struct ethtool_cmd *cmd)
+{
+	cmd->supported = SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+				SUPPORTED_Autoneg;
+
+	switch (tp->xcvr_select) {
+	case TYPHOON_XCVR_10HALF:
+		cmd->advertising = ADVERTISED_10baseT_Half;
+		break;
+	case TYPHOON_XCVR_10FULL:
+		cmd->advertising = ADVERTISED_10baseT_Full;
+		break;
+	case TYPHOON_XCVR_100HALF:
+		cmd->advertising = ADVERTISED_100baseT_Half;
+		break;
+	case TYPHOON_XCVR_100FULL:
+		cmd->advertising = ADVERTISED_100baseT_Full;
+		break;
+	case TYPHOON_XCVR_AUTONEG:
+		cmd->advertising = ADVERTISED_10baseT_Half |
+					    ADVERTISED_10baseT_Full |
+					    ADVERTISED_100baseT_Half |
+					    ADVERTISED_100baseT_Full |
+					    ADVERTISED_Autoneg;
+		break;
+	}
+
+	if(tp->capabilities & TYPHOON_FIBER) {
+		cmd->supported |= SUPPORTED_FIBRE;
+		cmd->advertising |= ADVERTISED_FIBRE;
+		cmd->port = PORT_FIBRE;
+	} else {
+		cmd->supported |= SUPPORTED_10baseT_Half |
+		    			SUPPORTED_10baseT_Full |
+					SUPPORTED_TP;
+		cmd->advertising |= ADVERTISED_TP;
+		cmd->port = PORT_TP;
+	}
+
+	/* need to get stats to make these link speed/duplex valid */
+	typhoon_do_get_stats(tp);
+	cmd->speed = tp->speed;
+	cmd->duplex = tp->duplex;
+	cmd->phy_address = 0;
+	cmd->transceiver = XCVR_INTERNAL;
+	if(tp->xcvr_select == TYPHOON_XCVR_AUTONEG)
+		cmd->autoneg = AUTONEG_ENABLE;
+	else
+		cmd->autoneg = AUTONEG_DISABLE;
+	cmd->maxtxpkt = 1;
+	cmd->maxrxpkt = 1;
+}
+
+static inline int
+typhoon_ethtool_sset(struct typhoon *tp, struct ethtool_cmd *cmd)
+{
+	struct cmd_desc xp_cmd;
+	int xcvr;
+	int err;
+
+	if(cmd->autoneg == AUTONEG_ENABLE) {
+		xcvr = TYPHOON_XCVR_AUTONEG;
+	} else {
+		if(cmd->duplex == DUPLEX_HALF) {
+			if(cmd->speed == SPEED_10)
+				xcvr = TYPHOON_XCVR_10HALF;
+			else if(cmd->speed == SPEED_100)
+				xcvr = TYPHOON_XCVR_100HALF;
+			else
+				return -EINVAL;
+		} else if(cmd->duplex == DUPLEX_FULL) {
+			if(cmd->speed == SPEED_10)
+				xcvr = TYPHOON_XCVR_10FULL;
+			else if(cmd->speed == SPEED_100)
+				xcvr = TYPHOON_XCVR_100FULL;
+			else
+				return -EINVAL;
+		} else
+			return -EINVAL;
+	}
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_XCVR_SELECT);
+	xp_cmd.parm1 = cpu_to_le16(xcvr);
+	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+	if(err < 0)
+		return err;
+
+	tp->xcvr_select = xcvr;
+	if(cmd->autoneg == AUTONEG_ENABLE) {
+		tp->speed = 0xff;	/* invalid */
+		tp->duplex = 0xff;	/* invalid */
+	} else {
+		tp->speed = cmd->speed;
+		tp->duplex = cmd->duplex;
+	}
+
+	return 0;
+}
+
+static inline int
+typhoon_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	struct typhoon *tp = (struct typhoon *) dev->priv;
+	u32 ethcmd;
+
+	if(copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+		return -EFAULT;
+
+	switch (ethcmd) {
+	case ETHTOOL_GDRVINFO: {
+			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
+
+			typhoon_ethtool_gdrvinfo(tp, &info);
+			if(copy_to_user(useraddr, &info, sizeof(info)))
+				return -EFAULT;
+			return 0;
+		}
+	case ETHTOOL_GSET: {
+			struct ethtool_cmd cmd = { ETHTOOL_GSET };
+
+			typhoon_ethtool_gset(tp, &cmd);
+			if(copy_to_user(useraddr, &cmd, sizeof(cmd)))
+				return -EFAULT;
+			return 0;
+		}
+	case ETHTOOL_SSET: {
+			struct ethtool_cmd cmd;
+			if(copy_from_user(&cmd, useraddr, sizeof(cmd)))
+				return -EFAULT;
+
+			return typhoon_ethtool_sset(tp, &cmd);
+		}
+	case ETHTOOL_GLINK:{
+			struct ethtool_value edata = { ETHTOOL_GLINK };
+
+			edata.data = netif_carrier_ok(dev) ? 1 : 0;
+			if(copy_to_user(useraddr, &edata, sizeof(edata)))
+				return -EFAULT;
+			return 0;
+		}
+	case ETHTOOL_GWOL: {
+			struct ethtool_wolinfo wol = { ETHTOOL_GWOL };
+
+			if(tp->wol_events & TYPHOON_WAKE_LINK_EVENT)
+				wol.wolopts |= WAKE_PHY;
+			if(tp->wol_events & TYPHOON_WAKE_MAGIC_PKT)
+				wol.wolopts |= WAKE_MAGIC;
+			if(copy_to_user(useraddr, &wol, sizeof(wol)))
+				return -EFAULT;
+			return 0;
+	}
+	case ETHTOOL_SWOL: {
+			struct ethtool_wolinfo wol;
+
+			if(copy_from_user(&wol, useraddr, sizeof(wol)))
+				return -EFAULT;
+			tp->wol_events = 0;
+			if(wol.wolopts & WAKE_PHY)
+				tp->wol_events |= TYPHOON_WAKE_LINK_EVENT;
+			if(wol.wolopts & WAKE_MAGIC)
+				tp->wol_events |= TYPHOON_WAKE_MAGIC_PKT;
+			return 0;
+	}
+	default:
+		break;
+	}
+
+	return -EOPNOTSUPP;
+}
+
+static int
+typhoon_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	switch (cmd) {
+	case SIOCETHTOOL:
+		return typhoon_ethtool_ioctl(dev, (void *) ifr->ifr_data);
+	default:
+		break;
+	}
+
+	return -EOPNOTSUPP;
+}
+
+static int
+typhoon_wait_interrupt(unsigned long ioaddr)
+{
+	int i, err = 0;
+
+	for(i = 0; i < TYPHOON_WAIT_TIMEOUT; i++) {
+		if(readl(ioaddr + TYPHOON_REG_INTR_STATUS) &
+		   TYPHOON_INTR_BOOTCMD)
+			goto out;
+		udelay(TYPHOON_UDELAY);
+	}
+
+	err = -ETIMEDOUT;
+
+out:
+	writel(TYPHOON_INTR_BOOTCMD, ioaddr + TYPHOON_REG_INTR_STATUS);
+	return err;
+}
+
+#define shared_offset(x)	offsetof(struct typhoon_shared, x)
+
+static void
+typhoon_init_interface(struct typhoon *tp)
+{
+	struct typhoon_interface *iface = &tp->shared->iface;
+	dma_addr_t shared_dma;
+
+	memset(tp->shared, 0, sizeof(struct typhoon_shared));
+
+	/* The *Hi members of iface are all init'd to zero by the memset().
+	 */
+	shared_dma = tp->shared_dma + shared_offset(indexes);
+	iface->ringIndex = cpu_to_le32(shared_dma);
+
+	shared_dma = tp->shared_dma + shared_offset(txLo);
+	iface->txLoAddr = cpu_to_le32(shared_dma);
+	iface->txLoSize = cpu_to_le32(TXLO_ENTRIES * sizeof(struct tx_desc));
+
+	shared_dma = tp->shared_dma + shared_offset(txHi);
+	iface->txHiAddr = cpu_to_le32(shared_dma);
+	iface->txHiSize = cpu_to_le32(TXHI_ENTRIES * sizeof(struct tx_desc));
+
+	shared_dma = tp->shared_dma + shared_offset(rxBuff);
+	iface->rxBuffAddr = cpu_to_le32(shared_dma);
+	iface->rxBuffSize = cpu_to_le32(RXFREE_ENTRIES *
+					sizeof(struct rx_free));
+
+	shared_dma = tp->shared_dma + shared_offset(rxLo);
+	iface->rxLoAddr = cpu_to_le32(shared_dma);
+	iface->rxLoSize = cpu_to_le32(RX_ENTRIES * sizeof(struct rx_desc));
+
+	shared_dma = tp->shared_dma + shared_offset(rxHi);
+	iface->rxHiAddr = cpu_to_le32(shared_dma);
+	iface->rxHiSize = cpu_to_le32(RX_ENTRIES * sizeof(struct rx_desc));
+
+	shared_dma = tp->shared_dma + shared_offset(cmd);
+	iface->cmdAddr = cpu_to_le32(shared_dma);
+	iface->cmdSize = cpu_to_le32(COMMAND_RING_SIZE);
+
+	shared_dma = tp->shared_dma + shared_offset(resp);
+	iface->respAddr = cpu_to_le32(shared_dma);
+	iface->respSize = cpu_to_le32(RESPONSE_RING_SIZE);
+
+	shared_dma = tp->shared_dma + shared_offset(zeroWord);
+	iface->zeroAddr = cpu_to_le32(shared_dma);
+
+	tp->indexes = &tp->shared->indexes;
+	tp->txLoRing.ringBase = (u8 *) tp->shared->txLo;
+	tp->txHiRing.ringBase = (u8 *) tp->shared->txHi;
+	tp->rxLoRing.ringBase = (u8 *) tp->shared->rxLo;
+	tp->rxHiRing.ringBase = (u8 *) tp->shared->rxHi;
+	tp->rxBuffRing.ringBase = (u8 *) tp->shared->rxBuff;
+	tp->cmdRing.ringBase = (u8 *) tp->shared->cmd;
+	tp->respRing.ringBase = (u8 *) tp->shared->resp;;
+
+	tp->txLoRing.writeRegister = TYPHOON_REG_TX_LO_READY;
+	tp->txHiRing.writeRegister = TYPHOON_REG_TX_HI_READY;
+
+	tp->txlo_dma_addr = iface->txLoAddr;
+	tp->card_state = Sleeping;
+	smp_wmb();
+
+	tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM;
+	tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON;
+
+	spin_lock_init(&tp->command_lock);
+	spin_lock_init(&tp->state_lock);
+}
+
+static void
+typhoon_init_rings(struct typhoon *tp)
+{
+	memset(tp->indexes, 0, sizeof(struct typhoon_indexes));
+
+	tp->txLoRing.lastWrite = 0;
+	tp->txHiRing.lastWrite = 0;
+	tp->rxLoRing.lastWrite = 0;
+	tp->rxHiRing.lastWrite = 0;
+	tp->rxBuffRing.lastWrite = 0;
+	tp->cmdRing.lastWrite = 0;
+	tp->cmdRing.lastWrite = 0;
+
+	tp->txLoRing.lastRead = 0;
+	tp->txHiRing.lastRead = 0;
+}
+
+static int
+typhoon_download_firmware(struct typhoon *tp)
+{
+	unsigned long ioaddr = tp->ioaddr;
+	struct pci_dev *pdev = tp->pdev;
+	struct typhoon_file_header *fHdr;
+	struct typhoon_section_header *sHdr;
+	u8 *image_data;
+	void *dpage;
+	dma_addr_t dpage_dma;
+	unsigned int csum;
+	u32 irqEnabled;
+	u32 irqMasked;
+	u32 numSections;
+	u32 section_len;
+	u32 len;
+	u32 load_addr;
+	int i;
+	int err;
+
+	err = -EINVAL;
+	fHdr = (struct typhoon_file_header *) typhoon_firmware_image;
+	image_data = (u8 *) fHdr;
+
+	if(memcmp(fHdr->tag, "TYPHOON", 8)) {
+		printk(KERN_ERR "%s: Invalid firmware image!\n", tp->name);
+		goto err_out;
+	}
+
+	/* Cannot just map the firmware image using pci_map_single() as
+	 * the firmware is part of the kernel/module image, so we allocate
+	 * some consistent memory to copy the sections into, as it is simpler,
+	 * and short-lived. If we ever split out and require a userland
+	 * firmware loader, then we can revisit this.
+	 */
+	err = -ENOMEM;
+	dpage = pci_alloc_consistent(pdev, PAGE_SIZE, &dpage_dma);
+	if(!dpage) {
+		printk(KERN_ERR "%s: no DMA mem for firmware\n", tp->name);
+		goto err_out;
+	}
+
+	irqEnabled = readl(ioaddr + TYPHOON_REG_INTR_ENABLE);
+	writel(irqEnabled | TYPHOON_INTR_BOOTCMD,
+	       ioaddr + TYPHOON_REG_INTR_ENABLE);
+	irqMasked = readl(ioaddr + TYPHOON_REG_INTR_MASK);
+	writel(irqMasked | TYPHOON_INTR_BOOTCMD,
+	       ioaddr + TYPHOON_REG_INTR_MASK);
+
+	err = -ETIMEDOUT;
+	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
+		printk(KERN_ERR "%s: card ready timeout\n", tp->name);
+		goto err_out_irq;
+	}
+
+	numSections = le32_to_cpu(fHdr->numSections);
+	load_addr = le32_to_cpu(fHdr->startAddr);
+
+	writel(TYPHOON_INTR_BOOTCMD, ioaddr + TYPHOON_REG_INTR_STATUS);
+	writel(load_addr, ioaddr + TYPHOON_REG_DOWNLOAD_BOOT_ADDR);
+	typhoon_post_pci_writes(ioaddr);
+	writel(TYPHOON_BOOTCMD_RUNTIME_IMAGE, ioaddr + TYPHOON_REG_COMMAND);
+
+	image_data += sizeof(struct typhoon_file_header);
+
+	/* The readl() in typhoon_wait_interrupt() will force the
+	 * last write to the command register to post, so
+	 * we don't need a typhoon_post_pci_writes() after it.
+	 */
+	for(i = 0; i < numSections; i++) {
+		sHdr = (struct typhoon_section_header *) image_data;
+		image_data += sizeof(struct typhoon_section_header);
+		load_addr = le32_to_cpu(sHdr->startAddr);
+		section_len = le32_to_cpu(sHdr->len);
+
+		while(section_len) {
+			len = min_t(u32, section_len, PAGE_SIZE);
+
+			if(typhoon_wait_interrupt(ioaddr) < 0 ||
+			   readl(ioaddr + TYPHOON_REG_STATUS) !=
+			   TYPHOON_STATUS_WAITING_FOR_SEGMENT) {
+				printk(KERN_ERR "%s: segment ready timeout\n",
+				       tp->name);
+				goto err_out_irq;
+			}
+
+			/* Do an pseudo IPv4 checksum on the data -- first
+			 * need to convert each u16 to cpu order before
+			 * summing. Fortunately, due to the properties of
+			 * the checksum, we can do this once, at the end.
+			 */
+			csum = csum_partial_copy_nocheck(image_data, dpage,
+							 len, 0);
+			csum = csum_fold(csum);
+			csum = le16_to_cpu(csum);
+
+			writel(len, ioaddr + TYPHOON_REG_BOOT_LENGTH);
+			writel(csum, ioaddr + TYPHOON_REG_BOOT_CHECKSUM);
+			writel(load_addr, ioaddr + TYPHOON_REG_BOOT_DEST_ADDR);
+			writel(0, ioaddr + TYPHOON_REG_BOOT_DATA_HI);
+			writel(dpage_dma, ioaddr + TYPHOON_REG_BOOT_DATA_LO);
+			typhoon_post_pci_writes(ioaddr);
+			writel(TYPHOON_BOOTCMD_SEG_AVAILABLE,
+			       ioaddr + TYPHOON_REG_COMMAND);
+
+			image_data += len;
+			load_addr += len;
+			section_len -= len;
+		}
+	}
+
+	if(typhoon_wait_interrupt(ioaddr) < 0 ||
+	   readl(ioaddr + TYPHOON_REG_STATUS) !=
+	   TYPHOON_STATUS_WAITING_FOR_SEGMENT) {
+		printk(KERN_ERR "%s: final segment ready timeout\n", tp->name);
+		goto err_out_irq;
+	}
+
+	writel(TYPHOON_BOOTCMD_DNLD_COMPLETE, ioaddr + TYPHOON_REG_COMMAND);
+
+	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) {
+		printk(KERN_ERR "%s: boot ready timeout, status 0x%0x\n",
+		       tp->name, readl(ioaddr + TYPHOON_REG_STATUS));
+		goto err_out_irq;
+	}
+
+	err = 0;
+
+err_out_irq:
+	writel(irqMasked, ioaddr + TYPHOON_REG_INTR_MASK);
+	writel(irqEnabled, ioaddr + TYPHOON_REG_INTR_ENABLE);
+
+	pci_free_consistent(pdev, PAGE_SIZE, dpage, dpage_dma);
+
+err_out:
+	return err;
+}
+
+static int
+typhoon_boot_3XP(struct typhoon *tp, u32 initial_status)
+{
+	unsigned long ioaddr = tp->ioaddr;
+
+	if(typhoon_wait_status(ioaddr, initial_status) < 0) {
+		printk(KERN_ERR "%s: boot ready timeout\n", tp->name);
+		goto out_timeout;
+	}
+
+	writel(0, ioaddr + TYPHOON_REG_BOOT_RECORD_ADDR_HI);
+	writel(tp->shared_dma, ioaddr + TYPHOON_REG_BOOT_RECORD_ADDR_LO);
+	typhoon_post_pci_writes(ioaddr);
+	writel(TYPHOON_BOOTCMD_REG_BOOT_RECORD, ioaddr + TYPHOON_REG_COMMAND);
+
+	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_RUNNING) < 0) {
+		printk(KERN_ERR "%s: boot finish timeout (status 0x%x)\n",
+		       tp->name, readl(ioaddr + TYPHOON_REG_STATUS));
+		goto out_timeout;
+	}
+
+	/* Clear the Transmit and Command ready registers
+	 */
+	writel(0, ioaddr + TYPHOON_REG_TX_HI_READY);
+	writel(0, ioaddr + TYPHOON_REG_CMD_READY);
+	writel(0, ioaddr + TYPHOON_REG_TX_LO_READY);
+	typhoon_post_pci_writes(ioaddr);
+	writel(TYPHOON_BOOTCMD_BOOT, ioaddr + TYPHOON_REG_COMMAND);
+
+	return 0;
+
+out_timeout:
+	return -ETIMEDOUT;
+}
+
+static u32
+typhoon_clean_tx(struct typhoon *tp, struct transmit_ring *txRing,
+			volatile u32 * index)
+{
+	u32 lastRead = txRing->lastRead;
+	struct tx_desc *tx;
+	dma_addr_t skb_dma;
+	int dma_len;
+	int type;
+
+	while(lastRead != le32_to_cpu(*index)) {
+		tx = (struct tx_desc *) (txRing->ringBase + lastRead);
+		type = tx->flags & TYPHOON_TYPE_MASK;
+
+		if(type == TYPHOON_TX_DESC) {
+			/* This tx_desc describes a packet.
+			 */
+			unsigned long ptr = tx->addr | ((u64)tx->addrHi << 32);
+			struct sk_buff *skb = (struct sk_buff *) ptr;
+			dev_kfree_skb_irq(skb);
+		} else if(type == TYPHOON_FRAG_DESC) {
+			/* This tx_desc describes a memory mapping. Free it.
+			 */
+			skb_dma = (dma_addr_t) le32_to_cpu(tx->addr);
+			dma_len = le16_to_cpu(tx->len);
+			pci_unmap_single(tp->pdev, skb_dma, dma_len,
+				       PCI_DMA_TODEVICE);
+		}
+
+		tx->flags = 0;
+		typhoon_inc_tx_index(&lastRead, 1);
+	}
+
+	return lastRead;
+}
+
+static void
+typhoon_tx_complete(struct typhoon *tp, struct transmit_ring *txRing,
+			volatile u32 * index)
+{
+	u32 lastRead;
+	int numDesc = MAX_SKB_FRAGS + 1;
+
+	/* This will need changing if we start to use the Hi Tx ring. */
+	lastRead = typhoon_clean_tx(tp, txRing, index);
+	if(netif_queue_stopped(tp->dev) && typhoon_num_free(txRing->lastWrite,
+				lastRead, TXLO_ENTRIES) > (numDesc + 2))
+		netif_wake_queue(tp->dev);
+
+	txRing->lastRead = lastRead;
+	smp_wmb();
+}
+
+static void
+typhoon_recycle_rx_skb(struct typhoon *tp, u32 idx)
+{
+	struct typhoon_indexes *indexes = tp->indexes;
+	struct rxbuff_ent *rxb = &tp->rxbuffers[idx];
+	struct basic_ring *ring = &tp->rxBuffRing;
+	struct rx_free *r;
+
+	if((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) ==
+				indexes->rxBuffCleared) {
+		/* no room in ring, just drop the skb
+		 */
+		dev_kfree_skb_any(rxb->skb);
+		rxb->skb = NULL;
+		return;
+	}
+
+	r = (struct rx_free *) (ring->ringBase + ring->lastWrite);
+	typhoon_inc_rxfree_index(&ring->lastWrite, 1);
+	r->virtAddr = idx;
+	r->physAddr = cpu_to_le32(rxb->dma_addr);
+
+	/* Tell the card about it */
+	wmb();
+	indexes->rxBuffReady = cpu_to_le32(ring->lastWrite);
+}
+
+static int
+typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx)
+{
+	struct typhoon_indexes *indexes = tp->indexes;
+	struct rxbuff_ent *rxb = &tp->rxbuffers[idx];
+	struct basic_ring *ring = &tp->rxBuffRing;
+	struct rx_free *r;
+	struct sk_buff *skb;
+	dma_addr_t dma_addr;
+
+	rxb->skb = NULL;
+
+	if((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) ==
+				indexes->rxBuffCleared)
+		return -ENOMEM;
+
+	skb = dev_alloc_skb(PKT_BUF_SZ);
+	if(!skb)
+		return -ENOMEM;
+
+#if 0
+	/* Please, 3com, fix the firmware to allow DMA to a unaligned
+	 * address! Pretty please?
+	 */
+	skb_reserve(skb, 2);
+#endif
+
+	skb->dev = tp->dev;
+	dma_addr = pci_map_single(tp->pdev, skb->tail,
+				  PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+
+	/* Since no card does 64 bit DAC, the high bits will never
+	 * change from zero.
+	 */
+	r = (struct rx_free *) (ring->ringBase + ring->lastWrite);
+	typhoon_inc_rxfree_index(&ring->lastWrite, 1);
+	r->virtAddr = idx;
+	r->physAddr = cpu_to_le32(dma_addr);
+	rxb->skb = skb;
+	rxb->dma_addr = dma_addr;
+
+	/* Tell the card about it */
+	wmb();
+	indexes->rxBuffReady = cpu_to_le32(ring->lastWrite);
+	return 0;
+}
+
+static int
+typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile u32 * ready,
+	   volatile u32 * cleared, int budget)
+{
+	struct rx_desc *rx;
+	struct sk_buff *skb, *new_skb;
+	struct rxbuff_ent *rxb;
+	dma_addr_t dma_addr;
+	u32 local_ready;
+	u32 rxaddr;
+	int pkt_len;
+	u32 idx;
+	u32 csum_bits;
+	int received;
+
+	received = 0;
+	local_ready = le32_to_cpu(*ready);
+	rxaddr = le32_to_cpu(*cleared);
+	while(rxaddr != local_ready && budget > 0) {
+		rx = (struct rx_desc *) (rxRing->ringBase + rxaddr);
+		idx = rx->addr;
+		rxb = &tp->rxbuffers[idx];
+		skb = rxb->skb;
+		dma_addr = rxb->dma_addr;
+
+		rxaddr += sizeof(struct rx_desc);
+		rxaddr %= RX_ENTRIES * sizeof(struct rx_desc);
+
+		if(rx->flags & TYPHOON_RX_ERROR) {
+			typhoon_recycle_rx_skb(tp, idx);
+			continue;
+		}
+
+		pkt_len = le16_to_cpu(rx->frameLen);
+
+		if(pkt_len < rx_copybreak &&
+		   (new_skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			new_skb->dev = tp->dev;
+			skb_reserve(new_skb, 2);
+			pci_dma_sync_single(tp->pdev, dma_addr, PKT_BUF_SZ,
+					    PCI_DMA_FROMDEVICE);
+			eth_copy_and_sum(new_skb, skb->tail, pkt_len, 0);
+			skb_put(new_skb, pkt_len);
+			typhoon_recycle_rx_skb(tp, idx);
+		} else {
+			new_skb = skb;
+			skb_put(new_skb, pkt_len);
+			pci_unmap_single(tp->pdev, dma_addr, PKT_BUF_SZ,
+				       PCI_DMA_FROMDEVICE);
+			typhoon_alloc_rx_skb(tp, idx);
+		}
+		new_skb->protocol = eth_type_trans(new_skb, tp->dev);
+		csum_bits = rx->rxStatus & (TYPHOON_RX_IP_CHK_GOOD |
+			TYPHOON_RX_UDP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD);
+		if(csum_bits ==
+		   (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_TCP_CHK_GOOD)
+		   || csum_bits ==
+		   (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_UDP_CHK_GOOD)) {
+			new_skb->ip_summed = CHECKSUM_UNNECESSARY;
+		} else
+			new_skb->ip_summed = CHECKSUM_NONE;
+
+		spin_lock(&tp->state_lock);
+		if(tp->vlgrp != NULL && rx->rxStatus & TYPHOON_RX_VLAN)
+			vlan_hwaccel_receive_skb(new_skb, tp->vlgrp,
+						 ntohl(rx->vlanTag) & 0xffff);
+		else
+			netif_receive_skb(new_skb);
+		spin_unlock(&tp->state_lock);
+
+		tp->dev->last_rx = jiffies;
+		received++;
+		budget--;
+	}
+	*cleared = cpu_to_le32(rxaddr);
+
+	return received;
+}
+
+static void
+typhoon_fill_free_ring(struct typhoon *tp)
+{
+	u32 i;
+
+	for(i = 0; i < RXENT_ENTRIES; i++) {
+		struct rxbuff_ent *rxb = &tp->rxbuffers[i];
+		if(rxb->skb)
+			continue;
+		if(typhoon_alloc_rx_skb(tp, i) < 0)
+			break;
+	}
+}
+
+static int
+typhoon_poll(struct net_device *dev, int *total_budget)
+{
+	struct typhoon *tp = (struct typhoon *) dev->priv;
+	struct typhoon_indexes *indexes = tp->indexes;
+	int orig_budget = *total_budget;
+	int budget, work_done, done;
+
+	rmb();
+	if(!tp->awaiting_resp && indexes->respReady != indexes->respCleared)
+			typhoon_process_response(tp, 0, NULL);
+
+	if(le32_to_cpu(indexes->txLoCleared) != tp->txLoRing.lastRead)
+		typhoon_tx_complete(tp, &tp->txLoRing, &indexes->txLoCleared);
+
+	if(orig_budget > dev->quota)
+		orig_budget = dev->quota;
+
+	budget = orig_budget;
+	work_done = 0;
+	done = 1;
+
+	if(indexes->rxHiCleared != indexes->rxHiReady) {
+		work_done = typhoon_rx(tp, &tp->rxHiRing, &indexes->rxHiReady,
+			   		&indexes->rxHiCleared, budget);
+		budget -= work_done;
+	}
+
+	if(indexes->rxLoCleared != indexes->rxLoReady) {
+		work_done += typhoon_rx(tp, &tp->rxLoRing, &indexes->rxLoReady,
+			   		&indexes->rxLoCleared, budget);
+	}
+
+	if(work_done) {
+		*total_budget -= work_done;
+		dev->quota -= work_done;
+
+		if(work_done >= orig_budget)
+			done = 0;
+	}
+
+	if(le32_to_cpu(indexes->rxBuffCleared) == tp->rxBuffRing.lastWrite) {
+		/* rxBuff ring is empty, try to fill it. */
+		typhoon_fill_free_ring(tp);
+	}
+
+	if(done) {
+		netif_rx_complete(dev);
+		writel(TYPHOON_INTR_NONE, tp->ioaddr + TYPHOON_REG_INTR_MASK);
+		typhoon_post_pci_writes(tp->ioaddr);
+	}
+
+	return (done ? 0 : 1);
+}
+
+static void
+typhoon_interrupt(int irq, void *dev_instance, struct pt_regs *rgs)
+{
+	struct net_device *dev = (struct net_device *) dev_instance;
+	unsigned long ioaddr = dev->base_addr;
+	u32 intr_status;
+
+	intr_status = readl(ioaddr + TYPHOON_REG_INTR_STATUS);
+	if(!intr_status)
+		return;
+
+	writel(intr_status, ioaddr + TYPHOON_REG_INTR_STATUS);
+
+	if(netif_rx_schedule_prep(dev)) {
+		writel(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
+		typhoon_post_pci_writes(ioaddr);
+		__netif_rx_schedule(dev);
+	} else {
+		printk(KERN_ERR "%s: Error, poll already scheduled\n",
+                       dev->name);
+	}
+}
+
+static void
+typhoon_free_rx_rings(struct typhoon *tp)
+{
+	u32 i;
+
+	for(i = 0; i < RXENT_ENTRIES; i++) {
+		struct rxbuff_ent *rxb = &tp->rxbuffers[i];
+		if(rxb->skb) {
+			pci_unmap_single(tp->pdev, rxb->dma_addr, PKT_BUF_SZ,
+				       PCI_DMA_FROMDEVICE);
+			dev_kfree_skb(rxb->skb);
+			rxb->skb = NULL;
+		}
+	}
+}
+
+static int
+typhoon_sleep(struct typhoon *tp, int state, u16 events)
+{
+	struct pci_dev *pdev = tp->pdev;
+	unsigned long ioaddr = tp->ioaddr;
+	struct cmd_desc xp_cmd;
+	int err;
+
+	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_ENABLE_WAKE_EVENTS);
+	xp_cmd.parm1 = events;
+	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+	if(err < 0) {
+		printk(KERN_ERR "%s: typhoon_sleep(): wake events cmd err %d\n",
+				tp->name, err);
+		return err;
+	}
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_GOTO_SLEEP);
+	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+	if(err < 0) {
+		printk(KERN_ERR "%s: typhoon_sleep(): sleep cmd err %d\n",
+				tp->name, err);
+		return err;
+	}
+
+	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_SLEEPING) < 0)
+		return -ETIMEDOUT;
+
+	pci_enable_wake(tp->pdev, state, 1);
+	pci_disable_device(pdev);
+	return pci_set_power_state(pdev, state);
+}
+
+static int
+typhoon_wakeup(struct typhoon *tp, int wait_type)
+{
+	struct pci_dev *pdev = tp->pdev;
+	unsigned long ioaddr = tp->ioaddr;
+
+	pci_set_power_state(pdev, 0);
+	pci_restore_state(pdev, tp->pci_state);
+
+	writel(TYPHOON_BOOTCMD_WAKEUP, ioaddr + TYPHOON_REG_COMMAND);
+	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_WAITING_FOR_HOST) < 0)
+		return typhoon_reset(ioaddr, wait_type);
+
+	return 0;
+}
+
+static int
+typhoon_start_runtime(struct typhoon *tp)
+{
+	struct net_device *dev = tp->dev;
+	unsigned long ioaddr = tp->ioaddr;
+	struct cmd_desc xp_cmd;
+	int err;
+
+	typhoon_init_rings(tp);
+	typhoon_fill_free_ring(tp);
+
+	err = typhoon_download_firmware(tp);
+	if(err < 0) {
+		printk("%s: cannot load runtime on 3XP\n", tp->name);
+		goto error_out;
+	}
+
+	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_BOOT) < 0) {
+		printk("%s: cannot boot 3XP\n", tp->name);
+		err = -EIO;
+		goto error_out;
+	}
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_MAX_PKT_SIZE);
+	xp_cmd.parm1 = cpu_to_le16(PKT_BUF_SZ);
+	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+	if(err < 0)
+		goto error_out;
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_MAC_ADDRESS);
+	xp_cmd.parm1 = cpu_to_le16(ntohs(*(u16 *)&dev->dev_addr[0]));
+	xp_cmd.parm2 = cpu_to_le32(ntohl(*(u32 *)&dev->dev_addr[2]));
+	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+	if(err < 0)
+		goto error_out;
+
+	/* Disable IRQ coalescing -- we can reenable it when 3Com gives
+	 * us some more information on how to control it.
+	 */
+	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_IRQ_COALESCE_CTRL);
+	xp_cmd.parm1 = 0;
+	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+	if(err < 0)
+		goto error_out;
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_XCVR_SELECT);
+	xp_cmd.parm1 = tp->xcvr_select;
+	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+	if(err < 0)
+		goto error_out;
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_VLAN_TYPE_WRITE);
+	xp_cmd.parm1 = __constant_cpu_to_le16(ETH_P_8021Q);
+	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+	if(err < 0)
+		goto error_out;
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_OFFLOAD_TASKS);
+	spin_lock_bh(&tp->state_lock);
+	xp_cmd.parm2 = tp->offload;
+	xp_cmd.parm3 = tp->offload;
+	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+	spin_unlock_bh(&tp->state_lock);
+	if(err < 0)
+		goto error_out;
+
+	typhoon_set_rx_mode(dev);
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_TX_ENABLE);
+	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+	if(err < 0)
+		goto error_out;
+
+	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_RX_ENABLE);
+	err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+	if(err < 0)
+		goto error_out;
+
+	tp->card_state = Running;
+	smp_wmb();
+
+	writel(TYPHOON_INTR_ENABLE_ALL, ioaddr + TYPHOON_REG_INTR_ENABLE);
+	writel(TYPHOON_INTR_NONE, ioaddr + TYPHOON_REG_INTR_MASK);
+	typhoon_post_pci_writes(ioaddr);
+
+	return 0;
+
+error_out:
+	typhoon_reset(ioaddr, WaitNoSleep);
+	typhoon_free_rx_rings(tp);
+	typhoon_init_rings(tp);
+	return err;
+}
+
+static int
+typhoon_stop_runtime(struct typhoon *tp, int wait_type)
+{
+	struct typhoon_indexes *indexes = tp->indexes;
+	struct transmit_ring *txLo = &tp->txLoRing;
+	unsigned long ioaddr = tp->ioaddr;
+	struct cmd_desc xp_cmd;
+	int i;
+
+	/* Disable interrupts early, since we can't schedule a poll
+	 * when called with !netif_running(). This will be posted
+	 * when we force the posting of the command.
+	 */
+	writel(TYPHOON_INTR_NONE, ioaddr + TYPHOON_REG_INTR_ENABLE);
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_RX_DISABLE);
+	typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+
+	/* Wait 1/2 sec for any outstanding transmits to occur
+	 * We'll cleanup after the reset if this times out.
+	 */
+	for(i = 0; i < TYPHOON_WAIT_TIMEOUT; i++) {
+		if(indexes->txLoCleared == cpu_to_le32(txLo->lastWrite))
+			break;
+		udelay(TYPHOON_UDELAY);
+	}
+
+	if(i == TYPHOON_WAIT_TIMEOUT)
+		printk(KERN_ERR
+		       "%s: halt timed out waiting for Tx to complete\n",
+		       tp->name);
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_TX_DISABLE);
+	typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+
+	/* save the statistics so when we bring the interface up again,
+	 * the values reported to userspace are correct.
+	 */
+	tp->card_state = Sleeping;
+	smp_wmb();
+	typhoon_do_get_stats(tp);
+	memcpy(&tp->stats_saved, &tp->stats, sizeof(struct net_device_stats));
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_HALT);
+	typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
+
+	if(typhoon_wait_status(ioaddr, TYPHOON_STATUS_HALTED) < 0)
+		printk(KERN_ERR "%s: timed out waiting for 3XP to halt\n",
+		       tp->name);
+
+	if(typhoon_reset(ioaddr, wait_type) < 0) {
+		printk(KERN_ERR "%s: unable to reset 3XP\n", tp->name);
+		return -ETIMEDOUT;
+	}
+
+	/* cleanup any outstanding Tx packets */
+	if(indexes->txLoCleared != cpu_to_le32(txLo->lastWrite)) {
+		indexes->txLoCleared = cpu_to_le32(txLo->lastWrite);
+		typhoon_clean_tx(tp, &tp->txLoRing, &indexes->txLoCleared);
+	}
+
+	return 0;
+}
+
+static void
+typhoon_tx_timeout(struct net_device *dev)
+{
+	struct typhoon *tp = (struct typhoon *) dev->priv;
+
+	if(typhoon_reset(dev->base_addr, WaitNoSleep) < 0) {
+		printk(KERN_WARNING "%s: could not reset in tx timeout\n",
+					dev->name);
+		goto truely_dead;
+	}
+
+	/* If we ever start using the Hi ring, it will need cleaning too */
+	typhoon_clean_tx(tp, &tp->txLoRing, &tp->indexes->txLoCleared);
+	typhoon_free_rx_rings(tp);
+
+	if(typhoon_start_runtime(tp) < 0) {
+		printk(KERN_ERR "%s: could not start runtime in tx timeout\n",
+					dev->name);
+		goto truely_dead;
+        }
+
+	netif_wake_queue(dev);
+	return;
+
+truely_dead:
+	/* Reset the hardware, and turn off carrier to avoid more timeouts */
+	typhoon_reset(dev->base_addr, NoWait);
+	netif_carrier_off(dev);
+}
+
+static int
+typhoon_open(struct net_device *dev)
+{
+	struct typhoon *tp = (struct typhoon *) dev->priv;
+	int err;
+
+	err = typhoon_wakeup(tp, WaitSleep);
+	if(err < 0) {
+		printk(KERN_ERR "%s: unable to wakeup device\n", dev->name);
+		goto out_sleep;
+	}
+
+	err = request_irq(dev->irq, &typhoon_interrupt, SA_SHIRQ,
+				dev->name, dev);
+	if(err < 0)
+		goto out_sleep;
+
+	err = typhoon_start_runtime(tp);
+	if(err < 0)
+		goto out_irq;
+
+	netif_start_queue(dev);
+	return 0;
+
+out_irq:
+	free_irq(dev->irq, dev);
+
+out_sleep:
+	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
+		printk(KERN_ERR "%s: unable to reboot into sleep img\n",
+				dev->name);
+		typhoon_reset(dev->base_addr, NoWait);
+		goto out;
+	}
+
+	if(typhoon_sleep(tp, 3, 0) < 0) 
+		printk(KERN_ERR "%s: unable to go back to sleep\n", dev->name);
+
+out:
+	return err;
+}
+
+static int
+typhoon_close(struct net_device *dev)
+{
+	struct typhoon *tp = (struct typhoon *) dev->priv;
+
+	netif_stop_queue(dev);
+
+	if(typhoon_stop_runtime(tp, WaitSleep) < 0)
+		printk(KERN_ERR "%s: unable to stop runtime\n", dev->name);
+
+	/* Make sure there is no irq handler running on a different CPU. */
+	typhoon_synchronize_irq(dev->irq);
+	free_irq(dev->irq, dev);
+
+	typhoon_free_rx_rings(tp);
+	typhoon_init_rings(tp);
+
+	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0)
+		printk(KERN_ERR "%s: unable to boot sleep image\n", dev->name);
+
+	if(typhoon_sleep(tp, 3, 0) < 0)
+		printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name);
+
+	return 0;
+}
+
+#if CONFIG_PM
+static int
+typhoon_resume(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct typhoon *tp = (struct typhoon *) dev->priv;
+
+	/* If we're down, resume when we are upped.
+	 */
+	if(!netif_running(dev))
+		return 0;
+
+	if(typhoon_wakeup(tp, WaitNoSleep) < 0) {
+		printk(KERN_ERR "%s: critical: could not wake up in resume\n",
+				dev->name);
+		goto reset;
+	}
+
+	if(typhoon_start_runtime(tp) < 0) {
+		printk(KERN_ERR "%s: critical: could not start runtime in "
+				"resume\n", dev->name);
+		goto reset;
+	}
+
+	netif_device_attach(dev);
+	netif_start_queue(dev);
+	return 0;
+
+reset:
+	typhoon_reset(dev->base_addr, NoWait);
+	return -EBUSY;
+}
+
+static int
+typhoon_suspend(struct pci_dev *pdev, u32 state)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct typhoon *tp = (struct typhoon *) dev->priv;
+	struct cmd_desc xp_cmd;
+
+	/* If we're down, we're already suspended.
+	 */
+	if(!netif_running(dev))
+		return 0;
+
+	spin_lock_bh(&tp->state_lock);
+	if(tp->vlgrp && tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) {
+		spin_unlock_bh(&tp->state_lock);
+		printk(KERN_ERR "%s: cannot do WAKE_MAGIC with VLANS\n",
+				dev->name);
+		return -EBUSY;
+	}
+	spin_unlock_bh(&tp->state_lock);
+
+	netif_device_detach(dev);
+
+	if(typhoon_stop_runtime(tp, WaitNoSleep) < 0) {
+		printk(KERN_ERR "%s: unable to stop runtime\n", dev->name);
+		goto need_resume;
+	}
+
+	typhoon_free_rx_rings(tp);
+	typhoon_init_rings(tp);
+
+	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
+		printk(KERN_ERR "%s: unable to boot sleep image\n", dev->name);
+		goto need_resume;
+	}
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_MAC_ADDRESS);
+	xp_cmd.parm1 = cpu_to_le16(ntohs(*(u16 *)&dev->dev_addr[0]));
+	xp_cmd.parm2 = cpu_to_le32(ntohl(*(u32 *)&dev->dev_addr[2]));
+	if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) {
+		printk(KERN_ERR "%s: unable to set mac address in suspend\n",
+				dev->name);
+		goto need_resume;
+	}
+
+	INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_SET_RX_FILTER);
+	xp_cmd.parm1 = TYPHOON_RX_FILTER_DIRECTED | TYPHOON_RX_FILTER_BROADCAST;
+	if(typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL) < 0) {
+		printk(KERN_ERR "%s: unable to set rx filter in suspend\n",
+				dev->name);
+		goto need_resume;
+	}
+
+	if(typhoon_sleep(tp, state, tp->wol_events) < 0) {
+		printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name);
+		goto need_resume;
+	}
+
+	return 0;
+
+need_resume:
+	typhoon_resume(pdev);
+	return -EBUSY;
+}
+
+static int
+typhoon_enable_wake(struct pci_dev *pdev, u32 state, int enable)
+{
+	return pci_enable_wake(pdev, state, enable);
+}
+#endif
+
+static int __devinit
+typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	static int did_version = 0;
+	struct net_device *dev;
+	struct typhoon *tp;
+	int card_id = (int) ent->driver_data;
+	unsigned long ioaddr;
+	void *shared;
+	dma_addr_t shared_dma;
+	struct cmd_desc xp_cmd;
+	struct resp_desc xp_resp;
+	int i;
+	int err = 0;
+
+	if(!did_version++)
+		printk(KERN_INFO "%s", version);
+
+	dev = alloc_etherdev(sizeof(*tp));
+	if(dev == NULL) {
+		printk(ERR_PFX "%s: unable to alloc new net device\n",
+		       pdev->slot_name);
+		err = -ENOMEM;
+		goto error_out;
+	}
+	SET_MODULE_OWNER(dev);
+
+	err = pci_enable_device(pdev);
+	if(err < 0) {
+		printk(ERR_PFX "%s: unable to enable device\n",
+		       pdev->slot_name);
+		goto error_out_dev;
+	}
+
+	/* If we transitioned from D3->D0 in pci_enable_device(),
+	 * we lost our configuration and need to restore it to the
+	 * conditions at boot.
+	 */
+	pci_restore_state(pdev, NULL);
+
+	err = pci_set_dma_mask(pdev, 0xffffffffULL);
+	if(err < 0) {
+		printk(ERR_PFX "%s: No usable DMA configuration\n",
+		       pdev->slot_name);
+		goto error_out_dev;
+	}
+
+	/* sanity checks, resource #1 is our mmio area
+	 */
+	if(!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
+		printk(ERR_PFX
+		       "%s: region #1 not a PCI MMIO resource, aborting\n",
+		       pdev->slot_name);
+		err = -ENODEV;
+		goto error_out_dev;
+	}
+	if(pci_resource_len(pdev, 1) < 128) {
+		printk(ERR_PFX "%s: Invalid PCI MMIO region size, aborting\n",
+		       pdev->slot_name);
+		err = -ENODEV;
+		goto error_out_dev;
+	}
+
+	err = pci_request_regions(pdev, "typhoon");
+	if(err < 0) {
+		printk(ERR_PFX "%s: could not request regions\n",
+		       pdev->slot_name);
+		goto error_out_dev;
+	}
+
+	pci_set_master(pdev);
+	pci_set_mwi(pdev);
+
+	/* map our MMIO region
+	 */
+	ioaddr = pci_resource_start(pdev, 1);
+	ioaddr = (unsigned long) ioremap(ioaddr, 128);
+	if(!ioaddr) {
+		printk(ERR_PFX "%s: cannot remap MMIO, aborting\n",
+		       pdev->slot_name);
+		err = -EIO;
+		goto error_out_regions;
+	}
+	dev->base_addr = ioaddr;
+
+	/* allocate pci dma space for rx and tx descriptor rings
+	 */
+	shared = pci_alloc_consistent(pdev, sizeof(struct typhoon_shared),
+				      &shared_dma);
+	if(!shared) {
+		printk(ERR_PFX "%s: could not allocate DMA memory\n",
+		       pdev->slot_name);
+		err = -ENOMEM;
+		goto error_out_remap;
+	}
+
+	dev->irq = pdev->irq;
+	tp = dev->priv;
+	tp->shared = (struct typhoon_shared *) shared;
+	tp->shared_dma = shared_dma;
+	tp->pdev = pdev;
+	tp->tx_pdev = pdev;
+	tp->ioaddr = dev->base_addr;
+	tp->tx_ioaddr = dev->base_addr;
+	tp->dev = dev;
+
+	/* need to be able to restore PCI state after a suspend */
+	pci_save_state(pdev, tp->pci_state);
+
+	/* Init sequence:
+	 * 1) Reset the adapter to clear any bad juju
+	 * 2) Reload the sleep image
+	 * 3) Boot the sleep image
+	 * 4) Get the hardware address.
+	 * 5) Put the card to sleep.
+	 */
+	if(typhoon_reset(ioaddr, WaitSleep) < 0) {
+		printk(ERR_PFX "%s: could not reset 3XP\n", pdev->slot_name);
+		err = -EIO;
+		goto error_out_dma;
+	}
+
+	/* dev->name is not valid until we register, but we need to
+	 * use some common routines to initialize the card. So that those
+	 * routines print the right name, we keep our oun pointer to the name
+	 */
+	tp->name = pdev->slot_name;
+
+	typhoon_init_interface(tp);
+	typhoon_init_rings(tp);
+
+	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0) {
+		printk(ERR_PFX "%s: cannot boot 3XP sleep image\n",
+		       pdev->slot_name);
+		err = -EIO;
+		goto error_out_reset;
+	}
+
+	INIT_COMMAND_WITH_RESPONSE(&xp_cmd, TYPHOON_CMD_READ_MAC_ADDRESS);
+	if(typhoon_issue_command(tp, 1, &xp_cmd, 1, &xp_resp) < 0) {
+		printk(ERR_PFX "%s: cannot read MAC address\n",
+		       pdev->slot_name);
+		err = -EIO;
+		goto error_out_reset;
+	}
+
+	*(u16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp.parm1));
+	*(u32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp.parm2));
+
+	if(!is_valid_ether_addr(dev->dev_addr)) {
+		printk(ERR_PFX "%s: Could not obtain valid ethernet address, "
+		       "aborting\n", pdev->slot_name);
+		goto error_out_reset;
+	}
+
+	if(typhoon_sleep(tp, 3, 0) < 0) {
+		printk(ERR_PFX "%s: cannot put adapter to sleep\n",
+		       pdev->slot_name);
+		err = -EIO;
+		goto error_out_reset;
+	}
+
+	tp->capabilities = typhoon_card_info[card_id].capabilities;
+	tp->xcvr_select = TYPHOON_XCVR_AUTONEG;
+
+	/* The chip-specific entries in the device structure. */
+	dev->open		= typhoon_open;
+	dev->hard_start_xmit	= typhoon_start_tx;
+	dev->stop		= typhoon_close;
+	dev->set_multicast_list	= typhoon_set_rx_mode;
+	dev->tx_timeout		= typhoon_tx_timeout;
+	dev->poll		= typhoon_poll;
+	dev->weight		= 16;
+	dev->watchdog_timeo	= TX_TIMEOUT;
+	dev->get_stats		= typhoon_get_stats;
+	dev->set_mac_address	= typhoon_set_mac_address;
+	dev->do_ioctl		= typhoon_ioctl;
+	dev->vlan_rx_register	= typhoon_vlan_rx_register;
+	dev->vlan_rx_kill_vid	= typhoon_vlan_rx_kill_vid;
+
+	/* We can handle scatter gather, up to 16 entries, and
+	 * we can do IP checksumming (only version 4, doh...)
+	 */
+	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	dev->features |= NETIF_F_TSO;
+
+	if(register_netdev(dev) < 0)
+		goto error_out_reset;
+
+	/* fixup our local name */
+	tp->name = dev->name;
+
+	pci_set_drvdata(pdev, dev);
+
+	printk(KERN_INFO "%s: %s at 0x%lx, ",
+	       dev->name, typhoon_card_info[card_id].name, ioaddr);
+	for(i = 0; i < 5; i++)
+		printk("%2.2x:", dev->dev_addr[i]);
+	printk("%2.2x\n", dev->dev_addr[i]);
+
+	return 0;
+
+error_out_reset:
+	typhoon_reset(ioaddr, NoWait);
+
+error_out_dma:
+	pci_free_consistent(pdev, sizeof(struct typhoon_shared),
+			    shared, shared_dma);
+error_out_remap:
+	iounmap((void *) ioaddr);
+error_out_regions:
+	pci_release_regions(pdev);
+error_out_dev:
+	kfree(dev);
+error_out:
+	return err;
+}
+
+static void __devexit
+typhoon_remove_one(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct typhoon *tp = (struct typhoon *) (dev->priv);
+
+	unregister_netdev(dev);
+	pci_set_power_state(pdev, 0);
+	pci_restore_state(pdev, tp->pci_state);
+	typhoon_reset(dev->base_addr, NoWait);
+	iounmap((char *) (dev->base_addr));
+	pci_free_consistent(pdev, sizeof(struct typhoon_shared),
+			    tp->shared, tp->shared_dma);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
+	kfree(dev);
+}
+
+static struct pci_driver typhoon_driver = {
+	.name		= DRV_MODULE_NAME,
+	.id_table	= typhoon_pci_tbl,
+	.probe		= typhoon_init_one,
+	.remove		= __devexit_p(typhoon_remove_one),
+#if CONFIG_PM
+	.suspend	= typhoon_suspend,
+	.resume		= typhoon_resume,
+	.enable_wake	= typhoon_enable_wake,
+#endif
+};
+
+static int __init
+typhoon_init(void)
+{
+	return pci_module_init(&typhoon_driver);
+}
+
+static void __exit
+typhoon_cleanup(void)
+{
+	pci_unregister_driver(&typhoon_driver);
+}
+
+module_init(typhoon_init);
+module_exit(typhoon_cleanup);
diff -Nru a/drivers/net/typhoon.h b/drivers/net/typhoon.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/net/typhoon.h	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,613 @@
+/* typhoon.h:	chip info for the 3Com 3CR990 family of controllers */
+/*
+	Written 2002-2003 by David Dillow <dave@thedillows.org>
+
+	This software may be used and distributed according to the terms of
+	the GNU General Public License (GPL), incorporated herein by reference.
+	Drivers based on or derived from this code fall under the GPL and must
+	retain the authorship, copyright and license notice.  This file is not
+	a complete program and may only be used when the entire operating
+	system is licensed under the GPL.
+
+	This software is available on a public web site. It may enable
+	cryptographic capabilities of the 3Com hardware, and may be
+	exported from the United States under License Exception "TSU"
+	pursuant to 15 C.F.R. Section 740.13(e).
+
+	This work was funded by the National Library of Medicine under
+	the Department of Energy project number 0274DD06D1 and NLM project
+	number Y1-LM-2015-01.
+*/
+
+/* All Typhoon ring positions are specificed in bytes, and point to the
+ * first "clean" entry in the ring -- ie the next entry we use for whatever
+ * purpose.
+ */
+
+/* The Typhoon basic ring
+ * ringBase:  where this ring lives (our virtual address)
+ * lastWrite: the next entry we'll use
+ */
+struct basic_ring {
+	u8 *ringBase;
+	u32 lastWrite;
+};
+
+/* The Typoon transmit ring -- same as a basic ring, plus:
+ * lastRead:      where we're at in regard to cleaning up the ring
+ * writeRegister: register to use for writing (different for Hi & Lo rings)
+ */
+struct transmit_ring {
+	u8 *ringBase;
+	u32 lastWrite;
+	u32 lastRead;
+	int writeRegister;
+};
+
+/* The host<->Typhoon ring index structure
+ * This indicates the current positions in the rings
+ * 
+ * All values must be in little endian format for the 3XP
+ *
+ * rxHiCleared:   entry we've cleared to in the Hi receive ring
+ * rxLoCleared:   entry we've cleared to in the Lo receive ring
+ * rxBuffReady:   next entry we'll put a free buffer in
+ * respCleared:   entry we've cleared to in the response ring
+ *
+ * txLoCleared:   entry the NIC has cleared to in the Lo transmit ring
+ * txHiCleared:   entry the NIC has cleared to in the Hi transmit ring
+ * rxLoReady:     entry the NIC has filled to in the Lo receive ring
+ * rxBuffCleared: entry the NIC has cleared in the free buffer ring
+ * cmdCleared:    entry the NIC has cleared in the command ring
+ * respReady:     entry the NIC has filled to in the response ring
+ * rxHiReady:     entry the NIC has filled to in the Hi receive ring
+ */
+struct typhoon_indexes {
+	/* The first four are written by the host, and read by the NIC */
+	volatile u32 rxHiCleared;
+	volatile u32 rxLoCleared;
+	volatile u32 rxBuffReady;
+	volatile u32 respCleared;
+
+	/* The remaining are written by the NIC, and read by the host */
+	volatile u32 txLoCleared;
+	volatile u32 txHiCleared;
+	volatile u32 rxLoReady;
+	volatile u32 rxBuffCleared;
+	volatile u32 cmdCleared;
+	volatile u32 respReady;
+	volatile u32 rxHiReady;
+} __attribute__ ((packed));
+
+/* The host<->Typhoon interface
+ * Our means of communicating where things are
+ *
+ * All values must be in little endian format for the 3XP
+ *
+ * ringIndex:   64 bit bus address of the index structure
+ * txLoAddr:    64 bit bus address of the Lo transmit ring
+ * txLoSize:    size (in bytes) of the Lo transmit ring
+ * txHi*:       as above for the Hi priority transmit ring
+ * rxLo*:       as above for the Lo priority receive ring
+ * rxBuff*:     as above for the free buffer ring
+ * cmd*:        as above for the command ring
+ * resp*:       as above for the response ring
+ * zeroAddr:    64 bit bus address of a zero word (for DMA)
+ * rxHi*:       as above for the Hi Priority receive ring
+ *
+ * While there is room for 64 bit addresses, current versions of the 3XP
+ * only do 32 bit addresses, so the *Hi for each of the above will always
+ * be zero.
+ */
+struct typhoon_interface {
+	u32 ringIndex;
+	u32 ringIndexHi;
+	u32 txLoAddr;
+	u32 txLoAddrHi;
+	u32 txLoSize;
+	u32 txHiAddr;
+	u32 txHiAddrHi;
+	u32 txHiSize;
+	u32 rxLoAddr;
+	u32 rxLoAddrHi;
+	u32 rxLoSize;
+	u32 rxBuffAddr;
+	u32 rxBuffAddrHi;
+	u32 rxBuffSize;
+	u32 cmdAddr;
+	u32 cmdAddrHi;
+	u32 cmdSize;
+	u32 respAddr;
+	u32 respAddrHi;
+	u32 respSize;
+	u32 zeroAddr;
+	u32 zeroAddrHi;
+	u32 rxHiAddr;
+	u32 rxHiAddrHi;
+	u32 rxHiSize;
+} __attribute__ ((packed));
+
+/* The Typhoon transmit/fragment descriptor
+ *
+ * A packet is described by a packet descriptor, followed by option descriptors,
+ * if any, then one or more fragment descriptors.
+ * 
+ * Packet descriptor:
+ * flags:	Descriptor type
+ * len:i	zero, or length of this packet
+ * addr*:	8 bytes of opaque data to the firmware -- for skb pointer
+ * processFlags: Determine offload tasks to perform on this packet.
+ *
+ * Fragment descriptor:
+ * flags:	Descriptor type
+ * len:i	length of this fragment
+ * addr:	low bytes of DMA address for this part of the packet
+ * addrHi:	hi bytes of DMA address for this part of the packet
+ * processFlags: must be zero
+ *
+ * TYPHOON_DESC_VALID is not mentioned in their docs, but their Linux
+ * driver uses it.
+ */
+struct tx_desc {
+	u8  flags;
+#define TYPHOON_TYPE_MASK	0x07
+#define 	TYPHOON_FRAG_DESC	0x00
+#define 	TYPHOON_TX_DESC		0x01
+#define 	TYPHOON_CMD_DESC	0x02
+#define 	TYPHOON_OPT_DESC	0x03
+#define 	TYPHOON_RX_DESC		0x04
+#define 	TYPHOON_RESP_DESC	0x05
+#define TYPHOON_OPT_TYPE_MASK	0xf0
+#define 	TYPHOON_OPT_IPSEC	0x00
+#define 	TYPHOON_OPT_TCP_SEG	0x10
+#define TYPHOON_CMD_RESPOND	0x40
+#define TYPHOON_RESP_ERROR	0x40
+#define TYPHOON_RX_ERROR	0x40
+#define TYPHOON_DESC_VALID	0x80
+	u8  numDesc;
+	u16 len;
+	u32 addr;
+	u32 addrHi;
+	u32 processFlags;
+#define TYPHOON_TX_PF_NO_CRC		__constant_cpu_to_le32(0x00000001)
+#define TYPHOON_TX_PF_IP_CHKSUM		__constant_cpu_to_le32(0x00000002)
+#define TYPHOON_TX_PF_TCP_CHKSUM	__constant_cpu_to_le32(0x00000004)
+#define TYPHOON_TX_PF_TCP_SEGMENT	__constant_cpu_to_le32(0x00000008)
+#define TYPHOON_TX_PF_INSERT_VLAN	__constant_cpu_to_le32(0x00000010)
+#define TYPHOON_TX_PF_IPSEC		__constant_cpu_to_le32(0x00000020)
+#define TYPHOON_TX_PF_VLAN_PRIORITY	__constant_cpu_to_le32(0x00000040)
+#define TYPHOON_TX_PF_UDP_CHKSUM	__constant_cpu_to_le32(0x00000080)
+#define TYPHOON_TX_PF_PAD_FRAME		__constant_cpu_to_le32(0x00000100)
+#define TYPHOON_TX_PF_RESERVED		__constant_cpu_to_le32(0x00000e00)
+#define TYPHOON_TX_PF_VLAN_MASK		__constant_cpu_to_le32(0x0ffff000)
+#define TYPHOON_TX_PF_INTERNAL		__constant_cpu_to_le32(0xf0000000)
+#define TYPHOON_TX_PF_VLAN_TAG_SHIFT	12
+} __attribute__ ((packed));
+
+/* The TCP Segmentation offload option descriptor
+ *
+ * flags:	descriptor type
+ * numDesc:	must be 1
+ * mss_flags:	bits 0-11 (little endian) are MSS, 12 is first TSO descriptor
+ *			13 is list TSO descriptor, set both if only one TSO
+ * respAddrLo:	low bytes of address of the bytesTx field of this descriptor
+ * bytesTx:	total number of bytes in this TSO request
+ * status:	0 on completion
+ */
+struct tcpopt_desc {
+	u8  flags;
+	u8  numDesc;
+	u16 mss_flags;
+#define TYPHOON_TSO_FIRST		__constant_cpu_to_le16(0x1000)
+#define TYPHOON_TSO_LAST		__constant_cpu_to_le16(0x2000)
+	u32 respAddrLo;
+	u32 bytesTx;
+	u32 status;
+} __attribute__ ((packed));
+
+/* The IPSEC Offload descriptor
+ *
+ * flags:	descriptor type
+ * numDesc:	must be 1
+ * ipsecFlags:	bit 0: 0 -- generate IV, 1 -- use supplied IV
+ * sa1, sa2:	Security Association IDs for this packet
+ * reserved:	set to 0
+ */
+struct ipsec_desc {
+	u8  flags;
+	u8  numDesc;
+	u16 ipsecFlags;
+#define TYPHOON_IPSEC_GEN_IV	__constant_cpu_to_le16(0x0000)
+#define TYPHOON_IPSEC_USE_IV	__constant_cpu_to_le16(0x0001)
+	u32 sa1;
+	u32 sa2;
+	u32 reserved;
+} __attribute__ ((packed));
+
+/* The Typhoon receive descriptor (Updated by NIC)
+ *
+ * flags:         Descriptor type, error indication
+ * numDesc:       Always zero
+ * frameLen:      the size of the packet received
+ * addr:          low 32 bytes of the virtual addr passed in for this buffer
+ * addrHi:        high 32 bytes of the virtual addr passed in for this buffer
+ * rxStatus:      Error if set in flags, otherwise result of offload processing
+ * filterResults: results of filtering on packet, not used
+ * ipsecResults:  Results of IPSEC processing
+ * vlanTag:       the 801.2q TCI from the packet
+ */
+struct rx_desc {
+	u8  flags;
+	u8  numDesc;
+	u16 frameLen;
+	u32 addr;
+	u32 addrHi;
+	u32 rxStatus;
+#define TYPHOON_RX_ERR_INTERNAL		__constant_cpu_to_le32(0x00000000)
+#define TYPHOON_RX_ERR_FIFO_UNDERRUN	__constant_cpu_to_le32(0x00000001)
+#define TYPHOON_RX_ERR_BAD_SSD		__constant_cpu_to_le32(0x00000002)
+#define TYPHOON_RX_ERR_RUNT		__constant_cpu_to_le32(0x00000003)
+#define TYPHOON_RX_ERR_CRC		__constant_cpu_to_le32(0x00000004)
+#define TYPHOON_RX_ERR_OVERSIZE		__constant_cpu_to_le32(0x00000005)
+#define TYPHOON_RX_ERR_ALIGN		__constant_cpu_to_le32(0x00000006)
+#define TYPHOON_RX_ERR_DRIBBLE		__constant_cpu_to_le32(0x00000007)
+#define TYPHOON_RX_PROTO_MASK		__constant_cpu_to_le32(0x00000003)
+#define TYPHOON_RX_PROTO_UNKNOWN	__constant_cpu_to_le32(0x00000000)
+#define TYPHOON_RX_PROTO_IP		__constant_cpu_to_le32(0x00000001)
+#define TYPHOON_RX_PROTO_IPX		__constant_cpu_to_le32(0x00000002)
+#define TYPHOON_RX_VLAN			__constant_cpu_to_le32(0x00000004)
+#define TYPHOON_RX_IP_FRAG		__constant_cpu_to_le32(0x00000008)
+#define TYPHOON_RX_IPSEC		__constant_cpu_to_le32(0x00000010)
+#define TYPHOON_RX_IP_CHK_FAIL		__constant_cpu_to_le32(0x00000020)
+#define TYPHOON_RX_TCP_CHK_FAIL		__constant_cpu_to_le32(0x00000040)
+#define TYPHOON_RX_UDP_CHK_FAIL		__constant_cpu_to_le32(0x00000080)
+#define TYPHOON_RX_IP_CHK_GOOD		__constant_cpu_to_le32(0x00000100)
+#define TYPHOON_RX_TCP_CHK_GOOD		__constant_cpu_to_le32(0x00000200)
+#define TYPHOON_RX_UDP_CHK_GOOD		__constant_cpu_to_le32(0x00000400)
+	u16 filterResults;
+#define TYPHOON_RX_FILTER_MASK		__constant_cpu_to_le16(0x7fff)
+#define TYPHOON_RX_FILTERED		__constant_cpu_to_le16(0x8000)
+	u16 ipsecResults;
+#define TYPHOON_RX_OUTER_AH_GOOD	__constant_cpu_to_le16(0x0001)
+#define TYPHOON_RX_OUTER_ESP_GOOD	__constant_cpu_to_le16(0x0002)
+#define TYPHOON_RX_INNER_AH_GOOD	__constant_cpu_to_le16(0x0004)
+#define TYPHOON_RX_INNER_ESP_GOOD	__constant_cpu_to_le16(0x0008)
+#define TYPHOON_RX_OUTER_AH_FAIL	__constant_cpu_to_le16(0x0010)
+#define TYPHOON_RX_OUTER_ESP_FAIL	__constant_cpu_to_le16(0x0020)
+#define TYPHOON_RX_INNER_AH_FAIL	__constant_cpu_to_le16(0x0040)
+#define TYPHOON_RX_INNER_ESP_FAIL	__constant_cpu_to_le16(0x0080)
+#define TYPHOON_RX_UNKNOWN_SA		__constant_cpu_to_le16(0x0100)
+#define TYPHOON_RX_ESP_FORMAT_ERR	__constant_cpu_to_le16(0x0200)
+	u32 vlanTag;
+} __attribute__ ((packed));
+
+/* The Typhoon free buffer descriptor, used to give a buffer to the NIC
+ *
+ * physAddr:    low 32 bits of the bus address of the buffer
+ * physAddrHi:  high 32 bits of the bus address of the buffer, always zero
+ * virtAddr:    low 32 bits of the skb address
+ * virtAddrHi:  high 32 bits of the skb address, always zero
+ *
+ * the virt* address is basically two 32 bit cookies, just passed back
+ * from the NIC
+ */
+struct rx_free {
+	u32 physAddr;
+	u32 physAddrHi;
+	u32 virtAddr;
+	u32 virtAddrHi;
+} __attribute__ ((packed));
+
+/* The Typhoon command descriptor, used for commands and responses
+ *
+ * flags:   descriptor type
+ * numDesc: number of descriptors following in this command/response,
+ *				ie, zero for a one descriptor command
+ * cmd:     the command
+ * seqNo:   sequence number (unused)
+ * parm1:   use varies by command
+ * parm2:   use varies by command
+ * parm3:   use varies by command
+ */
+struct cmd_desc {
+	u8  flags;
+	u8  numDesc;
+	u16 cmd;
+#define TYPHOON_CMD_TX_ENABLE		__constant_cpu_to_le16(0x0001)
+#define TYPHOON_CMD_TX_DISABLE		__constant_cpu_to_le16(0x0002)
+#define TYPHOON_CMD_RX_ENABLE		__constant_cpu_to_le16(0x0003)
+#define TYPHOON_CMD_RX_DISABLE		__constant_cpu_to_le16(0x0004)
+#define TYPHOON_CMD_SET_RX_FILTER	__constant_cpu_to_le16(0x0005)
+#define TYPHOON_CMD_READ_STATS		__constant_cpu_to_le16(0x0007)
+#define TYPHOON_CMD_XCVR_SELECT		__constant_cpu_to_le16(0x0013)
+#define TYPHOON_CMD_SET_MAX_PKT_SIZE	__constant_cpu_to_le16(0x001a)
+#define TYPHOON_CMD_READ_MEDIA_STATUS	__constant_cpu_to_le16(0x001b)
+#define TYPHOON_CMD_GOTO_SLEEP		__constant_cpu_to_le16(0x0023)
+#define TYPHOON_CMD_SET_MULTICAST_HASH	__constant_cpu_to_le16(0x0025)
+#define TYPHOON_CMD_SET_MAC_ADDRESS	__constant_cpu_to_le16(0x0026)
+#define TYPHOON_CMD_READ_MAC_ADDRESS	__constant_cpu_to_le16(0x0027)
+#define TYPHOON_CMD_VLAN_TYPE_WRITE	__constant_cpu_to_le16(0x002b)
+#define TYPHOON_CMD_CREATE_SA		__constant_cpu_to_le16(0x0034)
+#define TYPHOON_CMD_DELETE_SA		__constant_cpu_to_le16(0x0035)
+#define TYPHOON_CMD_READ_VERSIONS	__constant_cpu_to_le16(0x0043)
+#define TYPHOON_CMD_IRQ_COALESCE_CTRL	__constant_cpu_to_le16(0x0045)
+#define TYPHOON_CMD_ENABLE_WAKE_EVENTS	__constant_cpu_to_le16(0x0049)
+#define TYPHOON_CMD_SET_OFFLOAD_TASKS	__constant_cpu_to_le16(0x004f)
+#define TYPHOON_CMD_HELLO_RESP		__constant_cpu_to_le16(0x0057)
+#define TYPHOON_CMD_HALT		__constant_cpu_to_le16(0x005d)
+#define TYPHOON_CMD_READ_IPSEC_INFO	__constant_cpu_to_le16(0x005e)
+#define TYPHOON_CMD_GET_IPSEC_ENABLE	__constant_cpu_to_le16(0x0067)
+#define TYPHOON_CMD_GET_CMD_LVL		__constant_cpu_to_le16(0x0069)
+	u16 seqNo;
+	u16 parm1;
+	u32 parm2;
+	u32 parm3;
+} __attribute__ ((packed));
+
+/* The Typhoon response descriptor, see command descriptor for details
+ */
+struct resp_desc {
+	u8  flags;
+	u8  numDesc;
+	u16 cmd;
+	u16 seqNo;
+	u16 parm1;
+	u32 parm2;
+	u32 parm3;
+} __attribute__ ((packed));
+
+#define INIT_COMMAND_NO_RESPONSE(x, command)				\
+	do { struct cmd_desc *_ptr = (x);				\
+		memset(_ptr, 0, sizeof(struct cmd_desc));		\
+		_ptr->flags = TYPHOON_CMD_DESC | TYPHOON_DESC_VALID;	\
+		_ptr->cmd = command;					\
+	} while(0)
+
+/* We set seqNo to 1 if we're expecting a response from this command */
+#define INIT_COMMAND_WITH_RESPONSE(x, command)				\
+	do { struct cmd_desc *_ptr = (x);				\
+		memset(_ptr, 0, sizeof(struct cmd_desc));		\
+		_ptr->flags = TYPHOON_CMD_RESPOND | TYPHOON_CMD_DESC;	\
+		_ptr->flags |= TYPHOON_DESC_VALID; 			\
+		_ptr->cmd = command;					\
+		_ptr->seqNo = 1;					\
+	} while(0)
+
+/* TYPHOON_CMD_SET_RX_FILTER filter bits (cmd.parm1)
+ */
+#define TYPHOON_RX_FILTER_DIRECTED	__constant_cpu_to_le16(0x0001)
+#define TYPHOON_RX_FILTER_ALL_MCAST	__constant_cpu_to_le16(0x0002)
+#define TYPHOON_RX_FILTER_BROADCAST	__constant_cpu_to_le16(0x0004)
+#define TYPHOON_RX_FILTER_PROMISCOUS	__constant_cpu_to_le16(0x0008)
+#define TYPHOON_RX_FILTER_MCAST_HASH	__constant_cpu_to_le16(0x0010)
+
+/* TYPHOON_CMD_READ_STATS response format
+ */
+struct stats_resp {
+	u8  flags;
+	u8  numDesc;
+	u16 cmd;
+	u16 seqNo;
+	u16 unused;
+	u32 txPackets;
+	u64 txBytes;
+	u32 txDeferred;
+	u32 txLateCollisions;
+	u32 txCollisions;
+	u32 txCarrierLost;
+	u32 txMultipleCollisions;
+	u32 txExcessiveCollisions;
+	u32 txFifoUnderruns;
+	u32 txMulticastTxOverflows;
+	u32 txFiltered;
+	u32 rxPacketsGood;
+	u64 rxBytesGood;
+	u32 rxFifoOverruns;
+	u32 BadSSD;
+	u32 rxCrcErrors;
+	u32 rxOversized;
+	u32 rxBroadcast;
+	u32 rxMulticast;
+	u32 rxOverflow;
+	u32 rxFiltered;
+	u32 linkStatus;
+#define TYPHOON_LINK_STAT_MASK		__constant_cpu_to_le32(0x00000001)
+#define TYPHOON_LINK_GOOD		__constant_cpu_to_le32(0x00000001)
+#define TYPHOON_LINK_BAD		__constant_cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_SPEED_MASK		__constant_cpu_to_le32(0x00000002)
+#define TYPHOON_LINK_100MBPS		__constant_cpu_to_le32(0x00000002)
+#define TYPHOON_LINK_10MBPS		__constant_cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_DUPLEX_MASK	__constant_cpu_to_le32(0x00000004)
+#define TYPHOON_LINK_FULL_DUPLEX	__constant_cpu_to_le32(0x00000004)
+#define TYPHOON_LINK_HALF_DUPLEX	__constant_cpu_to_le32(0x00000000)
+	u32 unused2;
+	u32 unused3;
+} __attribute__ ((packed));
+
+/* TYPHOON_CMD_XCVR_SELECT xcvr values (resp.parm1)
+ */
+#define TYPHOON_XCVR_10HALF	__constant_cpu_to_le16(0x0000)
+#define TYPHOON_XCVR_10FULL	__constant_cpu_to_le16(0x0001)
+#define TYPHOON_XCVR_100HALF	__constant_cpu_to_le16(0x0002)
+#define TYPHOON_XCVR_100FULL	__constant_cpu_to_le16(0x0003)
+#define TYPHOON_XCVR_AUTONEG	__constant_cpu_to_le16(0x0004)
+
+/* TYPHOON_CMD_READ_MEDIA_STATUS (resp.parm1)
+ */
+#define TYPHOON_MEDIA_STAT_CRC_STRIP_DISABLE	__constant_cpu_to_le16(0x0004)
+#define TYPHOON_MEDIA_STAT_COLLISION_DETECT	__constant_cpu_to_le16(0x0010)
+#define TYPHOON_MEDIA_STAT_CARRIER_SENSE	__constant_cpu_to_le16(0x0020)
+#define TYPHOON_MEDIA_STAT_POLARITY_REV		__constant_cpu_to_le16(0x0400)
+#define TYPHOON_MEDIA_STAT_NO_LINK		__constant_cpu_to_le16(0x0800)
+
+/* TYPHOON_CMD_SET_MULTICAST_HASH enable values (cmd.parm1)
+ */
+#define TYPHOON_MCAST_HASH_DISABLE	__constant_cpu_to_le16(0x0000)
+#define TYPHOON_MCAST_HASH_ENABLE	__constant_cpu_to_le16(0x0001)
+#define TYPHOON_MCAST_HASH_SET		__constant_cpu_to_le16(0x0002)
+
+/* TYPHOON_CMD_CREATE_SA descriptor and settings
+ */
+struct sa_descriptor {
+	u8  flags;
+	u8  numDesc;
+	u16 cmd;
+	u16 seqNo;
+	u16 mode;
+#define TYPHOON_SA_MODE_NULL		__constant_cpu_to_le16(0x0000)
+#define TYPHOON_SA_MODE_AH		__constant_cpu_to_le16(0x0001)
+#define TYPHOON_SA_MODE_ESP		__constant_cpu_to_le16(0x0002)
+	u8  hashFlags;
+#define TYPHOON_SA_HASH_ENABLE		0x01
+#define TYPHOON_SA_HASH_SHA1		0x02
+#define TYPHOON_SA_HASH_MD5		0x04
+	u8  direction;
+#define TYPHOON_SA_DIR_RX		0x00
+#define TYPHOON_SA_DIR_TX		0x01
+	u8  encryptionFlags;
+#define TYPHOON_SA_ENCRYPT_ENABLE	0x01
+#define TYPHOON_SA_ENCRYPT_DES		0x02
+#define TYPHOON_SA_ENCRYPT_3DES		0x00
+#define TYPHOON_SA_ENCRYPT_3DES_2KEY	0x00
+#define TYPHOON_SA_ENCRYPT_3DES_3KEY	0x04
+#define TYPHOON_SA_ENCRYPT_CBC		0x08
+#define TYPHOON_SA_ENCRYPT_ECB		0x00
+	u8  specifyIndex;
+#define TYPHOON_SA_SPECIFY_INDEX	0x01
+#define TYPHOON_SA_GENERATE_INDEX	0x00
+	u32 SPI;
+	u32 destAddr;
+	u32 destMask;
+	u8  integKey[20];
+	u8  confKey[24];
+	u32 index;
+	u32 unused;
+	u32 unused2;
+} __attribute__ ((packed));
+
+/* TYPHOON_CMD_SET_OFFLOAD_TASKS bits (cmd.parm2 (Tx) & cmd.parm3 (Rx))
+ * This is all for IPv4.
+ */
+#define TYPHOON_OFFLOAD_TCP_CHKSUM	__constant_cpu_to_le32(0x00000002)
+#define TYPHOON_OFFLOAD_UDP_CHKSUM	__constant_cpu_to_le32(0x00000004)
+#define TYPHOON_OFFLOAD_IP_CHKSUM	__constant_cpu_to_le32(0x00000008)
+#define TYPHOON_OFFLOAD_IPSEC		__constant_cpu_to_le32(0x00000010)
+#define TYPHOON_OFFLOAD_BCAST_THROTTLE	__constant_cpu_to_le32(0x00000020)
+#define TYPHOON_OFFLOAD_DHCP_PREVENT	__constant_cpu_to_le32(0x00000040)
+#define TYPHOON_OFFLOAD_VLAN		__constant_cpu_to_le32(0x00000080)
+#define TYPHOON_OFFLOAD_FILTERING	__constant_cpu_to_le32(0x00000100)
+#define TYPHOON_OFFLOAD_TCP_SEGMENT	__constant_cpu_to_le32(0x00000200)
+
+/* TYPHOON_CMD_ENABLE_WAKE_EVENTS bits (cmd.parm1)
+ */
+#define TYPHOON_WAKE_MAGIC_PKT		__constant_cpu_to_le16(0x01)
+#define TYPHOON_WAKE_LINK_EVENT		__constant_cpu_to_le16(0x02)
+#define TYPHOON_WAKE_ICMP_ECHO		__constant_cpu_to_le16(0x04)
+#define TYPHOON_WAKE_ARP		__constant_cpu_to_le16(0x08)
+
+/* These are used to load the firmware image on the NIC
+ */
+struct typhoon_file_header {
+	u8  tag[8];
+	u32 version;
+	u32 numSections;
+	u32 startAddr;
+} __attribute__ ((packed));
+
+struct typhoon_section_header {
+	u32 len;
+	u16 checksum;
+	u16 reserved;
+	u32 startAddr;
+} __attribute__ ((packed));
+
+/* The Typhoon Register offsets
+ */
+#define TYPHOON_REG_SOFT_RESET			0x00
+#define TYPHOON_REG_INTR_STATUS			0x04
+#define TYPHOON_REG_INTR_ENABLE			0x08
+#define TYPHOON_REG_INTR_MASK			0x0c
+#define TYPHOON_REG_SELF_INTERRUPT		0x10
+#define TYPHOON_REG_HOST2ARM7			0x14
+#define TYPHOON_REG_HOST2ARM6			0x18
+#define TYPHOON_REG_HOST2ARM5			0x1c
+#define TYPHOON_REG_HOST2ARM4			0x20
+#define TYPHOON_REG_HOST2ARM3			0x24
+#define TYPHOON_REG_HOST2ARM2			0x28
+#define TYPHOON_REG_HOST2ARM1			0x2c
+#define TYPHOON_REG_HOST2ARM0			0x30
+#define TYPHOON_REG_ARM2HOST3			0x34
+#define TYPHOON_REG_ARM2HOST2			0x38
+#define TYPHOON_REG_ARM2HOST1			0x3c
+#define TYPHOON_REG_ARM2HOST0			0x40
+
+#define TYPHOON_REG_BOOT_DATA_LO		TYPHOON_REG_HOST2ARM5
+#define TYPHOON_REG_BOOT_DATA_HI		TYPHOON_REG_HOST2ARM4
+#define TYPHOON_REG_BOOT_DEST_ADDR		TYPHOON_REG_HOST2ARM3
+#define TYPHOON_REG_BOOT_CHECKSUM		TYPHOON_REG_HOST2ARM2
+#define TYPHOON_REG_BOOT_LENGTH			TYPHOON_REG_HOST2ARM1
+
+#define TYPHOON_REG_DOWNLOAD_BOOT_ADDR		TYPHOON_REG_HOST2ARM1
+
+#define TYPHOON_REG_BOOT_RECORD_ADDR_HI		TYPHOON_REG_HOST2ARM2
+#define TYPHOON_REG_BOOT_RECORD_ADDR_LO		TYPHOON_REG_HOST2ARM1
+
+#define TYPHOON_REG_TX_LO_READY			TYPHOON_REG_HOST2ARM3
+#define TYPHOON_REG_CMD_READY			TYPHOON_REG_HOST2ARM2
+#define TYPHOON_REG_TX_HI_READY			TYPHOON_REG_HOST2ARM1
+
+#define TYPHOON_REG_COMMAND			TYPHOON_REG_HOST2ARM0
+#define TYPHOON_REG_HEARTBEAT			TYPHOON_REG_ARM2HOST3
+#define TYPHOON_REG_STATUS			TYPHOON_REG_ARM2HOST0
+
+/* 3XP Reset values (TYPHOON_REG_SOFT_RESET)
+ */
+#define TYPHOON_RESET_ALL	0x7f
+#define TYPHOON_RESET_NONE	0x00
+
+/* 3XP irq bits (TYPHOON_REG_INTR{STATUS,ENABLE,MASK})
+ *
+ * Some of these came from OpenBSD, as the 3Com docs have it wrong
+ * (INTR_SELF) or don't list it at all (INTR_*_ABORT)
+ *
+ * Enabling irqs on the Heartbeat reg (ArmToHost3) gets you an irq
+ * about every 8ms, so don't do it.
+ */
+#define TYPHOON_INTR_HOST_INT		0x00000001
+#define TYPHOON_INTR_ARM2HOST0		0x00000002
+#define TYPHOON_INTR_ARM2HOST1		0x00000004
+#define TYPHOON_INTR_ARM2HOST2		0x00000008
+#define TYPHOON_INTR_ARM2HOST3		0x00000010
+#define TYPHOON_INTR_DMA0		0x00000020
+#define TYPHOON_INTR_DMA1		0x00000040
+#define TYPHOON_INTR_DMA2		0x00000080
+#define TYPHOON_INTR_DMA3		0x00000100
+#define TYPHOON_INTR_MASTER_ABORT	0x00000200
+#define TYPHOON_INTR_TARGET_ABORT	0x00000400
+#define TYPHOON_INTR_SELF		0x00000800
+#define TYPHOON_INTR_RESERVED		0xfffff000
+
+#define TYPHOON_INTR_BOOTCMD		TYPHOON_INTR_ARM2HOST0
+
+#define TYPHOON_INTR_ENABLE_ALL		0xffffffef
+#define TYPHOON_INTR_ALL		0xffffffff
+#define TYPHOON_INTR_NONE		0x00000000
+
+/* The commands for the 3XP chip (TYPHOON_REG_COMMAND)
+ */
+#define TYPHOON_BOOTCMD_BOOT			0x00
+#define TYPHOON_BOOTCMD_WAKEUP			0xfa
+#define TYPHOON_BOOTCMD_DNLD_COMPLETE		0xfb
+#define TYPHOON_BOOTCMD_SEG_AVAILABLE		0xfc
+#define TYPHOON_BOOTCMD_RUNTIME_IMAGE		0xfd
+#define TYPHOON_BOOTCMD_REG_BOOT_RECORD		0xff
+
+/* 3XP Status values (TYPHOON_REG_STATUS)
+ */
+#define TYPHOON_STATUS_WAITING_FOR_BOOT		0x07
+#define TYPHOON_STATUS_SECOND_INIT		0x08
+#define TYPHOON_STATUS_RUNNING			0x09
+#define TYPHOON_STATUS_WAITING_FOR_HOST		0x0d
+#define TYPHOON_STATUS_WAITING_FOR_SEGMENT	0x10
+#define TYPHOON_STATUS_SLEEPING			0x11
+#define TYPHOON_STATUS_HALTED			0x14
diff -Nru a/drivers/net/wan/comx-hw-comx.c b/drivers/net/wan/comx-hw-comx.c
--- a/drivers/net/wan/comx-hw-comx.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/net/wan/comx-hw-comx.c	Fri Feb 14 15:53:08 2003
@@ -492,11 +492,11 @@
 
 	COMX_CMD(dev, COMX_CMD_INIT); 
 	jiffs = jiffies;
-	while (COMX_readw(dev, OFF_A_L2_LINKUP) != 1 && jiffies < jiffs + HZ) {
+	while (COMX_readw(dev, OFF_A_L2_LINKUP) != 1 && time_before(jiffies, jiffs + HZ)) {
 		schedule_timeout(1);
 	}
 	
-	if (jiffies >= jiffs + HZ) {
+	if (time_after_eq(jiffies, jiffs + HZ)) {
 		printk(KERN_ERR "%s: board timeout on INIT command\n", dev->name);
 		ch->HW_release_board(dev, savep);
 		retval=-EIO;
@@ -507,11 +507,11 @@
 	COMX_CMD(dev, COMX_CMD_OPEN);
 
 	jiffs = jiffies;
-	while (COMX_readw(dev, OFF_A_L2_LINKUP) != 3 && jiffies < jiffs + HZ) {
+	while (COMX_readw(dev, OFF_A_L2_LINKUP) != 3 && time_before(jiffies, jiffs + HZ)) {
 		schedule_timeout(1);
 	}
 	
-	if (jiffies >= jiffs + HZ) {
+	if (time_after_eq(jiffies, jiffs + HZ)) {
 		printk(KERN_ERR "%s: board timeout on OPEN command\n", dev->name);
 		ch->HW_release_board(dev, savep);
 		retval=-EIO;
diff -Nru a/drivers/net/wan/comx-hw-mixcom.c b/drivers/net/wan/comx-hw-mixcom.c
--- a/drivers/net/wan/comx-hw-mixcom.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/net/wan/comx-hw-mixcom.c	Fri Feb 14 15:53:12 2003
@@ -104,7 +104,7 @@
 	unsigned delay = 0;
 
 	while ((cec = (rd_hscx(dev, HSCX_STAR) & HSCX_CEC) != 0) && 
-	    (jiffs + HZ > jiffies)) {
+	    time_before(jiffies, jiffs + HZ)) {
 		udelay(1);
 		if (++delay > (100000 / HZ)) break;
 	}
diff -Nru a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
--- a/drivers/net/wireless/orinoco.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/net/wireless/orinoco.c	Fri Feb 14 15:53:12 2003
@@ -3057,7 +3057,7 @@
 
 	ratemode = priv->bitratemode;
 
-	if ( (ratemode < 0) || (ratemode > BITRATE_TABLE_SIZE) )
+	if ( (ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE) )
 		BUG();
 
 	rrq->value = bitrate_table[ratemode].bitrate * 100000;
diff -Nru a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
--- a/drivers/oprofile/buffer_sync.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/oprofile/buffer_sync.c	Fri Feb 14 15:53:09 2003
@@ -199,8 +199,16 @@
 	last_cookie = ~0UL;
 }
 
+static void add_kernel_ctx_switch(unsigned int in_kernel)
+{
+	add_event_entry(ESCAPE_CODE);
+	if (in_kernel)
+		add_event_entry(KERNEL_ENTER_SWITCH_CODE); 
+	else
+		add_event_entry(KERNEL_EXIT_SWITCH_CODE); 
+}
  
-static void add_ctx_switch(pid_t pid, unsigned long cookie)
+static void add_user_ctx_switch(pid_t pid, unsigned long cookie)
 {
 	add_event_entry(ESCAPE_CODE);
 	add_event_entry(CTX_SWITCH_CODE); 
@@ -243,19 +251,13 @@
 }
 
  
-static inline int is_kernel(unsigned long val)
-{
-	return val > PAGE_OFFSET;
-}
-
-
 /* Add a sample to the global event buffer. If possible the
  * sample is converted into a persistent dentry/offset pair
  * for later lookup from userspace.
  */
-static void add_sample(struct mm_struct * mm, struct op_sample * s)
+static void add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
 {
-	if (is_kernel(s->eip)) {
+	if (in_kernel) {
 		add_sample_entry(s->eip, s->event);
 	} else if (mm) {
 		add_us_sample(mm, s);
@@ -319,26 +321,34 @@
 	struct mm_struct * mm = 0;
 	struct task_struct * new;
 	unsigned long cookie;
+	int in_kernel = 1;
 	int i;
  
 	for (i=0; i < cpu_buf->pos; ++i) {
 		struct op_sample * s = &cpu_buf->buffer[i];
  
 		if (is_ctx_switch(s->eip)) {
-			new = (struct task_struct *)s->event;
- 
-			release_mm(mm);
-			mm = take_task_mm(new);
- 
-			cookie = get_exec_dcookie(mm);
-			add_ctx_switch(new->pid, cookie);
+			if (s->event <= 1) {
+				/* kernel/userspace switch */
+				in_kernel = s->event;
+				add_kernel_ctx_switch(s->event);
+			} else {
+				/* userspace context switch */
+				new = (struct task_struct *)s->event;
+
+				release_mm(mm);
+				mm = take_task_mm(new);
+
+				cookie = get_exec_dcookie(mm);
+				add_user_ctx_switch(new->pid, cookie);
+			}
 		} else {
-			add_sample(mm, s);
+			add_sample(mm, s, in_kernel);
 		}
 	}
 	release_mm(mm);
 
-	cpu_buf->pos = 0;
+	cpu_buffer_reset(cpu_buf);
 }
  
  
@@ -364,10 +374,12 @@
 		 * lockers only, and this region is already
 		 * protected by buffer_sem. It's raw to prevent
 		 * the preempt bogometer firing. Fruity, huh ? */
-		_raw_spin_lock(&cpu_buf->int_lock);
-		add_cpu_switch(i);
-		sync_buffer(cpu_buf);
-		_raw_spin_unlock(&cpu_buf->int_lock);
+		if (cpu_buf->pos > 0) {
+			_raw_spin_lock(&cpu_buf->int_lock);
+			add_cpu_switch(i);
+			sync_buffer(cpu_buf);
+			_raw_spin_unlock(&cpu_buf->int_lock);
+		}
 	}
 
 	up(&buffer_sem);
@@ -393,3 +405,4 @@
 	schedule_work(&sync_wq);
 	/* timer is re-added by the scheduled task */
 }
+
diff -Nru a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
--- a/drivers/oprofile/cpu_buffer.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/oprofile/cpu_buffer.c	Fri Feb 14 15:53:08 2003
@@ -62,6 +62,7 @@
 		spin_lock_init(&b->int_lock);
 		b->pos = 0;
 		b->last_task = 0;
+		b->last_is_kernel = -1;
 		b->sample_received = 0;
 		b->sample_lost_locked = 0;
 		b->sample_lost_overflow = 0;
@@ -84,12 +85,20 @@
  * be safe from any context. Instead we trylock the CPU's int_lock.
  * int_lock is taken by the processing code in sync_cpu_buffers()
  * so we avoid disturbing that.
+ *
+ * is_kernel is needed because on some architectures you cannot
+ * tell if you are in kernel or user space simply by looking at
+ * eip. We tag this in the buffer by generating kernel enter/exit
+ * events whenever is_kernel changes
  */
-void oprofile_add_sample(unsigned long eip, unsigned long event, int cpu)
+void oprofile_add_sample(unsigned long eip, unsigned int is_kernel, 
+	unsigned long event, int cpu)
 {
 	struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[cpu];
 	struct task_struct * task;
 
+	is_kernel = !!is_kernel;
+
 	cpu_buf->sample_received++;
  
 	if (!spin_trylock(&cpu_buf->int_lock)) {
@@ -101,9 +110,17 @@
 		cpu_buf->sample_lost_overflow++;
 		goto out;
 	}
- 
+
 	task = current;
 
+	/* notice a switch from user->kernel or vice versa */
+	if (cpu_buf->last_is_kernel != is_kernel) {
+		cpu_buf->last_is_kernel = is_kernel;
+		cpu_buf->buffer[cpu_buf->pos].eip = ~0UL;
+		cpu_buf->buffer[cpu_buf->pos].event = is_kernel;
+		cpu_buf->pos++;
+	}
+
 	/* notice a task switch */
 	if (cpu_buf->last_task != task) {
 		cpu_buf->last_task = task;
@@ -130,3 +147,19 @@
 out:
 	spin_unlock(&cpu_buf->int_lock);
 }
+
+/* resets the cpu buffer to a sane state - should be called with 
+ * cpu_buf->int_lock held
+ */
+void cpu_buffer_reset(struct oprofile_cpu_buffer *cpu_buf)
+{
+	cpu_buf->pos = 0;
+
+	/* reset these to invalid values; the next sample
+	 * collected will populate the buffer with proper
+	 * values to initialize the buffer
+	 */
+	cpu_buf->last_is_kernel = -1;
+	cpu_buf->last_task = 0;
+}
+
diff -Nru a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h
--- a/drivers/oprofile/cpu_buffer.h	Fri Feb 14 15:53:12 2003
+++ b/drivers/oprofile/cpu_buffer.h	Fri Feb 14 15:53:12 2003
@@ -20,7 +20,7 @@
 int alloc_cpu_buffers(void);
 
 void free_cpu_buffers(void);
- 
+
 /* CPU buffer is composed of such entries (which are
  * also used for context switch notes)
  */
@@ -34,6 +34,7 @@
 	/* protected by int_lock */
 	unsigned long pos;
 	struct task_struct * last_task;
+	int last_is_kernel;
 	struct op_sample * buffer;
 	unsigned long sample_received;
 	unsigned long sample_lost_locked;
@@ -42,5 +43,7 @@
 } ____cacheline_aligned;
 
 extern struct oprofile_cpu_buffer cpu_buffer[];
+
+void cpu_buffer_reset(struct oprofile_cpu_buffer *cpu_buf);
 
 #endif /* OPROFILE_CPU_BUFFER_H */
diff -Nru a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h
--- a/drivers/oprofile/event_buffer.h	Fri Feb 14 15:53:09 2003
+++ b/drivers/oprofile/event_buffer.h	Fri Feb 14 15:53:09 2003
@@ -25,9 +25,11 @@
  * relevant data.
  */
 #define ESCAPE_CODE		~0UL
-#define CTX_SWITCH_CODE 	1
-#define CPU_SWITCH_CODE 	2
-#define COOKIE_SWITCH_CODE 	3
+#define CTX_SWITCH_CODE 		1
+#define CPU_SWITCH_CODE 		2
+#define COOKIE_SWITCH_CODE 		3
+#define KERNEL_ENTER_SWITCH_CODE	4
+#define KERNEL_EXIT_SWITCH_CODE		5
  
 /* add data to the event buffer */
 void add_event_entry(unsigned long data);
diff -Nru a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
--- a/drivers/oprofile/oprof.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/oprofile/oprof.c	Fri Feb 14 15:53:09 2003
@@ -20,7 +20,6 @@
 #include "oprofile_stats.h"
  
 struct oprofile_operations * oprofile_ops;
-enum oprofile_cpu oprofile_cpu_type;
 unsigned long oprofile_started;
 static unsigned long is_setup;
 static DECLARE_MUTEX(start_sem);
@@ -127,9 +126,15 @@
 	/* Architecture must fill in the interrupt ops and the
 	 * logical CPU type.
 	 */
-	err = oprofile_arch_init(&oprofile_ops, &oprofile_cpu_type);
+	err = oprofile_arch_init(&oprofile_ops);
 	if (err)
 		goto out;
+
+	if (!oprofile_ops->cpu_type) {
+		printk(KERN_ERR "oprofile: cpu_type not set !\n");
+		err = -EFAULT;
+		goto out;
+	}
 
 	err = oprofilefs_register();
 	if (err)
diff -Nru a/drivers/oprofile/oprof.h b/drivers/oprofile/oprof.h
--- a/drivers/oprofile/oprof.h	Fri Feb 14 15:53:09 2003
+++ b/drivers/oprofile/oprof.h	Fri Feb 14 15:53:09 2003
@@ -24,7 +24,6 @@
 extern unsigned long fs_buffer_size;
 extern unsigned long fs_cpu_buffer_size;
 extern unsigned long fs_buffer_watershed;
-extern enum oprofile_cpu oprofile_cpu_type;
 extern struct oprofile_operations * oprofile_ops;
 extern unsigned long oprofile_started;
  
diff -Nru a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c
--- a/drivers/oprofile/oprofile_files.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/oprofile/oprofile_files.c	Fri Feb 14 15:53:10 2003
@@ -21,9 +21,7 @@
  
 static ssize_t cpu_type_read(struct file * file, char * buf, size_t count, loff_t * offset)
 {
-	unsigned long cpu_type = oprofile_cpu_type;
-
-	return oprofilefs_ulong_to_user(&cpu_type, buf, count, offset);
+	return oprofilefs_str_to_user(oprofile_ops->cpu_type, buf, count, offset);
 }
  
  
diff -Nru a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c
--- a/drivers/oprofile/oprofilefs.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/oprofile/oprofilefs.c	Fri Feb 14 15:53:09 2003
@@ -44,6 +44,29 @@
 	.drop_inode 	= generic_delete_inode,
 };
 
+
+ssize_t oprofilefs_str_to_user(char const * str, char * buf, size_t count, loff_t * offset)
+{
+	size_t len = strlen(str);
+
+	if (!count)
+		return 0;
+
+	if (*offset > len)
+		return 0;
+
+	if (count > len - *offset)
+		count = len - *offset;
+
+	if (copy_to_user(buf, str + *offset, count))
+		return -EFAULT;
+
+	*offset += count;
+
+	return count;
+}
+
+
 #define TMPBUFSIZE 50
 
 ssize_t oprofilefs_ulong_to_user(unsigned long * val, char * buf, size_t count, loff_t * offset)
@@ -91,7 +114,7 @@
 		return -EFAULT;
 
 	spin_lock(&oprofilefs_lock);
-	*val = simple_strtoul(tmpbuf, NULL, 10);
+	*val = simple_strtoul(tmpbuf, NULL, 0);
 	spin_unlock(&oprofilefs_lock);
 	return 0;
 }
diff -Nru a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
--- a/drivers/pcmcia/i82092.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/pcmcia/i82092.c	Fri Feb 14 15:53:12 2003
@@ -384,7 +384,7 @@
 	unsigned int val;
 	enter("card_present");
 	
-	if ((socketno<0) || (socketno > MAX_SOCKETS))
+	if ((socketno<0) || (socketno >= MAX_SOCKETS))
 		return 0;
 	if (sockets[socketno].io_base == 0)
 		return 0;
diff -Nru a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
--- a/drivers/pnp/pnpbios/core.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/pnp/pnpbios/core.c	Fri Feb 14 15:53:08 2003
@@ -615,8 +615,8 @@
 {
 	static struct pnp_docking_station_info now;
 	int docked = -1, d = 0;
-	daemonize();
-	strcpy(current->comm, "kpnpbiosd");
+	daemonize("kpnpbiosd");
+	allow_signal(SIGKILL);
 	while(!unloading && !signal_pending(current))
 	{
 		int status;
diff -Nru a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
--- a/drivers/s390/net/lcs.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/s390/net/lcs.c	Fri Feb 14 15:53:09 2003
@@ -908,7 +908,7 @@
 
 	card = (struct lcs_card *) data;
 
-	daemonize();
+	daemonize("fixipm");
 	LCS_DBF_TEXT(5, trace, "fixipm");
 	spin_lock(&card->lock);
 	list_for_each_safe(l, n, &card->ipm_list) {
@@ -1370,7 +1370,7 @@
 	struct lcs_card *card;
 
 	card = (struct lcs_card *) data;
-	daemonize();
+	daemonize("lgwstpln");
 	LCS_DBF_TEXT(4, trace, "lgwstpln");
 	if (card->dev)
 		netif_stop_queue(card->dev);
@@ -1397,7 +1397,7 @@
 	struct lcs_card *card;
 
 	card = (struct lcs_card *) data;
-	daemonize();
+	daemonize("lgwstpln");
 	LCS_DBF_TEXT(4, trace, "lgwstpln");
 	if (card->dev)
 		netif_stop_queue(card->dev);
@@ -1436,7 +1436,7 @@
 	struct lcs_card *card;
 
 	card = (struct lcs_card *) data;
-	daemonize();
+	daemonize("lgwstop");
 	LCS_DBF_TEXT(4, trace, "lgwstop");
 	if (card->dev)
 		netif_stop_queue(card->dev);
diff -Nru a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c
--- a/drivers/sbus/char/bbc_envctrl.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/sbus/char/bbc_envctrl.c	Fri Feb 14 15:53:09 2003
@@ -457,8 +457,8 @@
 
 static int kenvctrld(void *__unused)
 {
-	daemonize();
-	strcpy(current->comm, "kenvctrld");
+	daemonize("kenvctrld");
+	allow_signal(SIGKILL);
 	kenvctrld_task = current;
 
 	printk(KERN_INFO "bbc_envctrl: kenvctrld starting...\n");
diff -Nru a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
--- a/drivers/sbus/char/envctrl.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/sbus/char/envctrl.c	Fri Feb 14 15:53:09 2003
@@ -1016,8 +1016,9 @@
 
 	poll_interval = 5 * HZ; /* TODO env_mon_interval */
 
-	daemonize();
-	strcpy(current->comm, "kenvctrld");
+	daemonize("kenvctrld");
+	allow_signal(SIGKILL);
+
 	kenvctrld_task = current;
 
 	printk(KERN_INFO "envctrl: %s starting...\n", current->comm);
diff -Nru a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
--- a/drivers/scsi/NCR53c406a.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/scsi/NCR53c406a.c	Fri Feb 14 15:53:09 2003
@@ -697,7 +697,7 @@
 
 	/* We are locked here already by the mid layer */
 	REG0;
-	outb(SCpnt->target, DEST_ID);	/* set destination */
+	outb(SCpnt->device->id, DEST_ID);	/* set destination */
 	outb(FLUSH_FIFO, CMD_REG);	/* reset the fifos */
 
 	for (i = 0; i < SCpnt->cmd_len; i++) {
diff -Nru a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
--- a/drivers/scsi/aacraid/aachba.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/scsi/aacraid/aachba.c	Fri Feb 14 15:53:09 2003
@@ -1094,7 +1094,7 @@
 		qd.cnum = TARGET_LUN_TO_CONTAINER(qd.target, qd.lun);
 	else if ((qd.bus == -1) && (qd.target == -1) && (qd.lun == -1)) 
 	{
-		if (qd.cnum < 0 || qd.cnum > MAXIMUM_NUM_CONTAINERS)
+		if (qd.cnum < 0 || qd.cnum >= MAXIMUM_NUM_CONTAINERS)
 			return -EINVAL;
 		qd.instance = dev->scsi_host_ptr->host_no;
 		qd.bus = 0;
@@ -1129,7 +1129,7 @@
 	if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk)))
 		return -EFAULT;
 
-	if (dd.cnum > MAXIMUM_NUM_CONTAINERS)
+	if (dd.cnum >= MAXIMUM_NUM_CONTAINERS)
 		return -EINVAL;
 	/*
 	 *	Mark this container as being deleted.
@@ -1152,7 +1152,7 @@
 	if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk)))
 		return -EFAULT;
 
-	if (dd.cnum > MAXIMUM_NUM_CONTAINERS)
+	if (dd.cnum >= MAXIMUM_NUM_CONTAINERS)
 		return -EINVAL;
 	/*
 	 *	If the container is locked, it can not be deleted by the API.
diff -Nru a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
--- a/drivers/scsi/aacraid/commsup.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/scsi/aacraid/commsup.c	Fri Feb 14 15:53:12 2003
@@ -816,8 +816,8 @@
 	 *	Set up the name that will appear in 'ps'
 	 *	stored in  task_struct.comm[16].
 	 */
-	sprintf(current->comm, "aacraid");
-	daemonize();
+	daemonize("aacraid");
+	allow_signal(SIGKILL);
 	/*
 	 *	Let the DPC know it has a place to send the AIF's to.
 	 */
diff -Nru a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
--- a/drivers/scsi/aha1740.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/scsi/aha1740.c	Fri Feb 14 15:53:09 2003
@@ -315,8 +315,8 @@
 {
     unchar direction;
     unchar *cmd = (unchar *) SCpnt->cmnd;
-    unchar target = SCpnt->target;
-    struct aha1740_hostdata *host = HOSTDATA(SCpnt->host);
+    unchar target = SCpnt->device->id;
+    struct aha1740_hostdata *host = HOSTDATA(SCpnt->device->host);
     unsigned long flags;
     void *buff = SCpnt->request_buffer;
     int bufflen = SCpnt->request_bufflen;
@@ -416,7 +416,7 @@
 	host->ecb[ecbno].datalen = bufflen;
 	host->ecb[ecbno].dataptr = isa_virt_to_bus(buff);
     }
-    host->ecb[ecbno].lun = SCpnt->lun;
+    host->ecb[ecbno].lun = SCpnt->device->lun;
     host->ecb[ecbno].ses = 1;	/* Suppress underrun errors */
     host->ecb[ecbno].dir = direction;
     host->ecb[ecbno].ars = 1;  /* Yes, get the sense on an error */
@@ -449,7 +449,7 @@
 #define LOOPCNT_WARN 10		/* excessive mbxout wait -> syslog-msg */
 #define LOOPCNT_MAX 1000000	/* mbxout deadlock -> panic() after ~ 2 sec. */
 	int loopcnt;
-	unsigned int base = SCpnt->host->io_port;
+	unsigned int base = SCpnt->device->host->io_port;
 	DEB(printk("aha1740[%d] critical section\n",ecbno));
 
 	spin_lock_irqsave(&aha1740_lock, flags);
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c	Fri Feb 14 15:53:08 2003
@@ -1560,7 +1560,7 @@
 	hscb = scb->hscb;
 	hscb->control = 0;
 	hscb->scsiid = BUILD_SCSIID(ahd, cmd);
-	hscb->lun = cmd->lun;
+	hscb->lun = cmd->device->lun;
 	hscb->cdb_len = 0;
 	hscb->task_management = SIU_TASKMGMT_LUN_RESET;
 	scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE;
@@ -2854,8 +2854,7 @@
 	 * Complete thread creation.
 	 */
 	lock_kernel();
-	daemonize();
-	sprintf(current->comm, "ahd_dv_%d", ahd->unit);
+	daemonize("ahd_dv_%d", ahd->unit);
 	unlock_kernel();
 
 	while (1) {
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c
--- a/drivers/scsi/aic7xxx/aic79xx_pci.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.c	Fri Feb 14 15:53:09 2003
@@ -691,7 +691,7 @@
 
 static const char *split_status_strings[] =
 {
-	"%s: Received split response in %s.\n"
+	"%s: Received split response in %s.\n",
 	"%s: Received split completion error message in %s\n",
 	"%s: Receive overrun in %s\n",
 	"%s: Count not complete in %s\n",
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c	Fri Feb 14 15:53:09 2003
@@ -4708,8 +4708,8 @@
 
 #ifdef AHC_DEBUG
 	if (ahc_debug & AHC_SHOW_MISC) {
-		printf("%s: hardware scb %d bytes; kernel scb %d bytes; "
-		       "ahc_dma %d bytes\n",
+		printf("%s: hardware scb %Zu bytes; kernel scb %Zu bytes; "
+		       "ahc_dma %Zu bytes\n",
 			ahc_name(ahc),
 			sizeof(struct hardware_scb),
 			sizeof(struct scb),
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c	Fri Feb 14 15:53:08 2003
@@ -2355,16 +2355,10 @@
 #endif
 
 	/*
-	 * Don't care about any signals.
-	 */
-	siginitsetinv(&current->blocked, 0);
-
-	/*
 	 * Complete thread creation.
 	 */
 	lock_kernel();
-	daemonize();
-	sprintf(current->comm, "ahc_dv_%d", ahc->unit);
+	daemonize("ahc_dv_%d", ahc->unit);
 	unlock_kernel();
 
 	while (1) {
diff -Nru a/drivers/scsi/cpqfcTSworker.c b/drivers/scsi/cpqfcTSworker.c
--- a/drivers/scsi/cpqfcTSworker.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/scsi/cpqfcTSworker.c	Fri Feb 14 15:53:12 2003
@@ -165,15 +165,10 @@
   ENTER("WorkerThread");
 
   lock_kernel();
-  daemonize();
+  daemonize("cpqfcTS_wt_%d", HostAdapter->host_no);
   siginitsetinv(&current->blocked, SHUTDOWN_SIGS);
 
 
-  /*
-   * Set the name of this process.
-   */
-  sprintf(current->comm, "cpqfcTS_wt_%d", HostAdapter->host_no);
-
   cpqfcHBAdata->fcQueReady = &fcQueReady;  // primary wait point
   cpqfcHBAdata->TYOBcomplete = &fcTYOBcomplete;
   cpqfcHBAdata->TachFrozen = &TachFrozen;
@@ -448,7 +443,7 @@
       LONG x_ID = fcLQ->Qitem[QconsumerNdx].ulBuff[0];
       BOOLEAN FrozeTach = FALSE;   
      
-      if( x_ID > TACH_SEST_LEN )  // (in)sanity check
+      if ( x_ID >= TACH_SEST_LEN )  // (in)sanity check
       {
 //	printk( " cpqfcTS ERROR! BOGUS x_ID %Xh", x_ID);
 	break;
diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
--- a/drivers/scsi/dpt_i2o.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/scsi/dpt_i2o.c	Fri Feb 14 15:53:12 2003
@@ -1402,7 +1402,7 @@
 				printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
 				continue;
 			}
-			if(scsi_id > MAX_ID){
+			if (scsi_id >= MAX_ID){
 				printk(KERN_WARNING"%s: SCSI ID %d out of range \n", pHba->name, bus_no);
 				continue;
 			}
@@ -1476,7 +1476,7 @@
 				if(bus_no >= MAX_CHANNEL) {	// Something wrong skip it
 					continue;
 				}
-				if(scsi_id > MAX_ID){
+				if (scsi_id >= MAX_ID) {
 					continue;
 				}
 				if( pHba->channel[bus_no].device[scsi_id] == NULL){
diff -Nru a/drivers/scsi/eata.c b/drivers/scsi/eata.c
--- a/drivers/scsi/eata.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/scsi/eata.c	Fri Feb 14 15:53:12 2003
@@ -1193,9 +1193,9 @@
    }
 #endif
 
-   spin_unlock(&driver_lock);
+   spin_unlock_irq(&driver_lock);
    sh[j] = scsi_register(tpnt, sizeof(struct hostdata));
-   spin_lock(&driver_lock);
+   spin_lock_irq(&driver_lock);
 
    if (sh[j] == NULL) {
       printk("%s: unable to register host, detaching.\n", name);
@@ -1450,9 +1450,8 @@
 
 static int eata2x_detect(Scsi_Host_Template *tpnt) {
    unsigned int j = 0, k;
-   unsigned long spin_flags;
 
-   spin_lock_irqsave(&driver_lock, spin_flags);
+   spin_lock_irq(&driver_lock);
 
    tpnt->proc_name = "eata2x";
 
@@ -1490,7 +1489,7 @@
       }
 
    num_boards = j;
-   spin_unlock_irqrestore(&driver_lock, spin_flags);
+   spin_unlock_irq(&driver_lock);
    return j;
 }
 
diff -Nru a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
--- a/drivers/scsi/fd_mcs.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/scsi/fd_mcs.c	Fri Feb 14 15:53:09 2003
@@ -87,6 +87,7 @@
 #include <linux/delay.h>
 #include <linux/mca.h>
 #include <linux/spinlock.h>
+#include <linux/mca-legacy.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -732,7 +733,7 @@
 		outb(0x40 | FIFO_COUNT, Interrupt_Cntl_port);
 
 		outb(0x82, SCSI_Cntl_port);	/* Bus Enable + Select */
-		outb(adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port);
+		outb(adapter_mask | (1 << current_SC->device->id), SCSI_Data_NoACK_port);
 
 		/* Stop arbitration and enable parity */
 		outb(0x10 | PARITY_MASK, TMC_Cntl_port);
@@ -744,7 +745,7 @@
 		status = inb(SCSI_Status_port);
 		if (!(status & 0x01)) {
 			/* Try again, for slow devices */
-			if (fd_mcs_select(shpnt, current_SC->target)) {
+			if (fd_mcs_select(shpnt, current_SC->device->id)) {
 #if EVERY_ACCESS
 				printk(" SFAIL ");
 #endif
@@ -802,7 +803,7 @@
 #endif
 #if ERRORS_ONLY
 			if (current_SC->SCp.Status && current_SC->SCp.Status != 2 && current_SC->SCp.Status != 8) {
-				printk("ERROR fd_mcs: target = %d, command = %x, status = %x\n", current_SC->target, current_SC->cmnd[0], current_SC->SCp.Status);
+				printk("ERROR fd_mcs: target = %d, command = %x, status = %x\n", current_SC->device->id, current_SC->cmnd[0], current_SC->SCp.Status);
 			}
 #endif
 			break;
@@ -1150,7 +1151,7 @@
 
 static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
-	struct Scsi_Host *shpnt = SCpnt->host;
+	struct Scsi_Host *shpnt = SCpnt->device->host;
 
 	if (in_command) {
 		panic("fd_mcs: fd_mcs_queue() NOT REENTRANT!\n");
@@ -1243,7 +1244,7 @@
 		break;
 	}
 
-	printk("(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n", SCpnt->SCp.phase, SCpnt->target, *(unsigned char *) SCpnt->cmnd, SCpnt->use_sg, SCpnt->request_bufflen);
+	printk("(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n", SCpnt->SCp.phase, SCpnt->device->id, *(unsigned char *) SCpnt->cmnd, SCpnt->use_sg, SCpnt->request_bufflen);
 	printk("sent_command = %d, have_data_in = %d, timeout = %d\n", SCpnt->SCp.sent_command, SCpnt->SCp.have_data_in, SCpnt->timeout);
 #if DEBUG_RACE
 	printk("in_interrupt_flag = %d\n", in_interrupt_flag);
@@ -1286,7 +1287,7 @@
 
 static int fd_mcs_abort(Scsi_Cmnd * SCpnt)
 {
-	struct Scsi_Host *shpnt = SCpnt->host;
+	struct Scsi_Host *shpnt = SCpnt->device->host;
 
 	unsigned long flags;
 #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
@@ -1331,7 +1332,7 @@
 }
 
 static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
-	struct Scsi_Host *shpnt = SCpnt->host;
+	struct Scsi_Host *shpnt = SCpnt->device->host;
 
 #if DEBUG_RESET
 	static int called_once = 0;
diff -Nru a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
--- a/drivers/scsi/ibmmca.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/scsi/ibmmca.c	Fri Feb 14 15:53:08 2003
@@ -39,6 +39,7 @@
 #include <linux/string.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>
+#include <linux/mca-legacy.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -668,8 +669,8 @@
 	ld(ihost_index)[ldn].cmd = NULL;
 #ifdef IM_DEBUG_TIMEOUT
 	if (cmd) {
-		if ((cmd->target == TIMEOUT_PUN) && (cmd->lun == TIMEOUT_LUN)) {
-			printk("IBM MCA SCSI: Ignoring interrupt from pun=%x, lun=%x.\n", cmd->target, cmd->lun);
+		if ((cmd->target == TIMEOUT_PUN) && (cmd->device->lun == TIMEOUT_LUN)) {
+			printk("IBM MCA SCSI: Ignoring interrupt from pun=%x, lun=%x.\n", cmd->target, cmd->device->lun);
 			return;
 		}
 	}
@@ -1824,7 +1825,7 @@
 	int i;
 	struct scatterlist *sl;
 
-	shpnt = cmd->host;
+	shpnt = cmd->device->host;
 	/* search for the right hostadapter */
 	for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
 
@@ -1836,16 +1837,16 @@
 	}
 	max_pun = subsystem_maxid(host_index);
 	if (ibm_ansi_order) {
-		target = max_pun - 1 - cmd->target;
-		if ((target <= subsystem_pun(host_index)) && (cmd->target <= subsystem_pun(host_index)))
+		target = max_pun - 1 - cmd->device->id;
+		if ((target <= subsystem_pun(host_index)) && (cmd->device->id <= subsystem_pun(host_index)))
 			target--;
-		else if ((target >= subsystem_pun(host_index)) && (cmd->target >= subsystem_pun(host_index)))
+		else if ((target >= subsystem_pun(host_index)) && (cmd->device->id >= subsystem_pun(host_index)))
 			target++;
 	} else
-		target = cmd->target;
+		target = cmd->device->id;
 
 	/* if (target,lun) is NO LUN or not existing at all, return error */
-	if ((get_scsi(host_index)[target][cmd->lun] == TYPE_NO_LUN) || (get_scsi(host_index)[target][cmd->lun] == TYPE_NO_DEVICE)) {
+	if ((get_scsi(host_index)[target][cmd->device->lun] == TYPE_NO_LUN) || (get_scsi(host_index)[target][cmd->device->lun] == TYPE_NO_DEVICE)) {
 		cmd->result = DID_NO_CONNECT << 16;
 		if (done)
 			done(cmd);
@@ -1853,7 +1854,7 @@
 	}
 
 	/*if (target,lun) unassigned, do further checks... */
-	ldn = get_ldn(host_index)[target][cmd->lun];
+	ldn = get_ldn(host_index)[target][cmd->device->lun];
 	if (ldn >= MAX_LOG_DEV) {	/* on invalid ldn do special stuff */
 		if (ldn > MAX_LOG_DEV) {	/* dynamical remapping if ldn unassigned */
 			current_ldn = next_ldn(host_index);	/* stop-value for one circle */
@@ -1864,7 +1865,7 @@
 					next_ldn(host_index) = 7;
 				if (current_ldn == next_ldn(host_index)) {	/* One circle done ? */
 					/* no non-processing ldn found */
-					printk("IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n" "              On ldn 7-14 SCSI-commands everywhere in progress.\n" "              Reporting DID_NO_CONNECT for device (%d,%d).\n", target, cmd->lun);
+					printk("IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n" "              On ldn 7-14 SCSI-commands everywhere in progress.\n" "              Reporting DID_NO_CONNECT for device (%d,%d).\n", target, cmd->device->lun);
 					cmd->result = DID_NO_CONNECT << 16;	/* return no connect */
 					if (done)
 						done(cmd);
@@ -1884,26 +1885,26 @@
 			/* set reduced interrupt_handler-mode for checking */
 			local_checking_phase_flag(host_index) = 1;
 			/* map found ldn to pun,lun */
-			get_ldn(host_index)[target][cmd->lun] = next_ldn(host_index);
+			get_ldn(host_index)[target][cmd->device->lun] = next_ldn(host_index);
 			/* change ldn to the right value, that is now next_ldn */
 			ldn = next_ldn(host_index);
 			/* unassign all ldns (pun,lun,ldn does not matter for remove) */
 			immediate_assign(host_index, 0, 0, 0, REMOVE_LDN);
 			/* set only LDN for remapped device */
-			immediate_assign(host_index, target, cmd->lun, ldn, SET_LDN);
+			immediate_assign(host_index, target, cmd->device->lun, ldn, SET_LDN);
 			/* get device information for ld[ldn] */
 			if (device_exists(host_index, ldn, &ld(host_index)[ldn].block_length, &ld(host_index)[ldn].device_type)) {
 				ld(host_index)[ldn].cmd = NULL;	/* To prevent panic set 0, because
 								   devices that were not assigned,
 								   should have nothing in progress. */
-				get_scsi(host_index)[target][cmd->lun] = ld(host_index)[ldn].device_type;
+				get_scsi(host_index)[target][cmd->device->lun] = ld(host_index)[ldn].device_type;
 				/* increase assignment counters for statistics in /proc */
 				IBM_DS(host_index).dynamical_assignments++;
 				IBM_DS(host_index).ldn_assignments[ldn]++;
 			} else
 				/* panic here, because a device, found at boottime has
 				   vanished */
-				panic("IBM MCA SCSI: ldn=0x%x, SCSI-device on (%d,%d) vanished!\n", ldn, target, cmd->lun);
+				panic("IBM MCA SCSI: ldn=0x%x, SCSI-device on (%d,%d) vanished!\n", ldn, target, cmd->device->lun);
 			/* unassign again all ldns (pun,lun,ldn does not matter for remove) */
 			immediate_assign(host_index, 0, 0, 0, REMOVE_LDN);
 			/* remap all ldns, as written in the pun/lun table */
@@ -1919,7 +1920,7 @@
 			local_checking_phase_flag(host_index) = 0;
 #ifdef IM_DEBUG_PROBE
 			/* Information on syslog terminal */
-			printk("IBM MCA SCSI: ldn=0x%x dynamically reassigned to (%d,%d).\n", ldn, target, cmd->lun);
+			printk("IBM MCA SCSI: ldn=0x%x dynamically reassigned to (%d,%d).\n", ldn, target, cmd->device->lun);
 #endif
 			/* increase next_ldn for next dynamical assignment */
 			next_ldn(host_index)++;
@@ -2141,7 +2142,7 @@
 	printk("IBM MCA SCSI: Abort subroutine called...\n");
 #endif
 
-	shpnt = cmd->host;
+	shpnt = cmd->device->host;
 	/* search for the right hostadapter */
 	for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
 
@@ -2149,7 +2150,7 @@
 		cmd->result = DID_NO_CONNECT << 16;
 		if (cmd->scsi_done)
 			(cmd->scsi_done) (cmd);
-		shpnt = cmd->host;
+		shpnt = cmd->device->host;
 #ifdef IM_DEBUG_PROBE
 		printk(KERN_DEBUG "IBM MCA SCSI: Abort adapter selection failed!\n");
 #endif
@@ -2157,17 +2158,17 @@
 	}
 	max_pun = subsystem_maxid(host_index);
 	if (ibm_ansi_order) {
-		target = max_pun - 1 - cmd->target;
-		if ((target <= subsystem_pun(host_index)) && (cmd->target <= subsystem_pun(host_index)))
+		target = max_pun - 1 - cmd->device->id;
+		if ((target <= subsystem_pun(host_index)) && (cmd->device->id <= subsystem_pun(host_index)))
 			target--;
-		else if ((target >= subsystem_pun(host_index)) && (cmd->target >= subsystem_pun(host_index)))
+		else if ((target >= subsystem_pun(host_index)) && (cmd->device->id >= subsystem_pun(host_index)))
 			target++;
 	} else
-		target = cmd->target;
+		target = cmd->device->id;
 
 	/* get logical device number, and disable system interrupts */
-	printk(KERN_WARNING "IBM MCA SCSI: Sending abort to device pun=%d, lun=%d.\n", target, cmd->lun);
-	ldn = get_ldn(host_index)[target][cmd->lun];
+	printk(KERN_WARNING "IBM MCA SCSI: Sending abort to device pun=%d, lun=%d.\n", target, cmd->device->lun);
+	ldn = get_ldn(host_index)[target][cmd->device->lun];
 
 	/*if cmd for this ldn has already finished, no need to abort */
 	if (!ld(host_index)[ldn].cmd) {
@@ -2242,7 +2243,7 @@
 		BUG();
 
 	ticks = IM_RESET_DELAY * HZ;
-	shpnt = cmd->host;
+	shpnt = cmd->device->host;
 	/* search for the right hostadapter */
 	for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
 
diff -Nru a/drivers/scsi/imm.c b/drivers/scsi/imm.c
--- a/drivers/scsi/imm.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/scsi/imm.c	Fri Feb 14 15:53:12 2003
@@ -733,7 +733,7 @@
 
 static inline int imm_send_command(Scsi_Cmnd * cmd)
 {
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
     int k;
 
     /* NOTE: IMM uses byte pairs */
@@ -758,7 +758,7 @@
      *  0     Told to schedule
      *  1     Finished data transfer
      */
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
     unsigned short ppb = IMM_BASE(host_no);
     unsigned long start_jiffies = jiffies;
 
@@ -845,7 +845,7 @@
 int imm_command(Scsi_Cmnd * cmd)
 {
     static int first_pass = 1;
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
 
     if (first_pass) {
 	printk("imm: using non-queuing interface\n");
@@ -867,7 +867,7 @@
 	schedule();
 
     if (cmd->SCp.phase)		/* Only disconnect if we have connected */
-	imm_disconnect(cmd->host->unique_id);
+	imm_disconnect(cmd->device->host->unique_id);
 
     imm_pb_release(host_no);
     imm_hosts[host_no].cur_cmd = 0;
@@ -883,7 +883,7 @@
 {
     imm_struct *tmp = (imm_struct *) data;
     Scsi_Cmnd *cmd = tmp->cur_cmd;
-    struct Scsi_Host *host = cmd->host;
+    struct Scsi_Host *host = cmd->device->host;
     unsigned long flags;
 
     if (!cmd) {
@@ -930,9 +930,9 @@
 #endif
 
     if (cmd->SCp.phase > 1)
-	imm_disconnect(cmd->host->unique_id);
+	imm_disconnect(cmd->device->host->unique_id);
     if (cmd->SCp.phase > 0)
-	imm_pb_release(cmd->host->unique_id);
+	imm_pb_release(cmd->device->host->unique_id);
 
     spin_lock_irqsave(host->host_lock, flags);
     tmp->cur_cmd = 0;
@@ -943,7 +943,7 @@
 
 static int imm_engine(imm_struct * tmp, Scsi_Cmnd * cmd)
 {
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
     unsigned short ppb = IMM_BASE(host_no);
     unsigned char l = 0, h = 0;
     int retv, x;
@@ -972,7 +972,7 @@
 
 	/* Phase 2 - We are now talking to the scsi bus */
     case 2:
-	if (!imm_select(host_no, cmd->target)) {
+	if (!imm_select(host_no, cmd->device->id)) {
 	    imm_fail(host_no, DID_NO_CONNECT);
 	    return 0;
 	}
@@ -1082,7 +1082,7 @@
 
 int imm_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
 
     if (imm_hosts[host_no].cur_cmd) {
 	printk("IMM: bug in imm_queuecommand\n");
@@ -1125,7 +1125,7 @@
 
 int imm_abort(Scsi_Cmnd * cmd)
 {
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
     /*
      * There is no method for aborting commands since Iomega
      * have tied the SCSI_MESSAGE line high in the interface
@@ -1157,7 +1157,7 @@
 
 int imm_reset(Scsi_Cmnd * cmd)
 {
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
 
     if (cmd->SCp.phase)
 	imm_disconnect(host_no);
diff -Nru a/drivers/scsi/ips.c b/drivers/scsi/ips.c
--- a/drivers/scsi/ips.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/scsi/ips.c	Fri Feb 14 15:53:08 2003
@@ -195,14 +195,14 @@
  * DRIVER_VER
  */
 #define IPS_VERSION_HIGH        "5.99"
-#define IPS_VERSION_LOW         ".00-BETA"
+#define IPS_VERSION_LOW         ".01-BETA"
 
 
 #if !defined(__i386__) && !defined(__ia64__)
    #error "This driver has only been tested on the x86/ia64 platforms"
 #endif
 
-#if LINUX_VERSION_CODE <= LinuxVersionCode(2,5,0)
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
     #include "sd.h"
     #define IPS_SG_ADDRESS(sg)       ((sg)->address)
     #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags)
@@ -241,6 +241,7 @@
 static unsigned int ips_next_controller = 0;
 static unsigned int ips_num_controllers = 0;
 static unsigned int ips_released_controllers = 0;
+static int          ips_hotplug;
 static int          ips_cmd_timeout = 60;
 static int          ips_reset_timeout = 60 * 5;
 static int          ips_force_memio = 1;             /* Always use Memory Mapped I/O    */
@@ -572,7 +573,7 @@
          ips_free(ips_ha[i]);
          ips_released_controllers++;
    } 
-
+   ips_hotplug = 1;
    return (ips_num_controllers);
 }
 
@@ -702,6 +703,7 @@
    /* free IRQ */
    free_irq(ha->irq, ha);
 
+   IPS_REMOVE_HOST(sh);
    scsi_unregister(sh);
 
    ips_released_controllers++;
@@ -1136,17 +1138,21 @@
 /*                                                                          */
 /****************************************************************************/
 static int
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ips_biosparam(Disk *disk, kdev_t dev, int geom[]) {
+   ips_ha_t         *ha = (ips_ha_t *) disk->device->host->hostdata;
+   unsigned long     capacity = disk->capacity;
+#else
 ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
 		sector_t capacity, int geom[]) {
-   ips_ha_t         *ha;
+   ips_ha_t         *ha = (ips_ha_t *) sdev->host->hostdata;
+#endif
    int               heads;
    int               sectors;
    int               cylinders;
 
    METHOD_TRACE("ips_biosparam", 1);
 
-   ha = (ips_ha_t *) sdev->host->hostdata;
-
    if (!ha)
       /* ?!?! host adater info invalid */
       return (0);
@@ -1178,7 +1184,7 @@
 
    return (0);
 }
-
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 /****************************************************************************/
 /*                                                                          */
 /* Routine Name: ips_select_queue_depth                                     */
@@ -1188,7 +1194,7 @@
 /*   Select queue depths for the devices on the contoller                   */
 /*                                                                          */
 /****************************************************************************/
-/*static void
+static void
 ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) {
    Scsi_Device *device;
    ips_ha_t    *ha;
@@ -1221,8 +1227,8 @@
       }
    }
 }
-*/
 
+#else
 /****************************************************************************/
 /*                                                                          */
 /* Routine Name: ips_slave_configure                                        */
@@ -1247,6 +1253,7 @@
    }
    return 0;
 }
+#endif
 
 /****************************************************************************/
 /*                                                                          */
@@ -3375,8 +3382,8 @@
                 ips_name,
                 ha->host_num,
                 scb->scsi_cmd->device->channel,
-                scb->scsi_cmd->channel->id,
-                scb->scsi_cmd->channel->lun,
+                scb->scsi_cmd->device->id,
+                scb->scsi_cmd->device->lun,
                 scb->basic_status,
                 scb->extended_status,
                 scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
@@ -4223,6 +4230,12 @@
       mdata.pdata.pg4.RotationalOffset = 0;
       mdata.pdata.pg4.MediumRotationRate = 0;
       break;
+   case 0x8:
+      mdata.pdata.pg8.PageCode = 8;
+      mdata.pdata.pg8.PageLength = sizeof(IPS_SCSI_MODE_PAGE8);
+      mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg8.PageLength;
+      /* everything else is left set to 0 */
+      break;
 
    default:
       return (0);
@@ -6744,7 +6757,7 @@
 	sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
 	sh->use_clustering = sh->hostt->use_clustering;
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
 	sh->max_sectors = 128;
 #endif 
 
@@ -6753,6 +6766,7 @@
 	sh->max_channel = ha->nbus - 1;
 	sh->can_queue = ha->max_cmds-1;
 
+	IPS_ADD_HOST(sh, NULL);
 	return 0;
 }
 
@@ -6793,11 +6807,11 @@
 		return -ENODEV;
 	ips_driver_template.module = THIS_MODULE;
 	ips_order_controllers();
-	if( scsi_register_host(&ips_driver_template) ){
+	if( IPS_REGISTER_HOSTS(&ips_driver_template) ){
 		pci_unregister_driver(&ips_pci_driver);
 		return -ENODEV;
 	}
-
+	register_reboot_notifier(&ips_notifier);
 	return 0;
 }
 
@@ -6810,7 +6824,7 @@
 /****************************************************************************/
 static void __exit
 ips_module_exit(void){
-	scsi_unregister_host(&ips_driver_template);
+	IPS_UNREGISTER_HOSTS(&ips_driver_template);
 	pci_unregister_driver(&ips_pci_driver);
 	unregister_reboot_notifier(&ips_notifier);
 }
@@ -6840,6 +6854,12 @@
     if (rc == SUCCESS)
        rc = ips_init_phase2(index);  
 
+    if(ips_hotplug)
+       if(ips_register_scsi(index)){
+          ips_free(ips_ha[index]);
+          rc = -1;
+       }
+
     if (rc == SUCCESS)
        ips_num_controllers++;
 
@@ -7127,7 +7147,7 @@
 }
 
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,9)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
 MODULE_LICENSE("GPL");
 #endif
 
diff -Nru a/drivers/scsi/ips.h b/drivers/scsi/ips.h
--- a/drivers/scsi/ips.h	Fri Feb 14 15:53:09 2003
+++ b/drivers/scsi/ips.h	Fri Feb 14 15:53:09 2003
@@ -64,11 +64,7 @@
    /*
     * Some handy macros
     */
-   #ifndef LinuxVersionCode
-      #define LinuxVersionCode(x,y,z)  (((x)<<16)+((y)<<8)+(z))
-   #endif
-
-   #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,20) || defined CONFIG_HIGHIO
+   #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) || defined CONFIG_HIGHIO
       #define IPS_HIGHIO
       #define IPS_HIGHMEM_IO     .highmem_io = 1,
    #else
@@ -97,14 +93,21 @@
     #define IPS_SGLIST_SIZE(ha)       (IPS_USE_ENH_SGLIST(ha) ? \
                                          sizeof(IPS_ENH_SG_LIST) : sizeof(IPS_STD_SG_LIST))
 
-   #if LINUX_VERSION_CODE < LinuxVersionCode(2,4,4)
+   #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)
       #define pci_set_dma_mask(dev,mask) (1)
       #define scsi_set_pci_device(sh,dev) (0)
    #endif
 
-   #if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0)
-      #define scsi_register_host(x)    scsi_register_module(MODULE_SCSI_HA,x)
-      #define scsi_unregister_host(x)  scsi_unregister_module(MODULE_SCSI_HA,x)
+   #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+      #define IPS_REGISTER_HOSTS(SHT)      scsi_register_module(MODULE_SCSI_HA,SHT)
+      #define IPS_UNREGISTER_HOSTS(SHT)    scsi_unregister_module(MODULE_SCSI_HA,SHT)
+      #define IPS_ADD_HOST(shost,device)
+      #define IPS_REMOVE_HOST(shost)
+   #else
+      #define IPS_REGISTER_HOSTS(SHT)      (!ips_detect(SHT))
+      #define IPS_UNREGISTER_HOSTS(SHT)
+      #define IPS_ADD_HOST(shost,device)   scsi_add_host(shost,device)
+      #define IPS_REMOVE_HOST(shost)       scsi_remove_host(shost)
    #endif
 
    #ifndef MDELAY
@@ -439,7 +442,7 @@
    /*
     * Scsi_Host Template
     */
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,5,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
    static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
    static int ips_biosparam(Disk *disk, kdev_t dev, int geom[]);
 #define IPS {	\
@@ -959,6 +962,20 @@
 } IPS_SCSI_MODE_PAGE4;
 
 /*
+ * Sense Data Format - Page 8
+ */
+typedef struct {
+   uint8_t  PageCode;
+   uint8_t  PageLength;
+   uint8_t  flags;
+   uint8_t  RetentPrio;
+   uint16_t DisPrefetchLen;
+   uint16_t MinPrefetchLen;
+   uint16_t MaxPrefetchLen;
+   uint16_t MaxPrefetchCeiling;
+} IPS_SCSI_MODE_PAGE8;
+
+/*
  * Sense Data Format - Block Descriptor (DASD)
  */
 typedef struct {
@@ -985,6 +1002,7 @@
    union {
       IPS_SCSI_MODE_PAGE3 pg3;
       IPS_SCSI_MODE_PAGE4 pg4;
+      IPS_SCSI_MODE_PAGE8 pg8;
    } pdata;
 } IPS_SCSI_MODE_PAGE_DATA;
 
diff -Nru a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
--- a/drivers/scsi/ppa.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/scsi/ppa.c	Fri Feb 14 15:53:11 2003
@@ -148,7 +148,7 @@
 		      "pardevice is owning the port for too longtime!\n",
 			   i);
 		    parport_unregister_device(ppa_hosts[i].dev);
-		    spin_lock_irq(ppa_hosts[i].cur_cmd->host->host_lock);
+		    spin_lock_irq(ppa_hosts[i].cur_cmd->device->host->host_lock);
 		    return 0;
 		}
 	    }
@@ -635,7 +635,7 @@
 
 static inline int ppa_send_command(Scsi_Cmnd * cmd)
 {
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
     int k;
 
     w_ctr(PPA_BASE(host_no), 0x0c);
@@ -661,7 +661,7 @@
      *  0     Told to schedule
      *  1     Finished data transfer
      */
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
     unsigned short ppb = PPA_BASE(host_no);
     unsigned long start_jiffies = jiffies;
 
@@ -752,7 +752,7 @@
 int ppa_command(Scsi_Cmnd * cmd)
 {
     static int first_pass = 1;
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
 
     if (first_pass) {
 	printk("ppa: using non-queuing interface\n");
@@ -774,7 +774,7 @@
 	schedule();
 
     if (cmd->SCp.phase)		/* Only disconnect if we have connected */
-	ppa_disconnect(cmd->host->unique_id);
+	ppa_disconnect(cmd->device->host->unique_id);
 
     ppa_pb_release(host_no);
     ppa_hosts[host_no].cur_cmd = 0;
@@ -807,7 +807,7 @@
     case DID_OK:
 	break;
     case DID_NO_CONNECT:
-	printk("ppa: no device at SCSI ID %i\n", cmd->target);
+	printk("ppa: no device at SCSI ID %i\n", cmd->device->target);
 	break;
     case DID_BUS_BUSY:
 	printk("ppa: BUS BUSY - EPP timeout detected\n");
@@ -836,21 +836,21 @@
 #endif
 
     if (cmd->SCp.phase > 1)
-	ppa_disconnect(cmd->host->unique_id);
+	ppa_disconnect(cmd->device->host->unique_id);
     if (cmd->SCp.phase > 0)
-	ppa_pb_release(cmd->host->unique_id);
+	ppa_pb_release(cmd->device->host->unique_id);
 
     tmp->cur_cmd = 0;
     
-    spin_lock_irqsave(cmd->host->host_lock, flags);
+    spin_lock_irqsave(cmd->device->host->host_lock, flags);
     cmd->scsi_done(cmd);
-    spin_unlock_irqrestore(cmd->host->host_lock, flags);
+    spin_unlock_irqrestore(cmd->device->host->host_lock, flags);
     return;
 }
 
 static int ppa_engine(ppa_struct * tmp, Scsi_Cmnd * cmd)
 {
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
     unsigned short ppb = PPA_BASE(host_no);
     unsigned char l = 0, h = 0;
     int retv;
@@ -900,7 +900,7 @@
 	}
 
     case 2:			/* Phase 2 - We are now talking to the scsi bus */
-	if (!ppa_select(host_no, cmd->target)) {
+	if (!ppa_select(host_no, cmd->device->id)) {
 	    ppa_fail(host_no, DID_NO_CONNECT);
 	    return 0;
 	}
@@ -966,7 +966,7 @@
 
 int ppa_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
 
     if (ppa_hosts[host_no].cur_cmd) {
 	printk("PPA: bug in ppa_queuecommand\n");
@@ -1011,7 +1011,7 @@
 
 int ppa_abort(Scsi_Cmnd * cmd)
 {
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
     /*
      * There is no method for aborting commands since Iomega
      * have tied the SCSI_MESSAGE line high in the interface
@@ -1039,7 +1039,7 @@
 
 int ppa_reset(Scsi_Cmnd * cmd)
 {
-    int host_no = cmd->host->unique_id;
+    int host_no = cmd->device->host->unique_id;
 
     if (cmd->SCp.phase)
 	ppa_disconnect(host_no);
diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
--- a/drivers/scsi/scsi_error.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/scsi/scsi_error.c	Fri Feb 14 15:53:08 2003
@@ -1579,24 +1579,14 @@
 	int rtn;
 	DECLARE_MUTEX_LOCKED(sem);
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigfillset(&current->blocked);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
 	lock_kernel();
 
 	/*
 	 *    Flush resources
 	 */
 
-	daemonize();
-
-	/*
-	 * Set the name of this process.
-	 */
+	daemonize("scsi_eh_%d", shost->host_no);
 
-	sprintf(current->comm, "scsi_eh_%d", shost->host_no);
 	current->flags |= PF_IOTHREAD;
 
 	shost->eh_wait = &sem;
diff -Nru a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c
--- a/drivers/scsi/seagate.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/scsi/seagate.c	Fri Feb 14 15:53:09 2003
@@ -683,8 +683,8 @@
 
 	DANY ("seagate: que_command");
 	done_fn = done;
-	current_target = SCpnt->target;
-	current_lun = SCpnt->lun;
+	current_target = SCpnt->device->id;
+	current_lun = SCpnt->device->lun;
 	current_cmnd = SCpnt->cmnd;
 	current_data = (unsigned char *) SCpnt->request_buffer;
 	current_bufflen = SCpnt->request_bufflen;
@@ -713,7 +713,7 @@
 #endif				/* LINKED */
 			reconnect = CAN_RECONNECT;
 
-		result = internal_command(SCint->target, SCint->lun, SCint->cmnd,
+		result = internal_command(SCint->device->id, SCint->device->lun, SCint->cmnd,
 				      SCint->request_buffer, SCint->request_bufflen, reconnect);
 		if (msg_byte(result) == DISCONNECT)
 			break;
@@ -729,7 +729,7 @@
 
 static int seagate_st0x_command(Scsi_Cmnd * SCpnt)
 {
-	return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd,
+	return internal_command (SCpnt->device->id, SCpnt->device->lun, SCpnt->cmnd,
 				 SCpnt->request_buffer, SCpnt->request_bufflen,
 				 (int) NO_RECONNECT);
 }
diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/scsi/st.c	Fri Feb 14 15:53:11 2003
@@ -3618,7 +3618,7 @@
 static ssize_t st_device_kdev_read(struct device *dev, char *page)
 {
 	kdev_t kdev; 
-	kdev.value=(int)dev->driver_data;
+	kdev.value=(unsigned long)dev->driver_data;
 	return sprintf(page, "%x\n",kdev.value);
 }
 static DEVICE_ATTR(kdev,S_IRUGO,st_device_kdev_read,NULL);
diff -Nru a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
--- a/drivers/scsi/sym53c416.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/scsi/sym53c416.c	Fri Feb 14 15:53:09 2003
@@ -1,4 +1,4 @@
-/* 
+/*
  *  sym53c416.c
  *  Low-level SCSI driver for sym53c416 chip.
  *  Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.com)
@@ -272,7 +272,7 @@
 		{
 			i = jiffies + timeout;
 			spin_unlock_irqrestore(&sym53c416_lock, flags);
-			while(jiffies < i && (inb(base + PIO_INT_REG) & EMPTY) && timeout)
+			while(time_before(jiffies, i) && (inb(base + PIO_INT_REG) & EMPTY) && timeout)
 				if(inb(base + PIO_INT_REG) & SCI)
 					timeout = 0;
 			spin_lock_irqsave(&sym53c416_lock, flags);
@@ -316,7 +316,7 @@
 		{
 			i = jiffies + timeout;
 			spin_unlock_irqrestore(&sym53c416_lock, flags);
-			while(jiffies < i && (inb(base + PIO_INT_REG) & FULL) && timeout)
+			while(time_before(jiffies, i) && (inb(base + PIO_INT_REG) & FULL) && timeout)
 				;
 			spin_lock_irqsave(&sym53c416_lock, flags);
 			if(inb(base + PIO_INT_REG) & FULL)
@@ -552,7 +552,7 @@
 	outb(0x00, base + DEST_BUS_ID);
 	/* Wait for interrupt to occur */
 	i = jiffies + 20;
-	while(i > jiffies && !(inb(base + STATUS_REG) & SCI))
+	while(time_before(jiffies, i) && !(inb(base + STATUS_REG) & SCI))
 		barrier();
 	if(time_before_eq(i, jiffies))	/* timed out */
 		return 0;
@@ -763,7 +763,7 @@
 	int i;
 
 	/* Store base register as we can have more than one controller in the system */
-	base = SCpnt->host->io_port;
+	base = SCpnt->device->host->io_port;
 	current_command = SCpnt;                  /* set current command                */
 	current_command->scsi_done = done;        /* set ptr to done function           */
 	current_command->SCp.phase = command_ph;  /* currect phase is the command phase */
@@ -771,7 +771,7 @@
 	current_command->SCp.Message = 0;
 
 	spin_lock_irqsave(&sym53c416_lock, flags);
-	outb(SCpnt->target, base + DEST_BUS_ID); /* Set scsi id target        */
+	outb(SCpnt->device->id, base + DEST_BUS_ID); /* Set scsi id target        */
 	outb(FLUSH_FIFO, base + COMMAND_REG);    /* Flush SCSI and PIO FIFO's */
 	/* Write SCSI command into the SCSI fifo */
 	for(i = 0; i < SCpnt->cmd_len; i++)
@@ -819,7 +819,7 @@
 	int i;
 
 	/* printk("sym53c416_reset\n"); */
-	base = SCpnt->host->io_port;
+	base = SCpnt->device->host->io_port;
 	/* search scsi_id - fixme, we shouldnt need to iterate for this! */
 	for(i = 0; i < host_index && scsi_id != -1; i++)
 		if(hosts[i].base == base)
diff -Nru a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
--- a/drivers/scsi/u14-34f.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/scsi/u14-34f.c	Fri Feb 14 15:53:09 2003
@@ -847,9 +847,9 @@
 
    if (have_old_firmware) tpnt->use_clustering = DISABLE_CLUSTERING;
 
-   spin_unlock(&driver_lock);
+   spin_unlock_irq(&driver_lock);
    sh[j] = scsi_register(tpnt, sizeof(struct hostdata));
-   spin_lock(&driver_lock);
+   spin_lock_irq(&driver_lock);
 
    if (sh[j] == NULL) {
       printk("%s: unable to register host, detaching.\n", name);
diff -Nru a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
--- a/drivers/scsi/ultrastor.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/scsi/ultrastor.c	Fri Feb 14 15:53:10 2003
@@ -504,7 +504,7 @@
      * Brrr, &config.mscp[0].SCint->host) it is something magical....
      * XXX and FIXME
      */
-    if (request_irq(config.interrupt, do_ultrastor_interrupt, 0, "Ultrastor", &config.mscp[0].SCint->host)) {
+    if (request_irq(config.interrupt, do_ultrastor_interrupt, 0, "Ultrastor", &config.mscp[0].SCint->device->host)) {
 	printk("Unable to allocate IRQ%u for UltraStor controller.\n",
 	       config.interrupt);
 	goto out_release_port;
@@ -714,9 +714,9 @@
 
        ???  Which other device types should never use the cache?   */
     my_mscp->ca = SCpnt->device->type != TYPE_TAPE;
-    my_mscp->target_id = SCpnt->target;
+    my_mscp->target_id = SCpnt->device->id;
     my_mscp->ch_no = 0;
-    my_mscp->lun = SCpnt->lun;
+    my_mscp->lun = SCpnt->device->lun;
     if (SCpnt->use_sg) {
 	/* Set scatter/gather flag in SCSI command packet */
 	my_mscp->sg = TRUE;
@@ -832,7 +832,7 @@
     unsigned char old_aborted;
     unsigned long flags;
     void (*done)(Scsi_Cmnd *);
-    struct Scsi_Host *host = SCpnt->host;
+    struct Scsi_Host *host = SCpnt->device->host;
 
     if(config.slot) 
       return FAILED;  /* Do not attempt an abort for the 24f */
@@ -954,7 +954,7 @@
 {
     unsigned long flags;
     int i;
-    struct Scsi_Host *host = SCpnt->host;
+    struct Scsi_Host *host = SCpnt->device->host;
     
 #if (ULTRASTOR_DEBUG & UD_RESET)
     printk("US14F: reset: called\n");
diff -Nru a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
--- a/drivers/scsi/wd7000.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/scsi/wd7000.c	Fri Feb 14 15:53:12 2003
@@ -1122,13 +1122,13 @@
 	register unchar *cdb = (unchar *) SCpnt->cmnd;
 	register unchar idlun;
 	register short cdblen;
-	Adapter *host = (Adapter *) SCpnt->host->hostdata;
+	Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
 
 	cdblen = SCpnt->cmd_len;
-	idlun = ((SCpnt->target << 5) & 0xe0) | (SCpnt->lun & 7);
+	idlun = ((SCpnt->device->id << 5) & 0xe0) | (SCpnt->device->lun & 7);
 	SCpnt->scsi_done = done;
 	SCpnt->SCp.phase = 1;
-	scb = alloc_scbs(SCpnt->host, 1);
+	scb = alloc_scbs(SCpnt->device->host, 1);
 	scb->idlun = idlun;
 	memcpy(scb->cdb, cdb, cdblen);
 	scb->direc = 0x40;	/* Disable direction check */
@@ -1141,7 +1141,7 @@
 		struct scatterlist *sg = (struct scatterlist *) SCpnt->request_buffer;
 		unsigned i;
 
-		if (SCpnt->host->sg_tablesize == SG_NONE) {
+		if (SCpnt->device->host->sg_tablesize == SG_NONE) {
 			panic("wd7000_queuecommand: scatter/gather not supported.\n");
 		}
 		dprintk("Using scatter/gather with %d elements.\n", SCpnt->use_sg);
@@ -1646,7 +1646,7 @@
  */
 static int wd7000_abort(Scsi_Cmnd * SCpnt)
 {
-	Adapter *host = (Adapter *) SCpnt->host->hostdata;
+	Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
 
 	if (inb(host->iobase + ASC_STAT) & INT_IM) {
 		printk("wd7000_abort: lost interrupt\n");
@@ -1677,7 +1677,7 @@
 
 static int wd7000_host_reset(Scsi_Cmnd * SCpnt)
 {
-	Adapter *host = (Adapter *) SCpnt->host->hostdata;
+	Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
 
 	if (wd7000_adapter_reset(host) < 0)
 		return FAILED;
diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
--- a/drivers/serial/sunsu.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/serial/sunsu.c	Fri Feb 14 15:53:09 2003
@@ -527,7 +527,7 @@
 			}
 			kbd_pt_regs = regs;
 #ifdef CONFIG_SERIO
-			serio_interrupt(&up->serio, ch, 0);
+			serio_interrupt(&up->serio, ch, 0, regs);
 #endif
 		} else if (up->su_type == SU_PORT_MS) {
 			int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -541,7 +541,7 @@
 
 			case 0:
 #ifdef CONFIG_SERIO
-				serio_interrupt(&up->serio, ch, 0);
+				serio_interrupt(&up->serio, ch, 0, regs);
 #endif
 				break;
 			};
diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- a/drivers/serial/sunzilog.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/serial/sunzilog.c	Fri Feb 14 15:53:12 2003
@@ -303,7 +303,7 @@
 		}
 		kbd_pt_regs = regs;
 #ifdef CONFIG_SERIO
-		serio_interrupt(&up->serio, ch, 0);
+		serio_interrupt(&up->serio, ch, 0, regs);
 #endif
 	} else if (ZS_IS_MOUSE(up)) {
 		int ret = suncore_mouse_baud_detection(ch, is_break);
@@ -317,7 +317,7 @@
 
 		case 0:
 #ifdef CONFIG_SERIO
-			serio_interrupt(&up->serio, ch, 0);
+			serio_interrupt(&up->serio, ch, 0, regs);
 #endif
 			break;
 		};
@@ -488,6 +488,8 @@
 			return;
 	}
 
+	up->flags &= ~SUNZILOG_FLAG_TX_ACTIVE;
+
 	if (ZS_REGS_HELD(up)) {
 		__load_zsregs(channel, up->curregs);
 		up->flags &= ~SUNZILOG_FLAG_REGS_HELD;
@@ -495,15 +497,11 @@
 
 	if (ZS_TX_STOPPED(up)) {
 		up->flags &= ~SUNZILOG_FLAG_TX_STOPPED;
-
-		sbus_writeb(RES_Tx_P, &channel->control);
-		ZSDELAY();
-		ZS_WSYNC(channel);
-
-		return;
+		goto ack_tx_int;
 	}
 
 	if (up->port.x_char) {
+		up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
 		sbus_writeb(up->port.x_char, &channel->data);
 		ZSDELAY();
 		ZS_WSYNC(channel);
@@ -516,9 +514,14 @@
 	if (up->port.info == NULL)
 		goto ack_tx_int;
 	xmit = &up->port.info->xmit;
-	if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port))
+	if (uart_circ_empty(xmit)) {
+		uart_write_wakeup(&up->port);
+		goto ack_tx_int;
+	}
+	if (uart_tx_stopped(&up->port))
 		goto ack_tx_int;
 
+	up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
 	sbus_writeb(xmit->buf[xmit->tail], &channel->data);
 	ZSDELAY();
 	ZS_WSYNC(channel);
@@ -529,9 +532,6 @@
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 		uart_write_wakeup(&up->port);
 
-	if (uart_circ_empty(xmit))
-		goto ack_tx_int;
-
 	return;
 
 ack_tx_int:
@@ -725,6 +725,9 @@
 	struct zilog_channel *channel;
 	unsigned long flags;
 
+	if (ZS_IS_CONS(up))
+		return;
+
 	spin_lock_irqsave(&port->lock, flags);
 
 	channel = ZILOG_CHANNEL_FROM_PORT(port);
@@ -1027,7 +1030,7 @@
 	.owner		=	THIS_MODULE,
 	.driver_name	=	"ttyS",
 #ifdef CONFIG_DEVFS_FS
-	.dev_name	=	"ttyS%d",
+	.dev_name	=	"tts/%d",
 #else
 	.dev_name	=	"ttyS%d",
 #endif
@@ -1481,7 +1484,7 @@
 	/*
 	 * Temporary fix.
 	 */
-	for (channel = 0; channel < NUM_CHANNELS - 1; channel++)
+	for (channel = 0; channel < NUM_CHANNELS; channel++)
 		spin_lock_init(&sunzilog_port_table[channel].port.lock);
 
 	sunzilog_irq_chain = up = &sunzilog_port_table[0];
@@ -1588,6 +1591,7 @@
 		} else {
 			/* Normal serial TTY. */
 			up->parity_mask = 0xff;
+			up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
 			up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
 			up->curregs[R3] = RxENAB | Rx8;
 			up->curregs[R5] = TxENAB | Tx8;
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/usb/core/hub.c	Fri Feb 14 15:53:09 2003
@@ -1083,10 +1083,8 @@
 	 * so get rid of all our resources
 	 */
 
-	daemonize();
-
-	/* Setup a nice name */
-	strcpy(current->comm, "khubd");
+	daemonize("khubd");
+	allow_signal(SIGKILL);
 
 	/* Send me a signal to get me die (for debugging) */
 	do {
diff -Nru a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
--- a/drivers/usb/input/Kconfig	Fri Feb 14 15:53:12 2003
+++ b/drivers/usb/input/Kconfig	Fri Feb 14 15:53:12 2003
@@ -49,7 +49,7 @@
 	  If unsure, say N.
 
 config HID_PID
-	bool "PID Devices"
+	bool "PID Devices (Microsoft Sidewinder Force Feedback 2)"
 	depends on HID_FF
 	help
 	  Say Y here if you have a PID-compliant joystick and wish to enable force
@@ -67,6 +67,15 @@
 	  Note: if you say N here, this device will still be supported, but without
 	  force feedback.
 
+config THRUSTMASTER_FF
+	bool "ThrustMaster FireStorm Dual Power 2 support (EXPERIMENTAL)"
+	depends on HID_FF && EXPERIMENTAL
+	help
+	  Say Y here if you have a THRUSTMASTER FireStore Dual Power 2,
+	  and want to enable force feedback support for it.
+	  Note: if you say N here, this device will still be supported, but without
+	  force feedback.
+
 config USB_HIDDEV
 	bool "/dev/hiddev raw HID device support"
 	depends on USB_HID
@@ -80,7 +89,6 @@
 	  This driver requires CONFIG_USB_HID.
 
 	  If unsure, say Y.
-
 
 menu "USB HID Boot Protocol drivers"
 	depends on USB!=n && USB_HID!=y
diff -Nru a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
--- a/drivers/usb/input/Makefile	Fri Feb 14 15:53:11 2003
+++ b/drivers/usb/input/Makefile	Fri Feb 14 15:53:11 2003
@@ -19,6 +19,9 @@
 ifeq ($(CONFIG_LOGITECH_FF),y)
 	hid-objs	+= hid-lgff.o
 endif
+ifeq ($(CONFIG_THRUSTMASTER_FF),y)
+	hid-objs	+= hid-tmff.o
+endif
 ifeq ($(CONFIG_HID_FF),y)
 	hid-objs	+= hid-ff.o
 endif
diff -Nru a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
--- a/drivers/usb/input/aiptek.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/usb/input/aiptek.c	Fri Feb 14 15:53:12 2003
@@ -155,6 +155,8 @@
 		dbg("received unknown report #%d", data[0]);
 	}
 
+	input_regs(dev, regs);
+
 	proximity = data[5] & 0x01;
 	input_report_key(dev, BTN_TOOL_PEN, proximity);
 
@@ -222,13 +224,18 @@
 		usb_unlink_urb(aiptek->irq);
 }
 
-/* 
- * FIXME, either remove this call, or talk the maintainer into 
- * adding usb_set_report back into the core.
- */
-#if 0
+#define USB_REQ_SET_REPORT	0x09
+static int
+usb_set_report(struct usb_device *dev, struct usb_host_interface *inter, unsigned char type,
+		unsigned char id, void *buf, int size)
+{
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+		USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+		(type << 8) + id, inter->desc.bInterfaceNumber, buf, size, HZ);
+}
+
 static void
-aiptek_command(struct usb_device *dev, unsigned int ifnum,
+aiptek_command(struct usb_device *dev, struct usb_host_interface *inter,
 	       unsigned char command, unsigned char data)
 {
 	__u8 buf[3];
@@ -237,17 +244,17 @@
 	buf[1] = command;
 	buf[2] = data;
 
-	if (usb_set_report(dev, ifnum, 3, 2, buf, 3) != 3) {
+	if (usb_set_report(dev, inter, 3, 2, buf, 3) != 3) {
 		dbg("aiptek_command: 0x%x 0x%x\n", command, data);
 	}
 }
-#endif
 
 static int 
 aiptek_probe(struct usb_interface *intf,
 	     const struct usb_device_id *id)
 {
 	struct usb_device *dev = interface_to_usbdev (intf);
+	struct usb_host_interface *interface = intf->altsetting + 0;
 	struct usb_endpoint_descriptor *endpoint;
 	struct aiptek *aiptek;
 
@@ -269,11 +276,11 @@
 		return -ENOMEM;
 	}
 
-	// Resolution500LPI
-//	aiptek_command(dev, ifnum, 0x18, 0x04);
+	/* Resolution500LPI */
+	aiptek_command(dev, interface, 0x18, 0x04);
 
-	// SwitchToTablet
-//	aiptek_command(dev, ifnum, 0x10, 0x01);
+	/* SwitchToTablet */
+	aiptek_command(dev, interface, 0x10, 0x01);
 
 	aiptek->features = aiptek_features + id->driver_info;
 
diff -Nru a/drivers/usb/input/fixp-arith.h b/drivers/usb/input/fixp-arith.h
--- a/drivers/usb/input/fixp-arith.h	Fri Feb 14 15:53:12 2003
+++ b/drivers/usb/input/fixp-arith.h	Fri Feb 14 15:53:12 2003
@@ -38,7 +38,7 @@
 #define FRAC_MASK ((1<<FRAC_N)-1)
 
 // Not to be used directly. Use fixp_{cos,sin}
-fixp_t cos_table[45] = {
+static fixp_t cos_table[45] = {
 	0x0100,	0x00FF,	0x00FF,	0x00FE,	0x00FD,	0x00FC,	0x00FA,	0x00F8,
 	0x00F6,	0x00F3,	0x00F0,	0x00ED,	0x00E9,	0x00E6,	0x00E2,	0x00DD,
 	0x00D9,	0x00D4,	0x00CF,	0x00C9,	0x00C4,	0x00BE,	0x00B8,	0x00B1,
@@ -49,7 +49,7 @@
 
 
 /* a: 123 -> 123.0 */
-inline fixp_t fixp_new(s16 a)
+static inline fixp_t fixp_new(s16 a)
 {
 	return a<<FRAC_N;
 }
@@ -58,12 +58,12 @@
       0x8000 -> 1.0
       0x0000 -> 0.0
 */
-inline fixp_t fixp_new16(s16 a)
+static inline fixp_t fixp_new16(s16 a)
 {
 	return ((s32)a)>>(16-FRAC_N);
 }
 
-inline fixp_t fixp_cos(unsigned int degrees)
+static inline fixp_t fixp_cos(unsigned int degrees)
 {
 	int quadrant = (degrees / 90) & 3;
 	unsigned int i = degrees % 90;
@@ -77,12 +77,12 @@
 	return (quadrant == 1 || quadrant == 2)? -cos_table[i] : cos_table[i];
 }
 
-inline fixp_t fixp_sin(unsigned int degrees)
+static inline fixp_t fixp_sin(unsigned int degrees)
 {
 	return -fixp_cos(degrees + 90);
 }
 
-inline fixp_t fixp_mult(fixp_t a, fixp_t b)
+static inline fixp_t fixp_mult(fixp_t a, fixp_t b)
 {
 	return ((s32)(a*b))>>FRAC_N;
 }
diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/usb/input/hid-core.c	Fri Feb 14 15:53:11 2003
@@ -773,13 +773,13 @@
 	return -1;
 }
 
-static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
+static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs)
 {
 	hid_dump_input(usage, value);
 	if (hid->claimed & HID_CLAIMED_INPUT)
-		hidinput_hid_event(hid, field, usage, value);
+		hidinput_hid_event(hid, field, usage, value, regs);
 	if (hid->claimed & HID_CLAIMED_HIDDEV)
-		hiddev_hid_event(hid, field, usage, value);
+		hiddev_hid_event(hid, field, usage, value, regs);
 }
 
 /*
@@ -788,7 +788,7 @@
  * reporting to the layer).
  */
 
-static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data)
+static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, struct pt_regs *regs)
 {
 	unsigned n;
 	unsigned count = field->report_count;
@@ -818,25 +818,25 @@
 			} else {
 				if (value[n] == field->value[n]) continue;
 			}	
-			hid_process_event(hid, field, &field->usage[n], value[n]);
+			hid_process_event(hid, field, &field->usage[n], value[n], regs);
 			continue;
 		}
 
 		if (field->value[n] >= min && field->value[n] <= max
 			&& field->usage[field->value[n] - min].hid
 			&& search(value, field->value[n], count))
-				hid_process_event(hid, field, &field->usage[field->value[n] - min], 0);
+				hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, regs);
 
 		if (value[n] >= min && value[n] <= max
 			&& field->usage[value[n] - min].hid
 			&& search(field->value, value[n], count))
-				hid_process_event(hid, field, &field->usage[value[n] - min], 1);
+				hid_process_event(hid, field, &field->usage[value[n] - min], 1, regs);
 	}
 
 	memcpy(field->value, value, count * sizeof(__s32));
 }
 
-static int hid_input_report(int type, struct urb *urb)
+static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs)
 {
 	struct hid_device *hid = urb->context;
 	struct hid_report_enum *report_enum = hid->report_enum + type;
@@ -886,7 +886,7 @@
 		hiddev_report_event(hid, report);
 
 	for (n = 0; n < report->maxfield; n++)
-		hid_input_field(hid, report->field[n], data);
+		hid_input_field(hid, report->field[n], data, regs);
 
 	if (hid->claimed & HID_CLAIMED_INPUT)
 		hidinput_report_event(hid, report);
@@ -905,7 +905,7 @@
 
 	switch (urb->status) {
 	case 0:			/* success */
-		hid_input_report(HID_INPUT_REPORT, urb);
+		hid_input_report(HID_INPUT_REPORT, urb, regs);
 		break;
 	case -ECONNRESET:	/* unlink */
 	case -ENOENT:
@@ -1130,7 +1130,7 @@
 	spin_lock_irqsave(&hid->ctrllock, flags);
 
 	if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) 
-		hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb);
+		hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, regs);
 
 	hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
 
@@ -1327,6 +1327,9 @@
 #define USB_VENDOR_ID_ONTRAK		0x0a07
 #define USB_DEVICE_ID_ONTRAK_ADU100	0x0064
 
+#define USB_VENDOR_ID_TANGTOP          0x0d3d
+#define USB_DEVICE_ID_TANGTOP_USBPS2   0x0001
+
 struct hid_blacklist {
 	__u16 idVendor;
 	__u16 idProduct;
@@ -1368,6 +1371,7 @@
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET },
 	{ 0, 0 }
 };
 
@@ -1533,6 +1537,8 @@
 	kfree(buf);
 
 	hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
+	if (!hid->urbctrl)
+		goto fail;
 	usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr,
 			     hid->ctrlbuf, 1, hid_ctrl, hid);
 	hid->urbctrl->setup_dma = hid->cr_dma;
diff -Nru a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c
--- a/drivers/usb/input/hid-ff.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/usb/input/hid-ff.c	Fri Feb 14 15:53:09 2003
@@ -38,6 +38,7 @@
 extern int hid_lgff_init(struct hid_device* hid);
 extern int hid_lg3d_init(struct hid_device* hid);
 extern int hid_pid_init(struct hid_device* hid);
+extern int hid_tmff_init(struct hid_device* hid);
 
 /*
  * This table contains pointers to initializers. To add support for new
@@ -56,6 +57,9 @@
 #endif
 #ifdef CONFIG_HID_PID
 	{0x45e, 0x001b, hid_pid_init},
+#endif
+#ifdef CONFIG_THRUSTMASTER_FF
+	{0x44f, 0xb304, hid_tmff_init},
 #endif
 	{0, 0, NULL} /* Terminating entry */
 };
diff -Nru a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
--- a/drivers/usb/input/hid-input.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/usb/input/hid-input.c	Fri Feb 14 15:53:09 2003
@@ -364,8 +364,13 @@
 		
 		input->absmin[usage->code] = a;
 		input->absmax[usage->code] = b;
-		input->absfuzz[usage->code] = (b - a) >> 8;
-		input->absflat[usage->code] = (b - a) >> 4;
+		input->absfuzz[usage->code] = 0;
+		input->absflat[usage->code] = 0;
+
+		if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK) {
+			input->absfuzz[usage->code] = (b - a) >> 8;
+			input->absflat[usage->code] = (b - a) >> 4;
+		}
 	}
 
 	if (usage->hat_min != usage->hat_max) {
@@ -380,10 +385,12 @@
 	}
 }
 
-void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
+void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs)
 {
 	struct input_dev *input = &hid->input;
 	int *quirks = &hid->quirks;
+
+	input_regs(input, regs);
 
 	if (usage->hat_min != usage->hat_max) {
 		value = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1;
diff -Nru a/drivers/usb/input/hid-tmff.c b/drivers/usb/input/hid-tmff.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/input/hid-tmff.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,461 @@
+/*
+ * Force feedback support for various HID compliant devices by ThrustMaster:
+ *    ThrustMaster FireStorm Dual Power 2
+ * and possibly others whose device ids haven't been added.
+ *
+ *  Modified to support ThrustMaster devices by Zinx Verituse
+ *  on 2003-01-25 from the Logitech force feedback driver,
+ *  which is by Johann Deneux.
+ *
+ *  Copyright (c) 2003 Zinx Verituse <zinx@epicsol.org>
+ *  Copyright (c) 2002 Johann Deneux
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/input.h>
+#include <linux/sched.h>
+
+#undef DEBUG
+#include <linux/usb.h>
+
+#include <linux/circ_buf.h>
+
+#include "hid.h"
+#include "fixp-arith.h"
+
+/* Usages for thrustmaster devices I know about */
+#define THRUSTMASTER_USAGE_RUMBLE_LR	(HID_UP_GENDESK | 0xbb)
+#define DELAY_CALC(t,delay)		((t) + (delay)*HZ/1000)
+
+/* Effect status */
+#define EFFECT_STARTED 0	/* Effect is going to play after some time */
+#define EFFECT_PLAYING 1	/* Effect is playing */
+#define EFFECT_USED    2
+
+/* For tmff_device::flags */
+#define DEVICE_CLOSING 0	/* The driver is being unitialised */
+
+/* Check that the current process can access an effect */
+#define CHECK_OWNERSHIP(effect) (current->pid == 0 \
+        || effect.owner == current->pid)
+
+#define TMFF_CHECK_ID(id)	((id) >= 0 && (id) < TMFF_EFFECTS)
+
+#define TMFF_CHECK_OWNERSHIP(i, l) \
+        (test_bit(EFFECT_USED, l->effects[i].flags) \
+        && CHECK_OWNERSHIP(l->effects[i]))
+
+#define TMFF_EFFECTS 8
+
+struct tmff_effect {
+	pid_t owner;
+
+	struct ff_effect effect;
+
+	unsigned long flags[1];
+	unsigned int count;             /* Number of times left to play */
+
+	unsigned long play_at;          /* When the effect starts to play */
+	unsigned long stop_at;		/* When the effect ends */
+};
+
+struct tmff_device {
+	struct hid_device *hid;
+
+	struct hid_report *report;
+
+	struct hid_field *rumble;
+
+	unsigned int effects_playing;
+	struct tmff_effect effects[TMFF_EFFECTS];
+	spinlock_t lock;             /* device-level lock. Having locks on
+					a per-effect basis could be nice, but
+					isn't really necessary */
+
+	unsigned long flags[1];      /* Contains various information about the
+					state of the driver for this device */
+
+	struct timer_list timer;
+};
+
+/* Callbacks */
+static void hid_tmff_exit(struct hid_device *hid);
+static int hid_tmff_event(struct hid_device *hid, struct input_dev *input,
+			  unsigned int type, unsigned int code, int value);
+static int hid_tmff_flush(struct input_dev *input, struct file *file);
+static int hid_tmff_upload_effect(struct input_dev *input,
+				  struct ff_effect *effect);
+static int hid_tmff_erase(struct input_dev *input, int id);
+
+/* Local functions */
+static void hid_tmff_recalculate_timer(struct tmff_device *tmff);
+static void hid_tmff_timer(unsigned long timer_data);
+
+int hid_tmff_init(struct hid_device *hid)
+{
+	struct tmff_device *private;
+	struct list_head *pos;
+
+	private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL);
+	if (!private) return -ENOMEM;
+
+	memset(private, 0, sizeof(struct tmff_device));
+	hid->ff_private = private;
+
+	/* Find the report to use */
+	__list_for_each(pos, &hid->report_enum[HID_OUTPUT_REPORT].report_list) {
+		struct hid_report *report = (struct hid_report *)pos;
+		int fieldnum;
+
+		for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) {
+			struct hid_field *field = report->field[fieldnum];
+
+			if (field->maxusage <= 0)
+				continue;
+
+			switch (field->usage[0].hid) {
+				case THRUSTMASTER_USAGE_RUMBLE_LR:
+					if (field->report_count < 2) {
+						warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR with report_count < 2");
+						continue;
+					}
+
+					if (field->logical_maximum == field->logical_minimum) {
+						warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR with logical_maximum == logical_minimum");
+						continue;
+					}
+
+					if (private->report && private->report != report) {
+						warn("ignoring THRUSTMASTER_USAGE_RUMBLE_LR in other report");
+						continue;
+					}
+
+					if (private->rumble && private->rumble != field) {
+						warn("ignoring duplicate THRUSTMASTER_USAGE_RUMBLE_LR");
+						continue;
+					}
+
+					private->report = report;
+					private->rumble = field;
+
+					set_bit(FF_RUMBLE, hid->input.ffbit);
+					break;
+
+				default:
+					warn("ignoring unknown output usage %08x", field->usage[0].hid);
+					continue;
+			}
+
+			/* Fallthrough to here only when a valid usage is found */
+			hid->input.upload_effect = hid_tmff_upload_effect;
+			hid->input.flush = hid_tmff_flush;
+
+			set_bit(EV_FF, hid->input.evbit);
+			hid->input.ff_effects_max = TMFF_EFFECTS;
+		}
+	}
+
+	private->hid = hid;
+
+	spin_lock_init(&private->lock);
+	init_timer(&private->timer);
+	private->timer.data = (unsigned long)private;
+	private->timer.function = hid_tmff_timer;
+
+	/* Event and exit callbacks */
+	hid->ff_exit = hid_tmff_exit;
+	hid->ff_event = hid_tmff_event;
+
+	info("Force feedback for ThrustMaster rumble pad devices by Zinx Verituse <zinx@epicsol.org>");
+
+	return 0;
+}
+
+static void hid_tmff_exit(struct hid_device *hid)
+{
+	struct tmff_device *tmff = hid->ff_private;
+	unsigned long flags;
+
+	spin_lock_irqsave(&tmff->lock, flags);
+
+	set_bit(DEVICE_CLOSING, tmff->flags);
+	del_timer_sync(&tmff->timer);
+
+	spin_unlock_irqrestore(&tmff->lock, flags);
+
+	kfree(tmff);
+}
+
+static int hid_tmff_event(struct hid_device *hid, struct input_dev *input,
+			  unsigned int type, unsigned int code, int value)
+{
+	struct tmff_device *tmff = hid->ff_private;
+	struct tmff_effect *effect = &tmff->effects[code];
+	unsigned long flags;
+
+	if (type != EV_FF)
+		return -EINVAL;
+	if (!TMFF_CHECK_ID(code))
+		return -EINVAL;
+	if (!TMFF_CHECK_OWNERSHIP(code, tmff))
+		return -EACCES;
+	if (value < 0)
+		return -EINVAL;
+
+	spin_lock_irqsave(&tmff->lock, flags);
+
+	if (value > 0) {
+		set_bit(EFFECT_STARTED, effect->flags);
+		clear_bit(EFFECT_PLAYING, effect->flags);
+		effect->count = value;
+		effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay);
+	} else {
+		clear_bit(EFFECT_STARTED, effect->flags);
+		clear_bit(EFFECT_PLAYING, effect->flags);
+	}
+
+	hid_tmff_recalculate_timer(tmff);
+
+	spin_unlock_irqrestore(&tmff->lock, flags);
+
+	return 0;
+
+}
+
+/* Erase all effects this process owns */
+
+static int hid_tmff_flush(struct input_dev *dev, struct file *file)
+{
+	struct hid_device *hid = dev->private;
+	struct tmff_device *tmff = hid->ff_private;
+	int i;
+
+	for (i=0; i<dev->ff_effects_max; ++i)
+
+	     /* NOTE: no need to lock here. The only times EFFECT_USED is
+		modified is when effects are uploaded or when an effect is
+		erased. But a process cannot close its dev/input/eventX fd
+		and perform ioctls on the same fd all at the same time */
+
+		if (current->pid == tmff->effects[i].owner
+		     && test_bit(EFFECT_USED, tmff->effects[i].flags))
+			if (hid_tmff_erase(dev, i))
+				warn("erase effect %d failed", i);
+
+
+	return 0;
+}
+
+static int hid_tmff_erase(struct input_dev *dev, int id)
+{
+	struct hid_device *hid = dev->private;
+	struct tmff_device *tmff = hid->ff_private;
+	unsigned long flags;
+
+	if (!TMFF_CHECK_ID(id))
+		return -EINVAL;
+	if (!TMFF_CHECK_OWNERSHIP(id, tmff))
+		return -EACCES;
+
+	spin_lock_irqsave(&tmff->lock, flags);
+
+	tmff->effects[id].flags[0] = 0;
+	hid_tmff_recalculate_timer(tmff);
+
+	spin_unlock_irqrestore(&tmff->lock, flags);
+
+	return 0;
+}
+
+static int hid_tmff_upload_effect(struct input_dev *input,
+				  struct ff_effect *effect)
+{
+	struct hid_device *hid = input->private;
+	struct tmff_device *tmff = hid->ff_private;
+	int id;
+	unsigned long flags;
+
+	if (!test_bit(effect->type, input->ffbit))
+		return -EINVAL;
+	if (effect->id != -1 && !TMFF_CHECK_ID(effect->id))
+		return -EINVAL;
+
+	spin_lock_irqsave(&tmff->lock, flags);
+
+	if (effect->id == -1) {
+		/* Find a free effect */
+		for (id = 0; id < TMFF_EFFECTS && test_bit(EFFECT_USED, tmff->effects[id].flags); ++id);
+
+		if (id >= TMFF_EFFECTS) {
+			spin_unlock_irqrestore(&tmff->lock, flags);
+			return -ENOSPC;
+		}
+
+		effect->id = id;
+		tmff->effects[id].owner = current->pid;
+		tmff->effects[id].flags[0] = 0;
+		set_bit(EFFECT_USED, tmff->effects[id].flags);
+
+	} else {
+		/* Re-uploading an owned effect, to change parameters */
+		id = effect->id;
+		clear_bit(EFFECT_PLAYING, tmff->effects[id].flags);
+	}
+
+	tmff->effects[id].effect = *effect;
+
+	hid_tmff_recalculate_timer(tmff);
+
+	spin_unlock_irqrestore(&tmff->lock, flags);
+	return 0;
+}
+
+/* Start the timer for the next start/stop/delay */
+/* Always call this while tmff->lock is locked */
+
+static void hid_tmff_recalculate_timer(struct tmff_device *tmff)
+{
+	int i;
+	int events = 0;
+	unsigned long next_time;
+
+	next_time = 0;	/* Shut up compiler's incorrect warning */
+
+	/* Find the next change in an effect's status */
+	for (i = 0; i < TMFF_EFFECTS; ++i) {
+		struct tmff_effect *effect = &tmff->effects[i];
+		unsigned long play_time;
+
+		if (!test_bit(EFFECT_STARTED, effect->flags))
+			continue;
+
+		effect->stop_at = DELAY_CALC(effect->play_at, effect->effect.replay.length);
+
+		if (!test_bit(EFFECT_PLAYING, effect->flags))
+			play_time = effect->play_at;
+		else
+			play_time = effect->stop_at;
+
+		events++;
+
+		if (time_after(jiffies, play_time))
+			play_time = jiffies;
+
+		if (events == 1)
+			next_time = play_time;
+		else {
+			if (time_after(next_time, play_time))
+				next_time = play_time;
+		}
+	}
+
+	if (!events && tmff->effects_playing) {
+		/* Treat all effects turning off as an event */
+		events = 1;
+		next_time = jiffies;
+	}
+
+	if (!events) {
+		/* No events, no time, no need for a timer. */
+		del_timer_sync(&tmff->timer);
+		return;
+	}
+
+	mod_timer(&tmff->timer, next_time);
+}
+
+/* Changes values from 0 to 0xffff into values from minimum to maximum */
+static inline int hid_tmff_scale(unsigned int in, int minimum, int maximum)
+{
+	int ret;
+
+	ret = (in * (maximum - minimum) / 0xffff) + minimum;
+	if (ret < minimum)
+		return minimum;
+	if (ret > maximum)
+		return maximum;
+	return ret;
+}
+
+static void hid_tmff_timer(unsigned long timer_data)
+{
+	struct tmff_device *tmff = (struct tmff_device *) timer_data;
+	struct hid_device *hid = tmff->hid;
+	unsigned long flags;
+	int left = 0, right = 0;	/* Rumbling */
+	int i;
+
+	spin_lock_irqsave(&tmff->lock, flags);
+
+	tmff->effects_playing = 0;
+
+	for (i = 0; i < TMFF_EFFECTS; ++i) {
+		struct tmff_effect *effect = &tmff->effects[i];
+
+		if (!test_bit(EFFECT_STARTED, effect->flags))
+			continue;
+
+		if (!time_after(jiffies, effect->play_at))
+			continue;
+
+		if (time_after(jiffies, effect->stop_at)) {
+
+			dbg("Finished playing once %d", i);
+			clear_bit(EFFECT_PLAYING, effect->flags);
+
+			if (--effect->count <= 0) {
+				dbg("Stopped %d", i);
+				clear_bit(EFFECT_STARTED, effect->flags);
+				continue;
+			} else {
+				dbg("Start again %d", i);
+				effect->play_at = DELAY_CALC(jiffies, effect->effect.replay.delay);
+				continue;
+			}
+		}
+
+		++tmff->effects_playing;
+
+		set_bit(EFFECT_PLAYING, effect->flags);
+
+		switch (effect->effect.type) {
+			case FF_RUMBLE:
+				right += effect->effect.u.rumble.strong_magnitude;
+				left += effect->effect.u.rumble.weak_magnitude;
+				break;
+			default:
+				BUG();
+				break;
+		}
+	}
+
+	left = hid_tmff_scale(left, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
+	right = hid_tmff_scale(right, tmff->rumble->logical_minimum, tmff->rumble->logical_maximum);
+
+	if (left != tmff->rumble->value[0] || right != tmff->rumble->value[1]) {
+		tmff->rumble->value[0] = left;
+		tmff->rumble->value[1] = right;
+		dbg("(left,right)=(%08x, %08x)", left, right);
+		hid_submit_report(hid, tmff->report, USB_DIR_OUT);
+	}
+
+	if (!test_bit(DEVICE_CLOSING, tmff->flags))
+		hid_tmff_recalculate_timer(tmff);
+
+	spin_unlock_irqrestore(&tmff->lock, flags);
+}
diff -Nru a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
--- a/drivers/usb/input/hid.h	Fri Feb 14 15:53:08 2003
+++ b/drivers/usb/input/hid.h	Fri Feb 14 15:53:08 2003
@@ -206,7 +206,7 @@
 #define HID_QUIRK_IGNORE	0x04
 #define HID_QUIRK_NOGET		0x08
 #define HID_QUIRK_HIDDEV	0x10
-#define HID_QUIRK_BADPAD        0x12
+#define HID_QUIRK_BADPAD        0x20
 
 /*
  * This is the global enviroment of the parser. This information is
@@ -420,13 +420,13 @@
 /* Applications from HID Usage Tables 4/8/99 Version 1.1 */
 /* We ignore a few input applications that are not widely used */
 #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || ( a == 0x00010080) || ( a == 0x000c0001))
-extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
+extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32, struct pt_regs *regs);
 extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
 extern int hidinput_connect(struct hid_device *);
 extern void hidinput_disconnect(struct hid_device *);
 #else
 #define IS_INPUT_APPLICATION(a) (0)
-static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { }
+static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) { }
 static inline void hidinput_report_event(struct hid_device *hid, struct hid_report *report) { }
 static inline int hidinput_connect(struct hid_device *hid) { return -ENODEV; }
 static inline void hidinput_disconnect(struct hid_device *hid) { }
diff -Nru a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/usb/input/hiddev.c	Fri Feb 14 15:53:09 2003
@@ -180,7 +180,7 @@
  * the interrupt pipe
  */
 void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
-		      struct hid_usage *usage, __s32 value)
+		      struct hid_usage *usage, __s32 value, struct pt_regs *regs)
 {
 	unsigned type = field->report_type;
 	struct hiddev_usage_ref uref;
diff -Nru a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
--- a/drivers/usb/input/powermate.c	Fri Feb 14 15:53:11 2003
+++ b/drivers/usb/input/powermate.c	Fri Feb 14 15:53:11 2003
@@ -1,9 +1,9 @@
 /*
  * A driver for the Griffin Technology, Inc. "PowerMate" USB controller dial.
  *
- * v1.0, (c)2002 William R Sowerbutts <will@sowerbutts.com>
+ * v1.1, (c)2002 William R Sowerbutts <will@sowerbutts.com>
  *
- * This device is a stainless steel knob which connects over USB. It can measure
+ * This device is a anodised aluminium knob which connects over USB. It can measure
  * clockwise and anticlockwise rotation. The dial also acts as a pushbutton with
  * a spring for automatic release. The base contains a pair of LEDs which illuminate
  * the translucent base. It rotates without limit and reports its relative rotation
@@ -15,13 +15,17 @@
  * speeds of up to 7 clicks either clockwise or anticlockwise between pollings from
  * the host. If it counts more than 7 clicks before it is polled, it will wrap back
  * to zero and start counting again. This was at quite high speed, however, almost
- * certainly faster than the human hand could turn it.
+ * certainly faster than the human hand could turn it. Griffin say that it loses a
+ * pulse or two on a direction change; the granularity is so fine that I never
+ * noticed this in practice.
  *
  * The device's microcontroller can be programmed to set the LED to either a constant
  * intensity, or to a rhythmic pulsing. Several patterns and speeds are available.
  *
  * Griffin were very happy to provide documentation and free hardware for development.
  *
+ * Some userspace tools are available on the web: http://sowerbutts.com/powermate/
+ *
  */
 
 #include <linux/kernel.h>
@@ -96,6 +100,7 @@
 	}
 
 	/* handle updates to device state */
+	input_regs(&pm->input, regs);
 	input_report_key(&pm->input, BTN_0, pm->data[0] & 0x01);
 	input_report_rel(&pm->input, REL_DIAL, pm->data[1]);
 	input_sync(&pm->input);
@@ -115,11 +120,7 @@
 	if (pm->config->status == -EINPROGRESS) 
 		return; /* an update is already in progress; it'll issue this update when it completes */
 
-	if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS){
-		pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS );
-		pm->configcr->wIndex = cpu_to_le16( pm->static_brightness );
-		pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS;
-	}else if (pm->requires_update & UPDATE_PULSE_ASLEEP){
+	if (pm->requires_update & UPDATE_PULSE_ASLEEP){
 		pm->configcr->wValue = cpu_to_le16( SET_PULSE_ASLEEP );
 		pm->configcr->wIndex = cpu_to_le16( pm->pulse_asleep ? 1 : 0 );
 		pm->requires_update &= ~UPDATE_PULSE_ASLEEP;
@@ -159,6 +160,10 @@
 		pm->configcr->wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE );
 		pm->configcr->wIndex = cpu_to_le16( (arg << 8) | op );
 		pm->requires_update &= ~UPDATE_PULSE_MODE;
+	}else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS){
+		pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS );
+		pm->configcr->wIndex = cpu_to_le16( pm->static_brightness );
+		pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS;
 	}else{
 		printk(KERN_ERR "powermate: unknown update required");
 		pm->requires_update = 0; /* fudge the bug */
@@ -219,11 +224,11 @@
 	}
 	if (pulse_asleep != pm->pulse_asleep){
 		pm->pulse_asleep = pulse_asleep;
-		pm->requires_update |= UPDATE_PULSE_ASLEEP;
+		pm->requires_update |= (UPDATE_PULSE_ASLEEP | UPDATE_STATIC_BRIGHTNESS);
 	}
 	if (pulse_awake != pm->pulse_awake){
 		pm->pulse_awake = pulse_awake;
-		pm->requires_update |= UPDATE_PULSE_AWAKE;
+		pm->requires_update |= (UPDATE_PULSE_AWAKE | UPDATE_STATIC_BRIGHTNESS);
 	}
 	if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table){
 		pm->pulse_speed = pulse_speed;
diff -Nru a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
--- a/drivers/usb/input/usbkbd.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/usb/input/usbkbd.c	Fri Feb 14 15:53:12 2003
@@ -99,6 +99,8 @@
 		goto resubmit;
 	}
 
+	input_regs(&kbd->dev, regs);
+
 	for (i = 0; i < 8; i++)
 		input_report_key(&kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
 
diff -Nru a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
--- a/drivers/usb/input/usbmouse.c	Fri Feb 14 15:53:12 2003
+++ b/drivers/usb/input/usbmouse.c	Fri Feb 14 15:53:12 2003
@@ -76,6 +76,7 @@
 		goto resubmit;
 	}
 
+	input_regs(dev, regs);
 
 	input_report_key(dev, BTN_LEFT,   data[0] & 0x01);
 	input_report_key(dev, BTN_RIGHT,  data[0] & 0x02);
diff -Nru a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
--- a/drivers/usb/input/wacom.c	Fri Feb 14 15:53:08 2003
+++ b/drivers/usb/input/wacom.c	Fri Feb 14 15:53:08 2003
@@ -102,6 +102,17 @@
 	char phys[32];
 };
 
+#define USB_REQ_SET_REPORT	0x09
+static int usb_set_report(struct usb_interface *intf, unsigned char type,
+				unsigned char id, void *buf, int size)
+{
+        return usb_control_msg(interface_to_usbdev(intf),
+		usb_sndctrlpipe(interface_to_usbdev(intf), 0),
+                USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+                (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber,
+		buf, size, HZ);
+}
+
 static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct wacom *wacom = urb->context;
@@ -129,6 +140,8 @@
 		dbg("received unknown report #%d", data[0]);
 
 	prox = data[1] & 0x40;
+
+	input_regs(dev, regs);
 	
 	input_report_key(dev, BTN_TOOL_PEN, prox);
 	
@@ -179,6 +192,7 @@
 		goto exit;
 	}
 
+	input_regs(dev, regs);
 	input_report_key(dev, BTN_TOOL_PEN, 1);
 	input_report_abs(dev, ABS_X, data[2] << 8 | data[1]);
 	input_report_abs(dev, ABS_Y, data[4] << 8 | data[3]);
@@ -223,6 +237,8 @@
 	x = data[2] | ((__u32)data[3] << 8);
 	y = data[4] | ((__u32)data[5] << 8);
 
+	input_regs(dev, regs);
+
 	switch ((data[1] >> 5) & 3) {
 
 		case 0:	/* Pen */
@@ -294,6 +310,8 @@
 	if (data[0] != 2)
 		dbg("received unknown report #%d", data[0]);
 
+	input_regs(dev, regs);
+
 	/* tool number */
 	idx = data[1] & 0x01;
 
@@ -481,6 +499,7 @@
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usb_endpoint_descriptor *endpoint;
+	char rep_data[2] = {0x02, 0x02};
 	struct wacom *wacom;
 	char path[64];
 
@@ -575,11 +594,9 @@
 
 	input_register_device(&wacom->dev);
 
-#if 0	/* Missing usb_set_report() */
 	usb_set_report(intf, 3, 2, rep_data, 2);
 	usb_set_report(intf, 3, 5, rep_data, 0);
 	usb_set_report(intf, 3, 6, rep_data, 0);
-#endif
 
 	printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path);
 
diff -Nru a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
--- a/drivers/usb/input/xpad.c	Fri Feb 14 15:53:10 2003
+++ b/drivers/usb/input/xpad.c	Fri Feb 14 15:53:10 2003
@@ -124,9 +124,11 @@
  *	 http://euc.jp/periphs/xbox-controller.ja.html
  */
 
-static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
+static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs)
 {
 	struct input_dev *dev = &xpad->dev;
+
+	input_regs(dev, regs);
 	
 	/* left stick */
 	input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12]));
@@ -183,7 +185,7 @@
 		goto exit;
 	}
 	
-	xpad_process_packet(xpad, 0, xpad->idata);
+	xpad_process_packet(xpad, 0, xpad->idata, regs);
 
 exit:
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c	Fri Feb 14 15:53:09 2003
+++ b/drivers/usb/storage/usb.c	Fri Feb 14 15:53:09 2003
@@ -298,18 +298,9 @@
 	 * This thread doesn't need any user-level access,
 	 * so get rid of all our resources..
 	 */
-	daemonize();
+	daemonize("usb-storage");
 
-	/* avoid getting signals */
-	spin_lock_irq(&current->sighand->siglock);
-	flush_signals(current);
 	current->flags |= PF_IOTHREAD;
-	sigfillset(&current->blocked);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	/* set our name for identification purposes */
-	sprintf(current->comm, "usb-storage");
 
 	unlock_kernel();
 
diff -Nru a/fs/afs/cmservice.c b/fs/afs/cmservice.c
--- a/fs/afs/cmservice.c	Fri Feb 14 15:53:09 2003
+++ b/fs/afs/cmservice.c	Fri Feb 14 15:53:09 2003
@@ -120,17 +120,9 @@
 	int die;
 
 	printk("kAFS: Started kafscmd %d\n",current->pid);
-	strcpy(current->comm,"kafscmd");
-
-	daemonize();
+	daemonize("kafscmd");
 
 	complete(&kafscmd_alive);
-
-	/* only certain signals are of interest */
-	spin_lock_irq(&current->sighand->siglock);
-	siginitsetinv(&current->blocked,0);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
 
 	/* loop around looking for things to attend to */
 	do {
diff -Nru a/fs/afs/internal.h b/fs/afs/internal.h
--- a/fs/afs/internal.h	Fri Feb 14 15:53:09 2003
+++ b/fs/afs/internal.h	Fri Feb 14 15:53:09 2003
@@ -47,7 +47,7 @@
 		siginfo_t sinfo;
 
 		spin_lock_irq(&current->sighand->siglock);
-		dequeue_signal(&current->blocked,&sinfo);
+		dequeue_signal(current,&current->blocked,&sinfo);
 		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
diff -Nru a/fs/afs/kafsasyncd.c b/fs/afs/kafsasyncd.c
--- a/fs/afs/kafsasyncd.c	Fri Feb 14 15:53:12 2003
+++ b/fs/afs/kafsasyncd.c	Fri Feb 14 15:53:12 2003
@@ -94,17 +94,10 @@
 	kafsasyncd_task = current;
 
 	printk("kAFS: Started kafsasyncd %d\n",current->pid);
-	strcpy(current->comm,"kafsasyncd");
 
-	daemonize();
+	daemonize("kafsasyncd");
 
 	complete(&kafsasyncd_alive);
-
-	/* only certain signals are of interest */
-	spin_lock_irq(&current->sighand->siglock);
-	siginitsetinv(&current->blocked,0);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
 
 	/* loop around looking for things to attend to */
 	do {
diff -Nru a/fs/afs/kafstimod.c b/fs/afs/kafstimod.c
--- a/fs/afs/kafstimod.c	Fri Feb 14 15:53:11 2003
+++ b/fs/afs/kafstimod.c	Fri Feb 14 15:53:11 2003
@@ -71,17 +71,10 @@
 	afs_timer_t *timer;
 
 	printk("kAFS: Started kafstimod %d\n",current->pid);
-	strcpy(current->comm,"kafstimod");
 
-	daemonize();
+	daemonize("kafstimod");
 
 	complete(&kafstimod_alive);
-
-	/* only certain signals are of interest */
-	spin_lock_irq(&current->sighand->siglock);
-	siginitsetinv(&current->blocked,0);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
 
 	/* loop around looking for things to attend to */
  loop:
diff -Nru a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c	Fri Feb 14 15:53:10 2003
+++ b/fs/buffer.c	Fri Feb 14 15:53:10 2003
@@ -31,7 +31,6 @@
 #include <linux/highmem.h>
 #include <linux/module.h>
 #include <linux/writeback.h>
-#include <linux/mempool.h>
 #include <linux/hash.h>
 #include <linux/suspend.h>
 #include <linux/buffer_head.h>
@@ -2619,6 +2618,24 @@
 }
 
 /*
+ * For a data-integrity writeout, we need to wait upon any in-progress I/O
+ * and then start new I/O and then wait upon it.
+ */
+void sync_dirty_buffer(struct buffer_head *bh)
+{
+	WARN_ON(atomic_read(&bh->b_count) < 1);
+	lock_buffer(bh);
+	if (test_clear_buffer_dirty(bh)) {
+		get_bh(bh);
+		bh->b_end_io = end_buffer_io_sync;
+		submit_bh(WRITE, bh);
+		wait_on_buffer(bh);
+	} else {
+		unlock_buffer(bh);
+	}
+}
+
+/*
  * Sanity checks for try_to_free_buffers.
  */
 static void check_ttfb_buffer(struct page *page, struct buffer_head *bh)
@@ -2773,7 +2790,6 @@
  * Buffer-head allocation
  */
 static kmem_cache_t *bh_cachep;
-static mempool_t *bh_mempool;
 
 /*
  * Once the number of bh's in the machine exceeds this level, we start
@@ -2807,7 +2823,7 @@
 	
 struct buffer_head *alloc_buffer_head(void)
 {
-	struct buffer_head *ret = mempool_alloc(bh_mempool, GFP_NOFS);
+	struct buffer_head *ret = kmem_cache_alloc(bh_cachep, GFP_NOFS);
 	if (ret) {
 		preempt_disable();
 		__get_cpu_var(bh_accounting).nr++;
@@ -2821,7 +2837,7 @@
 void free_buffer_head(struct buffer_head *bh)
 {
 	BUG_ON(!list_empty(&bh->b_assoc_buffers));
-	mempool_free(bh, bh_mempool);
+	kmem_cache_free(bh_cachep, bh);
 	preempt_disable();
 	__get_cpu_var(bh_accounting).nr--;
 	recalc_bh_state();
@@ -2829,7 +2845,8 @@
 }
 EXPORT_SYMBOL(free_buffer_head);
 
-static void init_buffer_head(void *data, kmem_cache_t *cachep, unsigned long flags)
+static void
+init_buffer_head(void *data, kmem_cache_t *cachep, unsigned long flags)
 {
 	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
 			    SLAB_CTOR_CONSTRUCTOR) {
@@ -2840,19 +2857,6 @@
 	}
 }
 
-static void *bh_mempool_alloc(int gfp_mask, void *pool_data)
-{
-	return kmem_cache_alloc(bh_cachep, gfp_mask);
-}
-
-static void bh_mempool_free(void *element, void *pool_data)
-{
-	return kmem_cache_free(bh_cachep, element);
-}
-
-#define NR_RESERVED (10*MAX_BUF_PER_PAGE)
-#define MAX_UNUSED_BUFFERS NR_RESERVED+20
-
 static void buffer_init_cpu(int cpu)
 {
 	struct bh_accounting *bha = &per_cpu(bh_accounting, cpu);
@@ -2889,8 +2893,6 @@
 	bh_cachep = kmem_cache_create("buffer_head",
 			sizeof(struct buffer_head), 0,
 			0, init_buffer_head, NULL);
-	bh_mempool = mempool_create(MAX_UNUSED_BUFFERS, bh_mempool_alloc,
-				bh_mempool_free, NULL);
 	for (i = 0; i < ARRAY_SIZE(bh_wait_queue_heads); i++)
 		init_waitqueue_head(&bh_wait_queue_heads[i].wqh);
 
diff -Nru a/fs/cifs/connect.c b/fs/cifs/connect.c
--- a/fs/cifs/connect.c	Fri Feb 14 15:53:12 2003
+++ b/fs/cifs/connect.c	Fri Feb 14 15:53:12 2003
@@ -95,7 +95,8 @@
 	struct mid_q_entry *mid_entry;
 	char *temp;
 
-	daemonize();
+	daemonize("cifsd");
+	allow_signal(SIGKILL);
 
 	server->tsk = current;	/* save process info to wake at shutdown */
 	cFYI(1, ("\nDemultiplex PID: %d", current->pid));
diff -Nru a/fs/devfs/base.c b/fs/devfs/base.c
--- a/fs/devfs/base.c	Fri Feb 14 15:53:09 2003
+++ b/fs/devfs/base.c	Fri Feb 14 15:53:09 2003
@@ -1169,7 +1169,7 @@
     *leaf_pos = (name[namelen] == '/') ? (namelen + 1) : 0;
     for (; namelen > 0; name += next_pos, namelen -= next_pos)
     {
-	struct devfs_entry *de, *old;
+	struct devfs_entry *de, *old = NULL;
 
 	if ( ( de = _devfs_descend (dir, name, namelen, &next_pos) ) == NULL )
 	{
diff -Nru a/fs/eventpoll.c b/fs/eventpoll.c
--- a/fs/eventpoll.c	Fri Feb 14 15:53:09 2003
+++ b/fs/eventpoll.c	Fri Feb 14 15:53:09 2003
@@ -261,7 +261,7 @@
 			  struct epoll_event *events);
 static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, int maxevents);
 static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents,
-		   int timeout);
+		   long timeout);
 static int eventpollfs_delete_dentry(struct dentry *dentry);
 static struct inode *ep_eventpoll_inode(void);
 static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
@@ -446,7 +446,7 @@
  * file descriptors inside the epoll interface. It is the kernel part of
  * the userspace epoll_create(2).
  */
-asmlinkage int sys_epoll_create(int size)
+asmlinkage long sys_epoll_create(int size)
 {
 	int error, fd;
 	unsigned int hashbits;
@@ -492,7 +492,7 @@
  * file that enable the insertion/removal/change of file descriptors inside
  * the interest set. It rapresents the kernel part of the user spcae epoll_ctl(2).
  */
-asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
+asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
 {
 	int error;
 	struct file *file, *tfile;
@@ -596,8 +596,8 @@
  * Implement the event wait interface for the eventpoll file. It is the kernel
  * part of the user space epoll_wait(2).
  */
-asmlinkage int sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
-			      int timeout)
+asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
+			       int timeout)
 {
 	int error;
 	struct file *file;
@@ -1420,7 +1420,7 @@
 
 
 static int ep_poll(struct eventpoll *ep, struct epoll_event *events, int maxevents,
-		   int timeout)
+		   long timeout)
 {
 	int res, eavail;
 	unsigned long flags;
@@ -1428,10 +1428,12 @@
 	wait_queue_t wait;
 
 	/*
-	 * Calculate the timeout by checking for the "infinite" value ( -1 ).
-	 * The passed timeout is in milliseconds, that why (t * HZ) / 1000.
+	 * Calculate the timeout by checking for the "infinite" value ( -1 )
+	 * and the overflow condition. The passed timeout is in milliseconds,
+	 * that why (t * HZ) / 1000.
 	 */
-	jtimeout = timeout == -1 ? MAX_SCHEDULE_TIMEOUT: (timeout * HZ) / 1000;
+	jtimeout = timeout == -1 || timeout > (MAX_SCHEDULE_TIMEOUT - 1000) / HZ ?
+		MAX_SCHEDULE_TIMEOUT: (timeout * HZ + 999) / 1000;
 
 retry:
 	write_lock_irqsave(&ep->lock, flags);
diff -Nru a/fs/exec.c b/fs/exec.c
--- a/fs/exec.c	Fri Feb 14 15:53:09 2003
+++ b/fs/exec.c	Fri Feb 14 15:53:09 2003
@@ -596,6 +596,7 @@
 		newsig->group_exit_code = 0;
 		newsig->group_exit_task = NULL;
 		newsig->group_stop_count = 0;
+		newsig->curr_target = NULL;
 		init_sigpending(&newsig->shared_pending);
 	}
 
diff -Nru a/fs/ext2/balloc.c b/fs/ext2/balloc.c
--- a/fs/ext2/balloc.c	Fri Feb 14 15:53:09 2003
+++ b/fs/ext2/balloc.c	Fri Feb 14 15:53:09 2003
@@ -233,10 +233,8 @@
 	}
 
 	mark_buffer_dirty(bitmap_bh);
-	if (sb->s_flags & MS_SYNCHRONOUS) {
-		ll_rw_block(WRITE, 1, &bitmap_bh);
-		wait_on_buffer(bitmap_bh);
-	}
+	if (sb->s_flags & MS_SYNCHRONOUS)
+		sync_dirty_buffer(bitmap_bh);
 
 	group_release_blocks(desc, bh2, group_freed);
 	freed += group_freed;
@@ -466,10 +464,8 @@
 	write_unlock(&EXT2_I(inode)->i_meta_lock);
 
 	mark_buffer_dirty(bitmap_bh);
-	if (sb->s_flags & MS_SYNCHRONOUS) {
-		ll_rw_block(WRITE, 1, &bitmap_bh);
-		wait_on_buffer(bitmap_bh);
-	}
+	if (sb->s_flags & MS_SYNCHRONOUS)
+		sync_dirty_buffer(bitmap_bh);
 
 	ext2_debug ("allocating block %d. ", block);
 
diff -Nru a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
--- a/fs/ext2/ialloc.c	Fri Feb 14 15:53:10 2003
+++ b/fs/ext2/ialloc.c	Fri Feb 14 15:53:10 2003
@@ -146,10 +146,8 @@
 		mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
 	}
 	mark_buffer_dirty(bitmap_bh);
-	if (sb->s_flags & MS_SYNCHRONOUS) {
-		ll_rw_block(WRITE, 1, &bitmap_bh);
-		wait_on_buffer(bitmap_bh);
-	}
+	if (sb->s_flags & MS_SYNCHRONOUS)
+		sync_dirty_buffer(bitmap_bh);
 	sb->s_dirt = 1;
 error_return:
 	brelse(bitmap_bh);
@@ -485,10 +483,8 @@
 	ext2_set_bit(i, bitmap_bh->b_data);
 
 	mark_buffer_dirty(bitmap_bh);
-	if (sb->s_flags & MS_SYNCHRONOUS) {
-		ll_rw_block(WRITE, 1, &bitmap_bh);
-		wait_on_buffer(bitmap_bh);
-	}
+	if (sb->s_flags & MS_SYNCHRONOUS)
+		sync_dirty_buffer(bitmap_bh);
 	brelse(bitmap_bh);
 
 	ino = group * EXT2_INODES_PER_GROUP(sb) + i + 1;
diff -Nru a/fs/ext2/inode.c b/fs/ext2/inode.c
--- a/fs/ext2/inode.c	Fri Feb 14 15:53:08 2003
+++ b/fs/ext2/inode.c	Fri Feb 14 15:53:08 2003
@@ -443,10 +443,8 @@
 		 * But we now rely upon generic_osync_inode()
 		 * and b_inode_buffers.  But not for directories.
 		 */
-		if (S_ISDIR(inode->i_mode) && IS_DIRSYNC(inode)) {
-			ll_rw_block(WRITE, 1, &bh);
-			wait_on_buffer(bh);
-		}
+		if (S_ISDIR(inode->i_mode) && IS_DIRSYNC(inode))
+			sync_dirty_buffer(bh);
 		parent = nr;
 	}
 	if (n == num)
@@ -1208,8 +1206,7 @@
 		raw_inode->i_block[n] = ei->i_data[n];
 	mark_buffer_dirty(bh);
 	if (do_sync) {
-		ll_rw_block (WRITE, 1, &bh);
-		wait_on_buffer (bh);
+		sync_dirty_buffer(bh);
 		if (buffer_req(bh) && !buffer_uptodate(bh)) {
 			printk ("IO error syncing ext2 inode [%s:%08lx]\n",
 				sb->s_id, (unsigned long) ino);
diff -Nru a/fs/ext2/super.c b/fs/ext2/super.c
--- a/fs/ext2/super.c	Fri Feb 14 15:53:11 2003
+++ b/fs/ext2/super.c	Fri Feb 14 15:53:11 2003
@@ -842,8 +842,7 @@
 {
 	es->s_wtime = cpu_to_le32(get_seconds());
 	mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
-	ll_rw_block(WRITE, 1, &EXT2_SB(sb)->s_sbh);
-	wait_on_buffer(EXT2_SB(sb)->s_sbh);
+	sync_dirty_buffer(EXT2_SB(sb)->s_sbh);
 	sb->s_dirt = 0;
 }
 
diff -Nru a/fs/ext2/xattr.c b/fs/ext2/xattr.c
--- a/fs/ext2/xattr.c	Fri Feb 14 15:53:11 2003
+++ b/fs/ext2/xattr.c	Fri Feb 14 15:53:11 2003
@@ -774,8 +774,7 @@
 		}
 		mark_buffer_dirty(new_bh);
 		if (IS_SYNC(inode)) {
-			ll_rw_block(WRITE, 1, &new_bh);
-			wait_on_buffer(new_bh); 
+			sync_dirty_buffer(new_bh);
 			error = -EIO;
 			if (buffer_req(new_bh) && !buffer_uptodate(new_bh))
 				goto cleanup;
@@ -865,10 +864,8 @@
 		HDR(bh)->h_refcount = cpu_to_le32(
 			le32_to_cpu(HDR(bh)->h_refcount) - 1);
 		mark_buffer_dirty(bh);
-		if (IS_SYNC(inode)) {
-			ll_rw_block(WRITE, 1, &bh);
-			wait_on_buffer(bh);
-		}
+		if (IS_SYNC(inode))
+			sync_dirty_buffer(bh);
 		DQUOT_FREE_BLOCK(inode, 1);
 	}
 	EXT2_I(inode)->i_file_acl = 0;
diff -Nru a/fs/ext3/acl.c b/fs/ext3/acl.c
--- a/fs/ext3/acl.c	Fri Feb 14 15:53:09 2003
+++ b/fs/ext3/acl.c	Fri Feb 14 15:53:09 2003
@@ -231,7 +231,7 @@
 			return (int)PTR_ERR(value);
 	}
 
-	error = ext3_xattr_set(handle, inode, name_index, "", value, size, 0);
+	error = ext3_xattr_set_handle(handle, inode, name_index, "", value, size, 0);
 
 	if (value)
 		kfree(value);
diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
--- a/fs/ext3/inode.c	Fri Feb 14 15:53:11 2003
+++ b/fs/ext3/inode.c	Fri Feb 14 15:53:11 2003
@@ -1317,10 +1317,7 @@
 		goto out_fail;
 
 	needed = ext3_writepage_trans_blocks(inode);
-	if (wbc->for_reclaim)
-		handle = ext3_journal_try_start(inode, needed);
-	else
-		handle = ext3_journal_start(inode, needed);
+	handle = ext3_journal_start(inode, needed);
 				
 	if (IS_ERR(handle)) {
 		ret = PTR_ERR(handle);
diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c
--- a/fs/ext3/super.c	Fri Feb 14 15:53:12 2003
+++ b/fs/ext3/super.c	Fri Feb 14 15:53:12 2003
@@ -1343,9 +1343,7 @@
 	 * superblock lock.
 	 */
 	EXT3_SB(sb)->s_mount_state |= EXT3_ORPHAN_FS;
-	unlock_super(sb);	/* akpm: sigh */
 	ext3_orphan_cleanup(sb, es);
-	lock_super(sb);
 	EXT3_SB(sb)->s_mount_state &= ~EXT3_ORPHAN_FS;
 	if (needs_recovery)
 		printk (KERN_INFO "EXT3-fs: recovery complete.\n");
@@ -1627,10 +1625,8 @@
 	es->s_wtime = cpu_to_le32(get_seconds());
 	BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "marking dirty");
 	mark_buffer_dirty(EXT3_SB(sb)->s_sbh);
-	if (sync) {
-		ll_rw_block(WRITE, 1, &EXT3_SB(sb)->s_sbh);
-		wait_on_buffer(EXT3_SB(sb)->s_sbh);
-	}
+	if (sync)
+		sync_dirty_buffer(EXT3_SB(sb)->s_sbh);
 }
 
 
diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c
--- a/fs/ext3/xattr.c	Fri Feb 14 15:53:10 2003
+++ b/fs/ext3/xattr.c	Fri Feb 14 15:53:10 2003
@@ -88,8 +88,9 @@
 # define ea_bdebug(f...)
 #endif
 
-static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *,
-			   struct ext3_xattr_header *);
+static int ext3_xattr_set_handle2(handle_t *, struct inode *,
+				  struct buffer_head *,
+				  struct ext3_xattr_header *);
 
 static int ext3_xattr_cache_insert(struct buffer_head *);
 static struct buffer_head *ext3_xattr_cache_find(struct inode *,
@@ -459,7 +460,7 @@
 }
 
 /*
- * ext3_xattr_set()
+ * ext3_xattr_set_handle()
  *
  * Create, replace or remove an extended attribute for this inode. Buffer
  * is NULL to remove an existing extended attribute, and non-NULL to
@@ -471,8 +472,9 @@
  * Returns 0, or a negative error number on failure.
  */
 int
-ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
-	       const char *name, const void *value, size_t value_len, int flags)
+ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+		      const char *name, const void *value, size_t value_len,
+		      int flags)
 {
 	struct super_block *sb = inode->i_sb;
 	struct buffer_head *bh = NULL;
@@ -673,7 +675,8 @@
 			/* Remove this attribute. */
 			if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) {
 				/* This block is now empty. */
-				error = ext3_xattr_set2(handle, inode, bh,NULL);
+				error = ext3_xattr_set_handle2(handle, inode,
+							       bh, NULL);
 				goto cleanup;
 			} else {
 				/* Remove the old name. */
@@ -701,7 +704,7 @@
 	}
 	ext3_xattr_rehash(header, here);
 
-	error = ext3_xattr_set2(handle, inode, bh, header);
+	error = ext3_xattr_set_handle2(handle, inode, bh, header);
 
 cleanup:
 	brelse(bh);
@@ -713,11 +716,12 @@
 }
 
 /*
- * Second half of ext3_xattr_set(): Update the file system.
+ * Second half of ext3_xattr_set_handle(): Update the file system.
  */
 static int
-ext3_xattr_set2(handle_t *handle, struct inode *inode,
-		struct buffer_head *old_bh, struct ext3_xattr_header *header)
+ext3_xattr_set_handle2(handle_t *handle, struct inode *inode,
+		       struct buffer_head *old_bh,
+		       struct ext3_xattr_header *header)
 {
 	struct super_block *sb = inode->i_sb;
 	struct buffer_head *new_bh = NULL;
@@ -827,6 +831,34 @@
 cleanup:
 	if (old_bh != new_bh)
 		brelse(new_bh);
+
+	return error;
+}
+
+/*
+ * ext3_xattr_set()
+ *
+ * Like ext3_xattr_set_handle, but start from an inode. This extended
+ * attribute modification is a filesystem transaction by itself.
+ *
+ * Returns 0, or a negative error number on failure.
+ */
+int
+ext3_xattr_set(struct inode *inode, int name_index, const char *name,
+	       const void *value, size_t value_len, int flags)
+{
+	handle_t *handle;
+	int error;
+
+	lock_kernel();
+	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
+	if (IS_ERR(handle))
+		error = PTR_ERR(handle);
+	else
+		error = ext3_xattr_set_handle(handle, inode, name_index, name,
+					      value, value_len, flags);
+	ext3_journal_stop(handle, inode);
+	unlock_kernel();
 
 	return error;
 }
diff -Nru a/fs/ext3/xattr.h b/fs/ext3/xattr.h
--- a/fs/ext3/xattr.h	Fri Feb 14 15:53:12 2003
+++ b/fs/ext3/xattr.h	Fri Feb 14 15:53:12 2003
@@ -73,7 +73,8 @@
 
 extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
 extern int ext3_xattr_list(struct inode *, char *, size_t);
-extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int);
+extern int ext3_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
+extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int);
 
 extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
 extern void ext3_xattr_put_super(struct super_block *);
@@ -101,7 +102,14 @@
 }
 
 static inline int
-ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index,
+ext3_xattr_set(struct inode *inode, int name_index, const char *name,
+	       const void *value, size_t size, int flags)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int
+ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
 	       const char *name, const void *value, size_t size, int flags)
 {
 	return -EOPNOTSUPP;
diff -Nru a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c
--- a/fs/ext3/xattr_user.c	Fri Feb 14 15:53:09 2003
+++ b/fs/ext3/xattr_user.c	Fri Feb 14 15:53:09 2003
@@ -61,7 +61,6 @@
 ext3_xattr_user_set(struct inode *inode, const char *name,
 		    const void *value, size_t size, int flags)
 {
-	handle_t *handle;
 	int error;
 
 	if (strcmp(name, "") == 0)
@@ -79,16 +78,9 @@
 	if (error)
 		return error;
   
-	lock_kernel();
-	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
-	if (IS_ERR(handle))
-		return PTR_ERR(handle);
-	error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name,
-			       value, size, flags);
-	ext3_journal_stop(handle, inode);
-	unlock_kernel();
+	return ext3_xattr_set(inode, EXT3_XATTR_INDEX_USER, name,
+			      value, size, flags);
 
-	return error;
 }
 
 struct ext3_xattr_handler ext3_xattr_user_handler = {
diff -Nru a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
--- a/fs/hugetlbfs/inode.c	Fri Feb 14 15:53:12 2003
+++ b/fs/hugetlbfs/inode.c	Fri Feb 14 15:53:12 2003
@@ -45,6 +45,7 @@
 {
 	struct inode *inode =file->f_dentry->d_inode;
 	struct address_space *mapping = inode->i_mapping;
+	loff_t len;
 	int ret;
 
 	if (!capable(CAP_IPC_LOCK))
@@ -65,6 +66,10 @@
 	vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
 	vma->vm_ops = &hugetlb_vm_ops;
 	ret = hugetlb_prefault(mapping, vma);
+	len = (loff_t)(vma->vm_end - vma->vm_start) +
+			((loff_t)vma->vm_pgoff << PAGE_SHIFT);
+	if (ret == 0 && inode->i_size < len)
+		inode->i_size = len;
 	up(&inode->i_sem);
 	return ret;
 }
@@ -211,7 +216,7 @@
 		list_add(&inode->i_list, &inode_unused);
 	}
 	inodes_stat.nr_unused++;
-	if (!super_block | (super_block->s_flags & MS_ACTIVE)) {
+	if (!super_block || (super_block->s_flags & MS_ACTIVE)) {
 		spin_unlock(&inode_lock);
 		return;
 	}
diff -Nru a/fs/jbd/commit.c b/fs/jbd/commit.c
--- a/fs/jbd/commit.c	Fri Feb 14 15:53:12 2003
+++ b/fs/jbd/commit.c	Fri Feb 14 15:53:12 2003
@@ -562,8 +562,7 @@
 	{
 		struct buffer_head *bh = jh2bh(descriptor);
 		set_buffer_uptodate(bh);
-		ll_rw_block(WRITE, 1, &bh);
-		wait_on_buffer(bh);
+		sync_dirty_buffer(bh);
 		__brelse(bh);		/* One for getblk() */
 		journal_unlock_journal_head(descriptor);
 	}
diff -Nru a/fs/jbd/journal.c b/fs/jbd/journal.c
--- a/fs/jbd/journal.c	Fri Feb 14 15:53:09 2003
+++ b/fs/jbd/journal.c	Fri Feb 14 15:53:09 2003
@@ -38,7 +38,6 @@
 #include <linux/proc_fs.h>
 
 EXPORT_SYMBOL(journal_start);
-EXPORT_SYMBOL(journal_try_start);
 EXPORT_SYMBOL(journal_restart);
 EXPORT_SYMBOL(journal_extend);
 EXPORT_SYMBOL(journal_stop);
@@ -203,14 +202,9 @@
 
 	current_journal = journal;
 
-	lock_kernel();
-	daemonize();
-	spin_lock_irq(&current->sighand->siglock);
-	sigfillset(&current->blocked);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	daemonize("kjournald");
 
-	sprintf(current->comm, "kjournald");
+	lock_kernel();
 
 	/* Set up an interval timer which can be used to trigger a
            commit wakeup after the commit interval expires */
@@ -960,9 +954,10 @@
 
 	BUFFER_TRACE(bh, "marking dirty");
 	mark_buffer_dirty(bh);
-	ll_rw_block(WRITE, 1, &bh);
 	if (wait)
-		wait_on_buffer(bh);
+		sync_dirty_buffer(bh);
+	else
+		ll_rw_block(WRITE, 1, &bh);
 
 	/* If we have just flushed the log (by marking s_start==0), then
 	 * any future commit will have to be careful to update the
@@ -1296,8 +1291,7 @@
 	bh = journal->j_sb_buffer;
 	BUFFER_TRACE(bh, "marking dirty");
 	mark_buffer_dirty(bh);
-	ll_rw_block(WRITE, 1, &bh);
-	wait_on_buffer(bh);
+	sync_dirty_buffer(bh);
 	return 0;
 }
 
diff -Nru a/fs/jbd/recovery.c b/fs/jbd/recovery.c
--- a/fs/jbd/recovery.c	Fri Feb 14 15:53:12 2003
+++ b/fs/jbd/recovery.c	Fri Feb 14 15:53:12 2003
@@ -212,16 +212,14 @@
  * 
  * The primary function for recovering the log contents when mounting a
  * journaled device.  
- */
-int journal_recover(journal_t *journal)
-{
-/*
+ *
  * Recovery is done in three passes.  In the first pass, we look for the
  * end of the log.  In the second, we assemble the list of revoke
  * blocks.  In the third and final pass, we replay any un-revoked blocks
  * in the log.  
  */
-
+int journal_recover(journal_t *journal)
+{
 	int			err;
 	journal_superblock_t *	sb;
 
@@ -273,15 +271,13 @@
  * journal structures in memory to ignore it (presumably because the
  * caller has evidence that it is out of date).  
  * This function does'nt appear to be exorted..
- */
-int journal_skip_recovery(journal_t *journal)
-{
-/*
+ *
  * We perform one pass over the journal to allow us to tell the user how
  * much recovery information is being erased, and to let us initialise
  * the journal transaction sequence numbers to the next unused ID. 
  */
-
+int journal_skip_recovery(journal_t *journal)
+{
 	int			err;
 	journal_superblock_t *	sb;
 
diff -Nru a/fs/jbd/transaction.c b/fs/jbd/transaction.c
--- a/fs/jbd/transaction.c	Fri Feb 14 15:53:09 2003
+++ b/fs/jbd/transaction.c	Fri Feb 14 15:53:09 2003
@@ -266,113 +266,6 @@
 	return handle;
 }
 
-/*
- * Return zero on success
- */
-static int try_start_this_handle(journal_t *journal, handle_t *handle)
-{
-	transaction_t *transaction;
-	int needed;
-	int nblocks = handle->h_buffer_credits;
-	int ret = 0;
-
-	jbd_debug(3, "New handle %p maybe going live.\n", handle);
-
-	lock_journal(journal);
-
-	if (is_journal_aborted(journal) ||
-	    (journal->j_errno != 0 && !(journal->j_flags & JFS_ACK_ERR))) {
-		ret = -EROFS;
-		goto fail_unlock;
-	}
-
-	if (journal->j_barrier_count)
-		goto fail_unlock;
-
-	if (!journal->j_running_transaction && get_transaction(journal, 1) == 0)
-		goto fail_unlock;
-	
-	transaction = journal->j_running_transaction;
-	if (transaction->t_state == T_LOCKED)
-		goto fail_unlock;
-	
-	needed = transaction->t_outstanding_credits + nblocks;
-	/* We could run log_start_commit here */
-	if (needed > journal->j_max_transaction_buffers)
-		goto fail_unlock;
-
-	needed = journal->j_max_transaction_buffers;
-	if (journal->j_committing_transaction) 
-		needed += journal->j_committing_transaction->
-						t_outstanding_credits;
-	
-	if (log_space_left(journal) < needed)
-		goto fail_unlock;
-
-	handle->h_transaction = transaction;
-	transaction->t_outstanding_credits += nblocks;
-	transaction->t_updates++;
-	jbd_debug(4, "Handle %p given %d credits (total %d, free %d)\n",
-		  handle, nblocks, transaction->t_outstanding_credits,
-		  log_space_left(journal));
-	unlock_journal(journal);
-	return 0;
-
-fail_unlock:
-	unlock_journal(journal);
-	if (ret >= 0)
-		ret = -1;
-	return ret;
-}
-
-/**
- * handle_t *journal_try_start() - Don't block, but try and get a handle
- * @journal: Journal to start transaction on.
- * @nblocks: number of block buffer we might modify
- * 
- * Try to start a handle, but non-blockingly.  If we weren't able
- * to, return an ERR_PTR value.
- */
-handle_t *journal_try_start(journal_t *journal, int nblocks)
-{
-	handle_t *handle = journal_current_handle();
-	int err;
-	
-	if (!journal)
-		return ERR_PTR(-EROFS);
-
-	if (handle) {
-		jbd_debug(4, "h_ref %d -> %d\n",
-				handle->h_ref,
-				handle->h_ref + 1);
-		J_ASSERT(handle->h_transaction->t_journal == journal);
-		if (is_handle_aborted(handle))
-			return ERR_PTR(-EIO);
-		handle->h_ref++;
-		return handle;
-	} else {
-		jbd_debug(4, "no current transaction\n");
-	}
-	
-	if (is_journal_aborted(journal))
-		return ERR_PTR(-EIO);
-
-	handle = new_handle(nblocks);
-	if (!handle)
-		return ERR_PTR(-ENOMEM);
-
-	current->journal_info = handle;
-
-	err = try_start_this_handle(journal, handle);
-	if (err < 0) {
-		kfree(handle);
-		current->journal_info = NULL;
-		return ERR_PTR(err);
-	}
-
-	return handle;
-}
-
 /**
  * int journal_extend() - extend buffer credits.
  * @handle:  handle to 'extend'
@@ -969,22 +862,23 @@
 }
 
 /** 
- * int journal_dirty_data() -  mark a buffer as containing dirty data which needs to be flushed before we can commit the current transaction.  
+ * int journal_dirty_data() -  mark a buffer as containing dirty data which
+ *                             needs to be flushed before we can commit the
+ *                             current transaction.  
  * @handle: transaction
  * @bh: bufferhead to mark
  * 
  * The buffer is placed on the transaction's data list and is marked as
  * belonging to the transaction.
  *
- * Returns error number or 0 on success.  
- */
-int journal_dirty_data (handle_t *handle, struct buffer_head *bh)
-{
-/*
+ * Returns error number or 0 on success.
+ *
  * journal_dirty_data() can be called via page_launder->ext3_writepage
  * by kswapd.  So it cannot block.  Happily, there's nothing here
  * which needs lock_journal if `async' is set.
  */
+int journal_dirty_data (handle_t *handle, struct buffer_head *bh)
+{
 	journal_t *journal = handle->h_transaction->t_journal;
 	int need_brelse = 0;
 	struct journal_head *jh;
@@ -1079,8 +973,7 @@
 				atomic_inc(&bh->b_count);
 				spin_unlock(&journal_datalist_lock);
 				need_brelse = 1;
-				ll_rw_block(WRITE, 1, &bh);
-				wait_on_buffer(bh);
+				sync_dirty_buffer(bh);
 				spin_lock(&journal_datalist_lock);
 				/* The buffer may become locked again at any
 				   time if it is redirtied */
@@ -1130,23 +1023,22 @@
  * @handle: transaction to add buffer to.
  * @bh: buffer to mark 
  * 
- * mark dirty metadata which needs to be journaled as part of the current transaction.
+ * mark dirty metadata which needs to be journaled as part of the current
+ * transaction.
  *
  * The buffer is placed on the transaction's metadata list and is marked
  * as belonging to the transaction.  
  *
  * Returns error number or 0 on success.  
- */
-int journal_dirty_metadata (handle_t *handle, struct buffer_head *bh)
-{
-/*
+ *
  * Special care needs to be taken if the buffer already belongs to the
  * current committing transaction (in which case we should have frozen
  * data present for that commit).  In that case, we don't relink the
  * buffer: that only gets done when the old transaction finally
  * completes its commit.
- * 
  */
+int journal_dirty_metadata (handle_t *handle, struct buffer_head *bh)
+{
 	transaction_t *transaction = handle->h_transaction;
 	journal_t *journal = transaction->t_journal;
 	struct journal_head *jh = bh2jh(bh);
@@ -1361,8 +1253,7 @@
 		}
 		atomic_inc(&bh->b_count);
 		spin_unlock(&journal_datalist_lock);
-		ll_rw_block (WRITE, 1, &bh);
-		wait_on_buffer(bh);
+		sync_dirty_buffer(bh);
 		__brelse(bh);
 		goto out;
 	}
@@ -1728,13 +1619,6 @@
  * to be called. We do this if the page is releasable by try_to_free_buffers().
  * We also do it if the page has locked or dirty buffers and the caller wants
  * us to perform sync or async writeout.
- */
-int journal_try_to_free_buffers(journal_t *journal, 
-				struct page *page, int unused_gfp_mask)
-{
-/*
- * journal_try_to_free_buffers().  Try to remove all this page's buffers
- * from the journal.
  *
  * This complicates JBD locking somewhat.  We aren't protected by the
  * BKL here.  We wish to remove the buffer from its committing or
@@ -1754,6 +1638,9 @@
  * cannot happen because we never reallocate freed data as metadata
  * while the data is part of a transaction.  Yes?
  */
+int journal_try_to_free_buffers(journal_t *journal, 
+				struct page *page, int unused_gfp_mask)
+{
 	struct buffer_head *head;
 	struct buffer_head *bh;
 	int ret = 0;
diff -Nru a/fs/jffs/intrep.c b/fs/jffs/intrep.c
--- a/fs/jffs/intrep.c	Fri Feb 14 15:53:10 2003
+++ b/fs/jffs/intrep.c	Fri Feb 14 15:53:10 2003
@@ -3378,7 +3378,7 @@
 			unsigned long signr = 0;
 
 			spin_lock_irq(&current->sighand->siglock);
-			signr = dequeue_signal(&current->blocked, &info);
+			signr = dequeue_signal(current, &current->blocked, &info);
 			spin_unlock_irq(&current->sighand->siglock);
 
 			switch(signr) {
diff -Nru a/fs/jffs2/background.c b/fs/jffs2/background.c
--- a/fs/jffs2/background.c	Fri Feb 14 15:53:08 2003
+++ b/fs/jffs2/background.c	Fri Feb 14 15:53:08 2003
@@ -82,13 +82,11 @@
 {
 	struct jffs2_sb_info *c = _c;
 
-	daemonize();
+	daemonize("jffs2_gcd_mtd%d", c->mtd->index);
 
 	c->gc_task = current;
 	up(&c->gc_thread_start);
 
-	sprintf(current->comm, "jffs2_gcd_mtd%d", c->mtd->index);
-
 	set_user_nice(current, 10);
 
 	for (;;) {
@@ -116,7 +114,7 @@
 			unsigned long signr;
 
 			spin_lock_irq(&current_sig_lock);
-			signr = dequeue_signal(&current->blocked, &info);
+			signr = dequeue_signal(current, &current->blocked, &info);
 			spin_unlock_irq(&current_sig_lock);
 
 			switch(signr) {
diff -Nru a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
--- a/fs/jfs/jfs_imap.c	Fri Feb 14 15:53:09 2003
+++ b/fs/jfs/jfs_imap.c	Fri Feb 14 15:53:09 2003
@@ -2980,8 +2980,7 @@
 		j_sb->s_flag |= JFS_BAD_SAIT;
 
 		mark_buffer_dirty(bh);
-		ll_rw_block(WRITE, 1, &bh);
-		wait_on_buffer(bh);
+		sync_dirty_buffer(bh);
 		brelse(bh);
 		return;
 	}
diff -Nru a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
--- a/fs/jfs/jfs_logmgr.c	Fri Feb 14 15:53:10 2003
+++ b/fs/jfs/jfs_logmgr.c	Fri Feb 14 15:53:10 2003
@@ -2132,17 +2132,7 @@
 {
 	struct lbuf *bp;
 
-	lock_kernel();
-
-	daemonize();
-	strcpy(current->comm, "jfsIO");
-
-	unlock_kernel();
-
-	spin_lock_irq(&current->sighand->siglock);
-	sigfillset(&current->blocked);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	daemonize("jfsIO");
 
 	complete(&jfsIOwait);
 
diff -Nru a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c
--- a/fs/jfs/jfs_mount.c	Fri Feb 14 15:53:09 2003
+++ b/fs/jfs/jfs_mount.c	Fri Feb 14 15:53:09 2003
@@ -449,8 +449,7 @@
 	}
 
 	mark_buffer_dirty(bh);
-	ll_rw_block(WRITE, 1, &bh);
-	wait_on_buffer(bh);
+	sync_dirty_buffer(bh);
 	brelse(bh);
 
 	return 0;
diff -Nru a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
--- a/fs/jfs/jfs_txnmgr.c	Fri Feb 14 15:53:11 2003
+++ b/fs/jfs/jfs_txnmgr.c	Fri Feb 14 15:53:11 2003
@@ -2771,20 +2771,10 @@
 	struct tblock *tblk;
 	unsigned long flags;
 
-	lock_kernel();
-
-	daemonize();
-	strcpy(current->comm, "jfsCommit");
-
-	unlock_kernel();
+	daemonize("jfsCommit");
 
 	jfsCommitTask = current;
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigfillset(&current->blocked);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
 	LAZY_LOCK_INIT();
 	TxAnchor.unlock_queue = TxAnchor.unlock_tail = 0;
 
@@ -2978,17 +2968,7 @@
 	int rc;
 	tid_t tid;
 
-	lock_kernel();
-
-	daemonize();
-	strcpy(current->comm, "jfsSync");
-
-	unlock_kernel();
-
-	spin_lock_irq(&current->sighand->siglock);
-	sigfillset(&current->blocked);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	daemonize("jfsSync");
 
 	complete(&jfsIOwait);
 
diff -Nru a/fs/jfs/namei.c b/fs/jfs/namei.c
--- a/fs/jfs/namei.c	Fri Feb 14 15:53:12 2003
+++ b/fs/jfs/namei.c	Fri Feb 14 15:53:12 2003
@@ -972,10 +972,8 @@
 #if 0
 				set_buffer_uptodate(bp);
 				mark_buffer_dirty(bp, 1);
-				if (IS_SYNC(dip)) {
-					ll_rw_block(WRITE, 1, &bp);
-					wait_on_buffer(bp);
-				}
+				if (IS_SYNC(dip))
+					sync_dirty_buffer(bp);
 				brelse(bp);
 #endif				/* 0 */
 				ssize -= copy_size;
diff -Nru a/fs/jfs/resize.c b/fs/jfs/resize.c
--- a/fs/jfs/resize.c	Fri Feb 14 15:53:11 2003
+++ b/fs/jfs/resize.c	Fri Feb 14 15:53:11 2003
@@ -243,8 +243,7 @@
 
 		/* synchronously update superblock */
 		mark_buffer_dirty(bh);
-		ll_rw_block(WRITE, 1, &bh);
-		wait_on_buffer(bh);
+		sync_dirty_buffer(bh);
 		brelse(bh);
 
 		/*
@@ -512,15 +511,13 @@
 		memcpy(j_sb2, j_sb, sizeof (struct jfs_superblock));
 
 		mark_buffer_dirty(bh);
-		ll_rw_block(WRITE, 1, &bh2);
-		wait_on_buffer(bh2);
+		sync_dirty_buffer(bh2);
 		brelse(bh2);
 	}
 
 	/* write primary superblock */
 	mark_buffer_dirty(bh);
-	ll_rw_block(WRITE, 1, &bh);
-	wait_on_buffer(bh);
+	sync_dirty_buffer(bh);
 	brelse(bh);
 
 	goto resume;
diff -Nru a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
--- a/fs/lockd/clntlock.c	Fri Feb 14 15:53:12 2003
+++ b/fs/lockd/clntlock.c	Fri Feb 14 15:53:12 2003
@@ -201,10 +201,8 @@
 	struct file_lock *fl;
 	struct inode *inode;
 
-	daemonize();
-	snprintf(current->comm, sizeof(current->comm),
-		 "%s-reclaim",
-		 host->h_name);
+	daemonize("%s-reclaim", host->h_name);
+	allow_signal(SIGKILL);
 
 	/* This one ensures that our parent doesn't terminate while the
 	 * reclaim is in progress */
diff -Nru a/fs/lockd/svc.c b/fs/lockd/svc.c
--- a/fs/lockd/svc.c	Fri Feb 14 15:53:11 2003
+++ b/fs/lockd/svc.c	Fri Feb 14 15:53:11 2003
@@ -97,14 +97,10 @@
 	nlmsvc_pid = current->pid;
 	up(&lockd_start);
 
-	daemonize();
-	sprintf(current->comm, "lockd");
+	daemonize("lockd");
 
-	/* Process request with signals blocked.  */
-	spin_lock_irq(&current->sighand->siglock);
-	siginitsetinv(&current->blocked, sigmask(SIGKILL));
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	/* Process request with signals blocked, but allow SIGKILL.  */
+	allow_signal(SIGKILL);
 
 	/* kick rpciod */
 	rpciod_up();
@@ -126,9 +122,7 @@
 	{
 		long timeout = MAX_SCHEDULE_TIMEOUT;
 		if (signalled()) {
-			spin_lock_irq(&current->sighand->siglock);
 			flush_signals(current);
-			spin_unlock_irq(&current->sighand->siglock);
 			if (nlmsvc_ops) {
 				nlmsvc_invalidate_all();
 				grace_period_expire = set_grace_period();
diff -Nru a/fs/minix/inode.c b/fs/minix/inode.c
--- a/fs/minix/inode.c	Fri Feb 14 15:53:10 2003
+++ b/fs/minix/inode.c	Fri Feb 14 15:53:10 2003
@@ -517,8 +517,7 @@
 	bh = minix_update_inode(inode);
 	if (bh && buffer_dirty(bh))
 	{
-		ll_rw_block(WRITE, 1, &bh);
-		wait_on_buffer(bh);
+		sync_dirty_buffer(bh);
 		if (buffer_req(bh) && !buffer_uptodate(bh))
 		{
 			printk ("IO error syncing minix inode [%s:%08lx]\n",
diff -Nru a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c
--- a/fs/ncpfs/sock.c	Fri Feb 14 15:53:09 2003
+++ b/fs/ncpfs/sock.c	Fri Feb 14 15:53:09 2003
@@ -757,9 +757,9 @@
 			   What if we've blocked it ourselves?  What about
 			   alarms?  Why, in fact, are we mucking with the
 			   sigmask at all? -- r~ */
-			if (current->sig->action[SIGINT - 1].sa.sa_handler == SIG_DFL)
+			if (current->sighand->action[SIGINT - 1].sa.sa_handler == SIG_DFL)
 				mask |= sigmask(SIGINT);
-			if (current->sig->action[SIGQUIT - 1].sa.sa_handler == SIG_DFL)
+			if (current->sighand->action[SIGQUIT - 1].sa.sa_handler == SIG_DFL)
 				mask |= sigmask(SIGQUIT);
 		}
 		siginitsetinv(&current->blocked, mask);
diff -Nru a/fs/nfs/inode.c b/fs/nfs/inode.c
--- a/fs/nfs/inode.c	Fri Feb 14 15:53:12 2003
+++ b/fs/nfs/inode.c	Fri Feb 14 15:53:12 2003
@@ -93,6 +93,7 @@
 	.nrvers			= sizeof(nfs_version) / sizeof(nfs_version[0]),
 	.version		= nfs_version,
 	.stats			= &nfs_rpcstat,
+	.pipe_dir_name		= "/nfs",
 };
 
 static inline unsigned long
diff -Nru a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
--- a/fs/nfs/nfs3proc.c	Fri Feb 14 15:53:10 2003
+++ b/fs/nfs/nfs3proc.c	Fri Feb 14 15:53:10 2003
@@ -651,7 +651,7 @@
 	default:	return -EINVAL;
 	}
 
-	dprintk("NFS call  mknod %s %x\n", name->name, rdev);
+	dprintk("NFS call  mknod %s %x\n", name->name, (unsigned)rdev);
 	dir_attr.valid = 0;
 	fattr->valid = 0;
 	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
diff -Nru a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
--- a/fs/nfs/nfs3xdr.c	Fri Feb 14 15:53:12 2003
+++ b/fs/nfs/nfs3xdr.c	Fri Feb 14 15:53:12 2003
@@ -146,7 +146,7 @@
 static u32 *
 xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
 {
-	unsigned int	type;
+	unsigned int	type, major, minor;
 	int		fmode;
 
 	type = ntohl(*p++);
@@ -160,9 +160,12 @@
 	fattr->gid = ntohl(*p++);
 	p = xdr_decode_hyper(p, &fattr->size);
 	p = xdr_decode_hyper(p, &fattr->du.nfs3.used);
+
 	/* Turn remote device info into Linux-specific dev_t */
-	fattr->rdev = ntohl(*p++) << MINORBITS;
-	fattr->rdev |= ntohl(*p++) & MINORMASK;
+	major = ntohl(*p++);
+	minor = ntohl(*p++);
+	fattr->rdev = MKDEV(major, minor);
+
 	p = xdr_decode_hyper(p, &fattr->fsid_u.nfs3);
 	p = xdr_decode_hyper(p, &fattr->fileid);
 	p = xdr_decode_time3(p, &fattr->atime);
@@ -412,8 +415,8 @@
 	*p++ = htonl(args->type);
 	p = xdr_encode_sattr(p, args->sattr);
 	if (args->type == NF3CHR || args->type == NF3BLK) {
-		*p++ = htonl(args->rdev >> MINORBITS);
-		*p++ = htonl(args->rdev & MINORMASK);
+		*p++ = htonl(MAJOR(args->rdev));
+		*p++ = htonl(MINOR(args->rdev));
 	}
 
 	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
diff -Nru a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
--- a/fs/nfs/nfs4xdr.c	Fri Feb 14 15:53:12 2003
+++ b/fs/nfs/nfs4xdr.c	Fri Feb 14 15:53:12 2003
@@ -1385,13 +1385,14 @@
                 dprintk("read_attrs: gid=%d\n", (int)nfp->gid);
         }
         if (bmval1 & FATTR4_WORD1_RAWDEV) {
-                READ_BUF(8);
-                len += 8;
-                READ32(dummy32);
-		nfp->rdev = (dummy32 << MINORBITS);
-                READ32(dummy32);
-		nfp->rdev |= (dummy32 & MINORMASK);
-                dprintk("read_attrs: rdev=%d\n", nfp->rdev);
+		uint32_t major, minor;
+
+		READ_BUF(8);
+		len += 8;
+		READ32(major);
+		READ32(minor);
+		nfp->rdev = MKDEV(major, minor);
+		dprintk("read_attrs: rdev=0x%x\n", nfp->rdev);
         }
         if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
                 READ_BUF(8);
diff -Nru a/fs/nfsd/export.c b/fs/nfsd/export.c
--- a/fs/nfsd/export.c	Fri Feb 14 15:53:11 2003
+++ b/fs/nfsd/export.c	Fri Feb 14 15:53:11 2003
@@ -606,7 +606,8 @@
 
 	dprintk("exp_export called for %s:%s (%x/%ld fl %x).\n",
 			nxp->ex_client, nxp->ex_path,
-			nxp->ex_dev, (long) nxp->ex_ino, nxp->ex_flags);
+			(unsigned)nxp->ex_dev, (long)nxp->ex_ino,
+			nxp->ex_flags);
 
 	/* Try to lock the export table for update */
 	exp_writelock();
@@ -760,8 +761,8 @@
 			expkey_put(&key->h, &svc_expkey_cache);
 		} else
 			dprintk("nfsd: no export %x/%lx for %s\n",
-				nxp->ex_dev, (unsigned long) nxp->ex_ino,
-				nxp->ex_client);
+				(unsigned)nxp->ex_dev,
+				(unsigned long) nxp->ex_ino, nxp->ex_client);
 		auth_domain_put(dom);
 		cache_flush();
 	} else
diff -Nru a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
--- a/fs/nfsd/nfssvc.c	Fri Feb 14 15:53:08 2003
+++ b/fs/nfsd/nfssvc.c	Fri Feb 14 15:53:08 2003
@@ -173,8 +173,7 @@
 	/* Lock module and set up kernel thread */
 	MOD_INC_USE_COUNT;
 	lock_kernel();
-	daemonize();
-	sprintf(current->comm, "nfsd");
+	daemonize("nfsd");
 	current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 
 	siginitsetinv(&shutdown_mask, SHUTDOWN_SIGS);
diff -Nru a/fs/ntfs/super.c b/fs/ntfs/super.c
--- a/fs/ntfs/super.c	Fri Feb 14 15:53:12 2003
+++ b/fs/ntfs/super.c	Fri Feb 14 15:53:12 2003
@@ -505,8 +505,7 @@
 			memcpy(bh_primary->b_data, bh_backup->b_data,
 					sb->s_blocksize);
 			mark_buffer_dirty(bh_primary);
-			ll_rw_block(WRITE, 1, &bh_primary);
-			wait_on_buffer(bh_primary);
+			sync_dirty_buffer(bh_primary);
 			if (buffer_uptodate(bh_primary)) {
 				brelse(bh_backup);
 				return bh_primary;
diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c
--- a/fs/partitions/check.c	Fri Feb 14 15:53:12 2003
+++ b/fs/partitions/check.c	Fri Feb 14 15:53:12 2003
@@ -297,7 +297,7 @@
 	struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj);
 	int part = p - disk->part + 1;
 	dev_t base = MKDEV(disk->major, disk->first_minor); 
-	return sprintf(page, "%04x\n",base + part);
+	return sprintf(page, "%04x\n", (unsigned)(base + part));
 }
 static ssize_t part_start_read(struct hd_struct * p, char *page)
 {
diff -Nru a/fs/proc/array.c b/fs/proc/array.c
--- a/fs/proc/array.c	Fri Feb 14 15:53:11 2003
+++ b/fs/proc/array.c	Fri Feb 14 15:53:11 2003
@@ -211,6 +211,9 @@
 	buffer += sprintf(buffer, "SigPnd:\t");
 	buffer = render_sigset_t(&p->pending.signal, buffer);
 	*buffer++ = '\n';
+	buffer += sprintf(buffer, "ShdPnd:\t");
+	buffer = render_sigset_t(&p->signal->shared_pending.signal, buffer);
+	*buffer++ = '\n';
 	buffer += sprintf(buffer, "SigBlk:\t");
 	buffer = render_sigset_t(&p->blocked, buffer);
 	*buffer++ = '\n';
diff -Nru a/fs/proc/generic.c b/fs/proc/generic.c
--- a/fs/proc/generic.c	Fri Feb 14 15:53:12 2003
+++ b/fs/proc/generic.c	Fri Feb 14 15:53:12 2003
@@ -65,43 +65,108 @@
 
 		start = NULL;
 		if (dp->get_info) {
-			/*
-			 * Handle backwards compatibility with the old net
-			 * routines.
-			 */
+			/* Handle old net routines */
 			n = dp->get_info(page, &start, *ppos, count);
 			if (n < count)
 				eof = 1;
 		} else if (dp->read_proc) {
+			/*
+			 * How to be a proc read function
+			 * ------------------------------
+			 * Prototype:
+			 *    int f(char *buffer, char **start, off_t offset,
+			 *          int count, int *peof, void *dat)
+			 *
+			 * Assume that the buffer is "count" bytes in size.
+			 *
+			 * If you know you have supplied all the data you
+			 * have, set *peof.
+			 *
+			 * You have three ways to return data:
+			 * 0) Leave *start = NULL.  (This is the default.)
+			 *    Put the data of the requested offset at that
+			 *    offset within the buffer.  Return the number (n)
+			 *    of bytes there are from the beginning of the
+			 *    buffer up to the last byte of data.  If the
+			 *    number of supplied bytes (= n - offset) is 
+			 *    greater than zero and you didn't signal eof
+			 *    and the reader is prepared to take more data
+			 *    you will be called again with the requested
+			 *    offset advanced by the number of bytes 
+			 *    absorbed.  This interface is useful for files
+			 *    no larger than the buffer.
+			 * 1) Set *start = an unsigned long value less than
+			 *    the buffer address but greater than zero.
+			 *    Put the data of the requested offset at the
+			 *    beginning of the buffer.  Return the number of
+			 *    bytes of data placed there.  If this number is
+			 *    greater than zero and you didn't signal eof
+			 *    and the reader is prepared to take more data
+			 *    you will be called again with the requested
+			 *    offset advanced by *start.  This interface is
+			 *    useful when you have a large file consisting
+			 *    of a series of blocks which you want to count
+			 *    and return as wholes.
+			 *    (Hack by Paul.Russell@rustcorp.com.au)
+			 * 2) Set *start = an address within the buffer.
+			 *    Put the data of the requested offset at *start.
+			 *    Return the number of bytes of data placed there.
+			 *    If this number is greater than zero and you
+			 *    didn't signal eof and the reader is prepared to
+			 *    take more data you will be called again with the
+			 *    requested offset advanced by the number of bytes
+			 *    absorbed.
+			 */
 			n = dp->read_proc(page, &start, *ppos,
 					  count, &eof, dp->data);
 		} else
 			break;
 
-		if (!start) {
-			/*
-			 * For proc files that are less than 4k
-			 */
-			start = page + *ppos;
+		if (n == 0)   /* end of file */
+			break;
+		if (n < 0) {  /* error */
+			if (retval == 0)
+				retval = n;
+			break;
+		}
+
+		if (start == NULL) {
+			if (n > PAGE_SIZE) {
+				printk(KERN_ERR
+				       "proc_file_read: Apparent buffer overflow!\n");
+				n = PAGE_SIZE;
+			}
+			if (n > count)
+				n = count;
 			n -= *ppos;
 			if (n <= 0)
 				break;
+			start = page + *ppos;
+		} else if (start < page) {
+			if (n > PAGE_SIZE) {
+				printk(KERN_ERR
+				       "proc_file_read: Apparent buffer overflow!\n");
+				n = PAGE_SIZE;
+			}
+			if (n > count) {
+				/*
+				 * Don't reduce n because doing so might
+				 * cut off part of a data block.
+				 */
+				printk(KERN_WARNING
+				       "proc_file_read: Read count exceeded\n");
+			}
+		} else /* start >= page */ {
+			unsigned long startoff = (unsigned long)(start - page);
+			if (n > (PAGE_SIZE - startoff)) {
+				printk(KERN_ERR
+				       "proc_file_read: Apparent buffer overflow!\n");
+				n = PAGE_SIZE - startoff;
+			}
 			if (n > count)
 				n = count;
 		}
-		if (n == 0)
-			break;	/* End of file */
-		if (n < 0) {
-			if (retval == 0)
-				retval = n;
-			break;
-		}
 		
-		/* This is a hack to allow mangling of file pos independent
- 		 * of actual bytes read.  Simply place the data at page,
- 		 * return the bytes, and set `start' to the desired offset
- 		 * as an unsigned int. - Paul.Russell@rustcorp.com.au
-		 */
  		n -= copy_to_user(buf, start < page ? page : start, n);
 		if (n == 0) {
 			if (retval == 0)
@@ -109,7 +174,7 @@
 			break;
 		}
 
-		*ppos += start < page ? (long)start : n; /* Move down the file */
+		*ppos += start < page ? (unsigned long)start : n;
 		nbytes -= n;
 		buf += n;
 		retval += n;
diff -Nru a/fs/qnx4/inode.c b/fs/qnx4/inode.c
--- a/fs/qnx4/inode.c	Fri Feb 14 15:53:12 2003
+++ b/fs/qnx4/inode.c	Fri Feb 14 15:53:12 2003
@@ -44,8 +44,7 @@
    	bh = qnx4_update_inode(inode);
 	if (bh && buffer_dirty(bh))
 	{
-		ll_rw_block(WRITE, 1, &bh);
-		wait_on_buffer(bh);
+		sync_dirty_buffer(bh);
 		if (buffer_req(bh) && !buffer_uptodate(bh))
 		{
 			printk ("IO error syncing qnx4 inode [%s:%08lx]\n",
diff -Nru a/fs/reiserfs/hashes.c b/fs/reiserfs/hashes.c
--- a/fs/reiserfs/hashes.c	Fri Feb 14 15:53:12 2003
+++ b/fs/reiserfs/hashes.c	Fri Feb 14 15:53:12 2003
@@ -18,6 +18,7 @@
 // r5_hash
 //
 
+#include <linux/kernel.h>
 #include <asm/types.h>
 #include <asm/bug.h>
 
diff -Nru a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
--- a/fs/reiserfs/journal.c	Fri Feb 14 15:53:11 2003
+++ b/fs/reiserfs/journal.c	Fri Feb 14 15:53:11 2003
@@ -735,8 +735,7 @@
   }
 
   mark_buffer_dirty(jl->j_commit_bh) ;
-  ll_rw_block(WRITE, 1, &(jl->j_commit_bh)) ;
-  wait_on_buffer(jl->j_commit_bh) ;
+  sync_dirty_buffer(jl->j_commit_bh) ;
   if (!buffer_uptodate(jl->j_commit_bh)) {
     reiserfs_panic(s, "journal-615: buffer write failed\n") ;
   }
@@ -828,8 +827,7 @@
     jh->j_first_unflushed_offset = cpu_to_le32(offset) ;
     jh->j_mount_id = cpu_to_le32(SB_JOURNAL(p_s_sb)->j_mount_id) ;
     set_buffer_dirty(SB_JOURNAL(p_s_sb)->j_header_bh) ;
-    ll_rw_block(WRITE, 1, &(SB_JOURNAL(p_s_sb)->j_header_bh)) ;
-    wait_on_buffer((SB_JOURNAL(p_s_sb)->j_header_bh)) ; 
+    sync_dirty_buffer(SB_JOURNAL(p_s_sb)->j_header_bh) ;
     if (!buffer_uptodate(SB_JOURNAL(p_s_sb)->j_header_bh)) {
       printk( "reiserfs: journal-837: IO error during journal replay\n" );
       return -EIO ;
diff -Nru a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
--- a/fs/reiserfs/resize.c	Fri Feb 14 15:53:09 2003
+++ b/fs/reiserfs/resize.c	Fri Feb 14 15:53:09 2003
@@ -118,10 +118,9 @@
 		memset(bitmap[i].bh->b_data, 0, sb_blocksize(sb));
 		reiserfs_test_and_set_le_bit(0, bitmap[i].bh->b_data);
 
-		mark_buffer_dirty(bitmap[i].bh) ;
 		set_buffer_uptodate(bitmap[i].bh);
-		ll_rw_block(WRITE, 1, &bitmap[i].bh);
-		wait_on_buffer(bitmap[i].bh);
+		mark_buffer_dirty(bitmap[i].bh) ;
+		sync_dirty_buffer(bitmap[i].bh);
 		// update bitmap_info stuff
 		bitmap[i].first_zero_hint=1;
 		bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
diff -Nru a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c
--- a/fs/smbfs/smbiod.c	Fri Feb 14 15:53:11 2003
+++ b/fs/smbfs/smbiod.c	Fri Feb 14 15:53:11 2003
@@ -283,14 +283,9 @@
 static int smbiod(void *unused)
 {
 	MOD_INC_USE_COUNT;
-	daemonize();
+	daemonize("smbiod");
 
-	spin_lock_irq(&current->sighand->siglock);
-	siginitsetinv(&current->blocked, sigmask(SIGKILL));
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	strcpy(current->comm, "smbiod");
+	allow_signal(SIGKILL);
 
 	VERBOSE("SMB Kernel thread starting (%d) ...\n", current->pid);
 
diff -Nru a/fs/sysfs/inode.c b/fs/sysfs/inode.c
--- a/fs/sysfs/inode.c	Fri Feb 14 15:53:12 2003
+++ b/fs/sysfs/inode.c	Fri Feb 14 15:53:12 2003
@@ -210,7 +210,7 @@
 	struct kobject * kobj = file->f_dentry->d_parent->d_fsdata;
 	struct sysfs_ops * ops = buffer->ops;
 	int ret = 0;
-	size_t count;
+	ssize_t count;
 
 	if (!buffer->page)
 		buffer->page = (char *) __get_free_page(GFP_KERNEL);
diff -Nru a/fs/sysv/inode.c b/fs/sysv/inode.c
--- a/fs/sysv/inode.c	Fri Feb 14 15:53:08 2003
+++ b/fs/sysv/inode.c	Fri Feb 14 15:53:08 2003
@@ -265,8 +265,7 @@
 
         bh = sysv_update_inode(inode);
         if (bh && buffer_dirty(bh)) {
-                ll_rw_block(WRITE, 1, &bh);
-                wait_on_buffer(bh);
+                sync_dirty_buffer(bh);
                 if (buffer_req(bh) && !buffer_uptodate(bh)) {
                         printk ("IO error syncing sysv inode [%s:%08lx]\n",
                                 inode->i_sb->s_id, inode->i_ino);
diff -Nru a/fs/sysv/itree.c b/fs/sysv/itree.c
--- a/fs/sysv/itree.c	Fri Feb 14 15:53:09 2003
+++ b/fs/sysv/itree.c	Fri Feb 14 15:53:09 2003
@@ -15,10 +15,8 @@
 static inline void dirty_indirect(struct buffer_head *bh, struct inode *inode)
 {
 	mark_buffer_dirty_inode(bh, inode);
-	if (IS_SYNC(inode)) {
-		ll_rw_block (WRITE, 1, &bh);
-		wait_on_buffer (bh);
-	}
+	if (IS_SYNC(inode))
+		sync_dirty_buffer(bh);
 }
 
 static int block_to_path(struct inode *inode, long block, int offsets[DEPTH])
diff -Nru a/fs/udf/inode.c b/fs/udf/inode.c
--- a/fs/udf/inode.c	Fri Feb 14 15:53:12 2003
+++ b/fs/udf/inode.c	Fri Feb 14 15:53:12 2003
@@ -1520,8 +1520,7 @@
 	mark_buffer_dirty(bh);
 	if (do_sync)
 	{
-		ll_rw_block(WRITE, 1, &bh);
-		wait_on_buffer(bh);
+		sync_dirty_buffer(bh);
 		if (buffer_req(bh) && !buffer_uptodate(bh))
 		{
 			printk("IO error syncing udf inode [%s:%08lx]\n",
diff -Nru a/fs/ufs/balloc.c b/fs/ufs/balloc.c
--- a/fs/ufs/balloc.c	Fri Feb 14 15:53:11 2003
+++ b/fs/ufs/balloc.c	Fri Feb 14 15:53:11 2003
@@ -114,6 +114,7 @@
 	ubh_mark_buffer_dirty (USPI_UBH);
 	ubh_mark_buffer_dirty (UCPI_UBH);
 	if (sb->s_flags & MS_SYNCHRONOUS) {
+		ubh_wait_on_buffer (UCPI_UBH);
 		ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **)&ucpi);
 		ubh_wait_on_buffer (UCPI_UBH);
 	}
@@ -199,6 +200,7 @@
 	ubh_mark_buffer_dirty (USPI_UBH);
 	ubh_mark_buffer_dirty (UCPI_UBH);
 	if (sb->s_flags & MS_SYNCHRONOUS) {
+		ubh_wait_on_buffer (UCPI_UBH);
 		ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **)&ucpi);
 		ubh_wait_on_buffer (UCPI_UBH);
 	}
@@ -228,10 +230,8 @@
 		memset (bh->b_data, 0, sb->s_blocksize); \
 		set_buffer_uptodate(bh); \
 		mark_buffer_dirty (bh); \
-		if (IS_SYNC(inode)) { \
-			ll_rw_block (WRITE, 1, &bh); \
-			wait_on_buffer (bh); \
-		} \
+		if (IS_SYNC(inode)) \
+			sync_dirty_buffer(bh); \
 		brelse (bh); \
 	}
 
@@ -364,10 +364,8 @@
 				clear_buffer_dirty(bh);
 				bh->b_blocknr = result + i;
 				mark_buffer_dirty (bh);
-				if (IS_SYNC(inode)) {
-					ll_rw_block (WRITE, 1, &bh);
-					wait_on_buffer (bh);
-				}
+				if (IS_SYNC(inode))
+					sync_dirty_buffer(bh);
 				brelse (bh);
 			}
 			else
@@ -459,6 +457,7 @@
 	ubh_mark_buffer_dirty (USPI_UBH);
 	ubh_mark_buffer_dirty (UCPI_UBH);
 	if (sb->s_flags & MS_SYNCHRONOUS) {
+		ubh_wait_on_buffer (UCPI_UBH);
 		ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **)&ucpi);
 		ubh_wait_on_buffer (UCPI_UBH);
 	}
@@ -584,6 +583,7 @@
 	ubh_mark_buffer_dirty (USPI_UBH);
 	ubh_mark_buffer_dirty (UCPI_UBH);
 	if (sb->s_flags & MS_SYNCHRONOUS) {
+		ubh_wait_on_buffer (UCPI_UBH);
 		ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **)&ucpi);
 		ubh_wait_on_buffer (UCPI_UBH);
 	}
diff -Nru a/fs/ufs/dir.c b/fs/ufs/dir.c
--- a/fs/ufs/dir.c	Fri Feb 14 15:53:12 2003
+++ b/fs/ufs/dir.c	Fri Feb 14 15:53:12 2003
@@ -356,10 +356,8 @@
 	dir->i_version++;
 	de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino);
 	mark_buffer_dirty(bh);
-	if (IS_DIRSYNC(dir)) {
-		ll_rw_block (WRITE, 1, &bh);
-		wait_on_buffer(bh);
-	}
+	if (IS_DIRSYNC(dir))
+		sync_dirty_buffer(bh);
 	brelse (bh);
 }
 
@@ -457,10 +455,8 @@
 	de->d_ino = cpu_to_fs32(sb, inode->i_ino);
 	ufs_set_de_type(sb, de, inode->i_mode);
 	mark_buffer_dirty(bh);
-	if (IS_DIRSYNC(dir)) {
-		ll_rw_block (WRITE, 1, &bh);
-		wait_on_buffer (bh);
-	}
+	if (IS_DIRSYNC(dir))
+		sync_dirty_buffer(bh);
 	brelse (bh);
 	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
 	dir->i_version++;
@@ -508,10 +504,8 @@
 			inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 			mark_inode_dirty(inode);
 			mark_buffer_dirty(bh);
-			if (IS_DIRSYNC(inode)) {
-				ll_rw_block(WRITE, 1, &bh);
-				wait_on_buffer(bh);
-			}
+			if (IS_DIRSYNC(inode))
+				sync_dirty_buffer(bh);
 			brelse(bh);
 			UFSD(("EXIT\n"))
 			return 0;
diff -Nru a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c
--- a/fs/ufs/ialloc.c	Fri Feb 14 15:53:12 2003
+++ b/fs/ufs/ialloc.c	Fri Feb 14 15:53:12 2003
@@ -124,6 +124,7 @@
 	ubh_mark_buffer_dirty (USPI_UBH);
 	ubh_mark_buffer_dirty (UCPI_UBH);
 	if (sb->s_flags & MS_SYNCHRONOUS) {
+		ubh_wait_on_buffer (UCPI_UBH);
 		ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **) &ucpi);
 		ubh_wait_on_buffer (UCPI_UBH);
 	}
@@ -248,6 +249,7 @@
 	ubh_mark_buffer_dirty (USPI_UBH);
 	ubh_mark_buffer_dirty (UCPI_UBH);
 	if (sb->s_flags & MS_SYNCHRONOUS) {
+		ubh_wait_on_buffer (UCPI_UBH);
 		ubh_ll_rw_block (WRITE, 1, (struct ufs_buffer_head **) &ucpi);
 		ubh_wait_on_buffer (UCPI_UBH);
 	}
diff -Nru a/fs/ufs/inode.c b/fs/ufs/inode.c
--- a/fs/ufs/inode.c	Fri Feb 14 15:53:09 2003
+++ b/fs/ufs/inode.c	Fri Feb 14 15:53:09 2003
@@ -298,10 +298,8 @@
 	}
 
 	mark_buffer_dirty(bh);
-	if (IS_SYNC(inode)) {
-		ll_rw_block (WRITE, 1, &bh);
-		wait_on_buffer (bh);
-	}
+	if (IS_SYNC(inode))
+		sync_dirty_buffer(bh);
 	inode->i_ctime = CURRENT_TIME;
 	mark_inode_dirty(inode);
 out:
@@ -635,10 +633,8 @@
 		memset (ufs_inode, 0, sizeof(struct ufs_inode));
 		
 	mark_buffer_dirty(bh);
-	if (do_sync) {
-		ll_rw_block (WRITE, 1, &bh);
-		wait_on_buffer (bh);
-	}
+	if (do_sync)
+		sync_dirty_buffer(bh);
 	brelse (bh);
 	
 	UFSD(("EXIT\n"))
diff -Nru a/fs/ufs/truncate.c b/fs/ufs/truncate.c
--- a/fs/ufs/truncate.c	Fri Feb 14 15:53:10 2003
+++ b/fs/ufs/truncate.c	Fri Feb 14 15:53:10 2003
@@ -284,6 +284,7 @@
 		}
 	}
 	if (IS_SYNC(inode) && ind_ubh && ubh_buffer_dirty(ind_ubh)) {
+		ubh_wait_on_buffer (ind_ubh);
 		ubh_ll_rw_block (WRITE, 1, &ind_ubh);
 		ubh_wait_on_buffer (ind_ubh);
 	}
@@ -351,6 +352,7 @@
 		}
 	}
 	if (IS_SYNC(inode) && dind_bh && ubh_buffer_dirty(dind_bh)) {
+		ubh_wait_on_buffer (dind_bh);
 		ubh_ll_rw_block (WRITE, 1, &dind_bh);
 		ubh_wait_on_buffer (dind_bh);
 	}
@@ -415,6 +417,7 @@
 		}
 	}
 	if (IS_SYNC(inode) && tind_bh && ubh_buffer_dirty(tind_bh)) {
+		ubh_wait_on_buffer (tind_bh);
 		ubh_ll_rw_block (WRITE, 1, &tind_bh);
 		ubh_wait_on_buffer (tind_bh);
 	}
diff -Nru a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c
--- a/fs/xfs/pagebuf/page_buf.c	Fri Feb 14 15:53:08 2003
+++ b/fs/xfs/pagebuf/page_buf.c	Fri Feb 14 15:53:08 2003
@@ -1578,15 +1578,8 @@
 		TIMER_INITIALIZER((timeout_fn)pagebuf_daemon_wakeup, 0, 0);
 
 	/*  Set up the thread  */
-	daemonize();
+	daemonize("pagebufd");
 
-	/* Avoid signals */
-	spin_lock_irq(&current->sighand->siglock);
-	sigfillset(&current->blocked);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	strcpy(current->comm, "pagebufd");
 	current->flags |= PF_MEMALLOC;
 
 	INIT_LIST_HEAD(&tmp);
diff -Nru a/include/acpi/acpi.h b/include/acpi/acpi.h
--- a/include/acpi/acpi.h	Fri Feb 14 15:53:10 2003
+++ b/include/acpi/acpi.h	Fri Feb 14 15:53:10 2003
@@ -30,21 +30,21 @@
  * We put them here because we don't want to duplicate them
  * in the rest of the source code again and again.
  */
-#include "acconfig.h"           /* Configuration constants */
-#include "platform/acenv.h"     /* Target environment specific items */
-#include "actypes.h"            /* Fundamental common data types */
-#include "acexcep.h"            /* ACPI exception codes */
-#include "acmacros.h"           /* C macros */
-#include "actbl.h"              /* ACPI table definitions */
-#include "aclocal.h"            /* Internal data types */
-#include "acoutput.h"           /* Error output and Debug macros */
-#include "acpiosxf.h"           /* Interfaces to the ACPI-to-OS layer*/
-#include "acpixf.h"             /* ACPI core subsystem external interfaces */
-#include "acobject.h"           /* ACPI internal object */
-#include "acstruct.h"           /* Common structures */
-#include "acglobal.h"           /* All global variables */
-#include "achware.h"            /* Hardware defines and interfaces */
-#include "acutils.h"            /* Utility interfaces */
+#include <acpi/acconfig.h>           /* Configuration constants */
+#include <acpi/platform/acenv.h>     /* Target environment specific items */
+#include <acpi/actypes.h>            /* Fundamental common data types */
+#include <acpi/acexcep.h>            /* ACPI exception codes */
+#include <acpi/acmacros.h>           /* C macros */
+#include <acpi/actbl.h>              /* ACPI table definitions */
+#include <acpi/aclocal.h>            /* Internal data types */
+#include <acpi/acoutput.h>           /* Error output and Debug macros */
+#include <acpi/acpiosxf.h>           /* Interfaces to the ACPI-to-OS layer*/
+#include <acpi/acpixf.h>             /* ACPI core subsystem external interfaces */
+#include <acpi/acobject.h>           /* ACPI internal object */
+#include <acpi/acstruct.h>           /* Common structures */
+#include <acpi/acglobal.h>           /* All global variables */
+#include <acpi/achware.h>            /* Hardware defines and interfaces */
+#include <acpi/acutils.h>            /* Utility interfaces */
 
 
 #endif /* __ACPI_H__ */
diff -Nru a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
--- a/include/acpi/acpi_drivers.h	Fri Feb 14 15:53:12 2003
+++ b/include/acpi/acpi_drivers.h	Fri Feb 14 15:53:12 2003
@@ -27,7 +27,7 @@
 #define __ACPI_DRIVERS_H__
 
 #include <linux/acpi.h>
-#include "acpi_bus.h"
+#include <acpi/acpi_bus.h>
 
 
 #define ACPI_MAX_STRING			80
diff -Nru a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
--- a/include/acpi/acpiosxf.h	Fri Feb 14 15:53:08 2003
+++ b/include/acpi/acpiosxf.h	Fri Feb 14 15:53:08 2003
@@ -29,8 +29,8 @@
 #ifndef __ACPIOSXF_H__
 #define __ACPIOSXF_H__
 
-#include "platform/acenv.h"
-#include "actypes.h"
+#include <acpi/platform/acenv.h>
+#include <acpi/actypes.h>
 
 
 /* Priorities for acpi_os_queue_for_execution */
diff -Nru a/include/acpi/acpixf.h b/include/acpi/acpixf.h
--- a/include/acpi/acpixf.h	Fri Feb 14 15:53:08 2003
+++ b/include/acpi/acpixf.h	Fri Feb 14 15:53:08 2003
@@ -27,8 +27,8 @@
 #ifndef __ACXFACE_H__
 #define __ACXFACE_H__
 
-#include "actypes.h"
-#include "actbl.h"
+#include <acpi/actypes.h>
+#include <acpi/actbl.h>
 
 
  /*
diff -Nru a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
--- a/include/acpi/platform/acenv.h	Fri Feb 14 15:53:09 2003
+++ b/include/acpi/platform/acenv.h	Fri Feb 14 15:53:09 2003
@@ -97,8 +97,8 @@
 
 /*! [Begin] no source code translation */
 
-#if defined(_LINUX)
-#include "aclinux.h"
+#if defined(__linux__)
+#include <acpi/platform/aclinux.h>
 
 #elif defined(_AED_EFI)
 #include "acefi.h"
diff -Nru a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
--- a/include/acpi/platform/aclinux.h	Fri Feb 14 15:53:12 2003
+++ b/include/acpi/platform/aclinux.h	Fri Feb 14 15:53:12 2003
@@ -28,6 +28,7 @@
 #define ACPI_OS_NAME                "Linux"
 
 #define ACPI_USE_SYSTEM_CLIBRARY
+#define ACPI_USE_DO_WHILE_0
 
 #ifdef __KERNEL__
 
diff -Nru a/include/asm-alpha/signal.h b/include/asm-alpha/signal.h
--- a/include/asm-alpha/signal.h	Fri Feb 14 15:53:10 2003
+++ b/include/asm-alpha/signal.h	Fri Feb 14 15:53:10 2003
@@ -186,6 +186,7 @@
 #ifdef __KERNEL__
 #include <asm/sigcontext.h>
 
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
 #define HAVE_ARCH_SYS_PAUSE
 
 #endif
diff -Nru a/include/asm-cris/signal.h b/include/asm-cris/signal.h
--- a/include/asm-cris/signal.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-cris/signal.h	Fri Feb 14 15:53:12 2003
@@ -181,6 +181,7 @@
 /* here we could define asm-optimized sigaddset, sigdelset etc. operations. 
  * if we don't, generic ones are used from linux/signal.h
  */
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-i386/fixmap.h b/include/asm-i386/fixmap.h
--- a/include/asm-i386/fixmap.h	Fri Feb 14 15:53:08 2003
+++ b/include/asm-i386/fixmap.h	Fri Feb 14 15:53:08 2003
@@ -60,7 +60,7 @@
 #ifdef CONFIG_X86_F00F_BUG
 	FIX_F00F_IDT,	/* Virtual mapping for IDT */
 #endif
-#ifdef CONFIG_X86_CYCLONE
+#ifdef CONFIG_X86_SUMMIT
 	FIX_CYCLONE_TIMER, /*cyclone timer register*/
 #endif 
 #ifdef CONFIG_HIGHMEM
diff -Nru a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h
--- a/include/asm-i386/mach-summit/mach_apic.h	Fri Feb 14 15:53:11 2003
+++ b/include/asm-i386/mach-summit/mach_apic.h	Fri Feb 14 15:53:11 2003
@@ -3,7 +3,7 @@
 
 extern int x86_summit;
 
-#define esr_disable (1)
+#define esr_disable (x86_summit ? 1 : 0)
 #define no_balance_irq (0)
 
 #define XAPIC_DEST_CPUS_MASK    0x0Fu
@@ -15,14 +15,14 @@
 #define APIC_DFR_VALUE	(x86_summit ? APIC_DFR_CLUSTER : APIC_DFR_FLAT)
 #define TARGET_CPUS	(x86_summit ? XAPIC_DEST_CPUS_MASK : cpu_online_map)
 
-#define INT_DELIVERY_MODE dest_Fixed
+#define INT_DELIVERY_MODE (x86_summit ? dest_Fixed : dest_LowestPrio)
 #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
 
 #define APIC_BROADCAST_ID     (x86_summit ? 0xFF : 0x0F)
-#define check_apicid_used(bitmap, apicid) (0)
+#define check_apicid_used(bitmap, apicid) (x86_summit ? 0 : (bitmap & (1 << apicid)))
 
 /* we don't use the phys_cpu_present_map to indicate apicid presence */
-#define check_apicid_present(bit) (1) 
+#define check_apicid_present(bit) (x86_summit ? 1 : (phys_cpu_present_map & (1 << bit))) 
 
 extern u8 bios_cpu_apicid[];
 
@@ -106,7 +106,10 @@
 
 static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
 {
-	return (1);
+	if (x86_summit)
+		return (1);
+	else
+		return test_bit(boot_cpu_physical_apicid, &phys_cpu_present_map);
 }
 
 #endif /* __ASM_MACH_APIC_H */
diff -Nru a/include/asm-i386/mach-summit/mach_mpparse.h b/include/asm-i386/mach-summit/mach_mpparse.h
--- a/include/asm-i386/mach-summit/mach_mpparse.h	Fri Feb 14 15:53:09 2003
+++ b/include/asm-i386/mach-summit/mach_mpparse.h	Fri Feb 14 15:53:09 2003
@@ -1,6 +1,8 @@
 #ifndef __ASM_MACH_MPPARSE_H
 #define __ASM_MACH_MPPARSE_H
 
+extern int use_cyclone;
+
 static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, 
 				struct mpc_config_translation *translation)
 {
@@ -17,14 +19,18 @@
 {
 	if (!strncmp(oem, "IBM ENSW", 8) && 
 			(!strncmp(productid, "VIGIL SMP", 9) 
-			 || !strncmp(productid, "RUTHLESS SMP", 12)))
+			 || !strncmp(productid, "RUTHLESS SMP", 12))){
 		x86_summit = 1;
+		use_cyclone = 1; /*enable cyclone-timer*/
+	}
 }
 
 /* Hook from generic ACPI tables.c */
 static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
-	if (!strncmp(oem_id, "IBM", 3) && !strncmp(oem_table_id, "SERVIGIL", 8))
+	if (!strncmp(oem_id, "IBM", 3) && !strncmp(oem_table_id, "SERVIGIL", 8)){
 		x86_summit = 1;
+		use_cyclone = 1; /*enable cyclone-timer*/
+	}
 }
 #endif /* __ASM_MACH_MPPARSE_H */
diff -Nru a/include/asm-i386/module.h b/include/asm-i386/module.h
--- a/include/asm-i386/module.h	Fri Feb 14 15:53:09 2003
+++ b/include/asm-i386/module.h	Fri Feb 14 15:53:09 2003
@@ -46,6 +46,8 @@
 #define MODULE_PROC_FAMILY "WINCHIP3D "
 #elif CONFIG_MCYRIXIII
 #define MODULE_PROC_FAMILY "CYRIXIII "
+#elif CONFIG_MVIAC3_2
+#define MODULE_PROC_FAMILY "VIAC3-2 "
 #else
 #error unknown processor family
 #endif
diff -Nru a/include/asm-i386/msr.h b/include/asm-i386/msr.h
--- a/include/asm-i386/msr.h	Fri Feb 14 15:53:08 2003
+++ b/include/asm-i386/msr.h	Fri Feb 14 15:53:08 2003
@@ -93,6 +93,90 @@
 #define MSR_IA32_MC0_ADDR		0x402
 #define MSR_IA32_MC0_MISC		0x403
 
+/* Pentium IV performance counter MSRs */
+#define MSR_P4_BPU_PERFCTR0 		0x300
+#define MSR_P4_BPU_PERFCTR1 		0x301
+#define MSR_P4_BPU_PERFCTR2 		0x302
+#define MSR_P4_BPU_PERFCTR3 		0x303
+#define MSR_P4_MS_PERFCTR0 		0x304
+#define MSR_P4_MS_PERFCTR1 		0x305
+#define MSR_P4_MS_PERFCTR2 		0x306
+#define MSR_P4_MS_PERFCTR3 		0x307
+#define MSR_P4_FLAME_PERFCTR0 		0x308
+#define MSR_P4_FLAME_PERFCTR1 		0x309
+#define MSR_P4_FLAME_PERFCTR2 		0x30a
+#define MSR_P4_FLAME_PERFCTR3 		0x30b
+#define MSR_P4_IQ_PERFCTR0 		0x30c
+#define MSR_P4_IQ_PERFCTR1 		0x30d
+#define MSR_P4_IQ_PERFCTR2 		0x30e
+#define MSR_P4_IQ_PERFCTR3 		0x30f
+#define MSR_P4_IQ_PERFCTR4 		0x310
+#define MSR_P4_IQ_PERFCTR5 		0x311
+#define MSR_P4_BPU_CCCR0 		0x360
+#define MSR_P4_BPU_CCCR1 		0x361
+#define MSR_P4_BPU_CCCR2 		0x362
+#define MSR_P4_BPU_CCCR3 		0x363
+#define MSR_P4_MS_CCCR0 		0x364
+#define MSR_P4_MS_CCCR1 		0x365
+#define MSR_P4_MS_CCCR2 		0x366
+#define MSR_P4_MS_CCCR3 		0x367
+#define MSR_P4_FLAME_CCCR0 		0x368
+#define MSR_P4_FLAME_CCCR1 		0x369
+#define MSR_P4_FLAME_CCCR2 		0x36a
+#define MSR_P4_FLAME_CCCR3 		0x36b
+#define MSR_P4_IQ_CCCR0 		0x36c
+#define MSR_P4_IQ_CCCR1 		0x36d
+#define MSR_P4_IQ_CCCR2 		0x36e
+#define MSR_P4_IQ_CCCR3 		0x36f
+#define MSR_P4_IQ_CCCR4 		0x370
+#define MSR_P4_IQ_CCCR5 		0x371
+#define MSR_P4_ALF_ESCR0 		0x3ca
+#define MSR_P4_ALF_ESCR1 		0x3cb
+#define MSR_P4_BPU_ESCR0 		0x3b2
+#define MSR_P4_BPU_ESCR1 		0x3b3
+#define MSR_P4_BSU_ESCR0 		0x3a0
+#define MSR_P4_BSU_ESCR1 		0x3a1
+#define MSR_P4_CRU_ESCR0 		0x3b8
+#define MSR_P4_CRU_ESCR1 		0x3b9
+#define MSR_P4_CRU_ESCR2 		0x3cc
+#define MSR_P4_CRU_ESCR3 		0x3cd
+#define MSR_P4_CRU_ESCR4 		0x3e0
+#define MSR_P4_CRU_ESCR5 		0x3e1
+#define MSR_P4_DAC_ESCR0 		0x3a8
+#define MSR_P4_DAC_ESCR1 		0x3a9
+#define MSR_P4_FIRM_ESCR0 		0x3a4
+#define MSR_P4_FIRM_ESCR1 		0x3a5
+#define MSR_P4_FLAME_ESCR0 		0x3a6
+#define MSR_P4_FLAME_ESCR1 		0x3a7
+#define MSR_P4_FSB_ESCR0 		0x3a2
+#define MSR_P4_FSB_ESCR1 		0x3a3
+#define MSR_P4_IQ_ESCR0 		0x3ba
+#define MSR_P4_IQ_ESCR1 		0x3bb
+#define MSR_P4_IS_ESCR0 		0x3b4
+#define MSR_P4_IS_ESCR1 		0x3b5
+#define MSR_P4_ITLB_ESCR0 		0x3b6
+#define MSR_P4_ITLB_ESCR1 		0x3b7
+#define MSR_P4_IX_ESCR0 		0x3c8
+#define MSR_P4_IX_ESCR1 		0x3c9
+#define MSR_P4_MOB_ESCR0 		0x3aa
+#define MSR_P4_MOB_ESCR1 		0x3ab
+#define MSR_P4_MS_ESCR0 		0x3c0
+#define MSR_P4_MS_ESCR1 		0x3c1
+#define MSR_P4_PMH_ESCR0 		0x3ac
+#define MSR_P4_PMH_ESCR1 		0x3ad
+#define MSR_P4_RAT_ESCR0 		0x3bc
+#define MSR_P4_RAT_ESCR1 		0x3bd
+#define MSR_P4_SAAT_ESCR0 		0x3ae
+#define MSR_P4_SAAT_ESCR1 		0x3af
+#define MSR_P4_SSU_ESCR0 		0x3be
+#define MSR_P4_SSU_ESCR1 		0x3bf    /* guess: not defined in manual */
+#define MSR_P4_TBPU_ESCR0 		0x3c2
+#define MSR_P4_TBPU_ESCR1 		0x3c3
+#define MSR_P4_TC_ESCR0 		0x3c4
+#define MSR_P4_TC_ESCR1 		0x3c5
+#define MSR_P4_U2L_ESCR0 		0x3b0
+#define MSR_P4_U2L_ESCR1 		0x3b1
+
 /* AMD Defined MSRs */
 #define MSR_K6_EFER			0xC0000080
 #define MSR_K6_STAR			0xC0000081
diff -Nru a/include/asm-i386/signal.h b/include/asm-i386/signal.h
--- a/include/asm-i386/signal.h	Fri Feb 14 15:53:09 2003
+++ b/include/asm-i386/signal.h	Fri Feb 14 15:53:09 2003
@@ -217,6 +217,7 @@
 
 struct pt_regs;
 extern int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-ia64/signal.h b/include/asm-ia64/signal.h
--- a/include/asm-ia64/signal.h	Fri Feb 14 15:53:09 2003
+++ b/include/asm-ia64/signal.h	Fri Feb 14 15:53:09 2003
@@ -166,6 +166,7 @@
 
 #  include <asm/sigcontext.h>
 
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
 #define HAVE_ARCH_SYS_PAUSE
 
 #endif /* __KERNEL__ */
diff -Nru a/include/asm-m68knommu/signal.h b/include/asm-m68knommu/signal.h
--- a/include/asm-m68knommu/signal.h	Fri Feb 14 15:53:10 2003
+++ b/include/asm-m68knommu/signal.h	Fri Feb 14 15:53:10 2003
@@ -176,6 +176,8 @@
 #include <asm/sigcontext.h>
 #undef __HAVE_ARCH_SIG_BITOPS
 
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
 #endif /* __KERNEL__ */
 
 #endif /* _M68KNOMMU_SIGNAL_H */
diff -Nru a/include/asm-mips/signal.h b/include/asm-mips/signal.h
--- a/include/asm-mips/signal.h	Fri Feb 14 15:53:09 2003
+++ b/include/asm-mips/signal.h	Fri Feb 14 15:53:09 2003
@@ -169,6 +169,8 @@
 #define _BRK_THREADBP	11	/* For threads, user bp (used by debuggers) */
 #define BRK_MULOVF	1023	/* Multiply overflow */
 
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
 #endif /* defined (__KERNEL__) */
 
 #endif /* _ASM_SIGNAL_H */
diff -Nru a/include/asm-mips64/signal.h b/include/asm-mips64/signal.h
--- a/include/asm-mips64/signal.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-mips64/signal.h	Fri Feb 14 15:53:12 2003
@@ -168,6 +168,9 @@
 #define BRK_NORLD	10	/* No rld found - not used by Linux/MIPS */
 #define _BRK_THREADBP	11	/* For threads, user bp (used by debuggers) */
 #define BRK_MULOVF	1023	/* Multiply overflow */
+
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
 #endif /* defined (__KERNEL__) || defined (__USE_MISC) */
 
 #endif /* !defined (_ASM_SIGNAL_H) */
diff -Nru a/include/asm-ppc/signal.h b/include/asm-ppc/signal.h
--- a/include/asm-ppc/signal.h	Fri Feb 14 15:53:08 2003
+++ b/include/asm-ppc/signal.h	Fri Feb 14 15:53:08 2003
@@ -150,6 +150,7 @@
 
 #ifdef __KERNEL__
 #include <asm/sigcontext.h>
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
 #endif /* __KERNEL__ */
 
 #endif
diff -Nru a/include/asm-ppc64/signal.h b/include/asm-ppc64/signal.h
--- a/include/asm-ppc64/signal.h	Fri Feb 14 15:53:09 2003
+++ b/include/asm-ppc64/signal.h	Fri Feb 14 15:53:09 2003
@@ -143,4 +143,6 @@
 	size_t ss_size;
 } stack_t;
 
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
 #endif /* _ASMPPC64_SIGNAL_H */
diff -Nru a/include/asm-s390/signal.h b/include/asm-s390/signal.h
--- a/include/asm-s390/signal.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-s390/signal.h	Fri Feb 14 15:53:12 2003
@@ -175,6 +175,8 @@
 #define sa_handler      _u._sa_handler
 #define sa_sigaction    _u._sa_sigaction
 
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
 #endif /* __KERNEL__ */
 
 typedef struct sigaltstack {
diff -Nru a/include/asm-s390x/signal.h b/include/asm-s390x/signal.h
--- a/include/asm-s390x/signal.h	Fri Feb 14 15:53:11 2003
+++ b/include/asm-s390x/signal.h	Fri Feb 14 15:53:11 2003
@@ -175,6 +175,8 @@
 #define sa_handler      _u._sa_handler
 #define sa_sigaction    _u._sa_sigaction
 
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
 #endif /* __KERNEL__ */
 
 typedef struct sigaltstack {
diff -Nru a/include/asm-sh/signal.h b/include/asm-sh/signal.h
--- a/include/asm-sh/signal.h	Fri Feb 14 15:53:10 2003
+++ b/include/asm-sh/signal.h	Fri Feb 14 15:53:10 2003
@@ -165,6 +165,8 @@
 #ifdef __KERNEL__
 #include <asm/sigcontext.h>
 
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_SH_SIGNAL_H */
diff -Nru a/include/asm-sparc/cacheflush.h b/include/asm-sparc/cacheflush.h
--- a/include/asm-sparc/cacheflush.h	Fri Feb 14 15:53:09 2003
+++ b/include/asm-sparc/cacheflush.h	Fri Feb 14 15:53:09 2003
@@ -62,8 +62,9 @@
 #define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr)
 #define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr)
 
-extern void flush_page_to_ram(struct page *page);
+extern void sparc_flush_page_to_ram(struct page *page);
 
-#define flush_dcache_page(page)			do { } while (0)
+#define flush_page_to_ram(page)			do { } while (0)
+#define flush_dcache_page(page)			sparc_flush_page_to_ram(page)
 
 #endif /* _SPARC_CACHEFLUSH_H */
diff -Nru a/include/asm-sparc/page.h b/include/asm-sparc/page.h
--- a/include/asm-sparc/page.h	Fri Feb 14 15:53:09 2003
+++ b/include/asm-sparc/page.h	Fri Feb 14 15:53:09 2003
@@ -31,8 +31,14 @@
 
 #define clear_page(page)	 memset((void *)(page), 0, PAGE_SIZE)
 #define copy_page(to,from) 	memcpy((void *)(to), (void *)(from), PAGE_SIZE)
-#define clear_user_page(addr, vaddr, page)	clear_page(addr)
-#define copy_user_page(to, from, vaddr, page)	copy_page(to, from)
+#define clear_user_page(addr, vaddr, page)	\
+	do { 	clear_page(addr);		\
+		sparc_flush_page_to_ram(page);	\
+	} while (0)
+#define copy_user_page(to, from, vaddr, page)	\
+	do {	copy_page(to, from);		\
+		sparc_flush_page_to_ram(page);	\
+	} while (0)
 
 /* The following structure is used to hold the physical
  * memory configuration of the machine.  This is filled in
diff -Nru a/include/asm-sparc/signal.h b/include/asm-sparc/signal.h
--- a/include/asm-sparc/signal.h	Fri Feb 14 15:53:11 2003
+++ b/include/asm-sparc/signal.h	Fri Feb 14 15:53:11 2003
@@ -216,7 +216,32 @@
 	size_t		ss_size;
 } stack_t;
 
-#define HAVE_ARCH_GET_SIGNAL_TO_DELIVER
+struct sparc_deliver_cookie {
+	int restart_syscall;
+	unsigned long orig_i0;
+};
+
+#define ptrace_signal_deliver(REGS, COOKIE) \
+do {	struct sparc_deliver_cookie *cp = (COOKIE); \
+	if (cp->restart_syscall && \
+	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND || \
+	     regs->u_regs[UREG_I0] == ERESTARTSYS || \
+	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { \
+		/* replay the system call when we are done */ \
+		regs->u_regs[UREG_I0] = cp->orig_i0; \
+		regs->pc -= 4; \
+		regs->npc -= 4; \
+		cp->restart_syscall = 0; \
+	} \
+	if (cp->restart_syscall && \
+	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { \
+		regs->u_regs[UREG_G1] = __NR_restart_syscall; \
+		regs->pc -= 4; \
+		regs->npc -= 4; \
+		cp->restart_syscall = 0; \
+	} \
+} while (0)
+
 
 #endif /* !(__ASSEMBLY__) */
 
diff -Nru a/include/asm-sparc/system.h b/include/asm-sparc/system.h
--- a/include/asm-sparc/system.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-sparc/system.h	Fri Feb 14 15:53:12 2003
@@ -62,8 +62,6 @@
 	return serial_console ? 0 : 1;
 }
 
-extern struct pt_regs *kbd_pt_regs;
-
 /* When a context switch happens we must flush all user windows so that
  * the windows of the current process are flushed onto its stack. This
  * way the windows are all clean for the next process and the stack
diff -Nru a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h
--- a/include/asm-sparc64/signal.h	Fri Feb 14 15:53:09 2003
+++ b/include/asm-sparc64/signal.h	Fri Feb 14 15:53:09 2003
@@ -245,7 +245,32 @@
 	compat_size_t		ss_size;
 } stack_t32;
 
-#define HAVE_ARCH_GET_SIGNAL_TO_DELIVER
+struct signal_deliver_cookie {
+	int restart_syscall;
+	unsigned long orig_i0;
+};
+
+#define ptrace_signal_deliver(REGS, COOKIE) \
+do {	struct signal_deliver_cookie *cp = (COOKIE); \
+	if (cp->restart_syscall && \
+	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND || \
+	     regs->u_regs[UREG_I0] == ERESTARTSYS || \
+	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) { \
+		/* replay the system call when we are done */ \
+		regs->u_regs[UREG_I0] = cp->orig_i0; \
+		regs->tpc -= 4; \
+		regs->tnpc -= 4; \
+		cp->restart_syscall = 0; \
+	} \
+	if (cp->restart_syscall && \
+	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { \
+		regs->u_regs[UREG_G1] = __NR_restart_syscall; \
+		regs->tpc -= 4; \
+		regs->tnpc -= 4; \
+		cp->restart_syscall = 0; \
+	} \
+} while (0)
+
 #define HAVE_ARCH_SYS_PAUSE
 
 #endif
diff -Nru a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
--- a/include/asm-sparc64/system.h	Fri Feb 14 15:53:08 2003
+++ b/include/asm-sparc64/system.h	Fri Feb 14 15:53:08 2003
@@ -131,8 +131,6 @@
 	return serial_console ? 0 : 1;
 }
 
-extern struct pt_regs *kbd_pt_regs;
-
 extern void synchronize_user_stack(void);
 
 extern void __flushw_user(void);
diff -Nru a/include/asm-v850/signal.h b/include/asm-v850/signal.h
--- a/include/asm-v850/signal.h	Fri Feb 14 15:53:09 2003
+++ b/include/asm-v850/signal.h	Fri Feb 14 15:53:09 2003
@@ -188,6 +188,8 @@
 #include <asm/sigcontext.h>
 #undef __HAVE_ARCH_SIG_BITOPS
 
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
 #endif /* __KERNEL__ */
 
 #endif /* __V850_SIGNAL_H__ */
diff -Nru a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h
--- a/include/asm-x86_64/acpi.h	Fri Feb 14 15:53:11 2003
+++ b/include/asm-x86_64/acpi.h	Fri Feb 14 15:53:11 2003
@@ -48,8 +48,8 @@
 
 #define ACPI_ASM_MACROS
 #define BREAKPOINT3
-#define ACPI_DISABLE_IRQS() __cli()
-#define ACPI_ENABLE_IRQS()  __sti()
+#define ACPI_DISABLE_IRQS() local_irq_disable()
+#define ACPI_ENABLE_IRQS()  local_irq_enable()
 #define ACPI_FLUSH_CPU_CACHE()	wbinvd()
 
 /*
@@ -141,6 +141,10 @@
 #define boot_cpu_physical_apicid boot_cpu_id
 
 extern int acpi_disabled;
+
+#define dmi_broken (0)
+#define BROKEN_ACPI_Sx		0x0001
+#define BROKEN_INIT_AFTER_S1	0x0002
 
 #endif /*__KERNEL__*/
 
diff -Nru a/include/asm-x86_64/current.h b/include/asm-x86_64/current.h
--- a/include/asm-x86_64/current.h	Fri Feb 14 15:53:08 2003
+++ b/include/asm-x86_64/current.h	Fri Feb 14 15:53:08 2003
@@ -12,15 +12,6 @@
 	return t;
 } 
 
-
-#define stack_current() \
-({								\
-	struct thread_info *ti;					\
-	__asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (~8191UL));	\
-	ti->task;					\
-})
-
-
 #define current get_current()
 
 #else
diff -Nru a/include/asm-x86_64/desc.h b/include/asm-x86_64/desc.h
--- a/include/asm-x86_64/desc.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-x86_64/desc.h	Fri Feb 14 15:53:12 2003
@@ -135,6 +135,14 @@
 			      DESC_LDT, size); 
 }
 
+static inline void set_seg_base(unsigned cpu, int entry, void *base)
+{ 
+	struct desc_struct *d = &cpu_gdt_table[cpu][entry];
+	d->base0 = PTR_LOW(base);
+	d->base1 = PTR_MIDDLE(base);
+	d->base2 = PTR_HIGH(base);
+} 
+
 #define LDT_entry_a(info) \
 	((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
 #define LDT_entry_b(info) \
diff -Nru a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h
--- a/include/asm-x86_64/dma-mapping.h	Fri Feb 14 15:53:10 2003
+++ b/include/asm-x86_64/dma-mapping.h	Fri Feb 14 15:53:10 2003
@@ -1,5 +1,5 @@
-#ifndef _ASM_X8664_DMA_MAPPING_H
-#define _ASM_X8664_DMA_MAPPING_H
+#ifndef _X8664_DMA_MAPPING_H
+#define _X8664_DMA_MAPPING_H 1
 
 #include <asm-generic/dma-mapping.h>
 
diff -Nru a/include/asm-x86_64/e820.h b/include/asm-x86_64/e820.h
--- a/include/asm-x86_64/e820.h	Fri Feb 14 15:53:08 2003
+++ b/include/asm-x86_64/e820.h	Fri Feb 14 15:53:08 2003
@@ -47,7 +47,7 @@
 			      int type);
 extern void setup_memory_region(void);
 extern void contig_e820_setup(void); 
-extern void e820_end_of_ram(void);
+extern unsigned long e820_end_of_ram(void);
 extern void e820_reserve_resources(void);
 extern void e820_print_map(char *who);
 extern int e820_mapped(unsigned long start, unsigned long end, int type);
diff -Nru a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h
--- a/include/asm-x86_64/i387.h	Fri Feb 14 15:53:10 2003
+++ b/include/asm-x86_64/i387.h	Fri Feb 14 15:53:10 2003
@@ -39,16 +39,10 @@
 #define kernel_fpu_end() stts()
 
 #define unlazy_fpu(tsk) do { \
-	if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) \
+	if ((tsk)->thread_info->flags & TIF_USEDFPU) \
 		save_init_fpu(tsk); \
 } while (0)
 
-#define unlazy_current_fpu() do { \
-	if (test_thread_flag(TIF_USEDFPU)) \
-		save_init_fpu(tsk); \
-} while (0)
-
-
 #define clear_fpu(tsk) do { \
 	if (test_tsk_thread_flag(tsk, TIF_USEDFPU)) {		\
 		asm volatile("fwait");				\
@@ -134,7 +128,7 @@
 {
 	asm volatile( "fxsave %0 ; fnclex"
 		      : "=m" (tsk->thread.i387.fxsave));
-	clear_tsk_thread_flag(tsk, TIF_USEDFPU);
+	tsk->thread_info->flags &= ~TIF_USEDFPU;
 	stts();
 }
 
diff -Nru a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h
--- a/include/asm-x86_64/ia32.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-x86_64/ia32.h	Fri Feb 14 15:53:12 2003
@@ -26,28 +26,18 @@
 #include <asm/sigcontext32.h>
 
 /* signal.h */
-#define _IA32_NSIG	       64
-#define _IA32_NSIG_BPW	       32
-#define _IA32_NSIG_WORDS	       (_IA32_NSIG / _IA32_NSIG_BPW)
-
-typedef struct {
-       unsigned int sig[_IA32_NSIG_WORDS];
-} sigset32_t;
-
 struct sigaction32 {
        unsigned int  sa_handler;	/* Really a pointer, but need to deal 
 					     with 32 bits */
        unsigned int sa_flags;
        unsigned int sa_restorer;	/* Another 32 bit pointer */
-       sigset32_t sa_mask;		/* A 32 bit mask */
+       compat_sigset_t sa_mask;		/* A 32 bit mask */
 };
 
-typedef unsigned int old_sigset32_t;	/* at least 32 bits */
-
 struct old_sigaction32 {
        unsigned int  sa_handler;	/* Really a pointer, but need to deal 
 					     with 32 bits */
-       old_sigset32_t sa_mask;		/* A 32 bit mask */
+       compat_old_sigset_t sa_mask;		/* A 32 bit mask */
        unsigned int sa_flags;
        unsigned int sa_restorer;	/* Another 32 bit pointer */
 };
@@ -63,7 +53,7 @@
 	unsigned int 	  uc_link;
 	stack_ia32_t	  uc_stack;
 	struct sigcontext_ia32 uc_mcontext;
-	sigset32_t	  uc_sigmask;	/* mask last for extensibility */
+	compat_sigset_t	  uc_sigmask;	/* mask last for extensibility */
 };
 
 /* This matches struct stat64 in glibc2.2, hence the absolutely
diff -Nru a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
--- a/include/asm-x86_64/io.h	Fri Feb 14 15:53:09 2003
+++ b/include/asm-x86_64/io.h	Fri Feb 14 15:53:09 2003
@@ -1,6 +1,8 @@
 #ifndef _ASM_IO_H
 #define _ASM_IO_H
 
+#include <linux/config.h>
+
 /*
  * This file contains the definitions for the x86 IO instructions
  * inb/inw/inl/outb/outw/outl and the "string versions" of the same
@@ -135,7 +137,12 @@
 /*
  * Change "struct page" to physical address.
  */
+#ifdef CONFIG_DISCONTIGMEM
+#include <asm/mmzone.h>
+#define page_to_phys(page)    ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
+#else
 #define page_to_phys(page)	((page - mem_map) << PAGE_SHIFT)
+#endif
 
 extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
 
diff -Nru a/include/asm-x86_64/mmsegment.h b/include/asm-x86_64/mmsegment.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-x86_64/mmsegment.h	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,8 @@
+#ifndef _ASM_MMSEGMENT_H
+#define _ASM_MMSEGMENT_H 1
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#endif
diff -Nru a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-x86_64/mmzone.h	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,79 @@
+/* K8 NUMA support */
+/* Copyright 2002,2003 by Andi Kleen, SuSE Labs */
+/* 2.5 Version losely based on the NUMAQ Code by Pat Gaughen. */
+#ifndef _ASM_X86_64_MMZONE_H
+#define _ASM_X86_64_MMZONE_H 1
+
+#include <linux/config.h>
+
+#ifdef CONFIG_DISCONTIGMEM
+
+#define VIRTUAL_BUG_ON(x) 
+
+#include <asm/numnodes.h>
+#include <asm/smp.h>
+
+#define MAXNODE 8 
+#define NODEMAPSIZE 0xff
+
+/* Simple perfect hash to map physical addresses to node numbers */
+extern int memnode_shift; 
+extern u8  memnodemap[NODEMAPSIZE]; 
+extern int maxnode;
+
+extern struct pglist_data *node_data[];
+
+/* kern_addr_valid below hardcodes the same algorithm*/
+static inline __attribute__((pure)) int phys_to_nid(unsigned long addr) 
+{ 
+	int nid; 
+	VIRTUAL_BUG_ON((addr >> memnode_shift) >= NODEMAPSIZE);
+	nid = memnodemap[addr >> memnode_shift]; 
+	VIRTUAL_BUG_ON(nid > maxnode); 
+	return nid; 
+} 
+
+#define kvaddr_to_nid(kaddr)	phys_to_nid(__pa(kaddr))
+#define NODE_DATA(nid)		(node_data[nid])
+
+#define node_mem_map(nid)	(NODE_DATA(nid)->node_mem_map)
+
+#define node_mem_map(nid)	(NODE_DATA(nid)->node_mem_map)
+#define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
+#define node_end_pfn(nid)       (NODE_DATA(nid)->node_start_pfn + \
+				 NODE_DATA(nid)->node_size)
+#define node_size(nid)		(NODE_DATA(nid)->node_size)
+
+#define local_mapnr(kvaddr) \
+	( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) )
+#define kern_addr_valid(kvaddr) ({					\
+	int ok = 0;							\
+        unsigned long index = __pa(kvaddr) >> memnode_shift;		\
+	if (index <= NODEMAPSIZE) {					\
+		unsigned nodeid = memnodemap[index];			\
+		unsigned long pfn = __pa(kvaddr) >> PAGE_SHIFT;		\
+		unsigned long start_pfn = node_start_pfn(nodeid);	\
+		ok = (nodeid != 0xff) &&				\
+		     (pfn >= start_pfn) &&				\
+		     (pfn <  start_pfn + node_size(nodeid));		\
+	}								\
+        ok;								\
+})
+
+/* AK: this currently doesn't deal with invalid addresses. We'll see 
+   if the 2.5 kernel doesn't pass them
+   (2.4 used to). */
+#define pfn_to_page(pfn) ({ \
+	int nid = phys_to_nid(((unsigned long)(pfn)) << PAGE_SHIFT); 	\
+	((pfn) - node_start_pfn(nid)) + node_mem_map(nid);		\
+})
+
+#define page_to_pfn(page) \
+	(long)(((page) - page_zone(page)->zone_mem_map) + page_zone(page)->zone_start_pfn)
+
+/* AK: !DISCONTIGMEM just forces it to 1. Can't we too? */
+#define pfn_valid(pfn)          ((pfn) < num_physpages)
+
+
+#endif
+#endif
diff -Nru a/include/asm-x86_64/mpspec.h b/include/asm-x86_64/mpspec.h
--- a/include/asm-x86_64/mpspec.h	Fri Feb 14 15:53:09 2003
+++ b/include/asm-x86_64/mpspec.h	Fri Feb 14 15:53:09 2003
@@ -185,7 +185,6 @@
 extern int mp_current_pci_id;
 extern unsigned long mp_lapic_addr;
 extern int pic_mode;
-extern int using_apic_timer;
 
 #ifdef CONFIG_ACPI_BOOT
 extern void mp_register_lapic (u8 id, u8 enabled);
@@ -198,6 +197,8 @@
 extern void mp_parse_prt (void);
 #endif /*CONFIG_X86_IO_APIC*/
 #endif
+
+extern int using_apic_timer;
 
 #endif
 
diff -Nru a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h
--- a/include/asm-x86_64/msr.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-x86_64/msr.h	Fri Feb 14 15:53:12 2003
@@ -67,6 +67,61 @@
 			  : "=a" (low), "=d" (high) \
 			  : "c" (counter))
 
+extern inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
+{
+	__asm__("cpuid"
+		: "=a" (*eax),
+		  "=b" (*ebx),
+		  "=c" (*ecx),
+		  "=d" (*edx)
+		: "0" (op));
+}
+
+/*
+ * CPUID functions returning a single datum
+ */
+extern inline unsigned int cpuid_eax(unsigned int op)
+{
+	unsigned int eax;
+
+	__asm__("cpuid"
+		: "=a" (eax)
+		: "0" (op)
+		: "bx", "cx", "dx");
+	return eax;
+}
+extern inline unsigned int cpuid_ebx(unsigned int op)
+{
+	unsigned int eax, ebx;
+
+	__asm__("cpuid"
+		: "=a" (eax), "=b" (ebx)
+		: "0" (op)
+		: "cx", "dx" );
+	return ebx;
+}
+extern inline unsigned int cpuid_ecx(unsigned int op)
+{
+	unsigned int eax, ecx;
+
+	__asm__("cpuid"
+		: "=a" (eax), "=c" (ecx)
+		: "0" (op)
+		: "bx", "dx" );
+	return ecx;
+}
+extern inline unsigned int cpuid_edx(unsigned int op)
+{
+	unsigned int eax, edx;
+
+	__asm__("cpuid"
+		: "=a" (eax), "=d" (edx)
+		: "0" (op)
+		: "bx", "cx");
+	return edx;
+}
+
+
 #endif
 
 /* AMD/K8 specific MSRs */ 
diff -Nru a/include/asm-x86_64/numa.h b/include/asm-x86_64/numa.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-x86_64/numa.h	Fri Feb 14 15:53:12 2003
@@ -0,0 +1,22 @@
+#ifndef _ASM_X8664_NUMA_H 
+#define _ASM_X8664_NUMA_H 1
+
+#define MAXNODE 8 
+#define NODEMASK 0xff
+
+struct node { 
+	u64 start,end; 
+};
+
+#define for_all_nodes(x) for ((x) = 0; (x) <= maxnode; (x)++) \
+				if ((1UL << (x)) & nodes_present)
+
+#define early_for_all_nodes(n) \
+	for (n=0; n<MAXNODE;n++) if (nodes[n].start!=nodes[n].end)
+
+extern int compute_hash_shift(struct node *nodes, int numnodes, u64 maxmem);
+extern unsigned long nodes_present;
+
+#define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT))
+
+#endif
diff -Nru a/include/asm-x86_64/numnodes.h b/include/asm-x86_64/numnodes.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-x86_64/numnodes.h	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,12 @@
+#ifndef _ASM_X8664_NUMNODES_H
+#define _ASM_X8664_NUMNODES_H 1
+
+#include <linux/config.h>
+
+#ifdef CONFIG_DISCONTIGMEM
+#define MAX_NUMNODES 8	/* APIC limit currently */
+#else
+#define MAX_NUMNODES 1
+#endif
+
+#endif
diff -Nru a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
--- a/include/asm-x86_64/page.h	Fri Feb 14 15:53:08 2003
+++ b/include/asm-x86_64/page.h	Fri Feb 14 15:53:08 2003
@@ -1,6 +1,8 @@
 #ifndef _X86_64_PAGE_H
 #define _X86_64_PAGE_H
 
+#include <linux/config.h>
+
 /* PAGE_SHIFT determines the page size */
 #define PAGE_SHIFT	12
 #ifdef __ASSEMBLY__
@@ -10,7 +12,13 @@
 #endif
 #define PAGE_MASK	(~(PAGE_SIZE-1))
 #define PHYSICAL_PAGE_MASK	(~(PAGE_SIZE-1) & (__PHYSICAL_MASK << PAGE_SHIFT))
-#define THREAD_SIZE (2*PAGE_SIZE)
+
+#define THREAD_ORDER 1 
+#ifdef __ASSEMBLY__
+#define THREAD_SIZE  (1 << (PAGE_SHIFT + THREAD_ORDER))
+#else
+#define THREAD_SIZE  (1UL << (PAGE_SHIFT + THREAD_ORDER))
+#endif
 #define CURRENT_MASK (~(THREAD_SIZE-1))
 
 #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
@@ -58,7 +66,7 @@
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
-/* See Documentation/x86_64/mm.txt for a description of the layout. */
+/* See Documentation/x86_64/mm.txt for a description of the memory map. */
 #define __START_KERNEL		0xffffffff80100000
 #define __START_KERNEL_map	0xffffffff80000000
 #define __PAGE_OFFSET           0x0000010000000000
@@ -100,10 +108,13 @@
 	  __pa(v); })
 
 #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
+#ifndef CONFIG_DISCONTIGMEM
 #define pfn_to_page(pfn)	(mem_map + (pfn))
 #define page_to_pfn(page)	((unsigned long)((page) - mem_map))
-#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_valid(pfn)		((pfn) < max_mapnr)
+#endif
+
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
 
diff -Nru a/include/asm-x86_64/pda.h b/include/asm-x86_64/pda.h
--- a/include/asm-x86_64/pda.h	Fri Feb 14 15:53:09 2003
+++ b/include/asm-x86_64/pda.h	Fri Feb 14 15:53:09 2003
@@ -55,7 +55,10 @@
        } \
        } while (0)
 
-
+/* 
+ * AK: PDA read accesses should be neither volatile nor have an memory clobber.
+ * Unfortunately removing them causes all hell to break lose currently.
+ */
 #define pda_from_op(op,field) ({ \
        typedef typeof_field(struct x8664_pda, field) T__; T__ ret__; \
        switch (sizeof_field(struct x8664_pda, field)) { 		\
diff -Nru a/include/asm-x86_64/pgalloc.h b/include/asm-x86_64/pgalloc.h
--- a/include/asm-x86_64/pgalloc.h	Fri Feb 14 15:53:10 2003
+++ b/include/asm-x86_64/pgalloc.h	Fri Feb 14 15:53:10 2003
@@ -14,8 +14,7 @@
 
 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
 {
-	set_pmd(pmd, __pmd(_PAGE_TABLE | 
-			   ((u64)(pte - mem_map) << PAGE_SHIFT))); 
+	set_pmd(pmd, __pmd(_PAGE_TABLE | (page_to_pfn(pte) << PAGE_SHIFT)));
 }
 
 extern __inline__ pmd_t *get_pmd(void)
@@ -76,6 +75,6 @@
 } 
 
 #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
-#define __pmd_free_tlb(tlb,x)   do { } while (0)
+#define __pmd_free_tlb(tlb,x)   pmd_free(x)
 
 #endif /* _X86_64_PGALLOC_H */
diff -Nru a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
--- a/include/asm-x86_64/pgtable.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-x86_64/pgtable.h	Fri Feb 14 15:53:12 2003
@@ -103,6 +103,8 @@
 #define ptep_get_and_clear(xp)	__pte(xchg(&(xp)->pte, 0))
 #define pte_same(a, b)		((a).pte == (b).pte)
 
+#define PML4_SIZE	(1UL << PML4_SHIFT)
+#define PML4_MASK       (~(PML4_SIZE-1))
 #define PMD_SIZE	(1UL << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
@@ -317,7 +319,8 @@
 
 /* PMD  - Level 2 access */
 #define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PTE_MASK))
-#define pmd_page(pmd)        (mem_map + ((pmd_val(pmd) & PTE_MASK)>>PAGE_SHIFT))
+#define pmd_page(pmd)		(pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+
 #define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
 #define pmd_offset(dir, address) ((pmd_t *) pgd_page(*(dir)) + \
 			__pmd_offset(address))
@@ -372,7 +375,9 @@
 
 #endif /* !__ASSEMBLY__ */
 
+#ifndef CONFIG_DISCONTIGMEM
 #define kern_addr_valid(addr)	(1)
+#endif
 
 #define io_remap_page_range remap_page_range
 
diff -Nru a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
--- a/include/asm-x86_64/processor.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-x86_64/processor.h	Fri Feb 14 15:53:12 2003
@@ -17,6 +17,7 @@
 #include <asm/msr.h>
 #include <asm/current.h>
 #include <asm/system.h>
+#include <asm/mmsegment.h>
 
 #define TF_MASK		0x00000100
 #define IF_MASK		0x00000200
@@ -110,64 +111,6 @@
 #define X86_EFLAGS_ID	0x00200000 /* CPUID detection flag */
 
 /*
- *	Generic CPUID function
- * 	FIXME: This really belongs to msr.h
- */
-extern inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
-{
-	__asm__("cpuid"
-		: "=a" (*eax),
-		  "=b" (*ebx),
-		  "=c" (*ecx),
-		  "=d" (*edx)
-		: "0" (op));
-}
-
-/*
- * CPUID functions returning a single datum
- */
-extern inline unsigned int cpuid_eax(unsigned int op)
-{
-	unsigned int eax;
-
-	__asm__("cpuid"
-		: "=a" (eax)
-		: "0" (op)
-		: "bx", "cx", "dx");
-	return eax;
-}
-extern inline unsigned int cpuid_ebx(unsigned int op)
-{
-	unsigned int eax, ebx;
-
-	__asm__("cpuid"
-		: "=a" (eax), "=b" (ebx)
-		: "0" (op)
-		: "cx", "dx" );
-	return ebx;
-}
-extern inline unsigned int cpuid_ecx(unsigned int op)
-{
-	unsigned int eax, ecx;
-
-	__asm__("cpuid"
-		: "=a" (eax), "=c" (ecx)
-		: "0" (op)
-		: "bx", "dx" );
-	return ecx;
-}
-extern inline unsigned int cpuid_edx(unsigned int op)
-{
-	unsigned int eax, edx;
-
-	__asm__("cpuid"
-		: "=a" (eax), "=d" (edx)
-		: "0" (op)
-		: "bx", "cx");
-	return edx;
-}
-
-/*
  * Intel CPU features in CR4
  */
 #define X86_CR4_VME		0x0001	/* enable vm86 extensions */
@@ -210,36 +153,6 @@
 		:"ax");
 }
 
-#if 0
-/*
- *      Cyrix CPU configuration register indexes
- */
-#define CX86_CCR0 0xc0
-#define CX86_CCR1 0xc1
-#define CX86_CCR2 0xc2
-#define CX86_CCR3 0xc3
-#define CX86_CCR4 0xe8
-#define CX86_CCR5 0xe9
-#define CX86_CCR6 0xea
-#define CX86_CCR7 0xeb
-#define CX86_DIR0 0xfe
-#define CX86_DIR1 0xff
-#define CX86_ARR_BASE 0xc4
-#define CX86_RCR_BASE 0xdc
-
-/*
- *      Cyrix CPU indexed register access macros
- */
-
-#define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })
-
-#define setCx86(reg, data) do { \
-	outb((reg), 0x22); \
-	outb((data), 0x23); \
-} while (0)
-
-#endif
-
 /*
  * Bus types
  */
@@ -286,10 +199,6 @@
 	struct i387_fxsave_struct	fxsave;
 };
 
-typedef struct {
-	unsigned long seg;
-} mm_segment_t;
-
 struct tss_struct {
 	u32 reserved1;
 	u64 rsp0;	
@@ -302,7 +211,7 @@
 	u16 reserved5;
 	u16 io_map_base;
 	u32 io_bitmap[IO_BITMAP_SIZE];
-} __attribute__((packed));
+} __attribute__((packed)) ____cacheline_aligned;
 
 struct thread_struct {
 	unsigned long	rsp0;
@@ -336,6 +245,7 @@
 #define NMI_STACK 3 
 #define N_EXCEPTION_STACKS 3  /* hw limit: 7 */
 #define EXCEPTION_STKSZ 1024
+#define EXCEPTION_STK_ORDER 0
 
 #define start_thread(regs,new_rip,new_rsp) do { \
 	asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0));	 \
@@ -378,6 +288,13 @@
 	__asm__ __volatile__("rep;nop": : :"memory");
 }
 
+/* Stop speculative execution */
+extern inline void sync_core(void)
+{ 
+	int tmp;
+	asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
+} 
+
 #define cpu_has_fpu 1
 
 #define ARCH_HAS_PREFETCH
@@ -389,7 +306,6 @@
 #define spin_lock_prefetch(x)  prefetchw(x)
 #define cpu_relax()   rep_nop()
 
-
 /*
  *      NSC/Cyrix CPU configuration register indexes
  */
@@ -416,5 +332,12 @@
 	outb((reg), 0x22); \
 	outb((data), 0x23); \
 } while (0)
+
+#define stack_current() \
+({								\
+	struct thread_info *ti;					\
+	asm("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK));	\
+	ti->task;					\
+})
 
 #endif /* __ASM_X86_64_PROCESSOR_H */
diff -Nru a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
--- a/include/asm-x86_64/proto.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-x86_64/proto.h	Fri Feb 14 15:53:12 2003
@@ -25,6 +25,8 @@
 
 extern void do_softirq_thunk(void);
 
+extern int numa_setup(char *opt);
+
 extern int setup_early_printk(char *); 
 extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2)));
 
@@ -36,18 +38,27 @@
 extern void reserve_bootmem_generic(unsigned long phys, unsigned len);
 extern void free_bootmem_generic(unsigned long phys, unsigned len);
 
-extern unsigned long start_pfn, end_pfn, end_pfn_map; 
+extern unsigned long end_pfn_map; 
 
 extern void show_stack(unsigned long * rsp);
 
 extern void exception_table_check(void);
 
-extern int acpi_boot_init(char *);
+extern void acpi_reserve_bootmem(void);
+
+extern void swap_low_mappings(void);
 
 extern int map_syscall32(struct mm_struct *mm, unsigned long address);
 extern char *syscall32_page;
 
+void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end);
+
+extern unsigned long max_mapnr;
+extern unsigned long end_pfn; 
+extern unsigned long table_start, table_end;
+
 struct thread_struct;
+struct user_desc;
 
 int do_set_thread_area(struct thread_struct *t, struct user_desc *u_info);
 int do_get_thread_area(struct thread_struct *t, struct user_desc *u_info);
diff -Nru a/include/asm-x86_64/segment.h b/include/asm-x86_64/segment.h
--- a/include/asm-x86_64/segment.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-x86_64/segment.h	Fri Feb 14 15:53:12 2003
@@ -19,13 +19,15 @@
 #define __USER_DS     0x2b   /* 5*8+3 */ 
 #define __USER_CS     0x33   /* 6*8+3 */ 
 #define __USER32_DS	__USER_DS 
+#define __KERNEL16_CS	(GDT_ENTRY_KERNELCS16 * 8)
 
 #define GDT_ENTRY_TLS 1
 #define GDT_ENTRY_TSS 8	/* needs two entries */
 #define GDT_ENTRY_LDT 10
 #define GDT_ENTRY_TLS_MIN 11
 #define GDT_ENTRY_TLS_MAX 13
-#define GDT_ENTRY_LONGBASE 14
+/* 14 free */
+#define GDT_ENTRY_KERNELCS16 15
 
 #define GDT_ENTRY_TLS_ENTRIES 3
 
diff -Nru a/include/asm-x86_64/signal.h b/include/asm-x86_64/signal.h
--- a/include/asm-x86_64/signal.h	Fri Feb 14 15:53:08 2003
+++ b/include/asm-x86_64/signal.h	Fri Feb 14 15:53:08 2003
@@ -200,6 +200,9 @@
 }
 #endif
 #endif
+
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
 #endif /* __KERNEL__ */
 
 #endif
diff -Nru a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
--- a/include/asm-x86_64/smp.h	Fri Feb 14 15:53:08 2003
+++ b/include/asm-x86_64/smp.h	Fri Feb 14 15:53:08 2003
@@ -44,7 +44,9 @@
 extern void smp_send_reschedule_all(void);
 extern void smp_invalidate_rcv(void);		/* Process an NMI */
 extern void (*mtrr_hook) (void);
-extern void zap_low_mappings (void);
+extern void zap_low_mappings(void);
+
+#define SMP_TRAMPOLINE_BASE 0x6000
 
 /*
  * On x86 all CPUs are mapped 1:1 to the APIC space.
@@ -55,38 +57,26 @@
 extern volatile unsigned long cpu_callout_map;
 
 #define cpu_possible(cpu) (cpu_callout_map & (1<<(cpu)))
+#define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
 
-extern inline int cpu_logical_map(int cpu)
-{
-	return cpu;
-}
-extern inline int cpu_number_map(int cpu)
-{
-	return cpu;
-}
+#define for_each_cpu(cpu, mask) \
+	for(mask = cpu_online_map; \
+	    cpu = __ffs(mask), mask != 0; \
+	    mask &= ~(1UL<<cpu))
 
-extern inline unsigned int num_online_cpus(void)
+extern inline int any_online_cpu(unsigned int mask)
 {
-	return hweight32(cpu_online_map);
-}
+	if (mask & cpu_online_map)
+		return __ffs(mask & cpu_online_map);
 
-extern inline int find_next_cpu(unsigned cpu) 
-{ 
-	unsigned long left = cpu_online_map >> (cpu+1); 
-	if (!left) 
 		return -1; 
-	return ffz(~left) + cpu; 		
 } 
 
-extern inline int find_first_cpu(void)
+extern inline unsigned int num_online_cpus(void)
 { 
-	return ffz(~cpu_online_map); 	
+	return hweight32(cpu_online_map);
 } 
 
-/* RED-PEN different from i386 */
-#define for_each_cpu(i) \
-	for((i) = find_first_cpu(); (i)>=0; (i)=find_next_cpu(i))
-
 static inline int num_booting_cpus(void)
 {
 	return hweight32(cpu_callout_map);
@@ -94,28 +84,25 @@
 
 extern volatile unsigned long cpu_callout_map;
 
-/*
- * Some lowlevel functions might want to know about
- * the real APIC ID <-> CPU # mapping.
- */
-extern volatile int x86_apicid_to_cpu[NR_CPUS];
-extern volatile int x86_cpu_to_apicid[NR_CPUS];
-
-/*
- * This function is needed by all SMP systems. It must _always_ be valid
- * from the initial startup. We map APIC_BASE very early in page_setup(),
- * so this is correct in the x86 case.
- */
-
 #define smp_processor_id() read_pda(cpunumber)
 
-
 extern __inline int hard_smp_processor_id(void)
 {
 	/* we don't want to mark this access volatile - bad code generation */
 	return GET_APIC_ID(*(unsigned int *)(APIC_BASE+APIC_ID));
 }
 
+extern int disable_apic;
+extern int slow_smp_processor_id(void);
+
+extern inline int safe_smp_processor_id(void)
+{ 
+	if (disable_apic)
+		return slow_smp_processor_id(); 
+	else
+		return hard_smp_processor_id();
+} 
+
 #define cpu_online(cpu) (cpu_online_map & (1<<(cpu)))
 #endif /* !ASSEMBLY */
 
@@ -128,6 +115,7 @@
 
 #ifndef CONFIG_SMP
 #define stack_smp_processor_id() 0
+#define safe_smp_processor_id() 0
 #define for_each_cpu(x) (x)=0;
 #define cpu_logical_map(x) (x)
 #else
@@ -135,7 +123,7 @@
 #define stack_smp_processor_id() \
 ({ 								\
 	struct thread_info *ti;					\
-	__asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (~8191UL));	\
+	__asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK));	\
 	ti->cpu;						\
 })
 #endif
diff -Nru a/include/asm-x86_64/spinlock.h b/include/asm-x86_64/spinlock.h
--- a/include/asm-x86_64/spinlock.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-x86_64/spinlock.h	Fri Feb 14 15:53:12 2003
@@ -15,7 +15,7 @@
 
 typedef struct {
 	volatile unsigned int lock;
-#if CONFIG_DEBUG_SPINLOCK
+#ifdef CONFIG_DEBUG_SPINLOCK
 	unsigned magic;
 #endif
 } spinlock_t;
@@ -56,13 +56,56 @@
 
 /*
  * This works. Despite all the confusion.
+ * (except on PPro SMP or if we are using OOSTORE)
+ * (PPro errata 66, 92)
  */
+ 
+#if !defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE)
+
 #define spin_unlock_string \
-	"movb $1,%0"
+	"movb $1,%0" \
+		:"=m" (lock->lock) : : "memory"
+
+
+static inline void _raw_spin_unlock(spinlock_t *lock)
+{
+#ifdef CONFIG_DEBUG_SPINLOCK
+	if (lock->magic != SPINLOCK_MAGIC)
+		BUG();
+	if (!spin_is_locked(lock))
+		BUG();
+#endif
+	__asm__ __volatile__(
+		spin_unlock_string
+	);
+}
+
+#else
+
+#define spin_unlock_string \
+	"xchgb %b0, %1" \
+		:"=q" (oldval), "=m" (lock->lock) \
+		:"0" (oldval) : "memory"
+
+static inline void _raw_spin_unlock(spinlock_t *lock)
+{
+	char oldval = 1;
+#ifdef CONFIG_DEBUG_SPINLOCK
+	if (lock->magic != SPINLOCK_MAGIC)
+		BUG();
+	if (!spin_is_locked(lock))
+		BUG();
+#endif
+	__asm__ __volatile__(
+		spin_unlock_string
+	);
+}
+
+#endif
 
 static inline int _raw_spin_trylock(spinlock_t *lock)
 {
-	signed char oldval;
+	char oldval;
 	__asm__ __volatile__(
 		"xchgb %b0,%1"
 		:"=q" (oldval), "=m" (lock->lock)
@@ -85,18 +128,6 @@
 		:"=m" (lock->lock) : : "memory");
 }
 
-static inline void _raw_spin_unlock(spinlock_t *lock)
-{
-#ifdef CONFIG_DEBUG_SPINLOCK
-	if (lock->magic != SPINLOCK_MAGIC)
-		BUG();
-	if (!spin_is_locked(lock))
-		BUG();
-#endif
-	__asm__ __volatile__(
-		spin_unlock_string
-		:"=m" (lock->lock) : : "memory");
-}
 
 /*
  * Read-write spinlocks, allowing multiple readers
@@ -127,6 +158,8 @@
 
 #define rwlock_init(x)	do { *(x) = RW_LOCK_UNLOCKED; } while(0)
 
+#define rwlock_is_locked(x) ((x)->lock != RW_LOCK_BIAS)
+
 /*
  * On x86, we implement read-write locks as a 32-bit counter
  * with the high bit (sign) being the "contended" bit.
@@ -136,9 +169,9 @@
  * Changed to use the same technique as rw semaphores.  See
  * semaphore.h for details.  -ben
  */
-/* the spinlock helpers are in arch/x86_64/kernel/semaphore.S */
+/* the spinlock helpers are in arch/i386/kernel/semaphore.c */
 
-extern inline void _raw_read_lock(rwlock_t *rw)
+static inline void _raw_read_lock(rwlock_t *rw)
 {
 #ifdef CONFIG_DEBUG_SPINLOCK
 	if (rw->magic != RWLOCK_MAGIC)
@@ -167,7 +200,5 @@
 	atomic_add(RW_LOCK_BIAS, count);
 	return 0;
 }
-
-#define rwlock_is_locked(x) ((x)->lock != RW_LOCK_BIAS)
 
 #endif /* __ASM_SPINLOCK_H */
diff -Nru a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
--- a/include/asm-x86_64/system.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-x86_64/system.h	Fri Feb 14 15:53:12 2003
@@ -83,7 +83,7 @@
 #define loadsegment(seg,value)	\
 	asm volatile("\n"			\
 		"1:\t"				\
-		"movl %0,%%" #seg "\n"		\
+		"movl %k0,%%" #seg "\n"		\
 		"2:\n"				\
 		".section .fixup,\"ax\"\n"	\
 		"3:\t"				\
@@ -94,7 +94,7 @@
 		".align 8\n\t"			\
 		".quad 1b,3b\n"			\
 		".previous"			\
-		: :"r" ((int)(value)))
+		: :"r" (value))
 
 #define set_debug(value,register) \
                 __asm__("movq %0,%%db" #register  \
@@ -117,6 +117,13 @@
 static inline void write_cr0(unsigned long val) 
 { 
 	asm volatile("movq %0,%%cr0" :: "r" (val));
+} 
+
+static inline unsigned long read_cr3(void)
+{ 
+	unsigned long cr3;
+	asm("movq %%cr3,%0" : "=r" (cr3));
+	return cr3;
 } 
 
 static inline unsigned long read_cr4(void)
diff -Nru a/include/asm-x86_64/thread_info.h b/include/asm-x86_64/thread_info.h
--- a/include/asm-x86_64/thread_info.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-x86_64/thread_info.h	Fri Feb 14 15:53:12 2003
@@ -9,11 +9,8 @@
 
 #ifdef __KERNEL__
 
-#ifndef __ASSEMBLY__
-#include <asm/processor.h>
-#include <linux/config.h>
-#include <asm/pda.h>
-#endif
+#include <asm/page.h>
+#include <asm/types.h>
 
 /*
  * low level task data that entry.S needs immediate access to
@@ -21,6 +18,10 @@
  * - this struct shares the supervisor stack pages
  */
 #ifndef __ASSEMBLY__
+struct task_struct;
+struct exec_domain;
+#include <asm/mmsegment.h>
+
 struct thread_info {
 	struct task_struct	*task;		/* main task structure */
 	struct exec_domain	*exec_domain;	/* execution domain */
@@ -31,7 +32,6 @@
 	mm_segment_t		addr_limit;	
 	struct restart_block    restart_block;
 };
-
 #endif
 
 /*
@@ -55,27 +55,17 @@
 #define init_thread_info	(init_thread_union.thread_info)
 #define init_stack		(init_thread_union.stack)
 
-/* how to get the thread information struct from C */
-
-#define THREAD_SIZE (2*PAGE_SIZE)
-
 static inline struct thread_info *current_thread_info(void)
 { 
 	struct thread_info *ti;
-	ti = (void *)read_pda(kernelstack) + PDA_STACKOFFSET - THREAD_SIZE;
-	return ti; 
-} 
-
-static inline struct thread_info *stack_thread_info(void)
-{
-	struct thread_info *ti;
-	__asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (~8191UL));
+	asm("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK));
 	return ti;
 }
 
 /* thread information allocation */
-#define alloc_thread_info() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
-#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
+#define alloc_thread_info() \
+	((struct thread_info *) __get_free_pages(GFP_KERNEL,THREAD_ORDER))
+#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER)
 #define get_thread_info(ti) get_task_struct((ti)->task)
 #define put_thread_info(ti) put_task_struct((ti)->task)
 
@@ -84,7 +74,7 @@
 /* how to get the thread information struct from ASM */
 /* only works on the process stack. otherwise get it via the PDA. */
 #define GET_THREAD_INFO(reg) \
-	movq $-8192, reg; \
+	movq $CURRENT_MASK, reg; \
 	andq %rsp, reg
 
 #endif
diff -Nru a/include/asm-x86_64/timex.h b/include/asm-x86_64/timex.h
--- a/include/asm-x86_64/timex.h	Fri Feb 14 15:53:10 2003
+++ b/include/asm-x86_64/timex.h	Fri Feb 14 15:53:10 2003
@@ -1,7 +1,7 @@
 /*
- * linux/include/asm-x8664/timex.h
+ * linux/include/asm-x86_64/timex.h
  *
- * x8664 architecture timex specifications
+ * x86-64 architecture timex specifications
  */
 #ifndef _ASMx8664_TIMEX_H
 #define _ASMx8664_TIMEX_H
@@ -16,20 +16,6 @@
 	(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
 		<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
 
-/*
- * Standard way to access the cycle counter on i586+ CPUs.
- * Currently only used on SMP.
- *
- * If you really have a SMP machine with i486 chips or older,
- * compile for that, and this will just always return zero.
- * That's ok, it just means that the nicer scheduling heuristics
- * won't work for you.
- *
- * We only use the low 32 bits, and we'd simply better make sure
- * that we reschedule before that wraps. Scheduling at least every
- * four billion cycles just basically sounds like a good idea,
- * regardless of how fast the machine is. 
- */
 typedef unsigned long long cycles_t;
 
 extern cycles_t cacheflush_time;
diff -Nru a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h
--- a/include/asm-x86_64/topology.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-x86_64/topology.h	Fri Feb 14 15:53:12 2003
@@ -1,6 +1,26 @@
 #ifndef _ASM_X86_64_TOPOLOGY_H
 #define _ASM_X86_64_TOPOLOGY_H
 
+#include <linux/config.h>
+
+#ifdef CONFIG_DISCONTIGMEM
+
+/* Map the K8 CPU local memory controllers to a simple 1:1 CPU:NODE topology */
+
+extern int fake_node;
+extern unsigned long cpu_online_map;
+
+#define cpu_to_node(cpu)		(fake_node ? 0 : (cpu))
+#define memblk_to_node(memblk) 	(fake_node ? 0 : (memblk))
+#define parent_node(node)		(node)
+#define node_to_first_cpu(node) 	(fake_node ? 0 : (node))
+#define node_to_cpu_mask(node)	(fake_node ? cpu_online_map : (1UL << (node)))
+#define node_to_memblk(node)		(node)
+
+#define NODE_BALANCE_RATE 30	/* CHECKME */ 
+
+#endif
+
 #include <asm-generic/topology.h>
 
-#endif /* _ASM_X86_64_TOPOLOGY_H */
+#endif
diff -Nru a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
--- a/include/asm-x86_64/unistd.h	Fri Feb 14 15:53:11 2003
+++ b/include/asm-x86_64/unistd.h	Fri Feb 14 15:53:11 2003
@@ -500,8 +500,10 @@
 __SYSCALL(__NR_restart_syscall, sys_restart_syscall)
 #define __NR_semtimedop		220
 __SYSCALL(__NR_semtimedop, sys_semtimedop)
+#define __NR_fadvise64		221
+__SYSCALL(__NR_fadvise64, sys_fadvise64)
 
-#define __NR_syscall_max __NR_semtimedop
+#define __NR_syscall_max __NR_fadvise64
 #ifndef __NO_STUBS
 
 /* user-visible error numbers are in the range -1 - -4095 */
diff -Nru a/include/asm-x86_64/vsyscall.h b/include/asm-x86_64/vsyscall.h
--- a/include/asm-x86_64/vsyscall.h	Fri Feb 14 15:53:12 2003
+++ b/include/asm-x86_64/vsyscall.h	Fri Feb 14 15:53:12 2003
@@ -2,6 +2,7 @@
 #define _ASM_X86_64_VSYSCALL_H_
 
 #include <linux/time.h>
+#include <linux/seqlock.h>
 
 enum vsyscall_num {
 	__NR_vgettimeofday,
@@ -19,8 +20,10 @@
 #define __section_wall_jiffies __attribute__ ((unused, __section__ (".wall_jiffies"), aligned(16)))
 #define __section_jiffies __attribute__ ((unused, __section__ (".jiffies"), aligned(16)))
 #define __section_sys_tz __attribute__ ((unused, __section__ (".sys_tz"), aligned(16)))
+#define __section_sysctl_vsyscall __attribute__ ((unused, __section__ (".sysctl_vsyscall"), aligned(16)))
 #define __section_xtime __attribute__ ((unused, __section__ (".xtime"), aligned(16)))
-#define __section_vxtime_sequence __attribute__ ((unused, __section__ (".vxtime_sequence"), aligned(16)))
+#define __section_xtime_lock __attribute__ ((unused, __section__ (".xtime_lock"), aligned(L1_CACHE_BYTES)))
+
 
 struct hpet_data {
 	long address;		/* base address */
@@ -36,21 +39,21 @@
 #define hpet_writel(d,a)        writel(d, fix_to_virt(FIX_HPET_BASE) + a)
 
 /* vsyscall space (readonly) */
-extern long __vxtime_sequence[2];
 extern struct hpet_data __hpet;
 extern struct timespec __xtime;
 extern volatile unsigned long __jiffies;
 extern unsigned long __wall_jiffies;
 extern struct timezone __sys_tz;
+extern seqlock_t __xtime_lock;
 
 /* kernel space (writeable) */
-extern long vxtime_sequence[2];
 extern struct hpet_data hpet;
 extern unsigned long wall_jiffies;
 extern struct timezone sys_tz;
+extern int sysctl_vsyscall;
+extern seqlock_t xtime_lock;
 
-#define vxtime_lock() do { vxtime_sequence[0]++; wmb(); } while(0)
-#define vxtime_unlock() do { wmb(); vxtime_sequence[1]++; } while (0)
+#define ARCH_HAVE_XTIME_LOCK 1
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/linux/agp_backend.h b/include/linux/agp_backend.h
--- a/include/linux/agp_backend.h	Fri Feb 14 15:53:12 2003
+++ b/include/linux/agp_backend.h	Fri Feb 14 15:53:12 2003
@@ -53,17 +53,6 @@
 	INTEL_460GX,
 	INTEL_I7505,
 	VIA_GENERIC,
-	VIA_VP3,
-	VIA_MVP3,
-	VIA_MVP4,
-	VIA_APOLLO_PRO,
-	VIA_APOLLO_KX133,
-	VIA_APOLLO_KT133,
-	VIA_APOLLO_KT400,
-	VIA_APOLLO_KT400_3,
-	VIA_APOLLO_PRO_266,
-	VIA_VT8605,
-	VIA_P4X,
 	SIS_GENERIC,
 	AMD_GENERIC,
 	AMD_IRONGATE,
@@ -84,6 +73,7 @@
 	SVWRKS_LE,
 	SVWRKS_GENERIC,
 	HP_ZX1,
+	ALPHA_CORE_AGP,
 };
 
 struct agp_version {
@@ -102,6 +92,7 @@
 	int current_memory;
 	int cant_use_aperture;
 	unsigned long page_mask;
+	struct vm_operations_struct *vm_ops;
 } agp_kern_info;
 
 /* 
diff -Nru a/include/linux/buffer_head.h b/include/linux/buffer_head.h
--- a/include/linux/buffer_head.h	Fri Feb 14 15:53:08 2003
+++ b/include/linux/buffer_head.h	Fri Feb 14 15:53:08 2003
@@ -169,6 +169,7 @@
 void free_buffer_head(struct buffer_head * bh);
 void FASTCALL(unlock_buffer(struct buffer_head *bh));
 void ll_rw_block(int, int, struct buffer_head * bh[]);
+void sync_dirty_buffer(struct buffer_head *bh);
 int submit_bh(int, struct buffer_head *);
 void write_boundary_block(struct block_device *bdev,
 			sector_t bblock, unsigned blocksize);
diff -Nru a/include/linux/cpufreq.h b/include/linux/cpufreq.h
--- a/include/linux/cpufreq.h	Fri Feb 14 15:53:11 2003
+++ b/include/linux/cpufreq.h	Fri Feb 14 15:53:11 2003
@@ -2,10 +2,10 @@
  *  linux/include/linux/cpufreq.h
  *
  *  Copyright (C) 2001 Russell King
- *            (C) 2002 Dominik Brodowski <linux@brodo.de>
+ *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
  *            
  *
- * $Id: cpufreq.h,v 1.29 2002/11/11 15:35:47 db Exp $
+ * $Id: cpufreq.h,v 1.36 2003/01/20 17:31:48 db Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -20,6 +20,9 @@
 #include <linux/device.h>
 
 
+#define CPUFREQ_NAME_LEN 16
+
+
 /*********************************************************************
  *                     CPUFREQ NOTIFIER INTERFACE                    *
  *********************************************************************/
@@ -37,14 +40,17 @@
 
 #define CPUFREQ_POLICY_POWERSAVE        (1)
 #define CPUFREQ_POLICY_PERFORMANCE      (2)
+#define CPUFREQ_POLICY_GOVERNOR         (3)
 
 /* Frequency values here are CPU kHz so that hardware which doesn't run 
  * with some frequencies can complain without having to guess what per 
  * cent / per mille means. 
- * Maximum transition latency is in nanoseconds - if it's unknown,
+ * Maximum transition latency is in microseconds - if it's unknown,
  * CPUFREQ_ETERNAL shall be used.
  */
 
+struct cpufreq_governor;
+
 #define CPUFREQ_ETERNAL (-1)
 struct cpufreq_cpuinfo {
 	unsigned int            max_freq;
@@ -57,6 +63,7 @@
 	unsigned int            min;    /* in kHz */
 	unsigned int            max;    /* in kHz */
         unsigned int            policy; /* see above */
+	struct cpufreq_governor *governor; /* see below */
 	struct cpufreq_cpuinfo  cpuinfo;     /* see above */
 	struct intf_data        intf;   /* interface data */
 };
@@ -104,25 +111,62 @@
 	return carry + val;
 };
 
+/*********************************************************************
+ *                          CPUFREQ GOVERNORS                        *
+ *********************************************************************/
+
+#define CPUFREQ_GOV_START  1
+#define CPUFREQ_GOV_STOP   2
+#define CPUFREQ_GOV_LIMITS 3
+
+struct cpufreq_governor {
+	char			name[CPUFREQ_NAME_LEN];
+	int	(*governor)	(struct cpufreq_policy *policy,
+				 unsigned int event);
+	struct list_head	governor_list;
+	struct module           *owner;
+};
+
+/* pass a target to the cpufreq driver 
+ * _l : (cpufreq_driver_sem is not held)
+ */
+inline int cpufreq_driver_target(struct cpufreq_policy *policy,
+				 unsigned int target_freq,
+				 unsigned int relation);
+
+inline int cpufreq_driver_target_l(struct cpufreq_policy *policy,
+				   unsigned int target_freq,
+				   unsigned int relation);
+
+/* pass an event to the cpufreq governor */
+int cpufreq_governor_l(unsigned int cpu, unsigned int event);
+
+int cpufreq_register_governor(struct cpufreq_governor *governor);
+void cpufreq_unregister_governor(struct cpufreq_governor *governor);
 
 /*********************************************************************
  *                      CPUFREQ DRIVER INTERFACE                     *
  *********************************************************************/
 
-#define CPUFREQ_NAME_LEN 16
+#define CPUFREQ_RELATION_L 0  /* lowest frequency at or above target */
+#define CPUFREQ_RELATION_H 1  /* highest frequency below or at target */
 
 struct cpufreq_driver {
 	/* needed by all drivers */
-	int     (*verify)       (struct cpufreq_policy *policy);
-	int     (*setpolicy)    (struct cpufreq_policy *policy);
-	struct cpufreq_policy   *policy;
-	char           		name[CPUFREQ_NAME_LEN];
+	int	(*verify)	(struct cpufreq_policy *policy);
+	struct cpufreq_policy	*policy;
+	char			name[CPUFREQ_NAME_LEN];
+	/* define one out of two */
+	int	(*setpolicy)	(struct cpufreq_policy *policy);
+	int	(*target)	(struct cpufreq_policy *policy,
+				 unsigned int target_freq,
+				 unsigned int relation);
 	/* optional, for the moment */
-	int     (*init)        (struct cpufreq_policy *policy);
-	int     (*exit)        (struct cpufreq_policy *policy);
+	int	(*init)		(struct cpufreq_policy *policy);
+	int	(*exit)		(struct cpufreq_policy *policy);
 	/* 2.4. compatible API */
 #ifdef CONFIG_CPU_FREQ_24_API
-	unsigned int            cpu_cur_freq[NR_CPUS];
+	unsigned int		cpu_cur_freq[NR_CPUS];
 #endif
 };
 
@@ -275,5 +319,11 @@
 int cpufreq_frequency_table_setpolicy(struct cpufreq_policy *policy,
 				      struct cpufreq_frequency_table *table,
 				      unsigned int *index);
+
+int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
+				   struct cpufreq_frequency_table *table,
+				   unsigned int target_freq,
+				   unsigned int relation,
+				   unsigned int *index);
 
 #endif /* _LINUX_CPUFREQ_H */
diff -Nru a/include/linux/eventpoll.h b/include/linux/eventpoll.h
--- a/include/linux/eventpoll.h	Fri Feb 14 15:53:09 2003
+++ b/include/linux/eventpoll.h	Fri Feb 14 15:53:09 2003
@@ -32,10 +32,10 @@
 
 
 /* Kernel space functions implementing the user space "epoll" API */
-asmlinkage int sys_epoll_create(int size);
-asmlinkage int sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
-asmlinkage int sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
-			      int timeout);
+asmlinkage long sys_epoll_create(int size);
+asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
+asmlinkage long sys_epoll_wait(int epfd, struct epoll_event *events, int maxevents,
+			       int timeout);
 
 /* Used to initialize the epoll bits inside the "struct file" */
 void eventpoll_init_file(struct file *file);
diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h
--- a/include/linux/ext3_jbd.h	Fri Feb 14 15:53:08 2003
+++ b/include/linux/ext3_jbd.h	Fri Feb 14 15:53:08 2003
@@ -210,14 +210,6 @@
 	return journal_start(journal, nblocks);
 }
 
-static inline handle_t *
-ext3_journal_try_start(struct inode *inode, int nblocks)
-{
-	if (inode->i_sb->s_flags & MS_RDONLY)
-		return ERR_PTR(-EROFS);
-	return journal_try_start(EXT3_JOURNAL(inode), nblocks);
-}
-
 /* 
  * The only special thing we need to do here is to make sure that all
  * journal_stop calls result in the superblock being marked dirty, so
diff -Nru a/include/linux/hfs_sysdep.h b/include/linux/hfs_sysdep.h
--- a/include/linux/hfs_sysdep.h	Fri Feb 14 15:53:08 2003
+++ b/include/linux/hfs_sysdep.h	Fri Feb 14 15:53:08 2003
@@ -155,13 +155,8 @@
 }
 
 static inline void hfs_buffer_sync(hfs_buffer buffer) {
-	while (buffer_locked(buffer)) {
-		wait_on_buffer(buffer);
-	}
-	if (buffer_dirty(buffer)) {
-		ll_rw_block(WRITE, 1, &buffer);
-		wait_on_buffer(buffer);
-	}
+	if (buffer_dirty(buffer))
+		sync_dirty_buffer(buffer);
 }
 
 static inline void *hfs_buffer_data(const hfs_buffer buffer) {
diff -Nru a/include/linux/hiddev.h b/include/linux/hiddev.h
--- a/include/linux/hiddev.h	Fri Feb 14 15:53:09 2003
+++ b/include/linux/hiddev.h	Fri Feb 14 15:53:09 2003
@@ -204,7 +204,7 @@
 int hiddev_connect(struct hid_device *);
 void hiddev_disconnect(struct hid_device *);
 void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
-		      struct hid_usage *usage, __s32 value);
+		      struct hid_usage *usage, __s32 value, struct pt_regs *regs);
 void hiddev_report_event(struct hid_device *hid, struct hid_report *report);
 int __init hiddev_init(void);
 void __exit hiddev_exit(void);
@@ -212,7 +212,7 @@
 static inline int hiddev_connect(struct hid_device *hid) { return -1; }
 static inline void hiddev_disconnect(struct hid_device *hid) { }
 static inline void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
-		      struct hid_usage *usage, __s32 value) { }
+		      struct hid_usage *usage, __s32 value, struct pt_regs *regs) { }
 static inline void hiddev_report_event(struct hid_device *hid, struct hid_report *report) { }
 static inline int hiddev_init(void) { return 0; }
 static inline void hiddev_exit(void) { }
diff -Nru a/include/linux/hugetlb.h b/include/linux/hugetlb.h
--- a/include/linux/hugetlb.h	Fri Feb 14 15:53:10 2003
+++ b/include/linux/hugetlb.h	Fri Feb 14 15:53:10 2003
@@ -26,6 +26,7 @@
 					unsigned long address);
 struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
 				pmd_t *pmd, int write);
+int is_aligned_hugepage_range(unsigned long addr, unsigned long len);
 int pmd_huge(pmd_t pmd);
 
 extern int htlbpage_max;
@@ -56,6 +57,7 @@
 #define hugepage_vma(mm, addr)			0
 #define mark_mm_hugetlb(mm, vma)		do { } while (0)
 #define follow_huge_pmd(mm, addr, pmd, write)	0
+#define is_aligned_hugepage_range(addr, len)	0
 #define pmd_huge(x)	0
 
 #ifndef HPAGE_MASK
diff -Nru a/include/linux/input.h b/include/linux/input.h
--- a/include/linux/input.h	Fri Feb 14 15:53:09 2003
+++ b/include/linux/input.h	Fri Feb 14 15:53:09 2003
@@ -774,6 +774,7 @@
 	struct timer_list timer;
 
 	struct pm_dev *pm_dev;
+	struct pt_regs *regs;
 	int state;
 
 	int sync;
@@ -899,12 +900,14 @@
 
 void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
 
-#define input_sync(a)		input_event(a, EV_SYN, SYN_REPORT, 0)
 #define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c))
 #define input_report_rel(a,b,c) input_event(a, EV_REL, b, c)
 #define input_report_abs(a,b,c) input_event(a, EV_ABS, b, c)
 #define input_report_ff(a,b,c)	input_event(a, EV_FF, b, c)
 #define input_report_ff_status(a,b,c)	input_event(a, EV_FF_STATUS, b, c)
+
+#define input_regs(a,b)		do { (a)->regs = (b); } while (0)
+#define input_sync(a)		do { input_event(a, EV_SYN, SYN_REPORT, 0); (a)->regs = NULL; } while (0)
 
 extern struct device_class input_devclass;
 
diff -Nru a/include/linux/jbd.h b/include/linux/jbd.h
--- a/include/linux/jbd.h	Fri Feb 14 15:53:12 2003
+++ b/include/linux/jbd.h	Fri Feb 14 15:53:12 2003
@@ -726,7 +726,6 @@
  */
 
 extern handle_t *journal_start(journal_t *, int nblocks);
-extern handle_t *journal_try_start(journal_t *, int nblocks);
 extern int	 journal_restart (handle_t *, int nblocks);
 extern int	 journal_extend (handle_t *, int nblocks);
 extern int	 journal_get_write_access (handle_t *, struct buffer_head *);
diff -Nru a/include/linux/jiffies.h b/include/linux/jiffies.h
--- a/include/linux/jiffies.h	Fri Feb 14 15:53:08 2003
+++ b/include/linux/jiffies.h	Fri Feb 14 15:53:08 2003
@@ -15,24 +15,14 @@
 extern u64 jiffies_64;
 extern unsigned long volatile jiffies;
 
+#if (BITS_PER_LONG < 64)
+u64 get_jiffies_64(void);
+#else
 static inline u64 get_jiffies_64(void)
 {
-#if BITS_PER_LONG < 64
-	extern seqlock_t xtime_lock;
-	unsigned long seq;
-	u64 tmp;
-
-	do {
-		seq = read_seqbegin(&xtime_lock);
-		tmp = jiffies_64;
-	} while (read_seqretry(&xtime_lock, seq));
-
-	return tmp;
-#else
 	return (u64)jiffies;
-#endif
 }
-
+#endif
 
 /*
  *	These inlines deal with timer wrapping correctly. You are 
diff -Nru a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h
--- a/include/linux/kbd_kern.h	Fri Feb 14 15:53:12 2003
+++ b/include/linux/kbd_kern.h	Fri Feb 14 15:53:12 2003
@@ -43,11 +43,12 @@
 #define LED_SHOW_IOCTL 1        /* only change leds upon ioctl */
 #define LED_SHOW_MEM 2          /* `heartbeat': peek into memory */
 
-	unsigned char ledflagstate:3;	/* flags, not lights */
-	unsigned char default_ledflagstate:3;
+	unsigned char ledflagstate:4;	/* flags, not lights */
+	unsigned char default_ledflagstate:4;
 #define VC_SCROLLOCK	0	/* scroll-lock mode */
 #define VC_NUMLOCK	1	/* numeric lock mode */
 #define VC_CAPSLOCK	2	/* capslock mode */
+#define VC_KANALOCK	3	/* kanalock mode */
 
 	unsigned char kbdmode:2;	/* one 2-bit value */
 #define VC_XLATE	0	/* translate keycodes using keymap */
diff -Nru a/include/linux/keyboard.h b/include/linux/keyboard.h
--- a/include/linux/keyboard.h	Fri Feb 14 15:53:09 2003
+++ b/include/linux/keyboard.h	Fri Feb 14 15:53:09 2003
@@ -9,6 +9,7 @@
 #define KG_ALT		3
 #define KG_ALTGR	1
 #define KG_SHIFTL	4
+#define KG_KANASHIFT	4
 #define KG_SHIFTR	5
 #define KG_CTRLL	6
 #define KG_CTRLR	7
diff -Nru a/include/linux/mca-legacy.h b/include/linux/mca-legacy.h
--- a/include/linux/mca-legacy.h	Fri Feb 14 15:53:12 2003
+++ b/include/linux/mca-legacy.h	Fri Feb 14 15:53:12 2003
@@ -7,6 +7,8 @@
 #ifndef _LINUX_MCA_LEGACY_H
 #define _LINUX_MCA_LEGACY_H
 
+#warning "MCA legacy - please move your driver to the new sysfs api"
+
 /* MCA_NOTFOUND is an error condition.  The other two indicate
  * motherboard POS registers contain the adapter.  They might be
  * returned by the mca_find_adapter() function, and can be used as
diff -Nru a/include/linux/oprofile.h b/include/linux/oprofile.h
--- a/include/linux/oprofile.h	Fri Feb 14 15:53:11 2003
+++ b/include/linux/oprofile.h	Fri Feb 14 15:53:11 2003
@@ -21,14 +21,6 @@
 struct dentry;
 struct file_operations;
  
-enum oprofile_cpu {
-	OPROFILE_CPU_PPRO,
-	OPROFILE_CPU_PII,
-	OPROFILE_CPU_PIII,
-	OPROFILE_CPU_ATHLON,
-	OPROFILE_CPU_TIMER
-};
-
 /* Operations structure to be filled in */
 struct oprofile_operations {
 	/* create any necessary configuration files in the oprofile fs.
@@ -42,20 +34,23 @@
 	int (*start)(void);
 	/* Stop delivering interrupts. */
 	void (*stop)(void);
+	/* CPU identification string. */
+	char * cpu_type;
 };
 
 /**
  * One-time initialisation. *ops must be set to a filled-in
- * operations structure. oprofile_cpu_type must be set.
+ * operations structure.
  * Return 0 on success.
  */
-int oprofile_arch_init(struct oprofile_operations ** ops, enum oprofile_cpu * cpu);
+int oprofile_arch_init(struct oprofile_operations ** ops);
  
 /**
  * Add a sample. This may be called from any context. Pass
  * smp_processor_id() as cpu.
  */
-extern void oprofile_add_sample(unsigned long eip, unsigned long event, int cpu);
+extern void oprofile_add_sample(unsigned long eip, unsigned int is_kernel, 
+	unsigned long event, int cpu);
 
 /**
  * Create a file of the given name as a child of the given root, with
@@ -79,6 +74,12 @@
 /** create a directory */
 struct dentry * oprofilefs_mkdir(struct super_block * sb, struct dentry * root,
 	char const * name);
+
+/**
+ * Write the given asciz string to the given user buffer @buf, updating *offset
+ * appropriately. Returns bytes written or -EFAULT.
+ */
+ssize_t oprofilefs_str_to_user(char const * str, char * buf, size_t count, loff_t * offset);
 
 /**
  * Convert an unsigned long value into ASCII and copy it to the user buffer @buf,
diff -Nru a/include/linux/pc_keyb.h b/include/linux/pc_keyb.h
--- a/include/linux/pc_keyb.h	Fri Feb 14 15:53:09 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,130 +0,0 @@
-/*
- *	include/linux/pc_keyb.h
- *
- *	PC Keyboard And Keyboard Controller
- *
- *	(c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
- */
-
-/*
- *	Configuration Switches
- */
-
-#undef KBD_REPORT_ERR			/* Report keyboard errors */
-#define KBD_REPORT_UNKN			/* Report unknown scan codes */
-#define KBD_REPORT_TIMEOUTS		/* Report keyboard timeouts */
-#undef KBD_IS_FOCUS_9000		/* We have the brain-damaged FOCUS-9000 keyboard */
-#undef INITIALIZE_MOUSE			/* Define if your PS/2 mouse needs initialization. */
-
-
-
-#define KBD_INIT_TIMEOUT 1000		/* Timeout in ms for initializing the keyboard */
-#define KBC_TIMEOUT 250			/* Timeout in ms for sending to keyboard controller */
-#define KBD_TIMEOUT 1000		/* Timeout in ms for keyboard command acknowledge */
-
-/*
- *	Internal variables of the driver
- */
-
-extern unsigned char pckbd_read_mask;
-extern unsigned char aux_device_present;
-
-/*
- *	Keyboard Controller Registers on normal PCs.
- */
-
-#define KBD_STATUS_REG		0x64	/* Status register (R) */
-#define KBD_CNTL_REG		0x64	/* Controller command register (W) */
-#define KBD_DATA_REG		0x60	/* Keyboard data register (R/W) */
-
-/*
- *	Keyboard Controller Commands
- */
-
-#define KBD_CCMD_READ_MODE	0x20	/* Read mode bits */
-#define KBD_CCMD_WRITE_MODE	0x60	/* Write mode bits */
-#define KBD_CCMD_GET_VERSION	0xA1	/* Get controller version */
-#define KBD_CCMD_MOUSE_DISABLE	0xA7	/* Disable mouse interface */
-#define KBD_CCMD_MOUSE_ENABLE	0xA8	/* Enable mouse interface */
-#define KBD_CCMD_TEST_MOUSE	0xA9	/* Mouse interface test */
-#define KBD_CCMD_SELF_TEST	0xAA	/* Controller self test */
-#define KBD_CCMD_KBD_TEST	0xAB	/* Keyboard interface test */
-#define KBD_CCMD_KBD_DISABLE	0xAD	/* Keyboard interface disable */
-#define KBD_CCMD_KBD_ENABLE	0xAE	/* Keyboard interface enable */
-#define KBD_CCMD_WRITE_AUX_OBUF	0xD3    /* Write to output buffer as if
-					   initiated by the auxiliary device */
-#define KBD_CCMD_WRITE_MOUSE	0xD4	/* Write the following byte to the mouse */
-
-/*
- *	Keyboard Commands
- */
-
-#define KBD_CMD_SET_LEDS	0xED	/* Set keyboard leds */
-#define KBD_CMD_SET_RATE	0xF3	/* Set typematic rate */
-#define KBD_CMD_ENABLE		0xF4	/* Enable scanning */
-#define KBD_CMD_DISABLE		0xF5	/* Disable scanning */
-#define KBD_CMD_RESET		0xFF	/* Reset */
-
-/*
- *	Keyboard Replies
- */
-
-#define KBD_REPLY_POR		0xAA	/* Power on reset */
-#define KBD_REPLY_ACK		0xFA	/* Command ACK */
-#define KBD_REPLY_RESEND	0xFE	/* Command NACK, send the cmd again */
-
-/*
- *	Status Register Bits
- */
-
-#define KBD_STAT_OBF 		0x01	/* Keyboard output buffer full */
-#define KBD_STAT_IBF 		0x02	/* Keyboard input buffer full */
-#define KBD_STAT_SELFTEST	0x04	/* Self test successful */
-#define KBD_STAT_CMD		0x08	/* Last write was a command write (0=data) */
-#define KBD_STAT_UNLOCKED	0x10	/* Zero if keyboard locked */
-#define KBD_STAT_MOUSE_OBF	0x20	/* Mouse output buffer full */
-#define KBD_STAT_GTO 		0x40	/* General receive/xmit timeout */
-#define KBD_STAT_PERR 		0x80	/* Parity error */
-
-#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
-
-/*
- *	Controller Mode Register Bits
- */
-
-#define KBD_MODE_KBD_INT	0x01	/* Keyboard data generate IRQ1 */
-#define KBD_MODE_MOUSE_INT	0x02	/* Mouse data generate IRQ12 */
-#define KBD_MODE_SYS 		0x04	/* The system flag (?) */
-#define KBD_MODE_NO_KEYLOCK	0x08	/* The keylock doesn't affect the keyboard if set */
-#define KBD_MODE_DISABLE_KBD	0x10	/* Disable keyboard interface */
-#define KBD_MODE_DISABLE_MOUSE	0x20	/* Disable mouse interface */
-#define KBD_MODE_KCC 		0x40	/* Scan code conversion to PC format */
-#define KBD_MODE_RFU		0x80
-
-/*
- *	Mouse Commands
- */
-
-#define AUX_SET_RES		0xE8	/* Set resolution */
-#define AUX_SET_SCALE11		0xE6	/* Set 1:1 scaling */
-#define AUX_SET_SCALE21		0xE7	/* Set 2:1 scaling */
-#define AUX_GET_SCALE		0xE9	/* Get scaling factor */
-#define AUX_SET_STREAM		0xEA	/* Set stream mode */
-#define AUX_SET_SAMPLE		0xF3	/* Set sample rate */
-#define AUX_ENABLE_DEV		0xF4	/* Enable aux device */
-#define AUX_DISABLE_DEV		0xF5	/* Disable aux device */
-#define AUX_RESET		0xFF	/* Reset aux device */
-#define AUX_ACK			0xFA	/* Command byte ACK. */
-
-#define AUX_BUF_SIZE		2048	/* This might be better divisible by
-					   three to make overruns stay in sync
-					   but then the read function would need
-					   a lock etc - ick */
-
-struct aux_queue {
-	unsigned long head;
-	unsigned long tail;
-	wait_queue_head_t proc_list;
-	struct fasync_struct *fasync;
-	unsigned char buf[AUX_BUF_SIZE];
-};
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	Fri Feb 14 15:53:09 2003
+++ b/include/linux/pci_ids.h	Fri Feb 14 15:53:09 2003
@@ -893,6 +893,14 @@
 #define PCI_DEVICE_ID_3COM_3C905TX	0x9050
 #define PCI_DEVICE_ID_3COM_3C905T4	0x9051
 #define PCI_DEVICE_ID_3COM_3C905B_TX	0x9055
+#define PCI_DEVICE_ID_3COM_3CR990	0x9900
+#define PCI_DEVICE_ID_3COM_3CR990_TX_95	0x9902
+#define PCI_DEVICE_ID_3COM_3CR990_TX_97	0x9903
+#define PCI_DEVICE_ID_3COM_3CR990B	0x9904
+#define PCI_DEVICE_ID_3COM_3CR990_FX	0x9905
+#define PCI_DEVICE_ID_3COM_3CR990SVR95	0x9908
+#define PCI_DEVICE_ID_3COM_3CR990SVR97	0x9909
+#define PCI_DEVICE_ID_3COM_3CR990SVR	0x990a
 
 #define PCI_VENDOR_ID_SMC		0x10b8
 #define PCI_DEVICE_ID_SMC_EPIC100	0x0005
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h	Fri Feb 14 15:53:08 2003
+++ b/include/linux/sched.h	Fri Feb 14 15:53:08 2003
@@ -509,6 +509,7 @@
 /* per-UID process charging. */
 extern struct user_struct * alloc_uid(uid_t);
 extern void free_uid(struct user_struct *);
+extern void switch_uid(struct user_struct *);
 
 #include <asm/current.h>
 
@@ -529,7 +530,7 @@
 extern void proc_caches_init(void);
 extern void flush_signals(struct task_struct *);
 extern void flush_signal_handlers(struct task_struct *);
-extern int dequeue_signal(sigset_t *mask, siginfo_t *info);
+extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info);
 extern void block_all_signals(int (*notifier)(void *priv), void *priv,
 			      sigset_t *mask);
 extern void unblock_all_signals(void);
@@ -615,7 +616,8 @@
 extern NORET_TYPE void do_group_exit(int);
 
 extern void reparent_to_init(void);
-extern void daemonize(void);
+extern void daemonize(const char *, ...);
+extern int allow_signal(int);
 extern task_t *child_reaper;
 
 extern int do_execve(char *, char **, char **, struct pt_regs *);
diff -Nru a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h	Fri Feb 14 15:53:11 2003
+++ b/include/linux/serio.h	Fri Feb 14 15:53:11 2003
@@ -10,10 +10,13 @@
  */
 
 #include <linux/ioctl.h>
-#include <linux/list.h>
 
 #define SPIOCSTYPE	_IOW('q', 0x01, unsigned long)
 
+#ifdef __KERNEL__
+
+#include <linux/list.h>
+
 struct serio;
 
 struct serio {
@@ -47,7 +50,7 @@
 	char *name;
 
 	void (*write_wakeup)(struct serio *);
-	void (*interrupt)(struct serio *, unsigned char, unsigned int);
+	void (*interrupt)(struct serio *, unsigned char, unsigned int, struct pt_regs *);
 	void (*connect)(struct serio *, struct serio_dev *dev);
 	void (*disconnect)(struct serio *);
 	void (*cleanup)(struct serio *);
@@ -58,7 +61,7 @@
 int serio_open(struct serio *serio, struct serio_dev *dev);
 void serio_close(struct serio *serio);
 void serio_rescan(struct serio *serio);
-void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags);
+void serio_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs);
 
 void serio_register_port(struct serio *serio);
 void serio_unregister_port(struct serio *serio);
@@ -85,6 +88,8 @@
 		serio->dev->cleanup(serio);
 }
 
+#endif
+
 /*
  * bit masks for use in "interrupt" flags (3rd argument)
  */
@@ -122,6 +127,8 @@
 #define SERIO_TWIDKBD	0x23
 #define SERIO_TWIDJOY	0x24
 #define SERIO_HIL	0x25
+#define SERIO_SNES232	0x26
+#define SERIO_SEMTECH	0x27
 
 #define SERIO_ID	0xff00UL
 #define SERIO_EXTRA	0xff0000UL
diff -Nru a/include/linux/signal.h b/include/linux/signal.h
--- a/include/linux/signal.h	Fri Feb 14 15:53:09 2003
+++ b/include/linux/signal.h	Fri Feb 14 15:53:09 2003
@@ -208,7 +208,7 @@
 
 #ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
 struct pt_regs;
-extern int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs);
+extern int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs, void *cookie);
 #endif
 
 #endif /* __KERNEL__ */
diff -Nru a/include/linux/spinlock.h b/include/linux/spinlock.h
--- a/include/linux/spinlock.h	Fri Feb 14 15:53:10 2003
+++ b/include/linux/spinlock.h	Fri Feb 14 15:53:10 2003
@@ -179,6 +179,7 @@
 #define _raw_read_unlock(lock)	do { (void)(lock); } while(0)
 #define _raw_write_lock(lock)	do { (void)(lock); } while(0)
 #define _raw_write_unlock(lock)	do { (void)(lock); } while(0)
+#define _raw_write_trylock(lock) ({ (void)(lock); (1); })
 
 #endif /* !SMP */
 
diff -Nru a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
--- a/include/linux/sunrpc/clnt.h	Fri Feb 14 15:53:11 2003
+++ b/include/linux/sunrpc/clnt.h	Fri Feb 14 15:53:11 2003
@@ -79,6 +79,7 @@
 	unsigned int		nrvers;		/* number of versions */
 	struct rpc_version **	version;	/* version array */
 	struct rpc_stat *	stats;		/* statistics */
+	char *			pipe_dir_name;	/* path to rpc_pipefs dir */
 };
 
 struct rpc_version {
diff -Nru a/include/net/af_unix.h b/include/net/af_unix.h
--- a/include/net/af_unix.h	Fri Feb 14 15:53:12 2003
+++ b/include/net/af_unix.h	Fri Feb 14 15:53:12 2003
@@ -13,9 +13,30 @@
 
 extern atomic_t unix_tot_inflight;
 
+static inline unix_socket *first_unix_socket(int *i)
+{
+	for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) {
+		if (unix_socket_table[*i])
+			return unix_socket_table[*i];
+	}
+	return NULL;
+}
 
-#define forall_unix_sockets(i, s) for (i=0; i<=UNIX_HASH_SIZE; i++) \
-                                    for (s=unix_socket_table[i]; s; s=s->next)
+static inline unix_socket *next_unix_socket(int *i, unix_socket *s)
+{
+	/* More in this chain? */
+	if (s->next)
+		return s->next;
+	/* Look for next non-empty chain. */
+	for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
+		if (unix_socket_table[*i])
+			return unix_socket_table[*i];
+	}
+	return NULL;
+}
+
+#define forall_unix_sockets(i, s) \
+	for (s = first_unix_socket(&(i)); s; s = next_unix_socket(&(i),(s)))
 
 struct unix_address
 {
diff -Nru a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h
--- a/include/net/irda/irda_device.h	Fri Feb 14 15:53:12 2003
+++ b/include/net/irda/irda_device.h	Fri Feb 14 15:53:12 2003
@@ -173,12 +173,33 @@
 
 	__u8 *head;	      /* start of buffer */
 	__u8 *data;	      /* start of data in buffer */
-	__u8 *tail;           /* end of data in buffer */
 
-	int len;	      /* length of data */
-	int truesize;	      /* total size of buffer */
+	int len;	      /* current length of data */
+	int truesize;	      /* total allocated size of buffer */
 	__u16 fcs;
+
+	struct sk_buff *skb;	/* ZeroCopy Rx in async_unwrap_char() */
 } iobuff_t;
+
+/* Maximum SIR frame (skb) that we expect to receive *unwrapped*.
+ * Max LAP MTU (I field) is 2048 bytes max (IrLAP 1.1, chapt 6.6.5, p40).
+ * Max LAP header is 2 bytes (for now).
+ * Max CRC is 2 bytes at SIR, 4 bytes at FIR. 
+ * Need 1 byte for skb_reserve() to align IP header for IrLAN.
+ * Add a few extra bytes just to be safe (buffer is power of two anyway)
+ * Jean II */
+#define IRDA_SKB_MAX_MTU	2064
+/* Maximum SIR frame that we expect to send, wrapped (i.e. with XBOFS
+ * and escaped characters on top of above). */
+#define IRDA_SIR_MAX_FRAME	4269
+
+/* The SIR unwrapper async_unwrap_char() will use a Rx-copy-break mechanism
+ * when using the optional ZeroCopy Rx, where only small frames are memcpy
+ * to a smaller skb to save memory. This is the thresold under which copy
+ * will happen (and over which it won't happen).
+ * Some FIR drivers may use this #define as well...
+ * This is the same value as various Ethernet drivers. - Jean II */
+#define IRDA_RX_COPY_THRESHOLD  256
 
 /* Function prototypes */
 int  irda_device_init(void);
diff -Nru a/include/net/irda/wrapper.h b/include/net/irda/wrapper.h
--- a/include/net/irda/wrapper.h	Fri Feb 14 15:53:10 2003
+++ b/include/net/irda/wrapper.h	Fri Feb 14 15:53:10 2003
@@ -52,8 +52,6 @@
 
 /* Proto definitions */
 int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize);
-void async_bump(struct net_device *dev, struct net_device_stats *stats,
-		__u8 *buf, int len);
 void async_unwrap_char(struct net_device *dev, struct net_device_stats *stats,
 		       iobuff_t *buf, __u8 byte);
 
diff -Nru a/include/net/sctp/command.h b/include/net/sctp/command.h
--- a/include/net/sctp/command.h	Fri Feb 14 15:53:12 2003
+++ b/include/net/sctp/command.h	Fri Feb 14 15:53:12 2003
@@ -1,34 +1,34 @@
 /* SCTP kernel reference Implementation Copyright (C) 1999-2001
  * Cisco, Motorola, and IBM
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
+ *
  * These are the definitions needed for the command object.
- * 
- * The SCTP reference implementation  is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation  is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * the SCTP reference implementation  is distributed in the hope that it 
+ *
+ * the SCTP reference implementation  is distributed in the hope that it
  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
  *                 ************************
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to one of the
  * following email addresses:
- * 
+ *
  * La Monte H.P. Yarroll <piggy@acm.org>
  * Karl Knutson <karl@athena.chicago.il.us>
  * Ardelle Fan <ardelle.fan@intel.com>
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
@@ -69,11 +69,11 @@
 	SCTP_CMD_INIT_FAILED,   /* High level, do init failure work. */
 	SCTP_CMD_REPORT_DUP,	/* Report a duplicate TSN.  */
 	SCTP_CMD_REPORT_BIGGAP, /* Narc on a TSN (it was too high).  */
-	SCTP_CMD_SET_BIND_ADDR, /* Set the association bind_addr.  */
 	SCTP_CMD_STRIKE,	/* Mark a strike against a transport.  */
 	SCTP_CMD_TRANSMIT,      /* Transmit the outqueue. */
-	SCTP_CMD_HB_TIMERS_START,    /* Start the heartbeat timers.  */
-	SCTP_CMD_HB_TIMERS_UPDATE,   /* Update the heartbeat timers.  */
+	SCTP_CMD_HB_TIMERS_START,    /* Start the heartbeat timers. */
+	SCTP_CMD_HB_TIMER_UPDATE,    /* Update a heartbeat timers.  */
+	SCTP_CMD_HB_TIMERS_STOP,     /* Stop the heartbeat timers.  */
 	SCTP_CMD_TRANSPORT_RESET,    /* Reset the status of a transport. */
 	SCTP_CMD_TRANSPORT_ON,       /* Mark the transport as active. */
 	SCTP_CMD_REPORT_ERROR,   /* Pass this error back out of the sm. */
@@ -112,7 +112,7 @@
 	void *ptr;
 	sctp_chunk_t *chunk;
 	sctp_association_t *asoc;
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 	sctp_bind_addr_t  *bp;
 	sctp_init_chunk_t *init;
 	sctp_ulpevent_t *ulpevent;
@@ -160,7 +160,7 @@
 SCTP_ARG_CONSTRUCTOR(PTR,	void *, ptr)
 SCTP_ARG_CONSTRUCTOR(CHUNK,	sctp_chunk_t *, chunk)
 SCTP_ARG_CONSTRUCTOR(ASOC,	sctp_association_t *, asoc)
-SCTP_ARG_CONSTRUCTOR(TRANSPORT,	sctp_transport_t *, transport)
+SCTP_ARG_CONSTRUCTOR(TRANSPORT,	struct sctp_transport *, transport)
 SCTP_ARG_CONSTRUCTOR(BA,	sctp_bind_addr_t *, bp)
 SCTP_ARG_CONSTRUCTOR(PEER_INIT,	sctp_init_chunk_t *, init)
 SCTP_ARG_CONSTRUCTOR(ULPEVENT,  sctp_ulpevent_t *, ulpevent)
diff -Nru a/include/net/sctp/constants.h b/include/net/sctp/constants.h
--- a/include/net/sctp/constants.h	Fri Feb 14 15:53:09 2003
+++ b/include/net/sctp/constants.h	Fri Feb 14 15:53:09 2003
@@ -3,33 +3,33 @@
  * Copyright (c) 1999-2001 Motorola, Inc.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001-2002 International Business Machines Corp.
- * 
+ *
  * This file is part of the SCTP kernel reference Implementation
- * 
+ *
  * This file is part of the implementation of the add-IP extension,
  * based on <draft-ietf-tsvwg-addip-sctp-02.txt> June 29, 2001,
  * for the SCTP kernel reference Implementation.
- * 
- * The SCTP reference implementation  is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ *
+ * The SCTP reference implementation  is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * the SCTP reference implementation  is distributed in the hope that it 
+ *
+ * the SCTP reference implementation  is distributed in the hope that it
  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  *                 ************************
  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
+ * Boston, MA 02111-1307, USA.
+ *
  * Please send any bug reports or fixes you make to one of the following email
  * addresses:
- * 
+ *
  * La Monte H.P. Yarroll <piggy@acm.org>
  * Karl Knutson <karl@athena.chicago.il.us>
  * Randall Stewart <randall@stewart.chicago.il.us>
@@ -38,14 +38,14 @@
  * Xingang Guo <xingang.guo@intel.com>
  * Sridhar Samudrala <samudrala@us.ibm.com>
  * Daisy Chang <daisyc@us.ibm.com>
- * 
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
- * 
+ *
  * There are still LOTS of bugs in this code... I always run on the motto
  * "it is a wonder any code ever works :)"
- * 
- * 
+ *
+ *
  */
 
 #ifndef __sctp_constants_h__
@@ -56,17 +56,10 @@
 #include <linux/ipv6.h> /* For ipv6hdr. */
 #include <net/sctp/user.h>
 
-/* What a hack!  Jiminy Cricket!  */
-enum { SCTP_MAX_STREAM = 10 };
-
-/* Define the amount of space to reserve for SCTP, IP, LL.
- * There is a little bit of waste that we are always allocating
- * for ipv6 headers, but this seems worth the simplicity.
- */
-
-#define SCTP_IP_OVERHEAD ((sizeof(struct sctphdr)\
-                          + sizeof(struct ipv6hdr)\
-                          + MAX_HEADER))
+/* Value used for stream negotiation. */
+enum { SCTP_MAX_STREAM = 0xffff };
+enum { SCTP_DEFAULT_OUTSTREAMS = 10 };
+enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM };
 
 /* Define the amount of space to reserve for SCTP, IP, LL.
  * There is a little bit of waste that we are always allocating
@@ -105,57 +98,37 @@
  */
 
 typedef enum {
-
 	SCTP_EVENT_TIMEOUT_NONE = 0,
 	SCTP_EVENT_TIMEOUT_T1_COOKIE,
 	SCTP_EVENT_TIMEOUT_T1_INIT,
 	SCTP_EVENT_TIMEOUT_T2_SHUTDOWN,
 	SCTP_EVENT_TIMEOUT_T3_RTX,
-	SCTP_EVENT_TIMEOUT_T4_RTO,
 	SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD,
 	SCTP_EVENT_TIMEOUT_HEARTBEAT,
 	SCTP_EVENT_TIMEOUT_SACK,
 	SCTP_EVENT_TIMEOUT_AUTOCLOSE,
-	SCTP_EVENT_TIMEOUT_PMTU_RAISE,
-
 } sctp_event_timeout_t;
 
-#define SCTP_EVENT_TIMEOUT_MAX		SCTP_EVENT_TIMEOUT_PMTU_RAISE
+#define SCTP_EVENT_TIMEOUT_MAX		SCTP_EVENT_TIMEOUT_AUTOCLOSE
 #define SCTP_NUM_TIMEOUT_TYPES		(SCTP_EVENT_TIMEOUT_MAX + 1)
 
 typedef enum {
-
 	SCTP_EVENT_NO_PENDING_TSN = 0,
-	SCTP_EVENT_ICMP_UNREACHFRAG,
-
 } sctp_event_other_t;
 
-#define SCTP_EVENT_OTHER_MAX		SCTP_EVENT_ICMP_UNREACHFRAG
+#define SCTP_EVENT_OTHER_MAX		SCTP_EVENT_NO_PENDING_TSN
 #define SCTP_NUM_OTHER_TYPES		(SCTP_EVENT_OTHER_MAX + 1)
 
 /* These are primitive requests from the ULP.  */
 typedef enum {
-
-	SCTP_PRIMITIVE_INITIALIZE = 0,
-	SCTP_PRIMITIVE_ASSOCIATE,
+	SCTP_PRIMITIVE_ASSOCIATE = 0,
 	SCTP_PRIMITIVE_SHUTDOWN,
 	SCTP_PRIMITIVE_ABORT,
 	SCTP_PRIMITIVE_SEND,
-	SCTP_PRIMITIVE_SETPRIMARY,
-	SCTP_PRIMITIVE_RECEIVE,
-	SCTP_PRIMITIVE_STATUS,
-	SCTP_PRIMITIVE_CHANGEHEARTBEAT,
 	SCTP_PRIMITIVE_REQUESTHEARTBEAT,
-	SCTP_PRIMITIVE_GETSRTTREPORT,
-	SCTP_PRIMITIVE_SETFAILURETHRESHOLD,
-	SCTP_PRIMITIVE_SETPROTOPARAMETERS,
-	SCTP_PRIMITIVE_RECEIVE_UNSENT,
-	SCTP_PRIMITIVE_RECEIVE_UNACKED,
-	SCTP_PRIMITIVE_DESTROY,
-
 } sctp_event_primitive_t;
 
-#define SCTP_EVENT_PRIMITIVE_MAX	SCTP_PRIMITIVE_DESTROY
+#define SCTP_EVENT_PRIMITIVE_MAX	SCTP_PRIMITIVE_REQUESTHEARTBEAT
 #define SCTP_NUM_PRIMITIVE_TYPES	(SCTP_EVENT_PRIMITIVE_MAX + 1)
 
 /* We define here a utility type for manipulating subtypes.
@@ -268,8 +241,13 @@
 #define SCTP_ADDR_REACHABLE		2
 #define SCTP_ADDR_NOT_REACHABLE		1
 
+/* Maximum chunk length considering padding requirements. */
+enum { SCTP_MAX_CHUNK_LEN = ((1<<16) - sizeof(__u32)) };
 
-
+/* Encourage Cookie-Echo bundling by pre-fragmenting chunks a little
+ * harder (until reaching ESTABLISHED state).
+ */
+enum { SCTP_ARBITRARY_COOKIE_ECHO_LEN = 200 };
 
 /* Guess at how big to make the TSN mapping array.
  * We guarantee that we can handle at least this big a gap between the
@@ -289,7 +267,8 @@
  * is enough room for 131 duplicate reports.  Round down to the
  * nearest power of 2.
  */
-#define SCTP_MAX_DUP_TSNS 128
+enum { SCTP_MIN_PMTU = 576 };
+enum { SCTP_MAX_DUP_TSNS = 128 };
 
 typedef enum {
 	SCTP_COUNTER_INIT_ERROR,
@@ -298,7 +277,6 @@
 /* How many counters does an association need? */
 #define SCTP_NUMBER_COUNTERS	5
 
-
 /* Here we define the default timers.  */
 
 /* cookie timer def = ? seconds */
@@ -317,10 +295,6 @@
 #define SCTP_DEFAULT_TIMEOUT_SACK	((200 * HZ) / 1000)
 #define SCTP_DEFAULT_TIMEOUT_SACK_MAX	((500 * HZ) / 1000) /* 500 ms */
 
-/* How long do we wait before attempting to raise the PMTU?  */
-#define SCTP_DEFAULT_TIMEOUT_PMTU_RAISE (10 * 60 * HZ) /* 10 Minutes */
-#define SCTP_DEFAULT_TIMEOUT_PMTU_RAISE_MIN (10 * 60 * HZ) /* 10 Minutes */
-
 /* RTO.Initial              - 3  seconds
  * RTO.Min                  - 1  second
  * RTO.Max                  - 60 seconds
@@ -439,6 +413,13 @@
 #define SCTP_ADDR6_PEERSUPP	0x00000004	/* IPv6 address is supported by
 						   peer */
 
+/* Reasons to retransmit. */
+typedef enum {
+	SCTP_RETRANSMIT_T3_RTX,
+	SCTP_RETRANSMIT_FAST_RTX,
+	SCTP_RETRANSMIT_PMTU_DISCOVERY,
+} sctp_retransmit_reason_t;
+
 /* Reasons to lower cwnd. */
 typedef enum {
 	SCTP_LOWER_CWND_T3_RTX,
@@ -448,4 +429,3 @@
 } sctp_lower_cwnd_t;
 
 #endif /* __sctp_constants_h__ */
-
diff -Nru a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
--- a/include/net/sctp/sctp.h	Fri Feb 14 15:53:09 2003
+++ b/include/net/sctp/sctp.h	Fri Feb 14 15:53:09 2003
@@ -1,8 +1,8 @@
 /* SCTP kernel reference Implementation
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2002 International Business Machines, Corp.
- * Copyright (c) 2001 Intel Corp.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
+ * Copyright (c) 2001-2003 Intel Corp.
  *
  * This file is part of the SCTP kernel reference Implementation
  *
@@ -36,7 +36,9 @@
  *    La Monte H.P. Yarroll <piggy@acm.org>
  *    Xingang Guo           <xingang.guo@intel.com>
  *    Jon Grimm             <jgrimm@us.ibm.com>
- *    Daisy Chang	    <daisyc@us.ibm.com>
+ *    Daisy Chang           <daisyc@us.ibm.com>
+ *    Sridhar Samudrala     <sri@us.ibm.com>
+ *    Ardelle Fan           <ardelle.fan@intel.com>
  *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
@@ -147,7 +149,9 @@
 /*
  * sctp_crc32c.c
  */
-extern __u32 count_crc(__u8 *ptr, __u16 count);
+extern __u32 sctp_start_cksum(__u8 *ptr, __u16 count);
+extern __u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 cksum);
+extern __u32 sctp_end_cksum(__u32 cksum);
 
 /*
  * sctp_input.c
@@ -162,6 +166,9 @@
 extern void __sctp_hash_endpoint(sctp_endpoint_t *);
 extern void sctp_unhash_endpoint(sctp_endpoint_t *);
 extern void __sctp_unhash_endpoint(sctp_endpoint_t *);
+extern sctp_association_t *__sctp_lookup_association(const union sctp_addr *,
+						     const union sctp_addr *,
+						     struct sctp_transport **);
 
 /*
  * sctp_hashdriver.c
@@ -266,6 +273,7 @@
 extern atomic_t sctp_dbg_objcnt_chunk;
 extern atomic_t sctp_dbg_objcnt_bind_addr;
 extern atomic_t sctp_dbg_objcnt_addr;
+extern atomic_t sctp_dbg_objcnt_ssnmap;
 
 /* Macros to atomically increment/decrement objcnt counters.  */
 #define SCTP_DBG_OBJCNT_INC(name) \
@@ -416,6 +424,23 @@
 	}
 
 	return retval;
+}
+
+/* Generate a random jitter in the range of -50% ~ +50% of input RTO. */
+static inline __s32 sctp_jitter(__u32 rto)
+{
+	static __u32 sctp_rand;
+	__s32 ret;
+
+	sctp_rand += jiffies;
+	sctp_rand ^= (sctp_rand << 12);
+	sctp_rand ^= (sctp_rand >> 20);
+
+	/* Choose random number from 0 to rto, then move to -50% ~ +50% 
+	 * of rto. 
+	 */
+	ret = sctp_rand % rto - (rto >> 1);
+	return ret;
 }
 
 /* Walk through a list of TLV parameters.  Don't trust the
diff -Nru a/include/net/sctp/sm.h b/include/net/sctp/sm.h
--- a/include/net/sctp/sm.h	Fri Feb 14 15:53:09 2003
+++ b/include/net/sctp/sm.h	Fri Feb 14 15:53:09 2003
@@ -256,7 +256,7 @@
 				   const sctp_chunk_t *,
 				   const struct msghdr *);
 sctp_chunk_t *sctp_make_heartbeat(const sctp_association_t *,
-				  const sctp_transport_t *,
+				  const struct sctp_transport *,
 				  const void *payload,
 				  const size_t paylen);
 sctp_chunk_t *sctp_make_heartbeat_ack(const sctp_association_t *,
@@ -269,6 +269,11 @@
 				 const void *payload,
 				 size_t paylen);
 void sctp_chunk_assign_tsn(sctp_chunk_t *);
+void sctp_chunk_assign_ssn(sctp_chunk_t *);
+int sctp_datachunks_from_user(sctp_association_t *,
+			      const struct sctp_sndrcvinfo *,
+			      struct msghdr *, int len,
+			      struct sk_buff_head *);
 
 
 /* Prototypes for statetable processing. */
diff -Nru a/include/net/sctp/structs.h b/include/net/sctp/structs.h
--- a/include/net/sctp/structs.h	Fri Feb 14 15:53:12 2003
+++ b/include/net/sctp/structs.h	Fri Feb 14 15:53:12 2003
@@ -42,7 +42,7 @@
  *    Sridhar Samudrala     <sri@us.ibm.com>
  *    Daisy Chang	    <daisyc@us.ibm.com>
  *    Dajiang Zhang         <dajiang.zhang@nokia.com>
- *    Ardelle Fan           <ardelle.fan@intel.com> 
+ *    Ardelle Fan           <ardelle.fan@intel.com>
  *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
@@ -104,27 +104,26 @@
 
 
 /* Forward declarations for data structures. */
-struct SCTP_protocol;
+struct sctp_protocol;
 struct SCTP_endpoint;
 struct SCTP_association;
-struct SCTP_transport;
+struct sctp_transport;
 struct SCTP_packet;
 struct SCTP_chunk;
 struct SCTP_inqueue;
-struct SCTP_outqueue;
+struct sctp_outq;
 struct SCTP_bind_addr;
+struct sctp_ulpq;
 struct sctp_opt;
 struct sctp_endpoint_common;
+struct sctp_ssnmap;
 
-
-typedef struct SCTP_protocol sctp_protocol_t;
+typedef struct sctp_protocol sctp_protocol_t;
 typedef struct SCTP_endpoint sctp_endpoint_t;
 typedef struct SCTP_association sctp_association_t;
-typedef struct SCTP_transport sctp_transport_t;
 typedef struct SCTP_packet sctp_packet_t;
 typedef struct SCTP_chunk sctp_chunk_t;
 typedef struct SCTP_inqueue sctp_inqueue_t;
-typedef struct SCTP_outqueue sctp_outqueue_t;
 typedef struct SCTP_bind_addr sctp_bind_addr_t;
 typedef struct sctp_opt sctp_opt_t;
 typedef struct sctp_endpoint_common sctp_endpoint_common_t;
@@ -133,7 +132,6 @@
 #include <net/sctp/ulpevent.h>
 #include <net/sctp/ulpqueue.h>
 
-
 /* Structures useful for managing bind/connect. */
 
 typedef struct sctp_bind_bucket {
@@ -157,7 +155,7 @@
 
 
 /* The SCTP protocol structure. */
-struct SCTP_protocol {
+struct sctp_protocol {
 	/* RFC2960 Section 14. Suggested SCTP Protocol Parameter Values
 	 *
 	 * The following protocol parameters are RECOMMENDED:
@@ -183,8 +181,8 @@
 
 	/* Valid.Cookie.Life        - 60  seconds  */
 	int valid_cookie_life;
-	
-	/* Whether Cookie Preservative is enabled(1) or not(0) */ 
+
+	/* Whether Cookie Preservative is enabled(1) or not(0) */
 	int cookie_preserve_enable;
 
 	/* Association.Max.Retrans  - 10 attempts
@@ -239,7 +237,9 @@
  * (i.e. things that depend on the address family.)
  */
 struct sctp_af {
-	int		(*queue_xmit)	(struct sk_buff *skb);
+	int		(*sctp_xmit)	(struct sk_buff *skb,
+					 struct sctp_transport *,
+					 int ipfragok);
 	int 		(*setsockopt)	(struct sock *sk,
 					 int level,
 					 int optname,
@@ -250,12 +250,18 @@
 					 int optname,
 					 char *optval,
 					 int *optlen);
-	struct dst_entry *(*get_dst)	(union sctp_addr *daddr,
+	struct dst_entry *(*get_dst)	(sctp_association_t *asoc,
+					 union sctp_addr *daddr,
 					 union sctp_addr *saddr);
+	void 		(*get_saddr)	(sctp_association_t *asoc,
+					 struct dst_entry *dst,
+					 union sctp_addr *daddr,
+				 	 union sctp_addr *saddr);	 
 	void            (*copy_addrlist) (struct list_head *,
 					  struct net_device *);
 	void            (*dst_saddr)    (union sctp_addr *saddr,
-					 struct dst_entry *dst);
+					 struct dst_entry *dst,
+					 unsigned short port);
 	int             (*cmp_addr)     (const union sctp_addr *addr1,
 					 const union sctp_addr *addr2);
 	void            (*addr_copy)    (union sctp_addr *dst,
@@ -282,7 +288,7 @@
 int sctp_register_af(struct sctp_af *);
 
 /* Protocol family functions. */
-typedef struct sctp_pf {
+struct sctp_pf {
 	void (*event_msgname)(sctp_ulpevent_t *, char *, int *);
 	void (*skb_msgname)  (struct sk_buff *, char *, int *);
 	int  (*af_supported) (sa_family_t);
@@ -291,7 +297,7 @@
 			  struct sctp_opt *);
 	int  (*bind_verify) (struct sctp_opt *, union sctp_addr *);
 	struct sctp_af *af;
-} sctp_pf_t;
+};
 
 /* SCTP Socket type: UDP or TCP style. */
 typedef enum {
@@ -318,7 +324,7 @@
 	__u32 autoclose;
 	__u8 nodelay;
 	__u8 disable_fragments;
-	sctp_pf_t *pf;
+	struct sctp_pf *pf;
 };
 
 
@@ -360,7 +366,8 @@
         struct timeval expiration;
 
 	/* Number of inbound/outbound streams which are set
-	 * and negotiated during the INIT process. */
+	 * and negotiated during the INIT process.
+	 */
 	__u16 sinit_num_ostreams;
 	__u16 sinit_max_instreams;
 
@@ -426,6 +433,49 @@
 	unsigned long sent_at;
 } sctp_sender_hb_info_t __attribute__((packed));
 
+/*
+ *  RFC 2960 1.3.2 Sequenced Delivery within Streams
+ *
+ *  The term "stream" is used in SCTP to refer to a sequence of user
+ *  messages that are to be delivered to the upper-layer protocol in
+ *  order with respect to other messages within the same stream.  This is
+ *  in contrast to its usage in TCP, where it refers to a sequence of
+ *  bytes (in this document a byte is assumed to be eight bits).
+ *  ...
+ *
+ *  This is the structure we use to track both our outbound and inbound
+ *  SSN, or Stream Sequence Numbers.
+ */
+
+struct sctp_stream {
+	__u16 *ssn;
+	unsigned int len;
+};
+
+struct sctp_ssnmap {
+	struct sctp_stream in;
+	struct sctp_stream out;
+	int malloced;
+};
+
+struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *, __u16, __u16);
+struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, int priority);
+void sctp_ssnmap_free(struct sctp_ssnmap *map);
+void sctp_ssnmap_clear(struct sctp_ssnmap *map);
+
+/* What is the current SSN number for this stream? */
+static inline __u16 sctp_ssn_peek(struct sctp_stream *stream, __u16 id)
+{
+	return stream->ssn[id];
+}
+
+/* Return the next SSN number for this stream.  */
+static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id)
+{
+	return stream->ssn[id]++;
+}
+
+
 /* RFC2960 1.4 Key Terms
  *
  * o Chunk: A unit of information within an SCTP packet, consisting of
@@ -499,6 +549,7 @@
 	__u8 rtt_in_progress;  /* Is this chunk used for RTT calculation? */
 	__u8 num_times_sent;   /* How man times did we send this? */
 	__u8 has_tsn;          /* Does this chunk have a TSN yet? */
+	__u8 has_ssn;          /* Does this chunk have a SSN yet? */
 	__u8 singleton;        /* Was this the only chunk in the packet? */
 	__u8 end_of_packet;    /* Was this the last chunk in the packet? */
 	__u8 ecn_ce_done;      /* Have we processed the ECN CE bit? */
@@ -516,15 +567,13 @@
 	 * For an outbound chunk, it tells us where we'd like it to
 	 * go.  It is NULL if we have no preference.
 	 */
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 };
 
 sctp_chunk_t *sctp_make_chunk(const sctp_association_t *, __u8 type,
 			      __u8 flags, int size);
 void sctp_free_chunk(sctp_chunk_t *);
-sctp_chunk_t *sctp_copy_chunk(sctp_chunk_t *, int flags);
 void  *sctp_addto_chunk(sctp_chunk_t *chunk, int len, const void *data);
-int sctp_user_addto_chunk(sctp_chunk_t *chunk, int len, struct iovec *data);
 sctp_chunk_t *sctp_chunkify(struct sk_buff *, const sctp_association_t *,
 			    struct sock *);
 void sctp_init_addrs(sctp_chunk_t *, union sctp_addr *, union sctp_addr *);
@@ -560,7 +609,7 @@
 	 * The function we finally use to pass down to the next lower
 	 * layer lives in the transport structure.
 	 */
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 
 	/* Allow a callback for getting a high priority chunk
 	 * bundled early into the packet (This is used for ECNE).
@@ -575,30 +624,33 @@
 	/* This packet contains a COOKIE-ECHO chunk. */
 	int has_cookie_echo;
 
+	/* SCTP cannot fragment this packet. So let ip fragment it. */
+	int ipfragok;
+
 	int malloced;
 };
 
-typedef int (sctp_outqueue_thandler_t)(sctp_outqueue_t *, void *);
-typedef int (sctp_outqueue_ehandler_t)(sctp_outqueue_t *);
-typedef sctp_packet_t *(sctp_outqueue_ohandler_init_t)
+typedef int (sctp_outq_thandler_t)(struct sctp_outq *, void *);
+typedef int (sctp_outq_ehandler_t)(struct sctp_outq *);
+typedef sctp_packet_t *(sctp_outq_ohandler_init_t)
 	(sctp_packet_t *,
-         sctp_transport_t *,
+         struct sctp_transport *,
          __u16 sport,
          __u16 dport);
-typedef sctp_packet_t *(sctp_outqueue_ohandler_config_t)
+typedef sctp_packet_t *(sctp_outq_ohandler_config_t)
         (sctp_packet_t *,
 	 __u32 vtag,
 	 int ecn_capable,
 	 sctp_packet_phandler_t *get_prepend_chunk);
-typedef sctp_xmit_t (sctp_outqueue_ohandler_t)(sctp_packet_t *,
+typedef sctp_xmit_t (sctp_outq_ohandler_t)(sctp_packet_t *,
                                                sctp_chunk_t *);
-typedef int (sctp_outqueue_ohandler_force_t)(sctp_packet_t *);
+typedef int (sctp_outq_ohandler_force_t)(sctp_packet_t *);
 
-sctp_outqueue_ohandler_init_t    sctp_packet_init;
-sctp_outqueue_ohandler_config_t  sctp_packet_config;
-sctp_outqueue_ohandler_t         sctp_packet_append_chunk;
-sctp_outqueue_ohandler_t         sctp_packet_transmit_chunk;
-sctp_outqueue_ohandler_force_t   sctp_packet_transmit;
+sctp_outq_ohandler_init_t    sctp_packet_init;
+sctp_outq_ohandler_config_t  sctp_packet_config;
+sctp_outq_ohandler_t         sctp_packet_append_chunk;
+sctp_outq_ohandler_t         sctp_packet_transmit_chunk;
+sctp_outq_ohandler_force_t   sctp_packet_transmit;
 void sctp_packet_free(sctp_packet_t *);
 
 
@@ -622,7 +674,7 @@
  *      period.
  *
  */
-struct SCTP_transport {
+struct sctp_transport {
 	/* A list of transports. */
 	struct list_head transports;
 
@@ -692,6 +744,8 @@
 
 	/* Destination */
 	struct dst_entry *dst;
+	/* Source address. */
+	union sctp_addr saddr;
 
 	/* When was the last time(in jiffies) that a data packet was sent on
 	 * this transport?  This is used to adjust the cwnd when the transport
@@ -771,24 +825,26 @@
 	int malloced; /* Is this structure kfree()able? */
 };
 
-extern sctp_transport_t *sctp_transport_new(const union sctp_addr *, int);
-extern sctp_transport_t *sctp_transport_init(sctp_transport_t *,
-					     const union sctp_addr *, int);
-extern void sctp_transport_set_owner(sctp_transport_t *, sctp_association_t *);
-extern void sctp_transport_route(sctp_transport_t *, union sctp_addr *,
-				 struct sctp_opt *);
-extern void sctp_transport_free(sctp_transport_t *);
-extern void sctp_transport_destroy(sctp_transport_t *);
-extern void sctp_transport_reset_timers(sctp_transport_t *);
-extern void sctp_transport_hold(sctp_transport_t *);
-extern void sctp_transport_put(sctp_transport_t *);
-extern void sctp_transport_update_rto(sctp_transport_t *, __u32);
-extern void sctp_transport_raise_cwnd(sctp_transport_t *, __u32, __u32);
-extern void sctp_transport_lower_cwnd(sctp_transport_t *, sctp_lower_cwnd_t);
+struct sctp_transport *sctp_transport_new(const union sctp_addr *, int);
+struct sctp_transport *sctp_transport_init(struct sctp_transport *,
+					   const union sctp_addr *, int);
+void sctp_transport_set_owner(struct sctp_transport *, sctp_association_t *);
+void sctp_transport_route(struct sctp_transport *, union sctp_addr *,
+			  struct sctp_opt *);
+void sctp_transport_pmtu(struct sctp_transport *);
+void sctp_transport_free(struct sctp_transport *);
+void sctp_transport_destroy(struct sctp_transport *);
+void sctp_transport_reset_timers(struct sctp_transport *);
+void sctp_transport_hold(struct sctp_transport *);
+void sctp_transport_put(struct sctp_transport *);
+void sctp_transport_update_rto(struct sctp_transport *, __u32);
+void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32);
+void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t);
+unsigned long sctp_transport_timeout(struct sctp_transport *);
+
 
 /* This is the structure we use to queue packets as they come into
- * SCTP.  We write packets to it and read chunks from it.  It handles
- * fragment reassembly and chunk unbundling.
+ * SCTP.  We write packets to it and read chunks from it.
  */
 struct SCTP_inqueue {
 	/* This is actually a queue of sctp_chunk_t each
@@ -835,7 +891,7 @@
  *
  * When free()'d, it empties itself out via output_handler().
  */
-struct SCTP_outqueue {
+struct sctp_outq {
 	sctp_association_t *asoc;
 
 	/* BUG: This really should be an array of streams.
@@ -861,11 +917,11 @@
 	 * layer.  This is always SCTP_packet, but we separate the two
 	 * structures to make testing simpler.
 	 */
-	sctp_outqueue_ohandler_init_t	*init_output;
-	sctp_outqueue_ohandler_config_t	*config_output;
-	sctp_outqueue_ohandler_t	*append_output;
-	sctp_outqueue_ohandler_t	*build_output;
-	sctp_outqueue_ohandler_force_t	*force_output;
+	sctp_outq_ohandler_init_t	*init_output;
+	sctp_outq_ohandler_config_t	*config_output;
+	sctp_outq_ohandler_t	*append_output;
+	sctp_outq_ohandler_t	*build_output;
+	sctp_outq_ohandler_force_t	*force_output;
 
 	/* How many unackd bytes do we have in-flight?  */
 	__u32 outstanding_bytes;
@@ -877,24 +933,24 @@
 	int malloced;
 };
 
-sctp_outqueue_t *sctp_outqueue_new(sctp_association_t *);
-void sctp_outqueue_init(sctp_association_t *, sctp_outqueue_t *);
-void sctp_outqueue_teardown(sctp_outqueue_t *);
-void sctp_outqueue_free(sctp_outqueue_t*);
-void sctp_force_outqueue(sctp_outqueue_t *);
-int sctp_push_outqueue(sctp_outqueue_t *, sctp_chunk_t *chunk);
-int sctp_flush_outqueue(sctp_outqueue_t *, int);
-int sctp_sack_outqueue(sctp_outqueue_t *, sctp_sackhdr_t *);
-int sctp_outqueue_is_empty(const sctp_outqueue_t *);
-int sctp_outqueue_set_output_handlers(sctp_outqueue_t *,
-                                      sctp_outqueue_ohandler_init_t init,
-                                      sctp_outqueue_ohandler_config_t config,
-                                      sctp_outqueue_ohandler_t append,
-                                      sctp_outqueue_ohandler_t build,
-                                      sctp_outqueue_ohandler_force_t force);
-void sctp_outqueue_restart(sctp_outqueue_t *);
-void sctp_retransmit(sctp_outqueue_t *, sctp_transport_t *, __u8);
-void sctp_retransmit_mark(sctp_outqueue_t *, sctp_transport_t *, __u8);
+struct sctp_outq *sctp_outq_new(sctp_association_t *);
+void sctp_outq_init(sctp_association_t *, struct sctp_outq *);
+void sctp_outq_teardown(struct sctp_outq *);
+void sctp_outq_free(struct sctp_outq*);
+int sctp_outq_tail(struct sctp_outq *, sctp_chunk_t *chunk);
+int sctp_outq_flush(struct sctp_outq *, int);
+int sctp_outq_sack(struct sctp_outq *, sctp_sackhdr_t *);
+int sctp_outq_is_empty(const struct sctp_outq *);
+int sctp_outq_set_output_handlers(struct sctp_outq *,
+				  sctp_outq_ohandler_init_t init,
+				  sctp_outq_ohandler_config_t config,
+				  sctp_outq_ohandler_t append,
+				  sctp_outq_ohandler_t build,
+				  sctp_outq_ohandler_force_t force);
+void sctp_outq_restart(struct sctp_outq *);
+void sctp_retransmit(struct sctp_outq *, struct sctp_transport *,
+		     sctp_retransmit_reason_t);
+void sctp_retransmit_mark(struct sctp_outq *, struct sctp_transport *, __u8);
 
 
 /* These bind address data fields common between endpoints and associations */
@@ -1027,7 +1083,7 @@
 	/* These are the system-wide defaults and other stuff which is
 	 * endpoint-independent.
 	 */
-	sctp_protocol_t *proto;
+	struct sctp_protocol *proto;
 
 	/* Associations: A list of current associations and mappings
 	 *            to the data consumers for each association. This
@@ -1066,10 +1122,7 @@
 {
 	sctp_endpoint_t *ep;
 
-	/* We are not really a list, but the list_entry() macro is
-	 * really quite generic to find the address of an outter struct.
-	 */
-	ep = list_entry(base, sctp_endpoint_t, base);
+	ep = container_of(base, sctp_endpoint_t, base);
 	return ep;
 }
 
@@ -1083,7 +1136,7 @@
 void sctp_endpoint_add_asoc(sctp_endpoint_t *, sctp_association_t *asoc);
 sctp_association_t *sctp_endpoint_lookup_assoc(const sctp_endpoint_t *ep,
 					       const union sctp_addr *paddr,
-					       sctp_transport_t **);
+					       struct sctp_transport **);
 int sctp_endpoint_is_peeled_off(sctp_endpoint_t *, const union sctp_addr *);
 sctp_endpoint_t *sctp_endpoint_is_match(sctp_endpoint_t *,
 					const union sctp_addr *);
@@ -1184,7 +1237,7 @@
 		 * designate the connection we are currently using to
 		 * transmit new data and most control chunks.
 		 */
-		sctp_transport_t *primary_path;
+		struct sctp_transport *primary_path;
 
 		/* Cache the primary path address here, when we
 		 * need a an address for msg_name.
@@ -1195,7 +1248,7 @@
 		 *   The path that we are currently using to
 		 *   transmit new data and most control chunks.
 		 */
-		sctp_transport_t *active_path;
+		struct sctp_transport *active_path;
 
 		/* retran_path
 		 *
@@ -1207,13 +1260,13 @@
 		 * different from the last destination address to
 		 * which the DATA chunk was sent.
 		 */
-		sctp_transport_t *retran_path;
+		struct sctp_transport *retran_path;
 
 		/* Pointer to last transport I have sent on.  */
-		sctp_transport_t *last_sent_to;
+		struct sctp_transport *last_sent_to;
 
 		/* This is the last transport I have recieved DATA on.  */
-		sctp_transport_t *last_data_from;
+		struct sctp_transport *last_data_from;
 
 		/*
 		 * Mapping  An array of bits or bytes indicating which out of
@@ -1325,7 +1378,7 @@
 	struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES];
 
 	/* Transport to which SHUTDOWN chunk was last sent.  */
-	sctp_transport_t *shutdown_last_sent_to;
+	struct sctp_transport *shutdown_last_sent_to;
 
 	/* Next TSN    : The next TSN number to be assigned to a new
 	 *             : DATA chunk.  This is sent in the INIT or INIT
@@ -1408,18 +1461,15 @@
 	} defaults;
 
 	/* This tracks outbound ssn for a given stream.  */
-	__u16 ssn[SCTP_MAX_STREAM];
+	struct sctp_ssnmap *ssnmap;
 
 	/* All outbound chunks go through this structure.  */
-	sctp_outqueue_t outqueue;
+	struct sctp_outq outqueue;
 
 	/* A smart pipe that will handle reordering and fragmentation,
 	 * as well as handle passing events up to the ULP.
-	 * In the future, we should make this at least dynamic, if
-	 * not also some sparse structure.
 	 */
-	sctp_ulpqueue_t ulpq;
-	__u8 _ssnmap[sctp_ulpqueue_storage_size(SCTP_MAX_STREAM)];
+	struct sctp_ulpq ulpq;
 
 	/* Need to send an ECNE Chunk? */
 	int need_ecne;
@@ -1505,7 +1555,7 @@
 	 *
 	 *
 	 * [I really think this is EXACTLY the sort of intelligence
-	 *  which already resides in SCTP_outqueue.  Please move this
+	 *  which already resides in sctp_outq.  Please move this
 	 *  queue and its supporting logic down there.  --piggy]
 	 */
 	struct sk_buff_head addip_chunks;
@@ -1546,10 +1596,7 @@
 {
 	sctp_association_t *asoc;
 
-	/* We are not really a list, but the list_entry() macro is
-	 * really quite generic find the address of an outter struct.
-	 */
-	asoc = list_entry(base, sctp_association_t, base);
+	asoc = container_of(base, sctp_association_t, base);
 	return asoc;
 }
 
@@ -1567,24 +1614,33 @@
 void sctp_association_put(sctp_association_t *);
 void sctp_association_hold(sctp_association_t *);
 
-sctp_transport_t *sctp_assoc_choose_shutdown_transport(sctp_association_t *);
-sctp_transport_t *sctp_assoc_lookup_paddr(const sctp_association_t *,
+struct sctp_transport *sctp_assoc_choose_shutdown_transport(sctp_association_t *);
+struct sctp_transport *sctp_assoc_lookup_paddr(const sctp_association_t *,
 					  const union sctp_addr *);
-sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *,
+struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *,
 				     const union sctp_addr *address,
 				     const int priority);
-void sctp_assoc_control_transport(sctp_association_t *, sctp_transport_t *,
+void sctp_assoc_control_transport(sctp_association_t *,
+				  struct sctp_transport *,
 				  sctp_transport_cmd_t, sctp_sn_error_t);
-sctp_transport_t *sctp_assoc_lookup_tsn(sctp_association_t *, __u32);
-sctp_transport_t *sctp_assoc_is_match(sctp_association_t *,
-				      const union sctp_addr *,
-				      const union sctp_addr *);
+struct sctp_transport *sctp_assoc_lookup_tsn(sctp_association_t *, __u32);
+struct sctp_transport *sctp_assoc_is_match(sctp_association_t *,
+					   const union sctp_addr *,
+					   const union sctp_addr *);
 void sctp_assoc_migrate(sctp_association_t *, struct sock *);
 void sctp_assoc_update(sctp_association_t *dst, sctp_association_t *src);
 
 __u32 __sctp_association_get_next_tsn(sctp_association_t *);
 __u32 __sctp_association_get_tsn_block(sctp_association_t *, int);
 __u16 __sctp_association_get_next_ssn(sctp_association_t *, __u16 sid);
+
+void sctp_assoc_sync_pmtu(sctp_association_t *);
+void sctp_assoc_rwnd_increase(sctp_association_t *, int);
+void sctp_assoc_rwnd_decrease(sctp_association_t *, int);
+
+int sctp_assoc_set_bind_addr_from_ep(sctp_association_t *, int);
+int sctp_assoc_set_bind_addr_from_cookie(sctp_association_t *,
+					 sctp_cookie_t *, int);
 
 int sctp_cmp_addr_exact(const union sctp_addr *ss1,
 		        const union sctp_addr *ss2);
diff -Nru a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h
--- a/include/net/sctp/ulpqueue.h	Fri Feb 14 15:53:09 2003
+++ b/include/net/sctp/ulpqueue.h	Fri Feb 14 15:53:09 2003
@@ -1,39 +1,44 @@
 /* SCTP kernel reference Implementation
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001 International Business Machines, Corp.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
- * 
- * These are the definitions needed for the sctp_ulpqueue type.  The 
- * sctp_ulpqueue is the interface between the Upper Layer Protocol, or ULP,
+ *
+ * These are the definitions needed for the sctp_ulpq type.  The
+ * sctp_ulpq is the interface between the Upper Layer Protocol, or ULP,
  * and the core SCTP state machine.  This is the component which handles
- * reassembly and ordering.  
- * 
- * The SCTP reference implementation  is free software; 
- * you can redistribute it and/or modify it under the terms of 
+ * reassembly and ordering.
+ *
+ * The SCTP reference implementation  is free software;
+ * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
- * 
- * the SCTP reference implementation  is distributed in the hope that it 
+ *
+ * the SCTP reference implementation  is distributed in the hope that it
  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
  *                 ************************
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with GNU CC; see the file COPYING.  If not, write to
  * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.  
- * 
- * Please send any bug reports or fixes you make to one of the
- * following email addresses:
- * 
- * Jon Grimm <jgrimm@us.ibm.com>
- * La Monte H.P. Yarroll <piggy@acm.org>
- * 
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email addresses:
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ *   Jon Grimm             <jgrimm@us.ibm.com>
+ *   La Monte H.P. Yarroll <piggy@acm.org>
+ *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
  */
@@ -42,46 +47,26 @@
 #define __sctp_ulpqueue_h__
 
 /* A structure to carry information to the ULP (e.g. Sockets API) */
-typedef struct sctp_ulpqueue {
+struct sctp_ulpq {
 	int malloced;
-	spinlock_t lock;
 	sctp_association_t *asoc;
 	struct sk_buff_head reasm;
 	struct sk_buff_head lobby;
-	__u16 ssn[0];
-} sctp_ulpqueue_t;
-
-/* This macro assists in creation of external storage for variable length
- * internal buffers.
- */
-#define sctp_ulpqueue_storage_size(inbound) (sizeof(__u16) * (inbound))
-
-sctp_ulpqueue_t *sctp_ulpqueue_new(sctp_association_t *asoc,
-				   __u16 inbound,
-				   int priority);
-
-sctp_ulpqueue_t *sctp_ulpqueue_init(sctp_ulpqueue_t *ulpq,
-				    sctp_association_t *asoc,
-				    __u16 inbound);
-
-void sctp_ulpqueue_free(sctp_ulpqueue_t *);
+};
 
+/* Prototypes. */
+struct sctp_ulpq *sctp_ulpq_new(sctp_association_t *asoc, int priority);
+struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *, sctp_association_t *);
+void sctp_ulpq_free(struct sctp_ulpq *);
 
 /* Add a new DATA chunk for processing. */
-int sctp_ulpqueue_tail_data(sctp_ulpqueue_t *,
-			    sctp_chunk_t *chunk,
-			    int priority);
-
+int sctp_ulpq_tail_data(struct sctp_ulpq *, sctp_chunk_t *chunk, int priority);
 
 /* Add a new event for propogation to the ULP. */
-int sctp_ulpqueue_tail_event(sctp_ulpqueue_t *, 
-			     sctp_ulpevent_t *event);
-
+int sctp_ulpq_tail_event(struct sctp_ulpq *, struct sctp_ulpevent *ev);
 
 /* Is the ulpqueue empty. */
-int sctp_ulpqueue_is_empty(sctp_ulpqueue_t *);
-
-int sctp_ulpqueue_is_data_empty(sctp_ulpqueue_t *);
+int sctp_ulpqueue_is_empty(struct sctp_ulpq *);
 
 #endif /* __sctp_ulpqueue_h__ */
 
@@ -90,4 +75,4 @@
 
 
 
- 
+
diff -Nru a/include/net/sctp/user.h b/include/net/sctp/user.h
--- a/include/net/sctp/user.h	Fri Feb 14 15:53:08 2003
+++ b/include/net/sctp/user.h	Fri Feb 14 15:53:08 2003
@@ -100,6 +100,14 @@
 #define SCTP_SOCKOPT_BINDX_REM	SCTP_SOCKOPT_BINDX_REM
 	SCTP_SOCKOPT_PEELOFF, 	/* peel off association. */
 #define SCTP_SOCKOPT_PEELOFF	SCTP_SOCKOPT_PEELOFF
+	SCTP_GET_PEER_ADDRS_NUM, 	/* Get number of peer addresss. */
+#define SCTP_GET_PEER_ADDRS_NUM	SCTP_GET_PEER_ADDRS_NUM
+	SCTP_GET_PEER_ADDRS, 	/* Get all peer addresss. */
+#define SCTP_GET_PEER_ADDRS	SCTP_GET_PEER_ADDRS
+	SCTP_GET_LOCAL_ADDRS_NUM, 	/* Get number of local addresss. */
+#define SCTP_GET_LOCAL_ADDRS_NUM	SCTP_GET_LOCAL_ADDRS_NUM
+	SCTP_GET_LOCAL_ADDRS, 	/* Get all local addresss. */
+#define SCTP_GET_LOCAL_ADDRS	SCTP_GET_LOCAL_ADDRS
 };
 
 
@@ -576,6 +584,15 @@
 	__u16		ssto_streamid_end;
 };
 
+/*
+ * 8.3 8.5 get all peer/local addresses on a socket
+ * This parameter struct is for getsockopt
+ */
+struct sctp_getaddrs {
+	sctp_assoc_t            assoc_id;
+	int			addr_num;
+	struct sockaddr_storage *addrs;
+};
 
 /* These are bit fields for msghdr->msg_flags.  See section 5.1.  */
 /* On user space Linux, these live in <bits/socket.h> as an enum.  */
diff -Nru a/include/net/xfrm.h b/include/net/xfrm.h
--- a/include/net/xfrm.h	Fri Feb 14 15:53:12 2003
+++ b/include/net/xfrm.h	Fri Feb 14 15:53:12 2003
@@ -8,6 +8,7 @@
 #include <linux/netdevice.h>
 #include <linux/crypto.h>
 #include <linux/pfkeyv2.h>
+#include <linux/in6.h>
 
 #include <net/dst.h>
 #include <net/route.h>
@@ -423,5 +424,24 @@
 extern struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);
 extern struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name);
 extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name);
+
+static inline int
+xfrm6_selector_match(struct xfrm_selector *sel, struct flowi *fl)
+{
+      return  !memcmp(fl->fl6_dst, sel->daddr.a6, sizeof(struct in6_addr)) &&
+              !((fl->uli_u.ports.dport^sel->dport)&sel->dport_mask) &&
+              !((fl->uli_u.ports.sport^sel->sport)&sel->sport_mask) &&
+              (fl->proto == sel->proto || !sel->proto) &&
+              (fl->oif == sel->ifindex || !sel->ifindex) &&
+              !memcmp(fl->fl6_src, sel->saddr.a6, sizeof(struct in6_addr));
+}
+
+extern int xfrm6_register_type(struct xfrm_type *type);
+extern int xfrm6_unregister_type(struct xfrm_type *type);
+extern struct xfrm_type *xfrm6_get_type(u8 proto);
+
+extern struct xfrm_state *xfrm6_state_lookup(struct in6_addr *daddr, u32 spi, u8 proto);
+struct xfrm_state * xfrm6_find_acq(u8 mode, u16 reqid, u8 proto, struct in6_addr *daddr, struct in6_addr *saddr, int create);
+void xfrm6_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
 
 #endif	/* _NET_XFRM_H */
diff -Nru a/kernel/cpufreq.c b/kernel/cpufreq.c
--- a/kernel/cpufreq.c	Fri Feb 14 15:53:09 2003
+++ b/kernel/cpufreq.c	Fri Feb 14 15:53:09 2003
@@ -2,9 +2,9 @@
  *  linux/kernel/cpufreq.c
  *
  *  Copyright (C) 2001 Russell King
- *            (C) 2002 Dominik Brodowski <linux@brodo.de>
+ *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
  *
- *  $Id: cpufreq.c,v 1.50 2002/11/11 15:35:48 db Exp $
+ *  $Id: cpufreq.c,v 1.59 2003/01/20 17:31:48 db Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -34,7 +34,6 @@
 #include <linux/sysctl.h>
 #endif
 
-
 /**
  * The "cpufreq driver" - the arch- or hardware-dependend low
  * level driver of CPUFreq support, and its locking mutex. 
@@ -67,6 +66,9 @@
 static unsigned int     cpu_cur_freq[NR_CPUS];
 #endif
 
+LIST_HEAD(cpufreq_governor_list);
+
+static int cpufreq_governor(unsigned int cpu, unsigned int event);
 
 /*********************************************************************
  *                          SYSFS INTERFACE                          *
@@ -75,16 +77,31 @@
 /**
  * cpufreq_parse_governor - parse a governor string
  */
-static int cpufreq_parse_governor (char *str_governor, unsigned int *governor)
+static int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor)
 {
-	if (!strnicmp(str_governor, "performance", 11)) {
-		*governor = CPUFREQ_POLICY_PERFORMANCE;
+	if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
+		*policy = CPUFREQ_POLICY_PERFORMANCE;
 		return 0;
-	} else if (!strnicmp(str_governor, "powersave", 9)) {
-		*governor = CPUFREQ_POLICY_POWERSAVE;
+	} else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) {
+		*policy = CPUFREQ_POLICY_POWERSAVE;
 		return 0;
-	} else
-		return -EINVAL;
+	} else 	{
+		struct cpufreq_governor *t;
+		down(&cpufreq_driver_sem);
+		if (!cpufreq_driver || !cpufreq_driver->target)
+			goto out;
+		list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
+			if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) {
+				*governor = t;
+				*policy = CPUFREQ_POLICY_GOVERNOR;
+				up(&cpufreq_driver_sem);
+				return 0;
+			}
+		}
+	out:
+		up(&cpufreq_driver_sem);
+	}
+	return -EINVAL;
 }
 
 
@@ -171,6 +188,8 @@
 static ssize_t show_scaling_governor (struct device *dev, char *buf)
 {
 	unsigned int value = 0;
+	char value2[CPUFREQ_NAME_LEN];
+
 
 	if (!dev)
 		return 0;
@@ -178,6 +197,8 @@
 	down(&cpufreq_driver_sem);
 	if (cpufreq_driver)
 		value = cpufreq_driver->policy[to_cpu_nr(dev)].policy;
+	if (value == CPUFREQ_POLICY_GOVERNOR)
+		strncpy(value2, cpufreq_driver->policy[to_cpu_nr(dev)].governor->name, CPUFREQ_NAME_LEN);
 	up(&cpufreq_driver_sem);
 
 	switch (value) {
@@ -185,6 +206,8 @@
 		return sprintf(buf, "powersave\n");
 	case CPUFREQ_POLICY_PERFORMANCE:
 		return sprintf(buf, "performance\n");
+	case CPUFREQ_POLICY_GOVERNOR:
+		return sprintf(buf, "%s\n", value2);
 	}
 
 	return -EINVAL;
@@ -212,7 +235,7 @@
 	if (ret != 1)
 		return -EINVAL;
 
-	if (cpufreq_parse_governor(str_governor, &policy.policy))
+	if (cpufreq_parse_governor(str_governor, &policy.policy, &policy.governor))
 		return -EINVAL;
 
 	ret = cpufreq_set_policy(&policy);
@@ -241,6 +264,34 @@
 	return sprintf(buf, "%s\n", value);
 }
 
+/**
+ * show_available_govs - show the available CPUfreq governors
+ */
+static ssize_t show_available_govs(struct device *dev, char *buf)
+{
+	ssize_t i = 0;
+	struct cpufreq_governor *t;
+
+	if (!dev)
+		return 0;
+
+	i += sprintf(buf, "performance powersave");
+
+	down(&cpufreq_driver_sem);
+	if (!cpufreq_driver || !cpufreq_driver->target)
+		goto out;
+
+	list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
+		if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2)))
+			goto out;
+		i += snprintf(&buf[i], CPUFREQ_NAME_LEN, " %s", t->name);
+	}
+ out:
+	up(&cpufreq_driver_sem);
+	i += sprintf(&buf[i], "\n");
+	return i;
+}
+
 
 /**
  * cpufreq_per_cpu_attr_ro - read-only cpufreq per-CPU file
@@ -267,6 +318,7 @@
 
 static DEVICE_ATTR(scaling_governor, (S_IRUGO | S_IWUSR), show_scaling_governor, store_scaling_governor);
 static DEVICE_ATTR(scaling_driver, S_IRUGO, show_scaling_driver, NULL);
+static DEVICE_ATTR(available_scaling_governors, S_IRUGO, show_available_govs, NULL);
 
 
 /**
@@ -299,10 +351,12 @@
 	}
 
 	/* set default policy on this CPU */
-	policy.policy = cpufreq_driver->policy[cpu].policy;
-	policy.min    = cpufreq_driver->policy[cpu].min;
-	policy.max    = cpufreq_driver->policy[cpu].max;
-	policy.cpu    = cpu;
+	memcpy(&policy, 
+	       &cpufreq_driver->policy[cpu], 
+	       sizeof(struct cpufreq_policy));
+
+	if (cpufreq_driver->target)
+		cpufreq_governor(cpu, CPUFREQ_GOV_START);
 
 	up(&cpufreq_driver_sem);
 	ret = cpufreq_set_policy(&policy);
@@ -339,6 +393,7 @@
 	device_create_file (dev, &dev_attr_scaling_max_freq);
 	device_create_file (dev, &dev_attr_scaling_governor);
 	device_create_file (dev, &dev_attr_scaling_driver);
+	device_create_file (dev, &dev_attr_available_scaling_governors);
 
 	up(&cpufreq_driver_sem);
 	return ret;
@@ -356,6 +411,9 @@
 	struct device * dev = intf->dev;
 	unsigned int cpu = to_cpu_nr(dev);
 
+	if (cpufreq_driver->target)
+		cpufreq_governor(cpu, CPUFREQ_GOV_STOP);
+
 	if (cpufreq_driver->exit)
 		cpufreq_driver->exit(&cpufreq_driver->policy[cpu]);
 
@@ -364,7 +422,8 @@
 	device_remove_file (dev, &dev_attr_scaling_min_freq);
 	device_remove_file (dev, &dev_attr_scaling_max_freq);
 	device_remove_file (dev, &dev_attr_scaling_governor);
-	device_remove_file (dev, &dev_attr_scaling_governor);
+	device_remove_file (dev, &dev_attr_scaling_driver);
+	device_remove_file (dev, &dev_attr_available_scaling_governors);
 
 	return 0;
 }
@@ -443,12 +502,11 @@
 	return -EINVAL;
 
 scan_policy:
-	result = cpufreq_parse_governor(str_governor, &policy->policy);
+	result = cpufreq_parse_governor(str_governor, &policy->policy, &policy->governor);
 
 	return result;
 }
 
-
 /**
  * cpufreq_proc_read - read /proc/cpufreq
  *
@@ -477,7 +535,8 @@
 		if (!cpu_online(i))
 			continue;
 
-		cpufreq_get_policy(&policy, i);
+		if (cpufreq_get_policy(&policy, i))
+			continue;
 
 		if (!policy.cpuinfo.max_freq)
 			continue;
@@ -494,6 +553,9 @@
 		case CPUFREQ_POLICY_PERFORMANCE:
 			p += sprintf(p, "performance\n");
 			break;
+		case CPUFREQ_POLICY_GOVERNOR:
+			p += snprintf(p, CPUFREQ_NAME_LEN, "%s\n", policy.governor->name);
+			break;
 		default:
 			p += sprintf(p, "INVALID\n");
 			break;
@@ -1065,6 +1127,136 @@
 EXPORT_SYMBOL(cpufreq_unregister_notifier);
 
 
+/*********************************************************************
+ *                              GOVERNORS                            *
+ *********************************************************************/
+
+inline int cpufreq_driver_target_l(struct cpufreq_policy *policy,
+				   unsigned int target_freq,
+				   unsigned int relation)
+{
+	unsigned int ret;
+	down(&cpufreq_driver_sem);
+	if (!cpufreq_driver)
+		ret = -EINVAL;
+	else
+		ret = cpufreq_driver->target(policy, target_freq, relation);
+	up(&cpufreq_driver_sem);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cpufreq_driver_target_l);
+
+
+inline int cpufreq_driver_target(struct cpufreq_policy *policy,
+				 unsigned int target_freq,
+				 unsigned int relation)
+{
+	return cpufreq_driver->target(policy, target_freq, relation);
+}
+EXPORT_SYMBOL_GPL(cpufreq_driver_target);
+
+
+static int cpufreq_governor(unsigned int cpu, unsigned int event)
+{
+	int ret = 0;
+	struct cpufreq_policy *policy = &cpufreq_driver->policy[cpu];
+
+	switch (policy->policy) {
+	case CPUFREQ_POLICY_POWERSAVE: 
+		if ((event == CPUFREQ_GOV_LIMITS) || (event == CPUFREQ_GOV_START))
+			ret = cpufreq_driver->target(policy, policy->min, CPUFREQ_RELATION_L);
+		break;
+	case CPUFREQ_POLICY_PERFORMANCE:
+		if ((event == CPUFREQ_GOV_LIMITS) || (event == CPUFREQ_GOV_START))
+			ret = cpufreq_driver->target(policy, policy->max, CPUFREQ_RELATION_H);
+		break;
+	case CPUFREQ_POLICY_GOVERNOR:
+		ret = -EINVAL;
+		if (event == CPUFREQ_GOV_START)
+			if (!try_module_get(cpufreq_driver->policy[cpu].governor->owner))
+				break;
+		ret = cpufreq_driver->policy[cpu].governor->governor(policy, event);
+		if ((event == CPUFREQ_GOV_STOP) ||
+			(ret && (event == CPUFREQ_GOV_START)))
+			module_put(cpufreq_driver->policy[cpu].governor->owner);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
+
+int cpufreq_governor_l(unsigned int cpu, unsigned int event)
+{
+	int ret = 0;
+	down(&cpufreq_driver_sem);
+	ret = cpufreq_governor(cpu, event);
+	up(&cpufreq_driver_sem);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cpufreq_governor_l);
+
+
+int cpufreq_register_governor(struct cpufreq_governor *governor)
+{
+	struct cpufreq_governor *t;
+
+	if (!governor)
+		return -EINVAL;
+
+	if (!strnicmp(governor->name,"powersave",CPUFREQ_NAME_LEN))
+		return -EBUSY;
+	if (!strnicmp(governor->name,"performance",CPUFREQ_NAME_LEN))
+		return -EBUSY;
+
+	down(&cpufreq_driver_sem);
+	
+	list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
+		if (!strnicmp(governor->name,t->name,CPUFREQ_NAME_LEN)) {
+			up(&cpufreq_driver_sem);
+			return -EBUSY;
+		}
+	}
+	list_add(&governor->governor_list, &cpufreq_governor_list);
+ 	up(&cpufreq_driver_sem);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cpufreq_register_governor);
+
+
+void cpufreq_unregister_governor(struct cpufreq_governor *governor)
+{
+	unsigned int i;
+	
+	if (!governor)
+		return;
+
+	down(&cpufreq_driver_sem);
+	/* 
+	 * Unless the user uses rmmod -f, we can be safe. But we never
+	 * know, so check whether if it's currently used. If so,
+	 * stop it and replace it with the default governor.
+	 */
+	for (i=0; i<NR_CPUS; i++)
+	{
+		if (cpufreq_driver && 
+		    (cpufreq_driver->policy[i].policy == CPUFREQ_POLICY_GOVERNOR) && 
+		    (cpufreq_driver->policy[i].governor == governor)) {
+			cpufreq_governor(i, CPUFREQ_GOV_STOP);
+			cpufreq_driver->policy[i].policy = CPUFREQ_POLICY_PERFORMANCE;
+			cpufreq_governor(i, CPUFREQ_GOV_START);
+		}
+	}
+	/* now we can safely remove it from the list */
+	list_del(&governor->governor_list);
+	up(&cpufreq_driver_sem);
+	return;
+}
+EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
+
+
 
 /*********************************************************************
  *                          POLICY INTERFACE                         *
@@ -1084,15 +1276,11 @@
 		up(&cpufreq_driver_sem);
 		return -EINVAL;
 	}
-	
-	policy->min    = cpufreq_driver->policy[cpu].min;
-	policy->max    = cpufreq_driver->policy[cpu].max;
-	policy->policy = cpufreq_driver->policy[cpu].policy;
-	policy->cpuinfo.max_freq       = cpufreq_driver->policy[cpu].cpuinfo.max_freq;
-	policy->cpuinfo.min_freq       = cpufreq_driver->policy[cpu].cpuinfo.min_freq;
-	policy->cpuinfo.transition_latency = cpufreq_driver->policy[cpu].cpuinfo.transition_latency;
-	policy->cpu    = cpu;
 
+	memcpy(policy, 
+	       &cpufreq_driver->policy[cpu], 
+	       sizeof(struct cpufreq_policy));
+	
 	up(&cpufreq_driver_sem);
 
 	return 0;
@@ -1111,16 +1299,15 @@
 	int ret;
 
 	down(&cpufreq_driver_sem);
-	if (!cpufreq_driver || !cpufreq_driver->verify || 
-	    !cpufreq_driver->setpolicy || !policy ||
+	if (!cpufreq_driver || !policy ||
 	    (policy->cpu >= NR_CPUS) || (!cpu_online(policy->cpu))) {
 		up(&cpufreq_driver_sem);
 		return -EINVAL;
 	}
 
-	policy->cpuinfo.max_freq       = cpufreq_driver->policy[policy->cpu].cpuinfo.max_freq;
-	policy->cpuinfo.min_freq       = cpufreq_driver->policy[policy->cpu].cpuinfo.min_freq;
-	policy->cpuinfo.transition_latency = cpufreq_driver->policy[policy->cpu].cpuinfo.transition_latency;
+	memcpy(&policy->cpuinfo, 
+	       &cpufreq_driver->policy[policy->cpu].cpuinfo, 
+	       sizeof(struct cpufreq_cpuinfo));
 
 	/* verify the cpu speed can be set within this limit */
 	ret = cpufreq_driver->verify(policy);
@@ -1156,13 +1343,35 @@
 
 	cpufreq_driver->policy[policy->cpu].min    = policy->min;
 	cpufreq_driver->policy[policy->cpu].max    = policy->max;
-	cpufreq_driver->policy[policy->cpu].policy = policy->policy;
 
 #ifdef CONFIG_CPU_FREQ_24_API
 	cpu_cur_freq[policy->cpu] = policy->max;
 #endif
 
-	ret = cpufreq_driver->setpolicy(policy);
+	if (cpufreq_driver->setpolicy) {
+		cpufreq_driver->policy[policy->cpu].policy = policy->policy;
+		ret = cpufreq_driver->setpolicy(policy);
+	} else {
+		if ((policy->policy != cpufreq_driver->policy[policy->cpu].policy) || 
+		    ((policy->policy == CPUFREQ_POLICY_GOVERNOR) && (policy->governor != cpufreq_driver->policy[policy->cpu].governor))) {
+			unsigned int old_pol = cpufreq_driver->policy[policy->cpu].policy;
+			struct cpufreq_governor *old_gov = cpufreq_driver->policy[policy->cpu].governor;
+			/* end old governor */
+			cpufreq_governor(policy->cpu, CPUFREQ_GOV_STOP);
+			cpufreq_driver->policy[policy->cpu].policy = policy->policy;
+			cpufreq_driver->policy[policy->cpu].governor = policy->governor;
+			/* start new governor */
+			if (cpufreq_governor(policy->cpu, CPUFREQ_GOV_START)) {
+				cpufreq_driver->policy[policy->cpu].policy = old_pol;
+				cpufreq_driver->policy[policy->cpu].governor = old_gov;
+				cpufreq_governor(policy->cpu, CPUFREQ_GOV_START);
+			}
+			/* might be a policy change, too */
+			cpufreq_governor(policy->cpu, CPUFREQ_GOV_LIMITS);
+		} else {
+			cpufreq_governor(policy->cpu, CPUFREQ_GOV_LIMITS);
+		}
+	}
 	
 	up(&cpufreq_driver_sem);
 
@@ -1253,7 +1462,7 @@
 		return -EBUSY;
 	
 	if (!driver_data || !driver_data->verify || 
-	    !driver_data->setpolicy)
+	    ((!driver_data->setpolicy) && (!driver_data->target)))
 		return -EINVAL;
 
 	down(&cpufreq_driver_sem);
@@ -1271,6 +1480,7 @@
 			up(&cpufreq_driver_sem);
 			return -ENOMEM;
 		}
+		memset(cpufreq_driver->policy, 0, NR_CPUS * sizeof(struct cpufreq_policy));
 	}
 	
 	up(&cpufreq_driver_sem);
@@ -1359,11 +1569,8 @@
 			up(&cpufreq_driver_sem);
 			return 0;
 		}
-	
-		policy.min    = cpufreq_driver->policy[i].min;
-		policy.max    = cpufreq_driver->policy[i].max;
-		policy.policy = cpufreq_driver->policy[i].policy;
-		policy.cpu    = i;
+
+		memcpy(&policy, &cpufreq_driver->policy[i], sizeof(struct cpufreq_policy));
 		up(&cpufreq_driver_sem);
 
 		ret += cpufreq_set_policy(&policy);
@@ -1493,3 +1700,73 @@
 	return 0;
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_setpolicy);
+
+int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
+				   struct cpufreq_frequency_table *table,
+				   unsigned int target_freq,
+				   unsigned int relation,
+				   unsigned int *index)
+{
+	struct cpufreq_frequency_table optimal = { .index = ~0, };
+	struct cpufreq_frequency_table suboptimal = { .index = ~0, };
+	unsigned int i;
+
+	switch (relation) {
+	case CPUFREQ_RELATION_H:
+		optimal.frequency = 0;
+		suboptimal.frequency = ~0;
+		break;
+	case CPUFREQ_RELATION_L:
+		optimal.frequency = ~0;
+		suboptimal.frequency = 0;
+		break;
+	}
+
+	if (!cpu_online(policy->cpu))
+		return -EINVAL;
+
+	for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+		unsigned int freq = table[i].frequency;
+		if (freq == CPUFREQ_ENTRY_INVALID)
+			continue;
+		if ((freq < policy->min) || (freq > policy->max))
+			continue;
+		switch(relation) {
+		case CPUFREQ_RELATION_H:
+			if (freq <= target_freq) {
+				if (freq >= optimal.frequency) {
+					optimal.frequency = freq;
+					optimal.index = i;
+				}
+			} else {
+				if (freq <= suboptimal.frequency) {
+					suboptimal.frequency = freq;
+					suboptimal.index = i;
+				}
+			}
+			break;
+		case CPUFREQ_RELATION_L:
+			if (freq >= target_freq) {
+				if (freq <= optimal.frequency) {
+					optimal.frequency = freq;
+					optimal.index = i;
+				}
+			} else {
+				if (freq >= suboptimal.frequency) {
+					suboptimal.frequency = freq;
+					suboptimal.index = i;
+				}
+			}
+			break;
+		}
+	}
+	if (optimal.index > i) {
+		if (suboptimal.index > i)
+			return -EINVAL;
+		*index = suboptimal.index;
+	} else
+		*index = optimal.index;
+	
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
diff -Nru a/kernel/exit.c b/kernel/exit.c
--- a/kernel/exit.c	Fri Feb 14 15:53:12 2003
+++ b/kernel/exit.c	Fri Feb 14 15:53:12 2003
@@ -249,7 +249,7 @@
 	/* signals? */
 	security_task_reparent_to_init(current);
 	memcpy(current->rlim, init_task.rlim, sizeof(*(current->rlim)));
-	current->user = INIT_USER;
+	switch_uid(INIT_USER);
 
 	write_unlock_irq(&tasklist_lock);
 }
@@ -278,14 +278,38 @@
 }
 
 /*
+ * Let kernel threads use this to say that they
+ * allow a certain signal (since daemonize() will
+ * have disabled all of them by default).
+ */
+int allow_signal(int sig)
+{
+	if (sig < 1 || sig > _NSIG)
+		return -EINVAL;
+
+	spin_lock_irq(&current->sighand->siglock);
+	sigdelset(&current->blocked, sig);
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+	return 0;
+}
+
+EXPORT_SYMBOL(allow_signal);
+
+/*
  *	Put all the gunge required to become a kernel thread without
  *	attached user resources in one place where it belongs.
  */
 
-void daemonize(void)
+void daemonize(const char *name, ...)
 {
+	va_list args;
 	struct fs_struct *fs;
+	sigset_t blocked;
 
+	va_start(args, name);
+	vsnprintf(current->comm, sizeof(current->comm), name, args);
+	va_end(args);
 
 	/*
 	 * If we were started as result of loading a module, close all of the
@@ -296,6 +320,11 @@
 
 	set_special_pids(1, 1);
 	current->tty = NULL;
+
+	/* Block and flush all signals */
+	sigfillset(&blocked);
+	sigprocmask(SIG_BLOCK, &blocked, NULL);
+	flush_signals(current);
 
 	/* Become as one with the init task */
 
diff -Nru a/kernel/kmod.c b/kernel/kmod.c
--- a/kernel/kmod.c	Fri Feb 14 15:53:09 2003
+++ b/kernel/kmod.c	Fri Feb 14 15:53:09 2003
@@ -110,10 +110,10 @@
 	   as the super user right after the execve fails if you time
 	   the signal just right.
 	*/
-	spin_lock_irq(&curtask->sighand->siglock);
-	sigemptyset(&curtask->blocked);
 	flush_signals(curtask);
 	flush_signal_handlers(curtask);
+	spin_lock_irq(&curtask->sighand->siglock);
+	sigemptyset(&curtask->blocked);
 	recalc_sigpending();
 	spin_unlock_irq(&curtask->sighand->siglock);
 
@@ -121,15 +121,7 @@
 		if (curtask->files->fd[i]) close(i);
 	}
 
-	/* Drop the "current user" thing */
-	{
-		struct user_struct *user = curtask->user;
-		curtask->user = INIT_USER;
-		atomic_inc(&INIT_USER->__count);
-		atomic_inc(&INIT_USER->processes);
-		atomic_dec(&user->processes);
-		free_uid(user);
-	}
+	switch_uid(INIT_USER);
 
 	/* Give kmod all effective privileges.. */
 	curtask->euid = curtask->fsuid = 0;
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Fri Feb 14 15:53:08 2003
+++ b/kernel/ksyms.c	Fri Feb 14 15:53:08 2003
@@ -208,6 +208,7 @@
 EXPORT_SYMBOL(__brelse);
 EXPORT_SYMBOL(__bforget);
 EXPORT_SYMBOL(ll_rw_block);
+EXPORT_SYMBOL(sync_dirty_buffer);
 EXPORT_SYMBOL(submit_bh);
 EXPORT_SYMBOL(unlock_buffer);
 EXPORT_SYMBOL(__wait_on_buffer);
@@ -489,6 +490,9 @@
 EXPORT_SYMBOL(xtime_lock);
 EXPORT_SYMBOL(do_gettimeofday);
 EXPORT_SYMBOL(do_settimeofday);
+#if (BITS_PER_LONG < 64)
+EXPORT_SYMBOL(get_jiffies_64);
+#endif
 #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
 EXPORT_SYMBOL(__might_sleep);
 #endif
diff -Nru a/kernel/pm.c b/kernel/pm.c
--- a/kernel/pm.c	Fri Feb 14 15:53:09 2003
+++ b/kernel/pm.c	Fri Feb 14 15:53:09 2003
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/pm.h>
 #include <linux/interrupt.h>
+#include <linux/sysrq.h>
 
 int pm_active;
 
@@ -292,3 +293,41 @@
 EXPORT_SYMBOL(pm_send_all);
 EXPORT_SYMBOL(pm_find);
 EXPORT_SYMBOL(pm_active);
+
+
+#ifdef CONFIG_MAGIC_SYSRQ
+
+/**
+ * handle_poweroff	-	sysrq callback for power down
+ * @key: key pressed (unused)
+ * @pt_regs: register state (unused)
+ * @kbd: keyboard state (unused)
+ * @tty: tty involved (unused)
+ *
+ * When the user hits Sys-Rq o to power down the machine this is the
+ * callback we use.
+ */
+
+static void handle_poweroff (int key, struct pt_regs *pt_regs,
+			     struct tty_struct *tty)
+{
+	if (pm_power_off)
+		pm_power_off();
+}
+
+static struct sysrq_key_op	sysrq_poweroff_op = {
+	.handler        = handle_poweroff,
+	.help_msg       = "powerOff",
+	.action_msg     = "Power Off\n"
+};
+
+#endif  /* CONFIG_MAGIC_SYSRQ */
+
+
+static int pm_init(void)
+{
+	register_sysrq_key('o', &sysrq_poweroff_op);
+	return 0;
+}
+
+subsys_initcall(pm_init);
diff -Nru a/kernel/ptrace.c b/kernel/ptrace.c
--- a/kernel/ptrace.c	Fri Feb 14 15:53:12 2003
+++ b/kernel/ptrace.c	Fri Feb 14 15:53:12 2003
@@ -351,4 +351,9 @@
 	set_current_state(TASK_STOPPED);
 	notify_parent(current, SIGCHLD);
 	schedule();
+
+	/*
+	 * Signals sent while we were stopped might set TIF_SIGPENDING.
+	 */
+	recalc_sigpending();
 }
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	Fri Feb 14 15:53:12 2003
+++ b/kernel/sched.c	Fri Feb 14 15:53:12 2003
@@ -506,7 +506,8 @@
  */
 void wake_up_forked_process(task_t * p)
 {
-	runqueue_t *rq = this_rq_lock();
+	unsigned long flags;
+	runqueue_t *rq = task_rq_lock(current, &flags);
 
 	p->state = TASK_RUNNING;
 	if (!rt_task(p)) {
@@ -522,7 +523,7 @@
 	set_task_cpu(p, smp_processor_id());
 	activate_task(p, rq);
 
-	rq_unlock(rq);
+	task_rq_unlock(rq, &flags);
 }
 
 /*
@@ -2245,8 +2246,7 @@
 	runqueue_t *rq;
 	int ret;
 
-	daemonize();
-	sigfillset(&current->blocked);
+	daemonize("migration/%d", cpu);
 	set_fs(KERNEL_DS);
 
 	/*
@@ -2259,8 +2259,6 @@
 
 	rq = this_rq();
 	rq->migration_thread = current;
-
-	sprintf(current->comm, "migration/%d", smp_processor_id());
 
 	for (;;) {
 		runqueue_t *rq_src, *rq_dest;
diff -Nru a/kernel/signal.c b/kernel/signal.c
--- a/kernel/signal.c	Fri Feb 14 15:53:09 2003
+++ b/kernel/signal.c	Fri Feb 14 15:53:09 2003
@@ -141,14 +141,34 @@
 	(((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) &&	\
 	 ((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN))
 
-#define sig_ignored(t, signr) \
-	(!((t)->ptrace & PT_PTRACED) && \
-	 (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_IGN)
-
 #define sig_fatal(t, signr) \
 	(!T(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \
 	 (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)
 
+static inline int sig_ignored(struct task_struct *t, int sig)
+{
+	void * handler;
+
+	/*
+	 * Tracers always want to know about signals..
+	 */
+	if (t->ptrace & PT_PTRACED)
+		return 0;
+
+	/*
+	 * Blocked signals are never ignored, since the
+	 * signal handler may change by the time it is
+	 * unblocked.
+	 */
+	if (sigismember(&t->blocked, sig))
+		return 0;
+
+	/* Is it explicitly or implicitly ignored? */
+	handler = t->sighand->action[sig-1].sa.sa_handler;
+	return   handler == SIG_IGN ||
+		(handler == SIG_DFL && sig_kernel_ignore(sig));
+}
+
 /*
  * Re-calculate pending state from the set of locally pending
  * signals, globally pending signals, and blocked signals.
@@ -256,8 +276,13 @@
 void
 flush_signals(struct task_struct *t)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&t->sighand->siglock, flags);
 	clear_tsk_thread_flag(t,TIF_SIGPENDING);
 	flush_sigqueue(&t->pending);
+	flush_sigqueue(&t->signal->shared_pending);
+	spin_unlock_irqrestore(&t->sighand->siglock, flags);
 }
 
 /*
@@ -460,11 +485,11 @@
  *
  * All callers have to hold the siglock.
  */
-int dequeue_signal(sigset_t *mask, siginfo_t *info)
+int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
 {
-	int signr = __dequeue_signal(&current->pending, mask, info);
+	int signr = __dequeue_signal(&tsk->pending, mask, info);
 	if (!signr)
-		signr = __dequeue_signal(&current->signal->shared_pending,
+		signr = __dequeue_signal(&tsk->signal->shared_pending,
 					 mask, info);
 	return signr;
 }
@@ -619,6 +644,7 @@
 		rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending);
 		t = p;
 		do {
+			unsigned int state;
 			rm_from_queue(SIG_KERNEL_STOP_MASK, &t->pending);
 			
 			/*
@@ -635,9 +661,12 @@
 			 * Wake up the stopped thread _after_ setting
 			 * TIF_SIGPENDING
 			 */
-			if (!sigismember(&t->blocked, SIGCONT))
+			state = TASK_STOPPED;
+			if (sig_user_defined(t, SIGCONT) && !sigismember(&t->blocked, SIGCONT)) {
 				set_tsk_thread_flag(t, TIF_SIGPENDING);
-			wake_up_state(t, TASK_STOPPED);
+				state |= TASK_INTERRUPTIBLE;
+			}
+			wake_up_state(t, state);
 
 			t = next_thread(t);
 		} while (t != p);
@@ -1396,7 +1425,7 @@
 
 #ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
 
-int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs)
+int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs, void *cookie)
 {
 	sigset_t *mask = &current->blocked;
 
@@ -1427,13 +1456,15 @@
 			continue;
 		}
 	dequeue:
-		signr = dequeue_signal(mask, info);
+		signr = dequeue_signal(current, mask, info);
 		spin_unlock_irq(&current->sighand->siglock);
 
 		if (!signr)
 			break;
 
 		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			ptrace_signal_deliver(regs, cookie);
+
 			/*
 			 * If there is a group stop in progress,
 			 * we must participate in the bookkeeping.
@@ -1576,7 +1607,6 @@
 	return -EINTR;
 }
 
-
 /*
  * We don't need to get the kernel lock - this is all local to this
  * particular thread.. (and that's good, because this is _heavily_
@@ -1781,7 +1811,7 @@
 	}
 
 	spin_lock_irq(&current->sighand->siglock);
-	sig = dequeue_signal(&these, &info);
+	sig = dequeue_signal(current, &these, &info);
 	if (!sig) {
 		timeout = MAX_SCHEDULE_TIMEOUT;
 		if (uts)
@@ -1801,7 +1831,7 @@
 			timeout = schedule_timeout(timeout);
 
 			spin_lock_irq(&current->sighand->siglock);
-			sig = dequeue_signal(&these, &info);
+			sig = dequeue_signal(current, &these, &info);
 			current->blocked = current->real_blocked;
 			siginitset(&current->real_blocked, 0);
 			recalc_sigpending();
diff -Nru a/kernel/softirq.c b/kernel/softirq.c
--- a/kernel/softirq.c	Fri Feb 14 15:53:09 2003
+++ b/kernel/softirq.c	Fri Feb 14 15:53:09 2003
@@ -300,17 +300,14 @@
 {
 	int cpu = (int) (long) __bind_cpu;
 
-	daemonize();
+	daemonize("ksoftirqd/%d", cpu);
 	set_user_nice(current, 19);
 	current->flags |= PF_IOTHREAD;
-	sigfillset(&current->blocked);
 
 	/* Migrate to the right CPU */
 	set_cpus_allowed(current, 1UL << cpu);
 	if (smp_processor_id() != cpu)
 		BUG();
-
-	sprintf(current->comm, "ksoftirqd/%d", cpu);
 
 	__set_current_state(TASK_INTERRUPTIBLE);
 	mb();
diff -Nru a/kernel/sys.c b/kernel/sys.c
--- a/kernel/sys.c	Fri Feb 14 15:53:08 2003
+++ b/kernel/sys.c	Fri Feb 14 15:53:08 2003
@@ -561,19 +561,12 @@
   
 static int set_user(uid_t new_ruid, int dumpclear)
 {
-	struct user_struct *new_user, *old_user;
+	struct user_struct *new_user;
 
-	/* What if a process setreuid()'s and this brings the
-	 * new uid over his NPROC rlimit?  We can check this now
-	 * cheaply with the new uid cache, so if it matters
-	 * we should be checking for it.  -DaveM
-	 */
 	new_user = alloc_uid(new_ruid);
 	if (!new_user)
 		return -EAGAIN;
-	old_user = current->user;
-	atomic_dec(&old_user->processes);
-	atomic_inc(&new_user->processes);
+	switch_uid(new_user);
 
 	if(dumpclear)
 	{
@@ -581,8 +574,6 @@
 		wmb();
 	}
 	current->uid = new_ruid;
-	current->user = new_user;
-	free_uid(old_user);
 	return 0;
 }
 
@@ -916,6 +907,7 @@
 	p = find_task_by_pid(pid);
 	if (!p)
 		goto out;
+
 	err = -EINVAL;
 	if (!thread_group_leader(p))
 		goto out;
@@ -927,11 +919,16 @@
 		err = -EACCES;
 		if (p->did_exec)
 			goto out;
-	} else if (p != current)
-		goto out;
+	} else {
+		err = -ESRCH;
+		if (p != current)
+			goto out;
+	}
+
 	err = -EPERM;
 	if (p->leader)
 		goto out;
+
 	if (pgid != pid) {
 		struct task_struct *p;
 		struct pid *pid;
diff -Nru a/kernel/time.c b/kernel/time.c
--- a/kernel/time.c	Fri Feb 14 15:53:09 2003
+++ b/kernel/time.c	Fri Feb 14 15:53:09 2003
@@ -27,7 +27,6 @@
 #include <linux/timex.h>
 #include <linux/errno.h>
 #include <linux/smp_lock.h>
-
 #include <asm/uaccess.h>
 
 /* 
@@ -416,3 +415,17 @@
 
 	return now; 
 }
+
+#if (BITS_PER_LONG < 64)
+u64 get_jiffies_64(void)
+{
+	unsigned long seq;
+	u64 ret;
+
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		ret = jiffies_64;
+	} while (read_seqretry(&xtime_lock, seq));
+	return ret;
+}
+#endif
diff -Nru a/kernel/user.c b/kernel/user.c
--- a/kernel/user.c	Fri Feb 14 15:53:09 2003
+++ b/kernel/user.c	Fri Feb 14 15:53:09 2003
@@ -116,6 +116,23 @@
 	return up;
 }
 
+void switch_uid(struct user_struct *new_user)
+{
+	struct user_struct *old_user;
+
+	/* What if a process setreuid()'s and this brings the
+	 * new uid over his NPROC rlimit?  We can check this now
+	 * cheaply with the new uid cache, so if it matters
+	 * we should be checking for it.  -DaveM
+	 */
+	old_user = current->user;
+	atomic_inc(&new_user->__count);
+	atomic_inc(&new_user->processes);
+	atomic_dec(&old_user->processes);
+	current->user = new_user;
+	free_uid(old_user);
+}
+
 
 static int __init uid_cache_init(void)
 {
diff -Nru a/kernel/workqueue.c b/kernel/workqueue.c
--- a/kernel/workqueue.c	Fri Feb 14 15:53:12 2003
+++ b/kernel/workqueue.c	Fri Feb 14 15:53:12 2003
@@ -172,19 +172,14 @@
 	DECLARE_WAITQUEUE(wait, current);
 	struct k_sigaction sa;
 
-	daemonize();
-	sprintf(current->comm, "%s/%d", startup->name, cpu);
+	daemonize("%s/%d", startup->name, cpu);
+	allow_signal(SIGCHLD);
 	current->flags |= PF_IOTHREAD;
 	cwq->thread = current;
 
 	set_user_nice(current, -10);
 	set_cpus_allowed(current, 1UL << cpu);
 
-	spin_lock_irq(&current->sighand->siglock);
-	siginitsetinv(&current->blocked, sigmask(SIGCHLD));
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
 	complete(&startup->done);
 
 	/* Install a handler so SIGCLD is delivered */
@@ -213,10 +208,7 @@
 				/* SIGCHLD - auto-reaping */ ;
 
 			/* zap all other signals */
-			spin_lock_irq(&current->sighand->siglock);
 			flush_signals(current);
-			recalc_sigpending();
-			spin_unlock_irq(&current->sighand->siglock);
 		}
 	}
 	remove_wait_queue(&cwq->more_work, &wait);
diff -Nru a/lib/radix-tree.c b/lib/radix-tree.c
--- a/lib/radix-tree.c	Fri Feb 14 15:53:09 2003
+++ b/lib/radix-tree.c	Fri Feb 14 15:53:09 2003
@@ -154,8 +154,7 @@
 
 			/* Increase the height.  */
 			node->slots[0] = root->rnode;
-			if (root->rnode)
-				node->count = 1;
+			node->count = 1;
 			root->rnode = node;
 			root->height++;
 		} while (height > root->height);
diff -Nru a/lib/vsprintf.c b/lib/vsprintf.c
--- a/lib/vsprintf.c	Fri Feb 14 15:53:12 2003
+++ b/lib/vsprintf.c	Fri Feb 14 15:53:12 2003
@@ -306,7 +306,8 @@
 
 		/* get the conversion qualifier */
 		qualifier = -1;
-		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
+		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
+		    *fmt =='Z' || *fmt == 'z') {
 			qualifier = *fmt;
 			++fmt;
 			if (qualifier == 'l' && *fmt == 'l') {
@@ -381,7 +382,7 @@
 				if (qualifier == 'l') {
 					long * ip = va_arg(args, long *);
 					*ip = (str - buf);
-				} else if (qualifier == 'Z') {
+				} else if (qualifier == 'Z' || qualifier == 'z') {
 					size_t * ip = va_arg(args, size_t *);
 					*ip = (str - buf);
 				} else {
@@ -432,7 +433,7 @@
 			num = va_arg(args, unsigned long);
 			if (flags & SIGN)
 				num = (signed long) num;
-		} else if (qualifier == 'Z') {
+		} else if (qualifier == 'Z' || qualifier == 'z') {
 			num = va_arg(args, size_t);
 		} else if (qualifier == 'h') {
 			num = (unsigned short) va_arg(args, int);
@@ -565,7 +566,8 @@
 
 		/* get conversion qualifier */
 		qualifier = -1;
-		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'Z') {
+		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
+		    *fmt == 'Z' || *fmt == 'z') {
 			qualifier = *fmt;
 			fmt++;
 		}
@@ -680,6 +682,7 @@
 			}
 			break;
 		case 'Z':
+		case 'z':
 		{
 			size_t *s = (size_t*) va_arg(args,size_t*);
 			*s = (size_t) simple_strtoul(str,&next,base);
diff -Nru a/mm/fadvise.c b/mm/fadvise.c
--- a/mm/fadvise.c	Fri Feb 14 15:53:09 2003
+++ b/mm/fadvise.c	Fri Feb 14 15:53:09 2003
@@ -20,7 +20,7 @@
  * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could
  * deactivate the pages and clear PG_Referenced.
  */
-int sys_fadvise64(int fd, loff_t offset, size_t len, int advice)
+long sys_fadvise64(int fd, loff_t offset, size_t len, int advice)
 {
 	struct file *file = fget(fd);
 	struct inode *inode;
diff -Nru a/mm/mmap.c b/mm/mmap.c
--- a/mm/mmap.c	Fri Feb 14 15:53:11 2003
+++ b/mm/mmap.c	Fri Feb 14 15:53:11 2003
@@ -801,6 +801,13 @@
 			return -ENOMEM;
 		if (addr & ~PAGE_MASK)
 			return -EINVAL;
+		if (file && is_file_hugepages(file)) {
+			unsigned long ret;
+
+			ret = is_aligned_hugepage_range(addr, len);
+			if (ret)
+				return ret;
+		}
 		return addr;
 	}
 
@@ -1224,8 +1231,10 @@
 	/* we have  start < mpnt->vm_end  */
 
 	if (is_vm_hugetlb_page(mpnt)) {
-		if ((start & ~HPAGE_MASK) || (len & ~HPAGE_MASK))
-			return -EINVAL;
+		int ret = is_aligned_hugepage_range(start, len);
+
+		if (ret)
+			return ret;
 	}
 
 	/* if it doesn't overlap, we have nothing.. */
diff -Nru a/mm/pdflush.c b/mm/pdflush.c
--- a/mm/pdflush.c	Fri Feb 14 15:53:12 2003
+++ b/mm/pdflush.c	Fri Feb 14 15:53:12 2003
@@ -86,14 +86,7 @@
 
 static int __pdflush(struct pdflush_work *my_work)
 {
-	daemonize();
-	strcpy(current->comm, "pdflush");
-
-	/* interruptible sleep, so block all signals */
-	spin_lock_irq(&current->sighand->siglock);
-	siginitsetinv(&current->blocked, 0);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	daemonize("pdflush");
 
 	current->flags |= PF_FLUSHER;
 	my_work->fn = NULL;
diff -Nru a/mm/swap_state.c b/mm/swap_state.c
--- a/mm/swap_state.c	Fri Feb 14 15:53:09 2003
+++ b/mm/swap_state.c	Fri Feb 14 15:53:09 2003
@@ -294,7 +294,7 @@
  */
 void free_pages_and_swap_cache(struct page **pages, int nr)
 {
-	const int chunk = 16;
+	int chunk = 16;
 	struct page **pagep = pages;
 
 	lru_add_drain();
diff -Nru a/mm/vmscan.c b/mm/vmscan.c
--- a/mm/vmscan.c	Fri Feb 14 15:53:09 2003
+++ b/mm/vmscan.c	Fri Feb 14 15:53:09 2003
@@ -757,7 +757,7 @@
  */
 static int
 shrink_caches(struct zone *classzone, int priority, int *total_scanned,
-		int gfp_mask, const int nr_pages, struct page_state *ps)
+		int gfp_mask, int nr_pages, struct page_state *ps)
 {
 	struct zone *first_classzone;
 	struct zone *zone;
@@ -928,10 +928,8 @@
 	struct task_struct *tsk = current;
 	DEFINE_WAIT(wait);
 
-	daemonize();
+	daemonize("kswapd%d", pgdat->node_id);
 	set_cpus_allowed(tsk, node_to_cpumask(pgdat->node_id));
-	sprintf(tsk->comm, "kswapd%d", pgdat->node_id);
-	sigfillset(&tsk->blocked);
 	
 	/*
 	 * Tell the memory management that we're a "memory allocator",
diff -Nru a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c
--- a/net/ax25/sysctl_net_ax25.c	Fri Feb 14 15:53:12 2003
+++ b/net/ax25/sysctl_net_ax25.c	Fri Feb 14 15:53:12 2003
@@ -33,73 +33,168 @@
 static int ax25_table_size;
 
 static ctl_table ax25_dir_table[] = {
-	{NET_AX25, "ax25", NULL, 0, 0555, NULL},
-	{0}
+	{
+		.ctl_name	= NET_AX25,
+		.procname	= "ax25",
+		.maxlen		= 0,
+		.mode		= 0555,
+	},
+	{ .ctl_name = 0 }
 };
 
 static ctl_table ax25_root_table[] = {
-	{CTL_NET, "net", NULL, 0, 0555, ax25_dir_table},
-	{0}
+	{
+		.ctl_name	= CTL_NET,
+		.procname	= "net",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ax25_dir_table
+	},
+	{ .ctl_name = 0 }
 };
 
 static const ctl_table ax25_param_table[] = {
-	{NET_AX25_IP_DEFAULT_MODE, "ip_default_mode",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_ipdefmode, &max_ipdefmode},
-	{NET_AX25_DEFAULT_MODE, "ax25_default_mode",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_axdefmode, &max_axdefmode},
-	{NET_AX25_BACKOFF_TYPE, "backoff_type",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_backoff, &max_backoff},
-	{NET_AX25_CONNECT_MODE, "connect_mode",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_conmode, &max_conmode},
-	{NET_AX25_STANDARD_WINDOW, "standard_window_size",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_window, &max_window},
-	{NET_AX25_EXTENDED_WINDOW, "extended_window_size",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_ewindow, &max_ewindow},
-	{NET_AX25_T1_TIMEOUT, "t1_timeout",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_t1, &max_t1},
-	{NET_AX25_T2_TIMEOUT, "t2_timeout",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_t2, &max_t2},
-	{NET_AX25_T3_TIMEOUT, "t3_timeout",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_t3, &max_t3},
-	{NET_AX25_IDLE_TIMEOUT, "idle_timeout",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_idle, &max_idle},
-	{NET_AX25_N2, "maximum_retry_count",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_n2, &max_n2},
-	{NET_AX25_PACLEN, "maximum_packet_length",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_paclen, &max_paclen},
-	{NET_AX25_PROTOCOL, "protocol",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_proto, &max_proto},
-	{NET_AX25_DAMA_SLAVE_TIMEOUT, "dama_slave_timeout",
-	 NULL, sizeof(int), 0644, NULL,
-	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 &min_ds_timeout, &max_ds_timeout},
-	{0}	/* that's all, folks! */
+	{
+		.ctl_name	= NET_AX25_IP_DEFAULT_MODE,
+		.procname	= "ip_default_mode",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_ipdefmode,
+		.extra2		= &max_ipdefmode
+	},
+	{
+		.ctl_name	= NET_AX25_DEFAULT_MODE,
+		.procname	= "ax25_default_mode",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_axdefmode,
+		.extra2		= &max_axdefmode
+	},
+	{
+		.ctl_name	= NET_AX25_BACKOFF_TYPE,
+		.procname	= "backoff_type",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_backoff,
+		.extra2		= &max_backoff
+	},
+	{
+		.ctl_name	= NET_AX25_CONNECT_MODE,
+		.procname	= "connect_mode",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_conmode,
+		.extra2		= &max_conmode
+	},
+	{
+		.ctl_name	= NET_AX25_STANDARD_WINDOW,
+		.procname	= "standard_window_size",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_window,
+		.extra2		= &max_window
+	},
+	{
+		.ctl_name	= NET_AX25_EXTENDED_WINDOW,
+		.procname	= "extended_window_size",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_ewindow,
+		.extra2		= &max_ewindow
+	},
+	{
+		.ctl_name	= NET_AX25_T1_TIMEOUT,
+		.procname	= "t1_timeout",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_t1,
+		.extra2		= &max_t1
+	},
+	{
+		.ctl_name	= NET_AX25_T2_TIMEOUT,
+		.procname	= "t2_timeout",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_t2,
+		.extra2		= &max_t2
+	},
+	{
+		.ctl_name	= NET_AX25_T3_TIMEOUT,
+		.procname	= "t3_timeout",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_t3,
+		.extra2		= &max_t3
+	},
+	{
+		.ctl_name	= NET_AX25_IDLE_TIMEOUT,
+		.procname	= "idle_timeout",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_idle,
+		.extra2		= &max_idle
+	},
+	{
+		.ctl_name	= NET_AX25_N2,
+		.procname	= "maximum_retry_count",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_n2,
+		.extra2		= &max_n2
+	},
+	{
+		.ctl_name	= NET_AX25_PACLEN,
+		.procname	= "maximum_packet_length",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_paclen,
+		.extra2		= &max_paclen
+	},
+	{
+		.ctl_name	= NET_AX25_PROTOCOL,
+		.procname	= "protocol",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_proto,
+		.extra2		= &max_proto
+	},
+	{
+		.ctl_name	= NET_AX25_DAMA_SLAVE_TIMEOUT,
+		.procname	= "dama_slave_timeout",
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_ds_timeout,
+		.extra2		= &max_ds_timeout
+	},
+	{ .ctl_name = 0 }	/* that's all, folks! */
 };
 
 void ax25_register_sysctl(void)
diff -Nru a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
--- a/net/bluetooth/af_bluetooth.c	Fri Feb 14 15:53:09 2003
+++ b/net/bluetooth/af_bluetooth.c	Fri Feb 14 15:53:09 2003
@@ -92,7 +92,7 @@
 
 static int bt_sock_create(struct socket *sock, int proto)
 {
-	if (proto > BT_MAX_PROTO)
+	if (proto >= BT_MAX_PROTO)
 		return -EINVAL;
 
 #if defined(CONFIG_KMOD)
diff -Nru a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
--- a/net/bluetooth/bnep/core.c	Fri Feb 14 15:53:12 2003
+++ b/net/bluetooth/bnep/core.c	Fri Feb 14 15:53:12 2003
@@ -478,13 +478,9 @@
 
 	BT_DBG("");
 
-        daemonize();
+        daemonize("kbnepd %s", dev->name);
 	set_user_nice(current, -15);
 	current->flags |= PF_IOTHREAD;
-        sigfillset(&current->blocked);
-	flush_signals(current);
-
-        sprintf(current->comm, "kbnepd %s", dev->name);
 
         set_fs(KERNEL_DS);
 
diff -Nru a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
--- a/net/bluetooth/rfcomm/core.c	Fri Feb 14 15:53:08 2003
+++ b/net/bluetooth/rfcomm/core.c	Fri Feb 14 15:53:08 2003
@@ -1705,13 +1705,9 @@
 
 	atomic_inc(&running);
 
-	daemonize();
+	daemonize("krfcommd");
 	set_user_nice(current, -10);
 	current->flags |= PF_IOTHREAD;
-	sigfillset(&current->blocked);
-	flush_signals(current);
-
-	sprintf(current->comm, "krfcommd");
 
 	set_fs(KERNEL_DS);
 
diff -Nru a/net/core/rtnetlink.c b/net/core/rtnetlink.c
--- a/net/core/rtnetlink.c	Fri Feb 14 15:53:12 2003
+++ b/net/core/rtnetlink.c	Fri Feb 14 15:53:12 2003
@@ -351,7 +351,7 @@
 		return 0;
 
 	family = ((struct rtgenmsg*)NLMSG_DATA(nlh))->rtgen_family;
-	if (family > NPROTO) {
+	if (family >= NPROTO) {
 		*errp = -EAFNOSUPPORT;
 		return -1;
 	}
diff -Nru a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
--- a/net/core/sysctl_net_core.c	Fri Feb 14 15:53:09 2003
+++ b/net/core/sysctl_net_core.c	Fri Feb 14 15:53:09 2003
@@ -36,59 +36,139 @@
 
 ctl_table core_table[] = {
 #ifdef CONFIG_NET
-	{NET_CORE_WMEM_MAX, "wmem_max",
-	 &sysctl_wmem_max, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_CORE_RMEM_MAX, "rmem_max",
-	 &sysctl_rmem_max, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_CORE_WMEM_DEFAULT, "wmem_default",
-	 &sysctl_wmem_default, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_CORE_RMEM_DEFAULT, "rmem_default",
-	 &sysctl_rmem_default, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_CORE_DEV_WEIGHT, "dev_weight",
-	 &weight_p, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_CORE_MAX_BACKLOG, "netdev_max_backlog",
-	 &netdev_max_backlog, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_CORE_NO_CONG_THRESH, "no_cong_thresh",
-	 &no_cong, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_CORE_NO_CONG, "no_cong",
-	 &no_cong, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_CORE_LO_CONG, "lo_cong",
-	 &lo_cong, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_CORE_MOD_CONG, "mod_cong",
-	 &mod_cong, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
+	{
+		.ctl_name	= NET_CORE_WMEM_MAX,
+		.procname	= "wmem_max",
+		.data		= &sysctl_wmem_max,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_CORE_RMEM_MAX,
+		.procname	= "rmem_max",
+		.data		= &sysctl_rmem_max,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_CORE_WMEM_DEFAULT,
+		.procname	= "wmem_default",
+		.data		= &sysctl_wmem_default,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_CORE_RMEM_DEFAULT,
+		.procname	= "rmem_default",
+		.data		= &sysctl_rmem_default,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_CORE_DEV_WEIGHT,
+		.procname	= "dev_weight",
+		.data		= &weight_p,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_CORE_MAX_BACKLOG,
+		.procname	= "netdev_max_backlog",
+		.data		= &netdev_max_backlog,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_CORE_NO_CONG_THRESH,
+		.procname	= "no_cong_thresh",
+		.data		= &no_cong,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_CORE_NO_CONG,
+		.procname	= "no_cong",
+		.data		= &no_cong,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_CORE_LO_CONG,
+		.procname	= "lo_cong",
+		.data		= &lo_cong,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_CORE_MOD_CONG,
+		.procname	= "mod_cong",
+		.data		= &mod_cong,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
 #ifdef CONFIG_NET_FASTROUTE
-	{NET_CORE_FASTROUTE, "netdev_fastroute",
-	 &netdev_fastroute, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
+	{
+		.ctl_name	= NET_CORE_FASTROUTE,
+		.procname	= "netdev_fastroute",
+		.data		= &netdev_fastroute,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
 #endif
-	{NET_CORE_MSG_COST, "message_cost",
-	 &net_msg_cost, sizeof(int), 0644, NULL,
-	 &proc_dointvec_jiffies},
-	{NET_CORE_MSG_BURST, "message_burst",
-	 &net_msg_burst, sizeof(int), 0644, NULL,
-	 &proc_dointvec_jiffies},
-	{NET_CORE_OPTMEM_MAX, "optmem_max",
-	 &sysctl_optmem_max, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_CORE_HOT_LIST_LENGTH, "hot_list_length",
-	 &sysctl_hot_list_len, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
+	{
+		.ctl_name	= NET_CORE_MSG_COST,
+		.procname	= "message_cost",
+		.data		= &net_msg_cost,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies
+	},
+	{
+		.ctl_name	= NET_CORE_MSG_BURST,
+		.procname	= "message_burst",
+		.data		= &net_msg_burst,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies
+	},
+	{
+		.ctl_name	= NET_CORE_OPTMEM_MAX,
+		.procname	= "optmem_max",
+		.data		= &sysctl_optmem_max,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_CORE_HOT_LIST_LENGTH,
+		.procname	= "hot_list_length",
+		.data		= &sysctl_hot_list_len,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
 #ifdef CONFIG_NET_DIVERT
-	{NET_CORE_DIVERT_VERSION, "divert_version",
-	 (void *)sysctl_divert_version, 32, 0444, NULL,
-	 &proc_dostring},
+	{
+		.ctl_name	= NET_CORE_DIVERT_VERSION,
+		.procname	= "divert_version",
+		.data		= (void *)sysctl_divert_version,
+		.maxlen		= 32,
+		.mode		= 0444,
+		.proc_handler	= &proc_dostring
+	},
 #endif /* CONFIG_NET_DIVERT */
 #endif /* CONFIG_NET */
-	{ 0 }
+	{ .ctl_name = 0 }
 };
 #endif
diff -Nru a/net/econet/af_econet.c b/net/econet/af_econet.c
--- a/net/econet/af_econet.c	Fri Feb 14 15:53:10 2003
+++ b/net/econet/af_econet.c	Fri Feb 14 15:53:10 2003
@@ -338,6 +338,7 @@
 		
 		eb = (struct ec_cb *)&skb->cb;
 		
+		/* BUG: saddr may be NULL */
 		eb->cookie = saddr->cookie;
 		eb->sec = *saddr;
 		eb->sent = ec_tx_done;
diff -Nru a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
--- a/net/ipv4/netfilter/arptable_filter.c	Fri Feb 14 15:53:08 2003
+++ b/net/ipv4/netfilter/arptable_filter.c	Fri Feb 14 15:53:08 2003
@@ -37,10 +37,10 @@
 } initial_table __initdata
 = { { "filter", FILTER_VALID_HOOKS, 3,
       sizeof(struct arpt_standard) * 2 + sizeof(struct arpt_error),
-      { [NF_ARP_IN] 0,
-	[NF_ARP_OUT] sizeof(struct arpt_standard) },
-      { [NF_ARP_IN] 0,
-	[NF_ARP_OUT] sizeof(struct arpt_standard), },
+      { [NF_ARP_IN] = 0,
+	[NF_ARP_OUT] = sizeof(struct arpt_standard) },
+      { [NF_ARP_IN] = 0,
+	[NF_ARP_OUT] = sizeof(struct arpt_standard), },
       0, NULL, { } },
     {
 	    /* ARP_IN */
diff -Nru a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
--- a/net/ipv4/netfilter/ip_conntrack_core.c	Fri Feb 14 15:53:08 2003
+++ b/net/ipv4/netfilter/ip_conntrack_core.c	Fri Feb 14 15:53:08 2003
@@ -1361,19 +1361,37 @@
 static struct ctl_table_header *ip_conntrack_sysctl_header;
 
 static ctl_table ip_conntrack_table[] = {
-	{ NET_IP_CONNTRACK_MAX, NET_IP_CONNTRACK_MAX_NAME, &ip_conntrack_max,
-	  sizeof(ip_conntrack_max), 0644,  NULL, proc_dointvec },
- 	{ 0 }
+	{
+		.ctl_name	= NET_IP_CONNTRACK_MAX,
+		.procname	= NET_IP_CONNTRACK_MAX_NAME,
+		.data		= &ip_conntrack_max,
+		.maxlen		= sizeof(ip_conntrack_max),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec
+	},
+ 	{ .ctl_name = 0 }
 };
 
 static ctl_table ip_conntrack_dir_table[] = {
-	{NET_IPV4, "ipv4", NULL, 0, 0555, ip_conntrack_table, 0, 0, 0, 0, 0},
-	{ 0 }
+	{
+		.ctl_name	= NET_IPV4,
+		.procname	= "ipv4",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ip_conntrack_table
+	},
+	{ .ctl_name = 0 }
 };
 
 static ctl_table ip_conntrack_root_table[] = {
-	{CTL_NET, "net", NULL, 0, 0555, ip_conntrack_dir_table, 0, 0, 0, 0, 0},
-	{ 0 }
+	{
+		.ctl_name	= CTL_NET,
+		.procname	= "net",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ip_conntrack_dir_table
+	},
+	{ .ctl_name = 0 }
 };
 #endif /*CONFIG_SYSCTL*/
 
diff -Nru a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c
--- a/net/ipv4/netfilter/ip_nat_ftp.c	Fri Feb 14 15:53:11 2003
+++ b/net/ipv4/netfilter/ip_nat_ftp.c	Fri Feb 14 15:53:11 2003
@@ -160,10 +160,10 @@
 		     unsigned int,
 		     struct ip_conntrack *,
 		     enum ip_conntrack_info)
-= { [IP_CT_FTP_PORT] mangle_rfc959_packet,
-    [IP_CT_FTP_PASV] mangle_rfc959_packet,
-    [IP_CT_FTP_EPRT] mangle_eprt_packet,
-    [IP_CT_FTP_EPSV] mangle_epsv_packet
+= { [IP_CT_FTP_PORT] = mangle_rfc959_packet,
+    [IP_CT_FTP_PASV] = mangle_rfc959_packet,
+    [IP_CT_FTP_EPRT] = mangle_eprt_packet,
+    [IP_CT_FTP_EPSV] = mangle_epsv_packet
 };
 
 static int ftp_data_fixup(const struct ip_ct_ftp_expect *ct_ftp_info,
diff -Nru a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c
--- a/net/ipv4/netfilter/ip_nat_rule.c	Fri Feb 14 15:53:09 2003
+++ b/net/ipv4/netfilter/ip_nat_rule.c	Fri Feb 14 15:53:09 2003
@@ -56,12 +56,12 @@
 } nat_initial_table __initdata
 = { { "nat", NAT_VALID_HOOKS, 4,
       sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
-      { [NF_IP_PRE_ROUTING] 0,
-	[NF_IP_POST_ROUTING] sizeof(struct ipt_standard),
-	[NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2 },
-      { [NF_IP_PRE_ROUTING] 0,
-	[NF_IP_POST_ROUTING] sizeof(struct ipt_standard),
-	[NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2 },
+      { [NF_IP_PRE_ROUTING] = 0,
+	[NF_IP_POST_ROUTING] = sizeof(struct ipt_standard),
+	[NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },
+      { [NF_IP_PRE_ROUTING] = 0,
+	[NF_IP_POST_ROUTING] = sizeof(struct ipt_standard),
+	[NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },
       0, NULL, { } },
     {
 	    /* PRE_ROUTING */
diff -Nru a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
--- a/net/ipv4/netfilter/ip_queue.c	Fri Feb 14 15:53:12 2003
+++ b/net/ipv4/netfilter/ip_queue.c	Fri Feb 14 15:53:12 2003
@@ -586,19 +586,37 @@
 static struct ctl_table_header *ipq_sysctl_header;
 
 static ctl_table ipq_table[] = {
-	{ NET_IPQ_QMAX, NET_IPQ_QMAX_NAME, &sysctl_maxlen,
-	  sizeof(sysctl_maxlen), 0644,  NULL, proc_dointvec },
- 	{ 0 }
+	{
+		.ctl_name	= NET_IPQ_QMAX,
+		.procname	= NET_IPQ_QMAX_NAME,
+		.data		= &sysctl_maxlen,
+		.maxlen		= sizeof(sysctl_maxlen),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec
+	},
+ 	{ .ctl_name = 0 }
 };
 
 static ctl_table ipq_dir_table[] = {
-	{NET_IPV4, "ipv4", NULL, 0, 0555, ipq_table, 0, 0, 0, 0, 0},
-	{ 0 }
+	{
+		.ctl_name	= NET_IPV4,
+		.procname	= "ipv4",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ipq_table
+	},
+	{ .ctl_name = 0 }
 };
 
 static ctl_table ipq_root_table[] = {
-	{CTL_NET, "net", NULL, 0, 0555, ipq_dir_table, 0, 0, 0, 0, 0},
-	{ 0 }
+	{
+		.ctl_name	= CTL_NET,
+		.procname	= "net",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ipq_dir_table
+	},
+	{ .ctl_name = 0 }
 };
 
 static int
diff -Nru a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
--- a/net/ipv4/netfilter/iptable_filter.c	Fri Feb 14 15:53:09 2003
+++ b/net/ipv4/netfilter/iptable_filter.c	Fri Feb 14 15:53:09 2003
@@ -35,12 +35,12 @@
 } initial_table __initdata
 = { { "filter", FILTER_VALID_HOOKS, 4,
       sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
-      { [NF_IP_LOCAL_IN] 0,
-	[NF_IP_FORWARD] sizeof(struct ipt_standard),
-	[NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2 },
-      { [NF_IP_LOCAL_IN] 0,
-	[NF_IP_FORWARD] sizeof(struct ipt_standard),
-	[NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) * 2 },
+      { [NF_IP_LOCAL_IN] = 0,
+	[NF_IP_FORWARD] = sizeof(struct ipt_standard),
+	[NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },
+      { [NF_IP_LOCAL_IN] = 0,
+	[NF_IP_FORWARD] = sizeof(struct ipt_standard),
+	[NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },
       0, NULL, { } },
     {
 	    /* LOCAL_IN */
diff -Nru a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
--- a/net/ipv4/netfilter/iptable_mangle.c	Fri Feb 14 15:53:12 2003
+++ b/net/ipv4/netfilter/iptable_mangle.c	Fri Feb 14 15:53:12 2003
@@ -48,16 +48,16 @@
 } initial_table __initdata
 = { { "mangle", MANGLE_VALID_HOOKS, 6,
       sizeof(struct ipt_standard) * 5 + sizeof(struct ipt_error),
-      { [NF_IP_PRE_ROUTING] 	0,
-	[NF_IP_LOCAL_IN] 	sizeof(struct ipt_standard),
-	[NF_IP_FORWARD] 	sizeof(struct ipt_standard) * 2,
-	[NF_IP_LOCAL_OUT] 	sizeof(struct ipt_standard) * 3,
-	[NF_IP_POST_ROUTING] 	sizeof(struct ipt_standard) * 4 },
-      { [NF_IP_PRE_ROUTING] 	0,
-	[NF_IP_LOCAL_IN] 	sizeof(struct ipt_standard),
-	[NF_IP_FORWARD] 	sizeof(struct ipt_standard) * 2,
-	[NF_IP_LOCAL_OUT] 	sizeof(struct ipt_standard) * 3,
-	[NF_IP_POST_ROUTING]	sizeof(struct ipt_standard) * 4 },
+      { [NF_IP_PRE_ROUTING] 	= 0,
+	[NF_IP_LOCAL_IN] 	= sizeof(struct ipt_standard),
+	[NF_IP_FORWARD] 	= sizeof(struct ipt_standard) * 2,
+	[NF_IP_LOCAL_OUT] 	= sizeof(struct ipt_standard) * 3,
+	[NF_IP_POST_ROUTING] 	= sizeof(struct ipt_standard) * 4 },
+      { [NF_IP_PRE_ROUTING] 	= 0,
+	[NF_IP_LOCAL_IN] 	= sizeof(struct ipt_standard),
+	[NF_IP_FORWARD] 	= sizeof(struct ipt_standard) * 2,
+	[NF_IP_LOCAL_OUT] 	= sizeof(struct ipt_standard) * 3,
+	[NF_IP_POST_ROUTING]	= sizeof(struct ipt_standard) * 4 },
       0, NULL, { } },
     {
 	    /* PRE_ROUTING */
diff -Nru a/net/ipv4/proc.c b/net/ipv4/proc.c
--- a/net/ipv4/proc.c	Fri Feb 14 15:53:08 2003
+++ b/net/ipv4/proc.c	Fri Feb 14 15:53:08 2003
@@ -99,7 +99,7 @@
 		    *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) +
 					 sizeof (unsigned long) * nr));
 		res +=
-		    *((unsigned long *) (((void *) per_cpu_ptr(mib[0], i)) +
+		    *((unsigned long *) (((void *) per_cpu_ptr(mib[1], i)) +
 					 sizeof (unsigned long) * nr));
 	}
 	return res;
diff -Nru a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
--- a/net/ipv4/sysctl_net_ipv4.c	Fri Feb 14 15:53:12 2003
+++ b/net/ipv4/sysctl_net_ipv4.c	Fri Feb 14 15:53:12 2003
@@ -88,144 +88,465 @@
 }
 
 ctl_table ipv4_table[] = {
-        {NET_IPV4_TCP_TIMESTAMPS, "tcp_timestamps",
-         &sysctl_tcp_timestamps, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-        {NET_IPV4_TCP_WINDOW_SCALING, "tcp_window_scaling",
-         &sysctl_tcp_window_scaling, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-        {NET_IPV4_TCP_SACK, "tcp_sack",
-         &sysctl_tcp_sack, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-        {NET_IPV4_TCP_RETRANS_COLLAPSE, "tcp_retrans_collapse",
-         &sysctl_tcp_retrans_collapse, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-        {NET_IPV4_FORWARD, "ip_forward",
-         &ipv4_devconf.forwarding, sizeof(int), 0644, NULL,
-         &ipv4_sysctl_forward,&ipv4_sysctl_forward_strategy},
-        {NET_IPV4_DEFAULT_TTL, "ip_default_ttl",
-         &sysctl_ip_default_ttl, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-        {NET_IPV4_AUTOCONFIG, "ip_autoconfig",
-         &ipv4_config.autoconfig, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-        {NET_IPV4_NO_PMTU_DISC, "ip_no_pmtu_disc",
-         &ipv4_config.no_pmtu_disc, sizeof(int), 0644, NULL,
-         &proc_dointvec},
-	{NET_IPV4_NONLOCAL_BIND, "ip_nonlocal_bind",
-	 &sysctl_ip_nonlocal_bind, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_IPV4_TCP_SYN_RETRIES, "tcp_syn_retries",
-	 &sysctl_tcp_syn_retries, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_SYNACK_RETRIES, "tcp_synack_retries",
-	 &sysctl_tcp_synack_retries, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_MAX_ORPHANS, "tcp_max_orphans",
-	 &sysctl_tcp_max_orphans, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_MAX_TW_BUCKETS, "tcp_max_tw_buckets",
-	 &sysctl_tcp_max_tw_buckets, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_IPV4_IPFRAG_HIGH_THRESH, "ipfrag_high_thresh",
-	 &sysctl_ipfrag_high_thresh, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_IPV4_IPFRAG_LOW_THRESH, "ipfrag_low_thresh",
-	 &sysctl_ipfrag_low_thresh, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_IPV4_DYNADDR, "ip_dynaddr",
-	 &sysctl_ip_dynaddr, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_IPV4_IPFRAG_TIME, "ipfrag_time",
-	 &sysctl_ipfrag_time, sizeof(int), 0644, NULL, &proc_dointvec_jiffies, 
-	 &sysctl_jiffies},
-	{NET_IPV4_TCP_KEEPALIVE_TIME, "tcp_keepalive_time",
-	 &sysctl_tcp_keepalive_time, sizeof(int), 0644, NULL, 
-	 &proc_dointvec_jiffies, &sysctl_jiffies},
-	{NET_IPV4_TCP_KEEPALIVE_PROBES, "tcp_keepalive_probes",
-	 &sysctl_tcp_keepalive_probes, sizeof(int), 0644, NULL, 
-	 &proc_dointvec},
-	{NET_IPV4_TCP_KEEPALIVE_INTVL, "tcp_keepalive_intvl",
-	 &sysctl_tcp_keepalive_intvl, sizeof(int), 0644, NULL,
-	 &proc_dointvec_jiffies, &sysctl_jiffies},
-	{NET_IPV4_TCP_RETRIES1, "tcp_retries1",
-	 &sysctl_tcp_retries1, sizeof(int), 0644, NULL, &proc_dointvec_minmax, 
-	 &sysctl_intvec, NULL, NULL, &tcp_retr1_max},
-	{NET_IPV4_TCP_RETRIES2, "tcp_retries2",
-	 &sysctl_tcp_retries2, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_IPV4_TCP_FIN_TIMEOUT, "tcp_fin_timeout",
-	 &sysctl_tcp_fin_timeout, sizeof(int), 0644, NULL, 
-	 &proc_dointvec_jiffies, &sysctl_jiffies},
+        {
+		.ctl_name	= NET_IPV4_TCP_TIMESTAMPS,
+		.procname	= "tcp_timestamps",
+		.data		= &sysctl_tcp_timestamps,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+        {
+		.ctl_name	= NET_IPV4_TCP_WINDOW_SCALING,
+		.procname	= "tcp_window_scaling",
+		.data		= &sysctl_tcp_window_scaling,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+        {
+		.ctl_name	= NET_IPV4_TCP_SACK,
+		.procname	= "tcp_sack",
+		.data		= &sysctl_tcp_sack,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+        {
+		.ctl_name	= NET_IPV4_TCP_RETRANS_COLLAPSE,
+		.procname	= "tcp_retrans_collapse",
+		.data		= &sysctl_tcp_retrans_collapse,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+        {
+		.ctl_name	= NET_IPV4_FORWARD,
+		.procname	= "ip_forward",
+		.data		= &ipv4_devconf.forwarding,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &ipv4_sysctl_forward,
+		.strategy	= &ipv4_sysctl_forward_strategy
+	},
+        {
+		.ctl_name	= NET_IPV4_DEFAULT_TTL,
+		.procname	= "ip_default_ttl",
+ 		.data		= &sysctl_ip_default_ttl,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+        {
+		.ctl_name	= NET_IPV4_AUTOCONFIG,
+		.procname	= "ip_autoconfig",
+		.data		= &ipv4_config.autoconfig,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+        {
+		.ctl_name	= NET_IPV4_NO_PMTU_DISC,
+		.procname	= "ip_no_pmtu_disc",
+		.data		= &ipv4_config.no_pmtu_disc,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_NONLOCAL_BIND,
+		.procname	= "ip_nonlocal_bind",
+		.data		= &sysctl_ip_nonlocal_bind,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_TCP_SYN_RETRIES,
+		.procname	= "tcp_syn_retries",
+		.data		= &sysctl_tcp_syn_retries,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_SYNACK_RETRIES,
+		.procname	= "tcp_synack_retries",
+		.data		= &sysctl_tcp_synack_retries,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_MAX_ORPHANS,
+		.procname	= "tcp_max_orphans",
+		.data		= &sysctl_tcp_max_orphans,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_MAX_TW_BUCKETS,
+		.procname	= "tcp_max_tw_buckets",
+		.data		= &sysctl_tcp_max_tw_buckets,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_IPFRAG_HIGH_THRESH,
+		.procname	= "ipfrag_high_thresh",
+		.data		= &sysctl_ipfrag_high_thresh,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_IPFRAG_LOW_THRESH,
+		.procname	= "ipfrag_low_thresh",
+		.data		= &sysctl_ipfrag_low_thresh,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_DYNADDR,
+		.procname	= "ip_dynaddr",
+		.data		= &sysctl_ip_dynaddr,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_IPFRAG_TIME,
+		.procname	= "ipfrag_time",
+		.data		= &sysctl_ipfrag_time,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
+	{
+		.ctl_name	= NET_IPV4_TCP_KEEPALIVE_TIME,
+		.procname	= "tcp_keepalive_time",
+		.data		= &sysctl_tcp_keepalive_time,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
+	{
+		.ctl_name	= NET_IPV4_TCP_KEEPALIVE_PROBES,
+		.procname	= "tcp_keepalive_probes",
+		.data		= &sysctl_tcp_keepalive_probes,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_TCP_KEEPALIVE_INTVL,
+		.procname	= "tcp_keepalive_intvl",
+		.data		= &sysctl_tcp_keepalive_intvl,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
+	{
+		.ctl_name	= NET_IPV4_TCP_RETRIES1,
+		.procname	= "tcp_retries1",
+		.data		= &sysctl_tcp_retries1,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra2		= &tcp_retr1_max
+	},
+	{
+		.ctl_name	= NET_IPV4_TCP_RETRIES2,
+		.procname	= "tcp_retries2",
+		.data		= &sysctl_tcp_retries2,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_TCP_FIN_TIMEOUT,
+		.procname	= "tcp_fin_timeout",
+		.data		= &sysctl_tcp_fin_timeout,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
 #ifdef CONFIG_SYN_COOKIES
-	{NET_TCP_SYNCOOKIES, "tcp_syncookies",
-	 &sysctl_tcp_syncookies, sizeof(int), 0644, NULL, &proc_dointvec},
+	{
+		.ctl_name	= NET_TCP_SYNCOOKIES,
+		.procname	= "tcp_syncookies",
+		.data		= &sysctl_tcp_syncookies,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
 #endif
-	{NET_TCP_TW_RECYCLE, "tcp_tw_recycle",
-	 &sysctl_tcp_tw_recycle, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_ABORT_ON_OVERFLOW, "tcp_abort_on_overflow",
-	 &sysctl_tcp_abort_on_overflow, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_STDURG, "tcp_stdurg", &sysctl_tcp_stdurg,
-	 sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_RFC1337, "tcp_rfc1337", &sysctl_tcp_rfc1337,
-	 sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_MAX_SYN_BACKLOG, "tcp_max_syn_backlog", &sysctl_max_syn_backlog,
-	 sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_IPV4_LOCAL_PORT_RANGE, "ip_local_port_range",
-	 &sysctl_local_port_range, sizeof(sysctl_local_port_range), 0644, 
-	 NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL,
-	 ip_local_port_range_min, ip_local_port_range_max },
-	{NET_IPV4_ICMP_ECHO_IGNORE_ALL, "icmp_echo_ignore_all",
-	 &sysctl_icmp_echo_ignore_all, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS, "icmp_echo_ignore_broadcasts",
-	 &sysctl_icmp_echo_ignore_broadcasts, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES, "icmp_ignore_bogus_error_responses",
-	 &sysctl_icmp_ignore_bogus_error_responses, sizeof(int), 0644, NULL,
-	 &proc_dointvec},
-	{NET_IPV4_ROUTE, "route", NULL, 0, 0555, ipv4_route_table},
+	{
+		.ctl_name	= NET_TCP_TW_RECYCLE,
+		.procname	= "tcp_tw_recycle",
+		.data		= &sysctl_tcp_tw_recycle,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_ABORT_ON_OVERFLOW,
+		.procname	= "tcp_abort_on_overflow",
+		.data		= &sysctl_tcp_abort_on_overflow,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_STDURG,
+		.procname	= "tcp_stdurg",
+		.data		= &sysctl_tcp_stdurg,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_RFC1337,
+		.procname	= "tcp_rfc1337",
+		.data		= &sysctl_tcp_rfc1337,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_MAX_SYN_BACKLOG,
+		.procname	= "tcp_max_syn_backlog",
+		.data		= &sysctl_max_syn_backlog,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_LOCAL_PORT_RANGE,
+		.procname	= "ip_local_port_range",
+		.data		= &sysctl_local_port_range,
+		.maxlen		= sizeof(sysctl_local_port_range),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= ip_local_port_range_min,
+		.extra2		= ip_local_port_range_max
+	},
+	{
+		.ctl_name	= NET_IPV4_ICMP_ECHO_IGNORE_ALL,
+		.procname	= "icmp_echo_ignore_all",
+		.data		= &sysctl_icmp_echo_ignore_all,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS,
+		.procname	= "icmp_echo_ignore_broadcasts",
+		.data		= &sysctl_icmp_echo_ignore_broadcasts,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES,
+		.procname	= "icmp_ignore_bogus_error_responses",
+		.data		= &sysctl_icmp_ignore_bogus_error_responses,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_ROUTE,
+		.procname	= "route",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ipv4_route_table
+	},
 #ifdef CONFIG_IP_MULTICAST
-	{NET_IPV4_IGMP_MAX_MEMBERSHIPS, "igmp_max_memberships",
-	 &sysctl_igmp_max_memberships, sizeof(int), 0644, NULL, &proc_dointvec},
+	{
+		.ctl_name	= NET_IPV4_IGMP_MAX_MEMBERSHIPS,
+		.procname	= "igmp_max_memberships",
+		.data		= &sysctl_igmp_max_memberships,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+
 #endif
-	{NET_IPV4_INET_PEER_THRESHOLD, "inet_peer_threshold",
-	 &inet_peer_threshold, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_IPV4_INET_PEER_MINTTL, "inet_peer_minttl",
-	 &inet_peer_minttl, sizeof(int), 0644, NULL,
-	 &proc_dointvec_jiffies, &sysctl_jiffies},
-	{NET_IPV4_INET_PEER_MAXTTL, "inet_peer_maxttl",
-	 &inet_peer_maxttl, sizeof(int), 0644, NULL,
-	 &proc_dointvec_jiffies, &sysctl_jiffies},
-	{NET_IPV4_INET_PEER_GC_MINTIME, "inet_peer_gc_mintime",
-	 &inet_peer_gc_mintime, sizeof(int), 0644, NULL,
-	 &proc_dointvec_jiffies, &sysctl_jiffies},
-	{NET_IPV4_INET_PEER_GC_MAXTIME, "inet_peer_gc_maxtime",
-	 &inet_peer_gc_maxtime, sizeof(int), 0644, NULL,
-	 &proc_dointvec_jiffies, &sysctl_jiffies},
-	{NET_TCP_ORPHAN_RETRIES, "tcp_orphan_retries",
-	 &sysctl_tcp_orphan_retries, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_FACK, "tcp_fack",
-	 &sysctl_tcp_fack, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_REORDERING, "tcp_reordering",
-	 &sysctl_tcp_reordering, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_ECN, "tcp_ecn",
-	 &sysctl_tcp_ecn, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_DSACK, "tcp_dsack",
-	 &sysctl_tcp_dsack, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_MEM, "tcp_mem",
-	 &sysctl_tcp_mem, sizeof(sysctl_tcp_mem), 0644, NULL, &proc_dointvec},
-	{NET_TCP_WMEM, "tcp_wmem",
-	 &sysctl_tcp_wmem, sizeof(sysctl_tcp_wmem), 0644, NULL, &proc_dointvec},
-	{NET_TCP_RMEM, "tcp_rmem",
-	 &sysctl_tcp_rmem, sizeof(sysctl_tcp_rmem), 0644, NULL, &proc_dointvec},
-	{NET_TCP_APP_WIN, "tcp_app_win",
-	 &sysctl_tcp_app_win, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_ADV_WIN_SCALE, "tcp_adv_win_scale",
-	 &sysctl_tcp_adv_win_scale, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_IPV4_ICMP_RATELIMIT, "icmp_ratelimit",
-	 &sysctl_icmp_ratelimit, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_IPV4_ICMP_RATEMASK, "icmp_ratemask",
-	 &sysctl_icmp_ratemask, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_TW_REUSE, "tcp_tw_reuse",
-	 &sysctl_tcp_tw_reuse, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_FRTO, "tcp_frto",
-	 &sysctl_tcp_frto, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_TCP_LOW_LATENCY, "tcp_low_latency",
-	 &sysctl_tcp_low_latency, sizeof(int), 0644, NULL, &proc_dointvec},
-	{0}
+	{
+		.ctl_name	= NET_IPV4_INET_PEER_THRESHOLD,
+		.procname	= "inet_peer_threshold",
+		.data		= &inet_peer_threshold,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_INET_PEER_MINTTL,
+		.procname	= "inet_peer_minttl",
+		.data		= &inet_peer_minttl,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
+	{
+		.ctl_name	= NET_IPV4_INET_PEER_MAXTTL,
+		.procname	= "inet_peer_maxttl",
+		.data		= &inet_peer_maxttl,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
+	{
+		.ctl_name	= NET_IPV4_INET_PEER_GC_MINTIME,
+		.procname	= "inet_peer_gc_mintime",
+		.data		= &inet_peer_gc_mintime,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
+	{
+		.ctl_name	= NET_IPV4_INET_PEER_GC_MAXTIME,
+		.procname	= "inet_peer_gc_maxtime",
+		.data		= &inet_peer_gc_maxtime,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
+	{
+		.ctl_name	= NET_TCP_ORPHAN_RETRIES,
+		.procname	= "tcp_orphan_retries",
+		.data		= &sysctl_tcp_orphan_retries,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_FACK,
+		.procname	= "tcp_fack",
+		.data		= &sysctl_tcp_fack,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_REORDERING,
+		.procname	= "tcp_reordering",
+		.data		= &sysctl_tcp_reordering,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_ECN,
+		.procname	= "tcp_ecn",
+		.data		= &sysctl_tcp_ecn,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_DSACK,
+		.procname	= "tcp_dsack",
+		.data		= &sysctl_tcp_dsack,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_MEM,
+		.procname	= "tcp_mem",
+		.data		= &sysctl_tcp_mem,
+		.maxlen		= sizeof(sysctl_tcp_mem),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_WMEM,
+		.procname	= "tcp_wmem",
+		.data		= &sysctl_tcp_wmem,
+		.maxlen		= sizeof(sysctl_tcp_wmem),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_RMEM,
+		.procname	= "tcp_rmem",
+		.data		= &sysctl_tcp_rmem,
+		.maxlen		= sizeof(sysctl_tcp_rmem),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_APP_WIN,
+		.procname	= "tcp_app_win",
+		.data		= &sysctl_tcp_app_win,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_ADV_WIN_SCALE,
+		.procname	= "tcp_adv_win_scale",
+		.data		= &sysctl_tcp_adv_win_scale,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_ICMP_RATELIMIT,
+		.procname	= "icmp_ratelimit",
+		.data		= &sysctl_icmp_ratelimit,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_IPV4_ICMP_RATEMASK,
+		.procname	= "icmp_ratemask",
+		.data		= &sysctl_icmp_ratemask,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_TW_REUSE,
+		.procname	= "tcp_tw_reuse",
+		.data		= &sysctl_tcp_tw_reuse,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_FRTO,
+		.procname	= "tcp_frto",
+		.data		= &sysctl_tcp_frto,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_TCP_LOW_LATENCY,
+		.procname	= "tcp_low_latency",
+		.data		= &sysctl_tcp_low_latency,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{ .ctl_name = 0 }
 };
 
 #endif /* CONFIG_SYSCTL */
diff -Nru a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
--- a/net/ipv4/tcp_output.c	Fri Feb 14 15:53:12 2003
+++ b/net/ipv4/tcp_output.c	Fri Feb 14 15:53:12 2003
@@ -1522,7 +1522,8 @@
 	}
 
 	if (err <= 0) {
-		tp->backoff++;
+		if (tp->backoff < sysctl_tcp_retries2)
+			tp->backoff++;
 		tp->probes_out++;
 		tcp_reset_xmit_timer (sk, TCP_TIME_PROBE0, 
 				      min(tp->rto << tp->backoff, TCP_RTO_MAX));
diff -Nru a/net/ipv4/xfrm_state.c b/net/ipv4/xfrm_state.c
--- a/net/ipv4/xfrm_state.c	Fri Feb 14 15:53:12 2003
+++ b/net/ipv4/xfrm_state.c	Fri Feb 14 15:53:12 2003
@@ -1,6 +1,7 @@
 #include <net/xfrm.h>
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
+#include <net/ipv6.h>
 
 /* Each xfrm_state may be linked to two tables:
 
@@ -219,7 +220,8 @@
 
 	spin_lock_bh(&xfrm_state_lock);
 	list_for_each_entry(x, xfrm_state_bydst+h, bydst) {
-		if (daddr == x->id.daddr.xfrm4_addr &&
+		if (x->props.family == AF_INET &&
+		    daddr == x->id.daddr.xfrm4_addr &&
 		    x->props.reqid == tmpl->reqid &&
 		    (saddr == x->props.saddr.xfrm4_addr || !saddr || !x->props.saddr.xfrm4_addr) &&
 		    tmpl->mode == x->props.mode &&
@@ -282,6 +284,7 @@
 		x->id = tmpl->id;
 		if (x->id.daddr.xfrm4_addr == 0)
 			x->id.daddr.xfrm4_addr = daddr;
+		x->props.family = AF_INET;
 		x->props.saddr = tmpl->saddr;
 		if (x->props.saddr.xfrm4_addr == 0)
 			x->props.saddr.xfrm4_addr = saddr;
@@ -317,7 +320,12 @@
 
 void xfrm_state_insert(struct xfrm_state *x)
 {
-	unsigned h = ntohl(x->id.daddr.xfrm4_addr);
+	unsigned h = 0;
+
+	if (x->props.family == AF_INET)
+		h = ntohl(x->id.daddr.xfrm4_addr);
+	else if (x->props.family == AF_INET6)
+		h = ntohl(x->id.daddr.a6[2]^x->id.daddr.a6[3]);
 
 	h = (h ^ (h>>16)) % XFRM_DST_HSIZE;
 
@@ -325,7 +333,10 @@
 	list_add(&x->bydst, xfrm_state_bydst+h);
 	atomic_inc(&x->refcnt);
 
-	h = ntohl(x->id.daddr.xfrm4_addr^x->id.spi^x->id.proto);
+	if (x->props.family == AF_INET)
+		h = ntohl(x->id.daddr.xfrm4_addr^x->id.spi^x->id.proto);
+	else
+		h = ntohl(x->id.daddr.a6[2]^x->id.daddr.a6[3]^x->id.spi^x->id.proto);
 	h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE;
 	list_add(&x->byspi, xfrm_state_byspi+h);
 	atomic_inc(&x->refcnt);
@@ -382,7 +393,8 @@
 
 	spin_lock_bh(&xfrm_state_lock);
 	list_for_each_entry(x, xfrm_state_byspi+h, byspi) {
-		if (spi == x->id.spi &&
+		if (x->props.family == AF_INET &&
+		    spi == x->id.spi &&
 		    daddr == x->id.daddr.xfrm4_addr &&
 		    proto == x->id.proto) {
 			atomic_inc(&x->refcnt);
@@ -405,7 +417,8 @@
 
 	spin_lock_bh(&xfrm_state_lock);
 	list_for_each_entry(x, xfrm_state_bydst+h, bydst) {
-		if (daddr == x->id.daddr.xfrm4_addr &&
+		if (x->props.family == AF_INET &&
+		    daddr == x->id.daddr.xfrm4_addr &&
 		    mode == x->props.mode &&
 		    proto == x->id.proto &&
 		    saddr == x->props.saddr.xfrm4_addr &&
@@ -432,6 +445,7 @@
 		x0->km.state = XFRM_STATE_ACQ;
 		x0->id.daddr.xfrm4_addr = daddr;
 		x0->id.proto = proto;
+		x0->props.family = AF_INET;
 		x0->props.mode = mode;
 		x0->props.reqid = reqid;
 		x0->lft.hard_add_expires_seconds = ACQ_EXPIRES;
@@ -591,8 +605,14 @@
 	int i;
 
 	for (i=0; i<n; i++) {
-		if (!xfrm4_selector_match(&x[i]->sel, fl))
+		if (x[i]->props.family == AF_INET &&
+		    !xfrm4_selector_match(&x[i]->sel, fl))
+			return -EINVAL;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+		if (x[i]->props.family == AF_INET6 &&
+		    !xfrm6_selector_match(&x[i]->sel, fl))
 			return -EINVAL;
+#endif
 	}
 	return 0;
 }
@@ -701,3 +721,119 @@
 		INIT_LIST_HEAD(&xfrm_state_byspi[i]);
 	}
 }
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+struct xfrm_state *
+xfrm6_state_lookup(struct in6_addr *daddr, u32 spi, u8 proto)
+{
+	unsigned h = ntohl(daddr->s6_addr32[2]^daddr->s6_addr32[3]^spi^proto);
+	struct xfrm_state *x;
+
+	h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE;
+
+	spin_lock_bh(&xfrm_state_lock);
+	list_for_each_entry(x, xfrm_state_byspi+h, byspi) {
+		if (x->props.family == AF_INET6 &&
+		    spi == x->id.spi &&
+		    !ipv6_addr_cmp(daddr, (struct in6_addr *)x->id.daddr.a6) &&
+		    proto == x->id.proto) {
+			atomic_inc(&x->refcnt);
+			spin_unlock_bh(&xfrm_state_lock);
+			return x;
+		}
+	}
+	spin_unlock_bh(&xfrm_state_lock);
+	return NULL;
+}
+
+struct xfrm_state *
+xfrm6_find_acq(u8 mode, u16 reqid, u8 proto, struct in6_addr *daddr, struct in6_addr *saddr, int create)
+{
+	struct xfrm_state *x, *x0;
+	unsigned h = ntohl(daddr->s6_addr32[2]^daddr->s6_addr32[3]);
+
+	h = (h ^ (h>>16)) % XFRM_DST_HSIZE;
+	x0 = NULL;
+
+	spin_lock_bh(&xfrm_state_lock);
+	list_for_each_entry(x, xfrm_state_bydst+h, bydst) {
+		if (x->props.family == AF_INET6 &&
+		    !memcmp(daddr, x->id.daddr.a6, sizeof(struct in6_addr)) &&
+		    mode == x->props.mode &&
+		    proto == x->id.proto &&
+		    !memcmp(saddr, x->props.saddr.a6, sizeof(struct in6_addr)) &&
+		    reqid == x->props.reqid &&
+		    x->km.state == XFRM_STATE_ACQ) {
+			    if (!x0)
+				    x0 = x;
+			    if (x->id.spi)
+				    continue;
+			    x0 = x;
+			    break;
+		    }
+	}
+	if (x0) {
+		atomic_inc(&x0->refcnt);
+	} else if (create && (x0 = xfrm_state_alloc()) != NULL) {
+		memcpy(x0->sel.daddr.a6, daddr, sizeof(struct in6_addr));
+		memcpy(x0->sel.saddr.a6, saddr, sizeof(struct in6_addr));
+		x0->sel.prefixlen_d = 128;
+		x0->sel.prefixlen_s = 128;
+		memcpy(x0->props.saddr.a6, saddr, sizeof(struct in6_addr));
+		x0->km.state = XFRM_STATE_ACQ;
+		memcpy(x0->id.daddr.a6, daddr, sizeof(struct in6_addr));
+		x0->id.proto = proto;
+		x0->props.family = AF_INET6;
+		x0->props.mode = mode;
+		x0->props.reqid = reqid;
+		x0->lft.hard_add_expires_seconds = ACQ_EXPIRES;
+		atomic_inc(&x0->refcnt);
+		mod_timer(&x0->timer, jiffies + ACQ_EXPIRES*HZ);
+		atomic_inc(&x0->refcnt);
+		list_add_tail(&x0->bydst, xfrm_state_bydst+h);
+		wake_up(&km_waitq);
+	}
+	spin_unlock_bh(&xfrm_state_lock);
+	return x0;
+}
+
+void
+xfrm6_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi)
+{
+	u32 h;
+	struct xfrm_state *x0;
+
+	if (x->id.spi)
+		return;
+
+	if (minspi == maxspi) {
+		x0 = xfrm6_state_lookup((struct in6_addr*)x->id.daddr.a6, minspi, x->id.proto);
+		if (x0) {
+			xfrm_state_put(x0);
+			return;
+		}
+		x->id.spi = minspi;
+	} else {
+		u32 spi = 0;
+		minspi = ntohl(minspi);
+		maxspi = ntohl(maxspi);
+		for (h=0; h<maxspi-minspi+1; h++) {
+			spi = minspi + net_random()%(maxspi-minspi+1);
+			x0 = xfrm6_state_lookup((struct in6_addr*)x->id.daddr.a6, htonl(spi), x->id.proto);
+			if (x0 == NULL)
+				break;
+			xfrm_state_put(x0);
+		}
+		x->id.spi = htonl(spi);
+	}
+	if (x->id.spi) {
+		spin_lock_bh(&xfrm_state_lock);
+		h = ntohl(x->id.daddr.a6[2]^x->id.daddr.a6[3]^x->id.spi^x->id.proto);
+		h = (h ^ (h>>10) ^ (h>>20)) % XFRM_DST_HSIZE;
+		list_add(&x->byspi, xfrm_state_byspi+h);
+		atomic_inc(&x->refcnt);
+		spin_unlock_bh(&xfrm_state_lock);
+		wake_up(&km_waitq);
+	}
+}
+#endif /* CONFIG_IPV6 || CONFIG_IPV6_MODULE */
diff -Nru a/net/ipv6/Makefile b/net/ipv6/Makefile
--- a/net/ipv6/Makefile	Fri Feb 14 15:53:12 2003
+++ b/net/ipv6/Makefile	Fri Feb 14 15:53:12 2003
@@ -11,3 +11,5 @@
 		ip6_flowlabel.o ipv6_syms.o
 
 obj-$(CONFIG_NETFILTER)	+= netfilter/
+
+obj-y += xfrm_policy.o
diff -Nru a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c
--- a/net/ipv6/ipv6_syms.c	Fri Feb 14 15:53:12 2003
+++ b/net/ipv6/ipv6_syms.c	Fri Feb 14 15:53:12 2003
@@ -4,6 +4,7 @@
 #include <net/ipv6.h>
 #include <net/addrconf.h>
 #include <net/ip6_route.h>
+#include <net/xfrm.h>
 
 EXPORT_SYMBOL(ipv6_addr_type);
 EXPORT_SYMBOL(icmpv6_send);
@@ -25,3 +26,6 @@
 EXPORT_SYMBOL(inet6_ioctl);
 EXPORT_SYMBOL(ipv6_get_saddr);
 EXPORT_SYMBOL(ipv6_chk_addr);
+EXPORT_SYMBOL(xfrm6_register_type);
+EXPORT_SYMBOL(xfrm6_unregister_type);
+EXPORT_SYMBOL(xfrm6_get_type);
diff -Nru a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
--- a/net/ipv6/netfilter/ip6_queue.c	Fri Feb 14 15:53:09 2003
+++ b/net/ipv6/netfilter/ip6_queue.c	Fri Feb 14 15:53:09 2003
@@ -628,19 +628,37 @@
 static struct ctl_table_header *ipq_sysctl_header;
 
 static ctl_table ipq_table[] = {
-	{ NET_IPQ_QMAX, NET_IPQ_QMAX_NAME, &sysctl_maxlen,
-	  sizeof(sysctl_maxlen), 0644,  NULL, proc_dointvec },
- 	{ 0 }
+	{
+		.ctl_name	= NET_IPQ_QMAX,
+		.procname	= NET_IPQ_QMAX_NAME,
+		.data		= &sysctl_maxlen,
+		.maxlen		= sizeof(sysctl_maxlen),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec
+	},
+ 	{ .ctl_name = 0 }
 };
 
 static ctl_table ipq_dir_table[] = {
-	{NET_IPV6, "ipv6", NULL, 0, 0555, ipq_table, 0, 0, 0, 0, 0},
-	{ 0 }
+	{
+		.ctl_name	= NET_IPV6,
+		.procname	= "ipv6",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ipq_table
+	},
+	{ .ctl_name = 0 }
 };
 
 static ctl_table ipq_root_table[] = {
-	{CTL_NET, "net", NULL, 0, 0555, ipq_dir_table, 0, 0, 0, 0, 0},
-	{ 0 }
+	{
+		.ctl_name	= CTL_NET,
+		.procname	= "net",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ipq_dir_table
+	},
+	{ .ctl_name = 0 }
 };
 
 static int
diff -Nru a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
--- a/net/ipv6/netfilter/ip6table_filter.c	Fri Feb 14 15:53:08 2003
+++ b/net/ipv6/netfilter/ip6table_filter.c	Fri Feb 14 15:53:08 2003
@@ -35,12 +35,12 @@
 } initial_table __initdata
 = { { "filter", FILTER_VALID_HOOKS, 4,
       sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
-      { [NF_IP6_LOCAL_IN] 0,
-	[NF_IP6_FORWARD] sizeof(struct ip6t_standard),
-	[NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) * 2 },
-      { [NF_IP6_LOCAL_IN] 0,
-	[NF_IP6_FORWARD] sizeof(struct ip6t_standard),
-	[NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) * 2 },
+      { [NF_IP6_LOCAL_IN] = 0,
+	[NF_IP6_FORWARD] = sizeof(struct ip6t_standard),
+	[NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 },
+      { [NF_IP6_LOCAL_IN] = 0,
+	[NF_IP6_FORWARD] = sizeof(struct ip6t_standard),
+	[NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2 },
       0, NULL, { } },
     {
 	    /* LOCAL_IN */
diff -Nru a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
--- a/net/ipv6/netfilter/ip6table_mangle.c	Fri Feb 14 15:53:09 2003
+++ b/net/ipv6/netfilter/ip6table_mangle.c	Fri Feb 14 15:53:09 2003
@@ -45,16 +45,16 @@
 } initial_table __initdata
 = { { "mangle", MANGLE_VALID_HOOKS, 6,
       sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error),
-      { [NF_IP6_PRE_ROUTING] 	0,
-	[NF_IP6_LOCAL_IN]	sizeof(struct ip6t_standard),
-	[NF_IP6_FORWARD]	sizeof(struct ip6t_standard) * 2,
-	[NF_IP6_LOCAL_OUT] 	sizeof(struct ip6t_standard) * 3,
-	[NF_IP6_POST_ROUTING]	sizeof(struct ip6t_standard) * 4},
-      { [NF_IP6_PRE_ROUTING] 	0,
-	[NF_IP6_LOCAL_IN]	sizeof(struct ip6t_standard),
-	[NF_IP6_FORWARD]	sizeof(struct ip6t_standard) * 2,
-	[NF_IP6_LOCAL_OUT] 	sizeof(struct ip6t_standard) * 3,
-	[NF_IP6_POST_ROUTING]	sizeof(struct ip6t_standard) * 4},
+      { [NF_IP6_PRE_ROUTING] 	= 0,
+	[NF_IP6_LOCAL_IN]	= sizeof(struct ip6t_standard),
+	[NF_IP6_FORWARD]	= sizeof(struct ip6t_standard) * 2,
+	[NF_IP6_LOCAL_OUT] 	= sizeof(struct ip6t_standard) * 3,
+	[NF_IP6_POST_ROUTING]	= sizeof(struct ip6t_standard) * 4},
+      { [NF_IP6_PRE_ROUTING] 	= 0,
+	[NF_IP6_LOCAL_IN]	= sizeof(struct ip6t_standard),
+	[NF_IP6_FORWARD]	= sizeof(struct ip6t_standard) * 2,
+	[NF_IP6_LOCAL_OUT] 	= sizeof(struct ip6t_standard) * 3,
+	[NF_IP6_POST_ROUTING]	= sizeof(struct ip6t_standard) * 4},
       0, NULL, { } },
     {
 	    /* PRE_ROUTING */
diff -Nru a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
--- a/net/ipv6/sysctl_net_ipv6.c	Fri Feb 14 15:53:08 2003
+++ b/net/ipv6/sysctl_net_ipv6.c	Fri Feb 14 15:53:08 2003
@@ -20,24 +20,54 @@
 #ifdef CONFIG_SYSCTL
 
 ctl_table ipv6_table[] = {
-	{NET_IPV6_ROUTE, "route", NULL, 0, 0555, ipv6_route_table},
-	{NET_IPV6_ICMP, "icmp", NULL, 0, 0500, ipv6_icmp_table},
-	{NET_IPV6_BINDV6ONLY, "bindv6only",
-	 &sysctl_ipv6_bindv6only, sizeof(int), 0644, NULL, &proc_dointvec},
-	{0}
+	{
+		.ctl_name	= NET_IPV6_ROUTE,
+		.procname	= "route",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ipv6_route_table
+	},
+	{
+		.ctl_name	= NET_IPV6_ICMP,
+		.procname	= "icmp",
+		.maxlen		= 0,
+		.mode		= 0500,
+		.child		= ipv6_icmp_table
+	},
+	{
+		.ctl_name	= NET_IPV6_BINDV6ONLY,
+		.procname	= "bindv6only",
+		.data		= &sysctl_ipv6_bindv6only,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{ .ctl_name = 0 }
 };
 
 #ifdef MODULE
 static struct ctl_table_header *ipv6_sysctl_header;
 
 static ctl_table ipv6_net_table[] = {
-	{NET_IPV6, "ipv6", NULL, 0, 0555, ipv6_table},
-        {0}
+	{
+		.ctl_name	= NET_IPV6,
+		.procname	= "ipv6",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ipv6_table
+	},
+        { .ctl_name = 0 }
 };
 
 static ctl_table ipv6_root_table[] = {
-	{CTL_NET, "net", NULL, 0, 0555, ipv6_net_table},
-        {0}
+	{
+		.ctl_name	= CTL_NET,
+		.procname	= "net",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ipv6_net_table
+	},
+        { .ctl_name = 0 }
 };
 
 void ipv6_sysctl_register(void)
diff -Nru a/net/ipv6/xfrm_policy.c b/net/ipv6/xfrm_policy.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/ipv6/xfrm_policy.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,43 @@
+#include <net/xfrm.h>
+#include <net/ip.h>
+
+static struct xfrm_type *xfrm6_type_map[256];
+static rwlock_t xfrm6_type_lock = RW_LOCK_UNLOCKED;
+
+int xfrm6_register_type(struct xfrm_type *type)
+{
+	int err = 0;
+
+	write_lock(&xfrm6_type_lock);
+	if (xfrm6_type_map[type->proto] == NULL)
+		xfrm6_type_map[type->proto] = type;
+	else
+		err = -EEXIST;
+	write_unlock(&xfrm6_type_lock);
+	return err;
+}
+
+int xfrm6_unregister_type(struct xfrm_type *type)
+{
+	int err = 0;
+
+	write_lock(&xfrm6_type_lock);
+	if (xfrm6_type_map[type->proto] != type)
+		err = -ENOENT;
+	else
+		xfrm6_type_map[type->proto] = NULL;
+	write_unlock(&xfrm6_type_lock);
+	return err;
+}
+
+struct xfrm_type *xfrm6_get_type(u8 proto)
+{
+	struct xfrm_type *type;
+
+	read_lock(&xfrm6_type_lock);
+	type = xfrm6_type_map[proto];
+	if (type && !try_module_get(type->owner))
+		type = NULL;
+	read_unlock(&xfrm6_type_lock);
+	return type;
+}
diff -Nru a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c
--- a/net/irda/ircomm/ircomm_param.c	Fri Feb 14 15:53:10 2003
+++ b/net/irda/ircomm/ircomm_param.c	Fri Feb 14 15:53:10 2003
@@ -442,7 +442,9 @@
 		param->pv.i = self->settings.dte;
 	else {
 		dte = (__u8) param->pv.i;
-		
+
+		self->settings.dce = 0;
+				
 		if (dte & IRCOMM_DELTA_DTR)
 			self->settings.dce |= (IRCOMM_DELTA_DSR|
 					      IRCOMM_DELTA_RI |
diff -Nru a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
--- a/net/irda/ircomm/ircomm_tty.c	Fri Feb 14 15:53:09 2003
+++ b/net/irda/ircomm/ircomm_tty.c	Fri Feb 14 15:53:09 2003
@@ -490,7 +490,8 @@
 	if (line < 0x10) {
 		self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE;
 		self->settings.service_type = IRCOMM_9_WIRE; /* 9 wire as default */
-		self->settings.dce = IRCOMM_CTS | IRCOMM_CD; /* Default line settings */
+		/* Jan Kiszka -> add DSR/RI -> Conform to IrCOMM spec */
+		self->settings.dce = IRCOMM_CTS | IRCOMM_CD | IRCOMM_DSR | IRCOMM_RI; /* Default line settings */
 		IRDA_DEBUG(2, "%s(), IrCOMM device\n", __FUNCTION__ );
 	} else {
 		IRDA_DEBUG(2, "%s(), IrLPT device\n", __FUNCTION__ );
diff -Nru a/net/irda/irlap_event.c b/net/irda/irlap_event.c
--- a/net/irda/irlap_event.c	Fri Feb 14 15:53:11 2003
+++ b/net/irda/irlap_event.c	Fri Feb 14 15:53:11 2003
@@ -1870,7 +1870,7 @@
 				irlap_update_nr_received(self, info->nr);
 
 				irlap_wait_min_turn_around(self, &self->qos_tx);
-				irlap_send_rr_frame(self, CMD_FRAME);
+				irlap_send_rr_frame(self, RSP_FRAME);
 
 				irlap_start_wd_timer(self, self->wd_timeout);
 			}
@@ -2035,18 +2035,18 @@
 		irlap_update_nr_received(self, info->nr);
 		if (self->remote_busy) {
 			irlap_wait_min_turn_around(self, &self->qos_tx);
-			irlap_send_rr_frame(self, CMD_FRAME);
+			irlap_send_rr_frame(self, RSP_FRAME);
 		} else
-			irlap_resend_rejected_frames(self, CMD_FRAME);
+			irlap_resend_rejected_frames(self, RSP_FRAME);
 		irlap_start_wd_timer(self, self->wd_timeout);
 		break;
 	case RECV_SREJ_CMD:
 		irlap_update_nr_received(self, info->nr);
 		if (self->remote_busy) {
 			irlap_wait_min_turn_around(self, &self->qos_tx);
-			irlap_send_rr_frame(self, CMD_FRAME);
+			irlap_send_rr_frame(self, RSP_FRAME);
 		} else
-			irlap_resend_rejected_frame(self, CMD_FRAME);
+			irlap_resend_rejected_frame(self, RSP_FRAME);
 		irlap_start_wd_timer(self, self->wd_timeout);
 		break;
 	case WD_TIMER_EXPIRED:
diff -Nru a/net/irda/irsyms.c b/net/irda/irsyms.c
--- a/net/irda/irsyms.c	Fri Feb 14 15:53:12 2003
+++ b/net/irda/irsyms.c	Fri Feb 14 15:53:12 2003
@@ -165,6 +165,7 @@
 EXPORT_SYMBOL(async_wrap_skb);
 EXPORT_SYMBOL(async_unwrap_char);
 EXPORT_SYMBOL(irda_calc_crc16);
+EXPORT_SYMBOL(irda_crc16_table);
 EXPORT_SYMBOL(irda_start_timer);
 EXPORT_SYMBOL(setup_dma);
 EXPORT_SYMBOL(infrared_mode);
diff -Nru a/net/irda/irsysctl.c b/net/irda/irsysctl.c
--- a/net/irda/irsysctl.c	Fri Feb 14 15:53:09 2003
+++ b/net/irda/irsysctl.c	Fri Feb 14 15:53:09 2003
@@ -99,60 +99,175 @@
 
 /* One file */
 static ctl_table irda_table[] = {
-	{ DISCOVERY, "discovery", &sysctl_discovery,
-	  sizeof(int), 0644, NULL, &proc_dointvec },
-	{ DEVNAME, "devname", sysctl_devname,
-	  65, 0644, NULL, &do_devname, &sysctl_string},
+	{
+		.ctl_name	= DISCOVERY,
+		.procname	= "discovery",
+		.data		= &sysctl_discovery,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= DEVNAME,
+		.procname	= "devname",
+		.data		= sysctl_devname,
+		.maxlen		= 65,
+		.mode		= 0644,
+		.proc_handler	= &do_devname,
+		.strategy	= &sysctl_string
+	},
 #ifdef CONFIG_IRDA_DEBUG
-        { DEBUG, "debug", &irda_debug,
-	  sizeof(int), 0644, NULL, &proc_dointvec },
+        {
+		.ctl_name	= DEBUG,
+		.procname	= "debug",
+		.data		= &irda_debug,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
 #endif
 #ifdef CONFIG_IRDA_FAST_RR
-        { FAST_POLL, "fast_poll_increase", &sysctl_fast_poll_increase,
-	  sizeof(int), 0644, NULL, &proc_dointvec },
+        {
+		.ctl_name	= FAST_POLL,
+		.procname	= "fast_poll_increase",
+		.data		= &sysctl_fast_poll_increase,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
 #endif
-	{ DISCOVERY_SLOTS, "discovery_slots", &sysctl_discovery_slots,
-	  sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec,
-	  NULL, &min_discovery_slots, &max_discovery_slots },
-	{ DISCOVERY_TIMEOUT, "discovery_timeout", &sysctl_discovery_timeout,
-	  sizeof(int), 0644, NULL, &proc_dointvec },
-	{ SLOT_TIMEOUT, "slot_timeout", &sysctl_slot_timeout,
-	  sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec,
-	  NULL, &min_slot_timeout, &max_slot_timeout },
-	{ MAX_BAUD_RATE, "max_baud_rate", &sysctl_max_baud_rate,
-	  sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec,
-	  NULL, &min_max_baud_rate, &max_max_baud_rate },
-	{ MIN_TX_TURN_TIME, "min_tx_turn_time", &sysctl_min_tx_turn_time,
-	  sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec,
-	  NULL, &min_min_tx_turn_time, &max_min_tx_turn_time },
-	{ MAX_TX_DATA_SIZE, "max_tx_data_size", &sysctl_max_tx_data_size,
-	  sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec,
-	  NULL, &min_max_tx_data_size, &max_max_tx_data_size },
-	{ MAX_TX_WINDOW, "max_tx_window", &sysctl_max_tx_window,
-	  sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec,
-	  NULL, &min_max_tx_window, &max_max_tx_window },
-	{ MAX_NOREPLY_TIME, "max_noreply_time", &sysctl_max_noreply_time,
-	  sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec,
-	  NULL, &min_max_noreply_time, &max_max_noreply_time },
-	{ WARN_NOREPLY_TIME, "warn_noreply_time", &sysctl_warn_noreply_time,
-	  sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec,
-	  NULL, &min_warn_noreply_time, &max_warn_noreply_time },
-	{ LAP_KEEPALIVE_TIME, "lap_keepalive_time", &sysctl_lap_keepalive_time,
-	  sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec,
-	  NULL, &min_lap_keepalive_time, &max_lap_keepalive_time },
-	{ 0 }
+	{
+		.ctl_name	= DISCOVERY_SLOTS,
+		.procname	= "discovery_slots",
+		.data		= &sysctl_discovery_slots,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_discovery_slots,
+		.extra2		= &max_discovery_slots
+	},
+	{
+		.ctl_name	= DISCOVERY_TIMEOUT,
+		.procname	= "discovery_timeout",
+		.data		= &sysctl_discovery_timeout,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= SLOT_TIMEOUT,
+		.procname	= "slot_timeout",
+		.data		= &sysctl_slot_timeout,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_slot_timeout,
+		.extra2		= &max_slot_timeout
+	},
+	{
+		.ctl_name	= MAX_BAUD_RATE,
+		.procname	= "max_baud_rate",
+		.data		= &sysctl_max_baud_rate,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_max_baud_rate,
+		.extra2		= &max_max_baud_rate
+	},
+	{
+		.ctl_name	= MIN_TX_TURN_TIME,
+		.procname	= "min_tx_turn_time",
+		.data		= &sysctl_min_tx_turn_time,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_min_tx_turn_time,
+		.extra2		= &max_min_tx_turn_time
+	},
+	{
+		.ctl_name	= MAX_TX_DATA_SIZE,
+		.procname	= "max_tx_data_size",
+		.data		= &sysctl_max_tx_data_size,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_max_tx_data_size,
+		.extra2		= &max_max_tx_data_size
+	},
+	{
+		.ctl_name	= MAX_TX_WINDOW,
+		.procname	= "max_tx_window",
+		.data		= &sysctl_max_tx_window,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_max_tx_window,
+		.extra2		= &max_max_tx_window
+	},
+	{
+		.ctl_name	= MAX_NOREPLY_TIME,
+		.procname	= "max_noreply_time",
+		.data		= &sysctl_max_noreply_time,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_max_noreply_time,
+		.extra2		= &max_max_noreply_time
+	},
+	{
+		.ctl_name	= WARN_NOREPLY_TIME,
+		.procname	= "warn_noreply_time",
+		.data		= &sysctl_warn_noreply_time,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_warn_noreply_time,
+		.extra2		= &max_warn_noreply_time
+	},
+	{
+		.ctl_name	= LAP_KEEPALIVE_TIME,
+		.procname	= "lap_keepalive_time",
+		.data		= &sysctl_lap_keepalive_time,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_lap_keepalive_time,
+		.extra2		= &max_lap_keepalive_time
+	},
+	{ .ctl_name = 0 }
 };
 
 /* One directory */
 static ctl_table irda_net_table[] = {
-	{ NET_IRDA, "irda", NULL, 0, 0555, irda_table },
-	{ 0 }
+	{
+		.ctl_name	= NET_IRDA,
+		.procname	= "irda",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= irda_table
+	},
+	{ .ctl_name = 0 }
 };
 
 /* The parent directory */
 static ctl_table irda_root_table[] = {
-	{ CTL_NET, "net", NULL, 0, 0555, irda_net_table },
-	{ 0 }
+	{
+		.ctl_name	= CTL_NET,
+		.procname	= "net",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= irda_net_table
+	},
+	{ .ctl_name = 0 }
 };
 
 static struct ctl_table_header *irda_table_header;
diff -Nru a/net/irda/qos.c b/net/irda/qos.c
--- a/net/irda/qos.c	Fri Feb 14 15:53:12 2003
+++ b/net/irda/qos.c	Fri Feb 14 15:53:12 2003
@@ -722,8 +722,8 @@
 	i = value_index(speed, baud_rates, 10);
 	j = value_index(max_turn_time, max_turn_times, 4);
 
-	ASSERT(((i >=0) && (i <=10)), return 0;);
-	ASSERT(((j >=0) && (j <=4)), return 0;);
+	ASSERT(((i >=0) && (i <10)), return 0;);
+	ASSERT(((j >=0) && (j <4)), return 0;);
 
 	line_capacity = max_line_capacities[i][j];
 
diff -Nru a/net/irda/wrapper.c b/net/irda/wrapper.c
--- a/net/irda/wrapper.c	Fri Feb 14 15:53:12 2003
+++ b/net/irda/wrapper.c	Fri Feb 14 15:53:12 2003
@@ -13,6 +13,7 @@
  *
  *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
  *     All Rights Reserved.
+ *     Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
@@ -37,29 +38,41 @@
 #include <net/irda/irlap_frame.h>
 #include <net/irda/irda_device.h>
 
-static inline int stuff_byte(__u8 byte, __u8 *buf);
-
-static void state_outside_frame(struct net_device *dev,
-				struct net_device_stats *stats,
-				iobuff_t *rx_buff, __u8 byte);
-static void state_begin_frame(struct net_device *dev,
-			      struct net_device_stats *stats,
-			      iobuff_t *rx_buff, __u8 byte);
-static void state_link_escape(struct net_device *dev,
-			      struct net_device_stats *stats,
-			      iobuff_t *rx_buff, __u8 byte);
-static void state_inside_frame(struct net_device *dev,
-			       struct net_device_stats *stats,
-			       iobuff_t *rx_buff, __u8 byte);
+/************************** FRAME WRAPPING **************************/
+/*
+ * Unwrap and unstuff SIR frames
+ *
+ * Note : at FIR and MIR, HDLC framing is used and usually handled
+ * by the controller, so we come here only for SIR... Jean II
+ */
 
-static void (*state[])(struct net_device *dev, struct net_device_stats *stats,
-		       iobuff_t *rx_buff, __u8 byte) =
+/*
+ * Function stuff_byte (byte, buf)
+ *
+ *    Byte stuff one single byte and put the result in buffer pointed to by
+ *    buf. The buffer must at all times be able to have two bytes inserted.
+ *
+ * This is in a tight loop, better inline it, so need to be prior to callers.
+ * (2000 bytes on P6 200MHz, non-inlined ~370us, inline ~170us) - Jean II
+ */
+static inline int stuff_byte(__u8 byte, __u8 *buf)
 {
-	state_outside_frame,
-	state_begin_frame,
-	state_link_escape,
-	state_inside_frame,
-};
+	switch (byte) {
+	case BOF: /* FALLTHROUGH */
+	case EOF: /* FALLTHROUGH */
+	case CE:
+		/* Insert transparently coded */
+		buf[0] = CE;               /* Send link escape */
+		buf[1] = byte^IRDA_TRANS;    /* Complement bit 5 */
+		return 2;
+		/* break; */
+	default:
+		 /* Non-special value, no transparency required */
+		buf[0] = byte;
+		return 1;
+		/* break; */
+	}
+}
 
 /*
  * Function async_wrap (skb, *tx_buff, buffsize)
@@ -107,7 +120,7 @@
 		xbofs = 163;
 	}
 
-	memset(tx_buff+n, XBOF, xbofs);
+	memset(tx_buff + n, XBOF, xbofs);
 	n += xbofs;
 
 	/* Start of packet character BOF */
@@ -140,31 +153,45 @@
 	return n;
 }
 
+/************************* FRAME UNWRAPPING *************************/
 /*
- * Function stuff_byte (byte, buf)
+ * Unwrap and unstuff SIR frames
  *
- *    Byte stuff one single byte and put the result in buffer pointed to by
- *    buf. The buffer must at all times be able to have two bytes inserted.
+ * Complete rewrite by Jean II :
+ * More inline, faster, more compact, more logical. Jean II
+ * (16 bytes on P6 200MHz, old 5 to 7 us, new 4 to 6 us)
+ * (24 bytes on P6 200MHz, old 9 to 10 us, new 7 to 8 us)
+ * (for reference, 115200 b/s is 1 byte every 69 us)
+ * And reduce wrapper.o by ~900B in the process ;-)
+ *
+ * Then, we have the addition of ZeroCopy, which is optional
+ * (i.e. the driver must initiate it) and improve final processing.
+ * (2005 B frame + EOF on P6 200MHz, without 30 to 50 us, with 10 to 25 us)
  *
+ * Note : at FIR and MIR, HDLC framing is used and usually handled
+ * by the controller, so we come here only for SIR... Jean II
  */
-static inline int stuff_byte(__u8 byte, __u8 *buf)
-{
-	switch (byte) {
-	case BOF: /* FALLTHROUGH */
-	case EOF: /* FALLTHROUGH */
-	case CE:
-		/* Insert transparently coded */
-		buf[0] = CE;               /* Send link escape */
-		buf[1] = byte^IRDA_TRANS;    /* Complement bit 5 */
-		return 2;
-		/* break; */
-	default:
-		 /* Non-special value, no transparency required */
-		buf[0] = byte;
-		return 1;
-		/* break; */
-	}
-}
+
+/*
+ * We can also choose where we want to do the CRC calculation. We can
+ * do it "inline", as we receive the bytes, or "postponed", when
+ * receiving the End-Of-Frame.
+ * (16 bytes on P6 200MHz, inlined 4 to 6 us, postponed 4 to 5 us)
+ * (24 bytes on P6 200MHz, inlined 7 to 8 us, postponed 5 to 7 us)
+ * With ZeroCopy :
+ * (2005 B frame on P6 200MHz, inlined 10 to 25 us, postponed 140 to 180 us)
+ * Without ZeroCopy :
+ * (2005 B frame on P6 200MHz, inlined 30 to 50 us, postponed 150 to 180 us)
+ * (Note : numbers taken with irq disabled)
+ *
+ * From those numbers, it's not clear which is the best strategy, because
+ * we end up running through a lot of data one way or another (i.e. cache
+ * misses). I personally prefer to avoid the huge latency spike of the
+ * "postponed" solution, because it come just at the time when we have
+ * lot's of protocol processing to do and it will hurt our ability to
+ * reach low link turnaround times... Jean II
+ */
+//#define POSTPONE_RX_CRC
 
 /*
  * Function async_bump (buf, len, stats)
@@ -172,136 +199,228 @@
  *    Got a frame, make a copy of it, and pass it up the stack! We can try
  *    to inline it since it's only called from state_inside_frame
  */
-inline void async_bump(struct net_device *dev, struct net_device_stats *stats,
-		       __u8 *buf, int len)
+static inline void
+async_bump(struct net_device *dev,
+	   struct net_device_stats *stats,
+	   iobuff_t *rx_buff)
 {
-	struct sk_buff *skb;
-
-	skb = dev_alloc_skb(len+1);
-	if (!skb)  {
+	struct sk_buff *newskb;
+	struct sk_buff *dataskb;
+	int		docopy;
+
+	/* Check if we need to copy the data to a new skb or not.
+	 * If the driver doesn't use ZeroCopy Rx, we have to do it.
+	 * With ZeroCopy Rx, the rx_buff already point to a valid
+	 * skb. But, if the frame is small, it is more efficient to
+	 * copy it to save memory (copy will be fast anyway - that's
+	 * called Rx-copy-break). Jean II */
+	docopy = ((rx_buff->skb == NULL) ||
+		  (rx_buff->len < IRDA_RX_COPY_THRESHOLD));
+
+	/* Allocate a new skb */
+	newskb = dev_alloc_skb(docopy ? rx_buff->len + 1 : rx_buff->truesize);
+	if (!newskb)  {
 		stats->rx_dropped++;
+		/* We could deliver the current skb if doing ZeroCopy Rx,
+		 * but this would stall the Rx path. Better drop the
+		 * packet... Jean II */
 		return;
 	}
 
-	/* Align IP header to 20 bytes */
-	skb_reserve(skb, 1);
+	/* Align IP header to 20 bytes (i.e. increase skb->data)
+	 * Note this is only useful with IrLAN, as PPP has a variable
+	 * header size (2 or 1 bytes) - Jean II */
+	skb_reserve(newskb, 1);
+
+	if(docopy) {
+		/* Copy data without CRC (lenght already checked) */
+		memcpy(newskb->data, rx_buff->data, rx_buff->len - 2);
+		/* Deliver this skb */
+		dataskb = newskb;
+	} else {
+		/* We are using ZeroCopy. Deliver old skb */
+		dataskb = rx_buff->skb;
+		/* And hook the new skb to the rx_buff */
+		rx_buff->skb = newskb;
+		rx_buff->head = newskb->data;	/* NOT newskb->head */
+		//printk(KERN_DEBUG "ZeroCopy : len = %d, dataskb = %p, newskb = %p\n", rx_buff->len, dataskb, newskb);
+	}
 
-        /* Copy data without CRC */
-	memcpy(skb_put(skb, len-2), buf, len-2);
+	/* Set proper length on skb (without CRC) */
+	skb_put(dataskb, rx_buff->len - 2);
 
 	/* Feed it to IrLAP layer */
-	skb->dev = dev;
-	skb->mac.raw  = skb->data;
-	skb->protocol = htons(ETH_P_IRDA);
+	dataskb->dev = dev;
+	dataskb->mac.raw  = dataskb->data;
+	dataskb->protocol = htons(ETH_P_IRDA);
 
-	netif_rx(skb);
+	netif_rx(dataskb);
 
 	stats->rx_packets++;
-	stats->rx_bytes += len;
+	stats->rx_bytes += rx_buff->len;
+
+	/* Clean up rx_buff (redundant with async_unwrap_bof() ???) */
+	rx_buff->data = rx_buff->head;
+	rx_buff->len = 0;
 }
 
 /*
- * Function async_unwrap_char (dev, rx_buff, byte)
+ * Function async_unwrap_bof(dev, byte)
  *
- *    Parse and de-stuff frame received from the IrDA-port
+ *    Handle Beggining Of Frame character received within a frame
  *
  */
-inline void async_unwrap_char(struct net_device *dev,
-			      struct net_device_stats *stats,
-			      iobuff_t *rx_buff, __u8 byte)
+static inline void
+async_unwrap_bof(struct net_device *dev,
+		 struct net_device_stats *stats,
+		 iobuff_t *rx_buff, __u8 byte)
 {
-	(*state[rx_buff->state])(dev, stats, rx_buff, byte);
+	switch(rx_buff->state) {
+	case LINK_ESCAPE:
+	case INSIDE_FRAME:
+		/* Not supposed to happen, the previous frame is not
+		 * finished - Jean II */
+		IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n",
+			   __FUNCTION__);
+		stats->rx_errors++;
+		stats->rx_missed_errors++;
+		irda_device_set_media_busy(dev, TRUE);
+		break;
+
+	case OUTSIDE_FRAME:
+	case BEGIN_FRAME:
+	default:
+		/* We may receive multiple BOF at the start of frame */ 
+		break;
+	}
+
+	/* Now receiving frame */
+	rx_buff->state = BEGIN_FRAME;
+	rx_buff->in_frame = TRUE;
+
+	/* Time to initialize receive buffer */
+	rx_buff->data = rx_buff->head;
+	rx_buff->len = 0;
+	rx_buff->fcs = INIT_FCS;
 }
 
 /*
- * Function state_outside_frame (dev, rx_buff, byte)
+ * Function async_unwrap_eof(dev, byte)
  *
- *    Not receiving any frame (or just bogus data)
+ *    Handle End Of Frame character received within a frame
  *
  */
-static void state_outside_frame(struct net_device *dev,
-				struct net_device_stats *stats,
-				iobuff_t *rx_buff, __u8 byte)
+static inline void
+async_unwrap_eof(struct net_device *dev,
+		 struct net_device_stats *stats,
+		 iobuff_t *rx_buff, __u8 byte)
 {
-	switch (byte) {
-	case BOF:
-		rx_buff->state = BEGIN_FRAME;
-		rx_buff->in_frame = TRUE;
-		break;
-	case XBOF:
-		/* idev->xbofs++; */
-		break;
-	case EOF:
+#ifdef POSTPONE_RX_CRC
+	int	i;
+#endif
+
+	switch(rx_buff->state) {
+	case OUTSIDE_FRAME:
+		/* Probably missed the BOF */
+		stats->rx_errors++;
+		stats->rx_missed_errors++;
 		irda_device_set_media_busy(dev, TRUE);
 		break;
+
+	case BEGIN_FRAME:
+	case LINK_ESCAPE:
+	case INSIDE_FRAME:
 	default:
-		irda_device_set_media_busy(dev, TRUE);
+		/* Note : in the case of BEGIN_FRAME and LINK_ESCAPE,
+		 * the fcs will most likely not match and generate an
+		 * error, as expected - Jean II */
+		rx_buff->state = OUTSIDE_FRAME;
+		rx_buff->in_frame = FALSE;
+
+#ifdef POSTPONE_RX_CRC
+		/* If we haven't done the CRC as we receive bytes, we
+		 * must do it now... Jean II */
+		for(i = 0; i < rx_buff->len; i++)
+			rx_buff->fcs = irda_fcs(rx_buff->fcs,
+						rx_buff->data[i]);
+#endif
+
+		/* Test FCS and signal success if the frame is good */
+		if (rx_buff->fcs == GOOD_FCS) {
+			/* Deliver frame */
+			async_bump(dev, stats, rx_buff);
+			break;
+		} else {
+			/* Wrong CRC, discard frame!  */
+			irda_device_set_media_busy(dev, TRUE);
+
+			IRDA_DEBUG(1, "%s(), crc error\n", __FUNCTION__);
+			stats->rx_errors++;
+			stats->rx_crc_errors++;
+		}
 		break;
 	}
 }
 
 /*
- * Function state_begin_frame (idev, byte)
+ * Function async_unwrap_ce(dev, byte)
  *
- *    Begin of frame detected
+ *    Handle Character Escape character received within a frame
  *
  */
-static void state_begin_frame(struct net_device *dev,
-			      struct net_device_stats *stats,
-			      iobuff_t *rx_buff, __u8 byte)
+static inline void
+async_unwrap_ce(struct net_device *dev,
+		 struct net_device_stats *stats,
+		 iobuff_t *rx_buff, __u8 byte)
 {
-	/* Time to initialize receive buffer */
-	rx_buff->data = rx_buff->head;
-	rx_buff->len = 0;
-	rx_buff->fcs = INIT_FCS;
-
-	switch (byte) {
-	case BOF:
-		/* Continue */
-		break;
-	case CE:
-		/* Stuffed byte */
-		rx_buff->state = LINK_ESCAPE;
+	switch(rx_buff->state) {
+	case OUTSIDE_FRAME:
+		/* Activate carrier sense */
+		irda_device_set_media_busy(dev, TRUE);
 		break;
-	case EOF:
-		/* Abort frame */
-		rx_buff->state = OUTSIDE_FRAME;
-		IRDA_DEBUG(1, "%s(), abort frame\n", __FUNCTION__);
-		stats->rx_errors++;
-		stats->rx_frame_errors++;
+
+	case LINK_ESCAPE:
+		WARNING("%s: state not defined\n", __FUNCTION__);
 		break;
+
+	case BEGIN_FRAME:
+	case INSIDE_FRAME:
 	default:
-		rx_buff->data[rx_buff->len++] = byte;
-		rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
-		rx_buff->state = INSIDE_FRAME;
+		/* Stuffed byte comming */
+		rx_buff->state = LINK_ESCAPE;
 		break;
 	}
 }
 
 /*
- * Function state_link_escape (dev, byte)
+ * Function async_unwrap_other(dev, byte)
  *
- *    Found link escape character
+ *    Handle other characters received within a frame
  *
  */
-static void state_link_escape(struct net_device *dev,
-			      struct net_device_stats *stats,
-			      iobuff_t *rx_buff, __u8 byte)
+static inline void
+async_unwrap_other(struct net_device *dev,
+		   struct net_device_stats *stats,
+		   iobuff_t *rx_buff, __u8 byte)
 {
-	switch (byte) {
-	case BOF: /* New frame? */
-		IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n",
-			   __FUNCTION__);
-		rx_buff->state = BEGIN_FRAME;
-		irda_device_set_media_busy(dev, TRUE);
-		break;
-	case CE:
-		WARNING("%s: state not defined\n", __FUNCTION__);
-		break;
-	case EOF: /* Abort frame */
-		rx_buff->state = OUTSIDE_FRAME;
+	switch(rx_buff->state) {
+		/* This is on the critical path, case are ordered by
+		 * probability (most frequent first) - Jean II */
+	case INSIDE_FRAME:
+		/* Must be the next byte of the frame */
+		if (rx_buff->len < rx_buff->truesize)  {
+			rx_buff->data[rx_buff->len++] = byte;
+#ifndef POSTPONE_RX_CRC
+			rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
+#endif
+		} else {
+			IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
+				   __FUNCTION__);
+			rx_buff->state = OUTSIDE_FRAME;
+		}
 		break;
-	default:
+
+	case LINK_ESCAPE:
 		/*
 		 *  Stuffed char, complement bit 5 of byte
 		 *  following CE, IrLAP p.114
@@ -309,67 +428,58 @@
 		byte ^= IRDA_TRANS;
 		if (rx_buff->len < rx_buff->truesize)  {
 			rx_buff->data[rx_buff->len++] = byte;
+#ifndef POSTPONE_RX_CRC
 			rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
+#endif
 			rx_buff->state = INSIDE_FRAME;
 		} else {
-			IRDA_DEBUG(1, "%s(), rx buffer overflow\n",
+			IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
 				   __FUNCTION__);
 			rx_buff->state = OUTSIDE_FRAME;
 		}
 		break;
+
+	case OUTSIDE_FRAME:
+		/* Activate carrier sense */
+		if(byte != XBOF)
+			irda_device_set_media_busy(dev, TRUE);
+		break;
+
+	case BEGIN_FRAME:
+	default:
+		rx_buff->data[rx_buff->len++] = byte;
+#ifndef POSTPONE_RX_CRC
+		rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
+#endif
+		rx_buff->state = INSIDE_FRAME;
+		break;
 	}
 }
 
 /*
- * Function state_inside_frame (dev, byte)
+ * Function async_unwrap_char (dev, rx_buff, byte)
  *
- *    Handle bytes received within a frame
+ *    Parse and de-stuff frame received from the IrDA-port
  *
+ * This is the main entry point for SIR drivers.
  */
-static void state_inside_frame(struct net_device *dev,
-			       struct net_device_stats *stats,
-			       iobuff_t *rx_buff, __u8 byte)
+void async_unwrap_char(struct net_device *dev,
+		       struct net_device_stats *stats,
+		       iobuff_t *rx_buff, __u8 byte)
 {
-	int ret = 0;
-
-	switch (byte) {
-	case BOF: /* New frame? */
-		IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n",
-			   __FUNCTION__);
-		rx_buff->state = BEGIN_FRAME;
-		irda_device_set_media_busy(dev, TRUE);
+	switch(byte) {
+	case CE:
+		async_unwrap_ce(dev, stats, rx_buff, byte);
 		break;
-	case CE: /* Stuffed char */
-		rx_buff->state = LINK_ESCAPE;
+	case BOF:
+		async_unwrap_bof(dev, stats, rx_buff, byte);
 		break;
-	case EOF: /* End of frame */
-		rx_buff->state = OUTSIDE_FRAME;
-		rx_buff->in_frame = FALSE;
-
-		/* Test FCS and signal success if the frame is good */
-		if (rx_buff->fcs == GOOD_FCS) {
-			/* Deliver frame */
-			async_bump(dev, stats, rx_buff->data, rx_buff->len);
-			ret = TRUE;
-			break;
-		} else {
-			/* Wrong CRC, discard frame!  */
-			irda_device_set_media_busy(dev, TRUE);
-
-			IRDA_DEBUG(1, "%s(), crc error\n", __FUNCTION__);
-			stats->rx_errors++;
-			stats->rx_crc_errors++;
-		}
+	case EOF:
+		async_unwrap_eof(dev, stats, rx_buff, byte);
 		break;
-	default: /* Must be the next byte of the frame */
-		if (rx_buff->len < rx_buff->truesize)  {
-			rx_buff->data[rx_buff->len++] = byte;
-			rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
-		} else {
-			IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
-				   __FUNCTION__);
-			rx_buff->state = OUTSIDE_FRAME;
-		}
+	default:
+		async_unwrap_other(dev, stats, rx_buff, byte);
 		break;
 	}
 }
+
diff -Nru a/net/key/af_key.c b/net/key/af_key.c
--- a/net/key/af_key.c	Fri Feb 14 15:53:09 2003
+++ b/net/key/af_key.c	Fri Feb 14 15:53:09 2003
@@ -9,6 +9,7 @@
  * Authors:	Maxim Giryaev	<gem@asplinux.ru>
  *		David S. Miller	<davem@redhat.com>
  *		Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+ *		Kunihiro Ishiguro <kunihiro@ipinfusion.com>
  */
 
 #include <linux/config.h>
@@ -351,7 +352,9 @@
 	struct sadb_address *sp = p;
 	struct sockaddr *addr = (struct sockaddr *)(sp + 1);
 	struct sockaddr_in *sin;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	struct sockaddr_in6 *sin6;
+#endif
 	int len;
 
 	switch (addr->sa_family) {
@@ -362,7 +365,7 @@
 		    sp->sadb_address_prefixlen > 32)
 			return -EINVAL;
 		break;
-
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	case AF_INET6:
 		len  = sizeof(*sp) + sizeof(*sin6) + (sizeof(uint64_t) - 1);
 		len /= sizeof(uint64_t);
@@ -370,7 +373,7 @@
 		    sp->sadb_address_prefixlen > 128)
 			return -EINVAL;
 		break;
-
+#endif
 	default:
 		/* It is user using kernel to keep track of security
 		 * associations for another protocol, such as
@@ -400,7 +403,11 @@
 	d_addr = (struct sockaddr *)(dst + 1);
 	if (s_addr->sa_family != d_addr->sa_family)
 		return 0;
-	if (s_addr->sa_family != AF_INET)
+	if (s_addr->sa_family != AF_INET
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	    && s_addr->sa_family != AF_INET6
+#endif
+		)
 		return 0;
 
 	return 1;
@@ -497,25 +504,27 @@
 	return (proto ? proto : IPSEC_PROTO_ANY);
 }
 
-static xfrm_address_t *pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr,
-						 xfrm_address_t *xaddr)
+static int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr,
+				     xfrm_address_t *xaddr)
 {
 	switch (((struct sockaddr*)(addr + 1))->sa_family) {
 	case AF_INET:
 		xaddr->xfrm4_addr = 
-			((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr;
+			((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr;
 		if (addr->sadb_address_prefixlen)
 			xaddr->xfrm4_mask = htonl(~0 << (32 - addr->sadb_address_prefixlen));
-		break;
+		return AF_INET;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	case AF_INET6:
 		memcpy(xaddr->a6, 
-		       &((struct sockaddr_in6*)(addr + 1))->sin6_addr,
-		       sizeof(xaddr->a6));
+		       &((struct sockaddr_in6 *)(addr + 1))->sin6_addr,
+		       sizeof(struct in6_addr));
+		return AF_INET6;
+#endif
 	default:
-		return NULL;
+		return 0;
 	}
-
-	return xaddr;
+	/* NOTREACHED */
 }
 
 static struct  xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs)
@@ -540,11 +549,15 @@
 
 	switch (((struct sockaddr *)(addr + 1))->sa_family) {
 	case AF_INET:
-		x = xfrm_state_lookup(((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr,
+		x = xfrm_state_lookup(((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr,
 				      sa->sadb_sa_spi, proto);
 		break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	case AF_INET6:
-		/* XXX handle IPv6 */
+		x = xfrm6_state_lookup(&((struct sockaddr_in6 *)(addr + 1))->sin6_addr,
+				       sa->sadb_sa_spi, proto);
+		break;
+#endif
 	default:
 		x = NULL;
 		break;
@@ -554,6 +567,22 @@
 }
 
 #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1)))
+static int
+pfkey_sockaddr_size(sa_family_t family)
+{
+	switch (family) {
+	case AF_INET:
+		return PFKEY_ALIGN8(sizeof(struct sockaddr_in));
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		return PFKEY_ALIGN8(sizeof(struct sockaddr_in6));
+#endif
+	default:
+		return 0;
+	}
+	/* NOTREACHED */
+}
+
 static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, int hsc)
 {
 	struct sk_buff *skb;
@@ -563,9 +592,19 @@
 	struct sadb_address *addr;
 	struct sadb_key *key;
 	struct sadb_x_sa2 *sa2;
+	struct sockaddr_in *sin;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	struct sockaddr_in6 *sin6;
+#endif
 	int size;
 	int auth_key_size = 0;
 	int encrypt_key_size = 0;
+	int sockaddr_size;
+
+	/* address family check */
+	sockaddr_size = pfkey_sockaddr_size(x->props.family);
+	if (!sockaddr_size)
+		ERR_PTR(-EINVAL);
 
 	/* base, SA, (lifetime (HSC),) address(SD), (address(P),)
 	   key(AE), (identity(SD),) (sensitivity)> */
@@ -574,13 +613,18 @@
 		((hsc & 1) ? sizeof(struct sadb_lifetime) : 0) +
 		((hsc & 2) ? sizeof(struct sadb_lifetime) : 0) +
 			sizeof(struct sadb_address)*2 + 
-				sizeof(struct sockaddr_in)*2 + /* XXX */
+				sockaddr_size*2 +
 					sizeof(struct sadb_x_sa2);
-	/* XXX identity & sensitivity */
+	/* identity & sensitivity */
 
-	if (x->sel.saddr.xfrm4_addr != x->props.saddr.xfrm4_addr)
-		size += sizeof(struct sadb_address) + 
-			sizeof(struct sockaddr_in); /* XXX */
+	if ((x->props.family == AF_INET &&
+	     x->sel.saddr.xfrm4_addr != x->props.saddr.xfrm4_addr)
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	    || (x->props.family == AF_INET6 &&
+		memcmp (x->sel.saddr.a6, x->props.saddr.a6, sizeof (struct in6_addr)))
+#endif
+		)
+		size += sizeof(struct sadb_address) + sockaddr_size;
 
 	if (add_keys) {
 		if (x->aalg && x->aalg->alg_key_len) {
@@ -664,50 +708,113 @@
 	lifetime->sadb_lifetime_usetime = x->curlft.use_time;
 	/* src address */
 	addr = (struct sadb_address*) skb_put(skb, 
-					      sizeof(struct sadb_address)+sizeof(struct sockaddr_in));
+					      sizeof(struct sadb_address)+sockaddr_size);
 	addr->sadb_address_len = 
-		(sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/
+		(sizeof(struct sadb_address)+sockaddr_size)/
 			sizeof(uint64_t);
 	addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
 	/* "if the ports are non-zero, then the sadb_address_proto field, 
 	   normally zero, MUST be filled in with the transport 
 	   protocol's number." - RFC2367 */
 	addr->sadb_address_proto = 0; 
-	addr->sadb_address_prefixlen = 32; /* XXX */ 
 	addr->sadb_address_reserved = 0;
-	((struct sockaddr_in*)(addr + 1))->sin_family = AF_INET;
-	((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr = 
-		x->props.saddr.xfrm4_addr;
+	if (x->props.family == AF_INET) {
+		addr->sadb_address_prefixlen = 32;
+
+		sin = (struct sockaddr_in *) (addr + 1);
+		sin->sin_family = AF_INET;
+		sin->sin_addr.s_addr = x->props.saddr.xfrm4_addr;
+		sin->sin_port = 0;
+		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+	}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	else if (x->props.family == AF_INET6) {
+ 		addr->sadb_address_prefixlen = 128;
+
+		sin6 = (struct sockaddr_in6 *) (addr + 1);
+		sin6->sin6_family = AF_INET6;
+		sin6->sin6_port = 0;
+		sin6->sin6_flowinfo = 0;
+ 		memcpy(&sin6->sin6_addr, x->props.saddr.a6,
+		       sizeof(struct in6_addr));
+		sin6->sin6_scope_id = 0;
+ 	}
+#endif
+	else
+		BUG();
+
 	/* dst address */
 	addr = (struct sadb_address*) skb_put(skb, 
-					      sizeof(struct sadb_address)+sizeof(struct sockaddr_in));
+					      sizeof(struct sadb_address)+sockaddr_size);
 	addr->sadb_address_len = 
-		(sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/
+		(sizeof(struct sadb_address)+sockaddr_size)/
 			sizeof(uint64_t);
 	addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
 	addr->sadb_address_proto = 0; 
 	addr->sadb_address_prefixlen = 32; /* XXX */ 
 	addr->sadb_address_reserved = 0;
-	((struct sockaddr_in*)(addr + 1))->sin_family = AF_INET;
-	((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr = 
-		x->id.daddr.xfrm4_addr;
-
-	if (x->sel.saddr.xfrm4_addr != x->props.saddr.xfrm4_addr) {
-		addr = (struct sadb_address*) skb_put(skb, 
-						      sizeof(struct sadb_address)+sizeof(struct sockaddr_in));
-		addr->sadb_address_len = 
-			(sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/
+	if (x->props.family == AF_INET) {
+		sin = (struct sockaddr_in *) (addr + 1);
+		sin->sin_family = AF_INET;
+		sin->sin_addr.s_addr = x->id.daddr.xfrm4_addr;
+		sin->sin_port = 0;
+		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+
+		if (x->sel.saddr.xfrm4_addr != x->props.saddr.xfrm4_addr) {
+			addr = (struct sadb_address*) skb_put(skb, 
+				sizeof(struct sadb_address)+sockaddr_size);
+			addr->sadb_address_len = 
+				(sizeof(struct sadb_address)+sockaddr_size)/
+				sizeof(uint64_t);
+			addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
+			addr->sadb_address_proto =
+				pfkey_proto_from_xfrm(x->sel.proto);
+			addr->sadb_address_prefixlen = x->sel.prefixlen_s;
+			addr->sadb_address_reserved = 0;
+
+			sin = (struct sockaddr_in *) (addr + 1);
+			sin->sin_family = AF_INET;
+			sin->sin_addr.s_addr = x->sel.saddr.xfrm4_addr;
+			sin->sin_port = x->sel.sport;
+			memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+		}
+	}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	else if (x->props.family == AF_INET6) {
+		addr->sadb_address_prefixlen = 128;
+
+		sin6 = (struct sockaddr_in6 *) (addr + 1);
+		sin6->sin6_family = AF_INET6;
+		sin6->sin6_port = 0;
+		sin6->sin6_flowinfo = 0;
+		memcpy(&sin6->sin6_addr, x->id.daddr.a6, sizeof(struct in6_addr));
+		sin6->sin6_scope_id = 0;
+
+		if (memcmp (x->sel.saddr.a6, x->props.saddr.a6,
+			    sizeof(struct in6_addr))) {
+			addr = (struct sadb_address *) skb_put(skb, 
+				sizeof(struct sadb_address)+sockaddr_size);
+			addr->sadb_address_len = 
+				(sizeof(struct sadb_address)+sockaddr_size)/
 				sizeof(uint64_t);
-		addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
-		addr->sadb_address_proto = pfkey_proto_from_xfrm(x->sel.proto);
-		addr->sadb_address_prefixlen = x->sel.prefixlen_s;
-		addr->sadb_address_reserved = 0;
-		((struct sockaddr_in*)(addr + 1))->sin_family = AF_INET;
-		((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr = 
-			x->sel.saddr.xfrm4_addr;
-		((struct sockaddr_in*)(addr + 1))->sin_port = 
-			x->sel.sport;
+			addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
+			addr->sadb_address_proto =
+				pfkey_proto_from_xfrm(x->sel.proto);
+			addr->sadb_address_prefixlen = x->sel.prefixlen_s;
+			addr->sadb_address_reserved = 0;
+
+			sin6 = (struct sockaddr_in6 *) (addr + 1);
+			sin6->sin6_family = AF_INET6;
+			sin6->sin6_port = x->sel.sport;
+			sin6->sin6_flowinfo = 0;
+			memcpy(&sin6->sin6_addr, x->sel.saddr.a6,
+			       sizeof(struct in6_addr));
+			sin6->sin6_scope_id = 0;
+		}
 	}
+#endif
+	else
+		BUG();
 
 	/* auth key */
 	if (add_keys && auth_key_size) {
@@ -797,6 +904,7 @@
 		return ERR_PTR(-EINVAL);
 	key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1];
 	if (key != NULL &&
+	    sa->sadb_sa_encrypt != SADB_EALG_NULL &&
 	    ((key->sadb_key_bits+7) / 8 == 0 ||
 	     (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
 		return ERR_PTR(-EINVAL);
@@ -864,8 +972,10 @@
 	}
 	/* x->algo.flags = sa->sadb_sa_flags; */
 
-	pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 
-				  &x->props.saddr);
+	x->props.family = pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 
+						    &x->props.saddr);
+	if (!x->props.family)
+		goto out;
 	pfkey_sadb_addr2xfrm_addr((struct sadb_address *) ext_hdrs[SADB_EXT_ADDRESS_DST-1], 
 				  &x->id.daddr);
 
@@ -885,7 +995,20 @@
 		x->sel.prefixlen_s = addr->sadb_address_prefixlen;
 	}
 
-	x->type = xfrm_get_type(proto);
+	switch (x->props.family) {
+	case AF_INET:
+		x->type = xfrm_get_type(proto);
+		break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		x->type = xfrm6_get_type(proto);
+		break;
+#endif
+	default:
+		x->type = NULL;
+		break;
+	}
+
 	if (x->type == NULL)
 		goto out;
 	if (x->type->init_state(x, NULL))
@@ -912,8 +1035,7 @@
 {
 	struct sk_buff *resp_skb;
 	struct sadb_x_sa2 *sa2;
-	struct sadb_address *addr;
-	struct sockaddr_in *saddr, *daddr;
+	struct sadb_address *saddr, *daddr;
 	struct sadb_msg *out_hdr;
 	struct xfrm_state *x;
 	u8 mode;
@@ -936,13 +1058,27 @@
 		reqid = 0;
 	}
 
-	addr = ext_hdrs[SADB_EXT_ADDRESS_SRC-1];
-	saddr = (struct sockaddr_in*)(addr + 1);
-	addr = ext_hdrs[SADB_EXT_ADDRESS_DST-1];
-	daddr = (struct sockaddr_in*)(addr + 1);
+	saddr = ext_hdrs[SADB_EXT_ADDRESS_SRC-1];
+	daddr = ext_hdrs[SADB_EXT_ADDRESS_DST-1];
+
+	switch (((struct sockaddr *)(saddr + 1))->sa_family) {
+	case AF_INET:
+		x = xfrm_find_acq(mode, reqid, proto,
+				  ((struct sockaddr_in *)(daddr + 1))->sin_addr.s_addr,
+				  ((struct sockaddr_in *)(saddr + 1))->sin_addr.s_addr, 1);
+		break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	case AF_INET6:
+		x = xfrm6_find_acq(mode, reqid, proto,
+				   &((struct sockaddr_in6 *)(daddr + 1))->sin6_addr,
+				   &((struct sockaddr_in6 *)(saddr + 1))->sin6_addr, 1);
+		break;
+#endif
+	default:
+		x = NULL;
+		break;
+	}
 
-	x = xfrm_find_acq(mode, reqid, proto, daddr->sin_addr.s_addr,
-			  saddr->sin_addr.s_addr, 1);
 	if (x == NULL)
 		return -ENOENT;
 
@@ -960,7 +1096,18 @@
 			min_spi = htonl(0x100);
 			max_spi = htonl(0x0fffffff);
 		}
-		xfrm_alloc_spi(x, min_spi, max_spi);
+		switch (x->props.family) {
+		case AF_INET:
+			xfrm_alloc_spi(x, min_spi, max_spi);
+			break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+		case AF_INET6:
+			xfrm6_alloc_spi(x, min_spi, max_spi);
+			break;
+#endif
+		default:
+			break;
+		}
 		if (x->id.spi)
 			resp_skb = pfkey_xfrm_state2msg(x, 0, 3);
 	}
@@ -1028,9 +1175,23 @@
 	/* XXX there is race condition */
 	x1 = pfkey_xfrm_state_lookup(hdr, ext_hdrs);
 	if (!x1) {
-		x1 = xfrm_find_acq(x->props.mode, x->props.reqid, x->id.proto,
-				   x->id.daddr.xfrm4_addr,
-				   x->props.saddr.xfrm4_addr, 0);
+		switch (x->props.family) {
+		case AF_INET:
+			x1 = xfrm_find_acq(x->props.mode, x->props.reqid, x->id.proto,
+					   x->id.daddr.xfrm4_addr,
+					   x->props.saddr.xfrm4_addr, 0);
+			break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+		case AF_INET6:
+			x1 = xfrm6_find_acq(x->props.mode, x->props.reqid, x->id.proto,
+					    (struct in6_addr*)x->id.daddr.a6,
+					    (struct in6_addr*)x->props.saddr.a6, 0);
+			break;
+#endif
+		default:
+			x1 = NULL;
+			break;
+		}
 		if (x1 && x1->id.spi != x->id.spi && x1->id.spi) {
 			xfrm_state_put(x1);
 			x1 = NULL;
@@ -1339,7 +1500,10 @@
 parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
 {
 	struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr;
-	struct sockaddr_in *addr;
+	struct sockaddr_in *sin;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	struct sockaddr_in6 *sin6;
+#endif
 
 	if (xp->xfrm_nr >= XFRM_MAX_DEPTH)
 		return -ELOOP;
@@ -1361,10 +1525,32 @@
 
 	/* addresses present only in tunnel mode */
 	if (t->mode) {
-		addr = (void*)(rq+1);
-		t->saddr.xfrm4_addr = addr->sin_addr.s_addr;
-		addr++;
-		t->id.daddr.xfrm4_addr = addr->sin_addr.s_addr;
+		switch (xp->family) {
+		case AF_INET:
+			sin = (void*)(rq+1);
+			if (sin->sin_family != AF_INET)
+				return -EINVAL;
+			t->saddr.xfrm4_addr = sin->sin_addr.s_addr;
+			sin++;
+			if (sin->sin_family != AF_INET)
+				return -EINVAL;
+			t->id.daddr.xfrm4_addr = sin->sin_addr.s_addr;
+			break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+		case AF_INET6:
+			sin6 = (void *)(rq+1);
+			if (sin6->sin6_family != AF_INET6)
+				return -EINVAL;
+			memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
+			sin6++;
+			if (sin6->sin6_family != AF_INET6)
+				return -EINVAL;
+			memcpy(t->id.daddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
+			break;
+#endif
+		default:
+			return -EINVAL;
+		}
 	}
 	/* No way to set this via kame pfkey */
 	t->aalgos = t->ealgos = t->calgos = ~0;
@@ -1388,28 +1574,54 @@
 	return 0;
 }
 
-static struct sk_buff * pfkey_xfrm_policy2msg(struct xfrm_policy *xp, int dir)
+static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
+{
+	int sockaddr_size = pfkey_sockaddr_size(xp->family);
+	int socklen = (xp->family == AF_INET ?
+		       sizeof(struct sockaddr_in) :
+		       sizeof(struct sockaddr_in6));
+
+	return sizeof(struct sadb_msg) +
+		(sizeof(struct sadb_lifetime) * 3) +
+		(sizeof(struct sadb_address) * 2) + 
+		(sockaddr_size * 2) +
+		sizeof(struct sadb_x_policy) +
+		(xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) +
+				(socklen * 2)));
+}
+
+static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp)
 {
 	struct sk_buff *skb;
+	int size;
+
+	size = pfkey_xfrm_policy2msg_size(xp);
+
+	skb =  alloc_skb(size + 16, GFP_ATOMIC);
+	if (skb == NULL)
+		return ERR_PTR(-ENOBUFS);
+
+	return skb;
+}
+
+static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, int dir)
+{
 	struct sadb_msg *hdr;
 	struct sadb_address *addr;
 	struct sadb_lifetime *lifetime;
 	struct sadb_x_policy *pol;
 	struct sockaddr_in   *sin;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	struct sockaddr_in6  *sin6;
+#endif
 	int i;
 	int size;
+	int sockaddr_size = pfkey_sockaddr_size(xp->family);
+	int socklen = (xp->family == AF_INET ?
+		       sizeof(struct sockaddr_in) :
+		       sizeof(struct sockaddr_in6));
 
-	size = sizeof(struct sadb_msg) +
-		sizeof(struct sadb_lifetime) * 3 +
-			sizeof(struct sadb_address)*2 + 
-				sizeof(struct sockaddr_in)*2 + /* XXX */
-					sizeof(struct sadb_x_policy) +
-						xp->xfrm_nr*(sizeof(struct sadb_x_ipsecrequest) +
-							     sizeof(struct sockaddr_in)*2);
-
-	skb =  alloc_skb(size + 16, GFP_ATOMIC);
-	if (skb == NULL)
-		return ERR_PTR(-ENOBUFS);
+	size = pfkey_xfrm_policy2msg_size(xp);
 
 	/* call should fill header later */
 	hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg));
@@ -1417,35 +1629,66 @@
 
 	/* src address */
 	addr = (struct sadb_address*) skb_put(skb, 
-					      sizeof(struct sadb_address)+sizeof(struct sockaddr_in));
+					      sizeof(struct sadb_address)+sockaddr_size);
 	addr->sadb_address_len = 
-		(sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/
+		(sizeof(struct sadb_address)+sockaddr_size)/
 			sizeof(uint64_t);
 	addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
 	addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
 	addr->sadb_address_prefixlen = xp->selector.prefixlen_s;
 	addr->sadb_address_reserved = 0;
 	/* src address */
-	sin = (struct sockaddr_in*)(addr + 1);
-	sin->sin_family = AF_INET;
-	sin->sin_addr.s_addr = xp->selector.saddr.xfrm4_addr;
-	sin->sin_port = xp->selector.sport;
-	memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+	if (xp->family == AF_INET) {
+		sin = (struct sockaddr_in *) (addr + 1);
+		sin->sin_family = AF_INET;
+		sin->sin_addr.s_addr = xp->selector.saddr.xfrm4_addr;
+		sin->sin_port = xp->selector.sport;
+		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+	}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	else if (xp->family == AF_INET6) {
+		sin6 = (struct sockaddr_in6 *) (addr + 1);
+		sin6->sin6_family = AF_INET6;
+		sin6->sin6_port = xp->selector.sport;
+		sin6->sin6_flowinfo = 0;
+		memcpy(&sin6->sin6_addr, xp->selector.saddr.a6,
+		       sizeof(struct in6_addr));;
+		sin6->sin6_scope_id = 0;
+	}
+#endif
+	else
+		BUG();
+
 	/* dst address */
 	addr = (struct sadb_address*) skb_put(skb, 
-					      sizeof(struct sadb_address)+sizeof(struct sockaddr_in));
+					      sizeof(struct sadb_address)+sockaddr_size);
 	addr->sadb_address_len =
-		(sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/
+		(sizeof(struct sadb_address)+sockaddr_size)/
 			sizeof(uint64_t);
 	addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
 	addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
 	addr->sadb_address_prefixlen = xp->selector.prefixlen_d; 
 	addr->sadb_address_reserved = 0;
-	sin = (struct sockaddr_in*)(addr + 1);
-	sin->sin_family = AF_INET;
-	sin->sin_addr.s_addr = xp->selector.daddr.xfrm4_addr;
-	sin->sin_port = xp->selector.dport;
-	memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+	if (xp->family == AF_INET) {
+		sin = (struct sockaddr_in *) (addr + 1);
+		sin->sin_family = AF_INET;
+		sin->sin_addr.s_addr = xp->selector.daddr.xfrm4_addr;
+		sin->sin_port = xp->selector.dport;
+		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+	}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	else if (xp->family == AF_INET6) {
+		sin6 = (struct sockaddr_in6 *) (addr + 1);
+		sin6->sin6_family = AF_INET6;
+		sin6->sin6_port = xp->selector.dport;
+		sin6->sin6_flowinfo = 0;
+		memcpy(&sin6->sin6_addr, xp->selector.daddr.a6,
+		       sizeof(struct in6_addr));
+		sin6->sin6_scope_id = 0;
+	}
+#endif
+	else
+		BUG();
 
 	/* hard time */
 	lifetime = (struct sadb_lifetime *)  skb_put(skb, 
@@ -1498,9 +1741,9 @@
 
 		req_size = sizeof(struct sadb_x_ipsecrequest);
 		if (t->mode)
-			req_size += 2*sizeof(struct sockaddr_in);
-		else 
-			size -= 2*sizeof(struct sockaddr_in);
+			req_size += 2*socklen;
+		else
+			size -= 2*socklen;
 		rq = (void*)skb_put(skb, req_size);
 		pol->sadb_x_policy_len += req_size/8;
 		rq->sadb_x_ipsecrequest_len = req_size;
@@ -1513,21 +1756,45 @@
 			rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE;
 		rq->sadb_x_ipsecrequest_reqid = t->reqid;
 		if (t->mode) {
-			sin = (void*)(rq+1);
-			sin->sin_family = AF_INET;
-			sin->sin_addr.s_addr = t->saddr.xfrm4_addr;
-			sin->sin_port = 0;
-			memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
-			sin++;
-			sin->sin_family = AF_INET;
-			sin->sin_addr.s_addr = t->id.daddr.xfrm4_addr;
-			sin->sin_port = 0;
-			memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+			switch (xp->family) {
+			case AF_INET:
+				sin = (void*)(rq+1);
+				sin->sin_family = AF_INET;
+				sin->sin_addr.s_addr = t->saddr.xfrm4_addr;
+				sin->sin_port = 0;
+				memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+				sin++;
+				sin->sin_family = AF_INET;
+				sin->sin_addr.s_addr = t->id.daddr.xfrm4_addr;
+				sin->sin_port = 0;
+				memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+				break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+			case AF_INET6:
+				sin6 = (void*)(rq+1);
+				sin6->sin6_family = AF_INET6;
+				sin6->sin6_port = 0;
+				sin6->sin6_flowinfo = 0;
+				memcpy(&sin6->sin6_addr, t->saddr.a6,
+				       sizeof(struct in6_addr));
+				sin6->sin6_scope_id = 0;
+
+				sin6++;
+				sin6->sin6_family = AF_INET6;
+				sin6->sin6_port = 0;
+				sin6->sin6_flowinfo = 0;
+				memcpy(&sin6->sin6_addr, t->id.daddr.a6,
+				       sizeof(struct in6_addr));
+				sin6->sin6_scope_id = 0;
+				break;
+#endif
+			default:
+				break;
+			}
 		}
 	}
 	hdr->sadb_msg_len = size / sizeof(uint64_t);
 	hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);
-	return skb;
 }
 
 static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
@@ -1559,10 +1826,14 @@
 		      XFRM_POLICY_BLOCK : XFRM_POLICY_ALLOW);
 
 	sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1], 
-	pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.saddr);
+	xp->family = pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.saddr);
+	if (!xp->family) {
+		err = -EINVAL;
+		goto out;
+	}
 	xp->selector.prefixlen_s = sa->sadb_address_prefixlen;
 	xp->selector.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
-	xp->selector.sport = ((struct sockaddr_in*)(sa+1))->sin_port;
+	xp->selector.sport = ((struct sockaddr_in *)(sa+1))->sin_port;
 	if (xp->selector.sport)
 		xp->selector.sport_mask = ~0;
 
@@ -1575,7 +1846,7 @@
 	 */
 	xp->selector.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
 
-	xp->selector.dport = ((struct sockaddr_in*)(sa+1))->sin_port;
+	xp->selector.dport = ((struct sockaddr_in *)(sa+1))->sin_port;
 	if (xp->selector.dport)
 		xp->selector.dport_mask = ~0;
 
@@ -1600,7 +1871,7 @@
 	    (err = parse_ipsecrequests(xp, pol)) < 0)
 		goto out;
 
-	out_skb = pfkey_xfrm_policy2msg(xp, pol->sadb_x_policy_dir-1);
+	out_skb = pfkey_xfrm_policy2msg_prep(xp);
 	if (IS_ERR(out_skb)) {
 		err =  PTR_ERR(out_skb);
 		goto out;
@@ -1613,6 +1884,8 @@
 		goto out;
 	}
 
+	pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1);
+
 	xfrm_pol_put(xp);
 
 	out_hdr = (struct sadb_msg *) out_skb->data;
@@ -1655,7 +1928,7 @@
 	pfkey_sadb_addr2xfrm_addr(sa, &sel.saddr);
 	sel.prefixlen_s = sa->sadb_address_prefixlen;
 	sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
-	sel.sport = ((struct sockaddr_in*)(sa+1))->sin_port;
+	sel.sport = ((struct sockaddr_in *)(sa+1))->sin_port;
 	if (sel.sport)
 		sel.sport_mask = ~0;
 
@@ -1663,7 +1936,7 @@
 	pfkey_sadb_addr2xfrm_addr(sa, &sel.daddr);
 	sel.prefixlen_d = sa->sadb_address_prefixlen;
 	sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
-	sel.dport = ((struct sockaddr_in*)(sa+1))->sin_port;
+	sel.dport = ((struct sockaddr_in *)(sa+1))->sin_port;
 	if (sel.dport)
 		sel.dport_mask = ~0;
 
@@ -1673,11 +1946,12 @@
 
 	err = 0;
 
-	out_skb = pfkey_xfrm_policy2msg(xp, pol->sadb_x_policy_dir-1);
+	out_skb = pfkey_xfrm_policy2msg_prep(xp);
 	if (IS_ERR(out_skb)) {
 		err =  PTR_ERR(out_skb);
 		goto out;
 	}
+	pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1);
 
 	out_hdr = (struct sadb_msg *) out_skb->data;
 	out_hdr->sadb_msg_version = hdr->sadb_msg_version;
@@ -1715,11 +1989,12 @@
 
 	err = 0;
 
-	out_skb = pfkey_xfrm_policy2msg(xp, pol->sadb_x_policy_dir-1);
+	out_skb = pfkey_xfrm_policy2msg_prep(xp);
 	if (IS_ERR(out_skb)) {
 		err =  PTR_ERR(out_skb);
 		goto out;
 	}
+	pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1);
 
 	out_hdr = (struct sadb_msg *) out_skb->data;
 	out_hdr->sadb_msg_version = hdr->sadb_msg_version;
@@ -1746,10 +2021,12 @@
 	struct sk_buff *out_skb;
 	struct sadb_msg *out_hdr;
 
-	out_skb = pfkey_xfrm_policy2msg(xp, dir);
+	out_skb = pfkey_xfrm_policy2msg_prep(xp);
 	if (IS_ERR(out_skb))
 		return PTR_ERR(out_skb);
 
+	pfkey_xfrm_policy2msg(out_skb, xp, dir);
+
 	out_hdr = (struct sadb_msg *) out_skb->data;
 	out_hdr->sadb_msg_version = data->hdr->sadb_msg_version;
 	out_hdr->sadb_msg_type = SADB_X_SPDDUMP;
@@ -2023,12 +2300,21 @@
 	struct sadb_msg *hdr;
 	struct sadb_address *addr;
 	struct sadb_x_policy *pol;
+	struct sockaddr_in *sin;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	struct sockaddr_in6 *sin6;
+#endif
+	int sockaddr_size;
 	int size;
 	
+	sockaddr_size = pfkey_sockaddr_size(x->props.family);
+	if (!sockaddr_size)
+		return -EINVAL;
+
 	size = sizeof(struct sadb_msg) +
-		sizeof(struct sadb_address)*2 + 
-			sizeof(struct sockaddr_in)*2 +   /* XXX */
-				sizeof(struct sadb_x_policy);
+		(sizeof(struct sadb_address) * 2) +
+		(sockaddr_size * 2) +
+		sizeof(struct sadb_x_policy);
 	
 	if (x->id.proto == IPPROTO_AH)
 		size += count_ah_combs(t);
@@ -2051,33 +2337,71 @@
 
 	/* src address */
 	addr = (struct sadb_address*) skb_put(skb, 
-					      sizeof(struct sadb_address)+sizeof(struct sockaddr_in));
+					      sizeof(struct sadb_address)+sockaddr_size);
 	addr->sadb_address_len = 
-		(sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/
+		(sizeof(struct sadb_address)+sockaddr_size)/
 			sizeof(uint64_t);
 	addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
 	addr->sadb_address_proto = 0;
-	addr->sadb_address_prefixlen = 32;
 	addr->sadb_address_reserved = 0;
-	((struct sockaddr_in*)(addr + 1))->sin_family = AF_INET;
-	((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr = 
-		x->props.saddr.xfrm4_addr;
-	((struct sockaddr_in*)(addr + 1))->sin_port = 0;
+	if (x->props.family == AF_INET) {
+		addr->sadb_address_prefixlen = 32;
+
+		sin = (struct sockaddr_in *) (addr + 1);
+		sin->sin_family = AF_INET;
+		sin->sin_addr.s_addr = x->props.saddr.xfrm4_addr;
+		sin->sin_port = 0;
+		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+	}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	else if (x->props.family == AF_INET6) {
+		addr->sadb_address_prefixlen = 128;
+
+		sin6 = (struct sockaddr_in6 *) (addr + 1);
+		sin6->sin6_family = AF_INET6;
+		sin6->sin6_port = 0;
+		sin6->sin6_flowinfo = 0;
+		memcpy(&sin6->sin6_addr,
+		       x->props.saddr.a6, sizeof(struct in6_addr));
+		sin6->sin6_scope_id = 0;
+	}
+#endif
+	else
+		BUG();
 	
 	/* dst address */
 	addr = (struct sadb_address*) skb_put(skb, 
-					      sizeof(struct sadb_address)+sizeof(struct sockaddr_in));
+					      sizeof(struct sadb_address)+sockaddr_size);
 	addr->sadb_address_len =
-		(sizeof(struct sadb_address)+sizeof(struct sockaddr_in))/
+		(sizeof(struct sadb_address)+sockaddr_size)/
 			sizeof(uint64_t);
 	addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
 	addr->sadb_address_proto = 0;
-	addr->sadb_address_prefixlen = 32; 
 	addr->sadb_address_reserved = 0;
-	((struct sockaddr_in*)(addr + 1))->sin_family = AF_INET;
-	((struct sockaddr_in*)(addr + 1))->sin_addr.s_addr = 
-		x->id.daddr.xfrm4_addr;
-	((struct sockaddr_in*)(addr + 1))->sin_port = 0;
+	if (x->props.family == AF_INET) {
+		addr->sadb_address_prefixlen = 32; 
+
+		sin = (struct sockaddr_in *) (addr + 1);
+		sin->sin_family = AF_INET;
+		sin->sin_addr.s_addr = x->id.daddr.xfrm4_addr;
+		sin->sin_port = 0;
+		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
+	}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	else if (x->props.family == AF_INET6) {
+		addr->sadb_address_prefixlen = 128; 
+
+		sin6 = (struct sockaddr_in6 *) (addr + 1);
+		sin6->sin6_family = AF_INET6;
+		sin6->sin6_port = 0;
+		sin6->sin6_flowinfo = 0;
+		memcpy(&sin6->sin6_addr,
+		       x->id.daddr.a6, sizeof(struct in6_addr));
+		sin6->sin6_scope_id = 0;
+	}
+#endif
+	else
+		BUG();
 
 	pol = (struct sadb_x_policy *)  skb_put(skb, sizeof(struct sadb_x_policy));
 	pol->sadb_x_policy_len = sizeof(struct sadb_x_policy)/sizeof(uint64_t);
diff -Nru a/net/netsyms.c b/net/netsyms.c
--- a/net/netsyms.c	Fri Feb 14 15:53:09 2003
+++ b/net/netsyms.c	Fri Feb 14 15:53:09 2003
@@ -324,6 +324,11 @@
 EXPORT_SYMBOL(xfrm_policy_flush);
 EXPORT_SYMBOL(xfrm_policy_byid);
 EXPORT_SYMBOL(xfrm_policy_list);
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+EXPORT_SYMBOL(xfrm6_state_lookup);
+EXPORT_SYMBOL(xfrm6_find_acq);
+EXPORT_SYMBOL(xfrm6_alloc_spi);
+#endif
 
 EXPORT_SYMBOL_GPL(xfrm_probe_algs);
 EXPORT_SYMBOL_GPL(xfrm_count_auth_supported);
diff -Nru a/net/rxrpc/internal.h b/net/rxrpc/internal.h
--- a/net/rxrpc/internal.h	Fri Feb 14 15:53:09 2003
+++ b/net/rxrpc/internal.h	Fri Feb 14 15:53:09 2003
@@ -55,7 +55,7 @@
 		siginfo_t sinfo;
 
 		spin_lock_irq(&current->sighand->siglock);
-		dequeue_signal(&current->blocked,&sinfo);
+		dequeue_signal(current,&current->blocked,&sinfo);
 		spin_unlock_irq(&current->sighand->siglock);
 	}
 }
diff -Nru a/net/rxrpc/krxiod.c b/net/rxrpc/krxiod.c
--- a/net/rxrpc/krxiod.c	Fri Feb 14 15:53:08 2003
+++ b/net/rxrpc/krxiod.c	Fri Feb 14 15:53:08 2003
@@ -42,15 +42,8 @@
 	DECLARE_WAITQUEUE(krxiod,current);
 
 	printk("Started krxiod %d\n",current->pid);
-	strcpy(current->comm,"krxiod");
 
-	daemonize();
-
-	/* only certain signals are of interest */
-	spin_lock_irq(&current->sighand->siglock);
-	siginitsetinv(&current->blocked,0);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	daemonize("krxiod");
 
 	/* loop around waiting for work to do */
 	do {
diff -Nru a/net/rxrpc/krxsecd.c b/net/rxrpc/krxsecd.c
--- a/net/rxrpc/krxsecd.c	Fri Feb 14 15:53:09 2003
+++ b/net/rxrpc/krxsecd.c	Fri Feb 14 15:53:09 2003
@@ -54,15 +54,8 @@
 	int die;
 
 	printk("Started krxsecd %d\n",current->pid);
-	strcpy(current->comm,"krxsecd");
 
-	daemonize();
-
-	/* only certain signals are of interest */
-	spin_lock_irq(&current->sighand->siglock);
-	siginitsetinv(&current->blocked,0);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	daemonize("krxsecd");
 
 	/* loop around waiting for work to do */
 	do {
diff -Nru a/net/rxrpc/krxtimod.c b/net/rxrpc/krxtimod.c
--- a/net/rxrpc/krxtimod.c	Fri Feb 14 15:53:08 2003
+++ b/net/rxrpc/krxtimod.c	Fri Feb 14 15:53:08 2003
@@ -70,17 +70,10 @@
 	rxrpc_timer_t *timer;
 
 	printk("Started krxtimod %d\n",current->pid);
-	strcpy(current->comm,"krxtimod");
 
-	daemonize();
+	daemonize("krxtimod");
 
 	complete(&krxtimod_alive);
-
-	/* only certain signals are of interest */
-	spin_lock_irq(&current->sighand->siglock);
-	siginitsetinv(&current->blocked,0);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
 
 	/* loop around looking for things to attend to */
  loop:
diff -Nru a/net/sched/sch_gred.c b/net/sched/sch_gred.c
--- a/net/sched/sch_gred.c	Fri Feb 14 15:53:12 2003
+++ b/net/sched/sch_gred.c	Fri Feb 14 15:53:12 2003
@@ -116,7 +116,7 @@
 	}
 
 
-	if ( ((skb->tc_index&0xf) > t->DPs) || !(q=t->tab[skb->tc_index&0xf])) {
+	if ( ((skb->tc_index&0xf) > (t->DPs -1)) || !(q=t->tab[skb->tc_index&0xf])) {
 		printk("GRED: setting to default (%d)\n ",t->def);
 		if (!(q=t->tab[t->def])) {
 			DPRINTK("GRED: setting to default FAILED! dropping!! "
diff -Nru a/net/sctp/Kconfig b/net/sctp/Kconfig
--- a/net/sctp/Kconfig	Fri Feb 14 15:53:09 2003
+++ b/net/sctp/Kconfig	Fri Feb 14 15:53:09 2003
@@ -6,7 +6,7 @@
 	depends on INET && EXPERIMENTAL
 
 config IPV6_SCTP__
-	bool
+	tristate
 	default y if IPV6=n
 	default IPV6 if IPV6
 
diff -Nru a/net/sctp/Makefile b/net/sctp/Makefile
--- a/net/sctp/Makefile	Fri Feb 14 15:53:12 2003
+++ b/net/sctp/Makefile	Fri Feb 14 15:53:12 2003
@@ -10,7 +10,7 @@
 	  inqueue.o outqueue.o ulpqueue.o command.o \
 	  tsnmap.o bind_addr.o socket.o primitive.o \
 	  output.o input.o hashdriver.o sla1.o \
-	  debug.o
+	  debug.o ssnmap.o
 
 ifeq ($(CONFIG_SCTP_ADLER32), y)
 sctp-y += adler32.o
diff -Nru a/net/sctp/adler32.c b/net/sctp/adler32.c
--- a/net/sctp/adler32.c	Fri Feb 14 15:53:12 2003
+++ b/net/sctp/adler32.c	Fri Feb 14 15:53:12 2003
@@ -1,6 +1,7 @@
 /* SCTP kernel reference Implementation
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2003 International Business Machines, Corp.
  * 
  * This file is part of the SCTP kernel reference Implementation
  * 
@@ -36,6 +37,7 @@
  *    Randall Stewart <rstewar1@email.mot.com>
  *    Ken Morneau     <kmorneau@cisco.com>
  *    Qiaobing Xie    <qxie1@email.mot.com>
+ *    Sridhar Samudrala <sri@us.ibm.com>
  * 
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
@@ -122,7 +124,7 @@
 	return (s2 << 16) + s1;
 }
 
-__u32 count_crc(__u8 *ptr, __u16 count)
+__u32 sctp_start_cksum(__u8 *ptr, __u16 count)
 {
 	/*
 	 * Update a running Adler-32 checksum with the bytes
@@ -145,4 +147,16 @@
 	adler = update_adler32(adler, ptr, count);
 
         return adler;
+}
+
+__u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 adler)
+{
+	adler = update_adler32(adler, ptr, count);
+
+	return adler;
+}
+
+__u32 sctp_end_cksum(__u32 adler)
+{
+	return adler;
 }
diff -Nru a/net/sctp/associola.c b/net/sctp/associola.c
--- a/net/sctp/associola.c	Fri Feb 14 15:53:08 2003
+++ b/net/sctp/associola.c	Fri Feb 14 15:53:08 2003
@@ -1,7 +1,7 @@
 /* SCTP kernel reference Implementation
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2002 International Business Machines Corp.
+ * Copyright (c) 2001-2003 International Business Machines Corp.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 La Monte H.P. Yarroll
  *
@@ -166,15 +166,10 @@
 	asoc->max_init_attempts	= sp->initmsg.sinit_max_attempts;
 	asoc->max_init_timeo    = sp->initmsg.sinit_max_init_timeo * HZ;
 
-	/* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
-	 *
-	 * The stream sequence number in all the streams shall start
-	 * from 0 when the association is established.  Also, when the
-	 * stream sequence number reaches the value 65535 the next
-	 * stream sequence number shall be set to 0.
+	/* Allocate storage for the ssnmap after the inbound and outbound
+	 * streams have been negotiated during Init.
 	 */
-	for (i = 0; i < SCTP_MAX_STREAM; i++)
-		asoc->ssn[i] = 0;
+	asoc->ssnmap = NULL;
 
 	/* Set the local window size for receive.
 	 * This is also the rcvbuf space per association.
@@ -252,15 +247,15 @@
 				    asoc);
 
 	/* Create an output queue.  */
-	sctp_outqueue_init(asoc, &asoc->outqueue);
-	sctp_outqueue_set_output_handlers(&asoc->outqueue,
-					  sctp_packet_init,
-					  sctp_packet_config,
-					  sctp_packet_append_chunk,
-					  sctp_packet_transmit_chunk,
-					  sctp_packet_transmit);
+	sctp_outq_init(asoc, &asoc->outqueue);
+	sctp_outq_set_output_handlers(&asoc->outqueue,
+				      sctp_packet_init,
+				      sctp_packet_config,
+				      sctp_packet_append_chunk,
+				      sctp_packet_transmit_chunk,
+				      sctp_packet_transmit);
 
-	if (NULL == sctp_ulpqueue_init(&asoc->ulpq, asoc, SCTP_MAX_STREAM))
+	if (NULL == sctp_ulpq_init(&asoc->ulpq, asoc))
 		goto fail_init;
 
 	/* Set up the tsn tracking. */
@@ -296,7 +291,7 @@
  */
 void sctp_association_free(sctp_association_t *asoc)
 {
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 	sctp_endpoint_t *ep;
 	struct list_head *pos, *temp;
 	int i;
@@ -310,14 +305,17 @@
 	asoc->base.dead = 1;
 
 	/* Dispose of any data lying around in the outqueue. */
-	sctp_outqueue_free(&asoc->outqueue);
+	sctp_outq_free(&asoc->outqueue);
 
 	/* Dispose of any pending messages for the upper layer. */
-	sctp_ulpqueue_free(&asoc->ulpq);
+	sctp_ulpq_free(&asoc->ulpq);
 
 	/* Dispose of any pending chunks on the inqueue. */
 	sctp_inqueue_free(&asoc->base.inqueue);
 
+	/* Free ssnmap storage. */
+	sctp_ssnmap_free(asoc->ssnmap);
+
 	/* Clean up the bound address list. */
 	sctp_bind_addr_free(&asoc->base.bind_addr);
 
@@ -339,7 +337,7 @@
 
 	/* Release the transport structures. */
 	list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
-		transport = list_entry(pos, sctp_transport_t, transports);
+		transport = list_entry(pos, struct sctp_transport, transports);
 		list_del(pos);
 		sctp_transport_free(transport);
 	}
@@ -365,11 +363,11 @@
 
 
 /* Add a transport address to an association.  */
-sctp_transport_t *sctp_assoc_add_peer(sctp_association_t *asoc,
-				      const union sctp_addr *addr,
-				      int priority)
+struct sctp_transport *sctp_assoc_add_peer(sctp_association_t *asoc,
+					   const union sctp_addr *addr,
+					   int priority)
 {
-	sctp_transport_t *peer;
+	struct sctp_transport *peer;
 	sctp_opt_t *sp;
 	unsigned short port;
 
@@ -392,8 +390,8 @@
 
 	sctp_transport_set_owner(peer, asoc);
 
-	/* Cache a route for the transport. */
-	sctp_transport_route(peer, NULL, sctp_sk(asoc->base.sk));
+	/* Initialize the pmtu of the transport. */
+	sctp_transport_pmtu(peer);
 
 	/* If this is the first transport addr on this association,
 	 * initialize the association PMTU to the peer's PMTU.
@@ -478,16 +476,16 @@
 }
 
 /* Lookup a transport by address. */
-sctp_transport_t *sctp_assoc_lookup_paddr(const sctp_association_t *asoc,
+struct sctp_transport *sctp_assoc_lookup_paddr(const sctp_association_t *asoc,
 					  const union sctp_addr *address)
 {
-	sctp_transport_t *t;
+	struct sctp_transport *t;
 	struct list_head *pos;
 
 	/* Cycle through all transports searching for a peer address. */
 
 	list_for_each(pos, &asoc->peer.transport_addr_list) {
-		t = list_entry(pos, sctp_transport_t, transports);
+		t = list_entry(pos, struct sctp_transport, transports);
 		if (sctp_cmp_addr_exact(address, &t->ipaddr))
 			return t;
 	}
@@ -500,13 +498,13 @@
  * Select and update the new active and retran paths.
  */
 void sctp_assoc_control_transport(sctp_association_t *asoc,
-				  sctp_transport_t *transport,
+				  struct sctp_transport *transport,
 				  sctp_transport_cmd_t command,
 				  sctp_sn_error_t error)
 {
-	sctp_transport_t *t = NULL;
-	sctp_transport_t *first;
-	sctp_transport_t *second;
+	struct sctp_transport *t = NULL;
+	struct sctp_transport *first;
+	struct sctp_transport *second;
 	sctp_ulpevent_t *event;
 	struct list_head *pos;
 	int spc_state = 0;
@@ -524,7 +522,7 @@
 		break;
 
 	default:
-		BUG();
+		return;
 	};
 
 	/* Generate and send a SCTP_PEER_ADDR_CHANGE notification to the
@@ -534,7 +532,7 @@
 				(struct sockaddr_storage *) &transport->ipaddr,
 				0, spc_state, error, GFP_ATOMIC);
 	if (event)
-		sctp_ulpqueue_tail_event(&asoc->ulpq, event);
+		sctp_ulpq_tail_event(&asoc->ulpq, event);
 
 	/* Select new active and retran paths. */
 
@@ -547,7 +545,7 @@
 	first = NULL; second = NULL;
 
 	list_for_each(pos, &asoc->peer.transport_addr_list) {
-		t = list_entry(pos, sctp_transport_t, transports);
+		t = list_entry(pos, struct sctp_transport, transports);
 
 		if (!t->active)
 			continue;
@@ -631,11 +629,6 @@
 	return retval;
 }
 
-/* Fetch the next Stream Sequence Number for stream number 'sid'.  */
-__u16 __sctp_association_get_next_ssn(sctp_association_t *asoc, __u16 sid)
-{
-	return asoc->ssn[sid]++;
-}
 
 /* Compare two addresses to see if they match.  Wildcard addresses
  * only match themselves.
@@ -695,12 +688,12 @@
 /*
  * Find which transport this TSN was sent on.
  */
-sctp_transport_t *sctp_assoc_lookup_tsn(sctp_association_t *asoc, __u32 tsn)
+struct sctp_transport *sctp_assoc_lookup_tsn(sctp_association_t *asoc, __u32 tsn)
 {
-	sctp_transport_t *active;
-	sctp_transport_t *match;
+	struct sctp_transport *active;
+	struct sctp_transport *match;
 	struct list_head *entry, *pos;
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 	sctp_chunk_t *chunk;
 	__u32 key = htonl(tsn);
 
@@ -734,7 +727,7 @@
 
 	/* If not found, go search all the other transports. */
 	list_for_each(pos, &asoc->peer.transport_addr_list) {
-		transport = list_entry(pos, sctp_transport_t, transports);
+		transport = list_entry(pos, struct sctp_transport, transports);
 
 		if (transport == active)
 			break;
@@ -752,11 +745,11 @@
 }
 
 /* Is this the association we are looking for? */
-sctp_transport_t *sctp_assoc_is_match(sctp_association_t *asoc,
-				      const union sctp_addr *laddr,
-				      const union sctp_addr *paddr)
+struct sctp_transport *sctp_assoc_is_match(sctp_association_t *asoc,
+					   const union sctp_addr *laddr,
+					   const union sctp_addr *paddr)
 {
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 
 	sctp_read_lock(&asoc->base.addr_lock);
 
@@ -852,8 +845,6 @@
 /* Update an association (possibly from unexpected COOKIE-ECHO processing).  */
 void sctp_assoc_update(sctp_association_t *asoc, sctp_association_t *new)
 {
-	int i;
-
 	/* Copy in new parameters of peer. */
 	asoc->c = new->c;
 	asoc->peer.rwnd = new->peer.rwnd;
@@ -872,23 +863,28 @@
 
 	/* If the case is A (association restart), use
 	 * initial_tsn as next_tsn. If the case is B, use
-	 * current next_tsn in case there is data sent to peer
+	 * current next_tsn in case data sent to peer
 	 * has been discarded and needs retransmission.
 	 */
 	if (SCTP_STATE_ESTABLISHED == asoc->state) {
+
 		asoc->next_tsn = new->next_tsn;
 		asoc->ctsn_ack_point = new->ctsn_ack_point;
 
 		/* Reinitialize SSN for both local streams
 		 * and peer's streams.
 		 */
-		for (i = 0; i < SCTP_MAX_STREAM; i++) {
-			asoc->ssn[i] = 0;
-			asoc->ulpq.ssn[i] = 0;
-		}
+		sctp_ssnmap_clear(asoc->ssnmap);
+
 	} else {
 		asoc->ctsn_ack_point = asoc->next_tsn - 1;
+		if (!asoc->ssnmap) {
+			/* Move the ssnmap. */
+			asoc->ssnmap = new->ssnmap;
+			new->ssnmap = NULL;
+		}
 	}
+
 }
 
 /* Choose the transport for sending a shutdown packet.
@@ -896,9 +892,9 @@
  * through the inactive transports as this is the next best thing
  * we can try.
  */
-sctp_transport_t *sctp_assoc_choose_shutdown_transport(sctp_association_t *asoc)
+struct sctp_transport *sctp_assoc_choose_shutdown_transport(sctp_association_t *asoc)
 {
-	sctp_transport_t *t, *next;
+	struct sctp_transport *t, *next;
 	struct list_head *head = &asoc->peer.transport_addr_list;
 	struct list_head *pos;
 
@@ -921,7 +917,7 @@
 		else
 			pos = pos->next;
 
-		t = list_entry(pos, sctp_transport_t, transports);
+		t = list_entry(pos, struct sctp_transport, transports);
 
 		/* Try to find an active transport. */
 
@@ -946,4 +942,137 @@
 	}
 
 	return t;
+}
+
+/* Update the association's pmtu and frag_point by going through all the
+ * transports. This routine is called when a transport's PMTU has changed.
+ */
+void sctp_assoc_sync_pmtu(sctp_association_t *asoc)
+{
+	struct sctp_transport *t;
+	struct list_head *pos;
+	__u32 pmtu = 0;
+
+	if (!asoc)
+		return;
+
+	/* Get the lowest pmtu of all the transports. */
+	list_for_each(pos, &asoc->peer.transport_addr_list) {
+		t = list_entry(pos, struct sctp_transport, transports);
+		if (!pmtu || (t->pmtu < pmtu))
+			pmtu = t->pmtu;
+	}
+
+	if (pmtu) {
+		asoc->pmtu = pmtu;
+		asoc->frag_point = pmtu - (SCTP_IP_OVERHEAD +
+					   sizeof(sctp_data_chunk_t));
+	}
+
+	SCTP_DEBUG_PRINTK("%s: asoc:%p, pmtu:%d, frag_point:%d\n",
+			  __FUNCTION__, asoc, asoc->pmtu, asoc->frag_point);
+}
+
+/* Increase asoc's rwnd by len and send any window update SACK if needed. */
+void sctp_assoc_rwnd_increase(sctp_association_t *asoc, int len)
+{
+	sctp_chunk_t *sack;
+	struct timer_list *timer;
+
+	if (asoc->rwnd_over) {
+		if (asoc->rwnd_over >= len) {
+			asoc->rwnd_over -= len;
+		} else {
+			asoc->rwnd += (len - asoc->rwnd_over);
+			asoc->rwnd_over = 0;
+		}
+	} else {
+		asoc->rwnd += len;
+	}
+
+	SCTP_DEBUG_PRINTK("%s: asoc %p rwnd increased by %d to (%u, %u) - %u\n",
+			  __FUNCTION__, asoc, len, asoc->rwnd, asoc->rwnd_over,
+			  asoc->a_rwnd);
+
+	/* Send a window update SACK if the rwnd has increased by at least the
+	 * minimum of the association's PMTU and half of the receive buffer.
+	 * The algorithm used is similar to the one described in 
+	 * Section 4.2.3.3 of RFC 1122.
+	 */
+	if ((asoc->state == SCTP_STATE_ESTABLISHED) &&
+	    (asoc->rwnd > asoc->a_rwnd) &&
+	    ((asoc->rwnd - asoc->a_rwnd) >=
+		     min_t(__u32, (asoc->base.sk->rcvbuf >> 1), asoc->pmtu))) {
+		SCTP_DEBUG_PRINTK("%s: Sending window update SACK- asoc: %p "
+				  "rwnd: %u a_rwnd: %u\n",
+				  __FUNCTION__, asoc, asoc->rwnd, asoc->a_rwnd);
+		sack = sctp_make_sack(asoc); 
+		if (!sack)
+			return;	
+
+		/* Update the last advertised rwnd value. */
+		asoc->a_rwnd = asoc->rwnd;
+
+		asoc->peer.sack_needed = 0;
+		asoc->peer.next_dup_tsn = 0;
+
+		sctp_outq_tail(&asoc->outqueue, sack);
+
+		/* Stop the SACK timer.  */
+		timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK];
+		if (timer_pending(timer) && del_timer(timer))
+			sctp_association_put(asoc);
+	} 
+}
+
+/* Decrease asoc's rwnd by len. */
+void sctp_assoc_rwnd_decrease(sctp_association_t *asoc, int len)
+{
+	SCTP_ASSERT(asoc->rwnd, "rwnd zero", return);
+	SCTP_ASSERT(!asoc->rwnd_over, "rwnd_over not zero", return);
+	if (asoc->rwnd >= len) {
+		asoc->rwnd -= len;
+	} else {
+		asoc->rwnd_over = len - asoc->rwnd;
+		asoc->rwnd = 0;
+	}
+	SCTP_DEBUG_PRINTK("%s: asoc %p rwnd decreased by %d to (%u, %u)\n",
+			  __FUNCTION__, asoc, len, asoc->rwnd, asoc->rwnd_over);
+}
+
+/* Build the bind address list for the association based on info from the
+ * local endpoint and the remote peer.
+ */
+int sctp_assoc_set_bind_addr_from_ep(sctp_association_t *asoc, int priority)
+{
+	sctp_scope_t scope;
+	int flags;
+
+	/* Use scoping rules to determine the subset of addresses from
+	 * the endpoint.
+	 */
+	scope = sctp_scope(&asoc->peer.active_path->ipaddr);
+	flags = (PF_INET6 == asoc->base.sk->family) ? SCTP_ADDR6_ALLOWED : 0;
+	if (asoc->peer.ipv4_address)
+		flags |= SCTP_ADDR4_PEERSUPP;
+	if (asoc->peer.ipv6_address)
+		flags |= SCTP_ADDR6_PEERSUPP;
+
+	return sctp_bind_addr_copy(&asoc->base.bind_addr,
+				   &asoc->ep->base.bind_addr,
+				   scope, priority, flags);
+}
+
+/* Build the association's bind address list from the cookie.  */
+int sctp_assoc_set_bind_addr_from_cookie(sctp_association_t *asoc,
+					 sctp_cookie_t *cookie, int priority)
+{
+	int var_size2 = ntohs(cookie->peer_init->chunk_hdr.length);
+	int var_size3 = cookie->raw_addr_list_len;
+	__u8 *raw_addr_list = (__u8 *)cookie + sizeof(sctp_cookie_t) +
+				      var_size2;
+
+	return sctp_raw_to_bind_addrs(&asoc->base.bind_addr, raw_addr_list,
+				      var_size3, asoc->ep->base.bind_addr.port,
+				      priority);
 }
diff -Nru a/net/sctp/command.c b/net/sctp/command.c
--- a/net/sctp/command.c	Fri Feb 14 15:53:11 2003
+++ b/net/sctp/command.c	Fri Feb 14 15:53:11 2003
@@ -47,8 +47,8 @@
 {
 	sctp_cmd_seq_t *retval = t_new(sctp_cmd_seq_t, priority);
 
-	/* XXX Check for NULL? -DaveM */
-	sctp_init_cmd_seq(retval);
+	if (retval)
+		sctp_init_cmd_seq(retval);
 
 	return retval;
 }
diff -Nru a/net/sctp/crc32c.c b/net/sctp/crc32c.c
--- a/net/sctp/crc32c.c	Fri Feb 14 15:53:12 2003
+++ b/net/sctp/crc32c.c	Fri Feb 14 15:53:12 2003
@@ -1,6 +1,6 @@
 /* SCTP kernel reference Implementation
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001 International Business Machines, Corp.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
  * 
  * This file is part of the SCTP kernel reference Implementation
  * 
@@ -33,6 +33,7 @@
  * Written or modified by: 
  *    Dinakaran Joseph 
  *    Jon Grimm <jgrimm@us.ibm.com>
+ *    Sridhar Samudrala <sri@us.ibm.com>
  * 
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
@@ -135,11 +136,10 @@
 	0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351,
 };
      
-__u32 count_crc(__u8 *buffer, __u16 length)
+__u32 sctp_start_cksum(__u8 *buffer, __u16 length)
 {
     	__u32 crc32 = ~(__u32) 0;
-	__u32 i, result;
-	__u8 byte0, byte1, byte2, byte3;
+	__u32 i;
 
 	/* Optimize this routine to be SCTP specific, knowing how
 	 * to skip the checksum field of the SCTP header.
@@ -157,6 +157,24 @@
 	for (i = sizeof(struct sctphdr); i < length ; i++)
 		CRC32C(crc32, buffer[i]);
 
+	return crc32;
+}
+
+__u32 sctp_update_cksum(__u8 *buffer, __u16 length, __u32 crc32)
+{
+	__u32 i;
+
+	for (i = 0; i < length ; i++)
+		CRC32C(crc32, buffer[i]);
+
+	return crc32;
+}
+
+__u32 sctp_end_cksum(__u32 crc32)
+{
+	__u32 result;
+	__u8 byte0, byte1, byte2, byte3;
+
 	result = ~crc32;
 
 	/*  result  now holds the negated polynomial remainder;
@@ -183,5 +201,3 @@
 		 byte3);
 	return crc32;
 }
-
-
diff -Nru a/net/sctp/debug.c b/net/sctp/debug.c
--- a/net/sctp/debug.c	Fri Feb 14 15:53:09 2003
+++ b/net/sctp/debug.c	Fri Feb 14 15:53:09 2003
@@ -148,22 +148,11 @@
 
 /* Printable forms of primitives */
 static const char *sctp_primitive_tbl[SCTP_NUM_PRIMITIVE_TYPES] = {
-	"PRIMITIVE_INITIALIZE",
 	"PRIMITIVE_ASSOCIATE",
 	"PRIMITIVE_SHUTDOWN",
 	"PRIMITIVE_ABORT",
 	"PRIMITIVE_SEND",
-	"PRIMITIVE_SETPRIMARY",
-	"PRIMITIVE_RECEIVE",
-	"PRIMITIVE_STATUS",
-	"PRIMITIVE_CHANGEHEARTBEAT",
 	"PRIMITIVE_REQUESTHEARTBEAT",
-	"PRIMITIVE_GETSRTTREPORT",
-	"PRIMITIVE_SETFAILURETHRESHOLD",
-	"PRIMITIVE_SETPROTOPARAMETERS",
-	"PRIMITIVE_RECEIVE_UNSENT",
-	"PRIMITIVE_RECEIVE_UNACKED",
-	"PRIMITIVE_DESTROY"
 };
 
 /* Lookup primitive debug name. */
@@ -178,7 +167,6 @@
 
 static const char *sctp_other_tbl[] = {
 	"NO_PENDING_TSN",
-	"ICMP_UNREACHFRAG"
 };
 
 /* Lookup "other" debug name. */
@@ -197,12 +185,10 @@
 	"TIMEOUT_T1_INIT",
 	"TIMEOUT_T2_SHUTDOWN",
 	"TIMEOUT_T3_RTX",
-	"TIMEOUT_T4_RTO",
 	"TIMEOUT_T5_SHUTDOWN_GUARD",
 	"TIMEOUT_HEARTBEAT",
 	"TIMEOUT_SACK",
 	"TIMEOUT_AUTOCLOSE",
-	"TIMEOUT_PMTU_RAISE",
 };
 
 /* Lookup timer debug name. */
diff -Nru a/net/sctp/endpointola.c b/net/sctp/endpointola.c
--- a/net/sctp/endpointola.c	Fri Feb 14 15:53:09 2003
+++ b/net/sctp/endpointola.c	Fri Feb 14 15:53:09 2003
@@ -137,7 +137,6 @@
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = 
 		sp->rtoinfo.srto_initial;
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0;
-	ep->timeouts[SCTP_EVENT_TIMEOUT_T4_RTO] = 0;
 
 	/* sctpimpguide-05 Section 2.12.2
 	 * If the 'T5-shutdown-guard' timer is used, it SHOULD be set to the
@@ -152,8 +151,6 @@
 		SCTP_DEFAULT_TIMEOUT_SACK;
 	ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = 
 		sp->autoclose * HZ;
-	ep->timeouts[SCTP_EVENT_TIMEOUT_PMTU_RAISE] = 
-		SCTP_DEFAULT_TIMEOUT_PMTU_RAISE;
 
 	/* Set up the default send/receive buffer space.  */
 
@@ -264,7 +261,7 @@
 sctp_association_t *__sctp_endpoint_lookup_assoc(
 	const sctp_endpoint_t *endpoint,
 	const union sctp_addr *paddr,
-	sctp_transport_t **transport)
+	struct sctp_transport **transport)
 {
 	int rport;
 	sctp_association_t *asoc;
@@ -289,9 +286,10 @@
 }
 
 /* Lookup association on an endpoint based on a peer address.  BH-safe.  */
-sctp_association_t *sctp_endpoint_lookup_assoc(const sctp_endpoint_t *ep,
-					       const union sctp_addr *paddr,
-					       sctp_transport_t **transport)
+sctp_association_t *sctp_endpoint_lookup_assoc(
+	const sctp_endpoint_t *ep,
+	const union sctp_addr *paddr,
+	struct sctp_transport **transport)
 {
 	sctp_association_t *asoc;
 
@@ -333,7 +331,7 @@
 {
 	sctp_association_t *asoc;
 	struct sock *sk;
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 	sctp_chunk_t *chunk;
 	sctp_inqueue_t *inqueue;
 	sctp_subtype_t subtype;
diff -Nru a/net/sctp/input.c b/net/sctp/input.c
--- a/net/sctp/input.c	Fri Feb 14 15:53:08 2003
+++ b/net/sctp/input.c	Fri Feb 14 15:53:08 2003
@@ -1,7 +1,7 @@
 /* SCTP kernel reference Implementation
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001 International Business Machines, Corp.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
@@ -53,6 +53,9 @@
 #include <linux/socket.h>
 #include <linux/ip.h>
 #include <linux/time.h> /* For struct timeval */
+#include <net/ip.h>
+#include <net/icmp.h>
+#include <net/snmp.h>
 #include <net/sock.h>
 #include <net/xfrm.h>
 #include <net/sctp/sctp.h>
@@ -63,7 +66,7 @@
 sctp_association_t *__sctp_rcv_lookup(struct sk_buff *skb,
 				      const union sctp_addr *laddr,
 				      const union sctp_addr *paddr,
-				      sctp_transport_t **transportp);
+				      struct sctp_transport **transportp);
 sctp_endpoint_t *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr);
 
 
@@ -72,10 +75,19 @@
 {
 	struct sctphdr *sh;
 	__u32 cmp, val;
+	struct sk_buff *list = skb_shinfo(skb)->frag_list;
 
 	sh = (struct sctphdr *) skb->h.raw;
 	cmp = ntohl(sh->checksum);
-	val = count_crc((__u8 *)sh, skb->len);
+
+	val = sctp_start_cksum((__u8 *)sh, skb_headlen(skb));
+
+	for (; list; list = list->next)
+		val = sctp_update_cksum((__u8 *)list->data, skb_headlen(list),
+					val);
+
+	val = sctp_end_cksum(val);
+
 	if (val != cmp) {
 		/* CRC failure, dump it. */
 		return -1;
@@ -92,7 +104,7 @@
 	sctp_association_t *asoc;
 	sctp_endpoint_t *ep = NULL;
 	sctp_endpoint_common_t *rcvr;
-	sctp_transport_t *transport = NULL;
+	struct sctp_transport *transport = NULL;
 	sctp_chunk_t *chunk;
 	struct sctphdr *sh;
 	union sctp_addr src;
@@ -248,6 +260,27 @@
         return 0;
 }
 
+/* Handle icmp frag needed error. */
+static inline void sctp_icmp_frag_needed(struct sock *sk,
+					 sctp_association_t *asoc,
+					 struct sctp_transport *transport,
+					 __u32 pmtu)
+{
+	if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
+		printk(KERN_WARNING "%s: Reported pmtu %d too low, "
+		       "using default minimum of %d\n", __FUNCTION__, pmtu,
+		       SCTP_DEFAULT_MINSEGMENT);
+		pmtu = SCTP_DEFAULT_MINSEGMENT;
+	}
+
+	if (!sock_owned_by_user(sk) && transport && (transport->pmtu != pmtu)) {
+		transport->pmtu = pmtu;
+		sctp_assoc_sync_pmtu(asoc);
+		sctp_retransmit(&asoc->outqueue, transport,
+				SCTP_RETRANSMIT_PMTU_DISCOVERY );
+	}
+}
+
 /*
  * This routine is called by the ICMP module when it gets some
  * sort of error condition.  If err < 0 then the socket should
@@ -263,9 +296,109 @@
  * is probably better.
  *
  */
-void sctp_v4_err(struct sk_buff *skb, u32 info)
+void sctp_v4_err(struct sk_buff *skb, __u32 info)
 {
-	/* This should probably involve a call to SCTPhandleICMP().  */
+	struct iphdr *iph = (struct iphdr *)skb->data;
+	struct sctphdr *sh = (struct sctphdr *)(skb->data + (iph->ihl <<2));
+	int type = skb->h.icmph->type;
+	int code = skb->h.icmph->code;
+	union sctp_addr saddr, daddr;
+	struct inet_opt *inet;
+	struct sock *sk = NULL;
+	sctp_endpoint_t *ep = NULL;
+	sctp_association_t *asoc = NULL;
+	struct sctp_transport *transport;
+	int err;
+
+	if (skb->len < ((iph->ihl << 2) + 8)) {
+		ICMP_INC_STATS_BH(IcmpInErrors);
+		return;
+	}
+
+	saddr.v4.sin_family = AF_INET;
+	saddr.v4.sin_port = ntohs(sh->source);
+	memcpy(&saddr.v4.sin_addr.s_addr, &iph->saddr, sizeof(struct in_addr));	
+	daddr.v4.sin_family = AF_INET;
+	daddr.v4.sin_port = ntohs(sh->dest);
+	memcpy(&daddr.v4.sin_addr.s_addr, &iph->daddr, sizeof(struct in_addr));	
+
+	/* Look for an association that matches the incoming ICMP error 
+	 * packet.
+	 */
+	asoc = __sctp_lookup_association(&saddr, &daddr, &transport);
+	if (!asoc) {
+		/* If there is no matching association, see if it matches any
+		 * endpoint. This may happen for an ICMP error generated in 
+		 * response to an INIT_ACK. 
+		 */ 
+		ep = __sctp_rcv_lookup_endpoint(&daddr);
+		if (!ep) {
+			ICMP_INC_STATS_BH(IcmpInErrors);
+			return;
+		}
+	}
+
+	if (asoc) {
+		if (ntohl(sh->vtag) != asoc->c.peer_vtag) {
+			ICMP_INC_STATS_BH(IcmpInErrors);
+			goto out;
+		}
+		sk = asoc->base.sk;
+	} else
+		sk = ep->base.sk;
+
+	sctp_bh_lock_sock(sk);
+	/* If too many ICMPs get dropped on busy
+	 * servers this needs to be solved differently.
+	 */
+	if (sock_owned_by_user(sk))
+		NET_INC_STATS_BH(LockDroppedIcmps);
+
+	switch (type) {
+	case ICMP_PARAMETERPROB:
+		err = EPROTO;
+		break;
+	case ICMP_DEST_UNREACH:
+		if (code > NR_ICMP_UNREACH)
+			goto out_unlock;
+
+		/* PMTU discovery (RFC1191) */
+		if (ICMP_FRAG_NEEDED == code) {
+			sctp_icmp_frag_needed(sk, asoc, transport, info);
+			goto out_unlock;
+		}
+
+		err = icmp_err_convert[code].errno;
+		break;
+	case ICMP_TIME_EXCEEDED:
+		/* Ignore any time exceeded errors due to fragment reassembly
+		 * timeouts.
+		 */
+		if (ICMP_EXC_FRAGTIME == code)
+			goto out_unlock;
+
+		err = EHOSTUNREACH;
+		break;
+	default:
+		goto out_unlock;
+	}
+
+	inet = inet_sk(sk);
+	if (!sock_owned_by_user(sk) && inet->recverr) {
+		sk->err = err;
+		sk->error_report(sk);
+	} else {  /* Only an error on timeout */
+		sk->err_soft = err;
+	}
+
+out_unlock:
+	sctp_bh_unlock_sock(sk);
+out:
+	sock_put(sk);
+	if (asoc)
+		sctp_association_put(asoc);
+	if (ep)	
+		sctp_endpoint_put(ep);
 }
 
 /*
@@ -303,17 +436,17 @@
 		 * chunk, the receiver should silently discard the packet
 		 * and take no further action.
 		 */
-		if (ch->type == SCTP_CID_SHUTDOWN_COMPLETE)
+		if (SCTP_CID_SHUTDOWN_COMPLETE == ch->type)
 			goto discard;
 
 		/* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR
 		 * or a COOKIE ACK the SCTP Packet should be silently
 		 * discarded.
 		 */
-		if (ch->type == SCTP_CID_COOKIE_ACK)
+		if (SCTP_CID_COOKIE_ACK == ch->type)
 			goto discard;
 
-		if (ch->type == SCTP_CID_ERROR) {
+		if (SCTP_CID_ERROR == ch->type) {
 			err = (sctp_errhdr_t *)(ch + sizeof(sctp_chunkhdr_t));
 			if (SCTP_ERROR_STALE_COOKIE == err->cause)
 				goto discard;
@@ -485,12 +618,12 @@
 /* Look up an association. */
 sctp_association_t *__sctp_lookup_association(const union sctp_addr *laddr,
 					      const union sctp_addr *paddr,
-					      sctp_transport_t **transportp)
+					      struct sctp_transport **transportp)
 {
 	sctp_hashbucket_t *head;
 	sctp_endpoint_common_t *epb;
 	sctp_association_t *asoc;
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 	int hash;
 
 	/* Optimize here for direct hit, only listening connections can
@@ -521,7 +654,7 @@
 /* Look up an association. BH-safe. */
 sctp_association_t *sctp_lookup_association(const union sctp_addr *laddr,
 					    const union sctp_addr *paddr,
-					    sctp_transport_t **transportp)
+					    struct sctp_transport **transportp)
 {
 	sctp_association_t *asoc;
 
@@ -537,7 +670,7 @@
 			 const union sctp_addr *paddr)
 {
 	sctp_association_t *asoc;
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 
 	if ((asoc = sctp_lookup_association(laddr, paddr, &transport))) {
 		sock_put(asoc->base.sk);
@@ -567,7 +700,7 @@
  *
  */
 static sctp_association_t *__sctp_rcv_init_lookup(struct sk_buff *skb,
-	const union sctp_addr *laddr, sctp_transport_t **transportp)
+	const union sctp_addr *laddr, struct sctp_transport **transportp)
 {
 	sctp_association_t *asoc;
 	union sctp_addr addr;
@@ -627,7 +760,7 @@
 sctp_association_t *__sctp_rcv_lookup(struct sk_buff *skb,
 				      const union sctp_addr *paddr,
 				      const union sctp_addr *laddr,
-				      sctp_transport_t **transportp)
+				      struct sctp_transport **transportp)
 {
 	sctp_association_t *asoc;
 
diff -Nru a/net/sctp/ipv6.c b/net/sctp/ipv6.c
--- a/net/sctp/ipv6.c	Fri Feb 14 15:53:11 2003
+++ b/net/sctp/ipv6.c	Fri Feb 14 15:53:11 2003
@@ -98,43 +98,22 @@
 }
 
 /* Based on tcp_v6_xmit() in tcp_ipv6.c. */
-static inline int sctp_v6_xmit(struct sk_buff *skb)
+static inline int sctp_v6_xmit(struct sk_buff *skb,
+			       struct sctp_transport *transport, int ipfragok)
 {
 	struct sock *sk = skb->sk;
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct flowi fl;
 	struct dst_entry *dst = skb->dst;
 	struct rt6_info *rt6 = (struct rt6_info *)dst;
-	struct in6_addr saddr;
-	int err;
 
 	fl.proto = sk->protocol;
-	fl.fl6_dst = &rt6->rt6i_dst.addr;
 
-	/* FIXME: Currently, ip6_route_output() doesn't fill in the source
-	 * address in the returned route entry. So we call ipv6_get_saddr()
-	 * to get an appropriate source address. It is possible that this address
-	 * may not be part of the bind address list of the association.
-	 * Once ip6_route_ouput() is fixed so that it returns a route entry
-	 * with an appropriate source address, the following if condition can
-	 * be removed. With ip6_route_output() returning a source address filled
-	 * route entry, sctp_transport_route() can do real source address 
-	 * selection for v6.
+	/* Fill in the dest address from the route entry passed with the skb
+	 * and the source address from the transport.
 	 */ 
-	if (ipv6_addr_any(&rt6->rt6i_src.addr)) {
-		err = ipv6_get_saddr(dst, fl.fl6_dst, &saddr);
-
-		if (err) {
-			printk(KERN_ERR "%s: No saddr available for "
-			       "DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
-			       __FUNCTION__, NIP6(fl.fl6_src));
-			return err;
-		}
-
-		fl.fl6_src = &saddr;
-	} else {
-		fl.fl6_src = &rt6->rt6i_src.addr;
-	}
+	fl.fl6_dst = &rt6->rt6i_dst.addr;
+	fl.fl6_src = &transport->saddr.v6.sin6_addr; 
 
 	fl.fl6_flowlabel = np->flow_label;
 	IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
@@ -147,20 +126,26 @@
 		fl.nl_u.ip6_u.daddr = rt0->addr;
 	}
 
+	SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, "
+			  "src:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
+			  "dst:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+			  __FUNCTION__, skb, skb->len, NIP6(fl.fl6_src),
+			  NIP6(fl.fl6_dst));
+
 	return ip6_xmit(sk, skb, &fl, np->opt);
 }
 
 /* Returns the dst cache entry for the given source and destination ip
  * addresses.
  */
-struct dst_entry *sctp_v6_get_dst(union sctp_addr *daddr,
+struct dst_entry *sctp_v6_get_dst(sctp_association_t *asoc,
+				  union sctp_addr *daddr,
 				  union sctp_addr *saddr)
 {
 	struct dst_entry *dst;
 	struct flowi fl = {
 		.nl_u = { .ip6_u = { .daddr = &daddr->v6.sin6_addr, } } };
 
-
 	SCTP_DEBUG_PRINTK("%s: DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ",
 			  __FUNCTION__, NIP6(fl.fl6_dst));
 
@@ -181,12 +166,96 @@
 			NIP6(&rt->rt6i_dst.addr), NIP6(&rt->rt6i_src.addr));
 	} else {
 		SCTP_DEBUG_PRINTK("NO ROUTE\n");
-		return NULL;
 	}
 
 	return dst;
 }
 
+/* Returns the number of consecutive initial bits that match in the 2 ipv6
+ * addresses.
+ */ 
+static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
+					 union sctp_addr *s2)
+{
+	struct in6_addr *a1 = &s1->v6.sin6_addr;
+	struct in6_addr *a2 = &s2->v6.sin6_addr;
+	int i, j;
+
+	for (i = 0; i < 4 ; i++) {
+		__u32 a1xora2;
+
+		a1xora2 = a1->s6_addr32[i] ^ a2->s6_addr32[i];
+		
+		if ((j = fls(ntohl(a1xora2))))
+			return (i * 32 + 32 - j);
+	}
+
+	return (i*32);
+}
+
+/* Fills in the source address(saddr) based on the destination address(daddr)
+ * and asoc's bind address list.
+ */   
+void sctp_v6_get_saddr(sctp_association_t *asoc, struct dst_entry *dst,
+		       union sctp_addr *daddr, union sctp_addr *saddr)
+{
+	sctp_bind_addr_t *bp;
+	rwlock_t *addr_lock;
+	struct sockaddr_storage_list *laddr;
+	struct list_head *pos;
+	sctp_scope_t scope;
+	union sctp_addr *baddr = NULL;
+	__u8 matchlen = 0;
+	__u8 bmatchlen;
+
+	SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p "
+			  "daddr:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ",
+			  __FUNCTION__, asoc, dst, NIP6(&daddr->v6.sin6_addr));
+
+	if (!asoc) {
+		ipv6_get_saddr(dst, &daddr->v6.sin6_addr, &saddr->v6.sin6_addr);
+		SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: "
+				  "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+				  NIP6(&saddr->v6.sin6_addr));
+		return;
+	}
+
+	scope = sctp_scope(daddr);
+
+	bp = &asoc->base.bind_addr;
+	addr_lock = &asoc->base.addr_lock;
+
+	/* Go through the bind address list and find the best source address
+	 * that matches the scope of the destination address.
+	 */
+	sctp_read_lock(addr_lock);
+	list_for_each(pos, &bp->address_list) {
+		laddr = list_entry(pos, struct sockaddr_storage_list, list);
+		if ((laddr->a.sa.sa_family == AF_INET6) &&
+		    (scope <= sctp_scope(&laddr->a))) {
+			bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
+			if (!baddr || (matchlen < bmatchlen)) {
+				baddr = &laddr->a;
+				matchlen = bmatchlen;
+			}
+		}
+	}
+
+	if (baddr) {
+		memcpy(saddr, baddr, sizeof(union sctp_addr));
+		SCTP_DEBUG_PRINTK("saddr: "
+				  "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+				  NIP6(&saddr->v6.sin6_addr));
+	} else {
+		printk(KERN_ERR "%s: asoc:%p Could not find a valid source "
+		       "address for the "
+		       "dest:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+		       __FUNCTION__, asoc, NIP6(&daddr->v6.sin6_addr));
+	}
+
+	sctp_read_unlock(addr_lock);
+}
+
 /* Make a copy of all potential local addresses. */
 static void sctp_v6_copy_addrlist(struct list_head *addrlist,
 				  struct net_device *dev)
@@ -257,10 +326,12 @@
 }
 
 /* Initialize a sctp_addr from a dst_entry. */
-static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst)
+static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst,
+			      unsigned short port)
 {
 	struct rt6_info *rt = (struct rt6_info *)dst;
 	addr->sa.sa_family = AF_INET6;
+	addr->v6.sin6_port = port;
 	ipv6_addr_copy(&addr->v6.sin6_addr, &rt->rt6i_src.addr);
 }
 
@@ -527,10 +598,11 @@
 };
 
 static struct sctp_af sctp_ipv6_specific = {
-	.queue_xmit      = sctp_v6_xmit,
-	.setsockopt    = ipv6_setsockopt,
+	.sctp_xmit       = sctp_v6_xmit,
+	.setsockopt      = ipv6_setsockopt,
 	.getsockopt      = ipv6_getsockopt,
 	.get_dst	 = sctp_v6_get_dst,
+	.get_saddr	 = sctp_v6_get_saddr,
 	.copy_addrlist   = sctp_v6_copy_addrlist,
 	.from_skb        = sctp_v6_from_skb,
 	.from_sk         = sctp_v6_from_sk,
@@ -572,7 +644,7 @@
 	/* Register the SCTP specfic AF_INET6 functions. */
 	sctp_register_af(&sctp_ipv6_specific);
 
-	/* Register notifier for inet6 address additions/deletions. */ 
+	/* Register notifier for inet6 address additions/deletions. */
 	register_inet6addr_notifier(&sctp_inetaddr_notifier);
 
 	return 0;
diff -Nru a/net/sctp/objcnt.c b/net/sctp/objcnt.c
--- a/net/sctp/objcnt.c	Fri Feb 14 15:53:08 2003
+++ b/net/sctp/objcnt.c	Fri Feb 14 15:53:08 2003
@@ -54,6 +54,7 @@
 SCTP_DBG_OBJCNT(bind_addr);
 SCTP_DBG_OBJCNT(chunk);
 SCTP_DBG_OBJCNT(addr);
+SCTP_DBG_OBJCNT(ssnmap);
 
 /* An array to make it easy to pretty print the debug information
  * to the proc fs.
@@ -66,6 +67,7 @@
 	SCTP_DBG_OBJCNT_ENTRY(chunk),
 	SCTP_DBG_OBJCNT_ENTRY(bind_addr),
 	SCTP_DBG_OBJCNT_ENTRY(addr),
+	SCTP_DBG_OBJCNT_ENTRY(ssnmap),
 };
 
 /* Callback from procfs to read out objcount information.
diff -Nru a/net/sctp/output.c b/net/sctp/output.c
--- a/net/sctp/output.c	Fri Feb 14 15:53:09 2003
+++ b/net/sctp/output.c	Fri Feb 14 15:53:09 2003
@@ -1,7 +1,7 @@
 /* SCTP kernel reference Implementation
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001 International Business Machines, Corp.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
  *
  * This file is part of the SCTP kernel reference Implementation
  *
@@ -62,7 +62,6 @@
 #include <net/sctp/sm.h>
 
 /* Forward declarations for private helpers. */
-__u32 count_crc(__u8 *ptr, __u16  count);
 static void sctp_packet_reset(sctp_packet_t *packet);
 static sctp_xmit_t sctp_packet_append_data(sctp_packet_t *packet,
 					   sctp_chunk_t *chunk);
@@ -81,6 +80,7 @@
 	packet->ecn_capable = ecn_capable;
 	packet->get_prepend_chunk = prepend_handler;
 	packet->has_cookie_echo = 0;
+	packet->ipfragok = 0;
 
 	/* We might need to call the prepend_handler right away.  */
 	if (packet_empty)
@@ -90,7 +90,7 @@
 
 /* Initialize the packet structure. */
 sctp_packet_t *sctp_packet_init(sctp_packet_t *packet,
-				sctp_transport_t *transport,
+				struct sctp_transport *transport,
 				__u16 sport,
 				__u16 dport)
 {
@@ -102,6 +102,7 @@
 	packet->ecn_capable = 0;
 	packet->get_prepend_chunk = NULL;
 	packet->has_cookie_echo = 0;
+	packet->ipfragok = 0;
 	packet->malloced = 0;
 	sctp_packet_reset(packet);
 	return packet;
@@ -193,6 +194,7 @@
 				 * transmit and rely on IP
 				 * fragmentation.
 				 */
+				packet->ipfragok = 1;
 				goto append;
 			}
 		} else { /* !packet_empty */
@@ -228,13 +230,13 @@
 }
 
 /* All packets are sent to the network through this function from
- * sctp_push_outqueue().
+ * sctp_outq_tail().
  *
  * The return value is a normal kernel error return value.
  */
 int sctp_packet_transmit(sctp_packet_t *packet)
 {
-	sctp_transport_t *transport = packet->transport;
+	struct sctp_transport *transport = packet->transport;
 	sctp_association_t *asoc = transport->asoc;
 	struct sctphdr *sh;
 	__u32 crc32;
@@ -358,22 +360,14 @@
 	 * Note: Adler-32 is no longer applicable, as has been replaced
 	 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
 	 */
-	crc32 = count_crc((__u8 *)sh, nskb->len);
+	crc32 = sctp_start_cksum((__u8 *)sh, nskb->len);
+	crc32 = sctp_end_cksum(crc32);
 
 	/* 3) Put the resultant value into the checksum field in the
 	 *    common header, and leave the rest of the bits unchanged.
 	 */
 	sh->checksum = htonl(crc32);
 
-	/* FIXME:  Delete the rest of this switch statement once phase 2
-	 * of address selection (ipv6 support) drops in.
-	 */
-	switch (transport->ipaddr.sa.sa_family) {
-	case AF_INET6:
-		SCTP_V6(inet6_sk(sk)->daddr = transport->ipaddr.v6.sin6_addr;)
-		break;
-	};
-
 	/* IP layer ECN support
 	 * From RFC 2481
 	 *  "The ECN-Capable Transport (ECT) bit would be set by the
@@ -423,8 +417,10 @@
 	}
 
 	dst = transport->dst;
-	if (!dst || dst->obsolete) {
+	/* The 'obsolete' field of dst is set to 2 when a dst is freed. */
+	if (!dst || (dst->obsolete > 1)) {
 		sctp_transport_route(transport, NULL, sctp_sk(sk));
+		sctp_assoc_sync_pmtu(asoc);
 	}
 
 	nskb->dst = dst_clone(transport->dst);
@@ -433,14 +429,22 @@
 
 	SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb length %d\n",
 			  nskb->len);
-	(*transport->af_specific->queue_xmit)(nskb);
+	(*transport->af_specific->sctp_xmit)(nskb, transport, packet->ipfragok);
 out:
 	packet->size = SCTP_IP_OVERHEAD;
 	return err;
 no_route:
 	kfree_skb(nskb);
 	IP_INC_STATS_BH(IpOutNoRoutes);
-	err = -EHOSTUNREACH;
+
+	/* FIXME: Returning the 'err' will effect all the associations
+	 * associated with a socket, although only one of the paths of the
+	 * association is unreachable.
+	 * The real failure of a transport or association can be passed on
+	 * to the user via notifications. So setting this error may not be
+	 * required.
+	 */
+	 /* err = -EHOSTUNREACH; */
 	goto out;
 }
 
@@ -473,7 +477,7 @@
 {
 	sctp_xmit_t retval = SCTP_XMIT_OK;
 	size_t datasize, rwnd, inflight;
-	sctp_transport_t *transport = packet->transport;
+	struct sctp_transport *transport = packet->transport;
 	__u32 max_burst_bytes;
 
 	/* RFC 2960 6.1  Transmission of DATA Chunks
diff -Nru a/net/sctp/outqueue.c b/net/sctp/outqueue.c
--- a/net/sctp/outqueue.c	Fri Feb 14 15:53:09 2003
+++ b/net/sctp/outqueue.c	Fri Feb 14 15:53:09 2003
@@ -2,11 +2,11 @@
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
  * Copyright (c) 2001 Intel Corp.
- * Copyright (c) 2001-2002 International Business Machines Corp.
+ * Copyright (c) 2001-2003 International Business Machines Corp.
  *
  * This file is part of the SCTP kernel reference Implementation
  *
- * These functions implement the outqueue class.   The outqueue handles
+ * These functions implement the sctp_outq class.   The outqueue handles
  * bundling and queueing of outgoing SCTP chunks.
  *
  * The SCTP reference implementation is free software;
@@ -47,39 +47,39 @@
  */
 
 #include <linux/types.h>
-#include <linux/list.h> /* For struct list_head */
+#include <linux/list.h>   /* For struct list_head */
 #include <linux/socket.h>
 #include <linux/ip.h>
-#include <net/sock.h>		/* For skb_set_owner_w */
+#include <net/sock.h>	  /* For skb_set_owner_w */
 
 #include <net/sctp/sctp.h>
 
 /* Declare internal functions here.  */
 static int sctp_acked(sctp_sackhdr_t *sack, __u32 tsn);
-static void sctp_check_transmitted(sctp_outqueue_t *q,
+static void sctp_check_transmitted(struct sctp_outq *q,
 				   struct list_head *transmitted_queue,
-				   sctp_transport_t *transport,
+				   struct sctp_transport *transport,
 				   sctp_sackhdr_t *sack,
 				   __u32 highest_new_tsn);
 
 /* Generate a new outqueue.  */
-sctp_outqueue_t *sctp_outqueue_new(sctp_association_t *asoc)
+struct sctp_outq *sctp_outq_new(sctp_association_t *asoc)
 {
-	sctp_outqueue_t *q;
+	struct sctp_outq *q;
 
-	q = t_new(sctp_outqueue_t, GFP_KERNEL);
+	q = t_new(struct sctp_outq, GFP_KERNEL);
 	if (q) {
-		sctp_outqueue_init(asoc, q);
+		sctp_outq_init(asoc, q);
 		q->malloced = 1;
 	}
 	return q;
 }
 
-/* Initialize an existing SCTP_outqueue.  This does the boring stuff.
+/* Initialize an existing sctp_outq.  This does the boring stuff.
  * You still need to define handlers if you really want to DO
  * something with this structure...
  */
-void sctp_outqueue_init(sctp_association_t *asoc, sctp_outqueue_t *q)
+void sctp_outq_init(sctp_association_t *asoc, struct sctp_outq *q)
 {
 	q->asoc = asoc;
 	skb_queue_head_init(&q->out);
@@ -102,15 +102,15 @@
 /* Free the outqueue structure and any related pending chunks.
  * FIXME: Add SEND_FAILED support.
  */
-void sctp_outqueue_teardown(sctp_outqueue_t *q)
+void sctp_outq_teardown(struct sctp_outq *q)
 {
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 	struct list_head *lchunk, *pos, *temp;
 	sctp_chunk_t *chunk;
 
 	/* Throw away unacknowledged chunks. */
 	list_for_each(pos, &q->asoc->peer.transport_addr_list) {
-		transport = list_entry(pos, sctp_transport_t, transports);
+		transport = list_entry(pos, struct sctp_transport, transports);
 		while ((lchunk = sctp_list_dequeue(&transport->transmitted))) {
 			chunk = list_entry(lchunk, sctp_chunk_t,
 					   transmitted_list);
@@ -125,35 +125,39 @@
 		sctp_free_chunk(chunk);
 	}
 
-	/* Throw away any leftover chunks. */
+	/* Throw away any chunks in the retransmit queue. */ 
+	list_for_each_safe(lchunk, temp, &q->retransmit) {
+		list_del(lchunk);
+		chunk = list_entry(lchunk, sctp_chunk_t, transmitted_list);
+		sctp_free_chunk(chunk);
+	}
+
+	/* Throw away any leftover data chunks. */
 	while ((chunk = (sctp_chunk_t *) skb_dequeue(&q->out)))
 		sctp_free_chunk(chunk);
+
+	/* Throw away any leftover control chunks. */
+	while ((chunk = (sctp_chunk_t *) skb_dequeue(&q->control)))
+		sctp_free_chunk(chunk);
 }
 
 /* Free the outqueue structure and any related pending chunks.  */
-void sctp_outqueue_free(sctp_outqueue_t *q)
+void sctp_outq_free(struct sctp_outq *q)
 {
 	/* Throw away leftover chunks. */
-	sctp_outqueue_teardown(q);
+	sctp_outq_teardown(q);
 
 	/* If we were kmalloc()'d, free the memory.  */
 	if (q->malloced)
 		kfree(q);
 }
 
-/* Transmit any pending partial chunks.  */
-void sctp_force_outqueue(sctp_outqueue_t *q)
-{
-	/* Do we really need this? */
-	/* BUG */
-}
-
-/* Put a new chunk in an SCTP_outqueue.  */
-int sctp_push_outqueue(sctp_outqueue_t *q, sctp_chunk_t *chunk)
+/* Put a new chunk in an sctp_outq.  */
+int sctp_outq_tail(struct sctp_outq *q, sctp_chunk_t *chunk)
 {
 	int error = 0;
 
-	SCTP_DEBUG_PRINTK("sctp_push_outqueue(%p, %p[%s])\n",
+	SCTP_DEBUG_PRINTK("sctp_outq_tail(%p, %p[%s])\n",
 			  q, chunk, chunk && chunk->chunk_hdr ?
 			  sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type))
 			  : "Illegal Chunk");
@@ -184,8 +188,7 @@
 
 		default:
 			SCTP_DEBUG_PRINTK("outqueueing (%p, %p[%s])\n",
-			  q, chunk,
-			  chunk && chunk->chunk_hdr ?
+			  q, chunk, chunk && chunk->chunk_hdr ?
 			  sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type))
 			  : "Illegal Chunk");
 
@@ -193,13 +196,13 @@
 			q->empty = 0;
 			break;
 		};
-	} else {
+	} else
 		skb_queue_tail(&q->control, (struct sk_buff *) chunk);
-	}
+
 	if (error < 0)
 		return error;
 
-	error = sctp_flush_outqueue(q, 0);
+	error = sctp_outq_flush(q, 0);
 
 	return error;
 }
@@ -207,7 +210,7 @@
 /* Insert a chunk into the retransmit queue.  Chunks on the retransmit
  * queue are kept in order, based on the TSNs.
  */
-void sctp_retransmit_insert(struct list_head *tlchunk, sctp_outqueue_t *q)
+void sctp_retransmit_insert(struct list_head *tlchunk, struct sctp_outq *q)
 {
 	struct list_head *rlchunk;
 	sctp_chunk_t *tchunk, *rchunk;
@@ -230,15 +233,15 @@
 		list_add_tail(tlchunk, &q->retransmit);
 	}
 }
-			
+
 /* Mark all the eligible packets on a transport for retransmission.  */
-void sctp_retransmit_mark(sctp_outqueue_t *q, sctp_transport_t *transport,
+void sctp_retransmit_mark(struct sctp_outq *q, 
+			  struct sctp_transport *transport,
 			  __u8 fast_retransmit)
 {
 	struct list_head *lchunk, *ltemp;
 	sctp_chunk_t *chunk;
 
-
 	/* Walk through the specified transmitted queue.  */
 	list_for_each_safe(lchunk, ltemp, &transport->transmitted) {
 		chunk = list_entry(lchunk, sctp_chunk_t, transmitted_list);
@@ -246,8 +249,9 @@
 		/* If we are doing retransmission due to a fast retransmit,
 		 * only the chunk's that are marked for fast retransmit
 		 * should be added to the retransmit queue.  If we are doing
-		 * retransmission due to a timeout, only the chunks that are
-		 * not yet acked should be added to the retransmit queue.
+		 * retransmission due to a timeout or pmtu discovery, only the
+		 * chunks that are not yet acked should be added to the
+		 * retransmit queue.
 		 */
 		if ((fast_retransmit && chunk->fast_retransmit) ||
 		   (!fast_retransmit && !chunk->tsn_gap_acked)) {
@@ -302,20 +306,27 @@
 /* Mark all the eligible packets on a transport for retransmission and force
  * one packet out.
  */
-void sctp_retransmit(sctp_outqueue_t *q, sctp_transport_t *transport,
-		     __u8 fast_retransmit)
+void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
+		     sctp_retransmit_reason_t reason)
 {
 	int error = 0;
+	__u8 fast_retransmit = 0;
 
-	if (fast_retransmit) {
-		sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX);
-	} else {
+	switch(reason) {
+	case SCTP_RETRANSMIT_T3_RTX:
 		sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_T3_RTX);
+		break;
+	case SCTP_RETRANSMIT_FAST_RTX:
+		sctp_transport_lower_cwnd(transport, SCTP_LOWER_CWND_FAST_RTX);
+		fast_retransmit = 1;
+		break;
+	default:
+		break;
 	}
 
 	sctp_retransmit_mark(q, transport, fast_retransmit);
 
-	error = sctp_flush_outqueue(q, /* rtx_timeout */ 1);
+	error = sctp_outq_flush(q, /* rtx_timeout */ 1);
 
 	if (error)
 		q->asoc->base.sk->err = -error;
@@ -323,18 +334,18 @@
 
 /*
  * Transmit DATA chunks on the retransmit queue.  Upon return from
- * sctp_flush_retran_queue() the packet 'pkt' may contain chunks which
+ * sctp_outq_flush_rtx() the packet 'pkt' may contain chunks which
  * need to be transmitted by the caller.
  * We assume that pkt->transport has already been set.
  *
  * The return value is a normal kernel error return value.
  */
-static int sctp_flush_retran_queue(sctp_outqueue_t *q, sctp_packet_t *pkt,
-				   int rtx_timeout, int *start_timer)
+static int sctp_outq_flush_rtx(struct sctp_outq *q, sctp_packet_t *pkt,
+			       int rtx_timeout, int *start_timer)
 {
 	struct list_head *lqueue;
 	struct list_head *lchunk;
-	sctp_transport_t *transport = pkt->transport;
+	struct sctp_transport *transport = pkt->transport;
 	sctp_xmit_t status;
 	sctp_chunk_t *chunk;
 	sctp_association_t *asoc;
@@ -374,6 +385,18 @@
 			continue;
 		}
 #endif
+
+		/* Make sure that Gap Acked TSNs are not retransmitted.  A
+		 * simple approach is just to move such TSNs out of the
+		 * way and into a 'transmitted' queue and skip to the
+		 * next chunk.
+		 */
+		if (chunk->tsn_gap_acked) {
+			list_add_tail(lchunk, &transport->transmitted);
+			lchunk = sctp_list_dequeue(lqueue);
+			continue;
+		}
+
 		/* Attempt to append this chunk to the packet. */
 		status = (*q->append_output)(pkt, chunk);
 
@@ -427,10 +450,10 @@
  * queue.  'pos' points to the next chunk in the output queue after the
  * chunk that is currently in the process of fragmentation.
  */
-void sctp_xmit_frag(sctp_outqueue_t *q, struct sk_buff *pos,
+void sctp_xmit_frag(struct sctp_outq *q, struct sk_buff *pos,
 		    sctp_packet_t *packet, sctp_chunk_t *frag, __u32 tsn)
 {
-	sctp_transport_t *transport = packet->transport;
+	struct sctp_transport *transport = packet->transport;
 	struct sk_buff_head *queue = &q->out;
 	sctp_xmit_t status;
 	int error;
@@ -503,7 +526,7 @@
  * The argument 'frag' point to the first fragment and it holds the list
  * of all the other fragments in the 'frag_list' field.
  */
-void sctp_xmit_fragmented_chunks(sctp_outqueue_t *q, sctp_packet_t *packet,
+void sctp_xmit_fragmented_chunks(struct sctp_outq *q, sctp_packet_t *packet,
 				 sctp_chunk_t *frag)
 {
 	sctp_association_t *asoc = frag->asoc;
@@ -548,6 +571,7 @@
 	sctp_chunk_t *first_frag, *frag;
 	struct list_head *frag_list;
 	int nfrags;
+	__u8 old_flags, flags;
 
 	/* nfrags = no. of max size fragments + any smaller last fragment. */
 	nfrags = ((chunk_data_len / max_frag_data_len) +
@@ -556,13 +580,20 @@
 	/* Start of the data in the chunk. */
 	data_ptr += sizeof(sctp_datahdr_t);
 
+	/* Are we fragmenting an already fragmented large message? */
+ 	old_flags = chunk->chunk_hdr->flags;
+	if (old_flags & SCTP_DATA_FIRST_FRAG)
+		flags = SCTP_DATA_FIRST_FRAG;
+	else 
+		flags = SCTP_DATA_MIDDLE_FRAG;
+
 	/* Make the first fragment. */
 	first_frag = sctp_make_datafrag(asoc, sinfo, max_frag_data_len,
-					data_ptr, SCTP_DATA_FIRST_FRAG, ssn);
+					data_ptr, flags, ssn);
 
 	if (!first_frag)
 		goto err;
-
+	first_frag->has_ssn = 1;
 	/* All the fragments are added to the frag_list of the first chunk. */
 	frag_list = &first_frag->frag_list;
 
@@ -576,7 +607,7 @@
 					  ssn);
 		if (!frag)
 			goto err;
-
+		frag->has_ssn = 1;
 		/* Add the middle fragment to the first fragment's
 		 * frag_list.
 		 */
@@ -586,11 +617,17 @@
 		data_ptr += max_frag_data_len;
 	}
 
+	if (old_flags & SCTP_DATA_LAST_FRAG)
+		flags = SCTP_DATA_LAST_FRAG;
+	else
+		flags = SCTP_DATA_MIDDLE_FRAG;
+
 	/* Make the last fragment. */
 	frag = sctp_make_datafrag(asoc, sinfo, chunk_data_len, data_ptr,
-				  SCTP_DATA_LAST_FRAG, ssn);
+				  flags, ssn);
 	if (!frag)
 		goto err;
+	frag->has_ssn = 1;
 
 	/* Add the last fragment to the first fragment's frag_list. */
 	list_add_tail(&frag->frag_list, frag_list);
@@ -620,7 +657,7 @@
 }
 
 /*
- * sctp_flush_outqueue - Try to flush an outqueue.
+ * sctp_outq_flush - Try to flush an outqueue.
  *
  * Description: Send everything in q which we legally can, subject to
  * congestion limitations.
@@ -629,7 +666,7 @@
  * locking concerns must be made.  Today we use the sock lock to protect
  * this function.
  */
-int sctp_flush_outqueue(sctp_outqueue_t *q, int rtx_timeout)
+int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
 {
 	sctp_packet_t *packet;
 	sctp_packet_t singleton;
@@ -642,13 +679,12 @@
 	sctp_packet_phandler_t *s_ecne_handler = NULL;
 	sctp_packet_phandler_t *ecne_handler = NULL;
 	struct sk_buff_head *queue;
-	sctp_transport_t *transport = NULL;
-	sctp_transport_t *new_transport;
+	struct sctp_transport *transport = NULL;
+	struct sctp_transport *new_transport;
 	sctp_chunk_t *chunk;
 	sctp_xmit_t status;
 	int error = 0;
 	int start_timer = 0;
-	sctp_ulpevent_t *event;
 
 	/* These transports have chunks to send. */
 	struct list_head transport_list;
@@ -783,10 +819,8 @@
 			(*q->config_output)(packet, vtag,
 					    ecn_capable, ecne_handler);
 		retran:
-			error = sctp_flush_retran_queue(q,
-							packet,
-							rtx_timeout,
-							&start_timer);
+			error = sctp_outq_flush_rtx(q, packet,
+						    rtx_timeout, &start_timer);
 
 			if (start_timer)
 				sctp_transport_reset_timers(transport);
@@ -813,15 +847,14 @@
 			 */
 			if (chunk->sinfo.sinfo_stream >=
 			    asoc->c.sinit_num_ostreams) {
+				struct sctp_ulpevent *ev;
+
 				/* Generate a SEND FAILED event. */
-				event = sctp_ulpevent_make_send_failed(asoc,
-						chunk, SCTP_DATA_UNSENT,
-						SCTP_ERROR_INV_STRM,
-						GFP_ATOMIC);
-				if (event) {
-					sctp_ulpqueue_tail_event(&asoc->ulpq,
-								 event);
-				}
+				ev = sctp_ulpevent_make_send_failed(asoc,
+					    chunk, SCTP_DATA_UNSENT,
+					    SCTP_ERROR_INV_STRM, GFP_ATOMIC);
+				if (ev)
+					sctp_ulpq_tail_event(&asoc->ulpq, ev);
 
 				/* Free the chunk. This chunk is not on any
 				 * list yet, just free it.
@@ -830,6 +863,12 @@
 				continue;
 			}
 
+			/* Now do delayed assignment of SSN.  This will
+			 * probably change again when we start supporting
+			 * large (> approximately 2^16) size messages.
+			 */
+			sctp_chunk_assign_ssn(chunk);
+
 			/* If there is a specified transport, use it.
 			 * Otherwise, we want to use the active path.
 			 */
@@ -878,7 +917,7 @@
 				/* We could not append this chunk, so put
 				 * the chunk back on the output queue.
 				 */
-				SCTP_DEBUG_PRINTK("sctp_flush_outqueue: could "
+				SCTP_DEBUG_PRINTK("sctp_outq_flush: could "
 					"not transmit TSN: 0x%x, status: %d\n",
 					ntohl(chunk->subh.data_hdr->tsn),
 					status);
@@ -952,8 +991,9 @@
 	 * --xguo
 	 */
 	while ((ltransport = sctp_list_dequeue(&transport_list)) != NULL ) {
-		sctp_transport_t *t = list_entry(ltransport,
-						 sctp_transport_t, send_ready);
+		struct sctp_transport *t = list_entry(ltransport,
+						      struct sctp_transport, 
+						      send_ready);
 		if (t != transport)
 			transport = t;
 
@@ -966,12 +1006,12 @@
 }
 
 /* Set the various output handling callbacks.  */
-int sctp_outqueue_set_output_handlers(sctp_outqueue_t *q,
-				      sctp_outqueue_ohandler_init_t init,
-				      sctp_outqueue_ohandler_config_t config,
-				      sctp_outqueue_ohandler_t append,
-				      sctp_outqueue_ohandler_t build,
-				      sctp_outqueue_ohandler_force_t force)
+int sctp_outq_set_output_handlers(struct sctp_outq *q,
+				      sctp_outq_ohandler_init_t init,
+				      sctp_outq_ohandler_config_t config,
+				      sctp_outq_ohandler_t append,
+				      sctp_outq_ohandler_t build,
+				      sctp_outq_ohandler_force_t force)
 {
 	q->init_output = init;
 	q->config_output = config;
@@ -1005,7 +1045,7 @@
 				  sctp_association_t *asoc)
 {
 	struct list_head *ltransport, *lchunk;
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 	sctp_chunk_t *chunk;
 	__u32 highest_new_tsn, tsn;
 	struct list_head *transport_list = &asoc->peer.transport_addr_list;
@@ -1013,7 +1053,7 @@
 	highest_new_tsn = ntohl(sack->cum_tsn_ack);
 
 	list_for_each(ltransport, transport_list) {
-		transport = list_entry(ltransport, sctp_transport_t,
+		transport = list_entry(ltransport, struct sctp_transport,
 				       transports);
 		list_for_each(lchunk, &transport->transmitted) {
 			chunk = list_entry(lchunk, sctp_chunk_t,
@@ -1028,17 +1068,17 @@
 	}
 
 	return highest_new_tsn;
-} 
+}
 
 /* This is where we REALLY process a SACK.
  *
- * Process the sack against the outqueue.  Mostly, this just frees
+ * Process the SACK against the outqueue.  Mostly, this just frees
  * things off the transmitted queue.
  */
-int sctp_sack_outqueue(sctp_outqueue_t *q, sctp_sackhdr_t *sack)
+int sctp_outq_sack(struct sctp_outq *q, sctp_sackhdr_t *sack)
 {
 	sctp_association_t *asoc = q->asoc;
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 	sctp_chunk_t *tchunk;
 	struct list_head *lchunk, *transport_list, *pos;
 	sctp_sack_variable_t *frags = sack->variable;
@@ -1053,7 +1093,7 @@
 	sack_ctsn = ntohl(sack->cum_tsn_ack);
 
 	/* Get the highest TSN in the sack. */
-	highest_tsn = sack_ctsn + 
+	highest_tsn = sack_ctsn +
 		      ntohs(frags[ntohs(sack->num_gap_ack_blocks) - 1].gab.end);
 
 	if (TSN_lt(asoc->highest_sacked, highest_tsn)) {
@@ -1074,7 +1114,8 @@
 	 * This is a MASSIVE candidate for optimization.
 	 */
 	list_for_each(pos, transport_list) {
-		transport  = list_entry(pos, sctp_transport_t, transports);
+		transport  = list_entry(pos, struct sctp_transport, 
+					transports);
 		sctp_check_transmitted(q, &transport->transmitted,
 				       transport, sack, highest_new_tsn);
 	}
@@ -1127,7 +1168,8 @@
 		goto finish;
 
 	list_for_each(pos, transport_list) {
-		transport  = list_entry(pos, sctp_transport_t, transports);
+		transport  = list_entry(pos, struct sctp_transport, 
+					transports);
 		q->empty = q->empty && list_empty(&transport->transmitted);
 		if (!q->empty)
 			goto finish;
@@ -1139,7 +1181,7 @@
 }
 
 /* Is the outqueue empty?  */
-int sctp_outqueue_is_empty(const sctp_outqueue_t *q)
+int sctp_outq_is_empty(const struct sctp_outq *q)
 {
 	return q->empty;
 }
@@ -1161,9 +1203,9 @@
  * transmitted_queue, we print a range: SACKED: TSN1-TSN2, TSN3, TSN4-TSN5.
  * KEPT TSN6-TSN7, etc.
  */
-static void sctp_check_transmitted(sctp_outqueue_t *q,
+static void sctp_check_transmitted(struct sctp_outq *q,
 				   struct list_head *transmitted_queue,
-				   sctp_transport_t *transport,
+				   struct sctp_transport *transport,
 				   sctp_sackhdr_t *sack,
 				   __u32 highest_new_tsn_in_sack)
 {
@@ -1494,7 +1536,7 @@
 
 	if (transport) {
 		if (do_fast_retransmit)
-			sctp_retransmit(q, transport, do_fast_retransmit);
+			sctp_retransmit(q, transport, SCTP_RETRANSMIT_FAST_RTX);
 
 		SCTP_DEBUG_PRINTK("%s: transport: %p, cwnd: %d, "
 				  "ssthresh: %d, flight_size: %d, pba: %d\n",
diff -Nru a/net/sctp/primitive.c b/net/sctp/primitive.c
--- a/net/sctp/primitive.c	Fri Feb 14 15:53:12 2003
+++ b/net/sctp/primitive.c	Fri Feb 14 15:53:12 2003
@@ -203,23 +203,3 @@
  */
 
 DECLARE_PRIMITIVE(REQUESTHEARTBEAT);
-
-/* COMMENT BUG.  Find out where this is mentioned in the spec.  */
-int sctp_other_icmp_unreachfrag(sctp_association_t *asoc, void *arg)
-{
-	int error = 0;
-	sctp_event_t event_type;
-	sctp_subtype_t subtype;
-	sctp_state_t state;
-	sctp_endpoint_t *ep;
-
-	event_type = SCTP_EVENT_T_OTHER;
-	subtype = SCTP_ST_OTHER(SCTP_EVENT_ICMP_UNREACHFRAG);
-	state = asoc ? asoc->state : SCTP_STATE_CLOSED;
-	ep = asoc ? asoc->ep : NULL;
-
-	error = sctp_do_sm(event_type, subtype, state, ep,
-			   asoc, arg, GFP_ATOMIC);
-
-	return error;
-}
diff -Nru a/net/sctp/protocol.c b/net/sctp/protocol.c
--- a/net/sctp/protocol.c	Fri Feb 14 15:53:11 2003
+++ b/net/sctp/protocol.c	Fri Feb 14 15:53:11 2003
@@ -82,7 +82,7 @@
 }
 
 /* Set up the proc fs entry for the SCTP protocol. */
-void sctp_proc_init(void)
+__init void sctp_proc_init(void)
 {
 	if (!proc_net_sctp) {
 		struct proc_dir_entry *ent;
@@ -223,37 +223,6 @@
 	return error;
 }
 
-/* Returns the dst cache entry for the given source and destination ip
- * addresses.
- */
-struct dst_entry *sctp_v4_get_dst(union sctp_addr *daddr,
-				  union sctp_addr *saddr)
-{
-	struct rtable *rt;
-	struct flowi fl;
-
-	memset(&fl, 0x0, sizeof(struct flowi));
-	fl.fl4_dst  = daddr->v4.sin_addr.s_addr;
-	fl.proto = IPPROTO_SCTP;
-
-	if (saddr)
-		fl.fl4_src = saddr->v4.sin_addr.s_addr;
-
-	SCTP_DEBUG_PRINTK("%s: DST:%u.%u.%u.%u, SRC:%u.%u.%u.%u - ",
-			  __FUNCTION__, NIPQUAD(fl.fl4_dst),
-			  NIPQUAD(fl.fl4_src));
-
-	if (ip_route_output_key(&rt, &fl)) {
-		SCTP_DEBUG_PRINTK("NO ROUTE\n");
-		return NULL;
-	}
-
-	SCTP_DEBUG_PRINTK("rt_dst:%u.%u.%u.%u, rt_src:%u.%u.%u.%u\n",
-			  NIPQUAD(rt->rt_src), NIPQUAD(rt->rt_dst));
-
-	return &rt->u.dst;
-}
-
 /* Initialize a sctp_addr from in incoming skb.  */
 static void sctp_v4_from_skb(union sctp_addr *addr, struct sk_buff *skb,
 			     int is_saddr)
@@ -292,10 +261,12 @@
 
 
 /* Initialize a sctp_addr from a dst_entry. */
-static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct dst_entry *dst)
+static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct dst_entry *dst,
+			      unsigned short port)
 {
 	struct rtable *rt = (struct rtable *)dst;
 	saddr->v4.sin_family = AF_INET;
+	saddr->v4.sin_port = port;
 	saddr->v4.sin_addr.s_addr = rt->rt_src;
 }
 
@@ -394,6 +365,108 @@
 	return retval;
 }
 
+/* Returns a valid dst cache entry for the given source and destination ip
+ * addresses. If an association is passed, trys to get a dst entry with a
+ * source adddress that matches an address in the bind address list. 
+ */
+struct dst_entry *sctp_v4_get_dst(sctp_association_t *asoc,
+				  union sctp_addr *daddr,
+				  union sctp_addr *saddr)
+{
+	struct rtable *rt;
+	struct flowi fl;
+	sctp_bind_addr_t *bp;
+	rwlock_t *addr_lock;
+	struct sockaddr_storage_list *laddr;
+	struct list_head *pos;
+	struct dst_entry *dst = NULL;
+	union sctp_addr dst_saddr;
+
+	memset(&fl, 0x0, sizeof(struct flowi));
+	fl.fl4_dst  = daddr->v4.sin_addr.s_addr;
+	fl.proto = IPPROTO_SCTP;
+
+	if (saddr)
+		fl.fl4_src = saddr->v4.sin_addr.s_addr;
+
+	SCTP_DEBUG_PRINTK("%s: DST:%u.%u.%u.%u, SRC:%u.%u.%u.%u - ",
+			  __FUNCTION__, NIPQUAD(fl.fl4_dst),
+			  NIPQUAD(fl.fl4_src));
+
+	if (!ip_route_output_key(&rt, &fl)) {
+		dst = &rt->u.dst;
+	}
+
+	/* If there is no association or if a source address is passed, no
+	 * more validation is required.
+	 */
+	if (!asoc || saddr)
+		goto out;
+
+	bp = &asoc->base.bind_addr;
+	addr_lock = &asoc->base.addr_lock;
+
+	if (dst) {
+		/* Walk through the bind address list and look for a bind
+		 * address that matches the source address of the returned dst.
+		 */
+		sctp_read_lock(addr_lock);
+		list_for_each(pos, &bp->address_list) {
+			laddr = list_entry(pos, struct sockaddr_storage_list,
+					   list);
+			sctp_v4_dst_saddr(&dst_saddr, dst, bp->port);
+			if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a))
+				goto out_unlock;
+		}
+		sctp_read_unlock(addr_lock);
+
+		/* None of the bound addresses match the source address of the
+		 * dst. So release it.
+		 */
+		dst_release(dst);
+		dst = NULL;
+	}
+
+	/* Walk through the bind address list and try to get a dst that
+	 * matches a bind address as the source address.
+	 */
+	sctp_read_lock(addr_lock);
+	list_for_each(pos, &bp->address_list) {
+		laddr = list_entry(pos, struct sockaddr_storage_list, list);
+
+		if (AF_INET == laddr->a.sa.sa_family) {
+			fl.fl4_src = laddr->a.v4.sin_addr.s_addr;
+			dst = sctp_v4_get_dst(asoc, daddr, &laddr->a);
+			if (!ip_route_output_key(&rt, &fl)) {
+				dst = &rt->u.dst;
+				goto out_unlock;
+			}
+		}
+	}
+
+out_unlock:
+	sctp_read_unlock(addr_lock);
+out:
+	if (dst)
+		SCTP_DEBUG_PRINTK("rt_dst:%u.%u.%u.%u, rt_src:%u.%u.%u.%u\n",
+			  	  NIPQUAD(rt->rt_dst), NIPQUAD(rt->rt_src));
+	else
+		SCTP_DEBUG_PRINTK("NO ROUTE\n");
+
+	return dst;
+}
+
+/* For v4, the source address is cached in the route entry(dst). So no need
+ * to cache it separately and hence this is an empty routine.
+ */
+void sctp_v4_get_saddr(sctp_association_t *asoc,
+		       struct dst_entry *dst,
+		       union sctp_addr *daddr,
+		       union sctp_addr *saddr)
+{
+
+}
+
 /* Event handler for inet address addition/deletion events.
  * Basically, whenever there is an event, we re-build our local address list.
  */
@@ -545,6 +618,19 @@
 	return sctp_v4_available(addr);
 }
 
+/* Wrapper routine that calls the ip transmit routine. */
+static inline int sctp_v4_xmit(struct sk_buff *skb,
+			       struct sctp_transport *transport, int ipfragok)
+{
+	SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, "
+			  "src:%u.%u.%u.%u, dst:%u.%u.%u.%u\n",
+			  __FUNCTION__, skb, skb->len,
+			  NIPQUAD(((struct rtable *)skb->dst)->rt_src),
+			  NIPQUAD(((struct rtable *)skb->dst)->rt_dst));
+
+	return ip_queue_xmit(skb, ipfragok);
+}
+
 struct sctp_af sctp_ipv4_specific;
 
 static struct sctp_pf sctp_pf_inet = {
@@ -601,10 +687,11 @@
 
 /* IPv4 address related functions.  */
 struct sctp_af sctp_ipv4_specific = {
-	.queue_xmit     = ip_queue_xmit,
+	.sctp_xmit      = sctp_v4_xmit,
 	.setsockopt     = ip_setsockopt,
 	.getsockopt     = ip_getsockopt,
 	.get_dst	= sctp_v4_get_dst,
+	.get_saddr	= sctp_v4_get_saddr,
 	.copy_addrlist  = sctp_v4_copy_addrlist,
 	.from_skb       = sctp_v4_from_skb,
 	.from_sk        = sctp_v4_from_sk,
@@ -688,7 +775,7 @@
 }
 
 /* Initialize the universe into something sensible.  */
-int sctp_init(void)
+__init int sctp_init(void)
 {
 	int i;
 	int status = 0;
@@ -750,13 +837,9 @@
 
 	/* Implementation specific variables. */
 
-	/* Initialize default stream count setup information.
-	 * Note: today the stream accounting data structures are very
-	 * fixed size, so one really does need to make sure that these have
-	 * upper/lower limits when changing.
-	 */
-	sctp_proto.max_instreams    = SCTP_MAX_STREAM;
-	sctp_proto.max_outstreams   = SCTP_MAX_STREAM;
+	/* Initialize default stream count setup information. */
+	sctp_proto.max_instreams    = SCTP_DEFAULT_INSTREAMS;
+	sctp_proto.max_outstreams   = SCTP_DEFAULT_OUTSTREAMS;
 
 	/* Allocate and initialize the association hash table.  */
 	sctp_proto.assoc_hashsize = 4096;
@@ -829,6 +912,7 @@
 
 	sctp_get_local_addr_list(&sctp_proto);
 
+	__unsafe(THIS_MODULE);
 	return 0;
 
 err_ctl_sock_init:
@@ -852,7 +936,7 @@
 }
 
 /* Exit handler for the SCTP protocol.  */
-void sctp_exit(void)
+__exit void sctp_exit(void)
 {
 	/* BUG.  This should probably do something useful like clean
 	 * up all the remaining associations and all that memory.
@@ -889,4 +973,3 @@
 MODULE_AUTHOR("Linux Kernel SCTP developers <lksctp-developers@lists.sourceforge.net>");
 MODULE_DESCRIPTION("Support for the SCTP protocol (RFC2960)");
 MODULE_LICENSE("GPL");
-
diff -Nru a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
--- a/net/sctp/sm_make_chunk.c	Fri Feb 14 15:53:09 2003
+++ b/net/sctp/sm_make_chunk.c	Fri Feb 14 15:53:09 2003
@@ -82,12 +82,12 @@
 
 /* gcc 3.2 doesn't allow initialization of zero-length arrays. So the above
  * structure is split and the address types array is initialized using a
- * fixed length array. 
+ * fixed length array.
  */
 static const __u16 sat_addr_types[2] = {
 	SCTP_PARAM_IPV4_ADDRESS,
 	SCTP_V6(SCTP_PARAM_IPV6_ADDRESS,)
-};			
+};
 
 /* RFC 2960 3.3.2 Initiation (INIT) (1)
  *
@@ -116,8 +116,8 @@
 	err.cause = cause_code;
 	len = sizeof(sctp_errhdr_t) + paylen;
 	padlen = len % 4;
-	len += padlen;
 	err.length  = htons(len);
+	len += padlen;
 	sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err);
 	chunk->subh.err_hdr = sctp_addto_chunk(chunk, paylen, payload);
 }
@@ -242,35 +242,10 @@
 	sctp_cookie_param_t *cookie;
 	int cookie_len;
 	size_t chunksize;
-	int error;
-	sctp_scope_t scope;
-	sctp_bind_addr_t *bp = NULL;
-	int flags;
 
 	retval = NULL;
 
-	/* Build up the bind address list for the association based on
-	 * info from the local endpoint and the remote peer.
-	 */
-	bp = sctp_bind_addr_new(priority);
-	if (!bp)
-		goto nomem_bindaddr;
-
-	/* Look for supported address types parameter and then build
-	 * our address list based on that.
-	 */
-	scope = sctp_scope(&asoc->peer.active_path->ipaddr);
-	flags = (PF_INET6 == asoc->base.sk->family) ? SCTP_ADDR6_ALLOWED : 0;
-	if (asoc->peer.ipv4_address)
-		flags |= SCTP_ADDR4_PEERSUPP;
-	if (asoc->peer.ipv6_address)
-		flags |= SCTP_ADDR6_PEERSUPP;
-	error = sctp_bind_addr_copy(bp, &asoc->ep->base.bind_addr,
-				    scope, priority, flags);
-	if (error)
-		goto nomem_copyaddr;
-
-	addrs = sctp_bind_addrs_to_raw(bp, &addrs_len, priority);
+	addrs = sctp_bind_addrs_to_raw(&asoc->base.bind_addr, &addrs_len, priority);
 	if (!addrs.v)
 		goto nomem_rawaddr;
 
@@ -333,9 +308,6 @@
 nomem_cookie:
 	kfree(addrs.v);
 nomem_rawaddr:
-nomem_copyaddr:
-	sctp_bind_addr_free(bp);
-nomem_bindaddr:
 	return retval;
 }
 
@@ -598,23 +570,9 @@
 				   const struct sctp_sndrcvinfo *sinfo,
 				   int data_len)
 {
-	__u16 ssn;
 	__u8 flags = SCTP_DATA_NOT_FRAG;
 
-	/* Sockets API Extensions for SCTP 5.2.2
-	 *  MSG_UNORDERED - This flag requests the un-ordered delivery of the
-	 *  message.  If this flag is clear, the datagram is considered an
-	 *  ordered send and a new ssn is generated.  The flags field is set
-	 *  in the inner routine - sctp_make_datafrag_empty().
-	 */
-	if (sinfo->sinfo_flags & MSG_UNORDERED) {
-		ssn = 0;
-	} else {
-		ssn = __sctp_association_get_next_ssn(asoc,
-						      sinfo->sinfo_stream);
-	}
-
-	return sctp_make_datafrag_empty(asoc, sinfo, data_len, flags, ssn);
+	return sctp_make_datafrag_empty(asoc, sinfo, data_len, flags, 0);
 }
 
 /* Create a selective ackowledgement (SACK) for the given
@@ -714,6 +672,7 @@
 	return retval;
 }
 
+/* FIXME: Comments. */
 sctp_chunk_t *sctp_make_shutdown(const sctp_association_t *asoc)
 {
 	sctp_chunk_t *retval;
@@ -897,7 +856,7 @@
 
 /* Make a HEARTBEAT chunk.  */
 sctp_chunk_t *sctp_make_heartbeat(const sctp_association_t *asoc,
-				  const sctp_transport_t *transport,
+				  const struct sctp_transport *transport,
 				  const void *payload, const size_t paylen)
 {
 	sctp_chunk_t *retval = sctp_make_chunk(asoc, SCTP_CID_HEARTBEAT,
@@ -909,7 +868,7 @@
 	/* Cast away the 'const', as this is just telling the chunk
 	 * what transport it belongs to.
 	 */
-	retval->transport = (sctp_transport_t *) transport;
+	retval->transport = (struct sctp_transport *) transport;
 	retval->subh.hbs_hdr = sctp_addto_chunk(retval, paylen, payload);
 
 nodata:
@@ -1013,6 +972,7 @@
 	retval->asoc		= (sctp_association_t *) asoc;
 	retval->num_times_sent	= 0;
 	retval->has_tsn		= 0;
+	retval->has_ssn         = 0;
 	retval->rtt_in_progress	= 0;
 	retval->sent_at	= jiffies;
 	retval->singleton	= 1;
@@ -1118,53 +1078,6 @@
 	SCTP_DBG_OBJCNT_DEC(chunk);
 }
 
-/* Do a deep copy of a chunk.  */
-sctp_chunk_t *sctp_copy_chunk(sctp_chunk_t *chunk, const int priority)
-{
-	sctp_chunk_t *retval;
-	long offset;
-
-	retval = t_new(sctp_chunk_t, priority);
-	if (!retval)
-		goto nodata;
-
-	/* Do the shallow copy.  */
-	*retval = *chunk;
-
-	/* Make sure that the copy does NOT think it is on any lists.  */
-	retval->next = NULL;
-	retval->prev = NULL;
-	retval->list = NULL;
-	INIT_LIST_HEAD(&retval->transmitted_list);
-	INIT_LIST_HEAD(&retval->frag_list);
-
-	/* Now we copy the deep structure.  */
-	retval->skb = skb_copy(chunk->skb, priority);
-	if (!retval->skb) {
-		kfree(retval);
-		goto nodata;
-	}
-
-	/* Move the copy headers to point into the new skb.  */
-	offset = ((__u8 *)retval->skb->head)
-		- ((__u8 *)chunk->skb->head);
-
-	if (retval->param_hdr.v)
-		retval->param_hdr.v += offset;
-	if (retval->subh.v)
-		retval->subh.v += offset;
-	if (retval->chunk_end)
-		((__u8 *) retval->chunk_end) += offset;
-	if (retval->chunk_hdr)
-		((__u8 *) retval->chunk_hdr) += offset;
-	if (retval->sctp_hdr)
-		((__u8 *) retval->sctp_hdr) += offset;
-	SCTP_DBG_OBJCNT_INC(chunk);
-	return retval;
-
-nodata:
-	return NULL;
-}
 
 /* Append bytes to the end of a chunk.  Will panic if chunk is not big
  * enough.
@@ -1193,7 +1106,8 @@
  * chunk is not big enough.
  * Returns a kernel err value.
  */
-int sctp_user_addto_chunk(sctp_chunk_t *chunk, int len, struct iovec *data)
+static int sctp_user_addto_chunk(sctp_chunk_t *chunk, int off, int len,
+				 struct iovec *data)
 {
 	__u8 *target;
 	int err = 0;
@@ -1202,7 +1116,7 @@
 	target = skb_put(chunk->skb, len);
 
 	/* Copy data (whole iovec) into chunk */
-	if ((err = memcpy_fromiovec(target, data, len)))
+	if ((err = memcpy_fromiovecend(target, data, off, len)))
 		goto out;
 
 	/* Adjust the chunk length field.  */
@@ -1214,6 +1128,152 @@
 	return err;
 }
 
+/* A data chunk can have a maximum payload of (2^16 - 20).  Break
+ * down any such message into smaller chunks.  Opportunistically, fragment
+ * the chunks down to the current MTU constraints.  We may get refragmented
+ * later if the PMTU changes, but it is _much better_ to fragment immediately
+ * with a reasonable guess than always doing our fragmentation on the
+ * soft-interrupt.
+ */
+
+
+int sctp_datachunks_from_user(sctp_association_t *asoc,
+			      const struct sctp_sndrcvinfo *sinfo,
+			      struct msghdr *msg, int msg_len,
+			      struct sk_buff_head *chunks)
+{
+	int max, whole, i, offset, over, err;
+	int len, first_len;
+	sctp_chunk_t *chunk;
+	__u8 frag;
+
+	/* What is a reasonable fragmentation point right now? */
+	max = asoc->pmtu;
+	if (max < SCTP_MIN_PMTU)
+		max = SCTP_MIN_PMTU;
+	max -= SCTP_IP_OVERHEAD;
+
+	/* Make sure not beyond maximum chunk size. */
+	if (max > SCTP_MAX_CHUNK_LEN)
+		max = SCTP_MAX_CHUNK_LEN;
+
+	/* Subtract out the overhead of a data chunk header. */
+	max -= sizeof(struct sctp_data_chunk);
+
+	whole = 0;
+	first_len = max;
+
+	/* Encourage Cookie-ECHO bundling. */
+	if (asoc->state < SCTP_STATE_ESTABLISHED) {
+		whole = msg_len / (max - SCTP_ARBITRARY_COOKIE_ECHO_LEN);
+
+		/* Account for the DATA to be bundled with the COOKIE-ECHO. */
+		if (whole) {
+			first_len = max - SCTP_ARBITRARY_COOKIE_ECHO_LEN;
+			msg_len -= first_len;
+			whole = 1;
+		}
+	} 
+
+	/* How many full sized?  How many bytes leftover? */
+	whole += msg_len / max;
+	over = msg_len % max;
+	offset = 0;
+
+	/* Create chunks for all the full sized DATA chunks. */
+	for (i=0, len=first_len; i < whole; i++) {
+		frag = SCTP_DATA_MIDDLE_FRAG;
+
+		if (0 == i)
+			frag |= SCTP_DATA_FIRST_FRAG;
+
+		if ((i == (whole - 1)) && !over)
+			frag |= SCTP_DATA_LAST_FRAG;
+
+		chunk = sctp_make_datafrag_empty(asoc, sinfo, len, frag, 0);
+
+		if (!chunk)
+			goto nomem;
+		err = sctp_user_addto_chunk(chunk, offset, len, msg->msg_iov);
+		if (err < 0)
+			goto errout;
+
+		offset += len;
+
+		/* Put the chunk->skb back into the form expected by send.  */
+		__skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr
+			   - (__u8 *)chunk->skb->data);
+
+		__skb_queue_tail(chunks, (struct sk_buff *)chunk);
+
+		/* The first chunk, the first chunk was likely short 
+		 * to allow bundling, so reset to full size.
+		 */
+		if (0 == i)
+			len = max;
+	}
+
+	/* .. now the leftover bytes. */
+	if (over) {
+		if (!whole)
+			frag = SCTP_DATA_NOT_FRAG;
+		else
+			frag = SCTP_DATA_LAST_FRAG;
+
+		chunk = sctp_make_datafrag_empty(asoc, sinfo, over, frag, 0);
+
+		if (!chunk)
+			goto nomem;
+
+		err = sctp_user_addto_chunk(chunk, offset, over, msg->msg_iov);
+
+		/* Put the chunk->skb back into the form expected by send.  */
+		__skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr
+			   - (__u8 *)chunk->skb->data);
+		if (err < 0)
+			goto errout;
+
+		__skb_queue_tail(chunks, (struct sk_buff *)chunk);
+	}
+	err = 0;
+	goto out;
+
+nomem:
+	err = -ENOMEM;
+errout:
+	while ((chunk = (sctp_chunk_t *)__skb_dequeue(chunks)))
+		sctp_free_chunk(chunk);
+out:
+	return err;
+}
+
+/* Helper function to assign a TSN if needed.  This assumes that both
+ * the data_hdr and association have already been assigned.
+ */
+void sctp_chunk_assign_ssn(sctp_chunk_t *chunk)
+{
+	__u16 ssn;
+	__u16 sid;
+
+	if (chunk->has_ssn)
+		return;
+
+	/* This is the last possible instant to assign a SSN. */
+	if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
+		ssn = 0;
+	} else {
+		sid = htons(chunk->subh.data_hdr->stream);
+		if (chunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG)
+			ssn = sctp_ssn_next(&chunk->asoc->ssnmap->out, sid);
+		else
+			ssn = sctp_ssn_peek(&chunk->asoc->ssnmap->out, sid);
+		ssn = htons(ssn);
+	}
+
+	chunk->subh.data_hdr->ssn = ssn;
+	chunk->has_ssn = 1;
+}
+
 /* Helper function to assign a TSN if needed.  This assumes that both
  * the data_hdr and association have already been assigned.
  */
@@ -1352,11 +1412,10 @@
 	sctp_signed_cookie_t *cookie;
 	sctp_cookie_t *bear_cookie;
 	int headersize, bodysize;
-	int fixed_size, var_size1, var_size2, var_size3;
+	int fixed_size;
 	__u8 digest_buf[SCTP_SIGNATURE_SIZE];
 	int secret;
 	sctp_scope_t scope;
-	__u8 *raw_addr_list;
 
 	headersize = sizeof(sctp_chunkhdr_t) + SCTP_SECRET_SIZE;
 	bodysize = ntohs(chunk->chunk_hdr->length) - headersize;
@@ -1377,9 +1436,6 @@
 	/* Process the cookie.  */
 	cookie = chunk->subh.cookie_hdr;
 	bear_cookie = &cookie->c;
-	var_size1 = ntohs(chunk->chunk_hdr->length) - fixed_size;
-	var_size2 = ntohs(bear_cookie->peer_init->chunk_hdr.length);
-	var_size3 = bear_cookie->raw_addr_list_len;
 
 	/* Check the signature.  */
 	secret = ep->current_key;
@@ -1403,6 +1459,7 @@
 	 * for init collision case of lost COOKIE ACK.
 	 */
 	if (!asoc && tv_lt(bear_cookie->expiration, chunk->skb->stamp)) {
+		__u16 len;
 		/*
 		 * Section 3.3.10.3 Stale Cookie Error (3)
 		 *
@@ -1411,8 +1468,8 @@
 		 * Stale Cookie Error:  Indicates the receipt of a valid State
 		 * Cookie that has expired.
 		 */
-		*err_chk_p = sctp_make_op_error_space(asoc, chunk,
-						ntohs(chunk->chunk_hdr->length));
+		len = ntohs(chunk->chunk_hdr->length);
+		*err_chk_p = sctp_make_op_error_space(asoc, chunk, len);
 		if (*err_chk_p) {
 			suseconds_t usecs = (chunk->skb->stamp.tv_sec -
 				bear_cookie->expiration.tv_sec) * 1000000L +
@@ -1443,12 +1500,8 @@
 	/* Populate the association from the cookie.  */
 	retval->c = *bear_cookie;
 
-	/* Build the bind address list based on the cookie.  */
-	raw_addr_list = (__u8 *) bear_cookie +
-		sizeof(sctp_cookie_t) + var_size2;
-	if (sctp_raw_to_bind_addrs(&retval->base.bind_addr, raw_addr_list,
-				   var_size3, retval->base.bind_addr.port,
-				   priority)) {
+	if (sctp_assoc_set_bind_addr_from_cookie(retval, bear_cookie,
+						 GFP_ATOMIC) < 0) {
 		*error = -SCTP_IERROR_NOMEM;
 		goto fail;
 	}
@@ -1477,6 +1530,57 @@
  * 3rd Level Abstractions
  ********************************************************************/
 
+/*
+ * Report a missing mandatory parameter.
+ */
+struct __sctp_missing {
+	__u32 num_missing;
+	__u16 type;
+}  __attribute__((packed));;
+static int sctp_process_missing_param(const sctp_association_t *asoc,
+				      sctp_param_t paramtype,
+				      sctp_chunk_t *chunk,
+				      sctp_chunk_t **err_chk_p)
+{
+	struct __sctp_missing report;
+	__u16 len;
+
+	len = WORD_ROUND(sizeof(report));
+
+	/* Make an ERROR chunk, preparing enough room for
+	 * returning multiple unknown parameters.
+	 */
+	if (!*err_chk_p)
+		*err_chk_p = sctp_make_op_error_space(asoc, chunk, len);
+
+	if (*err_chk_p) {
+		report.num_missing = htonl(1);
+		report.type = paramtype;
+		sctp_init_cause(*err_chk_p, SCTP_ERROR_INV_PARAM,
+				&report, sizeof(report));
+	}
+
+	/* Stop processing this chunk. */
+	return 0;
+}
+
+/* Report an Invalid Mandatory Parameter.  */
+static int sctp_process_inv_mandatory(const sctp_association_t *asoc,
+				      sctp_chunk_t *chunk,
+				      sctp_chunk_t **err_chk_p)
+{
+	/* Invalid Mandatory Parameter Error has no payload. */
+
+	if (!*err_chk_p)
+		*err_chk_p = sctp_make_op_error_space(asoc, chunk, 0);
+
+	if (*err_chk_p)
+		sctp_init_cause(*err_chk_p, SCTP_ERROR_INV_PARAM, NULL, 0);
+
+	/* Stop processing this chunk. */
+	return 0;
+}
+
 /* Do not attempt to handle the HOST_NAME parm.  However, do
  * send back an indicator to the peer.
  */
@@ -1487,9 +1591,7 @@
 {
 	__u16 len = ntohs(param.p->length);
 
-	/* Make an ERROR chunk, preparing enough room for
-	 * returning multiple unknown parameters.
-	 */
+	/* Make an ERROR chunk. */
 	if (!*err_chk_p)
 		*err_chk_p = sctp_make_op_error_space(asoc, chunk, len);
 
@@ -1570,7 +1672,8 @@
 		} else {
 			/* If there is no memory for generating the ERROR
 			 * report as specified, an ABORT will be triggered
-			 * to the peer and the association won't be established.
+			 * to the peer and the association won't be
+			 * established.
 			 */
 			retval = 0;
 		}
@@ -1633,12 +1736,33 @@
 		     sctp_chunk_t **err_chk_p)
 {
 	union sctp_params param;
+	int has_cookie = 0;
+
+	/* Verify stream values are non-zero. */
+	if ((0 == peer_init->init_hdr.num_outbound_streams) ||
+	    (0 == peer_init->init_hdr.num_inbound_streams)) {
 
-	/* FIXME - Verify the fixed fields of the INIT chunk. Also, verify
-	 * the mandatory parameters somewhere here and generate either the
-	 * "Missing mandatory parameter" error or the "Invalid mandatory
-	 * parameter" error.
+		sctp_process_inv_mandatory(asoc, chunk, err_chk_p);
+		return 0;
+	}
+
+	/* Check for missing mandatory parameters.  */
+	sctp_walk_params(param, peer_init, init_hdr.params) {
+
+		if (SCTP_PARAM_STATE_COOKIE == param.p->type)
+			has_cookie = 1;
+
+	} /* for (loop through all parameters) */
+
+	/* The only missing mandatory param possible today is
+	 * the state cookie for an INIT-ACK chunk.
 	 */
+	if ((SCTP_CID_INIT_ACK == cid) && !has_cookie) {
+
+		sctp_process_missing_param(asoc, SCTP_PARAM_STATE_COOKIE,
+					   chunk, err_chk_p);
+		return 0;
+	}
 
 	/* Find unrecognized parameters. */
 
@@ -1654,6 +1778,7 @@
 
 /* Unpack the parameters in an INIT packet into an association.
  * Returns 0 on failure, else success.
+ * FIXME:  This is an association method.
  */
 int sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
 		      const union sctp_addr *peer_addr,
@@ -1661,7 +1786,7 @@
 		      int priority)
 {
 	union sctp_params param;
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 	struct list_head *pos, *temp;
 	char *cookie;
 
@@ -1710,6 +1835,12 @@
 			ntohs(peer_init->init_hdr.num_inbound_streams);
 	}
 
+	if (asoc->c.sinit_max_instreams >
+	    ntohs(peer_init->init_hdr.num_outbound_streams)) {
+		asoc->c.sinit_max_instreams =
+			ntohs(peer_init->init_hdr.num_outbound_streams);
+	}
+
 	/* Copy Initiation tag from INIT to VT_peer in cookie.   */
 	asoc->c.peer_vtag = asoc->peer.i.init_tag;
 
@@ -1730,7 +1861,7 @@
 	 * advertised window).
 	 */
 	list_for_each(pos, &asoc->peer.transport_addr_list) {
-		transport = list_entry(pos, sctp_transport_t, transports);
+		transport = list_entry(pos, struct sctp_transport, transports);
 		transport->ssthresh = asoc->peer.i.a_rwnd;
 	}
 
@@ -1738,6 +1869,21 @@
 	sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE,
 			 asoc->peer.i.initial_tsn);
 
+	/* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
+	 *
+	 * The stream sequence number in all the streams shall start
+	 * from 0 when the association is established.  Also, when the
+	 * stream sequence number reaches the value 65535 the next
+	 * stream sequence number shall be set to 0.
+	 */
+
+	/* Allocate storage for the negotiated streams. */
+	asoc->ssnmap = sctp_ssnmap_new(asoc->peer.i.num_outbound_streams,
+				       asoc->c.sinit_num_ostreams,
+				       priority);
+	if (!asoc->ssnmap)
+		goto nomem_ssnmap;
+
 	/* ADDIP Section 4.1 ASCONF Chunk Procedures
 	 *
 	 * When an endpoint has an ASCONF signaled change to be sent to the
@@ -1751,10 +1897,11 @@
 	asoc->peer.addip_serial = asoc->peer.i.initial_tsn - 1;
 	return 1;
 
+nomem_ssnmap:
 clean_up:
 	/* Release the transport structures. */
 	list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
-		transport = list_entry(pos, sctp_transport_t, transports);
+		transport = list_entry(pos, struct sctp_transport, transports);
 		list_del(pos);
 		sctp_transport_free(transport);
 	}
diff -Nru a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
--- a/net/sctp/sm_sideeffect.c	Fri Feb 14 15:53:11 2003
+++ b/net/sctp/sm_sideeffect.c	Fri Feb 14 15:53:11 2003
@@ -56,33 +56,29 @@
 #include <net/sctp/sm.h>
 
 /* Do forward declarations of static functions.  */
-static void sctp_do_ecn_ce_work(sctp_association_t *asoc,
-				__u32 lowest_tsn);
+static void sctp_do_ecn_ce_work(sctp_association_t *,__u32 lowest_tsn);
 static sctp_chunk_t *sctp_do_ecn_ecne_work(sctp_association_t *asoc,
 					   __u32 lowest_tsn,
 					   sctp_chunk_t *);
-static void sctp_do_ecn_cwr_work(sctp_association_t *asoc,
-				 __u32 lowest_tsn);
-
-static void sctp_do_8_2_transport_strike(sctp_association_t *asoc,
-					 sctp_transport_t *transport);
-static void sctp_cmd_init_failed(sctp_cmd_seq_t *, sctp_association_t *asoc);
-static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *, sctp_association_t *asoc,
-				  sctp_event_t event_type, sctp_subtype_t stype,
+static void sctp_do_ecn_cwr_work(sctp_association_t *,__u32 lowest_tsn);
+static void sctp_do_8_2_transport_strike(sctp_association_t *,
+					 struct sctp_transport *);
+static void sctp_cmd_init_failed(sctp_cmd_seq_t *, sctp_association_t *);
+static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *, sctp_association_t *,
+				  sctp_event_t, sctp_subtype_t,
 				  sctp_chunk_t *chunk);
-static int sctp_cmd_process_init(sctp_cmd_seq_t *, sctp_association_t *asoc,
+static int sctp_cmd_process_init(sctp_cmd_seq_t *, sctp_association_t *,
 				 sctp_chunk_t *chunk,
 				 sctp_init_chunk_t *peer_init,
 				 int priority);
 static void sctp_cmd_hb_timers_start(sctp_cmd_seq_t *, sctp_association_t *);
-static void sctp_cmd_hb_timers_update(sctp_cmd_seq_t *, sctp_association_t *,
-				      sctp_transport_t *);
-static void sctp_cmd_set_bind_addrs(sctp_cmd_seq_t *, sctp_association_t *,
-				    sctp_bind_addr_t *);
+static void sctp_cmd_hb_timers_stop(sctp_cmd_seq_t *, sctp_association_t *);
+static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *, sctp_association_t *,
+				     struct sctp_transport *);
 static void sctp_cmd_transport_reset(sctp_cmd_seq_t *, sctp_association_t *,
-				     sctp_transport_t *);
+				     struct sctp_transport *);
 static void sctp_cmd_transport_on(sctp_cmd_seq_t *, sctp_association_t *,
-				  sctp_transport_t *, sctp_chunk_t *);
+				  struct sctp_transport *, sctp_chunk_t *);
 static int sctp_cmd_process_sack(sctp_cmd_seq_t *, sctp_association_t *,
 				 sctp_sackhdr_t *);
 static void sctp_cmd_setup_t2(sctp_cmd_seq_t *, sctp_association_t *,
@@ -264,7 +260,7 @@
 	struct list_head *pos;
 	struct timer_list *timer;
 	unsigned long timeout;
-	sctp_transport_t *t;
+	struct sctp_transport *t;
 	sctp_sackhdr_t sackh;
 
 	if(SCTP_EVENT_T_TIMEOUT != event_type)
@@ -296,7 +292,7 @@
 		       break;
 
 		case SCTP_CMD_PURGE_OUTQUEUE:
-		       sctp_outqueue_teardown(&asoc->outqueue);
+		       sctp_outq_teardown(&asoc->outqueue);
 		       break;
 
 		case SCTP_CMD_DELETE_TCB:
@@ -395,9 +391,9 @@
 					  command->obj.ptr,
 					  "ulpq:",
 					  &asoc->ulpq);
-			sctp_ulpqueue_tail_data(&asoc->ulpq,
-						command->obj.ptr,
-						GFP_ATOMIC);
+			sctp_ulpq_tail_data(&asoc->ulpq,
+					    command->obj.ptr,
+					    GFP_ATOMIC);
 			break;
 
 		case SCTP_CMD_EVENT_ULP:
@@ -407,14 +403,14 @@
 					  command->obj.ptr,
 					  "ulpq:",
 					  &asoc->ulpq);
-			sctp_ulpqueue_tail_event(&asoc->ulpq,
-						 command->obj.ptr);
+			sctp_ulpq_tail_event(&asoc->ulpq,
+					     command->obj.ptr);
 			break;
 
 		case SCTP_CMD_REPLY:
 			/* Send a chunk to our peer.  */
-			error = sctp_push_outqueue(&asoc->outqueue,
-						   command->obj.ptr);
+			error = sctp_outq_tail(&asoc->outqueue,
+					       command->obj.ptr);
 			break;
 
 		case SCTP_CMD_SEND_PKT:
@@ -427,12 +423,13 @@
 		case SCTP_CMD_RETRAN:
 			/* Mark a transport for retransmission.  */
 			sctp_retransmit(&asoc->outqueue,
-					command->obj.transport, 0);
+					command->obj.transport,
+					SCTP_RETRANSMIT_T3_RTX);
 			break;
 
 		case SCTP_CMD_TRANSMIT:
 			/* Kick start transmission. */
-			error = sctp_flush_outqueue(&asoc->outqueue, 0);
+			error = sctp_outq_flush(&asoc->outqueue, 0);
 			break;
 
 		case SCTP_CMD_ECN_CE:
@@ -502,7 +499,7 @@
 			 * COOKIE-ECHO we need to resend.
 			 */
 			list_for_each(pos, &asoc->peer.transport_addr_list) {
-				t = list_entry(pos, sctp_transport_t,
+				t = list_entry(pos, struct sctp_transport,
 					       transports);
 				sctp_retransmit_mark(&asoc->outqueue, t, 0);
 			}
@@ -547,11 +544,6 @@
 			SCTP_DEBUG_PRINTK("vtag mismatch!\n");
 			break;
 
-		case SCTP_CMD_SET_BIND_ADDR:
-		        sctp_cmd_set_bind_addrs(commands, asoc,
-						command->obj.bp);
-			break;
-
 		case SCTP_CMD_STRIKE:
 			/* Mark one strike against a transport.  */
 			sctp_do_8_2_transport_strike(asoc,
@@ -572,9 +564,13 @@
 			sctp_cmd_hb_timers_start(commands, asoc);
 			break;
 
-		case SCTP_CMD_HB_TIMERS_UPDATE:
+		case SCTP_CMD_HB_TIMER_UPDATE:
 			t = command->obj.transport;
-			sctp_cmd_hb_timers_update(commands, asoc, t);
+			sctp_cmd_hb_timer_update(commands, asoc, t);
+			break;
+
+		case SCTP_CMD_HB_TIMERS_STOP:
+			sctp_cmd_hb_timers_stop(commands, asoc);
 			break;
 
 		case SCTP_CMD_REPORT_ERROR:
@@ -599,7 +595,7 @@
 
 		case SCTP_CMD_RTO_PENDING:
 			t = command->obj.transport;
-			t->rto_pending = 1;	
+			t->rto_pending = 1;
 			break;
 
 		default:
@@ -656,7 +652,7 @@
 	 * recent than the last response.
 	 */
 	if (TSN_lt(asoc->last_cwr_tsn, lowest_tsn)) {
-		sctp_transport_t *transport;
+		struct sctp_transport *transport;
 
 		/* Find which transport's congestion variables
 		 * need to be adjusted.
@@ -743,7 +739,7 @@
 		asoc->peer.sack_needed = 0;
 		asoc->peer.next_dup_tsn = 0;
 
-		error = sctp_push_outqueue(&asoc->outqueue, sack);
+		error = sctp_outq_tail(&asoc->outqueue, sack);
 
 		/* Stop the SACK timer.  */
 		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
@@ -802,7 +798,7 @@
 void sctp_generate_t3_rtx_event(unsigned long peer)
 {
 	int error;
-	sctp_transport_t *transport = (sctp_transport_t *) peer;
+	struct sctp_transport *transport = (struct sctp_transport *) peer;
 	sctp_association_t *asoc = transport->asoc;
 
 	/* Check whether a task is in the sock.  */
@@ -917,7 +913,7 @@
 void sctp_generate_heartbeat_event(unsigned long data)
 {
 	int error = 0;
-	sctp_transport_t *transport = (sctp_transport_t *) data;
+	struct sctp_transport *transport = (struct sctp_transport *) data;
 	sctp_association_t *asoc = transport->asoc;
 
 	sctp_bh_lock_sock(asoc->base.sk);
@@ -957,24 +953,16 @@
 	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_SACK);
 }
 
-void sctp_generate_pmtu_raise_event(unsigned long data)
-{
-	sctp_association_t *asoc = (sctp_association_t *) data;
-	sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_PMTU_RAISE);
-}
-
 sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = {
 	NULL,
 	sctp_generate_t1_cookie_event,
 	sctp_generate_t1_init_event,
 	sctp_generate_t2_shutdown_event,
 	NULL,
-	NULL,
 	sctp_generate_t5_shutdown_guard_event,
 	sctp_generate_heartbeat_event,
 	sctp_generate_sack_event,
 	sctp_generate_autoclose_event,
-	sctp_generate_pmtu_raise_event,
 };
 
 /********************************************************************
@@ -997,7 +985,7 @@
  *
  */
 static void sctp_do_8_2_transport_strike(sctp_association_t *asoc,
-					 sctp_transport_t *transport)
+					 struct sctp_transport *transport)
 {
 	/* The check for association's overall error counter exceeding the
 	 * threshold is done in the state function.
@@ -1095,7 +1083,7 @@
 /* Process an init chunk (may be real INIT/INIT-ACK or an embedded INIT
  * inside the cookie.  In reality, this is only used for INIT-ACK processing
  * since all other cases use "temporary" associations and can do all
- * their work in statefuns directly. 
+ * their work in statefuns directly.
  */
 static int sctp_cmd_process_init(sctp_cmd_seq_t *commands,
 				 sctp_association_t *asoc,
@@ -1125,7 +1113,7 @@
 static void sctp_cmd_hb_timers_start(sctp_cmd_seq_t *cmds,
 				     sctp_association_t *asoc)
 {
-	sctp_transport_t *t;
+	struct sctp_transport *t;
 	struct list_head *pos;
 
 	/* Start a heartbeat timer for each transport on the association.
@@ -1133,45 +1121,43 @@
 	 * the needed data structures go away.
 	 */
 	list_for_each(pos, &asoc->peer.transport_addr_list) {
-		t = list_entry(pos, sctp_transport_t, transports);
-		if (!mod_timer(&t->hb_timer,
-			       t->hb_interval + t->rto + jiffies)) {
+		t = list_entry(pos, struct sctp_transport, transports);
+
+		if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t)))
 			sctp_transport_hold(t);
-		}
 	}
 }
 
-/* Helper function to update the heartbeat timer. */
-static void sctp_cmd_hb_timers_update(sctp_cmd_seq_t *cmds,
-				   sctp_association_t *asoc,
-				   sctp_transport_t *t)
+static void sctp_cmd_hb_timers_stop(sctp_cmd_seq_t *cmds,
+				    sctp_association_t *asoc)
 {
-	/* Update the heartbeat timer.  */
-	if (!mod_timer(&t->hb_timer, t->hb_interval + t->rto + jiffies))
-		sctp_transport_hold(t);
-}
+	struct sctp_transport *t;
+	struct list_head *pos;
+
+	/* Stop all heartbeat timers. */
 
-/* Helper function to break out SCTP_CMD_SET_BIND_ADDR handling.  */
-void sctp_cmd_set_bind_addrs(sctp_cmd_seq_t *cmds, sctp_association_t *asoc,
-			     sctp_bind_addr_t *bp)
-{
-	struct list_head *pos, *temp;
-
-	list_for_each_safe(pos, temp, &bp->address_list) {
-		list_del_init(pos);
-		list_add_tail(pos, &asoc->base.bind_addr.address_list);
+	list_for_each(pos, &asoc->peer.transport_addr_list) {
+		t = list_entry(pos, struct sctp_transport, transports);
+		if (del_timer(&t->hb_timer))
+			sctp_transport_put(t);
 	}
+} 
 
-	/* Free the temporary bind addr header, otherwise
-	 * there will a memory leak.
-	 */
-	sctp_bind_addr_free(bp);
+/* Helper function to update the heartbeat timer. */
+static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds,
+				     sctp_association_t *asoc,
+				     struct sctp_transport *t)
+{
+	/* Update the heartbeat timer.  */
+	if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t)))
+		sctp_transport_hold(t);
 }
 
 /* Helper function to handle the reception of an HEARTBEAT ACK.  */
 static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
 				  sctp_association_t *asoc,
-				  sctp_transport_t *t, sctp_chunk_t *chunk)
+				  struct sctp_transport *t,
+				  sctp_chunk_t *chunk)
 {
 	sctp_sender_hb_info_t *hbinfo;
 
@@ -1203,7 +1189,7 @@
  */
 static void sctp_cmd_transport_reset(sctp_cmd_seq_t *cmds,
 				     sctp_association_t *asoc,
-				     sctp_transport_t *t)
+				     struct sctp_transport *t)
 {
 	sctp_transport_lower_cwnd(t, SCTP_LOWER_CWND_INACTIVE);
 
@@ -1218,7 +1204,7 @@
 {
 	int err;
 
-	if (sctp_sack_outqueue(&asoc->outqueue, sackh)) {
+	if (sctp_outq_sack(&asoc->outqueue, sackh)) {
 		/* There are no more TSNs awaiting SACK.  */
 		err = sctp_do_sm(SCTP_EVENT_T_OTHER,
 				 SCTP_ST_OTHER(SCTP_EVENT_NO_PENDING_TSN),
@@ -1228,7 +1214,7 @@
 		/* Windows may have opened, so we need
 		 * to check if we have DATA to transmit
 		 */
-		err = sctp_flush_outqueue(&asoc->outqueue, 0);
+		err = sctp_outq_flush(&asoc->outqueue, 0);
 	}
 
 	return err;
@@ -1240,7 +1226,7 @@
 static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds, sctp_association_t *asoc,
 			      sctp_chunk_t *chunk)
 {
-	sctp_transport_t *t;
+	struct sctp_transport *t;
 
 	t = sctp_assoc_choose_shutdown_transport(asoc);
 	asoc->shutdown_last_sent_to = t;
diff -Nru a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
--- a/net/sctp/sm_statefuns.c	Fri Feb 14 15:53:08 2003
+++ b/net/sctp/sm_statefuns.c	Fri Feb 14 15:53:08 2003
@@ -191,7 +191,7 @@
 	int len;
 
 	/* If the packet is an OOTB packet which is temporarily on the
-	 * control endpoint, responding with an ABORT.
+	 * control endpoint, respond with an ABORT.
 	 */
 	if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
 		return sctp_sf_ootb(ep, asoc, type, arg, commands);
@@ -262,6 +262,9 @@
 		len = ntohs(err_chunk->chunk_hdr->length) -
 			sizeof(sctp_chunkhdr_t);
 
+	if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
+		goto nomem_ack;
+	
 	repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
 	if (!repl)
 		goto nomem_ack;
@@ -506,7 +509,7 @@
 	sctp_chunk_t *err_chk_p;
 
 	/* If the packet is an OOTB packet which is temporarily on the
-	 * control endpoint, responding with an ABORT.
+	 * control endpoint, respond with an ABORT.
 	 */
 	if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
 		return sctp_sf_ootb(ep, asoc, type, arg, commands);
@@ -678,7 +681,7 @@
 				     void *arg,
 				     sctp_cmd_seq_t *commands)
 {
-	sctp_transport_t *transport = (sctp_transport_t *) arg;
+	struct sctp_transport *transport = (struct sctp_transport *) arg;
 	sctp_chunk_t *reply;
 	sctp_sender_hb_info_t hbinfo;
 	size_t paylen = 0;
@@ -711,7 +714,7 @@
 					void *arg,
 					sctp_cmd_seq_t *commands)
 {
-	sctp_transport_t *transport = (sctp_transport_t *) arg;
+	struct sctp_transport *transport = (struct sctp_transport *) arg;
 
 	if (asoc->overall_error_count >= asoc->overall_error_threshold) {
 		/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
@@ -737,7 +740,7 @@
 		sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_RESET,
 				SCTP_TRANSPORT(transport));
 	}
-	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_UPDATE,
+	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMER_UPDATE,
 			SCTP_TRANSPORT(transport));
 
         return SCTP_DISPOSITION_CONSUME;
@@ -842,7 +845,7 @@
 {
 	sctp_chunk_t *chunk = arg;
 	union sctp_addr from_addr;
-	sctp_transport_t *link;
+	struct sctp_transport *link;
 	sctp_sender_hb_info_t *hbinfo;
 	unsigned long max_interval;
 
@@ -944,7 +947,7 @@
 				       sctp_chunk_t *init,
 				       sctp_cmd_seq_t *commands)
 {
-	sctp_transport_t *new_addr, *addr;
+	struct sctp_transport *new_addr, *addr;
 	struct list_head *pos, *pos2;
 	int found;
 
@@ -963,10 +966,11 @@
 	found = 0;
 
 	list_for_each(pos, &new_asoc->peer.transport_addr_list) {
-		new_addr = list_entry(pos, sctp_transport_t, transports);
+		new_addr = list_entry(pos, struct sctp_transport, transports);
 		found = 0;
 		list_for_each(pos2, &asoc->peer.transport_addr_list) {
-			addr = list_entry(pos2, sctp_transport_t, transports);
+			addr = list_entry(pos2, struct sctp_transport,
+					  transports);
 			if (sctp_cmp_addr_exact(&new_addr->ipaddr,
 						&addr->ipaddr)) {
 				found = 1;
@@ -1048,20 +1052,17 @@
 	    (asoc->c.peer_vtag == new_asoc->c.peer_ttag))
 		return 'A';
 
-	/* Collision case D.
-	 * Note: Test case D first, otherwise it may be incorrectly
-	 * identified as second case of B if the value of the Tie_tag is
-	 * not filled into the state cookie.
-	 */
-	if ((asoc->c.my_vtag == new_asoc->c.my_vtag) &&
-	    (asoc->c.peer_vtag == new_asoc->c.peer_vtag))
-		return 'D';
-
 	/* Collision case B. */
 	if ((asoc->c.my_vtag == new_asoc->c.my_vtag) &&
 	    ((asoc->c.peer_vtag != new_asoc->c.peer_vtag) ||
-	     (!new_asoc->c.my_ttag && !new_asoc->c.peer_ttag)))
+	     (0 == asoc->c.peer_vtag))) {
 		return 'B';
+	}
+
+	/* Collision case D. */
+	if ((asoc->c.my_vtag == new_asoc->c.my_vtag) &&
+	    (asoc->c.peer_vtag == new_asoc->c.peer_vtag))
+		return 'D';
 
 	/* Collision case C. */
 	if ((asoc->c.my_vtag != new_asoc->c.my_vtag) &&
@@ -1070,7 +1071,8 @@
 	    (0 == new_asoc->c.peer_ttag))
 		return 'C';
 
-	return 'E'; /* No such case available. */
+	/* No match to any of the special cases; discard this packet. */
+	return 'E';
 }
 
 /* Common helper routine for both duplicate and simulataneous INIT
@@ -1182,6 +1184,10 @@
 		len = ntohs(err_chunk->chunk_hdr->length) -
 			sizeof(sctp_chunkhdr_t);
 	}
+
+	if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
+		goto nomem;
+
 	repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
 	if (!repl)
 		goto nomem;
@@ -1337,7 +1343,7 @@
 
 
 
-/* Unexpected COOKIE-ECHO handlerfor peer restart (Table 2, action 'A')
+/* Unexpected COOKIE-ECHO handler for peer restart (Table 2, action 'A')
  *
  * Section 5.2.4
  *  A)  In this case, the peer may have restarted.
@@ -1500,11 +1506,17 @@
 	sctp_ulpevent_t *ev = NULL;
 	sctp_chunk_t *repl;
 
-	/* The local endpoint cannot use any value from the received
-	 * state cookie and need to immediately resend a COOKIE-ACK
-	 * and move into ESTABLISHED if it hasn't done so.
+	/* Clarification from Implementor's Guide:
+	 * D) When both local and remote tags match the endpoint should
+         * enter the ESTABLISHED state, if it is in the COOKIE-ECHOED state.
+         * It should stop any cookie timer that may be running and send
+         * a COOKIE ACK.
 	 */
-	if (SCTP_STATE_ESTABLISHED != asoc->state) {
+
+	/* Don't accidentally move back into established state. */
+	if (asoc->state < SCTP_STATE_ESTABLISHED) {
+		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+				SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
 		sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 				SCTP_STATE(SCTP_STATE_ESTABLISHED));
 		sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_START,
@@ -1528,13 +1540,14 @@
 				SCTP_ULPEVENT(ev));
 	}
 	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
-
+	
 	repl = sctp_make_cookie_ack(new_asoc, chunk);
 	if (!repl)
 		goto nomem;
-
+	
 	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
 	sctp_add_cmd_sf(commands, SCTP_CMD_TRANSMIT, SCTP_NULL());
+
 	return SCTP_DISPOSITION_CONSUME;
 
 nomem:
@@ -1605,8 +1618,6 @@
 			sctp_send_stale_cookie_err(ep, asoc, chunk, commands,
 						   err_chk_p);
 			return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
-
-			break;
 		case -SCTP_IERROR_BAD_SIG:
 		default:
 			return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -1629,7 +1640,7 @@
 					      new_asoc);
 		break;
 
-	case 'C': /* Collisioun case C. */
+	case 'C': /* Collision case C. */
 		retval = sctp_sf_do_dupcook_c(ep, asoc, chunk, commands,
 					      new_asoc);
 		break;
@@ -1639,9 +1650,8 @@
 					      new_asoc);
 		break;
 
-	default: /* No such case, discard it. */
-		printk(KERN_WARNING "%s:unknown case\n", __FUNCTION__);
-		retval = SCTP_DISPOSITION_DISCARD;
+	default: /* Discard packet for all others. */
+		retval = sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 		break;
         };
 
@@ -1799,7 +1809,7 @@
 	sctp_cookie_preserve_param_t bht;
 	sctp_errhdr_t *err;
 	struct list_head *pos;
-	sctp_transport_t *t;
+	struct sctp_transport *t;
 	sctp_chunk_t *reply;
 	sctp_bind_addr_t *bp;
 	int attempts;
@@ -1848,9 +1858,11 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_INC,
 			SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR));
 
-	/* If we've sent any data bundled with COOKIE-ECHO we need to resend. */
+	/* If we've sent any data bundled with COOKIE-ECHO we need to
+	 * resend.
+	 */
 	list_for_each(pos, &asoc->peer.transport_addr_list) {
-		t = list_entry(pos, sctp_transport_t, transports);
+		t = list_entry(pos, struct sctp_transport, transports);
 		sctp_add_cmd_sf(commands, SCTP_CMD_RETRAN, SCTP_TRANSPORT(t));
 	}
 
@@ -2030,7 +2042,7 @@
 			SCTP_STATE(SCTP_STATE_SHUTDOWN_RECEIVED));
 	disposition = SCTP_DISPOSITION_CONSUME;
 
-	if (sctp_outqueue_is_empty(&asoc->outqueue)) {
+	if (sctp_outq_is_empty(&asoc->outqueue)) {
 		disposition = sctp_sf_do_9_2_shutdown_ack(ep, asoc, type,
 							  arg, commands);
 	}
@@ -3229,10 +3241,6 @@
 				       sctp_cmd_seq_t *commands)
 {
 	sctp_chunk_t *repl;
-	sctp_bind_addr_t *bp;
-	sctp_scope_t scope;
-	int error;
-	int flags;
 
 	/* The comment below says that we enter COOKIE-WAIT AFTER
 	 * sending the INIT, but that doesn't actually work in our
@@ -3241,35 +3249,6 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_COOKIE_WAIT));
 
-	/* Build up the bind address list for the association based on
-	 * info from the local endpoint and the remote peer.
-	 */
-	bp = sctp_bind_addr_new(GFP_ATOMIC);
-	if (!bp)
-		goto nomem;
-
-	/* Use scoping rules to determine the subset of addresses from
-	 * the endpoint.
-	 */
-	scope = sctp_scope(&asoc->peer.active_path->ipaddr);
-	flags = (PF_INET6 == asoc->base.sk->family) ? SCTP_ADDR6_ALLOWED : 0;
-	if (asoc->peer.ipv4_address)
-		flags |= SCTP_ADDR4_PEERSUPP;
-	if (asoc->peer.ipv6_address)
-		flags |= SCTP_ADDR6_PEERSUPP;
-	error = sctp_bind_addr_copy(bp, &ep->base.bind_addr, scope,
-				    GFP_ATOMIC, flags);
-	if (error)
-		goto nomem;
-
-	/* FIXME: Either move address assignment out of this function
-	 * or else move the association allocation/init into this function.
-	 * The association structure is brand new before calling this
-	 * function, so would not be a sideeffect if the allocation
-	 * moved into this function.  --jgrimm
-	 */
-	sctp_add_cmd_sf(commands, SCTP_CMD_SET_BIND_ADDR, (sctp_arg_t) bp);
-
 	/* RFC 2960 5.1 Normal Establishment of an Association
 	 *
 	 * A) "A" first sends an INIT chunk to "Z".  In the INIT, "A"
@@ -3278,7 +3257,7 @@
 	 * 1 to 4294967295 (see 5.3.1 for Tag value selection). ...
 	 */
 
-	repl = sctp_make_init(asoc, bp, GFP_ATOMIC, 0);
+	repl = sctp_make_init(asoc, &asoc->base.bind_addr, GFP_ATOMIC, 0);
 	if (!repl)
 		goto nomem;
 
@@ -3297,9 +3276,6 @@
 	return SCTP_DISPOSITION_CONSUME;
 
 nomem:
-	if (bp)
-		sctp_bind_addr_free(bp);
-
 	return SCTP_DISPOSITION_NOMEM;
 }
 
@@ -3429,7 +3405,7 @@
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
 
 	disposition = SCTP_DISPOSITION_CONSUME;
-	if (sctp_outqueue_is_empty(&asoc->outqueue)) {
+	if (sctp_outq_is_empty(&asoc->outqueue)) {
 		disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
 							    arg, commands);
 	}
@@ -3767,7 +3743,7 @@
 					void *arg,
 					sctp_cmd_seq_t *commands)
 {
-	return sctp_sf_heartbeat(ep, asoc, type, (sctp_transport_t *)arg,
+	return sctp_sf_heartbeat(ep, asoc, type, (struct sctp_transport *)arg,
 				 commands);
 }
 
@@ -3837,6 +3813,13 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_SHUTDOWN_SENT));
 
+	/* sctp-implguide 2.10 Issues with Heartbeating and failover
+	 *
+	 * HEARTBEAT ... is discontinued after sending either SHUTDOWN
+         * or SHUTDOWN-ACK.
+	 */
+	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL());
+
 	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
 
 	return SCTP_DISPOSITION_CONSUME;
@@ -3889,6 +3872,14 @@
 	/* Enter the SHUTDOWN-ACK-SENT state.  */
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_SHUTDOWN_ACK_SENT));
+
+	/* sctp-implguide 2.10 Issues with Heartbeating and failover
+	 *
+	 * HEARTBEAT ... is discontinued after sending either SHUTDOWN
+         * or SHUTDOWN-ACK.
+	 */
+	sctp_add_cmd_sf(commands, SCTP_CMD_HB_TIMERS_STOP, SCTP_NULL());
+
 	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
 
 	return SCTP_DISPOSITION_CONSUME;
@@ -3933,7 +3924,7 @@
 					void *arg,
 					sctp_cmd_seq_t *commands)
 {
-	sctp_transport_t *transport = arg;
+	struct sctp_transport *transport = arg;
 
 	if (asoc->overall_error_count >= asoc->overall_error_threshold) {
 		/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
@@ -4203,7 +4194,7 @@
 	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
 	disposition = SCTP_DISPOSITION_CONSUME;
-	if (sctp_outqueue_is_empty(&asoc->outqueue)) {
+	if (sctp_outq_is_empty(&asoc->outqueue)) {
 		disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
 							    arg, commands);
 	}
@@ -4333,7 +4324,7 @@
 				 const sctp_chunk_t *chunk)
 {
 	sctp_packet_t *packet;
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 	__u16 sport;
 	__u16 dport;
 	__u32 vtag;
diff -Nru a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
--- a/net/sctp/sm_statetable.c	Fri Feb 14 15:53:12 2003
+++ b/net/sctp/sm_statetable.c	Fri Feb 14 15:53:12 2003
@@ -1,7 +1,7 @@
 /* SCTP kernel reference Implementation
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001 International Business Machines, Corp.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 Nokia, Inc.
  *
@@ -49,7 +49,7 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
-sctp_sm_table_entry_t bug = {
+static sctp_sm_table_entry_t bug = {
 	.fn = sctp_sf_bug, 
 	.name = "sctp_sf_bug"
 };
@@ -206,7 +206,7 @@
 	/* SCTP_STATE_COOKIE_WAIT */ \
 	{.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
 	{.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
@@ -216,7 +216,7 @@
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
 	{.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 } /* TYPE_SCTP_HEARTBEAT_ACK */
 
 #define TYPE_SCTP_ABORT { \
@@ -293,19 +293,19 @@
 	/* SCTP_STATE_CLOSED */ \
 	{.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
 	{.fn = sctp_sf_cookie_echoed_err, .name = "sctp_sf_cookie_echoed_err"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
 	{.fn = sctp_sf_operr_notify, .name = "sctp_sf_operr_notify"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_operr_notify, .name = "sctp_sf_operr_notify"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_operr_notify, .name = "sctp_sf_operr_notify"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \
 } /* TYPE_SCTP_ERROR */
 
 #define TYPE_SCTP_COOKIE_ECHO { \
@@ -504,26 +504,6 @@
 	{.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"},
 };	/* chunk unknown */
 
-#define TYPE_SCTP_PRIMITIVE_INITIALIZE  { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-} /* TYPE_SCTP_PRIMITIVE_INITIALIZE */
 
 #define TYPE_SCTP_PRIMITIVE_ASSOCIATE  { \
 	/* SCTP_STATE_EMPTY */ \
@@ -619,90 +599,6 @@
 	{.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \
 } /* TYPE_SCTP_PRIMITIVE_SEND */
 
-#define TYPE_SCTP_PRIMITIVE_SETPRIMARY  { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-} /* TYPE_SCTP_PRIMITIVE_SETPRIMARY */
-
-#define TYPE_SCTP_PRIMITIVE_RECEIVE  { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-} /* TYPE_SCTP_PRIMITIVE_RECEIVE */
-
-#define TYPE_SCTP_PRIMITIVE_STATUS  { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-} /* TYPE_SCTP_PRIMITIVE_STATUS */
-
-#define TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT  { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-} /* TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT */
-
 #define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT  { \
 	/* SCTP_STATE_EMPTY */ \
 	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
@@ -731,152 +627,16 @@
 	 .name = "sctp_sf_do_prm_requestheartbeat"},          \
 } /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */
 
-#define TYPE_SCTP_PRIMITIVE_GETSRTTREPORT  { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-} /* TYPE_SCTP_PRIMITIVE_GETSRTTREPORT */
-
-#define TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD  { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-} /* TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD */
-
-#define TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS  { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-} /* TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS */
-
-#define TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT  { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-} /* TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT */
-
-#define TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED  { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-} /* TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED */
-
-#define TYPE_SCTP_PRIMITIVE_DESTROY  { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-} /* TYPE_SCTP_PRIMITIVE_DESTROY */
 
 /* The primary index for this table is the primitive type.
  * The secondary index for this table is the state.
  */
 sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = {
-	TYPE_SCTP_PRIMITIVE_INITIALIZE,
 	TYPE_SCTP_PRIMITIVE_ASSOCIATE,
 	TYPE_SCTP_PRIMITIVE_SHUTDOWN,
 	TYPE_SCTP_PRIMITIVE_ABORT,
 	TYPE_SCTP_PRIMITIVE_SEND,
-	TYPE_SCTP_PRIMITIVE_SETPRIMARY,
-	TYPE_SCTP_PRIMITIVE_RECEIVE,
-	TYPE_SCTP_PRIMITIVE_STATUS,
-	TYPE_SCTP_PRIMITIVE_CHANGEHEARTBEAT,
 	TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT,
-	TYPE_SCTP_PRIMITIVE_GETSRTTREPORT,
-	TYPE_SCTP_PRIMITIVE_SETFAILURETHRESHOLD,
-	TYPE_SCTP_PRIMITIVE_SETPROTOPARAMETERS,
-	TYPE_SCTP_PRIMITIVE_RECEIVE_UNSENT,
-	TYPE_SCTP_PRIMITIVE_RECEIVE_UNACKED,
-	TYPE_SCTP_PRIMITIVE_DESTROY,
 };
 
 #define TYPE_SCTP_OTHER_NO_PENDING_TSN  { \
@@ -902,30 +662,8 @@
 	{.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \
 }
 
-#define TYPE_SCTP_OTHER_ICMP_UNREACHFRAG  { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-}
-
 sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_OTHER_NO_PENDING_TSN,
-	TYPE_SCTP_OTHER_ICMP_UNREACHFRAG,
 };
 
 #define TYPE_SCTP_EVENT_TIMEOUT_NONE { \
@@ -1033,27 +771,6 @@
 	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 }
 
-#define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-}
-
 #define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \
 	/* SCTP_STATE_EMPTY */ \
 	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
@@ -1089,11 +806,11 @@
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
 	{.fn = sctp_sf_sendbeat_8_3, .name = "sctp_sf_sendbeat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_sendbeat_8_3, .name = "sctp_sf_sendbeat_8_3"}, \
 	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
+	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 }
 
 #define TYPE_SCTP_EVENT_TIMEOUT_SACK { \
@@ -1139,39 +856,16 @@
 	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 }
 
-#define TYPE_SCTP_EVENT_TIMEOUT_PMTU_RAISE { \
-	/* SCTP_STATE_EMPTY */ \
-	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
-	/* SCTP_STATE_CLOSED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_ESTABLISHED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_PENDING */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-	/* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
-	{.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \
-}
-
 sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = {
 	TYPE_SCTP_EVENT_TIMEOUT_NONE,
 	TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE,
 	TYPE_SCTP_EVENT_TIMEOUT_T1_INIT,
 	TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN,
 	TYPE_SCTP_EVENT_TIMEOUT_T3_RTX,
-	TYPE_SCTP_EVENT_TIMEOUT_T4_RTO,
 	TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD,
 	TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT,
 	TYPE_SCTP_EVENT_TIMEOUT_SACK,
 	TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE,
-	TYPE_SCTP_EVENT_TIMEOUT_PMTU_RAISE,
 };
 
 sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, sctp_state_t state)
diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c	Fri Feb 14 15:53:12 2003
+++ b/net/sctp/socket.c	Fri Feb 14 15:53:12 2003
@@ -1,7 +1,7 @@
 /* Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2002 International Business Machines, Corp.
- * Copyright (c) 2001-2002 Intel Corp.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
+ * Copyright (c) 2001-2003 Intel Corp.
  * Copyright (c) 2001-2002 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
  *
@@ -47,6 +47,7 @@
  *    Daisy Chang           <daisyc@us.ibm.com>
  *    Sridhar Samudrala     <samudrala@us.ibm.com>
  *    Inaky Perez-Gonzalez  <inaky.gonzalez@intel.com>
+ *    Ardelle Fan	    <ardelle.fan@intel.com>
  *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
@@ -131,7 +132,7 @@
 static long sctp_get_port_local(struct sock *, union sctp_addr *);
 
 /* Verify this is a valid sockaddr. */
-static struct sctp_af *sctp_sockaddr_af(struct sctp_opt *opt, 
+static struct sctp_af *sctp_sockaddr_af(struct sctp_opt *opt,
 					union sctp_addr *addr, int len)
 {
 	struct sctp_af *af;
@@ -716,7 +717,7 @@
 	sctp_opt_t *sp;
 	sctp_endpoint_t *ep;
 	sctp_association_t *new_asoc=NULL, *asoc=NULL;
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 	sctp_chunk_t *chunk = NULL;
 	union sctp_addr to;
 	struct sockaddr *msg_name = NULL;
@@ -729,6 +730,7 @@
 	sctp_scope_t scope;
 	long timeo;
 	__u16 sinfo_flags = 0;
+	struct sk_buff_head chunks;
 
 	SCTP_DEBUG_PRINTK("sctp_sendmsg(sk: %p, msg: %p, msg_len: %d)\n",
 			  sk, msg, msg_len);
@@ -754,8 +756,8 @@
 	 */
 	if ((SCTP_SOCKET_UDP_HIGH_BANDWIDTH != sp->type) && msg->msg_name) {
 		int msg_namelen = msg->msg_namelen;
-	
-		err = sctp_verify_addr(sk, (union sctp_addr *)msg->msg_name, 
+
+		err = sctp_verify_addr(sk, (union sctp_addr *)msg->msg_name,
 				       msg_namelen);
 		if (err)
 			return err;
@@ -806,7 +808,7 @@
 		asoc = sctp_endpoint_lookup_assoc(ep, &to, &transport);
 		if (!asoc) {
 			/* If we could not find a matching association on the
-			 * endpoint, make sure that there is no peeled-off 
+			 * endpoint, make sure that there is no peeled-off
 			 * association on another socket.
 			 */
 			if (sctp_endpoint_is_peeled_off(ep, &to)) {
@@ -868,13 +870,6 @@
 					goto out_unlock;
 				}
 			} else {
-				/* Check against the defaults.  */
-				if (sinfo->sinfo_stream >=
-				    sp->initmsg.sinit_num_ostreams) {
-					err = -EINVAL;
-					goto out_unlock;
-				}
-
 				/* Check against the requested.  */
 				if (sinfo->sinfo_stream >=
 				    sinit->sinit_num_ostreams) {
@@ -915,14 +910,8 @@
 					sinit->sinit_num_ostreams;
 			}
 			if (sinit->sinit_max_instreams) {
-				if (sinit->sinit_max_instreams <=
-				    SCTP_MAX_STREAM) {
-					asoc->c.sinit_max_instreams =
-						sinit->sinit_max_instreams;
-				} else {
-					asoc->c.sinit_max_instreams =
-						SCTP_MAX_STREAM;
-				}
+				asoc->c.sinit_max_instreams =
+					sinit->sinit_max_instreams;
 			}
 			if (sinit->sinit_max_attempts) {
 				asoc->max_init_attempts
@@ -936,6 +925,15 @@
 
 		/* Prime the peer's transport structures.  */
 		transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL);
+		if (!transport) {
+			err = -ENOMEM;
+			goto out_free;
+		}
+		err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL);
+		if (err < 0) {
+			err = -ENOMEM;
+			goto out_free;
+		}
 	}
 
 	/* ASSERT: we have a valid association at this point.  */
@@ -949,19 +947,6 @@
 		goto out_free;
 	}
 
-	/* FIXME: In the current implementation, a single chunk is created
-	 * for the entire message initially, even if it has to be fragmented
-	 * later.  As the length field in the chunkhdr is used to set
-	 * the chunk length, the maximum size of the chunk and hence the
-	 * message is limited by its type(__u16).
-	 * The real fix is to fragment the message before creating the chunks.
-	 */
-	if (msg_len > ((__u16)(~(__u16)0) -
-		       WORD_ROUND(sizeof(sctp_data_chunk_t)+1))) {
-		err = -EMSGSIZE;
-		goto out_free;
-	}
-
 	/* If fragmentation is disabled and the message length exceeds the
 	 * association fragmentation point, return EMSGSIZE.  The I-D
 	 * does not specify what this error is, but this looks like
@@ -994,13 +979,6 @@
 			goto out_free;
 	}
 
-	/* Get enough memory for the whole message.  */
-	chunk = sctp_make_data_empty(asoc, sinfo, msg_len);
-	if (!chunk) {
-		err = -ENOMEM;
-		goto out_free;
-	}
-
 #if 0
 	/* FIXME: This looks wrong so I'll comment out.
 	 * We should be able to use this same technique for
@@ -1016,20 +994,13 @@
 	}
 #endif /* 0 */
 
-	/* Copy the message from the user.  */
-	err = sctp_user_addto_chunk(chunk, msg_len, msg->msg_iov);
-	if (err < 0)
+	/* Break the message into multiple chunks of maximum size. */
+	skb_queue_head_init(&chunks);
+	err = sctp_datachunks_from_user(asoc, sinfo, msg, msg_len, &chunks);
+	if (err)
 		goto out_free;
 
-	SCTP_DEBUG_PRINTK("Copied message to chunk: %p.\n", chunk);
-
-	/* Put the chunk->skb back into the form expected by send.  */
-	__skb_pull(chunk->skb, (__u8 *)chunk->chunk_hdr
-		   - (__u8 *)chunk->skb->data);
-
-	/* Do accounting for the write space.  */
-	sctp_set_owner_w(chunk);
-
+	/* Auto-connect, if we aren't connected already. */
 	if (SCTP_STATE_CLOSED == asoc->state) {
 		err = sctp_primitive_ASSOCIATE(asoc, NULL);
 		if (err < 0)
@@ -1037,18 +1008,22 @@
 		SCTP_DEBUG_PRINTK("We associated primitively.\n");
 	}
 
-	/* Send it to the lower layers.  */
-	err = sctp_primitive_SEND(asoc, chunk);
+	/* Now send the (possibly) fragmented message. */
+	while ((chunk = (sctp_chunk_t *)__skb_dequeue(&chunks))) {
 
-	SCTP_DEBUG_PRINTK("We sent primitively.\n");
+		/* Do accounting for the write space.  */
+		sctp_set_owner_w(chunk);
+		/* Send it to the lower layers.  */
+		sctp_primitive_SEND(asoc, chunk);
+		SCTP_DEBUG_PRINTK("We sent primitively.\n");
+	}
 
-	/* BUG: SCTP_CHECK_TIMER(sk); */
 	if (!err) {
 		err = msg_len;
 		goto out_unlock;
 	}
 	/* If we are already past ASSOCIATE, the lower
-	 * layers are responsible for its cleanup.
+	 * layers are responsible for association cleanup.
 	 */
 	goto out_free_chunk;
 
@@ -1086,23 +1061,30 @@
  * frag_list. len specifies the total amount of data that needs to be removed.
  * when 'len' bytes could be removed from the skb, it returns 0.
  * If 'len' exceeds the total skb length,  it returns the no. of bytes that
- * could not be removed. 
- */  
+ * could not be removed.
+ */
 static int sctp_skb_pull(struct sk_buff *skb, int len)
 {
 	struct sk_buff *list;
+	int skb_len = skb_headlen(skb);
+	int rlen;
 
-	if (len <= skb->len) {
+	if (len <= skb_len) {
 		__skb_pull(skb, len);
 		return 0;
 	}
-	len -= skb->len;
-	__skb_pull(skb, skb->len);
+	len -= skb_len;
+	__skb_pull(skb, skb_len);
 
 	for (list = skb_shinfo(skb)->frag_list; list; list = list->next) {
-		len = sctp_skb_pull(list, len);
-		if (!len)
+		rlen = sctp_skb_pull(list, len);
+		skb->len -= (len-rlen);
+		skb->data_len -= (len-rlen);
+
+		if (!rlen)
 			return 0;
+
+		len = rlen;
 	}
 
 	return len;
@@ -1130,7 +1112,7 @@
 {
 	sctp_ulpevent_t *event = NULL;
 	sctp_opt_t *sp = sctp_sk(sk);
-	struct sk_buff *skb, *list;
+	struct sk_buff *skb;
 	int copied;
 	int err = 0;
 	int skb_len;
@@ -1152,10 +1134,8 @@
 
 	/* Get the total length of the skb including any skb's in the
 	 * frag_list.
-	 */ 
+	 */
 	skb_len = skb->len;
-	for (list = skb_shinfo(skb)->frag_list; list; list = list->next)
-		skb_len += list->len;
 
 	copied = skb_len;
 	if (copied > len)
@@ -1190,14 +1170,20 @@
 	/* If skb's length exceeds the user's buffer, update the skb and
 	 * push it back to the receive_queue so that the next call to
 	 * recvmsg() will return the remaining data. Don't set MSG_EOR.
-	 * Otherwise, set MSG_EOR indicating the end of a message. 
+	 * Otherwise, set MSG_EOR indicating the end of a message.
 	 */
 	if (skb_len > copied) {
 		msg->msg_flags &= ~MSG_EOR;
 		if (flags & MSG_PEEK)
-			goto out_free;	
+			goto out_free;
 		sctp_skb_pull(skb, copied);
 		skb_queue_head(&sk->receive_queue, skb);
+		/* When only partial message is copied to the user, increase
+		 * rwnd by that amount. If all the data in the skb is read,
+		 * rwnd is updated when the skb's destructor is called via
+		 * sctp_ulpevent_free().
+		 */
+		sctp_assoc_rwnd_increase(event->asoc, copied);
 		goto out;
 	} else {
 		 msg->msg_flags |= MSG_EOR;
@@ -1260,7 +1246,7 @@
 	struct sctp_paddrparams params;
 	sctp_association_t *asoc;
 	union sctp_addr *addr;
-	sctp_transport_t *trans;
+	struct sctp_transport *trans;
 	int error;
 
 	if (optlen != sizeof(struct sctp_paddrparams))
@@ -1449,7 +1435,7 @@
 	sctp_opt_t *sp;
 	sctp_endpoint_t *ep;
 	sctp_association_t *asoc;
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 	union sctp_addr to;
 	sctp_scope_t scope;
 	long timeo;
@@ -1463,7 +1449,7 @@
 	sp = sctp_sk(sk);
 	ep = sp->ep;
 
-	/* connect() cannot be done on a peeled-off socket. */ 
+	/* connect() cannot be done on a peeled-off socket. */
 	if (SCTP_SOCKET_UDP_HIGH_BANDWIDTH == sp->type) {
 		err = -EISCONN;
 		goto out_unlock;
@@ -1471,7 +1457,7 @@
 
 	err = sctp_verify_addr(sk, (union sctp_addr *)uaddr, addr_len);
 	if (err)
-		goto out_unlock;	
+		goto out_unlock;
 
 	memcpy(&to, uaddr, addr_len);
 	to.v4.sin_port = ntohs(to.v4.sin_port);
@@ -1479,7 +1465,7 @@
 	asoc = sctp_endpoint_lookup_assoc(ep, &to, &transport);
 	if (asoc) {
 		if (asoc->state >= SCTP_STATE_ESTABLISHED)
-			err = -EISCONN;	
+			err = -EISCONN;
 		else
 			err = -EALREADY;
 		goto out_unlock;
@@ -1514,10 +1500,19 @@
 
 	/* Prime the peer's transport structures.  */
 	transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL);
+	if (!transport) {
+		sctp_association_free(asoc);
+		goto out_unlock;
+	}
+	err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL);
+	if (err < 0) {
+		sctp_association_free(asoc);
+		goto out_unlock;
+	}
 
 	err = sctp_primitive_ASSOCIATE(asoc, NULL);
 	if (err < 0) {
-		sctp_association_free(asoc); 
+		sctp_association_free(asoc);
 		goto out_unlock;
 	}
 
@@ -1666,7 +1661,7 @@
 	struct sctp_status status;
 	sctp_endpoint_t *ep;
 	sctp_association_t *assoc = NULL;
-	sctp_transport_t *transport;
+	struct sctp_transport *transport;
 	sctp_assoc_t associd;
 	int retval = 0;
 
@@ -1885,7 +1880,7 @@
 	struct sctp_paddrparams params;
 	sctp_association_t *asoc;
 	union sctp_addr *addr;
-	sctp_transport_t *trans;
+	struct sctp_transport *trans;
 
 	if (len != sizeof(struct sctp_paddrparams))
 		return -EINVAL;
@@ -1915,7 +1910,7 @@
 	 * before this address shall be considered unreachable.
 	 */
 	params.spp_pathmaxrxt = trans->error_threshold;
-	
+
 	if (copy_to_user(optval, &params, len))
 		return -EFAULT;
 	*optlen = len;
@@ -1932,6 +1927,166 @@
 	return 0;
 }
 
+static inline int sctp_getsockopt_get_peer_addrs_num(struct sock *sk, int len,
+				char *optval, int *optlen)
+{
+	sctp_assoc_t id;
+	sctp_association_t *asoc;
+	struct list_head *pos;
+	int cnt = 0;
+
+	if (len != sizeof(sctp_assoc_t))
+		return -EINVAL;
+
+	if (copy_from_user(&id, optval, sizeof(sctp_assoc_t)))
+		return -EFAULT;
+
+	/*
+	 *  For UDP-style sockets, id specifies the association to query.
+	 */
+	asoc = sctp_id2assoc(sk, id);
+	if (!asoc)
+		return -EINVAL;
+
+	list_for_each(pos, &asoc->peer.transport_addr_list) {
+		cnt ++;
+	}
+	if (copy_to_user(optval, &cnt, sizeof(int)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static inline int sctp_getsockopt_get_peer_addrs(struct sock *sk, int len,
+				char *optval, int *optlen)
+{
+	sctp_association_t *asoc;
+	struct list_head *pos;
+	int cnt = 0;
+	struct sctp_getaddrs getaddrs;
+	struct sctp_transport *from;
+	struct sockaddr_storage *to;
+
+	if (len != sizeof(struct sctp_getaddrs))
+		return -EINVAL;
+
+	if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs)))
+		return -EFAULT;
+
+	if (getaddrs.addr_num <= 0) return -EINVAL;
+	/*
+	 *  For UDP-style sockets, id specifies the association to query.
+	 */
+	asoc = sctp_id2assoc(sk, getaddrs.assoc_id);
+	if (!asoc)
+		return -EINVAL;
+
+	to = getaddrs.addrs;
+	list_for_each(pos, &asoc->peer.transport_addr_list) {
+		from = list_entry(pos, struct sctp_transport, transports);
+		if (copy_to_user(to, &from->ipaddr, sizeof(from->ipaddr)))
+			return -EFAULT;
+		to ++;
+		cnt ++;
+		if (cnt >= getaddrs.addr_num) break;
+	}
+	getaddrs.addr_num = cnt;
+	if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static inline int sctp_getsockopt_get_local_addrs_num(struct sock *sk, int len,
+				char *optval, int *optlen)
+{
+	sctp_assoc_t id;
+	sctp_bind_addr_t *bp;
+	sctp_association_t *asoc;
+	struct list_head *pos;
+	int cnt = 0;
+
+	if (len != sizeof(sctp_assoc_t))
+		return -EINVAL;
+
+	if (copy_from_user(&id, optval, sizeof(sctp_assoc_t)))
+		return -EFAULT;
+
+	/*
+	 *  For UDP-style sockets, id specifies the association to query.
+	 *  If the id field is set to the value '0' then the locally bound
+	 *  addresses are returned without regard to any particular
+	 *  association.
+	 */
+	if (0 == id) {
+		bp = &sctp_sk(sk)->ep->base.bind_addr;
+	} else {
+		asoc = sctp_id2assoc(sk, id);
+		if (!asoc)
+			return -EINVAL;
+		bp = &asoc->base.bind_addr;
+	}
+
+	list_for_each(pos, &bp->address_list) {
+		cnt ++;
+	}
+	if (copy_to_user(optval, &cnt, sizeof(int)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static inline int sctp_getsockopt_get_local_addrs(struct sock *sk, int len,
+				char *optval, int *optlen)
+{
+	sctp_bind_addr_t *bp;
+	sctp_association_t *asoc;
+	struct list_head *pos;
+	int cnt = 0;
+	struct sctp_getaddrs getaddrs;
+	struct sockaddr_storage_list *from;
+	struct sockaddr_storage *to;
+
+	if (len != sizeof(struct sctp_getaddrs))
+		return -EINVAL;
+
+	if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs)))
+		return -EFAULT;
+
+	if (getaddrs.addr_num <= 0) return -EINVAL;
+	/*
+	 *  For UDP-style sockets, id specifies the association to query.
+	 *  If the id field is set to the value '0' then the locally bound
+	 *  addresses are returned without regard to any particular
+	 *  association.
+	 */
+	if (0 == getaddrs.assoc_id) {
+		bp = &sctp_sk(sk)->ep->base.bind_addr;
+	} else {
+		asoc = sctp_id2assoc(sk, getaddrs.assoc_id);
+		if (!asoc)
+			return -EINVAL;
+		bp = &asoc->base.bind_addr;
+	}
+
+	to = getaddrs.addrs;
+	list_for_each(pos, &bp->address_list) {
+		from = list_entry(pos,
+				struct sockaddr_storage_list,
+				list);
+		if (copy_to_user(to, &from->a, sizeof(from->a)))
+			return -EFAULT;
+		to ++;
+		cnt ++;
+		if (cnt >= getaddrs.addr_num) break;
+	}
+	getaddrs.addr_num = cnt;
+	if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs)))
+		return -EFAULT;
+
+	return 0;
+}
+
 SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
 				char *optval, int *optlen)
 {
@@ -1989,6 +2144,26 @@
 		retval = sctp_getsockopt_initmsg(sk, len, optval, optlen);
 		break;
 
+	case SCTP_GET_PEER_ADDRS_NUM:
+		retval = sctp_getsockopt_get_peer_addrs_num(sk, len, optval,
+							      optlen);
+		break;
+
+	case SCTP_GET_LOCAL_ADDRS_NUM:
+		retval = sctp_getsockopt_get_local_addrs_num(sk, len, optval,
+							      optlen);
+		break;
+
+	case SCTP_GET_PEER_ADDRS:
+		retval = sctp_getsockopt_get_peer_addrs(sk, len, optval,
+							      optlen);
+		break;
+
+	case SCTP_GET_LOCAL_ADDRS:
+		retval = sctp_getsockopt_get_local_addrs(sk, len, optval,
+							      optlen);
+		break;
+
 	default:
 		retval = -ENOPROTOOPT;
 		break;
@@ -2029,7 +2204,7 @@
 	sctp_protocol_t *sctp = sctp_get_protocol();
 	unsigned short snum;
 	int ret;
-	
+
 	/* NOTE:  Remember to put this back to net order. */
 	addr->v4.sin_port = ntohs(addr->v4.sin_port);
 	snum = addr->v4.sin_port;
@@ -2098,7 +2273,7 @@
 		}
 	}
 
-	
+
 	if (pp != NULL && pp->sk != NULL) {
 		/* We had a port hash table hit - there is an
 		 * available port (pp != NULL) and it is being
@@ -2129,7 +2304,7 @@
 
 			if (sk_reuse && sk2->reuse)
 				continue;
-			
+
 			if (sctp_bind_addr_match(&ep2->base.bind_addr, addr,
 						 sctp_sk(sk)))
 				goto found;
@@ -2187,7 +2362,7 @@
 }
 
 /* Assign a 'snum' port to the socket.  If snum == 0, an ephemeral
- * port is requested.  
+ * port is requested.
  */
 static int sctp_get_port(struct sock *sk, unsigned short snum)
 {
@@ -2657,10 +2832,10 @@
 		return -EINVAL;
 
 	/* Is this a valid SCTP address?  */
-	if (!af->addr_valid((union sctp_addr *)addr)) 
+	if (!af->addr_valid((union sctp_addr *)addr))
 		return -EINVAL;
 
-	return 0;	
+	return 0;
 }
 
 /* Get the sndbuf space available at the time on the association.  */
diff -Nru a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sctp/ssnmap.c	Fri Feb 14 15:53:13 2003
@@ -0,0 +1,113 @@
+/* SCTP kernel reference Implementation
+ * Copyright (c) 2003 International Business Machines, Corp.
+ *
+ * This file is part of the SCTP kernel reference Implementation
+ *
+ * These functions manipulate sctp SSN tracker.
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP reference implementation is distributed in the hope that it
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ *                 ************************
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ *    Jon Grimm             <jgrimm@us.ibm.com>
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+
+#include <linux/types.h>
+#include <net/sctp/sctp.h>
+#include <net/sctp/sm.h>
+
+
+/* Storage size needed for map includes 2 headers and then the
+ * specific needs of in or out streams.
+ */
+static inline size_t sctp_ssnmap_size(__u16 in, __u16 out)
+{
+	return sizeof(struct sctp_ssnmap) + (in + out) * sizeof(__u16);
+}
+
+
+/* Create a new sctp_ssnmap.
+ * Allocate room to store at least 'len' contiguous TSNs.
+ */
+struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, int priority)
+{
+	struct sctp_ssnmap *retval;
+
+	retval = kmalloc(sctp_ssnmap_size(in, out), priority);
+
+	if (!retval)
+		goto fail;
+
+	if (!sctp_ssnmap_init(retval, in, out))
+		goto fail_map;
+
+	retval->malloced = 1;
+	SCTP_DBG_OBJCNT_INC(ssnmap);
+
+	return retval;
+
+fail_map:
+	kfree(retval);
+fail:
+	return NULL;
+}
+
+
+/* Initialize a block of memory as a ssnmap.  */
+struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
+				     __u16 out)
+{
+	memset(map, 0x00, sctp_ssnmap_size(in, out));
+
+	/* Start 'in' stream just after the map header. */
+	map->in.ssn = (__u16 *)&map[1];
+	map->in.len = in;
+
+	/* Start 'out' stream just after 'in'. */
+	map->out.ssn = &map->in.ssn[in];
+	map->out.len = out;
+
+	return map;
+}
+
+/* Clear out the ssnmap streams.  */
+void sctp_ssnmap_clear(struct sctp_ssnmap *map)
+{
+	size_t size;
+
+	size = (map->in.len + map->out.len) * sizeof(__u16);
+	memset(map->in.ssn, 0x00, size);
+}
+
+/* Dispose of a ssnmap.  */
+void sctp_ssnmap_free(struct sctp_ssnmap *map)
+{
+	if (map && map->malloced) {
+		kfree(map);
+		SCTP_DBG_OBJCNT_DEC(ssnmap);
+	}
+}
diff -Nru a/net/sctp/sysctl.c b/net/sctp/sysctl.c
--- a/net/sctp/sysctl.c	Fri Feb 14 15:53:09 2003
+++ b/net/sctp/sysctl.c	Fri Feb 14 15:53:09 2003
@@ -45,53 +45,131 @@
 extern sctp_protocol_t sctp_proto;
 
 static ctl_table sctp_table[] = {
-	{ NET_SCTP_RTO_INITIAL, "rto_initial",
-	  &sctp_proto.rto_initial, sizeof(int), 0644, NULL,
-	  &proc_dointvec_jiffies, &sysctl_jiffies },
-	{ NET_SCTP_RTO_MIN, "rto_min",
-	  &sctp_proto.rto_min, sizeof(int), 0644, NULL,
-	  &proc_dointvec_jiffies, &sysctl_jiffies },
-	{ NET_SCTP_RTO_MAX, "rto_max",
-	  &sctp_proto.rto_max, sizeof(int), 0644, NULL,
-	  &proc_dointvec_jiffies, &sysctl_jiffies },
-	{ NET_SCTP_VALID_COOKIE_LIFE, "valid_cookie_life",
-	  &sctp_proto.valid_cookie_life, sizeof(int), 0644, NULL,
-	  &proc_dointvec_jiffies, &sysctl_jiffies },
-	{ NET_SCTP_MAX_BURST, "max_burst",
-	  &sctp_proto.max_burst, sizeof(int), 0644, NULL,
-	  &proc_dointvec },
-	{ NET_SCTP_ASSOCIATION_MAX_RETRANS, "association_max_retrans",
-	  &sctp_proto.max_retrans_association, sizeof(int), 0644, NULL,
-	  &proc_dointvec },
-	{ NET_SCTP_PATH_MAX_RETRANS, "path_max_retrans",
-	  &sctp_proto.max_retrans_path, sizeof(int), 0644, NULL,
-	  &proc_dointvec },
-	{ NET_SCTP_MAX_INIT_RETRANSMITS, "max_init_retransmits",
-	  &sctp_proto.max_retrans_init, sizeof(int), 0644, NULL,
-	  &proc_dointvec },
-	{ NET_SCTP_HB_INTERVAL, "hb_interval",
-	  &sctp_proto.hb_interval, sizeof(int), 0644, NULL,
-	  &proc_dointvec_jiffies, &sysctl_jiffies },
-	{ NET_SCTP_PRESERVE_ENABLE, "cookie_preserve_enable",
-	  &sctp_proto.cookie_preserve_enable, sizeof(int), 0644, NULL,
-	  &proc_dointvec_jiffies, &sysctl_jiffies },
-	{ NET_SCTP_RTO_ALPHA, "rto_alpha_exp_divisor",
-	  &sctp_proto.rto_alpha, sizeof(int), 0644, NULL,
-	  &proc_dointvec },
-	{ NET_SCTP_RTO_BETA, "rto_beta_exp_divisor",
-	  &sctp_proto.rto_beta, sizeof(int), 0644, NULL,
-	  &proc_dointvec },
-	{ 0 }
+	{
+		.ctl_name	= NET_SCTP_RTO_INITIAL,
+		.procname	= "rto_initial",
+		.data		= &sctp_proto.rto_initial,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
+	{
+		.ctl_name	= NET_SCTP_RTO_MIN,
+		.procname	= "rto_min",
+		.data		= &sctp_proto.rto_min,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
+	{
+		.ctl_name	= NET_SCTP_RTO_MAX,
+		.procname	= "rto_max",
+		.data		= &sctp_proto.rto_max,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
+	{
+		.ctl_name	= NET_SCTP_VALID_COOKIE_LIFE,
+		.procname	= "valid_cookie_life",
+		.data		= &sctp_proto.valid_cookie_life,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
+	{
+		.ctl_name	= NET_SCTP_MAX_BURST,
+		.procname	= "max_burst",
+		.data		= &sctp_proto.max_burst,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_SCTP_ASSOCIATION_MAX_RETRANS,
+		.procname	= "association_max_retrans",
+		.data		= &sctp_proto.max_retrans_association,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_SCTP_PATH_MAX_RETRANS,
+		.procname	= "path_max_retrans",
+		.data		= &sctp_proto.max_retrans_path,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_SCTP_MAX_INIT_RETRANSMITS,
+		.procname	= "max_init_retransmits",
+		.data		= &sctp_proto.max_retrans_init,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_SCTP_HB_INTERVAL,
+		.procname	= "hb_interval",
+		.data		= &sctp_proto.hb_interval,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
+	{
+		.ctl_name	= NET_SCTP_PRESERVE_ENABLE,
+		.procname	= "cookie_preserve_enable",
+		.data		= &sctp_proto.cookie_preserve_enable,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+		.strategy	= &sysctl_jiffies
+	},
+	{
+		.ctl_name	= NET_SCTP_RTO_ALPHA,
+		.procname	= "rto_alpha_exp_divisor",
+		.data		= &sctp_proto.rto_alpha,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.ctl_name	= NET_SCTP_RTO_BETA,
+		.procname	= "rto_beta_exp_divisor",
+		.data		= &sctp_proto.rto_beta,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{ .ctl_name = 0 }
 };
 
 static ctl_table sctp_net_table[] = {
-	{ NET_SCTP, "sctp", NULL, 0, 0555, sctp_table },
-	{ 0 }
+	{
+		.ctl_name	= NET_SCTP,
+		.procname	= "sctp",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= sctp_table
+	},
+	{ .ctl_name = 0 }
 };
 
 static ctl_table sctp_root_table[] = {
-	{ CTL_NET, "net", NULL, 0, 0555, sctp_net_table },
-	{ 0 }
+	{
+		.ctl_name	= CTL_NET,
+		.procname	= "net",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= sctp_net_table
+	},
+	{ .ctl_name = 0 }
 };
 
 static struct ctl_table_header * sctp_sysctl_header;
diff -Nru a/net/sctp/transport.c b/net/sctp/transport.c
--- a/net/sctp/transport.c	Fri Feb 14 15:53:09 2003
+++ b/net/sctp/transport.c	Fri Feb 14 15:53:09 2003
@@ -1,7 +1,7 @@
 /* SCTP kernel reference Implementation
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001 International Business Machines Corp.
+ * Copyright (c) 2001-2003 International Business Machines Corp.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 La Monte H.P. Yarroll
  *
@@ -42,6 +42,7 @@
  *    Xingang Guo           <xingang.guo@intel.com>
  *    Hui Huang             <hui.huang@nokia.com>
  *    Sridhar Samudrala	    <sri@us.ibm.com>
+ *    Ardelle Fan	    <ardelle.fan@intel.com>
  *
  * Any bugs reported given to us we will try to fix... any fixes shared will
  * be incorporated into the next SCTP release.
@@ -53,11 +54,12 @@
 /* 1st Level Abstractions.  */
 
 /* Allocate and initialize a new transport.  */
-sctp_transport_t *sctp_transport_new(const union sctp_addr *addr, int priority)
+struct sctp_transport *sctp_transport_new(const union sctp_addr *addr,
+					  int priority)
 {
-        sctp_transport_t *transport;
+        struct sctp_transport *transport;
 
-        transport = t_new(sctp_transport_t, priority);
+        transport = t_new(struct sctp_transport, priority);
 	if (!transport)
 		goto fail;
 
@@ -77,9 +79,9 @@
 }
 
 /* Intialize a new transport from provided memory.  */
-sctp_transport_t *sctp_transport_init(sctp_transport_t *peer,
-				      const union sctp_addr *addr,
-				      int priority)
+struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
+					   const union sctp_addr *addr,
+					   int priority)
 {
 	sctp_protocol_t *proto = sctp_get_protocol();
 
@@ -88,6 +90,9 @@
 	peer->af_specific = sctp_get_af_specific(addr->sa.sa_family);
 	peer->asoc = NULL;
 
+	peer->dst = NULL;
+	memset(&peer->saddr, 0, sizeof(union sctp_addr));
+
 	/* From 6.3.1 RTO Calculation:
 	 *
 	 * C1) Until an RTT measurement has been made for a packet sent to the
@@ -139,7 +144,7 @@
 /* This transport is no longer needed.  Free up if possible, or
  * delay until it last reference count.
  */
-void sctp_transport_free(sctp_transport_t *transport)
+void sctp_transport_free(struct sctp_transport *transport)
 {
 	transport->dead = 1;
 
@@ -153,7 +158,7 @@
 /* Destroy the transport data structure.
  * Assumes there are no more users of this structure.
  */
-void sctp_transport_destroy(sctp_transport_t *transport)
+void sctp_transport_destroy(struct sctp_transport *transport)
 {
 	SCTP_ASSERT(transport->dead, "Transport is not dead", return);
 
@@ -168,7 +173,7 @@
 /* Start T3_rtx timer if it is not already running and update the heartbeat
  * timer.  This routine is called everytime a DATA chunk is sent.
  */
-void sctp_transport_reset_timers(sctp_transport_t *transport)
+void sctp_transport_reset_timers(struct sctp_transport *transport)
 {
 	/* RFC 2960 6.3.2 Retransmission Timer Rules
 	 *
@@ -177,96 +182,61 @@
 	 * start it running so that it will expire after the RTO of that
 	 * address.
 	 */
-	if (!timer_pending(&transport->T3_rtx_timer)) {
+
+	if (!timer_pending(&transport->T3_rtx_timer))
 		if (!mod_timer(&transport->T3_rtx_timer,
 			       jiffies + transport->rto))
 			sctp_transport_hold(transport);
-	}
 
 	/* When a data chunk is sent, reset the heartbeat interval.  */
 	if (!mod_timer(&transport->hb_timer,
-		       transport->hb_interval + transport->rto + jiffies))
-		sctp_transport_hold(transport);
+		       sctp_transport_timeout(transport)))
+	    sctp_transport_hold(transport);
 }
 
 /* This transport has been assigned to an association.
  * Initialize fields from the association or from the sock itself.
  * Register the reference count in the association.
  */
-void sctp_transport_set_owner(sctp_transport_t *transport,
+void sctp_transport_set_owner(struct sctp_transport *transport,
 			      sctp_association_t *asoc)
 {
 	transport->asoc = asoc;
 	sctp_association_hold(asoc);
 }
 
-/* Caches the dst entry for a transport's destination address and an optional
- * souce address.
- */ 
-void sctp_transport_route(sctp_transport_t *transport, union sctp_addr *saddr,
-			  struct sctp_opt *opt)
+/* Initialize the pmtu of a transport. */ 
+void sctp_transport_pmtu(struct sctp_transport *transport)
 {
-	sctp_association_t *asoc = transport->asoc;
-	struct sctp_af *af = transport->af_specific;
-	union sctp_addr *daddr = &transport->ipaddr;
-	sctp_bind_addr_t *bp;
-	rwlock_t *addr_lock;
-	struct sockaddr_storage_list *laddr;
-	struct list_head *pos;
 	struct dst_entry *dst;
-	union sctp_addr dst_saddr;
-
-	dst = af->get_dst(daddr, saddr);
-
-	/* If there is no association or if a source address is passed,
-	 * no more validation is required.
-	 */
-	if (!asoc || saddr)
-		goto out;
 
-	if (SCTP_STATE_ESTABLISHED == asoc->state) {
-		bp = &asoc->base.bind_addr;
-		addr_lock = &asoc->base.addr_lock;
-	} else {
-		bp = &asoc->ep->base.bind_addr;
-		addr_lock = &asoc->ep->base.addr_lock;
-	}
+	dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL);
 
 	if (dst) {
-		/* Walk through the bind address list and look for a bind
-		 * address that matches the source address of the returned dst.
-		 */
-		sctp_read_lock(addr_lock);
-		list_for_each(pos, &bp->address_list) {
-			laddr = list_entry(pos, struct sockaddr_storage_list,
-					   list);
-			af->dst_saddr(&dst_saddr, dst);
-	                if (opt->pf->cmp_addr(&dst_saddr, &laddr->a, opt))
-				goto out_unlock;
-		}
-		sctp_read_unlock(addr_lock);
-	
-		/* None of the bound addresses match the source address of the
-		 * dst. So release it.
-		 */	
+		transport->pmtu = dst_pmtu(dst);
 		dst_release(dst);
-	}
+	} else
+		transport->pmtu = SCTP_DEFAULT_MAXSEGMENT;
+}
 
-	/* Walk through the bind address list and try to get a dst that
-	 * matches a bind address as the source address.
-	 */
-	sctp_read_lock(addr_lock);
-	list_for_each(pos, &bp->address_list) {
-		laddr = list_entry(pos, struct sockaddr_storage_list, list);
-
-		dst = af->get_dst(daddr, &laddr->a);
-		if (dst)
-			goto out_unlock;
-	}
+/* Caches the dst entry and source address for a transport's destination
+ * address.
+ */
+void sctp_transport_route(struct sctp_transport *transport,
+			  union sctp_addr *saddr, struct sctp_opt *opt)
+{
+	sctp_association_t *asoc = transport->asoc;
+	struct sctp_af *af = transport->af_specific;
+	union sctp_addr *daddr = &transport->ipaddr;
+	struct dst_entry *dst;
+
+	dst = af->get_dst(asoc, daddr, saddr);
+
+	if (saddr)
+		memcpy(&transport->saddr, saddr, sizeof(union sctp_addr));
+	else
+		af->get_saddr(asoc, dst, daddr, &transport->saddr);
 
-out_unlock:
-	sctp_read_unlock(addr_lock);
-out:
 	transport->dst = dst;
 	if (dst)
 		transport->pmtu = dst_pmtu(dst);
@@ -275,7 +245,7 @@
 }
 
 /* Hold a reference to a transport.  */
-void sctp_transport_hold(sctp_transport_t *transport)
+void sctp_transport_hold(struct sctp_transport *transport)
 {
 	atomic_inc(&transport->refcnt);
 }
@@ -283,14 +253,14 @@
 /* Release a reference to a transport and clean up
  * if there are no more references.
  */
-void sctp_transport_put(sctp_transport_t *transport)
+void sctp_transport_put(struct sctp_transport *transport)
 {
 	if (atomic_dec_and_test(&transport->refcnt))
 		sctp_transport_destroy(transport);
 }
 
 /* Update transport's RTO based on the newly calculated RTT. */
-void sctp_transport_update_rto(sctp_transport_t *tp, __u32 rtt)
+void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
 {
 	sctp_protocol_t *proto = sctp_get_protocol();
 
@@ -330,7 +300,7 @@
 	if (tp->rttvar == 0)
 		tp->rttvar = SCTP_CLOCK_GRANULARITY;
 
-	/* 6.3.1 C3) After the computation, update RTO <- SRTT + 4 * RTTVAR.  */
+	/* 6.3.1 C3) After the computation, update RTO <- SRTT + 4 * RTTVAR. */
 	tp->rto = tp->srtt + (tp->rttvar << 2);
 
 	/* 6.3.1 C6) Whenever RTO is computed, if it is less than RTO.Min
@@ -360,8 +330,8 @@
 /* This routine updates the transport's cwnd and partial_bytes_acked
  * parameters based on the bytes acked in the received SACK.
  */
-void sctp_transport_raise_cwnd(sctp_transport_t *transport, __u32 sack_ctsn,
-			       __u32 bytes_acked)
+void sctp_transport_raise_cwnd(struct sctp_transport *transport,
+			       __u32 sack_ctsn, __u32 bytes_acked)
 {
 	__u32 cwnd, ssthresh, flight_size, pba, pmtu;
 
@@ -389,8 +359,8 @@
 		 * two conditions are met can the cwnd be increased otherwise
 		 * the cwnd MUST not be increased. If these conditions are met
 		 * then cwnd MUST be increased by at most the lesser of
-		 * 1) the total size of the previously outstanding DATA chunk(s)
-		 * acknowledged, and 2) the destination's path MTU.
+		 * 1) the total size of the previously outstanding DATA 
+		 * chunk(s) acknowledged, and 2) the destination's path MTU.
 		 */
 		if (bytes_acked > pmtu)
 			cwnd += pmtu;
@@ -403,18 +373,18 @@
 				  transport, bytes_acked, cwnd,
 				  ssthresh, flight_size, pba);
 	} else {
-		/* RFC 2960 7.2.2 Whenever cwnd is greater than ssthresh, upon
-		 * each SACK arrival that advances the Cumulative TSN Ack Point,
-		 * increase partial_bytes_acked by the total number of bytes of
-		 * all new chunks acknowledged in that SACK including chunks
-		 * acknowledged by the new Cumulative TSN Ack and by Gap Ack
-		 * Blocks.
+		/* RFC 2960 7.2.2 Whenever cwnd is greater than ssthresh, 
+		 * upon each SACK arrival that advances the Cumulative TSN Ack 
+		 * Point, increase partial_bytes_acked by the total number of 
+		 * bytes of all new chunks acknowledged in that SACK including 
+		 * chunks acknowledged by the new Cumulative TSN Ack and by 
+		 * Gap Ack Blocks.
 		 *
-		 * When partial_bytes_acked is equal to or greater than cwnd and
-		 * before the arrival of the SACK the sender had cwnd or more
-		 * bytes of data outstanding (i.e., before arrival of the SACK,
-		 * flightsize was greater than or equal to cwnd), increase cwnd
-		 * by MTU, and reset partial_bytes_acked to
+		 * When partial_bytes_acked is equal to or greater than cwnd 
+		 * and before the arrival of the SACK the sender had cwnd or 
+		 * more bytes of data outstanding (i.e., before arrival of the 
+		 * SACK, flightsize was greater than or equal to cwnd), 
+		 * increase cwnd by MTU, and reset partial_bytes_acked to
 		 * (partial_bytes_acked - cwnd).
 		 */
 		pba += bytes_acked;
@@ -437,7 +407,7 @@
 /* This routine is used to lower the transport's cwnd when congestion is
  * detected.
  */
-void sctp_transport_lower_cwnd(sctp_transport_t *transport,
+void sctp_transport_lower_cwnd(struct sctp_transport *transport,
 			       sctp_lower_cwnd_t reason)
 {
 	switch (reason) {
@@ -513,4 +483,13 @@
 			  "%d ssthresh: %d\n", __FUNCTION__,
 			  transport, reason,
 			  transport->cwnd, transport->ssthresh);
+}
+
+/* What is the next timeout value for this transport? */
+unsigned long sctp_transport_timeout(struct sctp_transport *t)
+{
+	unsigned long timeout;
+	timeout = t->hb_interval + t->rto + sctp_jitter(t->rto);
+	timeout += jiffies;
+	return timeout;
 }
diff -Nru a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
--- a/net/sctp/ulpevent.c	Fri Feb 14 15:53:09 2003
+++ b/net/sctp/ulpevent.c	Fri Feb 14 15:53:09 2003
@@ -606,9 +606,9 @@
 sctp_ulpevent_t *sctp_ulpevent_make_rcvmsg(sctp_association_t *asoc,
 					   sctp_chunk_t *chunk, int priority)
 {
-	sctp_ulpevent_t *event;
+	sctp_ulpevent_t *event, *levent;
 	struct sctp_sndrcvinfo *info;
-	struct sk_buff *skb;
+	struct sk_buff *skb, *list;
 	size_t padding, len;
 
 	/* Clone the original skb, sharing the data.  */
@@ -647,6 +647,16 @@
 
 	event->malloced = 1;
 
+	for (list = skb_shinfo(skb)->frag_list; list; list = list->next) {
+		sctp_ulpevent_set_owner_r(list, asoc);
+		/* Initialize event with flags 0.  */
+		levent = sctp_ulpevent_init(event, skb, 0);
+		if (!levent)
+			goto fail_init;
+
+		levent->malloced = 1;
+	}
+
 	info = (struct sctp_sndrcvinfo *) &event->sndrcvinfo;
 
 	/* Sockets API Extensions for SCTP
@@ -762,8 +772,6 @@
 {
 	sctp_association_t *asoc;
 	sctp_ulpevent_t *event;
-	sctp_chunk_t *sack;
-	struct timer_list *timer;
 
 	/* Current stack structures assume that the rcv buffer is
 	 * per socket.   For UDP style sockets this is not true as
@@ -773,50 +781,7 @@
 	 */
 	event = (sctp_ulpevent_t *) skb->cb;
 	asoc = event->asoc;
-	if (asoc->rwnd_over) {
-		if (asoc->rwnd_over >= skb->len) {
-			asoc->rwnd_over -= skb->len;
-		} else {
-			asoc->rwnd += (skb->len - asoc->rwnd_over);
-			asoc->rwnd_over = 0;
-		}
-	} else {
-		asoc->rwnd += skb->len;
-	}
-
-	SCTP_DEBUG_PRINTK("rwnd increased by %d to (%u, %u) - %u\n",
-			  skb->len, asoc->rwnd, asoc->rwnd_over, asoc->a_rwnd);
-
-	/* Send a window update SACK if the rwnd has increased by at least the
-	 * minimum of the association's PMTU and half of the receive buffer.
-	 * The algorithm used is similar to the one described in Section 4.2.3.3
-	 * of RFC 1122.
-	 */
-	if ((asoc->state == SCTP_STATE_ESTABLISHED) &&
-	    (asoc->rwnd > asoc->a_rwnd) &&
-	    ((asoc->rwnd - asoc->a_rwnd) >=
-		     min_t(__u32, (asoc->base.sk->rcvbuf >> 1), asoc->pmtu))) {
-		SCTP_DEBUG_PRINTK("Sending window update SACK- rwnd: %u "
-				  "a_rwnd: %u\n", asoc->rwnd, asoc->a_rwnd);
-		sack = sctp_make_sack(asoc); 
-		if (!sack)
-			goto out;
-
-		/* Update the last advertised rwnd value. */
-		asoc->a_rwnd = asoc->rwnd;
-
-		asoc->peer.sack_needed = 0;
-		asoc->peer.next_dup_tsn = 0;
-
-		sctp_push_outqueue(&asoc->outqueue, sack);
-
-		/* Stop the SACK timer.  */
-		timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK];
-		if (timer_pending(timer) && del_timer(timer))
-			sctp_association_put(asoc);
-	} 
-
-out:
+	sctp_assoc_rwnd_increase(asoc, skb_headlen(skb));
 	sctp_association_put(asoc);
 }
 
@@ -838,16 +803,7 @@
 
 	skb->destructor = sctp_rcvmsg_rfree;
 
-	SCTP_ASSERT(asoc->rwnd, "rwnd zero", return);
-	SCTP_ASSERT(!asoc->rwnd_over, "rwnd_over not zero", return);
-	if (asoc->rwnd >= skb->len) {
-		asoc->rwnd -= skb->len;
-	} else {
-		asoc->rwnd_over = skb->len - asoc->rwnd;
-		asoc->rwnd = 0;
-	}
-	SCTP_DEBUG_PRINTK("rwnd decreased by %d to (%u, %u)\n",
-			  skb->len, asoc->rwnd, asoc->rwnd_over);
+	sctp_assoc_rwnd_decrease(asoc, skb_headlen(skb));
 }
 
 /* A simple destructor to give up the reference to the association. */
diff -Nru a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
--- a/net/sctp/ulpqueue.c	Fri Feb 14 15:53:12 2003
+++ b/net/sctp/ulpqueue.c	Fri Feb 14 15:53:12 2003
@@ -1,7 +1,7 @@
 /* SCTP kernel reference Implementation
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2002 International Business Machines, Corp.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 Nokia, Inc.
  * Copyright (c) 2001 La Monte H.P. Yarroll
@@ -49,51 +49,39 @@
 #include <net/sctp/sm.h>
 
 /* Forward declarations for internal helpers.  */
-static inline sctp_ulpevent_t * sctp_ulpqueue_reasm(sctp_ulpqueue_t *ulpq,
-						    sctp_ulpevent_t *event);
-static inline sctp_ulpevent_t *sctp_ulpqueue_order(sctp_ulpqueue_t *ulpq,
-						   sctp_ulpevent_t *event);
+static inline struct sctp_ulpevent * sctp_ulpq_reasm(struct sctp_ulpq *ulpq,
+						     struct sctp_ulpevent *);
+static inline struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *,
+						    struct sctp_ulpevent *);
 
 /* 1st Level Abstractions */
 
 /* Create a new ULP queue.  */
-sctp_ulpqueue_t *sctp_ulpqueue_new(sctp_association_t *asoc,
-				   __u16 inbound, int priority)
+struct sctp_ulpq *sctp_ulpq_new(sctp_association_t *asoc, int priority)
 {
-	sctp_ulpqueue_t *ulpq;
-	size_t size;
+	struct sctp_ulpq *ulpq;
 
-	/* Today, there is only a fixed size of storage needed for
-	 * stream support, but make the interfaces acceptable for
-	 * the future.
-	 */
-	size = sizeof(sctp_ulpqueue_t)+sctp_ulpqueue_storage_size(inbound);
-	ulpq = kmalloc(size, priority);
+	ulpq = kmalloc(sizeof(struct sctp_ulpq), priority);
 	if (!ulpq)
 		goto fail;
-	if (!sctp_ulpqueue_init(ulpq, asoc, inbound))
+	if (!sctp_ulpq_init(ulpq, asoc))
 		goto fail_init;
 	ulpq->malloced = 1;
 	return ulpq;
 
 fail_init:
 	kfree(ulpq);
-
 fail:
 	return NULL;
 }
 
 /* Initialize a ULP queue from a block of memory.  */
-sctp_ulpqueue_t *sctp_ulpqueue_init(sctp_ulpqueue_t *ulpq,
-				    sctp_association_t *asoc,
-				    __u16 inbound)
-{
-	memset(ulpq,
-	       sizeof(sctp_ulpqueue_t) + sctp_ulpqueue_storage_size(inbound),
-	       0x00);
+struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *ulpq,
+				 sctp_association_t *asoc)
+{
+	memset(ulpq, sizeof(struct sctp_ulpq), 0x00);
 
 	ulpq->asoc = asoc;
-	spin_lock_init(&ulpq->lock);
 	skb_queue_head_init(&ulpq->reasm);
 	skb_queue_head_init(&ulpq->lobby);
 	ulpq->malloced = 0;
@@ -101,38 +89,39 @@
 	return ulpq;
 }
 
+
 /* Flush the reassembly and ordering queues.  */
-void sctp_ulpqueue_flush(sctp_ulpqueue_t *ulpq)
+void sctp_ulpq_flush(struct sctp_ulpq *ulpq)
 {
 	struct sk_buff *skb;
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 
 	while ((skb = skb_dequeue(&ulpq->lobby))) {
-		event = (sctp_ulpevent_t *) skb->cb;
+		event = (struct sctp_ulpevent *) skb->cb;
 		sctp_ulpevent_free(event);
 	}
 
 	while ((skb = skb_dequeue(&ulpq->reasm))) {
-		event = (sctp_ulpevent_t *) skb->cb;
+		event = (struct sctp_ulpevent *) skb->cb;
 		sctp_ulpevent_free(event);
 	}
 }
 
 /* Dispose of a ulpqueue.  */
-void sctp_ulpqueue_free(sctp_ulpqueue_t *ulpq)
+void sctp_ulpq_free(struct sctp_ulpq *ulpq)
 {
-	sctp_ulpqueue_flush(ulpq);
+	sctp_ulpq_flush(ulpq);
 	if (ulpq->malloced)
 		kfree(ulpq);
 }
 
 /* Process an incoming DATA chunk.  */
-int sctp_ulpqueue_tail_data(sctp_ulpqueue_t *ulpq, sctp_chunk_t *chunk,
+int sctp_ulpq_tail_data(struct sctp_ulpq *ulpq, sctp_chunk_t *chunk,
 			    int priority)
 {
 	struct sk_buff_head temp;
 	sctp_data_chunk_t *hdr;
-	sctp_ulpevent_t *event;
+	struct sctp_ulpevent *event;
 
 	hdr = (sctp_data_chunk_t *) chunk->chunk_hdr;
 
@@ -147,7 +136,7 @@
 		return -ENOMEM;
 
 	/* Do reassembly if needed.  */
-	event = sctp_ulpqueue_reasm(ulpq, event);
+	event = sctp_ulpq_reasm(ulpq, event);
 
 	/* Do ordering if needed.  */
 	if (event) {
@@ -155,18 +144,18 @@
 		skb_queue_head_init(&temp);
 		skb_queue_tail(&temp, event->parent);
 
-		event = sctp_ulpqueue_order(ulpq, event);
+		event = sctp_ulpq_order(ulpq, event);
 	}
 
 	/* Send event to the ULP.  */
 	if (event)
-		sctp_ulpqueue_tail_event(ulpq, event);
+		sctp_ulpq_tail_event(ulpq, event);
 
 	return 0;
 }
 
 /* Add a new event for propogation to the ULP.  */
-int sctp_ulpqueue_tail_event(sctp_ulpqueue_t *ulpq, sctp_ulpevent_t *event)
+int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event)
 {
 	struct sock *sk = ulpq->asoc->base.sk;
 
@@ -202,20 +191,18 @@
 /* 2nd Level Abstractions */
 
 /* Helper function to store chunks that need to be reassembled.  */
-static inline void sctp_ulpqueue_store_reasm(sctp_ulpqueue_t *ulpq, sctp_ulpevent_t *event)
+static inline void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq, 
+					 struct sctp_ulpevent *event)
 {
 	struct sk_buff *pos, *tmp;
-	sctp_ulpevent_t *cevent;
+	struct sctp_ulpevent *cevent;
 	__u32 tsn, ctsn;
-	unsigned long flags __attribute ((unused));
 
 	tsn = event->sndrcvinfo.sinfo_tsn;
 
-	sctp_spin_lock_irqsave(&ulpq->reasm.lock, flags);
-
 	/* Find the right place in this list. We store them by TSN.  */
 	sctp_skb_for_each(pos, &ulpq->reasm, tmp) {
-		cevent = (sctp_ulpevent_t *)pos->cb;
+		cevent = (struct sctp_ulpevent *)pos->cb;
 		ctsn = cevent->sndrcvinfo.sinfo_tsn;
 
 		if (TSN_lt(tsn, ctsn))
@@ -227,29 +214,45 @@
 		__skb_insert(event->parent, pos->prev, pos, &ulpq->reasm);
 	else
 		__skb_queue_tail(&ulpq->reasm, event->parent);
-
-	sctp_spin_unlock_irqrestore(&ulpq->reasm.lock, flags);
 }
 
 /* Helper function to return an event corresponding to the reassembled
  * datagram.
+ * This routine creates a re-assembled skb given the first and last skb's
+ * as stored in the reassembly queue. The skb's may be non-linear if the sctp
+ * payload was fragmented on the way and ip had to reassemble them.
+ * We add the rest of skb's to the first skb's fraglist.
  */
-static inline sctp_ulpevent_t *sctp_make_reassembled_event(struct sk_buff *f_frag, struct sk_buff *l_frag)
+static inline struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff *f_frag, struct sk_buff *l_frag)
 {
 	struct sk_buff *pos;
-	sctp_ulpevent_t *event;
-	struct sk_buff *pnext;
+	struct sctp_ulpevent *event;
+	struct sk_buff *pnext, *last;
+	struct sk_buff *list = skb_shinfo(f_frag)->frag_list;
 
+	/* Store the pointer to the 2nd skb */
 	pos = f_frag->next;
 
-	/* Set the first fragment's frag_list to point to the 2nd fragment.  */
-	skb_shinfo(f_frag)->frag_list = pos;
+	/* Get the last skb in the f_frag's frag_list if present. */
+	for (last = list; list; last = list, list = list->next);
+
+	/* Add the list of remaining fragments to the first fragments
+	 * frag_list.
+	 */
+	if (last)
+		last->next = pos;
+	else
+		skb_shinfo(f_frag)->frag_list = pos;
 
 	/* Remove the first fragment from the reassembly queue.  */
 	__skb_unlink(f_frag, f_frag->list);
 	do {
 		pnext = pos->next;
 
+		/* Update the len and data_len fields of the first fragment. */
+		f_frag->len += pos->len;
+		f_frag->data_len += pos->len;
+
 		/* Remove the fragment from the reassembly queue.  */
 		__skb_unlink(pos, pos->list);
 
@@ -269,13 +272,12 @@
 /* Helper function to check if an incoming chunk has filled up the last
  * missing fragment in a SCTP datagram and return the corresponding event.
  */
-static inline sctp_ulpevent_t *sctp_ulpqueue_retrieve_reassembled(sctp_ulpqueue_t *ulpq)
+static inline sctp_ulpevent_t *sctp_ulpq_retrieve_reassembled(struct sctp_ulpq *ulpq)
 {
 	struct sk_buff *pos, *tmp;
 	sctp_ulpevent_t *cevent;
 	struct sk_buff *first_frag = NULL;
 	__u32 ctsn, next_tsn;
-	unsigned long flags __attribute ((unused));
 	sctp_ulpevent_t *retval = NULL;
 
 	/* Initialized to 0 just to avoid compiler warning message. Will
@@ -284,8 +286,6 @@
 	 */
 	next_tsn = 0;
 
-	sctp_spin_lock_irqsave(&ulpq->reasm.lock, flags);
-
 	/* The chunks are held in the reasm queue sorted by TSN.
 	 * Walk through the queue sequentially and look for a sequence of
 	 * fragmented chunks that complete a datagram.
@@ -327,7 +327,6 @@
 		if (retval)
 			break;
 	}
-	sctp_spin_unlock_irqrestore(&ulpq->reasm.lock, flags);
 
 	return retval;
 }
@@ -335,7 +334,7 @@
 /* Helper function to reassemble chunks. Hold chunks on the reasm queue that
  * need reassembling.
  */
-static inline sctp_ulpevent_t *sctp_ulpqueue_reasm(sctp_ulpqueue_t *ulpq,
+static inline sctp_ulpevent_t *sctp_ulpq_reasm(struct sctp_ulpq *ulpq,
 						   sctp_ulpevent_t *event)
 {
 	sctp_ulpevent_t *retval = NULL;
@@ -350,8 +349,8 @@
 	if (SCTP_DATA_NOT_FRAG == (event->chunk_flags & SCTP_DATA_FRAG_MASK))
 		return event;
 
-	sctp_ulpqueue_store_reasm(ulpq, event);
-	retval = sctp_ulpqueue_retrieve_reassembled(ulpq);
+	sctp_ulpq_store_reasm(ulpq, event);
+	retval = sctp_ulpq_retrieve_reassembled(ulpq);
 
 	return retval;
 }
@@ -359,20 +358,20 @@
 /* Helper function to gather skbs that have possibly become
  * ordered by an an incoming chunk.
  */
-static inline void sctp_ulpqueue_retrieve_ordered(sctp_ulpqueue_t *ulpq,
-						  sctp_ulpevent_t *event)
+static inline void sctp_ulpq_retrieve_ordered(struct sctp_ulpq *ulpq,
+					      sctp_ulpevent_t *event)
 {
 	struct sk_buff *pos, *tmp;
-	sctp_ulpevent_t *cevent;
+	struct sctp_ulpevent *cevent;
+	struct sctp_stream *in;
 	__u16 sid, csid;
 	__u16 ssn, cssn;
-	unsigned long flags __attribute ((unused));
 
 	sid = event->sndrcvinfo.sinfo_stream;
 	ssn = event->sndrcvinfo.sinfo_ssn;
+	in  = &ulpq->asoc->ssnmap->in;
 
 	/* We are holding the chunks by stream, by SSN.  */
-	sctp_spin_lock_irqsave(&ulpq->lobby.lock, flags);
 	sctp_skb_for_each(pos, &ulpq->lobby, tmp) {
 		cevent = (sctp_ulpevent_t *) pos->cb;
 		csid = cevent->sndrcvinfo.sinfo_stream;
@@ -386,32 +385,31 @@
 		if (csid < sid)
 			continue;
 
-		if (cssn != ulpq->ssn[sid])
+		if (cssn != sctp_ssn_peek(in, sid))
 			break;
 
-		ulpq->ssn[sid]++;
+		/* Found it, so mark in the ssnmap. */
+		sctp_ssn_next(in, sid);
+	       
 		__skb_unlink(pos, pos->list);
 
 		/* Attach all gathered skbs to the event.  */
 		__skb_queue_tail(event->parent->list, pos);
 	}
-	sctp_spin_unlock_irqrestore(&ulpq->lobby.lock, flags);
 }
 
 /* Helper function to store chunks needing ordering.  */
-static inline void sctp_ulpqueue_store_ordered(sctp_ulpqueue_t *ulpq,
-					       sctp_ulpevent_t *event)
+static inline void sctp_ulpq_store_ordered(struct sctp_ulpq *ulpq,
+					   sctp_ulpevent_t *event)
 {
 	struct sk_buff *pos, *tmp;
 	sctp_ulpevent_t *cevent;
 	__u16 sid, csid;
 	__u16 ssn, cssn;
-	unsigned long flags __attribute ((unused));
 
 	sid = event->sndrcvinfo.sinfo_stream;
 	ssn = event->sndrcvinfo.sinfo_ssn;
 
-	sctp_spin_lock_irqsave(&ulpq->lobby.lock, flags);
 
 	/* Find the right place in this list.  We store them by
 	 * stream ID and then by SSN.
@@ -432,14 +430,13 @@
 		__skb_insert(event->parent, pos->prev, pos, &ulpq->lobby);
 	else
 		__skb_queue_tail(&ulpq->lobby, event->parent);
-
-	sctp_spin_unlock_irqrestore(&ulpq->lobby.lock, flags);
 }
 
-static inline sctp_ulpevent_t *sctp_ulpqueue_order(sctp_ulpqueue_t *ulpq,
-						   sctp_ulpevent_t *event)
+static inline sctp_ulpevent_t *sctp_ulpq_order(struct sctp_ulpq *ulpq,
+					       sctp_ulpevent_t *event)
 {
 	__u16 sid, ssn;
+	struct sctp_stream *in;
 
 	/* FIXME: We should be using some new chunk structure here
 	 * instead of carrying chunk fields in the event structure.
@@ -454,23 +451,24 @@
 	/* Note: The stream ID must be verified before this routine.  */
 	sid = event->sndrcvinfo.sinfo_stream;
 	ssn = event->sndrcvinfo.sinfo_ssn;
+	in  = &ulpq->asoc->ssnmap->in;
 
 	/* Is this the expected SSN for this stream ID?  */
-	if (ssn != ulpq->ssn[sid]) {
+	if (ssn != sctp_ssn_peek(in, sid)) {
 		/* We've received something out of order, so find where it
 		 * needs to be placed.  We order by stream and then by SSN.
 		 */
-		sctp_ulpqueue_store_ordered(ulpq, event);
+		sctp_ulpq_store_ordered(ulpq, event);
 		return NULL;
 	}
 
 	/* Mark that the next chunk has been found.  */
-	ulpq->ssn[sid]++;
+	sctp_ssn_next(in, sid);
 
 	/* Go find any other chunks that were waiting for
 	 * ordering.
 	 */
-	sctp_ulpqueue_retrieve_ordered(ulpq, event);
+	sctp_ulpq_retrieve_ordered(ulpq, event);
 
 	return event;
 }
diff -Nru a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
--- a/net/sunrpc/clnt.c	Fri Feb 14 15:53:09 2003
+++ b/net/sunrpc/clnt.c	Fri Feb 14 15:53:09 2003
@@ -63,6 +63,32 @@
 static u32 *	call_verify(struct rpc_task *task);
 
 
+static int
+rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
+{
+	static uint32_t clntid;
+	int maxlen = sizeof(clnt->cl_pathname);
+	int error;
+
+	if (dir_name == NULL)
+		return 0;
+	for (;;) {
+		snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname),
+				"%s/clnt%x", dir_name,
+				(unsigned int)clntid++);
+		clnt->cl_pathname[sizeof(clnt->cl_pathname) - 1] = '\0';
+		clnt->cl_dentry = rpc_mkdir(clnt->cl_pathname, clnt);
+		if (!IS_ERR(clnt->cl_dentry))
+			return 0;
+		error = PTR_ERR(clnt->cl_dentry);
+		if (error != -EEXIST) {
+			printk(KERN_INFO "RPC: Couldn't create pipefs entry %s, error %d\n",
+					clnt->cl_pathname, error);
+			return error;
+		}
+	}
+}
+
 /*
  * Create an RPC client
  * FIXME: This should also take a flags argument (as in task->tk_flags).
@@ -109,14 +135,9 @@
 
 	rpc_init_rtt(&clnt->cl_rtt, xprt->timeout.to_initval);
 
-	snprintf(clnt->cl_pathname, sizeof(clnt->cl_pathname),
-			"/%s/clnt%p", clnt->cl_protname, clnt);
-	clnt->cl_dentry = rpc_mkdir(clnt->cl_pathname, clnt);
-	if (IS_ERR(clnt->cl_dentry)) {
-		printk(KERN_INFO "RPC: Couldn't create pipefs entry %s\n",
-				clnt->cl_pathname);
+	if (rpc_setup_pipedir(clnt, program->pipe_dir_name) < 0)
 		goto out_no_path;
-	}
+
 	if (!rpcauth_create(flavor, clnt)) {
 		printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n",
 				flavor);
diff -Nru a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
--- a/net/sunrpc/rpc_pipe.c	Fri Feb 14 15:53:09 2003
+++ b/net/sunrpc/rpc_pipe.c	Fri Feb 14 15:53:09 2003
@@ -476,54 +476,58 @@
  * FIXME: This probably has races.
  */
 static void
-rpc_depopulate(struct dentry *dir)
+rpc_depopulate(struct dentry *parent)
 {
+	struct inode *dir = parent->d_inode;
 	LIST_HEAD(head);
 	struct list_head *pos, *next;
 	struct dentry *dentry;
 
-	down(&dir->d_inode->i_sem);
+	down(&dir->i_sem);
 	spin_lock(&dcache_lock);
-	list_for_each_safe(pos, next, &dir->d_subdirs) {
+	list_for_each_safe(pos, next, &parent->d_subdirs) {
 		dentry = list_entry(pos, struct dentry, d_child);
 		if (!d_unhashed(dentry)) {
 			dget_locked(dentry);
-			list_del(&dentry->d_hash);
+			__d_drop(dentry);
 			list_add(&dentry->d_hash, &head);
 		}
 	}
 	spin_unlock(&dcache_lock);
 	while (!list_empty(&head)) {
 		dentry = list_entry(head.next, struct dentry, d_hash);
-		list_del_init(&dentry->d_hash);
+		/* Private list, so no dcache_lock needed and use __d_drop */
+		__d_drop(dentry);
 		if (dentry->d_inode) {
 			rpc_inode_setowner(dentry->d_inode, NULL);
-			simple_unlink(dir->d_inode, dentry);
+			simple_unlink(dir, dentry);
 		}
 		dput(dentry);
 	}
-	up(&dir->d_inode->i_sem);
+	up(&dir->i_sem);
 }
 
 static int
-rpc_populate(struct dentry *dir,
+rpc_populate(struct dentry *parent,
 		struct rpc_filelist *files,
 		int start, int eof)
 {
-	void *private = RPC_I(dir->d_inode)->private;
+	struct inode *inode, *dir = parent->d_inode;
+	void *private = RPC_I(dir)->private;
 	struct qstr name;
 	struct dentry *dentry;
-	struct inode *inode;
 	int mode, i;
+
+	down(&dir->i_sem);
 	for (i = start; i < eof; i++) {
 		name.name = files[i].name;
 		name.len = strlen(name.name);
 		name.hash = full_name_hash(name.name, name.len);
-		dentry = d_alloc(dir, &name);
+		dentry = d_alloc(parent, &name);
 		if (!dentry)
 			goto out_bad;
 		mode = files[i].mode;
-		inode = rpc_get_inode(dir->d_inode->i_sb, mode);
+		inode = rpc_get_inode(dir->i_sb, mode);
 		if (!inode) {
 			dput(dentry);
 			goto out_bad;
@@ -534,13 +538,15 @@
 		if (private)
 			rpc_inode_setowner(inode, private);
 		if (S_ISDIR(mode))
-			dir->d_inode->i_nlink++;
+			dir->i_nlink++;
 		d_add(dentry, inode);
 	}
+	up(&dir->i_sem);
 	return 0;
 out_bad:
+	up(&dir->i_sem);
 	printk(KERN_WARNING "%s: %s failed to populate directory %s\n",
-			__FILE__, __FUNCTION__, dir->d_name.name);
+			__FILE__, __FUNCTION__, parent->d_name.name);
 	return -ENOMEM;
 }
 
@@ -569,6 +575,7 @@
 {
 	int error;
 
+	shrink_dcache_parent(dentry);
 	rpc_inode_setowner(dentry->d_inode, NULL);
 	if ((error = simple_rmdir(dir, dentry)) != 0)
 		return error;
diff -Nru a/net/sunrpc/sched.c b/net/sunrpc/sched.c
--- a/net/sunrpc/sched.c	Fri Feb 14 15:53:10 2003
+++ b/net/sunrpc/sched.c	Fri Feb 14 15:53:10 2003
@@ -962,14 +962,8 @@
 	rpciod_pid = current->pid;
 	up(&rpciod_running);
 
-	daemonize();
-
-	spin_lock_irq(&current->sighand->siglock);
-	siginitsetinv(&current->blocked, sigmask(SIGKILL));
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	strcpy(current->comm, "rpciod");
+	daemonize("rpciod");
+	allow_signal(SIGKILL);
 
 	dprintk("RPC: rpciod starting (pid %d)\n", rpciod_pid);
 	while (rpciod_users) {
diff -Nru a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
--- a/net/sunrpc/sysctl.c	Fri Feb 14 15:53:08 2003
+++ b/net/sunrpc/sysctl.c	Fri Feb 14 15:53:08 2003
@@ -116,23 +116,51 @@
 	return 0;
 }
 
-#define DIRENTRY(nam1, nam2, child)	\
-	{CTL_##nam1, #nam2, NULL, 0, 0555, child }
-#define DBGENTRY(nam1, nam2)	\
-	{CTL_##nam1##DEBUG, #nam2 "_debug", &nam2##_debug, sizeof(int),\
-	 0644, NULL, &proc_dodebug}
-
-static ctl_table		debug_table[] = {
-	DBGENTRY(RPC,  rpc),
-	DBGENTRY(NFS,  nfs),
-	DBGENTRY(NFSD, nfsd),
-	DBGENTRY(NLM,  nlm),
-	{0}
+static ctl_table debug_table[] = {
+	{
+		.ctl_name	= CTL_RPCDEBUG,
+		.procname	= "rpc_debug",
+		.data		= &rpc_debug,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dodebug
+	}, 
+	{
+		.ctl_name	= CTL_NFSDEBUG,
+		.procname	= "nfs_debug",
+		.data		= &nfs_debug,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dodebug
+	}, 
+	{
+		.ctl_name	= CTL_NFSDDEBUG,
+		.procname	= "nfsd_debug",
+		.data		= &nfsd_debug,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dodebug
+	}, 
+	{
+		.ctl_name	= CTL_NLMDEBUG,
+		.procname	= "nlm_debug",
+		.data		= &nlm_debug,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dodebug
+	}, 
+	{ .ctl_name = 0 }
 };
 
-static ctl_table		sunrpc_table[] = {
-	DIRENTRY(SUNRPC, sunrpc, debug_table),
-	{0}
+static ctl_table sunrpc_table[] = {
+	{
+		.ctl_name	= CTL_SUNRPC,
+		.procname	= "sunrpc",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= debug_table
+	},
+	{ .ctl_name = 0 }
 };
 
 #endif
diff -Nru a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
--- a/net/sunrpc/xprt.c	Fri Feb 14 15:53:11 2003
+++ b/net/sunrpc/xprt.c	Fri Feb 14 15:53:11 2003
@@ -1273,25 +1273,41 @@
 }
 
 /*
+ * Allocate a 'unique' XID
+ */
+static u32
+xprt_alloc_xid(void)
+{
+	static spinlock_t xid_lock = SPIN_LOCK_UNLOCKED;
+	static int need_init = 1;
+	static u32 xid;
+	u32 ret;
+
+	spin_lock(&xid_lock);
+	if (unlikely(need_init)) {
+		xid = get_seconds() << 12;
+		need_init = 0;
+	}
+	ret = xid++;
+	spin_unlock(&xid_lock);
+	return ret;
+}
+
+/*
  * Initialize RPC request
  */
 static void
 xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
 {
 	struct rpc_rqst	*req = task->tk_rqstp;
-	static u32	xid = 0;
-
-	if (!xid)
-		xid = get_seconds() << 12;
 
-	dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid, req, xid);
 	req->rq_timeout = xprt->timeout;
 	req->rq_task	= task;
 	req->rq_xprt    = xprt;
-	req->rq_xid     = xid++;
-	if (!xid)
-		xid++;
+	req->rq_xid     = xprt_alloc_xid();
 	INIT_LIST_HEAD(&req->rq_list);
+	dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid,
+			req, req->rq_xid);
 }
 
 /*
diff -Nru a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c
--- a/net/unix/sysctl_net_unix.c	Fri Feb 14 15:53:09 2003
+++ b/net/unix/sysctl_net_unix.c	Fri Feb 14 15:53:09 2003
@@ -15,20 +15,37 @@
 extern int sysctl_unix_max_dgram_qlen;
 
 ctl_table unix_table[] = {
-	{NET_UNIX_MAX_DGRAM_QLEN, "max_dgram_qlen",
-	&sysctl_unix_max_dgram_qlen, sizeof(int), 0600, NULL, 
-	 &proc_dointvec },
-	{0}
+	{
+		.ctl_name	= NET_UNIX_MAX_DGRAM_QLEN,
+		.procname	= "max_dgram_qlen",
+		.data		= &sysctl_unix_max_dgram_qlen,
+		.maxlen		= sizeof(int),
+		.mode		= 0600,
+		.proc_handler	= &proc_dointvec
+	},
+	{ .ctl_name = 0 }
 };
 
 static ctl_table unix_net_table[] = {
-	{NET_UNIX, "unix", NULL, 0, 0555, unix_table},
-	{0}
+	{
+		.ctl_name	= NET_UNIX,
+		.procname	= "unix",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= unix_table
+	},
+	{ .ctl_name = 0 }
 };
 
 static ctl_table unix_root_table[] = {
-	{CTL_NET, "net", NULL, 0, 0555, unix_net_table},
-	{0}
+	{
+		.ctl_name	= CTL_NET,
+		.procname	= "net",
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= unix_net_table
+	},
+	{ .ctl_name = 0 }
 };
 
 static struct ctl_table_header * unix_sysctl_header;
diff -Nru a/net/x25/x25_link.c b/net/x25/x25_link.c
--- a/net/x25/x25_link.c	Fri Feb 14 15:53:08 2003
+++ b/net/x25/x25_link.c	Fri Feb 14 15:53:08 2003
@@ -218,8 +218,9 @@
 
 	dptr = skb_put(skb, X25_STD_MIN_LEN + 2);
 
-	*dptr++ = ((lci >> 8) & 0x0F) | nb->extended ? X25_GFI_EXTSEQ :
-							  X25_GFI_STDSEQ;
+	*dptr++ = ((lci >> 8) & 0x0F) | (nb->extended ?
+					 X25_GFI_EXTSEQ :
+					 X25_GFI_STDSEQ);
 	*dptr++ = (lci >> 0) & 0xFF;
 	*dptr++ = X25_CLEAR_REQUEST;
 	*dptr++ = cause;
diff -Nru a/scripts/Makefile.build b/scripts/Makefile.build
--- a/scripts/Makefile.build	Fri Feb 14 15:53:12 2003
+++ b/scripts/Makefile.build	Fri Feb 14 15:53:12 2003
@@ -94,7 +94,7 @@
 	else								      \
 		$(CPP) -D__GENKSYMS__ $(c_flags) $<			      \
 		| $(GENKSYMS) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)	      \
-		| sed -n 's/\#define __ver_\(\w*\)\W*\(\w*\)/__crc_\1 = 0x\2 ;/gp' \
+		| sed -n 's/\#define __ver_\([^ 	]*\)[ 	]*\([^ 	]*\)/__crc_\1 = 0x\2 ;/gp' \
 		> $(@D)/.tmp_$(@F:.o=.ver);				      \
 									      \
 		$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) 		      \
diff -Nru a/scripts/Makefile.lib b/scripts/Makefile.lib
--- a/scripts/Makefile.lib	Fri Feb 14 15:53:10 2003
+++ b/scripts/Makefile.lib	Fri Feb 14 15:53:10 2003
@@ -165,7 +165,7 @@
 # ---------------------------------------------------------------------------
 
 quiet_cmd_objcopy = OBJCOPY $@
-cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $< $@
+cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
 
 # Gzip
 # ---------------------------------------------------------------------------
@@ -178,14 +178,16 @@
 # ===========================================================================
 
 # function to only execute the passed command if necessary
+# >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file
+# note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars
 
 if_changed = $(if $(strip $? \
 		          $(filter-out $(cmd_$(1)),$(cmd_$@))\
 			  $(filter-out $(cmd_$@),$(cmd_$(1)))),\
 	@set -e; \
-	$(if $($(quiet)cmd_$(1)),echo '  $($(quiet)cmd_$(1))';) \
+	$(if $($(quiet)cmd_$(1)),echo '  $(subst ','\'',$($(quiet)cmd_$(1)))';) \
 	$(cmd_$(1)); \
-	echo 'cmd_$@ := $(cmd_$(1))' > $(@D)/.$(@F).cmd)
+	echo 'cmd_$@ := $(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).cmd)
 
 
 # execute the command and also postprocess generated .d dependencies
@@ -195,9 +197,9 @@
 		          $(filter-out $(cmd_$(1)),$(cmd_$@))\
 			  $(filter-out $(cmd_$@),$(cmd_$(1)))),\
 	@set -e; \
-	$(if $($(quiet)cmd_$(1)),echo '  $($(quiet)cmd_$(1))';) \
+	$(if $($(quiet)cmd_$(1)),echo '  $(subst ','\'',$($(quiet)cmd_$(1)))';) \
 	$(cmd_$(1)); \
-	scripts/fixdep $(depfile) $@ '$(cmd_$(1))' > $(@D)/.$(@F).tmp; \
+	scripts/fixdep $(depfile) $@ '$(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \
 	rm -f $(depfile); \
 	mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd)
 
diff -Nru a/scripts/Makefile.modver b/scripts/Makefile.modver
--- a/scripts/Makefile.modver	Fri Feb 14 15:53:09 2003
+++ b/scripts/Makefile.modver	Fri Feb 14 15:53:09 2003
@@ -9,11 +9,12 @@
 
 #
 
-__modules := $(shell cd $(MODVERDIR); cat *.mod)
+__modules := $(shell cat /dev/null $(wildcard $(MODVERDIR)/*.mod))
 modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o)))
 
 ifneq ($(filter-out $(modules),$(__modules)),)
-  $(warning *** Uh-oh, you have stale module entries. You messed with SUBDIRS, don't complain if something goes wrong.)
+  $(warning *** Uh-oh, you have stale module entries. You messed with SUBDIRS,)
+  $(warning     do not complain if something goes wrong.)
 endif
 
 __modversions: $(modules)
diff -Nru a/scripts/fixdep.c b/scripts/fixdep.c
--- a/scripts/fixdep.c	Fri Feb 14 15:53:10 2003
+++ b/scripts/fixdep.c	Fri Feb 14 15:53:10 2003
@@ -277,6 +277,8 @@
 	parse_config_file(map, st.st_size);
 
 	munmap(map, st.st_size);
+
+	close(fd);
 }
 
 void parse_dep_file(void *map, size_t len)
@@ -346,6 +348,8 @@
 	parse_dep_file(map, st.st_size);
 
 	munmap(map, st.st_size);
+
+	close(fd);
 }
 
 void traps(void)
diff -Nru a/sound/oss/ad1848.c b/sound/oss/ad1848.c
--- a/sound/oss/ad1848.c	Fri Feb 14 15:53:11 2003
+++ b/sound/oss/ad1848.c	Fri Feb 14 15:53:11 2003
@@ -209,15 +209,12 @@
 
 static int ad_read(ad1848_info * devc, int reg)
 {
-	unsigned long flags;
 	int x;
 	int timeout = 900000;
 
 	while (timeout > 0 && inb(devc->base) == 0x80)	/*Are we initializing */
 		timeout--;
 
-	spin_lock_irqsave(&devc->lock,flags);
-	
 	if(reg < 32)
 	{
 		outb(((unsigned char) (reg & 0xff) | devc->MCE_bit), io_Index_Addr(devc));
@@ -233,21 +230,17 @@
 		outb(((unsigned char) (xra & 0xff)), io_Indexed_Data(devc));
 		x = inb(io_Indexed_Data(devc));
 	}
-	spin_unlock_irqrestore(&devc->lock,flags);
 
 	return x;
 }
 
 static void ad_write(ad1848_info * devc, int reg, int data)
 {
-	unsigned long flags;
 	int timeout = 900000;
 
 	while (timeout > 0 && inb(devc->base) == 0x80)	/* Are we initializing */
 		timeout--;
 
-	spin_lock_irqsave(&devc->lock,flags);
-	
 	if(reg < 32)
 	{
 		outb(((unsigned char) (reg & 0xff) | devc->MCE_bit), io_Index_Addr(devc));
@@ -263,7 +256,6 @@
 		outb(((unsigned char) (xra & 0xff)), io_Indexed_Data(devc));
 		outb((unsigned char) (data & 0xff), io_Indexed_Data(devc));
 	}
-	spin_unlock_irqrestore(&devc->lock,flags);
 }
 
 static void wait_for_calibration(ad1848_info * devc)
@@ -319,37 +311,29 @@
 
 static void ad_enter_MCE(ad1848_info * devc)
 {
-	unsigned long flags;
 	int timeout = 1000;
 	unsigned short prev;
 
 	while (timeout > 0 && inb(devc->base) == 0x80)	/*Are we initializing */
 		timeout--;
 
-	spin_lock_irqsave(&devc->lock,flags);
-
 	devc->MCE_bit = 0x40;
 	prev = inb(io_Index_Addr(devc));
 	if (prev & 0x40)
 	{
-		spin_unlock_irqrestore(&devc->lock,flags);
 		return;
 	}
 	outb((devc->MCE_bit), io_Index_Addr(devc));
-	spin_unlock_irqrestore(&devc->lock,flags);
 }
 
 static void ad_leave_MCE(ad1848_info * devc)
 {
-	unsigned long flags;
 	unsigned char prev, acal;
 	int timeout = 1000;
 
 	while (timeout > 0 && inb(devc->base) == 0x80)	/*Are we initializing */
 		timeout--;
 
-	spin_lock_irqsave(&devc->lock,flags);
-
 	acal = ad_read(devc, 9);
 
 	devc->MCE_bit = 0x00;
@@ -358,19 +342,18 @@
 
 	if ((prev & 0x40) == 0)	/* Not in MCE mode */
 	{
-		spin_unlock_irqrestore(&devc->lock,flags);
 		return;
 	}
 	outb((0x00), io_Index_Addr(devc));	/* Clear the MCE bit */
 	if (acal & 0x08)	/* Auto calibration is enabled */
 		wait_for_calibration(devc);
-	spin_unlock_irqrestore(&devc->lock,flags);
 }
 
 static int ad1848_set_recmask(ad1848_info * devc, int mask)
 {
 	unsigned char   recdev;
 	int             i, n;
+	unsigned long flags;
 
 	mask &= devc->supported_rec_devices;
 
@@ -392,6 +375,7 @@
 		if (mask & (1 << i))
 			n++;
 
+	spin_lock_irqsave(&devc->lock,flags);
 	if (!soundpro) {
 		if (n == 0)
 			mask = SOUND_MASK_MIC;
@@ -460,6 +444,7 @@
 			}
 		}
 	}
+	spin_unlock_irqrestore(&devc->lock,flags);
 
 	/* Rename the mixer bits back if necessary */
 	for (i = 0; i < 32; i++)
@@ -527,6 +512,7 @@
 {
 	int regoffs, muteregoffs;
 	unsigned char val, muteval;
+	unsigned long flags;
 
 	regoffs = devc->mix_devices[dev][channel].regno;
 	muteregoffs = devc->mix_devices[dev][channel].mutereg;
@@ -539,12 +525,14 @@
 	else
 		change_bits(devc, &val, &val, dev, channel, value);
 
+	spin_lock_irqsave(&devc->lock,flags);
 	ad_write(devc, regoffs, val);
 	devc->saved_regs[regoffs] = val;
 	if (muteregoffs != regoffs) {
 		ad_write(devc, muteregoffs, muteval);
 		devc->saved_regs[muteregoffs] = muteval;
 	}
+	spin_unlock_irqrestore(&devc->lock,flags);
 }
 
 static int ad1848_mixer_set(ad1848_info * devc, int dev, int value)
@@ -600,6 +588,7 @@
 {
 	int i;
 	char name[32];
+	unsigned long flags;
 
 	devc->mix_devices = &(ad1848_mix_devices[0]);
 
@@ -666,6 +655,7 @@
 	
 	devc->mixer_output_port = devc->levels[31] | AUDIO_HEADPHONE | AUDIO_LINE_OUT;
 
+	spin_lock_irqsave(&devc->lock,flags);
 	if (!soundpro) {
 		if (devc->mixer_output_port & AUDIO_SPEAKER)
 			ad_write(devc, 26, ad_read(devc, 26) & ~0x40);	/* Unmute mono out */
@@ -679,6 +669,7 @@
 		/* Enable surround mode and SB16 mixer */
 		ad_write(devc, 16, 0x60);
 	}
+	spin_unlock_irqrestore(&devc->lock,flags);
 }
 
 static int ad1848_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
@@ -693,14 +684,17 @@
 
 		if (val != 0xffff) 
 		{
+			unsigned long flags;
 			val &= (AUDIO_SPEAKER | AUDIO_HEADPHONE | AUDIO_LINE_OUT);
 			devc->mixer_output_port = val;
 			val |= AUDIO_HEADPHONE | AUDIO_LINE_OUT;	/* Always on */
 			devc->mixer_output_port = val;
+			spin_lock_irqsave(&devc->lock,flags);
 			if (val & AUDIO_SPEAKER)
 				ad_write(devc, 26, ad_read(devc, 26) & ~0x40);	/* Unmute mono out */
 			else
 				ad_write(devc, 26, ad_read(devc, 26) | 0x40);		/* Mute mono out */
+			spin_unlock_irqrestore(&devc->lock,flags);
 		}
 		val = devc->mixer_output_port;
 		return put_user(val, (int *)arg);
@@ -985,10 +979,11 @@
 	devc = (ad1848_info *) audio_devs[dev]->devc;
 	portc = (ad1848_port_info *) audio_devs[dev]->portc;
 
-	spin_lock_irqsave(&devc->lock,flags);
+	/* here we don't have to protect against intr */
+	spin_lock(&devc->lock);
 	if (portc->open_mode || (devc->open_mode & mode))
 	{
-		spin_unlock_irqrestore(&devc->lock,flags);
+		spin_unlock(&devc->lock);
 		return -EBUSY;
 	}
 	devc->dual_dma = 0;
@@ -1001,17 +996,19 @@
 	devc->audio_mode = 0;
 	devc->open_mode |= mode;
 	portc->open_mode = mode;
+	spin_unlock(&devc->lock);
 	ad1848_trigger(dev, 0);
 
 	if (mode & OPEN_READ)
 		devc->record_dev = dev;
 	if (mode & OPEN_WRITE)
 		devc->playback_dev = dev;
-	spin_unlock_irqrestore(&devc->lock,flags);
 /*
  * Mute output until the playback really starts. This decreases clicking (hope so).
  */
+	spin_lock_irqsave(&devc->lock,flags);
 	ad_mute(devc);
+	spin_unlock_irqrestore(&devc->lock,flags);
 
 	return 0;
 }
@@ -1024,11 +1021,11 @@
 
 	DEB(printk("ad1848_close(void)\n"));
 
-	spin_lock_irqsave(&devc->lock,flags);
-
 	devc->intr_active = 0;
 	ad1848_halt(dev);
 
+	spin_lock_irqsave(&devc->lock,flags);
+
 	devc->audio_mode = 0;
 	devc->open_mode &= ~portc->open_mode;
 	portc->open_mode = 0;
@@ -1585,6 +1582,7 @@
 		printk(KERN_ERR "ad1848.c: Port %x not free.\n", io_base);
 		return 0;
 	}
+	spin_lock_init(&devc->lock);
 	devc->base = io_base;
 	devc->irq_ok = 0;
 	devc->timer_running = 0;
@@ -1969,7 +1967,6 @@
 
 	ad1848_port_info *portc = NULL;
 
-	spin_lock_init(&devc->lock);
 	devc->irq = (irq > 0) ? irq : 0;
 	devc->open_mode = 0;
 	devc->timer_ticks = 0;
@@ -2112,6 +2109,7 @@
 int ad1848_control(int cmd, int arg)
 {
 	ad1848_info *devc;
+	unsigned long flags;
 
 	if (nr_ad1848_devs < 1)
 		return -ENODEV;
@@ -2123,9 +2121,11 @@
 		case AD1848_SET_XTAL:	/* Change clock frequency of AD1845 (only ) */
 			if (devc->model != MD_1845 || devc->model != MD_1845_SSCAPE)
 				return -EINVAL;
+			spin_lock_irqsave(&devc->lock,flags);
 			ad_enter_MCE(devc);
 			ad_write(devc, 29, (ad_read(devc, 29) & 0x1f) | (arg << 5));
 			ad_leave_MCE(devc);
+			spin_unlock_irqrestore(&devc->lock,flags);
 			break;
 
 		case AD1848_MIXER_REROUTE:
@@ -2253,8 +2253,10 @@
 		}
 		else if (devc->model != MD_1848)
 		{
+			spin_lock(&devc->lock);
 			alt_stat = ad_read(devc, 24);
 			ad_write(devc, 24, ad_read(devc, 24) & ~alt_stat);	/* Selective ack */
+			spin_unlock(&devc->lock);
 		}
 
 		if ((devc->open_mode & OPEN_READ) && (devc->audio_mode & PCM_ENABLE_INPUT) && (alt_stat & 0x20))
@@ -2831,11 +2833,8 @@
 
 static int ad1848_resume(ad1848_info *devc)
 {
-	unsigned long flags;
 	int mixer_levels[32], i;
 
-	spin_lock_irqsave(&devc->lock,flags);
-	
 	/* Thinkpad is a bit more of PITA than normal. The BIOS tends to
 	   restore it in a different config to the one we use.  Need to
 	   fix this somehow */
@@ -2851,7 +2850,7 @@
 	if (!devc->subtype) {
 		static signed char interrupt_bits[12] = { -1, -1, -1, -1, -1, 0x00, -1, 0x08, -1, 0x10, 0x18, 0x20 };
 		static char dma_bits[4] = { 1, 2, 0, 3 };
-
+		unsigned long flags;
 		signed char bits;
 		char dma2_bit = 0;
 
@@ -2860,10 +2859,11 @@
 		bits = interrupt_bits[devc->irq];
 		if (bits == -1) {
 			printk(KERN_ERR "MSS: Bad IRQ %d\n", devc->irq);
-			spin_unlock_irqrestore(&devc->lock,flags);
 			return -1;
 		}
 
+		spin_lock_irqsave(&devc->lock,flags);
+	
 		outb((bits | 0x40), config_port); 
 
 		if (devc->dma2 != -1 && devc->dma2 != devc->dma1)
@@ -2873,9 +2873,9 @@
 				dma2_bit = 0x04;
 
 		outb((bits | dma_bits[devc->dma1] | dma2_bit), config_port);
+		spin_unlock_irqrestore(&devc->lock,flags);
 	}
 
-	spin_unlock_irqrestore(&devc->lock,flags);
 	return 0;
 }
 
diff -Nru a/sound/oss/es1370.c b/sound/oss/es1370.c
--- a/sound/oss/es1370.c	Fri Feb 14 15:53:12 2003
+++ b/sound/oss/es1370.c	Fri Feb 14 15:53:12 2003
@@ -2669,7 +2669,8 @@
 	}
 	set_fs(fs);
 	/* register gameport */
-	gameport_register_port(&s->gameport);
+	if (s->gameport.io)
+		gameport_register_port(&s->gameport);
 
 	/* store it in the driver field */
 	pci_set_drvdata(pcidev, s);
diff -Nru a/sound/oss/es1371.c b/sound/oss/es1371.c
--- a/sound/oss/es1371.c	Fri Feb 14 15:53:12 2003
+++ b/sound/oss/es1371.c	Fri Feb 14 15:53:12 2003
@@ -2963,7 +2963,8 @@
 	/* turn on S/PDIF output driver if requested */
 	outl(cssr, s->io+ES1371_REG_STATUS);
 	/* register gameport */
-	gameport_register_port(&s->gameport);
+	if (s->gameport.io)
+		gameport_register_port(&s->gameport);
 	/* store it in the driver field */
 	pci_set_drvdata(pcidev, s);
 	/* put it into driver list */
diff -Nru a/sound/oss/nec_vrc5477.c b/sound/oss/nec_vrc5477.c
--- a/sound/oss/nec_vrc5477.c	Fri Feb 14 15:53:12 2003
+++ b/sound/oss/nec_vrc5477.c	Fri Feb 14 15:53:12 2003
@@ -6,6 +6,8 @@
  *     AC97 sound dirver for NEC Vrc5477 chip (an integrated, 
  *     multi-function controller chip for MIPS CPUs)
  *
+ * VRA support Copyright 2001 Bradley D. LaRonde <brad@ltc.com>
+ *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
  * Free Software Foundation;  either version 2 of the  License, or (at your
@@ -78,22 +80,31 @@
 #include <linux/smp_lock.h>
 #include <linux/ac97_codec.h>
 #include <linux/wrapper.h>
+#include <linux/interrupt.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
 #include <asm/hardirq.h>
 
-#include <asm/ddb5xxx/debug.h>
+/* -------------------debug macros -------------------------------------- */
+/* #undef VRC5477_AC97_DEBUG */
+#define VRC5477_AC97_DEBUG
 
 #undef VRC5477_AC97_VERBOSE_DEBUG
+/* #define VRC5477_AC97_VERBOSE_DEBUG */
 
-/* one must turn on CONFIG_LL_DEBUG before VERBOSE_DEBUG is turned */
 #if defined(VRC5477_AC97_VERBOSE_DEBUG)
-#if !defined(CONFIG_LL_DEBUG)
-#error "You must turn CONFIG_LL_DEBUG"
-#endif
+#define VRC5477_AC97_DEBUG
 #endif
 
+#if defined(VRC5477_AC97_DEBUG)
+#include <linux/kernel.h>
+#define ASSERT(x)  if (!(x)) { \
+	panic("assertion failed at %s:%d: %s\n", __FILE__, __LINE__, #x); }
+#else
+#define	ASSERT(x)
+#endif /* VRC5477_AC97_DEBUG */
+
 #if defined(VRC5477_AC97_VERBOSE_DEBUG)
 static u16 inTicket=0; 		/* check sync between intr & write */
 static u16 outTicket=0;
@@ -179,16 +190,17 @@
 	unsigned long io;
 	unsigned int irq;
 
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
 	/* debug /proc entry */
 	struct proc_dir_entry *ps;
 	struct proc_dir_entry *ac97_ps;
-#endif /* CONFIG_LL_DEBUG */
+#endif /* VRC5477_AC97_DEBUG */
 
 	struct ac97_codec codec;
 
 	unsigned dacChannels, adcChannels;
 	unsigned short dacRate, adcRate;
+	unsigned short extended_status;
 
 	spinlock_t lock;
 	struct semaphore open_sem;
@@ -226,7 +238,7 @@
 
 /* --------------------------------------------------------------------- */
 
-extern inline unsigned ld2(unsigned int x)
+static inline unsigned ld2(unsigned int x)
 {
     unsigned r = 0;
 	
@@ -275,7 +287,7 @@
                 (VRC5477_CODEC_RD_RRDYA | VRC5477_CODEC_RD_RRDYD) ) {
 		/* we get either addr or data, or both */
 		if (result & VRC5477_CODEC_RD_RRDYA) {
-			MIPS_ASSERT(addr == ((result >> 16) & 0x7f) );
+			ASSERT(addr == ((result >> 16) & 0x7f) );
 		}
 		if (result & VRC5477_CODEC_RD_RRDYD) {
 			break;
@@ -315,6 +327,43 @@
 	while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
 }
 
+static int ac97_codec_not_present(struct ac97_codec *codec)
+{
+	struct vrc5477_ac97_state *s = 
+		(struct vrc5477_ac97_state *)codec->private_data;
+	unsigned long flags;
+	unsigned short count  = 0xffff; 
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	/* wait until we can access codec registers */
+	do {
+	       if (!(inl(s->io + VRC5477_CODEC_WR) & 0x80000000))
+		       break;
+	} while (--count);
+
+	if (count == 0) {
+		spin_unlock_irqrestore(&s->lock, flags);
+		return -1;
+	}
+
+	/* write 0 to reset */
+	outl((AC97_RESET << 16) | 0, s->io + VRC5477_CODEC_WR);
+
+	/* test whether we get a response from ac97 chip */
+	count  = 0xffff; 
+	do { 
+	       if (!(inl(s->io + VRC5477_CODEC_WR) & 0x80000000))
+		       break;
+	} while (--count);
+
+	if (count == 0) {
+		spin_unlock_irqrestore(&s->lock, flags);
+		return -1;
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	return 0;
+}
 
 /* --------------------------------------------------------------------- */
 
@@ -345,14 +394,16 @@
 
 static void set_dac_rate(struct vrc5477_ac97_state *s, unsigned rate)
 {
+	if(s->extended_status & AC97_EXTSTAT_VRA) {
 	wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, rate);
-	s->dacRate = rate;
+		s->dacRate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
+	}
 }
 
 
 /* --------------------------------------------------------------------- */
 
-extern inline void 
+static inline void 
 stop_dac(struct vrc5477_ac97_state *s)
 {
 	struct dmabuf* db = &s->dma_dac;
@@ -408,7 +459,7 @@
 	}
 
 	/* we should have some data to do the DMA trasnfer */
-	MIPS_ASSERT(db->count >= db->fragSize);
+	ASSERT(db->count >= db->fragSize);
 
 	/* clear pending fales interrupts */
 	outl(VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END, 
@@ -442,12 +493,12 @@
 	outl (temp, s->io + VRC5477_CTRL);
 
 	/* it is time to setup next dma transfer */
-	MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
-	MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+	ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+	ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
 
 	temp = db->nextOut + db->fragSize;
 	if (temp >= db->fragTotalSize) {
-		MIPS_ASSERT(temp == db->fragTotalSize);
+		ASSERT(temp == db->fragTotalSize);
 		temp = 0;
 	}
 
@@ -463,14 +514,14 @@
 #if defined(VRC5477_AC97_VERBOSE_DEBUG)
 	outTicket = *(u16*)(db->lbuf+db->nextOut);
 	if (db->count > db->fragSize) {
-		MIPS_ASSERT((u16)(outTicket+1) == *(u16*)(db->lbuf+temp));
+		ASSERT((u16)(outTicket+1) == *(u16*)(db->lbuf+temp));
 	}
 #endif
 
 	spin_unlock_irqrestore(&s->lock, flags);
 }	
 
-extern inline void stop_adc(struct vrc5477_ac97_state *s)
+static inline void stop_adc(struct vrc5477_ac97_state *s)
 {
 	struct dmabuf* db = &s->dma_adc;
 	unsigned long flags;
@@ -521,7 +572,7 @@
 	}
 
 	/* we should at least have some free space in the buffer */
-	MIPS_ASSERT(db->count < db->fragTotalSize - db->fragSize * 2);
+	ASSERT(db->count < db->fragTotalSize - db->fragSize * 2);
 
 	/* clear pending ones */
 	outl(VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END, 
@@ -553,7 +604,7 @@
 	/* it is time to setup next dma transfer */
 	temp = db->nextIn + db->fragSize;
 	if (temp >= db->fragTotalSize) {
-		MIPS_ASSERT(temp == db->fragTotalSize);
+		ASSERT(temp == db->fragTotalSize);
 		temp = 0;
 	}
 	outl(db->lbufDma + temp, s->io + VRC5477_ADC1_BADDR);
@@ -569,11 +620,11 @@
 #define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
 #define DMABUF_MINORDER 1
 
-extern inline void dealloc_dmabuf(struct vrc5477_ac97_state *s, 
+static inline void dealloc_dmabuf(struct vrc5477_ac97_state *s, 
 				  struct dmabuf *db)
 {
 	if (db->lbuf) {
-		MIPS_ASSERT(db->rbuf);
+		ASSERT(db->rbuf);
 		pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder,
 				    db->lbuf, db->lbufDma);
 		pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder,
@@ -592,7 +643,7 @@
 	unsigned bufsize;
 
 	if (!db->lbuf) {
-		MIPS_ASSERT(!db->rbuf);
+		ASSERT(!db->rbuf);
 
 		db->ready = 0;
 		for (order = DMABUF_DEFAULTORDER; 
@@ -606,7 +657,7 @@
 							&db->rbufDma);
 			if (db->lbuf && db->rbuf) break;
 			if (db->lbuf) {
-			    MIPS_ASSERT(!db->rbuf);
+			    ASSERT(!db->rbuf);
 			    pci_free_consistent(s->dev, 
 						PAGE_SIZE << order,
 						db->lbuf,
@@ -614,7 +665,7 @@
 			}
 		}
 		if (!db->lbuf) {
-			MIPS_ASSERT(!db->rbuf);
+			ASSERT(!db->rbuf);
 			return -ENOMEM;
 		}
 
@@ -643,13 +694,13 @@
 	return 0;
 }
 
-extern inline int prog_dmabuf_adc(struct vrc5477_ac97_state *s)
+static inline int prog_dmabuf_adc(struct vrc5477_ac97_state *s)
 {
     stop_adc(s);
     return prog_dmabuf(s, &s->dma_adc, s->adcRate);
 }
 
-extern inline int prog_dmabuf_dac(struct vrc5477_ac97_state *s)
+static inline int prog_dmabuf_dac(struct vrc5477_ac97_state *s)
 {
     stop_dac(s);
     return prog_dmabuf(s, &s->dma_dac, s->dacRate);
@@ -677,7 +728,7 @@
 	/* set the base addr for next DMA transfer */
 	temp = adc->nextIn + 2*adc->fragSize;
 	if (temp >= adc->fragTotalSize) {
-		MIPS_ASSERT( (temp == adc->fragTotalSize) ||
+		ASSERT( (temp == adc->fragTotalSize) ||
                              (temp == adc->fragTotalSize + adc->fragSize) );
 		temp -= adc->fragTotalSize;
 	}
@@ -687,7 +738,7 @@
 	/* adjust nextIn */
 	adc->nextIn += adc->fragSize;
 	if (adc->nextIn >= adc->fragTotalSize) {
-		MIPS_ASSERT(adc->nextIn == adc->fragTotalSize);
+		ASSERT(adc->nextIn == adc->fragTotalSize);
 		adc->nextIn = 0;
 	}
 
@@ -706,13 +757,13 @@
 	unsigned temp;
 
 	/* next DMA transfer should already started */
-	MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
-	MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+	// ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+	// ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
 
 	/* let us set for next next DMA transfer */
 	temp = dac->nextOut + dac->fragSize*2;
 	if (temp >= dac->fragTotalSize) {
-		MIPS_ASSERT( (temp == dac->fragTotalSize) || 
+		ASSERT( (temp == dac->fragTotalSize) || 
                              (temp == dac->fragTotalSize + dac->fragSize) );
 		temp -= dac->fragTotalSize;
 	}
@@ -728,35 +779,35 @@
 		printk("assert fail: - %d vs %d\n", 
 		        *(u16*)(dac->lbuf +  dac->nextOut),
                         outTicket);
-                MIPS_ASSERT(1 == 0);
+                ASSERT(1 == 0);
 	}
 #endif
 
 	/* adjust nextOut pointer */
 	dac->nextOut += dac->fragSize;
 	if (dac->nextOut >= dac->fragTotalSize) {
-		MIPS_ASSERT(dac->nextOut == dac->fragTotalSize);
+		ASSERT(dac->nextOut == dac->fragTotalSize);
 		dac->nextOut = 0;
 	}
 
 	/* adjust count */
 	dac->count -= dac->fragSize;
 	if (dac->count <=0 ) {
-		MIPS_ASSERT(dac->count == 0);
-		MIPS_ASSERT(dac->nextIn == dac->nextOut);
 		/* buffer under run */
+		dac->count = 0;
+		dac->nextIn = dac->nextOut;
 		stop_dac(s);
 	}
 
 #if defined(VRC5477_AC97_VERBOSE_DEBUG)
 	if (dac->count) {
 		outTicket ++;
-		MIPS_ASSERT(*(u16*)(dac->lbuf +  dac->nextOut) == outTicket);
+		ASSERT(*(u16*)(dac->lbuf +  dac->nextOut) == outTicket);
 	}
 #endif
 	
 	/* we cannot have both under run and someone is waiting on us */
-	MIPS_ASSERT(! (waitqueue_active(&dac->wait) && (dac->count <= 0)) );
+	ASSERT(! (waitqueue_active(&dac->wait) && (dac->count <= 0)) );
 
 	/* wake up anybody listening */
 	if (waitqueue_active(&dac->wait))
@@ -905,7 +956,7 @@
 
 		copyCount -= count;
 		bufStart += count;
-		MIPS_ASSERT(bufStart <= db->fragTotalSize);
+		ASSERT(bufStart <= db->fragTotalSize);
 		buffer += count *2;
 	}
 	return 0;
@@ -937,12 +988,12 @@
 		}
 		if (copyCount + db->nextOut > db->fragTotalSize) {
 			copyCount = db->fragTotalSize - db->nextOut;
-			MIPS_ASSERT((copyCount % db->fragSize) == 0);
+			ASSERT((copyCount % db->fragSize) == 0);
 		}
 
 		copyFragCount = (copyCount-1) >> db->fragShift;
 		copyFragCount = (copyFragCount+1) << db->fragShift;
-		MIPS_ASSERT(copyFragCount >= copyCount);
+		ASSERT(copyFragCount >= copyCount);
 
 		/* we copy differently based on adc channels */
 		if (s->adcChannels == 1) {
@@ -965,12 +1016,12 @@
 
 		db->nextOut += copyFragCount;
 		if (db->nextOut >= db->fragTotalSize) {
-			MIPS_ASSERT(db->nextOut == db->fragTotalSize);
+			ASSERT(db->nextOut == db->fragTotalSize);
 			db->nextOut = 0;
 		}
 
-		MIPS_ASSERT((copyFragCount % db->fragSize) == 0);
-		MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount));
+		ASSERT((copyFragCount % db->fragSize) == 0);
+		ASSERT( (count == 0) || (copyCount == copyFragCount));
 	}
 
 	spin_lock_irqsave(&s->lock, flags);
@@ -999,7 +1050,7 @@
 	if (!access_ok(VERIFY_WRITE, buffer, count))
 		return -EFAULT;
 
-	MIPS_ASSERT(db->ready);
+	ASSERT(db->ready);
 
 	while (count > 0) {
 		// wait for samples in capture buffer
@@ -1024,7 +1075,7 @@
 			}
 		} while (avail <= 0);
 
-		MIPS_ASSERT( (avail % db->fragSize) == 0);
+		ASSERT( (avail % db->fragSize) == 0);
 		copyCount = copy_adc_to_user(s, buffer, count, avail);
 		if (copyCount <=0 ) {
 			if (!ret) ret = -EFAULT;
@@ -1047,7 +1098,7 @@
 	struct dmabuf *db = &s->dma_dac;
 	int bufStart = db->nextIn;
 
-	MIPS_ASSERT(db->ready);
+	ASSERT(db->ready);
 
         for (; copyCount > 0; ) {
                 int i;
@@ -1065,7 +1116,7 @@
 
                 copyCount -= count;
 		bufStart += count;
-		MIPS_ASSERT(bufStart <= db->fragTotalSize);
+		ASSERT(bufStart <= db->fragTotalSize);
                 buffer += count *2;
         }
         return 0;
@@ -1101,13 +1152,11 @@
 		}
                 if (copyCount + db->nextIn > db->fragTotalSize) {
                         copyCount = db->fragTotalSize - db->nextIn;
-                        MIPS_ASSERT((copyCount % db->fragSize) == 0);
-                        MIPS_ASSERT(copyCount > 0);
+                        ASSERT(copyCount > 0);
                 }
 
-		copyFragCount = (copyCount-1) >> db->fragShift;
-		copyFragCount = (copyFragCount+1) << db->fragShift;
-		MIPS_ASSERT(copyFragCount >= copyCount);
+		copyFragCount = copyCount;
+		ASSERT(copyFragCount >= copyCount);
 
 		/* we copy differently based on the number channels */
 		if (s->dacChannels == 1) {
@@ -1147,12 +1196,11 @@
 
 		db->nextIn += copyFragCount;
 		if (db->nextIn >= db->fragTotalSize) {
-			MIPS_ASSERT(db->nextIn == db->fragTotalSize);
+			ASSERT(db->nextIn == db->fragTotalSize);
 			db->nextIn = 0;
 		}
 
-		MIPS_ASSERT((copyFragCount % db->fragSize) == 0);
-		MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount));
+		ASSERT( (count == 0) || (copyCount == copyFragCount));
 	}
 
 	spin_lock_irqsave(&s->lock, flags);
@@ -1162,7 +1210,7 @@
 	}
 
 	/* nextIn should not be equal to nextOut unless we are full */
-	MIPS_ASSERT( ( (db->count == db->fragTotalSize) && 
+	ASSERT( ( (db->count == db->fragTotalSize) && 
                        (db->nextIn == db->nextOut) ) ||
                      ( (db->count < db->fragTotalSize) &&
                        (db->nextIn != db->nextOut) ) );
@@ -1210,7 +1258,6 @@
 			}
 		} while (avail <= 0);
 	
-		MIPS_ASSERT( (avail % db->fragSize) == 0);
 		copyCount = copy_dac_from_user(s, buffer, count, avail);
 		if (copyCount < 0) {
 			if (!ret) ret = -EFAULT;
@@ -1251,7 +1298,7 @@
 	return mask;
 }
 
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
 static struct ioctl_str_t {
     unsigned int cmd;
     const char* str;
@@ -1302,7 +1349,7 @@
 	int count;
 	int val, ret;
 
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
 	for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
 		if (ioctl_str[count].cmd == cmd)
 			break;
@@ -1633,7 +1680,7 @@
  * CODEC chipstate
  */
 
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
 
 struct {
        const char *regname;
@@ -1757,7 +1804,7 @@
 	return len;
 
 }
-#endif /* CONFIG_LL_DEBUG */
+#endif /* VRC5477_AC97_DEBUG */
 
 /* --------------------------------------------------------------------- */
 
@@ -1770,88 +1817,13 @@
 MODULE_DESCRIPTION("NEC Vrc5477 audio (AC97) Driver");
 MODULE_LICENSE("GPL");
 
-/* --------------------------------------------------------------------- */
-extern void jsun_scan_pci_bus(void);
-extern void vrc5477_show_pci_regs(void);
-extern void vrc5477_show_pdar_regs(void);
-
-/* -------------------------------------------------------- */
-#define         AC97_BASE               0xbb000000
-#define         myinl(x)                  *(volatile u32*)(AC97_BASE + (x))
-#define         myoutl(x,y)               *(volatile u32*)(AC97_BASE + (y)) = (x)
-
-u16 myrdcodec(u8 addr)
-{
-        u32 result;
-
-        /* wait until we can access codec registers */
-        // while (inl(VRC5477_CODEC_WR) & 0x80000000);
-
-        /* write the address and "read" command to codec */
-        addr = addr & 0x7f;
-        myoutl((addr << 16) | VRC5477_CODEC_WR_RWC, VRC5477_CODEC_WR);
-
-        /* get the return result */
-        udelay(100); /* workaround hardware bug */
-        // dump_memory(0xbb000000, 48);
-        while ( ((result=myinl(VRC5477_CODEC_RD)) & 0xc0000000) != 0xc0000000);
-        MIPS_ASSERT(addr == ((result >> 16) & 0x7f) );
-        return result & 0xffff;
-}
-
-void mywrcodec(u8 addr, u16 data)
-{
-        /* wait until we can access codec registers */
-        while (myinl(VRC5477_CODEC_WR) & 0x80000000);
-
-        /* write the address and value to codec */
-        myoutl((addr << 16) | data, VRC5477_CODEC_WR);
-
-}
-
-
-void jsun_ac97_test(struct vrc5477_ac97_state *s)
-{
-        int i;
-
-        /* reset codec */
-	/*
-        wrcodec(&s->codec, 0, 0);
-        while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
-	*/
-        mywrcodec(0, 0);
-        while (myinl(VRC5477_CODEC_WR) & 0x80000000);
-
-	for (i=0; i< 0x40; i+=4) {	
-	MIPS_ASSERT(inl(s->io+i) == myinl(i));
-	}
-
-        printk("codec registers : ");
-        for (i=0; i<= 0x3a; i+=2) {
-                if ( (i%0x10) == 0) {
-                        printk("\n%02x\t", i);
-                }
-                // printk("%04x\t", rdcodec(&s->codec, i));
-                printk("%04x\t", myrdcodec(i));
-        }
-        printk("\n\n");
-        printk("codec registers : ");
-        for (i=0; i<= 0x3a; i+=2) {
-                if ( (i%0x10) == 0) {
-                        printk("\n%02x\t", i);
-                }
-                printk("%04x\t", rdcodec(&s->codec, i));
-        }
-        printk("\n\n");
-}
-
 static int __devinit vrc5477_ac97_probe(struct pci_dev *pcidev,
 					const struct pci_device_id *pciid)
 {
 	struct vrc5477_ac97_state *s;
+#ifdef VRC5477_AC97_DEBUG
 	char proc_str[80];
-
-	MIPS_DEBUG(printk("vrc5477_ac97_probe() invoked\n"));
+#endif
 
 	if (pcidev->irq == 0) 
 		return -1;
@@ -1883,6 +1855,13 @@
          * no persistent state across file opens.
 	 */
 
+	/* test if get response from ac97, if not return */
+        if (ac97_codec_not_present(&(s->codec))) {
+		printk(KERN_ERR PFX "no ac97 codec\n");
+		goto err_region;
+
+        }
+
 	if (!request_region(s->io, pci_resource_len(pcidev,0),
 			    VRC5477_AC97_MODULE_NAME)) {
 		printk(KERN_ERR PFX "io ports %#lx->%#lx in use\n",
@@ -1904,37 +1883,27 @@
 	     register_sound_mixer(&vrc5477_ac97_mixer_fops, -1)) < 0)
 		goto err_dev2;
 
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
 	/* intialize the debug proc device */
 	s->ps = create_proc_read_entry(VRC5477_AC97_MODULE_NAME, 0, NULL,
 				       proc_vrc5477_ac97_dump, NULL);
-#endif /* CONFIG_LL_DEBUG */
+#endif /* VRC5477_AC97_DEBUG */
 	
 	/* enable pci io and bus mastering */
 	if (pci_enable_device(pcidev))
 		goto err_dev3;
 	pci_set_master(pcidev);
 
-/*
-jsun_scan_pci_bus();
-vrc5477_show_pci_regs();
-vrc5477_show_pdar_regs();
-*/
-
 	/* cold reset the AC97 */
 	outl(VRC5477_ACLINK_CTRL_RST_ON | VRC5477_ACLINK_CTRL_RST_TIME,
 	     s->io + VRC5477_ACLINK_CTRL);
 	while (inl(s->io + VRC5477_ACLINK_CTRL) & VRC5477_ACLINK_CTRL_RST_ON);
 
-/*
-jsun_ac97_test(s);
-*/
-
 	/* codec init */
 	if (!ac97_probe_codec(&s->codec))
 		goto err_dev3;
 
-#ifdef CONFIG_LL_DEBUG
+#ifdef VRC5477_AC97_DEBUG
 	sprintf(proc_str, "driver/%s/%d/ac97", 
 		VRC5477_AC97_MODULE_NAME, s->codec.id);
 	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
@@ -1942,16 +1911,28 @@
 	/* TODO : why this proc file does not show up? */
 #endif
 
+	/* Try to enable variable rate audio mode. */
+	wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+		rdcodec(&s->codec, AC97_EXTENDED_STATUS) | AC97_EXTSTAT_VRA);
+	/* Did we enable it? */
+	if(rdcodec(&s->codec, AC97_EXTENDED_STATUS) & AC97_EXTSTAT_VRA)
+		s->extended_status |= AC97_EXTSTAT_VRA;
+	else {
+		s->dacRate = 48000;
+		printk(KERN_INFO PFX "VRA mode not enabled; rate fixed at %d.",
+			s->dacRate);
+	}
+
         /* let us get the default volumne louder */
-        wrcodec(&s->codec, 0x2, 0);
-        wrcodec(&s->codec, 0x18, 0x0707);
-	/* mute line in loopback to line out */
-	wrcodec(&s->codec, 0x10, 0x8000);
+        wrcodec(&s->codec, 0x2, 0x1010);	/* master volume, middle */
+        wrcodec(&s->codec, 0xc, 0x10);		/* phone volume, middle */
+        // wrcodec(&s->codec, 0xe, 0x10);		/* misc volume, middle */
+	wrcodec(&s->codec, 0x10, 0x8000);	/* line-in 2 line-out disable */
+        wrcodec(&s->codec, 0x18, 0x0707);	/* PCM out (line out) middle */
+
 
 	/* by default we select line in the input */
 	wrcodec(&s->codec, 0x1a, 0x0404);
-	/* pick middle value for record gain */
-	// wrcodec(&s->codec, 0x1c, 0x0707);
 	wrcodec(&s->codec, 0x1c, 0x0f0f);
 	wrcodec(&s->codec, 0x1e, 0x07);
 
@@ -1989,10 +1970,12 @@
 	if (!s)
 		return;
 	list_del(&s->devs);
-#ifdef CONFIG_LL_DEBUG
+
+#ifdef VRC5477_AC97_DEBUG
 	if (s->ps)
 		remove_proc_entry(VRC5477_AC97_MODULE_NAME, NULL);
-#endif /* CONFIG_LL_DEBUG */
+#endif /* VRC5477_AC97_DEBUG */
+
 	synchronize_irq(s->irq);
 	free_irq(s->irq, s);
 	release_region(s->io, pci_resource_len(dev,0));
@@ -2003,8 +1986,6 @@
 }
 
 
-#define		PCI_VENDOR_ID_NEC		0x1033
-#define		PCI_DEVICE_ID_NEC_VRC5477_AC97	0x00A6
 static struct pci_device_id id_table[] __devinitdata = {
     { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC5477_AC97, 
       PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
@@ -2024,7 +2005,7 @@
 {
 	if (!pci_present())   /* No PCI bus in this machine! */
 		return -ENODEV;
-	printk("Vrc5477 AC97 driver: version v0.1 time " __TIME__ " " __DATE__ " by Jun Sun\n");
+	printk("Vrc5477 AC97 driver: version v0.2 time " __TIME__ " " __DATE__ " by Jun Sun\n");
 	return pci_module_init(&vrc5477_ac97_driver);
 }
 
diff -Nru a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c
--- a/sound/oss/rme96xx.c	Fri Feb 14 15:53:09 2003
+++ b/sound/oss/rme96xx.c	Fri Feb 14 15:53:09 2003
@@ -10,6 +10,17 @@
    *  11 May 2001: 0.4 fixed for SMP, included into kernel source tree
    *  17 May 2001: 0.5 draining code didn't work on new cards
    *  18 May 2001: 0.6 remove synchronize_irq() call 
+   *  17 Jul 2001: 0.7 updated xrmectrl to make it work for newer cards
+   *   2 feb 2002: 0.8 fixed pci device handling, see below for patches from Heiko (Thanks!)
+                       Marcus Meissner <Marcus.Meissner@caldera.de>
+
+		       Modifications - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
+		       HP20020108 fixed handling of "large" read()
+		       HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c
+		       HP20020118 made mixer ioctl and handling of devices>1 more safe
+		       HP20020201 fixed handling of "large" read() properly
+		       added REV 1.5 S/P-DIF receiver support
+		       SNDCTL_DSP_SPEED now returns the actual speed
    *  10 Aug 2002: added synchronize_irq() again
 
 TODO:
@@ -20,15 +31,17 @@
    - mixer mmap interface
    - mixer ioctl
    - get rid of noise upon first open (why ??)
-   - allow multiple open(at least for read)
+   - allow multiple open (at least for read)
    - allow multiple open for non overlapping regions
    - recheck the multiple devices part (offsets of different devices, etc)
    - do decent draining in _release --- done
    - SMP support
+   - what about using fragstotal>2 for small fragsize? (HP20020118)
+   - add support for AFMT_S32_LE
 */
 
 #ifndef RMEVERSION
-#define RMEVERSION "0.6"
+#define RMEVERSION "0.8"
 #endif
 
 #include <linux/version.h>
@@ -41,6 +54,8 @@
 #include <linux/smp_lock.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <asm/dma.h>
+#include <asm/hardirq.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/poll.h>
@@ -134,45 +149,57 @@
 #define RME96xx_F_0          0x0400000 /*  000=64kHz, 100=88.2kHz, 011=96kHz  */
 #define RME96xx_F_1          0x0800000 /*  111=32kHz, 110=44.1kHz, 101=48kHz, */
 
-#define RME96xx_F_2          0x1000000 /*  od external Crystal Chip if ERF=1*/
+#define RME96xx_F_2          0x1000000 /*  001=Rev 1.5+ external Crystal Chip */
 #define RME96xx_ERF          0x2000000 /* Error-Flag of SDPIF Receiver (1=No Lock)*/
 #define RME96xx_buffer_id    0x4000000 /* toggles by each interrupt on rec/play */
 #define RME96xx_tc_valid     0x8000000 /* 1 = a signal is detected on time-code input */
+#define RME96xx_SPDIF_READ  0x10000000 /* byte available from Rev 1.5+ SPDIF interface */
 
 /* Status Register Fields */
 
 #define RME96xx_lock            (RME96xx_lock_0|RME96xx_lock_1|RME96xx_lock_2)
-#define RME96xx_buf_pos          0x000FFC0 
 #define RME96xx_sync            (RME96xx_sync_0|RME96xx_sync_1|RME96xx_sync_2)
 #define RME96xx_F               (RME96xx_F_0|RME96xx_F_1|RME96xx_F_2)
+#define rme96xx_decode_spdif_rate(x) ((x)>>22)
 
+/* Bit 6..15 : h/w buffer pointer */
+#define RME96xx_buf_pos          0x000FFC0 
+/* Bits 31,30,29 are bits 5,4,3 of h/w pointer position on later
+   Rev G EEPROMS and Rev 1.5 cards or later.
+*/ 
+#define RME96xx_REV15_buf_pos(x) ((((x)&0xE0000000)>>26)|((x)&RME96xx_buf_pos))
 
 
 /* Control-Register: */			    
 /*--------------------------------------------------------------------------------*/
 
-#define RME96xx_start_bit	   0x0001    /* start record/play */
-#define RME96xx_latency0	   0x0002    /* Bit 0 -  Buffer size or latency */
-#define RME96xx_latency1	   0x0004    /* Bit 1 - Buffer size or latency */
-#define RME96xx_latency2	   0x0008    /* Bit 2 - Buffer size or latency */
-
-#define RME96xx_Master		   0x0010   /* Clock Mode Master=1,Slave/Auto=0 */
-#define RME96xx_IE		   0x0020   /* Interupt Enable */
-#define RME96xx_freq		   0x0040   /* samplerate 0=44.1/88.2, 1=48/96 kHz*/
-
-
-#define RME96xx_DS                 0x0100   /* Doule Speed 0=44.1/48, 1=88.2/96 Khz */
-#define RME96xx_PRO		   0x0200    /* spdif 0=consumer, 1=professional Mode*/
-#define RME96xx_EMP		   0x0400    /* spdif Emphasis 0=None, 1=ON */
-#define RME96xx_Dolby		   0x0800    /* spdif Non-audio bit 1=set, 0=unset */
-
-#define RME96xx_opt_out	           0x1000  /* Use 1st optical OUT as SPDIF: 1=yes,0=no */
-#define RME96xx_wsel               0x2000  /* use Wordclock as sync (overwrites master)*/
-#define RME96xx_inp_0              0x4000  /* SPDIF-IN: 00=optical (ADAT1),     */
-#define RME96xx_inp_1              0x8000  /* 01=koaxial (Cinch), 10=Internal CDROM*/
-
-#define RME96xx_SyncRef0           0x10000  /* preferred sync-source in autosync */
-#define RME96xx_SyncRef1           0x20000  /* 00=ADAT1,01=ADAT2,10=ADAT3,11=SPDIF */
+#define RME96xx_start_bit	0x0001 /* start record/play */
+#define RME96xx_latency0	0x0002 /* Buffer size / latency */
+#define RME96xx_latency1	0x0004 /*   buffersize = 512Bytes * 2^n */
+#define RME96xx_latency2	0x0008 /*   0=64samples ... 7=8192samples */
+
+#define RME96xx_Master		0x0010 /* Clock Mode 1=Master, 0=Slave/Auto */
+#define RME96xx_IE		0x0020 /* Interupt Enable */
+#define RME96xx_freq		0x0040 /* samplerate 0=44.1/88.2, 1=48/96 kHz*/
+#define RME96xx_freq1		0x0080 /* samplerate 0=32 kHz, 1=other rates ??? (from ALSA, but may be wrong) */
+#define RME96xx_DS              0x0100 /* double speed 0=44.1/48, 1=88.2/96 Khz */
+#define RME96xx_PRO		0x0200 /* SPDIF-OUT 0=consumer, 1=professional */
+#define RME96xx_EMP		0x0400 /* SPDIF-OUT emphasis 0=off, 1=on */
+#define RME96xx_Dolby		0x0800 /* SPDIF-OUT non-audio bit 1=set, 0=unset */
+
+#define RME96xx_opt_out	        0x1000 /* use 1st optical OUT as SPDIF: 1=yes, 0=no */
+#define RME96xx_wsel            0x2000 /* use Wordclock as sync (overwrites master) */
+#define RME96xx_inp_0           0x4000 /* SPDIF-IN 00=optical (ADAT1), */
+#define RME96xx_inp_1           0x8000 /* 01=coaxial (Cinch), 10=internal CDROM */
+
+#define RME96xx_SyncRef0       0x10000 /* preferred sync-source in autosync */
+#define RME96xx_SyncRef1       0x20000 /* 00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */
+
+#define RME96xx_SPDIF_RESET    (1<<18) /* Rev 1.5+: h/w SPDIF receiver */
+#define RME96xx_SPDIF_SELECT   (1<<19)
+#define RME96xx_SPDIF_CLOCK    (1<<20)
+#define RME96xx_SPDIF_WRITE    (1<<21)
+#define RME96xx_ADAT1_INTERNAL (1<<22) /* Rev 1.5+: if set, internal CD connector carries ADAT */
 
 
 #define RME96xx_ctrl_init            (RME96xx_latency0 |\
@@ -186,7 +213,9 @@
 #define RME96xx_latency (RME96xx_latency0|RME96xx_latency1|RME96xx_latency2)
 #define RME96xx_inp         (RME96xx_inp_0|RME96xx_inp_1)
 #define RME96xx_SyncRef    (RME96xx_SyncRef0|RME96xx_SyncRef1)
-/* latency = 512Bytes * 2^n, where n is made from Bit3 ... Bit0 */
+#define RME96xx_mixer_allowed (RME96xx_Master|RME96xx_PRO|RME96xx_EMP|RME96xx_Dolby|RME96xx_opt_out|RME96xx_wsel|RME96xx_inp|RME96xx_SyncRef|RME96xx_ADAT1_INTERNAL)
+
+/* latency = 512Bytes * 2^n, where n is made from Bit3 ... Bit1  (??? HP20020201) */
 
 #define RME96xx_SET_LATENCY(x)   (((x)&0x7)<<1)
 #define RME96xx_GET_LATENCY(x)   (((x)>>1)&0x7)
@@ -211,6 +240,7 @@
 
 
 #define RME96xx_MAX_DEVS 4 /* we provide some OSS stereodevs */
+#define RME96xx_MASK_DEVS 0x3 /* RME96xx_MAX_DEVS-1 */
 
 #define RME_MESS "rme96xx:"
 /*------------------------------------------------------------------------ 
@@ -259,8 +289,10 @@
 
 	u32 thru_bits; /* thru 1=on, 0=off channel 1=Bit1... channel 26= Bit26 */
 
-	int open_count;
+	int hw_rev;             /* h/w rev * 10 (i.e. 1.5 has hw_rev = 15) */
+	char *card_name;	/* hammerfall or hammerfall light names */
 
+	int open_count;         /* unused ???   HP20020201 */
 
 	int rate;
 	int latency;
@@ -324,6 +356,181 @@
 
 }
 
+inline int rme96xx_get_sample_rate_status(rme96xx_info* s)
+{
+	int val;
+	u32 status;
+	status = readl(s->iobase + RME96xx_status_register);
+	val = (status & RME96xx_fs48) ? 48000 : 44100;
+	if (status & RME96xx_DS_rd)
+		val *= 2;
+	return val;
+}
+
+inline int rme96xx_get_sample_rate_ctrl(rme96xx_info* s)
+{
+	int val;
+	val = (s->control_register & RME96xx_freq) ? 48000 : 44100;
+	if (s->control_register & RME96xx_DS)
+		val *= 2;
+	return val;
+}
+
+
+/* code from ALSA card-rme9652.c for rev 1.5 SPDIF receiver   HP 20020201 */
+
+static void rme96xx_spdif_set_bit (rme96xx_info* s, int mask, int onoff)
+{
+	if (onoff) 
+		s->control_register |= mask;
+	else 
+		s->control_register &= ~mask;
+		
+	writel(s->control_register,s->iobase + RME96xx_control_register);
+}
+
+static void rme96xx_spdif_write_byte (rme96xx_info* s, const int val)
+{
+	long mask;
+	long i;
+
+	for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) {
+		if (val & mask)
+			rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 1);
+		else 
+			rme96xx_spdif_set_bit (s, RME96xx_SPDIF_WRITE, 0);
+
+		rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1);
+		rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0);
+	}
+}
+
+static int rme96xx_spdif_read_byte (rme96xx_info* s)
+{
+	long mask;
+	long val;
+	long i;
+
+	val = 0;
+
+	for (i = 0, mask = 0x80;  i < 8; i++, mask >>= 1) {
+		rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 1);
+		if (readl(s->iobase + RME96xx_status_register) & RME96xx_SPDIF_READ)
+			val |= mask;
+		rme96xx_spdif_set_bit (s, RME96xx_SPDIF_CLOCK, 0);
+	}
+
+	return val;
+}
+
+static void rme96xx_write_spdif_codec (rme96xx_info* s, const int address, const int data)
+{
+	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
+	rme96xx_spdif_write_byte (s, 0x20);
+	rme96xx_spdif_write_byte (s, address);
+	rme96xx_spdif_write_byte (s, data);
+	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
+}
+
+
+static int rme96xx_spdif_read_codec (rme96xx_info* s, const int address)
+{
+	int ret;
+
+	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
+	rme96xx_spdif_write_byte (s, 0x20);
+	rme96xx_spdif_write_byte (s, address);
+	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
+	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 1);
+
+	rme96xx_spdif_write_byte (s, 0x21);
+	ret = rme96xx_spdif_read_byte (s);
+	rme96xx_spdif_set_bit (s, RME96xx_SPDIF_SELECT, 0);
+
+	return ret;
+}
+
+static void rme96xx_initialize_spdif_receiver (rme96xx_info* s)
+{
+	/* XXX what unsets this ? */
+	/* no idea ???   HP 20020201 */
+
+	s->control_register |= RME96xx_SPDIF_RESET;
+
+	rme96xx_write_spdif_codec (s, 4, 0x40);
+	rme96xx_write_spdif_codec (s, 17, 0x13);
+	rme96xx_write_spdif_codec (s, 6, 0x02);
+}
+
+static inline int rme96xx_spdif_sample_rate (rme96xx_info *s, int *spdifrate)
+{
+	unsigned int rate_bits;
+
+	*spdifrate = 0x1;
+	if (readl(s->iobase + RME96xx_status_register) & RME96xx_ERF) {
+		return -1;	/* error condition */
+	}
+	
+	if (s->hw_rev == 15) {
+
+		int x, y, ret;
+		
+		x = rme96xx_spdif_read_codec (s, 30);
+
+		if (x != 0) 
+			y = 48000 * 64 / x;
+		else
+			y = 0;
+
+		if      (y > 30400 && y < 33600)  {ret = 32000; *spdifrate = 0x7;}
+		else if (y > 41900 && y < 46000)  {ret = 44100; *spdifrate = 0x6;}
+		else if (y > 46000 && y < 50400)  {ret = 48000; *spdifrate = 0x5;}
+		else if (y > 60800 && y < 67200)  {ret = 64000; *spdifrate = 0x0;}
+		else if (y > 83700 && y < 92000)  {ret = 88200; *spdifrate = 0x4;}
+		else if (y > 92000 && y < 100000) {ret = 96000; *spdifrate = 0x3;}
+		else                              {ret = 0; *spdifrate = 0x1;}
+		return ret;
+	}
+
+	rate_bits = readl(s->iobase + RME96xx_status_register) & RME96xx_F;
+
+	switch (*spdifrate = rme96xx_decode_spdif_rate(rate_bits)) {
+	case 0x7:
+		return 32000;
+		break;
+
+	case 0x6:
+		return 44100;
+		break;
+
+	case 0x5:
+		return 48000;
+		break;
+
+	case 0x4:
+		return 88200;
+		break;
+
+	case 0x3:
+		return 96000;
+		break;
+
+	case 0x0:
+		return 64000;
+		break;
+
+	default:
+		/* was an ALSA warning ...
+		  snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n",
+		  s->card_name, rate_bits);
+		*/
+		return 0;
+		break;
+	}
+}
+
+/* end of code from ALSA card-rme9652.c */
+
 
 
 /* the hwbuf in the status register seems to have some jitter, to get rid of
@@ -662,6 +869,9 @@
 int rme96xx_init(rme96xx_info* s)
 {
 	int i;
+	int status;
+	unsigned short rev;
+
 	DBG(printk(__FUNCTION__"\n"));
 	numcards++;
 
@@ -694,6 +904,56 @@
 		rme96xx_dmabuf_init(s,dma,2*i,2*i);
 	}
 
+	/* code from ALSA card-rme9652.c   HP 20020201 */
+        /* Determine the h/w rev level of the card. This seems like
+	   a particularly kludgy way to encode it, but its what RME
+	   chose to do, so we follow them ...
+	*/
+
+	status = readl(s->iobase + RME96xx_status_register);
+	if (rme96xx_decode_spdif_rate(status&RME96xx_F) == 1) {
+		s->hw_rev = 15;
+	} else {
+		s->hw_rev = 11;
+	}
+
+	/* Differentiate between the standard Hammerfall, and the
+	   "Light", which does not have the expansion board. This
+	   method comes from information received from Mathhias
+	   Clausen at RME. Display the EEPROM and h/w revID where
+	   relevant.  
+	*/
+
+	pci_read_config_word(s->pcidev, PCI_CLASS_REVISION, &rev);
+	switch (rev & 0xff) {
+	case 8: /* original eprom */
+		if (s->hw_rev == 15) {
+			s->card_name = "RME Digi9636 (Rev 1.5)";
+		} else {
+			s->card_name = "RME Digi9636";
+		}
+		break;
+	case 9: /* W36_G EPROM */
+		s->card_name = "RME Digi9636 (Rev G)";
+		break;
+	case 4: /* W52_G EPROM */
+		s->card_name = "RME Digi9652 (Rev G)";
+		break;
+	default:
+	case 3: /* original eprom */
+		if (s->hw_rev == 15) {
+			s->card_name = "RME Digi9652 (Rev 1.5)";
+		} else {
+			s->card_name = "RME Digi9652";
+		}
+		break;
+	}
+
+	printk(KERN_INFO RME_MESS" detected %s (hw_rev %d)\n",s->card_name,s->hw_rev); 
+
+	if (s->hw_rev == 15)
+		rme96xx_initialize_spdif_receiver (s);
+
 	s->started = 0;
 	rme96xx_setlatency(s,7);
 
@@ -734,7 +994,7 @@
 
 	if (pci_enable_device(pcidev))
 		goto err_irq;
-	if (request_irq(s->irq, rme96xx_interrupt, SA_SHIRQ, "es1370", s)) {
+	if (request_irq(s->irq, rme96xx_interrupt, SA_SHIRQ, "rme96xx", s)) {
 		printk(KERN_ERR RME_MESS" irq %u in use\n", s->irq);
 		goto err_irq;
 	}
@@ -836,6 +1096,7 @@
 	if (!pci_present())   /* No PCI bus in this machine! */
 		return -ENODEV;
 	printk(KERN_INFO RME_MESS" version "RMEVERSION" time " __TIME__ " " __DATE__ "\n");
+	devices = ((devices-1) & RME96xx_MASK_DEVS) + 1;
 	printk(KERN_INFO RME_MESS" reserving %d dsp device(s)\n",devices);
         numcards = 0;
 	return pci_module_init(&rme96xx_driver);
@@ -859,13 +1120,11 @@
 ---------------------------------------------------------------------------*/
 
 #define RME96xx_FMT (AFMT_S16_LE|AFMT_U8|AFMT_S32_BLOCKED)
+/* AFTM_U8 is not (yet?) supported ...  HP20020201 */
 
-
-static int rme96xx_ioctl(struct inode *in, struct file *file, 
-						unsigned int cmd, unsigned long arg)
+static int rme96xx_ioctl(struct inode *in, struct file *file, unsigned int cmd, unsigned long arg)
 {
 
-
 	struct dmabuf * dma = (struct dmabuf *)file->private_data; 
 	rme96xx_info *s = dma->s;
 	unsigned long flags;
@@ -918,14 +1177,23 @@
 			case 96000: 
 				rme96xx_set_ctrl(s,RME96xx_freq);
 				break;
+			/* just report current rate as default
+			   e.g. use 0 to "select" current digital input rate
 			default:
 				rme96xx_unset_ctrl(s,RME96xx_freq);
 				val = 44100;
+			*/
 			}
 			if (val > 50000)
 				rme96xx_set_ctrl(s,RME96xx_DS);
 			else
 				rme96xx_unset_ctrl(s,RME96xx_DS);
+			/* set val to actual value  HP 20020201 */
+			/* NOTE: if not "Sync Master", reported rate might be not yet "updated" ... but I don't want to insert a long udelay() here */
+			if ((s->control_register & RME96xx_Master) && !(s->control_register & RME96xx_wsel))
+				val = rme96xx_get_sample_rate_ctrl(s);
+			else
+				val = rme96xx_get_sample_rate_status(s);
 			s->rate = val;
 			spin_unlock_irqrestore(&s->lock, flags);
 		}
@@ -1146,6 +1414,8 @@
 		return 0;
 
         case SOUND_PCM_READ_RATE:
+		/* HP20020201 */
+		s->rate = rme96xx_get_sample_rate_status(s);
 		return put_user(s->rate, (int *)arg);
 
         case SOUND_PCM_READ_CHANNELS:
@@ -1179,28 +1449,29 @@
 {
 	int minor = minor(in->i_rdev);
 	struct list_head *list;
-	int devnum = ((minor-3)/16) % devices; /* default = 0 */
+	int devnum;
 	rme96xx_info *s;
 	struct dmabuf* dma;
 	DECLARE_WAITQUEUE(wait, current); 
 
 	DBG(printk("device num %d open\n",devnum));
 
-/* ??? */
 	for (list = devs.next; ; list = list->next) {
 		if (list == &devs)
 			return -ENODEV;
 		s = list_entry(list, rme96xx_info, devs);
-		if (!((s->dspnum[devnum] ^ minor) & ~0xf)) 
+		for (devnum=0; devnum<devices; devnum++)
+			if (!((s->dspnum[devnum] ^ minor) & ~0xf)) 
+				break;
+		if (devnum<devices)
 			break;
 	}
        	VALIDATE_STATE(s);
-/* ??? */
 
 	dma = &s->dma[devnum];
 	f->private_data = dma;
 	/* wait for device to become free */
-	down(&s->dma[devnum].open_sem);
+	down(&dma->open_sem);
 	while (dma->open_mode & f->f_mode) {
 		if (f->f_flags & O_NONBLOCK) {
 			up(&dma->open_sem);
@@ -1219,11 +1490,11 @@
 
 	COMM                ("hardware open")
 
-	if (!s->dma[devnum].opened) rme96xx_dmabuf_init(dma->s,dma,dma->inoffset,dma->outoffset);
+	if (!dma->opened) rme96xx_dmabuf_init(dma->s,dma,dma->inoffset,dma->outoffset);
 
-	s->dma[devnum].open_mode |= (f->f_mode & (FMODE_READ | FMODE_WRITE));
-	s->dma[devnum].opened = 1;
-	up(&s->dma[devnum].open_sem);
+	dma->open_mode |= (f->f_mode & (FMODE_READ | FMODE_WRITE));
+	dma->opened = 1;
+	up(&dma->open_sem);
 
 	DBG(printk("device num %d open finished\n",devnum));
 	return 0;
@@ -1232,7 +1503,7 @@
 static int rme96xx_release(struct inode *in, struct file *file)
 {
 	struct dmabuf * dma = (struct dmabuf*) file->private_data;
-	/* int hwp; */
+	/* int hwp;  ... was unused   HP20020201 */
 	DBG(printk(__FUNCTION__"\n"));
 
 	COMM          ("draining")
@@ -1261,8 +1532,7 @@
 }
 
 
-static ssize_t rme96xx_write(struct file *file, const char *buffer, 
-									  size_t count, loff_t *ppos)
+static ssize_t rme96xx_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
 {
 	struct dmabuf *dma = (struct dmabuf *)file->private_data;
 	ssize_t ret = 0;
@@ -1296,7 +1566,6 @@
 		dma->readptr = hwp;
 		dma->writeptr = hwp;
 		dma->started = 1;
-		COMM          ("first write done")
 	}
 
   	while (count > 0) {
@@ -1331,11 +1600,11 @@
 	return ret;
 }
 
-static ssize_t rme96xx_read(struct file *file, char *buffer,size_t count, loff_t *ppos)
+static ssize_t rme96xx_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
 { 
 	struct dmabuf *dma = (struct dmabuf *)file->private_data;
 	ssize_t ret = 0;
-	int cnt;
+	int cnt; /* number of bytes from "buffer" that will/can be used */
 	int hop = count/dma->inchannels;
 	int hwp;
 	int exact = (file->f_flags & O_NONBLOCK); 
@@ -1356,9 +1625,6 @@
 	if (! (dma->open_mode  & FMODE_READ))
                 return -ENXIO;
 
-	if (count > ((dma->s->fragsize*dma->inchannels)>>dma->formatshift))
-	    return -EFAULT;
-
 	if (!dma->s->started) rme96xx_startcard(dma->s,exact);
 	hwp = rme96xx_gethwptr(dma->s,0);
 
@@ -1444,7 +1710,7 @@
 
 
 /* this is the mapping */
-
+	vma->vm_flags &= ~VM_IO;
 	dma->mmapped = 1;
 	unlock_kernel();
 	return 0;
@@ -1529,8 +1795,12 @@
 {
 	rme96xx_info *s = (rme96xx_info *)file->private_data;
 	u32 status;
+	int spdifrate;
 
 	status = readl(s->iobase + RME96xx_status_register);
+	/* hack to convert rev 1.5 SPDIF rate to "crystalrate" format   HP 20020201 */
+	rme96xx_spdif_sample_rate(s,&spdifrate);
+	status = (status & ~RME96xx_F) | ((spdifrate<<22) & RME96xx_F);
 
 	VALIDATE_STATE(s);
 	if (cmd == SOUND_MIXER_PRIVATE1) {
@@ -1538,9 +1808,21 @@
 		if (copy_from_user(&mixer,(void*)arg,sizeof(mixer)))
 			return -EFAULT;
 		
-		if (file->f_mode & FMODE_WRITE) {
-		     s->dma[mixer.devnr].outoffset = mixer.o_offset;
-		     s->dma[mixer.devnr].inoffset = mixer.i_offset;
+		mixer.devnr &= RME96xx_MASK_DEVS;
+		if (mixer.devnr >= devices)
+			mixer.devnr = devices-1;
+		if (file->f_mode & FMODE_WRITE && !s->dma[mixer.devnr].opened) {
+			/* modify only if device not open */
+			if (mixer.o_offset < 0)
+				mixer.o_offset = 0;
+			if (mixer.o_offset >= RME96xx_CHANNELS_PER_CARD)
+				mixer.o_offset = RME96xx_CHANNELS_PER_CARD-1;
+			if (mixer.i_offset < 0)
+				mixer.i_offset = 0;
+			if (mixer.i_offset >= RME96xx_CHANNELS_PER_CARD)
+				mixer.i_offset = RME96xx_CHANNELS_PER_CARD-1;
+			s->dma[mixer.devnr].outoffset = mixer.o_offset;
+			s->dma[mixer.devnr].inoffset = mixer.i_offset;
 		}
 
 		mixer.o_offset = s->dma[mixer.devnr].outoffset;
@@ -1552,13 +1834,14 @@
 		return put_user(status, (int *)arg);
 	}
 	if (cmd == SOUND_MIXER_PRIVATE3) {
-	     u32 control;
-	     if (copy_from_user(&control,(void*)arg,sizeof(control)))
-		     return -EFAULT;
-	     if (file->f_mode & FMODE_WRITE) {
-		  s->control_register = control;
-		  writel(control,s->iobase + RME96xx_control_register);
-	     }
+		u32 control;
+		if (copy_from_user(&control,(void*)arg,sizeof(control)))
+			return -EFAULT;
+		if (file->f_mode & FMODE_WRITE) {
+			s->control_register &= ~RME96xx_mixer_allowed;
+			s->control_register |= control & RME96xx_mixer_allowed;
+			writel(control,s->iobase + RME96xx_control_register);
+		}
 
 	     return put_user(s->control_register, (int *)arg);
 	}
diff -Nru a/sound/oss/rme96xx.h b/sound/oss/rme96xx.h
--- a/sound/oss/rme96xx.h	Fri Feb 14 15:53:09 2003
+++ b/sound/oss/rme96xx.h	Fri Feb 14 15:53:09 2003
@@ -1,5 +1,12 @@
 /* (C) 2000 Guenter Geiger <geiger@debian.org>
    with copy/pastes from the driver of Winfried Ritsch <ritsch@iem.kug.ac.at>
+
+Modifications - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
+   HP20020116 towards REV 1.5 support, based on ALSA's card-rme9652.c
+   HP20020201 completed?
+
+A text/graphic control panel (rmectrl/xrmectrl) is available from
+   http://gige.xdv.org/pages/soft/pages/rme
 */
 
 
@@ -7,55 +14,65 @@
 #define AFMT_S32_BLOCKED 0x0000400
 #endif
 
+/* AFMT_S16_BLOCKED not yet supported */
 #ifndef AFMT_S16_BLOCKED 
 #define AFMT_S16_BLOCKED 0x0000800
 #endif
 
 
 typedef struct rme_status {
-     unsigned int irq:1;    /* high or low */
-     unsigned int lockmask:3;  /* ADAT1, ADAT2, ADAT3 */
-     unsigned int sr48:1;   /* current sample rate */
-     unsigned int wclock:1; /* wordclock used ? */
-     unsigned int bufpoint:10;
-
-     unsigned int syncmask:3;  /* ADAT1, ADAT2, ADAT3 */
-     unsigned int doublespeed:1;
-     unsigned int tc_busy:1;
-     unsigned int tc_out:1;
-     unsigned int crystalrate:3;
-     unsigned int spdif_error:1;
-     unsigned int bufid:1;
-     unsigned int tc_valid:1;     
+	unsigned int irq:1;
+	unsigned int lockmask:3;     /* ADAT input PLLs locked */
+	                             /*   100=ADAT1, 010=ADAT2, 001=ADAT3 */
+	unsigned int sr48:1;         /* sample rate: 0=44.1/88.2 1=48/96 kHz */
+	unsigned int wclock:1;       /* 1=wordclock used */
+	unsigned int bufpoint:10;
+	unsigned int syncmask:3;     /* ADAT input in sync with system clock */
+	                             /* 100=ADAT1, 010=ADAT2, 001=ADAT3 */
+	unsigned int doublespeed:1;  /* sample rate: 0=44.1/48 1=88.2/96 kHz */
+	unsigned int tc_busy:1;
+	unsigned int tc_out:1;
+	unsigned int crystalrate:3;  /* spdif input sample rate: */
+	                             /*   000=64kHz, 100=88.2kHz, 011=96kHz */
+	                             /*   111=32kHz, 110=44.1kHz, 101=48kHz */
+	unsigned int spdif_error:1;  /* 1=no spdif lock */
+	unsigned int bufid:1;
+	unsigned int tc_valid:1;     /* 1=timecode input detected */
+	unsigned int spdif_read:1;
 } rme_status_t;
 
 
+/* only fields marked W: can be modified by writing to SOUND_MIXER_PRIVATE3 */
 typedef struct rme_control {
-     unsigned int start:1;
-     unsigned int latency:3;
-
-     unsigned int master:1;
-     unsigned int ie:1;
-     unsigned int sr48:1;
-     unsigned int spare:1;
-
-     unsigned int doublespeed:1;
-     unsigned int pro:1;
-     unsigned int emphasis:1;
-     unsigned int dolby:1;
-
-     unsigned int opt_out:1;
-     unsigned int wordclock:1;
-     unsigned int spdif_in:2;
-
-     unsigned int sync_ref:2;
+	unsigned int start:1;
+	unsigned int latency:3;      /* buffer size / latency [samples]: */
+	                             /*   0=64 ... 7=8192 */
+	unsigned int master:1;       /* W: clock mode: 1=master 0=slave/auto */
+	unsigned int ie:1;
+	unsigned int sr48:1;         /* samplerate 0=44.1/88.2, 1=48/96 kHz */
+	unsigned int spare:1;
+	unsigned int doublespeed:1;  /* double speed 0=44.1/48, 1=88.2/96 Khz */
+	unsigned int pro:1;          /* W: SPDIF-OUT 0=consumer, 1=professional */
+	unsigned int emphasis:1;     /* W: SPDIF-OUT emphasis 0=off, 1=on */
+	unsigned int dolby:1;        /* W: SPDIF-OUT non-audio bit 1=set, 0=unset */
+	unsigned int opt_out:1;      /* W: use 1st optical OUT as SPDIF: 1=yes, 0=no */
+	unsigned int wordclock:1;    /* W: use Wordclock as sync (overwrites master) */
+        unsigned int spdif_in:2;     /* W: SPDIF-IN: */
+                                     /*    00=optical (ADAT1), 01=coaxial (Cinch), 10=internal CDROM */
+	unsigned int sync_ref:2;     /* W: preferred sync-source in autosync */
+                                     /*    00=ADAT1, 01=ADAT2, 10=ADAT3, 11=SPDIF */
+	unsigned int spdif_reset:1;
+	unsigned int spdif_select:1;
+	unsigned int spdif_clock:1;
+	unsigned int spdif_write:1;
+	unsigned int adat1_cd:1;     /* W: Rev 1.5+: if set, internal CD connector carries ADAT */
 } rme_ctrl_t;
 
 
 typedef struct _rme_mixer {
-     int i_offset;
-     int o_offset;
-     int devnr;
-     int spare[8];
+	int i_offset;
+	int o_offset;
+	int devnr;
+	int spare[8];
 } rme_mixer;
 
diff -Nru a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
--- a/sound/oss/vwsnd.c	Fri Feb 14 15:53:10 2003
+++ b/sound/oss/vwsnd.c	Fri Feb 14 15:53:10 2003
@@ -3260,7 +3260,7 @@
 	li_writel(&lith, LI_HOST_CONTROLLER, LI_HC_LINK_ENABLE);
 	do {
 		w = li_readl(&lith, LI_HOST_CONTROLLER);
-	} while (w == LI_HC_LINK_ENABLE && jiffies < later);
+	} while (w == LI_HC_LINK_ENABLE && time_before(jiffies, later));
 	
 	li_destroy(&lith);
 
diff -Nru a/sound/pci/ens1370.c b/sound/pci/ens1370.c
--- a/sound/pci/ens1370.c	Fri Feb 14 15:53:12 2003
+++ b/sound/pci/ens1370.c	Fri Feb 14 15:53:12 2003
@@ -1664,7 +1664,7 @@
 	if (!request_region(ensoniq->gameport.io, 8, "ens137x: gameport")) {
 #define ES___GAMEPORT_LOG_DELAY (30*HZ)
 		// avoid log pollution: limit to 2 infos per minute
-		if (jiffies > last_jiffies + ES___GAMEPORT_LOG_DELAY) {
+		if (time_after(jiffies, last_jiffies + ES___GAMEPORT_LOG_DELAY)) {
 			last_jiffies = jiffies;
 			snd_printk("gameport io port 0x%03x in use", ensoniq->gameport.io);
 		}
diff -Nru a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
--- a/sound/pci/korg1212/korg1212.c	Fri Feb 14 15:53:08 2003
+++ b/sound/pci/korg1212/korg1212.c	Fri Feb 14 15:53:08 2003
@@ -598,7 +598,7 @@
                         return;
                 if (!korg1212->inIRQ)
                         schedule();
-        } while (jiffies < endtime);
+        } while (time_before(jiffies, endtime));
 
         writel(0, &korg1212->sharedBufferPtr->cardCommand);
 }
