aboutsummaryrefslogtreecommitdiffstats
path: root/net/9p/trans_virtio.c
diff options
context:
space:
mode:
authorEric Van Hensbergen <ericvh@gmail.com>2008-10-13 19:45:21 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2008-10-17 12:04:42 -0400
commit91b8534fa8f5e01f249b1bf8df0a2540053549ad (patch)
treefde6b3b63dad229108106553106995889b4f0fa7 /net/9p/trans_virtio.c
parent1b0a763bdd5ed467d0e03b88e045000c749303fb (diff)
9p: make rpc code common and rework flush code
This code moves the rpc function to the common client base, reorganizes the flush code to be more simple and stable, and makes the necessary adjustments to the underlying transports to adapt to the new structure. This reduces the overall amount of code duplication between the transports and should make adding new transports more straightforward. Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
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,