diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 22:11:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 22:11:49 -0400 |
commit | 832fe9c222c7d431c2bff5765a0ac61bcb3df8c8 (patch) | |
tree | ce4a482723db61955c47a028b14e3227d290d3be | |
parent | ed9559d38a87a44e3bda87d73a50aab92471d7dc (diff) | |
parent | e34f87256794b87e7f4a8f1812538be7b7b5214c (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
virtio: Add transport feature handling stub for virtio_ring.
virtio: Rename set_features to finalize_features
virtio: Formally reserve bits 28-31 to be 'transport' features.
s390: use virtio_console for KVM on s390
virtio: console as a config option
virtio_console: use virtqueue notification for hvc_console
hvc_console: rework setup to replace irq functions with callbacks
virtio_blk: check for hardsector size from host
virtio: Use bus_type probe and remove methods
virtio: don't always force a notification when ring is full
virtio: clarify that ABI is usable by any implementations
virtio: Recycle unused recv buffer pages for large skbs in net driver
virtio net: Allow receiving SG packets
virtio net: Add ethtool ops for SG/GSO
virtio: fix virtio_net xmit of freed skb bug
28 files changed, 385 insertions, 124 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index eb530b4128ba..2ed88122be93 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -565,6 +565,7 @@ bool "s390 guest support (EXPERIMENTAL)" | |||
565 | depends on 64BIT && EXPERIMENTAL | 565 | depends on 64BIT && EXPERIMENTAL |
566 | select VIRTIO | 566 | select VIRTIO |
567 | select VIRTIO_RING | 567 | select VIRTIO_RING |
568 | select VIRTIO_CONSOLE | ||
568 | help | 569 | help |
569 | Select this option if you want to run the kernel under s390 linux | 570 | Select this option if you want to run the kernel under s390 linux |
570 | endmenu | 571 | endmenu |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b358e18273b0..62122bad1e33 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <asm/sections.h> | 54 | #include <asm/sections.h> |
55 | #include <asm/ebcdic.h> | 55 | #include <asm/ebcdic.h> |
56 | #include <asm/compat.h> | 56 | #include <asm/compat.h> |
57 | #include <asm/kvm_virtio.h> | ||
57 | 58 | ||
58 | long psw_kernel_bits = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY | | 59 | long psw_kernel_bits = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY | |
59 | PSW_MASK_MCHECK | PSW_DEFAULT_KEY); | 60 | PSW_MASK_MCHECK | PSW_DEFAULT_KEY); |
@@ -766,7 +767,8 @@ setup_arch(char **cmdline_p) | |||
766 | printk("We are running under VM (64 bit mode)\n"); | 767 | printk("We are running under VM (64 bit mode)\n"); |
767 | else if (MACHINE_IS_KVM) { | 768 | else if (MACHINE_IS_KVM) { |
768 | printk("We are running under KVM (64 bit mode)\n"); | 769 | printk("We are running under KVM (64 bit mode)\n"); |
769 | add_preferred_console("ttyS", 1, NULL); | 770 | add_preferred_console("hvc", 0, NULL); |
771 | s390_virtio_console_init(); | ||
770 | } else | 772 | } else |
771 | printk("We are running native (64 bit mode)\n"); | 773 | printk("We are running native (64 bit mode)\n"); |
772 | #endif /* CONFIG_64BIT */ | 774 | #endif /* CONFIG_64BIT */ |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index dd7ea203f940..42251095134f 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -196,6 +196,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
196 | int err; | 196 | int err; |
197 | u64 cap; | 197 | u64 cap; |
198 | u32 v; | 198 | u32 v; |
199 | u32 blk_size; | ||
199 | 200 | ||
200 | if (index_to_minor(index) >= 1 << MINORBITS) | 201 | if (index_to_minor(index) >= 1 << MINORBITS) |
201 | return -ENOSPC; | 202 | return -ENOSPC; |
@@ -290,6 +291,13 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
290 | if (!err) | 291 | if (!err) |
291 | blk_queue_max_hw_segments(vblk->disk->queue, v); | 292 | blk_queue_max_hw_segments(vblk->disk->queue, v); |
292 | 293 | ||
294 | /* Host can optionally specify the block size of the device */ | ||
295 | err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE, | ||
296 | offsetof(struct virtio_blk_config, blk_size), | ||
297 | &blk_size); | ||
298 | if (!err) | ||
299 | blk_queue_hardsect_size(vblk->disk->queue, blk_size); | ||
300 | |||
293 | add_disk(vblk->disk); | 301 | add_disk(vblk->disk); |
294 | return 0; | 302 | return 0; |
295 | 303 | ||
@@ -330,7 +338,7 @@ static struct virtio_device_id id_table[] = { | |||
330 | 338 | ||
331 | static unsigned int features[] = { | 339 | static unsigned int features[] = { |
332 | VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, | 340 | VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, |
333 | VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, | 341 | VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, |
334 | }; | 342 | }; |
335 | 343 | ||
336 | static struct virtio_driver virtio_blk = { | 344 | static struct virtio_driver virtio_blk = { |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 67b07576f8bf..6c070dc5f2d4 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -578,11 +578,14 @@ config HVC_DRIVER | |||
578 | It will automatically be selected if one of the back-end console drivers | 578 | It will automatically be selected if one of the back-end console drivers |
579 | is selected. | 579 | is selected. |
580 | 580 | ||
581 | config HVC_IRQ | ||
582 | bool | ||
581 | 583 | ||
582 | config HVC_CONSOLE | 584 | config HVC_CONSOLE |
583 | bool "pSeries Hypervisor Virtual Console support" | 585 | bool "pSeries Hypervisor Virtual Console support" |
584 | depends on PPC_PSERIES | 586 | depends on PPC_PSERIES |
585 | select HVC_DRIVER | 587 | select HVC_DRIVER |
588 | select HVC_IRQ | ||
586 | help | 589 | help |
587 | pSeries machines when partitioned support a hypervisor virtual | 590 | pSeries machines when partitioned support a hypervisor virtual |
588 | console. This driver allows each pSeries partition to have a console | 591 | console. This driver allows each pSeries partition to have a console |
@@ -593,6 +596,7 @@ config HVC_ISERIES | |||
593 | depends on PPC_ISERIES | 596 | depends on PPC_ISERIES |
594 | default y | 597 | default y |
595 | select HVC_DRIVER | 598 | select HVC_DRIVER |
599 | select HVC_IRQ | ||
596 | help | 600 | help |
597 | iSeries machines support a hypervisor virtual console. | 601 | iSeries machines support a hypervisor virtual console. |
598 | 602 | ||
@@ -614,13 +618,18 @@ config HVC_XEN | |||
614 | bool "Xen Hypervisor Console support" | 618 | bool "Xen Hypervisor Console support" |
615 | depends on XEN | 619 | depends on XEN |
616 | select HVC_DRIVER | 620 | select HVC_DRIVER |
621 | select HVC_IRQ | ||
617 | default y | 622 | default y |
618 | help | 623 | help |
619 | Xen virtual console device driver | 624 | Xen virtual console device driver |
620 | 625 | ||
621 | config VIRTIO_CONSOLE | 626 | config VIRTIO_CONSOLE |
622 | bool | 627 | tristate "Virtio console" |
628 | depends on VIRTIO | ||
623 | select HVC_DRIVER | 629 | select HVC_DRIVER |
630 | help | ||
631 | Virtio console for use with lguest and other hypervisors. | ||
632 | |||
624 | 633 | ||
625 | config HVCS | 634 | config HVCS |
626 | tristate "IBM Hypervisor Virtual Console Server support" | 635 | tristate "IBM Hypervisor Virtual Console Server support" |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 4b6e736cfa02..eb02c3506800 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -48,6 +48,7 @@ obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o | |||
48 | obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o | 48 | obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o |
49 | obj-$(CONFIG_HVC_BEAT) += hvc_beat.o | 49 | obj-$(CONFIG_HVC_BEAT) += hvc_beat.o |
50 | obj-$(CONFIG_HVC_DRIVER) += hvc_console.o | 50 | obj-$(CONFIG_HVC_DRIVER) += hvc_console.o |
51 | obj-$(CONFIG_HVC_IRQ) += hvc_irq.o | ||
51 | obj-$(CONFIG_HVC_XEN) += hvc_xen.o | 52 | obj-$(CONFIG_HVC_XEN) += hvc_xen.o |
52 | obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o | 53 | obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o |
53 | obj-$(CONFIG_RAW_DRIVER) += raw.o | 54 | obj-$(CONFIG_RAW_DRIVER) += raw.o |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 2f9759d625cc..02aac104842d 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/kbd_kern.h> | 28 | #include <linux/kbd_kern.h> |
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/kref.h> | ||
31 | #include <linux/kthread.h> | 30 | #include <linux/kthread.h> |
32 | #include <linux/list.h> | 31 | #include <linux/list.h> |
33 | #include <linux/module.h> | 32 | #include <linux/module.h> |
@@ -75,23 +74,6 @@ static int hvc_init(void); | |||
75 | static int sysrq_pressed; | 74 | static int sysrq_pressed; |
76 | #endif | 75 | #endif |
77 | 76 | ||
78 | struct hvc_struct { | ||
79 | spinlock_t lock; | ||
80 | int index; | ||
81 | struct tty_struct *tty; | ||
82 | unsigned int count; | ||
83 | int do_wakeup; | ||
84 | char *outbuf; | ||
85 | int outbuf_size; | ||
86 | int n_outbuf; | ||
87 | uint32_t vtermno; | ||
88 | struct hv_ops *ops; | ||
89 | int irq_requested; | ||
90 | int irq; | ||
91 | struct list_head next; | ||
92 | struct kref kref; /* ref count & hvc_struct lifetime */ | ||
93 | }; | ||
94 | |||
95 | /* dynamic list of hvc_struct instances */ | 77 | /* dynamic list of hvc_struct instances */ |
96 | static LIST_HEAD(hvc_structs); | 78 | static LIST_HEAD(hvc_structs); |
97 | 79 | ||
@@ -298,27 +280,15 @@ int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops) | |||
298 | 280 | ||
299 | return 0; | 281 | return 0; |
300 | } | 282 | } |
283 | EXPORT_SYMBOL_GPL(hvc_instantiate); | ||
301 | 284 | ||
302 | /* Wake the sleeping khvcd */ | 285 | /* Wake the sleeping khvcd */ |
303 | static void hvc_kick(void) | 286 | void hvc_kick(void) |
304 | { | 287 | { |
305 | hvc_kicked = 1; | 288 | hvc_kicked = 1; |
306 | wake_up_process(hvc_task); | 289 | wake_up_process(hvc_task); |
307 | } | 290 | } |
308 | 291 | EXPORT_SYMBOL_GPL(hvc_kick); | |
309 | static int hvc_poll(struct hvc_struct *hp); | ||
310 | |||
311 | /* | ||
312 | * NOTE: This API isn't used if the console adapter doesn't support interrupts. | ||
313 | * In this case the console is poll driven. | ||
314 | */ | ||
315 | static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance) | ||
316 | { | ||
317 | /* if hvc_poll request a repoll, then kick the hvcd thread */ | ||
318 | if (hvc_poll(dev_instance)) | ||
319 | hvc_kick(); | ||
320 | return IRQ_HANDLED; | ||
321 | } | ||
322 | 292 | ||
323 | static void hvc_unthrottle(struct tty_struct *tty) | 293 | static void hvc_unthrottle(struct tty_struct *tty) |
324 | { | 294 | { |
@@ -333,7 +303,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
333 | { | 303 | { |
334 | struct hvc_struct *hp; | 304 | struct hvc_struct *hp; |
335 | unsigned long flags; | 305 | unsigned long flags; |
336 | int irq = 0; | ||
337 | int rc = 0; | 306 | int rc = 0; |
338 | 307 | ||
339 | /* Auto increments kref reference if found. */ | 308 | /* Auto increments kref reference if found. */ |
@@ -352,18 +321,15 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
352 | tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */ | 321 | tty->low_latency = 1; /* Makes flushes to ldisc synchronous. */ |
353 | 322 | ||
354 | hp->tty = tty; | 323 | hp->tty = tty; |
355 | /* Save for request_irq outside of spin_lock. */ | 324 | |
356 | irq = hp->irq; | 325 | if (hp->ops->notifier_add) |
357 | if (irq) | 326 | rc = hp->ops->notifier_add(hp, hp->data); |
358 | hp->irq_requested = 1; | ||
359 | 327 | ||
360 | spin_unlock_irqrestore(&hp->lock, flags); | 328 | spin_unlock_irqrestore(&hp->lock, flags); |
361 | /* check error, fallback to non-irq */ | 329 | |
362 | if (irq) | ||
363 | rc = request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED, "hvc_console", hp); | ||
364 | 330 | ||
365 | /* | 331 | /* |
366 | * If the request_irq() fails and we return an error. The tty layer | 332 | * If the notifier fails we return an error. The tty layer |
367 | * will call hvc_close() after a failed open but we don't want to clean | 333 | * will call hvc_close() after a failed open but we don't want to clean |
368 | * up there so we'll clean up here and clear out the previously set | 334 | * up there so we'll clean up here and clear out the previously set |
369 | * tty fields and return the kref reference. | 335 | * tty fields and return the kref reference. |
@@ -371,7 +337,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
371 | if (rc) { | 337 | if (rc) { |
372 | spin_lock_irqsave(&hp->lock, flags); | 338 | spin_lock_irqsave(&hp->lock, flags); |
373 | hp->tty = NULL; | 339 | hp->tty = NULL; |
374 | hp->irq_requested = 0; | ||
375 | spin_unlock_irqrestore(&hp->lock, flags); | 340 | spin_unlock_irqrestore(&hp->lock, flags); |
376 | tty->driver_data = NULL; | 341 | tty->driver_data = NULL; |
377 | kref_put(&hp->kref, destroy_hvc_struct); | 342 | kref_put(&hp->kref, destroy_hvc_struct); |
@@ -386,7 +351,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
386 | static void hvc_close(struct tty_struct *tty, struct file * filp) | 351 | static void hvc_close(struct tty_struct *tty, struct file * filp) |
387 | { | 352 | { |
388 | struct hvc_struct *hp; | 353 | struct hvc_struct *hp; |
389 | int irq = 0; | ||
390 | unsigned long flags; | 354 | unsigned long flags; |
391 | 355 | ||
392 | if (tty_hung_up_p(filp)) | 356 | if (tty_hung_up_p(filp)) |
@@ -404,9 +368,8 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) | |||
404 | spin_lock_irqsave(&hp->lock, flags); | 368 | spin_lock_irqsave(&hp->lock, flags); |
405 | 369 | ||
406 | if (--hp->count == 0) { | 370 | if (--hp->count == 0) { |
407 | if (hp->irq_requested) | 371 | if (hp->ops->notifier_del) |
408 | irq = hp->irq; | 372 | hp->ops->notifier_del(hp, hp->data); |
409 | hp->irq_requested = 0; | ||
410 | 373 | ||
411 | /* We are done with the tty pointer now. */ | 374 | /* We are done with the tty pointer now. */ |
412 | hp->tty = NULL; | 375 | hp->tty = NULL; |
@@ -418,10 +381,6 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) | |||
418 | * waking periodically to check chars_in_buffer(). | 381 | * waking periodically to check chars_in_buffer(). |
419 | */ | 382 | */ |
420 | tty_wait_until_sent(tty, HVC_CLOSE_WAIT); | 383 | tty_wait_until_sent(tty, HVC_CLOSE_WAIT); |
421 | |||
422 | if (irq) | ||
423 | free_irq(irq, hp); | ||
424 | |||
425 | } else { | 384 | } else { |
426 | if (hp->count < 0) | 385 | if (hp->count < 0) |
427 | printk(KERN_ERR "hvc_close %X: oops, count is %d\n", | 386 | printk(KERN_ERR "hvc_close %X: oops, count is %d\n", |
@@ -436,7 +395,6 @@ static void hvc_hangup(struct tty_struct *tty) | |||
436 | { | 395 | { |
437 | struct hvc_struct *hp = tty->driver_data; | 396 | struct hvc_struct *hp = tty->driver_data; |
438 | unsigned long flags; | 397 | unsigned long flags; |
439 | int irq = 0; | ||
440 | int temp_open_count; | 398 | int temp_open_count; |
441 | 399 | ||
442 | if (!hp) | 400 | if (!hp) |
@@ -458,13 +416,12 @@ static void hvc_hangup(struct tty_struct *tty) | |||
458 | hp->count = 0; | 416 | hp->count = 0; |
459 | hp->n_outbuf = 0; | 417 | hp->n_outbuf = 0; |
460 | hp->tty = NULL; | 418 | hp->tty = NULL; |
461 | if (hp->irq_requested) | 419 | |
462 | /* Saved for use outside of spin_lock. */ | 420 | if (hp->ops->notifier_del) |
463 | irq = hp->irq; | 421 | hp->ops->notifier_del(hp, hp->data); |
464 | hp->irq_requested = 0; | 422 | |
465 | spin_unlock_irqrestore(&hp->lock, flags); | 423 | spin_unlock_irqrestore(&hp->lock, flags); |
466 | if (irq) | 424 | |
467 | free_irq(irq, hp); | ||
468 | while(temp_open_count) { | 425 | while(temp_open_count) { |
469 | --temp_open_count; | 426 | --temp_open_count; |
470 | kref_put(&hp->kref, destroy_hvc_struct); | 427 | kref_put(&hp->kref, destroy_hvc_struct); |
@@ -575,7 +532,7 @@ static u32 timeout = MIN_TIMEOUT; | |||
575 | #define HVC_POLL_READ 0x00000001 | 532 | #define HVC_POLL_READ 0x00000001 |
576 | #define HVC_POLL_WRITE 0x00000002 | 533 | #define HVC_POLL_WRITE 0x00000002 |
577 | 534 | ||
578 | static int hvc_poll(struct hvc_struct *hp) | 535 | int hvc_poll(struct hvc_struct *hp) |
579 | { | 536 | { |
580 | struct tty_struct *tty; | 537 | struct tty_struct *tty; |
581 | int i, n, poll_mask = 0; | 538 | int i, n, poll_mask = 0; |
@@ -602,10 +559,10 @@ static int hvc_poll(struct hvc_struct *hp) | |||
602 | if (test_bit(TTY_THROTTLED, &tty->flags)) | 559 | if (test_bit(TTY_THROTTLED, &tty->flags)) |
603 | goto throttled; | 560 | goto throttled; |
604 | 561 | ||
605 | /* If we aren't interrupt driven and aren't throttled, we always | 562 | /* If we aren't notifier driven and aren't throttled, we always |
606 | * request a reschedule | 563 | * request a reschedule |
607 | */ | 564 | */ |
608 | if (hp->irq == 0) | 565 | if (!hp->irq_requested) |
609 | poll_mask |= HVC_POLL_READ; | 566 | poll_mask |= HVC_POLL_READ; |
610 | 567 | ||
611 | /* Read data if any */ | 568 | /* Read data if any */ |
@@ -674,6 +631,7 @@ static int hvc_poll(struct hvc_struct *hp) | |||
674 | 631 | ||
675 | return poll_mask; | 632 | return poll_mask; |
676 | } | 633 | } |
634 | EXPORT_SYMBOL_GPL(hvc_poll); | ||
677 | 635 | ||
678 | /* | 636 | /* |
679 | * This kthread is either polling or interrupt driven. This is determined by | 637 | * This kthread is either polling or interrupt driven. This is determined by |
@@ -733,7 +691,7 @@ static const struct tty_operations hvc_ops = { | |||
733 | .chars_in_buffer = hvc_chars_in_buffer, | 691 | .chars_in_buffer = hvc_chars_in_buffer, |
734 | }; | 692 | }; |
735 | 693 | ||
736 | struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, | 694 | struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data, |
737 | struct hv_ops *ops, int outbuf_size) | 695 | struct hv_ops *ops, int outbuf_size) |
738 | { | 696 | { |
739 | struct hvc_struct *hp; | 697 | struct hvc_struct *hp; |
@@ -754,7 +712,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, | |||
754 | memset(hp, 0x00, sizeof(*hp)); | 712 | memset(hp, 0x00, sizeof(*hp)); |
755 | 713 | ||
756 | hp->vtermno = vtermno; | 714 | hp->vtermno = vtermno; |
757 | hp->irq = irq; | 715 | hp->data = data; |
758 | hp->ops = ops; | 716 | hp->ops = ops; |
759 | hp->outbuf_size = outbuf_size; | 717 | hp->outbuf_size = outbuf_size; |
760 | hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))]; | 718 | hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))]; |
@@ -784,6 +742,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, | |||
784 | 742 | ||
785 | return hp; | 743 | return hp; |
786 | } | 744 | } |
745 | EXPORT_SYMBOL_GPL(hvc_alloc); | ||
787 | 746 | ||
788 | int __devexit hvc_remove(struct hvc_struct *hp) | 747 | int __devexit hvc_remove(struct hvc_struct *hp) |
789 | { | 748 | { |
diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h index 42ffb17e15df..d9ce10915625 100644 --- a/drivers/char/hvc_console.h +++ b/drivers/char/hvc_console.h | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #ifndef HVC_CONSOLE_H | 27 | #ifndef HVC_CONSOLE_H |
28 | #define HVC_CONSOLE_H | 28 | #define HVC_CONSOLE_H |
29 | #include <linux/kref.h> | ||
29 | 30 | ||
30 | /* | 31 | /* |
31 | * This is the max number of console adapters that can/will be found as | 32 | * This is the max number of console adapters that can/will be found as |
@@ -42,24 +43,50 @@ | |||
42 | */ | 43 | */ |
43 | #define HVC_ALLOC_TTY_ADAPTERS 8 | 44 | #define HVC_ALLOC_TTY_ADAPTERS 8 |
44 | 45 | ||
46 | struct hvc_struct { | ||
47 | spinlock_t lock; | ||
48 | int index; | ||
49 | struct tty_struct *tty; | ||
50 | unsigned int count; | ||
51 | int do_wakeup; | ||
52 | char *outbuf; | ||
53 | int outbuf_size; | ||
54 | int n_outbuf; | ||
55 | uint32_t vtermno; | ||
56 | struct hv_ops *ops; | ||
57 | int irq_requested; | ||
58 | int data; | ||
59 | struct list_head next; | ||
60 | struct kref kref; /* ref count & hvc_struct lifetime */ | ||
61 | }; | ||
45 | 62 | ||
46 | /* implemented by a low level driver */ | 63 | /* implemented by a low level driver */ |
47 | struct hv_ops { | 64 | struct hv_ops { |
48 | int (*get_chars)(uint32_t vtermno, char *buf, int count); | 65 | int (*get_chars)(uint32_t vtermno, char *buf, int count); |
49 | int (*put_chars)(uint32_t vtermno, const char *buf, int count); | 66 | int (*put_chars)(uint32_t vtermno, const char *buf, int count); |
50 | }; | ||
51 | 67 | ||
52 | struct hvc_struct; | 68 | /* Callbacks for notification. Called in open and close */ |
69 | int (*notifier_add)(struct hvc_struct *hp, int irq); | ||
70 | void (*notifier_del)(struct hvc_struct *hp, int irq); | ||
71 | }; | ||
53 | 72 | ||
54 | /* Register a vterm and a slot index for use as a console (console_init) */ | 73 | /* Register a vterm and a slot index for use as a console (console_init) */ |
55 | extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops); | 74 | extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops); |
56 | 75 | ||
57 | /* register a vterm for hvc tty operation (module_init or hotplug add) */ | 76 | /* register a vterm for hvc tty operation (module_init or hotplug add) */ |
58 | extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq, | 77 | extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int data, |
59 | struct hv_ops *ops, int outbuf_size); | 78 | struct hv_ops *ops, int outbuf_size); |
60 | /* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ | 79 | /* remove a vterm from hvc tty operation (module_exit or hotplug remove) */ |
61 | extern int __devexit hvc_remove(struct hvc_struct *hp); | 80 | extern int __devexit hvc_remove(struct hvc_struct *hp); |
62 | 81 | ||
82 | /* data available */ | ||
83 | int hvc_poll(struct hvc_struct *hp); | ||
84 | void hvc_kick(void); | ||
85 | |||
86 | /* default notifier for irq based notification */ | ||
87 | extern int notifier_add_irq(struct hvc_struct *hp, int data); | ||
88 | extern void notifier_del_irq(struct hvc_struct *hp, int data); | ||
89 | |||
63 | 90 | ||
64 | #if defined(CONFIG_XMON) && defined(CONFIG_SMP) | 91 | #if defined(CONFIG_XMON) && defined(CONFIG_SMP) |
65 | #include <asm/xmon.h> | 92 | #include <asm/xmon.h> |
diff --git a/drivers/char/hvc_irq.c b/drivers/char/hvc_irq.c new file mode 100644 index 000000000000..73a59cdb8947 --- /dev/null +++ b/drivers/char/hvc_irq.c | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Copyright IBM Corp. 2001,2008 | ||
3 | * | ||
4 | * This file contains the IRQ specific code for hvc_console | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #include <linux/interrupt.h> | ||
9 | |||
10 | #include "hvc_console.h" | ||
11 | |||
12 | static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance) | ||
13 | { | ||
14 | /* if hvc_poll request a repoll, then kick the hvcd thread */ | ||
15 | if (hvc_poll(dev_instance)) | ||
16 | hvc_kick(); | ||
17 | return IRQ_HANDLED; | ||
18 | } | ||
19 | |||
20 | /* | ||
21 | * For IRQ based systems these callbacks can be used | ||
22 | */ | ||
23 | int notifier_add_irq(struct hvc_struct *hp, int irq) | ||
24 | { | ||
25 | int rc; | ||
26 | |||
27 | if (!irq) { | ||
28 | hp->irq_requested = 0; | ||
29 | return 0; | ||
30 | } | ||
31 | rc = request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED, | ||
32 | "hvc_console", hp); | ||
33 | if (!rc) | ||
34 | hp->irq_requested = 1; | ||
35 | return rc; | ||
36 | } | ||
37 | |||
38 | void notifier_del_irq(struct hvc_struct *hp, int irq) | ||
39 | { | ||
40 | if (!irq) | ||
41 | return; | ||
42 | free_irq(irq, hp); | ||
43 | hp->irq_requested = 0; | ||
44 | } | ||
diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c index a08f8f981c11..b71c610fe5ae 100644 --- a/drivers/char/hvc_iseries.c +++ b/drivers/char/hvc_iseries.c | |||
@@ -200,6 +200,8 @@ done: | |||
200 | static struct hv_ops hvc_get_put_ops = { | 200 | static struct hv_ops hvc_get_put_ops = { |
201 | .get_chars = get_chars, | 201 | .get_chars = get_chars, |
202 | .put_chars = put_chars, | 202 | .put_chars = put_chars, |
203 | .notifier_add = notifier_add_irq, | ||
204 | .notifier_del = notifier_del_irq, | ||
203 | }; | 205 | }; |
204 | 206 | ||
205 | static int __devinit hvc_vio_probe(struct vio_dev *vdev, | 207 | static int __devinit hvc_vio_probe(struct vio_dev *vdev, |
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c index 79711aa4b41d..93f3840c1682 100644 --- a/drivers/char/hvc_vio.c +++ b/drivers/char/hvc_vio.c | |||
@@ -80,6 +80,8 @@ static int filtered_get_chars(uint32_t vtermno, char *buf, int count) | |||
80 | static struct hv_ops hvc_get_put_ops = { | 80 | static struct hv_ops hvc_get_put_ops = { |
81 | .get_chars = filtered_get_chars, | 81 | .get_chars = filtered_get_chars, |
82 | .put_chars = hvc_put_chars, | 82 | .put_chars = hvc_put_chars, |
83 | .notifier_add = notifier_add_irq, | ||
84 | .notifier_del = notifier_del_irq, | ||
83 | }; | 85 | }; |
84 | 86 | ||
85 | static int __devinit hvc_vio_probe(struct vio_dev *vdev, | 87 | static int __devinit hvc_vio_probe(struct vio_dev *vdev, |
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c index db2ae4216279..6b70aa66a587 100644 --- a/drivers/char/hvc_xen.c +++ b/drivers/char/hvc_xen.c | |||
@@ -100,6 +100,8 @@ static int read_console(uint32_t vtermno, char *buf, int len) | |||
100 | static struct hv_ops hvc_ops = { | 100 | static struct hv_ops hvc_ops = { |
101 | .get_chars = read_console, | 101 | .get_chars = read_console, |
102 | .put_chars = write_console, | 102 | .put_chars = write_console, |
103 | .notifier_add = notifier_add_irq, | ||
104 | .notifier_del = notifier_del_irq, | ||
103 | }; | 105 | }; |
104 | 106 | ||
105 | static int __init xen_init(void) | 107 | static int __init xen_init(void) |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index dc17fe3a88bc..d0f4eb6fdb7f 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -46,6 +46,9 @@ static char *in, *inbuf; | |||
46 | /* The operations for our console. */ | 46 | /* The operations for our console. */ |
47 | static struct hv_ops virtio_cons; | 47 | static struct hv_ops virtio_cons; |
48 | 48 | ||
49 | /* The hvc device */ | ||
50 | static struct hvc_struct *hvc; | ||
51 | |||
49 | /*D:310 The put_chars() callback is pretty straightforward. | 52 | /*D:310 The put_chars() callback is pretty straightforward. |
50 | * | 53 | * |
51 | * We turn the characters into a scatter-gather list, add it to the output | 54 | * We turn the characters into a scatter-gather list, add it to the output |
@@ -134,6 +137,27 @@ int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int)) | |||
134 | return hvc_instantiate(0, 0, &virtio_cons); | 137 | return hvc_instantiate(0, 0, &virtio_cons); |
135 | } | 138 | } |
136 | 139 | ||
140 | /* | ||
141 | * we support only one console, the hvc struct is a global var | ||
142 | * There is no need to do anything | ||
143 | */ | ||
144 | static int notifier_add_vio(struct hvc_struct *hp, int data) | ||
145 | { | ||
146 | hp->irq_requested = 1; | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static void notifier_del_vio(struct hvc_struct *hp, int data) | ||
151 | { | ||
152 | hp->irq_requested = 0; | ||
153 | } | ||
154 | |||
155 | static void hvc_handle_input(struct virtqueue *vq) | ||
156 | { | ||
157 | if (hvc_poll(hvc)) | ||
158 | hvc_kick(); | ||
159 | } | ||
160 | |||
137 | /*D:370 Once we're further in boot, we get probed like any other virtio device. | 161 | /*D:370 Once we're further in boot, we get probed like any other virtio device. |
138 | * At this stage we set up the output virtqueue. | 162 | * At this stage we set up the output virtqueue. |
139 | * | 163 | * |
@@ -144,7 +168,6 @@ int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int)) | |||
144 | static int __devinit virtcons_probe(struct virtio_device *dev) | 168 | static int __devinit virtcons_probe(struct virtio_device *dev) |
145 | { | 169 | { |
146 | int err; | 170 | int err; |
147 | struct hvc_struct *hvc; | ||
148 | 171 | ||
149 | vdev = dev; | 172 | vdev = dev; |
150 | 173 | ||
@@ -158,7 +181,7 @@ static int __devinit virtcons_probe(struct virtio_device *dev) | |||
158 | /* Find the input queue. */ | 181 | /* Find the input queue. */ |
159 | /* FIXME: This is why we want to wean off hvc: we do nothing | 182 | /* FIXME: This is why we want to wean off hvc: we do nothing |
160 | * when input comes in. */ | 183 | * when input comes in. */ |
161 | in_vq = vdev->config->find_vq(vdev, 0, NULL); | 184 | in_vq = vdev->config->find_vq(vdev, 0, hvc_handle_input); |
162 | if (IS_ERR(in_vq)) { | 185 | if (IS_ERR(in_vq)) { |
163 | err = PTR_ERR(in_vq); | 186 | err = PTR_ERR(in_vq); |
164 | goto free; | 187 | goto free; |
@@ -173,15 +196,18 @@ static int __devinit virtcons_probe(struct virtio_device *dev) | |||
173 | /* Start using the new console output. */ | 196 | /* Start using the new console output. */ |
174 | virtio_cons.get_chars = get_chars; | 197 | virtio_cons.get_chars = get_chars; |
175 | virtio_cons.put_chars = put_chars; | 198 | virtio_cons.put_chars = put_chars; |
199 | virtio_cons.notifier_add = notifier_add_vio; | ||
200 | virtio_cons.notifier_del = notifier_del_vio; | ||
176 | 201 | ||
177 | /* The first argument of hvc_alloc() is the virtual console number, so | 202 | /* The first argument of hvc_alloc() is the virtual console number, so |
178 | * we use zero. The second argument is the interrupt number; we | 203 | * we use zero. The second argument is the parameter for the |
179 | * currently leave this as zero: it would be better not to use the | 204 | * notification mechanism (like irq number). We currently leave this |
180 | * hvc mechanism and fix this (FIXME!). | 205 | * as zero, virtqueues have implicit notifications. |
181 | * | 206 | * |
182 | * The third argument is a "struct hv_ops" containing the put_chars() | 207 | * The third argument is a "struct hv_ops" containing the put_chars() |
183 | * and get_chars() pointers. The final argument is the output buffer | 208 | * get_chars(), notifier_add() and notifier_del() pointers. |
184 | * size: we can do any size, so we put PAGE_SIZE here. */ | 209 | * The final argument is the output buffer size: we can do any size, |
210 | * so we put PAGE_SIZE here. */ | ||
185 | hvc = hvc_alloc(0, 0, &virtio_cons, PAGE_SIZE); | 211 | hvc = hvc_alloc(0, 0, &virtio_cons, PAGE_SIZE); |
186 | if (IS_ERR(hvc)) { | 212 | if (IS_ERR(hvc)) { |
187 | err = PTR_ERR(hvc); | 213 | err = PTR_ERR(hvc); |
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index 1a8de57289eb..37344aaee22f 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c | |||
@@ -98,16 +98,20 @@ static u32 lg_get_features(struct virtio_device *vdev) | |||
98 | return features; | 98 | return features; |
99 | } | 99 | } |
100 | 100 | ||
101 | static void lg_set_features(struct virtio_device *vdev, u32 features) | 101 | static void lg_finalize_features(struct virtio_device *vdev) |
102 | { | 102 | { |
103 | unsigned int i; | 103 | unsigned int i, bits; |
104 | struct lguest_device_desc *desc = to_lgdev(vdev)->desc; | 104 | struct lguest_device_desc *desc = to_lgdev(vdev)->desc; |
105 | /* Second half of bitmap is features we accept. */ | 105 | /* Second half of bitmap is features we accept. */ |
106 | u8 *out_features = lg_features(desc) + desc->feature_len; | 106 | u8 *out_features = lg_features(desc) + desc->feature_len; |
107 | 107 | ||
108 | /* Give virtio_ring a chance to accept features. */ | ||
109 | vring_transport_features(vdev); | ||
110 | |||
108 | memset(out_features, 0, desc->feature_len); | 111 | memset(out_features, 0, desc->feature_len); |
109 | for (i = 0; i < min(desc->feature_len * 8, 32); i++) { | 112 | bits = min_t(unsigned, desc->feature_len, sizeof(vdev->features)) * 8; |
110 | if (features & (1 << i)) | 113 | for (i = 0; i < bits; i++) { |
114 | if (test_bit(i, vdev->features)) | ||
111 | out_features[i / 8] |= (1 << (i % 8)); | 115 | out_features[i / 8] |= (1 << (i % 8)); |
112 | } | 116 | } |
113 | } | 117 | } |
@@ -297,7 +301,7 @@ static void lg_del_vq(struct virtqueue *vq) | |||
297 | /* The ops structure which hooks everything together. */ | 301 | /* The ops structure which hooks everything together. */ |
298 | static struct virtio_config_ops lguest_config_ops = { | 302 | static struct virtio_config_ops lguest_config_ops = { |
299 | .get_features = lg_get_features, | 303 | .get_features = lg_get_features, |
300 | .set_features = lg_set_features, | 304 | .finalize_features = lg_finalize_features, |
301 | .get = lg_get, | 305 | .get = lg_get, |
302 | .set = lg_set, | 306 | .set = lg_set, |
303 | .get_status = lg_get_status, | 307 | .get_status = lg_get_status, |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index c28d7cb2035b..0196a0df9021 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -19,6 +19,7 @@ | |||
19 | //#define DEBUG | 19 | //#define DEBUG |
20 | #include <linux/netdevice.h> | 20 | #include <linux/netdevice.h> |
21 | #include <linux/etherdevice.h> | 21 | #include <linux/etherdevice.h> |
22 | #include <linux/ethtool.h> | ||
22 | #include <linux/module.h> | 23 | #include <linux/module.h> |
23 | #include <linux/virtio.h> | 24 | #include <linux/virtio.h> |
24 | #include <linux/virtio_net.h> | 25 | #include <linux/virtio_net.h> |
@@ -54,9 +55,15 @@ struct virtnet_info | |||
54 | struct tasklet_struct tasklet; | 55 | struct tasklet_struct tasklet; |
55 | bool free_in_tasklet; | 56 | bool free_in_tasklet; |
56 | 57 | ||
58 | /* I like... big packets and I cannot lie! */ | ||
59 | bool big_packets; | ||
60 | |||
57 | /* Receive & send queues. */ | 61 | /* Receive & send queues. */ |
58 | struct sk_buff_head recv; | 62 | struct sk_buff_head recv; |
59 | struct sk_buff_head send; | 63 | struct sk_buff_head send; |
64 | |||
65 | /* Chain pages by the private ptr. */ | ||
66 | struct page *pages; | ||
60 | }; | 67 | }; |
61 | 68 | ||
62 | static inline struct virtio_net_hdr *skb_vnet_hdr(struct sk_buff *skb) | 69 | static inline struct virtio_net_hdr *skb_vnet_hdr(struct sk_buff *skb) |
@@ -69,6 +76,23 @@ static inline void vnet_hdr_to_sg(struct scatterlist *sg, struct sk_buff *skb) | |||
69 | sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr)); | 76 | sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr)); |
70 | } | 77 | } |
71 | 78 | ||
79 | static void give_a_page(struct virtnet_info *vi, struct page *page) | ||
80 | { | ||
81 | page->private = (unsigned long)vi->pages; | ||
82 | vi->pages = page; | ||
83 | } | ||
84 | |||
85 | static struct page *get_a_page(struct virtnet_info *vi, gfp_t gfp_mask) | ||
86 | { | ||
87 | struct page *p = vi->pages; | ||
88 | |||
89 | if (p) | ||
90 | vi->pages = (struct page *)p->private; | ||
91 | else | ||
92 | p = alloc_page(gfp_mask); | ||
93 | return p; | ||
94 | } | ||
95 | |||
72 | static void skb_xmit_done(struct virtqueue *svq) | 96 | static void skb_xmit_done(struct virtqueue *svq) |
73 | { | 97 | { |
74 | struct virtnet_info *vi = svq->vdev->priv; | 98 | struct virtnet_info *vi = svq->vdev->priv; |
@@ -88,6 +112,7 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, | |||
88 | unsigned len) | 112 | unsigned len) |
89 | { | 113 | { |
90 | struct virtio_net_hdr *hdr = skb_vnet_hdr(skb); | 114 | struct virtio_net_hdr *hdr = skb_vnet_hdr(skb); |
115 | int err; | ||
91 | 116 | ||
92 | if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) { | 117 | if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) { |
93 | pr_debug("%s: short packet %i\n", dev->name, len); | 118 | pr_debug("%s: short packet %i\n", dev->name, len); |
@@ -95,10 +120,23 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, | |||
95 | goto drop; | 120 | goto drop; |
96 | } | 121 | } |
97 | len -= sizeof(struct virtio_net_hdr); | 122 | len -= sizeof(struct virtio_net_hdr); |
98 | BUG_ON(len > MAX_PACKET_LEN); | ||
99 | 123 | ||
100 | skb_trim(skb, len); | 124 | if (len <= MAX_PACKET_LEN) { |
125 | unsigned int i; | ||
101 | 126 | ||
127 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | ||
128 | give_a_page(dev->priv, skb_shinfo(skb)->frags[i].page); | ||
129 | skb->data_len = 0; | ||
130 | skb_shinfo(skb)->nr_frags = 0; | ||
131 | } | ||
132 | |||
133 | err = pskb_trim(skb, len); | ||
134 | if (err) { | ||
135 | pr_debug("%s: pskb_trim failed %i %d\n", dev->name, len, err); | ||
136 | dev->stats.rx_dropped++; | ||
137 | goto drop; | ||
138 | } | ||
139 | skb->truesize += skb->data_len; | ||
102 | dev->stats.rx_bytes += skb->len; | 140 | dev->stats.rx_bytes += skb->len; |
103 | dev->stats.rx_packets++; | 141 | dev->stats.rx_packets++; |
104 | 142 | ||
@@ -160,7 +198,7 @@ static void try_fill_recv(struct virtnet_info *vi) | |||
160 | { | 198 | { |
161 | struct sk_buff *skb; | 199 | struct sk_buff *skb; |
162 | struct scatterlist sg[2+MAX_SKB_FRAGS]; | 200 | struct scatterlist sg[2+MAX_SKB_FRAGS]; |
163 | int num, err; | 201 | int num, err, i; |
164 | 202 | ||
165 | sg_init_table(sg, 2+MAX_SKB_FRAGS); | 203 | sg_init_table(sg, 2+MAX_SKB_FRAGS); |
166 | for (;;) { | 204 | for (;;) { |
@@ -170,6 +208,24 @@ static void try_fill_recv(struct virtnet_info *vi) | |||
170 | 208 | ||
171 | skb_put(skb, MAX_PACKET_LEN); | 209 | skb_put(skb, MAX_PACKET_LEN); |
172 | vnet_hdr_to_sg(sg, skb); | 210 | vnet_hdr_to_sg(sg, skb); |
211 | |||
212 | if (vi->big_packets) { | ||
213 | for (i = 0; i < MAX_SKB_FRAGS; i++) { | ||
214 | skb_frag_t *f = &skb_shinfo(skb)->frags[i]; | ||
215 | f->page = get_a_page(vi, GFP_ATOMIC); | ||
216 | if (!f->page) | ||
217 | break; | ||
218 | |||
219 | f->page_offset = 0; | ||
220 | f->size = PAGE_SIZE; | ||
221 | |||
222 | skb->data_len += PAGE_SIZE; | ||
223 | skb->len += PAGE_SIZE; | ||
224 | |||
225 | skb_shinfo(skb)->nr_frags++; | ||
226 | } | ||
227 | } | ||
228 | |||
173 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; | 229 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; |
174 | skb_queue_head(&vi->recv, skb); | 230 | skb_queue_head(&vi->recv, skb); |
175 | 231 | ||
@@ -335,16 +391,11 @@ again: | |||
335 | free_old_xmit_skbs(vi); | 391 | free_old_xmit_skbs(vi); |
336 | 392 | ||
337 | /* If we has a buffer left over from last time, send it now. */ | 393 | /* If we has a buffer left over from last time, send it now. */ |
338 | if (unlikely(vi->last_xmit_skb)) { | 394 | if (unlikely(vi->last_xmit_skb) && |
339 | if (xmit_skb(vi, vi->last_xmit_skb) != 0) { | 395 | xmit_skb(vi, vi->last_xmit_skb) != 0) |
340 | /* Drop this skb: we only queue one. */ | 396 | goto stop_queue; |
341 | vi->dev->stats.tx_dropped++; | 397 | |
342 | kfree_skb(skb); | 398 | vi->last_xmit_skb = NULL; |
343 | skb = NULL; | ||
344 | goto stop_queue; | ||
345 | } | ||
346 | vi->last_xmit_skb = NULL; | ||
347 | } | ||
348 | 399 | ||
349 | /* Put new one in send queue and do transmit */ | 400 | /* Put new one in send queue and do transmit */ |
350 | if (likely(skb)) { | 401 | if (likely(skb)) { |
@@ -370,6 +421,11 @@ stop_queue: | |||
370 | netif_start_queue(dev); | 421 | netif_start_queue(dev); |
371 | goto again; | 422 | goto again; |
372 | } | 423 | } |
424 | if (skb) { | ||
425 | /* Drop this skb: we only queue one. */ | ||
426 | vi->dev->stats.tx_dropped++; | ||
427 | kfree_skb(skb); | ||
428 | } | ||
373 | goto done; | 429 | goto done; |
374 | } | 430 | } |
375 | 431 | ||
@@ -408,6 +464,22 @@ static int virtnet_close(struct net_device *dev) | |||
408 | return 0; | 464 | return 0; |
409 | } | 465 | } |
410 | 466 | ||
467 | static int virtnet_set_tx_csum(struct net_device *dev, u32 data) | ||
468 | { | ||
469 | struct virtnet_info *vi = netdev_priv(dev); | ||
470 | struct virtio_device *vdev = vi->vdev; | ||
471 | |||
472 | if (data && !virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) | ||
473 | return -ENOSYS; | ||
474 | |||
475 | return ethtool_op_set_tx_hw_csum(dev, data); | ||
476 | } | ||
477 | |||
478 | static struct ethtool_ops virtnet_ethtool_ops = { | ||
479 | .set_tx_csum = virtnet_set_tx_csum, | ||
480 | .set_sg = ethtool_op_set_sg, | ||
481 | }; | ||
482 | |||
411 | static int virtnet_probe(struct virtio_device *vdev) | 483 | static int virtnet_probe(struct virtio_device *vdev) |
412 | { | 484 | { |
413 | int err; | 485 | int err; |
@@ -427,6 +499,7 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
427 | #ifdef CONFIG_NET_POLL_CONTROLLER | 499 | #ifdef CONFIG_NET_POLL_CONTROLLER |
428 | dev->poll_controller = virtnet_netpoll; | 500 | dev->poll_controller = virtnet_netpoll; |
429 | #endif | 501 | #endif |
502 | SET_ETHTOOL_OPS(dev, &virtnet_ethtool_ops); | ||
430 | SET_NETDEV_DEV(dev, &vdev->dev); | 503 | SET_NETDEV_DEV(dev, &vdev->dev); |
431 | 504 | ||
432 | /* Do we support "hardware" checksums? */ | 505 | /* Do we support "hardware" checksums? */ |
@@ -462,11 +535,18 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
462 | vi->dev = dev; | 535 | vi->dev = dev; |
463 | vi->vdev = vdev; | 536 | vi->vdev = vdev; |
464 | vdev->priv = vi; | 537 | vdev->priv = vi; |
538 | vi->pages = NULL; | ||
465 | 539 | ||
466 | /* If they give us a callback when all buffers are done, we don't need | 540 | /* If they give us a callback when all buffers are done, we don't need |
467 | * the timer. */ | 541 | * the timer. */ |
468 | vi->free_in_tasklet = virtio_has_feature(vdev,VIRTIO_F_NOTIFY_ON_EMPTY); | 542 | vi->free_in_tasklet = virtio_has_feature(vdev,VIRTIO_F_NOTIFY_ON_EMPTY); |
469 | 543 | ||
544 | /* If we can receive ANY GSO packets, we must allocate large ones. */ | ||
545 | if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) | ||
546 | || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) | ||
547 | || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN)) | ||
548 | vi->big_packets = true; | ||
549 | |||
470 | /* We expect two virtqueues, receive then send. */ | 550 | /* We expect two virtqueues, receive then send. */ |
471 | vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); | 551 | vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); |
472 | if (IS_ERR(vi->rvq)) { | 552 | if (IS_ERR(vi->rvq)) { |
@@ -541,6 +621,10 @@ static void virtnet_remove(struct virtio_device *vdev) | |||
541 | vdev->config->del_vq(vi->svq); | 621 | vdev->config->del_vq(vi->svq); |
542 | vdev->config->del_vq(vi->rvq); | 622 | vdev->config->del_vq(vi->rvq); |
543 | unregister_netdev(vi->dev); | 623 | unregister_netdev(vi->dev); |
624 | |||
625 | while (vi->pages) | ||
626 | __free_pages(get_a_page(vi, GFP_KERNEL), 0); | ||
627 | |||
544 | free_netdev(vi->dev); | 628 | free_netdev(vi->dev); |
545 | } | 629 | } |
546 | 630 | ||
@@ -553,7 +637,9 @@ static unsigned int features[] = { | |||
553 | VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, | 637 | VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, |
554 | VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, | 638 | VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, |
555 | VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, | 639 | VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, |
556 | VIRTIO_NET_F_HOST_ECN, VIRTIO_F_NOTIFY_ON_EMPTY, | 640 | VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, |
641 | VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */ | ||
642 | VIRTIO_F_NOTIFY_ON_EMPTY, | ||
557 | }; | 643 | }; |
558 | 644 | ||
559 | static struct virtio_driver virtio_net = { | 645 | static struct virtio_driver virtio_net = { |
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index 5ab34340919b..79954bd6bfa5 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/virtio.h> | 16 | #include <linux/virtio.h> |
17 | #include <linux/virtio_config.h> | 17 | #include <linux/virtio_config.h> |
18 | #include <linux/virtio_console.h> | ||
18 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
19 | #include <linux/virtio_ring.h> | 20 | #include <linux/virtio_ring.h> |
20 | #include <linux/pfn.h> | 21 | #include <linux/pfn.h> |
@@ -87,16 +88,20 @@ static u32 kvm_get_features(struct virtio_device *vdev) | |||
87 | return features; | 88 | return features; |
88 | } | 89 | } |
89 | 90 | ||
90 | static void kvm_set_features(struct virtio_device *vdev, u32 features) | 91 | static void kvm_finalize_features(struct virtio_device *vdev) |
91 | { | 92 | { |
92 | unsigned int i; | 93 | unsigned int i, bits; |
93 | struct kvm_device_desc *desc = to_kvmdev(vdev)->desc; | 94 | struct kvm_device_desc *desc = to_kvmdev(vdev)->desc; |
94 | /* Second half of bitmap is features we accept. */ | 95 | /* Second half of bitmap is features we accept. */ |
95 | u8 *out_features = kvm_vq_features(desc) + desc->feature_len; | 96 | u8 *out_features = kvm_vq_features(desc) + desc->feature_len; |
96 | 97 | ||
98 | /* Give virtio_ring a chance to accept features. */ | ||
99 | vring_transport_features(vdev); | ||
100 | |||
97 | memset(out_features, 0, desc->feature_len); | 101 | memset(out_features, 0, desc->feature_len); |
98 | for (i = 0; i < min(desc->feature_len * 8, 32); i++) { | 102 | bits = min_t(unsigned, desc->feature_len, sizeof(vdev->features)) * 8; |
99 | if (features & (1 << i)) | 103 | for (i = 0; i < bits; i++) { |
104 | if (test_bit(i, vdev->features)) | ||
100 | out_features[i / 8] |= (1 << (i % 8)); | 105 | out_features[i / 8] |= (1 << (i % 8)); |
101 | } | 106 | } |
102 | } | 107 | } |
@@ -222,7 +227,7 @@ static void kvm_del_vq(struct virtqueue *vq) | |||
222 | */ | 227 | */ |
223 | static struct virtio_config_ops kvm_vq_configspace_ops = { | 228 | static struct virtio_config_ops kvm_vq_configspace_ops = { |
224 | .get_features = kvm_get_features, | 229 | .get_features = kvm_get_features, |
225 | .set_features = kvm_set_features, | 230 | .finalize_features = kvm_finalize_features, |
226 | .get = kvm_get, | 231 | .get = kvm_get, |
227 | .set = kvm_set, | 232 | .set = kvm_set, |
228 | .get_status = kvm_get_status, | 233 | .get_status = kvm_get_status, |
@@ -333,6 +338,25 @@ static int __init kvm_devices_init(void) | |||
333 | return 0; | 338 | return 0; |
334 | } | 339 | } |
335 | 340 | ||
341 | /* code for early console output with virtio_console */ | ||
342 | static __init int early_put_chars(u32 vtermno, const char *buf, int count) | ||
343 | { | ||
344 | char scratch[17]; | ||
345 | unsigned int len = count; | ||
346 | |||
347 | if (len > sizeof(scratch) - 1) | ||
348 | len = sizeof(scratch) - 1; | ||
349 | scratch[len] = '\0'; | ||
350 | memcpy(scratch, buf, len); | ||
351 | kvm_hypercall1(KVM_S390_VIRTIO_NOTIFY, __pa(scratch)); | ||
352 | return len; | ||
353 | } | ||
354 | |||
355 | void s390_virtio_console_init(void) | ||
356 | { | ||
357 | virtio_cons_early_init(early_put_chars); | ||
358 | } | ||
359 | |||
336 | /* | 360 | /* |
337 | * We do this after core stuff, but before the drivers. | 361 | * We do this after core stuff, but before the drivers. |
338 | */ | 362 | */ |
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 7084e7e146c0..5b78fd0aff0a 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c | |||
@@ -71,13 +71,6 @@ static int virtio_uevent(struct device *_dv, struct kobj_uevent_env *env) | |||
71 | dev->id.device, dev->id.vendor); | 71 | dev->id.device, dev->id.vendor); |
72 | } | 72 | } |
73 | 73 | ||
74 | static struct bus_type virtio_bus = { | ||
75 | .name = "virtio", | ||
76 | .match = virtio_dev_match, | ||
77 | .dev_attrs = virtio_dev_attrs, | ||
78 | .uevent = virtio_uevent, | ||
79 | }; | ||
80 | |||
81 | static void add_status(struct virtio_device *dev, unsigned status) | 74 | static void add_status(struct virtio_device *dev, unsigned status) |
82 | { | 75 | { |
83 | dev->config->set_status(dev, dev->config->get_status(dev) | status); | 76 | dev->config->set_status(dev, dev->config->get_status(dev) | status); |
@@ -120,12 +113,16 @@ static int virtio_dev_probe(struct device *_d) | |||
120 | set_bit(f, dev->features); | 113 | set_bit(f, dev->features); |
121 | } | 114 | } |
122 | 115 | ||
116 | /* Transport features always preserved to pass to finalize_features. */ | ||
117 | for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++) | ||
118 | if (device_features & (1 << i)) | ||
119 | set_bit(i, dev->features); | ||
120 | |||
123 | err = drv->probe(dev); | 121 | err = drv->probe(dev); |
124 | if (err) | 122 | if (err) |
125 | add_status(dev, VIRTIO_CONFIG_S_FAILED); | 123 | add_status(dev, VIRTIO_CONFIG_S_FAILED); |
126 | else { | 124 | else { |
127 | /* They should never have set feature bits beyond 32 */ | 125 | dev->config->finalize_features(dev); |
128 | dev->config->set_features(dev, dev->features[0]); | ||
129 | add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); | 126 | add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); |
130 | } | 127 | } |
131 | return err; | 128 | return err; |
@@ -147,13 +144,20 @@ static int virtio_dev_remove(struct device *_d) | |||
147 | return 0; | 144 | return 0; |
148 | } | 145 | } |
149 | 146 | ||
147 | static struct bus_type virtio_bus = { | ||
148 | .name = "virtio", | ||
149 | .match = virtio_dev_match, | ||
150 | .dev_attrs = virtio_dev_attrs, | ||
151 | .uevent = virtio_uevent, | ||
152 | .probe = virtio_dev_probe, | ||
153 | .remove = virtio_dev_remove, | ||
154 | }; | ||
155 | |||
150 | int register_virtio_driver(struct virtio_driver *driver) | 156 | int register_virtio_driver(struct virtio_driver *driver) |
151 | { | 157 | { |
152 | /* Catch this early. */ | 158 | /* Catch this early. */ |
153 | BUG_ON(driver->feature_table_size && !driver->feature_table); | 159 | BUG_ON(driver->feature_table_size && !driver->feature_table); |
154 | driver->driver.bus = &virtio_bus; | 160 | driver->driver.bus = &virtio_bus; |
155 | driver->driver.probe = virtio_dev_probe; | ||
156 | driver->driver.remove = virtio_dev_remove; | ||
157 | return driver_register(&driver->driver); | 161 | return driver_register(&driver->driver); |
158 | } | 162 | } |
159 | EXPORT_SYMBOL_GPL(register_virtio_driver); | 163 | EXPORT_SYMBOL_GPL(register_virtio_driver); |
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index eae7236310e4..c7dc37c7cce9 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -94,12 +94,17 @@ static u32 vp_get_features(struct virtio_device *vdev) | |||
94 | return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); | 94 | return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); |
95 | } | 95 | } |
96 | 96 | ||
97 | /* virtio config->set_features() implementation */ | 97 | /* virtio config->finalize_features() implementation */ |
98 | static void vp_set_features(struct virtio_device *vdev, u32 features) | 98 | static void vp_finalize_features(struct virtio_device *vdev) |
99 | { | 99 | { |
100 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 100 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
101 | 101 | ||
102 | iowrite32(features, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES); | 102 | /* Give virtio_ring a chance to accept features. */ |
103 | vring_transport_features(vdev); | ||
104 | |||
105 | /* We only support 32 feature bits. */ | ||
106 | BUILD_BUG_ON(ARRAY_SIZE(vdev->features) != 1); | ||
107 | iowrite32(vdev->features[0], vp_dev->ioaddr+VIRTIO_PCI_GUEST_FEATURES); | ||
103 | } | 108 | } |
104 | 109 | ||
105 | /* virtio config->get() implementation */ | 110 | /* virtio config->get() implementation */ |
@@ -297,7 +302,7 @@ static struct virtio_config_ops virtio_pci_config_ops = { | |||
297 | .find_vq = vp_find_vq, | 302 | .find_vq = vp_find_vq, |
298 | .del_vq = vp_del_vq, | 303 | .del_vq = vp_del_vq, |
299 | .get_features = vp_get_features, | 304 | .get_features = vp_get_features, |
300 | .set_features = vp_set_features, | 305 | .finalize_features = vp_finalize_features, |
301 | }; | 306 | }; |
302 | 307 | ||
303 | /* the PCI probing function */ | 308 | /* the PCI probing function */ |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 72bf8bc09014..6eb5303fed11 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -18,6 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | #include <linux/virtio.h> | 19 | #include <linux/virtio.h> |
20 | #include <linux/virtio_ring.h> | 20 | #include <linux/virtio_ring.h> |
21 | #include <linux/virtio_config.h> | ||
21 | #include <linux/device.h> | 22 | #include <linux/device.h> |
22 | 23 | ||
23 | #ifdef DEBUG | 24 | #ifdef DEBUG |
@@ -87,8 +88,11 @@ static int vring_add_buf(struct virtqueue *_vq, | |||
87 | if (vq->num_free < out + in) { | 88 | if (vq->num_free < out + in) { |
88 | pr_debug("Can't add buf len %i - avail = %i\n", | 89 | pr_debug("Can't add buf len %i - avail = %i\n", |
89 | out + in, vq->num_free); | 90 | out + in, vq->num_free); |
90 | /* We notify *even if* VRING_USED_F_NO_NOTIFY is set here. */ | 91 | /* FIXME: for historical reasons, we force a notify here if |
91 | vq->notify(&vq->vq); | 92 | * there are outgoing parts to the buffer. Presumably the |
93 | * host should service the ring ASAP. */ | ||
94 | if (out) | ||
95 | vq->notify(&vq->vq); | ||
92 | END_USE(vq); | 96 | END_USE(vq); |
93 | return -ENOSPC; | 97 | return -ENOSPC; |
94 | } | 98 | } |
@@ -320,4 +324,19 @@ void vring_del_virtqueue(struct virtqueue *vq) | |||
320 | } | 324 | } |
321 | EXPORT_SYMBOL_GPL(vring_del_virtqueue); | 325 | EXPORT_SYMBOL_GPL(vring_del_virtqueue); |
322 | 326 | ||
327 | /* Manipulates transport-specific feature bits. */ | ||
328 | void vring_transport_features(struct virtio_device *vdev) | ||
329 | { | ||
330 | unsigned int i; | ||
331 | |||
332 | for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++) { | ||
333 | switch (i) { | ||
334 | default: | ||
335 | /* We don't understand this bit. */ | ||
336 | clear_bit(i, vdev->features); | ||
337 | } | ||
338 | } | ||
339 | } | ||
340 | EXPORT_SYMBOL_GPL(vring_transport_features); | ||
341 | |||
323 | MODULE_LICENSE("GPL"); | 342 | MODULE_LICENSE("GPL"); |
diff --git a/include/asm-s390/kvm_virtio.h b/include/asm-s390/kvm_virtio.h index 5c871a990c29..146100224def 100644 --- a/include/asm-s390/kvm_virtio.h +++ b/include/asm-s390/kvm_virtio.h | |||
@@ -50,4 +50,14 @@ struct kvm_vqconfig { | |||
50 | #define KVM_S390_VIRTIO_RESET 1 | 50 | #define KVM_S390_VIRTIO_RESET 1 |
51 | #define KVM_S390_VIRTIO_SET_STATUS 2 | 51 | #define KVM_S390_VIRTIO_SET_STATUS 2 |
52 | 52 | ||
53 | #ifdef __KERNEL__ | ||
54 | /* early virtio console setup */ | ||
55 | #ifdef CONFIG_VIRTIO_CONSOLE | ||
56 | extern void s390_virtio_console_init(void); | ||
57 | #else | ||
58 | static inline void s390_virtio_console_init(void) | ||
59 | { | ||
60 | } | ||
61 | #endif /* CONFIG_VIRTIO_CONSOLE */ | ||
62 | #endif /* __KERNEL__ */ | ||
53 | #endif | 63 | #endif |
diff --git a/include/linux/virtio_9p.h b/include/linux/virtio_9p.h index 8eff0b53910b..b3c4a60ceeb3 100644 --- a/include/linux/virtio_9p.h +++ b/include/linux/virtio_9p.h | |||
@@ -1,5 +1,7 @@ | |||
1 | #ifndef _LINUX_VIRTIO_9P_H | 1 | #ifndef _LINUX_VIRTIO_9P_H |
2 | #define _LINUX_VIRTIO_9P_H | 2 | #define _LINUX_VIRTIO_9P_H |
3 | /* This header is BSD licensed so anyone can use the definitions to implement | ||
4 | * compatible drivers/servers. */ | ||
3 | #include <linux/virtio_config.h> | 5 | #include <linux/virtio_config.h> |
4 | 6 | ||
5 | /* The ID for virtio console */ | 7 | /* The ID for virtio console */ |
diff --git a/include/linux/virtio_balloon.h b/include/linux/virtio_balloon.h index 979524ee75b7..c30c7bfbf39b 100644 --- a/include/linux/virtio_balloon.h +++ b/include/linux/virtio_balloon.h | |||
@@ -1,5 +1,7 @@ | |||
1 | #ifndef _LINUX_VIRTIO_BALLOON_H | 1 | #ifndef _LINUX_VIRTIO_BALLOON_H |
2 | #define _LINUX_VIRTIO_BALLOON_H | 2 | #define _LINUX_VIRTIO_BALLOON_H |
3 | /* This header is BSD licensed so anyone can use the definitions to implement | ||
4 | * compatible drivers/servers. */ | ||
3 | #include <linux/virtio_config.h> | 5 | #include <linux/virtio_config.h> |
4 | 6 | ||
5 | /* The ID for virtio_balloon */ | 7 | /* The ID for virtio_balloon */ |
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h index 5f79a5f9de79..c1aef85243bf 100644 --- a/include/linux/virtio_blk.h +++ b/include/linux/virtio_blk.h | |||
@@ -1,5 +1,7 @@ | |||
1 | #ifndef _LINUX_VIRTIO_BLK_H | 1 | #ifndef _LINUX_VIRTIO_BLK_H |
2 | #define _LINUX_VIRTIO_BLK_H | 2 | #define _LINUX_VIRTIO_BLK_H |
3 | /* This header is BSD licensed so anyone can use the definitions to implement | ||
4 | * compatible drivers/servers. */ | ||
3 | #include <linux/virtio_config.h> | 5 | #include <linux/virtio_config.h> |
4 | 6 | ||
5 | /* The ID for virtio_block */ | 7 | /* The ID for virtio_block */ |
@@ -11,6 +13,7 @@ | |||
11 | #define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */ | 13 | #define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */ |
12 | #define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */ | 14 | #define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */ |
13 | #define VIRTIO_BLK_F_RO 5 /* Disk is read-only */ | 15 | #define VIRTIO_BLK_F_RO 5 /* Disk is read-only */ |
16 | #define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/ | ||
14 | 17 | ||
15 | struct virtio_blk_config | 18 | struct virtio_blk_config |
16 | { | 19 | { |
@@ -26,6 +29,8 @@ struct virtio_blk_config | |||
26 | __u8 heads; | 29 | __u8 heads; |
27 | __u8 sectors; | 30 | __u8 sectors; |
28 | } geometry; | 31 | } geometry; |
32 | /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */ | ||
33 | __u32 blk_size; | ||
29 | } __attribute__((packed)); | 34 | } __attribute__((packed)); |
30 | 35 | ||
31 | /* These two define direction. */ | 36 | /* These two define direction. */ |
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index f364bbf63c34..bf8ec283b232 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h | |||
@@ -1,5 +1,8 @@ | |||
1 | #ifndef _LINUX_VIRTIO_CONFIG_H | 1 | #ifndef _LINUX_VIRTIO_CONFIG_H |
2 | #define _LINUX_VIRTIO_CONFIG_H | 2 | #define _LINUX_VIRTIO_CONFIG_H |
3 | /* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so | ||
4 | * anyone can use the definitions to implement compatible drivers/servers. */ | ||
5 | |||
3 | /* Virtio devices use a standardized configuration space to define their | 6 | /* Virtio devices use a standardized configuration space to define their |
4 | * features and pass configuration information, but each implementation can | 7 | * features and pass configuration information, but each implementation can |
5 | * store and access that space differently. */ | 8 | * store and access that space differently. */ |
@@ -15,6 +18,12 @@ | |||
15 | /* We've given up on this device. */ | 18 | /* We've given up on this device. */ |
16 | #define VIRTIO_CONFIG_S_FAILED 0x80 | 19 | #define VIRTIO_CONFIG_S_FAILED 0x80 |
17 | 20 | ||
21 | /* Some virtio feature bits (currently bits 28 through 31) are reserved for the | ||
22 | * transport being used (eg. virtio_ring), the rest are per-device feature | ||
23 | * bits. */ | ||
24 | #define VIRTIO_TRANSPORT_F_START 28 | ||
25 | #define VIRTIO_TRANSPORT_F_END 32 | ||
26 | |||
18 | /* Do we get callbacks when the ring is completely used, even if we've | 27 | /* Do we get callbacks when the ring is completely used, even if we've |
19 | * suppressed them? */ | 28 | * suppressed them? */ |
20 | #define VIRTIO_F_NOTIFY_ON_EMPTY 24 | 29 | #define VIRTIO_F_NOTIFY_ON_EMPTY 24 |
@@ -52,9 +61,10 @@ | |||
52 | * @get_features: get the array of feature bits for this device. | 61 | * @get_features: get the array of feature bits for this device. |
53 | * vdev: the virtio_device | 62 | * vdev: the virtio_device |
54 | * Returns the first 32 feature bits (all we currently need). | 63 | * Returns the first 32 feature bits (all we currently need). |
55 | * @set_features: confirm what device features we'll be using. | 64 | * @finalize_features: confirm what device features we'll be using. |
56 | * vdev: the virtio_device | 65 | * vdev: the virtio_device |
57 | * feature: the first 32 feature bits | 66 | * This gives the final feature bits for the device: it can change |
67 | * the dev->feature bits if it wants. | ||
58 | */ | 68 | */ |
59 | struct virtio_config_ops | 69 | struct virtio_config_ops |
60 | { | 70 | { |
@@ -70,7 +80,7 @@ struct virtio_config_ops | |||
70 | void (*callback)(struct virtqueue *)); | 80 | void (*callback)(struct virtqueue *)); |
71 | void (*del_vq)(struct virtqueue *vq); | 81 | void (*del_vq)(struct virtqueue *vq); |
72 | u32 (*get_features)(struct virtio_device *vdev); | 82 | u32 (*get_features)(struct virtio_device *vdev); |
73 | void (*set_features)(struct virtio_device *vdev, u32 features); | 83 | void (*finalize_features)(struct virtio_device *vdev); |
74 | }; | 84 | }; |
75 | 85 | ||
76 | /* If driver didn't advertise the feature, it will never appear. */ | 86 | /* If driver didn't advertise the feature, it will never appear. */ |
diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h index ed2d4ead7eb7..19a0da0dba41 100644 --- a/include/linux/virtio_console.h +++ b/include/linux/virtio_console.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _LINUX_VIRTIO_CONSOLE_H | 1 | #ifndef _LINUX_VIRTIO_CONSOLE_H |
2 | #define _LINUX_VIRTIO_CONSOLE_H | 2 | #define _LINUX_VIRTIO_CONSOLE_H |
3 | #include <linux/virtio_config.h> | 3 | #include <linux/virtio_config.h> |
4 | /* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so | ||
5 | * anyone can use the definitions to implement compatible drivers/servers. */ | ||
4 | 6 | ||
5 | /* The ID for virtio console */ | 7 | /* The ID for virtio console */ |
6 | #define VIRTIO_ID_CONSOLE 3 | 8 | #define VIRTIO_ID_CONSOLE 3 |
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index 38c0571820fb..5e33761b9b8a 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h | |||
@@ -1,5 +1,7 @@ | |||
1 | #ifndef _LINUX_VIRTIO_NET_H | 1 | #ifndef _LINUX_VIRTIO_NET_H |
2 | #define _LINUX_VIRTIO_NET_H | 2 | #define _LINUX_VIRTIO_NET_H |
3 | /* This header is BSD licensed so anyone can use the definitions to implement | ||
4 | * compatible drivers/servers. */ | ||
3 | #include <linux/virtio_config.h> | 5 | #include <linux/virtio_config.h> |
4 | 6 | ||
5 | /* The ID for virtio_net */ | 7 | /* The ID for virtio_net */ |
diff --git a/include/linux/virtio_pci.h b/include/linux/virtio_pci.h index b3151659cf49..cdef35742932 100644 --- a/include/linux/virtio_pci.h +++ b/include/linux/virtio_pci.h | |||
@@ -9,9 +9,8 @@ | |||
9 | * Authors: | 9 | * Authors: |
10 | * Anthony Liguori <aliguori@us.ibm.com> | 10 | * Anthony Liguori <aliguori@us.ibm.com> |
11 | * | 11 | * |
12 | * This work is licensed under the terms of the GNU GPL, version 2 or later. | 12 | * This header is BSD licensed so anyone can use the definitions to implement |
13 | * See the COPYING file in the top-level directory. | 13 | * compatible drivers/servers. |
14 | * | ||
15 | */ | 14 | */ |
16 | 15 | ||
17 | #ifndef _LINUX_VIRTIO_PCI_H | 16 | #ifndef _LINUX_VIRTIO_PCI_H |
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index abe481ed990e..c4a598fb3826 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h | |||
@@ -120,6 +120,8 @@ struct virtqueue *vring_new_virtqueue(unsigned int num, | |||
120 | void (*notify)(struct virtqueue *vq), | 120 | void (*notify)(struct virtqueue *vq), |
121 | void (*callback)(struct virtqueue *vq)); | 121 | void (*callback)(struct virtqueue *vq)); |
122 | void vring_del_virtqueue(struct virtqueue *vq); | 122 | void vring_del_virtqueue(struct virtqueue *vq); |
123 | /* Filter out transport-specific feature bits. */ | ||
124 | void vring_transport_features(struct virtio_device *vdev); | ||
123 | 125 | ||
124 | irqreturn_t vring_interrupt(int irq, void *_vq); | 126 | irqreturn_t vring_interrupt(int irq, void *_vq); |
125 | #endif /* __KERNEL__ */ | 127 | #endif /* __KERNEL__ */ |
diff --git a/include/linux/virtio_rng.h b/include/linux/virtio_rng.h index 331afb6c9f62..1a85dab8a940 100644 --- a/include/linux/virtio_rng.h +++ b/include/linux/virtio_rng.h | |||
@@ -1,5 +1,7 @@ | |||
1 | #ifndef _LINUX_VIRTIO_RNG_H | 1 | #ifndef _LINUX_VIRTIO_RNG_H |
2 | #define _LINUX_VIRTIO_RNG_H | 2 | #define _LINUX_VIRTIO_RNG_H |
3 | /* This header is BSD licensed so anyone can use the definitions to implement | ||
4 | * compatible drivers/servers. */ | ||
3 | #include <linux/virtio_config.h> | 5 | #include <linux/virtio_config.h> |
4 | 6 | ||
5 | /* The ID for virtio_rng */ | 7 | /* The ID for virtio_rng */ |