linux/drivers/rapidio/devices/rio_mport_cdev.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * RapidIO mport character device
 *
 * Copyright 2014-2015 Integrated Device Technology, Inc.
 *    Alexandre Bounine <[email protected]>
 * Copyright 2014-2015 Prodrive Technologies
 *    Andre van Herk <[email protected]>
 *    Jerry Jacobs <[email protected]>
 * Copyright (C) 2014 Texas Instruments Incorporated
 *    Aurelien Jacquiot <[email protected]>
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/list.h>
#include <linux/fs.h>
#include <linux/err.h>
#include <linux/net.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/kfifo.h>

#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mman.h>

#include <linux/dma-mapping.h>
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
#include <linux/dmaengine.h>
#endif

#include <linux/rio.h>
#include <linux/rio_ids.h>
#include <linux/rio_drv.h>
#include <linux/rio_mport_cdev.h>

#include "../rio.h"

#define DRV_NAME
#define DRV_PREFIX
#define DEV_NAME
#define DRV_VERSION

/* Debug output filtering masks */
enum {};

#ifdef DEBUG
#define rmcd_debug(level, fmt, arg...)
#else
#define rmcd_debug
#endif

#define rmcd_warn(fmt, arg...)

#define rmcd_error(fmt, arg...)

MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_VERSION();

static int dma_timeout =; /* DMA transfer timeout in msec */
module_param(dma_timeout, int, S_IRUGO);
MODULE_PARM_DESC();

#ifdef DEBUG
static u32 dbg_level =;
module_param(dbg_level, uint, S_IWUSR | S_IWGRP | S_IRUGO);
MODULE_PARM_DESC();
#endif

/*
 * An internal DMA coherent buffer
 */
struct mport_dma_buf {};

/*
 * Internal memory mapping structure
 */
enum rio_mport_map_dir {};

struct rio_mport_mapping {};

struct rio_mport_dma_map {};

#define MPORT_MAX_DMA_BUFS
#define MPORT_EVENT_DEPTH

/*
 * mport_dev  driver-specific structure that represents mport device
 * @active    mport device status flag
 * @node      list node to maintain list of registered mports
 * @cdev      character device
 * @dev       associated device object
 * @mport     associated subsystem's master port device object
 * @buf_mutex lock for buffer handling
 * @file_mutex - lock for open files list
 * @file_list  - list of open files on given mport
 * @properties properties of this mport
 * @portwrites queue of inbound portwrites
 * @pw_lock    lock for port write queue
 * @mappings   queue for memory mappings
 * @dma_chan   DMA channels associated with this device
 * @dma_ref:
 * @comp:
 */
struct mport_dev {};

/*
 * mport_cdev_priv - data structure specific to individual file object
 *                   associated with an open device
 * @md    master port character device object
 * @async_queue - asynchronous notification queue
 * @list - file objects tracking list
 * @db_filters    inbound doorbell filters for this descriptor
 * @pw_filters    portwrite filters for this descriptor
 * @event_fifo    event fifo for this descriptor
 * @event_rx_wait wait queue for this descriptor
 * @fifo_lock     lock for event_fifo
 * @event_mask    event mask for this descriptor
 * @dmach DMA engine channel allocated for specific file object
 */
struct mport_cdev_priv {};

/*
 * rio_mport_pw_filter - structure to describe a portwrite filter
 * md_node   node in mport device's list
 * priv_node node in private file object's list
 * priv      reference to private data
 * filter    actual portwrite filter
 */
struct rio_mport_pw_filter {};

/*
 * rio_mport_db_filter - structure to describe a doorbell filter
 * @data_node reference to device node
 * @priv_node node in private data
 * @priv      reference to private data
 * @filter    actual doorbell filter
 */
struct rio_mport_db_filter {};

static LIST_HEAD(mport_devs);
static DEFINE_MUTEX(mport_devs_lock);

#if (0) /* used by commented out portion of poll function : FIXME */
static DECLARE_WAIT_QUEUE_HEAD(mport_cdev_wait);
#endif

static const struct class dev_class =;
static dev_t dev_number;

static void mport_release_mapping(struct kref *ref);

static int rio_mport_maint_rd(struct mport_cdev_priv *priv, void __user *arg,
			      int local)
{}

static int rio_mport_maint_wr(struct mport_cdev_priv *priv, void __user *arg,
			      int local)
{}


/*
 * Inbound/outbound memory mapping functions
 */
static int
rio_mport_create_outbound_mapping(struct mport_dev *md, struct file *filp,
				  u16 rioid, u64 raddr, u32 size,
				  dma_addr_t *paddr)
{}

static int
rio_mport_get_outbound_mapping(struct mport_dev *md, struct file *filp,
			       u16 rioid, u64 raddr, u32 size,
			       dma_addr_t *paddr)
{}

static int rio_mport_obw_map(struct file *filp, void __user *arg)
{}

/*
 * rio_mport_obw_free() - unmap an OutBound Window from RapidIO address space
 *
 * @priv: driver private data
 * @arg:  buffer handle returned by allocation routine
 */
