Commit 86ae3b2a authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.12pre9

parent 6ae9dd08
......@@ -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
......
/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 ###
......@@ -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 */
......@@ -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-198
.rept NR_syscalls-186
.long SYMBOL_NAME(sys_ni_syscall)
.endr
#endif
......@@ -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-198
.rept NR_syscalls-190
.long SYMBOL_NAME(sys_ni_syscall)
.endr
......@@ -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();
}
......
......@@ -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) {
......
......@@ -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)
......
......@@ -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)
......@@ -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
......@@ -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. */
......
......@@ -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. */
......
......@@ -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. */
......
......@@ -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;
......
This diff is collapsed.
......@@ -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;
}
......
......@@ -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
......@@ -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
......@@ -27,7 +27,6 @@
/*****************************************************************************/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/socket.h>
#include <asm/uaccess.h>
......
......@@ -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);
This diff is collapsed.
#!/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.
......@@ -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();
......
......@@ -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
......@@ -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;
return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
res = 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);
......
......@@ -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;
}
......
......@@ -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
......
......@@ -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__)
......
......@@ -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
......
......@@ -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)
......
......@@ -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
......@@ -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
......
......@@ -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> */
......
......@@ -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
......
......@@ -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> */
......
......@@ -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
......
......@@ -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
......
......@@ -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 SEGV_ACCERR 2 /* invalid permissions for mapped object */
#define SRGV_ACCERR 2 /* invalid permissions for mapped object */
#define NSIGSEGV 2
/*
......
......@@ -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
......
......@@ -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 SEGV_ACCERR 2 /* invalid permissions for mapped object */
#define SRGV_ACCERR 2 /* invalid permissions for mapped object */
#define NSIGSEGV 2
/*
......
......@@ -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) \
......
......@@ -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 SEGV_ACCERR 2 /* invalid permissions for mapped object */
#define SRGV_ACCERR 2 /* invalid permissions for mapped object */
#define NSIGSEGV 2
/*
......
......@@ -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) \
......
......@@ -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
......@@ -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 *);
......
......@@ -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
......@@ -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;
......
......@@ -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:
......
This diff is collapsed.
......@@ -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) {
......
......@@ -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) {
......
......@@ -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;
}
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment