How to Use Writeb in Ioctl Function?

How to Use Writeb in Ioctl Function?

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.

4
Chloe Bennett
Author

Chloe Bennett

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.