diff options
| -rw-r--r-- | drivers/block/virtio_blk.c | 10 | ||||
| -rw-r--r-- | drivers/lguest/lguest_device.c | 2 | ||||
| -rw-r--r-- | drivers/net/virtio_net.c | 8 | ||||
| -rw-r--r-- | drivers/virtio/virtio.c | 13 |
4 files changed, 28 insertions, 5 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 3cf7129d83..924ddd8bcc 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
| @@ -223,7 +223,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
| 223 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap); | 223 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap); |
| 224 | if (err) { | 224 | if (err) { |
| 225 | dev_err(&vdev->dev, "Bad/missing capacity in config\n"); | 225 | dev_err(&vdev->dev, "Bad/missing capacity in config\n"); |
| 226 | goto out_put_disk; | 226 | goto out_cleanup_queue; |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | /* If capacity is too big, truncate with warning. */ | 229 | /* If capacity is too big, truncate with warning. */ |
| @@ -239,7 +239,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
| 239 | blk_queue_max_segment_size(vblk->disk->queue, v); | 239 | blk_queue_max_segment_size(vblk->disk->queue, v); |
| 240 | else if (err != -ENOENT) { | 240 | else if (err != -ENOENT) { |
| 241 | dev_err(&vdev->dev, "Bad SIZE_MAX in config\n"); | 241 | dev_err(&vdev->dev, "Bad SIZE_MAX in config\n"); |
| 242 | goto out_put_disk; | 242 | goto out_cleanup_queue; |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v); | 245 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v); |
| @@ -247,12 +247,14 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
| 247 | blk_queue_max_hw_segments(vblk->disk->queue, v); | 247 | blk_queue_max_hw_segments(vblk->disk->queue, v); |
| 248 | else if (err != -ENOENT) { | 248 | else if (err != -ENOENT) { |
| 249 | dev_err(&vdev->dev, "Bad SEG_MAX in config\n"); | 249 | dev_err(&vdev->dev, "Bad SEG_MAX in config\n"); |
| 250 | goto out_put_disk; | 250 | goto out_cleanup_queue; |
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | add_disk(vblk->disk); | 253 | add_disk(vblk->disk); |
| 254 | return 0; | 254 | return 0; |
| 255 | 255 | ||
| 256 | out_cleanup_queue: | ||
| 257 | blk_cleanup_queue(vblk->disk->queue); | ||
| 256 | out_put_disk: | 258 | out_put_disk: |
| 257 | put_disk(vblk->disk); | 259 | put_disk(vblk->disk); |
| 258 | out_unregister_blkdev: | 260 | out_unregister_blkdev: |
| @@ -277,6 +279,8 @@ static void virtblk_remove(struct virtio_device *vdev) | |||
| 277 | put_disk(vblk->disk); | 279 | put_disk(vblk->disk); |
| 278 | unregister_blkdev(major, "virtblk"); | 280 | unregister_blkdev(major, "virtblk"); |
| 279 | mempool_destroy(vblk->pool); | 281 | mempool_destroy(vblk->pool); |
| 282 | /* There should be nothing in the queue now, so no need to shutdown */ | ||
| 283 | vdev->config->del_vq(vblk->vq); | ||
| 280 | kfree(vblk); | 284 | kfree(vblk); |
| 281 | } | 285 | } |
| 282 | 286 | ||
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index 66f3872225..e2eec38c83 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c | |||
| @@ -247,6 +247,8 @@ static void lg_del_vq(struct virtqueue *vq) | |||
| 247 | { | 247 | { |
| 248 | struct lguest_vq_info *lvq = vq->priv; | 248 | struct lguest_vq_info *lvq = vq->priv; |
| 249 | 249 | ||
| 250 | /* Release the interrupt */ | ||
| 251 | free_irq(lvq->config.irq, vq); | ||
| 250 | /* Tell virtio_ring.c to free the virtqueue. */ | 252 | /* Tell virtio_ring.c to free the virtqueue. */ |
| 251 | vring_del_virtqueue(vq); | 253 | vring_del_virtqueue(vq); |
| 252 | /* Unmap the pages containing the ring. */ | 254 | /* Unmap the pages containing the ring. */ |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index a75be57fb2..d74e6f4aa2 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
| @@ -404,8 +404,12 @@ free: | |||
| 404 | 404 | ||
| 405 | static void virtnet_remove(struct virtio_device *vdev) | 405 | static void virtnet_remove(struct virtio_device *vdev) |
| 406 | { | 406 | { |
| 407 | unregister_netdev(vdev->priv); | 407 | struct virtnet_info *vi = vdev->priv; |
| 408 | free_netdev(vdev->priv); | 408 | |
| 409 | vdev->config->del_vq(vi->svq); | ||
| 410 | vdev->config->del_vq(vi->rvq); | ||
| 411 | unregister_netdev(vi->dev); | ||
| 412 | free_netdev(vi->dev); | ||
| 409 | } | 413 | } |
| 410 | 414 | ||
| 411 | static struct virtio_device_id id_table[] = { | 415 | static struct virtio_device_id id_table[] = { |
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 15d7787dea..69d7ea02cd 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c | |||
| @@ -96,10 +96,23 @@ static int virtio_dev_probe(struct device *_d) | |||
| 96 | return err; | 96 | return err; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static int virtio_dev_remove(struct device *_d) | ||
| 100 | { | ||
| 101 | struct virtio_device *dev = container_of(_d,struct virtio_device,dev); | ||
| 102 | struct virtio_driver *drv = container_of(dev->dev.driver, | ||
| 103 | struct virtio_driver, driver); | ||
| 104 | |||
| 105 | dev->config->set_status(dev, dev->config->get_status(dev) | ||
| 106 | & ~VIRTIO_CONFIG_S_DRIVER); | ||
| 107 | drv->remove(dev); | ||
| 108 | return 0; | ||
| 109 | } | ||
| 110 | |||
| 99 | int register_virtio_driver(struct virtio_driver *driver) | 111 | int register_virtio_driver(struct virtio_driver *driver) |
| 100 | { | 112 | { |
| 101 | driver->driver.bus = &virtio_bus; | 113 | driver->driver.bus = &virtio_bus; |
| 102 | driver->driver.probe = virtio_dev_probe; | 114 | driver->driver.probe = virtio_dev_probe; |
| 115 | driver->driver.remove = virtio_dev_remove; | ||
| 103 | return driver_register(&driver->driver); | 116 | return driver_register(&driver->driver); |
| 104 | } | 117 | } |
| 105 | EXPORT_SYMBOL_GPL(register_virtio_driver); | 118 | EXPORT_SYMBOL_GPL(register_virtio_driver); |
