]>
Commit | Line | Data |
---|---|---|
15b49bee YZ |
1 | PCI Express I/O Virtualization Howto |
2 | Copyright (C) 2009 Intel Corporation | |
3 | Yu Zhao <yu.zhao@intel.com> | |
4 | ||
5 | ||
6 | 1. Overview | |
7 | ||
8 | 1.1 What is SR-IOV | |
9 | ||
10 | Single Root I/O Virtualization (SR-IOV) is a PCI Express Extended | |
11 | capability which makes one physical device appear as multiple virtual | |
12 | devices. The physical device is referred to as Physical Function (PF) | |
13 | while the virtual devices are referred to as Virtual Functions (VF). | |
14 | Allocation of the VF can be dynamically controlled by the PF via | |
15 | registers encapsulated in the capability. By default, this feature is | |
16 | not enabled and the PF behaves as traditional PCIe device. Once it's | |
17 | turned on, each VF's PCI configuration space can be accessed by its own | |
18 | Bus, Device and Function Number (Routing ID). And each VF also has PCI | |
19 | Memory Space, which is used to map its register set. VF device driver | |
20 | operates on the register set so it can be functional and appear as a | |
21 | real existing PCI device. | |
22 | ||
23 | 2. User Guide | |
24 | ||
25 | 2.1 How can I enable SR-IOV capability | |
26 | ||
27 | The device driver (PF driver) will control the enabling and disabling | |
28 | of the capability via API provided by SR-IOV core. If the hardware | |
29 | has SR-IOV capability, loading its PF driver would enable it and all | |
30 | VFs associated with the PF. | |
31 | ||
32 | 2.2 How can I use the Virtual Functions | |
33 | ||
34 | The VF is treated as hot-plugged PCI devices in the kernel, so they | |
35 | should be able to work in the same way as real PCI devices. The VF | |
36 | requires device driver that is same as a normal PCI device's. | |
37 | ||
38 | 3. Developer Guide | |
39 | ||
40 | 3.1 SR-IOV API | |
41 | ||
42 | To enable SR-IOV capability: | |
43 | int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); | |
44 | 'nr_virtfn' is number of VFs to be enabled. | |
45 | ||
46 | To disable SR-IOV capability: | |
47 | void pci_disable_sriov(struct pci_dev *dev); | |
48 | ||
49 | To notify SR-IOV core of Virtual Function Migration: | |
50 | irqreturn_t pci_sriov_migration(struct pci_dev *dev); | |
51 | ||
52 | 3.2 Usage example | |
53 | ||
54 | Following piece of code illustrates the usage of the SR-IOV API. | |
55 | ||
56 | static int __devinit dev_probe(struct pci_dev *dev, const struct pci_device_id *id) | |
57 | { | |
58 | pci_enable_sriov(dev, NR_VIRTFN); | |
59 | ||
60 | ... | |
61 | ||
62 | return 0; | |
63 | } | |
64 | ||
65 | static void __devexit dev_remove(struct pci_dev *dev) | |
66 | { | |
67 | pci_disable_sriov(dev); | |
68 | ||
69 | ... | |
70 | } | |
71 | ||
72 | static int dev_suspend(struct pci_dev *dev, pm_message_t state) | |
73 | { | |
74 | ... | |
75 | ||
76 | return 0; | |
77 | } | |
78 | ||
79 | static int dev_resume(struct pci_dev *dev) | |
80 | { | |
81 | ... | |
82 | ||
83 | return 0; | |
84 | } | |
85 | ||
86 | static void dev_shutdown(struct pci_dev *dev) | |
87 | { | |
88 | ... | |
89 | } | |
90 | ||
91 | static struct pci_driver dev_driver = { | |
92 | .name = "SR-IOV Physical Function driver", | |
93 | .id_table = dev_id_table, | |
94 | .probe = dev_probe, | |
95 | .remove = __devexit_p(dev_remove), | |
96 | .suspend = dev_suspend, | |
97 | .resume = dev_resume, | |
98 | .shutdown = dev_shutdown, | |
99 | }; |