Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=cb4812358423e7ea47d2b6471918d65238452cc5
Commit:     cb4812358423e7ea47d2b6471918d65238452cc5
Parent:     5a606b72a4309a656cd1a19ad137dc5557c4b8ea
Author:     David S. Miller <[EMAIL PROTECTED]>
AuthorDate: Wed Jul 11 18:14:41 2007 -0700
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Mon Jul 16 04:04:09 2007 -0700

    [SPARC64]: Assorted LDC bug cures.
    
    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 <[EMAIL PROTECTED]>
---
 arch/sparc64/kernel/ldc.c |   56 ++++++++++++++++++++++++++++++--------------
 include/asm-sparc64/ldc.h |    3 +-
 2 files changed, 39 insertions(+), 20 deletions(-)

diff --git a/arch/sparc64/kernel/ldc.c b/arch/sparc64/kernel/ldc.c
index 0fa04d6..4cba286 100644
--- a/arch/sparc64/kernel/ldc.c
+++ b/arch/sparc64/kernel/ldc.c
@@ -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;
 
diff --git a/include/asm-sparc64/ldc.h b/include/asm-sparc64/ldc.h
index 24fd236..1c13738 100644
--- a/include/asm-sparc64/ldc.h
+++ b/include/asm-sparc64/ldc.h
@@ -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
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to