Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm currently trying to compile a Linux USB UART driver, which is provided here: http://www.exar.com/connectivity/uart-and-bridging-solutions/usb-uarts/xr21v1410

The driver consists of 2 header files and one large C file. These are the contents of the Makefile:

obj-m := vizzini.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD       := $(shell pwd)

EXTRA_CFLAGS    := -DDEBUG=0

all:
    $(MAKE) -C $(KERNELDIR) M=$(PWD)

modules_install:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

clean:
    rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions vtty

This is the error the compiler is throwing when I run make:

[sj755@localhost xr21v141x-lnx-2.6.35-pak]$ make
make -C /lib/modules/3.4.9-2.fc16.x86_64/build M=/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak
make[1]: Entering directory `/usr/src/kernels/3.4.9-2.fc16.x86_64'
  LD      /home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/built-in.o
  CC [M]  /home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.o
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1643:9: warning: initialization from incompatible pointer type [enabled by default]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1643:9: warning: (near initialization for ‘vizzini_device.ioctl’) [enabled by default]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1646:9: warning: initialization from incompatible pointer type [enabled by default]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1646:9: warning: (near initialization for ‘vizzini_device.tiocmget’) [enabled by default]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1647:9: warning: initialization from incompatible pointer type [enabled by default]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1647:9: warning: (near initialization for ‘vizzini_device.tiocmset’) [enabled by default]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c: In function ‘vizzini_init’:
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1663:9: error: implicit declaration of function ‘usb_serial_register’ [-Werror=implicit-function-declaration]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1677:9: error: implicit declaration of function ‘usb_serial_deregister’ [-Werror=implicit-function-declaration]
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c: In function ‘__check_debug’:
/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.c:1698:83: warning: return from incompatible pointer type [enabled by default]
cc1: some warnings being treated as errors
make[2]: *** [/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak/vizzini.o] Error 1
make[1]: *** [_module_/home/sj755/Downloads/xr21v141x-lnx-2.6.35-pak] Error 2
make[1]: Leaving directory `/usr/src/kernels/3.4.9-2.fc16.x86_64'
make: *** [all] Error 2

These are the headers included in the main c source file:

#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/errno.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
#include <linux/serial.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
#include <asm/uaccess.h>

#include <linux/usb/cdc.h>
#ifndef CDC_DATA_INTERFACE_TYPE
#define CDC_DATA_INTERFACE_TYPE 0x0a
#endif
#ifndef USB_RT_ACM
#define USB_RT_ACM      (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
#define ACM_CTRL_DTR            0x01
#define ACM_CTRL_RTS            0x02
#define ACM_CTRL_DCD            0x01
#define ACM_CTRL_DSR            0x02
#define ACM_CTRL_BRK            0x04
#define ACM_CTRL_RI             0x08
#define ACM_CTRL_FRAMING        0x10
#define ACM_CTRL_PARITY         0x20
#define ACM_CTRL_OVERRUN        0x40
#endif

#include "linux/version.h"

#include "vizzini.h"

Running Linux kernel 3.4.9-2.fc16.x86_64

I would greatly appreciate any help in resolving the errors.

share|improve this question

2 Answers 2

up vote 1 down vote accepted

In more recent versions of the linux kernel, the usb_serial_register and usb_serial_deregister functions were made static. Thus, the functions only exist as text in the kernel object files. The usb_serial_register_drivers and usb_serial_deregister_drivers can instead be used.

Here are the definitions of the two sets of functions:

int usb_serial_register(struct usb_serial_driver *driver);
void usb_serial_deregister(struct usb_serial_driver *device);
int usb_serial_register_drivers(struct usb_driver *udriver,
                                struct usb_serial_driver * const serial_drivers[]);
void usb_serial_deregister_drivers(struct usb_driver *udriver,
                                   struct usb_serial_driver * const serial_drivers[]);

usb_serial_register_drivers takes an NULL terminated array of pointers to usb-serial drivers to be registered and a usb_driver used for matching devices/interfaces. The details of the two sets of functions can be read here:

http://lxr.free-electrons.com/source/drivers/usb/serial/usb-serial.c?v=3.4#L1379

http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/drivers/usb/serial/usb-serial.c#L1337

Within the source code for the driver, lines such as this:

retval = usb_serial_register(&vizzini_device);

were replaced with this:

struct usb_serial_driver *serial_drivers[2] = {&vizzini_device,NULL};
retval = usb_serial_register_drivers(&vizzini_driver,serial_drivers);

vizzini_driver and vizzini_device was defined elsewhere in the code as the following:

static struct usb_driver vizzini_driver = {
        .name          = "vizzini",
        .probe         = usb_serial_probe,
        .disconnect    = vizzini_disconnect,
        .id_table      = id_table,
        .no_dynamic_id = 1,
};
static struct usb_serial_driver vizzini_device = {
        .driver = {
                .owner =    THIS_MODULE,
                .name =     "vizzini",
        },
    .usb_driver     = &vizzini_driver,
        .description        = "Vizzini USB serial port",
        .id_table           = id_table,
        .calc_num_ports     = vizzini_calc_num_ports,
        .probe              = vizzini_probe,
        .open               = vizzini_open,
        .close              = vizzini_close,
        .write              = vizzini_write,
        .write_room         = vizzini_write_room,
        .ioctl              = vizzini_ioctl,
        .set_termios        = vizzini_set_termios,
        .break_ctl          = vizzini_break_ctl,
        .tiocmget           = vizzini_tiocmget,
        .tiocmset           = vizzini_tiocmset,
        .attach             = vizzini_attach,
        .disconnect        = vizzini_serial_disconnect,
        .release           = vizzini_serial_release,
        .read_int_callback  = vizzini_int_callback,
};
share|improve this answer

API inside the kernel is far from stable, so unless the driver is roughly contemporary with the kernel source it just won't work (and the warnings/error messsages you give point in that exact direction). And most out-of-tree drivers are horrible code, so take that one with a grain (or shovelfull) of salt. Look if that is suported by current kernels, either officially or in staging drivers. Check Linux-USB, there you might find some pointers.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.