diff -ur --new-file old/linux/drivers/atm/eni.c new/linux/drivers/atm/eni.c
--- old/linux/drivers/atm/eni.c	Wed Nov 13 23:49:47 1996
+++ new/linux/drivers/atm/eni.c	Wed Nov 13 23:50:18 1996
@@ -423,6 +423,10 @@
 	j = j >> 1;
 	dma_wr = eni_dev->reg[MID_DMA_WR_RX];
 	dma_rd = eni_dev->reg[MID_DMA_RD_RX];
+	/*
+	 * Can I move the dma_wr pointer by 2j+1 positions without overwriting
+	 * data that hasn't been read (position of dma_rd) yet ?
+	 */
 	if (!NEPMOK(dma_wr,j+j+1,dma_rd,NR_DMA_RX)) { /* @@@ +1 is ugly */
 		printk(KERN_WARNING DEV_LABEL "(itf %d): RX DMA full\n",
 		    vcc->dev->number);
@@ -956,9 +960,13 @@
 		size = ((size-(size % ATM_CELL_PAYLOAD)) >> 2)+TX_DESCR_SIZE;
 						/* add segmentation header */
 	}
+	/*
+	 * Can I move tx_pos by size bytes without getting closer than TX_GAP
+	 * to the read pointer ? TX_GAP means to leave some space for what
+	 * the manual calls "too close".
+	 */
 	if (!NEPMOK(tx->tx_pos,size+TX_GAP,
 	    eni_dev->reg[MID_TX_RDPTR(tx->index)],tx->words)) {
-	    /* leave some space for "too close" */
 		DPRINTK(DEV_LABEL "(itf %d): TX full (size %ld)\n",
 		    vcc->dev->number,size);
 		return enq_next;
diff -ur --new-file old/linux/include/linux/atmdev.h new/linux/include/linux/atmdev.h
--- old/linux/include/linux/atmdev.h	Wed Nov 13 23:49:47 1996
+++ new/linux/include/linux/atmdev.h	Wed Nov 13 23:50:18 1996
@@ -123,8 +123,8 @@
 #define ATM_VF_META	128	/* SVC socket isn't used for normal data
 				   traffic and doesn't depend on signaling
 				   to be available */
-#define ATM_VF_AQREL	256	/* Arequipa socket is being released */
-#define ATM_VF_AQINUSE	512	/* socket is available for Arequipa use */
+#define ATM_VF_AQREL	256	/* Arequipa VC is being released */
+#define ATM_VF_AQDANG	512	/* VC is in Arequipa's dangling list */
 #define ATM_VF_SCRX	ATM_SC_RX /* 1024; allow single-copy in the RX dir. */
 #define ATM_VF_SCTX	ATM_SC_TX /* 2048; allow single-copy in the TX dir. */
 
diff -ur --new-file old/linux/include/linux/atmsap.h new/linux/include/linux/atmsap.h
--- old/linux/include/linux/atmsap.h	Wed Nov 13 23:49:47 1996
+++ new/linux/include/linux/atmsap.h	Wed Nov 13 23:50:18 1996
@@ -19,14 +19,14 @@
 /* BEGIN_L2 */
 #define ATM_L2_NONE	0	/* L2 not specified */
 #define ATM_L2_ISO1745  0x01	/* Basic mode ISO 1745 */
-#define ATM_L2_Q291	0x02	/* ITU-T Q.291 */
+#define ATM_L2_Q291	0x02	/* ITU-T Q.291 (Rec. I.441) */
 #define ATM_L2_X25_LL	0x06	/* ITU-T X.25, link layer */
 #define ATM_L2_X25_ML	0x07	/* ITU-T X.25, multilink */
-#define ATM_L2_LAPB	0x08	/* Extended LAPB, half-duplex */
-#define ATM_L2_HDLC_ARM	0x09	/* HDLC ARM (ISO 4335) */
-#define ATM_L2_HDLC_NRM	0x0a	/* HDLC NRM (ISO 4335) */
-#define ATM_L2_HDLC_ABM	0x0b	/* HDLC ABM (ISO 4335) */
-#define ATM_L2_ISO8802	0x0c	/* LAN LLC (ISO 8802/2) */
+#define ATM_L2_LAPB	0x08	/* Extended LAPB, half-duplex (Rec. T.71) */
+#define ATM_L2_HDLC_ARM	0x09	/* HDLC ARM (ISO/IEC 4335) */
+#define ATM_L2_HDLC_NRM	0x0a	/* HDLC NRM (ISO/IEC 4335) */
+#define ATM_L2_HDLC_ABM	0x0b	/* HDLC ABM (ISO/IEC 4335) */
+#define ATM_L2_ISO8802	0x0c	/* LAN LLC (ISO/IEC 8802/2) */
 #define ATM_L2_X75	0x0d	/* ITU-T X.75, SLP */
 #define ATM_L2_Q922	0x0e	/* ITU-T Q.922 */
 #define ATM_L2_USER	0x10	/* user-specified */
@@ -42,8 +42,8 @@
 #define ATM_L3_NONE	0	/* L3 not specified */
 #define ATM_L3_X25	0x06	/* ITU-T X.25, packet layer */
 #define ATM_L3_ISO8208	0x07	/* ISO/IEC 8208 */
-#define ATM_L3_X223	0x08	/* ITU-T X.223/ISO 8878 */
-#define ATM_L3_ISO8473	0x09	/* ISO/IEC 8473 */
+#define ATM_L3_X223	0x08	/* ITU-T X.223 | ISO/IEC 8878 */
+#define ATM_L3_ISO8473	0x09	/* ITU-T X.223 | ISO/IEC 8473 */
 #define ATM_L3_T70	0x0a	/* ITU-T T.70 minimum network layer */
 #define ATM_L3_TR9577	0x0b	/* ISO/IEC TR 9577 */
 #define ATM_L3_USER	0x10	/* user-specified */
diff -ur --new-file old/linux/include/net/sock.h new/linux/include/net/sock.h
--- old/linux/include/net/sock.h	Wed Nov 13 23:49:52 1996
+++ new/linux/include/net/sock.h	Wed Nov 13 23:50:19 1996
@@ -323,7 +323,7 @@
 	struct socket		*arequipa;   /* dedicated link layer socket,
 						NULL if not connected */
 	struct rtable		*aq_route;   /* buffer for fake route, NULL
-						if neither present nor expect */
+						if neither preset nor expect */
 #endif
 
 /*
diff -ur --new-file old/linux/net/atm/arequipa.c new/linux/net/atm/arequipa.c
--- old/linux/net/atm/arequipa.c	Wed Nov 13 23:49:48 1996
+++ new/linux/net/atm/arequipa.c	Wed Nov 13 23:50:19 1996
@@ -57,7 +57,7 @@
 };
 
 
-static struct atm_vcc *aq_list = NULL;
+static struct atm_vcc *aq_list = NULL; /* dangling Arequipa VCs */
 static unsigned long aq_generation = 0;
 
 
@@ -67,11 +67,11 @@
 
 	save_flags(flags);
 	cli();
-	if (!(vcc->flags & ATM_VF_AQINUSE)) {
+	if (!(vcc->flags & ATM_VF_AQDANG)) {
 		restore_flags(flags);
 		return;
 	}
-	vcc->flags &= ~ATM_VF_AQINUSE;
+	vcc->flags &= ~ATM_VF_AQDANG;
 	if (vcc->aq_prev) vcc->aq_prev->aq_next = vcc->aq_next;
 	else aq_list = vcc->aq_next;
 	if (vcc->aq_next) vcc->aq_next->aq_prev = vcc->aq_prev;
@@ -191,7 +191,7 @@
 }
 
 
-static void make_aq_vcc(struct socket *lower)
+static void make_aq_vcc(struct socket *lower,int incoming)
 {
 	struct atm_vcc *vcc;
 	unsigned long flags;
@@ -204,9 +204,12 @@
 	vcc->push = atm_push_arequipa;
 	vcc->peek = atm_peek_clip;
 	vcc->push_oam = NULL;
-	vcc->aq_next = aq_list;
-	vcc->aq_prev = NULL;
-	aq_list = vcc;
+	if (incoming) {
+	    vcc->flags |= ATM_VF_AQDANG;
+	    vcc->aq_next = aq_list;
+	    vcc->aq_prev = NULL;
+	    aq_list = vcc;
+	}
 	vcc->generation = aq_generation++;
 	restore_flags(flags);
 	lower->file->f_count++;
@@ -215,6 +218,7 @@
 
 static int arequipa_attach_unchecked(struct socket *lower,struct sock *upper)
 {
+	unsigned long flags;
 	struct rtable *rt;
 	int error;
 
@@ -225,7 +229,10 @@
 	}
 	error = check_aq_vcc(lower);
 	if (error) return error;
+	save_flags(flags);
+	cli();
 	if (ATM_SD(lower)->upper) {
+		restore_flags(flags);
 		printk(KERN_WARNING "arequipa_attach_unchecked: lower is "
 		    "already attached\n");
 		return -EISCONN;
@@ -236,6 +243,7 @@
 	ATM_SD(lower)->upper = upper;
 	rt = upper->ip_route_cache; /* revalidate cache */
 	upper->ip_route_cache = NULL;
+	restore_flags(flags);
 	set_rt_cache(upper,rt);
 	/*
 	 * The next statement violates RFC1122, because it may change MSS when
@@ -288,6 +296,7 @@
 
 int arequipa_preset(struct socket *lower,struct sock *upper)
 {
+	unsigned long flags;
 	int error;
 
 	if (upper->state == TCP_LISTEN) return -EPROTO;
@@ -297,8 +306,11 @@
 	}
 	error = arequipa_expect(upper,1);
 	if (error) return error;
+	save_flags(flags);
+	cli();
 	error = arequipa_attach_unchecked(lower,upper);
-	if (!error) make_aq_vcc(lower);
+	if (!error) make_aq_vcc(lower,0);
+	restore_flags(flags);
 	return error;
 }
 
@@ -311,7 +323,7 @@
 	error = check_aq_vcc(lower);
 	if (error) return error;
 	ATM_SD(lower)->upper = NULL;
-	make_aq_vcc(lower);
+	make_aq_vcc(lower,1);
 	DPRINTK("aq_incoming %d\n",lower->file->f_count);
 	return 0;
 }
diff -ur --new-file old/linux/net/atm/common.c new/linux/net/atm/common.c
--- old/linux/net/atm/common.c	Wed Nov 13 23:49:48 1996
+++ new/linux/net/atm/common.c	Wed Nov 13 23:50:18 1996
@@ -345,8 +345,8 @@
 	void *buff;
 	int size;
 
-	if (sock->state != SS_CONNECTED || flags || m->msg_name)
-		return -EINVAL;
+	if (sock->state != SS_CONNECTED) return -ENOTCONN;
+	if (flags) return -EOPNOTSUPP;
 	if (m->msg_iovlen != 1) return -ENOSYS; /* fix this later @@@ */
 	buff = m->msg_iov->iov_base;
 	size = m->msg_iov->iov_len;
@@ -414,13 +414,14 @@
 {
 	struct atm_vcc *vcc;
 	struct sk_buff *skb;
-	int eff;
+	int eff,error;
 
 	const void *buff;
 	int size;
 
-	if (sock->state != SS_CONNECTED || flags || m->msg_name)
-		return -EINVAL;
+	if (sock->state != SS_CONNECTED) return -ENOTCONN;
+	if (flags) return -EOPNOTSUPP;
+	if (m->msg_name) return -EISCONN;
 	if (m->msg_iovlen != 1) return -ENOSYS; /* fix this later @@@ */
 	buff = m->msg_iov->iov_base;
 	size = m->msg_iov->iov_len;
@@ -459,9 +460,9 @@
 			atomic_add(skb->truesize+ATM_PDU_OVHD,&vcc->tx_inuse);
 			skb->atm.iovcnt = res;
 			skb_device_lock(skb);
-			vcc->dev->ops->send(vcc,skb);
+			error = vcc->dev->ops->send(vcc,skb);
 			/* FIXME: security: may send up to 3 "garbage" bytes */
-			return size;
+			return error ? error : size;
 		}
 	}
 #endif
@@ -494,11 +495,11 @@
                 printk("send %d:%s\n",vcc->vci,buf);
         }
 #endif
-	vcc->dev->ops->send(vcc,skb);
+	error = vcc->dev->ops->send(vcc,skb);
 #if 0 /* experimental */
 	while (vcc->dev->sending) sleep_on(&vcc->sleep);
 #endif
-	return size;
+	return error ? error : size;
 }
 
 
