Commit dfc52b82 authored by Linus Torvalds's avatar Linus Torvalds

v2.4.9.11 -> v2.4.9.12

  - Alan Cox: much more merging
  - Pete Zaitcev: ymfpci race fixes
  - Andrea Arkangeli: VM race fix and OOM tweak.
  - Arjan Van de Ven: merge RH kernel fixes
  - Andi Kleen: use more readable 'likely()/unlikely()' instead of __builtin_expect()
  - Keith Owens: fix 64-bit ELF types
  - Gerd Knorr: mark more broken PCI bridges, update btaudio driver
  - Paul Mackerras: powermac driver update
  - me: clean up PTRACE_DETACH to use common infrastructure
parent a880f45a
......@@ -48,7 +48,7 @@ necessary on all systems; obviously, if you don't have any PCMCIA (PC
Card) hardware, for example, you probably needn't concern yourself
with pcmcia-cs.
o Gnu C 2.91.66 # gcc --version
o Gnu C 2.95.3 # gcc --version
o Gnu make 3.77 # make --version
o binutils 2.9.1.0.25 # ld -v
o util-linux 2.10o # fdformat --version
......@@ -70,17 +70,23 @@ computer. The next paragraph applies to users of x86 CPUs, but not
necessarily to users of other CPUs. Users of other CPUs should obtain
information about their gcc version requirements from another source.
The recommended compiler for the kernel is egcs 1.1.2 (gcc 2.91.66), and it
should be used when you need absolute stability. You may use gcc 2.95.x
instead if you wish, although it may cause problems. Later versions of gcc
have not received much testing for Linux kernel compilation, and there are
The recommended compiler for the kernel is gcc 2.95.3 or .4, and it
should be used when you need absolute stability. You may use gcc 3.0.x
instead if you wish, although it may cause problems. Later versions of gcc
have not received much testing for Linux kernel compilation, and there are
almost certainly bugs (mainly, but not exclusively, in the kernel) that
will need to be fixed in order to use these compilers. In any case, using
pgcc instead of egcs or plain gcc is just asking for trouble.
Note that gcc 2.7.2.3 is no longer a supported kernel compiler. The kernel
no longer works around bugs in gcc 2.7.2.3 and, in fact, will refuse to
be compiled with it.
be compiled with it. egcs-1.1.2 has register allocation problems in very
obscure cases. We have ensured the kernel does not trip these in any known
situation. The 2.5 tree is likely to drop egcs-1.1.2 workarounds.
The Red Hat gcc 2.96 compiler subtree can also be used to build this tree.
You should ensure you use gcc-2.96-74 or later. gcc-2.96-54 will not build
the kernel correctly.
In addition, please pay attention to compiler optimization. Anything
greater than -O2 may not be wise. Similarly, if you choose to use gcc-2.95.x
......
Is your SMP system locking up unpredictably? No keyboard activity, just
Is your ix86 system locking up unpredictably? No keyboard activity, just
a frustrating complete hard lockup? Do you want to help us debugging
such lockups? If all yes then this document is definitely for you.
on Intel SMP hardware there is a feature that enables us to generate
'watchdog NMI interrupts'. (NMI: Non Maskable Interrupt - these get
executed even if the system is otherwise locked up hard) This can be
used to debug hard kernel lockups. By executing periodic NMI interrupts,
the kernel can monitor whether any CPU has locked up, and print out
debugging messages if so. You can enable/disable the NMI watchdog at boot
time with the 'nmi_watchdog=1' boot parameter. Eg. the relevant
lilo.conf entry:
On Intel and similar ix86 type hardware there is a feature that enables
us to generate 'watchdog NMI interrupts'. (NMI: Non Maskable Interrupt
which get executed even if the system is otherwise locked up hard).
This can be used to debug hard kernel lockups. By executing periodic
NMI interrupts, the kernel can monitor whether any CPU has locked up,
and print out debugging messages if so. You must enable the NMI
watchdog at boot time with the 'nmi_watchdog=n' boot parameter. Eg.
the relevant lilo.conf entry:
append="nmi_watchdog=1"
For SMP machines and UP machines with an IO-APIC use nmi_watchdog=1.
For UP machines without an IO-APIC use nmi_watchdog=2, this only works
for some processor types. If in doubt, boot with nmi_watchdog=1 and
check the NMI count in /proc/interrupts; if the count is zero then
reboot with nmi_watchdog=2 and check the NMI count. If it is still
zero then log a problem, you probably have a processor that needs to be
added to the nmi code.
A 'lockup' is the following scenario: if any CPU in the system does not
execute the period local timer interrupt for more than 5 seconds, then
the NMI handler generates an oops and kills the process. This
......@@ -24,8 +32,9 @@ then the system has crashed so hard (eg. hardware-wise) that either it
cannot even accept NMI interrupts, or the crash has made the kernel
unable to print messages.
NOTE: currently the NMI-oopser is enabled unconditionally on x86 SMP
boxes.
NOTE: starting with 2.4.2-ac18 the NMI-oopser is disabled by default,
you have to enable it with a boot time parameter. Prior to 2.4.2-ac18
the NMI-oopser is enabled unconditionally on x86 SMP boxes.
[ feel free to send bug reports, suggestions and patches to
Ingo Molnar <mingo@redhat.com> or the Linux SMP mailing
......
......@@ -31,23 +31,28 @@ Still somewhat experimental. The driver should work stable, i.e. it
should'nt crash your box. It might not work as expected, have bugs,
not being fully OSS API compilant, ...
Latest versions are available from http://bytesex.org/bttv/, the
driver is in the bttv tarball. Kernel patches might be available too,
have a look at http://bytesex.org/bttv/listing.html.
The chip knows two different modes. btaudio registers two dsp
devices, one for each mode. They can not be used at the same time.
Digital audio mode
==================
The chip knows different modes. Right now you have to pick the one you
want to use at insmod time. Digital audio mode is the default. The
chip gives you 16 bit stereo sound with ~32 kHz sample rate. According
to the specs it should be possible to get up to 48 kHz, but I havn't
figured out yet how this works. The specs are not very verbose :-(
The chip gives you 16 bit stereo sound. The sample rate depends on
the external source which feeds the bt878 with digital sound via I2S
interface. There is a insmod option (rate) to tell the driver which
sample rate the hardware uses (32000 is the default).
Lower sample rates are possible too, but the code isn't written yet.
For now you are limited to the fixed 32 kHz. Mono works throuth, the
driver will do that in software for you.
One possible source for digital sound is the msp34xx audio processor
chip which provides digital sound via I2S with 32 kHz sample rate. My
Hauppauge board works this way.
With my Hauppauge I get clear sound, but I got also reports saying that
digital audio mode does'nt work. Guess Hauppauge connected the msp34xx
output to the bt878's I2S digital audio input port.
The Osprey-200 reportly gives you digital sound with 44100 Hz sample
rate. It is also possible that you get no sound at all.
analog mode (A/D)
......@@ -67,11 +72,17 @@ With my Hauppauge I get noisy sound on the second input (mapped to line2
by the mixer device). Others get a useable signal on line1.
more hints
==========
some examples
=============
* read audio data from btaudio (dsp2), send to es1730 (dsp,dsp1):
$ sox -w -r 32000 -t ossdsp /dev/dsp2 -t ossdsp /dev/dsp
* read audio data from btaudio, send to esound daemon (which might be
running on another host):
$ sox -c 2 -w -r 32000 -t ossdsp /dev/dsp2 -t sw - | esdcat -r 32000
$ sox -c 1 -w -r 32000 -t ossdsp /dev/dsp2 -t sw - | esdcat -m -r 32000
/me uses "sox -w -r 32000 -t ossdsp /dev/dsp2 -t ossdsp /dev/dsp"
to dump audio data from btaudio (dsp2) to es1730 (dsp,dsp1).
Have fun,
......
Linux Magic System Request Key Hacks
Documentation for sysrq.c version 1.15
Last update: $Date: 2001/01/28 10:15:59 $
MAGIC SYSRQ KEY DOCUMENTATION v1.32
------------------------------------
[Sat Apr 8 22:15:03 CEST 2000]
* What is the magic SysRQ key?
* What is the magic SysRq key?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It is a 'magical' key combo you can hit which kernel will respond to
It is a 'magical' key combo you can hit which the kernel will respond to
regardless of whatever else it is doing, unless it is completely locked up.
* How do I enable the magic SysRQ key?
* How do I enable the magic SysRq key?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You need to say "yes" to 'Magic SysRq key (CONFIG_MAGIC_SYSRQ)' when
configuring the kernel. This option is only available in 2.1.x or later
kernels. Once you boot the new kernel, you need to enable it manually
using following command:
configuring the kernel. When running on a kernel with SysRq compiled in, it
may be DISABLED at run-time using following command:
echo "0" > /proc/sys/kernel/sysrq
echo "1" > /proc/sys/kernel/sysrq
Note that previous versions disabled sysrq by default, and you were required
to specifically enable it at run-time. That is not the case any longer.
* How do I use the magic SysRQ key?
* How do I use the magic SysRq key?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On x86 - You press the key combo 'ALT-SysRQ-<command key>'. Note - Some
(older?) may not have a key labeled 'SysRQ'. The 'SysRQ' key is
On x86 - You press the key combo 'ALT-SysRq-<command key>'. Note - Some
keyboards may not have a key labeled 'SysRq'. The 'SysRq' key is
also known as the 'Print Screen' key.
On SPARC - You press 'ALT-STOP-<command key>', I believe.
......@@ -33,14 +34,14 @@ On PowerPC - Press 'ALT - Print Screen (or F13) - <command key>,
Print Screen (or F13) - <command key> may suffice.
On other - If you know of the key combos for other architectures, please
let me know so I can add them to this section.
let me know so I can add them to this section.
* What are the 'command' keys?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'r' - Turns off keyboard raw mode and sets it to XLATE.
'k' - Secure Access Key (SAK) Kills all programs on the current virtual
console. NOTE: See important comments below in SAK section.
'k' - Secure Access Key (SAK) Kills all programs on the current virtual
console. NOTE: See important comments below in SAK section.
'b' - Will immediately reboot the system without syncing or unmounting
your disks.
......@@ -70,8 +71,8 @@ On other - If you know of the key combos for other architectures, please
'l' - Send a SIGKILL to all processes, INCLUDING init. (Your system
will be non-functional after this.)
'h' - Will display help ( actually any other key than those listed
above will display help. but 'h' is easy to remember :-)
'h' - Will display help ( actually any other key than those listed
above will display help. but 'h' is easy to remember :-)
* Okay, so what can I use them for?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
......@@ -83,8 +84,8 @@ when you would try to login. It will kill all programs on given console
and thus letting you make sure that the login prompt you see is actually
the one from init, not some trojan program.
IMPORTANT:In its true form it is not a true SAK like the one in :IMPORTANT
IMPORTATN:c2 compliant systems, and it should be mistook as such. :IMPORTANT
It seems other find it useful as (System Attention Key) which is
IMPORTANT:c2 compliant systems, and it should be mistook as such. :IMPORTANT
It seems other find it useful as (System Attention Key) which is
useful when you want to exit a program that will not let you switch consoles.
(For example, X or a svgalib program.)
......@@ -93,7 +94,7 @@ and 'U'mount first.
'S'ync is great when your system is locked up, it allows you to sync your
disks and will certainly lessen the chance of data loss and fscking. Note
that the sync hasn't taken place until you see the "OK" and "Done" appear
that the sync hasn't taken place until you see the "OK" and "Done" appear
on the screen. (If the kernel is really in strife, you may not ever get the
OK or Done message...)
......@@ -111,30 +112,72 @@ t'E'rm and k'I'll are useful if you have some sort of runaway process you
are unable to kill any other way, especially if it's spawning other
processes.
* Sometimes SysRQ seems to get 'stuck' after using it, what can I do?
* Sometimes SysRq seems to get 'stuck' after using it, what can I do?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
That happens to me, also. I've found that tapping shift, alt, and control
on both sides of the keyboard, and hitting an invalid sysrq sequence again
will fix the problem. (ie, something like alt-sysrq-z). Switching to another
virtual console (ALT+Fn) and then back again should also help.
* I hit SysRQ, but nothing seems to happen, what's wrong?
* I hit SysRq, but nothing seems to happen, what's wrong?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There are some keyboards that send different scancodes for SysRQ than the
pre-defined 0x54. So if SysRQ doesn't work out of the box for a certain
keyboard, run 'showkey -s' to find out the proper scancode sequence. Then
use 'setkeycodes <sequence> 84' to define this sequence to the usual SysRQ
There are some keyboards that send different scancodes for SysRq than the
pre-defined 0x54. So if SysRq doesn't work out of the box for a certain
keyboard, run 'showkey -s' to find out the proper scancode sequence. Then
use 'setkeycodes <sequence> 84' to define this sequence to the usual SysRq
code (84 is decimal for 0x54). It's probably best to put this command in a
boot script. Oh, and by the way, you exit 'showkey' by not typing anything
boot script. Oh, and by the way, you exit 'showkey' by not typing anything
for ten seconds.
* I want to add SysRQ key events to a module, how does it work?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In order to register a basic function with the table, you must first include
the header 'include/linux/sysrq.h', this will define everything else you need.
Next, you must create a sysrq_key_op struct, and populate it with A) the key
handler function you will use, B) a help_msg string, that will print when SysRQ
prints help, and C) an action_msg string, that will print right before your
handler is called. Your handler must conform to the protoype in 'sysrq.h'.
After the sysrq_key_op is created, you can call the macro
register_sysrq_key(int key, struct sysrq_key_op *op_p) that is defined in
sysrq.h, this will register the operation pointed to by 'op_p' at table
key 'key', if that slot in the table is blank. At module unload time, you must
call the macro unregister_sysrq_key(int key, struct sysrq_key_op *op_p), which
will remove the key op pointed to by 'op_p' from the key 'key', if and only if
it is currently registered in that slot. This is in case the slot has been
overwritten since you registered it.
The Magic SysRQ system works by registering key operations against a key op
lookup table, which is defined in 'drivers/char/sysrq.c'. This key table has
a number of operations registered into it at compile time, but is mutable,
and 4 functions are exported for interface to it: __sysrq_lock_table,
__sysrq_unlock_table, __sysrq_get_key_op, and __sysrq_put_key_op. The
functions __sysrq_swap_key_ops and __sysrq_swap_key_ops_nolock are defined
in the header itself, and the REGISTER and UNREGISTER macros are built fromi
these. More complex (and dangerous!) manipulations of the table are possible
using these functions, but you must be careful to always lock the table before
you read or write from it, and to unlock it again when you are done. (And of
course, to never ever leave an invalid pointer in the table). Null pointers in
the table are always safe :)
If for some reason you feel the need to call the handle_sysrq function from
within a function called by handle_sysrq, you must be aware that you are in
a lock (you are also in an interupt handler, which means don't sleep!), so
you must call __handle_sysrq_nolock instead.
* I have more questions, who can I ask?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You may feel free to send email to myrdraal@deathsdoor.com, and I will
respond as soon as possible.
respond as soon as possible.
-Myrdraal
And I'll answer any questions about the registration system you got, also
responding as soon as possible.
-Crutcher
* Credits
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Written by Mydraal <myrdraal@deathsdoor.com>
Updated by Adam Sulmicki <adam@cfar.umd.edu>
Updated by Jeremy M. Dolan <jmd@turbogeek.org> 2001/01/28 10:15:59
Added to by Crutcher Dunnavant <crutcher+kernel@datastacks.com>
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 10
EXTRAVERSION =-pre11
EXTRAVERSION =-pre12
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
......@@ -228,7 +228,9 @@ MRPROPER_FILES = \
.menuconfig.log \
include/asm \
.hdepend scripts/mkdep scripts/split-include scripts/docproc \
$(TOPDIR)/include/linux/modversions.h
$(TOPDIR)/include/linux/modversions.h \
kernel.spec
# directories removed with 'make mrproper'
MRPROPER_DIRS = \
include/config \
......@@ -252,7 +254,7 @@ Version: dummy
boot: vmlinux
@$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C arch/$(ARCH)/boot
vmlinux: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o \
--start-group \
$(CORE_FILES) \
......@@ -297,11 +299,7 @@ $(TOPDIR)/include/linux/version.h: include/linux/version.h
$(TOPDIR)/include/linux/compile.h: include/linux/compile.h
newversion:
@if [ ! -f .version ]; then \
echo 1 > .version; \
else \
expr 0`cat .version` + 1 > .version; \
fi
. scripts/mkversion > .version
include/linux/compile.h: $(CONFIGURATION) include/linux/version.h newversion
@echo -n \#define UTS_VERSION \"\#`cat .version` > .ver
......@@ -423,7 +421,8 @@ mrproper: clean archmrproper
$(MAKE) -C Documentation/DocBook mrproper
distclean: mrproper
rm -f core `find . \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
rm -f core `find . \( -not -type d \) -and \
\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
-o -name '.*.rej' -o -name '.SUMS' -o -size 0 \) -type f -print` TAGS tags
......@@ -506,3 +505,30 @@ scripts/mkdep: scripts/mkdep.c
scripts/split-include: scripts/split-include.c
$(HOSTCC) $(HOSTCFLAGS) -o scripts/split-include scripts/split-include.c
#
# RPM target
#
# If you do a make spec before packing the tarball you can rpm -ta it
#
spec:
. scripts/mkspec >kernel.spec
#
# Build a tar ball, generate an rpm from it and pack the result
# There arw two bits of magic here
# 1) The use of /. to avoid tar packing just the symlink
# 2) Removing the .dep files as they have source paths in them that
# will become invalid
#
rpm: clean spec
find . \( -size 0 -o -name .depend -o -name .hdepend \) -type f -print | xargs rm -f
set -e; \
cd $(TOPDIR)/.. ; \
ln -sf $(TOPDIR) $(KERNELPATH) ; \
tar -cvz --exclude CVS -f $(KERNELPATH).tar.gz $(KERNELPATH)/. ; \
rm $(KERNELPATH) ; \
cd $(TOPDIR) ; \
. scripts/mkversion > .version ; \
rpm -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
rm $(TOPDIR)/../$(KERNELPATH).tar.gz
......@@ -233,6 +233,16 @@ ptrace_cancel_bpt(struct task_struct * child)
return (nsaved != 0);
}
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure the single step bit is not set.
*/
void ptrace_disable(struct task_struct *child)
{
ptrace_cancel_bpt(child);
}
asmlinkage long
sys_ptrace(long request, long pid, long addr, long data,
int a4, int a5, struct pt_regs regs)
......@@ -362,21 +372,8 @@ sys_ptrace(long request, long pid, long addr, long data,
ret = 0;
goto out;
case PTRACE_DETACH: /* detach a process that was attached. */
ret = -EIO;
if ((unsigned long) data > _NSIG)
goto out;
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
wake_up_process(child);
child->exit_code = data;
write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irq(&tasklist_lock);
/* make sure single-step breakpoint is gone. */
ptrace_cancel_bpt(child);
ret = 0;
case PTRACE_DETACH: /* detach a process that was attached. */
ret = ptrace_detach(child, data);
goto out;
default:
......
......@@ -386,6 +386,16 @@ void __ptrace_cancel_bpt(struct task_struct *child)
}
}
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure the single step bit is not set.
*/
void ptrace_disable(struct task_struct *child)
{
__ptrace_cancel_bpt(child);
}
static int do_ptrace(int request, struct task_struct *child, long addr, long data)
{
unsigned long tmp;
......@@ -491,20 +501,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
* detach a process that was attached.
*/
case PTRACE_DETACH:
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irq(&tasklist_lock);
/* make sure single-step breakpoint is gone. */
__ptrace_cancel_bpt(child);
wake_up_process (child);
ret = 0;
ret = ptrace_detach(child, data);
break;
/*
......
......@@ -82,6 +82,16 @@ static inline int put_reg(struct task_struct *task, unsigned int regno,
return 0;
}
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure the single step bit is not set.
*/
void ptrace_disable(struct task_struct *child)
{
/* Todo - pending singlesteps? */
}
/* Note that this implementation of ptrace behaves differently from vanilla
* ptrace. Contrary to what the man page says, in the PTRACE_PEEKTEXT,
* PTRACE_PEEKDATA, and PTRACE_PEEKUSER requests the data variable is not
......@@ -245,24 +255,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
break;
}
case PTRACE_DETACH: { /* detach a process that was attached. */
long tmp;
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
child->ptrace &= ~(PT_PTRACED | PT_TRACESYS);
child->exit_code = data;
write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irq(&tasklist_lock);
/* TODO: make sure any pending breakpoint is killed */
wake_up_process(child);
ret = 0;
case PTRACE_DETACH:
ret = ptrace_detach(child, data);
break;
}
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
int i;
......
......@@ -186,7 +186,10 @@ mainmenu_option next_comment
comment 'General setup'
bool 'Networking support' CONFIG_NET
bool 'SGI Visual Workstation support' CONFIG_VISWS
# Visual Workstation support is utterly broken.
# If you want to see it working mail an VW540 to hch@infradead.org 8)
#bool 'SGI Visual Workstation support' CONFIG_VISWS
if [ "$CONFIG_VISWS" = "y" ]; then
define_bool CONFIG_X86_VISWS_APIC y
define_bool CONFIG_X86_LOCAL_APIC y
......@@ -388,6 +391,13 @@ fi
mainmenu_option next_comment
comment 'Kernel hacking'
#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
bool ' Debug memory allocations' CONFIG_DEBUG_SLAB
bool ' Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
bool ' Magic SysRq key' CONFIG_MAGIC_SYSRQ
bool ' Spinlock debugging' CONFIG_DEBUG_SPINLOCK
bool ' Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE
fi
endmenu
......@@ -65,7 +65,6 @@ CONFIG_HAVE_DEC_LOCK=y
# General setup
#
CONFIG_NET=y
# CONFIG_VISWS is not set
CONFIG_X86_IO_APIC=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_PCI=y
......@@ -255,6 +254,9 @@ CONFIG_IDEDMA_AUTO=y
# CONFIG_IDEDMA_IVB is not set
# CONFIG_DMA_NONPCI is not set
CONFIG_BLK_DEV_IDE_MODES=y
# CONFIG_BLK_DEV_ATARAID is not set
# CONFIG_BLK_DEV_ATARAID_PDC is not set
# CONFIG_BLK_DEV_ATARAID_HPT is not set
#
# SCSI support
......@@ -378,7 +380,6 @@ CONFIG_DUMMY=m
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_ARM_AM79C961A is not set
# CONFIG_SUNLANCE is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNBMAC is not set
......@@ -400,8 +401,6 @@ CONFIG_NET_PCI=y
# CONFIG_APRICOT is not set
# CONFIG_CS89x0 is not set
# CONFIG_TULIP is not set
# CONFIG_TULIP_MWI is not set
# CONFIG_TULIP_MMIO is not set
# CONFIG_DE4X5 is not set
# CONFIG_DGRS is not set
# CONFIG_DM9102 is not set
......@@ -428,9 +427,9 @@ CONFIG_EEPRO100=y
# Ethernet (1000 Mbit)
#
# CONFIG_ACENIC is not set
# CONFIG_ACENIC_OMIT_TIGON_I is not set
# CONFIG_DL2K is not set
# CONFIG_MYRI_SBUS is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_SK98LIN is not set
......@@ -468,6 +467,7 @@ CONFIG_PCMCIA_PCNET=y
# CONFIG_PCMCIA_XIRC2PS is not set
# CONFIG_ARCNET_COM20020_CS is not set
# CONFIG_PCMCIA_IBMTR is not set
# CONFIG_PCMCIA_XIRCOM is not set
# CONFIG_PCMCIA_XIRTULIP is not set
CONFIG_NET_PCMCIA_RADIO=y
CONFIG_PCMCIA_RAYCS=y
......@@ -774,4 +774,4 @@ CONFIG_USB_STORAGE=y
#
# Kernel hacking
#
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_DEBUG_KERNEL is not set
......@@ -30,15 +30,15 @@ obj-y += pci-pc.o pci-irq.o
endif
endif
obj-$(CONFIG_MCA) += mca.o
obj-$(CONFIG_MTRR) += mtrr.o
obj-$(CONFIG_X86_MSR) += msr.o
obj-$(CONFIG_X86_CPUID) += cpuid.o
obj-$(CONFIG_MICROCODE) += microcode.o
obj-$(CONFIG_APM) += apm.o
obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o
obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o
obj-$(CONFIG_MCA) += mca.o
obj-$(CONFIG_MTRR) += mtrr.o
obj-$(CONFIG_X86_MSR) += msr.o
obj-$(CONFIG_X86_CPUID) += cpuid.o
obj-$(CONFIG_MICROCODE) += microcode.o
obj-$(CONFIG_APM) += apm.o
obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o
obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o apic.o nmi.o
obj-$(CONFIG_X86_IO_APIC) += io_apic.o
obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o
include $(TOPDIR)/Rules.make
This diff is collapsed.
......@@ -148,6 +148,10 @@
* 1.14: Make connection version persist across module unload/load.
* Enable and engage power management earlier.
* Disengage power management on module unload.
* Changed to use the sysrq-register hack for registering the
* power off function called by magic sysrq based upon discussions
* in irc://irc.openprojects.net/#kernelnewbies
* (Crutcher Dunnavant <crutcher+kernel@datastacks.com>).
* Make CONFIG_APM_REAL_MODE_POWER_OFF run time configurable.
* (Arjan van de Ven <arjanv@redhat.com>) modified by sfr.
* Work around byte swap bug in one of the Vaio's BIOS's
......@@ -197,12 +201,11 @@
#include <asm/uaccess.h>
#include <asm/desc.h>
#include <linux/sysrq.h>
extern unsigned long get_cmos_time(void);
extern void machine_real_restart(unsigned char *, int);
#ifdef CONFIG_MAGIC_SYSRQ
extern void (*sysrq_power_off)(void);
#endif
#if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
extern int (*console_blank_hook)(int);
#endif
......@@ -686,6 +689,23 @@ static void apm_power_off(void)
(void) apm_set_power_state(APM_STATE_OFF);
}
#ifdef CONFIG_MAGIC_SYSRQ
/*
* Magic sysrq key and handler for the power off function
*/
void handle_poweroff (int key, struct pt_regs *pt_regs,
struct kbd_struct *kbd, struct tty_struct *tty) {
apm_power_off();
}
struct sysrq_key_op sysrq_poweroff_op = {
handler: handle_poweroff,
help_msg: "Off",
action_msg: "Power Off\n"
};
#endif
#ifdef CONFIG_APM_DO_ENABLE
static int apm_enable_power_management(int enable)
{
......@@ -1544,9 +1564,8 @@ static int apm(void *unused)
/* Install our power off handler.. */
if (power_off)
pm_power_off = apm_power_off;
#ifdef CONFIG_MAGIC_SYSRQ
sysrq_power_off = apm_power_off;
#endif
register_sysrq_key('o',&sysrq_poweroff_op);
if (smp_num_cpus == 1) {
#if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
console_blank_hook = apm_console_blank;
......@@ -1761,9 +1780,7 @@ static void __exit apm_exit(void)
}
misc_deregister(&apm_device);
remove_proc_entry("apm", NULL);
#ifdef CONFIG_MAGIC_SYSRQ
sysrq_power_off = NULL;
#endif
unregister_sysrq_key('o',&sysrq_poweroff_op);
if (power_off)
pm_power_off = NULL;
exit_kapmd = 1;
......
This diff is collapsed.
......@@ -165,3 +165,13 @@ EXPORT_SYMBOL(empty_zero_page);
#ifdef CONFIG_HAVE_DEC_LOCK
EXPORT_SYMBOL(atomic_dec_and_lock);
#endif
#ifdef CONFIG_DEBUG_BUGVERBOSE
EXPORT_SYMBOL(do_BUG);
#endif
#if defined(CONFIG_SONYPI) || defined(CONFIG_SONYPI_MODULE)
extern int is_sony_vaio_laptop;
EXPORT_SYMBOL(is_sony_vaio_laptop);
#endif
......@@ -20,6 +20,7 @@
#include <asm/pgtable.h>
#include <asm/delay.h>
#include <asm/desc.h>
#include <asm/apic.h>
#include <linux/irq.h>
......@@ -415,6 +416,9 @@ void __init init_ISA_irqs (void)
{
int i;
#ifdef CONFIG_X86_LOCAL_APIC
init_bsp_APIC();
#endif
init_8259A(0);
for (i = 0; i < NR_IRQS; i++) {
......
......@@ -33,25 +33,17 @@
#include <asm/smp.h>
#include <asm/desc.h>
#undef APIC_LOCKUP_DEBUG
#define APIC_LOCKUP_DEBUG
static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
/*
* # of IO-APICs and # of IRQ routing registers
* # of IRQ routing registers
*/
int nr_ioapics;
int nr_ioapic_registers[MAX_IO_APICS];
/* I/O APIC entries */
struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
/* # of MP IRQ source entries */
struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
/* MP IRQ source entries */
int mp_irq_entries;
#if CONFIG_SMP
# define TARGET_CPUS cpu_online_map
#else
......@@ -754,11 +746,9 @@ void __init print_IO_APIC(void)
printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)&reg_01);
printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.entries);
if ( (reg_01.entries != 0x0f) && /* older (Neptune) boards */
(reg_01.entries != 0x11) &&
(reg_01.entries != 0x17) && /* typical ISA+PCI boards */
(reg_01.entries != 0x1b) && /* Compaq Proliant boards */
(reg_01.entries != 0x1f) && /* dual Xeon boards */
(reg_01.entries != 0x20) &&
(reg_01.entries != 0x22) && /* bigger Xeon boards */
(reg_01.entries != 0x2E) &&
(reg_01.entries != 0x3F)
......@@ -769,7 +759,8 @@ void __init print_IO_APIC(void)
if ( (reg_01.version != 0x01) && /* 82489DX IO-APICs */
(reg_01.version != 0x10) && /* oldest IO-APICs */
(reg_01.version != 0x11) && /* Pentium/Pro IO-APICs */
(reg_01.version != 0x13) /* Xeon IO-APICs */
(reg_01.version != 0x13) && /* Xeon IO-APICs */
(reg_01.entries != 0x20) /* Intel P64H (82806 AA) */
)
UNEXPECTED_IO_APIC();
if (reg_01.__reserved_1 || reg_01.__reserved_2)
......@@ -820,7 +811,7 @@ void __init print_IO_APIC(void)
continue;
printk(KERN_DEBUG "IRQ%d ", i);
for (;;) {
printk("-> %d", entry->pin);
printk("-> %d:%d", entry->apic, entry->pin);
if (!entry->next)
break;
entry = irq_2_pin + entry->next;
......@@ -1128,25 +1119,6 @@ static int __init timer_irq_works(void)
return 0;
}
static int __init nmi_irq_works(void)
{
irq_cpustat_t tmp[NR_CPUS];
int j, cpu;
memcpy(tmp, irq_stat, sizeof(tmp));
sti();
mdelay(50);
for (j = 0; j < smp_num_cpus; j++) {
cpu = cpu_logical_map(j);
if (nmi_count(cpu) - tmp[cpu].__nmi_count <= 3) {
printk(KERN_WARNING "CPU#%d NMI appears to be stuck.\n", cpu);
return 0;
}
}
return 1;
}
/*
* In the SMP+IOAPIC case it might happen that there are an unspecified
* number of pending IRQ events unhandled. These cases are very rare,
......@@ -1236,6 +1208,7 @@ static unsigned int startup_level_ioapic_irq (unsigned int irq)
static void end_level_ioapic_irq (unsigned int irq)
{
unsigned long v;
int i;
/*
* It appears there is an erratum which affects at least version 0x11
......@@ -1256,11 +1229,12 @@ static void end_level_ioapic_irq (unsigned int irq)
* operation to prevent an edge-triggered interrupt escaping meanwhile.
* The idea is from Manfred Spraul. --macro
*/
v = apic_read(APIC_TMR + ((IO_APIC_VECTOR(irq) & ~0x1f) >> 1));
i = IO_APIC_VECTOR(irq);
v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
ack_APIC_irq();
if (!(v & (1 << (IO_APIC_VECTOR(irq) & 0x1f)))) {
if (!(v & (1 << (i & 0x1f)))) {
#ifdef APIC_MISMATCH_DEBUG
atomic_inc(&irq_mis_count);
#endif
......@@ -1524,7 +1498,7 @@ static inline void check_timer(void)
pin1 = find_isa_irq_pin(0, mp_INT);
pin2 = find_isa_irq_pin(0, mp_ExtINT);
printk(KERN_INFO "..TIMER: vector=%02X pin1=%d pin2=%d\n", vector, pin1, pin2);
printk(KERN_INFO "..TIMER: vector=0x%02X pin1=%d pin2=%d\n", vector, pin1, pin2);
if (pin1 != -1) {
/*
......@@ -1532,11 +1506,11 @@ static inline void check_timer(void)
*/
unmask_IO_APIC_irq(0);
if (timer_irq_works()) {
if (nmi_watchdog) {
if (nmi_watchdog == NMI_IO_APIC) {
disable_8259A_irq(0);
setup_nmi();
enable_8259A_irq(0);
nmi_irq_works();
check_nmi_watchdog();
}
return;
}
......@@ -1553,9 +1527,9 @@ static inline void check_timer(void)
setup_ExtINT_IRQ0_pin(pin2, vector);
if (timer_irq_works()) {
printk("works.\n");
if (nmi_watchdog) {
if (nmi_watchdog == NMI_IO_APIC) {
setup_nmi();
nmi_irq_works();
check_nmi_watchdog();
}
return;
}
......@@ -1636,19 +1610,3 @@ void __init setup_IO_APIC(void)
check_timer();
print_IO_APIC();
}
#ifndef CONFIG_SMP
/*
* This initializes the IO-APIC and APIC hardware if this is
* a UP kernel.
*/
void IO_APIC_init_uniprocessor (void)
{
if (!smp_found_config)
return;
connect_bsp_APIC();
setup_local_APIC();
setup_IO_APIC();
setup_APIC_clocks();
}
#endif
......@@ -166,7 +166,7 @@ int get_irq_list(char *buf)
p += sprintf(p, "%10u ",
nmi_count(cpu_logical_map(j)));
p += sprintf(p, "\n");
#if CONFIG_SMP
#if CONFIG_X86_LOCAL_APIC
p += sprintf(p, "LOC: ");
for (j = 0; j < smp_num_cpus; j++)
p += sprintf(p, "%10u ",
......@@ -471,14 +471,15 @@ int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction *
* disable_irq_nosync - disable an irq without waiting
* @irq: Interrupt to disable
*
* Disable the selected interrupt line. Disables of an interrupt
* stack. Unlike disable_irq(), this function does not ensure existing
* Disable the selected interrupt line. Disables and Enables are
* nested.
* Unlike disable_irq(), this function does not ensure existing
* instances of the IRQ handler have completed before returning.
*
* This function may be called from IRQ context.
*/
void inline disable_irq_nosync(unsigned int irq)
inline void disable_irq_nosync(unsigned int irq)
{
irq_desc_t *desc = irq_desc + irq;
unsigned long flags;
......@@ -495,9 +496,9 @@ void inline disable_irq_nosync(unsigned int irq)
* disable_irq - disable an irq and wait for completion
* @irq: Interrupt to disable
*
* Disable the selected interrupt line. Disables of an interrupt
* stack. That is for two disables you need two enables. This
* function waits for any pending IRQ handlers for this interrupt
* Disable the selected interrupt line. Enables and Disables are
* nested.
* This function waits for any pending IRQ handlers for this interrupt
* to complete before returning. If you use this function while
* holding a resource the IRQ handler may need you will deadlock.
*
......@@ -516,11 +517,12 @@ void disable_irq(unsigned int irq)
}
/**
* enable_irq - enable interrupt handling on an irq
* enable_irq - enable handling of an irq
* @irq: Interrupt to enable
*
* Re-enables the processing of interrupts on this IRQ line
* providing no disable_irq calls are now in effect.
* Undoes the effect of one call to disable_irq(). If this
* matches the last disable, processing of interrupts on this
* IRQ line is re-enabled.
*
* This function may be called from IRQ context.
*/
......@@ -1027,20 +1029,9 @@ int setup_irq(unsigned int irq, struct irqaction * new)
static struct proc_dir_entry * root_irq_dir;
static struct proc_dir_entry * irq_dir [NR_IRQS];
static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
#define HEX_DIGITS 8
static int irq_affinity_read_proc (char *page, char **start, off_t off,
int count, int *eof, void *data)
{
if (count < HEX_DIGITS+1)
return -EINVAL;
return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
}
static unsigned int parse_hex_value (const char *buffer,
unsigned long count, unsigned long *ret)
{
......@@ -1078,6 +1069,19 @@ static unsigned int parse_hex_value (const char *buffer,
return 0;
}
#if CONFIG_SMP
static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
static int irq_affinity_read_proc (char *page, char **start, off_t off,
int count, int *eof, void *data)
{
if (count < HEX_DIGITS+1)
return -EINVAL;
return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
}
static int irq_affinity_write_proc (struct file *file, const char *buffer,
unsigned long count, void *data)
{
......@@ -1089,7 +1093,6 @@ static int irq_affinity_write_proc (struct file *file, const char *buffer,
err = parse_hex_value(buffer, count, &new_value);
#if CONFIG_SMP
/*
* Do not allow disabling IRQs completely - it's a too easy
* way to make the system unusable accidentally :-) At least
......@@ -1097,7 +1100,6 @@ static int irq_affinity_write_proc (struct file *file, const char *buffer,
*/
if (!(new_value & cpu_online_map))
return -EINVAL;
#endif
irq_affinity[irq] = new_value;
irq_desc[irq].handler->set_affinity(irq, new_value);
......@@ -1105,6 +1107,8 @@ static int irq_affinity_write_proc (struct file *file, const char *buffer,
return full_count;
}
#endif
static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
int count, int *eof, void *data)
{
......@@ -1132,7 +1136,6 @@ static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
static void register_irq_proc (unsigned int irq)
{
struct proc_dir_entry *entry;
char name [MAX_NAMELEN];
if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
......@@ -1145,15 +1148,23 @@ static void register_irq_proc (unsigned int irq)
/* create /proc/irq/1234 */
irq_dir[irq] = proc_mkdir(name, root_irq_dir);
/* create /proc/irq/1234/smp_affinity */
entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
#if CONFIG_SMP
{
struct proc_dir_entry *entry;
entry->nlink = 1;
entry->data = (void *)(long)irq;
entry->read_proc = irq_affinity_read_proc;
entry->write_proc = irq_affinity_write_proc;
/* create /proc/irq/1234/smp_affinity */
entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
smp_affinity_entry[irq] = entry;
if (entry) {
entry->nlink = 1;
entry->data = (void *)(long)irq;
entry->read_proc = irq_affinity_read_proc;
entry->write_proc = irq_affinity_write_proc;
}
smp_affinity_entry[irq] = entry;
}
#endif
}
unsigned long prof_cpu_mask = -1;
......@@ -1169,6 +1180,9 @@ void init_irq_proc (void)
/* create /proc/irq/prof_cpu_mask */
entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
if (!entry)
return;
entry->nlink = 1;
entry->data = (void *)&prof_cpu_mask;
entry->read_proc = prof_cpu_mask_read_proc;
......
......@@ -38,6 +38,18 @@ int apic_version [MAX_APICS];
int mp_bus_id_to_type [MAX_MP_BUSSES];
int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
int mp_current_pci_id;
/* I/O APIC entries */
struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
/* # of MP IRQ source entries */
struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
/* MP IRQ source entries */
int mp_irq_entries;
int nr_ioapics;
int pic_mode;
unsigned long mp_lapic_addr;
......@@ -225,6 +237,11 @@ static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
MAX_IO_APICS, nr_ioapics);
panic("Recompile kernel with bigger MAX_IO_APICS!.\n");
}
if (!m->mpc_apicaddr) {
printk(KERN_ERR "WARNING: bogus zero I/O APIC address"
" found in MP table, skipping!\n");
return;
}
mp_ioapics[nr_ioapics] = *m;
nr_ioapics++;
}
......@@ -365,10 +382,19 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
return num_processors;
}
static int __init ELCR_trigger(unsigned int irq)
{
unsigned int port;
port = 0x4d0 + (irq >> 3);
return (inb(port) >> (irq & 7)) & 1;
}
static void __init construct_default_ioirq_mptable(int mpc_default_type)
{
struct mpc_config_intsrc intsrc;
int i;
int ELCR_fallback = 0;
intsrc.mpc_type = MP_INTSRC;
intsrc.mpc_irqflag = 0; /* conforming */
......@@ -376,6 +402,26 @@ static void __init construct_default_ioirq_mptable(int mpc_default_type)
intsrc.mpc_dstapic = mp_ioapics[0].mpc_apicid;
intsrc.mpc_irqtype = mp_INT;
/*
* If true, we have an ISA/PCI system with no IRQ entries
* in the MP table. To prevent the PCI interrupts from being set up
* incorrectly, we try to use the ELCR. The sanity check to see if
* there is good ELCR data is very simple - IRQ0, 1, 2 and 13 can
* never be level sensitive, so we simply see if the ELCR agrees.
* If it does, we assume it's valid.
*/
if (mpc_default_type == 5) {
printk("ISA/PCI bus type with no IRQ information... falling back to ELCR\n");
if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) || ELCR_trigger(13))
printk("ELCR contains invalid data... not using ELCR\n");
else {
printk("Using ELCR to identify PCI interrupts\n");
ELCR_fallback = 1;
}
}
for (i = 0; i < 16; i++) {
switch (mpc_default_type) {
case 2:
......@@ -387,6 +433,18 @@ static void __init construct_default_ioirq_mptable(int mpc_default_type)
continue; /* IRQ2 is never connected */
}
if (ELCR_fallback) {
/*
* If the ELCR indicates a level-sensitive interrupt, we
* copy that information over to the MP table in the
* irqflag field (level sensitive, active high polarity).
*/
if (ELCR_trigger(i))
intsrc.mpc_irqflag = 13;
else
intsrc.mpc_irqflag = 0;
}
intsrc.mpc_srcbusirq = i;
intsrc.mpc_dstirq = i ? i : 2; /* IRQ0 to INTIN2 */
MP_intsrc_info(&intsrc);
......@@ -641,7 +699,7 @@ void __init find_visws_smp(void)
*/
void __init find_smp_config (void)
{
#ifdef CONFIG_X86_IO_APIC
#ifdef CONFIG_X86_LOCAL_APIC
find_intel_smp();
#endif
#ifdef CONFIG_VISWS
......
/*
* linux/arch/i386/nmi.c
*
* NMI watchdog support on APIC systems
*
* Started by Ingo Molnar <mingo@redhat.com>
*
* Fixes:
* Mikael Pettersson : AMD K7 support for local APIC NMI watchdog.
* Mikael Pettersson : Power Management for local APIC NMI watchdog.
*/
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/mc146818rtc.h>
#include <linux/kernel_stat.h>
#include <asm/smp.h>
#include <asm/mtrr.h>
#include <asm/mpspec.h>
unsigned int nmi_watchdog = NMI_NONE;
static unsigned int nmi_hz = HZ;
unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */
#define K7_EVNTSEL_ENABLE (1 << 22)
#define K7_EVNTSEL_INT (1 << 20)
#define K7_EVNTSEL_OS (1 << 17)
#define K7_EVNTSEL_USR (1 << 16)
#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76
#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING
#define P6_EVNTSEL0_ENABLE (1 << 22)
#define P6_EVNTSEL_INT (1 << 20)
#define P6_EVNTSEL_OS (1 << 17)
#define P6_EVNTSEL_USR (1 << 16)
#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79
#define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED
int __init check_nmi_watchdog (void)
{
irq_cpustat_t tmp[NR_CPUS];
int j, cpu;
printk(KERN_INFO "testing NMI watchdog ... ");
memcpy(tmp, irq_stat, sizeof(tmp));
sti();
mdelay((10*1000)/nmi_hz); // wait 10 ticks
for (j = 0; j < smp_num_cpus; j++) {
cpu = cpu_logical_map(j);
if (nmi_count(cpu) - tmp[cpu].__nmi_count <= 5) {
printk("CPU#%d: NMI appears to be stuck!\n", cpu);
return -1;
}
}
printk("OK.\n");
/* now that we know it works we can reduce NMI frequency to
something more reasonable; makes a difference in some configs */
if (nmi_watchdog == NMI_LOCAL_APIC)
nmi_hz = 1;
return 0;
}
static int __init setup_nmi_watchdog(char *str)
{
int nmi;
get_option(&str, &nmi);
if (nmi >= NMI_INVALID)
return 0;
if (nmi == NMI_NONE)
nmi_watchdog = nmi;
/*
* If any other x86 CPU has a local APIC, then
* please test the NMI stuff there and send me the
* missing bits. Right now Intel P6 and AMD K7 only.
*/
if ((nmi == NMI_LOCAL_APIC) &&
(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
(boot_cpu_data.x86 == 6))
nmi_watchdog = nmi;
if ((nmi == NMI_LOCAL_APIC) &&
(boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
(boot_cpu_data.x86 == 6))
nmi_watchdog = nmi;
/*
* We can enable the IO-APIC watchdog
* unconditionally.
*/
if (nmi == NMI_IO_APIC)
nmi_watchdog = nmi;
return 1;
}
__setup("nmi_watchdog=", setup_nmi_watchdog);
#ifdef CONFIG_PM
#include <linux/pm.h>
struct pm_dev *nmi_pmdev;
static void disable_apic_nmi_watchdog(void)
{
switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_AMD:
wrmsr(MSR_K7_EVNTSEL0, 0, 0);
break;
case X86_VENDOR_INTEL:
wrmsr(MSR_IA32_EVNTSEL0, 0, 0);
break;
}
}
static int nmi_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
{
switch (rqst) {
case PM_SUSPEND:
disable_apic_nmi_watchdog();
break;
case PM_RESUME:
setup_apic_nmi_watchdog();
break;
}
return 0;
}
static void nmi_pm_init(void)
{
if (!nmi_pmdev)
nmi_pmdev = apic_pm_register(PM_SYS_DEV, 0, nmi_pm_callback);
}
#define __pminit /*empty*/
#else /* CONFIG_PM */
static inline void nmi_pm_init(void) { }
#define __pminit __init
#endif /* CONFIG_PM */
/*
* Activate the NMI watchdog via the local APIC.
* Original code written by Keith Owens.
*/
static void __pminit setup_k7_watchdog(void)
{
int i;
unsigned int evntsel;
nmi_perfctr_msr = MSR_K7_PERFCTR0;
for(i = 0; i < 4; ++i) {
wrmsr(MSR_K7_EVNTSEL0+i, 0, 0);
wrmsr(MSR_K7_PERFCTR0+i, 0, 0);
}
evntsel = K7_EVNTSEL_INT
| K7_EVNTSEL_OS
| K7_EVNTSEL_USR
| K7_NMI_EVENT;
wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
Dprintk("setting K7_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000));
wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1);
apic_write(APIC_LVTPC, APIC_DM_NMI);
evntsel |= K7_EVNTSEL_ENABLE;
wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
}
static void __pminit setup_p6_watchdog(void)
{
int i;
unsigned int evntsel;
nmi_perfctr_msr = MSR_IA32_PERFCTR0;
for(i = 0; i < 2; ++i) {
wrmsr(MSR_IA32_EVNTSEL0+i, 0, 0);
wrmsr(MSR_IA32_PERFCTR0+i, 0, 0);
}
evntsel = P6_EVNTSEL_INT
| P6_EVNTSEL_OS
| P6_EVNTSEL_USR
| P6_NMI_EVENT;
wrmsr(MSR_IA32_EVNTSEL0, evntsel, 0);
Dprintk("setting IA32_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000));
wrmsr(MSR_IA32_PERFCTR0, -(cpu_khz/nmi_hz*1000), 0);
apic_write(APIC_LVTPC, APIC_DM_NMI);
evntsel |= P6_EVNTSEL0_ENABLE;
wrmsr(MSR_IA32_EVNTSEL0, evntsel, 0);
}
void __pminit setup_apic_nmi_watchdog (void)
{
switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_AMD:
if (boot_cpu_data.x86 != 6)
return;
setup_k7_watchdog();
break;
case X86_VENDOR_INTEL:
if (boot_cpu_data.x86 != 6)
return;
setup_p6_watchdog();
break;
default:
return;
}
nmi_pm_init();
}
static spinlock_t nmi_print_lock = SPIN_LOCK_UNLOCKED;
/*
* the best way to detect whether a CPU has a 'hard lockup' problem
* is to check it's local APIC timer IRQ counts. If they are not
* changing then that CPU has some problem.
*
* as these watchdog NMI IRQs are generated on every CPU, we only
* have to check the current processor.
*
* since NMIs dont listen to _any_ locks, we have to be extremely
* careful not to rely on unsafe variables. The printk might lock
* up though, so we have to break up any console locks first ...
* [when there will be more tty-related locks, break them up
* here too!]
*/
static unsigned int
last_irq_sums [NR_CPUS],
alert_counter [NR_CPUS];
void touch_nmi_watchdog (void)
{
int i;
/*
* Just reset the alert counters, (other CPUs might be
* spinning on locks we hold):
*/
for (i = 0; i < smp_num_cpus; i++)
alert_counter[i] = 0;
}
void nmi_watchdog_tick (struct pt_regs * regs)
{
/*
* Since current-> is always on the stack, and we always switch
* the stack NMI-atomically, it's safe to use smp_processor_id().
*/
int sum, cpu = smp_processor_id();
sum = apic_timer_irqs[cpu];
if (last_irq_sums[cpu] == sum) {
/*
* Ayiee, looks like this CPU is stuck ...
* wait a few IRQs (5 seconds) before doing the oops ...
*/
alert_counter[cpu]++;
if (alert_counter[cpu] == 5*nmi_hz) {
spin_lock(&nmi_print_lock);
/*
* We are in trouble anyway, lets at least try
* to get a message out.
*/
bust_spinlocks(1);
printk("NMI Watchdog detected LOCKUP on CPU%d, registers:\n", cpu);
show_registers(regs);
printk("console shuts up ...\n");
console_silent();
spin_unlock(&nmi_print_lock);
bust_spinlocks(0);
do_exit(SIGSEGV);
}
} else {
last_irq_sums[cpu] = sum;
alert_counter[cpu] = 0;
}
if (nmi_perfctr_msr)
wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1);
}
......@@ -154,6 +154,12 @@ static long no_idt[2];
static int reboot_mode;
int reboot_thru_bios;
#ifdef CONFIG_SMP
int reboot_smp = 0;
static int reboot_cpu = -1;
/* shamelessly grabbed from lib/vsprintf.c for readability */
#define is_digit(c) ((c) >= '0' && (c) <= '9')
#endif
static int __init reboot_setup(char *str)
{
while(1) {
......@@ -170,6 +176,19 @@ static int __init reboot_setup(char *str)
case 'h': /* "hard" reboot by toggling RESET and/or crashing the CPU */
reboot_thru_bios = 0;
break;
#ifdef CONFIG_SMP
case 's': /* "smp" reboot by executing reset on BSP or other CPU*/
reboot_smp = 1;
if (is_digit(*(str+1))) {
reboot_cpu = (int) (*(str+1) - '0');
if (is_digit(*(str+2)))
reboot_cpu = reboot_cpu*10 + (int)(*(str+2) - '0');
}
/* we will leave sorting out the final value
when we are ready to reboot, since we might not
have set up boot_cpu_id or smp_num_cpu */
break;
#endif
}
if((str = strchr(str,',')) != NULL)
str++;
......@@ -346,6 +365,34 @@ void machine_real_restart(unsigned char *code, int length)
void machine_restart(char * __unused)
{
#if CONFIG_SMP
int cpuid;
cpuid = GET_APIC_ID(apic_read(APIC_ID));
if (reboot_smp) {
/* check to see if reboot_cpu is valid
if its not, default to the BSP */
if ((reboot_cpu == -1) ||
(reboot_cpu > (NR_CPUS -1)) ||
!(phys_cpu_present_map & (1<<cpuid)))
reboot_cpu = boot_cpu_id;
reboot_smp = 0; /* use this as a flag to only go through this once*/
/* re-run this function on the other CPUs
it will fall though this section since we have
cleared reboot_smp, and do the reboot if it is the
correct CPU, otherwise it halts. */
if (reboot_cpu != cpuid)
smp_call_function((void *)machine_restart , NULL, 1, 0);
}
/* if reboot_cpu is still -1, then we want a tradional reboot,
and if we are not running on the reboot_cpu,, halt */
if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) {
for (;;)
__asm__ __volatile__ ("hlt");
}
/*
* Stop all CPUs and turn off local APICs and the IO-APIC, so
* other OSs see a clean IRQ state.
......
......@@ -134,6 +134,19 @@ static unsigned long getreg(struct task_struct *child,
return retval;
}
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure the single step bit is not set.
*/
void ptrace_disable(struct task_struct *child)
{
long tmp;
tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG;
put_stack_long(child, EFL_OFFSET, tmp);
}
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
......@@ -320,26 +333,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
break;
}
case PTRACE_DETACH: { /* detach a process that was attached. */
long tmp;
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
child->ptrace = 0;
child->exit_code = data;
write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irq(&tasklist_lock);
/* make sure the single step bit is not set. */
tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG;
put_stack_long(child, EFL_OFFSET, tmp);
wake_up_process(child);
ret = 0;
case PTRACE_DETACH:
/* detach a process that was attached. */
ret = ptrace_detach(child, data);
break;
}
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
if (!access_ok(VERIFY_WRITE, (unsigned *)data, FRAME_SIZE*sizeof(long))) {
......
......@@ -943,7 +943,7 @@ void __init setup_arch(char **cmdline_p)
reserve_bootmem(PAGE_SIZE, PAGE_SIZE);
#endif
#ifdef CONFIG_X86_IO_APIC
#ifdef CONFIG_X86_LOCAL_APIC
/*
* Find and reserve possible boot-time SMP configuration:
*/
......@@ -976,17 +976,16 @@ void __init setup_arch(char **cmdline_p)
smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
#endif
paging_init();
#ifdef CONFIG_X86_IO_APIC
#ifdef CONFIG_X86_LOCAL_APIC
/*
* get boot-time SMP configuration:
*/
if (smp_found_config)
get_smp_config();
#endif
#ifdef CONFIG_X86_LOCAL_APIC
init_apic_mappings();
#endif
/*
* Request address space for all standard RAM and ROM resources
* and also for regions reported as reserved by the e820.
......
......@@ -429,9 +429,10 @@ struct call_data_struct {
atomic_t started;
atomic_t finished;
int wait;
};
} __attribute__ ((__aligned__(SMP_CACHE_BYTES)));
static struct call_data_struct * call_data;
static struct call_data_struct call_data_array[NR_CPUS];
/*
* this function sends a 'generic call function' IPI to all other CPUs
......@@ -453,33 +454,45 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
* hardware interrupt handler, you may call it from a bottom half handler.
*/
{
struct call_data_struct data;
int cpus = smp_num_cpus-1;
struct call_data_struct *data;
int cpus = (cpu_online_map & ~(1 << smp_processor_id()));
if (!cpus)
return 0;
data.func = func;
data.info = info;
atomic_set(&data.started, 0);
data.wait = wait;
data = &call_data_array[smp_processor_id()];
data->func = func;
data->info = info;
data->wait = wait;
if (wait)
atomic_set(&data.finished, 0);
spin_lock_bh(&call_lock);
call_data = &data;
wmb();
atomic_set(&data->finished, 0);
/* We have do to this one last to make sure that the IPI service
* code desn't get confused if it gets an unexpected repeat
* trigger of an old IPI while we're still setting up the new
* one. */
atomic_set(&data->started, 0);
local_bh_disable();
spin_lock(&call_lock);
call_data = data;
/* Send a message to all other CPUs and wait for them to respond */
send_IPI_allbutself(CALL_FUNCTION_VECTOR);
/* Wait for response */
while (atomic_read(&data.started) != cpus)
while (atomic_read(&data->started) != cpus)
barrier();
/* It is now safe to reuse the "call_data" global, but we need
* to keep local bottom-halves disabled until after waiters have
* been acknowledged to prevent reuse of the per-cpu call data
* entry. */
spin_unlock(&call_lock);
if (wait)
while (atomic_read(&data.finished) != cpus)
while (atomic_read(&data->finished) != cpus)
barrier();
spin_unlock_bh(&call_lock);
local_bh_enable();
return 0;
}
......@@ -529,18 +542,17 @@ asmlinkage void smp_call_function_interrupt(void)
ack_APIC_irq();
/*
* Notify initiating CPU that I've grabbed the data and am
* about to execute the function
* Notify initiating CPU that I've grabbed the data and am about
* to execute the function (and avoid servicing any single IPI
* twice)
*/
mb();
atomic_inc(&call_data->started);
if (test_and_set_bit(smp_processor_id(), &call_data->started))
return;
/*
* At this point the info structure may be out of scope unless wait==1
*/
(*func)(info);
if (wait) {
mb();
atomic_inc(&call_data->finished);
}
if (wait)
set_bit(smp_processor_id(), &call_data->finished);
}
......@@ -780,7 +780,6 @@ static void __init do_boot_cpu (int apicid)
}
cycles_t cacheflush_time;
extern unsigned long cpu_khz;
static void smp_tune_scheduling (void)
{
......@@ -870,12 +869,15 @@ void __init smp_boot_cpus(void)
* get out of here now!
*/
if (!smp_found_config) {
printk(KERN_NOTICE "SMP motherboard not detected. Using dummy APIC emulation.\n");
printk(KERN_NOTICE "SMP motherboard not detected.\n");
#ifndef CONFIG_VISWS
io_apic_irqs = 0;
#endif
cpu_online_map = phys_cpu_present_map = 1;
smp_num_cpus = 1;
if (APIC_init_uniprocessor())
printk(KERN_NOTICE "Local APIC not detected."
" Using dummy APIC emulation.\n");
goto smp_done;
}
......@@ -1003,7 +1005,7 @@ void __init smp_boot_cpus(void)
* Here we can be sure that there is an IO-APIC in the system. Let's
* go and set it up:
*/
if (!skip_ioapic_setup)
if (!skip_ioapic_setup && nr_ioapics)
setup_IO_APIC();
#endif
......@@ -1021,4 +1023,3 @@ void __init smp_boot_cpus(void)
smp_done:
zap_low_mappings();
}
......@@ -422,7 +422,7 @@ static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *reg
if (!user_mode(regs))
x86_do_profile(regs->eip);
#else
if (!smp_found_config)
if (!using_apic_timer)
smp_local_timer_interrupt(regs);
#endif
......
......@@ -186,7 +186,7 @@ void show_stack(unsigned long * esp)
show_trace(esp);
}
static void show_registers(struct pt_regs *regs)
void show_registers(struct pt_regs *regs)
{
int i;
int in_kernel = 1;
......@@ -418,108 +418,14 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
printk("Do you have a strange power saving mode enabled?\n");
}
#if CONFIG_X86_IO_APIC
int nmi_watchdog = 0;
static int __init setup_nmi_watchdog(char *str)
{
get_option(&str, &nmi_watchdog);
return 1;
}
__setup("nmi_watchdog=", setup_nmi_watchdog);
static spinlock_t nmi_print_lock = SPIN_LOCK_UNLOCKED;
static unsigned int
last_irq_sums [NR_CPUS],
alert_counter [NR_CPUS];
/*
* Sometimes, we know that we're disabling interrupts for too long.
* This happens during long writes to slow console devices, and may
* happen in other places.
*
* To prevent the NMI watchdog from firing when we're doing these things,
* touch_nmi_watchdog() may be used to reset the NMI watchdog timer
* back to its full interval (five seconds).
*/
void touch_nmi_watchdog (void)
{
int i;
/*
* Just reset the alert counters, (other CPUs might be
* spinning on locks we hold):
*/
for (i = 0; i < smp_num_cpus; i++)
alert_counter[i] = 0;
}
/*
* The best way to detect whether a CPU has a 'hard lockup' problem
* is to check it's local APIC timer IRQ counts. If they are not
* changing then that CPU has some problem.
*
* As these watchdog NMI IRQs are generated on every CPU, we only
* have to check the current processor.
*
* Since NMIs don't listen to _any_ locks, we have to be extremely
* careful not to rely on unsafe variables. The printk path might lock
* up though, so we use bust_spinlocks() to break up any console
* locks first. There may be other tty-related locks which require
* breaking as well. They can be broken in bust_spinlocks(), or the
* global variable `oops_in_progress' may be used to bypass the
* tty locking.
*/
inline void nmi_watchdog_tick(struct pt_regs * regs)
{
/*
* Since current-> is always on the stack, and we always switch
* the stack NMI-atomically, it's safe to use smp_processor_id().
*/
int sum, cpu = smp_processor_id();
sum = apic_timer_irqs[cpu];
if (last_irq_sums[cpu] == sum) {
/*
* Ayiee, looks like this CPU is stuck ...
* wait a few IRQs (5 seconds) before doing the oops ...
*/
alert_counter[cpu]++;
if (alert_counter[cpu] == 5*HZ) {
spin_lock(&nmi_print_lock);
/*
* We are in trouble anyway, lets at least try
* to get a message out.
*/
bust_spinlocks(1);
printk("NMI Watchdog detected LOCKUP on CPU%d, registers:\n", cpu);
show_registers(regs);
printk("console shuts up ...\n");
console_silent();
spin_unlock(&nmi_print_lock);
bust_spinlocks(0);
do_exit(SIGSEGV);
}
} else {
last_irq_sums[cpu] = sum;
alert_counter[cpu] = 0;
}
}
#endif
asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
{
unsigned char reason = inb(0x61);
++nmi_count(smp_processor_id());
if (!(reason & 0xc0)) {
#if CONFIG_X86_IO_APIC
#if CONFIG_X86_LOCAL_APIC
/*
* Ok, so this is none of the documented NMI sources,
* so it must be the NMI watchdog.
......@@ -527,11 +433,9 @@ asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
if (nmi_watchdog) {
nmi_watchdog_tick(regs);
return;
} else
unknown_nmi_error(reason, regs);
#else
unknown_nmi_error(reason, regs);
}
#endif
unknown_nmi_error(reason, regs);
return;
}
if (reason & 0x80)
......
......@@ -44,6 +44,7 @@ __generic_copy_from_user(void *to, const void *from, unsigned long n)
unsigned long
__generic_copy_to_user(void *to, const void *from, unsigned long n)
{
prefetch(from);
if (access_ok(VERIFY_WRITE, to, n))
__copy_user(to,from,n);
return n;
......@@ -52,6 +53,7 @@ __generic_copy_to_user(void *to, const void *from, unsigned long n)
unsigned long
__generic_copy_from_user(void *to, const void *from, unsigned long n)
{
prefetchw(to);
if (access_ok(VERIFY_READ, from, n))
__copy_user_zeroing(to,from,n);
else
......
......@@ -111,7 +111,9 @@ void bust_spinlocks(int yes)
#endif
} else {
int loglevel_save = console_loglevel;
#ifdef CONFIG_VT
unblank_screen();
#endif
oops_in_progress = 0;
/*
* OK, the message is on the console. Now we call printk()
......@@ -124,16 +126,11 @@ void bust_spinlocks(int yes)
}
}
#if 0
/*
* Verbose bug reporting: call do_BUG(__FILE__, __LINE__) in page.h:BUG() to enable this
*/
void do_BUG(const char *file, int line)
{
bust_spinlocks(1);
printk("kernel BUG at %s:%d!\n", file, line);
}
#endif
asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
extern unsigned long idt;
......
......@@ -789,6 +789,21 @@ access_uarea (struct task_struct *child, unsigned long addr, unsigned long *data
return 0;
}
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure the single step bit is not set.
*/
void ptrace_disable(struct task_struct *child)
{
/* make sure the single step/take-branch tra bits are not set: */
ia64_psr(pt)->ss = 0;
ia64_psr(pt)->tb = 0;
/* Turn off flag indicating that the KRBS is sync'd with child's VM: */
child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED;
}
asmlinkage long
sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
long arg4, long arg5, long arg6, long arg7, long stack)
......@@ -965,27 +980,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
goto out_tsk;
case PTRACE_DETACH: /* detach a process that was attached. */
ret = -EIO;
if (data > _NSIG)
goto out_tsk;
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
write_lock_irqsave(&tasklist_lock, flags);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irqrestore(&tasklist_lock, flags);
/* make sure the single step/take-branch tra bits are not set: */
ia64_psr(pt)->ss = 0;
ia64_psr(pt)->tb = 0;
/* Turn off flag indicating that the KRBS is sync'd with child's VM: */
child->thread.flags &= ~IA64_THREAD_KRBS_SYNCED;
wake_up_process(child);
ret = 0;
ret = ptrace_detach(child, data);
goto out_tsk;
default:
......
......@@ -87,6 +87,19 @@ static inline int put_reg(struct task_struct *task, int regno,
return 0;
}
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure the single step bit is not set.
*/
void ptrace_disable(struct task_struct *child)
{
unsigned long tmp;
/* make sure the single step bit is not set. */
tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
put_reg(child, PT_SR, tmp);
}
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
......@@ -279,26 +292,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
break;
}
case PTRACE_DETACH: { /* detach a process that was attached. */
long tmp;
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
write_lock_irqsave(&tasklist_lock, flags);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irqrestore(&tasklist_lock, flags);
/* make sure the single step bit is not set. */
tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
put_reg(child, PT_SR, tmp);
wake_up_process(child);
ret = 0;
case PTRACE_DETACH: /* detach a process that was attached. */
ret = ptrace_detach(child, data);
break;
}
case PTRACE_GETREGS: { /* Get all gp regs from the child. */
int i;
......
......@@ -29,6 +29,16 @@
#include <asm/bootinfo.h>
#include <asm/cpu.h>
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure single step bits etc are not set.
*/
void ptrace_disable(struct task_struct *child)
{
/* Nothing to do.. */
}
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
......@@ -291,18 +301,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
break;
case PTRACE_DETACH: /* detach a process that was attached. */
res = -EIO;
if ((unsigned long) data > _NSIG)
break;
child->ptrace = 0;
child->exit_code = data;
write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irq(&tasklist_lock);
wake_up_process(child);
res = 0;
res = ptrace_detach(child, data);
break;
case PTRACE_SETOPTIONS:
......
......@@ -28,6 +28,16 @@
#include <asm/system.h>
#include <asm/uaccess.h>
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure single step bits etc are not set.
*/
void ptrace_disable(struct task_struct *child)
{
/* Nothing to do.. */
}
/*
* Tracing a 32-bit process with a 64-bit strace and vice versa will not
* work. I don't know how to fix this.
......@@ -261,21 +271,9 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
break;
}
case PTRACE_DETACH: { /* detach a process that was attached. */
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
child->ptrace = 0;
child->exit_code = data;
write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irq(&tasklist_lock);
wake_up_process(child);
ret = 0;
case PTRACE_DETACH: /* detach a process that was attached. */
ret = ptrace_detach(child, data);
break;
}
case PTRACE_SETOPTIONS: {
if (data & PTRACE_O_TRACESYSGOOD)
......@@ -533,21 +531,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
break;
}
case PTRACE_DETACH: { /* detach a process that was attached. */
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
child->ptrace = 0;
child->exit_code = data;
write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irq(&tasklist_lock);
wake_up_process(child);
ret = 0;
case PTRACE_DETACH: /* detach a process that was attached. */
ret = ptrace_detach(child, data);
break;
}
case PTRACE_SETOPTIONS: {
if (data & PTRACE_O_TRACESYSGOOD)
......
......@@ -31,6 +31,20 @@
#define PT_SINGLESTEP 0x10000
#define PT_BLOCKSTEP 0x20000
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure single step bits etc are not set.
*/
void ptrace_disable(struct task_struct *child)
{
/* make sure the trap bits are not set */
pa_psw(child)->r = 0;
pa_psw(child)->t = 0;
pa_psw(child)->h = 0;
pa_psw(child)->l = 0;
}
long sys_ptrace(long request, pid_t pid, long addr, long data)
{
struct task_struct *child;
......@@ -226,17 +240,8 @@ long sys_ptrace(long request, pid_t pid, long addr, long data)
goto out_wake;
case PTRACE_DETACH:
ret = -EIO;
if ((unsigned long) data > _NSIG)
goto out_tsk;
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS|PT_SINGLESTEP|PT_BLOCKSTEP);
child->exit_code = data;
write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irq(&tasklist_lock);
goto out_wake_notrap;
ret = ptrace_detach(child, data);
goto out_tsk;
default:
ret = -EIO;
......
......@@ -89,6 +89,17 @@ clear_single_step(struct task_struct *task)
regs->msr &= ~MSR_SE;
}
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure single step bits etc are not set.
*/
void ptrace_disable(struct task_struct *child)
{
/* make sure the single step bit is not set. */
clear_single_step(child);
}
int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
......@@ -249,23 +260,9 @@ int sys_ptrace(long request, long pid, long addr, long data)
break;
}
case PTRACE_DETACH: { /* detach a process that was attached. */
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irq(&tasklist_lock);
/* make sure the single step bit is not set. */
clear_single_step(child);
wake_up_process(child);
ret = 0;
case PTRACE_DETACH:
ret = ptrace_detach(child, data);
break;
}
default:
ret = -EIO;
......
......@@ -202,6 +202,17 @@ int copy_user(struct task_struct *task,saddr_t useraddr,addr_t copyaddr,int len,
return(0);
}
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure single step bits etc are not set.
*/
void ptrace_disable(struct task_struct *child)
{
/* make sure the single step bit is not set. */
clear_single_step(child);
}
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
......@@ -327,20 +338,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
break;
case PTRACE_DETACH: /* detach a process that was attached. */
ret = -EIO;
if ((unsigned long) data >= _NSIG)
break;
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
write_lock_irqsave(&tasklist_lock, flags);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irqrestore(&tasklist_lock, flags);
/* make sure the single step bit is not set. */
clear_single_step(child);
wake_up_process(child);
ret = 0;
ret = ptrace_detach(child, data);
break;
case PTRACE_PEEKUSR_AREA:
case PTRACE_POKEUSR_AREA:
......
......@@ -216,6 +216,17 @@ int copy_user(struct task_struct *task,saddr_t useraddr, addr_t copyaddr,
return(0);
}
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure single step bits etc are not set.
*/
void ptrace_disable(struct task_struct *child)
{
/* make sure the single step bit is not set. */
clear_single_step(child);
}
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
......@@ -341,21 +352,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
break;
case PTRACE_DETACH: /* detach a process that was attached. */
ret = -EIO;
if ((unsigned long) data >= _NSIG)
break;
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
write_lock_irqsave(&tasklist_lock, flags);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irqrestore(&tasklist_lock, flags);
/* make sure the single step bit is not set. */
clear_single_step(child);
wake_up_process(child);
ret = 0;
ret = ptrace_detach(child, data);
break;
case PTRACE_PEEKUSR_AREA:
case PTRACE_POKEUSR_AREA:
if((ret=copy_from_user(&parea,(void *)addr,sizeof(parea)))==0)
......
......@@ -147,6 +147,16 @@ ubc_set_tracing(int asid, unsigned long nextpc1, unsigned nextpc2)
ctrl_outw(BRCR_PCBA | BRCR_PCBB, UBC_BRCR);
}
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure single step bits etc are not set.
*/
void ptrace_disable(struct task_struct *child)
{
/* nothing to do.. */
}
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child, *tsk = current;
......@@ -342,21 +352,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
break;
}
case PTRACE_DETACH: { /* detach a process that was attached. */
ret = -EIO;
if ((unsigned long) data > _NSIG)
break;
child->ptrace = 0;
child->exit_code = data;
write_lock_irq(&tasklist_lock);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irq(&tasklist_lock);
wake_up_process(child);
ret = 0;
case PTRACE_DETACH: /* detach a process that was attached. */
ret = ptrace_detach(child, data);
break;
}
case PTRACE_SETOPTIONS: {
if (data & PTRACE_O_TRACESYSGOOD)
......
......@@ -260,6 +260,16 @@ char *pt_rq [] = {
};
#endif
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure single step bits etc are not set.
*/
void ptrace_disable(struct task_struct *child)
{
/* nothing to do */
}
asmlinkage void do_ptrace(struct pt_regs *regs)
{
unsigned long request = regs->u_regs[UREG_I0];
......@@ -576,19 +586,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
case PTRACE_SUNDETACH: { /* detach a process that was attached. */
unsigned long flags;
if ((unsigned long) data > _NSIG) {
int err = ptrace_detach(child, data);
if (err) {
pt_error_return(regs, EIO);
goto out_tsk;
}
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
wake_up_process(child);
child->exit_code = data;
write_lock_irqsave(&tasklist_lock, flags);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irqrestore(&tasklist_lock, flags);
pt_succ_return(regs, 0);
goto out_tsk;
}
......
......@@ -105,6 +105,16 @@ char *pt_rq [] = {
};
#endif
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure single step bits etc are not set.
*/
void ptrace_disable(struct task_struct *child)
{
/* nothing to do */
}
asmlinkage void do_ptrace(struct pt_regs *regs)
{
int request = regs->u_regs[UREG_I0];
......@@ -562,22 +572,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
}
case PTRACE_SUNDETACH: { /* detach a process that was attached. */
unsigned long flags;
if ((unsigned long) data > _NSIG) {
int error = ptrace_detach(child, data);
if (error) {
pt_error_return(regs, EIO);
goto out_tsk;
}
child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
write_lock_irqsave(&tasklist_lock, flags);
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
write_unlock_irqrestore(&tasklist_lock, flags);
wake_up_process(child);
pt_succ_return(regs, 0);
goto out_tsk;
}
......
This diff is collapsed.
......@@ -416,6 +416,8 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
case BLKRASET:
case BLKRAGET:
case BLKPG:
case BLKELVGET:
case BLKELVSET:
return( blk_ioctl(inode->i_rdev, cmd, arg));
case CCISS_GETPCIINFO:
{
......
......@@ -1262,6 +1262,8 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
case BLKROGET:
case BLKRASET:
case BLKRAGET:
case BLKELVGET:
case BLKELVSET:
case BLKPG:
return blk_ioctl(inode->i_rdev, cmd, arg);
......
......@@ -28,7 +28,7 @@ int verbose=0; /* set this to 1 to see debugging messages and whatnot */
#define EXPORT_SYMTAB
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/malloc.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <asm/io.h>
......
......@@ -536,6 +536,8 @@ MODULE_PARM_DESC(rd_size, "Size of each RAM disk in kbytes.");
MODULE_PARM (rd_blocksize, "i");
MODULE_PARM_DESC(rd_blocksize, "Blocksize of each RAM disk in bytes.");
MODULE_LICENSE("GPL");
/* End of non-loading portions of the RAM disk driver */
#ifdef RD_LOADER
......
......@@ -120,6 +120,9 @@ struct agp_bridge_data {
void (*free_by_type) (agp_memory *);
unsigned long (*agp_alloc_page) (void);
void (*agp_destroy_page) (unsigned long);
int (*suspend)(void);
void (*resume)(void);
};
#define OUTREG32(mmap, addr, val) __raw_writel((val), (mmap)+(addr))
......@@ -157,6 +160,9 @@ struct agp_bridge_data {
#ifndef PCI_DEVICE_ID_VIA_8363_0
#define PCI_DEVICE_ID_VIA_8363_0 0x0305
#endif
#ifndef PCI_DEVICE_ID_VIA_82C694X_0
#define PCI_DEVICE_ID_VIA_82C694X_0 0x0605
#endif
#ifndef PCI_DEVICE_ID_INTEL_810_0
#define PCI_DEVICE_ID_INTEL_810_0 0x7120
#endif
......@@ -196,8 +202,8 @@ struct agp_bridge_data {
#ifndef PCI_DEVICE_ID_AMD_IRONGATE_0
#define PCI_DEVICE_ID_AMD_IRONGATE_0 0x7006
#endif
#ifndef PCI_DEVICE_ID_AMD_761_0
#define PCI_DEVICE_ID_AMD_761_0 0x700e
#ifndef PCI_DEVICE_ID_AMD_762_0
#define PCI_DEVICE_ID_AMD_762_0 0x700C
#endif
#ifndef PCI_VENDOR_ID_AL
#define PCI_VENDOR_ID_AL 0x10b9
......
......@@ -38,6 +38,7 @@
#include <linux/init.h>
#include <linux/pagemap.h>
#include <linux/miscdevice.h>
#include <linux/pm.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
......@@ -48,6 +49,7 @@
MODULE_AUTHOR("Jeff Hartmann <jhartmann@precisioninsight.com>");
MODULE_PARM(agp_try_unsupported, "1i");
MODULE_LICENSE("GPL and additional rights");
EXPORT_SYMBOL(agp_free_memory);
EXPORT_SYMBOL(agp_allocate_memory);
EXPORT_SYMBOL(agp_copy_info);
......@@ -636,6 +638,15 @@ static int agp_generic_create_gatt_table(void)
return 0;
}
static int agp_generic_suspend(void)
{
return 0;
}
static void agp_generic_resume(void)
{
}
static int agp_generic_free_gatt_table(void)
{
int page_order;
......@@ -784,28 +795,31 @@ static void agp_generic_free_by_type(agp_memory * curr)
static unsigned long agp_generic_alloc_page(void)
{
void *pt;
pt = (void *) __get_free_page(GFP_KERNEL);
if (pt == NULL) {
struct page * page;
page = alloc_page(GFP_KERNEL);
if (page == NULL) {
return 0;
}
atomic_inc(&virt_to_page(pt)->count);
set_bit(PG_locked, &virt_to_page(pt)->flags);
atomic_inc(&page->count);
set_bit(PG_locked, &page->flags);
atomic_inc(&agp_bridge.current_memory_agp);
return (unsigned long) pt;
return (unsigned long)page_address(page);
}
static void agp_generic_destroy_page(unsigned long page)
static void agp_generic_destroy_page(unsigned long addr)
{
void *pt = (void *) page;
void *pt = (void *) addr;
struct page *page;
if (pt == NULL) {
return;
}
atomic_dec(&virt_to_page(pt)->count);
clear_bit(PG_locked, &virt_to_page(pt)->flags);
wake_up(&virt_to_page(pt)->wait);
page = virt_to_page(pt);
atomic_dec(&page->count);
clear_bit(PG_locked, &page->flags);
wake_up(&page->wait);
free_page((unsigned long) pt);
atomic_dec(&agp_bridge.current_memory_agp);
}
......@@ -1092,6 +1106,8 @@ static int __init intel_i810_setup(struct pci_dev *i810_dev)
agp_bridge.free_by_type = intel_i810_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
......@@ -1243,6 +1259,10 @@ static unsigned long intel_mask_memory(unsigned long addr, int type)
return addr | agp_bridge.masks[0].mask;
}
static void intel_resume(void)
{
intel_configure();
}
/* Setup function */
static gatt_mask intel_generic_masks[] =
......@@ -1285,6 +1305,8 @@ static int __init intel_generic_setup (struct pci_dev *pdev)
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = intel_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
......@@ -1316,6 +1338,8 @@ static int __init intel_840_setup (struct pci_dev *pdev)
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
......@@ -1347,6 +1371,8 @@ static int __init intel_850_setup (struct pci_dev *pdev)
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
......@@ -1465,6 +1491,8 @@ static int __init via_generic_setup (struct pci_dev *pdev)
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
......@@ -1577,6 +1605,8 @@ static int __init sis_generic_setup (struct pci_dev *pdev)
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
......@@ -1953,6 +1983,8 @@ static int __init amd_irongate_setup (struct pci_dev *pdev)
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = agp_generic_alloc_page;
agp_bridge.agp_destroy_page = agp_generic_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
......@@ -2108,15 +2140,15 @@ static void ali_cache_flush(void)
static unsigned long ali_alloc_page(void)
{
void *pt;
struct page *page;
u32 temp;
pt = (void *) __get_free_page(GFP_KERNEL);
if (pt == NULL)
page = alloc_page(GFP_KERNEL);
if (page == NULL)
return 0;
atomic_inc(&virt_to_page(pt)->count);
set_bit(PG_locked, &virt_to_page(pt)->flags);
atomic_inc(&page->count);
set_bit(PG_locked, &page->flags);
atomic_inc(&agp_bridge.current_memory_agp);
global_cache_flush();
......@@ -2125,16 +2157,17 @@ static unsigned long ali_alloc_page(void)
pci_read_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL, &temp);
pci_write_config_dword(agp_bridge.dev, ALI_CACHE_FLUSH_CTRL,
(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
virt_to_phys((void *)pt)) |
virt_to_phys(page_address(page))) |
ALI_CACHE_FLUSH_EN ));
}
return (unsigned long) pt;
return (unsigned long)page_address(page);
}
static void ali_destroy_page(unsigned long page)
static void ali_destroy_page(unsigned long addr)
{
u32 temp;
void *pt = (void *) page;
void *pt = (void *) addr;
struct page *page;
if (pt == NULL)
return;
......@@ -2149,9 +2182,10 @@ static void ali_destroy_page(unsigned long page)
ALI_CACHE_FLUSH_EN));
}
atomic_dec(&virt_to_page(pt)->count);
clear_bit(PG_locked, &virt_to_page(pt)->flags);
wake_up(&virt_to_page(pt)->wait);
page = virt_to_page(pt);
atomic_dec(&page->count);
clear_bit(PG_locked, &page->flags);
wake_up(&page->wait);
free_page((unsigned long) pt);
atomic_dec(&agp_bridge.current_memory_agp);
}
......@@ -2197,6 +2231,8 @@ static int __init ali_generic_setup (struct pci_dev *pdev)
agp_bridge.free_by_type = agp_generic_free_by_type;
agp_bridge.agp_alloc_page = ali_alloc_page;
agp_bridge.agp_destroy_page = ali_destroy_page;
agp_bridge.suspend = agp_generic_suspend;
agp_bridge.resume = agp_generic_resume;
agp_bridge.cant_use_aperture = 0;
return 0;
......@@ -2410,7 +2446,7 @@ static int serverworks_fetch_size(void)
&temp);
pci_write_config_dword(agp_bridge.dev,
serverworks_private.gart_addr_ofs,
0xfe000000);
SVWRKS_SIZE_MASK);
pci_read_config_dword(agp_bridge.dev,
serverworks_private.gart_addr_ofs,
&temp2);
......@@ -2895,11 +2931,11 @@ static struct {
"AMD",
"Irongate",
amd_irongate_setup },
{ PCI_DEVICE_ID_AMD_761_0,
{ PCI_DEVICE_ID_AMD_762_0,
PCI_VENDOR_ID_AMD,
AMD_761,
AMD_IRONGATE,
"AMD",
"761",
"AMD 760MP",
amd_irongate_setup },
{ 0,
PCI_VENDOR_ID_AMD,
......@@ -2952,6 +2988,7 @@ static struct {
"Intel",
"Generic",
intel_generic_setup },
#endif /* CONFIG_AGP_INTEL */
#ifdef CONFIG_AGP_SIS
......@@ -2979,29 +3016,11 @@ static struct {
"SiS",
"530",
sis_generic_setup },
{ PCI_DEVICE_ID_SI_630,
PCI_VENDOR_ID_SI,
SIS_GENERIC,
"SiS",
"Generic",
sis_generic_setup },
{ PCI_DEVICE_ID_SI_540,
{ PCI_DEVICE_ID_SI_735,
PCI_VENDOR_ID_SI,
SIS_GENERIC,
"SiS",
"Generic",
sis_generic_setup },
{ PCI_DEVICE_ID_SI_620,
PCI_VENDOR_ID_SI,
SIS_GENERIC,
"SiS",
"Generic",
sis_generic_setup },
{ PCI_DEVICE_ID_SI_530,
PCI_VENDOR_ID_SI,
SIS_GENERIC,
"SiS",
"Generic",
"735",
sis_generic_setup },
{ 0,
PCI_VENDOR_ID_SI,
......@@ -3048,6 +3067,12 @@ static struct {
"Via",
"Apollo Pro KT133",
via_generic_setup },
{ PCI_DEVICE_ID_VIA_8367_0,
PCI_VENDOR_ID_VIA,
VIA_APOLLO_KT133,
"Via",
"Apollo Pro KT266",
via_generic_setup },
{ 0,
PCI_VENDOR_ID_VIA,
VIA_GENERIC,
......@@ -3372,7 +3397,7 @@ static int __init agp_backend_initialize(void)
size_value = agp_bridge.fetch_size();
if (size_value == 0) {
printk(KERN_ERR PFX "unable to detrimine aperture size.\n");
printk(KERN_ERR PFX "unable to determine aperture size.\n");
rc = -EINVAL;
goto err_out;
}
......@@ -3434,6 +3459,19 @@ static void agp_backend_cleanup(void)
}
}
static int agp_power(struct pm_dev *dev, pm_request_t rq, void *data)
{
switch(rq)
{
case PM_SUSPEND:
return agp_bridge.suspend();
case PM_RESUME:
agp_bridge.resume();
return 0;
}
return 0;
}
extern int agp_frontend_initialize(void);
extern void agp_frontend_cleanup(void);
......@@ -3468,11 +3506,14 @@ static int __init agp_init(void)
}
inter_module_register("drm_agp", THIS_MODULE, &drm_agp);
pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge.dev), agp_power);
return 0;
}
static void __exit agp_cleanup(void)
{
pm_unregister_all(agp_power);
agp_frontend_cleanup();
agp_backend_cleanup();
inter_module_unregister("drm_agp");
......
......@@ -661,6 +661,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
p = (long) kmalloc(structsize, GFP_KERNEL);
if (!p)
return -ENOMEM;
memset((void *)p, 0, structsize);
vc_cons[currcons].d = (struct vc_data *)p;
vt_cons[currcons] = (struct vt_struct *)(p+sizeof(struct vc_data));
visual_init(currcons, 1);
......
......@@ -911,6 +911,10 @@ static void kbd_bh(unsigned long dummy)
EXPORT_SYMBOL(keyboard_tasklet);
DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
typedef void (pm_kbd_func) (void);
pm_callback pm_kbd_request_override = NULL;
int __init kbd_init(void)
{
int i;
......@@ -934,7 +938,7 @@ int __init kbd_init(void)
tasklet_enable(&keyboard_tasklet);
tasklet_schedule(&keyboard_tasklet);
pm_kbd = pm_register(PM_SYS_DEV, PM_SYS_KBC, NULL);
pm_kbd = pm_register(PM_SYS_DEV, PM_SYS_KBC, pm_kbd_request_override);
return 0;
}
......@@ -397,6 +397,32 @@ char pckbd_unexpected_up(unsigned char keycode)
return 0200;
}
void pckbd_pm_resume(void)
{
#if defined CONFIG_PSMOUSE
unsigned long flags;
if (queue) { /* Aux port detected */
if (aux_count == 0) { /* Mouse not in use */
spin_lock_irqsave(&kbd_controller_lock, flags);
/*
* Dell Lat. C600 A06 enables mouse after resume.
* When user touches the pad, it posts IRQ 12
* (which we do not process), thus holding keyboard.
*/
kbd_write_command(KBD_CCMD_MOUSE_DISABLE);
/* kbd_write_cmd(AUX_INTS_OFF); */ /* Config & lock */
kb_wait();
kbd_write_command(KBD_CCMD_WRITE_MODE);
kb_wait();
kbd_write_output(AUX_INTS_OFF);
spin_unlock_irqrestore(&kbd_controller_lock, flags);
}
}
#endif
}
static inline void handle_mouse_event(unsigned char scancode)
{
#ifdef CONFIG_PSMOUSE
......@@ -521,7 +547,7 @@ static int send_data(unsigned char data)
mdelay(1);
if (!--timeout) {
#ifdef KBD_REPORT_TIMEOUTS
printk(KERN_WARNING "keyboard: Timeout - AT keyboard not present?\n");
printk(KERN_WARNING "keyboard: Timeout - AT keyboard not present?(%02x)\n", data);
#endif
return 0;
}
......@@ -707,6 +733,53 @@ static void kbd_write_output_w(int data)
spin_unlock_irqrestore(&kbd_controller_lock, flags);
}
#if defined(__alpha__)
/*
* Some Alphas cannot mask some/all interrupts, so we have to
* make sure not to allow interrupts AT ALL when polling for
* specific return values from the keyboard.
*
* I think this should work on any architecture, but for now, only Alpha.
*/
static int kbd_write_command_w_and_wait(int data)
{
unsigned long flags;
int input;
spin_lock_irqsave(&kbd_controller_lock, flags);
kb_wait();
kbd_write_command(data);
input = kbd_wait_for_input();
spin_unlock_irqrestore(&kbd_controller_lock, flags);
return input;
}
static int kbd_write_output_w_and_wait(int data)
{
unsigned long flags;
int input;
spin_lock_irqsave(&kbd_controller_lock, flags);
kb_wait();
kbd_write_output(data);
input = kbd_wait_for_input();
spin_unlock_irqrestore(&kbd_controller_lock, flags);
return input;
}
#else
static int kbd_write_command_w_and_wait(int data)
{
kbd_write_command_w(data);
return kbd_wait_for_input();
}
static int kbd_write_output_w_and_wait(int data)
{
kbd_write_output_w(data);
return kbd_wait_for_input();
}
#endif /* __alpha__ */
#if defined CONFIG_PSMOUSE
static void kbd_write_cmd(int cmd)
{
......@@ -790,8 +863,8 @@ static char * __init initialize_kbd(void)
| KBD_MODE_KCC);
/* ibm powerpc portables need this to use scan-code set 1 -- Cort */
kbd_write_command_w(KBD_CCMD_READ_MODE);
if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
if (!(kbd_write_command_w_and_wait(KBD_CCMD_READ_MODE) & KBD_MODE_KCC))
{
/*
* If the controller does not support conversion,
* Set the keyboard to scan-code set 1.
......@@ -802,20 +875,16 @@ static char * __init initialize_kbd(void)
kbd_wait_for_input();
}
kbd_write_output_w(KBD_CMD_ENABLE);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
if (kbd_write_output_w_and_wait(KBD_CMD_ENABLE) != KBD_REPLY_ACK)
return "Enable keyboard: no ACK";
/*
* Finally, set the typematic rate to maximum.
*/
kbd_write_output_w(KBD_CMD_SET_RATE);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
return "Set rate: no ACK";
kbd_write_output_w(0x00);
if (kbd_wait_for_input() != KBD_REPLY_ACK)
if (kbd_write_output_w_and_wait(KBD_CMD_SET_RATE) != KBD_REPLY_ACK)
return "Set rate: no ACK";
if (kbd_write_output_w_and_wait(0x00) != KBD_REPLY_ACK)
return "Set rate: no 2nd ACK";
return NULL;
}
......@@ -1109,13 +1178,20 @@ static struct miscdevice psaux_mouse = {
static int __init psaux_init(void)
{
int retval;
if (!detect_auxiliary_port())
return -EIO;
misc_register(&psaux_mouse);
if ((retval = misc_register(&psaux_mouse)))
return retval;
queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
if (queue == NULL)
panic("psaux_init(): out of memory");
if (queue == NULL) {
printk(KERN_ERR "psaux_init(): out of memory\n");
misc_deregister(&psaux_mouse);
return -ENOMEM;
}
memset(queue, 0, sizeof(*queue));
queue->head = queue->tail = 0;
init_waitqueue_head(&queue->proc_list);
......
......@@ -1591,12 +1591,9 @@ random_ioctl(struct inode * inode, struct file * file,
return -EPERM;
p = (int *) arg;
ent_count = random_state->entropy_count;
if (put_user(ent_count, p++))
return -EFAULT;
if (get_user(size, p))
return -EFAULT;
if (put_user(random_state->poolinfo.poolwords, p++))
if (put_user(ent_count, p++) ||
get_user(size, p) ||
put_user(random_state->poolinfo.poolwords, p++))
return -EFAULT;
if (size < 0)
return -EINVAL;
......@@ -1809,13 +1806,13 @@ static int uuid_strategy(ctl_table *table, int *name, int nlen,
if (uuid[8] == 0)
generate_random_uuid(uuid);
get_user(len, oldlenp);
if (get_user(len, oldlenp))
return -EFAULT;
if (len) {
if (len > 16)
len = 16;
if (copy_to_user(oldval, uuid, len))
return -EFAULT;
if (put_user(len, oldlenp))
if (copy_to_user(oldval, uuid, len) ||
put_user(len, oldlenp))
return -EFAULT;
}
return 1;
......
......@@ -48,6 +48,7 @@ static int minor = -1;
static int verbose; /* = 0 */
static int fnkeyinit; /* = 0 */
static int camera; /* = 0 */
extern int is_sony_vaio_laptop; /* set in DMI table parse routines */
/* Inits the queue */
static inline void sonypi_initq(void) {
......@@ -108,32 +109,23 @@ static inline int sonypi_emptyq(void) {
}
static void sonypi_ecrset(u16 addr, u16 value) {
int n = 100;
while (n-- && (inw_p(SONYPI_CST_IOPORT) & 3))
udelay(1);
wait_on_command(inw_p(SONYPI_CST_IOPORT) & 3);
outw_p(0x81, SONYPI_CST_IOPORT);
while (inw_p(SONYPI_CST_IOPORT) & 2)
udelay(1);
wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
outw_p(addr, SONYPI_DATA_IOPORT);
while (inw_p(SONYPI_CST_IOPORT) & 2)
udelay(1);
wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
outw_p(value, SONYPI_DATA_IOPORT);
while (inw_p(SONYPI_CST_IOPORT) & 2)
udelay(1);
wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
}
static u16 sonypi_ecrget(u16 addr) {
int n = 100;
while (n-- && (inw_p(SONYPI_CST_IOPORT) & 3))
udelay(1);
wait_on_command(inw_p(SONYPI_CST_IOPORT) & 3);
outw_p(0x80, SONYPI_CST_IOPORT);
while (inw_p(SONYPI_CST_IOPORT) & 2)
udelay(1);
wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
outw_p(addr, SONYPI_DATA_IOPORT);
while (inw_p(SONYPI_CST_IOPORT) & 2)
udelay(1);
wait_on_command(inw_p(SONYPI_CST_IOPORT) & 2);
return inw_p(SONYPI_DATA_IOPORT);
}
......@@ -189,8 +181,7 @@ static void __devexit sonypi_r505_dis(void) {
static u8 sonypi_call1(u8 dev) {
u8 v1, v2;
while (inb_p(sonypi_device.ioport2) & 2)
udelay(1);
wait_on_command(inb_p(sonypi_device.ioport2) & 2);
outb(dev, sonypi_device.ioport2);
v1 = inb_p(sonypi_device.ioport2);
v2 = inb_p(sonypi_device.ioport1);
......@@ -200,14 +191,10 @@ static u8 sonypi_call1(u8 dev) {
static u8 sonypi_call2(u8 dev, u8 fn) {
u8 v1;
while (inb_p(sonypi_device.ioport2) & 2)
udelay(1);
wait_on_command(inb_p(sonypi_device.ioport2) & 2);
outb(dev, sonypi_device.ioport2);
while (inb_p(sonypi_device.ioport2) & 2)
udelay(1);
wait_on_command(inb_p(sonypi_device.ioport2) & 2);
outb(fn, sonypi_device.ioport1);
v1 = inb_p(sonypi_device.ioport1);
return v1;
}
......@@ -215,18 +202,12 @@ static u8 sonypi_call2(u8 dev, u8 fn) {
static u8 sonypi_call3(u8 dev, u8 fn, u8 v) {
u8 v1;
while (inb_p(sonypi_device.ioport2) & 2)
udelay(1);
wait_on_command(inb_p(sonypi_device.ioport2) & 2);
outb(dev, sonypi_device.ioport2);
while (inb_p(sonypi_device.ioport2) & 2)
udelay(1);
wait_on_command(inb_p(sonypi_device.ioport2) & 2);
outb(fn, sonypi_device.ioport1);
while (inb_p(sonypi_device.ioport2) & 2)
udelay(1);
wait_on_command(inb_p(sonypi_device.ioport2) & 2);
outb(v, sonypi_device.ioport1);
v1 = inb_p(sonypi_device.ioport1);
return v1;
}
......@@ -246,11 +227,8 @@ static u8 sonypi_read(u8 fn) {
/* Set brightness, hue etc */
static void sonypi_set(u8 fn, u8 v) {
int n = 100;
while (n--)
if (sonypi_call3(0x90, fn, v) == 0)
break;
wait_on_command(sonypi_call3(0x90, fn, v));
}
/* Tests if the camera is ready */
......@@ -325,6 +303,13 @@ void sonypi_irq(int irq, void *dev_id, struct pt_regs *regs) {
v1 = inb_p(sonypi_device.ioport1);
v2 = inb_p(sonypi_device.ioport2);
if ((v2 & SONYPI_NORMAL_PKEY_EV) == SONYPI_NORMAL_PKEY_EV) {
for (i = 0; sonypi_pkeyev[i].event; i++)
if (sonypi_pkeyev[i].data == v1) {
event = sonypi_pkeyev[i].event;
goto found;
}
}
if ((v2 & sonypi_jogger_ev) == sonypi_jogger_ev) {
for (i = 0; sonypi_joggerev[i].event; i++)
if (sonypi_joggerev[i].data == v1) {
......@@ -608,7 +593,7 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev,
for (i = 0; irq_list[i].irq; i++) {
if (!request_irq(irq_list[i].irq, sonypi_irq,
SA_INTERRUPT, "sonypi", sonypi_irq)) {
SA_SHIRQ, "sonypi", sonypi_irq)) {
sonypi_device.irq = irq_list[i].irq;
sonypi_device.bits = irq_list[i].bits;
break;
......@@ -690,7 +675,10 @@ static struct pci_driver sonypi_driver = {
};
static int __init sonypi_init_module(void) {
return pci_module_init(&sonypi_driver);
if (is_sony_vaio_laptop)
return pci_module_init(&sonypi_driver);
else
return -ENODEV;
}
static void __exit sonypi_cleanup_module(void) {
......@@ -703,6 +691,8 @@ module_exit(sonypi_cleanup_module);
MODULE_AUTHOR("Stelian Pop <stelian.pop@fr.alcove.com>");
MODULE_DESCRIPTION("Sony Programmable I/O Control Device driver");
MODULE_LICENSE("GPL");
MODULE_PARM(minor,"i");
MODULE_PARM_DESC(minor, "minor number of the misc device, default is -1 (automatic)");
......
......@@ -35,7 +35,7 @@
#ifdef __KERNEL__
#define SONYPI_DRIVER_MAJORVERSION 1
#define SONYPI_DRIVER_MINORVERSION 2
#define SONYPI_DRIVER_MINORVERSION 5
#include <linux/types.h>
#include <linux/pci.h>
......@@ -138,6 +138,7 @@ static struct sonypi_irq_list sonypi_r505_irq_list[] = {
#define SONYPI_NORMAL_FNKEY_EV 0x20
#define SONYPI_R505_FNKEY_EV 0x08
#define SONYPI_BLUETOOTH_EV 0x30
#define SONYPI_NORMAL_PKEY_EV 0x40
struct sonypi_event {
u8 data;
......@@ -189,6 +190,14 @@ static struct sonypi_event sonypi_fnkeyev[] = {
{ 0x00, 0x00 }
};
/* The set of possible program key events */
static struct sonypi_event sonypi_pkeyev[] = {
{ 0x01, SONYPI_EVENT_PKEY_P1 },
{ 0x02, SONYPI_EVENT_PKEY_P2 },
{ 0x04, SONYPI_EVENT_PKEY_P3 },
{ 0x00, 0x00 }
};
/* The set of possible bluetooth events */
static struct sonypi_event sonypi_blueev[] = {
{ 0x55, SONYPI_EVENT_BLUETOOTH_PRESSED },
......@@ -223,6 +232,14 @@ struct sonypi_device {
int model;
};
#define wait_on_command(command) { \
unsigned int n = 10000; \
while (--n && (command)) \
udelay(1); \
if (!n) \
printk(KERN_WARNING "sonypi command failed at " __FILE__ " : " __FUNCTION__ "(line %d)\n", __LINE__); \
}
#endif /* __KERNEL__ */
#endif /* _SONYPI_PRIV_H_ */
This diff is collapsed.
......@@ -18,6 +18,7 @@
#include <linux/fcntl.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <asm/io.h>
#include <asm/bitops.h>
......@@ -27,11 +28,6 @@
#undef TTY_DEBUG_WAIT_UNTIL_SENT
#undef DEBUG
#ifdef DEBUG
# define PRINTK(x) printk (x)
#else
# define PRINTK(x) /**/
#endif
/*
* Internal flag options for termios setting behavior
......@@ -145,18 +141,19 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios
static int set_termios(struct tty_struct * tty, unsigned long arg, int opt)
{
struct termios tmp_termios;
int retval;
int retval = tty_check_change(tty);
retval = tty_check_change(tty);
if (retval)
return retval;
if (opt & TERMIOS_TERMIO) {
memcpy(&tmp_termios, tty->termios, sizeof(struct termios));
if (user_termio_to_kernel_termios(&tmp_termios, (struct termio *) arg))
if (user_termio_to_kernel_termios(&tmp_termios,
(struct termio *) arg))
return -EFAULT;
} else {
if (user_termios_to_kernel_termios(&tmp_termios, (struct termios *) arg))
if (user_termios_to_kernel_termios(&tmp_termios,
(struct termios *) arg))
return -EFAULT;
}
......@@ -232,9 +229,7 @@ static int get_sgttyb(struct tty_struct * tty, struct sgttyb * sgttyb)
tmp.sg_erase = tty->termios->c_cc[VERASE];
tmp.sg_kill = tty->termios->c_cc[VKILL];
tmp.sg_flags = get_sgflags(tty);
if (copy_to_user(sgttyb, &tmp, sizeof(tmp)))
return -EFAULT;
return 0;
return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
}
static void set_sgflags(struct termios * termios, int flags)
......@@ -247,7 +242,8 @@ static void set_sgflags(struct termios * termios, int flags)
termios->c_lflag &= ~ICANON;
}
if (flags & 0x08) { /* echo */
termios->c_lflag |= ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
termios->c_lflag |= ECHO | ECHOE | ECHOK |
ECHOCTL | ECHOKE | IEXTEN;
}
if (flags & 0x10) { /* crmod */
termios->c_oflag |= OPOST | ONLCR;
......@@ -293,9 +289,7 @@ static int get_tchars(struct tty_struct * tty, struct tchars * tchars)
tmp.t_stopc = tty->termios->c_cc[VSTOP];
tmp.t_eofc = tty->termios->c_cc[VEOF];
tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
if (copy_to_user(tchars, &tmp, sizeof(tmp)))
return -EFAULT;
return 0;
return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
}
static int set_tchars(struct tty_struct * tty, struct tchars * tchars)
......@@ -325,9 +319,7 @@ static int get_ltchars(struct tty_struct * tty, struct ltchars * ltchars)
tmp.t_flushc = tty->termios->c_cc[VEOL2]; /* what is flushc anyway? */
tmp.t_werasc = tty->termios->c_cc[VWERASE];
tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
if (copy_to_user(ltchars, &tmp, sizeof(tmp)))
return -EFAULT;
return 0;
return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
}
static int set_ltchars(struct tty_struct * tty, struct ltchars * ltchars)
......@@ -480,7 +472,7 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
return 0;
case TIOCSLCKTRMIOS:
if (!suser())
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios *) arg))
return -EFAULT;
......@@ -493,9 +485,8 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
if (tty->driver.type != TTY_DRIVER_TYPE_PTY ||
tty->driver.subtype != PTY_TYPE_MASTER)
return -ENOTTY;
retval = get_user(pktmode, (int *) arg);
if (retval)
return retval;
if (get_user(pktmode, (int *) arg))
return -EFAULT;
if (pktmode) {
if (!tty->packet) {
tty->packet = 1;
......@@ -508,9 +499,8 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
case TIOCGSOFTCAR:
return put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg);
case TIOCSSOFTCAR:
retval = get_user(arg, (unsigned int *) arg);
if (retval)
return retval;
if (get_user(arg, (unsigned int *) arg))
return -EFAULT;
tty->termios->c_cflag =
((tty->termios->c_cflag & ~CLOCAL) |
(arg ? CLOCAL : 0));
......@@ -519,3 +509,5 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
return -ENOIOCTLCMD;
}
}
EXPORT_SYMBOL(n_tty_ioctl);
......@@ -92,8 +92,9 @@ unsigned int video_scan_lines;
*/
#if defined(__i386__) || defined(__alpha__) || defined(__powerpc__) \
|| (defined(__mips__) && !defined(CONFIG_SGI_IP22)) \
|| (defined(__arm__) && defined(CONFIG_HOST_FOOTBRIDGE))
|| (defined(__mips__) && defined(CONFIG_ISA)) \
|| (defined(__arm__) && defined(CONFIG_HOST_FOOTBRIDGE)) \
|| defined(__x86_64__)
static void
kd_nosound(unsigned long ignored)
......
......@@ -188,4 +188,8 @@ else
define_bool CONFIG_BLK_DEV_IDE_MODES n
fi
dep_tristate 'Support for IDE Raid controllers' CONFIG_BLK_DEV_ATARAID $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL
dep_tristate ' Support Promise software RAID (Fasttrak(tm))' CONFIG_BLK_DEV_ATARAID_PDC $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID
dep_tristate ' Highpoint 370 software RAID' CONFIG_BLK_DEV_ATARAID_HPT $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID
endmenu
......@@ -66,6 +66,12 @@ ide-obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o
ide-obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
ide-obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o
# The virtualised raid layers MUST come after the ide itself or bad stuff
# will happen.
obj-$(CONFIG_BLK_DEV_ATARAID) += ataraid.o
obj-$(CONFIG_BLK_DEV_ATARAID_PDC) += pdcraid.o
obj-$(CONFIG_BLK_DEV_ATARAID_HPT) += hptraid.o
ide-obj-$(CONFIG_PROC_FS) += ide-proc.o
ide-mod-objs := $(export-objs) $(ide-obj-y)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
struct highpoint_raid_conf
{
int8_t filler1[32];
u_int32_t magic;
#define HPT_MAGIC_OK 0x5a7816f0
#define HPT_MAGIC_BAD 0x5a7816fd
u_int32_t magic_0;
u_int32_t magic_1;
u_int32_t order;
#define HPT_O_MIRROR 0x01
#define HPT_O_STRIPE 0x02
#define HPT_O_OK 0x04
u_int8_t raid_disks;
u_int8_t raid0_shift;
u_int8_t type;
#define HPT_T_RAID_0 0x00
#define HPT_T_RAID_1 0x01
#define HPT_T_RAID_01_RAID_0 0x02
#define HPT_T_SPAN 0x03
#define HPT_T_RAID_3 0x04
#define HPT_T_RAID_5 0x05
#define HPT_T_SINGLEDISK 0x06
#define HPT_T_RAID_01_RAID_1 0x07
u_int8_t disk_number;
u_int32_t total_secs;
u_int32_t disk_mode;
u_int32_t boot_mode;
u_int8_t boot_disk;
u_int8_t boot_protect;
u_int8_t error_log_entries;
u_int8_t error_log_index;
struct
{
u_int32_t timestamp;
u_int8_t reason;
#define HPT_R_REMOVED 0xfe
#define HPT_R_BROKEN 0xff
u_int8_t disk;
u_int8_t status;
u_int8_t sectors;
u_int32_t lba;
} errorlog[32];
u_int8_t filler[60];
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -908,6 +908,9 @@ init_trackpad(int id)
r1_buffer[5],
0x03, /*r1_buffer[6],*/
r1_buffer[7]);
/* Without this flush, the trackpad may be locked up */
adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
}
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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