pci_request_regions erring out

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi All,

 I am currently working on the realtek driver available in http://linuxgazette.net/156/jangir.html.

 When I run the driver, pci_request_regions is erring out as :
Device enabled
----------------------------------------------------------------
Base 0  Starting Address = 9c00 End Address = 9cff  Length = 256
This Port is I/O mapped. It is NON Prefetchable.This is readable and writable.
Base 0 starting Address = 9c00  End Address = 9cff Length = 256 resource is not available
Base 1  Starting Address = fdaff000 End Address = fdaff0ff  Length = 256
This Port is Memory mapped. It is NON Prefetchable. This is readable and writable.
Reading the PCI BAR registers
Checking the PCI BAR registers for Memory mapped flag
Calling pci_request_region
8139too 0000:04:03.0: BAR 0: can't reserve I/O region [0x9c00-0x9cff]
Could not get PCI region
sys_init_module: 'real3'->init suspiciously returned 1, it should follow 0/-E convention
sys_init_module: loading module anyway...

I am attaching the driver code. Any clues as to why?

Thanks & Regards,
D.Giriprasad
#define REALTEK_VENDER_ID  0x10EC
#define REALTEK_DEVICE_ID   0x8139

//#define REALTEK_VENDER_ID 0x10b5 
//#define REALTEK_DEVICE_ID  0x9050 

//#define VENDOR_ID 0x10b5
//#define DEVICE_ID 0x9050

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/stddef.h>
#include <linux/pci.h>
#include <linux/etherdevice.h>

int print_pci(struct pci_dev *pdev);

struct rtl8139_private 
{
        struct pci_dev *pci_dev;  /* PCI device */
        void *mmio_addr; /* memory mapped I/O addr */
        unsigned long regs_len; /* length of I/O or MMI/O region */
};


static struct pci_dev* probe_for_realtek8139(void) 
{
        struct pci_dev *pdev = NULL;
        /* Ensure we are not working on a non-PCI system */
        //if(!pci_present( )) {
        //       printk("<1>pci not present\n");
        //       return pdev;
        //}
        //else
        //        printk("<1>pci device is present\n");

        /* Look for RealTek 8139 NIC */
        pdev = pci_find_device(REALTEK_VENDER_ID, REALTEK_DEVICE_ID, NULL);
        if(pdev) {
               printk("Found PCI device with vendorid = %x deviceid = %x\n", REALTEK_VENDER_ID, REALTEK_DEVICE_ID);
               /* device found, enable it */
               if(pci_enable_device(pdev)) {
                        printk("Could not enable the device\n");
                       return NULL;
               }
               else
                        printk("Device enabled\n");
        }
        else {
                printk("device not found\n");
               return pdev;
        }
        return pdev;
}


#define DRIVER "rtl8139"
static struct net_device *rtl8139_dev;

static int rtl8139_init(struct pci_dev *pdev, struct net_device **dev_out) 
{
        struct net_device *dev;
        struct rtl8139_private *tp;

        /* 
         * alloc_etherdev allocates memory for dev and dev->priv.
         * dev->priv shall have sizeof(struct rtl8139_private) memory
         * allocated.
         */
        dev = alloc_etherdev(sizeof(struct rtl8139_private));
        if(!dev) {
                printk("Could not allocate etherdev\n");
               return -1;
        }

        tp = dev->priv;
        tp->pci_dev = pdev;
        *dev_out = dev;

        return 0;
}

static int rtl8139_open(struct net_device *dev) 
{  
   printk("rtl8139_open is called\n"); 
   return 0; 
}

static int rtl8139_stop(struct net_device *dev) 
{
         printk("rtl8139_open is called\n");
        return 0;
}

static int rtl8139_start_xmit(struct sk_buff *skb, struct net_device *dev) 
{
         printk("rtl8139_start_xmit is called\n");
        return 0;
}

static struct net_device_stats* rtl8139_get_stats(struct net_device *dev) 
{
         printk("rtl8139_get_stats is called\n");
        return 0;
}

