w23

mos7840 с ядрами >=2.6.26.3

Mar 03, 2009 16:45

С ума можно сойти, что я вам хочу сказать-то:
Намедни столкнулся с неприятным ядерным багом #11585, суть которого сводится к тому, что в ядрах после 2.6.26.3 USB->serial конверторы на базе mos7840 стали вести себя, как говно. А именно: слать всякий мусор, вместо того, что надо, и сегфолтить ядро при отключении модуля/устройства. Происходит это из-за жидов долбоебовновой строчки "serial->minor = SERIAL_TTY_NO_MINOR;" в функции create_serial() файла drivers/usb/serial/usb-serial.c. Эта строчка решает другой баг, который мне видеть не приходилось, но если я понимаю его суть, то связан он с тем, что при каком-нибудь провале на стадии инициализации конвертора, до того, как ему выдадут minor, существующий невыданный minor (равный на этой стадии 0) будет высвобожден. Когда он не занят. Лол. Поэтому они решили пометить не выданный minor как SERIAL_TTY_NO_MINOR. И всё бы хорошо, но модуль mos7840 этот самый minor использует в функции attach() (функция mos7840_startup() в файле drivers/usb/serial/mos7840.c), а вызов attach() происходит еще до того, как minor будет выдан. БАБАХ! Баг не проявлял себя раньше из-за того, что все ленивые долбоебы и нихуя не тестируют при наличии только одного конвертора ему как раз и выдается minor = 0. А теперь получается, что во время attach() minor == SERIAL_TTY_NO_MINOR, а после инициализации он уже другой. Драйверу это, разумеется, не нравится, ему плохеет и всё взрывается к чертям.
Патч для этой ситуации очень простой - выдать minor до вызова attach(). Ну или можно покопаться в ужаснейшем коде mos7840 (который изобилует комментариями вида ".................." и " !!!") и понять, зачем же ему там minor нужен. Что более правильно, но мне было лень.

Простой патч выглядит так:

--- linux.orig/drivers/usb/serial/usb-serial.c 2009-02-24 14:26:15.000000000 +0600 +++ linux/drivers/usb/serial/usb-serial.c 2009-03-03 15:05:41.000000000 +0600 @@ -908,6 +908,12 @@ } else if (num_interrupt_out) { dbg("the device claims to support interrupt out transfers, but write_int_callback is not defined"); } + + if (get_free_serial (serial, num_ports, &minor) == NULL) { + dev_err(&interface->dev, "No more free serial devices\n"); + goto probe_error; + } + serial->minor = minor; /* if this device type has an attach function, call it */ if (type->attach) { @@ -926,12 +932,6 @@ } } - if (get_free_serial (serial, num_ports, &minor) == NULL) { - dev_err(&interface->dev, "No more free serial devices\n"); - goto probe_error; - } - serial->minor = minor; - /* register all of the individual ports with the driver core */ for (i = 0; i < num_ports; ++i) { port = serial->port[i];

Тут встает тот же вопрос, который должен был встать у авторов патча, закоммиченного в 2.6.26.3: не сломает ли это что-нибудь еще? Протестируйте, пожалуйста, если есть на чём.

me, linux, tech

Previous post Next post
Up
[]