As a word of warning to those looking to use the S2.11N2.18 recently released, I believe that there is a bug in the locking of disc_mutex in the GobiSerial driver whereby a race condition is introduced with a second thread that is holding the mutex. Use this version with extreme caution.
Specifically, this is the code segment that has me concerned:
$ vim GobiSerial/GobiSerial.c
...
346 /* only send down the usb control message if enabled */
347 if (serial->dev && flow_control) {
348 int already_locked = mutex_is_locked(&serial->disc_mutex); <<<
349 if (!already_locked)
350 mutex_lock(&serial->disc_mutex);
...
The problem is that other threads can lock serial->disc_mutex prior to the Gobi_dtr_rts() function being called. This results in a race condition where Gobi_dtr_rts() can improperly ignore the existing lock on serial->disc_mutex.
I welcome any data or analysis that proves this concern false, but a grep of “disc_mutex” in the drivers directory of a vanilla kernel’s source shows that it is locked and unlocked several different places in the usbserial hierarchy:
$ grep -R disc_mutex kernel-3.4.42/drivers/usb/serial/
drivers/usb/serial/usb-serial.c: * disconnected, return with its disc_mutex held and its refcount
drivers/usb/serial/usb-serial.c: mutex_lock(&serial->disc_mutex);
drivers/usb/serial/usb-serial.c: mutex_unlock(&serial->disc_mutex);
drivers/usb/serial/usb-serial.c: mutex_unlock(&serial->disc_mutex);
drivers/usb/serial/usb-serial.c: mutex_unlock(&serial->disc_mutex);
drivers/usb/serial/usb-serial.c: mutex_lock(&serial->disc_mutex);
drivers/usb/serial/usb-serial.c: mutex_unlock(&serial->disc_mutex);
drivers/usb/serial/usb-serial.c: mutex_lock(&serial->disc_mutex);
drivers/usb/serial/usb-serial.c: mutex_unlock(&serial->disc_mutex);
drivers/usb/serial/usb-serial.c: mutex_unlock(&serial->disc_mutex);
drivers/usb/serial/usb-serial.c: mutex_init(&serial->disc_mutex);
drivers/usb/serial/usb-serial.c: mutex_lock(&serial->disc_mutex);
drivers/usb/serial/usb-serial.c: mutex_unlock(&serial->disc_mutex);
drivers/usb/serial/usb-serial.c: mutex_lock(&serial->disc_mutex);
drivers/usb/serial/usb-serial.c: mutex_unlock(&serial->disc_mutex);
Chris