git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git]
/
drivers
/
net
/
slip.c
diff --git
a/drivers/net/slip.c
b/drivers/net/slip.c
index
6209a35
..
a0806d2
100644
(file)
--- a/
drivers/net/slip.c
+++ b/
drivers/net/slip.c
@@
-55,12
+55,12
@@
*/
#define SL_CHECK_TRANSMIT
*/
#define SL_CHECK_TRANSMIT
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/uaccess.h>
-#include <
asm
/bitops.h>
+#include <
linux
/bitops.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
@@
-73,6
+73,7
@@
#include <linux/rtnetlink.h>
#include <linux/if_arp.h>
#include <linux/if_slip.h>
#include <linux/rtnetlink.h>
#include <linux/if_arp.h>
#include <linux/if_slip.h>
+#include <linux/delay.h>
#include <linux/init.h>
#include "slip.h"
#ifdef CONFIG_INET
#include <linux/init.h>
#include "slip.h"
#ifdef CONFIG_INET
@@
-85,8
+86,8
@@
static struct net_device **slip_devs;
static struct net_device **slip_devs;
-int slip_maxdev = SL_NRUNIT; /* Can be overridden with insmod! */
-
MODULE_PARM(slip_maxdev, "i"
);
+static int slip_maxdev = SL_NRUNIT;
+
module_param(slip_maxdev, int, 0
);
MODULE_PARM_DESC(slip_maxdev, "Maximum number of slip devices");
static int slip_esc(unsigned char *p, unsigned char *d, int len);
MODULE_PARM_DESC(slip_maxdev, "Maximum number of slip devices");
static int slip_esc(unsigned char *p, unsigned char *d, int len);
@@
-112,7
+113,7
@@
static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd);
* on actively running device.
*********************************/
* on actively running device.
*********************************/
-/*
+/*
Allocate channel buffers.
*/
Allocate channel buffers.
*/
@@
-184,15
+185,12
@@
sl_alloc_bufs(struct slip *sl, int mtu)
/* Cleanup */
err_exit:
#ifdef SL_INCLUDE_CSLIP
/* Cleanup */
err_exit:
#ifdef SL_INCLUDE_CSLIP
- if (cbuff)
- kfree(cbuff);
+ kfree(cbuff);
if (slcomp)
slhc_free(slcomp);
#endif
if (slcomp)
slhc_free(slcomp);
#endif
- if (xbuff)
- kfree(xbuff);
- if (rbuff)
- kfree(rbuff);
+ kfree(xbuff);
+ kfree(rbuff);
return err;
}
return err;
}
@@
-200,22
+198,16
@@
err_exit:
static void
sl_free_bufs(struct slip *sl)
{
static void
sl_free_bufs(struct slip *sl)
{
- void * tmp;
-
/* Free all SLIP frame buffers. */
/* Free all SLIP frame buffers. */
- if ((tmp = xchg(&sl->rbuff, NULL)) != NULL)
- kfree(tmp);
- if ((tmp = xchg(&sl->xbuff, NULL)) != NULL)
- kfree(tmp);
+ kfree(xchg(&sl->rbuff, NULL));
+ kfree(xchg(&sl->xbuff, NULL));
#ifdef SL_INCLUDE_CSLIP
#ifdef SL_INCLUDE_CSLIP
- if ((tmp = xchg(&sl->cbuff, NULL)) != NULL)
- kfree(tmp);
- if ((tmp = xchg(&sl->slcomp, NULL)) != NULL)
- slhc_free(tmp);
+ kfree(xchg(&sl->cbuff, NULL));
+ slhc_free(xchg(&sl->slcomp, NULL));
#endif
}
#endif
}
-/*
+/*
Reallocate slip channel buffers.
*/
Reallocate slip channel buffers.
*/
@@
-237,10
+229,10
@@
static int sl_realloc_bufs(struct slip *sl, int mtu)
if (len < 576 * 2)
len = 576 * 2;
if (len < 576 * 2)
len = 576 * 2;
- xbuff =
(unsigned char *) kmalloc
(len + 4, GFP_ATOMIC);
- rbuff =
(unsigned char *) kmalloc
(len + 4, GFP_ATOMIC);
+ xbuff =
kmalloc
(len + 4, GFP_ATOMIC);
+ rbuff =
kmalloc
(len + 4, GFP_ATOMIC);
#ifdef SL_INCLUDE_CSLIP
#ifdef SL_INCLUDE_CSLIP
- cbuff =
(unsigned char *) kmalloc
(len + 4, GFP_ATOMIC);
+ cbuff =
kmalloc
(len + 4, GFP_ATOMIC);
#endif
#endif
@@
-296,13
+288,10
@@
done_on_bh:
spin_unlock_bh(&sl->lock);
done:
spin_unlock_bh(&sl->lock);
done:
- if (xbuff)
- kfree(xbuff);
- if (rbuff)
- kfree(rbuff);
+ kfree(xbuff);
+ kfree(rbuff);
#ifdef SL_INCLUDE_CSLIP
#ifdef SL_INCLUDE_CSLIP
- if (cbuff)
- kfree(cbuff);
+ kfree(cbuff);
#endif
return err;
}
#endif
return err;
}
@@
-365,7
+354,7
@@
sl_bump(struct slip *sl)
#endif /* SL_INCLUDE_CSLIP */
sl->rx_bytes+=count;
#endif /* SL_INCLUDE_CSLIP */
sl->rx_bytes+=count;
-
+
skb = dev_alloc_skb(count);
if (skb == NULL) {
printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name);
skb = dev_alloc_skb(count);
if (skb == NULL) {
printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name);
@@
-417,7
+406,7
@@
sl_encaps(struct slip *sl, unsigned char *icp, int len)
* 14 Oct 1994 Dmitry Gorodchanin.
*/
sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
* 14 Oct 1994 Dmitry Gorodchanin.
*/
sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
- actual = sl->tty->driver->write(sl->tty,
0,
sl->xbuff, count);
+ actual = sl->tty->driver->write(sl->tty, sl->xbuff, count);
#ifdef SL_CHECK_TRANSMIT
sl->dev->trans_start = jiffies;
#endif
#ifdef SL_CHECK_TRANSMIT
sl->dev->trans_start = jiffies;
#endif
@@
-451,20
+440,18
@@
static void slip_write_wakeup(struct tty_struct *tty)
return;
}
return;
}
- actual = tty->driver->write(tty,
0,
sl->xhead, sl->xleft);
+ actual = tty->driver->write(tty, sl->xhead, sl->xleft);
sl->xleft -= actual;
sl->xhead += actual;
}
static void sl_tx_timeout(struct net_device *dev)
{
sl->xleft -= actual;
sl->xhead += actual;
}
static void sl_tx_timeout(struct net_device *dev)
{
- struct slip *sl =
(struct slip*)(dev->pri
v);
+ struct slip *sl =
netdev_priv(de
v);
spin_lock(&sl->lock);
if (netif_queue_stopped(dev)) {
spin_lock(&sl->lock);
if (netif_queue_stopped(dev)) {
- struct slip *sl = (struct slip*)(dev->priv);
-
if (!netif_running(dev))
goto out;
if (!netif_running(dev))
goto out;
@@
-494,7
+481,7
@@
out:
static int
sl_xmit(struct sk_buff *skb, struct net_device *dev)
{
static int
sl_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct slip *sl =
(struct slip*)(dev->pri
v);
+ struct slip *sl =
netdev_priv(de
v);
spin_lock(&sl->lock);
if (!netif_running(dev)) {
spin_lock(&sl->lock);
if (!netif_running(dev)) {
@@
-528,7
+515,7
@@
sl_xmit(struct sk_buff *skb, struct net_device *dev)
static int
sl_close(struct net_device *dev)
{
static int
sl_close(struct net_device *dev)
{
- struct slip *sl =
(struct slip*)(dev->pri
v);
+ struct slip *sl =
netdev_priv(de
v);
spin_lock_bh(&sl->lock);
if (sl->tty) {
spin_lock_bh(&sl->lock);
if (sl->tty) {
@@
-547,7
+534,7
@@
sl_close(struct net_device *dev)
static int sl_open(struct net_device *dev)
{
static int sl_open(struct net_device *dev)
{
- struct slip *sl =
(struct slip*)(dev->pri
v);
+ struct slip *sl =
netdev_priv(de
v);
if (sl->tty==NULL)
return -ENODEV;
if (sl->tty==NULL)
return -ENODEV;
@@
-561,7
+548,7
@@
static int sl_open(struct net_device *dev)
static int sl_change_mtu(struct net_device *dev, int new_mtu)
{
static int sl_change_mtu(struct net_device *dev, int new_mtu)
{
- struct slip *sl =
(struct slip*)(dev->pri
v);
+ struct slip *sl =
netdev_priv(de
v);
if (new_mtu < 68 || new_mtu > 65534)
return -EINVAL;
if (new_mtu < 68 || new_mtu > 65534)
return -EINVAL;
@@
-577,7
+564,7
@@
static struct net_device_stats *
sl_get_stats(struct net_device *dev)
{
static struct net_device_stats stats;
sl_get_stats(struct net_device *dev)
{
static struct net_device_stats stats;
- struct slip *sl =
(struct slip*)(dev->pri
v);
+ struct slip *sl =
netdev_priv(de
v);
#ifdef SL_INCLUDE_CSLIP
struct slcompress *comp;
#endif
#ifdef SL_INCLUDE_CSLIP
struct slcompress *comp;
#endif
@@
-612,10
+599,10
@@
sl_get_stats(struct net_device *dev)
static int sl_init(struct net_device *dev)
{
static int sl_init(struct net_device *dev)
{
- struct slip *sl =
(struct slip*)(dev->pri
v);
+ struct slip *sl =
netdev_priv(de
v);
/*
/*
- * Finish setting up the DEVICE info.
+ * Finish setting up the DEVICE info.
*/
dev->mtu = sl->mtu;
*/
dev->mtu = sl->mtu;
@@
-630,7
+617,7
@@
static int sl_init(struct net_device *dev)
static void sl_uninit(struct net_device *dev)
{
static void sl_uninit(struct net_device *dev)
{
- struct slip *sl =
(struct slip*)(dev->pri
v);
+ struct slip *sl =
netdev_priv(de
v);
sl_free_bufs(sl);
}
sl_free_bufs(sl);
}
@@
-663,18
+650,15
@@
static void sl_setup(struct net_device *dev)
******************************************/
******************************************/
-static int slip_receive_room(struct tty_struct *tty)
-{
- return 65536; /* We can handle an infinite amount of data. :-) */
-}
-
/*
* Handle the 'receiver data ready' interrupt.
* This function is called by the 'tty_io' module in the kernel when
* a block of SLIP data has been received, which can now be decapsulated
/*
* Handle the 'receiver data ready' interrupt.
* This function is called by the 'tty_io' module in the kernel when
* a block of SLIP data has been received, which can now be decapsulated
- * and sent on to some IP layer for further processing.
+ * and sent on to some IP layer for further processing. This will not
+ * be re-entered while running but other ldisc functions may be called
+ * in parallel
*/
*/
-
+
static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
{
struct slip *sl = (struct slip *) tty->disc_data;
static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
{
struct slip *sl = (struct slip *) tty->disc_data;
@@
-717,7
+701,7
@@
static void sl_sync(void)
if ((dev = slip_devs[i]) == NULL)
break;
if ((dev = slip_devs[i]) == NULL)
break;
- sl =
dev->priv
;
+ sl =
netdev_priv(dev)
;
if (sl->tty || sl->leased)
continue;
if (dev->flags&IFF_UP)
if (sl->tty || sl->leased)
continue;
if (dev->flags&IFF_UP)
@@
-736,7
+720,7
@@
sl_alloc(dev_t line)
struct net_device *dev = NULL;
struct slip *sl;
struct net_device *dev = NULL;
struct slip *sl;
- if (slip_devs == NULL)
+ if (slip_devs == NULL)
return NULL; /* Master array missing ! */
for (i = 0; i < slip_maxdev; i++) {
return NULL; /* Master array missing ! */
for (i = 0; i < slip_maxdev; i++) {
@@
-744,7
+728,7
@@
sl_alloc(dev_t line)
if (dev == NULL)
break;
if (dev == NULL)
break;
- sl =
dev->priv
;
+ sl =
netdev_priv(dev)
;
if (sl->leased) {
if (sl->line != line)
continue;
if (sl->leased) {
if (sl->line != line)
continue;
@@
-786,7
+770,7
@@
sl_alloc(dev_t line)
i = sel;
dev = slip_devs[i];
if (score > 1) {
i = sel;
dev = slip_devs[i];
if (score > 1) {
- sl =
dev->priv
;
+ sl =
netdev_priv(dev)
;
sl->flags &= (1 << SLF_INUSE);
return sl;
}
sl->flags &= (1 << SLF_INUSE);
return sl;
}
@@
-797,14
+781,14
@@
sl_alloc(dev_t line)
return NULL;
if (dev) {
return NULL;
if (dev) {
- sl =
dev->priv
;
+ sl =
netdev_priv(dev)
;
if (test_bit(SLF_INUSE, &sl->flags)) {
unregister_netdevice(dev);
dev = NULL;
slip_devs[i] = NULL;
}
}
if (test_bit(SLF_INUSE, &sl->flags)) {
unregister_netdevice(dev);
dev = NULL;
slip_devs[i] = NULL;
}
}
-
+
if (!dev) {
char name[IFNAMSIZ];
sprintf(name, "sl%d", i);
if (!dev) {
char name[IFNAMSIZ];
sprintf(name, "sl%d", i);
@@
-815,7
+799,7
@@
sl_alloc(dev_t line)
dev->base_addr = i;
}
dev->base_addr = i;
}
- sl =
dev->priv
;
+ sl =
netdev_priv(dev)
;
/* Initialize channel control data */
sl->magic = SLIP_MAGIC;
/* Initialize channel control data */
sl->magic = SLIP_MAGIC;
@@
-831,7
+815,7
@@
sl_alloc(dev_t line)
sl->outfill_timer.function=sl_outfill;
#endif
slip_devs[i] = dev;
sl->outfill_timer.function=sl_outfill;
#endif
slip_devs[i] = dev;
-
+
return sl;
}
return sl;
}
@@
-841,16
+825,18
@@
sl_alloc(dev_t line)
* SLIP line discipline is called for. Because we are
* sure the tty line exists, we only have to link it to
* a free SLIP channel...
* SLIP line discipline is called for. Because we are
* sure the tty line exists, we only have to link it to
* a free SLIP channel...
+ *
+ * Called in process context serialized from other ldisc calls.
*/
*/
-static int
-slip_open(struct tty_struct *tty)
+
+s
tatic int s
lip_open(struct tty_struct *tty)
{
struct slip *sl;
int err;
if(!capable(CAP_NET_ADMIN))
return -EPERM;
{
struct slip *sl;
int err;
if(!capable(CAP_NET_ADMIN))
return -EPERM;
-
+
/* RTnetlink lock is misused here to serialize concurrent
opens of slip channels. There are better ways, but it is
the simplest one.
/* RTnetlink lock is misused here to serialize concurrent
opens of slip channels. There are better ways, but it is
the simplest one.
@@
-876,10
+862,6
@@
slip_open(struct tty_struct *tty)
tty->disc_data = sl;
sl->line = tty_devnum(tty);
sl->pid = current->pid;
tty->disc_data = sl;
sl->line = tty_devnum(tty);
sl->pid = current->pid;
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
- if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer(tty);
if (!test_bit(SLF_INUSE, &sl->flags)) {
/* Perform the low-level SLIP initialization. */
if (!test_bit(SLF_INUSE, &sl->flags)) {
/* Perform the low-level SLIP initialization. */
@@
-905,6
+887,7
@@
slip_open(struct tty_struct *tty)
/* Done. We have linked the TTY line to a channel. */
rtnl_unlock();
/* Done. We have linked the TTY line to a channel. */
rtnl_unlock();
+ tty->receive_room = 65536; /* We don't flow control */
return sl->dev->base_addr;
err_free_bufs:
return sl->dev->base_addr;
err_free_bufs:
@@
-923,6
+906,9
@@
err_exit:
}
/*
}
/*
+
+ FIXME: 1,2 are fixed 3 was never true anyway.
+
Let me to blame a bit.
1. TTY module calls this funstion on soft interrupt.
2. TTY module calls this function WITH MASKED INTERRUPTS!
Let me to blame a bit.
1. TTY module calls this funstion on soft interrupt.
2. TTY module calls this function WITH MASKED INTERRUPTS!
@@
-934,16
+920,15
@@
err_exit:
By-product (not desired): sl? does not feel hangups and remains open.
It is supposed, that user level program (dip, diald, slattach...)
By-product (not desired): sl? does not feel hangups and remains open.
It is supposed, that user level program (dip, diald, slattach...)
- will catch SIGHUP and make the rest of work.
+ will catch SIGHUP and make the rest of work.
I see no way to make more with current tty code. --ANK
*/
/*
* Close down a SLIP channel.
I see no way to make more with current tty code. --ANK
*/
/*
* Close down a SLIP channel.
- * This means flushing out any pending queues, and then restoring the
- * TTY line discipline to what it was before it got hooked to SLIP
- * (which usually is TTY again).
+ * This means flushing out any pending queues, and then returning. This
+ * call is serialized against other ldisc functions.
*/
static void
slip_close(struct tty_struct *tty)
*/
static void
slip_close(struct tty_struct *tty)
@@
-1254,7
+1239,7
@@
static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
{
static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
{
- struct slip *sl =
(struct slip*)(dev->pri
v);
+ struct slip *sl =
netdev_priv(de
v);
unsigned long *p = (unsigned long *)&rq->ifr_ifru;
if (sl == NULL) /* Allocation failed ?? */
unsigned long *p = (unsigned long *)&rq->ifr_ifru;
if (sl == NULL) /* Allocation failed ?? */
@@
-1306,7
+1291,7
@@
static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
break;
case SIOCSLEASE:
break;
case SIOCSLEASE:
- /* Resolve race condition, when ioctl'ing hanged up
+ /* Resolve race condition, when ioctl'ing hanged up
and opened by another process device.
*/
if (sl->tty != current->signal->tty && sl->pid != current->pid) {
and opened by another process device.
*/
if (sl->tty != current->signal->tty && sl->pid != current->pid) {
@@
-1335,7
+1320,6
@@
static struct tty_ldisc sl_ldisc = {
.close = slip_close,
.ioctl = slip_ioctl,
.receive_buf = slip_receive_buf,
.close = slip_close,
.ioctl = slip_ioctl,
.receive_buf = slip_receive_buf,
- .receive_room = slip_receive_room,
.write_wakeup = slip_write_wakeup,
};
.write_wakeup = slip_write_wakeup,
};
@@
-1366,7
+1350,7
@@
static int __init slip_init(void)
}
/* Clear the pointer array, we allocate devices when we need them */
}
/* Clear the pointer array, we allocate devices when we need them */
- memset(slip_devs, 0, sizeof(struct net_device *)*slip_maxdev);
+ memset(slip_devs, 0, sizeof(struct net_device *)*slip_maxdev);
/* Fill in our line protocol discipline, and register it */
if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0) {
/* Fill in our line protocol discipline, and register it */
if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0) {
@@
-1384,23
+1368,21
@@
static void __exit slip_exit(void)
unsigned long timeout = jiffies + HZ;
int busy = 0;
unsigned long timeout = jiffies + HZ;
int busy = 0;
- if (slip_devs == NULL)
+ if (slip_devs == NULL)
return;
/* First of all: check for active disciplines and hangup them.
*/
do {
return;
/* First of all: check for active disciplines and hangup them.
*/
do {
- if (busy) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ / 10);
- }
+ if (busy)
+ msleep_interruptible(100);
busy = 0;
for (i = 0; i < slip_maxdev; i++) {
dev = slip_devs[i];
if (!dev)
continue;
busy = 0;
for (i = 0; i < slip_maxdev; i++) {
dev = slip_devs[i];
if (!dev)
continue;
- sl =
dev->priv
;
+ sl =
netdev_priv(dev)
;
spin_lock_bh(&sl->lock);
if (sl->tty) {
busy++;
spin_lock_bh(&sl->lock);
if (sl->tty) {
busy++;
@@
-1417,13
+1399,13
@@
static void __exit slip_exit(void)
continue;
slip_devs[i] = NULL;
continue;
slip_devs[i] = NULL;
- sl =
dev->priv
;
+ sl =
netdev_priv(dev)
;
if (sl->tty) {
printk(KERN_ERR "%s: tty discipline still running\n",
dev->name);
/* Intentionally leak the control block. */
dev->destructor = NULL;
if (sl->tty) {
printk(KERN_ERR "%s: tty discipline still running\n",
dev->name);
/* Intentionally leak the control block. */
dev->destructor = NULL;
- }
+ }
unregister_netdev(dev);
}
unregister_netdev(dev);
}
@@
-1431,7
+1413,7
@@
static void __exit slip_exit(void)
kfree(slip_devs);
slip_devs = NULL;
kfree(slip_devs);
slip_devs = NULL;
- if ((i = tty_
register_ldisc(N_SLIP, NULL
)))
+ if ((i = tty_
unregister_ldisc(N_SLIP
)))
{
printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i);
}
{
printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i);
}
@@
-1469,7
+1451,7
@@
static void sl_outfill(unsigned long sls)
if (!netif_queue_stopped(sl->dev))
{
/* if device busy no outfill */
if (!netif_queue_stopped(sl->dev))
{
/* if device busy no outfill */
- sl->tty->driver->write(sl->tty,
0,
&s, 1);
+ sl->tty->driver->write(sl->tty, &s, 1);
}
}
else
}
}
else