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
ab92dab4
Commit
ab92dab4
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 2.1.109pre1
parent
7eaba1c7
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
758 additions
and
628 deletions
+758
-628
CREDITS
CREDITS
+60
-52
Documentation/filesystems/ncpfs.txt
Documentation/filesystems/ncpfs.txt
+8
-8
Makefile
Makefile
+1
-1
arch/i386/kernel/entry.S
arch/i386/kernel/entry.S
+25
-12
arch/i386/kernel/ldt.c
arch/i386/kernel/ldt.c
+91
-46
arch/i386/kernel/process.c
arch/i386/kernel/process.c
+168
-60
arch/i386/kernel/ptrace.c
arch/i386/kernel/ptrace.c
+3
-12
arch/i386/kernel/signal.c
arch/i386/kernel/signal.c
+2
-17
arch/i386/kernel/traps.c
arch/i386/kernel/traps.c
+75
-84
arch/i386/mm/fault.c
arch/i386/mm/fault.c
+3
-3
arch/i386/mm/init.c
arch/i386/mm/init.c
+0
-1
drivers/char/console.c
drivers/char/console.c
+4
-1
drivers/net/de4x5.c
drivers/net/de4x5.c
+242
-219
drivers/net/de4x5.h
drivers/net/de4x5.h
+1
-1
fs/ncpfs/Makefile
fs/ncpfs/Makefile
+3
-3
include/asm-i386/bugs.h
include/asm-i386/bugs.h
+3
-3
include/asm-i386/processor.h
include/asm-i386/processor.h
+26
-28
include/asm-i386/system.h
include/asm-i386/system.h
+25
-73
kernel/fork.c
kernel/fork.c
+4
-0
kernel/printk.c
kernel/printk.c
+1
-2
mm/filemap.c
mm/filemap.c
+13
-2
No files found.
CREDITS
View file @
ab92dab4
This is at least a partial credits-file of people that have
contributed to the
linux project. It is sorted by name,
and
formatted
in a format that allows for easy grepping and
beautification by scripts. The fields are: name (N), email (E),
web-address (W), PGP key ID and fingerprint (P), description (D)
and snail-mail address (S).
contributed to the
Linux project. It is sorted by name
and
formatted
to allow easy grepping and beautification by
scripts. The fields are: name (N), email (E), web-address
(W), PGP key ID and fingerprint (P), description (D), and
snail-mail address (S).
Thanks,
Linus
...
...
@@ -46,8 +46,8 @@ W: http://www.inconnect.com/~andersen
P: 1024/FC4CFFED 78 3C 6A 19 FA 5D 92 5A FB AC 7B A5 A5 E1 FF 8E
D: Maintainer of ide-cd and Uniform CD-ROM driver,
D: ATAPI CD-Changer support, Major 2.1.x CD-ROM update.
S: 4538 South Carnegie Tech St
.
S: West Valley City, U
T
84120
S: 4538 South Carnegie Tech St
reet
S: West Valley City, U
tah
84120
S: USA
N: H. Peter Anvin
...
...
@@ -56,7 +56,7 @@ W: http://www.zytor.com/~hpa/
P: 2047/2A960705 BA 03 D3 2C 14 A8 A8 BD 1E DF FE 69 EE 35 BD 74
D: Author of the SYSLINUX boot loader, maintainer of the linux.* news
D: hierarchy and the Linux Device List; various kernel hacks
S: 4390 Albany Dr
.
#46
S: 4390 Albany Dr
ive
#46
S: San Jose, California 95129
S: USA
...
...
@@ -85,7 +85,8 @@ E: aycock@cpsc.ucalgary.ca
D: Adaptec 274x driver
S: Department of Computer Science
S: University of Calgary
S: Calgary, Alberta, Canada
S: Calgary, Alberta
S: Canada
N: Ralf Baechle
E: ralf@gnu.ai.mit.edu
...
...
@@ -143,7 +144,7 @@ S: Germany
N: Donald Becker
E: becker@cesdis.gsfc.nasa.gov
D: General low-level networking hacker
D: Most of the
ethercard
drivers
D: Most of the
Ethernet
drivers
D: Original author of the NFS server
S: USRA Center of Excellence in Space Data and Information Sciences
S: Code 930.5, Goddard Space Flight Center
...
...
@@ -185,7 +186,8 @@ D: Device driver hacking
D: Some Linux/ARM stuff
D: Co-architect of the parallel port sharing system
S: Nexus Electronics Ltd
S: 10 St Barnabas Road, Cambridge, UK. CB1 2BY
S: 10 St Barnabas Road, Cambridge CB1 2BY
S: United Kingdom
N: Thomas Bogendoerfer
E: tsbogend@alpha.franken.de
...
...
@@ -217,8 +219,9 @@ E: braam@cs.cmu.edu
W: http://coda.cs.cmu.edu/~braam
D: Coda Filesystem
S: Dept of Computer Science
S: 5000 Forbes Ave
S: Pittsburgh PA 15213
S: 5000 Forbes Avenue
S: Pittsburgh, Pennsylvania 15213
S: USA
N: Andries Brouwer
E: aeb@cwi.nl
...
...
@@ -273,7 +276,8 @@ E: chihjen@iis.sinica.edu.tw
D: IGMP(Internet Group Management Protocol) version 2
S: 3F, 65 Tajen street
S: Tamsui town, Taipei county,
S: Taiwan 251, Republic of China
S: Taiwan 251
S: Republic of China
N: Raymond Chen
E: raymondc@microsoft.com
...
...
@@ -412,7 +416,8 @@ S: Germany
N: Tom Dyas
E: tdyas@eden.rutgers.edu
D: minor hacks and some sparc port stuff
S: New Jersey, USA
S: New Jersey
S: USA
N: Drew Eckhardt
E: drew@PoohSticks.ORG
...
...
@@ -425,7 +430,7 @@ S: USA
N: Heiko Eissfeldt
E: heiko@colossus.escape.de heiko@unifix.de
D: verify_area stuff, generic
scsi
fixes
D: verify_area stuff, generic
SCSI
fixes
D: SCSI Programming HOWTO
D: POSIX.1 compliance testing
S: Unifix Software GmbH
...
...
@@ -458,7 +463,7 @@ E: fizban@tin.it
P: 1024/6E657BB5 AF 22 90 33 78 76 04 8B AF F9 97 1E B5 E2 65 30
D: Audio Excel DSP 16 init driver author
D: libmodem author
D: Yet Another Micro Monitor port and current mantainer
D: Yet Another Micro Monitor port and current ma
i
ntainer
D: First ELF-HOWTO author
D: random kernel hacker
S: Via Paolo VI n.29
...
...
@@ -482,7 +487,7 @@ S: Hungary
N: Jrgen Fischer
E: fischer@et-inf.fho-emden.de (=?iso-8859-1?q?J=FCrgen?= Fischer)
D: Author of Adaptec AHA-152x
scsi
driver
D: Author of Adaptec AHA-152x
SCSI
driver
S: Schulstrae 18
S: 26506 Norden
S: Germany
...
...
@@ -493,7 +498,7 @@ D: Improved mmap and munmap handling
D: General mm minor tidyups
S: 67 Surrey St.
S: Darlinghurst, Sydney
S: N
SW
2010
S: N
ew South Wales
2010
S: Australia
N: Ralf Flaxa
...
...
@@ -526,7 +531,7 @@ D: Initial GPL'd Frame Relay driver
D: Dynamic PPP devices
D: Sundry modularizations (PPP, IPX, ...) and fixes
S: Caldera, Inc.
S: 240 West Center St
.
S: 240 West Center St
reet
S: Orem, Utah 84059-1920
S: USA
...
...
@@ -571,7 +576,7 @@ D: prctl() syscall
D: /proc/mtrr support to manipulate MTRRs on Pentium Pro's
S: CSIRO Australia Telescope National Facility
S: P.O. Box 76, Epping
S: N
.S.W.
, 2121
S: N
ew South Wales
, 2121
S: Australia
N: Dmitry S. Gorodchanin
...
...
@@ -586,7 +591,7 @@ E: gpg109@rsphy1.anu.edu.au
W: http://rsphy1.anu.edu.au/~gpg109
D: Real Time Clock driver author.
D: 8390 net driver hacker (ne2000, wd8013, smc-ultra, 3c503, etc.)
D: Ethernet-H
owTo and BootPrompt-HowTo
author.
D: Ethernet-H
OWTO and BootPrompt-HOWTO
author.
D: Added many new CONFIG options (modules, ramdisk, generic-serial, etc.)
D: Implemented 1st "official" kernel thread (moved user bdflush to kflushd)
D: Various other random hacks, patches and utilities.
...
...
@@ -601,7 +606,7 @@ S: USA
N: Michael A. Griffith
E: grif@cs.ucr.edu
W: http://www.cs.ucr.edu/~grif
D: Loopback speedup, qlogic
scsi
hacking, VT_LOCKSWITCH
D: Loopback speedup, qlogic
SCSI
hacking, VT_LOCKSWITCH
S: Department of Computer Science
S: University of California, Riverside
S: Riverside, California 92521-0304
...
...
@@ -613,7 +618,7 @@ W: http://www.torque.net/linux-pp.html
D: original author of ppa driver for parallel port ZIP drive
D: original architect of the parallel-port sharing scheme
D: PARIDE subsystem: drivers for parallel port IDE & ATAPI devices
S: 44 St. Joseph St
.
, Suite 506
S: 44 St. Joseph St
reet
, Suite 506
S: Toronto, Ontario, M4Y 2W4
S: Canada
...
...
@@ -694,7 +699,7 @@ S: Germany
N: Michael Hipp
E: mhipp@student.uni-tuebingen.de
D: drivers for the racal ni5210 & ni6510
e
thernet-boards
D: drivers for the racal ni5210 & ni6510
E
thernet-boards
S: Talstr. 1
S: D - 72072 Tuebingen
S: Germany
...
...
@@ -716,7 +721,7 @@ N: Kenji Tsutomu Hollis
E: khollis@bitgate.com
W: http://www.nurk.org/
D: Berkshire PC Watchdog Driver
S: P
O
Box 15
S: P
ost Office
Box 15
S: Grants Pass, Oregon 97526
S: USA
...
...
@@ -739,7 +744,7 @@ P: 1024/1FD44539 DF 4B EB 9F 5B 68 38 9A 40 E3 FB 71 D1 C8 0B 56
D: Kernel development
D: Minor kernel modifications to support Wabi and Wine
S: Caldera, Inc.
S: 240 West Center St
.
S: 240 West Center St
reet
S: Orem, Utah 84059-1920
S: USA
...
...
@@ -854,7 +859,7 @@ S: Germany
N: Russell King
E: rmk@arm.uk.linux.org
D: Linux/arm integrat
e
r, maintainer & hacker
D: Linux/arm integrat
o
r, maintainer & hacker
S: Burgh Heath, Tadworth, Surrey.
S: England
...
...
@@ -870,8 +875,8 @@ E: ikluft@thunder.sbay.org
W: http://www.kluft.com/~ikluft/
D: NET-1 beta testing & minor patches, original Smail binary packages for
D: Slackware and Debian, vote-taker for 2nd comp.os.linux reorganization
S: P
O
Box 611311
S: San Jose, C
A
95161-1311
S: P
ost Office
Box 611311
S: San Jose, C
alifornia
95161-1311
S: USA
N: Alain L. Knaff
...
...
@@ -991,7 +996,7 @@ S: Australia
N: Hans Lermen
E: lermen@elserv.ffm.fgan.de
D: Author of the LOADLIN Linux loader, hacking on boot stuff
D: Co
-
ordinator of DOSEMU releases
D: Coordinator of DOSEMU releases
S: Am Muehlenweg 38
S: D53424 Remagen
S: Germany
...
...
@@ -1000,12 +1005,13 @@ N: Achim Leubner
E: achim@vortex.de
D: GDT SCSI Disk Array Controller driver
S: ICP vortex Computersysteme GmbH
S: Flein, Germany
S: Flein
S: Germany
N: Phil Lewis
E: beans@bucket.ualr.edu
D: Promised to send money if I would put his name in the source tree.
S: P
O
Box 371
S: P
ost Office
Box 371
S: North Little Rock, Arkansas 72115
S: USA
...
...
@@ -1041,7 +1047,7 @@ S: United Kingdom
N: Warner Losh
E: imp@village.org
D: Linux/MIPS Deskstation support, Provided OI/OB for Linux
S: 8786 Niwot Rd
S: 8786 Niwot R
oa
d
S: Niwot, Colorado 80503
S: USA
...
...
@@ -1099,7 +1105,7 @@ S: Australia
N: James B. MacLean
E: macleajb@ednet.ns.ca
W: http://www.ednet.ns.ca/~macleajb/dosemu.html
D: Former Co
-
ordinator of DOSEMU releases
D: Former Coordinator of DOSEMU releases
D: Program in DOSEMU
S: PO BOX 220, HFX. CENTRAL
S: Halifax, Nova Scotia
...
...
@@ -1138,7 +1144,7 @@ E: mike.mclagan@linux.org
W: http://www.invlogic.com/~mmclagan
D: DLCI/FRAD drivers for Sangoma SDLAs
S: Innovative Logic Corp
S: P
.O.
Box 1068
S: P
ost Office
Box 1068
S: Laurel, Maryland 20732
S: USA
...
...
@@ -1202,7 +1208,7 @@ D: New Linux-Activists maintainer
D: Linux Emacs elf/qmagic support + other libc/gcc things
D: Yee bore de yee bore! ;-)
S: 111 Alta Tierra Court
S: Los Gatos, C
A
95032
S: Los Gatos, C
alifornia
95032
S: USA
N: Rick Miller
...
...
@@ -1242,7 +1248,7 @@ N: David Mosberger-Tang
E: David.Mosberger@acm.org
D: Linux/Alpha
S: 35706 Runckel Lane
S: Fremont, C
A
94536
S: Fremont, C
alifornia
94536
S: USA
N: Ian A. Murdock
...
...
@@ -1285,8 +1291,8 @@ W: http://www.crynwr.com/~nelson
P: 1024/83942741 FF 68 EE 27 A0 5A AA C3 F5 DC 05 62 BD 5B 20 2F
D: Author of cs89x0, maintainer of kernel changelog through 1.3.3
D: Wrote many packet drivers, from which some Ethernet drivers are derived.
S: 521 Pleasant Valley R
d.
S: Potsdam, N
Y
13676
S: 521 Pleasant Valley R
oad
S: Potsdam, N
ew York
13676
S: USA
N: Michael Neuffer
...
...
@@ -1402,7 +1408,7 @@ E: quinlan@pathname.com
W: http://www.pathname.com/~quinlan/
D: FSSTND coordinator; FHS editor
D: random Linux documentation, patches, and hacks
S: 4390 Albany Dr
.
#41A
S: 4390 Albany Dr
ive
#41A
S: San Jose, California 95129
S: USA
...
...
@@ -1501,7 +1507,7 @@ D: Developed Generic IP Firewalling Chains with Michael Neuling.
N: Thomas Sailer
E: sailer@ife.ee.ethz.ch
E: HB9JNX@HB9W.CHE.EU (packet radio)
D: hfmodem, Baycom and
Sound
card radio modem driver
D: hfmodem, Baycom and
sound
card radio modem driver
S: Weinbergstrasse 76
S: 8408 Winterthur
S: Switzerland
...
...
@@ -1541,12 +1547,13 @@ D: Random Linux Hacker, Linux Promoter
D: CD-List, Books-List, Ex-FAQ
D: Linux-Support, -Mailbox, -Stammtisch
D: several improvements to system programs
S: Oldenburg, Germany
S: Oldenburg
S: Germany
N: Darren Senn
E: sinster@darkwater.com
D: Whatever I notice needs doing (so far: itimers, /proc)
S: P
OB
64132
S: P
ost Office Box
64132
S: Sunnyvale, California 94088-4132
S: USA
...
...
@@ -1589,11 +1596,11 @@ S: USA
N: Craig Small
E: csmall@triode.apana.org.au
E: vk2xlz@gonzo.vk2xlz.ampr.org (packet radio)
D: Gracilis PackeTwin device driver
D: RSPF daemon
S: 10 Stockalls Place
S: Minto, NSW, 2566
S: Australia
D: Gracilis PackeTwin device driver
D: RSPF daemon
N: Chris Smith
E: csmith@convex.com
...
...
@@ -1681,14 +1688,14 @@ D: Author of several small utilities
D: (bogomips, scope, eject, statserial)
S: 1 Laurie Court
S: Kanata, Ontario
S: C
ANADA
K2L 1S2
S: C
anada
K2L 1S2
N: Andrew Tridgell
E: Andrew.Tridgell@anu.edu.au
D: dosemu, networking, samba
S: 3 Ballow Crescent
S: MacGregor A.C.T
S:
2615
Australia
S: MacGregor A.C.T
2615
S: Australia
N: Winfried Trmper
E: winni@xpilot.org
...
...
@@ -1720,7 +1727,8 @@ E: tsusheng@scf.usc.edu
D: IGMP(Internet Group Management Protocol) version 2
S: 2F 14 ALY 31 LN 166 SEC 1 SHIH-PEI RD
S: Taipei
S: Taiwan 112, Republic of China
S: Taiwan 112
S: Republic of China
S: 24335 Delta Drive
S: Diamond Bar, California 91765
S: USA
...
...
@@ -1799,7 +1807,7 @@ D: Turtle Beach MultiSound sound driver
S: USA
N: Dirk Verworner
D: Co-author of
g
erman book ``Linux-Kernel-Programmierung''
D: Co-author of
G
erman book ``Linux-Kernel-Programmierung''
D: Co-founder of Berlin Linux User Group
N: Patrick Volkerding
...
...
@@ -1903,7 +1911,7 @@ S: Finland
N: Jonathan Woithe
E: jwoithe@physics.adelaide.edu.au
W: http://www.physics.adelaide.edu.au/~jwoithe
D: ALS-007 soundcard extensions to Sound Blaster driver
D: ALS-007 sound
card extensions to Sound Blaster driver
S: 4/36 Trevelyan St
S: Wayville SA 5034
S: Australia
...
...
Documentation/filesystems/ncpfs.txt
View file @
ab92dab4
ncpfs is a filesystem which
understands the NCP protocol, designed by the
Novell Corporation for their NetWare(tm) product. NCP is functionally
similar to the NFS used in the
tcp/ip
community.
To mount a Net
ware-F
ilesystem, you need a special mount program, which
can be found in
ncpfs package. Home
site for ncpfs is
The ncpfs filesystem
understands the NCP protocol, designed by the
Novell Corporation for their NetWare(tm) product.
NCP is functionally
similar to the NFS used in the
TCP/IP
community.
To mount a Net
Ware f
ilesystem, you need a special mount program, which
can be found in
the ncpfs package. The home
site for ncpfs is
ftp.gwdg.de/pub/linux/misc/ncpfs, but sunsite and its many mirrors
will have it as well.
Related products are linware and mars_nwe, which will give Linux partial
NetWare
Server functionality.
Linware's home site is: klokan.sh.cvut.cz/pub/linux/linware,
Mars_nwe can be found on
ftp.gwdg.de/pub/linux/misc/ncpfs.
NetWare
server functionality. Linware's home site is
klokan.sh.cvut.cz/pub/linux/linware; mars_nwe can be found on
ftp.gwdg.de/pub/linux/misc/ncpfs.
Makefile
View file @
ab92dab4
VERSION
=
2
PATCHLEVEL
=
1
SUBLEVEL
=
10
8
SUBLEVEL
=
10
9
ARCH
:=
$(
shell
uname
-m
|
sed
-e
s/i.86/i386/
-e
s/sun4u/sparc64/
-e
s/arm.
*
/arm/
-e
s/sa110/arm/
)
...
...
arch/i386/kernel/entry.S
View file @
ab92dab4
...
...
@@ -94,18 +94,31 @@ ENOSYS = 38
movl
%
dx
,%
ds
; \
movl
%
dx
,%
es
;
#define RESTORE_ALL \
popl
%
ebx
; \
popl
%
ecx
; \
popl
%
edx
; \
popl
%
esi
; \
popl
%
edi
; \
popl
%
ebp
; \
popl
%
eax
; \
popl
%
ds
; \
popl
%
es
; \
addl
$
4
,%
esp
; \
iret
#define RESTORE_ALL \
popl
%
ebx
; \
popl
%
ecx
; \
popl
%
edx
; \
popl
%
esi
; \
popl
%
edi
; \
popl
%
ebp
; \
popl
%
eax
; \
1
:
popl
%
ds
; \
2
:
popl
%
es
; \
3
:
addl
$
4
,%
esp
; \
iret
; \
.
section
fixup
,"
ax
"
; \
4
:
pushl
$
0
; \
popl
%
ds
; \
jmp
2
b
; \
5
:
pushl
$
0
; \
popl
%
es
; \
jmp
3
b
; \
.
previous
; \
.
section
__ex_table
,"
a
"
;\
.
align
4
; \
.
long
1
b
,
4
b
; \
.
long
2
b
,
5
b
; \
.
previous
#define GET_CURRENT(reg) \
movl
%
esp
,
reg
; \
...
...
arch/i386/kernel/ldt.c
View file @
ab92dab4
...
...
@@ -35,21 +35,29 @@ static int read_ldt(void * ptr, unsigned long bytecount)
static
int
write_ldt
(
void
*
ptr
,
unsigned
long
bytecount
,
int
oldmode
)
{
struct
mm_struct
*
mm
=
current
->
mm
;
void
*
ldt
;
__u32
entry_1
,
entry_2
,
*
lp
;
__u16
selector
,
reg_fs
,
reg_gs
;
int
error
;
struct
modify_ldt_ldt_s
ldt_info
;
unsigned
long
*
lp
;
struct
mm_struct
*
mm
;
int
error
,
i
;
error
=
-
EINVAL
;
if
(
bytecount
!=
sizeof
(
ldt_info
))
return
-
EINVAL
;
error
=
copy_from_user
(
&
ldt_info
,
ptr
,
sizeof
(
ldt_info
));
if
(
error
)
return
-
EFAULT
;
if
((
ldt_info
.
contents
==
3
&&
(
oldmode
||
ldt_info
.
seg_not_present
==
0
))
||
ldt_info
.
entry_number
>=
LDT_ENTRIES
)
return
-
EINVAL
;
goto
out
;
error
=
-
EFAULT
;
if
(
copy_from_user
(
&
ldt_info
,
ptr
,
sizeof
(
ldt_info
)))
goto
out
;
mm
=
current
->
mm
;
error
=
-
EINVAL
;
if
(
ldt_info
.
entry_number
>=
LDT_ENTRIES
)
goto
out
;
if
(
ldt_info
.
contents
==
3
)
{
if
(
oldmode
)
goto
out
;
if
(
ldt_info
.
seg_not_present
==
0
)
goto
out
;
}
/*
* Horrible dependencies! Try to get rid of this. This is wrong,
...
...
@@ -62,60 +70,97 @@ static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
* For no good reason except historical, the GDT index of the LDT
* is chosen to follow the index number in the task[] array.
*/
if
(
!
mm
->
segments
)
{
for
(
i
=
1
;
i
<
NR_TASKS
;
i
++
)
{
if
(
task
[
i
]
==
current
)
{
if
(
!
(
mm
->
segments
=
(
void
*
)
vmalloc
(
LDT_ENTRIES
*
LDT_ENTRY_SIZE
)))
return
-
ENOMEM
;
memset
(
mm
->
segments
,
0
,
LDT_ENTRIES
*
LDT_ENTRY_SIZE
);
set_ldt_desc
(
gdt
+
(
i
<<
1
)
+
FIRST_LDT_ENTRY
,
mm
->
segments
,
LDT_ENTRIES
);
load_ldt
(
i
);
}
ldt
=
mm
->
segments
;
if
(
!
ldt
)
{
error
=
-
ENOMEM
;
ldt
=
vmalloc
(
LDT_ENTRIES
*
LDT_ENTRY_SIZE
);
if
(
!
ldt
)
goto
out
;
memset
(
ldt
,
0
,
LDT_ENTRIES
*
LDT_ENTRY_SIZE
);
/*
* Make sure someone else hasn't allocated it for us ...
*/
if
(
!
mm
->
segments
)
{
int
i
=
current
->
tarray_ptr
-
&
task
[
0
];
mm
->
segments
=
ldt
;
set_ldt_desc
(
gdt
+
(
i
<<
1
)
+
FIRST_LDT_ENTRY
,
ldt
,
LDT_ENTRIES
);
load_ldt
(
i
);
if
(
mm
->
count
>
1
)
printk
(
KERN_WARNING
"LDT allocated for cloned task!
\n
"
);
}
else
{
vfree
(
ldt
);
}
}
lp
=
(
unsigned
long
*
)
(
LDT_ENTRY_SIZE
*
ldt_info
.
entry_number
+
(
unsigned
long
)
mm
->
segments
);
/*
* Check whether the entry to be changed is currently in use.
* If it is, we may need extra validation checks in case the
* kernel is forced to save and restore the selector.
*
* Note: we check the fs and gs values as well, as these are
* loaded by the signal code and during a task switch.
*/
selector
=
(
ldt_info
.
entry_number
<<
3
)
|
4
;
__asm__
(
"movw %%fs,%0"
:
"=r"
(
reg_fs
));
__asm__
(
"movw %%gs,%0"
:
"=r"
(
reg_gs
));
lp
=
(
__u32
*
)
((
selector
&
~
7
)
+
(
char
*
)
ldt
);
/* Allow LDTs to be cleared by the user. */
if
(
ldt_info
.
base_addr
==
0
&&
ldt_info
.
limit
==
0
&&
(
oldmode
||
(
ldt_info
.
contents
==
0
&&
ldt_info
.
read_exec_only
==
1
&&
ldt_info
.
seg_32bit
==
0
&&
ldt_info
.
limit_in_pages
==
0
&&
ldt_info
.
seg_not_present
==
1
&&
ldt_info
.
useable
==
0
))
)
{
*
lp
=
0
;
*
(
lp
+
1
)
=
0
;
return
0
;
if
(
ldt_info
.
base_addr
==
0
&&
ldt_info
.
limit
==
0
)
{
if
(
oldmode
||
(
ldt_info
.
contents
==
0
&&
ldt_info
.
read_exec_only
==
1
&&
ldt_info
.
seg_32bit
==
0
&&
ldt_info
.
limit_in_pages
==
0
&&
ldt_info
.
seg_not_present
==
1
&&
ldt_info
.
useable
==
0
))
{
entry_1
=
0
;
entry_2
=
0
;
goto
out_check
;
}
}
*
lp
=
((
ldt_info
.
base_addr
&
0x0000ffff
)
<<
16
)
|
entry_1
=
((
ldt_info
.
base_addr
&
0x0000ffff
)
<<
16
)
|
(
ldt_info
.
limit
&
0x0ffff
);
*
(
lp
+
1
)
=
(
ldt_info
.
base_addr
&
0xff000000
)
|
((
ldt_info
.
base_addr
&
0x00ff0000
)
>>
16
)
|
entry_2
=
(
ldt_info
.
base_addr
&
0xff000000
)
|
((
ldt_info
.
base_addr
&
0x00ff0000
)
>>
16
)
|
(
ldt_info
.
limit
&
0xf0000
)
|
(
ldt_info
.
contents
<<
10
)
|
((
ldt_info
.
read_exec_only
^
1
)
<<
9
)
|
(
ldt_info
.
contents
<<
10
)
|
((
ldt_info
.
seg_not_present
^
1
)
<<
15
)
|
(
ldt_info
.
seg_32bit
<<
22
)
|
(
ldt_info
.
limit_in_pages
<<
23
)
|
((
ldt_info
.
seg_not_present
^
1
)
<<
15
)
|
0x7000
;
if
(
!
oldmode
)
*
(
lp
+
1
)
|=
(
ldt_info
.
useable
<<
20
);
return
0
;
if
(
!
oldmode
)
entry_2
|=
(
ldt_info
.
useable
<<
20
);
out_check:
/* OK to change the entry ... */
*
lp
=
entry_1
;
*
(
lp
+
1
)
=
entry_2
;
error
=
0
;
out:
return
error
;
}
asmlinkage
int
sys_modify_ldt
(
int
func
,
void
*
ptr
,
unsigned
long
bytecount
)
{
int
ret
;
int
ret
=
-
ENOSYS
;
lock_kernel
();
if
(
func
==
0
)
switch
(
func
)
{
case
0
:
ret
=
read_ldt
(
ptr
,
bytecount
);
else
if
(
func
==
1
)
break
;
case
1
:
ret
=
write_ldt
(
ptr
,
bytecount
,
1
);
else
if
(
func
==
0x11
)
break
;
case
0x11
:
ret
=
write_ldt
(
ptr
,
bytecount
,
0
);
else
ret
=
-
ENOSYS
;
break
;
}
unlock_kernel
();
return
ret
;
}
arch/i386/kernel/process.c
View file @
ab92dab4
...
...
@@ -48,12 +48,10 @@
spinlock_t
semaphore_wake_lock
=
SPIN_LOCK_UNLOCKED
;
struct
task_struct
*
last_task_used_math
=
NULL
;
#ifdef __SMP__
asmlinkage
void
ret_from_
smp
fork
(
void
)
__asm__
(
"ret_from_smpfork"
);
asmlinkage
void
ret_from_fork
(
void
)
__asm__
(
"ret_from_smpfork"
);
#else
asmlinkage
void
ret_from_
sys_call
(
void
)
__asm__
(
"ret_from_sys_call"
);
asmlinkage
void
ret_from_
fork
(
void
)
__asm__
(
"ret_from_sys_call"
);
#endif
#ifdef CONFIG_APM
...
...
@@ -427,15 +425,20 @@ void show_regs(struct pt_regs * regs)
void
release_segments
(
struct
mm_struct
*
mm
)
{
void
*
ldt
;
void
*
ldt
=
mm
->
segments
;
int
nr
;
/* forget local segments */
__asm__
__volatile__
(
"movl %w0,%%fs ; movl %w0,%%gs ; lldt %w0"
:
/* no outputs */
:
"r"
(
0
));
current
->
tss
.
ldt
=
0
;
/*
* Set the GDT entry back to the default.
*/
nr
=
current
->
tarray_ptr
-
&
task
[
0
];
set_ldt_desc
(
gdt
+
(
nr
<<
1
)
+
FIRST_LDT_ENTRY
,
&
default_ldt
,
1
);
ldt
=
mm
->
segments
;
if
(
ldt
)
{
mm
->
segments
=
NULL
;
vfree
(
ldt
);
...
...
@@ -447,9 +450,7 @@ void release_segments(struct mm_struct *mm)
*/
void
exit_thread
(
void
)
{
/* forget lazy i387 state */
if
(
last_task_used_math
==
current
)
last_task_used_math
=
NULL
;
/* nothing to do ... */
}
void
flush_thread
(
void
)
...
...
@@ -462,71 +463,103 @@ void flush_thread(void)
/*
* Forget coprocessor state..
*/
#ifdef __SMP__
if
(
current
->
flags
&
PF_USEDFPU
)
{
current
->
flags
&=
~
PF_USEDFPU
;
stts
();
}
#else
if
(
last_task_used_math
==
current
)
{
last_task_used_math
=
NULL
;
stts
();
}
#endif
current
->
used_math
=
0
;
current
->
flags
&=
~
PF_USEDFPU
;
}
void
release_thread
(
struct
task_struct
*
dead_task
)
{
}
static
inline
void
unlazy_fpu
(
struct
task_struct
*
tsk
)
{
if
(
tsk
->
flags
&
PF_USEDFPU
)
{
tsk
->
flags
&=
~
PF_USEDFPU
;
__asm__
(
"fnsave %0"
:
"=m"
(
tsk
->
tss
.
i387
));
stts
();
}
}
/*
* If new_mm is NULL, we're being called to set up the LDT descriptor
* for a clone task. Each clone must have a separate entry in the GDT.
*/
void
copy_segments
(
int
nr
,
struct
task_struct
*
p
,
struct
mm_struct
*
new_mm
)
{
int
ldt_size
=
1
;
void
*
ldt
=
&
default_ldt
;
struct
mm_struct
*
old_mm
=
current
->
mm
;
void
*
old_ldt
=
old_mm
->
segments
,
*
ldt
=
old_ldt
;
int
ldt_size
=
LDT_ENTRIES
;
p
->
tss
.
ldt
=
_LDT
(
nr
);
if
(
old_mm
->
segments
)
{
new_mm
->
segments
=
vmalloc
(
LDT_ENTRIES
*
LDT_ENTRY_SIZE
);
if
(
new_mm
->
segments
)
{
ldt
=
new_mm
->
segments
;
ldt_size
=
LDT_ENTRIES
;
memcpy
(
ldt
,
old_mm
->
segments
,
LDT_ENTRIES
*
LDT_ENTRY_SIZE
);
if
(
old_ldt
)
{
if
(
new_mm
)
{
ldt
=
vmalloc
(
LDT_ENTRIES
*
LDT_ENTRY_SIZE
);
new_mm
->
segments
=
ldt
;
if
(
!
ldt
)
{
printk
(
KERN_WARNING
"ldt allocation failed
\n
"
);
goto
no_ldt
;
}
memcpy
(
ldt
,
old_ldt
,
LDT_ENTRIES
*
LDT_ENTRY_SIZE
);
}
}
else
{
no_ldt:
ldt
=
&
default_ldt
;
ldt_size
=
1
;
}
set_ldt_desc
(
gdt
+
(
nr
<<
1
)
+
FIRST_LDT_ENTRY
,
ldt
,
ldt_size
);
}
/*
* Save a segment.
*/
#define savesegment(seg,value) \
asm volatile("movl %%" #seg ",%0":"=m" (*(int *)&(value)))
/*
* Load a segment. Fall back on loading the zero
* segment if something goes wrong..
*/
#define loadsegment(seg,value) \
asm volatile("\n" \
"1:\t" \
"movl %0,%%" #seg "\n" \
"2:\n" \
".section fixup,\"ax\"\n" \
"3:\t" \
"pushl $0\n\t" \
"popl %%" #seg "\n\t" \
"jmp 2b\n" \
".previous\n" \
".section __ex_table,\"a\"\n\t" \
".align 4\n\t" \
".long 1b,3b\n" \
".previous" \
: :"m" (*(unsigned int *)&(value)))
int
copy_thread
(
int
nr
,
unsigned
long
clone_flags
,
unsigned
long
esp
,
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
{
struct
pt_regs
*
childregs
;
p
->
tss
.
tr
=
_TSS
(
nr
);
p
->
tss
.
es
=
__KERNEL_DS
;
p
->
tss
.
cs
=
__KERNEL_CS
;
p
->
tss
.
ss
=
__KERNEL_DS
;
p
->
tss
.
ds
=
__KERNEL_DS
;
p
->
tss
.
fs
=
__USER_DS
;
p
->
tss
.
gs
=
__USER_DS
;
set_tss_desc
(
gdt
+
(
nr
<<
1
)
+
FIRST_TSS_ENTRY
,
&
(
p
->
tss
));
p
->
tss
.
ss0
=
__KERNEL_DS
;
p
->
tss
.
esp0
=
2
*
PAGE_SIZE
+
(
unsigned
long
)
p
;
childregs
=
((
struct
pt_regs
*
)
(
p
->
tss
.
esp0
))
-
1
;
p
->
tss
.
esp
=
(
unsigned
long
)
childregs
;
#ifdef __SMP__
p
->
tss
.
eip
=
(
unsigned
long
)
ret_from_smpfork
;
p
->
tss
.
eflags
=
regs
->
eflags
&
0xffffcdff
;
/* iopl always 0 for a new process */
#else
p
->
tss
.
eip
=
(
unsigned
long
)
ret_from_sys_call
;
p
->
tss
.
eflags
=
regs
->
eflags
&
0xffffcfff
;
/* iopl always 0 for a new process */
#endif
p
->
tss
.
ebx
=
(
unsigned
long
)
p
;
*
childregs
=
*
regs
;
childregs
->
eax
=
0
;
childregs
->
esp
=
esp
;
p
->
tss
.
back_link
=
0
;
set_tss_desc
(
gdt
+
(
nr
<<
1
)
+
FIRST_TSS_ENTRY
,
&
(
p
->
tss
));
childregs
->
eflags
=
regs
->
eflags
&
0xffffcfff
;
/* iopl always 0 for a new process */
p
->
tss
.
esp
=
(
unsigned
long
)
childregs
;
p
->
tss
.
eip
=
(
unsigned
long
)
ret_from_fork
;
savesegment
(
fs
,
p
->
tss
.
fs
);
savesegment
(
gs
,
p
->
tss
.
gs
);
/*
* a bitmap offset pointing outside of the TSS limit causes a nicely
...
...
@@ -535,12 +568,9 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
*/
p
->
tss
.
bitmap
=
sizeof
(
struct
thread_struct
);
#ifdef __SMP__
if
(
current
->
flags
&
PF_USEDFPU
)
#else
if
(
last_task_used_math
==
current
)
#endif
__asm__
(
"clts ; fnsave %0 ; frstor %0"
:
"=m"
(
p
->
tss
.
i387
));
unlazy_fpu
(
current
);
asm
volatile
(
"fwait"
);
p
->
tss
.
i387
=
current
->
tss
.
i387
;
return
0
;
}
...
...
@@ -552,16 +582,11 @@ int dump_fpu (struct pt_regs * regs, struct user_i387_struct* fpu)
{
int
fpvalid
;
if
((
fpvalid
=
current
->
used_math
)
!=
0
)
{
if
(
boot_cpu_data
.
hard_math
)
{
if
(
last_task_used_math
==
current
)
{
__asm__
(
"clts ; fsave %0; fwait"
:
:
"m"
(
*
fpu
));
}
else
memcpy
(
fpu
,
&
current
->
tss
.
i387
.
hard
,
sizeof
(
*
fpu
));
}
else
{
memcpy
(
fpu
,
&
current
->
tss
.
i387
.
hard
,
sizeof
(
*
fpu
));
}
fpvalid
=
current
->
used_math
;
if
(
fpvalid
)
{
unlazy_fpu
(
current
);
asm
volatile
(
"fwait"
);
memcpy
(
fpu
,
&
current
->
tss
.
i387
.
hard
,
sizeof
(
*
fpu
));
}
return
fpvalid
;
...
...
@@ -597,8 +622,8 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
dump
->
regs
.
eax
=
regs
->
eax
;
dump
->
regs
.
ds
=
regs
->
xds
;
dump
->
regs
.
es
=
regs
->
xes
;
__asm__
(
"movl %%fs,%0"
:
"=r"
(
dump
->
regs
.
fs
)
);
__asm__
(
"movl %%gs,%0"
:
"=r"
(
dump
->
regs
.
gs
)
);
savesegment
(
fs
,
dump
->
regs
.
fs
);
savesegment
(
gs
,
dump
->
regs
.
gs
);
dump
->
regs
.
orig_eax
=
regs
->
orig_eax
;
dump
->
regs
.
eip
=
regs
->
eip
;
dump
->
regs
.
cs
=
regs
->
xcs
;
...
...
@@ -609,6 +634,89 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
dump
->
u_fpvalid
=
dump_fpu
(
regs
,
&
dump
->
i387
);
}
/*
* This special macro can be used to load a debugging register
*/
#define loaddebug(tsk,register) \
__asm__("movl %0,%%db" #register \
:
/* no output */
\
:"r" (tsk->debugreg[register]))
/*
* switch_to(x,yn) should switch tasks from x to y.
*
* We fsave/fwait so that an exception goes off at the right time
* (as a call from the fsave or fwait in effect) rather than to
* the wrong process. Lazy FP saving no longer makes any sense
* with modern CPU's, and this simplifies a lot of things (SMP
* and UP become the same).
*
* NOTE! We used to use the x86 hardware context switching. The
* reason for not using it any more becomes apparent when you
* try to recover gracefully from saved state that is no longer
* valid (stale segment register values in particular). With the
* hardware task-switch, there is no way to fix up bad state in
* a reasonable manner.
*
* The fact that Intel documents the hardware task-switching to
* be slow is a fairly red herring - this code is not noticeably
* faster. However, there _is_ some room for improvement here,
* so the performance issues may eventually be a valid point.
* More important, however, is the fact that this allows us much
* more flexibility.
*/
void
__switch_to
(
struct
task_struct
*
prev
,
struct
task_struct
*
next
)
{
/* Do the FPU save and set TS if it wasn't set before.. */
unlazy_fpu
(
prev
);
/*
* Reload TR, LDT and the page table pointers..
*
* We need TR for the IO permission bitmask (and
* the vm86 bitmasks in case we ever use enhanced
* v86 mode properly).
*
* We could do LDT things lazily if this turns out
* to be a win. Most processes will have the default
* LDT.
*
* We want to get rid of the TR register some day,
* and copy the bitmaps around by hand. Oh, well.
* In the meantime we have to clear the busy bit
* in the TSS entry, ugh.
*/
gdt_table
[
next
->
tss
.
tr
>>
3
].
b
&=
0xfffffdff
;
asm
volatile
(
"ltr %0"
:
:
"g"
(
*
(
unsigned
short
*
)
&
next
->
tss
.
tr
));
asm
volatile
(
"lldt %0"
:
:
"g"
(
*
(
unsigned
short
*
)
&
next
->
tss
.
ldt
));
if
(
next
->
tss
.
cr3
!=
prev
->
tss
.
cr3
)
asm
volatile
(
"movl %0,%%cr3"
:
:
"r"
(
next
->
tss
.
cr3
));
/*
* Save away %fs and %gs. No need to save %es and %ds, as
* those are always kernel segments while inside the kernel.
* Restore the new values.
*/
asm
volatile
(
"movl %%fs,%0"
:
"=m"
(
*
(
int
*
)
&
prev
->
tss
.
fs
));
asm
volatile
(
"movl %%gs,%0"
:
"=m"
(
*
(
int
*
)
&
prev
->
tss
.
gs
));
loadsegment
(
fs
,
next
->
tss
.
fs
);
loadsegment
(
gs
,
next
->
tss
.
gs
);
/*
* Now maybe reload the debug registers
*/
if
(
next
->
debugreg
[
7
]){
loaddebug
(
next
,
0
);
loaddebug
(
next
,
1
);
loaddebug
(
next
,
2
);
loaddebug
(
next
,
3
);
loaddebug
(
next
,
6
);
loaddebug
(
next
,
7
);
}
}
asmlinkage
int
sys_fork
(
struct
pt_regs
regs
)
{
int
ret
;
...
...
arch/i386/kernel/ptrace.c
View file @
ab92dab4
...
...
@@ -624,14 +624,8 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
#ifdef CONFIG_MATH_EMULATION
if
(
boot_cpu_data
.
hard_math
)
{
#endif
if
(
last_task_used_math
==
child
)
{
clts
();
__asm__
(
"fnsave %0; fwait"
:
"=m"
(
child
->
tss
.
i387
.
hard
));
last_task_used_math
=
NULL
;
stts
();
}
__copy_to_user
((
void
*
)
data
,
&
child
->
tss
.
i387
.
hard
,
sizeof
(
struct
user_i387_struct
));
__copy_to_user
((
void
*
)
data
,
&
child
->
tss
.
i387
.
hard
,
sizeof
(
struct
user_i387_struct
));
#ifdef CONFIG_MATH_EMULATION
}
else
{
save_i387_soft
(
&
child
->
tss
.
i387
.
soft
,
...
...
@@ -652,13 +646,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
#ifdef CONFIG_MATH_EMULATION
if
(
boot_cpu_data
.
hard_math
)
{
#endif
if
(
last_task_used_math
==
child
)
{
/* Discard the state of the FPU */
last_task_used_math
=
NULL
;
}
__copy_from_user
(
&
child
->
tss
.
i387
.
hard
,
(
void
*
)
data
,
sizeof
(
struct
user_i387_struct
));
child
->
flags
&=
~
PF_USEDFPU
;
stts
();
#ifdef CONFIG_MATH_EMULATION
}
else
{
restore_i387_soft
(
&
child
->
tss
.
i387
.
soft
,
...
...
arch/i386/kernel/signal.c
View file @
ab92dab4
...
...
@@ -153,17 +153,10 @@ struct rt_sigframe
static
inline
int
restore_i387_hard
(
struct
_fpstate
*
buf
)
{
#ifdef __SMP__
if
(
current
->
flags
&
PF_USEDFPU
)
{
current
->
flags
&=
~
PF_USEDFPU
;
stts
();
}
#else
if
(
current
==
last_task_used_math
)
{
last_task_used_math
=
NULL
;
stts
();
}
#endif
current
->
flags
&=
~
PF_USEDFPU
;
return
__copy_from_user
(
&
current
->
tss
.
i387
.
hard
,
buf
,
sizeof
(
*
buf
));
}
...
...
@@ -315,20 +308,12 @@ asmlinkage int sys_rt_sigreturn(unsigned long __unused)
static
inline
int
save_i387_hard
(
struct
_fpstate
*
buf
)
{
#ifdef __SMP__
if
(
current
->
flags
&
PF_USEDFPU
)
{
__asm__
__volatile__
(
"fnsave %0"
:
"=m"
(
current
->
tss
.
i387
.
hard
));
stts
();
current
->
flags
&=
~
PF_USEDFPU
;
}
#else
if
(
current
==
last_task_used_math
)
{
__asm__
__volatile__
(
"fnsave %0"
:
"=m"
(
current
->
tss
.
i387
.
hard
));
last_task_used_math
=
NULL
;
__asm__
__volatile__
(
"fwait"
);
/* not needed on 486+ */
stts
();
}
#endif
asm
volatile
(
"fwait"
);
current
->
tss
.
i387
.
hard
.
status
=
current
->
tss
.
i387
.
hard
.
swd
;
if
(
__copy_to_user
(
buf
,
&
current
->
tss
.
i387
.
hard
,
sizeof
(
*
buf
)))
return
-
1
;
...
...
arch/i386/kernel/traps.c
View file @
ab92dab4
...
...
@@ -66,23 +66,6 @@ out: \
unlock_kernel(); \
}
#define get_seg_byte(seg,addr) ({ \
register unsigned char __res; \
__asm__("pushl %%fs;movl %%ax,%%fs;movb %%fs:%2,%%al;popl %%fs" \
:"=a" (__res):"0" (seg),"m" (*(addr))); \
__res;})
#define get_seg_long(seg,addr) ({ \
register unsigned long __res; \
__asm__("pushl %%fs;movl %%ax,%%fs;movl %%fs:%2,%%eax;popl %%fs" \
:"=a" (__res):"0" (seg),"m" (*(addr))); \
__res;})
#define _fs() ({ \
register unsigned short __res; \
__asm__("movl %%fs,%%ax":"=a" (__res):); \
__res;})
void
page_exception
(
void
);
asmlinkage
void
divide_error
(
void
);
...
...
@@ -118,6 +101,7 @@ int kstack_depth_to_print = 24;
static
void
show_registers
(
struct
pt_regs
*
regs
)
{
int
i
;
int
in_kernel
=
1
;
unsigned
long
esp
;
unsigned
short
ss
;
unsigned
long
*
stack
,
addr
,
module_start
,
module_end
;
...
...
@@ -126,6 +110,7 @@ static void show_registers(struct pt_regs *regs)
esp
=
(
unsigned
long
)
&
regs
->
esp
;
ss
=
__KERNEL_DS
;
if
(
regs
->
xcs
&
3
)
{
in_kernel
=
0
;
esp
=
regs
->
esp
;
ss
=
regs
->
xss
&
0xffff
;
}
...
...
@@ -138,53 +123,59 @@ static void show_registers(struct pt_regs *regs)
printk
(
"ds: %04x es: %04x ss: %04x
\n
"
,
regs
->
xds
&
0xffff
,
regs
->
xes
&
0xffff
,
ss
);
store_TR
(
i
);
printk
(
"Process %s (pid: %d, process nr: %d, stackpage=%08lx)
\n
Stack:
"
,
printk
(
"Process %s (pid: %d, process nr: %d, stackpage=%08lx)"
,
current
->
comm
,
current
->
pid
,
0xffff
&
i
,
4096
+
(
unsigned
long
)
current
);
stack
=
(
unsigned
long
*
)
esp
;
for
(
i
=
0
;
i
<
kstack_depth_to_print
;
i
++
)
{
if
(((
long
)
stack
&
4095
)
==
0
)
break
;
if
(
i
&&
((
i
%
8
)
==
0
))
printk
(
"
\n
"
);
printk
(
"%08lx "
,
get_seg_long
(
ss
,
stack
++
));
}
printk
(
"
\n
Call Trace: "
);
stack
=
(
unsigned
long
*
)
esp
;
i
=
1
;
module_start
=
PAGE_OFFSET
+
(
max_mapnr
<<
PAGE_SHIFT
);
module_start
=
((
module_start
+
VMALLOC_OFFSET
)
&
~
(
VMALLOC_OFFSET
-
1
));
module_end
=
module_start
+
MODULE_RANGE
;
while
(((
long
)
stack
&
4095
)
!=
0
)
{
addr
=
get_seg_long
(
ss
,
stack
++
);
/*
* If the address is either in the text segment of the
* kernel, or in the region which contains vmalloc'ed
* memory, it *may* be the address of a calling
* routine; if so, print it so that someone tracing
* down the cause of the crash will be able to figure
* out the call path that was taken.
*/
if
(((
addr
>=
(
unsigned
long
)
&
_stext
)
&&
(
addr
<=
(
unsigned
long
)
&
_etext
))
||
((
addr
>=
module_start
)
&&
(
addr
<=
module_end
)))
{
/*
* When in-kernel, we also print out the stack and code at the
* time of the fault..
*/
if
(
in_kernel
)
{
printk
(
"
\n
Stack: "
);
stack
=
(
unsigned
long
*
)
esp
;
for
(
i
=
0
;
i
<
kstack_depth_to_print
;
i
++
)
{
if
(((
long
)
stack
&
4095
)
==
0
)
break
;
if
(
i
&&
((
i
%
8
)
==
0
))
printk
(
"
\n
"
);
printk
(
"[<%08lx>] "
,
addr
);
i
++
;
printk
(
"%08lx "
,
*
stack
++
);
}
printk
(
"
\n
Call Trace: "
);
stack
=
(
unsigned
long
*
)
esp
;
i
=
1
;
module_start
=
PAGE_OFFSET
+
(
max_mapnr
<<
PAGE_SHIFT
);
module_start
=
((
module_start
+
VMALLOC_OFFSET
)
&
~
(
VMALLOC_OFFSET
-
1
));
module_end
=
module_start
+
MODULE_RANGE
;
while
(((
long
)
stack
&
4095
)
!=
0
)
{
addr
=
*
stack
++
;
/*
* If the address is either in the text segment of the
* kernel, or in the region which contains vmalloc'ed
* memory, it *may* be the address of a calling
* routine; if so, print it so that someone tracing
* down the cause of the crash will be able to figure
* out the call path that was taken.
*/
if
(((
addr
>=
(
unsigned
long
)
&
_stext
)
&&
(
addr
<=
(
unsigned
long
)
&
_etext
))
||
((
addr
>=
module_start
)
&&
(
addr
<=
module_end
)))
{
if
(
i
&&
((
i
%
8
)
==
0
))
printk
(
"
\n
"
);
printk
(
"[<%08lx>] "
,
addr
);
i
++
;
}
}
printk
(
"
\n
Code: "
);
for
(
i
=
0
;
i
<
20
;
i
++
)
printk
(
"%02x "
,
((
unsigned
char
*
)
regs
->
eip
)[
i
]);
printk
(
"
\n
"
);
}
printk
(
"
\n
Code: "
);
for
(
i
=
0
;
i
<
20
;
i
++
)
printk
(
"%02x "
,
0xff
&
get_seg_byte
(
regs
->
xcs
&
0xffff
,(
i
+
(
char
*
)
regs
->
eip
)));
printk
(
"
\n
"
);
}
spinlock_t
die_lock
;
void
die
_if_kernel
(
const
char
*
str
,
struct
pt_regs
*
regs
,
long
err
)
void
die
(
const
char
*
str
,
struct
pt_regs
*
regs
,
long
err
)
{
if
((
regs
->
eflags
&
VM_MASK
)
||
(
3
&
regs
->
xcs
)
==
3
)
return
;
console_verbose
();
spin_lock_irq
(
&
die_lock
);
printk
(
"%s: %04lx
\n
"
,
str
,
err
&
0xffff
);
...
...
@@ -193,6 +184,12 @@ void die_if_kernel(const char * str, struct pt_regs * regs, long err)
do_exit
(
SIGSEGV
);
}
static
void
die_if_kernel
(
const
char
*
str
,
struct
pt_regs
*
regs
,
long
err
)
{
if
(
!
(
regs
->
eflags
&
VM_MASK
)
&&
!
(
3
&
regs
->
xcs
))
die
(
str
,
regs
,
err
);
}
DO_VM86_ERROR
(
0
,
SIGFPE
,
"divide error"
,
divide_error
,
current
)
DO_VM86_ERROR
(
3
,
SIGTRAP
,
"int3"
,
int3
,
current
)
DO_VM86_ERROR
(
4
,
SIGSEGV
,
"overflow"
,
overflow
,
current
)
...
...
@@ -200,7 +197,7 @@ DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds, current)
DO_ERROR
(
6
,
SIGILL
,
"invalid operand"
,
invalid_op
,
current
)
DO_VM86_ERROR
(
7
,
SIGSEGV
,
"device not available"
,
device_not_available
,
current
)
DO_ERROR
(
8
,
SIGSEGV
,
"double fault"
,
double_fault
,
current
)
DO_ERROR
(
9
,
SIGFPE
,
"coprocessor segment overrun"
,
coprocessor_segment_overrun
,
last_task_used_math
)
DO_ERROR
(
9
,
SIGFPE
,
"coprocessor segment overrun"
,
coprocessor_segment_overrun
,
current
)
DO_ERROR
(
10
,
SIGSEGV
,
"invalid TSS"
,
invalid_TSS
,
current
)
DO_ERROR
(
11
,
SIGBUS
,
"segment not present"
,
segment_not_present
,
current
)
DO_ERROR
(
12
,
SIGBUS
,
"stack segment"
,
stack_segment
,
current
)
...
...
@@ -224,17 +221,34 @@ asmlinkage void cache_flush_denied(struct pt_regs * regs, long error_code)
asmlinkage
void
do_general_protection
(
struct
pt_regs
*
regs
,
long
error_code
)
{
if
(
regs
->
eflags
&
VM_MASK
)
goto
gp_in_vm86
;
if
(
!
(
regs
->
xcs
&
3
))
goto
gp_in_kernel
;
lock_kernel
();
if
(
regs
->
eflags
&
VM_MASK
)
{
handle_vm86_fault
((
struct
kernel_vm86_regs
*
)
regs
,
error_code
);
goto
out
;
}
die_if_kernel
(
"general protection"
,
regs
,
error_code
);
current
->
tss
.
error_code
=
error_code
;
current
->
tss
.
trap_no
=
13
;
force_sig
(
SIGSEGV
,
current
);
out:
return
;
gp_in_vm86:
lock_kernel
();
handle_vm86_fault
((
struct
kernel_vm86_regs
*
)
regs
,
error_code
);
unlock_kernel
();
return
;
gp_in_kernel:
{
unsigned
long
fixup
;
fixup
=
search_exception_table
(
regs
->
eip
);
if
(
fixup
)
{
regs
->
eip
=
fixup
;
return
;
}
die
(
"general protection fault"
,
regs
,
error_code
);
}
}
static
void
mem_parity_error
(
unsigned
char
reason
,
struct
pt_regs
*
regs
)
...
...
@@ -295,9 +309,7 @@ asmlinkage void do_debug(struct pt_regs * regs, long error_code)
__asm__
(
"movl %0,%%db7"
:
/* no output */
:
"r"
(
0
));
goto
out
;
}
die_if_kernel
(
"debug"
,
regs
,
error_code
);
out:
unlock_kernel
();
}
...
...
@@ -313,16 +325,7 @@ void math_error(void)
lock_kernel
();
clts
();
#ifdef __SMP__
task
=
current
;
#else
task
=
last_task_used_math
;
last_task_used_math
=
NULL
;
if
(
!
task
)
{
__asm__
(
"fnclex"
);
goto
out
;
}
#endif
/*
* Save the info for the exception handler
*/
...
...
@@ -333,9 +336,6 @@ void math_error(void)
force_sig
(
SIGFPE
,
task
);
task
->
tss
.
trap_no
=
16
;
task
->
tss
.
error_code
=
0
;
#ifndef __SMP__
out:
#endif
unlock_kernel
();
}
...
...
@@ -373,15 +373,6 @@ asmlinkage void math_state_restore(void)
* case we swap processors. We also don't use the coprocessor
* timer - IRQ 13 mode isn't used with SMP machines (thank god).
*/
#ifndef __SMP__
if
(
last_task_used_math
==
current
)
return
;
if
(
last_task_used_math
)
__asm__
(
"fnsave %0"
:
"=m"
(
last_task_used_math
->
tss
.
i387
));
else
__asm__
(
"fnclex"
);
last_task_used_math
=
current
;
#endif
if
(
current
->
used_math
)
__asm__
(
"frstor %0"
:
:
"m"
(
current
->
tss
.
i387
));
...
...
arch/i386/mm/fault.c
View file @
ab92dab4
...
...
@@ -22,7 +22,7 @@
#include <asm/pgtable.h>
#include <asm/hardirq.h>
extern
void
die
_if_kernel
(
const
char
*
,
struct
pt_regs
*
,
long
);
extern
void
die
(
const
char
*
,
struct
pt_regs
*
,
long
);
/*
* Ugly, ugly, but the goto's result in better assembly..
...
...
@@ -101,7 +101,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
__asm__
(
"movl %%cr2,%0"
:
"=r"
(
address
));
if
(
local_irq_count
[
smp_processor_id
()])
die
_if_kernel
(
"page fault from irq handler"
,
regs
,
error_code
);
die
(
"page fault from irq handler"
,
regs
,
error_code
);
tsk
=
current
;
mm
=
tsk
->
mm
;
...
...
@@ -235,7 +235,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
printk
(
KERN_ALERT
"*pte = %08lx
\n
"
,
page
);
}
lock_kernel
();
die
_if_kernel
(
"Oops"
,
regs
,
error_code
);
die
(
"Oops"
,
regs
,
error_code
);
do_exit
(
SIGKILL
);
unlock_kernel
();
}
arch/i386/mm/init.c
View file @
ab92dab4
...
...
@@ -27,7 +27,6 @@
#include <asm/pgtable.h>
#include <asm/dma.h>
extern
void
die_if_kernel
(
char
*
,
struct
pt_regs
*
,
long
);
extern
void
show_net_buffers
(
void
);
void
__bad_pte_kernel
(
pmd_t
*
pmd
)
...
...
drivers/char/console.c
View file @
ab92dab4
...
...
@@ -2316,7 +2316,6 @@ __initfunc(unsigned long con_init(unsigned long kmem_start))
{
const
char
*
display_desc
=
NULL
;
unsigned
int
currcons
=
0
;
char
q
[
2
]
=
{
0
,
1
};
if
(
conswitchp
)
kmem_start
=
conswitchp
->
con_startup
(
kmem_start
,
...
...
@@ -2397,11 +2396,15 @@ __initfunc(unsigned long con_init(unsigned long kmem_start))
#if 0
/* The logo is too ugly to live */
{
char q[2] = { 0, 1 };
if (console_show_logo)
q[1] += console_show_logo();
conswitchp->con_putcs(vc_cons[fg_console].d, linux_logo_banner,
sizeof(linux_logo_banner)-1, q[1]-1, q[0]);
putconsxy(0, q);
}
#endif
sw
->
con_cursor
(
vc_cons
[
currcons
].
d
,
CM_DRAW
);
printk
(
"Console: %s %s %ldx%ld"
,
...
...
drivers/net/de4x5.c
View file @
ab92dab4
...
...
@@ -213,14 +213,17 @@
insmod de4x5 args='eth1:fdx autosense=BNC eth0:autosense=100Mb'.
For a compiled in driver,
somewhere in this file
, place e.g.
For a compiled in driver,
at or above line 548
, place e.g.
#define DE4X5_PARM "eth0:fdx autosense=AUI eth2:autosense=TP"
Yes, I know full duplex
isn't
permissible on BNC or AUI; they're just
examples. By default, full duplex is turned
off and
AUTO is the default
autosense setting.
In reality, I expect only the
full duplex option to
Yes, I know full duplex
isn't
permissible on BNC or AUI; they're just
examples. By default, full duplex is turned
off and
AUTO is the default
autosense setting.
In reality, I expect only the
full duplex option to
be used. Note the use of single quotes in the two examples above and the
lack of commas to separate items.
lack of commas to separate items. ALSO, you must get the requested media
correct in relation to what the adapter SROM says it has. There's no way
to determine this in advance other than by trial and error and common
sense, e.g. call a BNC connectored port 'BNC', not '10Mb'.
TO DO:
------
...
...
@@ -374,11 +377,33 @@
0.535 21-Feb-98 Fix Ethernet Address PROM reset bug for DC21040.
0.536 21-Mar-98 Change pci_probe() to use the pci_dev structure.
**Incompatible with 2.0.x from here.**
0.540 5-Jul-98 Atomicize assertion of dev->interrupt for SMP
from <lma@varesearch.com>
Add TP, AUI and BNC cases to 21140m_autoconf() for
case where a 21140 under SROM control uses, e.g. AUI
from problem report by <delchini@lpnp09.in2p3.fr>
Add MII parallel detection to 2114x_autoconf() for
case where no autonegotiation partner exists from
problem report by <mlapsley@ndirect.co.uk>.
Add ability to force connection type directly even
when using SROM control from problem report by
<earl@exis.net>.
Updated the PCI interface to conform with the latest
version. I hope nothing is broken...
Add TX done interrupt modification from suggestion
by <Austin.Donnelly@cl.cam.ac.uk>.
Fix is_anc_capable() bug reported by
<Austin.Donnelly@cl.cam.ac.uk>.
Fix type[13]_infoblock() bug: during MII search, PHY
lp->rst not run because lp->ibn not initialised -
from report & fix by <paubert@iram.es>.
Fix probe bug with EISA & PCI cards present from
report by <eirik@netcom.com>.
=========================================================================
*/
static
const
char
*
version
=
"de4x5.c:V0.5
36 1998/3
/5 davies@maniac.ultranet.com
\n
"
;
static
const
char
*
version
=
"de4x5.c:V0.5
40 1998/7
/5 davies@maniac.ultranet.com
\n
"
;
#include <linux/config.h>
#include <linux/module.h>
...
...
@@ -933,7 +958,7 @@ static int test_bad_enet(struct device *dev, int status);
static
void
eisa_probe
(
struct
device
*
dev
,
u_long
iobase
);
#endif
static
void
pci_probe
(
struct
device
*
dev
,
u_long
iobase
);
static
void
srom_search
(
int
index
);
static
void
srom_search
(
struct
pci_dev
*
pdev
);
static
char
*
build_setup_frame
(
struct
device
*
dev
,
int
mode
);
static
void
disable_ast
(
struct
device
*
dev
);
static
void
enable_ast
(
struct
device
*
dev
,
u32
time_out
);
...
...
@@ -980,12 +1005,12 @@ static int loading_module = 0;
static
char
name
[
DE4X5_NAME_LENGTH
+
1
];
#if !defined(__sparc_v9__) && !defined(__powerpc__)
static
u_char
de4x5_irq
[]
=
EISA_ALLOWED_IRQ_LIST
;
static
int
lastEISA
=
0
;
#else
static
int
lastEISA
=
MAX_EISA_SLOTS
;
/* Only PCI probes */
#endif
static
int
num_de4x5s
=
0
;
static
int
cfrv
=
0
,
useSROM
=
0
;
#if !defined(__sparc_v9__) && !defined(__powerpc__)
static
int
lastEISA
=
0
;
#endif
static
int
lastPCI
=
-
1
;
static
struct
device
*
lastModule
=
NULL
;
...
...
@@ -1036,9 +1061,9 @@ static int (*dc_infoblock[])(struct device *dev, u_char, u_char *) = {
#define PHY_HARD_RESET {\
outl(GEP_HRST, DE4X5_GEP);
/* Hard RESET the PHY dev. */
\
mdelay(1);
/* Assert for 1ms */
\
mdelay(1);
/* Assert for 1ms */
\
outl(0x00, DE4X5_GEP);\
mdelay(2);
/* Wait for 2ms */
\
mdelay(2);
/* Wait for 2ms */
\
}
...
...
@@ -1054,7 +1079,9 @@ de4x5_probe(struct device *dev))
#if !defined(__sparc_v9__) && !defined(__powerpc__)
eisa_probe
(
dev
,
iobase
);
#endif
pci_probe
(
dev
,
iobase
);
if
(
lastEISA
==
MAX_EISA_SLOTS
)
{
pci_probe
(
dev
,
iobase
);
}
return
(
dev
->
priv
?
0
:
-
ENODEV
);
}
...
...
@@ -1151,21 +1178,15 @@ de4x5_hw_init(struct device *dev, u_long iobase))
/*
** Choose correct autosensing in case someone messed up
*/
if
((
lp
->
params
.
autosense
&
AUTO
)
||
lp
->
useSROM
)
{
lp
->
autosense
=
AUTO
;
}
else
{
if
(
lp
->
chipset
!=
DC21140
)
{
if
((
lp
->
chipset
==
DC21040
)
&&
(
lp
->
params
.
autosense
&
TP_NW
))
{
lp
->
params
.
autosense
=
TP
;
}
if
((
lp
->
chipset
==
DC21041
)
&&
(
lp
->
params
.
autosense
&
BNC_AUI
))
{
lp
->
params
.
autosense
=
BNC
;
}
lp
->
autosense
=
lp
->
params
.
autosense
&
0x001f
;
}
else
{
lp
->
autosense
=
lp
->
params
.
autosense
&
0x00c0
;
}
}
lp
->
autosense
=
lp
->
params
.
autosense
;
if
(
lp
->
chipset
!=
DC21140
)
{
if
((
lp
->
chipset
==
DC21040
)
&&
(
lp
->
params
.
autosense
&
TP_NW
))
{
lp
->
params
.
autosense
=
TP
;
}
if
((
lp
->
chipset
==
DC21041
)
&&
(
lp
->
params
.
autosense
&
BNC_AUI
))
{
lp
->
params
.
autosense
=
BNC
;
}
}
lp
->
fdx
=
lp
->
params
.
fdx
;
sprintf
(
lp
->
adapter_name
,
"%s (%s)"
,
name
,
dev
->
name
);
...
...
@@ -1308,8 +1329,9 @@ de4x5_open(struct device *dev)
lp
->
state
=
OPEN
;
de4x5_dbg_open
(
dev
);
if
(
request_irq
(
dev
->
irq
,
(
void
*
)
de4x5_interrupt
,
SA_SHIRQ
,
lp
->
adapter_name
,
dev
))
{
lp
->
adapter_name
,
dev
))
{
printk
(
"de4x5_open(): Requested IRQ%d is busy - attemping FAST/SHARE..."
,
dev
->
irq
);
if
(
request_irq
(
dev
->
irq
,
de4x5_interrupt
,
SA_INTERRUPT
|
SA_SHIRQ
,
lp
->
adapter_name
,
dev
))
{
...
...
@@ -1448,7 +1470,7 @@ de4x5_sw_reset(struct device *dev)
}
/*
** Writes a socket buffer address to the next available transmit descriptor
** Writes a socket buffer address to the next available transmit descriptor
.
*/
static
int
de4x5_queue_pkt
(
struct
sk_buff
*
skb
,
struct
device
*
dev
)
...
...
@@ -1542,12 +1564,11 @@ de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs)
lp
=
(
struct
de4x5_private
*
)
dev
->
priv
;
iobase
=
dev
->
base_addr
;
if
(
dev
->
interrupt
)
printk
(
"%s: Re-entering the interrupt handler.
\n
"
,
dev
->
name
);
if
(
test_and_set_bit
(
MASK_INTERRUPTS
,
(
void
*
)
&
dev
->
interrupt
)
)
printk
(
"%s: Re-entering the interrupt handler.
\n
"
,
dev
->
name
);
DISABLE_IRQs
;
/* Ensure non re-entrancy */
synchronize_irq
();
dev
->
interrupt
=
MASK_INTERRUPTS
;
for
(
limit
=
0
;
limit
<
8
;
limit
++
)
{
sts
=
inl
(
DE4X5_STS
);
/* Read IRQ status */
...
...
@@ -1868,16 +1889,27 @@ de4x5_local_stats(struct device *dev, char *buf, int pkt_len)
return
;
}
/*
** Removes the TD_IC flag from previous descriptor to improve TX performance.
** If the flag is changed on a descriptor that is being read by the hardware,
** I assume PCI transaction ordering will mean you are either successful or
** just miss asserting the change to the hardware. Anyway you're messing with
** a descriptor you don't own, but this shouldn't kill the chip provided
** the descriptor register is read only to the hardware.
*/
static
void
load_packet
(
struct
device
*
dev
,
char
*
buf
,
u32
flags
,
struct
sk_buff
*
skb
)
{
struct
de4x5_private
*
lp
=
(
struct
de4x5_private
*
)
dev
->
priv
;
int
entry
=
(
lp
->
tx_new
?
lp
->
tx_new
-
1
:
lp
->
txRingSize
-
1
);
lp
->
tx_ring
[
lp
->
tx_new
].
buf
=
cpu_to_le32
(
virt_to_bus
(
buf
));
lp
->
tx_ring
[
lp
->
tx_new
].
des1
&=
cpu_to_le32
(
TD_TER
);
lp
->
tx_ring
[
lp
->
tx_new
].
des1
|=
cpu_to_le32
(
flags
);
lp
->
tx_skb
[
lp
->
tx_new
]
=
skb
;
lp
->
tx_ring
[
entry
].
des1
&=
cpu_to_le32
(
~
TD_IC
);
barrier
();
lp
->
tx_ring
[
lp
->
tx_new
].
status
=
cpu_to_le32
(
T_OWN
);
barrier
();
...
...
@@ -2044,7 +2076,7 @@ eisa_probe(struct device *dev, u_long ioaddr))
return
;
}
#endif
/* !(__sparc_v9__) */
#endif
/* !(__sparc_v9__)
&& !(__powerpc__)
*/
/*
** PCI bus I/O device probe
...
...
@@ -2057,22 +2089,25 @@ eisa_probe(struct device *dev, u_long ioaddr))
** bit. Here, check for I/O accesses and then set BM. If you put the card in
** a non BM slot, you're on your own (and complain to the PC vendor that your
** PC doesn't conform to the PCI standard)!
**
** This function is only compatible with the *latest* 2.1.x kernels. For 2.0.x
** kernels use the V0.535[n] drivers.
*/
#define PCI_DEVICE (dev_num << 3)
#define PCI_LAST_DEV 32
__initfunc
(
static
void
pci_probe
(
struct
device
*
dev
,
u_long
ioaddr
))
{
u_char
pb
,
pbus
,
dev_num
,
dnum
,
dev_fn
,
timer
;
u_short
dev_id
,
vendor
,
index
,
status
;
u_char
pb
,
pbus
,
dev_num
,
dnum
,
timer
;
u_short
vendor
,
index
,
status
;
u_int
irq
=
0
,
device
,
class
=
DE4X5_CLASS_CODE
;
u_long
iobase
=
0
;
/* Clear upper 32 bits in Alphas */
struct
bus_type
*
lp
=
&
bus
;
struct
pci_dev
*
pdev
=
NULL
;
if
(
lastPCI
==
NO_MORE_PCI
)
return
;
if
(
!
pci_present
())
{
if
(
!
pci
bios
_present
())
{
lastPCI
=
NO_MORE_PCI
;
return
;
/* No PCI bus in this machine! */
}
...
...
@@ -2088,96 +2123,77 @@ pci_probe(struct device *dev, u_long ioaddr))
dnum
=
0
;
}
for
(
index
=
lastPCI
+
1
;
(
pcibios_find_class
(
class
,
index
,
&
pb
,
&
dev_fn
)
!=
PCIBIOS_DEVICE_NOT_FOUND
);
index
++
)
{
dev_num
=
PCI_SLOT
(
dev_fn
);
if
((
!
pbus
&&
!
dnum
)
||
((
pbus
==
pb
)
&&
(
dnum
==
dev_num
)))
{
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,85)
struct
pci_dev
*
pdev
=
pci_find_slot
(
pb
,
dev_fn
);
#else
u_char
tirq
;
u_int
tmp
;
#endif
device
=
0
;
pcibios_read_config_word
(
pb
,
PCI_DEVICE
,
PCI_VENDOR_ID
,
&
vendor
);
pcibios_read_config_word
(
pb
,
PCI_DEVICE
,
PCI_DEVICE_ID
,
&
dev_id
);
device
=
dev_id
;
device
<<=
8
;
if
(
!
(
is_DC21040
||
is_DC21041
||
is_DC21140
||
is_DC2114x
))
{
continue
;
}
/* Search for an SROM on this bus */
if
(
lp
->
bus_num
!=
pb
)
{
lp
->
bus_num
=
pb
;
srom_search
(
index
);
}
for
(
index
=
lastPCI
+
1
;
(
pdev
=
pci_find_class
(
class
,
pdev
))
!=
NULL
;
index
++
)
{
dev_num
=
PCI_SLOT
(
pdev
->
devfn
);
pb
=
pdev
->
bus
->
number
;
if
((
pbus
||
dnum
)
&&
((
pbus
!=
pb
)
||
(
dnum
!=
dev_num
)))
continue
;
/* Get the chip configuration revision register */
pcibios_read_config_dword
(
pb
,
PCI_DEVICE
,
PCI_REVISION_ID
,
&
cfrv
);
vendor
=
pdev
->
vendor
;
device
=
pdev
->
device
<<
8
;
if
(
!
(
is_DC21040
||
is_DC21041
||
is_DC21140
||
is_DC2114x
))
continue
;
/* Set the device number information
*/
lp
->
device
=
dev_num
;
/* Search for an SROM on this bus
*/
if
(
lp
->
bus_num
!=
pb
)
{
lp
->
bus_num
=
pb
;
/* Set the chipset information */
if
(
is_DC2114x
)
device
|=
(
cfrv
&
CFRV_RN
);
lp
->
chipset
=
device
;
srom_search
(
pdev
);
}
/* Get the board I/O address and IRQ */
#if LINUX_VERSION_CODE < LinuxVersionCode(2,1,85)
pcibios_read_config_dword
(
pb
,
PCI_DEVICE
,
PCI_BASE_ADDRESS_0
,
&
tmp
);
iobase
=
tmp
;
pcibios_read_config_byte
(
pb
,
PCI_DEVICE
,
PCI_INTERRUPT_LINE
,
&
tirq
);
irq
=
tirq
;
#else
iobase
=
pdev
->
base_address
[
0
];
irq
=
pdev
->
irq
;
#endif
iobase
&=
CBIO_MASK
;
/* Get the chip configuration revision register */
pcibios_read_config_dword
(
pb
,
pdev
->
devfn
,
PCI_REVISION_ID
,
&
cfrv
);
/* Set the device number information */
lp
->
device
=
dev_num
;
lp
->
bus_num
=
pb
;
/* Set the chipset information */
if
(
is_DC2114x
)
device
|=
(
cfrv
&
CFRV_RN
);
lp
->
chipset
=
device
;
if
((
irq
==
0
)
||
(
irq
==
0xff
)
||
((
int
)
irq
==
-
1
))
continue
;
/* Get the board I/O address (64 bits on sparc64) */
iobase
=
pdev
->
base_address
[
0
]
&
CBIO_MASK
;
/* Check if I/O accesses and Bus Mastering are enabled */
pcibios_read_config_word
(
pb
,
PCI_DEVICE
,
PCI_COMMAND
,
&
status
);
/* Fetch the IRQ to be used */
irq
=
pdev
->
irq
;
if
((
irq
==
0
)
||
(
irq
==
0xff
)
||
((
int
)
irq
==
-
1
))
continue
;
/* Check if I/O accesses and Bus Mastering are enabled */
pcibios_read_config_word
(
pb
,
pdev
->
devfn
,
PCI_COMMAND
,
&
status
);
#ifdef __powerpc__
if
(
!
(
status
&
PCI_COMMAND_IO
))
{
status
|=
PCI_COMMAND_IO
;
pcibios_write_config_word
(
pb
,
PCI_DEVICE
,
PCI_COMMAND
,
status
);
pcibios_read_config_word
(
pb
,
PCI_DEVICE
,
PCI_COMMAND
,
&
status
);
}
if
(
!
(
status
&
PCI_COMMAND_IO
))
{
status
|=
PCI_COMMAND_IO
;
pcibios_write_config_word
(
pb
,
pdev
->
devfn
,
PCI_COMMAND
,
status
);
pcibios_read_config_word
(
pb
,
pdev
->
devfn
,
PCI_COMMAND
,
&
status
);
}
#endif
/* __powerpc__ */
if
(
!
(
status
&
PCI_COMMAND_IO
))
continue
;
if
(
!
(
status
&
PCI_COMMAND_IO
))
continue
;
if
(
!
(
status
&
PCI_COMMAND_MASTER
))
{
status
|=
PCI_COMMAND_MASTER
;
pcibios_write_config_word
(
pb
,
PCI_DEVICE
,
PCI_COMMAND
,
status
);
pcibios_read_config_word
(
pb
,
PCI_DEVICE
,
PCI_COMMAND
,
&
status
);
}
if
(
!
(
status
&
PCI_COMMAND_MASTER
))
continue
;
if
(
!
(
status
&
PCI_COMMAND_MASTER
))
{
status
|=
PCI_COMMAND_MASTER
;
pcibios_write_config_word
(
pb
,
pdev
->
devfn
,
PCI_COMMAND
,
status
);
pcibios_read_config_word
(
pb
,
pdev
->
devfn
,
PCI_COMMAND
,
&
status
);
}
if
(
!
(
status
&
PCI_COMMAND_MASTER
))
continue
;
/* Check the latency timer for values >= 0x60 */
pcibios_read_config_byte
(
pb
,
PCI_DEVICE
,
PCI_LATENCY_TIMER
,
&
timer
);
if
(
timer
<
0x60
)
{
pcibios_write_config_byte
(
pb
,
PCI_DEVICE
,
PCI_LATENCY_TIMER
,
0x60
);
}
/* Check the latency timer for values >= 0x60 */
pcibios_read_config_byte
(
pb
,
pdev
->
devfn
,
PCI_LATENCY_TIMER
,
&
timer
);
if
(
timer
<
0x60
)
{
pcibios_write_config_byte
(
pb
,
pdev
->
devfn
,
PCI_LATENCY_TIMER
,
0x60
);
}
DevicePresent
(
DE4X5_APROM
);
if
(
check_region
(
iobase
,
DE4X5_PCI_TOTAL_SIZE
)
==
0
)
{
dev
->
irq
=
irq
;
if
((
status
=
de4x5_hw_init
(
dev
,
iobase
))
==
0
)
{
num_de4x5s
++
;
if
(
loading_module
)
{
link_modules
(
lastModule
,
dev
);
lastPCI
=
index
;
}
return
;
DevicePresent
(
DE4X5_APROM
);
if
(
check_region
(
iobase
,
DE4X5_PCI_TOTAL_SIZE
)
==
0
)
{
dev
->
irq
=
irq
;
if
((
status
=
de4x5_hw_init
(
dev
,
iobase
))
==
0
)
{
num_de4x5s
++
;
if
(
loading_module
)
{
link_modules
(
lastModule
,
dev
);
lastPCI
=
index
;
}
}
else
if
(
ioaddr
!=
0
)
{
printk
(
"%s: region already allocated at 0x%04lx.
\n
"
,
dev
->
name
,
iobase
);
return
;
}
}
else
if
(
ioaddr
!=
0
)
{
printk
(
"%s: region already allocated at 0x%04lx.
\n
"
,
dev
->
name
,
iobase
);
}
}
...
...
@@ -2193,44 +2209,27 @@ pci_probe(struct device *dev, u_long ioaddr))
** For single port cards this is a time waster...
*/
__initfunc
(
static
void
srom_search
(
int
index
))
srom_search
(
struct
pci_dev
*
pdev
))
{
u_char
pb
,
dev_fn
;
u_short
dev_id
,
dev_num
,
vendor
,
status
;
u_char
pb
;
u_short
vendor
,
status
;
u_int
irq
=
0
,
device
,
class
=
DE4X5_CLASS_CODE
;
u_long
iobase
=
0
;
/* Clear upper 32 bits in Alphas */
int
i
,
j
;
struct
bus_type
*
lp
=
&
bus
;
#ifndef __sparc_v9__
u_char
tirq
;
u_int
tmp
;
#endif
for
(;
(
pcibios_find_class
(
class
,
index
,
&
pb
,
&
dev_fn
)
!=
PCIBIOS_DEVICE_NOT_FOUND
);
index
++
)
{
#ifdef __sparc_v9__
struct
pci_dev
*
pdev
;
for
(
pdev
=
pci_devices
;
pdev
;
pdev
=
pdev
->
next
)
{
if
((
pdev
->
bus
->
number
==
pb
)
&&
(
pdev
->
devfn
==
dev_fn
))
break
;
}
#endif
if
(
lp
->
bus_num
!=
pb
)
return
;
dev_num
=
PCI_SLOT
(
dev_fn
);
device
=
0
;
pcibios_read_config_word
(
pb
,
PCI_DEVICE
,
PCI_VENDOR_ID
,
&
vendor
);
pcibios_read_config_word
(
pb
,
PCI_DEVICE
,
PCI_DEVICE_ID
,
&
dev_id
);
device
=
dev_id
;
device
<<=
8
;
if
(
!
(
is_DC21040
||
is_DC21041
||
is_DC21140
||
is_DC2114x
))
{
continue
;
}
while
((
pdev
=
pci_find_class
(
class
,
pdev
))
!=
NULL
)
{
if
(
lp
->
bus_num
!=
pdev
->
bus
->
number
)
return
;
pb
=
pdev
->
bus
->
number
;
vendor
=
pdev
->
vendor
;
device
=
pdev
->
device
<<
8
;
if
(
!
(
is_DC21040
||
is_DC21041
||
is_DC21140
||
is_DC2114x
))
continue
;
/* Get the chip configuration revision register */
pcibios_read_config_dword
(
pb
,
PCI_DEVICE
,
PCI_REVISION_ID
,
&
cfrv
);
pcibios_read_config_dword
(
pb
,
pdev
->
devfn
,
PCI_REVISION_ID
,
&
cfrv
);
/* Set the device number information */
lp
->
device
=
dev_num
;
lp
->
device
=
PCI_SLOT
(
pdev
->
devfn
)
;
lp
->
bus_num
=
pb
;
/* Set the chipset information */
...
...
@@ -2238,25 +2237,14 @@ srom_search(int index))
lp
->
chipset
=
device
;
/* Get the board I/O address (64 bits on sparc64) */
#ifndef __sparc_v9__
pcibios_read_config_dword
(
pb
,
PCI_DEVICE
,
PCI_BASE_ADDRESS_0
,
&
tmp
);
iobase
=
tmp
;
#else
iobase
=
pdev
->
base_address
[
0
];
#endif
iobase
&=
CBIO_MASK
;
iobase
=
pdev
->
base_address
[
0
]
&
CBIO_MASK
;
/* Fetch the IRQ to be used */
#ifndef __sparc_v9__
pcibios_read_config_byte
(
pb
,
PCI_DEVICE
,
PCI_INTERRUPT_LINE
,
&
tirq
);
irq
=
tirq
;
#else
irq
=
pdev
->
irq
;
#endif
if
((
irq
==
0
)
||
(
irq
==
0xff
)
||
((
int
)
irq
==
-
1
))
continue
;
/* Check if I/O accesses are enabled */
pcibios_read_config_word
(
pb
,
PCI_DEVICE
,
PCI_COMMAND
,
&
status
);
pcibios_read_config_word
(
pb
,
pdev
->
devfn
,
PCI_COMMAND
,
&
status
);
if
(
!
(
status
&
PCI_COMMAND_IO
))
continue
;
/* Search for a valid SROM attached to this DECchip */
...
...
@@ -2709,9 +2697,9 @@ dc21140m_autoconf(struct device *dev)
int
ana
,
anlpa
,
cap
,
cr
,
slnk
,
sr
;
int
next_tick
=
DE4X5_AUTOSENSE_MS
;
u_long
imr
,
omr
,
iobase
=
dev
->
base_addr
;
switch
(
lp
->
media
)
{
case
INIT
:
case
INIT
:
if
(
lp
->
timeout
<
0
)
{
DISABLE_IRQs
;
lp
->
tx_enable
=
FALSE
;
...
...
@@ -2757,9 +2745,9 @@ dc21140m_autoconf(struct device *dev)
}
break
;
case
ANS
:
case
ANS
:
switch
(
lp
->
local_state
)
{
case
0
:
case
0
:
if
(
lp
->
timeout
<
0
)
{
mii_wr
(
MII_CR_ASSE
|
MII_CR_RAN
,
MII_CR
,
lp
->
phy
[
lp
->
active
].
addr
,
DE4X5_MII
);
}
...
...
@@ -2777,7 +2765,7 @@ dc21140m_autoconf(struct device *dev)
}
break
;
case
1
:
case
1
:
if
((
sr
=
test_mii_reg
(
dev
,
MII_SR
,
MII_SR_ASSC
,
TRUE
,
2000
))
<
0
)
{
next_tick
=
sr
&
~
TIMER_CB
;
}
else
{
...
...
@@ -2805,7 +2793,7 @@ dc21140m_autoconf(struct device *dev)
}
break
;
case
SPD_DET
:
/* Choose 10Mb/s or 100Mb/s */
case
SPD_DET
:
/* Choose 10Mb/s or 100Mb/s */
if
(
lp
->
timeout
<
0
)
{
lp
->
tmp
=
(
lp
->
phy
[
lp
->
active
].
id
?
MII_SR_LKS
:
(
~
gep_rd
(
dev
)
&
GEP_LNP
));
...
...
@@ -2825,7 +2813,7 @@ dc21140m_autoconf(struct device *dev)
}
break
;
case
_100Mb
:
/* Set 100Mb/s */
case
_100Mb
:
/* Set 100Mb/s */
next_tick
=
3000
;
if
(
!
lp
->
tx_enable
)
{
SET_100Mb
;
...
...
@@ -2840,8 +2828,10 @@ dc21140m_autoconf(struct device *dev)
}
}
break
;
case
_10Mb
:
/* Set 10Mb/s */
case
BNC
:
case
AUI
:
case
_10Mb
:
/* Set 10Mb/s */
next_tick
=
3000
;
if
(
!
lp
->
tx_enable
)
{
SET_10Mb
;
...
...
@@ -2857,7 +2847,7 @@ dc21140m_autoconf(struct device *dev)
}
break
;
case
NC
:
case
NC
:
if
(
lp
->
media
!=
lp
->
c_media
)
{
de4x5_dbg_media
(
dev
);
lp
->
c_media
=
lp
->
media
;
...
...
@@ -2893,33 +2883,54 @@ dc2114x_autoconf(struct device *dev)
int
next_tick
=
DE4X5_AUTOSENSE_MS
;
switch
(
lp
->
media
)
{
case
INIT
:
case
INIT
:
if
(
lp
->
timeout
<
0
)
{
DISABLE_IRQs
;
lp
->
tx_enable
=
FALSE
;
lp
->
linkOK
=
0
;
lp
->
timeout
=
-
1
;
de4x5_save_skbs
(
dev
);
/* Save non transmitted skb's */
de4x5_save_skbs
(
dev
);
/* Save non transmitted skb's */
if
(
lp
->
params
.
autosense
&
~
AUTO
)
{
srom_map_media
(
dev
);
/* Fixed media requested */
if
(
lp
->
media
!=
lp
->
params
.
autosense
)
{
lp
->
tcount
++
;
lp
->
media
=
INIT
;
return
next_tick
;
}
lp
->
media
=
INIT
;
}
}
if
((
next_tick
=
de4x5_reset_phy
(
dev
))
<
0
)
{
next_tick
&=
~
TIMER_CB
;
}
else
{
lp
->
media
=
SPD_DET
;
if
((
lp
->
infoblock_media
==
ANS
)
&&
if
(
lp
->
autosense
==
_100Mb
)
{
lp
->
media
=
_100Mb
;
}
else
if
(
lp
->
autosense
==
_10Mb
)
{
lp
->
media
=
_10Mb
;
}
else
if
(
lp
->
autosense
==
TP
)
{
lp
->
media
=
TP
;
}
else
if
(
lp
->
autosense
==
BNC
)
{
lp
->
media
=
BNC
;
}
else
if
(
lp
->
autosense
==
AUI
)
{
lp
->
media
=
AUI
;
}
else
{
lp
->
media
=
SPD_DET
;
if
((
lp
->
infoblock_media
==
ANS
)
&&
((
sr
=
is_anc_capable
(
dev
))
&
MII_SR_ANC
))
{
ana
=
(((
sr
>>
6
)
&
MII_ANA_TAF
)
|
MII_ANA_CSMA
);
ana
&=
(
lp
->
fdx
?
~
0
:
~
MII_ANA_FDAM
);
mii_wr
(
ana
,
MII_ANA
,
lp
->
phy
[
lp
->
active
].
addr
,
DE4X5_MII
);
lp
->
media
=
ANS
;
}
}
lp
->
local_state
=
0
;
next_tick
=
dc2114x_autoconf
(
dev
);
}
break
;
case
ANS
:
case
ANS
:
switch
(
lp
->
local_state
)
{
case
0
:
case
0
:
if
(
lp
->
timeout
<
0
)
{
mii_wr
(
MII_CR_ASSE
|
MII_CR_RAN
,
MII_CR
,
lp
->
phy
[
lp
->
active
].
addr
,
DE4X5_MII
);
}
...
...
@@ -2937,7 +2948,7 @@ dc2114x_autoconf(struct device *dev)
}
break
;
case
1
:
case
1
:
if
((
sr
=
test_mii_reg
(
dev
,
MII_SR
,
MII_SR_ASSC
,
TRUE
,
2000
))
<
0
)
{
next_tick
=
sr
&
~
TIMER_CB
;
}
else
{
...
...
@@ -2959,15 +2970,15 @@ dc2114x_autoconf(struct device *dev)
}
}
/* Auto Negotiation failed to finish */
next_tick
=
dc2114x_autoconf
(
dev
);
}
/* Auto Negotiation failed to start */
}
/* Auto Negotiation failed to start
*/
break
;
}
break
;
case
AUI
:
case
AUI
:
if
(
!
lp
->
tx_enable
)
{
if
(
lp
->
timeout
<
0
)
{
omr
=
inl
(
DE4X5_OMR
);
/* Set up half duplex for AUI
*/
omr
=
inl
(
DE4X5_OMR
);
/* Set up half duplex for AUI
*/
outl
(
omr
&
~
OMR_FDX
,
DE4X5_OMR
);
}
irqs
=
0
;
...
...
@@ -2990,13 +3001,13 @@ dc2114x_autoconf(struct device *dev)
}
break
;
case
AUI_SUSPECT
:
case
AUI_SUSPECT
:
next_tick
=
de4x5_suspect_state
(
dev
,
1000
,
AUI
,
ping_media
,
dc2114x_autoconf
);
break
;
case
BNC
:
case
BNC
:
switch
(
lp
->
local_state
)
{
case
0
:
case
0
:
if
(
lp
->
timeout
<
0
)
{
omr
=
inl
(
DE4X5_OMR
);
/* Set up half duplex for BNC */
outl
(
omr
&
~
OMR_FDX
,
DE4X5_OMR
);
...
...
@@ -3012,7 +3023,7 @@ dc2114x_autoconf(struct device *dev)
}
break
;
case
1
:
case
1
:
if
(
!
lp
->
tx_enable
)
{
if
((
sts
=
ping_media
(
dev
,
3000
))
<
0
)
{
next_tick
=
sts
&
~
TIMER_CB
;
...
...
@@ -3033,11 +3044,11 @@ dc2114x_autoconf(struct device *dev)
}
break
;
case
BNC_SUSPECT
:
case
BNC_SUSPECT
:
next_tick
=
de4x5_suspect_state
(
dev
,
1000
,
BNC
,
ping_media
,
dc2114x_autoconf
);
break
;
case
SPD_DET
:
/* Choose 10Mb/s or 100Mb/s */
case
SPD_DET
:
/* Choose 10Mb/s or 100Mb/s */
if
(
srom_map_media
(
dev
)
<
0
)
{
lp
->
tcount
++
;
lp
->
media
=
INIT
;
...
...
@@ -3053,9 +3064,17 @@ dc2114x_autoconf(struct device *dev)
lp
->
media
=
SPD_DET
;
return
PDET_LINK_WAIT
;
}
}
if
(((
lp
->
media
==
_100Mb
)
&&
is_100_up
(
dev
))
||
}
if
(
lp
->
media
==
ANS
)
{
/* Do MII parallel detection */
if
(
is_spd_100
(
dev
))
{
lp
->
media
=
_100Mb
;
}
else
{
lp
->
media
=
_10Mb
;
}
next_tick
=
dc2114x_autoconf
(
dev
);
}
else
if
(((
lp
->
media
==
_100Mb
)
&&
is_100_up
(
dev
))
||
((
lp
->
media
==
_10Mb
)
&&
is_10_up
(
dev
))
||
(
lp
->
media
==
TP
)
||
(
lp
->
media
==
BNC
)
||
(
lp
->
media
==
AUI
))
{
next_tick
=
dc2114x_autoconf
(
dev
);
}
else
{
...
...
@@ -3064,7 +3083,7 @@ dc2114x_autoconf(struct device *dev)
}
break
;
case
_10Mb
:
case
_10Mb
:
next_tick
=
3000
;
if
(
!
lp
->
tx_enable
)
{
SET_10Mb
;
...
...
@@ -3080,7 +3099,7 @@ dc2114x_autoconf(struct device *dev)
}
break
;
case
_100Mb
:
case
_100Mb
:
next_tick
=
3000
;
if
(
!
lp
->
tx_enable
)
{
SET_100Mb
;
...
...
@@ -3096,7 +3115,7 @@ dc2114x_autoconf(struct device *dev)
}
break
;
default:
default:
lp
->
tcount
++
;
printk
(
"Huh?: media:%02x
\n
"
,
lp
->
media
);
lp
->
media
=
INIT
;
...
...
@@ -3466,7 +3485,7 @@ is_anc_capable(struct device *dev)
if
(
lp
->
phy
[
lp
->
active
].
id
&&
(
!
lp
->
useSROM
||
lp
->
useMII
))
{
return
(
mii_rd
(
MII_SR
,
lp
->
phy
[
lp
->
active
].
addr
,
DE4X5_MII
));
}
else
if
((
lp
->
chipset
&
~
0x00ff
)
==
DC2114x
)
{
return
(
inl
(
DE4X5_SISR
)
&
SISR_LPN
)
>>
1
1
;
return
(
inl
(
DE4X5_SISR
)
&
SISR_LPN
)
>>
1
2
;
}
else
{
return
0
;
}
...
...
@@ -4415,7 +4434,7 @@ srom_exec(struct device *dev, u_char *p)
while
(
count
--
)
{
gep_wr
(((
lp
->
chipset
==
DC21140
)
&&
(
lp
->
ibn
!=
5
)
?
*
p
++
:
TWIDDLE
(
w
++
)),
dev
);
mdelay
(
2
);
/* 2ms per action */
mdelay
(
2
);
/* 2ms per action */
}
if
(
lp
->
chipset
!=
DC21140
)
{
...
...
@@ -4645,6 +4664,7 @@ type1_infoblock(struct device *dev, u_char count, u_char *p)
p
+=
2
;
if
(
lp
->
state
==
INITIALISED
)
{
lp
->
ibn
=
1
;
lp
->
active
=
*
p
++
;
lp
->
phy
[
lp
->
active
].
gep
=
(
*
p
?
p
:
0
);
p
+=
(
*
p
+
1
);
lp
->
phy
[
lp
->
active
].
rst
=
(
*
p
?
p
:
0
);
p
+=
(
*
p
+
1
);
...
...
@@ -4724,6 +4744,7 @@ type3_infoblock(struct device *dev, u_char count, u_char *p)
p
+=
2
;
if
(
lp
->
state
==
INITIALISED
)
{
lp
->
ibn
=
3
;
lp
->
active
=
*
p
++
;
lp
->
phy
[
lp
->
active
].
gep
=
(
*
p
?
p
:
0
);
p
+=
(
2
*
(
*
p
)
+
1
);
lp
->
phy
[
lp
->
active
].
rst
=
(
*
p
?
p
:
0
);
p
+=
(
2
*
(
*
p
)
+
1
);
...
...
@@ -5471,24 +5492,24 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
}
tmp
;
switch
(
ioc
->
cmd
)
{
case
DE4X5_GET_HWADDR
:
/* Get the hardware address */
case
DE4X5_GET_HWADDR
:
/* Get the hardware address */
ioc
->
len
=
ETH_ALEN
;
status
=
verify_area
(
VERIFY_WRITE
,
(
void
*
)
ioc
->
data
,
ioc
->
len
);
if
(
status
)
break
;
break
;
for
(
i
=
0
;
i
<
ETH_ALEN
;
i
++
)
{
tmp
.
addr
[
i
]
=
dev
->
dev_addr
[
i
];
}
copy_to_user
(
ioc
->
data
,
tmp
.
addr
,
ioc
->
len
);
break
;
case
DE4X5_SET_HWADDR
:
/* Set the hardware address */
case
DE4X5_SET_HWADDR
:
/* Set the hardware address */
status
=
verify_area
(
VERIFY_READ
,
(
void
*
)
ioc
->
data
,
ETH_ALEN
);
if
(
status
)
break
;
break
;
status
=
-
EPERM
;
if
(
!
capable
(
CAP_NET_ADMIN
))
break
;
break
;
status
=
0
;
copy_from_user
(
tmp
.
addr
,
ioc
->
data
,
ETH_ALEN
);
for
(
i
=
0
;
i
<
ETH_ALEN
;
i
++
)
{
...
...
@@ -5498,13 +5519,13 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
/* Set up the descriptor and give ownership to the card */
while
(
test_and_set_bit
(
0
,
(
void
*
)
&
dev
->
tbusy
)
!=
0
);
load_packet
(
dev
,
lp
->
setup_frame
,
TD_IC
|
PERFECT_F
|
TD_SET
|
SETUP_FRAME_LEN
,
NULL
);
SETUP_FRAME_LEN
,
NULL
);
lp
->
tx_new
=
(
++
lp
->
tx_new
)
%
lp
->
txRingSize
;
outl
(
POLL_DEMAND
,
DE4X5_TPD
);
/* Start the TX */
dev
->
tbusy
=
0
;
/* Unlock the TX ring */
break
;
case
DE4X5_SET_PROM
:
/* Set Promiscuous Mode */
case
DE4X5_SET_PROM
:
/* Set Promiscuous Mode */
if
(
capable
(
CAP_NET_ADMIN
))
{
omr
=
inl
(
DE4X5_OMR
);
omr
|=
OMR_PR
;
...
...
@@ -5515,7 +5536,7 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
}
break
;
case
DE4X5_CLR_PROM
:
/* Clear Promiscuous Mode */
case
DE4X5_CLR_PROM
:
/* Clear Promiscuous Mode */
if
(
capable
(
CAP_NET_ADMIN
))
{
omr
=
inl
(
DE4X5_OMR
);
omr
&=
~
OMR_PR
;
...
...
@@ -5526,11 +5547,11 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
}
break
;
case
DE4X5_SAY_BOO
:
/* Say "Boo!" to the kernel log file */
case
DE4X5_SAY_BOO
:
/* Say "Boo!" to the kernel log file */
printk
(
"%s: Boo!
\n
"
,
dev
->
name
);
break
;
case
DE4X5_MCA_EN
:
/* Enable pass all multicast addressing */
case
DE4X5_MCA_EN
:
/* Enable pass all multicast addressing */
if
(
capable
(
CAP_NET_ADMIN
))
{
omr
=
inl
(
DE4X5_OMR
);
omr
|=
OMR_PM
;
...
...
@@ -5540,18 +5561,18 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
}
break
;
case
DE4X5_GET_STATS
:
/* Get the driver statistics */
case
DE4X5_GET_STATS
:
/* Get the driver statistics */
ioc
->
len
=
sizeof
(
lp
->
pktStats
);
status
=
verify_area
(
VERIFY_WRITE
,
(
void
*
)
ioc
->
data
,
ioc
->
len
);
if
(
status
)
break
;
break
;
cli
();
copy_to_user
(
ioc
->
data
,
&
lp
->
pktStats
,
ioc
->
len
);
sti
();
break
;
case
DE4X5_CLR_STATS
:
/* Zero out the driver statistics */
case
DE4X5_CLR_STATS
:
/* Zero out the driver statistics */
if
(
capable
(
CAP_NET_ADMIN
))
{
cli
();
memset
(
&
lp
->
pktStats
,
0
,
sizeof
(
lp
->
pktStats
));
...
...
@@ -5561,14 +5582,14 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
}
break
;
case
DE4X5_GET_OMR
:
/* Get the OMR Register contents */
case
DE4X5_GET_OMR
:
/* Get the OMR Register contents */
tmp
.
addr
[
0
]
=
inl
(
DE4X5_OMR
);
if
(
!
(
status
=
verify_area
(
VERIFY_WRITE
,
(
void
*
)
ioc
->
data
,
1
)))
{
copy_to_user
(
ioc
->
data
,
tmp
.
addr
,
1
);
}
break
;
case
DE4X5_SET_OMR
:
/* Set the OMR Register contents */
case
DE4X5_SET_OMR
:
/* Set the OMR Register contents */
if
(
capable
(
CAP_NET_ADMIN
))
{
if
(
!
(
status
=
verify_area
(
VERIFY_READ
,
(
void
*
)
ioc
->
data
,
1
)))
{
copy_from_user
(
tmp
.
addr
,
ioc
->
data
,
1
);
...
...
@@ -5579,7 +5600,7 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
}
break
;
case
DE4X5_GET_REG
:
/* Get the DE4X5 Registers */
case
DE4X5_GET_REG
:
/* Get the DE4X5 Registers */
j
=
0
;
tmp
.
lval
[
0
]
=
inl
(
DE4X5_STS
);
j
+=
4
;
tmp
.
lval
[
1
]
=
inl
(
DE4X5_BMR
);
j
+=
4
;
...
...
@@ -5687,7 +5708,7 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
break;
*/
default:
default:
status
=
-
EOPNOTSUPP
;
}
...
...
@@ -5766,30 +5787,32 @@ unlink_modules(struct device *p)
static
int
count_adapters
(
void
)
{
int
i
,
j
;
int
i
,
j
=
0
;
char
name
[
DE4X5_STRLEN
];
u_char
pb
,
dev_fn
,
dev_num
;
u_short
dev_id
,
vendor
;
u_char
pb
,
dev_fn
;
u_short
vendor
;
u_int
class
=
DE4X5_CLASS_CODE
;
u_int
device
;
struct
pci_dev
*
pdev
;
#if !defined(__sparc_v9__) && !defined(__powerpc__)
u_long
iobase
=
0x1000
;
for
(
j
=
0
,
i
=
1
;
i
<
MAX_EISA_SLOTS
;
i
++
,
iobase
+=
EISA_SLOT_INC
)
{
for
(
i
=
1
;
i
<
MAX_EISA_SLOTS
;
i
++
,
iobase
+=
EISA_SLOT_INC
)
{
if
(
EISA_signature
(
name
,
EISA_ID
))
j
++
;
}
#endif
if
(
!
pci_present
())
return
j
;
if
(
!
pci
bios
_present
())
return
j
;
for
(
i
=
0
;
(
pcibios_find_class
(
class
,
i
,
&
pb
,
&
dev_fn
)
!=
PCIBIOS_DEVICE_NOT_FOUND
);
i
++
)
{
dev_num
=
PCI_SLOT
(
dev_fn
);
device
=
0
;
pcibios_read_config_word
(
pb
,
PCI_DEVICE
,
PCI_VENDOR_ID
,
&
vendor
);
pcibios_read_config_word
(
pb
,
PCI_DEVICE
,
PCI_DEVICE_ID
,
&
dev_id
);
device
=
dev_id
;
device
<<=
8
;
for
(
pdev
=
pci_devices
;
pdev
;
pdev
=
pdev
->
next
)
{
if
((
pdev
->
bus
->
number
==
pb
)
&&
(
pdev
->
devfn
==
dev_fn
))
break
;
}
vendor
=
pdev
->
vendor
;
device
=
pdev
->
device
<<
8
;
if
(
is_DC21040
||
is_DC21041
||
is_DC21140
||
is_DC2114x
)
j
++
;
}
...
...
drivers/net/de4x5.h
View file @
ab92dab4
...
...
@@ -811,7 +811,7 @@
** Media / mode state machine definitions
** User selectable:
*/
#define TP 0x00
01
/* 10Base-T
*/
#define TP 0x00
40
/* 10Base-T (now equiv to _10Mb)
*/
#define TP_NW 0x0002
/* 10Base-T with Nway */
#define BNC 0x0004
/* Thinwire */
#define AUI 0x0008
/* Thickwire */
...
...
fs/ncpfs/Makefile
View file @
ab92dab4
#
# Makefile for the linux ncp
-
filesystem routines.
# Makefile for the linux ncp
filesystem routines.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (
ie
not a .c file).
# unless it's something special (not a .c file).
#
# Note 2! The CFLAGS definitions are now in the main makefile.
..
# Note 2! The CFLAGS definitions are now in the main makefile.
O_TARGET
:=
ncpfs.o
O_OBJS
:=
dir.o file.o inode.o ioctl.o mmap.o ncplib_kernel.o sock.o
\
...
...
include/asm-i386/bugs.h
View file @
ab92dab4
...
...
@@ -41,7 +41,7 @@ __initfunc(static void copro_timeout(void))
timer_table
[
COPRO_TIMER
].
expires
=
jiffies
+
100
;
timer_active
|=
1
<<
COPRO_TIMER
;
printk
(
KERN_ERR
"387 failed: trying to reset
\n
"
);
send_sig
(
SIGFPE
,
last_task_used_math
,
1
);
send_sig
(
SIGFPE
,
current
,
1
);
outb_p
(
0
,
0xf1
);
outb_p
(
0
,
0xf0
);
}
...
...
@@ -156,7 +156,7 @@ __initfunc(static void check_popad(void))
* misexecution of code under Linux. Owners of such processors should
* contact AMD for precise details and a CPU swap.
*
* See http://www.
chorus
.com/~poulot/k6bug.html
* See http://www.
mygale
.com/~poulot/k6bug.html
* http://www.amd.com/K6/k6docs/revgd.html
*
* The following test is erm.. interesting. AMD neglected to up
...
...
@@ -202,7 +202,7 @@ __initfunc(static void check_amd_k6(void))
printk
(
"system stability may be impaired when more than 32 MB are used.
\n
"
);
else
printk
(
"probably OK (after B9730xxxx).
\n
"
);
printk
(
KERN_INFO
"Please see http://www.
chorus.com/
poulot/k6bug.html
\n
"
);
printk
(
KERN_INFO
"Please see http://www.
mygale.com/~
poulot/k6bug.html
\n
"
);
}
}
...
...
include/asm-i386/processor.h
View file @
ab92dab4
...
...
@@ -74,9 +74,6 @@ extern unsigned int machine_id;
extern
unsigned
int
machine_submodel_id
;
extern
unsigned
int
BIOS_revision
;
/* Lazy FPU handling on uni-processor */
extern
struct
task_struct
*
last_task_used_math
;
/*
* User space process size: 3GB (default).
*/
...
...
@@ -166,33 +163,34 @@ struct thread_struct {
#define INIT_MMAP \
{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
#define INIT_TSS { \
0,0, \
sizeof(init_stack) + (long) &init_stack, \
__KERNEL_DS, 0, \
0,0,0,0,0,0, \
(long) &swapper_pg_dir - PAGE_OFFSET, \
0,0,0,0,0,0,0,0,0,0, \
__USER_DS,0,__USER_DS,0,__USER_DS,0, \
__USER_DS,0,__USER_DS,0,__USER_DS,0, \
_LDT(0),0, \
0, 0x8000, \
{~0, },
/* ioperm */
\
_TSS(0), 0, 0, 0, (mm_segment_t) { 0 }
/* obsolete */
, \
{ { 0, }, },
/* 387 state */
\
NULL, 0, 0, 0, 0, 0
/* vm86_info */
, \
#define INIT_TSS { \
0,0,
/* back_link, __blh */
\
sizeof(init_stack) + (long) &init_stack,
/* esp0 */
\
__KERNEL_DS, 0,
/* ss0 */
\
0,0,0,0,0,0,
/* stack1, stack2 */
\
(long) &swapper_pg_dir - PAGE_OFFSET,
/* cr3 */
\
0,0,
/* eip,eflags */
\
0,0,0,0,
/* eax,ecx,edx,ebx */
\
0,0,0,0,
/* esp,ebp,esi,edi */
\
0,0,0,0,0,0,
/* es,cs,ss */
\
0,0,0,0,0,0,
/* ds,fs,gs */
\
_LDT(0),0,
/* ldt */
\
0, 0x8000,
/* tace, bitmap */
\
{~0, },
/* ioperm */
\
_TSS(0), 0, 0, 0, (mm_segment_t) { 0 },
/* obsolete */
\
{ { 0, }, },
/* 387 state */
\
NULL, 0, 0, 0, 0, 0,
/* vm86_info */
\
}
#define start_thread(regs, new_eip, new_esp) do {\
unsigned long seg = __USER_DS; \
__asm__("movl %w0,%%fs ; movl %w0,%%gs":"=r" (seg) :"0" (seg)); \
set_fs(USER_DS); \
regs->xds = seg; \
regs->xes = seg; \
regs->xss = seg; \
regs->xcs = __USER_CS; \
regs->eip = new_eip; \
regs->esp = new_esp; \
#define start_thread(regs, new_eip, new_esp) do { \
__asm__("movl %w0,%%fs ; movl %w0,%%gs": :"r" (0)); \
set_fs(USER_DS); \
regs->xds = __USER_DS; \
regs->xes = __USER_DS; \
regs->xss = __USER_DS; \
regs->xcs = __USER_CS; \
regs->eip = new_eip; \
regs->esp = new_esp; \
} while (0)
/* Forward declaration, a strange C thing */
...
...
include/asm-i386/system.h
View file @
ab92dab4
#ifndef __ASM_SYSTEM_H
#define __ASM_SYSTEM_H
#include <linux/kernel.h>
#include <asm/segment.h>
/*
...
...
@@ -35,84 +36,35 @@ __asm__("str %%ax\n\t" \
:"=a" (n) \
:"0" (0),"i" (FIRST_TSS_ENTRY<<3))
/* This special macro can be used to load a debugging register */
#define loaddebug(tsk,register) \
__asm__("movl %0,%%db" #register \
:
/* no output */
\
:"r" (tsk->debugreg[register]))
struct
task_struct
;
/* one of the stranger aspects of C forward declarations.. */
extern
void
FASTCALL
(
__switch_to
(
struct
task_struct
*
prev
,
struct
task_struct
*
next
));
/*
* switch_to(n) should switch tasks to task nr n, first
* checking that n isn't the current task, in which case it does nothing.
* This also clears the TS-flag if the task we switched to has used
* the math co-processor latest.
*
* It also reloads the debug regs if necessary..
* We do most of the task switching in C, but we need
* to do the EIP/ESP switch in assembly..
*/
#ifdef __SMP__
/*
* Keep the lock depth straight. If we switch on an interrupt from
* kernel->user task we need to lose a depth, and if we switch the
* other way we need to gain a depth. Same layer switches come out
* the same.
*
* We spot a switch in user mode because the kernel counter is the
* same as the interrupt counter depth. (We never switch during the
* message/invalidate IPI).
*
* We fsave/fwait so that an exception goes off at the right time
* (as a call from the fsave or fwait in effect) rather than to
* the wrong process.
*/
#define switch_to(prev,next) do { \
if(prev->flags&PF_USEDFPU) \
{ \
__asm__ __volatile__("fnsave %0":"=m" (prev->tss.i387.hard)); \
__asm__ __volatile__("fwait"); \
prev->flags&=~PF_USEDFPU; \
} \
__asm__("ljmp %0\n\t" \
:
/* no output */
\
:"m" (*(((char *)&next->tss.tr)-4)), \
"c" (next)); \
/* Now maybe reload the debug registers */
\
if(prev->debugreg[7]){ \
loaddebug(prev,0); \
loaddebug(prev,1); \
loaddebug(prev,2); \
loaddebug(prev,3); \
loaddebug(prev,6); \
loaddebug(prev,7); \
} \
#define switch_to(prev,next) do { \
unsigned long eax, edx, ecx; \
asm volatile("pushl %%edi\n\t" \
"pushl %%esi\n\t" \
"pushl %%ebp\n\t" \
"pushl %%ebx\n\t" \
"movl %%esp,%0\n\t"
/* save ESP */
\
"movl %5,%%esp\n\t"
/* restore ESP */
\
"movl $1f,%1\n\t"
/* save EIP */
\
"pushl %6\n\t"
/* restore EIP */
\
"jmp __switch_to\n" \
"1:\t" \
"popl %%ebx\n\t" \
"popl %%ebp\n\t" \
"popl %%esi\n\t" \
"popl %%edi" \
:"=m" (prev->tss.esp),"=m" (prev->tss.eip), \
"=a" (eax), "=d" (edx), "=c" (ecx) \
:"m" (next->tss.esp),"m" (next->tss.eip), \
"a" (prev), "d" (next)); \
} while (0)
#else
#define switch_to(prev,next) do { \
__asm__("ljmp %0\n\t" \
"cmpl %1,"SYMBOL_NAME_STR(last_task_used_math)"\n\t" \
"jne 1f\n\t" \
"clts\n" \
"1:" \
:
/* no outputs */
\
:"m" (*(((char *)&next->tss.tr)-4)), \
"r" (prev), "r" (next)); \
/* Now maybe reload the debug registers */
\
if(prev->debugreg[7]){ \
loaddebug(prev,0); \
loaddebug(prev,1); \
loaddebug(prev,2); \
loaddebug(prev,3); \
loaddebug(prev,6); \
loaddebug(prev,7); \
} \
} while (0)
#endif
#define _set_base(addr,base) \
__asm__("movw %%dx,%0\n\t" \
"rorl $16,%%edx\n\t" \
...
...
kernel/fork.c
View file @
ab92dab4
...
...
@@ -308,6 +308,10 @@ static inline int copy_mm(int nr, unsigned long clone_flags, struct task_struct
if
(
clone_flags
&
CLONE_VM
)
{
mmget
(
current
->
mm
);
/*
* Set up the LDT descriptor for the clone task.
*/
copy_segments
(
nr
,
tsk
,
NULL
);
SET_PAGE_DIR
(
tsk
,
current
->
mm
->
pgd
);
return
0
;
}
...
...
kernel/printk.c
View file @
ab92dab4
...
...
@@ -14,8 +14,6 @@
#include <stdarg.h>
#include <asm/system.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
...
...
@@ -27,6 +25,7 @@
#include <linux/console.h>
#include <linux/init.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#define LOG_BUF_LEN 8192
...
...
mm/filemap.c
View file @
ab92dab4
...
...
@@ -851,7 +851,7 @@ static int file_send_actor(read_descriptor_t * desc, const char *area, unsigned
return
written
;
}
asmlinkage
ssize_t
sys_sendfile
(
int
out_fd
,
int
in_fd
,
size_t
count
)
asmlinkage
ssize_t
sys_sendfile
(
int
out_fd
,
int
in_fd
,
off_t
*
offset
,
size_t
count
)
{
ssize_t
retval
;
struct
file
*
in_file
,
*
out_file
;
...
...
@@ -900,16 +900,27 @@ asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, size_t count)
retval
=
0
;
if
(
count
)
{
read_descriptor_t
desc
;
loff_t
pos
=
0
,
*
ppos
;
retval
=
-
EFAULT
;
ppos
=
&
in_file
->
f_pos
;
if
(
offset
)
{
if
(
get_user
(
pos
,
offset
))
goto
fput_out
;
ppos
=
&
pos
;
}
desc
.
written
=
0
;
desc
.
count
=
count
;
desc
.
buf
=
(
char
*
)
out_file
;
desc
.
error
=
0
;
do_generic_file_read
(
in_file
,
&
in_file
->
f_
pos
,
&
desc
,
file_send_actor
);
do_generic_file_read
(
in_file
,
p
pos
,
&
desc
,
file_send_actor
);
retval
=
desc
.
written
;
if
(
!
retval
)
retval
=
desc
.
error
;
if
(
offset
)
put_user
(
pos
,
offset
);
}
...
...
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