LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware > Linux - Embedded & Single-board computer
User Name
Password
Linux - Embedded & Single-board computer This forum is for the discussion of Linux on both embedded devices and single-board computers (such as the Raspberry Pi, BeagleBoard and PandaBoard). Discussions involving Arduino, plug computers and other micro-controller like devices are also welcome.

Notices


Reply
  Search this Thread
Old 06-13-2017, 07:26 AM   #1
cyapicioglu
LQ Newbie
 
Registered: Jun 2017
Posts: 3

Rep: Reputation: Disabled
Using ioctl for writing different types


In my project, I want to develop a Linux driver for communicating FPGA through PCIe.In the ioctl method I have,


//-------------------------------------------------------------
static long fpgaIoctl(struct file *filePtr, unsigned int flag, unsigned long data)
{
struct DevInfo_t *devInfo = 0;
devInfo = (struct DevInfo_t *) filePtr->private_data;
SFPGA_IOCTL* pIoctl = (SFPGA_IOCTL*)data;

switch(flag)
{

//#define FPGA_WRITE_BYTE 0x101 ///< Defined for writing BYTE format
case FPGA_WRITE_BYTE:
//FPGA_WRITEB(filePtr->, pIoctl->datab, pIoctl->offset);
//writeb(data, devInfo->resource[0].RegsBase+offset);
printk(KERN_INFO "FPGA_WRITEB calisiyor");
printk(KERN_ALERT "---%s---", (char *)data);

writeb((u8)data,devInfo->resource[0].RegsBase+pIoctl->offset);
printk(KERN_INFO "Written value: %d", (char)devInfo->resource[0].RegsBase+pIoctl->offset);
break;


}

return 0;
}
//------------------------------------------------------------

My first question is that can I use the following definitions to write different format like qword,word,long and so on? or something possible to write differetn types of data?

//------------------------------------------------------------
#if 0
extern u8 readb(const volatile void __iomem *addr);
extern u16 readw(const volatile void __iomem *addr);
extern u32 readl(const volatile void __iomem *addr);
extern u64 readq(const volatile void __iomem *addr);
extern void writeb(u8 b, volatile void __iomem *addr);
extern void writew(u16 b, volatile void __iomem *addr);
extern void writel(u32 b, volatile void __iomem *addr);
extern void writeq(u64 b, volatile void __iomem *addr);
#endif
//-------------------------------------------------------------

My devInfo structure is like the following;

//-------------------------------------------------------------

struct DevInfo_t
{
struct
{
int type;
int flag;
void* RegsBase; ///< Register base address
PHYSICAL_ADDRESS PhysBase;
u32 RegsLength;
}resource[6];

/* the kernel pci device data structure */
struct pci_dev *pciDev;
__iomem u32 *registers;


/* upstream root node */
struct pci_dev *upstream;

/* kernel's virtual addr. for the mapped BARs */
void * __iomem bar[NUM_BARS];

/* length of each memory region. Used for error checking. */
size_t barLengths[NUM_BARS];

/* temporary buffer. If allocated, will be BUFFER_SIZE. */
char *buffer;
wait_queue_head_t wait_q;

/* Mutex for this device. */
struct semaphore sem;

/* PID of process that called open() */
int userPID;
int flag;

/* character device */
dev_t cdevNum;
struct cdev cdev;
struct class *myClass;
struct device *device;

};

//-------------------------------------------------------------

and SFPGA_IOCTL structure is;


//-------------------------------------------------------------
typedef struct
{
union
{
u8 datab;
u16 dataw;
u32 datal;
u64 dataqw;
};
u64 offset;

}SFPGA_IOCTL;

//-------------------------------------------------------------


Subsequently,I take the RegisteryBase as follows in the probe function,

