⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtd-dm7520.c

📁 rt 7520采集卡 linux驱动源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
      }    if (!(dm7520_table[card_idx].lasmap[LCFG] &&          dm7520_table[card_idx].lasmap[LAS0] &&          dm7520_table[card_idx].lasmap[LAS1] &&          dm7520_table[card_idx].irq  )) // unsuccessful      {	   printk(KERN_INFO "dm7520%d: Something is unsuccessful.\n",card_idx);	   for (i=0;i<=LCFG;i++)	     {	      if (dm7520_table[card_idx].lasmap[i])          	iounmap((void*)dm7520_table[i].lasmap[i]);	     }	   if (dm7520_table[i].irq)	     {          free_irq(dm7520_table[i].irq,&dm7520_table[i]);	     }	   continue;      }    else      {   	   dm7520_table[card_idx].present=1;      }        	ret=dm7520_register_procfile(card_idx);      dm7520_table[card_idx].fifosize=dm7520_probefifosize(card_idx);    printk(KERN_INFO "dm7520%d: FIFO size %d.\n",card_idx,           dm7520_table[card_idx].fifosize);           /*        Here we have to fiddle with the delay for the        interruptible_sleep_on_timeout functions, because the FIFO       size determines the max value we can wait otherwise the       FIFO fills up. This is a quick hack.    */    if (dm7520_table[card_idx].fifosize==1024)      {       dm7520_table[card_idx].jiffie_r=READ_TIMEOUT_SHORT;       dm7520_table[card_idx].jiffie_w=WRITE_TIMEOUT_SHORT;      }    else      {       dm7520_table[card_idx].jiffie_r=READ_TIMEOUT_LONG;       dm7520_table[card_idx].jiffie_w=WRITE_TIMEOUT_LONG;      }    epld_version=GETMEM32(card_idx,LAS0,0)&0xFF;    if ((epld_version&0xF0)>>4 == 0x0F)      {   	   VPRINTK(KERN_INFO "dm7520%d: pre-v8 EPLD.\n",card_idx);      }    else      {   	   VPRINTK(KERN_INFO "dm7520%d: EPLD version %08X.\n",card_idx,epld_version>>4);      }    dm7520_table[card_idx].flags&=~DM7520_FLAGS_BMCAP;	pci_read_config_word(pdev, PCI_COMMAND, &pci_command);	new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;	if (pci_command != new_command)      {	   printk(KERN_INFO "dm7520%d: Busmastering not enabled on this device.\n", card_idx);	   pci_write_config_word(pdev, PCI_COMMAND, new_command);      }    else      {       if (epld_version&0x01)         {          dm7520_table[card_idx].flags|=DM7520_FLAGS_BMCAP;          DMABUF(card_idx,0)=kmalloc(DMASIZE(card_idx),GFP_KERNEL);          DMABUF(card_idx,1)=kmalloc(DMASIZE(card_idx),GFP_KERNEL);
          DMATEMPBUF(card_idx,0)=kmalloc(DMATEMPSIZE,GFP_KERNEL);
          DMATEMPBUF(card_idx,1)=kmalloc(DMATEMPSIZE,GFP_KERNEL);
		  CONTROLBUF(card_idx) = kmalloc(PAGE_SIZE, GFP_KERNEL);
		
          if (!DMABUF(card_idx,0) && !DMABUF(card_idx,1))    	  {	     printk(KERN_INFO "dm7520%d: Unable to get DMA buffer.\n", card_idx);             dm7520_table[card_idx].flags&=~DM7520_FLAGS_BMCAP;          }          else          {
			if (DMATEMPBUF(card_idx,0)) {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)								for (page=virt_to_page(DMATEMPBUF(card_idx,0));
					page<(virt_to_page(DMATEMPBUF(card_idx,0)+DMATEMPSIZE));
					page++){
					mem_map_reserve(page);									}
#else				for (i=MAP_NR(DMATEMPBUF(card_idx,0));
					i<MAP_NR((DMATEMPBUF(card_idx,0)+DMATEMPSIZE));
					i++){
					mem_map_reserve(i);									}				#endif				//				printk("<1> dmatempbuf0=%ld\n",(long)DMATEMPBUF(card_idx,0));			}			else			printk(KERN_INFO "Could not allocate memory for DMATEMPBUF(card_idx,0)\n");			if (DMATEMPBUF(card_idx,1)) {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)							for (page=virt_to_page(DMATEMPBUF(card_idx,1));
					page<(virt_to_page(DMATEMPBUF(card_idx,1)+DMATEMPSIZE));
					page++){
					mem_map_reserve(page);
				}
