Problem: The huawei_cdc_ncm driver (for the 4G LTE dongle Huawei E3276) gets unregistered and the control device /dev/cdc-wdmN disappears after sending exactly 121 AT commands to the device. After a few seconds, the driver is re-registered and the control device reappears. Test program causing the error included at the end of this message. Keywords: huawei_cdc_ncm, LTE, AT commands, cdc-wdm Detailed problem description: The behavior has been verified on kernel 3.16.0 and on kernel 3.17.1, on a 64-bit Core i5 x86 machine and on a a smaller embedded 32-bit x86 machine. Exact command does not matter, used 'ATI' and 'AT^HCSQ?' with same result. Distros used are Kubuntu 14.04.1 LTS on the i5 and Debian Wheezy on the embedded machine. Kernel modules: huawei_cdc_ncm, cdc_ncm The test program contains some rudimentary C++ but should be readable even to die-hard C guys ;) The program is crude but hopefully useful for debugging. If more info is needed, let me know and I will provide it. Best regards, /Erik Alapää // // Program that causes temporary loss of cdc-wdmN device and huawei_cdc_ncm // driver reload after 121 AT commands sent. // // No makefile, just compile with 'g++ -g wdm_err.cpp -o wdm_err'. // // Usage, see 'Usage: ' message in the code below. // #include <cstdio> #include <cstdlib> #include <cerrno> #include <cstring> #include <sys/time.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <stdexcept> #include <string> #include <iostream> #include <fstream> using std::string; using std::cout; using std::runtime_error; using std::endl; using std::fstream; int main(int argc, char* argv[]) { fd_set rfds; fd_set wfds; struct timeval tv; struct timeval tv2; int retval; int n; const int SZ = 512; char errbuf[SZ]; char ctrlin_buf[SZ]; //string command("AT^HCSQ?\n"); string command("ATI\n"); string response; string resp_line; fstream at_file; int sleep_us = 0; int sendcount = 0; char CTRL_DEVICE[SZ]; // Get file descriptor for select() if (argc == 3) { cout << "Setting AT ctrl device to \'" << argv[1] << "\'\n"; strcpy(CTRL_DEVICE, argv[1]); cout << "Sleep interval " << sleep_us << " us\n"; } else { cout << "Usage: rw2 <at-ctrl-device> <sleeptime in us> (ctrl is typically /dev/cdc-wdmN)\n\n"; throw std::runtime_error("Too few args, no ctrl device specified!"); } int ctrl = open(CTRL_DEVICE, O_RDWR); if (ctrl == -1) { throw std::runtime_error(strerror_r(errno, errbuf, SZ)); } sleep_us = atoi(argv[2]); // Get fstream for C++-style reading and writing at_file.open(CTRL_DEVICE, std::fstream::in | std::fstream::out | std::fstream::app); if (!at_file) { throw runtime_error("Could not open wdm device file!\n"); } for (;;) { tv.tv_sec = 10; tv.tv_usec = 0; FD_ZERO(&rfds); FD_SET(ctrl, &rfds); FD_ZERO(&wfds); FD_SET(ctrl, &wfds); if (at_file.bad()) { throw runtime_error("wdm device file gone bad!"); } tv2.tv_sec = 0; tv2.tv_usec = sleep_us; retval = select(0, NULL, NULL, NULL, &tv2); // sleep if (retval == -1) { throw std::runtime_error(strerror_r(errno, errbuf, SZ)); } retval = select(ctrl+1, &rfds, &wfds, NULL, &tv); if (retval == -1) { throw std::runtime_error(strerror_r(errno, errbuf, SZ)); } if (at_file.bad()) { throw runtime_error("wdm device file gone bad!"); } if (FD_ISSET(ctrl, &wfds)) { cout << "Writing command \'" << command << "\' to ctrl device\n"; command += "\r"; at_file << command << endl; cout << sendcount++; } if (FD_ISSET(ctrl, &rfds)) { n = read(ctrl, ctrlin_buf, SZ); // ifstrem::read fails for some reason if (n == -1) { throw std::runtime_error(strerror_r(errno, errbuf, SZ)); } response = std::string(ctrlin_buf, n); cout << response << endl; } } return 0; } -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html