Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://github.com/rustyrussell/linux

* git://github.com/rustyrussell/linux:
virtio-blk: use ida to allocate disk index
virtio: Add platform bus driver for memory mapped virtio device
virtio: Dont add "config" to list for !per_vq_vector
virtio: console: wait for first console port for early console output
virtio: console: add port stats for bytes received, sent and discarded
virtio: console: make discard_port_data() use get_inbuf()
virtio: console: rename variable
virtio: console: make get_inbuf() return port->inbuf if present
virtio: console: Fix return type for get_inbuf()
virtio: console: Use wait_event_freezable instead of _interruptible
virtio: console: Ignore port name update request if name already set
virtio: console: Fix indentation
virtio: modify vring_init and vring_size to take account of the layout containing *_event_idx
virtio.h: correct comment for struct virtio_driver
virtio-net: Use virtio_config_val() for retrieving config
virtio_config: Add virtio_config_val_len()
virtio-console: Use virtio_config_val() for retrieving config

+744 -66
+17
Documentation/devicetree/bindings/virtio/mmio.txt
··· 1 + * virtio memory mapped device 2 + 3 + See http://ozlabs.org/~rusty/virtio-spec/ for more details. 4 + 5 + Required properties: 6 + 7 + - compatible: "virtio,mmio" compatibility string 8 + - reg: control registers base address and size including configuration space 9 + - interrupts: interrupt generated by the device 10 + 11 + Example: 12 + 13 + virtio_block@3000 { 14 + compatible = "virtio,mmio"; 15 + reg = <0x3000 0x100>; 16 + interrupts = <41>; 17 + }
+24 -6
drivers/block/virtio_blk.c
··· 8 8 #include <linux/scatterlist.h> 9 9 #include <linux/string_helpers.h> 10 10 #include <scsi/scsi_cmnd.h> 11 + #include <linux/idr.h> 11 12 12 13 #define PART_BITS 4 13 14 14 - static int major, index; 15 + static int major; 16 + static DEFINE_IDA(vd_index_ida); 17 + 15 18 struct workqueue_struct *virtblk_wq; 16 19 17 20 struct virtio_blk ··· 37 34 38 35 /* What host tells us, plus 2 for header & tailer. */ 39 36 unsigned int sg_elems; 37 + 38 + /* Ida index - used to track minor number allocations. */ 39 + int index; 40 40 41 41 /* Scatterlist: can be too big for stack. */ 42 42 struct scatterlist sg[/*sg_elems*/]; ··· 282 276 return index << PART_BITS; 283 277 } 284 278 279 + static int minor_to_index(int minor) 280 + { 281 + return minor >> PART_BITS; 282 + } 283 + 285 284 static ssize_t virtblk_serial_show(struct device *dev, 286 285 struct device_attribute *attr, char *buf) 287 286 { ··· 352 341 { 353 342 struct virtio_blk *vblk; 354 343 struct request_queue *q; 355 - int err; 344 + int err, index; 356 345 u64 cap; 357 346 u32 v, blk_size, sg_elems, opt_io_size; 358 347 u16 min_io_size; 359 348 u8 physical_block_exp, alignment_offset; 360 349 361 - if (index_to_minor(index) >= 1 << MINORBITS) 362 - return -ENOSPC; 350 + err = ida_simple_get(&vd_index_ida, 0, minor_to_index(1 << MINORBITS), 351 + GFP_KERNEL); 352 + if (err < 0) 353 + goto out; 354 + index = err; 363 355 364 356 /* We need to know how many segments before we allocate. */ 365 357 err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX, ··· 379 365 sizeof(vblk->sg[0]) * sg_elems, GFP_KERNEL); 380 366 if (!vblk) { 381 367 err = -ENOMEM; 382 - goto out; 368 + goto out_free_index; 383 369 } 384 370 385 371 INIT_LIST_HEAD(&vblk->reqs); ··· 435 421 vblk->disk->private_data = vblk; 436 422 vblk->disk->fops = &virtblk_fops; 437 423 vblk->disk->driverfs_dev = &vdev->dev; 438 - index++; 424 + vblk->index = index; 439 425 440 426 /* configure queue flush support */ 441 427 if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH)) ··· 530 516 vdev->config->del_vqs(vdev); 531 517 out_free_vblk: 532 518 kfree(vblk); 519 + out_free_index: 520 + ida_simple_remove(&vd_index_ida, index); 533 521 out: 534 522 return err; 535 523 } ··· 539 523 static void __devexit virtblk_remove(struct virtio_device *vdev) 540 524 { 541 525 struct virtio_blk *vblk = vdev->priv; 526 + int index = vblk->index; 542 527 543 528 flush_work(&vblk->config_work); 544 529 ··· 555 538 mempool_destroy(vblk->pool); 556 539 vdev->config->del_vqs(vdev); 557 540 kfree(vblk); 541 + ida_simple_remove(&vd_index_ida, index); 558 542 } 559 543 560 544 static const struct virtio_device_id id_table[] = {
+81 -43
drivers/char/virtio_console.c
··· 19 19 */ 20 20 #include <linux/cdev.h> 21 21 #include <linux/debugfs.h> 22 + #include <linux/completion.h> 22 23 #include <linux/device.h> 23 24 #include <linux/err.h> 25 + #include <linux/freezer.h> 24 26 #include <linux/fs.h> 25 27 #include <linux/init.h> 26 28 #include <linux/list.h> ··· 75 73 static struct ports_driver_data pdrvdata; 76 74 77 75 DEFINE_SPINLOCK(pdrvdata_lock); 76 + DECLARE_COMPLETION(early_console_added); 78 77 79 78 /* This struct holds information that's relevant only for console ports */ 80 79 struct console { ··· 154 151 int chr_major; 155 152 }; 156 153 154 + struct port_stats { 155 + unsigned long bytes_sent, bytes_received, bytes_discarded; 156 + }; 157 + 157 158 /* This struct holds the per-port data */ 158 159 struct port { 159 160 /* Next port in the list, head is in the ports_device */ ··· 184 177 185 178 /* File in the debugfs directory that exposes this port's information */ 186 179 struct dentry *debugfs_file; 180 + 181 + /* 182 + * Keep count of the bytes sent, received and discarded for 183 + * this port for accounting and debugging purposes. These 184 + * counts are not reset across port open / close events. 185 + */ 186 + struct port_stats stats; 187 187 188 188 /* 189 189 * The entries in this struct will be valid if this port is ··· 361 347 } 362 348 363 349 /* Callers should take appropriate locks */ 364 - static void *get_inbuf(struct port *port) 350 + static struct port_buffer *get_inbuf(struct port *port) 365 351 { 366 352 struct port_buffer *buf; 367 - struct virtqueue *vq; 368 353 unsigned int len; 369 354 370 - vq = port->in_vq; 371 - buf = virtqueue_get_buf(vq, &len); 355 + if (port->inbuf) 356 + return port->inbuf; 357 + 358 + buf = virtqueue_get_buf(port->in_vq, &len); 372 359 if (buf) { 373 360 buf->len = len; 374 361 buf->offset = 0; 362 + port->stats.bytes_received += len; 375 363 } 376 364 return buf; 377 365 } ··· 400 384 static void discard_port_data(struct port *port) 401 385 { 402 386 struct port_buffer *buf; 403 - struct virtqueue *vq; 404 - unsigned int len; 405 - int ret; 387 + unsigned int err; 406 388 407 389 if (!port->portdev) { 408 390 /* Device has been unplugged. vqs are already gone. */ 409 391 return; 410 392 } 411 - vq = port->in_vq; 412 - if (port->inbuf) 413 - buf = port->inbuf; 414 - else 415 - buf = virtqueue_get_buf(vq, &len); 393 + buf = get_inbuf(port); 416 394 417 - ret = 0; 395 + err = 0; 418 396 while (buf) { 419 - if (add_inbuf(vq, buf) < 0) { 420 - ret++; 397 + port->stats.bytes_discarded += buf->len - buf->offset; 398 + if (add_inbuf(port->in_vq, buf) < 0) { 399 + err++; 421 400 free_buf(buf); 422 401 } 423 - buf = virtqueue_get_buf(vq, &len); 402 + port->inbuf = NULL; 403 + buf = get_inbuf(port); 424 404 } 425 - port->inbuf = NULL; 426 - if (ret) 405 + if (err) 427 406 dev_warn(port->dev, "Errors adding %d buffers back to vq\n", 428 - ret); 407 + err); 429 408 } 430 409 431 410 static bool port_has_data(struct port *port) ··· 428 417 unsigned long flags; 429 418 bool ret; 430 419 431 - spin_lock_irqsave(&port->inbuf_lock, flags); 432 - if (port->inbuf) { 433 - ret = true; 434 - goto out; 435 - } 436 - port->inbuf = get_inbuf(port); 437 - if (port->inbuf) { 438 - ret = true; 439 - goto out; 440 - } 441 420 ret = false; 442 - out: 421 + spin_lock_irqsave(&port->inbuf_lock, flags); 422 + port->inbuf = get_inbuf(port); 423 + if (port->inbuf) 424 + ret = true; 425 + 443 426 spin_unlock_irqrestore(&port->inbuf_lock, flags); 444 427 return ret; 445 428 } ··· 534 529 cpu_relax(); 535 530 done: 536 531 spin_unlock_irqrestore(&port->outvq_lock, flags); 532 + 533 + port->stats.bytes_sent += in_count; 537 534 /* 538 535 * We're expected to return the amount of data we wrote -- all 539 536 * of it ··· 640 633 if (filp->f_flags & O_NONBLOCK) 641 634 return -EAGAIN; 642 635 643 - ret = wait_event_interruptible(port->waitqueue, 644 - !will_read_block(port)); 636 + ret = wait_event_freezable(port->waitqueue, 637 + !will_read_block(port)); 645 638 if (ret < 0) 646 639 return ret; 647 640 } ··· 684 677 if (nonblock) 685 678 return -EAGAIN; 686 679 687 - ret = wait_event_interruptible(port->waitqueue, 688 - !will_write_block(port)); 680 + ret = wait_event_freezable(port->waitqueue, 681 + !will_write_block(port)); 689 682 if (ret < 0) 690 683 return ret; 691 684 } ··· 1066 1059 out_offset += snprintf(buf + out_offset, out_count - out_offset, 1067 1060 "outvq_full: %d\n", port->outvq_full); 1068 1061 out_offset += snprintf(buf + out_offset, out_count - out_offset, 1062 + "bytes_sent: %lu\n", port->stats.bytes_sent); 1063 + out_offset += snprintf(buf + out_offset, out_count - out_offset, 1064 + "bytes_received: %lu\n", 1065 + port->stats.bytes_received); 1066 + out_offset += snprintf(buf + out_offset, out_count - out_offset, 1067 + "bytes_discarded: %lu\n", 1068 + port->stats.bytes_discarded); 1069 + out_offset += snprintf(buf + out_offset, out_count - out_offset, 1069 1070 "is_console: %s\n", 1070 1071 is_console_port(port) ? "yes" : "no"); 1071 1072 out_offset += snprintf(buf + out_offset, out_count - out_offset, ··· 1158 1143 port->cons.ws.ws_row = port->cons.ws.ws_col = 0; 1159 1144 1160 1145 port->host_connected = port->guest_connected = false; 1146 + port->stats = (struct port_stats) { 0 }; 1161 1147 1162 1148 port->outvq_full = false; 1163 1149 ··· 1368 1352 break; 1369 1353 1370 1354 init_port_console(port); 1355 + complete(&early_console_added); 1371 1356 /* 1372 1357 * Could remove the port here in case init fails - but 1373 1358 * have to notify the host first. ··· 1410 1393 send_sigio_to_port(port); 1411 1394 break; 1412 1395 case VIRTIO_CONSOLE_PORT_NAME: 1396 + /* 1397 + * If we woke up after hibernation, we can get this 1398 + * again. Skip it in that case. 1399 + */ 1400 + if (port->name) 1401 + break; 1402 + 1413 1403 /* 1414 1404 * Skip the size of the header and the cpkt to get the size 1415 1405 * of the name that was sent ··· 1505 1481 return; 1506 1482 1507 1483 spin_lock_irqsave(&port->inbuf_lock, flags); 1508 - if (!port->inbuf) 1509 - port->inbuf = get_inbuf(port); 1484 + port->inbuf = get_inbuf(port); 1510 1485 1511 1486 /* 1512 1487 * Don't queue up data when port is closed. This condition ··· 1586 1563 portdev->out_vqs = kmalloc(nr_ports * sizeof(struct virtqueue *), 1587 1564 GFP_KERNEL); 1588 1565 if (!vqs || !io_callbacks || !io_names || !portdev->in_vqs || 1589 - !portdev->out_vqs) { 1566 + !portdev->out_vqs) { 1590 1567 err = -ENOMEM; 1591 1568 goto free; 1592 1569 } ··· 1671 1648 struct ports_device *portdev; 1672 1649 int err; 1673 1650 bool multiport; 1651 + bool early = early_put_chars != NULL; 1652 + 1653 + /* Ensure to read early_put_chars now */ 1654 + barrier(); 1674 1655 1675 1656 portdev = kmalloc(sizeof(*portdev), GFP_KERNEL); 1676 1657 if (!portdev) { ··· 1702 1675 1703 1676 multiport = false; 1704 1677 portdev->config.max_nr_ports = 1; 1705 - if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) { 1678 + if (virtio_config_val(vdev, VIRTIO_CONSOLE_F_MULTIPORT, 1679 + offsetof(struct virtio_console_config, 1680 + max_nr_ports), 1681 + &portdev->config.max_nr_ports) == 0) 1706 1682 multiport = true; 1707 - vdev->config->get(vdev, offsetof(struct virtio_console_config, 1708 - max_nr_ports), 1709 - &portdev->config.max_nr_ports, 1710 - sizeof(portdev->config.max_nr_ports)); 1711 - } 1712 1683 1713 1684 err = init_vqs(portdev); 1714 1685 if (err < 0) { ··· 1744 1719 1745 1720 __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID, 1746 1721 VIRTIO_CONSOLE_DEVICE_READY, 1); 1722 + 1723 + /* 1724 + * If there was an early virtio console, assume that there are no 1725 + * other consoles. We need to wait until the hvc_alloc matches the 1726 + * hvc_instantiate, otherwise tty_open will complain, resulting in 1727 + * a "Warning: unable to open an initial console" boot failure. 1728 + * Without multiport this is done in add_port above. With multiport 1729 + * this might take some host<->guest communication - thus we have to 1730 + * wait. 1731 + */ 1732 + if (multiport && early) 1733 + wait_for_completion(&early_console_added); 1734 + 1747 1735 return 0; 1748 1736 1749 1737 free_vqs:
+5 -9
drivers/net/virtio_net.c
··· 925 925 { 926 926 u16 v; 927 927 928 - if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) 929 - return; 930 - 931 - vi->vdev->config->get(vi->vdev, 928 + if (virtio_config_val(vi->vdev, VIRTIO_NET_F_STATUS, 932 929 offsetof(struct virtio_net_config, status), 933 - &v, sizeof(v)); 930 + &v) < 0) 931 + return; 934 932 935 933 /* Ignore unknown (future) status bits */ 936 934 v &= VIRTIO_NET_S_LINK_UP; ··· 1004 1006 } 1005 1007 1006 1008 /* Configuration may specify what MAC to use. Otherwise random. */ 1007 - if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) { 1008 - vdev->config->get(vdev, 1009 + if (virtio_config_val_len(vdev, VIRTIO_NET_F_MAC, 1009 1010 offsetof(struct virtio_net_config, mac), 1010 - dev->dev_addr, dev->addr_len); 1011 - } else 1011 + dev->dev_addr, dev->addr_len) < 0) 1012 1012 random_ether_addr(dev->dev_addr); 1013 1013 1014 1014 /* Set up our device-specific information */
+11
drivers/virtio/Kconfig
··· 35 35 36 36 If unsure, say M. 37 37 38 + config VIRTIO_MMIO 39 + tristate "Platform bus driver for memory mapped virtio devices (EXPERIMENTAL)" 40 + depends on EXPERIMENTAL 41 + select VIRTIO 42 + select VIRTIO_RING 43 + ---help--- 44 + This drivers provides support for memory mapped virtio 45 + platform device driver. 46 + 47 + If unsure, say N. 48 + 38 49 endmenu
+1
drivers/virtio/Makefile
··· 1 1 obj-$(CONFIG_VIRTIO) += virtio.o 2 2 obj-$(CONFIG_VIRTIO_RING) += virtio_ring.o 3 + obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o 3 4 obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o 4 5 obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
+479
drivers/virtio/virtio_mmio.c
··· 1 + /* 2 + * Virtio memory mapped device driver 3 + * 4 + * Copyright 2011, ARM Ltd. 5 + * 6 + * This module allows virtio devices to be used over a virtual, memory mapped 7 + * platform device. 8 + * 9 + * Registers layout (all 32-bit wide): 10 + * 11 + * offset d. name description 12 + * ------ -- ---------------- ----------------- 13 + * 14 + * 0x000 R MagicValue Magic value "virt" 15 + * 0x004 R Version Device version (current max. 1) 16 + * 0x008 R DeviceID Virtio device ID 17 + * 0x00c R VendorID Virtio vendor ID 18 + * 19 + * 0x010 R HostFeatures Features supported by the host 20 + * 0x014 W HostFeaturesSel Set of host features to access via HostFeatures 21 + * 22 + * 0x020 W GuestFeatures Features activated by the guest 23 + * 0x024 W GuestFeaturesSel Set of activated features to set via GuestFeatures 24 + * 0x028 W GuestPageSize Size of guest's memory page in bytes 25 + * 26 + * 0x030 W QueueSel Queue selector 27 + * 0x034 R QueueNumMax Maximum size of the currently selected queue 28 + * 0x038 W QueueNum Queue size for the currently selected queue 29 + * 0x03c W QueueAlign Used Ring alignment for the current queue 30 + * 0x040 RW QueuePFN PFN for the currently selected queue 31 + * 32 + * 0x050 W QueueNotify Queue notifier 33 + * 0x060 R InterruptStatus Interrupt status register 34 + * 0x060 W InterruptACK Interrupt acknowledge register 35 + * 0x070 RW Status Device status register 36 + * 37 + * 0x100+ RW Device-specific configuration space 38 + * 39 + * Based on Virtio PCI driver by Anthony Liguori, copyright IBM Corp. 2007 40 + * 41 + * This work is licensed under the terms of the GNU GPL, version 2 or later. 42 + * See the COPYING file in the top-level directory. 43 + */ 44 + 45 + #include <linux/highmem.h> 46 + #include <linux/interrupt.h> 47 + #include <linux/io.h> 48 + #include <linux/list.h> 49 + #include <linux/module.h> 50 + #include <linux/platform_device.h> 51 + #include <linux/slab.h> 52 + #include <linux/spinlock.h> 53 + #include <linux/virtio.h> 54 + #include <linux/virtio_config.h> 55 + #include <linux/virtio_mmio.h> 56 + #include <linux/virtio_ring.h> 57 + 58 + 59 + 60 + /* The alignment to use between consumer and producer parts of vring. 61 + * Currently hardcoded to the page size. */ 62 + #define VIRTIO_MMIO_VRING_ALIGN PAGE_SIZE 63 + 64 + 65 + 66 + #define to_virtio_mmio_device(_plat_dev) \ 67 + container_of(_plat_dev, struct virtio_mmio_device, vdev) 68 + 69 + struct virtio_mmio_device { 70 + struct virtio_device vdev; 71 + struct platform_device *pdev; 72 + 73 + void __iomem *base; 74 + unsigned long version; 75 + 76 + /* a list of queues so we can dispatch IRQs */ 77 + spinlock_t lock; 78 + struct list_head virtqueues; 79 + }; 80 + 81 + struct virtio_mmio_vq_info { 82 + /* the actual virtqueue */ 83 + struct virtqueue *vq; 84 + 85 + /* the number of entries in the queue */ 86 + unsigned int num; 87 + 88 + /* the index of the queue */ 89 + int queue_index; 90 + 91 + /* the virtual address of the ring queue */ 92 + void *queue; 93 + 94 + /* the list node for the virtqueues list */ 95 + struct list_head node; 96 + }; 97 + 98 + 99 + 100 + /* Configuration interface */ 101 + 102 + static u32 vm_get_features(struct virtio_device *vdev) 103 + { 104 + struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); 105 + 106 + /* TODO: Features > 32 bits */ 107 + writel(0, vm_dev->base + VIRTIO_MMIO_HOST_FEATURES_SEL); 108 + 109 + return readl(vm_dev->base + VIRTIO_MMIO_HOST_FEATURES); 110 + } 111 + 112 + static void vm_finalize_features(struct virtio_device *vdev) 113 + { 114 + struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); 115 + int i; 116 + 117 + /* Give virtio_ring a chance to accept features. */ 118 + vring_transport_features(vdev); 119 + 120 + for (i = 0; i < ARRAY_SIZE(vdev->features); i++) { 121 + writel(i, vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES_SET); 122 + writel(vdev->features[i], 123 + vm_dev->base + VIRTIO_MMIO_GUEST_FEATURES); 124 + } 125 + } 126 + 127 + static void vm_get(struct virtio_device *vdev, unsigned offset, 128 + void *buf, unsigned len) 129 + { 130 + struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); 131 + u8 *ptr = buf; 132 + int i; 133 + 134 + for (i = 0; i < len; i++) 135 + ptr[i] = readb(vm_dev->base + VIRTIO_MMIO_CONFIG + offset + i); 136 + } 137 + 138 + static void vm_set(struct virtio_device *vdev, unsigned offset, 139 + const void *buf, unsigned len) 140 + { 141 + struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); 142 + const u8 *ptr = buf; 143 + int i; 144 + 145 + for (i = 0; i < len; i++) 146 + writeb(ptr[i], vm_dev->base + VIRTIO_MMIO_CONFIG + offset + i); 147 + } 148 + 149 + static u8 vm_get_status(struct virtio_device *vdev) 150 + { 151 + struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); 152 + 153 + return readl(vm_dev->base + VIRTIO_MMIO_STATUS) & 0xff; 154 + } 155 + 156 + static void vm_set_status(struct virtio_device *vdev, u8 status) 157 + { 158 + struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); 159 + 160 + /* We should never be setting status to 0. */ 161 + BUG_ON(status == 0); 162 + 163 + writel(status, vm_dev->base + VIRTIO_MMIO_STATUS); 164 + } 165 + 166 + static void vm_reset(struct virtio_device *vdev) 167 + { 168 + struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); 169 + 170 + /* 0 status means a reset. */ 171 + writel(0, vm_dev->base + VIRTIO_MMIO_STATUS); 172 + } 173 + 174 + 175 + 176 + /* Transport interface */ 177 + 178 + /* the notify function used when creating a virt queue */ 179 + static void vm_notify(struct virtqueue *vq) 180 + { 181 + struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev); 182 + struct virtio_mmio_vq_info *info = vq->priv; 183 + 184 + /* We write the queue's selector into the notification register to 185 + * signal the other end */ 186 + writel(info->queue_index, vm_dev->base + VIRTIO_MMIO_QUEUE_NOTIFY); 187 + } 188 + 189 + /* Notify all virtqueues on an interrupt. */ 190 + static irqreturn_t vm_interrupt(int irq, void *opaque) 191 + { 192 + struct virtio_mmio_device *vm_dev = opaque; 193 + struct virtio_mmio_vq_info *info; 194 + struct virtio_driver *vdrv = container_of(vm_dev->vdev.dev.driver, 195 + struct virtio_driver, driver); 196 + unsigned long status; 197 + unsigned long flags; 198 + irqreturn_t ret = IRQ_NONE; 199 + 200 + /* Read and acknowledge interrupts */ 201 + status = readl(vm_dev->base + VIRTIO_MMIO_INTERRUPT_STATUS); 202 + writel(status, vm_dev->base + VIRTIO_MMIO_INTERRUPT_ACK); 203 + 204 + if (unlikely(status & VIRTIO_MMIO_INT_CONFIG) 205 + && vdrv && vdrv->config_changed) { 206 + vdrv->config_changed(&vm_dev->vdev); 207 + ret = IRQ_HANDLED; 208 + } 209 + 210 + if (likely(status & VIRTIO_MMIO_INT_VRING)) { 211 + spin_lock_irqsave(&vm_dev->lock, flags); 212 + list_for_each_entry(info, &vm_dev->virtqueues, node) 213 + ret |= vring_interrupt(irq, info->vq); 214 + spin_unlock_irqrestore(&vm_dev->lock, flags); 215 + } 216 + 217 + return ret; 218 + } 219 + 220 + 221 + 222 + static void vm_del_vq(struct virtqueue *vq) 223 + { 224 + struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev); 225 + struct virtio_mmio_vq_info *info = vq->priv; 226 + unsigned long flags, size; 227 + 228 + spin_lock_irqsave(&vm_dev->lock, flags); 229 + list_del(&info->node); 230 + spin_unlock_irqrestore(&vm_dev->lock, flags); 231 + 232 + vring_del_virtqueue(vq); 233 + 234 + /* Select and deactivate the queue */ 235 + writel(info->queue_index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL); 236 + writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN); 237 + 238 + size = PAGE_ALIGN(vring_size(info->num, VIRTIO_MMIO_VRING_ALIGN)); 239 + free_pages_exact(info->queue, size); 240 + kfree(info); 241 + } 242 + 243 + static void vm_del_vqs(struct virtio_device *vdev) 244 + { 245 + struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); 246 + struct virtqueue *vq, *n; 247 + 248 + list_for_each_entry_safe(vq, n, &vdev->vqs, list) 249 + vm_del_vq(vq); 250 + 251 + free_irq(platform_get_irq(vm_dev->pdev, 0), vm_dev); 252 + } 253 + 254 + 255 + 256 + static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index, 257 + void (*callback)(struct virtqueue *vq), 258 + const char *name) 259 + { 260 + struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); 261 + struct virtio_mmio_vq_info *info; 262 + struct virtqueue *vq; 263 + unsigned long flags, size; 264 + int err; 265 + 266 + /* Select the queue we're interested in */ 267 + writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL); 268 + 269 + /* Queue shouldn't already be set up. */ 270 + if (readl(vm_dev->base + VIRTIO_MMIO_QUEUE_PFN)) { 271 + err = -ENOENT; 272 + goto error_available; 273 + } 274 + 275 + /* Allocate and fill out our active queue description */ 276 + info = kmalloc(sizeof(*info), GFP_KERNEL); 277 + if (!info) { 278 + err = -ENOMEM; 279 + goto error_kmalloc; 280 + } 281 + info->queue_index = index; 282 + 283 + /* Allocate pages for the queue - start with a queue as big as 284 + * possible (limited by maximum size allowed by device), drop down 285 + * to a minimal size, just big enough to fit descriptor table 286 + * and two rings (which makes it "alignment_size * 2") 287 + */ 288 + info->num = readl(vm_dev->base + VIRTIO_MMIO_QUEUE_NUM_MAX); 289 + while (1) { 290 + size = PAGE_ALIGN(vring_size(info->num, 291 + VIRTIO_MMIO_VRING_ALIGN)); 292 + /* Already smallest possible allocation? */ 293 + if (size <= VIRTIO_MMIO_VRING_ALIGN * 2) { 294 + err = -ENOMEM; 295 + goto error_alloc_pages; 296 + } 297 + 298 + info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); 299 + if (info->queue) 300 + break; 301 + 302 + info->num /= 2; 303 + } 304 + 305 + /* Activate the queue */ 306 + writel(info->num, vm_dev->base + VIRTIO_MMIO_QUEUE_NUM); 307 + writel(VIRTIO_MMIO_VRING_ALIGN, 308 + vm_dev->base + VIRTIO_MMIO_QUEUE_ALIGN); 309 + writel(virt_to_phys(info->queue) >> PAGE_SHIFT, 310 + vm_dev->base + VIRTIO_MMIO_QUEUE_PFN); 311 + 312 + /* Create the vring */ 313 + vq = vring_new_virtqueue(info->num, VIRTIO_MMIO_VRING_ALIGN, 314 + vdev, info->queue, vm_notify, callback, name); 315 + if (!vq) { 316 + err = -ENOMEM; 317 + goto error_new_virtqueue; 318 + } 319 + 320 + vq->priv = info; 321 + info->vq = vq; 322 + 323 + spin_lock_irqsave(&vm_dev->lock, flags); 324 + list_add(&info->node, &vm_dev->virtqueues); 325 + spin_unlock_irqrestore(&vm_dev->lock, flags); 326 + 327 + return vq; 328 + 329 + error_new_virtqueue: 330 + writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_PFN); 331 + free_pages_exact(info->queue, size); 332 + error_alloc_pages: 333 + kfree(info); 334 + error_kmalloc: 335 + error_available: 336 + return ERR_PTR(err); 337 + } 338 + 339 + static int vm_find_vqs(struct virtio_device *vdev, unsigned nvqs, 340 + struct virtqueue *vqs[], 341 + vq_callback_t *callbacks[], 342 + const char *names[]) 343 + { 344 + struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev); 345 + unsigned int irq = platform_get_irq(vm_dev->pdev, 0); 346 + int i, err; 347 + 348 + err = request_irq(irq, vm_interrupt, IRQF_SHARED, 349 + dev_name(&vdev->dev), vm_dev); 350 + if (err) 351 + return err; 352 + 353 + for (i = 0; i < nvqs; ++i) { 354 + vqs[i] = vm_setup_vq(vdev, i, callbacks[i], names[i]); 355 + if (IS_ERR(vqs[i])) { 356 + vm_del_vqs(vdev); 357 + return PTR_ERR(vqs[i]); 358 + } 359 + } 360 + 361 + return 0; 362 + } 363 + 364 + 365 + 366 + static struct virtio_config_ops virtio_mmio_config_ops = { 367 + .get = vm_get, 368 + .set = vm_set, 369 + .get_status = vm_get_status, 370 + .set_status = vm_set_status, 371 + .reset = vm_reset, 372 + .find_vqs = vm_find_vqs, 373 + .del_vqs = vm_del_vqs, 374 + .get_features = vm_get_features, 375 + .finalize_features = vm_finalize_features, 376 + }; 377 + 378 + 379 + 380 + /* Platform device */ 381 + 382 + static int __devinit virtio_mmio_probe(struct platform_device *pdev) 383 + { 384 + struct virtio_mmio_device *vm_dev; 385 + struct resource *mem; 386 + unsigned long magic; 387 + 388 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 389 + if (!mem) 390 + return -EINVAL; 391 + 392 + if (!devm_request_mem_region(&pdev->dev, mem->start, 393 + resource_size(mem), pdev->name)) 394 + return -EBUSY; 395 + 396 + vm_dev = devm_kzalloc(&pdev->dev, sizeof(*vm_dev), GFP_KERNEL); 397 + if (!vm_dev) 398 + return -ENOMEM; 399 + 400 + vm_dev->vdev.dev.parent = &pdev->dev; 401 + vm_dev->vdev.config = &virtio_mmio_config_ops; 402 + vm_dev->pdev = pdev; 403 + INIT_LIST_HEAD(&vm_dev->virtqueues); 404 + spin_lock_init(&vm_dev->lock); 405 + 406 + vm_dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); 407 + if (vm_dev->base == NULL) 408 + return -EFAULT; 409 + 410 + /* Check magic value */ 411 + magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE); 412 + if (memcmp(&magic, "virt", 4) != 0) { 413 + dev_warn(&pdev->dev, "Wrong magic value 0x%08lx!\n", magic); 414 + return -ENODEV; 415 + } 416 + 417 + /* Check device version */ 418 + vm_dev->version = readl(vm_dev->base + VIRTIO_MMIO_VERSION); 419 + if (vm_dev->version != 1) { 420 + dev_err(&pdev->dev, "Version %ld not supported!\n", 421 + vm_dev->version); 422 + return -ENXIO; 423 + } 424 + 425 + vm_dev->vdev.id.device = readl(vm_dev->base + VIRTIO_MMIO_DEVICE_ID); 426 + vm_dev->vdev.id.vendor = readl(vm_dev->base + VIRTIO_MMIO_VENDOR_ID); 427 + 428 + writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_GUEST_PAGE_SIZE); 429 + 430 + platform_set_drvdata(pdev, vm_dev); 431 + 432 + return register_virtio_device(&vm_dev->vdev); 433 + } 434 + 435 + static int __devexit virtio_mmio_remove(struct platform_device *pdev) 436 + { 437 + struct virtio_mmio_device *vm_dev = platform_get_drvdata(pdev); 438 + 439 + unregister_virtio_device(&vm_dev->vdev); 440 + 441 + return 0; 442 + } 443 + 444 + 445 + 446 + /* Platform driver */ 447 + 448 + static struct of_device_id virtio_mmio_match[] = { 449 + { .compatible = "virtio,mmio", }, 450 + {}, 451 + }; 452 + MODULE_DEVICE_TABLE(of, virtio_mmio_match); 453 + 454 + static struct platform_driver virtio_mmio_driver = { 455 + .probe = virtio_mmio_probe, 456 + .remove = __devexit_p(virtio_mmio_remove), 457 + .driver = { 458 + .name = "virtio-mmio", 459 + .owner = THIS_MODULE, 460 + .of_match_table = virtio_mmio_match, 461 + }, 462 + }; 463 + 464 + static int __init virtio_mmio_init(void) 465 + { 466 + return platform_driver_register(&virtio_mmio_driver); 467 + } 468 + 469 + static void __exit virtio_mmio_exit(void) 470 + { 471 + platform_driver_unregister(&virtio_mmio_driver); 472 + } 473 + 474 + module_init(virtio_mmio_init); 475 + module_exit(virtio_mmio_exit); 476 + 477 + MODULE_AUTHOR("Pawel Moll <pawel.moll@arm.com>"); 478 + MODULE_DESCRIPTION("Platform bus driver for memory mapped virtio devices"); 479 + MODULE_LICENSE("GPL");
+7 -3
drivers/virtio/virtio_pci.c
··· 415 415 } 416 416 } 417 417 418 - spin_lock_irqsave(&vp_dev->lock, flags); 419 - list_add(&info->node, &vp_dev->virtqueues); 420 - spin_unlock_irqrestore(&vp_dev->lock, flags); 418 + if (callback) { 419 + spin_lock_irqsave(&vp_dev->lock, flags); 420 + list_add(&info->node, &vp_dev->virtqueues); 421 + spin_unlock_irqrestore(&vp_dev->lock, flags); 422 + } else { 423 + INIT_LIST_HEAD(&info->node); 424 + } 421 425 422 426 return vq; 423 427
+2 -2
include/linux/virtio.h
··· 131 131 * virtio_driver - operations for a virtio I/O driver 132 132 * @driver: underlying device driver (populate name and owner). 133 133 * @id_table: the ids serviced by this driver. 134 - * @feature_table: an array of feature numbers supported by this device. 134 + * @feature_table: an array of feature numbers supported by this driver. 135 135 * @feature_table_size: number of entries in the feature table array. 136 136 * @probe: the function to call when a device is found. Returns 0 or -errno. 137 - * @remove: the function when a device is removed. 137 + * @remove: the function to call when a device is removed. 138 138 * @config_changed: optional function to call when the device configuration 139 139 * changes; may be called in interrupt context. 140 140 */
+3
include/linux/virtio_config.h
··· 155 155 #define virtio_config_val(vdev, fbit, offset, v) \ 156 156 virtio_config_buf((vdev), (fbit), (offset), (v), sizeof(*v)) 157 157 158 + #define virtio_config_val_len(vdev, fbit, offset, v, len) \ 159 + virtio_config_buf((vdev), (fbit), (offset), (v), (len)) 160 + 158 161 static inline int virtio_config_buf(struct virtio_device *vdev, 159 162 unsigned int fbit, 160 163 unsigned int offset,
+111
include/linux/virtio_mmio.h
··· 1 + /* 2 + * Virtio platform device driver 3 + * 4 + * Copyright 2011, ARM Ltd. 5 + * 6 + * Based on Virtio PCI driver by Anthony Liguori, copyright IBM Corp. 2007 7 + * 8 + * This header is BSD licensed so anyone can use the definitions to implement 9 + * compatible drivers/servers. 10 + * 11 + * Redistribution and use in source and binary forms, with or without 12 + * modification, are permitted provided that the following conditions 13 + * are met: 14 + * 1. Redistributions of source code must retain the above copyright 15 + * notice, this list of conditions and the following disclaimer. 16 + * 2. Redistributions in binary form must reproduce the above copyright 17 + * notice, this list of conditions and the following disclaimer in the 18 + * documentation and/or other materials provided with the distribution. 19 + * 3. Neither the name of IBM nor the names of its contributors 20 + * may be used to endorse or promote products derived from this software 21 + * without specific prior written permission. 22 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND 23 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 26 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 + * SUCH DAMAGE. 33 + */ 34 + 35 + #ifndef _LINUX_VIRTIO_MMIO_H 36 + #define _LINUX_VIRTIO_MMIO_H 37 + 38 + /* 39 + * Control registers 40 + */ 41 + 42 + /* Magic value ("virt" string) - Read Only */ 43 + #define VIRTIO_MMIO_MAGIC_VALUE 0x000 44 + 45 + /* Virtio device version - Read Only */ 46 + #define VIRTIO_MMIO_VERSION 0x004 47 + 48 + /* Virtio device ID - Read Only */ 49 + #define VIRTIO_MMIO_DEVICE_ID 0x008 50 + 51 + /* Virtio vendor ID - Read Only */ 52 + #define VIRTIO_MMIO_VENDOR_ID 0x00c 53 + 54 + /* Bitmask of the features supported by the host 55 + * (32 bits per set) - Read Only */ 56 + #define VIRTIO_MMIO_HOST_FEATURES 0x010 57 + 58 + /* Host features set selector - Write Only */ 59 + #define VIRTIO_MMIO_HOST_FEATURES_SEL 0x014 60 + 61 + /* Bitmask of features activated by the guest 62 + * (32 bits per set) - Write Only */ 63 + #define VIRTIO_MMIO_GUEST_FEATURES 0x020 64 + 65 + /* Activated features set selector - Write Only */ 66 + #define VIRTIO_MMIO_GUEST_FEATURES_SET 0x024 67 + 68 + /* Guest's memory page size in bytes - Write Only */ 69 + #define VIRTIO_MMIO_GUEST_PAGE_SIZE 0x028 70 + 71 + /* Queue selector - Write Only */ 72 + #define VIRTIO_MMIO_QUEUE_SEL 0x030 73 + 74 + /* Maximum size of the currently selected queue - Read Only */ 75 + #define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034 76 + 77 + /* Queue size for the currently selected queue - Write Only */ 78 + #define VIRTIO_MMIO_QUEUE_NUM 0x038 79 + 80 + /* Used Ring alignment for the currently selected queue - Write Only */ 81 + #define VIRTIO_MMIO_QUEUE_ALIGN 0x03c 82 + 83 + /* Guest's PFN for the currently selected queue - Read Write */ 84 + #define VIRTIO_MMIO_QUEUE_PFN 0x040 85 + 86 + /* Queue notifier - Write Only */ 87 + #define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 88 + 89 + /* Interrupt status - Read Only */ 90 + #define VIRTIO_MMIO_INTERRUPT_STATUS 0x060 91 + 92 + /* Interrupt acknowledge - Write Only */ 93 + #define VIRTIO_MMIO_INTERRUPT_ACK 0x064 94 + 95 + /* Device status register - Read Write */ 96 + #define VIRTIO_MMIO_STATUS 0x070 97 + 98 + /* The config space is defined by each driver as 99 + * the per-driver configuration space - Read Write */ 100 + #define VIRTIO_MMIO_CONFIG 0x100 101 + 102 + 103 + 104 + /* 105 + * Interrupt flags (re: interrupt status & acknowledge registers) 106 + */ 107 + 108 + #define VIRTIO_MMIO_INT_VRING (1 << 0) 109 + #define VIRTIO_MMIO_INT_CONFIG (1 << 1) 110 + 111 + #endif
+3 -3
include/linux/virtio_ring.h
··· 135 135 vr->num = num; 136 136 vr->desc = p; 137 137 vr->avail = p + num*sizeof(struct vring_desc); 138 - vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + align-1) 139 - & ~(align - 1)); 138 + vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(__u16) 139 + + align-1) & ~(align - 1)); 140 140 } 141 141 142 142 static inline unsigned vring_size(unsigned int num, unsigned long align) 143 143 { 144 - return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num) 144 + return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (3 + num) 145 145 + align - 1) & ~(align - 1)) 146 146 + sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num; 147 147 }