#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/bitops.h>
#include <asm/system.h>
#include <asm/uaccess.h>
-#include <asm/bitops.h>
# include <linux/ctype.h>
#include <linux/string.h>
#include <linux/seq_file.h>
#include <linux/serial.h>
#include <linux/serialP.h>
+#include <linux/rcupdate.h>
#include <net/arp.h>
#include <linux/ip.h>
NoStructure = 0, /* Really old firmware */
StructuredMessages = 1, /* Parsable AT response msgs */
ChecksummedMessages = 2 /* Parsable AT response msgs with checksums */
-} FirmwareLevel;
+};
struct strip {
int magic;
/* Global variables */
static LIST_HEAD(strip_list);
-static spinlock_t strip_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(strip_lock);
/************************************************************************/
/* Macros */
strip_info->mtu = dev->mtu = mtu;
return (1);
}
- if (r)
- kfree(r);
- if (s)
- kfree(s);
- if (t)
- kfree(t);
+ kfree(r);
+ kfree(s);
+ kfree(t);
return (0);
}
*/
static int strip_change_mtu(struct net_device *dev, int new_mtu)
{
- struct strip *strip_info = dev->priv;
+ struct strip *strip_info = netdev_priv(dev);
int old_mtu = strip_info->mtu;
unsigned char *orbuff = strip_info->rx_buff;
unsigned char *osbuff = strip_info->sx_buff;
printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n",
strip_info->dev->name, old_mtu, strip_info->mtu);
- if (orbuff)
- kfree(orbuff);
- if (osbuff)
- kfree(osbuff);
- if (otbuff)
- kfree(otbuff);
-
+ kfree(orbuff);
+ kfree(osbuff);
+ kfree(otbuff);
return 0;
}
set_baud(tty, strip_info->user_baud);
}
- tty->driver->write(tty, 0, s.string, s.length);
+ tty->driver->write(tty, s.string, s.length);
#ifdef EXT_COUNTERS
strip_info->tx_ebytes += s.length;
#endif
if (strip_info->tx_left > 0) {
int num_written =
- tty->driver->write(tty, 0, strip_info->tx_head,
+ tty->driver->write(tty, strip_info->tx_head,
strip_info->tx_left);
strip_info->tx_left -= num_written;
strip_info->tx_head += num_written;
*/
if (haddr.c[0] == 0xFF) {
u32 brd = 0;
- struct in_device *in_dev = in_dev_get(strip_info->dev);
- if (in_dev == NULL)
+ struct in_device *in_dev;
+
+ rcu_read_lock();
+ in_dev = __in_dev_get_rcu(strip_info->dev);
+ if (in_dev == NULL) {
+ rcu_read_unlock();
return NULL;
- read_lock(&in_dev->lock);
+ }
if (in_dev->ifa_list)
brd = in_dev->ifa_list->ifa_broadcast;
- read_unlock(&in_dev->lock);
- in_dev_put(in_dev);
+ rcu_read_unlock();
/* arp_query returns 1 if it succeeds in looking up the address, 0 if it fails */
if (!arp_query(haddr.c, brd, strip_info->dev)) {
}
if (1) {
- struct in_device *in_dev = in_dev_get(strip_info->dev);
+ struct in_device *in_dev;
+
brd = addr = 0;
+ rcu_read_lock();
+ in_dev = __in_dev_get_rcu(strip_info->dev);
if (in_dev) {
- read_lock(&in_dev->lock);
if (in_dev->ifa_list) {
brd = in_dev->ifa_list->ifa_broadcast;
addr = in_dev->ifa_list->ifa_local;
}
- read_unlock(&in_dev->lock);
- in_dev_put(in_dev);
}
+ rcu_read_unlock();
}
/* Encapsulate a datagram and kick it into a TTY queue. */
static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct strip *strip_info = (struct strip *) (dev->priv);
+ struct strip *strip_info = netdev_priv(dev);
if (!netif_running(dev)) {
printk(KERN_ERR "%s: xmit call when iface is down\n",
unsigned short type, void *daddr, void *saddr,
unsigned len)
{
- struct strip *strip_info = (struct strip *) (dev->priv);
+ struct strip *strip_info = netdev_priv(dev);
STRIP_Header *header = (STRIP_Header *) skb_push(skb, sizeof(STRIP_Header));
/*printk(KERN_INFO "%s: strip_header 0x%04X %s\n", dev->name, type,
header->src_addr = strip_info->true_dev_addr;
header->protocol = htons(type);
- /*HexDump("strip_header", (struct strip *)(dev->priv), skb->data, skb->data + skb->len); */
+ /*HexDump("strip_header", netdev_priv(dev), skb->data, skb->data + skb->len); */
if (!daddr)
return (-dev->hard_header_len);
/************************************************************************/
/* Receiving routines */
-static int strip_receive_room(struct tty_struct *tty)
-{
- return 0x10000; /* We can handle an infinite amount of data. :-) */
-}
-
/*
* This function parses the response to the ATS300? command,
* extracting the radio version and serial number.
return 0;
}
-static int dev_set_mac_address(struct net_device *dev, void *addr)
+static int strip_set_mac_address(struct net_device *dev, void *addr)
{
- struct strip *strip_info = (struct strip *) (dev->priv);
+ struct strip *strip_info = netdev_priv(dev);
struct sockaddr *sa = addr;
printk(KERN_INFO "%s: strip_set_dev_mac_address called\n", dev->name);
set_mac_address(strip_info, (MetricomAddress *) sa->sa_data);
static struct net_device_stats *strip_get_stats(struct net_device *dev)
{
+ struct strip *strip_info = netdev_priv(dev);
static struct net_device_stats stats;
- struct strip *strip_info = (struct strip *) (dev->priv);
memset(&stats, 0, sizeof(struct net_device_stats));
/*
* Here's the order things happen:
* When the user runs "slattach -p strip ..."
- * 1. The TTY module calls strip_open
+ * 1. The TTY module calls strip_open;;
* 2. strip_open calls strip_alloc
* 3. strip_alloc calls register_netdev
* 4. register_netdev calls strip_dev_init
static int strip_open_low(struct net_device *dev)
{
- struct strip *strip_info = (struct strip *) (dev->priv);
+ struct strip *strip_info = netdev_priv(dev);
if (strip_info->tty == NULL)
return (-ENODEV);
static int strip_close_low(struct net_device *dev)
{
- struct strip *strip_info = (struct strip *) (dev->priv);
+ struct strip *strip_info = netdev_priv(dev);
if (strip_info->tty == NULL)
return -EBUSY;
/*
* Free all STRIP frame buffers.
*/
- if (strip_info->rx_buff) {
- kfree(strip_info->rx_buff);
- strip_info->rx_buff = NULL;
- }
- if (strip_info->sx_buff) {
- kfree(strip_info->sx_buff);
- strip_info->sx_buff = NULL;
- }
- if (strip_info->tx_buff) {
- kfree(strip_info->tx_buff);
- strip_info->tx_buff = NULL;
- }
+ kfree(strip_info->rx_buff);
+ strip_info->rx_buff = NULL;
+ kfree(strip_info->sx_buff);
+ strip_info->sx_buff = NULL;
+ kfree(strip_info->tx_buff);
+ strip_info->tx_buff = NULL;
+
del_timer(&strip_info->idle_timer);
return 0;
}
dev->hard_start_xmit = strip_xmit;
dev->hard_header = strip_header;
dev->rebuild_header = strip_rebuild_header;
- dev->set_mac_address = dev_set_mac_address;
+ dev->set_mac_address = strip_set_mac_address;
dev->get_stats = strip_get_stats;
dev->change_mtu = strip_change_mtu;
}
strip_info->tty = tty;
tty->disc_data = strip_info;
+ tty->receive_room = 65536;
+
if (tty->driver->flush_buffer)
tty->driver->flush_buffer(tty);
- if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer(tty);
/*
* Restore default settings
.close = strip_close,
.ioctl = strip_ioctl,
.receive_buf = strip_receive_buf,
- .receive_room = strip_receive_room,
.write_wakeup = strip_write_some_more,
};
/* Unregister with the /proc/net file here. */
proc_net_remove("strip");
- if ((i = tty_register_ldisc(N_STRIP, NULL)))
+ if ((i = tty_unregister_ldisc(N_STRIP)))
printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
printk(signoff);