devices/rtdmnet.c : abuse RTDM api to allow sendmsg and recvmsg to be called indirectly from userland cobalt process ioctl, while rtdm_socket is created from a kernel thread.
/**
Network Driver for Beckhoff CCAT communication controller
Copyright (C) 2014 Beckhoff Automation GmbH
Author: Patrick Bruenn <p.bruenn@beckhoff.com>
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.
*/
#ifndef _CCAT_H_
#define _CCAT_H_
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/hrtimer.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include "../ecdev.h"
#define DRV_EXTRAVERSION "-ec"
#define DRV_VERSION "0.15" DRV_EXTRAVERSION
#define DRV_DESCRIPTION "Beckhoff CCAT Ethernet/EtherCAT Network Driver"
#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
extern const struct ccat_driver eth_eim_driver;
extern const struct ccat_driver eth_dma_driver;
#ifdef CONFIG_GPIO
extern const struct ccat_driver gpio_driver;
#endif
extern const struct ccat_driver sram_driver;
extern const struct ccat_driver update_driver;
/**
* CCAT function type identifiers (u16)
*/
enum ccat_info_t {
CCATINFO_NOTUSED = 0,
CCATINFO_ETHERCAT_NODMA = 0x3,
CCATINFO_GPIO = 0xd,
CCATINFO_EPCS_PROM = 0xf,
CCATINFO_ETHERCAT_MASTER_DMA = 0x14,
CCATINFO_SRAM = 0x16,
};
struct ccat_cdev {
atomic_t in_use;
void __iomem *ioaddr;
size_t iosize;
dev_t dev;
struct cdev cdev;
struct ccat_class *class;
};
/**
* struct cdev_buffer
* @ccdev: referenced character device
* @data: buffer used for write operations
* @size: number of bytes written to the data buffer
*/
struct cdev_buffer {
struct ccat_cdev *ccdev;
size_t size;
char data[];
};
extern int ccat_cdev_open(struct inode *const i, struct file *const f);
extern int ccat_cdev_release(struct inode *const i, struct file *const f);
/**
* struct ccat_device - CCAT device representation
* @pdev: pointer to the pci object allocated by the kernel
* @bar_0: holding information about PCI BAR 0
* @bar_2: holding information about PCI BAR 2 (optional)
* @functions: list of available (driver loaded) FPGA functions
*
* One instance of a ccat_device should represent a physical CCAT. Since
* a CCAT is implemented as FPGA the available functions can vary.
*/
struct ccat_device {
void *pdev;
void __iomem *bar_0;
void __iomem *bar_2;
struct list_head functions;
};
struct ccat_info_block {
u16 type;
u16 rev;
union {
u32 config;
u8 num_gpios;
struct {
u16 tx_size;
u16 rx_size;
};
struct {
u8 tx_dma_chan;
u8 rx_dma_chan;
};
struct {
u8 sram_width;
u8 sram_size;
u16 reserved;
};
};
u32 addr;
u32 size;
};
struct ccat_function {
const struct ccat_driver *drv;
struct ccat_device *ccat;
struct ccat_info_block info;
struct list_head list;
void *private_data;
};
struct ccat_class {
dev_t dev;
struct class *class;
atomic_t instances;
const unsigned count;
struct ccat_cdev *devices;
const char *name;
struct file_operations fops;
};
extern void ccat_cdev_remove(struct ccat_function *func);
extern int ccat_cdev_probe(struct ccat_function *func,
struct ccat_class *cdev_class, size_t iosize);
/**
* struct ccat_driver - CCAT FPGA function
* @probe: add device instance
* @remove: remove device instance
* @type: type of the FPGA function supported by this driver
* @cdev_class: if not NULL that driver supports ccat_class_init()/_exit()
*/
struct ccat_driver {
int (*probe) (struct ccat_function * func);
void (*remove) (struct ccat_function * drv);
enum ccat_info_t type;
struct ccat_class *cdev_class;
};
#endif /* #ifndef _CCAT_H_ */