* [patch 6/6] s390: remove tty support from ctc network device driver [2/2]
From: Frank Pavlic @ 2006-03-22 16:42 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-kernel
[patch 6/6] s390: remove tty support from ctc network device driver [2/2]
From: Peter Tiedemann <ptiedem@de.ibm.com>
[2/2]: remove ctctty.c and ctctty.h files .
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
ctctty.c | 1259 ---------------------------------------------------------------
ctctty.h | 35 -
2 files changed, 1294 deletions(-)
diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c
deleted file mode 100644
index 5cdcdbf..0000000
--- a/drivers/s390/net/ctctty.c
+++ /dev/null
@@ -1,1259 +0,0 @@
-/*
- * CTC / ESCON network driver, tty interface.
- *
- * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
- *
- * 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial_reg.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <asm/uaccess.h>
-#include <linux/devfs_fs_kernel.h>
-#include "ctctty.h"
-#include "ctcdbug.h"
-
-#define CTC_TTY_MAJOR 43
-#define CTC_TTY_MAX_DEVICES 64
-
-#define CTC_ASYNC_MAGIC 0x49344C01 /* for paranoia-checking */
-#define CTC_ASYNC_INITIALIZED 0x80000000 /* port was initialized */
-#define CTC_ASYNC_NORMAL_ACTIVE 0x20000000 /* Normal device active */
-#define CTC_ASYNC_CLOSING 0x08000000 /* Serial port is closing */
-#define CTC_ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */
-#define CTC_ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */
-#define CTC_ASYNC_HUP_NOTIFY 0x0001 /* Notify tty on hangups/closes */
-#define CTC_ASYNC_NETDEV_OPEN 0x0002 /* Underlying netdev is open */
-#define CTC_ASYNC_TX_LINESTAT 0x0004 /* Must send line status */
-#define CTC_ASYNC_SPLIT_TERMIOS 0x0008 /* Sep. termios for dialin/out */
-#define CTC_TTY_XMIT_SIZE 1024 /* Default bufsize for write */
-#define CTC_SERIAL_XMIT_MAX 4000 /* Maximum bufsize for write */
-
-/* Private data (similar to async_struct in <linux/serial.h>) */
-typedef struct {
- int magic;
- int flags; /* defined in tty.h */
- int mcr; /* Modem control register */
- int msr; /* Modem status register */
- int lsr; /* Line status register */
- int line;
- int count; /* # of fd on device */
- int blocked_open; /* # of blocked opens */
- struct net_device *netdev;
- struct sk_buff_head tx_queue; /* transmit queue */
- struct sk_buff_head rx_queue; /* receive queue */
- struct tty_struct *tty; /* Pointer to corresponding tty */
- wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
- struct semaphore write_sem;
- struct tasklet_struct tasklet;
- struct timer_list stoptimer;
-} ctc_tty_info;
-
-/* Description of one CTC-tty */
-typedef struct {
- struct tty_driver *ctc_tty_device; /* tty-device */
- ctc_tty_info info[CTC_TTY_MAX_DEVICES]; /* Private data */
-} ctc_tty_driver;
-
-static ctc_tty_driver *driver;
-
-/* Leave this unchanged unless you know what you do! */
-#define MODEM_PARANOIA_CHECK
-#define MODEM_DO_RESTART
-
-#define CTC_TTY_NAME "ctctty"
-
-static __u32 ctc_tty_magic = CTC_ASYNC_MAGIC;
-static int ctc_tty_shuttingdown = 0;
-
-static spinlock_t ctc_tty_lock;
-
-/* ctc_tty_try_read() is called from within ctc_tty_rcv_skb()
- * to stuff incoming data directly into a tty's flip-buffer. If the
- * flip buffer is full, the packet gets queued up.
- *
- * Return:
- * 1 = Success
- * 0 = Failure, data has to be buffered and later processed by
- * ctc_tty_readmodem().
- */
-static int
-ctc_tty_try_read(ctc_tty_info * info, struct sk_buff *skb)
-{
- int len;
- struct tty_struct *tty;
-
- DBF_TEXT(trace, 5, __FUNCTION__);
- if ((tty = info->tty)) {
- if (info->mcr & UART_MCR_RTS) {
- len = skb->len;
- tty_insert_flip_string(tty, skb->data, len);
- tty_flip_buffer_push(tty);
- kfree_skb(skb);
- return 1;
- }
- }
- return 0;
-}
-
-/* ctc_tty_readmodem() is called periodically from within timer-interrupt.
- * It tries getting received data from the receive queue an stuff it into
- * the tty's flip-buffer.
- */
-static int
-ctc_tty_readmodem(ctc_tty_info *info)
-{
- int ret = 1;
- struct tty_struct *tty;
-
- DBF_TEXT(trace, 5, __FUNCTION__);
- if ((tty = info->tty)) {
- if (info->mcr & UART_MCR_RTS) {
- struct sk_buff *skb;
-
- if ((skb = skb_dequeue(&info->rx_queue))) {
- int len = skb->len;
- tty_insert_flip_string(tty, skb->data, len);
- skb_pull(skb, len);
- tty_flip_buffer_push(tty);
- if (skb->len > 0)
- skb_queue_head(&info->rx_queue, skb);
- else {
- kfree_skb(skb);
- ret = !skb_queue_empty(&info->rx_queue);
- }
- }
- }
- }
- return ret;
-}
-
-void
-ctc_tty_setcarrier(struct net_device *netdev, int on)
-{
- int i;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if ((!driver) || ctc_tty_shuttingdown)
- return;
- for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
- if (driver->info[i].netdev == netdev) {
- ctc_tty_info *info = &driver->info[i];
- if (on)
- info->msr |= UART_MSR_DCD;
- else
- info->msr &= ~UART_MSR_DCD;
- if ((info->flags & CTC_ASYNC_CHECK_CD) && (!on))
- tty_hangup(info->tty);
- }
-}
-
-void
-ctc_tty_netif_rx(struct sk_buff *skb)
-{
- int i;
- ctc_tty_info *info = NULL;
-
- DBF_TEXT(trace, 5, __FUNCTION__);
- if (!skb)
- return;
- if ((!skb->dev) || (!driver) || ctc_tty_shuttingdown) {
- dev_kfree_skb(skb);
- return;
- }
- for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
- if (driver->info[i].netdev == skb->dev) {
- info = &driver->info[i];
- break;
- }
- if (!info) {
- dev_kfree_skb(skb);
- return;
- }
- if (skb->len < 6) {
- dev_kfree_skb(skb);
- return;
- }
- if (memcmp(skb->data, &ctc_tty_magic, sizeof(__u32))) {
- dev_kfree_skb(skb);
- return;
- }
- skb_pull(skb, sizeof(__u32));
-
- i = *((int *)skb->data);
- skb_pull(skb, sizeof(info->mcr));
- if (i & UART_MCR_RTS) {
- info->msr |= UART_MSR_CTS;
- if (info->flags & CTC_ASYNC_CTS_FLOW)
- info->tty->hw_stopped = 0;
- } else {
- info->msr &= ~UART_MSR_CTS;
- if (info->flags & CTC_ASYNC_CTS_FLOW)
- info->tty->hw_stopped = 1;
- }
- if (i & UART_MCR_DTR)
- info->msr |= UART_MSR_DSR;
- else
- info->msr &= ~UART_MSR_DSR;
- if (skb->len <= 0) {
- kfree_skb(skb);
- return;
- }
- /* Try to deliver directly via tty-flip-buf if queue is empty */
- if (skb_queue_empty(&info->rx_queue))
- if (ctc_tty_try_read(info, skb))
- return;
- /* Direct deliver failed or queue wasn't empty.
- * Queue up for later dequeueing via timer-irq.
- */
- skb_queue_tail(&info->rx_queue, skb);
- /* Schedule dequeuing */
- tasklet_schedule(&info->tasklet);
-}
-
-static int
-ctc_tty_tint(ctc_tty_info * info)
-{
- struct sk_buff *skb = skb_dequeue(&info->tx_queue);
- int stopped = (info->tty->hw_stopped || info->tty->stopped);
- int wake = 1;
- int rc;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (!info->netdev) {
- if (skb)
- kfree_skb(skb);
- return 0;
- }
- if (info->flags & CTC_ASYNC_TX_LINESTAT) {
- int skb_res = info->netdev->hard_header_len +
- sizeof(info->mcr) + sizeof(__u32);
- /* If we must update line status,
- * create an empty dummy skb and insert it.
- */
- if (skb)
- skb_queue_head(&info->tx_queue, skb);
-
- skb = dev_alloc_skb(skb_res);
- if (!skb) {
- printk(KERN_WARNING
- "ctc_tty: Out of memory in %s%d tint\n",
- CTC_TTY_NAME, info->line);
- return 1;
- }
- skb_reserve(skb, skb_res);
- stopped = 0;
- wake = 0;
- }
- if (!skb)
- return 0;
- if (stopped) {
- skb_queue_head(&info->tx_queue, skb);
- return 1;
- }
-#if 0
- if (skb->len > 0)
- printk(KERN_DEBUG "tint: %d %02x\n", skb->len, *(skb->data));
- else
- printk(KERN_DEBUG "tint: %d STAT\n", skb->len);
-#endif
- memcpy(skb_push(skb, sizeof(info->mcr)), &info->mcr, sizeof(info->mcr));
- memcpy(skb_push(skb, sizeof(__u32)), &ctc_tty_magic, sizeof(__u32));
- rc = info->netdev->hard_start_xmit(skb, info->netdev);
- if (rc) {
- skb_pull(skb, sizeof(info->mcr) + sizeof(__u32));
- if (skb->len > 0)
- skb_queue_head(&info->tx_queue, skb);
- else
- kfree_skb(skb);
- } else {
- struct tty_struct *tty = info->tty;
-
- info->flags &= ~CTC_ASYNC_TX_LINESTAT;
- if (tty) {
- tty_wakeup(tty);
- }
- }
- return (skb_queue_empty(&info->tx_queue) ? 0 : 1);
-}
-
-/************************************************************
- *
- * Modem-functions
- *
- * mostly "stolen" from original Linux-serial.c and friends.
- *
- ************************************************************/
-
-static inline int
-ctc_tty_paranoia_check(ctc_tty_info * info, char *name, const char *routine)
-{
-#ifdef MODEM_PARANOIA_CHECK
- if (!info) {
- printk(KERN_WARNING "ctc_tty: null info_struct for %s in %s\n",
- name, routine);
- return 1;
- }
- if (info->magic != CTC_ASYNC_MAGIC) {
- printk(KERN_WARNING "ctc_tty: bad magic for info struct %s in %s\n",
- name, routine);
- return 1;
- }
-#endif
- return 0;
-}
-
-static void
-ctc_tty_inject(ctc_tty_info *info, char c)
-{
- int skb_res;
- struct sk_buff *skb;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_shuttingdown)
- return;
- skb_res = info->netdev->hard_header_len + sizeof(info->mcr) +
- sizeof(__u32) + 1;
- skb = dev_alloc_skb(skb_res);
- if (!skb) {
- printk(KERN_WARNING
- "ctc_tty: Out of memory in %s%d tx_inject\n",
- CTC_TTY_NAME, info->line);
- return;
- }
- skb_reserve(skb, skb_res);
- *(skb_put(skb, 1)) = c;
- skb_queue_head(&info->tx_queue, skb);
- tasklet_schedule(&info->tasklet);
-}
-
-static void
-ctc_tty_transmit_status(ctc_tty_info *info)
-{
- DBF_TEXT(trace, 5, __FUNCTION__);
- if (ctc_tty_shuttingdown)
- return;
- info->flags |= CTC_ASYNC_TX_LINESTAT;
- tasklet_schedule(&info->tasklet);
-}
-
-static void
-ctc_tty_change_speed(ctc_tty_info * info)
-{
- unsigned int cflag;
- unsigned int quot;
- int i;
-
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (!info->tty || !info->tty->termios)
- return;
- cflag = info->tty->termios->c_cflag;
-
- quot = i = cflag & CBAUD;
- if (i & CBAUDEX) {
- i &= ~CBAUDEX;
- if (i < 1 || i > 2)
- info->tty->termios->c_cflag &= ~CBAUDEX;
- else
- i += 15;
- }
- if (quot) {
- info->mcr |= UART_MCR_DTR;
- info->mcr |= UART_MCR_RTS;
- ctc_tty_transmit_status(info);
- } else {
- info->mcr &= ~UART_MCR_DTR;
- info->mcr &= ~UART_MCR_RTS;
- ctc_tty_transmit_status(info);
- return;
- }
-
- /* CTS flow control flag and modem status interrupts */
- if (cflag & CRTSCTS) {
- info->flags |= CTC_ASYNC_CTS_FLOW;
- } else
- info->flags &= ~CTC_ASYNC_CTS_FLOW;
- if (cflag & CLOCAL)
- info->flags &= ~CTC_ASYNC_CHECK_CD;
- else {
- info->flags |= CTC_ASYNC_CHECK_CD;
- }
-}
-
-static int
-ctc_tty_startup(ctc_tty_info * info)
-{
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (info->flags & CTC_ASYNC_INITIALIZED)
- return 0;
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "starting up %s%d ...\n", CTC_TTY_NAME, info->line);
-#endif
- /*
- * Now, initialize the UART
- */
- info->mcr = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
- /*
- * and set the speed of the serial port
- */
- ctc_tty_change_speed(info);
-
- info->flags |= CTC_ASYNC_INITIALIZED;
- if (!(info->flags & CTC_ASYNC_NETDEV_OPEN))
- info->netdev->open(info->netdev);
- info->flags |= CTC_ASYNC_NETDEV_OPEN;
- return 0;
-}
-
-static void
-ctc_tty_stopdev(unsigned long data)
-{
- ctc_tty_info *info = (ctc_tty_info *)data;
-
- if ((!info) || (!info->netdev) ||
- (info->flags & CTC_ASYNC_INITIALIZED))
- return;
- info->netdev->stop(info->netdev);
- info->flags &= ~CTC_ASYNC_NETDEV_OPEN;
-}
-
-/*
- * This routine will shutdown a serial port; interrupts are disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
- */
-static void
-ctc_tty_shutdown(ctc_tty_info * info)
-{
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (!(info->flags & CTC_ASYNC_INITIALIZED))
- return;
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "Shutting down %s%d ....\n", CTC_TTY_NAME, info->line);
-#endif
- info->msr &= ~UART_MSR_RI;
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
- info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS);
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
- mod_timer(&info->stoptimer, jiffies + (10 * HZ));
- skb_queue_purge(&info->tx_queue);
- skb_queue_purge(&info->rx_queue);
- info->flags &= ~CTC_ASYNC_INITIALIZED;
-}
-
-/* ctc_tty_write() is the main send-routine. It is called from the upper
- * levels within the kernel to perform sending data. Depending on the
- * online-flag it either directs output to the at-command-interpreter or
- * to the lower level. Additional tasks done here:
- * - If online, check for escape-sequence (+++)
- * - If sending audio-data, call ctc_tty_DLEdown() to parse DLE-codes.
- * - If receiving audio-data, call ctc_tty_end_vrx() to abort if needed.
- * - If dialing, abort dial.
- */
-static int
-ctc_tty_write(struct tty_struct *tty, const u_char * buf, int count)
-{
- int c;
- int total = 0;
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 5, __FUNCTION__);
- if (ctc_tty_shuttingdown)
- goto ex;
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write"))
- goto ex;
- if (!tty)
- goto ex;
- if (!info->netdev) {
- total = -ENODEV;
- goto ex;
- }
- while (1) {
- struct sk_buff *skb;
- int skb_res;
-
- c = (count < CTC_TTY_XMIT_SIZE) ? count : CTC_TTY_XMIT_SIZE;
- if (c <= 0)
- break;
-
- skb_res = info->netdev->hard_header_len + sizeof(info->mcr) +
- + sizeof(__u32);
- skb = dev_alloc_skb(skb_res + c);
- if (!skb) {
- printk(KERN_WARNING
- "ctc_tty: Out of memory in %s%d write\n",
- CTC_TTY_NAME, info->line);
- break;
- }
- skb_reserve(skb, skb_res);
- memcpy(skb_put(skb, c), buf, c);
- skb_queue_tail(&info->tx_queue, skb);
- buf += c;
- total += c;
- count -= c;
- }
- if (!skb_queue_empty(&info->tx_queue)) {
- info->lsr &= ~UART_LSR_TEMT;
- tasklet_schedule(&info->tasklet);
- }
-ex:
- DBF_TEXT(trace, 6, __FUNCTION__);
- return total;
-}
-
-static int
-ctc_tty_write_room(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write_room"))
- return 0;
- return CTC_TTY_XMIT_SIZE;
-}
-
-static int
-ctc_tty_chars_in_buffer(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_chars_in_buffer"))
- return 0;
- return 0;
-}
-
-static void
-ctc_tty_flush_buffer(struct tty_struct *tty)
-{
- ctc_tty_info *info;
- unsigned long flags;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (!tty)
- goto ex;
- spin_lock_irqsave(&ctc_tty_lock, flags);
- info = (ctc_tty_info *) tty->driver_data;
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_buffer")) {
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- goto ex;
- }
- skb_queue_purge(&info->tx_queue);
- info->lsr |= UART_LSR_TEMT;
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- wake_up_interruptible(&tty->write_wait);
- tty_wakeup(tty);
-ex:
- DBF_TEXT_(trace, 2, "ex: %s ", __FUNCTION__);
- return;
-}
-
-static void
-ctc_tty_flush_chars(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_shuttingdown)
- return;
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_chars"))
- return;
- if (tty->stopped || tty->hw_stopped || skb_queue_empty(&info->tx_queue))
- return;
- tasklet_schedule(&info->tasklet);
-}
-
-/*
- * ------------------------------------------------------------
- * ctc_tty_throttle()
- *
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void
-ctc_tty_throttle(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_throttle"))
- return;
- info->mcr &= ~UART_MCR_RTS;
- if (I_IXOFF(tty))
- ctc_tty_inject(info, STOP_CHAR(tty));
- ctc_tty_transmit_status(info);
-}
-
-static void
-ctc_tty_unthrottle(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_unthrottle"))
- return;
- info->mcr |= UART_MCR_RTS;
- if (I_IXOFF(tty))
- ctc_tty_inject(info, START_CHAR(tty));
- ctc_tty_transmit_status(info);
-}
-
-/*
- * ------------------------------------------------------------
- * ctc_tty_ioctl() and friends
- * ------------------------------------------------------------
- */
-
-/*
- * ctc_tty_get_lsr_info - get line status register info
- *
- * Purpose: Let user call ioctl() to get info when the UART physically
- * is emptied. On bus types like RS485, the transmitter must
- * release the bus after transmitting. This must be done when
- * the transmit shift register is empty, not be done when the
- * transmit holding register is empty. This functionality
- * allows RS485 driver to be written in user space.
- */
-static int
-ctc_tty_get_lsr_info(ctc_tty_info * info, uint __user *value)
-{
- u_char status;
- uint result;
- ulong flags;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- spin_lock_irqsave(&ctc_tty_lock, flags);
- status = info->lsr;
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
- put_user(result, value);
- return 0;
-}
-
-
-static int ctc_tty_tiocmget(struct tty_struct *tty, struct file *file)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
- u_char control,
- status;
- uint result;
- ulong flags;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
- return -ENODEV;
- if (tty->flags & (1 << TTY_IO_ERROR))
- return -EIO;
-
- control = info->mcr;
- spin_lock_irqsave(&ctc_tty_lock, flags);
- status = info->msr;
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
- | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
- | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
- | ((status & UART_MSR_RI) ? TIOCM_RNG : 0)
- | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0)
- | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
- return result;
-}
-
-static int
-ctc_tty_tiocmset(struct tty_struct *tty, struct file *file,
- unsigned int set, unsigned int clear)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
- return -ENODEV;
- if (tty->flags & (1 << TTY_IO_ERROR))
- return -EIO;
-
- if (set & TIOCM_RTS)
- info->mcr |= UART_MCR_RTS;
- if (set & TIOCM_DTR)
- info->mcr |= UART_MCR_DTR;
-
- if (clear & TIOCM_RTS)
- info->mcr &= ~UART_MCR_RTS;
- if (clear & TIOCM_DTR)
- info->mcr &= ~UART_MCR_DTR;
-
- if ((set | clear) & (TIOCM_RTS|TIOCM_DTR))
- ctc_tty_transmit_status(info);
- return 0;
-}
-
-static int
-ctc_tty_ioctl(struct tty_struct *tty, struct file *file,
- uint cmd, ulong arg)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
- int error;
- int retval;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
- return -ENODEV;
- if (tty->flags & (1 << TTY_IO_ERROR))
- return -EIO;
- switch (cmd) {
- case TCSBRK: /* SVID version: non-zero arg --> no break */
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TCSBRK\n", CTC_TTY_NAME, info->line);
-#endif
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- return 0;
- case TCSBRKP: /* support for POSIX tcsendbreak() */
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TCSBRKP\n", CTC_TTY_NAME, info->line);
-#endif
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- return 0;
- case TIOCGSOFTCAR:
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TIOCGSOFTCAR\n", CTC_TTY_NAME,
- info->line);
-#endif
- error = put_user(C_CLOCAL(tty) ? 1 : 0, (ulong __user *) arg);
- return error;
- case TIOCSSOFTCAR:
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TIOCSSOFTCAR\n", CTC_TTY_NAME,
- info->line);
-#endif
- error = get_user(arg, (ulong __user *) arg);
- if (error)
- return error;
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- return 0;
- case TIOCSERGETLSR: /* Get line status register */
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TIOCSERGETLSR\n", CTC_TTY_NAME,
- info->line);
-#endif
- if (access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(uint)))
- return ctc_tty_get_lsr_info(info, (uint __user *) arg);
- else
- return -EFAULT;
- default:
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on %s%d\n", cmd,
- CTC_TTY_NAME, info->line);
-#endif
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static void
-ctc_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
- unsigned int cflag = tty->termios->c_cflag;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- ctc_tty_change_speed(info);
-
- /* Handle transition to B0 */
- if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) {
- info->mcr &= ~(UART_MCR_DTR|UART_MCR_RTS);
- ctc_tty_transmit_status(info);
- }
-
- /* Handle transition from B0 to other */
- if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
- info->mcr |= UART_MCR_DTR;
- if (!(tty->termios->c_cflag & CRTSCTS) ||
- !test_bit(TTY_THROTTLED, &tty->flags)) {
- info->mcr |= UART_MCR_RTS;
- }
- ctc_tty_transmit_status(info);
- }
-
- /* Handle turning off CRTSCTS */
- if ((old_termios->c_cflag & CRTSCTS) &&
- !(tty->termios->c_cflag & CRTSCTS))
- tty->hw_stopped = 0;
-}
-
-/*
- * ------------------------------------------------------------
- * ctc_tty_open() and friends
- * ------------------------------------------------------------
- */
-static int
-ctc_tty_block_til_ready(struct tty_struct *tty, struct file *filp, ctc_tty_info *info)
-{
- DECLARE_WAITQUEUE(wait, NULL);
- int do_clocal = 0;
- unsigned long flags;
- int retval;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- /*
- * 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) ||
- (info->flags & CTC_ASYNC_CLOSING)) {
- if (info->flags & CTC_ASYNC_CLOSING)
- wait_event(info->close_wait,
- !(info->flags & CTC_ASYNC_CLOSING));
-#ifdef MODEM_DO_RESTART
- if (info->flags & CTC_ASYNC_HUP_NOTIFY)
- return -EAGAIN;
- else
- return -ERESTARTSYS;
-#else
- return -EAGAIN;
-#endif
- }
- /*
- * If non-blocking mode is set, then make the check up front
- * and then exit.
- */
- if ((filp->f_flags & O_NONBLOCK) ||
- (tty->flags & (1 << TTY_IO_ERROR))) {
- info->flags |= CTC_ASYNC_NORMAL_ACTIVE;
- return 0;
- }
- if (tty->termios->c_cflag & CLOCAL)
- do_clocal = 1;
- /*
- * Block waiting for the carrier detect and the line to become
- * free (i.e., not in use by the callout). While we are in
- * this loop, info->count is dropped by one, so that
- * ctc_tty_close() knows when to free things. We restore it upon
- * exit, either normal or abnormal.
- */
- retval = 0;
- add_wait_queue(&info->open_wait, &wait);
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_block_til_ready before block: %s%d, count = %d\n",
- CTC_TTY_NAME, info->line, info->count);
-#endif
- spin_lock_irqsave(&ctc_tty_lock, flags);
- if (!(tty_hung_up_p(filp)))
- info->count--;
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- info->blocked_open++;
- while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) ||
- !(info->flags & CTC_ASYNC_INITIALIZED)) {
-#ifdef MODEM_DO_RESTART
- if (info->flags & CTC_ASYNC_HUP_NOTIFY)
- retval = -EAGAIN;
- else
- retval = -ERESTARTSYS;
-#else
- retval = -EAGAIN;
-#endif
- break;
- }
- if (!(info->flags & CTC_ASYNC_CLOSING) &&
- (do_clocal || (info->msr & UART_MSR_DCD))) {
- break;
- }
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_block_til_ready blocking: %s%d, count = %d\n",
- CTC_TTY_NAME, info->line, info->count);
-#endif
- schedule();
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&info->open_wait, &wait);
- if (!tty_hung_up_p(filp))
- info->count++;
- info->blocked_open--;
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_block_til_ready after blocking: %s%d, count = %d\n",
- CTC_TTY_NAME, info->line, info->count);
-#endif
- if (retval)
- return retval;
- info->flags |= CTC_ASYNC_NORMAL_ACTIVE;
- return 0;
-}
-
-/*
- * This routine is called whenever a serial port is opened. It
- * enables interrupts for a serial port, linking in its async structure into
- * the IRQ chain. It also performs the serial-specific
- * initialization for the tty structure.
- */
-static int
-ctc_tty_open(struct tty_struct *tty, struct file *filp)
-{
- ctc_tty_info *info;
- unsigned long saveflags;
- int retval,
- line;
-
- DBF_TEXT(trace, 3, __FUNCTION__);
- line = tty->index;
- if (line < 0 || line > CTC_TTY_MAX_DEVICES)
- return -ENODEV;
- info = &driver->info[line];
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_open"))
- return -ENODEV;
- if (!info->netdev)
- return -ENODEV;
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_open %s, count = %d\n", tty->name,
- info->count);
-#endif
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- info->count++;
- tty->driver_data = info;
- info->tty = tty;
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
- /*
- * Start up serial port
- */
- retval = ctc_tty_startup(info);
- if (retval) {
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_open return after startup\n");
-#endif
- return retval;
- }
- retval = ctc_tty_block_til_ready(tty, filp, info);
- if (retval) {
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_open return after ctc_tty_block_til_ready \n");
-#endif
- return retval;
- }
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_open %s successful...\n", tty->name);
-#endif
- return 0;
-}
-
-static void
-ctc_tty_close(struct tty_struct *tty, struct file *filp)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
- ulong flags;
- ulong timeout;
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (!info || ctc_tty_paranoia_check(info, tty->name, "ctc_tty_close"))
- return;
- spin_lock_irqsave(&ctc_tty_lock, flags);
- if (tty_hung_up_p(filp)) {
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_close return after tty_hung_up_p\n");
-#endif
- return;
- }
- if ((tty->count == 1) && (info->count != 1)) {
- /*
- * Uh, oh. tty->count is 1, which means that the tty
- * structure will be freed. Info->count should always
- * be one in these conditions. If it's greater than
- * one, we've got real problems, since it means the
- * serial port won't be shutdown.
- */
- printk(KERN_ERR "ctc_tty_close: bad port count; tty->count is 1, "
- "info->count is %d\n", info->count);
- info->count = 1;
- }
- if (--info->count < 0) {
- printk(KERN_ERR "ctc_tty_close: bad port count for %s%d: %d\n",
- CTC_TTY_NAME, info->line, info->count);
- info->count = 0;
- }
- if (info->count) {
- local_irq_restore(flags);
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_close after info->count != 0\n");
-#endif
- return;
- }
- info->flags |= CTC_ASYNC_CLOSING;
- tty->closing = 1;
- /*
- * At this point we stop accepting input. To do this, we
- * disable the receive line status interrupts, and tell the
- * interrupt driver to stop checking the data ready bit in the
- * line status register.
- */
- if (info->flags & CTC_ASYNC_INITIALIZED) {
- tty_wait_until_sent(tty, 30*HZ); /* 30 seconds timeout */
- /*
- * Before we drop DTR, make sure the UART transmitter
- * has completely drained; this is especially
- * important if there is a transmit FIFO!
- */
- timeout = jiffies + HZ;
- while (!(info->lsr & UART_LSR_TEMT)) {
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- msleep(500);
- spin_lock_irqsave(&ctc_tty_lock, flags);
- if (time_after(jiffies,timeout))
- break;
- }
- }
- ctc_tty_shutdown(info);
- if (tty->driver->flush_buffer) {
- skb_queue_purge(&info->tx_queue);
- info->lsr |= UART_LSR_TEMT;
- }
- tty_ldisc_flush(tty);
- info->tty = 0;
- tty->closing = 0;
- if (info->blocked_open) {
- msleep_interruptible(500);
- wake_up_interruptible(&info->open_wait);
- }
- info->flags &= ~(CTC_ASYNC_NORMAL_ACTIVE | CTC_ASYNC_CLOSING);
- wake_up_interruptible(&info->close_wait);
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_close normal exit\n");
-#endif
-}
-
-/*
- * ctc_tty_hangup() --- called by tty_hangup() when a hangup is signaled.
- */
-static void
-ctc_tty_hangup(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *)tty->driver_data;
- unsigned long saveflags;
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_hangup"))
- return;
- ctc_tty_shutdown(info);
- info->count = 0;
- info->flags &= ~CTC_ASYNC_NORMAL_ACTIVE;
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- info->tty = 0;
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
- wake_up_interruptible(&info->open_wait);
-}
-
-
-/*
- * For all online tty's, try sending data to
- * the lower levels.
- */
-static void
-ctc_tty_task(unsigned long arg)
-{
- ctc_tty_info *info = (void *)arg;
- unsigned long saveflags;
- int again;
-
- DBF_TEXT(trace, 3, __FUNCTION__);
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- if ((!ctc_tty_shuttingdown) && info) {
- again = ctc_tty_tint(info);
- if (!again)
- info->lsr |= UART_LSR_TEMT;
- again |= ctc_tty_readmodem(info);
- if (again) {
- tasklet_schedule(&info->tasklet);
- }
- }
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
-}
-
-static struct tty_operations ctc_ops = {
- .open = ctc_tty_open,
- .close = ctc_tty_close,
- .write = ctc_tty_write,
- .flush_chars = ctc_tty_flush_chars,
- .write_room = ctc_tty_write_room,
- .chars_in_buffer = ctc_tty_chars_in_buffer,
- .flush_buffer = ctc_tty_flush_buffer,
- .ioctl = ctc_tty_ioctl,
- .throttle = ctc_tty_throttle,
- .unthrottle = ctc_tty_unthrottle,
- .set_termios = ctc_tty_set_termios,
- .hangup = ctc_tty_hangup,
- .tiocmget = ctc_tty_tiocmget,
- .tiocmset = ctc_tty_tiocmset,
-};
-
-int
-ctc_tty_init(void)
-{
- int i;
- ctc_tty_info *info;
- struct tty_driver *device;
-
- DBF_TEXT(trace, 2, __FUNCTION__);
- driver = kmalloc(sizeof(ctc_tty_driver), GFP_KERNEL);
- if (driver == NULL) {
- printk(KERN_WARNING "Out of memory in ctc_tty_modem_init\n");
- return -ENOMEM;
- }
- memset(driver, 0, sizeof(ctc_tty_driver));
- device = alloc_tty_driver(CTC_TTY_MAX_DEVICES);
- if (!device) {
- kfree(driver);
- printk(KERN_WARNING "Out of memory in ctc_tty_modem_init\n");
- return -ENOMEM;
- }
-
- device->devfs_name = "ctc/" CTC_TTY_NAME;
- device->name = CTC_TTY_NAME;
- device->major = CTC_TTY_MAJOR;
- device->minor_start = 0;
- device->type = TTY_DRIVER_TYPE_SERIAL;
- device->subtype = SERIAL_TYPE_NORMAL;
- device->init_termios = tty_std_termios;
- device->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- device->flags = TTY_DRIVER_REAL_RAW;
- device->driver_name = "ctc_tty",
- tty_set_operations(device, &ctc_ops);
- if (tty_register_driver(device)) {
- printk(KERN_WARNING "ctc_tty: Couldn't register serial-device\n");
- put_tty_driver(device);
- kfree(driver);
- return -1;
- }
- driver->ctc_tty_device = device;
- for (i = 0; i < CTC_TTY_MAX_DEVICES; i++) {
- info = &driver->info[i];
- init_MUTEX(&info->write_sem);
- tasklet_init(&info->tasklet, ctc_tty_task,
- (unsigned long) info);
- info->magic = CTC_ASYNC_MAGIC;
- info->line = i;
- info->tty = 0;
- info->count = 0;
- info->blocked_open = 0;
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
- skb_queue_head_init(&info->tx_queue);
- skb_queue_head_init(&info->rx_queue);
- init_timer(&info->stoptimer);
- info->stoptimer.function = ctc_tty_stopdev;
- info->stoptimer.data = (unsigned long)info;
- info->mcr = UART_MCR_RTS;
- }
- return 0;
-}
-
-int
-ctc_tty_register_netdev(struct net_device *dev) {
- int ttynum;
- char *err;
- char *p;
-
- DBF_TEXT(trace, 2, __FUNCTION__);
- if ((!dev) || (!dev->name)) {
- printk(KERN_WARNING
- "ctc_tty_register_netdev called "
- "with NULL dev or NULL dev-name\n");
- return -1;
- }
-
- /*
- * If the name is a format string the caller wants us to
- * do a name allocation : format string must end with %d
- */
- if (strchr(dev->name, '%'))
- {
- int err = dev_alloc_name(dev, dev->name); // dev->name is changed by this
- if (err < 0) {
- printk(KERN_DEBUG "dev_alloc returned error %d\n", err);
- return err;
- }
-
- }
-
- for (p = dev->name; p && ((*p < '0') || (*p > '9')); p++);
- ttynum = simple_strtoul(p, &err, 0);
- if ((ttynum < 0) || (ttynum >= CTC_TTY_MAX_DEVICES) ||
- (err && *err)) {
- printk(KERN_WARNING
- "ctc_tty_register_netdev called "
- "with number in name '%s'\n", dev->name);
- return -1;
- }
- if (driver->info[ttynum].netdev) {
- printk(KERN_WARNING
- "ctc_tty_register_netdev called "
- "for already registered device '%s'\n",
- dev->name);
- return -1;
- }
- driver->info[ttynum].netdev = dev;
- return 0;
-}
-
-void
-ctc_tty_unregister_netdev(struct net_device *dev) {
- int i;
- unsigned long saveflags;
- ctc_tty_info *info = NULL;
-
- DBF_TEXT(trace, 2, __FUNCTION__);
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
- if (driver->info[i].netdev == dev) {
- info = &driver->info[i];
- break;
- }
- if (info) {
- info->netdev = NULL;
- skb_queue_purge(&info->tx_queue);
- skb_queue_purge(&info->rx_queue);
- }
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
-}
-
-void
-ctc_tty_cleanup(void) {
- unsigned long saveflags;
-
- DBF_TEXT(trace, 2, __FUNCTION__);
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- ctc_tty_shuttingdown = 1;
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
- tty_unregister_driver(driver->ctc_tty_device);
- put_tty_driver(driver->ctc_tty_device);
- kfree(driver);
- driver = NULL;
-}
diff --git a/drivers/s390/net/ctctty.h b/drivers/s390/net/ctctty.h
deleted file mode 100644
index 7254dc0..0000000
--- a/drivers/s390/net/ctctty.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * CTC / ESCON network driver, tty interface.
- *
- * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
- *
- * 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _CTCTTY_H_
-#define _CTCTTY_H_
-
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-
-extern int ctc_tty_register_netdev(struct net_device *);
-extern void ctc_tty_unregister_netdev(struct net_device *);
-extern void ctc_tty_netif_rx(struct sk_buff *);
-extern int ctc_tty_init(void);
-extern void ctc_tty_cleanup(void);
-extern void ctc_tty_setcarrier(struct net_device *, int);
-
-#endif
^ permalink raw reply related
* [patch 5/6] s390: remove tty support from ctc network device driver [1/2]
From: Frank Pavlic @ 2006-03-22 16:42 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-kernel, netdev
[patch 5/6] s390: remove tty support from ctc network device driver [1/2]
From: Peter Tiedemann <ptiedem@de.ibm.com>
[1/2]:
tty support code will be removed from the ctc network device driver.
Today we have a couple of alternatives which are performing much
better. The second thing is that ctc should be a network
device driver only.
We should not mix tty and networking here.
This first patch will remove the tty code from ctcmain.c .
It also removes the build entry from the Makefile as well as TTY
definitions from ctcmain.h.
The second patch will remove two files, ctctty.c and ctctty.h.
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
Makefile | 3 ++-
ctcmain.c | 45 +++++++++------------------------------------
ctcmain.h | 12 +++++-------
3 files changed, 16 insertions(+), 44 deletions(-)
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index 90d4d0e..6775a83 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -2,7 +2,7 @@
# S/390 network devices
#
-ctc-objs := ctcmain.o ctctty.o ctcdbug.o
+ctc-objs := ctcmain.o ctcdbug.o
obj-$(CONFIG_IUCV) += iucv.o
obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
@@ -10,6 +10,7 @@ obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o
obj-$(CONFIG_LCS) += lcs.o cu3088.o
obj-$(CONFIG_CLAW) += claw.o cu3088.o
+obj-$(CONFIG_MPC) += ctcmpc.o fsm.o cu3088.o
qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o
qeth-$(CONFIG_PROC_FS) += qeth_proc.o
obj-$(CONFIG_QETH) += qeth.o
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index af9f212..e2ccaf5 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -6,7 +6,7 @@
* Fixes by : Jochen Röhrig (roehrig@de.ibm.com)
* Arnaldo Carvalho de Melo <acme@conectiva.com.br>
Peter Tiedemann (ptiedem@de.ibm.com)
- * Driver Model stuff by : Cornelia Huck <huckc@de.ibm.com>
+ * Driver Model stuff by : Cornelia Huck <cornelia.huck@de.ibm.com>
*
* Documentation used:
* - Principles of Operation (IBM doc#: SA22-7201-06)
@@ -65,7 +65,6 @@
#include <asm/idals.h>
-#include "ctctty.h"
#include "fsm.h"
#include "cu3088.h"
@@ -479,10 +478,7 @@ ctc_unpack_skb(struct channel *ch, struc
skb->dev = pskb->dev;
skb->protocol = pskb->protocol;
pskb->ip_summed = CHECKSUM_UNNECESSARY;
- if (ch->protocol == CTC_PROTO_LINUX_TTY)
- ctc_tty_netif_rx(skb);
- else
- netif_rx_ni(skb);
+ netif_rx_ni(skb);
/**
* Successful rx; reset logflags
*/
@@ -557,8 +553,7 @@ ccw_unit_check(struct channel *ch, unsig
DBF_TEXT(trace, 5, __FUNCTION__);
if (sense & SNS0_INTERVENTION_REQ) {
if (sense & 0x01) {
- if (ch->protocol != CTC_PROTO_LINUX_TTY)
- ctc_pr_debug("%s: Interface disc. or Sel. reset "
+ ctc_pr_debug("%s: Interface disc. or Sel. reset "
"(remote)\n", ch->id);
fsm_event(ch->fsm, CH_EVENT_UC_RCRESET, ch);
} else {
@@ -2034,7 +2029,6 @@ static void
dev_action_chup(fsm_instance * fi, int event, void *arg)
{
struct net_device *dev = (struct net_device *) arg;
- struct ctc_priv *privptr = dev->priv;
DBF_TEXT(trace, 3, __FUNCTION__);
switch (fsm_getstate(fi)) {
@@ -2049,8 +2043,6 @@ dev_action_chup(fsm_instance * fi, int e
fsm_newstate(fi, DEV_STATE_RUNNING);
ctc_pr_info("%s: connected with remote side\n",
dev->name);
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- ctc_tty_setcarrier(dev, 1);
ctc_clear_busy(dev);
}
break;
@@ -2059,8 +2051,6 @@ dev_action_chup(fsm_instance * fi, int e
fsm_newstate(fi, DEV_STATE_RUNNING);
ctc_pr_info("%s: connected with remote side\n",
dev->name);
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- ctc_tty_setcarrier(dev, 1);
ctc_clear_busy(dev);
}
break;
@@ -2086,14 +2076,10 @@ dev_action_chup(fsm_instance * fi, int e
static void
dev_action_chdown(fsm_instance * fi, int event, void *arg)
{
- struct net_device *dev = (struct net_device *) arg;
- struct ctc_priv *privptr = dev->priv;
DBF_TEXT(trace, 3, __FUNCTION__);
switch (fsm_getstate(fi)) {
case DEV_STATE_RUNNING:
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- ctc_tty_setcarrier(dev, 0);
if (event == DEV_EVENT_TXDOWN)
fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);
else
@@ -2397,8 +2383,6 @@ ctc_tx(struct sk_buff *skb, struct net_d
*/
if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {
fsm_event(privptr->fsm, DEV_EVENT_START, dev);
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- return -EBUSY;
dev_kfree_skb(skb);
privptr->stats.tx_dropped++;
privptr->stats.tx_errors++;
@@ -2608,20 +2592,13 @@ ctc_netdev_unregister(struct net_device
if (!dev)
return;
privptr = (struct ctc_priv *) dev->priv;
- if (privptr->protocol != CTC_PROTO_LINUX_TTY)
- unregister_netdev(dev);
- else
- ctc_tty_unregister_netdev(dev);
+ unregister_netdev(dev);
}
static int
ctc_netdev_register(struct net_device * dev)
{
- struct ctc_priv *privptr = (struct ctc_priv *) dev->priv;
- if (privptr->protocol != CTC_PROTO_LINUX_TTY)
- return register_netdev(dev);
- else
- return ctc_tty_register_netdev(dev);
+ return register_netdev(dev);
}
static void
@@ -2667,7 +2644,9 @@ ctc_proto_store(struct device *dev, stru
if (!priv)
return -ENODEV;
sscanf(buf, "%u", &value);
- if ((value < 0) || (value > CTC_PROTO_MAX))
+ if (!((value == CTC_PROTO_S390) ||
+ (value == CTC_PROTO_LINUX) ||
+ (value == CTC_PROTO_OS390)))
return -EINVAL;
priv->protocol = value;
@@ -2897,10 +2876,7 @@ ctc_new_device(struct ccwgroup_device *c
goto out;
}
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- strlcpy(dev->name, "ctctty%d", IFNAMSIZ);
- else
- strlcpy(dev->name, "ctc%d", IFNAMSIZ);
+ strlcpy(dev->name, "ctc%d", IFNAMSIZ);
for (direction = READ; direction <= WRITE; direction++) {
privptr->channel[direction] =
@@ -3046,7 +3022,6 @@ ctc_exit(void)
{
DBF_TEXT(setup, 3, __FUNCTION__);
unregister_cu3088_discipline(&ctc_group_driver);
- ctc_tty_cleanup();
ctc_unregister_dbf_views();
ctc_pr_info("CTC driver unloaded\n");
}
@@ -3073,10 +3048,8 @@ ctc_init(void)
ctc_pr_crit("ctc_init failed with ctc_register_dbf_views rc = %d\n", ret);
return ret;
}
- ctc_tty_init();
ret = register_cu3088_discipline(&ctc_group_driver);
if (ret) {
- ctc_tty_cleanup();
ctc_unregister_dbf_views();
}
return ret;
diff --git a/drivers/s390/net/ctcmain.h b/drivers/s390/net/ctcmain.h
index d2e835c..7f305d1 100644
--- a/drivers/s390/net/ctcmain.h
+++ b/drivers/s390/net/ctcmain.h
@@ -35,7 +35,9 @@
#include <asm/ccwdev.h>
#include <asm/ccwgroup.h>
-#include "ctctty.h"
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+
#include "fsm.h"
#include "cu3088.h"
@@ -50,9 +52,7 @@
#define CTC_PROTO_S390 0
#define CTC_PROTO_LINUX 1
-#define CTC_PROTO_LINUX_TTY 2
#define CTC_PROTO_OS390 3
-#define CTC_PROTO_MAX 3
#define CTC_BUFSIZE_LIMIT 65535
#define CTC_BUFSIZE_DEFAULT 32768
@@ -257,15 +257,13 @@ static __inline__ void
ctc_clear_busy(struct net_device * dev)
{
clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy));
- if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)
- netif_wake_queue(dev);
+ netif_wake_queue(dev);
}
static __inline__ int
ctc_test_and_set_busy(struct net_device * dev)
{
- if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)
- netif_stop_queue(dev);
+ netif_stop_queue(dev);
return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy);
}
^ permalink raw reply related
* [patch 4/6] s390: qeth :allow setting of attribute "route6" to "no_router".
From: Frank Pavlic @ 2006-03-22 16:42 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-kernel, netdev
[patch 4/6] s390: qeth :allow setting of attribute "route6" to "no_router".
From: Ursula Braun <braunu@de.ibm.com>
when setting route6 attribute back to no_router qeth does not
issue an IP ASSIST command to reset router value to no_router.
Once primary_router is set device stays in this mode.
Issue an IP ASSIST command when no_router is set in route6.
Device will be reset and thus will not longer run as a primary
router.
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
qeth_main.c | 5 -----
1 files changed, 5 deletions(-)
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 69329ea..021cd5d 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -7339,11 +7339,6 @@ qeth_setrouting_v6(struct qeth_card *car
qeth_correct_routing_type(card, &card->options.route6.type,
QETH_PROT_IPV6);
- if ((card->options.route6.type == NO_ROUTER) ||
- ((card->info.type == QETH_CARD_TYPE_OSAE) &&
- (card->options.route6.type == MULTICAST_ROUTER) &&
- !qeth_is_supported6(card,IPA_OSA_MC_ROUTER)))
- return 0;
rc = qeth_send_setrouting(card, card->options.route6.type,
QETH_PROT_IPV6);
if (rc) {
^ permalink raw reply related
* [patch 3/6] s390: qeth driver cleanups
From: Frank Pavlic @ 2006-03-22 16:42 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-kernel
[patch 3/6] s390: qeth driver cleanups
From: Ursula Braun <braunu@de.ibm.com>
- code analyzing tool BEAM has found some unreachable
and unnecessary statements and also conditions
which are always true.
- removed some useless MII code since OSA card will never
allow to set such values.
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
qeth_main.c | 49 ++++---------------------------------------------
qeth_proc.c | 18 +++++++++---------
qeth_sys.c | 2 +-
3 files changed, 14 insertions(+), 55 deletions(-)
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 634c395..69329ea 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1364,7 +1364,7 @@ qeth_wait_for_buffer(struct qeth_channel
static void
qeth_clear_cmd_buffers(struct qeth_channel *channel)
{
- int cnt = 0;
+ int cnt;
for (cnt=0; cnt < QETH_CMD_BUFFER_NO; cnt++)
qeth_release_buffer(channel,&channel->iob[cnt]);
@@ -2814,11 +2814,11 @@ qeth_handle_send_error(struct qeth_card
QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
return QETH_SEND_ERROR_LINK_FAILURE;
case 3:
+ default:
QETH_DBF_TEXT(trace, 1, "SIGAcc3");
QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
return QETH_SEND_ERROR_KICK_IT;
}
- return QETH_SEND_ERROR_LINK_FAILURE;
}
void
@@ -3865,6 +3865,7 @@ qeth_get_cast_type(struct qeth_card *car
if ((hdr_mac == QETH_TR_MAC_NC) ||
(hdr_mac == QETH_TR_MAC_C))
return RTN_MULTICAST;
+ break;
/* eth or so multicast? */
default:
if ((hdr_mac == QETH_ETH_MAC_V4) ||
@@ -4586,38 +4587,11 @@ qeth_mdio_read(struct net_device *dev, i
case MII_NCONFIG: /* network interface config */
break;
default:
- rc = 0;
break;
}
return rc;
}
-static void
-qeth_mdio_write(struct net_device *dev, int phy_id, int regnum, int value)
-{
- switch(regnum){
- case MII_BMCR: /* Basic mode control register */
- case MII_BMSR: /* Basic mode status register */
- case MII_PHYSID1: /* PHYS ID 1 */
- case MII_PHYSID2: /* PHYS ID 2 */
- case MII_ADVERTISE: /* Advertisement control reg */
- case MII_LPA: /* Link partner ability reg */
- case MII_EXPANSION: /* Expansion register */
- case MII_DCOUNTER: /* disconnect counter */
- case MII_FCSCOUNTER: /* false carrier counter */
- case MII_NWAYTEST: /* N-way auto-neg test register */
- case MII_RERRCOUNTER: /* rx error counter */
- case MII_SREVISION: /* silicon revision */
- case MII_RESV1: /* reserved 1 */
- case MII_LBRERROR: /* loopback, rx, bypass error */
- case MII_PHYADDR: /* physical address */
- case MII_RESV2: /* reserved 2 */
- case MII_TPISTATUS: /* TPI status for 10mbps */
- case MII_NCONFIG: /* network interface config */
- default:
- break;
- }
-}
static inline const char *
qeth_arp_get_error_cause(int *rc)
@@ -5237,21 +5211,6 @@ qeth_do_ioctl(struct net_device *dev, st
mii_data->val_out = qeth_mdio_read(dev,mii_data->phy_id,
mii_data->reg_num);
break;
- case SIOCSMIIREG:
- rc = -EOPNOTSUPP;
- break;
- /* TODO: remove return if qeth_mdio_write does something */
- if (!capable(CAP_NET_ADMIN)){
- rc = -EPERM;
- break;
- }
- mii_data = if_mii(rq);
- if (mii_data->phy_id != 0)
- rc = -EINVAL;
- else
- qeth_mdio_write(dev, mii_data->phy_id, mii_data->reg_num,
- mii_data->val_in);
- break;
default:
rc = -EOPNOTSUPP;
}
@@ -6901,7 +6860,7 @@ qeth_send_setassparms(struct qeth_card *
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
if (len <= sizeof(__u32))
cmd->data.setassparms.data.flags_32bit = (__u32) data;
- else if (len > sizeof(__u32))
+ else /* (len > sizeof(__u32)) */
memcpy(&cmd->data.setassparms.data, (void *) data, len);
rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param);
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
index 1304641..360d782 100644
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -74,7 +74,7 @@ qeth_procfile_seq_next(struct seq_file *
static inline const char *
qeth_get_router_str(struct qeth_card *card, int ipv)
{
- int routing_type = 0;
+ enum qeth_routing_types routing_type = NO_ROUTER;
if (ipv == 4) {
routing_type = card->options.route4.type;
@@ -86,26 +86,26 @@ qeth_get_router_str(struct qeth_card *ca
#endif /* CONFIG_QETH_IPV6 */
}
- if (routing_type == PRIMARY_ROUTER)
+ switch (routing_type){
+ case PRIMARY_ROUTER:
return "pri";
- else if (routing_type == SECONDARY_ROUTER)
+ case SECONDARY_ROUTER:
return "sec";
- else if (routing_type == MULTICAST_ROUTER) {
+ case MULTICAST_ROUTER:
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
return "mc+";
return "mc";
- } else if (routing_type == PRIMARY_CONNECTOR) {
+ case PRIMARY_CONNECTOR:
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
return "p+c";
return "p.c";
- } else if (routing_type == SECONDARY_CONNECTOR) {
+ case SECONDARY_CONNECTOR:
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
return "s+c";
return "s.c";
- } else if (routing_type == NO_ROUTER)
+ default: /* NO_ROUTER */
return "no";
- else
- return "unk";
+ }
}
static int
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index c1831f5..f2a076a 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -115,7 +115,7 @@ qeth_dev_portno_store(struct device *dev
return -EPERM;
portno = simple_strtoul(buf, &tmp, 16);
- if ((portno < 0) || (portno > MAX_PORTNO)){
+ if (portno > MAX_PORTNO){
PRINT_WARN("portno 0x%X is out of range\n", portno);
return -EINVAL;
}
^ permalink raw reply related
* [patch 2/6] s390: qeth driver statistics fixes
From: Frank Pavlic @ 2006-03-22 16:42 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-kernel, netdev
[patch 2/6] s390: qeth driver statistics fixes
From: Ursula Braun <braunu@de.ibm.com>
- display "unsigned int" values in /proc/qeth_perf with %u instead of %i
- omit qdio header length when increasing card->stats.tx_bytes
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
qeth_main.c | 3 ++-
qeth_proc.c | 38 +++++++++++++++++++-------------------
2 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index dba7f7f..634c395 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -4419,6 +4419,7 @@ qeth_send_packet(struct qeth_card *card,
int elements_needed = 0;
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
struct qeth_eddp_context *ctx = NULL;
+ int tx_bytes = skb->len;
int rc;
QETH_DBF_TEXT(trace, 6, "sendpkt");
@@ -4499,7 +4500,7 @@ qeth_send_packet(struct qeth_card *card,
elements_needed, ctx);
if (!rc){
card->stats.tx_packets++;
- card->stats.tx_bytes += skb->len;
+ card->stats.tx_bytes += tx_bytes;
#ifdef CONFIG_QETH_PERF_STATS
if (skb_shinfo(skb)->tso_size &&
!(large_send == QETH_LARGE_SEND_NO)) {
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
index 3c6339d..1304641 100644
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -192,27 +192,27 @@ qeth_perf_procfile_seq_show(struct seq_f
CARD_DDEV_ID(card),
QETH_CARD_IFNAME(card)
);
- seq_printf(s, " Skb's/buffers received : %li/%i\n"
- " Skb's/buffers sent : %li/%i\n\n",
+ seq_printf(s, " Skb's/buffers received : %lu/%u\n"
+ " Skb's/buffers sent : %lu/%u\n\n",
card->stats.rx_packets, card->perf_stats.bufs_rec,
card->stats.tx_packets, card->perf_stats.bufs_sent
);
- seq_printf(s, " Skb's/buffers sent without packing : %li/%i\n"
- " Skb's/buffers sent with packing : %i/%i\n\n",
+ seq_printf(s, " Skb's/buffers sent without packing : %lu/%u\n"
+ " Skb's/buffers sent with packing : %u/%u\n\n",
card->stats.tx_packets - card->perf_stats.skbs_sent_pack,
card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack,
card->perf_stats.skbs_sent_pack,
card->perf_stats.bufs_sent_pack
);
- seq_printf(s, " Skbs sent in SG mode : %i\n"
- " Skb fragments sent in SG mode : %i\n\n",
+ seq_printf(s, " Skbs sent in SG mode : %u\n"
+ " Skb fragments sent in SG mode : %u\n\n",
card->perf_stats.sg_skbs_sent,
card->perf_stats.sg_frags_sent);
- seq_printf(s, " large_send tx (in Kbytes) : %i\n"
- " large_send count : %i\n\n",
+ seq_printf(s, " large_send tx (in Kbytes) : %u\n"
+ " large_send count : %u\n\n",
card->perf_stats.large_send_bytes >> 10,
card->perf_stats.large_send_cnt);
- seq_printf(s, " Packing state changes no pkg.->packing : %i/%i\n"
+ seq_printf(s, " Packing state changes no pkg.->packing : %u/%u\n"
" Watermarks L/H : %i/%i\n"
" Current buffer usage (outbound q's) : "
"%i/%i/%i/%i\n\n",
@@ -229,16 +229,16 @@ qeth_perf_procfile_seq_show(struct seq_f
atomic_read(&card->qdio.out_qs[3]->used_buffers)
: 0
);
- seq_printf(s, " Inbound handler time (in us) : %i\n"
- " Inbound handler count : %i\n"
- " Inbound do_QDIO time (in us) : %i\n"
- " Inbound do_QDIO count : %i\n\n"
- " Outbound handler time (in us) : %i\n"
- " Outbound handler count : %i\n\n"
- " Outbound time (in us, incl QDIO) : %i\n"
- " Outbound count : %i\n"
- " Outbound do_QDIO time (in us) : %i\n"
- " Outbound do_QDIO count : %i\n\n",
+ seq_printf(s, " Inbound handler time (in us) : %u\n"
+ " Inbound handler count : %u\n"
+ " Inbound do_QDIO time (in us) : %u\n"
+ " Inbound do_QDIO count : %u\n\n"
+ " Outbound handler time (in us) : %u\n"
+ " Outbound handler count : %u\n\n"
+ " Outbound time (in us, incl QDIO) : %u\n"
+ " Outbound count : %u\n"
+ " Outbound do_QDIO time (in us) : %u\n"
+ " Outbound do_QDIO count : %u\n\n",
card->perf_stats.inbound_time,
card->perf_stats.inbound_cnt,
card->perf_stats.inbound_do_qdio_time,
^ permalink raw reply related
* [patch 1/6] s390: minor claw driver fix
From: Frank Pavlic @ 2006-03-22 16:42 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-kernel
Hi ,
following 6 patches are for s390 network drivers claw, qeth and ctc.
tty support will be removed from the ctc network device driver , which will
happen with patch 5/6 and 6/6 . The latter one will remove two files , ctctty.c and ctctty.h .
Thanks
Frank
[patch 1/6] s390: minor claw driver fix
From: Frank Pavlic <fpavlic@de.ibm.com>
use CONFIG_ARCH_S390X instead of CONFIG_64BIT in function dumpit .
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
claw.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index a86436a..4687bb5 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -1601,7 +1601,7 @@ dumpit(char* buf, int len)
__u32 ct, sw, rm, dup;
char *ptr, *rptr;
char tbuf[82], tdup[82];
-#if (CONFIG_64BIT)
+#if (CONFIG_ARCH_S390X)
char addr[22];
#else
char addr[12];
@@ -1617,7 +1617,7 @@ dumpit(char* buf, int len)
dup = 0;
for ( ct=0; ct < len; ct++, ptr++, rptr++ ) {
if (sw == 0) {
-#if (CONFIG_64BIT)
+#if (CONFIG_ARCH_S390X)
sprintf(addr, "%16.16lX",(unsigned long)rptr);
#else
sprintf(addr, "%8.8X",(__u32)rptr);
@@ -1632,7 +1632,7 @@ dumpit(char* buf, int len)
if (sw == 8) {
strcat(bhex, " ");
}
-#if (CONFIG_64BIT)
+#if (CONFIG_ARCH_S390X)
sprintf(tbuf,"%2.2lX", (unsigned long)*ptr);
#else
sprintf(tbuf,"%2.2X", (__u32)*ptr);
^ permalink raw reply related
* Re: [patch 1/6] s390: minor claw driver fix
From: Christoph Hellwig @ 2006-03-22 16:28 UTC (permalink / raw)
To: Frank Pavlic; +Cc: Jeff Garzik, netdev, linux-kernel
In-Reply-To: <20060322160336.1becec81@localhost.localdomain>
On Wed, Mar 22, 2006 at 04:03:36PM +0100, Frank Pavlic wrote:
> Hi ,
> following 6 patches are for s390 network drivers claw, qeth and ctc.
> tty support will be removed from the ctc network device driver
Why?
^ permalink raw reply
* Re: [patch 1/6] s390: minor claw driver fix
From: Martin Schwidefsky @ 2006-03-22 15:42 UTC (permalink / raw)
To: Frank Pavlic; +Cc: Jeff Garzik, netdev, linux-kernel
In-Reply-To: <20060322162821.6ebd9af6@localhost.localdomain>
On 3/22/06, Frank Pavlic <fpavlic@de.ibm.com> wrote:
> [patch 1/6] s390: minor claw driver fix
>
> From: Frank Pavlic <fpavlic@de.ibm.com>
>
> use CONFIG_ARCH_S390X instead of CONFIG_64BIT in function dumpit .
Nack. CONFIG_ARCH_S390X doesn't exists anymore. It has been replaced
by CONFIG_64BIT in 2.6.16.
--
blue skies,
Martin
^ permalink raw reply
* [patch 6/6] s390: remove tty support from ctc network device driver [2/2]
From: Frank Pavlic @ 2006-03-22 15:28 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-kernel
[patch 6/6] s390: remove tty support from ctc network device driver [2/2]
From: Peter Tiedemann <ptiedem@de.ibm.com>
[2/2]: remove ctctty.c and ctctty.h files .
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
ctctty.c | 1259 ---------------------------------------------------------------
ctctty.h | 35 -
2 files changed, 1294 deletions(-)
diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c
deleted file mode 100644
index 5cdcdbf..0000000
--- a/drivers/s390/net/ctctty.c
+++ /dev/null
@@ -1,1259 +0,0 @@
-/*
- * CTC / ESCON network driver, tty interface.
- *
- * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
- *
- * 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial_reg.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <asm/uaccess.h>
-#include <linux/devfs_fs_kernel.h>
-#include "ctctty.h"
-#include "ctcdbug.h"
-
-#define CTC_TTY_MAJOR 43
-#define CTC_TTY_MAX_DEVICES 64
-
-#define CTC_ASYNC_MAGIC 0x49344C01 /* for paranoia-checking */
-#define CTC_ASYNC_INITIALIZED 0x80000000 /* port was initialized */
-#define CTC_ASYNC_NORMAL_ACTIVE 0x20000000 /* Normal device active */
-#define CTC_ASYNC_CLOSING 0x08000000 /* Serial port is closing */
-#define CTC_ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */
-#define CTC_ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */
-#define CTC_ASYNC_HUP_NOTIFY 0x0001 /* Notify tty on hangups/closes */
-#define CTC_ASYNC_NETDEV_OPEN 0x0002 /* Underlying netdev is open */
-#define CTC_ASYNC_TX_LINESTAT 0x0004 /* Must send line status */
-#define CTC_ASYNC_SPLIT_TERMIOS 0x0008 /* Sep. termios for dialin/out */
-#define CTC_TTY_XMIT_SIZE 1024 /* Default bufsize for write */
-#define CTC_SERIAL_XMIT_MAX 4000 /* Maximum bufsize for write */
-
-/* Private data (similar to async_struct in <linux/serial.h>) */
-typedef struct {
- int magic;
- int flags; /* defined in tty.h */
- int mcr; /* Modem control register */
- int msr; /* Modem status register */
- int lsr; /* Line status register */
- int line;
- int count; /* # of fd on device */
- int blocked_open; /* # of blocked opens */
- struct net_device *netdev;
- struct sk_buff_head tx_queue; /* transmit queue */
- struct sk_buff_head rx_queue; /* receive queue */
- struct tty_struct *tty; /* Pointer to corresponding tty */
- wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
- struct semaphore write_sem;
- struct tasklet_struct tasklet;
- struct timer_list stoptimer;
-} ctc_tty_info;
-
-/* Description of one CTC-tty */
-typedef struct {
- struct tty_driver *ctc_tty_device; /* tty-device */
- ctc_tty_info info[CTC_TTY_MAX_DEVICES]; /* Private data */
-} ctc_tty_driver;
-
-static ctc_tty_driver *driver;
-
-/* Leave this unchanged unless you know what you do! */
-#define MODEM_PARANOIA_CHECK
-#define MODEM_DO_RESTART
-
-#define CTC_TTY_NAME "ctctty"
-
-static __u32 ctc_tty_magic = CTC_ASYNC_MAGIC;
-static int ctc_tty_shuttingdown = 0;
-
-static spinlock_t ctc_tty_lock;
-
-/* ctc_tty_try_read() is called from within ctc_tty_rcv_skb()
- * to stuff incoming data directly into a tty's flip-buffer. If the
- * flip buffer is full, the packet gets queued up.
- *
- * Return:
- * 1 = Success
- * 0 = Failure, data has to be buffered and later processed by
- * ctc_tty_readmodem().
- */
-static int
-ctc_tty_try_read(ctc_tty_info * info, struct sk_buff *skb)
-{
- int len;
- struct tty_struct *tty;
-
- DBF_TEXT(trace, 5, __FUNCTION__);
- if ((tty = info->tty)) {
- if (info->mcr & UART_MCR_RTS) {
- len = skb->len;
- tty_insert_flip_string(tty, skb->data, len);
- tty_flip_buffer_push(tty);
- kfree_skb(skb);
- return 1;
- }
- }
- return 0;
-}
-
-/* ctc_tty_readmodem() is called periodically from within timer-interrupt.
- * It tries getting received data from the receive queue an stuff it into
- * the tty's flip-buffer.
- */
-static int
-ctc_tty_readmodem(ctc_tty_info *info)
-{
- int ret = 1;
- struct tty_struct *tty;
-
- DBF_TEXT(trace, 5, __FUNCTION__);
- if ((tty = info->tty)) {
- if (info->mcr & UART_MCR_RTS) {
- struct sk_buff *skb;
-
- if ((skb = skb_dequeue(&info->rx_queue))) {
- int len = skb->len;
- tty_insert_flip_string(tty, skb->data, len);
- skb_pull(skb, len);
- tty_flip_buffer_push(tty);
- if (skb->len > 0)
- skb_queue_head(&info->rx_queue, skb);
- else {
- kfree_skb(skb);
- ret = !skb_queue_empty(&info->rx_queue);
- }
- }
- }
- }
- return ret;
-}
-
-void
-ctc_tty_setcarrier(struct net_device *netdev, int on)
-{
- int i;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if ((!driver) || ctc_tty_shuttingdown)
- return;
- for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
- if (driver->info[i].netdev == netdev) {
- ctc_tty_info *info = &driver->info[i];
- if (on)
- info->msr |= UART_MSR_DCD;
- else
- info->msr &= ~UART_MSR_DCD;
- if ((info->flags & CTC_ASYNC_CHECK_CD) && (!on))
- tty_hangup(info->tty);
- }
-}
-
-void
-ctc_tty_netif_rx(struct sk_buff *skb)
-{
- int i;
- ctc_tty_info *info = NULL;
-
- DBF_TEXT(trace, 5, __FUNCTION__);
- if (!skb)
- return;
- if ((!skb->dev) || (!driver) || ctc_tty_shuttingdown) {
- dev_kfree_skb(skb);
- return;
- }
- for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
- if (driver->info[i].netdev == skb->dev) {
- info = &driver->info[i];
- break;
- }
- if (!info) {
- dev_kfree_skb(skb);
- return;
- }
- if (skb->len < 6) {
- dev_kfree_skb(skb);
- return;
- }
- if (memcmp(skb->data, &ctc_tty_magic, sizeof(__u32))) {
- dev_kfree_skb(skb);
- return;
- }
- skb_pull(skb, sizeof(__u32));
-
- i = *((int *)skb->data);
- skb_pull(skb, sizeof(info->mcr));
- if (i & UART_MCR_RTS) {
- info->msr |= UART_MSR_CTS;
- if (info->flags & CTC_ASYNC_CTS_FLOW)
- info->tty->hw_stopped = 0;
- } else {
- info->msr &= ~UART_MSR_CTS;
- if (info->flags & CTC_ASYNC_CTS_FLOW)
- info->tty->hw_stopped = 1;
- }
- if (i & UART_MCR_DTR)
- info->msr |= UART_MSR_DSR;
- else
- info->msr &= ~UART_MSR_DSR;
- if (skb->len <= 0) {
- kfree_skb(skb);
- return;
- }
- /* Try to deliver directly via tty-flip-buf if queue is empty */
- if (skb_queue_empty(&info->rx_queue))
- if (ctc_tty_try_read(info, skb))
- return;
- /* Direct deliver failed or queue wasn't empty.
- * Queue up for later dequeueing via timer-irq.
- */
- skb_queue_tail(&info->rx_queue, skb);
- /* Schedule dequeuing */
- tasklet_schedule(&info->tasklet);
-}
-
-static int
-ctc_tty_tint(ctc_tty_info * info)
-{
- struct sk_buff *skb = skb_dequeue(&info->tx_queue);
- int stopped = (info->tty->hw_stopped || info->tty->stopped);
- int wake = 1;
- int rc;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (!info->netdev) {
- if (skb)
- kfree_skb(skb);
- return 0;
- }
- if (info->flags & CTC_ASYNC_TX_LINESTAT) {
- int skb_res = info->netdev->hard_header_len +
- sizeof(info->mcr) + sizeof(__u32);
- /* If we must update line status,
- * create an empty dummy skb and insert it.
- */
- if (skb)
- skb_queue_head(&info->tx_queue, skb);
-
- skb = dev_alloc_skb(skb_res);
- if (!skb) {
- printk(KERN_WARNING
- "ctc_tty: Out of memory in %s%d tint\n",
- CTC_TTY_NAME, info->line);
- return 1;
- }
- skb_reserve(skb, skb_res);
- stopped = 0;
- wake = 0;
- }
- if (!skb)
- return 0;
- if (stopped) {
- skb_queue_head(&info->tx_queue, skb);
- return 1;
- }
-#if 0
- if (skb->len > 0)
- printk(KERN_DEBUG "tint: %d %02x\n", skb->len, *(skb->data));
- else
- printk(KERN_DEBUG "tint: %d STAT\n", skb->len);
-#endif
- memcpy(skb_push(skb, sizeof(info->mcr)), &info->mcr, sizeof(info->mcr));
- memcpy(skb_push(skb, sizeof(__u32)), &ctc_tty_magic, sizeof(__u32));
- rc = info->netdev->hard_start_xmit(skb, info->netdev);
- if (rc) {
- skb_pull(skb, sizeof(info->mcr) + sizeof(__u32));
- if (skb->len > 0)
- skb_queue_head(&info->tx_queue, skb);
- else
- kfree_skb(skb);
- } else {
- struct tty_struct *tty = info->tty;
-
- info->flags &= ~CTC_ASYNC_TX_LINESTAT;
- if (tty) {
- tty_wakeup(tty);
- }
- }
- return (skb_queue_empty(&info->tx_queue) ? 0 : 1);
-}
-
-/************************************************************
- *
- * Modem-functions
- *
- * mostly "stolen" from original Linux-serial.c and friends.
- *
- ************************************************************/
-
-static inline int
-ctc_tty_paranoia_check(ctc_tty_info * info, char *name, const char *routine)
-{
-#ifdef MODEM_PARANOIA_CHECK
- if (!info) {
- printk(KERN_WARNING "ctc_tty: null info_struct for %s in %s\n",
- name, routine);
- return 1;
- }
- if (info->magic != CTC_ASYNC_MAGIC) {
- printk(KERN_WARNING "ctc_tty: bad magic for info struct %s in %s\n",
- name, routine);
- return 1;
- }
-#endif
- return 0;
-}
-
-static void
-ctc_tty_inject(ctc_tty_info *info, char c)
-{
- int skb_res;
- struct sk_buff *skb;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_shuttingdown)
- return;
- skb_res = info->netdev->hard_header_len + sizeof(info->mcr) +
- sizeof(__u32) + 1;
- skb = dev_alloc_skb(skb_res);
- if (!skb) {
- printk(KERN_WARNING
- "ctc_tty: Out of memory in %s%d tx_inject\n",
- CTC_TTY_NAME, info->line);
- return;
- }
- skb_reserve(skb, skb_res);
- *(skb_put(skb, 1)) = c;
- skb_queue_head(&info->tx_queue, skb);
- tasklet_schedule(&info->tasklet);
-}
-
-static void
-ctc_tty_transmit_status(ctc_tty_info *info)
-{
- DBF_TEXT(trace, 5, __FUNCTION__);
- if (ctc_tty_shuttingdown)
- return;
- info->flags |= CTC_ASYNC_TX_LINESTAT;
- tasklet_schedule(&info->tasklet);
-}
-
-static void
-ctc_tty_change_speed(ctc_tty_info * info)
-{
- unsigned int cflag;
- unsigned int quot;
- int i;
-
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (!info->tty || !info->tty->termios)
- return;
- cflag = info->tty->termios->c_cflag;
-
- quot = i = cflag & CBAUD;
- if (i & CBAUDEX) {
- i &= ~CBAUDEX;
- if (i < 1 || i > 2)
- info->tty->termios->c_cflag &= ~CBAUDEX;
- else
- i += 15;
- }
- if (quot) {
- info->mcr |= UART_MCR_DTR;
- info->mcr |= UART_MCR_RTS;
- ctc_tty_transmit_status(info);
- } else {
- info->mcr &= ~UART_MCR_DTR;
- info->mcr &= ~UART_MCR_RTS;
- ctc_tty_transmit_status(info);
- return;
- }
-
- /* CTS flow control flag and modem status interrupts */
- if (cflag & CRTSCTS) {
- info->flags |= CTC_ASYNC_CTS_FLOW;
- } else
- info->flags &= ~CTC_ASYNC_CTS_FLOW;
- if (cflag & CLOCAL)
- info->flags &= ~CTC_ASYNC_CHECK_CD;
- else {
- info->flags |= CTC_ASYNC_CHECK_CD;
- }
-}
-
-static int
-ctc_tty_startup(ctc_tty_info * info)
-{
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (info->flags & CTC_ASYNC_INITIALIZED)
- return 0;
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "starting up %s%d ...\n", CTC_TTY_NAME, info->line);
-#endif
- /*
- * Now, initialize the UART
- */
- info->mcr = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
- /*
- * and set the speed of the serial port
- */
- ctc_tty_change_speed(info);
-
- info->flags |= CTC_ASYNC_INITIALIZED;
- if (!(info->flags & CTC_ASYNC_NETDEV_OPEN))
- info->netdev->open(info->netdev);
- info->flags |= CTC_ASYNC_NETDEV_OPEN;
- return 0;
-}
-
-static void
-ctc_tty_stopdev(unsigned long data)
-{
- ctc_tty_info *info = (ctc_tty_info *)data;
-
- if ((!info) || (!info->netdev) ||
- (info->flags & CTC_ASYNC_INITIALIZED))
- return;
- info->netdev->stop(info->netdev);
- info->flags &= ~CTC_ASYNC_NETDEV_OPEN;
-}
-
-/*
- * This routine will shutdown a serial port; interrupts are disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
- */
-static void
-ctc_tty_shutdown(ctc_tty_info * info)
-{
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (!(info->flags & CTC_ASYNC_INITIALIZED))
- return;
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "Shutting down %s%d ....\n", CTC_TTY_NAME, info->line);
-#endif
- info->msr &= ~UART_MSR_RI;
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
- info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS);
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
- mod_timer(&info->stoptimer, jiffies + (10 * HZ));
- skb_queue_purge(&info->tx_queue);
- skb_queue_purge(&info->rx_queue);
- info->flags &= ~CTC_ASYNC_INITIALIZED;
-}
-
-/* ctc_tty_write() is the main send-routine. It is called from the upper
- * levels within the kernel to perform sending data. Depending on the
- * online-flag it either directs output to the at-command-interpreter or
- * to the lower level. Additional tasks done here:
- * - If online, check for escape-sequence (+++)
- * - If sending audio-data, call ctc_tty_DLEdown() to parse DLE-codes.
- * - If receiving audio-data, call ctc_tty_end_vrx() to abort if needed.
- * - If dialing, abort dial.
- */
-static int
-ctc_tty_write(struct tty_struct *tty, const u_char * buf, int count)
-{
- int c;
- int total = 0;
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 5, __FUNCTION__);
- if (ctc_tty_shuttingdown)
- goto ex;
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write"))
- goto ex;
- if (!tty)
- goto ex;
- if (!info->netdev) {
- total = -ENODEV;
- goto ex;
- }
- while (1) {
- struct sk_buff *skb;
- int skb_res;
-
- c = (count < CTC_TTY_XMIT_SIZE) ? count : CTC_TTY_XMIT_SIZE;
- if (c <= 0)
- break;
-
- skb_res = info->netdev->hard_header_len + sizeof(info->mcr) +
- + sizeof(__u32);
- skb = dev_alloc_skb(skb_res + c);
- if (!skb) {
- printk(KERN_WARNING
- "ctc_tty: Out of memory in %s%d write\n",
- CTC_TTY_NAME, info->line);
- break;
- }
- skb_reserve(skb, skb_res);
- memcpy(skb_put(skb, c), buf, c);
- skb_queue_tail(&info->tx_queue, skb);
- buf += c;
- total += c;
- count -= c;
- }
- if (!skb_queue_empty(&info->tx_queue)) {
- info->lsr &= ~UART_LSR_TEMT;
- tasklet_schedule(&info->tasklet);
- }
-ex:
- DBF_TEXT(trace, 6, __FUNCTION__);
- return total;
-}
-
-static int
-ctc_tty_write_room(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write_room"))
- return 0;
- return CTC_TTY_XMIT_SIZE;
-}
-
-static int
-ctc_tty_chars_in_buffer(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_chars_in_buffer"))
- return 0;
- return 0;
-}
-
-static void
-ctc_tty_flush_buffer(struct tty_struct *tty)
-{
- ctc_tty_info *info;
- unsigned long flags;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (!tty)
- goto ex;
- spin_lock_irqsave(&ctc_tty_lock, flags);
- info = (ctc_tty_info *) tty->driver_data;
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_buffer")) {
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- goto ex;
- }
- skb_queue_purge(&info->tx_queue);
- info->lsr |= UART_LSR_TEMT;
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- wake_up_interruptible(&tty->write_wait);
- tty_wakeup(tty);
-ex:
- DBF_TEXT_(trace, 2, "ex: %s ", __FUNCTION__);
- return;
-}
-
-static void
-ctc_tty_flush_chars(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_shuttingdown)
- return;
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_chars"))
- return;
- if (tty->stopped || tty->hw_stopped || skb_queue_empty(&info->tx_queue))
- return;
- tasklet_schedule(&info->tasklet);
-}
-
-/*
- * ------------------------------------------------------------
- * ctc_tty_throttle()
- *
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void
-ctc_tty_throttle(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_throttle"))
- return;
- info->mcr &= ~UART_MCR_RTS;
- if (I_IXOFF(tty))
- ctc_tty_inject(info, STOP_CHAR(tty));
- ctc_tty_transmit_status(info);
-}
-
-static void
-ctc_tty_unthrottle(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_unthrottle"))
- return;
- info->mcr |= UART_MCR_RTS;
- if (I_IXOFF(tty))
- ctc_tty_inject(info, START_CHAR(tty));
- ctc_tty_transmit_status(info);
-}
-
-/*
- * ------------------------------------------------------------
- * ctc_tty_ioctl() and friends
- * ------------------------------------------------------------
- */
-
-/*
- * ctc_tty_get_lsr_info - get line status register info
- *
- * Purpose: Let user call ioctl() to get info when the UART physically
- * is emptied. On bus types like RS485, the transmitter must
- * release the bus after transmitting. This must be done when
- * the transmit shift register is empty, not be done when the
- * transmit holding register is empty. This functionality
- * allows RS485 driver to be written in user space.
- */
-static int
-ctc_tty_get_lsr_info(ctc_tty_info * info, uint __user *value)
-{
- u_char status;
- uint result;
- ulong flags;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- spin_lock_irqsave(&ctc_tty_lock, flags);
- status = info->lsr;
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
- put_user(result, value);
- return 0;
-}
-
-
-static int ctc_tty_tiocmget(struct tty_struct *tty, struct file *file)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
- u_char control,
- status;
- uint result;
- ulong flags;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
- return -ENODEV;
- if (tty->flags & (1 << TTY_IO_ERROR))
- return -EIO;
-
- control = info->mcr;
- spin_lock_irqsave(&ctc_tty_lock, flags);
- status = info->msr;
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
- | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
- | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
- | ((status & UART_MSR_RI) ? TIOCM_RNG : 0)
- | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0)
- | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
- return result;
-}
-
-static int
-ctc_tty_tiocmset(struct tty_struct *tty, struct file *file,
- unsigned int set, unsigned int clear)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
- return -ENODEV;
- if (tty->flags & (1 << TTY_IO_ERROR))
- return -EIO;
-
- if (set & TIOCM_RTS)
- info->mcr |= UART_MCR_RTS;
- if (set & TIOCM_DTR)
- info->mcr |= UART_MCR_DTR;
-
- if (clear & TIOCM_RTS)
- info->mcr &= ~UART_MCR_RTS;
- if (clear & TIOCM_DTR)
- info->mcr &= ~UART_MCR_DTR;
-
- if ((set | clear) & (TIOCM_RTS|TIOCM_DTR))
- ctc_tty_transmit_status(info);
- return 0;
-}
-
-static int
-ctc_tty_ioctl(struct tty_struct *tty, struct file *file,
- uint cmd, ulong arg)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
- int error;
- int retval;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
- return -ENODEV;
- if (tty->flags & (1 << TTY_IO_ERROR))
- return -EIO;
- switch (cmd) {
- case TCSBRK: /* SVID version: non-zero arg --> no break */
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TCSBRK\n", CTC_TTY_NAME, info->line);
-#endif
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- return 0;
- case TCSBRKP: /* support for POSIX tcsendbreak() */
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TCSBRKP\n", CTC_TTY_NAME, info->line);
-#endif
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- return 0;
- case TIOCGSOFTCAR:
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TIOCGSOFTCAR\n", CTC_TTY_NAME,
- info->line);
-#endif
- error = put_user(C_CLOCAL(tty) ? 1 : 0, (ulong __user *) arg);
- return error;
- case TIOCSSOFTCAR:
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TIOCSSOFTCAR\n", CTC_TTY_NAME,
- info->line);
-#endif
- error = get_user(arg, (ulong __user *) arg);
- if (error)
- return error;
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- return 0;
- case TIOCSERGETLSR: /* Get line status register */
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TIOCSERGETLSR\n", CTC_TTY_NAME,
- info->line);
-#endif
- if (access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(uint)))
- return ctc_tty_get_lsr_info(info, (uint __user *) arg);
- else
- return -EFAULT;
- default:
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on %s%d\n", cmd,
- CTC_TTY_NAME, info->line);
-#endif
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static void
-ctc_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
- unsigned int cflag = tty->termios->c_cflag;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- ctc_tty_change_speed(info);
-
- /* Handle transition to B0 */
- if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) {
- info->mcr &= ~(UART_MCR_DTR|UART_MCR_RTS);
- ctc_tty_transmit_status(info);
- }
-
- /* Handle transition from B0 to other */
- if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
- info->mcr |= UART_MCR_DTR;
- if (!(tty->termios->c_cflag & CRTSCTS) ||
- !test_bit(TTY_THROTTLED, &tty->flags)) {
- info->mcr |= UART_MCR_RTS;
- }
- ctc_tty_transmit_status(info);
- }
-
- /* Handle turning off CRTSCTS */
- if ((old_termios->c_cflag & CRTSCTS) &&
- !(tty->termios->c_cflag & CRTSCTS))
- tty->hw_stopped = 0;
-}
-
-/*
- * ------------------------------------------------------------
- * ctc_tty_open() and friends
- * ------------------------------------------------------------
- */
-static int
-ctc_tty_block_til_ready(struct tty_struct *tty, struct file *filp, ctc_tty_info *info)
-{
- DECLARE_WAITQUEUE(wait, NULL);
- int do_clocal = 0;
- unsigned long flags;
- int retval;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- /*
- * 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) ||
- (info->flags & CTC_ASYNC_CLOSING)) {
- if (info->flags & CTC_ASYNC_CLOSING)
- wait_event(info->close_wait,
- !(info->flags & CTC_ASYNC_CLOSING));
-#ifdef MODEM_DO_RESTART
- if (info->flags & CTC_ASYNC_HUP_NOTIFY)
- return -EAGAIN;
- else
- return -ERESTARTSYS;
-#else
- return -EAGAIN;
-#endif
- }
- /*
- * If non-blocking mode is set, then make the check up front
- * and then exit.
- */
- if ((filp->f_flags & O_NONBLOCK) ||
- (tty->flags & (1 << TTY_IO_ERROR))) {
- info->flags |= CTC_ASYNC_NORMAL_ACTIVE;
- return 0;
- }
- if (tty->termios->c_cflag & CLOCAL)
- do_clocal = 1;
- /*
- * Block waiting for the carrier detect and the line to become
- * free (i.e., not in use by the callout). While we are in
- * this loop, info->count is dropped by one, so that
- * ctc_tty_close() knows when to free things. We restore it upon
- * exit, either normal or abnormal.
- */
- retval = 0;
- add_wait_queue(&info->open_wait, &wait);
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_block_til_ready before block: %s%d, count = %d\n",
- CTC_TTY_NAME, info->line, info->count);
-#endif
- spin_lock_irqsave(&ctc_tty_lock, flags);
- if (!(tty_hung_up_p(filp)))
- info->count--;
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- info->blocked_open++;
- while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) ||
- !(info->flags & CTC_ASYNC_INITIALIZED)) {
-#ifdef MODEM_DO_RESTART
- if (info->flags & CTC_ASYNC_HUP_NOTIFY)
- retval = -EAGAIN;
- else
- retval = -ERESTARTSYS;
-#else
- retval = -EAGAIN;
-#endif
- break;
- }
- if (!(info->flags & CTC_ASYNC_CLOSING) &&
- (do_clocal || (info->msr & UART_MSR_DCD))) {
- break;
- }
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_block_til_ready blocking: %s%d, count = %d\n",
- CTC_TTY_NAME, info->line, info->count);
-#endif
- schedule();
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&info->open_wait, &wait);
- if (!tty_hung_up_p(filp))
- info->count++;
- info->blocked_open--;
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_block_til_ready after blocking: %s%d, count = %d\n",
- CTC_TTY_NAME, info->line, info->count);
-#endif
- if (retval)
- return retval;
- info->flags |= CTC_ASYNC_NORMAL_ACTIVE;
- return 0;
-}
-
-/*
- * This routine is called whenever a serial port is opened. It
- * enables interrupts for a serial port, linking in its async structure into
- * the IRQ chain. It also performs the serial-specific
- * initialization for the tty structure.
- */
-static int
-ctc_tty_open(struct tty_struct *tty, struct file *filp)
-{
- ctc_tty_info *info;
- unsigned long saveflags;
- int retval,
- line;
-
- DBF_TEXT(trace, 3, __FUNCTION__);
- line = tty->index;
- if (line < 0 || line > CTC_TTY_MAX_DEVICES)
- return -ENODEV;
- info = &driver->info[line];
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_open"))
- return -ENODEV;
- if (!info->netdev)
- return -ENODEV;
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_open %s, count = %d\n", tty->name,
- info->count);
-#endif
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- info->count++;
- tty->driver_data = info;
- info->tty = tty;
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
- /*
- * Start up serial port
- */
- retval = ctc_tty_startup(info);
- if (retval) {
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_open return after startup\n");
-#endif
- return retval;
- }
- retval = ctc_tty_block_til_ready(tty, filp, info);
- if (retval) {
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_open return after ctc_tty_block_til_ready \n");
-#endif
- return retval;
- }
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_open %s successful...\n", tty->name);
-#endif
- return 0;
-}
-
-static void
-ctc_tty_close(struct tty_struct *tty, struct file *filp)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
- ulong flags;
- ulong timeout;
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (!info || ctc_tty_paranoia_check(info, tty->name, "ctc_tty_close"))
- return;
- spin_lock_irqsave(&ctc_tty_lock, flags);
- if (tty_hung_up_p(filp)) {
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_close return after tty_hung_up_p\n");
-#endif
- return;
- }
- if ((tty->count == 1) && (info->count != 1)) {
- /*
- * Uh, oh. tty->count is 1, which means that the tty
- * structure will be freed. Info->count should always
- * be one in these conditions. If it's greater than
- * one, we've got real problems, since it means the
- * serial port won't be shutdown.
- */
- printk(KERN_ERR "ctc_tty_close: bad port count; tty->count is 1, "
- "info->count is %d\n", info->count);
- info->count = 1;
- }
- if (--info->count < 0) {
- printk(KERN_ERR "ctc_tty_close: bad port count for %s%d: %d\n",
- CTC_TTY_NAME, info->line, info->count);
- info->count = 0;
- }
- if (info->count) {
- local_irq_restore(flags);
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_close after info->count != 0\n");
-#endif
- return;
- }
- info->flags |= CTC_ASYNC_CLOSING;
- tty->closing = 1;
- /*
- * At this point we stop accepting input. To do this, we
- * disable the receive line status interrupts, and tell the
- * interrupt driver to stop checking the data ready bit in the
- * line status register.
- */
- if (info->flags & CTC_ASYNC_INITIALIZED) {
- tty_wait_until_sent(tty, 30*HZ); /* 30 seconds timeout */
- /*
- * Before we drop DTR, make sure the UART transmitter
- * has completely drained; this is especially
- * important if there is a transmit FIFO!
- */
- timeout = jiffies + HZ;
- while (!(info->lsr & UART_LSR_TEMT)) {
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- msleep(500);
- spin_lock_irqsave(&ctc_tty_lock, flags);
- if (time_after(jiffies,timeout))
- break;
- }
- }
- ctc_tty_shutdown(info);
- if (tty->driver->flush_buffer) {
- skb_queue_purge(&info->tx_queue);
- info->lsr |= UART_LSR_TEMT;
- }
- tty_ldisc_flush(tty);
- info->tty = 0;
- tty->closing = 0;
- if (info->blocked_open) {
- msleep_interruptible(500);
- wake_up_interruptible(&info->open_wait);
- }
- info->flags &= ~(CTC_ASYNC_NORMAL_ACTIVE | CTC_ASYNC_CLOSING);
- wake_up_interruptible(&info->close_wait);
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_close normal exit\n");
-#endif
-}
-
-/*
- * ctc_tty_hangup() --- called by tty_hangup() when a hangup is signaled.
- */
-static void
-ctc_tty_hangup(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *)tty->driver_data;
- unsigned long saveflags;
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_hangup"))
- return;
- ctc_tty_shutdown(info);
- info->count = 0;
- info->flags &= ~CTC_ASYNC_NORMAL_ACTIVE;
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- info->tty = 0;
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
- wake_up_interruptible(&info->open_wait);
-}
-
-
-/*
- * For all online tty's, try sending data to
- * the lower levels.
- */
-static void
-ctc_tty_task(unsigned long arg)
-{
- ctc_tty_info *info = (void *)arg;
- unsigned long saveflags;
- int again;
-
- DBF_TEXT(trace, 3, __FUNCTION__);
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- if ((!ctc_tty_shuttingdown) && info) {
- again = ctc_tty_tint(info);
- if (!again)
- info->lsr |= UART_LSR_TEMT;
- again |= ctc_tty_readmodem(info);
- if (again) {
- tasklet_schedule(&info->tasklet);
- }
- }
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
-}
-
-static struct tty_operations ctc_ops = {
- .open = ctc_tty_open,
- .close = ctc_tty_close,
- .write = ctc_tty_write,
- .flush_chars = ctc_tty_flush_chars,
- .write_room = ctc_tty_write_room,
- .chars_in_buffer = ctc_tty_chars_in_buffer,
- .flush_buffer = ctc_tty_flush_buffer,
- .ioctl = ctc_tty_ioctl,
- .throttle = ctc_tty_throttle,
- .unthrottle = ctc_tty_unthrottle,
- .set_termios = ctc_tty_set_termios,
- .hangup = ctc_tty_hangup,
- .tiocmget = ctc_tty_tiocmget,
- .tiocmset = ctc_tty_tiocmset,
-};
-
-int
-ctc_tty_init(void)
-{
- int i;
- ctc_tty_info *info;
- struct tty_driver *device;
-
- DBF_TEXT(trace, 2, __FUNCTION__);
- driver = kmalloc(sizeof(ctc_tty_driver), GFP_KERNEL);
- if (driver == NULL) {
- printk(KERN_WARNING "Out of memory in ctc_tty_modem_init\n");
- return -ENOMEM;
- }
- memset(driver, 0, sizeof(ctc_tty_driver));
- device = alloc_tty_driver(CTC_TTY_MAX_DEVICES);
- if (!device) {
- kfree(driver);
- printk(KERN_WARNING "Out of memory in ctc_tty_modem_init\n");
- return -ENOMEM;
- }
-
- device->devfs_name = "ctc/" CTC_TTY_NAME;
- device->name = CTC_TTY_NAME;
- device->major = CTC_TTY_MAJOR;
- device->minor_start = 0;
- device->type = TTY_DRIVER_TYPE_SERIAL;
- device->subtype = SERIAL_TYPE_NORMAL;
- device->init_termios = tty_std_termios;
- device->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- device->flags = TTY_DRIVER_REAL_RAW;
- device->driver_name = "ctc_tty",
- tty_set_operations(device, &ctc_ops);
- if (tty_register_driver(device)) {
- printk(KERN_WARNING "ctc_tty: Couldn't register serial-device\n");
- put_tty_driver(device);
- kfree(driver);
- return -1;
- }
- driver->ctc_tty_device = device;
- for (i = 0; i < CTC_TTY_MAX_DEVICES; i++) {
- info = &driver->info[i];
- init_MUTEX(&info->write_sem);
- tasklet_init(&info->tasklet, ctc_tty_task,
- (unsigned long) info);
- info->magic = CTC_ASYNC_MAGIC;
- info->line = i;
- info->tty = 0;
- info->count = 0;
- info->blocked_open = 0;
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
- skb_queue_head_init(&info->tx_queue);
- skb_queue_head_init(&info->rx_queue);
- init_timer(&info->stoptimer);
- info->stoptimer.function = ctc_tty_stopdev;
- info->stoptimer.data = (unsigned long)info;
- info->mcr = UART_MCR_RTS;
- }
- return 0;
-}
-
-int
-ctc_tty_register_netdev(struct net_device *dev) {
- int ttynum;
- char *err;
- char *p;
-
- DBF_TEXT(trace, 2, __FUNCTION__);
- if ((!dev) || (!dev->name)) {
- printk(KERN_WARNING
- "ctc_tty_register_netdev called "
- "with NULL dev or NULL dev-name\n");
- return -1;
- }
-
- /*
- * If the name is a format string the caller wants us to
- * do a name allocation : format string must end with %d
- */
- if (strchr(dev->name, '%'))
- {
- int err = dev_alloc_name(dev, dev->name); // dev->name is changed by this
- if (err < 0) {
- printk(KERN_DEBUG "dev_alloc returned error %d\n", err);
- return err;
- }
-
- }
-
- for (p = dev->name; p && ((*p < '0') || (*p > '9')); p++);
- ttynum = simple_strtoul(p, &err, 0);
- if ((ttynum < 0) || (ttynum >= CTC_TTY_MAX_DEVICES) ||
- (err && *err)) {
- printk(KERN_WARNING
- "ctc_tty_register_netdev called "
- "with number in name '%s'\n", dev->name);
- return -1;
- }
- if (driver->info[ttynum].netdev) {
- printk(KERN_WARNING
- "ctc_tty_register_netdev called "
- "for already registered device '%s'\n",
- dev->name);
- return -1;
- }
- driver->info[ttynum].netdev = dev;
- return 0;
-}
-
-void
-ctc_tty_unregister_netdev(struct net_device *dev) {
- int i;
- unsigned long saveflags;
- ctc_tty_info *info = NULL;
-
- DBF_TEXT(trace, 2, __FUNCTION__);
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
- if (driver->info[i].netdev == dev) {
- info = &driver->info[i];
- break;
- }
- if (info) {
- info->netdev = NULL;
- skb_queue_purge(&info->tx_queue);
- skb_queue_purge(&info->rx_queue);
- }
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
-}
-
-void
-ctc_tty_cleanup(void) {
- unsigned long saveflags;
-
- DBF_TEXT(trace, 2, __FUNCTION__);
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- ctc_tty_shuttingdown = 1;
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
- tty_unregister_driver(driver->ctc_tty_device);
- put_tty_driver(driver->ctc_tty_device);
- kfree(driver);
- driver = NULL;
-}
diff --git a/drivers/s390/net/ctctty.h b/drivers/s390/net/ctctty.h
deleted file mode 100644
index 7254dc0..0000000
--- a/drivers/s390/net/ctctty.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * CTC / ESCON network driver, tty interface.
- *
- * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
- *
- * 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _CTCTTY_H_
-#define _CTCTTY_H_
-
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-
-extern int ctc_tty_register_netdev(struct net_device *);
-extern void ctc_tty_unregister_netdev(struct net_device *);
-extern void ctc_tty_netif_rx(struct sk_buff *);
-extern int ctc_tty_init(void);
-extern void ctc_tty_cleanup(void);
-extern void ctc_tty_setcarrier(struct net_device *, int);
-
-#endif
^ permalink raw reply related
* [patch 5/6] s390: remove tty support from ctc network device driver [1/2]
From: Frank Pavlic @ 2006-03-22 15:28 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-kernel, netdev
[patch 5/6] s390: remove tty support from ctc network device driver [1/2]
From: Peter Tiedemann <ptiedem@de.ibm.com>
[1/2]:
tty support code will be removed from the ctc network device driver.
Today we have a couple of alternatives which are performing much
better. The second thing is that ctc should be a network
device driver only.
We should not mix tty and networking here.
This first patch will remove the tty code from ctcmain.c .
It also removes the build entry from the Makefile as well as TTY
definitions from ctcmain.h.
The second patch will remove two files, ctctty.c and ctctty.h.
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
Makefile | 3 ++-
ctcmain.c | 45 +++++++++------------------------------------
ctcmain.h | 12 +++++-------
3 files changed, 16 insertions(+), 44 deletions(-)
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index 90d4d0e..6775a83 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -2,7 +2,7 @@
# S/390 network devices
#
-ctc-objs := ctcmain.o ctctty.o ctcdbug.o
+ctc-objs := ctcmain.o ctcdbug.o
obj-$(CONFIG_IUCV) += iucv.o
obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
@@ -10,6 +10,7 @@ obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o
obj-$(CONFIG_LCS) += lcs.o cu3088.o
obj-$(CONFIG_CLAW) += claw.o cu3088.o
+obj-$(CONFIG_MPC) += ctcmpc.o fsm.o cu3088.o
qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o
qeth-$(CONFIG_PROC_FS) += qeth_proc.o
obj-$(CONFIG_QETH) += qeth.o
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index af9f212..e2ccaf5 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -6,7 +6,7 @@
* Fixes by : Jochen Röhrig (roehrig@de.ibm.com)
* Arnaldo Carvalho de Melo <acme@conectiva.com.br>
Peter Tiedemann (ptiedem@de.ibm.com)
- * Driver Model stuff by : Cornelia Huck <huckc@de.ibm.com>
+ * Driver Model stuff by : Cornelia Huck <cornelia.huck@de.ibm.com>
*
* Documentation used:
* - Principles of Operation (IBM doc#: SA22-7201-06)
@@ -65,7 +65,6 @@
#include <asm/idals.h>
-#include "ctctty.h"
#include "fsm.h"
#include "cu3088.h"
@@ -479,10 +478,7 @@ ctc_unpack_skb(struct channel *ch, struc
skb->dev = pskb->dev;
skb->protocol = pskb->protocol;
pskb->ip_summed = CHECKSUM_UNNECESSARY;
- if (ch->protocol == CTC_PROTO_LINUX_TTY)
- ctc_tty_netif_rx(skb);
- else
- netif_rx_ni(skb);
+ netif_rx_ni(skb);
/**
* Successful rx; reset logflags
*/
@@ -557,8 +553,7 @@ ccw_unit_check(struct channel *ch, unsig
DBF_TEXT(trace, 5, __FUNCTION__);
if (sense & SNS0_INTERVENTION_REQ) {
if (sense & 0x01) {
- if (ch->protocol != CTC_PROTO_LINUX_TTY)
- ctc_pr_debug("%s: Interface disc. or Sel. reset "
+ ctc_pr_debug("%s: Interface disc. or Sel. reset "
"(remote)\n", ch->id);
fsm_event(ch->fsm, CH_EVENT_UC_RCRESET, ch);
} else {
@@ -2034,7 +2029,6 @@ static void
dev_action_chup(fsm_instance * fi, int event, void *arg)
{
struct net_device *dev = (struct net_device *) arg;
- struct ctc_priv *privptr = dev->priv;
DBF_TEXT(trace, 3, __FUNCTION__);
switch (fsm_getstate(fi)) {
@@ -2049,8 +2043,6 @@ dev_action_chup(fsm_instance * fi, int e
fsm_newstate(fi, DEV_STATE_RUNNING);
ctc_pr_info("%s: connected with remote side\n",
dev->name);
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- ctc_tty_setcarrier(dev, 1);
ctc_clear_busy(dev);
}
break;
@@ -2059,8 +2051,6 @@ dev_action_chup(fsm_instance * fi, int e
fsm_newstate(fi, DEV_STATE_RUNNING);
ctc_pr_info("%s: connected with remote side\n",
dev->name);
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- ctc_tty_setcarrier(dev, 1);
ctc_clear_busy(dev);
}
break;
@@ -2086,14 +2076,10 @@ dev_action_chup(fsm_instance * fi, int e
static void
dev_action_chdown(fsm_instance * fi, int event, void *arg)
{
- struct net_device *dev = (struct net_device *) arg;
- struct ctc_priv *privptr = dev->priv;
DBF_TEXT(trace, 3, __FUNCTION__);
switch (fsm_getstate(fi)) {
case DEV_STATE_RUNNING:
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- ctc_tty_setcarrier(dev, 0);
if (event == DEV_EVENT_TXDOWN)
fsm_newstate(fi, DEV_STATE_STARTWAIT_TX);
else
@@ -2397,8 +2383,6 @@ ctc_tx(struct sk_buff *skb, struct net_d
*/
if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {
fsm_event(privptr->fsm, DEV_EVENT_START, dev);
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- return -EBUSY;
dev_kfree_skb(skb);
privptr->stats.tx_dropped++;
privptr->stats.tx_errors++;
@@ -2608,20 +2592,13 @@ ctc_netdev_unregister(struct net_device
if (!dev)
return;
privptr = (struct ctc_priv *) dev->priv;
- if (privptr->protocol != CTC_PROTO_LINUX_TTY)
- unregister_netdev(dev);
- else
- ctc_tty_unregister_netdev(dev);
+ unregister_netdev(dev);
}
static int
ctc_netdev_register(struct net_device * dev)
{
- struct ctc_priv *privptr = (struct ctc_priv *) dev->priv;
- if (privptr->protocol != CTC_PROTO_LINUX_TTY)
- return register_netdev(dev);
- else
- return ctc_tty_register_netdev(dev);
+ return register_netdev(dev);
}
static void
@@ -2667,7 +2644,9 @@ ctc_proto_store(struct device *dev, stru
if (!priv)
return -ENODEV;
sscanf(buf, "%u", &value);
- if ((value < 0) || (value > CTC_PROTO_MAX))
+ if (!((value == CTC_PROTO_S390) ||
+ (value == CTC_PROTO_LINUX) ||
+ (value == CTC_PROTO_OS390)))
return -EINVAL;
priv->protocol = value;
@@ -2897,10 +2876,7 @@ ctc_new_device(struct ccwgroup_device *c
goto out;
}
- if (privptr->protocol == CTC_PROTO_LINUX_TTY)
- strlcpy(dev->name, "ctctty%d", IFNAMSIZ);
- else
- strlcpy(dev->name, "ctc%d", IFNAMSIZ);
+ strlcpy(dev->name, "ctc%d", IFNAMSIZ);
for (direction = READ; direction <= WRITE; direction++) {
privptr->channel[direction] =
@@ -3046,7 +3022,6 @@ ctc_exit(void)
{
DBF_TEXT(setup, 3, __FUNCTION__);
unregister_cu3088_discipline(&ctc_group_driver);
- ctc_tty_cleanup();
ctc_unregister_dbf_views();
ctc_pr_info("CTC driver unloaded\n");
}
@@ -3073,10 +3048,8 @@ ctc_init(void)
ctc_pr_crit("ctc_init failed with ctc_register_dbf_views rc = %d\n", ret);
return ret;
}
- ctc_tty_init();
ret = register_cu3088_discipline(&ctc_group_driver);
if (ret) {
- ctc_tty_cleanup();
ctc_unregister_dbf_views();
}
return ret;
diff --git a/drivers/s390/net/ctcmain.h b/drivers/s390/net/ctcmain.h
index d2e835c..7f305d1 100644
--- a/drivers/s390/net/ctcmain.h
+++ b/drivers/s390/net/ctcmain.h
@@ -35,7 +35,9 @@
#include <asm/ccwdev.h>
#include <asm/ccwgroup.h>
-#include "ctctty.h"
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+
#include "fsm.h"
#include "cu3088.h"
@@ -50,9 +52,7 @@
#define CTC_PROTO_S390 0
#define CTC_PROTO_LINUX 1
-#define CTC_PROTO_LINUX_TTY 2
#define CTC_PROTO_OS390 3
-#define CTC_PROTO_MAX 3
#define CTC_BUFSIZE_LIMIT 65535
#define CTC_BUFSIZE_DEFAULT 32768
@@ -257,15 +257,13 @@ static __inline__ void
ctc_clear_busy(struct net_device * dev)
{
clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy));
- if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)
- netif_wake_queue(dev);
+ netif_wake_queue(dev);
}
static __inline__ int
ctc_test_and_set_busy(struct net_device * dev)
{
- if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY)
- netif_stop_queue(dev);
+ netif_stop_queue(dev);
return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy);
}
^ permalink raw reply related
* [patch 4/6] s390: qeth :allow setting of attribute "route6" to "no_router".
From: Frank Pavlic @ 2006-03-22 15:28 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-kernel, netdev
[patch 4/6] s390: qeth :allow setting of attribute "route6" to "no_router".
From: Ursula Braun <braunu@de.ibm.com>
when setting route6 attribute back to no_router qeth does not
issue an IP ASSIST command to reset router value to no_router.
Once primary_router is set device stays in this mode.
Issue an IP ASSIST command when no_router is set in route6.
Device will be reset and thus will not longer run as a primary
router.
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
qeth_main.c | 5 -----
1 files changed, 5 deletions(-)
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 69329ea..021cd5d 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -7339,11 +7339,6 @@ qeth_setrouting_v6(struct qeth_card *car
qeth_correct_routing_type(card, &card->options.route6.type,
QETH_PROT_IPV6);
- if ((card->options.route6.type == NO_ROUTER) ||
- ((card->info.type == QETH_CARD_TYPE_OSAE) &&
- (card->options.route6.type == MULTICAST_ROUTER) &&
- !qeth_is_supported6(card,IPA_OSA_MC_ROUTER)))
- return 0;
rc = qeth_send_setrouting(card, card->options.route6.type,
QETH_PROT_IPV6);
if (rc) {
^ permalink raw reply related
* [patch 3/6] s390: qeth driver cleanups
From: Frank Pavlic @ 2006-03-22 15:28 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-kernel
[patch 3/6] s390: qeth driver cleanups
From: Ursula Braun <braunu@de.ibm.com>
- code analyzing tool BEAM has found some unreachable
and unnecessary statements and also conditions
which are always true.
- removed some useless MII code since OSA card will never
allow to set such values.
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
qeth_main.c | 49 ++++---------------------------------------------
qeth_proc.c | 18 +++++++++---------
qeth_sys.c | 2 +-
3 files changed, 14 insertions(+), 55 deletions(-)
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 634c395..69329ea 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1364,7 +1364,7 @@ qeth_wait_for_buffer(struct qeth_channel
static void
qeth_clear_cmd_buffers(struct qeth_channel *channel)
{
- int cnt = 0;
+ int cnt;
for (cnt=0; cnt < QETH_CMD_BUFFER_NO; cnt++)
qeth_release_buffer(channel,&channel->iob[cnt]);
@@ -2814,11 +2814,11 @@ qeth_handle_send_error(struct qeth_card
QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
return QETH_SEND_ERROR_LINK_FAILURE;
case 3:
+ default:
QETH_DBF_TEXT(trace, 1, "SIGAcc3");
QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
return QETH_SEND_ERROR_KICK_IT;
}
- return QETH_SEND_ERROR_LINK_FAILURE;
}
void
@@ -3865,6 +3865,7 @@ qeth_get_cast_type(struct qeth_card *car
if ((hdr_mac == QETH_TR_MAC_NC) ||
(hdr_mac == QETH_TR_MAC_C))
return RTN_MULTICAST;
+ break;
/* eth or so multicast? */
default:
if ((hdr_mac == QETH_ETH_MAC_V4) ||
@@ -4586,38 +4587,11 @@ qeth_mdio_read(struct net_device *dev, i
case MII_NCONFIG: /* network interface config */
break;
default:
- rc = 0;
break;
}
return rc;
}
-static void
-qeth_mdio_write(struct net_device *dev, int phy_id, int regnum, int value)
-{
- switch(regnum){
- case MII_BMCR: /* Basic mode control register */
- case MII_BMSR: /* Basic mode status register */
- case MII_PHYSID1: /* PHYS ID 1 */
- case MII_PHYSID2: /* PHYS ID 2 */
- case MII_ADVERTISE: /* Advertisement control reg */
- case MII_LPA: /* Link partner ability reg */
- case MII_EXPANSION: /* Expansion register */
- case MII_DCOUNTER: /* disconnect counter */
- case MII_FCSCOUNTER: /* false carrier counter */
- case MII_NWAYTEST: /* N-way auto-neg test register */
- case MII_RERRCOUNTER: /* rx error counter */
- case MII_SREVISION: /* silicon revision */
- case MII_RESV1: /* reserved 1 */
- case MII_LBRERROR: /* loopback, rx, bypass error */
- case MII_PHYADDR: /* physical address */
- case MII_RESV2: /* reserved 2 */
- case MII_TPISTATUS: /* TPI status for 10mbps */
- case MII_NCONFIG: /* network interface config */
- default:
- break;
- }
-}
static inline const char *
qeth_arp_get_error_cause(int *rc)
@@ -5237,21 +5211,6 @@ qeth_do_ioctl(struct net_device *dev, st
mii_data->val_out = qeth_mdio_read(dev,mii_data->phy_id,
mii_data->reg_num);
break;
- case SIOCSMIIREG:
- rc = -EOPNOTSUPP;
- break;
- /* TODO: remove return if qeth_mdio_write does something */
- if (!capable(CAP_NET_ADMIN)){
- rc = -EPERM;
- break;
- }
- mii_data = if_mii(rq);
- if (mii_data->phy_id != 0)
- rc = -EINVAL;
- else
- qeth_mdio_write(dev, mii_data->phy_id, mii_data->reg_num,
- mii_data->val_in);
- break;
default:
rc = -EOPNOTSUPP;
}
@@ -6901,7 +6860,7 @@ qeth_send_setassparms(struct qeth_card *
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
if (len <= sizeof(__u32))
cmd->data.setassparms.data.flags_32bit = (__u32) data;
- else if (len > sizeof(__u32))
+ else /* (len > sizeof(__u32)) */
memcpy(&cmd->data.setassparms.data, (void *) data, len);
rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param);
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
index 1304641..360d782 100644
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -74,7 +74,7 @@ qeth_procfile_seq_next(struct seq_file *
static inline const char *
qeth_get_router_str(struct qeth_card *card, int ipv)
{
- int routing_type = 0;
+ enum qeth_routing_types routing_type = NO_ROUTER;
if (ipv == 4) {
routing_type = card->options.route4.type;
@@ -86,26 +86,26 @@ qeth_get_router_str(struct qeth_card *ca
#endif /* CONFIG_QETH_IPV6 */
}
- if (routing_type == PRIMARY_ROUTER)
+ switch (routing_type){
+ case PRIMARY_ROUTER:
return "pri";
- else if (routing_type == SECONDARY_ROUTER)
+ case SECONDARY_ROUTER:
return "sec";
- else if (routing_type == MULTICAST_ROUTER) {
+ case MULTICAST_ROUTER:
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
return "mc+";
return "mc";
- } else if (routing_type == PRIMARY_CONNECTOR) {
+ case PRIMARY_CONNECTOR:
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
return "p+c";
return "p.c";
- } else if (routing_type == SECONDARY_CONNECTOR) {
+ case SECONDARY_CONNECTOR:
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
return "s+c";
return "s.c";
- } else if (routing_type == NO_ROUTER)
+ default: /* NO_ROUTER */
return "no";
- else
- return "unk";
+ }
}
static int
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index c1831f5..f2a076a 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -115,7 +115,7 @@ qeth_dev_portno_store(struct device *dev
return -EPERM;
portno = simple_strtoul(buf, &tmp, 16);
- if ((portno < 0) || (portno > MAX_PORTNO)){
+ if (portno > MAX_PORTNO){
PRINT_WARN("portno 0x%X is out of range\n", portno);
return -EINVAL;
}
^ permalink raw reply related
* [patch 2/6] s390: qeth driver statistics fixes
From: Frank Pavlic @ 2006-03-22 15:28 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-kernel, netdev
[patch 2/6] s390: qeth driver statistics fixes
From: Ursula Braun <braunu@de.ibm.com>
- display "unsigned int" values in /proc/qeth_perf with %u instead of %i
- omit qdio header length when increasing card->stats.tx_bytes
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
qeth_main.c | 3 ++-
qeth_proc.c | 38 +++++++++++++++++++-------------------
2 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index dba7f7f..634c395 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -4419,6 +4419,7 @@ qeth_send_packet(struct qeth_card *card,
int elements_needed = 0;
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
struct qeth_eddp_context *ctx = NULL;
+ int tx_bytes = skb->len;
int rc;
QETH_DBF_TEXT(trace, 6, "sendpkt");
@@ -4499,7 +4500,7 @@ qeth_send_packet(struct qeth_card *card,
elements_needed, ctx);
if (!rc){
card->stats.tx_packets++;
- card->stats.tx_bytes += skb->len;
+ card->stats.tx_bytes += tx_bytes;
#ifdef CONFIG_QETH_PERF_STATS
if (skb_shinfo(skb)->tso_size &&
!(large_send == QETH_LARGE_SEND_NO)) {
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
index 3c6339d..1304641 100644
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -192,27 +192,27 @@ qeth_perf_procfile_seq_show(struct seq_f
CARD_DDEV_ID(card),
QETH_CARD_IFNAME(card)
);
- seq_printf(s, " Skb's/buffers received : %li/%i\n"
- " Skb's/buffers sent : %li/%i\n\n",
+ seq_printf(s, " Skb's/buffers received : %lu/%u\n"
+ " Skb's/buffers sent : %lu/%u\n\n",
card->stats.rx_packets, card->perf_stats.bufs_rec,
card->stats.tx_packets, card->perf_stats.bufs_sent
);
- seq_printf(s, " Skb's/buffers sent without packing : %li/%i\n"
- " Skb's/buffers sent with packing : %i/%i\n\n",
+ seq_printf(s, " Skb's/buffers sent without packing : %lu/%u\n"
+ " Skb's/buffers sent with packing : %u/%u\n\n",
card->stats.tx_packets - card->perf_stats.skbs_sent_pack,
card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack,
card->perf_stats.skbs_sent_pack,
card->perf_stats.bufs_sent_pack
);
- seq_printf(s, " Skbs sent in SG mode : %i\n"
- " Skb fragments sent in SG mode : %i\n\n",
+ seq_printf(s, " Skbs sent in SG mode : %u\n"
+ " Skb fragments sent in SG mode : %u\n\n",
card->perf_stats.sg_skbs_sent,
card->perf_stats.sg_frags_sent);
- seq_printf(s, " large_send tx (in Kbytes) : %i\n"
- " large_send count : %i\n\n",
+ seq_printf(s, " large_send tx (in Kbytes) : %u\n"
+ " large_send count : %u\n\n",
card->perf_stats.large_send_bytes >> 10,
card->perf_stats.large_send_cnt);
- seq_printf(s, " Packing state changes no pkg.->packing : %i/%i\n"
+ seq_printf(s, " Packing state changes no pkg.->packing : %u/%u\n"
" Watermarks L/H : %i/%i\n"
" Current buffer usage (outbound q's) : "
"%i/%i/%i/%i\n\n",
@@ -229,16 +229,16 @@ qeth_perf_procfile_seq_show(struct seq_f
atomic_read(&card->qdio.out_qs[3]->used_buffers)
: 0
);
- seq_printf(s, " Inbound handler time (in us) : %i\n"
- " Inbound handler count : %i\n"
- " Inbound do_QDIO time (in us) : %i\n"
- " Inbound do_QDIO count : %i\n\n"
- " Outbound handler time (in us) : %i\n"
- " Outbound handler count : %i\n\n"
- " Outbound time (in us, incl QDIO) : %i\n"
- " Outbound count : %i\n"
- " Outbound do_QDIO time (in us) : %i\n"
- " Outbound do_QDIO count : %i\n\n",
+ seq_printf(s, " Inbound handler time (in us) : %u\n"
+ " Inbound handler count : %u\n"
+ " Inbound do_QDIO time (in us) : %u\n"
+ " Inbound do_QDIO count : %u\n\n"
+ " Outbound handler time (in us) : %u\n"
+ " Outbound handler count : %u\n\n"
+ " Outbound time (in us, incl QDIO) : %u\n"
+ " Outbound count : %u\n"
+ " Outbound do_QDIO time (in us) : %u\n"
+ " Outbound do_QDIO count : %u\n\n",
card->perf_stats.inbound_time,
card->perf_stats.inbound_cnt,
card->perf_stats.inbound_do_qdio_time,
^ permalink raw reply related
* [patch 1/6] s390: minor claw driver fix
From: Frank Pavlic @ 2006-03-22 15:28 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-kernel
Hi ,
following 6 patches are for s390 network drivers claw, qeth and ctc.
tty support will be removed from the ctc network device driver , which will
happen with patch 5/6 and 6/6 . The latter one will remove two files , ctctty.c and ctctty.h .
Thanks
Frank
[patch 1/6] s390: minor claw driver fix
From: Frank Pavlic <fpavlic@de.ibm.com>
use CONFIG_ARCH_S390X instead of CONFIG_64BIT in function dumpit .
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
claw.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index a86436a..4687bb5 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -1601,7 +1601,7 @@ dumpit(char* buf, int len)
__u32 ct, sw, rm, dup;
char *ptr, *rptr;
char tbuf[82], tdup[82];
-#if (CONFIG_64BIT)
+#if (CONFIG_ARCH_S390X)
char addr[22];
#else
char addr[12];
@@ -1617,7 +1617,7 @@ dumpit(char* buf, int len)
dup = 0;
for ( ct=0; ct < len; ct++, ptr++, rptr++ ) {
if (sw == 0) {
-#if (CONFIG_64BIT)
+#if (CONFIG_ARCH_S390X)
sprintf(addr, "%16.16lX",(unsigned long)rptr);
#else
sprintf(addr, "%8.8X",(__u32)rptr);
@@ -1632,7 +1632,7 @@ dumpit(char* buf, int len)
if (sw == 8) {
strcat(bhex, " ");
}
-#if (CONFIG_64BIT)
+#if (CONFIG_ARCH_S390X)
sprintf(tbuf,"%2.2lX", (unsigned long)*ptr);
#else
sprintf(tbuf,"%2.2X", (__u32)*ptr);
^ permalink raw reply related
* Re: [PATCH 6/6 v2] IB: userspace support for RDMA connection manager
From: Roland Dreier @ 2006-03-22 15:18 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: netdev, linux-kernel, openib-general
In-Reply-To: <20060322083009.GF1802@mellanox.co.il>
Michael> BTW, is there some way to see your git tree e.g. with gitweb?
Sure,
http://www.kernel.org/git/?p=linux/kernel/git/roland/infiniband.git;a=summary
- R.
^ permalink raw reply
* [patch 6/6] s390: remove tty support from ctc network device driver [2/2]
From: Frank Pavlic @ 2006-03-22 15:03 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-kernel
[patch 6/6] s390: remove tty support from ctc network device driver [2/2]
From: Peter Tiedemann <ptiedem@de.ibm.com>
[2/2]: remove ctctty.c and ctctty.h files .
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
ctctty.c | 1259 ---------------------------------------------------------------
ctctty.h | 35 -
2 files changed, 1294 deletions(-)
diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c
deleted file mode 100644
index 5cdcdbf..0000000
--- a/drivers/s390/net/ctctty.c
+++ /dev/null
@@ -1,1259 +0,0 @@
-/*
- * CTC / ESCON network driver, tty interface.
- *
- * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
- *
- * 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial_reg.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <asm/uaccess.h>
-#include <linux/devfs_fs_kernel.h>
-#include "ctctty.h"
-#include "ctcdbug.h"
-
-#define CTC_TTY_MAJOR 43
-#define CTC_TTY_MAX_DEVICES 64
-
-#define CTC_ASYNC_MAGIC 0x49344C01 /* for paranoia-checking */
-#define CTC_ASYNC_INITIALIZED 0x80000000 /* port was initialized */
-#define CTC_ASYNC_NORMAL_ACTIVE 0x20000000 /* Normal device active */
-#define CTC_ASYNC_CLOSING 0x08000000 /* Serial port is closing */
-#define CTC_ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */
-#define CTC_ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */
-#define CTC_ASYNC_HUP_NOTIFY 0x0001 /* Notify tty on hangups/closes */
-#define CTC_ASYNC_NETDEV_OPEN 0x0002 /* Underlying netdev is open */
-#define CTC_ASYNC_TX_LINESTAT 0x0004 /* Must send line status */
-#define CTC_ASYNC_SPLIT_TERMIOS 0x0008 /* Sep. termios for dialin/out */
-#define CTC_TTY_XMIT_SIZE 1024 /* Default bufsize for write */
-#define CTC_SERIAL_XMIT_MAX 4000 /* Maximum bufsize for write */
-
-/* Private data (similar to async_struct in <linux/serial.h>) */
-typedef struct {
- int magic;
- int flags; /* defined in tty.h */
- int mcr; /* Modem control register */
- int msr; /* Modem status register */
- int lsr; /* Line status register */
- int line;
- int count; /* # of fd on device */
- int blocked_open; /* # of blocked opens */
- struct net_device *netdev;
- struct sk_buff_head tx_queue; /* transmit queue */
- struct sk_buff_head rx_queue; /* receive queue */
- struct tty_struct *tty; /* Pointer to corresponding tty */
- wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
- struct semaphore write_sem;
- struct tasklet_struct tasklet;
- struct timer_list stoptimer;
-} ctc_tty_info;
-
-/* Description of one CTC-tty */
-typedef struct {
- struct tty_driver *ctc_tty_device; /* tty-device */
- ctc_tty_info info[CTC_TTY_MAX_DEVICES]; /* Private data */
-} ctc_tty_driver;
-
-static ctc_tty_driver *driver;
-
-/* Leave this unchanged unless you know what you do! */
-#define MODEM_PARANOIA_CHECK
-#define MODEM_DO_RESTART
-
-#define CTC_TTY_NAME "ctctty"
-
-static __u32 ctc_tty_magic = CTC_ASYNC_MAGIC;
-static int ctc_tty_shuttingdown = 0;
-
-static spinlock_t ctc_tty_lock;
-
-/* ctc_tty_try_read() is called from within ctc_tty_rcv_skb()
- * to stuff incoming data directly into a tty's flip-buffer. If the
- * flip buffer is full, the packet gets queued up.
- *
- * Return:
- * 1 = Success
- * 0 = Failure, data has to be buffered and later processed by
- * ctc_tty_readmodem().
- */
-static int
-ctc_tty_try_read(ctc_tty_info * info, struct sk_buff *skb)
-{
- int len;
- struct tty_struct *tty;
-
- DBF_TEXT(trace, 5, __FUNCTION__);
- if ((tty = info->tty)) {
- if (info->mcr & UART_MCR_RTS) {
- len = skb->len;
- tty_insert_flip_string(tty, skb->data, len);
- tty_flip_buffer_push(tty);
- kfree_skb(skb);
- return 1;
- }
- }
- return 0;
-}
-
-/* ctc_tty_readmodem() is called periodically from within timer-interrupt.
- * It tries getting received data from the receive queue an stuff it into
- * the tty's flip-buffer.
- */
-static int
-ctc_tty_readmodem(ctc_tty_info *info)
-{
- int ret = 1;
- struct tty_struct *tty;
-
- DBF_TEXT(trace, 5, __FUNCTION__);
- if ((tty = info->tty)) {
- if (info->mcr & UART_MCR_RTS) {
- struct sk_buff *skb;
-
- if ((skb = skb_dequeue(&info->rx_queue))) {
- int len = skb->len;
- tty_insert_flip_string(tty, skb->data, len);
- skb_pull(skb, len);
- tty_flip_buffer_push(tty);
- if (skb->len > 0)
- skb_queue_head(&info->rx_queue, skb);
- else {
- kfree_skb(skb);
- ret = !skb_queue_empty(&info->rx_queue);
- }
- }
- }
- }
- return ret;
-}
-
-void
-ctc_tty_setcarrier(struct net_device *netdev, int on)
-{
- int i;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if ((!driver) || ctc_tty_shuttingdown)
- return;
- for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
- if (driver->info[i].netdev == netdev) {
- ctc_tty_info *info = &driver->info[i];
- if (on)
- info->msr |= UART_MSR_DCD;
- else
- info->msr &= ~UART_MSR_DCD;
- if ((info->flags & CTC_ASYNC_CHECK_CD) && (!on))
- tty_hangup(info->tty);
- }
-}
-
-void
-ctc_tty_netif_rx(struct sk_buff *skb)
-{
- int i;
- ctc_tty_info *info = NULL;
-
- DBF_TEXT(trace, 5, __FUNCTION__);
- if (!skb)
- return;
- if ((!skb->dev) || (!driver) || ctc_tty_shuttingdown) {
- dev_kfree_skb(skb);
- return;
- }
- for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
- if (driver->info[i].netdev == skb->dev) {
- info = &driver->info[i];
- break;
- }
- if (!info) {
- dev_kfree_skb(skb);
- return;
- }
- if (skb->len < 6) {
- dev_kfree_skb(skb);
- return;
- }
- if (memcmp(skb->data, &ctc_tty_magic, sizeof(__u32))) {
- dev_kfree_skb(skb);
- return;
- }
- skb_pull(skb, sizeof(__u32));
-
- i = *((int *)skb->data);
- skb_pull(skb, sizeof(info->mcr));
- if (i & UART_MCR_RTS) {
- info->msr |= UART_MSR_CTS;
- if (info->flags & CTC_ASYNC_CTS_FLOW)
- info->tty->hw_stopped = 0;
- } else {
- info->msr &= ~UART_MSR_CTS;
- if (info->flags & CTC_ASYNC_CTS_FLOW)
- info->tty->hw_stopped = 1;
- }
- if (i & UART_MCR_DTR)
- info->msr |= UART_MSR_DSR;
- else
- info->msr &= ~UART_MSR_DSR;
- if (skb->len <= 0) {
- kfree_skb(skb);
- return;
- }
- /* Try to deliver directly via tty-flip-buf if queue is empty */
- if (skb_queue_empty(&info->rx_queue))
- if (ctc_tty_try_read(info, skb))
- return;
- /* Direct deliver failed or queue wasn't empty.
- * Queue up for later dequeueing via timer-irq.
- */
- skb_queue_tail(&info->rx_queue, skb);
- /* Schedule dequeuing */
- tasklet_schedule(&info->tasklet);
-}
-
-static int
-ctc_tty_tint(ctc_tty_info * info)
-{
- struct sk_buff *skb = skb_dequeue(&info->tx_queue);
- int stopped = (info->tty->hw_stopped || info->tty->stopped);
- int wake = 1;
- int rc;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (!info->netdev) {
- if (skb)
- kfree_skb(skb);
- return 0;
- }
- if (info->flags & CTC_ASYNC_TX_LINESTAT) {
- int skb_res = info->netdev->hard_header_len +
- sizeof(info->mcr) + sizeof(__u32);
- /* If we must update line status,
- * create an empty dummy skb and insert it.
- */
- if (skb)
- skb_queue_head(&info->tx_queue, skb);
-
- skb = dev_alloc_skb(skb_res);
- if (!skb) {
- printk(KERN_WARNING
- "ctc_tty: Out of memory in %s%d tint\n",
- CTC_TTY_NAME, info->line);
- return 1;
- }
- skb_reserve(skb, skb_res);
- stopped = 0;
- wake = 0;
- }
- if (!skb)
- return 0;
- if (stopped) {
- skb_queue_head(&info->tx_queue, skb);
- return 1;
- }
-#if 0
- if (skb->len > 0)
- printk(KERN_DEBUG "tint: %d %02x\n", skb->len, *(skb->data));
- else
- printk(KERN_DEBUG "tint: %d STAT\n", skb->len);
-#endif
- memcpy(skb_push(skb, sizeof(info->mcr)), &info->mcr, sizeof(info->mcr));
- memcpy(skb_push(skb, sizeof(__u32)), &ctc_tty_magic, sizeof(__u32));
- rc = info->netdev->hard_start_xmit(skb, info->netdev);
- if (rc) {
- skb_pull(skb, sizeof(info->mcr) + sizeof(__u32));
- if (skb->len > 0)
- skb_queue_head(&info->tx_queue, skb);
- else
- kfree_skb(skb);
- } else {
- struct tty_struct *tty = info->tty;
-
- info->flags &= ~CTC_ASYNC_TX_LINESTAT;
- if (tty) {
- tty_wakeup(tty);
- }
- }
- return (skb_queue_empty(&info->tx_queue) ? 0 : 1);
-}
-
-/************************************************************
- *
- * Modem-functions
- *
- * mostly "stolen" from original Linux-serial.c and friends.
- *
- ************************************************************/
-
-static inline int
-ctc_tty_paranoia_check(ctc_tty_info * info, char *name, const char *routine)
-{
-#ifdef MODEM_PARANOIA_CHECK
- if (!info) {
- printk(KERN_WARNING "ctc_tty: null info_struct for %s in %s\n",
- name, routine);
- return 1;
- }
- if (info->magic != CTC_ASYNC_MAGIC) {
- printk(KERN_WARNING "ctc_tty: bad magic for info struct %s in %s\n",
- name, routine);
- return 1;
- }
-#endif
- return 0;
-}
-
-static void
-ctc_tty_inject(ctc_tty_info *info, char c)
-{
- int skb_res;
- struct sk_buff *skb;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_shuttingdown)
- return;
- skb_res = info->netdev->hard_header_len + sizeof(info->mcr) +
- sizeof(__u32) + 1;
- skb = dev_alloc_skb(skb_res);
- if (!skb) {
- printk(KERN_WARNING
- "ctc_tty: Out of memory in %s%d tx_inject\n",
- CTC_TTY_NAME, info->line);
- return;
- }
- skb_reserve(skb, skb_res);
- *(skb_put(skb, 1)) = c;
- skb_queue_head(&info->tx_queue, skb);
- tasklet_schedule(&info->tasklet);
-}
-
-static void
-ctc_tty_transmit_status(ctc_tty_info *info)
-{
- DBF_TEXT(trace, 5, __FUNCTION__);
- if (ctc_tty_shuttingdown)
- return;
- info->flags |= CTC_ASYNC_TX_LINESTAT;
- tasklet_schedule(&info->tasklet);
-}
-
-static void
-ctc_tty_change_speed(ctc_tty_info * info)
-{
- unsigned int cflag;
- unsigned int quot;
- int i;
-
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (!info->tty || !info->tty->termios)
- return;
- cflag = info->tty->termios->c_cflag;
-
- quot = i = cflag & CBAUD;
- if (i & CBAUDEX) {
- i &= ~CBAUDEX;
- if (i < 1 || i > 2)
- info->tty->termios->c_cflag &= ~CBAUDEX;
- else
- i += 15;
- }
- if (quot) {
- info->mcr |= UART_MCR_DTR;
- info->mcr |= UART_MCR_RTS;
- ctc_tty_transmit_status(info);
- } else {
- info->mcr &= ~UART_MCR_DTR;
- info->mcr &= ~UART_MCR_RTS;
- ctc_tty_transmit_status(info);
- return;
- }
-
- /* CTS flow control flag and modem status interrupts */
- if (cflag & CRTSCTS) {
- info->flags |= CTC_ASYNC_CTS_FLOW;
- } else
- info->flags &= ~CTC_ASYNC_CTS_FLOW;
- if (cflag & CLOCAL)
- info->flags &= ~CTC_ASYNC_CHECK_CD;
- else {
- info->flags |= CTC_ASYNC_CHECK_CD;
- }
-}
-
-static int
-ctc_tty_startup(ctc_tty_info * info)
-{
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (info->flags & CTC_ASYNC_INITIALIZED)
- return 0;
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "starting up %s%d ...\n", CTC_TTY_NAME, info->line);
-#endif
- /*
- * Now, initialize the UART
- */
- info->mcr = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
- /*
- * and set the speed of the serial port
- */
- ctc_tty_change_speed(info);
-
- info->flags |= CTC_ASYNC_INITIALIZED;
- if (!(info->flags & CTC_ASYNC_NETDEV_OPEN))
- info->netdev->open(info->netdev);
- info->flags |= CTC_ASYNC_NETDEV_OPEN;
- return 0;
-}
-
-static void
-ctc_tty_stopdev(unsigned long data)
-{
- ctc_tty_info *info = (ctc_tty_info *)data;
-
- if ((!info) || (!info->netdev) ||
- (info->flags & CTC_ASYNC_INITIALIZED))
- return;
- info->netdev->stop(info->netdev);
- info->flags &= ~CTC_ASYNC_NETDEV_OPEN;
-}
-
-/*
- * This routine will shutdown a serial port; interrupts are disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
- */
-static void
-ctc_tty_shutdown(ctc_tty_info * info)
-{
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (!(info->flags & CTC_ASYNC_INITIALIZED))
- return;
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "Shutting down %s%d ....\n", CTC_TTY_NAME, info->line);
-#endif
- info->msr &= ~UART_MSR_RI;
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
- info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS);
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
- mod_timer(&info->stoptimer, jiffies + (10 * HZ));
- skb_queue_purge(&info->tx_queue);
- skb_queue_purge(&info->rx_queue);
- info->flags &= ~CTC_ASYNC_INITIALIZED;
-}
-
-/* ctc_tty_write() is the main send-routine. It is called from the upper
- * levels within the kernel to perform sending data. Depending on the
- * online-flag it either directs output to the at-command-interpreter or
- * to the lower level. Additional tasks done here:
- * - If online, check for escape-sequence (+++)
- * - If sending audio-data, call ctc_tty_DLEdown() to parse DLE-codes.
- * - If receiving audio-data, call ctc_tty_end_vrx() to abort if needed.
- * - If dialing, abort dial.
- */
-static int
-ctc_tty_write(struct tty_struct *tty, const u_char * buf, int count)
-{
- int c;
- int total = 0;
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 5, __FUNCTION__);
- if (ctc_tty_shuttingdown)
- goto ex;
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write"))
- goto ex;
- if (!tty)
- goto ex;
- if (!info->netdev) {
- total = -ENODEV;
- goto ex;
- }
- while (1) {
- struct sk_buff *skb;
- int skb_res;
-
- c = (count < CTC_TTY_XMIT_SIZE) ? count : CTC_TTY_XMIT_SIZE;
- if (c <= 0)
- break;
-
- skb_res = info->netdev->hard_header_len + sizeof(info->mcr) +
- + sizeof(__u32);
- skb = dev_alloc_skb(skb_res + c);
- if (!skb) {
- printk(KERN_WARNING
- "ctc_tty: Out of memory in %s%d write\n",
- CTC_TTY_NAME, info->line);
- break;
- }
- skb_reserve(skb, skb_res);
- memcpy(skb_put(skb, c), buf, c);
- skb_queue_tail(&info->tx_queue, skb);
- buf += c;
- total += c;
- count -= c;
- }
- if (!skb_queue_empty(&info->tx_queue)) {
- info->lsr &= ~UART_LSR_TEMT;
- tasklet_schedule(&info->tasklet);
- }
-ex:
- DBF_TEXT(trace, 6, __FUNCTION__);
- return total;
-}
-
-static int
-ctc_tty_write_room(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_write_room"))
- return 0;
- return CTC_TTY_XMIT_SIZE;
-}
-
-static int
-ctc_tty_chars_in_buffer(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_chars_in_buffer"))
- return 0;
- return 0;
-}
-
-static void
-ctc_tty_flush_buffer(struct tty_struct *tty)
-{
- ctc_tty_info *info;
- unsigned long flags;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (!tty)
- goto ex;
- spin_lock_irqsave(&ctc_tty_lock, flags);
- info = (ctc_tty_info *) tty->driver_data;
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_buffer")) {
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- goto ex;
- }
- skb_queue_purge(&info->tx_queue);
- info->lsr |= UART_LSR_TEMT;
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- wake_up_interruptible(&tty->write_wait);
- tty_wakeup(tty);
-ex:
- DBF_TEXT_(trace, 2, "ex: %s ", __FUNCTION__);
- return;
-}
-
-static void
-ctc_tty_flush_chars(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_shuttingdown)
- return;
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_chars"))
- return;
- if (tty->stopped || tty->hw_stopped || skb_queue_empty(&info->tx_queue))
- return;
- tasklet_schedule(&info->tasklet);
-}
-
-/*
- * ------------------------------------------------------------
- * ctc_tty_throttle()
- *
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void
-ctc_tty_throttle(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_throttle"))
- return;
- info->mcr &= ~UART_MCR_RTS;
- if (I_IXOFF(tty))
- ctc_tty_inject(info, STOP_CHAR(tty));
- ctc_tty_transmit_status(info);
-}
-
-static void
-ctc_tty_unthrottle(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_unthrottle"))
- return;
- info->mcr |= UART_MCR_RTS;
- if (I_IXOFF(tty))
- ctc_tty_inject(info, START_CHAR(tty));
- ctc_tty_transmit_status(info);
-}
-
-/*
- * ------------------------------------------------------------
- * ctc_tty_ioctl() and friends
- * ------------------------------------------------------------
- */
-
-/*
- * ctc_tty_get_lsr_info - get line status register info
- *
- * Purpose: Let user call ioctl() to get info when the UART physically
- * is emptied. On bus types like RS485, the transmitter must
- * release the bus after transmitting. This must be done when
- * the transmit shift register is empty, not be done when the
- * transmit holding register is empty. This functionality
- * allows RS485 driver to be written in user space.
- */
-static int
-ctc_tty_get_lsr_info(ctc_tty_info * info, uint __user *value)
-{
- u_char status;
- uint result;
- ulong flags;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- spin_lock_irqsave(&ctc_tty_lock, flags);
- status = info->lsr;
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
- put_user(result, value);
- return 0;
-}
-
-
-static int ctc_tty_tiocmget(struct tty_struct *tty, struct file *file)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
- u_char control,
- status;
- uint result;
- ulong flags;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
- return -ENODEV;
- if (tty->flags & (1 << TTY_IO_ERROR))
- return -EIO;
-
- control = info->mcr;
- spin_lock_irqsave(&ctc_tty_lock, flags);
- status = info->msr;
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
- | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
- | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0)
- | ((status & UART_MSR_RI) ? TIOCM_RNG : 0)
- | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0)
- | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0);
- return result;
-}
-
-static int
-ctc_tty_tiocmset(struct tty_struct *tty, struct file *file,
- unsigned int set, unsigned int clear)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
- return -ENODEV;
- if (tty->flags & (1 << TTY_IO_ERROR))
- return -EIO;
-
- if (set & TIOCM_RTS)
- info->mcr |= UART_MCR_RTS;
- if (set & TIOCM_DTR)
- info->mcr |= UART_MCR_DTR;
-
- if (clear & TIOCM_RTS)
- info->mcr &= ~UART_MCR_RTS;
- if (clear & TIOCM_DTR)
- info->mcr &= ~UART_MCR_DTR;
-
- if ((set | clear) & (TIOCM_RTS|TIOCM_DTR))
- ctc_tty_transmit_status(info);
- return 0;
-}
-
-static int
-ctc_tty_ioctl(struct tty_struct *tty, struct file *file,
- uint cmd, ulong arg)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
- int error;
- int retval;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_ioctl"))
- return -ENODEV;
- if (tty->flags & (1 << TTY_IO_ERROR))
- return -EIO;
- switch (cmd) {
- case TCSBRK: /* SVID version: non-zero arg --> no break */
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TCSBRK\n", CTC_TTY_NAME, info->line);
-#endif
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- return 0;
- case TCSBRKP: /* support for POSIX tcsendbreak() */
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TCSBRKP\n", CTC_TTY_NAME, info->line);
-#endif
- retval = tty_check_change(tty);
- if (retval)
- return retval;
- tty_wait_until_sent(tty, 0);
- return 0;
- case TIOCGSOFTCAR:
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TIOCGSOFTCAR\n", CTC_TTY_NAME,
- info->line);
-#endif
- error = put_user(C_CLOCAL(tty) ? 1 : 0, (ulong __user *) arg);
- return error;
- case TIOCSSOFTCAR:
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TIOCSSOFTCAR\n", CTC_TTY_NAME,
- info->line);
-#endif
- error = get_user(arg, (ulong __user *) arg);
- if (error)
- return error;
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) |
- (arg ? CLOCAL : 0));
- return 0;
- case TIOCSERGETLSR: /* Get line status register */
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "%s%d ioctl TIOCSERGETLSR\n", CTC_TTY_NAME,
- info->line);
-#endif
- if (access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(uint)))
- return ctc_tty_get_lsr_info(info, (uint __user *) arg);
- else
- return -EFAULT;
- default:
-#ifdef CTC_DEBUG_MODEM_IOCTL
- printk(KERN_DEBUG "UNKNOWN ioctl 0x%08x on %s%d\n", cmd,
- CTC_TTY_NAME, info->line);
-#endif
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-static void
-ctc_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
- unsigned int cflag = tty->termios->c_cflag;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- ctc_tty_change_speed(info);
-
- /* Handle transition to B0 */
- if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) {
- info->mcr &= ~(UART_MCR_DTR|UART_MCR_RTS);
- ctc_tty_transmit_status(info);
- }
-
- /* Handle transition from B0 to other */
- if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
- info->mcr |= UART_MCR_DTR;
- if (!(tty->termios->c_cflag & CRTSCTS) ||
- !test_bit(TTY_THROTTLED, &tty->flags)) {
- info->mcr |= UART_MCR_RTS;
- }
- ctc_tty_transmit_status(info);
- }
-
- /* Handle turning off CRTSCTS */
- if ((old_termios->c_cflag & CRTSCTS) &&
- !(tty->termios->c_cflag & CRTSCTS))
- tty->hw_stopped = 0;
-}
-
-/*
- * ------------------------------------------------------------
- * ctc_tty_open() and friends
- * ------------------------------------------------------------
- */
-static int
-ctc_tty_block_til_ready(struct tty_struct *tty, struct file *filp, ctc_tty_info *info)
-{
- DECLARE_WAITQUEUE(wait, NULL);
- int do_clocal = 0;
- unsigned long flags;
- int retval;
-
- DBF_TEXT(trace, 4, __FUNCTION__);
- /*
- * 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) ||
- (info->flags & CTC_ASYNC_CLOSING)) {
- if (info->flags & CTC_ASYNC_CLOSING)
- wait_event(info->close_wait,
- !(info->flags & CTC_ASYNC_CLOSING));
-#ifdef MODEM_DO_RESTART
- if (info->flags & CTC_ASYNC_HUP_NOTIFY)
- return -EAGAIN;
- else
- return -ERESTARTSYS;
-#else
- return -EAGAIN;
-#endif
- }
- /*
- * If non-blocking mode is set, then make the check up front
- * and then exit.
- */
- if ((filp->f_flags & O_NONBLOCK) ||
- (tty->flags & (1 << TTY_IO_ERROR))) {
- info->flags |= CTC_ASYNC_NORMAL_ACTIVE;
- return 0;
- }
- if (tty->termios->c_cflag & CLOCAL)
- do_clocal = 1;
- /*
- * Block waiting for the carrier detect and the line to become
- * free (i.e., not in use by the callout). While we are in
- * this loop, info->count is dropped by one, so that
- * ctc_tty_close() knows when to free things. We restore it upon
- * exit, either normal or abnormal.
- */
- retval = 0;
- add_wait_queue(&info->open_wait, &wait);
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_block_til_ready before block: %s%d, count = %d\n",
- CTC_TTY_NAME, info->line, info->count);
-#endif
- spin_lock_irqsave(&ctc_tty_lock, flags);
- if (!(tty_hung_up_p(filp)))
- info->count--;
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- info->blocked_open++;
- while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) ||
- !(info->flags & CTC_ASYNC_INITIALIZED)) {
-#ifdef MODEM_DO_RESTART
- if (info->flags & CTC_ASYNC_HUP_NOTIFY)
- retval = -EAGAIN;
- else
- retval = -ERESTARTSYS;
-#else
- retval = -EAGAIN;
-#endif
- break;
- }
- if (!(info->flags & CTC_ASYNC_CLOSING) &&
- (do_clocal || (info->msr & UART_MSR_DCD))) {
- break;
- }
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_block_til_ready blocking: %s%d, count = %d\n",
- CTC_TTY_NAME, info->line, info->count);
-#endif
- schedule();
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&info->open_wait, &wait);
- if (!tty_hung_up_p(filp))
- info->count++;
- info->blocked_open--;
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_block_til_ready after blocking: %s%d, count = %d\n",
- CTC_TTY_NAME, info->line, info->count);
-#endif
- if (retval)
- return retval;
- info->flags |= CTC_ASYNC_NORMAL_ACTIVE;
- return 0;
-}
-
-/*
- * This routine is called whenever a serial port is opened. It
- * enables interrupts for a serial port, linking in its async structure into
- * the IRQ chain. It also performs the serial-specific
- * initialization for the tty structure.
- */
-static int
-ctc_tty_open(struct tty_struct *tty, struct file *filp)
-{
- ctc_tty_info *info;
- unsigned long saveflags;
- int retval,
- line;
-
- DBF_TEXT(trace, 3, __FUNCTION__);
- line = tty->index;
- if (line < 0 || line > CTC_TTY_MAX_DEVICES)
- return -ENODEV;
- info = &driver->info[line];
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_open"))
- return -ENODEV;
- if (!info->netdev)
- return -ENODEV;
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_open %s, count = %d\n", tty->name,
- info->count);
-#endif
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- info->count++;
- tty->driver_data = info;
- info->tty = tty;
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
- /*
- * Start up serial port
- */
- retval = ctc_tty_startup(info);
- if (retval) {
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_open return after startup\n");
-#endif
- return retval;
- }
- retval = ctc_tty_block_til_ready(tty, filp, info);
- if (retval) {
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_open return after ctc_tty_block_til_ready \n");
-#endif
- return retval;
- }
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_open %s successful...\n", tty->name);
-#endif
- return 0;
-}
-
-static void
-ctc_tty_close(struct tty_struct *tty, struct file *filp)
-{
- ctc_tty_info *info = (ctc_tty_info *) tty->driver_data;
- ulong flags;
- ulong timeout;
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (!info || ctc_tty_paranoia_check(info, tty->name, "ctc_tty_close"))
- return;
- spin_lock_irqsave(&ctc_tty_lock, flags);
- if (tty_hung_up_p(filp)) {
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_close return after tty_hung_up_p\n");
-#endif
- return;
- }
- if ((tty->count == 1) && (info->count != 1)) {
- /*
- * Uh, oh. tty->count is 1, which means that the tty
- * structure will be freed. Info->count should always
- * be one in these conditions. If it's greater than
- * one, we've got real problems, since it means the
- * serial port won't be shutdown.
- */
- printk(KERN_ERR "ctc_tty_close: bad port count; tty->count is 1, "
- "info->count is %d\n", info->count);
- info->count = 1;
- }
- if (--info->count < 0) {
- printk(KERN_ERR "ctc_tty_close: bad port count for %s%d: %d\n",
- CTC_TTY_NAME, info->line, info->count);
- info->count = 0;
- }
- if (info->count) {
- local_irq_restore(flags);
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_close after info->count != 0\n");
-#endif
- return;
- }
- info->flags |= CTC_ASYNC_CLOSING;
- tty->closing = 1;
- /*
- * At this point we stop accepting input. To do this, we
- * disable the receive line status interrupts, and tell the
- * interrupt driver to stop checking the data ready bit in the
- * line status register.
- */
- if (info->flags & CTC_ASYNC_INITIALIZED) {
- tty_wait_until_sent(tty, 30*HZ); /* 30 seconds timeout */
- /*
- * Before we drop DTR, make sure the UART transmitter
- * has completely drained; this is especially
- * important if there is a transmit FIFO!
- */
- timeout = jiffies + HZ;
- while (!(info->lsr & UART_LSR_TEMT)) {
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
- msleep(500);
- spin_lock_irqsave(&ctc_tty_lock, flags);
- if (time_after(jiffies,timeout))
- break;
- }
- }
- ctc_tty_shutdown(info);
- if (tty->driver->flush_buffer) {
- skb_queue_purge(&info->tx_queue);
- info->lsr |= UART_LSR_TEMT;
- }
- tty_ldisc_flush(tty);
- info->tty = 0;
- tty->closing = 0;
- if (info->blocked_open) {
- msleep_interruptible(500);
- wake_up_interruptible(&info->open_wait);
- }
- info->flags &= ~(CTC_ASYNC_NORMAL_ACTIVE | CTC_ASYNC_CLOSING);
- wake_up_interruptible(&info->close_wait);
- spin_unlock_irqrestore(&ctc_tty_lock, flags);
-#ifdef CTC_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "ctc_tty_close normal exit\n");
-#endif
-}
-
-/*
- * ctc_tty_hangup() --- called by tty_hangup() when a hangup is signaled.
- */
-static void
-ctc_tty_hangup(struct tty_struct *tty)
-{
- ctc_tty_info *info = (ctc_tty_info *)tty->driver_data;
- unsigned long saveflags;
- DBF_TEXT(trace, 3, __FUNCTION__);
- if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_hangup"))
- return;
- ctc_tty_shutdown(info);
- info->count = 0;
- info->flags &= ~CTC_ASYNC_NORMAL_ACTIVE;
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- info->tty = 0;
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
- wake_up_interruptible(&info->open_wait);
-}
-
-
-/*
- * For all online tty's, try sending data to
- * the lower levels.
- */
-static void
-ctc_tty_task(unsigned long arg)
-{
- ctc_tty_info *info = (void *)arg;
- unsigned long saveflags;
- int again;
-
- DBF_TEXT(trace, 3, __FUNCTION__);
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- if ((!ctc_tty_shuttingdown) && info) {
- again = ctc_tty_tint(info);
- if (!again)
- info->lsr |= UART_LSR_TEMT;
- again |= ctc_tty_readmodem(info);
- if (again) {
- tasklet_schedule(&info->tasklet);
- }
- }
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
-}
-
-static struct tty_operations ctc_ops = {
- .open = ctc_tty_open,
- .close = ctc_tty_close,
- .write = ctc_tty_write,
- .flush_chars = ctc_tty_flush_chars,
- .write_room = ctc_tty_write_room,
- .chars_in_buffer = ctc_tty_chars_in_buffer,
- .flush_buffer = ctc_tty_flush_buffer,
- .ioctl = ctc_tty_ioctl,
- .throttle = ctc_tty_throttle,
- .unthrottle = ctc_tty_unthrottle,
- .set_termios = ctc_tty_set_termios,
- .hangup = ctc_tty_hangup,
- .tiocmget = ctc_tty_tiocmget,
- .tiocmset = ctc_tty_tiocmset,
-};
-
-int
-ctc_tty_init(void)
-{
- int i;
- ctc_tty_info *info;
- struct tty_driver *device;
-
- DBF_TEXT(trace, 2, __FUNCTION__);
- driver = kmalloc(sizeof(ctc_tty_driver), GFP_KERNEL);
- if (driver == NULL) {
- printk(KERN_WARNING "Out of memory in ctc_tty_modem_init\n");
- return -ENOMEM;
- }
- memset(driver, 0, sizeof(ctc_tty_driver));
- device = alloc_tty_driver(CTC_TTY_MAX_DEVICES);
- if (!device) {
- kfree(driver);
- printk(KERN_WARNING "Out of memory in ctc_tty_modem_init\n");
- return -ENOMEM;
- }
-
- device->devfs_name = "ctc/" CTC_TTY_NAME;
- device->name = CTC_TTY_NAME;
- device->major = CTC_TTY_MAJOR;
- device->minor_start = 0;
- device->type = TTY_DRIVER_TYPE_SERIAL;
- device->subtype = SERIAL_TYPE_NORMAL;
- device->init_termios = tty_std_termios;
- device->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- device->flags = TTY_DRIVER_REAL_RAW;
- device->driver_name = "ctc_tty",
- tty_set_operations(device, &ctc_ops);
- if (tty_register_driver(device)) {
- printk(KERN_WARNING "ctc_tty: Couldn't register serial-device\n");
- put_tty_driver(device);
- kfree(driver);
- return -1;
- }
- driver->ctc_tty_device = device;
- for (i = 0; i < CTC_TTY_MAX_DEVICES; i++) {
- info = &driver->info[i];
- init_MUTEX(&info->write_sem);
- tasklet_init(&info->tasklet, ctc_tty_task,
- (unsigned long) info);
- info->magic = CTC_ASYNC_MAGIC;
- info->line = i;
- info->tty = 0;
- info->count = 0;
- info->blocked_open = 0;
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
- skb_queue_head_init(&info->tx_queue);
- skb_queue_head_init(&info->rx_queue);
- init_timer(&info->stoptimer);
- info->stoptimer.function = ctc_tty_stopdev;
- info->stoptimer.data = (unsigned long)info;
- info->mcr = UART_MCR_RTS;
- }
- return 0;
-}
-
-int
-ctc_tty_register_netdev(struct net_device *dev) {
- int ttynum;
- char *err;
- char *p;
-
- DBF_TEXT(trace, 2, __FUNCTION__);
- if ((!dev) || (!dev->name)) {
- printk(KERN_WARNING
- "ctc_tty_register_netdev called "
- "with NULL dev or NULL dev-name\n");
- return -1;
- }
-
- /*
- * If the name is a format string the caller wants us to
- * do a name allocation : format string must end with %d
- */
- if (strchr(dev->name, '%'))
- {
- int err = dev_alloc_name(dev, dev->name); // dev->name is changed by this
- if (err < 0) {
- printk(KERN_DEBUG "dev_alloc returned error %d\n", err);
- return err;
- }
-
- }
-
- for (p = dev->name; p && ((*p < '0') || (*p > '9')); p++);
- ttynum = simple_strtoul(p, &err, 0);
- if ((ttynum < 0) || (ttynum >= CTC_TTY_MAX_DEVICES) ||
- (err && *err)) {
- printk(KERN_WARNING
- "ctc_tty_register_netdev called "
- "with number in name '%s'\n", dev->name);
- return -1;
- }
- if (driver->info[ttynum].netdev) {
- printk(KERN_WARNING
- "ctc_tty_register_netdev called "
- "for already registered device '%s'\n",
- dev->name);
- return -1;
- }
- driver->info[ttynum].netdev = dev;
- return 0;
-}
-
-void
-ctc_tty_unregister_netdev(struct net_device *dev) {
- int i;
- unsigned long saveflags;
- ctc_tty_info *info = NULL;
-
- DBF_TEXT(trace, 2, __FUNCTION__);
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
- if (driver->info[i].netdev == dev) {
- info = &driver->info[i];
- break;
- }
- if (info) {
- info->netdev = NULL;
- skb_queue_purge(&info->tx_queue);
- skb_queue_purge(&info->rx_queue);
- }
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
-}
-
-void
-ctc_tty_cleanup(void) {
- unsigned long saveflags;
-
- DBF_TEXT(trace, 2, __FUNCTION__);
- spin_lock_irqsave(&ctc_tty_lock, saveflags);
- ctc_tty_shuttingdown = 1;
- spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
- tty_unregister_driver(driver->ctc_tty_device);
- put_tty_driver(driver->ctc_tty_device);
- kfree(driver);
- driver = NULL;
-}
diff --git a/drivers/s390/net/ctctty.h b/drivers/s390/net/ctctty.h
deleted file mode 100644
index 7254dc0..0000000
--- a/drivers/s390/net/ctctty.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * CTC / ESCON network driver, tty interface.
- *
- * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
- *
- * 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef _CTCTTY_H_
-#define _CTCTTY_H_
-
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-
-extern int ctc_tty_register_netdev(struct net_device *);
-extern void ctc_tty_unregister_netdev(struct net_device *);
-extern void ctc_tty_netif_rx(struct sk_buff *);
-extern int ctc_tty_init(void);
-extern void ctc_tty_cleanup(void);
-extern void ctc_tty_setcarrier(struct net_device *, int);
-
-#endif
^ permalink raw reply related
* [patch 4/6] s390: qeth :allow setting of attribute "route6" to "no_router".
From: Frank Pavlic @ 2006-03-22 15:03 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-kernel, netdev
[patch 4/6] s390: qeth :allow setting of attribute "route6" to "no_router".
From: Ursula Braun <braunu@de.ibm.com>
when setting route6 attribute back to no_router qeth does not
issue an IP ASSIST command to reset router value to no_router.
Once primary_router is set device stays in this mode.
Issue an IP ASSIST command when no_router is set in route6.
Device will be reset and thus will not longer run as a primary
router.
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
qeth_main.c | 5 -----
1 files changed, 5 deletions(-)
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 69329ea..021cd5d 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -7339,11 +7339,6 @@ qeth_setrouting_v6(struct qeth_card *car
qeth_correct_routing_type(card, &card->options.route6.type,
QETH_PROT_IPV6);
- if ((card->options.route6.type == NO_ROUTER) ||
- ((card->info.type == QETH_CARD_TYPE_OSAE) &&
- (card->options.route6.type == MULTICAST_ROUTER) &&
- !qeth_is_supported6(card,IPA_OSA_MC_ROUTER)))
- return 0;
rc = qeth_send_setrouting(card, card->options.route6.type,
QETH_PROT_IPV6);
if (rc) {
^ permalink raw reply related
* [patch 3/6] s390: qeth driver cleanups
From: Frank Pavlic @ 2006-03-22 15:03 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-kernel
[patch 3/6] s390: qeth driver cleanups
From: Ursula Braun <braunu@de.ibm.com>
- code analyzing tool BEAM has found some unreachable
and unnecessary statements and also conditions
which are always true.
- removed some useless MII code since OSA card will never
allow to set such values.
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
qeth_main.c | 49 ++++---------------------------------------------
qeth_proc.c | 18 +++++++++---------
qeth_sys.c | 2 +-
3 files changed, 14 insertions(+), 55 deletions(-)
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 634c395..69329ea 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1364,7 +1364,7 @@ qeth_wait_for_buffer(struct qeth_channel
static void
qeth_clear_cmd_buffers(struct qeth_channel *channel)
{
- int cnt = 0;
+ int cnt;
for (cnt=0; cnt < QETH_CMD_BUFFER_NO; cnt++)
qeth_release_buffer(channel,&channel->iob[cnt]);
@@ -2814,11 +2814,11 @@ qeth_handle_send_error(struct qeth_card
QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
return QETH_SEND_ERROR_LINK_FAILURE;
case 3:
+ default:
QETH_DBF_TEXT(trace, 1, "SIGAcc3");
QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
return QETH_SEND_ERROR_KICK_IT;
}
- return QETH_SEND_ERROR_LINK_FAILURE;
}
void
@@ -3865,6 +3865,7 @@ qeth_get_cast_type(struct qeth_card *car
if ((hdr_mac == QETH_TR_MAC_NC) ||
(hdr_mac == QETH_TR_MAC_C))
return RTN_MULTICAST;
+ break;
/* eth or so multicast? */
default:
if ((hdr_mac == QETH_ETH_MAC_V4) ||
@@ -4586,38 +4587,11 @@ qeth_mdio_read(struct net_device *dev, i
case MII_NCONFIG: /* network interface config */
break;
default:
- rc = 0;
break;
}
return rc;
}
-static void
-qeth_mdio_write(struct net_device *dev, int phy_id, int regnum, int value)
-{
- switch(regnum){
- case MII_BMCR: /* Basic mode control register */
- case MII_BMSR: /* Basic mode status register */
- case MII_PHYSID1: /* PHYS ID 1 */
- case MII_PHYSID2: /* PHYS ID 2 */
- case MII_ADVERTISE: /* Advertisement control reg */
- case MII_LPA: /* Link partner ability reg */
- case MII_EXPANSION: /* Expansion register */
- case MII_DCOUNTER: /* disconnect counter */
- case MII_FCSCOUNTER: /* false carrier counter */
- case MII_NWAYTEST: /* N-way auto-neg test register */
- case MII_RERRCOUNTER: /* rx error counter */
- case MII_SREVISION: /* silicon revision */
- case MII_RESV1: /* reserved 1 */
- case MII_LBRERROR: /* loopback, rx, bypass error */
- case MII_PHYADDR: /* physical address */
- case MII_RESV2: /* reserved 2 */
- case MII_TPISTATUS: /* TPI status for 10mbps */
- case MII_NCONFIG: /* network interface config */
- default:
- break;
- }
-}
static inline const char *
qeth_arp_get_error_cause(int *rc)
@@ -5237,21 +5211,6 @@ qeth_do_ioctl(struct net_device *dev, st
mii_data->val_out = qeth_mdio_read(dev,mii_data->phy_id,
mii_data->reg_num);
break;
- case SIOCSMIIREG:
- rc = -EOPNOTSUPP;
- break;
- /* TODO: remove return if qeth_mdio_write does something */
- if (!capable(CAP_NET_ADMIN)){
- rc = -EPERM;
- break;
- }
- mii_data = if_mii(rq);
- if (mii_data->phy_id != 0)
- rc = -EINVAL;
- else
- qeth_mdio_write(dev, mii_data->phy_id, mii_data->reg_num,
- mii_data->val_in);
- break;
default:
rc = -EOPNOTSUPP;
}
@@ -6901,7 +6860,7 @@ qeth_send_setassparms(struct qeth_card *
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
if (len <= sizeof(__u32))
cmd->data.setassparms.data.flags_32bit = (__u32) data;
- else if (len > sizeof(__u32))
+ else /* (len > sizeof(__u32)) */
memcpy(&cmd->data.setassparms.data, (void *) data, len);
rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param);
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
index 1304641..360d782 100644
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -74,7 +74,7 @@ qeth_procfile_seq_next(struct seq_file *
static inline const char *
qeth_get_router_str(struct qeth_card *card, int ipv)
{
- int routing_type = 0;
+ enum qeth_routing_types routing_type = NO_ROUTER;
if (ipv == 4) {
routing_type = card->options.route4.type;
@@ -86,26 +86,26 @@ qeth_get_router_str(struct qeth_card *ca
#endif /* CONFIG_QETH_IPV6 */
}
- if (routing_type == PRIMARY_ROUTER)
+ switch (routing_type){
+ case PRIMARY_ROUTER:
return "pri";
- else if (routing_type == SECONDARY_ROUTER)
+ case SECONDARY_ROUTER:
return "sec";
- else if (routing_type == MULTICAST_ROUTER) {
+ case MULTICAST_ROUTER:
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
return "mc+";
return "mc";
- } else if (routing_type == PRIMARY_CONNECTOR) {
+ case PRIMARY_CONNECTOR:
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
return "p+c";
return "p.c";
- } else if (routing_type == SECONDARY_CONNECTOR) {
+ case SECONDARY_CONNECTOR:
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
return "s+c";
return "s.c";
- } else if (routing_type == NO_ROUTER)
+ default: /* NO_ROUTER */
return "no";
- else
- return "unk";
+ }
}
static int
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index c1831f5..f2a076a 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -115,7 +115,7 @@ qeth_dev_portno_store(struct device *dev
return -EPERM;
portno = simple_strtoul(buf, &tmp, 16);
- if ((portno < 0) || (portno > MAX_PORTNO)){
+ if (portno > MAX_PORTNO){
PRINT_WARN("portno 0x%X is out of range\n", portno);
return -EINVAL;
}
^ permalink raw reply related
* [patch 2/6] s390: qeth driver statistics fixes
From: Frank Pavlic @ 2006-03-22 15:03 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-kernel, netdev
[patch 2/6] s390: qeth driver statistics fixes
From: Ursula Braun <braunu@de.ibm.com>
- display "unsigned int" values in /proc/qeth_perf with %u instead of %i
- omit qdio header length when increasing card->stats.tx_bytes
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
qeth_main.c | 3 ++-
qeth_proc.c | 38 +++++++++++++++++++-------------------
2 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index dba7f7f..634c395 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -4419,6 +4419,7 @@ qeth_send_packet(struct qeth_card *card,
int elements_needed = 0;
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
struct qeth_eddp_context *ctx = NULL;
+ int tx_bytes = skb->len;
int rc;
QETH_DBF_TEXT(trace, 6, "sendpkt");
@@ -4499,7 +4500,7 @@ qeth_send_packet(struct qeth_card *card,
elements_needed, ctx);
if (!rc){
card->stats.tx_packets++;
- card->stats.tx_bytes += skb->len;
+ card->stats.tx_bytes += tx_bytes;
#ifdef CONFIG_QETH_PERF_STATS
if (skb_shinfo(skb)->tso_size &&
!(large_send == QETH_LARGE_SEND_NO)) {
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
index 3c6339d..1304641 100644
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -192,27 +192,27 @@ qeth_perf_procfile_seq_show(struct seq_f
CARD_DDEV_ID(card),
QETH_CARD_IFNAME(card)
);
- seq_printf(s, " Skb's/buffers received : %li/%i\n"
- " Skb's/buffers sent : %li/%i\n\n",
+ seq_printf(s, " Skb's/buffers received : %lu/%u\n"
+ " Skb's/buffers sent : %lu/%u\n\n",
card->stats.rx_packets, card->perf_stats.bufs_rec,
card->stats.tx_packets, card->perf_stats.bufs_sent
);
- seq_printf(s, " Skb's/buffers sent without packing : %li/%i\n"
- " Skb's/buffers sent with packing : %i/%i\n\n",
+ seq_printf(s, " Skb's/buffers sent without packing : %lu/%u\n"
+ " Skb's/buffers sent with packing : %u/%u\n\n",
card->stats.tx_packets - card->perf_stats.skbs_sent_pack,
card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack,
card->perf_stats.skbs_sent_pack,
card->perf_stats.bufs_sent_pack
);
- seq_printf(s, " Skbs sent in SG mode : %i\n"
- " Skb fragments sent in SG mode : %i\n\n",
+ seq_printf(s, " Skbs sent in SG mode : %u\n"
+ " Skb fragments sent in SG mode : %u\n\n",
card->perf_stats.sg_skbs_sent,
card->perf_stats.sg_frags_sent);
- seq_printf(s, " large_send tx (in Kbytes) : %i\n"
- " large_send count : %i\n\n",
+ seq_printf(s, " large_send tx (in Kbytes) : %u\n"
+ " large_send count : %u\n\n",
card->perf_stats.large_send_bytes >> 10,
card->perf_stats.large_send_cnt);
- seq_printf(s, " Packing state changes no pkg.->packing : %i/%i\n"
+ seq_printf(s, " Packing state changes no pkg.->packing : %u/%u\n"
" Watermarks L/H : %i/%i\n"
" Current buffer usage (outbound q's) : "
"%i/%i/%i/%i\n\n",
@@ -229,16 +229,16 @@ qeth_perf_procfile_seq_show(struct seq_f
atomic_read(&card->qdio.out_qs[3]->used_buffers)
: 0
);
- seq_printf(s, " Inbound handler time (in us) : %i\n"
- " Inbound handler count : %i\n"
- " Inbound do_QDIO time (in us) : %i\n"
- " Inbound do_QDIO count : %i\n\n"
- " Outbound handler time (in us) : %i\n"
- " Outbound handler count : %i\n\n"
- " Outbound time (in us, incl QDIO) : %i\n"
- " Outbound count : %i\n"
- " Outbound do_QDIO time (in us) : %i\n"
- " Outbound do_QDIO count : %i\n\n",
+ seq_printf(s, " Inbound handler time (in us) : %u\n"
+ " Inbound handler count : %u\n"
+ " Inbound do_QDIO time (in us) : %u\n"
+ " Inbound do_QDIO count : %u\n\n"
+ " Outbound handler time (in us) : %u\n"
+ " Outbound handler count : %u\n\n"
+ " Outbound time (in us, incl QDIO) : %u\n"
+ " Outbound count : %u\n"
+ " Outbound do_QDIO time (in us) : %u\n"
+ " Outbound do_QDIO count : %u\n\n",
card->perf_stats.inbound_time,
card->perf_stats.inbound_cnt,
card->perf_stats.inbound_do_qdio_time,
^ permalink raw reply related
* [patch 1/6] s390: minor claw driver fix
From: Frank Pavlic @ 2006-03-22 15:03 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, linux-kernel
Hi ,
following 6 patches are for s390 network drivers claw, qeth and ctc.
tty support will be removed from the ctc network device driver , which will
happen with patch 5/6 and 6/6 . The latter one will remove two files , ctctty.c and ctctty.h .
Thanks
Frank
[patch 1/6] s390: minor claw driver fix
From: Frank Pavlic <fpavlic@de.ibm.com>
use CONFIG_ARCH_S390X instead of CONFIG_64BIT in function dumpit .
Signed-off-by: Frank Pavlic <fpavlic@de.ibm.com>
diffstat:
claw.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index a86436a..4687bb5 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -1601,7 +1601,7 @@ dumpit(char* buf, int len)
__u32 ct, sw, rm, dup;
char *ptr, *rptr;
char tbuf[82], tdup[82];
-#if (CONFIG_64BIT)
+#if (CONFIG_ARCH_S390X)
char addr[22];
#else
char addr[12];
@@ -1617,7 +1617,7 @@ dumpit(char* buf, int len)
dup = 0;
for ( ct=0; ct < len; ct++, ptr++, rptr++ ) {
if (sw == 0) {
-#if (CONFIG_64BIT)
+#if (CONFIG_ARCH_S390X)
sprintf(addr, "%16.16lX",(unsigned long)rptr);
#else
sprintf(addr, "%8.8X",(__u32)rptr);
@@ -1632,7 +1632,7 @@ dumpit(char* buf, int len)
if (sw == 8) {
strcat(bhex, " ");
}
-#if (CONFIG_64BIT)
+#if (CONFIG_ARCH_S390X)
sprintf(tbuf,"%2.2lX", (unsigned long)*ptr);
#else
sprintf(tbuf,"%2.2X", (__u32)*ptr);
^ permalink raw reply related
* Re: [PATCH 6/6 v2] IB: userspace support for RDMA connection manager
From: Michael S. Tsirkin @ 2006-03-22 8:30 UTC (permalink / raw)
To: Roland Dreier; +Cc: netdev, linux-kernel, openib-general
In-Reply-To: <adawten6yu1.fsf@cisco.com>
Quoting r. Roland Dreier <rdreier@cisco.com>:
> Subject: Re: [PATCH 6/6 v2] IB: userspace support for RDMA connection manager
>
> I added this patch to the rdma_cm branch in my git tree.
BTW, is there some way to see your git tree e.g. with gitweb?
--
Michael S. Tsirkin
Staff Engineer, Mellanox Technologies
^ permalink raw reply
* [RFC][UPDATED PATCH 2.6.16] [Patch 9/9] Generic netlink interface for delay accounting
From: Balbir Singh @ 2006-03-22 7:49 UTC (permalink / raw)
To: jamal; +Cc: Matt Helsley, Shailabh Nagar, linux-kernel, netdev
In-Reply-To: <1142304506.5219.34.camel@jzny2>
On Mon, Mar 13, 2006 at 09:48:26PM -0500, jamal wrote:
> On Mon, 2006-13-03 at 18:33 -0800, Matt Helsley wrote:
> > On Mon, 2006-03-13 at 19:56 -0500, Shailabh Nagar wrote:
>
>
> I had a long description in an earlier email feedback; but the summary
> of it is the GET command is generic like TASKSTATS_CMD_GET; the message
> itself carries TLVs of what needs to be gotten which are
> either PID and/or TGID etc. Anyways, theres a long spill of what i am
> saying in that earlier email. Perhaps the current patch is a transition
> towards that?
>
Hi, Jamal,
Please find the updated version of delayacct-genetlink.patch. We hope
this iteration is closer to your expectation. I have copied the enums
you suggested in your previous review comments and used them.
Comments addressed (in this patch)
- Changed the code to use TLV's for data exchange between kernel and
user space
Thanks,
Balbir
Documentation for the patch
Create a generic netlink interface (NETLINK_GENERIC family),
called "taskstats", for getting delay and cpu statistics of
tasks and thread groups during their lifetime and when they exit.
More changes expected. Following comments will go into a
Documentation file:
When a task is alive, userspace can get its stats by sending a
command containing its pid. Sending a tgid returns the sum of stats
of the tasks belonging to that tgid (where such a sum makes sense).
Together, the command interface allows stats for a large number of
tasks to be collected more efficiently than would be possible
through /proc or any per-pid interface.
The netlink interface also sends the stats for each task to userspace
when the task is exiting. This permits fine-grain accounting for
short-lived tasks, which is important if userspace is doing its own
aggregation of statistics based on some grouping of tasks
(e.g. CSA jobs, ELSA banks or CKRM classes).
If the exiting task belongs to a thread group (with more members than itself)
, the latters delay stats are also sent out on the task's exit. This allows
userspace to get accurate data at a per-tgid level while the tid's of a tgid
are exiting one by one.
The interface has been deliberately kept distinct from the delay
accounting code since it is potentially usable by other kernel components
that need to export per-pid/tgid data. The format of data returned to
userspace is versioned and the command interface easily extensible to
facilitate reuse.
If reuse is not deemed useful enough, the naming, placement of functions
and config options will be modified to make this an interface for delay
accounting alone.
Signed-off-by: Shailabh Nagar <nagar@watson.ibm.com>
Signed-off-by: Balbir Singh <balbir@in.ibm.com>
---
include/linux/delayacct.h | 11 ++
include/linux/taskstats.h | 112 ++++++++++++++++++++
init/Kconfig | 16 ++
kernel/Makefile | 1
kernel/delayacct.c | 44 ++++++++
kernel/taskstats.c | 251 ++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 432 insertions(+), 3 deletions(-)
diff -puN include/linux/delayacct.h~delayacct-genetlink include/linux/delayacct.h
--- linux-2.6.16/include/linux/delayacct.h~delayacct-genetlink 2006-03-22 11:56:03.000000000 +0530
+++ linux-2.6.16-balbir/include/linux/delayacct.h 2006-03-22 11:56:03.000000000 +0530
@@ -15,6 +15,7 @@
#define _LINUX_TASKDELAYS_H
#include <linux/sched.h>
+#include <linux/taskstats.h>
#ifdef CONFIG_TASK_DELAY_ACCT
extern int delayacct_on; /* Delay accounting turned on/off */
@@ -25,6 +26,7 @@ extern void __delayacct_tsk_exit(struct
extern void __delayacct_blkio_start(void);
extern void __delayacct_blkio_end(void);
extern unsigned long long __delayacct_blkio_ticks(struct task_struct *);
+extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *);
static inline void delayacct_tsk_init(struct task_struct *tsk)
{
@@ -72,4 +74,13 @@ static inline unsigned long long delayac
return 0;
}
#endif /* CONFIG_TASK_DELAY_ACCT */
+#ifdef CONFIG_TASKSTATS
+static inline int delayacct_add_tsk(struct taskstats *d,
+ struct task_struct *tsk)
+{
+ if (!tsk->delays)
+ return -EINVAL;
+ return __delayacct_add_tsk(d, tsk);
+}
+#endif
#endif /* _LINUX_TASKDELAYS_H */
diff -puN /dev/null include/linux/taskstats.h
--- /dev/null 2004-06-24 23:34:38.000000000 +0530
+++ linux-2.6.16-balbir/include/linux/taskstats.h 2006-03-22 13:12:01.000000000 +0530
@@ -0,0 +1,112 @@
+/* taskstats.h - exporting per-task statistics
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ * (C) Balbir Singh, IBM Corp. 2006
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _LINUX_TASKSTATS_H
+#define _LINUX_TASKSTATS_H
+
+/* Format for per-task data returned to userland when
+ * - a task exits
+ * - listener requests stats for a task
+ *
+ * The struct is versioned. Newer versions should only add fields to
+ * the bottom of the struct to maintain backward compatibility.
+ *
+ * To create the next version, bump up the taskstats_version variable
+ * and delineate the start of newly added fields with a comment indicating
+ * the version number.
+ */
+
+#define TASKSTATS_VERSION 1
+#define TASKSTATS_NOPID -1
+
+struct taskstats {
+ /* Maintain 64-bit alignment while extending */
+ /* Version 1 */
+
+ /* XXX_count is number of delay values recorded.
+ * XXX_total is corresponding cumulative delay in nanoseconds
+ */
+
+#define TASKSTATS_NOCPUSTATS 1
+ __u64 cpu_count;
+ __u64 cpu_delay_total; /* wait, while runnable, for cpu */
+ __u64 blkio_count;
+ __u64 blkio_delay_total; /* sync,block io completion wait*/
+ __u64 swapin_count;
+ __u64 swapin_delay_total; /* swapin page fault wait*/
+
+ __u64 cpu_run_total; /* cpu running time
+ * no count available/provided */
+};
+
+
+#define TASKSTATS_LISTEN_GROUP 0x1
+
+/*
+ * Commands sent from userspace
+ * Not versioned. New commands should only be inserted at the enum's end
+ */
+
+enum {
+ TASKSTATS_CMD_UNSPEC = 0, /* Reserved */
+ TASKSTATS_CMD_GET, /* user->kernel request */
+ TASKSTATS_CMD_NEW, /* kernel->user event */
+ __TASKSTATS_CMD_MAX,
+};
+
+#define TASKSTATS_CMD_MAX (__TASKSTATS_CMD_MAX - 1)
+
+enum {
+ TASKSTATS_TYPE_UNSPEC = 0, /* Reserved */
+ TASKSTATS_TYPE_TGID, /* Thread group id */
+ TASKSTATS_TYPE_PID, /* Process id */
+ TASKSTATS_TYPE_STATS, /* taskstats structure */
+ __TASKSTATS_TYPE_MAX,
+};
+
+#define TASKSTATS_TYPE_MAX (__TASKSTATS_TYPE_MAX - 1)
+
+enum {
+ TASKSTATS_CMD_ATTR_UNSPEC = 0,
+ TASKSTATS_CMD_ATTR_PID,
+ TASKSTATS_CMD_ATTR_TGID,
+ __TASKSTATS_CMD_ATTR_MAX,
+};
+
+#define TASKSTATS_CMD_ATTR_MAX (__TASKSTATS_CMD_ATTR_MAX - 1)
+
+enum {
+ TASKSTATS_MSG_UNICAST, /* send data only to requester */
+ TASKSTATS_MSG_MULTICAST, /* send data to a group */
+};
+
+
+/* NETLINK_GENERIC related info */
+
+#define TASKSTATS_GENL_NAME "TASKSTATS"
+#define TASKSTATS_GENL_VERSION 0x1
+
+#ifdef __KERNEL__
+
+#include <linux/sched.h>
+
+#ifdef CONFIG_TASKSTATS
+extern void taskstats_exit_pid(struct task_struct *);
+#else
+static inline void taskstats_exit_pid(struct task_struct *tsk)
+{}
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_TASKSTATS_H */
diff -puN init/Kconfig~delayacct-genetlink init/Kconfig
--- linux-2.6.16/init/Kconfig~delayacct-genetlink 2006-03-22 11:56:03.000000000 +0530
+++ linux-2.6.16-balbir/init/Kconfig 2006-03-22 11:56:03.000000000 +0530
@@ -158,11 +158,21 @@ config TASK_DELAY_ACCT
in pages. Such statistics can help in setting a task's priorities
relative to other tasks for cpu, io, rss limits etc.
- Unlike BSD process accounting, this information is available
- continuously during the lifetime of a task.
-
Say N if unsure.
+config TASKSTATS
+ bool "Export task/process statistics through netlink (EXPERIMENTAL)"
+ depends on TASK_DELAY_ACCT
+ default y
+ help
+ Export selected statistics for tasks/processes through the
+ generic netlink interface. Unlike BSD process accounting, the
+ statistics are available during the lifetime of tasks/processes as
+ responses to commands. Like BSD accounting, they are sent to user
+ space on task exit.
+
+ Say Y if unsure.
+
config SYSCTL
bool "Sysctl support"
---help---
diff -puN kernel/delayacct.c~delayacct-genetlink kernel/delayacct.c
--- linux-2.6.16/kernel/delayacct.c~delayacct-genetlink 2006-03-22 11:56:03.000000000 +0530
+++ linux-2.6.16-balbir/kernel/delayacct.c 2006-03-22 13:12:01.000000000 +0530
@@ -1,6 +1,7 @@
/* delayacct.c - per-task delay accounting
*
* Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ * Copyright (C) Balbir Singh, IBM Corp. 2006
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
@@ -16,9 +17,12 @@
#include <linux/time.h>
#include <linux/sysctl.h>
#include <linux/delayacct.h>
+#include <linux/taskstats.h>
+#include <linux/mutex.h>
int delayacct_on = 0; /* Delay accounting turned on/off */
kmem_cache_t *delayacct_cache;
+static DEFINE_MUTEX(delayacct_exit_mutex);
static int __init delayacct_setup_enable(char *str)
{
@@ -51,10 +55,16 @@ void __delayacct_tsk_init(struct task_st
void __delayacct_tsk_exit(struct task_struct *tsk)
{
+ /*
+ * Protect against racing thread group exits
+ */
+ mutex_lock(&delayacct_exit_mutex);
+ taskstats_exit_pid(tsk);
if (tsk->delays) {
kmem_cache_free(delayacct_cache, tsk->delays);
tsk->delays = NULL;
}
+ mutex_unlock(&delayacct_exit_mutex);
}
/*
@@ -124,3 +134,37 @@ unsigned long long __delayacct_blkio_tic
spin_unlock(&tsk->delays->lock);
return ret;
}
+#ifdef CONFIG_TASKSTATS
+int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk)
+{
+ nsec_t tmp;
+ struct timespec ts;
+ unsigned long t1,t2;
+
+ /* zero XXX_total,non-zero XXX_count implies XXX stat overflowed */
+
+ tmp = (nsec_t)d->cpu_run_total ;
+ tmp += (u64)(tsk->utime+tsk->stime)*TICK_NSEC;
+ d->cpu_run_total = (tmp < (nsec_t)d->cpu_run_total)? 0: tmp;
+
+ /* No locking available for sched_info. Take snapshot first. */
+ t1 = tsk->sched_info.pcnt;
+ t2 = tsk->sched_info.run_delay;
+
+ d->cpu_count += t1;
+
+ jiffies_to_timespec(t2, &ts);
+ tmp = (nsec_t)d->cpu_delay_total + timespec_to_ns(&ts);
+ d->cpu_delay_total = (tmp < (nsec_t)d->cpu_delay_total)? 0: tmp;
+
+ spin_lock(&tsk->delays->lock);
+ tmp = d->blkio_delay_total + tsk->delays->blkio_delay;
+ d->blkio_delay_total = (tmp < d->blkio_delay_total)? 0: tmp;
+ tmp = d->swapin_delay_total + tsk->delays->swapin_delay;
+ d->swapin_delay_total = (tmp < d->swapin_delay_total)? 0: tmp;
+ d->blkio_count += tsk->delays->blkio_count;
+ d->swapin_count += tsk->delays->swapin_count;
+ spin_unlock(&tsk->delays->lock);
+ return 0;
+}
+#endif /* CONFIG_TASKSTATS */
diff -puN kernel/Makefile~delayacct-genetlink kernel/Makefile
--- linux-2.6.16/kernel/Makefile~delayacct-genetlink 2006-03-22 11:56:03.000000000 +0530
+++ linux-2.6.16-balbir/kernel/Makefile 2006-03-22 11:56:03.000000000 +0530
@@ -35,6 +35,7 @@ obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
obj-$(CONFIG_SECCOMP) += seccomp.o
obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
+obj-$(CONFIG_TASKSTATS) += taskstats.o
ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff -puN /dev/null kernel/taskstats.c
--- /dev/null 2004-06-24 23:34:38.000000000 +0530
+++ linux-2.6.16-balbir/kernel/taskstats.c 2006-03-22 13:12:07.000000000 +0530
@@ -0,0 +1,251 @@
+/*
+ * taskstats.c - Export per-task statistics to userland
+ *
+ * Copyright (C) Shailabh Nagar, IBM Corp. 2006
+ * (C) Balbir Singh, IBM Corp. 2006
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/taskstats.h>
+#include <linux/delayacct.h>
+#include <net/genetlink.h>
+#include <asm/atomic.h>
+
+const int taskstats_version = TASKSTATS_VERSION;
+static DEFINE_PER_CPU(__u32, taskstats_seqnum) = { 0 };
+static int family_registered = 0;
+
+static struct genl_family family = {
+ .id = GENL_ID_GENERATE,
+ .name = TASKSTATS_GENL_NAME,
+ .version = TASKSTATS_GENL_VERSION,
+ .hdrsize = 0,
+ .maxattr = TASKSTATS_CMD_ATTR_MAX,
+};
+
+static struct nla_policy taskstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1] __read_mostly = {
+ [TASKSTATS_CMD_ATTR_PID] = { .type = NLA_U32 },
+ [TASKSTATS_CMD_ATTR_TGID] = { .type = NLA_U32 },
+};
+
+
+static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp,
+ void **replyp)
+{
+ struct sk_buff *skb;
+ void *reply;
+
+ skb = nlmsg_new(NLMSG_GOODSIZE);
+ if (!skb)
+ return -ENOMEM;
+
+ if (!info) {
+ int seq = get_cpu_var(taskstats_seqnum)++;
+ put_cpu_var(taskstats_seqnum);
+
+ reply = genlmsg_put(skb, 0, seq,
+ family.id, 0, NLM_F_REQUEST,
+ cmd, family.version);
+ } else
+ reply = genlmsg_put(skb, info->snd_pid, info->snd_seq,
+ family.id, 0, info->nlhdr->nlmsg_flags,
+ info->genlhdr->cmd, family.version);
+ if (reply == NULL) {
+ nlmsg_free(skb);
+ return -EINVAL;
+ }
+
+ *skbp = skb;
+ *replyp = reply;
+ return 0;
+}
+
+static int send_reply(struct sk_buff *skb, pid_t pid, int event)
+{
+ struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data);
+ void *reply;
+ int rc;
+
+ reply = genlmsg_data(genlhdr);
+
+ rc = genlmsg_end(skb, reply);
+ if (rc < 0) {
+ nlmsg_free(skb);
+ return rc;
+ }
+
+ if (event == TASKSTATS_MSG_MULTICAST)
+ return genlmsg_multicast(skb, pid, TASKSTATS_LISTEN_GROUP);
+ return genlmsg_unicast(skb, pid);
+}
+
+static inline int fill_pid(pid_t pid, struct task_struct *pidtsk,
+ struct taskstats *stats)
+{
+ int rc;
+ struct task_struct *tsk = pidtsk;
+
+ if (!pidtsk) {
+ read_lock(&tasklist_lock);
+ tsk = find_task_by_pid(pid);
+ if (!tsk) {
+ read_unlock(&tasklist_lock);
+ return -ESRCH;
+ }
+ get_task_struct(tsk);
+ read_unlock(&tasklist_lock);
+ } else
+ get_task_struct(tsk);
+
+ rc = delayacct_add_tsk(stats, tsk);
+ put_task_struct(tsk);
+
+ return rc;
+
+}
+
+static inline int fill_tgid(pid_t tgid, struct task_struct *tgidtsk,
+ struct taskstats *stats)
+{
+ int rc;
+ struct task_struct *tsk, *first;
+
+ first = tgidtsk;
+ read_lock(&tasklist_lock);
+ if (!first) {
+ first = find_task_by_pid(tgid);
+ if (!first) {
+ read_unlock(&tasklist_lock);
+ return -ESRCH;
+ }
+ }
+ tsk = first;
+ do {
+ rc = delayacct_add_tsk(stats, tsk);
+ if (rc)
+ break;
+ } while_each_thread(first, tsk);
+ read_unlock(&tasklist_lock);
+
+ return rc;
+}
+
+static int taskstats_send_stats(struct sk_buff *skb, struct genl_info *info)
+{
+ int rc;
+ struct sk_buff *rep_skb;
+ struct taskstats stats;
+ void *reply;
+
+ memset(&stats, 0, sizeof(stats));
+ rc = prepare_reply(info, info->genlhdr->cmd, &rep_skb, &reply);
+ if (rc < 0)
+ return rc;
+
+ if (info->attrs[TASKSTATS_CMD_ATTR_PID]) {
+ u32 pid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_PID]);
+ NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_PID, pid);
+ rc = fill_pid((pid_t)pid, NULL, &stats);
+ if (rc < 0)
+ return rc;
+ }
+
+ if (info->attrs[TASKSTATS_CMD_ATTR_TGID]) {
+ u32 tgid = nla_get_u32(info->attrs[TASKSTATS_CMD_ATTR_TGID]);
+ NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_TGID, tgid);
+ rc = fill_tgid((pid_t)tgid, NULL, &stats);
+ if (rc < 0)
+ return rc;
+ }
+
+ NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS, stats);
+ return send_reply(rep_skb, info->snd_pid, TASKSTATS_MSG_UNICAST);
+
+nla_put_failure:
+ return genlmsg_cancel(rep_skb, reply);
+
+}
+
+
+/* Send pid data out on exit */
+void taskstats_exit_pid(struct task_struct *tsk)
+{
+ int rc;
+ struct sk_buff *rep_skb;
+ void *reply;
+ struct taskstats stats;
+
+ /*
+ * tasks can start to exit very early. Ensure that the family
+ * is registered before notifications are sent out
+ */
+ if (!family_registered)
+ return;
+
+ memset(&stats, 0, sizeof(stats));
+ rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, &reply);
+ if (rc < 0)
+ return;
+
+ NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_PID, (u32)tsk->pid);
+ rc = fill_pid(tsk->pid, tsk, &stats);
+ if (rc < 0)
+ return;
+
+ NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS, stats);
+ rc = send_reply(rep_skb, 0, TASKSTATS_MSG_MULTICAST);
+
+ if (rc || thread_group_empty(tsk))
+ return;
+
+ /* Send tgid data too */
+ rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, &reply);
+ if (rc < 0)
+ return;
+
+ NLA_PUT_U32(rep_skb, TASKSTATS_TYPE_TGID, (u32)tsk->tgid);
+ rc = fill_tgid(tsk->tgid, tsk, &stats);
+ if (rc < 0)
+ return;
+
+ NLA_PUT_TYPE(rep_skb, struct taskstats, TASKSTATS_TYPE_STATS, stats);
+ send_reply(rep_skb, 0, TASKSTATS_MSG_MULTICAST);
+
+nla_put_failure:
+ genlmsg_cancel(rep_skb, reply);
+}
+
+static struct genl_ops taskstats_ops = {
+ .cmd = TASKSTATS_CMD_GET,
+ .doit = taskstats_send_stats,
+ .policy = taskstats_cmd_get_policy,
+};
+
+static int __init taskstats_init(void)
+{
+ if (genl_register_family(&family))
+ return -EFAULT;
+ family_registered = 1;
+
+ if (genl_register_ops(&family, &taskstats_ops))
+ goto err;
+
+ return 0;
+err:
+ genl_unregister_family(&family);
+ family_registered = 0;
+ return -EFAULT;
+}
+
+late_initcall(taskstats_init);
_
^ permalink raw reply
* [patch 2/2] net: Node aware multipath device round robin -- device locality check
From: Ravikiran G Thirumalai @ 2006-03-22 6:08 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: davem, Andrew Morton, Shai Fultheim (Shai@scalex86.org),
pravin b shelar
In-Reply-To: <20060322060540.GA3603@localhost.localdomain>
This patch checks device locality on every ip packet xmit.
In multipath configuration tcp connection to route association is done at
session startup time. The tcp session process is migrated to different nodes
after this association. This would mean a remote NIC is chosen for xmit,
although a local NIC could be available. Following patch checks if a
local NIC is available for the desitnation, and recalculates routes if so.
his leads to remote NIC transfer in some tcp work load such as AB.
Downside: adds a bitmap to struct rtable. But only if
CONFIG_IP_ROUTE_MULTIPATH_NODE is enabled.
Comments, suggestions welcome.
Signed-off by: Pravin B. Shelar <pravins@calsoftinc.com>
Signed-off by: Ravikiran Thirumalai <kiran@scalex86.org>
Signed-off by: Shai Fultheim <shai@scalex86.org>
Index: linux-2.6.16/include/net/route.h
===================================================================
--- linux-2.6.16.orig/include/net/route.h 2006-03-19 21:53:29.000000000 -0800
+++ linux-2.6.16/include/net/route.h 2006-03-20 14:52:24.000000000 -0800
@@ -75,6 +75,13 @@ struct rtable
/* Miscellaneous cached information */
__u32 rt_spec_dst; /* RFC1122 specific destination */
struct inet_peer *peer; /* long-living peer info */
+#ifdef CONFIG_IP_ROUTE_MULTIPATH_NODE
+ /* bitmap bit is set if current node has a local multi-path device for
+ * this route.
+ */
+ DECLARE_BITMAP (mp_if_bitmap, MAX_NUMNODES);
+#endif
+
};
struct ip_rt_acct
@@ -201,4 +208,21 @@ static inline struct inet_peer *rt_get_p
extern ctl_table ipv4_route_table[];
+#ifdef CONFIG_IP_ROUTE_MULTIPATH_NODE
+
+#include <linux/ip_mp_alg.h>
+
+static inline int dst_dev_node_check(struct rtable *rt)
+{
+ int cnode = numa_node_id();
+ if (unlikely(netdev_node(rt->u.dst.dev) != cnode)) {
+ if (test_bit(cnode, rt->mp_if_bitmap))
+ return 1;
+ }
+ return 0;
+}
+#else
+#define dst_dev_node_check(rt) 0
+#endif
+
#endif /* _ROUTE_H */
Index: linux-2.6.16/net/ipv4/ip_output.c
===================================================================
--- linux-2.6.16.orig/net/ipv4/ip_output.c 2006-03-19 21:53:29.000000000 -0800
+++ linux-2.6.16/net/ipv4/ip_output.c 2006-03-20 14:52:24.000000000 -0800
@@ -309,7 +309,7 @@ int ip_queue_xmit(struct sk_buff *skb, i
/* Make sure we can route this packet. */
rt = (struct rtable *)__sk_dst_check(sk, 0);
- if (rt == NULL) {
+ if ((rt == NULL ) || dst_dev_node_check(rt)) {
u32 daddr;
/* Use correct destination address if we have options. */
Index: linux-2.6.16/net/ipv4/route.c
===================================================================
--- linux-2.6.16.orig/net/ipv4/route.c 2006-03-19 21:53:29.000000000 -0800
+++ linux-2.6.16/net/ipv4/route.c 2006-03-20 14:52:24.000000000 -0800
@@ -2313,6 +2313,22 @@ static inline int ip_mkroute_output(stru
if (res->fi && res->fi->fib_nhs > 1) {
unsigned char hopcount = res->fi->fib_nhs;
+#ifdef CONFIG_IP_ROUTE_MULTIPATH_NODE
+ DECLARE_BITMAP (mp_if_bitmap, MAX_NUMNODES);
+ bitmap_zero(mp_if_bitmap, MAX_NUMNODES);
+ /* Calculating device bitmap for this multipath route */
+ if (res->fi->fib_mp_alg == IP_MP_ALG_DRR) {
+ for (hop = 0; hop < hopcount; hop++) {
+ struct net_device *dev2nexthop;
+
+ res->nh_sel = hop;
+ dev2nexthop = FIB_RES_DEV(*res);
+ dev_hold(dev2nexthop);
+ set_bit(netdev_node(dev2nexthop), mp_if_bitmap);
+ dev_put(dev2nexthop);
+ }
+ }
+#endif
for (hop = 0; hop < hopcount; hop++) {
struct net_device *dev2nexthop;
@@ -2343,6 +2359,10 @@ static inline int ip_mkroute_output(stru
FIB_RES_NETMASK(*res),
res->prefixlen,
&FIB_RES_NH(*res));
+
+#ifdef CONFIG_IP_ROUTE_MULTIPATH_NODE
+ bitmap_copy(rth->mp_if_bitmap, mp_if_bitmap, MAX_NUMNODES);
+#endif
cleanup:
/* release work reference to output device */
dev_put(dev2nexthop);
^ permalink raw reply
* [patch 1/2] net: Node aware multipath device round robin
From: Ravikiran G Thirumalai @ 2006-03-22 6:05 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: davem, Andrew Morton, Shai Fultheim (Shai@scalex86.org),
pravin b shelar
Following patch adds in node aware, device round robin ip multipathing.
It is based on multipath_drr.c, the multipath device round robin algorithm, and
is derived from it. This implementation maintians per node state table, and
round robins between interfaces on the same node. The implementation needs to
be aware of the NIC proximity to a node. Hence we have added a nodeid field to
struct netdevice. NIC device drivers can initialize this with the node id
the NIC belongs to. This patch uses IP_MP_ALG_DRR slot like the regular
multipath_drr too. So either SMP multipath_drr or node aware
multipath_node_drr should be used for device round robin, based on system having
proximity information for the NICs.
Performance results:
1. Single NIC test -- 1 client targets 1 nic on the server with 300 concurrent
requests.
2. 4 NIC test -- 1 client targets 4 nics, all on different nodes on the server with 300 concurrent requests.
We see about 135% improvement on AB requests per second with this patch and
the device_locality_check patch on single NIC test, on the Rackable c5100
machine (server). We see about 64% improvement when all 4 NICS are targeted.
Credits: This work was originally done by Justin Forbes
Comments?
Signed-off by: Pravin B. Shelar <pravin.shelar@calsoftinc.com>
Signed-off by: Shobhit Dayal <shobhit.dayal@calsoftinc.com>
Signed-off by: Ravikiran Thirumalai <kiran@scalex86.org>
Signed-off by: Shai Fultheim <shai@scalex86.org>
Index: linux-2.6.16/drivers/net/e1000/e1000_main.c
===================================================================
--- linux-2.6.16.orig/drivers/net/e1000/e1000_main.c 2006-03-19 21:53:29.000000000 -0800
+++ linux-2.6.16/drivers/net/e1000/e1000_main.c 2006-03-20 14:52:23.000000000 -0800
@@ -692,6 +692,7 @@ e1000_probe(struct pci_dev *pdev,
SET_MODULE_OWNER(netdev);
SET_NETDEV_DEV(netdev, &pdev->dev);
+ SET_NETDEV_NODE(netdev, pcibus_to_node(pdev->bus));
pci_set_drvdata(pdev, netdev);
adapter = netdev_priv(netdev);
Index: linux-2.6.16/drivers/net/tg3.c
===================================================================
--- linux-2.6.16.orig/drivers/net/tg3.c 2006-03-19 21:53:29.000000000 -0800
+++ linux-2.6.16/drivers/net/tg3.c 2006-03-20 14:52:23.000000000 -0800
@@ -10705,6 +10705,7 @@ static int __devinit tg3_init_one(struct
SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
+ SET_NETDEV_NODE(dev, pcibus_to_node(pdev->bus));
dev->features |= NETIF_F_LLTX;
#if TG3_VLAN_TAG_USED
Index: linux-2.6.16/include/linux/netdevice.h
===================================================================
--- linux-2.6.16.orig/include/linux/netdevice.h 2006-03-19 21:53:29.000000000 -0800
+++ linux-2.6.16/include/linux/netdevice.h 2006-03-20 14:52:23.000000000 -0800
@@ -315,7 +315,9 @@ struct net_device
/* Interface index. Unique device identifier */
int ifindex;
int iflink;
-
+#ifdef CONFIG_NUMA
+ int node; /* NUMA node this IF is close to */
+#endif
struct net_device_stats* (*get_stats)(struct net_device *dev);
struct iw_statistics* (*get_wireless_stats)(struct net_device *dev);
@@ -520,6 +522,14 @@ static inline void *netdev_priv(struct n
*/
#define SET_NETDEV_DEV(net, pdev) ((net)->class_dev.dev = (pdev))
+#ifdef CONFIG_NUMA
+#define SET_NETDEV_NODE(dev, nodeid) ((dev)->node = (nodeid))
+#define netdev_node(dev) ((dev)->node)
+#else
+#define SET_NETDEV_NODE(dev, nodeid) do {} while (0)
+#define netdev_node(dev) (-1)
+#endif
+
struct packet_type {
__be16 type; /* This is really htons(ether_type). */
struct net_device *dev; /* NULL is wildcarded here */
Index: linux-2.6.16/net/core/dev.c
===================================================================
--- linux-2.6.16.orig/net/core/dev.c 2006-03-19 21:53:29.000000000 -0800
+++ linux-2.6.16/net/core/dev.c 2006-03-20 14:52:23.000000000 -0800
@@ -3003,7 +3003,8 @@ struct net_device *alloc_netdev(int size
if (sizeof_priv)
dev->priv = netdev_priv(dev);
-
+
+ SET_NETDEV_NODE(dev, -1);
setup(dev);
strcpy(dev->name, name);
return dev;
Index: linux-2.6.16/net/ipv4/Kconfig
===================================================================
--- linux-2.6.16.orig/net/ipv4/Kconfig 2006-03-19 21:53:29.000000000 -0800
+++ linux-2.6.16/net/ipv4/Kconfig 2006-03-20 14:52:23.000000000 -0800
@@ -164,6 +164,15 @@ config IP_ROUTE_MULTIPATH_DRR
available interfaces. This policy makes sense if the connections
should be primarily distributed on interfaces and not on routes.
+config IP_ROUTE_MULTIPATH_NODE
+ tristate "MULTIPATH: interface RR algorithm with node affinity"
+ depends on IP_ROUTE_MULTIPATH_CACHED && NUMA && !IP_ROUTE_MULTIPATH_DRR
+ help
+ This allows equal cost multipath device round robin alogorithm to
+ use node affinity when choosing the device for outbound traffic. This
+ is similar to CONFIG_IP_ROUTE_MULTIPATH_DRR. Choose this if you
+ have a NUMA system, and the NICs have node proximity.
+
config IP_ROUTE_VERBOSE
bool "IP: verbose route monitoring"
depends on IP_ADVANCED_ROUTER
Index: linux-2.6.16/net/ipv4/Makefile
===================================================================
--- linux-2.6.16.orig/net/ipv4/Makefile 2006-03-19 21:53:29.000000000 -0800
+++ linux-2.6.16/net/ipv4/Makefile 2006-03-20 14:52:23.000000000 -0800
@@ -28,6 +28,7 @@ obj-$(CONFIG_IP_ROUTE_MULTIPATH_RR) += m
obj-$(CONFIG_IP_ROUTE_MULTIPATH_RANDOM) += multipath_random.o
obj-$(CONFIG_IP_ROUTE_MULTIPATH_WRANDOM) += multipath_wrandom.o
obj-$(CONFIG_IP_ROUTE_MULTIPATH_DRR) += multipath_drr.o
+obj-$(CONFIG_IP_ROUTE_MULTIPATH_NODE) += multipath_node_drr.o
obj-$(CONFIG_NETFILTER) += netfilter.o netfilter/
obj-$(CONFIG_IP_VS) += ipvs/
obj-$(CONFIG_INET_DIAG) += inet_diag.o
Index: linux-2.6.16/net/ipv4/multipath_node_drr.c
===================================================================
--- linux-2.6.16.orig/net/ipv4/multipath_node_drr.c 2006-02-28 01:25:15.174738088 -0800
+++ linux-2.6.16/net/ipv4/multipath_node_drr.c 2006-03-20 14:52:23.000000000 -0800
@@ -0,0 +1,264 @@
+/*
+ * Node aware device round robin policy for multipath.
+ * Extension of multipath device round robin for NUMA node based multipathing.
+ * Derived from net/ipv4/multipath_drr.c
+ */
+
+#include <linux/netdevice.h>
+#include <linux/module.h>
+#include <net/ip_mp_alg.h>
+
+struct multipath_device {
+ int ifi; /* interface index of device */
+ atomic_t usecount;
+ int allocated;
+ int node; /* node id of device */
+};
+
+#define MULTIPATH_MAX_DEVICECANDIDATES 16
+
+static struct multipath_device *local_state[MAX_NUMNODES] __read_mostly;
+static DEFINE_SPINLOCK(state_lock);
+
+static int inline __multipath_findslot(int ifindex, int nid)
+{
+ int i, idx, mx;
+ struct multipath_device *state = local_state[nid];
+
+ i = ifindex % MULTIPATH_MAX_DEVICECANDIDATES;
+ if (likely(state[i].allocated == 0))
+ return i;
+
+ mx = i + MULTIPATH_MAX_DEVICECANDIDATES;
+
+ for (; i < mx; i++) {
+ idx = i % MULTIPATH_MAX_DEVICECANDIDATES;
+ if (state[idx].allocated == 0)
+ return idx;
+ }
+ return -1;
+}
+
+static int inline __multipath_finddev(int ifindex, int nid)
+{
+ int i, mx, idx;
+ struct multipath_device *state = local_state[nid];
+
+ i = ifindex % MULTIPATH_MAX_DEVICECANDIDATES;
+ if (likely(state[i].ifi == ifindex))
+ return i;
+
+ mx = i + MULTIPATH_MAX_DEVICECANDIDATES;
+
+ for (; i < mx; i++) {
+ idx = i % MULTIPATH_MAX_DEVICECANDIDATES;
+
+ if (state[idx].ifi == ifindex)
+ return idx;
+ }
+ return -1;
+}
+
+static int drr_dev_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct net_device *dev = ptr;
+ int devidx, nid;
+
+ switch (event) {
+ case NETDEV_UNREGISTER:
+ case NETDEV_DOWN:
+ spin_lock_bh(&state_lock);
+ for_each_node(nid) {
+ devidx = __multipath_finddev(dev->ifindex, nid);
+ if (devidx != -1) {
+ local_state[nid][devidx].ifi = 0;
+ local_state[nid][devidx].allocated = 0;
+ }
+ }
+
+ spin_unlock_bh(&state_lock);
+ break;
+ };
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block drr_dev_notifier = {
+ .notifier_call = drr_dev_event,
+};
+
+static void inline drr_safe_inc(atomic_t *usecount)
+{
+ int n;
+
+ atomic_inc(usecount);
+ n = atomic_read(usecount);
+ if (unlikely(n <= 0)) {
+ int i;
+ struct multipath_device *state = local_state[numa_node_id()];
+
+ for (i = 0; i < MULTIPATH_MAX_DEVICECANDIDATES; i++)
+ atomic_set(&state[i].usecount, 0);
+
+ }
+}
+
+static int update_state_table(struct rtable *nh, int node)
+{
+ int devidx = -1;
+ struct multipath_device *state;
+ int nh_ifidx = nh->u.dst.dev->ifindex;
+ /* add the interface to the array
+ * SMP safe
+ */
+ spin_lock_bh(&state_lock);
+
+ /* due to SMP: search again */
+ devidx = __multipath_finddev(nh_ifidx, node);
+ if (devidx == -1) {
+ /* add entry for device */
+ state = local_state[node];
+ /* find free slot in state table */
+ devidx = __multipath_findslot(nh_ifidx, node);
+ if (devidx == -1) {
+ /* unlikely but possible */
+ goto out;
+ } else {
+ state[devidx].allocated = 1;
+ state[devidx].ifi = nh_ifidx;
+ atomic_set(&state[devidx].usecount, 0);
+ state[devidx].node = netdev_node(nh->u.dst.dev);
+ }
+ }
+out:
+ spin_unlock_bh(&state_lock);
+ return devidx;
+}
+
+static void drr_select_route(const struct flowi *flp,
+ struct rtable *first, struct rtable **rp)
+{
+ struct rtable *nh, *cur_min = NULL, *cur_min_nrr = NULL;
+ int devidx = -1;
+ int cur_min_devidx = -1, cur_min_devidx_nrr = -1;
+ int min_usecount = INT_MAX, min_usecount_nrr = INT_MAX;
+ int node = numa_node_id();
+ struct multipath_device *state;
+
+ /* 1. make sure all alt. nexthops have the same GC related data */
+ /* 2. determine the new candidate to be returned */
+ state = local_state[node];
+ for (nh = rcu_dereference(first); nh;
+ nh = rcu_dereference(nh->u.rt_next)) {
+ if ((nh->u.dst.flags & DST_BALANCED) != 0 &&
+ multipath_comparekeys(&nh->fl, flp)) {
+ int count;
+ int nh_ifidx = nh->u.dst.dev->ifindex;
+
+ nh->u.dst.lastuse = jiffies;
+ nh->u.dst.__use++;
+
+ /* search for the output interface */
+
+ /* this is not SMP safe, only add/remove are
+ * SMP safe as wrong usecount updates have no big
+ * impact
+ */
+ devidx = __multipath_finddev(nh_ifidx, node);
+ if (devidx == -1) {
+ devidx = update_state_table(nh, node);
+ if (devidx == -1)
+ continue;
+ }
+ count = atomic_read(&state[devidx].usecount);
+
+ /* RR on node local interfaces if available */
+ if (state[devidx].node == node) {
+ if (count < min_usecount_nrr) {
+ cur_min_nrr = nh;
+ cur_min_devidx_nrr = devidx;
+ min_usecount_nrr = count;
+ /* lowest used. So use this IF */
+ if (min_usecount_nrr == 0)
+ break;
+ }
+ } else {
+ if (count < min_usecount) {
+ cur_min = nh;
+ cur_min_devidx = devidx;
+ min_usecount = count;
+ }
+ }
+ }
+ }
+
+ /* If node local route is present, choose it. Else choose SMP RR */
+ if (cur_min_devidx_nrr != -1) {
+ drr_safe_inc(&state[cur_min_devidx_nrr].usecount);
+ *rp = cur_min_nrr;
+ return ;
+ }
+
+ if (cur_min_devidx != -1) {
+ drr_safe_inc(&state[cur_min_devidx].usecount);
+ *rp = cur_min;
+ } else
+ *rp = first;
+}
+
+static struct ip_mp_alg_ops drr_ops = {
+ .mp_alg_select_route = drr_select_route,
+};
+
+static int __init drr_init(void)
+{
+ int err, nid;
+ int size = MULTIPATH_MAX_DEVICECANDIDATES *
+ sizeof(struct multipath_device);
+ for_each_node(nid) {
+ int i;
+ local_state[nid] = kmalloc_node(size, GFP_KERNEL, nid);
+ if (local_state[nid] == NULL) {
+ int i;
+ for_each_node(i){
+ if (i < nid)
+ kfree(local_state[i]);
+ }
+ printk(KERN_CRIT"drr_init: Cannot allocate state table\n");
+ return -ENOMEM;
+ }
+ for (i = 0; i < MULTIPATH_MAX_DEVICECANDIDATES; i++) {
+ local_state[nid][i].allocated = 0;
+ local_state[nid][i].ifi = 0;
+ }
+ }
+ err = register_netdevice_notifier(&drr_dev_notifier);
+
+ if (err)
+ return err;
+
+ err = multipath_alg_register(&drr_ops, IP_MP_ALG_DRR);
+ if (err)
+ goto fail;
+
+ return 0;
+
+fail:
+ unregister_netdevice_notifier(&drr_dev_notifier);
+ return err;
+}
+
+static void __exit drr_exit(void)
+{
+ int nid;
+ unregister_netdevice_notifier(&drr_dev_notifier);
+ multipath_alg_unregister(&drr_ops, IP_MP_ALG_DRR);
+ for_each_node(nid){
+ kfree(local_state[nid]);
+ }
+}
+
+module_init(drr_init);
+module_exit(drr_exit);
+MODULE_LICENSE("GPL");
^ permalink raw reply
* Re: [PATCH 2.6.16-rc6 1/1] ipw2200: Add Kconfig entries for QOS and Monitor mode
From: Zhu Yi @ 2006-03-22 3:11 UTC (permalink / raw)
To: Andreas Happe; +Cc: Adrian Bunk, Andrew Morton, linux-kernel, jgarzik, netdev
In-Reply-To: <20060318174703.GA22072@localdomain>
On Sat, 2006-03-18 at 18:47 +0100, Andreas Happe wrote:
> Adds Kconfig entries for enabling Monitor mode and Quality of service
> to the ipw2200 driver. It also renames the IPW_QOS define to
> IPW2200_QOS.
>
> As Monitor mode generates lots of firmware errors it depends upon
> BROKEN. QOS is under development, so it depends upon EXPERIMENTAL.
Ack the rename and QoS description changes.
The IPW2200_MONITOR and monitor mode firmware error are already fixed in
wireless-2.6 GIT
http://kernel.org/git/?p=linux/kernel/git/linville/wireless-2.6.git;a=summary
Wireless related development happens there. I'd suggest you create
patches against that tree.
Thanks,
-yi
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox