All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Hans J. Koch" <hjk@hansjkoch.de>
To: "Worth, Kevin" <kevin.worth@hp.com>
Cc: "Hans J. Koch" <hjk@hansjkoch.de>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"u.kleine-koenig@pengutronix.de" <u.kleine-koenig@pengutronix.de>
Subject: Re: Using uio_pdrv to create an platform device for an FPGA, mmap() fails
Date: Thu, 30 Aug 2012 21:00:19 +0200	[thread overview]
Message-ID: <20120830190019.GB4819@local> (raw)
In-Reply-To: <B5EF724456FFB24A8C8AE88E26CE8F4B66840BEE@G9W0725.americas.hpqcorp.net>

On Thu, Aug 30, 2012 at 06:36:53PM +0000, Worth, Kevin wrote:
> Thanks for the reply, Hans. Your question about opening /dev/uio0 O_RDWR
> prompted me to check out how I was creating /dev/uio0 ... my system
> isn't using udev, and I was accidentally creating it with major/minor
> number 254/0 instead of the correct 253/0 (found by looking at
> /proc/devices). Fixed that and the mmap() call started working.

Good.

> 
> Verified that if /dev/uio0 has permissions 0644, root can open it O_RDWR
> and mmap PROT_READ | PROT_WRITE using the below code and write to an
> address within my memory map. Of course this contradicts the statement
> "/dev/uioX is a read-only file" in the UIO howto.

You're right. That wants to be fixed...

> 
> Including my updated, tested code for completeness.
> Note I also cleaned up the device registration a little by
> using a different platform_device_register_ call and removing fields
> in the struct uio_info that get filled in by uio_pdrv automatically.

If you want to have that included in the mainline, please choose a more
descriptive name than "myfpga" and send a proper patch.

Thanks,
Hans

> 
> -Kevin
> 
> # lsuio -m -v
> uio0: name=uio_myfpga, version=0.1, events=0
>         map[0]: addr=0xD0000000, size=262144, mmap test: OK
>         Device attributes:
>         uevent=DRIVER=uio_pdrv
>         modalias=platform:uio_pdrv
> 
> ------Kernelspace------
> #include <linux/platform_device.h>
> #include <linux/uio_driver.h>
> #include <linux/module.h>
> 
> #define MYFPGA_BASE     0xd0000000 // 3G
> #define MYFPGA_SIZE     0x00040000 // 256k
> 
> static struct resource myfpga_resources[] = {
>     {
>         .start = MYFPGA_BASE,
>         .end   = MYFPGA_BASE + MYFPGA_SIZE - 1,
>         .name  = "myfpga",
>         .flags = IORESOURCE_MEM
>     }
> };
> 
> static struct uio_info myfpga_uio_info = {
>    .name = "uio_myfpga",
>    .version = "0.1",
> };
> 
> static struct platform_device *myfpga_uio_pdev;
> 
> static int __init myfpga_init(void)
> {
>     myfpga_uio_pdev = platform_device_register_resndata (NULL,
>                                                          "uio_pdrv",
>                                                          -1,
>                                                          myfpga_resources,
>                                                          1,
>                                                          &myfpga_uio_info,
>                                                          sizeof(struct uio_info)
>                                                         );
>     if (IS_ERR(myfpga_uio_pdev)) {
>         return PTR_ERR(myfpga_uio_pdev);
>     }
> 
>     return 0;
> }
> 
> static void __exit myfpga_exit(void)
> {
>     platform_device_unregister(myfpga_uio_pdev);
> }
> 
> module_init(myfpga_init);
> module_exit(myfpga_exit);
> 
> ------Userspace-------
> #include <sys/types.h>
> #include <sys/mman.h>
> #include <sys/stat.h>
> 
> #include <dirent.h>
> #include <string.h>
> #include <stdlib.h>
> #include <stdio.h>
> #include <fcntl.h>
> #include <unistd.h>
> #include <stdint.h>
> 
> #define MYFPGA_BASE     0xd0000000 // 3G
> #define MYFPGA_SIZE     0x00040000 // 256k
> #define MYFPGA_MAP_NUM  0 // First and only defined map
> 
> #define BIT32(n) (1 << (n))
> 
> /* Use mmap()'ped address "iomem", not physical MYFPGA address */
> #define MYFPGA_REG(iomem) (volatile uint32_t*)(iomem + 0x8) // Third 32-bit reg
> 
> int main (int argc, char *argv[])
> {
>     int fd;
>     void *iomem;
>     fd = open("/dev/uio0", O_RDWR|O_SYNC);
>     if (fd < 0) {
>         printf("failed to open /dev/uio0, quitting\n");
>         return -1;
>     }
>     /* Note offset has a special meaning with uio devices */
>     iomem = mmap(NULL, MYFPGA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
>                  MYFPGA_MAP_NUM * getpagesize());
>     if (iomem == MAP_FAILED) {
>         printf("mmap failed, quitting\n");
>         close(fd);
>         return -2;
>     }
> 
>     /* Set bit 5 of MYFPGA_REG register */
>     *MYFPGA_REG(iomem) |= BIT32(5);
> 
>     munmap(iomem, MYFPGA_SIZE);
>     close(fd);
>     return 0;
> }
>  
> 

  reply	other threads:[~2012-08-30 19:00 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-29 23:19 Using uio_pdrv to create an platform device for an FPGA, mmap() fails Worth, Kevin
2012-08-30  3:27 ` Hans J. Koch
2012-08-30 18:36   ` Worth, Kevin
2012-08-30 19:00     ` Hans J. Koch [this message]
2012-08-30 20:10       ` Worth, Kevin
2012-08-30 22:24         ` Hans J. Koch
2012-08-30 23:03           ` Worth, Kevin
2012-08-31  8:42             ` Hans J. Koch

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120830190019.GB4819@local \
    --to=hjk@hansjkoch.de \
    --cc=kevin.worth@hp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=u.kleine-koenig@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.