[PATCH 00/70] tty updates proposed for 2.6.27 - Kernel

This is a discussion on [PATCH 00/70] tty updates proposed for 2.6.27 - Kernel ; This patch series introduces the idea of a tty_port - a common structure that eventually all ports will have. Some drivers are migrated to make partial use of the tty port commonality and helpers but only a little. On the ...

+ Reply to Thread
Page 1 of 4 1 2 3 ... LastLast
Results 1 to 20 of 77

Thread: [PATCH 00/70] tty updates proposed for 2.6.27

  1. [PATCH 00/70] tty updates proposed for 2.6.27

    This patch series introduces the idea of a tty_port - a common structure
    that eventually all ports will have. Some drivers are migrated to make partial
    use of the tty port commonality and helpers but only a little.

    On the USB side the USB tty API is changed to fix a whole pile of races where
    tty->port->tty cannot be assumed to be tty (because of hangup/reopen). The
    USB drivers all get a spring clean and the entire pile have been dragged into
    CodingStyle near compliance (some cases where the checkpatch whines that
    make no sense have been ignored).

    Greg: At the end of this series there shouldn't be any white space issues
    although some earlier patches introduce them and later ones take them away

    Aim... load... fire...
    ---

    Alan Cox (70):
    tty-usb-mos7720: Coding style
    whiteheat: remove unused variable
    mos7840: remove loads of bogus assignments to status
    omninet: Use string flip functions
    tty-usb-omninet: Coding style
    tty-usb-option: Coding style
    tty-usb-oti6858: Coding style
    tty-usb-safe-serial: Coding style
    tty-usb-ti-usb: Coding style
    tty-usb-spcp8x5: Minor coding style
    tty-usb-sierra: Coding style - minor
    tty-usb-pl2303: Coding style
    mct_u232: Use flip buffer functions
    tty-usb-mct-u232: Coding style
    kobil_sct: Fix ioctls
    tty-usb-kobil-sct: Coding style
    keyspan_pda: Use string flip functions
    tty-usb-kl5kusb105: Coding style
    tty-usb-keyspan-pda: Coding style
    keyspan: Use string flip functions when possible
    tty-usb-keyspan: Coding style
    tty-usb-iuu-phoenix: Clean up to coding style
    tty-usb-ir-usb: Clean up to coding style
    tty-usb-ipw: Coding style
    ipaq: Coding style
    io_ti: Minor coding style
    usb-serial: Coding style
    io_edgeport: Fix various bogus returns to the tty layer
    tty-usb-io_edgeport: Coding style
    tty-usb-visor: Coding style
    tty-usb-hp4x: Fix overlong line
    tty-usb-generic: Code cleanup
    garmin_gps: Coding style
    funsoft: Switch to linux/uaccess
    ftdi_sio: Coding style
    empeg: Coding style
    digi_acceleport: coding style
    usb-cypress: There is no 0 case to go with CS5/6/7/8 so remove the test
    cypress_m8: coding style
    cyberjack: Coding style
    cp2101: coding style
    tty-usb-console: Fix termios
    tty-usb-console: tidy the USB console code
    usb-serial-bus: tidy coding style
    belkin_sa: clean up code
    whiteheat: fix bugs found in the tidy and audit
    whiteheat: coding style
    usb_serial: API all change
    tty: add more tty_port fields
    termios: Termios defines for other platforms
    cyclades: use tty_port
    tty: Clean up tiocmset
    synclink: use tty_port
    stallion: use tty_port
    serial: use tty_port
    rocket: use tty_port
    mxser: use tty_port
    moxa: use tty_port
    istallion: use tty_port
    isicom: use tty_port
    riscom8: remove bogus checks
    riscom8: use tty_port
    gs: use tty_port
    esp: use tty_port
    epca: use tty_port
    tty.h: clean up
    tty: Introduce a tty_port common structure
    drivers/serial/: remove CVS keywords
    drivers/char/rio/: remove VCS tags
    tty: Ldisc revamp


    drivers/bluetooth/hci_ldisc.c | 6
    drivers/char/cyclades.c | 342 +++--
    drivers/char/epca.c | 110 +-
    drivers/char/epca.h | 7
    drivers/char/esp.c | 272 ++--
    drivers/char/generic_serial.c | 158 +-
    drivers/char/ip2/i2lib.c | 4
    drivers/char/ip2/ip2main.c | 7
    drivers/char/isicom.c | 207 +--
    drivers/char/istallion.c | 116 +-
    drivers/char/moxa.c | 93 +
    drivers/char/mxser.c | 284 ++--
    drivers/char/n_hdlc.c | 6
    drivers/char/n_r3964.c | 2
    drivers/char/n_tty.c | 2
    drivers/char/pcmcia/synclink_cs.c | 4
    drivers/char/pty.c | 10
    drivers/char/rio/cirrus.h | 3
    drivers/char/rio/cmdblk.h | 6
    drivers/char/rio/cmdpkt.h | 6
    drivers/char/rio/daemon.h | 6
    drivers/char/rio/errors.h | 6
    drivers/char/rio/func.h | 6
    drivers/char/rio/map.h | 4
    drivers/char/rio/param.h | 5
    drivers/char/rio/parmmap.h | 7
    drivers/char/rio/pci.h | 4
    drivers/char/rio/protsts.h | 7
    drivers/char/rio/rio_linux.c | 25
    drivers/char/rio/rioboard.h | 6
    drivers/char/rio/riocmd.c | 13
    drivers/char/rio/rioctrl.c | 4
    drivers/char/rio/riodrvr.h | 4
    drivers/char/rio/rioinfo.h | 4
    drivers/char/rio/rioinit.c | 3
    drivers/char/rio/riointr.c | 14
    drivers/char/rio/rioparam.c | 6
    drivers/char/rio/rioroute.c | 3
    drivers/char/rio/riospace.h | 4
    drivers/char/rio/riotable.c | 3
    drivers/char/rio/riotty.c | 20
    drivers/char/rio/route.h | 6
    drivers/char/rio/unixrup.h | 4
    drivers/char/riscom8.c | 187 +--
    drivers/char/riscom8.h | 10
    drivers/char/rocket.c | 139 +-
    drivers/char/rocket.h | 4
    drivers/char/rocket_int.h | 11
    drivers/char/selection.c | 3
    drivers/char/specialix.c | 153 +-
    drivers/char/specialix_io8.h | 8
    drivers/char/stallion.c | 160 +-
    drivers/char/sx.c | 115 +-
    drivers/char/synclink.c | 213 ++-
    drivers/char/synclink_gt.c | 219 ++-
    drivers/char/synclinkmp.c | 219 ++-
    drivers/char/tty_io.c | 420 ++++--
    drivers/char/tty_ioctl.c | 16
    drivers/input/serio/serport.c | 2
    drivers/isdn/capi/capi.c | 4
    drivers/isdn/gigaset/ser-gigaset.c | 2
    drivers/net/hamradio/6pack.c | 2
    drivers/net/hamradio/mkiss.c | 2
    drivers/net/irda/irtty-sir.c | 2
    drivers/net/ppp_async.c | 2
    drivers/net/ppp_synctty.c | 2
    drivers/net/slip.c | 2
    drivers/net/wan/pc300_tty.c | 4
    drivers/net/wan/x25_asy.c | 2
    drivers/net/wireless/strip.c | 2
    drivers/serial/21285.c | 6
    drivers/serial/8250.c | 8
    drivers/serial/8250.h | 2
    drivers/serial/8250_pci.c | 2
    drivers/serial/8250_pnp.c | 2
    drivers/serial/Kconfig | 2
    drivers/serial/Makefile | 2
    drivers/serial/amba-pl010.c | 6
    drivers/serial/amba-pl011.c | 2
    drivers/serial/clps711x.c | 7
    drivers/serial/cpm_uart/cpm_uart_core.c | 4
    drivers/serial/jsm/jsm_neo.c | 2
    drivers/serial/jsm/jsm_tty.c | 8
    drivers/serial/m32r_sio.c | 4
    drivers/serial/mpsc.c | 4
    drivers/serial/pnx8xxx_uart.c | 2
    drivers/serial/sa1100.c | 7
    drivers/serial/serial_core.c | 80 +
    drivers/serial/sunsu.c | 2
    drivers/usb/serial/Kconfig | 8
    drivers/usb/serial/aircable.c | 19
    drivers/usb/serial/airprime.c | 16
    drivers/usb/serial/ark3116.c | 32
    drivers/usb/serial/belkin_sa.c | 201 ++-
    drivers/usb/serial/belkin_sa.h | 15
    drivers/usb/serial/bus.c | 20
    drivers/usb/serial/ch341.c | 10
    drivers/usb/serial/console.c | 136 +-
    drivers/usb/serial/cp2101.c | 381 +++---
    drivers/usb/serial/cyberjack.c | 176 +--
    drivers/usb/serial/cypress_m8.c | 703 +++++-----
    drivers/usb/serial/cypress_m8.h | 2
    drivers/usb/serial/digi_acceleport.c | 804 ++++++------
    drivers/usb/serial/empeg.c | 257 ++--
    drivers/usb/serial/ezusb.c | 22
    drivers/usb/serial/ftdi_sio.c | 1249 ++++++++++--------
    drivers/usb/serial/ftdi_sio.h | 126 +-
    drivers/usb/serial/funsoft.c | 2
    drivers/usb/serial/garmin_gps.c | 400 +++---
    drivers/usb/serial/generic.c | 122 +-
    drivers/usb/serial/hp4x.c | 3
    drivers/usb/serial/io_edgeport.c | 2106 +++++++++++++++++--------------
    drivers/usb/serial/io_fw_down3.h | 11
    drivers/usb/serial/io_tables.h | 6
    drivers/usb/serial/io_ti.c | 1924 +++++++++++++---------------
    drivers/usb/serial/ipaq.c | 143 +-
    drivers/usb/serial/ipw.c | 294 ++--
    drivers/usb/serial/ir-usb.c | 398 +++---
    drivers/usb/serial/iuu_phoenix.c | 58 -
    drivers/usb/serial/keyspan.c | 969 +++++++-------
    drivers/usb/serial/keyspan.h | 39 -
    drivers/usb/serial/keyspan_pda.c | 238 ++--
    drivers/usb/serial/kl5kusb105.c | 415 +++---
    drivers/usb/serial/kobil_sct.c | 617 +++++----
    drivers/usb/serial/mct_u232.c | 364 +++--
    drivers/usb/serial/mos7720.c | 308 ++---
    drivers/usb/serial/mos7840.c | 557 +++-----
    drivers/usb/serial/navman.c | 10
    drivers/usb/serial/omninet.c | 171 +--
    drivers/usb/serial/option.c | 166 +-
    drivers/usb/serial/oti6858.c | 255 ++--
    drivers/usb/serial/pl2303.c | 140 +-
    drivers/usb/serial/safe_serial.c | 298 ++--
    drivers/usb/serial/sierra.c | 95 -
    drivers/usb/serial/spcp8x5.c | 73 +
    drivers/usb/serial/ti_fw_3410.h | 4
    drivers/usb/serial/ti_fw_5052.h | 5
    drivers/usb/serial/ti_usb_3410_5052.c | 460 ++++---
    drivers/usb/serial/usb-serial.c | 393 +++---
    drivers/usb/serial/visor.c | 384 +++---
    drivers/usb/serial/whiteheat.c | 484 ++++---
    drivers/usb/serial/whiteheat.h | 78 +
    fs/proc/proc_tty.c | 48 -
    include/asm-avr32/ioctls.h | 4
    include/asm-frv/ioctls.h | 4
    include/asm-frv/termbits.h | 5
    include/linux/cyclades.h | 13
    include/linux/generic_serial.h | 8
    include/linux/hayesesp.h | 9
    include/linux/istallion.h | 6
    include/linux/serial_core.h | 26
    include/linux/stallion.h | 6
    include/linux/tty.h | 204 ++-
    include/linux/tty_ldisc.h | 7
    include/linux/usb/serial.h | 56 -
    net/bluetooth/rfcomm/tty.c | 13
    net/irda/ircomm/ircomm_tty.c | 14
    157 files changed, 10296 insertions(+), 10160 deletions(-)

    --
    "When you turn it on, listen and smell for anything odd and if it smells
    or crackles, shut it off and let me know - that's the one I had to
    realign with a hammer because it was slighly damaged in shipping"
    -- Michael K Johnson

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. [PATCH 04/70] tty: Introduce a tty_port common structure

    From: Alan Cox

    Every tty driver has its own concept of a port structure and because they all
    differ we cannot extract commonality. Begin fixing this by creating a structure
    drivers can elect to use so that over time we can push fields into this and
    create commonality and then introduce common methods.

    Signed-off-by: Alan Cox
    ---

    drivers/char/tty_io.c | 34 ++++++++++++++++++++++++++++++++++
    include/linux/tty.h | 30 +++++++++++++++++++++++++++++-
    2 files changed, 63 insertions(+), 1 deletions(-)


    diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
    index ab1dd0a..1856096 100644
    --- a/drivers/char/tty_io.c
    +++ b/drivers/char/tty_io.c
    @@ -2088,6 +2088,40 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf,
    return tty_write(file, buf, count, ppos);
    }

    +void tty_port_init(struct tty_port *port)
    +{
    + memset(port, 0, sizeof(*port));
    + init_waitqueue_head(&port->open_wait);
    + init_waitqueue_head(&port->close_wait);
    + mutex_init(&port->mutex);
    +}
    +EXPORT_SYMBOL(tty_port_init);
    +
    +int tty_port_alloc_xmit_buf(struct tty_port *port)
    +{
    + /* We may sleep in get_zeroed_page() */
    + mutex_lock(&port->mutex);
    + if (port->xmit_buf == NULL)
    + port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
    + mutex_unlock(&port->mutex);
    + if (port->xmit_buf == NULL)
    + return -ENOMEM;
    + return 0;
    +}
    +EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
    +
    +void tty_port_free_xmit_buf(struct tty_port *port)
    +{
    + mutex_lock(&port->mutex);
    + if (port->xmit_buf != NULL) {
    + free_page((unsigned long)port->xmit_buf);
    + port->xmit_buf = NULL;
    + }
    + mutex_unlock(&port->mutex);
    +}
    +EXPORT_SYMBOL(tty_port_free_xmit_buf);
    +
    +
    static char ptychar[] = "pqrstuvwxyzabcde";

    /**
    diff --git a/include/linux/tty.h b/include/linux/tty.h
    index 013711e..d7c695b 100644
    --- a/include/linux/tty.h
    +++ b/include/linux/tty.h
    @@ -166,6 +166,29 @@ struct tty_bufhead {

    struct device;
    struct signal_struct;
    +
    +/*
    + * Port level information. Each device keeps its own port level information
    + * so provide a common structure for those ports wanting to use common support
    + * routines.
    + *
    + * The tty port has a different lifetime to the tty so must be kept apart.
    + * In addition be careful as tty -> port mappings are valid for the life
    + * of the tty object but in many cases port -> tty mappings are valid only
    + * until a hangup so don't use the wrong path.
    + */
    +
    +struct tty_port {
    + struct tty_struct *tty; /* Back pointer */
    + int blocked_open; /* Waiting to open */
    + int count; /* Usage count */
    + wait_queue_head_t open_wait; /* Open waiters */
    + wait_queue_head_t close_wait; /* Close waiters */
    + unsigned long flags; /* TTY flags ASY_*/
    + struct mutex mutex; /* Locking */
    + unsigned char *xmit_buf; /* Optional buffer */
    +};
    +
    /*
    * Where all of the state associated with a tty is kept while the tty
    * is open. Since the termios state should be kept even if the tty
    @@ -214,7 +237,7 @@ struct tty_struct {
    struct list_head tty_files;

    #define N_TTY_BUF_SIZE 4096
    -
    +
    /*
    * The following is data for the N_TTY line discipline. For
    * historical reasons, this is included in the tty structure.
    @@ -242,6 +265,7 @@ struct tty_struct {
    spinlock_t read_lock;
    /* If the tty has a pending do_SAK, queue it here - akpm */
    struct work_struct SAK_work;
    + struct tty_port *port;
    };

    /* tty magic number */
    @@ -350,6 +374,10 @@ extern void tty_write_unlock(struct tty_struct *tty);
    extern int tty_write_lock(struct tty_struct *tty, int ndelay);
    #define tty_is_writelocked(tty) (mutex_is_locked(&tty->atomic_write_lock))

    +extern void tty_port_init(struct tty_port *port);
    +extern int tty_port_alloc_xmit_buf(struct tty_port *port);
    +extern void tty_port_free_xmit_buf(struct tty_port *port);
    +


    /* n_tty.c */

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. [PATCH 01/70] tty: Ldisc revamp

    From: Alan Cox

    Move the line disciplines towards a conventional ->ops arrangement. For the
    moment the actual 'tty_ldisc' struct in the tty is kept as part of the tty
    struct but this can then be changed if it turns out that when it all settles
    down we want to refcount ldiscs separately to the tty.

    Pull the ldisc code out of /proc and put it with our ldisc code.

    Signed-off-by: Alan Cox
    ---

    drivers/bluetooth/hci_ldisc.c | 6 -
    drivers/char/cyclades.c | 3
    drivers/char/epca.c | 4
    drivers/char/ip2/i2lib.c | 4
    drivers/char/ip2/ip2main.c | 7 -
    drivers/char/n_hdlc.c | 6 -
    drivers/char/n_r3964.c | 2
    drivers/char/n_tty.c | 2
    drivers/char/pcmcia/synclink_cs.c | 4
    drivers/char/pty.c | 10 +
    drivers/char/selection.c | 3
    drivers/char/synclink.c | 4
    drivers/char/synclink_gt.c | 4
    drivers/char/synclinkmp.c | 4
    drivers/char/tty_io.c | 336 +++++++++++++++++++++++-------------
    drivers/char/tty_ioctl.c | 16 +-
    drivers/input/serio/serport.c | 2
    drivers/isdn/capi/capi.c | 4
    drivers/isdn/gigaset/ser-gigaset.c | 2
    drivers/net/hamradio/6pack.c | 2
    drivers/net/hamradio/mkiss.c | 2
    drivers/net/irda/irtty-sir.c | 2
    drivers/net/ppp_async.c | 2
    drivers/net/ppp_synctty.c | 2
    drivers/net/slip.c | 2
    drivers/net/wan/pc300_tty.c | 4
    drivers/net/wan/x25_asy.c | 2
    drivers/net/wireless/strip.c | 2
    fs/proc/proc_tty.c | 48 -----
    include/linux/tty.h | 9 -
    include/linux/tty_ldisc.h | 7 +
    net/bluetooth/rfcomm/tty.c | 13 -
    net/irda/ircomm/ircomm_tty.c | 14 +-
    33 files changed, 287 insertions(+), 247 deletions(-)


    diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
    index e5cd856..69df187 100644
    --- a/drivers/bluetooth/hci_ldisc.c
    +++ b/drivers/bluetooth/hci_ldisc.c
    @@ -282,8 +282,8 @@ static int hci_uart_tty_open(struct tty_struct *tty)
    /* FIXME: why is this needed. Note don't use ldisc_ref here as the
    open path is before the ldisc is referencable */

    - if (tty->ldisc.flush_buffer)
    - tty->ldisc.flush_buffer(tty);
    + if (tty->ldisc.ops->flush_buffer)
    + tty->ldisc.ops->flush_buffer(tty);
    tty_driver_flush_buffer(tty);

    return 0;
    @@ -514,7 +514,7 @@ static unsigned int hci_uart_tty_poll(struct tty_struct *tty,

    static int __init hci_uart_init(void)
    {
    - static struct tty_ldisc hci_uart_ldisc;
    + static struct tty_ldisc_ops hci_uart_ldisc;
    int err;

    BT_INFO("HCI UART driver ver %s", VERSION);
    diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
    index ef73e72..2bf4b4a 100644
    --- a/drivers/char/cyclades.c
    +++ b/drivers/char/cyclades.c
    @@ -5246,7 +5246,8 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
    HZ, info->idle_stats.recv_bytes,
    (cur_jifs - info->idle_stats.recv_idle)/
    HZ, info->idle_stats.overruns,
    - (long)info->tty->ldisc.num);
    + /* FIXME: double check locking */
    + (long)info->tty->ldisc.ops->num);
    else
    size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
    "%10lu %8lu %9lu %6ld\n",
    diff --git a/drivers/char/epca.c b/drivers/char/epca.c
    index 60a4df7..aa8e19f 100644
    --- a/drivers/char/epca.c
    +++ b/drivers/char/epca.c
    @@ -2262,8 +2262,8 @@ static int pc_ioctl(struct tty_struct *tty, struct file *file,
    tty_wait_until_sent(tty, 0);
    } else {
    /* ldisc lock already held in ioctl */
    - if (tty->ldisc.flush_buffer)
    - tty->ldisc.flush_buffer(tty);
    + if (tty->ldisc.ops->flush_buffer)
    + tty->ldisc.ops->flush_buffer(tty);
    }
    unlock_kernel();
    /* Fall Thru */
    diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
    index 938879c..897468b 100644
    --- a/drivers/char/ip2/i2lib.c
    +++ b/drivers/char/ip2/i2lib.c
    @@ -868,11 +868,11 @@ i2Input(i2ChanStrPtr pCh)
    amountToMove = count;
    }
    // Move the first block
    - pCh->pTTY->ldisc.receive_buf( pCh->pTTY,
    + pCh->pTTY->ldisc.ops->receive_buf( pCh->pTTY,
    &(pCh->Ibuf[stripIndex]), NULL, amountToMove );
    // If we needed to wrap, do the second data move
    if (count > amountToMove) {
    - pCh->pTTY->ldisc.receive_buf( pCh->pTTY,
    + pCh->pTTY->ldisc.ops->receive_buf( pCh->pTTY,
    pCh->Ibuf, NULL, count - amountToMove );
    }
    // Bump and wrap the stripIndex all at once by the amount of data read. This
    diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
    index c12cf8f..85f068c 100644
    --- a/drivers/char/ip2/ip2main.c
    +++ b/drivers/char/ip2/ip2main.c
    @@ -1263,11 +1263,12 @@ static void do_input(struct work_struct *work)
    // code duplicated from n_tty (ldisc)
    static inline void isig(int sig, struct tty_struct *tty, int flush)
    {
    + /* FIXME: This is completely bogus */
    if (tty->pgrp)
    kill_pgrp(tty->pgrp, sig, 1);
    if (flush || !L_NOFLSH(tty)) {
    - if ( tty->ldisc.flush_buffer )
    - tty->ldisc.flush_buffer(tty);
    + if ( tty->ldisc.ops->flush_buffer )
    + tty->ldisc.ops->flush_buffer(tty);
    i2InputFlush( tty->driver_data );
    }
    }
    @@ -1316,7 +1317,7 @@ static void do_status(struct work_struct *work)
    }
    tmp = pCh->pTTY->real_raw;
    pCh->pTTY->real_raw = 0;
    - pCh->pTTY->ldisc.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
    + pCh->pTTY->ldisc->ops.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
    pCh->pTTY->real_raw = tmp;
    }
    #endif /* NEVER_HAPPENS_AS_SETUP_XXX */
    diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
    index a35bfd7..ed4e033 100644
    --- a/drivers/char/n_hdlc.c
    +++ b/drivers/char/n_hdlc.c
    @@ -199,7 +199,7 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty);
    #define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data))
    #define n_hdlc2tty(n_hdlc) ((n_hdlc)->tty)

    -static struct tty_ldisc n_hdlc_ldisc = {
    +static struct tty_ldisc_ops n_hdlc_ldisc = {
    .owner = THIS_MODULE,
    .magic = TTY_LDISC_MAGIC,
    .name = "hdlc",
    @@ -342,8 +342,8 @@ static int n_hdlc_tty_open (struct tty_struct *tty)
    #endif

    /* Flush any pending characters in the driver and discipline. */
    - if (tty->ldisc.flush_buffer)
    - tty->ldisc.flush_buffer(tty);
    + if (tty->ldisc.ops->flush_buffer)
    + tty->ldisc.ops->flush_buffer(tty);

    tty_driver_flush_buffer(tty);

    diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
    index 9021690..ae377aa 100644
    --- a/drivers/char/n_r3964.c
    +++ b/drivers/char/n_r3964.c
    @@ -143,7 +143,7 @@ static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
    static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
    char *fp, int count);

    -static struct tty_ldisc tty_ldisc_N_R3964 = {
    +static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
    .owner = THIS_MODULE,
    .magic = TTY_LDISC_MAGIC,
    .name = "R3964",
    diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
    index 8096389..708c2b1 100644
    --- a/drivers/char/n_tty.c
    +++ b/drivers/char/n_tty.c
    @@ -1573,7 +1573,7 @@ static unsigned int normal_poll(struct tty_struct *tty, struct file *file,
    return mask;
    }

    -struct tty_ldisc tty_ldisc_N_TTY = {
    +struct tty_ldisc_ops tty_ldisc_N_TTY = {
    .magic = TTY_LDISC_MAGIC,
    .name = "n_tty",
    .open = n_tty_open,
    diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
    index 1dd0e99..95743e2 100644
    --- a/drivers/char/pcmcia/synclink_cs.c
    +++ b/drivers/char/pcmcia/synclink_cs.c
    @@ -514,8 +514,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
    return;
    ld = tty_ldisc_ref(tty);
    if (ld) {
    - if (ld->receive_buf)
    - ld->receive_buf(tty, data, flags, count);
    + if (ld->ops->receive_buf)
    + ld->ops->receive_buf(tty, data, flags, count);
    tty_ldisc_deref(ld);
    }
    }
    diff --git a/drivers/char/pty.c b/drivers/char/pty.c
    index 0a05c03..76b2793 100644
    --- a/drivers/char/pty.c
    +++ b/drivers/char/pty.c
    @@ -111,7 +111,7 @@ static int pty_write(struct tty_struct * tty, const unsigned char *buf, int coun
    c = to->receive_room;
    if (c > count)
    c = count;
    - to->ldisc.receive_buf(to, buf, NULL, c);
    + to->ldisc.ops->receive_buf(to, buf, NULL, c);

    return c;
    }
    @@ -149,11 +149,11 @@ static int pty_chars_in_buffer(struct tty_struct *tty)
    int count;

    /* We should get the line discipline lock for "tty->link" */
    - if (!to || !to->ldisc.chars_in_buffer)
    + if (!to || !to->ldisc.ops->chars_in_buffer)
    return 0;

    /* The ldisc must report 0 if no characters available to be read */
    - count = to->ldisc.chars_in_buffer(to);
    + count = to->ldisc.ops->chars_in_buffer(to);

    if (tty->driver->subtype == PTY_TYPE_SLAVE) return count;

    @@ -186,8 +186,8 @@ static void pty_flush_buffer(struct tty_struct *tty)
    if (!to)
    return;

    - if (to->ldisc.flush_buffer)
    - to->ldisc.flush_buffer(to);
    + if (to->ldisc.ops->flush_buffer)
    + to->ldisc.ops->flush_buffer(to);

    if (to->packet) {
    spin_lock_irqsave(&tty->ctrl_lock, flags);
    diff --git a/drivers/char/selection.c b/drivers/char/selection.c
    index d63f5cc..2978a49 100644
    --- a/drivers/char/selection.c
    +++ b/drivers/char/selection.c
    @@ -327,7 +327,8 @@ int paste_selection(struct tty_struct *tty)
    }
    count = sel_buffer_lth - pasted;
    count = min(count, tty->receive_room);
    - tty->ldisc.receive_buf(tty, sel_buffer + pasted, NULL, count);
    + tty->ldisc.ops->receive_buf(tty, sel_buffer + pasted,
    + NULL, count);
    pasted += count;
    }
    remove_wait_queue(&vc->paste_wait, &wait);
    diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
    index ac5080d..5e4b2e6 100644
    --- a/drivers/char/synclink.c
    +++ b/drivers/char/synclink.c
    @@ -975,8 +975,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
    return;
    ld = tty_ldisc_ref(tty);
    if (ld) {
    - if (ld->receive_buf)
    - ld->receive_buf(tty, data, flags, count);
    + if (ld->ops->receive_buf)
    + ld->ops->receive_buf(tty, data, flags, count);
    tty_ldisc_deref(ld);
    }
    }
    diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
    index 55c1653..e473778 100644
    --- a/drivers/char/synclink_gt.c
    +++ b/drivers/char/synclink_gt.c
    @@ -641,8 +641,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
    return;
    ld = tty_ldisc_ref(tty);
    if (ld) {
    - if (ld->receive_buf)
    - ld->receive_buf(tty, data, flags, count);
    + if (ld->ops->receive_buf)
    + ld->ops->receive_buf(tty, data, flags, count);
    tty_ldisc_deref(ld);
    }
    }
    diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
    index bec5486..5341b5a 100644
    --- a/drivers/char/synclinkmp.c
    +++ b/drivers/char/synclinkmp.c
    @@ -712,8 +712,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
    return;
    ld = tty_ldisc_ref(tty);
    if (ld) {
    - if (ld->receive_buf)
    - ld->receive_buf(tty, data, flags, count);
    + if (ld->ops->receive_buf)
    + ld->ops->receive_buf(tty, data, flags, count);
    tty_ldisc_deref(ld);
    }
    }
    diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
    index e94bee0..ab1dd0a 100644
    --- a/drivers/char/tty_io.c
    +++ b/drivers/char/tty_io.c
    @@ -95,8 +95,9 @@
    #include
    #include
    #include
    +#include

    -#include
    +#include
    #include

    #include
    @@ -682,7 +683,7 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
    static DEFINE_SPINLOCK(tty_ldisc_lock);
    static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
    /* Line disc dispatch table */
    -static struct tty_ldisc tty_ldiscs[NR_LDISCS];
    +static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];

    /**
    * tty_register_ldisc - install a line discipline
    @@ -697,7 +698,7 @@ static struct tty_ldisc tty_ldiscs[NR_LDISCS];
    * takes tty_ldisc_lock to guard against ldisc races
    */

    -int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
    +int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
    {
    unsigned long flags;
    int ret = 0;
    @@ -706,10 +707,9 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
    return -EINVAL;

    spin_lock_irqsave(&tty_ldisc_lock, flags);
    - tty_ldiscs[disc] = *new_ldisc;
    - tty_ldiscs[disc].num = disc;
    - tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
    - tty_ldiscs[disc].refcount = 0;
    + tty_ldiscs[disc] = new_ldisc;
    + new_ldisc->num = disc;
    + new_ldisc->refcount = 0;
    spin_unlock_irqrestore(&tty_ldisc_lock, flags);

    return ret;
    @@ -737,19 +737,56 @@ int tty_unregister_ldisc(int disc)
    return -EINVAL;

    spin_lock_irqsave(&tty_ldisc_lock, flags);
    - if (tty_ldiscs[disc].refcount)
    + if (tty_ldiscs[disc]->refcount)
    ret = -EBUSY;
    else
    - tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
    + tty_ldiscs[disc] = NULL;
    spin_unlock_irqrestore(&tty_ldisc_lock, flags);

    return ret;
    }
    EXPORT_SYMBOL(tty_unregister_ldisc);

    +
    +/**
    + * tty_ldisc_try_get - try and reference an ldisc
    + * @disc: ldisc number
    + * @ld: tty ldisc structure to complete
    + *
    + * Attempt to open and lock a line discipline into place. Return
    + * the line discipline refcounted and assigned in ld. On an error
    + * report the error code back
    + */
    +
    +static int tty_ldisc_try_get(int disc, struct tty_ldisc *ld)
    +{
    + unsigned long flags;
    + struct tty_ldisc_ops *ldops;
    + int err = -EINVAL;
    +
    + spin_lock_irqsave(&tty_ldisc_lock, flags);
    + ld->ops = NULL;
    + ldops = tty_ldiscs[disc];
    + /* Check the entry is defined */
    + if (ldops) {
    + /* If the module is being unloaded we can't use it */
    + if (!try_module_get(ldops->owner))
    + err = -EAGAIN;
    + else {
    + /* lock it */
    + ldops->refcount++;
    + ld->ops = ldops;
    + err = 0;
    + }
    + }
    + spin_unlock_irqrestore(&tty_ldisc_lock, flags);
    + return err;
    +}
    +
    /**
    * tty_ldisc_get - take a reference to an ldisc
    * @disc: ldisc number
    + * @ld: tty line discipline structure to use
    *
    * Takes a reference to a line discipline. Deals with refcounts and
    * module locking counts. Returns NULL if the discipline is not available.
    @@ -760,32 +797,20 @@ EXPORT_SYMBOL(tty_unregister_ldisc);
    * takes tty_ldisc_lock to guard against ldisc races
    */

    -struct tty_ldisc *tty_ldisc_get(int disc)
    +static int tty_ldisc_get(int disc, struct tty_ldisc *ld)
    {
    - unsigned long flags;
    - struct tty_ldisc *ld;
    + int err;

    if (disc < N_TTY || disc >= NR_LDISCS)
    - return NULL;
    -
    - spin_lock_irqsave(&tty_ldisc_lock, flags);
    -
    - ld = &tty_ldiscs[disc];
    - /* Check the entry is defined */
    - if (ld->flags & LDISC_FLAG_DEFINED) {
    - /* If the module is being unloaded we can't use it */
    - if (!try_module_get(ld->owner))
    - ld = NULL;
    - else /* lock it */
    - ld->refcount++;
    - } else
    - ld = NULL;
    - spin_unlock_irqrestore(&tty_ldisc_lock, flags);
    - return ld;
    + return -EINVAL;
    + err = tty_ldisc_try_get(disc, ld);
    + if (err == -EAGAIN) {
    + request_module("tty-ldisc-%d", disc);
    + err = tty_ldisc_try_get(disc, ld);
    + }
    + return err;
    }

    -EXPORT_SYMBOL_GPL(tty_ldisc_get);
    -
    /**
    * tty_ldisc_put - drop ldisc reference
    * @disc: ldisc number
    @@ -797,22 +822,67 @@ EXPORT_SYMBOL_GPL(tty_ldisc_get);
    * takes tty_ldisc_lock to guard against ldisc races
    */

    -void tty_ldisc_put(int disc)
    +static void tty_ldisc_put(struct tty_ldisc_ops *ld)
    {
    - struct tty_ldisc *ld;
    unsigned long flags;
    + int disc = ld->num;

    BUG_ON(disc < N_TTY || disc >= NR_LDISCS);

    spin_lock_irqsave(&tty_ldisc_lock, flags);
    - ld = &tty_ldiscs[disc];
    + ld = tty_ldiscs[disc];
    BUG_ON(ld->refcount == 0);
    ld->refcount--;
    module_put(ld->owner);
    spin_unlock_irqrestore(&tty_ldisc_lock, flags);
    }

    -EXPORT_SYMBOL_GPL(tty_ldisc_put);
    +static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
    +{
    + return (*pos < NR_LDISCS) ? pos : NULL;
    +}
    +
    +static void * tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
    +{
    + (*pos)++;
    + return (*pos < NR_LDISCS) ? pos : NULL;
    +}
    +
    +static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
    +{
    +}
    +
    +static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
    +{
    + int i = *(loff_t *)v;
    + struct tty_ldisc ld;
    +
    + if (tty_ldisc_get(i, &ld) < 0)
    + return 0;
    + seq_printf(m, "%-10s %2d\n", ld.ops->name ? ld.ops->name : "???", i);
    + tty_ldisc_put(ld.ops);
    + return 0;
    +}
    +
    +static const struct seq_operations tty_ldiscs_seq_ops = {
    + .start = tty_ldiscs_seq_start,
    + .next = tty_ldiscs_seq_next,
    + .stop = tty_ldiscs_seq_stop,
    + .show = tty_ldiscs_seq_show,
    +};
    +
    +static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
    +{
    + return seq_open(file, &tty_ldiscs_seq_ops);
    +}
    +
    +const struct file_operations tty_ldiscs_proc_fops = {
    + .owner = THIS_MODULE,
    + .open = proc_tty_ldiscs_open,
    + .read = seq_read,
    + .llseek = seq_lseek,
    + .release = seq_release,
    +};

    /**
    * tty_ldisc_assign - set ldisc on a tty
    @@ -829,8 +899,8 @@ EXPORT_SYMBOL_GPL(tty_ldisc_put);

    static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
    {
    + ld->refcount = 0;
    tty->ldisc = *ld;
    - tty->ldisc.refcount = 0;
    }

    /**
    @@ -954,6 +1024,41 @@ static void tty_ldisc_enable(struct tty_struct *tty)
    }

    /**
    + * tty_ldisc_restore - helper for tty ldisc change
    + * @tty: tty to recover
    + * @old: previous ldisc
    + *
    + * Restore the previous line discipline or N_TTY when a line discipline
    + * change fails due to an open error
    + */
    +
    +static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
    +{
    + char buf[64];
    + struct tty_ldisc new_ldisc;
    +
    + /* There is an outstanding reference here so this is safe */
    + tty_ldisc_get(old->ops->num, old);
    + tty_ldisc_assign(tty, old);
    + tty_set_termios_ldisc(tty, old->ops->num);
    + if (old->ops->open && (old->ops->open(tty) < 0)) {
    + tty_ldisc_put(old->ops);
    + /* This driver is always present */
    + if (tty_ldisc_get(N_TTY, &new_ldisc) < 0)
    + panic("n_tty: get");
    + tty_ldisc_assign(tty, &new_ldisc);
    + tty_set_termios_ldisc(tty, N_TTY);
    + if (new_ldisc.ops->open) {
    + int r = new_ldisc.ops->open(tty);
    + if (r < 0)
    + panic("Couldn't open N_TTY ldisc for "
    + "%s --- error %d.",
    + tty_name(tty, buf), r);
    + }
    + }
    +}
    +
    +/**
    * tty_set_ldisc - set line discipline
    * @tty: the terminal to set
    * @ldisc: the line discipline
    @@ -967,28 +1072,18 @@ static void tty_ldisc_enable(struct tty_struct *tty)

    static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
    {
    - int retval = 0;
    - struct tty_ldisc o_ldisc;
    - char buf[64];
    + int retval;
    + struct tty_ldisc o_ldisc, new_ldisc;
    int work;
    unsigned long flags;
    - struct tty_ldisc *ld;
    struct tty_struct *o_tty;

    - if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS))
    - return -EINVAL;
    -
    restart:
    -
    - ld = tty_ldisc_get(ldisc);
    - /* Eduardo Blanco */
    - /* Cyrus Durgin */
    - if (ld == NULL) {
    - request_module("tty-ldisc-%d", ldisc);
    - ld = tty_ldisc_get(ldisc);
    - }
    - if (ld == NULL)
    - return -EINVAL;
    + /* This is a bit ugly for now but means we can break the 'ldisc
    + is part of the tty struct' assumption later */
    + retval = tty_ldisc_get(ldisc, &new_ldisc);
    + if (retval)
    + return retval;

    /*
    * Problem: What do we do if this blocks ?
    @@ -996,8 +1091,8 @@ restart:

    tty_wait_until_sent(tty, 0);

    - if (tty->ldisc.num == ldisc) {
    - tty_ldisc_put(ldisc);
    + if (tty->ldisc.ops->num == ldisc) {
    + tty_ldisc_put(new_ldisc.ops);
    return 0;
    }

    @@ -1024,7 +1119,7 @@ restart:
    /* Free the new ldisc we grabbed. Must drop the lock
    first. */
    spin_unlock_irqrestore(&tty_ldisc_lock, flags);
    - tty_ldisc_put(ldisc);
    + tty_ldisc_put(o_ldisc.ops);
    /*
    * There are several reasons we may be busy, including
    * random momentary I/O traffic. We must therefore
    @@ -1038,7 +1133,7 @@ restart:
    }
    if (o_tty && o_tty->ldisc.refcount) {
    spin_unlock_irqrestore(&tty_ldisc_lock, flags);
    - tty_ldisc_put(ldisc);
    + tty_ldisc_put(o_tty->ldisc.ops);
    if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
    return -ERESTARTSYS;
    goto restart;
    @@ -1049,8 +1144,9 @@ restart:
    * another ldisc change
    */
    if (!test_bit(TTY_LDISC, &tty->flags)) {
    + struct tty_ldisc *ld;
    spin_unlock_irqrestore(&tty_ldisc_lock, flags);
    - tty_ldisc_put(ldisc);
    + tty_ldisc_put(new_ldisc.ops);
    ld = tty_ldisc_ref_wait(tty);
    tty_ldisc_deref(ld);
    goto restart;
    @@ -1060,7 +1156,7 @@ restart:
    if (o_tty)
    clear_bit(TTY_LDISC, &o_tty->flags);
    spin_unlock_irqrestore(&tty_ldisc_lock, flags);
    -
    +
    /*
    * From this point on we know nobody has an ldisc
    * usage reference, nor can they obtain one until
    @@ -1070,45 +1166,30 @@ restart:
    work = cancel_delayed_work(&tty->buf.work);
    /*
    * Wait for ->hangup_work and ->buf.work handlers to terminate
    + * MUST NOT hold locks here.
    */
    flush_scheduled_work();
    /* Shutdown the current discipline. */
    - if (tty->ldisc.close)
    - (tty->ldisc.close)(tty);
    + if (o_ldisc.ops->close)
    + (o_ldisc.ops->close)(tty);

    /* Now set up the new line discipline. */
    - tty_ldisc_assign(tty, ld);
    + tty_ldisc_assign(tty, &new_ldisc);
    tty_set_termios_ldisc(tty, ldisc);
    - if (tty->ldisc.open)
    - retval = (tty->ldisc.open)(tty);
    + if (new_ldisc.ops->open)
    + retval = (new_ldisc.ops->open)(tty);
    if (retval < 0) {
    - tty_ldisc_put(ldisc);
    - /* There is an outstanding reference here so this is safe */
    - tty_ldisc_assign(tty, tty_ldisc_get(o_ldisc.num));
    - tty_set_termios_ldisc(tty, tty->ldisc.num);
    - if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) {
    - tty_ldisc_put(o_ldisc.num);
    - /* This driver is always present */
    - tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
    - tty_set_termios_ldisc(tty, N_TTY);
    - if (tty->ldisc.open) {
    - int r = tty->ldisc.open(tty);
    -
    - if (r < 0)
    - panic("Couldn't open N_TTY ldisc for "
    - "%s --- error %d.",
    - tty_name(tty, buf), r);
    - }
    - }
    + tty_ldisc_put(new_ldisc.ops);
    + tty_ldisc_restore(tty, &o_ldisc);
    }
    /* At this point we hold a reference to the new ldisc and a
    a reference to the old ldisc. If we ended up flipping back
    to the existing ldisc we have two references to it */

    - if (tty->ldisc.num != o_ldisc.num && tty->ops->set_ldisc)
    + if (tty->ldisc.ops->num != o_ldisc.ops->num && tty->ops->set_ldisc)
    tty->ops->set_ldisc(tty);

    - tty_ldisc_put(o_ldisc.num);
    + tty_ldisc_put(o_ldisc.ops);

    /*
    * Allow ldisc referencing to occur as soon as the driver
    @@ -1335,8 +1416,8 @@ void tty_wakeup(struct tty_struct *tty)
    if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) {
    ld = tty_ldisc_ref(tty);
    if (ld) {
    - if (ld->write_wakeup)
    - ld->write_wakeup(tty);
    + if (ld->ops->write_wakeup)
    + ld->ops->write_wakeup(tty);
    tty_ldisc_deref(ld);
    }
    }
    @@ -1357,8 +1438,8 @@ void tty_ldisc_flush(struct tty_struct *tty)
    {
    struct tty_ldisc *ld = tty_ldisc_ref(tty);
    if (ld) {
    - if (ld->flush_buffer)
    - ld->flush_buffer(tty);
    + if (ld->ops->flush_buffer)
    + ld->ops->flush_buffer(tty);
    tty_ldisc_deref(ld);
    }
    tty_buffer_flush(tty);
    @@ -1386,7 +1467,7 @@ static void tty_reset_termios(struct tty_struct *tty)
    * do_tty_hangup - actual handler for hangup events
    * @work: tty device
    *
    - * This can be called by the "eventd" kernel thread. That is process
    +k * This can be called by the "eventd" kernel thread. That is process
    * synchronous but doesn't hold any locks, so we need to make sure we
    * have the appropriate locks for what we're doing.
    *
    @@ -1449,14 +1530,14 @@ static void do_tty_hangup(struct work_struct *work)
    ld = tty_ldisc_ref(tty);
    if (ld != NULL) {
    /* We may have no line discipline at this point */
    - if (ld->flush_buffer)
    - ld->flush_buffer(tty);
    + if (ld->ops->flush_buffer)
    + ld->ops->flush_buffer(tty);
    tty_driver_flush_buffer(tty);
    if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
    - ld->write_wakeup)
    - ld->write_wakeup(tty);
    - if (ld->hangup)
    - ld->hangup(tty);
    + ld->ops->write_wakeup)
    + ld->ops->write_wakeup(tty);
    + if (ld->ops->hangup)
    + ld->ops->hangup(tty);
    }
    /*
    * FIXME: Once we trust the LDISC code better we can wait here for
    @@ -1825,8 +1906,8 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
    /* We want to wait for the line discipline to sort out in this
    situation */
    ld = tty_ldisc_ref_wait(tty);
    - if (ld->read)
    - i = (ld->read)(tty, file, buf, count);
    + if (ld->ops->read)
    + i = (ld->ops->read)(tty, file, buf, count);
    else
    i = -EIO;
    tty_ldisc_deref(ld);
    @@ -1978,10 +2059,10 @@ static ssize_t tty_write(struct file *file, const char __user *buf,
    printk(KERN_ERR "tty driver %s lacks a write_room method.\n",
    tty->driver->name);
    ld = tty_ldisc_ref_wait(tty);
    - if (!ld->write)
    + if (!ld->ops->write)
    ret = -EIO;
    else
    - ret = do_tty_write(ld->write, tty, file, buf, count);
    + ret = do_tty_write(ld->ops->write, tty, file, buf, count);
    tty_ldisc_deref(ld);
    return ret;
    }
    @@ -2076,6 +2157,7 @@ static int init_dev(struct tty_driver *driver, int idx,
    struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc;
    struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
    int retval = 0;
    + struct tty_ldisc *ld;

    /* check whether we're reopening an existing tty */
    if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
    @@ -2224,17 +2306,19 @@ static int init_dev(struct tty_driver *driver, int idx,
    * If we fail here just call release_tty to clean up. No need
    * to decrement the use counts, as release_tty doesn't care.
    */
    +
    + ld = &tty->ldisc;

    - if (tty->ldisc.open) {
    - retval = (tty->ldisc.open)(tty);
    + if (ld->ops->open) {
    + retval = (ld->ops->open)(tty);
    if (retval)
    goto release_mem_out;
    }
    - if (o_tty && o_tty->ldisc.open) {
    - retval = (o_tty->ldisc.open)(o_tty);
    + if (o_tty && o_tty->ldisc.ops->open) {
    + retval = (o_tty->ldisc.ops->open)(o_tty);
    if (retval) {
    - if (tty->ldisc.close)
    - (tty->ldisc.close)(tty);
    + if (ld->ops->close)
    + (ld->ops->close)(tty);
    goto release_mem_out;
    }
    tty_ldisc_enable(o_tty);
    @@ -2378,6 +2462,7 @@ static void release_tty(struct tty_struct *tty, int idx)
    static void release_dev(struct file *filp)
    {
    struct tty_struct *tty, *o_tty;
    + struct tty_ldisc ld;
    int pty_master, tty_closing, o_tty_closing, do_sleep;
    int devpts;
    int idx;
    @@ -2611,26 +2696,27 @@ static void release_dev(struct file *filp)
    spin_unlock_irqrestore(&tty_ldisc_lock, flags);
    /*
    * Shutdown the current line discipline, and reset it to N_TTY.
    - * N.B. why reset ldisc when we're releasing the memory??
    *
    * FIXME: this MUST get fixed for the new reflocking
    */
    - if (tty->ldisc.close)
    - (tty->ldisc.close)(tty);
    - tty_ldisc_put(tty->ldisc.num);
    + if (tty->ldisc.ops->close)
    + (tty->ldisc.ops->close)(tty);
    + tty_ldisc_put(tty->ldisc.ops);

    /*
    * Switch the line discipline back
    */
    - tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
    + WARN_ON(tty_ldisc_get(N_TTY, &ld));
    + tty_ldisc_assign(tty, &ld);
    tty_set_termios_ldisc(tty, N_TTY);
    if (o_tty) {
    /* FIXME: could o_tty be in setldisc here ? */
    clear_bit(TTY_LDISC, &o_tty->flags);
    - if (o_tty->ldisc.close)
    - (o_tty->ldisc.close)(o_tty);
    - tty_ldisc_put(o_tty->ldisc.num);
    - tty_ldisc_assign(o_tty, tty_ldisc_get(N_TTY));
    + if (o_tty->ldisc.ops->close)
    + (o_tty->ldisc.ops->close)(o_tty);
    + tty_ldisc_put(o_tty->ldisc.ops);
    + WARN_ON(tty_ldisc_get(N_TTY, &ld));
    + tty_ldisc_assign(o_tty, &ld);
    tty_set_termios_ldisc(o_tty, N_TTY);
    }
    /*
    @@ -2876,8 +2962,8 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait)
    return 0;

    ld = tty_ldisc_ref_wait(tty);
    - if (ld->poll)
    - ret = (ld->poll)(tty, filp, wait);
    + if (ld->ops->poll)
    + ret = (ld->ops->poll)(tty, filp, wait);
    tty_ldisc_deref(ld);
    return ret;
    }
    @@ -2947,7 +3033,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
    if (get_user(ch, p))
    return -EFAULT;
    ld = tty_ldisc_ref_wait(tty);
    - ld->receive_buf(tty, &ch, &mbz, 1);
    + ld->ops->receive_buf(tty, &ch, &mbz, 1);
    tty_ldisc_deref(ld);
    return 0;
    }
    @@ -3501,7 +3587,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
    case TIOCGSID:
    return tiocgsid(tty, real_tty, p);
    case TIOCGETD:
    - return put_user(tty->ldisc.num, (int __user *)p);
    + return put_user(tty->ldisc.ops->num, (int __user *)p);
    case TIOCSETD:
    return tiocsetd(tty, p);
    #ifdef CONFIG_VT
    @@ -3554,8 +3640,8 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
    }
    ld = tty_ldisc_ref_wait(tty);
    retval = -EINVAL;
    - if (ld->ioctl) {
    - retval = ld->ioctl(tty, file, cmd, arg);
    + if (ld->ops->ioctl) {
    + retval = ld->ops->ioctl(tty, file, cmd, arg);
    if (retval == -ENOIOCTLCMD)
    retval = -EINVAL;
    }
    @@ -3582,8 +3668,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
    }

    ld = tty_ldisc_ref_wait(tty);
    - if (ld->compat_ioctl)
    - retval = ld->compat_ioctl(tty, file, cmd, arg);
    + if (ld->ops->compat_ioctl)
    + retval = ld->ops->compat_ioctl(tty, file, cmd, arg);
    tty_ldisc_deref(ld);

    return retval;
    @@ -3755,7 +3841,8 @@ static void flush_to_ldisc(struct work_struct *work)
    flag_buf = head->flag_buf_ptr + head->read;
    head->read += count;
    spin_unlock_irqrestore(&tty->buf.lock, flags);
    - disc->receive_buf(tty, char_buf, flag_buf, count);
    + disc->ops->receive_buf(tty, char_buf,
    + flag_buf, count);
    spin_lock_irqsave(&tty->buf.lock, flags);
    }
    /* Restore the queue head */
    @@ -3816,9 +3903,12 @@ EXPORT_SYMBOL(tty_flip_buffer_push);

    static void initialize_tty_struct(struct tty_struct *tty)
    {
    + struct tty_ldisc ld;
    memset(tty, 0, sizeof(struct tty_struct));
    tty->magic = TTY_MAGIC;
    - tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
    + if (tty_ldisc_get(N_TTY, &ld) < 0)
    + panic("n_tty: init_tty");
    + tty_ldisc_assign(tty, &ld);
    tty->session = NULL;
    tty->pgrp = NULL;
    tty->overrun_time = jiffies;
    diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
    index b1a757a..ea41b1f 100644
    --- a/drivers/char/tty_ioctl.c
    +++ b/drivers/char/tty_ioctl.c
    @@ -491,8 +491,8 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)

    ld = tty_ldisc_ref(tty);
    if (ld != NULL) {
    - if (ld->set_termios)
    - (ld->set_termios)(tty, &old_termios);
    + if (ld->ops->set_termios)
    + (ld->ops->set_termios)(tty, &old_termios);
    tty_ldisc_deref(ld);
    }
    mutex_unlock(&tty->termios_mutex);
    @@ -552,8 +552,8 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
    ld = tty_ldisc_ref(tty);

    if (ld != NULL) {
    - if ((opt & TERMIOS_FLUSH) && ld->flush_buffer)
    - ld->flush_buffer(tty);
    + if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
    + ld->ops->flush_buffer(tty);
    tty_ldisc_deref(ld);
    }

    @@ -959,12 +959,12 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
    ld = tty_ldisc_ref(tty);
    switch (arg) {
    case TCIFLUSH:
    - if (ld && ld->flush_buffer)
    - ld->flush_buffer(tty);
    + if (ld && ld->ops->flush_buffer)
    + ld->ops->flush_buffer(tty);
    break;
    case TCIOFLUSH:
    - if (ld && ld->flush_buffer)
    - ld->flush_buffer(tty);
    + if (ld && ld->ops->flush_buffer)
    + ld->ops->flush_buffer(tty);
    /* fall through */
    case TCOFLUSH:
    tty_driver_flush_buffer(tty);
    diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
    index 7ff71ba..b9694b6 100644
    --- a/drivers/input/serio/serport.c
    +++ b/drivers/input/serio/serport.c
    @@ -216,7 +216,7 @@ static void serport_ldisc_write_wakeup(struct tty_struct * tty)
    * The line discipline structure.
    */

    -static struct tty_ldisc serport_ldisc = {
    +static struct tty_ldisc_ops serport_ldisc = {
    .owner = THIS_MODULE,
    .name = "input",
    .open = serport_ldisc_open,
    diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
    index 6ca0bb9..18deefa 100644
    --- a/drivers/isdn/capi/capi.c
    +++ b/drivers/isdn/capi/capi.c
    @@ -465,7 +465,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
    ld = tty_ldisc_ref(mp->tty);
    if (ld == NULL)
    return -1;
    - if (ld->receive_buf == NULL) {
    + if (ld->ops->receive_buf == NULL) {
    #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
    printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n");
    #endif
    @@ -500,7 +500,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
    printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
    datahandle, skb->len);
    #endif
    - ld->receive_buf(mp->tty, skb->data, NULL, skb->len);
    + ld->ops->receive_buf(mp->tty, skb->data, NULL, skb->len);
    kfree_skb(skb);
    tty_ldisc_deref(ld);
    return 0;
    diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
    index 45d1ee9..5e89fa1 100644
    --- a/drivers/isdn/gigaset/ser-gigaset.c
    +++ b/drivers/isdn/gigaset/ser-gigaset.c
    @@ -766,7 +766,7 @@ gigaset_tty_wakeup(struct tty_struct *tty)
    cs_put(cs);
    }

    -static struct tty_ldisc gigaset_ldisc = {
    +static struct tty_ldisc_ops gigaset_ldisc = {
    .owner = THIS_MODULE,
    .magic = TTY_LDISC_MAGIC,
    .name = "ser_gigaset",
    diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
    index 9d57212..19dd0a6 100644
    --- a/drivers/net/hamradio/6pack.c
    +++ b/drivers/net/hamradio/6pack.c
    @@ -783,7 +783,7 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
    return err;
    }

    -static struct tty_ldisc sp_ldisc = {
    +static struct tty_ldisc_ops sp_ldisc = {
    .owner = THIS_MODULE,
    .magic = TTY_LDISC_MAGIC,
    .name = "6pack",
    diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
    index 6516603..c6ca475 100644
    --- a/drivers/net/hamradio/mkiss.c
    +++ b/drivers/net/hamradio/mkiss.c
    @@ -969,7 +969,7 @@ out:
    mkiss_put(ax);
    }

    -static struct tty_ldisc ax_ldisc = {
    +static struct tty_ldisc_ops ax_ldisc = {
    .owner = THIS_MODULE,
    .magic = TTY_LDISC_MAGIC,
    .name = "mkiss",
    diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
    index e6f40b7..9e33196 100644
    --- a/drivers/net/irda/irtty-sir.c
    +++ b/drivers/net/irda/irtty-sir.c
    @@ -533,7 +533,7 @@ static void irtty_close(struct tty_struct *tty)

    /* ------------------------------------------------------- */

    -static struct tty_ldisc irda_ldisc = {
    +static struct tty_ldisc_ops irda_ldisc = {
    .magic = TTY_LDISC_MAGIC,
    .name = "irda",
    .flags = 0,
    diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
    index f1a52de..451bdb5 100644
    --- a/drivers/net/ppp_async.c
    +++ b/drivers/net/ppp_async.c
    @@ -378,7 +378,7 @@ ppp_asynctty_wakeup(struct tty_struct *tty)
    }


    -static struct tty_ldisc ppp_ldisc = {
    +static struct tty_ldisc_ops ppp_ldisc = {
    .owner = THIS_MODULE,
    .magic = TTY_LDISC_MAGIC,
    .name = "ppp",
    diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
    index b8f0369..801d8f9 100644
    --- a/drivers/net/ppp_synctty.c
    +++ b/drivers/net/ppp_synctty.c
    @@ -418,7 +418,7 @@ ppp_sync_wakeup(struct tty_struct *tty)
    }


    -static struct tty_ldisc ppp_sync_ldisc = {
    +static struct tty_ldisc_ops ppp_sync_ldisc = {
    .owner = THIS_MODULE,
    .magic = TTY_LDISC_MAGIC,
    .name = "pppsync",
    diff --git a/drivers/net/slip.c b/drivers/net/slip.c
    index 84af68f..1d58991 100644
    --- a/drivers/net/slip.c
    +++ b/drivers/net/slip.c
    @@ -1301,7 +1301,7 @@ static int sl_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
    #endif
    /* VSV changes end */

    -static struct tty_ldisc sl_ldisc = {
    +static struct tty_ldisc_ops sl_ldisc = {
    .owner = THIS_MODULE,
    .magic = TTY_LDISC_MAGIC,
    .name = "slip",
    diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
    index e03eef2..c2c10c6 100644
    --- a/drivers/net/wan/pc300_tty.c
    +++ b/drivers/net/wan/pc300_tty.c
    @@ -688,9 +688,9 @@ static void cpc_tty_rx_work(struct work_struct *work)
    if (cpc_tty->tty) {
    ld = tty_ldisc_ref(cpc_tty->tty);
    if (ld) {
    - if (ld->receive_buf) {
    + if (ld->ops->receive_buf) {
    CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name);
    - ld->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size);
    + ld->ops->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size);
    }
    tty_ldisc_deref(ld);
    }
    diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
    index 249e180..183806e 100644
    --- a/drivers/net/wan/x25_asy.c
    +++ b/drivers/net/wan/x25_asy.c
    @@ -751,7 +751,7 @@ static void x25_asy_setup(struct net_device *dev)
    dev->flags = IFF_NOARP;
    }

    -static struct tty_ldisc x25_ldisc = {
    +static struct tty_ldisc_ops x25_ldisc = {
    .owner = THIS_MODULE,
    .magic = TTY_LDISC_MAGIC,
    .name = "X.25",
    diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
    index 883af89..417e9e6 100644
    --- a/drivers/net/wireless/strip.c
    +++ b/drivers/net/wireless/strip.c
    @@ -2728,7 +2728,7 @@ static int strip_ioctl(struct tty_struct *tty, struct file *file,
    /************************************************** **********************/
    /* Initialization */

    -static struct tty_ldisc strip_ldisc = {
    +static struct tty_ldisc_ops strip_ldisc = {
    .magic = TTY_LDISC_MAGIC,
    .name = "strip",
    .owner = THIS_MODULE,
    diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c
    index 21f490f..d153946 100644
    --- a/fs/proc/proc_tty.c
    +++ b/fs/proc/proc_tty.c
    @@ -136,54 +136,6 @@ static const struct file_operations proc_tty_drivers_operations = {
    .release = seq_release,
    };

    -static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
    -{
    - return (*pos < NR_LDISCS) ? pos : NULL;
    -}
    -
    -static void * tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
    -{
    - (*pos)++;
    - return (*pos < NR_LDISCS) ? pos : NULL;
    -}
    -
    -static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
    -{
    -}
    -
    -static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
    -{
    - int i = *(loff_t *)v;
    - struct tty_ldisc *ld;
    -
    - ld = tty_ldisc_get(i);
    - if (ld == NULL)
    - return 0;
    - seq_printf(m, "%-10s %2d\n", ld->name ? ld->name : "???", i);
    - tty_ldisc_put(i);
    - return 0;
    -}
    -
    -static const struct seq_operations tty_ldiscs_seq_ops = {
    - .start = tty_ldiscs_seq_start,
    - .next = tty_ldiscs_seq_next,
    - .stop = tty_ldiscs_seq_stop,
    - .show = tty_ldiscs_seq_show,
    -};
    -
    -static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
    -{
    - return seq_open(file, &tty_ldiscs_seq_ops);
    -}
    -
    -static const struct file_operations tty_ldiscs_proc_fops = {
    - .owner = THIS_MODULE,
    - .open = proc_tty_ldiscs_open,
    - .read = seq_read,
    - .llseek = seq_lseek,
    - .release = seq_release,
    -};
    -
    /*
    * This function is called by tty_register_driver() to handle
    * registering the driver's /proc handler into /proc/tty/driver/
    diff --git a/include/linux/tty.h b/include/linux/tty.h
    index 324a3b2..013711e 100644
    --- a/include/linux/tty.h
    +++ b/include/linux/tty.h
    @@ -185,6 +185,7 @@ struct tty_struct {
    struct tty_driver *driver;
    const struct tty_operations *ops;
    int index;
    + /* The ldisc objects are protected by tty_ldisc_lock at the moment */
    struct tty_ldisc ldisc;
    struct mutex termios_mutex;
    spinlock_t ctrl_lock;
    @@ -289,7 +290,7 @@ extern void tty_wait_until_sent(struct tty_struct * tty, long timeout);
    extern int tty_check_change(struct tty_struct * tty);
    extern void stop_tty(struct tty_struct * tty);
    extern void start_tty(struct tty_struct * tty);
    -extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc);
    +extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
    extern int tty_unregister_ldisc(int disc);
    extern int tty_register_driver(struct tty_driver *driver);
    extern int tty_unregister_driver(struct tty_driver *driver);
    @@ -330,9 +331,7 @@ extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b);
    extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *);
    extern void tty_ldisc_deref(struct tty_ldisc *);
    extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *);
    -
    -extern struct tty_ldisc *tty_ldisc_get(int);
    -extern void tty_ldisc_put(int);
    +extern const struct file_operations tty_ldiscs_proc_fops;

    extern void tty_wakeup(struct tty_struct *tty);
    extern void tty_ldisc_flush(struct tty_struct *tty);
    @@ -354,7 +353,7 @@ extern int tty_write_lock(struct tty_struct *tty, int ndelay);


    /* n_tty.c */
    -extern struct tty_ldisc tty_ldisc_N_TTY;
    +extern struct tty_ldisc_ops tty_ldisc_N_TTY;

    /* tty_audit.c */
    #ifdef CONFIG_AUDIT
    diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h
    index 6226504..40f38d8 100644
    --- a/include/linux/tty_ldisc.h
    +++ b/include/linux/tty_ldisc.h
    @@ -104,7 +104,7 @@
    #include
    #include

    -struct tty_ldisc {
    +struct tty_ldisc_ops {
    int magic;
    char *name;
    int num;
    @@ -142,6 +142,11 @@ struct tty_ldisc {
    int refcount;
    };

    +struct tty_ldisc {
    + struct tty_ldisc_ops *ops;
    + int refcount;
    +};
    +
    #define TTY_LDISC_MAGIC 0x5403

    #define LDISC_FLAG_DEFINED 0x00000001
    diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
    index c919187..0a387f2 100644
    --- a/net/bluetooth/rfcomm/tty.c
    +++ b/net/bluetooth/rfcomm/tty.c
    @@ -617,14 +617,7 @@ static void rfcomm_tty_wakeup(unsigned long arg)
    return;

    BT_DBG("dev %p tty %p", dev, tty);
    -
    - if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
    - (tty->ldisc.write_wakeup)(tty);
    -
    - wake_up_interruptible(&tty->write_wait);
    -#ifdef SERIAL_HAVE_POLL_WAIT
    - wake_up_interruptible(&tty->poll_wait);
    -#endif
    + tty_wakeup(tty);
    }

    static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
    @@ -1005,9 +998,7 @@ static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
    return;

    skb_queue_purge(&dev->dlc->tx_queue);
    -
    - if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
    - tty->ldisc.write_wakeup(tty);
    + tty_wakeup(tty);
    }

    static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
    diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
    index 76c3057..e4e2cae 100644
    --- a/net/irda/ircomm/ircomm_tty.c
    +++ b/net/irda/ircomm/ircomm_tty.c
    @@ -650,12 +650,7 @@ static void ircomm_tty_do_softint(struct work_struct *work)
    }

    /* Check if user (still) wants to be waken up */
    - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
    - tty->ldisc.write_wakeup)
    - {
    - (tty->ldisc.write_wakeup)(tty);
    - }
    - wake_up_interruptible(&tty->write_wait);
    + tty_wakeup(tty);
    }

    /*
    @@ -1141,6 +1136,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
    struct sk_buff *skb)
    {
    struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
    + struct tty_ldisc *ld;

    IRDA_DEBUG(2, "%s()\n", __func__ );

    @@ -1173,7 +1169,11 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
    * involve the flip buffers, since we are not running in an interrupt
    * handler
    */
    - self->tty->ldisc.receive_buf(self->tty, skb->data, NULL, skb->len);
    +
    + ld = tty_ldisc_ref(self->tty);
    + if (ld)
    + ld->ops->receive_buf(self->tty, skb->data, NULL, skb->len);
    + tty_ldisc_deref(ld);

    /* No need to kfree_skb - see ircomm_ttp_data_indication() */


    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  4. [PATCH 28/70] tty-usb-console: tidy the USB console code

    From: Alan Cox

    Code tidy

    Signed-off-by: Alan Cox
    ---

    drivers/usb/serial/console.c | 127 ++++++++++++++++++++++--------------------
    1 files changed, 66 insertions(+), 61 deletions(-)


    diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
    index 940f5de..9a4cd0a 100644
    --- a/drivers/usb/serial/console.c
    +++ b/drivers/usb/serial/console.c
    @@ -6,7 +6,7 @@
    * This program is free software; you can redistribute it and/or
    * modify it under the terms of the GNU General Public License version
    * 2 as published by the Free Software Foundation.
    - *
    + *
    * Thanks to Randy Dunlap for the original version of this code.
    *
    */
    @@ -67,7 +67,7 @@ static int usb_console_setup(struct console *co, char *options)
    struct tty_struct *tty = NULL;
    struct ktermios *termios = NULL, dummy;

    - dbg ("%s", __func__);
    + dbg("%s", __func__);

    if (options) {
    baud = simple_strtoul(options, NULL, 10);
    @@ -84,52 +84,52 @@ static int usb_console_setup(struct console *co, char *options)

    /* build a cflag setting */
    switch (baud) {
    - case 1200:
    - cflag |= B1200;
    - break;
    - case 2400:
    - cflag |= B2400;
    - break;
    - case 4800:
    - cflag |= B4800;
    - break;
    - case 19200:
    - cflag |= B19200;
    - break;
    - case 38400:
    - cflag |= B38400;
    - break;
    - case 57600:
    - cflag |= B57600;
    - break;
    - case 115200:
    - cflag |= B115200;
    - break;
    - case 9600:
    - default:
    - cflag |= B9600;
    - /*
    - * Set this to a sane value to prevent a divide error
    - */
    - baud = 9600;
    - break;
    + case 1200:
    + cflag |= B1200;
    + break;
    + case 2400:
    + cflag |= B2400;
    + break;
    + case 4800:
    + cflag |= B4800;
    + break;
    + case 19200:
    + cflag |= B19200;
    + break;
    + case 38400:
    + cflag |= B38400;
    + break;
    + case 57600:
    + cflag |= B57600;
    + break;
    + case 115200:
    + cflag |= B115200;
    + break;
    + case 9600:
    + default:
    + cflag |= B9600;
    + /*
    + * Set this to a sane value to prevent a divide error
    + */
    + baud = 9600;
    + break;
    }
    switch (bits) {
    - case 7:
    - cflag |= CS7;
    - break;
    - default:
    - case 8:
    - cflag |= CS8;
    - break;
    + case 7:
    + cflag |= CS7;
    + break;
    + default:
    + case 8:
    + cflag |= CS8;
    + break;
    }
    switch (parity) {
    - case 'o': case 'O':
    - cflag |= PARODD;
    - break;
    - case 'e': case 'E':
    - cflag |= PARENB;
    - break;
    + case 'o': case 'O':
    + cflag |= PARODD;
    + break;
    + case 'e': case 'E':
    + cflag |= PARENB;
    + break;
    }
    co->cflag = cflag;

    @@ -140,7 +140,7 @@ static int usb_console_setup(struct console *co, char *options)
    serial = usb_serial_get_by_index(co->index);
    if (serial == NULL) {
    /* no device is connected yet, sorry */
    - err ("No USB device connected to ttyUSB%i", co->index);
    + err("No USB device connected to ttyUSB%i", co->index);
    return -ENODEV;
    }

    @@ -148,7 +148,7 @@ static int usb_console_setup(struct console *co, char *options)
    port->port.tty = NULL;

    info->port = port;
    -
    +
    ++port->port.count;
    if (port->port.count == 1) {
    if (serial->type->set_termios) {
    @@ -174,7 +174,7 @@ static int usb_console_setup(struct console *co, char *options)
    port->port.tty = tty;
    }

    - /* only call the device specific open if this
    + /* only call the device specific open if this
    * is the first time the port is opened */
    if (serial->type->open)
    retval = serial->type->open(NULL, port, NULL);
    @@ -211,7 +211,8 @@ reset_open_count:
    goto out;
    }

    -static void usb_console_write(struct console *co, const char *buf, unsigned count)
    +static void usb_console_write(struct console *co,
    + const char *buf, unsigned count)
    {
    static struct usbcons_info *info = &usbcons_info;
    struct usb_serial_port *port = info->port;
    @@ -228,7 +229,7 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun
    dbg("%s - port %d, %d byte(s)", __func__, port->number, count);

    if (!port->port.count) {
    - dbg ("%s - port not opened", __func__);
    + dbg("%s - port not opened", __func__);
    return;
    }

    @@ -236,14 +237,15 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun
    unsigned int i;
    unsigned int lf;
    /* search for LF so we can insert CR if necessary */
    - for (i=0, lf=0 ; i < count ; i++) {
    + for (i = 0, lf = 0 ; i < count ; i++) {
    if (*(buf + i) == 10) {
    lf = 1;
    i++;
    break;
    }
    }
    - /* pass on to the driver specific version of this function if it is available */
    + /* pass on to the driver specific version of this function if
    + it is available */
    if (serial->type->write)
    retval = serial->type->write(NULL, port, buf, i);
    else
    @@ -253,9 +255,11 @@ static void usb_console_write(struct console *co, const char *buf, unsigned coun
    /* append CR after LF */
    unsigned char cr = 13;
    if (serial->type->write)
    - retval = serial->type->write(NULL, port, &cr, 1);
    + retval = serial->type->write(NULL,
    + port, &cr, 1);
    else
    - retval = usb_serial_generic_write(NULL, port, &cr, 1);
    + retval = usb_serial_generic_write(NULL,
    + port, &cr, 1);
    dbg("%s - return value : %d", __func__, retval);
    }
    buf += i;
    @@ -273,18 +277,19 @@ static struct console usbcons = {

    void usb_serial_console_disconnect(struct usb_serial *serial)
    {
    - if (serial && serial->port && serial->port[0] && serial->port[0] == usbcons_info.port) {
    + if (serial && serial->port && serial->port[0]
    + && serial->port[0] == usbcons_info.port) {
    usb_serial_console_exit();
    usb_serial_put(serial);
    }
    }

    -void usb_serial_console_init (int serial_debug, int minor)
    +void usb_serial_console_init(int serial_debug, int minor)
    {
    debug = serial_debug;

    if (minor == 0) {
    - /*
    + /*
    * Call register_console() if this is the first device plugged
    * in. If we call it earlier, then the callback to
    * console_setup() will fail, as there is not a device seen by
    @@ -293,16 +298,16 @@ void usb_serial_console_init (int serial_debug, int minor)
    /*
    * Register console.
    * NOTES:
    - * console_setup() is called (back) immediately (from register_console).
    - * console_write() is called immediately from register_console iff
    - * CON_PRINTBUFFER is set in flags.
    + * console_setup() is called (back) immediately (from
    + * register_console). console_write() is called immediately
    + * from register_console iff CON_PRINTBUFFER is set in flags.
    */
    - dbg ("registering the USB serial console.");
    + dbg("registering the USB serial console.");
    register_console(&usbcons);
    }
    }

    -void usb_serial_console_exit (void)
    +void usb_serial_console_exit(void)
    {
    if (usbcons_info.port) {
    unregister_console(&usbcons);

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  5. [PATCH 17/70] stallion: use tty_port

    From: Alan Cox

    Switch the stallion driver to use the tty_port structure

    Signed-off-by: Alan Cox
    ---

    drivers/char/stallion.c | 160 +++++++++++++++++++++++-----------------------
    include/linux/stallion.h | 6 --
    2 files changed, 81 insertions(+), 85 deletions(-)


    diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
    index d17be10..0243efb 100644
    --- a/drivers/char/stallion.c
    +++ b/drivers/char/stallion.c
    @@ -613,17 +613,17 @@ static void stl_cd_change(struct stlport *portp)
    {
    unsigned int oldsigs = portp->sigs;

    - if (!portp->tty)
    + if (!portp->port.tty)
    return;

    portp->sigs = stl_getsignals(portp);

    if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0))
    - wake_up_interruptible(&portp->open_wait);
    + wake_up_interruptible(&portp->port.open_wait);

    if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0))
    - if (portp->flags & ASYNC_CHECK_CD)
    - tty_hangup(portp->tty);
    + if (portp->port.flags & ASYNC_CHECK_CD)
    + tty_hangup(portp->port.tty);
    }

    /*
    @@ -734,11 +734,11 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
    * On the first open of the device setup the port hardware, and
    * initialize the per port data structure.
    */
    - portp->tty = tty;
    + portp->port.tty = tty;
    tty->driver_data = portp;
    - portp->refcount++;
    + portp->port.count++;

    - if ((portp->flags & ASYNC_INITIALIZED) == 0) {
    + if ((portp->port.flags & ASYNC_INITIALIZED) == 0) {
    if (!portp->tx.buf) {
    portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
    if (!portp->tx.buf)
    @@ -752,7 +752,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
    stl_enablerxtx(portp, 1, 1);
    stl_startrxtx(portp, 1, 0);
    clear_bit(TTY_IO_ERROR, &tty->flags);
    - portp->flags |= ASYNC_INITIALIZED;
    + portp->port.flags |= ASYNC_INITIALIZED;
    }

    /*
    @@ -761,9 +761,9 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
    * The sleep here does not need interrupt protection since the wakeup
    * for it is done with the same context.
    */
    - if (portp->flags & ASYNC_CLOSING) {
    - interruptible_sleep_on(&portp->close_wait);
    - if (portp->flags & ASYNC_HUP_NOTIFY)
    + if (portp->port.flags & ASYNC_CLOSING) {
    + interruptible_sleep_on(&portp->port.close_wait);
    + if (portp->port.flags & ASYNC_HUP_NOTIFY)
    return -EAGAIN;
    return -ERESTARTSYS;
    }
    @@ -777,7 +777,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
    if ((rc = stl_waitcarrier(portp, filp)) != 0)
    return rc;

    - portp->flags |= ASYNC_NORMAL_ACTIVE;
    + portp->port.flags |= ASYNC_NORMAL_ACTIVE;

    return 0;
    }
    @@ -801,25 +801,25 @@ static int stl_waitcarrier(struct stlport *portp, struct file *filp)

    spin_lock_irqsave(&stallion_lock, flags);

    - if (portp->tty->termios->c_cflag & CLOCAL)
    + if (portp->port.tty->termios->c_cflag & CLOCAL)
    doclocal++;

    portp->openwaitcnt++;
    if (! tty_hung_up_p(filp))
    - portp->refcount--;
    + portp->port.count--;

    for (; {
    /* Takes brd_lock internally */
    stl_setsignals(portp, 1, 1);
    if (tty_hung_up_p(filp) ||
    - ((portp->flags & ASYNC_INITIALIZED) == 0)) {
    - if (portp->flags & ASYNC_HUP_NOTIFY)
    + ((portp->port.flags & ASYNC_INITIALIZED) == 0)) {
    + if (portp->port.flags & ASYNC_HUP_NOTIFY)
    rc = -EBUSY;
    else
    rc = -ERESTARTSYS;
    break;
    }
    - if (((portp->flags & ASYNC_CLOSING) == 0) &&
    + if (((portp->port.flags & ASYNC_CLOSING) == 0) &&
    (doclocal || (portp->sigs & TIOCM_CD)))
    break;
    if (signal_pending(current)) {
    @@ -827,11 +827,11 @@ static int stl_waitcarrier(struct stlport *portp, struct file *filp)
    break;
    }
    /* FIXME */
    - interruptible_sleep_on(&portp->open_wait);
    + interruptible_sleep_on(&portp->port.open_wait);
    }

    if (! tty_hung_up_p(filp))
    - portp->refcount++;
    + portp->port.count++;
    portp->openwaitcnt--;
    spin_unlock_irqrestore(&stallion_lock, flags);

    @@ -904,15 +904,15 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
    spin_unlock_irqrestore(&stallion_lock, flags);
    return;
    }
    - if ((tty->count == 1) && (portp->refcount != 1))
    - portp->refcount = 1;
    - if (portp->refcount-- > 1) {
    + if ((tty->count == 1) && (portp->port.count != 1))
    + portp->port.count = 1;
    + if (portp->port.count-- > 1) {
    spin_unlock_irqrestore(&stallion_lock, flags);
    return;
    }

    - portp->refcount = 0;
    - portp->flags |= ASYNC_CLOSING;
    + portp->port.count = 0;
    + portp->port.flags |= ASYNC_CLOSING;

    /*
    * May want to wait for any data to drain before closing. The BUSY
    @@ -930,7 +930,7 @@ static void stl_close(struct tty_struct *tty, struct file *filp)


    spin_lock_irqsave(&stallion_lock, flags);
    - portp->flags &= ~ASYNC_INITIALIZED;
    + portp->port.flags &= ~ASYNC_INITIALIZED;
    spin_unlock_irqrestore(&stallion_lock, flags);

    stl_disableintrs(portp);
    @@ -949,16 +949,16 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
    tty_ldisc_flush(tty);

    tty->closing = 0;
    - portp->tty = NULL;
    + portp->port.tty = NULL;

    if (portp->openwaitcnt) {
    if (portp->close_delay)
    msleep_interruptible(jiffies_to_msecs(portp->close_delay));
    - wake_up_interruptible(&portp->open_wait);
    + wake_up_interruptible(&portp->port.open_wait);
    }

    - portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
    - wake_up_interruptible(&portp->close_wait);
    + portp->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
    + wake_up_interruptible(&portp->port.close_wait);
    }

    /************************************************** ***************************/
    @@ -1153,7 +1153,7 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp)
    memset(&sio, 0, sizeof(struct serial_struct));
    sio.line = portp->portnr;
    sio.port = portp->ioaddr;
    - sio.flags = portp->flags;
    + sio.flags = portp->port.flags;
    sio.baud_base = portp->baud_base;
    sio.close_delay = portp->close_delay;
    sio.closing_wait = portp->closing_wait;
    @@ -1194,17 +1194,17 @@ static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp)
    if ((sio.baud_base != portp->baud_base) ||
    (sio.close_delay != portp->close_delay) ||
    ((sio.flags & ~ASYNC_USR_MASK) !=
    - (portp->flags & ~ASYNC_USR_MASK)))
    + (portp->port.flags & ~ASYNC_USR_MASK)))
    return -EPERM;
    }

    - portp->flags = (portp->flags & ~ASYNC_USR_MASK) |
    + portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) |
    (sio.flags & ASYNC_USR_MASK);
    portp->baud_base = sio.baud_base;
    portp->close_delay = sio.close_delay;
    portp->closing_wait = sio.closing_wait;
    portp->custom_divisor = sio.custom_divisor;
    - stl_setport(portp, portp->tty->termios);
    + stl_setport(portp, portp->port.tty->termios);
    return 0;
    }

    @@ -1353,7 +1353,7 @@ static void stl_settermios(struct tty_struct *tty, struct ktermios *old)
    stl_start(tty);
    }
    if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
    - wake_up_interruptible(&portp->open_wait);
    + wake_up_interruptible(&portp->port.open_wait);
    }

    /************************************************** ***************************/
    @@ -1438,7 +1438,7 @@ static void stl_hangup(struct tty_struct *tty)
    if (portp == NULL)
    return;

    - portp->flags &= ~ASYNC_INITIALIZED;
    + portp->port.flags &= ~ASYNC_INITIALIZED;
    stl_disableintrs(portp);
    if (tty->termios->c_cflag & HUPCL)
    stl_setsignals(portp, 0, 0);
    @@ -1452,10 +1452,10 @@ static void stl_hangup(struct tty_struct *tty)
    portp->tx.head = NULL;
    portp->tx.tail = NULL;
    }
    - portp->tty = NULL;
    - portp->flags &= ~ASYNC_NORMAL_ACTIVE;
    - portp->refcount = 0;
    - wake_up_interruptible(&portp->open_wait);
    + portp->port.tty = NULL;
    + portp->port.flags &= ~ASYNC_NORMAL_ACTIVE;
    + portp->port.count = 0;
    + wake_up_interruptible(&portp->port.open_wait);
    }

    /************************************************** ***************************/
    @@ -1814,8 +1814,8 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp)
    portp->baud_base = STL_BAUDBASE;
    portp->close_delay = STL_CLOSEDELAY;
    portp->closing_wait = 30 * HZ;
    - init_waitqueue_head(&portp->open_wait);
    - init_waitqueue_head(&portp->close_wait);
    + init_waitqueue_head(&portp->port.open_wait);
    + init_waitqueue_head(&portp->port.close_wait);
    portp->stats.brd = portp->brdnr;
    portp->stats.panel = portp->panelnr;
    portp->stats.port = portp->portnr;
    @@ -1840,8 +1840,8 @@ static void stl_cleanup_panels(struct stlbrd *brdp)
    portp = panelp->ports[k];
    if (portp == NULL)
    continue;
    - if (portp->tty != NULL)
    - stl_hangup(portp->tty);
    + if (portp->port.tty != NULL)
    + stl_hangup(portp->port.tty);
    kfree(portp->tx.buf);
    kfree(portp);
    }
    @@ -2513,7 +2513,7 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp)
    }

    portp->stats.state = portp->istate;
    - portp->stats.flags = portp->flags;
    + portp->stats.flags = portp->port.flags;
    portp->stats.hwid = portp->hwid;

    portp->stats.ttystate = 0;
    @@ -2524,16 +2524,16 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp)
    portp->stats.rxbuffered = 0;

    spin_lock_irqsave(&stallion_lock, flags);
    - if (portp->tty != NULL)
    - if (portp->tty->driver_data == portp) {
    - portp->stats.ttystate = portp->tty->flags;
    + if (portp->port.tty != NULL)
    + if (portp->port.tty->driver_data == portp) {
    + portp->stats.ttystate = portp->port.tty->flags;
    /* No longer available as a statistic */
    - portp->stats.rxbuffered = 1; /*portp->tty->flip.count; */
    - if (portp->tty->termios != NULL) {
    - portp->stats.cflags = portp->tty->termios->c_cflag;
    - portp->stats.iflags = portp->tty->termios->c_iflag;
    - portp->stats.oflags = portp->tty->termios->c_oflag;
    - portp->stats.lflags = portp->tty->termios->c_lflag;
    + portp->stats.rxbuffered = 1; /*portp->port.tty->flip.count; */
    + if (portp->port.tty->termios != NULL) {
    + portp->stats.cflags = portp->port.tty->termios->c_cflag;
    + portp->stats.iflags = portp->port.tty->termios->c_iflag;
    + portp->stats.oflags = portp->port.tty->termios->c_oflag;
    + portp->stats.lflags = portp->port.tty->termios->c_lflag;
    }
    }
    spin_unlock_irqrestore(&stallion_lock, flags);
    @@ -2939,15 +2939,15 @@ static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp)
    }
    baudrate = stl_baudrates[baudrate];
    if ((tiosp->c_cflag & CBAUD) == B38400) {
    - if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
    + if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
    baudrate = 57600;
    - else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
    + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
    baudrate = 115200;
    - else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
    + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
    baudrate = 230400;
    - else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
    + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
    baudrate = 460800;
    - else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
    + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
    baudrate = (portp->baud_base / portp->custom_divisor);
    }
    if (baudrate > STL_CD1400MAXBAUD)
    @@ -2969,9 +2969,9 @@ static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp)
    mcor1 |= MCOR1_DCD;
    mcor2 |= MCOR2_DCD;
    sreron |= SRER_MODEM;
    - portp->flags |= ASYNC_CHECK_CD;
    + portp->port.flags |= ASYNC_CHECK_CD;
    } else
    - portp->flags &= ~ASYNC_CHECK_CD;
    + portp->port.flags &= ~ASYNC_CHECK_CD;

    /*
    * Setup cd1400 enhanced modes if we can. In particular we want to
    @@ -3242,7 +3242,7 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state)

    if (portp == NULL)
    return;
    - tty = portp->tty;
    + tty = portp->port.tty;
    if (tty == NULL)
    return;

    @@ -3304,7 +3304,7 @@ static void stl_cd1400sendflow(struct stlport *portp, int state)

    if (portp == NULL)
    return;
    - tty = portp->tty;
    + tty = portp->port.tty;
    if (tty == NULL)
    return;

    @@ -3503,8 +3503,8 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr)
    if ((len == 0) || ((len < STL_TXBUFLOW) &&
    (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
    set_bit(ASYI_TXLOW, &portp->istate);
    - if (portp->tty)
    - tty_wakeup(portp->tty);
    + if (portp->port.tty)
    + tty_wakeup(portp->port.tty);
    }

    if (len == 0) {
    @@ -3568,7 +3568,7 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
    return;
    }
    portp = panelp->ports[(ioack >> 3)];
    - tty = portp->tty;
    + tty = portp->port.tty;

    if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) {
    outb((RDCR + portp->uartaddr), ioaddr);
    @@ -3613,7 +3613,7 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
    if (portp->rxmarkmsk & status) {
    if (status & ST_BREAK) {
    status = TTY_BREAK;
    - if (portp->flags & ASYNC_SAK) {
    + if (portp->port.flags & ASYNC_SAK) {
    do_SAK(tty);
    BRDENABLE(portp->brdnr, portp->pagenr);
    }
    @@ -3899,15 +3899,15 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp)
    }
    baudrate = stl_baudrates[baudrate];
    if ((tiosp->c_cflag & CBAUD) == B38400) {
    - if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
    + if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
    baudrate = 57600;
    - else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
    + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
    baudrate = 115200;
    - else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
    + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
    baudrate = 230400;
    - else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
    + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
    baudrate = 460800;
    - else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
    + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
    baudrate = (portp->baud_base / portp->custom_divisor);
    }
    if (baudrate > STL_SC26198MAXBAUD)
    @@ -3922,11 +3922,11 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp)
    * Check what form of modem signaling is required and set it up.
    */
    if (tiosp->c_cflag & CLOCAL) {
    - portp->flags &= ~ASYNC_CHECK_CD;
    + portp->port.flags &= ~ASYNC_CHECK_CD;
    } else {
    iopr |= IOPR_DCDCOS;
    imron |= IR_IOPORT;
    - portp->flags |= ASYNC_CHECK_CD;
    + portp->port.flags |= ASYNC_CHECK_CD;
    }

    /*
    @@ -4174,7 +4174,7 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state)

    if (portp == NULL)
    return;
    - tty = portp->tty;
    + tty = portp->port.tty;
    if (tty == NULL)
    return;

    @@ -4243,7 +4243,7 @@ static void stl_sc26198sendflow(struct stlport *portp, int state)

    if (portp == NULL)
    return;
    - tty = portp->tty;
    + tty = portp->port.tty;
    if (tty == NULL)
    return;

    @@ -4421,8 +4421,8 @@ static void stl_sc26198txisr(struct stlport *portp)
    if ((len == 0) || ((len < STL_TXBUFLOW) &&
    (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
    set_bit(ASYI_TXLOW, &portp->istate);
    - if (portp->tty)
    - tty_wakeup(portp->tty);
    + if (portp->port.tty)
    + tty_wakeup(portp->port.tty);
    }

    if (len == 0) {
    @@ -4475,7 +4475,7 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack)

    pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack);

    - tty = portp->tty;
    + tty = portp->port.tty;
    ioaddr = portp->ioaddr;
    outb(GIBCR, (ioaddr + XP_ADDR));
    len = inb(ioaddr + XP_DATA) + 1;
    @@ -4527,7 +4527,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char
    struct tty_struct *tty;
    unsigned int ioaddr;

    - tty = portp->tty;
    + tty = portp->port.tty;
    ioaddr = portp->ioaddr;

    if (status & SR_RXPARITY)
    @@ -4544,7 +4544,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char
    if (portp->rxmarkmsk & status) {
    if (status & SR_RXBREAK) {
    status = TTY_BREAK;
    - if (portp->flags & ASYNC_SAK) {
    + if (portp->port.flags & ASYNC_SAK) {
    do_SAK(tty);
    BRDENABLE(portp->brdnr, portp->pagenr);
    }
    diff --git a/include/linux/stallion.h b/include/linux/stallion.h
    index 0424d75..336af33 100644
    --- a/include/linux/stallion.h
    +++ b/include/linux/stallion.h
    @@ -69,6 +69,7 @@ struct stlrq {
    */
    struct stlport {
    unsigned long magic;
    + struct tty_port port;
    unsigned int portnr;
    unsigned int panelnr;
    unsigned int brdnr;
    @@ -76,12 +77,10 @@ struct stlport {
    int uartaddr;
    unsigned int pagenr;
    unsigned long istate;
    - int flags;
    int baud_base;
    int custom_divisor;
    int close_delay;
    int closing_wait;
    - int refcount;
    int openwaitcnt;
    int brklen;
    unsigned int sigs;
    @@ -92,9 +91,6 @@ struct stlport {
    unsigned long clk;
    unsigned long hwid;
    void *uartp;
    - struct tty_struct *tty;
    - wait_queue_head_t open_wait;
    - wait_queue_head_t close_wait;
    comstats_t stats;
    struct stlrq tx;
    };

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  6. [PATCH 30/70] cp2101: coding style

    From: Alan Cox

    Bring up to coding style

    Signed-off-by: Alan Cox
    ---

    drivers/usb/serial/cp2101.c | 318 +++++++++++++++++++++----------------------
    1 files changed, 158 insertions(+), 160 deletions(-)


    diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
    index 908803e..16a0fda 100644
    --- a/drivers/usb/serial/cp2101.c
    +++ b/drivers/usb/serial/cp2101.c
    @@ -25,7 +25,7 @@
    #include
    #include
    #include
    -#include
    +#include
    #include

    /*
    @@ -45,12 +45,12 @@ static void cp2101_close(struct tty_struct *, struct usb_serial_port *,
    static void cp2101_get_termios(struct tty_struct *);
    static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *,
    struct ktermios*);
    -static int cp2101_tiocmget (struct tty_struct *, struct file *);
    -static int cp2101_tiocmset (struct tty_struct *, struct file *,
    +static int cp2101_tiocmget(struct tty_struct *, struct file *);
    +static int cp2101_tiocmset(struct tty_struct *, struct file *,
    unsigned int, unsigned int);
    static void cp2101_break_ctl(struct tty_struct *, int);
    -static int cp2101_startup (struct usb_serial *);
    -static void cp2101_shutdown(struct usb_serial*);
    +static int cp2101_startup(struct usb_serial *);
    +static void cp2101_shutdown(struct usb_serial *);


    static int debug;
    @@ -96,7 +96,7 @@ static struct usb_device_id id_table [] = {
    { } /* Terminating Entry */
    };

    -MODULE_DEVICE_TABLE (usb, id_table);
    +MODULE_DEVICE_TABLE(usb, id_table);

    static struct usb_driver cp2101_driver = {
    .name = "cp2101",
    @@ -205,12 +205,12 @@ static int cp2101_get_config(struct usb_serial_port *port, u8 request,
    request++;

    /* Issue the request, attempting to read 'size' bytes */
    - result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0),
    + result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
    request, REQTYPE_DEVICE_TO_HOST, 0x0000,
    0, buf, size, 300);

    /* Convert data into an array of integers */
    - for (i=0; i + for (i = 0; i < length; i++)
    data[i] = le32_to_cpu(buf[i]);

    kfree(buf);
    @@ -253,12 +253,12 @@ static int cp2101_set_config(struct usb_serial_port *port, u8 request,
    buf[i] = cpu_to_le32(data[i]);

    if (size > 2) {
    - result = usb_control_msg (serial->dev,
    + result = usb_control_msg(serial->dev,
    usb_sndctrlpipe(serial->dev, 0),
    request, REQTYPE_HOST_TO_DEVICE, 0x0000,
    0, buf, size, 300);
    } else {
    - result = usb_control_msg (serial->dev,
    + result = usb_control_msg(serial->dev,
    usb_sndctrlpipe(serial->dev, 0),
    request, REQTYPE_HOST_TO_DEVICE, data[0],
    0, NULL, 0, 300);
    @@ -274,7 +274,7 @@ static int cp2101_set_config(struct usb_serial_port *port, u8 request,
    }

    /* Single data value */
    - result = usb_control_msg (serial->dev,
    + result = usb_control_msg(serial->dev,
    usb_sndctrlpipe(serial->dev, 0),
    request, REQTYPE_HOST_TO_DEVICE, data[0],
    0, NULL, 0, 300);
    @@ -292,7 +292,7 @@ static inline int cp2101_set_config_single(struct usb_serial_port *port,
    return cp2101_set_config(port, request, &data, 2);
    }

    -static int cp2101_open (struct tty_struct *tty, struct usb_serial_port *port,
    +static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port,
    struct file *filp)
    {
    struct usb_serial *serial = port->serial;
    @@ -307,7 +307,7 @@ static int cp2101_open (struct tty_struct *tty, struct usb_serial_port *port,
    }

    /* Start reading from the device */
    - usb_fill_bulk_urb (port->read_urb, serial->dev,
    + usb_fill_bulk_urb(port->read_urb, serial->dev,
    usb_rcvbulkpipe(serial->dev,
    port->bulk_in_endpointAddress),
    port->read_urb->transfer_buffer,
    @@ -330,7 +330,7 @@ static int cp2101_open (struct tty_struct *tty, struct usb_serial_port *port,
    return 0;
    }

    -static void cp2101_cleanup (struct usb_serial_port *port)
    +static void cp2101_cleanup(struct usb_serial_port *port)
    {
    struct usb_serial *serial = port->serial;

    @@ -346,7 +346,7 @@ static void cp2101_cleanup (struct usb_serial_port *port)
    }

    static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port,
    - struct file * filp)
    + struct file *filp)
    {
    dbg("%s - port %d", __func__, port->number);

    @@ -367,6 +367,7 @@ static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port,
    * from the device, corrects any unsupported values, and configures the
    * termios structure to reflect the state of the device
    */
    +
    static void cp2101_get_termios(struct tty_struct *tty)
    {
    struct usb_serial_port *port = tty->driver_data;
    @@ -391,99 +392,97 @@ static void cp2101_get_termios(struct tty_struct *tty)

    cp2101_get_config(port, CP2101_BITS, &bits, 2);
    cflag &= ~CSIZE;
    - switch(bits & BITS_DATA_MASK) {
    - case BITS_DATA_5:
    - dbg("%s - data bits = 5", __func__);
    - cflag |= CS5;
    - break;
    - case BITS_DATA_6:
    - dbg("%s - data bits = 6", __func__);
    - cflag |= CS6;
    - break;
    - case BITS_DATA_7:
    - dbg("%s - data bits = 7", __func__);
    - cflag |= CS7;
    - break;
    - case BITS_DATA_8:
    - dbg("%s - data bits = 8", __func__);
    - cflag |= CS8;
    - break;
    - case BITS_DATA_9:
    - dbg("%s - data bits = 9 (not supported, "
    - "using 8 data bits)", __func__);
    - cflag |= CS8;
    - bits &= ~BITS_DATA_MASK;
    - bits |= BITS_DATA_8;
    - cp2101_set_config(port, CP2101_BITS, &bits, 2);
    - break;
    - default:
    - dbg("%s - Unknown number of data bits, "
    - "using 8", __func__);
    - cflag |= CS8;
    - bits &= ~BITS_DATA_MASK;
    - bits |= BITS_DATA_8;
    - cp2101_set_config(port, CP2101_BITS, &bits, 2);
    - break;
    + switch (bits & BITS_DATA_MASK) {
    + case BITS_DATA_5:
    + dbg("%s - data bits = 5", __func__);
    + cflag |= CS5;
    + break;
    + case BITS_DATA_6:
    + dbg("%s - data bits = 6", __func__);
    + cflag |= CS6;
    + break;
    + case BITS_DATA_7:
    + dbg("%s - data bits = 7", __func__);
    + cflag |= CS7;
    + break;
    + case BITS_DATA_8:
    + dbg("%s - data bits = 8", __func__);
    + cflag |= CS8;
    + break;
    + case BITS_DATA_9:
    + dbg("%s - data bits = 9 (not supported, using 8 data bits)",
    + __func__);
    + cflag |= CS8;
    + bits &= ~BITS_DATA_MASK;
    + bits |= BITS_DATA_8;
    + cp2101_set_config(port, CP2101_BITS, &bits, 2);
    + break;
    + default:
    + dbg("%s - Unknown number of data bits, using 8", __func__);
    + cflag |= CS8;
    + bits &= ~BITS_DATA_MASK;
    + bits |= BITS_DATA_8;
    + cp2101_set_config(port, CP2101_BITS, &bits, 2);
    + break;
    }

    - switch(bits & BITS_PARITY_MASK) {
    - case BITS_PARITY_NONE:
    - dbg("%s - parity = NONE", __func__);
    - cflag &= ~PARENB;
    - break;
    - case BITS_PARITY_ODD:
    - dbg("%s - parity = ODD", __func__);
    - cflag |= (PARENB|PARODD);
    - break;
    - case BITS_PARITY_EVEN:
    - dbg("%s - parity = EVEN", __func__);
    - cflag &= ~PARODD;
    - cflag |= PARENB;
    - break;
    - case BITS_PARITY_MARK:
    - dbg("%s - parity = MARK (not supported, "
    - "disabling parity)", __func__);
    - cflag &= ~PARENB;
    - bits &= ~BITS_PARITY_MASK;
    - cp2101_set_config(port, CP2101_BITS, &bits, 2);
    - break;
    - case BITS_PARITY_SPACE:
    - dbg("%s - parity = SPACE (not supported, "
    - "disabling parity)", __func__);
    - cflag &= ~PARENB;
    - bits &= ~BITS_PARITY_MASK;
    - cp2101_set_config(port, CP2101_BITS, &bits, 2);
    - break;
    - default:
    - dbg("%s - Unknown parity mode, "
    - "disabling parity", __func__);
    - cflag &= ~PARENB;
    - bits &= ~BITS_PARITY_MASK;
    - cp2101_set_config(port, CP2101_BITS, &bits, 2);
    - break;
    + switch (bits & BITS_PARITY_MASK) {
    + case BITS_PARITY_NONE:
    + dbg("%s - parity = NONE", __func__);
    + cflag &= ~PARENB;
    + break;
    + case BITS_PARITY_ODD:
    + dbg("%s - parity = ODD", __func__);
    + cflag |= (PARENB|PARODD);
    + break;
    + case BITS_PARITY_EVEN:
    + dbg("%s - parity = EVEN", __func__);
    + cflag &= ~PARODD;
    + cflag |= PARENB;
    + break;
    + case BITS_PARITY_MARK:
    + dbg("%s - parity = MARK (not supported, disabling parity)",
    + __func__);
    + cflag &= ~PARENB;
    + bits &= ~BITS_PARITY_MASK;
    + cp2101_set_config(port, CP2101_BITS, &bits, 2);
    + break;
    + case BITS_PARITY_SPACE:
    + dbg("%s - parity = SPACE (not supported, disabling parity)",
    + __func__);
    + cflag &= ~PARENB;
    + bits &= ~BITS_PARITY_MASK;
    + cp2101_set_config(port, CP2101_BITS, &bits, 2);
    + break;
    + default:
    + dbg("%s - Unknown parity mode, disabling parity", __func__);
    + cflag &= ~PARENB;
    + bits &= ~BITS_PARITY_MASK;
    + cp2101_set_config(port, CP2101_BITS, &bits, 2);
    + break;
    }

    cflag &= ~CSTOPB;
    - switch(bits & BITS_STOP_MASK) {
    - case BITS_STOP_1:
    - dbg("%s - stop bits = 1", __func__);
    - break;
    - case BITS_STOP_1_5:
    - dbg("%s - stop bits = 1.5 (not supported, "
    - "using 1 stop bit)", __func__);
    - bits &= ~BITS_STOP_MASK;
    - cp2101_set_config(port, CP2101_BITS, &bits, 2);
    - break;
    - case BITS_STOP_2:
    - dbg("%s - stop bits = 2", __func__);
    - cflag |= CSTOPB;
    - break;
    - default:
    - dbg("%s - Unknown number of stop bits, "
    - "using 1 stop bit", __func__);
    - bits &= ~BITS_STOP_MASK;
    - cp2101_set_config(port, CP2101_BITS, &bits, 2);
    - break;
    + switch (bits & BITS_STOP_MASK) {
    + case BITS_STOP_1:
    + dbg("%s - stop bits = 1", __func__);
    + break;
    + case BITS_STOP_1_5:
    + dbg("%s - stop bits = 1.5 (not supported, using 1 stop bit)",
    + __func__);
    + bits &= ~BITS_STOP_MASK;
    + cp2101_set_config(port, CP2101_BITS, &bits, 2);
    + break;
    + case BITS_STOP_2:
    + dbg("%s - stop bits = 2", __func__);
    + cflag |= CSTOPB;
    + break;
    + default:
    + dbg("%s - Unknown number of stop bits, using 1 stop bit",
    + __func__);
    + bits &= ~BITS_STOP_MASK;
    + cp2101_set_config(port, CP2101_BITS, &bits, 2);
    + break;
    }

    cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16);
    @@ -498,11 +497,11 @@ static void cp2101_get_termios(struct tty_struct *tty)
    tty->termios->c_cflag = cflag;
    }

    -static void cp2101_set_termios (struct tty_struct *tty,
    +static void cp2101_set_termios(struct tty_struct *tty,
    struct usb_serial_port *port, struct ktermios *old_termios)
    {
    unsigned int cflag, old_cflag;
    - int baud=0, bits;
    + int baud = 0, bits;
    unsigned int modem_ctl[4];

    dbg("%s - port %d", __func__, port->number);
    @@ -518,30 +517,30 @@ static void cp2101_set_termios (struct tty_struct *tty,
    /* If the baud rate is to be updated*/
    if (baud != tty_termios_baud_rate(old_termios)) {
    switch (baud) {
    - case 0:
    - case 600:
    - case 1200:
    - case 1800:
    - case 2400:
    - case 4800:
    - case 7200:
    - case 9600:
    - case 14400:
    - case 19200:
    - case 28800:
    - case 38400:
    - case 55854:
    - case 57600:
    - case 115200:
    - case 127117:
    - case 230400:
    - case 460800:
    - case 921600:
    - case 3686400:
    - break;
    - default:
    - baud = 9600;
    - break;
    + case 0:
    + case 600:
    + case 1200:
    + case 1800:
    + case 2400:
    + case 4800:
    + case 7200:
    + case 9600:
    + case 14400:
    + case 19200:
    + case 28800:
    + case 38400:
    + case 55854:
    + case 57600:
    + case 115200:
    + case 127117:
    + case 230400:
    + case 460800:
    + case 921600:
    + case 3686400:
    + break;
    + default:
    + baud = 9600;
    + break;
    }

    if (baud) {
    @@ -563,28 +562,28 @@ static void cp2101_set_termios (struct tty_struct *tty,
    cp2101_get_config(port, CP2101_BITS, &bits, 2);
    bits &= ~BITS_DATA_MASK;
    switch (cflag & CSIZE) {
    - case CS5:
    - bits |= BITS_DATA_5;
    - dbg("%s - data bits = 5", __func__);
    - break;
    - case CS6:
    - bits |= BITS_DATA_6;
    - dbg("%s - data bits = 6", __func__);
    - break;
    - case CS7:
    - bits |= BITS_DATA_7;
    - dbg("%s - data bits = 7", __func__);
    - break;
    - case CS8:
    - bits |= BITS_DATA_8;
    - dbg("%s - data bits = 8", __func__);
    - break;
    - /*case CS9:
    - bits |= BITS_DATA_9;
    - dbg("%s - data bits = 9", __func__);
    - break;*/
    - default:
    - dev_err(&port->dev, "cp2101 driver does not "
    + case CS5:
    + bits |= BITS_DATA_5;
    + dbg("%s - data bits = 5", __func__);
    + break;
    + case CS6:
    + bits |= BITS_DATA_6;
    + dbg("%s - data bits = 6", __func__);
    + break;
    + case CS7:
    + bits |= BITS_DATA_7;
    + dbg("%s - data bits = 7", __func__);
    + break;
    + case CS8:
    + bits |= BITS_DATA_8;
    + dbg("%s - data bits = 8", __func__);
    + break;
    + /*case CS9:
    + bits |= BITS_DATA_9;
    + dbg("%s - data bits = 9", __func__);
    + break;*/
    + default:
    + dev_err(&port->dev, "cp2101 driver does not "
    "support the number of bits requested,"
    " using 8 bit mode\n");
    bits |= BITS_DATA_8;
    @@ -716,30 +715,29 @@ static void cp2101_break_ctl(struct tty_struct *tty, int break_state)
    else
    state = BREAK_ON;
    dbg("%s - turning break %s", __func__,
    - state==BREAK_OFF ? "off" : "on");
    + state == BREAK_OFF ? "off" : "on");
    cp2101_set_config(port, CP2101_BREAK, &state, 2);
    }

    -static int cp2101_startup (struct usb_serial *serial)
    +static int cp2101_startup(struct usb_serial *serial)
    {
    /* CP2101 buffers behave strangely unless device is reset */
    usb_reset_device(serial->dev);
    return 0;
    }

    -static void cp2101_shutdown (struct usb_serial *serial)
    +static void cp2101_shutdown(struct usb_serial *serial)
    {
    int i;

    dbg("%s", __func__);

    /* Stop reads and writes on all ports */
    - for (i=0; i < serial->num_ports; ++i) {
    + for (i = 0; i < serial->num_ports; ++i)
    cp2101_cleanup(serial->port[i]);
    - }
    }

    -static int __init cp2101_init (void)
    +static int __init cp2101_init(void)
    {
    int retval;

    @@ -759,10 +757,10 @@ static int __init cp2101_init (void)
    return 0;
    }

    -static void __exit cp2101_exit (void)
    +static void __exit cp2101_exit(void)
    {
    - usb_deregister (&cp2101_driver);
    - usb_serial_deregister (&cp2101_device);
    + usb_deregister(&cp2101_driver);
    + usb_serial_deregister(&cp2101_device);
    }

    module_init(cp2101_init);

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  7. [PATCH 11/70] isicom: use tty_port

    From: Alan Cox

    Switch isicom to use a tty_port structure for some fields

    Signed-off-by: Alan Cox
    ---

    drivers/char/isicom.c | 181 +++++++++++++++++++++----------------------------
    1 files changed, 79 insertions(+), 102 deletions(-)


    diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
    index 4f3cefa..20be56f 100644
    --- a/drivers/char/isicom.c
    +++ b/drivers/char/isicom.c
    @@ -198,17 +198,12 @@ struct isi_board {

    struct isi_port {
    unsigned short magic;
    - unsigned int flags;
    - int count;
    - int blocked_open;
    + struct tty_port port;
    int close_delay;
    u16 channel;
    u16 status;
    u16 closing_wait;
    struct isi_board *card;
    - struct tty_struct *tty;
    - wait_queue_head_t close_wait;
    - wait_queue_head_t open_wait;
    unsigned char *xmit_buf;
    int xmit_head;
    int xmit_tail;
    @@ -430,11 +425,11 @@ static void isicom_tx(unsigned long _data)

    for (; count > 0; count--, port++) {
    /* port not active or tx disabled to force flow control */
    - if (!(port->flags & ASYNC_INITIALIZED) ||
    + if (!(port->port.flags & ASYNC_INITIALIZED) ||
    !(port->status & ISI_TXOK))
    continue;

    - tty = port->tty;
    + tty = port->port.tty;

    if (tty == NULL)
    continue;
    @@ -458,7 +453,7 @@ static void isicom_tx(unsigned long _data)
    if (residue == YES) {
    residue = NO;
    if (cnt > 0) {
    - wrd |= (port->xmit_buf[port->xmit_tail]
    + wrd |= (port->port.xmit_buf[port->xmit_tail]
    << 8);
    port->xmit_tail = (port->xmit_tail + 1)
    & (SERIAL_XMIT_SIZE - 1);
    @@ -474,14 +469,14 @@ static void isicom_tx(unsigned long _data)
    if (cnt <= 0)
    break;
    word_count = cnt >> 1;
    - outsw(base, port->xmit_buf+port->xmit_tail, word_count);
    + outsw(base, port->port.xmit_buf+port->xmit_tail, word_count);
    port->xmit_tail = (port->xmit_tail
    + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
    txcount -= (word_count << 1);
    port->xmit_cnt -= (word_count << 1);
    if (cnt & 0x0001) {
    residue = YES;
    - wrd = port->xmit_buf[port->xmit_tail];
    + wrd = port->port.xmit_buf[port->xmit_tail];
    port->xmit_tail = (port->xmit_tail + 1)
    & (SERIAL_XMIT_SIZE - 1);
    port->xmit_cnt--;
    @@ -548,13 +543,13 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
    return IRQ_HANDLED;
    }
    port = card->ports + channel;
    - if (!(port->flags & ASYNC_INITIALIZED)) {
    + if (!(port->port.flags & ASYNC_INITIALIZED)) {
    outw(0x0000, base+0x04); /* enable interrupts */
    spin_unlock(&card->card_lock);
    return IRQ_HANDLED;
    }

    - tty = port->tty;
    + tty = port->port.tty;
    if (tty == NULL) {
    word_count = byte_count >> 1;
    while (byte_count > 1) {
    @@ -572,7 +567,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
    header = inw(base);
    switch (header & 0xff) {
    case 0: /* Change in EIA signals */
    - if (port->flags & ASYNC_CHECK_CD) {
    + if (port->port.flags & ASYNC_CHECK_CD) {
    if (port->status & ISI_DCD) {
    if (!(header & ISI_DCD)) {
    /* Carrier has been lost */
    @@ -585,7 +580,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
    /* Carrier has been detected */
    pr_dbg("interrupt: DCD->high.\n");
    port->status |= ISI_DCD;
    - wake_up_interruptible(&port->open_wait);
    + wake_up_interruptible(&port->port.open_wait);
    }
    } else {
    if (header & ISI_DCD)
    @@ -594,17 +589,17 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
    port->status &= ~ISI_DCD;
    }

    - if (port->flags & ASYNC_CTS_FLOW) {
    - if (port->tty->hw_stopped) {
    + if (port->port.flags & ASYNC_CTS_FLOW) {
    + if (port->port.tty->hw_stopped) {
    if (header & ISI_CTS) {
    - port->tty->hw_stopped = 0;
    + port->port.tty->hw_stopped = 0;
    /* start tx ing */
    port->status |= (ISI_TXOK
    | ISI_CTS);
    tty_wakeup(tty);
    }
    } else if (!(header & ISI_CTS)) {
    - port->tty->hw_stopped = 1;
    + port->port.tty->hw_stopped = 1;
    /* stop tx ing */
    port->status &= ~(ISI_TXOK | ISI_CTS);
    }
    @@ -629,7 +624,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)

    case 1: /* Received Break !!! */
    tty_insert_flip_char(tty, 0, TTY_BREAK);
    - if (port->flags & ASYNC_SAK)
    + if (port->port.flags & ASYNC_SAK)
    do_SAK(tty);
    tty_flip_buffer_push(tty);
    break;
    @@ -681,7 +676,7 @@ static void isicom_config_port(struct isi_port *port)
    shift_count = card->shift_count;
    unsigned char flow_ctrl;

    - tty = port->tty;
    + tty = port->port.tty;

    if (tty == NULL)
    return;
    @@ -697,7 +692,7 @@ static void isicom_config_port(struct isi_port *port)

    /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
    if (baud < 1 || baud > 4)
    - port->tty->termios->c_cflag &= ~CBAUDEX;
    + port->port.tty->termios->c_cflag &= ~CBAUDEX;
    else
    baud += 15;
    }
    @@ -708,13 +703,13 @@ static void isicom_config_port(struct isi_port *port)
    * the 'setserial' utility.
    */

    - if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
    + if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
    baud++; /* 57.6 Kbps */
    - if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
    + if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
    baud += 2; /* 115 Kbps */
    - if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
    + if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
    baud += 3; /* 230 kbps*/
    - if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
    + if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
    baud += 4; /* 460 kbps*/
    }
    if (linuxb_to_isib[baud] == -1) {
    @@ -754,15 +749,15 @@ static void isicom_config_port(struct isi_port *port)
    InterruptTheCard(base);
    }
    if (C_CLOCAL(tty))
    - port->flags &= ~ASYNC_CHECK_CD;
    + port->port.flags &= ~ASYNC_CHECK_CD;
    else
    - port->flags |= ASYNC_CHECK_CD;
    + port->port.flags |= ASYNC_CHECK_CD;

    /* flow control settings ...*/
    flow_ctrl = 0;
    - port->flags &= ~ASYNC_CTS_FLOW;
    + port->port.flags &= ~ASYNC_CTS_FLOW;
    if (C_CRTSCTS(tty)) {
    - port->flags |= ASYNC_CTS_FLOW;
    + port->port.flags |= ASYNC_CTS_FLOW;
    flow_ctrl |= ISICOM_CTSRTS;
    }
    if (I_IXON(tty))
    @@ -809,23 +804,15 @@ static int isicom_setup_port(struct isi_port *port)
    struct isi_board *card = port->card;
    unsigned long flags;

    - if (port->flags & ASYNC_INITIALIZED)
    + if (port->port.flags & ASYNC_INITIALIZED)
    return 0;
    - if (!port->xmit_buf) {
    - /* Relies on BKL */
    - unsigned long page = get_zeroed_page(GFP_KERNEL);
    - if (page == 0)
    - return -ENOMEM;
    - if (port->xmit_buf)
    - free_page(page);
    - else
    - port->xmit_buf = (unsigned char *) page;
    - }
    + if (tty_port_alloc_xmit_buf(&port->port) < 0)
    + return -ENOMEM;

    spin_lock_irqsave(&card->card_lock, flags);
    - if (port->tty)
    - clear_bit(TTY_IO_ERROR, &port->tty->flags);
    - if (port->count == 1)
    + if (port->port.tty)
    + clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
    + if (port->port.count == 1)
    card->count++;

    port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
    @@ -839,7 +826,7 @@ static int isicom_setup_port(struct isi_port *port)
    }

    isicom_config_port(port);
    - port->flags |= ASYNC_INITIALIZED;
    + port->port.flags |= ASYNC_INITIALIZED;
    spin_unlock_irqrestore(&card->card_lock, flags);

    return 0;
    @@ -855,10 +842,10 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,

    /* block if port is in the process of being closed */

    - if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
    + if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
    pr_dbg("block_til_ready: close in progress.\n");
    - interruptible_sleep_on(&port->close_wait);
    - if (port->flags & ASYNC_HUP_NOTIFY)
    + interruptible_sleep_on(&port->port.close_wait);
    + if (port->port.flags & ASYNC_HUP_NOTIFY)
    return -EAGAIN;
    else
    return -ERESTARTSYS;
    @@ -869,7 +856,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
    if ((filp->f_flags & O_NONBLOCK) ||
    (tty->flags & (1 << TTY_IO_ERROR))) {
    pr_dbg("block_til_ready: non-block mode.\n");
    - port->flags |= ASYNC_NORMAL_ACTIVE;
    + port->port.flags |= ASYNC_NORMAL_ACTIVE;
    return 0;
    }

    @@ -879,26 +866,26 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
    /* block waiting for DCD to be asserted, and while
    callout dev is busy */
    retval = 0;
    - add_wait_queue(&port->open_wait, &wait);
    + add_wait_queue(&port->port.open_wait, &wait);

    spin_lock_irqsave(&card->card_lock, flags);
    if (!tty_hung_up_p(filp))
    - port->count--;
    - port->blocked_open++;
    + port->port.count--;
    + port->port.blocked_open++;
    spin_unlock_irqrestore(&card->card_lock, flags);

    while (1) {
    raise_dtr_rts(port);

    set_current_state(TASK_INTERRUPTIBLE);
    - if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) {
    - if (port->flags & ASYNC_HUP_NOTIFY)
    + if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) {
    + if (port->port.flags & ASYNC_HUP_NOTIFY)
    retval = -EAGAIN;
    else
    retval = -ERESTARTSYS;
    break;
    }
    - if (!(port->flags & ASYNC_CLOSING) &&
    + if (!(port->port.flags & ASYNC_CLOSING) &&
    (do_clocal || (port->status & ISI_DCD))) {
    break;
    }
    @@ -909,15 +896,15 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
    schedule();
    }
    set_current_state(TASK_RUNNING);
    - remove_wait_queue(&port->open_wait, &wait);
    + remove_wait_queue(&port->port.open_wait, &wait);
    spin_lock_irqsave(&card->card_lock, flags);
    if (!tty_hung_up_p(filp))
    - port->count++;
    - port->blocked_open--;
    + port->port.count++;
    + port->port.blocked_open--;
    spin_unlock_irqrestore(&card->card_lock, flags);
    if (retval)
    return retval;
    - port->flags |= ASYNC_NORMAL_ACTIVE;
    + port->port.flags |= ASYNC_NORMAL_ACTIVE;
    return 0;
    }

    @@ -947,9 +934,9 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)

    isicom_setup_board(card);

    - port->count++;
    + port->port.count++;
    tty->driver_data = port;
    - port->tty = tty;
    + port->port.tty = tty;
    error = isicom_setup_port(port);
    if (error == 0)
    error = block_til_ready(tty, filp, port);
    @@ -970,18 +957,15 @@ static void isicom_shutdown_port(struct isi_port *port)
    struct isi_board *card = port->card;
    struct tty_struct *tty;

    - tty = port->tty;
    + tty = port->port.tty;

    - if (!(port->flags & ASYNC_INITIALIZED))
    + if (!(port->port.flags & ASYNC_INITIALIZED))
    return;

    - if (port->xmit_buf) {
    - free_page((unsigned long) port->xmit_buf);
    - port->xmit_buf = NULL;
    - }
    - port->flags &= ~ASYNC_INITIALIZED;
    + tty_port_free_xmit_buf(&port->port);
    + port->port.flags &= ~ASYNC_INITIALIZED;
    /* 3rd October 2000 : Vinayak P Risbud */
    - port->tty = NULL;
    + port->port.tty = NULL;

    /*Fix done by Anil .S on 30-04-2001
    remote login through isi port has dtr toggle problem
    @@ -1046,24 +1030,24 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
    return;
    }

    - if (tty->count == 1 && port->count != 1) {
    + if (tty->count == 1 && port->port.count != 1) {
    printk(KERN_WARNING "ISICOM0x%lx) isicom_close: bad port "
    "count tty->count = 1 port count = %d.\n",
    - card->base, port->count);
    - port->count = 1;
    + card->base, port->port.count);
    + port->port.count = 1;
    }
    - if (--port->count < 0) {
    + if (--port->port.count < 0) {
    printk(KERN_WARNING "ISICOM0x%lx) isicom_close: bad port "
    "count for channel%d = %d", card->base, port->channel,
    - port->count);
    - port->count = 0;
    + port->port.count);
    + port->port.count = 0;
    }

    - if (port->count) {
    + if (port->port.count) {
    spin_unlock_irqrestore(&card->card_lock, flags);
    return;
    }
    - port->flags |= ASYNC_CLOSING;
    + port->port.flags |= ASYNC_CLOSING;
    tty->closing = 1;
    spin_unlock_irqrestore(&card->card_lock, flags);

    @@ -1072,7 +1056,7 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
    /* indicate to the card that no more data can be received
    on this port */
    spin_lock_irqsave(&card->card_lock, flags);
    - if (port->flags & ASYNC_INITIALIZED) {
    + if (port->port.flags & ASYNC_INITIALIZED) {
    card->port_status &= ~(1 << port->channel);
    outw(card->port_status, card->base + 0x02);
    }
    @@ -1085,7 +1069,7 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
    spin_lock_irqsave(&card->card_lock, flags);
    tty->closing = 0;

    - if (port->blocked_open) {
    + if (port->port.blocked_open) {
    spin_unlock_irqrestore(&card->card_lock, flags);
    if (port->close_delay) {
    pr_dbg("scheduling until time out.\n");
    @@ -1093,10 +1077,10 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
    jiffies_to_msecs(port->close_delay));
    }
    spin_lock_irqsave(&card->card_lock, flags);
    - wake_up_interruptible(&port->open_wait);
    + wake_up_interruptible(&port->port.open_wait);
    }
    - port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
    - wake_up_interruptible(&port->close_wait);
    + port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
    + wake_up_interruptible(&port->port.close_wait);
    spin_unlock_irqrestore(&card->card_lock, flags);
    }

    @@ -1112,9 +1096,6 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
    if (isicom_paranoia_check(port, tty->name, "isicom_write"))
    return 0;

    - if (!port->xmit_buf)
    - return 0;
    -
    spin_lock_irqsave(&card->card_lock, flags);

    while (1) {
    @@ -1123,7 +1104,7 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
    if (cnt <= 0)
    break;

    - memcpy(port->xmit_buf + port->xmit_head, buf, cnt);
    + memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt);
    port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
    - 1);
    port->xmit_cnt += cnt;
    @@ -1147,16 +1128,13 @@ static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
    if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
    return 0;

    - if (!port->xmit_buf)
    - return 0;
    -
    spin_lock_irqsave(&card->card_lock, flags);
    if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
    spin_unlock_irqrestore(&card->card_lock, flags);
    return 0;
    }

    - port->xmit_buf[port->xmit_head++] = ch;
    + port->port.xmit_buf[port->xmit_head++] = ch;
    port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
    port->xmit_cnt++;
    spin_unlock_irqrestore(&card->card_lock, flags);
    @@ -1172,7 +1150,7 @@ static void isicom_flush_chars(struct tty_struct *tty)
    return;

    if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
    - !port->xmit_buf)
    + !port->port.xmit_buf)
    return;

    /* this tells the transmitter to consider this port for
    @@ -1274,23 +1252,23 @@ static int isicom_set_serial_info(struct isi_port *port,

    lock_kernel();

    - reconfig_port = ((port->flags & ASYNC_SPD_MASK) !=
    + reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) !=
    (newinfo.flags & ASYNC_SPD_MASK));

    if (!capable(CAP_SYS_ADMIN)) {
    if ((newinfo.close_delay != port->close_delay) ||
    (newinfo.closing_wait != port->closing_wait) ||
    ((newinfo.flags & ~ASYNC_USR_MASK) !=
    - (port->flags & ~ASYNC_USR_MASK))) {
    + (port->port.flags & ~ASYNC_USR_MASK))) {
    unlock_kernel();
    return -EPERM;
    }
    - port->flags = ((port->flags & ~ASYNC_USR_MASK) |
    + port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
    (newinfo.flags & ASYNC_USR_MASK));
    } else {
    port->close_delay = newinfo.close_delay;
    port->closing_wait = newinfo.closing_wait;
    - port->flags = ((port->flags & ~ASYNC_FLAGS) |
    + port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
    (newinfo.flags & ASYNC_FLAGS));
    }
    if (reconfig_port) {
    @@ -1314,7 +1292,7 @@ static int isicom_get_serial_info(struct isi_port *port,
    out_info.line = port - isi_ports;
    out_info.port = port->card->base;
    out_info.irq = port->card->irq;
    - out_info.flags = port->flags;
    + out_info.flags = port->port.flags;
    /* out_info.baud_base = ? */
    out_info.close_delay = port->close_delay;
    out_info.closing_wait = port->closing_wait;
    @@ -1454,10 +1432,10 @@ static void isicom_hangup(struct tty_struct *tty)
    isicom_shutdown_port(port);
    spin_unlock_irqrestore(&port->card->card_lock, flags);

    - port->count = 0;
    - port->flags &= ~ASYNC_NORMAL_ACTIVE;
    - port->tty = NULL;
    - wake_up_interruptible(&port->open_wait);
    + port->port.count = 0;
    + port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
    + port->port.tty = NULL;
    + wake_up_interruptible(&port->port.open_wait);
    }


    @@ -1824,8 +1802,7 @@ static int __init isicom_init(void)
    port->close_delay = 50 * HZ/100;
    port->closing_wait = 3000 * HZ/100;
    port->status = 0;
    - init_waitqueue_head(&port->open_wait);
    - init_waitqueue_head(&port->close_wait);
    + tty_port_init(&port->port);
    /* . . . */
    }
    isi_card[idx].base = 0;

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  8. [PATCH 06/70] epca: use tty_port

    From: Alan Cox

    Switch the EPCA driver to include and begin using a tty_port structure

    Signed-off-by: Alan Cox
    ---

    drivers/char/epca.c | 106 ++++++++++++++++++++++++++-------------------------
    drivers/char/epca.h | 7 ---
    2 files changed, 54 insertions(+), 59 deletions(-)


    diff --git a/drivers/char/epca.c b/drivers/char/epca.c
    index aa8e19f..ac9995f 100644
    --- a/drivers/char/epca.c
    +++ b/drivers/char/epca.c
    @@ -432,7 +432,7 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
    spin_unlock_irqrestore(&epca_lock, flags);
    return;
    }
    - if (ch->count-- > 1) {
    + if (ch->port.count-- > 1) {
    /* Begin channel is open more than once */
    /*
    * Return without doing anything. Someone might still
    @@ -442,19 +442,19 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
    return;
    }
    /* Port open only once go ahead with shutdown & reset */
    - BUG_ON(ch->count < 0);
    + BUG_ON(ch->port.count < 0);

    /*
    * Let the rest of the driver know the channel is being closed.
    * This becomes important if an open is attempted before close
    * is finished.
    */
    - ch->asyncflags |= ASYNC_CLOSING;
    + ch->port.flags |= ASYNC_CLOSING;
    tty->closing = 1;

    spin_unlock_irqrestore(&epca_lock, flags);

    - if (ch->asyncflags & ASYNC_INITIALIZED) {
    + if (ch->port.flags & ASYNC_INITIALIZED) {
    /* Setup an event to indicate when the
    transmit buffer empties */
    setup_empty_event(tty, ch);
    @@ -469,17 +469,17 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
    spin_lock_irqsave(&epca_lock, flags);
    tty->closing = 0;
    ch->event = 0;
    - ch->tty = NULL;
    + ch->port.tty = NULL;
    spin_unlock_irqrestore(&epca_lock, flags);

    - if (ch->blocked_open) {
    + if (ch->port.blocked_open) {
    if (ch->close_delay)
    msleep_interruptible(jiffies_to_msecs(ch->close_delay));
    - wake_up_interruptible(&ch->open_wait);
    + wake_up_interruptible(&ch->port.open_wait);
    }
    - ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED |
    + ch->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED |
    ASYNC_CLOSING);
    - wake_up_interruptible(&ch->close_wait);
    + wake_up_interruptible(&ch->port.close_wait);
    }
    }

    @@ -489,7 +489,7 @@ static void shutdown(struct channel *ch)
    struct tty_struct *tty;
    struct board_chan __iomem *bc;

    - if (!(ch->asyncflags & ASYNC_INITIALIZED))
    + if (!(ch->port.flags & ASYNC_INITIALIZED))
    return;

    spin_lock_irqsave(&epca_lock, flags);
    @@ -504,7 +504,7 @@ static void shutdown(struct channel *ch)
    */
    if (bc)
    writeb(0, &bc->idata);
    - tty = ch->tty;
    + tty = ch->port.tty;

    /* If we're a modem control device and HUPCL is on, drop RTS & DTR. */
    if (tty->termios->c_cflag & HUPCL) {
    @@ -518,7 +518,7 @@ static void shutdown(struct channel *ch)
    * will have to reinitialized. Set a flag to indicate this.
    */
    /* Prevent future Digi programmed interrupts from coming active */
    - ch->asyncflags &= ~ASYNC_INITIALIZED;
    + ch->port.flags &= ~ASYNC_INITIALIZED;
    spin_unlock_irqrestore(&epca_lock, flags);
    }

    @@ -538,12 +538,12 @@ static void pc_hangup(struct tty_struct *tty)
    shutdown(ch);

    spin_lock_irqsave(&epca_lock, flags);
    - ch->tty = NULL;
    + ch->port.tty = NULL;
    ch->event = 0;
    - ch->count = 0;
    - ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED);
    + ch->port.count = 0;
    + ch->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED);
    spin_unlock_irqrestore(&epca_lock, flags);
    - wake_up_interruptible(&ch->open_wait);
    + wake_up_interruptible(&ch->port.open_wait);
    }
    }

    @@ -795,7 +795,7 @@ static int block_til_ready(struct tty_struct *tty,
    unsigned long flags;

    if (tty_hung_up_p(filp)) {
    - if (ch->asyncflags & ASYNC_HUP_NOTIFY)
    + if (ch->port.flags & ASYNC_HUP_NOTIFY)
    retval = -EAGAIN;
    else
    retval = -ERESTARTSYS;
    @@ -806,10 +806,10 @@ static int block_til_ready(struct tty_struct *tty,
    * If the device is in the middle of being closed, then block until
    * it's done, and then try again.
    */
    - if (ch->asyncflags & ASYNC_CLOSING) {
    - interruptible_sleep_on(&ch->close_wait);
    + if (ch->port.flags & ASYNC_CLOSING) {
    + interruptible_sleep_on(&ch->port.close_wait);

    - if (ch->asyncflags & ASYNC_HUP_NOTIFY)
    + if (ch->port.flags & ASYNC_HUP_NOTIFY)
    return -EAGAIN;
    else
    return -ERESTARTSYS;
    @@ -820,7 +820,7 @@ static int block_til_ready(struct tty_struct *tty,
    * If non-blocking mode is set, then make the check up front
    * and then exit.
    */
    - ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
    + ch->port.flags |= ASYNC_NORMAL_ACTIVE;
    return 0;
    }
    if (tty->termios->c_cflag & CLOCAL)
    @@ -828,24 +828,24 @@ static int block_til_ready(struct tty_struct *tty,
    /* Block waiting for the carrier detect and the line to become free */

    retval = 0;
    - add_wait_queue(&ch->open_wait, &wait);
    + add_wait_queue(&ch->port.open_wait, &wait);

    spin_lock_irqsave(&epca_lock, flags);
    /* We dec count so that pc_close will know when to free things */
    if (!tty_hung_up_p(filp))
    - ch->count--;
    - ch->blocked_open++;
    + ch->port.count--;
    + ch->port.blocked_open++;
    while (1) {
    set_current_state(TASK_INTERRUPTIBLE);
    if (tty_hung_up_p(filp) ||
    - !(ch->asyncflags & ASYNC_INITIALIZED)) {
    - if (ch->asyncflags & ASYNC_HUP_NOTIFY)
    + !(ch->port.flags & ASYNC_INITIALIZED)) {
    + if (ch->port.flags & ASYNC_HUP_NOTIFY)
    retval = -EAGAIN;
    else
    retval = -ERESTARTSYS;
    break;
    }
    - if (!(ch->asyncflags & ASYNC_CLOSING) &&
    + if (!(ch->port.flags & ASYNC_CLOSING) &&
    (do_clocal || (ch->imodem & ch->dcd)))
    break;
    if (signal_pending(current)) {
    @@ -864,17 +864,17 @@ static int block_til_ready(struct tty_struct *tty,
    }

    __set_current_state(TASK_RUNNING);
    - remove_wait_queue(&ch->open_wait, &wait);
    + remove_wait_queue(&ch->port.open_wait, &wait);
    if (!tty_hung_up_p(filp))
    - ch->count++;
    - ch->blocked_open--;
    + ch->port.count++;
    + ch->port.blocked_open--;

    spin_unlock_irqrestore(&epca_lock, flags);

    if (retval)
    return retval;

    - ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
    + ch->port.flags |= ASYNC_NORMAL_ACTIVE;
    return 0;
    }

    @@ -933,7 +933,7 @@ static int pc_open(struct tty_struct *tty, struct file *filp)
    * necessary because we do not wish to flush and shutdown the channel
    * until the last app holding the channel open, closes it.
    */
    - ch->count++;
    + ch->port.count++;
    /*
    * Set a kernel structures pointer to our local channel structure. This
    * way we can get to it when passed only a tty struct.
    @@ -957,14 +957,14 @@ static int pc_open(struct tty_struct *tty, struct file *filp)
    writew(head, &bc->rout);

    /* Set the channels associated tty structure */
    - ch->tty = tty;
    + ch->port.tty = tty;

    /*
    * The below routine generally sets up parity, baud, flow control
    * issues, etc.... It effect both control flags and input flags.
    */
    epcaparam(tty, ch);
    - ch->asyncflags |= ASYNC_INITIALIZED;
    + ch->port.flags |= ASYNC_INITIALIZED;
    memoff(ch);
    spin_unlock_irqrestore(&epca_lock, flags);

    @@ -976,7 +976,7 @@ static int pc_open(struct tty_struct *tty, struct file *filp)
    * waiting for the line...
    */
    spin_lock_irqsave(&epca_lock, flags);
    - ch->tty = tty;
    + ch->port.tty = tty;
    globalwinon(ch);
    /* Enable Digi Data events */
    writeb(1, &bc->idata);
    @@ -1017,8 +1017,8 @@ static void __exit epca_module_exit(void)
    }
    ch = card_ptr[crd];
    for (count = 0; count < bd->numports; count++, ch++) {
    - if (ch && ch->tty)
    - tty_hangup(ch->tty);
    + if (ch && ch->port.tty)
    + tty_hangup(ch->port.tty);
    }
    }
    pci_unregister_driver(&epca_driver);
    @@ -1427,7 +1427,7 @@ static void post_fep_init(unsigned int crd)
    ch->boardnum = crd;
    ch->channelnum = i;
    ch->magic = EPCA_MAGIC;
    - ch->tty = NULL;
    + ch->port.tty = NULL;

    if (shrinkmem) {
    fepcmd(ch, SETBUFFER, 32, 0, 0, 0);
    @@ -1510,10 +1510,10 @@ static void post_fep_init(unsigned int crd)
    ch->fepstopca = 0;

    ch->close_delay = 50;
    - ch->count = 0;
    - ch->blocked_open = 0;
    - init_waitqueue_head(&ch->open_wait);
    - init_waitqueue_head(&ch->close_wait);
    + ch->port.count = 0;
    + ch->port.blocked_open = 0;
    + init_waitqueue_head(&ch->port.open_wait);
    + init_waitqueue_head(&ch->port.close_wait);

    spin_unlock_irqrestore(&epca_lock, flags);
    }
    @@ -1633,15 +1633,15 @@ static void doevent(int crd)
    if (event & MODEMCHG_IND) {
    /* A modem signal change has been indicated */
    ch->imodem = mstat;
    - if (ch->asyncflags & ASYNC_CHECK_CD) {
    + if (ch->port.flags & ASYNC_CHECK_CD) {
    /* We are now receiving dcd */
    if (mstat & ch->dcd)
    - wake_up_interruptible(&ch->open_wait);
    + wake_up_interruptible(&ch->port.open_wait);
    else /* No dcd; hangup */
    pc_sched_event(ch, EPCA_EVENT_HANGUP);
    }
    }
    - tty = ch->tty;
    + tty = ch->port.tty;
    if (tty) {
    if (event & BREAK_IND) {
    /* A break has been indicated */
    @@ -1880,9 +1880,9 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
    * that the driver will wait on carrier detect.
    */
    if (ts->c_cflag & CLOCAL)
    - ch->asyncflags &= ~ASYNC_CHECK_CD;
    + ch->port.flags &= ~ASYNC_CHECK_CD;
    else
    - ch->asyncflags |= ASYNC_CHECK_CD;
    + ch->port.flags |= ASYNC_CHECK_CD;
    mval = ch->m_dtr | ch->m_rts;
    } /* End CBAUD not detected */
    iflag = termios2digi_i(ch, ts->c_iflag);
    @@ -1972,7 +1972,7 @@ static void receive_data(struct channel *ch)
    globalwinon(ch);
    if (ch->statusflags & RXSTOPPED)
    return;
    - tty = ch->tty;
    + tty = ch->port.tty;
    if (tty)
    ts = tty->termios;
    bc = ch->brdchan;
    @@ -2032,7 +2032,7 @@ static void receive_data(struct channel *ch)
    globalwinon(ch);
    writew(tail, &bc->rout);
    /* Must be called with global data */
    - tty_schedule_flip(ch->tty);
    + tty_schedule_flip(ch->port.tty);
    }

    static int info_ioctl(struct tty_struct *tty, struct file *file,
    @@ -2376,7 +2376,7 @@ static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios)

    if (!(old_termios->c_cflag & CLOCAL) &&
    (tty->termios->c_cflag & CLOCAL))
    - wake_up_interruptible(&ch->open_wait);
    + wake_up_interruptible(&ch->port.open_wait);

    } /* End if channel valid */
    }
    @@ -2386,13 +2386,13 @@ static void do_softint(struct work_struct *work)
    struct channel *ch = container_of(work, struct channel, tqueue);
    /* Called in response to a modem change event */
    if (ch && ch->magic == EPCA_MAGIC) {
    - struct tty_struct *tty = ch->tty;
    + struct tty_struct *tty = ch->port.tty;

    if (tty && tty->driver_data) {
    if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
    tty_hangup(tty);
    - wake_up_interruptible(&ch->open_wait);
    - ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
    + wake_up_interruptible(&ch->port.open_wait);
    + ch->port.flags &= ~ASYNC_NORMAL_ACTIVE;
    }
    }
    }
    diff --git a/drivers/char/epca.h b/drivers/char/epca.h
    index 3c77c02..d414bf2 100644
    --- a/drivers/char/epca.h
    +++ b/drivers/char/epca.h
    @@ -84,6 +84,7 @@ static char *board_desc[] =
    struct channel
    {
    long magic;
    + struct tty_port port;
    unsigned char boardnum;
    unsigned char channelnum;
    unsigned char omodem; /* FEP output modem status */
    @@ -117,10 +118,7 @@ struct channel
    unsigned short rxbufhead;
    unsigned short rxbufsize;
    int close_delay;
    - int count;
    - int blocked_open;
    unsigned long event;
    - int asyncflags;
    uint dev;
    unsigned long statusflags;
    unsigned long c_iflag;
    @@ -132,9 +130,6 @@ struct channel
    struct board_info *board;
    struct board_chan __iomem *brdchan;
    struct digi_struct digiext;
    - struct tty_struct *tty;
    - wait_queue_head_t open_wait;
    - wait_queue_head_t close_wait;
    struct work_struct tqueue;
    struct global_data __iomem *mailbox;
    };

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  9. [PATCH 16/70] serial: use tty_port

    From: Alan Cox

    Switch the serial_core based drivers to use the new tty_port structure. We
    can't quite use all of it yet because of the dynamically allocated extras
    in the serial_core layer.

    Signed-off-by: Alan Cox
    ---

    drivers/serial/8250.c | 2 +
    drivers/serial/jsm/jsm_neo.c | 2 +
    drivers/serial/jsm/jsm_tty.c | 8 ++--
    drivers/serial/serial_core.c | 80 ++++++++++++++++++++++--------------------
    include/linux/serial_core.h | 26 ++++++--------
    5 files changed, 60 insertions(+), 58 deletions(-)


    diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
    index b040912..2dbfba8 100644
    --- a/drivers/serial/8250.c
    +++ b/drivers/serial/8250.c
    @@ -1287,7 +1287,7 @@ static void serial8250_enable_ms(struct uart_port *port)
    static void
    receive_chars(struct uart_8250_port *up, unsigned int *status)
    {
    - struct tty_struct *tty = up->port.info->tty;
    + struct tty_struct *tty = up->port.info->port.tty;
    unsigned char ch, lsr = *status;
    int max_count = 256;
    char flag;
    diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
    index b2d6f5b..b7584ca 100644
    --- a/drivers/serial/jsm/jsm_neo.c
    +++ b/drivers/serial/jsm/jsm_neo.c
    @@ -998,7 +998,7 @@ static void neo_param(struct jsm_channel *ch)
    { 50, B50 },
    };

    - cflag = C_BAUD(ch->uart_port.info->tty);
    + cflag = C_BAUD(ch->uart_port.info->port.tty);
    baud = 9600;
    for (i = 0; i < ARRAY_SIZE(baud_rates); i++) {
    if (baud_rates[i].cflag == cflag) {
    diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
    index 94ec663..a697914 100644
    --- a/drivers/serial/jsm/jsm_tty.c
    +++ b/drivers/serial/jsm/jsm_tty.c
    @@ -145,7 +145,7 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch)
    struct ktermios *termios;

    spin_lock_irqsave(&port->lock, lock_flags);
    - termios = port->info->tty->termios;
    + termios = port->info->port.tty->termios;
    if (ch == termios->c_cc[VSTART])
    channel->ch_bd->bd_ops->send_start_character(channel);

    @@ -239,7 +239,7 @@ static int jsm_tty_open(struct uart_port *port)
    channel->ch_cached_lsr = 0;
    channel->ch_stops_sent = 0;

    - termios = port->info->tty->termios;
    + termios = port->info->port.tty->termios;
    channel->ch_c_cflag = termios->c_cflag;
    channel->ch_c_iflag = termios->c_iflag;
    channel->ch_c_oflag = termios->c_oflag;
    @@ -272,7 +272,7 @@ static void jsm_tty_close(struct uart_port *port)
    jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n");

    bd = channel->ch_bd;
    - ts = channel->uart_port.info->tty->termios;
    + ts = channel->uart_port.info->port.tty->termios;

    channel->ch_flags &= ~(CH_STOPI);

    @@ -515,7 +515,7 @@ void jsm_input(struct jsm_channel *ch)
    if (!ch)
    return;

    - tp = ch->uart_port.info->tty;
    + tp = ch->uart_port.info->port.tty;

    bd = ch->ch_bd;
    if(!bd)
    diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
    index c9b64e7..f10e953 100644
    --- a/drivers/serial/serial_core.c
    +++ b/drivers/serial/serial_core.c
    @@ -50,7 +50,7 @@ static struct lock_class_key port_lock_key;

    #define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)

    -#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0))
    +#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->port.blocked_open : 0))

    #ifdef CONFIG_SERIAL_CORE_CONSOLE
    #define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line)
    @@ -113,7 +113,7 @@ static void uart_start(struct tty_struct *tty)
    static void uart_tasklet_action(unsigned long data)
    {
    struct uart_state *state = (struct uart_state *)data;
    - tty_wakeup(state->info->tty);
    + tty_wakeup(state->info->port.tty);
    }

    static inline void
    @@ -135,7 +135,7 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)

    /*
    * Startup the port. This will be called once per open. All calls
    - * will be serialised by the per-port semaphore.
    + * will be serialised by the per-port mutex.
    */
    static int uart_startup(struct uart_state *state, int init_hw)
    {
    @@ -152,7 +152,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
    * once we have successfully opened the port. Also set
    * up the tty->alt_speed kludge
    */
    - set_bit(TTY_IO_ERROR, &info->tty->flags);
    + set_bit(TTY_IO_ERROR, &info->port.tty->flags);

    if (port->type == PORT_UNKNOWN)
    return 0;
    @@ -162,6 +162,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
    * buffer.
    */
    if (!info->xmit.buf) {
    + /* This is protected by the per port mutex */
    page = get_zeroed_page(GFP_KERNEL);
    if (!page)
    return -ENOMEM;
    @@ -182,20 +183,20 @@ static int uart_startup(struct uart_state *state, int init_hw)
    * Setup the RTS and DTR signals once the
    * port is open and ready to respond.
    */
    - if (info->tty->termios->c_cflag & CBAUD)
    + if (info->port.tty->termios->c_cflag & CBAUD)
    uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
    }

    if (info->flags & UIF_CTS_FLOW) {
    spin_lock_irq(&port->lock);
    if (!(port->ops->get_mctrl(port) & TIOCM_CTS))
    - info->tty->hw_stopped = 1;
    + info->port.tty->hw_stopped = 1;
    spin_unlock_irq(&port->lock);
    }

    info->flags |= UIF_INITIALIZED;

    - clear_bit(TTY_IO_ERROR, &info->tty->flags);
    + clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
    }

    if (retval && capable(CAP_SYS_ADMIN))
    @@ -217,8 +218,8 @@ static void uart_shutdown(struct uart_state *state)
    /*
    * Set the TTY IO error marker
    */
    - if (info->tty)
    - set_bit(TTY_IO_ERROR, &info->tty->flags);
    + if (info->port.tty)
    + set_bit(TTY_IO_ERROR, &info->port.tty->flags);

    if (info->flags & UIF_INITIALIZED) {
    info->flags &= ~UIF_INITIALIZED;
    @@ -226,7 +227,7 @@ static void uart_shutdown(struct uart_state *state)
    /*
    * Turn off DTR and RTS early.
    */
    - if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
    + if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
    uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);

    /*
    @@ -426,7 +427,7 @@ EXPORT_SYMBOL(uart_get_divisor);
    static void
    uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
    {
    - struct tty_struct *tty = state->info->tty;
    + struct tty_struct *tty = state->info->port.tty;
    struct uart_port *port = state->port;
    struct ktermios *termios;

    @@ -834,8 +835,8 @@ static int uart_set_info(struct uart_state *state,
    state->closing_wait = closing_wait;
    if (new_serial.xmit_fifo_size)
    port->fifosize = new_serial.xmit_fifo_size;
    - if (state->info->tty)
    - state->info->tty->low_latency =
    + if (state->info->port.tty)
    + state->info->port.tty->low_latency =
    (port->flags & UPF_LOW_LATENCY) ? 1 : 0;

    check_and_exit:
    @@ -855,7 +856,7 @@ static int uart_set_info(struct uart_state *state,
    printk(KERN_NOTICE
    "%s sets custom speed on %s. This "
    "is deprecated.\n", current->comm,
    - tty_name(state->info->tty, buf));
    + tty_name(state->info->port.tty, buf));
    }
    uart_change_speed(state, NULL);
    }
    @@ -887,7 +888,7 @@ static int uart_get_lsr_info(struct uart_state *state,
    */
    if (port->x_char ||
    ((uart_circ_chars_pending(&state->info->xmit) > 0) &&
    - !state->info->tty->stopped && !state->info->tty->hw_stopped))
    + !state->info->port.tty->stopped && !state->info->port.tty->hw_stopped))
    result &= ~TIOCSER_TEMT;

    return put_user(result, value);
    @@ -1237,7 +1238,7 @@ static void uart_set_termios(struct tty_struct *tty,
    */
    if (!(old_termios->c_cflag & CLOCAL) &&
    (tty->termios->c_cflag & CLOCAL))
    - wake_up_interruptible(&state->info->open_wait);
    + wake_up_interruptible(&state->info->port.open_wait);
    #endif
    }

    @@ -1318,9 +1319,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
    tty_ldisc_flush(tty);

    tty->closing = 0;
    - state->info->tty = NULL;
    + state->info->port.tty = NULL;

    - if (state->info->blocked_open) {
    + if (state->info->port.blocked_open) {
    if (state->close_delay)
    msleep_interruptible(state->close_delay);
    } else if (!uart_console(port)) {
    @@ -1331,7 +1332,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
    * Wake up anyone trying to open this port.
    */
    state->info->flags &= ~UIF_NORMAL_ACTIVE;
    - wake_up_interruptible(&state->info->open_wait);
    + wake_up_interruptible(&state->info->port.open_wait);

    done:
    mutex_unlock(&state->mutex);
    @@ -1415,8 +1416,8 @@ static void uart_hangup(struct tty_struct *tty)
    uart_shutdown(state);
    state->count = 0;
    state->info->flags &= ~UIF_NORMAL_ACTIVE;
    - state->info->tty = NULL;
    - wake_up_interruptible(&state->info->open_wait);
    + state->info->port.tty = NULL;
    + wake_up_interruptible(&state->info->port.open_wait);
    wake_up_interruptible(&state->info->delta_msr_wait);
    }
    mutex_unlock(&state->mutex);
    @@ -1430,7 +1431,7 @@ static void uart_hangup(struct tty_struct *tty)
    */
    static void uart_update_termios(struct uart_state *state)
    {
    - struct tty_struct *tty = state->info->tty;
    + struct tty_struct *tty = state->info->port.tty;
    struct uart_port *port = state->port;

    if (uart_console(port) && port->cons->cflag) {
    @@ -1469,17 +1470,17 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
    struct uart_port *port = state->port;
    unsigned int mctrl;

    - info->blocked_open++;
    + info->port.blocked_open++;
    state->count--;

    - add_wait_queue(&info->open_wait, &wait);
    + add_wait_queue(&info->port.open_wait, &wait);
    while (1) {
    set_current_state(TASK_INTERRUPTIBLE);

    /*
    * If we have been hung up, tell userspace/restart open.
    */
    - if (tty_hung_up_p(filp) || info->tty == NULL)
    + if (tty_hung_up_p(filp) || info->port.tty == NULL)
    break;

    /*
    @@ -1498,8 +1499,8 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
    * have set TTY_IO_ERROR for a non-existant port.
    */
    if ((filp->f_flags & O_NONBLOCK) ||
    - (info->tty->termios->c_cflag & CLOCAL) ||
    - (info->tty->flags & (1 << TTY_IO_ERROR)))
    + (info->port.tty->termios->c_cflag & CLOCAL) ||
    + (info->port.tty->flags & (1 << TTY_IO_ERROR)))
    break;

    /*
    @@ -1507,7 +1508,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
    * not set RTS here - we want to make sure we catch
    * the data from the modem.
    */
    - if (info->tty->termios->c_cflag & CBAUD)
    + if (info->port.tty->termios->c_cflag & CBAUD)
    uart_set_mctrl(port, TIOCM_DTR);

    /*
    @@ -1529,15 +1530,15 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
    break;
    }
    set_current_state(TASK_RUNNING);
    - remove_wait_queue(&info->open_wait, &wait);
    + remove_wait_queue(&info->port.open_wait, &wait);

    state->count++;
    - info->blocked_open--;
    + info->port.blocked_open--;

    if (signal_pending(current))
    return -ERESTARTSYS;

    - if (!info->tty || tty_hung_up_p(filp))
    + if (!info->port.tty || tty_hung_up_p(filp))
    return -EAGAIN;

    return 0;
    @@ -1560,10 +1561,13 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line)
    goto err_unlock;
    }

    + /* BKL: RACE HERE - LEAK */
    + /* We should move this into the uart_state structure and kill off
    + this whole complexity */
    if (!state->info) {
    state->info = kzalloc(sizeof(struct uart_info), GFP_KERNEL);
    if (state->info) {
    - init_waitqueue_head(&state->info->open_wait);
    + init_waitqueue_head(&state->info->port.open_wait);
    init_waitqueue_head(&state->info->delta_msr_wait);

    /*
    @@ -1620,7 +1624,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
    * be re-entered while allocating the info structure, or while we
    * request any IRQs that the driver may need. This also has the nice
    * side-effect that it delays the action of uart_hangup, so we can
    - * guarantee that info->tty will always contain something reasonable.
    + * guarantee that info->port.tty will always contain something reasonable.
    */
    state = uart_get(drv, line);
    if (IS_ERR(state)) {
    @@ -1636,7 +1640,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
    tty->driver_data = state;
    tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0;
    tty->alt_speed = 0;
    - state->info->tty = tty;
    + state->info->port.tty = tty;

    /*
    * If the port is in the middle of closing, bail out now.
    @@ -2097,8 +2101,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
    /*
    * If that's unset, use the tty termios setting.
    */
    - if (state->info && state->info->tty && termios.c_cflag == 0)
    - termios = *state->info->tty->termios;
    + if (state->info && state->info->port.tty && termios.c_cflag == 0)
    + termios = *state->info->port.tty->termios;

    uart_change_pm(state, 0);
    port->ops->set_termios(port, &termios, NULL);
    @@ -2517,8 +2521,8 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
    tty_unregister_device(drv->tty_driver, port->line);

    info = state->info;
    - if (info && info->tty)
    - tty_vhangup(info->tty);
    + if (info && info->port.tty)
    + tty_vhangup(info->port.tty);

    /*
    * All users of this port should now be disconnected from
    diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
    index d8f31de..7583c02 100644
    --- a/include/linux/serial_core.h
    +++ b/include/linux/serial_core.h
    @@ -343,13 +343,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))
    @@ -357,11 +359,7 @@ struct uart_info {
    #define UIF_INITIALIZED ((__force uif_t) (1 << 31))
    #define UIF_SUSPENDED ((__force uif_t) (1 << 30))

    - int blocked_open;
    -
    struct tasklet_struct tlet;
    -
    - wait_queue_head_t open_wait;
    wait_queue_head_t delta_msr_wait;
    };

    @@ -438,8 +436,8 @@ int uart_resume_port(struct uart_driver *reg, struct uart_port *port);
    #define uart_circ_chars_free(circ) \
    (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))

    -#define uart_tx_stopped(port) \
    - ((port)->info->tty->stopped || (port)->info->tty->hw_stopped)
    +#define uart_tx_stopped(portp) \
    + ((portp)->info->port.tty->stopped || (portp)->info->port.tty->hw_stopped)

    /*
    * The following are helper functions for the low level drivers.
    @@ -450,7 +448,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
    #ifdef SUPPORT_SYSRQ
    if (port->sysrq) {
    if (ch && time_before(jiffies, port->sysrq)) {
    - handle_sysrq(ch, port->info ? port->info->tty : NULL);
    + handle_sysrq(ch, port->info ? port->info->port.tty : NULL);
    port->sysrq = 0;
    return 1;
    }
    @@ -479,7 +477,7 @@ static inline int uart_handle_break(struct uart_port *port)
    }
    #endif
    if (port->flags & UPF_SAK)
    - do_SAK(info->tty);
    + do_SAK(info->port.tty);
    return 0;
    }

    @@ -502,9 +500,9 @@ uart_handle_dcd_change(struct uart_port *port, unsigned int status)

    if (info->flags & UIF_CHECK_CD) {
    if (status)
    - wake_up_interruptible(&info->open_wait);
    - else if (info->tty)
    - tty_hangup(info->tty);
    + wake_up_interruptible(&info->port.open_wait);
    + else if (info->port.tty)
    + tty_hangup(info->port.tty);
    }
    }

    @@ -517,7 +515,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;

    port->icount.cts++;

    @@ -543,7 +541,7 @@ static inline void
    uart_insert_char(struct uart_port *port, unsigned int status,
    unsigned int overrun, unsigned int ch, unsigned int flag)
    {
    - struct tty_struct *tty = port->info->tty;
    + struct tty_struct *tty = port->info->port.tty;

    if ((status & port->ignore_status_mask & ~overrun) == 0)
    tty_insert_flip_char(tty, ch, flag);

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  10. [PATCH 34/70] digi_acceleport: coding style

    From: Alan Cox

    Code tidy

    Signed-off-by: Alan Cox
    ---

    drivers/usb/serial/digi_acceleport.c | 693 ++++++++++++++++++----------------
    1 files changed, 358 insertions(+), 335 deletions(-)


    diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
    index 847848b..0f3d553 100644
    --- a/drivers/usb/serial/digi_acceleport.c
    +++ b/drivers/usb/serial/digi_acceleport.c
    @@ -1,237 +1,236 @@
    /*
    -* Digi AccelePort USB-4 and USB-2 Serial Converters
    -*
    -* Copyright 2000 by Digi International
    -*
    -* This program is free software; you can redistribute it and/or modify
    -* it under the terms of the GNU General Public License as published by
    -* the Free Software Foundation; either version 2 of the License, or
    -* (at your option) any later version.
    -*
    -* Shamelessly based on Brian Warner's keyspan_pda.c and Greg Kroah-Hartman's
    -* usb-serial driver.
    -*
    -* Peter Berger (pberger@brimson.com)
    -* Al Borchers (borchers@steinerpoint.com)
    -*
    -* (12/03/2001) gkh
    -* switched to using port->port.count instead of private version.
    -* Removed port->active
    -*
    -* (04/08/2001) gb
    -* Identify version on module load.
    -*
    -* (11/01/2000) Adam J. Richter
    -* usb_device_id table support
    -*
    -* (11/01/2000) pberger and borchers
    -* -- Turned off the USB_DISABLE_SPD flag for write bulk urbs--it caused
    -* USB 4 ports to hang on startup.
    -* -- Serialized access to write urbs by adding the dp_write_urb_in_use
    -* flag; otherwise, the driver caused SMP system hangs. Watching the
    -* urb status is not sufficient.
    -*
    -* (10/05/2000) gkh
    -* -- Fixed bug with urb->dev not being set properly, now that the usb
    -* core needs it.
    -*
    -* (8/8/2000) pberger and borchers
    -* -- Fixed close so that
    -* - it can timeout while waiting for transmit idle, if needed;
    -* - it ignores interrupts when flushing the port, turning
    -* of modem signalling, and so on;
    -* - it waits for the flush to really complete before returning.
    -* -- Read_bulk_callback and write_bulk_callback check for a closed
    -* port before using the tty struct or writing to the port.
    -* -- The two changes above fix the oops caused by interrupted closes.
    -* -- Added interruptible args to write_oob_command and set_modem_signals
    -* and added a timeout arg to transmit_idle; needed for fixes to
    -* close.
    -* -- Added code for rx_throttle and rx_unthrottle so that input flow
    -* control works.
    -* -- Added code to set overrun, parity, framing, and break errors
    -* (untested).
    -* -- Set USB_DISABLE_SPD flag for write bulk urbs, so no 0 length
    -* bulk writes are done. These hung the Digi USB device. The
    -* 0 length bulk writes were a new feature of usb-uhci added in
    -* the 2.4.0-test6 kernels.
    -* -- Fixed mod inc race in open; do mod inc before sleeping to wait
    -* for a close to finish.
    -*
    -* (7/31/2000) pberger
    -* -- Fixed bugs with hardware handshaking:
    -* - Added code to set/clear tty->hw_stopped in digi_read_oob_callback()
    -* and digi_set_termios()
    -* -- Added code in digi_set_termios() to
    -* - add conditional in code handling transition from B0 to only
    -* set RTS if RTS/CTS flow control is either not in use or if
    -* the port is not currently throttled.
    -* - handle turning off CRTSCTS.
    -*
    -* (7/30/2000) borchers
    -* -- Added support for more than one Digi USB device by moving
    -* globals to a private structure in the pointed to from the
    -* usb_serial structure.
    -* -- Moved the modem change and transmit idle wait queues into
    -* the port private structure, so each port has its own queue
    -* rather than sharing global queues.
    -* -- Added support for break signals.
    -*
    -* (7/25/2000) pberger
    -* -- Added USB-2 support. Note: the USB-2 supports 3 devices: two
    -* serial and a parallel port. The parallel port is implemented
    -* as a serial-to-parallel converter. That is, the driver actually
    -* presents all three USB-2 interfaces as serial ports, but the third
    -* one physically connects to a parallel device. Thus, for example,
    -* one could plug a parallel printer into the USB-2's third port,
    -* but from the kernel's (and userland's) point of view what's
    -* actually out there is a serial device.
    -*
    -* (7/15/2000) borchers
    -* -- Fixed race in open when a close is in progress.
    -* -- Keep count of opens and dec the module use count for each
    -* outstanding open when shutdown is called (on disconnect).
    -* -- Fixed sanity checks in read_bulk_callback and write_bulk_callback
    -* so pointers are checked before use.
    -* -- Split read bulk callback into in band and out of band
    -* callbacks, and no longer restart read chains if there is
    -* a status error or a sanity error. This fixed the seg
    -* faults and other errors we used to get on disconnect.
    -* -- Port->active is once again a flag as usb-serial intended it
    -* to be, not a count. Since it was only a char it would
    -* have been limited to 256 simultaneous opens. Now the open
    -* count is kept in the port private structure in dp_open_count.
    -* -- Added code for modularization of the digi_acceleport driver.
    -*
    -* (6/27/2000) pberger and borchers
    -* -- Zeroed out sync field in the wakeup_task before first use;
    -* otherwise the uninitialized value might prevent the task from
    -* being scheduled.
    -* -- Initialized ret value to 0 in write_bulk_callback, otherwise
    -* the uninitialized value could cause a spurious debugging message.
    -*
    -* (6/22/2000) pberger and borchers
    -* -- Made cond_wait_... inline--apparently on SPARC the flags arg
    -* to spin_lock_irqsave cannot be passed to another function
    -* to call spin_unlock_irqrestore. Thanks to Pauline Middelink.
    -* -- In digi_set_modem_signals the inner nested spin locks use just
    -* spin_lock() rather than spin_lock_irqsave(). The old code
    -* mistakenly left interrupts off. Thanks to Pauline Middelink.
    -* -- copy_from_user (which can sleep) is no longer called while a
    -* spinlock is held. We copy to a local buffer before getting
    -* the spinlock--don't like the extra copy but the code is simpler.
    -* -- Printk and dbg are no longer called while a spin lock is held.
    -*
    -* (6/4/2000) pberger and borchers
    -* -- Replaced separate calls to spin_unlock_irqrestore and
    -* interruptible_sleep_on_timeout with a new function
    -* cond_wait_interruptible_timeout_irqrestore. This eliminates
    -* the race condition where the wake up could happen after
    -* the unlock and before the sleep.
    -* -- Close now waits for output to drain.
    -* -- Open waits until any close in progress is finished.
    -* -- All out of band responses are now processed, not just the
    -* first in a USB packet.
    -* -- Fixed a bug that prevented the driver from working when the
    -* first Digi port was not the first USB serial port--the driver
    -* was mistakenly using the external USB serial port number to
    -* try to index into its internal ports.
    -* -- Fixed an SMP bug -- write_bulk_callback is called directly from
    -* an interrupt, so spin_lock_irqsave/spin_unlock_irqrestore are
    -* needed for locks outside write_bulk_callback that are also
    -* acquired by write_bulk_callback to prevent deadlocks.
    -* -- Fixed support for select() by making digi_chars_in_buffer()
    -* return 256 when -EINPROGRESS is set, as the line discipline
    -* code in n_tty.c expects.
    -* -- Fixed an include file ordering problem that prevented debugging
    -* messages from working.
    -* -- Fixed an intermittent timeout problem that caused writes to
    -* sometimes get stuck on some machines on some kernels. It turns
    -* out in these circumstances write_chan() (in n_tty.c) was
    -* asleep waiting for our wakeup call. Even though we call
    -* wake_up_interruptible() in digi_write_bulk_callback(), there is
    -* a race condition that could cause the wakeup to fail: if our
    -* wake_up_interruptible() call occurs between the time that our
    -* driver write routine finishes and write_chan() sets current->state
    -* to TASK_INTERRUPTIBLE, the effect of our wakeup setting the state
    -* to TASK_RUNNING will be lost and write_chan's subsequent call to
    -* schedule() will never return (unless it catches a signal).
    -* This race condition occurs because write_bulk_callback() (and thus
    -* the wakeup) are called asynchronously from an interrupt, rather than
    -* from the scheduler. We can avoid the race by calling the wakeup
    -* from the scheduler queue and that's our fix: Now, at the end of
    -* write_bulk_callback() we queue up a wakeup call on the scheduler
    -* task queue. We still also invoke the wakeup directly since that
    -* squeezes a bit more performance out of the driver, and any lost
    -* race conditions will get cleaned up at the next scheduler run.
    -*
    -* NOTE: The problem also goes away if you comment out
    -* the two code lines in write_chan() where current->state
    -* is set to TASK_RUNNING just before calling driver.write() and to
    -* TASK_INTERRUPTIBLE immediately afterwards. This is why the
    -* problem did not show up with the 2.2 kernels -- they do not
    -* include that code.
    -*
    -* (5/16/2000) pberger and borchers
    -* -- Added timeouts to sleeps, to defend against lost wake ups.
    -* -- Handle transition to/from B0 baud rate in digi_set_termios.
    -*
    -* (5/13/2000) pberger and borchers
    -* -- All commands now sent on out of band port, using
    -* digi_write_oob_command.
    -* -- Get modem control signals whenever they change, support TIOCMGET/
    -* SET/BIS/BIC ioctls.
    -* -- digi_set_termios now supports parity, word size, stop bits, and
    -* receive enable.
    -* -- Cleaned up open and close, use digi_set_termios and
    -* digi_write_oob_command to set port parameters.
    -* -- Added digi_startup_device to start read chains on all ports.
    -* -- Write buffer is only used when count==1, to be sure put_char can
    -* write a char (unless the buffer is full).
    -*
    -* (5/10/2000) pberger and borchers
    -* -- Added MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT calls on open/close.
    -* -- Fixed problem where the first incoming character is lost on
    -* port opens after the first close on that port. Now we keep
    -* the read_urb chain open until shutdown.
    -* -- Added more port conditioning calls in digi_open and digi_close.
    -* -- Convert port->active to a use count so that we can deal with multiple
    -* opens and closes properly.
    -* -- Fixed some problems with the locking code.
    -*
    -* (5/3/2000) pberger and borchers
    -* -- First alpha version of the driver--many known limitations and bugs.
    -*
    -*
    -* Locking and SMP
    -*
    -* - Each port, including the out-of-band port, has a lock used to
    -* serialize all access to the port's private structure.
    -* - The port lock is also used to serialize all writes and access to
    -* the port's URB.
    -* - The port lock is also used for the port write_wait condition
    -* variable. Holding the port lock will prevent a wake up on the
    -* port's write_wait; this can be used with cond_wait_... to be sure
    -* the wake up is not lost in a race when dropping the lock and
    -* sleeping waiting for the wakeup.
    -* - digi_write() does not sleep, since it is sometimes called on
    -* interrupt time.
    -* - digi_write_bulk_callback() and digi_read_bulk_callback() are
    -* called directly from interrupts. Hence spin_lock_irqsave()
    -* and spin_unlock_irqrestore() are used in the rest of the code
    -* for any locks they acquire.
    -* - digi_write_bulk_callback() gets the port lock before waking up
    -* processes sleeping on the port write_wait. It also schedules
    -* wake ups so they happen from the scheduler, because the tty
    -* system can miss wake ups from interrupts.
    -* - All sleeps use a timeout of DIGI_RETRY_TIMEOUT before looping to
    -* recheck the condition they are sleeping on. This is defensive,
    -* in case a wake up is lost.
    -* - Following Documentation/DocBook/kernel-locking.pdf no spin locks
    -* are held when calling copy_to/from_user or printk.
    -*
    -* $Id: digi_acceleport.c,v 1.80.1.2 2000/11/02 05:45:08 root Exp $
    -*/
    + * Digi AccelePort USB-4 and USB-2 Serial Converters
    + *
    + * Copyright 2000 by Digi International
    + *
    + * This program is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License as published by
    + * the Free Software Foundation; either version 2 of the License, or
    + * (at your option) any later version.
    + *
    + * Shamelessly based on Brian Warner's keyspan_pda.c and Greg Kroah-Hartman's
    + * usb-serial driver.
    + *
    + * Peter Berger (pberger@brimson.com)
    + * Al Borchers (borchers@steinerpoint.com)
    + *
    + * (12/03/2001) gkh
    + * switched to using port->port.count instead of private version.
    + * Removed port->active
    + *
    + * (04/08/2001) gb
    + * Identify version on module load.
    + *
    + * (11/01/2000) Adam J. Richter
    + * usb_device_id table support
    + *
    + * (11/01/2000) pberger and borchers
    + * -- Turned off the USB_DISABLE_SPD flag for write bulk urbs--it caused
    + * USB 4 ports to hang on startup.
    + * -- Serialized access to write urbs by adding the dp_write_urb_in_use
    + * flag; otherwise, the driver caused SMP system hangs. Watching the
    + * urb status is not sufficient.
    + *
    + * (10/05/2000) gkh
    + * -- Fixed bug with urb->dev not being set properly, now that the usb
    + * core needs it.
    + *
    + * (8/8/2000) pberger and borchers
    + * -- Fixed close so that
    + * - it can timeout while waiting for transmit idle, if needed;
    + * - it ignores interrupts when flushing the port, turning
    + * of modem signalling, and so on;
    + * - it waits for the flush to really complete before returning.
    + * -- Read_bulk_callback and write_bulk_callback check for a closed
    + * port before using the tty struct or writing to the port.
    + * -- The two changes above fix the oops caused by interrupted closes.
    + * -- Added interruptible args to write_oob_command and set_modem_signals
    + * and added a timeout arg to transmit_idle; needed for fixes to
    + * close.
    + * -- Added code for rx_throttle and rx_unthrottle so that input flow
    + * control works.
    + * -- Added code to set overrun, parity, framing, and break errors
    + * (untested).
    + * -- Set USB_DISABLE_SPD flag for write bulk urbs, so no 0 length
    + * bulk writes are done. These hung the Digi USB device. The
    + * 0 length bulk writes were a new feature of usb-uhci added in
    + * the 2.4.0-test6 kernels.
    + * -- Fixed mod inc race in open; do mod inc before sleeping to wait
    + * for a close to finish.
    + *
    + * (7/31/2000) pberger
    + * -- Fixed bugs with hardware handshaking:
    + * - Added code to set/clear tty->hw_stopped in digi_read_oob_callback()
    + * and digi_set_termios()
    + * -- Added code in digi_set_termios() to
    + * - add conditional in code handling transition from B0 to only
    + * set RTS if RTS/CTS flow control is either not in use or if
    + * the port is not currently throttled.
    + * - handle turning off CRTSCTS.
    + *
    + * (7/30/2000) borchers
    + * -- Added support for more than one Digi USB device by moving
    + * globals to a private structure in the pointed to from the
    + * usb_serial structure.
    + * -- Moved the modem change and transmit idle wait queues into
    + * the port private structure, so each port has its own queue
    + * rather than sharing global queues.
    + * -- Added support for break signals.
    + *
    + * (7/25/2000) pberger
    + * -- Added USB-2 support. Note: the USB-2 supports 3 devices: two
    + * serial and a parallel port. The parallel port is implemented
    + * as a serial-to-parallel converter. That is, the driver actually
    + * presents all three USB-2 interfaces as serial ports, but the third
    + * one physically connects to a parallel device. Thus, for example,
    + * one could plug a parallel printer into the USB-2's third port,
    + * but from the kernel's (and userland's) point of view what's
    + * actually out there is a serial device.
    + *
    + * (7/15/2000) borchers
    + * -- Fixed race in open when a close is in progress.
    + * -- Keep count of opens and dec the module use count for each
    + * outstanding open when shutdown is called (on disconnect).
    + * -- Fixed sanity checks in read_bulk_callback and write_bulk_callback
    + * so pointers are checked before use.
    + * -- Split read bulk callback into in band and out of band
    + * callbacks, and no longer restart read chains if there is
    + * a status error or a sanity error. This fixed the seg
    + * faults and other errors we used to get on disconnect.
    + * -- Port->active is once again a flag as usb-serial intended it
    + * to be, not a count. Since it was only a char it would
    + * have been limited to 256 simultaneous opens. Now the open
    + * count is kept in the port private structure in dp_open_count.
    + * -- Added code for modularization of the digi_acceleport driver.
    + *
    + * (6/27/2000) pberger and borchers
    + * -- Zeroed out sync field in the wakeup_task before first use;
    + * otherwise the uninitialized value might prevent the task from
    + * being scheduled.
    + * -- Initialized ret value to 0 in write_bulk_callback, otherwise
    + * the uninitialized value could cause a spurious debugging message.
    + *
    + * (6/22/2000) pberger and borchers
    + * -- Made cond_wait_... inline--apparently on SPARC the flags arg
    + * to spin_lock_irqsave cannot be passed to another function
    + * to call spin_unlock_irqrestore. Thanks to Pauline Middelink.
    + * -- In digi_set_modem_signals the inner nested spin locks use just
    + * spin_lock() rather than spin_lock_irqsave(). The old code
    + * mistakenly left interrupts off. Thanks to Pauline Middelink.
    + * -- copy_from_user (which can sleep) is no longer called while a
    + * spinlock is held. We copy to a local buffer before getting
    + * the spinlock--don't like the extra copy but the code is simpler.
    + * -- Printk and dbg are no longer called while a spin lock is held.
    + *
    + * (6/4/2000) pberger and borchers
    + * -- Replaced separate calls to spin_unlock_irqrestore and
    + * interruptible_sleep_on_timeout with a new function
    + * cond_wait_interruptible_timeout_irqrestore. This eliminates
    + * the race condition where the wake up could happen after
    + * the unlock and before the sleep.
    + * -- Close now waits for output to drain.
    + * -- Open waits until any close in progress is finished.
    + * -- All out of band responses are now processed, not just the
    + * first in a USB packet.
    + * -- Fixed a bug that prevented the driver from working when the
    + * first Digi port was not the first USB serial port--the driver
    + * was mistakenly using the external USB serial port number to
    + * try to index into its internal ports.
    + * -- Fixed an SMP bug -- write_bulk_callback is called directly from
    + * an interrupt, so spin_lock_irqsave/spin_unlock_irqrestore are
    + * needed for locks outside write_bulk_callback that are also
    + * acquired by write_bulk_callback to prevent deadlocks.
    + * -- Fixed support for select() by making digi_chars_in_buffer()
    + * return 256 when -EINPROGRESS is set, as the line discipline
    + * code in n_tty.c expects.
    + * -- Fixed an include file ordering problem that prevented debugging
    + * messages from working.
    + * -- Fixed an intermittent timeout problem that caused writes to
    + * sometimes get stuck on some machines on some kernels. It turns
    + * out in these circumstances write_chan() (in n_tty.c) was
    + * asleep waiting for our wakeup call. Even though we call
    + * wake_up_interruptible() in digi_write_bulk_callback(), there is
    + * a race condition that could cause the wakeup to fail: if our
    + * wake_up_interruptible() call occurs between the time that our
    + * driver write routine finishes and write_chan() sets current->state
    + * to TASK_INTERRUPTIBLE, the effect of our wakeup setting the state
    + * to TASK_RUNNING will be lost and write_chan's subsequent call to
    + * schedule() will never return (unless it catches a signal).
    + * This race condition occurs because write_bulk_callback() (and thus
    + * the wakeup) are called asynchronously from an interrupt, rather than
    + * from the scheduler. We can avoid the race by calling the wakeup
    + * from the scheduler queue and that's our fix: Now, at the end of
    + * write_bulk_callback() we queue up a wakeup call on the scheduler
    + * task queue. We still also invoke the wakeup directly since that
    + * squeezes a bit more performance out of the driver, and any lost
    + * race conditions will get cleaned up at the next scheduler run.
    + *
    + * NOTE: The problem also goes away if you comment out
    + * the two code lines in write_chan() where current->state
    + * is set to TASK_RUNNING just before calling driver.write() and to
    + * TASK_INTERRUPTIBLE immediately afterwards. This is why the
    + * problem did not show up with the 2.2 kernels -- they do not
    + * include that code.
    + *
    + * (5/16/2000) pberger and borchers
    + * -- Added timeouts to sleeps, to defend against lost wake ups.
    + * -- Handle transition to/from B0 baud rate in digi_set_termios.
    + *
    + * (5/13/2000) pberger and borchers
    + * -- All commands now sent on out of band port, using
    + * digi_write_oob_command.
    + * -- Get modem control signals whenever they change, support TIOCMGET/
    + * SET/BIS/BIC ioctls.
    + * -- digi_set_termios now supports parity, word size, stop bits, and
    + * receive enable.
    + * -- Cleaned up open and close, use digi_set_termios and
    + * digi_write_oob_command to set port parameters.
    + * -- Added digi_startup_device to start read chains on all ports.
    + * -- Write buffer is only used when count==1, to be sure put_char can
    + * write a char (unless the buffer is full).
    + *
    + * (5/10/2000) pberger and borchers
    + * -- Added MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT calls on open/close.
    + * -- Fixed problem where the first incoming character is lost on
    + * port opens after the first close on that port. Now we keep
    + * the read_urb chain open until shutdown.
    + * -- Added more port conditioning calls in digi_open and digi_close.
    + * -- Convert port->active to a use count so that we can deal with multiple
    + * opens and closes properly.
    + * -- Fixed some problems with the locking code.
    + *
    + * (5/3/2000) pberger and borchers
    + * -- First alpha version of the driver--many known limitations and bugs.
    + *
    + *
    + * Locking and SMP
    + *
    + * - Each port, including the out-of-band port, has a lock used to
    + * serialize all access to the port's private structure.
    + * - The port lock is also used to serialize all writes and access to
    + * the port's URB.
    + * - The port lock is also used for the port write_wait condition
    + * variable. Holding the port lock will prevent a wake up on the
    + * port's write_wait; this can be used with cond_wait_... to be sure
    + * the wake up is not lost in a race when dropping the lock and
    + * sleeping waiting for the wakeup.
    + * - digi_write() does not sleep, since it is sometimes called on
    + * interrupt time.
    + * - digi_write_bulk_callback() and digi_read_bulk_callback() are
    + * called directly from interrupts. Hence spin_lock_irqsave()
    + * and spin_unlock_irqrestore() are used in the rest of the code
    + * for any locks they acquire.
    + * - digi_write_bulk_callback() gets the port lock before waking up
    + * processes sleeping on the port write_wait. It also schedules
    + * wake ups so they happen from the scheduler, because the tty
    + * system can miss wake ups from interrupts.
    + * - All sleeps use a timeout of DIGI_RETRY_TIMEOUT before looping to
    + * recheck the condition they are sleeping on. This is defensive,
    + * in case a wake up is lost.
    + * - Following Documentation/DocBook/kernel-locking.pdf no spin locks
    + * are held when calling copy_to/from_user or printk.
    + *
    + */

    #include
    #include
    @@ -243,7 +242,7 @@
    #include
    #include
    #include
    -#include
    +#include
    #include
    #include
    #include
    @@ -443,8 +442,8 @@ static int digi_set_modem_signals(struct usb_serial_port *port,
    unsigned int modem_signals, int interruptible);
    static int digi_transmit_idle(struct usb_serial_port *port,
    unsigned long timeout);
    -static void digi_rx_throttle (struct tty_struct *tty);
    -static void digi_rx_unthrottle (struct tty_struct *tty);
    +static void digi_rx_throttle(struct tty_struct *tty);
    +static void digi_rx_unthrottle(struct tty_struct *tty);
    static void digi_set_termios(struct tty_struct *tty,
    struct usb_serial_port *port, struct ktermios *old_termios);
    static void digi_break_ctl(struct tty_struct *tty, int break_state);
    @@ -488,7 +487,7 @@ static struct usb_device_id id_table_4 [] = {
    { } /* Terminating entry */
    };

    -MODULE_DEVICE_TABLE (usb, id_table_combined);
    +MODULE_DEVICE_TABLE(usb, id_table_combined);

    static struct usb_driver digi_driver = {
    .name = "digi_acceleport",
    @@ -593,7 +592,8 @@ static long cond_wait_interruptible_timeout_irqrestore(

    static void digi_wakeup_write_lock(struct work_struct *work)
    {
    - struct digi_port *priv = container_of(work, struct digi_port, dp_wakeup_work);
    + struct digi_port *priv =
    + container_of(work, struct digi_port, dp_wakeup_work);
    struct usb_serial_port *port = priv->dp_port;
    unsigned long flags;

    @@ -632,8 +632,8 @@ static int digi_write_oob_command(struct usb_serial_port *port,
    dbg("digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, count);

    spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
    - while(count > 0) {
    - while(oob_port->write_urb->status == -EINPROGRESS
    + while (count > 0) {
    + while (oob_port->write_urb->status == -EINPROGRESS
    || oob_priv->dp_write_urb_in_use) {
    cond_wait_interruptible_timeout_irqrestore(
    &oob_port->write_wait, DIGI_RETRY_TIMEOUT,
    @@ -650,7 +650,8 @@ static int digi_write_oob_command(struct usb_serial_port *port,
    memcpy(oob_port->write_urb->transfer_buffer, buf, len);
    oob_port->write_urb->transfer_buffer_length = len;
    oob_port->write_urb->dev = port->serial->dev;
    - if ((ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0) {
    + ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);
    + if (ret == 0) {
    oob_priv->dp_write_urb_in_use = 1;
    count -= len;
    buf += len;
    @@ -694,9 +695,10 @@ static int digi_write_inb_command(struct usb_serial_port *port,
    timeout = ULONG_MAX;

    spin_lock_irqsave(&priv->dp_port_lock, flags);
    - while(count > 0 && ret == 0) {
    - while((port->write_urb->status == -EINPROGRESS
    - || priv->dp_write_urb_in_use) && time_before(jiffies, timeout)) {
    + while (count > 0 && ret == 0) {
    + while ((port->write_urb->status == -EINPROGRESS
    + || priv->dp_write_urb_in_use)
    + && time_before(jiffies, timeout)) {
    cond_wait_interruptible_timeout_irqrestore(
    &port->write_wait, DIGI_RETRY_TIMEOUT,
    &priv->dp_port_lock, flags);
    @@ -727,7 +729,8 @@ static int digi_write_inb_command(struct usb_serial_port *port,
    }
    port->write_urb->dev = port->serial->dev;

    - if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) {
    + ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
    + if (ret == 0) {
    priv->dp_write_urb_in_use = 1;
    priv->dp_out_buf_len = 0;
    count -= len;
    @@ -760,7 +763,7 @@ static int digi_set_modem_signals(struct usb_serial_port *port,

    int ret;
    struct digi_port *port_priv = usb_get_serial_port_data(port);
    - struct usb_serial_port *oob_port = (struct usb_serial_port *)((struct digi_serial *)(usb_get_serial_data(port->serial)))->ds_oob_port;
    + struct usb_serial_port *oob_port = (struct usb_serial_port *) ((struct digi_serial *)(usb_get_serial_data(port->serial)))->ds_oob_port;
    struct digi_port *oob_priv = usb_get_serial_port_data(oob_port);
    unsigned char *data = oob_port->write_urb->transfer_buffer;
    unsigned long flags = 0;
    @@ -772,7 +775,8 @@ static int digi_set_modem_signals(struct usb_serial_port *port,
    spin_lock_irqsave(&oob_priv->dp_port_lock, flags);
    spin_lock(&port_priv->dp_port_lock);

    - while(oob_port->write_urb->status == -EINPROGRESS || oob_priv->dp_write_urb_in_use) {
    + while (oob_port->write_urb->status == -EINPROGRESS ||
    + oob_priv->dp_write_urb_in_use) {
    spin_unlock(&port_priv->dp_port_lock);
    cond_wait_interruptible_timeout_irqrestore(
    &oob_port->write_wait, DIGI_RETRY_TIMEOUT,
    @@ -784,17 +788,20 @@ static int digi_set_modem_signals(struct usb_serial_port *port,
    }
    data[0] = DIGI_CMD_SET_DTR_SIGNAL;
    data[1] = port_priv->dp_port_num;
    - data[2] = (modem_signals&TIOCM_DTR) ? DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE;
    + data[2] = (modem_signals & TIOCM_DTR) ?
    + DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE;
    data[3] = 0;
    data[4] = DIGI_CMD_SET_RTS_SIGNAL;
    data[5] = port_priv->dp_port_num;
    - data[6] = (modem_signals&TIOCM_RTS) ? DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE;
    + data[6] = (modem_signals & TIOCM_RTS) ?
    + DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE;
    data[7] = 0;

    oob_port->write_urb->transfer_buffer_length = 8;
    oob_port->write_urb->dev = port->serial->dev;

    - if ((ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0) {
    + ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);
    + if (ret == 0) {
    oob_priv->dp_write_urb_in_use = 1;
    port_priv->dp_modem_signals =
    (port_priv->dp_modem_signals&~(TIOCM_DTR|TIOCM_RTS))
    @@ -836,12 +843,13 @@ static int digi_transmit_idle(struct usb_serial_port *port,

    timeout += jiffies;

    - if ((ret = digi_write_inb_command(port, buf, 2, timeout - jiffies)) != 0)
    + ret = digi_write_inb_command(port, buf, 2, timeout - jiffies);
    + if (ret != 0)
    return ret;

    spin_lock_irqsave(&priv->dp_port_lock, flags);

    - while(time_before(jiffies, timeout) && !priv->dp_transmit_idle) {
    + while (time_before(jiffies, timeout) && !priv->dp_transmit_idle) {
    cond_wait_interruptible_timeout_irqrestore(
    &priv->dp_transmit_idle_wait, DIGI_RETRY_TIMEOUT,
    &priv->dp_port_lock, flags);
    @@ -902,7 +910,7 @@ static void digi_rx_unthrottle(struct tty_struct *tty)
    }


    -static void digi_set_termios(struct tty_struct *tty,
    +static void digi_set_termios(struct tty_struct *tty,
    struct usb_serial_port *port, struct ktermios *old_termios)
    {
    struct digi_port *priv = usb_get_serial_port_data(port);
    @@ -912,14 +920,15 @@ static void digi_set_termios(struct tty_struct *tty,
    unsigned int old_cflag = old_termios->c_cflag;
    unsigned char buf[32];
    unsigned int modem_signals;
    - int arg,ret;
    + int arg, ret;
    int i = 0;
    speed_t baud;

    dbg("digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, old_cflag=0x%x", priv->dp_port_num, iflag, old_iflag, cflag, old_cflag);

    /* set baud rate */
    - if ((baud = tty_get_baud_rate(tty)) != tty_termios_baud_rate(old_termios)) {
    + baud = tty_get_baud_rate(tty);
    + if (baud != tty_termios_baud_rate(old_termios)) {
    arg = -1;

    /* reassert DTR and (maybe) RTS on transition from B0 */
    @@ -933,30 +942,30 @@ static void digi_set_termios(struct tty_struct *tty,
    digi_set_modem_signals(port, modem_signals, 1);
    }
    switch (baud) {
    - /* drop DTR and RTS on transition to B0 */
    - case 0: digi_set_modem_signals(port, 0, 1); break;
    - case 50: arg = DIGI_BAUD_50; break;
    - case 75: arg = DIGI_BAUD_75; break;
    - case 110: arg = DIGI_BAUD_110; break;
    - case 150: arg = DIGI_BAUD_150; break;
    - case 200: arg = DIGI_BAUD_200; break;
    - case 300: arg = DIGI_BAUD_300; break;
    - case 600: arg = DIGI_BAUD_600; break;
    - case 1200: arg = DIGI_BAUD_1200; break;
    - case 1800: arg = DIGI_BAUD_1800; break;
    - case 2400: arg = DIGI_BAUD_2400; break;
    - case 4800: arg = DIGI_BAUD_4800; break;
    - case 9600: arg = DIGI_BAUD_9600; break;
    - case 19200: arg = DIGI_BAUD_19200; break;
    - case 38400: arg = DIGI_BAUD_38400; break;
    - case 57600: arg = DIGI_BAUD_57600; break;
    - case 115200: arg = DIGI_BAUD_115200; break;
    - case 230400: arg = DIGI_BAUD_230400; break;
    - case 460800: arg = DIGI_BAUD_460800; break;
    - default:
    - arg = DIGI_BAUD_9600;
    - baud = 9600;
    - break;
    + /* drop DTR and RTS on transition to B0 */
    + case 0: digi_set_modem_signals(port, 0, 1); break;
    + case 50: arg = DIGI_BAUD_50; break;
    + case 75: arg = DIGI_BAUD_75; break;
    + case 110: arg = DIGI_BAUD_110; break;
    + case 150: arg = DIGI_BAUD_150; break;
    + case 200: arg = DIGI_BAUD_200; break;
    + case 300: arg = DIGI_BAUD_300; break;
    + case 600: arg = DIGI_BAUD_600; break;
    + case 1200: arg = DIGI_BAUD_1200; break;
    + case 1800: arg = DIGI_BAUD_1800; break;
    + case 2400: arg = DIGI_BAUD_2400; break;
    + case 4800: arg = DIGI_BAUD_4800; break;
    + case 9600: arg = DIGI_BAUD_9600; break;
    + case 19200: arg = DIGI_BAUD_19200; break;
    + case 38400: arg = DIGI_BAUD_38400; break;
    + case 57600: arg = DIGI_BAUD_57600; break;
    + case 115200: arg = DIGI_BAUD_115200; break;
    + case 230400: arg = DIGI_BAUD_230400; break;
    + case 460800: arg = DIGI_BAUD_460800; break;
    + default:
    + arg = DIGI_BAUD_9600;
    + baud = 9600;
    + break;
    }
    if (arg != -1) {
    buf[i++] = DIGI_CMD_SET_BAUD_RATE;
    @@ -1082,7 +1091,8 @@ static void digi_set_termios(struct tty_struct *tty,
    buf[i++] = arg;
    buf[i++] = 0;
    }
    - if ((ret = digi_write_oob_command(port, buf, i, 1)) != 0)
    + ret = digi_write_oob_command(port, buf, i, 1);
    + if (ret != 0)
    dbg("digi_set_termios: write oob failed, ret=%d", ret);
    tty_encode_baud_rate(tty, baud, baud);
    }
    @@ -1138,7 +1148,7 @@ static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
    const unsigned char *buf, int count)
    {

    - int ret,data_len,new_len;
    + int ret, data_len, new_len;
    struct digi_port *priv = usb_get_serial_port_data(port);
    unsigned char *data = port->write_urb->transfer_buffer;
    unsigned long flags = 0;
    @@ -1156,7 +1166,8 @@ static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
    spin_lock_irqsave(&priv->dp_port_lock, flags);

    /* wait for urb status clear to submit another urb */
    - if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use) {
    + if (port->write_urb->status == -EINPROGRESS ||
    + priv->dp_write_urb_in_use) {
    /* buffer data if count is 1 (probably put_char) if possible */
    if (count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE) {
    priv->dp_out_buf[priv->dp_out_buf_len++] = *buf;
    @@ -1191,7 +1202,8 @@ static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
    /* copy in new data */
    memcpy(data, buf, new_len);

    - if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) {
    + ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
    + if (ret == 0) {
    priv->dp_write_urb_in_use = 1;
    ret = new_len;
    priv->dp_out_buf_len = 0;
    @@ -1205,7 +1217,7 @@ static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
    dbg("digi_write: returning %d", ret);
    return ret;

    -}
    +}

    static void digi_write_bulk_callback(struct urb *urb)
    {
    @@ -1220,13 +1232,13 @@ static void digi_write_bulk_callback(struct urb *urb)
    dbg("digi_write_bulk_callback: TOP, urb->status=%d", status);

    /* port and serial sanity check */
    - if (port == NULL || (priv=usb_get_serial_port_data(port)) == NULL) {
    + if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) {
    err("%s: port or port->private is NULL, status=%d",
    __func__, status);
    return;
    }
    serial = port->serial;
    - if (serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL) {
    + if (serial == NULL || (serial_priv = usb_get_serial_data(serial)) == NULL) {
    err("%s: serial or serial->private is NULL, status=%d",
    __func__, status);
    return;
    @@ -1249,13 +1261,15 @@ static void digi_write_bulk_callback(struct urb *urb)
    && priv->dp_out_buf_len > 0) {
    *((unsigned char *)(port->write_urb->transfer_buffer))
    = (unsigned char)DIGI_CMD_SEND_DATA;
    - *((unsigned char *)(port->write_urb->transfer_buffer)+1)
    + *((unsigned char *)(port->write_urb->transfer_buffer) + 1)
    = (unsigned char)priv->dp_out_buf_len;
    - port->write_urb->transfer_buffer_length = priv->dp_out_buf_len+2;
    + port->write_urb->transfer_buffer_length =
    + priv->dp_out_buf_len + 2;
    port->write_urb->dev = serial->dev;
    - memcpy(port->write_urb->transfer_buffer+2, priv->dp_out_buf,
    + memcpy(port->write_urb->transfer_buffer + 2, priv->dp_out_buf,
    priv->dp_out_buf_len);
    - if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) {
    + ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
    + if (ret == 0) {
    priv->dp_write_urb_in_use = 1;
    priv->dp_out_buf_len = 0;
    }
    @@ -1281,7 +1295,8 @@ static int digi_write_room(struct tty_struct *tty)

    spin_lock_irqsave(&priv->dp_port_lock, flags);

    - if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use)
    + if (port->write_urb->status == -EINPROGRESS ||
    + priv->dp_write_urb_in_use)
    room = 0;
    else
    room = port->bulk_out_size - 2 - priv->dp_out_buf_len;
    @@ -1337,7 +1352,7 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
    }

    /* wait for a close in progress to finish */
    - while(priv->dp_in_close) {
    + while (priv->dp_in_close) {
    cond_wait_interruptible_timeout_irqrestore(
    &priv->dp_close_wait, DIGI_RETRY_TIMEOUT,
    &priv->dp_port_lock, flags);
    @@ -1347,7 +1362,7 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
    }

    spin_unlock_irqrestore(&priv->dp_port_lock, flags);
    -
    +
    /* read modem signals automatically whenever they change */
    buf[0] = DIGI_CMD_READ_INPUT_SIGNALS;
    buf[1] = priv->dp_port_num;
    @@ -1360,7 +1375,8 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
    buf[6] = DIGI_FLUSH_TX | DIGI_FLUSH_RX;
    buf[7] = 0;

    - if ((ret = digi_write_oob_command(port, buf, 8, 1)) != 0)
    + ret = digi_write_oob_command(port, buf, 8, 1);
    + if (ret != 0)
    dbg("digi_open: write oob failed, ret=%d", ret);

    /* set termios settings */
    @@ -1411,9 +1427,8 @@ static void digi_close(struct tty_struct *tty, struct usb_serial_port *port,

    if (port->serial->dev) {
    /* wait for transmit idle */
    - if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) {
    + if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0)
    digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT);
    - }
    /* drop DTR and RTS */
    digi_set_modem_signals(port, 0, 0);

    @@ -1447,11 +1462,13 @@ static void digi_close(struct tty_struct *tty, struct usb_serial_port *port,
    buf[18] = DIGI_FLUSH_TX | DIGI_FLUSH_RX;
    buf[19] = 0;

    - if ((ret = digi_write_oob_command(port, buf, 20, 0)) != 0)
    + ret = digi_write_oob_command(port, buf, 20, 0);
    + if (ret != 0)
    dbg("digi_close: write oob failed, ret=%d", ret);

    /* wait for final commands on oob port to complete */
    - prepare_to_wait(&priv->dp_flush_wait, &wait, TASK_INTERRUPTIBLE);
    + prepare_to_wait(&priv->dp_flush_wait, &wait,
    + TASK_INTERRUPTIBLE);
    schedule_timeout(DIGI_CLOSE_TIMEOUT);
    finish_wait(&priv->dp_flush_wait, &wait);

    @@ -1479,7 +1496,7 @@ exit:

    static int digi_startup_device(struct usb_serial *serial)
    {
    - int i,ret = 0;
    + int i, ret = 0;
    struct digi_serial *serial_priv = usb_get_serial_data(serial);
    struct usb_serial_port *port;

    @@ -1497,7 +1514,8 @@ static int digi_startup_device(struct usb_serial *serial)
    for (i = 0; i < serial->type->num_ports + 1; i++) {
    port = serial->port[i];
    port->write_urb->dev = port->serial->dev;
    - if ((ret = usb_submit_urb(port->read_urb, GFP_KERNEL)) != 0) {
    + ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
    + if (ret != 0) {
    err("%s: usb_submit_urb failed, ret=%d, port=%d",
    __func__, ret, i);
    break;
    @@ -1518,7 +1536,7 @@ static int digi_startup(struct usb_serial *serial)

    /* allocate the private data structures for all ports */
    /* number of regular ports + 1 for the out-of-band port */
    - for(i = 0; i < serial->type->num_ports + 1; i++) {
    + for (i = 0; i < serial->type->num_ports + 1; i++) {
    /* allocate port private structure */
    priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL);
    if (priv == NULL) {
    @@ -1581,7 +1599,7 @@ static void digi_shutdown(struct usb_serial *serial)

    /* free the private data structures for all ports */
    /* number of regular ports + 1 for the out-of-band port */
    - for(i = 0; i < serial->type->num_ports + 1; i++)
    + for (i = 0; i < serial->type->num_ports + 1; i++)
    kfree(usb_get_serial_port_data(serial->port[i]));
    kfree(usb_get_serial_data(serial));
    }
    @@ -1604,7 +1622,7 @@ static void digi_read_bulk_callback(struct urb *urb)
    return;
    }
    if (port->serial == NULL ||
    - (serial_priv=usb_get_serial_data(port->serial)) == NULL) {
    + (serial_priv = usb_get_serial_data(port->serial)) == NULL) {
    err("%s: serial is bad or serial->private is NULL, status=%d",
    __func__, status);
    return;
    @@ -1628,22 +1646,23 @@ static void digi_read_bulk_callback(struct urb *urb)

    /* continue read */
    urb->dev = port->serial->dev;
    - if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
    + ret = usb_submit_urb(urb, GFP_ATOMIC);
    + if (ret != 0) {
    err("%s: failed resubmitting urb, ret=%d, port=%d",
    __func__, ret, priv->dp_port_num);
    }

    }

    -/*
    -* Digi Read INB Callback
    -*
    -* Digi Read INB Callback handles reads on the in band ports, sending
    -* the data on to the tty subsystem. When called we know port and
    -* port->private are not NULL and port->serial has been validated.
    -* It returns 0 if successful, 1 if successful but the port is
    -* throttled, and -1 if the sanity checks failed.
    -*/
    +/*
    + * Digi Read INB Callback
    + *
    + * Digi Read INB Callback handles reads on the in band ports, sending
    + * the data on to the tty subsystem. When called we know port and
    + * port->private are not NULL and port->serial has been validated.
    + * It returns 0 if successful, 1 if successful but the port is
    + * throttled, and -1 if the sanity checks failed.
    + */

    static int digi_read_inb_callback(struct urb *urb)
    {
    @@ -1654,8 +1673,8 @@ static int digi_read_inb_callback(struct urb *urb)
    int opcode = ((unsigned char *)urb->transfer_buffer)[0];
    int len = ((unsigned char *)urb->transfer_buffer)[1];
    int port_status = ((unsigned char *)urb->transfer_buffer)[2];
    - unsigned char *data = ((unsigned char *)urb->transfer_buffer)+3;
    - int flag,throttled;
    + unsigned char *data = ((unsigned char *)urb->transfer_buffer) + 3;
    + int flag, throttled;
    int i;
    int status = urb->status;

    @@ -1666,7 +1685,7 @@ static int digi_read_inb_callback(struct urb *urb)

    /* short/multiple packet check */
    if (urb->actual_length != len + 2) {
    - err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, "
    + err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, "
    "port=%d, opcode=%d, len=%d, actual_length=%d, "
    "status=%d", __func__, status, priv->dp_port_num,
    opcode, len, urb->actual_length, port_status);
    @@ -1708,8 +1727,9 @@ static int digi_read_inb_callback(struct urb *urb)
    if (flag == TTY_NORMAL)
    tty_insert_flip_string(tty, data, len);
    else {
    - for(i = 0; i < len; i++)
    - tty_insert_flip_char(tty, data[i], flag);
    + for (i = 0; i < len; i++)
    + tty_insert_flip_char(tty,
    + data[i], flag);
    }
    tty_flip_buffer_push(tty);
    }
    @@ -1721,19 +1741,19 @@ static int digi_read_inb_callback(struct urb *urb)
    else if (opcode != DIGI_CMD_RECEIVE_DATA)
    dbg("%s: unknown opcode: %d", __func__, opcode);

    - return(throttled ? 1 : 0);
    + return throttled ? 1 : 0;

    }


    -/*
    -* Digi Read OOB Callback
    -*
    -* Digi Read OOB Callback handles reads on the out of band port.
    -* When called we know port and port->private are not NULL and
    -* the port->serial is valid. It returns 0 if successful, and
    -* -1 if the sanity checks failed.
    -*/
    +/*
    + * Digi Read OOB Callback
    + *
    + * Digi Read OOB Callback handles reads on the out of band port.
    + * When called we know port and port->private are not NULL and
    + * the port->serial is valid. It returns 0 if successful, and
    + * -1 if the sanity checks failed.
    + */

    static int digi_read_oob_callback(struct urb *urb)
    {
    @@ -1743,12 +1763,13 @@ static int digi_read_oob_callback(struct urb *urb)
    struct digi_port *priv = usb_get_serial_port_data(port);
    int opcode, line, status, val;
    int i;
    + unsigned int rts;

    dbg("digi_read_oob_callback: port=%d, len=%d",
    priv->dp_port_num, urb->actual_length);

    /* handle each oob command */
    - for(i = 0; i < urb->actual_length - 3 {
    + for (i = 0; i < urb->actual_length - 3 {
    opcode = ((unsigned char *)urb->transfer_buffer)[i++];
    line = ((unsigned char *)urb->transfer_buffer)[i++];
    status = ((unsigned char *)urb->transfer_buffer)[i++];
    @@ -1762,27 +1783,29 @@ static int digi_read_oob_callback(struct urb *urb)

    port = serial->port[line];

    - if ((priv=usb_get_serial_port_data(port)) == NULL)
    + priv = usb_get_serial_port_data(port);
    + if (priv == NULL)
    return -1;

    + rts = 0;
    + if (port->port.count)
    + rts = port->port.tty->termios->c_cflag & CRTSCTS;
    +
    if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) {
    spin_lock(&priv->dp_port_lock);
    /* convert from digi flags to termiox flags */
    if (val & DIGI_READ_INPUT_SIGNALS_CTS) {
    priv->dp_modem_signals |= TIOCM_CTS;
    /* port must be open to use tty struct */
    - if (port->port.count
    - && port->port.tty->termios->c_cflag & CRTSCTS) {
    + if (rts) {
    port->port.tty->hw_stopped = 0;
    digi_wakeup_write(port);
    }
    } else {
    priv->dp_modem_signals &= ~TIOCM_CTS;
    /* port must be open to use tty struct */
    - if (port->port.count
    - && port->port.tty->termios->c_cflag & CRTSCTS) {
    + if (rts)
    port->port.tty->hw_stopped = 1;
    - }
    }
    if (val & DIGI_READ_INPUT_SIGNALS_DSR)
    priv->dp_modem_signals |= TIOCM_DSR;
    @@ -1819,7 +1842,7 @@ static int __init digi_init(void)
    if (retval)
    goto failed_acceleport_2_device;
    retval = usb_serial_register(&digi_acceleport_4_device);
    - if (retval)
    + if (retval)
    goto failed_acceleport_4_device;
    retval = usb_register(&digi_driver);
    if (retval)

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  11. [PATCH 21/70] termios: Termios defines for other platforms

    From: Alan Cox

    Fix up the termios of the people who have not yet got with the program

    Signed-off-by: Alan Cox
    ---

    include/asm-avr32/ioctls.h | 4 ++++
    include/asm-frv/ioctls.h | 4 ++++
    include/asm-frv/termbits.h | 5 ++++-
    3 files changed, 12 insertions(+), 1 deletions(-)


    diff --git a/include/asm-avr32/ioctls.h b/include/asm-avr32/ioctls.h
    index 0500426..0cf2c0a 100644
    --- a/include/asm-avr32/ioctls.h
    +++ b/include/asm-avr32/ioctls.h
    @@ -47,6 +47,10 @@
    #define TIOCSBRK 0x5427 /* BSD compatibility */
    #define TIOCCBRK 0x5428 /* BSD compatibility */
    #define TIOCGSID 0x5429 /* Return the session ID of FD */
    +#define TCGETS2 _IOR('T',0x2A, struct termios2)
    +#define TCSETS2 _IOW('T',0x2B, struct termios2)
    +#define TCSETSW2 _IOW('T',0x2C, struct termios2)
    +#define TCSETSF2 _IOW('T',0x2D, struct termios2)
    #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
    #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */

    diff --git a/include/asm-frv/ioctls.h b/include/asm-frv/ioctls.h
    index 341c7dd..d0c30e3 100644
    --- a/include/asm-frv/ioctls.h
    +++ b/include/asm-frv/ioctls.h
    @@ -47,6 +47,10 @@
    #define TIOCSBRK 0x5427 /* BSD compatibility */
    #define TIOCCBRK 0x5428 /* BSD compatibility */
    #define TIOCGSID 0x5429 /* Return the session ID of FD */
    +#define TCGETS2 _IOR('T',0x2A, struct termios2)
    +#define TCSETS2 _IOW('T',0x2B, struct termios2)
    +#define TCSETSW2 _IOW('T',0x2C, struct termios2)
    +#define TCSETSF2 _IOW('T',0x2D, struct termios2)
    #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
    #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */

    diff --git a/include/asm-frv/termbits.h b/include/asm-frv/termbits.h
    index 74851b4..5568492 100644
    --- a/include/asm-frv/termbits.h
    +++ b/include/asm-frv/termbits.h
    @@ -141,6 +141,7 @@ struct ktermios {
    #define HUPCL 0002000
    #define CLOCAL 0004000
    #define CBAUDEX 0010000
    +#define BOTHER 0010000
    #define B57600 0010001
    #define B115200 0010002
    #define B230400 0010003
    @@ -156,11 +157,13 @@ struct ktermios {
    #define B3000000 0010015
    #define B3500000 0010016
    #define B4000000 0010017
    -#define CIBAUD 002003600000 /* input baud rate (not used) */
    +#define CIBAUD 002003600000 /* Input baud rate */
    #define CTVB 004000000000 /* VisioBraille Terminal flow control */
    #define CMSPAR 010000000000 /* mark or space (stick) parity */
    #define CRTSCTS 020000000000 /* flow control */

    +#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
    +
    /* c_lflag bits */
    #define ISIG 0000001
    #define ICANON 0000002

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  12. [PATCH 10/70] riscom8: remove bogus checks

    From: Alan Cox

    Chris Malley posted a patch removing a NULL check in the riscom8 driver.
    Further analysis shows that even more of the tests are irrelevant so we
    can delete lots of stuff

    Signed-off-by: Alan Cox
    ---

    drivers/char/riscom8.c | 32 ++++++++------------------------
    1 files changed, 8 insertions(+), 24 deletions(-)


    diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
    index b0ba241..3ca8957 100644
    --- a/drivers/char/riscom8.c
    +++ b/drivers/char/riscom8.c
    @@ -638,9 +638,6 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
    unsigned char cor1 = 0, cor3 = 0;
    unsigned char mcor1 = 0, mcor2 = 0;

    - if (tty == NULL || tty->termios == NULL)
    - return;
    -
    port->IER = 0;
    port->COR2 = 0;
    port->MSVR = MSVR_RTS;
    @@ -794,8 +791,7 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)

    spin_lock_irqsave(&riscom_lock, flags);

    - if (port->port.tty)
    - clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
    + clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
    if (port->port.count == 1)
    bp->count++;
    port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
    @@ -807,10 +803,9 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
    }

    /* Must be called with interrupts disabled */
    -static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
    +static void rc_shutdown_port(struct tty_struct *tty,
    + struct riscom_board *bp, struct riscom_port *port)
    {
    - struct tty_struct *tty;
    -
    if (!(port->port.flags & ASYNC_INITIALIZED))
    return;

    @@ -830,10 +825,7 @@ static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
    }
    #endif
    tty_port_free_xmit_buf(&port->port);
    -
    - tty = port->port.tty;
    -
    - if (tty == NULL || C_HUPCL(tty)) {
    + if (C_HUPCL(tty)) {
    /* Drop DTR */
    bp->DTR |= (1u << port_No(port));
    rc_out(bp, RC_DTR, bp->DTR);
    @@ -848,8 +840,7 @@ static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
    port->IER = 0;
    rc_out(bp, CD180_IER, port->IER);

    - if (tty)
    - set_bit(TTY_IO_ERROR, &tty->flags);
    + set_bit(TTY_IO_ERROR, &tty->flags);
    port->port.flags &= ~ASYNC_INITIALIZED;

    if (--bp->count < 0) {
    @@ -1067,7 +1058,7 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
    break;
    }
    }
    - rc_shutdown_port(bp, port);
    + rc_shutdown_port(tty, bp, port);
    rc_flush_buffer(tty);
    tty_ldisc_flush(tty);

    @@ -1098,9 +1089,6 @@ static int rc_write(struct tty_struct *tty,

    bp = port_Board(port);

    - if (!tty || !port->port.xmit_buf)
    - return 0;
    -
    while (1) {
    spin_lock_irqsave(&riscom_lock, flags);

    @@ -1141,9 +1129,6 @@ static int rc_put_char(struct tty_struct *tty, unsigned char ch)
    if (rc_paranoia_check(port, tty->name, "rc_put_char"))
    return 0;

    - if (!tty || !port->port.xmit_buf)
    - return 0;
    -
    spin_lock_irqsave(&riscom_lock, flags);

    if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
    @@ -1167,8 +1152,7 @@ static void rc_flush_chars(struct tty_struct *tty)
    if (rc_paranoia_check(port, tty->name, "rc_flush_chars"))
    return;

    - if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
    - !port->port.xmit_buf)
    + if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped)
    return;

    spin_lock_irqsave(&riscom_lock, flags);
    @@ -1488,7 +1472,7 @@ static void rc_hangup(struct tty_struct *tty)

    bp = port_Board(port);

    - rc_shutdown_port(bp, port);
    + rc_shutdown_port(tty, bp, port);
    port->port.count = 0;
    port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
    port->port.tty = NULL;

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  13. [PATCH 12/70] istallion: use tty_port

    From: Alan Cox

    Switch istallion to use the new tty_port structure

    Signed-off-by: Alan Cox
    ---

    drivers/char/istallion.c | 116 +++++++++++++++++++++++----------------------
    include/linux/istallion.h | 6 --
    2 files changed, 59 insertions(+), 63 deletions(-)


    diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
    index 7c8b62f..6ef1c56 100644
    --- a/drivers/char/istallion.c
    +++ b/drivers/char/istallion.c
    @@ -735,8 +735,8 @@ static void stli_cleanup_ports(struct stlibrd *brdp)
    for (j = 0; j < STL_MAXPORTS; j++) {
    portp = brdp->ports[j];
    if (portp != NULL) {
    - if (portp->tty != NULL)
    - tty_hangup(portp->tty);
    + if (portp->port.tty != NULL)
    + tty_hangup(portp->port.tty);
    kfree(portp);
    }
    }
    @@ -811,9 +811,9 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
    * The sleep here does not need interrupt protection since the wakeup
    * for it is done with the same context.
    */
    - if (portp->flags & ASYNC_CLOSING) {
    - interruptible_sleep_on(&portp->close_wait);
    - if (portp->flags & ASYNC_HUP_NOTIFY)
    + if (portp->port.flags & ASYNC_CLOSING) {
    + interruptible_sleep_on(&portp->port.close_wait);
    + if (portp->port.flags & ASYNC_HUP_NOTIFY)
    return -EAGAIN;
    return -ERESTARTSYS;
    }
    @@ -824,7 +824,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
    * requires several commands to the board we will need to wait for any
    * other open that is already initializing the port.
    */
    - portp->tty = tty;
    + portp->port.tty = tty;
    tty->driver_data = portp;
    portp->refcount++;

    @@ -833,10 +833,10 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
    if (signal_pending(current))
    return -ERESTARTSYS;

    - if ((portp->flags & ASYNC_INITIALIZED) == 0) {
    + if ((portp->port.flags & ASYNC_INITIALIZED) == 0) {
    set_bit(ST_INITIALIZING, &portp->state);
    if ((rc = stli_initopen(brdp, portp)) >= 0) {
    - portp->flags |= ASYNC_INITIALIZED;
    + portp->port.flags |= ASYNC_INITIALIZED;
    clear_bit(TTY_IO_ERROR, &tty->flags);
    }
    clear_bit(ST_INITIALIZING, &portp->state);
    @@ -851,9 +851,9 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
    * The sleep here does not need interrupt protection since the wakeup
    * for it is done with the same context.
    */
    - if (portp->flags & ASYNC_CLOSING) {
    - interruptible_sleep_on(&portp->close_wait);
    - if (portp->flags & ASYNC_HUP_NOTIFY)
    + if (portp->port.flags & ASYNC_CLOSING) {
    + interruptible_sleep_on(&portp->port.close_wait);
    + if (portp->port.flags & ASYNC_HUP_NOTIFY)
    return -EAGAIN;
    return -ERESTARTSYS;
    }
    @@ -867,7 +867,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
    if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0)
    return rc;
    }
    - portp->flags |= ASYNC_NORMAL_ACTIVE;
    + portp->port.flags |= ASYNC_NORMAL_ACTIVE;
    return 0;
    }

    @@ -895,7 +895,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
    return;
    }

    - portp->flags |= ASYNC_CLOSING;
    + portp->port.flags |= ASYNC_CLOSING;

    /*
    * May want to wait for data to drain before closing. The BUSY flag
    @@ -911,7 +911,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
    if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
    tty_wait_until_sent(tty, portp->closing_wait);

    - portp->flags &= ~ASYNC_INITIALIZED;
    + portp->port.flags &= ~ASYNC_INITIALIZED;
    brdp = stli_brds[portp->brdnr];
    stli_rawclose(brdp, portp, 0, 0);
    if (tty->termios->c_cflag & HUPCL) {
    @@ -931,16 +931,16 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
    stli_flushbuffer(tty);

    tty->closing = 0;
    - portp->tty = NULL;
    + portp->port.tty = NULL;

    if (portp->openwaitcnt) {
    if (portp->close_delay)
    msleep_interruptible(jiffies_to_msecs(portp->close_delay));
    - wake_up_interruptible(&portp->open_wait);
    + wake_up_interruptible(&portp->port.open_wait);
    }

    - portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
    - wake_up_interruptible(&portp->close_wait);
    + portp->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
    + wake_up_interruptible(&portp->port.close_wait);
    }

    /************************************************** ***************************/
    @@ -970,7 +970,7 @@ static int stli_initopen(struct stlibrd *brdp, struct stliport *portp)
    sizeof(asynotify_t), 0)) < 0)
    return rc;

    - tty = portp->tty;
    + tty = portp->port.tty;
    if (tty == NULL)
    return -ENODEV;
    stli_mkasyport(portp, &aport, tty->termios);
    @@ -1169,7 +1169,7 @@ static int stli_setport(struct stliport *portp)

    if (portp == NULL)
    return -ENODEV;
    - if (portp->tty == NULL)
    + if (portp->port.tty == NULL)
    return -ENODEV;
    if (portp->brdnr >= stli_nrbrds)
    return -ENODEV;
    @@ -1177,7 +1177,7 @@ static int stli_setport(struct stliport *portp)
    if (brdp == NULL)
    return -ENODEV;

    - stli_mkasyport(portp, &aport, portp->tty->termios);
    + stli_mkasyport(portp, &aport, portp->port.tty->termios);
    return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0));
    }

    @@ -1196,7 +1196,7 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct
    rc = 0;
    doclocal = 0;

    - if (portp->tty->termios->c_cflag & CLOCAL)
    + if (portp->port.tty->termios->c_cflag & CLOCAL)
    doclocal++;

    spin_lock_irqsave(&stli_lock, flags);
    @@ -1211,14 +1211,14 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct
    &portp->asig, sizeof(asysigs_t), 0)) < 0)
    break;
    if (tty_hung_up_p(filp) ||
    - ((portp->flags & ASYNC_INITIALIZED) == 0)) {
    - if (portp->flags & ASYNC_HUP_NOTIFY)
    + ((portp->port.flags & ASYNC_INITIALIZED) == 0)) {
    + if (portp->port.flags & ASYNC_HUP_NOTIFY)
    rc = -EBUSY;
    else
    rc = -ERESTARTSYS;
    break;
    }
    - if (((portp->flags & ASYNC_CLOSING) == 0) &&
    + if (((portp->port.flags & ASYNC_CLOSING) == 0) &&
    (doclocal || (portp->sigs & TIOCM_CD))) {
    break;
    }
    @@ -1226,7 +1226,7 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct
    rc = -ERESTARTSYS;
    break;
    }
    - interruptible_sleep_on(&portp->open_wait);
    + interruptible_sleep_on(&portp->port.open_wait);
    }

    spin_lock_irqsave(&stli_lock, flags);
    @@ -1548,7 +1548,7 @@ static int stli_getserial(struct stliport *portp, struct serial_struct __user *s
    sio.type = PORT_UNKNOWN;
    sio.line = portp->portnr;
    sio.irq = 0;
    - sio.flags = portp->flags;
    + sio.flags = portp->port.flags;
    sio.baud_base = portp->baud_base;
    sio.close_delay = portp->close_delay;
    sio.closing_wait = portp->closing_wait;
    @@ -1583,11 +1583,11 @@ static int stli_setserial(struct stliport *portp, struct serial_struct __user *s
    if ((sio.baud_base != portp->baud_base) ||
    (sio.close_delay != portp->close_delay) ||
    ((sio.flags & ~ASYNC_USR_MASK) !=
    - (portp->flags & ~ASYNC_USR_MASK)))
    + (portp->port.flags & ~ASYNC_USR_MASK)))
    return -EPERM;
    }

    - portp->flags = (portp->flags & ~ASYNC_USR_MASK) |
    + portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) |
    (sio.flags & ASYNC_USR_MASK);
    portp->baud_base = sio.baud_base;
    portp->close_delay = sio.close_delay;
    @@ -1751,7 +1751,7 @@ static void stli_settermios(struct tty_struct *tty, struct ktermios *old)
    if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0))
    tty->hw_stopped = 0;
    if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
    - wake_up_interruptible(&portp->open_wait);
    + wake_up_interruptible(&portp->port.open_wait);
    }

    /************************************************** ***************************/
    @@ -1834,7 +1834,7 @@ static void stli_hangup(struct tty_struct *tty)
    if (brdp == NULL)
    return;

    - portp->flags &= ~ASYNC_INITIALIZED;
    + portp->port.flags &= ~ASYNC_INITIALIZED;

    if (!test_bit(ST_CLOSING, &portp->state))
    stli_rawclose(brdp, portp, 0, 0);
    @@ -1855,12 +1855,12 @@ static void stli_hangup(struct tty_struct *tty)
    clear_bit(ST_TXBUSY, &portp->state);
    clear_bit(ST_RXSTOP, &portp->state);
    set_bit(TTY_IO_ERROR, &tty->flags);
    - portp->tty = NULL;
    - portp->flags &= ~ASYNC_NORMAL_ACTIVE;
    + portp->port.tty = NULL;
    + portp->port.flags &= ~ASYNC_NORMAL_ACTIVE;
    portp->refcount = 0;
    spin_unlock_irqrestore(&stli_lock, flags);

    - wake_up_interruptible(&portp->open_wait);
    + wake_up_interruptible(&portp->port.open_wait);
    }

    /************************************************** ***************************/
    @@ -2188,7 +2188,7 @@ static void stli_read(struct stlibrd *brdp, struct stliport *portp)

    if (test_bit(ST_RXSTOP, &portp->state))
    return;
    - tty = portp->tty;
    + tty = portp->port.tty;
    if (tty == NULL)
    return;

    @@ -2362,7 +2362,7 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
    if (ap->notify) {
    nt = ap->changed;
    ap->notify = 0;
    - tty = portp->tty;
    + tty = portp->port.tty;

    if (nt.signal & SG_DCD) {
    oldsigs = portp->sigs;
    @@ -2370,10 +2370,10 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
    clear_bit(ST_GETSIGS, &portp->state);
    if ((portp->sigs & TIOCM_CD) &&
    ((oldsigs & TIOCM_CD) == 0))
    - wake_up_interruptible(&portp->open_wait);
    + wake_up_interruptible(&portp->port.open_wait);
    if ((oldsigs & TIOCM_CD) &&
    ((portp->sigs & TIOCM_CD) == 0)) {
    - if (portp->flags & ASYNC_CHECK_CD) {
    + if (portp->port.flags & ASYNC_CHECK_CD) {
    if (tty)
    tty_hangup(tty);
    }
    @@ -2392,7 +2392,7 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
    if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) {
    if (tty != NULL) {
    tty_insert_flip_char(tty, 0, TTY_BREAK);
    - if (portp->flags & ASYNC_SAK) {
    + if (portp->port.flags & ASYNC_SAK) {
    do_SAK(tty);
    EBRDENABLE(brdp);
    }
    @@ -2542,17 +2542,17 @@ static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermio
    /*
    * Start of by setting the baud, char size, parity and stop bit info.
    */
    - pp->baudout = tty_get_baud_rate(portp->tty);
    + pp->baudout = tty_get_baud_rate(portp->port.tty);
    if ((tiosp->c_cflag & CBAUD) == B38400) {
    - if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
    + if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
    pp->baudout = 57600;
    - else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
    + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
    pp->baudout = 115200;
    - else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
    + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
    pp->baudout = 230400;
    - else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
    + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
    pp->baudout = 460800;
    - else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
    + else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
    pp->baudout = (portp->baud_base / portp->custom_divisor);
    }
    if (pp->baudout > STL_MAXBAUD)
    @@ -2625,9 +2625,9 @@ static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermio
    * Set up clocal processing as required.
    */
    if (tiosp->c_cflag & CLOCAL)
    - portp->flags &= ~ASYNC_CHECK_CD;
    + portp->port.flags &= ~ASYNC_CHECK_CD;
    else
    - portp->flags |= ASYNC_CHECK_CD;
    + portp->port.flags |= ASYNC_CHECK_CD;

    /*
    * Transfer any persistent flags into the asyport structure.
    @@ -2703,8 +2703,8 @@ static int stli_initports(struct stlibrd *brdp)
    portp->baud_base = STL_BAUDBASE;
    portp->close_delay = STL_CLOSEDELAY;
    portp->closing_wait = 30 * HZ;
    - init_waitqueue_head(&portp->open_wait);
    - init_waitqueue_head(&portp->close_wait);
    + init_waitqueue_head(&portp->port.open_wait);
    + init_waitqueue_head(&portp->port.close_wait);
    init_waitqueue_head(&portp->raw_wait);
    panelport++;
    if (panelport >= brdp->panels[panelnr]) {
    @@ -4246,18 +4246,18 @@ static int stli_portcmdstats(struct stliport *portp)
    stli_comstats.panel = portp->panelnr;
    stli_comstats.port = portp->portnr;
    stli_comstats.state = portp->state;
    - stli_comstats.flags = portp->flags;
    + stli_comstats.flags = portp->port.flag;

    spin_lock_irqsave(&brd_lock, flags);
    - if (portp->tty != NULL) {
    - if (portp->tty->driver_data == portp) {
    - stli_comstats.ttystate = portp->tty->flags;
    + if (portp->port.tty != NULL) {
    + if (portp->port.tty->driver_data == portp) {
    + stli_comstats.ttystate = portp->port.tty->flags;
    stli_comstats.rxbuffered = -1;
    - if (portp->tty->termios != NULL) {
    - stli_comstats.cflags = portp->tty->termios->c_cflag;
    - stli_comstats.iflags = portp->tty->termios->c_iflag;
    - stli_comstats.oflags = portp->tty->termios->c_oflag;
    - stli_comstats.lflags = portp->tty->termios->c_lflag;
    + if (portp->port.tty->termios != NULL) {
    + stli_comstats.cflags = portp->port.tty->termios->c_cflag;
    + stli_comstats.iflags = portp->port.tty->termios->c_iflag;
    + stli_comstats.oflags = portp->port.tty->termios->c_oflag;
    + stli_comstats.lflags = portp->port.tty->termios->c_lflag;
    }
    }
    }
    diff --git a/include/linux/istallion.h b/include/linux/istallion.h
    index 5a84fe9..0d18407 100644
    --- a/include/linux/istallion.h
    +++ b/include/linux/istallion.h
    @@ -51,25 +51,21 @@
    */
    struct stliport {
    unsigned long magic;
    + struct tty_port port;
    unsigned int portnr;
    unsigned int panelnr;
    unsigned int brdnr;
    unsigned long state;
    unsigned int devnr;
    - int flags;
    int baud_base;
    int custom_divisor;
    int close_delay;
    int closing_wait;
    - int refcount;
    int openwaitcnt;
    int rc;
    int argsize;
    void *argp;
    unsigned int rxmarkmsk;
    - struct tty_struct *tty;
    - wait_queue_head_t open_wait;
    - wait_queue_head_t close_wait;
    wait_queue_head_t raw_wait;
    struct asysigs asig;
    unsigned long addr;

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  14. [PATCH 24/70] whiteheat: coding style

    From: Alan Cox

    Bring ezusb and whiteheat into line with the coding style

    Signed-off-by: Alan Cox
    ---

    drivers/usb/serial/ezusb.c | 22 +-
    drivers/usb/serial/whiteheat.c | 429 ++++++++++++++++++++++------------------
    drivers/usb/serial/whiteheat.h | 78 +++++--
    3 files changed, 302 insertions(+), 227 deletions(-)


    diff --git a/drivers/usb/serial/ezusb.c b/drivers/usb/serial/ezusb.c
    index cc4fbd9..711e84f 100644
    --- a/drivers/usb/serial/ezusb.c
    +++ b/drivers/usb/serial/ezusb.c
    @@ -20,7 +20,8 @@
    /* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */
    #define CPUCS_REG 0x7F92

    -int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest)
    +int ezusb_writememory(struct usb_serial *serial, int address,
    + unsigned char *data, int length, __u8 request)
    {
    int result;
    unsigned char *transfer_buffer;
    @@ -33,26 +34,27 @@ int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *da

    transfer_buffer = kmemdup(data, length, GFP_KERNEL);
    if (!transfer_buffer) {
    - dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n", __func__, length);
    + dev_err(&serial->dev->dev, "%s - kmalloc(%d) failed.\n",
    + __func__, length);
    return -ENOMEM;
    }
    - result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 3000);
    - kfree (transfer_buffer);
    + result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
    + request, 0x40, address, 0, transfer_buffer, length, 3000);
    + kfree(transfer_buffer);
    return result;
    }
    +EXPORT_SYMBOL_GPL(ezusb_writememory);

    -int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit)
    +int ezusb_set_reset(struct usb_serial *serial, unsigned char reset_bit)
    {
    int response;

    /* dbg("%s - %d", __func__, reset_bit); */
    - response = ezusb_writememory (serial, CPUCS_REG, &reset_bit, 1, 0xa0);
    + response = ezusb_writememory(serial, CPUCS_REG, &reset_bit, 1, 0xa0);
    if (response < 0)
    - dev_err(&serial->dev->dev, "%s- %d failed\n", __func__, reset_bit);
    + dev_err(&serial->dev->dev, "%s- %d failed\n",
    + __func__, reset_bit);
    return response;
    }
    -
    -
    -EXPORT_SYMBOL_GPL(ezusb_writememory);
    EXPORT_SYMBOL_GPL(ezusb_set_reset);

    diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
    index fdadf39..5a3ed57 100644
    --- a/drivers/usb/serial/whiteheat.c
    +++ b/drivers/usb/serial/whiteheat.c
    @@ -12,29 +12,31 @@
    * the Free Software Foundation; either version 2 of the License, or
    * (at your option) any later version.
    *
    - * See Documentation/usb/usb-serial.txt for more information on using this driver
    + * See Documentation/usb/usb-serial.txt for more information on using this
    + * driver
    *
    * (10/09/2002) Stuart MacDonald (stuartm@connecttech.com)
    * Upgrade to full working driver
    *
    * (05/30/2001) gkh
    - * switched from using spinlock to a semaphore, which fixes lots of problems.
    + * switched from using spinlock to a semaphore, which fixes lots of
    + * problems.
    *
    * (04/08/2001) gb
    * Identify version on module load.
    - *
    + *
    * 2001_Mar_19 gkh
    - * Fixed MOD_INC and MOD_DEC logic, the ability to open a port more
    + * Fixed MOD_INC and MOD_DEC logic, the ability to open a port more
    * than once, and the got the proper usb_device_id table entries so
    * the driver works again.
    *
    * (11/01/2000) Adam J. Richter
    * usb_device_id table support
    - *
    + *
    * (10/05/2000) gkh
    * Fixed bug with urb->dev not being set properly, now that the usb
    * core needs it.
    - *
    + *
    * (10/03/2000) smd
    * firmware is improved to guard against crap sent to device
    * firmware now replies CMD_FAILURE on bad things
    @@ -52,9 +54,9 @@
    * Fixed bug with port->minor that was found by Al Borchers
    *
    * (07/04/2000) gkh
    - * Added support for port settings. Baud rate can now be changed. Line signals
    - * are not transferred to and from the tty layer yet, but things seem to be
    - * working well now.
    + * Added support for port settings. Baud rate can now be changed. Line
    + * signals are not transferred to and from the tty layer yet, but things
    + * seem to be working well now.
    *
    * (05/04/2000) gkh
    * First cut at open and close commands. Data can flow through the ports at
    @@ -62,7 +64,7 @@
    *
    * (03/26/2000) gkh
    * Split driver up into device specific pieces.
    - *
    + *
    */

    #include
    @@ -75,14 +77,14 @@
    #include
    #include
    #include
    -#include
    +#include
    #include
    #include
    #include
    #include
    #include
    -#include "whiteheat_fw.h" /* firmware for the ConnectTech WhiteHEAT device */
    -#include "whiteheat.h" /* WhiteHEAT specific commands */
    +#include "whiteheat_fw.h" /* firmware for the ConnectTech WhiteHEAT */
    +#include "whiteheat.h" /* WhiteHEAT specific commands */

    static int debug;

    @@ -124,7 +126,7 @@ static struct usb_device_id id_table_combined [] = {
    { } /* Terminating entry */
    };

    -MODULE_DEVICE_TABLE (usb, id_table_combined);
    +MODULE_DEVICE_TABLE(usb, id_table_combined);

    static struct usb_driver whiteheat_driver = {
    .name = "whiteheat",
    @@ -135,26 +137,34 @@ static struct usb_driver whiteheat_driver = {
    };

    /* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */
    -static int whiteheat_firmware_download (struct usb_serial *serial, const struct usb_device_id *id);
    -static int whiteheat_firmware_attach (struct usb_serial *serial);
    +static int whiteheat_firmware_download(struct usb_serial *serial,
    + const struct usb_device_id *id);
    +static int whiteheat_firmware_attach(struct usb_serial *serial);

    /* function prototypes for the Connect Tech WhiteHEAT serial converter */
    -static int whiteheat_attach (struct usb_serial *serial);
    -static void whiteheat_shutdown (struct usb_serial *serial);
    -static int whiteheat_open (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
    -static void whiteheat_close (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
    -static int whiteheat_write (struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count);
    -static int whiteheat_write_room (struct tty_struct *tty);
    -static int whiteheat_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg);
    -static void whiteheat_set_termios (struct tty_struct *tty, struct usb_serial_port *port, struct ktermios * old);
    -static int whiteheat_tiocmget (struct tty_struct *tty, struct file *file);
    -static int whiteheat_tiocmset (struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear);
    -static void whiteheat_break_ctl (struct tty_struct *tty, int break_state);
    -static int whiteheat_chars_in_buffer (struct tty_struct *tty);
    -static void whiteheat_throttle (struct tty_struct *tty);
    -static void whiteheat_unthrottle (struct tty_struct *tty);
    -static void whiteheat_read_callback (struct urb *urb);
    -static void whiteheat_write_callback (struct urb *urb);
    +static int whiteheat_attach(struct usb_serial *serial);
    +static void whiteheat_shutdown(struct usb_serial *serial);
    +static int whiteheat_open(struct tty_struct *tty,
    + struct usb_serial_port *port, struct file *filp);
    +static void whiteheat_close(struct tty_struct *tty,
    + struct usb_serial_port *port, struct file *filp);
    +static int whiteheat_write(struct tty_struct *tty,
    + struct usb_serial_port *port,
    + const unsigned char *buf, int count);
    +static int whiteheat_write_room(struct tty_struct *tty);
    +static int whiteheat_ioctl(struct tty_struct *tty, struct file *file,
    + unsigned int cmd, unsigned long arg);
    +static void whiteheat_set_termios(struct tty_struct *tty,
    + struct usb_serial_port *port, struct ktermios *old);
    +static int whiteheat_tiocmget(struct tty_struct *tty, struct file *file);
    +static int whiteheat_tiocmset(struct tty_struct *tty, struct file *file,
    + unsigned int set, unsigned int clear);
    +static void whiteheat_break_ctl(struct tty_struct *tty, int break_state);
    +static int whiteheat_chars_in_buffer(struct tty_struct *tty);
    +static void whiteheat_throttle(struct tty_struct *tty);
    +static void whiteheat_unthrottle(struct tty_struct *tty);
    +static void whiteheat_read_callback(struct urb *urb);
    +static void whiteheat_write_callback(struct urb *urb);

    static struct usb_serial_driver whiteheat_fake_device = {
    .driver = {
    @@ -201,7 +211,9 @@ struct whiteheat_command_private {
    struct mutex mutex;
    __u8 port_running;
    __u8 command_finished;
    - wait_queue_head_t wait_command; /* for handling sleeping while waiting for a command to finish */
    + wait_queue_head_t wait_command; /* for handling sleeping whilst
    + waiting for a command to
    + finish */
    __u8 result_buffer[64];
    };

    @@ -238,11 +250,13 @@ static void command_port_write_callback(struct urb *urb);
    static void command_port_read_callback(struct urb *urb);

    static int start_port_read(struct usb_serial_port *port);
    -static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb, struct list_head *head);
    +static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
    + struct list_head *head);
    static struct list_head *list_first(struct list_head *head);
    static void rx_data_softint(struct work_struct *work);

    -static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize);
    +static int firm_send_command(struct usb_serial_port *port, __u8 command,
    + __u8 *data, __u8 datasize);
    static int firm_open(struct usb_serial_port *port);
    static int firm_close(struct usb_serial_port *port);
    static int firm_setup_port(struct tty_struct *tty);
    @@ -277,65 +291,67 @@ static int firm_report_tx_done(struct usb_serial_port *port);
    - device renumerated itself and comes up as new device id with all
    firmware download completed.
    */
    -static int whiteheat_firmware_download (struct usb_serial *serial, const struct usb_device_id *id)
    +static int whiteheat_firmware_download(struct usb_serial *serial,
    + const struct usb_device_id *id)
    {
    int response;
    const struct whiteheat_hex_record *record;
    -
    +
    dbg("%s", __func__);
    -
    - response = ezusb_set_reset (serial, 1);
    +
    + response = ezusb_set_reset(serial, 1);

    record = &whiteheat_loader[0];
    while (record->address != 0xffff) {
    - response = ezusb_writememory (serial, record->address,
    - (unsigned char *)record->data, record->data_size, 0xa0);
    + response = ezusb_writememory(serial, record->address,
    + (unsigned char *)record->data,
    + record->data_size, 0xa0);
    if (response < 0) {
    err("%s - ezusb_writememory failed for loader (%d %04X %p %d)",
    - __func__, response, record->address, record->data, record->data_size);
    + __func__, response, record->address,
    + record->data, record->data_size);
    break;
    }
    ++record;
    }

    - response = ezusb_set_reset (serial, 0);
    + response = ezusb_set_reset(serial, 0);

    record = &whiteheat_firmware[0];
    - while (record->address < 0x1b40) {
    + while (record->address < 0x1b40)
    ++record;
    - }
    while (record->address != 0xffff) {
    - response = ezusb_writememory (serial, record->address,
    - (unsigned char *)record->data, record->data_size, 0xa3);
    + response = ezusb_writememory(serial, record->address,
    + (unsigned char *)record->data, record->data_size, 0xa3);
    if (response < 0) {
    - err("%s - ezusb_writememory failed for first firmware step (%d %04X %p %d)",
    - __func__, response, record->address, record->data, record->data_size);
    + err("%s - ezusb_writememory failed for first firmware step (%d %04X %p %d)",
    + __func__, response, record->address,
    + record->data, record->data_size);
    break;
    }
    ++record;
    }
    -
    - response = ezusb_set_reset (serial, 1);
    +
    + response = ezusb_set_reset(serial, 1);

    record = &whiteheat_firmware[0];
    while (record->address < 0x1b40) {
    - response = ezusb_writememory (serial, record->address,
    - (unsigned char *)record->data, record->data_size, 0xa0);
    + response = ezusb_writememory(serial, record->address,
    + (unsigned char *)record->data, record->data_size, 0xa0);
    if (response < 0) {
    - err("%s - ezusb_writememory failed for second firmware step (%d %04X %p %d)",
    - __func__, response, record->address, record->data, record->data_size);
    + err("%s - ezusb_writememory failed for second firmware step (%d %04X %p %d)",
    + __func__, response, record->address,
    + record->data, record->data_size);
    break;
    }
    ++record;
    }
    -
    - response = ezusb_set_reset (serial, 0);
    -
    + ezusb_set_reset(serial, 0);
    return 0;
    }


    -static int whiteheat_firmware_attach (struct usb_serial *serial)
    +static int whiteheat_firmware_attach(struct usb_serial *serial)
    {
    /* We want this device to fail to have a driver assigned to it */
    return 1;
    @@ -345,7 +361,7 @@ static int whiteheat_firmware_attach (struct usb_serial *serial)
    /************************************************** ***************************
    * Connect Tech's White Heat serial driver functions
    ************************************************** ***************************/
    -static int whiteheat_attach (struct usb_serial *serial)
    +static int whiteheat_attach(struct usb_serial *serial)
    {
    struct usb_serial_port *command_port;
    struct whiteheat_command_private *command_info;
    @@ -366,43 +382,52 @@ static int whiteheat_attach (struct usb_serial *serial)

    command_port = serial->port[COMMAND_PORT];

    - pipe = usb_sndbulkpipe (serial->dev, command_port->bulk_out_endpointAddress);
    + pipe = usb_sndbulkpipe(serial->dev,
    + command_port->bulk_out_endpointAddress);
    command = kmalloc(2, GFP_KERNEL);
    if (!command)
    goto no_command_buffer;
    command[0] = WHITEHEAT_GET_HW_INFO;
    command[1] = 0;
    -
    +
    result = kmalloc(sizeof(*hw_info) + 1, GFP_KERNEL);
    if (!result)
    goto no_result_buffer;
    /*
    * When the module is reloaded the firmware is still there and
    * the endpoints are still in the usb core unchanged. This is the
    - * unlinking bug in disguise. Same for the call below.
    - */
    + * unlinking bug in disguise. Same for the call below.
    + */
    usb_clear_halt(serial->dev, pipe);
    - ret = usb_bulk_msg (serial->dev, pipe, command, 2, &alen, COMMAND_TIMEOUT_MS);
    + ret = usb_bulk_msg(serial->dev, pipe, command, 2,
    + &alen, COMMAND_TIMEOUT_MS);
    if (ret) {
    - err("%s: Couldn't send command [%d]", serial->type->description, ret);
    + err("%s: Couldn't send command [%d]",
    + serial->type->description, ret);
    goto no_firmware;
    } else if (alen != 2) {
    - err("%s: Send command incomplete [%d]", serial->type->description, alen);
    + err("%s: Send command incomplete [%d]",
    + serial->type->description, alen);
    goto no_firmware;
    }

    - pipe = usb_rcvbulkpipe (serial->dev, command_port->bulk_in_endpointAddress);
    + pipe = usb_rcvbulkpipe(serial->dev,
    + command_port->bulk_in_endpointAddress);
    /* See the comment on the usb_clear_halt() above */
    usb_clear_halt(serial->dev, pipe);
    - ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS);
    + ret = usb_bulk_msg(serial->dev, pipe, result,
    + sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS);
    if (ret) {
    - err("%s: Couldn't get results [%d]", serial->type->description, ret);
    + err("%s: Couldn't get results [%d]",
    + serial->type->description, ret);
    goto no_firmware;
    } else if (alen != sizeof(*hw_info) + 1) {
    - err("%s: Get results incomplete [%d]", serial->type->description, alen);
    + err("%s: Get results incomplete [%d]",
    + serial->type->description, alen);
    goto no_firmware;
    } else if (result[0] != command[0]) {
    - err("%s: Command failed [%d]", serial->type->description, result[0]);
    + err("%s: Command failed [%d]",
    + serial->type->description, result[0]);
    goto no_firmware;
    }

    @@ -416,7 +441,8 @@ static int whiteheat_attach (struct usb_serial *serial)

    info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL);
    if (info == NULL) {
    - err("%s: Out of memory for port structures\n", serial->type->description);
    + err("%s: Out of memory for port structures\n",
    + serial->type->description);
    goto no_private;
    }

    @@ -486,9 +512,11 @@ static int whiteheat_attach (struct usb_serial *serial)
    usb_set_serial_port_data(port, info);
    }

    - command_info = kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL);
    + command_info = kmalloc(sizeof(struct whiteheat_command_private),
    + GFP_KERNEL);
    if (command_info == NULL) {
    - err("%s: Out of memory for port structures\n", serial->type->description);
    + err("%s: Out of memory for port structures\n",
    + serial->type->description);
    goto no_command_private;
    }

    @@ -505,9 +533,12 @@ static int whiteheat_attach (struct usb_serial *serial)

    no_firmware:
    /* Firmware likely not running */
    - err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->description);
    - err("%s: If the firmware is not running (status led not blinking)\n", serial->type->description);
    - err("%s: please contact support@connecttech.com\n", serial->type->description);
    + err("%s: Unable to retrieve firmware version, try replugging\n",
    + serial->type->description);
    + err("%s: If the firmware is not running (status led not blinking)\n",
    + serial->type->description);
    + err("%s: please contact support@connecttech.com\n",
    + serial->type->description);
    kfree(result);
    return -ENODEV;

    @@ -550,7 +581,7 @@ no_command_buffer:
    }


    -static void whiteheat_shutdown (struct usb_serial *serial)
    +static void whiteheat_shutdown(struct usb_serial *serial)
    {
    struct usb_serial_port *command_port;
    struct usb_serial_port *port;
    @@ -565,7 +596,7 @@ static void whiteheat_shutdown (struct usb_serial *serial)

    /* free up our private data for our command port */
    command_port = serial->port[COMMAND_PORT];
    - kfree (usb_get_serial_port_data(command_port));
    + kfree(usb_get_serial_port_data(command_port));

    for (i = 0; i < serial->num_ports; i++) {
    port = serial->port[i];
    @@ -592,8 +623,7 @@ static void whiteheat_shutdown (struct usb_serial *serial)
    return;
    }

    -
    -static int whiteheat_open (struct tty_struct *tty,
    +static int whiteheat_open(struct tty_struct *tty,
    struct usb_serial_port *port, struct file *filp)
    {
    int retval = 0;
    @@ -635,7 +665,8 @@ static int whiteheat_open (struct tty_struct *tty,
    /* Start reading from the device */
    retval = start_port_read(port);
    if (retval) {
    - err("%s - failed submitting read urb, error %d", __func__, retval);
    + err("%s - failed submitting read urb, error %d",
    + __func__, retval);
    firm_close(port);
    stop_command_port(port->serial);
    goto exit;
    @@ -648,7 +679,7 @@ exit:


    static void whiteheat_close(struct tty_struct *tty,
    - struct usb_serial_port *port, struct file * filp)
    + struct usb_serial_port *port, struct file *filp)
    {
    struct whiteheat_private *info = usb_get_serial_port_data(port);
    struct whiteheat_urb_wrap *wrap;
    @@ -749,16 +780,19 @@ static int whiteheat_write(struct tty_struct *tty,

    wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);
    urb = wrap->urb;
    - bytes = (count > port->bulk_out_size) ? port->bulk_out_size : count;
    - memcpy (urb->transfer_buffer, buf + sent, bytes);
    + bytes = (count > port->bulk_out_size) ?
    + port->bulk_out_size : count;
    + memcpy(urb->transfer_buffer, buf + sent, bytes);

    - usb_serial_debug_data(debug, &port->dev, __func__, bytes, urb->transfer_buffer);
    + usb_serial_debug_data(debug, &port->dev,
    + __func__, bytes, urb->transfer_buffer);

    urb->dev = serial->dev;
    urb->transfer_buffer_length = bytes;
    result = usb_submit_urb(urb, GFP_ATOMIC);
    if (result) {
    - err("%s - failed submitting write urb, error %d", __func__, result);
    + err("%s - failed submitting write urb, error %d",
    + __func__, result);
    sent = result;
    spin_lock_irqsave(&info->lock, flags);
    list_add(tmp, &info->tx_urbs_free);
    @@ -776,7 +810,6 @@ static int whiteheat_write(struct tty_struct *tty,
    return sent;
    }

    -
    static int whiteheat_write_room(struct tty_struct *tty)
    {
    struct usb_serial_port *port = tty->driver_data;
    @@ -786,7 +819,7 @@ static int whiteheat_write_room(struct tty_struct *tty)
    unsigned long flags;

    dbg("%s - port %d", __func__, port->number);
    -
    +
    spin_lock_irqsave(&info->lock, flags);
    list_for_each(tmp, &info->tx_urbs_free)
    room++;
    @@ -797,8 +830,7 @@ static int whiteheat_write_room(struct tty_struct *tty)
    return (room);
    }

    -
    -static int whiteheat_tiocmget (struct tty_struct *tty, struct file *file)
    +static int whiteheat_tiocmget(struct tty_struct *tty, struct file *file)
    {
    struct usb_serial_port *port = tty->driver_data;
    struct whiteheat_private *info = usb_get_serial_port_data(port);
    @@ -815,8 +847,7 @@ static int whiteheat_tiocmget (struct tty_struct *tty, struct file *file)
    return modem_signals;
    }

    -
    -static int whiteheat_tiocmset (struct tty_struct *tty, struct file *file,
    +static int whiteheat_tiocmset(struct tty_struct *tty, struct file *file,
    unsigned int set, unsigned int clear)
    {
    struct usb_serial_port *port = tty->driver_data;
    @@ -840,7 +871,8 @@ static int whiteheat_tiocmset (struct tty_struct *tty, struct file *file,
    }


    -static int whiteheat_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
    +static int whiteheat_ioctl(struct tty_struct *tty, struct file *file,
    + unsigned int cmd, unsigned long arg)
    {
    struct usb_serial_port *port = tty->driver_data;
    struct serial_struct serstruct;
    @@ -849,50 +881,38 @@ static int whiteheat_ioctl (struct tty_struct *tty, struct file * file, unsigned
    dbg("%s - port %d, cmd 0x%.4x", __func__, port->number, cmd);

    switch (cmd) {
    - case TIOCGSERIAL:
    - memset(&serstruct, 0, sizeof(serstruct));
    - serstruct.type = PORT_16654;
    - serstruct.line = port->serial->minor;
    - serstruct.port = port->number;
    - serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
    - serstruct.xmit_fifo_size = port->bulk_out_size;
    - serstruct.custom_divisor = 0;
    - serstruct.baud_base = 460800;
    - serstruct.close_delay = CLOSING_DELAY;
    - serstruct.closing_wait = CLOSING_DELAY;
    -
    - if (copy_to_user(user_arg, &serstruct, sizeof(serstruct)))
    - return -EFAULT;
    -
    - break;
    -
    - case TIOCSSERIAL:
    - if (copy_from_user(&serstruct, user_arg, sizeof(serstruct)))
    - return -EFAULT;
    -
    - /*
    - * For now this is ignored. dip sets the ASYNC_[V]HI flags
    - * but this isn't used by us at all. Maybe someone somewhere
    - * will need the custom_divisor setting.
    - */
    -
    - break;
    -
    - default:
    - break;
    + case TIOCGSERIAL:
    + memset(&serstruct, 0, sizeof(serstruct));
    + serstruct.type = PORT_16654;
    + serstruct.line = port->serial->minor;
    + serstruct.port = port->number;
    + serstruct.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
    + serstruct.xmit_fifo_size = port->bulk_out_size;
    + serstruct.custom_divisor = 0;
    + serstruct.baud_base = 460800;
    + serstruct.close_delay = CLOSING_DELAY;
    + serstruct.closing_wait = CLOSING_DELAY;
    +
    + if (copy_to_user(user_arg, &serstruct, sizeof(serstruct)))
    + return -EFAULT;
    + break;
    + default:
    + break;
    }

    return -ENOIOCTLCMD;
    }


    -static void whiteheat_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios)
    +static void whiteheat_set_termios(struct tty_struct *tty,
    + struct usb_serial_port *port, struct ktermios *old_termios)
    {
    + /* FIXME */
    firm_setup_port(tty);
    }

    -
    -static void whiteheat_break_ctl(struct tty_struct *tty, int break_state) {
    +static void whiteheat_break_ctl(struct tty_struct *tty, int break_state)
    +{
    struct usb_serial_port *port = tty->driver_data;
    firm_set_break(port, break_state);
    }
    @@ -916,12 +936,12 @@ static int whiteheat_chars_in_buffer(struct tty_struct *tty)
    }
    spin_unlock_irqrestore(&info->lock, flags);

    - dbg ("%s - returns %d", __func__, chars);
    + dbg("%s - returns %d", __func__, chars);
    return chars;
    }


    -static void whiteheat_throttle (struct tty_struct *tty)
    +static void whiteheat_throttle(struct tty_struct *tty)
    {
    struct usb_serial_port *port = tty->driver_data;
    struct whiteheat_private *info = usb_get_serial_port_data(port);
    @@ -937,7 +957,7 @@ static void whiteheat_throttle (struct tty_struct *tty)
    }


    -static void whiteheat_unthrottle (struct tty_struct *tty)
    +static void whiteheat_unthrottle(struct tty_struct *tty)
    {
    struct usb_serial_port *port = tty->driver_data;
    struct whiteheat_private *info = usb_get_serial_port_data(port);
    @@ -986,7 +1006,7 @@ static void command_port_read_callback(struct urb *urb)

    command_info = usb_get_serial_port_data(command_port);
    if (!command_info) {
    - dbg ("%s - command_info is NULL, exiting.", __func__);
    + dbg("%s - command_info is NULL, exiting.", __func__);
    return;
    }
    if (status) {
    @@ -997,7 +1017,8 @@ static void command_port_read_callback(struct urb *urb)
    return;
    }

    - usb_serial_debug_data(debug, &command_port->dev, __func__, urb->actual_length, data);
    + usb_serial_debug_data(debug, &command_port->dev,
    + __func__, urb->actual_length, data);

    if (data[0] == WHITEHEAT_CMD_COMPLETE) {
    command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
    @@ -1006,21 +1027,23 @@ static void command_port_read_callback(struct urb *urb)
    command_info->command_finished = WHITEHEAT_CMD_FAILURE;
    wake_up(&command_info->wait_command);
    } else if (data[0] == WHITEHEAT_EVENT) {
    - /* These are unsolicited reports from the firmware, hence no waiting command to wakeup */
    + /* These are unsolicited reports from the firmware, hence no
    + waiting command to wakeup */
    dbg("%s - event received", __func__);
    } else if (data[0] == WHITEHEAT_GET_DTR_RTS) {
    - memcpy(command_info->result_buffer, &data[1], urb->actual_length - 1);
    + memcpy(command_info->result_buffer, &data[1],
    + urb->actual_length - 1);
    command_info->command_finished = WHITEHEAT_CMD_COMPLETE;
    wake_up(&command_info->wait_command);
    - } else {
    + } else
    dbg("%s - bad reply from firmware", __func__);
    - }
    -
    +
    /* Continue trying to always read */
    command_port->read_urb->dev = command_port->serial->dev;
    result = usb_submit_urb(command_port->read_urb, GFP_ATOMIC);
    if (result)
    - dbg("%s - failed resubmitting read urb, error %d", __func__, result);
    + dbg("%s - failed resubmitting read urb, error %d",
    + __func__, result);
    }


    @@ -1053,7 +1076,8 @@ static void whiteheat_read_callback(struct urb *urb)
    return;
    }

    - usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
    + usb_serial_debug_data(debug, &port->dev,
    + __func__, urb->actual_length, data);

    spin_lock(&info->lock);
    list_add_tail(&wrap->list, &info->rx_urb_q);
    @@ -1100,7 +1124,8 @@ static void whiteheat_write_callback(struct urb *urb)
    /************************************************** ***************************
    * Connect Tech's White Heat firmware interface
    ************************************************** ***************************/
    -static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize)
    +static int firm_send_command(struct usb_serial_port *port, __u8 command,
    + __u8 *data, __u8 datasize)
    {
    struct usb_serial_port *command_port;
    struct whiteheat_command_private *command_info;
    @@ -1115,13 +1140,13 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *d
    command_info = usb_get_serial_port_data(command_port);
    mutex_lock(&command_info->mutex);
    command_info->command_finished = false;
    -
    +
    transfer_buffer = (__u8 *)command_port->write_urb->transfer_buffer;
    transfer_buffer[0] = command;
    - memcpy (&transfer_buffer[1], data, datasize);
    + memcpy(&transfer_buffer[1], data, datasize);
    command_port->write_urb->transfer_buffer_length = datasize + 1;
    command_port->write_urb->dev = port->serial->dev;
    - retval = usb_submit_urb (command_port->write_urb, GFP_NOIO);
    + retval = usb_submit_urb(command_port->write_urb, GFP_NOIO);
    if (retval) {
    dbg("%s - submit urb failed", __func__);
    goto exit;
    @@ -1148,36 +1173,41 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *d
    if (command_info->command_finished == WHITEHEAT_CMD_COMPLETE) {
    dbg("%s - command completed.", __func__);
    switch (command) {
    - case WHITEHEAT_GET_DTR_RTS:
    - info = usb_get_serial_port_data(port);
    - memcpy(&info->mcr, command_info->result_buffer, sizeof(struct whiteheat_dr_info));
    + case WHITEHEAT_GET_DTR_RTS:
    + info = usb_get_serial_port_data(port);
    + memcpy(&info->mcr, command_info->result_buffer,
    + sizeof(struct whiteheat_dr_info));
    break;
    }
    }
    -
    exit:
    mutex_unlock(&command_info->mutex);
    return retval;
    }


    -static int firm_open(struct usb_serial_port *port) {
    +static int firm_open(struct usb_serial_port *port)
    +{
    struct whiteheat_simple open_command;

    open_command.port = port->number - port->serial->minor + 1;
    - return firm_send_command(port, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command));
    + return firm_send_command(port, WHITEHEAT_OPEN,
    + (__u8 *)&open_command, sizeof(open_command));
    }


    -static int firm_close(struct usb_serial_port *port) {
    +static int firm_close(struct usb_serial_port *port)
    +{
    struct whiteheat_simple close_command;

    close_command.port = port->number - port->serial->minor + 1;
    - return firm_send_command(port, WHITEHEAT_CLOSE, (__u8 *)&close_command, sizeof(close_command));
    + return firm_send_command(port, WHITEHEAT_CLOSE,
    + (__u8 *)&close_command, sizeof(close_command));
    }


    -static int firm_setup_port(struct tty_struct *tty) {
    +static int firm_setup_port(struct tty_struct *tty)
    +{
    struct usb_serial_port *port = tty->driver_data;
    struct whiteheat_port_settings port_settings;
    unsigned int cflag = tty->termios->c_cflag;
    @@ -1186,14 +1216,14 @@ static int firm_setup_port(struct tty_struct *tty) {

    /* get the byte size */
    switch (cflag & CSIZE) {
    - case CS5: port_settings.bits = 5; break;
    - case CS6: port_settings.bits = 6; break;
    - case CS7: port_settings.bits = 7; break;
    - default:
    - case CS8: port_settings.bits = 8; break;
    + case CS5: port_settings.bits = 5; break;
    + case CS6: port_settings.bits = 6; break;
    + case CS7: port_settings.bits = 7; break;
    + default:
    + case CS8: port_settings.bits = 8; break;
    }
    dbg("%s - data bits = %d", __func__, port_settings.bits);
    -
    +
    /* determine the parity */
    if (cflag & PARENB)
    if (cflag & CMSPAR)
    @@ -1219,7 +1249,8 @@ static int firm_setup_port(struct tty_struct *tty) {

    /* figure out the flow control settings */
    if (cflag & CRTSCTS)
    - port_settings.hflow = (WHITEHEAT_HFLOW_CTS | WHITEHEAT_HFLOW_RTS);
    + port_settings.hflow = (WHITEHEAT_HFLOW_CTS |
    + WHITEHEAT_HFLOW_RTS);
    else
    port_settings.hflow = WHITEHEAT_HFLOW_NONE;
    dbg("%s - hardware flow control = %s %s %s %s", __func__,
    @@ -1227,17 +1258,18 @@ static int firm_setup_port(struct tty_struct *tty) {
    (port_settings.hflow & WHITEHEAT_HFLOW_RTS) ? "RTS" : "",
    (port_settings.hflow & WHITEHEAT_HFLOW_DSR) ? "DSR" : "",
    (port_settings.hflow & WHITEHEAT_HFLOW_DTR) ? "DTR" : "");
    -
    +
    /* determine software flow control */
    if (I_IXOFF(tty))
    port_settings.sflow = WHITEHEAT_SFLOW_RXTX;
    else
    port_settings.sflow = WHITEHEAT_SFLOW_NONE;
    dbg("%s - software flow control = %c", __func__, port_settings.sflow);
    -
    +
    port_settings.xon = START_CHAR(tty);
    port_settings.xoff = STOP_CHAR(tty);
    - dbg("%s - XON = %2x, XOFF = %2x", __func__, port_settings.xon, port_settings.xoff);
    + dbg("%s - XON = %2x, XOFF = %2x",
    + __func__, port_settings.xon, port_settings.xoff);

    /* get the baud rate wanted */
    port_settings.baud = tty_get_baud_rate(tty);
    @@ -1247,61 +1279,74 @@ static int firm_setup_port(struct tty_struct *tty) {
    tty_encode_baud_rate(tty, port_settings.baud, port_settings.baud);
    /* handle any settings that aren't specified in the tty structure */
    port_settings.lloop = 0;
    -
    +
    /* now send the message to the device */
    - return firm_send_command(port, WHITEHEAT_SETUP_PORT, (__u8 *)&port_settings, sizeof(port_settings));
    + return firm_send_command(port, WHITEHEAT_SETUP_PORT,
    + (__u8 *)&port_settings, sizeof(port_settings));
    }


    -static int firm_set_rts(struct usb_serial_port *port, __u8 onoff) {
    +static int firm_set_rts(struct usb_serial_port *port, __u8 onoff)
    +{
    struct whiteheat_set_rdb rts_command;

    rts_command.port = port->number - port->serial->minor + 1;
    rts_command.state = onoff;
    - return firm_send_command(port, WHITEHEAT_SET_RTS, (__u8 *)&rts_command, sizeof(rts_command));
    + return firm_send_command(port, WHITEHEAT_SET_RTS,
    + (__u8 *)&rts_command, sizeof(rts_command));
    }


    -static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff) {
    +static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff)
    +{
    struct whiteheat_set_rdb dtr_command;

    dtr_command.port = port->number - port->serial->minor + 1;
    dtr_command.state = onoff;
    - return firm_send_command(port, WHITEHEAT_SET_RTS, (__u8 *)&dtr_command, sizeof(dtr_command));
    + return firm_send_command(port, WHITEHEAT_SET_RTS,
    + (__u8 *)&dtr_command, sizeof(dtr_command));
    }


    -static int firm_set_break(struct usb_serial_port *port, __u8 onoff) {
    +static int firm_set_break(struct usb_serial_port *port, __u8 onoff)
    +{
    struct whiteheat_set_rdb break_command;

    break_command.port = port->number - port->serial->minor + 1;
    break_command.state = onoff;
    - return firm_send_command(port, WHITEHEAT_SET_RTS, (__u8 *)&break_command, sizeof(break_command));
    + return firm_send_command(port, WHITEHEAT_SET_RTS,
    + (__u8 *)&break_command, sizeof(break_command));
    }


    -static int firm_purge(struct usb_serial_port *port, __u8 rxtx) {
    +static int firm_purge(struct usb_serial_port *port, __u8 rxtx)
    +{
    struct whiteheat_purge purge_command;

    purge_command.port = port->number - port->serial->minor + 1;
    purge_command.what = rxtx;
    - return firm_send_command(port, WHITEHEAT_PURGE, (__u8 *)&purge_command, sizeof(purge_command));
    + return firm_send_command(port, WHITEHEAT_PURGE,
    + (__u8 *)&purge_command, sizeof(purge_command));
    }


    -static int firm_get_dtr_rts(struct usb_serial_port *port) {
    +static int firm_get_dtr_rts(struct usb_serial_port *port)
    +{
    struct whiteheat_simple get_dr_command;

    get_dr_command.port = port->number - port->serial->minor + 1;
    - return firm_send_command(port, WHITEHEAT_GET_DTR_RTS, (__u8 *)&get_dr_command, sizeof(get_dr_command));
    + return firm_send_command(port, WHITEHEAT_GET_DTR_RTS,
    + (__u8 *)&get_dr_command, sizeof(get_dr_command));
    }


    -static int firm_report_tx_done(struct usb_serial_port *port) {
    +static int firm_report_tx_done(struct usb_serial_port *port)
    +{
    struct whiteheat_simple close_command;

    close_command.port = port->number - port->serial->minor + 1;
    - return firm_send_command(port, WHITEHEAT_REPORT_TX_DONE, (__u8 *)&close_command, sizeof(close_command));
    + return firm_send_command(port, WHITEHEAT_REPORT_TX_DONE,
    + (__u8 *)&close_command, sizeof(close_command));
    }


    @@ -1313,7 +1358,7 @@ static int start_command_port(struct usb_serial *serial)
    struct usb_serial_port *command_port;
    struct whiteheat_command_private *command_info;
    int retval = 0;
    -
    +
    command_port = serial->port[COMMAND_PORT];
    command_info = usb_get_serial_port_data(command_port);
    mutex_lock(&command_info->mutex);
    @@ -1324,7 +1369,8 @@ static int start_command_port(struct usb_serial *serial)
    command_port->read_urb->dev = serial->dev;
    retval = usb_submit_urb(command_port->read_urb, GFP_KERNEL);
    if (retval) {
    - err("%s - failed submitting read urb, error %d", __func__, retval);
    + err("%s - failed submitting read urb, error %d",
    + __func__, retval);
    goto exit;
    }
    }
    @@ -1394,7 +1440,8 @@ static int start_port_read(struct usb_serial_port *port)
    }


    -static struct whiteheat_urb_wrap *urb_to_wrap(struct urb* urb, struct list_head *head)
    +static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb,
    + struct list_head *head)
    {
    struct whiteheat_urb_wrap *wrap;
    struct list_head *tmp;
    @@ -1443,7 +1490,8 @@ static void rx_data_softint(struct work_struct *work)
    urb = wrap->urb;

    if (tty && urb->actual_length) {
    - int len = tty_buffer_request_room(tty, urb->actual_length);
    + int len = tty_buffer_request_room(tty,
    + urb->actual_length);
    /* This stuff can go away now I suspect */
    if (unlikely(len < urb->actual_length)) {
    spin_lock_irqsave(&info->lock, flags);
    @@ -1460,7 +1508,8 @@ static void rx_data_softint(struct work_struct *work)
    urb->dev = port->serial->dev;
    result = usb_submit_urb(urb, GFP_ATOMIC);
    if (result) {
    - err("%s - failed resubmitting read urb, error %d", __func__, result);
    + err("%s - failed resubmitting read urb, error %d",
    + __func__, result);
    spin_lock_irqsave(&info->lock, flags);
    list_add(tmp, &info->rx_urbs_free);
    continue;
    @@ -1479,7 +1528,7 @@ static void rx_data_softint(struct work_struct *work)
    /************************************************** ***************************
    * Connect Tech's White Heat module functions
    ************************************************** ***************************/
    -static int __init whiteheat_init (void)
    +static int __init whiteheat_init(void)
    {
    int retval;
    retval = usb_serial_register(&whiteheat_fake_device);
    @@ -1502,19 +1551,19 @@ failed_fake_register:
    }


    -static void __exit whiteheat_exit (void)
    +static void __exit whiteheat_exit(void)
    {
    - usb_deregister (&whiteheat_driver);
    - usb_serial_deregister (&whiteheat_fake_device);
    - usb_serial_deregister (&whiteheat_device);
    + usb_deregister(&whiteheat_driver);
    + usb_serial_deregister(&whiteheat_fake_device);
    + usb_serial_deregister(&whiteheat_device);
    }


    module_init(whiteheat_init);
    module_exit(whiteheat_exit);

    -MODULE_AUTHOR( DRIVER_AUTHOR );
    -MODULE_DESCRIPTION( DRIVER_DESC );
    +MODULE_AUTHOR(DRIVER_AUTHOR);
    +MODULE_DESCRIPTION(DRIVER_DESC);
    MODULE_LICENSE("GPL");

    module_param(urb_pool_size, int, 0);
    diff --git a/drivers/usb/serial/whiteheat.h b/drivers/usb/serial/whiteheat.h
    index f160797..38065df 100644
    --- a/drivers/usb/serial/whiteheat.h
    +++ b/drivers/usb/serial/whiteheat.h
    @@ -2,7 +2,7 @@
    * USB ConnectTech WhiteHEAT driver
    *
    * Copyright (C) 2002
    - * Connect Tech Inc.
    + * Connect Tech Inc.
    *
    * Copyright (C) 1999, 2000
    * Greg Kroah-Hartman (greg@kroah.com)
    @@ -12,7 +12,8 @@
    * the Free Software Foundation; either version 2 of the License, or
    * (at your option) any later version.
    *
    - * See Documentation/usb/usb-serial.txt for more information on using this driver
    + * See Documentation/usb/usb-serial.txt for more information on using this
    + * driver
    *
    */

    @@ -30,13 +31,16 @@
    #define WHITEHEAT_DUMP 7 /* dump memory */
    #define WHITEHEAT_STATUS 8 /* get status */
    #define WHITEHEAT_PURGE 9 /* clear the UART fifos */
    -#define WHITEHEAT_GET_DTR_RTS 10 /* get the state of DTR and RTS for a port */
    -#define WHITEHEAT_GET_HW_INFO 11 /* get EEPROM info and hardware ID */
    +#define WHITEHEAT_GET_DTR_RTS 10 /* get the state of DTR and RTS
    + for a port */
    +#define WHITEHEAT_GET_HW_INFO 11 /* get EEPROM info and
    + hardware ID */
    #define WHITEHEAT_REPORT_TX_DONE 12 /* get the next TX done */
    #define WHITEHEAT_EVENT 13 /* unsolicited status events */
    -#define WHITEHEAT_ECHO 14 /* send data to the indicated IN endpoint */
    -#define WHITEHEAT_DO_TEST 15 /* perform the specified test */
    -#define WHITEHEAT_CMD_COMPLETE 16 /* reply for certain commands */
    +#define WHITEHEAT_ECHO 14 /* send data to the indicated
    + IN endpoint */
    +#define WHITEHEAT_DO_TEST 15 /* perform specified test */
    +#define WHITEHEAT_CMD_COMPLETE 16 /* reply for some commands */
    #define WHITEHEAT_CMD_FAILURE 17 /* reply for failed commands */


    @@ -67,20 +71,28 @@ struct whiteheat_simple {
    #define WHITEHEAT_PAR_MARK '1' /* mark (force 1) parity */

    #define WHITEHEAT_SFLOW_NONE 'n' /* no software flow control */
    -#define WHITEHEAT_SFLOW_RX 'r' /* XOFF/ON is sent when RX fills/empties */
    -#define WHITEHEAT_SFLOW_TX 't' /* when received XOFF/ON will stop/start TX */
    +#define WHITEHEAT_SFLOW_RX 'r' /* XOFF/ON is sent when RX
    + fills/empties */
    +#define WHITEHEAT_SFLOW_TX 't' /* when received XOFF/ON will
    + stop/start TX */
    #define WHITEHEAT_SFLOW_RXTX 'b' /* both SFLOW_RX and SFLOW_TX */

    #define WHITEHEAT_HFLOW_NONE 0x00 /* no hardware flow control */
    -#define WHITEHEAT_HFLOW_RTS_TOGGLE 0x01 /* RTS is on during transmit, off otherwise */
    -#define WHITEHEAT_HFLOW_DTR 0x02 /* DTR is off/on when RX fills/empties */
    -#define WHITEHEAT_HFLOW_CTS 0x08 /* when received CTS off/on will stop/start TX */
    -#define WHITEHEAT_HFLOW_DSR 0x10 /* when received DSR off/on will stop/start TX */
    -#define WHITEHEAT_HFLOW_RTS 0x80 /* RTS is off/on when RX fills/empties */
    +#define WHITEHEAT_HFLOW_RTS_TOGGLE 0x01 /* RTS is on during transmit,
    + off otherwise */
    +#define WHITEHEAT_HFLOW_DTR 0x02 /* DTR is off/on when RX
    + fills/empties */
    +#define WHITEHEAT_HFLOW_CTS 0x08 /* when received CTS off/on
    + will stop/start TX */
    +#define WHITEHEAT_HFLOW_DSR 0x10 /* when received DSR off/on
    + will stop/start TX */
    +#define WHITEHEAT_HFLOW_RTS 0x80 /* RTS is off/on when RX
    + fills/empties */

    struct whiteheat_port_settings {
    __u8 port; /* port number (1 to N) */
    - __u32 baud; /* any value 7 - 460800, firmware calculates best fit; arrives little endian */
    + __u32 baud; /* any value 7 - 460800, firmware calculates
    + best fit; arrives little endian */
    __u8 bits; /* 5, 6, 7, or 8 */
    __u8 stop; /* 1 or 2, default 1 (2 = 1.5 if bits = 5) */
    __u8 parity; /* see WHITEHEAT_PAR_* above */
    @@ -167,12 +179,14 @@ struct whiteheat_echo {
    */
    #define WHITEHEAT_TEST_UART_RW 0x01 /* read/write uart registers */
    #define WHITEHEAT_TEST_UART_INTR 0x02 /* uart interrupt */
    -#define WHITEHEAT_TEST_SETUP_CONT 0x03 /* setup for PORT_CONT/PORT_DISCONT */
    +#define WHITEHEAT_TEST_SETUP_CONT 0x03 /* setup for
    + PORT_CONT/PORT_DISCONT */
    #define WHITEHEAT_TEST_PORT_CONT 0x04 /* port connect */
    #define WHITEHEAT_TEST_PORT_DISCONT 0x05 /* port disconnect */
    #define WHITEHEAT_TEST_UART_CLK_START 0x06 /* uart clock test start */
    #define WHITEHEAT_TEST_UART_CLK_STOP 0x07 /* uart clock test stop */
    -#define WHITEHEAT_TEST_MODEM_FT 0x08 /* modem signals, requires a loopback cable/connector */
    +#define WHITEHEAT_TEST_MODEM_FT 0x08 /* modem signals, requires a
    + loopback cable/connector */
    #define WHITEHEAT_TEST_ERASE_EEPROM 0x09 /* erase eeprom */
    #define WHITEHEAT_TEST_READ_EEPROM 0x0a /* read eeprom */
    #define WHITEHEAT_TEST_PROGRAM_EEPROM 0x0b /* program eeprom */
    @@ -198,19 +212,27 @@ struct whiteheat_test {
    #define WHITEHEAT_EVENT_CONNECT 0x08 /* connect field is valid */

    #define WHITEHEAT_FLOW_NONE 0x00 /* no flow control active */
    -#define WHITEHEAT_FLOW_HARD_OUT 0x01 /* TX is stopped by CTS (waiting for CTS to go on) */
    -#define WHITEHEAT_FLOW_HARD_IN 0x02 /* remote TX is stopped by RTS */
    -#define WHITEHEAT_FLOW_SOFT_OUT 0x04 /* TX is stopped by XOFF received (waiting for XON) */
    -#define WHITEHEAT_FLOW_SOFT_IN 0x08 /* remote TX is stopped by XOFF transmitted */
    +#define WHITEHEAT_FLOW_HARD_OUT 0x01 /* TX is stopped by CTS
    + (waiting for CTS to go on) */
    +#define WHITEHEAT_FLOW_HARD_IN 0x02 /* remote TX is stopped
    + by RTS */
    +#define WHITEHEAT_FLOW_SOFT_OUT 0x04 /* TX is stopped by XOFF
    + received (waiting for XON) */
    +#define WHITEHEAT_FLOW_SOFT_IN 0x08 /* remote TX is stopped by XOFF
    + transmitted */
    #define WHITEHEAT_FLOW_TX_DONE 0x80 /* TX has completed */

    struct whiteheat_status_info {
    __u8 port; /* port number (1 to N) */
    - __u8 event; /* indicates what the current event is, see WHITEHEAT_EVENT_* above */
    - __u8 modem; /* modem signal status (copy of uart's MSR register) */
    + __u8 event; /* indicates what the current event is,
    + see WHITEHEAT_EVENT_* above */
    + __u8 modem; /* modem signal status (copy of uart's
    + MSR register) */
    __u8 error; /* line status (copy of uart's LSR register) */
    - __u8 flow; /* flow control state, see WHITEHEAT_FLOW_* above */
    - __u8 connect; /* 0 means not connected, non-zero means connected */
    + __u8 flow; /* flow control state, see WHITEHEAT_FLOW_*
    + above */
    + __u8 connect; /* 0 means not connected, non-zero means
    + connected */
    };


    @@ -256,7 +278,8 @@ struct whiteheat_hw_info {
    struct whiteheat_event_info {
    __u8 port; /* port number (1 to N) */
    __u8 event; /* see whiteheat_status_info.event */
    - __u8 info; /* see whiteheat_status_info.modem, .error, .flow, .connect */
    + __u8 info; /* see whiteheat_status_info.modem, .error,
    + .flow, .connect */
    };


    @@ -269,7 +292,8 @@ struct whiteheat_event_info {

    struct whiteheat_test_info {
    __u8 port; /* port number (1 to N) */
    - __u8 test; /* indicates which test this is a response for, see WHITEHEAT_DO_TEST above */
    + __u8 test; /* indicates which test this is a response for,
    + see WHITEHEAT_DO_TEST above */
    __u8 status; /* see WHITEHEAT_TEST_* above */
    __u8 results[32]; /* test-dependent results */
    };

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  15. [PATCH 29/70] tty-usb-console: Fix termios

    From: Alan Cox

    Setting CFLAG bits is all well and good but you must sort out ispeed and
    ospeed properly.

    Signed-off-by: Alan Cox
    ---

    drivers/usb/serial/console.c | 37 +++++--------------------------------
    1 files changed, 5 insertions(+), 32 deletions(-)


    diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
    index 9a4cd0a..7b74238 100644
    --- a/drivers/usb/serial/console.c
    +++ b/drivers/usb/serial/console.c
    @@ -81,39 +81,11 @@ static int usb_console_setup(struct console *co, char *options)
    if (*s)
    doflow = (*s++ == 'r');
    }
    +
    + /* Sane default */
    + if (baud == 0)
    + baud = 9600;

    - /* build a cflag setting */
    - switch (baud) {
    - case 1200:
    - cflag |= B1200;
    - break;
    - case 2400:
    - cflag |= B2400;
    - break;
    - case 4800:
    - cflag |= B4800;
    - break;
    - case 19200:
    - cflag |= B19200;
    - break;
    - case 38400:
    - cflag |= B38400;
    - break;
    - case 57600:
    - cflag |= B57600;
    - break;
    - case 115200:
    - cflag |= B115200;
    - break;
    - case 9600:
    - default:
    - cflag |= B9600;
    - /*
    - * Set this to a sane value to prevent a divide error
    - */
    - baud = 9600;
    - break;
    - }
    switch (bits) {
    case 7:
    cflag |= CS7;
    @@ -188,6 +160,7 @@ static int usb_console_setup(struct console *co, char *options)

    if (serial->type->set_termios) {
    termios->c_cflag = cflag;
    + tty_termios_encode_baud_rate(termios, baud, baud);
    serial->type->set_termios(NULL, port, &dummy);

    port->port.tty = NULL;

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  16. [PATCH 26/70] belkin_sa: clean up code

    From: Alan Cox

    Coding style tidy up for belkin_sa

    Signed-off-by: Alan Cox
    ---

    drivers/usb/serial/belkin_sa.c | 148 +++++++++++++++++++++++-----------------
    drivers/usb/serial/belkin_sa.h | 15 ++--
    2 files changed, 94 insertions(+), 69 deletions(-)


    diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
    index 1a76269..2ebe06c 100644
    --- a/drivers/usb/serial/belkin_sa.c
    +++ b/drivers/usb/serial/belkin_sa.c
    @@ -7,13 +7,14 @@
    * This program is largely derived from work by the linux-usb group
    * and associated source files. Please see the usb/serial files for
    * individual credits and copyrights.
    - *
    + *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    * the Free Software Foundation; either version 2 of the License, or
    * (at your option) any later version.
    *
    - * See Documentation/usb/usb-serial.txt for more information on using this driver
    + * See Documentation/usb/usb-serial.txt for more information on using this
    + * driver
    *
    * TODO:
    * -- Add true modem contol line query capability. Currently we track the
    @@ -28,7 +29,8 @@
    * compressed all the differnent device entries into 1.
    *
    * 30-May-2001 gkh
    - * switched from using spinlock to a semaphore, which fixes lots of problems.
    + * switched from using spinlock to a semaphore, which fixes lots of
    + * problems.
    *
    * 08-Apr-2001 gb
    * - Identify version on module load.
    @@ -41,7 +43,7 @@
    * - Added support for the old Belkin and Peracom devices.
    * - Made the port able to be opened multiple times.
    * - Added some defaults incase the line settings are things these devices
    - * can't support.
    + * can't support.
    *
    * 18-Oct-2000 William Greathouse
    * Released into the wild (linux-usb-devel)
    @@ -72,7 +74,7 @@
    #include
    #include
    #include
    -#include
    +#include
    #include
    #include
    #include "belkin_sa.h"
    @@ -87,15 +89,19 @@ static int debug;
    #define DRIVER_DESC "USB Belkin Serial converter driver"

    /* function prototypes for a Belkin USB Serial Adapter F5U103 */
    -static int belkin_sa_startup (struct usb_serial *serial);
    -static void belkin_sa_shutdown (struct usb_serial *serial);
    -static int belkin_sa_open (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
    -static void belkin_sa_close (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp);
    -static void belkin_sa_read_int_callback (struct urb *urb);
    -static void belkin_sa_set_termios (struct tty_struct *tty, struct usb_serial_port *port, struct ktermios * old);
    -static void belkin_sa_break_ctl (struct tty_struct *tty, int break_state );
    -static int belkin_sa_tiocmget (struct tty_struct *tty, struct file *file);
    -static int belkin_sa_tiocmset (struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear);
    +static int belkin_sa_startup(struct usb_serial *serial);
    +static void belkin_sa_shutdown(struct usb_serial *serial);
    +static int belkin_sa_open(struct tty_struct *tty,
    + struct usb_serial_port *port, struct file *filp);
    +static void belkin_sa_close(struct tty_struct *tty,
    + struct usb_serial_port *port, struct file *filp);
    +static void belkin_sa_read_int_callback(struct urb *urb);
    +static void belkin_sa_set_termios(struct tty_struct *tty,
    + struct usb_serial_port *port, struct ktermios * old);
    +static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state);
    +static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file);
    +static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file,
    + unsigned int set, unsigned int clear);


    static struct usb_device_id id_table_combined [] = {
    @@ -105,10 +111,10 @@ static struct usb_device_id id_table_combined [] = {
    { USB_DEVICE(GOHUBS_VID, GOHUBS_PID) },
    { USB_DEVICE(GOHUBS_VID, HANDYLINK_PID) },
    { USB_DEVICE(BELKIN_DOCKSTATION_VID, BELKIN_DOCKSTATION_PID) },
    - { } /* Terminating entry */
    + { } /* Terminating entry */
    };

    -MODULE_DEVICE_TABLE (usb, id_table_combined);
    +MODULE_DEVICE_TABLE(usb, id_table_combined);

    static struct usb_driver belkin_driver = {
    .name = "belkin",
    @@ -130,7 +136,8 @@ static struct usb_serial_driver belkin_device = {
    .num_ports = 1,
    .open = belkin_sa_open,
    .close = belkin_sa_close,
    - .read_int_callback = belkin_sa_read_int_callback, /* How we get the status info */
    + .read_int_callback = belkin_sa_read_int_callback,
    + /* How we get the status info */
    .set_termios = belkin_sa_set_termios,
    .break_ctl = belkin_sa_break_ctl,
    .tiocmget = belkin_sa_tiocmget,
    @@ -158,12 +165,12 @@ struct belkin_sa_private {
    #define WDR_TIMEOUT 5000 /* default urb timeout */

    /* assumes that struct usb_serial *serial is available */
    -#define BSA_USB_CMD(c,v) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), \
    +#define BSA_USB_CMD(c, v) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), \
    (c), BELKIN_SA_SET_REQUEST_TYPE, \
    (v), 0, NULL, 0, WDR_TIMEOUT)

    /* do some startup allocations not currently performed by usb_serial_probe() */
    -static int belkin_sa_startup (struct usb_serial *serial)
    +static int belkin_sa_startup(struct usb_serial *serial)
    {
    struct usb_device *dev = serial->dev;
    struct belkin_sa_private *priv;
    @@ -171,20 +178,23 @@ static int belkin_sa_startup (struct usb_serial *serial)
    /* allocate the private data structure */
    priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL);
    if (!priv)
    - return (-1); /* error */
    + return -1; /* error */
    /* set initial values for control structures */
    spin_lock_init(&priv->lock);
    priv->control_state = 0;
    priv->last_lsr = 0;
    priv->last_msr = 0;
    /* see comments at top of file */
    - priv->bad_flow_control = (le16_to_cpu(dev->descriptor.bcdDevice) <= 0x0206) ? 1 : 0;
    - info("bcdDevice: %04x, bfc: %d", le16_to_cpu(dev->descriptor.bcdDevice), priv->bad_flow_control);
    + priv->bad_flow_control =
    + (le16_to_cpu(dev->descriptor.bcdDevice) <= 0x0206) ? 1 : 0;
    + info("bcdDevice: %04x, bfc: %d",
    + le16_to_cpu(dev->descriptor.bcdDevice),
    + priv->bad_flow_control);

    init_waitqueue_head(&serial->port[0]->write_wait);
    usb_set_serial_port_data(serial->port[0], priv);
    -
    - return (0);
    +
    + return 0;
    }


    @@ -192,11 +202,11 @@ static void belkin_sa_shutdown(struct usb_serial *serial)
    {
    struct belkin_sa_private *priv;
    int i;
    -
    - dbg ("%s", __func__);
    +
    + dbg("%s", __func__);

    /* stop reads and writes on all ports */
    - for (i=0; i < serial->num_ports; ++i) {
    + for (i = 0; i < serial->num_ports; ++i) {
    /* My special items, the standard routines free my urbs */
    priv = usb_get_serial_port_data(serial->port[i]);
    kfree(priv);
    @@ -204,7 +214,8 @@ static void belkin_sa_shutdown(struct usb_serial *serial)
    }


    -static int belkin_sa_open(struct tty_struct *tty, struct usb_serial_port *port, struct file *filp)
    +static int belkin_sa_open(struct tty_struct *tty,
    + struct usb_serial_port *port, struct file *filp)
    {
    int retval = 0;

    @@ -233,7 +244,7 @@ exit:
    } /* belkin_sa_open */


    -static void belkin_sa_close (struct tty_struct *tty,
    +static void belkin_sa_close(struct tty_struct *tty,
    struct usb_serial_port *port, struct file *filp)
    {
    dbg("%s port %d", __func__, port->number);
    @@ -271,7 +282,8 @@ static void belkin_sa_read_int_callback(struct urb *urb)
    goto exit;
    }

    - usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, data);
    + usb_serial_debug_data(debug, &port->dev, __func__,
    + urb->actual_length, data);

    /* Handle known interrupt data */
    /* ignore data[0] and data[1] */
    @@ -279,7 +291,7 @@ static void belkin_sa_read_int_callback(struct urb *urb)
    priv = usb_get_serial_port_data(port);
    spin_lock_irqsave(&priv->lock, flags);
    priv->last_msr = data[BELKIN_SA_MSR_INDEX];
    -
    +
    /* Record Control Line states */
    if (priv->last_msr & BELKIN_SA_MSR_DSR)
    priv->control_state |= TIOCM_DSR;
    @@ -327,9 +339,9 @@ static void belkin_sa_read_int_callback(struct urb *urb)
    #endif
    spin_unlock_irqrestore(&priv->lock, flags);
    exit:
    - retval = usb_submit_urb (urb, GFP_ATOMIC);
    + retval = usb_submit_urb(urb, GFP_ATOMIC);
    if (retval)
    - err ("%s - usb_submit_urb failed with result %d",
    + err("%s - usb_submit_urb failed with result %d",
    __func__, retval);
    }

    @@ -348,7 +360,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty,
    int bad_flow_control;
    speed_t baud;
    struct ktermios *termios = tty->termios;
    -
    +
    iflag = termios->c_iflag;
    cflag = termios->c_cflag;

    @@ -359,20 +371,21 @@ static void belkin_sa_set_termios(struct tty_struct *tty,
    control_state = priv->control_state;
    bad_flow_control = priv->bad_flow_control;
    spin_unlock_irqrestore(&priv->lock, flags);
    -
    +
    old_iflag = old_termios->c_iflag;
    old_cflag = old_termios->c_cflag;

    /* Set the baud rate */
    if ((cflag & CBAUD) != (old_cflag & CBAUD)) {
    /* reassert DTR and (maybe) RTS on transition from B0 */
    - if( (old_cflag&CBAUD) == B0 ) {
    + if ((old_cflag & CBAUD) == B0) {
    control_state |= (TIOCM_DTR|TIOCM_RTS);
    if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0)
    err("Set DTR error");
    /* don't set RTS if using hardware flow control */
    if (!(old_cflag & CRTSCTS))
    - if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 1) < 0)
    + if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST
    + , 1) < 0)
    err("Set RTS error");
    }
    }
    @@ -392,7 +405,8 @@ static void belkin_sa_set_termios(struct tty_struct *tty,
    err("Set baudrate error");
    } else {
    /* Disable flow control */
    - if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, BELKIN_SA_FLOW_NONE) < 0)
    + if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST,
    + BELKIN_SA_FLOW_NONE) < 0)
    err("Disable flowcontrol error");
    /* Drop RTS and DTR */
    control_state &= ~(TIOCM_DTR | TIOCM_RTS);
    @@ -403,9 +417,10 @@ static void belkin_sa_set_termios(struct tty_struct *tty,
    }

    /* set the parity */
    - if( (cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD)) ) {
    + if ((cflag ^ old_cflag) & (PARENB | PARODD)) {
    if (cflag & PARENB)
    - urb_value = (cflag & PARODD) ? BELKIN_SA_PARITY_ODD : BELKIN_SA_PARITY_EVEN;
    + urb_value = (cflag & PARODD) ? BELKIN_SA_PARITY_ODD
    + : BELKIN_SA_PARITY_EVEN;
    else
    urb_value = BELKIN_SA_PARITY_NONE;
    if (BSA_USB_CMD(BELKIN_SA_SET_PARITY_REQUEST, urb_value) < 0)
    @@ -413,31 +428,40 @@ static void belkin_sa_set_termios(struct tty_struct *tty,
    }

    /* set the number of data bits */
    - if( (cflag&CSIZE) != (old_cflag&CSIZE) ) {
    + if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
    switch (cflag & CSIZE) {
    - case CS5: urb_value = BELKIN_SA_DATA_BITS(5); break;
    - case CS6: urb_value = BELKIN_SA_DATA_BITS(6); break;
    - case CS7: urb_value = BELKIN_SA_DATA_BITS(7); break;
    - case CS8: urb_value = BELKIN_SA_DATA_BITS(8); break;
    - default: dbg("CSIZE was not CS5-CS8, using default of 8");
    - urb_value = BELKIN_SA_DATA_BITS(8);
    - break;
    + case CS5:
    + urb_value = BELKIN_SA_DATA_BITS(5);
    + break;
    + case CS6:
    + urb_value = BELKIN_SA_DATA_BITS(6);
    + break;
    + case CS7:
    + urb_value = BELKIN_SA_DATA_BITS(7);
    + break;
    + case CS8:
    + urb_value = BELKIN_SA_DATA_BITS(8);
    + break;
    + default: dbg("CSIZE was not CS5-CS8, using default of 8");
    + urb_value = BELKIN_SA_DATA_BITS(8);
    + break;
    }
    if (BSA_USB_CMD(BELKIN_SA_SET_DATA_BITS_REQUEST, urb_value) < 0)
    err("Set data bits error");
    }

    /* set the number of stop bits */
    - if( (cflag&CSTOPB) != (old_cflag&CSTOPB) ) {
    - urb_value = (cflag & CSTOPB) ? BELKIN_SA_STOP_BITS(2) : BELKIN_SA_STOP_BITS(1);
    - if (BSA_USB_CMD(BELKIN_SA_SET_STOP_BITS_REQUEST, urb_value) < 0)
    + if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) {
    + urb_value = (cflag & CSTOPB) ? BELKIN_SA_STOP_BITS(2)
    + : BELKIN_SA_STOP_BITS(1);
    + if (BSA_USB_CMD(BELKIN_SA_SET_STOP_BITS_REQUEST,
    + urb_value) < 0)
    err("Set stop bits error");
    }

    /* Set flow control */
    - if( (iflag&IXOFF) != (old_iflag&IXOFF)
    - || (iflag&IXON) != (old_iflag&IXON)
    - || (cflag&CRTSCTS) != (old_cflag&CRTSCTS) ) {
    + if (((iflag ^ old_iflag) & (IXOFF | IXON)) ||
    + ((cflag ^ old_cflag) & CRTSCTS)) {
    urb_value = 0;
    if ((iflag & IXOFF) || (iflag & IXON))
    urb_value |= (BELKIN_SA_FLOW_OXON | BELKIN_SA_FLOW_IXON);
    @@ -479,7 +503,7 @@ static int belkin_sa_tiocmget(struct tty_struct *tty, struct file *file)
    struct belkin_sa_private *priv = usb_get_serial_port_data(port);
    unsigned long control_state;
    unsigned long flags;
    -
    +
    dbg("%s", __func__);

    spin_lock_irqsave(&priv->lock, flags);
    @@ -501,7 +525,7 @@ static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file,
    int retval;
    int rts = 0;
    int dtr = 0;
    -
    +
    dbg("%s", __func__);

    spin_lock_irqsave(&priv->lock, flags);
    @@ -563,17 +587,17 @@ failed_usb_serial_register:

    static void __exit belkin_sa_exit (void)
    {
    - usb_deregister (&belkin_driver);
    + usb_deregister(&belkin_driver);
    usb_serial_deregister(&belkin_device);
    }


    -module_init (belkin_sa_init);
    -module_exit (belkin_sa_exit);
    +module_init(belkin_sa_init);
    +module_exit(belkin_sa_exit);

    -MODULE_AUTHOR( DRIVER_AUTHOR );
    -MODULE_DESCRIPTION( DRIVER_DESC );
    -MODULE_VERSION( DRIVER_VERSION );
    +MODULE_AUTHOR(DRIVER_AUTHOR);
    +MODULE_DESCRIPTION(DRIVER_DESC);
    +MODULE_VERSION(DRIVER_VERSION);
    MODULE_LICENSE("GPL");

    module_param(debug, bool, S_IRUGO | S_IWUSR);
    diff --git a/drivers/usb/serial/belkin_sa.h b/drivers/usb/serial/belkin_sa.h
    index 9116b92..c66a673 100644
    --- a/drivers/usb/serial/belkin_sa.h
    +++ b/drivers/usb/serial/belkin_sa.h
    @@ -7,13 +7,14 @@
    * This program is largely derived from work by the linux-usb group
    * and associated source files. Please see the usb/serial files for
    * individual credits and copyrights.
    - *
    + *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License as published by
    * the Free Software Foundation; either version 2 of the License, or
    * (at your option) any later version.
    *
    - * See Documentation/usb/usb-serial.txt for more information on using this driver
    + * See Documentation/usb/usb-serial.txt for more information on using this
    + * driver
    *
    * 12-Mar-2001 gkh
    * Added GoHubs GO-COM232 device id.
    @@ -27,7 +28,7 @@
    * adapter, so pardon any stupid mistakes. All of the information
    * I am using to write this driver was acquired by using a modified
    * UsbSnoop on Windows2000.
    - *
    + *
    */

    #ifndef __LINUX_USB_SERIAL_BSA_H
    @@ -96,20 +97,20 @@

    /*
    * It seems that the interrupt pipe is closely modelled after the
    - * 16550 register layout. This is probably because the adapter can
    + * 16550 register layout. This is probably because the adapter can
    * be used in a "DOS" environment to simulate a standard hardware port.
    */
    -#define BELKIN_SA_LSR_INDEX 2 /* Line Status Register */
    +#define BELKIN_SA_LSR_INDEX 2 /* Line Status Register */
    #define BELKIN_SA_LSR_RDR 0x01 /* receive data ready */
    #define BELKIN_SA_LSR_OE 0x02 /* overrun error */
    #define BELKIN_SA_LSR_PE 0x04 /* parity error */
    #define BELKIN_SA_LSR_FE 0x08 /* framing error */
    #define BELKIN_SA_LSR_BI 0x10 /* break indicator */
    -#define BELKIN_SA_LSR_THE 0x20 /* transmit holding register empty */
    +#define BELKIN_SA_LSR_THE 0x20 /* tx holding register empty */
    #define BELKIN_SA_LSR_TE 0x40 /* transmit register empty */
    #define BELKIN_SA_LSR_ERR 0x80 /* OE | PE | FE | BI */

    -#define BELKIN_SA_MSR_INDEX 3 /* Modem Status Register */
    +#define BELKIN_SA_MSR_INDEX 3 /* Modem Status Register */
    #define BELKIN_SA_MSR_DCTS 0x01 /* Delta CTS */
    #define BELKIN_SA_MSR_DDSR 0x02 /* Delta DSR */
    #define BELKIN_SA_MSR_DRI 0x04 /* Delta RI */

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  17. [PATCH 13/70] moxa: use tty_port

    From: Alan Cox

    Switch MOXA to use the new tty_port structure

    Signed-off-by: Alan Cox
    ---

    drivers/char/moxa.c | 87 +++++++++++++++++++++++++--------------------------
    1 files changed, 42 insertions(+), 45 deletions(-)


    diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
    index d57d3a6..bb9bcff 100644
    --- a/drivers/char/moxa.c
    +++ b/drivers/char/moxa.c
    @@ -130,17 +130,14 @@ struct moxaq_str {
    };

    struct moxa_port {
    + struct tty_port port;
    struct moxa_board_conf *board;
    - struct tty_struct *tty;
    void __iomem *tableAddr;

    int type;
    int close_delay;
    - unsigned int count;
    - int asyncflags;
    int cflag;
    unsigned long statusflags;
    - wait_queue_head_t open_wait;

    u8 DCDState;
    u8 lineCtrl;
    @@ -348,10 +345,10 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
    if (status & 4)
    tmp.dcd = 1;

    - if (!p->tty || !p->tty->termios)
    + if (!p->port.tty || !p->port.tty->termios)
    tmp.cflag = p->cflag;
    else
    - tmp.cflag = p->tty->termios->c_cflag;
    + tmp.cflag = p->port.tty->termios->c_cflag;
    copy:
    if (copy_to_user(argm, &tmp, sizeof(tmp))) {
    mutex_unlock(&moxa_openlock);
    @@ -828,7 +825,7 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
    p->type = PORT_16550A;
    p->close_delay = 5 * HZ / 10;
    p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
    - init_waitqueue_head(&p->open_wait);
    + tty_port_init(&p->port);
    }

    switch (brd->boardType) {
    @@ -884,12 +881,12 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)

    /* pci hot-un-plug support */
    for (a = 0; a < brd->numPorts; a++)
    - if (brd->ports[a].asyncflags & ASYNC_INITIALIZED)
    - tty_hangup(brd->ports[a].tty);
    + if (brd->ports[a].port.flags & ASYNC_INITIALIZED)
    + tty_hangup(brd->ports[a].port.tty);
    while (1) {
    opened = 0;
    for (a = 0; a < brd->numPorts; a++)
    - if (brd->ports[a].asyncflags & ASYNC_INITIALIZED)
    + if (brd->ports[a].port.flags & ASYNC_INITIALIZED)
    opened++;
    mutex_unlock(&moxa_openlock);
    if (!opened)
    @@ -1104,9 +1101,9 @@ static void moxa_close_port(struct moxa_port *ch)
    {
    moxa_shut_down(ch);
    MoxaPortFlushData(ch, 2);
    - ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
    - ch->tty->driver_data = NULL;
    - ch->tty = NULL;
    + ch->port.flags &= ~ASYNC_NORMAL_ACTIVE;
    + ch->port.tty->driver_data = NULL;
    + ch->port.tty = NULL;
    }

    static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
    @@ -1117,7 +1114,7 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
    u8 dcd;

    while (1) {
    - prepare_to_wait(&ch->open_wait, &wait, TASK_INTERRUPTIBLE);
    + prepare_to_wait(&ch->port.open_wait, &wait, TASK_INTERRUPTIBLE);
    if (tty_hung_up_p(filp)) {
    #ifdef SERIAL_DO_RESTART
    retval = -ERESTARTSYS;
    @@ -1138,7 +1135,7 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
    }
    schedule();
    }
    - finish_wait(&ch->open_wait, &wait);
    + finish_wait(&ch->port.open_wait, &wait);

    return retval;
    }
    @@ -1163,16 +1160,16 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
    }

    ch = &brd->ports[port % MAX_PORTS_PER_BOARD];
    - ch->count++;
    + ch->port.count++;
    tty->driver_data = ch;
    - ch->tty = tty;
    - if (!(ch->asyncflags & ASYNC_INITIALIZED)) {
    + ch->port.tty = tty;
    + if (!(ch->port.flags & ASYNC_INITIALIZED)) {
    ch->statusflags = 0;
    moxa_set_tty_param(tty, tty->termios);
    MoxaPortLineCtrl(ch, 1, 1);
    MoxaPortEnable(ch);
    MoxaSetFifo(ch, ch->type == PORT_16550A);
    - ch->asyncflags |= ASYNC_INITIALIZED;
    + ch->port.flags |= ASYNC_INITIALIZED;
    }
    mutex_unlock(&moxa_openlock);

    @@ -1181,11 +1178,11 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
    retval = moxa_block_till_ready(tty, filp, ch);
    mutex_lock(&moxa_openlock);
    if (retval) {
    - if (ch->count) /* 0 means already hung up... */
    - if (--ch->count == 0)
    + if (ch->port.count) /* 0 means already hung up... */
    + if (--ch->port.count == 0)
    moxa_close_port(ch);
    } else
    - ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
    + ch->port.flags |= ASYNC_NORMAL_ACTIVE;
    mutex_unlock(&moxa_openlock);

    return retval;
    @@ -1204,21 +1201,21 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
    ch = tty->driver_data;
    if (ch == NULL)
    goto unlock;
    - if (tty->count == 1 && ch->count != 1) {
    + if (tty->count == 1 && ch->port.count != 1) {
    printk(KERN_WARNING "moxa_close: bad serial port count; "
    - "tty->count is 1, ch->count is %d\n", ch->count);
    - ch->count = 1;
    + "tty->count is 1, ch->port.count is %d\n", ch->port.count);
    + ch->port.count = 1;
    }
    - if (--ch->count < 0) {
    + if (--ch->port.count < 0) {
    printk(KERN_WARNING "moxa_close: bad serial port count, "
    "device=%s\n", tty->name);
    - ch->count = 0;
    + ch->port.count = 0;
    }
    - if (ch->count)
    + if (ch->port.count)
    goto unlock;

    ch->cflag = tty->termios->c_cflag;
    - if (ch->asyncflags & ASYNC_INITIALIZED) {
    + if (ch->port.flags & ASYNC_INITIALIZED) {
    moxa_setup_empty_event(tty);
    tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
    }
    @@ -1374,7 +1371,7 @@ static void moxa_set_termios(struct tty_struct *tty,
    return;
    moxa_set_tty_param(tty, old_termios);
    if (!(old_termios->c_cflag & CLOCAL) && C_CLOCAL(tty))
    - wake_up_interruptible(&ch->open_wait);
    + wake_up_interruptible(&ch->port.open_wait);
    }

    static void moxa_stop(struct tty_struct *tty)
    @@ -1412,20 +1409,20 @@ static void moxa_hangup(struct tty_struct *tty)
    mutex_unlock(&moxa_openlock);
    return;
    }
    - ch->count = 0;
    + ch->port.count = 0;
    moxa_close_port(ch);
    mutex_unlock(&moxa_openlock);

    - wake_up_interruptible(&ch->open_wait);
    + wake_up_interruptible(&ch->port.open_wait);
    }

    static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
    {
    dcd = !!dcd;

    - if (dcd != p->DCDState && p->tty && C_CLOCAL(p->tty)) {
    + if (dcd != p->DCDState && p->port.tty && C_CLOCAL(p->port.tty)) {
    if (!dcd)
    - tty_hangup(p->tty);
    + tty_hangup(p->port.tty);
    }
    p->DCDState = dcd;
    }
    @@ -1433,9 +1430,9 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
    static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
    u16 __iomem *ip)
    {
    - struct tty_struct *tty = p->tty;
    + struct tty_struct *tty = p->port.tty;
    void __iomem *ofsAddr;
    - unsigned int inited = p->asyncflags & ASYNC_INITIALIZED;
    + unsigned int inited = p->port.flags & ASYNC_INITIALIZED;
    u16 intr;

    if (tty) {
    @@ -1566,9 +1563,9 @@ static void moxa_setup_empty_event(struct tty_struct *tty)

    static void moxa_shut_down(struct moxa_port *ch)
    {
    - struct tty_struct *tp = ch->tty;
    + struct tty_struct *tp = ch->port.tty;

    - if (!(ch->asyncflags & ASYNC_INITIALIZED))
    + if (!(ch->port.flags & ASYNC_INITIALIZED))
    return;

    MoxaPortDisable(ch);
    @@ -1580,7 +1577,7 @@ static void moxa_shut_down(struct moxa_port *ch)
    MoxaPortLineCtrl(ch, 0, 0);

    spin_lock_bh(&moxa_lock);
    - ch->asyncflags &= ~ASYNC_INITIALIZED;
    + ch->port.flags &= ~ASYNC_INITIALIZED;
    spin_unlock_bh(&moxa_lock);
    }

    @@ -1975,7 +1972,7 @@ static int MoxaPortWriteData(struct moxa_port *port,
    c = (head > tail) ? (head - tail - 1) : (head - tail + tx_mask);
    if (c > len)
    c = len;
    - moxaLog.txcnt[port->tty->index] += c;
    + moxaLog.txcnt[port->port.tty->index] += c;
    total = c;
    if (spage == epage) {
    bufhead = readw(ofsAddr + Ofs_txb);
    @@ -2017,7 +2014,7 @@ static int MoxaPortWriteData(struct moxa_port *port,

    static int MoxaPortReadData(struct moxa_port *port)
    {
    - struct tty_struct *tty = port->tty;
    + struct tty_struct *tty = port->port.tty;
    unsigned char *dst;
    void __iomem *baseAddr, *ofsAddr, *ofs;
    unsigned int count, len, total;
    @@ -2124,8 +2121,8 @@ static int moxa_get_serial_info(struct moxa_port *info,
    {
    struct serial_struct tmp = {
    .type = info->type,
    - .line = info->tty->index,
    - .flags = info->asyncflags,
    + .line = info->port.tty->index,
    + .flags = info->port.flags,
    .baud_base = 921600,
    .close_delay = info->close_delay
    };
    @@ -2148,13 +2145,13 @@ static int moxa_set_serial_info(struct moxa_port *info,

    if (!capable(CAP_SYS_ADMIN)) {
    if (((new_serial.flags & ~ASYNC_USR_MASK) !=
    - (info->asyncflags & ~ASYNC_USR_MASK)))
    + (info->port.flags & ~ASYNC_USR_MASK)))
    return -EPERM;
    } else
    info->close_delay = new_serial.close_delay * HZ / 100;

    new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS);
    - new_serial.flags |= (info->asyncflags & ASYNC_FLAGS);
    + new_serial.flags |= (info->port.flags & ASYNC_FLAGS);

    MoxaSetFifo(info, new_serial.type == PORT_16550A);


    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  18. [PATCH 05/70] tty.h: clean up

    From: Alan Cox

    Coding style clean up and white space tidy

    Signed-off-by: Alan Cox
    ---

    include/linux/tty.h | 165 ++++++++++++++++++++++++++-------------------------
    1 files changed, 85 insertions(+), 80 deletions(-)


    diff --git a/include/linux/tty.h b/include/linux/tty.h
    index d7c695b..46008e8 100644
    --- a/include/linux/tty.h
    +++ b/include/linux/tty.h
    @@ -71,7 +71,8 @@ struct tty_bufhead {
    struct tty_buffer *head; /* Queue head */
    struct tty_buffer *tail; /* Active buffer */
    struct tty_buffer *free; /* Free queue head */
    - int memory_used; /* Buffer space used excluding free queue */
    + int memory_used; /* Buffer space used excluding
    + free queue */
    };
    /*
    * When a break, frame error, or parity error happens, these codes are
    @@ -101,68 +102,68 @@ struct tty_bufhead {
    #define LNEXT_CHAR(tty) ((tty)->termios->c_cc[VLNEXT])
    #define EOL2_CHAR(tty) ((tty)->termios->c_cc[VEOL2])

    -#define _I_FLAG(tty,f) ((tty)->termios->c_iflag & (f))
    -#define _O_FLAG(tty,f) ((tty)->termios->c_oflag & (f))
    -#define _C_FLAG(tty,f) ((tty)->termios->c_cflag & (f))
    -#define _L_FLAG(tty,f) ((tty)->termios->c_lflag & (f))
    -
    -#define I_IGNBRK(tty) _I_FLAG((tty),IGNBRK)
    -#define I_BRKINT(tty) _I_FLAG((tty),BRKINT)
    -#define I_IGNPAR(tty) _I_FLAG((tty),IGNPAR)
    -#define I_PARMRK(tty) _I_FLAG((tty),PARMRK)
    -#define I_INPCK(tty) _I_FLAG((tty),INPCK)
    -#define I_ISTRIP(tty) _I_FLAG((tty),ISTRIP)
    -#define I_INLCR(tty) _I_FLAG((tty),INLCR)
    -#define I_IGNCR(tty) _I_FLAG((tty),IGNCR)
    -#define I_ICRNL(tty) _I_FLAG((tty),ICRNL)
    -#define I_IUCLC(tty) _I_FLAG((tty),IUCLC)
    -#define I_IXON(tty) _I_FLAG((tty),IXON)
    -#define I_IXANY(tty) _I_FLAG((tty),IXANY)
    -#define I_IXOFF(tty) _I_FLAG((tty),IXOFF)
    -#define I_IMAXBEL(tty) _I_FLAG((tty),IMAXBEL)
    -#define I_IUTF8(tty) _I_FLAG((tty),IUTF8)
    -
    -#define O_OPOST(tty) _O_FLAG((tty),OPOST)
    -#define O_OLCUC(tty) _O_FLAG((tty),OLCUC)
    -#define O_ONLCR(tty) _O_FLAG((tty),ONLCR)
    -#define O_OCRNL(tty) _O_FLAG((tty),OCRNL)
    -#define O_ONOCR(tty) _O_FLAG((tty),ONOCR)
    -#define O_ONLRET(tty) _O_FLAG((tty),ONLRET)
    -#define O_OFILL(tty) _O_FLAG((tty),OFILL)
    -#define O_OFDEL(tty) _O_FLAG((tty),OFDEL)
    -#define O_NLDLY(tty) _O_FLAG((tty),NLDLY)
    -#define O_CRDLY(tty) _O_FLAG((tty),CRDLY)
    -#define O_TABDLY(tty) _O_FLAG((tty),TABDLY)
    -#define O_BSDLY(tty) _O_FLAG((tty),BSDLY)
    -#define O_VTDLY(tty) _O_FLAG((tty),VTDLY)
    -#define O_FFDLY(tty) _O_FLAG((tty),FFDLY)
    -
    -#define C_BAUD(tty) _C_FLAG((tty),CBAUD)
    -#define C_CSIZE(tty) _C_FLAG((tty),CSIZE)
    -#define C_CSTOPB(tty) _C_FLAG((tty),CSTOPB)
    -#define C_CREAD(tty) _C_FLAG((tty),CREAD)
    -#define C_PARENB(tty) _C_FLAG((tty),PARENB)
    -#define C_PARODD(tty) _C_FLAG((tty),PARODD)
    -#define C_HUPCL(tty) _C_FLAG((tty),HUPCL)
    -#define C_CLOCAL(tty) _C_FLAG((tty),CLOCAL)
    -#define C_CIBAUD(tty) _C_FLAG((tty),CIBAUD)
    -#define C_CRTSCTS(tty) _C_FLAG((tty),CRTSCTS)
    -
    -#define L_ISIG(tty) _L_FLAG((tty),ISIG)
    -#define L_ICANON(tty) _L_FLAG((tty),ICANON)
    -#define L_XCASE(tty) _L_FLAG((tty),XCASE)
    -#define L_ECHO(tty) _L_FLAG((tty),ECHO)
    -#define L_ECHOE(tty) _L_FLAG((tty),ECHOE)
    -#define L_ECHOK(tty) _L_FLAG((tty),ECHOK)
    -#define L_ECHONL(tty) _L_FLAG((tty),ECHONL)
    -#define L_NOFLSH(tty) _L_FLAG((tty),NOFLSH)
    -#define L_TOSTOP(tty) _L_FLAG((tty),TOSTOP)
    -#define L_ECHOCTL(tty) _L_FLAG((tty),ECHOCTL)
    -#define L_ECHOPRT(tty) _L_FLAG((tty),ECHOPRT)
    -#define L_ECHOKE(tty) _L_FLAG((tty),ECHOKE)
    -#define L_FLUSHO(tty) _L_FLAG((tty),FLUSHO)
    -#define L_PENDIN(tty) _L_FLAG((tty),PENDIN)
    -#define L_IEXTEN(tty) _L_FLAG((tty),IEXTEN)
    +#define _I_FLAG(tty, f) ((tty)->termios->c_iflag & (f))
    +#define _O_FLAG(tty, f) ((tty)->termios->c_oflag & (f))
    +#define _C_FLAG(tty, f) ((tty)->termios->c_cflag & (f))
    +#define _L_FLAG(tty, f) ((tty)->termios->c_lflag & (f))
    +
    +#define I_IGNBRK(tty) _I_FLAG((tty), IGNBRK)
    +#define I_BRKINT(tty) _I_FLAG((tty), BRKINT)
    +#define I_IGNPAR(tty) _I_FLAG((tty), IGNPAR)
    +#define I_PARMRK(tty) _I_FLAG((tty), PARMRK)
    +#define I_INPCK(tty) _I_FLAG((tty), INPCK)
    +#define I_ISTRIP(tty) _I_FLAG((tty), ISTRIP)
    +#define I_INLCR(tty) _I_FLAG((tty), INLCR)
    +#define I_IGNCR(tty) _I_FLAG((tty), IGNCR)
    +#define I_ICRNL(tty) _I_FLAG((tty), ICRNL)
    +#define I_IUCLC(tty) _I_FLAG((tty), IUCLC)
    +#define I_IXON(tty) _I_FLAG((tty), IXON)
    +#define I_IXANY(tty) _I_FLAG((tty), IXANY)
    +#define I_IXOFF(tty) _I_FLAG((tty), IXOFF)
    +#define I_IMAXBEL(tty) _I_FLAG((tty), IMAXBEL)
    +#define I_IUTF8(tty) _I_FLAG((tty), IUTF8)
    +
    +#define O_OPOST(tty) _O_FLAG((tty), OPOST)
    +#define O_OLCUC(tty) _O_FLAG((tty), OLCUC)
    +#define O_ONLCR(tty) _O_FLAG((tty), ONLCR)
    +#define O_OCRNL(tty) _O_FLAG((tty), OCRNL)
    +#define O_ONOCR(tty) _O_FLAG((tty), ONOCR)
    +#define O_ONLRET(tty) _O_FLAG((tty), ONLRET)
    +#define O_OFILL(tty) _O_FLAG((tty), OFILL)
    +#define O_OFDEL(tty) _O_FLAG((tty), OFDEL)
    +#define O_NLDLY(tty) _O_FLAG((tty), NLDLY)
    +#define O_CRDLY(tty) _O_FLAG((tty), CRDLY)
    +#define O_TABDLY(tty) _O_FLAG((tty), TABDLY)
    +#define O_BSDLY(tty) _O_FLAG((tty), BSDLY)
    +#define O_VTDLY(tty) _O_FLAG((tty), VTDLY)
    +#define O_FFDLY(tty) _O_FLAG((tty), FFDLY)
    +
    +#define C_BAUD(tty) _C_FLAG((tty), CBAUD)
    +#define C_CSIZE(tty) _C_FLAG((tty), CSIZE)
    +#define C_CSTOPB(tty) _C_FLAG((tty), CSTOPB)
    +#define C_CREAD(tty) _C_FLAG((tty), CREAD)
    +#define C_PARENB(tty) _C_FLAG((tty), PARENB)
    +#define C_PARODD(tty) _C_FLAG((tty), PARODD)
    +#define C_HUPCL(tty) _C_FLAG((tty), HUPCL)
    +#define C_CLOCAL(tty) _C_FLAG((tty), CLOCAL)
    +#define C_CIBAUD(tty) _C_FLAG((tty), CIBAUD)
    +#define C_CRTSCTS(tty) _C_FLAG((tty), CRTSCTS)
    +
    +#define L_ISIG(tty) _L_FLAG((tty), ISIG)
    +#define L_ICANON(tty) _L_FLAG((tty), ICANON)
    +#define L_XCASE(tty) _L_FLAG((tty), XCASE)
    +#define L_ECHO(tty) _L_FLAG((tty), ECHO)
    +#define L_ECHOE(tty) _L_FLAG((tty), ECHOE)
    +#define L_ECHOK(tty) _L_FLAG((tty), ECHOK)
    +#define L_ECHONL(tty) _L_FLAG((tty), ECHONL)
    +#define L_NOFLSH(tty) _L_FLAG((tty), NOFLSH)
    +#define L_TOSTOP(tty) _L_FLAG((tty), TOSTOP)
    +#define L_ECHOCTL(tty) _L_FLAG((tty), ECHOCTL)
    +#define L_ECHOPRT(tty) _L_FLAG((tty), ECHOPRT)
    +#define L_ECHOKE(tty) _L_FLAG((tty), ECHOKE)
    +#define L_FLUSHO(tty) _L_FLAG((tty), FLUSHO)
    +#define L_PENDIN(tty) _L_FLAG((tty), PENDIN)
    +#define L_IEXTEN(tty) _L_FLAG((tty), IEXTEN)

    struct device;
    struct signal_struct;
    @@ -177,7 +178,7 @@ struct signal_struct;
    * of the tty object but in many cases port -> tty mappings are valid only
    * until a hangup so don't use the wrong path.
    */
    -
    +
    struct tty_port {
    struct tty_struct *tty; /* Back pointer */
    int blocked_open; /* Waiting to open */
    @@ -273,14 +274,14 @@ struct tty_struct {

    /*
    * These bits are used in the flags field of the tty structure.
    - *
    + *
    * So that interrupts won't be able to mess up the queues,
    * copy_to_cooked must be atomic with respect to itself, as must
    * tty->write. Thus, you must use the inline functions set_bit() and
    * clear_bit() to make things atomic.
    */
    #define TTY_THROTTLED 0 /* Call unthrottle() at threshold min */
    -#define TTY_IO_ERROR 1 /* Canse an I/O error (may be no ldisc too) */
    +#define TTY_IO_ERROR 1 /* Cause an I/O error (may be no ldisc too) */
    #define TTY_OTHER_CLOSED 2 /* Other side (if any) has closed */
    #define TTY_EXCLUSIVE 3 /* Exclusive open mode */
    #define TTY_DEBUG 4 /* Debugging */
    @@ -310,10 +311,10 @@ extern int vcs_init(void);
    extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
    const char *routine);
    extern char *tty_name(struct tty_struct *tty, char *buf);
    -extern void tty_wait_until_sent(struct tty_struct * tty, long timeout);
    -extern int tty_check_change(struct tty_struct * tty);
    -extern void stop_tty(struct tty_struct * tty);
    -extern void start_tty(struct tty_struct * tty);
    +extern void tty_wait_until_sent(struct tty_struct *tty, long timeout);
    +extern int tty_check_change(struct tty_struct *tty);
    +extern void stop_tty(struct tty_struct *tty);
    +extern void start_tty(struct tty_struct *tty);
    extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
    extern int tty_unregister_ldisc(int disc);
    extern int tty_register_driver(struct tty_driver *driver);
    @@ -335,10 +336,10 @@ extern int is_current_pgrp_orphaned(void);
    extern struct pid *tty_get_pgrp(struct tty_struct *tty);
    extern int is_ignored(int sig);
    extern int tty_signal(int sig, struct tty_struct *tty);
    -extern void tty_hangup(struct tty_struct * tty);
    -extern void tty_vhangup(struct tty_struct * tty);
    +extern void tty_hangup(struct tty_struct *tty);
    +extern void tty_vhangup(struct tty_struct *tty);
    extern void tty_unhangup(struct file *filp);
    -extern int tty_hung_up_p(struct file * filp);
    +extern int tty_hung_up_p(struct file *filp);
    extern void do_SAK(struct tty_struct *tty);
    extern void __do_SAK(struct tty_struct *tty);
    extern void disassociate_ctty(int priv);
    @@ -347,8 +348,10 @@ extern void tty_flip_buffer_push(struct tty_struct *tty);
    extern speed_t tty_get_baud_rate(struct tty_struct *tty);
    extern speed_t tty_termios_baud_rate(struct ktermios *termios);
    extern speed_t tty_termios_input_baud_rate(struct ktermios *termios);
    -extern void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud);
    -extern void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud);
    +extern void tty_termios_encode_baud_rate(struct ktermios *termios,
    + speed_t ibaud, speed_t obaud);
    +extern void tty_encode_baud_rate(struct tty_struct *tty,
    + speed_t ibaud, speed_t obaud);
    extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old);
    extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b);

    @@ -390,7 +393,8 @@ extern void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
    extern void tty_audit_exit(void);
    extern void tty_audit_fork(struct signal_struct *sig);
    extern void tty_audit_push(struct tty_struct *tty);
    -extern void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid);
    +extern void tty_audit_push_task(struct task_struct *tsk,
    + uid_t loginuid, u32 sessionid);
    #else
    static inline void tty_audit_add_data(struct tty_struct *tty,
    unsigned char *data, size_t size)
    @@ -405,19 +409,20 @@ static inline void tty_audit_fork(struct signal_struct *sig)
    static inline void tty_audit_push(struct tty_struct *tty)
    {
    }
    -static inline void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid)
    +static inline void tty_audit_push_task(struct task_struct *tsk,
    + uid_t loginuid, u32 sessionid)
    {
    }
    #endif

    /* tty_ioctl.c */
    -extern int n_tty_ioctl(struct tty_struct * tty, struct file * file,
    +extern int n_tty_ioctl(struct tty_struct *tty, struct file *file,
    unsigned int cmd, unsigned long arg);

    /* serial.c */

    extern void serial_console_init(void);
    -
    +
    /* pcxx.c */

    extern int pcxe_open(struct tty_struct *tty, struct file *filp);
    @@ -428,7 +433,7 @@ extern void console_print(const char *);

    /* vt.c */

    -extern int vt_ioctl(struct tty_struct *tty, struct file * file,
    +extern int vt_ioctl(struct tty_struct *tty, struct file *file,
    unsigned int cmd, unsigned long arg);

    #endif /* __KERNEL__ */

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  19. [PATCH 09/70] riscom8: use tty_port

    From: Alan Cox

    Switch riscom8 to use the new tty_port structure

    Signed-off-by: Alan Cox
    ---

    drivers/char/riscom8.c | 145 ++++++++++++++++++++++--------------------------
    drivers/char/riscom8.h | 8 ---
    2 files changed, 68 insertions(+), 85 deletions(-)


    diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
    index f073c71..b0ba241 100644
    --- a/drivers/char/riscom8.c
    +++ b/drivers/char/riscom8.c
    @@ -322,7 +322,7 @@ static struct riscom_port *rc_get_port(struct riscom_board const *bp,
    channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF;
    if (channel < CD180_NCH) {
    port = &rc_port[board_No(bp) * RC_NPORT + channel];
    - if (port->flags & ASYNC_INITIALIZED)
    + if (port->port.flags & ASYNC_INITIALIZED)
    return port;
    }
    printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n",
    @@ -341,7 +341,7 @@ static void rc_receive_exc(struct riscom_board const *bp)
    if (port == NULL)
    return;

    - tty = port->tty;
    + tty = port->port.tty;

    #ifdef RC_REPORT_OVERRUN
    status = rc_in(bp, CD180_RCSR);
    @@ -364,7 +364,7 @@ static void rc_receive_exc(struct riscom_board const *bp)
    printk(KERN_INFO "rc%d: port %d: Handling break...\n",
    board_No(bp), port_No(port));
    flag = TTY_BREAK;
    - if (port->flags & ASYNC_SAK)
    + if (port->port.flags & ASYNC_SAK)
    do_SAK(tty);

    } else if (status & RCSR_PE)
    @@ -392,7 +392,7 @@ static void rc_receive(struct riscom_board const *bp)
    if (port == NULL)
    return;

    - tty = port->tty;
    + tty = port->port.tty;

    count = rc_in(bp, CD180_RDCR);

    @@ -422,7 +422,7 @@ static void rc_transmit(struct riscom_board const *bp)
    if (port == NULL)
    return;

    - tty = port->tty;
    + tty = port->port.tty;

    if (port->IER & IER_TXEMPTY) {
    /* FIFO drained */
    @@ -467,7 +467,7 @@ static void rc_transmit(struct riscom_board const *bp)

    count = CD180_NFIFO;
    do {
    - rc_out(bp, CD180_TDR, port->xmit_buf[port->xmit_tail++]);
    + rc_out(bp, CD180_TDR, port->port.xmit_buf[port->xmit_tail++]);
    port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
    if (--port->xmit_cnt <= 0)
    break;
    @@ -492,12 +492,12 @@ static void rc_check_modem(struct riscom_board const *bp)
    if (port == NULL)
    return;

    - tty = port->tty;
    + tty = port->port.tty;

    mcr = rc_in(bp, CD180_MCR);
    if (mcr & MCR_CDCHG) {
    if (rc_in(bp, CD180_MSVR) & MSVR_CD)
    - wake_up_interruptible(&port->open_wait);
    + wake_up_interruptible(&port->port.open_wait);
    else
    tty_hangup(tty);
    }
    @@ -632,7 +632,7 @@ static void rc_shutdown_board(struct riscom_board *bp)
    */
    static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
    {
    - struct tty_struct *tty = port->tty;
    + struct tty_struct *tty = port->port.tty;
    unsigned long baud;
    long tmp;
    unsigned char cor1 = 0, cor3 = 0;
    @@ -786,28 +786,21 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
    {
    unsigned long flags;

    - if (port->flags & ASYNC_INITIALIZED)
    + if (port->port.flags & ASYNC_INITIALIZED)
    return 0;

    - if (!port->xmit_buf) {
    - /* We may sleep in get_zeroed_page() */
    - unsigned long tmp = get_zeroed_page(GFP_KERNEL);
    - if (tmp == 0)
    - return -ENOMEM;
    - if (port->xmit_buf)
    - free_page(tmp);
    - else
    - port->xmit_buf = (unsigned char *) tmp;
    - }
    + if (tty_port_alloc_xmit_buf(&port->port) < 0)
    + return -ENOMEM;
    +
    spin_lock_irqsave(&riscom_lock, flags);

    - if (port->tty)
    - clear_bit(TTY_IO_ERROR, &port->tty->flags);
    - if (port->count == 1)
    + if (port->port.tty)
    + clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
    + if (port->port.count == 1)
    bp->count++;
    port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
    rc_change_speed(bp, port);
    - port->flags |= ASYNC_INITIALIZED;
    + port->port.flags |= ASYNC_INITIALIZED;

    spin_unlock_irqrestore(&riscom_lock, flags);
    return 0;
    @@ -818,7 +811,7 @@ static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
    {
    struct tty_struct *tty;

    - if (!(port->flags & ASYNC_INITIALIZED))
    + if (!(port->port.flags & ASYNC_INITIALIZED))
    return;

    #ifdef RC_REPORT_OVERRUN
    @@ -836,12 +829,9 @@ static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
    printk("].\n");
    }
    #endif
    - if (port->xmit_buf) {
    - free_page((unsigned long) port->xmit_buf);
    - port->xmit_buf = NULL;
    - }
    + tty_port_free_xmit_buf(&port->port);

    - tty = port->tty;
    + tty = port->port.tty;

    if (tty == NULL || C_HUPCL(tty)) {
    /* Drop DTR */
    @@ -860,7 +850,7 @@ static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)

    if (tty)
    set_bit(TTY_IO_ERROR, &tty->flags);
    - port->flags &= ~ASYNC_INITIALIZED;
    + port->port.flags &= ~ASYNC_INITIALIZED;

    if (--bp->count < 0) {
    printk(KERN_INFO "rc%d: rc_shutdown_port: "
    @@ -890,9 +880,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
    * If the device is in the middle of being closed, then block
    * until it's done, and then try again.
    */
    - if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
    - interruptible_sleep_on(&port->close_wait);
    - if (port->flags & ASYNC_HUP_NOTIFY)
    + if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
    + interruptible_sleep_on(&port->port.close_wait);
    + if (port->port.flags & ASYNC_HUP_NOTIFY)
    return -EAGAIN;
    else
    return -ERESTARTSYS;
    @@ -904,7 +894,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
    */
    if ((filp->f_flags & O_NONBLOCK) ||
    (tty->flags & (1 << TTY_IO_ERROR))) {
    - port->flags |= ASYNC_NORMAL_ACTIVE;
    + port->port.flags |= ASYNC_NORMAL_ACTIVE;
    return 0;
    }

    @@ -919,16 +909,16 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
    * exit, either normal or abnormal.
    */
    retval = 0;
    - add_wait_queue(&port->open_wait, &wait);
    + add_wait_queue(&port->port.open_wait, &wait);

    spin_lock_irqsave(&riscom_lock, flags);

    if (!tty_hung_up_p(filp))
    - port->count--;
    + port->port.count--;

    spin_unlock_irqrestore(&riscom_lock, flags);

    - port->blocked_open++;
    + port->port.blocked_open++;
    while (1) {
    spin_lock_irqsave(&riscom_lock, flags);

    @@ -942,14 +932,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,

    set_current_state(TASK_INTERRUPTIBLE);
    if (tty_hung_up_p(filp) ||
    - !(port->flags & ASYNC_INITIALIZED)) {
    - if (port->flags & ASYNC_HUP_NOTIFY)
    + !(port->port.flags & ASYNC_INITIALIZED)) {
    + if (port->port.flags & ASYNC_HUP_NOTIFY)
    retval = -EAGAIN;
    else
    retval = -ERESTARTSYS;
    break;
    }
    - if (!(port->flags & ASYNC_CLOSING) &&
    + if (!(port->port.flags & ASYNC_CLOSING) &&
    (do_clocal || CD))
    break;
    if (signal_pending(current)) {
    @@ -959,14 +949,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
    schedule();
    }
    __set_current_state(TASK_RUNNING);
    - remove_wait_queue(&port->open_wait, &wait);
    + remove_wait_queue(&port->port.open_wait, &wait);
    if (!tty_hung_up_p(filp))
    - port->count++;
    - port->blocked_open--;
    + port->port.count++;
    + port->port.blocked_open--;
    if (retval)
    return retval;

    - port->flags |= ASYNC_NORMAL_ACTIVE;
    + port->port.flags |= ASYNC_NORMAL_ACTIVE;
    return 0;
    }

    @@ -990,9 +980,9 @@ static int rc_open(struct tty_struct *tty, struct file *filp)
    if (error)
    return error;

    - port->count++;
    + port->port.count++;
    tty->driver_data = port;
    - port->tty = tty;
    + port->port.tty = tty;

    error = rc_setup_port(bp, port);
    if (error == 0)
    @@ -1031,21 +1021,21 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
    goto out;

    bp = port_Board(port);
    - if ((tty->count == 1) && (port->count != 1)) {
    + if ((tty->count == 1) && (port->port.count != 1)) {
    printk(KERN_INFO "rc%d: rc_close: bad port count;"
    " tty->count is 1, port count is %d\n",
    - board_No(bp), port->count);
    - port->count = 1;
    + board_No(bp), port->port.count);
    + port->port.count = 1;
    }
    - if (--port->count < 0) {
    + if (--port->port.count < 0) {
    printk(KERN_INFO "rc%d: rc_close: bad port count "
    "for tty%d: %d\n",
    - board_No(bp), port_No(port), port->count);
    - port->count = 0;
    + board_No(bp), port_No(port), port->port.count);
    + port->port.count = 0;
    }
    - if (port->count)
    + if (port->port.count)
    goto out;
    - port->flags |= ASYNC_CLOSING;
    + port->port.flags |= ASYNC_CLOSING;
    /*
    * Now we wait for the transmit buffer to clear; and we notify
    * the line discipline to only process XON/XOFF characters.
    @@ -1060,7 +1050,7 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
    * line status register.
    */
    port->IER &= ~IER_RXD;
    - if (port->flags & ASYNC_INITIALIZED) {
    + if (port->port.flags & ASYNC_INITIALIZED) {
    port->IER &= ~IER_TXRDY;
    port->IER |= IER_TXEMPTY;
    rc_out(bp, CD180_CAR, port_No(port));
    @@ -1082,14 +1072,14 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
    tty_ldisc_flush(tty);

    tty->closing = 0;
    - port->tty = NULL;
    - if (port->blocked_open) {
    + port->port.tty = NULL;
    + if (port->port.blocked_open) {
    if (port->close_delay)
    msleep_interruptible(jiffies_to_msecs(port->close_delay));
    - wake_up_interruptible(&port->open_wait);
    + wake_up_interruptible(&port->port.open_wait);
    }
    - port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
    - wake_up_interruptible(&port->close_wait);
    + port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
    + wake_up_interruptible(&port->port.close_wait);

    out:
    spin_unlock_irqrestore(&riscom_lock, flags);
    @@ -1108,7 +1098,7 @@ static int rc_write(struct tty_struct *tty,

    bp = port_Board(port);

    - if (!tty || !port->xmit_buf)
    + if (!tty || !port->port.xmit_buf)
    return 0;

    while (1) {
    @@ -1119,7 +1109,7 @@ static int rc_write(struct tty_struct *tty,
    if (c <= 0)
    break; /* lock continues to be held */

    - memcpy(port->xmit_buf + port->xmit_head, buf, c);
    + memcpy(port->port.xmit_buf + port->xmit_head, buf, c);
    port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
    port->xmit_cnt += c;

    @@ -1151,7 +1141,7 @@ static int rc_put_char(struct tty_struct *tty, unsigned char ch)
    if (rc_paranoia_check(port, tty->name, "rc_put_char"))
    return 0;

    - if (!tty || !port->xmit_buf)
    + if (!tty || !port->port.xmit_buf)
    return 0;

    spin_lock_irqsave(&riscom_lock, flags);
    @@ -1159,7 +1149,7 @@ static int rc_put_char(struct tty_struct *tty, unsigned char ch)
    if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
    goto out;

    - port->xmit_buf[port->xmit_head++] = ch;
    + port->port.xmit_buf[port->xmit_head++] = ch;
    port->xmit_head &= SERIAL_XMIT_SIZE - 1;
    port->xmit_cnt++;
    ret = 1;
    @@ -1178,7 +1168,7 @@ static void rc_flush_chars(struct tty_struct *tty)
    return;

    if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
    - !port->xmit_buf)
    + !port->port.xmit_buf)
    return;

    spin_lock_irqsave(&riscom_lock, flags);
    @@ -1317,19 +1307,19 @@ static int rc_set_serial_info(struct riscom_port *port,
    return -EINVAL;
    #endif

    - change_speed = ((port->flags & ASYNC_SPD_MASK) !=
    + change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
    (tmp.flags & ASYNC_SPD_MASK));

    if (!capable(CAP_SYS_ADMIN)) {
    if ((tmp.close_delay != port->close_delay) ||
    (tmp.closing_wait != port->closing_wait) ||
    ((tmp.flags & ~ASYNC_USR_MASK) !=
    - (port->flags & ~ASYNC_USR_MASK)))
    + (port->port.flags & ~ASYNC_USR_MASK)))
    return -EPERM;
    - port->flags = ((port->flags & ~ASYNC_USR_MASK) |
    + port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
    (tmp.flags & ASYNC_USR_MASK));
    } else {
    - port->flags = ((port->flags & ~ASYNC_FLAGS) |
    + port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
    (tmp.flags & ASYNC_FLAGS));
    port->close_delay = tmp.close_delay;
    port->closing_wait = tmp.closing_wait;
    @@ -1355,7 +1345,7 @@ static int rc_get_serial_info(struct riscom_port *port,
    tmp.line = port - rc_port;
    tmp.port = bp->base;
    tmp.irq = bp->irq;
    - tmp.flags = port->flags;
    + tmp.flags = port->port.flags;
    tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC;
    tmp.close_delay = port->close_delay * HZ/100;
    tmp.closing_wait = port->closing_wait * HZ/100;
    @@ -1480,7 +1470,7 @@ static void rc_start(struct tty_struct *tty)

    spin_lock_irqsave(&riscom_lock, flags);

    - if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
    + if (port->xmit_cnt && port->port.xmit_buf && !(port->IER & IER_TXRDY)) {
    port->IER |= IER_TXRDY;
    rc_out(bp, CD180_CAR, port_No(port));
    rc_out(bp, CD180_IER, port->IER);
    @@ -1499,10 +1489,10 @@ static void rc_hangup(struct tty_struct *tty)
    bp = port_Board(port);

    rc_shutdown_port(bp, port);
    - port->count = 0;
    - port->flags &= ~ASYNC_NORMAL_ACTIVE;
    - port->tty = NULL;
    - wake_up_interruptible(&port->open_wait);
    + port->port.count = 0;
    + port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
    + port->port.tty = NULL;
    + wake_up_interruptible(&port->port.open_wait);
    }

    static void rc_set_termios(struct tty_struct *tty,
    @@ -1578,8 +1568,7 @@ static int __init rc_init_drivers(void)
    rc_port[i].magic = RISCOM8_MAGIC;
    rc_port[i].close_delay = 50 * HZ / 100;
    rc_port[i].closing_wait = 3000 * HZ / 100;
    - init_waitqueue_head(&rc_port[i].open_wait);
    - init_waitqueue_head(&rc_port[i].close_wait);
    + tty_port_init(&rc_port[i].port);
    }
    return 0;
    }
    diff --git a/drivers/char/riscom8.h b/drivers/char/riscom8.h
    index cdfdf43..29ddbab 100644
    --- a/drivers/char/riscom8.h
    +++ b/drivers/char/riscom8.h
    @@ -66,20 +66,14 @@ struct riscom_board {

    struct riscom_port {
    int magic;
    + struct tty_port port;
    int baud_base;
    - int flags;
    - struct tty_struct * tty;
    - int count;
    - int blocked_open;
    int timeout;
    int close_delay;
    - unsigned char * xmit_buf;
    int custom_divisor;
    int xmit_head;
    int xmit_tail;
    int xmit_cnt;
    - wait_queue_head_t open_wait;
    - wait_queue_head_t close_wait;
    short wakeup_chars;
    short break_length;
    unsigned short closing_wait;

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  20. [PATCH 33/70] usb-cypress: There is no 0 case to go with CS5/6/7/8 so remove the test

    From: Alan Cox



    Signed-off-by: Alan Cox
    ---

    drivers/usb/serial/cypress_m8.c | 37 +++++++++++++++++--------------------
    1 files changed, 17 insertions(+), 20 deletions(-)


    diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
    index bb9c7c4..22837a3 100644
    --- a/drivers/usb/serial/cypress_m8.c
    +++ b/drivers/usb/serial/cypress_m8.c
    @@ -1093,27 +1093,24 @@ static void cypress_set_termios(struct tty_struct *tty,
    } else
    parity_enable = parity_type = 0;

    - if (cflag & CSIZE) {
    - switch (cflag & CSIZE) {
    - case CS5:
    - data_bits = 0;
    - break;
    - case CS6:
    - data_bits = 1;
    - break;
    - case CS7:
    - data_bits = 2;
    - break;
    - case CS8:
    - data_bits = 3;
    - break;
    - default:
    - err("%s - CSIZE was set, but not CS5-CS8",
    - __func__);
    - data_bits = 3;
    - } else
    + switch (cflag & CSIZE) {
    + case CS5:
    + data_bits = 0;
    + break;
    + case CS6:
    + data_bits = 1;
    + break;
    + case CS7:
    + data_bits = 2;
    + break;
    + case CS8:
    data_bits = 3;
    -
    + break;
    + default:
    + err("%s - CSIZE was set, but not CS5-CS8",
    + __func__);
    + data_bits = 3;
    + }
    spin_lock_irqsave(&priv->lock, flags);
    oldlines = priv->line_control;
    if ((cflag & CBAUD) == B0) {

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread
Page 1 of 4 1 2 3 ... LastLast