--- linux-2.4.25/drivers/atm/Makefile 2004-02-23 15:18:29.000000000 +0100
+++ linux-2.4.25-atmdd/drivers/atm/Makefile 2004-02-29 22:51:26.000000000 +0100
@@ -31,6 +31,7 @@
- obj-$(CONFIG_ATM_IDT77252) += suni.o
endif
+ obj-$(CONFIG_ATM_DUMMY) += adummy.o
+obj-$(CONFIG_ATM_DD) += atmdd.o
obj-$(CONFIG_ATM_TCP) += atmtcp.o
obj-$(CONFIG_ATM_FIRESTREAM) += firestream.o
--- linux-2.4.25/drivers/atm/Kcnfig 2003-08-25 13:44:41.000000000 +0200
+++ linux-2.4.25-atmdd/drivers/atm/Kconfig 2004-02-29 22:52:59.000000000 +0100
@@ -4,6 +4,14 @@
+ default y
- menu "ATM drivers"
- depends on NETDEVICES && ATM
+ if ATM_DRIVERS && NETDEVICES && ATM
+
+config ATM_DD
+ tristate "ATM loopback"
+ hardware. It supports AAL5 and AAL0. Frames are merely looped back
+ to the sender on the same VC they were sent.
- config ATM_TCP
- tristate "ATM over TCP"
+ config ATM_DUMMY
+ tristate "Dummy ATM driver"
diff -urN linux-2.4.25/drivers/atm/atmdd.c linux-2.4.25-atmdd/drivers/atm/atmdd.c
--- linux-2.4.25/drivers/atm/atmdd.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.25-atmdd/drivers/atm/atmdd.c 2004-02-29 22:58:11.000000000 +0100
-@@ -0,0 +1,920 @@
+@@ -0,0 +1,921 @@
+/*
+#######################################################################
+#
+/*############ Includes ###############################################*/
+
+#include <linux/module.h>
-+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/atm.h>
+static int myatmdd_open(struct atm_vcc *vcc);
+static void myatmdd_close(struct atm_vcc *vcc);
+static int myatmdd_ioctl(struct atm_dev *dev, unsigned int cmd,void *arg);
-+static int myatmdd_setsockopt(struct atm_vcc *vcc,int level,int optname, void *optval,int optlen);
-+static int myatmdd_getsockopt(struct atm_vcc *vcc,int level,int optname, void *optval,int optlen);
++static int myatmdd_setsockopt(struct atm_vcc *vcc,int level,int optname, void __user *optval,unsigned int optlen);
++static int myatmdd_getsockopt(struct atm_vcc *vcc,int level,int optname, void __user *optval,int optlen);
+static int myatmdd_send(struct atm_vcc *vcc,struct sk_buff *skb);
+static int myatmdd_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flgs);
+static int myatmdd_proc_read(struct atm_dev *dev,loff_t *pos,char *page);
+ while ((skb = myatmdd_rxq_dequeue(&priv->rxqueue, &pkt_len)))
+ {
+ struct sk_buff *newskb;
++ struct timeval stamp;
+
+ /* Get a new skb to replace the one just consumed */
+ if (!(newskb = dev_alloc_skb(AAL5_BUFLEN)))
+ atomic_inc(&vcc->stats->rx);
+
+ /* add timestamp for upper layers to use */
-+ do_gettimeofday(&skb->stamp);
++ do_gettimeofday(&stamp);
++ skb->tstamp = timeval_to_ktime(stamp);
+
+ /* Point socket buffer at the right VCC before giving to socket layer */
+ ATM_SKB(skb)->vcc = vcc;
+ return -EINVAL;
+}
+
-+static int myatmdd_getsockopt(struct atm_vcc *vcc,int level,int optname, void *optval,int optlen)
++static int myatmdd_getsockopt(struct atm_vcc *vcc,int level,int optname, void __user *optval,int optlen)
+{
+ return -EINVAL;
+}
+
-+static int myatmdd_setsockopt(struct atm_vcc *vcc,int level,int optname, void *optval,int optlen)
++static int myatmdd_setsockopt(struct atm_vcc *vcc,int level,int optname, void __user *optval,unsigned int optlen)
+{
+ return -EINVAL;
+}
+ return -ENOMEM;
+
+ /* Register the new device */
-+ myatmdd_dev = atm_dev_register(MYATMDD,&myatmdd_ops,-1,NULL);
++ myatmdd_dev = atm_dev_register(MYATMDD,NULL,&myatmdd_ops,-1,NULL);
+
+ /* Were we able to register this device? */
+ if (myatmdd_dev == NULL)