两个相同VID PID的不同设备加载同一个KO文件中的不同驱动
两个相同VID PID的不同设备加载同一个KO文件中的不同驱动
问题:Realtek两个不同芯片的USB-TO-ETHERNET,PID VID都同为:8152。因为客户手中已经有一部分老的产品了,目前停产,新的产品使用不同的芯片。
需求:USB-TO-ETHERNET只是我们的外围设备的一部分,所以要求不管客户使用哪一个设备接进来,都能和主机搭配工作。
解决方案概述:
1,这是USB设备,所以通用USB接口标准会读取其设备描述。找出两种设备的关键不同点,我们的情况是:新旧设备的bNumConfigurations值不同,一个是1,另一个是2。
2,将驱动名统一为8152,跟据bNumConfigurations不同,加载不同的函数即可;
过程和代码:
1,先将新设备的驱动加入到kernel中,并确认新的驱动配新的设备可以工作。老的设备就不用说了,因为已经在工作中。
2,PIDVID加载时,只认一个驱动的名字。我这里设为“rtl8152”,所以驱动入口也只有一个。
static struct usb_driver rtl8152_driver = {
.name= MODULENAME,
.probe= rtl8152_probe,
.disconnect= rtl8152_disconnect,
.id_table= rtl8152_table,
.suspend= rtl8152_suspend,
.resume= rtl8152_resume
};
static int __init usb_rtl8152_init(void)
{
returnusb_register(&rtl8152_driver);
}
static void __exit usb_rtl8152_exit(void)
{
usb_deregister(&rtl8152_driver);
}
接下来要区分不同的设备执行不同的函数了。
贴代码最实际:
static int rtl8152_probe(structusb_interface *intf,
const struct usb_device_id *id)
{
structusb_device *udev = interface_to_usbdev(intf);
rtl8152_t*tp;
structnet_device *netdev;
usb_driver_set_configuration(udev,1);
return-ENODEV;
}
if(udev->descriptor.bNumConfigurations==1)
rtl815x=1;//--------------当bNumConfigurations为1时执行老驱动的函数;
else
rtl815x=2;//--------------当bNumConfigurations为其它时执行新驱动的函数;
netdev= alloc_etherdev(sizeof(rtl8152_t));
if(!netdev) {
printk("Outof memory");
return-ENOMEM;
}
tp= netdev_priv(netdev);
tp->msg_enable= 0x7FFF;
tp->intr_buff= kmalloc(INTBUFSIZE, GFP_KERNEL);
if(!tp->intr_buff) {
free_netdev(netdev);
return-ENOMEM;
}
if(rtl815x==1)//老驱动
{
tasklet_init(&tp->tl,r8152u_rx_fixup, (unsigned long)tp);
spin_lock_init(&tp->rx_pool_lock);
INIT_DELAYED_WORK(&tp->schedule,r8152u_rtl_work_func_t);
tp->udev= udev;
tp->netdev= netdev;
#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,29)
netdev->netdev_ops= &rtl8152_netdev_ops;
#else
netdev->open= rtl8152u_open;
netdev->stop= rtl8152u_close;
netdev->get_stats= rtl8152u_get_stats;
netdev->hard_start_xmit= rtl8152u_start_xmit;
netdev->tx_timeout= rtl8152u_tx_timeout;
// netdev->change_mtu = eth_change_mtu;
netdev->set_mac_address= rtl8152u_set_mac_address;
netdev->do_ioctl= rtl8152u_ioctl;
netdev->set_multicast_list= rtl8152u_set_rx_mode;
#endif /* HAVE_NET_DEVICE_OPS */
netdev->watchdog_timeo= RTL8152_TX_TIMEOUT;
netdev->features&= ~NETIF_F_IP_CSUM;
SET_ETHTOOL_OPS(netdev,&r8152u_ops);
tp->intr_interval= 100; /* 100ms */
if(!r8152u_alloc_all_urbs(tp)) {
err("outof memory");
gotoout;
}
if(!rtl8152u_reset(tp)) {
err("couldn'treset the device");
gotoout1;
}
r8152u_fill_skb_pool(tp);
rtl8152u_set_ethernet_addr(tp);
}
else
{//新驱动
tasklet_init(&tp->tl,rx_fixup, (unsigned long)tp);
INIT_DELAYED_WORK(&tp->schedule,rtl_work_func_t);
tp->udev= udev;
tp->netdev= netdev;
#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,29)
netdev->netdev_ops= &rtl8152_netdev_ops;
#else
netdev->open= rtl8152_open;
netdev->stop= rtl8152_close;
netdev->get_stats= rtl8152_get_stats;
netdev->hard_start_xmit= rtl8152_start_xmit;
netdev->tx_timeout= rtl8152_tx_timeout;
// netdev->change_mtu = eth_change_mtu;
netdev->set_mac_address= rtl8152_set_mac_address;
netdev->do_ioctl= rtl8152_ioctl;
netdev->set_multicast_list= rtl8152_set_rx_mode;
#endif /* HAVE_NET_DEVICE_OPS */
netdev->watchdog_timeo= RTL8152_TX_TIMEOUT;
netdev->features&= ~NETIF_F_IP_CSUM;
SET_ETHTOOL_OPS(netdev,&ops);
tp->intr_interval= 100; /* 100ms */
tp->speed= 0;
r8152b_init(tp);
if(!alloc_all_urbs(tp)) {
printk("outof memory");
gotoout;
}
tp->rx_skb= netdev_alloc_skb_ip_align(netdev, RTL8152_MTU + sizeof(RxDesc));
if(!tp->rx_skb)
gotoout1;
}
usb_set_intfdata(intf,tp);
SET_NETDEV_DEV(netdev,&intf->dev);
if(register_netdev(netdev) != 0) {
printk("couldn'tregister the device");
gotoout2;
}
dev_info(&intf->dev,"%s: rtl8152 is detected\n", netdev->name);
return0;
out2:
usb_set_intfdata(intf,NULL);
if(rtl815x==1)
{
r8152u_free_skb_pool(tp);
}
else
{
dev_kfree_skb(tp->rx_skb);
}
out1:
if(rtl815x==1)
{
r8152u_free_all_urbs(tp);
}
else
{
free_all_urbs(tp);
}
out:
kfree(tp->intr_buff);
free_netdev(netdev);
return-EIO;
}
static void rtl8152_disconnect(structusb_interface *intf)
{
rtl8152_t*tp = usb_get_intfdata(intf);
usb_set_intfdata(intf,NULL);
if(tp) {
set_bit(RTL8152_UNPLUG,&tp->flags);
tasklet_kill(&tp->tl);
unregister_netdev(tp->netdev);
if(rtl815x==1)
{
r8152u_unlink_all_urbs(tp);
r8152u_free_all_urbs(tp);
r8152u_free_skb_pool(tp);
}
else
{
free_all_urbs(tp);
}
if(tp->rx_skb)
dev_kfree_skb(tp->rx_skb);
kfree(tp->intr_buff);
free_netdev(tp->netdev);
}
}
/* table of devices that work with thisdriver */
static struct usb_device_id rtl8152_table[]= {//这个就一样了,就是因为这个PIDVID相同才到//这地步了
{USB_DEVICE_VER(VENDOR_ID_REALTEK,PRODUCT_ID_RTL8152, 0x2000, 0x2000)},
// {USB_DEVICE(VENDOR_ID_REALTEK,PRODUCT_ID_RTL8152)},
{}
};
MODULE_DEVICE_TABLE(usb, rtl8152_table);
其它函数和变量同样可以用全局变量:rtl815x==1/2来区分。再贴代码就没什么意义了。
因为只有一个设备名,和入口函数,系统注册加载时就当一个驱动来加载。只是按不同设备的参数执行不同函数罢了。
两个相同VID PID的不同设备加载同一个KO文件中的不同驱动相关推荐
- MTK6592平台 touchpanel驱动设备加载(一)
前言: 从事android驱动调试工作已有一年多了,之前一直没有系统的看一下内核,正好这几个月有时间,整理了一下关于内核中对设备.驱动的调用关系,目前我是在mtk6592 kk 平台以touchpan ...
- 如果在一个工程中有两个vhd文件,就相当于有两个模块,那么对于这个工程整体的bdf文件生成,怎么把这两个模块都加到同一个bdf文件中。bdf文件中两个模块之间的连线及输入输出,是自己输进去的还是自动生
如果在一个工程中有两个vhd文件,就相当于有两个模块,那么对于这个工程整体的bdf文件生成,怎么把这两个模块都加到同一个bdf文件中.bdf文件中两个模块之间的连线及输入输出,是自己输进去的还是自动生 ...
- 设备栈中各个设备加载顺序
如题,这是前几天某同事问我的问题.他假设设备栈中有Pdo,Fdo,以及附属于Fdo的设备上下过滤驱动以及类上下过滤驱动,在这种情况下,OS会以怎样的顺序加载这些设备? 我第一反应是当然先加载Fdo,然 ...
- MTK6592平台 touchpanel驱动设备加载(三)
项目初期对新的IC供应商压求: 1,各个片脚的电压域,待机和工作时候的电压必须在BB端端口电压域范围 2,中断触发方式,我们要求是下降沿触发,必须要改 3,flash分区情况和大小 4,flash是否 ...
- VirtualBox 下USB 设备加载的步骤及无法加载的解决办法
1. 将u盘插入电脑,在windows能够识别后,进入VirtualBox的选定要加载的虚拟机,选择设置-->选择usb设备项 2. 选择右边的第一或者是第二个图标,增加一个新的筛选器,第一个图 ...
- 两个class写在同一个java文件中
第一种: 一个public类,多个非public类,例如:public class A{}class B{}第二个class前面不能加public. 第二种: 第二种是内部类,写在公共类体里面的,例如 ...
- MTK6592平台 touchpanel驱动设备加载(二)
关于设备驱动加载,我这边整理出的函数调用关系流程图见下,主要为了解释进程如何调用驱动里面的probe函数
- 如何在inf文件中修改pid、vid
Inf文件即Device Information File(设备信息文件),用于引导驱动程序(*.sys)的安装.它实质上是一个文本文件,可以用记事本工具打开查看和编辑. 简单介绍一下USB设备驱动程 ...
- Linux查看U盘的Vid,CheckUDisk(查看USB的VID/PID/厂商信息)v5.4
CheckUDisk是一个免费的USB存储设备检测工具,能查看诸如USB存储设备名称.盘符.VID&PID.序列号.制造商信息.产品信息.版本.传输速度等连接到PC上的U盘信息.支持Win98 ...
最新文章
- 从未在一起更让人遗憾_我们从未在一起和我们最终没在一起,哪一个更让人难过?...
- [转]机器学习和深度学习资料汇总【01】
- Python 'takes exactly 1 argument (2 given)' Python error
- JZOJ 5431. 【NOIP2017提高A组集训10.28】序列操作
- golang PHP的区别,erlang和golang的区别
- ubuntu下数据库的导入导出
- 我被认定为高层次人才了!
- ubuntu安装宝塔界面
- 智百威收银系统服务器连接不上,收银系统进入不了收银系统怎么办 – 手机爱问...
- UniWebview Bug处理记录
- Cisco Packet Tracer中配置链路聚合
- 车载以太网交换机功能和应用案例汇总, 适用于AVB/TSN, 802.1AS(gPTP时钟同步)
- 微信小程序流量主广告怎么加圆角
- 计算机无法对NAS硬盘操作,群晖NAS联机失败不要慌,我用经验告诉你,这样做就能完美解决...
- Date与Calander使用及异同
- linux桌面支持hdpi,用于HiDPI显示器的最佳Linux桌面环境 | MOS86
- 以太坊源码分析-同步之Syncing接口
- 【音视频相关】nvidia-smi 命令扩展及问题分析举例(dmon/pmon/GPU性能相关)
- 注册表编辑器被改这样恢复
- Java对接HJ212协议设备