diff -ur -x RCS -x *,v proll_14/TODO proll_15/TODO
--- proll_14/TODO	Wed May  2 13:29:08 2001
+++ proll_15/TODO	Sun Dec 23 12:27:27 2001
@@ -1,4 +1,4 @@
-ID14
+ID15
 
  ## Detect flash and adjust /flash-memory properties.
 
@@ -18,3 +18,7 @@
 (Since ID07 there is a stub for this, works ok but not general enough)
 Autoswitching
  ## Cursor in hconsole; make vconsole use it.
+
+ ## Rewrite Gero's UDP/IP with sane buffering arrangement.
+Current code is way to fragile with a lot of assumptions.
+Try to ping the node and observe the result.
diff -ur -x RCS -x *,v proll_14/espr-flash/openprom.c proll_15/espr-flash/openprom.c
--- proll_14/espr-flash/openprom.c	Thu Jun  1 00:14:59 2000
+++ proll_15/espr-flash/openprom.c	Sat Aug  4 15:19:39 2001
@@ -294,12 +294,8 @@
         obp_nextprop	/* char * (*no_nextprop)(int node, char *name); */
 };
 
-static char arg_ro[] = "ro";
-static char arg_root[] = "root=/dev/hda4";	/* XXX Make dynamic... */
-static char arg_norarp[] = "ip=off";		/* XXX Make dynamic... */
-
 static struct linux_arguments_v0 obp_arg = {
-        { "he()", arg_ro, arg_root, arg_norarp, NULL, NULL, NULL, NULL },
+        { "he()", NULL, NULL, NULL, NULL, NULL, NULL, NULL },
 	{ "" },
 	{ 'h', 'e' },  0, 0, 0, NULL,
 	NULL
diff -ur -x RCS -x *,v proll_14/espr-ser-net/openprom.c proll_15/espr-ser-net/openprom.c
--- proll_14/espr-ser-net/openprom.c	Fri Nov 26 08:13:58 1999
+++ proll_15/espr-ser-net/openprom.c	Sun Dec 23 13:04:02 2001
@@ -239,6 +239,21 @@
 	{NULL, NULL, -1}
 };
 
+/*
+ * XXX FIXME: Properties are hardcoded for 8MB SIMM.
+ * If we ever encounter a 16B SIMM, we need to autodetect the size.
+ * Flash chips have Chip ID sequence that can be used for that.
+ */
+static int prop_flash8_regs[] = {
+	0x00000000, 0x20400000, 0x00800000,
+};
+static struct property propv_flash8[] = {
+	{"name",	"flash-memory", sizeof("flash-memory") },
+	{"reg",		(char*)&prop_flash8_regs[0], sizeof(prop_flash8_regs)},
+	{"model",	"AM29LV081", sizeof("AM29LV081") },
+	{NULL, NULL, -1}
+};
+
 
 static struct node nodes[] = {
 	{ &null_properties,	 1,  0 }, /* 0 = big brother of root */
@@ -246,7 +261,7 @@
 	{ propv_pci,		 3,  4 }, /*  2 "/pci" */
 	{ propv_cpu,		 5,  0 }, /*  3 "/MicroSPARC-IIep" */
 	{ propv_ebus,		 6, 10 }, /*  4 "/pci/ebus" */
-	{ propv_aliases,	 0,  0 }, /*  5 "/aliases" */
+	{ propv_aliases,	16,  0 }, /*  5 "/aliases" */
 	{ propv_igs,		 7,  0 }, /*  6 "/pci/igs" */
 	{ propv_hme,		 8,  0 }, /*  7 "/pci/network" */
 	{ propv_isa,		 9,  0 }, /*  8 "/pci/isa" */
@@ -257,6 +272,7 @@
 	{ propv_kd,		14,  0 }, /* 13 "/pci/ebus/8042/keyboard" */
 	{ propv_ms,		 0,  0 }, /* 14 "/pci/ebus/8042/kdmouse" */
 	{ propv_rtc,		 0,  0 }, /* 15 "/pci/ebus/rtc" */
+	{ propv_flash8,		 0,  0 }, /* 16 "/flash-memory" */
 };
 
 static struct linux_mlist_v0 totphys[MAX_BANKS];
@@ -277,8 +293,18 @@
         obp_nextprop	/* char * (*no_nextprop)(int node, char *name); */
 };
 
+#if 0 /* emergency */
+static char arg_ro[] = "ro";
+static char arg_root[] = "root=/dev/hda4";	/* XXX Make dynamic... */
+static char arg_norarp[] = "ip=off";		/* XXX Make dynamic... */
+#endif
+
 static struct linux_arguments_v0 obp_arg = {
+#if 0 /* emergency */
+        { "he()", arg_ro, arg_root, arg_norarp, NULL, NULL, NULL, NULL },
+#else
         { "he()", NULL, NULL, NULL, NULL, NULL, NULL, NULL },
+#endif
 	{ "" },
 	{ 'h', 'e' },  0, 0, 0, NULL,
 	NULL
@@ -439,6 +465,24 @@
 		printk(" A2 %x\n", base0);
 	}
 #endif
+
+	/*
+	 * Enable DMA master for HappyMeal.
+	 * Kernel 2.3.99 does _not_ do it.
+	 */
+	{
+		unsigned where;
+		unsigned devfn = 0x01;
+		unsigned bus = 0;
+		unsigned int cmd;
+
+		where = PCI_COMMAND;
+		st_bp_swap(PHYS_JK_PCI_CFA, CONFIG_CMD(bus,devfn,where));
+		cmd = ldh_bypass(PHYS_JK_PCI_CFD + (where & 7));
+		cmd |= (PCI_COMMAND_MASTER<<8);		/* byte swapped */
+		st_bp_swap(PHYS_JK_PCI_CFA, CONFIG_CMD(bus,devfn,where));
+		sth_bypass(PHYS_JK_PCI_CFD + (where & 7), cmd);
+	}
 
 	return &romvec0;
 }
diff -ur -x RCS -x *,v proll_14/krups/openprom.c proll_15/krups/openprom.c
--- proll_14/krups/openprom.c	Sun Jun 18 14:24:42 2000
+++ proll_15/krups/openprom.c	Sun Dec 23 10:12:21 2001
@@ -280,10 +280,14 @@
         obp_nextprop	/* char * (*no_nextprop)(int node, char *name); */
 };
 
-/* static char arg_sh[] = "init=/bin/bash"; */
+/*
+ * This is required by 2.4.17, according to Ian Chilton.
+ * It should be safe for flash because we override argv[1] in case of SILO.
+ */
+static char arg_nfsroot[] = "ip=bootp root=nfs";
 
 static struct linux_arguments_v0 obp_arg = {
-        { "he()", NULL, NULL, NULL, NULL, NULL, NULL, NULL },
+	{ "he()", arg_nfsroot, NULL, NULL, NULL, NULL, NULL, NULL },
 	{ "" },
 	{ 'h', 'e' },  0, 0, 0, NULL,
 	NULL
diff -ur -x RCS -x *,v proll_14/mrcoffee/openprom.c proll_15/mrcoffee/openprom.c
--- proll_14/mrcoffee/openprom.c	Sun Jun 18 12:27:47 2000
+++ proll_15/mrcoffee/openprom.c	Sun Dec 23 10:21:30 2001
@@ -82,14 +82,23 @@
 	0x2, 0x00240000, 0x00000004,
 	0x2, 0x00280000, 0x00000001,
 };
-static int vbporch = 0x1d;
+
+#if 1	/* Zaitcev */
+static int pixfreq = 0x03dfd240;
 static int hbporch = 0xa0;
+static int vfreq = 0x3c;
+#endif
+#if 0	/* Kevin Boone - 70Hz refresh */
+static int pixfreq = 0x047868C0;
+static int hbporch = 0x90;
+static int vfreq = 0x46;
+#endif
+
+static int vbporch = 0x1d;
 static int vsync = 0x6;
 static int hsync = 0x88;
 static int vfporch = 0x3;
 static int hfporch = 0x18;
-static int pixfreq = 0x03dfd240;
-static int vfreq = 0x3c;
 static int height = 0x300;
 static int width = 0x400;
 static int linebytes = 0x400;
@@ -259,8 +268,10 @@
         obp_nextprop	/* char * (*no_nextprop)(int node, char *name); */
 };
 
+static char arg_nfsroot[] = "ip=bootp root=nfs";
+
 static struct linux_arguments_v0 obp_arg = {
-        { "le()", NULL, NULL, NULL, NULL, NULL, NULL, NULL },
+	{ "le()", arg_nfsroot, NULL, NULL, NULL, NULL, NULL, NULL },
 	{ "" },
 	{ 'l', 'e' },  0, 0, 0, NULL,
 	NULL
diff -ur -x RCS -x *,v proll_14/src/arp.c proll_15/src/arp.c
--- proll_14/src/arp.c	Thu Mar 18 23:04:04 1999
+++ proll_15/src/arp.c	Sun Dec 23 11:55:19 2001
@@ -162,11 +162,12 @@
 	return(NULL);
 
   /* If the destination is not on subnet, send the packets through gateway */
-  if ((ip ^ myipaddr) & mynetmask)
+  if ((ip ^ myipaddr) & mynetmask) {
 	if (def_gw != IP_ANY)
 		ip = def_gw;
 	else
 		return(NULL);
+  }
 
   /* Check if we got the address in the cache already */
   if ((i = findip(ip)) >= 0)
diff -ur -x RCS -x *,v proll_14/src/ip.h proll_15/src/ip.h
--- proll_14/src/ip.h	Wed Mar 10 21:41:42 1999
+++ proll_15/src/ip.h	Sun Dec 23 11:29:37 2001
@@ -72,7 +72,7 @@
  */
 #define IP_TTL		255		/* 255 seconds TTL for each pkt	*/
 #define IP_RECV_SIZE	1024		/* Maximum receive packet size	*/
-#define IP_SEND_SIZE	576		/* Maximum send packet size	*/
+/* #define IP_SEND_SIZE	576 */		/* Maximum send packet size	*/
 
 #define IP_VERSION	4		/* IP version number		*/
 #define IP_MIN_HSIZE	20		/* Minimum size of IP header	*/
diff -ur -x RCS -x *,v proll_14/src/udp.c proll_15/src/udp.c
--- proll_14/src/udp.c	Sun Dec 12 22:36:42 1999
+++ proll_15/src/udp.c	Sun Dec 23 13:01:09 2001
@@ -10,6 +10,7 @@
  **************************************************************************
  *
  * Copyright (C) 1995-1998 Gero Kuhlmann <gero@gkminix.han.de>
+ * Copyright (C) 2001 Pete Zaitcev <zaitcev@yahoo.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
@@ -35,6 +36,24 @@
 #include "./ip.h"
 #include "./udp.h"
 
+/*
+ * An arbitrary constant. The only constraint is to let
+ * the packet and UDP pseudo-header to fit into an Ethernet frame.
+ */
+#define UDP_SEND_SIZE   577
+
+/*
+ * The checksum pseudo-header.
+ */
+struct udp_pseudo {
+  unsigned long ip_saddr;	/* set to iphdr.ip_saddr */
+  unsigned long ip_daddr;	/* set to iphdr.ip_daddr */
+  unsigned char filler;		/* set to 0 */
+  unsigned char ip_protocol;	/* set to iphdr.ip_protocol */
+  unsigned short udp_len;	/* set to udphdr.udp_len */
+};
+
+#define UDP_PSEUDO_LEN   (sizeof(struct udp_pseudo))
 
 /*
  **************************************************************************
@@ -87,10 +106,10 @@
 int            bufsize;
 unsigned char *addr;
 {
-#define ipp ((struct iphdr *)rcvbuf)
-#define udpp ((struct udphdr *)(rcvbuf + IP_MIN_HSIZE))
+  struct iphdr *ipp = ((struct iphdr *)buf);
+  struct udphdr *udpp = ((struct udphdr *)(buf + IP_MIN_HSIZE));
+  struct udp_pseudo psehdr;
 
-  register unsigned char *rcvbuf = buf;
   int size;
   t_ipaddr dadr;
 
@@ -105,6 +124,7 @@
    * of the header must be correct, and the packet should not be frag-
    * mented. The packet should also not be too large, and it has to be
    * a UDP packet, and be destined to the correct port number.
+   * XXX The code does not check the port despite the comment --zaitcev
    */
   size = ntohs(ipp->ip_tot_len) - IP_MIN_HSIZE;
   if (bufsize <= (IP_MIN_HSIZE + sizeof(struct udphdr)) ||
@@ -140,10 +160,31 @@
   udest = ntohs(udpp->udp_source);
   buflen = ntohs(udpp->udp_len) - sizeof(struct udphdr);
   readbuf = (unsigned char *)udpp + sizeof(struct udphdr);
-  return(TRUE);
 
-#undef ipp
-#undef udpp
+  /*
+   * Compute the checksum.
+   */
+  if (udpp->udp_check != 0) {
+    int csum, cslen;
+    unsigned char *p;
+
+    psehdr.ip_saddr = ld4((char *)&ipp->ip_saddr);
+    psehdr.ip_daddr = ld4((char *)&ipp->ip_daddr);
+    psehdr.filler = 0;
+    psehdr.ip_protocol = ipp->ip_protocol;
+    psehdr.udp_len = udpp->udp_len;
+    p = (unsigned char *)udpp - UDP_PSEUDO_LEN;
+    memcpy((char *)p, (char *)&psehdr, UDP_PSEUDO_LEN);
+    cslen = UDP_PSEUDO_LEN + ntohs(udpp->udp_len);
+    if ((csum = ipchksum(p, cslen)) != 0) {
+      unsigned sum0 = ntohs(udpp->udp_check);
+      udpp->udp_check = 0;
+      csum = ipchksum(p, cslen);
+      printf("UDP: bad checksum: host 0x%x our 0x%x\n", sum0, csum);
+    }
+  }
+
+  return(TRUE);
 }
 
 
@@ -185,8 +226,10 @@
 char *buf;
 int   len;
 {
-#define ipp ((struct iphdr *)writebuf)
-#define udpp ((struct udphdr *)(writebuf + IP_MIN_HSIZE))
+  struct iphdr *ipp = (struct iphdr *)writebuf;
+  struct udphdr *udpp = (struct udphdr *)(writebuf + IP_MIN_HSIZE);
+  struct udp_pseudo *psep;
+  int len1;
 
 #ifdef DEBUG
   printf("UDP: sending %d bytes from %ld.%d to %ld.%d (%x:%x:%x:%x:%x:%x)\n",
@@ -198,8 +241,10 @@
    * Copy the packet into the output buffer. It's size should not be larger
    * than maximum UDP packet
    */
-  if (len > UDP_SEND_SIZE)
-	len = UDP_SEND_SIZE;
+  if (len > UDP_SEND_SIZE) {
+    printf("udp_write: too long (%d)\n", len);
+    return 0;
+  }
   memcpy(((char *)udpp) + sizeof(struct udphdr), buf, len);
   len += sizeof(struct udphdr);
 
@@ -209,6 +254,24 @@
   udpp->udp_len = htons(len);
   udpp->udp_check = 0;
 
+  len1 = len;
+  if (len & 1) {
+    ((char *)udpp)[len1] = 0;
+    len1++;
+  }
+  psep = (struct udp_pseudo *) (((char *)udpp) + len1);
+  st4((char *)&psep->ip_saddr, htonl(myipaddr));
+  st4((char *)&psep->ip_daddr, htonl(udaddr));
+  psep->filler = 0;
+  psep->ip_protocol = IPPROTO_UDP;
+  psep->udp_len = htons(len);
+  len1 += UDP_PSEUDO_LEN;
+
+  /* Yep, no htons here: checksup is counted over bytes. */
+  if ((udpp->udp_check = ipchksum((unsigned char *)udpp, len1)) == 0) {
+    udpp->udp_check = 0xffff;
+  }
+
   /* Prepare IP header */
   ipp->ip_ihl_version = ((IP_VERSION << 4) | ((IP_MIN_HSIZE/4) & 0x0f)) & 0xff;
   ipp->ip_tos         = IP_STD_TOS;
@@ -226,11 +289,7 @@
   (void)write_packet(IP_MIN_HSIZE + len, htons(ETH_P_IP), udhw);
 
   return(len);
-
-#undef udpp
-#undef ipp
 }
-
 
 
 /*
diff -ur -x RCS -x *,v proll_14/src/udp.h proll_15/src/udp.h
--- proll_14/src/udp.h	Wed Mar 10 21:41:42 1999
+++ proll_15/src/udp.h	Sun Dec 23 11:30:36 2001
@@ -40,18 +40,6 @@
 };
 
 
-
-/*
- **************************************************************************
- *
- * Maximum size for user datagrams. Note: this assumes no options in the
- * IP header
- */
-#define UDP_SEND_SIZE	(IP_SEND_SIZE - sizeof(struct iphdr) - \
-							sizeof(struct udphdr))
-
-
-
 /*
  **************************************************************************
  *
diff -ur -x RCS -x *,v proll_14/src/version.h proll_15/src/version.h
--- proll_14/src/version.h	Wed May  2 13:36:17 2001
+++ proll_15/src/version.h	Sun Dec 23 10:22:06 2001
@@ -80,4 +80,4 @@
  * Initial revision
  *
  */
-#define PROLL_VERSION_STRING "ID14"	/* Compiles on 2.4 */
+#define PROLL_VERSION_STRING "ID15"
