usb驱动在windows系统下只用支持主流的WinXp和Win7,代码就一套,编译出32位和64位两个版本release给用户就ok了。
但在linux系统下就不一样了,众多的linux内核版本,即使常用的2.6.y和3.x.y都有好多种,针对每个版本内核都编译一把显然不现实。我们的做法是直接把驱动源码和Makefile发给客户,让客户自己编译。
但直接源码发给用户显然不符合公司的利益,上周老大让我试试看能不能把源码中核心内容编译成.a的静态库,加上一个.c的空壳release给用户。
当前驱动编译目录中只有三个文件:usb_drv.c(源码文件),usb_drv.h(接口文件,一些自定义的结构体和命令宏),Makefile。
usb_drv.c:
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kref.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/version.h> /*compare kernel version*/
///<<<<<Added compiler support for RHEL6 (2.6.32-71.el6.i686 SMP)
//#include <linux/smp_lock.h>
//<<<<<Added compiler support for Ubuntu12.10 (3.5.0-17-generic SMP)
#include <linux/mutex.h>
DEFINE_MUTEX(os_mutex); // define a mutex
//<<<<<<
#include "usb_drv.h"
......
static int Drv_Open(struct inode *inode, struct file *file)
{
......
}
static int Drv_Close(struct inode *inode, struct file *file)
{
......
}
static ssize_t Drv_Read(struct file *file, char *buffer, size_t count, loff_t *ppos)
{
......
}
static ssize_t Drv_Write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
{
......
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
int Drv_IOCtl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
#else
//<<<<<Added compiler support for Linux kenerl v3.0
int Drv_IOCtl(struct file *file, unsigned int cmd, unsigned long arg)
#endif
{
......
}
static struct file_operations xxx_fops = {
.owner = THIS_MODULE,
.read = Drv_Read,
.write = Drv_Write,
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
.ioctl = Drv_IOCtl,
#else
.unlocked_ioctl = Drv_IOCtl,
.compat_ioctl = Drv_IOCtl,
#endif
.open = Drv_Open,
.release = Drv_Close,
};
static struct usb_class_driver xxx_class = {
.name = "tailm",
.fo