first public release
[dpdk.git] / app / test / test_pci.c
1 /*-
2  *   BSD LICENSE
3  * 
4  *   Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  * 
7  *   Redistribution and use in source and binary forms, with or without 
8  *   modification, are permitted provided that the following conditions 
9  *   are met:
10  * 
11  *     * Redistributions of source code must retain the above copyright 
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright 
14  *       notice, this list of conditions and the following disclaimer in 
15  *       the documentation and/or other materials provided with the 
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its 
18  *       contributors may be used to endorse or promote products derived 
19  *       from this software without specific prior written permission.
20  * 
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  * 
33  *  version: DPDK.L.1.2.3-3
34  */
35
36 #include <stdio.h>
37 #include <string.h>
38 #include <stdint.h>
39 #include <sys/queue.h>
40
41 #include <cmdline_parse.h>
42
43 #include <rte_interrupts.h>
44 #include <rte_pci.h>
45
46 #include "test.h"
47
48 #define RTE_PCI_DEV_ID_DECL(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
49
50 #define TEST_BLACKLIST_NUM      0x100
51
52 /*
53  * PCI test
54  * ========
55  *
56  * - Register a driver with a ``devinit()`` function.
57  *
58  * - Dump all PCI devices.
59  *
60  * - Check that the ``devinit()`` function is called at least once.
61  */
62
63 int test_pci_run = 0; /* value checked by the multiprocess test */
64 static unsigned pci_dev_count;
65 static unsigned driver_registered = 0;
66 static struct rte_pci_addr blacklist[TEST_BLACKLIST_NUM];
67
68 static int my_driver_init(struct rte_pci_driver *dr,
69                           struct rte_pci_device *dev);
70
71 /*
72  * To test cases where RTE_PCI_DRV_NEED_IGB_UIO is set, and isn't set, two
73  * drivers are created (one with IGB devices, the other with IXGBE devices).
74  */
75
76 /* IXGBE NICS + e1000 used for Qemu */
77 #define RTE_LIBRTE_IXGBE_PMD 1
78 #undef RTE_LIBRTE_IGB_PMD
79 struct rte_pci_id my_driver_id[] = {
80
81 #include <rte_pci_dev_ids.h>
82
83 /* this device is the e1000 of qemu for testing */
84 {RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x100E)},
85
86 { .vendor_id = 0, /* sentinel */ },
87 };
88
89 struct rte_pci_id my_driver_id2[] = {
90
91 /* IGB NICS */
92 #undef RTE_LIBRTE_IXGBE_PMD
93 #define RTE_LIBRTE_IGB_PMD 1
94 #define RTE_PCI_DEV_USE_82575EB_COPPER
95 #include <rte_pci_dev_ids.h>
96
97 { .vendor_id = 0, /* sentinel */ },
98 };
99
100 struct rte_pci_driver my_driver = {
101         .name = "test_driver",
102         .devinit = my_driver_init,
103         .id_table = my_driver_id,
104         .drv_flags = RTE_PCI_DRV_NEED_IGB_UIO,
105 };
106
107 struct rte_pci_driver my_driver2 = {
108         .name = "test_driver2",
109         .devinit = my_driver_init,
110         .id_table = my_driver_id2,
111         .drv_flags = 0,
112 };
113
114 static int
115 my_driver_init(__attribute__((unused)) struct rte_pci_driver *dr,
116                struct rte_pci_device *dev)
117 {
118         printf("My driver init called in %s\n", dr->name);
119         printf("%x:%x:%x.%d", dev->addr.domain, dev->addr.bus,
120                dev->addr.devid, dev->addr.function);
121         printf(" - vendor:%x device:%x\n", dev->id.vendor_id, dev->id.device_id);
122
123         pci_dev_count ++;
124         return 0;
125 }
126
127 static void
128 blacklist_clear(void)
129 {
130         rte_eal_pci_set_blacklist(NULL, 0);
131 }
132
133
134
135 static void
136 blacklist_all_devices(void)
137 {
138         struct rte_pci_device *dev = NULL;
139         unsigned idx = 0;
140
141         memset(blacklist, 0, sizeof (blacklist));
142
143         TAILQ_FOREACH(dev, &device_list, next) {
144                 if (idx >= sizeof (blacklist) / sizeof (blacklist[0])) {
145                         printf("Error: too many devices to blacklist");
146                         break;
147                 }
148                 blacklist[idx] = dev->addr;
149                 ++idx;
150         }
151
152         rte_eal_pci_set_blacklist(blacklist, idx);
153         printf("%u devices blacklisted\n", idx);
154 }
155
156 int
157 test_pci(void)
158 {
159
160         printf("Dump all devices\n");
161         rte_eal_pci_dump();
162         if (driver_registered == 0) {
163                 rte_eal_pci_register(&my_driver);
164                 rte_eal_pci_register(&my_driver2);
165                 driver_registered = 1;
166         }
167
168         pci_dev_count = 0;
169         printf("Scan bus\n");
170         rte_eal_pci_probe();
171
172         if (pci_dev_count == 0) {
173                 printf("no device detected\n");
174                 return -1;
175         }
176
177         blacklist_all_devices();
178
179         pci_dev_count = 0;
180         printf("Scan bus with all devices blacklisted\n");
181         rte_eal_pci_probe();
182
183         blacklist_clear();
184
185         if (pci_dev_count != 0) {
186                 printf("not all devices are blacklisted\n");
187                 return -1;
188         }
189
190         test_pci_run = 1;
191         return 0;
192 }