diff options
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r-- | drivers/net/virtio_net.c | 44 |
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) | |||
295 | static int virtnet_close(struct net_device *dev) | 289 | static 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 | ||
377 | unregister: | ||
378 | unregister_netdev(dev); | ||
386 | free_send: | 379 | free_send: |
387 | vdev->config->del_vq(vi->svq); | 380 | vdev->config->del_vq(vi->svq); |
388 | free_recv: | 381 | free_recv: |
@@ -395,6 +388,19 @@ free: | |||
395 | static void virtnet_remove(struct virtio_device *vdev) | 388 | static 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); |