Recently, we tried to compile the GobiNet drivers for Linux on an Ubuntu 16.04 64bit machine.
The version of GobiNet
was GobiNet_2016-10-20.tar.gz ([download id=”2179″]).
To our surprise, we got a errors while compiling.
Solution:
Get the full project after it was patched from here: [download id=”3342″]
or
Download the following patched version of QMIDevice.c
and replace it on your machine [download id=”2183″].
Download the following patched version of GobiUSBNet.c
and replace it on your machine [download id=”3352″].
Errors/Warnings:
First warning: return from incompatible pointer type [-Wincompatible-pointer-types] (GobiUSBNet.c:1692:13)
We got the following warning:
module_exit(GobiUSBNetModExit); ^ include/linux/module.h:135:11: note: in definition of macro ‘module_exit’ { return exitfn; } \
module_exit is defined as follows:
typedef void (*exitcall_t)(void); #define module_exit(exitfn) \ static inline exitcall_t __exittest(void) \ { return exitfn; } \ void cleanup_module(void) __attribute__((alias(#exitfn)));
So we see that we need to update static int GobiUSBNetModExit(void)
to become static void GobiUSBNetModExit(void)
and have it return nothing.
GobiUSBNet.c:1669 @@ -1666,11 +1666,11 @@ RETURN VALUE: void ===========================================================================*/ // static int GobiUSBNetModExit(struct platform_device *pdev) -static int GobiUSBNetModExit(void) +static void GobiUSBNetModExit(void) { usb_deregister( &GobiNet ); class_destroy( gpClass ); - return 0; + return; }
Second warning: passing argument 1 of ‘atomic_read’ from incompatible pointer type [-Wincompatible-pointer-types] (QMIDevice.c:2393:21)
On this 64bit
architecture the f_count
of the struct file
is defined as long (64bit) so we should not use atomic_read
but atomic_long_read
instead.
@@ -2390,7 +2390,7 @@ int UserspaceClose( } // Fallthough. If f_count == 1 no need to do more checks - if (atomic_read( &pFilp->f_count ) != 1) + if (atomic_long_read( &pFilp->f_count ) != 1)^M { rcu_read_lock(); for_each_process( pEachTask )
First error: ‘struct file’ has no member named ‘f_dentry’ (in 9 placed of QMIDevice.c)
The error was error: struct file
has no member named f_dentry
Apparently, there was a change in the struct that contained f_dentry
in the kernel 3.19 source code which created this bug.
@@ -2269,7 +2269,7 @@ int UserspaceIOCTL( if (IsDeviceValid( pFilpData->mpDev ) == false) { DBG( "Invalid device! Updating f_ops\n" ); - pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; + pFilp->f_op = pFilp->f_path.dentry->d_inode->i_fop;^M return -ENXIO; } @@ -2427,7 +2427,7 @@ int UserspaceClose( if (IsDeviceValid( pFilpData->mpDev ) == false) { DBG( "Invalid device! Updating f_ops\n" ); - pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; + pFilp->f_op = pFilp->f_path.dentry->d_inode->i_fop;^M return -ENXIO; } @@ -2486,7 +2486,7 @@ ssize_t UserspaceRead( if (IsDeviceValid( pFilpData->mpDev ) == false) { DBG( "Invalid device! Updating f_ops\n" ); - pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; + pFilp->f_op = pFilp->f_path.dentry->d_inode->i_fop;^M return -ENXIO; } @@ -2567,7 +2567,7 @@ ssize_t UserspaceWrite( if (IsDeviceValid( pFilpData->mpDev ) == false) { DBG( "Invalid device! Updating f_ops\n" ); - pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; + pFilp->f_op = pFilp->f_path.dentry->d_inode->i_fop;^M return -ENXIO; } @@ -2646,7 +2646,7 @@ unsigned int UserspacePoll( if (IsDeviceValid( pFilpData->mpDev ) == false) { DBG( "Invalid device! Updating f_ops\n" ); - pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; + pFilp->f_op = pFilp->f_path.dentry->d_inode->i_fop;^M return POLLERR; } @@ -3003,9 +3003,9 @@ void DeregisterQMIDevice( sGobiUSBNet * pDev ) for (count = 0; count < pFDT->max_fds; count++) { pFilp = pFDT->fd[count]; - if (pFilp != NULL && pFilp->f_dentry != NULL) + if (pFilp != NULL && pFilp->f_path.dentry != NULL)^M { - if (pFilp->f_dentry->d_inode == pOpenInode) + if (pFilp->f_path.dentry->d_inode == pOpenInode)^M { // Close this file handle rcu_assign_pointer( pFDT->fd[count], NULL ); @@ -3050,9 +3050,9 @@ void DeregisterQMIDevice( sGobiUSBNet * pDev ) for (count = 0; count < pFDT->max_fds; count++) { pFilp = pFDT->fd[count]; - if (pFilp != NULL && pFilp->f_dentry != NULL) + if (pFilp != NULL && pFilp->f_path.dentry != NULL)^M { - if (pFilp->f_dentry->d_inode == pOpenInode) + if (pFilp->f_path.dentry->d_inode == pOpenInode)^M { // Close this file handle rcu_assign_pointer( pFDT->fd[count], NULL );
—
Following is the original output of the make
commands before and while we were patching the source files.
george@ubuntu-1604:~/Downloads$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04.1 LTS Release: 16.04 Codename: xenial george@ubuntu-1604:~/Downloads$ wget https://portland.source.codeaurora.org/patches/quic/gobi/Gobi_Linux/GobiNet_2016-10-20.tar.gz --2017-04-24 10:05:54-- https://portland.source.codeaurora.org/patches/quic/gobi/Gobi_Linux/GobiNet_2016-10-20.tar.gz Resolving portland.source.codeaurora.org (portland.source.codeaurora.org)... 198.145.29.80 Connecting to portland.source.codeaurora.org (portland.source.codeaurora.org)|198.145.29.80|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 43818 (43K) [application/x-gzip] Saving to: ‘GobiNet_2016-10-20.tar.gz’ GobiNet_2016-10-20.tar 100%[===========================>] 42,79K 111KB/s in 0,4s 2017-04-24 10:05:56 (111 KB/s) - ‘GobiNet_2016-10-20.tar.gz’ saved [43818/43818] george@ubuntu-1604:~/Downloads$ tar -xzf GobiNet_2016-10-20.tar.gz george@ubuntu-1604:~/Downloads$ cd gobiusbnet/ george@ubuntu-1604:~/Downloads/gobiusbnet$ make rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module.* modules.order make -C /lib/modules/4.4.0-57-generic/build M=/home/george/Downloads/gobiusbnet modules make[1]: Entering directory '/usr/src/linux-headers-4.4.0-57-generic' CC [M] /home/george/Downloads/gobiusbnet/qmap.o CC [M] /home/george/Downloads/gobiusbnet/GobiUSBNet.o In file included from include/linux/phy.h:22:0, from include/net/dsa.h:19, from include/linux/netdevice.h:44, from include/linux/etherdevice.h:26, from /home/george/Downloads/gobiusbnet/Structs.h:47, from /home/george/Downloads/gobiusbnet/GobiUSBNet.c:57: /home/george/Downloads/gobiusbnet/GobiUSBNet.c: In function ‘__exittest’: /home/george/Downloads/gobiusbnet/GobiUSBNet.c:1692:13: warning: return from incompatible pointer type [-Wincompatible-pointer-types] module_exit(GobiUSBNetModExit); ^ include/linux/module.h:135:11: note: in definition of macro ‘module_exit’ { return exitfn; } \ ^ CC [M] /home/george/Downloads/gobiusbnet/QMIDevice.o /home/george/Downloads/gobiusbnet/QMIDevice.c: In function ‘UserspaceIOCTL’: /home/george/Downloads/gobiusbnet/QMIDevice.c:2272:26: error: ‘struct file’ has no member named ‘f_dentry’ pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; ^ /home/george/Downloads/gobiusbnet/QMIDevice.c: In function ‘UserspaceClose’: /home/george/Downloads/gobiusbnet/QMIDevice.c:2393:21: warning: passing argument 1 of ‘atomic_read’ from incompatible pointer type [-Wincompatible-pointer-types] if (atomic_read( &pFilp->f_count ) != 1) ^ In file included from include/linux/atomic.h:4:0, from ./arch/x86/include/asm/thread_info.h:53, from include/linux/thread_info.h:54, from ./arch/x86/include/asm/preempt.h:6, from include/linux/preempt.h:59, from include/linux/spinlock.h:50, from include/linux/mm_types.h:8, from include/linux/kmemcheck.h:4, from include/linux/skbuff.h:18, from include/linux/if_ether.h:23, from include/linux/etherdevice.h:25, from /home/george/Downloads/gobiusbnet/Structs.h:47, from /home/george/Downloads/gobiusbnet/QMIDevice.h:95, from /home/george/Downloads/gobiusbnet/QMIDevice.c:91: ./arch/x86/include/asm/atomic.h:25:28: note: expected ‘const atomic_t * {aka const struct <anonymous> *}’ but argument is of type ‘atomic_long_t * {aka struct <anonymous> *}’ static __always_inline int atomic_read(const atomic_t *v) ^ /home/george/Downloads/gobiusbnet/QMIDevice.c:2430:26: error: ‘struct file’ has no member named ‘f_dentry’ pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; ^ /home/george/Downloads/gobiusbnet/QMIDevice.c: In function ‘UserspaceRead’: /home/george/Downloads/gobiusbnet/QMIDevice.c:2489:26: error: ‘struct file’ has no member named ‘f_dentry’ pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; ^ /home/george/Downloads/gobiusbnet/QMIDevice.c: In function ‘UserspaceWrite’: /home/george/Downloads/gobiusbnet/QMIDevice.c:2570:26: error: ‘struct file’ has no member named ‘f_dentry’ pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; ^ /home/george/Downloads/gobiusbnet/QMIDevice.c: In function ‘UserspacePoll’: /home/george/Downloads/gobiusbnet/QMIDevice.c:2649:26: error: ‘struct file’ has no member named ‘f_dentry’ pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; ^ /home/george/Downloads/gobiusbnet/QMIDevice.c: In function ‘DeregisterQMIDevice’: /home/george/Downloads/gobiusbnet/QMIDevice.c:3006:43: error: ‘struct file’ has no member named ‘f_dentry’ if (pFilp != NULL && pFilp->f_dentry != NULL) ^ /home/george/Downloads/gobiusbnet/QMIDevice.c:3008:28: error: ‘struct file’ has no member named ‘f_dentry’ if (pFilp->f_dentry->d_inode == pOpenInode) ^ /home/george/Downloads/gobiusbnet/QMIDevice.c:3053:46: error: ‘struct file’ has no member named ‘f_dentry’ if (pFilp != NULL && pFilp->f_dentry != NULL) ^ /home/george/Downloads/gobiusbnet/QMIDevice.c:3055:31: error: ‘struct file’ has no member named ‘f_dentry’ if (pFilp->f_dentry->d_inode == pOpenInode) ^ scripts/Makefile.build:258: recipe for target '/home/george/Downloads/gobiusbnet/QMIDevice.o' failed make[2]: *** [/home/george/Downloads/gobiusbnet/QMIDevice.o] Error 1 Makefile:1420: recipe for target '_module_/home/george/Downloads/gobiusbnet' failed make[1]: *** [_module_/home/george/Downloads/gobiusbnet] Error 2 make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-57-generic' Makefile:8: recipe for target 'all' failed make: *** [all] Error 2 george@ubuntu-1604:~/Downloads/gobiusbnet$ git diff diff --git a/GobiUSBNet.c b/GobiUSBNet.c index b8151e2..3b88372 100644 --- a/GobiUSBNet.c +++ b/GobiUSBNet.c @@ -1666,11 +1666,11 @@ RETURN VALUE: void ===========================================================================*/ // static int GobiUSBNetModExit(struct platform_device *pdev) -static int GobiUSBNetModExit(void) +static void GobiUSBNetModExit(void) { usb_deregister( &GobiNet ); class_destroy( gpClass ); - return 0; + return; } #if 0 diff --git a/QMIDevice.c b/QMIDevice.c index e7b3f72..6be39a6 100644 --- a/QMIDevice.c +++ b/QMIDevice.c @@ -2269,7 +2269,7 @@ int UserspaceIOCTL( if (IsDeviceValid( pFilpData->mpDev ) == false) { DBG( "Invalid device! Updating f_ops\n" ); - pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; + pFilp->f_op = pFilp->f_path.dentry->d_inode->i_fop;^M return -ENXIO; } @@ -2390,7 +2390,7 @@ int UserspaceClose( } // Fallthough. If f_count == 1 no need to do more checks - if (atomic_read( &pFilp->f_count ) != 1) + if (atomic_long_read( &pFilp->f_count ) != 1)^M { rcu_read_lock(); for_each_process( pEachTask ) @@ -2427,7 +2427,7 @@ int UserspaceClose( if (IsDeviceValid( pFilpData->mpDev ) == false) { DBG( "Invalid device! Updating f_ops\n" ); - pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; + pFilp->f_op = pFilp->f_path.dentry->d_inode->i_fop;^M return -ENXIO; } @@ -2486,7 +2486,7 @@ ssize_t UserspaceRead( if (IsDeviceValid( pFilpData->mpDev ) == false) { DBG( "Invalid device! Updating f_ops\n" ); - pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; + pFilp->f_op = pFilp->f_path.dentry->d_inode->i_fop;^M return -ENXIO; } @@ -2567,7 +2567,7 @@ ssize_t UserspaceWrite( if (IsDeviceValid( pFilpData->mpDev ) == false) { DBG( "Invalid device! Updating f_ops\n" ); - pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; + pFilp->f_op = pFilp->f_path.dentry->d_inode->i_fop;^M return -ENXIO; } @@ -2646,7 +2646,7 @@ unsigned int UserspacePoll( if (IsDeviceValid( pFilpData->mpDev ) == false) { DBG( "Invalid device! Updating f_ops\n" ); - pFilp->f_op = pFilp->f_dentry->d_inode->i_fop; + pFilp->f_op = pFilp->f_path.dentry->d_inode->i_fop;^M return POLLERR; } @@ -3003,9 +3003,9 @@ void DeregisterQMIDevice( sGobiUSBNet * pDev ) for (count = 0; count < pFDT->max_fds; count++) { pFilp = pFDT->fd[count]; - if (pFilp != NULL && pFilp->f_dentry != NULL) + if (pFilp != NULL && pFilp->f_path.dentry != NULL)^M { - if (pFilp->f_dentry->d_inode == pOpenInode) + if (pFilp->f_path.dentry->d_inode == pOpenInode)^M { // Close this file handle rcu_assign_pointer( pFDT->fd[count], NULL ); @@ -3050,9 +3050,9 @@ void DeregisterQMIDevice( sGobiUSBNet * pDev ) for (count = 0; count < pFDT->max_fds; count++) { pFilp = pFDT->fd[count]; - if (pFilp != NULL && pFilp->f_dentry != NULL) + if (pFilp != NULL && pFilp->f_path.dentry != NULL)^M { - if (pFilp->f_dentry->d_inode == pOpenInode) + if (pFilp->f_path.dentry->d_inode == pOpenInode)^M { // Close this file handle rcu_assign_pointer( pFDT->fd[count], NULL ); george@ubuntu-1604:~/Downloads/gobiusbnet$ make rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module.* modules.order make -C /lib/modules/4.4.0-57-generic/build M=/home/george/Downloads/gobiusbnet modules make[1]: Entering directory '/usr/src/linux-headers-4.4.0-57-generic' CC [M] /home/george/Downloads/gobiusbnet/qmap.o CC [M] /home/george/Downloads/gobiusbnet/GobiUSBNet.o CC [M] /home/george/Downloads/gobiusbnet/QMIDevice.o CC [M] /home/george/Downloads/gobiusbnet/QMI.o LD [M] /home/george/Downloads/gobiusbnet/GobiNet.o Building modules, stage 2. MODPOST 1 modules CC /home/george/Downloads/gobiusbnet/GobiNet.mod.o LD [M] /home/george/Downloads/gobiusbnet/GobiNet.ko make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-57-generic'