static int rio_mport_obw_free(struct file *filp, void __user *arg)
{}

/*
 * maint_hdid_set() - Set the host Device ID
 * @priv: driver private data
 * @arg:	Device Id
 */
static int maint_hdid_set(struct mport_cdev_priv *priv, void __user *arg)
{}

/*
 * maint_comptag_set() - Set the host Component Tag
 * @priv: driver private data
 * @arg:	Component Tag
 */
static int maint_comptag_set(struct mport_cdev_priv *priv, void __user *arg)
{}

#ifdef CONFIG_RAPIDIO_DMA_ENGINE

struct mport_dma_req {};

static void mport_release_def_dma(struct kref *dma_ref)
{}

static void mport_release_dma(struct kref *dma_ref)
{}

static void dma_req_free(struct kref *ref)
{}

static void dma_xfer_callback(void *param)
{}

/*
 * prep_dma_xfer() - Configure and send request to DMAengine to prepare DMA
 *                   transfer object.
 * Returns pointer to DMA transaction descriptor allocated by DMA driver on
 * success or ERR_PTR (and/or NULL) if failed. Caller must check returned
 * non-NULL pointer using IS_ERR macro.
 */
static struct dma_async_tx_descriptor
*prep_dma_xfer(struct dma_chan *chan, struct rio_transfer_io *transfer,
	struct sg_table *sgt, int nents, enum dma_transfer_direction dir,
	enum dma_ctrl_flags flags)
{}

/* Request DMA channel associated with this mport device.
 * Try to request DMA channel for every new process that opened given
 * mport. If a new DMA channel is not available use default channel
 * which is the first DMA channel opened on mport device.
 */
static int get_dma_channel(struct mport_cdev_priv *priv)
{}

static void put_dma_channel(struct mport_cdev_priv *priv)
{}

/*
 * DMA transfer functions
 */
static int do_dma_request(struct mport_dma_req *req,
			  struct rio_transfer_io *xfer,
			  enum rio_transfer_sync sync, int nents)
{}

/*
 * rio_dma_transfer() - Perform RapidIO DMA data transfer to/from
 *                      the remote RapidIO device
 * @filp: file pointer associated with the call
 * @transfer_mode: DMA transfer mode
 * @sync: synchronization mode
 * @dir: DMA transfer direction (DMA_MEM_TO_DEV = write OR
 *                               DMA_DEV_TO_MEM = read)
 * @xfer: data transfer descriptor structure
 */
static int
rio_dma_transfer(struct file *filp, u32 transfer_mode,
		 enum rio_transfer_sync sync, enum dma_data_direction dir,
		 struct rio_transfer_io *xfer)
{}

static int rio_mport_transfer_ioctl(struct file *filp, void __user *arg)
{}

static int rio_mport_wait_for_async_dma(struct file *filp, void __user *arg)
{}

static int rio_mport_create_dma_mapping(struct mport_dev *md, struct file *filp,
			u64 size, struct rio_mport_mapping **mapping)
{}

static int rio_mport_alloc_dma(struct file *filp, void __user *arg)
{}

static int rio_mport_free_dma(struct file *filp, void __user *arg)
{}
#else
static int rio_mport_transfer_ioctl(struct file *filp, void *arg)
{
	return -ENODEV;
}

static int rio_mport_wait_for_async_dma(struct file *filp, void __user *arg)
{
	return -ENODEV;
}

static int rio_mport_alloc_dma(struct file *filp, void __user *arg)
{
	return -ENODEV;
}

static int rio_mport_free_dma(struct file *filp, void __user *arg)
{
	return -ENODEV;
}
#endif /* CONFIG_RAPIDIO_DMA_ENGINE */

/*
 * Inbound/outbound memory mapping functions
 */

static int
rio_mport_create_inbound_mapping(struct mport_dev *md, struct file *filp,
				u64 raddr, u64 size,
				struct rio_mport_mapping **mapping)
{}

static int
rio_mport_get_inbound_mapping(struct mport_dev *md, struct file *filp,
			      u64 raddr, u64 size,
			      struct rio_mport_mapping **mapping)
{}

static int rio_mport_map_inbound(struct file *filp, void __user *arg)
{}

/*
 * rio_mport_inbound_free() - unmap from RapidIO address space and free
 *                    previously allocated inbound DMA coherent buffer
 * @priv: driver private data
 * @arg:  buffer handle returned by allocation routine
 */
static int rio_mport_inbound_free(struct file *filp, void __user *arg)
{}

/*
 * maint_port_idx_get() - Get the port index of the mport instance
 * @priv: driver private data
 * @arg:  port index
 */
static int maint_port_idx_get(struct mport_cdev_priv *priv, void __user *arg)
{}

static int rio_mport_add_event(struct mport_cdev_priv *priv,
			       struct rio_event *event)
{}

static void rio_mport_doorbell_handler(struct rio_mport *mport, void *dev_id,
				       u16 src, u16 dst, u16 info)
{}

static int rio_mport_add_db_filter(struct mport_cdev_priv *priv,
				   void __user *arg)
{}

