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 4d1d47953fc6..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); | 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); | 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); | 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 | ||
