All of lore.kernel.org
 help / color / mirror / Atom feed
* RE: Does IPTables have a 1:1 port-forwarding capability for a DNAT port-range ?
From: Ranjeet Shetye @ 2002-12-13 17:45 UTC (permalink / raw)
  To: netfilter
In-Reply-To: <3DF9CC70.3080603@istitutocolli.org>


Hi Andrea,

I was hoping that the answer would be "Yes, IPTables can do it", but I
think you are right. As a matter of fact, I have been looking into the
NetFilter code for the last couple of days and I was hoping that I
didn't need to hack the kernel code (cos its not documented). But it
looks like I will have to.

Anyways, I will take my query to the developer-mailing list and post a
reply here once everything is sorted out. In the meantime if anyone has
an architectural overview of Netfilter, one that maps out the
interactions between the various components and layers, I'd really
really like to get my hands on it!

Thanks for your help, Andrea.

Ranjeet Shetye
Senior Software Engineer
Zultys Technologies
771 Vaqueros Avenue
Sunnyvale  CA  94085
USA
Ranjeet.Shetye@Zultys.com
http://www.zultys.com/

 


> -----Original Message-----
> From: netfilter-admin@lists.netfilter.org 
> [mailto:netfilter-admin@lists.netfilter.org] On Behalf Of 
> Andrea Rossato
> Sent: Friday, December 13, 2002 4:03 AM
> To: netfilter@lists.netfilter.org
> Subject: Re: Does IPTables have a 1:1 port-forwarding 
> capability for a DNAT port-range ?
> 
> 
> Ranjeet Shetye wrote:
> > The reason for wanting a 1:1 rule is for X windows and 
> other fat port 
> > ranges. Dont want hundreds of rules in there if one can do the job. 
> > Can IPTables do it ? If so how ? If not, I guess I'll have 
> to get in 
> > touch with the developers for tips on a good starting point.
> 
> I believe that the only way is to hack nat code.
> I will start looking in
> net/ipv4/netfilter/ip_nat_core.c
> and the function manip_pkt that, as far as I understand, is 
> actually writing the NATed packet andrea
> 
> 




^ permalink raw reply

* Re: Intel P6 vs P7 system call performance
From: Margit Schubert-While @ 2002-12-13 17:51 UTC (permalink / raw)
  To: linux-kernel

Well, in the 2.4.x kernels, the P4 gets compiled as a I686 with NO special
treatment :-) (Not even prefetch, because of an ifdef bug)
The P3 at least gets one level of prefetch and the AMD's get special compile
options(arch=k6,athlon), full prefetch and SSE.

 >From Mike Hayward
 >Dual Pentium 4 Xeon 2.4Ghz 2.4.19 kernel 33661.9 lps (10 secs, 6 samples)

Hmm, P4 2.4Ghz , also gcc -O3 -march=i686

margit:/disk03/bytebench-3.1/src # ./hanoi 10
576264 loops
margit:/disk03/bytebench-3.1/src # ./hanoi 10
571001 loops
margit:/disk03/bytebench-3.1/src # ./hanoi 10
571133 loops
margit:/disk03/bytebench-3.1/src # ./hanoi 10
570517 loops
margit:/disk03/bytebench-3.1/src # ./hanoi 10
571019 loops
margit:/disk03/bytebench-3.1/src # ./hanoi 10
582688 loops

Margit 


^ permalink raw reply

* Re: Symlink indirection
From: Richard B. Johnson @ 2002-12-13 17:51 UTC (permalink / raw)
  To: Amos Waterland; +Cc: Jeff Bailey, Andrew Walrond, linux-kernel, libc-alpha
In-Reply-To: <20021213111515.A26218@kvasir.austin.ibm.com>

On Fri, 13 Dec 2002, Amos Waterland wrote:

> I think that you and Richard are dicussing a slightly different issue
> than the original poster asked about.  The original question was:
> 
> On Fri, 13 Dec 2002, Andrew Walrond wrote:
> > Is the number of allowed levels of symlink indirection (if that is the 
> > right phrase; I mean symlink -> symlink -> ... -> file) dependant on the 
> > kernel, or libc ? Where is it defined, and can it be changed?
> 
> To which Richard replied:
> 
> > Since a symlink is just a file containing a name, the resulting path
> > length is simply the maximum path length that user-space tools allow.
> > This should be defined as "PATH_MAX". Posix defines this as 255
> > characters but I think posix requires that this be the minimum and all
> > file-name handling buffers must be at least PATH_MAX in length.
> >
> > A hard link is just another directory-entry for the same file. This,
> > therefore follows the same rules. There must be enough space on the
> > device to contain the number of directory entries, as well as enough
> > buffer length in the tools necessary to manipulate these "nested"
> > directories, which are not really "nested" at all. 
> 
> But Richard is not actually completely correct.  There is a limit of 5
> levels of symlink indirection in vanilla 2.4 series Linux kernels.
> 
>   % touch 0
>   % for i in `seq 1 10`; do ln -s `ls | sort | tail -1` $i; done
>   % ls
>   0  1  10  2  3  4  5  6  7  8  9
>   % cat 5
>   % cat 6
>   cat: 6: Too many levels of symbolic links
>   % strace cat 6 2>&1 | grep 'open("6",'
>   open("6", O_RDONLY|O_LARGEFILE) = -1 ELOOP (Too many levels of symbolic links)
> 
> This has been discussed by Al Viro et al. many times on lkml.  I believe
> that it is not a user-space or POSIX issue, but rather a kernel issue.
> Thanks.
> 
> Amos Waterland
> 

Yep. I thought the original poster was talking about following
the links, i.e., "indirection", rather than creating links which
is "definition".

So, the kernel does set a limit on the number of symlinks of the form,

ln -s a b ; ln -s b c ; ln -s c d ; ln -s d e ; # etc.


Cheers,
Dick Johnson
Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips).
Why is the government concerned about the lunatic fringe? Think about it.



^ permalink raw reply

* [PATCH 2.4.21-BK] Fix typo in arch/arm/config.in
From: Marc-Christian Petersen @ 2002-12-13 17:47 UTC (permalink / raw)
  To: linux-kernel; +Cc: Marcelo Tosatti

