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'