u8 mss;
u8 state;
+#define LDC_IRQ_NAME_MAX 32
+ char rx_irq_name[LDC_IRQ_NAME_MAX];
+ char tx_irq_name[LDC_IRQ_NAME_MAX];
+
struct hlist_head mh_list;
struct hlist_node list;
*/
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;
}
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",
lp->tx_acked = head;
return 0;
}
- if (head == lp->tx_head)
+ if (head == lp->tx_tail)
return ldc_abort(lp);
}
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;
* state. This does not initiate a handshake, ldc_connect() does
* that.
*/
-int ldc_bind(struct ldc_channel *lp)
+int ldc_bind(struct ldc_channel *lp, const char *name)
{
unsigned long hv_err, flags;
int err = -EINVAL;
spin_lock_irqsave(&lp->lock, flags);
+ if (!name)
+ goto out_err;
+
if (lp->state != LDC_STATE_INIT)
goto out_err;
+ snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name);
+ snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
+
err = request_irq(lp->cfg.rx_irq, ldc_rx,
IRQF_SAMPLE_RANDOM | IRQF_SHARED,
- "LDC RX", lp);
+ lp->rx_irq_name, lp);
if (err)
goto out_err;
err = request_irq(lp->cfg.tx_irq, ldc_tx,
IRQF_SAMPLE_RANDOM | IRQF_SHARED,
- "LDC TX", lp);
+ lp->tx_irq_name, lp);
if (err)
goto out_free_rx_irq;
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;
}
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;
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))) {
}
if (!(p->stype & LDC_INFO)) {
new = rx_advance(lp, new);
+ err = rx_set_head(lp, new);
+ if (err)
+ break;
goto 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;
}
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;
static int sg_count_one(struct scatterlist *sg)
{
- unsigned long base = page_to_pfn(sg->page) << PAGE_SHIFT;
+ unsigned long base = page_to_pfn(sg_page(sg)) << PAGE_SHIFT;
long len = sg->length;
if ((sg->offset | len) & (8UL - 1))
state.nc = 0;
for (i = 0; i < num_sg; i++)
- fill_cookies(&state, page_to_pfn(sg[i].page) << PAGE_SHIFT,
+ fill_cookies(&state, page_to_pfn(sg_page(&sg[i])) << PAGE_SHIFT,
sg[i].offset, sg[i].length);
return state.nc;
static int __init ldc_init(void)
{
- struct mdesc_node *mp;
unsigned long major, minor;
+ struct mdesc_handle *hp;
const u64 *v;
+ u64 mp;
+
+ hp = mdesc_grab();
+ if (!hp)
+ return -ENODEV;
- mp = md_find_node_by_name(NULL, "platform");
- if (!mp)
+ mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "platform");
+ if (mp == MDESC_NODE_NULL)
return -ENODEV;
- v = md_get_property(mp, "domaining-enabled", NULL);
+ v = mdesc_get_property(hp, mp, "domaining-enabled", NULL);
if (!v)
return -ENODEV;