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
86ae3b2a
Commit
86ae3b2a
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 2.3.12pre9
parent
6ae9dd08
Changes
53
Hide whitespace changes
Inline
Side-by-side
Showing
53 changed files
with
1083 additions
and
1504 deletions
+1083
-1504
Documentation/Configure.help
Documentation/Configure.help
+9
-2
Documentation/proc_usb_info.txt
Documentation/proc_usb_info.txt
+221
-0
arch/alpha/kernel/entry.S
arch/alpha/kernel/entry.S
+0
-8
arch/arm/kernel/calls.S
arch/arm/kernel/calls.S
+1
-9
arch/i386/kernel/entry.S
arch/i386/kernel/entry.S
+1
-9
arch/i386/kernel/smp.c
arch/i386/kernel/smp.c
+39
-36
arch/i386/mm/fault.c
arch/i386/mm/fault.c
+0
-3
arch/m68k/kernel/entry.S
arch/m68k/kernel/entry.S
+0
-8
arch/mips/kernel/syscalls.h
arch/mips/kernel/syscalls.h
+0
-8
arch/ppc/kernel/misc.S
arch/ppc/kernel/misc.S
+1
-9
arch/sparc/kernel/systbls.S
arch/sparc/kernel/systbls.S
+1
-2
arch/sparc64/kernel/systbls.S
arch/sparc64/kernel/systbls.S
+2
-4
drivers/block/ll_rw_blk.c
drivers/block/ll_rw_blk.c
+1
-1
drivers/char/ppdev.c
drivers/char/ppdev.c
+38
-0
drivers/parport/parport_ax.c
drivers/parport/parport_ax.c
+0
-589
drivers/parport/parport_pc.c
drivers/parport/parport_pc.c
+2
-1
drivers/usb/Config.in
drivers/usb/Config.in
+3
-0
drivers/usb/Makefile
drivers/usb/Makefile
+8
-2
drivers/usb/ezusb.c
drivers/usb/ezusb.c
+0
-1
drivers/usb/inits.h
drivers/usb/inits.h
+2
-0
drivers/usb/proc_usb.c
drivers/usb/proc_usb.c
+487
-0
drivers/usb/procusb
drivers/usb/procusb
+41
-0
drivers/usb/usb-core.c
drivers/usb/usb-core.c
+7
-0
drivers/usb/usb.c
drivers/usb/usb.c
+13
-0
fs/proc/array.c
fs/proc/array.c
+103
-80
fs/proc/link.c
fs/proc/link.c
+42
-35
include/asm-alpha/siginfo.h
include/asm-alpha/siginfo.h
+0
-2
include/asm-alpha/unistd.h
include/asm-alpha/unistd.h
+0
-8
include/asm-arm/siginfo.h
include/asm-arm/siginfo.h
+0
-2
include/asm-arm/unistd.h
include/asm-arm/unistd.h
+0
-8
include/asm-i386/mmu_context.h
include/asm-i386/mmu_context.h
+12
-12
include/asm-i386/siginfo.h
include/asm-i386/siginfo.h
+1
-4
include/asm-i386/unistd.h
include/asm-i386/unistd.h
+0
-8
include/asm-m68k/siginfo.h
include/asm-m68k/siginfo.h
+0
-2
include/asm-m68k/unistd.h
include/asm-m68k/unistd.h
+0
-8
include/asm-mips/siginfo.h
include/asm-mips/siginfo.h
+0
-2
include/asm-mips/unistd.h
include/asm-mips/unistd.h
+0
-8
include/asm-ppc/siginfo.h
include/asm-ppc/siginfo.h
+1
-3
include/asm-ppc/unistd.h
include/asm-ppc/unistd.h
+0
-8
include/asm-sparc/siginfo.h
include/asm-sparc/siginfo.h
+1
-3
include/asm-sparc/unistd.h
include/asm-sparc/unistd.h
+0
-8
include/asm-sparc64/siginfo.h
include/asm-sparc64/siginfo.h
+1
-3
include/asm-sparc64/unistd.h
include/asm-sparc64/unistd.h
+0
-8
include/linux/limits.h
include/linux/limits.h
+0
-2
include/linux/sched.h
include/linux/sched.h
+1
-26
include/linux/time.h
include/linux/time.h
+3
-35
kernel/exit.c
kernel/exit.c
+0
-29
kernel/fork.c
kernel/fork.c
+0
-22
kernel/itimer.c
kernel/itimer.c
+3
-388
kernel/sched.c
kernel/sched.c
+1
-2
kernel/signal.c
kernel/signal.c
+36
-42
kernel/time.c
kernel/time.c
+0
-54
mm/memory.c
mm/memory.c
+1
-0
No files found.
Documentation/Configure.help
View file @
86ae3b2a
...
...
@@ -11921,7 +11921,7 @@ USB hub support
CONFIG_USB_HUB
To
expand
beyond
the
USB
ports
on
the
computer
,
a
device
called
a
hub
is
used
.
This
driver
supports
hubs
,
allowing
them
to
be
used
.
Say
'Y'
Say
'Y'
.
USB
mouse
support
CONFIG_USB_MOUSE
...
...
@@ -11931,7 +11931,7 @@ CONFIG_USB_MOUSE
USB
keyboard
support
CONFIG_USB_KBD
This
driver
allows
usb
keyboards
to
work
under
the
USB
stack
.
This
driver
allows
USB
keyboards
to
work
under
the
USB
stack
.
USB
audio
parsing
support
(
Preliminary
)
CONFIG_USB_AUDIO
...
...
@@ -11943,6 +11943,13 @@ CONFIG_USB_ACM
This
driver
allows
for
devices
which
support
the
Abstract
Control
Model
,
including
many
USB
-
based
modems
,
ISDN
adapters
,
and
network
adapters
.
USB
/
proc
filesystem
entry
support
(
Preliminary
)
CONFIG_USB_PROC
This
reports
USB
drivers
and
devices
in
the
/
proc
filesystem
.
Entries
are
located
in
/
proc
/
bus
/
usb
.
Note
that
you
must
enable
support
for
the
proc
filesystem
for
this
to
work
.
Support
for
user
-
space
parallel
port
device
drivers
CONFIG_PPDEV
Saying
Y
to
this
adds
support
for
/
dev
/
parport
device
nodes
.
This
...
...
Documentation/proc_usb_info.txt
0 → 100644
View file @
86ae3b2a
/proc/bus/usb filesystem output
===============================
(version 19990722)
The /proc filesystem for USB devices generates
/proc/bus/usb/drivers and /proc/bus/usb/devices.
/proc/bus/usb/drivers just lists the registered drivers,
one per line. Not very interesting or pretty.
In /proc/bus/usb/devices, each device's output has multiple
lines (except for a root hub) of ASCII output.
I made it ASCII instead of binary on purpose, so that someone
can obtain some useful data from it without the use of an
auxiliary program. However, with an auxiliary program, the numbers
in the first 4 columns of each "T:" line (topology info:
Lev, Prnt, Port, Cnt) can be used to build a USB topology diagram.
(I think. I haven't proved this, but I have tested it with 3
different topo/connections and it looked possible.)
Each line is tagged with a one-character ID for that line:
T = Topology (etc.)
D = Device descriptor info.
P = Product ID info. (from Device descriptor, but they won't fit
together on one line)
C = Configuration descriptor info. (* = active configuration)
I = Interface descriptor info.
E = Endpoint descriptor info.
=======================================================================
/proc/bus/usb/devices output format:
Legend:
d = decimal number (may have leading spaces or 0's)
x = hexadecimal number (may have leading spaces or 0's)
s = string
Topology info:
T: Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd If#=ddd MxCh=dd Driver=%s
| | | | | | | | | |__DriverName
| | | | | | | | |__MaxChildren
| | | | | | | |__Configured InterfaceNumber
| | | | | | |__Device Speed in Mbps
| | | | | |__DeviceNumber
| | | | |__Count of devices at this level
| | | |__Connector/Port on Parent for this device
| | |__Parent DeviceNumber
| |__Level in topology
|__Topology info tag
Device descriptor info & Product ID info:
D: Ver=x.xx Cls=xx(s) Sub=xx Prot=xx MxPS=dd #Cfgs=dd
P: Vendor=xxxx ProdID=xxxx Rev=xx.xx
where
D: Ver=x.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd
| | | | | | |__NumberConfigurations
| | | | | |__MaxPacketSize of Default Endpoint
| | | | |__DeviceProtocol
| | | |__DeviceSubClass
| | |__DeviceClass
| |__Device USB version
|__Device info tag #1
where
P: Vendor=xxxx ProdID=xxxx Rev=xx.xx
| | | |__Product revision number
| | |__Product ID code
| |__Vendor ID code
|__Device info tag #2
Configuration descriptor info:
C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA
| | | | |__MaxPower in mA
| | | |__Attributes
| | |__ConfiguratioNumber
| |__NumberOfInterfaces
|__Config info tag
Interface descriptor info (can be multiple per Config):
I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx
| | | | | | |__InterfaceProtocol
| | | | | |__InterfaceSubClass
| | | | |__InterfaceClass
| | | |__NumberOfEndpoints
| | |__AlternateSettingNumber
| |__InterfaceNumber
|__Interface info tag
Endpoint descriptor info (can be multiple per Interface):
E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddms
E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddms
| | | | |__Interval
| | | |__EndpointMaxPacketSize
| | |__Attributes(EndpointType)
| |__EndpointAddress(I=In,O=Out)
|__Endpoint info tag
=======================================================================
If a user or script is interested only in Topology info, for
example, use something like "grep ^T: /proc/bus/usb/devices"
for only the Topology lines. A command like
"grep -i ^[tdp]: /proc/bus/usb/devices" can be used to list
only the lines that begin with the characters in square brackets,
where the valid characters are TDPCIE. With a slightly more able
script, it can display any selected lines (for example, only T, D,
and P lines) and change their output format. (The "procusb"
Perl script is the beginning of this idea. It will list only
selected lines [selected from TDPCIE] or "All" lines from
/proc/bus/usb/devices.)
The Topology lines can be used to generate a graphic/pictorial
of the USB devices on a system's root hub. (See more below
on how to do this.)
The Configuration lines could be used to list maximum power
(in milliamps) that a system's USB devices are using.
For example, "grep ^C: /proc/bus/usb/devices".
Here's an example, from a system which has a UHCI root hub,
an external hub connected to the root hub, and a mouse and
a video camera connected to the external hub. [The video
camera is listed as (none) since it is not recognized by
any driver.]
T: Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= -1 Spd=12 If#= 0 MxCh= 2 Driver=(root hub)
T: Lev=01 Prnt=00 Port=00 Cnt=01 Dev#= 1 Spd=12 If#= 0 MxCh= 4 Driver=hub
D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0451 ProdID=1446 Rev= 1.00
C:* #If= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EP= 1 Cls=09(hub ) Sub=00 Prot=00
E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=255ms
T: Lev=02 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=1.5 If#= 0 MxCh= 0 Driver=mouse
D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0458 ProdID=0001 Rev= 0.00
C:* #If= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
I: If#= 0 Alt= 0 #EP= 1 Cls=03(HID ) Sub=01 Prot=02
E: Ad=81(I) Atr=03(Int.) MxPS= 3 Ivl= 10ms
T: Lev=02 Prnt=01 Port=02 Cnt=02 Dev#= 4 Spd=12 If#= 0 MxCh= 0 Driver=(none)
D: Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=04c8 ProdID=0720 Rev= 1.01
C:* #If= 1 Cfg#= 1 Atr=80 MxPwr=500mA
I: If#= 0 Alt= 0 #EP= 2 Cls=0a(unk. ) Sub=ff Prot=00
E: Ad=81(I) Atr=01(Isoc) MxPS= 1 Ivl= 1ms
E: Ad=82(I) Atr=01(Isoc) MxPS= 384 Ivl= 1ms
I: If#= 0 Alt= 1 #EP= 2 Cls=0a(unk. ) Sub=ff Prot=00
E: Ad=81(I) Atr=01(Isoc) MxPS= 1 Ivl= 1ms
E: Ad=82(I) Atr=01(Isoc) MxPS= 240 Ivl= 1ms
I: If#= 0 Alt= 2 #EP= 2 Cls=0a(unk. ) Sub=ff Prot=00
E: Ad=81(I) Atr=01(Isoc) MxPS= 1 Ivl= 1ms
E: Ad=82(I) Atr=01(Isoc) MxPS= 576 Ivl= 1ms
I: If#= 0 Alt= 3 #EP= 2 Cls=0a(unk. ) Sub=ff Prot=00
E: Ad=81(I) Atr=01(Isoc) MxPS= 1 Ivl= 1ms
E: Ad=82(I) Atr=01(Isoc) MxPS= 464 Ivl= 1ms
I: If#= 0 Alt= 4 #EP= 2 Cls=0a(unk. ) Sub=ff Prot=00
E: Ad=81(I) Atr=01(Isoc) MxPS= 1 Ivl= 1ms
E: Ad=82(I) Atr=01(Isoc) MxPS= 688 Ivl= 1ms
Selecting only the "T:" lines from this (for example, by using
"procusb t"), we have:
T: Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= -1 Spd=12 If#= 0 MxCh= 2 Driver=(root hub)
T: Lev=01 Prnt=00 Port=00 Cnt=01 Dev#= 1 Spd=12 If#= 0 MxCh= 4 Driver=hub
T: Lev=02 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=1.5 If#= 0 MxCh= 0 Driver=mouse
T: Lev=02 Prnt=01 Port=02 Cnt=02 Dev#= 4 Spd=12 If#= 0 MxCh= 0 Driver=(none)
Physically this looks like (or could be converted to):
+------------------+
| PC/root_hub (12)| Dev# = -1
+------------------+ (nn) is Mbps.
Level 0 | CN.0 | CN.1 | [CN = connector/port #]
+------------------+
/
/
+-----------------------+
Level 1 | Dev#1: 4-port hub (12)|
+-----------------------+
|CN.0 |CN.1 |CN.2 |CN.3 |
+-----------------------+
\ \____________________
\_____ \
\ \
+--------------------+ +--------------------+
Level 2 | Dev# 3: mouse (1.5)| | Dev# 4: (none) (12)|
+--------------------+ +--------------------+
Or, in a more tree-like structure (ports [Connectors] without
connections could be omitted):
PC: Dev# -1, root hub, 2 ports, 12 Mbps
|_ CN.0: Dev# 1, hub, 4 ports, 12 Mbps
|_ CN.0: Dev #3, mouse, 1.5 Mbps
|_ CN.1:
|_ CN.2: Dev #4, (none), 12 Mbps [or use "unknown" for (none)]
|_ CN.3:
|_ CN.1:
### END ###
arch/alpha/kernel/entry.S
View file @
86ae3b2a
...
...
@@ -1143,11 +1143,3 @@ sys_call_table:
.
quad
sys_capget
.
quad
sys_capset
.
quad
sys_sendfile
/*
370
*/
.
quad
sys_timer_create
.
quad
sys_timer_settime
.
quad
sys_timer_gettime
.
quad
sys_timer_getoverrun
.
quad
sys_timer_delete
/*
375
*/
.
quad
sys_clock_gettime
.
quad
sys_clock_settime
.
quad
sys_clock_getres
/*
378
*/
arch/arm/kernel/calls.S
View file @
86ae3b2a
...
...
@@ -200,16 +200,8 @@
.
long
SYMBOL_NAME
(
sys_ni_syscall
)
.
long
SYMBOL_NAME
(
sys_ni_syscall
)
/*
190
*/
.
long
SYMBOL_NAME
(
sys_vfork_wrapper
)
.
long
SYMBOL_NAME
(
sys_timer_create
)
.
long
SYMBOL_NAME
(
sys_timer_settime
)
.
long
SYMBOL_NAME
(
sys_timer_gettime
)
.
long
SYMBOL_NAME
(
sys_timer_getoverrun
)
/*
195
*/
.
long
SYMBOL_NAME
(
sys_timer_delete
)
.
long
SYMBOL_NAME
(
sys_clock_gettime
)
.
long
SYMBOL_NAME
(
sys_clock_settime
)
.
long
SYMBOL_NAME
(
sys_clock_getres
)
.
rept
NR_syscalls
-
1
98
.
rept
NR_syscalls
-
1
86
.
long
SYMBOL_NAME
(
sys_ni_syscall
)
.
endr
#endif
arch/i386/kernel/entry.S
View file @
86ae3b2a
...
...
@@ -560,14 +560,6 @@ ENTRY(sys_call_table)
.
long
SYMBOL_NAME
(
sys_ni_syscall
)
/*
streams1
*/
.
long
SYMBOL_NAME
(
sys_ni_syscall
)
/*
streams2
*/
.
long
SYMBOL_NAME
(
sys_vfork
)
/*
190
*/
.
long
SYMBOL_NAME
(
sys_timer_create
)
.
long
SYMBOL_NAME
(
sys_timer_settime
)
.
long
SYMBOL_NAME
(
sys_timer_gettime
)
.
long
SYMBOL_NAME
(
sys_timer_getoverrun
)
.
long
SYMBOL_NAME
(
sys_timer_delete
)
/*
195
*/
.
long
SYMBOL_NAME
(
sys_clock_gettime
)
.
long
SYMBOL_NAME
(
sys_clock_settime
)
.
long
SYMBOL_NAME
(
sys_clock_getres
)
/*
198
*/
/
*
*
NOTE
!!
This
doesn
't have to be exact - we just have
...
...
@@ -575,6 +567,6 @@ ENTRY(sys_call_table)
*
entries
.
Don
't panic if you notice that this hasn'
t
*
been
shrunk
every
time
we
add
a
new
system
call
.
*/
.
rept
NR_syscalls
-
19
8
.
rept
NR_syscalls
-
19
0
.
long
SYMBOL_NAME
(
sys_ni_syscall
)
.
endr
arch/i386/kernel/smp.c
View file @
86ae3b2a
...
...
@@ -1384,12 +1384,6 @@ void __init smp_boot_cpus(void)
printk
(
KERN_WARNING
"WARNING: SMP operation may be unreliable with B stepping processors.
\n
"
);
SMP_PRINTK
((
"Boot done.
\n
"
));
/*
* now we know the other CPUs have fired off and we know our
* APIC ID, so we can go init the TSS and stuff:
*/
cpu_init
();
cache_APIC_registers
();
#ifndef CONFIG_VISWS
/*
...
...
@@ -1401,6 +1395,11 @@ void __init smp_boot_cpus(void)
#endif
smp_done:
/*
* now we know the other CPUs have fired off and we know our
* APIC ID, so we can go init the TSS and stuff:
*/
cpu_init
();
}
...
...
@@ -1580,7 +1579,7 @@ static inline void send_IPI_single(int dest, int vector)
* bad as in the early days of SMP, so we might ease some of the
* paranoia here.
*/
static
void
flush_tlb_others
(
void
)
static
void
flush_tlb_others
(
unsigned
int
cpumask
)
{
int
cpu
=
smp_processor_id
();
int
stuck
;
...
...
@@ -1590,17 +1589,9 @@ static void flush_tlb_others(void)
* it's important that we do not generate any APIC traffic
* until the AP CPUs have booted up!
*/
if
(
cpu_online_map
)
{
/*
* The assignment is safe because it's volatile so the
* compiler cannot reorder it, because the i586 has
* strict memory ordering and because only the kernel
* lock holder may issue a tlb flush. If you break any
* one of those three change this to an atomic bus
* locked or.
*/
smp_invalidate_needed
=
cpu_online_map
;
cpumask
&=
cpu_online_map
;
if
(
cpumask
)
{
atomic_set_mask
(
cpumask
,
&
smp_invalidate_needed
);
/*
* Processors spinning on some lock with IRQs disabled
...
...
@@ -1623,8 +1614,10 @@ static void flush_tlb_others(void)
/*
* Take care of "crossing" invalidates
*/
if
(
test_bit
(
cpu
,
&
smp_invalidate_needed
))
clear_bit
(
cpu
,
&
smp_invalidate_needed
);
if
(
test_bit
(
cpu
,
&
smp_invalidate_needed
))
{
clear_bit
(
cpu
,
&
smp_invalidate_needed
);
local_flush_tlb
();
}
--
stuck
;
if
(
!
stuck
)
{
printk
(
"stuck on TLB IPI wait (CPU#%d)
\n
"
,
cpu
);
...
...
@@ -1647,44 +1640,43 @@ void flush_tlb_current_task(void)
unsigned
long
vm_mask
=
1
<<
current
->
processor
;
struct
mm_struct
*
mm
=
current
->
mm
;
if
(
mm
->
cpu_vm_mask
!=
vm_mask
)
flush_tlb_others
();
mm
->
cpu_vm_mask
=
vm_mask
;
if
(
mm
->
cpu_vm_mask
!=
vm_mask
)
{
flush_tlb_others
(
mm
->
cpu_vm_mask
&
~
vm_mask
);
mm
->
cpu_vm_mask
=
vm_mask
;
}
local_flush_tlb
();
}
void
flush_tlb_mm
(
struct
mm_struct
*
mm
)
{
unsigned
long
vm_mask
=
1
<<
current
->
processor
;
unsigned
long
cpu_mask
=
mm
->
cpu_vm_mask
&
~
vm_mask
;
if
(
mm
->
cpu_vm_mask
&
~
vm_mask
)
flush_tlb_others
();
mm
->
cpu_vm_mask
=
0
;
if
(
current
->
active_mm
==
mm
)
{
local_flush_tlb
();
mm
->
cpu_vm_mask
=
vm_mask
;
return
;
local_flush_tlb
()
;
}
mm
->
cpu_vm_mask
=
0
;
flush_tlb_others
(
cpu_mask
)
;
}
void
flush_tlb_page
(
struct
vm_area_struct
*
vma
,
unsigned
long
va
)
{
unsigned
long
vm_mask
=
1
<<
current
->
processor
;
struct
mm_struct
*
mm
=
vma
->
vm_mm
;
unsigned
long
cpu_mask
=
mm
->
cpu_vm_mask
&
~
vm_mask
;
if
(
mm
->
cpu_vm_mask
&
~
vm_mask
)
flush_tlb_others
();
mm
->
cpu_vm_mask
=
0
;
if
(
current
->
active_mm
==
mm
)
{
__flush_tlb_one
(
va
);
mm
->
cpu_vm_mask
=
vm_mask
;
return
;
}
mm
->
cpu_vm_mask
=
0
;
flush_tlb_others
(
cpu_mask
)
;
}
void
flush_tlb_all
(
void
)
{
flush_tlb_others
();
flush_tlb_others
(
~
(
1
<<
current
->
processor
)
);
local_flush_tlb
();
}
...
...
@@ -1908,13 +1900,24 @@ asmlinkage void smp_reschedule_interrupt(void)
}
/*
* Invalidate call-back
* Invalidate call-back.
*
* Mark the CPU as a VM user if there is a active
* thread holding on to an mm at this time. This
* allows us to optimize CPU cross-calls even in the
* presense of lazy TLB handling.
*/
asmlinkage
void
smp_invalidate_interrupt
(
void
)
{
if
(
test_and_clear_bit
(
smp_processor_id
(),
&
smp_invalidate_needed
))
local_flush_tlb
()
;
struct
task_struct
*
tsk
=
current
;
unsigned
int
cpu
=
tsk
->
processor
;
if
(
test_and_clear_bit
(
cpu
,
&
smp_invalidate_needed
))
{
struct
mm_struct
*
mm
=
tsk
->
mm
;
if
(
mm
)
atomic_set_mask
(
1
<<
cpu
,
&
mm
->
cpu_vm_mask
);
local_flush_tlb
();
}
ack_APIC_irq
();
}
...
...
arch/i386/mm/fault.c
View file @
86ae3b2a
...
...
@@ -245,9 +245,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
printk
(
" at virtual address %08lx
\n
"
,
address
);
printk
(
" printing eip:
\n
"
);
printk
(
"%08lx
\n
"
,
regs
->
eip
);
__asm__
(
"movl %%cr3,%0"
:
"=r"
(
page
));
printk
(
KERN_ALERT
"current->active_mm.pgd = %p, %%cr3 = %08lx
\n
"
,
tsk
->
active_mm
->
pgd
,
page
);
page
=
((
unsigned
long
*
)
__va
(
page
))[
address
>>
22
];
printk
(
KERN_ALERT
"*pde = %08lx
\n
"
,
page
);
if
(
page
&
1
)
{
...
...
arch/m68k/kernel/entry.S
View file @
86ae3b2a
...
...
@@ -609,14 +609,6 @@ SYMBOL_NAME_LABEL(sys_call_table)
.
long
SYMBOL_NAME
(
sys_ni_syscall
)
/*
streams1
*/
.
long
SYMBOL_NAME
(
sys_ni_syscall
)
/*
streams2
*/
.
long
SYMBOL_NAME
(
sys_vfork
)
/*
190
*/
.
long
SYMBOL_NAME
(
sys_timer_create
)
.
long
SYMBOL_NAME
(
sys_timer_settime
)
.
long
SYMBOL_NAME
(
sys_timer_gettime
)
.
long
SYMBOL_NAME
(
sys_timer_getoverrun
)
.
long
SYMBOL_NAME
(
sys_timer_delete
)
/*
195
*/
.
long
SYMBOL_NAME
(
sys_clock_gettime
)
.
long
SYMBOL_NAME
(
sys_clock_settime
)
.
long
SYMBOL_NAME
(
sys_clock_getres
)
/*
198
*/
.
rept
NR_syscalls
-(
.
-
SYMBOL_NAME
(
sys_call_table
))/
4
.
long
SYMBOL_NAME
(
sys_ni_syscall
)
...
...
arch/mips/kernel/syscalls.h
View file @
86ae3b2a
...
...
@@ -225,11 +225,3 @@ SYS(sys_sigaltstack, 2)
SYS
(
sys_sendfile
,
3
)
SYS
(
sys_ni_syscall
,
0
)
SYS
(
sys_ni_syscall
,
0
)
SYS
(
sys_timer_create
,
3
)
/* 4210 */
SYS
(
sys_timer_settime
,
4
)
SYS
(
sys_timer_gettime
,
2
)
SYS
(
sys_timer_getoverrun
,
1
)
SYS
(
sys_timer_delete
,
1
)
SYS
(
sys_clock_gettime
,
2
)
/* 4215 */
SYS
(
sys_clock_settime
,
2
)
SYS
(
sys_clock_getres
,
2
)
arch/ppc/kernel/misc.S
View file @
86ae3b2a
...
...
@@ -894,12 +894,4 @@ sys_call_table:
.
long
sys_ni_syscall
/*
streams1
*/
.
long
sys_ni_syscall
/*
streams2
*/
.
long
sys_vfork
.
long
sys_timer_create
/*
190
*/
.
long
sys_timer_settime
.
long
sys_timer_gettime
.
long
sys_timer_getoverrun
.
long
sys_timer_delete
.
long
sys_clock_gettime
/*
195
*/
.
long
sys_clock_settime
.
long
sys_clock_getres
/*
197
*/
.
space
(
NR_syscalls
-
197
)*
4
.
space
(
NR_syscalls
-
183
)*
4
arch/sparc/kernel/systbls.S
View file @
86ae3b2a
...
...
@@ -68,8 +68,7 @@ sys_call_table:
/*
240
*/
.
long
sys_munlockall
,
sys_sched_setparam
,
sys_sched_getparam
,
sys_sched_setscheduler
,
sys_sched_getscheduler
/*
245
*/
.
long
sys_sched_yield
,
sys_sched_get_priority_max
,
sys_sched_get_priority_min
,
sys_sched_rr_get_interval
,
sys_nanosleep
/*
250
*/
.
long
sys_mremap
,
sys_sysctl
,
sys_getsid
,
sys_fdatasync
,
sys_nfsservctl
/*
255
*/
.
long
sys_aplib
,
sys_timer_create
,
sys_timer_settime
,
sys_timer_gettime
,
sys_timer_getoverrun
/*
260
*/
.
long
sys_timer_delete
,
sys_clock_gettime
,
sys_clock_settime
,
sys_clock_getres
/*
255
*/
.
long
sys_aplib
,
sys_nis_syscall
/
*
Now
the
SunOS
syscall
table
.
*/
...
...
arch/sparc64/kernel/systbls.S
View file @
86ae3b2a
...
...
@@ -68,8 +68,7 @@ sys_call_table32:
/*
240
*/
.
word
sys_munlockall
,
sys_sched_setparam
,
sys_sched_getparam
,
sys_sched_setscheduler
,
sys_sched_getscheduler
.
word
sys_sched_yield
,
sys_sched_get_priority_max
,
sys_sched_get_priority_min
,
sys32_sched_rr_get_interval
,
sys32_nanosleep
/*
250
*/
.
word
sys_mremap
,
sys_sysctl
,
sys_getsid
,
sys_fdatasync
,
sys32_nfsservctl
/*
255
*/
.
word
sys_aplib
,
sys_timer_create
,
sys_timer_settime
,
sys_timer_gettime
,
sys_timer_getoverrun
/*
260
*/
.
word
sys_timer_delete
,
sys_clock_gettime
,
sys_clock_settime
,
sys_clock_getres
.
word
sys_aplib
/
*
Now
the
64
-
bit
native
Linux
syscall
table
.
*/
...
...
@@ -128,8 +127,7 @@ sys_call_table:
/*
240
*/
.
word
sys_munlockall
,
sys_sched_setparam
,
sys_sched_getparam
,
sys_sched_setscheduler
,
sys_sched_getscheduler
.
word
sys_sched_yield
,
sys_sched_get_priority_max
,
sys_sched_get_priority_min
,
sys_sched_rr_get_interval
,
sys_nanosleep
/*
250
*/
.
word
sys_mremap
,
sys_sysctl
,
sys_getsid
,
sys_fdatasync
,
sys_nfsservctl
/*
255
*/
.
word
sys_aplib
,
sys_timer_create
,
sys_timer_settime
,
sys_timer_gettime
,
sys_timer_getoverrun
/*
260
*/
.
word
sys_timer_delete
,
sys_clock_gettime
,
sys_clock_settime
,
sys_clock_getres
.
word
sys_aplib
/
*
Now
the
32
-
bit
SunOS
syscall
table
.
*/
...
...
drivers/block/ll_rw_blk.c
View file @
86ae3b2a
...
...
@@ -403,7 +403,7 @@ void make_request(int major,int rw, struct buffer_head * bh)
unsigned
long
maxsector
=
(
blk_size
[
major
][
MINOR
(
bh
->
b_rdev
)]
<<
1
)
+
1
;
if
(
maxsector
<
count
||
maxsector
-
count
<
sector
)
{
bh
->
b_state
&=
(
1
<<
BH_Lock
);
bh
->
b_state
&=
(
1
<<
BH_Lock
)
|
(
1
<<
BH_Mapped
)
;
/* This may well happen - the kernel calls bread()
without checking the size of the device, e.g.,
when mounting a device. */
...
...
drivers/char/ppdev.c
View file @
86ae3b2a
...
...
@@ -60,6 +60,8 @@ struct pp_struct {
unsigned
int
flags
;
int
irqresponse
;
unsigned
char
irqctl
;
struct
ieee1284_info
state
;
struct
ieee1284_info
saved_state
;
};
/* pp_struct.flags bitfields */
...
...
@@ -348,6 +350,9 @@ static int pp_ioctl(struct inode *inode, struct file *file,
/* First handle the cases that don't take arguments. */
if
(
cmd
==
PPCLAIM
)
{
struct
ieee1284_info
*
info
;
int
first_claim
=
0
;
if
(
pp
->
flags
&
PP_CLAIMED
)
{
printk
(
KERN_DEBUG
CHRDEV
"%x: you've already got it!
\n
"
,
minor
);
...
...
@@ -359,6 +364,8 @@ static int pp_ioctl(struct inode *inode, struct file *file,
int
err
=
register_device
(
minor
,
pp
);
if
(
err
)
return
err
;
first_claim
=
1
;
}
parport_claim_or_block
(
pp
->
pdev
);
...
...
@@ -367,6 +374,30 @@ static int pp_ioctl(struct inode *inode, struct file *file,
/* For interrupt-reporting to work, we need to be
* informed of each interrupt. */
enable_irq
(
pp
);
/* We may need to fix up the state machine. */
info
=
&
pp
->
pdev
->
port
->
ieee1284
;
pp
->
saved_state
.
mode
=
info
->
mode
;
pp
->
saved_state
.
phase
=
info
->
phase
;
if
(
pp
->
mode
!=
info
->
mode
)
{
int
phase
=
IEEE1284_PH_FWD_IDLE
;
if
(
first_claim
)
{
info
->
mode
=
pp
->
mode
;
switch
(
pp
->
mode
&
~
(
IEEE1284_DEVICEID
|
IEEE1284_ADDR
))
{
case
IEEE1284_MODE_NIBBLE
:
case
IEEE1284_MODE_BYTE
:
phase
=
IEEE1284_PH_REV_IDLE
;
}
info
->
phase
=
phase
;
}
else
{
/* Just restore the state. */
info
->
mode
=
pp
->
state
.
mode
;
info
->
phase
=
pp
->
state
.
phase
;
}
}
return
0
;
}
...
...
@@ -406,6 +437,7 @@ static int pp_ioctl(struct inode *inode, struct file *file,
port
=
pp
->
pdev
->
port
;
switch
(
cmd
)
{
struct
ieee1284_info
*
info
;
unsigned
char
reg
;
unsigned
char
mask
;
int
mode
;
...
...
@@ -431,6 +463,12 @@ static int pp_ioctl(struct inode *inode, struct file *file,
return
0
;
case
PPRELEASE
:
/* Save the state machine's state. */
info
=
&
pp
->
pdev
->
port
->
ieee1284
;
pp
->
state
.
mode
=
info
->
mode
;
pp
->
state
.
phase
=
info
->
phase
;
info
->
mode
=
pp
->
saved_state
.
mode
;
info
->
phase
=
pp
->
saved_state
.
phase
;
parport_release
(
pp
->
pdev
);
pp
->
flags
&=
~
PP_CLAIMED
;
return
0
;
...
...
drivers/parport/parport_ax.c
deleted
100644 → 0
View file @
6ae9dd08
/* $Id: parport_ax.c,v 1.20 1999/07/03 08:56:21 davem Exp $
* Parallel-port routines for Sun Ultra/AX architecture
*
* Author: Eddie C. Dost <ecd@skynet.be>
*
* based on work by:
* Phil Blundell <Philip.Blundell@pobox.com>
* Tim Waugh <tim@cyberelk.demon.co.uk>
* Jose Renau <renau@acm.org>
* David Campbell <campbell@tirian.che.curtin.edu.au>
* Grant Guenther <grant@torque.net>
*/
#include <linux/string.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/malloc.h>
#include <linux/init.h>
#include <linux/parport.h>
#include <asm/ptrace.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/ebus.h>
#include <asm/ns87303.h>
#include <asm/irq.h>
/*
* Define this if you have Devices which don't support short
* host read/write cycles.
*/
#undef HAVE_SLOW_DEVICES
#define DATA 0x00
#define STATUS 0x01
#define CONTROL 0x02
#define EPPADDR 0x03
#define EPPDATA 0x04
#define CFIFO 0x400
#define DFIFO 0x400
#define TFIFO 0x400
#define CONFIGA 0x400
#define CONFIGB 0x401
#define ECONTROL 0x402
static
void
parport_ax_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
parport_generic_irq
(
irq
,
(
struct
parport
*
)
dev_id
,
regs
);
}
void
parport_ax_write_epp
(
struct
parport
*
p
,
unsigned
char
d
)
{
outb
(
d
,
p
->
base
+
EPPDATA
);
}
unsigned
char
parport_ax_read_epp
(
struct
parport
*
p
)
{
return
inb
(
p
->
base
+
EPPDATA
);
}
void
parport_ax_write_epp_addr
(
struct
parport
*
p
,
unsigned
char
d
)
{
outb
(
d
,
p
->
base
+
EPPADDR
);
}
unsigned
char
parport_ax_read_epp_addr
(
struct
parport
*
p
)
{
return
inb
(
p
->
base
+
EPPADDR
);
}
int
parport_ax_epp_clear_timeout
(
struct
parport
*
pb
);
int
parport_ax_check_epp_timeout
(
struct
parport
*
p
)
{
if
(
!
(
inb
(
p
->
base
+
STATUS
)
&
1
))
return
0
;
parport_ax_epp_clear_timeout
(
p
);
return
1
;
}
unsigned
char
parport_ax_read_configb
(
struct
parport
*
p
)
{
return
inb
(
p
->
base
+
CONFIGB
);
}
void
parport_ax_write_data
(
struct
parport
*
p
,
unsigned
char
d
)
{
outb
(
d
,
p
->
base
+
DATA
);
}
unsigned
char
parport_ax_read_data
(
struct
parport
*
p
)
{
return
inb
(
p
->
base
+
DATA
);
}
void
parport_ax_write_control
(
struct
parport
*
p
,
unsigned
char
d
)
{
outb
(
d
,
p
->
base
+
CONTROL
);
}
unsigned
char
parport_ax_read_control
(
struct
parport
*
p
)
{
return
inb
(
p
->
base
+
CONTROL
);
}
unsigned
char
parport_ax_frob_control
(
struct
parport
*
p
,
unsigned
char
mask
,
unsigned
char
val
)
{
unsigned
char
old
=
inb
(
p
->
base
+
CONTROL
);
outb
(((
old
&
~
mask
)
^
val
),
p
->
base
+
CONTROL
);
return
old
;
}
void
parport_ax_write_status
(
struct
parport
*
p
,
unsigned
char
d
)
{
outb
(
d
,
p
->
base
+
STATUS
);
}
unsigned
char
parport_ax_read_status
(
struct
parport
*
p
)
{
return
inb
(
p
->
base
+
STATUS
);
}
void
parport_ax_write_econtrol
(
struct
parport
*
p
,
unsigned
char
d
)
{
outb
(
d
,
p
->
base
+
ECONTROL
);
}
unsigned
char
parport_ax_read_econtrol
(
struct
parport
*
p
)
{
return
inb
(
p
->
base
+
ECONTROL
);
}
unsigned
char
parport_ax_frob_econtrol
(
struct
parport
*
p
,
unsigned
char
mask
,
unsigned
char
val
)
{
unsigned
char
old
=
inb
(
p
->
base
+
ECONTROL
);
outb
(((
old
&
~
mask
)
^
val
),
p
->
base
+
ECONTROL
);
return
old
;
}
void
parport_ax_change_mode
(
struct
parport
*
p
,
int
m
)
{
/* FIXME */
parport_ax_frob_econtrol
(
p
,
0xe0
,
m
<<
5
);
}
void
parport_ax_write_fifo
(
struct
parport
*
p
,
unsigned
char
v
)
{
outb
(
v
,
p
->
base
+
DFIFO
);
}
unsigned
char
parport_ax_read_fifo
(
struct
parport
*
p
)
{
return
inb
(
p
->
base
+
DFIFO
);
}
void
parport_ax_disable_irq
(
struct
parport
*
p
)
{
struct
linux_ebus_dma
*
dma
=
p
->
private_data
;
unsigned
int
dcsr
;
dcsr
=
readl
((
unsigned
long
)
&
dma
->
dcsr
);
dcsr
&=
~
(
EBUS_DCSR_INT_EN
);
writel
(
dcsr
,
(
unsigned
long
)
&
dma
->
dcsr
);
}
void
parport_ax_enable_irq
(
struct
parport
*
p
)
{
struct
linux_ebus_dma
*
dma
=
p
->
private_data
;
unsigned
int
dcsr
;
dcsr
=
readl
((
unsigned
long
)
&
dma
->
dcsr
);
dcsr
|=
EBUS_DCSR_INT_EN
;
writel
(
dcsr
,
(
unsigned
long
)
&
dma
->
dcsr
);
}
void
parport_ax_init_state
(
struct
pardevice
*
dev
,
struct
parport_state
*
s
)
{
struct
linux_ebus_dma
*
dma
=
dev
->
port
->
private_data
;
s
->
u
.
ax
.
ctr
=
0xc
|
(
dev
->
irq_func
?
0x10
:
0x0
);
s
->
u
.
ax
.
ecr
=
0x0
;
if
(
dev
->
irq_func
)
s
->
u
.
ax
.
dcsr
=
(
readl
((
unsigned
long
)
&
dma
->
dcsr
)
|
EBUS_DCSR_INT_EN
);
else
s
->
u
.
ax
.
dcsr
=
(
readl
((
unsigned
long
)
&
dma
->
dcsr
)
&
~
EBUS_DCSR_INT_EN
);
}
void
parport_ax_save_state
(
struct
parport
*
p
,
struct
parport_state
*
s
)
{
struct
linux_ebus_dma
*
dma
=
p
->
private_data
;
s
->
u
.
ax
.
ctr
=
parport_ax_read_control
(
p
);
s
->
u
.
ax
.
ecr
=
parport_ax_read_econtrol
(
p
);
s
->
u
.
ax
.
dcsr
=
readl
((
unsigned
long
)
&
dma
->
dcsr
);
}
void
parport_ax_restore_state
(
struct
parport
*
p
,
struct
parport_state
*
s
)
{
struct
linux_ebus_dma
*
dma
=
p
->
private_data
;
parport_ax_write_control
(
p
,
s
->
u
.
ax
.
ctr
);
parport_ax_write_econtrol
(
p
,
s
->
u
.
ax
.
ecr
);
writel
(
s
->
u
.
ax
.
dcsr
,
(
unsigned
long
)
&
dma
->
dcsr
);
}
void
parport_ax_inc_use_count
(
void
)
{
#ifdef MODULE
MOD_INC_USE_COUNT
;
#endif
}
void
parport_ax_dec_use_count
(
void
)
{
#ifdef MODULE
MOD_DEC_USE_COUNT
;
#endif
}
static
struct
parport_operations
parport_ax_ops
=
{
parport_ax_write_data
,
parport_ax_read_data
,
parport_ax_write_control
,
parport_ax_read_control
,
parport_ax_frob_control
,
parport_ax_read_status
,
parport_ax_enable_irq
,
parport_ax_disable_irq
,
parport_ax_data_forward
,
parport_ax_data_reverse
,
parport_ax_interrupt
,
parport_ax_init_state
,
parport_ax_save_state
,
parport_ax_restore_state
,
parport_ax_inc_use_count
,
parport_ax_dec_use_count
,
parport_ieee1284_epp_write_data
,
parport_ieee1284_epp_read_data
,
parport_ieee1284_epp_write_addr
,
parport_ieee1284_epp_read_addr
,
parport_ieee1284_ecp_write_data
,
parport_ieee1284_ecp_read_data
,
parport_ieee1284_ecp_write_addr
,
parport_ieee1284_write_compat
,
parport_ieee1284_read_nibble
,
parport_ieee1284_read_byte
,
};
/******************************************************
* MODE detection section:
*/
/*
* Clear TIMEOUT BIT in EPP MODE
*/
int
parport_ax_epp_clear_timeout
(
struct
parport
*
pb
)
{
unsigned
char
r
;
if
(
!
(
parport_ax_read_status
(
pb
)
&
0x01
))
return
1
;
/* To clear timeout some chips require double read */
parport_ax_read_status
(
pb
);
r
=
parport_ax_read_status
(
pb
);
parport_ax_write_status
(
pb
,
r
|
0x01
);
/* Some reset by writing 1 */
parport_ax_write_status
(
pb
,
r
&
0xfe
);
/* Others by writing 0 */
r
=
parport_ax_read_status
(
pb
);
return
!
(
r
&
0x01
);
}
/* Check for ECP
*
* Old style XT ports alias io ports every 0x400, hence accessing ECONTROL
* on these cards actually accesses the CTR.
*
* Modern cards don't do this but reading from ECONTROL will return 0xff
* regardless of what is written here if the card does NOT support
* ECP.
*
* We will write 0x2c to ECONTROL and 0xcc to CTR since both of these
* values are "safe" on the CTR since bits 6-7 of CTR are unused.
*/
static
int
parport_ECR_present
(
struct
parport
*
pb
)
{
unsigned
int
r
;
unsigned
char
octr
=
pb
->
ops
->
read_control
(
pb
),
oecr
=
pb
->
ops
->
read_econtrol
(
pb
);
r
=
pb
->
ops
->
read_control
(
pb
);
if
((
pb
->
ops
->
read_econtrol
(
pb
)
&
0x3
)
==
(
r
&
0x3
))
{
pb
->
ops
->
write_control
(
pb
,
r
^
0x2
);
/* Toggle bit 1 */
r
=
pb
->
ops
->
read_control
(
pb
);
if
((
pb
->
ops
->
read_econtrol
(
pb
)
&
0x2
)
==
(
r
&
0x2
))
{
pb
->
ops
->
write_control
(
pb
,
octr
);
return
0
;
/* Sure that no ECONTROL register exists */
}
}
if
((
pb
->
ops
->
read_econtrol
(
pb
)
&
0x3
)
!=
0x1
)
return
0
;
pb
->
ops
->
write_econtrol
(
pb
,
0x34
);
if
(
pb
->
ops
->
read_econtrol
(
pb
)
!=
0x35
)
return
0
;
pb
->
ops
->
write_econtrol
(
pb
,
oecr
);
pb
->
ops
->
write_control
(
pb
,
octr
);
return
PARPORT_MODE_PCECR
;
}
static
int
parport_ECP_supported
(
struct
parport
*
pb
)
{
int
i
;
unsigned
char
oecr
=
pb
->
ops
->
read_econtrol
(
pb
);
/* If there is no ECONTROL, we have no hope of supporting ECP. */
if
(
!
(
pb
->
modes
&
PARPORT_MODE_PCECR
))
return
0
;
/*
* Using LGS chipset it uses ECONTROL register, but
* it doesn't support ECP or FIFO MODE
*/
pb
->
ops
->
write_econtrol
(
pb
,
0xc0
);
/* TEST FIFO */
for
(
i
=
0
;
i
<
1024
&&
(
pb
->
ops
->
read_econtrol
(
pb
)
&
0x01
);
i
++
)
pb
->
ops
->
write_fifo
(
pb
,
0xaa
);
pb
->
ops
->
write_econtrol
(
pb
,
oecr
);
return
(
i
==
1024
)
?
0
:
PARPORT_MODE_PCECP
;
}
/* Detect PS/2 support.
*
* Bit 5 (0x20) sets the PS/2 data direction; setting this high
* allows us to read data from the data lines. In theory we would get back
* 0xff but any peripheral attached to the port may drag some or all of the
* lines down to zero. So if we get back anything that isn't the contents
* of the data register we deem PS/2 support to be present.
*
* Some SPP ports have "half PS/2" ability - you can't turn off the line
* drivers, but an external peripheral with sufficiently beefy drivers of
* its own can overpower them and assert its own levels onto the bus, from
* where they can then be read back as normal. Ports with this property
* and the right type of device attached are likely to fail the SPP test,
* (as they will appear to have stuck bits) and so the fact that they might
* be misdetected here is rather academic.
*/
static
int
parport_PS2_supported
(
struct
parport
*
pb
)
{
int
ok
=
0
;
unsigned
char
octr
=
pb
->
ops
->
read_control
(
pb
);
pb
->
ops
->
write_control
(
pb
,
octr
|
0x20
);
/* try to tri-state buffer */
pb
->
ops
->
write_data
(
pb
,
0x55
);
if
(
pb
->
ops
->
read_data
(
pb
)
!=
0x55
)
ok
++
;
pb
->
ops
->
write_data
(
pb
,
0xaa
);
if
(
pb
->
ops
->
read_data
(
pb
)
!=
0xaa
)
ok
++
;
pb
->
ops
->
write_control
(
pb
,
octr
);
/* cancel input mode */
return
ok
?
PARPORT_MODE_PCPS2
:
0
;
}
static
int
parport_ECPPS2_supported
(
struct
parport
*
pb
)
{
int
mode
;
unsigned
char
oecr
=
pb
->
ops
->
read_econtrol
(
pb
);
if
(
!
(
pb
->
modes
&
PARPORT_MODE_PCECR
))
return
0
;
pb
->
ops
->
write_econtrol
(
pb
,
0x20
);
mode
=
parport_PS2_supported
(
pb
);
pb
->
ops
->
write_econtrol
(
pb
,
oecr
);
return
mode
?
PARPORT_MODE_PCECPPS2
:
0
;
}
#define printmode(x) \
{ \
if (p->modes & PARPORT_MODE_PC##x) { \
printk("%s%s", f ? "," : "", #x); \
f++; \
} \
}
int
init_one_port
(
struct
linux_ebus_device
*
dev
)
{
struct
parport
tmpport
,
*
p
;
unsigned
long
base
;
unsigned
long
config
;
unsigned
char
tmp
;
int
irq
,
dma
;
/* Pointer to NS87303 Configuration Registers */
config
=
dev
->
base_address
[
1
];
/* Setup temporary access to Device operations */
tmpport
.
base
=
dev
->
base_address
[
0
];
tmpport
.
ops
=
&
parport_ax_ops
;
/* Enable ECP mode, set bit 2 of the CTR first */
tmpport
.
ops
->
write_control
(
&
tmpport
,
0x04
);
tmp
=
ns87303_readb
(
config
,
PCR
);
tmp
|=
(
PCR_EPP_IEEE
|
PCR_ECP_ENABLE
|
PCR_ECP_CLK_ENA
);
ns87303_writeb
(
config
,
PCR
,
tmp
);
/* LPT CTR bit 5 controls direction of parallel port */
tmp
=
ns87303_readb
(
config
,
PTR
);
tmp
|=
PTR_LPT_REG_DIR
;
ns87303_writeb
(
config
,
PTR
,
tmp
);
/* Configure IRQ to Push Pull, Level Low */
tmp
=
ns87303_readb
(
config
,
PCR
);
tmp
&=
~
(
PCR_IRQ_ODRAIN
);
tmp
|=
PCR_IRQ_POLAR
;
ns87303_writeb
(
config
,
PCR
,
tmp
);
#ifndef HAVE_SLOW_DEVICES
/* Enable Zero Wait State for ECP */
tmp
=
ns87303_readb
(
config
,
FCR
);
tmp
|=
FCR_ZWS_ENA
;
ns87303_writeb
(
config
,
FCR
,
tmp
);
#endif
/*
* Now continue initializing the port
*/
base
=
dev
->
base_address
[
0
];
irq
=
dev
->
irqs
[
0
];
dma
=
PARPORT_DMA_AUTO
;
if
(
!
(
p
=
parport_register_port
(
base
,
irq
,
dma
,
&
parport_ax_ops
)))
return
0
;
/* Save away pointer to our EBus DMA */
p
->
private_data
=
(
void
*
)
dev
->
base_address
[
2
];
p
->
modes
=
PARPORT_MODE_PCSPP
|
parport_PS2_supported
(
p
);
if
(
!
check_region
(
p
->
base
+
0x400
,
3
))
{
p
->
modes
|=
parport_ECR_present
(
p
);
p
->
modes
|=
parport_ECP_supported
(
p
);
p
->
modes
|=
parport_ECPPS2_supported
(
p
);
}
p
->
size
=
3
;
if
(
p
->
dma
==
PARPORT_DMA_AUTO
)
p
->
dma
=
(
p
->
modes
&
PARPORT_MODE_PCECP
)
?
0
:
PARPORT_DMA_NONE
;
printk
(
KERN_INFO
"%s: PC-style at 0x%lx"
,
p
->
name
,
p
->
base
);
if
(
p
->
irq
!=
PARPORT_IRQ_NONE
)
printk
(
", irq %s"
,
__irq_itoa
(
p
->
irq
));
if
(
p
->
dma
!=
PARPORT_DMA_NONE
)
printk
(
", dma %d"
,
p
->
dma
);
printk
(
" ["
);
{
int
f
=
0
;
printmode
(
SPP
);
printmode
(
PS2
);
printmode
(
ECP
);
printmode
(
ECPPS2
);
}
printk
(
"]
\n
"
);
parport_proc_register
(
p
);
if
(
p
->
irq
!=
PARPORT_IRQ_NONE
)
if
((
err
=
request_irq
(
p
->
irq
,
parport_ax_interrupt
,
0
,
p
->
name
,
p
))
!=
0
)
return
0
;
/* @@@ FIXME */
request_region
(
p
->
base
,
p
->
size
,
p
->
name
);
if
(
p
->
modes
&
PARPORT_MODE_PCECR
)
request_region
(
p
->
base
+
0x400
,
3
,
p
->
name
);
request_region
((
unsigned
long
)
p
->
private_data
,
sizeof
(
struct
linux_ebus_dma
),
p
->
name
);
p
->
ops
->
write_control
(
p
,
0x0c
);
p
->
ops
->
write_data
(
p
,
0
);
/* Tell the high-level drivers about the port. */
parport_announce_port
(
p
);
return
1
;
}
EXPORT_NO_SYMBOLS
;
#ifdef MODULE
int
init_module
(
void
)
#else
__initfunc
(
int
parport_ax_init
(
void
))
#endif
{
struct
linux_ebus
*
ebus
;
struct
linux_ebus_device
*
edev
;
int
count
=
0
;
for_each_ebus
(
ebus
)
{
for_each_ebusdev
(
edev
,
ebus
)
{
if
(
!
strcmp
(
edev
->
prom_name
,
"ecpp"
))
count
+=
init_one_port
(
edev
);
}
}
return
count
?
0
:
-
ENODEV
;
}
#ifdef MODULE
void
cleanup_module
(
void
)
{
struct
parport
*
p
=
parport_enumerate
(),
*
tmp
;
while
(
p
)
{
tmp
=
p
->
next
;
if
(
p
->
modes
&
PARPORT_MODE_PCSPP
)
{
if
(
p
->
irq
!=
PARPORT_IRQ_NONE
)
{
parport_ax_disable_irq
(
p
);
free_irq
(
p
->
irq
,
p
);
}
release_region
(
p
->
base
,
p
->
size
);
if
(
p
->
modes
&
PARPORT_MODE_PCECR
)
release_region
(
p
->
base
+
0x400
,
3
);
release_region
((
unsigned
long
)
p
->
private_data
,
sizeof
(
struct
linux_ebus_dma
));
parport_proc_unregister
(
p
);
parport_unregister_port
(
p
);
}
p
=
tmp
;
}
}
#endif
drivers/parport/parport_pc.c
View file @
86ae3b2a
...
...
@@ -1831,6 +1831,7 @@ void cleanup_module(void)
tmp
=
p
->
next
;
if
(
p
->
modes
&
PARPORT_MODE_PCSPP
)
{
struct
parport_pc_private
*
priv
=
p
->
private_data
;
struct
parport_operations
*
ops
=
p
->
ops
;
if
(
p
->
dma
!=
PARPORT_DMA_NONE
)
free_dma
(
p
->
dma
);
if
(
p
->
irq
!=
PARPORT_IRQ_NONE
)
...
...
@@ -1844,8 +1845,8 @@ void cleanup_module(void)
if
(
priv
->
dma_buf
)
free_page
((
unsigned
long
)
priv
->
dma_buf
);
kfree
(
p
->
private_data
);
kfree
(
p
->
ops
);
/* hope no-one cached it */
parport_unregister_port
(
p
);
kfree
(
ops
);
/* hope no-one cached it */
}
p
=
tmp
;
}
...
...
drivers/usb/Config.in
View file @
86ae3b2a
...
...
@@ -35,6 +35,9 @@ if [ ! "$CONFIG_USB" = "n" ]; then
dep_tristate ' USB SCSI verbose debug' CONFIG_USB_SCSI_DEBUG $CONFIG_USB_SCSI
fi
dep_tristate 'EZUSB Firmware downloader' CONFIG_USB_EZUSB $CONFIG_USB
if [ "$CONFIG_PROC_FS" != "n" ]; then
bool 'Preliminary /proc/bus/usb support' CONFIG_USB_PROC
fi
fi
endmenu
drivers/usb/Makefile
View file @
86ae3b2a
...
...
@@ -22,6 +22,9 @@ endif
ifeq
($(CONFIG_USB),m)
M_OBJS
+=
usbcore.o
MIX_OBJS
+=
usb.o usb-debug.o usb-core.o
ifeq
($(CONFIG_USB_PROC),y)
MIX_OBJS
+=
proc_usb.o
endif
endif
ifeq
($(CONFIG_USB_UHCI),y)
...
...
@@ -153,7 +156,10 @@ usb-ohci.o: ohci.o ohci-debug.o
usb-ohci-hcd.o
:
ohci-hcd.o ohci-root-hub.o
$(LD)
$(LD_RFLAG)
-r
-o
$@
ohci-hcd.o ohci-root-hub.o
ifeq
($(CONFIG_USB_PROC),y)
usbcore.o
:
usb.o usb-debug.o usb-core.o proc_usb.o
$(LD)
$(LD_RFLAG)
-r
-o
$@
usb.o usb-debug.o usb-core.o proc_usb.o
else
usbcore.o
:
usb.o usb-debug.o usb-core.o
$(LD)
$(LD_RFLAG)
-r
-o
$@
usb.o usb-debug.o usb-core.o
endif
drivers/usb/ezusb.c
View file @
86ae3b2a
...
...
@@ -27,7 +27,6 @@
/*****************************************************************************/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/socket.h>
#include <asm/uaccess.h>
...
...
drivers/usb/inits.h
View file @
86ae3b2a
...
...
@@ -5,3 +5,5 @@ int usb_acm_init(void);
int
usb_printer_init
(
void
);
void
usb_hub_cleanup
(
void
);
void
usb_mouse_cleanup
(
void
);
int
proc_usb_init
(
void
);
void
proc_usb_cleanup
(
void
);
drivers/usb/proc_usb.c
0 → 100644
View file @
86ae3b2a
/*
* drivers/usb/proc_usb.c
* (C) Copyright 1999 Randy Dunlap.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*************************************************************
*
* This is a /proc/bus/usb filesystem output module for USB.
* It creates /proc/bus/usb/drivers and /proc/bus/usb/devices.
*
* /proc/bus/usb/devices contains USB topology, device, config, class,
* interface, & endpoint data.
*
* I considered using /proc/bus/usb/devices/device# for each device
* as it is attached or detached, but I didn't like this for some
* reason -- maybe it's just too deep of a directory structure.
* I also don't like looking in multiple places to gather and view
* the data. Having only one file for ./devices also prevents race
* conditions that could arise if a program was reading device info
* for devices that are being removed (unplugged). (That is, the
* program may find a directory for devnum_12 then try to open it,
* but it was just unplugged, so the directory is now deleted.
* But programs would just have to be prepared for situations like
* this in any plug-and-play environment.)
*/
#define __KERNEL__ 1
#include <linux/types.h>
#include <asm/types.h>
#include <linux/kernel.h>
/* #include <linux/module.h> */
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/list.h>
#include "usb.h"
#define DUMP_LIMIT (PAGE_SIZE - 100)
/* limit to only one memory page of output */
#define MAX_TOPO_LEVEL 6
static
char
*
format_topo
=
/* T: Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd If#=ddd MxCh=dd Driver=%s */
"T: Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s If#=%3d MxCh=%2d Driver=%s
\n
"
;
static
char
*
format_device1
=
/* D: Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */
"D: Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d
\n
"
;
static
char
*
format_device2
=
/* P: Vendor=xxxx ProdID=xxxx Rev=xx.xx */
"P: Vendor=%04x ProdID=%04x Rev=%2x.%02x
\n
"
;
static
char
*
format_config
=
/* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */
"C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA
\n
"
;
static
char
*
format_iface
=
/* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx */
"I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x
\n
"
;
static
char
*
format_endpt
=
/* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddms */
"E: Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%3dms
\n
"
;
/*
* Need access to the driver and USB bus lists.
* extern struct list_head usb_driver_list;
* extern struct list_head usb_bus_list;
* However, these will come from functions that return ptrs to each of them.
*/
extern
struct
list_head
*
usb_driver_get_list
(
void
);
extern
struct
list_head
*
usb_bus_get_list
(
void
);
extern
struct
proc_dir_entry
*
proc_bus
;
static
struct
proc_dir_entry
*
usbdir
=
NULL
,
*
driversdir
=
NULL
;
static
struct
proc_dir_entry
*
devicesdir
=
NULL
;
struct
class_info
{
int
class
;
char
*
class_name
;
};
struct
class_info
clas_info
[]
=
{
/* max. 5 chars. per name string */
{
USB_CLASS_PER_INTERFACE
,
">ifc"
},
{
USB_CLASS_AUDIO
,
"audio"
},
{
USB_CLASS_COMM
,
"comm."
},
{
USB_CLASS_HID
,
"HID"
},
{
USB_CLASS_HUB
,
"hub"
},
{
USB_CLASS_PRINTER
,
"print"
},
{
USB_CLASS_MASS_STORAGE
,
"stor."
},
{
USB_CLASS_VENDOR_SPEC
,
"vend."
},
{
-
1
,
"unk."
}
/* leave as last */
};
/*****************************************************************/
static
char
*
class_decode
(
const
int
class
)
{
int
ix
;
for
(
ix
=
0
;
clas_info
[
ix
].
class
!=
-
1
;
ix
++
)
if
(
clas_info
[
ix
].
class
==
class
)
break
;
return
(
clas_info
[
ix
].
class_name
);
}
static
int
usb_dump_endpoint_descriptor
(
const
struct
usb_endpoint_descriptor
*
desc
,
char
*
buf
,
int
*
len
)
{
char
*
EndpointType
[
4
]
=
{
"Ctrl"
,
"Isoc"
,
"Bulk"
,
"Int."
};
*
len
+=
sprintf
(
buf
+
*
len
,
format_endpt
,
desc
->
bEndpointAddress
,
(
desc
->
bEndpointAddress
&
USB_DIR_IN
)
?
'I'
:
'O'
,
desc
->
bmAttributes
,
EndpointType
[
desc
->
bmAttributes
&
3
],
desc
->
wMaxPacketSize
,
desc
->
bInterval
);
return
(
*
len
>=
DUMP_LIMIT
)
?
-
1
:
0
;
}
static
int
usb_dump_endpoint
(
const
struct
usb_endpoint_descriptor
*
endpoint
,
char
*
buf
,
int
*
len
)
{
if
(
usb_dump_endpoint_descriptor
(
endpoint
,
buf
,
len
)
<
0
)
return
-
1
;
return
0
;
}
static
int
usb_dump_interface_descriptor
(
const
struct
usb_interface_descriptor
*
desc
,
char
*
buf
,
int
*
len
)
{
*
len
+=
sprintf
(
buf
+
*
len
,
format_iface
,
desc
->
bInterfaceNumber
,
desc
->
bAlternateSetting
,
desc
->
bNumEndpoints
,
desc
->
bInterfaceClass
,
class_decode
(
desc
->
bInterfaceClass
),
desc
->
bInterfaceSubClass
,
desc
->
bInterfaceProtocol
);
return
(
*
len
>=
DUMP_LIMIT
)
?
-
1
:
0
;
}
static
int
usb_dump_interface
(
const
struct
usb_interface_descriptor
*
interface
,
char
*
buf
,
int
*
len
)
{
int
i
;
if
(
usb_dump_interface_descriptor
(
interface
,
buf
,
len
)
<
0
)
return
-
1
;
for
(
i
=
0
;
i
<
interface
->
bNumEndpoints
;
i
++
)
{
if
(
usb_dump_endpoint
(
interface
->
endpoint
+
i
,
buf
,
len
)
<
0
)
return
-
1
;
}
return
0
;
}
/* TBD:
* 0. TBDs
* 1. marking active config and ifaces (code lists all, but should mark
* which ones are active, if any)
* 2. Add proc_usb_init() call from usb-core.c.
* 3. proc_usb as a MODULE ?
* 4. use __initfunc() ?
* 5. add <halted> status to each endpoint line
*/
static
int
usb_dump_config_descriptor
(
const
struct
usb_config_descriptor
*
desc
,
const
int
active
,
char
*
buf
,
int
*
len
)
{
*
len
+=
sprintf
(
buf
+
*
len
,
format_config
,
active
?
'*'
:
' '
,
/* mark active/actual/current cfg. */
desc
->
bNumInterfaces
,
desc
->
bConfigurationValue
,
desc
->
bmAttributes
,
desc
->
MaxPower
*
2
);
return
(
*
len
>=
DUMP_LIMIT
)
?
-
1
:
0
;
}
static
int
usb_dump_config
(
const
struct
usb_config_descriptor
*
config
,
const
int
active
,
char
*
buf
,
int
*
len
)
{
int
i
,
j
;
struct
usb_alternate_setting
*
as
;
if
(
!
config
)
{
/* getting these some in 2.3.7; none in 2.3.6 */
*
len
+=
sprintf
(
buf
+
*
len
,
"(null Cfg. desc.)
\n
"
);
return
0
;
}
if
(
usb_dump_config_descriptor
(
config
,
active
,
buf
,
len
)
<
0
)
return
-
1
;
for
(
i
=
0
;
i
<
config
->
num_altsetting
;
i
++
)
{
as
=
config
->
altsetting
+
i
;
if
((
as
)
==
NULL
)
break
;
for
(
j
=
0
;
j
<
config
->
bNumInterfaces
;
j
++
)
if
(
usb_dump_interface
(
as
->
interface
+
j
,
buf
,
len
)
<
0
)
return
-
1
;
}
return
0
;
}
/*
* Dump the different USB descriptors.
*/
static
int
usb_dump_device_descriptor
(
const
struct
usb_device_descriptor
*
desc
,
char
*
buf
,
int
*
len
)
{
*
len
+=
sprintf
(
buf
+
*
len
,
format_device1
,
desc
->
bcdUSB
>>
8
,
desc
->
bcdUSB
&
0xff
,
desc
->
bDeviceClass
,
class_decode
(
desc
->
bDeviceClass
),
desc
->
bDeviceSubClass
,
desc
->
bDeviceProtocol
,
desc
->
bMaxPacketSize0
,
desc
->
bNumConfigurations
);
if
(
*
len
>=
DUMP_LIMIT
)
return
-
1
;
*
len
+=
sprintf
(
buf
+
*
len
,
format_device2
,
desc
->
idVendor
,
desc
->
idProduct
,
desc
->
bcdDevice
>>
8
,
desc
->
bcdDevice
&
0xff
);
return
(
*
len
>=
DUMP_LIMIT
)
?
-
1
:
0
;
}
static
int
usb_dump_desc
(
const
struct
usb_device
*
dev
,
char
*
buf
,
int
*
len
)
{
int
i
;
if
(
usb_dump_device_descriptor
(
&
dev
->
descriptor
,
buf
,
len
)
<
0
)
return
-
1
;
for
(
i
=
0
;
i
<
dev
->
descriptor
.
bNumConfigurations
;
i
++
)
{
if
(
usb_dump_config
(
dev
->
config
+
i
,
(
dev
->
config
+
i
)
==
dev
->
actconfig
,
/* active ? */
buf
,
len
)
<
0
)
return
-
1
;
}
return
0
;
}
#ifdef PROC_EXTRA
/* TBD: may want to add this code later */
static
int
usb_dump_hub_descriptor
(
const
struct
usb_hub_descriptor
*
desc
,
char
*
buf
,
int
*
len
)
{
int
leng
=
USB_DT_HUB_NONVAR_SIZE
;
unsigned
char
*
ptr
=
(
unsigned
char
*
)
desc
;
*
len
+=
sprintf
(
buf
+
*
len
,
"Interface:"
);
while
(
leng
)
{
*
len
+=
sprintf
(
buf
+
*
len
,
" %02x"
,
*
ptr
);
ptr
++
;
leng
--
;
}
*
len
+=
sprintf
(
buf
+
*
len
,
"
\n
"
);
return
(
*
len
>=
DUMP_LIMIT
)
?
-
1
:
0
;
}
static
int
usb_dump_string
(
const
struct
usb_device
*
dev
,
char
*
id
,
int
index
,
char
*
buf
,
int
*
len
)
{
if
(
index
<=
dev
->
maxstring
&&
dev
->
stringindex
&&
dev
->
stringindex
[
index
])
*
len
+=
sprintf
(
buf
+
*
len
,
"%s: %s "
,
id
,
dev
->
stringindex
[
index
]);
return
(
*
len
>=
DUMP_LIMIT
)
?
-
1
:
0
;
}
#endif
/* PROC_EXTRA */
/*****************************************************************/
static
int
usb_device_dump
(
char
*
buf
,
int
*
len
,
const
struct
usb_device
*
usbdev
,
int
level
,
int
index
,
int
count
)
{
int
chix
;
int
cnt
=
0
;
int
parent_devnum
;
if
(
level
>
MAX_TOPO_LEVEL
)
return
-
1
;
parent_devnum
=
usbdev
->
parent
?
(
usbdev
->
parent
->
devnum
==
-
1
)
?
0
:
usbdev
->
parent
->
devnum
:
0
;
/*
* So the root hub's parent is 0 and any device that is
* plugged into the root hub has a parent of 0.
*/
*
len
+=
sprintf
(
buf
+
*
len
,
format_topo
,
level
,
parent_devnum
,
index
,
count
,
usbdev
->
devnum
,
usbdev
->
slow
?
"1.5"
:
"12 "
,
usbdev
->
ifnum
,
usbdev
->
maxchild
,
usbdev
->
driver
?
usbdev
->
driver
->
name
:
(
level
==
0
)
?
"(root hub)"
:
"(none)"
);
/*
* level = topology-tier level;
* parent_devnum = parent device number;
* index = parent's connector number;
* count = device count at this level
*/
if
(
*
len
>=
DUMP_LIMIT
)
return
-
1
;
if
(
usbdev
->
devnum
>
0
)
{
/* for any except root hub */
if
(
usb_dump_desc
(
usbdev
,
buf
,
len
)
<
0
)
return
-
1
;
}
/* Now look at all of this device's children. */
for
(
chix
=
0
;
chix
<
usbdev
->
maxchild
;
chix
++
)
{
if
(
usbdev
->
children
[
chix
])
{
if
(
usb_device_dump
(
buf
,
len
,
usbdev
->
children
[
chix
],
level
+
1
,
chix
,
++
cnt
)
<
0
)
return
-
1
;
}
}
return
0
;
}
static
int
usb_bus_list_dump
(
char
*
buf
,
int
len
)
{
struct
list_head
*
usb_bus_list
=
usb_bus_get_list
();
struct
list_head
*
list
=
usb_bus_list
->
next
;
len
=
0
;
/*
* Go thru each usb_bus. Within each usb_bus: each usb_device.
* Within each usb_device: all of its device & config. descriptors,
* marking the currently active ones.
*/
while
(
list
!=
usb_bus_list
)
{
struct
usb_bus
*
bus
=
list_entry
(
list
,
struct
usb_bus
,
bus_list
);
if
(
usb_device_dump
(
buf
,
&
len
,
bus
->
root_hub
,
0
,
0
,
0
)
<
0
)
break
;
list
=
list
->
next
;
if
(
len
>=
DUMP_LIMIT
)
{
len
+=
sprintf
(
buf
+
len
,
"(truncated)
\n
"
);
break
;
}
}
return
(
len
);
}
static
int
usb_bus_list_dump_devices
(
char
*
buf
,
char
**
start
,
off_t
offset
,
int
len
,
int
*
eof
,
void
*
data
)
{
return
usb_bus_list_dump
(
buf
,
len
);
}
/*
* Dump usb_driver_list.
*
* We now walk the list of registered USB drivers.
*/
static
int
usb_driver_list_dump
(
char
*
buf
,
char
**
start
,
off_t
offset
,
int
len
,
int
*
eof
,
void
*
data
)
{
struct
list_head
*
usb_driver_list
=
usb_driver_get_list
();
struct
list_head
*
tmp
=
usb_driver_list
->
next
;
int
cnt
=
0
;
len
=
0
;
while
(
tmp
!=
usb_driver_list
)
{
struct
usb_driver
*
driver
=
list_entry
(
tmp
,
struct
usb_driver
,
driver_list
);
len
+=
sprintf
(
buf
+
len
,
"%s
\n
"
,
driver
->
name
);
cnt
++
;
tmp
=
tmp
->
next
;
if
(
len
>=
DUMP_LIMIT
)
{
len
+=
sprintf
(
buf
+
len
,
"(truncated)
\n
"
);
return
(
len
);
}
}
if
(
!
cnt
)
len
+=
sprintf
(
buf
+
len
,
"(none)
\n
"
);
return
(
len
);
}
void
proc_usb_cleanup
(
void
)
{
if
(
driversdir
)
remove_proc_entry
(
"drivers"
,
usbdir
);
if
(
devicesdir
)
remove_proc_entry
(
"devices"
,
usbdir
);
if
(
usbdir
)
remove_proc_entry
(
"usb"
,
proc_bus
);
}
int
proc_usb_init
(
void
)
{
usbdir
=
create_proc_entry
(
"usb"
,
S_IFDIR
,
proc_bus
);
if
(
!
usbdir
)
{
printk
(
"proc_usb: cannot create /proc/bus/usb entry
\n
"
);
return
-
1
;
}
driversdir
=
create_proc_entry
(
"drivers"
,
0
,
usbdir
);
if
(
!
driversdir
)
{
printk
(
"proc_usb: cannot create /proc/bus/usb/drivers entry
\n
"
);
proc_usb_cleanup
();
return
-
1
;
}
driversdir
->
read_proc
=
usb_driver_list_dump
;
devicesdir
=
create_proc_entry
(
"devices"
,
0
,
usbdir
);
if
(
!
devicesdir
)
{
printk
(
"proc_usb: cannot create /proc/bus/usb/devices entry
\n
"
);
proc_usb_cleanup
();
return
-
1
;
}
devicesdir
->
read_proc
=
usb_bus_list_dump_devices
;
return
0
;
}
#ifdef PROCFS_MODULE
/* TBD: support proc_fs MODULE ??? */
int
init_module
(
void
)
{
return
proc_usb_init
();
}
void
cleanup_module
(
void
)
{
proc_usb_cleanup
();
}
#endif
/* PROCFS_MODULE */
/* end proc_usb.c */
drivers/usb/procusb
0 → 100644
View file @
86ae3b2a
#!/usr/bin/perl
# Reads /proc/bus/usb/devices and selectively lists and/or
# interprets it.
$DEVFILENAME
=
"
/proc/bus/usb/devices
";
$PROGNAME
=
$0
;
$TAGS
=
$ARGV
[
0
];
# save user TAGS
if
(
length
(
$TAGS
)
==
0
)
{
print
"
usage:
$PROGNAME
tags
\n
";
print
"
where 'tags' can be any number of 'TDPCIE' or 'A(LL)'
\n
";
exit
1
;
}
$ALL
=
(
$TAGS
=~
/all/i
)
||
(
$TAGS
=~
/a/i
);
# TBD: Check that $TAGS is valid.
if
(
!
$ALL
)
{
}
if
(
!
open
(
DEVNUM
,
"
<
$DEVFILENAME
"))
{
print
"
$PROGNAME
: cannot open '
$DEVFILENAME
'
\n
";
exit
1
;
}
while
(
$line
=
<
DEVNUM
>
)
# read a text line from DEVNUM
{
if
((
$ALL
)
||
(
$line
=~
/^[$TAGS]:/i
))
# any of TAGS at beg. of line?
{
print
"
$line
";
# still has newline char on it
# TBD: add more/paging functionality.
}
}
# end while DEVNUM
close
(
DEVNUM
);
# END.
drivers/usb/usb-core.c
View file @
86ae3b2a
...
...
@@ -28,6 +28,7 @@
# endif
#endif
int
usb_init
(
void
)
{
#ifndef CONFIG_USB_MODULE
...
...
@@ -64,6 +65,9 @@ int usb_init(void)
# ifdef CONFIG_USB_SCSI
usb_scsi_init
();
# endif
#endif
#ifdef CONFIG_USB_PROC
proc_usb_init
();
#endif
return
0
;
}
...
...
@@ -72,6 +76,9 @@ int usb_init(void)
*/
void
cleanup_drivers
(
void
)
{
#ifdef CONFIG_USB_PROC
proc_usb_cleanup
();
#endif
#ifndef MODULE
# ifdef CONFIG_USB_HUB
usb_hub_cleanup
();
...
...
drivers/usb/usb.c
View file @
86ae3b2a
...
...
@@ -36,6 +36,7 @@
* 6 wLength 2 Count Bytes for data
*/
#include <linux/config.h>
#include <linux/string.h>
#include <linux/bitops.h>
#include <linux/malloc.h>
...
...
@@ -1140,3 +1141,15 @@ int usb_release_irq(struct usb_device *dev, void* handle)
{
return
dev
->
bus
->
op
->
release_irq
(
handle
);
}
#ifdef CONFIG_PROC_FS
struct
list_head
*
usb_driver_get_list
(
void
)
{
return
&
usb_driver_list
;
}
struct
list_head
*
usb_bus_get_list
(
void
)
{
return
&
usb_bus_list
;
}
#endif
fs/proc/array.c
View file @
86ae3b2a
...
...
@@ -42,6 +42,8 @@
* Alan Cox : security fixes.
* <Alan.Cox@linux.org>
*
* Al Viro : safe handling of mm_struct
*
*/
#include <linux/types.h>
...
...
@@ -386,21 +388,15 @@ static int get_cmdline(char * buffer)
return
sprintf
(
buffer
,
"%s
\n
"
,
saved_command_line
);
}
static
unsigned
long
get_phys_addr
(
struct
task_struct
*
p
,
unsigned
long
ptr
)
static
unsigned
long
get_phys_addr
(
struct
mm_struct
*
mm
,
unsigned
long
ptr
)
{
pgd_t
*
page_dir
;
pmd_t
*
page_middle
;
pte_t
pte
;
if
(
!
p
||
!
p
->
mm
||
ptr
>=
TASK_SIZE
)
return
0
;
/* Check for NULL pgd .. shouldn't happen! */
if
(
!
p
->
mm
->
pgd
)
{
printk
(
"get_phys_addr: pid %d has NULL pgd!
\n
"
,
p
->
pid
);
if
(
ptr
>=
TASK_SIZE
)
return
0
;
}
page_dir
=
pgd_offset
(
p
->
mm
,
ptr
);
page_dir
=
pgd_offset
(
mm
,
ptr
);
if
(
pgd_none
(
*
page_dir
))
return
0
;
if
(
pgd_bad
(
*
page_dir
))
{
...
...
@@ -422,7 +418,7 @@ static unsigned long get_phys_addr(struct task_struct * p, unsigned long ptr)
return
pte_page
(
pte
)
+
(
ptr
&
~
PAGE_MASK
);
}
static
int
get_array
(
struct
task_struct
*
p
,
unsigned
long
start
,
unsigned
long
end
,
char
*
buffer
)
static
int
get_array
(
struct
mm_struct
*
mm
,
unsigned
long
start
,
unsigned
long
end
,
char
*
buffer
)
{
unsigned
long
addr
;
int
size
=
0
,
result
=
0
;
...
...
@@ -431,7 +427,7 @@ static int get_array(struct task_struct *p, unsigned long start, unsigned long e
if
(
start
>=
end
)
return
result
;
for
(;;)
{
addr
=
get_phys_addr
(
p
,
start
);
addr
=
get_phys_addr
(
mm
,
start
);
if
(
!
addr
)
return
result
;
do
{
...
...
@@ -451,29 +447,42 @@ static int get_array(struct task_struct *p, unsigned long start, unsigned long e
return
result
;
}
static
int
get_env
(
int
pid
,
char
*
buffer
)
static
struct
mm_struct
*
get_mm
(
int
pid
)
{
struct
task_struct
*
p
;
struct
mm_struct
*
mm
=
NULL
;
read_lock
(
&
tasklist_lock
);
p
=
find_task_by_pid
(
pid
);
read_unlock
(
&
tasklist_lock
);
/* FIXME!! This should be done after the last use */
if
(
p
)
mm
=
p
->
mm
;
if
(
mm
)
atomic_inc
(
&
mm
->
mm_users
);
read_unlock
(
&
tasklist_lock
);
return
mm
;
}
if
(
!
p
||
!
p
->
mm
)
return
0
;
return
get_array
(
p
,
p
->
mm
->
env_start
,
p
->
mm
->
env_end
,
buffer
);
static
int
get_env
(
int
pid
,
char
*
buffer
)
{
struct
mm_struct
*
mm
=
get_mm
(
pid
);
int
res
=
0
;
if
(
mm
)
{
res
=
get_array
(
mm
,
mm
->
env_start
,
mm
->
env_end
,
buffer
);
mmput
(
mm
);
}
return
res
;
}
static
int
get_arg
(
int
pid
,
char
*
buffer
)
{
struct
task_struct
*
p
;
read_lock
(
&
tasklist_lock
);
p
=
find_task_by_pid
(
pid
);
read_unlock
(
&
tasklist_lock
);
/* FIXME!! This should be done after the last use */
if
(
!
p
||
!
p
->
mm
)
return
0
;
return
get_array
(
p
,
p
->
mm
->
arg_start
,
p
->
mm
->
arg_end
,
buffer
);
struct
mm_struct
*
mm
=
get_mm
(
pid
);
int
res
=
0
;
if
(
mm
)
{
res
=
get_array
(
mm
,
mm
->
arg_start
,
mm
->
arg_end
,
buffer
);
mmput
(
mm
);
}
return
res
;
}
/*
...
...
@@ -740,48 +749,44 @@ static inline char * task_state(struct task_struct *p, char *buffer)
return
buffer
;
}
static
inline
char
*
task_mem
(
struct
task_struct
*
p
,
char
*
buffer
)
static
inline
char
*
task_mem
(
struct
mm_struct
*
mm
,
char
*
buffer
)
{
struct
mm_struct
*
mm
=
p
->
mm
;
if
(
mm
)
{
struct
vm_area_struct
*
vma
;
unsigned
long
data
=
0
,
stack
=
0
;
unsigned
long
exec
=
0
,
lib
=
0
;
down
(
&
mm
->
mmap_sem
);
for
(
vma
=
mm
->
mmap
;
vma
;
vma
=
vma
->
vm_next
)
{
unsigned
long
len
=
(
vma
->
vm_end
-
vma
->
vm_start
)
>>
10
;
if
(
!
vma
->
vm_file
)
{
data
+=
len
;
if
(
vma
->
vm_flags
&
VM_GROWSDOWN
)
stack
+=
len
;
continue
;
}
if
(
vma
->
vm_flags
&
VM_WRITE
)
struct
vm_area_struct
*
vma
;
unsigned
long
data
=
0
,
stack
=
0
;
unsigned
long
exec
=
0
,
lib
=
0
;
down
(
&
mm
->
mmap_sem
);
for
(
vma
=
mm
->
mmap
;
vma
;
vma
=
vma
->
vm_next
)
{
unsigned
long
len
=
(
vma
->
vm_end
-
vma
->
vm_start
)
>>
10
;
if
(
!
vma
->
vm_file
)
{
data
+=
len
;
if
(
vma
->
vm_flags
&
VM_GROWSDOWN
)
stack
+=
len
;
continue
;
}
if
(
vma
->
vm_flags
&
VM_WRITE
)
continue
;
if
(
vma
->
vm_flags
&
VM_EXEC
)
{
exec
+=
len
;
if
(
vma
->
vm_flags
&
VM_EXECUTABLE
)
continue
;
if
(
vma
->
vm_flags
&
VM_EXEC
)
{
exec
+=
len
;
if
(
vma
->
vm_flags
&
VM_EXECUTABLE
)
continue
;
lib
+=
len
;
}
lib
+=
len
;
}
buffer
+=
sprintf
(
buffer
,
"VmSize:
\t
%8lu kB
\n
"
"VmLck:
\t
%8lu kB
\n
"
"VmRSS:
\t
%8lu kB
\n
"
"VmData:
\t
%8lu kB
\n
"
"VmStk:
\t
%8lu kB
\n
"
"VmExe:
\t
%8lu kB
\n
"
"VmLib:
\t
%8lu kB
\n
"
,
mm
->
total_vm
<<
(
PAGE_SHIFT
-
10
),
mm
->
locked_vm
<<
(
PAGE_SHIFT
-
10
),
mm
->
rss
<<
(
PAGE_SHIFT
-
10
),
data
-
stack
,
stack
,
exec
-
lib
,
lib
);
up
(
&
mm
->
mmap_sem
);
}
buffer
+=
sprintf
(
buffer
,
"VmSize:
\t
%8lu kB
\n
"
"VmLck:
\t
%8lu kB
\n
"
"VmRSS:
\t
%8lu kB
\n
"
"VmData:
\t
%8lu kB
\n
"
"VmStk:
\t
%8lu kB
\n
"
"VmExe:
\t
%8lu kB
\n
"
"VmLib:
\t
%8lu kB
\n
"
,
mm
->
total_vm
<<
(
PAGE_SHIFT
-
10
),
mm
->
locked_vm
<<
(
PAGE_SHIFT
-
10
),
mm
->
rss
<<
(
PAGE_SHIFT
-
10
),
data
-
stack
,
stack
,
exec
-
lib
,
lib
);
up
(
&
mm
->
mmap_sem
);
return
buffer
;
}
...
...
@@ -842,44 +847,61 @@ static int get_status(int pid, char * buffer)
{
char
*
orig
=
buffer
;
struct
task_struct
*
tsk
;
struct
mm_struct
*
mm
=
NULL
;
read_lock
(
&
tasklist_lock
);
tsk
=
find_task_by_pid
(
pid
);
if
(
tsk
)
mm
=
tsk
->
mm
;
if
(
mm
)
atomic_inc
(
&
mm
->
mm_users
);
read_unlock
(
&
tasklist_lock
);
/* FIXME!! This should be done after the last use */
if
(
!
tsk
)
return
0
;
buffer
=
task_name
(
tsk
,
buffer
);
buffer
=
task_state
(
tsk
,
buffer
);
buffer
=
task_mem
(
tsk
,
buffer
);
if
(
mm
)
buffer
=
task_mem
(
mm
,
buffer
);
buffer
=
task_sig
(
tsk
,
buffer
);
buffer
=
task_cap
(
tsk
,
buffer
);
if
(
mm
)
mmput
(
mm
);
return
buffer
-
orig
;
}
static
int
get_stat
(
int
pid
,
char
*
buffer
)
{
struct
task_struct
*
tsk
;
struct
mm_struct
*
mm
=
NULL
;
unsigned
long
vsize
,
eip
,
esp
,
wchan
;
long
priority
,
nice
;
int
tty_pgrp
;
sigset_t
sigign
,
sigcatch
;
char
state
;
int
res
;
read_lock
(
&
tasklist_lock
);
tsk
=
find_task_by_pid
(
pid
);
if
(
tsk
)
mm
=
tsk
->
mm
;
if
(
mm
)
atomic_inc
(
&
mm
->
mm_users
);
read_unlock
(
&
tasklist_lock
);
/* FIXME!! This should be done after the last use */
if
(
!
tsk
)
return
0
;
state
=
*
get_task_state
(
tsk
);
vsize
=
eip
=
esp
=
0
;
if
(
tsk
->
mm
)
{
struct
vm_area_struct
*
vma
=
tsk
->
mm
->
mmap
;
if
(
mm
)
{
struct
vm_area_struct
*
vma
;
down
(
&
mm
->
mmap_sem
);
vma
=
mm
->
mmap
;
while
(
vma
)
{
vsize
+=
vma
->
vm_end
-
vma
->
vm_start
;
vma
=
vma
->
vm_next
;
}
eip
=
KSTK_EIP
(
tsk
);
esp
=
KSTK_ESP
(
tsk
);
up
(
&
mm
->
mmap_sem
);
}
wchan
=
get_wchan
(
tsk
);
...
...
@@ -898,7 +920,7 @@ static int get_stat(int pid, char * buffer)
nice
=
tsk
->
priority
;
nice
=
20
-
(
nice
*
20
+
DEF_PRIORITY
/
2
)
/
DEF_PRIORITY
;
re
turn
sprintf
(
buffer
,
"%d (%s) %c %d %d %d %d %d %lu %lu \
re
s
=
sprintf
(
buffer
,
"%d (%s) %c %d %d %d %d %d %lu %lu \
%lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \
%lu %lu %lu %lu %lu %lu %lu %lu %d %d
\n
"
,
pid
,
...
...
@@ -924,11 +946,11 @@ static int get_stat(int pid, char * buffer)
tsk
->
it_real_value
,
tsk
->
start_time
,
vsize
,
tsk
->
mm
?
tsk
->
mm
->
rss
:
0
,
/* you might want to shift this left 3 */
mm
?
mm
->
rss
:
0
,
/* you might want to shift this left 3 */
tsk
->
rlim
?
tsk
->
rlim
[
RLIMIT_RSS
].
rlim_cur
:
0
,
tsk
->
mm
?
tsk
->
mm
->
start_code
:
0
,
tsk
->
mm
?
tsk
->
mm
->
end_code
:
0
,
tsk
->
mm
?
tsk
->
mm
->
start_stack
:
0
,
mm
?
mm
->
start_code
:
0
,
mm
?
mm
->
end_code
:
0
,
mm
?
mm
->
start_stack
:
0
,
esp
,
eip
,
/* The signal information here is obsolete.
...
...
@@ -944,6 +966,9 @@ static int get_stat(int pid, char * buffer)
tsk
->
cnswap
,
tsk
->
exit_signal
,
tsk
->
processor
);
if
(
mm
)
mmput
(
mm
);
return
res
;
}
static
inline
void
statm_pte_range
(
pmd_t
*
pmd
,
unsigned
long
address
,
unsigned
long
size
,
...
...
@@ -1021,19 +1046,15 @@ static void statm_pgd_range(pgd_t * pgd, unsigned long address, unsigned long en
static
int
get_statm
(
int
pid
,
char
*
buffer
)
{
struct
task_struct
*
tsk
;
struct
mm_struct
*
mm
=
get_mm
(
pid
)
;
int
size
=
0
,
resident
=
0
,
share
=
0
,
trs
=
0
,
lrs
=
0
,
drs
=
0
,
dt
=
0
;
read_lock
(
&
tasklist_lock
);
tsk
=
find_task_by_pid
(
pid
);
read_unlock
(
&
tasklist_lock
);
/* FIXME!! This should be done after the last use */
if
(
!
tsk
)
return
0
;
if
(
tsk
->
mm
)
{
struct
vm_area_struct
*
vma
=
tsk
->
mm
->
mmap
;
if
(
mm
)
{
struct
vm_area_struct
*
vma
;
down
(
&
mm
->
mmap_sem
);
vma
=
mm
->
mmap
;
while
(
vma
)
{
pgd_t
*
pgd
=
pgd_offset
(
tsk
->
mm
,
vma
->
vm_start
);
pgd_t
*
pgd
=
pgd_offset
(
mm
,
vma
->
vm_start
);
int
pages
=
0
,
shared
=
0
,
dirty
=
0
,
total
=
0
;
statm_pgd_range
(
pgd
,
vma
->
vm_start
,
vma
->
vm_end
,
&
pages
,
&
shared
,
&
dirty
,
&
total
);
...
...
@@ -1051,6 +1072,8 @@ static int get_statm(int pid, char * buffer)
drs
+=
pages
;
vma
=
vma
->
vm_next
;
}
up
(
&
mm
->
mmap_sem
);
mmput
(
mm
);
}
return
sprintf
(
buffer
,
"%d %d %d %d %d %d %d
\n
"
,
size
,
resident
,
share
,
trs
,
lrs
,
drs
,
dt
);
...
...
fs/proc/link.c
View file @
86ae3b2a
...
...
@@ -82,63 +82,70 @@ static struct dentry * proc_follow_link(struct dentry *dentry,
ino
&=
0x0000ffff
;
result
=
ERR_PTR
(
-
ENOENT
);
read_lock
(
&
tasklist_lock
);
p
=
find_task_by_pid
(
pid
);
if
(
!
p
)
goto
out_unlock
;
switch
(
ino
)
{
case
PROC_PID_CWD
:
if
(
!
p
->
fs
||
!
p
->
fs
->
pwd
)
goto
out_unlock
;
result
=
p
->
fs
->
pwd
;
goto
out_dget
;
read_lock
(
&
tasklist_lock
);
p
=
find_task_by_pid
(
pid
);
if
(
p
&&
p
->
fs
&&
p
->
fs
->
pwd
)
result
=
dget
(
p
->
fs
->
pwd
);
read_unlock
(
&
tasklist_lock
);
break
;
case
PROC_PID_ROOT
:
if
(
!
p
->
fs
||
!
p
->
fs
->
root
)
goto
out_unlock
;
result
=
p
->
fs
->
root
;
goto
out_dget
;
read_lock
(
&
tasklist_lock
);
p
=
find_task_by_pid
(
pid
);
if
(
p
&&
p
->
fs
&&
p
->
fs
->
root
)
result
=
dget
(
p
->
fs
->
root
);
read_unlock
(
&
tasklist_lock
);
break
;
case
PROC_PID_EXE
:
{
struct
mm_struct
*
mm
=
NULL
;
struct
vm_area_struct
*
vma
;
if
(
!
p
->
mm
)
goto
out_unlock
;
down
(
&
p
->
mm
->
mmap_sem
);
vma
=
p
->
mm
->
mmap
;
read_lock
(
&
tasklist_lock
);
p
=
find_task_by_pid
(
pid
);
if
(
p
)
mm
=
p
->
mm
;
if
(
mm
)
atomic_inc
(
&
mm
->
mm_users
);
read_unlock
(
&
tasklist_lock
);
if
(
!
mm
)
break
;
down
(
&
mm
->
mmap_sem
);
vma
=
mm
->
mmap
;
while
(
vma
)
{
if
((
vma
->
vm_flags
&
VM_EXECUTABLE
)
&&
vma
->
vm_file
)
{
result
=
vma
->
vm_file
->
f_dentry
;
up
(
&
p
->
mm
->
mmap_sem
);
goto
out_dget
;
result
=
dget
(
vma
->
vm_file
->
f_dentry
);
break
;
}
vma
=
vma
->
vm_next
;
}
up
(
&
p
->
mm
->
mmap_sem
);
goto
out_unlock
;
up
(
&
mm
->
mmap_sem
);
mmput
(
mm
);
break
;
}
default:
if
(
ino
&
PROC_PID_FD_DIR
)
{
struct
file
*
file
;
struct
files_struct
*
files
=
NULL
;
read_lock
(
&
tasklist_lock
);
p
=
find_task_by_pid
(
pid
);
if
(
p
)
files
=
p
->
files
;
read_unlock
(
&
tasklist_lock
);
if
(
!
files
)
break
;
ino
&=
0x7fff
;
if
(
!
p
->
files
)
/* shouldn't happen here */
goto
out_unlock
;
read_lock
(
&
p
->
files
->
file_lock
);
file
=
fcheck_task
(
p
,
ino
);
if
(
!
file
||
!
file
->
f_dentry
)
goto
out_unlock
;
result
=
file
->
f_dentry
;
read_lock
(
&
files
->
file_lock
);
/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
if
(
ino
<
files
->
max_fds
&&
(
file
=
files
->
fd
[
ino
])
&&
file
->
f_dentry
)
result
=
dget
(
file
->
f_dentry
);
read_unlock
(
&
p
->
files
->
file_lock
);
goto
out_dget
;
}
}
out_dget:
result
=
dget
(
result
);
out_unlock:
read_unlock
(
&
tasklist_lock
);
out:
return
result
;
}
...
...
include/asm-alpha/siginfo.h
View file @
86ae3b2a
...
...
@@ -67,8 +67,6 @@ typedef struct siginfo {
*/
#define si_pid _sifields._kill._pid
#define si_uid _sifields._kill._uid
#define si_timer1 _sifields._timer._timer1
#define si_timer2 _sifields._timer._timer2
#define si_status _sifields._sigchld._status
#define si_utime _sifields._sigchld._utime
#define si_stime _sifields._sigchld._stime
...
...
include/asm-alpha/unistd.h
View file @
86ae3b2a
...
...
@@ -308,14 +308,6 @@
#define __NR_capget 368
#define __NR_capset 369
#define __NR_sendfile 370
#define __NR_timer_create 371
#define __NR_timer_settime 372
#define __NR_timer_gettime 373
#define __NR_timer_getoverrun 374
#define __NR_timer_delete 375
#define __NR_clock_gettime 376
#define __NR_clock_settime 377
#define __NR_clock_getres 378
#if defined(__LIBRARY__) && defined(__GNUC__)
...
...
include/asm-arm/siginfo.h
View file @
86ae3b2a
...
...
@@ -67,8 +67,6 @@ typedef struct siginfo {
*/
#define si_pid _sifields._kill._pid
#define si_uid _sifields._kill._uid
#define si_timer1 _sifields._timer._timer1
#define si_timer2 _sifields._timer._timer2
#define si_status _sifields._sigchld._status
#define si_utime _sifields._sigchld._utime
#define si_stime _sifields._sigchld._stime
...
...
include/asm-arm/unistd.h
View file @
86ae3b2a
...
...
@@ -198,14 +198,6 @@
/* 188 reserved */
/* 189 reserved */
#define __NR_vfork (__NR_SYSCALL_BASE+190)
#define __NR_timer_create (__NR_SYSCALL_BASE+191)
#define __NR_timer_settime (__NR_SYSCALL_BASE+192)
#define __NR_timer_gettime (__NR_SYSCALL_BASE+193)
#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+194)
#define __NR_timer_delete (__NR_SYSCALL_BASE+195)
#define __NR_clock_gettime (__NR_SYSCALL_BASE+196)
#define __NR_clock_settime (__NR_SYSCALL_BASE+197)
#define __NR_clock_getres (__NR_SYSCALL_BASE+198)
#define __sys2(x) #x
#define __sys1(x) __sys2(x)
...
...
include/asm-i386/mmu_context.h
View file @
86ae3b2a
...
...
@@ -2,6 +2,7 @@
#define __I386_MMU_CONTEXT_H
#include <asm/desc.h>
#include <asm/atomic.h>
/*
* possibly do the LDT unload here?
...
...
@@ -11,20 +12,19 @@
static
inline
void
switch_mm
(
struct
mm_struct
*
prev
,
struct
mm_struct
*
next
,
unsigned
cpu
)
{
unsigned
long
vm_mask
;
/*
* Re-load LDT if necessary
*/
if
(
prev
->
segments
!=
next
->
segments
)
load_LDT
(
next
);
if
(
prev
!=
next
)
{
/*
* Re-load LDT if necessary
*/
if
(
prev
->
segments
!=
next
->
segments
)
load_LDT
(
next
);
/* Re-load page tables */
asm
volatile
(
"movl %0,%%cr3"
:
:
"r"
(
__pa
(
next
->
pgd
)));
vm_mask
=
1UL
<<
cpu
;
next
->
cpu_vm_mask
|=
vm_mask
;
prev
->
cpu_vm_mask
&=
~
vm_mask
;
/* Re-load page tables */
asm
volatile
(
"movl %0,%%cr3"
:
:
"r"
(
__pa
(
next
->
pgd
)));
clear_bit
(
cpu
,
&
prev
->
cpu_vm_mask
);
}
set_bit
(
cpu
,
&
next
->
cpu_vm_mask
);
}
#endif
include/asm-i386/siginfo.h
View file @
86ae3b2a
...
...
@@ -31,14 +31,13 @@ typedef struct siginfo {
struct
{
unsigned
int
_timer1
;
unsigned
int
_timer2
;
sigval_t
_sigval2
;
/* FIXME: must map to _sigval below because it is the same */
}
_timer
;
/* POSIX.1b signals */
struct
{
pid_t
_pid
;
/* sender's pid */
uid_t
_uid
;
/* sender's uid */
sigval_t
_sigval
;
/* FIXME: move out of union together with _sigval2 */
sigval_t
_sigval
;
}
_rt
;
/* SIGCHLD */
...
...
@@ -68,8 +67,6 @@ typedef struct siginfo {
*/
#define si_pid _sifields._kill._pid
#define si_uid _sifields._kill._uid
#define si_timer1 _sifields._timer._timer1
#define si_timer2 _sifields._timer._timer2
#define si_status _sifields._sigchld._status
#define si_utime _sifields._sigchld._utime
#define si_stime _sifields._sigchld._stime
...
...
include/asm-i386/unistd.h
View file @
86ae3b2a
...
...
@@ -195,14 +195,6 @@
#define __NR_getpmsg 188
/* some people actually want streams */
#define __NR_putpmsg 189
/* some people actually want streams */
#define __NR_vfork 190
#define __NR_timer_create 191
#define __NR_timer_settime 192
#define __NR_timer_gettime 193
#define __NR_timer_getoverrun 194
#define __NR_timer_delete 195
#define __NR_clock_gettime 196
#define __NR_clock_settime 197
#define __NR_clock_getres 198
/* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
...
...
include/asm-m68k/siginfo.h
View file @
86ae3b2a
...
...
@@ -67,8 +67,6 @@ typedef struct siginfo {
*/
#define si_pid _sifields._kill._pid
#define si_uid _sifields._kill._uid
#define si_timer1 _sifields._timer._timer1
#define si_timer2 _sifields._timer._timer2
#define si_status _sifields._sigchld._status
#define si_utime _sifields._sigchld._utime
#define si_stime _sifields._sigchld._stime
...
...
include/asm-m68k/unistd.h
View file @
86ae3b2a
...
...
@@ -194,14 +194,6 @@
#define __NR_getpmsg 188
/* some people actually want streams */
#define __NR_putpmsg 189
/* some people actually want streams */
#define __NR_vfork 190
#define __NR_timer_create 191
#define __NR_timer_settime 192
#define __NR_timer_gettime 193
#define __NR_timer_getoverrun 194
#define __NR_timer_delete 195
#define __NR_clock_gettime 196
#define __NR_clock_settime 197
#define __NR_clock_getres 198
/* user-visible error numbers are in the range -1 - -122: see
<asm-m68k/errno.h> */
...
...
include/asm-mips/siginfo.h
View file @
86ae3b2a
...
...
@@ -75,8 +75,6 @@ typedef struct siginfo {
*/
#define si_pid _sifields._kill._pid
#define si_uid _sifields._kill._uid
#define si_timer1 _sifields._timer._timer1
#define si_timer2 _sifields._timer._timer2
#define si_status _sifields._sigchld._status
#define si_utime _sifields._sigchld._utime
#define si_stime _sifields._sigchld._stime
...
...
include/asm-mips/unistd.h
View file @
86ae3b2a
...
...
@@ -1196,14 +1196,6 @@
#define __NR_sendfile (__NR_Linux + 207)
#define __NR_getpmsg (__NR_Linux + 208)
#define __NR_putpmsg (__NR_Linux + 209)
#define __NR_timer_create (__NR_Linux + 210)
#define __NR_timer_settime (__NR_Linux + 211)
#define __NR_timer_gettime (__NR_Linux + 212)
#define __NR_timer_getoverrun (__NR_Linux + 213)
#define __NR_timer_delete (__NR_Linux + 214)
#define __NR_clock_gettime (__NR_Linux + 215)
#define __NR_clock_settime (__NR_Linux + 216)
#define __NR_clock_getres (__NR_Linux + 217)
/*
* Offset of the last Linux flavoured syscall
...
...
include/asm-ppc/siginfo.h
View file @
86ae3b2a
...
...
@@ -67,8 +67,6 @@ typedef struct siginfo {
*/
#define si_pid _sifields._kill._pid
#define si_uid _sifields._kill._uid
#define si_timer1 _sifields._timer._timer1
#define si_timer2 _sifields._timer._timer2
#define si_status _sifields._sigchld._status
#define si_utime _sifields._sigchld._utime
#define si_stime _sifields._sigchld._stime
...
...
@@ -124,7 +122,7 @@ typedef struct siginfo {
* SIGSEGV si_codes
*/
#define SEGV_MAPERR 1
/* address not mapped to object */
#define S
E
GV_ACCERR 2
/* invalid permissions for mapped object */
#define S
R
GV_ACCERR 2
/* invalid permissions for mapped object */
#define NSIGSEGV 2
/*
...
...
include/asm-ppc/unistd.h
View file @
86ae3b2a
...
...
@@ -194,14 +194,6 @@
#define __NR_getpmsg 187
/* some people actually want streams */
#define __NR_putpmsg 188
/* some people actually want streams */
#define __NR_vfork 189
#define __NR_timer_create 190
#define __NR_timer_settime 191
#define __NR_timer_gettime 192
#define __NR_timer_getoverrun 193
#define __NR_timer_delete 194
#define __NR_clock_gettime 195
#define __NR_clock_settime 196
#define __NR_clock_getres 197
#define __NR(n) #n
...
...
include/asm-sparc/siginfo.h
View file @
86ae3b2a
...
...
@@ -70,8 +70,6 @@ typedef struct siginfo {
*/
#define si_pid _sifields._kill._pid
#define si_uid _sifields._kill._uid
#define si_timer1 _sifields._timer._timer1
#define si_timer2 _sifields._timer._timer2
#define si_status _sifields._sigchld._status
#define si_utime _sifields._sigchld._utime
#define si_stime _sifields._sigchld._stime
...
...
@@ -128,7 +126,7 @@ typedef struct siginfo {
* SIGSEGV si_codes
*/
#define SEGV_MAPERR 1
/* address not mapped to object */
#define S
E
GV_ACCERR 2
/* invalid permissions for mapped object */
#define S
R
GV_ACCERR 2
/* invalid permissions for mapped object */
#define NSIGSEGV 2
/*
...
...
include/asm-sparc/unistd.h
View file @
86ae3b2a
...
...
@@ -271,14 +271,6 @@
#define __NR_fdatasync 253
#define __NR_nfsservctl 254
#define __NR_aplib 255
#define __NR_timer_create 256
#define __NR_timer_settime 257
#define __NR_timer_gettime 258
#define __NR_timer_getoverrun 259
#define __NR_timer_delete 260
#define __NR_clock_gettime 261
#define __NR_clock_settime 262
#define __NR_clock_getres 263
#define _syscall0(type,name) \
type name(void) \
...
...
include/asm-sparc64/siginfo.h
View file @
86ae3b2a
...
...
@@ -129,8 +129,6 @@ typedef struct siginfo32 {
*/
#define si_pid _sifields._kill._pid
#define si_uid _sifields._kill._uid
#define si_timer1 _sifields._timer._timer1
#define si_timer2 _sifields._timer._timer2
#define si_status _sifields._sigchld._status
#define si_utime _sifields._sigchld._utime
#define si_stime _sifields._sigchld._stime
...
...
@@ -187,7 +185,7 @@ typedef struct siginfo32 {
* SIGSEGV si_codes
*/
#define SEGV_MAPERR 1
/* address not mapped to object */
#define S
E
GV_ACCERR 2
/* invalid permissions for mapped object */
#define S
R
GV_ACCERR 2
/* invalid permissions for mapped object */
#define NSIGSEGV 2
/*
...
...
include/asm-sparc64/unistd.h
View file @
86ae3b2a
...
...
@@ -271,14 +271,6 @@
#define __NR_fdatasync 253
#define __NR_nfsservctl 254
#define __NR_aplib 255
#define __NR_timer_create 256
#define __NR_timer_settime 257
#define __NR_timer_gettime 258
#define __NR_timer_getoverrun 259
#define __NR_timer_delete 260
#define __NR_clock_gettime 261
#define __NR_clock_settime 262
#define __NR_clock_getres 263
#define _syscall0(type,name) \
type name(void) \
...
...
include/linux/limits.h
View file @
86ae3b2a
...
...
@@ -14,8 +14,6 @@
#define PATH_MAX 4095
/* # chars in a path name */
#define PIPE_BUF 4096
/* # bytes in atomic write to a pipe */
#define MAX_ITIMERS 32
/* # POSIX.1b itimers per process */
#define RTSIG_MAX 32
#endif
include/linux/sched.h
View file @
86ae3b2a
...
...
@@ -35,7 +35,6 @@ extern unsigned long event;
#define CLONE_PID 0x00001000
/* set if pid shared */
#define CLONE_PTRACE 0x00002000
/* set if we want to let tracing continue on the child too */
#define CLONE_VFORK 0x00004000
/* set if the parent wants the child to wake it up on mm_release */
#define CLONE_ITIMERS 0x00008000
/* set if POSIX.1b itimers are shared */
/*
* These are the constant used to fake the fixed-point load-average
...
...
@@ -240,26 +239,6 @@ struct signal_struct {
*/
struct
user_struct
;
/* POSIX.1b interval timer structure. */
struct
k_itimer
{
spinlock_t
it_lock
;
clockid_t
it_clock
;
/* which timer type */
timer_t
it_id
;
/* timer id */
int
it_overrun
;
/* number of signals overrun */
struct
sigevent
it_signal
;
/* signal to be delivered */
struct
timespec
it_interval
;
/* interval (rounded to jiffies) */
int
it_incr
;
/* interval specified in jiffies */
struct
task_struct
*
it_process
;
/* process to send signal to */
struct
timer_list
it_timer
;
};
/* Structure to maintain the dynamically created POSIX.1b interval timers. */
struct
itimer_struct
{
atomic_t
count
;
spinlock_t
its_lock
;
struct
k_itimer
*
itimer
[
MAX_ITIMERS
];
};
struct
task_struct
{
/* these are hardcoded - don't touch */
volatile
long
state
;
/* -1 unrunnable, 0 runnable, >0 stopped */
...
...
@@ -315,7 +294,6 @@ struct task_struct {
unsigned
long
it_real_value
,
it_prof_value
,
it_virt_value
;
unsigned
long
it_real_incr
,
it_prof_incr
,
it_virt_incr
;
struct
timer_list
real_timer
;
struct
itimer_struct
*
posix_timers
;
/* POSIX.1b Interval Timers */
struct
tms
times
;
unsigned
long
start_time
;
long
per_cpu_utime
[
NR_CPUS
],
per_cpu_stime
[
NR_CPUS
];
...
...
@@ -353,7 +331,6 @@ struct task_struct {
spinlock_t
sigmask_lock
;
/* Protects signal and blocked */
struct
signal_struct
*
sig
;
sigset_t
signal
,
blocked
;
siginfo_t
nrt_info
[
SIGRTMIN
];
/* siginfo for non RT signals */
struct
signal_queue
*
sigqueue
,
**
sigqueue_tail
;
unsigned
long
sas_ss_sp
;
size_t
sas_ss_size
;
...
...
@@ -403,7 +380,6 @@ struct task_struct {
/* chld wait */
__WAIT_QUEUE_HEAD_INITIALIZER(name.wait_chldexit), NULL, \
/* timeout */
SCHED_OTHER,0,0,0,0,0,0,0, \
/* timer */
{ NULL, NULL, 0, 0, it_real_fn }, \
/* POSIX.1b timer */
NULL, \
/* utime */
{0,0,0,0},0, \
/* per CPU times */
{0, }, {0, }, \
/* flt */
0,0,0,0,0,0, \
...
...
@@ -422,7 +398,7 @@ struct task_struct {
/* fs */
&init_fs, \
/* files */
&init_files, \
/* mm */
NULL, &init_mm, \
/* signals */
SPIN_LOCK_UNLOCKED, &init_signals, {{0}}, {{0}},
{{0,},},
NULL, &init_task.sigqueue, 0, 0, \
/* signals */
SPIN_LOCK_UNLOCKED, &init_signals, {{0}}, {{0}}, NULL, &init_task.sigqueue, 0, 0, \
}
#ifndef INIT_TASK_SIZE
...
...
@@ -699,7 +675,6 @@ extern void exit_mm(struct task_struct *);
extern
void
exit_fs
(
struct
task_struct
*
);
extern
void
exit_files
(
struct
task_struct
*
);
extern
void
exit_sighand
(
struct
task_struct
*
);
extern
void
exit_itimers
(
struct
task_struct
*
);
extern
int
do_execve
(
char
*
,
char
**
,
char
**
,
struct
pt_regs
*
);
extern
int
do_fork
(
unsigned
long
,
unsigned
long
,
struct
pt_regs
*
);
...
...
include/linux/time.h
View file @
86ae3b2a
...
...
@@ -26,19 +26,6 @@ struct timespec {
*/
#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
/* Parameters used to convert the timespec values */
#ifndef USEC_PER_SEC
#define USEC_PER_SEC (1000000L)
#endif
#ifndef NSEC_PER_SEC
#define NSEC_PER_SEC (1000000000L)
#endif
#ifndef NSEC_PER_USEC
#define NSEC_PER_USEC (1000L)
#endif
static
__inline__
unsigned
long
timespec_to_jiffies
(
struct
timespec
*
value
)
{
...
...
@@ -47,15 +34,15 @@ timespec_to_jiffies(struct timespec *value)
if
(
sec
>=
(
MAX_JIFFY_OFFSET
/
HZ
))
return
MAX_JIFFY_OFFSET
;
nsec
+=
NSEC_PER_SEC
/
HZ
-
1
;
nsec
/=
NSEC_PER_SEC
/
HZ
;
nsec
+=
1000000000L
/
HZ
-
1
;
nsec
/=
1000000000L
/
HZ
;
return
HZ
*
sec
+
nsec
;
}
static
__inline__
void
jiffies_to_timespec
(
unsigned
long
jiffies
,
struct
timespec
*
value
)
{
value
->
tv_nsec
=
(
jiffies
%
HZ
)
*
(
NSEC_PER_SEC
/
HZ
);
value
->
tv_nsec
=
(
jiffies
%
HZ
)
*
(
1000000000L
/
HZ
);
value
->
tv_sec
=
jiffies
/
HZ
;
}
...
...
@@ -102,23 +89,4 @@ struct itimerval {
struct
timeval
it_value
;
/* current value */
};
/*
* Data types for POSIX.1b interval timers.
*/
typedef
int
clockid_t
;
typedef
int
timer_t
;
/*
* The IDs of the various system clocks (for POSIX.1b interval timers).
*/
#define CLOCK_REALTIME 0
/*
* The various flags for setting POSIX.1b interval timers.
*/
#define TIMER_ABSTIME 0x01
#endif
kernel/exit.c
View file @
86ae3b2a
...
...
@@ -235,34 +235,6 @@ void exit_sighand(struct task_struct *tsk)
__exit_sighand
(
tsk
);
}
static
inline
void
__exit_itimers
(
struct
task_struct
*
tsk
)
{
struct
itimer_struct
*
timers
=
tsk
->
posix_timers
;
struct
k_itimer
*
timr
;
int
i
;
if
(
timers
==
NULL
)
return
;
if
(
atomic_dec_and_test
(
&
timers
->
count
))
{
tsk
->
posix_timers
=
NULL
;
for
(
i
=
0
;
i
<
MAX_ITIMERS
;
i
++
)
{
timr
=
timers
->
itimer
[
i
];
if
(
timr
)
{
start_bh_atomic
();
del_timer
(
&
timr
->
it_timer
);
end_bh_atomic
();
kfree
(
timr
);
}
}
kfree
(
timers
);
}
}
void
exit_itimers
(
struct
task_struct
*
tsk
)
{
__exit_itimers
(
tsk
);
}
/*
* We can use these to temporarily drop into
* "lazy TLB" mode and back.
...
...
@@ -412,7 +384,6 @@ NORET_TYPE void do_exit(long code)
__exit_files
(
tsk
);
__exit_fs
(
tsk
);
__exit_sighand
(
tsk
);
__exit_itimers
(
tsk
);
exit_thread
();
tsk
->
state
=
TASK_ZOMBIE
;
tsk
->
exit_code
=
code
;
...
...
kernel/fork.c
View file @
86ae3b2a
...
...
@@ -580,24 +580,6 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
p
->
flags
=
new_flags
;
}
static
inline
int
copy_itimers
(
unsigned
long
clone_flags
,
struct
task_struct
*
tsk
)
{
if
(
clone_flags
&
CLONE_ITIMERS
)
{
atomic_inc
(
&
tsk
->
posix_timers
->
count
);
return
0
;
}
tsk
->
posix_timers
=
kmalloc
(
sizeof
(
*
tsk
->
posix_timers
),
GFP_KERNEL
);
if
(
tsk
->
posix_timers
==
NULL
)
return
-
1
;
spin_lock_init
(
&
tsk
->
posix_timers
->
its_lock
);
atomic_set
(
&
tsk
->
posix_timers
->
count
,
1
);
memset
(
tsk
->
posix_timers
->
itimer
,
0
,
sizeof
(
tsk
->
posix_timers
->
itimer
));
return
0
;
}
/*
* Ok, this is the main fork-routine. It copies the system process
* information (task[nr]) and sets up the necessary registers. It
...
...
@@ -696,8 +678,6 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
goto
bad_fork_cleanup_files
;
if
(
copy_sighand
(
clone_flags
,
p
))
goto
bad_fork_cleanup_fs
;
if
(
copy_itimers
(
clone_flags
,
p
))
goto
bad_fork_cleanup_itimers
;
if
(
copy_mm
(
clone_flags
,
p
))
goto
bad_fork_cleanup_sighand
;
retval
=
copy_thread
(
0
,
clone_flags
,
usp
,
p
,
regs
);
...
...
@@ -742,8 +722,6 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
down
(
&
sem
);
return
retval
;
bad_fork_cleanup_itimers:
exit_itimers
(
p
);
bad_fork_cleanup_sighand:
exit_sighand
(
p
);
bad_fork_cleanup_fs:
...
...
kernel/itimer.c
View file @
86ae3b2a
...
...
@@ -9,16 +9,14 @@
#include <linux/mm.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/malloc.h>
#include <linux/time.h>
#include <asm/uaccess.h>
/*
* change timeval to jiffies, trying to avoid the
* change timeval to jiffies, trying to avoid the
* most obvious overflows..
*
* The tv_*sec values are signed, but nothing seems to
* The tv_*sec values are signed, but nothing seems to
* indicate whether we really should use them as signed values
* when doing itimers. POSIX doesn't mention this (but if
* alarm() uses itimers without checking, we have to use unsigned
...
...
@@ -170,389 +168,6 @@ asmlinkage int sys_setitimer(int which, struct itimerval *value,
return
error
;
if
(
copy_to_user
(
ovalue
,
&
get_buffer
,
sizeof
(
get_buffer
)))
return
-
EFAULT
;
return
0
;
}
/* PRECONDITION:
* timr->it_lock must be locked
*/
static
void
timer_notify_task
(
struct
k_itimer
*
timr
)
{
struct
siginfo
info
;
int
ret
;
if
(
timr
->
it_signal
.
sigev_notify
==
SIGEV_SIGNAL
)
{
/* Send signal to the process that owns this timer. */
info
.
si_signo
=
timr
->
it_signal
.
sigev_signo
;
info
.
si_errno
=
0
;
info
.
si_code
=
SI_TIMER
;
/* TODO: if someone has better ideas what to put in
* the next two fields...
* si_timer1 is currently used in signal.c to check
* whether a signal from this timer is already in the signal
* queue.
*/
info
.
si_timer1
=
timr
->
it_id
;
info
.
si_timer2
=
0
;
info
.
si_value
=
timr
->
it_signal
.
sigev_value
;
ret
=
send_sig_info
(
info
.
si_signo
,
&
info
,
timr
->
it_process
);
switch
(
ret
)
{
case
0
:
/* all's well */
timr
->
it_overrun
=
0
;
break
;
case
1
:
/* signal from this timer was already in the queue */
timr
->
it_overrun
++
;
break
;
default:
printk
(
KERN_WARNING
"sending signal failed: %d
\n
"
,
ret
);
break
;
}
}
}
/* This function gets called when a POSIX.1b interval timer expires. */
static
void
posix_timer_fn
(
unsigned
long
__data
)
{
struct
k_itimer
*
timr
=
(
struct
k_itimer
*
)
__data
;
unsigned
long
interval
;
spin_lock
(
&
timr
->
it_lock
);
timer_notify_task
(
timr
);
/* Set up the timer for the next interval (if there is one) */
if
((
interval
=
timr
->
it_incr
)
==
0
)
goto
out
;
if
(
interval
>
(
unsigned
long
)
LONG_MAX
)
interval
=
LONG_MAX
;
timr
->
it_timer
.
expires
=
jiffies
+
interval
;
add_timer
(
&
timr
->
it_timer
);
out:
spin_unlock
(
&
timr
->
it_lock
);
}
/* Find the first available slot for the new timer. */
static
int
timer_find_slot
(
struct
itimer_struct
*
timers
)
{
int
i
;
for
(
i
=
0
;
i
<
MAX_ITIMERS
;
i
++
)
{
if
(
timers
->
itimer
[
i
]
==
NULL
)
return
i
;
}
return
-
1
;
}
static
int
good_sigevent
(
const
struct
sigevent
*
sigev
)
{
switch
(
sigev
->
sigev_notify
)
{
case
SIGEV_NONE
:
break
;
case
SIGEV_SIGNAL
:
if
((
sigev
->
sigev_signo
<=
0
)
||
(
sigev
->
sigev_signo
>
SIGRTMAX
))
return
0
;
break
;
default:
return
0
;
}
return
1
;
}
/* Create a POSIX.1b interval timer. */
asmlinkage
int
sys_timer_create
(
clockid_t
which_clock
,
struct
sigevent
*
timer_event_spec
,
timer_t
*
created_timer_id
)
{
int
error
=
0
;
struct
k_itimer
*
new_timer
=
NULL
;
struct
itimer_struct
*
timers
=
current
->
posix_timers
;
int
new_timer_id
;
/* Right now, we only support CLOCK_REALTIME for timers. */
if
(
which_clock
!=
CLOCK_REALTIME
)
return
-
EINVAL
;
new_timer
=
(
struct
k_itimer
*
)
kmalloc
(
sizeof
(
*
new_timer
),
GFP_KERNEL
);
if
(
new_timer
==
NULL
)
return
-
EAGAIN
;
spin_lock_init
(
&
new_timer
->
it_lock
);
new_timer
->
it_clock
=
which_clock
;
new_timer
->
it_incr
=
0
;
new_timer
->
it_overrun
=
0
;
if
(
timer_event_spec
)
{
if
(
copy_from_user
(
&
new_timer
->
it_signal
,
timer_event_spec
,
sizeof
(
new_timer
->
it_signal
)))
{
error
=
-
EFAULT
;
goto
out
;
}
if
(
!
good_sigevent
(
&
new_timer
->
it_signal
))
{
error
=
-
EINVAL
;
goto
out
;
}
}
else
{
new_timer
->
it_signal
.
sigev_notify
=
SIGEV_SIGNAL
;
new_timer
->
it_signal
.
sigev_signo
=
SIGALRM
;
}
new_timer
->
it_interval
.
tv_sec
=
0
;
new_timer
->
it_interval
.
tv_nsec
=
0
;
new_timer
->
it_process
=
current
;
new_timer
->
it_timer
.
next
=
NULL
;
new_timer
->
it_timer
.
prev
=
NULL
;
new_timer
->
it_timer
.
expires
=
0
;
new_timer
->
it_timer
.
data
=
(
unsigned
long
)
new_timer
;
new_timer
->
it_timer
.
function
=
posix_timer_fn
;
spin_lock
(
&
timers
->
its_lock
);
new_timer_id
=
timer_find_slot
(
timers
);
if
(
new_timer_id
==
-
1
)
{
error
=
-
EAGAIN
;
goto
out
;
}
new_timer
->
it_id
=
new_timer_id
;
timers
->
itimer
[
new_timer_id
]
=
new_timer
;
if
(
timer_event_spec
==
NULL
)
{
new_timer
->
it_signal
.
sigev_value
.
sival_int
=
new_timer_id
;
}
if
(
copy_to_user
(
created_timer_id
,
&
new_timer_id
,
sizeof
(
new_timer_id
)))
{
error
=
-
EFAULT
;
timers
->
itimer
[
new_timer_id
]
=
NULL
;
}
spin_unlock
(
&
timers
->
its_lock
);
out:
if
(
error
)
{
kfree
(
new_timer
);
}
return
error
;
}
/* good_timespec
*
* This function checks the elements of a timespec structure.
*
* Arguments:
* ts : Pointer to the timespec structure to check
*
* Return value:
* If a NULL pointer was passed in, or the tv_nsec field was less than 0 or
* greater than NSEC_PER_SEC, or the tv_sec field was less than 0, this
* function returns 0. Otherwise it returns 1.
*/
static
int
good_timespec
(
const
struct
timespec
*
ts
)
{
if
(
ts
==
NULL
)
return
0
;
if
(
ts
->
tv_sec
<
0
)
return
0
;
if
((
ts
->
tv_nsec
<
0
)
||
(
ts
->
tv_nsec
>=
NSEC_PER_SEC
))
return
0
;
return
1
;
}
static
inline
struct
k_itimer
*
lock_timer
(
struct
task_struct
*
tsk
,
timer_t
timer_id
)
{
struct
k_itimer
*
timr
;
if
((
timer_id
<
0
)
||
(
timer_id
>=
MAX_ITIMERS
))
return
NULL
;
spin_lock
(
&
tsk
->
posix_timers
->
its_lock
);
timr
=
tsk
->
posix_timers
->
itimer
[
timer_id
];
if
(
timr
)
spin_lock
(
&
timr
->
it_lock
);
spin_unlock
(
&
tsk
->
posix_timers
->
its_lock
);
return
timr
;
}
static
inline
void
unlock_timer
(
struct
k_itimer
*
timr
)
{
spin_unlock
(
&
timr
->
it_lock
);
}
/* Get the time remaining on a POSIX.1b interval timer. */
static
void
do_timer_gettime
(
struct
k_itimer
*
timr
,
struct
itimerspec
*
cur_setting
)
{
unsigned
long
expires
=
timr
->
it_timer
.
expires
;
if
(
expires
)
expires
-=
jiffies
;
jiffies_to_timespec
(
expires
,
&
cur_setting
->
it_value
);
cur_setting
->
it_interval
=
timr
->
it_interval
;
}
/* Get the time remaining on a POSIX.1b interval timer. */
asmlinkage
int
sys_timer_gettime
(
timer_t
timer_id
,
struct
itimerspec
*
setting
)
{
struct
k_itimer
*
timr
;
struct
itimerspec
cur_setting
;
timr
=
lock_timer
(
current
,
timer_id
);
if
(
!
timr
)
return
-
EINVAL
;
do_timer_gettime
(
timr
,
&
cur_setting
);
unlock_timer
(
timr
);
copy_to_user_ret
(
setting
,
&
cur_setting
,
sizeof
(
cur_setting
),
-
EFAULT
);
return
0
;
}
/* Get the number of overruns of a POSIX.1b interval timer */
asmlinkage
int
sys_timer_getoverrun
(
timer_t
timer_id
)
{
struct
k_itimer
*
timr
;
int
overrun
;
timr
=
lock_timer
(
current
,
timer_id
);
if
(
!
timr
)
return
-
EINVAL
;
overrun
=
timr
->
it_overrun
;
unlock_timer
(
timr
);
return
overrun
;
}
static
void
timer_value_abs_to_rel
(
struct
timespec
*
val
)
{
struct
timeval
tv
;
struct
timespec
ts
;
do_gettimeofday
(
&
tv
);
ts
.
tv_sec
=
tv
.
tv_sec
;
ts
.
tv_nsec
=
tv
.
tv_usec
*
NSEC_PER_USEC
;
/* check whether the time lies in the past */
if
((
val
->
tv_sec
<
ts
.
tv_sec
)
||
((
val
->
tv_sec
==
ts
.
tv_sec
)
&&
(
val
->
tv_nsec
<=
ts
.
tv_nsec
)))
{
/* expire immediately */
val
->
tv_sec
=
0
;
val
->
tv_nsec
=
0
;
}
else
{
val
->
tv_sec
-=
ts
.
tv_sec
;
val
->
tv_nsec
-=
ts
.
tv_nsec
;
if
(
val
->
tv_nsec
<
0
)
{
val
->
tv_nsec
+=
NSEC_PER_SEC
;
val
->
tv_sec
--
;
}
}
}
/* Set a POSIX.1b interval timer. */
static
void
do_timer_settime
(
struct
k_itimer
*
timr
,
int
flags
,
struct
itimerspec
*
new_setting
,
struct
itimerspec
*
old_setting
)
{
/* disable the timer */
start_bh_atomic
();
del_timer
(
&
timr
->
it_timer
);
end_bh_atomic
();
if
(
old_setting
)
{
do_timer_gettime
(
timr
,
old_setting
);
}
/* switch off the timer when it_value is zero */
if
((
new_setting
->
it_value
.
tv_sec
==
0
)
&&
(
new_setting
->
it_value
.
tv_nsec
==
0
))
{
timr
->
it_incr
=
0
;
timr
->
it_timer
.
expires
=
0
;
timr
->
it_interval
.
tv_sec
=
0
;
timr
->
it_interval
.
tv_nsec
=
0
;
return
;
}
timr
->
it_incr
=
timespec_to_jiffies
(
&
new_setting
->
it_interval
);
/* save the interval rounded to jiffies */
jiffies_to_timespec
(
timr
->
it_incr
,
&
timr
->
it_interval
);
if
(
flags
&
TIMER_ABSTIME
)
{
timer_value_abs_to_rel
(
&
new_setting
->
it_value
);
}
timr
->
it_timer
.
expires
=
timespec_to_jiffies
(
&
new_setting
->
it_value
)
+
jiffies
;
/*
* For some reason the timer does not fire immediately if expires is
* equal to jiffies, so the timer callback function is called directly.
*/
if
(
timr
->
it_timer
.
expires
==
jiffies
)
{
posix_timer_fn
((
unsigned
long
)
timr
);
}
else
{
add_timer
(
&
timr
->
it_timer
);
}
}
/* Set a POSIX.1b interval timer */
asmlinkage
int
sys_timer_settime
(
timer_t
timer_id
,
int
flags
,
const
struct
itimerspec
*
new_setting
,
struct
itimerspec
*
old_setting
)
{
struct
k_itimer
*
timr
;
struct
itimerspec
new_spec
,
old_spec
;
int
error
=
0
;
timr
=
lock_timer
(
current
,
timer_id
);
if
(
!
timr
)
return
-
EINVAL
;
if
(
new_setting
==
NULL
)
{
error
=
-
EINVAL
;
goto
out
;
}
if
(
copy_from_user
(
&
new_spec
,
new_setting
,
sizeof
(
new_spec
)))
{
error
=
-
EFAULT
;
goto
out
;
}
if
((
!
good_timespec
(
&
new_spec
.
it_interval
))
||
(
!
good_timespec
(
&
new_spec
.
it_value
)))
{
error
=
-
EINVAL
;
goto
out
;
}
do_timer_settime
(
timr
,
flags
,
&
new_spec
,
old_setting
?
&
old_spec
:
NULL
);
if
(
old_setting
)
{
if
(
copy_to_user
(
old_setting
,
&
old_spec
,
sizeof
(
old_spec
)))
{
error
=
-
EFAULT
;
}
}
out:
unlock_timer
(
timr
);
return
error
;
}
/* Delete a POSIX.1b interval timer. */
asmlinkage
int
sys_timer_delete
(
timer_t
timer_id
)
{
struct
k_itimer
*
timr
;
timr
=
lock_timer
(
current
,
timer_id
);
if
(
!
timr
)
return
-
EINVAL
;
start_bh_atomic
();
del_timer
(
&
timr
->
it_timer
);
end_bh_atomic
();
spin_lock
(
&
current
->
posix_timers
->
its_lock
);
kfree
(
timr
);
current
->
posix_timers
->
itimer
[
timer_id
]
=
NULL
;
spin_unlock
(
&
current
->
posix_timers
->
its_lock
);
return
-
EFAULT
;
return
0
;
}
kernel/sched.c
View file @
86ae3b2a
...
...
@@ -788,8 +788,7 @@ asmlinkage void schedule(void)
atomic_inc
(
&
oldmm
->
mm_count
);
}
else
{
if
(
next
->
active_mm
!=
mm
)
BUG
();
if
(
mm
!=
oldmm
)
switch_mm
(
oldmm
,
mm
,
this_cpu
);
switch_mm
(
oldmm
,
mm
,
this_cpu
);
}
if
(
!
prev
->
mm
)
{
...
...
kernel/signal.c
View file @
86ae3b2a
...
...
@@ -132,7 +132,17 @@ printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid,
/* Collect the siginfo appropriate to this signal. */
if
(
sig
<
SIGRTMIN
)
{
*
info
=
current
->
nrt_info
[
sig
];
/* XXX: As an extension, support queueing exactly
one non-rt signal if SA_SIGINFO is set, so that
we can get more detailed information about the
cause of the signal. */
/* Deciding not to init these couple of fields is
more expensive that just initializing them. */
info
->
si_signo
=
sig
;
info
->
si_errno
=
0
;
info
->
si_code
=
0
;
info
->
si_pid
=
0
;
info
->
si_uid
=
0
;
}
else
{
struct
signal_queue
*
q
,
**
pp
;
pp
=
&
current
->
sigqueue
;
...
...
@@ -175,6 +185,8 @@ printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid,
sigdelset
(
&
current
->
signal
,
sig
);
recalc_sigpending
(
current
);
/* XXX: Once POSIX.1b timers are in, if si_code == SI_TIMER,
we need to xchg out the timer overrun values. */
}
else
{
/* XXX: Once CLONE_PID is in to join those "threads" that are
part of the same "process", look for signals sent to the
...
...
@@ -235,29 +247,6 @@ static int ignored_signal(int sig, struct task_struct *t)
return
1
;
}
static
void
set_siginfo
(
siginfo_t
*
dst
,
const
siginfo_t
*
src
,
int
sig
)
{
switch
((
unsigned
long
)
src
)
{
case
0
:
dst
->
si_signo
=
sig
;
dst
->
si_errno
=
0
;
dst
->
si_code
=
SI_USER
;
dst
->
si_pid
=
current
->
pid
;
dst
->
si_uid
=
current
->
uid
;
break
;
case
1
:
dst
->
si_signo
=
sig
;
dst
->
si_errno
=
0
;
dst
->
si_code
=
SI_KERNEL
;
dst
->
si_pid
=
0
;
dst
->
si_uid
=
0
;
break
;
default:
*
dst
=
*
src
;
break
;
}
}
int
send_sig_info
(
int
sig
,
struct
siginfo
*
info
,
struct
task_struct
*
t
)
{
...
...
@@ -317,10 +306,12 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
if
(
sig
<
SIGRTMIN
)
{
/* Non-real-time signals are not queued. */
/* XXX: As an extension, support queueing exactly one
non-rt signal if SA_SIGINFO is set, so that we can
get more detailed information about the cause of
the signal. */
if
(
sigismember
(
&
t
->
signal
,
sig
))
goto
out
;
set_siginfo
(
&
t
->
nrt_info
[
sig
],
info
,
sig
);
}
else
{
/* Real-time signals must be queued if sent by sigqueue, or
some other real-time mechanism. It is implementation
...
...
@@ -332,21 +323,6 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
struct
signal_queue
*
q
=
0
;
/* In case of a POSIX timer generated signal you must check
if a signal from this timer is already in the queue */
if
(
info
&&
(
info
->
si_code
==
SI_TIMER
))
{
for
(
q
=
t
->
sigqueue
;
q
;
q
=
q
->
next
)
{
if
((
q
->
info
.
si_code
==
SI_TIMER
)
&&
(
q
->
info
.
si_timer1
==
info
->
si_timer1
))
{
/* this special value (1) is recognized
only by posix_timer_fn() in
itimer.c */
ret
=
1
;
goto
out
;
}
}
}
if
(
atomic_read
(
&
nr_queued_signals
)
<
max_queued_signals
)
{
q
=
(
struct
signal_queue
*
)
kmem_cache_alloc
(
signal_queue_cachep
,
GFP_ATOMIC
);
...
...
@@ -357,7 +333,25 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
q
->
next
=
NULL
;
*
t
->
sigqueue_tail
=
q
;
t
->
sigqueue_tail
=
&
q
->
next
;
set_siginfo
(
&
q
->
info
,
info
,
sig
);
switch
((
unsigned
long
)
info
)
{
case
0
:
q
->
info
.
si_signo
=
sig
;
q
->
info
.
si_errno
=
0
;
q
->
info
.
si_code
=
SI_USER
;
q
->
info
.
si_pid
=
current
->
pid
;
q
->
info
.
si_uid
=
current
->
uid
;
break
;
case
1
:
q
->
info
.
si_signo
=
sig
;
q
->
info
.
si_errno
=
0
;
q
->
info
.
si_code
=
SI_KERNEL
;
q
->
info
.
si_pid
=
0
;
q
->
info
.
si_uid
=
0
;
break
;
default:
q
->
info
=
*
info
;
break
;
}
}
else
{
/* If this was sent by a rt mechanism, try again. */
if
(
info
->
si_code
<
0
)
{
...
...
kernel/time.c
View file @
86ae3b2a
...
...
@@ -414,57 +414,3 @@ asmlinkage int sys_adjtimex(struct timex *txc_p)
ret
=
do_adjtimex
(
&
txc
);
return
copy_to_user
(
txc_p
,
&
txc
,
sizeof
(
struct
timex
))
?
-
EFAULT
:
ret
;
}
/* POSIX.1b clock functions */
asmlinkage
int
sys_clock_gettime
(
clockid_t
clock_id
,
struct
timespec
*
ts
)
{
struct
timespec
kts
;
struct
timeval
ktv
;
if
(
clock_id
!=
CLOCK_REALTIME
)
return
-
EINVAL
;
if
(
ts
==
NULL
)
return
0
;
do_gettimeofday
(
&
ktv
);
kts
.
tv_sec
=
ktv
.
tv_sec
;
kts
.
tv_nsec
=
ktv
.
tv_usec
*
NSEC_PER_USEC
;
if
(
copy_to_user
(
ts
,
&
kts
,
sizeof
(
kts
)))
return
-
EFAULT
;
return
0
;
}
asmlinkage
int
sys_clock_settime
(
clockid_t
clock_id
,
const
struct
timespec
*
ts
)
{
struct
timespec
new_ts
;
struct
timeval
tv
;
if
(
clock_id
!=
CLOCK_REALTIME
)
return
-
EINVAL
;
if
(
ts
==
NULL
)
return
0
;
if
(
copy_from_user
(
&
new_ts
,
ts
,
sizeof
(
*
ts
)))
return
-
EFAULT
;
tv
.
tv_sec
=
new_ts
.
tv_sec
;
tv
.
tv_usec
=
new_ts
.
tv_nsec
/
NSEC_PER_USEC
;
return
do_sys_settimeofday
(
&
tv
,
NULL
);
}
asmlinkage
int
sys_clock_getres
(
clockid_t
clock_id
,
struct
timespec
*
res
)
{
struct
timespec
kres
;
if
(
clock_id
!=
CLOCK_REALTIME
)
return
-
EINVAL
;
if
(
res
==
NULL
)
return
0
;
kres
.
tv_sec
=
0
;
kres
.
tv_nsec
=
NSEC_PER_SEC
/
HZ
;
if
(
copy_to_user
(
res
,
&
kres
,
sizeof
(
kres
)))
return
-
EFAULT
;
return
0
;
}
mm/memory.c
View file @
86ae3b2a
...
...
@@ -824,6 +824,7 @@ static int do_wp_page(struct task_struct * tsk, struct vm_area_struct * vma,
return
1
;
bad_wp_page:
spin_unlock
(
&
tsk
->
mm
->
page_table_lock
);
printk
(
"do_wp_page: bogus page at address %08lx (%08lx)
\n
"
,
address
,
old_page
);
return
-
1
;
}
...
...
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