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");