#else				for (i=MAP_NR(DMATEMPBUF(card_idx,1));
					i<MAP_NR((DMATEMPBUF(card_idx,1)+DMATEMPSIZE));
					i++){
					mem_map_reserve(i);
				}
#endif			//				printk("<1> dmatempbuf1=%ld\n",(long)DMATEMPBUF(card_idx,1));			}			else			printk(KERN_INFO "Could not allocate memory for DMATEMPBUF(card_idx,1)\n");			if (CONTROLBUF(card_idx)){#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)							page=virt_to_page(CONTROLBUF(card_idx));
				mem_map_reserve(page);			#else									i=MAP_NR(CONTROLBUF(card_idx));
				mem_map_reserve(i);				#endif							}			else			printk(KERN_INFO "Could not allocate memory for CONTROLBUF\n");                        }	}       else         {          dm7520_table[card_idx].dmasetup[0].dmabuf=NULL;          dm7520_table[card_idx].dmasetup[1].dmabuf=NULL;         }	  }	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);	if (pci_latency < 32)       {       VPRINTK("dm7520%d: PCI latency timer Changed to %d.\n",card_idx,32);       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 32);	  } 	card_idx++;   }	
 return card_idx;}/************************************************************************/ int init_module(){ int ret; memset(dm7520_table,0,MAXDM7520*sizeof(dm7520_table[0]));   printk(KERN_INFO "%s> \n", DRIVER_NAME); printk(   KERN_INFO "%s> Initializing module (version %s).\n",   DRIVER_NAME,   DRIVER_RELEASE ); printk(KERN_INFO "%s> %s\n", DRIVER_NAME, DRIVER_DESCRIPTION); printk(KERN_INFO "%s> %s\n", DRIVER_NAME, DRIVER_COPYRIGHT); ret=finddevices(); if (0==ret)   {    printk(KERN_INFO "dm7520: No devices found.\n");    return(-ENODEV);   } /*  * Register the character device, requesting dynamic major number allocation  */ dm7520_major = register_chrdev(0, DEVICE_NAME, &dm7520_fops); if (dm7520_major < 0) {   printk(     KERN_INFO     "%s> Dynamic character device registration failed with errno %d\n",     DRIVER_NAME,     -dm7520_major   );   return dm7520_major; } printk(   KERN_INFO "%s> Driver registered using character major number %d\n",   DRIVER_NAME,   dm7520_major ); SET_MODULE_OWNER(&dm7520_fops); return 0;}voidcleanup_module(void) {    int		ret;    int		i;    struct page	*page;    for (i = 0; i < MAXDM7520; i++) {	if (dm7520_table[i].present) {	    disable_PLX_it(i);	    reset_card(i);	    if (dm7520_table[i].dmasetup[0].dmainuse) {		dm7520_table[i].dmasetup[0].dmainuse = 0;		abort_dma0(i);		disable_dma(i, 0);	    }	    if (dm7520_table[i].dmasetup[1].dmainuse) {		dm7520_table[i].dmasetup[1].dmainuse = 0;		abort_dma1(i);		disable_dma(i, 1);	    }	dm7520_unregister_procfile(i);	    if (DMABUF(i, 0)) {		kfree(DMABUF(i, 0));	    }	    if (DMABUF(i, 1)) {		kfree(DMABUF(i, 1));	    }	    if (DMATEMPBUF(i, 0)) {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)		for (		    page = virt_to_page(DMATEMPBUF(i, 0));		    page < (virt_to_page(DMATEMPBUF(i, 0) + DMATEMPSIZE));		    page++		) {		    mem_map_unreserve(page);		}#endif		kfree(DMATEMPBUF(i, 0));	    }	    if (DMATEMPBUF(i, 1)) {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)		for (		    page = virt_to_page(DMATEMPBUF(i, 1));		    page < (virt_to_page(DMATEMPBUF(i, 1) + DMATEMPSIZE));		    page++		) {		    mem_map_unreserve(page);		}#endif		kfree(DMATEMPBUF(i, 1));	    }	    if (CONTROLBUF(i)) {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)		page = virt_to_page(CONTROLBUF(i));		mem_map_unreserve(page);#endif		kfree(CONTROLBUF(i));	    }	    iounmap((void*) dm7520_table[i].lasmap[LAS0]);	    iounmap((void*) dm7520_table[i].lasmap[LAS1]);	    iounmap((void*) dm7520_table[i].lasmap[LCFG]);	    free_irq(dm7520_table[i].irq, &dm7520_table[i]);	}    }    ret = unregister_chrdev(dm7520_major, DEVICE_NAME);     if (ret < 0)	printk("DM7520: Error in unregister_chrdev: %d\n", ret);}  /*=============================================================================What follows is source code for DM7520 /proc file entry support.  This wasbrought in from procfs.c. =============================================================================*/#ifndef DEBUGstatic char *rwchan_names[] = {"A/D", "HDIN", "D/A1", "D/A2"};#endifstatic ssize_tdm7520_proc_output(    char *buf,    char **start,    off_t offset,    int len,    int *eof,    void *data) {    int		minor;    DM7520_STAT	*devptr = (DM7520_STAT *) data;#ifdef DEBUG    uint32_t p_itcsr, p_d0s, p_d1s, p_d0m, p_d1m;#endif     minor = devptr - &(dm7520_table[0]);    len = 0;#ifdef DEBUG    dm7520_getregs(minor, &p_itcsr, &p_d0m, &p_d1m, &p_d0s, &p_d1s);    len = sprintf(	buf,	"IRQ: %d, LAS0 %p, LAS1 %p, LCFG %p, Busmaster: %s, opened: %d, "	"errorcode: %d, IT: %08X\n",	dm7520_table[minor].irq,	dm7520_table[minor].lasmap[LAS0],	dm7520_table[minor].lasmap[LAS1],	dm7520_table[minor].lasmap[LCFG],	(dm7520_table[minor].flags & DM7520_FLAGS_BMCAP) ? "yes" : "no",	dm7520_table[minor].opened,	dm7520_table[minor].errcode,	p_itcsr    );#else    len = sprintf(	buf,	"IRQ: %d, Busmaster: %s, opened: %d, errorcode: %d,\n used by %s, "	"used by %s.\n",	dm7520_table[minor].irq,	(dm7520_table[minor].flags & DM7520_FLAGS_BMCAP) ? "yes" : "no",	dm7520_table[minor].opened,	dm7520_table[minor].errcode,	dm7520_table[minor].dmasetup[0].dmainuse ?	    rwchan_names[(int) dm7520_table[minor].dmasetup[0].usedby] : "-",	dm7520_table[minor].dmasetup[1].dmainuse ?	    rwchan_names[(int) dm7520_table[minor].dmasetup[1].usedby] : "-"    );#endif //DEBUG    *eof = 1;     return len;}static ssize_tdm7520_proc_input(    struct file *file,    const char *buf,    size_t length,    loff_t *offset) {    return -EACCES;}static intdm7520_proc_permission(struct inode *inode, int op) {    if (op == MAY_READ) {	return 0;     }    return -EACCES;}intdm7520_proc_open(struct inode *inode, struct file *file) {    dm7520_incuse();    return 0;}intdm7520_proc_close(struct inode *inode, struct file *file) {    dm7520_decuse();    return 0;}intdm7520_register_procfile(int minor) {    struct proc_dir_entry	*pfile;#ifdef DEBUG    printk(KERN_INFO "registering /proc/%s\n", dm7520_table[minor].devname);#endif    pfile = create_proc_entry(	dm7520_table[minor].devname,	(S_IFREG | S_IRUGO | S_IWUSR),	&proc_root    );    if (pfile) {	pfile->read_proc = dm7520_proc_output;	pfile->data = &(dm7520_table[minor]);	dm7520_table[minor].procfile = pfile;	return 1;    } else {	dm7520_table[minor].procfile = NULL;    }    return 0;}voiddm7520_unregister_procfile(int minor) {    remove_proc_entry(dm7520_table[minor].devname, &proc_root);}  

⌨️ 快捷键说明

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