aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p/trans_virtio.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/9p/trans_virtio.c')
-rw-r--r--net/9p/trans_virtio.c85
1 files changed, 24 insertions, 61 deletions
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index e18de14c30d5..2d7781ec663b 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -126,17 +126,16 @@ static void req_done(struct virtqueue *vq)
126 struct virtio_chan *chan = vq->vdev->priv; 126 struct virtio_chan *chan = vq->vdev->priv;
127 struct p9_fcall *rc; 127 struct p9_fcall *rc;
128 unsigned int len; 128 unsigned int len;
129 unsigned long flags;
130 struct p9_req_t *req; 129 struct p9_req_t *req;
131 130
132 spin_lock_irqsave(&chan->lock, flags); 131 P9_DPRINTK(P9_DEBUG_TRANS, ": request done\n");
132
133 while ((rc = chan->vq->vq_ops->get_buf(chan->vq, &len)) != NULL) { 133 while ((rc = chan->vq->vq_ops->get_buf(chan->vq, &len)) != NULL) {
134 P9_DPRINTK(P9_DEBUG_TRANS, ": rc %p\n", rc);
135 P9_DPRINTK(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag);
134 req = p9_tag_lookup(chan->client, rc->tag); 136 req = p9_tag_lookup(chan->client, rc->tag);
135 req->status = REQ_STATUS_RCVD; 137 p9_client_cb(chan->client, req);
136 wake_up(req->wq);
137 } 138 }
138 /* In case queue is stopped waiting for more buffers. */
139 spin_unlock_irqrestore(&chan->lock, flags);
140} 139}
141 140
142/** 141/**
@@ -173,8 +172,14 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
173 return index-start; 172 return index-start;
174} 173}
175 174
175/* We don't currently allow canceling of virtio requests */
176static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
177{
178 return 1;
179}
180
176/** 181/**
177 * p9_virtio_rpc - issue a request and wait for a response 182 * p9_virtio_request - issue a request
178 * @t: transport state 183 * @t: transport state
179 * @tc: &p9_fcall request to transmit 184 * @tc: &p9_fcall request to transmit
180 * @rc: &p9_fcall to put reponse into 185 * @rc: &p9_fcall to put reponse into
@@ -182,44 +187,22 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
182 */ 187 */
183 188
184static int 189static int
185p9_virtio_rpc(struct p9_client *c, struct p9_fcall *tc, struct p9_fcall **rc) 190p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
186{ 191{
187 int in, out; 192 int in, out;
188 int n, err, size; 193 struct virtio_chan *chan = client->trans;
189 struct virtio_chan *chan = c->trans; 194 char *rdata = (char *)req->rc+sizeof(struct p9_fcall);
190 char *rdata;
191 struct p9_req_t *req;
192 unsigned long flags;
193
194 if (*rc == NULL) {
195 *rc = kmalloc(sizeof(struct p9_fcall) + c->msize, GFP_KERNEL);
196 if (!*rc)
197 return -ENOMEM;
198 }
199
200 rdata = (char *)*rc+sizeof(struct p9_fcall);
201
202 n = P9_NOTAG;
203 if (tc->id != P9_TVERSION) {
204 n = p9_idpool_get(c->tagpool);
205 if (n < 0)
206 return -ENOMEM;
207 }
208
209 spin_lock_irqsave(&chan->lock, flags);
210 req = p9_tag_alloc(c, n);
211 spin_unlock_irqrestore(&chan->lock, flags);
212
213 p9_set_tag(tc, n);
214 195
215 P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio rpc tag %d\n", n); 196 P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request\n");
216 197
217 out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, tc->sdata, tc->size); 198 out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, req->tc->sdata,
218 in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata, c->msize); 199 req->tc->size);
200 in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata,
201 client->msize);
219 202
220 req->status = REQ_STATUS_SENT; 203 req->status = REQ_STATUS_SENT;
221 204
222 if (chan->vq->vq_ops->add_buf(chan->vq, chan->sg, out, in, tc)) { 205 if (chan->vq->vq_ops->add_buf(chan->vq, chan->sg, out, in, req->tc)) {
223 P9_DPRINTK(P9_DEBUG_TRANS, 206 P9_DPRINTK(P9_DEBUG_TRANS,
224 "9p debug: virtio rpc add_buf returned failure"); 207 "9p debug: virtio rpc add_buf returned failure");
225 return -EIO; 208 return -EIO;
@@ -227,28 +210,7 @@ p9_virtio_rpc(struct p9_client *c, struct p9_fcall *tc, struct p9_fcall **rc)
227 210
228 chan->vq->vq_ops->kick(chan->vq); 211 chan->vq->vq_ops->kick(chan->vq);
229 212
230 wait_event(*req->wq, req->status == REQ_STATUS_RCVD); 213 P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request kicked\n");
231
232 size = le32_to_cpu(*(__le32 *) rdata);
233
234 err = p9_deserialize_fcall(rdata, size, *rc, c->dotu);
235 if (err < 0) {
236 P9_DPRINTK(P9_DEBUG_TRANS,
237 "9p debug: virtio rpc deserialize returned %d\n", err);
238 return err;
239 }
240
241#ifdef CONFIG_NET_9P_DEBUG
242 if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) {
243 char buf[150];
244
245 p9_printfcall(buf, sizeof(buf), *rc, c->dotu);
246 printk(KERN_NOTICE ">>> %p %s\n", c, buf);
247 }
248#endif
249
250 p9_free_req(c, req);
251
252 return 0; 214 return 0;
253} 215}
254 216
@@ -394,7 +356,8 @@ static struct p9_trans_module p9_virtio_trans = {
394 .name = "virtio", 356 .name = "virtio",
395 .create = p9_virtio_create, 357 .create = p9_virtio_create,
396 .close = p9_virtio_close, 358 .close = p9_virtio_close,
397 .rpc = p9_virtio_rpc, 359 .request = p9_virtio_request,
360 .cancel = p9_virtio_cancel,
398 .maxsize = PAGE_SIZE*16, 361 .maxsize = PAGE_SIZE*16,
399 .def = 0, 362 .def = 0,
400 .owner = THIS_MODULE, 363 .owner = THIS_MODULE,