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

📄 can_ioctl.h

📁 盛博can驱动程序功能很全
💻 H
字号:
#include <linux/ioctl.h>

int afm,lom,stm,sm,mode,err_count,arb_count;
struct err_cap_struct *err_capture;
struct arb_cap_struct *arb_capture;
unsigned long flag;
   
int irq,level;
enum bau baud;		
static int send_delay=200;
static int noblock_delay=100;
static int delay_by_baud=2;
int  status; 
struct filter_struct *filter;

extern int modify_irq(int , struct CAN_device_struct *);
extern void set_baudrate(enum bau,int);
extern void can_reset_buf();

#define CAN_IOC_MAGIC  'k'

#define CAN_IOCRESET            _IO(CAN_IOC_MAGIC, 0)
#define CAN_SET_NOBLOCKDELAY    _IOW(CAN_IOC_MAGIC,1,int)
#define CAN_SET_TRIGLEVEL       _IOW(CAN_IOC_MAGIC,2,int)
#define CAN_SET_BAUDRATE        _IOW(CAN_IOC_MAGIC,3,enum bau)
#define CAN_SET_AFM             _IOW(CAN_IOC_MAGIC,4,int)
#define CAN_SET_LOM             _IOW(CAN_IOC_MAGIC,5,int)
#define CAN_SET_SM              _IOW(CAN_IOC_MAGIC,6,int)
#define CAN_SET_STM             _IOW(CAN_IOC_MAGIC,7,int)
#define CAN_SET_FILTER           _IOW(CAN_IOC_MAGIC,8,filter)
#define CAN_SET_FILTER1          _IOW(CAN_IOC_MAGIC,9,filter)
#define CAN_SET_FILTER2          _IOW(CAN_IOC_MAGIC,10,filter)

#define CAN_GET_STATUS         _IOR(CAN_IOC_MAGIC,11,int)
#define CAN_GET_MODE           _IOR(CAN_IOC_MAGIC,12,int)
#define CAN_GET_FILTER         _IOR(CAN_IOC_MAGIC,13,filter)
#define CAN_GET_ERRCOUNT       _IOR(CAN_IOC_MAGIC,14,int)
#define CAN_GET_ERRCAPTURE     _IOR(CAN_IOC_MAGIC,15,err_capture)
#define CAN_GET_BAUDRATE       _IOR(CAN_IOC_MAGIC,16,enum bau )
#define CAN_GET_ARBCOUNT       _IOR(CAN_IOC_MAGIC,17,int)
#define CAN_GET_ARBCAPTURE     _IOR(CAN_IOC_MAGIC,18,arb_capture)


#define CAN_RESET                 _IO(CAN_IOC_MAGIC, 19) /* debugging tool */
#define CAN_SET_DELAY             _IOW(CAN_IOC_MAGIC,20,int)
#define CAN_SET_IRQ               _IOW(CAN_IOC_MAGIC,21,int)
#define CAN_IOC_MAXNR 22

int enable_set(struct CAN_device_struct *dev)
{
 int loop=0;
 while ((test_bit(0,&dev->rx_lock))||
        (test_bit(0,&dev->tx_lock))) {
    //____udelay(100000);
    if (loop++>3)  {
      printk("the device is busy ,don't  change the parms\n");
      return -1;
    }
 }
 
 return 0;
}

int CAN_ioctl(struct inode *inode, struct file *filp,
                 unsigned int cmd, unsigned long arg)
{

   int err = 1, size = _IOC_SIZE(cmd); /* the size bitfield in cmd */
   unsigned long flag;
    
   struct CAN_device_struct *dev=filp->private_data;

    if (_IOC_TYPE(cmd) != CAN_IOC_MAGIC) {
        printk("cmd type is not invalid\n");
        return -EINVAL;
    }

    if (_IOC_NR(cmd) > CAN_IOC_MAXNR) {
      printk("cmd  is not over max numbe\n");
       return -EINVAL;
    }

    if (_IOC_DIR(cmd) & _IOC_READ)
        err = access_ok(VERIFY_WRITE, (void *)arg, size);
    else if (_IOC_DIR(cmd) & _IOC_WRITE)
        err =  access_ok(VERIFY_READ, (void *)arg, size);
    
    if (!err) {
       printk("addrss is not valid\n");
       return err;
   }
    switch(cmd) {
      case CAN_IOCRESET:
          printk("enter iocreset\n");
	  can_ioc_reset(dev);
          printk("ioc rx=%d,tx=%d\n",dev->rx_lock,dev->tx_lock);
      
          dev->recv_head=dev->recv_tail=0;
          memset(dev->recv_data,0,4096);
          //memset_io(dev->base_addr+0x100,0,51*13);
          //memset_io(dev->base_addr+0x400,0,51*13);
          clear_bit(0,&dev->rx_lock);
          clear_bit(0,&dev->tx_lock);
     		break;	

      case CAN_SET_IRQ:

       		printk("begin can_set_irq\n");   

      	if (get_user(irq,(unsigned short int *)arg))
			return -EFAULT;
        if (enable_set(dev))
          return -1;
   
        save_flags(flag);
        cli();
        if (modify_irq(irq,dev)) {
            restore_flags(flag);
            printk("modify irq failed\n");
            return -1;
        }
        restore_flags(flag);     
        break;

      case CAN_SET_TRIGLEVEL: 
        printk("begin can_set_triglevel\n");  
      	if (get_user(level,(int *)arg))
		return -EFAULT;
        save_flags(flag);
      	cli();
      	if (enable_set(dev))
          return -1;
      	set_trig_level(level,dev->base_addr);
        dev->parm->trig_level=level ? level : 1; 
        restore_flags(flag);
        break;
       case CAN_SET_DELAY:
             printk("begin set send delay \n");
             if (enable_set(dev))
               return -1;
             if (get_user(send_delay,(int *)arg))
		     return -EFAULT;
             break;
       case CAN_SET_NOBLOCKDELAY: 
            if (enable_set(dev))
               return -1;
            if (get_user(noblock_delay,(int *)arg))
		    return -EFAULT;
            printk("noblock_delay=%d\n",noblock_delay);
            break;
      case CAN_SET_BAUDRATE: 
        printk("begin can_set_baudrate\n");  
        save_flags(flag);
      	cli();
      	if (enable_set(dev))
          return -1;
        if (get_user(baud,(enum bau *)arg))
		return -EFAULT;
        set_baudrate(baud,dev->base_addr);
        dev->parm->baud_rate=baud;
        delay_by_baud=baud+1;
        restore_flags(flag);
        break;
      case CAN_SET_AFM:
          printk("begin can_set_afm\n");
          if (get_user(afm,(int *)arg))
		  return -EFAULT;
          save_flags(flag);
          cli();
      	  if (enable_set(dev)) 
            return -1;
      	  set_AFM(afm?DOUBLE : SINGLE,dev->base_addr);
          restore_flags(flag);
          break;
      case CAN_SET_STM:
      	  printk("begin can_set_stm\n");  
          if (get_user(stm,(int *)arg))
		  return -EFAULT;
          save_flags(flag);
          cli();
      	  if (enable_set(dev))
            return -1;
      	  set_STM(stm?TOFF: TON ,dev->base_addr);
          restore_flags(flag);
          break; 	  
      case CAN_SET_LOM:
      	  printk("begin can_set_lom\n"); 
          if (get_user(lom,(int *)arg))
		  return -EFAULT;
          save_flags(flag);
          cli();
      	  if (enable_set(dev))
            return -1;
          set_LOM(lom?LOFF: LON ,dev->base_addr);
          restore_flags(flag);
          break; 	     
     case CAN_SET_SM:
      	  printk("begin can_set_sm\n"); 
          if (get_user(sm,(int *)arg))
		  return -EFAULT;
          save_flags(flag);
          cli();
      	  if (enable_set(dev))
            return -1;
      	  set_SM(sm?SOFF: SON ,dev->base_addr);
          restore_flags(flag);
          break; 	     
      
    case CAN_SET_FILTER:
          printk("begin can_set_filter\n");  
      	  save_flags(flag);
          cli();
      	  if (enable_set(dev)) {
            printk("some procees is sending or recving...,don't change it\n");
            return -1;
          }
          filter=(struct filter_struct *)kmalloc(sizeof(struct filter_struct),
                                                 GFP_KERNEL);
      	  memset(filter,0,sizeof(struct filter_struct)); 
      	  if (copy_from_user(filter,(struct filter_struct *)arg,
                             sizeof(struct filter_struct)))
		  return -EFAULT;
          set_FILTER(filter,dev->base_addr,0); 
          restore_flags(flag);
          break;
      case CAN_SET_FILTER1:
          printk("begin can_set_filter1\n");  
      	  save_flags(flag);
          cli();
      	  if (enable_set(dev))
            return -1;
      	   filter=(struct filter_struct *)kmalloc(sizeof(struct filter_struct),
                                                         GFP_KERNEL);
          if (copy_from_user(filter,(struct filter_struct *)arg,
                             sizeof(struct filter_struct)))
		  return -EFAULT;
      	  set_FILTER(filter,dev->base_addr,1);
          restore_flags(flag);
          break;	
       case CAN_SET_FILTER2:
          printk("begin can_set_filter2\n");  
      	  save_flags(flag);
          cli();
      	  if (enable_set(dev))
            return -1;
      	  filter=(struct filter_struct *)kmalloc(sizeof(struct filter_struct),
                                                         GFP_KERNEL);
      	  if (copy_from_user(filter,(struct filter_struct *)arg,
                             sizeof(struct filter_struct)))
		  return -EFAULT;
      	  set_FILTER(filter,dev->base_addr,2);
          restore_flags(flag);
          break;   
      case CAN_GET_FILTER:
          printk("begin can_get_filter\n");
          filter=(struct filter_struct *)kmalloc(sizeof(struct filter_struct),
                                                         GFP_KERNEL);
      	  memset(filter,0,sizeof(struct filter_struct)); 
          read_FILTER(filter,dev->base_addr);
      	  if (copy_to_user((struct filter_struct *)arg,filter,
                             sizeof(struct filter_struct)))
		  return -EFAULT;
      	  break;

      case CAN_GET_STATUS:
          printk("begin read status\n");
          status=read_status(dev->base_addr);
          printk("in ioctl status=%d\n",status);
          if (put_user(status,(int *)arg))
		  return -2;
          dev->status=status;
          break;
     case CAN_GET_MODE:
          printk("begin can_get_mode\n");  
          mode=(int)read_mode(dev->base_addr);
          if (put_user(mode,(int *)arg))
		  return -EFAULT;
          break;
     case CAN_GET_BAUDRATE:
          printk("begin can_get_baudrate\n");  
     	  switch (read_baudrate(dev->base_addr)) {
     	  	case 0:
     	  		baud= B1000;
     	  		break;
     	  	case 1:
     	  		baud= B800;
     	  		break;
     	  	case 2:
     	  		baud= B500;
     	  		break;
     	  	case 3:
     	  		baud= B320;
     	  		break;
     	  	case 4:
     	  		baud= B250;
     	  		break;
     	  	case 5:
     	  		baud= B160;
     	  		break;
     	  	case 6:
     	  		baud= B80;
     	  		break;
     	  	case 7:
     	  		baud= B40;
     	  		break;
     	  	case 8:
     	  		baud= B20;
     	  		break;
     	  	case 9:
     	  		baud= B10;
     	  		break;
     	  	case 10:
     	  		baud= B5;
            default:
            	return -1;
     	  	}
     	 if (put_user(baud,(enum bau *)arg)) return -EFAULT;
     	 break;

      case CAN_GET_ERRCOUNT:
          printk("begin can_get_errcount\n");  
      	  err_count=read_err_counter(dev->base_addr);
      	  if (put_user(err_count,(int *)arg)) return -EFAULT;
      	  break;

     case CAN_GET_ERRCAPTURE:
          printk("begin can_get_errcapture\n");  
          err_capture=kmalloc(sizeof(struct err_cap_struct),GFP_KERNEL);
      	  if (copy_from_user(err_capture,(struct err_cap_struct *)arg,
                             sizeof(struct err_cap_struct))) return -EFAULT;
          read_err_capture(err_capture,dev->base_addr); 
     	  if (copy_to_user((struct err_cap_struct *)arg,err_capture,
                        sizeof(struct err_cap_struct))) 
		  return -EFAULT;
          break;
          
      case CAN_GET_ARBCOUNT:
          printk("begin can_get_arbcount\n");  
      	  arb_count=read_arb_counter(dev->base_addr);
      	  if (put_user(arb_count,(int *)arg))
		  return -EFAULT;
      	  break;

      case CAN_GET_ARBCAPTURE:
          printk("begin can_get_abrcapture\n");  
          arb_capture=kmalloc(sizeof(struct arb_cap_struct),GFP_KERNEL);
#if 0
      	  copy_from_user_ret(arb_capture,(struct arb_cap_struct *)arg,
           			sizeof(struct arb_cap_struct),-EFAULT);
#else
      	  if (copy_from_user(arb_capture,(struct arb_cap_struct *)arg,
           					sizeof(struct arb_cap_struct)))
			  return -EFAULT;
#endif
      	  read_arb_capture(arb_capture,dev->base_addr); 
      	  if (copy_to_user((struct arb_cap_struct *)arg,arb_capture,
                            sizeof(struct arb_cap_struct)))
		  return -EFAULT;
          break;

      case CAN_RESET:
          printk("begin can_reset\n");  
      	  reset_CAN(dev->base_addr);
          break;
      default: 
        printk("unkonwn command \n");  
        return -EINVAL;
    }
    return 0;
}

⌨️ 快捷键说明

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