[-- Attachment #1: Type: text/plain, Size: 186 bytes --]

Hi Marcelo,

this fixes a typo in arch/arm/config.in.

old:    source drivers/ssi/Config.in
new:	source drivers/scsi/Config.in

 Without it, make menuconfig crashes.

ciao, Marc

[-- Attachment #2: 218_arch-arm-fix-typo.patch --]
[-- Type: text/x-diff, Size: 323 bytes --]

--- linux-old/arch/arm/config.in	2002-12-13 18:42:10.000000000 +0100
+++ linux-wolk4/arch/arm/config.in	2002-12-13 18:42:32.000000000 +0100
@@ -542,7 +542,7 @@
 endmenu
 
 if [ "$CONFIG_ARCH_CLPS711X" = "y" ]; then
-   source drivers/ssi/Config.in
+   source drivers/scsi/Config.in
 fi
 
 source drivers/ieee1394/Config.in

^ permalink raw reply

* RE: Unauthorized Activity Detection using IPTables
From: Ranjeet Shetye @ 2002-12-13 17:39 UTC (permalink / raw)
  To: netfilter
In-Reply-To: <4223A04BF7D1B941A25246ADD0462FF559A362@blr-m3-msg.wipro.com>

[-- Attachment #1: Type: text/plain, Size: 1798 bytes --]

 
I read this and I went "WHOA!"
 
**************************Disclaimer************************************
************
 
Information contained in this E-MAIL being proprietary to Wipro Limited
is 
'privileged' and 'confidential' and intended for use only by the
individual
 or entity to which it is addressed. You are notified that any use,
copying 
or dissemination of the information contained in the E-MAIL in any
manner 
whatsoever is strictly prohibited.
 
************************************************************************
***************

I think I know the comprehensive answer to your query but going by your
disclaimer "any use ... of the information contained in the E-MAIL in
any manner 
whatsoever is strictly prohibited", I cant help you without breaking a
few dozen laws, I guess, unless Ashcroft has passed even more while I
was writing this email. :D
 
Your disclaimers would be appropriate for private emails but I would
suggest that if you are going to be in a public forum then you will
necessarily have to change your disclaimers if you want people to be
able to come forward and help you!
 
take care,
Ranjeet Shetye
Senior Software Engineer
Zultys Technologies
771 Vaqueros Avenue
Sunnyvale  CA  94085
USA
Ranjeet.Shetye@Zultys.com
http://www.zultys.com/
 
-----Original Message-----
From: netfilter-admin@lists.netfilter.org
[mailto:netfilter-admin@lists.netfilter.org] On Behalf Of Amit Kumar
Gupta
Sent: Friday, December 13, 2002 6:44 AM
To: netfilter@lists.netfilter.org
Subject: Unauthorized Activity Detection using IPTables


Hi,
 
 
I want to know how to detect unauthorized activities in firewall using
IPtables.
If any user tries for some unauthorized service, I should be able to log
it and drop it.
 
 
Please give suggestions.
 
Thanks & Regards.
 
Amit

[-- Attachment #2: Type: text/html, Size: 8042 bytes --]

^ permalink raw reply

* Re: oops in the 2.4.20-NFSALL sunrpc code
From: Trond Myklebust @ 2002-12-13 17:39 UTC (permalink / raw)
  To: Ion Badulescu; +Cc: nfs
In-Reply-To: <Pine.LNX.4.44.0212131152280.15305-100000@moisil.badula.org>

>>>>> " " == Ion Badulescu <ionut@badula.org> writes:

     > Hmm... I can see two places where the NULL could be coming
     > from. One is calling rpc_init_task() with clnt==NULL, which
     > appears to be legal since the function checks clnt for NULL:

That would indeed be very borken behaviour, and would blow up in all
sorts of strange places. Feel free to put a BUG_ON() in there.

     > The other one would be rpc_release_task() if somehow an
     > xprt_timer is fired up, spins for a while on xprt->sock_lock,
     > and in the meantime rpc_release_task() is called and it
     > releases the client:

Should be impossible. See 11 lines further up:

        /* Synchronously delete any running timer */
        rpc_delete_timer(task);

Cheers,
  Trond


-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply

* Re: [Linux-ia64] kernel update (relative to 2.4.20)
From: Bjorn Helgaas @ 2002-12-13 17:36 UTC (permalink / raw)
  To: linux-ia64
In-Reply-To: <marc-linux-ia64-105590678205111@msgid-missing>

The linux-2.4.20-ia64-021210 patch broke the ski simulator kernel.
The attached additional patch fixes the problem, and also incorporates
the 2.5 simscsi code that auto-detects the simulated disk size, so you
don't need a 1G image.  Note that I also adopted the 2.5 config
symbols.

Sorry for the inconvenience.

Bjorn


diff -u -urN linux-2.4.20-ia64-021210/arch/ia64/config.in linux-ski/arch/ia64/config.in
--- linux-2.4.20-ia64-021210/arch/ia64/config.in	2002-12-10 14:23:20.000000000 -0700
+++ linux-ski/arch/ia64/config.in	2002-12-13 10:03:28.000000000 -0700
@@ -250,10 +250,10 @@
   mainmenu_option next_comment
   comment 'Simulated drivers'
 
-  bool 'Simulated Ethernet ' CONFIG_SIMETH
-  bool 'Simulated serial driver support' CONFIG_SIM_SERIAL
+  bool 'Simulated Ethernet ' CONFIG_HP_SIMETH
+  bool 'Simulated serial driver support' CONFIG_HP_SIMSERIAL
   if [ "$CONFIG_SCSI" != "n" ]; then
-    bool 'Simulated SCSI disk' CONFIG_SCSI_SIM
+    bool 'Simulated SCSI disk' CONFIG_HP_SIMSCSI
   fi
   endmenu
 fi
diff -u -urN linux-2.4.20-ia64-021210/arch/ia64/hp/sim/Makefile linux-ski/arch/ia64/hp/sim/Makefile
--- linux-2.4.20-ia64-021210/arch/ia64/hp/sim/Makefile	2002-12-10 14:23:20.000000000 -0700
+++ linux-ski/arch/ia64/hp/sim/Makefile	2002-12-13 10:04:07.000000000 -0700
@@ -12,8 +12,4 @@
 obj-y := hpsim_console.o hpsim_irq.o hpsim_setup.o
 obj-$(CONFIG_IA64_GENERIC) += hpsim_machvec.o
 
-obj-$(CONFIG_HP_SIMETH)	+= simeth.o
-obj-$(CONFIG_HP_SIMSERIAL) += simserial.o
-obj-$(CONFIG_HP_SIMSCSI) += simscsi.o
-
 include $(TOPDIR)/Rules.make
diff -u -urN linux-2.4.20-ia64-021210/arch/ia64/hp/sim/simeth.c linux-ski/arch/ia64/hp/sim/simeth.c
--- linux-2.4.20-ia64-021210/arch/ia64/hp/sim/simeth.c	2002-12-10 14:23:20.000000000 -0700
+++ linux-ski/arch/ia64/hp/sim/simeth.c	1969-12-31 17:00:00.000000000 -0700
@@ -1,533 +0,0 @@
-/*
- * Simulated Ethernet Driver
- *
- * Copyright (C) 1999-2001 Hewlett-Packard Co
- * Copyright (C) 1999-2001 Stephane Eranain <eranian@hpl.hp.com>
- */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <linux/notifier.h>
-#include <asm/bitops.h>
-#include <asm/system.h>
-#include <asm/irq.h>
-
-#define SIMETH_RECV_MAX	10
-
-/*
- * Maximum possible received frame for Ethernet.
- * We preallocate an sk_buff of that size to avoid costly 
- * memcpy for temporary buffer into sk_buff. We do basically
- * what's done in other drivers, like eepro with a ring.
- * The difference is, of course, that we don't have real DMA !!!
- */
-#define SIMETH_FRAME_SIZE	ETH_FRAME_LEN	
-
-
-#define SSC_NETDEV_PROBE		100
-#define SSC_NETDEV_SEND			101
-#define SSC_NETDEV_RECV			102
-#define SSC_NETDEV_ATTACH		103
-#define SSC_NETDEV_DETACH		104
-
-#define NETWORK_INTR			8
-
-struct simeth_local {
-	struct net_device_stats stats;
-	int 			simfd;	 /* descriptor in the simulator */
-};
-
-static int simeth_probe1(void);
-static int simeth_open(struct net_device *dev);
-static int simeth_close(struct net_device *dev);
-static int simeth_tx(struct sk_buff *skb, struct net_device *dev);
-static int simeth_rx(struct net_device *dev);
-static struct net_device_stats *simeth_get_stats(struct net_device *dev);
-static void simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs);
-static void set_multicast_list(struct net_device *dev);
-static int simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr);
-
-static char *simeth_version="0.3";
-
-/*
- * This variable is used to establish a mapping between the Linux/ia64 kernel
- * and the host linux kernel.
- *
- * As of today, we support only one card, even though most of the code
- * is ready for many more. The mapping is then:
- *	linux/ia64 -> linux/x86
- * 	   eth0    -> eth1
- *
- * In the future, we some string operations, we could easily support up
- * to 10 cards (0-9).
- *
- * The default mapping can be changed on the kernel command line by
- * specifying simeth=ethX (or whatever string you want).
- */
-static char *simeth_device="eth0";	 /* default host interface to use */
-
-
-
-static volatile unsigned int card_count; /* how many cards "found" so far */
-static int simeth_debug;		/* set to 1 to get debug information */
-
-/*
- * Used to catch IFF_UP & IFF_DOWN events
- */
-static struct notifier_block simeth_dev_notifier = {
-	simeth_device_event,
-	0
-};
-
-
-/*
- * Function used when using a kernel command line option.
- *
- * Format: simeth=interface_name (like eth0)
- */
-static int __init
-simeth_setup(char *str)
-{
-	simeth_device = str;
-	return 1;
-}
-
-__setup("simeth=", simeth_setup);
-
-/*
- * Function used to probe for simeth devices when not installed
- * as a loadable module
- */
-
-int __init
-simeth_probe (void)
-{
-	int r;
-
-	printk("simeth: v%s\n", simeth_version);
-
-	r = simeth_probe1();
-
-	if (r = 0) register_netdevice_notifier(&simeth_dev_notifier);
-
-	return r;
-}
-
-extern long ia64_ssc (long, long, long, long, int);
-extern void ia64_ssc_connect_irq (long intr, long irq);
-
-static inline int
-netdev_probe(char *name, unsigned char *ether)
-{
-	return ia64_ssc(__pa(name), __pa(ether), 0,0, SSC_NETDEV_PROBE);
-}
-
-
-static inline int
-netdev_connect(int irq)
-{
-	/* XXX Fix me
-	 * this does not support multiple cards
-	 * also no return value
-	 */
-	ia64_ssc_connect_irq(NETWORK_INTR, irq);
-	return 0;
-}
-
-static inline int
-netdev_attach(int fd, int irq, unsigned int ipaddr)
-{
-	/* this puts the host interface in the right mode (start interupting) */
-	return ia64_ssc(fd, ipaddr, 0,0, SSC_NETDEV_ATTACH);
-}
-
-
-static inline int
-netdev_detach(int fd)
-{
-	/*
-	 * inactivate the host interface (don't interrupt anymore) */
-	return ia64_ssc(fd, 0,0,0, SSC_NETDEV_DETACH);
-}
-
-static inline int
-netdev_send(int fd, unsigned char *buf, unsigned int len)
-{
-	return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_SEND);
-}
-
-static inline int
-netdev_read(int fd, unsigned char *buf, unsigned int len)
-{
-	return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_RECV);
-}
-
-/*
- * Function shared with module code, so cannot be in init section
- *
- * So far this function "detects" only one card (test_&_set) but could 
- * be extended easily.
- *
- * Return:
- * 	- -ENODEV is no device found
- *	- -ENOMEM is no more memory
- *	- 0 otherwise
- */
-static int
-simeth_probe1(void)
-{
-	unsigned char mac_addr[ETH_ALEN];
-	struct simeth_local *local;
-	struct net_device *dev;
-	int fd, i;
-
-	/*
-	 * XXX Fix me
-	 * let's support just one card for now
-	 */
-	if (test_and_set_bit(0, &card_count))
-		return -ENODEV;
-
-	/*
-	 * check with the simulator for the device
-	 */
-	fd = netdev_probe(simeth_device, mac_addr);
-	if (fd = -1)
-		return -ENODEV;
-
-	dev = init_etherdev(NULL, sizeof(struct simeth_local));
-	if (!dev)
-		return -ENOMEM;
-
-	memcpy(dev->dev_addr, mac_addr, sizeof(mac_addr));
-
-	dev->irq = ia64_alloc_vector();
-
-	/*
-	 * attach the interrupt in the simulator, this does enable interrupts
-	 * until a netdev_attach() is called
-	 */
-	netdev_connect(dev->irq);
-
-	memset(dev->priv, 0, sizeof(struct simeth_local));
-
-	local = dev->priv;
-	local->simfd = fd; /* keep track of underlying file descriptor */
-
-	dev->open		= simeth_open;
-	dev->stop		= simeth_close;
-	dev->hard_start_xmit	= simeth_tx;
-	dev->get_stats		= simeth_get_stats;
-	dev->set_multicast_list = set_multicast_list; /* no yet used */
-
-	/* Fill in the fields of the device structure with ethernet-generic values. */
-	ether_setup(dev);
-
-	printk("%s: hosteth=%s simfd=%d, HwAddr", dev->name, simeth_device, local->simfd);
-	for(i = 0; i < ETH_ALEN; i++) {
-		printk(" %2.2x", dev->dev_addr[i]);
-	}
-	printk(", IRQ %d\n", dev->irq);
-
-		return 0;
-}
-
-/*
- * actually binds the device to an interrupt vector
- */
-static int
-simeth_open(struct net_device *dev)
-{
-	if (request_irq(dev->irq, simeth_interrupt, 0, "simeth", dev)) {
-		printk ("simeth: unable to get IRQ %d.\n", dev->irq);
-		return -EAGAIN;
-	}
-
-	netif_start_queue(dev);
-
-	return 0;
-}
-
-/* copied from lapbether.c */
-static __inline__ int dev_is_ethdev(struct net_device *dev)
-{
-       return ( dev->type = ARPHRD_ETHER && strncmp(dev->name, "dummy", 5));
-}
-
-
-/*
- * Handler for IFF_UP or IFF_DOWN
- *
- * The reason for that is that we don't want to be interrupted when the
- * interface is down. There is no way to unconnect in the simualtor. Instead
- * we use this function to shutdown packet processing in the frame filter 
- * in the simulator. Thus no interrupts are generated
- *
- *
- * That's also the place where we pass the IP address of this device to the
- * simulator so that that we can start filtering packets for it
- *
- * There may be a better way of doing this, but I don't know which yet.
- */
-static int
-simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
-{
-	struct net_device *dev = (struct net_device *)ptr;
-	struct simeth_local *local;
-	struct in_device *in_dev;
-	struct in_ifaddr **ifap = NULL;
-	struct in_ifaddr *ifa = NULL;
-	int r;
-
-
-	if ( ! dev ) {
-		printk(KERN_WARNING "simeth_device_event dev=0\n");
-		return NOTIFY_DONE;
-	}
-
-	if ( event != NETDEV_UP && event != NETDEV_DOWN ) return NOTIFY_DONE;
-
-	/*
-	 * Check whether or not it's for an ethernet device
-	 *
-	 * XXX Fixme: This works only as long as we support one
-	 * type of ethernet device.
-	 */
-	if ( !dev_is_ethdev(dev) ) return NOTIFY_DONE;
-
-	if ((in_devÞv->ip_ptr) != NULL) {
-		for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
-			if (strcmp(dev->name, ifa->ifa_label) = 0) break;
-	}
-	if ( ifa = NULL ) {
-		printk("simeth_open: can't find device %s's ifa\n", dev->name);
-		return NOTIFY_DONE;
-	}
-
-	printk("simeth_device_event: %s ipaddr=0x%x\n", dev->name, htonl(ifa->ifa_local));
-
-	/*
-	 * XXX Fix me
-	 * if the device was up, and we're simply reconfiguring it, not sure
-	 * we get DOWN then UP.
-	 */
-
-	local = dev->priv;
-	/* now do it for real */
-	r = event = NETDEV_UP ? 
-		netdev_attach(local->simfd, dev->irq, htonl(ifa->ifa_local)):
-		netdev_detach(local->simfd);
-
-	printk("simeth: netdev_attach/detach: event=%s ->%d\n", event = NETDEV_UP ? "attach":"detach", r);
-
-	return NOTIFY_DONE;
-}
-
-static int
-simeth_close(struct net_device *dev)
-{
-	netif_stop_queue(dev);
-
-	free_irq(dev->irq, dev);
-
-	return 0;
-}
-
-/*
- * Only used for debug
- */
-static void
-frame_print(unsigned char *from, unsigned char *frame, int len)
-{
-	int i;
-
-	printk("%s: (%d) %02x", from, len, frame[0] & 0xff);
-	for(i=1; i < 6; i++ ) {
-		printk(":%02x", frame[i] &0xff);
-	}
-	printk(" %2x", frame[6] &0xff);
-	for(i=7; i < 12; i++ ) {
-		printk(":%02x", frame[i] &0xff);
-	}
-	printk(" [%02x%02x]\n", frame[12], frame[13]);
-
-	for(i\x14; i < len; i++ ) {
-		printk("%02x ", frame[i] &0xff);
-		if ( (i%10)=0) printk("\n");
-	}
-	printk("\n");
-}
-
-
-/*
- * Function used to transmit of frame, very last one on the path before
- * going to the simulator.
- */
-static int
-simeth_tx(struct sk_buff *skb, struct net_device *dev)
-{
-	struct simeth_local *local = (struct simeth_local *)dev->priv;
-
-#if 0
-	/* ensure we have at least ETH_ZLEN bytes (min frame size) */
-	unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-	/* Where do the extra padding bytes comes from inthe skbuff ? */
-#else
-	/* the real driver in the host system is going to take care of that
-	 * or maybe it's the NIC itself.
-	 */
-	unsigned int length = skb->len;
-#endif
-
-	local->stats.tx_bytes += skb->len;
-	local->stats.tx_packets++;
-
-
-	if (simeth_debug > 5) frame_print("simeth_tx", skb->data, length);
-
-	netdev_send(local->simfd, skb->data, length);
-
-	/*
-	 * we are synchronous on write, so we don't simulate a
-	 * trasnmit complete interrupt, thus we don't need to arm a tx
-	 */
-
-	dev_kfree_skb(skb);
-	return 0;
-}
-
-static inline struct sk_buff * 
-make_new_skb(struct net_device *dev)
-{
-	struct sk_buff *nskb;
-
-	/*
-	 * The +2 is used to make sure that the IP header is nicely
-	 * aligned (on 4byte boundary I assume 14+2\x16)
-	 */
-	nskb = dev_alloc_skb(SIMETH_FRAME_SIZE + 2);
-	if ( nskb = NULL ) {
-		printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name);
-		return NULL;
-	}
-	nskb->dev = dev;
-
-	skb_reserve(nskb, 2);	/* Align IP on 16 byte boundaries */
-
-	skb_put(nskb,SIMETH_FRAME_SIZE);
-
-	return nskb;
-}
-
-/*
- * called from interrupt handler to process a received frame
- */
-static int
-simeth_rx(struct net_device *dev)
-{
-	struct simeth_local	*local;
-	struct sk_buff		*skb;
-	int			len;
-	int			rcv_count = SIMETH_RECV_MAX;
-
-	local = (struct simeth_local *)dev->priv;
-	/*
-	 * the loop concept has been borrowed from other drivers
-	 * looks to me like it's a throttling thing to avoid pushing to many
-	 * packets at one time into the stack. Making sure we can process them
-	 * upstream and make forward progress overall
-	 */
-	do { 
-		if ( (skb=make_new_skb(dev)) = NULL ) {
-			printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name);
-			local->stats.rx_dropped++;
-			return 0;
-		}
-		/*
-		 * Read only one frame at a time
-		 */
-		len = netdev_read(local->simfd, skb->data, SIMETH_FRAME_SIZE);
-		if ( len = 0 ) {
-			if ( simeth_debug > 0 ) printk(KERN_WARNING "%s: count=%d netdev_read=0\n", dev->name, SIMETH_RECV_MAX-rcv_count);
-			break;
-		}
-#if 0
-		/*
-		 * XXX Fix me
-		 * Should really do a csum+copy here
-		 */
-		memcpy(skb->data, frame, len);
-#endif
-		skb->protocol = eth_type_trans(skb, dev);
-
-		if ( simeth_debug > 6 ) frame_print("simeth_rx", skb->data, len);
-
-		/*
-		 * push the packet up & trigger software interrupt
-		 */
-		netif_rx(skb);
-
-		local->stats.rx_packets++;
-		local->stats.rx_bytes += len;
-
-	} while ( --rcv_count );
-
-	return len; /* 0 = nothing left to read, otherwise, we can try again */
-}
-
-/*
- * Interrupt handler (Yes, we can do it too !!!)
- */
-static void
-simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-	struct net_device *dev = dev_id;
-
-	if ( dev = NULL ) {
-		printk(KERN_WARNING "simeth: irq %d for unknown device\n", irq);
-		return;
-	}
-
-	/*
-	 * very simple loop because we get interrupts only when receving
-	 */
-	while (simeth_rx(dev));
-}
-
-static struct net_device_stats *
-simeth_get_stats(struct net_device *dev)
-{
-	struct simeth_local  *local = (struct simeth_local *) dev->priv;
-
-	return &local->stats;
-}
-
-/* fake multicast ability */
-static void
-set_multicast_list(struct net_device *dev)
-{
-	printk(KERN_WARNING "%s: set_multicast_list called\n", dev->name);
-}
-
-#ifdef CONFIG_NET_FASTROUTE
-static int
-simeth_accept_fastpath(struct net_device *dev, struct dst_entry *dst)
-{
-	printk(KERN_WARNING "%s: simeth_accept_fastpath called\n", dev->name);
-	return -1;
-}
-#endif
-
-__initcall(simeth_probe);
diff -u -urN linux-2.4.20-ia64-021210/arch/ia64/hp/sim/simscsi.c linux-ski/arch/ia64/hp/sim/simscsi.c
--- linux-2.4.20-ia64-021210/arch/ia64/hp/sim/simscsi.c	2002-12-10 14:23:20.000000000 -0700
+++ linux-ski/arch/ia64/hp/sim/simscsi.c	1969-12-31 17:00:00.000000000 -0700
@@ -1,384 +0,0 @@
-/*
- * Simulated SCSI driver.
- *
- * Copyright (C) 1999, 2001 Hewlett-Packard Co
- * Copyright (C) 1999, 2001 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
- *
- * 99/12/18 David Mosberger	Added support for READ10/WRITE10 needed by linux v2.3.33
- */
-#include <linux/config.h>
-#include <linux/blk.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-
-#include <scsi/scsi.h>
-
-#include <asm/irq.h>
-
-#include "scsi.h"
-#include "sd.h"
-#include "hosts.h"
-#include "simscsi.h"
-
-#define DEBUG_SIMSCSI	1
-
-/* Simulator system calls: */
-
-#define SSC_OPEN			50
-#define SSC_CLOSE			51
-#define SSC_READ			52
-#define SSC_WRITE			53
-#define SSC_GET_COMPLETION		54
-#define SSC_WAIT_COMPLETION		55
-
-#define SSC_WRITE_ACCESS		2
-#define SSC_READ_ACCESS			1
-
-#ifdef DEBUG_SIMSCSI
-  int simscsi_debug;
-# define DBG	simscsi_debug
-#else
-# define DBG	0
-#endif
-
-#if 0
-struct timer_list disk_timer;
-#else
-static void simscsi_interrupt (unsigned long val);
-DECLARE_TASKLET(simscsi_tasklet, simscsi_interrupt, 0);
-#endif
-
-struct disk_req {
-	unsigned long addr;
-	unsigned len;
-};
-
-struct disk_stat {
-	int fd;
-	unsigned count;
-};
-
-extern long ia64_ssc (long arg0, long arg1, long arg2, long arg3, int nr);
-
-static int desc[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
-
-static struct queue_entry {
-	Scsi_Cmnd *sc;
-} queue[SIMSCSI_REQ_QUEUE_LEN];
-
-static int rd, wr;
-static atomic_t num_reqs = ATOMIC_INIT(0);
-
-/* base name for default disks */
-static char *simscsi_root = DEFAULT_SIMSCSI_ROOT;
-
-#define MAX_ROOT_LEN	128
-
-/*
- * used to setup a new base for disk images
- * to use /foo/bar/disk[a-z] as disk images
- * you have to specify simscsi=/foo/bar/disk on the command line
- */
-static int __init
-simscsi_setup (char *s)
-{
-	/* XXX Fix me we may need to strcpy() ? */
-	if (strlen(s) > MAX_ROOT_LEN) {
-		printk("simscsi_setup: prefix too long---using default %s\n", simscsi_root);
-	}
-	simscsi_root = s;
-	return 1;
-}
-
-__setup("simscsi=", simscsi_setup);
-
-static void
-simscsi_interrupt (unsigned long val)
-{
-	unsigned long flags;
-	Scsi_Cmnd *sc;
-
-	spin_lock_irqsave(&io_request_lock, flags);
-	{
-		while ((sc = queue[rd].sc) != 0) {
-			atomic_dec(&num_reqs);
-			queue[rd].sc = 0;
-			if (DBG)
-				printk("simscsi_interrupt: done with %ld\n", sc->serial_number);
-			(*sc->scsi_done)(sc);
-			rd = (rd + 1) % SIMSCSI_REQ_QUEUE_LEN;
-		}
-	}
-	spin_unlock_irqrestore(&io_request_lock, flags);
-}
-
-int
-simscsi_detect (Scsi_Host_Template *templ)
-{
-	templ->proc_name = "simscsi";
-#if 0
-	init_timer(&disk_timer);
-	disk_timer.function = simscsi_interrupt;
-#endif
-	return 1;	/* fake one SCSI host adapter */
-}
-
-int
-simscsi_release (struct Scsi_Host *host)
-{
-	return 0;	/* this is easy...  */
-}
-
-const char *
-simscsi_info (struct Scsi_Host *host)
-{
-	return "simulated SCSI host adapter";
-}
-
-int
-simscsi_abort (Scsi_Cmnd *cmd)
-{
-	printk ("simscsi_abort: unimplemented\n");
-	return SCSI_ABORT_SUCCESS;
-}
-
-int
-simscsi_reset (Scsi_Cmnd *cmd, unsigned int reset_flags)
-{
-	printk ("simscsi_reset: unimplemented\n");
-	return SCSI_RESET_SUCCESS;
-}
-
-int
-simscsi_biosparam (Disk *disk, kdev_t n, int ip[])
-{
-	int size = disk->capacity;
-
-	ip[0] = 64;
-	ip[1] = 32;
-	ip[2] = size >> 11;
-	return 0;
-}
-
-static void
-simscsi_readwrite (Scsi_Cmnd *sc, int mode, unsigned long offset, unsigned long len)
-{
-	struct disk_stat stat;
-	struct disk_req req;
-
-	req.addr = __pa(sc->request_buffer);
-	req.len  = len;			/* # of bytes to transfer */
-
-	if (sc->request_bufflen < req.len)
-		return;
-
-	stat.fd = desc[sc->target];
-	if (DBG)
-		printk("simscsi_%s @ %lx (off %lx, len %lu) ->",
-		       mode = SSC_READ ? "read":"write", req.addr, offset, len);
-	ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
-	ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
-
-	if (stat.count = req.len) {
-		sc->result = GOOD;
-	} else {
-		sc->result = DID_ERROR << 16;
-	}
-	if (DBG)
-		printk("%d\n", sc->result);
-}
-
-static void
-simscsi_sg_readwrite (Scsi_Cmnd *sc, int mode, unsigned long offset)
-{
-	int list_len = sc->use_sg;
-	struct scatterlist *sl = (struct scatterlist *)sc->buffer;
-	struct disk_stat stat;
-	struct disk_req req;
-
-	stat.fd = desc[sc->target];
-
-	while (list_len) {
-		req.addr = __pa(sl->address);
-		req.len  = sl->length;
-		if (DBG)
-			printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
-			       mode = SSC_READ ? "read":"write", req.addr, offset,
-			       list_len, sl->length);
-		ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
-		ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
-
-		/* should not happen in our case */
-		if (stat.count != req.len) {
-			sc->result = DID_ERROR << 16;
-			return;
-		}
-		offset +=  sl->length;
-		sl++;
-		list_len--;
-	}
-	sc->result = GOOD;
-}
-
-/*
- * function handling both READ_6/WRITE_6 (non-scatter/gather mode)
- * commands.
- * Added 02/26/99 S.Eranian
- */
-static void
-simscsi_readwrite6 (Scsi_Cmnd *sc, int mode)
-{
-	unsigned long offset;
-
-	offset = (((sc->cmnd[1] & 0x1f) << 16) | (sc->cmnd[2] << 8) | sc->cmnd[3])*512;
-	if (sc->use_sg > 0)
-		simscsi_sg_readwrite(sc, mode, offset);
-	else
-		simscsi_readwrite(sc, mode, offset, sc->cmnd[4]*512);
-}
-
-
-static void
-simscsi_readwrite10 (Scsi_Cmnd *sc, int mode)
-{
-	unsigned long offset;
-
-	offset = (  (sc->cmnd[2] << 24) | (sc->cmnd[3] << 16)
-		  | (sc->cmnd[4] <<  8) | (sc->cmnd[5] <<  0))*512;
-	if (sc->use_sg > 0)
-		simscsi_sg_readwrite(sc, mode, offset);
-	else
-		simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512);
-}
-
-int
-simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *))
-{
-	char fname[MAX_ROOT_LEN+16];
-	char *buf;
-#if DEBUG_SIMSCSI
-	register long sp asm ("sp");
-
-	if (DBG)
-		printk("simscsi_queuecommand: target=%d,cmnd=%u,sc=%lu,sp=%lx,done=%p\n",
-		       sc->target, sc->cmnd[0], sc->serial_number, sp, done);
-#endif
-
-	sc->result = DID_BAD_TARGET << 16;
-	sc->scsi_done = done;
-	if (sc->target <= 7 && sc->lun = 0) {
-		switch (sc->cmnd[0]) {
-		      case INQUIRY:
-			if (sc->request_bufflen < 35) {
-				break;
-			}
-			sprintf (fname, "%s%c", simscsi_root, 'a' + sc->target);
-			desc[sc->target] = ia64_ssc (__pa(fname), SSC_READ_ACCESS|SSC_WRITE_ACCESS,
-						     0, 0, SSC_OPEN);
-			if (desc[sc->target] < 0) {
-				/* disk doesn't exist... */
-				break;
-			}
-			buf = sc->request_buffer;
-			buf[0] = 0;	/* magnetic disk */
-			buf[1] = 0;	/* not a removable medium */
-			buf[2] = 2;	/* SCSI-2 compliant device */
-			buf[3] = 2;	/* SCSI-2 response data format */
-			buf[4] = 31;	/* additional length (bytes) */
-			buf[5] = 0;	/* reserved */
-			buf[6] = 0;	/* reserved */
-			buf[7] = 0;	/* various flags */
-			memcpy(buf + 8, "HP      SIMULATED DISK  0.00",  28);
-			sc->result = GOOD;
-			break;
-
-		      case TEST_UNIT_READY:
-			sc->result = GOOD;
-			break;
-
-		      case READ_6:
-			if (desc[sc->target] < 0 )
-				break;
-			simscsi_readwrite6(sc, SSC_READ);
-			break;
-
-		      case READ_10:
-			if (desc[sc->target] < 0 )
-				break;
-			simscsi_readwrite10(sc, SSC_READ);
-			break;
-
-		      case WRITE_6:
-			if (desc[sc->target] < 0)
-				break;
-			simscsi_readwrite6(sc, SSC_WRITE);
-			break;
-
-		      case WRITE_10:
-			if (desc[sc->target] < 0)
-				break;
-			simscsi_readwrite10(sc, SSC_WRITE);
-			break;
-
-
-		      case READ_CAPACITY:
-			if (desc[sc->target] < 0 || sc->request_bufflen < 8) {
-				break;
-			}
-			buf = sc->request_buffer;
-
-			/* pretend to be a 1GB disk (partition table contains real stuff): */
-			buf[0] = 0x00;
-			buf[1] = 0x1f;
-			buf[2] = 0xff;
-			buf[3] = 0xff;
-			/* set block size of 512 bytes: */
-			buf[4] = 0;
-			buf[5] = 0;
-			buf[6] = 2;
-			buf[7] = 0;
-			sc->result = GOOD;
-			break;
-
-		      case MODE_SENSE:
-			printk("MODE_SENSE\n");
-			break;
-
-		      case START_STOP:
-			printk("START_STOP\n");
-			break;
-
-		      default:
-			panic("simscsi: unknown SCSI command %u\n", sc->cmnd[0]);
-		}
-	}
-	if (sc->result = DID_BAD_TARGET) {
-		sc->result |= DRIVER_SENSE << 24;
-		sc->sense_buffer[0] = 0x70;
-		sc->sense_buffer[2] = 0x00;
-	}
-	if (atomic_read(&num_reqs) >= SIMSCSI_REQ_QUEUE_LEN) {
-		panic("Attempt to queue command while command is pending!!");
-	}
-	atomic_inc(&num_reqs);
-	queue[wr].sc = sc;
-	wr = (wr + 1) % SIMSCSI_REQ_QUEUE_LEN;
-
-#if 0
-	if (!timer_pending(&disk_timer)) {
-		disk_timer.expires = jiffies;
-		add_timer(&disk_timer);
-	}
-#else
-	tasklet_schedule(&simscsi_tasklet);
-#endif
-	return 0;
-}
-
-
-static Scsi_Host_Template driver_template = SIMSCSI;
-
-#include "scsi_module.c"
diff -u -urN linux-2.4.20-ia64-021210/arch/ia64/hp/sim/simscsi.h linux-ski/arch/ia64/hp/sim/simscsi.h
--- linux-2.4.20-ia64-021210/arch/ia64/hp/sim/simscsi.h	2002-12-10 14:23:20.000000000 -0700
+++ linux-ski/arch/ia64/hp/sim/simscsi.h	1969-12-31 17:00:00.000000000 -0700
@@ -1,39 +0,0 @@
-/*
- * Simulated SCSI driver.
- *
- * Copyright (C) 1999 Hewlett-Packard Co
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#ifndef SIMSCSI_H
-#define SIMSCSI_H
-
-#define SIMSCSI_REQ_QUEUE_LEN	64
-
-#define DEFAULT_SIMSCSI_ROOT	"/var/ski-disks/sd"
-
-extern int simscsi_detect (Scsi_Host_Template *);
-extern int simscsi_release (struct Scsi_Host *);
-extern const char *simscsi_info (struct Scsi_Host *);
-extern int simscsi_queuecommand (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-extern int simscsi_abort (Scsi_Cmnd *);
-extern int simscsi_reset (Scsi_Cmnd *, unsigned int);
-extern int simscsi_biosparam (Disk *, kdev_t, int[]);
-
-#define SIMSCSI {					\
-	detect:			simscsi_detect,		\
-	release:		simscsi_release,	\
-	info:			simscsi_info,		\
-	queuecommand:		simscsi_queuecommand,	\
-	abort:			simscsi_abort,		\
-	reset:			simscsi_reset,		\
-	bios_param:		simscsi_biosparam,	\
-	can_queue:		SIMSCSI_REQ_QUEUE_LEN,	\
-	this_id:		-1,			\
-	sg_tablesize:		SG_ALL,			\
-	cmd_per_lun:		SIMSCSI_REQ_QUEUE_LEN,	\
-	present:		0,			\
-	unchecked_isa_dma:	0,			\
-	use_clustering:		DISABLE_CLUSTERING	\
-}
-
-#endif /* SIMSCSI_H */
diff -u -urN linux-2.4.20-ia64-021210/arch/ia64/hp/sim/simserial.c linux-ski/arch/ia64/hp/sim/simserial.c
--- linux-2.4.20-ia64-021210/arch/ia64/hp/sim/simserial.c	2002-12-10 14:23:20.000000000 -0700
+++ linux-ski/arch/ia64/hp/sim/simserial.c	1969-12-31 17:00:00.000000000 -0700
@@ -1,1095 +0,0 @@
-/*
- * Simulated Serial Driver (fake serial)
- *
- * This driver is mostly used for bringup purposes and will go away.
- * It has a strong dependency on the system console. All outputs
- * are rerouted to the same facility as the one used by printk which, in our
- * case means sys_sim.c console (goes via the simulator). The code hereafter
- * is completely leveraged from the serial.c driver.
- *
- * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co
- *	Stephane Eranian <eranian@hpl.hp.com>
- *	David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * 02/04/00 D. Mosberger	Merged in serial.c bug fixes in rs_close().
- * 02/25/00 D. Mosberger	Synced up with 2.3.99pre-5 version of serial.c.
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/major.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/console.h>
-#include <linux/module.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/slab.h>
-
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-
-#undef SIMSERIAL_DEBUG	/* define this to get some debug information */
-
-#define KEYBOARD_INTR	3	/* must match with simulator! */
-
-#define NR_PORTS	1	/* only one port for now */
-#define SERIAL_INLINE	1
-
-#ifdef SERIAL_INLINE
-#define _INLINE_ inline
-#endif
-
-#ifndef MIN
-#define MIN(a,b)	((a) < (b) ? (a) : (b))
-#endif
-
-#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
-
-#define SSC_GETCHAR	21
-
-extern long ia64_ssc (long, long, long, long, int);
-extern void ia64_ssc_connect_irq (long intr, long irq);
-
-static char *serial_name = "SimSerial driver";
-static char *serial_version = "0.6";
-
-/*
- * This has been extracted from asm/serial.h. We need one eventually but
- * I don't know exactly what we're going to put in it so just fake one
- * for now.
- */
-#define BASE_BAUD ( 1843200 / 16 )
-
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-
-/*
- * Most of the values here are meaningless to this particular driver.
- * However some values must be preserved for the code (leveraged from serial.c
- * to work correctly).
- * port must not be 0
- * type must not be UNKNOWN
- * So I picked arbitrary (guess from where?) values instead
- */
-static struct serial_state rs_table[NR_PORTS]={
-  /* UART CLK   PORT IRQ     FLAGS        */
-  { 0, BASE_BAUD, 0x3F8, 0, STD_COM_FLAGS,0,PORT_16550 }  /* ttyS0 */
-};
-
-/*
- * Just for the fun of it !
- */
-static struct serial_uart_config uart_config[] = {
-	{ "unknown", 1, 0 },
-	{ "8250", 1, 0 },
-	{ "16450", 1, 0 },
-	{ "16550", 1, 0 },
-	{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO },
-	{ "cirrus", 1, 0 },
-	{ "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH },
-	{ "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |
-		  UART_STARTECH },
-	{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
-	{ 0, 0}
-};
-
-static struct tty_driver serial_driver, callout_driver;
-static int serial_refcount;
-
-static struct async_struct *IRQ_ports[NR_IRQS];
-static struct tty_struct *serial_table[NR_PORTS];
-static struct termios *serial_termios[NR_PORTS];
-static struct termios *serial_termios_locked[NR_PORTS];
-
-static struct console *console;
-
-static unsigned char *tmp_buf;
-static DECLARE_MUTEX(tmp_buf_sem);
-
-extern struct console *console_drivers; /* from kernel/printk.c */
-
-/*
- * ------------------------------------------------------------
- * rs_stop() and rs_start()
- *
- * This routines are called before setting or resetting tty->stopped.
- * They enable or disable transmitter interrupts, as necessary.
- * ------------------------------------------------------------
- */
-static void rs_stop(struct tty_struct *tty)
-{
-#ifdef SIMSERIAL_DEBUG
-	printk("rs_stop: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n",
-		tty->stopped, tty->hw_stopped, tty->flow_stopped);
-#endif
-
-}
-
-static void rs_start(struct tty_struct *tty)
-{
-#if SIMSERIAL_DEBUG
-	printk("rs_start: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n",
-		tty->stopped, tty->hw_stopped, tty->flow_stopped);
-#endif
-}
-
-static  void receive_chars(struct tty_struct *tty, struct pt_regs *regs)
-{
-	unsigned char ch;
-	static unsigned char seen_esc = 0;
-
-	while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) {
-		if ( ch = 27 && seen_esc = 0 ) {
-			seen_esc = 1;
-			continue;
-		} else {
-			if ( seen_esc=1 && ch = 'O' ) {
-				seen_esc = 2;
-				continue;
-			} else if ( seen_esc = 2 ) {
-				if ( ch = 'P' ) show_state();		/* F1 key */
-				if ( ch = 'Q' ) show_buffers();	/* F2 key */
-				seen_esc = 0;
-				continue;
-			}
-		}
-		seen_esc = 0;
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE) break;
-
-		*tty->flip.char_buf_ptr = ch;
-
-		*tty->flip.flag_buf_ptr = 0;
-
-		tty->flip.flag_buf_ptr++;
-		tty->flip.char_buf_ptr++;
-		tty->flip.count++;
-	}
-	tty_flip_buffer_push(tty);
-}
-
-/*
- * This is the serial driver's interrupt routine for a single port
- */
-static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
-{
-	struct async_struct * info;
-
-	/*
-	 * I don't know exactly why they don't use the dev_id opaque data
-	 * pointer instead of this extra lookup table
-	 */
-	info = IRQ_ports[irq];
-	if (!info || !info->tty) {
-		printk("simrs_interrupt_single: info|tty=0 info=%p problem\n", info);
-		return;
-	}
-	/*
-	 * pretty simple in our case, because we only get interrupts
-	 * on inbound traffic
-	 */
-	receive_chars(info->tty, regs);
-}
-
-/*
- * -------------------------------------------------------------------
- * Here ends the serial interrupt routines.
- * -------------------------------------------------------------------
- */
-
-#if 0
-/*
- * not really used in our situation so keep them commented out for now
- */
-static DECLARE_TASK_QUEUE(tq_serial); /* used to be at the top of the file */
-static void do_serial_bh(void)
-{
-	run_task_queue(&tq_serial);
-	printk("do_serial_bh: called\n");
-}
-#endif
-
-static void do_softint(void *private_)
-{
-	printk("simserial: do_softint called\n");
-}
-
-static void rs_put_char(struct tty_struct *tty, unsigned char ch)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-	unsigned long flags;
-
-	if (!tty || !info->xmit.buf) return;
-
-	save_flags(flags); cli();
-	if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) = 0) {
-		restore_flags(flags);
-		return;
-	}
-	info->xmit.buf[info->xmit.head] = ch;
-	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
-	restore_flags(flags);
-}
-
-static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
-{
-	int count;
-	unsigned long flags;
-
-	save_flags(flags); cli();
-
-	if (info->x_char) {
-		char c = info->x_char;
-
-		console->write(console, &c, 1);
-
-		info->state->icount.tx++;
-		info->x_char = 0;
-
-		goto out;
-	}
-
-	if (info->xmit.head = info->xmit.tail || info->tty->stopped || info->tty->hw_stopped) {
-#ifdef SIMSERIAL_DEBUG
-		printk("transmit_chars: head=%d, tail=%d, stopped=%d\n",
-		       info->xmit.head, info->xmit.tail, info->tty->stopped);
-#endif
-		goto out;
-	}
-	/*
-	 * We removed the loop and try to do it in to chunks. We need
-	 * 2 operations maximum because it's a ring buffer.
-	 *
-	 * First from current to tail if possible.
-	 * Then from the beginning of the buffer until necessary
-	 */
-
-	count = MIN(CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE),
-		    SERIAL_XMIT_SIZE - info->xmit.tail);
-	console->write(console, info->xmit.buf+info->xmit.tail, count);
-
-	info->xmit.tail = (info->xmit.tail+count) & (SERIAL_XMIT_SIZE-1);
-
-	/*
-	 * We have more at the beginning of the buffer
-	 */
-	count = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-	if (count) {
-		console->write(console, info->xmit.buf, count);
-		info->xmit.tail += count;
-	}
-out:
-	restore_flags(flags);
-}
-
-static void rs_flush_chars(struct tty_struct *tty)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-
-	if (info->xmit.head = info->xmit.tail || tty->stopped || tty->hw_stopped ||
-	    !info->xmit.buf)
-		return;
-
-	transmit_chars(info, NULL);
-}
-
-
-static int rs_write(struct tty_struct * tty, int from_user,
-		    const unsigned char *buf, int count)
-{
-	int	c, ret = 0;
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-	unsigned long flags;
-
-	if (!tty || !info->xmit.buf || !tmp_buf) return 0;
-
-	save_flags(flags);
-	if (from_user) {
-		down(&tmp_buf_sem);
-		while (1) {
-			int c1;
-			c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-			if (count < c)
-				c = count;
-			if (c <= 0)
-				break;
-
-			c -= copy_from_user(tmp_buf, buf, c);
-			if (!c) {
-				if (!ret)
-					ret = -EFAULT;
-				break;
-			}
-			cli();
-			c1 = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-			if (c1 < c)
-				c = c1;
-			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
-			info->xmit.head = ((info->xmit.head + c) &
-					   (SERIAL_XMIT_SIZE-1));
-			restore_flags(flags);
-			buf += c;
-			count -= c;
-			ret += c;
-		}
-		up(&tmp_buf_sem);
-	} else {
-		cli();
-		while (1) {
-			c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-			if (count < c)
-				c = count;
-			if (c <= 0) {
-				break;
-			}
-			memcpy(info->xmit.buf + info->xmit.head, buf, c);
-			info->xmit.head = ((info->xmit.head + c) &
-					   (SERIAL_XMIT_SIZE-1));
-			buf += c;
-			count -= c;
-			ret += c;
-		}
-		restore_flags(flags);
-	}
-	/*
-	 * Hey, we transmit directly from here in our case
-	 */
-	if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE)
-	    && !tty->stopped && !tty->hw_stopped) {
-		transmit_chars(info, NULL);
-	}
-	return ret;
-}
-
-static int rs_write_room(struct tty_struct *tty)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-
-	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-}
-
-static int rs_chars_in_buffer(struct tty_struct *tty)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-
-	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-}
-
-static void rs_flush_buffer(struct tty_struct *tty)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-	unsigned long flags;
-
-	save_flags(flags); cli();
-	info->xmit.head = info->xmit.tail = 0;
-	restore_flags(flags);
-
-	wake_up_interruptible(&tty->write_wait);
-
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
-}
-
-/*
- * This function is used to send a high-priority XON/XOFF character to
- * the device
- */
-static void rs_send_xchar(struct tty_struct *tty, char ch)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-
-	info->x_char = ch;
-	if (ch) {
-		/*
-		 * I guess we could call console->write() directly but
-		 * let's do that for now.
-		 */
-		transmit_chars(info, NULL);
-	}
-}
-
-/*
- * ------------------------------------------------------------
- * rs_throttle()
- *
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void rs_throttle(struct tty_struct * tty)
-{
-	if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty));
-
-	printk("simrs_throttle called\n");
-}
-
-static void rs_unthrottle(struct tty_struct * tty)
-{
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
-
-	if (I_IXOFF(tty)) {
-		if (info->x_char)
-			info->x_char = 0;
-		else
-			rs_send_xchar(tty, START_CHAR(tty));
-	}
-	printk("simrs_unthrottle called\n");
-}
-
-/*
- * rs_break() --- routine which turns the break handling on or off
- */
-static void rs_break(struct tty_struct *tty, int break_state)
-{
-}
-
-static int rs_ioctl(struct tty_struct *tty, struct file * file,
-		    unsigned int cmd, unsigned long arg)
-{
-	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
-	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
-	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
-		if (tty->flags & (1 << TTY_IO_ERROR))
-		    return -EIO;
-	}
-
-	switch (cmd) {
-		case TIOCMGET:
-			printk("rs_ioctl: TIOCMGET called\n");
-			return -EINVAL;
-		case TIOCMBIS:
-		case TIOCMBIC:
-		case TIOCMSET:
-			printk("rs_ioctl: TIOCMBIS/BIC/SET called\n");
-			return -EINVAL;
-		case TIOCGSERIAL:
-			printk("simrs_ioctl TIOCGSERIAL called\n");
-			return 0;
-		case TIOCSSERIAL:
-			printk("simrs_ioctl TIOCSSERIAL called\n");
-			return 0;
-		case TIOCSERCONFIG:
-			printk("rs_ioctl: TIOCSERCONFIG called\n");
-			return -EINVAL;
-
-		case TIOCSERGETLSR: /* Get line status register */
-			printk("rs_ioctl: TIOCSERGETLSR called\n");
-			return  -EINVAL;
-
-		case TIOCSERGSTRUCT:
-			printk("rs_ioctl: TIOCSERGSTRUCT called\n");
-#if 0
-			if (copy_to_user((struct async_struct *) arg,
-					 info, sizeof(struct async_struct)))
-				return -EFAULT;
-#endif
-			return 0;
-
-		/*
-		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
-		 * - mask passed in arg for lines of interest
-		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
-		 * Caller should use TIOCGICOUNT to see which one it was
-		 */
-		case TIOCMIWAIT:
-			printk("rs_ioctl: TIOCMIWAIT: called\n");
-			return 0;
-		/*
-		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
-		 * Return: write counters to the user passed counter struct
-		 * NB: both 1->0 and 0->1 transitions are counted except for
-		 *     RI where only 0->1 is counted.
-		 */
-		case TIOCGICOUNT:
-			printk("rs_ioctl: TIOCGICOUNT called\n");
-			return 0;
-
-		case TIOCSERGWILD:
-		case TIOCSERSWILD:
-			/* "setserial -W" is called in Debian boot */
-			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
-			return 0;
-
-		default:
-			return -ENOIOCTLCMD;
-		}
-	return 0;
-}
-
-#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
-static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
-{
-	unsigned int cflag = tty->termios->c_cflag;
-
-	if (   (cflag = old_termios->c_cflag)
-	    && (   RELEVANT_IFLAG(tty->termios->c_iflag)
-		= RELEVANT_IFLAG(old_termios->c_iflag)))
-	  return;
-
-
-	/* Handle turning off CRTSCTS */
-	if ((old_termios->c_cflag & CRTSCTS) &&
-	    !(tty->termios->c_cflag & CRTSCTS)) {
-		tty->hw_stopped = 0;
-		rs_start(tty);
-	}
-}
-/*
- * This routine will shutdown a serial port; interrupts are disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
- */
-static void shutdown(struct async_struct * info)
-{
-	unsigned long	flags;
-	struct serial_state *state;
-	int		retval;
-
-	if (!(info->flags & ASYNC_INITIALIZED)) return;
-
-	state = info->state;
-
-#ifdef SIMSERIAL_DEBUG
-	printk("Shutting down serial port %d (irq %d)....", info->line,
-	       state->irq);
-#endif
-
-	save_flags(flags); cli(); /* Disable interrupts */
-
-	/*
-	 * First unlink the serial port from the IRQ chain...
-	 */
-	if (info->next_port)
-		info->next_port->prev_port = info->prev_port;
-	if (info->prev_port)
-		info->prev_port->next_port = info->next_port;
-	else
-		IRQ_ports[state->irq] = info->next_port;
-
-	/*
-	 * Free the IRQ, if necessary
-	 */
-	if (state->irq && (!IRQ_ports[state->irq] ||
-			  !IRQ_ports[state->irq]->next_port)) {
-		if (IRQ_ports[state->irq]) {
-			free_irq(state->irq, NULL);
-			retval = request_irq(state->irq, rs_interrupt_single,
-					     IRQ_T(info), "serial", NULL);
-
-			if (retval)
-				printk("serial shutdown: request_irq: error %d"
-				       "  Couldn't reacquire IRQ.\n", retval);
-		} else
-			free_irq(state->irq, NULL);
-	}
-
-	if (info->xmit.buf) {
-		free_page((unsigned long) info->xmit.buf);
-		info->xmit.buf = 0;
-	}
-
-	if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
-
-	info->flags &= ~ASYNC_INITIALIZED;
-	restore_flags(flags);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_close()
- *
- * This routine is called when the serial port gets closed.  First, we
- * wait for the last remaining data to be sent.  Then, we unlink its
- * async structure from the interrupt chain if necessary, and we free
- * that IRQ if nothing is left in the chain.
- * ------------------------------------------------------------
- */
-static void rs_close(struct tty_struct *tty, struct file * filp)
-{
-	struct async_struct * info = (struct async_struct *)tty->driver_data;
-	struct serial_state *state;
-	unsigned long flags;
-
-	if (!info ) return;
-
-	state = info->state;
-
-	save_flags(flags); cli();
-
-	if (tty_hung_up_p(filp)) {
-#ifdef SIMSERIAL_DEBUG
-		printk("rs_close: hung_up\n");
-#endif
-		MOD_DEC_USE_COUNT;
-		restore_flags(flags);
-		return;
-	}
-#ifdef SIMSERIAL_DEBUG
-	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
-#endif
-	if ((tty->count = 1) && (state->count != 1)) {
-		/*
-		 * Uh, oh.  tty->count is 1, which means that the tty
-		 * structure will be freed.  state->count should always
-		 * be one in these conditions.  If it's greater than
-		 * one, we've got real problems, since it means the
-		 * serial port won't be shutdown.
-		 */
-		printk("rs_close: bad serial port count; tty->count is 1, "
-		       "state->count is %d\n", state->count);
-		state->count = 1;
-	}
-	if (--state->count < 0) {
-		printk("rs_close: bad serial port count for ttys%d: %d\n",
-		       info->line, state->count);
-		state->count = 0;
-	}
-	if (state->count) {
-		MOD_DEC_USE_COUNT;
-		restore_flags(flags);
-		return;
-	}
-	info->flags |= ASYNC_CLOSING;
-	restore_flags(flags);
-
-	/*
-	 * Now we wait for the transmit buffer to clear; and we notify
-	 * the line discipline to only process XON/XOFF characters.
-	 */
-	shutdown(info);
-	if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty);
-	info->event = 0;
-	info->tty = 0;
-	if (info->blocked_open) {
-		if (info->close_delay) {
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(info->close_delay);
-		}
-		wake_up_interruptible(&info->open_wait);
-	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|ASYNC_CLOSING);
-	wake_up_interruptible(&info->close_wait);
-	MOD_DEC_USE_COUNT;
-}
-
-/*
- * rs_wait_until_sent() --- wait until the transmitter is empty
- */
-static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
-{
-}
-
-
-/*
- * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
- */
-static void rs_hangup(struct tty_struct *tty)
-{
-	struct async_struct * info = (struct async_struct *)tty->driver_data;
-	struct serial_state *state = info->state;
-
-#ifdef SIMSERIAL_DEBUG
-	printk("rs_hangup: called\n");
-#endif
-
-	state = info->state;
-
-	rs_flush_buffer(tty);
-	if (info->flags & ASYNC_CLOSING)
-		return;
-	shutdown(info);
-
-	info->event = 0;
-	state->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
-	info->tty = 0;
-	wake_up_interruptible(&info->open_wait);
-}
-
-
-static int get_async_struct(int line, struct async_struct **ret_info)
-{
-	struct async_struct *info;
-	struct serial_state *sstate;
-
-	sstate = rs_table + line;
-	sstate->count++;
-	if (sstate->info) {
-		*ret_info = sstate->info;
-		return 0;
-	}
-	info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
-	if (!info) {
-		sstate->count--;
-		return -ENOMEM;
-	}
-	memset(info, 0, sizeof(struct async_struct));
-	init_waitqueue_head(&info->open_wait);
-	init_waitqueue_head(&info->close_wait);
-	init_waitqueue_head(&info->delta_msr_wait);
-	info->magic = SERIAL_MAGIC;
-	info->port = sstate->port;
-	info->flags = sstate->flags;
-	info->xmit_fifo_size = sstate->xmit_fifo_size;
-	info->line = line;
-	info->tqueue.routine = do_softint;
-	info->tqueue.data = info;
-	info->state = sstate;
-	if (sstate->info) {
-		kfree(info);
-		*ret_info = sstate->info;
-		return 0;
-	}
-	*ret_info = sstate->info = info;
-	return 0;
-}
-
-static int
-startup(struct async_struct *info)
-{
-	unsigned long flags;
-	int	retval=0;
-	void (*handler)(int, void *, struct pt_regs *);
-	struct serial_state *state= info->state;
-	unsigned long page;
-
-	page = get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
-	save_flags(flags); cli();
-
-	if (info->flags & ASYNC_INITIALIZED) {
-		free_page(page);
-		goto errout;
-	}
-
-	if (!state->port || !state->type) {
-		if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
-		free_page(page);
-		goto errout;
-	}
-	if (info->xmit.buf)
-		free_page(page);
-	else
-		info->xmit.buf = (unsigned char *) page;
-
-#ifdef SIMSERIAL_DEBUG
-	printk("startup: ttys%d (irq %d)...", info->line, state->irq);
-#endif
-
-	/*
-	 * Allocate the IRQ if necessary
-	 */
-	if (state->irq && (!IRQ_ports[state->irq] ||
-			  !IRQ_ports[state->irq]->next_port)) {
-		if (IRQ_ports[state->irq]) {
-			retval = -EBUSY;
-			goto errout;
-		} else
-			handler = rs_interrupt_single;
-
-		retval = request_irq(state->irq, handler, IRQ_T(info),
-				     "simserial", NULL);
-		if (retval) {
-			if (capable(CAP_SYS_ADMIN)) {
-				if (info->tty)
-					set_bit(TTY_IO_ERROR,
-						&info->tty->flags);
-				retval = 0;
-			}
-			goto errout;
-		}
-	}
-
-	/*
-	 * Insert serial port into IRQ chain.
-	 */
-	info->prev_port = 0;
-	info->next_port = IRQ_ports[state->irq];
-	if (info->next_port)
-		info->next_port->prev_port = info;
-	IRQ_ports[state->irq] = info;
-
-	if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags);
-
-	info->xmit.head = info->xmit.tail = 0;
-
-#if 0
-	/*
-	 * Set up serial timers...
-	 */
-	timer_table[RS_TIMER].expires = jiffies + 2*HZ/100;
-	timer_active |= 1 << RS_TIMER;
-#endif
-
-	/*
-	 * Set up the tty->alt_speed kludge
-	 */
-	if (info->tty) {
-		if ((info->flags & ASYNC_SPD_MASK) = ASYNC_SPD_HI)
-			info->tty->alt_speed = 57600;
-		if ((info->flags & ASYNC_SPD_MASK) = ASYNC_SPD_VHI)
-			info->tty->alt_speed = 115200;
-		if ((info->flags & ASYNC_SPD_MASK) = ASYNC_SPD_SHI)
-			info->tty->alt_speed = 230400;
-		if ((info->flags & ASYNC_SPD_MASK) = ASYNC_SPD_WARP)
-			info->tty->alt_speed = 460800;
-	}
-
-	info->flags |= ASYNC_INITIALIZED;
-	restore_flags(flags);
-	return 0;
-
-errout:
-	restore_flags(flags);
-	return retval;
-}
-
-
-/*
- * This routine is called whenever a serial port is opened.  It
- * enables interrupts for a serial port, linking in its async structure into
- * the IRQ chain.   It also performs the serial-specific
- * initialization for the tty structure.
- */
-static int rs_open(struct tty_struct *tty, struct file * filp)
-{
-	struct async_struct	*info;
-	int			retval, line;
-	unsigned long		page;
-
-	MOD_INC_USE_COUNT;
-	line = MINOR(tty->device) - tty->driver.minor_start;
-	if ((line < 0) || (line >= NR_PORTS)) {
-		MOD_DEC_USE_COUNT;
-		return -ENODEV;
-	}
-	retval = get_async_struct(line, &info);
-	if (retval) {
-		MOD_DEC_USE_COUNT;
-		return retval;
-	}
-	tty->driver_data = info;
-	info->tty = tty;
-
-#ifdef SIMSERIAL_DEBUG
-	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
-	       info->state->count);
-#endif
-	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
-
-	if (!tmp_buf) {
-		page = get_free_page(GFP_KERNEL);
-		if (!page) {
-			/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
-			return -ENOMEM;
-		}
-		if (tmp_buf)
-			free_page(page);
-		else
-			tmp_buf = (unsigned char *) page;
-	}
-
-	/*
-	 * If the port is the middle of closing, bail out now
-	 */
-	if (tty_hung_up_p(filp) ||
-	    (info->flags & ASYNC_CLOSING)) {
-		if (info->flags & ASYNC_CLOSING)
-			interruptible_sleep_on(&info->close_wait);
-		/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
-#ifdef SERIAL_DO_RESTART
-		return ((info->flags & ASYNC_HUP_NOTIFY) ?
-			-EAGAIN : -ERESTARTSYS);
-#else
-		return -EAGAIN;
-#endif
-	}
-
-	/*
-	 * Start up serial port
-	 */
-	retval = startup(info);
-	if (retval) {
-		/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
-		return retval;
-	}
-
-	if ((info->state->count = 1) &&
-	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver.subtype = SERIAL_TYPE_NORMAL)
-			*tty->termios = info->state->normal_termios;
-		else
-			*tty->termios = info->state->callout_termios;
-	}
-
-	/*
-	 * figure out which console to use (should be one already)
-	 */
-	console = console_drivers;
-	while (console) {
-		if ((console->flags & CON_ENABLED) && console->write) break;
-		console = console->next;
-	}
-
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
-#ifdef SIMSERIAL_DEBUG
-	printk("rs_open ttys%d successful\n", info->line);
-#endif
-	return 0;
-}
-
-/*
- * /proc fs routines....
- */
-
-static inline int line_info(char *buf, struct serial_state *state)
-{
-	return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n",
-		       state->line, uart_config[state->type].name,
-		       state->port, state->irq);
-}
-
-static int rs_read_proc(char *page, char **start, off_t off, int count,
-		 int *eof, void *data)
-{
-	int i, len = 0, l;
-	off_t	begin = 0;
-
-	len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version);
-	for (i = 0; i < NR_PORTS && len < 4000; i++) {
-		l = line_info(page + len, &rs_table[i]);
-		len += l;
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
-	}
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (begin-off);
-	return ((count < begin+len-off) ? count : begin+len-off);
-}
-
-/*
- * ---------------------------------------------------------------------
- * rs_init() and friends
- *
- * rs_init() is called at boot-time to initialize the serial driver.
- * ---------------------------------------------------------------------
- */
-
-/*
- * This routine prints out the appropriate serial driver version
- * number, and identifies which options were configured into this
- * driver.
- */
-static inline void show_serial_version(void)
-{
-	printk(KERN_INFO "%s version %s with", serial_name, serial_version);
-	printk(" no serial options enabled\n");
-}
-
-/*
- * The serial driver boot-time initialization code!
- */
-static int __init
-simrs_init (void)
-{
-	int			i;
-	struct serial_state	*state;
-
-	show_serial_version();
-
-	/* Initialize the tty_driver structure */
-
-	memset(&serial_driver, 0, sizeof(struct tty_driver));
-	serial_driver.magic = TTY_DRIVER_MAGIC;
-	serial_driver.driver_name = "simserial";
-	serial_driver.name = "ttyS";
-	serial_driver.major = TTY_MAJOR;
-	serial_driver.minor_start = 64;
-	serial_driver.num = 1;
-	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
-	serial_driver.subtype = SERIAL_TYPE_NORMAL;
-	serial_driver.init_termios = tty_std_termios;
-	serial_driver.init_termios.c_cflag -		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-	serial_driver.flags = TTY_DRIVER_REAL_RAW;
-	serial_driver.refcount = &serial_refcount;
-	serial_driver.table = serial_table;
-	serial_driver.termios = serial_termios;
-	serial_driver.termios_locked = serial_termios_locked;
-
-	serial_driver.open = rs_open;
-	serial_driver.close = rs_close;
-	serial_driver.write = rs_write;
-	serial_driver.put_char = rs_put_char;
-	serial_driver.flush_chars = rs_flush_chars;
-	serial_driver.write_room = rs_write_room;
-	serial_driver.chars_in_buffer = rs_chars_in_buffer;
-	serial_driver.flush_buffer = rs_flush_buffer;
-	serial_driver.ioctl = rs_ioctl;
-	serial_driver.throttle = rs_throttle;
-	serial_driver.unthrottle = rs_unthrottle;
-	serial_driver.send_xchar = rs_send_xchar;
-	serial_driver.set_termios = rs_set_termios;
-	serial_driver.stop = rs_stop;
-	serial_driver.start = rs_start;
-	serial_driver.hangup = rs_hangup;
-	serial_driver.break_ctl = rs_break;
-	serial_driver.wait_until_sent = rs_wait_until_sent;
-	serial_driver.read_proc = rs_read_proc;
-
-	/*
-	 * Let's have a little bit of fun !
-	 */
-	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
-
-		if (state->type = PORT_UNKNOWN) continue;
-
-		if (!state->irq) {
-			state->irq = ia64_alloc_vector();
-			ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq);
-		}
-
-		printk(KERN_INFO "ttyS%02d at 0x%04lx (irq = %d) is a %s\n",
-		       state->line,
-		       state->port, state->irq,
-		       uart_config[state->type].name);
-	}
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-	callout_driver.name = "cua";
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-
-	if (tty_register_driver(&serial_driver))
-		panic("Couldn't register simserial driver\n");
-
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
-
-	return 0;
-}
-
-#ifndef MODULE
-__initcall(simrs_init);
-#endif
diff -u -urN linux-2.4.20-ia64-021210/drivers/char/Makefile linux-ski/drivers/char/Makefile
--- linux-2.4.20-ia64-021210/drivers/char/Makefile	2002-11-28 16:53:12.000000000 -0700
+++ linux-ski/drivers/char/Makefile	2002-12-13 10:04:07.000000000 -0700
@@ -168,6 +168,7 @@
 obj-$(CONFIG_HIL) += hp_keyb.o
 obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
 obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o
