1/**
2 * \file
3 * \brief Bidirectional UMP channel
4 */
5
6/*
7 * Copyright (c) 2009, 2010, 2011, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#ifndef BARRELFISH_UMP_CHAN_H
16#define BARRELFISH_UMP_CHAN_H
17
18#include <sys/cdefs.h>
19
20#include <barrelfish/ump_endpoint.h>
21#include <barrelfish/monitor_client.h>
22
23__BEGIN_DECLS
24
25struct ump_chan;
26struct monitor_binding;
27
28struct ump_bind_continuation {
29    /**
30     * \brief Handler which runs when a binding succeeds or fails
31     * \param st State pointer set in closure
32     * \param err Success/failure of binding
33     * \param uc On success, contains pointer to channel
34     * \param notify On success, contains (optional) notification capability
35     */
36    void (*handler)(void *st, errval_t err, struct ump_chan *uc,
37                    struct capref notify);
38    void *st;
39};
40
41/// A bidirectional UMP channel
42struct ump_chan {
43    struct monitor_cap_handlers cap_handlers;   /* XXX: must be first */
44
45    struct ump_chan_state send_chan;       ///< Outgoing UMP channel state
46    struct ump_endpoint endpoint;          ///< Incoming UMP endpoint
47    struct waitset_chanstate send_waitset;
48    struct ump_chan *next, *prev;
49
50    /// connection state
51    enum {UMP_DISCONNECTED,     ///< Disconnected
52          UMP_BIND_WAIT,        ///< Waiting for bind reply
53          UMP_CONNECTED,        ///< Connection established
54    } connstate;
55
56    struct capref frame;        ///< Cap to shared frame
57    struct vregion *vregion;    ///< VRegion for shared frame
58    ump_index_t max_send_msgs;  ///< Number of messages that fit in the send channel
59    ump_index_t max_recv_msgs;  ///< Number of messages that fit in the recv channel
60    uintptr_t monitor_id;       ///< Local monitor's connection ID for this channel
61    struct monitor_binding *monitor_binding; ///< Monitor binding used for cap xfer
62
63    uintptr_t sendid;  ///< id for tracing
64    uintptr_t recvid;  ///< id for tracing
65
66    /* Arguments for an ongoing bind attempt */
67    iref_t iref;                ///< IREF to which we bound
68    size_t inchanlen, outchanlen;
69    struct capref notify_cap;
70    struct ump_bind_continuation bind_continuation; ///< Continuation for bind
71};
72
73struct event_queue_node;
74
75errval_t ump_chan_init(struct ump_chan *uc,
76                       volatile void *inbuf, size_t inbufsize,
77                       volatile void *outbuf, size_t outbufsize);
78errval_t ump_chan_bind(struct ump_chan *uc, struct ump_bind_continuation cont,
79                       struct event_queue_node *qnode,  iref_t iref,
80                       struct monitor_binding *monitor_binding,
81                       size_t inchanlen, size_t outchanlen,
82                       struct capref notify_cap);
83errval_t ump_chan_accept(struct ump_chan *uc, uintptr_t mon_id,
84                         struct capref frame, size_t inchanlen, size_t outchanlen);
85errval_t ump_chan_register_send(struct ump_chan *uc, struct waitset *ws,
86                                struct event_closure closure);
87void ump_channels_retry_send_disabled(dispatcher_handle_t handle);
88void ump_chan_send_bind_reply(struct monitor_binding *mb,
89                              struct ump_chan *uc, errval_t err,
90                              uintptr_t monitor_id, struct capref notify_cap);
91void ump_chan_destroy(struct ump_chan *uc);
92void ump_init(void);
93
94/**
95 * \brief Register an event handler to be notified when messages can be received
96 *
97 * In the future, call the closure on the given waitset when it is likely that
98 * a message can be received on the channel. A channel may only be registered
99 * with a single receive event handler on a single waitset at any one time.
100 *
101 * \param uc UMP channel
102 * \param ws Waitset
103 * \param closure Event handler
104 */
105static inline errval_t ump_chan_register_recv(struct ump_chan *uc,
106                                               struct waitset *ws,
107                                               struct event_closure closure)
108{
109    return ump_endpoint_register(&uc->endpoint, ws, closure);
110}
111
112/**
113 * \brief Cancel an event registration made with ump_chan_register_recv()
114 *
115 * \param uc UMP channel
116 */
117static inline errval_t ump_chan_deregister_recv(struct ump_chan *uc)
118{
119    return ump_endpoint_deregister(&uc->endpoint);
120}
121
122static inline errval_t ump_chan_recv(struct ump_chan *uc,
123                                     volatile struct ump_message **msg)
124{
125    assert(msg != NULL);
126    assert(uc != NULL);
127    return ump_endpoint_recv(&uc->endpoint, msg);
128}
129
130static inline errval_t ump_chan_can_recv(struct ump_chan *uc)
131{
132    assert(uc != NULL);
133    return ump_endpoint_can_recv(&uc->endpoint);
134}
135
136static inline volatile struct ump_message *ump_chan_get_next(
137                                struct ump_chan *uc, struct ump_control *ctrl)
138{
139    return ump_impl_get_next(&uc->send_chan, ctrl);
140}
141
142static inline bool ump_chan_can_send(struct ump_chan *uc)
143{
144    assert(uc != NULL);
145    return ump_impl_can_send(&uc->send_chan);
146}
147
148static inline void ump_chan_free_message(volatile struct ump_message *msg)
149{
150    ump_impl_free_message(msg);
151}
152
153/**
154 * \brief Migrate an event registration made with
155 * ump_chan_register_recv() to a new waitset
156 *
157 * \param lc LMP channel
158 * \param ws New waitset
159 */
160static inline void ump_chan_migrate_recv(struct ump_chan *lc,
161                                         struct waitset *ws)
162{
163    ump_endpoint_migrate(&lc->endpoint, ws);
164}
165
166static inline struct waitset_chanstate * ump_chan_get_receiving_channel(struct ump_chan *chan)
167{
168    return &chan->endpoint.waitset_state;
169}
170
171struct waitset_chanstate * monitor_bind_get_receiving_chanstate(struct monitor_binding *b);
172
173__END_DECLS
174
175#endif // BARRELFISH_UMP_CHAN_H
176