Skip to contentSkip to conversation

Add mkopci driver

PATCH In review [email protected] 6 participants 10 messages Mar 20, 2015 – Mar 26, 2015

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Add mkopci driver

mkopci (MB11.xx) device (RC Module project) provides data transference through a serial bus bar according to MIL-STD-1553. the driver used for operating devices, reads PCI configuration space and pass interrupts to user-space applications.

Please consider adding this patch to the linux-next queue.

---
 Documentation/misc-devices/mkopci.txt |   51 ++
 drivers/misc/Kconfig                  |    9 +
 drivers/misc/Makefile                 |    1 +
 drivers/misc/mkopci.c                 | 1272 +++++++++++++++++++++++++++++++++
 include/misc/mkopci.h                 |   81 +++
 5 files changed, 1414 insertions(+)

create mode 100644 Documentation/misc-devices/mkopci.txt create mode 100644 drivers/misc/mkopci.c
create mode 100644 include/misc/mkopci.h

Documentation/misc-devices/mkopci.txt new file +51 -0
new file mode 100644
index 0000000..0fcec6d
@@ -0,0 +1,51 @@
+    PCI-based MKO bus driver.
+
+
+For dealing with driver without using of root's account it will be helpfull
+to add group `mkopci' with appropriate users and put file, say 60-mkopci.rules to
+/etc/udev/rules.d in your system.
+--- cut 60-mkopci.rules ---
+# MKO devices
+KERNEL=="mkopci*", SUBSYSTEM=="mkopci", ACTION=="add", DRIVERS=="?*", ATTRS{idVendor}=="0x6403"
+GROUP="mkopci"
+---
+
+
+Kernel module parameters
+
+Kernel module can take parameters 'v' and 'omited'
+- 'v' is 0 to 3, and affects the amount of information
+output to the system log.
+0 - (default) comletely silent
+1 - prints only detected BARs, reports loading / unloading
+2 - + prints IRQ and memory mapping events
+3 - + prints ioctl events
+
+- 'plx9050bug_quirk' controls workaround controller PLX9050. Can
+the following values:
+0 - workaround is disabled (default)
+1 - workaround is enabled
+2 - forced bug
+
+- 'omited' tells the driver which device should not be initialized
+at load time.
+The value of this parameter to the kernel module 2.4 is a physical address
+device on the bus, such as "0x10800" without the quotes.
+In kernel versions 2.6+ can exclude multiple devices, transferring them
+values separated by commas, but not more than 4.
+
+The parameter values can be specified as follows:
+$ insmod/modprobe mkopci.[ko/o] parameter1_name=value [parameter2_name=value]
+
+Record the physical address of the device in the file /proc/mkopci/core
+also controls "visibility" for user programs. Missed return device
+You can command 'echo ADDR > /proc/mkopci/core'. ADDR can be either a simple
+number of device, but always in hexadecimal, or (for Linux-2.6+)
+the number of devices in a standard format Linux kind NM:XY.z.
+
+
+PROC filesystem
+
+/proc/mkopci/devices - read only text device table
+/proc/mkopci/core    - device table for user space applications
+
drivers/misc/Kconfig +9 -0
index 006242c..7db247e 100644
@@ -124,6 +124,15 @@ config PHANTOM
 	  If you choose to build module, its name will be phantom. If unsure,
 	  say N here.
 
+config MKOPCI 
+	tristate "Module PCI bus driver"
+	depends on PCI && PROC_FS
+	help
+	  Say Y here if you want to build a driver for Module(RC) MKOPCI devices.
+
+	  If you choose to build module, its name will be mkopci. If unsure,
+	  say N here.
+
 config INTEL_MID_PTI
 	tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard"
 	depends on PCI && TTY && (X86_INTEL_MID || COMPILE_TEST)
drivers/misc/Makefile +1 -0
index 7d5c4cd..afb92b4 100644
@@ -56,3 +56,4 @@ obj-$(CONFIG_GENWQE)		+= genwqe/
 obj-$(CONFIG_ECHO)		+= echo/
 obj-$(CONFIG_VEXPRESS_SYSCFG)	+= vexpress-syscfg.o
 obj-$(CONFIG_CXL_BASE)		+= cxl/
+obj-$(CONFIG_MKOPCI)		+= mkopci.o
drivers/misc/mkopci.c new file +1272 -0

1,272 lines not on this page · raw message

include/misc/mkopci.h new file +81 -0

81 lines not on this page · raw message

---

#1 lore raw

Sergej,

Quoted 6 lines · On Fri, Mar 20, 2015 at 1:10 PM, <[email protected]> wrote:

mkopci (MB11.xx) device (RC Module project) provides data transference through a serial bus bar according to MIL-STD-1553. the driver used for operating devices, reads PCI configuration space and pass interrupts to user-space applications.

Please consider adding this patch to the linux-next queue.

From a quick look I'd suggest to get the driver first in shape.

- You add new proc files, which is not really welcomed. Please consider sysfs.
- In the debug prints you compare against current->comm, also not nice.
- You use printk() in the interrupt handler.
- Why is this a misc driver at all? Does it really not fit into any other device class?
- I'm sure running checkpatch.pl against the patch would also not hurt. :)

Signature · 2 lines
Thanks,
//richard
#2 lore raw
Quoted 5 lines · Richard Weinberger

Sergej,

Quoted 2 lines · On Fri, Mar 20, 2015 at 1:10 PM, <[email protected]> wrote:

mkopci (MB11.xx) device (RC Module project) provides data transference through a serial bus bar according to MIL-STD-1553. the driver used for operating devices, reads PCI configuration space and pass interrupts to user-space applications.

BTW: Forgot to mention that this sounds like a job for UIO or VFIO. Did you consider it?

Signature · 2 lines
Thanks,
//richard
#3 lore raw
In reply to Richard Weinberger
Quoted 8 lines · Richard Weinberger

Sergej,

Quoted 4 lines · On Fri, Mar 20, 2015 at 1:10 PM, <[email protected]> wrote:

mkopci (MB11.xx) device (RC Module project) provides data transference through a serial bus bar according to MIL-STD-1553. the driver used for operating devices, reads PCI configuration space and pass interrupts to user-space applications.

Please consider adding this patch to the linux-next queue.

Quoted 8 lines

From a quick look I'd suggest to get the driver first in shape.

- You add new proc files, which is not really welcomed. Please consider sysfs.
- In the debug prints you compare against current->comm, also not nice.
- You use printk() in the interrupt handler.
- Why is this a misc driver at all? Does it really not fit into any other device class?
- I'm sure running checkpatch.pl against the patch would also not hurt. :)

And an additional, trivial, change you might also consider is using

    MODULE_LICENSE("GPL v2");

as that would match the license stated in the comment at the top of drivers/misc/mkopci.c.

Paul Bolle

#4 lore raw
In reply to Richard Weinberger

Richard, thanks for your review.

But I still have several notes about driver:

Quoted 1 line

- You add new proc files, which is not really welcomed. Please consider sysfs.

That will break a bunch of userspace applications, which use proc-files for several years (as long as from 2006 year)

Quoted 2 lines

- In the debug prints you compare against current->comm, also not nice.
- You use printk() in the interrupt handler.

That printks was only for driver tests, and does not need anymore, I think. And you're absolutely right :)

Quoted 2 lines

- Why is this a misc driver at all? Does it really not fit into any other device class?

I've don't think I can find an appropriate class. On the one hand, this is industrial bus but it has nothing in common with drivers/iio, or with drives/bus

Quoted 1 line

- I'm sure running checkpatch.pl against the patch would also not hurt. :)

Yes, but it only hurts with "line over 80 characters" warnings and hurts much :) And a couple of such warnings still remain...

Quoted 1 line

BTW: Forgot to mention that this sounds like a job for UIO or VFIO.

And again, you are right. But, again, there a number of applications wich use /proc/mkopci/core

But, of course, there may be decided that the kernel main line - this is not the place for such a driver. :) If the driver is suitable anyway, patch is at the end of this message

And thanks to Paul Bolle for noticing about license mismatch.

Quoted 8 lines · On Friday 20 March 2015 15:43:50 you wrote:

Sergej,

Quoted 4 lines · On Fri, Mar 20, 2015 at 1:10 PM, <[email protected]> wrote:

mkopci (MB11.xx) device (RC Module project) provides data transference through a serial bus bar according to MIL-STD-1553. the driver used for operating devices, reads PCI configuration space and pass interrupts to user-space applications.

Please consider adding this patch to the linux-next queue.

Quoted 10 lines

From a quick look I'd suggest to get the driver first in shape.

- You add new proc files, which is not really welcomed. Please consider sysfs.
- In the debug prints you compare against current->comm, also not nice.
- You use printk() in the interrupt handler.
- Why is this a misc driver at all? Does it really not fit into any other device class?
- I'm sure running checkpatch.pl against the patch would also not hurt. :)

Documentation/misc-devices/mkopci.txt new file +44 -0
new file mode 100644
index 0000000..499bc29
@@ -0,0 +1,44 @@
+    PCI-based MKO bus driver.
+
+
+For dealing with driver without using of root's account it will be helpful
+to add group `mkopci' with appropriate users and put file, say 60-mkopci.rules to
+/etc/udev/rules.d in your system.
+--- cut 60-mkopci.rules ---
+# MKO devices
+KERNEL=="mkopci*", SUBSYSTEM=="mkopci", ACTION=="add", DRIVERS=="?*", ATTRS{idVendor}=="0x6403"
+GROUP="mkopci"
+---
+
+Kernel module parameters
+
+Kernel module can take parameters 'v' and 'omited'
+- 'v' is 0 to 3, and affects the amount of information
+output to the system log.
+0 - (default) comletely silent
+1 - prints only detected BARs, reports loading / unloading
+2 - + prints IRQ and memory mapping events
+3 - + prints ioctl events
+
+- 'plx9050bug_quirk' controls workaround controller PLX9050. Can
+the following values:
+0 - workaround is disabled (default)
+1 - workaround is enabled
+2 - forced bug
+
+- 'omited' tells the driver which device should not be initialized
+at load time.
+The value of this parameter to the kernel module 2.4 is a physical address
+device on the bus, such as "0x10800" without the quotes.
+In kernel versions 2.6+ can exclude multiple devices, transferring them
+values separated by commas, but not more than 4.
+
+The parameter values can be specified as follows:
+$ insmod/modprobe mkopci.[Ko/o] parameter1_name=value [parameter2_name=value]
+
+Record the physical address of the device in the file /proc/mkopci/core
+also controls "visibility" for user programs. Missed return device
+You can command 'echo ADDR > /proc/mkopci/core'. ADDR can be either a simple
+number of device, but always in hexadecimal, or (for Linux-2.6+)
+the number of devices in a standard format Linux kind NM:XY.z.
+
drivers/misc/Kconfig +12 -0
index 006242c..c571451 100644
@@ -124,6 +124,18 @@ config PHANTOM
 	  If you choose to build module, its name will be phantom. If unsure,
 	  say N here.
 
