[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [microblaze-uclinux] FSL Driver Overhead



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi again,

After trying different variations of driver implementations, I couldn't get the overhead down. I then tried simply using the inline assembly instructions (put, get) to read/write to the FIFO directly from the OpenSSL code. My new speed measurements are as follows:

Software AES (128 bit): 75KB/s
Software+Hardware AES: 450 KB/s

Not a bad speed improvement after all!

On Jan 23, 2006, at 4:31 AM, Claudio Lanconelli wrote:

Hi Jonathan

Jonathan Jung wrote:

My driver implementation uses the example that Claudio suggested:

For Reading:
(...)
if(fsl_fifo->rx_cnt<FSLFIFO_BUF_SIZE)
{
restore_flags(flags);
do_reschedule++;
break;
}
restore_flags(flags);
(... End of function)

if(read_empty_counter !=0) printk("The number of read waits is %i \n",read_empty_counter);

This it isn't what I suggested to do. Look at my fslfifo.c.patch in the attachment.


For reading and writing (two examples):

key->rv = write(key->fd, &rk[i], sizeof(rk[i]));
key->rv = read(key->fd, &s0, sizeof(s0));

A better solution is to write your own simple driver, and use for example an ioctl() to implement a single transaction, both write to the fifo and read the result from the fifo.

If you need an example look at my fsl gpio driver in the attachment.
The ReadInputs command write a word to writefifo and read back a word from readfifo. Since the hardware ALWAYS puts the reply word in readfifo just after decode the command there would be no delay, and the loop is just for safeness (you can printk the k counter after the loop,
it should always be IO_FSLWAIT_LOOPS-1 ).

#define IO_FSLWAIT_LOOPS 10
extern __inline__ int Xfsl_IOctrl_ReadInputs(u32 *presult)
{
register int status, k, flags;

save_flags_cli (flags);
XFSL_IOCTRL_WriteCtrl( LSHIFT_IOCMD(RD_IN_SET_OUT_CMD), status );
if ( !Test_fsl_full(status) )
{
k = IO_FSLWAIT_LOOPS;
do {
XFSL_IOCTRL_ReadData( *presult, status );
} while ( Test_fsl_nodata(status) && --k > 0 );
*presult = RSHIFT_IOWORD(*presult & ~IOCMD_MASK); //Adjust result
}
restore_flags (flags);

return Test_fsl_status(status);
}

I hope this can help you.
Cheers,
Claudio Lanconelli

Index: fslfifo.c
===================================================================
RCS file: /var/cvs/uClinux-2.4.x/drivers/misc/fslfifo/fslfifo.c,v
retrieving revision 1.4
diff -u -r1.4 fslfifo.c
--- fslfifo.c	30 Nov 2005 05:25:42 -0000	1.4
+++ fslfifo.c	23 Jan 2006 12:05:30 -0000
@@ -73,6 +73,9 @@
 static struct miscdevice fsl_miscdev[MAX_FSLFIFO_COUNT];
 static struct fsl_fifo_t fsl_fifo_table[MAX_FSLFIFO_COUNT];

+static int write_full_counter;
+static int read_empty_counter;
+
 /* The tasklet data is the address of the first fsl_fifo in the array
    We do this so a single tasklet can process all fsl fifos
    hopefully saves us some time in doing multiple tasklet executions
@@ -134,6 +137,7 @@

 			if(fsl_nodata(fsl_status))
 			{
+				write_full_counter++;
 				do_reschedule++;
 				break;
 			}
@@ -186,14 +190,16 @@

 			void *ptr=&(fsl_fifo->rx_buf[fsl_fifo->rx_head]);

+			save_flags_cli(flags);
+
 			fsl_nget(fsl_fifo->id, val, fsl_status);
 			if(fsl_nodata(fsl_status))
 			{
+				read_empty_counter++;
+				restore_flags(flags);
 				break;
 			}

-			save_flags_cli(flags);
-
 			switch(fsl_fifo->width) {
 			case 1:
 				*((u8*)ptr) = val & 0xFF;
@@ -244,7 +250,7 @@
 	struct fsl_fifo_t *fsl_fifo;
 	int do_sched_tasklet=0;
 	unsigned flags;
-	int total=0;
+	int val, total=0;

 	fsl_fifo = (struct fsl_fifo_t *)f->private_data;
 	if(!fsl_fifo->exists)
@@ -256,6 +262,7 @@
 	while(fsl_fifo->tx_cnt==FSLFIFO_BUF_SIZE)
 	{
 		restore_flags(flags);
+		printk("fsl_write() BLOCK on SwFIFO full\n");
 		tasklet_schedule(&fsl_write_tasklet);
 		interruptible_sleep_on(&fsl_write_queue);
 		if(current->sigpending)
@@ -298,6 +305,13 @@
 	if(do_sched_tasklet)
 		tasklet_schedule(&fsl_write_tasklet);

+	save_flags(flags);
+	val = write_full_counter;
+	restore_flags(flags);
+
+	printk("fsl_write() wrote %d bytes (write_full_counter = %d)\n",
+			total, val);
+
 	return total;
 }

@@ -306,7 +320,7 @@
 {
 	struct fsl_fifo_t *fsl_fifo=(struct fsl_fifo_t *)f->private_data;
 	unsigned flags;
-	int total=0;
+	int val, total=0;

 	if(!fsl_fifo->exists)
 		return -ENODEV;
@@ -357,6 +371,13 @@
 	if(count)
 		tasklet_schedule(&fsl_read_tasklet);

+	save_flags_cli(flags);
+	val = read_empty_counter;
+	restore_flags(flags);
+
+	printk("fsl_read() read %d bytes (read_empty_counter = %d)\n",
+			total, val);
+
 	return total;
 }

@@ -370,6 +391,8 @@
 		return 0;

 	save_flags_cli(flags);
+	write_full_counter = 0;
+	read_empty_counter = 0;
 	fsl_fifo->rx_cnt=fsl_fifo->rx_head=fsl_fifo->rx_tail=0;
 	fsl_fifo->tx_cnt=fsl_fifo->tx_head=fsl_fifo->tx_tail=0;
 	restore_flags(flags);
/***
	$Id: mbfslgpio.c,v 1.2 2006/01/02 17:45:57 claudio Exp $
	mbfslgpio.c

	Microblaze FSL GPIO driver	
	(C) 2005  Claudio Lanconelli <lanconelli.claudio@xxxxxxxxx>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
***/

#include <linux/config.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/major.h> /* for MISC_MAJOR */

#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/delay.h>

#include <asm/mbfslgpio.h>
#include <asm/xfsl_ioctrl.h>

#include "mbfsl_iodefs.h"

#ifndef CONFIG_XILINX_FSL_IOCTRL_0_INSTANCE
#error "FSL I/O Core not instantiated!"
#endif

#define MBFSLGPIO_VERSION	" $Revision: 1.2 $"

#define DEBUG_MBFSLGPIO

#ifdef DEBUG_MBFSLGPIO
# define _DBG(x, fmt, args...) \
	do{ \
		if (mbfslgpio_debug >= x) \
printk(KERN_DEBUG "MBFSLGPIO %s: " fmt "\n", __FUNCTION__, ##args); \
	} while(0);
#else
# define _DBG(x, fmt, args...) do { } while(0);
#endif

#define	MBFSLGPIO_MINOR		241

#define	KB(x)	((x) * 1024L)
#define	MB(x)	( KB(x) * 1024L )


//Variables
int mbfslgpio_debug = 1;

/** Linux kernel driver section **/

//static ssize_t mbfslgpio_read( struct file *file, char *buf, size_t count, loff_t *ppos ); //static ssize_t mbfslgpio_write( struct file *file, const char *buf, size_t count, loff_t *ppos ); static int mbfslgpio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
static int mbfslgpio_open(struct inode *inode, struct file *filp);
static int mbfslgpio_release(struct inode *inode, struct file *filp);

static struct file_operations mbfslgpio_fops = {
	.owner	= THIS_MODULE,
//	.llseek	= mbfslgpio_llseek,
//	.read	= mbfslgpio_read,
//	.write	= mbfslgpio_write,
	.ioctl	= mbfslgpio_ioctl,
	.open	= mbfslgpio_open,
	.release= mbfslgpio_release
};

static struct miscdevice mbfslgpio_dev = {
	.minor	= MBFSLGPIO_MINOR,
	.name	= "mbfslgpio",
	.fops	= &mbfslgpio_fops,
};

//Only one process can open the graphic device at a time
static int mbfslgpio_open(struct inode *inode, struct file *filp)
{
	_DBG(2, "Open");

#ifdef	MODULE
	MOD_INC_USE_COUNT;
#endif	
	return 0;
}

static int mbfslgpio_release( struct inode *inode, struct file *file )
{
	_DBG(2, "Close");

#ifdef	MODULE
	MOD_DEC_USE_COUNT;
#endif	
	return 0;
}

static int mbfslgpio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	int retval = 0;
	u32 val;

	switch (cmd)
	{
		case MBFSLGPIO_IOCQDBGLEVEL:
		{
			_DBG(2, "get dbg level %d", mbfslgpio_debug);
			retval = mbfslgpio_debug;
			break;
		}
		case MBFSLGPIO_IOCTDBGLEVEL:
		{
			_DBG(2, "set dbg level %d", (int)arg);
			mbfslgpio_debug = (int)arg;
			break;
		}
		case MBFSLGPIO_IOCQINPUTS:
		{
			if ( Xfsl_IOctrl_ReadInputs(&val) )
			{
				retval = -EIO;
				_DBG(1, "Read inputs Error!");
			}
			else
			{
				retval = (int)val;
				_DBG(2, "Read inputs 0x%04x", retval);
			}
			break;
		}
		case MBFSLGPIO_IOCQOUTPUTS:
		{
			if ( Xfsl_IOctrl_ReadOutputs(&val) )
			{
				retval = -EIO;
				_DBG(1, "Read outputs Error!");
			}
			else
			{
				retval = (int)val;
				_DBG(2, "Read outputs 0x%04x", retval);
			}
			break;
		}
		case MBFSLGPIO_IOCTWROUTPUTS:
		case MBFSLGPIO_IOCTSETOUTPUTS:
		case MBFSLGPIO_IOCTCLROUTPUTS:
		case MBFSLGPIO_IOCTTOGOUTPUTS:
		default:
		{
			_DBG(1, "Unknown cmd=0x%x, arg=0x%lx", cmd, arg);
			retval = -EINVAL;
			break;
		}
	}
	return retval;
}

static int __init mbfslgpio_init(void)
{
	int result;

printk(KERN_INFO "Registering mbfslgpio " CONFIG_XILINX_FSL_IOCTRL_0_INSTANCE MBFSLGPIO_VERSION ". Major: %d Minor: %d\n", MISC_MAJOR, MBFSLGPIO_MINOR);

	result = misc_register(&mbfslgpio_dev);
	if (result)
	{
printk(KERN_ERR "%s: Could not register driver (%d)\n", mbfslgpio_dev.name, result);
		return result;
	}

	return 0;
}

static void __exit mbfslgpio_exit(void)
{
	misc_deregister(&mbfslgpio_dev);
}

module_init(mbfslgpio_init);
module_exit(mbfslgpio_exit);

MODULE_PARM(mbfslgpio_debug, "i");
MODULE_PARM_DESC(mbfslgpio_debug, "Correct debug level (0: no message, 4: verbose)");

MODULE_AUTHOR("Lanconelli Claudio <lanconelli.claudio@xxxxxxxxx>");
MODULE_DESCRIPTION("Microblaze FSL GPIO driver");
MODULE_LICENSE("GPL");
/*
 * xfsl_ioctrl.h -- FSL I/O Controller low level functions
 *
* Copyright (C) 2005 Claudio Lanconelli <lanconelli.claudio@xxxxxxxxx>
 *
 * $Id: xfsl_ioctrl.h,v 1.7 2005/12/21 16:00:13 claudio Exp $
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License
 *	as published by the Free Software Foundation; either version
 *	2 of the License, or (at your option) any later version.
 */

#ifndef _XFSL_IO_CTRL_H
#define _XFSL_IO_CTRL_H

#include <linux/config.h>

//xparameters.h
//SLOT IDs are automatically generated in xparameters.h. Unfortunately they are not in autoconf too!!!!
//So we must manually configure them

#ifndef XPAR_FSL_IOCTRL_OUTPUT_SLOT_ID
# ifndef CONFIG_MB_FSL_IOCTRL_OUT_SLOT_ID
#  error "MB_FSL_IOCTRL_OUT_SLOT_ID not configured!"
# endif
# ifndef CONFIG_MB_FSL_IOCTRL_IN_SLOT_ID
#  error "MB_FSL_IOCTRL_IN_SLOT_ID not configured!"
# endif
# define XPAR_FSL_IOCTRL_OUTPUT_SLOT_ID CONFIG_MB_FSL_IOCTRL_OUT_SLOT_ID
# define XPAR_FSL_IOCTRL_INPUT_SLOT_ID	CONFIG_MB_FSL_IOCTRL_IN_SLOT_ID
#endif

#ifndef CONFIG_BLOCKING_FSL_IO

# include <asm/fsl.h>

# define Test_fsl_status(x) ( (x) & (MSR_CARRY_MASK| MSR_FSL_ERROR_MASK) )
# define Test_fsl_error(x)	( (x) & MSR_FSL_ERROR_MASK )
# define Test_fsl_nodata(x)	( (x) & MSR_CARRY_MASK )
# define Test_fsl_full(x)	( (x) & MSR_CARRY_MASK )

# define XFSL_IOCTRL_WriteData(val,status) fsl_nput (XPAR_FSL_IOCTRL_OUTPUT_SLOT_ID,val,status) # define XFSL_IOCTRL_WriteCtrl(val,status) fsl_ncput (XPAR_FSL_IOCTRL_OUTPUT_SLOT_ID,val,status) # define XFSL_IOCTRL_ReadData(val,status) fsl_nget (XPAR_FSL_IOCTRL_INPUT_SLOT_ID,val,status)

#else

//Taken from mb_interface.h, simple fsl ops without status checking

# define microblaze_bwrite_datafsl(val, id) asm volatile ("put %0, rfsl" #id :: "d" (val)) # define microblaze_bwrite_cntlfsl(val, id) asm volatile ("cput % 0, rfsl" #id :: "d" (val)) # define microblaze_bread_datafsl(val, id) asm volatile ("get %0, rfsl" #id : "=d" (val)) # define microblaze_bread_cntlfsl(val, id) asm volatile ("cget %0, rfsl" #id : "=d" (val))

# define Test_fsl_status(x)	(0)
# define Test_fsl_error(x)	(0)
# define Test_fsl_nodata(x)	(0)
# define Test_fsl_full(x)	(0)

# if XPAR_FSL_IOCTRL_OUTPUT_SLOT_ID == 0
# define XFSL_IOCTRL_WriteData(val,status) microblaze_bwrite_datafsl(val,0) # define XFSL_IOCTRL_WriteCtrl(val,status) microblaze_bwrite_cntlfsl(val,0)
# elif XPAR_FSL_IOCTRL_OUTPUT_SLOT_ID == 1
# define XFSL_IOCTRL_WriteData(val,status) microblaze_bwrite_datafsl(val,1) # define XFSL_IOCTRL_WriteCtrl(val,status) microblaze_bwrite_cntlfsl(val,1)
# elif XPAR_FSL_IOCTRL_OUTPUT_SLOT_ID == 2
# define XFSL_IOCTRL_WriteData(val,status) microblaze_bwrite_datafsl(val,2) # define XFSL_IOCTRL_WriteCtrl(val,status) microblaze_bwrite_cntlfsl(val,2)
# elif XPAR_FSL_IOCTRL_OUTPUT_SLOT_ID == 3
# define XFSL_IOCTRL_WriteData(val,status) microblaze_bwrite_datafsl(val,3) # define XFSL_IOCTRL_WriteCtrl(val,status) microblaze_bwrite_cntlfsl(val,3)
# elif XPAR_FSL_IOCTRL_OUTPUT_SLOT_ID == 4
# define XFSL_IOCTRL_WriteData(val,status) microblaze_bwrite_datafsl(val,4) # define XFSL_IOCTRL_WriteCtrl(val,status) microblaze_bwrite_cntlfsl(val,4)
# elif XPAR_FSL_IOCTRL_OUTPUT_SLOT_ID == 5
# define XFSL_IOCTRL_WriteData(val,status) microblaze_bwrite_datafsl(val,5) # define XFSL_IOCTRL_WriteCtrl(val,status) microblaze_bwrite_cntlfsl(val,5)
# elif XPAR_FSL_IOCTRL_OUTPUT_SLOT_ID == 6
# define XFSL_IOCTRL_WriteData(val,status) microblaze_bwrite_datafsl(val,6) # define XFSL_IOCTRL_WriteCtrl(val,status) microblaze_bwrite_cntlfsl(val,6)
# elif XPAR_FSL_IOCTRL_OUTPUT_SLOT_ID == 7
# define XFSL_IOCTRL_WriteData(val,status) microblaze_bwrite_datafsl(val,7) # define XFSL_IOCTRL_WriteCtrl(val,status) microblaze_bwrite_cntlfsl(val,7)
# endif

# if XPAR_FSL_IOCTRL_INPUT_SLOT_ID == 0
# define XFSL_IOCTRL_ReadData(val,status) microblaze_bread_datafsl (val,0)
# elif XPAR_FSL_IOCTRL_INPUT_SLOT_ID == 1
# define XFSL_IOCTRL_ReadData(val,status) microblaze_bread_datafsl (val,1)
# elif XPAR_FSL_IOCTRL_INPUT_SLOT_ID == 2
# define XFSL_IOCTRL_ReadData(val,status) microblaze_bread_datafsl (val,2)
# elif XPAR_FSL_IOCTRL_INPUT_SLOT_ID == 3
# define XFSL_IOCTRL_ReadData(val,status) microblaze_bread_datafsl (val,3)
# elif XPAR_FSL_IOCTRL_INPUT_SLOT_ID == 4
# define XFSL_IOCTRL_ReadData(val,status) microblaze_bread_datafsl (val,4)
# elif XPAR_FSL_IOCTRL_INPUT_SLOT_ID == 5
# define XFSL_IOCTRL_ReadData(val,status) microblaze_bread_datafsl (val,5)
# elif XPAR_FSL_IOCTRL_INPUT_SLOT_ID == 6
# define XFSL_IOCTRL_ReadData(val,status) microblaze_bread_datafsl (val,6)
# elif XPAR_FSL_IOCTRL_INPUT_SLOT_ID == 7
# define XFSL_IOCTRL_ReadData(val,status) microblaze_bread_datafsl (val,7)
# endif

#endif


//Bits used to address the registers in the hardware
#define IOADDR_BITS		2

//Note that Microblaze need the value in MSBits
//It should be handled by the hardware to avoid all the shifting especially in
// case of no barrel shifter
#define RSHIFT_IOWORD(x) ((x) >> (32 - CONFIG_XILINX_FSL_IOCTRL_0_FSL_DATA_BITS)) #define LSHIFT_IOWORD(x) ((x) << (32 - CONFIG_XILINX_FSL_IOCTRL_0_FSL_DATA_BITS))
#define	LSHIFT_IOCMD(x)		((x) << (32 - IOADDR_BITS))
#define IOCMD_MASK			(0xffL << (32 - IOADDR_BITS))

//Commands code
#define	CLR_OUT_CMD	0L
#define SET_OUT_CMD	1L
#define	WR_OUT_CMD	2L
#define	TG_OUT_CMD	3L

#define	RD_OUT_CMD			0L
#define	RD_IN_WR_OUT_CMD	1L
#define	RD_IN_CLR_OUT_CMD	2L
#define	RD_IN_SET_OUT_CMD	3L

extern __inline__ int Xfsl_IOctrl_WriteOutputs(u32 Mask)
{
	register int status, flags;

	save_flags_cli(flags);
XFSL_IOCTRL_WriteData( LSHIFT_IOCMD(WR_OUT_CMD) | LSHIFT_IOWORD (Mask), status );
	restore_flags(flags);

	return Test_fsl_full(status);
}

extern __inline__ int Xfsl_IOctrl_SetOutputs(u32 Mask)
{
	register int status, flags;

	save_flags_cli(flags);
XFSL_IOCTRL_WriteData( LSHIFT_IOCMD(SET_OUT_CMD) | LSHIFT_IOWORD (Mask), status );
	restore_flags(flags);

	return Test_fsl_full(status);
}

extern __inline__ int Xfsl_IOctrl_ClearOutputs(u32 Mask)
{
	register int status, flags;

	save_flags_cli(flags);
XFSL_IOCTRL_WriteData( LSHIFT_IOCMD(CLR_OUT_CMD) | LSHIFT_IOWORD (Mask), status );
	restore_flags(flags);

	return Test_fsl_full(status);
}

extern __inline__ int Xfsl_IOctrl_ToggleOutputs(u32 Mask)
{
	register int status, flags;

	save_flags_cli(flags);
XFSL_IOCTRL_WriteData( LSHIFT_IOCMD(TG_OUT_CMD) | LSHIFT_IOWORD (Mask), status );
	restore_flags(flags);

	return Test_fsl_full(status);
}

#define IO_FSLWAIT_LOOPS	10

extern __inline__ int Xfsl_IOctrl_ReadOutputs(u32 *presult)
{
	register int status, k, flags;

	save_flags_cli (flags);
	XFSL_IOCTRL_WriteCtrl( LSHIFT_IOCMD(RD_OUT_CMD), status );
	if ( !Test_fsl_full(status) )
	{
		k = IO_FSLWAIT_LOOPS;
		do {
			XFSL_IOCTRL_ReadData( *presult, status );
		} while ( Test_fsl_nodata(status) && --k > 0 );
		*presult = RSHIFT_IOWORD(*presult & ~IOCMD_MASK);		//Adjust result
	}
	restore_flags (flags);

	return Test_fsl_status(status);
}

extern __inline__ int Xfsl_IOctrl_ReadInputs(u32 *presult)
{
	register int status, k, flags;

	save_flags_cli (flags);
	XFSL_IOCTRL_WriteCtrl( LSHIFT_IOCMD(RD_IN_SET_OUT_CMD), status );
	if ( !Test_fsl_full(status) )
	{
		k = IO_FSLWAIT_LOOPS;
		do {
			XFSL_IOCTRL_ReadData( *presult, status );
		} while ( Test_fsl_nodata(status) && --k > 0 );
		*presult = RSHIFT_IOWORD(*presult & ~IOCMD_MASK);		//Adjust result
	}
	restore_flags (flags);

	return Test_fsl_status(status);
}

extern __inline__ int Xfsl_IOctrl_ReadInputsWriteOutputs(u32 Mask, u32 *presult)
{
	register int status, k, flags;

	save_flags_cli (flags);
XFSL_IOCTRL_WriteCtrl( LSHIFT_IOCMD(RD_IN_WR_OUT_CMD) | LSHIFT_IOWORD(Mask), status );
	if ( !Test_fsl_full(status) )
	{
		k = IO_FSLWAIT_LOOPS;
		do {
			XFSL_IOCTRL_ReadData( *presult, status );
		} while ( Test_fsl_nodata(status) && --k > 0 );
		*presult = RSHIFT_IOWORD(*presult & ~IOCMD_MASK);		//Adjust result
	}
	restore_flags (flags);

	return Test_fsl_status(status);
}

extern __inline__ int Xfsl_IOctrl_ReadInputsClearOutputs(u32 Mask, u32 *presult)
{
	register int status, k, flags;

	save_flags_cli (flags);
XFSL_IOCTRL_WriteCtrl( LSHIFT_IOCMD(RD_IN_CLR_OUT_CMD) | LSHIFT_IOWORD(Mask), status );
	if ( !Test_fsl_full(status) )
	{
		k = IO_FSLWAIT_LOOPS;
		do {
			XFSL_IOCTRL_ReadData( *presult, status );
		} while ( Test_fsl_nodata(status) && --k > 0 );
		*presult = RSHIFT_IOWORD(*presult & ~IOCMD_MASK);		//Adjust result
	}
	restore_flags (flags);

	return Test_fsl_status(status);
}

extern __inline__ int Xfsl_IOctrl_ReadInputsSetOutputs(u32 Mask, u32 *presult)
{
	register int status, k, flags;

	save_flags_cli (flags);
XFSL_IOCTRL_WriteCtrl( LSHIFT_IOCMD(RD_IN_SET_OUT_CMD) | LSHIFT_IOWORD(Mask), status );
	if ( !Test_fsl_full(status) )
	{
		k = IO_FSLWAIT_LOOPS;
		do {
			XFSL_IOCTRL_ReadData( *presult, status );
		} while ( Test_fsl_nodata(status) && --k > 0 );
		*presult = RSHIFT_IOWORD(*presult & ~IOCMD_MASK);		//Adjust result
	}
	restore_flags (flags);

	return Test_fsl_status(status);
}

#endif
/**
 * $Id: mbfslgpio.h,v 1.1 2006/01/02 13:34:50 claudio Exp $
 **/

#ifndef _MBFSLGPIO_H
#define _MBFSLGPIO_H

#ifdef	__KERNEL__
#include <linux/ioctl.h>
#else
#include <sys/ioctl.h>
#endif

#define MBFSLGPIO_MAGIC 'g'

/*
 * S means "Set" through a ptr
 * T means "Tell" directly with the argument value
 * G means "Get" reply by setting through a ptr
 * Q means "Query" response is on the return value
 */

#define MBFSLGPIO_IOCQDBGLEVEL		_IOR(MBFSLGPIO_MAGIC, 1, unsigned int)
#define MBFSLGPIO_IOCTDBGLEVEL		_IOW(MBFSLGPIO_MAGIC, 2, unsigned int)

#define MBFSLGPIO_IOCQINPUTS		_IOR(MBFSLGPIO_MAGIC, 3, unsigned int)

#define MBFSLGPIO_IOCQOUTPUTS		_IOR(MBFSLGPIO_MAGIC, 5, unsigned int)
#define MBFSLGPIO_IOCTWROUTPUTS _IOW(MBFSLGPIO_MAGIC, 6, unsigned int) #define MBFSLGPIO_IOCTSETOUTPUTS _IOW(MBFSLGPIO_MAGIC, 7, unsigned int) #define MBFSLGPIO_IOCTCLROUTPUTS _IOW(MBFSLGPIO_MAGIC, 8, unsigned int) #define MBFSLGPIO_IOCTTOGOUTPUTS _IOW(MBFSLGPIO_MAGIC, 9, unsigned int)

#endif

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Darwin)

iD8DBQFD3rmt4kOt3FHegqgRAh2QAJ9L5+ke0WTfMCUQcSrMPhT1mDfS5QCfb6pl
Lc2dDoF3OZdf1emEUj0b5WQ=
=AITt
-----END PGP SIGNATURE-----
___________________________
microblaze-uclinux mailing list
microblaze-uclinux@xxxxxxxxxxxxxx
Project Home Page : http://www.itee.uq.edu.au/~jwilliams/mblaze-uclinux
Mailing List Archive : http://www.itee.uq.edu.au/~listarch/microblaze-uclinux/