+obj-$(CONFIG_HP_SIMSERIAL) += simserial.o
 obj-$(CONFIG_ROCKETPORT) += rocket.o
 obj-$(CONFIG_MOXA_SMARTIO) += mxser.o
 obj-$(CONFIG_MOXA_INTELLIO) += moxa.o
diff -u -urN linux-2.4.20-ia64-021210/drivers/char/simserial.c linux-ski/drivers/char/simserial.c
--- linux-2.4.20-ia64-021210/drivers/char/simserial.c	1969-12-31 17:00:00.000000000 -0700
+++ linux-ski/drivers/char/simserial.c	2002-12-13 10:04:07.000000000 -0700
@@ -0,0 +1,1095 @@
+/*
+ * Simulated Serial Driver (fake serial)
+ *
+ * This driver is mostly used for bringup purposes and will go away.
+ * It has a strong dependency on the system console. All outputs
+ * are rerouted to the same facility as the one used by printk which, in our
+ * case means sys_sim.c console (goes via the simulator). The code hereafter
+ * is completely leveraged from the serial.c driver.
+ *
+ * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * 02/04/00 D. Mosberger	Merged in serial.c bug fixes in rs_close().
+ * 02/25/00 D. Mosberger	Synced up with 2.3.99pre-5 version of serial.c.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/slab.h>
+
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#undef SIMSERIAL_DEBUG	/* define this to get some debug information */
+
+#define KEYBOARD_INTR	3	/* must match with simulator! */
+
+#define NR_PORTS	1	/* only one port for now */
+#define SERIAL_INLINE	1
+
+#ifdef SERIAL_INLINE
+#define _INLINE_ inline
+#endif
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
+
+#define SSC_GETCHAR	21
+
+extern long ia64_ssc (long, long, long, long, int);
+extern void ia64_ssc_connect_irq (long intr, long irq);
+
+static char *serial_name = "SimSerial driver";
+static char *serial_version = "0.6";
+
+/*
+ * This has been extracted from asm/serial.h. We need one eventually but
+ * I don't know exactly what we're going to put in it so just fake one
+ * for now.
+ */
+#define BASE_BAUD ( 1843200 / 16 )
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+/*
+ * Most of the values here are meaningless to this particular driver.
+ * However some values must be preserved for the code (leveraged from serial.c
+ * to work correctly).
+ * port must not be 0
+ * type must not be UNKNOWN
+ * So I picked arbitrary (guess from where?) values instead
+ */
+static struct serial_state rs_table[NR_PORTS]={
+  /* UART CLK   PORT IRQ     FLAGS        */
+  { 0, BASE_BAUD, 0x3F8, 0, STD_COM_FLAGS,0,PORT_16550 }  /* ttyS0 */
+};
+
+/*
+ * Just for the fun of it !
+ */
+static struct serial_uart_config uart_config[] = {
+	{ "unknown", 1, 0 },
+	{ "8250", 1, 0 },
+	{ "16450", 1, 0 },
+	{ "16550", 1, 0 },
+	{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "cirrus", 1, 0 },
+	{ "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH },
+	{ "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |
+		  UART_STARTECH },
+	{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
+	{ 0, 0}
+};
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+static struct async_struct *IRQ_ports[NR_IRQS];
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+static struct console *console;
+
+static unsigned char *tmp_buf;
+static DECLARE_MUTEX(tmp_buf_sem);
+
+extern struct console *console_drivers; /* from kernel/printk.c */
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_stop: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n",
+		tty->stopped, tty->hw_stopped, tty->flow_stopped);
+#endif
+
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+#if SIMSERIAL_DEBUG
+	printk("rs_start: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n",
+		tty->stopped, tty->hw_stopped, tty->flow_stopped);
+#endif
+}
+
+static  void receive_chars(struct tty_struct *tty, struct pt_regs *regs)
+{
+	unsigned char ch;
+	static unsigned char seen_esc = 0;
+
+	while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) {
+		if ( ch = 27 && seen_esc = 0 ) {
+			seen_esc = 1;
+			continue;
+		} else {
+			if ( seen_esc=1 && ch = 'O' ) {
+				seen_esc = 2;
+				continue;
+			} else if ( seen_esc = 2 ) {
+				if ( ch = 'P' ) show_state();		/* F1 key */
+				if ( ch = 'Q' ) show_buffers();	/* F2 key */
+				seen_esc = 0;
+				continue;
+			}
+		}
+		seen_esc = 0;
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) break;
+
+		*tty->flip.char_buf_ptr = ch;
+
+		*tty->flip.flag_buf_ptr = 0;
+
+		tty->flip.flag_buf_ptr++;
+		tty->flip.char_buf_ptr++;
+		tty->flip.count++;
+	}
+	tty_flip_buffer_push(tty);
+}
+
+/*
+ * This is the serial driver's interrupt routine for a single port
+ */
+static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct async_struct * info;
+
+	/*
+	 * I don't know exactly why they don't use the dev_id opaque data
+	 * pointer instead of this extra lookup table
+	 */
+	info = IRQ_ports[irq];
+	if (!info || !info->tty) {
+		printk("simrs_interrupt_single: info|tty=0 info=%p problem\n", info);
+		return;
+	}
+	/*
+	 * pretty simple in our case, because we only get interrupts
+	 * on inbound traffic
+	 */
+	receive_chars(info->tty, regs);
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+#if 0
+/*
+ * not really used in our situation so keep them commented out for now
+ */
+static DECLARE_TASK_QUEUE(tq_serial); /* used to be at the top of the file */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+	printk("do_serial_bh: called\n");
+}
+#endif
+
+static void do_softint(void *private_)
+{
+	printk("simserial: do_softint called\n");
+}
+
+static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (!tty || !info->xmit.buf) return;
+
+	save_flags(flags); cli();
+	if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) = 0) {
+		restore_flags(flags);
+		return;
+	}
+	info->xmit.buf[info->xmit.head] = ch;
+	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
+	restore_flags(flags);
+}
+
+static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
+{
+	int count;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+
+	if (info->x_char) {
+		char c = info->x_char;
+
+		console->write(console, &c, 1);
+
+		info->state->icount.tx++;
+		info->x_char = 0;
+
+		goto out;
+	}
+
+	if (info->xmit.head = info->xmit.tail || info->tty->stopped || info->tty->hw_stopped) {
+#ifdef SIMSERIAL_DEBUG
+		printk("transmit_chars: head=%d, tail=%d, stopped=%d\n",
+		       info->xmit.head, info->xmit.tail, info->tty->stopped);
+#endif
+		goto out;
+	}
+	/*
+	 * We removed the loop and try to do it in to chunks. We need
+	 * 2 operations maximum because it's a ring buffer.
+	 *
+	 * First from current to tail if possible.
+	 * Then from the beginning of the buffer until necessary
+	 */
+
+	count = MIN(CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE),
+		    SERIAL_XMIT_SIZE - info->xmit.tail);
+	console->write(console, info->xmit.buf+info->xmit.tail, count);
+
+	info->xmit.tail = (info->xmit.tail+count) & (SERIAL_XMIT_SIZE-1);
+
+	/*
+	 * We have more at the beginning of the buffer
+	 */
+	count = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+	if (count) {
+		console->write(console, info->xmit.buf, count);
+		info->xmit.tail += count;
+	}
+out:
+	restore_flags(flags);
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	if (info->xmit.head = info->xmit.tail || tty->stopped || tty->hw_stopped ||
+	    !info->xmit.buf)
+		return;
+
+	transmit_chars(info, NULL);
+}
+
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, ret = 0;
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (!tty || !info->xmit.buf || !tmp_buf) return 0;
+
+	save_flags(flags);
+	if (from_user) {
+		down(&tmp_buf_sem);
+		while (1) {
+			int c1;
+			c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+			cli();
+			c1 = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+			if (c1 < c)
+				c = c1;
+			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		cli();
+		while (1) {
+			c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0) {
+				break;
+			}
+			memcpy(info->xmit.buf + info->xmit.head, buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		restore_flags(flags);
+	}
+	/*
+	 * Hey, we transmit directly from here in our case
+	 */
+	if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE)
+	    && !tty->stopped && !tty->hw_stopped) {
+		transmit_chars(info, NULL);
+	}
+	return ret;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	info->xmit.head = info->xmit.tail = 0;
+	restore_flags(flags);
+
+	wake_up_interruptible(&tty->write_wait);
+
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	info->x_char = ch;
+	if (ch) {
+		/*
+		 * I guess we could call console->write() directly but
+		 * let's do that for now.
+		 */
+		transmit_chars(info, NULL);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ *
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+	if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty));
+
+	printk("simrs_throttle called\n");
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			rs_send_xchar(tty, START_CHAR(tty));
+	}
+	printk("simrs_unthrottle called\n");
+}
+
+/*
+ * rs_break() --- routine which turns the break handling on or off
+ */
+static void rs_break(struct tty_struct *tty, int break_state)
+{
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+
+	switch (cmd) {
+		case TIOCMGET:
+			printk("rs_ioctl: TIOCMGET called\n");
+			return -EINVAL;
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			printk("rs_ioctl: TIOCMBIS/BIC/SET called\n");
+			return -EINVAL;
+		case TIOCGSERIAL:
+			printk("simrs_ioctl TIOCGSERIAL called\n");
+			return 0;
+		case TIOCSSERIAL:
+			printk("simrs_ioctl TIOCSSERIAL called\n");
+			return 0;
+		case TIOCSERCONFIG:
+			printk("rs_ioctl: TIOCSERCONFIG called\n");
+			return -EINVAL;
+
+		case TIOCSERGETLSR: /* Get line status register */
+			printk("rs_ioctl: TIOCSERGETLSR called\n");
+			return  -EINVAL;
+
+		case TIOCSERGSTRUCT:
+			printk("rs_ioctl: TIOCSERGSTRUCT called\n");
+#if 0
+			if (copy_to_user((struct async_struct *) arg,
+					 info, sizeof(struct async_struct)))
+				return -EFAULT;
+#endif
+			return 0;
+
+		/*
+		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		 * - mask passed in arg for lines of interest
+		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		 * Caller should use TIOCGICOUNT to see which one it was
+		 */
+		case TIOCMIWAIT:
+			printk("rs_ioctl: TIOCMIWAIT: called\n");
+			return 0;
+		/*
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+		case TIOCGICOUNT:
+			printk("rs_ioctl: TIOCGICOUNT called\n");
+			return 0;
+
+		case TIOCSERGWILD:
+		case TIOCSERSWILD:
+			/* "setserial -W" is called in Debian boot */
+			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	unsigned int cflag = tty->termios->c_cflag;
+
+	if (   (cflag = old_termios->c_cflag)
+	    && (   RELEVANT_IFLAG(tty->termios->c_iflag)
+		= RELEVANT_IFLAG(old_termios->c_iflag)))
+	  return;
+
+
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+}
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct async_struct * info)
+{
+	unsigned long	flags;
+	struct serial_state *state;
+	int		retval;
+
+	if (!(info->flags & ASYNC_INITIALIZED)) return;
+
+	state = info->state;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("Shutting down serial port %d (irq %d)....", info->line,
+	       state->irq);
+#endif
+
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	/*
+	 * First unlink the serial port from the IRQ chain...
+	 */
+	if (info->next_port)
+		info->next_port->prev_port = info->prev_port;
+	if (info->prev_port)
+		info->prev_port->next_port = info->next_port;
+	else
+		IRQ_ports[state->irq] = info->next_port;
+
+	/*
+	 * Free the IRQ, if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			free_irq(state->irq, NULL);
+			retval = request_irq(state->irq, rs_interrupt_single,
+					     IRQ_T(info), "serial", NULL);
+
+			if (retval)
+				printk("serial shutdown: request_irq: error %d"
+				       "  Couldn't reacquire IRQ.\n", retval);
+		} else
+			free_irq(state->irq, NULL);
+	}
+
+	if (info->xmit.buf) {
+		free_page((unsigned long) info->xmit.buf);
+		info->xmit.buf = 0;
+	}
+
+	if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ *
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state;
+	unsigned long flags;
+
+	if (!info ) return;
+
+	state = info->state;
+
+	save_flags(flags); cli();
+
+	if (tty_hung_up_p(filp)) {
+#ifdef SIMSERIAL_DEBUG
+		printk("rs_close: hung_up\n");
+#endif
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
+#endif
+	if ((tty->count = 1) && (state->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  state->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("rs_close: bad serial port count; tty->count is 1, "
+		       "state->count is %d\n", state->count);
+		state->count = 1;
+	}
+	if (--state->count < 0) {
+		printk("rs_close: bad serial port count for ttys%d: %d\n",
+		       info->line, state->count);
+		state->count = 0;
+	}
+	if (state->count) {
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+	restore_flags(flags);
+
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	shutdown(info);
+	if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty);
+	info->event = 0;
+	info->tty = 0;
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	MOD_DEC_USE_COUNT;
+}
+
+/*
+ * rs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+}
+
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state = info->state;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_hangup: called\n");
+#endif
+
+	state = info->state;
+
+	rs_flush_buffer(tty);
+	if (info->flags & ASYNC_CLOSING)
+		return;
+	shutdown(info);
+
+	info->event = 0;
+	state->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+
+static int get_async_struct(int line, struct async_struct **ret_info)
+{
+	struct async_struct *info;
+	struct serial_state *sstate;
+
+	sstate = rs_table + line;
+	sstate->count++;
+	if (sstate->info) {
+		*ret_info = sstate->info;
+		return 0;
+	}
+	info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
+	if (!info) {
+		sstate->count--;
+		return -ENOMEM;
+	}
+	memset(info, 0, sizeof(struct async_struct));
+	init_waitqueue_head(&info->open_wait);
+	init_waitqueue_head(&info->close_wait);
+	init_waitqueue_head(&info->delta_msr_wait);
+	info->magic = SERIAL_MAGIC;
+	info->port = sstate->port;
+	info->flags = sstate->flags;
+	info->xmit_fifo_size = sstate->xmit_fifo_size;
+	info->line = line;
+	info->tqueue.routine = do_softint;
+	info->tqueue.data = info;
+	info->state = sstate;
+	if (sstate->info) {
+		kfree(info);
+		*ret_info = sstate->info;
+		return 0;
+	}
+	*ret_info = sstate->info = info;
+	return 0;
+}
+
+static int
+startup(struct async_struct *info)
+{
+	unsigned long flags;
+	int	retval=0;
+	void (*handler)(int, void *, struct pt_regs *);
+	struct serial_state *state= info->state;
+	unsigned long page;
+
+	page = get_free_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	save_flags(flags); cli();
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		goto errout;
+	}
+
+	if (!state->port || !state->type) {
+		if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
+		free_page(page);
+		goto errout;
+	}
+	if (info->xmit.buf)
+		free_page(page);
+	else
+		info->xmit.buf = (unsigned char *) page;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("startup: ttys%d (irq %d)...", info->line, state->irq);
+#endif
+
+	/*
+	 * Allocate the IRQ if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			retval = -EBUSY;
+			goto errout;
+		} else
+			handler = rs_interrupt_single;
+
+		retval = request_irq(state->irq, handler, IRQ_T(info),
+				     "simserial", NULL);
+		if (retval) {
+			if (capable(CAP_SYS_ADMIN)) {
+				if (info->tty)
+					set_bit(TTY_IO_ERROR,
+						&info->tty->flags);
+				retval = 0;
+			}
+			goto errout;
+		}
+	}
+
+	/*
+	 * Insert serial port into IRQ chain.
+	 */
+	info->prev_port = 0;
+	info->next_port = IRQ_ports[state->irq];
+	if (info->next_port)
+		info->next_port->prev_port = info;
+	IRQ_ports[state->irq] = info;
+
+	if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->xmit.head = info->xmit.tail = 0;
+
+#if 0
+	/*
+	 * Set up serial timers...
+	 */
+	timer_table[RS_TIMER].expires = jiffies + 2*HZ/100;
+	timer_active |= 1 << RS_TIMER;
+#endif
+
+	/*
+	 * Set up the tty->alt_speed kludge
+	 */
+	if (info->tty) {
+		if ((info->flags & ASYNC_SPD_MASK) = ASYNC_SPD_HI)
+			info->tty->alt_speed = 57600;
+		if ((info->flags & ASYNC_SPD_MASK) = ASYNC_SPD_VHI)
+			info->tty->alt_speed = 115200;
+		if ((info->flags & ASYNC_SPD_MASK) = ASYNC_SPD_SHI)
+			info->tty->alt_speed = 230400;
+		if ((info->flags & ASYNC_SPD_MASK) = ASYNC_SPD_WARP)
+			info->tty->alt_speed = 460800;
+	}
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+
+errout:
+	restore_flags(flags);
+	return retval;
+}
+
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+static int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct	*info;
+	int			retval, line;
+	unsigned long		page;
+
+	MOD_INC_USE_COUNT;
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if ((line < 0) || (line >= NR_PORTS)) {
+		MOD_DEC_USE_COUNT;
+		return -ENODEV;
+	}
+	retval = get_async_struct(line, &info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+	tty->driver_data = info;
+	info->tty = tty;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+	       info->state->count);
+#endif
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+
+	if (!tmp_buf) {
+		page = get_free_page(GFP_KERNEL);
+		if (!page) {
+			/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
+			return -ENOMEM;
+		}
+		if (tmp_buf)
+			free_page(page);
+		else
+			tmp_buf = (unsigned char *) page;
+	}
+
+	/*
+	 * If the port is the middle of closing, bail out now
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+		/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval) {
+		/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
+		return retval;
+	}
+
+	if ((info->state->count = 1) &&
+	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype = SERIAL_TYPE_NORMAL)
+			*tty->termios = info->state->normal_termios;
+		else
+			*tty->termios = info->state->callout_termios;
+	}
+
+	/*
+	 * figure out which console to use (should be one already)
+	 */
+	console = console_drivers;
+	while (console) {
+		if ((console->flags & CON_ENABLED) && console->write) break;
+		console = console->next;
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_open ttys%d successful\n", info->line);
+#endif
+	return 0;
+}
+
+/*
+ * /proc fs routines....
+ */
+
+static inline int line_info(char *buf, struct serial_state *state)
+{
+	return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n",
+		       state->line, uart_config[state->type].name,
+		       state->port, state->irq);
+}
+
+static int rs_read_proc(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	int i, len = 0, l;
+	off_t	begin = 0;
+
+	len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version);
+	for (i = 0; i < NR_PORTS && len < 4000; i++) {
+		l = line_info(page + len, &rs_table[i]);
+		len += l;
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (begin-off);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * rs_init() and friends
+ *
+ * rs_init() is called at boot-time to initialize the serial driver.
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * This routine prints out the appropriate serial driver version
+ * number, and identifies which options were configured into this
+ * driver.
+ */
+static inline void show_serial_version(void)
+{
+	printk(KERN_INFO "%s version %s with", serial_name, serial_version);
+	printk(" no serial options enabled\n");
+}
+
+/*
+ * The serial driver boot-time initialization code!
+ */
+static int __init
+simrs_init (void)
+{
+	int			i;
+	struct serial_state	*state;
+
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+	serial_driver.driver_name = "simserial";
+	serial_driver.name = "ttyS";
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64;
+	serial_driver.num = 1;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag +		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.put_char = rs_put_char;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.send_xchar = rs_send_xchar;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+	serial_driver.break_ctl = rs_break;
+	serial_driver.wait_until_sent = rs_wait_until_sent;
+	serial_driver.read_proc = rs_read_proc;
+
+	/*
+	 * Let's have a little bit of fun !
+	 */
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+
+		if (state->type = PORT_UNKNOWN) continue;
+
+		if (!state->irq) {
+			state->irq = ia64_alloc_vector();
+			ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq);
+		}
+
+		printk(KERN_INFO "ttyS%02d at 0x%04lx (irq = %d) is a %s\n",
+		       state->line,
+		       state->port, state->irq,
+		       uart_config[state->type].name);
+	}
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+	callout_driver.name = "cua";
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	callout_driver.read_proc = 0;
+	callout_driver.proc_entry = 0;
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register simserial driver\n");
+
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+
+	return 0;
+}
+
+#ifndef MODULE
+__initcall(simrs_init);
+#endif
diff -u -urN linux-2.4.20-ia64-021210/drivers/net/Makefile linux-ski/drivers/net/Makefile
--- linux-2.4.20-ia64-021210/drivers/net/Makefile	2002-11-28 16:53:13.000000000 -0700
+++ linux-ski/drivers/net/Makefile	2002-12-13 10:04:07.000000000 -0700
@@ -142,6 +142,7 @@
 obj-$(CONFIG_LNE390) += lne390.o 8390.o
 obj-$(CONFIG_NE3210) += ne3210.o 8390.o
 obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o
