diff options
Diffstat (limited to 'net/9p/trans_virtio.c')
-rw-r--r-- | net/9p/trans_virtio.c | 85 |
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 */ | ||
176 | static 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 | ||
184 | static int | 189 | static int |
185 | p9_virtio_rpc(struct p9_client *c, struct p9_fcall *tc, struct p9_fcall **rc) | 190 | p9_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, |