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