+obj-$(CONFIG_HP_SIMETH) += simeth.o
 
 obj-$(CONFIG_PPP) += ppp_generic.o slhc.o
 obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
diff -u -urN linux-2.4.20-ia64-021210/drivers/net/simeth.c linux-ski/drivers/net/simeth.c
--- linux-2.4.20-ia64-021210/drivers/net/simeth.c	1969-12-31 17:00:00.000000000 -0700
+++ linux-ski/drivers/net/simeth.c	2002-12-13 10:04:07.000000000 -0700
@@ -0,0 +1,533 @@
+/*
+ * Simulated Ethernet Driver
+ *
+ * Copyright (C) 1999-2001 Hewlett-Packard Co
+ * Copyright (C) 1999-2001 Stephane Eranain <eranian@hpl.hp.com>
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/in.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <linux/skbuff.h>
+#include <linux/notifier.h>
+#include <asm/bitops.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+
+#define SIMETH_RECV_MAX	10
+
+/*
+ * Maximum possible received frame for Ethernet.
+ * We preallocate an sk_buff of that size to avoid costly 
+ * memcpy for temporary buffer into sk_buff. We do basically
+ * what's done in other drivers, like eepro with a ring.
+ * The difference is, of course, that we don't have real DMA !!!
+ */
+#define SIMETH_FRAME_SIZE	ETH_FRAME_LEN	
+
+
+#define SSC_NETDEV_PROBE		100
+#define SSC_NETDEV_SEND			101
+#define SSC_NETDEV_RECV			102
+#define SSC_NETDEV_ATTACH		103
+#define SSC_NETDEV_DETACH		104
+
+#define NETWORK_INTR			8
+
+struct simeth_local {
+	struct net_device_stats stats;
+	int 			simfd;	 /* descriptor in the simulator */
+};
+
+static int simeth_probe1(void);
+static int simeth_open(struct net_device *dev);
+static int simeth_close(struct net_device *dev);
+static int simeth_tx(struct sk_buff *skb, struct net_device *dev);
+static int simeth_rx(struct net_device *dev);
+static struct net_device_stats *simeth_get_stats(struct net_device *dev);
+static void simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static void set_multicast_list(struct net_device *dev);
+static int simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr);
+
+static char *simeth_version="0.3";
+
+/*
+ * This variable is used to establish a mapping between the Linux/ia64 kernel
+ * and the host linux kernel.
+ *
+ * As of today, we support only one card, even though most of the code
+ * is ready for many more. The mapping is then:
+ *	linux/ia64 -> linux/x86
+ * 	   eth0    -> eth1
+ *
+ * In the future, we some string operations, we could easily support up
+ * to 10 cards (0-9).
+ *
+ * The default mapping can be changed on the kernel command line by
+ * specifying simeth=ethX (or whatever string you want).
+ */
+static char *simeth_device="eth0";	 /* default host interface to use */
+
+
+
+static volatile unsigned int card_count; /* how many cards "found" so far */
+static int simeth_debug;		/* set to 1 to get debug information */
+
+/*
+ * Used to catch IFF_UP & IFF_DOWN events
+ */
+static struct notifier_block simeth_dev_notifier = {
+	simeth_device_event,
+	0
+};
+
+
+/*
+ * Function used when using a kernel command line option.
+ *
+ * Format: simeth=interface_name (like eth0)
+ */
+static int __init
+simeth_setup(char *str)
+{
+	simeth_device = str;
+	return 1;
+}
+
+__setup("simeth=", simeth_setup);
+
+/*
+ * Function used to probe for simeth devices when not installed
+ * as a loadable module
+ */
+
+int __init
+simeth_probe (void)
+{
+	int r;
+
+	printk("simeth: v%s\n", simeth_version);
+
+	r = simeth_probe1();
+
+	if (r = 0) register_netdevice_notifier(&simeth_dev_notifier);
+
+	return r;
+}
+
+extern long ia64_ssc (long, long, long, long, int);
+extern void ia64_ssc_connect_irq (long intr, long irq);
+
+static inline int
+netdev_probe(char *name, unsigned char *ether)
+{
+	return ia64_ssc(__pa(name), __pa(ether), 0,0, SSC_NETDEV_PROBE);
+}
+
+
+static inline int
+netdev_connect(int irq)
+{
+	/* XXX Fix me
+	 * this does not support multiple cards
+	 * also no return value
+	 */
+	ia64_ssc_connect_irq(NETWORK_INTR, irq);
+	return 0;
+}
+
+static inline int
+netdev_attach(int fd, int irq, unsigned int ipaddr)
+{
+	/* this puts the host interface in the right mode (start interupting) */
+	return ia64_ssc(fd, ipaddr, 0,0, SSC_NETDEV_ATTACH);
+}
+
+
+static inline int
+netdev_detach(int fd)
+{
+	/*
+	 * inactivate the host interface (don't interrupt anymore) */
+	return ia64_ssc(fd, 0,0,0, SSC_NETDEV_DETACH);
+}
+
+static inline int
+netdev_send(int fd, unsigned char *buf, unsigned int len)
+{
+	return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_SEND);
+}
+
+static inline int
+netdev_read(int fd, unsigned char *buf, unsigned int len)
+{
+	return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_RECV);
+}
+
+/*
+ * Function shared with module code, so cannot be in init section
+ *
+ * So far this function "detects" only one card (test_&_set) but could 
+ * be extended easily.
+ *
+ * Return:
+ * 	- -ENODEV is no device found
+ *	- -ENOMEM is no more memory
+ *	- 0 otherwise
+ */
+static int
+simeth_probe1(void)
+{
+	unsigned char mac_addr[ETH_ALEN];
+	struct simeth_local *local;
+	struct net_device *dev;
+	int fd, i;
+
+	/*
+	 * XXX Fix me
+	 * let's support just one card for now
+	 */
+	if (test_and_set_bit(0, &card_count))
+		return -ENODEV;
+
+	/*
+	 * check with the simulator for the device
+	 */
+	fd = netdev_probe(simeth_device, mac_addr);
+	if (fd = -1)
+		return -ENODEV;
+
+	dev = init_etherdev(NULL, sizeof(struct simeth_local));
+	if (!dev)
+		return -ENOMEM;
+
+	memcpy(dev->dev_addr, mac_addr, sizeof(mac_addr));
+
+	dev->irq = ia64_alloc_vector();
+
+	/*
+	 * attach the interrupt in the simulator, this does enable interrupts
+	 * until a netdev_attach() is called
+	 */
+	netdev_connect(dev->irq);
+
+	memset(dev->priv, 0, sizeof(struct simeth_local));
+
+	local = dev->priv;
+	local->simfd = fd; /* keep track of underlying file descriptor */
+
+	dev->open		= simeth_open;
+	dev->stop		= simeth_close;
+	dev->hard_start_xmit	= simeth_tx;
+	dev->get_stats		= simeth_get_stats;
+	dev->set_multicast_list = set_multicast_list; /* no yet used */
+
+	/* Fill in the fields of the device structure with ethernet-generic values. */
+	ether_setup(dev);
+
+	printk("%s: hosteth=%s simfd=%d, HwAddr", dev->name, simeth_device, local->simfd);
+	for(i = 0; i < ETH_ALEN; i++) {
+		printk(" %2.2x", dev->dev_addr[i]);
+	}
+	printk(", IRQ %d\n", dev->irq);
+
+		return 0;
+}
+
+/*
+ * actually binds the device to an interrupt vector
+ */
+static int
+simeth_open(struct net_device *dev)
+{
+	if (request_irq(dev->irq, simeth_interrupt, 0, "simeth", dev)) {
+		printk ("simeth: unable to get IRQ %d.\n", dev->irq);
+		return -EAGAIN;
+	}
+
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+/* copied from lapbether.c */
+static __inline__ int dev_is_ethdev(struct net_device *dev)
+{
+       return ( dev->type = ARPHRD_ETHER && strncmp(dev->name, "dummy", 5));
+}
+
+
+/*
+ * Handler for IFF_UP or IFF_DOWN
+ *
+ * The reason for that is that we don't want to be interrupted when the
+ * interface is down. There is no way to unconnect in the simualtor. Instead
+ * we use this function to shutdown packet processing in the frame filter 
+ * in the simulator. Thus no interrupts are generated
+ *
+ *
+ * That's also the place where we pass the IP address of this device to the
+ * simulator so that that we can start filtering packets for it
+ *
+ * There may be a better way of doing this, but I don't know which yet.
+ */
+static int
+simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
+{
+	struct net_device *dev = (struct net_device *)ptr;
+	struct simeth_local *local;
+	struct in_device *in_dev;
+	struct in_ifaddr **ifap = NULL;
+	struct in_ifaddr *ifa = NULL;
+	int r;
+
+
+	if ( ! dev ) {
+		printk(KERN_WARNING "simeth_device_event dev=0\n");
+		return NOTIFY_DONE;
+	}
+
+	if ( event != NETDEV_UP && event != NETDEV_DOWN ) return NOTIFY_DONE;
+
+	/*
+	 * Check whether or not it's for an ethernet device
+	 *
+	 * XXX Fixme: This works only as long as we support one
+	 * type of ethernet device.
+	 */
+	if ( !dev_is_ethdev(dev) ) return NOTIFY_DONE;
+
+	if ((in_devÞv->ip_ptr) != NULL) {
+		for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
+			if (strcmp(dev->name, ifa->ifa_label) = 0) break;
+	}
+	if ( ifa = NULL ) {
+		printk("simeth_open: can't find device %s's ifa\n", dev->name);
+		return NOTIFY_DONE;
+	}
+
+	printk("simeth_device_event: %s ipaddr=0x%x\n", dev->name, htonl(ifa->ifa_local));
+
+	/*
+	 * XXX Fix me
+	 * if the device was up, and we're simply reconfiguring it, not sure
+	 * we get DOWN then UP.
+	 */
+
+	local = dev->priv;
+	/* now do it for real */
+	r = event = NETDEV_UP ? 
+		netdev_attach(local->simfd, dev->irq, htonl(ifa->ifa_local)):
+		netdev_detach(local->simfd);
+
+	printk("simeth: netdev_attach/detach: event=%s ->%d\n", event = NETDEV_UP ? "attach":"detach", r);
+
+	return NOTIFY_DONE;
+}
+
+static int
+simeth_close(struct net_device *dev)
+{
+	netif_stop_queue(dev);
+
+	free_irq(dev->irq, dev);
+
+	return 0;
+}
+
+/*
+ * Only used for debug
+ */
+static void
+frame_print(unsigned char *from, unsigned char *frame, int len)
+{
+	int i;
+
+	printk("%s: (%d) %02x", from, len, frame[0] & 0xff);
+	for(i=1; i < 6; i++ ) {
+		printk(":%02x", frame[i] &0xff);
+	}
+	printk(" %2x", frame[6] &0xff);
+	for(i=7; i < 12; i++ ) {
+		printk(":%02x", frame[i] &0xff);
+	}
+	printk(" [%02x%02x]\n", frame[12], frame[13]);
+
+	for(i\x14; i < len; i++ ) {
+		printk("%02x ", frame[i] &0xff);
+		if ( (i%10)=0) printk("\n");
+	}
+	printk("\n");
+}
+
+
+/*
+ * Function used to transmit of frame, very last one on the path before
+ * going to the simulator.
+ */
+static int
+simeth_tx(struct sk_buff *skb, struct net_device *dev)
+{
+	struct simeth_local *local = (struct simeth_local *)dev->priv;
+
+#if 0
+	/* ensure we have at least ETH_ZLEN bytes (min frame size) */
+	unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+	/* Where do the extra padding bytes comes from inthe skbuff ? */
+#else
+	/* the real driver in the host system is going to take care of that
+	 * or maybe it's the NIC itself.
+	 */
+	unsigned int length = skb->len;
+#endif
+
+	local->stats.tx_bytes += skb->len;
+	local->stats.tx_packets++;
+
+
+	if (simeth_debug > 5) frame_print("simeth_tx", skb->data, length);
+
+	netdev_send(local->simfd, skb->data, length);
+
+	/*
+	 * we are synchronous on write, so we don't simulate a
+	 * trasnmit complete interrupt, thus we don't need to arm a tx
+	 */
+
+	dev_kfree_skb(skb);
+	return 0;
+}
+
+static inline struct sk_buff * 
+make_new_skb(struct net_device *dev)
+{
+	struct sk_buff *nskb;
+
+	/*
+	 * The +2 is used to make sure that the IP header is nicely
+	 * aligned (on 4byte boundary I assume 14+2\x16)
+	 */
+	nskb = dev_alloc_skb(SIMETH_FRAME_SIZE + 2);
+	if ( nskb = NULL ) {
+		printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name);
+		return NULL;
+	}
+	nskb->dev = dev;
+
+	skb_reserve(nskb, 2);	/* Align IP on 16 byte boundaries */
+
+	skb_put(nskb,SIMETH_FRAME_SIZE);
+
+	return nskb;
+}
+
+/*
+ * called from interrupt handler to process a received frame
+ */
+static int
+simeth_rx(struct net_device *dev)
+{
+	struct simeth_local	*local;
+	struct sk_buff		*skb;
+	int			len;
+	int			rcv_count = SIMETH_RECV_MAX;
+
+	local = (struct simeth_local *)dev->priv;
+	/*
+	 * the loop concept has been borrowed from other drivers
+	 * looks to me like it's a throttling thing to avoid pushing to many
+	 * packets at one time into the stack. Making sure we can process them
+	 * upstream and make forward progress overall
+	 */
+	do { 
+		if ( (skb=make_new_skb(dev)) = NULL ) {
+			printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name);
+			local->stats.rx_dropped++;
+			return 0;
+		}
+		/*
+		 * Read only one frame at a time
+		 */
+		len = netdev_read(local->simfd, skb->data, SIMETH_FRAME_SIZE);
+		if ( len = 0 ) {
+			if ( simeth_debug > 0 ) printk(KERN_WARNING "%s: count=%d netdev_read=0\n", dev->name, SIMETH_RECV_MAX-rcv_count);
+			break;
+		}
+#if 0
+		/*
+		 * XXX Fix me
+		 * Should really do a csum+copy here
+		 */
+		memcpy(skb->data, frame, len);
+#endif
+		skb->protocol = eth_type_trans(skb, dev);
+
+		if ( simeth_debug > 6 ) frame_print("simeth_rx", skb->data, len);
+
+		/*
+		 * push the packet up & trigger software interrupt
+		 */
+		netif_rx(skb);
+
+		local->stats.rx_packets++;
+		local->stats.rx_bytes += len;
+
+	} while ( --rcv_count );
+
+	return len; /* 0 = nothing left to read, otherwise, we can try again */
+}
+
+/*
+ * Interrupt handler (Yes, we can do it too !!!)
+ */
+static void
+simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev = dev_id;
+
+	if ( dev = NULL ) {
+		printk(KERN_WARNING "simeth: irq %d for unknown device\n", irq);
+		return;
+	}
+
+	/*
+	 * very simple loop because we get interrupts only when receving
+	 */
+	while (simeth_rx(dev));
+}
+
+static struct net_device_stats *
+simeth_get_stats(struct net_device *dev)
+{
+	struct simeth_local  *local = (struct simeth_local *) dev->priv;
+
+	return &local->stats;
+}
+
+/* fake multicast ability */
+static void
+set_multicast_list(struct net_device *dev)
+{
+	printk(KERN_WARNING "%s: set_multicast_list called\n", dev->name);
+}
+
+#ifdef CONFIG_NET_FASTROUTE
+static int
+simeth_accept_fastpath(struct net_device *dev, struct dst_entry *dst)
+{
+	printk(KERN_WARNING "%s: simeth_accept_fastpath called\n", dev->name);
+	return -1;
+}
+#endif
+
+__initcall(simeth_probe);
diff -u -urN linux-2.4.20-ia64-021210/drivers/scsi/Makefile linux-ski/drivers/scsi/Makefile
--- linux-2.4.20-ia64-021210/drivers/scsi/Makefile	2002-12-10 14:23:20.000000000 -0700
+++ linux-ski/drivers/scsi/Makefile	2002-12-13 10:04:07.000000000 -0700
@@ -53,6 +53,7 @@
 obj-$(CONFIG_SUN3_SCSI)		+= sun3_scsi.o
 obj-$(CONFIG_MVME16x_SCSI)	+= mvme16x.o	53c7xx.o
 obj-$(CONFIG_BVME6000_SCSI)	+= bvme6000.o	53c7xx.o
