diff -ur --new-file old/linux/include/linux/atmsvc.h new/linux/include/linux/atmsvc.h
--- old/linux/include/linux/atmsvc.h	Mon Mar  1 17:00:31 1999
+++ new/linux/include/linux/atmsvc.h	Mon Mar  1 17:01:09 1999
@@ -1,6 +1,6 @@
 /* atmsvc.h - ATM signaling kernel-demon interface definitions */
  
-/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */
+/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */
  
 
 #ifndef _LINUX_ATMSVC_H
@@ -46,7 +46,8 @@
  * if signaling only uses one ATM interface).
  */
 
-#define SELECT_TOP_PCR(tp) ((tp).max_pcr && (tp).max_pcr != ATM_MAX_PCR ? \
-  (tp).max_pcr : (tp).min_pcr ? (tp).min_pcr : ATM_MAX_PCR)
+#define SELECT_TOP_PCR(tp) ((tp).pcr ? (tp).pcr : \
+  (tp).max_pcr && (tp).max_pcr != ATM_MAX_PCR ? (tp).max_pcr : \
+  (tp).min_pcr ? (tp).min_pcr : ATM_MAX_PCR)
 
 #endif
diff -ur --new-file old/linux/net/atm/misc.c new/linux/net/atm/misc.c
--- old/linux/net/atm/misc.c	Mon Mar  1 17:00:32 1999
+++ new/linux/net/atm/misc.c	Mon Mar  1 17:01:10 1999
@@ -1,6 +1,6 @@
 /* net/atm/misc.c - Various functions for use by ATM drivers */
 
-/* Written 1995-1998 by Werner Almesberger, EPFL ICA */
+/* Written 1995-1999 by Werner Almesberger, EPFL ICA */
 
 
 #include <linux/config.h>
@@ -107,7 +107,7 @@
  *	-   y   *	y-		x   y   *	y-
  *	-   y   z	z-		x   y   z	z-
  *
- * All non-error cases can be convered with the following simple set of rules:
+ * All non-error cases can be converted with the following simple set of rules:
  *
  *   if pcr == z then z-
  *   else if min == x && pcr == - then x+
diff -ur --new-file old/linux/net/atm/svc.c new/linux/net/atm/svc.c
--- old/linux/net/atm/svc.c	Mon Mar  1 17:00:32 1999
+++ new/linux/net/atm/svc.c	Mon Mar  1 17:01:10 1999
@@ -1,6 +1,6 @@
 /* net/atm/svc.c - ATM SVC sockets */
 
-/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */
+/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */
 
 
 #include <linux/string.h>
@@ -198,6 +198,7 @@
  * #ifndef CONFIG_SINGLE_SIGITF
  */
 	vcc->qos.txtp.max_pcr = SELECT_TOP_PCR(vcc->qos.txtp);
+	vcc->qos.txtp.pcr = 0;
 	vcc->qos.txtp.min_pcr = 0;
 /*
  * #endif
diff -ur --new-file old/linux/net/sched/sch_atm.c new/linux/net/sched/sch_atm.c
--- old/linux/net/sched/sch_atm.c	Mon Mar  1 17:00:32 1999
+++ new/linux/net/sched/sch_atm.c	Mon Mar  1 17:01:10 1999
@@ -170,12 +170,12 @@
 		DPRINTK("atm_tc_put: f_count %d\n",flow->sock->file->f_count);
 		sockfd_put(flow->sock);
 	}
+	if (flow->excess) atm_tc_put(sch,(unsigned long) flow->excess);
 	if (flow != &p->link) kfree(flow);
 	/*
 	 * If flow == &p->link, the qdisc no longer works at this point and
 	 * needs to be removed. (By the caller of atm_tc_put.)
 	 */
-	if (flow->excess) atm_tc_put(sch,(unsigned long) flow->excess);
 }
 
 
@@ -184,7 +184,7 @@
 {
 	struct atm_qdisc_data *p = PRIV(sch);
 	struct atm_flow_data *flow = (struct atm_flow_data *) *arg;
-	struct atm_flow_data *excess;
+	struct atm_flow_data *excess = NULL;
 	struct rtattr *opt = tca[TCA_OPTIONS-1];
 	struct rtattr *tb[TCA_ATM_MAX];
 	struct socket *sock;
@@ -196,7 +196,8 @@
 	/*
 	 * The concept of parents doesn't apply for this qdisc.
 	 */
-	if (parent && parent != TC_H_ROOT) return -EINVAL;
+	if (parent && parent != TC_H_ROOT && parent != sch->handle)
+		return -EINVAL;
 	/*
 	 * ATM classes cannot be changed. In order to change properties of the
 	 * ATM connection, that socket needs to be modified directly (via the
@@ -287,6 +288,7 @@
 	*arg = (unsigned long) flow;
 	return 0;
 err_out:
+	if (excess) atm_tc_put(sch,(unsigned long) excess);
 	sockfd_put(sock);
 	return error;
 }
@@ -300,7 +302,15 @@
 	DPRINTK("atm_tc_delete(sch %p,[qdisc %p],flow %p)\n",sch,p,flow);
 	if (!find_flow(PRIV(sch),flow)) return -EINVAL;
 	if (flow->filter_list || flow == &p->link) return -EBUSY;
-	if (flow->ref > 1) return -EBUSY; /* catch references via excess, etc.*/
+	/*
+	 * Reference count must be 2: one for "keepalive" (set at class
+	 * creation), and one for the reference held when calling delete.
+	 */
+	if (flow->ref < 2) {
+		printk(KERN_ERR "atm_tc_delete: flow->ref == %d\n",flow->ref);
+		return -EINVAL;
+	}
+	if (flow->ref > 2) return -EBUSY; /* catch references via excess, etc.*/
 	atm_tc_put(sch,arg);
 	return 0;
 }
@@ -522,6 +532,7 @@
 	DPRINTK("atm_tc_dump_class(sch %p,[qdisc %p],flow %p,skb %p,tcm %p)\n",
 	    sch,p,flow,skb,tcm);
 	if (!find_flow(p,flow)) return -EINVAL;
+	tcm->tcm_handle = flow->classid;
 	rta = (struct rtattr *) b;
 	RTA_PUT(skb,TCA_OPTIONS,0,NULL);
 	RTA_PUT(skb,TCA_ATM_HDR,flow->hdr_len,flow->hdr);