1 /**
2  * collectd - src/pcie_errors.c
3  *
4  * Copyright(c) 2018 Intel Corporation. All rights reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * Authors:
25  *   Kamil Wiatrowski <kamilx.wiatrowski@intel.com>
26  **/
27 
28 #define plugin_dispatch_notification plugin_dispatch_notification_pcie_test
29 
30 #include "pcie_errors.c" /* sic */
31 #include "testing.h"
32 
33 #define TEST_DOMAIN 1
34 #define TEST_BUS 5
35 #define TEST_DEVICE 0xc
36 #define TEST_FUNCTION 2
37 #define TEST_DEVICE_STR "0001:05:0c.2"
38 
39 #define G_BUFF_LEN 4
40 
41 static notification_t last_notif;
42 static char g_buff[G_BUFF_LEN];
43 
44 /* mock functions */
plugin_dispatch_notification_pcie_test(const notification_t * notif)45 int plugin_dispatch_notification_pcie_test(const notification_t *notif) {
46   last_notif = *notif;
47   return ENOTSUP;
48 }
49 
pread(int fd,void * buf,size_t count,off_t offset)50 ssize_t pread(__attribute__((unused)) int fd, void *buf, size_t count,
51               __attribute__((unused)) off_t offset) {
52   if (count == 0 || count > G_BUFF_LEN)
53     return -1;
54 
55   memcpy(buf, g_buff, count);
56   return count;
57 }
58 /* end mock functions */
59 
DEF_TEST(clear_dev_list)60 DEF_TEST(clear_dev_list) {
61   pcie_clear_list(NULL);
62 
63   llist_t *test_list = llist_create();
64   CHECK_NOT_NULL(test_list);
65 
66   pcie_device_t *dev = calloc(1, sizeof(*dev));
67   CHECK_NOT_NULL(dev);
68 
69   llentry_t *entry = llentry_create(NULL, dev);
70   CHECK_NOT_NULL(entry);
71 
72   llist_append(test_list, entry);
73 
74   for (llentry_t *e = llist_head(test_list); e != NULL; e = e->next) {
75     EXPECT_EQ_PTR(dev, e->value);
76   }
77 
78   pcie_clear_list(test_list);
79 
80   return 0;
81 }
82 
DEF_TEST(add_to_list)83 DEF_TEST(add_to_list) {
84   llist_t *test_list = llist_create();
85   CHECK_NOT_NULL(test_list);
86 
87   int ret = pcie_add_device(test_list, TEST_DOMAIN, TEST_BUS, TEST_DEVICE,
88                             TEST_FUNCTION);
89   EXPECT_EQ_INT(0, ret);
90 
91   llentry_t *e = llist_head(test_list);
92   CHECK_NOT_NULL(e);
93   OK(NULL == e->next);
94 
95   pcie_device_t *dev = e->value;
96   CHECK_NOT_NULL(dev);
97   EXPECT_EQ_INT(TEST_DOMAIN, dev->domain);
98   EXPECT_EQ_INT(TEST_BUS, dev->bus);
99   EXPECT_EQ_INT(TEST_DEVICE, dev->device);
100   EXPECT_EQ_INT(TEST_FUNCTION, dev->function);
101   EXPECT_EQ_INT(-1, dev->cap_exp);
102   EXPECT_EQ_INT(-1, dev->ecap_aer);
103 
104   pcie_clear_list(test_list);
105 
106   return 0;
107 }
108 
DEF_TEST(pcie_read)109 DEF_TEST(pcie_read) {
110   int ret;
111   pcie_device_t dev = {0};
112   uint32_t val = 0;
113   g_buff[0] = 4;
114   g_buff[1] = 3;
115   g_buff[2] = 2;
116   g_buff[3] = 1;
117 
118   ret = pcie_read(&dev, &val, 1, 0);
119   EXPECT_EQ_INT(0, ret);
120   EXPECT_EQ_INT(4, val);
121 
122   ret = pcie_read(&dev, &val, 2, 0);
123   EXPECT_EQ_INT(0, ret);
124   EXPECT_EQ_INT(0x304, val);
125 
126   ret = pcie_read(&dev, &val, 3, 0);
127   EXPECT_EQ_INT(0, ret);
128   EXPECT_EQ_INT(0x20304, val);
129 
130   ret = pcie_read(&dev, &val, 4, 0);
131   EXPECT_EQ_INT(0, ret);
132   EXPECT_EQ_INT(0x1020304, val);
133 
134   ret = pcie_read(&dev, &val, G_BUFF_LEN + 1, 0);
135   EXPECT_EQ_INT(-1, ret);
136 
137   pcie_fops.read = pcie_read;
138 
139   uint8_t val8 = pcie_read8(&dev, 0);
140   EXPECT_EQ_INT(4, val8);
141 
142   uint16_t val16 = pcie_read16(&dev, 0);
143   EXPECT_EQ_INT(0x304, val16);
144 
145   uint32_t val32 = pcie_read32(&dev, 0);
146   EXPECT_EQ_INT(0x1020304, val32);
147 
148   return 0;
149 }
150 
DEF_TEST(dispatch_notification)151 DEF_TEST(dispatch_notification) {
152   pcie_device_t dev = {0, TEST_DOMAIN, TEST_BUS, TEST_DEVICE, TEST_FUNCTION,
153                        0, 0,           0,        0,           0};
154   cdtime_t t = cdtime();
155   notification_t n = {
156       .severity = 1, .time = t, .plugin = "pcie_errors_test", .meta = NULL};
157 
158   pcie_dispatch_notification(&dev, &n, "test_type", "test_type_instance");
159   EXPECT_EQ_INT(1, last_notif.severity);
160   EXPECT_EQ_UINT64(t, last_notif.time);
161   EXPECT_EQ_STR("pcie_errors_test", last_notif.plugin);
162   OK(NULL == last_notif.meta);
163   EXPECT_EQ_STR(hostname_g, last_notif.host);
164   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
165   EXPECT_EQ_STR("test_type", last_notif.type);
166   EXPECT_EQ_STR("test_type_instance", last_notif.type_instance);
167 
168   return 0;
169 }
170 
DEF_TEST(access_config)171 DEF_TEST(access_config) {
172   pcie_config.use_sysfs = 0;
173   pcie_access_config();
174   EXPECT_EQ_PTR(pcie_list_devices_proc, pcie_fops.list_devices);
175   EXPECT_EQ_PTR(pcie_open_proc, pcie_fops.open);
176   EXPECT_EQ_PTR(pcie_close, pcie_fops.close);
177   EXPECT_EQ_PTR(pcie_read, pcie_fops.read);
178   EXPECT_EQ_STR(PCIE_DEFAULT_PROCDIR, pcie_config.access_dir);
179 
180   sstrncpy(pcie_config.access_dir, "Test", sizeof(pcie_config.access_dir));
181   pcie_access_config();
182   EXPECT_EQ_STR("Test", pcie_config.access_dir);
183 
184   pcie_config.use_sysfs = 1;
185   pcie_access_config();
186   EXPECT_EQ_PTR(pcie_list_devices_sysfs, pcie_fops.list_devices);
187   EXPECT_EQ_PTR(pcie_open_sysfs, pcie_fops.open);
188   EXPECT_EQ_PTR(pcie_close, pcie_fops.close);
189   EXPECT_EQ_PTR(pcie_read, pcie_fops.read);
190   EXPECT_EQ_STR("Test", pcie_config.access_dir);
191 
192   pcie_config.access_dir[0] = '\0';
193   pcie_access_config();
194   EXPECT_EQ_STR(PCIE_DEFAULT_SYSFSDIR, pcie_config.access_dir);
195 
196   return 0;
197 }
198 
DEF_TEST(plugin_config_fail)199 DEF_TEST(plugin_config_fail) {
200   oconfig_item_t test_cfg_parent = {"pcie_errors", NULL, 0, NULL, NULL, 0};
201   char value_buff[256] = "procs";
202   char key_buff[256] = "Sources";
203   oconfig_value_t test_cfg_value = {{value_buff}, OCONFIG_TYPE_STRING};
204   oconfig_item_t test_cfg = {
205       key_buff, &test_cfg_value, 1, &test_cfg_parent, NULL, 0};
206 
207   test_cfg_parent.children = &test_cfg;
208   test_cfg_parent.children_num = 1;
209 
210   int ret = pcie_plugin_config(&test_cfg_parent);
211   EXPECT_EQ_INT(-1, ret);
212 
213   sstrncpy(key_buff, "Source", sizeof(key_buff));
214   ret = pcie_plugin_config(&test_cfg_parent);
215   EXPECT_EQ_INT(-1, ret);
216 
217   sstrncpy(value_buff, "proc", sizeof(value_buff));
218   test_cfg_value.type = OCONFIG_TYPE_NUMBER;
219   ret = pcie_plugin_config(&test_cfg_parent);
220   EXPECT_EQ_INT(-1, ret);
221 
222   sstrncpy(key_buff, "AccessDir", sizeof(key_buff));
223   ret = pcie_plugin_config(&test_cfg_parent);
224   EXPECT_EQ_INT(-1, ret);
225 
226   return 0;
227 }
228 
DEF_TEST(plugin_config)229 DEF_TEST(plugin_config) {
230   oconfig_item_t test_cfg_parent = {"pcie_errors", NULL, 0, NULL, NULL, 0};
231   char value_buff[256] = "proc";
232   char key_buff[256] = "source";
233   oconfig_value_t test_cfg_value = {{value_buff}, OCONFIG_TYPE_STRING};
234   oconfig_item_t test_cfg = {
235       key_buff, &test_cfg_value, 1, &test_cfg_parent, NULL, 0};
236 
237   test_cfg_parent.children = &test_cfg;
238   test_cfg_parent.children_num = 1;
239 
240   pcie_config.use_sysfs = 1;
241   int ret = pcie_plugin_config(&test_cfg_parent);
242   EXPECT_EQ_INT(0, ret);
243   EXPECT_EQ_INT(0, pcie_config.use_sysfs);
244 
245   pcie_config.use_sysfs = 1;
246   sstrncpy(value_buff, "sysfs", sizeof(value_buff));
247   ret = pcie_plugin_config(&test_cfg_parent);
248   EXPECT_EQ_INT(0, ret);
249   EXPECT_EQ_INT(1, pcie_config.use_sysfs);
250 
251   sstrncpy(key_buff, "AccessDir", sizeof(key_buff));
252   sstrncpy(value_buff, "some/test/value", sizeof(value_buff));
253   ret = pcie_plugin_config(&test_cfg_parent);
254   EXPECT_EQ_INT(0, ret);
255   EXPECT_EQ_STR("some/test/value", pcie_config.access_dir);
256 
257   memset(&test_cfg_value.value, 0, sizeof(test_cfg_value.value));
258   test_cfg_value.value.boolean = 1;
259   test_cfg_value.type = OCONFIG_TYPE_BOOLEAN;
260   sstrncpy(key_buff, "ReportMasked", sizeof(key_buff));
261   ret = pcie_plugin_config(&test_cfg_parent);
262   EXPECT_EQ_INT(0, ret);
263   EXPECT_EQ_INT(1, pcie_config.notif_masked);
264 
265   sstrncpy(key_buff, "PersistentNotifications", sizeof(key_buff));
266   ret = pcie_plugin_config(&test_cfg_parent);
267   EXPECT_EQ_INT(0, ret);
268   EXPECT_EQ_INT(1, pcie_config.persistent);
269 
270   return 0;
271 }
272 
273 #define BAD_TLP_SET_MSG "Correctable Error set: Bad TLP Status"
274 #define BAD_TLP_CLEAR_MSG "Correctable Error cleared: Bad TLP Status"
275 
DEF_TEST(dispatch_correctable_errors)276 DEF_TEST(dispatch_correctable_errors) {
277   pcie_device_t dev = {0, TEST_DOMAIN, TEST_BUS, TEST_DEVICE, TEST_FUNCTION,
278                        0, 0,           0,        0,           0};
279   pcie_config.notif_masked = 0;
280   pcie_config.persistent = 0;
281 
282   pcie_dispatch_correctable_errors(&dev, PCI_ERR_COR_BAD_TLP,
283                                    ~(PCI_ERR_COR_BAD_TLP));
284   EXPECT_EQ_INT(NOTIF_WARNING, last_notif.severity);
285   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
286   OK(NULL == last_notif.meta);
287   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
288   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
289   EXPECT_EQ_STR(PCIE_SEV_CE, last_notif.type_instance);
290   EXPECT_EQ_STR(BAD_TLP_SET_MSG, last_notif.message);
291 
292   memset(&last_notif, 0, sizeof(last_notif));
293   dev.correctable_errors = PCI_ERR_COR_BAD_TLP;
294   pcie_dispatch_correctable_errors(&dev, PCI_ERR_COR_BAD_TLP,
295                                    ~(PCI_ERR_COR_BAD_TLP));
296   EXPECT_EQ_STR("", last_notif.plugin_instance);
297 
298   pcie_config.persistent = 1;
299   pcie_dispatch_correctable_errors(&dev, PCI_ERR_COR_BAD_TLP,
300                                    ~(PCI_ERR_COR_BAD_TLP));
301   EXPECT_EQ_INT(NOTIF_WARNING, last_notif.severity);
302   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
303   OK(NULL == last_notif.meta);
304   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
305   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
306   EXPECT_EQ_STR(PCIE_SEV_CE, last_notif.type_instance);
307   EXPECT_EQ_STR(BAD_TLP_SET_MSG, last_notif.message);
308 
309   memset(&last_notif, 0, sizeof(last_notif));
310   pcie_dispatch_correctable_errors(&dev, PCI_ERR_COR_BAD_TLP,
311                                    PCI_ERR_COR_BAD_TLP);
312   EXPECT_EQ_STR("", last_notif.plugin_instance);
313 
314   pcie_config.notif_masked = 1;
315   pcie_dispatch_correctable_errors(&dev, PCI_ERR_COR_BAD_TLP,
316                                    PCI_ERR_COR_BAD_TLP);
317   EXPECT_EQ_INT(NOTIF_WARNING, last_notif.severity);
318   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
319   OK(NULL == last_notif.meta);
320   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
321   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
322   EXPECT_EQ_STR(PCIE_SEV_CE, last_notif.type_instance);
323   EXPECT_EQ_STR(BAD_TLP_SET_MSG, last_notif.message);
324 
325   pcie_config.persistent = 0;
326   memset(&last_notif, 0, sizeof(last_notif));
327   pcie_dispatch_correctable_errors(&dev, PCI_ERR_COR_BAD_TLP,
328                                    PCI_ERR_COR_BAD_TLP);
329   EXPECT_EQ_STR("", last_notif.plugin_instance);
330 
331   dev.correctable_errors = 0;
332   pcie_dispatch_correctable_errors(&dev, PCI_ERR_COR_BAD_TLP,
333                                    PCI_ERR_COR_BAD_TLP);
334   EXPECT_EQ_INT(NOTIF_WARNING, last_notif.severity);
335   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
336   OK(NULL == last_notif.meta);
337   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
338   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
339   EXPECT_EQ_STR(PCIE_SEV_CE, last_notif.type_instance);
340   EXPECT_EQ_STR(BAD_TLP_SET_MSG, last_notif.message);
341 
342   pcie_dispatch_correctable_errors(&dev, PCI_ERR_COR_BAD_TLP,
343                                    ~(PCI_ERR_COR_BAD_TLP));
344   EXPECT_EQ_INT(NOTIF_WARNING, last_notif.severity);
345   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
346   OK(NULL == last_notif.meta);
347   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
348   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
349   EXPECT_EQ_STR(PCIE_SEV_CE, last_notif.type_instance);
350   EXPECT_EQ_STR(BAD_TLP_SET_MSG, last_notif.message);
351 
352   pcie_config.notif_masked = 0;
353   dev.correctable_errors = PCI_ERR_COR_BAD_TLP;
354   pcie_dispatch_correctable_errors(&dev, 0, ~(PCI_ERR_COR_BAD_TLP));
355   EXPECT_EQ_INT(NOTIF_OKAY, last_notif.severity);
356   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
357   OK(NULL == last_notif.meta);
358   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
359   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
360   EXPECT_EQ_STR(PCIE_SEV_CE, last_notif.type_instance);
361   EXPECT_EQ_STR(BAD_TLP_CLEAR_MSG, last_notif.message);
362 
363   return 0;
364 }
365 
366 #define FCP_NF_SET_MSG                                                         \
367   "Uncorrectable(non_fatal) Error set: Flow Control Protocol"
368 #define FCP_F_SET_MSG "Uncorrectable(fatal) Error set: Flow Control Protocol"
369 #define FCP_NF_CLEAR_MSG                                                       \
370   "Uncorrectable(non_fatal) Error cleared: Flow Control Protocol"
371 #define FCP_F_CLEAR_MSG                                                        \
372   "Uncorrectable(fatal) Error cleared: Flow Control Protocol"
373 
DEF_TEST(dispatch_uncorrectable_errors)374 DEF_TEST(dispatch_uncorrectable_errors) {
375   pcie_device_t dev = {0, TEST_DOMAIN, TEST_BUS, TEST_DEVICE, TEST_FUNCTION,
376                        0, 0,           0,        0,           0};
377   pcie_config.notif_masked = 0;
378   pcie_config.persistent = 0;
379 
380   pcie_dispatch_uncorrectable_errors(&dev, PCI_ERR_UNC_FCP, ~(PCI_ERR_UNC_FCP),
381                                      ~(PCI_ERR_UNC_FCP));
382   EXPECT_EQ_INT(NOTIF_WARNING, last_notif.severity);
383   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
384   OK(NULL == last_notif.meta);
385   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
386   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
387   EXPECT_EQ_STR(PCIE_SEV_NOFATAL, last_notif.type_instance);
388   EXPECT_EQ_STR(FCP_NF_SET_MSG, last_notif.message);
389 
390   pcie_dispatch_uncorrectable_errors(&dev, PCI_ERR_UNC_FCP, ~(PCI_ERR_UNC_FCP),
391                                      PCI_ERR_UNC_FCP);
392   EXPECT_EQ_INT(NOTIF_FAILURE, last_notif.severity);
393   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
394   OK(NULL == last_notif.meta);
395   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
396   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
397   EXPECT_EQ_STR(PCIE_SEV_FATAL, last_notif.type_instance);
398   EXPECT_EQ_STR(FCP_F_SET_MSG, last_notif.message);
399 
400   memset(&last_notif, 0, sizeof(last_notif));
401   dev.uncorrectable_errors = PCI_ERR_UNC_FCP;
402   pcie_dispatch_uncorrectable_errors(&dev, PCI_ERR_UNC_FCP, ~(PCI_ERR_UNC_FCP),
403                                      PCI_ERR_UNC_FCP);
404   EXPECT_EQ_STR("", last_notif.plugin_instance);
405 
406   pcie_config.persistent = 1;
407   pcie_dispatch_uncorrectable_errors(&dev, PCI_ERR_UNC_FCP, ~(PCI_ERR_UNC_FCP),
408                                      PCI_ERR_UNC_FCP);
409   EXPECT_EQ_INT(NOTIF_FAILURE, last_notif.severity);
410   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
411   OK(NULL == last_notif.meta);
412   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
413   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
414   EXPECT_EQ_STR(PCIE_SEV_FATAL, last_notif.type_instance);
415   EXPECT_EQ_STR(FCP_F_SET_MSG, last_notif.message);
416 
417   memset(&last_notif, 0, sizeof(last_notif));
418   pcie_dispatch_uncorrectable_errors(&dev, PCI_ERR_UNC_FCP, PCI_ERR_UNC_FCP,
419                                      PCI_ERR_UNC_FCP);
420   EXPECT_EQ_STR("", last_notif.plugin_instance);
421 
422   pcie_config.notif_masked = 1;
423   pcie_dispatch_uncorrectable_errors(&dev, PCI_ERR_UNC_FCP, PCI_ERR_UNC_FCP,
424                                      PCI_ERR_UNC_FCP);
425   EXPECT_EQ_INT(NOTIF_FAILURE, last_notif.severity);
426   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
427   OK(NULL == last_notif.meta);
428   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
429   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
430   EXPECT_EQ_STR(PCIE_SEV_FATAL, last_notif.type_instance);
431   EXPECT_EQ_STR(FCP_F_SET_MSG, last_notif.message);
432 
433   pcie_config.persistent = 0;
434   dev.uncorrectable_errors = 0;
435   memset(&last_notif, 0, sizeof(last_notif));
436   pcie_dispatch_uncorrectable_errors(&dev, PCI_ERR_UNC_FCP, ~(PCI_ERR_UNC_FCP),
437                                      PCI_ERR_UNC_FCP);
438   EXPECT_EQ_INT(NOTIF_FAILURE, last_notif.severity);
439   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
440   OK(NULL == last_notif.meta);
441   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
442   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
443   EXPECT_EQ_STR(PCIE_SEV_FATAL, last_notif.type_instance);
444   EXPECT_EQ_STR(FCP_F_SET_MSG, last_notif.message);
445 
446   pcie_config.notif_masked = 0;
447   dev.uncorrectable_errors = PCI_ERR_UNC_FCP;
448   pcie_dispatch_uncorrectable_errors(&dev, 0, ~(PCI_ERR_UNC_FCP),
449                                      ~(PCI_ERR_UNC_FCP));
450   EXPECT_EQ_INT(NOTIF_OKAY, last_notif.severity);
451   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
452   OK(NULL == last_notif.meta);
453   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
454   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
455   EXPECT_EQ_STR(PCIE_SEV_NOFATAL, last_notif.type_instance);
456   EXPECT_EQ_STR(FCP_NF_CLEAR_MSG, last_notif.message);
457 
458   memset(&last_notif, 0, sizeof(last_notif));
459   pcie_dispatch_uncorrectable_errors(&dev, 0, ~(PCI_ERR_UNC_FCP),
460                                      PCI_ERR_UNC_FCP);
461   EXPECT_EQ_INT(NOTIF_OKAY, last_notif.severity);
462   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
463   OK(NULL == last_notif.meta);
464   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
465   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
466   EXPECT_EQ_STR(PCIE_SEV_FATAL, last_notif.type_instance);
467   EXPECT_EQ_STR(FCP_F_CLEAR_MSG, last_notif.message);
468 
469   return 0;
470 }
471 
472 #define UR_SET_MSG "Device Status Error set: Unsupported Request"
473 #define UR_CLEAR_MSG "Device Status Error cleared: Unsupported Request"
474 #define FE_SET_MSG "Device Status Error set: Fatal Error"
475 #define FE_CLEAR_MSG "Device Status Error cleared: Fatal Error"
476 
DEF_TEST(device_status_errors)477 DEF_TEST(device_status_errors) {
478   pcie_device_t dev = {0, TEST_DOMAIN, TEST_BUS, TEST_DEVICE, TEST_FUNCTION,
479                        0, 0,           0,        0,           0};
480   pcie_config.persistent = 0;
481   g_buff[0] = (PCI_EXP_DEVSTA_URD & 0xff);
482 
483   memset(&last_notif, 0, sizeof(last_notif));
484   pcie_check_dev_status(&dev, 0);
485   EXPECT_EQ_INT(NOTIF_WARNING, last_notif.severity);
486   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
487   OK(NULL == last_notif.meta);
488   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
489   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
490   EXPECT_EQ_STR(PCIE_SEV_NOFATAL, last_notif.type_instance);
491   EXPECT_EQ_STR(UR_SET_MSG, last_notif.message);
492 
493   memset(&last_notif, 0, sizeof(last_notif));
494   pcie_check_dev_status(&dev, 0);
495   EXPECT_EQ_STR("", last_notif.plugin_instance);
496 
497   pcie_config.persistent = 1;
498   pcie_check_dev_status(&dev, 0);
499   EXPECT_EQ_INT(NOTIF_WARNING, last_notif.severity);
500   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
501   OK(NULL == last_notif.meta);
502   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
503   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
504   EXPECT_EQ_STR(PCIE_SEV_NOFATAL, last_notif.type_instance);
505   EXPECT_EQ_STR(UR_SET_MSG, last_notif.message);
506 
507   g_buff[0] = 0;
508   pcie_check_dev_status(&dev, 0);
509   EXPECT_EQ_INT(NOTIF_OKAY, last_notif.severity);
510   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
511   OK(NULL == last_notif.meta);
512   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
513   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
514   EXPECT_EQ_STR(PCIE_SEV_NOFATAL, last_notif.type_instance);
515   EXPECT_EQ_STR(UR_CLEAR_MSG, last_notif.message);
516 
517   pcie_config.persistent = 0;
518   dev.device_status = PCI_EXP_DEVSTA_URD;
519   pcie_check_dev_status(&dev, 0);
520   EXPECT_EQ_INT(NOTIF_OKAY, last_notif.severity);
521   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
522   OK(NULL == last_notif.meta);
523   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
524   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
525   EXPECT_EQ_STR(PCIE_SEV_NOFATAL, last_notif.type_instance);
526   EXPECT_EQ_STR(UR_CLEAR_MSG, last_notif.message);
527 
528   memset(&last_notif, 0, sizeof(last_notif));
529   pcie_check_dev_status(&dev, 0);
530   EXPECT_EQ_STR("", last_notif.plugin_instance);
531 
532   g_buff[0] = (PCI_EXP_DEVSTA_FED & 0xff);
533   pcie_check_dev_status(&dev, 0);
534   EXPECT_EQ_INT(NOTIF_FAILURE, last_notif.severity);
535   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
536   OK(NULL == last_notif.meta);
537   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
538   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
539   EXPECT_EQ_STR(PCIE_SEV_FATAL, last_notif.type_instance);
540   EXPECT_EQ_STR(FE_SET_MSG, last_notif.message);
541 
542   g_buff[0] = 0;
543   pcie_check_dev_status(&dev, 0);
544   EXPECT_EQ_INT(NOTIF_OKAY, last_notif.severity);
545   EXPECT_EQ_STR(PCIE_ERRORS_PLUGIN, last_notif.plugin);
546   OK(NULL == last_notif.meta);
547   EXPECT_EQ_STR(TEST_DEVICE_STR, last_notif.plugin_instance);
548   EXPECT_EQ_STR(PCIE_ERROR, last_notif.type);
549   EXPECT_EQ_STR(PCIE_SEV_FATAL, last_notif.type_instance);
550   EXPECT_EQ_STR(FE_CLEAR_MSG, last_notif.message);
551 
552   return 0;
553 }
554 
main(void)555 int main(void) {
556   RUN_TEST(clear_dev_list);
557   RUN_TEST(add_to_list);
558   RUN_TEST(pcie_read);
559   RUN_TEST(dispatch_notification);
560 
561   RUN_TEST(access_config);
562   RUN_TEST(plugin_config_fail);
563   RUN_TEST(plugin_config);
564 
565   RUN_TEST(dispatch_correctable_errors);
566   RUN_TEST(dispatch_uncorrectable_errors);
567   RUN_TEST(device_status_errors);
568 
569   END_TEST;
570 }
571