+obj-$(CONFIG_HP_SIMSCSI)	+= simscsi.o
 obj-$(CONFIG_SCSI_SIM710)	+= sim710.o
 obj-$(CONFIG_SCSI_ADVANSYS)	+= advansys.o
 obj-$(CONFIG_SCSI_PCI2000)	+= pci2000.o
diff -u -urN linux-2.4.20-ia64-021210/drivers/scsi/simscsi.c linux-ski/drivers/scsi/simscsi.c
--- linux-2.4.20-ia64-021210/drivers/scsi/simscsi.c	1969-12-31 17:00:00.000000000 -0700
+++ linux-ski/drivers/scsi/simscsi.c	2002-12-13 10:04:07.000000000 -0700
@@ -0,0 +1,395 @@
+/*
+ * Simulated SCSI driver.
+ *
+ * Copyright (C) 1999, 2001-2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ *
+ * 02/01/15 David Mosberger	Updated for v2.5.1
+ * 99/12/18 David Mosberger	Added support for READ10/WRITE10 needed by linux v2.3.33
+ */
+#include <linux/config.h>
+#include <linux/blk.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+
+#include <scsi/scsi.h>
+
+#include <asm/irq.h>
+
+#include "scsi.h"
+#include "sd.h"
+#include "hosts.h"
+#include "simscsi.h"
+
+#define DEBUG_SIMSCSI	1
+
+/* Simulator system calls: */
+
+#define SSC_OPEN			50
+#define SSC_CLOSE			51
+#define SSC_READ			52
+#define SSC_WRITE			53
+#define SSC_GET_COMPLETION		54
+#define SSC_WAIT_COMPLETION		55
+
+#define SSC_WRITE_ACCESS		2
+#define SSC_READ_ACCESS			1
+
+#if DEBUG_SIMSCSI
+  int simscsi_debug;
+# define DBG	simscsi_debug
+#else
+# define DBG	0
+#endif
+
+static void simscsi_interrupt (unsigned long val);
+DECLARE_TASKLET(simscsi_tasklet, simscsi_interrupt, 0);
+
+struct disk_req {
+	unsigned long addr;
+	unsigned len;
+};
+
+struct disk_stat {
+	int fd;
+	unsigned count;
+};
+
+extern long ia64_ssc (long arg0, long arg1, long arg2, long arg3, int nr);
+
+static int desc[16] = {
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+static struct queue_entry {
+	Scsi_Cmnd *sc;
+} queue[SIMSCSI_REQ_QUEUE_LEN];
+
+static int rd, wr;
+static atomic_t num_reqs = ATOMIC_INIT(0);
+
+/* base name for default disks */
+static char *simscsi_root = DEFAULT_SIMSCSI_ROOT;
+
+#define MAX_ROOT_LEN	128
+
+/*
+ * used to setup a new base for disk images
+ * to use /foo/bar/disk[a-z] as disk images
+ * you have to specify simscsi=/foo/bar/disk on the command line
+ */
+static int __init
+simscsi_setup (char *s)
+{
+	/* XXX Fix me we may need to strcpy() ? */
+	if (strlen(s) > MAX_ROOT_LEN) {
+		printk("simscsi_setup: prefix too long---using default %s\n", simscsi_root);
+	}
+	simscsi_root = s;
+	return 1;
+}
+
+__setup("simscsi=", simscsi_setup);
+
+static void
+simscsi_interrupt (unsigned long val)
+{
+	unsigned long flags;
+	Scsi_Cmnd *sc;
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	{
+		while ((sc = queue[rd].sc) != 0) {
+			atomic_dec(&num_reqs);
+			queue[rd].sc = 0;
+			if (DBG)
+				printk("simscsi_interrupt: done with %ld\n", sc->serial_number);
+			(*sc->scsi_done)(sc);
+			rd = (rd + 1) % SIMSCSI_REQ_QUEUE_LEN;
+		}
+	}
+	spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
+int
+simscsi_detect (Scsi_Host_Template *templ)
+{
+	templ->proc_name = "simscsi";
+	return 1;	/* fake one SCSI host adapter */
+}
+
+int
+simscsi_release (struct Scsi_Host *host)
+{
+	return 0;	/* this is easy...  */
+}
+
+const char *
+simscsi_info (struct Scsi_Host *host)
+{
+	return "simulated SCSI host adapter";
+}
+
+int
+simscsi_biosparam (Disk *disk, kdev_t n, int ip[])
+{
+	unsigned capacity = disk->capacity;
+
+	ip[0] = 64;		/* heads */
+	ip[1] = 32;		/* sectors */
+	ip[2] = capacity >> 11;	/* cylinders */
+	return 0;
+}
+
+static void
+simscsi_readwrite (Scsi_Cmnd *sc, int mode, unsigned long offset, unsigned long len)
+{
+	struct disk_stat stat;
+	struct disk_req req;
+
+	req.addr = __pa(sc->request_buffer);
+	req.len  = len;			/* # of bytes to transfer */
+
+	if (sc->request_bufflen < req.len)
+		return;
+
+	stat.fd = desc[sc->target];
+	if (DBG)
+		printk("simscsi_%s @ %lx (off %lx)\n",
+		       mode = SSC_READ ? "read":"write", req.addr, offset);
+	ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
+	ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
+
+	if (stat.count = req.len) {
+		sc->result = GOOD;
+	} else {
+		sc->result = DID_ERROR << 16;
+	}
+}
+
+static void
+simscsi_sg_readwrite (Scsi_Cmnd *sc, int mode, unsigned long offset)
+{
+	int list_len = sc->use_sg;
+	struct scatterlist *sl = (struct scatterlist *)sc->buffer;
+	struct disk_stat stat;
+	struct disk_req req;
+
+	stat.fd = desc[sc->target];
+
+	while (list_len) {
+		req.addr = __pa(sl->address);
+		req.len  = sl->length;
+		if (DBG)
+			printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
+			       mode = SSC_READ ? "read":"write", req.addr, offset,
+			       list_len, sl->length);
+		ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
+		ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
+
+		/* should not happen in our case */
+		if (stat.count != req.len) {
+			sc->result = DID_ERROR << 16;
+			return;
+		}
+		offset +=  sl->length;
+		sl++;
+		list_len--;
+	}
+	sc->result = GOOD;
+}
+
+/*
+ * function handling both READ_6/WRITE_6 (non-scatter/gather mode)
+ * commands.
+ * Added 02/26/99 S.Eranian
+ */
+static void
+simscsi_readwrite6 (Scsi_Cmnd *sc, int mode)
+{
+	unsigned long offset;
+
+	offset = (((sc->cmnd[1] & 0x1f) << 16) | (sc->cmnd[2] << 8) | sc->cmnd[3])*512;
+	if (sc->use_sg > 0)
+		simscsi_sg_readwrite(sc, mode, offset);
+	else
+		simscsi_readwrite(sc, mode, offset, sc->cmnd[4]*512);
+}
+
+static size_t
+simscsi_get_disk_size (int fd)
+{
+	struct disk_stat stat;
+	size_t bit, sectors = 0;
+	struct disk_req req;
+	char buf[512];
+
+	/*
+	 * This is a bit kludgey: the simulator doesn't provide a direct way of determining
+	 * the disk size, so we do a binary search, assuming a maximum disk size of 4GB.
+	 */
+	for (bit = (4UL << 30)/512; bit != 0; bit >>= 1) {
+		req.addr = __pa(&buf);
+		req.len = sizeof(buf);
+		ia64_ssc(fd, 1, __pa(&req), ((sectors | bit) - 1)*512, SSC_READ);
+		stat.fd = fd;
+		ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
+		if (stat.count = sizeof(buf))
+			sectors |= bit;
+	}
+	return sectors - 1;	/* return last valid sector number */
+}
+
+static void
+simscsi_readwrite10 (Scsi_Cmnd *sc, int mode)
+{
+	unsigned long offset;
+
+	offset = (  (sc->cmnd[2] << 24) | (sc->cmnd[3] << 16)
+		  | (sc->cmnd[4] <<  8) | (sc->cmnd[5] <<  0))*512;
+	if (sc->use_sg > 0)
+		simscsi_sg_readwrite(sc, mode, offset);
+	else
+		simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512);
+}
+
+int
+simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *))
+{
+	char fname[MAX_ROOT_LEN+16];
+	size_t disk_size;
+	char *buf;
+#if DEBUG_SIMSCSI
+	register long sp asm ("sp");
+
+	if (DBG)
+		printk("simscsi_queuecommand: target=%d,cmnd=%u,sc=%lu,sp=%lx,done=%p\n",
+		       sc->target, sc->cmnd[0], sc->serial_number, sp, done);
+#endif
+
+	sc->result = DID_BAD_TARGET << 16;
+	sc->scsi_done = done;
+	if (sc->target <= 15 && sc->lun = 0) {
+		switch (sc->cmnd[0]) {
+		      case INQUIRY:
+			if (sc->request_bufflen < 35) {
+				break;
+			}
+			sprintf (fname, "%s%c", simscsi_root, 'a' + sc->target);
+			desc[sc->target] = ia64_ssc(__pa(fname), SSC_READ_ACCESS|SSC_WRITE_ACCESS,
+						    0, 0, SSC_OPEN);
+			if (desc[sc->target] < 0) {
+				/* disk doesn't exist... */
+				break;
+			}
+			buf = sc->request_buffer;
+			buf[0] = 0;	/* magnetic disk */
+			buf[1] = 0;	/* not a removable medium */
+			buf[2] = 2;	/* SCSI-2 compliant device */
+			buf[3] = 2;	/* SCSI-2 response data format */
+			buf[4] = 31;	/* additional length (bytes) */
+			buf[5] = 0;	/* reserved */
+			buf[6] = 0;	/* reserved */
+			buf[7] = 0;	/* various flags */
+			memcpy(buf + 8, "HP      SIMULATED DISK  0.00",  28);
+			sc->result = GOOD;
+			break;
+
+		      case TEST_UNIT_READY:
+			sc->result = GOOD;
+			break;
+
+		      case READ_6:
+			if (desc[sc->target] < 0 )
+				break;
+			simscsi_readwrite6(sc, SSC_READ);
+			break;
+
+		      case READ_10:
+			if (desc[sc->target] < 0 )
+				break;
+			simscsi_readwrite10(sc, SSC_READ);
+			break;
+
+		      case WRITE_6:
+			if (desc[sc->target] < 0)
+				break;
+			simscsi_readwrite6(sc, SSC_WRITE);
+			break;
+
+		      case WRITE_10:
+			if (desc[sc->target] < 0)
+				break;
+			simscsi_readwrite10(sc, SSC_WRITE);
+			break;
+
+
+		      case READ_CAPACITY:
+			if (desc[sc->target] < 0 || sc->request_bufflen < 8) {
+				break;
+			}
+			buf = sc->request_buffer;
+
+			disk_size = simscsi_get_disk_size(desc[sc->target]);
+			buf[0] = (disk_size >> 24) & 0xff;
+			buf[1] = (disk_size >> 16) & 0xff;
+			buf[2] = (disk_size >>  8) & 0xff;
+			buf[3] = (disk_size >>  0) & 0xff;
+			/* set block size of 512 bytes: */
+			buf[4] = 0;
+			buf[5] = 0;
+			buf[6] = 2;
+			buf[7] = 0;
+			sc->result = GOOD;
+			break;
+
+		      case MODE_SENSE:
+			/* sd.c uses this to determine whether disk does write-caching. */
+			memset(sc->request_buffer, 0, 128);
+			sc->result = GOOD;
+			break;
+
+		      case START_STOP:
+			printk("START_STOP\n");
+			break;
+
+		      default:
+			panic("simscsi: unknown SCSI command %u\n", sc->cmnd[0]);
+		}
+	}
+	if (sc->result = DID_BAD_TARGET) {
+		sc->result |= DRIVER_SENSE << 24;
+		sc->sense_buffer[0] = 0x70;
+		sc->sense_buffer[2] = 0x00;
+	}
+	if (atomic_read(&num_reqs) >= SIMSCSI_REQ_QUEUE_LEN) {
+		panic("Attempt to queue command while command is pending!!");
+	}
+	atomic_inc(&num_reqs);
+	queue[wr].sc = sc;
+	wr = (wr + 1) % SIMSCSI_REQ_QUEUE_LEN;
+
+	tasklet_schedule(&simscsi_tasklet);
+	return 0;
+}
+
+int
+simscsi_reset (Scsi_Cmnd *cmd, unsigned int reset_flags)
+{
+	printk ("simscsi_reset: unimplemented\n");
+	return SCSI_RESET_SUCCESS;
+}
+
+int
+simscsi_abort (Scsi_Cmnd *cmd)
+{
+	printk ("simscsi_abort: unimplemented\n");
+	return SCSI_ABORT_SUCCESS;
+}
+
+static Scsi_Host_Template driver_template = SIMSCSI;
+
+#include "scsi_module.c"
diff -u -urN linux-2.4.20-ia64-021210/drivers/scsi/simscsi.h linux-ski/drivers/scsi/simscsi.h
--- linux-2.4.20-ia64-021210/drivers/scsi/simscsi.h	1969-12-31 17:00:00.000000000 -0700
+++ linux-ski/drivers/scsi/simscsi.h	2002-12-13 10:04:07.000000000 -0700
@@ -0,0 +1,39 @@
+/*
+ * Simulated SCSI driver.
+ *
+ * Copyright (C) 1999, 2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+#ifndef SIMSCSI_H
+#define SIMSCSI_H
+
+#define SIMSCSI_REQ_QUEUE_LEN	64
+
+#define DEFAULT_SIMSCSI_ROOT	"/var/ski-disks/sd"
+
+extern int simscsi_detect (Scsi_Host_Template *);
+extern int simscsi_release (struct Scsi_Host *);
+extern const char *simscsi_info (struct Scsi_Host *);
+extern int simscsi_queuecommand (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+extern int simscsi_abort (Scsi_Cmnd *);
+extern int simscsi_reset (Scsi_Cmnd *, unsigned int);
+extern int simscsi_biosparam (Disk *, kdev_t, int[]);
+
+#define SIMSCSI {						\
+	.detect			= simscsi_detect,		\
+	.release		= simscsi_release,		\
+	.info			= simscsi_info,			\
+	.queuecommand		= simscsi_queuecommand,		\
+	.abort			= simscsi_abort,		\
+	.reset			= simscsi_reset,		\
+	.bios_param		= simscsi_biosparam,		\
+	.can_queue		= SIMSCSI_REQ_QUEUE_LEN,	\
+	.this_id		= -1,				\
+	.sg_tablesize		= SG_ALL,			\
+	.cmd_per_lun		= SIMSCSI_REQ_QUEUE_LEN,	\
+	.present		= 0,				\
+	.unchecked_isa_dma	= 0,				\
+	.use_clustering		= DISABLE_CLUSTERING		\
+}
+
+#endif /* SIMSCSI_H */



