[packages/kernel/LINUX_5_4] - drop atmdd driver

baggins baggins at pld-linux.org
Thu Sep 11 01:34:51 CEST 2025


commit f14f0911a679d66e0e1d9dfbc3760283569756d8
Author: Jan Rękorajski <baggins at pld-linux.org>
Date:   Thu Sep 11 03:34:33 2025 +0200

    - drop atmdd driver

 kernel-atmdd.patch | 953 -----------------------------------------------------
 kernel.spec        |   2 -
 2 files changed, 955 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index cbc1e9bd..9d2508cf 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -176,7 +176,6 @@ Patch50:	kernel-imq.patch
 # by Baggins request:
 # derived from ftp://ftp.cmf.nrl.navy.mil/pub/chas/linux-atm/vbr/vbr-kernel-diffs
 Patch55:	kernel-atm-vbr.patch
-Patch56:	kernel-atmdd.patch
 
 # http://synce.svn.sourceforge.net/svnroot/synce/trunk/patches/linux-2.6.22-rndis_host-wm5.patch
 Patch59:	kernel-rndis_host-wm5.patch
@@ -649,7 +648,6 @@ cd linux-%{basever}
 %endif
 
 %patch -P 55 -p1
-%patch -P 56 -p1
 
 # kernel-rndis_host-wm5.patch
 %patch -P 59 -p1