+config MKOPCI
+	tristate "Module PCI bus driver"
+	depends on PCI && PROC_FS
+	help
+	  MKOPCI (MB11.xx) device (by RC Module project) provides data transference
+	  through a serial bus bar according to MIL-STD-1553.
+
+	  Say Y here if you want to build a driver for Module(RC) MKOPCI devices.
+
+	  If you choose to build module, its name will be mkopci. If unsure,
+	  say N here.
+
 config INTEL_MID_PTI
 	tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard"
 	depends on PCI && TTY && (X86_INTEL_MID || COMPILE_TEST)
drivers/misc/Makefile +1 -0
index 7d5c4cd..afb92b4 100644
@@ -56,3 +56,4 @@ obj-$(CONFIG_GENWQE)		+= genwqe/
 obj-$(CONFIG_ECHO)		+= echo/
 obj-$(CONFIG_VEXPRESS_SYSCFG)	+= vexpress-syscfg.o
 obj-$(CONFIG_CXL_BASE)		+= cxl/
+obj-$(CONFIG_MKOPCI)		+= mkopci.o
drivers/misc/mkopci.c new file +1272 -0

1,272 lines not on this page · raw message

include/misc/mkopci.h new file +81 -0

81 lines not on this page · raw message

Documentation/misc-devices/mkopci.txt new file +44 -0

