paep.c

来自「这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自」· C语言 代码 · 共 1,171 行 · 第 1/3 页

C
1,171
字号
		dev_param_p->flags |= READ_DATA_AVAILABLE;  		/*Post the semaphore controlling reads to the device*/		up(&dev_param_p->read_sem);		wake_up_interruptible(&dev_param_p->select_wq);        }        if (status & DMA_WRITE_COMPLETE) {                acknowledge_irq(DMA_WRITE_COMPLETE, dev_p);        #ifdef INSTRUMENT                ++dev_param_p->DMA_WRITE_COMPLETE_int_cnt;#endif/*INSTRUMENT*/                        dev_param_p->write_state = WS_DMA_COMPLETE;                wake_up_interruptible(&dev_param_p->wq);        }        if (status & DMA_WRITE_NO_SPACE) {                acknowledge_irq(DMA_WRITE_NO_SPACE, dev_p);        #ifdef INSTRUMENT                ++dev_param_p->DMA_WRITE_NO_SPACE_int_cnt;#endif/*INSTRUMENT*/                dev_param_p->write_fail_reason = DMA_WRITE_NO_SPACE;                wake_up_interruptible(&dev_param_p->wq);        }        if (status & DMA_WRITE_ERROR) {                acknowledge_irq(DMA_WRITE_ERROR, dev_p);#ifdef INSTRUMENT                ++dev_param_p->DMA_WRITE_ERROR_int_cnt;#endif/*INSTRUMENT*/                dev_param_p->write_fail_reason = DMA_WRITE_ERROR;                wake_up_interruptible(&dev_param_p->wq);             }        if (status & DMA_READ_COMPLETE) {                acknowledge_irq(DMA_READ_COMPLETE, dev_p);#ifdef INSTRUMENT                ++dev_param_p->DMA_READ_COMPLETE_int_cnt;#endif/*INSTRUMENT*/                    /* save how many didn't get transferred */                dev_param_p->read_residual = read_mailbox_status(dev_p);                dev_param_p->read_state = RS_DMA_COMPLETE;                wake_up_interruptible(&dev_param_p->rq);               }        if (status & DMA_READ_ERROR) {                acknowledge_irq(DMA_READ_ERROR, dev_p);#ifdef INSTRUMENT                ++dev_param_p->DMA_READ_ERROR_int_cnt;#endif/* INSTRUMENT */                wake_up_interruptible(&dev_param_p->rq);              }        return;}/* *  Module Initialization (find it on the PCI bus) */static int __init aep_init_module(void) {        int count;        BANNER();        printk("%s%s%s%s\n", aep_version_str, DRIVER_VERSION, " Build Date: ", __DATE__);        DPRINTK("AEP_MAXCARDS_NB = %d\n", AEP_MAXCARDS_NB);        dev_list_pp = NULL;        dma_buff_order = get_order(AEP_DMA_BUFFER_SIZE);           DPRINTK("dma_buff_order = %d\n", dma_buff_order);        DPRINTK("allocating pointer list\n");            dev_list_pp = (struct pci_dev **) kmalloc(AEP_MAXCARDS_NB * sizeof(struct pci_dev*), GFP_KERNEL);        DPRINTK("dev_list_pp = 0x%p\n", dev_list_pp);        if (!dev_list_pp) {                        ERR_PRINTK("Pointer list allocation failed (returning -ENOMEM)\n");                return -ENOMEM;        }            for (count = 0; count < AEP_MAXCARDS_NB; count++){                DPRINTK("zeroing pointer for card %d\n", count);                dev_list_pp[count] = NULL;        }        if (pci_present()){                if (pci_register_driver(&aep_driver) <= 0) {                        ERR_PRINTK("no devices (returning -ENODEV)\n");                        pci_unregister_driver(&aep_driver);                        return -ENODEV;                }        }            DPRINTK("returning\n");        return 0;}static void __exit aep_cleanup_module(void) {        DPRINTK("unregistering driver\n");        pci_unregister_driver(&aep_driver);            nb_cards = 0;        DPRINTK("freeing list of pointers 0x%p\n", dev_list_pp);        kfree(dev_list_pp);        dev_list_pp = NULL;}    /* setup data for one AEP card,   NOTE: pci_device_id can be used in the future if different   initialisation methods are required for different chipsets */static int __devinit aep_init_one_device (struct pci_dev *dev_p,                                          const struct pci_device_id *unused_p){        paep_unit_info_t *dev_param_p;            unsigned long bar1;        unsigned long bar3;        int major,result;           assert(dev_p);            BANNER();            exit_if_too_many_cards(nb_cards);        DPRINTK("allocating unit info struct\n");        dev_param_p = (paep_unit_info_t *) kmalloc(sizeof(paep_unit_info_t), GFP_KERNEL);        if (!dev_param_p) {                ERR_PRINTK("Couldn't allocate memory for device information (returning -ENOMEM)\n");                return -ENOMEM;        }            DPRINTK("dev_param_p = 0x%p\n", dev_param_p);        dev_p->driver_data = dev_param_p;            dev_param_p->major = 0;            dev_param_p->int_inuse = 0;        dev_param_p->flags = 0;        dev_param_p->config_space = 0;        dev_param_p->mem_space = 0;        dev_param_p->read_dma_buf_p = 0;        dev_param_p->write_dma_buf_p = 0;        init_waitqueue_head(&dev_param_p->rq);        init_waitqueue_head(&dev_param_p->drq);        init_waitqueue_head(&dev_param_p->wq);	init_waitqueue_head(&dev_param_p->select_wq);        dev_param_p->read_state = RS_IDLE;        dev_param_p->write_state = WS_IDLE;        dev_param_p->read_residual = 0;        dev_param_p->last_read_dma = 0;        dev_param_p->last_write_dma = 0;#ifdef INSTRUMENT        dev_param_p->open_cnt = 0;        dev_param_p->open_busy_cnt = 0;        dev_param_p->close_cnt = 0;        dev_param_p->read_cnt = 0;        dev_param_p->read_dma_cnt = 0;        dev_param_p->read_busy_cnt = 0;        dev_param_p->read_byte_cnt = 0;        dev_param_p->write_cnt = 0;        dev_param_p->write_dma_cnt = 0;        dev_param_p->write_busy_cnt = 0;        dev_param_p->write_busy_cnt2 = 0;        dev_param_p->write_byte_cnt = 0;        dev_param_p->interrupt_cnt = 0;        dev_param_p->SIGNAL_DRIVER_int_cnt = 0;        dev_param_p->DMA_WRITE_COMPLETE_int_cnt = 0;        dev_param_p->DMA_WRITE_NO_SPACE_int_cnt = 0;        dev_param_p->DMA_WRITE_ERROR_int_cnt = 0;        dev_param_p->DMA_READ_COMPLETE_int_cnt = 0;        dev_param_p->DMA_READ_ERROR_int_cnt = 0;#endif /* INSTRUMENT */            /* set up mapping to PCI device addresses */        DPRINTK("mapping PCI\n");        bar1 = pci_resource_start(dev_p, 0);        DPRINTK("bar1 = 0x%08lX\n", bar1);        dev_param_p->config_space = ioremap(bar1, AEP_CONFIG_SIZE);        DPRINTK("config_space = 0x%p\n", dev_param_p->config_space);            if (!dev_param_p->config_space) {                ERR_PRINTK("Unable to map PCI config space (returning -ENOMEM)\n");                kfree(dev_param_p);                return -ENOMEM;        }        bar3 = pci_resource_start(dev_p, 2);        DPRINTK("bar3 = 0x%08lX\n", bar3);        dev_param_p->mem_space = ioremap(bar3, AEP_MEM_SIZE);        DPRINTK("mem_space = 0x%p\n", dev_param_p->mem_space);        if (!dev_param_p->mem_space) {                ERR_PRINTK("Unable to map PCI memory space (returning -ENOMEM)\n");                iounmap(dev_param_p->config_space);                kfree(dev_param_p);                return -ENOMEM;        }        init_MUTEX(&(dev_param_p->aep_sem));     	init_MUTEX(&(dev_param_p->read_sem));                 /* create and register _PROPERLY_ /dev entry in device filesystem             * NOTE: unlike the driver for the 2.2 kernel, each card has a different major number             */        sprintf(dev_p->name, "%s%d", AEP_DEVICE_NAME, nb_cards);        major = devfs_register_chrdev(dev_param_p->major, dev_p->name, &aep_fops);            if (major < 0) {                        ERR_PRINTK("Unable to get major for aep device (returning %d)\n", major);                return major;        }        dev_param_p->dev_fs_handle = devfs_register(NULL, dev_p->name, DEVFS_FL_DEFAULT,                                                    dev_param_p->major, nb_cards, S_IFCHR | S_IRUGO | S_IWUSR,                                                    &aep_fops, NULL);            if (dev_param_p->major == 0)                dev_param_p->major = major; 				DPRINTK("successfully registered devfs entry %s (major=%d)\n",					dev_p->name, dev_param_p->major);                    				/*See the comment for the open routine for an explanation for why we're				requesting the irq here*/                DPRINTK("requesting irq %d\n", dev_p->irq);                result = request_irq(dev_p->irq, aep_interrupt_handler,                                     SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,                                     AEP_DEVICE_NAME, dev_p);                if (result) {                                    ERR_PRINTK("Can't get assigned irq %d (returning -EBUSY)\n", dev_p->irq);#ifdef INSTRUMEN                        ++dev_param_p->open_busy_cnt;#endif/*INSTRUMENT*/                        return( -EBUSY);                }                        dev_param_p->int_inuse = 1;#ifdef AEP_HAS_PROC_ENTRY        if (proc_entry_owner_p == NULL) {                        if ((dev_p->procent = create_proc_entry(AEP_DEVICE_NAME, S_IRUGO | S_IWUSR, NULL)) != NULL) {                            /* NOTE: I think there is no need to protect this section by a mutex,                             * as the driver registers each device sequentially one after another.                             * The first device will become the owner of the /proc entry. VF                             */                        dev_p->procent->read_proc = aep_read_procmem;                        proc_entry_owner_p = dev_p;                        DPRINTK("created proc entry %s successfully\n", AEP_DEVICE_NAME);                   } else                                WARN_PRINTK("Failed to create proc entry %s\n", AEP_DEVICE_NAME);        }    #endif /* AEP_HAS_PROC_ENTRY */        dev_list_pp[nb_cards] = dev_p;            nb_cards++;            DPRINTK("returning\n");        return 0;}/* unmap bar1 and bar3, free corresponding PCI resources */static void __devexit aep_remove_one_device (struct pci_dev *rem_dev_p){        int dev_num = 0;        int removed = 0;            struct pci_dev   *dev_p = NULL;        paep_unit_info_t *dev_param_p = NULL;            assert(rem_dev_p);            BANNER();        if (dev_list_pp)                        for (dev_num = 0; dev_num < AEP_MAXCARDS_NB; dev_num++) {                        dev_p = dev_list_pp[dev_num];                        if (dev_p)                                                if (dev_p == rem_dev_p) {                                        removed = dev_num;                                        dev_param_p = dev_p->driver_data;                                                            DPRINTK("cleaning up card %d\n", dev_num);            /* clean up resources */        if (dev_param_p->int_inuse) {                        DPRINTK("freeing irq\n");                free_irq(dev_p->irq, dev_p);                dev_param_p->int_inuse = 0;                } else                         WARN_PRINTK("IRQ not in use, won't free\n");#ifdef AEP_HAS_PROC_ENTRY                                        if (dev_p == proc_entry_owner_p) {                                                DPRINTK("removing proc entry %s\n", dev_p->procent->name);                                                remove_proc_entry(dev_p->procent->name, NULL);                                        }#endif /* AEP_HAS_PROC_ENTRY */                                           devfs_unregister_chrdev(dev_param_p->major, dev_p->name);                                        devfs_unregister(dev_param_p->dev_fs_handle);                                        DPRINTK("successfully un-registered devfs entry %s (major=%d)\n",                                                dev_p->name, dev_param_p->major);                                                                /* release all resources associated with each card */                                        if (dev_param_p->config_space) {                                                DPRINTK("     unmapping config space 0x%p\n", dev_param_p->config_space);                                                iounmap(dev_param_p->config_space);                                        }                                        if (dev_param_p->mem_space) {                                                DPRINTK("     unmapping register space 0x%p\n", dev_param_p->mem_space);                                                iounmap(dev_param_p->mem_space);                                        }                                        if (dev_param_p) {                                                DPRINTK("     freeing card info struct 0x%p\n", dev_param_p);                                                kfree(dev_param_p);                                                dev_param_p = NULL;                                        }                                                            dev_list_pp[removed] = NULL;                                        nb_cards--;                                }                 }   }module_init(aep_init_module); module_exit(aep_cleanup_module);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?