aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Stabellini <sstabellini@kernel.org>2017-07-06 14:00:00 -0400
committerBoris Ostrovsky <boris.ostrovsky@oracle.com>2017-08-31 09:45:55 -0400
commitb1efa69317e5e7e813620af180f262a0fc1db47c (patch)
treed538393302d418beb79f502447520514e02bab2a
parentd0e4d560c2433d29d11219567958b12bfe596d22 (diff)
xen/pvcalls: handle commands from the frontend
When the other end notifies us that there are commands to be read (pvcalls_back_event), wake up the backend thread to parse the command. The command ring works like most other Xen rings, so use the usual ring macros to read and write to it. The functions implementing the commands are empty stubs for now. [ boris: fixed whitespaces ] Signed-off-by: Stefano Stabellini <stefano@aporeto.com> Reviewed-by: Juergen Gross <jgross@suse.com> CC: boris.ostrovsky@oracle.com CC: jgross@suse.com Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
-rw-r--r--drivers/xen/pvcalls-back.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/drivers/xen/pvcalls-back.c b/drivers/xen/pvcalls-back.c
index 48b71236192d..a92e81d25f07 100644
--- a/drivers/xen/pvcalls-back.c
+++ b/drivers/xen/pvcalls-back.c
@@ -49,8 +49,133 @@ struct pvcalls_fedata {
49 struct semaphore socket_lock; 49 struct semaphore socket_lock;
50}; 50};
51 51
52static int pvcalls_back_socket(struct xenbus_device *dev,
53 struct xen_pvcalls_request *req)
54{
55 return 0;
56}
57
58static int pvcalls_back_connect(struct xenbus_device *dev,
59 struct xen_pvcalls_request *req)
60{
61 return 0;
62}
63
64static int pvcalls_back_release(struct xenbus_device *dev,
65 struct xen_pvcalls_request *req)
66{
67 return 0;
68}
69
70static int pvcalls_back_bind(struct xenbus_device *dev,
71 struct xen_pvcalls_request *req)
72{
73 return 0;
74}
75
76static int pvcalls_back_listen(struct xenbus_device *dev,
77 struct xen_pvcalls_request *req)
78{
79 return 0;
80}
81
82static int pvcalls_back_accept(struct xenbus_device *dev,
83 struct xen_pvcalls_request *req)
84{
85 return 0;
86}
87
88static int pvcalls_back_poll(struct xenbus_device *dev,
89 struct xen_pvcalls_request *req)
90{
91 return 0;
92}
93
94static int pvcalls_back_handle_cmd(struct xenbus_device *dev,
95 struct xen_pvcalls_request *req)
96{
97 int ret = 0;
98
99 switch (req->cmd) {
100 case PVCALLS_SOCKET:
101 ret = pvcalls_back_socket(dev, req);
102 break;
103 case PVCALLS_CONNECT:
104 ret = pvcalls_back_connect(dev, req);
105 break;
106 case PVCALLS_RELEASE:
107 ret = pvcalls_back_release(dev, req);
108 break;
109 case PVCALLS_BIND:
110 ret = pvcalls_back_bind(dev, req);
111 break;
112 case PVCALLS_LISTEN:
113 ret = pvcalls_back_listen(dev, req);
114 break;
115 case PVCALLS_ACCEPT:
116 ret = pvcalls_back_accept(dev, req);
117 break;
118 case PVCALLS_POLL:
119 ret = pvcalls_back_poll(dev, req);
120 break;
121 default:
122 {
123 struct pvcalls_fedata *fedata;
124 struct xen_pvcalls_response *rsp;
125
126 fedata = dev_get_drvdata(&dev->dev);
127 rsp = RING_GET_RESPONSE(
128 &fedata->ring, fedata->ring.rsp_prod_pvt++);
129 rsp->req_id = req->req_id;
130 rsp->cmd = req->cmd;
131 rsp->ret = -ENOTSUPP;
132 break;
133 }
134 }
135 return ret;
136}
137
138static void pvcalls_back_work(struct pvcalls_fedata *fedata)
139{
140 int notify, notify_all = 0, more = 1;
141 struct xen_pvcalls_request req;
142 struct xenbus_device *dev = fedata->dev;
143
144 while (more) {
145 while (RING_HAS_UNCONSUMED_REQUESTS(&fedata->ring)) {
146 RING_COPY_REQUEST(&fedata->ring,
147 fedata->ring.req_cons++,
148 &req);
149
150 if (!pvcalls_back_handle_cmd(dev, &req)) {
151 RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(
152 &fedata->ring, notify);
153 notify_all += notify;
154 }
155 }
156
157 if (notify_all) {
158 notify_remote_via_irq(fedata->irq);
159 notify_all = 0;
160 }
161
162 RING_FINAL_CHECK_FOR_REQUESTS(&fedata->ring, more);
163 }
164}
165
52static irqreturn_t pvcalls_back_event(int irq, void *dev_id) 166static irqreturn_t pvcalls_back_event(int irq, void *dev_id)
53{ 167{
168 struct xenbus_device *dev = dev_id;
169 struct pvcalls_fedata *fedata = NULL;
170
171 if (dev == NULL)
172 return IRQ_HANDLED;
173
174 fedata = dev_get_drvdata(&dev->dev);
175 if (fedata == NULL)
176 return IRQ_HANDLED;
177
178 pvcalls_back_work(fedata);
54 return IRQ_HANDLED; 179 return IRQ_HANDLED;
55} 180}
56 181