* [Xenomai-help] Xenomai mmap
@ 2011-01-17 16:59 Peter Hua
2011-01-17 17:03 ` Gilles Chanteperdrix
2011-01-17 18:08 ` Gilles Chanteperdrix
0 siblings, 2 replies; 11+ messages in thread
From: Peter Hua @ 2011-01-17 16:59 UTC (permalink / raw)
To: xenomai; +Cc: pwfhua
[-- Attachment #1.1: Type: text/plain, Size: 267 bytes --]
Is there any example code to map PCI registers into user space? I am having
problem getting functions rtdm_iomap_to_user and mmap to compile. My code
is attached.
Xenomai - 2.4.10
Kernel - 2.6.29.1
OS - Red Hat 5.5
Thanks in advance,
Peter Hua
[-- Attachment #1.2: Type: text/html, Size: 2527 bytes --]
[-- Attachment #2: malibu.c --]
[-- Type: text/plain, Size: 34273 bytes --]
/**
* This a driver written to interface with DSP boards from Innovative Integration
* It utilizes the RTDM device APIs from the Xenomai realtime Linux project.
*
*/
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/reboot.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/spinlock.h>
#include <linux/pagemap.h>
#include <linux/semaphore.h>
#include <linux/list.h>
#include <linux/vmalloc.h>
#include <linux/mman.h>
#include <asm/uaccess.h>
#include <asm/dma.h>
#include <asm/delay.h>
#include <asm/io.h>
#include <asm/msr.h>
#include <asm/page.h>
#include <linux/mman.h>
#include <asm-generic/system.h>
#include <rtdm/rtdm_driver.h>
#include "malibu.h"
#define VENDOR_ID 0x1303
#define DRV_NAME "malibu"
#define SIZE_MAX 1024
#define SOME_SUB_CLASS 1303
static void errMsg(int line, const char *place, const char *msg)
{
rtdm_printk(KERN_ALERT "malibu: Error at %s() line: %d, %s\n", place, line, msg);
}
#define MY_ERR(s) errMsg(__LINE__, __FUNCTION__, s)
static void logMsg(int line, const char *place, const char *msg)
{
rtdm_printk(KERN_INFO "MalibuDrv_RT: %s() line: %d, %s\n", place, line, msg);
}
#define MY_PRINT(s) logMsg(__LINE__, __FUNCTION__, s);
typedef struct {
void* kAddr;
uint64_t start;
uint64_t end;
uint64_t size;
} MyBar;
typedef struct {
void* kAddr;
dma_addr_t physAddr;
uint32_t size;
} MyBuf;
typedef struct {
struct list_head list;
struct cdev cdev;
struct device *sysdev;
struct pci_dev *pdev;
dev_t myDevT;
MyBar bars[MALIBU_BAR_MAX];
MyBuf bufs[MALIBU_BUF_MAX]; //DMA buffers
wait_queue_head_t intrWait;
struct fasync_struct* async_queue;
int mySig;
void* intrStatusAddr;
u32 intrMask;
u8 intrWriteback;
u32 iQueue[MALIBU_INTR_MAX];
u32 iPtrLow;
u32 iPtrHi;
void (*cntxtFunc)(void*);
void *cntxtArg;
u16 devOpen;
u8 wrOpen;
u8 numBars;
u8 isIrqEnabled;
int dev_id;
struct rtdm_device *xen_rtdm_device;
rtdm_irq_t irq_handle; /* device IRQ handle */
} MyData;
static struct class* devClass;
static dev_t baseDevT;
static int devCnt = 0;
LIST_HEAD(devList);
static int fasync(int fd, struct file *filep, int mode);
static int malibu_intr_handler(rtdm_irq_t * irq_context);
static char msgbuf[1000];
int MyMmap(struct file *filep, struct vm_area_struct *vma);
static struct file_operations myFileOps = {
.owner = THIS_MODULE,
//.release = release,
.mmap = MyMmap,
//.fasync = fasync,
};
static int malibu_rtdm_open(struct rtdm_dev_context *context,
rtdm_user_info_t * user_info, int oflags)
//static int open(struct inode *inodep, struct file *filep)
{
MyData *md, *ctx;
bool found=false;
int err=0;
unsigned long vaddr;
MY_PRINT("start");
ctx = (MyData *)context->dev_private;
list_for_each_entry(md, &devList, list) {
if (md->dev_id == context->device->device_id)
{
found = true;
MY_PRINT("device FOUND");
sprintf (msgbuf, "md=%p, md->device_id=%d", md, md->dev_id);
MY_PRINT(msgbuf);
memcpy(ctx, md, sizeof(MyData));
break;
}
}
if(!found)
{
MY_ERR("no matching device");
return -ENODEV;
}
if (ctx->wrOpen && (oflags & FMODE_WRITE)) {
MY_ERR("device already opened");
return -EBUSY;
}
#if 0
/* mark pages reserved so that remap_pfn_range works */
int b;
for(b=0;b<MALIBU_BAR_MAX;b++)
{
if (ctx->bars[b].kAddr == NULL)
break;
for (vaddr = (unsigned long)ctx->bars[b].kAddr;
vaddr < (unsigned long)ctx->bars[b].kAddr + ctx->bars[b].size;
vaddr += PAGE_SIZE)
SetPageReserved(virt_to_page(vaddr));
}
sprintf(msgbuf, "reserved, b=%d", b);
MY_PRINT(msgbuf);
#endif
if (oflags & FMODE_WRITE)
{
ctx->iPtrLow = 0;
ctx->iPtrHi = 0;
ctx->mySig = SIGIO;
ctx->cntxtFunc = 0;
ctx->cntxtArg = 0;
static unsigned long irqtype = (RTDM_IRQTYPE_SHARED | RTDM_IRQTYPE_EDGE);
sprintf(msgbuf, "irqtype=%d", irqtype);
MY_PRINT(msgbuf);
err = rtdm_irq_request(&ctx->irq_handle, ctx->pdev->irq,
(rtdm_irq_handler_t)malibu_intr_handler,
irqtype,
context->device->proc_name, (void *)ctx);
if(err != 0)
{
sprintf(msgbuf, "rtdm_irq_request() failed, err=%d, irq=%d, proc_name=%s",
err, ctx->pdev->irq, context->device->proc_name);
MY_ERR(msgbuf);
return err;
}
sprintf(msgbuf, "rtdm_irq_request() OK, irq=%d", ctx->irq_handle);
MY_PRINT(msgbuf);
ctx->wrOpen = 1;
}
ctx->devOpen++;
MY_PRINT("end OK");
return 0;
}
/**
* Close the device
*
* This function is called when the device shall be closed.
*
*/
static int malibu_rtdm_close(struct rtdm_dev_context *context,
rtdm_user_info_t * user_info)
{
MyData *ctx = context->dev_private;
rtdm_irq_free(&ctx->irq_handle);
MY_PRINT("closing device");
return 0;
}
static void freeBuffer(MyData* md, int n)
{
MyBuf* b = &md->bufs[n];
if (b->size == 0) return;
dma_free_coherent(&md->pdev->dev, b->size, b->kAddr, b->physAddr);
b->size = 0;
}
static int release(struct inode *inode, struct file *filep)
{
int i;
MyData* md = (MyData*) filep->private_data;
md->devOpen--;
if (filep->f_mode & FMODE_WRITE) {
md->wrOpen = 0;
//free_irq(md->pdev->irq, md);
rtdm_irq_free(&md->irq_handle);
for (i = 0; i < MALIBU_BUF_MAX; i++) freeBuffer(md, i);
fasync(-1, filep, 0);
}
return 0;
}
/* --- Mmap functions --- */
void malibu_map(struct vm_area_struct *area)
{
//unsigned long *status = (unsigned long *)area->vm_private_data;
//set_bit(MALIBU_BUF_MAP_NR, status);
}
void malibu_unmap(struct vm_area_struct *area)
{
//unsigned long *status = (unsigned long *)area->vm_private_data;
//clear_bit(MALIBU_BUF_MAP_NR, status);
}
static struct vm_operations_struct malibu_vm_ops = {
.open = malibu_map,
.close = malibu_unmap,
};
static struct vm_area_struct vma;
void * malibu_ioctl_mmap(rtdm_user_info_t *user_info,
MyData *cxt, MalibuDrv_MmapArg *arg)
{
//malibu_mmap_t map_cfg;
//malibu_dev_t *dev;
//malibu_buf_t *buf;
int ret=0;
void *usrAddr;
MY_PRINT("start");
/* Basic checkings */
#if 0
/* The mmap operation cannot be performed in a
real-time context */
if (rtdm_in_rt_context()) {
MY_ERR("in real-time context");
return -ENOSYS;
}
// dev = malibu_get_dev(cxt);
// buf = cxt->buffer;
if (!test_bit(malibu_DEV_ATTACHED_NR, &dev->flags)) {
__malibu_err("malibu_ioctl_mmap: cannot mmap on "
"an unattached device\n");
return -EINVAL;
}
if (test_bit(malibu_BUF_MAP_NR, &buf->flags)) {
__malibu_err("malibu_ioctl_mmap: buffer already mapped\n");
return -EBUSY;
}
if (rtdm_safe_copy_from_user(cxt->user_info,
&map_cfg, arg, sizeof(malibu_mmap_t)) != 0)
return -EFAULT;
/* Check the size to be mapped */
if (arg->size > cxt->bars[arg->barnum].size)
{
MY_ERR("bar size exceeded");
return -EFAULT;
}
#endif
/* All the magic is here */
sprintf(msgbuf, "kAddr=0x%p, size=%d", cxt->bars[arg->barnum].kAddr, arg->size);
MY_PRINT(msgbuf);
//arg->size += (PAGE_SIZE - (arg->size % PAGE_SIZE));
struct file *filp;
struct file_operations *old_fops;
void *old_priv_data;
void *user_addr;
filp = filp_open("/dev/zero", O_RDWR, 0);
if (IS_ERR(filp)) {
printk("open failed\n");
return filp;
}
old_fops = filp->f_op;
filp->f_op = &myFileOps;
old_priv_data = filp->private_data;
filp->private_data = cxt;
//down_write(¤t->mm->mmap_sem);
usrAddr = (void *)mmap(
0,
(size_t)arg->size,
(PROT_READ|PROT_WRITE),
MAP_SHARED,
filp, 0);
//up_write(¤t->mm->mmap_sem);
filp->f_op = old_fops;
filp->private_data = old_priv_data;
filp_close(filp, current->files);
#if 0
ret = rtdm_iomap_to_user(user_info,
cxt->bars[arg->barnum].kAddr,
arg->size,
PROT_READ | PROT_WRITE,
&usrAddr, //&arg->userAddr,
&malibu_vm_ops,
NULL);
#endif
if (ret < 0) {
sprintf(msgbuf, "malibu_ioctl_mmap: internal error, "
"rtdm_mmap_to_user failed (err=%d)\n", ret);
MY_ERR(msgbuf);
}
sprintf(msgbuf, "usrAddr=%p", usrAddr);
MY_PRINT(msgbuf);
//rtdm_safe_copy_to_user(cxt->user_info,
// &arg->UsrAdr, &usrAddr, sizeof(unsigned int));
MY_PRINT("end");
return usrAddr;
}
//static int ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg)
int malibu_rtdm_ioctl(struct rtdm_dev_context *context,
rtdm_user_info_t *user_info,
int cmd,
void *arg)
{
MyData* md = (MyData *)context->dev_private;
void *addr;
int err;
int retval = 0;
ioc_param_struct param = {0,0};
if (_IOC_TYPE(cmd) != MALIBU_IOC_MAGIC) return -ENOTTY;
/*
* the direction is a bitmask, and VERIFY_WRITE catches R/W
* transfers. `Type' is user-oriented, while
* access_ok is kernel-oriented, so the concept of "read" and
* "write" is reversed (i.e. when an user wants to read data,
* the kernel has to write them into the user space)
*
* always check the user space address before accessing it
*
* access_ok returns 0 for failure!
*/
if (_IOC_DIR(cmd) & _IOC_READ)
err = !rtdm_read_user_ok(user_info, arg, sizeof(ioc_param_struct));
else if (_IOC_DIR(cmd) & _IOC_WRITE)
err = !rtdm_rw_user_ok(user_info, arg, sizeof(ioc_param_struct));
if (err) return -EFAULT;
switch(cmd) {
case MALIBU_MMAP_BLOCK: {
void * usrAddr;
MalibuDrv_MmapArg *mArg = (MalibuDrv_MmapArg *)arg;
rtdm_iomap_to_user(user_info,
mArg->kernAddr,
mArg->size,
PROT_READ | PROT_WRITE,
&usrAddr, //&arg->userAddr,
&malibu_vm_ops,
NULL);
mArg->userAddr = usrAddr;
return (usrAddr);
break;
}
case MALIBU_MMAP_BAR: {
addr = malibu_ioctl_mmap(user_info,
md, arg);
MalibuDrv_MmapArg *tmp = (MalibuDrv_MmapArg *)(arg);
tmp->userAddr = addr;
sprintf(msgbuf, "addr=%p, addr=%d", tmp->userAddr, (int)addr);
MY_PRINT(msgbuf);
return (int)addr;
break;
}
case MALIBU_GET_INFO: {
MalibuDrv_INFO x;
x.vendorId = md->pdev->vendor;
x.deviceId = md->pdev->device;
x.subVendorId = md->pdev->subsystem_vendor;
x.subDeviceId = md->pdev->subsystem_device;
x.revision = md->pdev->revision;
x.bus = md->pdev->bus->number;
x.slot = PCI_SLOT(md->pdev->devfn);
x.func = PCI_FUNC(md->pdev->devfn);
x.numBars = md->numBars;
MY_PRINT("copying data to user");
sprintf(msgbuf, "x.vendorId=0x%x, x.deviceId=0x%x, x.numBars=%d",
md->pdev->vendor, md->pdev->device, x.numBars);
MY_PRINT(msgbuf);
if (user_info)
err = rtdm_safe_copy_to_user(user_info, arg,
&x, sizeof(x));
else
memcpy(arg, &x, sizeof(MalibuDrv_INFO));
break;
return err;
}
case MALIBU_GET_BAR_SIZE:
if (*(int *)arg < 0 || *(int *)arg >= MALIBU_BAR_MAX) return -EINVAL;
sprintf(msgbuf, "arg=%p, *arg=%d", arg, *(int *)arg);
MY_PRINT(msgbuf);
return md->bars[*(int *)arg].size;
case MALIBU_ALLOC_BUFFER: {
int n;
MalibuDrv_Buffer x;
MyBuf* b;
MY_PRINT("MALIBU_ALLOC_BUFFER start");
//TODO: if (!(filep->f_mode & FMODE_WRITE)) return -EACCES;
for (n = 0; n < MALIBU_BUF_MAX; n++) {
if (md->bufs[n].size == 0) break;
}
MY_PRINT("1");
if (n == MALIBU_BUF_MAX) {
MY_ERR("MALIBU_BUF_MAX");
return -ENOMEM;
}
MY_PRINT("2");
if (rtdm_safe_copy_from_user(user_info, &x, (const void __user*)arg, sizeof(x)))
{
MY_ERR("rtdm_safe_copy_from_user");
return -EFAULT;
}
MY_PRINT("3");
b = &md->bufs[n];
b->size = ((x.size + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
b->kAddr = dma_alloc_coherent(&md->pdev->dev, b->size, &b->physAddr, GFP_KERNEL);
MY_PRINT("4");
if (b->kAddr == 0) {
b->size = 0;
MY_ERR("b->kAddr == 0");
return -ENOMEM;
}
MY_PRINT("5");
x.physAddr = b->physAddr;
x.bufNum = n;
x.fileOffset = (n + MALIBU_BAR_MAX) * MALIBU_MMAP_SIZE;
sprintf(msgbuf, "x.pa=0x%p",x.physAddr);
MY_PRINT(msgbuf);
if (user_info)
err = rtdm_safe_copy_to_user(user_info, arg,
&x, sizeof(x));
else
memcpy(arg, &x, sizeof(x));
break;
MY_PRINT("7");
if(err != 0)
{
MY_ERR("rtdm_safe_copy_to_user");
freeBuffer(md, x.bufNum);
return err;
}
MY_PRINT("8");
((uint32_t*)b->kAddr)[0] = 0x12345678;
((uint32_t*)b->kAddr)[1] = n;
((uint32_t*)b->kAddr)[2] = md->myDevT;
MY_PRINT("MALIBU_ALLOC_BUFFER end OK");
return 0;
}
case MALIBU_FREE_BUFFER: {
int i;
MalibuDrv_Buffer x;
//TODO:if (!(filep->f_mode & FMODE_WRITE)) return -EACCES;
if (rtdm_safe_copy_from_user(user_info, &x, (const void __user*)arg, sizeof(x))) return -EFAULT;
for (i = 0; i < MALIBU_BUF_MAX; i++) {
if (md->bufs[i].physAddr == x.physAddr) {
freeBuffer(md, i);
break;
}
}
if (i == MALIBU_BUF_MAX) {
MY_ERR("");
return -ENOMEM;
}
return 0;
}
case MALIBU_ISR_ENABLE:
//TODO: if (!(filep->f_mode & FMODE_WRITE)) return -EACCES;
//enable_irq(md->pdev->irq);
rtdm_irq_enable(&md->irq_handle);
md->isIrqEnabled = 1;
return 0;
case MALIBU_ISR_DISABLE:
//TODO: if (!(filep->f_mode & FMODE_WRITE)) return -EACCES;
md->isIrqEnabled = 0;
//disable_irq(md->pdev->irq);
rtdm_irq_disable(&md->irq_handle);
return 0;
case MALIBU_GET_ISR_ENABLED:
return md->isIrqEnabled;
case MALIBU_GET_ISR_DEPTH:
return (md->iPtrLow - md->iPtrHi);
case MALIBU_ISR_CLEAR_ALL:
//TODO: if (!(filep->f_mode & FMODE_WRITE)) return -EACCES;
//disable_irq(md->pdev->irq);
rtdm_irq_disable(&md->irq_handle);
md->iPtrLow = 0;
md->iPtrHi = 0;
//enable_irq(md->pdev->irq);
rtdm_irq_enable(&md->irq_handle);
return 0; // no implemented yet
case MALIBU_DEQUEUE_ISR: {
MalibuDrv_DequeueISR x;
unsigned long j;
int ret;
//TODO: if (!(filep->f_mode & FMODE_WRITE)) return -EACCES;
if (rtdm_safe_copy_from_user(user_info, &x, (const void __user*)arg, (caddr_t)&x.depth - (caddr_t)&x)) return -EFAULT;
x.depth = 0;
x.cntxtFunc = md->cntxtFunc;
x.cntxtArg = md->cntxtArg;
x.errno = 0;
x.depth = 0;
j = timeval_to_jiffies(&x.timeout);
if (j == 0) {
if (md->iPtrLow != md->iPtrHi) {
while (md->iPtrLow != md->iPtrHi && x.depth < MALIBU_INTR_MAX) {
x.data[x.depth++] = md->iQueue[md->iPtrHi % MALIBU_INTR_MAX];
md->iPtrHi++;
}
}
else {
x.errno = ENODATA;
}
}
else {
ret = wait_event_interruptible_timeout(md->intrWait, md->iPtrLow != md->iPtrHi, j);
if (ret == 0) x.errno = ETIME;
else if (ret == -ERESTARTSYS) x.errno = ERESTARTSYS;
else {
while (md->iPtrLow != md->iPtrHi && x.depth < MALIBU_INTR_MAX) {
x.data[x.depth++] = md->iQueue[md->iPtrHi % MALIBU_INTR_MAX];
md->iPtrHi++;
}
jiffies_to_timeval(ret, &x.timeout);
}
}
if (user_info)
err = rtdm_safe_copy_to_user(user_info, arg,
&x, (caddr_t)&x.data[x.depth] - (caddr_t)&x);
else
memcpy(arg, &x, (caddr_t)&x.data[x.depth] - (caddr_t)&x);
break;
return err;
}
case MALIBU_SET_ISR_CTRL: {
MalibuDrv_IntCtrl x;
//TODO: if (!(filep->f_mode & FMODE_WRITE)) return -EACCES;
if (rtdm_safe_copy_from_user(user_info, &x, (const void __user*)arg, sizeof(x))) return -EFAULT;
md->intrMask = x.mask;
md->intrWriteback = x.type;
if (x.bar > MALIBU_BAR_MAX) {
MY_ERR("");
return -EINVAL;
}
if (x.byteOffset > md->bars[x.bar].size) {
MY_ERR("");
return -EINVAL;
}
md->intrStatusAddr = md->bars[x.bar].kAddr + x.byteOffset;
md->cntxtFunc = x.cntxtFunc;
md->cntxtArg = x.cntxtArg;
return 0;
}
case MALIBU_SET_SIG:
//TODO: if (!(filep->f_mode & FMODE_WRITE)) return -EACCES;
md->mySig = arg;
return 0;
case MALIBU_FAKE_SIG: {
MalibuDrv_FakeISR x;
if (rtdm_safe_copy_from_user(user_info, &x, (const void __user*)arg, sizeof(x))) return -EFAULT;
if ((md->iPtrLow - md->iPtrHi) < MALIBU_INTR_MAX-x.depth-1) {
int i;
for (i = 0; i < x.depth; i++) {
md->iQueue[md->iPtrLow % MALIBU_INTR_MAX] = x.data[i];
md->iPtrLow++;
}
wake_up_interruptible(&md->intrWait);
if (md->async_queue) kill_fasync(&md->async_queue, md->mySig, POLL_IN);
}
return 0;
}
default:
return -EINVAL;
}
}
//static irqreturn_t board_handler(unsigned int irq, void *dev_id, struct pt_regs *regs)
static int malibu_intr_handler(rtdm_irq_t * irq_context)
{
uint32_t rd;
MyData *md = rtdm_irq_get_arg(irq_context, MyData);
//MyData* md = (MyData*) dev_id;
//if(md->pdev->irq != irq) return IRQ_NONE;
rd = ioread32(md->intrStatusAddr);
if ((rd & md->intrMask) == 0) return IRQ_NONE;
if ((md->iPtrLow - md->iPtrHi) < MALIBU_INTR_MAX-1) {
md->iQueue[md->iPtrLow % MALIBU_INTR_MAX] = rd;
md->iPtrLow++;
wake_up_interruptible(&md->intrWait);
if (md->async_queue && md->mySig) kill_fasync(&md->async_queue, md->mySig, POLL_IN);
}
if (md->intrWriteback) iowrite32(rd, md->intrStatusAddr);
return IRQ_HANDLED;
}
static void vma_open(struct vm_area_struct* vma) { }
static void vma_close(struct vm_area_struct* vma) { }
static struct vm_operations_struct remap_vm_ops = {
.open = vma_open,
.close = vma_close,
};
int MyMmap(struct file *filep, struct vm_area_struct *vma)
{
MY_PRINT("start");
MyData* md = (MyData*) filep->private_data;
unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
unsigned long vsize = vma->vm_end - vma->vm_start;
unsigned long seg = off / MALIBU_MMAP_SIZE;
unsigned long seg_off = off % MALIBU_MMAP_SIZE;
unsigned long psize, pfn;
if (seg >= 0 && seg < MALIBU_BAR_MAX) {
if (md->bars[seg].size == 0) return -EINVAL;
pfn = (md->bars[seg].start + seg_off) >> PAGE_SHIFT;
psize = md->bars[seg].size - seg_off;
}
else if (seg >= MALIBU_BAR_MAX && seg < MALIBU_BAR_MAX + MALIBU_BUF_MAX) {
seg -= MALIBU_BAR_MAX;
if (md->bufs[seg].size == 0) return -EINVAL;
pfn = __pa(md->bufs[seg].kAddr + seg_off) >> PAGE_SHIFT;
psize = md->bufs[seg].size - seg_off;
}
else return -EINVAL;
if (vsize > psize) return -EINVAL;
if (remap_pfn_range(vma, vma->vm_start, pfn, vsize, vma->vm_page_prot)) return -EAGAIN;
vma->vm_ops = &remap_vm_ops;
vma_open(vma);
MY_PRINT("end");
return 0;
}
static int fasync(int fd, struct file *filep, int mode)
{
MyData* md = (MyData*) filep->private_data;
return fasync_helper(fd, filep, mode, &md->async_queue);
}
static ssize_t showDevInfo(struct device *dev, struct device_attribute* attr, char *buf)
{
MyData* md = (MyData*)dev->driver_data;
return snprintf(buf, PAGE_SIZE,
"vendor=0x%x\n"
"device=0x%x\n"
"subsystem_vendor=0x%x\n"
"subsystem_device=0x%x\n"
"revision=0x%x\n"
"bus=0x%x\n"
"slot=0x%x\n"
"func=0x%x\n"
"numBars=%d\n",
md->pdev->vendor,
md->pdev->device,
md->pdev->subsystem_vendor,
md->pdev->subsystem_device,
md->pdev->revision,
md->pdev->bus->number,
PCI_SLOT(md->pdev->devfn),
PCI_FUNC(md->pdev->devfn),
md->numBars);
}
static DEVICE_ATTR(devInfo, 0444, showDevInfo, NULL);
/**
* This structure describe the malibu RTDM device
*
*/
static struct rtdm_device malibu_rtdm_device = {
.struct_version = RTDM_DEVICE_STRUCT_VER,
.device_flags = RTDM_NAMED_DEVICE,
.context_size = sizeof(MyData),
.device_name = DRV_NAME,
.open_rt = malibu_rtdm_open,
.open_nrt = malibu_rtdm_open,
.ops = {
.close_rt = malibu_rtdm_close,
.close_nrt = malibu_rtdm_close,
.ioctl_rt = malibu_rtdm_ioctl,
.ioctl_nrt = malibu_rtdm_ioctl,
//.read_nrt = NULL,
//.write_nrt = NULL,
},
.device_class = RTDM_CLASS_EXPERIMENTAL,
.device_sub_class = SOME_SUB_CLASS,
.profile_version = 1,
.driver_name = DRV_NAME,
.driver_version = RTDM_DRIVER_VER(0, 1, 0),
.peripheral_name = "Malibu RT driver",
.provider_name = "Innovative Integration",
.proc_name = DRV_NAME,
};
static int allocEachDev(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct rtdm_device *rtdm_dev;
int ret_val = 0;
MyData *md, *lPtr;
int i, bCntr, error, b;
MY_PRINT("start");
if(id->vendor != VENDOR_ID) {
MY_ERR("");
return -ENODEV;
}
md = (MyData*) kzalloc(sizeof(MyData), GFP_KERNEL);
md->pdev = pdev;
sprintf(msgbuf, "pdev->irq=%d", pdev->irq);
MY_PRINT(msgbuf);
if (pci_enable_device(pdev)) {
MY_ERR("");
kfree(md);
return -ENODEV;
}
pci_set_master(pdev);
b = 0;
for (i = 0; i < MALIBU_BAR_MAX; i++) {
md->bars[b].start = pci_resource_start(pdev, i);
md->bars[b].end = pci_resource_end(pdev, i);
md->bars[b].size = pci_resource_len(pdev, i);
printk(KERN_ERR "bar=%d start=%llx end=%llx len=%llx\n", i,
md->bars[b].start,
md->bars[b].end,
md->bars[b].size);
if (md->bars[b].size == 0) continue;
md->bars[b].kAddr = (void*) ioremap(md->bars[i].start, md->bars[i].end - md->bars[i].start);
b++;
}
md->numBars = i;
init_waitqueue_head(&md->intrWait);
cdev_init(&md->cdev, &myFileOps);
md->cdev.owner = THIS_MODULE;
md->myDevT = MKDEV(MAJOR(baseDevT), MINOR(baseDevT)+devCnt);
if (cdev_add(&md->cdev, md->myDevT, 1)) {
MY_ERR("");
pci_disable_device(md->pdev);
kfree(md);
return -ENODEV;
}
bCntr = 0;
list_for_each_entry(lPtr, &devList, list) {
if (lPtr->pdev->device == pdev->device) bCntr++;
}
md->sysdev = device_create(devClass, &md->pdev->dev, md->myDevT, NULL, MALIBU_DEV_NAME, pdev->device, bCntr);
if (IS_ERR(md->sysdev)) {
MY_ERR("");
cdev_del(&md->cdev);
pci_disable_device(md->pdev);
kfree(md);
return -ENODEV;
}
md->sysdev->driver_data = (void*)md;
error = device_create_file(md->sysdev, &dev_attr_devInfo);
if (error) {
MY_ERR("");
device_destroy(devClass, md->myDevT);
cdev_del(&md->cdev);
for (i = 0; i < MALIBU_BAR_MAX; i++) {
if (md->bars[i].size) {
iounmap(md->bars[i].kAddr);
md->bars[i].size = 0;
}
}
pci_disable_device(md->pdev);
kfree(md);
return error;
}
md->dev_id = devCnt;
//alloc mem for rtdm structure
rtdm_dev = kmalloc(sizeof(struct rtdm_device), GFP_KERNEL);
if(!rtdm_dev){
MY_ERR("rtdm_device kmalloc failed\n");
ret_val = -ENOMEM; //Insufficient storage space is available.
return ret_val;
}
//copy the structure to the new memory
memcpy(rtdm_dev, &malibu_rtdm_device, sizeof(struct rtdm_device));
//create filename
snprintf(rtdm_dev->device_name,
RTDM_MAX_DEVNAME_LEN,
MALIBU_DEV_NAME,
pdev->device, bCntr);
//"malibu_%d", devCnt);
rtdm_dev->device_id = devCnt;
//define two other members of the rtdm_device structure
rtdm_dev->proc_name = rtdm_dev->device_name;
ret_val = rtdm_dev_register(rtdm_dev);
if(ret_val < 0){
MY_ERR("failed to register device with RTDM\n");
ret_val = -ENODEV;
return ret_val;
}
md->xen_rtdm_device = rtdm_dev;
list_add_tail(&md->list, &devList);
//always do this last
devCnt++;
MY_PRINT("end OK");
return 0;
}
static void removeAllDev(struct pci_dev *pdev)
{
MyData *md, *tmp;
MY_PRINT("start");
list_for_each_entry_safe(md, tmp, &devList, list)
{
if (md == NULL)
{
MY_PRINT("md is NULL");
return;
}
int i;
list_del(&md->list);
device_remove_file(md->sysdev, &dev_attr_devInfo);
device_destroy(devClass, md->myDevT);
cdev_del(&md->cdev);
for (i = 0; i < MALIBU_BUF_MAX; i++) freeBuffer(md, i);
for (i = 0; i < MALIBU_BAR_MAX; i++) {
if (md->bars[i].size) {
iounmap(md->bars[i].kAddr);
md->bars[i].size = 0;
}
}
pci_disable_device(md->pdev);
//remove char device from the system
//unregister RTdriver
rtdm_dev_unregister(md->xen_rtdm_device, 1000);
kfree(md->xen_rtdm_device);
kfree(md);
devCnt--;
}
MY_PRINT("end");
}
static struct pci_device_id ids[] = {
{ PCI_DEVICE(VENDOR_ID, PCI_ANY_ID) },
{ 0 },
};
static struct pci_driver pci_driver = {
.name = DRV_NAME,
.id_table = ids,
.probe = allocEachDev,
.remove = removeAllDev,
};
//MODULE_DEVICE_TABLE(pci, ids);
static ssize_t showDevCount(struct class *cls, char *buf)
{
return sprintf(buf, "%d\n", devCnt);
}
static CLASS_ATTR(devCount, 0444, showDevCount, NULL);
/**
* This function is called when the module is loaded
*
* It simply registers the RTDM device.
*
*/
static int __init mod_init(void)
{
int error;
MY_PRINT("initializing MalibuDrv_RT module");
devClass = class_create(THIS_MODULE, DRV_NAME);
if (IS_ERR(devClass)) {
MY_ERR("");
return PTR_ERR(devClass);
}
error = class_create_file(devClass, &class_attr_devCount);
if (error) {
MY_ERR("");
class_destroy(devClass);
return error;
}
error = alloc_chrdev_region(&baseDevT, 0, MALIBU_MAX_DEVS, DRV_NAME);
if (error) {
MY_ERR("");
class_remove_file(devClass, &class_attr_devCount);
class_destroy(devClass);
return error;
}
error = pci_register_driver(&pci_driver);
if (error) {
MY_ERR("");
unregister_chrdev_region(baseDevT, MALIBU_MAX_DEVS);
class_remove_file(devClass, &class_attr_devCount);
class_destroy(devClass);
return error;
}
return error;
}
/**
* This function is called when the module is unloaded
*
* It unregister the RTDM device, polling at 1000 ms for pending users.
*
*/
static void __exit mod_exit(void)
{
MY_PRINT("unregistering MalibuDrv_RT module");
pci_unregister_driver(&pci_driver);
unregister_chrdev_region(baseDevT, MALIBU_MAX_DEVS);
class_remove_file(devClass, &class_attr_devCount);
class_destroy(devClass);
}
module_init(mod_init);
module_exit(mod_exit);
MODULE_LICENSE("GPL");
[-- Attachment #3: malibu.h --]
[-- Type: text/plain, Size: 2878 bytes --]
#ifndef _MALIBU_H_
#define _MALIBU_H_
#include <linux/ioctl.h>
//#include <sys/time.h>
#ifndef __KERNEL__
#include <stdint.h>
#endif
#include <rtdm/rtdm.h>
typedef struct {
uint32_t vendorId;
uint32_t deviceId;
uint32_t subVendorId;
uint32_t subDeviceId;
uint32_t bus;
uint32_t slot;
uint32_t func;
uint8_t revision;
uint8_t numBars;
} MalibuDrv_INFO;
typedef struct {
uint64_t physAddr;
uint64_t fileOffset;
uint32_t size;
uint8_t bufNum;
} MalibuDrv_Buffer;
typedef struct {
uint32_t type;
uint32_t byteOffset;
uint32_t bar;
uint32_t mask;
void (*cntxtFunc)(void*);
void *cntxtArg;
} MalibuDrv_IntCtrl;
#define MALIBU_INTR_MAX 128 // how many isrs can be queued in the kernel
typedef struct {
struct timeval timeout;
int errno;
void (*cntxtFunc)(void*);
void *cntxtArg;
uint32_t depth;
uint32_t data[MALIBU_INTR_MAX];
} MalibuDrv_DequeueISR;
typedef struct {
uint32_t depth;
uint32_t data[MALIBU_INTR_MAX];
} MalibuDrv_FakeISR;
/**
* IOCTL stuff
*/
struct ioc_param{
uint32_t bv; /* 32bit vector to write to register, */
/* when reading from register, */
/* the value will be stored there */
uint8_t offset; /* offset address of the register we */
/* want to read from or write to */
};
typedef struct {
void *userAddr; /*user mode addr*/
uint64_t size;
uint8_t barnum;
void *kernAddr;
}MalibuDrv_MmapArg;
typedef struct ioc_param ioc_param_struct;
#define MALIBU_IOC_MAGIC 'm'
#define MALIBU_GET_INFO _IOR(MALIBU_IOC_MAGIC, 0, MalibuDrv_INFO)
#define MALIBU_GET_BAR_SIZE _IO(MALIBU_IOC_MAGIC, 1)
#define MALIBU_ALLOC_BUFFER _IOWR(MALIBU_IOC_MAGIC, 2, MalibuDrv_Buffer)
#define MALIBU_FREE_BUFFER _IOW(MALIBU_IOC_MAGIC, 3, MalibuDrv_Buffer)
#define MALIBU_ISR_ENABLE _IO(MALIBU_IOC_MAGIC, 4)
#define MALIBU_ISR_DISABLE _IO(MALIBU_IOC_MAGIC, 5)
#define MALIBU_GET_ISR_ENABLED _IO(MALIBU_IOC_MAGIC, 6)
#define MALIBU_GET_ISR_DEPTH _IO(MALIBU_IOC_MAGIC, 7)
#define MALIBU_ISR_CLEAR_ALL _IO(MALIBU_IOC_MAGIC, 8)
#define MALIBU_DEQUEUE_ISR _IOWR(MALIBU_IOC_MAGIC, 9, MalibuDrv_DequeueISR)
#define MALIBU_SET_ISR_CTRL _IOW(MALIBU_IOC_MAGIC, 10, MalibuDrv_IntCtrl)
#define MALIBU_SET_SIG _IO(MALIBU_IOC_MAGIC, 11)
#define MALIBU_FAKE_SIG _IOW(MALIBU_IOC_MAGIC, 12, MalibuDrv_FakeISR)
#define MALIBU_MMAP_BAR _IOWR(MALIBU_IOC_MAGIC, 13, MalibuDrv_MmapArg)
#define MALIBU_MMAP_BLOCK _IOWR(MALIBU_IOC_MAGIC, 14, MalibuDrv_MmapArg)
#define MALIBU_MAX_DEVS 256
#define MALIBU_MMAP_SIZE (16 * 1024 * 1024)
#define MALIBU_BAR_MAX 6
#define MALIBU_BUF_MAX 2
#define MALIBU_DEV_NAME "malibu%04x_%d"
#define MALIBU_BUF_MAP_NR 9
#define MALIBU_BUF_MAP (1 << MALIBU_BUF_MAP_NR)
#endif
[-- Attachment #4: malibuApp.c --]
[-- Type: text/plain, Size: 10443 bytes --]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#define __USE_GNU
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include "malibu.h"
struct timeval startTime;
void hello_world(char* data)
{
printf("hello frm hello_world\n");
printf("data=%x", data);
}
int checkFd(int fd, int secs)
{
int ret;
MalibuDrv_DequeueISR isr;
struct timeval now;
double diff;
int i;
isr.timeout.tv_sec = secs;
isr.timeout.tv_usec = 0;
if (rt_dev_ioctl(fd, MALIBU_DEQUEUE_ISR, &isr) < 0) {
perror("rt_dev_ioctl");
}
else {
gettimeofday(&now, 0);
diff = now.tv_sec - startTime.tv_sec + (now.tv_usec - startTime.tv_usec) / 1e6;
if (isr.errno) {
char buf[256];
strerror_r(isr.errno, buf, sizeof(buf));
printf("%15.f: fd=%d error=%s\n", diff, fd, buf);
}
else {
printf("%15.6f: fd=%d got depth=%d",
diff,
fd,
isr.depth);
if (secs != 0) printf(" time remaining=%f", isr.timeout.tv_sec + isr.timeout.tv_usec / 1e6);
printf("\n");
for (i = 0; i < isr.depth; i++) {
printf("\tdata[%d] = %08x\n", i, isr.data[i]);
}
if (isr.cntxtFunc) (*isr.cntxtFunc)(isr.cntxtArg);
}
}
return ret;
}
int doExit = 0;
void* backgroundThr(void* arg)
{
while (1) {
if (checkFd((long)arg, 2) < 0) break;
if (doExit) break;
}
printf("thread fd=%d exiting\n", (long) arg);
}
void myHandler(int sig, siginfo_t* info, void* arg)
{
int i;
if (sig == SIGPOLL && info->si_code == POLL_IN) {
checkFd(info->si_fd, 0);
}
}
int main(int argc, char * argv[])
{
struct sigaction act[8];
pthread_t tid[8];
int numBoards = 0;
int fds[8];
int i, j, boardCnt;
char *bars[8][MALIBU_BAR_MAX];
int barSize[8][MALIBU_BAR_MAX];
int barCnt[8];
char *bufPtrs[8][MALIBU_BUF_MAX];
MalibuDrv_Buffer bufs[8][MALIBU_BUF_MAX];
for (i = 0; i < 8; i++) {
struct stat sbuf;
char buf[128];
sprintf(buf, "/dev/malibu%04x_%d", 0x30, i);
if (stat(buf, &sbuf) < 0) {
break;
}
else {
printf("file \"%s\" exists\n", buf);
}
}
numBoards = i;
printf("numBoards = %d\n", numBoards);
for (i = 0; i < numBoards; i++)
{
char buf[128];
MalibuDrv_INFO info;
//sprintf(buf, "malibu_%d", i);
sprintf(buf, MALIBU_DEV_NAME, 0x30, i);
fds[i] = rt_dev_open(buf, O_RDWR);
if (fds[i] < 0)
{
sprintf(buf, "%s open failed", buf,i);
perror(buf);
return -1;
} else
printf("%s open OK, fds[%d]=%d\n", buf, i, fds[i]);
printf("calling rt_dev_ioctl::MALIBU_GET_INFO\n");
if (rt_dev_ioctl(fds[i], MALIBU_GET_INFO, &info) < 0)
{
perror("ioctl MALIBU_GET_INFO");
exit(-1);
}
printf("%d: vendorId=%x, deviceId=%x, subVendorId=%x, subDeviceId=%x, bus=%x, slot=%x, func=%x revision=%d numBars=%d\n",
i, info.vendorId, info.deviceId, info.subVendorId, info.subDeviceId,
info.bus, info.slot, info.func,
info.revision,
info.numBars);
bufs[i][0].size = 4 * 1024 * 1024;
bufs[i][0].bufNum = 0;
if (rt_dev_ioctl(fds[i], MALIBU_ALLOC_BUFFER, &bufs[i][0]) < 0) {
perror("rt_dev_ioctl MALIBU_ALLOC_BUFFER");
exit(-1);
}
printf("MALIBU_ALLOC_BUFFER: bufs.physAddr=%p\n", bufs[i][0].physAddr);
bufs[i][1].size = 1024 * 1024;
bufs[i][1].bufNum = 1;
if (rt_dev_ioctl(fds[i], MALIBU_ALLOC_BUFFER, &bufs[i][1]) < 0) {
perror("rt_dev_ioctl MALIBU_ALLOC_BUFFER");
exit(-1);
}
printf("MALIBU_ALLOC_BUFFER: bufs.physAddr=%p\n", bufs[i][1].physAddr);
printf("calling rt_dev_ioctl::MALIBU_GET_BAR_SIZE\n");
int bar=0;
int barSize = rt_dev_ioctl(fds[i], MALIBU_GET_BAR_SIZE, &bar);
printf("bar=%d, barSize = %d", bar, barSize);
printf("calling rt_dev_ioctl::MALIBU_FREE_BUFFER\n");
rt_dev_ioctl(fds[i], MALIBU_GET_BAR_SIZE, &bufs[i][0]);
rt_dev_ioctl(fds[i], MALIBU_GET_BAR_SIZE, &bufs[i][1]);
#if 0
for (barCnt[i] = 0; barCnt[i] < MALIBU_BAR_MAX; barCnt[i]++) {
barSize[i][barCnt[i]] = rt_dev_ioctl(fds[i], MALIBU_GET_BAR_SIZE, barCnt[i]);
if (barSize[i][barCnt[i]] < 0) {
perror("rt_dev_ioctl MALIBU_BAR_GET_SIZE");
exit(-1);
}
if (barSize[i][barCnt[i]] == 0) break;
printf("\tbarSize[%d][%d]=0x%x\n", i, barCnt[i], barSize[i][barCnt[i]]);
}
for (j = 0; j < barCnt[i]; j++) {
bars[i][j] = (char*)mmap(0, barSize[i][j], PROT_READ|PROT_WRITE, MAP_SHARED, fds[i], j * MALIBU_MMAP_SIZE);
if ((void*)bars[i][j] == MAP_FAILED) {
perror("mmap");
exit(-1);
}
printf("\tbar[%d][%d] = %p\n", i, j, bars[i][j]);
}
for (j = 0; j < 2; j++) {
bufPtrs[i][j] = (char*)mmap(0, bufs[i][j].size, PROT_READ|PROT_WRITE, MAP_SHARED, fds[i], (j + MALIBU_BAR_MAX) * MALIBU_MMAP_SIZE);
if ((void*)bufPtrs[i][j] == MAP_FAILED) {
perror("mmap");
exit(-1);
}
printf("\tbufPtrs[%d][%d] = %p, physAddr=%llx\n", i, j, bufPtrs[i][j], bufs[i][j].physAddr);
}
#endif
}
#if 0
boardCnt = i;
for (i = 0; i < boardCnt; i++) {
for (j = 0; j < boardCnt; j++) {
printf("board %d buf %d = %08x %08x %08x\n", i, j,
((uint32_t*)bufPtrs[i][j])[0],
((uint32_t*)bufPtrs[i][j])[1],
((uint32_t*)bufPtrs[i][j])[2]);
}
}
gettimeofday(&startTime, 0);
for (i = 0; i < boardCnt; i++) {
pthread_create(&tid[i], NULL, backgroundThr, (void*)fds[i]);
}
printf("calling rt_dev_ioctl::MALIBU_FAKE_SIG\n");
for (i = 0; i < 10; i++) {
int j;
MalibuDrv_FakeISR x;
sleep(1);
x.depth = i + 1;
for (j = 0; j < x.depth; j++) x.data[j] = 16 * i + j;
if (i & 1) rt_dev_ioctl(fds[0], MALIBU_FAKE_SIG, &x);
else rt_dev_ioctl(fds[1], MALIBU_FAKE_SIG, &x);
}
doExit = 1;
sleep(4);
printf("threads killed\n");
printf("calling rt_dev_ioctl::MALIBU_SET_ISR_CTRL\n");
for (i = 0; i < numBoards; i++) {
MalibuDrv_IntCtrl isrCtrl;
isrCtrl.bar = 0;
isrCtrl.byteOffset = 0;
isrCtrl.cntxtFunc = (void (*)(void*)) hello_world;
isrCtrl.cntxtArg = (void*) malloc(128);
sprintf((char*)isrCtrl.cntxtArg, "hello from %d\n", i);
if (rt_dev_ioctl(fds[i], MALIBU_SET_ISR_CTRL, &isrCtrl) < 0) {
perror("new rt_dev_ioctl\n");
exit(-1);
}
act[i].sa_sigaction = myHandler;
act[i].sa_flags = SA_SIGINFO;
sigemptyset(&act[i].sa_mask);
sigaction(SIGIO, act+i, 0);
// rt_dev_ioctl(fds[i], MALIBU_SET_SIG, SIGIO);
fcntl(fds[i], F_SETFL, O_ASYNC);
fcntl(fds[i], F_SETOWN, getpid());
fcntl(fds[i], F_SETSIG, SIGIO);
}
printf("MALIBU_FAKE_SIG\n");
for (i = 0; i < 10; i++) {
int j;
MalibuDrv_FakeISR x;
sleep(1);
x.depth = i + 1;
for (j = 0; j < x.depth; j++) x.data[j] = 16 * i + j;
if (i & 1) rt_dev_ioctl(fds[0], MALIBU_FAKE_SIG, &x);
else rt_dev_ioctl(fds[1], MALIBU_FAKE_SIG, &x);
}
for (i = 0; i < boardCnt; i++) {
for (j = 0; j < barCnt[i]; j++) {
if (munmap(bars[i][j], barSize[i][j]) < 0) {
perror("munmap");
exit(-1);
}
}
for (j = 0; j < 2; j++) {
if (munmap(bufPtrs[i][j], bufs[i][j].size) < 0) {
perror("munmap");
exit(-1);
}
}
}
#endif
sleep(3);
exit(0);
}
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Xenomai-help] Xenomai mmap
2011-01-17 16:59 [Xenomai-help] Xenomai mmap Peter Hua
@ 2011-01-17 17:03 ` Gilles Chanteperdrix
2011-01-17 18:37 ` Peter Hua
2011-01-17 18:08 ` Gilles Chanteperdrix
1 sibling, 1 reply; 11+ messages in thread
From: Gilles Chanteperdrix @ 2011-01-17 17:03 UTC (permalink / raw)
To: Peter Hua; +Cc: xenomai, pwfhua
Peter Hua wrote:
> Is there any example code to map PCI registers into user space? I am having
> problem getting functions rtdm_iomap_to_user and mmap to compile. My code
> is attached.
What platform? What error message do you get?
--
Gilles.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Xenomai-help] Xenomai mmap
2011-01-17 16:59 [Xenomai-help] Xenomai mmap Peter Hua
2011-01-17 17:03 ` Gilles Chanteperdrix
@ 2011-01-17 18:08 ` Gilles Chanteperdrix
2011-01-17 18:43 ` Peter Hua
2011-01-17 18:44 ` Peter Hua
1 sibling, 2 replies; 11+ messages in thread
From: Gilles Chanteperdrix @ 2011-01-17 18:08 UTC (permalink / raw)
To: Peter Hua; +Cc: xenomai, pwfhua
Peter Hua wrote:
> Is there any example code to map PCI registers into user space? I am having
> problem getting functions rtdm_iomap_to_user and mmap to compile. My code
> is attached.
>
>
>
> Xenomai - 2.4.10
>
> Kernel - 2.6.29.1
>
> OS - Red Hat 5.5
You will find the documentation of Xenomai 2.4.10 API here:
http://www.xenomai.org/documentation/xenomai-2.4/html/api/index.html
As you can see, it has no rtdm_iomap_to_user funtion.
--
Gilles.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Xenomai-help] Xenomai mmap
2011-01-17 17:03 ` Gilles Chanteperdrix
@ 2011-01-17 18:37 ` Peter Hua
2011-01-17 18:40 ` Gilles Chanteperdrix
2011-01-17 18:52 ` Philippe Gerum
0 siblings, 2 replies; 11+ messages in thread
From: Peter Hua @ 2011-01-17 18:37 UTC (permalink / raw)
To: 'Gilles Chanteperdrix'; +Cc: xenomai, pwfhua
Platform: X86, 64-bit
Thanks for the API linke. I have recoded to not use "rtdm_iomap_to_user" and used the mmap call. However, I am not able to open the driver with the open() call. It returned -1. Any suggestion? Example?
Thanks,
Peter Hua
Innovative Integration
805-578-4275
-----Original Message-----
From: Gilles Chanteperdrix [mailto:gilles.chanteperdrix@xenomai.org
Sent: Monday, January 17, 2011 9:03 AM
To: Peter Hua
Cc: xenomai@xenomai.org; pwfhua@domain.hid
Subject: Re: [Xenomai-help] Xenomai mmap
Peter Hua wrote:
> Is there any example code to map PCI registers into user space? I am having
> problem getting functions rtdm_iomap_to_user and mmap to compile. My code
> is attached.
What platform? What error message do you get?
--
Gilles.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Xenomai-help] Xenomai mmap
2011-01-17 18:37 ` Peter Hua
@ 2011-01-17 18:40 ` Gilles Chanteperdrix
2011-01-17 18:52 ` Philippe Gerum
1 sibling, 0 replies; 11+ messages in thread
From: Gilles Chanteperdrix @ 2011-01-17 18:40 UTC (permalink / raw)
To: Peter Hua; +Cc: xenomai, pwfhua
Peter Hua wrote:
> Platform: X86, 64-bit
>
> Thanks for the API linke. I have recoded to not use
> "rtdm_iomap_to_user" and used the mmap call. However, I am not able
> to open the driver with the open() call. It returned -1. Any
> suggestion? Example?
Suggestion? I do not know, buy a book on the POSIX API?
--
Gilles.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Xenomai-help] Xenomai mmap
2011-01-17 18:08 ` Gilles Chanteperdrix
@ 2011-01-17 18:43 ` Peter Hua
2011-01-17 18:45 ` Gilles Chanteperdrix
2011-01-17 18:44 ` Peter Hua
1 sibling, 1 reply; 11+ messages in thread
From: Peter Hua @ 2011-01-17 18:43 UTC (permalink / raw)
To: 'Gilles Chanteperdrix'; +Cc: xenomai, pwfhua
It is here:
http://www.xenomai.org/documentation/xenomai-2.4/html/api/index.html
Peter
-----Original Message-----
From: Gilles Chanteperdrix [mailto:gilles.chanteperdrix@xenomai.org
Sent: Monday, January 17, 2011 10:09 AM
To: Peter Hua
Cc: xenomai@xenomai.org; pwfhua@domain.hid
Subject: Re: [Xenomai-help] Xenomai mmap
Peter Hua wrote:
> Is there any example code to map PCI registers into user space? I am having
> problem getting functions rtdm_iomap_to_user and mmap to compile. My code
> is attached.
>
>
>
> Xenomai - 2.4.10
>
> Kernel - 2.6.29.1
>
> OS - Red Hat 5.5
You will find the documentation of Xenomai 2.4.10 API here:
http://www.xenomai.org/documentation/xenomai-2.4/html/api/index.html
As you can see, it has no rtdm_iomap_to_user funtion.
--
Gilles.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Xenomai-help] Xenomai mmap
2011-01-17 18:08 ` Gilles Chanteperdrix
2011-01-17 18:43 ` Peter Hua
@ 2011-01-17 18:44 ` Peter Hua
2011-01-17 18:54 ` Gilles Chanteperdrix
1 sibling, 1 reply; 11+ messages in thread
From: Peter Hua @ 2011-01-17 18:44 UTC (permalink / raw)
To: 'Gilles Chanteperdrix'; +Cc: xenomai, pwfhua
[-- Attachment #1.1: Type: text/plain, Size: 1021 bytes --]
One more time:
Thanks,
Peter Hua
Innovative Integration
805-578-4275
-----Original Message-----
From: Gilles Chanteperdrix [mailto:gilles.chanteperdrix@xenomai.org
Sent: Monday, January 17, 2011 10:09 AM
To: Peter Hua
Cc: xenomai@xenomai.org; pwfhua@domain.hid
Subject: Re: [Xenomai-help] Xenomai mmap
Peter Hua wrote:
> Is there any example code to map PCI registers into user space? I am having
> problem getting functions rtdm_iomap_to_user and mmap to compile. My code
> is attached.
>
>
>
> Xenomai - 2.4.10
>
> Kernel - 2.6.29.1
>
> OS - Red Hat 5.5
You will find the documentation of Xenomai 2.4.10 API here:
<http://www.xenomai.org/documentation/xenomai-2.4/html/api/index.html> http://www.xenomai.org/documentation/xenomai-2.4/html/api/index.html
As you can see, it has no rtdm_iomap_to_user funtion.
--
Gilles.
[-- Attachment #1.2: Type: text/html, Size: 4777 bytes --]
[-- Attachment #2: image001.png --]
[-- Type: image/png, Size: 935067 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Xenomai-help] Xenomai mmap
2011-01-17 18:43 ` Peter Hua
@ 2011-01-17 18:45 ` Gilles Chanteperdrix
0 siblings, 0 replies; 11+ messages in thread
From: Gilles Chanteperdrix @ 2011-01-17 18:45 UTC (permalink / raw)
To: Peter Hua; +Cc: xenomai, pwfhua
Peter Hua wrote:
> It is here:
>
> http://www.xenomai.org/documentation/xenomai-2.4/html/api/index.html
>
> Peter
Well not really, this is the index. But yes, Xenomai 2.4 has it. I am
surprised you get a compilation error then. But since you persist into
keeping this error a secret, I am afraid it will be hard for us to help you.
--
Gilles.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Xenomai-help] Xenomai mmap
2011-01-17 18:37 ` Peter Hua
2011-01-17 18:40 ` Gilles Chanteperdrix
@ 2011-01-17 18:52 ` Philippe Gerum
2011-01-17 22:10 ` Peter Hua
1 sibling, 1 reply; 11+ messages in thread
From: Philippe Gerum @ 2011-01-17 18:52 UTC (permalink / raw)
To: Peter Hua; +Cc: xenomai, pwfhua
On Mon, 2011-01-17 at 10:37 -0800, Peter Hua wrote:
> Platform: X86, 64-bit
>
> Thanks for the API linke. I have recoded to not use "rtdm_iomap_to_user" and used the mmap call. However, I am not able to open the driver with the open() call. It returned -1. Any suggestion? Example?
>
This is getting silly. Please make sure to use anything you may have
been given to do your work, by order of usefulness:
- brain,
- documentation,
- computer.
You obviously have a computer, so, if you are missing any other item
from this list, please make sure to get the complete package before
posting anew.
Also, please stop posting whatever code you happen to perpetrate to this
list: it gives anyone with a functional brain a huge feeling of
seasickness.
Final note: this list is not a cheap helpdesk to get his work done for
free. Everyone has to do some efforts to keep things rolling.
Thanks (I'm trying hard to mean it).
> Thanks,
> Peter Hua
> Innovative Integration
> 805-578-4275
>
>
> -----Original Message-----
> From: Gilles Chanteperdrix [mailto:gilles.chanteperdrix@xenomai.org]
> Sent: Monday, January 17, 2011 9:03 AM
> To: Peter Hua
> Cc: xenomai@xenomai.org; pwfhua@domain.hid
> Subject: Re: [Xenomai-help] Xenomai mmap
>
> Peter Hua wrote:
> > Is there any example code to map PCI registers into user space? I am having
> > problem getting functions rtdm_iomap_to_user and mmap to compile. My code
> > is attached.
>
> What platform? What error message do you get?
>
--
Philippe.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Xenomai-help] Xenomai mmap
2011-01-17 18:44 ` Peter Hua
@ 2011-01-17 18:54 ` Gilles Chanteperdrix
0 siblings, 0 replies; 11+ messages in thread
From: Gilles Chanteperdrix @ 2011-01-17 18:54 UTC (permalink / raw)
To: Peter Hua; +Cc: xenomai, pwfhua
Peter Hua wrote:
> One more time:
Ok. I feel like I am wasting my time with you, so, I am going to make a
few things clear:
- I do not have plenty of time, I am not your slave, so, I am not going
to work in your stead. If you want me to answer your questions, please
follow these guidelines:
http://www.catb.org/esr/faqs/smart-questions.html
- please follow usual usenet netiquette with regard to formatting,
quoting, etc...
--
Gilles.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Xenomai-help] Xenomai mmap
2011-01-17 18:52 ` Philippe Gerum
@ 2011-01-17 22:10 ` Peter Hua
0 siblings, 0 replies; 11+ messages in thread
From: Peter Hua @ 2011-01-17 22:10 UTC (permalink / raw)
To: 'Philippe Gerum', 'Gilles Chanteperdrix'; +Cc: xenomai, pwfhua
Let me apologies for my clumsiness, as I am new to all this. I will be more
careful.
Peter
-----Original Message-----
From: xenomai-help-bounces@domain.hid [mailto:xenomai-help-bounces@domain.hid] On
Behalf Of Philippe Gerum
Sent: Monday, January 17, 2011 10:52 AM
To: Peter Hua
Cc: xenomai@xenomai.org; pwfhua@domain.hid
Subject: Re: [Xenomai-help] Xenomai mmap
On Mon, 2011-01-17 at 10:37 -0800, Peter Hua wrote:
> Platform: X86, 64-bit
>
> Thanks for the API linke. I have recoded to not use "rtdm_iomap_to_user"
and used the mmap call. However, I am not able to open the driver with the
open() call. It returned -1. Any suggestion? Example?
>
This is getting silly. Please make sure to use anything you may have been
given to do your work, by order of usefulness:
- brain,
- documentation,
- computer.
You obviously have a computer, so, if you are missing any other item from
this list, please make sure to get the complete package before posting anew.
Also, please stop posting whatever code you happen to perpetrate to this
list: it gives anyone with a functional brain a huge feeling of seasickness.
Final note: this list is not a cheap helpdesk to get his work done for free.
Everyone has to do some efforts to keep things rolling.
Thanks (I'm trying hard to mean it).
> Thanks,
> Peter Hua
> Innovative Integration
> 805-578-4275
>
>
> -----Original Message-----
> From: Gilles Chanteperdrix [mailto:gilles.chanteperdrix@xenomai.org]
> Sent: Monday, January 17, 2011 9:03 AM
> To: Peter Hua
> Cc: xenomai@xenomai.org; pwfhua@domain.hid
> Subject: Re: [Xenomai-help] Xenomai mmap
>
> Peter Hua wrote:
> > Is there any example code to map PCI registers into user space? I am
having
> > problem getting functions rtdm_iomap_to_user and mmap to compile. My
code
> > is attached.
>
> What platform? What error message do you get?
>
--
Philippe.
_______________________________________________
Xenomai-help mailing list
Xenomai-help@domain.hid
https://mail.gna.org/listinfo/xenomai-help
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2011-01-17 22:10 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-01-17 16:59 [Xenomai-help] Xenomai mmap Peter Hua
2011-01-17 17:03 ` Gilles Chanteperdrix
2011-01-17 18:37 ` Peter Hua
2011-01-17 18:40 ` Gilles Chanteperdrix
2011-01-17 18:52 ` Philippe Gerum
2011-01-17 22:10 ` Peter Hua
2011-01-17 18:08 ` Gilles Chanteperdrix
2011-01-17 18:43 ` Peter Hua
2011-01-17 18:45 ` Gilles Chanteperdrix
2011-01-17 18:44 ` Peter Hua
2011-01-17 18:54 ` Gilles Chanteperdrix
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.