Initial load of pci testcases
diff --git a/testcases/kernel/device-drivers/pci/tpci/Makefile b/testcases/kernel/device-drivers/pci/tpci/Makefile
new file mode 100644
index 0000000..77c80ec
--- /dev/null
+++ b/testcases/kernel/device-drivers/pci/tpci/Makefile
@@ -0,0 +1,22 @@
+#
+# 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
new file mode 100644
index 0000000..1aef480
--- /dev/null
+++ b/testcases/kernel/device-drivers/pci/tpci/st_tpci.h
@@ -0,0 +1,9 @@
+//st_tpci.h
+
+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
new file mode 100644
index 0000000..1a6be03
--- /dev/null
+++ b/testcases/kernel/device-drivers/pci/tpci/tpci.c
@@ -0,0 +1,777 @@
+/*
+ * This pci 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
+ * 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 (srruyle@us.ibm.com)
+ * date: 5/20/2003
+ *
+ * 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 <srruyle@us.ibm.com>");
+MODULE_DESCRIPTION(PCI_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 Major = 0;
+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;
+ 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;
+}
+
+
+
+
+/*
+ * 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;
+
+ if(!pci_present())
+ printk("tpci: pci_present returned false\n");
+
+ 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
new file mode 100644
index 0000000..ad22554
--- /dev/null
+++ b/testcases/kernel/device-drivers/pci/tpci/tpci.h
@@ -0,0 +1,42 @@
+//tpci.h
+
+#define TPCI_TEST_DRIVER_NAME "pci test module"
+#define DEVICE_NAME "tpci"
+#define MAX_DEVFN 256
+#define MAX_BUS 256
+#define MAG_NUM 'k'
+
+#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)
+
+/*
+ * 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
new file mode 100644
index 0000000..ee03322
--- /dev/null
+++ b/testcases/kernel/device-drivers/pci/tpci/tpci.mod.c
@@ -0,0 +1,13 @@
+#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/user_tpci/Makefile b/testcases/kernel/device-drivers/pci/user_tpci/Makefile
new file mode 100644
index 0000000..0abb40c
--- /dev/null
+++ b/testcases/kernel/device-drivers/pci/user_tpci/Makefile
@@ -0,0 +1,8 @@
+test_pci: tpci_ki.o user_tpci.o
+ gcc tpci_ki.o user_tpci.o -o test_pci
+
+tpci_ki.o: tpci_ki.c
+ gcc -c tpci_ki.c
+
+user_tpci.o: user_tpci.c
+ gcc -c user_tpci.c
diff --git a/testcases/kernel/device-drivers/pci/user_tpci/tpci_ki.c b/testcases/kernel/device-drivers/pci/user_tpci/tpci_ki.c
new file mode 100644
index 0000000..c96a1c1
--- /dev/null
+++ b/testcases/kernel/device-drivers/pci/user_tpci/tpci_ki.c
@@ -0,0 +1,178 @@
+/*
+ * 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 (srruyle@us.ibm.com)
+ * 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
new file mode 100644
index 0000000..6f5fbcf
--- /dev/null
+++ b/testcases/kernel/device-drivers/pci/user_tpci/user_tpci.c
@@ -0,0 +1,175 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <linux/kernel.h>
+#include "user_tpci.h"
+#include "../tpci/tpci.h"
+
+static int tpci_fd = -1; /* file descriptor */
+
+int
+tpciopen() {
+ struct stat st;
+
+ if (stat("/dev/tpci", &st)) {
+ printf("\tERROR, Failed finding test pci kernel interface \n");
+ return (1);
+ }
+
+ if ((tpci_fd = open("/dev/tpci", O_RDWR)) < 0) {
+ printf("\tFailed opening test pci kernel interface \n");
+ return (1);
+ }
+
+ return 0;
+}
+
+int
+tpciclose() {
+
+ if (tpci_fd != -1) {
+ close (tpci_fd);
+ tpci_fd = -1;
+ }
+
+ return 0;
+}
+
+int main() {
+ int rc;
+
+ rc = tpciopen();
+ if (rc ) {
+ printf("Test PCI Driver may not be loaded\n");
+ exit(1);
+ }
+
+
+ /* test find pci */
+ if(ki_generic(tpci_fd, PCI_PROBE)) {
+ printf("Failed to find a pci device\n");
+ exit(1);
+ }
+ else
+ printf("Success probing for pci device\n");
+
+ /* test disable device */
+ if(ki_generic(tpci_fd, PCI_DISABLE))
+ printf("Failed to disable device \nMay still be in use by system\n");
+ else
+ printf("Disabled device\n");
+
+ /* test enable device */
+ if(ki_generic(tpci_fd, PCI_ENABLE))
+ printf("Failed to enable device\n");
+ else
+ printf("Enabled device\n");
+
+ /* test find from bus */
+ if(ki_generic(tpci_fd, FIND_BUS))
+ printf("Failed to find from bus pointer\n");
+ else
+ printf("Found device from bus pointer\n");
+
+ /* test find from device */
+ if(ki_generic(tpci_fd, FIND_DEVICE))
+ printf("Failed to find device from device info\n");
+ else
+ printf("Found device from device info\n");
+
+ /* test find from class */
+ if(ki_generic(tpci_fd, FIND_CLASS))
+ printf("Failed to find device from class\n");
+ else
+ printf("Found device from class \n");
+
+ /* test find subsys */
+ if(ki_generic(tpci_fd, FIND_SUBSYS))
+ printf("Failed to find device from subsys info\n");
+ else
+ printf("Found device from subsys info\n");
+
+ /* test scan bus */
+ if(ki_generic(tpci_fd, BUS_SCAN))
+ printf("Failed on bus scan call\n");
+ else
+ printf("Success scanning bus\n");
+
+ /* test scan slot */
+ if(ki_generic(tpci_fd, SLOT_SCAN))
+ printf("Failed on scan slot \n");
+ else
+ printf("Success scan slot\n");
+
+ /* test enable bridges */
+ if(ki_generic(tpci_fd, ENABLE_BRIDGES))
+ printf("Failed to enable bridges\n");
+ else
+ printf("Enabled bridges\n");
+
+ /* test bus add devices */
+ if(ki_generic(tpci_fd, BUS_ADD_DEVICES))
+ printf("Failed on bus add devices call\n");
+ else
+ printf("Success bus add devices\n");
+
+ /* test match device */
+ if(ki_generic(tpci_fd, MATCH_DEVICE))
+ printf("Failed on match device call\n");
+ else
+ printf("Success match device\n");
+
+#if 0
+ /* test unregister driver */
+ if(ki_generic(tpci_fd, UNREG_DRIVER))
+ printf("Failed to unregister driver\n");
+ else
+ printf("Unregistered driver\n");
+#endif
+
+ /* test register driver */
+ if(ki_generic(tpci_fd, REG_DRIVER))
+ printf("Failed to register driver\n");
+ else
+ printf("Registerd driver\n");
+
+ /* test pci resources */
+ if(ki_generic(tpci_fd, PCI_RESOURCES))
+ printf("Failed on pci_resources call\n");
+ else
+ printf("Success pci resources\n");
+
+ /* test save state */
+ if(ki_generic(tpci_fd, SAVE_STATE))
+ printf("Failed to save state of device\n");
+ else
+ printf("Saved state of device\n");
+
+ /* test restore state */
+ if(ki_generic(tpci_fd, RESTORE_STATE))
+ printf("Failed to restore state\n");
+ else
+ printf("Restored state\n");
+
+ /* test max bus */
+ if(ki_generic(tpci_fd, TEST_MAX_BUS))
+ printf("Failed on max bus call\n");
+ else
+ printf("Success max bus \n");
+
+ if(ki_generic(tpci_fd, FIND_CAP))
+ printf("Does not have tested capability\n");
+ else
+ printf("Device has tested capability\n");
+
+
+ rc = tpciclose();
+ if (rc ) {
+ printf("Test PCI Driver may not be closed\n");
+ exit(1);
+ }
+
+ return 0;
+}
diff --git a/testcases/kernel/device-drivers/pci/user_tpci/user_tpci.h b/testcases/kernel/device-drivers/pci/user_tpci/user_tpci.h
new file mode 100644
index 0000000..24ecd17
--- /dev/null
+++ b/testcases/kernel/device-drivers/pci/user_tpci/user_tpci.h
@@ -0,0 +1,13 @@
+//user_tpci.h
+int ki_generic(int, int);
+
+
+#if 0
+int ki_probe_pci_dev(int);
+int ki_enable_pci(int);
+int ki_disable_pci(int);
+int ki_find_bus(int);
+int ki_find_class(int);
+int ki_find_device(int);
+int ki_find_subsys(int);
+#endif