In my project,I want to use ioctl to write different format such as byte,word and so on.
static long fpgaIoctl(struct file *filePtr, unsigned int flag, unsigned long data)
{
SFPGA_IOCTL* pIoctl = (SFPGA_IOCTL*)data;
//struct DevInfo_t *devInfo = 0
int offset=pIoctl->offset;
printk(KERN_INFO "Offset value:%d",offset);
switch(flag)
{
//#define FPGA_WRITE_BYTE 0x101 ///< Defined for writing BYTE format
//#define FPGA_WRITEB(devInfo, data, offset) writeb(data, devInfo->resource[0].RegsBase+offset)
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(data,devInfo->resource[0].RegBase+offset);
break;
}
return 0;
}`
But,here I can not find a way to use devInfo in the Ioctl function to write my data.How can I define my devInfo struct in this function to access the registery base.
Also, my devInfo struct is like:
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 */
/* 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 my probe function for devInfo and first assign is:
static int fpgaProbe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct DevInfo_t *devInfo = 0;
int i;
int nvec=0;
LOGINF("Benim ilk logum nvec:%d", nvec);
LOGINF("Probe Fonksiyonundayım\n");
printk(KERN_INFO "Vendor = 0x%x, Device = 0x%x \n", dev->vendor, dev->device);
//Allocate and zero memory for devInfo
devInfo = kzalloc(sizeof(struct DevInfo_t), GFP_KERNEL);
if (!devInfo)
{
printk(KERN_WARNING "Couldn't allocate memory for device info!\n");
return -1;
}
//Copy in the pci device info
devInfo->pciDev = dev;
//Save the device info itself into the pci driver
dev_set_drvdata(&dev->dev, (void*) devInfo);
// Try to dynamically allocate a major number for the device -- more difficult but worth it
majorNumber = register_chrdev(0, DEVICE_NAME, &fileOps);
if (majorNumber<0)
{
printk(KERN_ALERT "failed to register a major number\n");
return majorNumber;
}
printk(KERN_INFO "registered correctly with major number %d\n", majorNumber);
// Register the device class
fpgacharClass = class_create(THIS_MODULE, CLASS_NAME);
if (IS_ERR(fpgacharClass))
{ // Check for error and clean up if there is
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_ALERT "Failed to register device class\n");
return -1; // Correct way to return an error on a pointer
}
printk(KERN_INFO "device class registered correctly\n");
// Register the device driver
fpgacharDevice = device_create(fpgacharClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
if (IS_ERR(fpgacharDevice))
{ // Clean up if there is an error
class_destroy(fpgacharClass); // Repeated code but the alternative is goto statements
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_ALERT "Failed to create the device\n");
return -1;
}
printk(KERN_INFO "device class created correctly\n"); // Made it! device was initialized
//Initialize other fields
devInfo->userPID = -1;
devInfo->buffer = kmalloc (BUFFER_SIZE * sizeof(char), GFP_KERNEL);
//Enable the PCI
if (pci_enable_device(dev))
{
printk(KERN_WARNING "pci_enable_device() failed!\n");
return -1;
}
//Enable PCI resources
if (pci_request_regions(dev, DRIVER_NAME))
{
printk(KERN_WARNING "pci_request_regions() failed!\n");
return -1;
}
pci_set_master(dev);
//Memory map the BAR regions into virtual memory space
//mapBars(devInfo);
//TODO: proper error catching and memory releasing
for(i=0;i<NUM_BARS;i++)
{
devInfo->resource[i].type=-1;
devInfo->resource[i].RegsBase=NULL;
devInfo->resource[i].RegsLength=-1;
}
for(i=0;i<NUM_BARS;i++)
{
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);
}
else if((pci_resource_flags(dev,i)&IORESOURCE_TYPE_BITS)==IORESOURCE_IO)
{
printk(KERN_INFO "iomap1\n");
//no iomap
}
}}
Is that possible to use
"struct DevInfo_t *devInfo =(struct DevInfo_t *) filePtr->private_data;"
in ioctl function to get devInfo information? or another things?
Thanks for your answers, King Regards.