diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-12-26 21:21:11 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-12-26 21:21:11 +0000 |
commit | 3caddfed9eea1c170e8e7bd76768502e2ec99891 (patch) | |
tree | 42990dad92da480a8b2634a1617d12b550317bb7 /sys/arch/sparc64 | |
parent | c2b4adaf322c7ff83060dd6590694cad4df7c81e (diff) |
Add support for fragmented messages.
Diffstat (limited to 'sys/arch/sparc64')
-rw-r--r-- | sys/arch/sparc64/dev/ldc.c | 23 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/ldcvar.h | 13 |
2 files changed, 33 insertions, 3 deletions
diff --git a/sys/arch/sparc64/dev/ldc.c b/sys/arch/sparc64/dev/ldc.c index 13799d5d818..5b172acdbb8 100644 --- a/sys/arch/sparc64/dev/ldc.c +++ b/sys/arch/sparc64/dev/ldc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ldc.c,v 1.6 2009/05/12 22:31:45 kettenis Exp $ */ +/* $OpenBSD: ldc.c,v 1.7 2009/12/26 21:21:10 kettenis Exp $ */ /* * Copyright (c) 2009 Mark Kettenis * @@ -72,6 +72,7 @@ ldc_rx_ctrl_vers(struct ldc_conn *lc, struct ldc_pkt *lp) { switch (lp->stype) { case LDC_INFO: + DPRINTF(("CTRL/INFO/VERS\n")); if (lp->major == LDC_VERSION_MAJOR && lp->minor == LDC_VERSION_MINOR) ldc_send_ack(lc); @@ -203,6 +204,8 @@ ldc_rx_ctrl_rdx(struct ldc_conn *lc, struct ldc_pkt *lp) void ldc_rx_data(struct ldc_conn *lc, struct ldc_pkt *lp) { + size_t len; + if (lp->stype != LDC_INFO) { DPRINTF(("DATA/0x%02x\n", lp->stype)); ldc_reset(lc); @@ -216,7 +219,23 @@ ldc_rx_data(struct ldc_conn *lc, struct ldc_pkt *lp) return; } - lc->lc_rx_data(lc, lp); + if (lp->env & LDC_FRAG_START) { + lc->lc_len = (lp->env & LDC_LEN_MASK) + 8; + KASSERT(lc->lc_len <= sizeof(lc->lc_msg)); + memcpy((uint8_t *)lc->lc_msg, lp, lc->lc_len); + } else { + len = (lp->env & LDC_LEN_MASK); + if (lc->lc_len + len > sizeof(lc->lc_msg)) { + DPRINTF(("Buffer overrun\n")); + ldc_reset(lc); + return; + } + memcpy(((uint8_t *)lc->lc_msg) + lc->lc_len, &lp->major, len); + lc->lc_len += len; + } + + if (lp->env & LDC_FRAG_STOP) + lc->lc_rx_data(lc, (struct ldc_pkt *)lc->lc_msg); } void diff --git a/sys/arch/sparc64/dev/ldcvar.h b/sys/arch/sparc64/dev/ldcvar.h index 832823a2375..bf7a9ed7f11 100644 --- a/sys/arch/sparc64/dev/ldcvar.h +++ b/sys/arch/sparc64/dev/ldcvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ldcvar.h,v 1.3 2009/05/12 21:52:30 kettenis Exp $ */ +/* $OpenBSD: ldcvar.h,v 1.4 2009/12/26 21:21:10 kettenis Exp $ */ /* * Copyright (c) 2009 Mark Kettenis * @@ -36,6 +36,8 @@ void ldc_queue_free(bus_dma_tag_t, struct ldc_queue *); #define LDC_VERSION_MAJOR 1 #define LDC_VERSION_MINOR 0 +#define LDC_PKT_PAYLOAD 56 + struct ldc_pkt { uint8_t type; uint8_t stype; @@ -74,6 +76,12 @@ struct ldc_pkt { #define LDC_FRAG_START 0x40 #define LDC_FRAG_STOP 0x80 +/* + * XXX Get rid of the +8 once we no longer need to store the header of + * the first packet. + */ +#define LDC_MSG_MAX (128 + 8) + struct ldc_conn { uint64_t lc_id; @@ -90,6 +98,9 @@ struct ldc_conn { #define LDC_SND_RTR 4 #define LDC_SND_RDX 5 + uint64_t lc_msg[LDC_MSG_MAX / 8]; + size_t lc_len; + void *lc_sc; void (*lc_reset)(struct ldc_conn *); void (*lc_start)(struct ldc_conn *); |