0

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.

0 Answers0