Commit 6f267f9c authored by Linus Torvalds's avatar Linus Torvalds

v2.4.6.9 -> v2.4.7

  - me: fix ptrace and /proc issues with new core-dump permissions
  - numerous: IDE tape driver update for completion handlers
  - Ben Collins: ieee1394 GUID cleanups
  - Jacek Stepniewski: nasty deadlock in rename()
parent 7b4d3039
VERSION = 2 VERSION = 2
PATCHLEVEL = 4 PATCHLEVEL = 4
SUBLEVEL = 7 SUBLEVEL = 7
EXTRAVERSION =-pre9 EXTRAVERSION =
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
......
...@@ -264,32 +264,7 @@ sys_ptrace(long request, long pid, long addr, long data, ...@@ -264,32 +264,7 @@ sys_ptrace(long request, long pid, long addr, long data,
if (!child) if (!child)
goto out_notsk; goto out_notsk;
if (request == PTRACE_ATTACH) { if (request == PTRACE_ATTACH) {
ret = -EPERM; ret = ptrace_attach(child);
if (child == current)
goto out;
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(current->gid != child->gid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)))
&& !capable(CAP_SYS_PTRACE))
goto out;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out;
child->ptrace |= PT_PTRACED;
write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out; goto out;
} }
ret = -ESRCH; ret = -ESRCH;
......
...@@ -594,32 +594,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -594,32 +594,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
goto out_tsk; goto out_tsk;
if (request == PTRACE_ATTACH) { if (request == PTRACE_ATTACH) {
if (child == current) ret = ptrace_attach(child);
goto out_tsk;
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out_tsk;
child->ptrace |= PT_PTRACED;
write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out_tsk; goto out_tsk;
} }
ret = -ESRCH; ret = -ESRCH;
......
...@@ -115,32 +115,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -115,32 +115,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
if (pid == 1) /* you may not mess with init */ if (pid == 1) /* you may not mess with init */
goto out_tsk; goto out_tsk;
if (request == PTRACE_ATTACH) { if (request == PTRACE_ATTACH) {
if (child == current) ret = ptrace_attach(child);
goto out_tsk;
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out_tsk;
child->ptrace |= PT_PTRACED;
write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out_tsk; goto out_tsk;
} }
ret = -ESRCH; ret = -ESRCH;
......
...@@ -165,34 +165,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -165,34 +165,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
goto out_tsk; goto out_tsk;
if (request == PTRACE_ATTACH) { if (request == PTRACE_ATTACH) {
if (child == current) ret = ptrace_attach(child);
goto out_tsk;
if(((current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
rmb();
if (!child->mm->dumpable && !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out_tsk;
child->ptrace |= PT_PTRACED;
write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out_tsk; goto out_tsk;
} }
ret = -ESRCH; ret = -ESRCH;
......
...@@ -768,32 +768,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data, ...@@ -768,32 +768,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
goto out_tsk; goto out_tsk;
if (request == PTRACE_ATTACH) { if (request == PTRACE_ATTACH) {
if (child == current) ret = ptrace_attach(child);
goto out_tsk;
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out_tsk;
child->ptrace |= PT_PTRACED;
if (child->p_pptr != current) {
unsigned long flags;
write_lock_irqsave(&tasklist_lock, flags);
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
write_unlock_irqrestore(&tasklist_lock, flags);
}
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out_tsk; goto out_tsk;
} }
ret = -ESRCH; ret = -ESRCH;
......
...@@ -118,32 +118,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -118,32 +118,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
goto out_tsk; goto out_tsk;
if (request == PTRACE_ATTACH) { if (request == PTRACE_ATTACH) {
if (child == current) ret = ptrace_attach(child);
goto out_tsk;
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out_tsk;
child->ptrace |= PT_PTRACED;
write_lock_irqsave(&tasklist_lock, flags);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irqrestore(&tasklist_lock, flags);
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out_tsk; goto out_tsk;
} }
ret = -ESRCH; ret = -ESRCH;
......
...@@ -66,34 +66,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -66,34 +66,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
goto out; goto out;
if (request == PTRACE_ATTACH) { if (request == PTRACE_ATTACH) {
if (child == current) res = ptrace_attach(child);
goto out_tsk;
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(current->gid != child->gid) ||
(!cap_issubset(child->cap_permitted,
current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out_tsk;
child->ptrace |= PT_PTRACED;
write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, child, 1);
res = 0;
goto out_tsk; goto out_tsk;
} }
res = -ESRCH; res = -ESRCH;
......
...@@ -62,32 +62,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) ...@@ -62,32 +62,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
goto out_tsk; goto out_tsk;
if (request == PTRACE_ATTACH) { if (request == PTRACE_ATTACH) {
if (child == current) ret = ptrace_attach(child);
goto out_tsk;
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out_tsk;
child->ptrace |= PT_PTRACED;
write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out_tsk; goto out_tsk;
} }
ret = -ESRCH; ret = -ESRCH;
...@@ -336,32 +311,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -336,32 +311,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
goto out; goto out;
if (request == PTRACE_ATTACH) { if (request == PTRACE_ATTACH) {
if (child == current) ret = ptrace_attach(child);
goto out_tsk;
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out_tsk;
child->ptrace |= PT_PTRACED;
write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out_tsk; goto out_tsk;
} }
ret = -ESRCH; ret = -ESRCH;
......
...@@ -61,32 +61,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data) ...@@ -61,32 +61,7 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
goto out_tsk; goto out_tsk;
if (request == PTRACE_ATTACH) { if (request == PTRACE_ATTACH) {
if (child == current) ret = ptrace_attach(child);
goto out_tsk;
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out_tsk;
child->ptrace |= PT_PTRACED;
if (child->p_pptr != current) {
unsigned long flags;
write_lock_irqsave(&tasklist_lock, flags);
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
write_unlock_irqrestore(&tasklist_lock, flags);
}
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out_tsk; goto out_tsk;
} }
ret = -ESRCH; ret = -ESRCH;
......
...@@ -118,33 +118,7 @@ int sys_ptrace(long request, long pid, long addr, long data) ...@@ -118,33 +118,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
goto out_tsk; goto out_tsk;
if (request == PTRACE_ATTACH) { if (request == PTRACE_ATTACH) {
if (child == current) ret = ptrace_attach(child);
goto out_tsk;
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid))
&& !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out_tsk;
child->ptrace |= PT_PTRACED;
write_lock_irq(&tasklist_lock);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out_tsk; goto out_tsk;
} }
ret = -ESRCH; ret = -ESRCH;
......
...@@ -233,31 +233,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -233,31 +233,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
goto out; goto out;
if (request == PTRACE_ATTACH) if (request == PTRACE_ATTACH)
{ {
if (child == current) ret = ptrace_attach(child);
goto out;
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid)) && !capable(CAP_SYS_PTRACE))
goto out;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out;
child->ptrace |= PT_PTRACED;
write_lock_irqsave(&tasklist_lock, flags);
if (child->p_pptr != current)
{
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irqrestore(&tasklist_lock, flags);
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out; goto out;
} }
ret = -ESRCH; ret = -ESRCH;
......
...@@ -247,31 +247,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -247,31 +247,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
goto out; goto out;
if (request == PTRACE_ATTACH) if (request == PTRACE_ATTACH)
{ {
if (child == current) ret = ptrace_attach(child);
goto out;
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid)) && !capable(CAP_SYS_PTRACE))
goto out;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out;
child->ptrace |= PT_PTRACED;
write_lock_irqsave(&tasklist_lock, flags);
if (child->p_pptr != current)
{
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irqrestore(&tasklist_lock, flags);
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out; goto out;
} }
ret = -ESRCH; ret = -ESRCH;
...@@ -433,31 +409,7 @@ asmlinkage int sys32_ptrace(long request, long pid, long addr, s32 data) ...@@ -433,31 +409,7 @@ asmlinkage int sys32_ptrace(long request, long pid, long addr, s32 data)
goto out; goto out;
if (request == PTRACE_ATTACH) if (request == PTRACE_ATTACH)
{ {
if (child == current) ret = ptrace_attach(child);
goto out;
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->suid) ||
(current->uid != child->uid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid)) && !capable(CAP_SYS_PTRACE))
goto out;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out;
child->ptrace |= PT_PTRACED;
write_lock_irqsave(&tasklist_lock, flags);
if (child->p_pptr != current)
{
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irqrestore(&tasklist_lock, flags);
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out; goto out;
} }
ret = -ESRCH; ret = -ESRCH;
......
...@@ -173,34 +173,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ...@@ -173,34 +173,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
goto out_tsk; goto out_tsk;
if (request == PTRACE_ATTACH) { if (request == PTRACE_ATTACH) {
if (child == tsk) ret = ptrace_attach(child);
goto out_tsk;
if(((tsk->uid != child->euid) ||
(tsk->uid != child->suid) ||
(tsk->uid != child->uid) ||
(tsk->gid != child->egid) ||
(tsk->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, tsk->cap_permitted)) ||
(tsk->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
rmb();
if (!child->mm->dumpable && !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED)
goto out_tsk;
child->ptrace |= PT_PTRACED;
write_lock_irq(&tasklist_lock);
if (child->p_pptr != tsk) {
REMOVE_LINKS(child);
child->p_pptr = tsk;
SET_LINKS(child);
}
write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, child, 1);
ret = 0;
goto out_tsk; goto out_tsk;
} }
ret = -ESRCH; ret = -ESRCH;
......
...@@ -320,38 +320,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs) ...@@ -320,38 +320,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
|| (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
unsigned long flags; unsigned long flags;
if(child == current) { if (ptrace_attach(child)) {
/* Try this under SunOS/Solaris, bwa haha
* You'll never be able to kill the process. ;-)
*/
pt_error_return(regs, EPERM); pt_error_return(regs, EPERM);
goto out_tsk; goto out_tsk;
} }
if((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->uid) ||
(current->uid != child->suid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) {
pt_error_return(regs, EPERM);
goto out_tsk;
}
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED) {
pt_error_return(regs, EPERM);
goto out_tsk;
}
child->ptrace |= PT_PTRACED;
write_lock_irqsave(&tasklist_lock, flags);
if(child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irqrestore(&tasklist_lock, flags);
send_sig(SIGSTOP, child, 1);
pt_succ_return(regs, 0); pt_succ_return(regs, 0);
goto out_tsk; goto out_tsk;
} }
......
# $Id: config.in,v 1.147 2001/07/18 07:52:34 davem Exp $ # $Id: config.in,v 1.148 2001/07/20 07:10:35 davem Exp $
# For a description of the syntax of this configuration file, # For a description of the syntax of this configuration file,
# see the Configure script. # see the Configure script.
# #
...@@ -207,7 +207,9 @@ fi ...@@ -207,7 +207,9 @@ fi
endmenu endmenu
source drivers/fc4/Config.in source drivers/fc4/Config.in
source drivers/message/fusion/Config.in source drivers/message/fusion/Config.in
source drivers/ieee1394/Config.in source drivers/ieee1394/Config.in
if [ "$CONFIG_NET" = "y" ]; then if [ "$CONFIG_NET" = "y" ]; then
......
...@@ -364,13 +364,23 @@ CONFIG_FUSION_LAN=m ...@@ -364,13 +364,23 @@ CONFIG_FUSION_LAN=m
CONFIG_NET_FC=y CONFIG_NET_FC=y
# #
# IEEE 1394 (FireWire) support # IEEE 1394 (FireWire) support (EXPERIMENTAL)
# #
CONFIG_IEEE1394=m CONFIG_IEEE1394=m
#
# Device Drivers
#
CONFIG_IEEE1394_PCILYNX=m CONFIG_IEEE1394_PCILYNX=m
# CONFIG_IEEE1394_PCILYNX_LOCALRAM is not set # CONFIG_IEEE1394_PCILYNX_LOCALRAM is not set
# CONFIG_IEEE1394_PCILYNX_PORTS is not set # CONFIG_IEEE1394_PCILYNX_PORTS is not set
CONFIG_IEEE1394_OHCI1394=m CONFIG_IEEE1394_OHCI1394=m
#
# Protocol Drivers
#
# CONFIG_IEEE1394_VIDEO1394 is not set
CONFIG_IEEE1394_SBP2=m
CONFIG_IEEE1394_RAWIO=m CONFIG_IEEE1394_RAWIO=m
# CONFIG_IEEE1394_VERBOSEDEBUG is not set # CONFIG_IEEE1394_VERBOSEDEBUG is not set
......
...@@ -170,38 +170,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs) ...@@ -170,38 +170,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
|| (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
unsigned long flags; unsigned long flags;
if (child == current) { if (ptrace_attach(child)) {
/* Try this under SunOS/Solaris, bwa haha
* You'll never be able to kill the process. ;-)
*/
pt_error_return(regs, EPERM); pt_error_return(regs, EPERM);
goto out_tsk; goto out_tsk;
} }
if ((!child->mm->dumpable ||
(current->uid != child->euid) ||
(current->uid != child->uid) ||
(current->uid != child->suid) ||
(current->gid != child->egid) ||
(current->gid != child->sgid) ||
(!cap_issubset(child->cap_permitted, current->cap_permitted)) ||
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE)) {
pt_error_return(regs, EPERM);
goto out_tsk;
}
/* the same process cannot be attached many times */
if (child->ptrace & PT_PTRACED) {
pt_error_return(regs, EPERM);
goto out_tsk;
}
child->ptrace |= PT_PTRACED;
write_lock_irqsave(&tasklist_lock, flags);
if (child->p_pptr != current) {
REMOVE_LINKS(child);
child->p_pptr = current;
SET_LINKS(child);
}
write_unlock_irqrestore(&tasklist_lock, flags);
send_sig(SIGSTOP, child, 1);
pt_succ_return(regs, 0); pt_succ_return(regs, 0);
goto out_tsk; goto out_tsk;
} }
......
...@@ -419,6 +419,7 @@ ...@@ -419,6 +419,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/completion.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -978,7 +979,7 @@ typedef struct { ...@@ -978,7 +979,7 @@ typedef struct {
int logical_blk_num; /* logical block number */ int logical_blk_num; /* logical block number */
__u16 wrt_pass_cntr; /* write pass counter */ __u16 wrt_pass_cntr; /* write pass counter */
__u32 update_frame_cntr; /* update frame counter */ __u32 update_frame_cntr; /* update frame counter */
struct semaphore *sem; struct completion *waiting;
int onstream_write_error; /* write error recovery active */ int onstream_write_error; /* write error recovery active */
int header_ok; /* header frame verified ok */ int header_ok; /* header frame verified ok */
int linux_media; /* reading linux-specifc media */ int linux_media; /* reading linux-specifc media */
...@@ -1886,8 +1887,8 @@ static void idetape_end_request (byte uptodate, ide_hwgroup_t *hwgroup) ...@@ -1886,8 +1887,8 @@ static void idetape_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
printk("ide-tape: %s: skipping over config parition..\n", tape->name); printk("ide-tape: %s: skipping over config parition..\n", tape->name);
#endif #endif
tape->onstream_write_error = OS_PART_ERROR; tape->onstream_write_error = OS_PART_ERROR;
if (tape->sem) if (tape->waiting)
up(tape->sem); complete(tape->waiting);
} }
} }
remove_stage = 1; remove_stage = 1;
...@@ -1903,8 +1904,8 @@ static void idetape_end_request (byte uptodate, ide_hwgroup_t *hwgroup) ...@@ -1903,8 +1904,8 @@ static void idetape_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
tape->nr_pending_stages++; tape->nr_pending_stages++;
tape->next_stage = tape->first_stage; tape->next_stage = tape->first_stage;
rq->current_nr_sectors = rq->nr_sectors; rq->current_nr_sectors = rq->nr_sectors;
if (tape->sem) if (tape->waiting)
up(tape->sem); complete(tape->waiting);
} }
} }
} else if (rq->cmd == IDETAPE_READ_RQ) { } else if (rq->cmd == IDETAPE_READ_RQ) {
...@@ -3064,15 +3065,15 @@ static void idetape_init_stage (ide_drive_t *drive, idetape_stage_t *stage, int ...@@ -3064,15 +3065,15 @@ static void idetape_init_stage (ide_drive_t *drive, idetape_stage_t *stage, int
} }
/* /*
* idetape_wait_for_request installs a semaphore in a pending request * idetape_wait_for_request installs a completion in a pending request
* and sleeps until it is serviced. * and sleeps until it is serviced.
* *
* The caller should ensure that the request will not be serviced * The caller should ensure that the request will not be serviced
* before we install the semaphore (usually by disabling interrupts). * before we install the completion (usually by disabling interrupts).
*/ */
static void idetape_wait_for_request (ide_drive_t *drive, struct request *rq) static void idetape_wait_for_request (ide_drive_t *drive, struct request *rq)
{ {
DECLARE_MUTEX_LOCKED(sem); DECLARE_COMPLETION(wait);
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
#if IDETAPE_DEBUG_BUGS #if IDETAPE_DEBUG_BUGS
...@@ -3081,12 +3082,12 @@ static void idetape_wait_for_request (ide_drive_t *drive, struct request *rq) ...@@ -3081,12 +3082,12 @@ static void idetape_wait_for_request (ide_drive_t *drive, struct request *rq)
return; return;
} }
#endif /* IDETAPE_DEBUG_BUGS */ #endif /* IDETAPE_DEBUG_BUGS */
rq->sem = &sem; rq->waiting = &wait;
tape->sem = &sem; tape->waiting = &wait;
spin_unlock(&tape->spinlock); spin_unlock(&tape->spinlock);
down(&sem); wait_for_completion(&wait);
rq->sem = NULL; rq->waiting = NULL;
tape->sem = NULL; tape->waiting = NULL;
spin_lock_irq(&tape->spinlock); spin_lock_irq(&tape->spinlock);
} }
......
...@@ -8,7 +8,7 @@ export-objs := ieee1394_syms.o ...@@ -8,7 +8,7 @@ export-objs := ieee1394_syms.o
list-multi := ieee1394.o list-multi := ieee1394.o
ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \ ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \
highlevel.o csr.o guid.o ieee1394_syms.o highlevel.o csr.o nodemgr.o ieee1394_syms.o
obj-$(CONFIG_IEEE1394) += ieee1394.o obj-$(CONFIG_IEEE1394) += ieee1394.o
obj-$(CONFIG_IEEE1394_PCILYNX) += pcilynx.o obj-$(CONFIG_IEEE1394_PCILYNX) += pcilynx.o
...@@ -16,8 +16,6 @@ obj-$(CONFIG_IEEE1394_OHCI1394) += ohci1394.o ...@@ -16,8 +16,6 @@ obj-$(CONFIG_IEEE1394_OHCI1394) += ohci1394.o
obj-$(CONFIG_IEEE1394_VIDEO1394) += video1394.o obj-$(CONFIG_IEEE1394_VIDEO1394) += video1394.o
obj-$(CONFIG_IEEE1394_RAWIO) += raw1394.o obj-$(CONFIG_IEEE1394_RAWIO) += raw1394.o
obj-$(CONFIG_IEEE1394_SBP2) += sbp2.o obj-$(CONFIG_IEEE1394_SBP2) += sbp2.o
obj-$(CONFIG_IEEE1394_ETH1394) += eth1394.o
obj-$(CONFIG_IEEE1394_IP1394) += ip1394.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "highlevel.h" #include "highlevel.h"
#include "ieee1394_transactions.h" #include "ieee1394_transactions.h"
#include "csr.h" #include "csr.h"
#include "guid.h" #include "nodemgr.h"
atomic_t hpsb_generation = ATOMIC_INIT(0); atomic_t hpsb_generation = ATOMIC_INIT(0);
...@@ -782,13 +782,13 @@ static int __init ieee1394_init(void) ...@@ -782,13 +782,13 @@ static int __init ieee1394_init(void)
{ {
init_hpsb_highlevel(); init_hpsb_highlevel();
init_csr(); init_csr();
init_ieee1394_guid(); init_ieee1394_nodemgr();
return 0; return 0;
} }
static void __exit ieee1394_cleanup(void) static void __exit ieee1394_cleanup(void)
{ {
cleanup_ieee1394_guid(); cleanup_ieee1394_nodemgr();
cleanup_csr(); cleanup_csr();
} }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include "ieee1394_core.h" #include "ieee1394_core.h"
#include "ieee1394_transactions.h" #include "ieee1394_transactions.h"
#include "highlevel.h" #include "highlevel.h"
#include "guid.h" #include "nodemgr.h"
EXPORT_SYMBOL(hpsb_register_lowlevel); EXPORT_SYMBOL(hpsb_register_lowlevel);
EXPORT_SYMBOL(hpsb_unregister_lowlevel); EXPORT_SYMBOL(hpsb_unregister_lowlevel);
...@@ -76,5 +76,5 @@ EXPORT_SYMBOL(highlevel_remove_host); ...@@ -76,5 +76,5 @@ EXPORT_SYMBOL(highlevel_remove_host);
EXPORT_SYMBOL(highlevel_host_reset); EXPORT_SYMBOL(highlevel_host_reset);
EXPORT_SYMBOL(highlevel_add_one_host); EXPORT_SYMBOL(highlevel_add_one_host);
EXPORT_SYMBOL(hpsb_guid_get_handle); EXPORT_SYMBOL(hpsb_guid_get_handle);
EXPORT_SYMBOL(hpsb_guid_localhost); EXPORT_SYMBOL(hpsb_get_host_by_ge);
EXPORT_SYMBOL(hpsb_guid_fill_packet); EXPORT_SYMBOL(hpsb_guid_fill_packet);
/* /*
* IEEE 1394 for Linux * Node information (ConfigROM) collection and management.
*
* GUID collection and management
* *
* Copyright (C) 2000 Andreas E. Bombe * Copyright (C) 2000 Andreas E. Bombe
* 2001 Ben Collins <bcollins@debian.net>
* *
* This code is licensed under the GPL. See the file COPYING in the root * This code is licensed under the GPL. See the file COPYING in the root
* directory of the kernel sources for details. * directory of the kernel sources for details.
...@@ -14,6 +13,8 @@ ...@@ -14,6 +13,8 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include "ieee1394_types.h" #include "ieee1394_types.h"
#include "ieee1394.h" #include "ieee1394.h"
...@@ -23,12 +24,37 @@ ...@@ -23,12 +24,37 @@
#include "csr.h" #include "csr.h"
/* Basically what we do here is start off retrieving the bus_info block.
* From there will fill in some info about the node, verify it is of IEEE
* 1394 type, and the the crc checks out ok. After that we start off with
* the root directory, and subdirectories. To do this, we retrieve the
* quadlet header for a directory, find out the length, and retrieve the
* complete directory entry (be it a leaf or a directory). We then process
* it and add the info to our structure for that particular node.
*
* We verify CRC's along the way for each directory/block/leaf. The
* entire node structure is generic, and simply stores the information in
* a way that's easy to parse by the protocol interface.
*
* XXX: Most of this isn't done yet :) */
static atomic_t outstanding_requests; static atomic_t outstanding_requests;
static LIST_HEAD(guid_list); static LIST_HEAD(node_list);
rwlock_t guid_lock = RW_LOCK_UNLOCKED; rwlock_t node_lock = RW_LOCK_UNLOCKED;
static LIST_HEAD(host_info_list);
spinlock_t host_info_lock = SPIN_LOCK_UNLOCKED;
struct guid_entry { struct host_info {
struct hpsb_host *host;
int pid;
wait_queue_head_t reset_wait;
struct list_head list;
};
struct node_entry {
struct list_head list; struct list_head list;
atomic_t refcount; atomic_t refcount;
...@@ -40,21 +66,12 @@ struct guid_entry { ...@@ -40,21 +66,12 @@ struct guid_entry {
atomic_t generation; atomic_t generation;
}; };
struct guid_req { static struct node_entry *create_node_entry(void)
struct hpsb_packet *pkt;
int retry;
unsigned int hdr_size;
int hdr_ptr;
u32 bus_info[5];
struct tq_struct tq;
};
static struct guid_entry *create_guid_entry(void)
{ {
struct guid_entry *ge; struct node_entry *ge;
unsigned long flags; unsigned long flags;
ge = kmalloc(sizeof(struct guid_entry), SLAB_ATOMIC); ge = kmalloc(sizeof(struct node_entry), SLAB_ATOMIC);
if (!ge) return NULL; if (!ge) return NULL;
INIT_LIST_HEAD(&ge->list); INIT_LIST_HEAD(&ge->list);
...@@ -64,21 +81,21 @@ static struct guid_entry *create_guid_entry(void) ...@@ -64,21 +81,21 @@ static struct guid_entry *create_guid_entry(void)
ge->node_id = 0; ge->node_id = 0;
atomic_set(&ge->generation, -1); atomic_set(&ge->generation, -1);
write_lock_irqsave(&guid_lock, flags); write_lock_irqsave(&node_lock, flags);
list_add_tail(&ge->list, &guid_list); list_add_tail(&ge->list, &node_list);
write_unlock_irqrestore(&guid_lock, flags); write_unlock_irqrestore(&node_lock, flags);
return ge; return ge;
} }
static struct guid_entry *find_entry(u64 guid) static struct node_entry *find_entry(u64 guid)
{ {
struct list_head *lh; struct list_head *lh;
struct guid_entry *ge; struct node_entry *ge;
lh = guid_list.next; lh = node_list.next;
while (lh != &guid_list) { while (lh != &node_list) {
ge = list_entry(lh, struct guid_entry, list); ge = list_entry(lh, struct node_entry, list);
if (ge->guid == guid) return ge; if (ge->guid == guid) return ge;
lh = lh->next; lh = lh->next;
} }
...@@ -88,7 +105,7 @@ static struct guid_entry *find_entry(u64 guid) ...@@ -88,7 +105,7 @@ static struct guid_entry *find_entry(u64 guid)
static void associate_guid(struct hpsb_host *host, nodeid_t nodeid, u64 guid) static void associate_guid(struct hpsb_host *host, nodeid_t nodeid, u64 guid)
{ {
struct guid_entry *ge; struct node_entry *ge;
unsigned long flags; unsigned long flags;
HPSB_DEBUG("Node %d on %s host: GUID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", HPSB_DEBUG("Node %d on %s host: GUID %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
...@@ -97,11 +114,11 @@ static void associate_guid(struct hpsb_host *host, nodeid_t nodeid, u64 guid) ...@@ -97,11 +114,11 @@ static void associate_guid(struct hpsb_host *host, nodeid_t nodeid, u64 guid)
((u8 *)&guid)[4], ((u8 *)&guid)[5], ((u8 *)&guid)[6], ((u8 *)&guid)[4], ((u8 *)&guid)[5], ((u8 *)&guid)[6],
((u8 *)&guid)[7]); ((u8 *)&guid)[7]);
read_lock_irqsave(&guid_lock, flags); read_lock_irqsave(&node_lock, flags);
ge = find_entry(guid); ge = find_entry(guid);
read_unlock_irqrestore(&guid_lock, flags); read_unlock_irqrestore(&node_lock, flags);
if (!ge) ge = create_guid_entry(); if (!ge) ge = create_node_entry();
if (!ge) return; if (!ge) return;
ge->host = host; ge->host = host;
...@@ -111,102 +128,22 @@ static void associate_guid(struct hpsb_host *host, nodeid_t nodeid, u64 guid) ...@@ -111,102 +128,22 @@ static void associate_guid(struct hpsb_host *host, nodeid_t nodeid, u64 guid)
atomic_set(&ge->generation, get_hpsb_generation()); atomic_set(&ge->generation, get_hpsb_generation());
} }
static void pkt_complete(struct guid_req *req) /* This is where we probe the nodes for their information and provided
* features. */
static void nodemgr_node_probe(struct hpsb_host *host)
{ {
struct hpsb_packet *pkt = req->pkt;
struct hpsb_host *host = pkt->host;
nodeid_t nodeid = pkt->node_id;
if (hpsb_packet_success (pkt)) {
HPSB_ERR("GUID quadlet transaction error for %d, retry: %d", nodeid,
req->retry);
req->retry++;
if (req->retry > 3)
goto finish;
else
goto retry;
}
/* Copy our received quadlet */
req->bus_info[req->hdr_ptr++] = be32_to_cpu(pkt->header[3]);
/* First quadlet, let's get some info */
if (req->hdr_ptr == 1) {
/* Get the bus_info_length from first quadlet */
req->hdr_size = req->bus_info[0] >> 24;
/* Make sure this isn't one of those minimal proprietary
* ROMs. IMO, we should just barf all over them. We need
* atleast four bus_info quads to get our EUI-64. */
if (req->hdr_size < 4) {
HPSB_INFO("Node %d on %s host has non-standard ROM format (%d quads), "
"cannot parse", nodeid, host->template->name, req->hdr_size);
goto finish;
}
/* Make sure we don't overflow. We have one quad for this
* first bus info block, the other 4 should be part of the
* bus info itself. */
if (req->hdr_size > (sizeof (req->bus_info) >> 2) - 1)
req->hdr_size = (sizeof (req->bus_info) >> 2) - 1;
}
/* We've got all the info we need, so let's check the EUI-64, and
* add it to our list. */
if (req->hdr_ptr >= req->hdr_size + 1) {
associate_guid(pkt->host, pkt->node_id,
((u64)req->bus_info[3] << 32) | req->bus_info[4]);
goto finish;
}
retry:
/* Here, we either retry a failed retrieve, or we have incremented
* our counter, to get the next quad in our header. */
free_tlabel(pkt->host, pkt->node_id, pkt->tlabel);
free_hpsb_packet(pkt);
pkt = hpsb_make_readqpacket(host, nodeid, CSR_REGISTER_BASE +
CSR_CONFIG_ROM + (req->hdr_ptr<<2));
if (!pkt) {
kfree(req);
HPSB_ERR("Out of memory in GUID processing");
return;
}
req->pkt = pkt;
req->retry = 0;
queue_task(&req->tq, &pkt->complete_tq);
if (!hpsb_send_packet(pkt)) {
HPSB_NOTICE("Failed to send GUID request to node %d", nodeid);
goto finish;
}
return;
finish:
free_tlabel(pkt->host, nodeid, pkt->tlabel);
free_hpsb_packet(pkt);
kfree(req);
if (atomic_dec_and_test(&outstanding_requests)) {
/* Do something useful */
}
return;
}
static void host_reset(struct hpsb_host *host)
{
struct guid_req *greq;
struct hpsb_packet *pkt;
struct selfid *sid = (struct selfid *)host->topology_map; struct selfid *sid = (struct selfid *)host->topology_map;
int nodecount = host->node_count; int nodecount = host->node_count;
nodeid_t nodeid = LOCAL_BUS; nodeid_t nodeid = LOCAL_BUS;
quadlet_t buffer[5], quad;
octlet_t base = CSR_REGISTER_BASE + CSR_CONFIG_ROM;
int retval;
/* We need to detect when the ConfigROM's generation has changed,
* so we only update the node's info when it needs to be. */
for (; nodecount; nodecount--, nodeid++, sid++) { for (; nodecount; nodecount--, nodeid++, sid++) {
int header_count = 0;
unsigned header_size = 0;
while (sid->extended) while (sid->extended)
sid++; sid++;
if (!sid->link_active) if (!sid->link_active)
...@@ -214,65 +151,70 @@ static void host_reset(struct hpsb_host *host) ...@@ -214,65 +151,70 @@ static void host_reset(struct hpsb_host *host)
if (nodeid == host->node_id) if (nodeid == host->node_id)
continue; continue;
greq = kmalloc(sizeof(struct guid_req), SLAB_ATOMIC); HPSB_DEBUG("Initiating ConfigROM request for node %d", nodeid & NODE_MASK);
if (!greq) {
HPSB_ERR("Out of memory in GUID processing");
return;
}
pkt = hpsb_make_readqpacket(host, nodeid, CSR_REGISTER_BASE + retval = hpsb_read(host, nodeid, base, &quad, 4);
CSR_CONFIG_ROM); buffer[header_count++] = be32_to_cpu(quad);
if (!pkt) { if (retval) {
kfree(greq); HPSB_ERR("ConfigROM quadlet transaction error for %d",
HPSB_ERR("Out of memory in GUID processing"); nodeid & NODE_MASK);
return; continue;
} }
INIT_TQUEUE(&greq->tq, (void (*)(void*))pkt_complete, greq); header_size = buffer[0] >> 24;
greq->hdr_size = 4; if (header_size < 4) {
greq->hdr_ptr = 0; HPSB_INFO("Node %d on %s host has non-standard ROM format (%d quads), "
greq->retry = 0; "cannot parse", nodeid & NODE_MASK, host->template->name,
greq->pkt = pkt; header_size);
continue;
}
queue_task(&greq->tq, &pkt->complete_tq); while (header_count <= header_size && (header_count<<2) < sizeof(buffer)) {
retval = hpsb_read(host, nodeid, base + (header_count<<2), &quad, 4);
buffer[header_count++] = be32_to_cpu(quad);
if (!hpsb_send_packet(pkt)) { if (retval) {
free_tlabel(pkt->host, pkt->node_id, pkt->tlabel); HPSB_ERR("ConfigROM quadlet transaction error for %d",
free_hpsb_packet(pkt); nodeid & NODE_MASK);
kfree(greq); goto failed_read;
HPSB_NOTICE("Failed to send GUID request to node %d", nodeid); }
}
HPSB_DEBUG("GUID request sent to node %d", nodeid & NODE_MASK); }
atomic_inc(&outstanding_requests); associate_guid(host, nodeid, be64_to_cpu(((u64)buffer[3] << 32) | buffer[4]));
failed_read:
continue;
} }
/* Need to detect when nodes are no longer associated with
* anything. I believe we can do this using the generation of the
* entries after a reset, compared the the hosts generation. */
} }
struct guid_entry *hpsb_guid_get_handle(u64 guid) struct node_entry *hpsb_guid_get_handle(u64 guid)
{ {
unsigned long flags; unsigned long flags;
struct guid_entry *ge; struct node_entry *ge;
read_lock_irqsave(&guid_lock, flags); read_lock_irqsave(&node_lock, flags);
ge = find_entry(guid); ge = find_entry(guid);
if (ge) atomic_inc(&ge->refcount); if (ge) atomic_inc(&ge->refcount);
read_unlock_irqrestore(&guid_lock, flags); read_unlock_irqrestore(&node_lock, flags);
return ge; return ge;
} }
struct hpsb_host *hpsb_guid_localhost(struct guid_entry *ge) struct hpsb_host *hpsb_get_host_by_ge(struct node_entry *ge)
{ {
if (atomic_read(&ge->generation) != get_hpsb_generation()) return NULL; if (atomic_read(&ge->generation) != get_hpsb_generation()) return NULL;
if (ge->node_id == ge->host->node_id) return ge->host; if (ge->node_id == ge->host->node_id) return ge->host;
return NULL; return NULL;
} }
int hpsb_guid_fill_packet(struct guid_entry *ge, struct hpsb_packet *pkt) int hpsb_guid_fill_packet(struct node_entry *ge, struct hpsb_packet *pkt)
{ {
if (atomic_read(&ge->generation) != get_hpsb_generation()) return 0; if (atomic_read(&ge->generation) != get_hpsb_generation()) return 0;
...@@ -282,24 +224,168 @@ int hpsb_guid_fill_packet(struct guid_entry *ge, struct hpsb_packet *pkt) ...@@ -282,24 +224,168 @@ int hpsb_guid_fill_packet(struct guid_entry *ge, struct hpsb_packet *pkt)
return 1; return 1;
} }
static int nodemgr_reset_handler(void *__hi)
{
struct host_info *hi = (struct host_info *)__hi;
struct hpsb_host *host = hi->host;
/* Standard thread setup */
lock_kernel();
daemonize();
strcpy(current->comm, "NodeMngr");
unlock_kernel();
for (;;) {
if (signal_pending(current))
break;
/* Let's take a short pause to make sure all the devices
* have time to settle. */
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(HZ/50);
if (hi && host)
nodemgr_node_probe(host);
/* Wait for the next bus reset */
if (hi && host)
interruptible_sleep_on(&hi->reset_wait);
}
return(0);
}
static void nodemgr_add_host(struct hpsb_host *host)
{
struct host_info *hi = kmalloc (sizeof (struct host_info), GFP_KERNEL);
int flags;
if (!hi) {
HPSB_ERR ("Out of memory in Node Manager");
return;
}
hi->host = host;
INIT_LIST_HEAD(&hi->list);
hi->pid = -1;
init_waitqueue_head(&hi->reset_wait);
spin_lock_irqsave (&host_info_lock, flags);
list_add_tail (&hi->list, &host_info_list);
spin_unlock_irqrestore (&host_info_lock, flags);
return;
}
static void nodemgr_schedule_thread (void *__hi)
{
struct host_info *hi = (struct host_info *)__hi;
hi->pid = kernel_thread(nodemgr_reset_handler, hi,
CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
}
static void nodemgr_host_reset(struct hpsb_host *host)
{
struct list_head *lh;
struct host_info *hi = NULL;
int flags;
spin_lock_irqsave (&host_info_lock, flags);
lh = host_info_list.next;
while (lh != &host_info_list) {
struct host_info *myhi = list_entry(lh, struct host_info, list);
if (myhi->host == host) {
hi = myhi;
break;
}
lh = lh->next;
}
if (hi == NULL) {
HPSB_ERR ("Could not process reset of non-existent host in Node Manager");
goto done_reset_host;
}
if (hi->pid >= 0) {
wake_up(&hi->reset_wait);
} else {
if (in_interrupt()) {
static struct tq_struct task;
memset(&task, 0, sizeof(struct tq_struct));
task.routine = nodemgr_schedule_thread;
task.data = (void*)hi;
if (schedule_task(&task) < 0)
HPSB_ERR ("Failed to schedule Node Manager thread!\n");
} else {
nodemgr_schedule_thread(hi);
}
}
done_reset_host:
spin_unlock_irqrestore (&host_info_lock, flags);
return;
}
static void nodemgr_remove_host(struct hpsb_host *host)
{
struct list_head *lh;
struct host_info *hi = NULL;
int flags;
spin_lock_irqsave (&host_info_lock, flags);
lh = host_info_list.next;
while (lh != &host_info_list) {
struct host_info *myhi = list_entry(lh, struct host_info, list);
if (myhi->host == host) {
hi = myhi;
break;
}
lh = lh->next;
}
if (hi == NULL) {
HPSB_ERR ("Could not remove non-exitent host in Node Manager");
goto done_remove_host;
}
if (hi->pid >= 0)
kill_proc(hi->pid, SIGINT, 1);
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(HZ*2); /* 2 second delay */
kfree (hi);
done_remove_host:
spin_unlock_irqrestore (&host_info_lock, flags);
return;
}
static struct hpsb_highlevel_ops guid_ops = { static struct hpsb_highlevel_ops guid_ops = {
host_reset: host_reset, add_host: nodemgr_add_host,
host_reset: nodemgr_host_reset,
remove_host: nodemgr_remove_host,
}; };
static struct hpsb_highlevel *hl; static struct hpsb_highlevel *hl;
void init_ieee1394_guid(void) void init_ieee1394_nodemgr(void)
{ {
atomic_set(&outstanding_requests, 0); atomic_set(&outstanding_requests, 0);
hl = hpsb_register_highlevel("GUID manager", &guid_ops); hl = hpsb_register_highlevel("Node manager", &guid_ops);
if (!hl) { if (!hl) {
HPSB_ERR("out of memory during ieee1394 initialization"); HPSB_ERR("Out of memory during ieee1394 initialization");
} }
} }
void cleanup_ieee1394_guid(void) void cleanup_ieee1394_nodemgr(void)
{ {
hpsb_unregister_highlevel(hl); hpsb_unregister_highlevel(hl);
} }
/*
* Copyright (C) 2000 Andreas E. Bombe
* 2001 Ben Collins <bcollins@debian.org>
*
* 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.
*/
#ifndef _IEEE1394_GUID_H #ifndef _IEEE1394_NODEMGR_H
#define _IEEE1394_GUID_H #define _IEEE1394_NODEMGR_H
/* /*
...@@ -11,8 +29,8 @@ ...@@ -11,8 +29,8 @@
* associated with current nodes). * associated with current nodes).
*/ */
struct guid_entry; struct node_entry;
typedef struct guid_entry *hpsb_guid_t; typedef struct node_entry *hpsb_guid_t;
/* /*
...@@ -32,7 +50,7 @@ hpsb_guid_t hpsb_guid_get_handle(u64 guid); ...@@ -32,7 +50,7 @@ hpsb_guid_t hpsb_guid_get_handle(u64 guid);
* Note that the local GUID currently isn't collected, so this will always * Note that the local GUID currently isn't collected, so this will always
* return NULL. * return NULL.
*/ */
struct hpsb_host *hpsb_guid_localhost(hpsb_guid_t handle); struct hpsb_host *hpsb_get_host_by_ge(hpsb_guid_t handle);
/* /*
* This will fill in the given, pre-initialised hpsb_packet with the current * This will fill in the given, pre-initialised hpsb_packet with the current
...@@ -48,7 +66,7 @@ struct hpsb_host *hpsb_guid_localhost(hpsb_guid_t handle); ...@@ -48,7 +66,7 @@ struct hpsb_host *hpsb_guid_localhost(hpsb_guid_t handle);
int hpsb_guid_fill_packet(hpsb_guid_t handle, struct hpsb_packet *pkt); int hpsb_guid_fill_packet(hpsb_guid_t handle, struct hpsb_packet *pkt);
void init_ieee1394_guid(void); void init_ieee1394_nodemgr(void);
void cleanup_ieee1394_guid(void); void cleanup_ieee1394_nodemgr(void);
#endif /* _IEEE1394_GUID_H */ #endif /* _IEEE1394_NODEMGR_H */
...@@ -178,7 +178,7 @@ static struct pci_device_id ohci1394_pci_tbl[] __devinitdata = { ...@@ -178,7 +178,7 @@ static struct pci_device_id ohci1394_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl); MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
static char version[] __devinitdata = static char version[] __devinitdata =
"ohci1394.c:v0.50 15/Jul/01 Ben Collins <bcollins@debian.org>"; "v0.50 15/Jul/01 Ben Collins <bcollins@debian.org>";
/* Module Parameters */ /* Module Parameters */
MODULE_PARM(attempt_root,"i"); MODULE_PARM(attempt_root,"i");
...@@ -216,6 +216,7 @@ static u8 get_phy_reg(struct ti_ohci *ohci, u8 addr) ...@@ -216,6 +216,7 @@ static u8 get_phy_reg(struct ti_ohci *ohci, u8 addr)
for (i = 0; i < OHCI_LOOP_COUNT; i++) { for (i = 0; i < OHCI_LOOP_COUNT; i++) {
if (reg_read(ohci, OHCI1394_PhyControl) & 0x80000000) if (reg_read(ohci, OHCI1394_PhyControl) & 0x80000000)
break; break;
mdelay(1); mdelay(1);
} }
...@@ -243,6 +244,7 @@ static void set_phy_reg(struct ti_ohci *ohci, u8 addr, u8 data) ...@@ -243,6 +244,7 @@ static void set_phy_reg(struct ti_ohci *ohci, u8 addr, u8 data)
r = reg_read(ohci, OHCI1394_PhyControl); r = reg_read(ohci, OHCI1394_PhyControl);
if (!(r & 0x00004000)) if (!(r & 0x00004000))
break; break;
mdelay(1); mdelay(1);
} }
...@@ -516,22 +518,6 @@ static int ohci_initialize(struct hpsb_host *host) ...@@ -516,22 +518,6 @@ static int ohci_initialize(struct hpsb_host *host)
/* Set the configuration ROM mapping register */ /* Set the configuration ROM mapping register */
reg_write(ohci, OHCI1394_ConfigROMmap, ohci->csr_config_rom_bus); reg_write(ohci, OHCI1394_ConfigROMmap, ohci->csr_config_rom_bus);
/* Set bus options */
reg_write(ohci, OHCI1394_BusOptions,
cpu_to_be32(ohci->csr_config_rom_cpu[2]));
#if 0
/* Write the GUID into the csr config rom */
ohci->csr_config_rom_cpu[3] =
be32_to_cpu(reg_read(ohci, OHCI1394_GUIDHi));
ohci->csr_config_rom_cpu[4] =
be32_to_cpu(reg_read(ohci, OHCI1394_GUIDLo));
#endif
/* Write the config ROM header */
reg_write(ohci, OHCI1394_ConfigROMhdr,
cpu_to_be32(ohci->csr_config_rom_cpu[0]));
ohci->max_packet_size = ohci->max_packet_size =
1<<(((reg_read(ohci, OHCI1394_BusOptions)>>12)&0xf)+1); 1<<(((reg_read(ohci, OHCI1394_BusOptions)>>12)&0xf)+1);
PRINT(KERN_DEBUG, ohci->id, "Max packet size = %d bytes", PRINT(KERN_DEBUG, ohci->id, "Max packet size = %d bytes",
...@@ -725,7 +711,7 @@ static void insert_packet(struct ti_ohci *ohci, ...@@ -725,7 +711,7 @@ static void insert_packet(struct ti_ohci *ohci,
OHCI_DMA_ALLOC("single, block transmit packet"); OHCI_DMA_ALLOC("single, block transmit packet");
if (ohci->payload_swap) if (ohci->payload_swap)
block_swab32(packet->data, packet->data_size>>2); block_swab32(packet->data, packet->data_size >> 2);
d->prg_cpu[idx]->end.branchAddress = 0; d->prg_cpu[idx]->end.branchAddress = 0;
d->prg_cpu[idx]->end.status = 0; d->prg_cpu[idx]->end.status = 0;
...@@ -1897,6 +1883,9 @@ static void ohci_init_config_rom(struct ti_ohci *ohci) ...@@ -1897,6 +1883,9 @@ static void ohci_init_config_rom(struct ti_ohci *ohci)
cf_put_1quad(&cr, reg_read(ohci, OHCI1394_GUIDLo)); cf_put_1quad(&cr, reg_read(ohci, OHCI1394_GUIDLo));
cf_unit_end(&cr); cf_unit_end(&cr);
DBGMSG(ohci->id, "GUID: %08x:%08x\n", reg_read(ohci, OHCI1394_GUIDHi),
reg_read(ohci, OHCI1394_GUIDLo));
/* IEEE P1212 suggests the initial ROM header CRC should only /* IEEE P1212 suggests the initial ROM header CRC should only
* cover the header itself (and not the entire ROM). Since we use * cover the header itself (and not the entire ROM). Since we use
* this, then we can make our bus_info_len the same as the CRC * this, then we can make our bus_info_len the same as the CRC
...@@ -1991,6 +1980,7 @@ int ohci_compare_swap(struct ti_ohci *ohci, quadlet_t *data, ...@@ -1991,6 +1980,7 @@ int ohci_compare_swap(struct ti_ohci *ohci, quadlet_t *data,
for (i = 0; i < OHCI_LOOP_COUNT; i++) { for (i = 0; i < OHCI_LOOP_COUNT; i++) {
if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000)
break; break;
mdelay(10); mdelay(10);
} }
...@@ -2180,7 +2170,7 @@ static int __devinit ohci1394_add_one(struct pci_dev *dev, const struct pci_devi ...@@ -2180,7 +2170,7 @@ static int __devinit ohci1394_add_one(struct pci_dev *dev, const struct pci_devi
if (ohci->ir_context == NULL) if (ohci->ir_context == NULL)
FAIL("Failed to allocate IR context"); FAIL("Failed to allocate IR context");
ohci->ISO_channel_usage= 0; ohci->ISO_channel_usage = 0;
spin_lock_init(&ohci->IR_channel_lock); spin_lock_init(&ohci->IR_channel_lock);
if (!request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ, if (!request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ,
...@@ -2191,10 +2181,6 @@ static int __devinit ohci1394_add_one(struct pci_dev *dev, const struct pci_devi ...@@ -2191,10 +2181,6 @@ static int __devinit ohci1394_add_one(struct pci_dev *dev, const struct pci_devi
ohci_init_config_rom(ohci); ohci_init_config_rom(ohci);
DBGMSG(ohci->id, "The 1st byte at offset 0x404 is: 0x%02x",
*((char *)ohci->csr_config_rom_cpu+4));
/* Tell the highlevel this host is ready */ /* Tell the highlevel this host is ready */
highlevel_add_one_host (host); highlevel_add_one_host (host);
......
...@@ -1351,6 +1351,7 @@ static int add_card(struct pci_dev *dev) ...@@ -1351,6 +1351,7 @@ static int add_card(struct pci_dev *dev)
lynx->id = num_of_cards-1; lynx->id = num_of_cards-1;
lynx->dev = dev; lynx->dev = dev;
lynx->host->pdev = dev;
lynx->lock = SPIN_LOCK_UNLOCKED; lynx->lock = SPIN_LOCK_UNLOCKED;
lynx->phy_reg_lock = SPIN_LOCK_UNLOCKED; lynx->phy_reg_lock = SPIN_LOCK_UNLOCKED;
......
...@@ -1688,6 +1688,10 @@ int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1688,6 +1688,10 @@ int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
error = -EINVAL; error = -EINVAL;
if (is_subdir(new_dentry, old_dentry)) if (is_subdir(new_dentry, old_dentry))
goto out_unlock; goto out_unlock;
/* Don't eat your daddy, dear... */
/* This also avoids locking issues */
if (old_dentry->d_parent == new_dentry)
goto out_unlock;
target = new_dentry->d_inode; target = new_dentry->d_inode;
if (target) { /* Hastur! Hastur! Hastur! */ if (target) { /* Hastur! Hastur! Hastur! */
triple_down(&old_dir->i_zombie, triple_down(&old_dir->i_zombie,
......
...@@ -645,6 +645,20 @@ static int proc_base_readdir(struct file * filp, ...@@ -645,6 +645,20 @@ static int proc_base_readdir(struct file * filp,
/* building an inode */ /* building an inode */
static int task_dumpable(struct task_struct *task)
{
int dumpable = 0;
struct mm_struct *mm;
task_lock(task);
mm = task->mm;
if (mm)
dumpable = mm->dumpable;
task_unlock(task);
return dumpable;
}
static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino) static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino)
{ {
struct inode * inode; struct inode * inode;
...@@ -670,7 +684,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st ...@@ -670,7 +684,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
inode->u.proc_i.task = task; inode->u.proc_i.task = task;
inode->i_uid = 0; inode->i_uid = 0;
inode->i_gid = 0; inode->i_gid = 0;
if (ino == PROC_PID_INO || task->mm->dumpable) { if (ino == PROC_PID_INO || task_dumpable(task)) {
inode->i_uid = task->euid; inode->i_uid = task->euid;
inode->i_gid = task->egid; inode->i_gid = task->egid;
} }
......
...@@ -442,6 +442,7 @@ extern int make_pages_present(unsigned long addr, unsigned long end); ...@@ -442,6 +442,7 @@ extern int make_pages_present(unsigned long addr, unsigned long end);
extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char *dst, int len); extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char *dst, int len);
extern int ptrace_writedata(struct task_struct *tsk, char * src, unsigned long dst, int len); extern int ptrace_writedata(struct task_struct *tsk, char * src, unsigned long dst, int len);
extern int ptrace_attach(struct task_struct *tsk);
/* /*
* On a two-level page table, this ends up being trivial. Thus the * On a two-level page table, this ends up being trivial. Thus the
......
/* Common Flash Interface structures /* Common Flash Interface structures
* See http://support.intel.com/design/flash/technote/index.htm * See http://support.intel.com/design/flash/technote/index.htm
* $Id: cfi.h,v 1.21 2001/06/03 01:32:57 nico Exp $ * $Id: cfi.h,v 1.22 2001/07/06 09:29:07 dwmw2 Exp $
*/ */
#ifndef __MTD_CFI_H__ #ifndef __MTD_CFI_H__
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/mtd/flashchip.h> #include <linux/mtd/flashchip.h>
#include <linux/mtd/cfi_endian.h> #include <linux/mtd/cfi_endian.h>
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/in6.h> #include <linux/in6.h>
#include <linux/completion.h>
#include <asm/checksum.h> #include <asm/checksum.h>
#if defined(CONFIG_PROC_FS) #if defined(CONFIG_PROC_FS)
...@@ -362,6 +363,10 @@ EXPORT_SYMBOL(add_wait_queue); ...@@ -362,6 +363,10 @@ EXPORT_SYMBOL(add_wait_queue);
EXPORT_SYMBOL(add_wait_queue_exclusive); EXPORT_SYMBOL(add_wait_queue_exclusive);
EXPORT_SYMBOL(remove_wait_queue); EXPORT_SYMBOL(remove_wait_queue);
/* completion handling */
EXPORT_SYMBOL(wait_for_completion);
EXPORT_SYMBOL(complete);
/* The notion of irq probe/assignment is foreign to S/390 */ /* The notion of irq probe/assignment is foreign to S/390 */
#if !defined(CONFIG_ARCH_S390) #if !defined(CONFIG_ARCH_S390)
......
...@@ -16,6 +16,51 @@ ...@@ -16,6 +16,51 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
int ptrace_attach(struct task_struct *task)
{
task_lock(task);
if (task->pid <= 1)
goto bad;
if (task == current)
goto bad;
if (!task->mm)
goto bad;
if(((current->uid != task->euid) ||
(current->uid != task->suid) ||
(current->uid != task->uid) ||
(current->gid != task->egid) ||
(current->gid != task->sgid) ||
(!cap_issubset(task->cap_permitted, current->cap_permitted)) ||
(current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
goto bad;
rmb();
if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
goto bad;
/* the same process cannot be attached many times */
if (task->ptrace & PT_PTRACED)
goto bad;
/* Go */
task->ptrace |= PT_PTRACED;
task_unlock(task);
write_lock_irq(&tasklist_lock);
if (task->p_pptr != current) {
REMOVE_LINKS(task);
task->p_pptr = current;
SET_LINKS(task);
}
write_unlock_irq(&tasklist_lock);
send_sig(SIGSTOP, task, 1);
return 0;
bad:
task_unlock(task);
return -EPERM;
}
/* /*
* Access another process' address space, one page at a time. * Access another process' address space, one page at a time.
*/ */
......
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