* [PATCH RESEND 1/2] s390: remove tty support from ctc network device driver [1/2]
From: Frank Pavlic @ 2006-04-13 18:19 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
Hi jeff,
after the first shot I sent to you did not apply I
resend two new patches I've made today to remove tty from ctc network driver.
Please apply ....
Thank you ...
Frank
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>
---
drivers/s390/net/Makefile | 3 ++-
drivers/s390/net/ctcmain.c | 45 +++++++++-----------------------------------
drivers/s390/net/ctcmain.h | 12 +++++-------
3 files changed, 16 insertions(+), 44 deletions(-)
fd1e8730b620e901a223034aaa6d97dde7a63b56
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);
}
--
1.2.4
^ permalink raw reply related
* [RESEND PATCH 2/2] s390: remove tty support from ctc network device driver [2/2]
From: Frank Pavlic @ 2006-04-13 18:19 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
Hi,
here comes the second of the two patches ...
Frank
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>
---
drivers/s390/net/ctctty.c | 1259 ---------------------------------------------
drivers/s390/net/ctctty.h | 35 -
2 files changed, 0 insertions(+), 1294 deletions(-)
delete mode 100644 drivers/s390/net/ctctty.c
delete mode 100644 drivers/s390/net/ctctty.h
aec009cf604020403752ed0c0826e0e2e83295e1
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
--
1.2.4
^ permalink raw reply related
* Re: via_rhine modules error on 2.6.16 with mii-tool
From: John W. Linville @ 2006-04-13 18:26 UTC (permalink / raw)
To: Roger Luethi; +Cc: Marco Berizzi, netdev
In-Reply-To: <20060327203946.GA11824@k3.hellgate.ch>
On Mon, Mar 27, 2006 at 10:39:46PM +0200, Roger Luethi wrote:
> On Fri, 24 Mar 2006 16:49:10 +0100, Marco Berizzi wrote:
> > Hello evebody.
> > I get this error on linux vanilla 2.6.16
> > with via_rhine module loaded when
> > I run mii-tool:
>
> That was caused by a recent change that replaced an mdelay with msleep.
>
> netdev_ioctl and friends (ethtool calls, too) are known to grab a spin lock
> before they do much of anything, and they hang onto it until they're done.
> They also call mdio_read/write, which requires millisecond delays on Rhine-I.
>
> So on Rhine-I with a 2.6.15+ kernel, the driver ends up calling msleep
> while holding a spin lock -- hence the stack dump.
>
> I wonder if low latency for ancient Rhine-I chips is worth the trouble.
IIRC, the point was that mdelay was getting called in interrupt
context and causing ugly messages to show-up in dmesg.
Would the patch below be sufficient? Or does the whole patch need
to be reverted?
John
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 2418715..e7b4bc3 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -1145,8 +1130,8 @@ static void rhine_disable_linkmon(void _
if (quirks & rqRhineI) {
iowrite8(0x01, ioaddr + MIIRegAddr); // MII_BMSR
- /* Do not call from ISR! */
- msleep(1);
+ /* Can be called from ISR. Evil. */
+ mdelay(1);
/* 0x80 must be set immediately before turning it off */
iowrite8(0x80, ioaddr + MIICmd);
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply related
* Re: via_rhine modules error on 2.6.16 with mii-tool
From: Stephen Hemminger @ 2006-04-13 18:40 UTC (permalink / raw)
To: John W. Linville; +Cc: Roger Luethi, Marco Berizzi, netdev
In-Reply-To: <20060413182638.GC25854@tuxdriver.com>
On Thu, 13 Apr 2006 14:26:43 -0400
"John W. Linville" <linville@tuxdriver.com> wrote:
> On Mon, Mar 27, 2006 at 10:39:46PM +0200, Roger Luethi wrote:
> > On Fri, 24 Mar 2006 16:49:10 +0100, Marco Berizzi wrote:
> > > Hello evebody.
> > > I get this error on linux vanilla 2.6.16
> > > with via_rhine module loaded when
> > > I run mii-tool:
> >
> > That was caused by a recent change that replaced an mdelay with msleep.
> >
> > netdev_ioctl and friends (ethtool calls, too) are known to grab a spin lock
> > before they do much of anything, and they hang onto it until they're done.
> > They also call mdio_read/write, which requires millisecond delays on Rhine-I.
> >
> > So on Rhine-I with a 2.6.15+ kernel, the driver ends up calling msleep
> > while holding a spin lock -- hence the stack dump.
> >
> > I wonder if low latency for ancient Rhine-I chips is worth the trouble.
>
> IIRC, the point was that mdelay was getting called in interrupt
> context and causing ugly messages to show-up in dmesg.
>
> Would the patch below be sufficient? Or does the whole patch need
> to be reverted?
>
> John
>
> diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
> index 2418715..e7b4bc3 100644
> --- a/drivers/net/via-rhine.c
> +++ b/drivers/net/via-rhine.c
> @@ -1145,8 +1130,8 @@ static void rhine_disable_linkmon(void _
> if (quirks & rqRhineI) {
> iowrite8(0x01, ioaddr + MIIRegAddr); // MII_BMSR
>
> - /* Do not call from ISR! */
> - msleep(1);
> + /* Can be called from ISR. Evil. */
> + mdelay(1);
>
> /* 0x80 must be set immediately before turning it off */
> iowrite8(0x80, ioaddr + MIICmd);
The right thing to do is get rid of the locking in via_rhine:netdev_ioctl and push
the locking down into mdio_read, mdio_write.
^ permalink raw reply
* Re: [RFC: 2.6 patch] net/netlink/: possible cleanups
From: David S. Miller @ 2006-04-13 20:26 UTC (permalink / raw)
To: bunk; +Cc: netdev, linux-kernel
In-Reply-To: <20060413162710.GE4162@stusta.de>
From: Adrian Bunk <bunk@stusta.de>
Date: Thu, 13 Apr 2006 18:27:10 +0200
> This patch contains the following possible cleanups plus changes related
> to them:
> - make the following needlessly global functions static:
> - attr.c: __nla_reserve()
> - attr.c: __nla_put()
> - #if 0 the following unused global functions:
> - attr.c: nla_validate()
> - attr.c: nla_find()
> - attr.c: nla_memcpy()
> - attr.c: nla_memcmp()
> - attr.c: nla_strcmp()
> - attr.c: nla_reserve()
> - genetlink.c: genl_unregister_ops()
> - remove the following unused EXPORT_SYMBOL's:
> - af_netlink.c: netlink_set_nonroot
> - attr.c: nla_parse
> - attr.c: nla_strlcpy
> - attr.c: nla_put
>
> Signed-off-by: Adrian Bunk <bunk@stusta.de>
Bunk-bot, you have to stop.
These interfaces were added so that new users of netlink could
write their code more easily.
Unused does not equate to "comment out or delete".
^ permalink raw reply
* Re: via_rhine modules error on 2.6.16 with mii-tool
From: Roger Luethi @ 2006-04-13 20:31 UTC (permalink / raw)
To: John W. Linville; +Cc: Marco Berizzi, netdev
In-Reply-To: <20060413182638.GC25854@tuxdriver.com>
On Thu, 13 Apr 2006 14:26:43 -0400, John W. Linville wrote:
> > I wonder if low latency for ancient Rhine-I chips is worth the trouble.
>
> IIRC, the point was that mdelay was getting called in interrupt
> context and causing ugly messages to show-up in dmesg.
I suppose the patch back then was to reduce latency; the ugly messages in
the kernel ring buffer were _introduced_ with the patch (you shouldn't get
error messages calling mdelay in interrupt context because that's what
mdelay is for).
> Would the patch below be sufficient? Or does the whole patch need
> to be reverted?
I'd revert the whole thing. There's no point in having the additional
work_struct complexity if we end up calling mdelay anyway.
Roger
^ permalink raw reply
* Re: via_rhine modules error on 2.6.16 with mii-tool
From: Roger Luethi @ 2006-04-13 20:47 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: John W. Linville, Marco Berizzi, netdev
In-Reply-To: <20060413114018.65fba555@localhost.localdomain>
On Thu, 13 Apr 2006 11:40:18 -0700, Stephen Hemminger wrote:
> The right thing to do is get rid of the locking in via_rhine:netdev_ioctl
> and push the locking down into mdio_read, mdio_write.
As I said before, a dozen other network drivers do the exact same thing --
they call generic_mii_ioctl right after grabbing the private spin lock (and
only one driver calls generic_mii_ioctl without taking the lock).
I am not keen on patches that make via-rhine more of a special case even if
it was safe now; next thing you know generic_mii_ioctl is changed in a way
that breaks the only driver that foolishly made assumptions about the
side-effects of that function.
If you can safely move the locking down for all network drivers, that would
be a different story, of course.
Roger
^ permalink raw reply
* Re: via_rhine modules error on 2.6.16 with mii-tool
From: Stephen Hemminger @ 2006-04-13 21:02 UTC (permalink / raw)
To: Roger Luethi; +Cc: John W. Linville, Marco Berizzi, netdev
In-Reply-To: <20060413204731.GB2874@k3.hellgate.ch>
On Thu, 13 Apr 2006 22:47:31 +0200
Roger Luethi <rl@hellgate.ch> wrote:
> On Thu, 13 Apr 2006 11:40:18 -0700, Stephen Hemminger wrote:
> > The right thing to do is get rid of the locking in via_rhine:netdev_ioctl
> > and push the locking down into mdio_read, mdio_write.
>
> As I said before, a dozen other network drivers do the exact same thing --
> they call generic_mii_ioctl right after grabbing the private spin lock (and
> only one driver calls generic_mii_ioctl without taking the lock).
>
>
> I am not keen on patches that make via-rhine more of a special case even if
> it was safe now; next thing you know generic_mii_ioctl is changed in a way
> that breaks the only driver that foolishly made assumptions about the
> side-effects of that function.
>
> If you can safely move the locking down for all network drivers, that would
> be a different story, of course.
>
> Roger
Didn't your mother ever tell you that just because everybody else does
it wrong, you don't have to.
The other drivers should be fixed as well. Phy access with irq's disabled
is not good. The hardware I checked takes 100's of usecs to do one read
transaction.
^ permalink raw reply
* Re: [PATCH] atm: clip timer race
From: Roland Dreier @ 2006-04-13 21:08 UTC (permalink / raw)
To: Herbert Xu; +Cc: Stephen Hemminger, davem, chas, linux-atm-general, netdev
In-Reply-To: <20060413124534.GA25333@gondor.apana.org.au>
Herbert> I don't think this is enough though since this timer is
Herbert> one of those self-rescheduling timers. You need to
Herbert> provide some sort of a flag for it to stop scheduling
Herbert> itself and synchronise it properly.
I'm probably missing an obvious race but it seems del_timer_sync()
should be fine on a timer that reschedules itself. del_timer_sync()
loops until try_to_del_timer_sync() succeeds, and
try_to_del_timer_sync() will fail unless the timer being killed is not
running (and it does this test with the timer base lock held).
OK, how am I being stupid?
- R.
^ permalink raw reply
* Re: via_rhine modules error on 2.6.16 with mii-tool
From: Francois Romieu @ 2006-04-13 21:36 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Roger Luethi, John W. Linville, Marco Berizzi, netdev
In-Reply-To: <20060413140252.1c22b078@localhost.localdomain>
Stephen Hemminger <shemminger@osdl.org> :
[...]
> The other drivers should be fixed as well. Phy access with irq's disabled
> is not good. The hardware I checked takes 100's of usecs to do one read
> transaction.
Yep, 802.3 allows it. :o|
It's surprizing that the low latency squadron has not complained so far
from our bad habit of spinlocked, irq disabled, MII access.
--
Ueimor
^ permalink raw reply
* Re: via_rhine modules error on 2.6.16 with mii-tool
From: Roger Luethi @ 2006-04-13 21:55 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: John W. Linville, Marco Berizzi, netdev
In-Reply-To: <20060413140252.1c22b078@localhost.localdomain>
On Thu, 13 Apr 2006 14:02:52 -0700, Stephen Hemminger wrote:
> > I am not keen on patches that make via-rhine more of a special case even if
> > it was safe now; next thing you know generic_mii_ioctl is changed in a way
> > that breaks the only driver that foolishly made assumptions about the
> > side-effects of that function.
> >
> > If you can safely move the locking down for all network drivers, that would
> > be a different story, of course.
>
> Didn't your mother ever tell you that just because everybody else does
> it wrong, you don't have to.
No, but she warned me not to spend time on fixing botched low latency
patches.
Look, it took a lot of time to make via-rhine stable. It's still got
unexplained issues. I have a patch here for a bug that makes a driver
reload necessary when it occurs (and the patch is sitting here because
nobody's able to reproduce the problem anymore). I am lacking adequate
documentation, I have little time to work on the driver, but quite a
to do list.
Does that sound like via-rhine would make a good guinea pig?
> The other drivers should be fixed as well. Phy access with irq's disabled
> is not good. The hardware I checked takes 100's of usecs to do one read
> transaction.
If you want to fix this in all drivers, more power to you. It is just not
high on my own priority list. I see the need for low latency, but latency
issues that only happen when people fiddle with MII settings don't seem all
that dramatic to me.
Roger
^ permalink raw reply
* Re: [PATCH] atm: clip timer race
From: Herbert Xu @ 2006-04-13 22:11 UTC (permalink / raw)
To: Roland Dreier; +Cc: herbert, shemminger, davem, chas, linux-atm-general, netdev
In-Reply-To: <adaek01p4j6.fsf@cisco.com>
Roland Dreier <rdreier@cisco.com> wrote:
>
> I'm probably missing an obvious race but it seems del_timer_sync()
> should be fine on a timer that reschedules itself. del_timer_sync()
> loops until try_to_del_timer_sync() succeeds, and
> try_to_del_timer_sync() will fail unless the timer being killed is not
> running (and it does this test with the timer base lock held).
>
> OK, how am I being stupid?
No you're definitely right. I just missed the fix that was made
to del_timer_sync last year.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [patch 1/3] softmac: return -EAGAIN from getscan while scanning
From: Pete Zaitcev @ 2006-04-13 22:21 UTC (permalink / raw)
To: Dan Williams; +Cc: johannes, netdev, linville, zaitcev
In-Reply-To: <1144930375.2372.10.camel@localhost.localdomain>
On Thu, 13 Apr 2006 08:12:55 -0400, Dan Williams <dcbw@redhat.com> wrote:
> > This sounds completely wrong. Do you guys remember the Subject: string
> > of this discussion by any chance?
> There are two options for tools: (a) request scan and block on GIWSCAN
> until it doesn't return EAGAIN, or (b) request a scan, enter a loop,
> wait for the GIWSCAN netlink message to come back. The point here is
> that if you have to write a tool with 100 lines of netlink message
> processing code _just_ to get the "scan done!" message, that's a bitch.
> More complicated programs can obviously do this, but simple tools don't
> want or need to.
Do you realize that "block" means "enterering the kernel and calling
schedule()", which is exactly what is NOT happening in the patch?
I would not mind if the tools "blocked in GIWSCAN", only until
it returns success and not EGAIN.
With EAGAIN returned, you have to a) block elsewhere and not in
GIWSCAN (perhaps in sleep(2) or select(2)), or b) not block at all
and loop.
> I believe that the patch for softmac/bcm43xx EAGAIN is correct.
It is correct, no doubt. The discussion is about wether it is
desirable.
-- Pete
^ permalink raw reply
* [PATCH 2/4] clip: get rid of PROC_FS ifdef
From: Stephen Hemminger @ 2006-04-13 22:23 UTC (permalink / raw)
To: David S. Miller; +Cc: chas, linux-atm-general, netdev, stable
In-Reply-To: <20060413151945.0f181d04@localhost.localdomain>
Don't need the ifdef here since create_proc_entry() is stubbed to always
return NULL.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
--- clip.orig/net/atm/clip.c 2006-04-13 15:18:21.000000000 -0700
+++ clip/net/atm/clip.c 2006-04-13 15:20:26.000000000 -0700
@@ -976,6 +976,7 @@
static int __init atm_clip_init(void)
{
+ struct proc_dir_entry *p;
neigh_table_init(&clip_tbl);
clip_tbl_hook = &clip_tbl;
@@ -985,15 +986,9 @@
setup_timer(&idle_timer, idle_timer_check, 0);
-#ifdef CONFIG_PROC_FS
- {
- struct proc_dir_entry *p;
-
- p = create_proc_entry("arp", S_IRUGO, atm_proc_root);
- if (p)
- p->proc_fops = &arp_seq_fops;
- }
-#endif
+ p = create_proc_entry("arp", S_IRUGO, atm_proc_root);
+ if (p)
+ p->proc_fops = &arp_seq_fops;
return 0;
}
^ permalink raw reply
* [PATCH 4/4] clip: add module info
From: Stephen Hemminger @ 2006-04-13 22:24 UTC (permalink / raw)
To: David S. Miller; +Cc: chas, linux-atm-general, netdev, stable
In-Reply-To: <20060413152224.2d46df99@localhost.localdomain>
Add module information
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
--- clip.orig/net/atm/clip.c 2006-04-13 15:20:38.000000000 -0700
+++ clip/net/atm/clip.c 2006-04-13 15:23:41.000000000 -0700
@@ -1017,5 +1017,6 @@
module_init(atm_clip_init);
module_exit(atm_clip_exit);
-
+MODULE_AUTHOR("Werner Almesberger");
+MODULE_DESCRIPTION("Classical/IP over ATM interface");
MODULE_LICENSE("GPL");
^ permalink raw reply
* [PATCH 3/4] clip: notifier related cleanups
From: Stephen Hemminger @ 2006-04-13 22:23 UTC (permalink / raw)
To: David S. Miller; +Cc: chas, linux-atm-general, netdev, stable
In-Reply-To: <20060413151945.0f181d04@localhost.localdomain>
Cleanup some code around notifier. Don't need (void) casts to ignore
return values, and use C90 style initializer. Just ignore unused device
events.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
--- clip.orig/net/atm/clip.c 2006-04-13 15:20:26.000000000 -0700
+++ clip/net/atm/clip.c 2006-04-13 15:20:38.000000000 -0700
@@ -443,7 +443,7 @@
}
clip_priv->stats.tx_packets++;
clip_priv->stats.tx_bytes += skb->len;
- (void)vcc->send(vcc, skb);
+ vcc->send(vcc, skb);
if (atm_may_send(vcc, 0)) {
entry->vccs->xoff = 0;
return 0;
@@ -620,26 +620,16 @@
switch (event) {
case NETDEV_UP:
DPRINTK("clip_device_event NETDEV_UP\n");
- (void)to_atmarpd(act_up, PRIV(dev)->number, 0);
+ to_atmarpd(act_up, PRIV(dev)->number, 0);
break;
case NETDEV_GOING_DOWN:
DPRINTK("clip_device_event NETDEV_DOWN\n");
- (void)to_atmarpd(act_down, PRIV(dev)->number, 0);
+ to_atmarpd(act_down, PRIV(dev)->number, 0);
break;
case NETDEV_CHANGE:
case NETDEV_CHANGEMTU:
DPRINTK("clip_device_event NETDEV_CHANGE*\n");
- (void)to_atmarpd(act_change, PRIV(dev)->number, 0);
- break;
- case NETDEV_REBOOT:
- case NETDEV_REGISTER:
- case NETDEV_DOWN:
- DPRINTK("clip_device_event %ld\n", event);
- /* ignore */
- break;
- default:
- printk(KERN_WARNING "clip_device_event: unknown event "
- "%ld\n", event);
+ to_atmarpd(act_change, PRIV(dev)->number, 0);
break;
}
return NOTIFY_DONE;
@@ -666,17 +656,13 @@
static struct notifier_block clip_dev_notifier = {
- clip_device_event,
- NULL,
- 0
+ .notifier_call = clip_device_event,
};
static struct notifier_block clip_inet_notifier = {
- clip_inet_event,
- NULL,
- 0
+ .notifier_call = clip_inet_event,
};
^ permalink raw reply
* [PATCH 1/4] clip: run through Lindent
From: Stephen Hemminger @ 2006-04-13 22:22 UTC (permalink / raw)
To: David S. Miller; +Cc: chas, linux-atm-general, netdev, stable
In-Reply-To: <20060412105545.3b089dd8@localhost.localdomain>
Run CLIP driver through Lindent script to fix formatting.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
--- clip.orig/net/atm/clip.c 2006-04-13 09:44:22.000000000 -0700
+++ clip/net/atm/clip.c 2006-04-13 15:18:21.000000000 -0700
@@ -2,7 +2,6 @@
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
#include <linux/config.h>
#include <linux/string.h>
#include <linux/errno.h>
@@ -55,21 +54,23 @@
static struct neigh_table clip_tbl;
static struct timer_list idle_timer;
-static int to_atmarpd(enum atmarp_ctrl_type type,int itf,unsigned long ip)
+static int to_atmarpd(enum atmarp_ctrl_type type, int itf, unsigned long ip)
{
struct sock *sk;
struct atmarp_ctrl *ctrl;
struct sk_buff *skb;
- DPRINTK("to_atmarpd(%d)\n",type);
- if (!atmarpd) return -EUNATCH;
+ DPRINTK("to_atmarpd(%d)\n", type);
+ if (!atmarpd)
+ return -EUNATCH;
skb = alloc_skb(sizeof(struct atmarp_ctrl),GFP_ATOMIC);
- if (!skb) return -ENOMEM;
+ if (!skb)
+ return -ENOMEM;
ctrl = (struct atmarp_ctrl *) skb_put(skb,sizeof(struct atmarp_ctrl));
ctrl->type = type;
ctrl->itf_num = itf;
ctrl->ip = ip;
- atm_force_charge(atmarpd,skb->truesize);
+ atm_force_charge(atmarpd, skb->truesize);
sk = sk_atm(atmarpd);
skb_queue_tail(&sk->sk_receive_queue, skb);
@@ -77,26 +78,24 @@
return 0;
}
-
-static void link_vcc(struct clip_vcc *clip_vcc,struct atmarp_entry *entry)
+static void link_vcc(struct clip_vcc *clip_vcc, struct atmarp_entry *entry)
{
- DPRINTK("link_vcc %p to entry %p (neigh %p)\n",clip_vcc,entry,
- entry->neigh);
+ DPRINTK("link_vcc %p to entry %p (neigh %p)\n", clip_vcc, entry,
+ entry->neigh);
clip_vcc->entry = entry;
- clip_vcc->xoff = 0; /* @@@ may overrun buffer by one packet */
+ clip_vcc->xoff = 0; /* @@@ may overrun buffer by one packet */
clip_vcc->next = entry->vccs;
entry->vccs = clip_vcc;
entry->neigh->used = jiffies;
}
-
static void unlink_clip_vcc(struct clip_vcc *clip_vcc)
{
struct atmarp_entry *entry = clip_vcc->entry;
struct clip_vcc **walk;
if (!entry) {
- printk(KERN_CRIT "!clip_vcc->entry (clip_vcc %p)\n",clip_vcc);
+ printk(KERN_CRIT "!clip_vcc->entry (clip_vcc %p)\n", clip_vcc);
return;
}
spin_lock_bh(&entry->neigh->dev->xmit_lock); /* block clip_start_xmit() */
@@ -105,24 +104,24 @@
if (*walk == clip_vcc) {
int error;
- *walk = clip_vcc->next; /* atomic */
+ *walk = clip_vcc->next; /* atomic */
clip_vcc->entry = NULL;
if (clip_vcc->xoff)
netif_wake_queue(entry->neigh->dev);
if (entry->vccs)
goto out;
- entry->expires = jiffies-1;
- /* force resolution or expiration */
+ entry->expires = jiffies - 1;
+ /* force resolution or expiration */
error = neigh_update(entry->neigh, NULL, NUD_NONE,
NEIGH_UPDATE_F_ADMIN);
if (error)
printk(KERN_CRIT "unlink_clip_vcc: "
- "neigh_update failed with %d\n",error);
+ "neigh_update failed with %d\n", error);
goto out;
}
printk(KERN_CRIT "ATMARP: unlink_clip_vcc failed (entry %p, vcc "
- "0x%p)\n",entry,clip_vcc);
-out:
+ "0x%p)\n", entry, clip_vcc);
+ out:
spin_unlock_bh(&entry->neigh->dev->xmit_lock);
}
@@ -151,13 +150,13 @@
DPRINTK("destruction postponed with ref %d\n",
atomic_read(&n->refcnt));
- while ((skb = skb_dequeue(&n->arp_queue)) != NULL)
+ while ((skb = skb_dequeue(&n->arp_queue)) != NULL)
dev_kfree_skb(skb);
return 0;
}
- DPRINTK("expired neigh %p\n",n);
+ DPRINTK("expired neigh %p\n", n);
return 1;
}
@@ -165,7 +164,7 @@
{
write_lock(&clip_tbl.lock);
__neigh_for_each_release(&clip_tbl, neigh_check_cb);
- mod_timer(&idle_timer, jiffies+CLIP_CHECK_INTERVAL*HZ);
+ mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
write_unlock(&clip_tbl.lock);
}
@@ -175,13 +174,13 @@
DPRINTK("clip_arp_rcv\n");
vcc = ATM_SKB(skb)->vcc;
- if (!vcc || !atm_charge(vcc,skb->truesize)) {
+ if (!vcc || !atm_charge(vcc, skb->truesize)) {
dev_kfree_skb_any(skb);
return 0;
}
- DPRINTK("pushing to %p\n",vcc);
- DPRINTK("using %p\n",CLIP_VCC(vcc)->old_push);
- CLIP_VCC(vcc)->old_push(vcc,skb);
+ DPRINTK("pushing to %p\n", vcc);
+ DPRINTK("using %p\n", CLIP_VCC(vcc)->old_push);
+ CLIP_VCC(vcc)->old_push(vcc, skb);
return 0;
}
@@ -191,34 +190,38 @@
0x03, /* Ctrl: Unnumbered Information Command PDU */
0x00, /* OUI: EtherType */
0x00,
- 0x00 };
+ 0x00
+};
-static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb)
+static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb)
{
struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
DPRINTK("clip push\n");
if (!skb) {
- DPRINTK("removing VCC %p\n",clip_vcc);
- if (clip_vcc->entry) unlink_clip_vcc(clip_vcc);
- clip_vcc->old_push(vcc,NULL); /* pass on the bad news */
+ DPRINTK("removing VCC %p\n", clip_vcc);
+ if (clip_vcc->entry)
+ unlink_clip_vcc(clip_vcc);
+ clip_vcc->old_push(vcc, NULL); /* pass on the bad news */
kfree(clip_vcc);
return;
}
- atm_return(vcc,skb->truesize);
+ atm_return(vcc, skb->truesize);
skb->dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : clip_devs;
- /* clip_vcc->entry == NULL if we don't have an IP address yet */
+ /* clip_vcc->entry == NULL if we don't have an IP address yet */
if (!skb->dev) {
dev_kfree_skb_any(skb);
return;
}
ATM_SKB(skb)->vcc = vcc;
skb->mac.raw = skb->data;
- if (!clip_vcc->encap || skb->len < RFC1483LLC_LEN || memcmp(skb->data,
- llc_oui,sizeof(llc_oui))) skb->protocol = htons(ETH_P_IP);
+ if (!clip_vcc->encap
+ || skb->len < RFC1483LLC_LEN
+ || memcmp(skb->data, llc_oui, sizeof (llc_oui)))
+ skb->protocol = htons(ETH_P_IP);
else {
skb->protocol = ((u16 *) skb->data)[3];
- skb_pull(skb,RFC1483LLC_LEN);
+ skb_pull(skb, RFC1483LLC_LEN);
if (skb->protocol == htons(ETH_P_ARP)) {
PRIV(skb->dev)->stats.rx_packets++;
PRIV(skb->dev)->stats.rx_bytes += skb->len;
@@ -233,58 +236,54 @@
netif_rx(skb);
}
-
/*
* Note: these spinlocks _must_not_ block on non-SMP. The only goal is that
* clip_pop is atomic with respect to the critical section in clip_start_xmit.
*/
-
-static void clip_pop(struct atm_vcc *vcc,struct sk_buff *skb)
+static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb)
{
struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
struct net_device *dev = skb->dev;
int old;
unsigned long flags;
- DPRINTK("clip_pop(vcc %p)\n",vcc);
- clip_vcc->old_pop(vcc,skb);
+ DPRINTK("clip_pop(vcc %p)\n", vcc);
+ clip_vcc->old_pop(vcc, skb);
/* skb->dev == NULL in outbound ARP packets */
- if (!dev) return;
- spin_lock_irqsave(&PRIV(dev)->xoff_lock,flags);
- if (atm_may_send(vcc,0)) {
- old = xchg(&clip_vcc->xoff,0);
- if (old) netif_wake_queue(dev);
+ if (!dev)
+ return;
+ spin_lock_irqsave(&PRIV(dev)->xoff_lock, flags);
+ if (atm_may_send(vcc, 0)) {
+ old = xchg(&clip_vcc->xoff, 0);
+ if (old)
+ netif_wake_queue(dev);
}
- spin_unlock_irqrestore(&PRIV(dev)->xoff_lock,flags);
+ spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags);
}
-
static void clip_neigh_destroy(struct neighbour *neigh)
{
- DPRINTK("clip_neigh_destroy (neigh %p)\n",neigh);
+ DPRINTK("clip_neigh_destroy (neigh %p)\n", neigh);
if (NEIGH2ENTRY(neigh)->vccs)
printk(KERN_CRIT "clip_neigh_destroy: vccs != NULL !!!\n");
NEIGH2ENTRY(neigh)->vccs = (void *) 0xdeadbeef;
}
-
-static void clip_neigh_solicit(struct neighbour *neigh,struct sk_buff *skb)
+static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb)
{
- DPRINTK("clip_neigh_solicit (neigh %p, skb %p)\n",neigh,skb);
- to_atmarpd(act_need,PRIV(neigh->dev)->number,NEIGH2ENTRY(neigh)->ip);
+ DPRINTK("clip_neigh_solicit (neigh %p, skb %p)\n", neigh, skb);
+ to_atmarpd(act_need, PRIV(neigh->dev)->number, NEIGH2ENTRY(neigh)->ip);
}
-
-static void clip_neigh_error(struct neighbour *neigh,struct sk_buff *skb)
+static void clip_neigh_error(struct neighbour *neigh, struct sk_buff *skb)
{
#ifndef CONFIG_ATM_CLIP_NO_ICMP
- icmp_send(skb,ICMP_DEST_UNREACH,ICMP_HOST_UNREACH,0);
+ icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
#endif
kfree_skb(skb);
}
-
static struct neigh_ops clip_neigh_ops = {
.family = AF_INET,
.solicit = clip_neigh_solicit,
@@ -295,7 +294,6 @@
.queue_xmit = dev_queue_xmit,
};
-
static int clip_constructor(struct neighbour *neigh)
{
struct atmarp_entry *entry = NEIGH2ENTRY(neigh);
@@ -303,9 +301,10 @@
struct in_device *in_dev;
struct neigh_parms *parms;
- DPRINTK("clip_constructor (neigh %p, entry %p)\n",neigh,entry);
+ DPRINTK("clip_constructor (neigh %p, entry %p)\n", neigh, entry);
neigh->type = inet_addr_type(entry->ip);
- if (neigh->type != RTN_UNICAST) return -EINVAL;
+ if (neigh->type != RTN_UNICAST)
+ return -EINVAL;
rcu_read_lock();
in_dev = __in_dev_get_rcu(dev);
@@ -324,13 +323,13 @@
neigh->ops->connected_output : neigh->ops->output;
entry->neigh = neigh;
entry->vccs = NULL;
- entry->expires = jiffies-1;
+ entry->expires = jiffies - 1;
return 0;
}
static u32 clip_hash(const void *pkey, const struct net_device *dev)
{
- return jhash_2words(*(u32 *)pkey, dev->ifindex, clip_tbl.hash_rnd);
+ return jhash_2words(*(u32 *) pkey, dev->ifindex, clip_tbl.hash_rnd);
}
static struct neigh_table clip_tbl = {
@@ -364,7 +363,6 @@
.gc_thresh3 = 1024,
};
-
/* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */
/*
@@ -374,15 +372,13 @@
* clip_setentry.
*/
-
-static int clip_encap(struct atm_vcc *vcc,int mode)
+static int clip_encap(struct atm_vcc *vcc, int mode)
{
CLIP_VCC(vcc)->encap = mode;
return 0;
}
-
-static int clip_start_xmit(struct sk_buff *skb,struct net_device *dev)
+static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct clip_priv *clip_priv = PRIV(dev);
struct atmarp_entry *entry;
@@ -390,7 +386,7 @@
int old;
unsigned long flags;
- DPRINTK("clip_start_xmit (skb %p)\n",skb);
+ DPRINTK("clip_start_xmit (skb %p)\n", skb);
if (!skb->dst) {
printk(KERN_ERR "clip_start_xmit: skb->dst == NULL\n");
dev_kfree_skb(skb);
@@ -399,9 +395,9 @@
}
if (!skb->dst->neighbour) {
#if 0
- skb->dst->neighbour = clip_find_neighbour(skb->dst,1);
+ skb->dst->neighbour = clip_find_neighbour(skb->dst, 1);
if (!skb->dst->neighbour) {
- dev_kfree_skb(skb); /* lost that one */
+ dev_kfree_skb(skb); /* lost that one */
clip_priv->stats.tx_dropped++;
return 0;
}
@@ -415,73 +411,73 @@
if (!entry->vccs) {
if (time_after(jiffies, entry->expires)) {
/* should be resolved */
- entry->expires = jiffies+ATMARP_RETRY_DELAY*HZ;
- to_atmarpd(act_need,PRIV(dev)->number,entry->ip);
+ entry->expires = jiffies + ATMARP_RETRY_DELAY * HZ;
+ to_atmarpd(act_need, PRIV(dev)->number, entry->ip);
}
if (entry->neigh->arp_queue.qlen < ATMARP_MAX_UNRES_PACKETS)
- skb_queue_tail(&entry->neigh->arp_queue,skb);
+ skb_queue_tail(&entry->neigh->arp_queue, skb);
else {
dev_kfree_skb(skb);
clip_priv->stats.tx_dropped++;
}
return 0;
}
- DPRINTK("neigh %p, vccs %p\n",entry,entry->vccs);
+ DPRINTK("neigh %p, vccs %p\n", entry, entry->vccs);
ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc;
- DPRINTK("using neighbour %p, vcc %p\n",skb->dst->neighbour,vcc);
+ DPRINTK("using neighbour %p, vcc %p\n", skb->dst->neighbour, vcc);
if (entry->vccs->encap) {
void *here;
- here = skb_push(skb,RFC1483LLC_LEN);
- memcpy(here,llc_oui,sizeof(llc_oui));
+ here = skb_push(skb, RFC1483LLC_LEN);
+ memcpy(here, llc_oui, sizeof(llc_oui));
((u16 *) here)[3] = skb->protocol;
}
atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
ATM_SKB(skb)->atm_options = vcc->atm_options;
entry->vccs->last_use = jiffies;
- DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n",skb,vcc,vcc->dev);
- old = xchg(&entry->vccs->xoff,1); /* assume XOFF ... */
+ DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, vcc, vcc->dev);
+ old = xchg(&entry->vccs->xoff, 1); /* assume XOFF ... */
if (old) {
printk(KERN_WARNING "clip_start_xmit: XOFF->XOFF transition\n");
return 0;
}
clip_priv->stats.tx_packets++;
clip_priv->stats.tx_bytes += skb->len;
- (void) vcc->send(vcc,skb);
- if (atm_may_send(vcc,0)) {
+ (void)vcc->send(vcc, skb);
+ if (atm_may_send(vcc, 0)) {
entry->vccs->xoff = 0;
return 0;
}
- spin_lock_irqsave(&clip_priv->xoff_lock,flags);
- netif_stop_queue(dev); /* XOFF -> throttle immediately */
+ spin_lock_irqsave(&clip_priv->xoff_lock, flags);
+ netif_stop_queue(dev); /* XOFF -> throttle immediately */
barrier();
if (!entry->vccs->xoff)
netif_start_queue(dev);
- /* Oh, we just raced with clip_pop. netif_start_queue should be
- good enough, because nothing should really be asleep because
- of the brief netif_stop_queue. If this isn't true or if it
- changes, use netif_wake_queue instead. */
- spin_unlock_irqrestore(&clip_priv->xoff_lock,flags);
+ /* Oh, we just raced with clip_pop. netif_start_queue should be
+ good enough, because nothing should really be asleep because
+ of the brief netif_stop_queue. If this isn't true or if it
+ changes, use netif_wake_queue instead. */
+ spin_unlock_irqrestore(&clip_priv->xoff_lock, flags);
return 0;
}
-
static struct net_device_stats *clip_get_stats(struct net_device *dev)
{
return &PRIV(dev)->stats;
}
-
-static int clip_mkip(struct atm_vcc *vcc,int timeout)
+static int clip_mkip(struct atm_vcc *vcc, int timeout)
{
struct clip_vcc *clip_vcc;
struct sk_buff_head copy;
struct sk_buff *skb;
- if (!vcc->push) return -EBADFD;
- clip_vcc = kmalloc(sizeof(struct clip_vcc),GFP_KERNEL);
- if (!clip_vcc) return -ENOMEM;
- DPRINTK("mkip clip_vcc %p vcc %p\n",clip_vcc,vcc);
+ if (!vcc->push)
+ return -EBADFD;
+ clip_vcc = kmalloc(sizeof(struct clip_vcc), GFP_KERNEL);
+ if (!clip_vcc)
+ return -ENOMEM;
+ DPRINTK("mkip clip_vcc %p vcc %p\n", clip_vcc, vcc);
clip_vcc->vcc = vcc;
vcc->user_back = clip_vcc;
set_bit(ATM_VF_IS_CLIP, &vcc->flags);
@@ -489,7 +485,7 @@
clip_vcc->xoff = 0;
clip_vcc->encap = 1;
clip_vcc->last_use = jiffies;
- clip_vcc->idle_timeout = timeout*HZ;
+ clip_vcc->idle_timeout = timeout * HZ;
clip_vcc->old_push = vcc->push;
clip_vcc->old_pop = vcc->pop;
vcc->push = clip_push;
@@ -499,27 +495,25 @@
/* re-process everything received between connection setup and MKIP */
while ((skb = skb_dequeue(©)) != NULL)
if (!clip_devs) {
- atm_return(vcc,skb->truesize);
+ atm_return(vcc, skb->truesize);
kfree_skb(skb);
- }
- else {
+ } else {
unsigned int len = skb->len;
- clip_push(vcc,skb);
+ clip_push(vcc, skb);
PRIV(skb->dev)->stats.rx_packets--;
PRIV(skb->dev)->stats.rx_bytes -= len;
}
return 0;
}
-
-static int clip_setentry(struct atm_vcc *vcc,u32 ip)
+static int clip_setentry(struct atm_vcc *vcc, u32 ip)
{
struct neighbour *neigh;
struct atmarp_entry *entry;
int error;
struct clip_vcc *clip_vcc;
- struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, .tos = 1 } } };
+ struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, .tos = 1}} };
struct rtable *rt;
if (vcc->push != clip_push) {
@@ -536,28 +530,29 @@
unlink_clip_vcc(clip_vcc);
return 0;
}
- error = ip_route_output_key(&rt,&fl);
- if (error) return error;
- neigh = __neigh_lookup(&clip_tbl,&ip,rt->u.dst.dev,1);
+ error = ip_route_output_key(&rt, &fl);
+ if (error)
+ return error;
+ neigh = __neigh_lookup(&clip_tbl, &ip, rt->u.dst.dev, 1);
ip_rt_put(rt);
if (!neigh)
return -ENOMEM;
entry = NEIGH2ENTRY(neigh);
if (entry != clip_vcc->entry) {
- if (!clip_vcc->entry) DPRINTK("setentry: add\n");
+ if (!clip_vcc->entry)
+ DPRINTK("setentry: add\n");
else {
DPRINTK("setentry: update\n");
unlink_clip_vcc(clip_vcc);
}
- link_vcc(clip_vcc,entry);
+ link_vcc(clip_vcc, entry);
}
- error = neigh_update(neigh, llc_oui, NUD_PERMANENT,
- NEIGH_UPDATE_F_OVERRIDE|NEIGH_UPDATE_F_ADMIN);
+ error = neigh_update(neigh, llc_oui, NUD_PERMANENT,
+ NEIGH_UPDATE_F_OVERRIDE | NEIGH_UPDATE_F_ADMIN);
neigh_release(neigh);
return error;
}
-
static void clip_setup(struct net_device *dev)
{
dev->hard_start_xmit = clip_start_xmit;
@@ -566,15 +561,14 @@
dev->type = ARPHRD_ATM;
dev->hard_header_len = RFC1483LLC_LEN;
dev->mtu = RFC1626_MTU;
- dev->tx_queue_len = 100; /* "normal" queue (packets) */
- /* When using a "real" qdisc, the qdisc determines the queue */
- /* length. tx_queue_len is only used for the default case, */
- /* without any more elaborate queuing. 100 is a reasonable */
- /* compromise between decent burst-tolerance and protection */
- /* against memory hogs. */
+ dev->tx_queue_len = 100; /* "normal" queue (packets) */
+ /* When using a "real" qdisc, the qdisc determines the queue */
+ /* length. tx_queue_len is only used for the default case, */
+ /* without any more elaborate queuing. 100 is a reasonable */
+ /* compromise between decent burst-tolerance and protection */
+ /* against memory hogs. */
}
-
static int clip_create(int number)
{
struct net_device *dev;
@@ -583,19 +577,19 @@
if (number != -1) {
for (dev = clip_devs; dev; dev = PRIV(dev)->next)
- if (PRIV(dev)->number == number) return -EEXIST;
- }
- else {
+ if (PRIV(dev)->number == number)
+ return -EEXIST;
+ } else {
number = 0;
for (dev = clip_devs; dev; dev = PRIV(dev)->next)
if (PRIV(dev)->number >= number)
- number = PRIV(dev)->number+1;
+ number = PRIV(dev)->number + 1;
}
dev = alloc_netdev(sizeof(struct clip_priv), "", clip_setup);
if (!dev)
return -ENOMEM;
clip_priv = PRIV(dev);
- sprintf(dev->name,"atm%d",number);
+ sprintf(dev->name, "atm%d", number);
spin_lock_init(&clip_priv->xoff_lock);
clip_priv->number = number;
error = register_netdev(dev);
@@ -605,12 +599,11 @@
}
clip_priv->next = clip_devs;
clip_devs = dev;
- DPRINTK("registered (net:%s)\n",dev->name);
+ DPRINTK("registered (net:%s)\n", dev->name);
return number;
}
-
-static int clip_device_event(struct notifier_block *this,unsigned long event,
+static int clip_device_event(struct notifier_block *this, unsigned long event,
void *arg)
{
struct net_device *dev = arg;
@@ -625,40 +618,39 @@
return NOTIFY_DONE;
switch (event) {
- case NETDEV_UP:
- DPRINTK("clip_device_event NETDEV_UP\n");
- (void) to_atmarpd(act_up,PRIV(dev)->number,0);
- break;
- case NETDEV_GOING_DOWN:
- DPRINTK("clip_device_event NETDEV_DOWN\n");
- (void) to_atmarpd(act_down,PRIV(dev)->number,0);
- break;
- case NETDEV_CHANGE:
- case NETDEV_CHANGEMTU:
- DPRINTK("clip_device_event NETDEV_CHANGE*\n");
- (void) to_atmarpd(act_change,PRIV(dev)->number,0);
- break;
- case NETDEV_REBOOT:
- case NETDEV_REGISTER:
- case NETDEV_DOWN:
- DPRINTK("clip_device_event %ld\n",event);
- /* ignore */
- break;
- default:
- printk(KERN_WARNING "clip_device_event: unknown event "
- "%ld\n",event);
- break;
+ case NETDEV_UP:
+ DPRINTK("clip_device_event NETDEV_UP\n");
+ (void)to_atmarpd(act_up, PRIV(dev)->number, 0);
+ break;
+ case NETDEV_GOING_DOWN:
+ DPRINTK("clip_device_event NETDEV_DOWN\n");
+ (void)to_atmarpd(act_down, PRIV(dev)->number, 0);
+ break;
+ case NETDEV_CHANGE:
+ case NETDEV_CHANGEMTU:
+ DPRINTK("clip_device_event NETDEV_CHANGE*\n");
+ (void)to_atmarpd(act_change, PRIV(dev)->number, 0);
+ break;
+ case NETDEV_REBOOT:
+ case NETDEV_REGISTER:
+ case NETDEV_DOWN:
+ DPRINTK("clip_device_event %ld\n", event);
+ /* ignore */
+ break;
+ default:
+ printk(KERN_WARNING "clip_device_event: unknown event "
+ "%ld\n", event);
+ break;
}
return NOTIFY_DONE;
}
-
-static int clip_inet_event(struct notifier_block *this,unsigned long event,
- void *ifa)
+static int clip_inet_event(struct notifier_block *this, unsigned long event,
+ void *ifa)
{
struct in_device *in_dev;
- in_dev = ((struct in_ifaddr *) ifa)->ifa_dev;
+ in_dev = ((struct in_ifaddr *)ifa)->ifa_dev;
if (!in_dev || !in_dev->dev) {
printk(KERN_WARNING "clip_inet_event: no device\n");
return NOTIFY_DONE;
@@ -667,8 +659,9 @@
* Transitions are of the down-change-up type, so it's sufficient to
* handle the change on up.
*/
- if (event != NETDEV_UP) return NOTIFY_DONE;
- return clip_device_event(this,NETDEV_CHANGE,in_dev->dev);
+ if (event != NETDEV_UP)
+ return NOTIFY_DONE;
+ return clip_device_event(this, NETDEV_CHANGE, in_dev->dev);
}
@@ -744,53 +737,53 @@
int err = 0;
switch (cmd) {
- case SIOCMKCLIP:
- case ATMARPD_CTRL:
- case ATMARP_MKIP:
- case ATMARP_SETENTRY:
- case ATMARP_ENCAP:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- break;
- default:
- return -ENOIOCTLCMD;
+ case SIOCMKCLIP:
+ case ATMARPD_CTRL:
+ case ATMARP_MKIP:
+ case ATMARP_SETENTRY:
+ case ATMARP_ENCAP:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ break;
+ default:
+ return -ENOIOCTLCMD;
}
switch (cmd) {
- case SIOCMKCLIP:
- err = clip_create(arg);
- break;
- case ATMARPD_CTRL:
- err = atm_init_atmarp(vcc);
- if (!err) {
- sock->state = SS_CONNECTED;
- __module_get(THIS_MODULE);
- }
- break;
- case ATMARP_MKIP:
- err = clip_mkip(vcc ,arg);
- break;
- case ATMARP_SETENTRY:
- err = clip_setentry(vcc, arg);
- break;
- case ATMARP_ENCAP:
- err = clip_encap(vcc, arg);
- break;
+ case SIOCMKCLIP:
+ err = clip_create(arg);
+ break;
+ case ATMARPD_CTRL:
+ err = atm_init_atmarp(vcc);
+ if (!err) {
+ sock->state = SS_CONNECTED;
+ __module_get(THIS_MODULE);
+ }
+ break;
+ case ATMARP_MKIP:
+ err = clip_mkip(vcc, arg);
+ break;
+ case ATMARP_SETENTRY:
+ err = clip_setentry(vcc, arg);
+ break;
+ case ATMARP_ENCAP:
+ err = clip_encap(vcc, arg);
+ break;
}
return err;
}
static struct atm_ioctl clip_ioctl_ops = {
- .owner = THIS_MODULE,
- .ioctl = clip_ioctl,
+ .owner = THIS_MODULE,
+ .ioctl = clip_ioctl,
};
#ifdef CONFIG_PROC_FS
static void svc_addr(struct seq_file *seq, struct sockaddr_atmsvc *addr)
{
- static int code[] = { 1,2,10,6,1,0 };
- static int e164[] = { 1,8,4,6,1,0 };
+ static int code[] = { 1, 2, 10, 6, 1, 0 };
+ static int e164[] = { 1, 8, 4, 6, 1, 0 };
if (*addr->sas_addr.pub) {
seq_printf(seq, "%s", addr->sas_addr.pub);
@@ -809,7 +802,7 @@
for (i = 0; fields[i]; i++) {
for (j = fields[i]; j; j--)
seq_printf(seq, "%02X", *prv++);
- if (fields[i+1])
+ if (fields[i + 1])
seq_putc(seq, '.');
}
}
@@ -828,8 +821,7 @@
svc = ((clip_vcc == SEQ_NO_VCC_TOKEN) ||
(sk_atm(clip_vcc->vcc)->sk_family == AF_ATMSVC));
- llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) ||
- clip_vcc->encap);
+ llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || clip_vcc->encap);
if (clip_vcc == SEQ_NO_VCC_TOKEN)
exp = entry->neigh->used;
@@ -839,10 +831,7 @@
exp = (jiffies - exp) / HZ;
seq_printf(seq, "%-6s%-4s%-4s%5ld ",
- dev->name,
- svc ? "SVC" : "PVC",
- llc ? "LLC" : "NULL",
- exp);
+ dev->name, svc ? "SVC" : "PVC", llc ? "LLC" : "NULL", exp);
off = scnprintf(buf, sizeof(buf) - 1, "%d.%d.%d.%d",
NIPQUAD(entry->ip));
@@ -860,8 +849,7 @@
} else if (!svc) {
seq_printf(seq, "%d.%d.%d\n",
clip_vcc->vcc->dev->number,
- clip_vcc->vcc->vpi,
- clip_vcc->vcc->vci);
+ clip_vcc->vcc->vpi, clip_vcc->vcc->vci);
} else {
svc_addr(seq, &clip_vcc->vcc->remote);
seq_putc(seq, '\n');
@@ -894,7 +882,7 @@
}
static void *clip_seq_vcc_walk(struct clip_seq_state *state,
- struct atmarp_entry *e, loff_t *pos)
+ struct atmarp_entry *e, loff_t * pos)
{
struct clip_vcc *vcc = state->vcc;
@@ -911,24 +899,24 @@
return vcc;
}
-
+
static void *clip_seq_sub_iter(struct neigh_seq_state *_state,
- struct neighbour *n, loff_t *pos)
+ struct neighbour *n, loff_t * pos)
{
- struct clip_seq_state *state = (struct clip_seq_state *) _state;
+ struct clip_seq_state *state = (struct clip_seq_state *)_state;
return clip_seq_vcc_walk(state, NEIGH2ENTRY(n), pos);
}
-static void *clip_seq_start(struct seq_file *seq, loff_t *pos)
+static void *clip_seq_start(struct seq_file *seq, loff_t * pos)
{
return neigh_seq_start(seq, pos, &clip_tbl, NEIGH_SEQ_NEIGH_ONLY);
}
static int clip_seq_show(struct seq_file *seq, void *v)
{
- static char atm_arp_banner[] =
- "IPitf TypeEncp Idle IP address ATM address\n";
+ static char atm_arp_banner[] =
+ "IPitf TypeEncp Idle IP address ATM address\n";
if (v == SEQ_START_TOKEN) {
seq_puts(seq, atm_arp_banner);
@@ -939,7 +927,7 @@
atmarp_info(seq, n->dev, NEIGH2ENTRY(n), vcc);
}
- return 0;
+ return 0;
}
static struct seq_operations arp_seq_ops = {
@@ -998,13 +986,13 @@
setup_timer(&idle_timer, idle_timer_check, 0);
#ifdef CONFIG_PROC_FS
-{
- struct proc_dir_entry *p;
+ {
+ struct proc_dir_entry *p;
- p = create_proc_entry("arp", S_IRUGO, atm_proc_root);
- if (p)
- p->proc_fops = &arp_seq_fops;
-}
+ p = create_proc_entry("arp", S_IRUGO, atm_proc_root);
+ if (p)
+ p->proc_fops = &arp_seq_fops;
+ }
#endif
return 0;
^ permalink raw reply
* Re: [patch 1/3] softmac: return -EAGAIN from getscan while scanning
From: Pete Zaitcev @ 2006-04-13 22:28 UTC (permalink / raw)
To: Jouni Malinen; +Cc: johannes, dcbw, netdev, linville, softmac-dev, zaitcev
In-Reply-To: <20060413160051.GE15499@instant802.com>
On Thu, 13 Apr 2006 09:00:51 -0700, "Jouni Malinen" <jkm@devicescape.com> wrote:
> That could be blocking an ioctl call for couple of seconds
> and would be quite horrible for single threaded programs.
I would say that waiting for couple of seconds in the kernel would
be quite wonderful for single threaded programs, when you consider
the alternative. I can guess now what your concern is, even though
you failed to articulate it: a single-threaded GUI application,
which cannot respond to events when blocked in getting scan results.
If that's the case, we should be looking at having both blocking
and non-blocking calls to fetch scan results.
> [...] but what if some other program were
> to request a new scan between the completion event and the attempt to
> read the previous scan results..
I do not see how this is relevant.
-- Pete
^ permalink raw reply
* Re: [patch 1/3] softmac: return -EAGAIN from getscan while scanning
From: Jouni Malinen @ 2006-04-13 22:45 UTC (permalink / raw)
To: Pete Zaitcev; +Cc: johannes, dcbw, netdev, linville, softmac-dev
In-Reply-To: <20060413152853.149186fb.zaitcev@redhat.com>
On Thu, Apr 13, 2006 at 03:28:53PM -0700, Pete Zaitcev wrote:
> On Thu, 13 Apr 2006 09:00:51 -0700, "Jouni Malinen" <jkm@devicescape.com> wrote:
>
> > That could be blocking an ioctl call for couple of seconds
> > and would be quite horrible for single threaded programs.
>
> I would say that waiting for couple of seconds in the kernel would
> be quite wonderful for single threaded programs, when you consider
> the alternative. I can guess now what your concern is, even though
> you failed to articulate it: a single-threaded GUI application,
> which cannot respond to events when blocked in getting scan results.
> If that's the case, we should be looking at having both blocking
> and non-blocking calls to fetch scan results.
No, my main concern was single-threaded design in wpa_suppliant.. If the
ioctl call is blocking, I would need to create a new (well, the first
additional) thread just for this use. Without that, the blocking call
would also block all control interface commands (interaction with
external programs) and controlling of other interfaces (if more than one
is used).
> > [...] but what if some other program were
> > to request a new scan between the completion event and the attempt to
> > read the previous scan results..
>
> I do not see how this is relevant.
That would make the application wait even if it properly waited for the
scan complete event before reading the scan result. If the get-results
call is blocking, the single-threaded application simply don't have any
easy way of getting the results while being able to do something else
while waiting for the scan to complete. Furthermore, blocking ioctl
handlers is not really something I would like to see in the kernel..
Aren't there some locks/semaphores/etc. kept for some cases?
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply
* Re: [stable] [PATCH 1/4] clip: run through Lindent
From: Greg KH @ 2006-04-13 22:45 UTC (permalink / raw)
To: Stephen Hemminger
Cc: David S. Miller, chas, netdev, linux-atm-general, stable
In-Reply-To: <20060413152224.2d46df99@localhost.localdomain>
On Thu, Apr 13, 2006 at 03:22:24PM -0700, Stephen Hemminger wrote:
> Run CLIP driver through Lindent script to fix formatting.
That's well and good, but really not a -stable thing. In fact, I don't
see any of these 4 patches being -stable material, do you?
thanks,
greg k-h
^ permalink raw reply
* Re: [patch 1/3] softmac: return -EAGAIN from getscan while scanning
From: Stephen Hemminger @ 2006-04-13 23:03 UTC (permalink / raw)
To: Jouni Malinen; +Cc: Pete Zaitcev, johannes, dcbw, netdev, linville, softmac-dev
In-Reply-To: <20060413224522.GK15499@instant802.com>
On Thu, 13 Apr 2006 15:45:22 -0700
"Jouni Malinen" <jkm@devicescape.com> wrote:
> On Thu, Apr 13, 2006 at 03:28:53PM -0700, Pete Zaitcev wrote:
> > On Thu, 13 Apr 2006 09:00:51 -0700, "Jouni Malinen" <jkm@devicescape.com> wrote:
> >
> > > That could be blocking an ioctl call for couple of seconds
> > > and would be quite horrible for single threaded programs.
> >
> > I would say that waiting for couple of seconds in the kernel would
> > be quite wonderful for single threaded programs, when you consider
> > the alternative. I can guess now what your concern is, even though
> > you failed to articulate it: a single-threaded GUI application,
> > which cannot respond to events when blocked in getting scan results.
> > If that's the case, we should be looking at having both blocking
> > and non-blocking calls to fetch scan results.
>
> No, my main concern was single-threaded design in wpa_suppliant.. If the
> ioctl call is blocking, I would need to create a new (well, the first
> additional) thread just for this use. Without that, the blocking call
> would also block all control interface commands (interaction with
> external programs) and controlling of other interfaces (if more than one
> is used).
>
> > > [...] but what if some other program were
> > > to request a new scan between the completion event and the attempt to
> > > read the previous scan results..
> >
> > I do not see how this is relevant.
>
> That would make the application wait even if it properly waited for the
> scan complete event before reading the scan result. If the get-results
> call is blocking, the single-threaded application simply don't have any
> easy way of getting the results while being able to do something else
> while waiting for the scan to complete. Furthermore, blocking ioctl
> handlers is not really something I would like to see in the kernel..
> Aren't there some locks/semaphores/etc. kept for some cases?
>
Sounds like you want a message interface like netlink, not ioctl's.
^ permalink raw reply
* [patch 05/22] sky2: bad memory reference on dual port cards
From: Greg KH @ 2006-04-13 23:07 UTC (permalink / raw)
To: linux-kernel, stable, Jeff Garzik
Cc: Justin Forbes, Zwane Mwaikambo, Theodore Ts'o, Randy Dunlap,
Dave Jones, Chuck Wolber, torvalds, akpm, alan, netdev,
Stephen Hemminger, Greg Kroah-Hartman
In-Reply-To: <20060413230637.GA5613@kroah.com>
[-- Attachment #1: sky2-bad-memory-reference-on-dual-port-cards.patch --]
[-- Type: text/plain, Size: 1317 bytes --]
-stable review patch. If anyone has any objections, please let us know.
------------------
Sky2 driver will oops referencing bad memory if used on
a dual port card. The problem is accessing past end of
MIB counter space.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/net/sky2.c | 4 ++--
drivers/net/sky2.h | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
--- linux-2.6.16.5.orig/drivers/net/sky2.c
+++ linux-2.6.16.5/drivers/net/sky2.c
@@ -579,8 +579,8 @@ static void sky2_mac_init(struct sky2_hw
reg = gma_read16(hw, port, GM_PHY_ADDR);
gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
- for (i = 0; i < GM_MIB_CNT_SIZE; i++)
- gma_read16(hw, port, GM_MIB_CNT_BASE + 8 * i);
+ for (i = GM_MIB_CNT_BASE; i <= GM_MIB_CNT_END; i += 4)
+ gma_read16(hw, port, i);
gma_write16(hw, port, GM_PHY_ADDR, reg);
/* transmit control */
--- linux-2.6.16.5.orig/drivers/net/sky2.h
+++ linux-2.6.16.5/drivers/net/sky2.h
@@ -1380,6 +1380,7 @@ enum {
/* MIB Counters */
#define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */
#define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */
+#define GM_MIB_CNT_END 0x025C /* Last MIB counter */
/*
* MIB Counters base address definitions (low word) -
--
^ permalink raw reply
* [patch 22/22] atm: clip causes unregister hang
From: Greg KH @ 2006-04-13 23:09 UTC (permalink / raw)
To: linux-kernel, stable, Herbert Xu, davem
Cc: Justin Forbes, Zwane Mwaikambo, Theodore Ts'o, Randy Dunlap,
Dave Jones, Chuck Wolber, torvalds, akpm, alan, chas, netdev,
Stephen Hemminger, Greg Kroah-Hartman
In-Reply-To: <20060413230637.GA5613@kroah.com>
[-- Attachment #1: atm-clip-causes-unregister-hang.patch --]
[-- Type: text/plain, Size: 3445 bytes --]
-stable review patch. If anyone has any objections, please let us know.
------------------
If Classical IP over ATM module is loaded, its neighbor table gets
populated when permanent neighbor entries are created; but these entries
are not flushed when the device is removed. Since the entry never gets
flushed the unregister of the network device never completes.
This version of the patch also adds locking around the reference to
the atm arp daemon to avoid races with events and daemon state changes.
(Note: barrier() was never really safe)
Bug-reference: http://bugzilla.kernel.org/show_bug.cgi?id=6295
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
net/atm/clip.c | 42 +++++++++++++++++++++++++++---------------
1 file changed, 27 insertions(+), 15 deletions(-)
--- linux-2.6.16.5.orig/net/atm/clip.c
+++ linux-2.6.16.5/net/atm/clip.c
@@ -613,12 +613,19 @@ static int clip_create(int number)
static int clip_device_event(struct notifier_block *this,unsigned long event,
- void *dev)
+ void *arg)
{
+ struct net_device *dev = arg;
+
+ if (event == NETDEV_UNREGISTER) {
+ neigh_ifdown(&clip_tbl, dev);
+ return NOTIFY_DONE;
+ }
+
/* ignore non-CLIP devices */
- if (((struct net_device *) dev)->type != ARPHRD_ATM ||
- ((struct net_device *) dev)->hard_start_xmit != clip_start_xmit)
+ if (dev->type != ARPHRD_ATM || dev->hard_start_xmit != clip_start_xmit)
return NOTIFY_DONE;
+
switch (event) {
case NETDEV_UP:
DPRINTK("clip_device_event NETDEV_UP\n");
@@ -686,14 +693,12 @@ static struct notifier_block clip_inet_n
static void atmarpd_close(struct atm_vcc *vcc)
{
DPRINTK("atmarpd_close\n");
- atmarpd = NULL; /* assumed to be atomic */
- barrier();
- unregister_inetaddr_notifier(&clip_inet_notifier);
- unregister_netdevice_notifier(&clip_dev_notifier);
- if (skb_peek(&sk_atm(vcc)->sk_receive_queue))
- printk(KERN_ERR "atmarpd_close: closing with requests "
- "pending\n");
+
+ rtnl_lock();
+ atmarpd = NULL;
skb_queue_purge(&sk_atm(vcc)->sk_receive_queue);
+ rtnl_unlock();
+
DPRINTK("(done)\n");
module_put(THIS_MODULE);
}
@@ -714,7 +719,12 @@ static struct atm_dev atmarpd_dev = {
static int atm_init_atmarp(struct atm_vcc *vcc)
{
- if (atmarpd) return -EADDRINUSE;
+ rtnl_lock();
+ if (atmarpd) {
+ rtnl_unlock();
+ return -EADDRINUSE;
+ }
+
if (start_timer) {
start_timer = 0;
init_timer(&idle_timer);
@@ -731,10 +741,7 @@ static int atm_init_atmarp(struct atm_vc
vcc->push = NULL;
vcc->pop = NULL; /* crash */
vcc->push_oam = NULL; /* crash */
- if (register_netdevice_notifier(&clip_dev_notifier))
- printk(KERN_ERR "register_netdevice_notifier failed\n");
- if (register_inetaddr_notifier(&clip_inet_notifier))
- printk(KERN_ERR "register_inetaddr_notifier failed\n");
+ rtnl_unlock();
return 0;
}
@@ -992,6 +999,8 @@ static int __init atm_clip_init(void)
clip_tbl_hook = &clip_tbl;
register_atm_ioctl(&clip_ioctl_ops);
+ register_netdevice_notifier(&clip_dev_notifier);
+ register_inetaddr_notifier(&clip_inet_notifier);
#ifdef CONFIG_PROC_FS
{
@@ -1012,6 +1021,9 @@ static void __exit atm_clip_exit(void)
remove_proc_entry("arp", atm_proc_root);
+ unregister_inetaddr_notifier(&clip_inet_notifier);
+ unregister_netdevice_notifier(&clip_dev_notifier);
+
deregister_atm_ioctl(&clip_ioctl_ops);
/* First, stop the idle timer, so it stops banging
--
^ permalink raw reply
* [PATCH 1/3] eth: use constant size address (revised)
From: Stephen Hemminger @ 2006-04-13 23:24 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20060411.172401.67034166.davem@davemloft.net>
Change the ethernet support routines to use constant address size.
This generates smaller faster code.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
--- sky2-2.6.17.orig/net/ethernet/eth.c 2006-03-07 13:28:54.000000000 -0800
+++ sky2-2.6.17/net/ethernet/eth.c 2006-04-12 13:10:56.000000000 -0700
@@ -77,6 +77,8 @@
{
struct ethhdr *eth = (struct ethhdr *)skb_push(skb,ETH_HLEN);
+ BUG_ON(dev->addr_len != ETH_ALEN);
+
/*
* Set the protocol type. For a packet of type ETH_P_802_3 we put the length
* in here instead. It is up to the 802.2 layer to carry protocol information.
@@ -93,11 +95,11 @@
if(!saddr)
saddr = dev->dev_addr;
- memcpy(eth->h_source,saddr,dev->addr_len);
+ memcpy(eth->h_source,saddr, ETH_ALEN);
if(daddr)
{
- memcpy(eth->h_dest,daddr,dev->addr_len);
+ memcpy(eth->h_dest,daddr, ETH_ALEN);
return ETH_HLEN;
}
@@ -107,7 +109,7 @@
if (dev->flags & (IFF_LOOPBACK|IFF_NOARP))
{
- memset(eth->h_dest, 0, dev->addr_len);
+ memset(eth->h_dest, 0, ETH_ALEN);
return ETH_HLEN;
}
@@ -140,7 +142,7 @@
"%s: unable to resolve type %X addresses.\n",
dev->name, (int)eth->h_proto);
- memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
+ memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
break;
}
@@ -223,8 +225,8 @@
return -1;
eth->h_proto = type;
- memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
- memcpy(eth->h_dest, neigh->ha, dev->addr_len);
+ memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
+ memcpy(eth->h_dest, neigh->ha, ETH_ALEN);
hh->hh_len = ETH_HLEN;
return 0;
}
@@ -236,7 +238,7 @@
void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
{
memcpy(((u8*)hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
- haddr, dev->addr_len);
+ haddr, ETH_ALEN);
}
EXPORT_SYMBOL(eth_type_trans);
@@ -246,7 +248,7 @@
struct sockaddr *addr=p;
if (netif_running(dev))
return -EBUSY;
- memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
return 0;
}
^ permalink raw reply
* Re: [patch 1/3] softmac: return -EAGAIN from getscan while scanning
From: Pete Zaitcev @ 2006-04-13 23:35 UTC (permalink / raw)
To: Jouni Malinen; +Cc: johannes, dcbw, netdev, linville, softmac-dev, zaitcev
In-Reply-To: <20060413224522.GK15499@instant802.com>
On Thu, 13 Apr 2006 15:45:22 -0700, "Jouni Malinen" <jkm@devicescape.com> wrote:
> > [...] I can guess now what your concern is, even though
> > you failed to articulate it: a single-threaded GUI application,
> > which cannot respond to events when blocked in getting scan results.
> > If that's the case, we should be looking at having both blocking
> > and non-blocking calls to fetch scan results.
>
> No, my main concern was single-threaded design in wpa_suppliant.. If the
> ioctl call is blocking, I would need to create a new (well, the first
> additional) thread just for this use. Without that, the blocking call
> would also block all control interface commands (interaction with
> external programs) and controlling of other interfaces (if more than one
> is used).
I see... Thanks for explainig it.
> [...] Furthermore, blocking ioctl
> handlers is not really something I would like to see in the kernel..
> Aren't there some locks/semaphores/etc. kept for some cases?
I think you are taking this concept too far. Consider things like
an ioctl to seek a magnetic tape N files forward, or an ioctl to
flush characters to a terminal. They seem to work fine in blocking
mode. And no, we do not have a generic API to expose semaphores
(I suppose you did not mean SYSV IPC above :-).
-- Pete
^ 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