int init_module(void) 
{
        struct pci_dev *pdev;
        unsigned long mmio_start, mmio_end, mmio_len, mmio_flags;
        void *ioaddr;
        struct rtl8139_private *tp;
        int i, err = 0;

        pdev = probe_for_realtek8139( );
        if(!pdev)
               return 0;

        print_pci(pdev);
        if(rtl8139_init(pdev, &rtl8139_dev)) {
                printk("Could not initialize device\n");
               return 0;
        }

        tp = rtl8139_dev->priv; // rtl8139 private information 
        
        printk("Reading the PCI BAR registers \n");
        // get PCI memory mapped I/O space base address from BAR1 
        mmio_start = pci_resource_start(pdev, 1);
        mmio_end = pci_resource_end(pdev, 1);
        mmio_len = pci_resource_len(pdev, 1);
        mmio_flags = pci_resource_flags(pdev, 1);

        printk("Checking the PCI BAR registers for Memory mapped flag \n");
        // make sure above region is MMI/O 
        if(!(mmio_flags & IORESOURCE_MEM)) {
                printk("region not MMI/O region\n");
               goto cleanup1;
        }
        else
                printk("region is Memory mapped region\n");
        
        printk("Calling pci_request_region \n");
        // get PCI memory space 
        if(pci_request_regions(pdev, DRIVER)) {
                printk("Could not get PCI region\n");
               goto cleanup1;
        }

        printk("Calling pci_set_master\n");
        pci_set_master(pdev);

        printk("Calling ioremap\n");
        // ioremap MMI/O region 
        ioaddr = ioremap(mmio_start, mmio_len);
        if(!ioaddr) {
                printk("Could not ioremap\n");
               goto cleanup2;
        }

        printk("Assigning ioaddress and length \n");
        rtl8139_dev->base_addr = (long)ioaddr;
        tp->mmio_addr = ioaddr;
        tp->regs_len = mmio_len;

        // UPDATE NET_DEVICE 

        printk("Assigning hardware address \n");
        for(i = 0; i < 6; i++) {  // Hardware Address 
               rtl8139_dev->dev_addr[i] = readb(rtl8139_dev->base_addr+i);
               rtl8139_dev->broadcast[i] = 0xff;
        }
        rtl8139_dev->hard_header_len = 14;

        printk("Assigning function address \n");
        memcpy(rtl8139_dev->name, DRIVER, sizeof(DRIVER)); // Device Name 
        rtl8139_dev->irq = pdev->irq;  // Interrupt Number 
        rtl8139_dev->open = rtl8139_open;
        rtl8139_dev->stop = rtl8139_stop;
        rtl8139_dev->hard_start_xmit = rtl8139_start_xmit;
        rtl8139_dev->get_stats = rtl8139_get_stats;

        printk("Calling register_netdev \n");
        // register the device 
        if(register_netdev(rtl8139_dev)) {
                printk("Could not register netdevice\n");
               goto cleanup0;
        }

cleanup0:
        unregister_netdev(rtl8139_dev);
        err = 1;
cleanup2:
        iounmap(tp->mmio_addr);
        err = 1;
cleanup1:
        pci_release_regions(tp->pci_dev);
        err = 1;

        return err;
}
               


void cleanup_module(void) 
{
        struct rtl8139_private *tp;
        tp = rtl8139_dev->priv;

        iounmap(tp->mmio_addr);
        pci_release_regions(tp->pci_dev);

        unregister_netdev(rtl8139_dev);
        pci_disable_device(tp->pci_dev);
        return;
}




// Should be called after pci_find_device and pci_enable_device have been called

int print_pci(struct pci_dev *dev)
{
	int i;
	int start, end, length, resflags;

	for (i = 0; i < 6; i++)
	{
		start = pci_resource_start (dev, i);
		if (!start)
			continue;
		end = pci_resource_end (dev, i);
		length = pci_resource_len (dev, i);
		resflags = pci_resource_flags (dev, i);

		if (resflags & IORESOURCE_IO)
		{
			printk("----------------------------------------------------------------\n");
			printk("Base %d  Starting Address = %x End Address = %x  Length = %d\n",i, start, end, length);
			printk ("This Port is I/O mapped. ");
			if (resflags & IORESOURCE_PREFETCH)
				printk ("It is Prefetchable.");
			else
				printk ("It is NON Prefetchable.");

			if (resflags & IORESOURCE_READONLY)
				printk ("This is read only.\n");
			else
				printk ("This is readable and writable.\n");

			if (check_region (start, length) < 0)
		   		printk
				("Base %d starting Address = %x  End Address = %x Length = %d resource is not available \n",
					i, start, end, length);
	  		//else if (request_region (start, length, DRIVER_NAME) < 0)
		//		 printk ("The Resource is not allocated for BAR %d\n", i);
		//	else
		//		printk ("The Resource is allocated for BAR %d\n", i);
		}
		else
		{
			if (resflags & IORESOURCE_MEM)
			{
				printk
				("Base %d  Starting Address = %x End Address = %x  Length = %d\n",i, start, end, length);
				printk ("This Port is Memory mapped. ");
				if (resflags & IORESOURCE_PREFETCH)
					printk ("It is Prefetchable. ");
				else
					printk ("It is NON Prefetchable. ");

				if (resflags & IORESOURCE_READONLY)
					printk ("It is read only.\n");
				else
					printk ("This is readable and writable.\n");
				if (check_mem_region (start, length) < 0)
				 printk
				 ("Base %d starting Address = %x  End Address = %x Length = %d resource is not available \n",
		     			i, start, end, length);
				else
				{
					//if (request_mem_region (start, length, DRIVER_NAME) < 0)
					//	printk("The Resource is not allocated for BAR %d\n", i);
			  		//else
					//	printk ("The Resource is allocated for BAR %d\n", i);
				}
			}
		}
    	}
	

	return 0;
}


_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux