Find the answer to your Linux question:
Results 1 to 2 of 2
Hi am developing a PCI Card and its driver for Linux. I got an open driver developed for a FPGA board (open code) and tried to understand the driver following ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    May 2010
    Posts
    11

    PCI Driver for Linux Problem


    Hi am developing a PCI Card and its driver for Linux. I got an open driver developed for a FPGA board (open code) and tried to understand the driver following the Linux Device Driver Book. I could understand most of the code but when i tried to build it for my kernel (Ubuntu 2.6.32-24) i got the following error:

    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:110: error: variable ‘pci_bridge_fops’ has initializer but incomplete type
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:112: error: unknown field ‘read’ specified in initializer
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:112: warning: excess elements in struct initializer
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:112: warning: (near initialization for ‘pci_bridge_fops’)
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:113: error: unknown field ‘write’ specified in initializer
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:113: warning: excess elements in struct initializer
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:113: warning: (near initialization for ‘pci_bridge_fops’)
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:114: error: unknown field ‘open’ specified in initializer
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:114: warning: excess elements in struct initializer
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:114: warning: (near initialization for ‘pci_bridge_fops’)
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:115: error: unknown field ‘release’ specified in initializer
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:115: warning: excess elements in struct initializer
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:115: warning: (near initialization for ‘pci_bridge_fops’)
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:116: error: unknown field ‘ioctl’ specified in initializer
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:116: warning: excess elements in struct initializer
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:116: warning: (near initialization for ‘pci_bridge_fops’)
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:117: error: unknown field ‘llseek’ specified in initializer
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:118: warning: excess elements in struct initializer
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:118: warning: (near initialization for ‘pci_bridge_fops’)
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c: In function ‘pci_bridge_init’:
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:218: error: implicit declaration of function ‘register_chrdev_region’
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:222: error: implicit declaration of function ‘alloc_chrdev_region’
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c: In function ‘pci_bridge_exit’:
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:316: error: implicit declaration of function ‘unregister_chrdev_region’
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c: In function ‘pci_bridge_open’:
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:327: error: dereferencing pointer to incomplete type
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:328: error: dereferencing pointer to incomplete type
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c: In function ‘bridge_lseek’:
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:352: error: dereferencing pointer to incomplete type
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:356: error: ‘SEEK_CUR’ undeclared (first use in this function)
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:356: error: (Each undeclared identifier is reported only once
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:356: error: for each function it appears in.)
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:357: error: ‘SEEK_END’ undeclared (first use in this function)
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c: In function ‘pci_bridge_read’:
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:386: error: dereferencing pointer to incomplete type
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:412: warning: passing argument 2 of ‘memcpy_fromio’ makes pointer from integer without a cast
    /usr/src/linux-headers-2.6.32-24-generic/arch/x86/include/asm/io_32.h:61: note: expected ‘const volatile void *’ but argument is of type ‘long unsigned int’
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c: In function ‘pci_bridge_write’:
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:448: error: dereferencing pointer to incomplete type
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:483: warning: passing argument 1 of ‘memcpy_toio’ makes pointer from integer without a cast
    /usr/src/linux-headers-2.6.32-24-generic/arch/x86/include/asm/io_32.h:67: note: expected ‘volatile void *’ but argument is of type ‘long unsigned int’
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c: In function ‘pci_bridge_ioctl’:
    /home/luis/Documents/PCIDRIVER/pci_bridge-driver.c:528: error: dereferencing pointer to incomplete type


    The code i am compiling is this one:

    Code:
    /*
     * pci_bridge-driver.c - template Linux driver for the opencores' pci bridge . Works on * kernel 2.6.x
     *
     * tested on Xubuntu, kernel 2.6.20-15-generic
     *
     *
     * Permission to use, copy, modify, and distribute this software for any
     * purpose with or without fee is hereby granted.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
     * RIGHTS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES
     * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     * OTHER DEALINGS IN THE SOFTWARE.
     */
    
    /*
     * Build/use notes (you'll probably need to be superuser to run most of
     * the steps below):
     *
     * 1) How to build the driver:
     *
     *      $ make
     *
     * 2) How to install the driver:
     *
     *      $ insmod pci_bridge-driver.ko
     *
     * TODO: change the code and use misc device and udev, so to avoid the stuff below (3-4) !!
     * 3) If pci_bridge_init_major (below) is 0, then obtain the major number:
     *
     *      $ cat /proc/devices
     *
     * Look for the line that contains the string "pci_bridge". The major
     * number is to the left.
     *
     * 4) Make the pci_bridge device special file. Substitute the major
     * number obtained above for <major_number>.
     *
     *      $ mknod /dev/pci_bridge c <major_number> 0
     *
     * 5) How to remove the driver:
     *
     *      $ rmmod pci_bridge-driver
     */
    
    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/pci.h>
    #include <linux/init.h>
    #include <linux/cdev.h>
    
    //#include <asm/byteorder.h>              /* PCI is little endian */
    #include <asm/uaccess.h>                /* copy to/from user */
    
    #include "kint.h"
    
    #define PCI_BRIDGE_DEVICE_ID 0x0001
    #define PCI_BRIDGE_VENDOR_ID 0x1895
    #define PCI_DRIVER_NAME "pci_bridge" /* driver name */
    #define BRIDGE_MEM_MAPPED 0
    #define BRIDGE_IO_MAPPED 1
    
    /*
     * PCI device IDs supported by this driver. The PCI_DEVICE macro sets
     * the vendor and device fields to its input arguments, sets subvendor
     * and subdevice to PCI_ANY_ID. It does not set the class fields.
     */
    static struct pci_device_id pci_bridge_ids[] = 
    {
    	{ PCI_DEVICE(PCI_BRIDGE_VENDOR_ID, PCI_BRIDGE_DEVICE_ID), },
    	{ 0, }
    };
    
    /*
     * For completeness, tell the module loading and hotplug systems
     * what PCI devices this module supports.
     */
    MODULE_DEVICE_TABLE(pci, pci_bridge_ids);
    
    /*
     * pci_register_driver parameter.
     */
    static int pci_bridge_probe(struct pci_dev *, const struct pci_device_id *);
    static void pci_bridge_remove(struct pci_dev *);
    
    static struct pci_driver pci_bridge_driver = 
    {
    	.name = PCI_DRIVER_NAME,
    	.id_table = pci_bridge_ids,
    	.probe = pci_bridge_probe,
    	.remove = pci_bridge_remove,
    };
    
    /*
     * File operations i/f.
     */
    int pci_bridge_open(struct inode *, struct file *);
    int pci_bridge_release(struct inode *, struct file *);
    ssize_t pci_bridge_read(struct file *, char __user *, size_t, loff_t *);
    ssize_t pci_bridge_write(struct file *, const char __user *, size_t, loff_t *);
    int pci_bridge_ioctl(struct inode *pnode, struct file *filp, unsigned int cmd, unsigned long arg);
    // seek file operation function
    loff_t  bridge_lseek(struct file *filp, loff_t offset, int origin);
    
    
    static struct file_operations pci_bridge_fops = 
    {
    	read: pci_bridge_read,
    	write: pci_bridge_write,
    	open: pci_bridge_open,
    	release: pci_bridge_release,
    	ioctl: pci_bridge_ioctl,
    	llseek: bridge_lseek
    };
    
    
    static int __init pci_bridge_init(void);
    static void __exit pci_bridge_exit(void);
    
    /*
     * Driver major number. 0 = allocate dynamically.
     */
    static int pci_bridge_init_major = 0;
    static int pci_bridge_major;
    
    /*
     * Per-device structure.
     */
    static struct pci_bridge_dev 
    {
    	struct cdev cdev;               /* Char device structure        */
    	struct pci_dev *pcidev;         /* PCI device pointer           */
    	int current_resource;
    	u32 page_addr;
    	u8 num_of_bases;
    	int base_map[6]; 
    	u32 bases[6];	
    	u32 base_size[6];
    	u32 base_page_offset;
    	u32 offset;
    } *pci_bridge_devices;
    
    
    /*
     * pci_bridge_probe - pci_driver probe function. Just enable the PCI device.
     * Could also check various configuration registers, find a specific PCI
     * device, request a specific region, etc.
     */
    static int pci_bridge_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
    {
    	struct pci_bridge_dev *dev;
    	printk("pci_bridge_probe called ...\n");
    	if(pcidev == NULL) 
    	{
            	printk(KERN_NOTICE "pci_bridge_probe: PCI DEV is NULL\n");
            	return -EINVAL;
    	}
    
    	dev = pci_bridge_devices; // only one device for now 
    	if(dev == NULL) 
    		printk("pci_bridge_probe: device structure not allocated\n");
    	else 
    	{
    		pci_enable_device(pcidev);
    		dev->pcidev = pcidev;
    	}
    
    	return 0;
    }
    
    /*
     * pci_bridge_remove - pci_driver remove function. Release allocated resources,
     * etc.
     */
    static void __devexit pci_bridge_remove(struct pci_dev *dev)
    {
        printk("pci_bridge_remove called ...\n");
    }
    
    /*
     * pci_bridge_init - module init function. By convention, the function is
     * declared static, even though it is not exported to the rest of the
     * kernel unless explicitly requested via the EXPORT_SYMBOL macro. The
     * __init qualifier tells the loader that the function is only used at
     * module initialization time.
     */
    static int __init pci_bridge_init(void)
    {
    	struct pci_bridge_dev *dev;
    	dev_t devno;
    	int result;
    	unsigned short num_of_bases;
    	u32 base_address;
    	printk("pci_bridge_init called ...\n");
    	
    	/*
    	* Allocate the per-device structure(s).
    	*/
    	pci_bridge_devices = kmalloc(sizeof(struct pci_bridge_dev), GFP_KERNEL);
    	if(pci_bridge_devices == NULL) 
    	{
    		result = -ENOMEM;
    		goto fail;
    	}
     
    	/*
    	* Get a range of minor numbers to work with, asking for a dynamic
    	* major unless directed otherwise at load time.
    	*/
    	if(pci_bridge_init_major) 
    	{
    		pci_bridge_major = pci_bridge_init_major;
    		devno = MKDEV(pci_bridge_major, 0);
    		result = register_chrdev_region(devno, 1, PCI_DRIVER_NAME);
    	} 
    	else 
    	{
    		result = alloc_chrdev_region(&devno, 0, 1, PCI_DRIVER_NAME);
    		pci_bridge_major = MAJOR(devno);
    	}
    	if(result < 0) 
    	{
    		printk(KERN_NOTICE "pci_bridge: can't get major %d\n", pci_bridge_major);
    		goto fail;
    	}
    
    	dev = pci_bridge_devices;/* only one device for now */
    
    	/*
    	* Initialize and add this device's character device table entry.
    	*/
    	dev->pcidev = NULL; 
    	cdev_init(&dev->cdev, &pci_bridge_fops);
    	dev->cdev.owner = THIS_MODULE;
    	dev->cdev.ops = &pci_bridge_fops;
    	dev->offset = 0;
    	result = cdev_add(&dev->cdev, devno, 1);
    	if(result) 
    	{
    		printk(KERN_NOTICE "Error %d adding %s device", result, PCI_DRIVER_NAME);
    		goto fail;
    	}
    	
    	if((result = pci_register_driver(&pci_bridge_driver)) != 0) 
    	{
    		printk(KERN_NOTICE "Error %d registering %s PCI device",result, PCI_DRIVER_NAME);
    		goto fail;
    	}
    	
    	if(dev->pcidev == NULL) 
    	{
    		printk(KERN_NOTICE "PCI DEV is NULL, probe failed?\n");
    		goto fail;
    	}
    
    	base_address = pci_resource_start(dev->pcidev, 0);
    
    	printk("<1> First base address register found at %08X \n ",  pci_resource_start(dev->pcidev, 0)); 
    	num_of_bases = 0;
    
    	while
    	((base_address = pci_resource_start(dev->pcidev, num_of_bases))!= 0x00000000 && (num_of_bases < 6))
    	{
    		unsigned long flags;
    		flags = pci_resource_flags(dev->pcidev, num_of_bases);
    		dev->bases[num_of_bases] = base_address;
    		dev->base_size[num_of_bases] = pci_resource_end(dev->pcidev, num_of_bases) - base_address + 1;
    		// check if resource is IO mapped
    		if (flags & IORESOURCE_IO)
    		    dev->base_map[num_of_bases] = BRIDGE_IO_MAPPED;
    		else
    		    dev->base_map[num_of_bases] = BRIDGE_MEM_MAPPED;	
    		num_of_bases++;
    	}
    
    	if (num_of_bases < 1)
    		printk("<1>No implemented base address registers found! \n ");
    
    	dev->current_resource = - 1;
    
    	// store number of bases in structure
    	dev->num_of_bases = num_of_bases;
    	printk("num_of_bases found %d \n", num_of_bases);
    	// display information about all base addresses found in this procedure
    	for (num_of_bases = 0; num_of_bases < dev->num_of_bases; num_of_bases++)
    	{
    		printk("<1>BAR%d range from %08X to %08X \n ", num_of_bases, dev->bases[num_of_bases], dev->bases[num_of_bases] + dev->base_size[num_of_bases]); 
    	}
    
    	return 0;
    	
    fail: 
    		pci_bridge_exit(); 
    		return result;
    }
    
    /*
     * pci_bridge_exit - module exit function. Release resources allocated
     * by pci_bridge_init.
     */
    static void __exit pci_bridge_exit(void)
    {
    	printk("pci_bridge_exit called ...\n");
    	if(pci_bridge_devices) 
    	{
    		struct pci_bridge_dev *dev;
    		dev = &pci_bridge_devices[0];
    		cdev_del(&dev->cdev);
    		kfree(pci_bridge_devices);
    		pci_bridge_devices = NULL;
    	}
    	unregister_chrdev_region(MKDEV(pci_bridge_major, 0), 1);
    	pci_bridge_major = 0;
    	pci_unregister_driver(&pci_bridge_driver);
    }
    
    /*
     * pci_bridge_open - open file processing.
     */
    int pci_bridge_open(struct inode *inode, struct file *filep)
    {
    	struct pci_bridge_dev *dev;
    	dev = container_of(inode->i_cdev, struct pci_bridge_dev, cdev);
    	filep->private_data = dev; // used by read, write, etc 
    	dev->current_resource = -1;
    	/* Success */
    	return 0;
    }
    
    /*
     * pci_bridge_release - close processing.
     */
    int pci_bridge_release(struct inode *inode, struct file *filep)
    {
    	/* Success */
    	return 0;
    }
    
    /*
     * seek file operation function
     */
    loff_t  bridge_lseek(struct file *filp, loff_t offset, int origin)
    {
    	struct pci_bridge_dev *dev;
    	loff_t requested_offset;
    	int resource_num;
    
    	dev = filp->private_data;
    	resource_num = dev->current_resource;
    	switch (origin)
    	{
    		case SEEK_CUR:requested_offset = dev->offset + offset; break;
    		case SEEK_END:requested_offset = dev->base_size[resource_num] + offset; break;
    		default:requested_offset  = offset; break;
    	}
    	
    	if ((requested_offset < 0) || (requested_offset > dev->base_size[resource_num]))
    		return -EFAULT;
    
    	dev->offset = requested_offset;
    	return requested_offset; 				 
    }
    
    
    /*
     * pci_bridge_read - read processing.
     */
    ssize_t pci_bridge_read (struct file *filp, char *buf, size_t count, loff_t *offset_out ) 
    {
    	struct pci_bridge_dev *dev;		
    	unsigned long current_address;
    	unsigned long actual_count;
    	unsigned long offset;
    	int resource_num;
    	int i;
    	unsigned int value;
            unsigned int *kern_buf;
            unsigned int *kern_buf_tmp;
    	unsigned long size;
    	int result;
    
    	dev = filp->private_data;
    	offset = dev->offset;
    	resource_num = dev->current_resource;
    	size   = dev->base_size[resource_num];
    	current_address = dev->page_addr + dev->base_page_offset + dev->offset;
    
    	if (dev->current_resource < 0)
    		return -ENODEV;
    	
    	if (offset == size)
    		return 0;
     
    	if ( (offset + count) > size )
    		actual_count = size - offset;
    	else
    		actual_count = count;
     
    	// verify range if it is OK to copy from
    	if ((result = access_ok(VERIFY_WRITE, buf, actual_count)) ==0)
    		return result;
     
    	kern_buf = kmalloc(actual_count, GFP_KERNEL | GFP_DMA);
    	kern_buf_tmp = kern_buf;
    	if (kern_buf <= 0)
    		return 0;
    
        	memcpy_fromio(kern_buf, current_address, actual_count);
    	i = actual_count/4;
    	while(i--) 
    	{
    //		value = readl(current_address);	
    		value = *(kern_buf);
    		put_user(value, ((unsigned int *)buf));	
    		buf += 4;
    		++kern_buf;
    //		current_address += 4;
    	}
    
    	kfree(kern_buf_tmp);
    	dev->offset = dev->offset + actual_count;
    	*(offset_out) = dev->offset;
    
    	return actual_count;  
     }	
    
    /*
     * pci_bridge_write - write processing.
     */
    ssize_t pci_bridge_write (struct file *filp, const char *buf, size_t count, loff_t *offset_out) 
    {
    	struct pci_bridge_dev *dev;
    	unsigned long current_address;
    	unsigned long actual_count;
    	unsigned long offset;
    	int resource_num;
     	int i;
    	int value;
    	unsigned long size;
    	int result;
    	int *kern_buf;
    	int *kern_buf_tmp;
    
        	dev = filp->private_data;
    	current_address = dev->page_addr + dev->base_page_offset + dev->offset;
    	resource_num = dev->current_resource;
    	size  = dev->base_size[resource_num];
    	offset = dev->offset;
     
    	if (dev->current_resource < 0)
    		return -ENODEV;
    
    	if (offset == size)
    		return 0;
     
    	if ( (offset + count) > size )
    		actual_count = size - offset;
    	else
    		actual_count = count;
     
    	// verify range if it is OK to copy from
    	if ((result = access_ok(VERIFY_READ, buf, actual_count)) == 0)
    		return result;
    	kern_buf = kmalloc(actual_count, GFP_KERNEL | GFP_DMA);
    	kern_buf_tmp = kern_buf;
    	if (kern_buf <= 0)
    		return 0;
    	i = actual_count/4;
    	while(i--) 
    	{
    		get_user(value, ((int *)buf));
    		//writel(value, current_address);
    		*kern_buf = value;
    		buf += 4;
    		//current_address += 4;
    		++kern_buf;
    	}
    
    	memcpy_toio(current_address, kern_buf_tmp, actual_count);
    	kfree(kern_buf_tmp);
    	dev->offset = dev->offset + actual_count;
    	*(offset_out) = dev->offset;
     
    	return actual_count; 
    }
    
    /*
     * helper function for memory remaping
     */
    int open_mem_mapped(struct pci_bridge_dev *dev)
    {
    	int resource_num = dev->current_resource;
    	unsigned long num_of_pages = 0;
    	unsigned long base = dev->bases[resource_num];
    	unsigned long size = dev->base_size[resource_num];
    	//printk("\n current resource=%d , size = %d, base=%08X", dev->current_resource , size, dev->bases[resource_num]);
    	if (!(num_of_pages = (unsigned long)(size/PAGE_SIZE)));
    		num_of_pages++;
    
    	dev->base_page_offset = base & ~PAGE_MASK;
    
    	if ((dev->base_page_offset + size) < (num_of_pages*PAGE_SIZE)) 
    		num_of_pages++;
    	
    	// remap memory mapped space
    	dev->page_addr = (unsigned long)ioremap(base & PAGE_MASK, num_of_pages * PAGE_SIZE);
    	
    	if (dev->page_addr == 0x00000000)
    		return -ENOMEM;
    	
    	return 0;
    }
    
    /*
     * ioctl: see kint.h for the meaning of args 
     */
    int pci_bridge_ioctl(struct inode *pnode, struct file *filp, unsigned int cmd, unsigned long arg) 
    {
    
    	int error = 0;
    	unsigned long base;
    	unsigned long base_size;
    	struct pci_bridge_dev *dev;
    	dev = filp->private_data;
    
    	if (_IOC_TYPE(cmd) != BRIDGE_IOC_NUM) return -EINVAL;
    	if (_IOC_NR(cmd) > BRIDGE_IOC_MAX_NUM) return -EINVAL;
    
    	switch (cmd)
    	{
    		case BRIDGE_IOC_CURRESGET:
    			// current resource - they start at 1
    			return (dev->current_resource + 1);  
    		
    		case BRIDGE_IOC_CURRESSET:
    			// check if resource is in a range of implemented resources
    			if (arg < 0 )
    				return -EINVAL;
    
    			// unmap previous resource if it was mapped
    			if (dev->current_resource >= 0)
    			{
    				iounmap((void *)dev->page_addr);
    			}	
    
    			if (arg == 0)
    			{
    				// previous resource unmaped - that's all
    				dev->current_resource = -1;
    				return 0;	
    			}
    
    			if (dev->num_of_bases < arg)
    				return -ENODEV;
    
    			// IO mapped not supported yet
    			if (dev->base_map[arg-1] == BRIDGE_IO_MAPPED)
    			{
    				// set current resource to none, since it was unmapped
    				dev->current_resource = -1;
    				return -ENODEV;
    			}
    			dev->current_resource= (int)(arg-1);
    			// remap new resource
    			if ( (error = open_mem_mapped(dev)) )
    			{
    				dev->current_resource = -1;
    				return error;
    			}
    			return 0;
    
    		case BRIDGE_IOC_CURBASE:
    			// check if any resource is currently activated
    			if (dev->current_resource>=0)
    			{
    				base = dev->bases[dev->current_resource];
    				printk("\n CURR_RES = %d",dev->current_resource );
    			}
    			else
    				base = 0x00000000;
    			
    			*(unsigned long *)arg = base;
    			return 0;
    
    		case BRIDGE_IOC_CURBASEMAP:
    			// check if any resource is currently activated
    			if (dev->current_resource>=0)
    				base = dev->page_addr;
    			else
    				base = 0x00000000;
    	
    			*(unsigned long *)arg = base;
    
    			return 0;
    
    		case BRIDGE_IOC_CURBASESIZE:	
    			// check if any resource is currently activated
    			if (dev->current_resource>=0)
    				base_size = dev->base_size[dev->current_resource];
    			else
    				base_size = 0x00000000;
    			
    			*(unsigned long *)arg = base_size;
    			return 0;
    
    		case BRIDGE_IOC_NUMOFRES:	
    			return (dev->num_of_bases);
    
    		default:
    			return -EINVAL;
    		
    	}
    
    }
    
    MODULE_LICENSE("GPL");
    
    module_init(pci_bridge_init);
    module_exit(pci_bridge_exit);
    The kint.h :

    Code:
    #include <asm-generic/ioctl.h>
    
    #define BRIDGE_IOC_NUM 'S'
    #define BRIDGE_IOC_MAX_NUM 11
    #define BRIDGE_IOC_CURRESGET    _IO(BRIDGE_IOC_NUM, 1)            // read current resource - (0 = none)
    #define BRIDGE_IOC_CURRESSET    _IO(BRIDGE_IOC_NUM, 2)            // set current resource
    #define BRIDGE_IOC_CURBASE      _IOR_BAD(BRIDGE_IOC_NUM, 3, base)     // read current resource base address
    #define BRIDGE_IOC_CURBASEMAP   _IOR_BAD(BRIDGE_IOC_NUM, 4, base)     // read current resource remaped base address ( 0 - not remaped)
    #define BRIDGE_IOC_CURBASESIZE  _IOR_BAD(BRIDGE_IOC_NUM, 5, base_size)// read current resource size
    #define BRIDGE_IOC_NUMOFRES     _IO(BRIDGE_IOC_NUM, 6)            // read number of found resources
    
    #define BRIDGE_P_IMG_CTRL1_ADDR	0x110
    #define BRIDGE_P_BA1_ADDR		0x114
    #define BRIDGE_P_AM1_ADDR		0x118
    #define BRIDGE_P_TA1_ADDR		0x11c
    
    #define BRIDGE_W_IMG_CTRL1_ADDR        0x184
    #define BRIDGE_W_BA1_ADDR              0x188
    #define BRIDGE_W_AM1_ADDR              0x18C
    #define BRIDGE_W_TA1_ADDR              0x190
    Any one have any idea how to solve this problem?

    I was able to build a module i did myself with no fops.

    Thank you

  2. #2
    Just Joined!
    Join Date
    May 2010
    Posts
    11
    Ok dumb mistake, forgot to include linux/fs.h. Sorry for not making homework hehe.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •