Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
bb9c5bf1
Commit
bb9c5bf1
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 1.3.10
parent
c3aa3674
Changes
57
Show whitespace changes
Inline
Side-by-side
Showing
57 changed files
with
2718 additions
and
1369 deletions
+2718
-1369
CREDITS
CREDITS
+11
-4
Makefile
Makefile
+3
-1
Rules.make
Rules.make
+1
-1
arch/alpha/boot/bootloader.lds
arch/alpha/boot/bootloader.lds
+49
-0
arch/alpha/kernel/Makefile
arch/alpha/kernel/Makefile
+1
-1
arch/alpha/kernel/entry.S
arch/alpha/kernel/entry.S
+15
-13
arch/alpha/kernel/process.c
arch/alpha/kernel/process.c
+0
-1
arch/alpha/kernel/ptrace.c
arch/alpha/kernel/ptrace.c
+192
-68
arch/alpha/kernel/traps.c
arch/alpha/kernel/traps.c
+26
-6
arch/alpha/vmlinux.lds
arch/alpha/vmlinux.lds
+49
-0
arch/i386/config.in
arch/i386/config.in
+1
-0
drivers/block/cdu31a.c
drivers/block/cdu31a.c
+81
-69
drivers/block/genhd.c
drivers/block/genhd.c
+6
-0
drivers/char/selection.c
drivers/char/selection.c
+3
-2
drivers/char/tty_ioctl.c
drivers/char/tty_ioctl.c
+221
-46
drivers/net/README.arcnet
drivers/net/README.arcnet
+91
-62
drivers/net/README.arcnet-jumpers
drivers/net/README.arcnet-jumpers
+396
-46
drivers/net/arcnet.c
drivers/net/arcnet.c
+958
-682
drivers/net/eql.c
drivers/net/eql.c
+1
-1
drivers/net/loopback.c
drivers/net/loopback.c
+1
-1
drivers/net/net_init.c
drivers/net/net_init.c
+3
-2
drivers/net/pi2.c
drivers/net/pi2.c
+1
-1
drivers/net/ppp.c
drivers/net/ppp.c
+14
-15
drivers/net/slip.c
drivers/net/slip.c
+1
-1
drivers/net/tunnel.c
drivers/net/tunnel.c
+3
-3
drivers/scsi/scsi_proc.c
drivers/scsi/scsi_proc.c
+0
-1
drivers/sound/pas2_card.c
drivers/sound/pas2_card.c
+2
-1
drivers/sound/sound_config.h
drivers/sound/sound_config.h
+4
-0
fs/ext2/namei.c
fs/ext2/namei.c
+1
-1
include/asm-alpha/a.out.h
include/asm-alpha/a.out.h
+69
-19
include/asm-alpha/lca.h
include/asm-alpha/lca.h
+9
-2
include/asm-alpha/termios.h
include/asm-alpha/termios.h
+56
-1
include/asm-i386/termios.h
include/asm-i386/termios.h
+34
-1
include/linux/etherdevice.h
include/linux/etherdevice.h
+2
-0
include/linux/fdreg.h
include/linux/fdreg.h
+1
-1
include/linux/icmp.h
include/linux/icmp.h
+6
-6
include/linux/if_ppp.h
include/linux/if_ppp.h
+37
-37
include/linux/in.h
include/linux/in.h
+8
-0
include/linux/netdevice.h
include/linux/netdevice.h
+1
-1
include/linux/sched.h
include/linux/sched.h
+1
-1
include/linux/skbuff.h
include/linux/skbuff.h
+5
-0
include/linux/symtab_begin.h
include/linux/symtab_begin.h
+16
-12
include/net/eth.h
include/net/eth.h
+1
-1
include/net/head_explode.h
include/net/head_explode.h
+0
-140
include/net/ip.h
include/net/ip.h
+1
-2
include/net/tcp.h
include/net/tcp.h
+3
-1
mm/vmalloc.c
mm/vmalloc.c
+114
-13
net/Changes
net/Changes
+50
-19
net/core/datagram.c
net/core/datagram.c
+2
-2
net/core/dev.c
net/core/dev.c
+5
-6
net/ipv4/af_inet.c
net/ipv4/af_inet.c
+5
-0
net/ipv4/icmp.c
net/ipv4/icmp.c
+2
-2
net/ipv4/igmp.c
net/ipv4/igmp.c
+14
-18
net/ipv4/ip.c
net/ipv4/ip.c
+124
-48
net/ipv4/ipip.c
net/ipv4/ipip.c
+2
-2
net/ipv4/route.c
net/ipv4/route.c
+6
-4
net/ipv4/udp.c
net/ipv4/udp.c
+9
-1
No files found.
CREDITS
View file @
bb9c5bf1
...
...
@@ -172,13 +172,20 @@ S: East Malvern, Victoria, 3145
S: Australia
N: Alan Cox
E:
A.Cox@swansea
.ac.uk
E:
iiitac@pyr.swan.ac.uk
E:
iialan@iifeak.swan
.ac.uk
E:
alan@cymru.net (use for commercial traffic)
E: gw4pts@gw4pts.ampr.org
E: GW4PTS@GB7SWN (packet radio)
D: NET2Debugged author
S: c/o I^2IT Limited
S: The Innovation Centre
S: University Of Wales
S: Swansea, SA2 8PP
S: Wales, UK
D: NET2Debugged/NET3 author
D: Network layer debugging
D: AX.25 & IPX alpha releases
D: Initial AX.25 & IPX releases
D: Original Linux netatalk patches.
D: Current 3c501 hacker. >>More 3c501 info/tricks wanted<<.
N: Laurence Culhane
E: loz@holmes.demon.co.uk
...
...
Makefile
View file @
bb9c5bf1
VERSION
=
1
PATCHLEVEL
=
3
SUBLEVEL
=
9
SUBLEVEL
=
10
ARCH
=
i386
...
...
@@ -283,3 +283,5 @@ else
dummy
:
endif
include
Rules.make
Rules.make
View file @
bb9c5bf1
...
...
@@ -6,7 +6,7 @@
# Common rules
#
.c.s
:
$(CC)
$(CFLAGS)
-S
$<
$(CC)
$(CFLAGS)
-S
$<
-o
$@
#
# A rule to do nothing
...
...
arch/alpha/boot/bootloader.lds
0 → 100644
View file @
bb9c5bf1
OUTPUT_FORMAT("ecoff-littlealpha")
ENTRY(__start)
SECTIONS
{
.text 0x20000000: {
_ftext = . ;
__istart = . ;
eprol = .;
*(.text)
__fstart = . ;
_etext = .;
}
.rdata : {
*(.rdata)
}
.pdata : {
_fpdata = .;
*(.pdata)
}
.data : {
_fdata = .;
*(.data)
CONSTRUCTORS
}
.xdata : {
*(.xdata)
}
_gp = ALIGN (16) + 0x8000;
.lit8 : {
*(.lit8)
}
.lita : {
*(.lita)
}
.sdata : {
*(.sdata)
}
_EDATA = .;
_FBSS = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
*(.bss)
*(COMMON)
}
_end = .;
}
arch/alpha/kernel/Makefile
View file @
bb9c5bf1
...
...
@@ -17,7 +17,7 @@
$(CC)
-D__ASSEMBLY__
-traditional
-c
$<
-o
$*
.o
OBJS
=
entry.o traps.o process.o osf_sys.o irq.o signal.o setup.o
\
lca.o bios32.o
lca.o bios32.o
ptrace.o
all
:
kernel.o head.o
...
...
arch/alpha/kernel/entry.S
View file @
bb9c5bf1
...
...
@@ -105,6 +105,9 @@
.
text
.
set
noat
#ifdef __linux__
.
set
singlegp
#endif
.
align
3
.
globl
entInt
...
...
@@ -191,9 +194,11 @@ kernel_fork:
stq
$
16
,
24
(
$
30
)
stq
$
17
,
32
(
$
30
)
stq
$
18
,
40
(
$
30
)
bis
$
31
,
2
,
$
0
/*
Register
v0
:
syscall
nr
for
fork
()
*/
SAVE_ALL
lda
$
27
,
sys_fork
jsr
$
26
,(
$
27
),
sys_fork
stq
$
0
,
0
(
$
30
)
br
ret_from_sys_call
.
end
kernel_fork
...
...
@@ -240,7 +245,7 @@ do_switch_stack:
stt
$f28
,
288
(
$
30
)
stt
$f29
,
296
(
$
30
)
stt
$f30
,
304
(
$
30
)
ret
$
31
,(
$
0
),
1
ret
$
31
,(
$
1
),
1
.
end
do_switch_stack
.
align
3
...
...
@@ -286,7 +291,7 @@ undo_switch_stack:
ldt
$f29
,
296
(
$
30
)
ldt
$f30
,
304
(
$
30
)
lda
$
30
,
SWITCH_STACK_SIZE
(
$
30
)
ret
$
31
,(
$
0
),
1
ret
$
31
,(
$
1
),
1
.
end
undo_switch_stack
.
align
3
...
...
@@ -363,14 +368,11 @@ entUna:
.
globl
sys_fork
.
ent
sys_fork
sys_fork
:
br
$
0
,
do_switch_stack
br
$
1
,
do_switch_stack
bis
$
30
,
$
30
,
$
16
lda
$
27
,
alpha_fork
jsr
$
26
,(
$
27
),
alpha_fork
br
$
0
,
undo_switch_stack
ldq
$
0
,
0
(
$
30
)
bis
$
31
,
2
,
$
19
/*
Make
sure
that
the
stored
user
register
v0
has
*/
stq
$
19
,
0
(
$
30
)
/*
the
syscall
#
for
fork
*/
br
$
1
,
undo_switch_stack
ret
$
31
,(
$
26
),
1
.
end
sys_fork
...
...
@@ -378,9 +380,9 @@ sys_fork:
.
globl
alpha_switch_to
.
ent
alpha_switch_to
alpha_switch_to
:
br
$
0
,
do_switch_stack
br
$
1
,
do_switch_stack
call_pal
PAL_swpctx
br
$
0
,
undo_switch_stack
br
$
1
,
undo_switch_stack
ret
$
31
,(
$
26
),
1
.
end
alpha_switch_to
...
...
@@ -450,7 +452,7 @@ restore_all:
.
align
3
signal_return
:
bis
$
30
,
$
30
,
$
17
br
$
0
,
do_switch_stack
br
$
1
,
do_switch_stack
bis
$
30
,
$
30
,
$
18
lda
$
27
,
do_signal
jsr
$
26
,(
$
27
),
do_signal
...
...
@@ -480,7 +482,7 @@ sys_sigreturn:
bis
$
30
,
$
30
,
$
18
lda
$
27
,
do_sigreturn
jsr
$
26
,(
$
27
),
do_sigreturn
br
$
0
,
undo_switch_stack
br
$
1
,
undo_switch_stack
br
$
31
,
ret_from_sys_call
.
end
sys_sigreturn
...
...
@@ -488,7 +490,7 @@ sys_sigreturn:
.
ent
sys_sigsuspend
sys_sigsuspend
:
bis
$
30
,
$
30
,
$
17
br
$
0
,
do_switch_stack
br
$
1
,
do_switch_stack
bis
$
30
,
$
30
,
$
18
lda
$
27
,
do_sigsuspend
jsr
$
26
,(
$
27
),
do_sigsuspend
...
...
@@ -504,7 +506,7 @@ sys_call_table:
.
quad
sys_unlink
,
do_entSys
,
sys_chdir
,
sys_fchdir
,
sys_mknod
.
quad
sys_chmod
,
sys_chown
,
sys_brk
,
do_entSys
,
sys_lseek
.
quad
sys_getxpid
,
osf_mount
,
osf_umount
,
sys_setuid
,
sys_getxuid
.
quad
do_entSys
,
do_entSys
,
do_entSys
,
do_entSys
,
do_entSys
.
quad
do_entSys
,
sys_ptrace
,
do_entSys
,
do_entSys
,
do_entSys
.
quad
do_entSys
,
do_entSys
,
do_entSys
,
sys_access
,
do_entSys
.
quad
do_entSys
,
sys_sync
,
sys_kill
,
do_entSys
,
sys_setpgid
.
quad
do_entSys
,
sys_dup
,
sys_pipe
,
do_entSys
,
do_entSys
...
...
arch/alpha/kernel/process.c
View file @
bb9c5bf1
...
...
@@ -123,7 +123,6 @@ void copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
childregs
->
r0
=
0
;
childregs
->
r19
=
0
;
childregs
->
r20
=
1
;
/* OSF/1 has some strange fork() semantics.. */
regs
->
r0
=
p
->
pid
;
regs
->
r20
=
0
;
stack
=
((
struct
switch_stack
*
)
regs
)
-
1
;
childstack
=
((
struct
switch_stack
*
)
childregs
)
-
1
;
...
...
arch/alpha/kernel/ptrace.c
View file @
bb9c5bf1
...
...
@@ -16,6 +16,25 @@
#include <asm/pgtable.h>
#include <asm/system.h>
#undef DEBUG
#ifdef DEBUG
enum
{
DBG_MEM
=
(
1
<<
0
),
DBG_BPT
=
(
1
<<
1
)
};
int
debug_mask
=
DBG_BPT
;
# define DBG(fac,args) {if ((fac) & debug_mask) printk args;}
#else
# define DBG(fac,args)
#endif
#define BREAKINST 0x00000080
/* call_pal bpt */
/* This was determined via brute force. */
#define MAGICNUM 496
...
...
@@ -24,18 +43,6 @@
* in exit.c or in signal.c.
*/
/* determines which flags the user has access to. */
/* 1 = access 0 = no access */
#define FLAG_MASK 0x00044dd5
/* set's the trap flag. */
#define TRAP_FLAG 0x100
/*
* this is the number to subtract from the top of the stack. To find
* the local frame.
*/
/* A mapping between register number and its offset on the kernel stack.
* You also need to add MAGICNUM to get past the kernel stack frame
* to the actual saved user info.
...
...
@@ -43,6 +50,12 @@
* 320 is the size of the switch_stack area.
*/
enum
{
REG_R0
=
0
,
REG_F0
=
32
,
REG_PC
=
64
};
static
int
map_reg_to_offset
[]
=
{
320
+
0
,
320
+
8
,
320
+
16
,
320
+
24
,
320
+
32
,
320
+
40
,
320
+
48
,
320
+
56
,
320
+
64
,
/* 0-8 */
0
,
8
,
16
,
24
,
32
,
40
,
48
,
/* 9-15 */
...
...
@@ -58,19 +71,14 @@ static int map_reg_to_offset[] = {
320
+
168
};
static
int
offset_of_register
(
int
reg_num
)
{
if
(
reg_num
<
0
||
reg_num
>
64
)
{
static
int
offset_of_register
(
int
reg_num
)
{
if
(
reg_num
<
0
||
reg_num
>
64
)
{
return
-
1
;
}
return
map_reg_to_offset
[
reg_num
];
}
static
void
unset_singlestep
(
struct
task_struct
*
child
)
{
}
static
void
set_singlestep
(
struct
task_struct
*
child
)
{
}
/* change a pid into a task struct. */
static
inline
struct
task_struct
*
get_task
(
int
pid
)
{
...
...
@@ -130,9 +138,7 @@ static unsigned long get_long(struct vm_area_struct * vma, unsigned long addr)
pte_t
*
pgtable
;
unsigned
long
page
;
#ifdef DEBUG
printk
(
"Getting long at 0x%lx
\n
"
,
addr
);
#endif
DBG
(
DBG_MEM
,
(
"Getting long at 0x%lx
\n
"
,
addr
));
repeat:
pgdir
=
pgd_offset
(
vma
->
vm_task
,
addr
);
if
(
pgd_none
(
*
pgdir
))
{
...
...
@@ -254,9 +260,7 @@ static int read_long(struct task_struct * tsk, unsigned long addr,
{
struct
vm_area_struct
*
vma
=
find_extend_vma
(
tsk
,
addr
);
#ifdef DEBUG
printk
(
"in read_long
\n
"
);
#endif
DBG
(
DBG_MEM
,
(
"in read_long
\n
"
));
if
(
!
vma
)
{
printk
(
"Unable to find vma for addr 0x%lx
\n
"
,
addr
);
return
-
EIO
;
...
...
@@ -306,9 +310,7 @@ static int read_long(struct task_struct * tsk, unsigned long addr,
}
else
{
long
l
=
get_long
(
vma
,
addr
);
#ifdef DEBUG
printk
(
"value is 0x%lx
\n
"
,
l
);
#endif
DBG
(
DBG_MEM
,
(
"value is 0x%lx
\n
"
,
l
));
*
result
=
l
;
}
return
0
;
...
...
@@ -391,33 +393,160 @@ static int write_long(struct task_struct * tsk, unsigned long addr,
return
0
;
}
/* Uh, this does ugly stuff. It stores the specified value in the a3
/*
* Read a 32bit int from address space TSK.
*/
static
int
read_int
(
struct
task_struct
*
tsk
,
unsigned
long
addr
,
unsigned
int
*
data
)
{
unsigned
long
l
,
align
;
int
res
;
align
=
addr
&
0x7
;
addr
&=
~
0x7
;
res
=
read_long
(
tsk
,
addr
,
&
l
);
if
(
res
<
0
)
return
res
;
if
(
align
==
0
)
{
*
data
=
l
;
}
else
{
*
data
=
l
>>
32
;
}
return
0
;
}
/*
* Write a 32bit word to address space TSK.
*
* For simplicity, do a read-modify-write of the 64bit word that
* contains the 32bit word that we are about to write.
*/
static
int
write_int
(
struct
task_struct
*
tsk
,
unsigned
long
addr
,
unsigned
int
data
)
{
unsigned
long
l
,
align
;
int
res
;
align
=
addr
&
0x7
;
addr
&=
~
0x7
;
res
=
read_long
(
tsk
,
addr
,
&
l
);
if
(
res
<
0
)
return
res
;
if
(
align
==
0
)
{
l
=
(
l
&
0xffffffff00000000UL
)
|
((
unsigned
long
)
data
<<
0
);
}
else
{
l
=
(
l
&
0x00000000ffffffffUL
)
|
((
unsigned
long
)
data
<<
32
);
}
return
write_long
(
tsk
,
addr
,
l
);
}
/*
* Uh, this does ugly stuff. It stores the specified value in the a3
* register. entry.S will swap a3 and the returned value from
* sys_ptrace() before returning to the user.
*/
static
inline
void
set_success
(
struct
pt_regs
*
regs
,
long
resval
)
{
regs
->
r19
=
resval
;
static
inline
void
set_success
(
struct
pt_regs
*
regs
,
long
resval
)
{
regs
->
r19
=
resval
;
}
/* This doesn't do diddly, actually--if the value returned from
/*
* This doesn't do diddly, actually--if the value returned from
* sys_ptrace() is != 0, it sets things up properly.
*/
static
inline
void
set_failure
(
struct
pt_regs
*
regs
,
long
errcode
)
{
regs
->
r19
=
0
;
static
inline
void
set_failure
(
struct
pt_regs
*
regs
,
long
errcode
)
{
regs
->
r19
=
0
;
}
asmlinkage
long
sys_ptrace
(
long
request
,
long
pid
,
long
addr
,
long
data
,
int
a4
,
int
a5
,
struct
pt_regs
regs
)
/*
* Set breakpoint.
*/
static
int
set_bpt
(
struct
task_struct
*
child
)
{
int
displ
,
i
,
res
,
reg_b
,
off
,
nsaved
=
0
;
u32
insn
,
op_code
;
unsigned
long
pc
;
pc
=
get_stack_long
(
child
,
map_reg_to_offset
[
REG_PC
]);
res
=
read_int
(
child
,
pc
,
&
insn
);
if
(
res
<
0
)
return
res
;
op_code
=
insn
>>
26
;
if
(
op_code
>=
0x30
)
{
/*
* It's a branch: instead of trying to figure out
* whether the branch will be taken or not, we'll put
* a breakpoint at either location. This is simpler,
* more reliable, and probably not a whole lot slower
* than the alternative approach of emulating the
* branch (emulation can be tricky for fp branches).
*/
displ
=
((
s32
)(
insn
<<
11
))
>>
9
;
child
->
debugreg
[
nsaved
++
]
=
pc
+
4
;
if
(
displ
)
/* guard against unoptimized code */
child
->
debugreg
[
nsaved
++
]
=
pc
+
4
+
displ
;
DBG
(
DBG_BPT
,
(
"execing branch
\n
"
));
}
else
if
(
op_code
==
0x1a
)
{
reg_b
=
(
insn
>>
16
)
&
0x1f
;
off
=
offset_of_register
(
reg_b
);
if
(
off
>=
0
)
{
child
->
debugreg
[
nsaved
++
]
=
get_stack_long
(
child
,
off
);
}
else
{
/* $31 (aka zero) doesn't have a stack-slot */
if
(
reg_b
==
31
)
{
child
->
debugreg
[
nsaved
++
]
=
0
;
}
else
{
return
-
EIO
;
}
}
DBG
(
DBG_BPT
,
(
"execing jump
\n
"
));
}
else
{
child
->
debugreg
[
nsaved
++
]
=
pc
+
4
;
DBG
(
DBG_BPT
,
(
"execing normal insn
\n
"
));
}
/* install breakpoints: */
for
(
i
=
0
;
i
<
nsaved
;
++
i
)
{
res
=
read_int
(
child
,
child
->
debugreg
[
i
],
&
insn
);
if
(
res
<
0
)
return
res
;
child
->
debugreg
[
i
+
2
]
=
insn
;
DBG
(
DBG_BPT
,
(
" -> next_pc=%lx
\n
"
,
child
->
debugreg
[
i
]));
res
=
write_int
(
child
,
child
->
debugreg
[
i
],
BREAKINST
);
if
(
res
<
0
)
return
res
;
}
child
->
debugreg
[
4
]
=
nsaved
;
return
0
;
}
int
ptrace_cancel_bpt
(
struct
task_struct
*
child
)
{
int
i
,
nsaved
=
child
->
debugreg
[
4
];
child
->
debugreg
[
4
]
=
0
;
for
(
i
=
0
;
i
<
nsaved
;
++
i
)
{
write_int
(
child
,
child
->
debugreg
[
i
],
child
->
debugreg
[
i
+
2
]);
}
return
nsaved
;
}
asmlinkage
long
sys_ptrace
(
long
request
,
long
pid
,
long
addr
,
long
data
,
int
a4
,
int
a5
,
struct
pt_regs
regs
)
{
struct
task_struct
*
child
;
struct
user
*
dummy
;
int
res
;
dummy
=
NULL
;
#ifdef DEBUG
printk
(
"request=%ld pid=%ld addr=0x%lx data=0x%lx
\n
"
,
request
,
pid
,
addr
,
data
);
#endif
DBG
(
DBG_MEM
,
(
"request=%ld pid=%ld addr=0x%lx data=0x%lx
\n
"
,
request
,
pid
,
addr
,
data
));
set_success
(
&
regs
,
0
);
if
(
request
==
PTRACE_TRACEME
)
{
/* are we already being traced? */
...
...
@@ -465,25 +594,19 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4,
return
0
;
}
if
(
!
(
child
->
flags
&
PF_PTRACED
))
{
#ifdef DEBUG
printk
(
"child not traced
\n
"
);
#endif
DBG
(
DBG_MEM
,
(
"child not traced
\n
"
));
set_failure
(
&
regs
,
-
ESRCH
);
return
-
ESRCH
;
}
if
(
child
->
state
!=
TASK_STOPPED
)
{
#ifdef DEBUG
printk
(
"child process not stopped
\n
"
);
#endif
DBG
(
DBG_MEM
,
(
"child process not stopped
\n
"
));
if
(
request
!=
PTRACE_KILL
)
{
set_failure
(
&
regs
,
-
ESRCH
);
return
-
ESRCH
;
}
}
if
(
child
->
p_pptr
!=
current
)
{
#ifdef DEBUG
printk
(
"child not parent of this process
\n
"
);
#endif
DBG
(
DBG_MEM
,
(
"child not parent of this process
\n
"
));
set_failure
(
&
regs
,
-
ESRCH
);
return
-
ESRCH
;
}
...
...
@@ -495,9 +618,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4,
unsigned
long
tmp
;
int
res
;
#ifdef DEBUG
printk
(
"doing request at addr 0x%lx
\n
"
,
addr
);
#endif
DBG
(
DBG_MEM
,
(
"doing request at addr 0x%lx
\n
"
,
addr
));
res
=
read_long
(
child
,
addr
,
&
tmp
);
if
(
res
<
0
)
{
set_failure
(
&
regs
,
res
);
...
...
@@ -520,16 +641,16 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4,
tmp
=
child
->
tss
.
usp
;
}
else
{
#ifdef DEBUG
int
reg
=
addr
;
#endif
addr
=
offset_of_register
(
addr
);
if
(
addr
<
0
)
{
set_failure
(
&
regs
,
-
EIO
);
if
(
addr
<
0
)
{
set_failure
(
&
regs
,
-
EIO
);
return
-
EIO
;
}
tmp
=
get_stack_long
(
child
,
addr
);
#ifdef DEBUG
printk
(
"%d = reg 0x%lx=tmp
\n
"
,
reg
,
tmp
);
#endif
DBG
(
DBG_MEM
,
(
"%d = reg 0x%lx=tmp
\n
"
,
reg
,
tmp
));
}
set_success
(
&
regs
,
tmp
);
return
0
;
...
...
@@ -573,12 +694,12 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4,
child
->
flags
&=
~
PF_TRACESYS
;
child
->
exit_code
=
data
;
child
->
state
=
TASK_RUNNING
;
unset_singlestep
(
child
);
ptrace_cancel_bpt
(
child
);
set_success
(
&
regs
,
data
);
return
0
;
}
/*
/*
* make the child exit. Best I can do is send it a sigkill.
* perhaps it should be put in the status that it wants to
* exit.
...
...
@@ -586,7 +707,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4,
case
PTRACE_KILL
:
{
child
->
state
=
TASK_RUNNING
;
child
->
exit_code
=
SIGKILL
;
unset_singlestep
(
child
);
ptrace_cancel_bpt
(
child
);
return
0
;
}
...
...
@@ -595,8 +716,11 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4,
set_failure
(
&
regs
,
-
EIO
);
return
-
EIO
;
}
res
=
set_bpt
(
child
);
if
(
res
<
0
)
{
return
res
;
}
child
->
flags
&=
~
PF_TRACESYS
;
set_singlestep
(
child
);
child
->
state
=
TASK_RUNNING
;
child
->
exit_code
=
data
;
/* give it a chance to run. */
...
...
@@ -615,7 +739,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data, int a4,
child
->
p_pptr
=
child
->
p_opptr
;
SET_LINKS
(
child
);
/* make sure the single step bit is not set. */
unset_singlestep
(
child
);
ptrace_cancel_bpt
(
child
);
return
0
;
}
...
...
arch/alpha/kernel/traps.c
View file @
bb9c5bf1
...
...
@@ -19,10 +19,10 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err)
unsigned
long
sp
;
unsigned
int
*
pc
;
if
(
regs
->
ps
&
8
)
return
;
printk
(
"%s(%d): %s %ld
\n
"
,
current
->
comm
,
current
->
pid
,
str
,
err
);
sp
=
(
unsigned
long
)
(
regs
+
1
);
if
(
regs
->
ps
&
8
)
sp
=
rdusp
();
printk
(
"pc = %lx ps = %04lx
\n
"
,
regs
->
pc
,
regs
->
ps
);
printk
(
"rp = %lx sp = %lx
\n
"
,
regs
->
r26
,
sp
);
printk
(
"r0=%lx r1=%lx r2=%lx r3=%lx
\n
"
,
...
...
@@ -36,8 +36,6 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err)
regs
->
r24
,
regs
->
r25
,
regs
->
r26
,
regs
->
r27
);
printk
(
"r28=%lx r29=%lx r30=%lx
\n
"
,
regs
->
r28
,
regs
->
gp
,
sp
);
if
(
regs
->
ps
&
8
)
return
;
printk
(
"Code:"
);
pc
=
(
unsigned
int
*
)
regs
->
pc
;
for
(
i
=
-
3
;
i
<
6
;
i
++
)
...
...
@@ -61,8 +59,29 @@ asmlinkage void do_entIF(unsigned long type, unsigned long a1, unsigned long a2,
unsigned
long
a3
,
unsigned
long
a4
,
unsigned
long
a5
,
struct
pt_regs
regs
)
{
extern
int
ptrace_cancel_bpt
(
struct
task_struct
*
who
);
die_if_kernel
(
"Instruction fault"
,
&
regs
,
type
);
switch
(
type
)
{
case
0
:
/* breakpoint */
if
(
ptrace_cancel_bpt
(
current
))
{
regs
.
pc
-=
4
;
/* make pc point to former bpt */
}
if
(
current
->
flags
&
PF_PTRACED
)
current
->
blocked
&=
~
(
1
<<
(
SIGTRAP
-
1
));
send_sig
(
SIGTRAP
,
current
,
1
);
break
;
case
1
:
/* bugcheck */
case
2
:
/* gentrap */
case
3
:
/* FEN fault */
case
4
:
/* opDEC */
send_sig
(
SIGILL
,
current
,
1
);
break
;
default:
panic
(
"do_entIF: unexpected instruction-fault type"
);
}
}
/*
...
...
@@ -131,6 +150,7 @@ asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg,
asmlinkage
long
do_entSys
(
unsigned
long
a0
,
unsigned
long
a1
,
unsigned
long
a2
,
unsigned
long
a3
,
unsigned
long
a4
,
unsigned
long
a5
,
struct
pt_regs
regs
)
{
if
(
regs
.
r0
!=
112
)
printk
(
"<sc %ld(%lx,%lx,%lx)>"
,
regs
.
r0
,
a0
,
a1
,
a2
);
return
-
1
;
}
...
...
arch/alpha/vmlinux.lds
0 → 100644
View file @
bb9c5bf1
OUTPUT_FORMAT("ecoff-littlealpha")
ENTRY(__start)
SECTIONS
{
.text 0xfffffc0000310000: {
_ftext = . ;
__istart = . ;
eprol = .;
*(.text)
__fstart = . ;
_etext = .;
}
.rdata : {
*(.rdata)
}
.pdata : {
_fpdata = .;
*(.pdata)
}
.data : {
_fdata = .;
*(.data)
CONSTRUCTORS
}
.xdata : {
*(.xdata)
}
_gp = ALIGN (16) + 0x8000;
.lit8 : {
*(.lit8)
}
.lita : {
*(.lita)
}
.sdata : {
*(.sdata)
}
_EDATA = .;
_FBSS = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
*(.bss)
*(COMMON)
}
_end = .;
}
arch/i386/config.in
View file @
bb9c5bf1
...
...
@@ -60,6 +60,7 @@ bool 'IP: Reverse ARP' CONFIG_INET_RARP n
bool 'IP: Assume subnets are local' CONFIG_INET_SNARL y
bool 'IP: Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n
bool 'IP: Drop source routed frames' CONFIG_IP_NOSR y
bool 'IP: Allow large windows (not recommend if <16Mb of memory)' CONFIG_SKB_LARGE y
fi
bool 'The IPX protocol' CONFIG_IPX n
bool 'Appletalk DDP' CONFIG_ATALK n
...
...
drivers/block/cdu31a.c
View file @
bb9c5bf1
...
...
@@ -185,7 +185,7 @@
#define DEBUG 0
#define CDU31A_READAHEAD
64
/* 64 sector, 32kB, 16
reads read-ahead */
#define CDU31A_READAHEAD
128
/* 128 sector, 64kB, 32
reads read-ahead */
#define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10
/* Define the following if you have data corruption problems. */
...
...
@@ -380,6 +380,8 @@ cdu31a_interrupt(int irq, struct pt_regs *regs)
static
inline
void
sony_sleep
(
void
)
{
unsigned
long
flags
;
if
(
irq_used
<=
0
)
{
current
->
state
=
TASK_INTERRUPTIBLE
;
...
...
@@ -388,10 +390,11 @@ sony_sleep(void)
}
else
/* Interrupt driven */
{
save_flags
(
flags
);
cli
();
enable_interrupts
();
interruptible_sleep_on
(
&
cdu31a_irq_wait
);
sti
(
);
restore_flags
(
flags
);
}
}
...
...
@@ -516,6 +519,18 @@ set_drive_params(void)
unsigned
char
params
[
3
];
params
[
0
]
=
SONY_SD_AUTO_SPIN_DOWN_TIME
;
params
[
1
]
=
0x00
;
/* Never spin down the drive. */
do_sony_cd_cmd
(
SONY_SET_DRIVE_PARAM_CMD
,
params
,
2
,
res_reg
,
&
res_size
);
if
((
res_size
<
2
)
||
((
res_reg
[
0
]
&
0xf0
)
==
0x20
))
{
printk
(
" Unable to set spin-down time: 0x%2.2x
\n
"
,
res_reg
[
1
]);
}
params
[
0
]
=
SONY_SD_MECH_CONTROL
;
params
[
1
]
=
0x03
;
/* Set auto spin up and auto eject */
if
(
is_double_speed
)
...
...
@@ -753,8 +768,10 @@ do_sony_cd_cmd(unsigned char cmd,
unsigned
int
retry_count
;
int
num_retries
;
int
recursive_call
;
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
if
(
current
!=
has_cd_task
)
/* Allow recursive calls to this routine */
{
...
...
@@ -777,7 +794,7 @@ do_sony_cd_cmd(unsigned char cmd,
{
recursive_call
=
1
;
}
sti
(
);
restore_flags
(
flags
);
num_retries
=
0
;
retry_cd_operation:
...
...
@@ -1356,24 +1373,31 @@ do_cdu31a_request(void)
unsigned
char
res_reg
[
12
];
unsigned
int
res_size
;
int
num_retries
;
unsigned
long
flags
;
/*
* Make sure no one else is using the driver; wait for them
* to finish if it is so.
*/
save_flags
(
flags
);
cli
();
while
(
sony_inuse
)
{
interruptible_sleep_on
(
&
sony_wait
);
if
(
current
->
signal
&
~
current
->
blocked
)
{
restore_flags
(
flags
);
if
(
CURRENT
&&
(
CURRENT
->
dev
>
0
))
{
end_request
(
0
);
}
return
;
}
}
sony_inuse
=
1
;
has_cd_task
=
current
;
sti
(
);
restore_flags
(
flags
);
/* Get drive status before doing anything. */
while
(
handle_sony_cd_attention
())
...
...
@@ -1507,6 +1531,7 @@ do_cdu31a_request(void)
}
if
(
start_request
(
block
/
4
,
CDU31A_READAHEAD
/
4
,
0
))
{
printk
(
"CDU31a: start request failed
\n
"
);
end_request
(
0
);
goto
cdu31a_request_startover
;
}
...
...
@@ -1991,11 +2016,13 @@ read_audio(struct cdrom_read_audio *ra,
unsigned
char
res_reg
[
12
];
unsigned
int
res_size
;
unsigned
int
cframe
;
unsigned
long
flags
;
/*
* Make sure no one else is using the driver; wait for them
* to finish if it is so.
*/
save_flags
(
flags
);
cli
();
while
(
sony_inuse
)
{
...
...
@@ -2007,7 +2034,7 @@ read_audio(struct cdrom_read_audio *ra,
}
sony_inuse
=
1
;
has_cd_task
=
current
;
sti
(
);
restore_flags
(
flags
);
if
(
!
sony_spun_up
)
{
...
...
@@ -2167,8 +2194,20 @@ read_audio(struct cdrom_read_audio *ra,
/*
* The big ugly ioctl handler.
*/
static
int
scd_ioctl
(
struct
inode
*
inode
,
static
int
do_sony_cd_cmd_chk
(
char
*
name
,
unsigned
char
cmd
,
unsigned
char
*
params
,
unsigned
int
num_params
,
unsigned
char
*
result_buffer
,
unsigned
int
*
result_size
)
{
do_sony_cd_cmd
(
cmd
,
params
,
num_params
,
result_buffer
,
result_size
);
if
((
*
result_size
<
2
)
||
((
result_buffer
[
0
]
&
0xf0
)
==
0x20
))
{
printk
(
"Sony CDROM error 0x%2.2x (CDROM%s)
\n
"
,
result_buffer
[
1
],
name
);
return
-
EIO
;
}
return
0
;
}
static
int
scd_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
...
...
@@ -2187,12 +2226,7 @@ scd_ioctl(struct inode *inode,
switch
(
cmd
)
{
case
CDROMSTART
:
/* Spin up the drive */
do_sony_cd_cmd
(
SONY_SPIN_UP_CMD
,
NULL
,
0
,
res_reg
,
&
res_size
);
if
((
res_size
<
2
)
||
((
res_reg
[
0
]
&
0xf0
)
==
0x20
))
{
printk
(
"Sony CDROM error 0x%2.2x (CDROMSTART)
\n
"
,
res_reg
[
1
]);
return
-
EIO
;
}
return
do_sony_cd_cmd_chk
(
"START"
,
SONY_SPIN_UP_CMD
,
NULL
,
0
,
res_reg
,
&
res_size
);
return
0
;
break
;
...
...
@@ -2204,25 +2238,11 @@ scd_ioctl(struct inode *inode,
* already not spinning.
*/
sony_audio_status
=
CDROM_AUDIO_NO_STATUS
;
do_sony_cd_cmd
(
SONY_SPIN_DOWN_CMD
,
NULL
,
0
,
res_reg
,
&
res_size
);
if
(
((
res_size
<
2
)
||
((
res_reg
[
0
]
&
0xf0
)
==
0x20
))
&&
(
res_reg
[
1
]
!=
SONY_NOT_SPIN_ERR
))
{
printk
(
"Sony CDROM error 0x%2.2x (CDROMSTOP)
\n
"
,
res_reg
[
1
]);
return
-
EIO
;
}
return
0
;
break
;
return
do_sony_cd_cmd_chk
(
"STOP"
,
SONY_SPIN_DOWN_CMD
,
NULL
,
0
,
res_reg
,
&
res_size
);
case
CDROMPAUSE
:
/* Pause the drive */
do_sony_cd_cmd
(
SONY_AUDIO_STOP_CMD
,
NULL
,
0
,
res_reg
,
&
res_size
);
if
((
res_size
<
2
)
||
((
res_reg
[
0
]
&
0xf0
)
==
0x20
))
{
printk
(
"Sony CDROM error 0x%2.2x (CDROMPAUSE)
\n
"
,
res_reg
[
1
]);
if
(
do_sony_cd_cmd_chk
(
"PAUSE"
,
SONY_AUDIO_STOP_CMD
,
NULL
,
0
,
res_reg
,
&
res_size
))
return
-
EIO
;
}
/* Get the current position and save it for resuming */
if
(
read_subcode
()
<
0
)
{
...
...
@@ -2251,18 +2271,15 @@ scd_ioctl(struct inode *inode,
params
[
5
]
=
final_pos_msf
[
1
];
params
[
6
]
=
final_pos_msf
[
2
];
params
[
0
]
=
0x03
;
do_sony_cd_cmd
(
SONY_AUDIO_PLAYBACK_CMD
,
params
,
7
,
res_reg
,
&
res_size
);
if
((
res_size
<
2
)
||
((
res_reg
[
0
]
&
0xf0
)
==
0x20
))
{
printk
(
"Sony CDROM error 0x%2.2x (CDROMRESUME)
\n
"
,
res_reg
[
1
]);
if
(
do_sony_cd_cmd_chk
(
"RESUME"
,
SONY_AUDIO_PLAYBACK_CMD
,
params
,
7
,
res_reg
,
&
res_size
)
<
0
)
return
-
EIO
;
}
sony_audio_status
=
CDROM_AUDIO_PLAY
;
return
0
;
break
;
case
CDROMPLAYMSF
:
/* Play starting at the given MSF address. */
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
6
);
i
=
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
6
);
if
(
i
)
return
i
;
do_sony_cd_cmd
(
SONY_SPIN_UP_CMD
,
NULL
,
0
,
res_reg
,
&
res_size
);
memcpy_fromfs
(
&
(
params
[
1
]),
(
void
*
)
arg
,
6
);
...
...
@@ -2272,12 +2289,8 @@ scd_ioctl(struct inode *inode,
params
[
i
]
=
int_to_bcd
(
params
[
i
]);
}
params
[
0
]
=
0x03
;
do_sony_cd_cmd
(
SONY_AUDIO_PLAYBACK_CMD
,
params
,
7
,
res_reg
,
&
res_size
);
if
((
res_size
<
2
)
||
((
res_reg
[
0
]
&
0xf0
)
==
0x20
))
{
printk
(
"Sony CDROM error 0x%2.2x (CDROMPLAYMSF)
\n
"
,
res_reg
[
1
]);
if
(
do_sony_cd_cmd_chk
(
"PLAYMSF"
,
SONY_AUDIO_PLAYBACK_CMD
,
params
,
7
,
res_reg
,
&
res_size
)
<
0
)
return
-
EIO
;
}
/* Save the final position for pauses and resumes */
final_pos_msf
[
0
]
=
params
[
4
];
...
...
@@ -2285,7 +2298,6 @@ scd_ioctl(struct inode *inode,
final_pos_msf
[
2
]
=
params
[
6
];
sony_audio_status
=
CDROM_AUDIO_PLAY
;
return
0
;
break
;
case
CDROMREADTOCHDR
:
/* Read the table of contents header */
{
...
...
@@ -2299,13 +2311,14 @@ scd_ioctl(struct inode *inode,
}
hdr
=
(
struct
cdrom_tochdr
*
)
arg
;
verify_area
(
VERIFY_WRITE
,
hdr
,
sizeof
(
*
hdr
));
i
=
verify_area
(
VERIFY_WRITE
,
hdr
,
sizeof
(
*
hdr
));
if
(
i
<
0
)
return
i
;
loc_hdr
.
cdth_trk0
=
bcd_to_int
(
sony_toc
->
first_track_num
);
loc_hdr
.
cdth_trk1
=
bcd_to_int
(
sony_toc
->
last_track_num
);
memcpy_tofs
(
hdr
,
&
loc_hdr
,
sizeof
(
*
hdr
));
}
return
0
;
break
;
case
CDROMREADTOCENTRY
:
/* Read a given table of contents entry */
{
...
...
@@ -2321,8 +2334,12 @@ scd_ioctl(struct inode *inode,
}
entry
=
(
struct
cdrom_tocentry
*
)
arg
;
verify_area
(
VERIFY_READ
,
entry
,
sizeof
(
*
entry
));
verify_area
(
VERIFY_WRITE
,
entry
,
sizeof
(
*
entry
));
i
=
verify_area
(
VERIFY_READ
,
entry
,
sizeof
(
*
entry
));
if
(
i
<
0
)
return
i
;
i
=
verify_area
(
VERIFY_WRITE
,
entry
,
sizeof
(
*
entry
));
if
(
i
<
0
)
return
i
;
memcpy_fromfs
(
&
loc_entry
,
entry
,
sizeof
(
loc_entry
));
...
...
@@ -2373,7 +2390,9 @@ scd_ioctl(struct inode *inode,
return
-
EIO
;
}
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
sizeof
(
ti
));
i
=
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
sizeof
(
ti
));
if
(
i
<
0
)
return
i
;
memcpy_fromfs
(
&
ti
,
(
char
*
)
arg
,
sizeof
(
ti
));
if
(
(
ti
.
cdti_trk0
<
sony_toc
->
first_track_num
)
...
...
@@ -2416,6 +2435,7 @@ scd_ioctl(struct inode *inode,
do_sony_cd_cmd
(
SONY_SPIN_UP_CMD
,
NULL
,
0
,
res_reg
,
&
res_size
);
do_sony_cd_cmd
(
SONY_AUDIO_PLAYBACK_CMD
,
params
,
7
,
res_reg
,
&
res_size
);
if
((
res_size
<
2
)
||
((
res_reg
[
0
]
&
0xf0
)
==
0x20
))
{
printk
(
"Params: %x %x %x %x %x %x %x
\n
"
,
params
[
0
],
params
[
1
],
...
...
@@ -2439,34 +2459,22 @@ scd_ioctl(struct inode *inode,
{
struct
cdrom_volctrl
volctrl
;
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
sizeof
(
volctrl
));
i
=
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
sizeof
(
volctrl
));
if
(
i
<
0
)
return
i
;
memcpy_fromfs
(
&
volctrl
,
(
char
*
)
arg
,
sizeof
(
volctrl
));
params
[
0
]
=
SONY_SD_AUDIO_VOLUME
;
params
[
1
]
=
volctrl
.
channel0
;
params
[
2
]
=
volctrl
.
channel1
;
do_sony_cd_cmd
(
SONY_SET_DRIVE_PARAM_CMD
,
params
,
3
,
res_reg
,
&
res_size
);
if
((
res_size
<
2
)
||
((
res_reg
[
0
]
&
0xf0
)
==
0x20
))
{
printk
(
"Sony CDROM error 0x%2.2x (CDROMVOLCTRL)
\n
"
,
res_reg
[
1
]);
return
-
EIO
;
}
return
do_sony_cd_cmd_chk
(
"VOLCTRL"
,
SONY_SET_DRIVE_PARAM_CMD
,
params
,
3
,
res_reg
,
&
res_size
);
}
return
0
;
case
CDROMEJECT
:
/* Eject the drive */
do_sony_cd_cmd
(
SONY_AUDIO_STOP_CMD
,
NULL
,
0
,
res_reg
,
&
res_size
);
do_sony_cd_cmd
(
SONY_SPIN_DOWN_CMD
,
NULL
,
0
,
res_reg
,
&
res_size
);
sony_audio_status
=
CDROM_AUDIO_INVALID
;
do_sony_cd_cmd
(
SONY_EJECT_CMD
,
NULL
,
0
,
res_reg
,
&
res_size
);
if
((
res_size
<
2
)
||
((
res_reg
[
0
]
&
0xf0
)
==
0x20
))
{
printk
(
"Sony CDROM error 0x%2.2x (CDROMEJECT)
\n
"
,
res_reg
[
1
]);
return
-
EIO
;
}
return
0
;
break
;
return
do_sony_cd_cmd_chk
(
"EJECT"
,
SONY_EJECT_CMD
,
NULL
,
0
,
res_reg
,
&
res_size
);
case
CDROMREADAUDIO
:
/* Read 2352 byte audio tracks and 2340 byte
raw data tracks. */
...
...
@@ -2480,10 +2488,14 @@ scd_ioctl(struct inode *inode,
return
-
EIO
;
}
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
sizeof
(
ra
));
i
=
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
sizeof
(
ra
));
if
(
i
<
0
)
return
i
;
memcpy_fromfs
(
&
ra
,
(
char
*
)
arg
,
sizeof
(
ra
));
verify_area
(
VERIFY_WRITE
,
ra
.
buf
,
CD_FRAMESIZE_RAW
*
ra
.
nframes
);
i
=
verify_area
(
VERIFY_WRITE
,
ra
.
buf
,
CD_FRAMESIZE_RAW
*
ra
.
nframes
);
if
(
i
<
0
)
return
i
;
if
(
ra
.
addr_format
==
CDROM_LBA
)
{
...
...
drivers/block/genhd.c
View file @
bb9c5bf1
...
...
@@ -114,7 +114,9 @@ static int msdos_partition(struct gendisk *hd, unsigned int dev, unsigned long f
struct
buffer_head
*
bh
;
struct
partition
*
p
;
int
mask
=
(
1
<<
hd
->
minor_shift
)
-
1
;
#ifdef CONFIG_BLK_DEV_IDE
extern
void
ide_xlate_1024
(
dev_t
);
#endif
read_mbr:
if
(
!
(
bh
=
bread
(
dev
,
0
,
1024
)))
{
...
...
@@ -149,7 +151,9 @@ static int msdos_partition(struct gendisk *hd, unsigned int dev, unsigned long f
first_sector
+=
p
->
end_sector
;
hd
->
part
[
MINOR
(
dev
)].
start_sect
+=
p
->
end_sector
;
hd
->
part
[
MINOR
(
dev
)].
nr_sects
-=
p
->
end_sector
;
#ifdef CONFIG_BLK_DEV_IDE
ide_xlate_1024
(
dev
);
/* harmless if not an IDE drive */
#endif
bh
->
b_dirt
=
0
;
/* prevent re-use of this block */
bh
->
b_uptodate
=
0
;
bh
->
b_req
=
0
;
...
...
@@ -162,7 +166,9 @@ static int msdos_partition(struct gendisk *hd, unsigned int dev, unsigned long f
*/
if
(
p
->
sys_ind
==
DM6_AUXPARTITION
)
{
printk
(
" [DM6]"
);
#ifdef CONFIG_BLK_DEV_IDE
ide_xlate_1024
(
dev
);
/* harmless if not an IDE drive */
#endif
}
current_minor
+=
4
;
/* first "extra" minor (for extended partitions) */
...
...
drivers/char/selection.c
View file @
bb9c5bf1
...
...
@@ -15,6 +15,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/malloc.h>
#include <linux/types.h>
#include <asm/segment.h>
...
...
@@ -69,7 +70,7 @@ clear_selection(void) {
* User settable table: what characters are to be considered alphabetic?
* 256 bits
*/
static
u
nsigned
long
inwordLut
[
8
]
=
{
static
u
32
inwordLut
[
8
]
=
{
0x00000000
,
/* control chars */
0x03FF0000
,
/* digits */
0x87FFFFFE
,
/* uppercase and '_' */
...
...
@@ -90,7 +91,7 @@ int sel_loadlut(const unsigned long arg)
int
i
=
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
36
);
if
(
i
)
return
i
;
memcpy_fromfs
(
inwordLut
,
(
u
nsigned
long
*
)(
arg
+
4
),
32
);
memcpy_fromfs
(
inwordLut
,
(
u
32
*
)(
arg
+
4
),
32
);
return
0
;
}
...
...
drivers/char/tty_ioctl.c
View file @
bb9c5bf1
...
...
@@ -94,48 +94,13 @@ static void unset_locked_termios(struct termios *termios,
old
->
c_cc
[
i
]
:
termios
->
c_cc
[
i
];
}
static
int
set_termios
(
struct
tty_struct
*
tty
,
unsigned
long
arg
,
int
opt
)
static
void
change_termios
(
struct
tty_struct
*
tty
,
struct
termios
*
new_termios
)
{
struct
termio
tmp_termio
;
struct
termios
tmp_termios
;
int
canon_change
;
struct
termios
old_termios
=
*
tty
->
termios
;
int
retval
,
canon_change
;
retval
=
tty_check_change
(
tty
);
if
(
retval
)
return
retval
;
if
(
opt
&
TERMIOS_TERMIO
)
{
retval
=
verify_area
(
VERIFY_READ
,
(
void
*
)
arg
,
sizeof
(
struct
termio
));
if
(
retval
)
return
retval
;
tmp_termios
=
*
tty
->
termios
;
memcpy_fromfs
(
&
tmp_termio
,
(
struct
termio
*
)
arg
,
sizeof
(
struct
termio
));
#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y))
SET_LOW_BITS
(
tmp_termios
.
c_iflag
,
tmp_termio
.
c_iflag
);
SET_LOW_BITS
(
tmp_termios
.
c_oflag
,
tmp_termio
.
c_oflag
);
SET_LOW_BITS
(
tmp_termios
.
c_cflag
,
tmp_termio
.
c_cflag
);
SET_LOW_BITS
(
tmp_termios
.
c_lflag
,
tmp_termio
.
c_lflag
);
memcpy
(
&
tmp_termios
.
c_cc
,
&
tmp_termio
.
c_cc
,
NCC
);
#undef SET_LOW_BITS
}
else
{
retval
=
verify_area
(
VERIFY_READ
,
(
void
*
)
arg
,
sizeof
(
struct
termios
));
if
(
retval
)
return
retval
;
memcpy_fromfs
(
&
tmp_termios
,
(
struct
termios
*
)
arg
,
sizeof
(
struct
termios
));
}
if
((
opt
&
TERMIOS_FLUSH
)
&&
tty
->
ldisc
.
flush_buffer
)
tty
->
ldisc
.
flush_buffer
(
tty
);
if
(
opt
&
TERMIOS_WAIT
)
tty_wait_until_sent
(
tty
,
0
);
cli
();
*
tty
->
termios
=
tmp
_termios
;
*
tty
->
termios
=
*
new
_termios
;
unset_locked_termios
(
tty
->
termios
,
&
old_termios
,
tty
->
termios_locked
);
canon_change
=
(
old_termios
.
c_lflag
^
tty
->
termios
->
c_lflag
)
&
ICANON
;
if
(
canon_change
)
{
...
...
@@ -173,7 +138,41 @@ static int set_termios(struct tty_struct * tty, unsigned long arg, int opt)
if
(
tty
->
ldisc
.
set_termios
)
(
*
tty
->
ldisc
.
set_termios
)(
tty
,
&
old_termios
);
}
static
int
set_termios
(
struct
tty_struct
*
tty
,
unsigned
long
arg
,
int
opt
)
{
struct
termios
tmp_termios
;
int
retval
;
retval
=
tty_check_change
(
tty
);
if
(
retval
)
return
retval
;
if
(
opt
&
TERMIOS_TERMIO
)
{
struct
termio
tmp_termio
;
retval
=
verify_area
(
VERIFY_READ
,
(
void
*
)
arg
,
sizeof
(
struct
termio
));
if
(
retval
)
return
retval
;
tmp_termios
=
*
tty
->
termios
;
memcpy_fromfs
(
&
tmp_termio
,
(
struct
termio
*
)
arg
,
sizeof
(
struct
termio
));
trans_from_termio
(
&
tmp_termio
,
&
tmp_termios
);
}
else
{
retval
=
verify_area
(
VERIFY_READ
,
(
void
*
)
arg
,
sizeof
(
struct
termios
));
if
(
retval
)
return
retval
;
memcpy_fromfs
(
&
tmp_termios
,
(
struct
termios
*
)
arg
,
sizeof
(
struct
termios
));
}
if
((
opt
&
TERMIOS_FLUSH
)
&&
tty
->
ldisc
.
flush_buffer
)
tty
->
ldisc
.
flush_buffer
(
tty
);
if
(
opt
&
TERMIOS_WAIT
)
tty_wait_until_sent
(
tty
,
0
);
change_termios
(
tty
,
&
tmp_termios
);
return
0
;
}
...
...
@@ -185,13 +184,7 @@ static int get_termio(struct tty_struct * tty, struct termio * termio)
i
=
verify_area
(
VERIFY_WRITE
,
termio
,
sizeof
(
struct
termio
));
if
(
i
)
return
i
;
tmp_termio
.
c_iflag
=
tty
->
termios
->
c_iflag
;
tmp_termio
.
c_oflag
=
tty
->
termios
->
c_oflag
;
tmp_termio
.
c_cflag
=
tty
->
termios
->
c_cflag
;
tmp_termio
.
c_lflag
=
tty
->
termios
->
c_lflag
;
tmp_termio
.
c_line
=
tty
->
termios
->
c_line
;
for
(
i
=
0
;
i
<
NCC
;
i
++
)
tmp_termio
.
c_cc
[
i
]
=
tty
->
termios
->
c_cc
[
i
];
trans_to_termio
(
tty
->
termios
,
&
tmp_termio
);
memcpy_tofs
(
termio
,
&
tmp_termio
,
sizeof
(
struct
termio
));
return
0
;
}
...
...
@@ -215,6 +208,169 @@ static unsigned long inq_canon(struct tty_struct * tty)
return
nr
;
}
#ifdef TIOCGETP
/*
* These are depracated, but there is limited support..
*
* The "sg_flags" translation is a joke..
*/
static
int
get_sgflags
(
struct
tty_struct
*
tty
)
{
int
flags
=
0
;
if
(
!
(
tty
->
termios
->
c_lflag
&
ICANON
))
if
(
tty
->
termios
->
c_lflag
&
ISIG
)
flags
|=
0x02
;
/* cbreak */
else
flags
|=
0x20
;
/* raw */
if
(
tty
->
termios
->
c_lflag
&
ECHO
)
flags
|=
0x08
;
/* echo */
if
(
tty
->
termios
->
c_oflag
&
OPOST
)
if
(
tty
->
termios
->
c_oflag
&
ONLCR
)
flags
|=
0x10
;
/* crmod */
return
flags
;
}
static
int
get_sgttyb
(
struct
tty_struct
*
tty
,
struct
sgttyb
*
sgttyb
)
{
int
retval
;
struct
sgttyb
tmp
;
retval
=
verify_area
(
VERIFY_WRITE
,
sgttyb
,
sizeof
(
struct
sgttyb
));
if
(
retval
)
return
retval
;
tmp
.
sg_ispeed
=
0
;
tmp
.
sg_ospeed
=
0
;
tmp
.
sg_erase
=
tty
->
termios
->
c_cc
[
VERASE
];
tmp
.
sg_kill
=
tty
->
termios
->
c_cc
[
VKILL
];
tmp
.
sg_flags
=
get_sgflags
(
tty
);
memcpy_tofs
(
sgttyb
,
&
tmp
,
sizeof
(
tmp
));
return
0
;
}
static
void
set_sgflags
(
struct
termios
*
termios
,
int
flags
)
{
termios
->
c_iflag
=
ICRNL
|
IXON
;
termios
->
c_oflag
=
0
;
termios
->
c_lflag
=
ISIG
|
ICANON
;
if
(
flags
&
0x02
)
{
/* cbreak */
termios
->
c_iflag
=
0
;
termios
->
c_lflag
&=
~
ICANON
;
}
if
(
flags
&
0x08
)
{
/* echo */
termios
->
c_lflag
|=
ECHO
|
ECHOE
|
ECHOK
|
ECHOCTL
|
ECHOKE
|
IEXTEN
;
}
if
(
flags
&
0x10
)
{
/* crmod */
termios
->
c_oflag
|=
OPOST
|
ONLCR
;
}
if
(
flags
&
0x20
)
{
/* raw */
termios
->
c_iflag
=
0
;
termios
->
c_lflag
&=
~
(
ISIG
|
ICANON
);
}
if
(
!
(
termios
->
c_lflag
&
ICANON
))
{
termios
->
c_cc
[
VMIN
]
=
1
;
termios
->
c_cc
[
VTIME
]
=
0
;
}
}
static
int
set_sgttyb
(
struct
tty_struct
*
tty
,
struct
sgttyb
*
sgttyb
)
{
int
retval
;
struct
sgttyb
tmp
;
struct
termios
termios
;
retval
=
verify_area
(
VERIFY_READ
,
sgttyb
,
sizeof
(
struct
sgttyb
));
if
(
retval
)
return
retval
;
retval
=
tty_check_change
(
tty
);
if
(
retval
)
return
retval
;
termios
=
*
tty
->
termios
;
memcpy_fromfs
(
&
tmp
,
sgttyb
,
sizeof
(
tmp
));
termios
.
c_cc
[
VERASE
]
=
tmp
.
sg_erase
;
termios
.
c_cc
[
VKILL
]
=
tmp
.
sg_kill
;
set_sgflags
(
&
termios
,
tmp
.
sg_flags
);
change_termios
(
tty
,
&
termios
);
return
0
;
}
#endif
#ifdef TIOCGETC
static
int
get_tchars
(
struct
tty_struct
*
tty
,
struct
tchars
*
tchars
)
{
int
retval
;
struct
tchars
tmp
;
retval
=
verify_area
(
VERIFY_WRITE
,
tchars
,
sizeof
(
struct
tchars
));
if
(
retval
)
return
retval
;
tmp
.
t_intrc
=
tty
->
termios
->
c_cc
[
VINTR
];
tmp
.
t_quitc
=
tty
->
termios
->
c_cc
[
VQUIT
];
tmp
.
t_startc
=
tty
->
termios
->
c_cc
[
VSTART
];
tmp
.
t_stopc
=
tty
->
termios
->
c_cc
[
VSTOP
];
tmp
.
t_eofc
=
tty
->
termios
->
c_cc
[
VEOF
];
tmp
.
t_brkc
=
tty
->
termios
->
c_cc
[
VEOL2
];
/* what is brkc anyway? */
memcpy_tofs
(
tchars
,
&
tmp
,
sizeof
(
tmp
));
return
0
;
}
static
int
set_tchars
(
struct
tty_struct
*
tty
,
struct
tchars
*
tchars
)
{
int
retval
;
struct
tchars
tmp
;
retval
=
verify_area
(
VERIFY_READ
,
tchars
,
sizeof
(
struct
tchars
));
if
(
retval
)
return
retval
;
memcpy_fromfs
(
&
tmp
,
tchars
,
sizeof
(
tmp
));
tty
->
termios
->
c_cc
[
VINTR
]
=
tmp
.
t_intrc
;
tty
->
termios
->
c_cc
[
VQUIT
]
=
tmp
.
t_quitc
;
tty
->
termios
->
c_cc
[
VSTART
]
=
tmp
.
t_startc
;
tty
->
termios
->
c_cc
[
VSTOP
]
=
tmp
.
t_stopc
;
tty
->
termios
->
c_cc
[
VEOF
]
=
tmp
.
t_eofc
;
tty
->
termios
->
c_cc
[
VEOL2
]
=
tmp
.
t_brkc
;
/* what is brkc anyway? */
return
0
;
}
#endif
#ifdef TIOCGLTC
static
int
get_ltchars
(
struct
tty_struct
*
tty
,
struct
ltchars
*
ltchars
)
{
int
retval
;
struct
ltchars
tmp
;
retval
=
verify_area
(
VERIFY_WRITE
,
ltchars
,
sizeof
(
struct
ltchars
));
if
(
retval
)
return
retval
;
tmp
.
t_suspc
=
tty
->
termios
->
c_cc
[
VSUSP
];
tmp
.
t_dsuspc
=
tty
->
termios
->
c_cc
[
VSUSP
];
/* what is dsuspc anyway? */
tmp
.
t_rprntc
=
tty
->
termios
->
c_cc
[
VREPRINT
];
tmp
.
t_flushc
=
tty
->
termios
->
c_cc
[
VEOL2
];
/* what is flushc anyway? */
tmp
.
t_werasc
=
tty
->
termios
->
c_cc
[
VWERASE
];
tmp
.
t_lnextc
=
tty
->
termios
->
c_cc
[
VLNEXT
];
memcpy_tofs
(
ltchars
,
&
tmp
,
sizeof
(
tmp
));
return
0
;
}
static
int
set_ltchars
(
struct
tty_struct
*
tty
,
struct
ltchars
*
ltchars
)
{
int
retval
;
struct
ltchars
tmp
;
retval
=
verify_area
(
VERIFY_READ
,
ltchars
,
sizeof
(
struct
ltchars
));
if
(
retval
)
return
retval
;
memcpy_fromfs
(
&
tmp
,
ltchars
,
sizeof
(
tmp
));
tty
->
termios
->
c_cc
[
VSUSP
]
=
tmp
.
t_suspc
;
tty
->
termios
->
c_cc
[
VEOL2
]
=
tmp
.
t_dsuspc
;
/* what is dsuspc anyway? */
tty
->
termios
->
c_cc
[
VREPRINT
]
=
tmp
.
t_rprntc
;
tty
->
termios
->
c_cc
[
VEOL2
]
=
tmp
.
t_flushc
;
/* what is flushc anyway? */
tty
->
termios
->
c_cc
[
VWERASE
]
=
tmp
.
t_werasc
;
tty
->
termios
->
c_cc
[
VLNEXT
]
=
tmp
.
t_lnextc
;
return
0
;
}
#endif
int
n_tty_ioctl
(
struct
tty_struct
*
tty
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
...
...
@@ -229,6 +385,25 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
real_tty
=
tty
;
switch
(
cmd
)
{
#ifdef TIOCGETP
case
TIOCGETP
:
return
get_sgttyb
(
real_tty
,
(
struct
sgttyb
*
)
arg
);
case
TIOCSETP
:
case
TIOCSETN
:
return
set_sgttyb
(
real_tty
,
(
struct
sgttyb
*
)
arg
);
#endif
#ifdef TIOCGETC
case
TIOCGETC
:
return
get_tchars
(
real_tty
,
(
struct
tchars
*
)
arg
);
case
TIOCSETC
:
return
set_tchars
(
real_tty
,
(
struct
tchars
*
)
arg
);
#endif
#ifdef TIOCGLTC
case
TIOCGLTC
:
return
get_ltchars
(
real_tty
,
(
struct
ltchars
*
)
arg
);
case
TIOCSLTC
:
return
set_ltchars
(
real_tty
,
(
struct
ltchars
*
)
arg
);
#endif
case
TCGETS
:
retval
=
verify_area
(
VERIFY_WRITE
,
(
void
*
)
arg
,
sizeof
(
struct
termios
));
...
...
drivers/net/README.arcnet
View file @
bb9c5bf1
---------------------------------------------------------------------------
---------------------------------------------------------------------------
-
NOTE: See also README.arcnet-jumpers in this directory for jumper-setting
information if you're like m
ost
of us and didn't happen to get a manual with
information if you're like m
any
of us and didn't happen to get a manual with
your ARCnet card.
---------------------------------------------------------------------------
---------------------------------------------------------------------------
-
Since no one seems to listen to me otherwise, perhaps a poem will get your
attention:
This is
scary
software
This is
alpha
software
If it works I DO CARE.
Hmm, I think I'm allowed to call that a poem, even though it's only two
...
...
@@ -30,63 +30,67 @@ Anyway, enough complaining. Let's get started:
These are the ARCnet drivers for Linux.
This is the first non-ALPHA release, so please be careful, and send all
possible success/failure reports to me. If I don't know when/if/how it
works, I won't be able to answer people's questions. Do we want that? Of
course not.
We're now back to more ALPHA releases after the 1.01 release which made it
into Linux 1.2.2, so please be careful, and send all possible
success/failure reports to me. If I don't know when/if/how it works, I
won't be able to answer people's questions. Do we want that? Of course
not.
Once again: DO send me success reports! I want to know if this is working!
(You know, it might be argued that I'm pushing this point a little too much.
If you think so, why not flame me in a quick little email? Please also
If you think so, why not flame me in a quick little e
-
mail? Please also
include the type of card(s) you're using, software, size of network, and
whether it's working or not.)
My e-mail address is:
apenwarr@
tourism.807-city.on.ca
apenwarr@
foxnet.net
Where do I discuss these drivers?
---------------------------------
As of the 0.22 release, we have a mailing list specifically for discussion
of the ARCnet drivers for Linux, and anything you might want to interface
them with (ie. DOS). I'll also post new versions of the Linux-ARCnet
distribution to the list in
tar-gzip-uuencode format.
There is a mailing list specifically for discussion of the ARCnet drivers
for Linux, and anything you might want to interface them with (ie. DOS).
I'll also post new versions of the Linux-ARCnet distribution to the list in
tar-gzip-uuencode format.
To subscribe to the list, send a message to listserv@
tourism.
807-city.on.ca
To subscribe to the list, send a message to listserv@807-city.on.ca
with the following line in the BODY (not the SUBJECT) of your message:
subscribe linux-arcnet YOUR REAL NAME
Remember to remove your signature, or you'll get an error back.
Send all bug (or success) reports to me or to the list.
You're free to use the comp.os.linux.development newsgroup too, but I can't
guarantee I'll see it there. (Hopefully, if my news server stays sane, I
will.)
The people on linux-net@vger.rutgers.edu have also been known to be very
helpful! :)
Other Drivers and Info
----------------------
Also, SMC (one of the companies that makes ARCnet cards) has a WorldWideWeb
site you might be interested in, which includes several drivers for various
cards including ARCnet. Try:
http://www.smc.com/
Performance Technologies makes various network software that supports
ARCnet.
http://www.perftech.com/ or ftp to ftp.perftech.com.
Novell makes a networking stack for DOS which includes ARCnet drivers. Try
ftp'ing to ftp.novell.com.
You can get the Crynwr packet driver collection (including arcether.com, the
one you'll want for arcnet cards) from oak.oakland.edu:/
pub/msdos/pktdrvr.
one you'll want for arcnet cards) from oak.oakland.edu:/
simtel/msdos/pktdrvr.
It won't work perfectly on a 386+ without patches, though, and also doesn't
like several cards. Mail me if you want a fixed version.
Last warning: This driver may be extremely dangerous, crash your computer,
or kill your dog! (although I'm pretty sure that I've worked that one
out...)
like several cards. Mail me if you want a fixed version. (Ahem: I may or
may not have a 100% fixed version by the time I get your mail!)
Loadable Module Support
-----------------------
This is a
new feature as of
0.42 ALPHA.
This is a
available starting with
0.42 ALPHA.
Configure and rebuild Linux. When asked, say NO to "arcnet support" if you
want loadable module support.
...
...
@@ -124,28 +128,47 @@ How do I get it to work with...?
--------------------------------
NFS: Should be fine linux->linux, just pretend you're using ethernet cards.
oak.oakland.edu:/pub/msdos/nfs has some nice DOS clients. I can't
get SOSS (dos-based server) to work, although someone has and can't
figure out why it won't work for me.
oak.oakland.edu:/simtel/msdos/nfs has some nice DOS clients. There
is also a DOS-based NFS server called SOSS. It doesn't multitask
quite the way Linux does (actually, it doesn't multitask AT ALL) but
you never know what you might need.
DOS: If you're using the freeware arcether.com, you might want to install
the source code patch. It helps with PC/TCP, and also can get
arcether to load if it timed out too quickly. Mail me if you need a
precompiled version of arcether.com. (ie. you if don't have a DOS
assembler)
Windows: See DOS :)
arcether to load if it timed out too quickly during initialization.
Mail me if you need a precompiled version of arcether.com. (ie. you
if don't have a DOS assembler)
OS2: May work okay. Please e-mail me if you find a freeware TCP/IP stack
for OS/2
.
Windows: See DOS :) Trumpet Winsock works fine with either the Novell or
Arcether client, assuming you remember to load winpkt of course
.
LAN Manager and Windows for Workgroups: These programs use protocols that
are incompatible with ARCnet for Linux. Rather than using the
internet-standard ARCnet protocol, they try to pretend the cards are
ethernet, and confuse everyone else on the network.
An upcoming release of ARCnet for Linux may have workarounds for
this stupid behaviour.
are incompatible with the internet standard. They try to pretend
the cards are ethernet, and confuse everyone else on the network.
However, v1.90 ALPHA and later of the Linux ARCnet driver support
this protocol via the 'arc0w' device. After setting up arc0 as
usual, ifconfig and set up routes to your WfWg-protocol hosts
through arc0w.
Using the freeware Samba server and clients for Linux, you can now
interface quite nicely with TCP/IP-based WfWg or Lan Manager
networks. In addition, the Linux host can be used as a router
between the standard and WfWg protocols, so hosts that could
previously never talk to each other should now be able to.
This feature is still in early testing, so please e-mail with any
comments/questions you might have.
OS2: Has not been tested. The "correct" solution would be to buy either of
IBM's "TCP/IP for OS/2" or "Warp Connect" packages. However,
ftp.microsoft.com also has a freeware Lan Manager for OS/2 client
which should use the same protocol as WfWg does. This has not been
tested, however. Please mail me with any results.
NetBSD/AmiTCP: These use an old version of the Internet standard ARCnet
protocol which is incompatible with the Linux driver at present.
Work to support these is underway and should be available in a
standard release soon.
It works: what now?
...
...
@@ -154,11 +177,12 @@ It works: what now?
Send mail describing your setup, preferably including driver version, kernel
version, ARCnet card model, CPU type, number of systems on your network, and
list of software in use to me at the following address:
apenwarr@
tourism.807-city.on.ca
apenwarr@
foxnet.net
I do send (sometimes automated) replies to all messages I receive. My mail
host is quite weird, so if you don't get a reply within a reasonable time,
please resend.
I do send (sometimes automated) replies to all messages I receive. My email
can be weird (and also usually gets forwarded all over the place along the
way to me), so if you don't get a reply within a reasonable time, please
resend.
It doesn't work: what now?
...
...
@@ -171,31 +195,36 @@ with "arcnet:" and has shown up since the last reboot) in your mail.
If you want to try fixing it yourself (I highly recommend that you mail me
about the problem first, since it might already have been solved) you may
want to try some of the debug levels available. For heavy testing on
D
EBUG
_DURING or more, it would be a REALLY good idea to kill your klogd
daemon first! D
EBUG
_DURING displays 4-5 lines for each packet sent or
received. D
EBUG
_TX and RX actually DISPLAY each packet as it is sent or
D_DURING or more, it would be a REALLY good idea to kill your klogd
daemon first! D_DURING displays 4-5 lines for each packet sent or
received. D_TX and RX actually DISPLAY each packet as it is sent or
received, which is obviously quite big.
You can run the arcdump shell script (available from me
) as root to list the
contents of the arcnet buffers at any time. To make any sense at all out of
this, you should grab the pertinent RFC's. (some are listed near the top of
arcnet.c). arcdump assumes your card is at 0xD0000. If it isn't, edit the
script.
You can run the arcdump shell script (available from me
or in the full
ARCnet package if you got it) as root to list the contents of the arcnet
buffers at any time. To make any sense at all out of this, you should grab
the pertinent RFC's. (some are listed near the top of arcnet.c). arcdump
assumes your card is at 0xD0000. If it isn't, edit the
script.
Buffers #0 and 1 are used for receiving, and Buffers #2 and 3 are for
sending. Ping-pong buffers are implemented both ways
, just to confuse you
.
sending. Ping-pong buffers are implemented both ways.
If your debug level i
s DEBUG_DURING or more, the buffers are cleared to a
constant value of 0x42 every time the card is reset (which should only
happen when you do an ifconfig up, or when Linux decides that the driver is
broken). This is to make it easier to figure out which bytes are being used
by a
packet.
If your debug level i
ncludes D_DURING, the buffers are cleared to a constant
value of 0x42 every time the card is reset (which should only happen when
you do an ifconfig up, or when Linux decides that the driver is broken).
This is to make it easier to figure out which bytes are being used by a
packet.
You can change the debug level without recompiling the kernel by typing:
ifconfig arc0 down metric 1x
ifconfig arc0 down metric 1x
xx
/etc/rc.d/rc.inet1
where "x" is the debug level you want. For example, "metric 14" would put
you at debug level 4. Debug level 3 is the default (D_EXTRA).
where "xxx" is the debug level you want. For example, "metric 1015" would put
you at debug level 15. Debug level 7 is currently the default.
Note that the debug level is (as of v1.90 ALPHA) a binary combination of
different debug flags; so debug level 7 is really 1+2+4 or
D_NORMAL+D_INIT+D_EXTRA. To reach D_DURING, you would add 8 to this,
resulting in debug level 15.
I want to send money: what now?
...
...
drivers/net/README.arcnet-jumpers
View file @
bb9c5bf1
...
...
@@ -6,7 +6,7 @@ driver configuration help.
Because so many people (myself included) seem to have obtained ARCnet cards
without manuals, this will be a quick listing of all jumper settings I can
find. Please e-mail apenwarr@
tourism.807-city.on.ca
with any settings for
find. Please e-mail apenwarr@
foxnet.net
with any settings for
your particular card.
Even if your ARCnet model isn't listed, but has the same jumpers, please
...
...
@@ -15,7 +15,7 @@ e-mail me to say so.
If your model isn't listed, and has different settings, PLEASE PLEASE tell
me. I had to figure mine out without the manual, and it WASN'T FUN!
Cards Listed in this file:
Cards Listed in this file
(in this order, mostly)
:
Manufacturer Model # Bits
------------ ------- ----
...
...
@@ -28,10 +28,14 @@ Cards Listed in this file:
SMC PC500Longboard 16
SMC PC550Longboard 16
SMC PC600 16
SMC? LCS-8830-T 16?
Puredata PDI507 16
CNet Tech CN120-Series 8
CNet Tech CN160-Series 16
No Name -- 8/16
No Name Taiwan R.O.C(?) 8
Tiara Tiara Lancard(?)
** SMC = Standard Microsystems Corp.
** CNet Tech = CNet Technology, Inc.
...
...
@@ -46,7 +50,7 @@ Unclassified Stuff
- And some unknowns (other info is welcome!):
From: root@ultraworld.xs4all.nl (Timo Hilbrink)
To: apenwarr@
tourism.807-city.on.ca
(Avery Pennarun)
To: apenwarr@
foxnet.net
(Avery Pennarun)
Date: Wed, 26 Oct 1994 02:10:32 +0000 (GMT)
Reply-To: timoh@xs4all.nl
...
...
@@ -55,7 +59,7 @@ Unclassified Stuff
About the jumpers: On my PC130 there is one more jumper, located near the
cable-connector and it's for changing to star or bus topology;
closed: star - open: bus
On the PC500 are some more jumper-pins, one block lab
e
led with RX,PDN,TXI
On the PC500 are some more jumper-pins, one block labled with RX,PDN,TXI
and another with ALE,LA17,LA18,LA19 these are undocumented..
[...more parts deleted...]
...
...
@@ -67,16 +71,17 @@ Quick Briefing:
---------------
All ARCnet cards should have a total of four different settings:
- the I/O address: this is the "port" your ARCnet card is on. Probed
values, as of v0.14, are only from 0x200 through 0x3F0. (If your card
has additional ones, which is possible, please tell me.) This should not
be the same as any other device on your system.
Supposedly MS Windows
prefers values of 0x300 or more, eating net connections on my system
otherwise.
be the same as any other device on your system.
According to a doc I
got from Novell, MS Windows prefers values of 0x300 or more, eating
netconnections on my system
otherwise.
- Avery's favourite: 0x300.
- the IRQ: on 8-bit cards, it might be 2 (9), 3, 4, 5, or 7.
on 16-bit cards, it might be 2 (9), 3, 4, 5, 7, or
9
-15. Make
on 16-bit cards, it might be 2 (9), 3, 4, 5, 7, or
10
-15. Make
sure this is different from any other card on your system. Note that
IRQ2 is the same as IRQ9, as far as Linux is concerned.
- Avery's favourite: IRQ2.
...
...
@@ -108,12 +113,18 @@ All ARCnet cards should have a total of four different settings:
PC100, PC110, PC120, PC130 (8-bit cards)
PC500, PC600 (16-bit cards)
---------------------------------
- mainly from Avery Pennarun <apenwarr@
tourism.807-city.on.ca>
- values depicted are
from Avery's setup.
- mainly from Avery Pennarun <apenwarr@
foxnet.net>. Values depicted are
from Avery's setup.
- special thanks to Timo Hilbrink <timoh@xs4all.nl> for noting that PC120,
130, 500, and 600 all have the same switches as Avery's PC100.
PC500/600 have several extra, undocumented pins though. (?)
- PC110 settings were verified by Stephen A. Wood <saw@cebaf.gov>
- On the other hand, John Edward Bauer <jbauer@badlands.NoDak.edu> said
the PC110 settings are all wrong. In his case, you need to switch all
the 1's with 0's. If you're having problems, try that.
- Also, the JP- and S-numbers probably don't match your card exactly. Try
to find jumpers/switches with the same number of settings - it's
probably more reliable.
JP5 [|] : : : :
...
...
@@ -184,6 +195,7 @@ PC500, PC600 (16-bit cards)
DO NOT SET THIS TO 0 OR 255 (0xFF)!
*****************************************************************************
** Standard Microsystems Corp (SMC) **
...
...
@@ -270,7 +282,7 @@ Setting the Node ID
The eight switches in group S2 are used to set the node ID.
Each node attached to the network must have an unique node ID which
must be diff
e
rent from 0.
must be diffrent from 0.
Switch 1 serves as the least significant bit (LSB).
The node ID is the sum of the values of all switches set to "1"
...
...
@@ -309,7 +321,7 @@ Setting the I/O Base Address
----------------------------
The first three switches in switch group S1 are used to select one
of eight possible I/O Base addresses using the followi
n
g table
of eight possible I/O Base addresses using the followig table
Switch | Hex I/O
...
...
@@ -317,7 +329,7 @@ of eight possible I/O Base addresses using the following table
-------|--------
0 0 0 | 260
0 0 1 | 290
0 1 0 | 2E0 (Manufact
ure
r's default)
0 1 0 | 2E0 (Manufact
o
r's default)
0 1 1 | 2F0
1 0 0 | 300
1 0 1 | 350
...
...
@@ -352,7 +364,7 @@ positions, determined by the offset, switches 7 and 8 of group S1.
0 1 0 1 0 | CD000 | CE000
0 1 0 1 1 | CD800 | CE000
| |
0 1 1 0 0 | D0000 | D2000 (Manufact
ure
r's default)
0 1 1 0 0 | D0000 | D2000 (Manufact
o
r's default)
0 1 1 0 1 | D0800 | D2000
0 1 1 1 0 | D1000 | D2000
0 1 1 1 1 | D1800 | D2000
...
...
@@ -389,7 +401,7 @@ parameters. These two jumpers are normally left open.
Refer to the COM9026 Data Sheet for alternate configurations.
To select a hardware interrupt level set one (only one!) of the jumpers
IRQ2, IRQ3, IRQ4, IRQ5, IRQ7. The
manufacture
r's default is IRQ2.
IRQ2, IRQ3, IRQ4, IRQ5, IRQ7. The
Manufacto
r's default is IRQ2.
Configuring the PC130E for Star or Bus Topology
...
...
@@ -412,7 +424,7 @@ board activity:
-------|------------------- ---------|-------------------
on | normal activity flash/on | data transfer
blink | reconfiguration off | no data transfer;
off | defectiv
e board or | incor
rect memory or
off | defectiv
board or | inco
rect memory or
| node ID is zero | I/O address
...
...
@@ -506,7 +518,7 @@ Setting the Node ID
The eight switches in group SW3 are used to set the node ID. Each node
attached to the network must have an unique node ID which must be
diff
e
rent from 0.
diffrent from 0.
Switch 1 serves as the least significant bit (LSB).
The node ID is the sum of the values of all switches set to "1"
...
...
@@ -546,7 +558,7 @@ Setting the I/O Base Address
----------------------------
The first six switches in switch group SW1 are used to select one
of 32 possible I/O Base addresses using the followi
n
g table
of 32 possible I/O Base addresses using the followig table
Switch | Hex I/O
6 5 4 3 2 1 | Address
...
...
@@ -565,7 +577,7 @@ of 32 possible I/O Base addresses using the following table
0 1 1 0 1 1 | 2B0
0 1 1 1 0 0 | 2C0
0 1 1 1 0 1 | 2D0
0 1 1 1 1 0 | 2E0 (Manufact
ure
r's default)
0 1 1 1 1 0 | 2E0 (Manufact
o
r's default)
0 1 1 1 1 1 | 2F0
1 1 0 0 0 0 | 300
1 1 0 0 0 1 | 310
...
...
@@ -634,10 +646,119 @@ board activity:
-------|------------------- ---------|-------------------
on | normal activity flash/on | data transfer
blink | reconfiguration off | no data transfer;
off | defectiv
e board or | incor
rect memory or
off | defectiv
board or | inco
rect memory or
| node ID is zero | I/O address
*****************************************************************************
** Possibly SMC **
LCS-8830-T (16-bit card)
------------------------
- from Mathias Katzer <mkatzer@HRZ.Uni-Bielefeld.DE>
This is a LCS-8830-T made by SMC, I think ('SMC' only appears on one PLCC,
nowhere else, not even on the few xeroxed sheets from the manual).
SMC Arcnet Board Type LCS-8830-T
------------------------------------
| |
| JP3 88 8 JP2 |
| ##### | \ |
| ##### ET1 ET2 ###|
| 8 ###|
| U3 SW 1 JP0 ###| Phone Jacks
| -- ###|
| | | |
| | | SW2 |
| | | |
| | | ##### |
| -- ##### #### BNC Connector
| ####
| 888888 JP1 |
| 234567 |
-- -------
|||||||||||||||||||||||||||
--------------------------
SW1: DIP-Switches for Station Address
SW2: DIP-Switches for Memory Base and I/O Base addresses
JP0: If closed, internal termination on (default open)
JP1: IRQ Jumpers
JP2: Boot-ROM enabled if closed
JP3: Jumpers for respsonse timeout
U3: Boot-ROM Socket
ET1 ET2 Response Time Idle Time Reconfiguration Time
78 86 840
X 285 316 1680
X 563 624 1680
X X 1130 1237 1680
(X means closed jumper)
(DIP-Switch downwards means "0")
The station address is binary-coded with SW1.
The I/O base address is coded with DIP-Switches 6,7 and 8 of SW2:
Switches Base
678 Address
000 260-26f
100 290-29f
010 2e0-2ef
110 2f0-2ff
001 300-30f
101 350-35f
011 380-38f
111 3e0-3ef
DIP Switches 1-5 of SW2 encode the RAM and ROM Adress Range:
Switches Ram Rom
12345 Adress Range Address Range
00000 C:0000-C:07ff C:2000-C:3fff
10000 C:0800-C:0fff
01000 C:1000-C:17ff
11000 C:1800-C:1fff
00100 C:4000-C:47ff C:6000-C:7fff
10100 C:4800-C:4fff
01100 C:5000-C:57ff
11100 C:5800-C:5fff
00010 C:C000-C:C7ff C:E000-C:ffff
10010 C:C800-C:Cfff
01010 C:D000-C:D7ff
11010 C:D800-C:Dfff
00110 D:0000-D:07ff D:2000-D:3fff
10110 D:0800-D:0fff
01110 D:1000-D:17ff
11110 D:1800-D:1fff
00001 D:4000-D:47ff D:6000-D:7fff
10001 D:4800-D:4fff
01001 D:5000-D:57ff
11001 D:5800-D:5fff
00101 D:8000-D:87ff D:A000-D:bfff
10101 D:8800-D:8fff
01101 D:9000-D:97ff
11101 D:9800-D:9fff
00011 D:C000-D:c7ff D:E000-D:ffff
10011 D:C800-D:cfff
01011 D:D000-D:d7ff
11011 D:D800-D:dfff
00111 E:0000-E:07ff E:2000-E:3fff
10111 E:0800-E:0fff
01111 E:1000-E:17ff
11111 E:1800-E:1fff
*****************************************************************************
** PureData Corp **
...
...
@@ -690,7 +811,7 @@ further information is welcome.]
DIP Switches:
The dip
switches accessible on the accessible end of the card while
The dipswitches accessible on the accessible end of the card while
it is installed, is used to set the arcnet address. There are 8
switches. Use an address from 1 to 254.
...
...
@@ -781,6 +902,7 @@ DIP Switches:
------------------------
- from Juergen Seifert <seifert@htwm.de>
CNET TECHNOLOGY INC. (CNet) ARCNET 120A SERIES
==============================================
...
...
@@ -856,7 +978,7 @@ Setting the Node ID
-------------------
The eight switches in SW2 are used to set the node ID. Each node attached
to the network must have an unique node ID which must be diff
e
rent from 0.
to the network must have an unique node ID which must be diffrent from 0.
Switch 1 (ID0) serves as the least significant bit (LSB).
The node ID is the sum of the values of all switches set to "1"
...
...
@@ -896,7 +1018,7 @@ Setting the I/O Base Address
----------------------------
The last three switches in switch block SW1 are used to select one
of eight possible I/O Base addresses using the followi
n
g table
of eight possible I/O Base addresses using the followig table
Switch | Hex I/O
...
...
@@ -904,7 +1026,7 @@ of eight possible I/O Base addresses using the following table
------------|--------
ON ON ON | 260
OFF ON ON | 290
ON OFF ON | 2E0 (Manufact
ure
r's default)
ON OFF ON | 2E0 (Manufact
o
r's default)
OFF OFF ON | 2F0
ON ON OFF | 300
OFF ON OFF | 350
...
...
@@ -926,7 +1048,7 @@ Switches 1-5 of switch block SW1 select the Memory Base address.
ON ON ON ON ON | C0000 | C2000
ON ON OFF ON ON | C4000 | C6000
ON ON ON OFF ON | CC000 | CE000
ON ON OFF OFF ON | D0000 | D2000 (Manufact
ure
r's default)
ON ON OFF OFF ON | D0000 | D2000 (Manufact
o
r's default)
ON ON ON ON OFF | D4000 | D6000
ON ON OFF ON OFF | D8000 | DA000
ON ON ON OFF OFF | DC000 | DE000
...
...
@@ -937,7 +1059,7 @@ Switches 1-5 of switch block SW1 select the Memory Base address.
Note: Since the switches 1 and 2 are always set to ON it may be possible
that they can be used to add an offset of 2K, 4K or 6K to the base
address, but this feature is not documented in the manual and I
haven't teste
d
it yet.
haven't teste
t
it yet.
Setting the Interrupt Line
...
...
@@ -1066,7 +1188,7 @@ Setting the Node ID
-------------------
The eight switches in SW2 are used to set the node ID. Each node attached
to the network must have an unique node ID which must be diff
e
rent from 0.
to the network must have an unique node ID which must be diffrent from 0.
Switch 1 (ID0) serves as the least significant bit (LSB).
The node ID is the sum of the values of all switches set to "1"
...
...
@@ -1106,14 +1228,14 @@ Setting the I/O Base Address
----------------------------
The first six switches in switch block SW1 are used to select the I/O Base
address using the followi
n
g table:
address using the followig table:
Switch | Hex I/O
1 2 3 4 5 6 | Address
------------------------|--------
OFF ON ON OFF OFF ON | 260
OFF ON OFF ON ON OFF | 290
OFF ON OFF OFF OFF ON | 2E0 (Manufact
ure
r's default)
OFF ON OFF OFF OFF ON | 2E0 (Manufact
o
r's default)
OFF ON OFF OFF OFF OFF | 2F0
OFF OFF ON ON ON ON | 300
OFF OFF ON OFF ON OFF | 350
...
...
@@ -1162,9 +1284,9 @@ JP3 through JP13 using the following table:
13 | 2 (=9) Default!
Note: - Do not use JP11=IRQ6, it may conflict with your Floppy Disk
Control
l
er
Controler
- Use JP3=IRQ14 only, if you don't have an IDE-, MFM-, or RLL-
Hard Disk, it may conflict with their control
l
ers
Hard Disk, it may conflict with their controlers
Setting the Timeout Parameters
...
...
@@ -1185,8 +1307,8 @@ NONAME 8-BIT ARCNET
===================
I have named this ARCnet card "NONAME", since there is no name of any
manufact
ure
r on the Installation manual nor on the shipping box. The only
hint to the existence of a manufact
urer at all is written into co
pper,
manufact
o
r on the Installation manual nor on the shipping box. The only
hint to the existence of a manufact
or at all is written into cu
pper,
it is "Made in Taiwan"
This description has been written by Juergen Seifert <seifert@htwm.de>
...
...
@@ -1230,7 +1352,7 @@ ET1, ET2 Extended Timeout Select
ROM ROM Enable Select
CN RG62 Coax Connector
STAR| BUS | T/P Three fields for placing a sign (colored circle)
indicating the topolog
y
of the card
indicating the topolog
ie
of the card
Setting one of the switches to Off means "1", On means "0".
...
...
@@ -1240,7 +1362,7 @@ Setting the Node ID
The eight switches in group SW1 are used to set the node ID.
Each node attached to the network must have an unique node ID which
must be diff
e
rent from 0.
must be diffrent from 0.
Switch 8 serves as the least significant bit (LSB).
The node ID is the sum of the values of all switches set to "1"
...
...
@@ -1280,14 +1402,14 @@ Setting the I/O Base Address
----------------------------
The first three switches in switch group SW2 are used to select one
of eight possible I/O Base addresses using the followi
n
g table
of eight possible I/O Base addresses using the followig table
Switch | Hex I/O
1 2 3 | Address
------------|--------
ON ON ON | 260
ON ON OFF | 290
ON OFF ON | 2E0 (Manufact
ure
r's default)
ON OFF ON | 2E0 (Manufact
o
r's default)
ON OFF OFF | 2F0
OFF ON ON | 300
OFF ON OFF | 350
...
...
@@ -1322,7 +1444,7 @@ positions, determined by the offset, switches 7 and 8 of group SW2.
0 1 0 1 0 | CD000 | CE000
0 1 0 1 1 | CD800 | CE000
| |
0 1 1 0 0 | D0000 | D2000 (Manufact
ure
r's default)
0 1 1 0 0 | D0000 | D2000 (Manufact
o
r's default)
0 1 1 0 1 | D0800 | D2000
0 1 1 1 0 | D1000 | D2000
0 1 1 1 1 | D1800 | D2000
...
...
@@ -1355,14 +1477,14 @@ Setting Interrupt Request Lines (IRQ)
-------------------------------------
To select a hardware interrupt level set one (only one!) of the jumpers
IRQ2, IRQ3, IRQ4, IRQ5 or IRQ7. The
manufacture
r's default is IRQ2.
IRQ2, IRQ3, IRQ4, IRQ5 or IRQ7. The
Manufacto
r's default is IRQ2.
Setting the Timeouts
--------------------
The two jumpers labeled ET1 and ET2 are used to determine the timeout
parameters (respons
e
and reconfiguration time). Every node in a network
parameters (respons and reconfiguration time). Every node in a network
must be set to the same timeout values.
ET1 ET2 | Response Time (us) | Reconfiguration Time (ms)
...
...
@@ -1382,7 +1504,7 @@ The manual of my 8-Bit NONAME ARCnet Card contains another description
of a 16-Bit Coax / Twisted Pair Card. This description is incomplete,
because there are missing two pages in the manual booklet. (The table
of contents reports pages ... 2-9, 2-11, 2-12, 3-1, ... but inside
the booklet there is a diff
e
rent way of counting ... 2-9, 2-10, A-1,
the booklet there is a diffrent way of counting ... 2-9, 2-10, A-1,
(empty page), 3-1, ..., 3-18, A-1 (again), A-2)
Also the picture of the board layout is not as good as the picture of
8-Bit card, because there isn't any letter like "SW1" written to the
...
...
@@ -1429,7 +1551,7 @@ Setting the Node ID
The eight switches in group SW2 are used to set the node ID.
Each node attached to the network must have an unique node ID which
must be diff
e
rent from 0.
must be diffrent from 0.
Switch 8 serves as the least significant bit (LSB).
The node ID is the sum of the values of all switches set to "1"
...
...
@@ -1469,14 +1591,14 @@ Setting the I/O Base Address
----------------------------
The first three switches in switch group SW1 are used to select one
of eight possible I/O Base addresses using the followi
n
g table
of eight possible I/O Base addresses using the followig table
Switch | Hex I/O
3 2 1 | Address
------------|--------
ON ON ON | 260
ON ON OFF | 290
ON OFF ON | 2E0 (Manufact
ure
r's default)
ON OFF ON | 2E0 (Manufact
o
r's default)
ON OFF OFF | 2F0
OFF ON ON | 300
OFF ON OFF | 350
...
...
@@ -1511,7 +1633,7 @@ positions, determined by the offset, switches 4 and 5 of group SW1.
0 1 0 1 0 | CD000 | CE000
0 1 0 1 1 | CD800 | CE000
| |
0 1 1 0 0 | D0000 | D2000 (Manufact
ure
r's default)
0 1 1 0 0 | D0000 | D2000 (Manufact
o
r's default)
0 1 1 0 1 | D0800 | D2000
0 1 1 1 0 | D1000 | D2000
0 1 1 1 1 | D1800 | D2000
...
...
@@ -1551,11 +1673,239 @@ Setting the Timeouts
*****************************************************************************
** No Name **
8-bit cards ("Made in Taiwan R.O.C.")
-----------
- from Vojtech Pavlik <vpav4328@diana.troja.mff.cuni.cz>
I have named this ARCnet card "NONAME", since I got only the card with
no manual at all and the only text identifying the manufacturer is
"MADE IN TAIWAN R.O.C" printed on the card.
This description was written by Vojtech Pavlik
(vpav4328@diana.troja.mff.cuni.cz) using parts of the ARCNET-jumpers
README file from Linux kernel 1.2.2.
____________________________________________________________
| 1 2 3 4 5 6 7 8 |
| |o|o| JP1 o|o|o|o|o|o|o|o| ON |
| + o|o|o|o|o|o|o|o| ___|
| _____________ o|o|o|o|o|o|o|o| OFF _____ | | ID7
| | | SW1 | | | | ID6
| > RAM (2k) | ____________________ | H | | S | ID5
| |_____________| | || y | | W | ID4
| | || b | | 2 | ID3
| | || r | | | ID2
| | || i | | | ID1
| | 90C65 || d | |___| ID0
| SW3 | || | |
| |o|o|o|o|o|o|o|o| ON | || I | |
| |o|o|o|o|o|o|o|o| | || C | |
| |o|o|o|o|o|o|o|o| OFF |____________________|| | _____|
| 1 2 3 4 5 6 7 8 | | | |___
| ______________ | | | BNC |___|
| | | |_____| |_____|
| > EPROM SOCKET | |
| |______________| |
| ______________|
| |
|_____________________________________________|
Legend:
90C65 ARCNET Chip
SW1 1-5: Base Memory Address Select
6-8: Base I/O Address Select
SW2 1-8: Node ID Select (ID0-ID7)
SW3 1-5: IRQ Select
6-7: Extra Timeout
8 : Rom Enable
JP1 Led connector
BNC Coax connector
Although the jumpers SW1 and SW3 are marked SW, not JP, they are jumpers, not
switches.
Setting the jumpers to ON means connecting the upper two pins, off the bottom
two - or - in case of IRQ setting, connecting none of them at all.
Setting the Node ID
-------------------
The eight switches in SW2 are used to set the node ID. Each node attached
to the network must have an unique node ID which must be diffrent from 0.
Switch 1 (ID0) serves as the least significant bit (LSB).
Setting one of the switches to Off means "1", On means "0".
The node ID is the sum of the values of all switches set to "1"
These values are:
Switch | Label | Value
-------|-------|-------
1 | ID0 | 1
2 | ID1 | 2
3 | ID2 | 4
4 | ID3 | 8
5 | ID4 | 16
6 | ID5 | 32
7 | ID6 | 64
8 | ID7 | 128
Some Examples:
Switch | Hex | Decimal
8 7 6 5 4 3 2 1 | Node ID | Node ID
----------------|---------|---------
0 0 0 0 0 0 0 0 | not allowed
0 0 0 0 0 0 0 1 | 1 | 1
0 0 0 0 0 0 1 0 | 2 | 2
0 0 0 0 0 0 1 1 | 3 | 3
. . . | |
0 1 0 1 0 1 0 1 | 55 | 85
. . . | |
1 0 1 0 1 0 1 0 | AA | 170
. . . | |
1 1 1 1 1 1 0 1 | FD | 253
1 1 1 1 1 1 1 0 | FE | 254
1 1 1 1 1 1 1 1 | FF | 255
Setting the I/O Base Address
----------------------------
The last three switches in switch block SW1 are used to select one
of eight possible I/O Base addresses using the followig table
Switch | Hex I/O
6 7 8 | Address
------------|--------
ON ON ON | 260
OFF ON ON | 290
ON OFF ON | 2E0 (Manufactor's default)
OFF OFF ON | 2F0
ON ON OFF | 300
OFF ON OFF | 350
ON OFF OFF | 380
OFF OFF OFF | 3E0
Setting the Base Memory (RAM) buffer Address
--------------------------------------------
The memory buffer (RAM) requires 2K. The base of this buffer can be
located in any of eight positions. The address of the Boot Prom is
memory base + 0x2000.
Jumpers 3-5 of jumper block SW1 select the Memory Base address.
Switch | Hex RAM | Hex ROM
1 2 3 4 5 | Address | Address *)
--------------------|---------|-----------
ON ON ON ON ON | C0000 | C2000
ON ON OFF ON ON | C4000 | C6000
ON ON ON OFF ON | CC000 | CE000
ON ON OFF OFF ON | D0000 | D2000 (Manufactor's default)
ON ON ON ON OFF | D4000 | D6000
ON ON OFF ON OFF | D8000 | DA000
ON ON ON OFF OFF | DC000 | DE000
ON ON OFF OFF OFF | E0000 | E2000
*) To enable the Boot ROM set the jumper 8 of jumper block SW3 to position ON.
The jumpers 1 and 2 probably add 0x0800, 0x1000 and 0x1800 to RAM addres.
Setting the Interrupt Line
--------------------------
Jumpers 1-5 of the jumper block SW3 controll the IRQ level.
Jumper | IRQ
1 2 3 4 5 |
----------------------------
ON OFF OFF OFF OFF | 2
OFF ON OFF OFF OFF | 3
OFF OFF ON OFF OFF | 4
OFF OFF OFF ON OFF | 5
OFF OFF OFF OFF ON | 7
Setting the Timeout Parameters
------------------------------
The jumpers 6-7 of the jumper block SW3 are used to determine the timeout
parameters. These two jumpers are normally left in the OFF position.
*****************************************************************************
** Tiara **
(model unknown)
-------------------------
- from Christoph Lameter <clameter@netcom.com>
Here is information about my card as far as I could figure it out:
----------------------------------------------- tiara
Tiara LanCard of Tiara Computer Systems.
+----------------------------------------------+
! ! Transmitter Unit ! !
! +------------------+ -------
! MEM Coax Connector
! ROM 7654321 <- I/O -------
! : : +--------+ !
! : : ! 90C66LJ! +++
! : : ! ! !D Switch to set
! : : ! ! !I the Nodenumber
! : : +--------+ !P
! !++
! 234567 <- IRQ !
+------------!!!!!!!!!!!!!!!!!!!!!!!!--------+
!!!!!!!!!!!!!!!!!!!!!!!!
0 = Jumper Installed
1 = Open
Top Jumper line Bit 7 = Rom Enable 654=Memory location 321=I/O
Settings for Memory Location (Top Jumper Line)
456 Address selected
000 C0000
001 C4000
010 CC000
011 D0000
100 D4000
101 D8000
110 DC000
111 E0000
Settings for I/O Address (Top Jumper Line)
123 Port
000 260
001 290
010 2E0
011 2F0
100 300
101 350
110 380
111 3E0
Settings for IRQ Selection (Lower Jumper Line)
234567
011111 IRQ 2
101111 IRQ 3
110111 IRQ 4
111011 IRQ 5
111110 IRQ 7
*****************************************************************************
Other Cards
-----------
I have no information on other models of ARCnet cards at the moment. Please
send any and all info to:
apenwarr@
tourism.807-city.on.ca
apenwarr@
foxnet.net
Thanks.
drivers/net/arcnet.c
View file @
bb9c5bf1
...
...
@@ -7,6 +7,8 @@
**********************
The original copyright was as follows:
skeleton.c Written 1993 by Donald Becker.
Copyright 1993 United States Government as represented by the
Director, National Security Agency. This software may only be used
...
...
@@ -15,101 +17,143 @@
**********************
v1.02 (95/06/21)
- A fix to make "exception" packets sent from Linux receivable
on other systems. (The protocol_id byte was sometimes being set
incorrectly, and Linux wasn't checking it on receive so it
didn't show up)
- Updated my email address. Please use apenwarr@foxnet.net
from now on.
v1.92 ALPHA (95/07/11)
- Fixes to make things work with kernel 1.3.x. Completely broke
1.2.x support. Oops? 1.2.x users keep using 1.91 ALPHA until I
get out a version that supports both.
v1.91 ALPHA (95/07/02)
- Oops. Exception packets hit us again! I remembered to test
them in Windows-protocol mode, but due to the many various
changes they broke in RFC1201 instead. All fixed.
- A long-standing bug with "exception" packets not setting
protocol_id properly has been corrected. This would have caused
random problems talking to non-Linux servers. I've also sent in
a patch to fix this in the latest stable ARCnet (now 1.02).
- ARC_P_IPX is an RFC1201 protocol too. Thanks, Tomasz.
- We're now "properly" (I think) handling the multiple 'tbusy' and
'start' flags (one for each protocol device) better.
- The driver should now start without a NULL-pointer dereference
if you aren't connected to the network.
v1.90 ALPHA (95/06/18)
- Removal of some outdated and messy config options (no one has
ever complained about the defaults since they were introduced):
DANGER_PROBE, EXTRA_DELAYS, IRQ_XMIT, CAREFUL_XMIT,
STRICT_MEM_DETECT, LIMIT_MTU, USE_TIMER_HANDLER. Also took out
a few "#if 0" sections which are no longer useful.
- Cleaned up debug levels - now instead of levels, there are
individual flags. Watch out when changing with ifconfig.
- More cleanups and beautification. Removed more dead code and
made sure every function was commented.
- Fixed the DETECT_RECONFIGS option so that it actually _won't_
detect reconfigs. Previously, the RECON irq would be disabled
but the recon messages would still be logged on the next normal
IRQ.
- Initial support for "multiprotocol" ARCnet (this involved a LOT
of reorganizing!). Added an arc0w device, which allows us to
talk to "Windows" ARCnet TCP/IP protocol. To use it, ifconfig
arc0 and arc0w (in that order). For now, Windows-protocol
hosts should have routes through arc0w - eventually I hope to
make things more automatic.
v1.11 ALPHA (95/06/07)
- Tomasz saves the day again with patches to fix operation if the
new VERIFY_ACK option is disabled.
- LOTS of little code cleanups/improvements by Tomasz.
- Changed autoprobe, since the "never-changing command port"
probe was causing problems for some people. I also reset the
card fewer times during the probe if DANGER_PROBE is defined,
since DANGER_PROBE seems to be a more reliable method anyway.
- It looks like the null-pointer problem was finally REALLY fixed
by some change from Linux 1.2.8 to 1.2.9. How handy!
v1.10 ALPHA (95/04/15)
- Fixed (?) some null-pointer dereference bugs
- Added better network error detection (from Tomasz) - in
particular, we now notice when our network isn't connected,
also known as a "network reconfiguration."
- We now increment lp->stats.tx_dropped in several more places,
on a suggestion from Tomasz.
- Minor cleanups/spelling fixes.
- We now monitor the TXACK bit in the status register: we don't do
anything with it yet, just notice when a transmitted packet isn't
acknowledged.
- Minor fix with sequence numbers (sometimes they were being sent in
the wrong order due to Linux's packet queuing).
v1.01 (95/03/24)
- Fixed some IPX-related bugs. (Thanks to Tomasz Motylewski
<motyl@tichy.ch.uj.edu.pl> for the patches to make arcnet work
with dosemu!)
v1.0 (95/02/15)
v1.0
0
(95/02/15)
- Initial non-alpha release.
TO DO:
- Test in systems with NON-ARCnet network cards, just to see if
autoprobe kills anything. With any luck, it won't. (It's pretty
careful.)
- Except some unfriendly NE2000's die. (as of 0.40-ALPHA)
- cards with shared memory that can be "turned off?"
autoprobe kills anything. Currently, we do cause some NE2000's to
die.
- What about cards with shared memory that can be "turned off?"
- NFS mount freezes after several megabytes to SOSS for DOS.
unmount/remount works. Is this arcnet-specific? I don't know.
- Add support for the various stupid bugs ("I didn't read the RFC"
syndrome) in Windows for Workgroups and LanMan.
*/
/**************************************************************************/
unmount/remount fixes it. Is this arcnet-specific? I don't know.
- Add support for "old" (RFC1051) protocol arcnet, such as AmiTCP
and NetBSD. Work in Tomasz' initial support for this.
- How about TCP/IP over netbios?
- Some newer ARCnets support promiscuous mode, supposedly.
If someone sends me information, I'll try to implement it.
- Remove excess lock variables that are probably not necessary
anymore due to the changes in Linux 1.2.9.
/* define this if you want to use the new but possibly dangerous ioprobe
* If you get lockups right after status5, you probably need
* to undefine this. It should make more cards probe correctly,
* I hope.
*/
#define DANGER_PROBE
/* define this if you want to use the "extra delays" which were removed
* in 0.41 since they seemed needless.
*/
#undef EXTRA_DELAYS
Sources:
- Crynwr arcnet.com/arcether.com packet drivers.
- arcnet.c v0.00 dated 1/1/94 and apparently by
Donald Becker - it didn't work :)
- skeleton.c v0.05 dated 11/16/93 by Donald Becker
(from Linux Kernel 1.1.45)
- The official ARCnet data sheets (!) thanks to Ken Cornetet
<kcornete@nyx10.cs.du.edu>
- RFC's 1201 and 1051 (mostly 1201) - re: ARCnet IP packets
- net/inet/eth.c (from kernel 1.1.50) for header-building info...
- Alternate Linux ARCnet source by V.Shergin <vsher@sao.stavropol.su>
- Textual information and more alternate source from Joachim Koenig
<jojo@repas.de>
*/
/* undefine this if you want to use the non-IRQ-driven transmitter. (possibly
* safer, although it takes more CPU time and IRQ_XMIT seems fine right now)
*/
#define IRQ_XMIT
static
char
*
version
=
"arcnet.c:v1.92 ALPHA 95/07/11 Avery Pennarun <apenwarr@foxnet.net>
\n
"
;
/* define this for "careful" transmitting. Try with and without if you have
* problems. If you use IRQ_XMIT, do NOT define this.
*/
#undef CAREFUL_XMIT
/**************************************************************************/
/* define this for an extra-careful memory detect. This should work all
* the time now, but you never know.
/* Define this if you want to detect network reconfigurations.
* They may be a real nuisance on a larger ARCnet network: but if you are
* a network administrator you probably would like to count them.
* Reconfigurations will be recorded in stats.tx_carrier_errors
* (the last field of the /proc/net/dev file).
*
* The card sends the reconfiguration signal when it loses the connection
* to the rest of its network. It is a 'Hello, is anybody there?' cry. This
* usually happens when a new computer on the network is powered on or when
* the cable is broken.
*/
#define
STRICT_MEM_DETECT
#define
DETECT_RECONFIGS
/*
define this to use the "old-style" limited MTU by default. It basically
*
disables packet splitting. ifconfig can still be used to reset the MTU
.
/*
Define this if you want to make sure transmitted packets are "acknowledged"
*
by the destination host, as long as they're not to the broadcast address
.
*
* leave this disabled if possible, so it will use ethernet defaults,
* which is our goal.
* That way, if one segment of a split packet doesn't get through, it can
* be resent immediately rather than confusing the other end.
*
* Disable this to return to 1.01-style behaviour, if you have problems.
*/
#
undef LIMIT_MTU
#
define VERIFY_ACK
/* define this if you have a problem with the card getting "stuck" now and
* then, which can only be fixed by a reboot or resetting the card manually
* via ifconfig up/down. ARCnet will set a timer function which is called
* 8 times every second.
*
* This should no longer be necessary. if you experience "stuck" ARCnet
* drivers, please email apenwarr@foxnet.net or I will remove
* this feature in a future release.
/* Define this if you want to make it easier to use the "call trace" when
* a kernel NULL pointer assignment occurs.
*/
#undef
USE_TIMER_HANDLER
#undef
static
/**************************************************************************/
static
char
*
version
=
"arcnet.c:v1.02 95/06/21 Avery Pennarun <apenwarr@foxnet.net>
\n
"
;
/*
Sources:
Crynwr arcnet.com/arcether.com packet drivers.
arcnet.c v0.00 dated 1/1/94 and apparently by
Donald Becker - it didn't work :)
skeleton.c v0.05 dated 11/16/93 by Donald Becker
(from Linux Kernel 1.1.45)
...I sure wish I had the ARCnet data sheets right about now!
RFC's 1201 and 1051 (mostly 1201) - re: ARCnet IP packets
net/inet/eth.c (from kernel 1.1.50) for header-building info...
Alternate Linux ARCnet source by V.Shergin <vsher@sao.stavropol.su>
Textual information and more alternate source from Joachim Koenig
<jojo@repas.de>
*/
#include <linux/config.h>
#ifdef MODULE
...
...
@@ -139,31 +183,31 @@ static char *version =
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <net/arp.h>
/* debug levels:
* D_OFF production
* D_NORMAL verification
* D_INIT show init/detect messages
* D_DURING show messages during normal use (ie interrupts)
* D_DATA show packets data from skb's, not on Arcnet card
* D_TX show tx packets
* D_RX show tx+rx packets
/* new debugging bitflags: each option can be enabled individually.
*
* these can be set while the driver is running by typing:
* ifconfig arc0 down metric 1xxx HOSTNAME
* where 1xx is 1000 + the debug level you want
* and HOSTNAME is your hostname/ip address
* and then resetting your routes.
*/
#define D_
OFF 0
#define
D_NORMAL 1
#define
D_INIT 2
#define D_EXTRA 3
#define D_DURING
4
#define D_
DATA 6
#define D_
TX 8
#define D_
RX 9
#define D_
NORMAL 1
/* D_NORMAL startup announcement */
#define
D_INIT 2
/* D_INIT show init/probe messages */
#define
D_EXTRA 4
/* D_EXTRA extra information */
/* debug levels past this point give LOTS of output! */
#define D_DURING
8
/* D_DURING during normal use (irq's) */
#define D_
TX 16
/* D_TX show tx packets */
#define D_
RX 32
/* D_RX show rx packets */
#define D_
SKB 64
/* D_SKB dump skb's */
#ifndef NET_DEBUG
#define NET_DEBUG
D_INIT
#define NET_DEBUG
D_NORMAL|D_INIT|D_EXTRA
#endif
static
unsigned
int
net_debug
=
NET_DEBUG
;
int
arc
net_debug
=
NET_DEBUG
;
#ifndef HAVE_AUTOIRQ
/* From auto_irq.c, in ioport.h for later versions. */
...
...
@@ -180,10 +224,20 @@ extern struct device *irq2dev_map[16];
#endif
/* macro to simplify debug checking */
#define BUGLVL(x) if (net_debug>=x)
#define BUGLVL(x) if (arcnet_debug&(x))
/* Some useful multiprotocol macros */
#define TBUSY lp->adev->tbusy \
=lp->wdev->tbusy
#define IF_TBUSY (lp->adev->tbusy \
|| lp->wdev->tbusy)
#define START lp->adev->start \
=lp->wdev->start
/* The number of low I/O ports used by the ethercard. */
#define
ETHERCARD
_TOTAL_SIZE 16
#define
ARCNET
_TOTAL_SIZE 16
/* Handy defines for ARCnet specific stuff */
...
...
@@ -193,7 +247,8 @@ extern struct device *irq2dev_map[16];
#define COMMAND (ioaddr+1)
/* writable, returns random vals on read (?) */
#define RESET (ioaddr+8)
/* software reset writable */
/* time needed for various things (in clock ticks, 1/100 sec) */
/* Time needed for various things (in clock ticks, 1/100 sec) */
/* We mostly don't bother with these - watch out. */
#define RESETtime 40
/* reset */
#define XMITtime 10
/* send (?) */
#define ACKtime 10
/* acknowledge (?) */
...
...
@@ -206,66 +261,73 @@ extern struct device *irq2dev_map[16];
* These numbers are compared with the length of the full packet,
* including ClientData header.
*/
#define MTU
(253+EXTRA_CLIENTDATA)
/* normal packet max size */
#define MinTU
(257+EXTRA_CLIENTDATA)
/* extended packet min size */
#define XMTU
(508+EXTRA_CLIENTDATA)
/* extended packet max size */
#define MTU
253
/* normal packet max size */
#define MinTU
257
/* extended packet min size */
#define XMTU
508
/* extended packet max size */
/* status/interrupt mask bit fields */
#define TXFREEflag 0x001
/* transmitter available */
#define TXACKflag 0x002
/* transmitted msg. ackd */
#define RECONflag 0x004
/* system reconfigured */
#define TESTflag 0x008
/* test flag */
#define RESETflag 0x010
/* power-on-reset */
#define RES1flag 0x020
/* unused */
#define RES2flag 0x040
/* unused */
#define NORXflag 0x080
/* receiver inhibited */
#define TXFREEflag 0x01
/* transmitter available */
#define TXACKflag 0x02
/* transmitted msg. ackd */
#define RECONflag 0x04
/* system reconfigured */
#define TESTflag 0x08
/* test flag */
#define RESETflag 0x10
/* power-on-reset */
#define RES1flag 0x20
/* unused */
#define RES2flag 0x40
/* unused */
#define NORXflag 0x80
/* receiver inhibited */
#ifdef DETECT_RECONFIGS
#define RECON_flag RECONflag
#else
#define RECON_flag 0
#endif
/* in the command register, the following bits have these meanings:
* 0-2 command
* 3-4 page number (for enable rcv/xmt command)
* 7 receive broadcasts
*/
#define NOTXcmd 0x0
0
1
/* disable transmitter */
#define NORXcmd 0x0
0
2
/* disable receiver */
#define TXcmd 0x0
0
3
/* enable transmitter */
#define RXcmd 0x0
0
4
/* enable receiver */
#define CONFIGcmd 0x0
0
5
/* define configuration */
#define CFLAGScmd 0x0
0
6
/* clear flags */
#define TESTcmd 0x0
0
7
/* load test flags */
#define NOTXcmd 0x01
/* disable transmitter */
#define NORXcmd 0x02
/* disable receiver */
#define TXcmd 0x03
/* enable transmitter */
#define RXcmd 0x04
/* enable receiver */
#define CONFIGcmd 0x05
/* define configuration */
#define CFLAGScmd 0x06
/* clear flags */
#define TESTcmd 0x07
/* load test flags */
/* flags for "clear flags" command */
#define RESETclear 0x0
0
8
/* power-on-reset */
#define CONFIGclear 0x
0
10
/* system reconfigured */
#define RESETclear 0x08
/* power-on-reset */
#define CONFIGclear 0x10
/* system reconfigured */
/* flags for "load test flags" command */
#define TESTload 0x0
0
8
/* test flag (diagnostic) */
#define TESTload 0x08
/* test flag (diagnostic) */
/* byte deposited into first address of buffers on reset */
#define TESTvalue 0321
/* that's octal for 0xD1 :) */
/* for "enable receiver" command */
#define RXbcasts 0x
0
80
/* receive broadcasts */
#define RXbcasts 0x80
/* receive broadcasts */
/* flags for "define configuration" command */
#define NORMALconf 0x00
0
/* 1-249 byte packets */
#define EXTconf 0x0
0
8
/* 250-504 byte packets */
#define NORMALconf 0x00
/* 1-249 byte packets */
#define EXTconf 0x08
/* 250-504 byte packets */
/* buffers (4 total) used for receive and xmit.
*/
#define EnableReceiver() outb(RXcmd|(recbuf<<3)|RXbcasts,COMMAND)
/*#define TXbuf 2 (Obsoleted by ping-pong xmits) */
/* Protocol ID's */
/*
RFC1201
Protocol ID's */
#define ARC_P_IP 212
/* 0xD4 */
#define ARC_P_ARP 213
/* 0xD5 */
#define ARC_P_RARP 214
/* 0xD6 */
#define ARC_P_IPX 250
/* 0xFA */
/* MS LanMan/WfWg protocol */
#define ARC_P_MS_TCPIP 0xE8
/* Unsupported/indirectly supported protocols */
#define ARC_P_LANSOFT 251
/* 0xFB */
#define ARC_P_ATALK 0xDD
/* Length of time between "stuck" checks */
#define TIMERval (HZ/8)
/* about 1/8 second */
/* these structures define the format of an arcnet packet. */
#define NORMAL 0
#define EXTENDED 1
...
...
@@ -293,17 +355,16 @@ union ArcPacket
*/
struct
ClientData
{
/* data that's NOT part of real packet */
u_char
daddr
;
/* Destination address - stored here,
* but WE MUST GET RID OF IT BEFORE SENDING A
* PACKET!!
/* data that's NOT part of real packet - we MUST get rid of it before
* actually sending!!
*/
u_char
saddr
;
/* Source address - necessary for IPX protocol */
u_char
saddr
,
/* Source address - needed for IPX */
daddr
;
/* Destination address */
/* data that IS part of real packet */
u_char
protocol_id
,
/* ARC_P_IP, ARC_P_ARP,
or ARC_P_RARP
*/
u_char
protocol_id
,
/* ARC_P_IP, ARC_P_ARP,
etc
*/
split_flag
;
/* for use with split packets */
u_short
sequence
;
/* sequence number
(?)
*/
u_short
sequence
;
/* sequence number */
};
#define EXTRA_CLIENTDATA (sizeof(struct ClientData)-4)
...
...
@@ -329,6 +390,11 @@ struct Outgoing
segnum
,
/* segment being sent */
numsegs
,
/* number of segments */
seglen
;
/* length of segment */
#ifdef VERIFY_ACK
short
lastload_dest
,
/* can last loaded packet be acked? */
lasttrans_dest
;
/* can last TX'd packet be acked? */
#endif
};
...
...
@@ -344,9 +410,13 @@ struct arcnet_local {
in_txhandler
,
/* in TX_IRQ handler? */
sending
;
/* transmit in progress? */
short
tx_left
;
/* segments of split packet left to TX */
struct
timer_list
timer
;
/* the timer interrupt struct */
struct
Incoming
incoming
[
256
];
/* one from each address */
struct
Outgoing
outgoing
;
/* packet currently being sent */
struct
device
*
adev
;
/* RFC1201 protocol device */
struct
device
*
wdev
;
/* Windows protocol device */
};
...
...
@@ -356,40 +426,38 @@ extern int arcnet_probe(struct device *dev);
static
int
arcnet_memprobe
(
struct
device
*
dev
,
u_char
*
addr
);
static
int
arcnet_ioprobe
(
struct
device
*
dev
,
short
ioaddr
);
#endif
static
int
arcnetW_init
(
struct
device
*
dev
);
static
int
arcnet_open
(
struct
device
*
dev
);
static
int
arcnet_close
(
struct
device
*
dev
);
static
int
arcnet_reset
(
struct
device
*
dev
);
static
int
arcnet_send_packet
(
struct
sk_buff
*
skb
,
struct
device
*
dev
);
#ifdef CAREFUL_XMIT
static
void
careful_xmit_wait
(
struct
device
*
dev
);
#else
#define careful_xmit_wait(dev)
#endif
static
void
arcnet_continue_tx
(
struct
device
*
dev
);
static
void
arcnet_prepare_tx
(
struct
device
*
dev
,
struct
ClientData
*
hdr
,
static
int
arcnetA_send_packet
(
struct
sk_buff
*
skb
,
struct
device
*
dev
);
static
void
arcnetA_continue_tx
(
struct
device
*
dev
);
static
void
arcnetA_prepare_tx
(
struct
device
*
dev
,
struct
ClientData
*
hdr
,
short
length
,
char
*
data
);
static
void
arcnet_go_tx
(
struct
device
*
dev
);
static
void
arcnetA_go_tx
(
struct
device
*
dev
);
static
int
arcnetW_send_packet
(
struct
sk_buff
*
skb
,
struct
device
*
dev
);
static
void
arcnet_interrupt
(
int
irq
,
struct
pt_regs
*
regs
);
static
void
arcnet_inthandler
(
struct
device
*
dev
);
static
void
arcnet_rx
(
struct
device
*
dev
,
int
recbuf
);
#ifdef USE_TIMER_HANDLER
static
void
arcnet_timer
(
unsigned
long
arg
);
#endif
static
void
arcnet_rx
(
struct
device
*
dev
,
int
recbuf
);
static
void
arcnetA_rx
(
struct
device
*
dev
,
struct
ClientData
*
arcsoft
,
int
length
,
u_char
saddr
,
u_char
daddr
);
static
void
arcnetW_rx
(
struct
device
*
dev
,
u_char
*
arcsoft
,
int
length
,
u_char
saddr
,
u_char
daddr
);
static
struct
enet_statistics
*
arcnet_get_stats
(
struct
device
*
dev
);
static
void
set_multicast_list
(
struct
device
*
dev
,
int
num_addrs
,
void
*
addrs
);
/* annoying functions for header/arp/etc building */
int
arc_header
(
struct
sk_buff
*
skb
,
struct
device
*
dev
,
unsigned
short
type
,
int
arc
netA
_header
(
struct
sk_buff
*
skb
,
struct
device
*
dev
,
unsigned
short
type
,
void
*
daddr
,
void
*
saddr
,
unsigned
len
);
int
arc_rebuild_header
(
void
*
eth
,
struct
device
*
dev
,
unsigned
long
raddr
,
int
arc
netA
_rebuild_header
(
void
*
eth
,
struct
device
*
dev
,
unsigned
long
raddr
,
struct
sk_buff
*
skb
);
unsigned
short
arc_type_trans
(
struct
sk_buff
*
skb
,
struct
device
*
dev
);
static
int
arcnet_reset
(
struct
device
*
dev
);
unsigned
short
arcnetA_type_trans
(
struct
sk_buff
*
skb
,
struct
device
*
dev
);
#ifdef MODULE
int
init_module
(
void
);
...
...
@@ -398,19 +466,17 @@ void cleanup_module(void);
#define tx_done(dev) 1
/*
#define JIFFER(time) for (delayval=jiffies+(time); delayval>jiffies;);
*/
#define JIFFER(time) for (delayval=0; delayval<(time*10); delayval++) \
udelay(1000);
#ifdef EXTRA_DELAYS
#define XJIFFER(time) JIFFER(time)
#else
#define XJIFFER(time)
#endif
/****************************************************************************
* *
* Probe and initialization *
* *
****************************************************************************/
/* Check for a network adaptor of this type, and return '0' if one exists.
* If dev->base_addr == 0, probe all likely locations.
* If dev->base_addr == 1, always return failure.
...
...
@@ -450,14 +516,14 @@ arcnet_probe(struct device *dev)
int
delayval
;
struct
arcnet_local
*
lp
;
if
(
net_debug
)
BUGLVL
(
D_NORMAL
)
{
printk
(
version
);
printk
(
"arcnet: ***
\n
"
);
printk
(
"arcnet: * Read linux/drivers/net/README.arcnet for important release notes!
\n
"
);
printk
(
"arcnet: *
\n
"
);
printk
(
"arcnet: * This
version should be stable, but e-mail me if you have any
\n
"
);
printk
(
"arcnet: *
questions, comments, or bug reports!
\n
"
);
printk
(
"arcnet: * This
is an ALPHA version! (Last stable release: v1.02) E-mail me if
\n
"
);
printk
(
"arcnet: *
you have any questions, comments, or bug reports.
\n
"
);
printk
(
"arcnet: ***
\n
"
);
}
...
...
@@ -473,7 +539,7 @@ arcnet_probe(struct device *dev)
else
for
(
port
=
&
ports
[
0
];
*
port
;
port
++
)
{
int
ioaddr
=
*
port
;
if
(
check_region
(
ioaddr
,
ETHERCARD
_TOTAL_SIZE
))
if
(
check_region
(
ioaddr
,
ARCNET
_TOTAL_SIZE
))
{
BUGLVL
(
D_INIT
)
printk
(
"arcnet: Skipping %Xh because of check_region...
\n
"
,
...
...
@@ -534,7 +600,7 @@ arcnet_probe(struct device *dev)
}
/* Grab the region so we can find another board if autoIRQ fails. */
request_region
(
dev
->
base_addr
,
ETHERCARD
_TOTAL_SIZE
,
"arcnet"
);
request_region
(
dev
->
base_addr
,
ARCNET
_TOTAL_SIZE
,
"arcnet"
);
printk
(
"%s: ARCnet card found at %03lXh, IRQ %d, ShMem at %lXh.
\n
"
,
dev
->
name
,
dev
->
base_addr
,
dev
->
irq
,
dev
->
mem_start
);
...
...
@@ -544,27 +610,26 @@ arcnet_probe(struct device *dev)
memset
(
dev
->
priv
,
0
,
sizeof
(
struct
arcnet_local
));
lp
=
(
struct
arcnet_local
*
)(
dev
->
priv
);
dev
->
open
=
arcnet_open
;
dev
->
stop
=
arcnet_close
;
dev
->
hard_start_xmit
=
arcnet
_send_packet
;
dev
->
get_stats
=
arcnet_get_stats
;
dev
->
open
=
arcnet_open
;
dev
->
stop
=
arcnet_close
;
dev
->
hard_start_xmit
=
arcnetA
_send_packet
;
dev
->
get_stats
=
arcnet_get_stats
;
#ifdef HAVE_MULTICAST
dev
->
set_multicast_list
=
&
set_multicast_list
;
#endif
/* Fill in the fields of the device structure with ethernet-generic values. */
/* Fill in the fields of the device structure with ethernet-generic
* values.
*/
ether_setup
(
dev
);
/* And now fill particular ones with arcnet values :) */
/* And now fill particular fields with arcnet values */
dev
->
type
=
ARPHRD_ARCNET
;
dev
->
hard_header_len
=
sizeof
(
struct
ClientData
);
BUGLVL
(
D_
EXTRA
)
BUGLVL
(
D_
DURING
)
printk
(
"arcnet: ClientData header size is %d.
\n
arcnet: HardHeader size is %d.
\n
"
,
sizeof
(
struct
ClientData
),
sizeof
(
struct
HardHeader
));
#if LIMIT_MTU
/* the old way - normally, now use ethernet default */
dev
->
mtu
=
512
-
sizeof
(
struct
HardHeader
)
+
EXTRA_CLIENTDATA
;
#endif
/* since we strip EXTRA_CLIENTDATA bytes off before sending,
* we let Linux add that many bytes to the packet data...
*/
...
...
@@ -585,8 +650,8 @@ arcnet_probe(struct device *dev)
lp
->
sequence
=
1
;
lp
->
recbuf
=
0
;
dev
->
hard_header
=
arc
_header
;
dev
->
rebuild_header
=
arc
_rebuild_header
;
dev
->
hard_header
=
arcnetA
_header
;
dev
->
rebuild_header
=
arcnetA
_rebuild_header
;
return
0
;
}
...
...
@@ -598,10 +663,10 @@ int arcnet_ioprobe(struct device *dev, short ioaddr)
int
delayval
,
airq
;
BUGLVL
(
D_INIT
)
{
printk
(
"arcnet: probing address %Xh
\n
"
,
ioaddr
);
BUGLVL
(
D_INIT
)
printk
(
"arcnet: status1=%Xh
\n
"
,
inb
(
STATUS
));
}
/* very simple - all we have to do is reset the card, and if there's
...
...
@@ -621,6 +686,7 @@ int arcnet_ioprobe(struct device *dev, short ioaddr)
return
ENODEV
;
}
#if 0
/* we'll try to be reasonably sure it's an arcnet by making sure
* the value of the COMMAND port changes automatically once in a
* while. I have no idea what those values ARE, but at least
...
...
@@ -641,13 +707,13 @@ int arcnet_ioprobe(struct device *dev, short ioaddr)
return ENODEV;
}
}
#endif
BUGLVL
(
D_INIT
)
printk
(
"arcnet: status2=%Xh
\n
"
,
inb
(
STATUS
));
/* now we turn the reset bit off so we can IRQ next reset... */
outb
(
CFLAGScmd
|
RESETclear
|
CONFIGclear
,
COMMAND
);
XJIFFER
(
ACKtime
);
if
(
inb
(
STATUS
)
&
RESETflag
)
/* reset flag STILL on */
{
BUGLVL
(
D_INIT
)
...
...
@@ -659,32 +725,6 @@ int arcnet_ioprobe(struct device *dev, short ioaddr)
/* set up automatic IRQ detection */
autoirq_setup
(
0
);
/* enable reset IRQ's (shouldn't be necessary, but worth a try) */
outb
(
RESETflag
,
INTMASK
);
/* now reset it again to generate an IRQ */
inb
(
RESET
);
JIFFER
(
RESETtime
);
BUGLVL
(
D_INIT
)
printk
(
"arcnet: status3=%Xh
\n
"
,
inb
(
STATUS
));
/* and turn the reset flag back off */
outb
(
CFLAGScmd
|
RESETclear
|
CONFIGclear
,
COMMAND
);
XJIFFER
(
ACKtime
);
BUGLVL
(
D_INIT
)
printk
(
"arcnet: status4=%Xh
\n
"
,
inb
(
STATUS
));
/* enable reset IRQ's again */
outb
(
RESETflag
,
INTMASK
);
/* now reset it again to generate an IRQ */
inb
(
RESET
);
JIFFER
(
RESETtime
);
BUGLVL
(
D_INIT
)
printk
(
"arcnet: status5=%Xh
\n
"
,
inb
(
STATUS
));
/* if we do this, we're sure to get an IRQ since the card has
* just reset and the NORXflag is on until we tell it to start
...
...
@@ -693,18 +733,15 @@ int arcnet_ioprobe(struct device *dev, short ioaddr)
* However, this could, theoretically, cause a lockup. Maybe I'm just
* not very good at theory! :)
*/
#ifdef DANGER_PROBE
outb
(
NORXflag
,
INTMASK
);
JIFFER
(
RESETtime
);
outb
(
0
,
INTMASK
);
#endif
/* and turn the reset flag back off */
outb
(
CFLAGScmd
|
RESETclear
|
CONFIGclear
,
COMMAND
);
XJIFFER
(
ACKtime
);
airq
=
autoirq_report
(
0
);
if
(
net_debug
>=
D_INIT
&&
airq
)
BUGLVL
(
D_INIT
)
if
(
airq
)
printk
(
"arcnet: autoirq is %d
\n
"
,
airq
);
/* if there was no autoirq AND the user hasn't set any defaults,
...
...
@@ -723,7 +760,6 @@ int arcnet_ioprobe(struct device *dev, short ioaddr)
{
/* now we turn the reset bit off */
outb
(
CFLAGScmd
|
RESETclear
|
CONFIGclear
,
COMMAND
);
XJIFFER
(
ACKtime
);
}
if
(
inb
(
STATUS
)
&
RESETflag
)
/* reset flag STILL on */
...
...
@@ -744,7 +780,7 @@ int arcnet_ioprobe(struct device *dev, short ioaddr)
}
else
if
(
dev
->
irq
==
2
)
{
if
(
net_debug
)
BUGLVL
(
D_NORMAL
)
printk
(
"arcnet: IRQ2 == IRQ9, don't worry.
\n
"
);
dev
->
irq
=
9
;
}
...
...
@@ -758,7 +794,7 @@ int arcnet_ioprobe(struct device *dev, short ioaddr)
/* A memory probe that is called after the card is reset.
* It checks for the official TESTvalue in byte 0 and makes sure the buffer
* has certain characteristics of an ARCnet.
..
* has certain characteristics of an ARCnet.
*/
int
arcnet_memprobe
(
struct
device
*
dev
,
u_char
*
addr
)
{
...
...
@@ -767,7 +803,6 @@ int arcnet_memprobe(struct device *dev,u_char *addr)
dev
->
mem_start
=
0
;
#ifdef STRICT_MEM_DETECT
/* probably better. */
/* ARCnet memory byte 0 is TESTvalue */
if
(
addr
[
0
]
!=
TESTvalue
)
{
...
...
@@ -786,15 +821,6 @@ int arcnet_memprobe(struct device *dev,u_char *addr)
(
unsigned
long
)
addr
,
addr
[
0
]);
return
ENODEV
;
}
#else
if
(
addr
[
0
]
!=
TESTvalue
)
{
BUGLVL
(
D_INIT
)
printk
(
"arcnet: probe failed. addr=%lXh, addr[0]=%Xh (not %Xh)
\n
"
,
(
unsigned
long
)
addr
,
addr
[
0
],
TESTvalue
);
return
ENODEV
;
}
#endif
/* got it! fill in dev */
dev
->
mem_start
=
(
unsigned
long
)
addr
;
...
...
@@ -807,64 +833,136 @@ int arcnet_memprobe(struct device *dev,u_char *addr)
#endif
/* MODULE */
/* Open/initialize the board. This is called (in the current kernel)
sometime after booting when the 'ifconfig' program is run.
This routine should set everything up anew at each open, even
registers that "should" only need to be set once at boot, so that
there is non-reboot way to recover if something goes wrong.
int
arcnet_reset
(
struct
device
*
dev
)
{
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
short
ioaddr
=
dev
->
base_addr
;
int
delayval
,
recbuf
=
lp
->
recbuf
;
u_char
*
cardmem
;
outb
(
0
,
INTMASK
);
/* no IRQ's, please! */
BUGLVL
(
D_INIT
)
printk
(
"arcnet: Resetting %s (status=%Xh)
\n
"
,
dev
->
name
,
inb
(
STATUS
));
inb
(
RESET
);
/* Reset by reading this port */
JIFFER
(
RESETtime
);
outb
(
CFLAGScmd
|
RESETclear
,
COMMAND
);
/* clear flags & end reset */
outb
(
CFLAGScmd
|
CONFIGclear
,
COMMAND
);
/* after a reset, the first byte of shared mem is TESTvalue and the
* second byte is our 8-bit ARCnet address.
*/
cardmem
=
(
u_char
*
)
dev
->
mem_start
;
if
(
cardmem
[
0
]
!=
TESTvalue
)
{
BUGLVL
(
D_INIT
)
printk
(
"arcnet: reset failed: TESTvalue not present.
\n
"
);
return
1
;
}
lp
->
arcnum
=
cardmem
[
1
];
/* save address for later use */
/* clear out status variables */
recbuf
=
lp
->
recbuf
=
0
;
lp
->
txbuf
=
2
;
/* enable extended (512-byte) packets */
outb
(
CONFIGcmd
|
EXTconf
,
COMMAND
);
/* clean out all the memory to make debugging make more sense :) */
BUGLVL
(
D_DURING
)
memset
((
void
*
)
dev
->
mem_start
,
0x42
,
2048
);
/* and enable receive of our first packet to the first buffer */
EnableReceiver
();
/* re-enable interrupts */
outb
(
NORXflag
|
RECON_flag
,
INTMASK
);
/* done! return success. */
return
0
;
}
static
int
arcnetW_init
(
struct
device
*
dev
)
{
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
ether_setup
(
lp
->
wdev
);
dev
->
dev_addr
[
0
]
=
0
;
dev
->
dev_addr
[
5
]
=
lp
->
arcnum
;
dev
->
mtu
=
493
;
/* MTU is small because of missing packet splitting */
lp
->
wdev
->
open
=
NULL
;
lp
->
wdev
->
stop
=
NULL
;
lp
->
wdev
->
hard_start_xmit
=
arcnetW_send_packet
;
BUGLVL
(
D_EXTRA
)
printk
(
"%s: ARCnet
\"
Windows
\"
protocol initialized.
\n
"
,
lp
->
wdev
->
name
);
return
0
;
}
/****************************************************************************
* *
* Open and close the driver *
* *
****************************************************************************/
/* Open/initialize the board. This is called sometime after booting when
* the 'ifconfig' program is run.
*
* This routine should set everything up anew at each open, even
* registers that "should" only need to be set once at boot, so that
* there is non-reboot way to recover if something goes wrong.
*/
static
int
arcnet_open
(
struct
device
*
dev
)
{
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
/* int ioaddr = dev->base_addr;*/
if
(
dev
->
metric
>=
10
)
if
(
dev
->
metric
>=
10
00
)
{
net_debug
=
dev
->
metric
-
10
;
arcnet_debug
=
dev
->
metric
-
1000
;
printk
(
"arcnet: debug level set to %d
\n
"
,
arcnet_debug
);
dev
->
metric
=
1
;
}
if
(
net_debug
)
printk
(
version
);
#if 0 /* Yup, they're hardwired in arcnets */
/* This is used if the interrupt line can turned off (shared).
See 3c503.c for an example of selecting the IRQ at config-time. */
if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet")) {
return -EAGAIN;
}
#endif
BUGLVL
(
D_NORMAL
)
printk
(
version
);
irq2dev_map
[
dev
->
irq
]
=
dev
;
/* Reset the hardware here. */
BUGLVL
(
D_EXTRA
)
printk
(
"arcnet: arcnet_open: resetting card.
\n
"
);
/* try to reset - twice if it fails the first time */
if
(
arcnet_reset
(
dev
)
&&
arcnet_reset
(
dev
))
return
-
ENODEV
;
/* chipset_init(dev, 1);*/
/* outb(0x00, ioaddr);*/
/* lp->open_time = jiffies;*/
dev
->
tbusy
=
0
;
dev
->
interrupt
=
0
;
dev
->
start
=
1
;
lp
->
intx
=
0
;
lp
->
in_txhandler
=
0
;
#ifdef USE_TIMER_HANDLER
/* grab a timer handler to recover from any missed IRQ's */
init_timer
(
&
lp
->
timer
);
lp
->
timer
.
expires
=
TIMERval
;
/* length of time */
lp
->
timer
.
data
=
(
unsigned
long
)
dev
;
/* pointer to "dev" structure */
lp
->
timer
.
function
=
&
arcnet_timer
;
/* timer handler */
add_timer
(
&
lp
->
timer
);
#endif
/* The RFC1201 driver is the default - just store */
lp
->
adev
=
dev
;
BUGLVL
(
D_EXTRA
)
printk
(
"%s: ARCnet RFC1201 protocol initialized.
\n
"
,
lp
->
adev
->
name
);
/* Initialize the Windows protocol driver */
lp
->
wdev
=
(
struct
device
*
)
kmalloc
(
sizeof
(
struct
device
),
GFP_KERNEL
);
memcpy
(
lp
->
wdev
,
dev
,
sizeof
(
struct
device
));
lp
->
wdev
->
name
=
(
char
*
)
kmalloc
(
10
,
GFP_KERNEL
);
sprintf
(
lp
->
wdev
->
name
,
"%sw"
,
dev
->
name
);
lp
->
wdev
->
init
=
arcnetW_init
;
register_netdev
(
lp
->
wdev
);
/* we're started */
START
=
1
;
#ifdef MODULE
MOD_INC_USE_COUNT
;
...
...
@@ -874,33 +972,34 @@ arcnet_open(struct device *dev)
}
/* The inverse routine to arcnet_open(). */
/* The inverse routine to arcnet_open - shuts down the card.
*/
static
int
arcnet_close
(
struct
device
*
dev
)
{
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
int
ioaddr
=
dev
->
base_addr
;
#ifdef EXTRA_DELAYS
int
delayval
;
#endif
/* lp->open_time = 0;*/
dev
->
tbusy
=
1
;
dev
->
start
=
0
;
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
/* release the timer */
del_timer
(
&
lp
->
timer
)
;
TBUSY
=
1
;
START
=
0
;
/* Flush the Tx and disable Rx here. */
/* resetting the card should do the job. */
/*inb(RESET);*/
outb
(
0
,
INTMASK
);
/* no IRQ's */
outb
(
NOTXcmd
,
COMMAND
);
/* disable transmit */
XJIFFER
(
ACKtime
);
outb
(
NORXcmd
,
COMMAND
);
/* disable receive */
/* do NOT free lp->adev!! It's static! */
lp
->
adev
=
NULL
;
/* free the Windows protocol device */
lp
->
wdev
->
start
=
0
;
lp
->
wdev
->
priv
=
NULL
;
unregister_netdev
(
lp
->
wdev
);
kfree
(
lp
->
wdev
->
name
);
kfree
(
lp
->
wdev
);
lp
->
wdev
=
NULL
;
/* Update the statistics here. */
#ifdef MODULE
...
...
@@ -911,12 +1010,21 @@ arcnet_close(struct device *dev)
}
/****************************************************************************
* *
* Transmitter routines *
* *
****************************************************************************/
/* Called by the kernel in order to transmit a packet.
*/
static
int
arcnet_send_packet
(
struct
sk_buff
*
skb
,
struct
device
*
dev
)
arcnet
A
_send_packet
(
struct
sk_buff
*
skb
,
struct
device
*
dev
)
{
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
int
ioaddr
=
dev
->
base_addr
;
/* short daddr;*/
lp
->
intx
++
;
...
...
@@ -924,7 +1032,14 @@ arcnet_send_packet(struct sk_buff *skb, struct device *dev)
printk
(
"arcnet: transmit requested (status=%Xh, inTX=%d)
\n
"
,
inb
(
STATUS
),
lp
->
intx
);
if
(
dev
->
tbusy
||
lp
->
in_txhandler
)
if
(
lp
->
in_txhandler
)
{
printk
(
"arcnet: send_packet called while in txhandler!
\n
"
);
lp
->
intx
--
;
return
1
;
}
if
(
IF_TBUSY
)
{
/* If we get here, some higher level has decided we are broken.
There should really be a "kick me" function call instead. */
...
...
@@ -932,18 +1047,6 @@ arcnet_send_packet(struct sk_buff *skb, struct device *dev)
int
recbuf
=
lp
->
recbuf
;
int
status
=
inb
(
STATUS
);
/* resume any stopped tx's */
#if 0
if (lp->txready && (inb(STATUS)&TXFREEflag))
{
printk("arcnet: kickme: starting a TX (status=%Xh)\n",
inb(STATUS));
arcnet_go_tx(dev);
lp->intx--;
return 1;
}
#endif
if
(
tickssofar
<
5
)
{
BUGLVL
(
D_DURING
)
...
...
@@ -955,27 +1058,36 @@ arcnet_send_packet(struct sk_buff *skb, struct device *dev)
return
1
;
}
BUGLVL
(
D_INIT
)
printk
(
"arcnet: transmit timed out (status=%Xh, inTX=%d, tickssofar=%d)
\n
"
,
status
,
lp
->
intx
,
tickssofar
);
BUGLVL
(
D_EXTRA
)
printk
(
"arcnet: transmit timed out (status=%Xh, inTX=%d, inTXh=%d, tickssofar=%d)
\n
"
,
status
,
lp
->
intx
,
lp
->
in_txhandler
,
tickssofar
);
lp
->
stats
.
tx_errors
++
;
/* Try to restart the adaptor. */
/*arcnet_reset(dev);*/
outb
(
0
,
INTMASK
);
if
(
status
&
NORXflag
)
EnableReceiver
();
if
(
!
(
status
&
TXFREEflag
))
outb
(
NOTXcmd
,
COMMAND
);
dev
->
trans_start
=
jiffies
;
if
(
lp
->
outgoing
.
skb
)
{
dev_kfree_skb
(
lp
->
outgoing
.
skb
,
FREE_WRITE
);
lp
->
stats
.
tx_dropped
++
;
}
lp
->
outgoing
.
skb
=
NULL
;
dev
->
tbusy
=
0
;
mark_bh
(
NET_BH
)
;
lp
->
intx
=
0
;
lp
->
in_txhandler
=
0
;
TBUSY
=
0
;
lp
->
intx
--
;
/*lp->intx=0;*/
/*lp->in_txhandler=0;*/
lp
->
txready
=
0
;
lp
->
sending
=
0
;
mark_bh
(
NET_BH
);
outb
(
NORXflag
|
RECON_flag
,
INTMASK
);
return
1
;
}
...
...
@@ -984,7 +1096,7 @@ arcnet_send_packet(struct sk_buff *skb, struct device *dev)
we are passed NULL. Caution: dev_tint() handles the cli()/sti()
itself. */
if
(
skb
==
NULL
)
{
BUGLVL
(
D_
INIT
)
BUGLVL
(
D_
NORMAL
)
printk
(
"arcnet: tx passed null skb (status=%Xh, inTX=%d, tickssofar=%ld)
\n
"
,
inb
(
STATUS
),
lp
->
intx
,
jiffies
-
dev
->
trans_start
);
dev_tint
(
dev
);
...
...
@@ -994,9 +1106,16 @@ arcnet_send_packet(struct sk_buff *skb, struct device *dev)
if
(
lp
->
txready
)
/* transmit already in progress! */
{
printk
(
"arcnet: trying to start new packet while busy!
\n
"
);
printk
(
"arcnet: marking as not ready.
\n
"
);
lp
->
txready
=
0
;
printk
(
"arcnet: trying to start new packet while busy! (status=%Xh)
\n
"
,
inb
(
STATUS
));
/*printk("arcnet: marking as not ready.\n");*/
outb
(
0
,
INTMASK
);
outb
(
NOTXcmd
,
COMMAND
);
/* abort current send */
arcnet_inthandler
(
dev
);
/* fake an interrupt */
lp
->
stats
.
tx_errors
++
;
lp
->
intx
--
;
lp
->
txready
=
0
;
/* we definitely need this line! */
return
1
;
}
...
...
@@ -1011,10 +1130,15 @@ arcnet_send_packet(struct sk_buff *skb, struct device *dev)
}
else
{
struct
Outgoing
*
out
=&
(
lp
->
outgoing
);
out
->
length
=
ETH_ZLEN
<
skb
->
len
?
skb
->
len
:
ETH_ZLEN
;
TBUSY
=
1
;
out
->
length
=
1
<
skb
->
len
?
skb
->
len
:
1
;
out
->
hdr
=
(
struct
ClientData
*
)
skb
->
data
;
out
->
skb
=
skb
;
BUGLVL
(
D_DATA
)
{
BUGLVL
(
D_SKB
)
{
short
i
;
for
(
i
=
0
;
i
<
skb
->
len
;
i
++
)
{
...
...
@@ -1024,25 +1148,25 @@ arcnet_send_packet(struct sk_buff *skb, struct device *dev)
printk
(
"
\n
"
);
}
#ifdef IRQ_XMIT
if
(
lp
->
txready
&&
inb
(
STATUS
)
&
TXFREEflag
)
arcnet_go_tx
(
dev
);
#endif
out
->
hdr
->
sequence
=
(
lp
->
sequence
++
);
if
(
lp
->
txready
&&
inb
(
STATUS
)
&
TXFREEflag
)
arcnetA_go_tx
(
dev
);
if
(
out
->
length
<=
XMTU
)
/* fits in one packet? */
/* fits in one packet? */
if
(
out
->
length
-
EXTRA_CLIENTDATA
<=
XMTU
)
{
BUGLVL
(
D_TX
)
printk
(
"arcnet: not splitting %d-byte packet. (split_flag=%d)
\n
"
,
BUGLVL
(
D_DURING
)
printk
(
"arcnet: not splitting %d-byte packet. (split_flag=%d)
\n
"
,
out
->
length
,
out
->
hdr
->
split_flag
);
BUGLVL
(
D_
INIT
)
if
(
out
->
hdr
->
split_flag
)
BUGLVL
(
D_
EXTRA
)
if
(
out
->
hdr
->
split_flag
)
printk
(
"arcnet: short packet has split_flag set?! (split_flag=%d)
\n
"
,
out
->
hdr
->
split_flag
);
out
->
numsegs
=
1
;
out
->
segnum
=
1
;
arcnet_prepare_tx
(
dev
,
out
->
hdr
,
arcnet
A
_prepare_tx
(
dev
,
out
->
hdr
,
out
->
length
-
sizeof
(
struct
ClientData
),
((
char
*
)
skb
->
data
)
+
sizeof
(
struct
ClientData
));
careful_xmit_wait
(
dev
);
/* done right away */
dev_kfree_skb
(
out
->
skb
,
FREE_WRITE
);
...
...
@@ -1050,16 +1174,16 @@ arcnet_send_packet(struct sk_buff *skb, struct device *dev)
if
(
!
lp
->
sending
)
{
arcnet_go_tx
(
dev
);
arcnet
A
_go_tx
(
dev
);
/* inform upper layers */
dev
->
tbusy
=
0
;
TBUSY
=
0
;
mark_bh
(
NET_BH
);
}
}
else
/* too big for one - split it */
{
int
maxsegsize
=
XMTU
-
sizeof
(
struct
ClientData
)
;
int
maxsegsize
=
XMTU
-
4
;
out
->
data
=
(
u_char
*
)
skb
->
data
+
sizeof
(
struct
ClientData
);
...
...
@@ -1071,23 +1195,22 @@ arcnet_send_packet(struct sk_buff *skb, struct device *dev)
BUGLVL
(
D_TX
)
printk
(
"arcnet: packet (%d bytes) split into %d fragments:
\n
"
,
out
->
length
,
out
->
numsegs
);
#ifdef IRQ_XMIT
/* if a packet waiting, launch it */
if
(
lp
->
txready
&&
inb
(
STATUS
)
&
TXFREEflag
)
arcnet_go_tx
(
dev
);
arcnet
A
_go_tx
(
dev
);
if
(
!
lp
->
txready
)
{
/* prepare a packet, launch it and prepare
* another.
*/
arcnet_continue_tx
(
dev
);
arcnet
A
_continue_tx
(
dev
);
if
(
!
lp
->
sending
)
{
arcnet_go_tx
(
dev
);
arcnet_continue_tx
(
dev
);
arcnet
A
_go_tx
(
dev
);
arcnet
A
_continue_tx
(
dev
);
if
(
!
lp
->
sending
)
arcnet_go_tx
(
dev
);
arcnet
A
_go_tx
(
dev
);
}
}
...
...
@@ -1101,29 +1224,7 @@ arcnet_send_packet(struct sk_buff *skb, struct device *dev)
if
(
out
->
skb
)
dev_kfree_skb
(
out
->
skb
,
FREE_WRITE
);
out
->
skb
=
NULL
;
#if 0
/* inform upper layers */
dev->tbusy=0;
mark_bh(NET_BH);
#endif
}
#else
/* non-irq xmit */
while
(
out
->
segnum
<
out
->
numsegs
)
{
arcnet_continue_tx
(
dev
);
careful_xmit_wait
(
dev
);
arcnet_go_tx
(
dev
);
dev
->
trans_start
=
jiffies
;
}
dev_kfree_skb
(
out
->
skb
,
FREE_WRITE
);
out
->
skb
=
NULL
;
/* inform upper layers */
dev
->
tbusy
=
0
;
mark_bh
(
NET_BH
);
#endif
}
}
...
...
@@ -1133,10 +1234,15 @@ arcnet_send_packet(struct sk_buff *skb, struct device *dev)
return
0
;
}
static
void
arcnet_continue_tx
(
struct
device
*
dev
)
/* After an RFC1201 split packet has been set up, this function calls
* arcnetA_prepare_tx to load the next segment into the card. This function
* does NOT automatically call arcnetA_go_tx to allow for easier double-
* buffering.
*/
static
void
arcnetA_continue_tx
(
struct
device
*
dev
)
{
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
int
maxsegsize
=
XMTU
-
sizeof
(
struct
ClientData
)
;
int
maxsegsize
=
XMTU
-
4
;
struct
Outgoing
*
out
=&
(
lp
->
outgoing
);
if
(
lp
->
txready
)
...
...
@@ -1163,57 +1269,35 @@ static void arcnet_continue_tx(struct device *dev)
out
->
segnum
+
1
,
out
->
seglen
,
out
->
numsegs
,
out
->
length
,
out
->
hdr
->
split_flag
);
arcnet_prepare_tx
(
dev
,
out
->
hdr
,
out
->
seglen
,
out
->
data
);
arcnet
A
_prepare_tx
(
dev
,
out
->
hdr
,
out
->
seglen
,
out
->
data
);
out
->
dataleft
-=
out
->
seglen
;
out
->
data
+=
out
->
seglen
;
out
->
segnum
++
;
}
#ifdef CAREFUL_XMIT
static
void
careful_xmit_wait
(
struct
device
*
dev
)
/* Given an skb, copy a packet into the ARCnet buffers for later transmission
* by arcnetA_go_tx.
*/
static
void
arcnetA_prepare_tx
(
struct
device
*
dev
,
struct
ClientData
*
hdr
,
short
length
,
char
*
data
)
{
int
ioaddr
=
dev
->
base_addr
;
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
/* wait patiently for tx to become available again */
while
(
!
(
inb
(
STATUS
)
&
TXFREEflag
)
)
{
if
(
jiffies
-
dev
->
trans_start
>
20
||
!
dev
->
tbusy
)
{
BUGLVL
(
D_INIT
)
printk
(
"arcnet: CAREFUL_XMIT timeout. (busy=%d, status=%Xh)
\n
"
,
dev
->
tbusy
,
inb
(
STATUS
));
lp
->
stats
.
tx_errors
++
;
outb
(
NOTXcmd
,
COMMAND
);
return
;
}
}
BUGLVL
(
D_TX
)
printk
(
"arcnet: transmit completed successfully. (status=%Xh)
\n
"
,
inb
(
STATUS
));
}
#endif
static
void
arcnet_prepare_tx
(
struct
device
*
dev
,
struct
ClientData
*
hdr
,
short
length
,
char
*
data
)
{
/* int ioaddr = dev->base_addr;*/
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
struct
ClientData
*
arcsoft
;
union
ArcPacket
*
arcpacket
=
(
union
ArcPacket
*
)(
dev
->
mem_start
+
512
*
(
lp
->
txbuf
^
1
));
u_char
pkttype
;
int
offset
;
short
daddr
;
struct
ClientData
*
arcsoft
;
union
ArcPacket
*
arcpacket
=
(
union
ArcPacket
*
)(
dev
->
mem_start
+
512
*
(
lp
->
txbuf
^
1
));
u_char
pkttype
;
int
offset
;
short
daddr
;
lp
->
txbuf
=
lp
->
txbuf
^
1
;
/* XOR with 1 to alternate between 2 and 3 */
length
+=
sizeof
(
struct
ClientData
)
;
length
+=
4
;
BUGLVL
(
D_TX
)
printk
(
"arcnet: arcnet_prep_tx: hdr:%ph, length:%d, data:%ph
\n
"
,
printk
(
"arcnet: arcnet
A
_prep_tx: hdr:%ph, length:%d, data:%ph
\n
"
,
hdr
,
length
,
data
);
/* clean out the page to make debugging make more sense :) */
...
...
@@ -1227,8 +1311,7 @@ arcnet_prepare_tx(struct device *dev,struct ClientData *hdr,short length,
{
pkttype
=
NORMAL
;
arcpacket
->
hardheader
.
offset1
=
offset
=
256
-
length
+
EXTRA_CLIENTDATA
;
arcpacket
->
hardheader
.
offset1
=
offset
=
256
-
length
;
arcsoft
=
(
struct
ClientData
*
)
(
&
arcpacket
->
raw
[
offset
-
EXTRA_CLIENTDATA
]);
}
...
...
@@ -1237,8 +1320,7 @@ arcnet_prepare_tx(struct device *dev,struct ClientData *hdr,short length,
pkttype
=
EXTENDED
;
arcpacket
->
hardheader
.
offset1
=
0
;
arcpacket
->
hardheader
.
offset2
=
offset
=
512
-
length
+
EXTRA_CLIENTDATA
;
arcpacket
->
hardheader
.
offset2
=
offset
=
512
-
length
;
arcsoft
=
(
struct
ClientData
*
)
(
&
arcpacket
->
raw
[
offset
-
EXTRA_CLIENTDATA
]);
}
...
...
@@ -1247,8 +1329,7 @@ arcnet_prepare_tx(struct device *dev,struct ClientData *hdr,short length,
pkttype
=
EXCEPTION
;
arcpacket
->
hardheader
.
offset1
=
0
;
arcpacket
->
hardheader
.
offset2
=
offset
=
512
-
length
-
4
+
EXTRA_CLIENTDATA
;
arcpacket
->
hardheader
.
offset2
=
offset
=
512
-
length
-
4
;
arcsoft
=
(
struct
ClientData
*
)
(
&
arcpacket
->
raw
[
offset
+
4
-
EXTRA_CLIENTDATA
]);
...
...
@@ -1267,11 +1348,9 @@ arcnet_prepare_tx(struct device *dev,struct ClientData *hdr,short length,
* - the first bytes of ClientData header are skipped
*/
memcpy
((
u_char
*
)
arcsoft
+
EXTRA_CLIENTDATA
,
(
u_char
*
)
hdr
+
EXTRA_CLIENTDATA
,
sizeof
(
struct
ClientData
)
-
EXTRA_CLIENTDATA
);
(
u_char
*
)
hdr
+
EXTRA_CLIENTDATA
,
4
);
memcpy
((
u_char
*
)
arcsoft
+
sizeof
(
struct
ClientData
),
data
,
length
-
sizeof
(
struct
ClientData
));
data
,
length
-
4
);
BUGLVL
(
D_DURING
)
printk
(
"arcnet: transmitting packet to station %02Xh (%d bytes, type=%d)
\n
"
,
daddr
,
length
,
pkttype
);
...
...
@@ -1292,35 +1371,18 @@ arcnet_prepare_tx(struct device *dev,struct ClientData *hdr,short length,
printk
(
"
\n
"
);
}
#ifdef CAREFUL_XMIT
#if 0
careful_xmit_wait(dev);
/* if we're not broadcasting, make sure the xmit was ack'd.
* if it wasn't, there is probably no card with that
* address... or else it missed our tx somehow.
*/
if (daddr && !(inb(STATUS)&TXACKflag))
{
BUGLVL(D_INIT)
printk("arcnet: transmit not acknowledged. (status=%Xh, daddr=%02Xh)\n",
inb(STATUS),daddr);
lp->stats.tx_errors++;
return -ENONET; /* "machine is not on the network" */
}
#endif
#ifdef VERIFY_ACK
lp
->
outgoing
.
lastload_dest
=
hdr
->
daddr
;
#endif
lp
->
txready
=
lp
->
txbuf
;
/* packet is ready for sending */
#if 0
#ifdef IRQ_XMIT
if (inb(STATUS)&TXFREEflag) arcnet_go_tx(dev);
#endif
#endif
}
/* Actually start transmitting a packet that was placed in the card's
* buffer by arcnetA_prepare_tx.
*/
static
void
arcnet_go_tx
(
struct
device
*
dev
)
arcnet
A
_go_tx
(
struct
device
*
dev
)
{
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
int
ioaddr
=
dev
->
base_addr
;
...
...
@@ -1334,25 +1396,176 @@ arcnet_go_tx(struct device *dev)
/* start sending */
outb
(
TXcmd
|
(
lp
->
txready
<<
3
),
COMMAND
);
#ifdef IRQ_XMIT
outb
(
TXFREEflag
|
NORXflag
,
INTMASK
);
#endif
outb
(
TXFREEflag
|
NORXflag
|
RECON_flag
,
INTMASK
);
dev
->
trans_start
=
jiffies
;
lp
->
txready
=
0
;
lp
->
sending
++
;
#ifdef VERIFY_ACK
lp
->
outgoing
.
lasttrans_dest
=
lp
->
outgoing
.
lastload_dest
;
lp
->
outgoing
.
lastload_dest
=
0
;
#endif
}
/* The typical workload of the driver:
Handle the network interface interrupts. */
/* Called by the kernel in order to transmit a "Windows" packet.
*/
static
int
arcnetW_send_packet
(
struct
sk_buff
*
skb
,
struct
device
*
dev
)
{
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
BUGLVL
(
D_DURING
)
printk
(
"%s: in arcnetW_send_packet (skb=%p)
\n
"
,
dev
->
name
,
skb
);
if
(
IF_TBUSY
)
{
/* If we get here, some higher level has decided we are broken.
There should really be a "kick me" function call instead. */
int
tickssofar
=
jiffies
-
dev
->
trans_start
;
if
(
tickssofar
<
10
)
return
1
;
printk
(
"%s: transmit timed out
\n
"
,
dev
->
name
);
/* Try to restart the adaptor. */
TBUSY
=
0
;
dev
->
trans_start
=
jiffies
;
return
0
;
}
/* If some higher layer thinks we've missed an tx-done interrupt
we are passed NULL. Caution: dev_tint() handles the cli()/sti()
itself. */
if
(
skb
==
NULL
)
{
dev_tint
(
dev
);
return
0
;
}
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
if
(
set_bit
(
0
,
(
void
*
)
&
dev
->
tbusy
)
!=
0
)
printk
(
"%s: Transmitter access conflict.
\n
"
,
dev
->
name
);
else
{
union
ArcPacket
*
arcpacket
=
(
union
ArcPacket
*
)(
dev
->
mem_start
+
512
*
(
lp
->
txbuf
^
1
));
u_char
*
arcsoft
,
daddr
;
short
offset
,
length
=
skb
->
len
+
1
;
TBUSY
=
1
;
if
(
length
>
XMTU
)
{
printk
(
"arcnet: MTU for %s and %s must be <= 493 for Windows protocol.
\n
"
,
lp
->
adev
->
name
,
lp
->
wdev
->
name
);
printk
(
"arcnet: transmit aborted.
\n
"
);
dev_kfree_skb
(
skb
,
FREE_WRITE
);
return
0
;
}
BUGLVL
(
D_DURING
)
printk
(
"arcnet: starting tx sequence...
\n
"
);
lp
->
txbuf
=
lp
->
txbuf
^
1
;
/* XOR with 1 to alternate btw 2 & 3 */
/* clean out the page to make debugging make more sense :) */
BUGLVL
(
D_DURING
)
memset
((
void
*
)
dev
->
mem_start
+
lp
->
txbuf
*
512
,
0x42
,
512
);
/* broadcasts have address FF:FF:FF:FF:FF:FF in etherspeak */
if
(((
struct
ethhdr
*
)(
skb
->
data
))
->
h_dest
[
0
]
==
0xFF
)
daddr
=
arcpacket
->
hardheader
.
destination
=
0
;
else
daddr
=
arcpacket
->
hardheader
.
destination
=
((
struct
ethhdr
*
)(
skb
->
data
))
->
h_dest
[
5
];
/* load packet into shared memory */
offset
=
512
-
length
;
if
(
length
>
MTU
)
/* long/exception packet */
{
if
(
length
<
MinTU
)
offset
-=
3
;
arcpacket
->
hardheader
.
offset1
=
0
;
arcpacket
->
hardheader
.
offset2
=
offset
;
}
else
/* short packet */
{
arcpacket
->
hardheader
.
offset1
=
(
offset
-=
256
);
}
BUGLVL
(
D_DURING
)
printk
(
"arcnet: length=%Xh, offset=%Xh, offset1=%Xh, offset2=%Xh
\n
"
,
length
,
offset
,
arcpacket
->
hardheader
.
offset1
,
arcpacket
->
hardheader
.
offset2
);
arcsoft
=&
arcpacket
->
raw
[
offset
];
arcsoft
[
0
]
=
ARC_P_MS_TCPIP
;
arcsoft
++
;
/* copy the packet into ARCnet shmem
* - the first bytes of ClientData header are skipped
*/
BUGLVL
(
D_DURING
)
printk
(
"arcnet: ready to memcpy
\n
"
);
memcpy
(
arcsoft
,
skb
->
data
,
skb
->
len
);
BUGLVL
(
D_DURING
)
printk
(
"arcnet: transmitting packet to station %02Xh (%d bytes)
\n
"
,
daddr
,
length
);
BUGLVL
(
D_TX
)
{
int
countx
,
county
;
printk
(
"arcnet: packet dump [tx] follows:"
);
for
(
county
=
0
;
county
<
16
+
(
length
>=
240
)
*
16
;
county
++
)
{
printk
(
"
\n
[%04X] "
,
county
*
16
);
for
(
countx
=
0
;
countx
<
16
;
countx
++
)
printk
(
"%02X "
,
arcpacket
->
raw
[
county
*
16
+
countx
]);
}
printk
(
"
\n
"
);
}
#ifdef VERIFY_ACK
lp
->
outgoing
.
lastload_dest
=
daddr
;
#endif
lp
->
txready
=
lp
->
txbuf
;
/* packet is ready for sending */
arcnetA_go_tx
(
dev
);
dev
->
trans_start
=
jiffies
;
}
dev_kfree_skb
(
skb
,
FREE_WRITE
);
return
0
;
}
/****************************************************************************
* *
* Interrupt handler *
* *
****************************************************************************/
/* The typical workload of the driver: Handle the network interface
* interrupts. This doesn't do much right now except call arcnet_inthandler,
* which takes different parameters but is sometimes called from other places
* as well.
*/
static
void
arcnet_interrupt
(
int
irq
,
struct
pt_regs
*
regs
)
{
struct
device
*
dev
=
(
struct
device
*
)(
irq2dev_map
[
irq
]);
if
(
dev
==
NULL
)
{
if
(
net_debug
>=
D_DURING
)
if
(
dev
==
NULL
||
!
dev
->
start
)
{
BUGLVL
(
D_EXTRA
)
printk
(
"arcnet: irq %d for unknown device.
\n
"
,
irq
);
return
;
}
...
...
@@ -1360,21 +1573,26 @@ arcnet_interrupt(int irq,struct pt_regs *regs)
arcnet_inthandler
(
dev
);
}
/* The actual interrupt handler routine - handle various IRQ's generated
* by the card.
*/
static
void
arcnet_inthandler
(
struct
device
*
dev
)
{
struct
arcnet_local
*
lp
;
int
ioaddr
,
status
,
boguscount
=
3
,
didsomething
;
if
(
dev
->
interrupt
)
printk
(
"arcnet: DRIVER PROBLEM! Nested arcnet interrupts!
\n
"
);
dev
->
interrupt
=
1
;
sti
();
ioaddr
=
dev
->
base_addr
;
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
#ifdef IRQ_XMIT
outb
(
0
,
INTMASK
);
#endif
sti
();
BUGLVL
(
D_DURING
)
printk
(
"arcnet: in net_interrupt (status=%Xh)
\n
"
,
inb
(
STATUS
));
...
...
@@ -1386,13 +1604,12 @@ arcnet_inthandler(struct device *dev)
if
(
!
dev
->
start
)
{
BUGLVL
(
D_
EXTRA
)
BUGLVL
(
D_
DURING
)
printk
(
"arcnet: ARCnet not yet initialized. irq ignored. (status=%Xh)
\n
"
,
status
);
#ifdef IRQ_XMIT
if
(
!
(
status
&
NORXflag
))
outb
(
NORXflag
,
INTMASK
);
#endif
outb
(
NORXflag
|
RECON_flag
,
INTMASK
);
dev
->
interrupt
=
0
;
return
;
}
...
...
@@ -1402,14 +1619,22 @@ arcnet_inthandler(struct device *dev)
*/
if
(
status
&
RESETflag
)
{
outb
(
CFLAGScmd
|
RESETclear
,
COMMAND
);
BUGLVL
(
D_INIT
)
printk
(
"arcnet: reset irq (status=%Xh)
\n
"
,
status
);
dev
->
interrupt
=
0
;
return
;
}
#ifdef DETECT_RECONFIGS
if
(
status
&
RECONflag
)
{
outb
(
CFLAGScmd
|
CONFIGclear
,
COMMAND
);
BUGLVL
(
D_EXTRA
)
printk
(
"arcnet: Network reconfiguration detected (status=%Xh)
\n
"
,
status
);
lp
->
stats
.
tx_carrier_errors
++
;
}
#endif
#if 1
/* yes, it's silly to disable this part but it makes good testing */
/* RX is inhibited - we must have received something. */
if
(
status
&
NORXflag
)
{
...
...
@@ -1427,8 +1652,7 @@ arcnet_inthandler(struct device *dev)
didsomething
++
;
}
#endif
#ifdef IRQ_XMIT
/* it can only be an xmit-done irq if we're xmitting :) */
if
(
status
&
TXFREEflag
&&
!
lp
->
in_txhandler
&&
lp
->
sending
)
{
...
...
@@ -1441,10 +1665,31 @@ arcnet_inthandler(struct device *dev)
printk
(
"arcnet: TX IRQ (stat=%Xh, numsegs=%d, segnum=%d, skb=%ph)
\n
"
,
status
,
out
->
numsegs
,
out
->
segnum
,
out
->
skb
);
#ifdef VERIFY_ACK
if
(
!
(
status
&
TXACKflag
))
{
if
(
lp
->
outgoing
.
lasttrans_dest
!=
0
)
{
BUGLVL
(
D_NORMAL
)
printk
(
"arcnet: transmit was not acknowledged! (status=%Xh, dest=%d)
\n
"
,
status
,
lp
->
outgoing
.
lasttrans_dest
);
lp
->
stats
.
tx_errors
++
;
}
else
{
BUGLVL
(
D_DURING
)
printk
(
"arcnet: broadcast was not acknowledged; that's normal (status=%Xh, dest=%d)
\n
"
,
status
,
lp
->
outgoing
.
lasttrans_dest
);
}
}
#endif
/* send packet if there is one */
if
(
lp
->
txready
)
{
arcnet_go_tx
(
dev
);
arcnet
A
_go_tx
(
dev
);
didsomething
++
;
}
...
...
@@ -1460,9 +1705,9 @@ arcnet_inthandler(struct device *dev)
printk
(
"arcnet: TX IRQ done: no split to continue.
\n
"
);
/* inform upper layers */
if
(
!
lp
->
txready
&&
dev
->
tbusy
)
if
(
!
lp
->
txready
&&
IF_TBUSY
)
{
dev
->
tbusy
=
0
;
TBUSY
=
0
;
mark_bh
(
NET_BH
);
}
...
...
@@ -1476,9 +1721,9 @@ arcnet_inthandler(struct device *dev)
* are done, then continue xmit.
*/
if
(
out
->
segnum
<
out
->
numsegs
)
arcnet_continue_tx
(
dev
);
arcnet
A
_continue_tx
(
dev
);
if
(
lp
->
txready
&&
!
lp
->
sending
)
arcnet_go_tx
(
dev
);
arcnet
A
_go_tx
(
dev
);
/* if segnum==numsegs, the transmission is finished;
* free the skb.
...
...
@@ -1492,9 +1737,9 @@ arcnet_inthandler(struct device *dev)
out
->
skb
=
NULL
;
/* inform upper layers */
if
(
!
lp
->
txready
&&
dev
->
tbusy
)
if
(
!
lp
->
txready
&&
IF_TBUSY
)
{
dev
->
tbusy
=
0
;
TBUSY
=
0
;
mark_bh
(
NET_BH
);
}
}
...
...
@@ -1502,47 +1747,50 @@ arcnet_inthandler(struct device *dev)
lp
->
in_txhandler
--
;
}
#endif
/* IRQ_XMIT */
}
while
(
--
boguscount
&&
didsomething
);
BUGLVL
(
D_DURING
)
printk
(
"arcnet: net_interrupt complete (status=%Xh)
\n
"
,
printk
(
"arcnet: net_interrupt complete (status=%Xh)
\n
\n
"
,
inb
(
STATUS
));
#ifdef IRQ_XMIT
if
(
dev
->
start
&&
lp
->
sending
)
outb
(
NORXflag
|
TXFREEflag
,
INTMASK
);
outb
(
NORXflag
|
TXFREEflag
|
RECON_flag
,
INTMASK
);
else
outb
(
NORXflag
,
INTMASK
);
#endif
outb
(
NORXflag
|
RECON_flag
,
INTMASK
);
dev
->
interrupt
=
0
;
}
/****************************************************************************
* *
* Receiver routines *
* *
****************************************************************************/
/* A packet has arrived; grab it from the buffers and possibly unsplit it.
* This is a generic packet receiver that calls arcnet??_rx depending on the
* protocol ID found.
*/
static
void
arcnet_rx
(
struct
device
*
dev
,
int
recbuf
)
{
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
int
ioaddr
=
dev
->
base_addr
;
/* int status = inb(STATUS);*/
struct
sk_buff
*
skb
;
union
ArcPacket
*
arcpacket
=
(
union
ArcPacket
*
)(
dev
->
mem_start
+
recbuf
*
512
);
struct
ClientData
*
soft
,
*
arcsoft
;
u_char
*
arcsoft
;
short
length
,
offset
;
u_char
pkttype
,
daddr
,
saddr
;
u_char
daddr
,
saddr
;
daddr
=
arcpacket
->
hardheader
.
destination
;
saddr
=
arcpacket
->
hardheader
.
source
;
daddr
=
arcpacket
->
hardheader
.
destination
;
/* if source is 0, it's
not
a "used" packet! */
/* if source is 0, it's a "used" packet! */
if
(
saddr
==
0
)
{
/*BUGLVL(D_DURING)*/
printk
(
"arcnet: discarding old packet. (status=%Xh)
\n
"
,
inb
(
STATUS
));
lp
->
stats
.
rx_errors
++
;
...
...
@@ -1553,30 +1801,91 @@ arcnet_rx(struct device *dev,int recbuf)
if
(
arcpacket
->
hardheader
.
offset1
)
/* Normal Packet */
{
offset
=
arcpacket
->
hardheader
.
offset1
;
arcsoft
=
(
struct
ClientData
*
)
(
&
arcpacket
->
raw
[
offset
-
EXTRA_CLIENTDATA
]);
length
=
256
-
offset
+
EXTRA_CLIENTDATA
;
pkttype
=
NORMAL
;
arcsoft
=&
arcpacket
->
raw
[
offset
];
length
=
256
-
offset
;
}
else
/* ExtendedPacket or ExceptionPacket */
{
offset
=
arcpacket
->
hardheader
.
offset2
;
arcsoft
=
(
struct
ClientData
*
)
(
&
arcpacket
->
raw
[
offset
-
EXTRA_CLIENTDATA
]);
arcsoft
=&
arcpacket
->
raw
[
offset
];
length
=
512
-
offset
;
}
BUGLVL
(
D_DURING
)
printk
(
"arcnet: received packet from %02Xh to %02Xh (%d bytes)
\n
"
,
saddr
,
daddr
,
length
);
/* call the right receiver for the protocol */
switch
(
arcsoft
[
0
])
{
case
ARC_P_IP
:
case
ARC_P_ARP
:
case
ARC_P_RARP
:
case
ARC_P_IPX
:
arcnetA_rx
(
dev
,(
struct
ClientData
*
)
arcsoft
,
length
,
saddr
,
daddr
);
break
;
case
ARC_P_MS_TCPIP
:
arcnetW_rx
(
dev
,
arcsoft
,
length
,
saddr
,
daddr
);
break
;
default:
printk
(
"arcnet: received unknown protocol %d (%Xh)
\n
"
,
arcsoft
[
0
],
arcsoft
[
0
]);
break
;
}
if
(
arcsoft
->
split_flag
!=
0xFF
)
/* Extended Packet */
BUGLVL
(
D_RX
)
{
length
=
512
-
offset
+
EXTRA_CLIENTDATA
;
pkttype
=
EXTENDED
;
int
countx
,
county
;
printk
(
"arcnet: rx packet dump follows:"
);
for
(
county
=
0
;
county
<
16
+
(
length
>
240
)
*
16
;
county
++
)
{
printk
(
"
\n
[%04X] "
,
county
*
16
);
for
(
countx
=
0
;
countx
<
16
;
countx
++
)
printk
(
"%02X "
,
arcpacket
->
raw
[
county
*
16
+
countx
]);
}
else
/* Exception Packet */
printk
(
"
\n
"
);
}
/* If any worth-while packets have been received, a mark_bh(NET_BH)
* has been done by netif_rx and Linux will handle them after we
* return.
*/
}
/* Packet receiver for "standard" RFC1201-style packets
*/
static
void
arcnetA_rx
(
struct
device
*
dev
,
struct
ClientData
*
arcsoft
,
int
length
,
u_char
saddr
,
u_char
daddr
)
{
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
struct
sk_buff
*
skb
;
struct
ClientData
*
soft
;
BUGLVL
(
D_DURING
)
printk
(
"arcnet: it's an RFC1201 packet (length=%d)
\n
"
,
length
);
arcsoft
=
(
struct
ClientData
*
)((
u_char
*
)
arcsoft
-
EXTRA_CLIENTDATA
);
length
+=
EXTRA_CLIENTDATA
;
if
(
arcsoft
->
split_flag
==
0xFF
)
/* Exception Packet */
{
BUGLVL
(
D_DURING
)
printk
(
"arcnet: compensating for exception packet
\n
"
);
/* skip over 4-byte junkola */
arcsoft
=
(
struct
ClientData
*
)
((
u_char
*
)
arcsoft
+
4
);
length
=
512
-
offset
+
EXTRA_CLIENTDATA
-
4
;
pkttype
=
EXCEPTION
;
}
length
-=
4
;
}
if
(
!
arcsoft
->
split_flag
)
/* not split */
...
...
@@ -1588,24 +1897,26 @@ arcnet_rx(struct device *dev,int recbuf)
if
(
in
->
skb
)
/* already assembling one! */
{
BUGLVL
(
D_
INIT
)
printk
(
"arcnet: aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)
\n
"
,
BUGLVL
(
D_
EXTRA
)
printk
(
"arcnet: aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)
\n
"
,
in
->
sequence
,
arcsoft
->
split_flag
,
arcsoft
->
sequence
);
kfree_skb
(
in
->
skb
,
FREE_WRITE
);
lp
->
stats
.
tx_dropped
++
;
lp
->
stats
.
rx_errors
++
;
in
->
skb
=
NULL
;
}
in
->
sequence
=
arcsoft
->
sequence
;
skb
=
dev_alloc_skb
(
length
);
skb
=
alloc_skb
(
length
,
GFP_ATOMIC
);
if
(
skb
==
NULL
)
{
printk
(
"%s: Memory squeeze, dropping packet.
\n
"
,
dev
->
name
);
printk
(
"arcnet: Memory squeeze, dropping packet.
\n
"
);
lp
->
stats
.
rx_dropped
++
;
return
;
}
soft
=
(
struct
ClientData
*
)
skb
_put
(
skb
,
length
)
;
soft
=
(
struct
ClientData
*
)
skb
->
data
;
skb
->
len
=
length
;
skb
->
dev
=
dev
;
memcpy
((
u_char
*
)
soft
+
EXTRA_CLIENTDATA
,
...
...
@@ -1614,30 +1925,10 @@ arcnet_rx(struct device *dev,int recbuf)
soft
->
daddr
=
daddr
;
soft
->
saddr
=
saddr
;
BUGLVL
(
D_DURING
)
printk
(
"arcnet: received packet from %02Xh to %02Xh (%d bytes, type=%d)
\n
"
,
saddr
,
daddr
,
length
,
pkttype
);
BUGLVL
(
D_RX
)
{
int
countx
,
county
;
printk
(
"arcnet: packet dump [rx-unsplit] follows:"
);
for
(
county
=
0
;
county
<
16
+
(
pkttype
!=
NORMAL
)
*
16
;
county
++
)
{
printk
(
"
\n
[%04X] "
,
county
*
16
);
for
(
countx
=
0
;
countx
<
16
;
countx
++
)
printk
(
"%02X "
,
arcpacket
->
raw
[
county
*
16
+
countx
]);
}
printk
(
"
\n
"
);
}
/* ARP packets have problems when sent from DOS.
* source address is always 0
! So we take the hardwar
e
*
source addr (which is impossible to fumble) and insert
* it ourselves.
* source address is always 0
on some systems! So we tak
e
*
the hardware source addr (which is impossible to fumble)
*
and insert
it ourselves.
*/
if
(
soft
->
protocol_id
==
ARC_P_ARP
)
{
...
...
@@ -1651,7 +1942,7 @@ arcnet_rx(struct device *dev,int recbuf)
if
(
!*
cptr
)
/* is saddr = 00? */
{
BUGLVL
(
D_
DURING
)
BUGLVL
(
D_
EXTRA
)
printk
(
"arcnet: ARP source address was 00h, set to %02Xh.
\n
"
,
saddr
);
*
cptr
=
saddr
;
...
...
@@ -1666,9 +1957,23 @@ arcnet_rx(struct device *dev,int recbuf)
{
printk
(
"arcnet: funny-shaped ARP packet. (%Xh, %Xh)
\n
"
,
arp
->
ar_hln
,
arp
->
ar_pln
);
lp
->
stats
.
rx_frame_errors
++
;
}
}
BUGLVL
(
D_SKB
)
{
short
i
;
for
(
i
=
0
;
i
<
skb
->
len
;
i
++
)
{
if
(
i
%
16
==
0
)
printk
(
"
\n
[%04hX] "
,
i
);
printk
(
"%02hX "
,((
unsigned
char
*
)
skb
->
data
)[
i
]);
}
skb
->
protocol
=
arc_type_trans
(
skb
,
dev
);
printk
(
"
\n
"
);
}
skb
->
protocol
=
arcnetA_type_trans
(
skb
,
dev
);
netif_rx
(
skb
);
lp
->
stats
.
rx_packets
++
;
}
...
...
@@ -1698,11 +2003,13 @@ arcnet_rx(struct device *dev,int recbuf)
if
(
in
->
skb
&&
in
->
sequence
!=
arcsoft
->
sequence
)
{
BUGLVL
(
D_
INIT
)
printk
(
"arcnet: wrong seq number, aborting assembly (expected=%d, seq=%d, splitflag=%d)
\n
"
,
BUGLVL
(
D_
EXTRA
)
printk
(
"arcnet: wrong seq number, aborting assembly (expected=%d, seq=%d, splitflag=%d)
\n
"
,
in
->
sequence
,
arcsoft
->
sequence
,
arcsoft
->
split_flag
);
kfree_skb
(
in
->
skb
,
FREE_WRITE
);
in
->
skb
=
NULL
;
lp
->
stats
.
tx_dropped
++
;
lp
->
stats
.
rx_fifo_errors
++
;
in
->
lastpacket
=
in
->
numpackets
=
0
;
}
...
...
@@ -1712,9 +2019,11 @@ arcnet_rx(struct device *dev,int recbuf)
arcsoft
->
split_flag
);
if
(
in
->
skb
)
/* already assembling one! */
{
BUGLVL
(
D_
INIT
)
printk
(
"arcnet: aborting previous (seq=%d) assembly (splitflag=%d, seq=%d)
\n
"
,
BUGLVL
(
D_
EXTRA
)
printk
(
"arcnet: aborting previous (seq=%d) assembly (splitflag=%d, seq=%d)
\n
"
,
in
->
sequence
,
arcsoft
->
split_flag
,
arcsoft
->
sequence
);
lp
->
stats
.
tx_dropped
++
;
lp
->
stats
.
rx_over_errors
++
;
kfree_skb
(
in
->
skb
,
FREE_WRITE
);
}
...
...
@@ -1724,14 +2033,15 @@ arcnet_rx(struct device *dev,int recbuf)
if
(
in
->
numpackets
>
16
)
{
printk
(
"arcnet: incoming packet more than 16 segments; dropping. (splitflag=%d)
\n
"
,
BUGLVL
(
D_EXTRA
)
printk
(
"arcnet: incoming packet more than 16 segments; dropping. (splitflag=%d)
\n
"
,
arcsoft
->
split_flag
);
lp
->
stats
.
rx_dropped
++
;
return
;
}
in
->
skb
=
skb
=
dev_alloc_skb
(
508
*
in
->
numpackets
+
sizeof
(
struct
ClientData
));
in
->
skb
=
skb
=
alloc_skb
(
508
*
in
->
numpackets
+
sizeof
(
struct
ClientData
),
GFP_ATOMIC
);
if
(
skb
==
NULL
)
{
printk
(
"%s: (split) memory squeeze, dropping packet.
\n
"
,
dev
->
name
);
...
...
@@ -1744,8 +2054,9 @@ arcnet_rx(struct device *dev,int recbuf)
*/
skb
->
free
=
1
;
soft
=
(
struct
ClientData
*
)
skb
_put
(
skb
,
sizeof
(
struct
ClientData
))
;
soft
=
(
struct
ClientData
*
)
skb
->
data
;
skb
->
len
=
sizeof
(
struct
ClientData
);
skb
->
dev
=
dev
;
memcpy
((
u_char
*
)
soft
+
EXTRA_CLIENTDATA
,
...
...
@@ -1762,8 +2073,9 @@ arcnet_rx(struct device *dev,int recbuf)
*/
if
(
!
in
->
skb
)
{
BUGLVL
(
D_
INIT
)
printk
(
"arcnet: can't continue split without starting first! (splitflag=%d, seq=%d)
\n
"
,
BUGLVL
(
D_
EXTRA
)
printk
(
"arcnet: can't continue split without starting first! (splitflag=%d, seq=%d)
\n
"
,
arcsoft
->
split_flag
,
arcsoft
->
sequence
);
lp
->
stats
.
rx_errors
++
;
return
;
}
...
...
@@ -1773,53 +2085,37 @@ arcnet_rx(struct device *dev,int recbuf)
/* harmless duplicate? ignore. */
if
(
packetnum
<=
in
->
lastpacket
-
1
)
{
BUGLVL
(
D_
INIT
)
printk
(
"arcnet: duplicate splitpacket ignored! (splitflag=%d)
\n
"
,
BUGLVL
(
D_
EXTRA
)
printk
(
"arcnet: duplicate splitpacket ignored! (splitflag=%d)
\n
"
,
arcsoft
->
split_flag
);
return
;
}
/* "bad" duplicate, kill reassembly */
BUGLVL
(
D_
INIT
)
printk
(
"arcnet: out-of-order splitpacket, reassembly (seq=%d) aborted (splitflag=%d, seq=%d)
\n
"
,
BUGLVL
(
D_
EXTRA
)
printk
(
"arcnet: out-of-order splitpacket, reassembly (seq=%d) aborted (splitflag=%d, seq=%d)
\n
"
,
in
->
sequence
,
arcsoft
->
split_flag
,
arcsoft
->
sequence
);
kfree_skb
(
in
->
skb
,
FREE_WRITE
);
in
->
skb
=
NULL
;
lp
->
stats
.
tx_dropped
++
;
lp
->
stats
.
rx_fifo_errors
++
;
in
->
lastpacket
=
in
->
numpackets
=
0
;
return
;
}
soft
=
(
struct
ClientData
*
)
skb
->
data
;
soft
=
(
struct
ClientData
*
)
in
->
skb
->
data
;
}
skb
=
in
->
skb
;
memcpy
(
skb
_put
(
skb
,
length
-
sizeof
(
struct
ClientData
))
,
memcpy
(
skb
->
data
+
skb
->
len
,
(
u_char
*
)
arcsoft
+
sizeof
(
struct
ClientData
),
length
-
sizeof
(
struct
ClientData
));
skb
->
len
+=
length
-
sizeof
(
struct
ClientData
);
soft
->
daddr
=
daddr
;
soft
->
saddr
=
saddr
;
BUGLVL
(
D_DURING
)
printk
(
"arcnet: received packet from %02Xh to %02Xh (%d bytes, type=%d)
\n
"
,
saddr
,
daddr
,
length
,
pkttype
);
BUGLVL
(
D_RX
)
{
int
countx
,
county
;
printk
(
"arcnet: packet dump [rx-split] follows:"
);
for
(
county
=
0
;
county
<
16
+
(
pkttype
!=
NORMAL
)
*
16
;
county
++
)
{
printk
(
"
\n
[%04X] "
,
county
*
16
);
for
(
countx
=
0
;
countx
<
16
;
countx
++
)
printk
(
"%02X "
,
arcpacket
->
raw
[
county
*
16
+
countx
]);
}
printk
(
"
\n
"
);
}
/* are we done? */
if
(
in
->
lastpacket
==
in
->
numpackets
)
{
...
...
@@ -1828,75 +2124,102 @@ arcnet_rx(struct device *dev,int recbuf)
skb
,
in
->
skb
);
in
->
skb
=
NULL
;
in
->
lastpacket
=
in
->
numpackets
=
0
;
skb
->
protocol
=
arc_type_trans
(
skb
,
dev
);
BUGLVL
(
D_SKB
)
{
short
i
;
for
(
i
=
0
;
i
<
skb
->
len
;
i
++
)
{
if
(
i
%
16
==
0
)
printk
(
"
\n
[%04hX] "
,
i
);
printk
(
"%02hX "
,((
unsigned
char
*
)
skb
->
data
)[
i
]);
}
printk
(
"
\n
"
);
}
skb
->
protocol
=
arcnetA_type_trans
(
skb
,
dev
);
netif_rx
(
skb
);
lp
->
stats
.
rx_packets
++
;
}
}
/* If any worth-while packets have been received, netif_rx()
has done a mark_bh(NET_BH) for us and will work on them
when we get to the bottom-half routine. */
}
#ifdef USE_TIMER_HANDLER
/* this function is called every once in a while to make sure the ARCnet
* isn't stuck.
*
* If we miss a receive IRQ, the receiver (and IRQ) is permanently disabled
* and we might never receive a packet again! This will check if this
* is the case, and if so, re-enable the receiver.
/* Packet receiver for non-standard Windows-style packets
*/
static
void
arcnet_timer
(
unsigned
long
arg
)
arcnetW_rx
(
struct
device
*
dev
,
u_char
*
arcsoft
,
int
length
,
u_char
saddr
,
u_char
daddr
)
{
struct
device
*
dev
=
(
struct
device
*
)
arg
;
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
short
ioaddr
=
dev
->
base_addr
;
int
status
=
inb
(
STATUS
);
struct
sk_buff
*
skb
;
/* if we didn't interrupt the IRQ handler, and RX's are still
* disabled, and we're not resetting the card... then we're stuck!
*/
if
(
!
dev
->
interrupt
&&
dev
->
start
&&
status
&
NORXflag
&&
!
status
&
RESETflag
)
{
BUGLVL
(
D_INIT
)
printk
(
"arcnet: timer: ARCnet was stuck! (status=%Xh)
\n
"
,
status
);
BUGLVL
(
D_DURING
)
printk
(
"arcnet: it's a Windows packet (length=%d)
\n
"
,
length
);
arcnet_inthandler
(
dev
);
skb
=
alloc_skb
(
length
,
GFP_ATOMIC
);
if
(
skb
==
NULL
)
{
printk
(
"arcnet: Memory squeeze, dropping packet.
\n
"
);
lp
->
stats
.
rx_dropped
++
;
return
;
}
/* requeue ourselves */
init_timer
(
&
lp
->
timer
);
lp
->
timer
.
expires
=
TIMERval
;
add_timer
(
&
lp
->
timer
);
skb
->
len
=
length
;
skb
->
dev
=
lp
->
wdev
;
memcpy
(
skb
->
data
,(
u_char
*
)
arcsoft
+
1
,
length
-
1
);
BUGLVL
(
D_SKB
)
{
short
i
;
printk
(
"arcnet: rx skb dump follows:
\n
"
);
for
(
i
=
0
;
i
<
skb
->
len
;
i
++
)
{
if
(
i
%
16
==
0
)
printk
(
"
\n
[%04hX] "
,
i
);
else
printk
(
"%02hX "
,((
u_char
*
)
skb
->
data
)[
i
]);
}
printk
(
"
\n
"
);
}
skb
->
protocol
=
eth_type_trans
(
skb
,
dev
);
netif_rx
(
skb
);
lp
->
stats
.
rx_packets
++
;
}
#endif
/****************************************************************************
* *
* Miscellaneous routines *
* *
****************************************************************************/
/* Get the current statistics. This may be called with the card open or
closed. */
* closed.
*/
static
struct
enet_statistics
*
arcnet_get_stats
(
struct
device
*
dev
)
{
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
/* short ioaddr = dev->base_addr;*/
return
&
lp
->
stats
;
}
/* Set or clear the multicast filter for this adaptor.
num_addrs == -1 Promiscuous mode, receive all packets
num_addrs == 0 Normal mode, clear multicast list
num_addrs > 0 Multicast mode, receive normal and MC packets, and do
best-effort filtering.
*
num_addrs == -1 Promiscuous mode, receive all packets
*
num_addrs == 0 Normal mode, clear multicast list
*
num_addrs > 0 Multicast mode, receive normal and MC packets, and do
*
best-effort filtering.
*/
static
void
set_multicast_list
(
struct
device
*
dev
,
int
num_addrs
,
void
*
addrs
)
{
#if 0 /* no promiscuous mode at all */
#if 0 /* no promiscuous mode at all
on most ARCnet models
*/
struct arcnet_local *lp=(struct arcnet_local *)(dev->priv);
short ioaddr = dev->base_addr;
...
...
@@ -1907,74 +2230,17 @@ set_multicast_list(struct device *dev, int num_addrs, void *addrs)
#endif
}
int
arcnet_reset
(
struct
device
*
dev
)
{
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
dev
->
priv
;
short
ioaddr
=
dev
->
base_addr
;
int
delayval
,
recbuf
=
lp
->
recbuf
;
outb
(
0
,
INTMASK
);
/* no IRQ's, please! */
BUGLVL
(
D_INIT
)
printk
(
"arcnet: Resetting %s (status=%Xh)
\n
"
,
dev
->
name
,
inb
(
STATUS
));
inb
(
RESET
);
/* Reset by reading this port */
JIFFER
(
RESETtime
);
outb
(
CFLAGScmd
|
RESETclear
,
COMMAND
);
/* clear flags & end reset */
outb
(
CFLAGScmd
|
CONFIGclear
,
COMMAND
);
/* after a reset, the first byte of shared mem is TESTvalue and the
* second byte is our 8-bit ARCnet address
*/
{
u_char
*
cardmem
=
(
u_char
*
)
dev
->
mem_start
;
if
(
cardmem
[
0
]
!=
TESTvalue
)
{
BUGLVL
(
D_INIT
)
printk
(
"arcnet: reset failed: TESTvalue not present.
\n
"
);
return
1
;
}
lp
->
arcnum
=
cardmem
[
1
];
/* save address for later use */
}
/* clear out status variables */
recbuf
=
lp
->
recbuf
=
0
;
lp
->
txbuf
=
2
;
/*dev->tbusy=0;*/
/* enable extended (512-byte) packets */
outb
(
CONFIGcmd
|
EXTconf
,
COMMAND
);
XJIFFER
(
ACKtime
);
/* clean out all the memory to make debugging make more sense :) */
BUGLVL
(
D_DURING
)
memset
((
void
*
)
dev
->
mem_start
,
0x42
,
2048
);
/* and enable receive of our first packet to the first buffer */
EnableReceiver
();
/* re-enable interrupts */
outb
(
NORXflag
,
INTMASK
);
/* done! return success. */
return
0
;
}
/*
* Create the ARCnet ClientData header for an arbitrary protocol layer
/* Create the ARCnet ClientData header for an arbitrary protocol layer
*
* saddr=NULL means use device source address (always will anyway)
* daddr=NULL means leave destination address (eg unresolved arp)
*/
int
arc_header
(
struct
sk_buff
*
skb
,
struct
device
*
dev
,
unsigned
short
type
,
int
arc
netA
_header
(
struct
sk_buff
*
skb
,
struct
device
*
dev
,
unsigned
short
type
,
void
*
daddr
,
void
*
saddr
,
unsigned
len
)
{
struct
ClientData
*
head
=
(
struct
ClientData
*
)
skb_push
(
skb
,
dev
->
hard_header_len
);
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)(
dev
->
priv
);
/* struct arcnet_local *lp=(struct arcnet_local *)(dev->priv);*/
/* set the protocol ID according to RFC-1201 */
switch
(
type
)
...
...
@@ -2000,18 +2266,18 @@ int arc_header(struct sk_buff *skb,struct device *dev,unsigned short type,
return
0
;
}
#if 1
/*
* Set the source hardware address.
* AVE: we can't do this, so we don't. Code below is directly
* stolen from eth.c driver and won't work.
** TM: but for debugging I would like to have saddr in the header
*
* This is pretty pointless for most purposes, but it can help
* in debugging. saddr is stored in the ClientData header and
* removed before sending the packet (since ARCnet does not allow
* us to change the source address in the actual packet sent)
*/
if
(
saddr
)
head
->
saddr
=
((
u_char
*
)
saddr
)[
0
];
else
head
->
saddr
=
((
u_char
*
)(
dev
->
dev_addr
))[
0
];
#endif
#if 0
/*
...
...
@@ -2028,7 +2294,7 @@ int arc_header(struct sk_buff *skb,struct device *dev,unsigned short type,
#endif
head
->
split_flag
=
0
;
/* split packets are done elsewhere */
head
->
sequence
=
(
lp
->
sequence
++
);
head
->
sequence
=
0
;
/* so are sequence numbers */
/* supposedly if daddr is NULL, we should ignore it... */
if
(
daddr
)
...
...
@@ -2043,18 +2309,17 @@ int arc_header(struct sk_buff *skb,struct device *dev,unsigned short type,
}
/*
* Rebuild the ARCnet ClientData header. This is called after an ARP
/* Rebuild the ARCnet ClientData header. This is called after an ARP
* (or in future other address resolution) has completed on this
* sk_buff. We now let ARP fill in the other fields.
*/
int
arc_rebuild_header
(
void
*
buff
,
struct
device
*
dev
,
unsigned
long
dst
,
int
arc
netA
_rebuild_header
(
void
*
buff
,
struct
device
*
dev
,
unsigned
long
dst
,
struct
sk_buff
*
skb
)
{
struct
ClientData
*
head
=
(
struct
ClientData
*
)
buff
;
/*
*
Only ARP/IP is
currently supported
*
Only ARP and IP are
currently supported
*/
if
(
head
->
protocol_id
!=
ARC_P_IP
)
...
...
@@ -2076,25 +2341,22 @@ int arc_rebuild_header(void *buff,struct device *dev,unsigned long dst,
#endif
}
/*
* Determine the packet's protocol ID.
/* Determine a packet's protocol ID.
*
* With ARCnet we have to convert everything to Ethernet-style stuff.
*/
unsigned
short
arc_type_trans
(
struct
sk_buff
*
skb
,
struct
device
*
dev
)
unsigned
short
arc
netA
_type_trans
(
struct
sk_buff
*
skb
,
struct
device
*
dev
)
{
struct
ClientData
*
head
=
(
struct
ClientData
*
)
skb
->
data
;
struct
arcnet_local
*
lp
=
(
struct
arcnet_local
*
)
(
dev
->
priv
);
/*
* Pull off the arcnet header.
*/
/* Pull off the arcnet header. */
skb
->
mac
.
raw
=
skb
->
data
;
skb_pull
(
skb
,
dev
->
hard_header_len
);
if
(
head
->
daddr
==
0
)
skb
->
pkt_type
=
PACKET_BROADCAST
;
else
if
(
dev
->
flags
&
IFF_PROMISC
)
else
if
(
dev
->
flags
&
IFF_PROMISC
)
{
/* if we're not sending to ourselves :) */
if
(
head
->
daddr
!=
dev
->
dev_addr
[
0
])
...
...
@@ -2108,20 +2370,31 @@ unsigned short arc_type_trans(struct sk_buff *skb,struct device *dev)
case
ARC_P_ARP
:
return
htons
(
ETH_P_ARP
);
case
ARC_P_RARP
:
return
htons
(
ETH_P_RARP
);
case
ARC_P_IPX
:
return
htons
(
ETH_P_IPX
);
case
ARC_P_ATALK
:
return
htons
(
ETH_P_ATALK
);
/* Doesn't work yet
*/
case
ARC_P_ATALK
:
return
htons
(
ETH_P_ATALK
);
/* untested appletalk
*/
case
ARC_P_LANSOFT
:
/* don't understand. fall through. */
default:
BUGLVL
(
D_
DURING
)
BUGLVL
(
D_
EXTRA
)
printk
(
"arcnet: received packet of unknown protocol id %d (%Xh)
\n
"
,
head
->
protocol_id
,
head
->
protocol_id
);
lp
->
stats
.
rx_frame_errors
++
;
return
0
;
}
return
htons
(
ETH_P_IP
);
}
/****************************************************************************
* *
* Kernel Loadable Module Support *
* *
****************************************************************************/
#ifdef MODULE
char
kernel_version
[]
=
UTS_RELEASE
;
static
struct
device
this
ARCnet
=
{
static
struct
device
this
card
=
{
" "
,
/* if blank, device name inserted by /linux/drivers/net/net_init.c */
0
,
0
,
0
,
0
,
0
,
0
,
/* I/O address, IRQ */
...
...
@@ -2129,29 +2402,29 @@ static struct device thisARCnet = {
int
io
=
0x0
;
/* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
int
irqnum
=
0
;
/* or use the insmod io= irq= shmem= options */
int
irqnum
=
0
;
/* or use the insmod io= irq
num
= shmem= options */
int
shmem
=
0
;
int
num
=
0
;
/* number of device (ie for
arc0, arc1, arc2
...) */
int
num
=
0
;
/* number of device (ie for
0 for arc0, 1 for arc1
...) */
int
init_module
(
void
)
{
sprintf
(
this
ARCnet
.
name
,
"arc%d"
,
num
);
sprintf
(
this
card
.
name
,
"arc%d"
,
num
);
this
ARCnet
.
base_addr
=
io
;
this
card
.
base_addr
=
io
;
this
ARCnet
.
irq
=
irqnum
;
if
(
this
ARCnet
.
irq
==
2
)
thisARCnet
.
irq
=
9
;
this
card
.
irq
=
irqnum
;
if
(
this
card
.
irq
==
2
)
thiscard
.
irq
=
9
;
if
(
shmem
)
{
this
ARCnet
.
mem_start
=
shmem
;
this
ARCnet
.
mem_end
=
thisARCnet
.
mem_start
+
512
*
4
-
1
;
this
ARCnet
.
rmem_start
=
thisARCnet
.
mem_start
+
512
*
0
;
this
ARCnet
.
rmem_end
=
thisARCnet
.
mem_start
+
512
*
2
-
1
;
this
card
.
mem_start
=
shmem
;
this
card
.
mem_end
=
thiscard
.
mem_start
+
512
*
4
-
1
;
this
card
.
rmem_start
=
thiscard
.
mem_start
+
512
*
0
;
this
card
.
rmem_end
=
thiscard
.
mem_start
+
512
*
2
-
1
;
}
if
(
register_netdev
(
&
this
ARCnet
)
!=
0
)
if
(
register_netdev
(
&
this
card
)
!=
0
)
return
-
EIO
;
return
0
;
}
...
...
@@ -2159,14 +2432,17 @@ init_module(void)
void
cleanup_module
(
void
)
{
if
(
MOD_IN_USE
)
{
printk
(
"%s: device busy, remove delayed
\n
"
,
thisARCnet
.
name
);
}
else
{
if
(
thisARCnet
.
start
)
arcnet_close
(
&
thisARCnet
);
if
(
thisARCnet
.
irq
)
free_irq
(
thisARCnet
.
irq
);
if
(
thisARCnet
.
base_addr
)
release_region
(
thisARCnet
.
base_addr
,
ETHERCARD_TOTAL_SIZE
);
unregister_netdev
(
&
thisARCnet
);
if
(
MOD_IN_USE
)
{
printk
(
"%s: device busy, remove delayed
\n
"
,
thiscard
.
name
);
}
else
{
if
(
thiscard
.
start
)
arcnet_close
(
&
thiscard
);
if
(
thiscard
.
irq
)
free_irq
(
thiscard
.
irq
);
if
(
thiscard
.
base_addr
)
release_region
(
thiscard
.
base_addr
,
ARCNET_TOTAL_SIZE
);
unregister_netdev
(
&
thiscard
);
}
}
...
...
@@ -2176,10 +2452,10 @@ cleanup_module(void)
/*
* Local variables:
* compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c
skeleton
.c"
* compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c
arcnet
.c"
* version-control: t
* kept-new-versions: 5
* tab-width:
4
* tab-width:
8
* End:
*/
drivers/net/eql.c
View file @
bb9c5bf1
...
...
@@ -249,7 +249,7 @@ eql_init(struct device *dev)
dev
->
pa_addr
=
0
;
dev
->
pa_brdaddr
=
0
;
dev
->
pa_mask
=
0
;
dev
->
pa_alen
=
sizeof
(
unsigned
long
)
;
dev
->
pa_alen
=
4
;
dev
->
type
=
ARPHRD_SLIP
;
...
...
drivers/net/loopback.c
View file @
bb9c5bf1
...
...
@@ -139,7 +139,7 @@ int loopback_init(struct device *dev)
dev
->
pa_addr
=
in_aton
(
"127.0.0.1"
);
dev
->
pa_brdaddr
=
in_aton
(
"127.255.255.255"
);
dev
->
pa_mask
=
in_aton
(
"255.0.0.0"
);
dev
->
pa_alen
=
sizeof
(
unsigned
long
)
;
dev
->
pa_alen
=
4
;
#endif
dev
->
priv
=
kmalloc
(
sizeof
(
struct
enet_statistics
),
GFP_KERNEL
);
memset
(
dev
->
priv
,
0
,
sizeof
(
struct
enet_statistics
));
...
...
drivers/net/net_init.c
View file @
bb9c5bf1
...
...
@@ -194,6 +194,7 @@ void ether_setup(struct device *dev)
dev
->
hard_header
=
eth_header
;
dev
->
rebuild_header
=
eth_rebuild_header
;
dev
->
set_mac_address
=
eth_mac_addr
;
dev
->
header_cache
=
eth_header_cache
;
dev
->
type
=
ARPHRD_ETHER
;
dev
->
hard_header_len
=
ETH_HLEN
;
...
...
@@ -209,7 +210,7 @@ void ether_setup(struct device *dev)
dev
->
pa_addr
=
0
;
dev
->
pa_brdaddr
=
0
;
dev
->
pa_mask
=
0
;
dev
->
pa_alen
=
sizeof
(
unsigned
long
)
;
dev
->
pa_alen
=
4
;
}
#ifdef CONFIG_TR
...
...
@@ -239,7 +240,7 @@ void tr_setup(struct device *dev)
dev
->
pa_addr
=
0
;
dev
->
pa_brdaddr
=
0
;
dev
->
pa_mask
=
0
;
dev
->
pa_alen
=
sizeof
(
unsigned
long
)
;
dev
->
pa_alen
=
4
;
}
#endif
...
...
drivers/net/pi2.c
View file @
bb9c5bf1
...
...
@@ -1442,7 +1442,7 @@ static int pi_probe(struct device *dev, int card_type)
dev
->
pa_addr
=
0
;
dev
->
pa_brdaddr
=
0
;
dev
->
pa_mask
=
0
;
dev
->
pa_alen
=
sizeof
(
unsigned
long
)
;
dev
->
pa_alen
=
4
;
return
0
;
}
...
...
drivers/net/ppp.c
View file @
bb9c5bf1
...
...
@@ -295,7 +295,7 @@ ppp_init(struct device *dev)
dev
->
pa_addr
=
0
;
dev
->
pa_brdaddr
=
0
;
dev
->
pa_mask
=
0
;
dev
->
pa_alen
=
sizeof
(
unsigned
long
)
;
dev
->
pa_alen
=
4
;
return
0
;
}
...
...
@@ -1144,7 +1144,7 @@ ppp_do_ip (struct ppp *ppp, unsigned short proto, unsigned char *c,
sendit:
if
(
ppp_debug_netpackets
)
{
struct
iphdr
*
iph
=
(
struct
iphdr
*
)
c
;
PRINTK
((
KERN_INFO
"%s <-- src %
lx dst %l
x len %d
\n
"
,
ppp
->
dev
->
name
,
PRINTK
((
KERN_INFO
"%s <-- src %
x dst %
x len %d
\n
"
,
ppp
->
dev
->
name
,
iph
->
saddr
,
iph
->
daddr
,
count
))
}
...
...
@@ -1251,9 +1251,8 @@ ppp_read(struct tty_struct *tty, struct file *file, unsigned char *buf, unsigned
CHECK_PPP
(
-
ENXIO
);
PRINTKN
(
4
,(
KERN_DEBUG
"ppp_read: called %x num %u
\n
"
,
(
unsigned
int
)
buf
,
nr
));
PRINTKN
(
4
,(
KERN_DEBUG
"ppp_read: called %p num %u
\n
"
,
buf
,
nr
));
do
{
/* try to acquire read lock */
...
...
@@ -1323,8 +1322,8 @@ ppp_stuff_char(struct ppp *ppp, unsigned char c)
{
int
curpt
=
ppp
->
xhead
-
ppp
->
xbuff
;
if
((
curpt
<
0
)
||
(
curpt
>
3000
))
{
PRINTK
((
KERN_DEBUG
"ppp_stuff_char: %
x %x
%d
\n
"
,
(
unsigned
int
)
ppp
->
xbuff
,
(
unsigned
int
)
ppp
->
xhead
,
curpt
))
PRINTK
((
KERN_DEBUG
"ppp_stuff_char: %
p %p
%d
\n
"
,
ppp
->
xbuff
,
ppp
->
xhead
,
curpt
))
}
if
(
in_xmap
(
ppp
,
c
))
{
*
ppp
->
xhead
++
=
PPP_ESC
;
...
...
@@ -1402,8 +1401,8 @@ ppp_write(struct tty_struct *tty, struct file *file, unsigned char *buf, unsigne
if
(
ppp_debug
>=
6
)
ppp_print_buffer
(
"xmit buffer"
,
ppp
->
xbuff
,
ppp
->
xhead
-
ppp
->
xbuff
,
KERNEL_DS
);
else
{
PRINTKN
(
4
,(
KERN_DEBUG
"ppp_write: writing %d chars
\n
"
,
ppp
->
xhead
-
ppp
->
xbuff
));
PRINTKN
(
4
,(
KERN_DEBUG
"ppp_write: writing %d chars
\n
"
,
(
int
)
(
ppp
->
xhead
-
ppp
->
xbuff
)
));
}
/* packet is ready-to-go */
...
...
@@ -1471,7 +1470,7 @@ ppp_ioctl(struct tty_struct *tty, struct file *file, unsigned int i,
if
(
error
==
0
)
{
put_user
(
ppp
->
xmit_async_map
[
0
],
(
int
*
)
l
);
PRINTKN
(
3
,(
KERN_INFO
"ppp_ioctl: get asyncmap: addr %lx asyncmap %lx
\n
"
,
l
,
ppp
->
xmit_async_map
[
0
]));
l
,
(
unsigned
long
)
ppp
->
xmit_async_map
[
0
]));
}
break
;
...
...
@@ -1482,7 +1481,7 @@ ppp_ioctl(struct tty_struct *tty, struct file *file, unsigned int i,
bset
(
ppp
->
xmit_async_map
,
PPP_FLAG
);
bset
(
ppp
->
xmit_async_map
,
PPP_ESC
);
PRINTKN
(
3
,(
KERN_INFO
"ppp_ioctl: set xmit asyncmap %lx
\n
"
,
ppp
->
xmit_async_map
[
0
]));
(
unsigned
long
)
ppp
->
xmit_async_map
[
0
]));
}
break
;
...
...
@@ -1491,7 +1490,7 @@ ppp_ioctl(struct tty_struct *tty, struct file *file, unsigned int i,
if
(
error
==
0
)
{
ppp
->
recv_async_map
=
get_user
((
int
*
)
l
);
PRINTKN
(
3
,(
KERN_INFO
"ppp_ioctl: set recv asyncmap %lx
\n
"
,
ppp
->
recv_async_map
));
(
unsigned
long
)
ppp
->
recv_async_map
));
}
break
;
...
...
@@ -1573,7 +1572,7 @@ ppp_ioctl(struct tty_struct *tty, struct file *file, unsigned int i,
error
=
verify_area
(
VERIFY_READ
,
(
void
*
)
l
,
sizeof
(
ppp
->
xmit_async_map
));
if
(
error
==
0
)
{
unsigned
long
temp_tbl
[
8
];
__u32
temp_tbl
[
8
];
memcpy_fromfs
(
temp_tbl
,
(
void
*
)
l
,
sizeof
(
ppp
->
xmit_async_map
));
temp_tbl
[
1
]
=
0x00000000
;
/* must not escape 0x20 - 0x3f */
...
...
@@ -1831,8 +1830,8 @@ ppp_xmit(struct sk_buff *skb, struct device *dev)
if
(
ppp_debug
>=
6
)
ppp_print_buffer
(
"xmit buffer"
,
ppp
->
xbuff
,
ppp
->
xhead
-
ppp
->
xbuff
,
KERNEL_DS
);
else
{
PRINTKN
(
4
,(
KERN_DEBUG
"ppp_write: writing %d chars
\n
"
,
ppp
->
xhead
-
ppp
->
xbuff
));
PRINTKN
(
4
,(
KERN_DEBUG
"ppp_write: writing %d chars
\n
"
,
(
int
)
(
ppp
->
xhead
-
ppp
->
xbuff
)
));
}
ppp_kick_tty
(
ppp
);
...
...
drivers/net/slip.c
View file @
bb9c5bf1
...
...
@@ -1141,7 +1141,7 @@ slip_init(struct device *dev)
dev
->
pa_addr
=
0
;
dev
->
pa_brdaddr
=
0
;
dev
->
pa_mask
=
0
;
dev
->
pa_alen
=
sizeof
(
unsigned
long
)
;
dev
->
pa_alen
=
4
;
return
0
;
}
...
...
drivers/net/tunnel.c
View file @
bb9c5bf1
...
...
@@ -244,7 +244,9 @@ print_ip(iph);
#ifdef TUNNEL_DEBUG
printk
(
"tunnel: calling ip_forward()
\n
"
);
#endif
ip_forward
(
skb2
,
dev
,
0
,
iph
->
daddr
,
0
);
if
(
ip_forward
(
skb2
,
dev
,
0
,
iph
->
daddr
,
0
))
kfree_skb
(
skb2
,
FREE_WRITE
);
#ifdef TUNNEL_DEBUG
printk
(
"Packet sent through tunnel interface!
\n
"
);
...
...
@@ -255,8 +257,6 @@ print_ip(iph);
#ifdef TUNNEL_DEBUG
printk
(
"tunnel: Updated usage statistics.
\n
"
);
#endif
/* Clean up and return okay. */
kfree_skb
(
skb2
,
FREE_WRITE
);
dev
->
tbusy
=
0
;
return
0
;
}
...
...
drivers/scsi/scsi_proc.c
View file @
bb9c5bf1
...
...
@@ -105,7 +105,6 @@ int generic_proc_info(char *buffer, char **start, off_t offset,
extern
int
dispatch_scsi_info
(
int
ino
,
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
func
)
{
int
retval
;
struct
Scsi_Host
*
hpnt
=
scsi_hostlist
;
if
(
func
!=
2
)
{
...
...
drivers/sound/pas2_card.c
View file @
bb9c5bf1
...
...
@@ -57,6 +57,7 @@ static char *pas_model_names[] =
/*
* to support other than the default base address
*/
extern
void
mix_write
(
unsigned
char
data
,
int
ioaddr
);
unsigned
char
pas_read
(
int
ioaddr
)
...
...
@@ -367,7 +368,7 @@ attach_pas_card (long mem_start, struct address_info *hw_config)
if
(
detect_pas_hw
(
hw_config
))
{
if
(
pas_model
=
pas_read
(
CHIP_REV
))
if
(
(
pas_model
=
pas_read
(
CHIP_REV
)
))
{
printk
(
" <%s rev %d>"
,
pas_model_names
[(
int
)
pas_model
],
pas_read
(
BOARD_REV_ID
));
}
...
...
drivers/sound/sound_config.h
View file @
bb9c5bf1
...
...
@@ -103,6 +103,10 @@
#define FM_MONO 0x388
/* This is the I/O address used by AdLib */
#ifndef PAS_BASE
#define PAS_BASE 0x388
#endif
/* SEQ_MAX_QUEUE is the maximum number of sequencer events buffered by the
driver. (There is no need to alter this) */
#define SEQ_MAX_QUEUE 1024
...
...
fs/ext2/namei.c
View file @
bb9c5bf1
...
...
@@ -766,7 +766,7 @@ int ext2_symlink (struct inode * dir, const char * name, int len,
for
(
l
=
0
;
l
<
inode
->
i_sb
->
s_blocksize
-
1
&&
symname
[
l
];
l
++
)
;
if
(
l
>=
EXT2_N_BLOCKS
*
sizeof
(
__u32
))
{
if
(
l
>=
sizeof
(
inode
->
u
.
ext2_i
.
i_data
))
{
ext2_debug
(
"l=%d, normal symlink
\n
"
,
l
);
...
...
include/asm-alpha/a.out.h
View file @
bb9c5bf1
#ifndef __ALPHA_A_OUT_H__
#define __ALPHA_A_OUT_H__
/* OSF/1 pseudo-a.out header */
/*
* OSF/1 ECOFF header structs. ECOFF files consist of:
* - a file header (struct filehdr),
* - an a.out header (struct aouthdr),
* - one or more section headers (struct scnhdr).
* The filhdr's "f_nscns" field contains the
* number of section headers.
*/
struct
filehdr
{
/* OSF/1 "file" header */
__u16
f_magic
,
f_nscns
;
__u32
f_timdat
;
__u64
f_symptr
;
__u32
f_nsyms
;
__u16
f_opthdr
,
f_flags
;
};
struct
aouthdr
{
__u64
info
;
/* after that it looks quite normal.. */
__u64
tsize
;
__u64
dsize
;
__u64
bsize
;
__u64
entry
;
__u64
text_start
;
/* with a few additions that actually make sense */
__u64
data_start
;
__u64
bss_start
;
__u32
gprmask
,
fprmask
;
/* but what are these? */
__u64
gpvalue
;
};
struct
scnhdr
{
char
s_name
[
8
];
__u64
s_paddr
;
__u64
s_vaddr
;
__u64
s_size
;
__u64
s_scnptr
;
__u64
s_relptr
;
__u64
s_lnnoptr
;
__u16
s_nreloc
;
__u16
s_nlnno
;
__u32
s_flags
;
};
struct
exec
{
/* OSF/1 "file" header */
unsigned
short
f_magic
,
f_nscns
;
unsigned
int
f_timdat
;
unsigned
long
f_symptr
;
unsigned
int
f_nsyms
;
unsigned
short
f_opthdr
,
f_flags
;
/* followed by a more normal "a.out" header */
unsigned
long
a_info
;
/* after that it looks quite normal.. */
unsigned
long
a_text
;
unsigned
long
a_data
;
unsigned
long
a_bss
;
unsigned
long
a_entry
;
unsigned
long
a_textstart
;
/* with a few additions that actually make sense */
unsigned
long
a_datastart
;
unsigned
long
a_bssstart
;
unsigned
int
a_gprmask
,
a_fprmask
;
/* but what are these? */
unsigned
long
a_gpvalue
;
struct
filehdr
fh
;
struct
aouthdr
ah
;
};
/*
* Define's so that the kernel exec code can access the a.out header
* fields...
*/
#define a_info ah.info
#define a_text ah.tsize
#define a_data ah.dsize
#define a_bss ah.bsize
#define a_entry ah.entry
#define a_textstart ah.text_start
#define a_datastart ah.data_start
#define a_bssstart ah.bss_start
#define a_gprmask ah.gprmask
#define a_fprmask ah.fprmask
#define a_gpvalue ah.gpvalue
#define N_TXTADDR(x) ((x).a_textstart)
#define N_DATADDR(x) ((x).a_datastart)
#define N_BSSADDR(x) ((x).a_bssstart)
...
...
@@ -29,12 +78,13 @@ struct exec
#define N_TRSIZE(x) 0
#define N_SYMSIZE(x) 0
#define SCNHSZ 64
/* XXX should be sizeof(scnhdr) */
#define AOUTHSZ sizeof(struct aouthdr)
#define SCNHSZ sizeof(struct scnhdr)
#define SCNROUND 16
#define N_TXTOFF(x) \
((long) N_MAGIC(x) == ZMAGIC ? 0 : \
(sizeof(struct exec) + (x).f_nscns*SCNHSZ + SCNROUND - 1) & ~(SCNROUND - 1))
(sizeof(struct exec) + (x).f
h.f
_nscns*SCNHSZ + SCNROUND - 1) & ~(SCNROUND - 1))
#ifdef __KERNEL__
...
...
include/asm-alpha/lca.h
View file @
bb9c5bf1
...
...
@@ -304,8 +304,15 @@ extern void writew(unsigned short b, unsigned long addr);
#define inb_p inb
#define outb_p outb
#define readl(addr) __readl(addr)
#define writel(b,addr) __writel(b,addr)
extern
inline
unsigned
long
readl
(
unsigned
long
addr
)
{
return
__readl
(
addr
);
}
extern
inline
void
writel
(
unsigned
int
b
,
unsigned
long
addr
)
{
__writel
(
b
,
addr
);
}
#undef vuip
...
...
include/asm-alpha/termios.h
View file @
bb9c5bf1
...
...
@@ -333,4 +333,59 @@ struct termios {
#define N_MOUSE 2
#define N_PPP 3
#endif
#ifdef __KERNEL__
/*
* Translate a "termio" structure into a "termios". Ugh.
*/
extern
inline
void
trans_from_termio
(
struct
termio
*
termio
,
struct
termios
*
termios
)
{
#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y))
SET_LOW_BITS
(
termios
->
c_iflag
,
termio
->
c_iflag
);
SET_LOW_BITS
(
termios
->
c_oflag
,
termio
->
c_oflag
);
SET_LOW_BITS
(
termios
->
c_cflag
,
termio
->
c_cflag
);
SET_LOW_BITS
(
termios
->
c_lflag
,
termio
->
c_lflag
);
#undef SET_LOW_BITS
termios
->
c_cc
[
VINTR
]
=
termio
->
c_cc
[
_VINTR
];
termios
->
c_cc
[
VQUIT
]
=
termio
->
c_cc
[
_VQUIT
];
termios
->
c_cc
[
VERASE
]
=
termio
->
c_cc
[
_VERASE
];
termios
->
c_cc
[
VKILL
]
=
termio
->
c_cc
[
_VKILL
];
termios
->
c_cc
[
VEOF
]
=
termio
->
c_cc
[
_VEOF
];
termios
->
c_cc
[
VMIN
]
=
termio
->
c_cc
[
_VMIN
];
termios
->
c_cc
[
VEOL
]
=
termio
->
c_cc
[
_VEOL
];
termios
->
c_cc
[
VTIME
]
=
termio
->
c_cc
[
_VTIME
];
termios
->
c_cc
[
VEOL2
]
=
termio
->
c_cc
[
_VEOL2
];
termios
->
c_cc
[
VSWTC
]
=
termio
->
c_cc
[
_VSWTC
];
}
/*
* Translate a "termios" structure into a "termio". Ugh.
*
* Note the "fun" _VMIN overloading.
*/
extern
inline
void
trans_to_termio
(
struct
termios
*
termios
,
struct
termio
*
termio
)
{
termio
->
c_iflag
=
termios
->
c_iflag
;
termio
->
c_oflag
=
termios
->
c_oflag
;
termio
->
c_cflag
=
termios
->
c_cflag
;
termio
->
c_lflag
=
termios
->
c_lflag
;
termio
->
c_line
=
termios
->
c_line
;
termio
->
c_cc
[
_VINTR
]
=
termios
->
c_cc
[
VINTR
];
termio
->
c_cc
[
_VQUIT
]
=
termios
->
c_cc
[
VQUIT
];
termio
->
c_cc
[
_VERASE
]
=
termios
->
c_cc
[
VERASE
];
termio
->
c_cc
[
_VKILL
]
=
termios
->
c_cc
[
VKILL
];
termio
->
c_cc
[
_VEOF
]
=
termios
->
c_cc
[
VEOF
];
termio
->
c_cc
[
_VEOL
]
=
termios
->
c_cc
[
VEOL
];
termio
->
c_cc
[
_VEOL2
]
=
termios
->
c_cc
[
VEOL2
];
termio
->
c_cc
[
_VSWTC
]
=
termios
->
c_cc
[
VSWTC
];
if
(
!
(
termios
->
c_lflag
&
ICANON
))
{
termio
->
c_cc
[
_VMIN
]
=
termios
->
c_cc
[
VMIN
];
termio
->
c_cc
[
_VTIME
]
=
termios
->
c_cc
[
VTIME
];
}
}
#endif
/* __KERNEL__ */
#endif
/* _ALPHA_TERMIOS_H */
include/asm-i386/termios.h
View file @
bb9c5bf1
...
...
@@ -263,4 +263,37 @@ struct termios {
#define N_MOUSE 2
#define N_PPP 3
#endif
#ifdef __KERNEL__
/*
* Translate a "termio" structure into a "termios". Ugh.
*/
extern
inline
void
trans_from_termio
(
struct
termio
*
termio
,
struct
termios
*
termios
)
{
#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y))
SET_LOW_BITS
(
termios
->
c_iflag
,
termio
->
c_iflag
);
SET_LOW_BITS
(
termios
->
c_oflag
,
termio
->
c_oflag
);
SET_LOW_BITS
(
termios
->
c_cflag
,
termio
->
c_cflag
);
SET_LOW_BITS
(
termios
->
c_lflag
,
termio
->
c_lflag
);
#undef SET_LOW_BITS
memcpy
(
termios
->
c_cc
,
termio
->
c_cc
,
NCC
);
}
/*
* Translate a "termios" structure into a "termio". Ugh.
*/
extern
inline
void
trans_to_termio
(
struct
termios
*
termios
,
struct
termio
*
termio
)
{
termio
->
c_iflag
=
termios
->
c_iflag
;
termio
->
c_oflag
=
termios
->
c_oflag
;
termio
->
c_cflag
=
termios
->
c_cflag
;
termio
->
c_lflag
=
termios
->
c_lflag
;
termio
->
c_line
=
termios
->
c_line
;
memcpy
(
termio
->
c_cc
,
termios
->
c_cc
,
NCC
);
}
#endif
/* __KERNEL__ */
#endif
/* _I386_TERMIOS_H */
include/linux/etherdevice.h
View file @
bb9c5bf1
...
...
@@ -34,8 +34,10 @@ extern int eth_header(struct sk_buff *skb, struct device *dev,
extern
int
eth_rebuild_header
(
void
*
buff
,
struct
device
*
dev
,
unsigned
long
dst
,
struct
sk_buff
*
skb
);
extern
unsigned
short
eth_type_trans
(
struct
sk_buff
*
skb
,
struct
device
*
dev
);
extern
void
eth_header_cache
(
struct
device
*
dev
,
struct
sock
*
sk
,
unsigned
long
saddr
,
unsigned
long
daddr
);
extern
void
eth_copy_and_sum
(
struct
sk_buff
*
dest
,
unsigned
char
*
src
,
int
length
,
int
base
);
extern
void
eth_header_cache
(
struct
device
*
dev
,
struct
sock
*
sk
,
unsigned
long
saddr
,
unsigned
long
daddr
);
#endif
...
...
include/linux/fdreg.h
View file @
bb9c5bf1
...
...
@@ -44,7 +44,7 @@
#define ST0_DS 0x03
/* drive select mask */
#define ST0_HA 0x04
/* Head (Address) */
#define ST0_NR 0x08
/* Not Ready */
#define ST0_ECE 0x10
/* Equipment chec
h
error */
#define ST0_ECE 0x10
/* Equipment chec
k
error */
#define ST0_SE 0x20
/* Seek end */
#define ST0_INTR 0xC0
/* Interrupt code mask */
...
...
include/linux/icmp.h
View file @
bb9c5bf1
...
...
@@ -59,15 +59,15 @@
struct
icmphdr
{
unsigned
char
type
;
unsigned
char
code
;
unsigned
short
checksum
;
__u8
type
;
__u8
code
;
__u16
checksum
;
union
{
struct
{
unsigned
short
id
;
unsigned
short
sequence
;
__u16
id
;
__u16
sequence
;
}
echo
;
unsigned
long
gateway
;
__u32
gateway
;
}
un
;
};
...
...
include/linux/if_ppp.h
View file @
bb9c5bf1
...
...
@@ -95,17 +95,17 @@
*/
struct
ppp_lqp_packet_hdr
{
unsigned
long
LastOutLQRs
;
/* Copied from PeerOutLQRs */
unsigned
long
LastOutPackets
;
/* Copied from PeerOutPackets */
unsigned
long
LastOutOctets
;
/* Copied from PeerOutOctets */
unsigned
long
PeerInLQRs
;
/* Copied from SavedInLQRs */
unsigned
long
PeerInPackets
;
/* Copied from SavedInPackets */
unsigned
long
PeerInDiscards
;
/* Copied from SavedInDiscards */
unsigned
long
PeerInErrors
;
/* Copied from SavedInErrors */
unsigned
long
PeerInOctets
;
/* Copied from SavedInOctets */
unsigned
long
PeerOutLQRs
;
/* Copied from OutLQRs, plus 1 */
unsigned
long
PeerOutPackets
;
/* Current ifOutUniPackets, + 1 */
unsigned
long
PeerOutOctets
;
/* Current ifOutOctets + LQR */
__u32
LastOutLQRs
;
/* Copied from PeerOutLQRs */
__u32
LastOutPackets
;
/* Copied from PeerOutPackets */
__u32
LastOutOctets
;
/* Copied from PeerOutOctets */
__u32
PeerInLQRs
;
/* Copied from SavedInLQRs */
__u32
PeerInPackets
;
/* Copied from SavedInPackets */
__u32
PeerInDiscards
;
/* Copied from SavedInDiscards */
__u32
PeerInErrors
;
/* Copied from SavedInErrors */
__u32
PeerInOctets
;
/* Copied from SavedInOctets */
__u32
PeerOutLQRs
;
/* Copied from OutLQRs, plus 1 */
__u32
PeerOutPackets
;
/* Current ifOutUniPackets, + 1 */
__u32
PeerOutOctets
;
/* Current ifOutOctets + LQR */
};
/*
...
...
@@ -114,11 +114,11 @@ struct ppp_lqp_packet_hdr {
*/
struct
ppp_lqp_packet_trailer
{
unsigned
long
SaveInLQRs
;
/* Current InLQRs on reception */
unsigned
long
SaveInPackets
;
/* Current ifInUniPackets */
unsigned
long
SaveInDiscards
;
/* Current ifInDiscards */
unsigned
long
SaveInErrors
;
/* Current ifInErrors */
unsigned
long
SaveInOctets
;
/* Current ifInOctects */
__u32
SaveInLQRs
;
/* Current InLQRs on reception */
__u32
SaveInPackets
;
/* Current ifInUniPackets */
__u32
SaveInDiscards
;
/* Current ifInDiscards */
__u32
SaveInErrors
;
/* Current ifInErrors */
__u32
SaveInOctets
;
/* Current ifInOctects */
};
/*
...
...
@@ -128,7 +128,7 @@ struct ppp_lqp_packet_trailer {
*/
struct
ppp_lpq_packet
{
unsigned
long
magic
;
/* current magic value */
__u32
magic
;
/* current magic value */
struct
ppp_lqp_packet_hdr
hdr
;
/* Header fields for structure */
struct
ppp_lqp_packet_trailer
tail
;
/* Trailer fields (not sent) */
};
...
...
@@ -138,21 +138,21 @@ struct ppp_lpq_packet {
*/
struct
ppp_stats
{
unsigned
long
rbytes
;
/* bytes received */
unsigned
long
rcomp
;
/* compressed packets received */
unsigned
long
runcomp
;
/* uncompressed packets received */
unsigned
long
rothers
;
/* non-ip frames received */
unsigned
long
rerrors
;
/* received errors */
unsigned
long
roverrun
;
/* "buffer overrun" counter */
unsigned
long
tossed
;
/* packets discarded */
unsigned
long
runts
;
/* frames too short to process */
unsigned
long
rgiants
;
/* frames too large to process */
unsigned
long
sbytes
;
/* bytes sent */
unsigned
long
scomp
;
/* compressed packets sent */
unsigned
long
suncomp
;
/* uncompressed packets sent */
unsigned
long
sothers
;
/* non-ip frames sent */
unsigned
long
serrors
;
/* transmitter errors */
unsigned
long
sbusy
;
/* "transmitter busy" counter */
__u32
rbytes
;
/* bytes received */
__u32
rcomp
;
/* compressed packets received */
__u32
runcomp
;
/* uncompressed packets received */
__u32
rothers
;
/* non-ip frames received */
__u32
rerrors
;
/* received errors */
__u32
roverrun
;
/* "buffer overrun" counter */
__u32
tossed
;
/* packets discarded */
__u32
runts
;
/* frames too short to process */
__u32
rgiants
;
/* frames too large to process */
__u32
sbytes
;
/* bytes sent */
__u32
scomp
;
/* compressed packets sent */
__u32
suncomp
;
/* uncompressed packets sent */
__u32
sothers
;
/* non-ip frames sent */
__u32
serrors
;
/* transmitter errors */
__u32
sbusy
;
/* "transmitter busy" counter */
};
/*
...
...
@@ -172,17 +172,17 @@ struct ppp {
int
magic
;
/* magic value for structure */
/* Bitmapped flag fields. */
char
inuse
;
/* are we allocated? */
char
sending
;
/* "channel busy" indicator */
char
escape
;
/* 0x20 if prev char was PPP_ESC*/
char
toss
;
/* toss this frame */
unsigned
long
inuse
;
/* are we allocated? */
unsigned
int
flags
;
/* miscellany */
unsigned
long
xmit_async_map
[
8
];
/* 1 bit means that given control
__u32
xmit_async_map
[
8
];
/* 1 bit means that given control
character is quoted on output*/
unsigned
long
recv_async_map
;
/* 1 bit means that given control
__u32
recv_async_map
;
/* 1 bit means that given control
character is ignored on input*/
int
mtu
;
/* maximum xmit frame size */
int
mru
;
/* maximum receive frame size */
...
...
@@ -193,7 +193,7 @@ struct ppp {
struct
tty_struct
*
tty
;
/* ptr to TTY structure */
struct
device
*
dev
;
/* easy for intr handling */
struct
slcompress
*
slcomp
;
/* for header compression */
unsigned
long
last_xmit
;
/* time of last transmission */
__u32
last_xmit
;
/* time of last transmission */
/* These are pointers to the malloc()ed frame buffers.
These buffers are used while processing a packet. If a packet
...
...
@@ -216,7 +216,7 @@ struct ppp {
unsigned
char
*
us_rbuff_end
;
/* end of allocated space */
unsigned
char
*
us_rbuff_head
;
/* head of waiting packets */
unsigned
char
*
us_rbuff_tail
;
/* tail of waiting packets */
unsigned
char
us_rbuff_lock
;
/* lock: bit 0 head bit 1 tail */
unsigned
long
us_rbuff_lock
;
/* lock: bit 0 head bit 1 tail */
int
inp_sig
;
/* input ready signal for pgrp */
int
inp_sig_pid
;
/* process to get notified */
...
...
include/linux/in.h
View file @
bb9c5bf1
...
...
@@ -118,4 +118,12 @@ struct sockaddr_in {
#include <asm/byteorder.h>
/* Some random defines to make it easier in the kernel.. */
#ifdef __KERNEL__
#define LOOPBACK(x) (((x) & htonl(0xff000000)) == htonl(0x7f000000))
#define MULTICAST(x) (((x) & htonl(0xf0000000)) == htonl(0xe0000000))
#endif
#endif
/* _LINUX_IN_H */
include/linux/netdevice.h
View file @
bb9c5bf1
...
...
@@ -156,7 +156,7 @@ struct device
int
(
*
do_ioctl
)(
struct
device
*
dev
,
struct
ifreq
*
ifr
,
int
cmd
);
#define HAVE_SET_CONFIG
int
(
*
set_config
)(
struct
device
*
dev
,
struct
ifmap
*
map
);
int
(
*
header_cache
)(
struct
device
*
dev
,
struct
sock
*
sk
,
unsigned
long
saddr
,
unsigned
long
daddr
);
void
(
*
header_cache
)(
struct
device
*
dev
,
struct
sock
*
sk
,
unsigned
long
saddr
,
unsigned
long
daddr
);
};
...
...
include/linux/sched.h
View file @
bb9c5bf1
...
...
@@ -147,7 +147,7 @@ struct task_struct {
unsigned
long
blocked
;
/* bitmap of masked signals */
unsigned
long
flags
;
/* per process flags, defined below */
int
errno
;
int
debugreg
[
8
];
/* Hardware debugging registers */
long
debugreg
[
8
];
/* Hardware debugging registers */
struct
exec_domain
*
exec_domain
;
/* various fields */
struct
linux_binfmt
*
binfmt
;
...
...
include/linux/skbuff.h
View file @
bb9c5bf1
...
...
@@ -90,8 +90,13 @@ struct sk_buff {
unsigned
char
*
end
;
/* End pointer */
};
#ifdef CONFIG_SKB_LARGE
#define SK_WMEM_MAX 65535
#define SK_RMEM_MAX 65535
#else
#define SK_WMEM_MAX 32767
#define SK_RMEM_MAX 32767
#endif
#if CONFIG_SKB_CHECK
#define SK_FREED_SKB 0x0DE2C0DE
...
...
include/linux/symtab_begin.h
View file @
bb9c5bf1
#include <linux/config.h>
#include <linux/linkage.h>
#ifdef CONFIG_MODVERSIONS
/* CONFIG_MODVERSIONS */
#undef _set_ver
#undef X
#ifndef __GENKSYMS__
#ifdef MODULE
#define _set_ver(sym,ver) \
#ifdef CONFIG_MODVERSIONS
# undef _set_ver
# undef X
# ifndef __GENKSYMS__
# ifdef MODULE
# define _set_ver(sym,ver) \
{ (void *) & sym ## _R ## ver, SYMBOL_NAME_STR(sym) "_R" #ver }
#else
/* MODULE */
#define _set_ver(sym,ver) \
#
else
/* MODULE */
#
define _set_ver(sym,ver) \
{ (void *) & sym, SYMBOL_NAME_STR(sym) "_R" #ver }
#endif
/* MODULE */
#define X(a) a
#
endif
/*
__GENKSYMS__ */
#
endif
/* MODULE */
#
define X(a) a
#
endif
/* !
__GENKSYMS__ */
#else
/* CONFIG_MODVERSIONS */
#define X(sym) { (void *) & sym, SYMBOL_NAME_STR(sym)}
#
define X(sym) { (void *) & sym, SYMBOL_NAME_STR(sym)}
#endif
/* CONFIG_MODVERSIONS */
#define EMPTY {0,0}
0
,
0
,
0
,
{
include/net/eth.h
View file @
bb9c5bf1
...
...
@@ -32,6 +32,6 @@ extern int eth_rebuild_header(void *buff, struct device *dev,
extern
void
eth_add_arp
(
unsigned
long
addr
,
struct
sk_buff
*
skb
,
struct
device
*
dev
);
extern
unsigned
short
eth_type_trans
(
struct
sk_buff
*
skb
,
struct
device
*
dev
);
extern
int
eth_header_cache
(
struct
device
*
dev
,
struct
sock
*
sk
,
unsigned
long
saddr
,
unsigned
long
daddr
);
extern
void
eth_header_cache
(
struct
device
*
dev
,
struct
sock
*
sk
,
unsigned
long
saddr
,
unsigned
long
daddr
);
#endif
/* _ETH_H */
include/net/head_explode.h
deleted
100644 → 0
View file @
c3aa3674
/*
* Header exploders. We inline those only appearing once.
*
* We assume 8 bit bytes.
*
* This is oriented to getting good code out of GCC. It may need
* tuning for other processors.
*
* Note only IGMP uses this so far. Just as an experiment.
*/
extern
__inline__
unsigned
char
*
exp_getu16
(
unsigned
char
*
bp
,
unsigned
short
*
u
)
{
*
u
=
(
*
bp
<<
8
)
|
bp
[
1
];
return
bp
+
2
;
}
extern
__inline__
unsigned
char
*
exp_getn16
(
unsigned
char
*
bp
,
unsigned
short
*
u
)
{
unsigned
char
*
tp
=
(
unsigned
char
*
)
u
;
*
tp
++=*
bp
++
;
*
tp
++=*
bp
++
;
return
bp
;
}
extern
__inline__
unsigned
char
*
imp_putu16
(
unsigned
char
*
bp
,
unsigned
short
n
)
{
*
bp
=
(
n
>>
8
);
bp
[
1
]
=
n
&
0xFF
;
return
bp
+
2
;
}
extern
__inline__
unsigned
char
*
imp_putn16
(
unsigned
char
*
bp
,
unsigned
short
n
)
{
unsigned
char
*
sp
=
(
unsigned
char
*
)
&
n
;
*
bp
++=*
sp
++
;
*
bp
++=*
sp
++
;
return
bp
;
}
extern
__inline__
unsigned
char
*
exp_getu32
(
unsigned
char
*
bp
,
unsigned
long
*
u
)
{
*
u
=
(
bp
[
0
]
<<
24
)
|
(
bp
[
1
]
<<
16
)
|
(
bp
[
2
]
<<
8
)
|
bp
[
3
];
return
bp
+
4
;
}
extern
__inline__
unsigned
char
*
exp_getn32
(
unsigned
char
*
bp
,
unsigned
long
*
u
)
{
unsigned
char
*
tp
=
(
unsigned
char
*
)
u
;
*
tp
++=*
bp
++
;
*
tp
++=*
bp
++
;
*
tp
++=*
bp
++
;
*
tp
++=*
bp
++
;
return
bp
;
}
extern
__inline__
unsigned
char
*
imp_putu32
(
unsigned
char
*
bp
,
unsigned
long
n
)
{
bp
[
0
]
=
n
>>
24
;
bp
[
1
]
=
(
n
>>
16
)
&
0xFF
;
bp
[
2
]
=
(
n
>>
8
)
&
0xFF
;
bp
[
3
]
=
n
&
0xFF
;
return
bp
+
4
;
}
extern
__inline__
unsigned
char
*
imp_putn32
(
unsigned
char
*
bp
,
unsigned
long
n
)
{
unsigned
char
*
sp
=
(
unsigned
char
*
)
&
n
;
*
bp
++=*
sp
++
;
*
bp
++=*
sp
++
;
*
bp
++=*
sp
++
;
*
bp
++=*
sp
++
;
return
bp
;
}
#if 0
extern __inline__ unsigned char *ip_explode(unsigned char *iph, struct ip_header *ip)
{
ip->version=*iph>>4; /* Avoid the shift. We do our equality checks shifted too */
ip->ihl=(*iph++)&0xF; /* Length in long words */
ip->tos=*iph++; /* Service type */
iph=exp_getu16(iph,&ip->tot_len); /* Length of packet */
iph=exp_getu16(iph,&ip->id); /* Packet identity */
iph=exp_getu16(iph,&ip->frag_off); /* Fragment offset */
ip->ttl=*iph++;
ip->protocol=*iph++;
iph=exp_getn16(iph,&ip->check);
iph=exp_getn32(iph,&ip->saddr);
iph=exp_getn32(iph,&ip->daddr);
return iph;
}
extern __inline__ unsigned char *icmp_explode(unsigned char *icmph, struct icmp_header *icmp)
{
icmp->type=*icmp++;
icmp->code=*icmp++;
icmph=exp_getn16(icmph,&icmp->checksum);
/* These two pairs are a union... expand both */
exp_getu32(icmph,&icmp->gateway);
icmph=exp_getu16(icmph,&icmp->id);
icmph=exp_getu16(icmph,&icmp->sequence);
return icmph;
}
#endif
extern
__inline__
unsigned
char
*
igmp_explode
(
unsigned
char
*
igmph
,
struct
igmp_header
*
igmp
)
{
igmp
->
type
=*
igmph
++
;
igmph
++
;
/* unused */
igmph
=
exp_getn16
(
igmph
,
&
igmp
->
csum
);
igmph
=
exp_getn32
(
igmph
,
&
igmp
->
group
);
return
igmph
;
}
#if 0
extern __inline__ unsigned char *tcp_explode(unsigned char *tcph, struct tcp_header *tcp)
{
tcph=exp_getu16(tcph,&tcp->source);
tcph=exp_getu16(tcph,&tcp->dest);
tcph=exp_getu32(tcph,&tcp->seq);
tcph=exp_getu32(tcph,&tcp->ack_seq);
tcph=exp_getu16(tcph,&tcp->u.bitmask);
tcph=exp_getu16(tcph,&tcp->window);
tcph=exp_getn16(tcph,&tcp->check);
tcph=exp_getu16(tcph,&tcp->urg_ptr);
return tcph;
}
extern __inline__ unsigned char *udp_explode(unsigned char *udph, struct udp_header *udp)
{
udph=exp_getu16(tcph,&udp->source);
udph=exp_getu16(udph,&udp->dest);
udph=exp_getu16(udph,&udp->len);
udph=exp_getn16(udph,&udp->check);
return udph;
}
#endif
include/net/ip.h
View file @
bb9c5bf1
...
...
@@ -44,7 +44,6 @@
extern
void
ip_mc_dropsocket
(
struct
sock
*
);
extern
void
ip_mc_dropdevice
(
struct
device
*
dev
);
extern
int
ip_mc_procinfo
(
char
*
,
char
**
,
off_t
,
int
);
#define MULTICAST(x) (IN_MULTICAST(htonl(x)))
#endif
...
...
@@ -89,7 +88,7 @@ extern int ip_build_header(struct sk_buff *skb,
/*extern unsigned short ip_compute_csum(unsigned char * buff, int len);*/
extern
int
ip_rcv
(
struct
sk_buff
*
skb
,
struct
device
*
dev
,
struct
packet_type
*
pt
);
extern
void
ip_forward
(
struct
sk_buff
*
skb
,
struct
device
*
dev
,
int
is_frag
,
unsigned
long
target_addr
,
int
target_strict
);
extern
int
ip_forward
(
struct
sk_buff
*
skb
,
struct
device
*
dev
,
int
is_frag
,
unsigned
long
target_addr
,
int
target_strict
);
extern
void
ip_send_check
(
struct
iphdr
*
ip
);
extern
int
ip_id_count
;
extern
void
ip_queue_xmit
(
struct
sock
*
sk
,
...
...
include/net/tcp.h
View file @
bb9c5bf1
...
...
@@ -24,7 +24,9 @@
#define MAX_FIN_SIZE 40 + MAX_HEADER + 15
#define MAX_ACK_SIZE 40 + MAX_HEADER + 15
#define MAX_RESET_SIZE 40 + MAX_HEADER + 15
#define MAX_WINDOW 16384
#define MAX_WINDOW 32767
/* Never offer a window over 32767 without using
window scaling (not yet supported). Some poor
stacks do signed 16bit maths! */
#define MIN_WINDOW 2048
#define MAX_ACK_BACKLOG 2
#define MIN_WRITE_SPACE 2048
...
...
mm/vmalloc.c
View file @
bb9c5bf1
...
...
@@ -167,6 +167,89 @@ static int alloc_area_pages(unsigned long address, unsigned long size)
return
0
;
}
static
inline
void
remap_area_pte
(
pte_t
*
pte
,
unsigned
long
address
,
unsigned
long
size
,
unsigned
long
offset
)
{
unsigned
long
end
;
address
&=
~
PMD_MASK
;
end
=
address
+
size
;
if
(
end
>
PMD_SIZE
)
end
=
PMD_SIZE
;
do
{
if
(
!
pte_none
(
*
pte
))
printk
(
"remap_area_pte: page already exists
\n
"
);
*
pte
=
mk_pte
(
offset
,
PAGE_KERNEL
);
address
+=
PAGE_SIZE
;
offset
+=
PAGE_SIZE
;
pte
++
;
}
while
(
address
<
end
);
}
static
inline
int
remap_area_pmd
(
pmd_t
*
pmd
,
unsigned
long
address
,
unsigned
long
size
,
unsigned
long
offset
)
{
unsigned
long
end
;
address
&=
~
PGDIR_MASK
;
end
=
address
+
size
;
if
(
end
>
PGDIR_SIZE
)
end
=
PGDIR_SIZE
;
offset
-=
address
;
do
{
pte_t
*
pte
=
pte_alloc_kernel
(
pmd
,
address
);
if
(
!
pte
)
return
-
ENOMEM
;
remap_area_pte
(
pte
,
address
,
end
-
address
,
address
+
offset
);
address
=
(
address
+
PMD_SIZE
)
&
PMD_MASK
;
pmd
++
;
}
while
(
address
<
end
);
return
0
;
}
static
int
remap_area_pages
(
unsigned
long
address
,
unsigned
long
offset
,
unsigned
long
size
)
{
pgd_t
*
dir
;
unsigned
long
end
=
address
+
size
;
offset
-=
address
;
dir
=
pgd_offset
(
&
init_task
,
address
);
while
(
address
<
end
)
{
pmd_t
*
pmd
=
pmd_alloc_kernel
(
dir
,
address
);
if
(
!
pmd
)
return
-
ENOMEM
;
if
(
remap_area_pmd
(
pmd
,
address
,
end
-
address
,
offset
+
address
))
return
-
ENOMEM
;
set_pgdir
(
address
,
*
dir
);
address
=
(
address
+
PGDIR_SIZE
)
&
PGDIR_MASK
;
dir
++
;
}
invalidate
();
return
0
;
}
static
struct
vm_struct
*
get_vm_area
(
unsigned
long
size
)
{
void
*
addr
;
struct
vm_struct
**
p
,
*
tmp
,
*
area
;
area
=
(
struct
vm_struct
*
)
kmalloc
(
sizeof
(
*
area
),
GFP_KERNEL
);
if
(
!
area
)
return
NULL
;
addr
=
(
void
*
)
VMALLOC_START
;
area
->
size
=
size
+
PAGE_SIZE
;
area
->
next
=
NULL
;
for
(
p
=
&
vmlist
;
(
tmp
=
*
p
)
;
p
=
&
tmp
->
next
)
{
if
(
size
+
(
unsigned
long
)
addr
<
(
unsigned
long
)
tmp
->
addr
)
break
;
addr
=
(
void
*
)
(
tmp
->
size
+
(
unsigned
long
)
tmp
->
addr
);
}
area
->
addr
=
addr
;
area
->
next
=
*
p
;
*
p
=
area
;
return
area
;
}
void
vfree
(
void
*
addr
)
{
struct
vm_struct
**
p
,
*
tmp
;
...
...
@@ -191,25 +274,15 @@ void vfree(void * addr)
void
*
vmalloc
(
unsigned
long
size
)
{
void
*
addr
;
struct
vm_struct
*
*
p
,
*
tmp
,
*
area
;
struct
vm_struct
*
area
;
size
=
PAGE_ALIGN
(
size
);
if
(
!
size
||
size
>
high_memory
)
return
NULL
;
area
=
(
struct
vm_struct
*
)
kmalloc
(
sizeof
(
*
area
),
GFP_KERNEL
);
area
=
get_vm_area
(
size
);
if
(
!
area
)
return
NULL
;
addr
=
(
void
*
)
VMALLOC_START
;
area
->
size
=
size
+
PAGE_SIZE
;
area
->
next
=
NULL
;
for
(
p
=
&
vmlist
;
(
tmp
=
*
p
)
;
p
=
&
tmp
->
next
)
{
if
(
size
+
(
unsigned
long
)
addr
<
(
unsigned
long
)
tmp
->
addr
)
break
;
addr
=
(
void
*
)
(
tmp
->
size
+
(
unsigned
long
)
tmp
->
addr
);
}
area
->
addr
=
addr
;
area
->
next
=
*
p
;
*
p
=
area
;
addr
=
area
->
addr
;
if
(
alloc_area_pages
(
VMALLOC_VMADDR
(
addr
),
size
))
{
vfree
(
addr
);
return
NULL
;
...
...
@@ -217,6 +290,34 @@ void * vmalloc(unsigned long size)
return
addr
;
}
/*
* Remap an arbitrary physical address space into the kernel virtual
* address space. Needed when the kernel wants to access high addresses
* directly.
*/
void
*
vremap
(
unsigned
long
offset
,
unsigned
long
size
)
{
void
*
addr
;
struct
vm_struct
*
area
;
if
(
offset
<
high_memory
)
return
NULL
;
if
(
offset
&
~
PAGE_MASK
)
return
NULL
;
size
=
PAGE_ALIGN
(
size
);
if
(
!
size
||
size
>
offset
+
size
)
return
NULL
;
area
=
get_vm_area
(
size
);
if
(
!
area
)
return
NULL
;
addr
=
area
->
addr
;
if
(
remap_area_pages
(
VMALLOC_VMADDR
(
addr
),
offset
,
size
))
{
vfree
(
addr
);
return
NULL
;
}
return
addr
;
}
int
vread
(
char
*
buf
,
char
*
addr
,
int
count
)
{
struct
vm_struct
**
p
,
*
tmp
;
...
...
net/Changes
View file @
bb9c5bf1
...
...
@@ -53,39 +53,39 @@ o TCP irtt support [TESTED]
o RTF_REJECT routing support [TESTED]
o Fixed 0 length fragment bug [TESTED]
o Fixed overlapping reasm bug [TESTED]
o Newest AX.25 code from John Naylor [
IN
]
o NetROM from John Naylor [
IN
]
o Newest AX.25 code from John Naylor [
TESTED
]
o NetROM from John Naylor [
TESTED
]
o Routerless DDP fixes from Wesley [TESTED]
------->>>>> ALPHA 005 <<<<<----------
o Several compile and bugfixes from Jakko [
IN
]
o Several compile and bugfixes from Jakko [
TESTED
]
o Connect fix from Matt Day (+ fix to fix) [TESTED]
o RTT, memory leak and other netrom/ax.25 cures
-- John Naylor [
IN
]
o IP source route via broadcast now illegal [
IN
]
-- John Naylor [
TESTED
]
o IP source route via broadcast now illegal [
TESTED
]
------->>>>> ALPHA 006 <<<<<----------
o Yet more NetROM/AX.25 improvements [
IN
]
o Yet more NetROM/AX.25 improvements [
TESTED
]
-- John Naylor
o Fixed a _stupid_ appletalk bug [TESTED]
o Missing include [
IN
]
o Missing include [
TESTED
]
-- Lots of people
o Can drop all source routes [
IN
]
o Can drop all source routes [
TESTED
]
o Printing fixes for ip_fw [IN]
o UDP checksum fix (Gerhard) [
IN
]
o UDP checksum fix (Gerhard) [
TESTED
]
o Newer 3c505 driver from Juha Laiho [IN]
o Security fix to axassociate [
IN
]
o Security fix to axassociate [
TESTED
]
o Loopback driver debugged (fixes named) [TESTED]
o SCC driver from Joerg Reuter [
IN
]
o IP Firewall accounting zero bug [
IN
]
o SCC driver from Joerg Reuter [
TESTED
]
o IP Firewall accounting zero bug [
TESTED
]
////////////////////////////1.3.0///////////////////////////
o Merged loadable firewall code [NOT INCLUDED YET]
o New buffers used totally non optimally [
SEEMS OK
]
o New buffers used totally non optimally [
TESTED
]
o Fast ip_forwarding (needs changing) [NOT INCLUDED YET]
o Fixed connection hang bug in new SWS code [TESTED]
o Buffer management hack putting skbuff control
...
...
@@ -93,10 +93,10 @@ o Buffer management hack putting skbuff control
totally cache non-optimal [TESTED]
o Faster checksum [Tom May] [IN]
o Appletalk router fixes [Michael Callahan] [IN]
o TCP state error fixes [Mark Tamsky] [
IN
]
o Verify area fixes [Heiko Eissfeldt] [
IN
]
o TCP state error fixes [Mark Tamsky] [
TESTED
]
o Verify area fixes [Heiko Eissfeldt] [
TESTED
]
o Routes use metric field [John Naylor] [IN]
o Major AX.25/NetROM fixes [John Nalor] [
IN
]
o Major AX.25/NetROM fixes [John Nalor] [
TESTED
]
------->>>>> NET3 030 <<<<<----------
...
...
@@ -104,18 +104,47 @@ o Long word align ethernet IP headers (64byte align for pentium) [TESTED]
(less helpful than I'd have liked)
o Fixed variable length header support to really work [TESTED]
o Mend appletalk/ipx partially [IN]
o Start playing with input checksum & copy [
IN
]
o Start playing with input checksum & copy [
TESTED
]
o Fixed PPP and other oddments [IN]
o Mended IPIP [Might work ;)]
------->>>>> 1.3.7 <<<<<----------
o Checksum bug fixed [TESTED]
o Lance driver panic cured [BROKEN]
o DEC ALPHA stuff (Linus) [ASK HIM NOT ME]
o Always try to keep output packet order
(eg for vat and BSD fast path tcp) [TESTED]
o Copy the mac pointer in skb_clone [TESTED]
o Fix tcpdump panic [IN]
o Fix dev_alloc_skb NULL deref bug [TESTED]
o Fix Security error in SIGURG stuff [TESTED]
o Missing 15 byte slack on ip_loopback [IN, still has mcast bugs left!]
------->>>>> 1.3.8 <<<<<----------
o UDP snmp count fixed [IN]
o IP snmp out count fixed [IN] (fragment still wrong)
o First bit of Dave Bonn's fast forwarding [IN]
o Fix leaks and double free in firewalling [IN]
o Fix memory scribble in ip_build_xmit [TESTED]
o Do fast cases of ip_build_xmit first
slows fragmented I/O down, speeds up smaller
packets. UDP send ttcp can now touch 7.5Mbyte/sec
with nothing else going on. UDP recv is slower 8( [TESTED]
o Fixed and enabled ethernet header caches [IN]
o Removed junk from igmp [IN]
o Obscure UDP/copy&sum bug fix [IN]
o Fixed multicast [IN]
o TCP does rerouting for most cases [NOT WORKING YET]
------->>>>> 1.3.? <<<<<----------
o Finish merging the bridge code
o Device locking
o SIOCSLEEPRT patch
o Options support in ip_build_xmit [PENDING]
o Fast checksum/copy on outgoing TCP
o Explode/implode headers for alpha,mips etc.
o Fast dev_grab_next() transmit reload function
and dev_push_failed() ??
o Faster ip_forward [PENDING]
...
...
@@ -127,6 +156,7 @@ o AX.25 set protocol type
o Clean up RAW AX.25 sockets.
o Finish 802.2 Class I code to be compliant to the oddities of 802.2
o Full variable length AX.25 support [JSN doing]
o Tidy BPQ support
0.2
---
...
...
@@ -139,6 +169,7 @@ o PPP for Sonix ISDN.
o Loadable firewall extensions.
o Screend loadable firewall module
o LZ SLIP [Done, resolving patent issues]
o AXIP
0.3
---
...
...
@@ -198,7 +229,7 @@ problem.
10. Frame Relay/WAN/ISDN drivers [I'm working on the sonix EuroISDN board
driver but thats for an internal project and its general release is still
a maybe (so is finishing it ;))].
a maybe (so is finishing it ;))]
[Someone is working on Frame Relay]
.
11. IP over SCSI.
...
...
net/core/datagram.c
View file @
bb9c5bf1
...
...
@@ -72,8 +72,10 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags, int noblock,
if
(
sk
->
err
)
{
release_sock
(
sk
);
cli
();
*
err
=-
sk
->
err
;
sk
->
err
=
0
;
restore_flags
(
intflags
);
return
NULL
;
}
...
...
@@ -163,8 +165,6 @@ void skb_free_datagram(struct sk_buff *skb)
void
skb_copy_datagram
(
struct
sk_buff
*
skb
,
int
offset
,
char
*
to
,
int
size
)
{
/* We will know all about the fraglist options to allow >4K receives
but not this release */
memcpy_tofs
(
to
,
skb
->
h
.
raw
+
offset
,
size
);
}
...
...
net/core/dev.c
View file @
bb9c5bf1
...
...
@@ -312,7 +312,6 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
void
dev_queue_xmit
(
struct
sk_buff
*
skb
,
struct
device
*
dev
,
int
pri
)
{
unsigned
long
flags
;
int
nitcount
;
struct
packet_type
*
ptype
;
int
where
=
0
;
/* used to say if the packet should go */
/* at the front or the back of the */
...
...
@@ -367,7 +366,7 @@ void dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri)
restore_flags
(
flags
);
/* copy outgoing packets to any sniffer packet handlers */
if
(
!
where
)
if
(
!
where
&&
dev_nit
)
{
skb
->
stamp
=
xtime
;
for
(
ptype
=
ptype_all
;
ptype
!=
NULL
;
ptype
=
ptype
->
next
)
...
...
@@ -384,7 +383,6 @@ void dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri)
skb2
->
h
.
raw
=
skb2
->
data
+
dev
->
hard_header_len
;
skb2
->
mac
.
raw
=
skb2
->
data
;
ptype
->
func
(
skb2
,
skb
->
dev
,
ptype
);
nitcount
--
;
}
}
}
...
...
@@ -458,7 +456,7 @@ void netif_rx(struct sk_buff *skb)
*/
#ifdef CONFIG_NET_RUNONIRQ
/* Dont enable yet, needs some driver mods */
i
net_bh
();
net_bh
();
#else
mark_bh
(
NET_BH
);
#endif
...
...
@@ -616,7 +614,8 @@ void net_bh(void *tmp)
/*
* Can we send anything now? We want to clear the
* decks for any more sends that get done as we
* process the input.
* process the input. This also minimises the
* latency on a transmit interrupt bh.
*/
dev_transmit
();
...
...
@@ -676,7 +675,7 @@ void net_bh(void *tmp)
for
(
ptype
=
ptype_base
[
ntohs
(
type
)
&
15
];
ptype
!=
NULL
;
ptype
=
ptype
->
next
)
{
if
(
(
ptype
->
type
==
type
||
ptype
->
type
==
htons
(
ETH_P_ALL
))
&&
(
!
ptype
->
dev
||
ptype
->
dev
==
skb
->
dev
))
if
(
ptype
->
type
==
type
&&
(
!
ptype
->
dev
||
ptype
->
dev
==
skb
->
dev
))
{
/*
* We already have a match queued. Deliver
...
...
net/ipv4/af_inet.c
View file @
bb9c5bf1
...
...
@@ -40,6 +40,9 @@
* (eg for big web sites), but only if
* specifically application requested.
* Alan Cox : New buffering throughout IP. Used dumbly.
* Alan Cox : New buffering now used smartly.
* Alan Cox : BSD rather than common sense interpretation of
* listen.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
...
...
@@ -491,6 +494,8 @@ static int inet_listen(struct socket *sock, int backlog)
* else does..
* Now truncate to 128 not 5.
*/
if
((
unsigned
)
backlog
==
0
)
/* BSDism */
backlog
=
1
;
if
((
unsigned
)
backlog
>
128
)
backlog
=
128
;
sk
->
max_ack_backlog
=
backlog
;
...
...
net/ipv4/icmp.c
View file @
bb9c5bf1
...
...
@@ -33,7 +33,7 @@
* Peter Belding : Tightened up ICMP redirect handling
* Alan Cox : Tightened even more.
* Arnt Gulbrandsen: Misplaced #endif with net redirect and break
*
*
A.N.Kuznetsov : ICMP timestamp still used skb+1
*
*
* This program is free software; you can redistribute it and/or
...
...
@@ -544,7 +544,7 @@ static void icmp_timestamp(struct icmphdr *icmph, struct sk_buff *skb, struct de
* Build ICMP_TIMESTAMP Response message.
*/
icmphr
=
(
struct
icmphdr
*
)
(
(
char
*
)
(
skb2
+
1
)
+
offset
);
icmphr
=
(
struct
icmphdr
*
)
(
skb2
->
data
+
offset
);
memcpy
((
char
*
)
icmphr
,
(
char
*
)
icmph
,
12
);
icmphr
->
type
=
ICMP_TIMESTAMPREPLY
;
icmphr
->
code
=
icmphr
->
checksum
=
0
;
...
...
net/ipv4/igmp.c
View file @
bb9c5bf1
...
...
@@ -14,6 +14,7 @@
* Alan Cox : Added lots of __inline__ to optimise
* the memory usage of all the tiny little
* functions.
* Alan Cox : Dumped the header building experiment.
*/
...
...
@@ -36,7 +37,6 @@
#include <net/sock.h>
#include <linux/igmp.h>
#include <net/checksum.h>
#include <net/head_explode.h>
#ifdef CONFIG_IP_MULTICAST
...
...
@@ -84,7 +84,7 @@ static void igmp_send_report(struct device *dev, unsigned long address, int type
{
struct
sk_buff
*
skb
=
alloc_skb
(
MAX_IGMP_SIZE
,
GFP_ATOMIC
);
int
tmp
;
unsigned
char
*
dp
;
struct
igmphdr
*
ih
;
if
(
skb
==
NULL
)
return
;
...
...
@@ -95,15 +95,12 @@ static void igmp_send_report(struct device *dev, unsigned long address, int type
kfree_skb
(
skb
,
FREE_WRITE
);
return
;
}
dp
=
skb
->
data
+
tmp
;
skb_put
(
skb
,
sizeof
(
struct
igmphdr
));
*
dp
++=
type
;
*
dp
++=
0
;
skb
->
h
.
raw
=
dp
;
dp
=
imp_putu16
(
dp
,
0
);
/* checksum */
dp
=
imp_putn32
(
dp
,
address
);
/* Address (already in net order) */
imp_putn16
(
skb
->
h
.
raw
,
ip_compute_csum
(
skb
->
data
+
tmp
,
sizeof
(
struct
igmphdr
)));
/* Checksum fill */
ih
=
(
struct
igmphdr
*
)
skb_put
(
skb
,
sizeof
(
struct
igmphdr
));
ih
->
type
=
IGMP_HOST_MEMBERSHIP_REPORT
;
ih
->
unused
=
0
;
ih
->
csum
=
0
;
ih
->
group
=
address
;
ih
->
csum
=
ip_compute_csum
((
void
*
)
ih
,
sizeof
(
struct
igmphdr
));
/* Checksum fill */
ip_queue_xmit
(
NULL
,
dev
,
skb
,
1
);
}
...
...
@@ -204,10 +201,9 @@ int igmp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
struct
inet_protocol
*
protocol
)
{
/* This basically follows the spec line by line -- see RFC1112 */
struct
igmp
_header
ig
h
;
struct
igmp
hdr
*
i
h
;
/* Pull the IGMP header */
igmp_explode
(
skb
->
h
.
raw
,
&
igh
);
ih
=
(
struct
igmphdr
*
)
skb
->
data
;
if
(
skb
->
len
<
sizeof
(
struct
igmphdr
)
||
skb
->
ip_hdr
->
ttl
!=
1
||
ip_compute_csum
((
void
*
)
skb
->
h
.
raw
,
sizeof
(
struct
igmphdr
)))
{
...
...
@@ -215,10 +211,10 @@ int igmp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
return
0
;
}
if
(
i
gh
.
type
==
IGMP_HOST_MEMBERSHIP_QUERY
&&
daddr
==
IGMP_ALL_HOSTS
)
if
(
i
h
->
type
==
IGMP_HOST_MEMBERSHIP_QUERY
&&
daddr
==
IGMP_ALL_HOSTS
)
igmp_heard_query
(
dev
);
if
(
i
gh
.
type
==
IGMP_HOST_MEMBERSHIP_REPORT
&&
daddr
==
igh
.
group
)
igmp_heard_report
(
dev
,
i
gh
.
group
);
if
(
i
h
->
type
==
IGMP_HOST_MEMBERSHIP_REPORT
&&
daddr
==
ih
->
group
)
igmp_heard_report
(
dev
,
i
h
->
group
);
kfree_skb
(
skb
,
FREE_READ
);
return
0
;
}
...
...
net/ipv4/ip.c
View file @
bb9c5bf1
...
...
@@ -82,6 +82,9 @@
* Alan Cox : Stopped broadcast source route explosions.
* Alan Cox : Can disable source routing
* Takeshi Sone : Masquerading didn't work.
* Dave Bonn,Alan Cox : Faster IP forwarding whenever possible.
* Alan Cox : Memory leaks, tramples, misc debugging.
* Alan Cox : Fixed multicast (by popular demand 8))
*
*
*
...
...
@@ -142,7 +145,6 @@ extern int last_retran;
extern
void
sort_send
(
struct
sock
*
sk
);
#define min(a,b) ((a)<(b)?(a):(b))
#define LOOPBACK(x) (((x) & htonl(0xff000000)) == htonl(0x7f000000))
/*
* SNMP management statistics
...
...
@@ -1007,7 +1009,7 @@ void ip_fragment(struct sock *sk, struct sk_buff *skb, struct device *dev, int i
* Forward an IP datagram to its next destination.
*/
void
ip_forward
(
struct
sk_buff
*
skb
,
struct
device
*
dev
,
int
is_frag
,
unsigned
long
target_addr
,
int
target_strict
)
int
ip_forward
(
struct
sk_buff
*
skb
,
struct
device
*
dev
,
int
is_frag
,
unsigned
long
target_addr
,
int
target_strict
)
{
struct
device
*
dev2
;
/* Output device */
struct
iphdr
*
iph
;
/* Our header */
...
...
@@ -1037,7 +1039,7 @@ void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned l
icmp_send
(
skb
,
ICMP_DEST_UNREACH
,
ICMP_HOST_UNREACH
,
0
,
dev
);
/* fall thru */
default:
return
;
return
-
1
;
}
}
#endif
...
...
@@ -1070,7 +1072,7 @@ void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned l
{
/* Tell the sender its packet died... */
icmp_send
(
skb
,
ICMP_TIME_EXCEEDED
,
ICMP_EXC_TTL
,
0
,
dev
);
return
;
return
-
1
;
}
/*
...
...
@@ -1086,7 +1088,7 @@ void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned l
* ICMP is screened later.
*/
icmp_send
(
skb
,
ICMP_DEST_UNREACH
,
ICMP_NET_UNREACH
,
0
,
dev
);
return
;
return
-
1
;
}
...
...
@@ -1109,8 +1111,7 @@ void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned l
if
(
target_strict
)
{
icmp_send
(
skb
,
ICMP_DEST_UNREACH
,
ICMP_SR_FAILED
,
0
,
dev
);
kfree_skb
(
skb
,
FREE_READ
);
return
;
return
-
1
;
}
/*
...
...
@@ -1125,7 +1126,7 @@ void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned l
* Tell the sender its packet cannot be delivered...
*/
icmp_send
(
skb
,
ICMP_DEST_UNREACH
,
ICMP_HOST_UNREACH
,
0
,
dev
);
return
;
return
-
1
;
}
if
(
rt
->
rt_gateway
!=
0
)
raddr
=
rt
->
rt_gateway
;
...
...
@@ -1145,12 +1146,12 @@ void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned l
* we calculated.
*/
#ifndef CONFIG_IP_NO_ICMP_REDIRECT
if
(
dev
==
dev2
&&
!
((
iph
->
saddr
^
iph
->
daddr
)
&
dev
->
pa_mask
)
&&
rt
->
rt_flags
&
RTF_MODIFIED
)
if
(
dev
==
dev2
&&
!
((
iph
->
saddr
^
iph
->
daddr
)
&
dev
->
pa_mask
)
&&
(
rt
->
rt_flags
&
RTF_MODIFIED
)
)
icmp_send
(
skb
,
ICMP_REDIRECT
,
ICMP_REDIR_HOST
,
raddr
,
dev
);
#endif
/*
* We now allocate a new buffer, and copy the datagram into it.
* We now
may
allocate a new buffer, and copy the datagram into it.
* If the indicated interface is up and running, kick it.
*/
...
...
@@ -1165,13 +1166,9 @@ void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned l
ip_fw_masquerade
(
&
skb
,
dev2
);
#endif
/*
* Current design decrees we copy the packet. For identical header
* lengths we could avoid it. The new skb code will let us push
* data so the problem goes away then.
*/
if
(
skb_headroom
(
skb
)
<
dev2
->
hard_header_len
)
skb2
=
alloc_skb
(
dev2
->
hard_header_len
+
skb
->
len
+
15
,
GFP_ATOMIC
);
else
skb2
=
skb
;
/*
* This is rare and since IP is tolerant of network failures
...
...
@@ -1181,13 +1178,20 @@ void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned l
if
(
skb2
==
NULL
)
{
NETDEBUG
(
printk
(
"
\n
IP: No memory available for IP forward
\n
"
));
return
;
return
-
1
;
}
/* Now build the MAC header. */
(
void
)
ip_send
(
skb2
,
raddr
,
skb
->
len
,
dev2
,
dev2
->
pa_addr
);
/*
* We have to copy the bytes over as the new header wouldn't fit
* the old buffer. This should be very rare.
*/
if
(
skb2
!=
skb
)
{
ptr
=
skb_put
(
skb2
,
skb
->
len
);
skb2
->
free
=
1
;
skb2
->
h
.
raw
=
ptr
;
...
...
@@ -1196,7 +1200,7 @@ void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned l
* Copy the packet data into the new buffer.
*/
memcpy
(
ptr
,
skb
->
h
.
raw
,
skb
->
len
);
}
ip_statistics
.
IpForwDatagrams
++
;
...
...
@@ -1234,6 +1238,16 @@ void ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, unsigned l
dev_queue_xmit
(
skb2
,
dev2
,
SOPRI_NORMAL
);
}
}
else
return
-
1
;
/*
* Tell the caller if their buffer is free.
*/
if
(
skb
==
skb2
)
return
0
;
return
1
;
}
...
...
@@ -1293,6 +1307,7 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
/*
* Our transport medium may have padded the buffer out. Now we know it
* is IP we can trim to the true length of the frame.
* Note this now means skb->len holds ntohs(iph->tot_len).
*/
skb_trim
(
skb
,
ntohs
(
iph
->
tot_len
));
...
...
@@ -1480,7 +1495,7 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
if
(
ip_fw_demasquerade
(
skb
))
{
struct
iphdr
*
iph
=
skb
->
h
.
iph
;
i
p_forward
(
skb
,
dev
,
is_frag
|
4
,
iph
->
daddr
,
0
);
i
f
(
ip_forward
(
skb
,
dev
,
is_frag
|
4
,
iph
->
daddr
,
0
))
kfree_skb
(
skb
,
FREE_WRITE
);
return
(
0
);
}
...
...
@@ -1620,15 +1635,7 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
}
/*
* Do any IP forwarding required. chk_addr() is expensive -- avoid it someday.
*
* This is inefficient. While finding out if it is for us we could also compute
* the routing table entry. This is where the great unified cache theory comes
* in as and when someone implements it
*
* For most hosts over 99% of packets match the first conditional
* and don't go via ip_chk_addr. Note: brd is set to IS_MYADDR at
* function entry.
* Do any IP forwarding required.
*/
/*
...
...
@@ -1646,18 +1653,14 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
*/
#ifdef CONFIG_IP_FORWARD
ip_forward
(
skb
,
dev
,
is_frag
,
target_addr
,
target_strict
);
if
(
ip_forward
(
skb
,
dev
,
is_frag
,
target_addr
,
target_strict
))
kfree_skb
(
skb
,
FREE_WRITE
);
#else
/* printk("Machine %lx tried to use us as a forwarder to %lx but we have forwarding disabled!\n",
iph->saddr,iph->daddr);*/
ip_statistics
.
IpInAddrErrors
++
;
#endif
/*
* The forwarder is inefficient and copies the packet. We
* free the original now.
*/
kfree_skb
(
skb
,
FREE_WRITE
);
#endif
return
(
0
);
}
...
...
@@ -1694,7 +1697,7 @@ static void ip_loopback(struct device *old_dev, struct sk_buff *skb)
/*
* Add the rest of the data space.
*/
newskb
->
ip_hdr
=
(
struct
iphdr
*
)
skb_put
(
skb
,
len
);
newskb
->
ip_hdr
=
(
struct
iphdr
*
)
skb_put
(
new
skb
,
len
);
/*
* Copy the data
*/
...
...
@@ -1894,7 +1897,7 @@ void ip_queue_xmit(struct sock *sk, struct device *dev,
}
}
#endif
if
((
dev
->
flags
&
IFF_BROADCAST
)
&&
iph
->
daddr
==
dev
->
pa_brdaddr
&&
!
(
dev
->
flags
&
IFF_LOOPBACK
))
if
((
dev
->
flags
&
IFF_BROADCAST
)
&&
(
iph
->
daddr
==
dev
->
pa_brdaddr
||
iph
->
daddr
==
0xFFFFFFFF
)
&&
!
(
dev
->
flags
&
IFF_LOOPBACK
))
ip_loopback
(
dev
,
skb
);
if
(
dev
->
flags
&
IFF_UP
)
...
...
@@ -1974,7 +1977,6 @@ int ip_mc_procinfo(char *buffer, char **start, off_t offset, int length)
}
#endif
/*
* Socket option code for IP. This is the end of the line after any TCP,UDP etc options on
* an IP socket.
...
...
@@ -1997,6 +1999,8 @@ static struct device *ip_mc_find_devfor(unsigned long addr)
return
NULL
;
}
#endif
int
ip_setsockopt
(
struct
sock
*
sk
,
int
level
,
int
optname
,
char
*
optval
,
int
optlen
)
{
int
val
,
err
;
...
...
@@ -2344,6 +2348,8 @@ int ip_build_xmit(struct sock *sk,
int
local
=
0
;
struct
device
*
dev
;
ip_statistics
.
IpOutRequests
++
;
#ifdef CONFIG_INET_MULTICAST
if
(
sk
&&
MULTICAST
(
daddr
)
&&
*
sk
->
ip_mc_name
)
...
...
@@ -2421,6 +2427,69 @@ int ip_build_xmit(struct sock *sk,
* Now compute the buffer space we require
*/
/*
* Try the simple case first. This leaves broadcast, multicast, fragmented frames, and by
* choice RAW frames within 20 bytes of maximum size(rare) to the long path
*/
if
(
length
+
20
<=
dev
->
mtu
&&
!
MULTICAST
(
daddr
)
&&
daddr
!=
0xFFFFFFFF
&&
daddr
!=
dev
->
pa_brdaddr
)
{
int
error
;
struct
sk_buff
*
skb
=
sock_alloc_send_skb
(
sk
,
length
+
20
+
15
+
dev
->
hard_header_len
,
0
,
&
error
);
if
(
skb
==
NULL
)
return
error
;
skb
->
dev
=
dev
;
skb
->
free
=
1
;
skb
->
when
=
jiffies
;
skb
->
sk
=
sk
;
skb
->
arp
=
0
;
skb
->
saddr
=
saddr
;
length
+=
20
;
/* We do this twice so the subtract once is quicker */
skb
->
raddr
=
(
rt
&&
rt
->
rt_gateway
)
?
rt
->
rt_gateway
:
daddr
;
skb_reserve
(
skb
,(
dev
->
hard_header_len
+
15
)
&~
15
);
if
(
sk
->
ip_hcache_state
>
0
)
{
memcpy
(
skb_push
(
skb
,
dev
->
hard_header_len
),
sk
->
ip_hcache_data
,
dev
->
hard_header_len
);
skb
->
arp
=
1
;
}
else
if
(
dev
->
hard_header
)
{
if
(
dev
->
hard_header
(
skb
,
dev
,
ETH_P_IP
,
NULL
,
NULL
,
0
)
>
0
)
skb
->
arp
=
1
;
}
skb
->
ip_hdr
=
iph
=
(
struct
iphdr
*
)
skb_put
(
skb
,
length
);
if
(
type
!=
IPPROTO_RAW
)
{
iph
->
version
=
4
;
iph
->
ihl
=
5
;
iph
->
tos
=
sk
->
ip_tos
;
iph
->
tot_len
=
htons
(
length
);
iph
->
id
=
htons
(
ip_id_count
++
);
iph
->
frag_off
=
0
;
iph
->
ttl
=
sk
->
ip_ttl
;
iph
->
protocol
=
type
;
iph
->
saddr
=
saddr
;
iph
->
daddr
=
daddr
;
iph
->
check
=
0
;
iph
->
check
=
ip_fast_csum
((
unsigned
char
*
)
iph
,
iph
->
ihl
);
getfrag
(
frag
,
saddr
,(
void
*
)(
iph
+
1
),
0
,
length
-
20
);
}
else
getfrag
(
frag
,
saddr
,(
void
*
)
iph
,
0
,
length
);
#ifdef CONFIG_IP_ACCT
ip_fw_chk
((
void
*
)
skb
->
data
,
dev
,
ip_acct_chain
,
IP_FW_F_ACCEPT
,
1
);
#endif
if
(
dev
->
flags
&
IFF_UP
)
dev_queue_xmit
(
skb
,
dev
,
sk
->
priority
);
else
{
ip_statistics
.
IpOutDiscards
++
;
kfree_skb
(
skb
,
FREE_WRITE
);
}
return
0
;
}
fragheaderlen
=
dev
->
hard_header_len
;
if
(
type
!=
IPPROTO_RAW
)
fragheaderlen
+=
20
;
...
...
@@ -2512,7 +2581,7 @@ int ip_build_xmit(struct sock *sk,
if
(
sk
->
ip_hcache_state
>
0
)
{
memcpy
(
skb
->
data
,
sk
->
ip_hcache_data
,
dev
->
hard_header_len
);
memcpy
(
skb
_push
(
skb
,
dev
->
hard_header_len
)
,
sk
->
ip_hcache_data
,
dev
->
hard_header_len
);
skb
->
arp
=
1
;
}
else
if
(
dev
->
hard_header
)
...
...
@@ -2526,7 +2595,7 @@ int ip_build_xmit(struct sock *sk,
* Find where to start putting bytes.
*/
iph
=
(
struct
iphdr
*
)
data
;
skb
->
ip_hdr
=
iph
=
(
struct
iphdr
*
)
data
;
/*
* Only write IP header onto non-raw packets
...
...
@@ -2620,6 +2689,13 @@ int ip_build_xmit(struct sock *sk,
kfree_skb
(
skb
,
FREE_READ
);
}
#endif
/*
* BSD loops broadcasts
*/
if
((
dev
->
flags
&
IFF_BROADCAST
)
&&
(
daddr
==
0xFFFFFFFF
||
daddr
==
dev
->
pa_brdaddr
)
&&
!
(
dev
->
flags
&
IFF_LOOPBACK
))
ip_loopback
(
dev
,
skb
);
/*
* Now queue the bytes into the device.
*/
...
...
net/ipv4/ipip.c
View file @
bb9c5bf1
...
...
@@ -56,7 +56,7 @@ int ipip_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
#ifdef TUNNEL_DEBUG
printk
(
"ipip_rcv: got a packet!
\n
"
);
#endif
i
p_forward
(
skb
,
dev
,
0
,
daddr
,
0
);
i
f
(
ip_forward
(
skb
,
dev
,
0
,
daddr
,
0
))
kfree_skb
(
skb
,
FREE_READ
);
MOD_DEC_USE_COUNT
;
return
(
0
);
...
...
net/ipv4/route.c
View file @
bb9c5bf1
...
...
@@ -29,6 +29,7 @@
* Alan Cox : RTF_REJECT support.
* Alan Cox : TCP irtt support.
* Jonathan Naylor : Added Metric support.
* Miquel van Smoorenburg : BSD API fixes.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
...
...
@@ -314,8 +315,7 @@ void ip_rt_add(short flags, unsigned long dst, unsigned long mask,
while
((
r
=
*
rp
)
!=
NULL
)
{
if
(
r
->
rt_dst
!=
dst
||
r
->
rt_mask
!=
mask
||
r
->
rt_metric
<
metric
)
r
->
rt_mask
!=
mask
)
{
rp
=
&
r
->
rt_next
;
continue
;
...
...
@@ -381,6 +381,7 @@ static int rt_new(struct rtentry *r)
char
*
devname
;
struct
device
*
dev
=
NULL
;
unsigned
long
flags
,
daddr
,
mask
,
gw
;
unsigned
char
metric
;
/*
* If a device is specified find it.
...
...
@@ -406,13 +407,14 @@ static int rt_new(struct rtentry *r)
/*
* Make local copies of the important bits
* We decrement the metric by one for BSD compatibility.
*/
flags
=
r
->
rt_flags
;
daddr
=
((
struct
sockaddr_in
*
)
&
r
->
rt_dst
)
->
sin_addr
.
s_addr
;
mask
=
((
struct
sockaddr_in
*
)
&
r
->
rt_genmask
)
->
sin_addr
.
s_addr
;
gw
=
((
struct
sockaddr_in
*
)
&
r
->
rt_gateway
)
->
sin_addr
.
s_addr
;
metric
=
r
->
rt_metric
>
0
?
r
->
rt_metric
-
1
:
0
;
/*
* BSD emulation: Permits route add someroute gw one-of-my-addresses
...
...
@@ -475,7 +477,7 @@ static int rt_new(struct rtentry *r)
* Add the route
*/
ip_rt_add
(
flags
,
daddr
,
mask
,
gw
,
dev
,
r
->
rt_mss
,
r
->
rt_window
,
r
->
rt_irtt
,
r
->
rt_
metric
);
ip_rt_add
(
flags
,
daddr
,
mask
,
gw
,
dev
,
r
->
rt_mss
,
r
->
rt_window
,
r
->
rt_irtt
,
metric
);
return
0
;
}
...
...
net/ipv4/udp.c
View file @
bb9c5bf1
...
...
@@ -45,6 +45,8 @@
* Arnt Gulbrandsen : New udp_send and stuff
* Alan Cox : Cache last socket
* Alan Cox : Route cache
* Alan Cox : Checksum precompute is bogus is some lame
* software is padding its udp frames in IP!
*
*
* This program is free software; you can redistribute it and/or
...
...
@@ -273,7 +275,10 @@ static int udp_send(struct sock *sk, struct sockaddr_in *sin,
else
a
=
ip_build_xmit
(
sk
,
udp_getfrag
,
&
ufh
,
ulen
,
sin
->
sin_addr
.
s_addr
,
rt
,
IPPROTO_UDP
);
return
(
a
<
0
?
a
:
len
);
if
(
a
<
0
)
return
a
;
udp_statistics
.
UdpOutDatagrams
++
;
return
len
;
}
...
...
@@ -533,6 +538,9 @@ int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
ulen
=
ntohs
(
uh
->
len
);
if
(
ulen
!=
len
)
skb
->
ip_summed
=
0
;
/* Bogoid padded frame */
if
(
ulen
>
len
||
len
<
sizeof
(
*
uh
)
||
ulen
<
sizeof
(
*
uh
))
{
NETDEBUG
(
printk
(
"UDP: short packet: %d/%d
\n
"
,
ulen
,
len
));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment