Recently, we tried to compile the GobiNet drivers for Linux on an Ubuntu 16.10 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=”2188″]
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=”3349″].
Errors:
First error: ‘struct net_device’ has no member named ‘trans_start’ (GobiUSBNet.c:876:8)
We removed the call to pNet->trans_start = jiffies;
and replaced it with netif_trans_update(pNet);
which as we can see below, it does the same thing in the end.
/* legacy drivers only, netdev_start_xmit() sets txq->trans_start */ static inline void netif_trans_update(struct net_device *dev) { struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); if (txq->trans_start != jiffies) txq->trans_start = jiffies; }
GobiUSBNet.c:876 @@ -873,7 +873,7 @@ int GobiUSBNetStartXmit( complete( &pAutoPM->mThreadDoWork ); // Start transfer timer - pNet->trans_start = jiffies; + netif_trans_update(pNet); // Free SKB dev_kfree_skb_any( pSKB );
Second error: return from incompatible pointer type [-Werror=incompatible-pointer-types] (GobiUSBNet.c:1692:13)
We got the following error:
/home/george/Downloads/gobiusbnet/GobiUSBNet.c: In function ‘__exittest’: /home/george/Downloads/gobiusbnet/GobiUSBNet.c:1692:13: error: return from incompatible pointer type [-Werror=incompatible-pointer-types] module_exit(GobiUSBNetModExit); ^ ./include/linux/module.h:137: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; }
Third error: passing argument 1 of ‘atomic_read’ from incompatible pointer type [-Werror=incompatible-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 )
Fourth 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-1610:~/Downloads$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.10 Release: 16.10 Codename: yakkety george@ubuntu-1610:~/Downloads$ wget https://portland.source.codeaurora.org/patches/quic/gobi/Gobi_Linux/GobiNet_2016-10-20.tar.gz --2017-04-24 09:42:08-- 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.gz 100%[=============================================>] 42,79K 217KB/s in 0,2s 2017-04-24 09:42:09 (217 KB/s) - ‘GobiNet_2016-10-20.tar.gz’ saved [43818/43818] george@ubuntu-1610:~/Downloads$ tar -xzf GobiNet_2016-10-20.tar.gz george@ubuntu-1610:~/Downloads$ cd gobiusbnet/ george@ubuntu-1610:~/Downloads/gobiusbnet$ make rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module.* modules.order make -C /lib/modules/4.8.0-27-generic/build M=/home/george/Downloads/gobiusbnet modules make[1]: Entering directory '/usr/src/linux-headers-4.8.0-27-generic' CC [M] /home/george/Downloads/gobiusbnet/qmap.o CC [M] /home/george/Downloads/gobiusbnet/GobiUSBNet.o /home/george/Downloads/gobiusbnet/GobiUSBNet.c: In function ‘GobiUSBNetStartXmit’: /home/george/Downloads/gobiusbnet/GobiUSBNet.c:876:8: error: ‘struct net_device’ has no member named ‘trans_start’; did you mean ‘mem_start’? pNet->trans_start = jiffies; ^~ In file included from ./include/linux/phy.h:24: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: error: return from incompatible pointer type [-Werror=incompatible-pointer-types] module_exit(GobiUSBNetModExit); ^ ./include/linux/module.h:137:11: note: in definition of macro ‘module_exit’ { return exitfn; } \ ^~~~~~ cc1: some warnings being treated as errors scripts/Makefile.build:289: recipe for target '/home/george/Downloads/gobiusbnet/GobiUSBNet.o' failed make[2]: *** [/home/george/Downloads/gobiusbnet/GobiUSBNet.o] Error 1 Makefile:1489: 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.8.0-27-generic' Makefile:8: recipe for target 'all' failed make: *** [all] Error 2 george@ubuntu-1610:~/Downloads/gobiusbnet$ 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; } george@ubuntu-1610:~/Downloads/gobiusbnet$ make all rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module.* modules.order make -C /lib/modules/4.8.0-27-generic/build M=/home/george/Downloads/gobiusbnet modules make[1]: Entering directory '/usr/src/linux-headers-4.8.0-27-generic' CC [M] /home/george/Downloads/gobiusbnet/qmap.o CC [M] /home/george/Downloads/gobiusbnet/GobiUSBNet.o /home/george/Downloads/gobiusbnet/GobiUSBNet.c: In function ‘GobiUSBNetStartXmit’: /home/george/Downloads/gobiusbnet/GobiUSBNet.c:876:8: error: ‘struct net_device’ has no member named ‘trans_start’; did you mean ‘mem_start’? pNet->trans_start = jiffies; ^~ scripts/Makefile.build:289: recipe for target '/home/george/Downloads/gobiusbnet/GobiUSBNet.o' failed make[2]: *** [/home/george/Downloads/gobiusbnet/GobiUSBNet.o] Error 1 Makefile:1489: 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.8.0-27-generic' Makefile:8: recipe for target 'all' failed make: *** [all] Error 2 george@ubuntu-1610:~/Downloads/gobiusbnet$ GobiUSBNet.c:876 @@ -873,7 +873,7 @@ int GobiUSBNetStartXmit( complete( &pAutoPM->mThreadDoWork ); // Start transfer timer - pNet->trans_start = jiffies; + netif_trans_update(pNet); // Free SKB dev_kfree_skb_any( pSKB ); george@ubuntu-1610:~/Downloads/gobiusbnet$ make all rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module.* modules.order make -C /lib/modules/4.8.0-27-generic/build M=/home/george/Downloads/gobiusbnet modules make[1]: Entering directory '/usr/src/linux-headers-4.8.0-27-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 /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’; did you mean ‘f_owner’? 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: error: passing argument 1 of ‘atomic_read’ from incompatible pointer type [-Werror=incompatible-pointer-types] if (atomic_read( &pFilp->f_count ) != 1) ^ In file included from ./arch/x86/include/asm/msr.h:66:0, from ./arch/x86/include/asm/processor.h:20, from ./arch/x86/include/asm/cpufeature.h:4, from ./arch/x86/include/asm/thread_info.h:52, 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:24: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’; did you mean ‘f_owner’? 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’; did you mean ‘f_owner’? 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’; did you mean ‘f_owner’? 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’; did you mean ‘f_owner’? 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’; did you mean ‘f_owner’? if (pFilp != NULL && pFilp->f_dentry != NULL) ^~ /home/george/Downloads/gobiusbnet/QMIDevice.c:3008:28: error: ‘struct file’ has no member named ‘f_dentry’; did you mean ‘f_owner’? if (pFilp->f_dentry->d_inode == pOpenInode) ^~ /home/george/Downloads/gobiusbnet/QMIDevice.c:3053:46: error: ‘struct file’ has no member named ‘f_dentry’; did you mean ‘f_owner’? if (pFilp != NULL && pFilp->f_dentry != NULL) ^~ /home/george/Downloads/gobiusbnet/QMIDevice.c:3055:31: error: ‘struct file’ has no member named ‘f_dentry’; did you mean ‘f_owner’? if (pFilp->f_dentry->d_inode == pOpenInode) ^~ cc1: some warnings being treated as errors scripts/Makefile.build:289: recipe for target '/home/george/Downloads/gobiusbnet/QMIDevice.o' failed make[2]: *** [/home/george/Downloads/gobiusbnet/QMIDevice.o] Error 1 Makefile:1489: 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.8.0-27-generic' Makefile:8: recipe for target 'all' failed make: *** [all] Error 2 - if (pFilp != NULL && pFilp->f_dentry != NULL) + if (pFilp != NULL && pFilp->f_path.dentry != NULL)^M george@ubuntu-1610:~/Downloads/gobiusbnet$ make all rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module.* modules.order make -C /lib/modules/4.8.0-27-generic/build M=/home/george/Downloads/gobiusbnet modules make[1]: Entering directory '/usr/src/linux-headers-4.8.0-27-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 /home/george/Downloads/gobiusbnet/QMIDevice.c: In function ‘UserspaceClose’: /home/george/Downloads/gobiusbnet/QMIDevice.c:2393:21: error: passing argument 1 of ‘atomic_read’ from incompatible pointer type [-Werror=incompatible-pointer-types] if (atomic_read( &pFilp->f_count ) != 1) ^ In file included from ./arch/x86/include/asm/msr.h:66:0, from ./arch/x86/include/asm/processor.h:20, from ./arch/x86/include/asm/cpufeature.h:4, from ./arch/x86/include/asm/thread_info.h:52, 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:24: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) ^~~~~~~~~~~ cc1: some warnings being treated as errors scripts/Makefile.build:289: recipe for target '/home/george/Downloads/gobiusbnet/QMIDevice.o' failed make[2]: *** [/home/george/Downloads/gobiusbnet/QMIDevice.o] Error 1 Makefile:1489: 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.8.0-27-generic' Makefile:8: recipe for target 'all' failed make: *** [all] Error 2 @@ -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 ) george@ubuntu-1610:~/Downloads/gobiusbnet$ make all rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module.* modules.order make -C /lib/modules/4.8.0-27-generic/build M=/home/george/Downloads/gobiusbnet modules make[1]: Entering directory '/usr/src/linux-headers-4.8.0-27-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.8.0-27-generic'
This post is also available in: Αγγλικα