public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Vijay Kumar <vijaykumar@bravegnu.org>
To: benh@kernel.crashing.org
Cc: "J.R. Mauro" <jrm8005@gmail.com>,
	Christoph Hellwig <hch@infradead.org>,
	Paul Mackerras <paulus@samba.org>, Greg KH <greg@kroah.com>,
	Stephen Rothwell <sfr@canb.auug.org.au>,
	LKML <linux-kernel@vger.kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	"William L. Irwin" <wli@holomorphy.com>,
	jayakumar.lkml@gmail.com, sparclinux@vger.kernel.org
Subject: Re: sparc/staging compile error
Date: Tue, 11 Nov 2008 12:28:22 +0530	[thread overview]
Message-ID: <49192D0E.2000600@bravegnu.org> (raw)
In-Reply-To: <1226099192.13603.78.camel@pasglop>

Benjamin Herrenschmidt wrote:
> In any case, we would need to understand better your driver userspace
> API and transfer model to find the right solution.

Please find below the user space skeleton code, to access the driver. It 
was written by Robert Fitzsimons robfitz@273k.net The driver is based on 
this user space interface.

In short, there is a ring buffer that is shared between the _device_ and 
_user-space_. The ring buffer has a header, that is shared between the 
_kernel_ and _user-space_.

The header specifies the offsets of various buffers in the ring buffer. In 
Rx, after user space has read a buffer, the user space writes -1 to the 
offset in the header. When the device has filled the buffer, the kernel 
space writes the offset back to the header.

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>

#define G_USED -1

struct group_circular_buffer {
	int32_t group_size_bytes;
	int32_t group_count;
	int32_t group_offset[0];
};

int sysfs_write_long(const char *name, long value);
int sysfs_read_long(const char *name, long *value);
int sysfs_read_buffer(const char *name, void *buffer, int len);
int process_group(void *group, int32_t group_size_bytes);

int main(int argc, char **argv)
{
	int uio_fd;
	int rx_fd;
	int group_index;
	long mmap_buffer_size;
	struct pollfd poll_fds;
	struct group_circular_buffer *ring;
	char buffer[128];

	/* Query supported device and channels */
	sysfs_read_buffer("/sys/.../uioX/name", buffer, sizeof(buffer));
	sysfs_read_buffer("/sys/.../uioX/version", buffer, sizeof(buffer));
	sysfs_read_buffer("/sys/.../uioX/channels", buffer, sizeof(buffer));

	/* Open and mmap UIO device */
	uio_fd = open("/dev/.../uioX", O_RDWR);
	// uio_mmap = mmap(..., uio_fd, ...); /* map BAR1 */

	/* Configure 1 megabyte receive dma buffer */
	sysfs_write_long("/sys/.../uioX/rx0/block_size", 512);
	sysfs_write_long("/sys/.../uioX/rx0/group_size", 1);
	sysfs_write_long("/sys/.../uioX/rx0/group_count", 256);

	// configure user firmware, uio_mmap

	/* Open rx char device, which allocates suitable dma/mmap buffers */
	rx_fd = open("/dev/.../uioX/rx0", O_RDWR);

	/* Query size of mmap buffer, maybe use mmap for this value? */
	sysfs_read_long("/sys/.../uioX/rx0/mmap_buffer_size", &mmap_buffer_size);

	ring = mmap(NULL, mmap_buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, 
rx_fd, 0);

	// start/reset capture, uio_mmap

	group_index = 0;

	while (1) {
		if (ring->group_offset[group_index] > 0) {
			process_group(ring + ring->group_offset[group_index], 
ring->group_size_bytes);

			ring->group_offset[group_index] = G_USED;

			group_index = (group_index + 1) % ring->group_count;
		} else {
			poll_fds.fd = rx_fd;
			poll_fds.events = POLLIN | POLLERR;
			poll_fds.revents = 0;

			poll(&poll_fds, 1, -1);
		}
	}

	// stop capture, uio_mmap

	// munmap(ring)
	// munmap(uio_mmap)
	close(rx_fd);
	close(uio_fd);

	return 0;
}

int sysfs_write_long(const char *name, long value)
{
	return 0;
}

int sysfs_read_long(const char *name, long *value)
{
	return 0;
}

int sysfs_read_buffer(const char *name, void *buffer, int len)
{
	return 0;
}

int process_group(void *group, int32_t group_size_bytes)
{
	return 0;
}


Regards,
Vijay

      reply	other threads:[~2008-11-11  6:48 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-06  5:36 sparc/staging compile error Stephen Rothwell
2008-11-06  6:37 ` Greg KH
2008-11-06  6:39   ` David Miller
2008-11-06 10:32   ` Paul Mackerras
2008-11-06 14:06     ` J.R. Mauro
2008-11-06 17:32       ` Christoph Hellwig
2008-11-06 17:36         ` J.R. Mauro
2008-11-07  8:40           ` Vijay Kumar
2008-11-07 23:06             ` Benjamin Herrenschmidt
2008-11-11  6:58               ` Vijay Kumar [this message]

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=49192D0E.2000600@bravegnu.org \
    --to=vijaykumar@bravegnu.org \
    --cc=benh@kernel.crashing.org \
    --cc=davem@davemloft.net \
    --cc=greg@kroah.com \
    --cc=hch@infradead.org \
    --cc=jayakumar.lkml@gmail.com \
    --cc=jrm8005@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paulus@samba.org \
    --cc=sfr@canb.auug.org.au \
    --cc=sparclinux@vger.kernel.org \
    --cc=wli@holomorphy.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox