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'