1 /*
2 * Copyright (c) International Business Machines Corp., 2001
3 * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 * This pci and pci-express testing kernel module will allow test calls
20 * to be driven through various ioctl calls in a
21 * user space program that has attained the appropriate
22 * file descriptor for this device. For the functions of
23 * this module to work correctly there must be a pci / pci-express
24 * device somewhere in the system. The tests do not need
25 * a specific device, and the first pci device available
26 * will be grabbed.
27 *
28 * author: Sean Ruyle (srruyle@us.ibm.com)
29 * date: 5/20/2003
30 * PCI-Express test scripts author: Amit Khanna (amit.khanna@intel.com)
31 * date: 8/20/2004
32 *
33 * file: tpci.c,
34 * module: tpci
35 */
36
37 #include <linux/types.h>
38 #include <linux/kernel.h>
39 #include <linux/fs.h>
40 #include <linux/ioctl.h>
41 #include <linux/module.h>
42 #include <linux/init.h>
43 #include <linux/pci.h>
44
45 #include "tpci.h"
46
47 MODULE_AUTHOR("Sean Ruyle <srruyle@us.ibm.com>");
48 MODULE_AUTHOR("Amit Khanna <amit.khanna@intel.com>");
49 MODULE_AUTHOR("Copyright (c) 2013 Oracle and/or its affiliates");
50 MODULE_DESCRIPTION("LTP PCI Test");
51 MODULE_LICENSE("GPL");
52
53 #define prk_err(fmt, ...) \
54 pr_err(PCI_DEVICE_NAME ": " fmt "\n", ##__VA_ARGS__)
55 #define prk_info(fmt, ...) \
56 pr_info(PCI_DEVICE_NAME ": " fmt "\n", ##__VA_ARGS__)
57 #define prk_debug(fmt, ...) \
58 pr_debug(PCI_DEVICE_NAME ": " fmt "\n", ##__VA_ARGS__)
59
60 #define TPASS 0
61 #define TFAIL 1
62 #define TSKIP 32
63
64 static DEFINE_PCI_DEVICE_TABLE(ltp_pci_tbl) = {
65 { PCI_DEVICE(PCI_ANY_ID, PCI_ANY_ID) },
66 { 0, }
67 };
68
69 MODULE_DEVICE_TABLE(pci, ltp_pci_tbl);
70
ltp_pci_probe(struct pci_dev * pci_dev,const struct pci_device_id * pci_ent)71 static int ltp_pci_probe(struct pci_dev *pci_dev,
72 const struct pci_device_id *pci_ent)
73 {
74 return 0;
75 }
76
77 static struct pci_driver ltp_pci_driver = {
78 .name = "LTP_PCI_DRIVER",
79 .id_table = ltp_pci_tbl,
80 .probe = ltp_pci_probe,
81 };
82
83 static int pci_registered;
84
85 struct tpci_user {
86 struct pci_dev *dev;
87 struct pci_bus *bus;
88 struct pci_driver *drv;
89 uint32_t state[16];
90 };
91 static struct tpci_user ltp_pci;
92
93 /*
94 * probe_pci_dev
95 * find a pci device that can be used for other test
96 * calls in this kernel module.
97 */
probe_pci_dev(unsigned int bus,unsigned int slot)98 static int probe_pci_dev(unsigned int bus, unsigned int slot)
99 {
100 struct pci_dev *dev;
101
102 if (ltp_pci.dev) {
103 pci_dev_put(ltp_pci.dev);
104 ltp_pci.dev = NULL;
105 }
106
107 dev = pci_get_bus_and_slot(bus, slot);
108 if (!dev || !dev->driver)
109 return -ENODEV;
110
111 prk_info("found pci_dev '%s', bus %u, devfn %u",
112 pci_name(dev), bus, slot);
113
114 ltp_pci.dev = dev;
115 ltp_pci.bus = dev->bus;
116 prk_info("Bus number: %d", dev->bus->number);
117 return 0;
118 }
119
120 /*
121 * pci_enable
122 * enable a pci device so that it may be used in
123 * later testing in the user test program
124 */
pci_enable(void)125 static int pci_enable(void)
126 {
127 struct pci_dev *dev = ltp_pci.dev;
128
129 prk_info("enable pci device");
130
131 /* check if can enable the device pointer */
132 if (!dev) {
133 prk_err("dev is NULL");
134 return TFAIL;
135 }
136
137 if (pci_enable_device(dev)) {
138 prk_err("failed to enable pci device");
139 return TFAIL;
140 }
141
142 prk_info("enabled pci device");
143 return TPASS;
144 }
145
pci_disable(void)146 static int pci_disable(void)
147 {
148 struct pci_dev *dev = ltp_pci.dev;
149
150 prk_info("disable pci device");
151
152 /* check if device pointer exists */
153 if (!dev) {
154 prk_err("dev is NULL");
155 return TFAIL;
156 }
157
158 prk_info("is pci enabled '%d', is managed '%d'",
159 pci_is_enabled(dev), pci_is_managed(dev));
160
161 pci_release_regions(dev);
162 pci_disable_device(dev);
163
164 if (dev->current_state == PCI_D3hot ||
165 dev->current_state == PCI_D3cold) {
166
167 prk_info("disabled pci device, state '%s'",
168 pci_power_name(dev->current_state));
169 return TPASS;
170
171 }
172
173 prk_err("failed to disable pci device, state '%s'",
174 pci_power_name(dev->current_state));
175 return TFAIL;
176 }
177
178 /*
179 * find_bus
180 * call to pci_find_bus, use values from bus
181 * pointer in ltp_pci, make sure that returns
182 * bus with same values
183 */
test_find_bus(void)184 static int test_find_bus(void)
185 {
186 int num = ltp_pci.bus->number;
187 struct pci_bus *temp = NULL;
188
189 prk_info("find bus");
190
191 temp = pci_find_bus(pci_domain_nr(ltp_pci.bus), num);
192
193 if (!temp) {
194 prk_info("pci_find_bus failed");
195 return TFAIL;
196 } else if (temp->number != num) {
197 prk_err("returned bus pointer w/ wrong bus number");
198 return TFAIL;
199 }
200
201 prk_info("success returned bus pointer");
202 return TPASS;
203 }
204
205 /*
206 * find_class
207 * call to pci_find_class, using values from the
208 * pci_dev pointer in ltp_pci structure
209 */
test_find_class(void)210 static int test_find_class(void)
211 {
212 unsigned int num = ltp_pci.dev->class;
213 struct pci_dev *temp = NULL;
214
215 prk_info("find pci class");
216
217 temp = pci_get_class(num, NULL);
218
219 if (!temp) {
220 prk_err("failed to find pci device from class number");
221 return TFAIL;
222 }
223
224 prk_info("found pci device from class number");
225 pci_dev_put(temp);
226
227 return TPASS;
228 }
229
230 /*
231 * find_device
232 * call to pci_find_device, using values for
233 * parameters from pci_dev pointer in the
234 * ltp_pci structure
235 */
test_find_device(void)236 static int test_find_device(void)
237 {
238 struct pci_dev *temp = NULL;
239 unsigned short ven = ltp_pci.dev->vendor, dev = ltp_pci.dev->device;
240
241 prk_info("get pci device");
242
243 temp = pci_get_device(ven, dev, NULL);
244
245 if (!temp) {
246 prk_err("failed to find pci device from device info");
247 return TFAIL;
248 }
249
250 prk_info("found pci device from device info");
251 pci_dev_put(temp);
252
253 return TPASS;
254 }
255
256 /*
257 * find_subsys
258 * call to pci_find_subsys, use valued from
259 * pci_dev pointer in ltp_pci structure to
260 * find pci_dev from subsys info
261 */
test_find_subsys(void)262 static int test_find_subsys(void)
263 {
264 struct pci_dev *temp;
265 unsigned short ven = ltp_pci.dev->vendor,
266 dev = ltp_pci.dev->device,
267 ss_ven = ltp_pci.dev->subsystem_vendor,
268 ss_dev = ltp_pci.dev->subsystem_device;
269
270 prk_info("get pci subsys");
271 temp = pci_get_subsys(ven, dev, ss_ven, ss_dev, NULL);
272
273 if (!temp) {
274 prk_err("failed to find pci device from subsys info");
275 return TFAIL;
276 }
277
278 prk_info("found pci device from subsys info");
279 pci_dev_put(temp);
280
281 return TPASS;
282 }
283
284 /*
285 * test_scan_bus
286 * call to pci_do_scan_bus, which takes
287 * a struct pci_bus pointer, which will
288 * return an integer for how far the
289 * function got in scanning bus
290 */
test_scan_bus(void)291 static int test_scan_bus(void)
292 {
293 #ifdef CONFIG_HOTPLUG
294 int num;
295 struct pci_bus *bus = ltp_pci.bus;
296
297 prk_info("scan pci bus");
298
299 num = pci_rescan_bus(bus);
300 /*
301 * check if returned number is greater than
302 * max number of bus or less than 0
303 */
304 if (num > MAX_BUS || num < 0) {
305 prk_err("failed scan bus");
306 return TFAIL;
307 }
308 prk_info("success scan bus");
309 return TPASS;
310 #else
311 prk_info("pci_rescan_bus() is not supported");
312 return TSKIP;
313 #endif
314 }
315
316 /*
317 * test_slot_scan
318 * make call to pci_scan_slot, which will
319 * find the device pointer and setup the
320 * device info
321 */
test_slot_scan(void)322 static int test_slot_scan(void)
323 {
324 int ret, num = ltp_pci.dev->devfn;
325 struct pci_bus *bus = ltp_pci.bus;
326
327 prk_info("scan pci slot");
328
329 ret = pci_scan_slot(bus, num);
330 if (ret >= 0) {
331 prk_info("found '%d' devices from scan slot", ret);
332 return TPASS;
333 }
334
335 prk_err("pci_scan_slot failed");
336 return TFAIL;
337 }
338
339 /*
340 * test_bus_add_devices
341 * make call to pci_bus_add_devices,
342 * which will check the device pointer
343 * that is passed in for more devices
344 * that it can add
345 */
test_bus_add_devices(void)346 static int test_bus_add_devices(void)
347 {
348 struct pci_bus *bus = ltp_pci.bus;
349
350 prk_info("add bus device");
351
352 pci_bus_add_devices(bus);
353
354 if (bus) {
355 prk_info("called bus_add_device");
356 return TPASS;
357 }
358
359 prk_err("bus_add_device failed");
360 return TFAIL;
361 }
362
363 /*
364 * test_enable_bridges
365 * make call to pci_enable_bridges,
366 * use bus pointer from the ltp_pci
367 * structure
368 */
test_enable_bridges(void)369 static int test_enable_bridges(void)
370 {
371 struct pci_bus *bus = ltp_pci.bus;
372
373 prk_info("enable bridges");
374
375 pci_enable_bridges(bus);
376
377 if (bus) {
378 prk_info("called enable bridges");
379 return TPASS;
380 }
381
382 prk_err("enable_bridges failed");
383 return TFAIL;
384 }
385
386 /*
387 * test_match_device
388 * make call to pci_match_device, returns a
389 * pci_device_id pointer
390 */
test_match_device(void)391 static int test_match_device(void)
392 {
393 struct pci_dev *dev = ltp_pci.dev;
394 struct pci_driver *drv;
395 const struct pci_device_id *id;
396
397 prk_info("test pci_device_id()");
398
399 drv = pci_dev_driver(dev);
400
401 if (!drv) {
402 prk_err("driver pointer not allocated for pci_dev");
403 return TFAIL;
404 }
405
406 id = pci_match_id(drv->id_table, dev);
407
408 if (id) {
409 prk_info("match device success");
410 return TPASS;
411 }
412
413 prk_err("failed return pci_device_id");
414 return TFAIL;
415 }
416
417
418 /*
419 * test_reg_driver
420 * make call to pci_register_driver, which will
421 * register the driver for a device with the
422 * system
423 */
test_reg_driver(void)424 static int test_reg_driver(void)
425 {
426 prk_info("test pci_register_driver");
427 if (pci_register_driver(<p_pci_driver)) {
428 prk_err("unsuccessful registering pci driver");
429 return TFAIL;
430 }
431 pci_registered = 1;
432 prk_info("success driver register");
433 return TPASS;
434 }
435
436 /*
437 * test_unreg_driver
438 * make call to pci_unregister_driver, which will
439 * unregister the driver for a device from the system
440 */
test_unreg_driver(void)441 static int test_unreg_driver(void)
442 {
443 pci_unregister_driver(<p_pci_driver);
444 pci_registered = 0;
445 return TPASS;
446 }
447
448 /*
449 * test_assign_resources
450 * make calls to pci_assign_resource, will need
451 * to setup a dev pointer and resource pointer,
452 */
test_assign_resources(void)453 static int test_assign_resources(void)
454 {
455 int i, ret, rc = 0;
456 struct pci_dev *dev = ltp_pci.dev;
457 struct resource *r;
458
459 prk_info("assign resources");
460
461 for (i = 0; i < 7; ++i) {
462 prk_info("assign resource #%d", i);
463 r = &dev->resource[i];
464 prk_info("name = %s, flags = %lu, start 0x%lx, end 0x%lx",
465 r->name, r->flags,
466 (unsigned long)r->start, (unsigned long)r->end);
467
468 if (r->flags & IORESOURCE_MEM &&
469 r->flags & IORESOURCE_PREFETCH) {
470 ret = pci_assign_resource(dev, i);
471 prk_info("assign resource to '%d', ret '%d'", i, ret);
472 rc |= (ret < 0 && ret != -EBUSY) ? TFAIL : TPASS;
473 }
474 }
475
476 /*
477 * enable device after call to assign resource
478 * because might error if (!r->start && r->end)
479 */
480 if (pci_enable_device(dev))
481 return TFAIL;
482
483 return rc;
484 }
485
486 /*
487 * test_save_state
488 * make call to pci_save_state, takes in a u32*
489 * buffer
490 */
test_save_state(void)491 static int test_save_state(void)
492 {
493 struct pci_dev *dev = ltp_pci.dev;
494
495 prk_info("save state");
496
497 if (pci_save_state(dev)) {
498 prk_err("failed save state");
499 return TFAIL;
500 }
501
502 prk_info("saved state of device");
503 return TPASS;
504 }
505
506 /*
507 * test_restore_state
508 * make call to pci_restore_state, get the state buffer
509 * should have been previously filled out by save state
510 */
test_restore_state(void)511 static int test_restore_state(void)
512 {
513 struct pci_dev *dev = ltp_pci.dev;
514
515 prk_info("restore state");
516
517 pci_restore_state(dev);
518
519 return TPASS;
520 }
521
522 /*
523 * test_find_cap
524 * make call to pci_find_capability, which
525 * will determine if a device has a certain
526 * capability, use second parameter to specify
527 * which capability you are looking for
528 */
test_find_cap(void)529 static int test_find_cap(void)
530 {
531 struct pci_dev *dev = ltp_pci.dev;
532
533 prk_info("find device capability");
534
535 if (pci_find_capability(dev, PCI_CAP_ID_PM))
536 prk_info("does not have tested capability");
537 else
538 prk_info("device has PM capability");
539
540 return TPASS;
541 }
542
543 /*
544 * test_read_pci_exp_config
545 * make call to pci_config_read and determine if
546 * the PCI-Express enhanced config space of this
547 * device can be read successfully.
548 */
test_read_pci_exp_config(void)549 static int test_read_pci_exp_config(void)
550 {
551 int pos;
552 u32 header;
553 struct pci_dev *dev = ltp_pci.dev;
554
555 /* skip the test if device doesn't have PCIe capability */
556 pos = pci_pcie_cap(dev);
557 if (!pos) {
558 prk_info("device doesn't have PCI-EXP capability");
559 return TSKIP;
560 }
561 prk_info("read the PCI Express configuration registers at 0x%x", pos);
562
563 if (pci_read_config_dword(dev, pos, &header)) {
564 prk_err("failed to read config dword");
565 return TFAIL;
566 }
567
568 /* comparing the value read with PCI_CAP_ID_EXP macro */
569 if ((header & 0x000000ff) == PCI_CAP_ID_EXP) {
570 prk_info("correct val read using PCIE driver installed: 0x%x",
571 header);
572 return TPASS;
573 }
574
575 prk_err("incorrect val read. PCIE driver/device not installed: 0x%x",
576 header);
577 return TFAIL;
578 }
579
test_case(unsigned int cmd)580 static int test_case(unsigned int cmd)
581 {
582 int rc = TSKIP;
583
584 switch (cmd) {
585 case PCI_ENABLE:
586 rc = pci_enable();
587 break;
588 case PCI_DISABLE:
589 rc = pci_disable();
590 break;
591 case FIND_BUS:
592 rc = test_find_bus();
593 break;
594 case FIND_CLASS:
595 rc = test_find_class();
596 break;
597 case FIND_DEVICE:
598 rc = test_find_device();
599 break;
600 case FIND_SUBSYS:
601 rc = test_find_subsys();
602 break;
603 case BUS_SCAN:
604 rc = test_scan_bus();
605 break;
606 case SLOT_SCAN:
607 rc = test_slot_scan();
608 break;
609 case BUS_ADD_DEVICES:
610 rc = test_bus_add_devices();
611 break;
612 case ENABLE_BRIDGES:
613 rc = test_enable_bridges();
614 break;
615 case MATCH_DEVICE:
616 rc = test_match_device();
617 break;
618 case REG_DRIVER:
619 rc = test_reg_driver();
620 break;
621 case UNREG_DRIVER:
622 rc = test_unreg_driver();
623 break;
624 case PCI_RESOURCES:
625 rc = test_assign_resources();
626 break;
627 case SAVE_STATE:
628 rc = test_save_state();
629 break;
630 case RESTORE_STATE:
631 rc = test_restore_state();
632 break;
633 case FIND_CAP:
634 rc = test_find_cap();
635 break;
636 case PCI_EXP_CAP_CONFIG:
637 rc = test_read_pci_exp_config();
638 break;
639 default:
640 prk_info("mismatching test-case command %d", cmd);
641 break;
642 }
643
644 return rc;
645 }
646
647 /*
648 * Test-case result,
649 * if test is passed, value will be set to 0
650 */
651 static int test_result;
652
device_release(struct device * dev)653 static void device_release(struct device *dev)
654 {
655 prk_info("device released\n");
656 }
657
658 static struct device tdev = {
659 .init_name = PCI_DEVICE_NAME,
660 .release = device_release,
661 };
662
663 /* print test result to sysfs file */
sys_result(struct device * dev,struct device_attribute * attr,char * buf)664 static ssize_t sys_result(struct device *dev,
665 struct device_attribute *attr, char *buf)
666 {
667 return scnprintf(buf, PAGE_SIZE, "%d\n", test_result);
668 }
669 static DEVICE_ATTR(result, S_IRUSR, sys_result, NULL);
670
sys_tcase(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)671 static ssize_t sys_tcase(struct device *dev,
672 struct device_attribute *attr, const char *buf, size_t count)
673 {
674 int tc = 0;
675
676 sscanf(buf, "%d", &tc);
677 prk_info("test-case %d", tc);
678
679 test_result = test_case(tc);
680
681 return count;
682 }
683 static DEVICE_ATTR(tcase, S_IWUSR, NULL, sys_tcase);
684
sys_bus_slot(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)685 static ssize_t sys_bus_slot(struct device *dev,
686 struct device_attribute *attr, const char *buf, size_t count)
687 {
688 unsigned int res, bus, slot;
689 int ret;
690
691 sscanf(buf, "%u", &res);
692
693 bus = res >> 8 & 0xFF;
694 slot = res & 0xFF;
695
696 ret = probe_pci_dev(bus, slot);
697 if (ret)
698 return ret;
699
700 return count;
701 }
702 static DEVICE_ATTR(bus_slot, S_IWUSR, NULL, sys_bus_slot);
703
tpci_init_module(void)704 static int tpci_init_module(void)
705 {
706 int err = 0;
707 prk_info("Starting module");
708
709 err = device_register(&tdev);
710 if (err) {
711 prk_err("Unable to register device");
712 goto err0;
713 }
714 prk_info("device registered\n");
715
716 err = device_create_file(&tdev, &dev_attr_result);
717 if (err) {
718 prk_err("Can't create sysfs file 'result'");
719 goto err1;
720 }
721
722 err = device_create_file(&tdev, &dev_attr_tcase);
723 if (err) {
724 prk_err(": Can't create sysfs file 'tc'");
725 goto err2;
726 }
727
728 err = device_create_file(&tdev, &dev_attr_bus_slot);
729 if (err) {
730 prk_err(": Can't create sysfs file 'bus_slot'");
731 goto err3;
732 }
733
734 return 0;
735
736 err3:
737 device_remove_file(&tdev, &dev_attr_tcase);
738 err2:
739 device_remove_file(&tdev, &dev_attr_result);
740 err1:
741 device_unregister(&tdev);
742 err0:
743 return err;
744 }
module_init(tpci_init_module)745 module_init(tpci_init_module)
746
747 static void tpci_exit_module(void)
748 {
749 prk_debug("Unloading module\n");
750 if (ltp_pci.dev)
751 pci_dev_put(ltp_pci.dev);
752
753 if (pci_registered)
754 pci_unregister_driver(<p_pci_driver);
755
756 device_remove_file(&tdev, &dev_attr_result);
757 device_remove_file(&tdev, &dev_attr_tcase);
758 device_remove_file(&tdev, &dev_attr_bus_slot);
759 device_unregister(&tdev);
760 }
761 module_exit(tpci_exit_module)
762