static void rio_mport_delete_db_filter(struct rio_mport_db_filter *db_filter)
{}

static int rio_mport_remove_db_filter(struct mport_cdev_priv *priv,
				      void __user *arg)
{}

static int rio_mport_match_pw(union rio_pw_msg *msg,
			      struct rio_pw_filter *filter)
{}

static int rio_mport_pw_handler(struct rio_mport *mport, void *context,
				union rio_pw_msg *msg, int step)
{}

static int rio_mport_add_pw_filter(struct mport_cdev_priv *priv,
				   void __user *arg)
{}

static void rio_mport_delete_pw_filter(struct rio_mport_pw_filter *pw_filter)
{}

static int rio_mport_match_pw_filter(struct rio_pw_filter *a,
				     struct rio_pw_filter *b)
{}

static int rio_mport_remove_pw_filter(struct mport_cdev_priv *priv,
				      void __user *arg)
{}

/*
 * rio_release_dev - release routine for kernel RIO device object
 * @dev: kernel device object associated with a RIO device structure
 *
 * Frees a RIO device struct associated a RIO device struct.
 * The RIO device struct is freed.
 */
static void rio_release_dev(struct device *dev)
{}


static void rio_release_net(struct device *dev)
{}


/*
 * rio_mport_add_riodev - creates a kernel RIO device object
 *
 * Allocates a RIO device data structure and initializes required fields based
 * on device's configuration space contents.
 * If the device has switch capabilities, then a switch specific portion is
 * allocated and configured.
 */
static int rio_mport_add_riodev(struct mport_cdev_priv *priv,
				   void __user *arg)
{}

static int rio_mport_del_riodev(struct mport_cdev_priv *priv, void __user *arg)
{}

/*
 * Mport cdev management
 */

/*
 * mport_cdev_open() - Open character device (mport)
 */
static int mport_cdev_open(struct inode *inode, struct file *filp)
{}

static int mport_cdev_fasync(int fd, struct file *filp, int mode)
{}

#ifdef CONFIG_RAPIDIO_DMA_ENGINE
static void mport_cdev_release_dma(struct file *filp)
{}
#else
#define mport_cdev_release_dma
#endif

/*
 * mport_cdev_release() - Release character device
 */
static int mport_cdev_release(struct inode *inode, struct file *filp)
{}

/*
 * mport_cdev_ioctl() - IOCTLs for character device
 */
static long mport_cdev_ioctl(struct file *filp,
		unsigned int cmd, unsigned long arg)
{}

/*
 * mport_release_mapping - free mapping resources and info structure
 * @ref: a pointer to the kref within struct rio_mport_mapping
 *
 * NOTE: Shall be called while holding buf_mutex.
 */
static void mport_release_mapping(struct kref *ref)
{}

static void mport_mm_open(struct vm_area_struct *vma)
{}

static void mport_mm_close(struct vm_area_struct *vma)
{}

static const struct vm_operations_struct vm_ops =;

static int mport_cdev_mmap(struct file *filp, struct vm_area_struct *vma)
{}

static __poll_t mport_cdev_poll(struct file *filp, poll_table *wait)
{}

static ssize_t mport_read(struct file *filp, char __user *buf, size_t count,
			loff_t *ppos)
{}

static ssize_t mport_write(struct file *filp, const char __user *buf,
			 size_t count, loff_t *ppos)
{}

static const struct file_operations mport_fops =;

/*
 * Character device management
 */

static void mport_device_release(struct device *dev)
{}

/*
 * mport_cdev_add() - Create mport_dev from rio_mport
 * @mport:	RapidIO master port
 */
static struct mport_dev *mport_cdev_add(struct rio_mport *mport)
{}

/*
 * mport_cdev_terminate_dma() - Stop all active DMA data transfers and release
 *                              associated DMA channels.
 */
static void mport_cdev_terminate_dma(struct mport_dev *md)
{}


/*
 * mport_cdev_kill_fasync() - Send SIGIO signal to all processes with open
 *                            mport_cdev files.
 */
static int mport_cdev_kill_fasync(struct mport_dev *md)
{}

/*
 * mport_cdev_remove() - Remove mport character device
 * @dev:	Mport device to remove
 */
static void mport_cdev_remove(struct mport_dev *md)
{}

/*
 * RIO rio_mport_interface driver
 */

/*
 * mport_add_mport() - Add rio_mport from LDM device struct
 * @dev:		Linux device model struct
 */
static int mport_add_mport(struct device *dev)
{}

/*
 * mport_remove_mport() - Remove rio_mport from global list
 * TODO remove device from global mport_dev list
 */
static void mport_remove_mport(struct device *dev)
{}

/* the rio_mport_interface is used to handle local mport devices */
static struct class_interface rio_mport_interface __refdata =;

/*
 * Linux kernel module
 */

/*
 * mport_init - Driver module loading
 */
static int __init mport_init(void)
{}

/**
 * mport_exit - Driver module unloading
 */
static void __exit mport_exit(void)
{}

module_init();
module_exit(mport_exit);