patch-2.0.36 linux/net/rose/rose_out.c
Next file: linux/net/rose/rose_route.c
Previous file: linux/net/rose/rose_loopback.c
Back to the patch index
Back to the overall index
- Lines: 106
- Date:
Sun Nov 15 10:33:22 1998
- Orig file:
v2.0.35/linux/net/rose/rose_out.c
- Orig date:
Sun Nov 15 10:50:02 1998
diff -u --recursive --new-file v2.0.35/linux/net/rose/rose_out.c linux/net/rose/rose_out.c
@@ -11,7 +11,6 @@
*
* History
* ROSE 001 Jonathan(G4KLX) Cloned from nr_out.c
- * ROSE 003 Jonathan(G4KLX) Removed M bit processing.
*/
#include <linux/config.h>
@@ -55,39 +54,56 @@
void rose_kick(struct sock *sk)
{
- struct sk_buff *skb;
- unsigned short end;
+ struct sk_buff *skb, *skbn;
+ unsigned short start, end;
- del_timer(&sk->timer);
+ if (sk->protinfo.rose->state != ROSE_STATE_3)
+ return;
- end = (sk->protinfo.rose->va + sysctl_rose_window_size) % ROSE_MODULUS;
+ if (sk->protinfo.rose->condition & ROSE_COND_PEER_RX_BUSY)
+ return;
- if (!(sk->protinfo.rose->condition & ROSE_COND_PEER_RX_BUSY) &&
- sk->protinfo.rose->vs != end &&
- skb_peek(&sk->write_queue) != NULL) {
- /*
- * Transmit data until either we're out of data to send or
- * the window is full.
- */
+ if (skb_peek(&sk->write_queue) == NULL)
+ return;
- skb = skb_dequeue(&sk->write_queue);
+ start = (skb_peek(&sk->protinfo.rose->ack_queue) == NULL) ? sk->protinfo.rose->va : sk->protinfo.rose->vs;
+ end = (sk->protinfo.rose->va + sysctl_rose_window_size) % ROSE_MODULUS;
- do {
- /*
- * Transmit the frame.
- */
- rose_send_iframe(sk, skb);
+ if (start == end)
+ return;
- sk->protinfo.rose->vs = (sk->protinfo.rose->vs + 1) % ROSE_MODULUS;
+ sk->protinfo.rose->vs = start;
- } while (sk->protinfo.rose->vs != end && (skb = skb_dequeue(&sk->write_queue)) != NULL);
+ /*
+ * Transmit data until either we're out of data to send or
+ * the window is full.
+ */
+
+ skb = skb_dequeue(&sk->write_queue);
+
+ do {
+ if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
+ skb_queue_head(&sk->write_queue, skb);
+ break;
+ }
- sk->protinfo.rose->vl = sk->protinfo.rose->vr;
- sk->protinfo.rose->condition &= ~ROSE_COND_ACK_PENDING;
- sk->protinfo.rose->timer = 0;
- }
+ /*
+ * Transmit the frame copy.
+ */
+ rose_send_iframe(sk, skbn);
- rose_set_timer(sk);
+ sk->protinfo.rose->vs = (sk->protinfo.rose->vs + 1) % ROSE_MODULUS;
+
+ /*
+ * Requeue the original data frame.
+ */
+ skb_queue_tail(&sk->protinfo.rose->ack_queue, skb);
+
+ } while (sk->protinfo.rose->vs != end && (skb = skb_dequeue(&sk->write_queue)) != NULL);
+
+ sk->protinfo.rose->vl = sk->protinfo.rose->vr;
+ sk->protinfo.rose->condition &= ~ROSE_COND_ACK_PENDING;
+ sk->protinfo.rose->timer = 0;
}
/*
@@ -105,16 +121,6 @@
sk->protinfo.rose->vl = sk->protinfo.rose->vr;
sk->protinfo.rose->condition &= ~ROSE_COND_ACK_PENDING;
sk->protinfo.rose->timer = 0;
-}
-
-void rose_check_iframes_acked(struct sock *sk, unsigned short nr)
-{
- if (sk->protinfo.rose->vs == nr) {
- sk->protinfo.rose->va = nr;
- } else {
- if (sk->protinfo.rose->va != nr)
- sk->protinfo.rose->va = nr;
- }
}
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov