]> Git Repo - qemu.git/blob - hw/virtio-pci.c
eepro100: Simplified device instantiation
[qemu.git] / hw / virtio-pci.c
1 /*
2  * Virtio PCI Bindings
3  *
4  * Copyright IBM, Corp. 2007
5  * Copyright (c) 2009 CodeSourcery
6  *
7  * Authors:
8  *  Anthony Liguori   <[email protected]>
9  *  Paul Brook        <[email protected]>
10  *
11  * This work is licensed under the terms of the GNU GPL, version 2.  See
12  * the COPYING file in the top-level directory.
13  *
14  */
15
16 #include <inttypes.h>
17
18 #include "virtio.h"
19 #include "virtio-blk.h"
20 #include "virtio-net.h"
21 #include "pci.h"
22 #include "qemu-error.h"
23 #include "msix.h"
24 #include "net.h"
25 #include "block_int.h"
26 #include "loader.h"
27 #include "kvm.h"
28
29 /* from Linux's linux/virtio_pci.h */
30
31 /* A 32-bit r/o bitmask of the features supported by the host */
32 #define VIRTIO_PCI_HOST_FEATURES        0
33
34 /* A 32-bit r/w bitmask of features activated by the guest */
35 #define VIRTIO_PCI_GUEST_FEATURES       4
36
37 /* A 32-bit r/w PFN for the currently selected queue */
38 #define VIRTIO_PCI_QUEUE_PFN            8
39
40 /* A 16-bit r/o queue size for the currently selected queue */
41 #define VIRTIO_PCI_QUEUE_NUM            12
42
43 /* A 16-bit r/w queue selector */
44 #define VIRTIO_PCI_QUEUE_SEL            14
45
46 /* A 16-bit r/w queue notifier */
47 #define VIRTIO_PCI_QUEUE_NOTIFY         16
48
49 /* An 8-bit device status register.  */
50 #define VIRTIO_PCI_STATUS               18
51
52 /* An 8-bit r/o interrupt status register.  Reading the value will return the
53  * current contents of the ISR and will also clear it.  This is effectively
54  * a read-and-acknowledge. */
55 #define VIRTIO_PCI_ISR                  19
56
57 /* MSI-X registers: only enabled if MSI-X is enabled. */
58 /* A 16-bit vector for configuration changes. */
59 #define VIRTIO_MSI_CONFIG_VECTOR        20
60 /* A 16-bit vector for selected queue notifications. */
61 #define VIRTIO_MSI_QUEUE_VECTOR         22
62
63 /* Config space size */
64 #define VIRTIO_PCI_CONFIG_NOMSI         20
65 #define VIRTIO_PCI_CONFIG_MSI           24
66 #define VIRTIO_PCI_REGION_SIZE(dev)     (msix_present(dev) ? \
67                                          VIRTIO_PCI_CONFIG_MSI : \
68                                          VIRTIO_PCI_CONFIG_NOMSI)
69
70 /* The remaining space is defined by each driver as the per-driver
71  * configuration space */
72 #define VIRTIO_PCI_CONFIG(dev)          (msix_enabled(dev) ? \
73                                          VIRTIO_PCI_CONFIG_MSI : \
74                                          VIRTIO_PCI_CONFIG_NOMSI)
75
76 /* Virtio ABI version, if we increment this, we break the guest driver. */
77 #define VIRTIO_PCI_ABI_VERSION          0
78
79 /* How many bits to shift physical queue address written to QUEUE_PFN.
80  * 12 is historical, and due to x86 page size. */
81 #define VIRTIO_PCI_QUEUE_ADDR_SHIFT    12
82
83 /* We can catch some guest bugs inside here so we continue supporting older
84    guests. */
85 #define VIRTIO_PCI_BUG_BUS_MASTER       (1 << 0)
86
87 /* QEMU doesn't strictly need write barriers since everything runs in
88  * lock-step.  We'll leave the calls to wmb() in though to make it obvious for
89  * KVM or if kqemu gets SMP support.
90  */
91 #define wmb() do { } while (0)
92
93 /* PCI bindings.  */
94
95 typedef struct {
96     PCIDevice pci_dev;
97     VirtIODevice *vdev;
98     uint32_t bugs;
99     uint32_t addr;
100     uint32_t class_code;
101     uint32_t nvectors;
102     BlockConf block;
103     NICConf nic;
104     uint32_t host_features;
105     /* Max. number of ports we can have for a the virtio-serial device */
106     uint32_t max_virtserial_ports;
107 } VirtIOPCIProxy;
108
109 /* virtio device */
110
111 static void virtio_pci_notify(void *opaque, uint16_t vector)
112 {
113     VirtIOPCIProxy *proxy = opaque;
114     if (msix_enabled(&proxy->pci_dev))
115         msix_notify(&proxy->pci_dev, vector);
116     else
117         qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
118 }
119
120 static void virtio_pci_save_config(void * opaque, QEMUFile *f)
121 {
122     VirtIOPCIProxy *proxy = opaque;
123     pci_device_save(&proxy->pci_dev, f);
124     msix_save(&proxy->pci_dev, f);
125     if (msix_present(&proxy->pci_dev))
126         qemu_put_be16(f, proxy->vdev->config_vector);
127 }
128
129 static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f)
130 {
131     VirtIOPCIProxy *proxy = opaque;
132     if (msix_present(&proxy->pci_dev))
133         qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n));
134 }
135
136 static int virtio_pci_load_config(void * opaque, QEMUFile *f)
137 {
138     VirtIOPCIProxy *proxy = opaque;
139     int ret;
140     ret = pci_device_load(&proxy->pci_dev, f);
141     if (ret) {
142         return ret;
143     }
144     msix_load(&proxy->pci_dev, f);
145     if (msix_present(&proxy->pci_dev)) {
146         qemu_get_be16s(f, &proxy->vdev->config_vector);
147     } else {
148         proxy->vdev->config_vector = VIRTIO_NO_VECTOR;
149     }
150     if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
151         return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
152     }
153
154     /* Try to find out if the guest has bus master disabled, but is
155        in ready state. Then we have a buggy guest OS. */
156     if (!(proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
157         !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
158         proxy->bugs |= VIRTIO_PCI_BUG_BUS_MASTER;
159     }
160     return 0;
161 }
162
163 static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f)
164 {
165     VirtIOPCIProxy *proxy = opaque;
166     uint16_t vector;
167     if (msix_present(&proxy->pci_dev)) {
168         qemu_get_be16s(f, &vector);
169     } else {
170         vector = VIRTIO_NO_VECTOR;
171     }
172     virtio_queue_set_vector(proxy->vdev, n, vector);
173     if (vector != VIRTIO_NO_VECTOR) {
174         return msix_vector_use(&proxy->pci_dev, vector);
175     }
176     return 0;
177 }
178
179 static void virtio_pci_reset(DeviceState *d)
180 {
181     VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
182     virtio_reset(proxy->vdev);
183     msix_reset(&proxy->pci_dev);
184     proxy->bugs = 0;
185 }
186
187 static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
188 {
189     VirtIOPCIProxy *proxy = opaque;
190     VirtIODevice *vdev = proxy->vdev;
191     target_phys_addr_t pa;
192
193     switch (addr) {
194     case VIRTIO_PCI_GUEST_FEATURES:
195         /* Guest does not negotiate properly?  We have to assume nothing. */
196         if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
197             if (vdev->bad_features)
198                 val = proxy->host_features & vdev->bad_features(vdev);
199             else
200                 val = 0;
201         }
202         if (vdev->set_features)
203             vdev->set_features(vdev, val);
204         vdev->guest_features = val;
205         break;
206     case VIRTIO_PCI_QUEUE_PFN:
207         pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
208         if (pa == 0) {
209             virtio_reset(proxy->vdev);
210             msix_unuse_all_vectors(&proxy->pci_dev);
211         }
212         else
213             virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
214         break;
215     case VIRTIO_PCI_QUEUE_SEL:
216         if (val < VIRTIO_PCI_QUEUE_MAX)
217             vdev->queue_sel = val;
218         break;
219     case VIRTIO_PCI_QUEUE_NOTIFY:
220         virtio_queue_notify(vdev, val);
221         break;
222     case VIRTIO_PCI_STATUS:
223         virtio_set_status(vdev, val & 0xFF);
224         if (vdev->status == 0) {
225             virtio_reset(proxy->vdev);
226             msix_unuse_all_vectors(&proxy->pci_dev);
227         }
228
229         /* Linux before 2.6.34 sets the device as OK without enabling
230            the PCI device bus master bit. In this case we need to disable
231            some safety checks. */
232         if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
233             !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
234             proxy->bugs |= VIRTIO_PCI_BUG_BUS_MASTER;
235         }
236         break;
237     case VIRTIO_MSI_CONFIG_VECTOR:
238         msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
239         /* Make it possible for guest to discover an error took place. */
240         if (msix_vector_use(&proxy->pci_dev, val) < 0)
241             val = VIRTIO_NO_VECTOR;
242         vdev->config_vector = val;
243         break;
244     case VIRTIO_MSI_QUEUE_VECTOR:
245         msix_vector_unuse(&proxy->pci_dev,
246                           virtio_queue_vector(vdev, vdev->queue_sel));
247         /* Make it possible for guest to discover an error took place. */
248         if (msix_vector_use(&proxy->pci_dev, val) < 0)
249             val = VIRTIO_NO_VECTOR;
250         virtio_queue_set_vector(vdev, vdev->queue_sel, val);
251         break;
252     default:
253         fprintf(stderr, "%s: unexpected address 0x%x value 0x%x\n",
254                 __func__, addr, val);
255         break;
256     }
257 }
258
259 static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
260 {
261     VirtIODevice *vdev = proxy->vdev;
262     uint32_t ret = 0xFFFFFFFF;
263
264     switch (addr) {
265     case VIRTIO_PCI_HOST_FEATURES:
266         ret = proxy->host_features;
267         break;
268     case VIRTIO_PCI_GUEST_FEATURES:
269         ret = vdev->guest_features;
270         break;
271     case VIRTIO_PCI_QUEUE_PFN:
272         ret = virtio_queue_get_addr(vdev, vdev->queue_sel)
273               >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
274         break;
275     case VIRTIO_PCI_QUEUE_NUM:
276         ret = virtio_queue_get_num(vdev, vdev->queue_sel);
277         break;
278     case VIRTIO_PCI_QUEUE_SEL:
279         ret = vdev->queue_sel;
280         break;
281     case VIRTIO_PCI_STATUS:
282         ret = vdev->status;
283         break;
284     case VIRTIO_PCI_ISR:
285         /* reading from the ISR also clears it. */
286         ret = vdev->isr;
287         vdev->isr = 0;
288         qemu_set_irq(proxy->pci_dev.irq[0], 0);
289         break;
290     case VIRTIO_MSI_CONFIG_VECTOR:
291         ret = vdev->config_vector;
292         break;
293     case VIRTIO_MSI_QUEUE_VECTOR:
294         ret = virtio_queue_vector(vdev, vdev->queue_sel);
295         break;
296     default:
297         break;
298     }
299
300     return ret;
301 }
302
303 static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr)
304 {
305     VirtIOPCIProxy *proxy = opaque;
306     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
307     addr -= proxy->addr;
308     if (addr < config)
309         return virtio_ioport_read(proxy, addr);
310     addr -= config;
311     return virtio_config_readb(proxy->vdev, addr);
312 }
313
314 static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr)
315 {
316     VirtIOPCIProxy *proxy = opaque;
317     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
318     addr -= proxy->addr;
319     if (addr < config)
320         return virtio_ioport_read(proxy, addr);
321     addr -= config;
322     return virtio_config_readw(proxy->vdev, addr);
323 }
324
325 static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr)
326 {
327     VirtIOPCIProxy *proxy = opaque;
328     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
329     addr -= proxy->addr;
330     if (addr < config)
331         return virtio_ioport_read(proxy, addr);
332     addr -= config;
333     return virtio_config_readl(proxy->vdev, addr);
334 }
335
336 static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val)
337 {
338     VirtIOPCIProxy *proxy = opaque;
339     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
340     addr -= proxy->addr;
341     if (addr < config) {
342         virtio_ioport_write(proxy, addr, val);
343         return;
344     }
345     addr -= config;
346     virtio_config_writeb(proxy->vdev, addr, val);
347 }
348
349 static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val)
350 {
351     VirtIOPCIProxy *proxy = opaque;
352     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
353     addr -= proxy->addr;
354     if (addr < config) {
355         virtio_ioport_write(proxy, addr, val);
356         return;
357     }
358     addr -= config;
359     virtio_config_writew(proxy->vdev, addr, val);
360 }
361
362 static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
363 {
364     VirtIOPCIProxy *proxy = opaque;
365     uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
366     addr -= proxy->addr;
367     if (addr < config) {
368         virtio_ioport_write(proxy, addr, val);
369         return;
370     }
371     addr -= config;
372     virtio_config_writel(proxy->vdev, addr, val);
373 }
374
375 static void virtio_map(PCIDevice *pci_dev, int region_num,
376                        pcibus_t addr, pcibus_t size, int type)
377 {
378     VirtIOPCIProxy *proxy = container_of(pci_dev, VirtIOPCIProxy, pci_dev);
379     VirtIODevice *vdev = proxy->vdev;
380     unsigned config_len = VIRTIO_PCI_REGION_SIZE(pci_dev) + vdev->config_len;
381
382     proxy->addr = addr;
383
384     register_ioport_write(addr, config_len, 1, virtio_pci_config_writeb, proxy);
385     register_ioport_write(addr, config_len, 2, virtio_pci_config_writew, proxy);
386     register_ioport_write(addr, config_len, 4, virtio_pci_config_writel, proxy);
387     register_ioport_read(addr, config_len, 1, virtio_pci_config_readb, proxy);
388     register_ioport_read(addr, config_len, 2, virtio_pci_config_readw, proxy);
389     register_ioport_read(addr, config_len, 4, virtio_pci_config_readl, proxy);
390
391     if (vdev->config_len)
392         vdev->get_config(vdev, vdev->config);
393 }
394
395 static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
396                                 uint32_t val, int len)
397 {
398     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
399
400     if (PCI_COMMAND == address) {
401         if (!(val & PCI_COMMAND_MASTER)) {
402             if (!(proxy->bugs & VIRTIO_PCI_BUG_BUS_MASTER)) {
403                 virtio_set_status(proxy->vdev,
404                                   proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
405             }
406         }
407     }
408
409     pci_default_write_config(pci_dev, address, val, len);
410     msix_write_config(pci_dev, address, val, len);
411 }
412
413 static unsigned virtio_pci_get_features(void *opaque)
414 {
415     VirtIOPCIProxy *proxy = opaque;
416     return proxy->host_features;
417 }
418
419 static void virtio_pci_guest_notifier_read(void *opaque)
420 {
421     VirtQueue *vq = opaque;
422     EventNotifier *n = virtio_queue_get_guest_notifier(vq);
423     if (event_notifier_test_and_clear(n)) {
424         virtio_irq(vq);
425     }
426 }
427
428 static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
429 {
430     VirtIOPCIProxy *proxy = opaque;
431     VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
432     EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
433
434     if (assign) {
435         int r = event_notifier_init(notifier, 0);
436         if (r < 0) {
437             return r;
438         }
439         qemu_set_fd_handler(event_notifier_get_fd(notifier),
440                             virtio_pci_guest_notifier_read, NULL, vq);
441     } else {
442         qemu_set_fd_handler(event_notifier_get_fd(notifier),
443                             NULL, NULL, NULL);
444         event_notifier_cleanup(notifier);
445     }
446
447     return 0;
448 }
449
450 static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign)
451 {
452     VirtIOPCIProxy *proxy = opaque;
453     VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
454     EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
455     int r;
456     if (assign) {
457         r = event_notifier_init(notifier, 1);
458         if (r < 0) {
459             return r;
460         }
461         r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
462                                        proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
463                                        n, assign);
464         if (r < 0) {
465             event_notifier_cleanup(notifier);
466         }
467     } else {
468         r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
469                                        proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
470                                        n, assign);
471         if (r < 0) {
472             return r;
473         }
474         event_notifier_cleanup(notifier);
475     }
476     return r;
477 }
478
479 static const VirtIOBindings virtio_pci_bindings = {
480     .notify = virtio_pci_notify,
481     .save_config = virtio_pci_save_config,
482     .load_config = virtio_pci_load_config,
483     .save_queue = virtio_pci_save_queue,
484     .load_queue = virtio_pci_load_queue,
485     .get_features = virtio_pci_get_features,
486     .set_host_notifier = virtio_pci_set_host_notifier,
487     .set_guest_notifier = virtio_pci_set_guest_notifier,
488 };
489
490 static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
491                             uint16_t vendor, uint16_t device,
492                             uint16_t class_code, uint8_t pif)
493 {
494     uint8_t *config;
495     uint32_t size;
496
497     proxy->vdev = vdev;
498
499     config = proxy->pci_dev.config;
500     pci_config_set_vendor_id(config, vendor);
501     pci_config_set_device_id(config, device);
502
503     config[0x08] = VIRTIO_PCI_ABI_VERSION;
504
505     config[0x09] = pif;
506     pci_config_set_class(config, class_code);
507     config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;
508
509     config[0x2c] = vendor & 0xFF;
510     config[0x2d] = (vendor >> 8) & 0xFF;
511     config[0x2e] = vdev->device_id & 0xFF;
512     config[0x2f] = (vdev->device_id >> 8) & 0xFF;
513
514     config[0x3d] = 1;
515
516     if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0)) {
517         pci_register_bar(&proxy->pci_dev, 1,
518                          msix_bar_size(&proxy->pci_dev),
519                          PCI_BASE_ADDRESS_SPACE_MEMORY,
520                          msix_mmio_map);
521     } else
522         vdev->nvectors = 0;
523
524     proxy->pci_dev.config_write = virtio_write_config;
525
526     size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len;
527     if (size & (size-1))
528         size = 1 << qemu_fls(size);
529
530     pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO,
531                            virtio_map);
532
533     virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
534     proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
535     proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
536     proxy->host_features = vdev->get_features(vdev, proxy->host_features);
537 }
538
539 static int virtio_blk_init_pci(PCIDevice *pci_dev)
540 {
541     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
542     VirtIODevice *vdev;
543
544     if (proxy->class_code != PCI_CLASS_STORAGE_SCSI &&
545         proxy->class_code != PCI_CLASS_STORAGE_OTHER)
546         proxy->class_code = PCI_CLASS_STORAGE_SCSI;
547
548     if (!proxy->block.dinfo) {
549         error_report("virtio-blk-pci: drive property not set");
550         return -1;
551     }
552     vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block);
553     vdev->nvectors = proxy->nvectors;
554     virtio_init_pci(proxy, vdev,
555                     PCI_VENDOR_ID_REDHAT_QUMRANET,
556                     PCI_DEVICE_ID_VIRTIO_BLOCK,
557                     proxy->class_code, 0x00);
558     /* make the actual value visible */
559     proxy->nvectors = vdev->nvectors;
560     return 0;
561 }
562
563 static int virtio_exit_pci(PCIDevice *pci_dev)
564 {
565     return msix_uninit(pci_dev);
566 }
567
568 static int virtio_blk_exit_pci(PCIDevice *pci_dev)
569 {
570     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
571
572     drive_uninit(proxy->block.dinfo);
573     return virtio_exit_pci(pci_dev);
574 }
575
576 static int virtio_serial_init_pci(PCIDevice *pci_dev)
577 {
578     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
579     VirtIODevice *vdev;
580
581     if (proxy->class_code != PCI_CLASS_COMMUNICATION_OTHER &&
582         proxy->class_code != PCI_CLASS_DISPLAY_OTHER && /* qemu 0.10 */
583         proxy->class_code != PCI_CLASS_OTHERS)          /* qemu-kvm  */
584         proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER;
585
586     vdev = virtio_serial_init(&pci_dev->qdev, proxy->max_virtserial_ports);
587     if (!vdev) {
588         return -1;
589     }
590     vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
591                                         ? proxy->max_virtserial_ports + 1
592                                         : proxy->nvectors;
593     virtio_init_pci(proxy, vdev,
594                     PCI_VENDOR_ID_REDHAT_QUMRANET,
595                     PCI_DEVICE_ID_VIRTIO_CONSOLE,
596                     proxy->class_code, 0x00);
597     proxy->nvectors = vdev->nvectors;
598     return 0;
599 }
600
601 static int virtio_net_init_pci(PCIDevice *pci_dev)
602 {
603     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
604     VirtIODevice *vdev;
605
606     vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic);
607
608     vdev->nvectors = proxy->nvectors;
609     virtio_init_pci(proxy, vdev,
610                     PCI_VENDOR_ID_REDHAT_QUMRANET,
611                     PCI_DEVICE_ID_VIRTIO_NET,
612                     PCI_CLASS_NETWORK_ETHERNET,
613                     0x00);
614
615     /* make the actual value visible */
616     proxy->nvectors = vdev->nvectors;
617     return 0;
618 }
619
620 static int virtio_net_exit_pci(PCIDevice *pci_dev)
621 {
622     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
623
624     virtio_net_exit(proxy->vdev);
625     return virtio_exit_pci(pci_dev);
626 }
627
628 static int virtio_balloon_init_pci(PCIDevice *pci_dev)
629 {
630     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
631     VirtIODevice *vdev;
632
633     vdev = virtio_balloon_init(&pci_dev->qdev);
634     virtio_init_pci(proxy, vdev,
635                     PCI_VENDOR_ID_REDHAT_QUMRANET,
636                     PCI_DEVICE_ID_VIRTIO_BALLOON,
637                     PCI_CLASS_MEMORY_RAM,
638                     0x00);
639     return 0;
640 }
641
642 static PCIDeviceInfo virtio_info[] = {
643     {
644         .qdev.name = "virtio-blk-pci",
645         .qdev.size = sizeof(VirtIOPCIProxy),
646         .init      = virtio_blk_init_pci,
647         .exit      = virtio_blk_exit_pci,
648         .qdev.props = (Property[]) {
649             DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
650             DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
651             DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
652             DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
653             DEFINE_PROP_END_OF_LIST(),
654         },
655         .qdev.reset = virtio_pci_reset,
656     },{
657         .qdev.name  = "virtio-net-pci",
658         .qdev.size  = sizeof(VirtIOPCIProxy),
659         .init       = virtio_net_init_pci,
660         .exit       = virtio_net_exit_pci,
661         .romfile    = "pxe-virtio.bin",
662         .qdev.props = (Property[]) {
663             DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
664             DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
665             DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
666             DEFINE_PROP_END_OF_LIST(),
667         },
668         .qdev.reset = virtio_pci_reset,
669     },{
670         .qdev.name = "virtio-serial-pci",
671         .qdev.alias = "virtio-serial",
672         .qdev.size = sizeof(VirtIOPCIProxy),
673         .init      = virtio_serial_init_pci,
674         .exit      = virtio_exit_pci,
675         .qdev.props = (Property[]) {
676             DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
677                                DEV_NVECTORS_UNSPECIFIED),
678             DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
679             DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
680             DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, max_virtserial_ports,
681                                31),
682             DEFINE_PROP_END_OF_LIST(),
683         },
684         .qdev.reset = virtio_pci_reset,
685     },{
686         .qdev.name = "virtio-balloon-pci",
687         .qdev.size = sizeof(VirtIOPCIProxy),
688         .init      = virtio_balloon_init_pci,
689         .exit      = virtio_exit_pci,
690         .qdev.props = (Property[]) {
691             DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
692             DEFINE_PROP_END_OF_LIST(),
693         },
694         .qdev.reset = virtio_pci_reset,
695     },{
696         /* end of list */
697     }
698 };
699
700 static void virtio_pci_register_devices(void)
701 {
702     pci_qdev_register_many(virtio_info);
703 }
704
705 device_init(virtio_pci_register_devices)
This page took 0.06184 seconds and 4 git commands to generate.