^ permalink raw reply

* Re: dmfs for 2.5.51
From: Joe Thornber @ 2002-12-13 17:43 UTC (permalink / raw)
  To: Greg KH; +Cc: Joe Thornber, lvm-devel, linux-kernel
In-Reply-To: <20021213172956.GB27800@kroah.com>

On Fri, Dec 13, 2002 at 09:29:56AM -0800, Greg KH wrote:
> The latest for Red Hat 7.2: gcc-2.96-112.7.2
> Are you using 3.2?

gcc version 2.95.4 20011002 (Debian prerelease)

> > The files can be larger than a single page, which complicates things
> > somewhat.
> 
> Hm, then using the seq_file interface might be easier.  I'll look into
> this.

Remember that the table file needs to hold two files at times: the new
table that is being read in and the old table in case the new table is
invalid.

- Joe

^ permalink raw reply

* Re: NVRAM/RTC
From: Matt Porter @ 2002-12-13 17:35 UTC (permalink / raw)
  To: Aman; +Cc: Matt Porter, linuxppc embedded
In-Reply-To: <00b801c2a2c1$70bc9470$370da8c0@aman>


On Fri, Dec 13, 2002 at 09:35:22PM +0530, Aman wrote:
> This might be a very basic question. By porting what do you mean?. As of now

