Проблема с USB-драйвером Linux () - PullRequest
3 голосов
/ 28 сентября 2011

В настоящее время я работаю над драйвером USB в режиме ядра для USB-модема Seowon SWU-3220A WiMAX. Это сложное устройство (после подключения оно появляется в системе как 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);

Кто-нибудь может сказать мне, где ошибка или предложить какой-нибудь обходной путь?

1 Ответ

6 голосов
/ 28 сентября 2011

Если это драйвер запоминающего устройства USB, который крадет его, прежде чем вы получите шанс, вы можете занести в черный список VID / PID для устройства с этим драйвером.

Поскольку вы упомянули, что это адаптер USB WiMAX, у меня будет странное предположение, что он представляет запоминающее устройство USB, которое содержит драйвер для него в Windows. Если это так, вам лучше работать с USB Modeswitch , который уже справляется с этим для 3G модемов. Обычно устройства ожидают, что некоторые магические байты (которые часто являются командами извлечения SCSI) убедят их перестать быть устройствами хранения данных и стать настоящим модемом. (Это обычно имеет другой PID).

Даже если ваше устройство нельзя убедить показать реальное устройство вместо драйвера с одним из существующих правил USB Modeswitch, было бы более уместно решить проблему с этим, чем взломать ядро.

Выполнение этого с помощью USB Modeswitch имеет ряд преимуществ по сравнению с тем, что вы предложили:

  1. Сохраняет все модульным:
    1. Ваш драйвер должен заботиться только о WiMAX и одном VID / PID для устройства
    2. Драйверу запоминающего устройства не нужно заботиться о сумасшедших устройствах - это просто похоже на подключение и отключение устройства. Изучение драйвера запоминающего устройства для каждого из этих устройств не подходит, ваше устройство, кажется, не является особым случаем.
    3. Знания о разделенных личностях устройства относятся только к USB-модовому переключателю, который существует только для решения этой проблемы.
  2. Это не нарушает аспекты устройства хранения данных на USB-накопителе - пользователи могут по какой-то причине захотеть просмотреть драйвер Windows под Linux, занесение в черный список этого устройства сделает это невозможным. Это может быть важно, если в конечном итоге вы также используете какую-либо прошивку, поставляемую с драйвером Windows под Linux.
  3. Это соответствует существующей настройке и сохраняет ваши изменения локально для вашего модуля. Это может быть важно, если вы когда-нибудь захотите получить свой драйвер в основном ядре.
...