More clean ups and a few more syscalls that don't need locking

Alan Cox (alan@lxorguk.ukuu.org.uk)
Mon, 3 Feb 97 23:30 GMT


Nothing stunning

o NFSroot fix
o LAPB improvements
o Textual clean ups
o Removed a nasty AP1000 hack from arp.c
o More syscalls dont lock the kernel
o IPX 802.2 over FDDI should now work. If/when this is OK I'd add
Appletalk too.

There are definitely still bugs in 2.1.25 - people getting error 514 back
to user space (a 'cannot happen'), a bug in the new select emulation causing
joe to exit very occasionally thinking it got its stdin closed and some
modules funnies still.

Alan

diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/Documentation/Configure.help linux/Documentation/Configure.help
--- linux.vanilla/Documentation/Configure.help Sun Feb 2 17:45:00 1997
+++ linux/Documentation/Configure.help Mon Feb 3 23:14:15 1997
@@ -2359,22 +2359,23 @@

WAN Router
CONFIG_WAN_ROUTER
+
Wide Area Networks (WANs), such as X.25, frame relay and leased
lines, are used to interconnect Local Area Networks (LANs) over vast
distances with data transfer rates significantly higher than those
achievable with commonly used asynchronous modem connections.
Usually, a quite expensive external device called `WAN router' is
- needed to connect to WAN.
- As an alternative, WAN router can be build into Linux kernel.
+ needed to connect to a WAN.
+ As an alternative, WAN routing can be built into the Linux kernel.
With relatively inexpensive WAN interface cards available on the
- market, a perfectly usable router can be built for less than half a
+ market, a perfectly usable router can be built for less than half the
price of an external router. If you have one of those cards (with
appropriate WAN Link Driver) and wish to use your Linux box as a WAN
router, you may say 'Y' to this option. You will also need a
wan-tools package available via FTP (user: anonymous) from
ftp.sangoma.com. Read Documentation/networking/wan-router.txt for
more information.
- WAN router is always built as a module ( = code which can be
+ WAN routing is always built as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
For general information about modules read Documentation/modules.txt.

@@ -2390,7 +2391,7 @@
Sangoma WANPIPE(tm) multiprotocol cards
CONFIG_VENDOR_SANGOMA
WANPIPE from Sangoma Technologies Inc. (http://www.sangoma.com)
- is a family of intelligent multiprotocol WAN adapter with data
+ is a family of intelligent multiprotocol WAN adapters with data
transfer rates up to T1 (1.544 Mbps). They are also known as
Synchronous Data Link Adapters (SDLA) and designated S502E(A), S503
or S508. If you have one of these cards, say 'Y' to this option.
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/arch/i386/kernel/ioport.c linux/arch/i386/kernel/ioport.c
--- linux.vanilla/arch/i386/kernel/ioport.c Tue Jan 28 21:33:13 1997
+++ linux/arch/i386/kernel/ioport.c Sun Feb 2 18:25:32 1997
@@ -53,19 +53,13 @@
*/
asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
{
- int ret = -EINVAL;
-
- lock_kernel();
if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
- goto out;
- ret = -EPERM;
+ return -EINVAL;
if (!suser())
- goto out;
+ return -EPERM;
+
set_bitmap((unsigned long *)current->tss.io_bitmap, from, num, !turn_on);
- ret = 0;
-out:
- unlock_kernel();
- return ret;
+ return 0;
}

unsigned int *stack;
@@ -80,23 +74,18 @@
* on system-call entry - see also fork() and the signal handling
* code.
*/
+
asmlinkage int sys_iopl(long ebx,long ecx,long edx,
long esi, long edi, long ebp, long eax, long ds,
long es, long orig_eax, long eip, long cs,
long eflags, long esp, long ss)
{
unsigned int level = ebx;
- int ret = -EINVAL;

- lock_kernel();
if (level > 3)
- goto out;
- ret = -EPERM;
+ return -EINVAL;
if (!suser())
- goto out;
+ return -EPERM;
*(&eflags) = (eflags & 0xffffcfff) | (level << 12);
- ret = 0;
-out:
- unlock_kernel();
- return ret;
+ return 0;
}
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/arch/i386/kernel/sys_i386.c linux/arch/i386/kernel/sys_i386.c
--- linux.vanilla/arch/i386/kernel/sys_i386.c Tue Jan 28 21:33:14 1997
+++ linux/arch/i386/kernel/sys_i386.c Sun Feb 2 18:27:29 1997
@@ -32,11 +32,11 @@

lock_kernel();
error = do_pipe(fd);
+ unlock_kernel();
if (!error) {
if (copy_to_user(fildes, fd, 2*sizeof(int)))
error = -EFAULT;
}
- unlock_kernel();
return error;
}

@@ -87,13 +87,12 @@
asmlinkage int old_select(struct sel_arg_struct *arg)
{
struct sel_arg_struct a;
- int ret = -EFAULT;
+ int ret;

- lock_kernel();
if (copy_from_user(&a, arg, sizeof(a)))
- goto out;
+ return -EFAULT;
+ lock_kernel();
ret = sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
-out:
unlock_kernel();
return ret;
}
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/fs/nfs/nfsroot.c linux/fs/nfs/nfsroot.c
--- linux.vanilla/fs/nfs/nfsroot.c Tue Jan 28 21:33:38 1997
+++ linux/fs/nfs/nfsroot.c Mon Feb 3 22:57:46 1997
@@ -598,6 +598,7 @@
iov.iov_base = buf;
iov.iov_len = size;
msg.msg_name = NULL;
+ msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/include/linux/modversions.h linux/include/linux/modversions.h
--- linux.vanilla/include/linux/modversions.h Thu Jan 1 01:00:00 1970
+++ linux/include/linux/modversions.h Sun Feb 2 18:34:26 1997
@@ -0,0 +1 @@
+#include <linux/modsetver.h>
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/include/net/lapb.h linux/include/net/lapb.h
--- linux.vanilla/include/net/lapb.h Thu Jan 23 23:27:27 1997
+++ linux/include/net/lapb.h Mon Feb 3 22:59:38 1997
@@ -44,11 +44,11 @@
#define LAPB_ADDR_D 0x07

/* Define Link State constants. */
-#define LAPB_STATE_0 0
-#define LAPB_STATE_1 1
-#define LAPB_STATE_2 2
-#define LAPB_STATE_3 3
-#define LAPB_STATE_4 4
+#define LAPB_STATE_0 0 /* Disconnected State */
+#define LAPB_STATE_1 1 /* Awaiting Connection State */
+#define LAPB_STATE_2 2 /* Awaiting Disconnection State */
+#define LAPB_STATE_3 3 /* Data Transfer State */
+#define LAPB_STATE_4 4 /* Frame Reject State */

#define LAPB_DEFAULT_MODE (LAPB_STANDARD | LAPB_SLP | LAPB_DTE)
#define LAPB_DEFAULT_WINDOW 7 /* Window=7 */
@@ -69,6 +69,7 @@
unsigned short n2, n2count;
unsigned short t1, t2;
unsigned short t1timer, t2timer;
+ struct sk_buff_head input_queue;
struct sk_buff_head write_queue;
struct sk_buff_head ack_queue;
unsigned char window;
@@ -77,7 +78,6 @@
} lapb_cb;

/* lapb_iface.c */
-extern lapb_cb *lapb_tokentostruct(void *);
extern void lapb_connect_confirmation(lapb_cb *, int);
extern void lapb_connect_indication(lapb_cb *, int);
extern void lapb_disconnect_confirmation(lapb_cb *, int);
@@ -86,13 +86,12 @@
extern int lapb_data_transmit(lapb_cb *, struct sk_buff *);

/* lapb_in.c */
+extern void lapb_data_input(lapb_cb *, struct sk_buff *);

/* lapb_out.c */
extern void lapb_kick(lapb_cb *);
extern void lapb_transmit_buffer(lapb_cb *, struct sk_buff *, int);
-extern void lapb_nr_error_recovery(lapb_cb *);
extern void lapb_establish_data_link(lapb_cb *);
-extern void lapb_transmit_enquiry(lapb_cb *);
extern void lapb_enquiry_response(lapb_cb *);
extern void lapb_timeout_response(lapb_cb *);
extern void lapb_check_iframes_acked(lapb_cb *, unsigned short);
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/kernel/sched.c linux/kernel/sched.c
--- linux.vanilla/kernel/sched.c Sun Feb 2 17:45:18 1997
+++ linux/kernel/sched.c Sun Feb 2 18:43:11 1997
@@ -1349,21 +1349,21 @@
{
unsigned long newprio;
int increase = 0;
- int ret = -EPERM;

/*
- * We need a lock. sys_setpriority can affect other tasks.
+ * Setpriority might change our priority at the same moment.
+ * We don't have to worry. Conceptually one call occurs first
+ * and we have a single winner.
*/

- lock_kernel();
newprio = increment;
if (increment < 0) {
if (!suser())
- goto out;
+ return -EPERM;
newprio = -increment;
increase = 1;
}
- ret = 0;
+
if (newprio > 40)
newprio = 40;
/*
@@ -1377,15 +1377,21 @@
increment = newprio;
if (increase)
increment = -increment;
+ /*
+ * Current->priority can change between this point
+ * and the assignment. We are assigning not doing add/subs
+ * so thats ok. Conceptually a process might just instantaneously
+ * read the value we stomp over. I don't think that is an issue
+ * unless posix makes it one. If so we can loop on changes
+ * to current->priority.
+ */
newprio = current->priority - increment;
if ((signed) newprio < 1)
newprio = 1;
if (newprio > DEF_PRIORITY*2)
newprio = DEF_PRIORITY*2;
current->priority = newprio;
-out:
- unlock_kernel();
- return ret;
+ return 0;
}

#endif
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/kernel/signal.c linux/kernel/signal.c
--- linux.vanilla/kernel/signal.c Tue Jan 28 21:33:49 1997
+++ linux/kernel/signal.c Sun Feb 2 18:03:17 1997
@@ -72,9 +72,8 @@
{
int ret;

- lock_kernel();
+ /* SMP safe */
ret = current->blocked;
- unlock_kernel();
return ret;
}

diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/kernel/sys.c linux/kernel/sys.c
--- linux.vanilla/kernel/sys.c Sun Feb 2 17:45:18 1997
+++ linux/kernel/sys.c Sun Feb 2 18:44:04 1997
@@ -205,18 +205,17 @@
*/
asmlinkage int sys_reboot(int magic, int magic_too, int flag)
{
- int error = -EPERM;
-
- lock_kernel();
if (!suser())
- goto out;
- error = -EINVAL;
+ return -EPERM;
if (magic != 0xfee1dead ||
(magic_too != 672274793 && magic_too != 85072278))
- goto out;
- error = 0;
+ return -EINVAL;
+
+
if (flag == 0x01234567)
{
+ /* SMP: We need to lock during the shutdown still */
+ lock_kernel();
notifier_call_chain(&boot_notifier_list, SYS_DOWN, NULL);
hard_reset_now();
}
@@ -225,6 +224,8 @@
else if (!flag)
C_A_D = 0;
else if (flag == 0xCDEF0123) {
+ /* SMP: We need to lock during the shutdown still */
+ lock_kernel();
printk(KERN_EMERG "System halted\n");
#ifdef __sparc__
halt_now();
@@ -236,10 +237,8 @@
notifier_call_chain(&boot_notifier_list, SYS_HALT, NULL);
do_exit(0);
} else
- error = -EINVAL;
-out:
- unlock_kernel();
- return error;
+ return -EINVAL;
+ return 0;
}

/*
@@ -659,24 +658,21 @@

asmlinkage long sys_times(struct tms * tbuf)
{
- int error;
-
- lock_kernel();
- if (tbuf) {
- error = put_user(current->utime,&tbuf->tms_utime);
- if (!error)
- error = put_user(current->stime,&tbuf->tms_stime);
- if (!error)
- error = put_user(current->cutime,&tbuf->tms_cutime);
- if (!error)
- error = put_user(current->cstime,&tbuf->tms_cstime);
- if (error)
- goto out;
+ /*
+ * In the SMP world we might just be unlucky and have one of
+ * the times increment as we use it. Since the value is an
+ * atomically safe type this is just fine. Conceptually its
+ * as if the syscall took an instant longer to occur.
+ */
+ if (tbuf)
+ {
+ if(put_user(current->utime,&tbuf->tms_utime)||
+ put_user(current->stime,&tbuf->tms_stime) ||
+ put_user(current->cutime,&tbuf->tms_cutime) ||
+ put_user(current->cstime,&tbuf->tms_cstime))
+ return -EFAULT;
}
- error = jiffies;
-out:
- unlock_kernel();
- return error;
+ return jiffies;
}

/*
@@ -691,6 +687,7 @@
* Auch. Had to add the 'did_exec' flag to conform completely to POSIX.
* LBT 04.03.94
*/
+
asmlinkage int sys_setpgid(pid_t pid, pid_t pgid)
{
struct task_struct * p;
@@ -820,45 +817,40 @@
*/
asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist)
{
- int i, err = -EINVAL;
+ int i;
+
+ /*
+ * SMP: Nobody else can change our grouplist. Thus we are
+ * safe.
+ */

- lock_kernel();
if (gidsetsize < 0)
- goto out;
+ return -EINVAL;
i = current->ngroups;
if (gidsetsize) {
- err = -EINVAL;
if (i > gidsetsize)
- goto out;
- err = -EFAULT;
+ return -EINVAL;
if (copy_to_user(grouplist, current->groups, sizeof(gid_t)*i))
- goto out;
+ return -EFAULT;
}
- err = i;
-out:
- unlock_kernel();
- return err;
+ return i;
}

+/*
+ * SMP: Our groups are not shared. We can copy to/from them safely
+ * without another task interfering.
+ */
+
asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist)
{
- int err = -EPERM;
-
- lock_kernel();
if (!suser())
- goto out;
- err = -EINVAL;
+ return -EPERM;
if ((unsigned) gidsetsize > NGROUPS)
- goto out;
- err = copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t));
- if (err) {
- gidsetsize = 0;
- err = -EFAULT;
- }
+ return -EINVAL;
+ if(copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t)))
+ return -EFAULT;
current->ngroups = gidsetsize;
-out:
- unlock_kernel();
- return err;
+ return 0;
}

int in_group_p(gid_t grp)
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/kernel/time.c linux/kernel/time.c
--- linux.vanilla/kernel/time.c Tue Jan 28 21:33:49 1997
+++ linux/kernel/time.c Sun Feb 2 18:02:30 1997
@@ -66,13 +66,13 @@
{
int i;

- lock_kernel();
+ /* SMP: This is fairly trivial. We grab CURRENT_TIME and
+ stuff it to user space. No side effects */
i = CURRENT_TIME;
if (tloc) {
if (put_user(i,tloc))
i = -EFAULT;
}
- unlock_kernel();
return i;
}

@@ -82,16 +82,20 @@
* why not move it into the appropriate arch directory (for those
* architectures that need it).
*/
+
asmlinkage int sys_stime(int * tptr)
{
int value = -EPERM;

- lock_kernel();
if (!suser())
- goto out;
- value = -EFAULT;
+ return -EPERM;
if (get_user(value, tptr))
- goto out;
+ return -EFAULT;
+ /*
+ * SMP: We need to lock out everything for the time update
+ * the new cli/sti semantics will let us drop this lock soon.
+ */
+ lock_kernel();
cli();
xtime.tv_sec = value;
xtime.tv_usec = 0;
@@ -99,10 +103,8 @@
time_maxerror = MAXPHASE;
time_esterror = MAXPHASE;
sti();
- value = 0;
-out:
unlock_kernel();
- return value;
+ return 0;
}

#endif
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/net/802/fddi.c linux/net/802/fddi.c
--- linux.vanilla/net/802/fddi.c Tue Jan 14 22:10:31 1997
+++ linux/net/802/fddi.c Mon Feb 3 23:11:43 1997
@@ -52,18 +52,23 @@
int fddi_header(struct sk_buff *skb, struct device *dev, unsigned short type,
void *daddr, void *saddr, unsigned len)
{
- struct fddihdr *fddi = (struct fddihdr *)skb_push(skb, FDDI_K_SNAP_HLEN);
-
- /* Fill in frame header - assume 802.2 SNAP frames for now */
-
+ int hl = FDDI_K_SNAP_HLEN;
+ struct fddihdr *fddi;
+
+ if(type!=htons(ETH_P_IP))
+ hl=FDDI_K_8022_HLEN-3;
+ fddi = (struct fddihdr *)skb_push(skb, hl);
fddi->fc = FDDI_FC_K_ASYNC_LLC_DEF;
- fddi->hdr.llc_snap.dsap = FDDI_EXTENDED_SAP;
- fddi->hdr.llc_snap.ssap = FDDI_EXTENDED_SAP;
- fddi->hdr.llc_snap.ctrl = FDDI_UI_CMD;
- fddi->hdr.llc_snap.oui[0] = 0x00;
- fddi->hdr.llc_snap.oui[1] = 0x00;
- fddi->hdr.llc_snap.oui[2] = 0x00;
- fddi->hdr.llc_snap.ethertype = htons(type);
+ if(type==htons(ETH_P_IP))
+ {
+ fddi->hdr.llc_snap.dsap = FDDI_EXTENDED_SAP;
+ fddi->hdr.llc_snap.ssap = FDDI_EXTENDED_SAP;
+ fddi->hdr.llc_snap.ctrl = FDDI_UI_CMD;
+ fddi->hdr.llc_snap.oui[0] = 0x00;
+ fddi->hdr.llc_snap.oui[1] = 0x00;
+ fddi->hdr.llc_snap.oui[2] = 0x00;
+ fddi->hdr.llc_snap.ethertype = htons(type);
+ }

/* Set the source and destination hardware addresses */

@@ -75,9 +80,9 @@
if (daddr != NULL)
{
memcpy(fddi->daddr, daddr, dev->addr_len);
- return(FDDI_K_SNAP_HLEN);
+ return(hl);
}
- return(-FDDI_K_SNAP_HLEN);
+ return(-hl);
}


@@ -114,15 +119,26 @@
unsigned short fddi_type_trans(struct sk_buff *skb, struct device *dev)
{
struct fddihdr *fddi = (struct fddihdr *)skb->data;
-
+ unsigned short type;
+
/*
* Set mac.raw field to point to FC byte, set data field to point
* to start of packet data. Assume 802.2 SNAP frames for now.
*/

skb->mac.raw = skb->data; /* point to frame control (FC) */
- skb_pull(skb, FDDI_K_SNAP_HLEN); /* adjust for 21 byte header */
-
+
+ if(fddi->hdr.llc_8022_1.dsap==0xe0)
+ {
+ skb_pull(skb, FDDI_K_8022_HLEN-3);
+ type=htons(ETH_P_8022);
+ }
+ else
+ {
+ skb_pull(skb, FDDI_K_SNAP_HLEN); /* adjust for 21 byte header */
+ type=fddi->hdr.llc_snap.ethertype;
+ }
+
/* Set packet type based on destination address and flag settings */

if (*fddi->daddr & 0x01)
@@ -141,5 +157,6 @@

/* Assume 802.2 SNAP frames, for now */

- return(fddi->hdr.llc_snap.ethertype);
+ return(type);
+
}
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/net/core/sock.c linux/net/core/sock.c
--- linux.vanilla/net/core/sock.c Tue Jan 28 21:33:50 1997
+++ linux/net/core/sock.c Sun Feb 2 18:29:07 1997
@@ -185,6 +185,10 @@
if(val > 65535)
val = 65535;
sk->sndbuf = val;
+ /*
+ * FIXME: Wake up sending tasks if we
+ * upped the value.
+ */
break;

case SO_RCVBUF:
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/net/ipv4/arp.c linux/net/ipv4/arp.c
--- linux.vanilla/net/ipv4/arp.c Sun Feb 2 17:45:19 1997
+++ linux/net/ipv4/arp.c Mon Feb 3 23:18:32 1997
@@ -54,6 +54,10 @@
* Stuart Cheshire : Metricom and grat arp fixes
* *** FOR 2.1 clean this up ***
* Lawrence V. Stefani: (08/12/96) Added FDDI support.
+ * Alan Cox : Took the AP1000 nasty FDDI hack and
+ * folded into the mainstream FDDI code.
+ * Ack spit, Linus how did you allow that
+ * one in...
*/

/* RFC1122 Status:
@@ -1383,7 +1387,7 @@
* is not from an IP number. We can't currently handle this, so toss
* it.
*/
-#ifdef CONFIG_FDDI
+#if defined(CONFIG_FDDI) || defined(CONFIG_AP1000)
if (dev->type == ARPHRD_FDDI)
{
/*
@@ -1415,18 +1419,7 @@
}
#else
if (arp->ar_hln != dev->addr_len ||
-#if CONFIG_AP1000
- /*
- * ARP from cafe-f was found to use ARPHDR_IEEE802 instead of
- * the expected ARPHDR_ETHER.
- */
- (strcmp(dev->name,"fddi") == 0 &&
- arp->ar_hrd != ARPHRD_ETHER && arp->ar_hrd != ARPHRD_IEEE802) ||
- (strcmp(dev->name,"fddi") != 0 &&
- dev->type != ntohs(arp->ar_hrd)) ||
-#else
dev->type != ntohs(arp->ar_hrd) ||
-#endif
dev->flags & IFF_NOARP ||
skb->pkt_type == PACKET_OTHERHOST ||
arp->ar_pln != 4) {
@@ -1491,8 +1484,6 @@
tha=arp_ptr;
arp_ptr += dev->addr_len;
memcpy(&tip, arp_ptr, 4);
-
-
/*
* Check for bad requests for 127.x.x.x and requests for multicast
* addresses. If this is one such, delete it.
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- linux.vanilla/net/ipv4/tcp_ipv4.c Sun Feb 2 17:45:21 1997
+++ linux/net/ipv4/tcp_ipv4.c Mon Feb 3 23:14:31 1997
@@ -629,7 +629,7 @@
if (sk->ack_backlog >= sk->max_ack_backlog ||
tcp_v4_syn_filter(sk, skb, saddr))
{
- printk(KERN_DEBUG "droping syn ack:%d max:%d\n",
+ printk(KERN_DEBUG "dropping syn ack:%d max:%d\n",
sk->ack_backlog, sk->max_ack_backlog);
#ifdef CONFIG_IP_TCPSF
tcp_v4_random_drop(sk);
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/net/lapb/lapb_iface.c linux/net/lapb/lapb_iface.c
--- linux.vanilla/net/lapb/lapb_iface.c Sun Feb 2 17:45:22 1997
+++ linux/net/lapb/lapb_iface.c Mon Feb 3 22:59:38 1997
@@ -14,6 +14,9 @@
*
* History
* LAPB 001 Jonathan Naylor Started Coding
+ *
+ * TODO
+ * Add FRMRs.
*/

#include <linux/config.h>
@@ -104,7 +107,7 @@
* Convert the integer token used by the device driver into a pointer
* to a LAPB control structure.
*/
-lapb_cb *lapb_tokentostruct(void *token)
+static lapb_cb *lapb_tokentostruct(void *token)
{
lapb_cb *lapb;

@@ -129,6 +132,7 @@

memset(lapb, 0x00, sizeof(*lapb));

+ skb_queue_head_init(&lapb->input_queue);
skb_queue_head_init(&lapb->write_queue);
skb_queue_head_init(&lapb->ack_queue);

@@ -323,6 +327,18 @@
skb_queue_tail(&lapb->write_queue, skb);

lapb_kick(lapb);
+
+ return LAPB_OK;
+}
+
+int lapb_data_received(void *token, struct sk_buff *skb)
+{
+ lapb_cb *lapb;
+
+ if ((lapb = lapb_tokentostruct(token)) == NULL)
+ return LAPB_BADTOKEN;
+
+ skb_queue_tail(&lapb->input_queue, skb);

return LAPB_OK;
}
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/net/lapb/lapb_in.c linux/net/lapb/lapb_in.c
--- linux.vanilla/net/lapb/lapb_in.c Sun Feb 2 17:45:22 1997
+++ linux/net/lapb/lapb_in.c Mon Feb 3 22:59:38 1997
@@ -312,6 +312,7 @@
lapb->condition = 0x00;
lapb->t1timer = 0;
lapb->t2timer = 0;
+ lapb->n2count = 0;
lapb->vs = 0;
lapb->vr = 0;
lapb->va = 0;
@@ -331,6 +332,7 @@
lapb->condition = 0x00;
lapb->t1timer = 0;
lapb->t2timer = 0;
+ lapb->n2count = 0;
lapb->vs = 0;
lapb->vr = 0;
lapb->va = 0;
@@ -384,7 +386,7 @@
#if LAPB_DEBUG > 0
printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n", lapb->token);
#endif
- lapb_nr_error_recovery(lapb);
+ lapb_establish_data_link(lapb);
lapb->state = LAPB_STATE_1;
}
break;
@@ -401,7 +403,7 @@
#if LAPB_DEBUG > 0
printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n", lapb->token);
#endif
- lapb_nr_error_recovery(lapb);
+ lapb_establish_data_link(lapb);
lapb->state = LAPB_STATE_1;
}
break;
@@ -415,12 +417,13 @@
if (lapb_validate_nr(lapb, nr)) {
lapb_frames_acked(lapb, nr);
lapb->t1timer = 0;
+ lapb->n2count = 0;
lapb_requeue_frames(lapb);
} else {
#if LAPB_DEBUG > 0
printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n", lapb->token);
#endif
- lapb_nr_error_recovery(lapb);
+ lapb_establish_data_link(lapb);
lapb->state = LAPB_STATE_1;
}
break;
@@ -433,7 +436,7 @@
#if LAPB_DEBUG > 0
printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n", lapb->token);
#endif
- lapb_nr_error_recovery(lapb);
+ lapb_establish_data_link(lapb);
lapb->state = LAPB_STATE_1;
break;
}
@@ -490,284 +493,11 @@
}

/*
- * State machine for state 4, Timer Recovery State.
- * The handling of the timer(s) is in file lapb_timer.c
- */
-static void lapb_state4_machine(lapb_cb *lapb, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
-{
- int queued = 0;
- int modulus;
-
- modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS : LAPB_SMODULUS;
-
- switch (frametype) {
- case LAPB_SABM:
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 RX SABM(%d)\n", lapb->token, pf);
-#endif
- if (lapb->mode & LAPB_EXTENDED) {
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n", lapb->token, pf);
-#endif
- lapb_send_control(lapb, LAPB_DM, pf, LAPB_RESPONSE);
- } else {
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n", lapb->token, pf);
-#endif
- lapb_send_control(lapb, LAPB_UA, pf, LAPB_RESPONSE);
- lapb->condition = 0x00;
- lapb->t1timer = 0;
- lapb->t2timer = 0;
- lapb->vs = 0;
- lapb->vr = 0;
- lapb->va = 0;
- lapb_requeue_frames(lapb);
- }
- break;
-
- case LAPB_SABME:
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 RX SABME(%d)\n", lapb->token, pf);
-#endif
- if (lapb->mode & LAPB_EXTENDED) {
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n", lapb->token, pf);
-#endif
- lapb_send_control(lapb, LAPB_UA, pf, LAPB_RESPONSE);
- lapb->condition = 0x00;
- lapb->t1timer = 0;
- lapb->t2timer = 0;
- lapb->vs = 0;
- lapb->vr = 0;
- lapb->va = 0;
- lapb_requeue_frames(lapb);
- } else {
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n", lapb->token, pf);
-#endif
- lapb_send_control(lapb, LAPB_DM, pf, LAPB_RESPONSE);
- }
- break;
-
- case LAPB_DISC:
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 RX DISC(%d)\n", lapb->token, pf);
-#endif
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S0\n", lapb->token);
-#endif
- lapb_clear_queues(lapb);
- lapb_send_control(lapb, LAPB_UA, pf, LAPB_RESPONSE);
- lapb->state = LAPB_STATE_0;
- lapb->t1timer = lapb->t1;
- lapb->t2timer = 0;
- lapb_disconnect_indication(lapb, LAPB_OK);
- break;
-
- case LAPB_DM:
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 RX DM(%d)\n", lapb->token, pf);
-#endif
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S0\n", lapb->token);
-#endif
- lapb_clear_queues(lapb);
- lapb->state = LAPB_STATE_0;
- lapb->t1timer = lapb->t1;
- lapb->t2timer = 0;
- lapb_disconnect_indication(lapb, LAPB_NOTCONNECTED);
- break;
-
- case LAPB_RNR:
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 RX RNR(%d) R%d\n", lapb->token, pf, nr);
-#endif
- lapb->condition |= LAPB_PEER_RX_BUSY_CONDITION;
- if (type == LAPB_RESPONSE && pf) {
- lapb->t1timer = 0;
- if (lapb_validate_nr(lapb, nr)) {
- lapb_frames_acked(lapb, nr);
- if (lapb->vs == lapb->va) {
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->token);
-#endif
- lapb->n2count = 0;
- lapb->state = LAPB_STATE_3;
- }
- } else {
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token);
-#endif
- lapb_nr_error_recovery(lapb);
- lapb->state = LAPB_STATE_1;
- }
- break;
- }
-
- lapb_check_need_response(lapb, type, pf);
- if (lapb_validate_nr(lapb, nr)) {
- lapb_frames_acked(lapb, nr);
- } else {
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token);
-#endif
- lapb_nr_error_recovery(lapb);
- lapb->state = LAPB_STATE_1;
- }
- break;
-
- case LAPB_RR:
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 RX RR(%d) R%d\n", lapb->token, pf, nr);
-#endif
- lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
- if (pf && type == LAPB_RESPONSE) {
- lapb->t1timer = 0;
- if (lapb_validate_nr(lapb, nr)) {
- lapb_frames_acked(lapb, nr);
- if (lapb->vs == lapb->va) {
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->token);
-#endif
- lapb->n2count = 0;
- lapb->state = LAPB_STATE_3;
- } else {
- lapb_requeue_frames(lapb);
- }
- } else {
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token);
-#endif
- lapb_nr_error_recovery(lapb);
- lapb->state = LAPB_STATE_1;
- }
- break;
- }
-
- lapb_check_need_response(lapb, type, pf);
- if (lapb_validate_nr(lapb, nr)) {
- lapb_frames_acked(lapb, nr);
- } else {
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token);
-#endif
- lapb_nr_error_recovery(lapb);
- lapb->state = LAPB_STATE_1;
- }
- break;
-
- case LAPB_REJ:
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 RX REJ(%d) R%d\n", lapb->token, pf, nr);
-#endif
- lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
- if (pf && type == LAPB_RESPONSE) {
- lapb->t1timer = 0;
- if (lapb_validate_nr(lapb, nr)) {
- lapb_frames_acked(lapb, nr);
- if (lapb->vs == lapb->va) {
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n", lapb->token);
-#endif
- lapb->n2count = 0;
- lapb->state = LAPB_STATE_3;
- } else {
- lapb_requeue_frames(lapb);
- }
- } else {
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token);
-#endif
- lapb_nr_error_recovery(lapb);
- lapb->state = LAPB_STATE_1;
- }
- break;
- }
-
- lapb_check_need_response(lapb, type, pf);
- if (lapb_validate_nr(lapb, nr)) {
- lapb_frames_acked(lapb, nr);
- if (lapb->vs != lapb->va)
- lapb_requeue_frames(lapb);
- } else {
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token);
-#endif
- lapb_nr_error_recovery(lapb);
- lapb->state = LAPB_STATE_1;
- }
- break;
-
- case LAPB_I:
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 RX I(%d) S%d R%d\n", lapb->token, pf, ns, nr);
-#endif
- if (!lapb_validate_nr(lapb, nr)) {
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token);
-#endif
- lapb_nr_error_recovery(lapb);
- lapb->state = LAPB_STATE_1;
- break;
- }
- lapb_frames_acked(lapb, nr);
- if (ns == lapb->vr) {
- lapb->vr = (lapb->vr + 1) % modulus;
- queued = lapb_data_indication(lapb, skb);
- lapb->condition &= ~LAPB_REJECT_CONDITION;
- if (pf) {
- lapb_enquiry_response(lapb);
- } else {
- if (!(lapb->condition & LAPB_ACK_PENDING_CONDITION)) {
- lapb->t2timer = lapb->t2;
- lapb->condition |= LAPB_ACK_PENDING_CONDITION;
- }
- }
- } else {
- if (lapb->condition & LAPB_REJECT_CONDITION) {
- if (pf)
- lapb_enquiry_response(lapb);
- } else {
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 TX REJ(%d) R%d\n", lapb->token, pf, lapb->vr);
-#endif
- lapb->condition |= LAPB_REJECT_CONDITION;
- lapb_send_control(lapb, LAPB_REJ, pf, LAPB_RESPONSE);
- lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
- }
- }
- break;
-
- case LAPB_FRMR:
- case LAPB_ILLEGAL:
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S4 TX {FRMR,ILLEGAL}(%d)\n", lapb->token, pf);
-#endif
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S1\n", lapb->token);
-#endif
- lapb_establish_data_link(lapb);
- lapb->state = LAPB_STATE_1;
- break;
-
- default:
- break;
- }
-
- if (!queued)
- kfree_skb(skb, FREE_READ);
-}
-
-/*
* Process an incoming LAPB frame
*/
-int lapb_data_received(void *token, struct sk_buff *skb)
+void lapb_data_input(lapb_cb *lapb, struct sk_buff *skb)
{
int frametype, ns, nr, pf, type;
- lapb_cb *lapb;
-
- if ((lapb = lapb_tokentostruct(token)) == NULL)
- return LAPB_BADTOKEN;

del_timer(&lapb->timer);

@@ -786,14 +516,9 @@
case LAPB_STATE_3:
lapb_state3_machine(lapb, skb, frametype, ns, nr, pf, type);
break;
- case LAPB_STATE_4:
- lapb_state4_machine(lapb, skb, frametype, ns, nr, pf, type);
- break;
}

lapb_set_timer(lapb);
-
- return LAPB_OK;
}

#endif
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/net/lapb/lapb_out.c linux/net/lapb/lapb_out.c
--- linux.vanilla/net/lapb/lapb_out.c Thu Jan 23 23:27:33 1997
+++ linux/net/lapb/lapb_out.c Mon Feb 3 22:59:38 1997
@@ -167,11 +167,6 @@
kfree_skb(skb, FREE_WRITE);
}

-void lapb_nr_error_recovery(lapb_cb *lapb)
-{
- lapb_establish_data_link(lapb);
-}
-
void lapb_establish_data_link(lapb_cb *lapb)
{
lapb->condition = 0x00;
@@ -193,19 +188,6 @@
lapb->t1timer = lapb->t1;
}

-void lapb_transmit_enquiry(lapb_cb *lapb)
-{
-#if LAPB_DEBUG > 1
- printk(KERN_DEBUG "lapb: (%p) S%d TX RR(1) R%d\n", lapb->token, lapb->state, lapb->vr);
-#endif
-
- lapb_send_control(lapb, LAPB_RR, LAPB_POLLON, LAPB_COMMAND);
-
- lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
-
- lapb->t1timer = lapb->t1;
-}
-
void lapb_enquiry_response(lapb_cb *lapb)
{
#if LAPB_DEBUG > 1
@@ -233,6 +215,7 @@
if (lapb->vs == nr) {
lapb_frames_acked(lapb, nr);
lapb->t1timer = 0;
+ lapb->n2count = 0;
} else {
if (lapb->va != nr) {
lapb_frames_acked(lapb, nr);
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/net/lapb/lapb_subr.c linux/net/lapb/lapb_subr.c
--- linux.vanilla/net/lapb/lapb_subr.c Thu Jan 23 23:27:34 1997
+++ linux/net/lapb/lapb_subr.c Mon Feb 3 22:59:38 1997
@@ -45,6 +45,9 @@
{
struct sk_buff *skb;

+ while ((skb = skb_dequeue(&lapb->input_queue)) != NULL)
+ kfree_skb(skb, FREE_READ);
+
while ((skb = skb_dequeue(&lapb->write_queue)) != NULL)
kfree_skb(skb, FREE_WRITE);

diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/net/lapb/lapb_timer.c linux/net/lapb/lapb_timer.c
--- linux.vanilla/net/lapb/lapb_timer.c Sun Feb 2 17:45:22 1997
+++ linux/net/lapb/lapb_timer.c Mon Feb 3 22:59:38 1997
@@ -67,12 +67,25 @@
static void lapb_timer(unsigned long param)
{
lapb_cb *lapb = (lapb_cb *)param;
+ struct sk_buff *skb;

- if (lapb->state == LAPB_STATE_3 || lapb->state == LAPB_STATE_4)
+ /*
+ * Process all packet received since the last clock tick.
+ */
+ while ((skb = skb_dequeue(&lapb->input_queue)) != NULL)
+ lapb_data_input(lapb, skb);
+
+ /*
+ * If in a data transfer state, transmit any data.
+ */
+ if (lapb->state == LAPB_STATE_3)
lapb_kick(lapb);

+ /*
+ * T2 expiry code.
+ */
if (lapb->t2timer > 0 && --lapb->t2timer == 0) {
- if (lapb->state == LAPB_STATE_3 || lapb->state == LAPB_STATE_4) {
+ if (lapb->state == LAPB_STATE_3) {
if (lapb->condition & LAPB_ACK_PENDING_CONDITION) {
lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
lapb_timeout_response(lapb);
@@ -80,16 +93,30 @@
}
}

+ /*
+ * If T1 isn't running, or hasn't timed out yet, keep going.
+ */
if (lapb->t1timer == 0 || --lapb->t1timer > 0) {
lapb_set_timer(lapb);
return;
}

+ /*
+ * T1 has expired.
+ */
switch (lapb->state) {
+
+ /*
+ * If we are a DCE, keep going DM .. DM .. DM
+ */
case LAPB_STATE_0:
if (lapb->mode & LAPB_DCE)
lapb_send_control(lapb, LAPB_DM, LAPB_POLLOFF, LAPB_RESPONSE);
break;
+
+ /*
+ * Awaiting connection state, send SABM(E), up to N2 times.
+ */
case LAPB_STATE_1:
if (lapb->n2count == lapb->n2) {
lapb_clear_queues(lapb);
@@ -115,6 +142,9 @@
}
break;

+ /*
+ * Awaiting disconnection state, send DISC, up to N2 times.
+ */
case LAPB_STATE_2:
if (lapb->n2count == lapb->n2) {
lapb_clear_queues(lapb);
@@ -133,27 +163,21 @@
}
break;

- case LAPB_STATE_3:
- lapb->n2count = 1;
- lapb_transmit_enquiry(lapb);
- lapb->state = LAPB_STATE_4;
-#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->token);
-#endif
- break;
-
- case LAPB_STATE_4:
+ /*
+ * Data transfer state, restransmit I frames, up to N2 times.
+ */
+ case LAPB_STATE_3:
if (lapb->n2count == lapb->n2) {
lapb_clear_queues(lapb);
lapb->state = LAPB_STATE_0;
lapb->t2timer = 0;
lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
#if LAPB_DEBUG > 0
- printk(KERN_DEBUG "lapb: (%p) S4 -> S0\n", lapb->token);
+ printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n", lapb->token);
#endif
} else {
lapb->n2count++;
- lapb_transmit_enquiry(lapb);
+ lapb_requeue_frames(lapb);
}
break;
}
diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/net/netrom/nr_dev.c linux/net/netrom/nr_dev.c
--- linux.vanilla/net/netrom/nr_dev.c Sun Feb 2 17:45:22 1997
+++ linux/net/netrom/nr_dev.c Mon Feb 3 22:59:38 1997
@@ -59,7 +59,7 @@

int nr_rx_ip(struct sk_buff *skb, struct device *dev)
{
- struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
+ struct net_device_stats *stats = (struct net_device_stats *)dev->priv;

if (!dev->start) {
stats->rx_errors++;
@@ -67,6 +67,8 @@
}

stats->rx_packets++;
+ stats->rx_bytes += skb->len;
+
skb->protocol = htons(ETH_P_IP);

/* Spoof incoming device */
@@ -115,7 +117,7 @@
static int nr_rebuild_header(struct sk_buff *skb)
{
struct device *dev = skb->dev;
- struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
+ struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
struct sk_buff *skbn;
unsigned char *bp = skb->data;

@@ -149,6 +151,7 @@
}

stats->tx_packets++;
+ stats->tx_bytes += skbn->len;

return 1;
}
@@ -188,7 +191,7 @@

static int nr_xmit(struct sk_buff *skb, struct device *dev)
{
- struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
+ struct net_device_stats *stats = (struct net_device_stats *)dev->priv;

if (skb == NULL || dev == NULL)
return 0;
@@ -221,9 +224,9 @@
return 0;
}

-static struct enet_statistics *nr_get_stats(struct device *dev)
+static struct net_device_stats *nr_get_stats(struct device *dev)
{
- return (struct enet_statistics *)dev->priv;
+ return (struct net_device_stats *)dev->priv;
}

int nr_init(struct device *dev)
@@ -250,10 +253,10 @@
dev->pa_mask = 0;
dev->pa_alen = sizeof(unsigned long);

- if ((dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL)) == NULL)
+ if ((dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL)) == NULL)
return -ENOMEM;

- memset(dev->priv, 0, sizeof(struct enet_statistics));
+ memset(dev->priv, 0, sizeof(struct net_device_stats));

dev->get_stats = nr_get_stats;

diff --unified --recursive --new-file --exclude-from exclude linux.vanilla/net/rose/rose_dev.c linux/net/rose/rose_dev.c
--- linux.vanilla/net/rose/rose_dev.c Sun Feb 2 17:45:23 1997
+++ linux/net/rose/rose_dev.c Mon Feb 3 22:59:38 1997
@@ -55,7 +55,7 @@

int rose_rx_ip(struct sk_buff *skb, struct device *dev)
{
- struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
+ struct net_device_stats *stats = (struct net_device_stats *)dev->priv;

if (!dev->start) {
stats->rx_errors++;
@@ -63,6 +63,8 @@
}

stats->rx_packets++;
+ stats->rx_bytes += skb->len;
+
skb->protocol = htons(ETH_P_IP);

/* Spoof incoming device */
@@ -96,7 +98,7 @@
static int rose_rebuild_header(struct sk_buff *skb)
{
struct device *dev = skb->dev;
- struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
+ struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
unsigned char *bp = (unsigned char *)skb->data;
struct sk_buff *skbn;

@@ -121,6 +123,7 @@
}

stats->tx_packets++;
+ stats->tx_bytes += skbn->len;

return 1;
}
@@ -160,7 +163,7 @@

static int rose_xmit(struct sk_buff *skb, struct device *dev)
{
- struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
+ struct net_device_stats *stats = (struct net_device_stats *)dev->priv;

if (skb == NULL || dev == NULL)
return 0;
@@ -193,9 +196,9 @@
return 0;
}

-static struct enet_statistics *rose_get_stats(struct device *dev)
+static struct net_device_stats *rose_get_stats(struct device *dev)
{
- return (struct enet_statistics *)dev->priv;
+ return (struct net_device_stats *)dev->priv;
}

int rose_init(struct device *dev)
@@ -222,10 +225,10 @@
dev->pa_mask = 0;
dev->pa_alen = sizeof(unsigned long);

- if ((dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL)) == NULL)
+ if ((dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL)) == NULL)
return -ENOMEM;

- memset(dev->priv, 0, sizeof(struct enet_statistics));
+ memset(dev->priv, 0, sizeof(struct net_device_stats));

dev->get_stats = rose_get_stats;