1 //#define DEBUG 2 #include <linux/spinlock.h> 3 #include <linux/slab.h> 4 #include <linux/blkdev.h> 5 #include <linux/hdreg.h> 6 #include <linux/module.h> 7 #include <linux/mutex.h> 8 #include <linux/virtio.h> 9 #include <linux/virtio_blk.h> 10 #include <linux/scatterlist.h> 11 #include <linux/string_helpers.h> 12 #include <scsi/scsi_cmnd.h> 13 #include <linux/idr.h> 14 15 #define PART_BITS 4 16 17 static int major; 18 static DEFINE_IDA(vd_index_ida); 19 20 struct workqueue_struct *virtblk_wq; 21 22 struct virtio_blk 23 { 24 spinlock_t lock; 25 26 struct virtio_device *vdev; 27 struct virtqueue *vq; 28 29 /* The disk structure for the kernel. */ 30 struct gendisk *disk; 31 32 /* Request tracking. */ 33 struct list_head reqs; 34 35 mempool_t *pool; 36 37 /* Process context for config space updates */ 38 struct work_struct config_work; 39 40 /* Lock for config space updates */ 41 struct mutex config_lock; 42 43 /* enable config space updates */ 44 bool config_enable; 45 46 /* What host tells us, plus 2 for header & tailer. */ 47 unsigned int sg_elems; 48 49 /* Ida index - used to track minor number allocations. */ 50 int index; 51 52 /* Scatterlist: can be too big for stack. */ 53 struct scatterlist sg[/*sg_elems*/]; 54 }; 55 56 struct virtblk_req 57 { 58 struct list_head list; 59 struct request *req; 60 struct virtio_blk_outhdr out_hdr; 61 struct virtio_scsi_inhdr in_hdr; 62 u8 status; 63 }; 64 65 static void blk_done(struct virtqueue *vq) 66 { 67 struct virtio_blk *vblk = vq->vdev->priv; 68 struct virtblk_req *vbr; 69 unsigned int len; 70 unsigned long flags; 71 72 spin_lock_irqsave(&vblk->lock, flags); 73 while ((vbr = virtqueue_get_buf(vblk->vq, &len)) != NULL) { 74 int error; 75 76 switch (vbr->status) { 77 case VIRTIO_BLK_S_OK: 78 error = 0; 79 break; 80 case VIRTIO_BLK_S_UNSUPP: 81 error = -ENOTTY; 82 break; 83 default: 84 error = -EIO; 85 break; 86 } 87 88 switch (vbr->req->cmd_type) { 89 case REQ_TYPE_BLOCK_PC: 90 vbr->req->resid_len = vbr->in_hdr.residual; 91 vbr->req->sense_len = vbr->in_hdr.sense_len; 92 vbr->req->errors = vbr->in_hdr.errors; 93 break; 94 case REQ_TYPE_SPECIAL: 95 vbr->req->errors = (error != 0); 96 break; 97 default: 98 break; 99 } 100 101 __blk_end_request_all(vbr->req, error); 102 list_del(&vbr->list); 103 mempool_free(vbr, vblk->pool); 104 } 105 /* In case queue is stopped waiting for more buffers. */ 106 blk_start_queue(vblk->disk->queue); 107 spin_unlock_irqrestore(&vblk->lock, flags); 108 } 109 110 static bool do_req(struct request_queue *q, struct virtio_blk *vblk, 111 struct request *req) 112 { 113 unsigned long num, out = 0, in = 0; 114 struct virtblk_req *vbr; 115 116 vbr = mempool_alloc(vblk->pool, GFP_ATOMIC); 117 if (!vbr) 118 /* When another request finishes we'll try again. */ 119 return false; 120 121 vbr->req = req; 122 123 if (req->cmd_flags & REQ_FLUSH) { 124 vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH; 125 vbr->out_hdr.sector = 0; 126 vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); 127 } else { 128 switch (req->cmd_type) { 129 case REQ_TYPE_FS: 130 vbr->out_hdr.type = 0; 131 vbr->out_hdr.sector = blk_rq_pos(vbr->req); 132 vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); 133 break; 134 case REQ_TYPE_BLOCK_PC: 135 vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD; 136 vbr->out_hdr.sector = 0; 137 vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); 138 break; 139 case REQ_TYPE_SPECIAL: 140 vbr->out_hdr.type = VIRTIO_BLK_T_GET_ID; 141 vbr->out_hdr.sector = 0; 142 vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); 143 break; 144 default: 145 /* We don't put anything else in the queue. */ 146 BUG(); 147 } 148 } 149 150 sg_set_buf(&vblk->sg[out++], &vbr->out_hdr, sizeof(vbr->out_hdr)); 151 152 /* 153 * If this is a packet command we need a couple of additional headers. 154 * Behind the normal outhdr we put a segment with the scsi command 155 * block, and before the normal inhdr we put the sense data and the 156 * inhdr with additional status information before the normal inhdr. 157 */ 158 if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) 159 sg_set_buf(&vblk->sg[out++], vbr->req->cmd, vbr->req->cmd_len); 160 161 num = blk_rq_map_sg(q, vbr->req, vblk->sg + out); 162 163 if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) { 164 sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, SCSI_SENSE_BUFFERSIZE); 165 sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr, 166 sizeof(vbr->in_hdr)); 167 } 168 169 sg_set_buf(&vblk->sg[num + out + in++], &vbr->status, 170 sizeof(vbr->status)); 171 172 if (num) { 173 if (rq_data_dir(vbr->req) == WRITE) { 174 vbr->out_hdr.type |= VIRTIO_BLK_T_OUT; 175 out += num; 176 } else { 177 vbr->out_hdr.type |= VIRTIO_BLK_T_IN; 178 in += num; 179 } 180 } 181 182 if (virtqueue_add_buf(vblk->vq, vblk->sg, out, in, vbr, GFP_ATOMIC)<0) { 183 mempool_free(vbr, vblk->pool); 184 return false; 185 } 186 187 list_add_tail(&vbr->list, &vblk->reqs); 188 return true; 189 } 190 191 static void do_virtblk_request(struct request_queue *q) 192 { 193 struct virtio_blk *vblk = q->queuedata; 194 struct request *req; 195 unsigned int issued = 0; 196 197 while ((req = blk_peek_request(q)) != NULL) { 198 BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems); 199 200 /* If this request fails, stop queue and wait for something to 201 finish to restart it. */ 202 if (!do_req(q, vblk, req)) { 203 blk_stop_queue(q); 204 break; 205 } 206 blk_start_request(req); 207 issued++; 208 } 209 210 if (issued) 211 virtqueue_kick(vblk->vq); 212 } 213 214 /* return id (s/n) string for *disk to *id_str 215 */ 216 static int virtblk_get_id(struct gendisk *disk, char *id_str) 217 { 218 struct virtio_blk *vblk = disk->private_data; 219 struct request *req; 220 struct bio *bio; 221 int err; 222 223 bio = bio_map_kern(vblk->disk->queue, id_str, VIRTIO_BLK_ID_BYTES, 224 GFP_KERNEL); 225 if (IS_ERR(bio)) 226 return PTR_ERR(bio); 227 228 req = blk_make_request(vblk->disk->queue, bio, GFP_KERNEL); 229 if (IS_ERR(req)) { 230 bio_put(bio); 231 return PTR_ERR(req); 232 } 233 234 req->cmd_type = REQ_TYPE_SPECIAL; 235 err = blk_execute_rq(vblk->disk->queue, vblk->disk, req, false); 236 blk_put_request(req); 237 238 return err; 239 } 240 241 static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, 242 unsigned int cmd, unsigned long data) 243 { 244 struct gendisk *disk = bdev->bd_disk; 245 struct virtio_blk *vblk = disk->private_data; 246 247 /* 248 * Only allow the generic SCSI ioctls if the host can support it. 249 */ 250 if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI)) 251 return -ENOTTY; 252 253 return scsi_cmd_blk_ioctl(bdev, mode, cmd, 254 (void __user *)data); 255 } 256 257 /* We provide getgeo only to please some old bootloader/partitioning tools */ 258 static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) 259 { 260 struct virtio_blk *vblk = bd->bd_disk->private_data; 261 struct virtio_blk_geometry vgeo; 262 int err; 263 264 /* see if the host passed in geometry config */ 265 err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY, 266 offsetof(struct virtio_blk_config, geometry), 267 &vgeo); 268 269 if (!err) { 270 geo->heads = vgeo.heads; 271 geo->sectors = vgeo.sectors; 272 geo->cylinders = vgeo.cylinders; 273 } else { 274 /* some standard values, similar to sd */ 275 geo->heads = 1 << 6; 276 geo->sectors = 1 << 5; 277 geo->cylinders = get_capacity(bd->bd_disk) >> 11; 278 } 279 return 0; 280 } 281 282 static const struct block_device_operations virtblk_fops = { 283 .ioctl = virtblk_ioctl, 284 .owner = THIS_MODULE, 285 .getgeo = virtblk_getgeo, 286 }; 287 288 static int index_to_minor(int index) 289 { 290 return index << PART_BITS; 291 } 292 293 static int minor_to_index(int minor) 294 { 295 return minor >> PART_BITS; 296 } 297 298 static ssize_t virtblk_serial_show(struct device *dev, 299 struct device_attribute *attr, char *buf) 300 { 301 struct gendisk *disk = dev_to_disk(dev); 302 int err; 303 304 /* sysfs gives us a PAGE_SIZE buffer */ 305 BUILD_BUG_ON(PAGE_SIZE < VIRTIO_BLK_ID_BYTES); 306 307 buf[VIRTIO_BLK_ID_BYTES] = '\0'; 308 err = virtblk_get_id(disk, buf); 309 if (!err) 310 return strlen(buf); 311 312 if (err == -EIO) /* Unsupported? Make it empty. */ 313 return 0; 314 315 return err; 316 } 317 DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL); 318 319 static void virtblk_config_changed_work(struct work_struct *work) 320 { 321 struct virtio_blk *vblk = 322 container_of(work, struct virtio_blk, config_work); 323 struct virtio_device *vdev = vblk->vdev; 324 struct request_queue *q = vblk->disk->queue; 325 char cap_str_2[10], cap_str_10[10]; 326 u64 capacity, size; 327 328 mutex_lock(&vblk->config_lock); 329 if (!vblk->config_enable) 330 goto done; 331 332 /* Host must always specify the capacity. */ 333 vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), 334 &capacity, sizeof(capacity)); 335 336 /* If capacity is too big, truncate with warning. */ 337 if ((sector_t)capacity != capacity) { 338 dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n", 339 (unsigned long long)capacity); 340 capacity = (sector_t)-1; 341 } 342 343 size = capacity * queue_logical_block_size(q); 344 string_get_size(size, STRING_UNITS_2, cap_str_2, sizeof(cap_str_2)); 345 string_get_size(size, STRING_UNITS_10, cap_str_10, sizeof(cap_str_10)); 346 347 dev_notice(&vdev->dev, 348 "new size: %llu %d-byte logical blocks (%s/%s)\n", 349 (unsigned long long)capacity, 350 queue_logical_block_size(q), 351 cap_str_10, cap_str_2); 352 353 set_capacity(vblk->disk, capacity); 354 revalidate_disk(vblk->disk); 355 done: 356 mutex_unlock(&vblk->config_lock); 357 } 358 359 static void virtblk_config_changed(struct virtio_device *vdev) 360 { 361 struct virtio_blk *vblk = vdev->priv; 362 363 queue_work(virtblk_wq, &vblk->config_work); 364 } 365 366 static int init_vq(struct virtio_blk *vblk) 367 { 368 int err = 0; 369 370 /* We expect one virtqueue, for output. */ 371 vblk->vq = virtio_find_single_vq(vblk->vdev, blk_done, "requests"); 372 if (IS_ERR(vblk->vq)) 373 err = PTR_ERR(vblk->vq); 374 375 return err; 376 } 377 378 /* 379 * Legacy naming scheme used for virtio devices. We are stuck with it for 380 * virtio blk but don't ever use it for any new driver. 381 */ 382 static int virtblk_name_format(char *prefix, int index, char *buf, int buflen) 383 { 384 const int base = 'z' - 'a' + 1; 385 char *begin = buf + strlen(prefix); 386 char *end = buf + buflen; 387 char *p; 388 int unit; 389 390 p = end - 1; 391 *p = '\0'; 392 unit = base; 393 do { 394 if (p == begin) 395 return -EINVAL; 396 *--p = 'a' + (index % unit); 397 index = (index / unit) - 1; 398 } while (index >= 0); 399 400 memmove(begin, p, end - p); 401 memcpy(buf, prefix, strlen(prefix)); 402 403 return 0; 404 } 405 406 static int __devinit virtblk_probe(struct virtio_device *vdev) 407 { 408 struct virtio_blk *vblk; 409 struct request_queue *q; 410 int err, index; 411 u64 cap; 412 u32 v, blk_size, sg_elems, opt_io_size; 413 u16 min_io_size; 414 u8 physical_block_exp, alignment_offset; 415 416 err = ida_simple_get(&vd_index_ida, 0, minor_to_index(1 << MINORBITS), 417 GFP_KERNEL); 418 if (err < 0) 419 goto out; 420 index = err; 421 422 /* We need to know how many segments before we allocate. */ 423 err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, 424 offsetof(struct virtio_blk_config, seg_max), 425 &sg_elems); 426 427 /* We need at least one SG element, whatever they say. */ 428 if (err || !sg_elems) 429 sg_elems = 1; 430 431 /* We need an extra sg elements at head and tail. */ 432 sg_elems += 2; 433 vdev->priv = vblk = kmalloc(sizeof(*vblk) + 434 sizeof(vblk->sg[0]) * sg_elems, GFP_KERNEL); 435 if (!vblk) { 436 err = -ENOMEM; 437 goto out_free_index; 438 } 439 440 INIT_LIST_HEAD(&vblk->reqs); 441 spin_lock_init(&vblk->lock); 442 vblk->vdev = vdev; 443 vblk->sg_elems = sg_elems; 444 sg_init_table(vblk->sg, vblk->sg_elems); 445 mutex_init(&vblk->config_lock); 446 INIT_WORK(&vblk->config_work, virtblk_config_changed_work); 447 vblk->config_enable = true; 448 449 err = init_vq(vblk); 450 if (err) 451 goto out_free_vblk; 452 453 vblk->pool = mempool_create_kmalloc_pool(1,sizeof(struct virtblk_req)); 454 if (!vblk->pool) { 455 err = -ENOMEM; 456 goto out_free_vq; 457 } 458 459 /* FIXME: How many partitions? How long is a piece of string? */ 460 vblk->disk = alloc_disk(1 << PART_BITS); 461 if (!vblk->disk) { 462 err = -ENOMEM; 463 goto out_mempool; 464 } 465 466 q = vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock); 467 if (!q) { 468 err = -ENOMEM; 469 goto out_put_disk; 470 } 471 472 q->queuedata = vblk; 473 474 virtblk_name_format("vd", index, vblk->disk->disk_name, DISK_NAME_LEN); 475 476 vblk->disk->major = major; 477 vblk->disk->first_minor = index_to_minor(index); 478 vblk->disk->private_data = vblk; 479 vblk->disk->fops = &virtblk_fops; 480 vblk->disk->driverfs_dev = &vdev->dev; 481 vblk->index = index; 482 483 /* configure queue flush support */ 484 if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH)) 485 blk_queue_flush(q, REQ_FLUSH); 486 487 /* If disk is read-only in the host, the guest should obey */ 488 if (virtio_has_feature(vdev, VIRTIO_BLK_F_RO)) 489 set_disk_ro(vblk->disk, 1); 490 491 /* Host must always specify the capacity. */ 492 vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity), 493 &cap, sizeof(cap)); 494 495 /* If capacity is too big, truncate with warning. */ 496 if ((sector_t)cap != cap) { 497 dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n", 498 (unsigned long long)cap); 499 cap = (sector_t)-1; 500 } 501 set_capacity(vblk->disk, cap); 502 503 /* We can handle whatever the host told us to handle. */ 504 blk_queue_max_segments(q, vblk->sg_elems-2); 505 506 /* No need to bounce any requests */ 507 blk_queue_bounce_limit(q, BLK_BOUNCE_ANY); 508 509 /* No real sector limit. */ 510 blk_queue_max_hw_sectors(q, -1U); 511 512 /* Host can optionally specify maximum segment size and number of 513 * segments. */ 514 err = virtio_config_val(vdev, VIRTIO_BLK_F_SIZE_MAX, 515 offsetof(struct virtio_blk_config, size_max), 516 &v); 517 if (!err) 518 blk_queue_max_segment_size(q, v); 519 else 520 blk_queue_max_segment_size(q, -1U); 521 522 /* Host can optionally specify the block size of the device */ 523 err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE, 524 offsetof(struct virtio_blk_config, blk_size), 525 &blk_size); 526 if (!err) 527 blk_queue_logical_block_size(q, blk_size); 528 else 529 blk_size = queue_logical_block_size(q); 530 531 /* Use topology information if available */ 532 err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, 533 offsetof(struct virtio_blk_config, physical_block_exp), 534 &physical_block_exp); 535 if (!err && physical_block_exp) 536 blk_queue_physical_block_size(q, 537 blk_size * (1 << physical_block_exp)); 538 539 err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, 540 offsetof(struct virtio_blk_config, alignment_offset), 541 &alignment_offset); 542 if (!err && alignment_offset) 543 blk_queue_alignment_offset(q, blk_size * alignment_offset); 544 545 err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, 546 offsetof(struct virtio_blk_config, min_io_size), 547 &min_io_size); 548 if (!err && min_io_size) 549 blk_queue_io_min(q, blk_size * min_io_size); 550 551 err = virtio_config_val(vdev, VIRTIO_BLK_F_TOPOLOGY, 552 offsetof(struct virtio_blk_config, opt_io_size), 553 &opt_io_size); 554 if (!err && opt_io_size) 555 blk_queue_io_opt(q, blk_size * opt_io_size); 556 557 558 add_disk(vblk->disk); 559 err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial); 560 if (err) 561 goto out_del_disk; 562 563 return 0; 564 565 out_del_disk: 566 del_gendisk(vblk->disk); 567 blk_cleanup_queue(vblk->disk->queue); 568 out_put_disk: 569 put_disk(vblk->disk); 570 out_mempool: 571 mempool_destroy(vblk->pool); 572 out_free_vq: 573 vdev->config->del_vqs(vdev); 574 out_free_vblk: 575 kfree(vblk); 576 out_free_index: 577 ida_simple_remove(&vd_index_ida, index); 578 out: 579 return err; 580 } 581 582 static void __devexit virtblk_remove(struct virtio_device *vdev) 583 { 584 struct virtio_blk *vblk = vdev->priv; 585 int index = vblk->index; 586 587 /* Prevent config work handler from accessing the device. */ 588 mutex_lock(&vblk->config_lock); 589 vblk->config_enable = false; 590 mutex_unlock(&vblk->config_lock); 591 592 /* Nothing should be pending. */ 593 BUG_ON(!list_empty(&vblk->reqs)); 594 595 /* Stop all the virtqueues. */ 596 vdev->config->reset(vdev); 597 598 flush_work(&vblk->config_work); 599 600 del_gendisk(vblk->disk); 601 blk_cleanup_queue(vblk->disk->queue); 602 put_disk(vblk->disk); 603 mempool_destroy(vblk->pool); 604 vdev->config->del_vqs(vdev); 605 kfree(vblk); 606 ida_simple_remove(&vd_index_ida, index); 607 } 608 609 #ifdef CONFIG_PM 610 static int virtblk_freeze(struct virtio_device *vdev) 611 { 612 struct virtio_blk *vblk = vdev->priv; 613 614 /* Ensure we don't receive any more interrupts */ 615 vdev->config->reset(vdev); 616 617 /* Prevent config work handler from accessing the device. */ 618 mutex_lock(&vblk->config_lock); 619 vblk->config_enable = false; 620 mutex_unlock(&vblk->config_lock); 621 622 flush_work(&vblk->config_work); 623 624 spin_lock_irq(vblk->disk->queue->queue_lock); 625 blk_stop_queue(vblk->disk->queue); 626 spin_unlock_irq(vblk->disk->queue->queue_lock); 627 blk_sync_queue(vblk->disk->queue); 628 629 vdev->config->del_vqs(vdev); 630 return 0; 631 } 632 633 static int virtblk_restore(struct virtio_device *vdev) 634 { 635 struct virtio_blk *vblk = vdev->priv; 636 int ret; 637 638 vblk->config_enable = true; 639 ret = init_vq(vdev->priv); 640 if (!ret) { 641 spin_lock_irq(vblk->disk->queue->queue_lock); 642 blk_start_queue(vblk->disk->queue); 643 spin_unlock_irq(vblk->disk->queue->queue_lock); 644 } 645 return ret; 646 } 647 #endif 648 649 static const struct virtio_device_id id_table[] = { 650 { VIRTIO_ID_BLOCK, VIRTIO_DEV_ANY_ID }, 651 { 0 }, 652 }; 653 654 static unsigned int features[] = { 655 VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY, 656 VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, VIRTIO_BLK_F_SCSI, 657 VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY 658 }; 659 660 /* 661 * virtio_blk causes spurious section mismatch warning by 662 * simultaneously referring to a __devinit and a __devexit function. 663 * Use __refdata to avoid this warning. 664 */ 665 static struct virtio_driver __refdata virtio_blk = { 666 .feature_table = features, 667 .feature_table_size = ARRAY_SIZE(features), 668 .driver.name = KBUILD_MODNAME, 669 .driver.owner = THIS_MODULE, 670 .id_table = id_table, 671 .probe = virtblk_probe, 672 .remove = __devexit_p(virtblk_remove), 673 .config_changed = virtblk_config_changed, 674 #ifdef CONFIG_PM 675 .freeze = virtblk_freeze, 676 .restore = virtblk_restore, 677 #endif 678 }; 679 680 static int __init init(void) 681 { 682 int error; 683 684 virtblk_wq = alloc_workqueue("virtio-blk", 0, 0); 685 if (!virtblk_wq) 686 return -ENOMEM; 687 688 major = register_blkdev(0, "virtblk"); 689 if (major < 0) { 690 error = major; 691 goto out_destroy_workqueue; 692 } 693 694 error = register_virtio_driver(&virtio_blk); 695 if (error) 696 goto out_unregister_blkdev; 697 return 0; 698 699 out_unregister_blkdev: 700 unregister_blkdev(major, "virtblk"); 701 out_destroy_workqueue: 702 destroy_workqueue(virtblk_wq); 703 return error; 704 } 705 706 static void __exit fini(void) 707 { 708 unregister_blkdev(major, "virtblk"); 709 unregister_virtio_driver(&virtio_blk); 710 destroy_workqueue(virtblk_wq); 711 } 712 module_init(init); 713 module_exit(fini); 714 715 MODULE_DEVICE_TABLE(virtio, id_table); 716 MODULE_DESCRIPTION("Virtio block driver"); 717 MODULE_LICENSE("GPL"); 718