]> err.no Git - linux-2.6/blobdiff - arch/sparc64/kernel/ldc.c
[ARM] 4652/1: pxa: fix a typo of pxa27x usb host clk definition
[linux-2.6] / arch / sparc64 / kernel / ldc.c
index 0fa04d6f978dbf30a6e75e8d30502c0e4543fc21..217478a94128783ae6055e689391dfb5d9919ee6 100644 (file)
@@ -158,6 +158,10 @@ struct ldc_channel {
        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;
@@ -239,8 +243,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 +497,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 +768,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 +1096,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;
@@ -1232,25 +1230,31 @@ EXPORT_SYMBOL(ldc_free);
  * 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;
 
@@ -1579,15 +1583,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 +1610,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 +1662,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 +1698,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 +1777,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 +1802,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;
 
@@ -2027,7 +2057,7 @@ static void fill_cookies(struct cookie_state *sp, unsigned long pa,
 
 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))
@@ -2091,7 +2121,7 @@ int ldc_map_sg(struct ldc_channel *lp,
        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;
@@ -2305,15 +2335,20 @@ EXPORT_SYMBOL(ldc_free_exp_dring);
 
 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;