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

📄 ul_linux.c

📁 linux下的RS485的驱动 值得一看
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************  uLan Communication - uL_DRV - multiplatform uLan driver  ul_linux.c	- Linux kernel and module specific part  (C) Copyright 1996-2004 by Pavel Pisa - project originator        http://cmp.felk.cvut.cz/~pisa  (C) Copyright 1996-2004 PiKRON Ltd.        http://www.pikron.com  (C) Copyright 2002-2004 Petr Smolik    The uLan driver project can be used and distributed   in compliance with any of next licenses   - GPL - GNU Public License     See file COPYING for details.   - LGPL - Lesser GNU Public License   - MPL - Mozilla Public License   - and other licenses added by project originator  Code can be modified and re-distributed under any combination  of the above listed licenses. If contributor does not agree with  some of the licenses, he/she can delete appropriate line.  WARNING: if you delete all lines, you are not allowed to  distribute code or sources in any form. *******************************************************************//*******************************************************************//* Linux kernel and module specific part */ MODULE_SUPPORTED_DEVICE("ul_drv");MODULE_AUTHOR("Pavel Pisa <pisa@cmp.felk.cvut.cz>");MODULE_DESCRIPTION("\uLan communication module ( 9 bit RS-485 protocol )\n\for communication with embedded controllers.\n\It uses i82510 addon card or RS-232 dongle");MODULE_LICENSE("GPL");EXPORT_NO_SYMBOLS;static int ulan_major_dev=ULAN_MAJOR;	/* uLan major device number */struct kc_class *ulan_class;#define UL_MINORS 9ul_drv *ul_drv_arr[UL_MINORS]={[0 ... UL_MINORS-1]=NULL};char *chip[UL_MINORS]={NULL,};int chip_specified;#if defined(UL_WITH_PCI) || defined(UL_WITH_USB)char *slot[UL_MINORS]={NULL,};int slot_specified;#endifint my_adr[UL_MINORS]={[0 ... UL_MINORS-1]=2};int my_adr_specified;int baud[UL_MINORS]={[0 ... UL_MINORS-1]=19200};int baud_specified;int baudbase[UL_MINORS]={[0 ... UL_MINORS-1]=0};int baudbase_specified;int irq[UL_MINORS]={0,};int irq_specified;int port[UL_MINORS]={0x3e8 	#if (UL_MINORS>1)		,[1 ... UL_MINORS-1]=0	#endif		};int port_specified;int debug=-1;		/* debug flags */int ul_usb_msg_inpr=0;	/* number of concurrent messages sent over USB */#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))module_param_array(chip, charp, &chip_specified, 0);module_param_array(my_adr, int, &my_adr_specified, 0);module_param_array(baud, int, &baud_specified, 0);module_param_array(irq, int, &irq_specified, 0);module_param_array(port, int, &port_specified, 0);module_param_array(baudbase, int, &baudbase_specified, 0);#if defined(UL_WITH_PCI) || defined(UL_WITH_USB)module_param_array(slot, charp, &slot_specified, 0);#endifmodule_param(debug, int, 0);module_param(ul_usb_msg_inpr, int, 0);module_param(ulbuffer, int, 0);#else /* LINUX_VERSION_CODE < 2,6,0 */MODULE_PARM(chip,"1-" __MODULE_STRING(UL_MINORS) "s");MODULE_PARM(my_adr,"1-" __MODULE_STRING(UL_MINORS) "i");MODULE_PARM(baud,"1-" __MODULE_STRING(UL_MINORS) "i");MODULE_PARM(irq,"1-" __MODULE_STRING(UL_MINORS) "i");MODULE_PARM(port,"1-" __MODULE_STRING(UL_MINORS) "i");MODULE_PARM(baudbase,"1-" __MODULE_STRING(UL_MINORS) "i");#if defined(UL_WITH_PCI) || defined(UL_WITH_USB)MODULE_PARM(slot,"1-" __MODULE_STRING(UL_MINORS) "s");#endifMODULE_PARM(debug,"i");MODULE_PARM(ul_usb_msg_inpr,"i");MODULE_PARM(ulbuffer,"i");#endif /* LINUX_VERSION_CODE < 2,6,0 */MODULE_PARM_DESC(chip,"chip type: auto, 82510, 16450, 16950-pci");MODULE_PARM_DESC(my_adr,"uLan address of defined interface");MODULE_PARM_DESC(baud,"define baudrates");MODULE_PARM_DESC(irq,"define irqs");MODULE_PARM_DESC(port,"define ports");MODULE_PARM_DESC(baudbase,"define UART base clock");#if defined(UL_WITH_PCI) || defined(UL_WITH_USB)MODULE_PARM_DESC(slot,"slot type (pci) and specification");#endifMODULE_PARM_DESC(debug,"debug flags (FATAL,CHIO,IRQ,MSG,FAILS,"\		       "SEQ,PORTS,FILE,FILT)");MODULE_PARM_DESC(ul_usb_msg_inpr,"used length of Tx fifo in conventor");MODULE_PARM_DESC(ulbuffer,"size of per interface buffer");#ifdef UL_WITH_PCIstatic int /*__devinit*/ ulan_pci_init_one (struct pci_dev *dev,                                   const struct pci_device_id *ent);static void /*__devexit*/ ulan_pci_remove_one (struct pci_dev *dev);MODULE_DEVICE_TABLE(pci, ulan_pci_tbl);static struct pci_driver ulan_pci_driver = {	name:		"ul_drv",	id_table:	ulan_pci_tbl,	probe:		ulan_pci_init_one,	remove:		ulan_pci_remove_one,};#endif /*UL_WITH_PCI*/#ifdef UL_WITH_USB#if (LINUX_VERSION_CODE < VERSION(2,5,41))static void *ul_usb_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id);static void ul_usb_disconnect(struct usb_device *dev, void *ptr);#else /* 2.5.41 */static int ul_usb_probe(struct usb_interface *intf, const struct usb_device_id *id);static void ul_usb_disconnect(struct usb_interface *intf);#endif /* 2.5.41 */MODULE_DEVICE_TABLE (usb, ulan_usb_tbl);#ifdef CONFIG_USB_DYNAMIC_MINORS/*  * if the user wants to use dynamic minor numbers, then we can have up to 256 * devices */#define UL_USB_MINOR_BASE	0#define MAX_DEVICES		256#else/* Get a minor range for your devices from the usb maintainer */#define UL_USB_MINOR_BASE	200/* we can have up to this number of device plugged in at once */#define MAX_DEVICES		16#endif/* usb specific object needed to register this driver with the usb subsystem */static struct usb_driver ul_usb_driver = {	name:		"ulan_usb",	probe:		ul_usb_probe,	disconnect:	ul_usb_disconnect,	/*fops:		&ul_usb_fops,*/	/* num_minors:	MAX_DEVICES,*/     #if (LINUX_VERSION_CODE < VERSION(2,5,8))	minor:		UL_USB_MINOR_BASE,     #endif	id_table:	ulan_usb_tbl,};#endif /*UL_WITH_USB*/static int ulan_open(struct inode *inode, struct file *file);static CLOSERET ulan_close(struct inode *inode, struct file *file);static int ulan_ioctl(struct inode *inode, struct file *file, 			unsigned int cmd, unsigned long arg);static RWRET ulan_write(WRITE_PARAMETERS);static RWRET ulan_read(READ_PARAMETERS);static loff_t ulan_lseek(LSEEK_PARAMETERS);static unsigned int ulan_poll(struct file *, poll_table *);/* static struct file_operations ulan_fops */KC_CHRDEV_FOPS_BEG(ulan_fops)	KC_FOPS_LSEEK(ulan_lseek)/* lseek              */	read:ulan_read,		/* read                */	write:ulan_write,	/* write               */	readdir:NULL,		/* readdir             */	poll:ulan_poll,		/* poll                */	ioctl:ulan_ioctl,	/* ioctl               */	mmap:NULL,		/* mmap                */	open:ulan_open,		/* open                */	KC_FOPS_FLUSH(NULL)	/* flush               */	KC_FOPS_RELEASE(ulan_close)/* close/release    */	fsync:NULL,		/* fsync               */	fasync:NULL,		/* fasync              */	NULL,			/* check_media_change  */	NULL,			/* revalidate          */KC_CHRDEV_FOPS_END;/* open ulan device */static int ulan_open(struct inode *inode, struct file *file){   ul_drv *udrv;  ul_opdata *opdata;  unsigned int minor = kc_dev2minor(inode->i_rdev);  #ifdef UL_WITH_DEVFS  if(minor==-1){    udrv=file->private_data;  }else  #endif /* UL_WITH_DEVFS */  {    if ((minor >= UL_MINORS)||(minor<0)) return -ENODEV;    udrv=ul_drv_arr[minor];  }  if (!udrv) return -ENODEV;  if(udrv->magic!=UL_DRV_MAGIC)  {    printk(KERN_CRIT "ulan_open: Wrong uLan MAGIC number!!!\n");    return -ENODEV;  }  kc_MOD_INC_USE_COUNT;  if(!(file->private_data=MALLOC(sizeof(ul_opdata))))  { kc_MOD_DEC_USE_COUNT;    return(-ENOMEM);  };  opdata=(ul_opdata*)file->private_data;  opdata->file=file;  opdata->magic=ULOP_MAGIC;  opdata->message=NULL;  opdata->udrv=udrv;  init_waitqueue_head(&opdata->wqrec);  opdata->opprew=NULL;  opdata->opnext=NULL;  opdata->recchain=NULL;  opdata->filtchain=NULL;  { /* add us onto list of clients of udrv */    ul_opdata *opptr;    UL_DRV_LOCK_FINI    UL_DRV_LOCK;    opptr=udrv->operators;    if(opptr) {opptr->opprew=opdata;opdata->opnext=opptr;};    UL_MB();    udrv->operators=opdata;    UL_DRV_UNLOCK;  };  return 0;};static CLOSERET ulan_close(struct inode *inode, struct file *file){  ul_opchain *opmember;  ul_opdata *opdata=(ul_opdata*)file->private_data;  if(opdata->magic!=ULOP_MAGIC) panic("ulan_close : BAD opdata magic !!!");  if (opdata->message) ulan_freemsg(opdata);  { /* delete us from list of clients of udrv */    ul_drv *udrv;    ul_opdata *opptr;    UL_DRV_LOCK_FINI    UL_DRV_LOCK;    if((udrv=opdata->udrv)!=NULL){      if((opptr=opdata->opnext)) opptr->opprew=opdata->opprew;      if((opptr=opdata->opprew)) opptr->opnext=opdata->opnext;      else udrv->operators=opdata->opnext;    }    UL_DRV_UNLOCK;    if(udrv)      if(udrv->irq>0) ul_synchronize_irq(udrv->irq);    while((udrv=opdata->udrv)!=NULL){      if(!uld_atomic_test_dfl(udrv,IN_BOTTOM))        break;      kc_yield();    }  }  schedule();  while((opmember=opdata->recchain))  {    del_from_opchain(&opdata->recchain,opmember);    if(opmember->message) ul_dec_ref_cnt(opmember->message);    FREE(opmember);  };  while((opmember=opdata->filtchain))  {    del_from_opchain(&opdata->filtchain,opmember);    FREE(opmember);  };  FREE(file->private_data);  kc_MOD_DEC_USE_COUNT;  return (CLOSERET)0;};static int ulan_ioctl(struct inode *inode, struct file *file, 			unsigned int cmd, unsigned long arg){  ul_msginfo msginfo;  int ret;  ul_opdata *opdata=(ul_opdata*)file->private_data;  if(opdata->magic!=ULOP_MAGIC) panic("ulan_ioctl : BAD opdata magic !!!");  switch (cmd) {   case UL_DRV_VER :	return UL_DRV_VERCODE;   case UL_NEWMSG :	if(kc_copy_from_user(&msginfo,(void *)arg,sizeof(msginfo)))	   return -EFAULT;  	return ulan_newmsg(opdata,&msginfo);   case UL_TAILMSG :	if(kc_copy_from_user(&msginfo,(void *)arg,sizeof(msginfo)))	   return -EFAULT;  	return ulan_tailmsg(opdata,&msginfo);   case UL_FREEMSG :  	return ulan_freemsg(opdata);   case UL_ACCEPTMSG :  		if(kc_copy_to_user((void *)arg,&msginfo,sizeof(msginfo)))	   return -EFAULT;	ret=ulan_acceptmsg(opdata,&msginfo);	if(kc_copy_to_user((void *)arg,&msginfo,sizeof(msginfo)))	   return -EFAULT;  	return  ret;   case UL_ACTAILMSG :  		if(kc_copy_to_user((void *)arg,&msginfo,sizeof(msginfo)))	   return -EFAULT;	ret=ulan_actailmsg(opdata,&msginfo);	if(kc_copy_to_user((void *)arg,&msginfo,sizeof(msginfo)))	   return -EFAULT;  	return  ret;   case UL_ADDFILT :	if(kc_copy_from_user(&msginfo,(void *)arg,sizeof(msginfo)))	   return -EFAULT;  	return ulan_addfilt(opdata,&msginfo);   case UL_ABORTMSG :  	return ulan_abortmsg(opdata);   case UL_REWMSG :  	return ulan_rewmsg(opdata);   case UL_KLOGBLL :        if(!opdata->udrv) return -ENODEV;	printudrvbll(opdata->udrv);    #ifdef ENABLE_UL_MEM_CHECK	printudrvoperators(opdata->udrv);    #endif /* ENABLE_UL_MEM_CHECK */	return 0;   case UL_STROKE :        if(!opdata->udrv) return -ENODEV;	ulan_stroke(opdata->udrv, 1);	return 0;   case UL_DEBFLG :	uld_debug_flg=arg;	return 0;   case UL_INEPOLL :        return ulan_inepoll(opdata);   case UL_SETMYADR :        return ulan_setmyadr(opdata,arg);  #ifdef UL_WITH_IAC   case UL_SETIDSTR :{	  char idstr[41];	  char ch;	  int ln=0;	  do{	    if(kc_get_user_byte(ch,(char*)arg))	      return -EFAULT;	    if(++arg>=sizeof(idstr))	      return -EINVAL;	    idstr[ln++]=ch;	  }while(ch);

⌨️ 快捷键说明

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