diff options
author | Suren A. Chilingaryan <csa@suren.me> | 2015-11-19 03:19:51 +0100 |
---|---|---|
committer | Suren A. Chilingaryan <csa@suren.me> | 2015-11-19 03:19:51 +0100 |
commit | 6191a86bf2de5413cc9100e1450b541e5dfcb8f9 (patch) | |
tree | c4edeb5e91aa4098c55d01a00f2d292d0635ae61 /driver | |
parent | 46754246bddd1c15d61e915bd860448bab8d7400 (diff) | |
download | pcitool-6191a86bf2de5413cc9100e1450b541e5dfcb8f9.tar.gz pcitool-6191a86bf2de5413cc9100e1450b541e5dfcb8f9.tar.bz2 pcitool-6191a86bf2de5413cc9100e1450b541e5dfcb8f9.tar.xz pcitool-6191a86bf2de5413cc9100e1450b541e5dfcb8f9.zip |
Support setting payload size
Diffstat (limited to 'driver')
-rw-r--r-- | driver/Makefile | 2 | ||||
-rw-r--r-- | driver/compat.c | 26 | ||||
-rw-r--r-- | driver/compat.h | 3 | ||||
-rw-r--r-- | driver/ioctl.c | 30 | ||||
-rw-r--r-- | driver/pciDriver.h | 8 |
5 files changed, 62 insertions, 7 deletions
diff --git a/driver/Makefile b/driver/Makefile index 3a242dd..83a8c46 100644 --- a/driver/Makefile +++ b/driver/Makefile @@ -1,6 +1,6 @@ obj-m := pciDriver.o -pciDriver-objs := base.o int.o umem.o kmem.o sysfs.o ioctl.o +pciDriver-objs := base.o int.o umem.o kmem.o sysfs.o ioctl.o compat.o KERNELDIR ?= /lib/modules/$(shell uname -r)/build INSTALLDIR ?= /lib/modules/$(shell uname -r)/kernel/extra diff --git a/driver/compat.c b/driver/compat.c new file mode 100644 index 0000000..a632781 --- /dev/null +++ b/driver/compat.c @@ -0,0 +1,26 @@ +#include <linux/pci.h> + +int pcidriver_pcie_get_mps(struct pci_dev *dev) +{ + u16 ctl; + + pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl); + + return 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); +} + +int pcidriver_pcie_set_mps(struct pci_dev *dev, int mps) +{ + u16 v; + + if (mps < 128 || mps > 4096 || !is_power_of_2(mps)) + return -EINVAL; + + v = ffs(mps) - 8; + if (v > dev->pcie_mpss) + return -EINVAL; + v <<= 5; + + return pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_PAYLOAD, v); +} diff --git a/driver/compat.h b/driver/compat.h index 25e402a..fd3f188 100644 --- a/driver/compat.h +++ b/driver/compat.h @@ -195,4 +195,7 @@ static inline void set_pages_reserved_compat(unsigned long cpua, unsigned long s #endif } +int pcidriver_pcie_get_mps(struct pci_dev *dev); +int pcidriver_pcie_set_mps(struct pci_dev *dev, int mps); + #endif diff --git a/driver/ioctl.c b/driver/ioctl.c index e003476..67cdc52 100644 --- a/driver/ioctl.c +++ b/driver/ioctl.c @@ -433,7 +433,6 @@ static int ioctl_version(pcidriver_privdata_t *privdata, unsigned long arg) return 0; } - /** * * Gets current device and driver configuration @@ -448,6 +447,7 @@ static int ioctl_device_state(pcidriver_privdata_t *privdata, unsigned long arg) info = (pcilib_device_state_t) { .iommu = iommu_present(privdata->pdev->dev.bus), + .mps = pcidriver_pcie_get_mps(privdata->pdev), .dma_mask = privdata->pdev->dma_mask }; @@ -468,7 +468,7 @@ static int ioctl_set_dma_mask(pcidriver_privdata_t *privdata, unsigned long arg) { int err; - if ((arg < 24) && (arg > 63)) + if ((arg < 24) || (arg > 64)) return -EINVAL; err = pci_set_dma_mask(privdata->pdev, DMA_BIT_MASK(arg)); @@ -477,8 +477,29 @@ static int ioctl_set_dma_mask(pcidriver_privdata_t *privdata, unsigned long arg) return err; } - printk(KERN_ERR "pci_set_dma_mask(%lu) successeded\n", arg); + return 0; +} + +/** + * + * Sets Max Payload Size. + * + * @param arg Not a pointer, but payload size in bits + * + */ +static int ioctl_set_mps(pcidriver_privdata_t *privdata, unsigned long arg) +{ + int err; + if ((arg != 128) && (arg != 256) && (arg != 512)) + return -EINVAL; + + err = pcidriver_pcie_set_mps(privdata->pdev, arg); + if (err < 0) { + printk(KERN_ERR "pcie_set_mps(%lu) failed\n", arg); + return err; + } + return 0; } @@ -551,6 +572,9 @@ long pcidriver_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case PCIDRIVER_IOC_DMA_MASK: return ioctl_set_dma_mask(privdata, arg); + case PCIDRIVER_IOC_MPS: + return ioctl_set_mps(privdata, arg); + default: return -EINVAL; } diff --git a/driver/pciDriver.h b/driver/pciDriver.h index d314952..2fda0ff 100644 --- a/driver/pciDriver.h +++ b/driver/pciDriver.h @@ -130,8 +130,9 @@ typedef struct { } pcilib_driver_version_t; typedef struct { - unsigned long iommu; - unsigned long dma_mask; + int iommu; /**< Specifies if IOMMU is enabled or disabled */ + int mps; /**< Maximum payload size */ + unsigned long dma_mask; /**< DMA mask */ } pcilib_device_state_t; typedef struct { @@ -235,7 +236,8 @@ typedef struct { #define PCIDRIVER_IOC_VERSION _IOR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 14, pcilib_driver_version_t * ) #define PCIDRIVER_IOC_DEVICE_STATE _IOR( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 15, pcilib_device_state_t * ) #define PCIDRIVER_IOC_DMA_MASK _IO( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 16) +#define PCIDRIVER_IOC_MPS _IO( PCIDRIVER_IOC_MAGIC, PCIDRIVER_IOC_BASE + 17) -#define PCIDRIVER_IOC_MAX 16 +#define PCIDRIVER_IOC_MAX 17 #endif |