44 lines not on this page · raw message

drivers/misc/Kconfig +12 -0
index 006242c..c571451 100644
@@ -124,6 +124,18 @@ config PHANTOM
 	  If you choose to build module, its name will be phantom. If unsure,
 	  say N here.
 
+config MKOPCI
+	tristate "Module PCI bus driver"
+	depends on PCI && PROC_FS
+	help
+	  MKOPCI (MB11.xx) device (by RC Module project) provides data transference
+	  through a serial bus bar according to MIL-STD-1553.
+
+	  Say Y here if you want to build a driver for Module(RC) MKOPCI devices.
+
+	  If you choose to build module, its name will be mkopci. If unsure,
+	  say N here.
+
 config INTEL_MID_PTI
 	tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard"
 	depends on PCI && TTY && (X86_INTEL_MID || COMPILE_TEST)
drivers/misc/Makefile +1 -0
index 7d5c4cd..afb92b4 100644
@@ -56,3 +56,4 @@ obj-$(CONFIG_GENWQE)		+= genwqe/
 obj-$(CONFIG_ECHO)		+= echo/
 obj-$(CONFIG_VEXPRESS_SYSCFG)	+= vexpress-syscfg.o
 obj-$(CONFIG_CXL_BASE)		+= cxl/
+obj-$(CONFIG_MKOPCI)		+= mkopci.o
drivers/misc/mkopci.c new file +1272 -0

1,272 lines not on this page · raw message

include/misc/mkopci.h new file +81 -0

81 lines not on this page · raw message

maintainer
#5 lore raw
Quoted 9 lines · Sergej Bauer

Richard, thanks for your review.

But I still have several notes about driver:

Quoted 1 line

- You add new proc files, which is not really welcomed. Please consider sysfs.

That will break a bunch of userspace applications, which use proc-files for several years (as long as from 2006 year)

Quoted 5 lines
Quoted 1 line

BTW: Forgot to mention that this sounds like a job for UIO or VFIO.

And again, you are right. But, again, there a number of applications wich use /proc/mkopci/core

But, of course, there may be decided that the kernel main line - this is not the place for such a driver. :) If the driver is suitable anyway, patch is at the end of this message

I don't think we should merge the driver with the proposed user interface. You can either create a high-level abstraction for MIL-STD-1553, or use UIO or VFIO to provide a trivial passthrough. In either case, both the ioctl interface and the procfs interface have no future, and existing user space programs need to adapt.

There is nothing wrong with adding a driver for this hardware, but I'd rather see it done properly than having an ad-hoc user space interface that was never reviewed publically before it got used by applications.

Arnd

#6 lore raw

Ok, I realized uselessness of merging this driver...

And you brought me to a standstill:

Quoted 1 line

passthrough. In either case, both the ioctl interface and the procfs interface have no future

But what will be after ioctl?

Quoted 27 lines · On Saturday 21 March 2015 18:41:42 Arnd Bergmann wrote:
Quoted 9 lines · Sergej Bauer

Richard, thanks for your review.

But I still have several notes about driver:

Quoted 1 line

- You add new proc files, which is not really welcomed. Please consider sysfs.

That will break a bunch of userspace applications, which use proc-files for several years (as long as from 2006 year)

Quoted 5 lines
Quoted 1 line

BTW: Forgot to mention that this sounds like a job for UIO or VFIO.

And again, you are right. But, again, there a number of applications wich use /proc/mkopci/core

But, of course, there may be decided that the kernel main line - this is not the place for such a driver. :) If the driver is suitable anyway, patch is at the end of this message

