From: Cyril H. <su...@li...> - 2013-10-16 12:51:14
|
The branch, master, has been updated via 02c479c2061ad481c7df78a7432bd8cc90027444 (commit) via 9dcb59183e535430d156d7c2a50ca78969d7485c (commit) from e2ecf28cbbcb99ff5ff576ad0c1ce7145d28bf76 (commit) - Log ----------------------------------------------------------------- commit 02c479c2061ad481c7df78a7432bd8cc90027444 Author: Alexey Kodanev <ale...@or...> Date: Wed Oct 16 14:26:40 2013 +0400 device-drivers: pci: fixes Obsolete code updated to the actual kernel PCI API. Changed test-cases handling from ioctl to sysfs. User-space program rewritten. Signed-off-by: Alexey Kodanev <ale...@or...> Reviewed-by: Cyril Hrubis <ch...@su...> commit 9dcb59183e535430d156d7c2a50ca78969d7485c Author: Alexey Kodanev <ale...@or...> Date: Tue Sep 24 17:37:08 2013 +0400 device-drivers: pci: rename files and remove useless files Signed-off-by: Alexey Kodanev <ale...@or...> Reviewed-by: Cyril Hrubis <ch...@su...> ----------------------------------------------------------------------- Summary of changes: .../kernel/device-drivers/{block => pci}/Makefile | 0 testcases/kernel/device-drivers/pci/tpci/Makefile | 22 - testcases/kernel/device-drivers/pci/tpci/st_tpci.h | 27 - testcases/kernel/device-drivers/pci/tpci/tpci.c | 893 -------------------- testcases/kernel/device-drivers/pci/tpci/tpci.h | 67 -- .../kernel/device-drivers/pci/tpci/tpci.mod.c | 29 - .../device-drivers/pci/tpci_kernel/.gitignore | 7 + .../kernel/device-drivers/pci/tpci_kernel/Makefile | 35 + .../device-drivers/pci/tpci_kernel/ltp_tpci.c | 787 +++++++++++++++++ .../pci/{tpci => tpci_kernel}/pci-exp-tests-HOWTO | 0 .../kernel/device-drivers/pci/tpci_kernel/tpci.h | 45 + .../kernel/device-drivers/pci/tpci_user/.gitignore | 1 + .../block_dev_user => pci/tpci_user}/Makefile | 0 .../kernel/device-drivers/pci/tpci_user/tpci.c | 120 +++ .../kernel/device-drivers/pci/user_tpci/Makefile | 9 - .../kernel/device-drivers/pci/user_tpci/tpci_ki.c | 198 ----- .../device-drivers/pci/user_tpci/user_tpci.c | 258 ------ .../device-drivers/pci/user_tpci/user_tpci.h | 31 - 18 files changed, 995 insertions(+), 1534 deletions(-) copy testcases/kernel/device-drivers/{block => pci}/Makefile (100%) delete mode 100644 testcases/kernel/device-drivers/pci/tpci/Makefile delete mode 100644 testcases/kernel/device-drivers/pci/tpci/st_tpci.h delete mode 100644 testcases/kernel/device-drivers/pci/tpci/tpci.c delete mode 100644 testcases/kernel/device-drivers/pci/tpci/tpci.h delete mode 100644 testcases/kernel/device-drivers/pci/tpci/tpci.mod.c create mode 100644 testcases/kernel/device-drivers/pci/tpci_kernel/.gitignore create mode 100644 testcases/kernel/device-drivers/pci/tpci_kernel/Makefile create mode 100644 testcases/kernel/device-drivers/pci/tpci_kernel/ltp_tpci.c rename testcases/kernel/device-drivers/pci/{tpci => tpci_kernel}/pci-exp-tests-HOWTO (100%) create mode 100644 testcases/kernel/device-drivers/pci/tpci_kernel/tpci.h create mode 100644 testcases/kernel/device-drivers/pci/tpci_user/.gitignore copy testcases/kernel/device-drivers/{block/block_dev_user => pci/tpci_user}/Makefile (100%) create mode 100644 testcases/kernel/device-drivers/pci/tpci_user/tpci.c delete mode 100644 testcases/kernel/device-drivers/pci/user_tpci/Makefile delete mode 100644 testcases/kernel/device-drivers/pci/user_tpci/tpci_ki.c delete mode 100644 testcases/kernel/device-drivers/pci/user_tpci/user_tpci.c delete mode 100644 testcases/kernel/device-drivers/pci/user_tpci/user_tpci.h diff --git a/testcases/kernel/device-drivers/block/Makefile b/testcases/kernel/device-drivers/pci/Makefile similarity index 100% copy from testcases/kernel/device-drivers/block/Makefile copy to testcases/kernel/device-drivers/pci/Makefile diff --git a/testcases/kernel/device-drivers/pci/tpci/Makefile b/testcases/kernel/device-drivers/pci/tpci/Makefile deleted file mode 100644 index 77c80ec..0000000 --- a/testcases/kernel/device-drivers/pci/tpci/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# -# Makefile for GCOV profiling kernel module -# - -#KERNELDIR := /usr/src/linux-2.5.64-gcov -CFLAGS := $(CFLAGS) -Wall - -ifneq ($(KERNELRELEASE),) - -obj-m := tpci.o -else -KDIR := /lib/modules/$(shell uname -r)/build -PWD := $(shell pwd) - -default: - $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules -# $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules -endif - -clean: - rm -f tpci.o 2>/dev/null || true - diff --git a/testcases/kernel/device-drivers/pci/tpci/st_tpci.h b/testcases/kernel/device-drivers/pci/tpci/st_tpci.h deleted file mode 100644 index 4538890..0000000 --- a/testcases/kernel/device-drivers/pci/tpci/st_tpci.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * - * Copyright (c) International Business Machines Corp., 2001 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * -*/ - -struct tpci_user { - struct pci_dev *dev; - struct pci_bus *bus; - struct pci_driver *drv; - uint32_t state[16]; -}; -typedef struct tpci_user tpci_user_t; diff --git a/testcases/kernel/device-drivers/pci/tpci/tpci.c b/testcases/kernel/device-drivers/pci/tpci/tpci.c deleted file mode 100644 index c994c55..0000000 --- a/testcases/kernel/device-drivers/pci/tpci/tpci.c +++ /dev/null @@ -1,893 +0,0 @@ -/* - * - * Copyright (c) International Business Machines Corp., 2001 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - - * This pci and pci-express testing kernel module will allow test calls - * to be driven through various ioctl calls in a - * user space program that has attained the appropriate - * file descriptor for this device. For the functions of - * this module to work correctly there must be a pci / pci-express - * device somewhere in the system. The tests do not need - * a specific device, and the first pci device available - * will be grabbed. - * - * author: Sean Ruyle (sr...@us...) - * date: 5/20/2003 - * PCI-Express test scripts author: Amit Khanna (ami...@in...) - * date: 8/20/2004 - * - * file: tpci.c, - * module: tpci - */ - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/ioctl.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <asm/uaccess.h> -#include "tpci.h" -#include "st_tpci.h" - -MODULE_AUTHOR - ("Sean Ruyle <sr...@us...>, Amit Khanna <ami...@in...>"); -MODULE_DESCRIPTION(TPCI_TEST_DRIVER_NAME); -MODULE_LICENSE("GPL"); - -static int tpci_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); -static int tpci_open(struct inode *, struct file *); -static int tpci_close(struct inode *, struct file *); - -static int probe_pci_dev(void); -static int pci_enable(void); -static int pci_disable(void); -static int test_find_bus(void); -static int test_find_class(void); -static int test_find_device(void); -static int test_find_subsys(void); -static int test_scan_bus(void); -static int test_slot_scan(void); -static int test_bus_add_devices(void); -static int test_enable_bridges(void); -static int test_match_device(void); -static int test_reg_driver(void); -static int test_unreg_driver(void); -static int test_assign_resources(void); -static int test_save_state(void); -static int test_restore_state(void); -static int test_max_bus(void); -static int test_find_cap(void); -static int test_find_pci_exp_cap(void); -static int test_read_pci_exp_config(void); - -static int Major = TPCI_MAJOR; -static tpci_user_t ltp_pci; - -/* - * File operations struct, to use operations find the - * correct file descriptor - */ -static struct file_operations tpci_fops = { -open: tpci_open, -release:tpci_close, -ioctl: tpci_ioctl, -}; - -/* - * open and close operations - */ -static int tpci_open(struct inode *ino, struct file *f) -{ - return 0; -} - -static int tpci_close(struct inode *ino, struct file *f) -{ - return 0; -} - -/* - * tpci_ioctl: - * a user space program can drive the test functions - * through a call to ioctl once the correct file - * descriptor has been attained - * - * calls functions: - * - */ -static int tpci_ioctl(struct inode *ino, struct file *f, - unsigned int cmd, unsigned long l) -{ - int rc; - struct tpci_interface tif; - caddr_t *inparms; - caddr_t *outparms; - - printk("Enter tpci_ioctl\n"); - - inparms = NULL; - outparms = NULL; - rc = 0; - - if (copy_from_user(&tif, (void *)l, sizeof(tif))) { - /* Bad address */ - return (-EFAULT); - } - - /* - * Setup inparms and outparms as needed - */ - if (tif.in_len > 0) { - inparms = (caddr_t *) kmalloc(tif.in_len, GFP_KERNEL); - if (!inparms) { - return (-ENOMEM); - } - - rc = copy_from_user(inparms, tif.in_data, tif.in_len); - if (rc) { - kfree(inparms); - return (-EFAULT); - } - } - if (tif.out_len > 0) { - outparms = (caddr_t *) kmalloc(tif.out_len, GFP_KERNEL); - if (!outparms) { - kfree(inparms); - return (-ENOMEM); - } - } - - /* - * determine which call to make on the cmd value - */ - switch (cmd) { - case PCI_PROBE: - rc = probe_pci_dev(); - break; - case PCI_ENABLE: - rc = pci_enable(); - break; - case PCI_DISABLE: - rc = pci_disable(); - break; - case FIND_BUS: - rc = test_find_bus(); - break; - case FIND_CLASS: - rc = test_find_class(); - break; - case FIND_DEVICE: - rc = test_find_device(); - break; - case FIND_SUBSYS: - rc = test_find_subsys(); - break; - case BUS_SCAN: - rc = test_scan_bus(); - break; - case SLOT_SCAN: - rc = test_slot_scan(); - break; - case BUS_ADD_DEVICES: - rc = test_bus_add_devices(); - break; - case ENABLE_BRIDGES: - rc = test_enable_bridges(); - break; - case MATCH_DEVICE: - rc = test_match_device(); - break; - case REG_DRIVER: - rc = test_reg_driver(); - break; - case UNREG_DRIVER: - rc = test_unreg_driver(); - break; - case PCI_RESOURCES: - rc = test_assign_resources(); - break; - case SAVE_STATE: - rc = test_save_state(); - break; - case RESTORE_STATE: - rc = test_restore_state(); - break; - case TEST_MAX_BUS: - rc = test_max_bus(); - break; - case FIND_CAP: - rc = test_find_cap(); - break; - case FIND_PCI_EXP_CAP: - rc = test_find_pci_exp_cap(); - break; - case READ_PCI_EXP_CONFIG: - rc = test_read_pci_exp_config(); - break; - default: - printk("Mismatching ioctl command\n"); - break; - } - - if (!(ltp_pci.dev)) - printk("tpci: After ioctl call dev is NULL\n"); - - /* - * copy in the return data, and test return code - */ - tif.out_rc = rc; - rc = 0; - - /* if outparms then copy outparms into tif.out_data */ - if (outparms) { - if (copy_to_user(tif.out_data, outparms, tif.out_len)) { - printk("tpci: Unsuccessful copy_to_user of outparms\n"); - rc = -EFAULT; - } - } - - /* copy tif structure into l so that can be used by user program */ - if (copy_to_user((void *)l, &tif, sizeof(tif))) { - printk("tpci: Unsuccessful copy_to_user of tif\n"); - rc = -EFAULT; - } - - /* - * free inparms and outparms - */ - if (inparms) { - kfree(inparms); - } - if (outparms) { - kfree(outparms); - } - - return rc; -} - -/* - * probe_pci_dev - * find a pci device that can be used for other test - * calls in this kernel module, select first device - * that finds for use, do not need a specific device - */ -static int probe_pci_dev() -{ - unsigned int i, j; - struct pci_dev *dev = - (struct pci_dev *)kmalloc(sizeof(struct pci_dev), GFP_KERNEL); - struct pci_bus *bus = - (struct pci_bus *)kmalloc(sizeof(struct pci_bus), GFP_KERNEL); - - /* Zero out the ltp_pci */ - memset(<p_pci, 0, sizeof(tpci_user_t)); - - ltp_pci.dev = dev; - ltp_pci.bus = bus; - - /* Probe until find a pci device */ - for (i = MAX_BUS; i > 0; i--) { - for (j = MAX_DEVFN; j > 1; j--) { - dev = pci_find_slot(i, j); - if (dev && dev->driver) { - printk - ("tpci: found pci_dev, bus %d, devfn %d\n", - i, j); - printk("Slot number: %d\n", dev->devfn); - - bus = dev->bus; - printk("Bus number: %d\n", bus->number); - - /* copy data into ltp_pci struct */ - memcpy(ltp_pci.dev, dev, - sizeof(struct pci_dev)); - memcpy(ltp_pci.bus, bus, - sizeof(struct pci_bus)); - - return 0; - } - } - } - - /* if reaches here did not find a pci device */ - printk("tpci: failed to find pci device\n"); - return 1; -} - -/* - * pci_enable - * enable a pci device so that it may be used in - * later testing in the user test program - */ -static int pci_enable() -{ - int rc = 0; - - struct pci_dev *dev = ltp_pci.dev; - - /* check if can enable the device pointer */ - if (!dev) { - printk("tpci: dev is NULL\n"); - return 1; - } - - if (pci_enable_device(dev)) { - printk("tpci: failed to enable pci device\n"); - rc = 1; - } else { - printk("tpci: enabled pci device\n"); - rc = 0; - } - - return rc; -} - -/* - * pci_disable - * call to pci_disable_device - */ -static int pci_disable() -{ - int rc = 0; - - struct pci_dev *dev = ltp_pci.dev; - - /* check if device pointer exists */ - if (!dev) { - printk("tpci: dev is NULL\n"); - return 1; - } - - pci_disable_device(dev); - - if (dev->current_state == 4 || dev->current_state == 3) { - printk("tpci: disabled pci device\n"); - rc = 0; - } else { - printk("tpci: failed to disable pci device\n"); - rc = 1; - } - - return rc; -} - -/* - * find_bus - * call to pci_find_bus, use values from bus - * pointer in ltp_pci, make sure that returns - * bus with same values - */ -static int test_find_bus() -{ - int rc; - int num = ltp_pci.bus->number; - struct pci_bus *temp = NULL; - - temp = pci_find_bus(num); - - if (!temp) { - printk("tpci: pci_find_bus failed to return bus pointer\n"); - rc = 1; - } else if (temp->number != num) { - printk("tpci: returned bus pointer w/ wrong bus number\n"); - rc = 1; - } else { - printk("tpci: success returned bus pointer \n"); - rc = 0; - } - - return rc; -} - -/* - * find_class - * call to pci_find_class, using values from the - * pci_dev pointer in ltp_pci structure - */ -static int test_find_class() -{ - int rc; - unsigned int num = ltp_pci.dev->class; - struct pci_dev *temp = NULL; - - temp = pci_find_class(num, NULL); - - if (!temp) { - printk("tpci: failed to find pci device from class number\n"); - rc = 1; - } else { - printk("tpci: found pci device from class number\n"); - rc = 0; - } - - return rc; -} - -/* - * find_device - * call to pci_find_device, using values for - * parameters from pci_dev pointer in the - * ltp_pci structure - */ -static int test_find_device() -{ - int rc; - struct pci_dev *temp = NULL; - unsigned short ven = ltp_pci.dev->vendor, dev = ltp_pci.dev->device; - - temp = pci_find_device(ven, dev, NULL); - - if (!temp) { - printk("tpci: failed to find pci device from device info\n"); - rc = 1; - } else { - printk("tpci: found pci device from device info\n"); - rc = 0; - } - - return rc; -} - -/* - * find_subsys - * call to pci_find_subsys, use valued from - * pci_dev pointer in ltp_pci structure to - * find pci_dev from subsys info - */ -static int test_find_subsys() -{ - int rc; - struct pci_dev *temp = NULL; - unsigned short ven = ltp_pci.dev->vendor, - dev = ltp_pci.dev->device, - ss_ven = ltp_pci.dev->subsystem_vendor, - ss_dev = ltp_pci.dev->subsystem_device; - - temp = pci_find_subsys(ven, dev, ss_ven, ss_dev, NULL); - - if (!temp) { - printk("tpci: failed to find pci device from subsys info\n"); - rc = 1; - } else { - printk("tpci: found pci device from subsys info\n"); - rc = 0; - } - - return rc; -} - -/* - * test_scan_bus - * call to pci_do_scan_bus, which takes - * a struct pci_bus pointer, which will - * return a an integer for how far the - * function got in scanning bus - */ -static int test_scan_bus() -{ - int rc, num; - struct pci_bus *bus = ltp_pci.bus; - - num = pci_do_scan_bus(bus); - - /* - * check if returned number is greater than - * max number of bus or less than 0 - */ - if (num > MAX_BUS || num < 0) { - printk("tpci: Failed scan bus\n"); - rc = 1; - } else { - printk("tpci: Success scan bus\n"); - rc = 0; - } - - return rc; -} - -/* - * test_slot_scan - * make call to pci_scan_slot, which will - * find the device pointer and setup the - * device info - */ -static int test_slot_scan() -{ - int rc, ret; - int num = ltp_pci.dev->devfn; - struct pci_bus *bus = ltp_pci.bus; - - ret = pci_scan_slot(bus, num); - - if (ret > 0) { - printk("tpci: Found device from scan slot\n"); - rc = 0; - } else { - printk("tpci: Failed find device from scan slot\n"); - rc = 1; - } - - return rc; -} - -/* - * test_bus_add_devices - * make call to pci_bus_add_devices, - * which will check the device pointer - * that is passed in for more devices - * that it can add - */ -static int test_bus_add_devices() -{ - int rc; - struct pci_bus *bus = ltp_pci.bus; - - pci_bus_add_devices(bus); - - if (bus) { - printk("tpci: Called bus_add_device\n"); - rc = 0; - } else { - printk("tpci: bus_add_device failed\n"); - rc = 1; - } - - return rc; -} - -/* - * test_enable_bridges - * make call to pci_enable_bridges, - * use bus pointer from the ltp_pci - * structure - */ -static int test_enable_bridges() -{ - int rc; - struct pci_bus *bus = ltp_pci.bus; - - pci_enable_bridges(bus); - - if (bus) { - printk("tpci: Called enable bridges\n"); - rc = 0; - } else { - printk("tpci: enable_bridges failed\n"); - rc = 1; - } - - return rc; -} - -/* - * test_match_device - * make call to pci_match_device, returns a - * pci_device_id pointer - */ -static int test_match_device() -{ - int rc; - struct pci_dev *dev = ltp_pci.dev; - struct pci_driver *drv; - const struct pci_device_id *id; - - drv = pci_dev_driver(dev); - - if (!drv) { - printk("driver pointer not allocated for pci_dev\n"); - return 1; - } - - id = pci_match_device(drv->id_table, dev); - - if (id) { - printk("tpci: Match device success\n"); - rc = 0; - } else { - printk("tpci: Failed return pci_device_id \n"); - rc = 1; - } - - return rc; -} - -/* - * test_reg_driver - * make call to pci_register_driver, which will - * register the driver for a device with the - * system - */ -static int test_reg_driver() -{ - int rc, ret; - struct pci_driver *drv = - (struct pci_driver *)kmalloc(sizeof(struct pci_driver), GFP_KERNEL); - struct pci_driver *tmp = ltp_pci.dev->driver; - - /* zero out drv structure */ - memset(drv, 0, sizeof(struct pci_driver)); - - /* copy in structure of tmp, reset some fields */ - drv->name = "Tmod_driver"; - drv->driver = tmp->driver; - - /* copy structure into ltp_pci.drv */ - ltp_pci.drv = drv; - memcpy(ltp_pci.drv, drv, sizeof(struct pci_driver)); - - if (!drv) { - printk("tpci: Device does not have a driver pointer\n"); - return 1; - } - - ret = pci_register_driver(drv); - - if (ret) { - printk("tpci: Success driver register\n"); - rc = 0; - } else { - rc = 1; - printk("tpci: unsuccessful registering pci driver\n"); - } - - return rc; -} - -/* - * test_unreg_driver - * make call to pci_unregister_driver, which will - * unregister the driver for a device from the system - */ -static int test_unreg_driver() -{ - int rc; - struct pci_driver *drv = ltp_pci.drv; - - if (!drv) { - printk("tpci: Device does not have a driver pointer\n"); - return 1; - } - - pci_unregister_driver(drv); - if (!drv) { - printk("tpci: Unsuccesful driver unregister\n"); - rc = 1; - } else { - printk("tpci: unregistering pci driver\n"); - rc = 0; - } - - return rc; -} - -/* - * test_assign_resources - * make calls to pci_assign_resource, will need - * to setup a dev pointer and resource pointer, - */ -static int test_assign_resources() -{ - int rc; - struct pci_dev *dev = ltp_pci.dev; - int resno; - - for (resno = 0; resno < 7; resno++) { - struct resource *r = dev->resource + resno; - if (r->flags) - pci_assign_resource(dev, resno); - } - - /* - * enable device after call to assign resource - * because might error if (!r->start && r->end) - */ - rc = pci_enable_device(dev); - - return rc; -} - -/* - * test_save_state - * make call to pci_save_state, takes in a u32* - * buffer - */ -static int test_save_state() -{ - int rc; - u32 *buffer = ltp_pci.state; - struct pci_dev *dev = ltp_pci.dev; - - rc = pci_save_state(dev, buffer); - if (rc) - printk("tpci: Failed save state\n"); - else - printk("tpci: Saved state of device\n"); - - return rc; -} - -/* - * test_restore_state - * make call to pci_restore_state, get the state buffer - * should have been previously filled out by save state - */ -static int test_restore_state() -{ - int rc; - u32 *buffer = ltp_pci.state; - struct pci_dev *dev = ltp_pci.dev; - - rc = pci_restore_state(dev, buffer); - if (rc) - printk("tpci: Failed restore state\n"); - else - printk("tpci: Restored state of device\n"); - - return rc; -} - -/* - * test_max_bus - * make call to pci_max_busnr, which will determine - * the max number of bus on the system - */ -static int test_max_bus() -{ - int rc, ret; - - ret = pci_max_busnr(); - if (ret) { - printk("Found max busnr\n"); - rc = 0; - } else { - printk("Did not return max busnr\n"); - rc = 1; - } - - return rc; -} - -/* - * test_find_cap - * make call to pci_find_capability, which - * will determine if a device has a certain - * capability, use second parameter to specify - * which capability you are looking for - */ -static int test_find_cap() -{ - int rc; - struct pci_dev *dev = ltp_pci.dev; - - rc = pci_find_capability(dev, PCI_CAP_ID_PM); - if (rc) - printk("tpci: Does not have tested capability\n"); - else - printk("tpci: Device has PM capability\n"); - - return rc; -} - -/* - * test_find_pci_exp_cap - * make call to pci_find_capability, which will - * determine if a device has PCI-EXPRESS capability, - * use second parameter to specify which capability - * you are looking for - */ -static int test_find_pci_exp_cap() -{ - int rc; - struct pci_dev *dev = ltp_pci.dev; - - rc = pci_find_capability(dev, PCI_CAP_ID_EXP); - if (rc) - printk("tpci: Device has PCI-EXP capability\n"); - else - printk("tpci: Device doesn't have PCI-EXP capability\n"); - return rc; -} - -/* - * test_read_pci_exp_config - * make call to pci_config_read and determine if - * the PCI-Express enhanced config space of this - * device can be read successfully. - */ -static int test_read_pci_exp_config() -{ - int rc; - int reg = 100, len = 4; /*PCI-Exp enhanced config register 0x100, 4 implies dword access */ - struct pci_dev *dev = ltp_pci.dev; - - u32 data, *value; - - printk("tpci: Device(%d) on bus(%d) & slot(%d) \n", dev, - dev->bus->number, dev->devfn); - printk("tpci: Reading the PCI Express configuration registers---\n"); - - printk - ("tpci: Reading PCI-Express AER CAP-ID REGISTER at Enh-Cfg AddrSpace 0x100\n"); - - rc = pci_config_read(0, dev->bus->number, PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn), reg, len, &data); - - *value = (u32) data; - - if (*value == AER_CAP_ID_VALUE) /*comparing the value read with AER_CAP_ID_VALUE macro */ - printk - ("tpci: \nCorrect value read using PCI-Express driver installed\n\n"); - else - printk - ("tpci: \nIncorrect value read. PCI-Express driver/device not installed\n\n"); - - return rc; -} - -/* - * tpci_init_module - * set the owner of tpci_fops, register the module - * as a char device, and perform any necessary - * initialization for pci devices - */ -static int tpci_init_module(void) -{ - int rc; - - SET_MODULE_OWNER(&tpci_fops); - - rc = register_chrdev(Major, DEVICE_NAME, &tpci_fops); - if (rc < 0) { - printk("tpci: Failed to register device.\n"); - return rc; - } - - if (Major == 0) - Major = rc; - - printk("tpci: Registration success.\n"); - return 0; -} - -/* - * tpci_exit_module - * unregister the device and any necessary - * operations to close for pci devices - */ -static void tpci_exit_module(void) -{ - int rc; - - kfree(ltp_pci.dev); - kfree(ltp_pci.bus); - kfree(ltp_pci.drv); - - rc = unregister_chrdev(Major, DEVICE_NAME); - if (rc < 0) - printk("tpci: unregister failed\n"); - else - printk("tpci: unregister success\n"); - -} - -module_init(tpci_init_module) - module_exit(tpci_exit_module) diff --git a/testcases/kernel/device-drivers/pci/tpci/tpci.h b/testcases/kernel/device-drivers/pci/tpci/tpci.h deleted file mode 100644 index bd81369..0000000 --- a/testcases/kernel/device-drivers/pci/tpci/tpci.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * Copyright (c) International Business Machines Corp., 2001 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#define TPCI_TEST_DRIVER_NAME "pci/pci-express test module" -#define TPCI_MAJOR 252 -#define DEVICE_NAME "/dev/tpci" -#define MAX_DEVFN 256 -#define MAX_BUS 256 -#define MAG_NUM 'k' -#define AER_CAP_ID_VALUE 0x14011 - -#define PCI_PROBE _IO(MAG_NUM, 1) -#define PCI_ENABLE _IO(MAG_NUM, 2) -#define PCI_DISABLE _IO(MAG_NUM, 3) -#define FIND_BUS _IO(MAG_NUM, 4) -#define FIND_DEVICE _IO(MAG_NUM, 5) -#define FIND_CLASS _IO(MAG_NUM, 6) -#define FIND_SUBSYS _IO(MAG_NUM, 7) -#define BUS_SCAN _IO(MAG_NUM, 8) -#define SLOT_SCAN _IO(MAG_NUM, 9) -#define ENABLE_BRIDGES _IO(MAG_NUM, 10) -#define BUS_ADD_DEVICES _IO(MAG_NUM, 11) -#define MATCH_DEVICE _IO(MAG_NUM, 12) -#define REG_DRIVER _IO(MAG_NUM, 13) -#define UNREG_DRIVER _IO(MAG_NUM, 14) -#define BUS_RESOURCES _IO(MAG_NUM, 15) -#define PCI_RESOURCES _IO(MAG_NUM, 16) -#define SAVE_STATE _IO(MAG_NUM, 19) -#define RESTORE_STATE _IO(MAG_NUM, 20) -#define TEST_MAX_BUS _IO(MAG_NUM, 21) -#define FIND_CAP _IO(MAG_NUM, 22) -#define FIND_PCI_EXP_CAP _IO(MAG_NUM, 23) -#define READ_PCI_EXP_CONFIG _IO(MAG_NUM, 24) -#ifndef SET_MODULE_OWNER -#define SET_MODULE_OWNER(dev) ((dev)->owner = THIS_MODULE) -#endif - -/* - * structures for PCI test driver - */ -struct tpci_interface { - int in_len; // input data length - caddr_t in_data; // input data - int out_rc; // return code from the test - int out_len; // output data length - caddr_t out_data; // output data -}; -typedef struct tpci_interface tpci_interface_t; - - diff --git a/testcases/kernel/device-drivers/pci/tpci/tpci.mod.c b/testcases/kernel/device-drivers/pci/tpci/tpci.mod.c deleted file mode 100644 index 0301727..0000000 --- a/testcases/kernel/device-drivers/pci/tpci/tpci.mod.c +++ /dev/null @@ -1,29 +0,0 @@ -#include <linux/module.h> -/* - * - * Copyright (c) International Business Machines Corp., 2001 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * -*/ -#include <linux/module.h> -#include <linux/vermagic.h> -#include <linux/compiler.h> - -const char vermagic[] - __attribute__ ((section("__vermagic"))) = VERMAGIC_STRING; - -static const char __module_depends[] - __attribute_used__ __attribute__ ((section(".modinfo"))) = "depends="; diff --git a/testcases/kernel/device-drivers/pci/tpci_kernel/.gitignore b/testcases/kernel/device-drivers/pci/tpci_kernel/.gitignore new file mode 100644 index 0000000..3e100ad --- /dev/null +++ b/testcases/kernel/device-drivers/pci/tpci_kernel/.gitignore @@ -0,0 +1,7 @@ +/ltp_tpci.ko +/*.mod.c +/modules.order +/.tmp_versions +/.*.ko +/.*.cmd +/Module.symvers diff --git a/testcases/kernel/device-drivers/pci/tpci_kernel/Makefile b/testcases/kernel/device-drivers/pci/tpci_kernel/Makefile new file mode 100644 index 0000000..02496af --- /dev/null +++ b/testcases/kernel/device-drivers/pci/tpci_kernel/Makefile @@ -0,0 +1,35 @@ +# Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +ifneq ($(KERNELRELEASE),) + +obj-m := ltp_tpci.o + +else + +top_srcdir ?= ../../../../.. + +include $(top_srcdir)/include/mk/env_pre.mk + +REQ_VERSION_MAJOR := 2 +REQ_VERSION_PATCH := 6 + +MAKE_TARGETS := ltp_tpci.ko + +include $(top_srcdir)/include/mk/module.mk +include $(top_srcdir)/include/mk/generic_leaf_target.mk + +endif \ No newline at end of file diff --git a/testcases/kernel/device-drivers/pci/tpci_kernel/ltp_tpci.c b/testcases/kernel/device-drivers/pci/tpci_kernel/ltp_tpci.c new file mode 100644 index 0000000..4e92f5e --- /dev/null +++ b/testcases/kernel/device-drivers/pci/tpci_kernel/ltp_tpci.c @@ -0,0 +1,787 @@ +/* + * Copyright (c) International Business Machines Corp., 2001 + * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * This pci and pci-express testing kernel module will allow test calls + * to be driven through various ioctl calls in a + * user space program that has attained the appropriate + * file descriptor for this device. For the functions of + * this module to work correctly there must be a pci / pci-express + * device somewhere in the system. The tests do not need + * a specific device, and the first pci device available + * will be grabbed. + * + * author: Sean Ruyle (sr...@us...) + * date: 5/20/2003 + * PCI-Express test scripts author: Amit Khanna (ami...@in...) + * date: 8/20/2004 + * + * file: tpci.c, + * module: tpci + */ + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/fs.h> +#include <linux/ioctl.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/pci.h> + +#include "tpci.h" + +MODULE_AUTHOR("Sean Ruyle <sr...@us...>"); +MODULE_AUTHOR("Amit Khanna <ami...@in...>"); +MODULE_AUTHOR("Copyright (c) 2013 Oracle and/or its affiliates"); +MODULE_DESCRIPTION("LTP PCI Test"); +MODULE_LICENSE("GPL"); + +#define prk_err(fmt, ...) \ + pr_err(PCI_DEVICE_NAME ": " fmt "\n", ##__VA_ARGS__) +#define prk_info(fmt, ...) \ + pr_info(PCI_DEVICE_NAME ": " fmt "\n", ##__VA_ARGS__) +#define prk_debug(fmt, ...) \ + pr_debug(PCI_DEVICE_NAME ": " fmt "\n", ##__VA_ARGS__) + +#define TPASS 0 +#define TFAIL 1 +#define TSKIP 32 + +static DEFINE_PCI_DEVICE_TABLE(ltp_pci_tbl) = { + { PCI_DEVICE(PCI_ANY_ID, PCI_ANY_ID) }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, ltp_pci_tbl); + +static int ltp_pci_probe(struct pci_dev *pci_dev, + const struct pci_device_id *pci_ent) +{ + return 0; +} + +static struct pci_driver ltp_pci_driver = { + .name = "LTP_PCI_DRIVER", + .id_table = ltp_pci_tbl, + .probe = ltp_pci_probe, +}; + +static int pci_registered; + +struct tpci_user { + struct pci_dev *dev; + struct pci_bus *bus; + struct pci_driver *drv; + uint32_t state[16]; +}; +static struct tpci_user ltp_pci; + +/* + * probe_pci_dev + * find a pci device that can be used for other test + * calls in this kernel module. + */ +static int probe_pci_dev(unsigned int bus, unsigned int slot) +{ + struct pci_dev *dev; + + prk_info("find arbitrary pci device for test"); + + if (ltp_pci.dev) { + pci_dev_put(ltp_pci.dev); + ltp_pci.dev = NULL; + } + + dev = pci_get_bus_and_slot(bus, slot); + if (!dev || !dev->driver) + return -ENODEV; + + prk_info("found pci_dev '%s', bus %u, devfn %u", + pci_name(dev), bus, slot); + + ltp_pci.dev = dev; + ltp_pci.bus = dev->bus; + prk_info("Bus number: %d", dev->bus->number); + return 0; +} + +/* + * pci_enable + * enable a pci device so that it may be used in + * later testing in the user test program + */ +static int pci_enable(void) +{ + struct pci_dev *dev = ltp_pci.dev; + + prk_info("enable pci device"); + + /* check if can enable the device pointer */ + if (!dev) { + prk_err("dev is NULL"); + return TFAIL; + } + + if (pci_enable_device(dev)) { + prk_err("failed to enable pci device"); + return TFAIL; + } + + prk_info("enabled pci device"); + return TPASS; +} + +static int pci_disable(void) +{ + struct pci_dev *dev = ltp_pci.dev; + + prk_info("disable pci device"); + + /* check if device pointer exists */ + if (!dev) { + prk_err("dev is NULL"); + return TFAIL; + } + + prk_info("is pci enabled '%d', is managed '%d'", + pci_is_enabled(dev), pci_is_managed(dev)); + + pci_release_regions(dev); + pci_disable_device(dev); + + if (dev->current_state == PCI_D3hot || + dev->current_state == PCI_D3cold) { + + prk_info("disabled pci device, state '%s'", + pci_power_name(dev->current_state)); + return TPASS; + + } + + prk_err("failed to disable pci device, state '%s'", + pci_power_name(dev->current_state)); + return TFAIL; +} + +/* + * find_bus + * call to pci_find_bus, use values from bus + * pointer in ltp_pci, make sure that returns + * bus with same values + */ +static int test_find_bus(void) +{ + int num = ltp_pci.bus->number; + struct pci_bus *temp = NULL; + + prk_info("find bus"); + + temp = pci_find_bus(pci_domain_nr(ltp_pci.bus), num); + + if (!temp) { + prk_info("pci_find_bus failed"); + return TFAIL; + } else if (temp->number != num) { + prk_err("returned bus pointer w/ wrong bus number"); + return TFAIL; + } + + prk_info("success returned bus pointer"); + return TPASS; +} + +/* + * find_class + * call to pci_find_class, using values from the + * pci_dev pointer in ltp_pci structure + */ +static int test_find_class(void) +{ + unsigned int num = ltp_pci.dev->class; + struct pci_dev *temp = NULL; + + prk_info("find pci class"); + + temp = pci_get_class(num, NULL); + + if (!temp) { + prk_err("failed to find pci device from class number"); + return TFAIL; + } + + prk_info("found pci device from class number"); + pci_dev_put(temp); + + return TPASS; +} + +/* + * find_device + * call to pci_find_device, using values for + * parameters from pci_dev pointer in the + * ltp_pci structure + */ +static int test_find_device(void) +{ + struct pci_dev *temp = NULL; + unsigned short ven = ltp_pci.dev->vendor, dev = ltp_pci.dev->device; + + prk_info("get pci device"); + + temp = pci_get_device(ven, dev, NULL); + + if (!temp) { + prk_err("failed to find pci device from device info"); + return TFAIL; + } + + prk_info("found pci device from device info"); + pci_dev_put(temp); + + return TPASS; +} + +/* + * find_subsys + * call to pci_find_subsys, use valued from + * pci_dev pointer in ltp_pci structure to + * find pci_dev from subsys info + */ +static int test_find_subsys(void) +{ + struct pci_dev *temp; + unsigned short ven = ltp_pci.dev->vendor, + dev = ltp_pci.dev->device, + ss_ven = ltp_pci.dev->subsystem_vendor, + ss_dev = ltp_pci.dev->subsystem_device; + + prk_info("get pci subsys"); + temp = pci_get_subsys(ven, dev, ss_ven, ss_dev, NULL); + + if (!temp) { + prk_err("failed to find pci device from subsys info"); + return TFAIL; + } + + prk_info("found pci device from subsys info"); + pci_dev_put(temp); + + return TPASS; +} + +/* + * test_scan_bus + * call to pci_do_scan_bus, which takes + * a struct pci_bus pointer, which will + * return an integer for how far the + * function got in scanning bus + */ +static int test_scan_bus(void) +{ +#ifdef CONFIG_HOTPLUG + int num; + struct pci_bus *bus = ltp_pci.bus; + + prk_info("scan pci bus"); + + num = pci_rescan_bus(bus); + /* + * check if returned number is greater than + * max number of bus or less than 0 + */ + if (num > MAX_BUS || num < 0) { + prk_err("failed scan bus"); + return TFAIL; + } + prk_info("success scan bus"); + return TPASS; +#else + prk_info("pci_rescan_bus() is not supported"); + return TSKIP; +#endif +} + +/* + * test_slot_scan + * make call to pci_scan_slot, which will + * find the device pointer and setup the + * device info + */ +static int test_slot_scan(void) +{ + int ret, num = ltp_pci.dev->devfn; + struct pci_bus *bus = ltp_pci.bus; + + prk_info("scan pci slot"); + + ret = pci_scan_slot(bus, num); + if (ret >= 0) { + prk_info("found '%d' devices from scan slot", ret); + return TPASS; + } + + prk_err("pci_scan_slot failed"); + return TFAIL; +} + +/* + * test_bus_add_devices + * make call to pci_bus_add_devices, + * which will check the device pointer + * that is passed in for more devices + * that it can add + */ +static int test_bus_add_devices(void) +{ + struct pci_bus *bus = ltp_pci.bus; + + prk_info("add bus device"); + + pci_bus_add_devices(bus); + + if (bus) { + prk_info("called bus_add_device"); + return TPASS; + } + + prk_err("bus_add_device failed"); + return TFAIL; +} + +/* + * test_enable_bridges + * make call to pci_enable_bridges, + * use bus pointer from the ltp_pci + * structure + */ +static int test_enable_bridges(void) +{ + struct pci_bus *bus = ltp_pci.bus; + + prk_info("enable bridges"); + + pci_enable_bridges(bus); + + if (bus) { + prk_info("called enable bridges"); + return TPASS; + } + + prk_err("enable_bridges failed"); + return TFAIL; +} + +/* + * test_match_device + * make call to pci_match_device, returns a + * pci_device_id pointer + */ +static int test_match_device(void) +{ + struct pci_dev *dev = ltp_pci.dev; + struct pci_driver *drv; + const struct pci_device_id *id; + + prk_info("test pci_device_id()"); + + drv = pci_dev_driver(dev); + + if (!drv) { + prk_err("driver pointer not allocated for pci_dev"); + return TFAIL; + } + + id = pci_match_id(drv->id_table, dev); + + if (id) { + prk_info("match device success"); + return TPASS; + } + + prk_err("failed return pci_device_id"); + return TFAIL; +} + + +/* + * test_reg_driver + * make call to pci_register_driver, which will + * register the driver for a device with the + * system + */ +static int test_reg_driver(void) +{ + prk_info("test pci_register_driver"); + if (pci_register_driver(<p_pci_driver)) { + prk_err("unsuccessful registering pci driver"); + return TFAIL; + } + pci_registered = 1; + prk_info("success driver register"); + return TPASS; +} + +/* + * test_unreg_driver + * make call to pci_unregister_driver, which will + * unregister the driver for a device from the system + */ +static int test_unreg_driver(void) +{ + pci_unregister_driver(<p_pci_driver); + pci_registered = 0; + return TPASS; +} + +/* + * test_assign_resources + * make calls to pci_assign_resource, will need + * to setup a dev pointer and resource pointer, + */ +static int test_assign_resources(void) +{ + int i, ret, rc = 0; + struct pci_dev *dev = ltp_pci.dev; + struct resource *r; + + prk_info("assign resources"); + + for (i = 0; i < 7; ++i) { + prk_info("assign resource #%d", i); + r = &dev->resource[i]; + prk_info("name = %s, flags = %lu, start 0x%lx, end 0x%lx", + r->name, r->flags, + (unsigned long)r->start, (unsigned long)r->end); + + if ((r->flags & IORESOURCE_MEM) == IORESOURCE_MEM) { + ret = pci_assign_resource(dev, i); + prk_info("assign resource to '%d', ret '%d'", i, ret); + rc |= (ret < 0 && ret != -EBUSY) ? TFAIL : TPASS; + } + } + + /* + * enable device after call to assign resource + * because might error if (!r->start && r->end) + */ + if (pci_enable_device(dev)) + return TFAIL; + + return rc; +} + +/* + * test_save_state + * make call to pci_save_state, takes in a u32* + * buffer + */ +static int test_save_state(void) +{ + struct pci_dev *dev = ltp_pci.dev; + + prk_info("save state"); + + if (pci_save_state(dev)) { + prk_err("failed save state"); + return TFAIL; + } + + prk_info("saved state of device"); + return TPASS; +} + +/* + * test_restore_state + * make call to pci_restore_state, get the state buffer + * should have been previously filled out by save state + */ +static int test_restore_state(void) +{ + struct pci_dev *dev = ltp_pci.dev; + + prk_info("restore state"); + + pci_restore_state(dev); + + return TPASS; +} + +/* + * test_find_cap + * make call to pci_find_capability, which + * will determine if a device has a certain + * capability, use second parameter to specify + * which capability you are looking for + */ +static int test_find_cap(void) +{ + struct pci_dev *dev = ltp_pci.dev; + + prk_info("find device capability"); + + if (pci_find_capability(dev, PCI_CAP_ID_PM)) + prk_info("does not have tested capability"); + else + prk_info("device has PM capability"); + + return TPASS; +} + +/* + * test_find_pci_exp_cap + * make call to pci_find_capability, which will + * determine if a device has PCI-EXPRESS capability, + * use second parameter to specify which capability + * you are looking for + */ +static int test_find_pci_exp_cap(void) +{ + struct pci_dev *dev = ltp_pci.dev; + + prk_info("find PCIe capability"); + + if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { + prk_info("device has PCI-EXP capability"); + return TPASS; + } + + prk_info("device doesn't have PCI-EXP capability"); + return TFAIL; +} + +/* + * test_read_pci_exp_config + * make call to pci_config_read and determine if + * the PCI-Express enhanced config space of this + * device can be read successfully. + */ +static int test_read_pci_exp_config(void) +{ + /* PCI-Exp enhanced config register 0x100, 4 implies dword access */ + int reg = 100; + struct pci_dev *dev = ltp_pci.dev; + u32 data; + + /* skip the test if device doesn't have PCIe capability */ + if (test_find_pci_exp_cap() == TFAIL) + return TSKIP; + + prk_info("dev on bus(%d) & slot (%d)", dev->bus->number, dev->devfn); + prk_info("reading the PCI Express configuration registers---"); + prk_info("reading PCI-Express AER CAP-ID REGISTER at Enh-Cfg AddrSpace 0x100"); + + if (pci_read_config_dword(dev, reg, &data)) { + prk_err("failed to read config word"); + return TFAIL; + } + + /* comparing the value read with AER_CAP_ID_VALUE macro */ + if (data == AER_CAP_ID_VALUE) { + prk_info("correct val read using PCIE driver installed: '%u'", + data); + return TPASS; + } + + prk_err("incorrect val read. PCIE driver/device not installed: '%u'", + data); + return TFAIL; +} + + +static int test_case(unsigned int cmd) +{ + int rc = TSKIP; + + switch (cmd) { + case PCI_ENABLE: + rc = pci_enable(); + break; + case PCI_DISABLE: + rc = pci_disable(); + break; + case FIND_BUS: + rc = test_find_bus(); + break; + case FIND_CLASS: + rc = test_find_class(); + break; + case FIND_DEVICE: + rc = test_find_device(); + break; + case FIND_SUBSYS: + rc = test_find_subsys(); + break; + case BUS_SCAN: + rc = test_scan_bus(); + break; + case SLOT_SCAN: + rc = test_slot_scan(); + break; + case BUS_ADD_DEVICES: + rc = test_bus_add_devices(); + break; + case ENABLE_BRIDGES: + rc = test_enable_bridges(); + break; + case MATCH_DEVICE: + rc = test_match_device(); + break; + case REG_DRIVER: + rc = test_reg_driver(); + break; + case UNREG_DRIVER: + rc = test_unreg_driver(); + break; + case PCI_RESOURCES: + rc = test_assign_resources(); + break; + case SAVE_STATE: + rc = test_save_state(); + break; + case RESTORE_STATE: + rc = test_restore_state(); + break; + case FIND_CAP: + rc = test_find_cap(); + break; + case PCI_EXP_CAP_CONFIG: + rc = test_read_pci_exp_config(); + break; + default: + prk_info("mismatching test-case command %d", cmd); + break; + } + + return rc; +} + +/* + * Test-case result, + * if test is passed, value will be set to 0 + */ +static int test_result; + +static void device_release(struct device *dev) +{ + prk_info("device released\n"); +} + +static struct device tdev = { + .init_name = PCI_DEVICE_NAME, + .release = device_release, +}; + +/* print test result to sysfs file */ +static ssize_t sys_result(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d\n", test_result); +} +static DEVICE_ATTR(result, S_IRUSR, sys_result, NULL); + +static ssize_t sys_tcase(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int tc = 0; + + sscanf(buf, "%d", &tc); + prk_info("test-case %d", tc); + + test_result = test_case(tc); + + return count; +} +static DEVICE_ATTR(tcase, S_IWUSR, NULL, sys_tcase); + +static ssize_t sys_bus_slot(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + unsigned int res, bus, slot; + int ret; + + sscanf(buf, "%u", &res); + + bus = res >> 8 & 0xFF; + slot = res & 0xFF; + + prk_info("get bus '%u' slot '%u'", bus, slot); + + ret = probe_pci_dev(bus, slot); + if (ret) + return ret; + + return count; +} +static DEVICE_ATTR(bus_slot, S_IWUSR, NULL, sys_bus_slot); + +static int tpci_init_module(void) +{ + int err = 0; + prk_info("Starting module"); + + err = device_register(&tdev); + if (err) { + prk_err("Unable to register device"); + goto err0; + } + prk_info("device registered\n"); + + err = device_create_file(&tdev, &dev_attr_result); + if (err) { + prk_err("Can't create sysfs file 'result'"); + goto err1; + } + + err = device_create_file(&tdev, &dev_attr_tcase); + if (err) { + prk_err(": Can't create sysfs file 'tc'"); + goto err2; + } + + err = device_create_file(&tdev, &dev_attr_bus_slot); + if (err) { + prk_err(": Can't create sysfs file 'bus_slot'"); + goto err3; + } + + return 0; + +err3: + device_remove_file(&tdev, &dev_attr_tcase); +err2: + device_remove_file(&tdev, &dev_attr_result); +err1: + device_unregister(&tdev); +err0: + return err; +} +module_init(tpci_init_module) + +static void tpci_exit_module(void) +{ + prk_debug("Unloading module\n"); + if (ltp_pci.dev) + pci_dev_put(ltp_pci.dev); + + if (pci_registered) + pci_unregister_driver(<p_pci_driver); + + device_remove_file(&tdev, &dev_attr_result); + device_remove_file(&tdev, &dev_attr_tcase); + device_unregister(&tdev); +} +module_exit(tpci_exit_module) diff --git a/testcases/kernel/device-drivers/pci/tpci/pci-exp-tests-HOWTO b/testcases/kernel/device-drivers/pci/tpci_kernel/pci-exp-tests-HOWTO similarity index 100% rename from testcases/kernel/device-drivers/pci/tpci/pci-exp-tests-HOWTO rename to testcases/kernel/device-drivers/pci/tpci_kernel/pci-exp-tests-HOWTO diff --git a/testcases/kernel/device-drivers/pci/tpci_kernel/tpci.h b/testcases/kernel/device-drivers/pci/tpci_kernel/tpci.h new file mode 100644 index 0000000..d5ee669 --- /dev/null +++ b/testcases/kernel/device-drivers/pci/tpci_kernel/tpci.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) International Business Machines Corp., 2001 + * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define PCI_DEVICE_NAME "ltp_tpci" +#define MAX_DEVFN 256 +#define MAX_BUS 256 +#define AER_CAP_ID_VALUE 0x14011 + +enum PCI_TCASES { + PCI_DISABLE = 0, + PCI_ENABLE, + FIND_BUS, + FIND_DEVICE, + FIND_CLASS, + FIND_SUBSYS, + BUS_SCAN, + SLOT_SCAN, + ENABLE_BRIDGES, + BUS_ADD_DEVICES, + MATCH_DEVICE, + REG_DRIVER, + UNREG_DRIVER, + PCI_RESOURCES, + SAVE_STATE, + RESTORE_STATE, + FIND_CAP, + PCI_EXP_CAP_CONFIG, + PCI_TCASES_NUM, +}; diff --git a/testcases/kernel/device-drivers/pci/tpci_user/.gitignore b/testcases/kernel/device-drivers/pci/tpci_user/.gitignore new file mode 100644 index 0000000..b1817e5 --- /dev/null +++ b/testcases/kernel/device-drivers/pci/tpci_user/.gitignore @@ -0,0 +1 @@ +/tpci diff --git a/testcases/kernel/device-drivers/block/block_dev_user/Makefile b/testcases/kernel/device-drivers/pci/tpci_user/Makefile similarity index 100% copy from testcases/kernel/device-drivers/block/block_dev_user/Makefile copy to testcases/kernel/device-drivers/pci/tpci_user/Makefile diff --git a/testcases/kernel/device-drivers/pci/tpci_user/tpci.c b/testcases/kernel/device-drivers/pci/tpci_user/tpci.c new file mode 100644 index 0000000..f121a18 --- /dev/null +++ b/testcases/kernel/device-drivers/pci/tpci_user/tpci.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Alexey Kodanev <ale...@or...> + * + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include "test.h" +#include "usctest.h" +#include "safe_macros.h" +#include "tst_module.h" + +#include "../tpci_kernel/tpci.h" + +char *TCID = "test_pci"; +int TST_TOTAL = PCI_TCASES_NUM; + +static const char module_name[] = PCI_DEVICE_NAME ".ko"; +static const char dev_result[] = "/sys/devices/" PCI_DEVICE_NAME "/result"; +static const char dev_tcase[] = "/sys/devices/" PCI_DEVICE_NAME "/tcase"; +static const char dev_busslot[] = "/sys/devices/" PCI_DEVICE_NAME "/bus_slot"; +static int module_loaded; + +static void cleanup(void) +{ + if (module_loaded) + tst_module_unload(NULL, module_name); + + TEST_CLEANUP; +} + +void setup(int argc, char *argv[]) +{ + tst_require_root(NULL); + + if (tst_kvercmp(2, 6, 0) < 0) { + tst_brkm(TCONF, NULL, + "Test must be run with kernel 2.6 or newer"); + } + + tst_sig(FORK, DEF_HANDLER, cleanup); +} + +static void run_pci_testcases(int bus, int slot) +{ + int i, res; + for (i = 0; i < TST_TOTAL; ++i) { + /* skip pci disable test-case, it is manual */ + if (i == PCI_DISABLE) + continue; + + SAFE_FILE_PRINTF(cleanup, dev_tcase, "%d", i); + SAFE_FILE_SCANF(cleanup, dev_result, "%d", &res); + + tst_resm(res, "PCI bus %02x slot %02x : Test-case '%d'", + bus, slot, i); + } +} + +static void test_run(void) +{ + tst_module_load(cleanup, module_name, NULL); + module_loaded = 1; + + char buf[6]; + int i, j, fd, count; + + for (i = 0; i < MAX_BUS; ++i) { + for (j = 0; j < MAX_DEVFN; ++j) { + /* set pci device for the test */ + fd = SAFE_OPEN(cleanup, dev_busslot, O_WRONLY); + count = snprintf(buf, 6, "%u", i << 8 | j); + errno = 0; + if (write(fd, buf, count) < 0) { + if (errno == ENODEV) { + SAFE_CLOSE(cleanup, fd); + continue; + } + tst_brkm(TBROK | TERRNO, cleanup, + "write to '%s' failed", dev_busslot); + } + SAFE_CLOSE(cleanup, fd); + + run_pci_testcases(i, j); + + } + } +} + +int main(int argc, char *argv[]) +{ + setup(argc, argv); + + test_run(); + + cleanup(); + + tst_exit(); +} diff --git a/testcases/kernel/device-drivers/pci/user_tpci/Makefile b/testcases/kernel/device-drivers/pci/user_tpci/Makefile deleted file mode 100644 index 38ed3eb..0000000 --- a/testcases/kernel/device-drivers/pci/user_tpci/Makefile +++ /dev/null @@ -1,9 +0,0 @@ - -CFLAGS += -Wall -OBJS = tpci_ki.o user_tpci.o - -test_pci: $(OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ - -clean: - rm -f $(OBJS) test_pci diff --git a/testcases/kernel/device-drivers/pci/user_tpci/tpci_ki.c b/testcases/kernel/device-drivers/pci/user_tpci/tpci_ki.c deleted file mode 100644 index 91e1471..0000000 --- a/testcases/kernel/device-drivers/pci/user_tpci/tpci_ki.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * - * Copyright (c) International Business Machines Corp., 2001 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - - * This file will include user space functions that will drive - * the kernel module tpci to test various pci functions - * and kernel calls. Each function will need to setup the tif - * structure so that the in parameters and out parameters - * are correctly initialized - * - * use tif structure for passing params between user - * space and kernel space, in some tests it is really - * not needed but makes easy to maintain all tests if - * have the same process to read in params in the - * kernel module no matter what the test is - * - * author: Sean Ruyle (sr...@us...) - * date: 5/21/2003 - * - * tpci_ki.c - */ - -#include <stdlib.h> -#include <stdio.h> -#include <sys/ioctl.h> -#include "../tpci/tpci.h" - -int ki_generic(int fd, int flag) -{ - int rc; - tpci_interface_t tif; - - /* - * build interface structure - */ - tif.in_len = 0; - tif.in_data = 0; - tif.out_len = 0; - tif.out_data = 0; - tif.out_rc = 0; - - /* - * ioctl call for flag - */ - rc = ioctl(fd, flag, &tif); - if (rc) { - printf("Ioctl error\n"); - return rc; - } - if (tif.out_rc) { - printf("Specific errorr: "); - return tif.out_rc; - } - - return rc; -} - -#if 0 -int ki_probe_pci_dev(int fd) -{ - - int rc; - tpci_interface_t tif; - - /* - * build interface structure - */ - tif.in_len = 0; - tif.in_data = 0; - tif.out_len = 0; - tif.out_data = 0; - tif.out_rc = 0; - - /* - * ioctl call for PCI_PROBE - */ - rc = ioctl(fd, PCI_PROBE, &tif); - if (rc) { - printf("Ioctl error\n"); - return rc; - } - if (tif.out_rc) { - printf("Specific error in ioctl call\n"); - return tif.out_rc; - } - - return rc; -} - -int ki_enable_pci(int fd) -{ - - int rc; - tpci_interface_t tif; - - /* - * build interface structure - */ - tif.in_len = 0; - tif.in_data = 0; - tif.out_len = 0; - tif.out_data = 0; - tif.out_rc = 0; - - /* - * ioctl call for PCI_ENABLE - */ - rc = ioctl(fd, PCI_ENABLE, &tif); - if (rc) { - printf("Ioctl error\n"); - return rc; - } - if (tif.out_rc) { - printf("Specific error in ioctl call\n"); - return tif.out_rc; - } - - return rc; -} - -int ki_disable_pci(int fd) -{ - - int rc; - tpci_interface_t tif; - - /* - * build interface structure - */ - tif.in_len = 0; - tif.in_data = 0; - tif.out_len = 0; - tif.out_data = 0; - tif.out_rc = 0; - - /* - * ioctl call for PCI_DISABLE - */ - rc = ioctl(fd, PCI_DISABLE, &tif); - if (rc) { - printf("Ioctl error\n"); - return rc; - } - if (tif.out_rc) { - printf("Specific error in ioctl call\n"); - return tif.out_rc; - } - - return rc; -} - -int ki_find_bus(int fd) -{ - - int rc; - tpci_interface_t tif; - - /* - * build interface structure - */ - tif.in_len = 0; - tif.in_data = 0; - tif.out_len = 0; - tif.out_data = 0; - tif.out_rc = 0; - - /* - * ioctl call for PCI_DISABLE - */ - rc = ioctl(fd, FIND_BUS, &tif); - if (rc) { - printf("Ioctl error\n"); - return rc; - } - if (tif.out_rc) { - printf("Specific error in ioctl call\n"); - return tif.out_rc; - } - - return rc; -} - -#endif diff --git a/testcases/kernel/device-drivers/pci/user_tpci/user_tpci.c b/testcases/kernel/device-drivers/pci/user_tpci/user_tpci.c deleted file mode 100644 index 3d4cc45..0000000 --- a/testcases/kernel/device-drivers/pci/user_tpci/user_tpci.c +++ /dev/null @@ -1,258 +0,0 @@ -#include <stdio.h> -/* - * - * Copyright (c) International Business Machines Corp., 2001 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdio.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <errno.h> -#include <linux/kernel.h> -#include <linux/... [truncated message content] |