diff options
| -rw-r--r-- | net/9p/trans_virtio.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index b88515936e4b..8ae08596aad8 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
| @@ -134,16 +134,24 @@ static void req_done(struct virtqueue *vq) | |||
| 134 | struct p9_fcall *rc; | 134 | struct p9_fcall *rc; |
| 135 | unsigned int len; | 135 | unsigned int len; |
| 136 | struct p9_req_t *req; | 136 | struct p9_req_t *req; |
| 137 | unsigned long flags; | ||
| 137 | 138 | ||
| 138 | P9_DPRINTK(P9_DEBUG_TRANS, ": request done\n"); | 139 | P9_DPRINTK(P9_DEBUG_TRANS, ": request done\n"); |
| 139 | 140 | ||
| 140 | while ((rc = virtqueue_get_buf(chan->vq, &len)) != NULL) { | 141 | do { |
| 141 | P9_DPRINTK(P9_DEBUG_TRANS, ": rc %p\n", rc); | 142 | spin_lock_irqsave(&chan->lock, flags); |
| 142 | P9_DPRINTK(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag); | 143 | rc = virtqueue_get_buf(chan->vq, &len); |
| 143 | req = p9_tag_lookup(chan->client, rc->tag); | 144 | spin_unlock_irqrestore(&chan->lock, flags); |
| 144 | req->status = REQ_STATUS_RCVD; | 145 | |
| 145 | p9_client_cb(chan->client, req); | 146 | if (rc != NULL) { |
| 146 | } | 147 | P9_DPRINTK(P9_DEBUG_TRANS, ": rc %p\n", rc); |
| 148 | P9_DPRINTK(P9_DEBUG_TRANS, ": lookup tag %d\n", | ||
| 149 | rc->tag); | ||
| 150 | req = p9_tag_lookup(chan->client, rc->tag); | ||
| 151 | req->status = REQ_STATUS_RCVD; | ||
| 152 | p9_client_cb(chan->client, req); | ||
| 153 | } | ||
| 154 | } while (rc != NULL); | ||
| 147 | } | 155 | } |
| 148 | 156 | ||
| 149 | /** | 157 | /** |
| @@ -199,23 +207,29 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req) | |||
| 199 | int in, out; | 207 | int in, out; |
| 200 | struct virtio_chan *chan = client->trans; | 208 | struct virtio_chan *chan = client->trans; |
| 201 | char *rdata = (char *)req->rc+sizeof(struct p9_fcall); | 209 | char *rdata = (char *)req->rc+sizeof(struct p9_fcall); |
| 210 | unsigned long flags; | ||
| 211 | int err; | ||
| 202 | 212 | ||
| 203 | P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request\n"); | 213 | P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request\n"); |
| 204 | 214 | ||
| 215 | req->status = REQ_STATUS_SENT; | ||
| 216 | |||
| 217 | spin_lock_irqsave(&chan->lock, flags); | ||
| 205 | out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, req->tc->sdata, | 218 | out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, req->tc->sdata, |
| 206 | req->tc->size); | 219 | req->tc->size); |
| 207 | in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata, | 220 | in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata, |
| 208 | client->msize); | 221 | client->msize); |
| 209 | 222 | ||
| 210 | req->status = REQ_STATUS_SENT; | 223 | err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc); |
| 211 | 224 | if (err < 0) { | |
| 212 | if (virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc) < 0) { | 225 | spin_unlock_irqrestore(&chan->lock, flags); |
| 213 | P9_DPRINTK(P9_DEBUG_TRANS, | 226 | P9_DPRINTK(P9_DEBUG_TRANS, |
| 214 | "9p debug: virtio rpc add_buf returned failure"); | 227 | "9p debug: virtio rpc add_buf returned failure"); |
| 215 | return -EIO; | 228 | return -EIO; |
| 216 | } | 229 | } |
| 217 | 230 | ||
| 218 | virtqueue_kick(chan->vq); | 231 | virtqueue_kick(chan->vq); |
| 232 | spin_unlock_irqrestore(&chan->lock, flags); | ||
| 219 | 233 | ||
| 220 | P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request kicked\n"); | 234 | P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request kicked\n"); |
| 221 | return 0; | 235 | return 0; |