//------------------------------------------------------------
if((pci_resource_flags(dev,i)&IORESOURCE_TYPE_BITS)==IORESOURCE_MEM)
{
printk(KERN_INFO "memmap1");
devInfo->resource[i].type=IORESOURCE_MEM;
devInfo->resource[i].flag=pci_resource_flags(dev,i);
devInfo->resource[i].RegsLength=(u32)pci_resource_len(dev,i);
devInfo->resource[i].RegsBase=ioremap_nocache(pci_resource_start(dev,i),pci_resource_len(dev,i));
devInfo->resource[i].PhysBase.QuadPart=(u64)pci_resource_start(dev,i);

if(devInfo->resource[i].RegsBase==NULL)
{
printk(KERN_ERR "pci_ioremap_bar da hata olustu!\n");
return -ENOMEM;
}
printk(KERN_INFO "%d. bar icin type:%d",i,devInfo->resource[i].type);
printk(KERN_INFO "%d. bar icin register length:%d",i,devInfo->resource[i].RegsLength);
printk(KERN_INFO "%d. bar icin RegsBase:%p",i,devInfo->resource[i].RegsBase);

}

//-------------------------------------------------------------

And my mapping function for BAR of FPGA is;

static int mapBars(struct DevInfo_t *devInfo)
{
int ct = 0;
unsigned long barStart, barEnd, barLength; ///<Used for specifying bar start and end points and it's length
for (ct = 0; ct < NUM_BARS; ct++)
{
printk(KERN_INFO "BAR Map edilmeye calisiliyor #%d of %d.\n", ct, NUM_BARS);
barStart = pci_resource_start(devInfo->pciDev, ct);
barEnd = pci_resource_end(devInfo->pciDev, ct);
barLength = barEnd - barStart + 1;

devInfo->barLengths[ct] = barLength;

//Check for empty BAR
if (!barStart || !barEnd)
{
devInfo->barLengths[ct] = 0;
printk(KERN_INFO "Boş bar! #%d.\n", ct);
continue;
}

//Check for messed up BAR
if (barLength < 1)
{
printk(KERN_WARNING "BAR #%d uzunluğu 1 byte'dan daha az!.\n", ct);
continue;
}

// If we have a valid bar region then map the device memory or
// IO region into kernel virtual address space
devInfo->bar[ct] = pci_iomap(devInfo->pciDev, ct, barLength);

if (!devInfo->bar[ct])
{
printk(KERN_WARNING "BAR #%d map edilemedi.\n", ct);
return -1;
}

printk(KERN_INFO "BAR%d mapped at 0x%p with length %lu.\n", ct, devInfo->bar[ct], barLength);
}
return 0;
}
//------------------------------------------------------------
So,I am very new to develop Linux kernel and device drivers and when I run my testcode I face a trouble and computer is rebooting itself and then I can not login the system with my username and password and also I can not success the write operation.What can be a problem with my driver code?

Other thing is

static long fpgaIoctl(struct file *filePtr, unsigned int flag, unsigned long data)
{
struct DevInfo_t *devInfo = 0;
devInfo = (struct DevInfo_t *) filePtr->private_data;
SFPGA_IOCTL* pIoctl = (SFPGA_IOCTL*)data;
}

From the above code I took the devInfo with "devInfo = (struct DevInfo_t *) filePtr->private_data;" Is that true for taking driver information?

Thanks for your attentions and answers,
Best Regards.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Linux 4.2 breaks permissions for cd writing ioctl? TheRealGrogan Slackware 13 09-22-2015 02:29 AM
[SOLVED] writing and reading driver value in ioctl Vermidias Programming 12 01-19-2011 04:10 AM
[SOLVED] writing and reading driver value in ioctl Vermidias Linux - Kernel 1 01-19-2011 12:54 AM
sys/types.h & linux/types.h conflict while compiling johnnyhal Linux - Software 1 12-28-2008 06:39 PM
How to pass IOCTL arguments from usespace ioctl call devkpict Linux - Kernel 1 12-07-2007 06:45 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware > Linux - Embedded & Single-board computer

All times are GMT -5. The time now is 10:25 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration