linux驱动错误: 初始值设定…

来源:互联网 发布:mac压缩包解压错误 编辑:程序博客网 时间:2024/05/01 22:39
这个错误网上搜索发现3.0.0.15版本内核file_operation结构体已经删除了ioctl函数,取代的是:
long (*unlocked_ioctl) (struct file *, unsigned int, unsignedlong);
long (*compat_ioctl) (struct file *, unsigned int, unsignedlong);

file_operation结构体在/usr/src/linux-3.0.0.15/include/linux/fs.h定义。

 

[plain] viewplaincopyprint?
  1. 1546 struct file_operations  
  2. 1547         struct module *owner;  
  3. 1548         loff_t (*llseek) (struct file *, loff_t, int);  
  4. 1549         ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);  
  5. 1550         ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);  
  6. 1551         ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);  
  7. 1552         ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);  
  8. 1553         int (*readdir) (struct file *, void *, filldir_t);  
  9. 1554         unsigned int (*poll) (struct file *, struct poll_table_struct *);  
  10. 1555         long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);  
  11. 1556         long (*compat_ioctl) (struct file *, unsigned int, unsigned long);  
  12. 1557         int (*mmap) (struct file *, struct vm_area_struct *);  
  13. 1558         int (*open) (struct inode *, struct file *);  
  14. 1559         int (*flush) (struct file *, fl_owner_t id);  
  15. 1560         int (*release) (struct inode *, struct file *);  
  16. 1561         int (*fsync) (struct file *, int datasync);  
  17. 1562         int (*aio_fsync) (struct kiocb *, int datasync);  
  18. 1563         int (*fasync) (int, struct file *, int);  
  19. 1564         int (*lock) (struct file *, int, struct file_lock *);  
  20. 1565         ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);  
  21. 1566         unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);  
  22. 1567         int (*check_flags)(int);  
  23. 1568         int (*flock) (struct file *, int, struct file_lock *);  
  24. 1569         ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);  
  25. 1570         ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);  
  26. 1571         int (*setlease)(struct file *, long, struct file_lock **);  
  27. 1572         long (*fallocate)(struct file *file, int mode, loff_t offset,  
  28. 1573                           loff_t len);  
  29. 1574 };  

2.6.30.4中file_operation的定义如下:

 

 

[plain] viewplaincopyprint?
  1. 1484 struct file_operations  
  2. 1485         struct module *owner;  
  3. 1486         loff_t (*llseek) (struct file *, loff_t, int);  
  4. 1487         ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);  
  5. 1488         ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);  
  6. 1489         ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);  
  7. 1490         ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);  
  8. 1491         int (*readdir) (struct file *, void *, filldir_t);  
  9. 1492         unsigned int (*poll) (struct file *, struct poll_table_struct *);  
  10. 1493         int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);  
  11. 1494         long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);  
  12. 1495         long (*compat_ioctl) (struct file *, unsigned int, unsigned long);  
  13. 1496         int (*mmap) (struct file *, struct vm_area_struct *);  
  14. 1497         int (*open) (struct inode *, struct file *);  
  15. 1498         int (*flush) (struct file *, fl_owner_t id);  
  16. 1499         int (*release) (struct inode *, struct file *);  
  17. 1500         int (*fsync) (struct file *, struct dentry *, int datasync);  
  18. 1501         int (*aio_fsync) (struct kiocb *, int datasync);  
  19. 1502         int (*fasync) (int, struct file *, int);  
  20. 1503         int (*lock) (struct file *, int, struct file_lock *);  
  21. 1504         ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);  
  22. 1505         unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);  
  23. 1506         int (*check_flags)(int);  
  24. 1507         int (*flock) (struct file *, int, struct file_lock *);  
  25. 1508         ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);  
  26. 1509         ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);  
  27. 1510         int (*setlease)(struct file *, long, struct file_lock **);  
  28. 1511 };  

在file_operation 赋值处修改:
.unlocked_ioctl = xxx_ioctl
那么,.unlocked_ioctl和compat_ioctl有什么区别呢:
long (*unlocked_ioctl) (struct file *filp, unsigned int cmd,                             unsigned long arg);

If a driver or filesystem providesan unlocked_ioctl() method,it will be called in preference to theolder ioctl(). The differences are thattheinode argument is not provided (it'savailableas filp->f_dentry->d_inode) and theBKL is not taken prior to the call. All new code should be writtenwith its own locking, and shoulduse unlocked_ioctl(). Old code should beconverted as time allows. For code which must run on multiplekernels, there is anew HAVE_UNLOCKED_IOCTL macrowhich can be tested to see if the newer method is available ornot.

Michael's patch adds one other operation:

 

    long (*compat_ioctl) (struct file *filp, unsigned int cmd,                           unsigned long arg);

If this method exists, it will be called (without the BKL) whenevera 32-bit processcalls ioctl() on a64-bit system. It should then do whatever is required to convertthe argument to native data types and carry out the request.If compat_ioctl() is notprovided, the older conversion mechanism will be used, as before.The HAVE_COMPAT_IOCTL macrocan be tested to see if this mechanism is available on any givenkernel.

The compat_ioctl() methodwill probably filter down into a few subsystems. Andi Kleen hasposted patches addingnew compat_ioctl() methodstothe block_device_operations and scsi_host_template structures,for example, though those patches have not been merged as of thiswriting.


PS:

1、消失的时间

ioctl消失的版本是v2.6.35到v2.6.36-rc1间

2、消失的原因

  简单的概括:这次ioctl的消失,并不是要把ioctl清理出去,而是要逐步的清理大内核锁(BKL)。

  这个让ioctl消失的过渡期长达5年,从2005年开始内核黑客就开始替换ioctl了。具体的原因lwn.net中有一篇很好的文章:The new way ofioctl()。我将他翻译了一下:ioctl()的新方法(必看)

当然,顺便了解一下大内核锁也是很有必要的:转载好文:《大内核锁将何去何从》

对于原来的ioctl,其实可以叫做lockedioctl。这个其实是相对于他的替代方法来讲的

3、在驱动编程时的注意事项

  • 在注册文件操作方法的结构体structfile_operations的时候原先的.ioctl=OOXX;替换为.unlocked_ioctl=OOXX;

但是要注意ioctl和unlocked_ioctl的定义有一点不同:unlocked_ioctl少了一个inode参数。但是如果方法中真的需要其中的数据,可以通过filp->f_dentry->d_inode获得。

  • 由于失去了大内核锁的保护,所以必须unlocked_ioctl方法中自行实现锁机制,以保证不会在操作设备的时候(特别在SMP系统中)产生竞态。(也就实现了用小锁替换大锁)







0 0