All of lore.kernel.org
 help / color / mirror / Atom feed
* [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(&current->mm->mmap_sem);
        usrAddr = (void *)mmap(
                0,
                (size_t)arg->size,
                (PROT_READ|PROT_WRITE),
                MAP_SHARED,
                filp, 0);
        //up_write(&current->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.