summaryrefslogtreecommitdiffstats
path: root/kernel/tests/lib/tst_ioctl.c
diff options
context:
space:
mode:
authorManuel Bentele2020-09-11 11:48:48 +0200
committerManuel Bentele2020-09-16 07:37:56 +0200
commita4215c3632c13218bb389d1f066549ab783028e3 (patch)
tree0468836ef5303f6eb94b876189ccaa60a7a2b453 /kernel/tests/lib/tst_ioctl.c
parentUpdated README with documentation of general information and build options (diff)
downloadxloop-a4215c3632c13218bb389d1f066549ab783028e3.tar.gz
xloop-a4215c3632c13218bb389d1f066549ab783028e3.tar.xz
xloop-a4215c3632c13218bb389d1f066549ab783028e3.zip
Added testcases from the Linux testing project (LTP)
Diffstat (limited to 'kernel/tests/lib/tst_ioctl.c')
-rw-r--r--kernel/tests/lib/tst_ioctl.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/kernel/tests/lib/tst_ioctl.c b/kernel/tests/lib/tst_ioctl.c
new file mode 100644
index 0000000..364220b
--- /dev/null
+++ b/kernel/tests/lib/tst_ioctl.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+
+#define TST_NO_DEFAULT_MAIN
+
+#include "tst_test.h"
+
+int tst_fibmap(const char *filename)
+{
+ /* test if FIBMAP ioctl is supported */
+ int fd, block = 0;
+
+ fd = open(filename, O_RDWR | O_CREAT, 0666);
+ if (fd < 0) {
+ tst_res(TWARN | TERRNO,
+ "open(%s, O_RDWR | O_CREAT, 0666) failed", filename);
+ return -1;
+ }
+
+ if (ioctl(fd, FIBMAP, &block)) {
+ tst_res(TINFO | TERRNO, "FIBMAP ioctl is NOT supported");
+ close(fd);
+ return 1;
+ }
+ tst_res(TINFO, "FIBMAP ioctl is supported");
+
+ if (close(fd)) {
+ tst_res(TWARN | TERRNO, "close(fd) failed");
+ return -1;
+ }
+ return 0;
+}
ref='#n176'>176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
// SPDX-License-Identifier: GPL-2.0
/*
 * PCI Backend - Handles the virtual fields found on the capability lists
 *               in the configuration space.
 *
 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
 */

#include <linux/kernel.h>
#include <linux/pci.h>
#include "pciback.h"
#include "conf_space.h"

static LIST_HEAD(capabilities);
struct xen_pcibk_config_capability {
	struct list_head cap_list;

	int capability;

	/* If the device has the capability found above, add these fields */
	const struct config_field *fields;
};

static const struct config_field caplist_header[] = {
	{
	 .offset    = PCI_CAP_LIST_ID,
	 .size      = 2, /* encompass PCI_CAP_LIST_ID & PCI_CAP_LIST_NEXT */
	 .u.w.read  = xen_pcibk_read_config_word,
	 .u.w.write = NULL,
	},
	{}
};

static inline void register_capability(struct xen_pcibk_config_capability *cap)
{
	list_add_tail(&cap->cap_list, &capabilities);
}

int xen_pcibk_config_capability_add_fields(struct pci_dev *dev)
{
	int err = 0;
	struct xen_pcibk_config_capability *cap;
	int cap_offset;

	list_for_each_entry(cap, &capabilities, cap_list) {
		cap_offset = pci_find_capability(dev, cap->capability);
		if (cap_offset) {
			dev_dbg(&dev->dev, "Found capability 0x%x at 0x%x\n",
				cap->capability, cap_offset);

			err = xen_pcibk_config_add_fields_offset(dev,
							       caplist_header,
							       cap_offset);
			if (err)
				goto out;
			err = xen_pcibk_config_add_fields_offset(dev,
							       cap->fields,
							       cap_offset);
			if (err)
				goto out;
		}
	}

out:
	return err;
}

static int vpd_address_write(struct pci_dev *dev, int offset, u16 value,
			     void *data)
{
	/* Disallow writes to the vital product data */
	if (value & PCI_VPD_ADDR_F)
		return PCIBIOS_SET_FAILED;
	else
		return pci_write_config_word(dev, offset, value);
}

static const struct config_field caplist_vpd[] = {
	{
	 .offset    = PCI_VPD_ADDR,
	 .size      = 2,
	 .u.w.read  = xen_pcibk_read_config_word,
	 .u.w.write = vpd_address_write,
	 },
	{
	 .offset     = PCI_VPD_DATA,
	 .size       = 4,
	 .u.dw.read  = xen_pcibk_read_config_dword,
	 .u.dw.write = NULL,
	 },
	{}
};

static int pm_caps_read(struct pci_dev *dev, int offset, u16 *value,
			void *data)
{
	int err;
	u16 real_value;

	err = pci_read_config_word(dev, offset, &real_value);
	if (err)
		goto out;

	*value = real_value & ~PCI_PM_CAP_PME_MASK;

out:
	return err;
}

/* PM_OK_BITS specifies the bits that the driver domain is allowed to change.
 * Can't allow driver domain to enable PMEs - they're shared */
#define PM_OK_BITS (PCI_PM_CTRL_PME_STATUS|PCI_PM_CTRL_DATA_SEL_MASK)