Update, 2011-02-27

If you are using OpenSUSE 11.3, you usually won't need to install any driver at all. Serial ports probably are located at /dev/ttyS4 and /dev/ttyS5. In order to access them, you should be member of group 'dialout'.

Update, 2010-02-04

If you are using the kernel module mcs9865 version >= from MosChip™ you won't need this patch. However, section Using the mcs9865 kernel module with SUSE Linux 11.1 might be of interest for you.

MCS9865 Linux kernel module patch


History / Motivation

Some days ago, I bought a serial port device providing two additional serial ports (manufacturer MosChip™). Installation of the the Linux software, provided by MosChip™ on a CD, failed with two basic errors:

Error #1: error: ‘struct uart_info’ has no member named ‘tty’ (3 times)
Error #2: error: ‘SA_SHIRQ’ undeclared (first use in this function) (1 time)

A driver download from http://driver-downloads.com, document DL-0234903, as recommended in the manual, did not solve the problem (same driver version).



Error #1:

With Kernel version 2.6.27, the former member of struct uart_info, struct tty_struct *tty has moved to the new sub structure struct tty_port port in linux/serial_core.h:

Kernel patch snippet:

    @@ -343,13 +341,15 @@ typedef unsigned int __bitwise__ uif_t;
    * stuff here.
    struct uart_info {
    -   struct tty_struct   *tty;
    +   struct tty_port      port;
    struct circ_buf      xmit;
    uif_t         flags;
    * Definitions for info->flags.  These are _private_ to serial_core, and
    * are specific to this structure.  They may be queried by low level drivers.
    + *
    + * FIXME: use the ASY_ definitions
    #define UIF_CHECK_CD      ((__force uif_t) (1 << 25))
    #define UIF_CTS_FLOW      ((__force uif_t) (1 << 26))
and, referencing
    @@ -517,7 +513,7 @@ static inline void
    uart_handle_cts_change(struct uart_port *port, unsigned int status)
    struct uart_info *info = port->info;
    -   struct tty_struct *tty = info->tty;
    +   struct tty_struct *tty = info->port.tty;

For full details please refer to http://www.linuxhq.com/kernel/v2.6/27/include/linux/serial_core.h .

Solution #1:

Usage of info->tty had to be replaced with info->port.tty.

Error #2:

In the history of linux/interrupt.h Kernel version 2.6.24 you can see that the deprecated IRQ flag SA_SHIRQ -which formerly was mapped to IRQF_SHARED- finally was removed from linux/interrupt.h as has been foreseen.:
    @@ -55,28 +55,6 @@
    #define IRQF_NOBALANCING   0x00000800
    #define IRQF_IRQPOLL      0x00001000
    - * Migration helpers. Scheduled for removal in 9/2007
    - * Do not use for new code !
    - */
    -static inline
    -unsigned long __deprecated deprecated_irq_flag(unsigned long flag)
    -   return flag;
    -#define SA_INTERRUPT      deprecated_irq_flag(IRQF_DISABLED)
    -#define SA_SAMPLE_RANDOM   deprecated_irq_flag(IRQF_SAMPLE_RANDOM)
    -#define SA_SHIRQ      deprecated_irq_flag(IRQF_SHARED)
    -#define SA_PROBEIRQ      deprecated_irq_flag(IRQF_PROBE_SHARED)
    -#define SA_PERCPU      deprecated_irq_flag(IRQF_PERCPU)
    -#define SA_TRIGGER_LOW      deprecated_irq_flag(IRQF_TRIGGER_LOW)
    -#define SA_TRIGGER_HIGH      deprecated_irq_flag(IRQF_TRIGGER_HIGH)
    -#define SA_TRIGGER_FALLING   deprecated_irq_flag(IRQF_TRIGGER_FALLING)
    -#define SA_TRIGGER_RISING   deprecated_irq_flag(IRQF_TRIGGER_RISING)
    -#define SA_TRIGGER_MASK      deprecated_irq_flag(IRQF_TRIGGER_MASK)
    typedef irqreturn_t (*irq_handler_t)(int, void *);
    struct irqaction {


Solution #2:

So, I decided to code something like
    #if !defined(SA_SHIRQ)
      if ((retval = request_irq(dev->irq, serial9865_interrupt,IRQF_SHARED,"mcs9865-serial",&serial9865_ports[retval])))
      if ((retval = request_irq(dev->irq, serial9865_interrupt,SA_SHIRQ,"mcs9865-serial",&serial9865_ports[retval])))
in order to ensure compatibility with earlier kernel versions.

Patch for mcs9865.c, version 1.0, Date 18-4-2008

Note: This patch comes without any warranty, and, furthermore, it is completely unofficial. I've tested it with version 1.0 of the mcs9865 kernel module and it appears to work well with kernel x86_64. I'm not the first one who found the solution, please look and search for "Razorblade". He obviously had patched the file, I spent some hours to find my own solution, and both turned out to be basically equal. The only difference would be that this version could be used with earlier kernel versions.

In order to apply the patch,

  1. rename your mcs9865.c file into, let's say, mcs9865_old.c.
  2. Copy mcs9865.patch into the same directory.
  3. Open a linux console, cd to this directory and type "patch mcs9865_old.c -i mcs9865.patch -o mcs9865.c".

Later versions

If you are using later versions of the MCS9865 (currently, you can download version from http://www.moschip.com/ , please take a look at the time stamp beneath the first heading on the beginning of this page), this patch might work as well. A message like "Hunk #4 FAILED at ..." from patch means that the last error message (SA_SHIRQ) already has been fixed by the manufacturer.

Patched file mcs9865.c (ver 1.0)

Using the mcs9865 kernel module with SUSE Linux 11.1