By "porting", I mean adding a set of code that reflect the unique
characteristics of your custom board.

> I copied the ebony bsp to different location and did changes to boot on the
> custom board. Till now it was booting without any problem. Once I changed
> the EBC configuration to configure some other FPGA ,bcos of which  linux
> booting hangs at " Now Booting the kernel ".

Hrm, without knowing your custom board I can't really comment on
the potential source of something that is specific to your board.

You can try enabling early boot text messages.  Hopefully it still
works on 440, I heard a rumor that it might be broken which would
require some changes to head_440.S.  An easier path is, of course,
using a hardware debugger (BDI) to point you to where you are
dying...I usually just dump logbuf before the console is inited
so I can read the buffered oops message.

> I commented the ioremap of RTC, and the definitions of
> ppc_md.set_rtc_time = todc_set_rtc_time;
>
> ppc_md.get_rtc_time = todc_get_rtc_time;
>
>  still the same problem. Should I hv to do something else also.

You need to get rid of time_init, set_rtc_time, get_rtc_time,
nvram_read_val, nvram_write_val too.

You *will* get an oops from a machine check if you even have
todc_time_init enabled...it will be attempting to read from
some bogus location.

Regards,
--
Matt Porter
porter@cox.net
This is Linux Country. On a quiet night, you can hear Windows reboot.

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply

* Re: 2.5.5[01]]: Xircom Cardbus broken (PCI resource collisions)
From: Dave Jones @ 2002-12-13 17:36 UTC (permalink / raw)
  To: Valdis.Kletnieks; +Cc: Petr Konecny, linux-kernel
In-Reply-To: <200212131718.gBDHIw27008173@turing-police.cc.vt.edu>

On Fri, Dec 13, 2002 at 12:18:58PM -0500, Valdis.Kletnieks@vt.edu wrote:
 > On Fri, 13 Dec 2002 17:33:00 +0100, Petr Konecny <pekon@informatics.muni.cz>  said:
 > > > I see why the if/continue was added - you don't want to be
 > > > calling device_register()/pci_insert_device() if
 > > > pci_enable_device() loses.  I don't see why 2.5.50 moved the
 > > > code up after pci_setup_device(). There's an outside chance
 > > > that the concept of moving the call was correct, but that it
 > > > should have been moved to between the calls to
 > > > pci_assign_resource() and pci_readb().  If that's the case,
 > > > then you're correct as well....
 > > I can confirm that this indeed works. I moved the two lines before
 > > pci_readb and the card works (every character you now read went through
 > > it). Who shall submit a patch to Linus ?
 > 
 > The problem is this from the 2.5.50 Changelog that Linus posted:
 > 
 > Dave Jones <davej@suse.de>:
 > ...
 >   o make cardbus PCI enable earlier
 > 
 > I'm willing to submit a patch, but I think Dave has to make the call whether
 > it should be backed out entirely, or moved after pci_assign_resource().
 > I certainly don't understand the code *or* PCI well enough to decide between
 > those two option...

It's my understanding that pci_enable_device() *must* be called
before we fiddle with dev->resource, dev->irq and the like.

		Dave

-- 
| Dave Jones.        http://www.codemonkey.org.uk
| SuSE Labs

^ permalink raw reply

* Re: dmfs for 2.5.51
From: Greg KH @ 2002-12-13 17:32 UTC (permalink / raw)
  To: Joe Thornber; +Cc: Andrew Morton, lvm-devel, linux-kernel
In-Reply-To: <20021213095806.GC1117@reti>

On Fri, Dec 13, 2002 at 09:58:06AM +0000, Joe Thornber wrote:
> On Thu, Dec 12, 2002 at 09:25:51PM -0800, Greg KH wrote:
> > On Thu, Dec 12, 2002 at 05:50:01PM -0800, Andrew Morton wrote:
> > > hm.  The whole thing seems hokey to me.  Not sure why.
> > 
> > I agree.  It doesn't feel right.  I mean, doing a mkdir(1) to create a
> > device, which causes files to be created automagically in that
> > directory?  Something needs to change here, and I proposed a single file
> > to write to that creates the device, but was shot down by the author.
> 
> Greg, I didn't mean to make it sound like I was shooting you down, I
> just said that we'd leave it as it was for now.

Sorry, I didn't mean it that way.  I understand and was trying to reach
more people.  Looks like I succeded :)

> Having written the
> code I wanted a bit more feedback.  When I started writing the fs
> interface a couple of people expressed concerns that I should try and
> map things properly onto fs semantics and not just create a single
> file.  Given Andrews comment I guess I haven't done a good job.  Could
> you flesh out your single file idea a bit more please, there's a lot
> of functionality to shoe horn in there.

Ok, I'll go work on that and see how it turns out.

> > > > ...
> > > > +  echo -e "0 56 linear /dev/hda3 0\n56 102344 linear /dev/hda4 0" > table
> > > 
> > > Maybe this is why.
> > 
> > Heh, yeah, welcome to parsers in the kernel :)
> > But the dm code today does much the same thing with ioctls, passing a
> > string down to the loaded modules below it.  So there is a bit of
> > president.  Even if it is ugly :)
> 
> y, the dm targets have always accepted their arguments as ascii
> strings.  So the file system interface just adds code to split the
> input into lines, and then sscanf the first three elements of the line
> - this is probably less code than the marshalling of binary data that
> is done in the ioctl interface.
> 
> I see the fact that we're using ascii data as being the big advantage
> of the fs interface, which neccessarily means doing a small amount of
> parsing in kernel.  You can't have things both ways.

I agree, I like the interface.  It's just a little strange the first
time you see it.

> > > > ...
> > > > +static struct page *find_page(struct dmfs_file *f, loff_t len, int fill)
> > > 
> > > This is called under spinlock.
> > > 
> > > > ...
> > > > +                       void *addr = (void *) __get_free_page(GFP_KERNEL);
> > > 
> > > whoops.
> 
> My fault :(
> 
> > Nice catch.  I'm not sure that the find_page(), __io() and friends
> > functions are really needed at all.
> 
> It would be nice to get rid of them, what shall we replace them with ?

Something like only creating one page as I did in the dev file, or the
seq_file interface.  I'll play around with the sizes of the files to see
how to fix this up.

thanks,

greg k-h

^ permalink raw reply

* Re: Symlink indirection
From: James Antill @ 2002-12-13 17:32 UTC (permalink / raw)
  To: Pete Zaitcev; +Cc: Marc-Christian Petersen, linux-kernel
In-Reply-To: <200212131616.gBDGGH302861@devserv.devel.redhat.com>

Pete Zaitcev <zaitcev@redhat.com> writes:

> >> Is the number of allowed levels of symlink indirection (if that is the
> >> right phrase; I mean symlink -> symlink -> ... -> file) dependant on the
> >> kernel, or libc ? Where is it defined, and can it be changed?
> > 
> > fs/namei.c
> > 
> >  if (current->link_count >= 5)
> > 
> > change to a higher value.
> 
> This is vey, very misleading statement. The counter mentioned above
> is there to protect stacks from overflow, but our symlink resolution
> is largely non-recursive, and certainly not in case of a tail
> recursion within the same directory.

 tail recursion is a bad name, as that implies the last element of the
path can go beyond the above value. A better way is to say that each
element of the path can have at most link_count and the total path can
have at most total_link_count symlinks (or that nested symlinks are
limited to a small number, in Al's words).

-- 
# James Antill -- james@and.org
:0:
* ^From: .*james@and\.org
/dev/null

^ permalink raw reply

* Re: dmfs for 2.5.51
From: Greg KH @ 2002-12-13 17:29 UTC (permalink / raw)
  To: Joe Thornber; +Cc: lvm-devel, linux-kernel
In-Reply-To: <20021213093745.GB1117@reti>

On Fri, Dec 13, 2002 at 09:37:45AM +0000, Joe Thornber wrote:
> Greg,
> 
> On Thu, Dec 12, 2002 at 05:26:19PM -0800, Greg KH wrote:
> > Here's a patch against 2.5.51 with a updated dmfs.
> 
> I've split out your two changes into seperate patches (patches 21 and
> 22) and made them available here:
> 
> http://people.sistina.com/~thornber/patches/2.5-unstable/2.5.51/2.5.51-dmfs-1/

Thanks.

> > with the following modifications:
> > 	- fixed compile time warnings with the dbg() macro (something
> > 	  better should be used here, I just commented it out...)
> 
> I'm not seeing any warnings, which compiler version are you using ?

The latest for Red Hat 7.2: gcc-2.96-112.7.2
Are you using 3.2?

> > 	- changed the dev file to print out the kdev value, not be the
> > 	  actual block device.
> 
> Should we really be exporting a kdev_t to userland, why not just print out
> 
> <major>:<minor>

No, look at the other dev files in sysfs, I stayed consistant with them.

> > With regards to the last change, I didn't follow the way the other files
> > operate with their complex page creation structure, as this is only a
> > simple one line file.  If the lvm developers want me to change this, I
> > will.
> 
> What you've done looks fine to me, though allocating a whole page to
> hold a single number seems overkill.  Why don't you just snprintf into
> a char[] held on the stack ?

Because I forgot you could do copy_to_user() with data on the stack :)
Good point, I'll change it...

> > If not, I would argue that a number of the other files created
> > should be changed to use this simpler format.  Or is there some reason
> > for creating these lists of pages that I'm missing?
> 
> The files can be larger than a single page, which complicates things
> somewhat.

Hm, then using the seq_file interface might be easier.  I'll look into
this.

thanks,

greg k-h

^ permalink raw reply

* kernel question
From: Joe Gofton @ 2002-12-13 17:29 UTC (permalink / raw)
  To: linux-kernel

I get this after I install a new kernel.  2.4.19 or 2.4.20.  This doesn't
happen with 2.4.18.  Is this bad?


Dec  1 11:10:32 ns1 kernel: SCSI subsystem driver Revision: 1.00
Dec  1 11:10:32 ns1 kernel: scsi0 : Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA
DRIVER, Rev 6.2.8
Dec  1 11:10:32 ns1 kernel:         <Adaptec 2940 Ultra2 SCSI adapter>
Dec  1 11:10:32 ns1 kernel:         aic7890/91: Ultra2 Wide Channel A,
SCSI Id=7, 32/253 SCBs
Dec  1 11:10:32 ns1 kernel:
Dec  1 11:10:32 ns1 kernel:   Vendor: QUANTUM   Model: ATLAS_V_18_WLS   
Rev: 0230
Dec  1 11:10:32 ns1 kernel:   Type:   Direct-Access                     
ANSI SCSI revision: 03
Dec  1 11:10:32 ns1 kernel:   Vendor: QUANTUM   Model: ATLAS_V_18_WLS   
Rev: 0230
Dec  1 11:10:32 ns1 kernel:   Type:   Direct-Access                     
ANSI SCSI revision: 03
Dec  1 11:10:32 ns1 kernel: scsi0:A:0:0: Tagged Queuing enabled.  Depth 253
Dec  1 11:10:32 ns1 kernel: scsi0:A:1:0: Tagged Queuing enabled.  Depth 253
Dec  1 11:10:32 ns1 kernel: scsi: <fdomain> Detection failed (no card)
Dec  1 11:10:32 ns1 kernel: PCI: Enabling device 00:09.0 (0006 -> 0007)
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x8
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: agpgart: Detected Via Apollo Pro chipset
Dec  1 11:10:32 ns1 kernel: agpgart: AGP aperture is 64M @ 0xd0000000
Dec  1 11:10:32 ns1 kernel: Highpoint HPT370 Softwareraid driver for linux
version 0.01
Dec  1 11:10:32 ns1 kernel: No raid array found
Dec  1 11:10:32 ns1 kernel: SCSI subsystem driver Revision: 1.00
Dec  1 11:10:32 ns1 kernel: scsi0 : Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA
DRIVER, Rev 6.2.8
Dec  1 11:10:32 ns1 kernel:         <Adaptec 2940 Ultra2 SCSI adapter>
Dec  1 11:10:32 ns1 kernel:         aic7890/91: Ultra2 Wide Channel A,
SCSI Id=7, 32/253 SCBs
Dec  1 11:10:32 ns1 kernel:
Dec  1 11:10:32 ns1 kernel:   Vendor: QUANTUM   Model: ATLAS_V_18_WLS   
Rev: 0230
Dec  1 11:10:32 ns1 kernel:   Type:   Direct-Access                     
ANSI SCSI revision: 03
Dec  1 11:10:32 ns1 kernel:   Vendor: QUANTUM   Model: ATLAS_V_18_WLS   
Rev: 0230
Dec  1 11:10:32 ns1 kernel:   Type:   Direct-Access                     
ANSI SCSI revision: 03
Dec  1 11:10:32 ns1 kernel: scsi0:A:0:0: Tagged Queuing enabled.  Depth 253
Dec  1 11:10:32 ns1 kernel: scsi0:A:1:0: Tagged Queuing enabled.  Depth 253
Dec  1 11:10:32 ns1 kernel: scsi: <fdomain> Detection failed (no card)
Dec  1 11:10:32 ns1 kernel: PCI: Enabling device 00:09.0 (0006 -> 0007)
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x8
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: scsi0: PCI error Interrupt at seqaddr = 0x9
Dec  1 11:10:32 ns1 kernel: scsi0: Signaled a Target Abort
Dec  1 11:10:32 ns1 kernel: Attached scsi disk sda at scsi0, channel 0, id
0, lun 0
Dec  1 11:10:32 ns1 kernel: Attached scsi disk sdb at scsi0, channel 0, id
1, lun 0
Dec  1 11:10:32 ns1 kernel: (scsi0:A:0): 80.000MB/s transfers (40.000MHz,
offset 63, 16bit)
Dec  1 11:10:32 ns1 kernel: SCSI device sda: 35861388 512-byte hdwr
sectors (18361 MB)
Dec  1 11:10:32 ns1 kernel: Partition check:
Dec  1 11:10:32 ns1 kernel:  sda: sda1 sda2 sda3 sda4 < sda5 sda6 sda7 >
Dec  1 11:10:32 ns1 kernel: (scsi0:A:1): 80.000MB/s transfers (40.000MHz,
offset 63, 16bit)
Dec  1 11:10:32 ns1 kernel: SCSI device sdb: 35861388 512-byte hdwr
sectors (18361 MB)
Dec  1 11:10:32 ns1 kernel:  sdb: sdb1 sdb2 sdb3 sdb4 < sdb5 sdb6 sdb7 >



^ permalink raw reply

* Re: [PATCH] Add CONFIG_ACPI_RELAXED_AML option
From: Carlos Morgado @ 2002-12-13 17:18 UTC (permalink / raw)
  To: acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <B9ECACBD6885D5119ADC00508B68C1EA0D19B9AB-LkGsggTGxVmSsB6bSF6DdVDQ4js95KgL@public.gmane.org>


On 2002.12.13 16:22:43 +0000 "Moore, Robert" wrote:

> 
> What is really being proposed here is for Linux ACPI to be bug-for-bug
> compatible with Microsoft.  This is impossible to do deterministically
> because the MS interpreter is closed source.  The only standard that we have
> that we can code to is the ACPI specification, and this has to be the last
> word on the matter.
> 

not to mention windows tends to ignore builtin dsdts afaik and use the ones
distributed in windows drivers. 
-- 
Carlos Morgado - chbm(at)chbm(dot)nu - http://chbm.nu/ -- gpgkey: 0x1FC57F0A
http://wwwkeys.pgp.net/ FP:0A27 35D3 C448 3641 0573 6876 2A37 4BB2 1FC5 7F0A
Software is like sex; it's better when it's free. - Linus Torvalds


-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/

^ permalink raw reply

* Re: Symlink indirection
From: James Antill @ 2002-12-13 17:24 UTC (permalink / raw)
  To: Andrew Walrond; +Cc: linux-kernel
In-Reply-To: <3DFA0C20.3020000@walrond.org>

Andrew Walrond <andrew@walrond.org> writes:

> Hi James.
> 
> Thanks for the info; my application is now entirely plausible :)
> And apologies for asking an FAQ. (Google didn't throw up anything useful)

 Sorry, this was an error on my part, I shouldn't reply to Richard's
posts until I've calmed down.

> BTW is documented anywhere except the code?

 Apart from this mailing list, not AFAIK.

> >  The link count is for recursively following symlinks, as the
> > original
> 
> > question wanted to know ... and has been discussed on lkml numerous
> > times.
> >  Andrew, one extra piece of information you might not know is that
> > the
> 
> > above value doesn't come into play when the new symlink is the last
> > element in the new path, then you get a higher value.
> >  The full code...
> >         if (current->link_count >= max_recursive_link)
> 
> >                 goto loop;
> >         if (current->total_link_count >= 40)
> >                 goto loop;
> > [...]
> >         current->link_count++;
> >         current->total_link_count++;
> >         UPDATE_ATIME(dentry->d_inode);
> >         err = dentry->d_inode->i_op->follow_link(dentry, nd);
> >         current->link_count--;
> > ...Ie. a link from /a -> /b/c where "b" is a symlink takes the
> 
> > "max_recursive_link" value (5 on vanilla kernels) but if "/b/c" was a
> > symlink then you get to use the 40 value.

 The last part of the path is still part of the follow_link, and thus
subject to the non-total link_count value. The only times you get the
bigger value is...

/a     -> /b/c
/b     -> /b.1     -> /b.2     -> /b.3     -> /b.4
/b.4/c -> /b.4/c.1 -> /b.4/c.2 -> /b.4/c.3 -> /b.4/c.4

...here you can open /a even if you'll follow more than ->link_count
links.

-- 
# James Antill -- james@and.org
:0:
* ^From: .*james@and\.org
/dev/null

^ permalink raw reply

* [linux-lvm] urgent and confidential
From: JOHNSON   MUSOLE @ 2002-12-13 17:16 UTC (permalink / raw)
  To: linux-lvm

Dear Sir, May I solicit your understanding, as I have had no prior contact with you, but circumstances made it to be this way today and I encourage you to read this mail. I am a Ghaninian, my name is Johnson Musole, I am the only son of Mr. Francis Joshua Musole a Gold miner in Ghana. Mr. Francis Musole died 3 months ago from an accident while working in the Gold field in Ghana. Our family is a family of 5,I my mum and my younger sisters. My late dad before his death saved quite some money $4.5m(Four and half million US dollars) which he made from Gold proceeds and some Gold bars which weighs so many kilograms and all this he deposited somewhere in Ghana. I and my younger sister Alima are the only one that has the related papers concerning this deposit. So much has taken place in my family since his death. Our Uncles are giving us a real battle because they are all interested in what they believe my late dad must have left behind for the family. As a result of this, My mum has gone to her home town to stay for safety and as I write to you, I am not in Ghana for obvious reasons being Security but you can confirm the authenticity of what I am telling you on phone through my younger sister Alima who is presently in Ghana. We need a guardian who will assist us to move this funds out of Ghana to his country for investment into a profitable business. We need western education and good life; our uncles are all out to take all we have from us. Thus the reason why we are asking for your assistance. We will compensate you for assisting us in this regard; we are ready to go into partnership with you provided you will be sincere to us. Please save, my family from this trouble and God will bless you I am expecting your response so that I can give you the full contact of my younger sister Alima in Ghana. She will handle everything on behalf of the family with my special advice and directions. We are willing to discuss your preferred mode of compensation here for you to feel satisfied after the business. Keep this offer confidential no matter your position please. I am expecting your response strictly through this my private mail address below: johnsonmusole21@www.com Regards, Johnson.

^ permalink raw reply

* Networking/Becker et al [was Re: pci-skeleton duplex check]
From: Larry McVoy @ 2002-12-13 17:22 UTC (permalink / raw)
  To: Donald Becker
  Cc: David S. Miller, Jeff Garzik, Roger Luethi, netdev,
	Linux Kernel Mailing List

In the for what it is worth department...  My brain dump on this situation.

I know Dave Miller, Don Becker, and Jeff Garzik personally, we've spent
time face to face.  These are all good guys, very important guys to the
kernel effort.

I've known Don for a long time and we've had a bunch of talks about why
his style and the Linux style doesn't mesh well.  Here's my view, which
may or may not be shared.

Don is a careful, thoughtful guy.  He is quite conservative when it comes
to programming.  His style most closely matches the Sun kernel style of
development; it does not match the Linux style at all.  The Linux style
is a lot more free wheeling, stuff changes a lot and the kernel team
depends heavily on the fact that it is has this vast army of free testers.
Without that army, I shudder to think what things would be like, I do not
think the current development style would work anywhere near as well.

But it does work, and it violates a lot of engineering disciplines that
old farts, like me and Don, respect.  I've learned to live with it, even
respect the fact that the Linux team does so well.  Don is having a much
tougher time.  He really wants the Linux team to work more like he works
and the Linux team doesn't want to do that at all, they point at their
success and believe that their development style is part of that success.

It is worth putting on the record that Don has done a lot for the Linux
effort, a huge amount, in fact.  Without Don, Linux would be dramatically
less far along than it is.  I've been here since before it had networking
and it really took off when Don started writing drivers.

It's also pointing out that I think he's right about the networking
regressions, suspend/resume on laptops used to work and now the network
is almost always hosed after I do that.

I doubt that either side is likely to change their view.  But, the real
point is how to we get Don's brain engaged on the kernel networking
drivers?  A few thoughts:

    a) Don is going to have to accept that the Linux kernel approach is
       the way it is.  Sitting on the sidelines and whining is not going
       to change how the kernel is developed.  Either get with the 
       program or not, but don't sit there and complain but refuse
       to work the way the rest of the people work.

    b) The kernel folks need to listen to Don more.  Draw him into the
       conversations about interface changes, try and extract the 
       knowledge he has, it's worth it.  Not doing so just means you
       are wasting time.

    c) Don needs to kill those mailing lists he maintains or merge them
       with the appropriate kernel lists.  That is a big part of the
       problem, the interesting stuff seems to be happening over in 
       Don's part of the world and the mainstream kernel team isn't
       aware of it.

    d) Beer.  More beer.  Much more beer and some face time.  If there
       is a tech conference coming up, I think we should get Don to 
       come and give him the first lifetime achievement award for
       Linux kernel development.  Then shove him and the other network
       hackers into a room with a keg and not let them out until they
       are smiling.  BitMover will kick in some money towards this if
       needed.

