Linux USB驱动程序探测()问题

Linux USB驱动程序探测()问题,linux,linux-kernel,usb,driver,linux-device-driver,Linux,Linux Kernel,Usb,Driver,Linux Device Driver,我目前正在为Seowon SWU-3220A WiMAX USB调制解调器开发内核模式USB驱动程序。这是一个复杂的设备(插入后,它会以USB CDROM的形式出现在系统中,驱动程序需要将其切换到调制解调器模式)。我的问题是从未调用驱动程序中的probe()函数。我认为这是因为操作系统使用标准的usb大容量存储驱动程序,而不是我自己的 我初始化驱动程序如下: #define GDM7213_VENDOR_ID 0x1076 #define GDM7213_PRODUCT_ID 0x7f40 s

我目前正在为Seowon SWU-3220A WiMAX USB调制解调器开发内核模式USB驱动程序。这是一个复杂的设备(插入后,它会以USB CDROM的形式出现在系统中,驱动程序需要将其切换到调制解调器模式)。我的问题是从未调用驱动程序中的probe()函数。我认为这是因为操作系统使用标准的usb大容量存储驱动程序,而不是我自己的

我初始化驱动程序如下:

#define GDM7213_VENDOR_ID 0x1076
#define GDM7213_PRODUCT_ID 0x7f40

static struct usb_device_id gdm7213_table [] = {
    { USB_DEVICE(GDM7213_VENDOR_ID, GDM7213_PRODUCT_ID) },
    { }
};

MODULE_DEVICE_TABLE(usb, gdm7213_table);

static struct usb_driver gdm7213_driver = {
    .name                 = "gdm7213",
    .probe                = gdm7213_probe,
    .disconnect           = gdm7213_disconnect,
    .suspend              = gdm7213_suspend,
    .resume               = gdm7213_resume,
    .pre_reset            = gdm7213_pre_reset,
    .post_reset           = gdm7213_post_reset,
    .id_table             = gdm7213_table,
};

static int gdm7213_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
    printk(KERN_INFO "GDM7213 gdm7213_probe()\n");
    return 0;
}

static int __init gdm7213_init_module(void)
{
    int result;
    printk(KERN_INFO "GDM7213 init_module()\n");

    result = usb_register(&gdm7213_driver);
    if (result)
        err("usb_register failed. Error number %d", result);

    return result;
}

static void __exit gdm7213_cleanup_module(void)
{
    printk(KERN_INFO "GDM7213 cleanup_module()\n");
    usb_deregister(&gdm7213_driver);
}

module_init(gdm7213_init_module);
module_exit(gdm7213_cleanup_module);

有人能告诉我哪里有bug或建议解决方法吗?

如果是USB大容量存储驱动程序在您有机会之前偷走了它,您可能希望将带有该驱动程序的设备的VID/PID列入黑名单

既然你提到了它是一个USB WiMAX适配器,我会有一个大胆的猜测,尽管它是一个USB大容量存储设备,其中包含了Windows上的驱动程序。如果是这样的话,你最好还是使用它,因为它已经为3G调制解调器处理了这个问题。通常,这些设备需要一些神奇的字节(通常是SCSI弹出命令)来说服它们不再是大容量存储设备,而成为真正的调制解调器。(通常也有不同的PID)

即使你的设备不能被说服用一个现有的USB Modeswitch规则来显示真实的设备而不是驱动程序,用它来解决这个问题也比内核破解更合适

与您的建议相比,使用USB Modeswitch具有许多优势:

  • 保持一切模块化:
  • 您的驱动程序只需关心WiMAX和设备的一个VID/PID
  • 大容量存储驱动程序不需要关心疯狂的设备——它看起来就像是在插拔设备。将这些设备中的每一种都教给大容量存储驱动程序是不合适的,因为您的设备似乎不是特例
  • 关于设备人格分裂的知识只与USB Modeswitch有关,USB Modeswitch的存在只是为了解决这个问题
  • 它不会破坏设备的USB大容量存储功能——出于某种原因,用户可能希望在Linux下查看Windows驱动程序,将此设备列入黑名单将使之无法实现。如果您最终也在Linux下使用Windows驱动程序附带的某些固件,这可能很重要
  • 它遵循现有设置,并将更改保留在模块的本地。如果你想让你的驱动程序在主线内核中运行,这可能很重要

  • 你能解释一下黑名单吗?谢谢你的回答。我将尝试使用usb_modeswitch,但我仍然需要内核驱动程序,因为linux内核还不支持这个设备。我认为通过驱动程序进行切换比通过usb_modeswitch更优雅。我仍然会编写一个内核驱动程序,但我会基于这样的假设来编写它,即该设备显示了“真实的”PID/VID,而不必担心它在首次插入时的大容量存储外观。(几乎)与windows驱动程序一起唱歌跳舞的所有其他设备的行为都是这样的,并且USB大容量存储驱动程序不需要知道那些会改变其想法的疯狂设备。看: