Home | History | Annotate | Download | only in tpci_kernel
      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 (at) us.ibm.com)
     29  * date:   5/20/2003
     30  * PCI-Express test scripts author: Amit Khanna (amit.khanna (at) 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 (at) us.ibm.com>");
     48 MODULE_AUTHOR("Amit Khanna <amit.khanna (at) 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 
     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  */
     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  */
    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 
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    424 static int test_reg_driver(void)
    425 {
    426 	prk_info("test pci_register_driver");
    427 	if (pci_register_driver(&ltp_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  */
    441 static int test_unreg_driver(void)
    442 {
    443 	pci_unregister_driver(&ltp_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  */
    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  */
    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  */
    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  */
    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  */
    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 
    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 
    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 */
    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 
    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 
    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 
    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 }
    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(&ltp_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