bus/vmbus: fix comment spelling
[dpdk.git] / drivers / bus / vmbus / vmbus_channel.c
index f9feada..46b3ba3 100644 (file)
@@ -59,6 +59,32 @@ vmbus_set_event(const struct rte_vmbus_device *dev,
        vmbus_set_monitor(dev, chan->monitor_id);
 }
 
+/*
+ * Set the wait between when hypervisor examines the trigger.
+ */
+void
+rte_vmbus_set_latency(const struct rte_vmbus_device *dev,
+                     const struct vmbus_channel *chan,
+                     uint32_t latency)
+{
+       uint32_t trig_idx = chan->monitor_id / VMBUS_MONTRIG_LEN;
+       uint32_t trig_offs = chan->monitor_id % VMBUS_MONTRIG_LEN;
+
+       if (latency >= UINT16_MAX * 100) {
+               VMBUS_LOG(ERR, "invalid latency value %u", latency);
+               return;
+       }
+
+       if (trig_idx >= VMBUS_MONTRIGS_MAX) {
+               VMBUS_LOG(ERR, "invalid monitor trigger %u",
+                         trig_idx);
+               return;
+       }
+
+       /* Host value is expressed in 100 nanosecond units */
+       dev->monitor_page->lat[trig_idx][trig_offs] = latency / 100;
+}
+
 /*
  * Notify host that there are data pending on our TX bufring.
  *
@@ -176,49 +202,37 @@ bool rte_vmbus_chan_rx_empty(const struct vmbus_channel *channel)
        return br->vbr->rindex == br->vbr->windex;
 }
 
-static int vmbus_read_and_signal(struct vmbus_channel *chan,
-                                void *data, size_t dlen, size_t skip)
+/* Signal host after reading N bytes */
+void rte_vmbus_chan_signal_read(struct vmbus_channel *chan, uint32_t bytes_read)
 {
        struct vmbus_br *rbr = &chan->rxbr;
-       uint32_t write_sz, pending_sz, bytes_read;
-       int error;
-
-       /* Record where host was when we started read (for debug) */
-       rbr->windex = rbr->vbr->windex;
-
-       /* Read data and skip packet header */
-       error = vmbus_rxbr_read(rbr, data, dlen, skip);
-       if (error)
-               return error;
+       uint32_t write_sz, pending_sz;
 
        /* No need for signaling on older versions */
        if (!rbr->vbr->feature_bits.feat_pending_send_sz)
-               return 0;
+               return;
 
        /* Make sure reading of pending happens after new read index */
        rte_mb();
 
        pending_sz = rbr->vbr->pending_send;
        if (!pending_sz)
-               return 0;
+               return;
 
        rte_smp_rmb();
        write_sz = vmbus_br_availwrite(rbr, rbr->vbr->windex);
-       bytes_read = dlen + skip + sizeof(uint64_t);
 
        /* If there was space before then host was not blocked */
        if (write_sz - bytes_read > pending_sz)
-               return 0;
+               return;
 
        /* If pending write will not fit */
        if (write_sz <= pending_sz)
-               return 0;
+               return;
 
        vmbus_set_event(chan->device, chan);
-       return 0;
 }
 
-/* TODO: replace this with inplace ring buffer (no copy) */
 int rte_vmbus_chan_recv(struct vmbus_channel *chan, void *data, uint32_t *len,
                        uint64_t *request_id)
 {
@@ -256,10 +270,16 @@ int rte_vmbus_chan_recv(struct vmbus_channel *chan, void *data, uint32_t *len,
        if (request_id)
                *request_id = pkt.xactid;
 
-       /* Read data and skip the header */
-       return vmbus_read_and_signal(chan, data, dlen, hlen);
+       /* Read data and skip packet header */
+       error = vmbus_rxbr_read(&chan->rxbr, data, dlen, hlen);
+       if (error)
+               return error;
+
+       rte_vmbus_chan_signal_read(chan, dlen + hlen + sizeof(uint64_t));
+       return 0;
 }
 
+/* TODO: replace this with inplace ring buffer (no copy) */
 int rte_vmbus_chan_recv_raw(struct vmbus_channel *chan,
                            void *data, uint32_t *len)
 {
@@ -291,8 +311,13 @@ int rte_vmbus_chan_recv_raw(struct vmbus_channel *chan,
        if (unlikely(dlen > bufferlen))
                return -ENOBUFS;
 
-       /* Put packet header in data buffer */
-       return vmbus_read_and_signal(chan, data, dlen, 0);
+       /* Read data and skip packet header */
+       error = vmbus_rxbr_read(&chan->rxbr, data, dlen, 0);
+       if (error)
+               return error;
+
+       /* Return the number of bytes read */
+       return dlen + sizeof(uint64_t);
 }
 
 int vmbus_chan_create(const struct rte_vmbus_device *device,
@@ -327,12 +352,21 @@ int vmbus_chan_create(const struct rte_vmbus_device *device,
 int rte_vmbus_chan_open(struct rte_vmbus_device *device,
                        struct vmbus_channel **new_chan)
 {
+       struct mapped_vmbus_resource *uio_res;
        int err;
 
+       uio_res = vmbus_uio_find_resource(device);
+       if (!uio_res) {
+               VMBUS_LOG(ERR, "can't find uio resource");
+               return -EINVAL;
+       }
+
        err = vmbus_chan_create(device, device->relid, 0,
                                device->monitor_id, new_chan);
-       if (!err)
+       if (!err) {
                device->primary = *new_chan;
+               uio_res->primary = *new_chan;
+       }
 
        return err;
 }
@@ -371,11 +405,16 @@ void rte_vmbus_chan_close(struct vmbus_channel *chan)
        const struct rte_vmbus_device *device = chan->device;
        struct vmbus_channel *primary = device->primary;
 
-       if (chan != primary)
+       /*
+        * intentionally leak primary channel because
+        * secondary may still reference it
+        */
+       if (chan != primary) {
                STAILQ_REMOVE(&primary->subchannel_list, chan,
                              vmbus_channel, next);
+               rte_free(chan);
+       }
 
-       rte_free(chan);
 }
 
 static void vmbus_dump_ring(FILE *f, const char *id, const struct vmbus_br *br)