--lm

On Fri, Dec 13, 2002 at 11:56:17AM -0500, Donald Becker wrote:
> On 13 Dec 2002, David S. Miller wrote:
> > On Thu, 2002-12-12 at 17:18, Donald Becker wrote:
> > > Or perhaps recognizing that when someone that has been a significant,
> > > continuous contributer since the early days of Linux
> > 
> > Until you learn to play nice with people and mesh within the
> > fabric of Linux development, I adamently do not classify you
> > as you appear to self-classify yourself.  You don't contribute,
> > you sit in your sandbox and then point fingers at the people who
> > do know how to work with other human beings and say "see how much
> > that stuff sucks?  well my stuff works, nyah!"
> ..
> > If Linux itself is worse off and went backwards in time for a while...
> 
> The development criteria used to be technically based, and that is still
> the public statement.  Now, as your statement makes clear, working code
> is an irrelevant criteria.
> 
> You comments immediately moved the subject from the technical merit and
> correctness of the code to an ad hominem attack.  The facts, and the
> code, clearly show the long term interaction and contribution.  In most
> cases the code and interfaces we are talking about were written and
> defined by me throughout the past decade.
> 
> 
> 
> -- 
> Donald Becker				becker@scyld.com
> Scyld Computing Corporation		http://www.scyld.com
> 410 Severn Ave. Suite 210		Scyld Beowulf cluster system
> Annapolis MD 21403			410-990-9993
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

-- 
---
Larry McVoy            	 lm at bitmover.com           http://www.bitmover.com/lm 

^ permalink raw reply

* Re: [PATCH] S4Bios support for 2.4.20 + acpi-20021205
From: Nils Faerber @ 2002-12-13 17:13 UTC (permalink / raw)
  Cc: ducrot-kk6yZipjEM5g9hUCZPvPmw, acpi-devel-pyega4qmqnRoyOMFzWx49A
In-Reply-To: <20021213163615.GI4327-j6u/t2rXLliUoIHC/UFpr9i2O/JbrIOy@public.gmane.org>

On Fri, 13 Dec 2002 17:36:15 +0100
Ducrot Bruno <ducrot-kk6yZipjEM5g9hUCZPvPmw@public.gmane.org> wrote:
> On Fri, Dec 13, 2002 at 05:14:31PM +0100, Nils Faerber wrote:
> > On Fri, 13 Dec 2002 16:53:09 +0100
> > Ducrot Bruno <ducrot-kk6yZipjEM5g9hUCZPvPmw@public.gmane.org> wrote:
> > > Patch for 2.4.20 and acpi-20021205 for adding s4bios feature.
> Well, I don't know.  Perhaps lphdisk (I don't remember the URI) could
> help.  Some googling permit to get it.  Or (who knows?) even a
> /dev/hda1 as a vfat partition can help?

AFAIK this is only good for Phoenix BIOS whereas mine is AWARD
Medallion. Couldn't this also be specified in ACPI specs, i.e. how a
suspend partition has to look like?

> > does it suspend? I know for Phoenix BIOSes there is a tool on the
> > net to create that partition. I have a Asus L3800C notebook which
> > has AFAIK an AWARD BIOS. And AFAIK there is no tool available from
> > ASUS or AWARD to create such a partition.
> In a really perfect world:
> echo 1 > /proc/acpi/sleep	# for standby
> echo 2 > /proc/acpi/sleep	# for suspend to ram
> echo 3 > /proc/acpi/sleep	# for suspend to ram, but with more power conservative
> echo 4 > /proc/acpi/sleep	# for suspend to disk
> echo 5 > /proc/acpi/sleep	# for shutdown unfriendly the system

That would really be perfect :)
S1 on mine does just switch of the fan and stops the CPU. Nothing more.
S2 does not exist.
S3 does nothing except for funny ACPI messages:
	acpi: sleep 3
	acpi: GO!
	acpi: acpi_suspend call 3

And your S4BIOS patch ends up freezing the machine after "saving CPU
context". Oh, but S5 behaves as expected :)

> and perhaps
> echo 4b > /proc/acpi/sleep	# for suspend to disk via s4bios

For me it would be sufficient beeing able to set this at kernel compile
time, i.e. either swsusp or s4bios.

> Actually, since there is no S4 support in 2.4, 4 and 4b is the same
> here.

Yup I know :(
The swsusp patch for latest 2.4.20 + ACPI does not yet exist but all my
trials with swsusp showed that it is promising but did not work.

> Please note also that this patch DO NOT fix devices suspensions codes
> in general, and have certainly some data corruption that need to be
> fixed before a real inclusion.

Sure, no problem!
I first have to find out what type of suspend storage this damn BIOS
wants to have, then I can try to suspend and opnly then try to resume
:=)

> Ducrot Bruno
Thanks again!
CU
  nils faerber

-- 
kernel concepts          Tel: +49-271-771091-12
Dreisbachstr. 24         Fax: +49-271-771091-19
D-57250 Netphen          D1 : +49-170-2729106
--


-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/

^ permalink raw reply

* Re: 2.5.5[01]]: Xircom Cardbus broken (PCI resource collisions)
From: Valdis.Kletnieks @ 2002-12-13 17:18 UTC (permalink / raw)
  To: Petr Konecny; +Cc: linux-kernel, Dave Jones
In-Reply-To: <200212131633.gBDGX0617899@anxur.fi.muni.cz>

[-- Attachment #1: Type: text/plain, Size: 1180 bytes --]

On Fri, 13 Dec 2002 17:33:00 +0100, Petr Konecny <pekon@informatics.muni.cz>  said:

>  Valdis> I see why the if/continue was added - you don't want to be
>  Valdis> calling device_register()/pci_insert_device() if
>  Valdis> pci_enable_device() loses.  I don't see why 2.5.50 moved the
>  Valdis> code up after pci_setup_device(). There's an outside chance
>  Valdis> that the concept of moving the call was correct, but that it
>  Valdis> should have been moved to between the calls to
>  Valdis> pci_assign_resource() and pci_readb().  If that's the case,
>  Valdis> then you're correct as well....
> I can confirm that this indeed works. I moved the two lines before
> pci_readb and the card works (every character you now read went through
> it). Who shall submit a patch to Linus ?

The problem is this from the 2.5.50 Changelog that Linus posted:

Dave Jones <davej@suse.de>:
...
  o make cardbus PCI enable earlier

I'm willing to submit a patch, but I think Dave has to make the call whether
it should be backed out entirely, or moved after pci_assign_resource().
I certainly don't understand the code *or* PCI well enough to decide between
those two option...

/Valdis


[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]

^ permalink raw reply

* Re: Symlink indirection
From: Amos Waterland @ 2002-12-13 17:15 UTC (permalink / raw)
  To: Jeff Bailey; +Cc: root, Andrew Walrond, linux-kernel, libc-alpha
In-Reply-To: <1039798306.921.11.camel@outpost.dnsalias.org>

I think that you and Richard are dicussing a slightly different issue
than the original poster asked about.  The original question was:

On Fri, 13 Dec 2002, Andrew Walrond wrote:
> Is the number of allowed levels of symlink indirection (if that is the 
> right phrase; I mean symlink -> symlink -> ... -> file) dependant on the 
> kernel, or libc ? Where is it defined, and can it be changed?

To which Richard replied:

> Since a symlink is just a file containing a name, the resulting path
> length is simply the maximum path length that user-space tools allow.
> This should be defined as "PATH_MAX". Posix defines this as 255
> characters but I think posix requires that this be the minimum and all
> file-name handling buffers must be at least PATH_MAX in length.
>
> A hard link is just another directory-entry for the same file. This,
> therefore follows the same rules. There must be enough space on the
> device to contain the number of directory entries, as well as enough
> buffer length in the tools necessary to manipulate these "nested"
> directories, which are not really "nested" at all. 

But Richard is not actually completely correct.  There is a limit of 5
levels of symlink indirection in vanilla 2.4 series Linux kernels.

  % touch 0
  % for i in `seq 1 10`; do ln -s `ls | sort | tail -1` $i; done
  % ls
  0  1  10  2  3  4  5  6  7  8  9
  % cat 5
  % cat 6
  cat: 6: Too many levels of symbolic links
  % strace cat 6 2>&1 | grep 'open("6",'
  open("6", O_RDONLY|O_LARGEFILE) = -1 ELOOP (Too many levels of symbolic links)

This has been discussed by Al Viro et al. many times on lkml.  I believe
that it is not a user-space or POSIX issue, but rather a kernel issue.
Thanks.

Amos Waterland

^ permalink raw reply

* Re: oops in the 2.4.20-NFSALL sunrpc code
From: Ion Badulescu @ 2002-12-13 17:05 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: nfs
In-Reply-To: <15865.65520.122137.890996@charged.uio.no>

On Fri, 13 Dec 2002, Trond Myklebust wrote:

> >>>>> " " == Ion Badulescu <ionut@badula.org> writes:
> 
>      > It's caused, from what I can tell, by task->tk_client being
>      > NULL in xprt_timer() at the time it is dereferenced. Looks like
>      > a race condition, probably facilitated by the SMP kernel.
> 
> It's definitely not a race condition: Every new task is supposed to
> call rpc_init_task() prior to calling rpc_execute(). This
> again initializes task->tk_client once and for all. It is never
> allowed to change.
> There is only one exception to the above rule, namely nfs_flushd,
> (which can never stray into net/sunrpc/xprt.c).

Hmm... I can see two places where the NULL could be coming from. One is 
calling rpc_init_task() with clnt==NULL, which appears to be legal since 
the function checks clnt for NULL:

        if (clnt)
                atomic_inc(&clnt->cl_users);

The other one would be rpc_release_task() if somehow an xprt_timer is 
fired up, spins for a while on xprt->sock_lock, and in the meantime 
rpc_release_task() is called and it releases the client:

        if (task->tk_client) {
                rpc_release_client(task->tk_client);
                task->tk_client = NULL;
        }

I don't see anything in rpc_release_task() that waits for xprt->sock_lock,
but I don't know the code that well and maybe something else prevents this
race.

> All I can say about this one is that it doesn't look like anything
> I've come across on any other setups. Have you tried to reproduce it
> on an actual 2.4.20 kernel?

No, and in fact I only got this oops once across several dozen machines 
and several weeks of uptime. It doesn't seems to be easily reproducible, 
that's why I'm inclined to think it's an SMP race.

However, as I said, the diff between 2.4.20 + those patches and my kernel, 
in the nfs/nfsd/sunrpc areas (including headers) is empty...

Thanks,
Ion

-- 
  It is better to keep your mouth shut and be thought a fool,
            than to open it and remove all doubt.



-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply

* Disappearing DNS packets
From: Steve Snodgrass @ 2002-12-13 17:05 UTC (permalink / raw)
  To: netfilter

I'm having a very strange problem and I was hoping that maybe someone has
seen this before.  Note that IP addresses have been sanitized.

I have a Red Hat 7.3 firewall using iptables 1.2.5 and kernel 2.4.18-10
separating two subnets.  The eth0 subnet contains a DNS server and the eth1
subnet contains a DNS client.  The firewall uses connection tracking and the
ruleset permits DNS queries from the client to the server.

192.168.10.20 ------ eth0-FIREWALL-eth1 ------ 192.168.3.8
DNS Server                                     DNS Client

Rule fragement from FORWARD chain:
ACCEPT   all  --  0.0.0.0/0     0.0.0.0/0        state RELATED,ESTABLISHED 
LOG      udp  --  192.168.3.8   192.168.10.20    udp dpt:53 LOG flags 0 level 4 
ACCEPT   udp  --  192.168.3.8   192.168.10.20    udp dpt:53 

The DNS client box is running squid, which happens to generate pairs of
similar DNS queries for some reason.  What is happening is that *one* of
the two queries gets dropped most of the time as it crosses the firewall.
Observe these tcpdumps:

firewall# tcpdump -i eth1 host 192.168.3.8 and port 53
tcpdump: listening on eth1
11:54:15.132008 192.168.3.8.32772 > 192.168.10.20.domain:  18+ A? www.google.com. (32) (DF)
11:54:15.132034 192.168.3.8.32772 > 192.168.10.20.domain:  19+ A? www.google.com. (32) (DF)
11:54:15.171377 192.168.10.20.domain > 192.168.3.8.32772:  18 1/4/2 A www.google.com (152) (DF)

firewall# tcpdump -i eth0 host 192.168.3.8 and port 53
tcpdump: listening on eth0
11:54:15.156014 192.168.3.8.32772 > 192.168.10.20.domain:  18+ A? www.google.com. (32) (DF)
11:54:15.171337 192.168.10.20.domain > 192.168.3.8.32772:  18 1/4/2 A www.google.com (152) (DF)

Note that the DNS query with query ID 19 has disappeared somewhere between
coming into eth1 and exiting eth0.

The logging rule I have in iptables does show both of those packets right
before they hit the ACCEPT rule:

IN=eth1 OUT=eth0 SRC=192.168.3.8 DST=192.168.10.20 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=UDP SPT=32772 DPT=53 LEN=40 
IN=eth1 OUT=eth0 SRC=192.168.3.8 DST=192.168.10.20 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=UDP SPT=32772 DPT=53 LEN=40 

I'm kind of at a loss here, does anyone have any idea what could be going on?
I'll be happy to provide any additional info that I can.  Thanks!

-- 
Steve Snodgrass * ssnodgra@pheran.com * Network and Unix Guru(?) at Large
Geek Code: GCS d? s: a C++ U++++$ P+++ L++ w PS+ 5++ b++ DI+ D++ e++ r+++ y+*
"If you want to be somebody else, change your mind."  -Sister Hazel


^ permalink raw reply

* Re: [LARTC] my qos-cbq didn't work
From: Stef Coene @ 2002-12-13 17:04 UTC (permalink / raw)
  To: lartc
In-Reply-To: <marc-lartc-103973481703733@msgid-missing>

On Friday 13 December 2002 00:09, James Ma wrote:
> Hi, All,
>
> I implemented the following qos scripts in my Linux gateway (redhat7.3,
> kernel 2.4.18), put ftp server (10.10.3.49) on one side (eth0 nic) and ftp
> client (10.10.5.3) on the other side (eth1 nic). I tried to up load a file
> (211kbytes) from client to ftp server. I wanted to see a 22kbps
> transmission rate. Quite surprise, the ftp client showed transmission rate
> as 6.8e+02 kbytes/s (211k transmitted in 0.3 seconds). It was the same as
> it without qos implementation. So the conclusion is the QoS was not working
> at all.
>
> Could anybody tell me what's wrong with the setting?
Yes I can.  You have a cbq qdisc attached to a cbq class.  This will cause 
some problems.  I did some test about this (www.docum.org on the test page).  
It's better to create only classes :

tc qdisc add dev eth0 root handle 10: cbq bandwidth 10mbit avpkt 500

tc class add dev eth0 parent 10:0 classid 10:2 cbq bandwidth 10mbit rate
22kbps $OPTION prio 3 bounded 

tc class add dev eth0 parent 10:2 classid 10:10 cbq bandwidth 10mbit rate
11kbps $OPTION prio 3 bounded 

tc class add dev eth0 parent 10:2 classid 10:20 cbq bandwidth 10mbit rate
11kbps $OPTION prio3 bounded 

If you bound 10:10 and 10:20 they are not able to borrow bandwidth from each 
other. 


Stef

-- 

stef.coene@docum.org
 "Using Linux as bandwidth manager"
     http://www.docum.org/
     #lartc @ irc.oftc.net

_______________________________________________
LARTC mailing list / LARTC@mailman.ds9a.nl
http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/

^ permalink raw reply

* [LARTC] HTB bug?
From: Abraham van der Merwe @ 2002-12-13 17:02 UTC (permalink / raw)
  To: lartc

[-- Attachment #1: Type: text/plain, Size: 2515 bytes --]

Hi!

A couple of weeks ago we started using the Linux TC implementation to shape
clients (using HTB) and since then our QoS box started crashing every now
and again (talk about inconvenient timing :P).

First we suspected hardware, but we replaced the hardware this week and it
still keeps crashing. Current machine specs:

Celeron 400 MHz
128MB Ram
128MB Compact Flash storage
Distribution: stripped down Debian (woody)

The machine runs now services whatsoever:

------------< snip <------< snip <------< snip <------------
root@rana:~# netstat -anp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
PID/Program nam
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node PID/Program name
Path
------------< snip <------< snip <------< snip <------------

It has no load whatsoever.

The kernel:

2.4.20rc1 with Andrea Arcangeli's pausing fix applied (I'm running the
kernel on several other machines that have much higher load (read: that
actually has load), including my own workstation and they're all very
stable.

The only other unknown is HTB and so I'm starting to suspect it. I'm using
tc from the iproute ss020116-try tarball with the HTB 3.6 patch applied.

Now the problem is that I don't have enough space to log to disk - I'm just
logging to console (also logging with kernel log level 8 to console). Each
time I get to the machine it is completely dead, and the keyboard leds is
flashing continuously. Unfortunately I can't see whether there is any oopses
or last dying messages since I only have serial console on the machine right
now (no messages to tty) and each time I didn't actually check the serial
console.

I know this isn't a very useful bug report (will try to get something more
useful later on), but I just want to know if somebody else have experienced
the same kind of behaviour lately.

In anycase, I've removed all the rules from the machine and is going to just
to QoS on our Cisco routers again until I resolve the problem :P

-- 

Regards
 Abraham

Real programmers don't write in BASIC.  Actually, no programmers write in
BASIC after reaching puberty.

___________________________________________________
 Abraham vd Merwe [ZR1BBQ] - Frogfoot Networks
 P.O. Box 3472, Matieland, Stellenbosch, 7602
 Cell: +27 82 565 4451 Http: http://www.frogfoot.net/
 Email: abz@frogfoot.net


[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]

^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.