diff options
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r-- | drivers/net/virtio_net.c | 45 |
1 files changed, 18 insertions, 27 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index f0bb1a4c8323..52198f6797a4 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -843,6 +843,10 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
843 | int err; | 843 | int err; |
844 | struct net_device *dev; | 844 | struct net_device *dev; |
845 | struct virtnet_info *vi; | 845 | struct virtnet_info *vi; |
846 | struct virtqueue *vqs[3]; | ||
847 | vq_callback_t *callbacks[] = { skb_recv_done, skb_xmit_done, NULL}; | ||
848 | const char *names[] = { "input", "output", "control" }; | ||
849 | int nvqs; | ||
846 | 850 | ||
847 | /* Allocate ourselves a network device with room for our info */ | 851 | /* Allocate ourselves a network device with room for our info */ |
848 | dev = alloc_etherdev(sizeof(struct virtnet_info)); | 852 | dev = alloc_etherdev(sizeof(struct virtnet_info)); |
@@ -903,25 +907,19 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
903 | if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) | 907 | if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) |
904 | vi->mergeable_rx_bufs = true; | 908 | vi->mergeable_rx_bufs = true; |
905 | 909 | ||
906 | /* We expect two virtqueues, receive then send. */ | 910 | /* We expect two virtqueues, receive then send, |
907 | vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); | 911 | * and optionally control. */ |
908 | if (IS_ERR(vi->rvq)) { | 912 | nvqs = virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) ? 3 : 2; |
909 | err = PTR_ERR(vi->rvq); | 913 | |
914 | err = vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names); | ||
915 | if (err) | ||
910 | goto free; | 916 | goto free; |
911 | } | ||
912 | 917 | ||
913 | vi->svq = vdev->config->find_vq(vdev, 1, skb_xmit_done); | 918 | vi->rvq = vqs[0]; |
914 | if (IS_ERR(vi->svq)) { | 919 | vi->svq = vqs[1]; |
915 | err = PTR_ERR(vi->svq); | ||
916 | goto free_recv; | ||
917 | } | ||
918 | 920 | ||
919 | if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) { | 921 | if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) { |
920 | vi->cvq = vdev->config->find_vq(vdev, 2, NULL); | 922 | vi->cvq = vqs[2]; |
921 | if (IS_ERR(vi->cvq)) { | ||
922 | err = PTR_ERR(vi->svq); | ||
923 | goto free_send; | ||
924 | } | ||
925 | 923 | ||
926 | if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VLAN)) | 924 | if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VLAN)) |
927 | dev->features |= NETIF_F_HW_VLAN_FILTER; | 925 | dev->features |= NETIF_F_HW_VLAN_FILTER; |
@@ -939,7 +937,7 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
939 | err = register_netdev(dev); | 937 | err = register_netdev(dev); |
940 | if (err) { | 938 | if (err) { |
941 | pr_debug("virtio_net: registering device failed\n"); | 939 | pr_debug("virtio_net: registering device failed\n"); |
942 | goto free_ctrl; | 940 | goto free_vqs; |
943 | } | 941 | } |
944 | 942 | ||
945 | /* Last of all, set up some receive buffers. */ | 943 | /* Last of all, set up some receive buffers. */ |
@@ -960,13 +958,8 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
960 | 958 | ||
961 | unregister: | 959 | unregister: |
962 | unregister_netdev(dev); | 960 | unregister_netdev(dev); |
963 | free_ctrl: | 961 | free_vqs: |
964 | if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) | 962 | vdev->config->del_vqs(vdev); |
965 | vdev->config->del_vq(vi->cvq); | ||
966 | free_send: | ||
967 | vdev->config->del_vq(vi->svq); | ||
968 | free_recv: | ||
969 | vdev->config->del_vq(vi->rvq); | ||
970 | free: | 963 | free: |
971 | free_netdev(dev); | 964 | free_netdev(dev); |
972 | return err; | 965 | return err; |
@@ -992,12 +985,10 @@ static void virtnet_remove(struct virtio_device *vdev) | |||
992 | 985 | ||
993 | BUG_ON(vi->num != 0); | 986 | BUG_ON(vi->num != 0); |
994 | 987 | ||
995 | vdev->config->del_vq(vi->svq); | ||
996 | vdev->config->del_vq(vi->rvq); | ||
997 | if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) | ||
998 | vdev->config->del_vq(vi->cvq); | ||
999 | unregister_netdev(vi->dev); | 988 | unregister_netdev(vi->dev); |
1000 | 989 | ||
990 | vdev->config->del_vqs(vi->vdev); | ||
991 | |||
1001 | while (vi->pages) | 992 | while (vi->pages) |
1002 | __free_pages(get_a_page(vi, GFP_KERNEL), 0); | 993 | __free_pages(get_a_page(vi, GFP_KERNEL), 0); |
1003 | 994 | ||