]> err.no Git - linux-2.6/commitdiff
[SPARC64]: Assorted LDC bug cures.
authorDavid S. Miller <davem@sunset.davemloft.net>
Thu, 12 Jul 2007 01:14:41 +0000 (18:14 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Mon, 16 Jul 2007 11:04:09 +0000 (04:04 -0700)
1) LDC_MODE_RELIABLE is deprecated an unused by anything, plus
   it and LDC_MODE_STREAM were mis-numbered.

2) read_stream() should try to read as much as possible into
   the per-LDC stream buffer area, so do not trim the read_nonraw()
   length by the caller's size parameter.

3) Send data ACKs when necessary in read_nonraw().

4) In read_nonraw() when we get a pure ACK, advance the RX head
   unconditionally past it.

5) Provide the ACKID field in the ldcdgb() packet dump in read_nonraw().
   This helps debugging stream mode LDC channel problems.

6) Decrease verbosity of rx_data_wait() so that it is more useful.
   A debugging message each loop iteration is too much.

7) In process_data_ack() stop the loop checking when we hit lp->tx_tail
   not lp->tx_head.

8) Set the seqid field properly in send_data_nack().

Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc64/kernel/ldc.c
include/asm-sparc64/ldc.h

index 0fa04d6f978dbf30a6e75e8d30502c0e4543fc21..4cba28685967797e4c8eee2b4a3aaf949affac2f 100644 (file)
@@ -239,8 +239,7 @@ static struct ldc_packet *handshake_get_tx_packet(struct ldc_channel *lp,
  */
 static unsigned long head_for_data(struct ldc_channel *lp)
 {
-       if (lp->cfg.mode == LDC_MODE_RELIABLE ||
-           lp->cfg.mode == LDC_MODE_STREAM)
+       if (lp->cfg.mode == LDC_MODE_STREAM)
                return lp->tx_acked;
        return lp->tx_head;
 }
@@ -494,7 +493,7 @@ static int send_data_nack(struct ldc_channel *lp, struct ldc_packet *data_pkt)
        p->type = data_pkt->type;
        p->stype = LDC_NACK;
        p->ctrl = data_pkt->ctrl & LDC_CTRL_MSK;
-       p->seqid = lp->snd_nxt;
+       p->seqid = lp->snd_nxt + 1;
        p->u.r.ackid = lp->rcv_nxt;
 
        ldcdbg(HS, "SEND DATA NACK type[0x%x] ctl[0x%x] seq[0x%x] ack[0x%x]\n",
@@ -765,7 +764,7 @@ static int process_data_ack(struct ldc_channel *lp,
                        lp->tx_acked = head;
                        return 0;
                }
-               if (head == lp->tx_head)
+               if (head == lp->tx_tail)
                        return ldc_abort(lp);
        }
 
@@ -1093,11 +1092,6 @@ struct ldc_channel *ldc_alloc(unsigned long id,
                mss = LDC_PACKET_SIZE - 8;
                break;
 
-       case LDC_MODE_RELIABLE:
-               mops = &nonraw_ops;
-               mss = LDC_PACKET_SIZE - 8 - 8;
-               break;
-
        case LDC_MODE_STREAM:
                mops = &stream_ops;
                mss = LDC_PACKET_SIZE - 8 - 8;
@@ -1579,15 +1573,14 @@ static int rx_data_wait(struct ldc_channel *lp, unsigned long cur_head)
                if (hv_err)
                        return ldc_abort(lp);
 
-               ldcdbg(DATA, "REREAD head[%lx] tail[%lx] chan_state[%lx]\n",
-                      dummy, lp->rx_tail, lp->chan_state);
-
                if (lp->chan_state == LDC_CHANNEL_DOWN ||
                    lp->chan_state == LDC_CHANNEL_RESETTING)
                        return -ECONNRESET;
 
                if (cur_head != lp->rx_tail) {
-                       ldcdbg(DATA, "DATA WAIT DONE\n");
+                       ldcdbg(DATA, "DATA WAIT DONE "
+                              "head[%lx] tail[%lx] chan_state[%lx]\n",
+                              dummy, lp->rx_tail, lp->chan_state);
                        return 0;
                }
 
@@ -1607,6 +1600,28 @@ static int rx_set_head(struct ldc_channel *lp, unsigned long head)
        return 0;
 }
 
+static void send_data_ack(struct ldc_channel *lp)
+{
+       unsigned long new_tail;
+       struct ldc_packet *p;
+
+       p = data_get_tx_packet(lp, &new_tail);
+       if (likely(p)) {
+               int err;
+
+               memset(p, 0, sizeof(*p));
+               p->type = LDC_DATA;
+               p->stype = LDC_ACK;
+               p->ctrl = 0;
+               p->seqid = lp->snd_nxt + 1;
+               p->u.r.ackid = lp->rcv_nxt;
+
+               err = send_tx_packet(lp, p, new_tail);
+               if (!err)
+                       lp->snd_nxt++;
+       }
+}
+
 static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size)
 {
        struct ldc_packet *first_frag;
@@ -1637,13 +1652,14 @@ static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size)
                BUG_ON(new == lp->rx_tail);
                p = lp->rx_base + (new / LDC_PACKET_SIZE);
 
-               ldcdbg(RX, "RX read pkt[%02x:%02x:%02x:%02x:%08x] "
+               ldcdbg(RX, "RX read pkt[%02x:%02x:%02x:%02x:%08x:%08x] "
                       "rcv_nxt[%08x]\n",
                       p->type,
                       p->stype,
                       p->ctrl,
                       p->env,
                       p->seqid,
+                      p->u.r.ackid,
                       lp->rcv_nxt);
 
                if (unlikely(!rx_seq_ok(lp, p->seqid))) {
@@ -1672,6 +1688,9 @@ static int read_nonraw(struct ldc_channel *lp, void *buf, unsigned int size)
                }
                if (!(p->stype & LDC_INFO)) {
                        new = rx_advance(lp, new);
+                       err = rx_set_head(lp, new);
+                       if (err)
+                               break;
                        goto no_data;
                }
 
@@ -1748,8 +1767,11 @@ no_data:
        if (err && first_frag)
                lp->rcv_nxt = first_frag->seqid - 1;
 
-       if (!err)
+       if (!err) {
                err = copied;
+               if (err > 0 && lp->cfg.mode != LDC_MODE_UNRELIABLE)
+                       send_data_ack(lp);
+       }
 
        return err;
 }
@@ -1770,9 +1792,7 @@ static int write_stream(struct ldc_channel *lp, const void *buf,
 static int read_stream(struct ldc_channel *lp, void *buf, unsigned int size)
 {
        if (!lp->mssbuf_len) {
-               int err = read_nonraw(lp, lp->mssbuf,
-                                     (size > lp->cfg.mtu ?
-                                      lp->cfg.mtu : size));
+               int err = read_nonraw(lp, lp->mssbuf, lp->cfg.mtu);
                if (err < 0)
                        return err;
 
index 24fd2367d33a335a1f4b2b968d0c0f2f8e6879fa..1c13738f13ffee6ad749f4f1e390ff74cf1ebd20 100644 (file)
@@ -25,8 +25,7 @@ struct ldc_channel_config {
 #define LDC_MODE_RAW           0x00
 #define LDC_MODE_UNRELIABLE    0x01
 #define LDC_MODE_RESERVED      0x02
-#define LDC_MODE_RELIABLE      0x03
-#define LDC_MODE_STREAM                0x04
+#define LDC_MODE_STREAM                0x03
 
        u8                      debug;
 #define LDC_DEBUG_HS           0x01