diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/Kconfig | 3 | ||||
-rw-r--r-- | drivers/block/cciss_scsi.c | 4 | ||||
-rw-r--r-- | drivers/block/sunvdc.c | 2 | ||||
-rw-r--r-- | drivers/block/ub.c | 23 | ||||
-rw-r--r-- | drivers/block/virtio_blk.c | 106 |
5 files changed, 70 insertions, 68 deletions
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index f2122855d4ec..64e5148d82bc 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
@@ -440,6 +440,7 @@ config VIRTIO_BLK | |||
440 | tristate "Virtio block driver (EXPERIMENTAL)" | 440 | tristate "Virtio block driver (EXPERIMENTAL)" |
441 | depends on EXPERIMENTAL && VIRTIO | 441 | depends on EXPERIMENTAL && VIRTIO |
442 | ---help--- | 442 | ---help--- |
443 | This is the virtual block driver for lguest. Say Y or M. | 443 | This is the virtual block driver for virtio. It can be used with |
444 | lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. | ||
444 | 445 | ||
445 | endif # BLK_DEV | 446 | endif # BLK_DEV |
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 63ee6c076cb3..55178e9973a0 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c | |||
@@ -1453,7 +1453,7 @@ static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd) | |||
1453 | rc = sendcmd(CCISS_RESET_MSG, ctlr, NULL, 0, 2, 0, 0, | 1453 | rc = sendcmd(CCISS_RESET_MSG, ctlr, NULL, 0, 2, 0, 0, |
1454 | (unsigned char *) &cmd_in_trouble->Header.LUN.LunAddrBytes[0], | 1454 | (unsigned char *) &cmd_in_trouble->Header.LUN.LunAddrBytes[0], |
1455 | TYPE_MSG); | 1455 | TYPE_MSG); |
1456 | /* sendcmd turned off interrputs on the board, turn 'em back on. */ | 1456 | /* sendcmd turned off interrupts on the board, turn 'em back on. */ |
1457 | (*c)->access.set_intr_mask(*c, CCISS_INTR_ON); | 1457 | (*c)->access.set_intr_mask(*c, CCISS_INTR_ON); |
1458 | if (rc == 0) | 1458 | if (rc == 0) |
1459 | return SUCCESS; | 1459 | return SUCCESS; |
@@ -1483,7 +1483,7 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd) | |||
1483 | 0, 2, 0, 0, | 1483 | 0, 2, 0, 0, |
1484 | (unsigned char *) &cmd_to_abort->Header.LUN.LunAddrBytes[0], | 1484 | (unsigned char *) &cmd_to_abort->Header.LUN.LunAddrBytes[0], |
1485 | TYPE_MSG); | 1485 | TYPE_MSG); |
1486 | /* sendcmd turned off interrputs on the board, turn 'em back on. */ | 1486 | /* sendcmd turned off interrupts on the board, turn 'em back on. */ |
1487 | (*c)->access.set_intr_mask(*c, CCISS_INTR_ON); | 1487 | (*c)->access.set_intr_mask(*c, CCISS_INTR_ON); |
1488 | if (rc == 0) | 1488 | if (rc == 0) |
1489 | return SUCCESS; | 1489 | return SUCCESS; |
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 66e30155b0ab..a8de037ecd4a 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c | |||
@@ -732,7 +732,7 @@ static struct vio_driver_ops vdc_vio_ops = { | |||
732 | .handshake_complete = vdc_handshake_complete, | 732 | .handshake_complete = vdc_handshake_complete, |
733 | }; | 733 | }; |
734 | 734 | ||
735 | static void print_version(void) | 735 | static void __devinit print_version(void) |
736 | { | 736 | { |
737 | static int version_printed; | 737 | static int version_printed; |
738 | 738 | ||
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index c6179d6ac6e4..a70c1c29a7aa 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -922,11 +922,6 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
922 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe, | 922 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe, |
923 | bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc); | 923 | bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc); |
924 | 924 | ||
925 | /* Fill what we shouldn't be filling, because usb-storage did so. */ | ||
926 | sc->work_urb.actual_length = 0; | ||
927 | sc->work_urb.error_count = 0; | ||
928 | sc->work_urb.status = 0; | ||
929 | |||
930 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { | 925 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { |
931 | /* XXX Clear stalls */ | 926 | /* XXX Clear stalls */ |
932 | ub_complete(&sc->work_done); | 927 | ub_complete(&sc->work_done); |
@@ -1313,9 +1308,6 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1313 | sc->last_pipe = pipe; | 1308 | sc->last_pipe = pipe; |
1314 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe, sg_virt(sg), | 1309 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe, sg_virt(sg), |
1315 | sg->length, ub_urb_complete, sc); | 1310 | sg->length, ub_urb_complete, sc); |
1316 | sc->work_urb.actual_length = 0; | ||
1317 | sc->work_urb.error_count = 0; | ||
1318 | sc->work_urb.status = 0; | ||
1319 | 1311 | ||
1320 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { | 1312 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { |
1321 | /* XXX Clear stalls */ | 1313 | /* XXX Clear stalls */ |
@@ -1356,9 +1348,6 @@ static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
1356 | sc->last_pipe = sc->recv_bulk_pipe; | 1348 | sc->last_pipe = sc->recv_bulk_pipe; |
1357 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe, | 1349 | usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe, |
1358 | &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc); | 1350 | &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc); |
1359 | sc->work_urb.actual_length = 0; | ||
1360 | sc->work_urb.error_count = 0; | ||
1361 | sc->work_urb.status = 0; | ||
1362 | 1351 | ||
1363 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { | 1352 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { |
1364 | /* XXX Clear stalls */ | 1353 | /* XXX Clear stalls */ |
@@ -1473,9 +1462,6 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | |||
1473 | 1462 | ||
1474 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, | 1463 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, |
1475 | (unsigned char*) cr, NULL, 0, ub_urb_complete, sc); | 1464 | (unsigned char*) cr, NULL, 0, ub_urb_complete, sc); |
1476 | sc->work_urb.actual_length = 0; | ||
1477 | sc->work_urb.error_count = 0; | ||
1478 | sc->work_urb.status = 0; | ||
1479 | 1465 | ||
1480 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { | 1466 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { |
1481 | ub_complete(&sc->work_done); | 1467 | ub_complete(&sc->work_done); |
@@ -1953,9 +1939,6 @@ static int ub_sync_reset(struct ub_dev *sc) | |||
1953 | 1939 | ||
1954 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, | 1940 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, |
1955 | (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); | 1941 | (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); |
1956 | sc->work_urb.actual_length = 0; | ||
1957 | sc->work_urb.error_count = 0; | ||
1958 | sc->work_urb.status = 0; | ||
1959 | 1942 | ||
1960 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { | 1943 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { |
1961 | printk(KERN_WARNING | 1944 | printk(KERN_WARNING |
@@ -2007,9 +1990,6 @@ static int ub_sync_getmaxlun(struct ub_dev *sc) | |||
2007 | 1990 | ||
2008 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe, | 1991 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe, |
2009 | (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl); | 1992 | (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl); |
2010 | sc->work_urb.actual_length = 0; | ||
2011 | sc->work_urb.error_count = 0; | ||
2012 | sc->work_urb.status = 0; | ||
2013 | 1993 | ||
2014 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) | 1994 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) |
2015 | goto err_submit; | 1995 | goto err_submit; |
@@ -2077,9 +2057,6 @@ static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe) | |||
2077 | 2057 | ||
2078 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, | 2058 | usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe, |
2079 | (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); | 2059 | (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl); |
2080 | sc->work_urb.actual_length = 0; | ||
2081 | sc->work_urb.error_count = 0; | ||
2082 | sc->work_urb.status = 0; | ||
2083 | 2060 | ||
2084 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { | 2061 | if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { |
2085 | printk(KERN_WARNING | 2062 | printk(KERN_WARNING |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 924ddd8bccd2..3b1a68d6eddb 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -7,8 +7,10 @@ | |||
7 | #include <linux/scatterlist.h> | 7 | #include <linux/scatterlist.h> |
8 | 8 | ||
9 | #define VIRTIO_MAX_SG (3+MAX_PHYS_SEGMENTS) | 9 | #define VIRTIO_MAX_SG (3+MAX_PHYS_SEGMENTS) |
10 | #define PART_BITS 4 | ||
11 | |||
12 | static int major, index; | ||
10 | 13 | ||
11 | static unsigned char virtblk_index = 'a'; | ||
12 | struct virtio_blk | 14 | struct virtio_blk |
13 | { | 15 | { |
14 | spinlock_t lock; | 16 | spinlock_t lock; |
@@ -36,7 +38,7 @@ struct virtblk_req | |||
36 | struct virtio_blk_inhdr in_hdr; | 38 | struct virtio_blk_inhdr in_hdr; |
37 | }; | 39 | }; |
38 | 40 | ||
39 | static bool blk_done(struct virtqueue *vq) | 41 | static void blk_done(struct virtqueue *vq) |
40 | { | 42 | { |
41 | struct virtio_blk *vblk = vq->vdev->priv; | 43 | struct virtio_blk *vblk = vq->vdev->priv; |
42 | struct virtblk_req *vbr; | 44 | struct virtblk_req *vbr; |
@@ -65,7 +67,6 @@ static bool blk_done(struct virtqueue *vq) | |||
65 | /* In case queue is stopped waiting for more buffers. */ | 67 | /* In case queue is stopped waiting for more buffers. */ |
66 | blk_start_queue(vblk->disk->queue); | 68 | blk_start_queue(vblk->disk->queue); |
67 | spin_unlock_irqrestore(&vblk->lock, flags); | 69 | spin_unlock_irqrestore(&vblk->lock, flags); |
68 | return true; | ||
69 | } | 70 | } |
70 | 71 | ||
71 | static bool do_req(struct request_queue *q, struct virtio_blk *vblk, | 72 | static bool do_req(struct request_queue *q, struct virtio_blk *vblk, |
@@ -153,20 +154,37 @@ static int virtblk_ioctl(struct inode *inode, struct file *filp, | |||
153 | (void __user *)data); | 154 | (void __user *)data); |
154 | } | 155 | } |
155 | 156 | ||
157 | /* We provide getgeo only to please some old bootloader/partitioning tools */ | ||
158 | static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) | ||
159 | { | ||
160 | /* some standard values, similar to sd */ | ||
161 | geo->heads = 1 << 6; | ||
162 | geo->sectors = 1 << 5; | ||
163 | geo->cylinders = get_capacity(bd->bd_disk) >> 11; | ||
164 | return 0; | ||
165 | } | ||
166 | |||
156 | static struct block_device_operations virtblk_fops = { | 167 | static struct block_device_operations virtblk_fops = { |
157 | .ioctl = virtblk_ioctl, | 168 | .ioctl = virtblk_ioctl, |
158 | .owner = THIS_MODULE, | 169 | .owner = THIS_MODULE, |
170 | .getgeo = virtblk_getgeo, | ||
159 | }; | 171 | }; |
160 | 172 | ||
173 | static int index_to_minor(int index) | ||
174 | { | ||
175 | return index << PART_BITS; | ||
176 | } | ||
177 | |||
161 | static int virtblk_probe(struct virtio_device *vdev) | 178 | static int virtblk_probe(struct virtio_device *vdev) |
162 | { | 179 | { |
163 | struct virtio_blk *vblk; | 180 | struct virtio_blk *vblk; |
164 | int err, major; | 181 | int err; |
165 | void *token; | ||
166 | unsigned int len; | ||
167 | u64 cap; | 182 | u64 cap; |
168 | u32 v; | 183 | u32 v; |
169 | 184 | ||
185 | if (index_to_minor(index) >= 1 << MINORBITS) | ||
186 | return -ENOSPC; | ||
187 | |||
170 | vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL); | 188 | vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL); |
171 | if (!vblk) { | 189 | if (!vblk) { |
172 | err = -ENOMEM; | 190 | err = -ENOMEM; |
@@ -178,7 +196,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
178 | vblk->vdev = vdev; | 196 | vblk->vdev = vdev; |
179 | 197 | ||
180 | /* We expect one virtqueue, for output. */ | 198 | /* We expect one virtqueue, for output. */ |
181 | vblk->vq = vdev->config->find_vq(vdev, blk_done); | 199 | vblk->vq = vdev->config->find_vq(vdev, 0, blk_done); |
182 | if (IS_ERR(vblk->vq)) { | 200 | if (IS_ERR(vblk->vq)) { |
183 | err = PTR_ERR(vblk->vq); | 201 | err = PTR_ERR(vblk->vq); |
184 | goto out_free_vblk; | 202 | goto out_free_vblk; |
@@ -190,17 +208,11 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
190 | goto out_free_vq; | 208 | goto out_free_vq; |
191 | } | 209 | } |
192 | 210 | ||
193 | major = register_blkdev(0, "virtblk"); | ||
194 | if (major < 0) { | ||
195 | err = major; | ||
196 | goto out_mempool; | ||
197 | } | ||
198 | |||
199 | /* FIXME: How many partitions? How long is a piece of string? */ | 211 | /* FIXME: How many partitions? How long is a piece of string? */ |
200 | vblk->disk = alloc_disk(1 << 4); | 212 | vblk->disk = alloc_disk(1 << PART_BITS); |
201 | if (!vblk->disk) { | 213 | if (!vblk->disk) { |
202 | err = -ENOMEM; | 214 | err = -ENOMEM; |
203 | goto out_unregister_blkdev; | 215 | goto out_mempool; |
204 | } | 216 | } |
205 | 217 | ||
206 | vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock); | 218 | vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock); |
@@ -209,22 +221,32 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
209 | goto out_put_disk; | 221 | goto out_put_disk; |
210 | } | 222 | } |
211 | 223 | ||
212 | sprintf(vblk->disk->disk_name, "vd%c", virtblk_index++); | 224 | if (index < 26) { |
225 | sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26); | ||
226 | } else if (index < (26 + 1) * 26) { | ||
227 | sprintf(vblk->disk->disk_name, "vd%c%c", | ||
228 | 'a' + index / 26 - 1, 'a' + index % 26); | ||
229 | } else { | ||
230 | const unsigned int m1 = (index / 26 - 1) / 26 - 1; | ||
231 | const unsigned int m2 = (index / 26 - 1) % 26; | ||
232 | const unsigned int m3 = index % 26; | ||
233 | sprintf(vblk->disk->disk_name, "vd%c%c%c", | ||
234 | 'a' + m1, 'a' + m2, 'a' + m3); | ||
235 | } | ||
236 | |||
213 | vblk->disk->major = major; | 237 | vblk->disk->major = major; |
214 | vblk->disk->first_minor = 0; | 238 | vblk->disk->first_minor = index_to_minor(index); |
215 | vblk->disk->private_data = vblk; | 239 | vblk->disk->private_data = vblk; |
216 | vblk->disk->fops = &virtblk_fops; | 240 | vblk->disk->fops = &virtblk_fops; |
241 | index++; | ||
217 | 242 | ||
218 | /* If barriers are supported, tell block layer that queue is ordered */ | 243 | /* If barriers are supported, tell block layer that queue is ordered */ |
219 | token = vdev->config->find(vdev, VIRTIO_CONFIG_BLK_F, &len); | 244 | if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER)) |
220 | if (virtio_use_bit(vdev, token, len, VIRTIO_BLK_F_BARRIER)) | ||
221 | blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); | 245 | blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); |
222 | 246 | ||
223 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap); | 247 | /* Host must always specify the capacity. */ |
224 | if (err) { | 248 | __virtio_config_val(vdev, offsetof(struct virtio_blk_config, capacity), |
225 | dev_err(&vdev->dev, "Bad/missing capacity in config\n"); | 249 | &cap); |
226 | goto out_cleanup_queue; | ||
227 | } | ||
228 | 250 | ||
229 | /* If capacity is too big, truncate with warning. */ | 251 | /* If capacity is too big, truncate with warning. */ |
230 | if ((sector_t)cap != cap) { | 252 | if ((sector_t)cap != cap) { |
@@ -234,31 +256,25 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
234 | } | 256 | } |
235 | set_capacity(vblk->disk, cap); | 257 | set_capacity(vblk->disk, cap); |
236 | 258 | ||
237 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SIZE_MAX, &v); | 259 | /* Host can optionally specify maximum segment size and number of |
260 | * segments. */ | ||
261 | err = virtio_config_val(vdev, VIRTIO_BLK_F_SIZE_MAX, | ||
262 | offsetof(struct virtio_blk_config, size_max), | ||
263 | &v); | ||
238 | if (!err) | 264 | if (!err) |
239 | blk_queue_max_segment_size(vblk->disk->queue, v); | 265 | blk_queue_max_segment_size(vblk->disk->queue, v); |
240 | else if (err != -ENOENT) { | ||
241 | dev_err(&vdev->dev, "Bad SIZE_MAX in config\n"); | ||
242 | goto out_cleanup_queue; | ||
243 | } | ||
244 | 266 | ||
245 | err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v); | 267 | err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, |
268 | offsetof(struct virtio_blk_config, seg_max), | ||
269 | &v); | ||
246 | if (!err) | 270 | if (!err) |
247 | blk_queue_max_hw_segments(vblk->disk->queue, v); | 271 | blk_queue_max_hw_segments(vblk->disk->queue, v); |
248 | else if (err != -ENOENT) { | ||
249 | dev_err(&vdev->dev, "Bad SEG_MAX in config\n"); | ||
250 | goto out_cleanup_queue; | ||
251 | } | ||
252 | 272 | ||
253 | add_disk(vblk->disk); | 273 | add_disk(vblk->disk); |
254 | return 0; | 274 | return 0; |
255 | 275 | ||
256 | out_cleanup_queue: | ||
257 | blk_cleanup_queue(vblk->disk->queue); | ||
258 | out_put_disk: | 276 | out_put_disk: |
259 | put_disk(vblk->disk); | 277 | put_disk(vblk->disk); |
260 | out_unregister_blkdev: | ||
261 | unregister_blkdev(major, "virtblk"); | ||
262 | out_mempool: | 278 | out_mempool: |
263 | mempool_destroy(vblk->pool); | 279 | mempool_destroy(vblk->pool); |
264 | out_free_vq: | 280 | out_free_vq: |
@@ -274,12 +290,16 @@ static void virtblk_remove(struct virtio_device *vdev) | |||
274 | struct virtio_blk *vblk = vdev->priv; | 290 | struct virtio_blk *vblk = vdev->priv; |
275 | int major = vblk->disk->major; | 291 | int major = vblk->disk->major; |
276 | 292 | ||
293 | /* Nothing should be pending. */ | ||
277 | BUG_ON(!list_empty(&vblk->reqs)); | 294 | BUG_ON(!list_empty(&vblk->reqs)); |
295 | |||
296 | /* Stop all the virtqueues. */ | ||
297 | vdev->config->reset(vdev); | ||
298 | |||
278 | blk_cleanup_queue(vblk->disk->queue); | 299 | blk_cleanup_queue(vblk->disk->queue); |
279 | put_disk(vblk->disk); | 300 | put_disk(vblk->disk); |
280 | unregister_blkdev(major, "virtblk"); | 301 | unregister_blkdev(major, "virtblk"); |
281 | mempool_destroy(vblk->pool); | 302 | 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); | 303 | vdev->config->del_vq(vblk->vq); |
284 | kfree(vblk); | 304 | kfree(vblk); |
285 | } | 305 | } |
@@ -299,11 +319,15 @@ static struct virtio_driver virtio_blk = { | |||
299 | 319 | ||
300 | static int __init init(void) | 320 | static int __init init(void) |
301 | { | 321 | { |
322 | major = register_blkdev(0, "virtblk"); | ||
323 | if (major < 0) | ||
324 | return major; | ||
302 | return register_virtio_driver(&virtio_blk); | 325 | return register_virtio_driver(&virtio_blk); |
303 | } | 326 | } |
304 | 327 | ||
305 | static void __exit fini(void) | 328 | static void __exit fini(void) |
306 | { | 329 | { |
330 | unregister_blkdev(major, "virtblk"); | ||
307 | unregister_virtio_driver(&virtio_blk); | 331 | unregister_virtio_driver(&virtio_blk); |
308 | } | 332 | } |
309 | module_init(init); | 333 | module_init(init); |