diff --git a/kernel-atmdd.patch b/kernel-atmdd.patch
deleted file mode 100644
index 6298f6b1..00000000
--- a/kernel-atmdd.patch
+++ /dev/null
@@ -1,953 +0,0 @@
-diff -urN linux-2.4.25/drivers/atm/Makefile linux-2.4.25-atmdd/drivers/atm/Makefile
---- 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 @@
- 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
- obj-$(CONFIG_ATM_LANAI)		+= lanai.o
-diff -urN linux-2.4.25/drivers/atm/Kconfig linux-2.4.25-atmdd/drivers/atm/Kconfig
---- 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 @@
- 	  If you say N, all options in this submenu will be skipped and disabled.
- 
- if ATM_DRIVERS && NETDEVICES && ATM
-+
-+config ATM_DD
-+	tristate "ATM loopback"
-+	depends on INET && ATM
-+	help
-+	  This is an example atm driver.  It does not require any actual ATM
-+	  hardware.  It supports AAL5 and AAL0.  Frames are merely looped back
-+	  to the sender on the same VC they were sent.
- 
- 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 @@
-+/*
-+#######################################################################
-+#
-+# (C) Copyright 2001
-+# Alex Zeffertt, Cambridge Broadband Ltd, ajz at cambridgebroadband.com
-+#
-+# This program is free software; you can redistribute it and/or
-+# modify it under the terms of the GNU General Public License as
-+# published by the Free Software Foundation; either version 2 of
-+# the License, or (at your option) any later version.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+# GNU General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with this program; if not, write to the Free Software
-+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-+# MA 02111-1307 USA
-+#######################################################################
-+# Notes:
-+# 
-+# This is an example atm driver.  It does not require any actual ATM
-+# hardware.  It supports AAL5 and AAL0.  frames are merely looped back
-+# to the sender on the same VC they were sent.
-+# 
-+#######################################################################
-+*/
-+
-+/*############ Includes ###############################################*/
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/atm.h>
-+#include <linux/atmdev.h>
-+#include <linux/skbuff.h>
-+#include <linux/init.h>
-+#include <linux/netdevice.h>
-+#include <linux/sched.h> /* for xtime */
-+
-+/*############ Defines ################################################*/
-+
-+#define MYATMDD "atmdd"
-+#define KLOG_PREAMBLE MYATMDD ": "
-+#define MYATMDD_VPI_BITS 1     /* Allow ?.1.? but not ?.2.? */
-+#define MYATMDD_VCI_BITS 11    /* Allow ?.?.2047 but not ?.?.2048 */
-+#define MYATMDD_PCR 100000
-+#define RXQ_SZ 16
-+#define TXQ_SZ 16
-+#define AAL5_MTU (1510+8) /* Default AAL5 Maximum Transmission Unit (and length of AAL5 buffers) */
-+#define AAL5_BUFLEN (((AAL5_MTU + 47)/48)*48) /* Round up to n*48 bytes */
-+#if 0
-+# define DEBUG(format,args...) printk(format,##args)
-+#else
-+# define DEBUG(format,args...)
-+#endif
-+/*############ Types ##################################################*/
-+
-+/* status flags shared between s/w and emulated h/w */
-+typedef enum {
-+    RX_EMPTY, /* No sk_buff present */
-+    RX_FULL,  /* sk_buff present and awaiting data */
-+    RX_RECVD, /* sk_buff present and contains valid data */
-+} myatmdd_rxstatus_e;
-+
-+/* status flags shared between s/w and emulated h/w */
-+typedef enum {
-+    TX_EMPTY, /* No sk_buff present */
-+    TX_FULL,  /* sk_buff present and awaiting transmission */
-+    TX_SENT,  /* sk_buff present and has been sent */
-+} myatmdd_txstatus_e;
-+
-+typedef struct {
-+    struct sk_buff **start;
-+    struct sk_buff **end;
-+    struct sk_buff **head;
-+    struct sk_buff **tail;
-+
-+    /* everything below this line emulates h/w */
-+    myatmdd_rxstatus_e *status;
-+    struct sk_buff **hw_ptr;
-+    int *pkt_len;
-+
-+} myatmdd_rxq_t;
-+
-+typedef struct {
-+    struct sk_buff **start;
-+    struct sk_buff **end;
-+    struct sk_buff **head;
-+    struct sk_buff **tail;
-+
-+    /* everything below this line emulates h/w */
-+    myatmdd_txstatus_e *status;
-+    struct sk_buff **hw_ptr;
-+    int *pkt_len;
-+
-+} myatmdd_txq_t;
-+
-+typedef struct {
-+} myatmdd_devdata_t;
-+
-+typedef struct {
-+    myatmdd_rxq_t rxqueue;
-+    myatmdd_txq_t txqueue;
-+} myatmdd_vccdata_t;
-+
-+/*############ Module paramters #######################################*/
-+
-+MODULE_AUTHOR("Alex Zeffertt, ajz at cambridgebroadband.com");
-+MODULE_DESCRIPTION("Example ATM device driver (loopback)");
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("GPL");
-+#endif
-+/*#################### Forward declarations ###########################*/
-+
-+static void myatmdd_emulate_loopback_hardware(struct atm_vcc *vcc);
-+
-+static void myatmdd_free_tx_skb(struct sk_buff *skb);
-+
-+/* these functions will need modifying in a real ATM driver */
-+static void myatmdd_rx_interrupt(struct atm_vcc *vcc);
-+static void myatmdd_tx_interrupt(struct atm_vcc *vcc);
-+
-+/* functions for manipulating circular bufs */
-+static int myatmdd_init_rxq(myatmdd_rxq_t *queue, int size);
-+static int myatmdd_init_txq(myatmdd_txq_t *queue, int size);
-+static int myatmdd_release_rxq(myatmdd_rxq_t *queue);
-+static int myatmdd_release_txq(myatmdd_txq_t *queue);
-+static int myatmdd_txq_enqueue(myatmdd_txq_t *queue, struct sk_buff *skb);
-+static int myatmdd_rxq_enqueue(myatmdd_rxq_t *queue, struct sk_buff *skb /* empty buffer */);
-+static struct sk_buff *myatmdd_txq_dequeue(myatmdd_txq_t *queue);
-+static struct sk_buff *myatmdd_rxq_dequeue(myatmdd_rxq_t *queue, int *pkt_len);
-+
-+/* myatmdd_ops registered by ATM device */
-+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 __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);
-+
-+/* myatmdd_phy_ops registered by phy driver */
-+static void myatmdd_phy_int(struct atm_dev *dev);
-+static int myatmdd_phy_start(struct atm_dev *dev); /* <-- This is the only thing exported by PHY driver */
-+static int myatmdd_phy_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg);
-+
-+/*#################### Global scope variables #########################*/
-+
-+/* operations registered by the atm device */
-+static const struct atmdev_ops myatmdd_ops =
-+{
-+	open:        myatmdd_open,
-+	close:       myatmdd_close,
-+	ioctl:       myatmdd_ioctl,
-+	getsockopt:  myatmdd_getsockopt,
-+	setsockopt:  myatmdd_setsockopt,
-+	send:        myatmdd_send,
-+	change_qos:  myatmdd_change_qos,
-+	proc_read:   myatmdd_proc_read,
-+    owner:       THIS_MODULE,
-+};
-+
-+/* operations registered by the phy driver */
-+static const struct atmphy_ops myatmdd_phy_ops = {
-+	start:      myatmdd_phy_start,
-+	ioctl:      myatmdd_phy_ioctl,
-+	interrupt:  myatmdd_phy_int,
-+};
-+
-+struct atm_dev *myatmdd_dev;
-+
-+/*#################### Function definitions ###########################*/
-+
-+
-+/*
-+#########################################################
-+#
-+#  Function : myatmdd_rx_interrupt, and myatmdd_tx_interrupt
-+#             
-+#  Purpose  : handle interrupt from hardware.  In first 
-+#             case this means extract recvd buffers and pass
-+#             it up protocol stack.  In 2nd case this means
-+#             free the sent buffers.
-+#             
-+#  Args     : pointer to private data of the VCC concerned
-+#             
-+#  Returns  : nowt
-+#             
-+#  Notes    : 
-+#             
-+##########################################################
-+#  Edit history:
-+#  Who     When    What
-+#  AJZ     10Apr03 Created
-+##########################################################
-+*/
-+
-+static void myatmdd_rx_interrupt(struct atm_vcc *vcc)
-+{
-+    struct sk_buff *skb;
-+    myatmdd_vccdata_t *priv = vcc->dev_data;
-+    int pkt_len;
-+
-+    DEBUG("%s\n", __FUNCTION__);
-+
-+    while ((skb = myatmdd_rxq_dequeue(&priv->rxqueue, &pkt_len)))
-+    {
-+        struct sk_buff *newskb;
-+
-+        /* Get a new skb to replace the one just consumed */
-+        if (!(newskb = dev_alloc_skb(AAL5_BUFLEN)))
-+        {
-+            atomic_inc(&vcc->stats->rx_err);
-+            printk(KERN_ERR KLOG_PREAMBLE "cannot receive packet - out of memory\n");
-+            /* put skb back in rx queue) */
-+            myatmdd_rxq_enqueue(&priv->rxqueue, skb);
-+            return;
-+        }
-+        myatmdd_rxq_enqueue(&priv->rxqueue, newskb);
-+
-+        if (!atm_charge (vcc, skb->truesize))
-+        {
-+            /* Exceeded memory quota for this vcc
-+             * NOTE: if atm_charge succeeds you must then push or accounting will screw up
-+             */
-+            dev_kfree_skb(skb);
-+            /* &vcc->stats->drop stats incremented in atm_charge */
-+        }
-+        else
-+        {
-+            /* sk_buff passed all sanity checks! */
-+            
-+            /* Add received length to socket buffer */
-+            skb_put(skb, pkt_len);
-+        
-+            /* update device stats */
-+            atomic_inc(&vcc->stats->rx);
-+
-+            /* add timestamp for upper layers to use */
-+            ktime_t kt = ktime_get_real();
-+            skb->tstamp = kt;
-+        
-+            /* Point socket buffer at the right VCC before giving to socket layer */
-+            ATM_SKB(skb)->vcc = vcc;
-+        
-+            /* push socket buffer up to ATM layer */
-+            vcc->push(vcc, skb);
-+        }
-+    }
-+}
-+
-+static void myatmdd_tx_interrupt(struct atm_vcc *vcc)
-+{
-+    struct sk_buff *skb;
-+    myatmdd_vccdata_t *priv = vcc->dev_data;
-+
-+    DEBUG("%s\n", __FUNCTION__);
-+
-+    while ((skb = myatmdd_txq_dequeue(&priv->txqueue)))
-+    {
-+        // Update channel stats and free the memory
-+        atomic_inc(&vcc->stats->tx);
-+        myatmdd_free_tx_skb(skb);
-+    }
-+}
-+
-+/*
-+#########################################################
-+#
-+#  Function : myatmdd_emulate_loopback_hardware
-+#             
-+#  Purpose  : emulate things normally done by hardware
-+#             i.e. copying tx bufs to rx bufs (we're modelling
-+#             a loopback system here), calling the tx done
-+#             interrupt, and calling the rx done interrupt.
-+#
-+#  Args     : priv = data private to VCC
-+#             
-+#  Returns  : nowt
-+#             
-+#  Notes    : 
-+#             
-+##########################################################
-+#  Edit history:
-+#  Who     When    What
-+#  AJZ     10Apr03 Created
-+##########################################################
-+*/
-+static void myatmdd_emulate_loopback_hardware(struct atm_vcc *vcc)
-+{
-+    myatmdd_vccdata_t *priv = vcc->dev_data;
-+    struct sk_buff **ptxskb;
-+    struct sk_buff **prxskb;
-+
-+    DEBUG("%s\n", __FUNCTION__);
-+
-+    ptxskb = priv->txqueue.hw_ptr;
-+    prxskb = priv->rxqueue.hw_ptr;
-+
-+    /* Send each tx buff waiting to go */
-+    while (priv->txqueue.status[ptxskb - priv->txqueue.start] == TX_FULL)
-+    {
-+        struct sk_buff *txskb = *ptxskb;
-+        struct sk_buff *rxskb = *prxskb;
-+        int pkt_len = priv->txqueue.pkt_len[ptxskb - priv->txqueue.start];
-+        
-+        /* Is there an rx buffer? */
-+        if (priv->rxqueue.status[prxskb - priv->rxqueue.start] == RX_FULL)
-+        {
-+            /* Yes - Is the length in range? */
-+            if (pkt_len <= AAL5_BUFLEN)
-+            {
-+                /* Yes - do the copy */
-+                memcpy(rxskb->data, txskb->data,pkt_len);
-+                priv->rxqueue.pkt_len[prxskb - priv->rxqueue.start] = pkt_len;
-+                
-+                /* Indicate rx buffer recvd */
-+                priv->rxqueue.status[prxskb - priv->rxqueue.start] = RX_RECVD;
-+                
-+                /* increment and maybe wrap rx pointer */
-+                if (++prxskb == priv->rxqueue.end)
-+                    prxskb = priv->rxqueue.start;
-+                priv->rxqueue.hw_ptr = prxskb;
-+            }
-+            else
-+            {
-+                /* No - then h/w cannot do a recv */
-+                printk(KERN_ERR KLOG_PREAMBLE "recvd frame too long - discarded\n");
-+            }
-+        }
-+        else
-+        {
-+            /* No - then h/w cannot do a recv */
-+            printk(KERN_ERR KLOG_PREAMBLE "no rx buffers available\n");
-+        }
-+        
-+        /* Indicate tx buffer sent */
-+        priv->txqueue.status[ptxskb - priv->txqueue.start] = TX_SENT;
-+
-+        /* increment and maybe wrap tx pointer */
-+        if (++ptxskb == priv->txqueue.end)
-+            ptxskb = priv->txqueue.start;
-+        priv->txqueue.hw_ptr = ptxskb;
-+        
-+        /* Call tx ring interrupt handler */
-+        myatmdd_tx_interrupt(vcc);
-+           
-+        /* Call tx ring interrupt handler */
-+        myatmdd_rx_interrupt(vcc);
-+    }
-+}
-+
-+/*
-+#########################################################
-+#
-+#  Function : functions for manipulating circular buffs
-+#             
-+#  Purpose  : 
-+#             
-+#  Args     : 
-+#             
-+#  Returns  : 
-+#             
-+#  Notes    : 
-+#             
-+##########################################################
-+#  Edit history:
-+#  Who     When    What
-+#  AJZ     10Apr03 Created
-+##########################################################
-+*/
-+
-+static int myatmdd_init_rxq(myatmdd_rxq_t *queue, int size)
-+{
-+    /* TODO - cope with kmalloc failure */
-+    struct sk_buff **pskb;
-+    int i;
-+
-+    DEBUG("%s\n", __FUNCTION__);
-+    queue->hw_ptr = queue->head = queue->tail = 
-+        queue->start = kmalloc(size * sizeof(struct sk_buff *), GFP_KERNEL);
-+    queue->end = &queue->start[size];
-+    for (pskb = queue->start; pskb < queue->end; pskb++)
-+        *pskb = NULL;
-+
-+    queue->status = kmalloc(size * sizeof(myatmdd_rxstatus_e),GFP_KERNEL);
-+    for (i = 0; i < size; i++)
-+        queue->status[i] = RX_EMPTY;
-+
-+    queue->pkt_len = kmalloc(size * sizeof(int),GFP_KERNEL);
-+    for (i = 0; i < size; i++)
-+        queue->pkt_len[i] = 0;
-+
-+    return 0;
-+}
-+
-+static int myatmdd_init_txq(myatmdd_txq_t *queue, int size)
-+{
-+    /* TODO - cope with kmalloc failure */
-+    struct sk_buff **pskb;
-+    int i;
-+
-+    DEBUG("%s\n", __FUNCTION__);
-+    queue->hw_ptr = queue->head = queue->tail = 
-+        queue->start = kmalloc(size * sizeof(struct sk_buff *), GFP_KERNEL);
-+    queue->end = &queue->start[size];
-+    for (pskb = queue->start; pskb < queue->end; pskb++)
-+        *pskb = NULL;
-+
-+    queue->status = kmalloc(size * sizeof(myatmdd_rxstatus_e),GFP_KERNEL);
-+    for (i = 0; i < size; i++)
-+        queue->status[i] = TX_EMPTY;
-+
-+    queue->pkt_len = kmalloc(size * sizeof(int),GFP_KERNEL);
-+    for (i = 0; i < size; i++)
-+        queue->pkt_len[i] = 0;
-+
-+    return 0;
-+}
-+
-+static int myatmdd_release_rxq(myatmdd_rxq_t *queue)
-+{
-+    struct sk_buff **pskb;
-+
-+    DEBUG("%s\n", __FUNCTION__);
-+    for (pskb = queue->start; pskb < queue->end; pskb++)
-+    {
-+        /* Is there an skb here */
-+        if (*pskb == NULL)
-+            continue;   /* No, so skip this entry in ring */
-+
-+        /* Yes - free it */
-+        dev_kfree_skb(*pskb);
-+    }
-+    kfree(queue->start);
-+    kfree(queue->status);
-+    kfree(queue->pkt_len);
-+
-+    return 0;
-+}
-+
-+static int myatmdd_release_txq(myatmdd_txq_t *queue)
-+{
-+    struct sk_buff **pskb;
-+
-+    DEBUG("%s\n", __FUNCTION__);
-+    /* Scan through all TX bd's and cleanup */
-+    for (pskb = queue->start; pskb < queue->end; pskb++)
-+    {  
-+        /* Is this buffer currently unused - i.e. no skb */
-+        if (*pskb == NULL)
-+            continue;             /* Yes, so ignore it */
-+
-+        /* If we reach here, we have found a socket buffer that
-+         * exists in the TX ring and is waiting to be released.
-+         */
-+        printk(KERN_WARNING KLOG_PREAMBLE "discarding unsent tx sk_buff\n");
-+        atomic_inc(&ATM_SKB(*pskb)->vcc->stats->tx_err);
-+        myatmdd_free_tx_skb(*pskb);
-+    }
-+    kfree(queue->start);
-+    kfree(queue->status);
-+    kfree(queue->pkt_len);
-+
-+    return 0;
-+}
-+
-+/* returns non-zero for "out of space" */
-+static int myatmdd_txq_enqueue(myatmdd_txq_t *queue, struct sk_buff *skb)
-+{
-+    /* increment head and wrap */
-+    struct sk_buff **newhead = queue->head + 1;
-+    if (newhead == queue->end)
-+        newhead = queue->start;
-+
-+    DEBUG("%s\n", __FUNCTION__);
-+
-+    /* abort if tx ring full */
-+    if (newhead == queue->tail)
-+        return -1;
-+    
-+    /* all is okay if we're here */
-+    *queue->head = skb;
-+    /* Tell hardware there's a buffer to send */
-+    queue->status[queue->head - queue->start] = TX_FULL;
-+    queue->pkt_len[queue->head - queue->start] = skb->len;
-+    queue->head = newhead;
-+    return 0;
-+}
-+
-+/* returns non-zero for "out of space" */
-+static int myatmdd_rxq_enqueue(myatmdd_rxq_t *queue, struct sk_buff *skb /* empty buffer */)
-+{
-+    /* increment head and wrap */
-+    struct sk_buff **newhead = queue->head + 1;
-+    if (newhead == queue->end)
-+        newhead = queue->start;
-+
-+    DEBUG("%s\n", __FUNCTION__);
-+
-+    /* abort if rx ring full */
-+    if (newhead == queue->tail)
-+        return -1;
-+    
-+    /* all is okay if we're here */
-+    *queue->head = skb;
-+    /* Tell hardware there's a buffer to send */
-+    queue->status[queue->head - queue->start] = RX_FULL;
-+    queue->head = newhead;
-+    return 0;
-+}
-+
-+static struct sk_buff *myatmdd_txq_dequeue(myatmdd_txq_t *queue)
-+{
-+    DEBUG("%s\n", __FUNCTION__);
-+    if (queue->tail != queue->head && queue->status[queue->tail - queue->start] == TX_SENT)
-+    {
-+        struct sk_buff *skb = *queue->tail;
-+
-+        /* increment tail and wrap */
-+        struct sk_buff **newtail = queue->tail + 1;
-+        if (newtail == queue->end)
-+            newtail = queue->start;
-+        *queue->tail = NULL;
-+        queue->status[queue->tail - queue->start] = TX_EMPTY;
-+        queue->tail = newtail;
-+        return skb;
-+    }
-+    return NULL;
-+}
-+
-+/* returns NULL for "no new recvd frames" */
-+static struct sk_buff *myatmdd_rxq_dequeue(myatmdd_rxq_t *queue, int *pkt_len)
-+{
-+    DEBUG("%s\n", __FUNCTION__);
-+    if (queue->tail != queue->head && queue->status[queue->tail - queue->start] == RX_RECVD)
-+    {
-+        struct sk_buff *skb = *queue->tail;
-+
-+        /* increment tail and wrap */
-+        struct sk_buff **newtail = queue->tail + 1;
-+        if (newtail == queue->end)
-+            newtail = queue->start;
-+        *queue->tail = NULL;
-+        queue->status[queue->tail - queue->start] = RX_EMPTY;
-+        *pkt_len = queue->pkt_len[queue->tail - queue->start];
-+        queue->tail = newtail;
-+        return skb;
-+    }
-+    return NULL;
-+}
-+
-+/*
-+#########################################################
-+#
-+#  Functions : 	Implementations of function ptrs in
-+#               myatmdd_phy_ops.  This is the phy driver
-+#	start:      myatmdd_phy_start,
-+#	ioctl:      myatmdd_phy_ioctl,
-+#	interrupt:  myatmdd_phy_int,
-+#             
-+#  Purpose  : See ATM device driver interface v0.1
-+#             
-+#  Notes    : Conforming to Linux ATM device driver i/f
-+#             interface.  Draft version 0.1
-+#             
-+#             Designed to work with multiple devices
-+##########################################################
-+#  Edit history:
-+#  Who     When    What
-+#  AJZ     10Apr03 Created
-+##########################################################
-+*/
-+static int myatmdd_phy_start(struct atm_dev *dev)
-+{
-+    /* Provide ATM driver with a pointer via which it
-+     * may invoke PHY driver's IOCTL or interrupt 
-+     * handlers.
-+     */
-+    dev->phy = &myatmdd_phy_ops;
-+
-+    /* If required allocate phy private data and save
-+     * pointer in dev->phy_data;
-+     */
-+    
-+    /* TODO Initialise PHY hardware... */
-+
-+    return 0;
-+}
-+
-+/* Should be called by SAR driver when it needs to handle an interrupt
-+ * triggered by PHY.
-+ */
-+static void myatmdd_phy_int(struct atm_dev *dev)
-+{
-+    /* Handle interrupt triggered by PHY */
-+}
-+
-+/* Gets called by SAR driver IOCTL handler for IOCTLS it doesn't recognise */
-+static int myatmdd_phy_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg)
-+{
-+	switch (cmd)
-+    {
-+//		case SONET_GETSTATZ:
-+        default:
-+            return -EINVAL;
-+    }
-+}
-+
-+/*
-+#########################################################
-+#
-+#  Function : myatmdd_free_tx_skb
-+#             
-+#  Purpose  : frees an sk_buff.
-+#             
-+#  Args     : skb=pointer to socket buffer
-+#             
-+#  Notes    : Tries to use the upper layer pop() function
-+#             but uses dev_kfree_skb() if this doesn't exist
-+##########################################################
-+#  Edit history:
-+#  Who     When    What
-+#  AJZ     10Apr03 Created
-+##########################################################
-+*/
-+static void myatmdd_free_tx_skb(struct sk_buff *skb)
-+{  
-+    struct atm_vcc *vcc;
-+
-+    DEBUG("%s\n", __FUNCTION__);
-+
-+    /* See if we can use the VCC pop function */
-+    if (((vcc = ATM_SKB(skb)->vcc) != NULL) && (vcc->pop != NULL))
-+    {
-+        /* Yes, so use ATM socket layer pop function */
-+        vcc->pop(vcc, skb);
-+    }
-+    else
-+    {  
-+        printk(KERN_WARNING KLOG_PREAMBLE "unable to call skb free function\n");
-+        /* No, so free socket buffer */
-+        dev_kfree_skb(skb);
-+    }
-+}
-+
-+/*
-+#########################################################
-+#
-+#  Functions : 	Implementations of function ptrs in
-+#               myatmdd_ops.
-+#   myatmdd_open(),
-+#	myatmdd_close(),
-+#	myatmdd_ioctl(),
-+#	myatmdd_getsockopt(),
-+#	myatmdd_setsockopt(),
-+#	myatmdd_send(),
-+#	myatmdd_sg_send(),
-+#	myatmdd_change_qos(),
-+#	myatmdd_proc_read()
-+# 
-+#             
-+#  Purpose  : See ATM device driver interface v0.1
-+#             
-+#  Notes    : Conforming to Linux ATM device driver i/f
-+#             interface.  Draft version 0.1
-+#             
-+#             Designed to work with multiple devices
-+##########################################################
-+#  Edit history:
-+#  Who     When    What
-+#  AJZ     10Apr03 Created
-+##########################################################
-+*/
-+static int myatmdd_open(struct atm_vcc *vcc)
-+{
-+    myatmdd_vccdata_t *priv;
-+    int i;
-+
-+    DEBUG("%s\n", __FUNCTION__);
-+
-+    /* Make sure we are opening a AAL0 or AAL5 connection */
-+    if ((vcc->qos.aal != ATM_AAL5) && (vcc->qos.aal != ATM_AAL0))
-+    {
-+        printk(KERN_WARNING KLOG_PREAMBLE "invalid AAL\n");
-+        return -EINVAL;
-+    }
-+
-+    /* Address is in use */
-+    set_bit(ATM_VF_ADDR, &vcc->flags);
-+
-+    /* Allocate some vcc-private memory */
-+    vcc->dev_data = kmalloc(sizeof(myatmdd_vccdata_t), GFP_KERNEL);
-+    if (vcc->dev_data == NULL)
-+        return -ENOMEM;
-+    priv = vcc->dev_data;
-+
-+    /* Setup the hardware for new VC... */
-+
-+    /* Do not allow half open VCs - otherwise the example driver will not be able
-+     * to loop back frames sent !
-+     */
-+    if (vcc->qos.rxtp.traffic_class == ATM_NONE || vcc->qos.txtp.traffic_class == ATM_NONE)
-+    {
-+        kfree(vcc->dev_data);
-+        return -EPERM;
-+    }
-+
-+    /* Create rx/tx queues for this VC */
-+    myatmdd_init_txq(&priv->txqueue, TXQ_SZ);
-+    myatmdd_init_rxq(&priv->rxqueue, RXQ_SZ);
-+    
-+    /* Fill rx queue with empty skbuffs */
-+    for (i = 0 ; i < RXQ_SZ - 1; i++)
-+    {
-+        struct sk_buff *skb = dev_alloc_skb(AAL5_BUFLEN);
-+        myatmdd_rxq_enqueue(&priv->rxqueue,skb);
-+    }
-+   
-+    /* Connection is now ready to receive data */
-+    set_bit(ATM_VF_READY, &vcc->flags);
-+
-+    return 0;
-+}
-+
-+static void myatmdd_close(struct atm_vcc *vcc)
-+{
-+    myatmdd_vccdata_t *priv = vcc->dev_data;
-+
-+    DEBUG("%s\n", __FUNCTION__);
-+
-+    /* Indicate channel closed */
-+    clear_bit(ATM_VF_READY, &vcc->flags);
-+
-+    /* TODO Uninitialise the hardware for this VC... */
-+    
-+    /* empty the rx and tx queues */
-+    myatmdd_release_txq(&priv->txqueue);
-+    myatmdd_release_rxq(&priv->rxqueue);
-+
-+    /* Free the vcc-private memory */
-+    kfree(vcc->dev_data);
-+}
-+  
-+static int myatmdd_ioctl(struct atm_dev *dev, unsigned int cmd,void *arg)
-+{
-+    /* myatmdd does not currently have an ioctl interface so pass ioctl onto PHY */
-+    if (dev->phy && dev->phy->ioctl) {
-+        return dev->phy->ioctl(dev, cmd, arg);
-+    }
-+    return -EINVAL;
-+}
-+
-+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 __user *optval,unsigned int optlen)
-+{
-+    return -EINVAL;
-+}
-+
-+/* Note may be called in either process or interrupt context! */
-+static int myatmdd_send(struct atm_vcc *vcc,struct sk_buff *skb)
-+{
-+    myatmdd_vccdata_t *priv = vcc->dev_data;
-+
-+    DEBUG("%s\n", __FUNCTION__);
-+
-+    /* Assign VCC to socket buffer
-+     * Note: this must be done before attempting to call
-+     * myatmdd_free_tx_skb() as this may use ATM_SKB(skb)->vcc->pop()
-+     */
-+    ATM_SKB(skb)->vcc = vcc;
-+
-+    /* Setup hardware to send and arrange callback of myatmdd_send_complete... */
-+
-+    /* In this example ATM device driver all VCs are looped back.
-+     * So copy to the rxq and emulate an rx interrupt
-+     */
-+
-+    /* Can we accept another skb to send ? */
-+    if (myatmdd_txq_enqueue(&priv->txqueue, skb))
-+    {
-+        /* No - free socket buffer */
-+        myatmdd_free_tx_skb(skb);
-+        
-+        /* Update tx channel stats */
-+        atomic_inc(&vcc->stats->tx_err);
-+        
-+        /* Tell protocol layer to back off */
-+        return(-EBUSY);
-+    }
-+
-+    /* This is the bit which copies the tx ring to the rx ring,
-+     * and triggers emulated rx and tx interrupts
-+     */
-+    myatmdd_emulate_loopback_hardware(vcc);
-+    
-+    return 0;
-+}
-+
-+static int myatmdd_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flgs)
-+{
-+    return 0;
-+}
-+
-+static int myatmdd_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
-+{
-+    int left = (int) *pos;
-+    
-+    if (!left--)
-+        return sprintf(page, "1st line of stats\n");
-+    if (!left--)
-+        return sprintf(page, "2nd line of stats\n");
-+    if (!left--)
-+        return sprintf(page, "3rd line of stats\n");
-+
-+    return 0;
-+}
-+
-+/*
-+#########################################################
-+#
-+#  Function : myatmdd_init
-+#             
-+#  Purpose  : init the module, init and register the ATM device
-+#             
-+#  Args     : none
-+#             
-+#  Returns  : return code
-+#             
-+#  Notes    : 
-+#             
-+##########################################################
-+#  Edit history:
-+#  Who     When    What
-+#  AJZ     10Apr03 Created
-+##########################################################
-+*/
-+int __init myatmdd_init(void)
-+{
-+    myatmdd_devdata_t *priv = kmalloc(sizeof(myatmdd_devdata_t),GFP_KERNEL);
-+
-+    if (priv == NULL)
-+        return -ENOMEM;
-+
-+    /* Register the new device */
-+    myatmdd_dev = atm_dev_register(MYATMDD,NULL,&myatmdd_ops,-1,NULL);
-+    
-+    /* Were we able to register this device? */
-+    if (myatmdd_dev == NULL)
-+    {
-+        printk(KERN_ERR KLOG_PREAMBLE "failed to register CPM ATM device\n");
-+        return -EPERM;
-+    }
-+
-+    /* Save pointer to device private data */
-+    myatmdd_dev->dev_data = priv;
-+
-+    /* Initialise device parameters */
-+    myatmdd_dev->ci_range.vpi_bits = MYATMDD_VPI_BITS;
-+    myatmdd_dev->ci_range.vci_bits = MYATMDD_VCI_BITS;
-+    myatmdd_dev->link_rate = MYATMDD_PCR;
-+    
-+    /* Set up phy device */
-+    myatmdd_phy_start(myatmdd_dev);
-+    
-+    /* TODO Initialise SAR hardware... */
-+
-+    /* Console output */
-+    printk(KERN_INFO KLOG_PREAMBLE "Initialised\n");
-+
-+    return 0;
-+}
-+
-+/* NOTE:
-+ * module_init() is called by insmod, if built as module, 
-+ * or by do_initcalls(), if built as a resident driver.
-+ */
-+module_init(myatmdd_init);
-+
-+/*
-+#########################################################
-+#
-+#  Function : myatmdd_exit
-+#             
-+#  Purpose  : delete module, uninit and dereg ATM device
-+#             
-+#  Args     : none
-+#             
-+#  Returns  : none
-+#             
-+#  Notes    : 
-+#             
-+##########################################################
-+#  Edit history:
-+#  Who     When    What
-+#  AJZ     10Apr03 Created
-+##########################################################
-+*/
-+
-+#ifdef MODULE
-+static void __exit myatmdd_exit(void)
-+{
-+    /* Disable SAR hardware... */
-+
-+    /* Console output */
-+    printk(KERN_ERR KLOG_PREAMBLE "Uninitialised\n");
-+    kfree(myatmdd_dev->dev_data);
-+    atm_dev_deregister(myatmdd_dev);
-+}
-+module_exit(myatmdd_exit);
-+
-+#endif /* MODULE */
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/kernel.git/commitdiff/f14f0911a679d66e0e1d9dfbc3760283569756d8



More information about the pld-cvs-commit mailing list