aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c44
1 files changed, 25 insertions, 19 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 73f01db59ab9..ec43284ffd13 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -282,12 +282,6 @@ static int virtnet_open(struct net_device *dev)
282{ 282{
283 struct virtnet_info *vi = netdev_priv(dev); 283 struct virtnet_info *vi = netdev_priv(dev);
284 284
285 try_fill_recv(vi);
286
287 /* If we didn't even get one input buffer, we're useless. */
288 if (vi->num == 0)
289 return -ENOMEM;
290
291 napi_enable(&vi->napi); 285 napi_enable(&vi->napi);
292 return 0; 286 return 0;
293} 287}
@@ -295,22 +289,9 @@ static int virtnet_open(struct net_device *dev)
295static int virtnet_close(struct net_device *dev) 289static int virtnet_close(struct net_device *dev)
296{ 290{
297 struct virtnet_info *vi = netdev_priv(dev); 291 struct virtnet_info *vi = netdev_priv(dev);
298 struct sk_buff *skb;
299 292
300 napi_disable(&vi->napi); 293 napi_disable(&vi->napi);
301 294
302 /* networking core has neutered skb_xmit_done/skb_recv_done, so don't
303 * worry about races vs. get(). */
304 vi->rvq->vq_ops->shutdown(vi->rvq);
305 while ((skb = __skb_dequeue(&vi->recv)) != NULL) {
306 kfree_skb(skb);
307 vi->num--;
308 }
309 vi->svq->vq_ops->shutdown(vi->svq);
310 while ((skb = __skb_dequeue(&vi->send)) != NULL)
311 kfree_skb(skb);
312
313 BUG_ON(vi->num != 0);
314 return 0; 295 return 0;
315} 296}
316 297
@@ -379,10 +360,22 @@ static int virtnet_probe(struct virtio_device *vdev)
379 pr_debug("virtio_net: registering device failed\n"); 360 pr_debug("virtio_net: registering device failed\n");
380 goto free_send; 361 goto free_send;
381 } 362 }
363
364 /* Last of all, set up some receive buffers. */
365 try_fill_recv(vi);
366
367 /* If we didn't even get one input buffer, we're useless. */
368 if (vi->num == 0) {
369 err = -ENOMEM;
370 goto unregister;
371 }
372
382 pr_debug("virtnet: registered device %s\n", dev->name); 373 pr_debug("virtnet: registered device %s\n", dev->name);
383 vdev->priv = vi; 374 vdev->priv = vi;
384 return 0; 375 return 0;
385 376
377unregister:
378 unregister_netdev(dev);
386free_send: 379free_send:
387 vdev->config->del_vq(vi->svq); 380 vdev->config->del_vq(vi->svq);
388free_recv: 381free_recv:
@@ -395,6 +388,19 @@ free:
395static void virtnet_remove(struct virtio_device *vdev) 388static void virtnet_remove(struct virtio_device *vdev)
396{ 389{
397 struct virtnet_info *vi = vdev->priv; 390 struct virtnet_info *vi = vdev->priv;
391 struct sk_buff *skb;
392
393 /* Free our skbs in send and recv queues, if any. */
394 vi->rvq->vq_ops->shutdown(vi->rvq);
395 while ((skb = __skb_dequeue(&vi->recv)) != NULL) {
396 kfree_skb(skb);
397 vi->num--;
398 }
399 vi->svq->vq_ops->shutdown(vi->svq);
400 while ((skb = __skb_dequeue(&vi->send)) != NULL)
401 kfree_skb(skb);
402
403 BUG_ON(vi->num != 0);
398 404
399 vdev->config->del_vq(vi->svq); 405 vdev->config->del_vq(vi->svq);
400 vdev->config->del_vq(vi->rvq); 406 vdev->config->del_vq(vi->rvq);