I don't think we should merge the driver with the proposed user interface. You can either create a high-level abstraction for MIL-STD-1553, or use UIO or VFIO to provide a trivial passthrough. In either case, both the ioctl interface and the procfs interface have no future, and existing user space programs need to adapt.

There is nothing wrong with adding a driver for this hardware, but I'd rather see it done properly than having an ad-hoc user space interface that was never reviewed publically before it got used by applications.

Arnd

#7 lore raw

Am 21.03.2015 um 18:24 schrieb Sergej Bauer:

Quoted 1 line

Ok, I realized uselessness of merging this driver...

Please don't give up that fast!
See: http://airlied.livejournal.com/#item80112

Quoted 3 lines

And you brought me to a standstill:

Quoted 1 line

passthrough. In either case, both the ioctl interface and the procfs interface have no future

But what will be after ioctl?

We will not drop the ioctl() system call. But having a character device with random ioctl()s is not really a good driver design.
Today we have much more elegant ways to interact between kernel and userspace than ioctl(). For example sysfs or netlink.

Thanks,
//richard

#8 lore raw

Thanks a lot :)

But the driver is really very insignificant.
I was wondering about sysfs before, but consumers will not be very happy to get another revision of userspace tools/library. So this is their own problems :)

Thanks again and sorry for this uselessness dialogue :)

Quoted 18 lines · On Saturday 21 March 2015 20:32:16 Richard Weinberger wrote:

Am 21.03.2015 um 18:24 schrieb Sergej Bauer:

Quoted 1 line

Ok, I realized uselessness of merging this driver...

Please don't give up that fast!
See: http://airlied.livejournal.com/#item80112

Quoted 3 lines

And you brought me to a standstill:

Quoted 1 line

passthrough. In either case, both the ioctl interface and the procfs interface have no future

But what will be after ioctl?

We will not drop the ioctl() system call. But having a character device with random ioctl()s is not really a good driver design.
Today we have much more elegant ways to interact between kernel and userspace than ioctl(). For example sysfs or netlink.

Thanks,
//richard

maintainer
#9 lore raw
In reply to [email protected]
Quoted 2 lines · On Fri, Mar 20, 2015 at 03:10:26PM +0300, [email protected] wrote:

mkopci (MB11.xx) device (RC Module project) provides data transference through a serial bus bar according to MIL-STD-1553. the driver used for operating devices, reads PCI configuration space and pass interrupts to user-space applications.

Why can't this be a UIO driver? Isn't that what the UIO interface already does?

Quoted 32 lines

Please consider adding this patch to the linux-next queue.

---
 Documentation/misc-devices/mkopci.txt |   51 ++
 drivers/misc/Kconfig                  |    9 +
 drivers/misc/Makefile                 |    1 +
 drivers/misc/mkopci.c                 | 1272 +++++++++++++++++++++++++++++++++
 include/misc/mkopci.h                 |   81 +++
 5 files changed, 1414 insertions(+)

create mode 100644 Documentation/misc-devices/mkopci.txt create mode 100644 drivers/misc/mkopci.c
create mode 100644 include/misc/mkopci.h