diff -ur --new-file old/linux/net/atm/lec.c new/linux/net/atm/lec.c
--- old/linux/net/atm/lec.c	Wed Nov 13 23:49:52 1996
+++ new/linux/net/atm/lec.c	Wed Nov 13 23:50:19 1996
@@ -542,7 +542,6 @@
                 }
                 skb->dev = dev;
                 skb->mac.raw = (unsigned char *)skb->data;
-                skb->mac.ethernet = (struct ethhdr *)skb_pull(skb, 2);     
                 if (*hdr->h_dest&1) {
                         if (memcmp(hdr->h_dest,dev->broadcast, ETH_ALEN)==0)
                                 skb->pkt_type=PACKET_BROADCAST;
@@ -556,7 +555,7 @@
                         skb->protocol = hdr->h_type;
                 else 
                         skb->protocol = htons(ETH_P_802_2);
-                skb->h.raw = skb_pull(skb, ETH_HLEN);
+                skb->h.raw = skb_pull(skb, LEC_HEADER_LEN);
                 netif_rx(skb);
                 priv->stats.rx_packets++;
         }
diff -ur --new-file old/linux/net/atm/lec_arpc.c new/linux/net/atm/lec_arpc.c
--- old/linux/net/atm/lec_arpc.c	Wed Nov 13 23:49:52 1996
+++ new/linux/net/atm/lec_arpc.c	Wed Nov 13 23:50:19 1996
@@ -1004,15 +1004,19 @@
 {
         struct lec_arp_table *entry, *prev;
         struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
+        unsigned long flags;
   
         lec_arp_lock(priv);
         entry = priv->lec_arp_empty_ones;
         if (vcc == entry->vcc) {
+                save_flags(flags);
+                cli();
                 del_timer(&entry->timer);
                 memcpy(entry->mac_addr, hdr->h_source, ETH_ALEN);
                 entry->status = ESI_FORWARD_DIRECT;
                 entry->last_used = jiffies;
                 priv->lec_arp_empty_ones = entry->next;
+                restore_flags(flags);
                 /* We might have got an entry */
                 if ((prev=lec_arp_find(priv,hdr->h_source))) {
                         lec_arp_remove(priv->lec_arp_tables, prev);
@@ -1033,11 +1037,14 @@
                 lec_arp_unlock(priv);
                 return;
         }
+        save_flags(flags);
+        cli();
         del_timer(&entry->timer);
         memcpy(entry->mac_addr, hdr->h_source, ETH_ALEN);
         entry->status = ESI_FORWARD_DIRECT;
         entry->last_used = jiffies;
         prev->next = entry->next;
+        restore_flags(flags);
         if ((prev = lec_arp_find(priv, hdr->h_source))) {
                 lec_arp_remove(priv->lec_arp_tables,prev);
                 kfree(prev);
diff -ur --new-file old/linux/net/atm/signaling.c new/linux/net/atm/signaling.c
--- old/linux/net/atm/signaling.c	Wed Nov 13 23:49:48 1996
+++ new/linux/net/atm/signaling.c	Wed Nov 13 23:50:19 1996
@@ -133,10 +133,6 @@
 	else msg->pvc = *pvc;
 	while (!sigd) {
 #ifdef WAIT_FOR_DEMON
-/*
- * Don't ever enable this as Arequipa depends on being able to send a
- * message to the signaling demon from an interrupt.
- */
 		if (silence < jiffies) {
 			printk(KERN_INFO "atmsvc: waiting for signaling demon "
 			    "...\n");