Commit 3f962a2c authored by Karen Xie's avatar Karen Xie

XDMA driver refresh

parent 9505aa0d
Release: 2019.2
===============
Change list:
- Updated data rate for performance run. Now it will print data rate based on the size.
- remove BUG_ON, return proper error code instead
- Streaming mode: enable credit mechanism by default
- Streaming mode: Do not read more than user supplied buffer size on C2H
- Streaming mode: Added support for Async-IO for both streaming and MM transfers
- fixed performance appliaction crash
...@@ -132,6 +132,14 @@ int xdma_user_isr_disable(void *dev_hndl, unsigned int mask); ...@@ -132,6 +132,14 @@ int xdma_user_isr_disable(void *dev_hndl, unsigned int mask);
*/ */
ssize_t xdma_xfer_submit(void *dev_hndl, int channel, bool write, u64 ep_addr, ssize_t xdma_xfer_submit(void *dev_hndl, int channel, bool write, u64 ep_addr,
struct sg_table *sgt, bool dma_mapped, int timeout_ms); struct sg_table *sgt, bool dma_mapped, int timeout_ms);
ssize_t xdma_xfer_submit_nowait(void *cb_hndl, void *dev_hndl, int channel, bool write, u64 ep_addr,
struct sg_table *sgt, bool dma_mapped, int timeout_ms);
ssize_t xdma_xfer_completion(void *cb_hndl, void *dev_hndl, int channel, bool write, u64 ep_addr,
struct sg_table *sgt, bool dma_mapped, int timeout_ms);
/////////////////////missing API//////////////////// /////////////////////missing API////////////////////
......
...@@ -13,7 +13,7 @@ ifneq ($(KERNELRELEASE),) ...@@ -13,7 +13,7 @@ ifneq ($(KERNELRELEASE),)
else else
BUILDSYSTEM_DIR:=/lib/modules/$(shell uname -r)/build BUILDSYSTEM_DIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd) PWD:=$(shell pwd)
all : all :
$(MAKE) -C $(BUILDSYSTEM_DIR) M=$(PWD) modules $(MAKE) -C $(BUILDSYSTEM_DIR) M=$(PWD) modules
clean: clean:
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -31,11 +31,11 @@ ...@@ -31,11 +31,11 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) #if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
#include <linux/swait.h> #include <linux/swait.h>
#endif #endif
/* /*
* if the config bar is fixed, the driver does not neeed to search through * if the config bar is fixed, the driver does not neeed to search through
* all of the bars * all of the bars
*/ */
//#define XDMA_CONFIG_BAR_NUM 1 //#define XDMA_CONFIG_BAR_NUM 1
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
#define XDMA_TRANSFER_MAX_DESC (2048) #define XDMA_TRANSFER_MAX_DESC (2048)
/* maximum size of a single DMA transfer descriptor */ /* maximum size of a single DMA transfer descriptor */
#define XDMA_DESC_BLEN_BITS 28 #define XDMA_DESC_BLEN_BITS 28
#define XDMA_DESC_BLEN_MAX ((1 << (XDMA_DESC_BLEN_BITS)) - 1) #define XDMA_DESC_BLEN_MAX ((1 << (XDMA_DESC_BLEN_BITS)) - 1)
/* bits of the SG DMA control register */ /* bits of the SG DMA control register */
...@@ -83,6 +83,7 @@ ...@@ -83,6 +83,7 @@
#define XDMA_CTRL_IE_DESC_ERROR (0x1FUL << 19) #define XDMA_CTRL_IE_DESC_ERROR (0x1FUL << 19)
#define XDMA_CTRL_NON_INCR_ADDR (1UL << 25) #define XDMA_CTRL_NON_INCR_ADDR (1UL << 25)
#define XDMA_CTRL_POLL_MODE_WB (1UL << 26) #define XDMA_CTRL_POLL_MODE_WB (1UL << 26)
#define XDMA_CTRL_STM_MODE_WB (1UL << 27)
/* bits of the SG DMA status register */ /* bits of the SG DMA status register */
#define XDMA_STAT_BUSY (1UL << 0) #define XDMA_STAT_BUSY (1UL << 0)
...@@ -138,7 +139,7 @@ ...@@ -138,7 +139,7 @@
/* all combined */ /* all combined */
#define XDMA_STAT_H2C_ERR_MASK \ #define XDMA_STAT_H2C_ERR_MASK \
(XDMA_STAT_COMMON_ERR_MASK | XDMA_STAT_DESC_ERR_MASK | \ (XDMA_STAT_COMMON_ERR_MASK | XDMA_STAT_DESC_ERR_MASK | \
XDMA_STAT_H2C_R_ERR_MASK | XDMA_STAT_H2C_W_ERR_MASK) XDMA_STAT_H2C_R_ERR_MASK | XDMA_STAT_H2C_W_ERR_MASK)
#define XDMA_STAT_C2H_ERR_MASK \ #define XDMA_STAT_C2H_ERR_MASK \
(XDMA_STAT_COMMON_ERR_MASK | XDMA_STAT_DESC_ERR_MASK | \ (XDMA_STAT_COMMON_ERR_MASK | XDMA_STAT_DESC_ERR_MASK | \
...@@ -161,7 +162,7 @@ ...@@ -161,7 +162,7 @@
#define XDMA_ID_C2H 0x1fc1U #define XDMA_ID_C2H 0x1fc1U
/* for C2H AXI-ST mode */ /* for C2H AXI-ST mode */
#define CYCLIC_RX_PAGES_MAX 256 #define CYCLIC_RX_PAGES_MAX 256
#define LS_BYTE_MASK 0x000000FFUL #define LS_BYTE_MASK 0x000000FFUL
...@@ -247,6 +248,23 @@ enum dev_capabilities { ...@@ -247,6 +248,23 @@ enum dev_capabilities {
/* SECTION: Structure definitions */ /* SECTION: Structure definitions */
struct xdma_io_cb {
void __user *buf;
size_t len;
void *private;
unsigned int pages_nr;
struct sg_table sgt;
struct page **pages;
/** total data size */
unsigned int count;
/** MM only, DDR/BRAM memory addr */
u64 ep_addr;
/** write: if write to the device */
struct xdma_request_cb *req;
u8 write:1;
void (*io_done)(unsigned long cb_hndl, int err);
};
struct config_regs { struct config_regs {
u32 identifier; u32 identifier;
u32 reserved_1[4]; u32 reserved_1[4];
...@@ -392,11 +410,14 @@ struct sw_desc { ...@@ -392,11 +410,14 @@ struct sw_desc {
struct xdma_transfer { struct xdma_transfer {
struct list_head entry; /* queue of non-completed transfers */ struct list_head entry; /* queue of non-completed transfers */
struct xdma_desc *desc_virt; /* virt addr of the 1st descriptor */ struct xdma_desc *desc_virt; /* virt addr of the 1st descriptor */
struct xdma_result *res_virt; /* virt addr of result for c2h streaming */
dma_addr_t res_bus; /* bus addr for result descriptors */
dma_addr_t desc_bus; /* bus addr of the first descriptor */ dma_addr_t desc_bus; /* bus addr of the first descriptor */
int desc_adjacent; /* adjacent descriptors at desc_bus */ int desc_adjacent; /* adjacent descriptors at desc_bus */
int desc_num; /* number of descriptors in transfer */ int desc_num; /* number of descriptors in transfer */
int desc_index; /* index for first descriptor in transfer */
enum dma_data_direction dir; enum dma_data_direction dir;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) #if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
struct swait_queue_head wq; struct swait_queue_head wq;
#else #else
wait_queue_head_t wq; /* wait queue for transfer completion */ wait_queue_head_t wq; /* wait queue for transfer completion */
...@@ -409,6 +430,7 @@ struct xdma_transfer { ...@@ -409,6 +430,7 @@ struct xdma_transfer {
int last_in_request; /* flag if last within request */ int last_in_request; /* flag if last within request */
unsigned int len; unsigned int len;
struct sg_table *sgt; struct sg_table *sgt;
struct xdma_io_cb *cb;
}; };
struct xdma_request_cb { struct xdma_request_cb {
...@@ -416,7 +438,8 @@ struct xdma_request_cb { ...@@ -416,7 +438,8 @@ struct xdma_request_cb {
unsigned int total_len; unsigned int total_len;
u64 ep_addr; u64 ep_addr;
struct xdma_transfer xfer; struct xdma_transfer tfer[2]; /* Use two transfers in case single request needs to be split */
struct xdma_io_cb *cb;
unsigned int sw_desc_idx; unsigned int sw_desc_idx;
unsigned int sw_desc_cnt; unsigned int sw_desc_cnt;
...@@ -450,7 +473,8 @@ struct xdma_engine { ...@@ -450,7 +473,8 @@ struct xdma_engine {
int max_extra_adj; /* descriptor prefetch capability */ int max_extra_adj; /* descriptor prefetch capability */
int desc_dequeued; /* num descriptors of completed transfers */ int desc_dequeued; /* num descriptors of completed transfers */
u32 status; /* last known status of device */ u32 status; /* last known status of device */
u32 interrupt_enable_mask_value;/* only used for MSIX mode to store per-engine interrupt mask value */ /* only used for MSIX mode to store per-engine interrupt mask value */
u32 interrupt_enable_mask_value;
/* Transfer list management */ /* Transfer list management */
struct list_head transfer_list; /* queue of transfers */ struct list_head transfer_list; /* queue of transfers */
...@@ -458,8 +482,10 @@ struct xdma_engine { ...@@ -458,8 +482,10 @@ struct xdma_engine {
/* Members applicable to AXI-ST C2H (cyclic) transfers */ /* Members applicable to AXI-ST C2H (cyclic) transfers */
struct xdma_result *cyclic_result; struct xdma_result *cyclic_result;
dma_addr_t cyclic_result_bus; /* bus addr for transfer */ dma_addr_t cyclic_result_bus; /* bus addr for transfer */
struct xdma_request_cb *cyclic_req; struct xdma_request_cb *cyclic_req;
struct sg_table cyclic_sgt; struct sg_table cyclic_sgt;
u8 *perf_buf_virt;
dma_addr_t perf_buf_bus; /* bus address */
u8 eop_found; /* used only for cyclic(rx:c2h) */ u8 eop_found; /* used only for cyclic(rx:c2h) */
int eop_count; int eop_count;
int rx_tail; /* follows the HW */ int rx_tail; /* follows the HW */
...@@ -474,7 +500,7 @@ struct xdma_engine { ...@@ -474,7 +500,7 @@ struct xdma_engine {
dma_addr_t poll_mode_bus; /* bus addr for descriptor writeback */ dma_addr_t poll_mode_bus; /* bus addr for descriptor writeback */
/* Members associated with interrupt mode support */ /* Members associated with interrupt mode support */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) #if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
struct swait_queue_head shutdown_wq; struct swait_queue_head shutdown_wq;
#else #else
wait_queue_head_t shutdown_wq; /* wait queue for shutdown sync */ wait_queue_head_t shutdown_wq; /* wait queue for shutdown sync */
...@@ -488,14 +514,23 @@ struct xdma_engine { ...@@ -488,14 +514,23 @@ struct xdma_engine {
spinlock_t desc_lock; /* protects concurrent access */ spinlock_t desc_lock; /* protects concurrent access */
dma_addr_t desc_bus; dma_addr_t desc_bus;
struct xdma_desc *desc; struct xdma_desc *desc;
int desc_idx; /* current descriptor index */
int desc_used; /* total descriptors used */
/* for performance test support */ /* for performance test support */
struct xdma_performance_ioctl *xdma_perf; /* perf test control */ struct xdma_performance_ioctl *xdma_perf; /* perf test control */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) #if KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE
struct swait_queue_head xdma_perf_wq; struct swait_queue_head xdma_perf_wq;
#else #else
wait_queue_head_t xdma_perf_wq; /* Perf test sync */ wait_queue_head_t xdma_perf_wq; /* Perf test sync */
#endif #endif
struct xdma_kthread *cmplthp;
/* completion status thread list for the queue */
struct list_head cmplthp_list;
/* pending work thread list */
/* cpu attached to intr_work */
unsigned int intr_work_cpu;
}; };
struct xdma_user_irq { struct xdma_user_irq {
...@@ -506,14 +541,14 @@ struct xdma_user_irq { ...@@ -506,14 +541,14 @@ struct xdma_user_irq {
wait_queue_head_t events_wq; /* wait queue to sync waiting threads */ wait_queue_head_t events_wq; /* wait queue to sync waiting threads */
irq_handler_t handler; irq_handler_t handler;
void *dev; void *dev;
}; };
/* XDMA PCIe device specific book-keeping */ /* XDMA PCIe device specific book-keeping */
#define XDEV_FLAG_OFFLINE 0x1 #define XDEV_FLAG_OFFLINE 0x1
struct xdma_dev { struct xdma_dev {
struct list_head list_head; struct list_head list_head;
struct list_head rcu_node; struct list_head rcu_node;
unsigned long magic; /* structure ID for sanity checks */ unsigned long magic; /* structure ID for sanity checks */
struct pci_dev *pdev; /* pci device struct from probe() */ struct pci_dev *pdev; /* pci device struct from probe() */
...@@ -525,7 +560,7 @@ struct xdma_dev { ...@@ -525,7 +560,7 @@ struct xdma_dev {
unsigned int flags; unsigned int flags;
/* PCIe BAR management */ /* PCIe BAR management */
void *__iomem bar[XDMA_BAR_NUM]; /* addresses for mapped BARs */ void __iomem *bar[XDMA_BAR_NUM]; /* addresses for mapped BARs */
int user_bar_idx; /* BAR index of user logic */ int user_bar_idx; /* BAR index of user logic */
int config_bar_idx; /* BAR index of XDMA config logic */ int config_bar_idx; /* BAR index of XDMA config logic */
int bypass_bar_idx; /* BAR index of XDMA bypass logic */ int bypass_bar_idx; /* BAR index of XDMA bypass logic */
...@@ -541,7 +576,7 @@ struct xdma_dev { ...@@ -541,7 +576,7 @@ struct xdma_dev {
int irq_line; /* flag if irq allocated successfully */ int irq_line; /* flag if irq allocated successfully */
int msi_enabled; /* flag if msi was enabled for the device */ int msi_enabled; /* flag if msi was enabled for the device */
int msix_enabled; /* flag if msi-x was enabled for the device */ int msix_enabled; /* flag if msi-x was enabled for the device */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0) #if KERNEL_VERSION(4, 12, 0) > LINUX_VERSION_CODE
struct msix_entry entry[32]; /* msi-x vector/entry table */ struct msix_entry entry[32]; /* msi-x vector/entry table */
#endif #endif
struct xdma_user_irq user_irq[16]; /* user IRQ management */ struct xdma_user_irq user_irq[16]; /* user IRQ management */
...@@ -621,8 +656,8 @@ void get_perf_stats(struct xdma_engine *engine); ...@@ -621,8 +656,8 @@ void get_perf_stats(struct xdma_engine *engine);
int xdma_cyclic_transfer_setup(struct xdma_engine *engine); int xdma_cyclic_transfer_setup(struct xdma_engine *engine);
int xdma_cyclic_transfer_teardown(struct xdma_engine *engine); int xdma_cyclic_transfer_teardown(struct xdma_engine *engine);
ssize_t xdma_engine_read_cyclic(struct xdma_engine *, char __user *, size_t, ssize_t xdma_engine_read_cyclic(struct xdma_engine *engine,
int); char __user *buf, size_t count, int timeout_ms);
int engine_addrmode_set(struct xdma_engine *engine, unsigned long arg); int engine_addrmode_set(struct xdma_engine *engine, unsigned long arg);
int engine_service_poll(struct xdma_engine *engine, u32 expected_desc_count);
#endif /* XDMA_LIB_H */ #endif /* XDMA_LIB_H */
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
#ifndef __XDMA_VERSION_H__ #ifndef __XDMA_VERSION_H__
#define __XDMA_VERSION_H__ #define __XDMA_VERSION_H__
#define DRV_MOD_MAJOR 2018 #define DRV_MOD_MAJOR 2019
#define DRV_MOD_MINOR 3 #define DRV_MOD_MINOR 2
#define DRV_MOD_PATCHLEVEL 41 #define DRV_MOD_PATCHLEVEL 42
#define DRV_MODULE_VERSION \ #define DRV_MODULE_VERSION \
__stringify(DRV_MOD_MAJOR) "." \ __stringify(DRV_MOD_MAJOR) "." \
......
...@@ -18,12 +18,12 @@ EXTRA_CFLAGS := -I$(topdir)/include $(XVC_FLAGS) ...@@ -18,12 +18,12 @@ EXTRA_CFLAGS := -I$(topdir)/include $(XVC_FLAGS)
#EXTRA_CFLAGS += -DINTERNAL_TESTING #EXTRA_CFLAGS += -DINTERNAL_TESTING
ifneq ($(KERNELRELEASE),) ifneq ($(KERNELRELEASE),)
$(TARGET_MODULE)-objs := libxdma.o xdma_cdev.o cdev_ctrl.o cdev_events.o cdev_sgdma.o cdev_xvc.o cdev_bypass.o xdma_mod.o $(TARGET_MODULE)-objs := libxdma.o xdma_cdev.o cdev_ctrl.o cdev_events.o cdev_sgdma.o cdev_xvc.o cdev_bypass.o xdma_mod.o xdma_thread.o
obj-m := $(TARGET_MODULE).o obj-m := $(TARGET_MODULE).o
else else
BUILDSYSTEM_DIR:=/lib/modules/$(shell uname -r)/build BUILDSYSTEM_DIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd) PWD:=$(shell pwd)
all : all :
$(MAKE) -C $(BUILDSYSTEM_DIR) M=$(PWD) modules $(MAKE) -C $(BUILDSYSTEM_DIR) M=$(PWD) modules
clean: clean:
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include "libxdma_api.h" #include "libxdma_api.h"
#include "xdma_cdev.h" #include "xdma_cdev.h"
#define write_register(v,mem,off) iowrite32(v, mem) #define write_register(v, mem, off) iowrite32(v, mem)
static int copy_desc_data(struct xdma_transfer *transfer, char __user *buf, static int copy_desc_data(struct xdma_transfer *transfer, char __user *buf,
size_t *buf_offset, size_t buf_size) size_t *buf_offset, size_t buf_size)
...@@ -29,8 +29,15 @@ static int copy_desc_data(struct xdma_transfer *transfer, char __user *buf, ...@@ -29,8 +29,15 @@ static int copy_desc_data(struct xdma_transfer *transfer, char __user *buf,
int copy_err; int copy_err;
int rc = 0; int rc = 0;
BUG_ON(!buf); if (!buf) {
BUG_ON(!buf_offset); pr_err("Invalid user buffer\n");
return -EINVAL;
}
if (!buf_offset) {
pr_err("Invalid user buffer offset\n");
return -EINVAL;
}
/* Fill user buffer with descriptor data */ /* Fill user buffer with descriptor data */
for (i = 0; i < transfer->desc_num; i++) { for (i = 0; i < transfer->desc_num; i++) {
...@@ -71,7 +78,7 @@ static ssize_t char_bypass_read(struct file *file, char __user *buf, ...@@ -71,7 +78,7 @@ static ssize_t char_bypass_read(struct file *file, char __user *buf,
xdev = xcdev->xdev; xdev = xcdev->xdev;
engine = xcdev->engine; engine = xcdev->engine;
dbg_sg("In char_bypass_read()\n"); dbg_sg("In %s()\n", __func__);
if (count & 3) { if (count & 3) {
dbg_sg("Buffer size must be a multiple of 4 bytes\n"); dbg_sg("Buffer size must be a multiple of 4 bytes\n");
...@@ -114,7 +121,7 @@ static ssize_t char_bypass_write(struct file *file, const char __user *buf, ...@@ -114,7 +121,7 @@ static ssize_t char_bypass_write(struct file *file, const char __user *buf,
struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data; struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data;
u32 desc_data; u32 desc_data;
u32 *bypass_addr; void __iomem *bypass_addr;
size_t buf_offset = 0; size_t buf_offset = 0;
int rc = 0; int rc = 0;
int copy_err; int copy_err;
...@@ -140,18 +147,21 @@ static ssize_t char_bypass_write(struct file *file, const char __user *buf, ...@@ -140,18 +147,21 @@ static ssize_t char_bypass_write(struct file *file, const char __user *buf,
return -ENODEV; return -ENODEV;
} }
dbg_sg("In char_bypass_write()\n"); dbg_sg("In %s()\n", __func__);
spin_lock(&engine->lock); spin_lock(&engine->lock);
/* Write descriptor data to the bypass BAR */ /* Write descriptor data to the bypass BAR */
bypass_addr = (u32 *)xdev->bar[xdev->bypass_bar_idx]; bypass_addr = xdev->bar[xdev->bypass_bar_idx];
bypass_addr += engine->bypass_offset; bypass_addr = (void __iomem *)(
(u32 __iomem *)bypass_addr + engine->bypass_offset
);
while (buf_offset < count) { while (buf_offset < count) {
copy_err = copy_from_user(&desc_data, &buf[buf_offset], copy_err = copy_from_user(&desc_data, &buf[buf_offset],
sizeof(u32)); sizeof(u32));
if (!copy_err) { if (!copy_err) {
write_register(desc_data, bypass_addr, bypass_addr - engine->bypass_offset); write_register(desc_data, bypass_addr,
bypass_addr - engine->bypass_offset);
buf_offset += sizeof(u32); buf_offset += sizeof(u32);
rc = buf_offset; rc = buf_offset;
} else { } else {
...@@ -183,5 +193,5 @@ static const struct file_operations bypass_fops = { ...@@ -183,5 +193,5 @@ static const struct file_operations bypass_fops = {
void cdev_bypass_init(struct xdma_cdev *xcdev) void cdev_bypass_init(struct xdma_cdev *xcdev)
{ {
cdev_init(&xcdev->cdev, &bypass_fops); cdev_init(&xcdev->cdev, &bypass_fops);
} }
...@@ -32,13 +32,13 @@ static ssize_t char_ctrl_read(struct file *fp, char __user *buf, size_t count, ...@@ -32,13 +32,13 @@ static ssize_t char_ctrl_read(struct file *fp, char __user *buf, size_t count,
{ {
struct xdma_cdev *xcdev = (struct xdma_cdev *)fp->private_data; struct xdma_cdev *xcdev = (struct xdma_cdev *)fp->private_data;
struct xdma_dev *xdev; struct xdma_dev *xdev;
void *reg; void __iomem *reg;
u32 w; u32 w;
int rv; int rv;
rv = xcdev_check(__func__, xcdev, 0); rv = xcdev_check(__func__, xcdev, 0);
if (rv < 0) if (rv < 0)
return rv; return rv;
xdev = xcdev->xdev; xdev = xcdev->xdev;
/* only 32-bit aligned and 32-bit multiples */ /* only 32-bit aligned and 32-bit multiples */
...@@ -48,8 +48,8 @@ static ssize_t char_ctrl_read(struct file *fp, char __user *buf, size_t count, ...@@ -48,8 +48,8 @@ static ssize_t char_ctrl_read(struct file *fp, char __user *buf, size_t count,
reg = xdev->bar[xcdev->bar] + *pos; reg = xdev->bar[xcdev->bar] + *pos;
//w = read_register(reg); //w = read_register(reg);
w = ioread32(reg); w = ioread32(reg);
dbg_sg("char_ctrl_read(@%p, count=%ld, pos=%d) value = 0x%08x\n", reg, dbg_sg("%s(@%p, count=%ld, pos=%d) value = 0x%08x\n",
(long)count, (int)*pos, w); __func__, reg, (long)count, (int)*pos, w);
rv = copy_to_user(buf, &w, 4); rv = copy_to_user(buf, &w, 4);
if (rv) if (rv)
dbg_sg("Copy to userspace failed but continuing\n"); dbg_sg("Copy to userspace failed but continuing\n");
...@@ -63,13 +63,13 @@ static ssize_t char_ctrl_write(struct file *file, const char __user *buf, ...@@ -63,13 +63,13 @@ static ssize_t char_ctrl_write(struct file *file, const char __user *buf,
{ {
struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data; struct xdma_cdev *xcdev = (struct xdma_cdev *)file->private_data;
struct xdma_dev *xdev; struct xdma_dev *xdev;
void *reg; void __iomem *reg;
u32 w; u32 w;
int rv; int rv;
rv = xcdev_check(__func__, xcdev, 0); rv = xcdev_check(__func__, xcdev, 0);
if (rv < 0) if (rv < 0)
return rv; return rv;
xdev = xcdev->xdev; xdev = xcdev->xdev;
/* only 32-bit aligned and 32-bit multiples */ /* only 32-bit aligned and 32-bit multiples */
...@@ -79,12 +79,11 @@ static ssize_t char_ctrl_write(struct file *file, const char __user *buf, ...@@ -79,12 +79,11 @@ static ssize_t char_ctrl_write(struct file *file, const char __user *buf,
/* first address is BAR base plus file position offset */ /* first address is BAR base plus file position offset */
reg = xdev->bar[xcdev->bar] + *pos; reg = xdev->bar[xcdev->bar] + *pos;
rv = copy_from_user(&w, buf, 4); rv = copy_from_user(&w, buf, 4);
if (rv) { if (rv)
pr_info("copy from user failed %d/4, but continuing.\n", rv); pr_info("copy from user failed %d/4, but continuing.\n", rv);
}
dbg_sg("char_ctrl_write(0x%08x @%p, count=%ld, pos=%d)\n", w, reg, dbg_sg("%s(0x%08x @%p, count=%ld, pos=%d)\n",
(long)count, (int)*pos); __func__, w, reg, (long)count, (int)*pos);
//write_register(w, reg); //write_register(w, reg);
iowrite32(w, reg); iowrite32(w, reg);
*pos += 4; *pos += 4;
...@@ -129,7 +128,7 @@ long char_ctrl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -129,7 +128,7 @@ long char_ctrl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
rv = xcdev_check(__func__, xcdev, 0); rv = xcdev_check(__func__, xcdev, 0);
if (rv < 0) if (rv < 0)
return rv; return rv;
xdev = xcdev->xdev; xdev = xcdev->xdev;
if (!xdev) { if (!xdev) {
...@@ -158,7 +157,7 @@ long char_ctrl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -158,7 +157,7 @@ long char_ctrl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
switch (cmd) { switch (cmd) {
case XDMA_IOCINFO: case XDMA_IOCINFO:
if (copy_from_user((void *)&ioctl_obj, (void *) arg, if (copy_from_user((void *)&ioctl_obj, (void __user *) arg,
sizeof(struct xdma_ioc_base))) { sizeof(struct xdma_ioc_base))) {
pr_err("copy_from_user failed.\n"); pr_err("copy_from_user failed.\n");
return -EFAULT; return -EFAULT;
...@@ -196,7 +195,7 @@ int bridge_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -196,7 +195,7 @@ int bridge_mmap(struct file *file, struct vm_area_struct *vma)
rv = xcdev_check(__func__, xcdev, 0); rv = xcdev_check(__func__, xcdev, 0);
if (rv < 0) if (rv < 0)
return rv; return rv;
xdev = xcdev->xdev; xdev = xcdev->xdev;
off = vma->vm_pgoff << PAGE_SHIFT; off = vma->vm_pgoff << PAGE_SHIFT;
......
...@@ -60,14 +60,14 @@ struct xdma_ioc_base { ...@@ -60,14 +60,14 @@ struct xdma_ioc_base {
}; };
struct xdma_ioc_info { struct xdma_ioc_info {
struct xdma_ioc_base base; struct xdma_ioc_base base;
unsigned short vendor; unsigned short vendor;
unsigned short device; unsigned short device;
unsigned short subsystem_vendor; unsigned short subsystem_vendor;
unsigned short subsystem_device; unsigned short subsystem_device;
unsigned int dma_engine_version; unsigned int dma_engine_version;
unsigned int driver_version; unsigned int driver_version;
unsigned long long feature_id; unsigned long long feature_id;
unsigned short domain; unsigned short domain;
unsigned char bus; unsigned char bus;
unsigned char dev; unsigned char dev;
......
...@@ -35,7 +35,7 @@ static ssize_t char_events_read(struct file *file, char __user *buf, ...@@ -35,7 +35,7 @@ static ssize_t char_events_read(struct file *file, char __user *buf,
rv = xcdev_check(__func__, xcdev, 0); rv = xcdev_check(__func__, xcdev, 0);
if (rv < 0) if (rv < 0)
return rv; return rv;
user_irq = xcdev->user_irq; user_irq = xcdev->user_irq;
if (!user_irq) { if (!user_irq) {
pr_info("xcdev 0x%p, user_irq NULL.\n", xcdev); pr_info("xcdev 0x%p, user_irq NULL.\n", xcdev);
...@@ -84,7 +84,7 @@ static unsigned int char_events_poll(struct file *file, poll_table *wait) ...@@ -84,7 +84,7 @@ static unsigned int char_events_poll(struct file *file, poll_table *wait)
rv = xcdev_check(__func__, xcdev, 0); rv = xcdev_check(__func__, xcdev, 0);
if (rv < 0) if (rv < 0)
return rv; return rv;
user_irq = xcdev->user_irq; user_irq = xcdev->user_irq;
if (!user_irq) { if (!user_irq) {
pr_info("xcdev 0x%p, user_irq NULL.\n", xcdev); pr_info("xcdev 0x%p, user_irq NULL.\n", xcdev);
......
This diff is collapsed.
...@@ -46,17 +46,16 @@ ...@@ -46,17 +46,16 @@
* _IOC_SIZE(nr) returns size * _IOC_SIZE(nr) returns size
*/ */
struct xdma_performance_ioctl struct xdma_performance_ioctl {
{ /* IOCTL_XDMA_IOCTL_Vx */
/* IOCTL_XDMA_IOCTL_Vx */ uint32_t version;
uint32_t version; uint32_t transfer_size;
uint32_t transfer_size; /* measurement */
/* measurement */ uint32_t stopped;
uint32_t stopped; uint32_t iterations;
uint32_t iterations; uint64_t clock_cycle_count;
uint64_t clock_cycle_count; uint64_t data_cycle_count;
uint64_t data_cycle_count; uint64_t pending_count;
uint64_t pending_count;
}; };
......
...@@ -32,30 +32,30 @@ ...@@ -32,30 +32,30 @@
#ifdef __REG_DEBUG__ #ifdef __REG_DEBUG__
/* SECTION: Function definitions */ /* SECTION: Function definitions */
inline void __write_register(const char *fn, u32 value, void *base, inline void __write_register(const char *fn, u32 value, void __iomem *base,
unsigned int off) unsigned int off)
{ {
pr_info("%s: 0x%p, W reg 0x%lx, 0x%x.\n", fn, base, off, value); pr_info("%s: 0x%p, W reg 0x%lx, 0x%x.\n", fn, base, off, value);
iowrite32(value, base + off); iowrite32(value, base + off);
} }
inline u32 __read_register(const char *fn, void *base, unsigned int off) inline u32 __read_register(const char *fn, void __iomem *base, unsigned int off)
{ {
u32 v = ioread32(base + off); u32 v = ioread32(base + off);
pr_info("%s: 0x%p, R reg 0x%lx, 0x%x.\n", fn, base, off, v); pr_info("%s: 0x%p, R reg 0x%lx, 0x%x.\n", fn, base, off, v);
return v; return v;
} }
#define write_register(v,base,off) __write_register(__func__, v, base, off) #define write_register(v, base, off) __write_register(__func__, v, base, off)
#define read_register(base,off) __read_register(__func__, base, off) #define read_register(base, off) __read_register(__func__, base, off)
#else #else
#define write_register(v,base,off) iowrite32(v, (base) + (off)) #define write_register(v, base, off) iowrite32(v, (base) + (off))
#define read_register(base,off) ioread32((base) + (off)) #define read_register(base, off) ioread32((base) + (off))
#endif /* #ifdef __REG_DEBUG__ */ #endif /* #ifdef __REG_DEBUG__ */
static int xvc_shift_bits(void *base, u32 tms_bits, u32 tdi_bits, static int xvc_shift_bits(void __iomem *base, u32 tms_bits, u32 tdi_bits,
u32 *tdo_bits) u32 *tdo_bits)
{ {
u32 control; u32 control;
...@@ -92,7 +92,7 @@ static int xvc_shift_bits(void *base, u32 tms_bits, u32 tdi_bits, ...@@ -92,7 +92,7 @@ static int xvc_shift_bits(void *base, u32 tms_bits, u32 tdi_bits,
static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{ {
struct xdma_cdev *xcdev = (struct xdma_cdev *)filp->private_data; struct xdma_cdev *xcdev = (struct xdma_cdev *)filp->private_data;
struct xdma_dev *xdev; struct xdma_dev *xdev;
struct xvc_ioc xvc_obj; struct xvc_ioc xvc_obj;
unsigned int opcode; unsigned int opcode;
...@@ -109,6 +109,7 @@ static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -109,6 +109,7 @@ static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
rv = xcdev_check(__func__, xcdev, 0); rv = xcdev_check(__func__, xcdev, 0);
if (rv < 0) if (rv < 0)
return rv; return rv;
xdev = xcdev->xdev; xdev = xcdev->xdev;
if (cmd != XDMA_IOCXVC) { if (cmd != XDMA_IOCXVC) {
...@@ -135,7 +136,7 @@ static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -135,7 +136,7 @@ static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
total_bits = xvc_obj.length; total_bits = xvc_obj.length;
total_bytes = (total_bits + 7) >> 3; total_bytes = (total_bits + 7) >> 3;
buffer = (char *)kmalloc(total_bytes * 3, GFP_KERNEL); buffer = (unsigned char *)kmalloc(total_bytes * 3, GFP_KERNEL);
if (!buffer) { if (!buffer) {
pr_info("OOM %u, op 0x%x, len %u bits, %u bytes.\n", pr_info("OOM %u, op 0x%x, len %u bits, %u bytes.\n",
3 * total_bytes, opcode, total_bits, total_bytes); 3 * total_bytes, opcode, total_bits, total_bytes);
...@@ -146,12 +147,16 @@ static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -146,12 +147,16 @@ static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
tdi_buf = tms_buf + total_bytes; tdi_buf = tms_buf + total_bytes;
tdo_buf = tdi_buf + total_bytes; tdo_buf = tdi_buf + total_bytes;
rv = copy_from_user((void *)tms_buf, xvc_obj.tms_buf, total_bytes); rv = copy_from_user((void *)tms_buf,
(const char __user *)xvc_obj.tms_buf,
total_bytes);
if (rv) { if (rv) {
pr_info("copy tmfs_buf failed: %d/%u.\n", rv, total_bytes); pr_info("copy tmfs_buf failed: %d/%u.\n", rv, total_bytes);
goto cleanup; goto cleanup;
} }
rv = copy_from_user((void *)tdi_buf, xvc_obj.tdi_buf, total_bytes); rv = copy_from_user((void *)tdi_buf,
(const char __user *)xvc_obj.tdi_buf,
total_bytes);
if (rv) { if (rv) {
pr_info("copy tdi_buf failed: %d/%u.\n", rv, total_bytes); pr_info("copy tdi_buf failed: %d/%u.\n", rv, total_bytes);
goto cleanup; goto cleanup;
...@@ -162,7 +167,8 @@ static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -162,7 +167,8 @@ static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
iobase = xdev->bar[xcdev->bar] + xcdev->base; iobase = xdev->bar[xcdev->bar] + xcdev->base;
/* set length register to 32 initially if more than one /* set length register to 32 initially if more than one
* word-transaction is to be done */ * word-transaction is to be done
*/
if (total_bits >= 32) if (total_bits >= 32)
write_register(0x20, iobase, XVC_BAR_LENGTH_REG); write_register(0x20, iobase, XVC_BAR_LENGTH_REG);
...@@ -173,7 +179,7 @@ static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -173,7 +179,7 @@ static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
u32 tms_store = 0; u32 tms_store = 0;
u32 tdi_store = 0; u32 tdi_store = 0;
u32 tdo_store = 0; u32 tdo_store = 0;
if (bits_left < 32) { if (bits_left < 32) {
/* set number of bits to shift out */ /* set number of bits to shift out */
write_register(bits_left, iobase, XVC_BAR_LENGTH_REG); write_register(bits_left, iobase, XVC_BAR_LENGTH_REG);
...@@ -186,33 +192,33 @@ static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -186,33 +192,33 @@ static long xvc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
/* Shift data out and copy to output buffer */ /* Shift data out and copy to output buffer */
rv = xvc_shift_bits(iobase, tms_store, tdi_store, &tdo_store); rv = xvc_shift_bits(iobase, tms_store, tdi_store, &tdo_store);
if (rv < 0) if (rv < 0)
goto cleanup; break;
memcpy(tdo_buf + bytes, &tdo_store, shift_bytes); memcpy(tdo_buf + bytes, &tdo_store, shift_bytes);
} }
if (rv < 0)
goto unlock;
/* if testing bar access swap tdi and tdo bufferes to "loopback" */ /* if testing bar access swap tdi and tdo bufferes to "loopback" */
if (opcode == 0x2) { if (opcode == 0x2) {
char *tmp = tdo_buf; unsigned char *tmp = tdo_buf;
tdo_buf = tdi_buf; tdo_buf = tdi_buf;
tdi_buf = tmp; tdi_buf = tmp;
} }
rv = copy_to_user((void *)xvc_obj.tdo_buf, tdo_buf, total_bytes); rv = copy_to_user(xvc_obj.tdo_buf, (const void *)tdo_buf, total_bytes);
if (rv) { if (rv)
pr_info("copy back tdo_buf failed: %d/%u.\n", rv, total_bytes); pr_info("copy back tdo_buf failed: %d/%u.\n", rv, total_bytes);
rv = -EFAULT;
goto cleanup;
}
cleanup:
if (buffer)
kfree(buffer);
unlock:
mmiowb(); mmiowb();
spin_unlock(&xcdev->lock); spin_unlock(&xcdev->lock);
cleanup:
kfree(buffer);
return rv; return rv;
} }
...@@ -220,10 +226,10 @@ cleanup: ...@@ -220,10 +226,10 @@ cleanup:
* character device file operations for the XVC * character device file operations for the XVC
*/ */
static const struct file_operations xvc_fops = { static const struct file_operations xvc_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = char_open, .open = char_open,
.release = char_close, .release = char_close,
.unlocked_ioctl = xvc_ioctl, .unlocked_ioctl = xvc_ioctl,
}; };
void cdev_xvc_init(struct xdma_cdev *xcdev) void cdev_xvc_init(struct xdma_cdev *xcdev)
......
...@@ -33,9 +33,9 @@ ...@@ -33,9 +33,9 @@
struct xvc_ioc { struct xvc_ioc {
unsigned int opcode; unsigned int opcode;
unsigned int length; unsigned int length;
unsigned char *tms_buf; const char __user *tms_buf;
unsigned char *tdi_buf; const char __user *tdi_buf;
unsigned char *tdo_buf; void __user *tdo_buf;
}; };
#define XDMA_IOCXVC _IOWR(XVC_MAGIC, 1, struct xvc_ioc) #define XDMA_IOCXVC _IOWR(XVC_MAGIC, 1, struct xvc_ioc)
......
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
#ifndef __XDMA_VERSION_H__ #ifndef __XDMA_VERSION_H__
#define __XDMA_VERSION_H__ #define __XDMA_VERSION_H__
#define DRV_MOD_MAJOR 2018 #define DRV_MOD_MAJOR 2019
#define DRV_MOD_MINOR 3 #define DRV_MOD_MINOR 2
#define DRV_MOD_PATCHLEVEL 50 #define DRV_MOD_PATCHLEVEL 51
#define DRV_MODULE_VERSION \ #define DRV_MODULE_VERSION \
__stringify(DRV_MOD_MAJOR) "." \ __stringify(DRV_MOD_MAJOR) "." \
......
This diff is collapsed.
...@@ -35,13 +35,13 @@ int xdma_cdev_init(void); ...@@ -35,13 +35,13 @@ int xdma_cdev_init(void);
int char_open(struct inode *inode, struct file *file); int char_open(struct inode *inode, struct file *file);
int char_close(struct inode *inode, struct file *file); int char_close(struct inode *inode, struct file *file);
int xcdev_check(const char *, struct xdma_cdev *, bool); int xcdev_check(const char *fname, struct xdma_cdev *xcdev, bool check_engine);
void cdev_ctrl_init(struct xdma_cdev *xcdev); void cdev_ctrl_init(struct xdma_cdev *xcdev);
void cdev_xvc_init(struct xdma_cdev *xcdev); void cdev_xvc_init(struct xdma_cdev *xcdev);
void cdev_event_init(struct xdma_cdev *xcdev); void cdev_event_init(struct xdma_cdev *xcdev);
void cdev_sgdma_init(struct xdma_cdev *xcdev); void cdev_sgdma_init(struct xdma_cdev *xcdev);
void cdev_bypass_init(struct xdma_cdev *xcdev); void cdev_bypass_init(struct xdma_cdev *xcdev);
long char_ctrl_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
void xpdev_destroy_interfaces(struct xdma_pci_dev *xpdev); void xpdev_destroy_interfaces(struct xdma_pci_dev *xpdev);
int xpdev_create_interfaces(struct xdma_pci_dev *xpdev); int xpdev_create_interfaces(struct xdma_pci_dev *xpdev);
......
...@@ -40,51 +40,51 @@ static char version[] = ...@@ -40,51 +40,51 @@ static char version[] =
MODULE_AUTHOR("Xilinx, Inc."); MODULE_AUTHOR("Xilinx, Inc.");
MODULE_DESCRIPTION(DRV_MODULE_DESC); MODULE_DESCRIPTION(DRV_MODULE_DESC);
MODULE_VERSION(DRV_MODULE_VERSION); MODULE_VERSION(DRV_MODULE_VERSION);
MODULE_LICENSE("GPL"); MODULE_LICENSE("Dual BSD/GPL");
/* SECTION: Module global variables */ /* SECTION: Module global variables */
static int xpdev_cnt = 0; static int xpdev_cnt;
static const struct pci_device_id pci_ids[] = { static const struct pci_device_id pci_ids[] = {
{ PCI_DEVICE(0x10ee, 0x903f), }, { PCI_DEVICE(0x10ee, 0x903f), },
{ PCI_DEVICE(0x10ee, 0x9038), }, { PCI_DEVICE(0x10ee, 0x9038), },
{ PCI_DEVICE(0x10ee, 0x9028), }, { PCI_DEVICE(0x10ee, 0x9028), },
{ PCI_DEVICE(0x10ee, 0x9018), }, { PCI_DEVICE(0x10ee, 0x9018), },
{ PCI_DEVICE(0x10ee, 0x9034), }, { PCI_DEVICE(0x10ee, 0x9034), },
{ PCI_DEVICE(0x10ee, 0x9024), }, { PCI_DEVICE(0x10ee, 0x9024), },
{ PCI_DEVICE(0x10ee, 0x9014), }, { PCI_DEVICE(0x10ee, 0x9014), },
{ PCI_DEVICE(0x10ee, 0x9032), }, { PCI_DEVICE(0x10ee, 0x9032), },
{ PCI_DEVICE(0x10ee, 0x9022), }, { PCI_DEVICE(0x10ee, 0x9022), },
{ PCI_DEVICE(0x10ee, 0x9012), }, { PCI_DEVICE(0x10ee, 0x9012), },
{ PCI_DEVICE(0x10ee, 0x9031), }, { PCI_DEVICE(0x10ee, 0x9031), },
{ PCI_DEVICE(0x10ee, 0x9021), }, { PCI_DEVICE(0x10ee, 0x9021), },
{ PCI_DEVICE(0x10ee, 0x9011), }, { PCI_DEVICE(0x10ee, 0x9011), },
{ PCI_DEVICE(0x10ee, 0x8011), }, { PCI_DEVICE(0x10ee, 0x8011), },
{ PCI_DEVICE(0x10ee, 0x8012), }, { PCI_DEVICE(0x10ee, 0x8012), },
{ PCI_DEVICE(0x10ee, 0x8014), }, { PCI_DEVICE(0x10ee, 0x8014), },
{ PCI_DEVICE(0x10ee, 0x8018), }, { PCI_DEVICE(0x10ee, 0x8018), },
{ PCI_DEVICE(0x10ee, 0x8021), }, { PCI_DEVICE(0x10ee, 0x8021), },
{ PCI_DEVICE(0x10ee, 0x8022), }, { PCI_DEVICE(0x10ee, 0x8022), },
{ PCI_DEVICE(0x10ee, 0x8024), }, { PCI_DEVICE(0x10ee, 0x8024), },
{ PCI_DEVICE(0x10ee, 0x8028), }, { PCI_DEVICE(0x10ee, 0x8028), },
{ PCI_DEVICE(0x10ee, 0x8031), }, { PCI_DEVICE(0x10ee, 0x8031), },
{ PCI_DEVICE(0x10ee, 0x8032), }, { PCI_DEVICE(0x10ee, 0x8032), },
{ PCI_DEVICE(0x10ee, 0x8034), }, { PCI_DEVICE(0x10ee, 0x8034), },
{ PCI_DEVICE(0x10ee, 0x8038), }, { PCI_DEVICE(0x10ee, 0x8038), },
{ PCI_DEVICE(0x10ee, 0x7011), }, { PCI_DEVICE(0x10ee, 0x7011), },
{ PCI_DEVICE(0x10ee, 0x7012), }, { PCI_DEVICE(0x10ee, 0x7012), },
{ PCI_DEVICE(0x10ee, 0x7014), }, { PCI_DEVICE(0x10ee, 0x7014), },
{ PCI_DEVICE(0x10ee, 0x7018), }, { PCI_DEVICE(0x10ee, 0x7018), },
{ PCI_DEVICE(0x10ee, 0x7021), }, { PCI_DEVICE(0x10ee, 0x7021), },
{ PCI_DEVICE(0x10ee, 0x7022), }, { PCI_DEVICE(0x10ee, 0x7022), },
{ PCI_DEVICE(0x10ee, 0x7024), }, { PCI_DEVICE(0x10ee, 0x7024), },
{ PCI_DEVICE(0x10ee, 0x7028), }, { PCI_DEVICE(0x10ee, 0x7028), },
{ PCI_DEVICE(0x10ee, 0x7031), }, { PCI_DEVICE(0x10ee, 0x7031), },
{ PCI_DEVICE(0x10ee, 0x7032), }, { PCI_DEVICE(0x10ee, 0x7032), },
{ PCI_DEVICE(0x10ee, 0x7034), }, { PCI_DEVICE(0x10ee, 0x7034), },
{ PCI_DEVICE(0x10ee, 0x7038), }, { PCI_DEVICE(0x10ee, 0x7038), },
{ PCI_DEVICE(0x10ee, 0x6828), }, { PCI_DEVICE(0x10ee, 0x6828), },
{ PCI_DEVICE(0x10ee, 0x6830), }, { PCI_DEVICE(0x10ee, 0x6830), },
...@@ -125,7 +125,7 @@ static void xpdev_free(struct xdma_pci_dev *xpdev) ...@@ -125,7 +125,7 @@ static void xpdev_free(struct xdma_pci_dev *xpdev)
static struct xdma_pci_dev *xpdev_alloc(struct pci_dev *pdev) static struct xdma_pci_dev *xpdev_alloc(struct pci_dev *pdev)
{ {
struct xdma_pci_dev *xpdev = kmalloc(sizeof(*xpdev), GFP_KERNEL); struct xdma_pci_dev *xpdev = kmalloc(sizeof(*xpdev), GFP_KERNEL);
if (!xpdev) if (!xpdev)
return NULL; return NULL;
...@@ -154,14 +154,28 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -154,14 +154,28 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
hndl = xdma_device_open(DRV_MODULE_NAME, pdev, &xpdev->user_max, hndl = xdma_device_open(DRV_MODULE_NAME, pdev, &xpdev->user_max,
&xpdev->h2c_channel_max, &xpdev->c2h_channel_max); &xpdev->h2c_channel_max, &xpdev->c2h_channel_max);
if (!hndl){ if (!hndl) {
rv = -EINVAL; rv = -EINVAL;
goto err_out; goto err_out;
} }
BUG_ON(xpdev->user_max > MAX_USER_IRQ); if (xpdev->user_max > MAX_USER_IRQ) {
BUG_ON(xpdev->h2c_channel_max > XDMA_CHANNEL_NUM_MAX); pr_err("Maximum users limit reached\n");
BUG_ON(xpdev->c2h_channel_max > XDMA_CHANNEL_NUM_MAX); rv = -EINVAL;
goto err_out;
}
if (xpdev->h2c_channel_max > XDMA_CHANNEL_NUM_MAX) {
pr_err("Maximun H2C channel limit reached\n");
rv = -EINVAL;
goto err_out;
}
if (xpdev->c2h_channel_max > XDMA_CHANNEL_NUM_MAX) {
pr_err("Maximun C2H channel limit reached\n");
rv = -EINVAL;
goto err_out;
}
if (!xpdev->h2c_channel_max && !xpdev->c2h_channel_max) if (!xpdev->h2c_channel_max && !xpdev->c2h_channel_max)
pr_warn("NO engine found!\n"); pr_warn("NO engine found!\n");
...@@ -181,7 +195,12 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -181,7 +195,12 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
rv = -EINVAL; rv = -EINVAL;
goto err_out; goto err_out;
} }
BUG_ON(hndl != xdev );
if (hndl != xdev) {
pr_err("xdev handle mismatch\n");
rv = -EINVAL;
goto err_out;
}
pr_info("%s xdma%d, pdev 0x%p, xdev 0x%p, 0x%p, usr %d, ch %d,%d.\n", pr_info("%s xdma%d, pdev 0x%p, xdev 0x%p, 0x%p, usr %d, ch %d,%d.\n",
dev_name(&pdev->dev), xdev->idx, pdev, xpdev, xdev, dev_name(&pdev->dev), xdev->idx, pdev, xpdev, xdev,
...@@ -198,7 +217,7 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -198,7 +217,7 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
return 0; return 0;
err_out: err_out:
pr_err("pdev 0x%p, err %d.\n", pdev, rv); pr_err("pdev 0x%p, err %d.\n", pdev, rv);
xpdev_free(xpdev); xpdev_free(xpdev);
return rv; return rv;
...@@ -219,7 +238,7 @@ static void remove_one(struct pci_dev *pdev) ...@@ -219,7 +238,7 @@ static void remove_one(struct pci_dev *pdev)
pdev, xpdev, xpdev->xdev); pdev, xpdev, xpdev->xdev);
xpdev_free(xpdev); xpdev_free(xpdev);
dev_set_drvdata(&pdev->dev, NULL); dev_set_drvdata(&pdev->dev, NULL);
} }
static pci_ers_result_t xdma_error_detected(struct pci_dev *pdev, static pci_ers_result_t xdma_error_detected(struct pci_dev *pdev,
...@@ -270,7 +289,7 @@ static void xdma_error_resume(struct pci_dev *pdev) ...@@ -270,7 +289,7 @@ static void xdma_error_resume(struct pci_dev *pdev)
pci_cleanup_aer_uncorrect_error_status(pdev); pci_cleanup_aer_uncorrect_error_status(pdev);
} }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) #if KERNEL_VERSION(4, 13, 0) <= LINUX_VERSION_CODE
static void xdma_reset_prepare(struct pci_dev *pdev) static void xdma_reset_prepare(struct pci_dev *pdev)
{ {
struct xdma_pci_dev *xpdev = dev_get_drvdata(&pdev->dev); struct xdma_pci_dev *xpdev = dev_get_drvdata(&pdev->dev);
...@@ -287,7 +306,7 @@ static void xdma_reset_done(struct pci_dev *pdev) ...@@ -287,7 +306,7 @@ static void xdma_reset_done(struct pci_dev *pdev)
xdma_device_online(pdev, xpdev->xdev); xdma_device_online(pdev, xpdev->xdev);
} }
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0) #elif KERNEL_VERSION(3, 16, 0) <= LINUX_VERSION_CODE
static void xdma_reset_notify(struct pci_dev *pdev, bool prepare) static void xdma_reset_notify(struct pci_dev *pdev, bool prepare)
{ {
struct xdma_pci_dev *xpdev = dev_get_drvdata(&pdev->dev); struct xdma_pci_dev *xpdev = dev_get_drvdata(&pdev->dev);
...@@ -305,10 +324,10 @@ static const struct pci_error_handlers xdma_err_handler = { ...@@ -305,10 +324,10 @@ static const struct pci_error_handlers xdma_err_handler = {
.error_detected = xdma_error_detected, .error_detected = xdma_error_detected,
.slot_reset = xdma_slot_reset, .slot_reset = xdma_slot_reset,
.resume = xdma_error_resume, .resume = xdma_error_resume,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) #if KERNEL_VERSION(4, 13, 0) <= LINUX_VERSION_CODE
.reset_prepare = xdma_reset_prepare, .reset_prepare = xdma_reset_prepare,
.reset_done = xdma_reset_done, .reset_done = xdma_reset_done,
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0) #elif KERNEL_VERSION(3, 16, 0) <= LINUX_VERSION_CODE
.reset_notify = xdma_reset_notify, .reset_notify = xdma_reset_notify,
#endif #endif
}; };
...@@ -324,8 +343,6 @@ static struct pci_driver pci_driver = { ...@@ -324,8 +343,6 @@ static struct pci_driver pci_driver = {
static int __init xdma_mod_init(void) static int __init xdma_mod_init(void)
{ {
int rv; int rv;
extern unsigned int desc_blen_max;
extern unsigned int sgdma_timeout;
pr_info("%s", version); pr_info("%s", version);
......
...@@ -44,14 +44,19 @@ ...@@ -44,14 +44,19 @@
#include <linux/splice.h> #include <linux/splice.h>
#include <linux/version.h> #include <linux/version.h>
#include <linux/uio.h> #include <linux/uio.h>
#include <linux/spinlock_types.h>
#include "libxdma.h" #include "libxdma.h"
#include "xdma_thread.h"
#define MAGIC_ENGINE 0xEEEEEEEEUL #define MAGIC_ENGINE 0xEEEEEEEEUL
#define MAGIC_DEVICE 0xDDDDDDDDUL #define MAGIC_DEVICE 0xDDDDDDDDUL
#define MAGIC_CHAR 0xCCCCCCCCUL #define MAGIC_CHAR 0xCCCCCCCCUL
#define MAGIC_BITSTREAM 0xBBBBBBBBUL #define MAGIC_BITSTREAM 0xBBBBBBBBUL
extern unsigned int desc_blen_max;
extern unsigned int sgdma_timeout;
struct xdma_cdev { struct xdma_cdev {
unsigned long magic; /* structure ID for sanity checks */ unsigned long magic; /* structure ID for sanity checks */
struct xdma_pci_dev *xpdev; struct xdma_pci_dev *xpdev;
...@@ -94,12 +99,19 @@ struct xdma_pci_dev { ...@@ -94,12 +99,19 @@ struct xdma_pci_dev {
void *data; void *data;
}; };
struct xdma_io_cb { struct cdev_async_io {
void __user *buf; struct kiocb *iocb;
size_t len; struct xdma_io_cb* cb;
unsigned int pages_nr; bool write;
struct sg_table sgt; bool cancel;
struct page **pages; int cmpl_cnt;
int req_cnt;
spinlock_t lock;
struct work_struct wrk_itm;
struct cdev_async_io *next;
ssize_t res;
ssize_t res2;
int err_cnt;
}; };
#endif /* ifndef __XDMA_MODULE_H__ */ #endif /* ifndef __XDMA_MODULE_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment