From 631f0929c155087648acdd00ef0e2039737f8803 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Sun, 28 Feb 2016 14:50:47 +0100 Subject: Support emulation mode without real hardware --- driver/base.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 14 deletions(-) (limited to 'driver/base.c') diff --git a/driver/base.c b/driver/base.c index bc9ab98..4e55dda 100644 --- a/driver/base.c +++ b/driver/base.c @@ -210,6 +210,10 @@ MODULE_LICENSE("GPL v2"); /* Module class */ static struct class_compat *pcidriver_class; +#ifdef PCIDRIVER_DUMMY_DEVICE +pcidriver_privdata_t *pcidriver_privdata = NULL; +#endif /* PCIDRIVER_DUMMY_DEVICE */ + /** * * Called when loading the driver @@ -217,7 +221,7 @@ static struct class_compat *pcidriver_class; */ static int __init pcidriver_init(void) { - int err; + int err = 0; /* Initialize the device count */ atomic_set(&pcidriver_deviceCount, 0); @@ -239,7 +243,11 @@ static int __init pcidriver_init(void) /* Register PCI driver. This function returns the number of devices on some * systems, therefore check for errors as < 0. */ +#ifdef PCIDRIVER_DUMMY_DEVICE + if ((err = pcidriver_probe(NULL, NULL)) < 0) { +#else /* PCIDRIVER_DUMMY_DEVICE */ if ((err = pci_register_driver(&pcidriver_driver)) < 0) { +#endif /* PCIDRIVER_DUMMY_DEVICE */ mod_info("Couldn't register PCI driver. Module not loaded.\n"); goto init_pcireg_fail; } @@ -268,7 +276,12 @@ init_alloc_fail: */ static void pcidriver_exit(void) { +#ifdef PCIDRIVER_DUMMY_DEVICE + pcidriver_remove(NULL); +#else pci_unregister_driver(&pcidriver_driver); +#endif /* PCIDRIVER_DUMMY_DEVICE */ + unregister_chrdev_region(pcidriver_devt, MAXDEVICES); if (pcidriver_class != NULL) @@ -286,12 +299,14 @@ static void pcidriver_exit(void) * Will be registered at module init. * */ +#ifndef PCIDRIVER_DUMMY_DEVICE static struct pci_driver pcidriver_driver = { .name = MODNAME, .id_table = pcidriver_ids, .probe = pcidriver_probe, .remove = pcidriver_remove, }; +#endif /* ! PCIDRIVER_DUMMY_DEVICE */ /** * @@ -301,7 +316,7 @@ static struct pci_driver pcidriver_driver = { */ static int __devinit pcidriver_probe(struct pci_dev *pdev, const struct pci_device_id *id) { - int err; + int err = 0; int devno; pcidriver_privdata_t *privdata; int devid; @@ -311,6 +326,9 @@ static int __devinit pcidriver_probe(struct pci_dev *pdev, const struct pci_devi * * However, there is some difference in the interrupt handling functions. */ +#ifdef PCIDRIVER_DUMMY_DEVICE + mod_info("Emulated device\n"); +#else /* PCIDRIVER_DUMMY_DEVICE */ if (id->vendor == PCIE_XILINX_VENDOR_ID) { if (id->device == PCIE_ML605_DEVICE_ID) { mod_info("Found ML605 board at %s\n", dev_name(&pdev->dev)); @@ -323,7 +341,7 @@ static int __devinit pcidriver_probe(struct pci_dev *pdev, const struct pci_devi } } else { /* It is something else */ - mod_info( "Found unknown board (%x:%x) at %s\n", id->vendor, id->device, dev_name(&pdev->dev)); + mod_info("Found unknown board (%x:%x) at %s\n", id->vendor, id->device, dev_name(&pdev->dev)); } /* Enable the device */ @@ -343,7 +361,8 @@ static int __devinit pcidriver_probe(struct pci_dev *pdev, const struct pci_devi /* Set Memory-Write-Invalidate support */ if ((err = pci_set_mwi(pdev)) != 0) - mod_info("MWI not supported. Continue without enabling MWI.\n"); + mod_info("MWI not supported. Continue without enabling MWI.\n"); +#endif /* PCIDRIVER_DUMMY_DEVICE */ /* Get / Increment the device id */ devid = atomic_inc_return(&pcidriver_deviceCount) - 1; @@ -367,22 +386,31 @@ static int __devinit pcidriver_probe(struct pci_dev *pdev, const struct pci_devi spin_lock_init(&(privdata->umemlist_lock)); atomic_set(&privdata->umem_count, 0); - pci_set_drvdata( pdev, privdata ); +#ifdef PCIDRIVER_DUMMY_DEVICE + pcidriver_privdata = privdata; +#else /* PCIDRIVER_DUMMY_DEVICE */ + pci_set_drvdata(pdev, privdata); privdata->pdev = pdev; +#endif /* PCIDRIVER_DUMMY_DEVICE */ /* Device add to sysfs */ devno = MKDEV(MAJOR(pcidriver_devt), MINOR(pcidriver_devt) + devid); privdata->devno = devno; - if (pcidriver_class != NULL) { - /* FIXME: some error checking missing here */ - privdata->class_dev = class_device_create(pcidriver_class, NULL, devno, &(pdev->dev), NODENAMEFMT, MINOR(pcidriver_devt) + devid, privdata); - class_set_devdata( privdata->class_dev, privdata ); - mod_info("Device /dev/%s%d added\n",NODENAME,MINOR(pcidriver_devt) + devid); - } + /* FIXME: some error checking missing here */ +#ifdef PCIDRIVER_DUMMY_DEVICE + privdata->class_dev = class_device_create(pcidriver_class, NULL, devno, NULL, NODENAMEFMT, MINOR(pcidriver_devt) + devid, privdata); +#else /* PCIDRIVER_DUMMY_DEVICE */ + privdata->class_dev = class_device_create(pcidriver_class, NULL, devno, &(pdev->dev), NODENAMEFMT, MINOR(pcidriver_devt) + devid, privdata); +#endif /* PCIDRIVER_DUMMY_DEVICE */ + class_set_devdata( privdata->class_dev, privdata ); + mod_info("Device /dev/%s%d added\n",NODENAME,MINOR(pcidriver_devt) + devid); + +#ifndef PCIDRIVER_DUMMY_DEVICE /* Setup mmaped BARs into kernel space */ if ((err = pcidriver_probe_irq(privdata)) != 0) goto probe_irq_probe_fail; +#endif /* ! PCIDRIVER_DUMMY_DEVICE */ /* Populate sysfs attributes for the class device */ /* TODO: correct errorhandling. ewww. must remove the files in reversed order :-( */ @@ -419,15 +447,19 @@ static int __devinit pcidriver_probe(struct pci_dev *pdev, const struct pci_devi probe_device_create_fail: probe_cdevadd_fail: +#ifndef PCIDRIVER_DUMMY_DEVICE probe_irq_probe_fail: pcidriver_irq_unmap_bars(privdata); +#endif /* ! PCIDRIVER_DUMMY_DEVICE */ kfree(privdata); probe_nomem: atomic_dec(&pcidriver_deviceCount); probe_maxdevices_fail: +#ifndef PCIDRIVER_DUMMY_DEVICE probe_dma_fail: pci_disable_device(pdev); probe_pcien_fail: +#endif /* ! PCIDRIVER_DUMMY_DEVICE */ return err; } @@ -440,8 +472,13 @@ static void __devexit pcidriver_remove(struct pci_dev *pdev) { pcidriver_privdata_t *privdata; +#ifdef PCIDRIVER_DUMMY_DEVICE + privdata = pcidriver_privdata; + pcidriver_privdata = NULL; +#else /* PCIDRIVER_DUMMY_DEVICE */ /* Get private data from the device */ privdata = pci_get_drvdata(pdev); +#endif /* PCIDRIVER_DUMMY_DEVICE */ /* Removing sysfs attributes from class device */ #define sysfs_attr(name) do { \ @@ -465,9 +502,11 @@ static void __devexit pcidriver_remove(struct pci_dev *pdev) /* Free all allocated kmem buffers before leaving */ pcidriver_kmem_free_all( privdata ); -#ifdef ENABLE_IRQ +#ifndef PCIDRIVER_DUMMY_DEVICE +# ifdef ENABLE_IRQ pcidriver_remove_irq(privdata); -#endif +# endif +#endif /* ! PCIDRIVER_DUMMY_DEVICE */ /* Removing Character device */ cdev_del(&(privdata->cdev)); @@ -478,10 +517,14 @@ static void __devexit pcidriver_remove(struct pci_dev *pdev) /* Releasing privdata */ kfree(privdata); +#ifdef PCIDRIVER_DUMMY_DEVICE + mod_info("Device at " NODENAMEFMT " removed\n", 0); +#else /* PCIDRIVER_DUMMY_DEVICE */ /* Disabling PCI device */ pci_disable_device(pdev); - mod_info("Device at %s removed\n", dev_name(&pdev->dev)); +#endif /* PCIDRIVER_DUMMY_DEVICE */ + } /*************************************************************************/ @@ -613,6 +656,9 @@ int pcidriver_mmap(struct file *filp, struct vm_area_struct *vma) /* Internal driver functions */ int pcidriver_mmap_pci(pcidriver_privdata_t *privdata, struct vm_area_struct *vmap, int bar) { +#ifdef PCIDRIVER_DUMMY_DEVICE + return -ENXIO; +#else /* PCIDRIVER_DUMMY_DEVICE */ int ret = 0; unsigned long bar_addr; unsigned long bar_length, vma_size; @@ -620,6 +666,7 @@ int pcidriver_mmap_pci(pcidriver_privdata_t *privdata, struct vm_area_struct *vm mod_info_dbg("Entering mmap_pci\n"); + /* Get info of the BAR to be mapped */ bar_addr = pci_resource_start(privdata->pdev, bar); bar_length = pci_resource_len(privdata->pdev, bar); @@ -680,4 +727,5 @@ int pcidriver_mmap_pci(pcidriver_privdata_t *privdata, struct vm_area_struct *vm } return 0; /* success */ +#endif /* PCIDRIVER_DUMMY_DEVICE */ } -- cgit v1.2.3