Documentation/misc-devices/mkopci.txt new file +12 -0
new file mode 100644
index 0000000..0fcec6d
@@ -0,0 +1,51 @@
+    PCI-based MKO bus driver.
+
+
+For dealing with driver without using of root's account it will be helpfull
+to add group `mkopci' with appropriate users and put file, say 60-mkopci.rules to
+/etc/udev/rules.d in your system.
+--- cut 60-mkopci.rules ---
+# MKO devices
+KERNEL=="mkopci*", SUBSYSTEM=="mkopci", ACTION=="add", DRIVERS=="?*", ATTRS{idVendor}=="0x6403"
+GROUP="mkopci"
+---
+

Documentation/misc-devices/mkopci.txt line 22

Quoted 10 lines
Documentation/misc-devices/mkopci.txt new file +10 -0
+
+Kernel module parameters
+
+Kernel module can take parameters 'v' and 'omited'
+- 'v' is 0 to 3, and affects the amount of information
+output to the system log.
+0 - (default) comletely silent
+1 - prints only detected BARs, reports loading / unloading
+2 - + prints IRQ and memory mapping events
+3 - + prints ioctl events

Please use the built-in dynamic debugging levels instead of custom ones like this.

Quoted 18 lines
Documentation/misc-devices/mkopci.txt new file +18 -0
+
+- 'plx9050bug_quirk' controls workaround controller PLX9050. Can
+the following values:
+0 - workaround is disabled (default)
+1 - workaround is enabled
+2 - forced bug
+
+- 'omited' tells the driver which device should not be initialized
+at load time.
+The value of this parameter to the kernel module 2.4 is a physical address
+device on the bus, such as "0x10800" without the quotes.
+In kernel versions 2.6+ can exclude multiple devices, transferring them
+values separated by commas, but not more than 4.
+
+The parameter values can be specified as follows:
+$ insmod/modprobe mkopci.[ko/o] parameter1_name=value [parameter2_name=value]
+
+Record the physical address of the device in the file /proc/mkopci/core

Documentation/misc-devices/mkopci.txt line 50

Quoted 10 lines
Documentation/misc-devices/mkopci.txt new file +10 -0
+also controls "visibility" for user programs. Missed return device
+You can command 'echo ADDR > /proc/mkopci/core'. ADDR can be either a simple
+number of device, but always in hexadecimal, or (for Linux-2.6+)
+the number of devices in a standard format Linux kind NM:XY.z.
+
+
+PROC filesystem
+
+/proc/mkopci/devices - read only text device table
+/proc/mkopci/core    - device table for user space applications

As others have said, proc is not for devices, we can't take new drivers that use this, sorry.

drivers/misc/Kconfig config PHANTOM · line 127

Quoted 10 lines
Documentation/misc-devices/mkopci.txt new file +1 -0
+
drivers/misc/Kconfig +1 -0
index 006242c..7db247e 100644
@@ -124,6 +124,15 @@ config PHANTOM
 	  If you choose to build module, its name will be phantom. If unsure,
 	  say N here.
 
+config MKOPCI 

Trailing whitespace :(

Quoted 57 lines
drivers/misc/Kconfig +8 -0
+	tristate "Module PCI bus driver"
+	depends on PCI && PROC_FS
+	help
+	  Say Y here if you want to build a driver for Module(RC) MKOPCI devices.
+
+	  If you choose to build module, its name will be mkopci. If unsure,
+	  say N here.
+
 config INTEL_MID_PTI
 	tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard"
 	depends on PCI && TTY && (X86_INTEL_MID || COMPILE_TEST)
drivers/misc/Makefile +1 -0
index 7d5c4cd..afb92b4 100644
@@ -56,3 +56,4 @@ obj-$(CONFIG_GENWQE)		+= genwqe/
 obj-$(CONFIG_ECHO)		+= echo/
 obj-$(CONFIG_VEXPRESS_SYSCFG)	+= vexpress-syscfg.o
 obj-$(CONFIG_CXL_BASE)		+= cxl/
+obj-$(CONFIG_MKOPCI)		+= mkopci.o
drivers/misc/mkopci.c new file +31 -0
new file mode 100644
index 0000000..d223478
@@ -0,0 +1,1272 @@
+/*
+ *  MKOPCI driver
+ *
+ *  Copyright (C) 2007-2015 Sergej Bauer <[email protected]>
+ *
+ *  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, version 2.
+*/
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/pci.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+
+#include "misc/mkopci.h"
+
+#define MKO_VENDOR  0x6403
+#define MKO_DEVICE1 0x0430

drivers/misc/mkopci.c line 41

Quoted 10 lines
drivers/misc/mkopci.c new file +10 -0
+#define MKO_DEVICE2 0x0431
+#define MKO_DEVICE3 0x0434
+
+#define PLX9050BUG_BAR0 0x1
+#define PLX9050BUG_BAR1 0x2
+#define PLX9050BUG_INJECT 0x4
+
+#if !defined(__user)
+#define __user
+#endif

Why is this needed?

Quoted 5 lines
drivers/misc/mkopci.c new file +5 -0
+
+static struct pci_device_id ids[] = {
+	{MKO_VENDOR, MKO_DEVICE1, PCI_ANY_ID, PCI_ANY_ID,},
+	{MKO_VENDOR, MKO_DEVICE2, PCI_ANY_ID, PCI_ANY_ID,},
+	{MKO_VENDOR, MKO_DEVICE3, PCI_ANY_ID, PCI_ANY_ID,},

drivers/misc/mkopci.c line 56

Quoted 10 lines
drivers/misc/mkopci.c new file +10 -0
+	{0, 0,}
+};
+
+MODULE_DEVICE_TABLE(pci, ids);
+
+#ifdef __LP64__
+#define PFMT	"llx"
+#else
+#define PFMT	"x"
+#endif

Are you sure you need this? We have data types to handle this already...

drivers/misc/mkopci.c line 58

Quoted 2 lines
drivers/misc/mkopci.c new file +2 -0
+
+unsigned char drv_version = 0x11;

Global variables?

Quoted 18 lines
drivers/misc/mkopci.c new file +18 -0
+#define mko_pci_addr(bus, device, func, regoffs) (\
+	((bus  & 0xFF) << 16) | ((device & 0x1F) << 11) | \
+	((func & 0x7)  <<  8) | (regoffs & 0xFC))
+
+static struct kmem_cache *mkopci_device_cache;
+static dev_t devp;
+static struct class *mkopci_class;
+static struct rw_semaphore devices_sem;
+static LIST_HEAD(devices);
+static atomic_t devices_nr = ATOMIC_INIT(0);
+
+/*** module parameters ***/
+static int plx9050bug_quirk = 1;
+/* verbosity level */
+static int v;
+module_param(plx9050bug_quirk, int, S_IRUGO);
+module_param(v, int, S_IRUGO);
+MODULE_PARM_DESC(plx9050bug_quirk, "PLX9050 bug quirk");

drivers/misc/mkopci.c line 86

Quoted 10 lines
drivers/misc/mkopci.c new file +10 -0
+MODULE_PARM_DESC(v, "verbosity level");
+
+/* only MAX_DEVICES_NR devices at once can be omited */
+static int omited[MAX_DEVICES_NR];
+static int omited_nr;
+module_param_array(omited, int, &omited_nr, S_IRUGO);
+MODULE_PARM_DESC(omited, "device(s) to omit");
+#ifndef VM_RESERVED
+#define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP)
+#endif

Why is this needed?

drivers/misc/mkopci.c line 87

Quoted 1 line
drivers/misc/mkopci.c new file +1 -0
+#define __unused __attribute__ ((unused))

We already have this.

Quoted 4 lines
drivers/misc/mkopci.c new file +4 -0
+
+/***************************** Interrupt handling *****************************/
+static int mkopci_wait_irq(struct mkopci_device *dev)
+{

drivers/misc/mkopci.c line 101

Quoted 10 lines
drivers/misc/mkopci.c new file +10 -0
+	volatile unsigned long *LPCI_4C =
+		(unsigned long *)(dev->core.lin_base[0] + 0x4C);
+
+	*LPCI_4C |= 0x49;
+
+	if (wait_event_interruptible(dev->wq, *LPCI_4C & 0x24))
+		return -ERESTARTSYS;
+	if (v > 1)
+		pr_info("mkopci%d: irq received\n", dev->core.n_dev);
+	*LPCI_4C &= ~0x40;

You can't directly access memory like this safely, please use the proper io memory functions instead, otherwise bad things are guaranteed to happen.

Hint, volatile doesn't mean what you think it does here...

drivers/misc/mkopci.c line 110

Quoted 9 lines
drivers/misc/mkopci.c new file +9 -0
+
+	return 0;
+}
+
+static irqreturn_t mkopci_int_handler(int __unused irq, void *dev)
+{
+	struct mkopci_device *mko_dev = (struct mkopci_device *)dev;
+	volatile unsigned long *LPCI_4C =
+	    (unsigned long *)((mko_dev->core.lin_base[0] + 0x4C));

Same here, don't use this.

drivers/misc/mkopci.c line 113

Quoted 3 lines
drivers/misc/mkopci.c new file +3 -0
+
+	if (*LPCI_4C & 0x24) {
+		*LPCI_4C &= ~0x40;

That breaks on lots of architectures :(

Quoted 47 lines
drivers/misc/mkopci.c new file +47 -0
+		wake_up_interruptible(&mko_dev->wq);
+	} else
+		return IRQ_NONE;
+
+	return IRQ_HANDLED;
+}
+
+static int mkopci_request_irq(struct mkopci_device *dev)
+{
+	int ret = 0;
+
+	if (dev->core.irq_requested) {
+		pr_err("mkopci%d: irq already requested\n", dev->core.n_dev);
+		return -EBUSY;
+	}
+	ret = request_irq(dev->core.irq, &mkopci_int_handler, IRQF_SHARED,
+			dev->core.name, dev);
+	if (ret) {
+		pr_err("mkopci%d: failed to request irq %d\n", dev->core.n_dev,
+			dev->core.irq);
+		return ret;
+	}
+
+	dev->core.irq_requested++;
+
+	if (strcmp(current->comm, "TestSetISR") && v > 1) {
+		pr_info("mkopci%d: irq %d requested (%s)\n", dev->core.n_dev,
+			dev->core.irq, current->comm);
+	}
+
+	return ret;
+}
+
+static void mkopci_free_irq(struct mkopci_device *dev)
+{
+	if (dev->core.irq_requested) {
+		synchronize_irq(dev->core.irq);
+		free_irq(dev->core.irq, dev);
+		dev->core.irq_requested--;
+
+		if (strcmp(current->comm, "TestSetISR") && v > 1) {
+			pr_info("mkopci%d: irq %d released\n", dev->core.n_dev,
+				dev->core.irq);
+		}
+	}
+}
+/************************* End of Interrupt handling **************************/

drivers/misc/mkopci.c line 170

Quoted 10 lines
drivers/misc/mkopci.c new file +10 -0
+
+/**************************** File operations *********************************/
+static int mkopci_open(struct inode *inode, struct file *filp)
+{
+	int ret = 0;
+	struct mkopci_device *dev =
+	    container_of(inode->i_cdev, struct mkopci_device, cdev);
+
+	if (!try_module_get(THIS_MODULE))
+		return -EINVAL;

That's racy, and not needed, and should never be in any kernel code ever. Please remove.

Quoted 10 lines
drivers/misc/mkopci.c new file +10 -0
+
+	if (dev == NULL) {
+		module_put(THIS_MODULE);
+		return -ENODEV;
+	}
+
+	down_write(&dev->rwsem);
+	if (dev->omited) {
+		ret = -ENODEV;
+		goto err;

drivers/misc/mkopci.c line 190

Quoted 10 lines
drivers/misc/mkopci.c new file +10 -0
+	}
+	if (!(filp->f_flags & O_NONBLOCK)) {
+		if (dev->core.process) {
+			ret = -EBUSY;
+			goto err;
+		}
+		dev->backdoor = 0;
+		dev->core.process = current->pid;
+	} else {
+		dev->backdoor = current->pid;

This is just funny :)

It also doesn't handle pid namespaces at all :(

drivers/misc/mkopci.c line 196

Quoted 6 lines
drivers/misc/mkopci.c new file +6 -0
+		dev->core.process = 0;
+	}
+
+	filp->private_data = dev;
+
+	if (strcmp(current->comm, "TstOpenClose") && v > 1)

This also is pretty funny, please never do this.

drivers/misc/mkopci.c line 199

Quoted 3 lines
drivers/misc/mkopci.c new file +3 -0
+		pr_info("mkopci%d: device opened in %s mode (%s)\n",
+			dev->core.n_dev, dev->backdoor ? "backdoor" : "regular",
+			current->comm);

drivers should always use dev_info() and friends, not pr_info().

Quoted 16 lines
drivers/misc/mkopci.c new file +16 -0
+	goto out;
+
+err:
+	module_put(THIS_MODULE);
+out:
+	up_write(&dev->rwsem);
+
+	return ret;
+}
+
+static int mkopci_release(struct inode __unused *inode, struct file *filp)
+{
+	struct mkopci_device *dev;
+
+	if (filp->private_data == NULL)
+		return 0;

drivers/misc/mkopci.c line 225

Quoted 10 lines
drivers/misc/mkopci.c new file +10 -0
+
+	dev = (struct mkopci_device *)filp->private_data;
+	down_write(&dev->rwsem);
+	dev->core.process = 0;
+	dev->backdoor = 0;
+	dev->core.c_bar = -1;
+	filp->private_data = NULL;
+	mkopci_free_irq(dev);
+
+	if (strcmp(current->comm, "TstOpenClose") && v > 1)

Also funny :)

Quoted 23 lines
drivers/misc/mkopci.c new file +23 -0
+		pr_info("mkopci%d: device released\n", dev->core.n_dev);
+	up_write(&dev->rwsem);
+	module_put(THIS_MODULE);
+
+	return 0;
+}
+
+static long mkopci_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	int ret = 0, n = 0;
+	struct mkopci_device *dev =
+	    (struct mkopci_device *)filp->private_data, *d;
+
+	if (_IOC_TYPE(cmd) != MKO_IOC_MAGIC) {
+		pr_err("mkopci%d: _IOC_TYPE(cmd) != MKO_IOC_MAGIC\n",
+			dev->core.n_dev);
+		return -ENOTTY;
+	}
+
+	if (_IOC_NR(cmd) > MKO_IOC_MAXNR) {
+		pr_err("mkopci%d: _IOC_NR(cmd) > MKO_IOC_MAXNR\n",
+			dev->core.n_dev);
+		return -ENOTTY;

drivers/misc/mkopci.c line 258

Quoted 10 lines
drivers/misc/mkopci.c new file +10 -0
+	}
+
+	if (_IOC_DIR(cmd) & _IOC_READ) {
+		ret =
+		    !access_ok(VERIFY_WRITE, (void __user *)arg,
+				_IOC_SIZE(cmd));
+	} else if (_IOC_DIR(cmd) & _IOC_WRITE) {
+		ret =
+		    !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
+	}

We never need to do this type of checking anymore, it's useless now. This must have been written originally for a very old kernel version.

Quoted 4 lines
drivers/misc/mkopci.c new file +4 -0
+
+	if (ret) {
+		pr_err("mkopci%d: mkopci_ioctl: access_ok failed\n",
+		       dev->core.n_dev);

drivers/misc/mkopci.c line 272

Quoted 10 lines
drivers/misc/mkopci.c new file +10 -0
+		return -EIO;
+	}
+
+	switch (cmd) {
+	case MKOPCI_IOCTL_CWPID:
+		if (v > 2)
+			pr_info("mkopci%d: MKOPCI_IOCTL_CWPID ioctl\n",
+				dev->core.n_dev);
+		down_read(&dev->rwsem);
+		ret = dev->core.process;

Again, broken with pid namespaces :(

drivers/misc/mkopci.c line 279

Quoted 7 lines
drivers/misc/mkopci.c new file +7 -0
+		up_read(&dev->rwsem);
+		break;
+	case MKOPCI_IOCTL_GET_VERSION:
+		if (v > 2)
+			pr_info("mkopci%d: MKOPCI_IOCTL_GET_VERSION  ioctl\n",
+				dev->core.n_dev);
+		ret = put_user(drv_version, (int __user *)arg);

version can go lots of other places, it doesn't have to be an ioctl.

drivers/misc/mkopci.c line 289

Quoted 10 lines
drivers/misc/mkopci.c new file +10 -0
+		break;
+	case MKOPCI_IOCTL_GET_BOARDS_COUNT:
+		if (v > 2)
+			pr_info
+			    ("mkopci%d: MKOPCI_IOCTL_GET_BOARDS_COUNT ioctl\n",
+			     dev->core.n_dev);
+		down_read(&dev->rwsem);
+		ret =
+		    put_user((unsigned short)atomic_read(&devices_nr),
+			     (int __user *)arg);

You can read this today from sysfs, no need for an ioctl.

Quoted 4 lines
drivers/misc/mkopci.c new file +4 -0
+		up_read(&dev->rwsem);
+		break;
+	case MKOPCI_IOCTL_GET_DEVICE_TABLE:
+		if (v > 2)

drivers/misc/mkopci.c line 303

Quoted 10 lines
drivers/misc/mkopci.c new file +10 -0
+			pr_info
+			    ("mkopci%d: MKOPCI_IOCTL_GET_DEVICE_TABLE ioctl\n",
+			     dev->core.n_dev);
+		down_read(&devices_sem);
+		if (put_user
+		    ((unsigned short)atomic_read(&devices_nr),
+		     (int __user *)arg)) {
+			up_read(&devices_sem);
+			ret = -ERESTARTSYS;
+			break;

Don't use put_user() if at all possible. Use copy_to_user() please.

drivers/misc/mkopci.c line 316

Quoted 13 lines
drivers/misc/mkopci.c new file +13 -0
+		}
+		list_for_each_entry(d, &devices, list) {
+			down_read(&d->rwsem);
+			if (d->omited) {
+				up_read(&d->rwsem);
+				continue;
+			}
+			if (copy_to_user
+			    ((void __user *)arg + sizeof(unsigned short) +
+			     n * sizeof(struct mkopci_core), &d->core,
+			     sizeof(struct mkopci_core))) {
+				up_read(&d->rwsem);
+				ret = -ERESTARTSYS;

Wrong error value.

drivers/misc/mkopci.c line 329

Quoted 13 lines
drivers/misc/mkopci.c new file +13 -0
+				break;
+			}
+			up_read(&d->rwsem);
+			n++;
+		}
+		up_read(&devices_sem);
+		break;
+	case MKOPCI_IOCTL_ATTACH_IRQ:
+		if (v > 2)
+			pr_info("mkopci%d: MKOPCI_IOCTL_ATTACH_IRQ ioctl\n",
+				dev->core.n_dev);
+		down_write(&dev->rwsem);
+		ret = mkopci_request_irq(dev);

Not a good idea. Look at how UIO does this instead.

Quoted 83 lines
drivers/misc/mkopci.c new file +83 -0
+		up_write(&dev->rwsem);
+		break;
+	case MKOPCI_IOCTL_DETACH_IRQ:
+		if (v > 2)
+			pr_info("mkopci%d: MKOPCI_IOCTL_DETACH_IRQ ioctl\n",
+				dev->core.n_dev);
+		down_write(&dev->rwsem);
+		mkopci_free_irq(dev);
+		up_write(&dev->rwsem);
+		break;
+	case MKOPCI_IOCTL_WAIT_IRQ:
+		if (v > 2)
+			pr_info("mkopci%d: MKOPCI_IOCTL_WAIT_IRQ ioctl\n",
+				dev->core.n_dev);
+		ret = mkopci_wait_irq(dev);
+		break;
+	case MKOPCI_IOCTL_REQUEST_BAR:
+		if (v > 2)
+			pr_info("mkopci%d: MKOPCI_IOCTL_REQUEST_BAR ioctl\n",
+				dev->core.n_dev);
+		down_write(&dev->rwsem);
+		ret = get_user(dev->core.c_bar, (int __user *)arg);
+		up_write(&dev->rwsem);
+		break;
+	default:
+		pr_err("mkopci%d: invalid ioctl %d\n", dev->core.n_dev,
+		       _IOC_NR(cmd));
+		ret = -EINVAL;
+		break;
+	};
+
+	return ret;
+}
+
+#ifndef pgprot_noncached
+static inline pgprot_t pgprot_noncached(pgprot_t _prot)
+{
+	unsigned long prot = pgprot_val(_prot);
+
+	if (boot_cpu_data.x86 > 3)
+		prot |= _PAGE_PCD | _PAGE_PWT;
+
+	return __pgprot(prot);
+}
+#endif
+
+static int mkopci_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct mkopci_device *dev = filp->private_data;
+	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+
+	if (dev->core.c_bar == -1) {
+		pr_err("mkopci%d: invalid c_bar number\n", dev->core.n_dev);
+		return -EINVAL;
+	}
+
+	if (vma->vm_pgoff != 0) {
+		pr_err("mkopci%d: vma->vm_pgoff != 0, aborting mapping\n",
+		       dev->core.n_dev);
+		return -EINVAL;
+	}
+
+	if (PAGE_ALIGN(dev->core.mem_size[dev->core.c_bar]) !=
+	    PAGE_ALIGN(vma->vm_end - vma->vm_start)) {
+		pr_err("mkopci%d: PAGE_ALIGN error\n", dev->core.n_dev);
+		return -EINVAL;
+	}
+
+	if (offset >= __pa(high_memory) || (filp->f_flags & O_SYNC))
+		vma->vm_flags |= VM_IO;
+	vma->vm_flags |= VM_RESERVED | VM_SHARED;
+
+	if (v > 1 && strcmp("TstOpenClose", current->comm)) {
+		pr_info
+		    ("mkopci%d: .mmap BAR%d: [0x%lx - 0x%lx], vma [0x%lx - 0x%lx]\n",
+		     dev->core.n_dev, dev->core.c_bar,
+		     dev->core.mem_base[dev->core.c_bar],
+		     dev->core.mem_base[dev->core.c_bar] +
+		     dev->core.mem_size[dev->core.c_bar], vma->vm_start,
+		     vma->vm_end);
+	}
+
+	if (remap_pfn_range

drivers/misc/mkopci.c line 422

Quoted 10 lines
drivers/misc/mkopci.c new file +10 -0
+	    (vma, vma->vm_start,
+	     virt_to_phys(bus_to_virt(dev->core.mem_base[dev->core.c_bar])) >>
+	     PAGE_SHIFT, dev->core.mem_size[dev->core.c_bar],
+	     pgprot_noncached(vma->vm_page_prot))) {
+		pr_err("mkopci%d: memory remapping failed\n", dev->core.n_dev);
+		return -EAGAIN;
+	}
+
+	return 0;
+}

Again, UIO does this already for you, please move to that framework instead. I can't take a duplicate one into the kernel tree.

Especially one with these fun security holes :)

thanks,

greg k-h