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

Merge bk://jfs.bkbits.net/linux-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents f67f7c15 551d9631
...@@ -247,6 +247,28 @@ ChangeLog ...@@ -247,6 +247,28 @@ ChangeLog
Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
2.0.20:
- Support non-resident directory index bitmaps. This means we now cope
with huge directories without problems.
- Fix a page leak that manifested itself in some cases when reading
directory contents.
- Internal cleanups.
2.0.19:
- Fix race condition and improvements in block i/o interface.
- Optimization when reading compressed files.
2.0.18:
- Fix race condition in reading of compressed files.
2.0.17:
- Cleanups and optimizations.
2.0.16:
- Fix stupid bug introduced in 2.0.15 in new attribute inode API.
- Big internal cleanup replacing the mftbmp access hacks by using the
new attribute inode API instead.
2.0.15:
- Bug fix in parsing of remount options.
- Internal changes implementing attribute (fake) inodes allowing all
attribute i/o to go via the page cache and to use all the normal
vfs/mm functionality.
2.0.14: 2.0.14:
- Internal changes improving run list merging code and minor locking - Internal changes improving run list merging code and minor locking
change to not rely on BKL in ntfs_statfs(). change to not rely on BKL in ntfs_statfs().
......
usb-xpad - Linux USB driver for XBOX HID gamecontrollers
This is the very first release of a driver for XBOX gamecontrollers.
Basically, this was hacked away in just a few hours, so don't expect
miracles.
0. Status
---------
For now, this driver has only been tested on just one Linux-Box.
This one is running a 2.4.18 kernel with usb-uhci on an amd athlon 600.
The jstest-program from joystick-1.2.15 (jstest-version 2.1.0) reports
8 axes and 10 buttons.
Alls 8 axes work, though they all have the same range (-32768..32767)
and the zero-setting is not correct for the triggers.
9 of the 10 buttons work (my black button does not work, though I can
see no reason for it not to), all of them are in digital mode, though
(the six buttons on the right side are "analog" ones).
1. USB adapter
--------------
Before you can actually use the driver, you need to get yourself an
adapter cable to connect the XBOX-controller to your Linux-Box.
Such a cable is pretty easy to build. The Controller itself is a USB device
(a hub with three ports; two expansion slots and the controller device)
with the only differnce in a nonstandard connector (5 pins vs. 4 on
standard USB connector).
You just need to solder an USB connector onto the cable and keep the
yellow wire unconnected. The other pins have the same order on both
connectors so there no magic to it. Detailed info on these matters can be found
on the net.
Thanks to the trip splitter found on the cable you don't even need to cut the
original cable, you can buy an extension cable and cut that instead. That way,
you can still use the controller with your XBOX, if you have one ;)
2. driver installation
----------------------
Once you have the adapter cable and the controller is connected, you need
to load your USB subsystem and should cat /proc/bus/usb/devices.
There should be an entry like the one in InterAct_german.dump.
Don't worry if the vendor and/or product ID don't match, those are easy to
add to the driver. You could do it yourself, just add the appropriate line
into the list after the line
'} xpad_device[] = {'
, but before the line that says
'{ 0x0000, 0x0000, "unknown...." }'.
In theory, the driver should work with other controllers than mine
(InterAct PowerPad pro, bought in Germany) just fine, but see for yourself.
If you compiled and installed the driver, test the functionality:
> modprobe usb-xpad
> modprobe joydev
> jstest /dev/input/js0
There should be a single line showing 18 inputs (8 axes, 10 buttons), and
it's values should change if you move the sticks and push the buttons.
It works? Voila, your done ;)
3. Thanks
---------
I have to thank ITO Takayuki for the detailed info on his site
http://euc.jp/periphs/xbox-controller.ja.html.
His useful info and both the usb-skeleton as well as the iforce input driver
helped a lot in rapid prototyping the basic functionality.
--
Marko Friedemann <mfr@bmx-chemnitz.de>
2002-07-02
This diff is collapsed.
...@@ -22,9 +22,8 @@ USB-specific: ...@@ -22,9 +22,8 @@ USB-specific:
-ENODEV specified USB-device or bus doesn't exist -ENODEV specified USB-device or bus doesn't exist
-ENXIO a control or interrupt URB is already queued to this endpoint; -ENXIO host controller driver does not support queuing of this type
or (UHCI only) a bulk URB is already queued to this endpoint of urb. (treat as a host controller bug.)
and USB_QUEUE_BULK wasn't used
-EINVAL a) Invalid transfer type specified (or not supported) -EINVAL a) Invalid transfer type specified (or not supported)
b) Invalid interrupt interval (0<=n<256) b) Invalid interrupt interval (0<=n<256)
...@@ -90,9 +89,9 @@ one or more packets could finish before an error stops further endpoint I/O. ...@@ -90,9 +89,9 @@ one or more packets could finish before an error stops further endpoint I/O.
greater than either the max packet size of the greater than either the max packet size of the
endpoint or the remaining buffer size. "Babble". endpoint or the remaining buffer size. "Babble".
-EREMOTEIO The endpoint returned less than max packet size -EREMOTEIO The data read from the endpoint did not fill the
and that amount did not fill the specified buffer specified buffer, and URB_SHORT_NOT_OK was set in
(and USB_DISBLE_SPD was not set in transfer_flags) urb->transfer_flags.
-ETIMEDOUT transfer timed out, NAK -ETIMEDOUT transfer timed out, NAK
......
...@@ -10,10 +10,12 @@ ...@@ -10,10 +10,12 @@
LDFLAGS_vmlinux :=-p -X -T arch/arm/vmlinux.lds LDFLAGS_vmlinux :=-p -X -T arch/arm/vmlinux.lds
OBJCOPYFLAGS :=-O binary -R .note -R .comment -S OBJCOPYFLAGS :=-O binary -R .note -R .comment -S
GZFLAGS :=-9 GZFLAGS :=-9
CFLAGS +=-pipe #CFLAGS +=-pipe
CFLAGS :=$(CFLAGS:-O2=-Os)
ifneq ($(CONFIG_NO_FRAME_POINTER),y) ifneq ($(CONFIG_NO_FRAME_POINTER),y)
CFLAGS :=$(CFLAGS:-fomit-frame-pointer=) CFLAGS :=$(CFLAGS: -fomit-frame-pointer=)
endif endif
ifeq ($(CONFIG_DEBUG_INFO),y) ifeq ($(CONFIG_DEBUG_INFO),y)
...@@ -24,7 +26,7 @@ endif ...@@ -24,7 +26,7 @@ endif
# the options further down the list override previous items. # the options further down the list override previous items.
# #
apcs-$(CONFIG_CPU_32) :=-mapcs-32 apcs-$(CONFIG_CPU_32) :=-mapcs-32
apcs-$(CONFIG_CPU_26) :=-mapcs-26 -mcpu=arm3 -Os apcs-$(CONFIG_CPU_26) :=-mapcs-26 -mcpu=arm3
# This selects which instruction set is used. # This selects which instruction set is used.
# Note that GCC is lame - it doesn't numerically define an # Note that GCC is lame - it doesn't numerically define an
...@@ -212,8 +214,11 @@ include/asm-arm/.proc: $(wildcard include/config/cpu/32.h) $(wildcard include/co ...@@ -212,8 +214,11 @@ include/asm-arm/.proc: $(wildcard include/config/cpu/32.h) $(wildcard include/co
@ln -sf proc-$(PROCESSOR) include/asm-arm/proc @ln -sf proc-$(PROCESSOR) include/asm-arm/proc
@touch $@ @touch $@
prepare: include/asm-arm/.arch include/asm-arm/.proc \ prepare: maketools
include/asm-arm/constants.h
.PHONY: maketools
maketools: include/asm-arm/.arch include/asm-arm/.proc \
include/asm-arm/constants.h include/linux/version.h FORCE
@$(MAKETOOLS) @$(MAKETOOLS)
vmlinux: arch/arm/vmlinux.lds vmlinux: arch/arm/vmlinux.lds
...@@ -222,6 +227,7 @@ arch/arm/vmlinux.lds: arch/arm/Makefile $(LDSCRIPT) \ ...@@ -222,6 +227,7 @@ arch/arm/vmlinux.lds: arch/arm/Makefile $(LDSCRIPT) \
$(wildcard include/config/cpu/32.h) \ $(wildcard include/config/cpu/32.h) \
$(wildcard include/config/cpu/26.h) \ $(wildcard include/config/cpu/26.h) \
$(wildcard include/config/arch/*.h) $(wildcard include/config/arch/*.h)
@echo ' Generating $@'
@sed 's/TEXTADDR/$(TEXTADDR)/;s/DATAADDR/$(DATAADDR)/' $(LDSCRIPT) >$@ @sed 's/TEXTADDR/$(TEXTADDR)/;s/DATAADDR/$(DATAADDR)/' $(LDSCRIPT) >$@
bzImage zImage zinstall Image bootpImage install: vmlinux bzImage zImage zinstall Image bootpImage install: vmlinux
...@@ -243,10 +249,6 @@ archmrproper: FORCE ...@@ -243,10 +249,6 @@ archmrproper: FORCE
archclean: FORCE archclean: FORCE
@$(MAKEBOOT) clean @$(MAKEBOOT) clean
# we need version.h
maketools: include/linux/version.h FORCE
@$(MAKETOOLS)
# My testing targets (that short circuit a few dependencies) # My testing targets (that short circuit a few dependencies)
zImg:; @$(MAKEBOOT) zImage zImg:; @$(MAKEBOOT) zImage
Img:; @$(MAKEBOOT) Image Img:; @$(MAKEBOOT) Image
......
...@@ -153,18 +153,15 @@ if [ "$CONFIG_ARCH_EP7211" = "y" -o \ ...@@ -153,18 +153,15 @@ if [ "$CONFIG_ARCH_EP7211" = "y" -o \
fi fi
endmenu endmenu
if [ "$CONFIG_ARCH_IOP310" = "y" ]; then mainmenu_option next_comment
mainmenu_option next_comment comment 'IOP310 Implementation Options'
comment 'IOP310 Implementation Options' dep_bool ' IQ80310' CONFIG_ARCH_IQ80310 $CONFIG_ARCH_IOP310
choice 'IOP310 System Type' \ comment 'IOP310 Chipset Features'
"IQ80310 CONFIG_ARCH_IQ80310" IQ80310 dep_bool 'Support Intel 80312 Application Accelerator Unit (EXPERIMENTAL)' CONFIG_IOP310_AAU $CONFIG_ARCH_IOP310 $CONFIG_EXPERIMENTAL
comment 'IOP310 Chipset Features' dep_bool 'Support Intel 80312 DMA (EXPERIMENTAL)' CONFIG_IOP310_DMA $CONFIG_ARCH_IOP310 $CONFIG_EXPERIMENTAL
bool 'Support Intel 80312 Application Accelerator Unit (EXPERIMENTAL)' CONFIG_IOP310_AAU dep_bool 'Support Intel 80312 Messaging Unit (EXPERIMENTAL)' CONFIG_IOP310_MU $CONFIG_ARCH_IOP310 $CONFIG_EXPERIMENTAL
bool 'Support Intel 80312 DMA (EXPERIMENTAL)' CONFIG_IOP310_DMA dep_bool 'Support Intel 80312 Performance Monitor (EXPERIMENTAL)' CONFIG_IOP310_PMON $CONFIG_ARCH_IOP310 $CONFIG_EXPERIMENTAL
bool 'Support Intel 80312 Messaging Unit (EXPERIMENTAL)' CONFIG_IOP310_MU endmenu
bool 'Support Intel 80312 Performance Monitor (EXPERIMENTAL)' CONFIG_IOP310_PMON
endmenu
fi
# Definitions to make life easier # Definitions to make life easier
if [ "$CONFIG_ARCH_ARCA5K" = "y" -o \ if [ "$CONFIG_ARCH_ARCA5K" = "y" -o \
......
This diff is collapsed.
...@@ -712,7 +712,6 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE ...@@ -712,7 +712,6 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE
mrs r9, cpsr @ Enable interrupts if they were mrs r9, cpsr @ Enable interrupts if they were
tst r3, #PSR_I_BIT tst r3, #PSR_I_BIT
biceq r9, r9, #PSR_I_BIT @ previously biceq r9, r9, #PSR_I_BIT @ previously
mov r0, r2 @ *** remove once everyones in sync
/* /*
* This routine must not corrupt r9 * This routine must not corrupt r9
*/ */
...@@ -855,7 +854,6 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go ...@@ -855,7 +854,6 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
stmdb r5, {sp, lr}^ stmdb r5, {sp, lr}^
alignment_trap r7, r7, __temp_abt alignment_trap r7, r7, __temp_abt
zero_fp zero_fp
mov r0, r2 @ remove once everyones in sync
#ifdef MULTI_ABORT #ifdef MULTI_ABORT
ldr r4, .LCprocfns @ pass r0, r3 to ldr r4, .LCprocfns @ pass r0, r3 to
mov lr, pc @ processor code mov lr, pc @ processor code
...@@ -913,10 +911,13 @@ __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go ...@@ -913,10 +911,13 @@ __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
stmdb r8, {sp, lr}^ @ Save user sp, lr stmdb r8, {sp, lr}^ @ Save user sp, lr
alignment_trap r4, r7, __temp_und alignment_trap r4, r7, __temp_und
zero_fp zero_fp
tst r6, #PSR_T_BIT @ Thumb mode?
bne fpundefinstr @ ignore FP
adrsvc al, r9, ret_from_exception @ r9 = normal FP return adrsvc al, r9, ret_from_exception @ r9 = normal FP return
adrsvc al, lr, fpundefinstr @ lr = undefined instr return adrsvc al, lr, fpundefinstr @ lr = undefined instr return
call_fpe: get_thread_info r10 @ get current thread call_fpe: set_cpsr_c r0, #MODE_SVC @ Enable interrupts
get_thread_info r10 @ get current thread
ldr r4, [r10, #TI_TASK] @ get current task ldr r4, [r10, #TI_TASK] @ get current task
mov r8, #1 mov r8, #1
strb r8, [r4, #TSK_USED_MATH] @ set current->used_math strb r8, [r4, #TSK_USED_MATH] @ set current->used_math
...@@ -924,8 +925,7 @@ call_fpe: get_thread_info r10 @ get current thread ...@@ -924,8 +925,7 @@ call_fpe: get_thread_info r10 @ get current thread
add r10, r10, #TI_FPSTATE @ r10 = workspace add r10, r10, #TI_FPSTATE @ r10 = workspace
ldr pc, [r4] @ Call FP module USR entry point ldr pc, [r4] @ Call FP module USR entry point
fpundefinstr: set_cpsr_c r0, #MODE_SVC @ Enable interrupts fpundefinstr: mov r0, sp
mov r0, sp
adrsvc al, lr, ret_from_exception adrsvc al, lr, ret_from_exception
b do_undefinstr b do_undefinstr
......
...@@ -202,8 +202,7 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs) ...@@ -202,8 +202,7 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
if (status & SA_SAMPLE_RANDOM) if (status & SA_SAMPLE_RANDOM)
add_interrupt_randomness(irq); add_interrupt_randomness(irq);
__cli(); spin_lock_irq(&irq_controller_lock);
spin_lock(&irq_controller_lock);
} }
/* /*
...@@ -634,6 +633,8 @@ unsigned long probe_irq_on(void) ...@@ -634,6 +633,8 @@ unsigned long probe_irq_on(void)
irq_desc[i].probing = 1; irq_desc[i].probing = 1;
irq_desc[i].triggered = 0; irq_desc[i].triggered = 0;
if (irq_desc[i].chip->type)
irq_desc[i].chip->type(i, IRQT_PROBE);
irq_desc[i].chip->unmask(i); irq_desc[i].chip->unmask(i);
irqs += 1; irqs += 1;
} }
......
...@@ -75,10 +75,10 @@ void (*pm_power_off)(void); ...@@ -75,10 +75,10 @@ void (*pm_power_off)(void);
*/ */
void default_idle(void) void default_idle(void)
{ {
__cli(); local_irq_disable();
if (!need_resched() && !hlt_counter) if (!need_resched() && !hlt_counter)
arch_idle(); arch_idle();
__sti(); local_irq_enable();
} }
/* /*
......
...@@ -40,12 +40,17 @@ ...@@ -40,12 +40,17 @@
* Get the address of the live pt_regs for the specified task. * Get the address of the live pt_regs for the specified task.
* These are saved onto the top kernel stack when the process * These are saved onto the top kernel stack when the process
* is not running. * is not running.
*
* Note: if a user thread is execve'd from kernel space, the
* kernel stack will not be empty on entry to the kernel, so
* ptracing these tasks will fail.
*/ */
static inline struct pt_regs * static inline struct pt_regs *
get_user_regs(struct task_struct *task) get_user_regs(struct task_struct *task)
{ {
return (struct pt_regs *) return (struct pt_regs *)
((unsigned long)task->thread_info + 8192 - sizeof(struct pt_regs)); ((unsigned long)task->thread_info + THREAD_SIZE -
8 - sizeof(struct pt_regs));
} }
/* /*
...@@ -54,7 +59,7 @@ get_user_regs(struct task_struct *task) ...@@ -54,7 +59,7 @@ get_user_regs(struct task_struct *task)
* this routine assumes that all the privileged stacks are in our * this routine assumes that all the privileged stacks are in our
* data space. * data space.
*/ */
static inline long get_stack_long(struct task_struct *task, int offset) static inline long get_user_reg(struct task_struct *task, int offset)
{ {
return get_user_regs(task)->uregs[offset]; return get_user_regs(task)->uregs[offset];
} }
...@@ -66,7 +71,7 @@ static inline long get_stack_long(struct task_struct *task, int offset) ...@@ -66,7 +71,7 @@ static inline long get_stack_long(struct task_struct *task, int offset)
* data space. * data space.
*/ */
static inline int static inline int
put_stack_long(struct task_struct *task, int offset, long data) put_user_reg(struct task_struct *task, int offset, long data)
{ {
struct pt_regs newregs, *regs = get_user_regs(task); struct pt_regs newregs, *regs = get_user_regs(task);
int ret = -EINVAL; int ret = -EINVAL;
...@@ -111,7 +116,7 @@ ptrace_getrn(struct task_struct *child, unsigned long insn) ...@@ -111,7 +116,7 @@ ptrace_getrn(struct task_struct *child, unsigned long insn)
unsigned int reg = (insn >> 16) & 15; unsigned int reg = (insn >> 16) & 15;
unsigned long val; unsigned long val;
val = get_stack_long(child, reg); val = get_user_reg(child, reg);
if (reg == 15) if (reg == 15)
val = pc_pointer(val + 8); val = pc_pointer(val + 8);
...@@ -133,10 +138,10 @@ ptrace_getaluop2(struct task_struct *child, unsigned long insn) ...@@ -133,10 +138,10 @@ ptrace_getaluop2(struct task_struct *child, unsigned long insn)
shift = (insn >> 8) & 15; shift = (insn >> 8) & 15;
type = 3; type = 3;
} else { } else {
val = get_stack_long (child, insn & 15); val = get_user_reg (child, insn & 15);
if (insn & (1 << 4)) if (insn & (1 << 4))
shift = (int)get_stack_long (child, (insn >> 8) & 15); shift = (int)get_user_reg (child, (insn >> 8) & 15);
else else
shift = (insn >> 7) & 31; shift = (insn >> 7) & 31;
...@@ -166,7 +171,7 @@ ptrace_getldrop2(struct task_struct *child, unsigned long insn) ...@@ -166,7 +171,7 @@ ptrace_getldrop2(struct task_struct *child, unsigned long insn)
int shift; int shift;
int type; int type;
val = get_stack_long(child, insn & 15); val = get_user_reg(child, insn & 15);
shift = (insn >> 7) & 31; shift = (insn >> 7) & 31;
type = (insn >> 5) & 3; type = (insn >> 5) & 3;
...@@ -215,7 +220,7 @@ get_branch_address(struct task_struct *child, unsigned long pc, unsigned long in ...@@ -215,7 +220,7 @@ get_branch_address(struct task_struct *child, unsigned long pc, unsigned long in
aluop1 = ptrace_getrn(child, insn); aluop1 = ptrace_getrn(child, insn);
aluop2 = ptrace_getaluop2(child, insn); aluop2 = ptrace_getaluop2(child, insn);
ccbit = get_stack_long(child, REG_PSR) & PSR_C_BIT ? 1 : 0; ccbit = get_user_reg(child, REG_PSR) & PSR_C_BIT ? 1 : 0;
switch (insn & OP_MASK) { switch (insn & OP_MASK) {
case OP_AND: alt = aluop1 & aluop2; break; case OP_AND: alt = aluop1 & aluop2; break;
...@@ -270,13 +275,7 @@ get_branch_address(struct task_struct *child, unsigned long pc, unsigned long in ...@@ -270,13 +275,7 @@ get_branch_address(struct task_struct *child, unsigned long pc, unsigned long in
unsigned int nr_regs; unsigned int nr_regs;
if (insn & (1 << 23)) { if (insn & (1 << 23)) {
nr_regs = insn & 65535; nr_regs = hweight16(insn & 65535) << 2;
nr_regs = (nr_regs & 0x5555) + ((nr_regs & 0xaaaa) >> 1);
nr_regs = (nr_regs & 0x3333) + ((nr_regs & 0xcccc) >> 2);
nr_regs = (nr_regs & 0x0707) + ((nr_regs & 0x7070) >> 4);
nr_regs = (nr_regs & 0x000f) + ((nr_regs & 0x0f00) >> 8);
nr_regs <<= 2;
if (!(insn & (1 << 24))) if (!(insn & (1 << 24)))
nr_regs -= 4; nr_regs -= 4;
...@@ -348,6 +347,11 @@ int ptrace_set_bpt(struct task_struct *child) ...@@ -348,6 +347,11 @@ int ptrace_set_bpt(struct task_struct *child)
regs = get_user_regs(child); regs = get_user_regs(child);
pc = instruction_pointer(regs); pc = instruction_pointer(regs);
if (thumb_mode(regs)) {
printk(KERN_WARNING "ptrace: can't handle thumb mode\n");
return -EINVAL;
}
res = read_tsk_long(child, pc, &insn); res = read_tsk_long(child, pc, &insn);
if (!res) { if (!res) {
struct debug_info *dbg = &child->thread.debug; struct debug_info *dbg = &child->thread.debug;
...@@ -411,6 +415,118 @@ void ptrace_disable(struct task_struct *child) ...@@ -411,6 +415,118 @@ void ptrace_disable(struct task_struct *child)
__ptrace_cancel_bpt(child); __ptrace_cancel_bpt(child);
} }
/*
* Handle hitting a breakpoint.
*/
void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
{
siginfo_t info;
/*
* The PC is always left pointing at the next instruction. Fix this.
*/
regs->ARM_pc -= 4;
if (tsk->thread.debug.nsaved == 0)
printk(KERN_ERR "ptrace: bogus breakpoint trap\n");
__ptrace_cancel_bpt(tsk);
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
info.si_addr = (void *)instruction_pointer(regs) -
(thumb_mode(regs) ? 2 : 4);
force_sig_info(SIGTRAP, &info, tsk);
}
/*
* Read the word at offset "off" into the "struct user". We
* actually access the pt_regs stored on the kernel stack.
*/
static int ptrace_read_user(struct task_struct *tsk, unsigned long off,
unsigned long *ret)
{
unsigned long tmp;
if (off & 3 || off >= sizeof(struct user))
return -EIO;
tmp = 0;
if (off < sizeof(struct pt_regs))
tmp = get_user_reg(tsk, off >> 2);
return put_user(tmp, ret);
}
/*
* Write the word at offset "off" into "struct user". We
* actually access the pt_regs stored on the kernel stack.
*/
static int ptrace_write_user(struct task_struct *tsk, unsigned long off,
unsigned long val)
{
if (off & 3 || off >= sizeof(struct user))
return -EIO;
if (off >= sizeof(struct pt_regs))
return 0;
return put_user_reg(tsk, off >> 2, val);
}
/*
* Get all user integer registers.
*/
static int ptrace_getregs(struct task_struct *tsk, void *uregs)
{
struct pt_regs *regs = get_user_regs(tsk);
return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
}
/*
* Set all user integer registers.
*/
static int ptrace_setregs(struct task_struct *tsk, void *uregs)
{
struct pt_regs newregs;
int ret;
ret = -EFAULT;
if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) {
struct pt_regs *regs = get_user_regs(tsk);
ret = -EINVAL;
if (valid_user_regs(&newregs)) {
*regs = newregs;
ret = 0;
}
}
return ret;
}
/*
* Get the child FPU state.
*/
static int ptrace_getfpregs(struct task_struct *tsk, void *ufp)
{
return copy_to_user(ufp, &tsk->thread_info->fpstate,
sizeof(struct user_fp)) ? -EFAULT : 0;
}
/*
* Set the child FPU state.
*/
static int ptrace_setfpregs(struct task_struct *tsk, void *ufp)
{
tsk->used_math = 1;
return copy_from_user(&tsk->thread_info->fpstate, ufp,
sizeof(struct user_fp)) ? -EFAULT : 0;
}
static int do_ptrace(int request, struct task_struct *child, long addr, long data) static int do_ptrace(int request, struct task_struct *child, long addr, long data)
{ {
unsigned long tmp; unsigned long tmp;
...@@ -427,18 +543,8 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat ...@@ -427,18 +543,8 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
ret = put_user(tmp, (unsigned long *) data); ret = put_user(tmp, (unsigned long *) data);
break; break;
/*
* read the word at location "addr" in the user registers.
*/
case PTRACE_PEEKUSR: case PTRACE_PEEKUSR:
ret = -EIO; ret = ptrace_read_user(child, addr, (unsigned long *)data);
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
break;
tmp = 0; /* Default return condition */
if (addr < sizeof(struct pt_regs))
tmp = get_stack_long(child, (int)addr >> 2);
ret = put_user(tmp, (unsigned long *)data);
break; break;
/* /*
...@@ -449,16 +555,8 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat ...@@ -449,16 +555,8 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
ret = write_tsk_long(child, addr, data); ret = write_tsk_long(child, addr, data);
break; break;
/*
* write the word at location addr in the user registers.
*/
case PTRACE_POKEUSR: case PTRACE_POKEUSR:
ret = -EIO; ret = ptrace_write_user(child, addr, data);
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
break;
if (addr < sizeof(struct pt_regs))
ret = put_stack_long(child, (int)addr >> 2, data);
break; break;
/* /*
...@@ -486,14 +584,12 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat ...@@ -486,14 +584,12 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
* exit. * exit.
*/ */
case PTRACE_KILL: case PTRACE_KILL:
/* already dead */
ret = 0;
if (child->state == TASK_ZOMBIE)
break;
child->exit_code = SIGKILL;
/* make sure single-step breakpoint is gone. */ /* make sure single-step breakpoint is gone. */
__ptrace_cancel_bpt(child); __ptrace_cancel_bpt(child);
if (child->state != TASK_ZOMBIE) {
child->exit_code = SIGKILL;
wake_up_process(child); wake_up_process(child);
}
ret = 0; ret = 0;
break; break;
...@@ -512,71 +608,32 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat ...@@ -512,71 +608,32 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
ret = 0; ret = 0;
break; break;
/*
* detach a process that was attached.
*/
case PTRACE_DETACH: case PTRACE_DETACH:
ret = ptrace_detach(child, data); ret = ptrace_detach(child, data);
break; break;
/* case PTRACE_GETREGS:
* Get all gp regs from the child. ret = ptrace_getregs(child, (void *)data);
*/
case PTRACE_GETREGS: {
struct pt_regs *regs = get_user_regs(child);
ret = 0;
if (copy_to_user((void *)data, regs,
sizeof(struct pt_regs)))
ret = -EFAULT;
break; break;
}
/*
* Set all gp regs in the child.
*/
case PTRACE_SETREGS: {
struct pt_regs newregs;
ret = -EFAULT; case PTRACE_SETREGS:
if (copy_from_user(&newregs, (void *)data, ret = ptrace_setregs(child, (void *)data);
sizeof(struct pt_regs)) == 0) {
struct pt_regs *regs = get_user_regs(child);
ret = -EINVAL;
if (valid_user_regs(&newregs)) {
*regs = newregs;
ret = 0;
}
}
break; break;
}
/*
* Get the child FPU state.
*/
case PTRACE_GETFPREGS: case PTRACE_GETFPREGS:
ret = -EIO; ret = ptrace_getfpregs(child, (void *)data);
if (!access_ok(VERIFY_WRITE, (void *)data, sizeof(struct user_fp)))
break;
/* we should check child->used_math here */
ret = __copy_to_user((void *)data, &child->thread_info->fpstate,
sizeof(struct user_fp)) ? -EFAULT : 0;
break; break;
/*
* Set the child FPU state.
*/
case PTRACE_SETFPREGS: case PTRACE_SETFPREGS:
ret = -EIO; ret = ptrace_setfpregs(child, (void *)data);
if (!access_ok(VERIFY_READ, (void *)data, sizeof(struct user_fp)))
break; break;
child->used_math = 1; case PTRACE_SETOPTIONS:
ret = __copy_from_user(&child->thread_info->fpstate, (void *)data, if (data & PTRACE_O_TRACESYSGOOD)
sizeof(struct user_fp)) ? -EFAULT : 0; child->ptrace |= PT_TRACESYSGOOD;
else
child->ptrace &= ~PT_TRACESYSGOOD;
ret = 0;
break; break;
default: default:
......
/* /*
* linux/arch/arm/kernel/ptrace.h * linux/arch/arm/kernel/ptrace.h
* *
* Copyright (C) 2000 Russell King * Copyright (C) 2000-2002 Russell King
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
*/ */
extern void __ptrace_cancel_bpt(struct task_struct *); extern void __ptrace_cancel_bpt(struct task_struct *);
extern int ptrace_set_bpt(struct task_struct *); extern int ptrace_set_bpt(struct task_struct *);
extern void ptrace_break(struct task_struct *, struct pt_regs *);
/* /*
* Clear a breakpoint, if one exists. * Clear a breakpoint, if one exists.
......
/* /*
* linux/arch/arm/kernel/signal.c * linux/arch/arm/kernel/signal.c
* *
* Copyright (C) 1995-2001 Russell King * Copyright (C) 1995-2002 Russell King
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -17,15 +17,15 @@ ...@@ -17,15 +17,15 @@
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/binfmts.h>
#include <linux/elf.h> #include <linux/elf.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
#include <asm/ucontext.h> #include <asm/ucontext.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/unistd.h>
#include "ptrace.h" #include "ptrace.h"
...@@ -49,7 +49,7 @@ static const unsigned long retcodes[4] = { ...@@ -49,7 +49,7 @@ static const unsigned long retcodes[4] = {
SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
}; };
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall); static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
/* /*
* atomically swap in the new signal mask, and wait for a signal. * atomically swap in the new signal mask, and wait for a signal.
...@@ -325,7 +325,7 @@ setup_return(struct pt_regs *regs, struct k_sigaction *ka, ...@@ -325,7 +325,7 @@ setup_return(struct pt_regs *regs, struct k_sigaction *ka,
unsigned long retcode; unsigned long retcode;
int thumb = 0; int thumb = 0;
#ifdef CONFIG_CPU_32 #ifdef CONFIG_CPU_32
unsigned long cpsr = regs->ARM_cpsr; unsigned long cpsr = regs->ARM_cpsr & ~PSR_f;
/* /*
* Maybe we need to deliver a 32-bit signal to a 26-bit task. * Maybe we need to deliver a 32-bit signal to a 26-bit task.
...@@ -501,7 +501,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, ...@@ -501,7 +501,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
* the kernel can handle, and then we build all the user-level signal handling * the kernel can handle, and then we build all the user-level signal handling
* stack-frames in one go after that. * stack-frames in one go after that.
*/ */
int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
{ {
struct k_sigaction *ka; struct k_sigaction *ka;
siginfo_t info; siginfo_t info;
...@@ -516,9 +516,6 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) ...@@ -516,9 +516,6 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
if (!user_mode(regs)) if (!user_mode(regs))
return 0; return 0;
if (!oldset)
oldset = &current->blocked;
single_stepping = ptrace_cancel_bpt(current); single_stepping = ptrace_cancel_bpt(current);
for (;;) { for (;;) {
...@@ -598,6 +595,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) ...@@ -598,6 +595,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
notify_parent(current, SIGCHLD); notify_parent(current, SIGCHLD);
schedule(); schedule();
single_stepping |= ptrace_cancel_bpt(current);
continue; continue;
} }
...@@ -655,5 +653,5 @@ asmlinkage void ...@@ -655,5 +653,5 @@ asmlinkage void
do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
{ {
if (thread_flags & _TIF_SIGPENDING) if (thread_flags & _TIF_SIGPENDING)
do_signal(NULL, regs, syscall); do_signal(&current->blocked, regs, syscall);
} }
/* /*
* linux/arch/arm/kernel/traps.c * linux/arch/arm/kernel/traps.c
* *
* Copyright (C) 1995, 1996 Russell King * Copyright (C) 1995-2002 Russell King
* Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -66,8 +66,17 @@ static int verify_stack(unsigned long sp) ...@@ -66,8 +66,17 @@ static int verify_stack(unsigned long sp)
static void dump_mem(const char *str, unsigned long bottom, unsigned long top) static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
{ {
unsigned long p = bottom & ~31; unsigned long p = bottom & ~31;
mm_segment_t fs;
int i; int i;
/*
* We need to switch to kernel mode so that we can use __get_user
* to safely read from kernel space. Note that we now dump the
* code first, just in case the backtrace kills us.
*/
fs = get_fs();
set_fs(KERNEL_DS);
printk("%s", str); printk("%s", str);
printk("(0x%08lx to 0x%08lx)\n", bottom, top); printk("(0x%08lx to 0x%08lx)\n", bottom, top);
...@@ -86,6 +95,8 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top) ...@@ -86,6 +95,8 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
} }
printk ("\n"); printk ("\n");
} }
set_fs(fs);
} }
static void dump_instr(struct pt_regs *regs) static void dump_instr(struct pt_regs *regs)
...@@ -93,8 +104,17 @@ static void dump_instr(struct pt_regs *regs) ...@@ -93,8 +104,17 @@ static void dump_instr(struct pt_regs *regs)
unsigned long addr = instruction_pointer(regs); unsigned long addr = instruction_pointer(regs);
const int thumb = thumb_mode(regs); const int thumb = thumb_mode(regs);
const int width = thumb ? 4 : 8; const int width = thumb ? 4 : 8;
mm_segment_t fs;
int i; int i;
/*
* We need to switch to kernel mode so that we can use __get_user
* to safely read from kernel space. Note that we now dump the
* code first, just in case the backtrace kills us.
*/
fs = get_fs();
set_fs(KERNEL_DS);
printk("Code: "); printk("Code: ");
for (i = -4; i < 1; i++) { for (i = -4; i < 1; i++) {
unsigned int val, bad; unsigned int val, bad;
...@@ -112,6 +132,8 @@ static void dump_instr(struct pt_regs *regs) ...@@ -112,6 +132,8 @@ static void dump_instr(struct pt_regs *regs)
} }
} }
printk("\n"); printk("\n");
set_fs(fs);
} }
static void dump_stack(struct task_struct *tsk, unsigned long sp) static void dump_stack(struct task_struct *tsk, unsigned long sp)
...@@ -171,22 +193,9 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) ...@@ -171,22 +193,9 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
current->comm, current->pid, tsk->thread_info + 1); current->comm, current->pid, tsk->thread_info + 1);
if (!user_mode(regs) || in_interrupt()) { if (!user_mode(regs) || in_interrupt()) {
mm_segment_t fs;
/*
* We need to switch to kernel mode so that we can
* use __get_user to safely read from kernel space.
* Note that we now dump the code first, just in case
* the backtrace kills us.
*/
fs = get_fs();
set_fs(KERNEL_DS);
dump_stack(tsk, (unsigned long)(regs + 1)); dump_stack(tsk, (unsigned long)(regs + 1));
dump_backtrace(regs, tsk); dump_backtrace(regs, tsk);
dump_instr(regs); dump_instr(regs);
set_fs(fs);
} }
spin_unlock_irq(&die_lock); spin_unlock_irq(&die_lock);
...@@ -233,7 +242,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs) ...@@ -233,7 +242,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs)
} }
#ifdef CONFIG_CPU_26 #ifdef CONFIG_CPU_26
asmlinkage void do_excpt(int address, struct pt_regs *regs, int mode) asmlinkage void do_excpt(unsigned long address, struct pt_regs *regs, int mode)
{ {
siginfo_t info; siginfo_t info;
...@@ -274,21 +283,12 @@ asmlinkage void do_unexp_fiq (struct pt_regs *regs) ...@@ -274,21 +283,12 @@ asmlinkage void do_unexp_fiq (struct pt_regs *regs)
asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode) asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
{ {
unsigned int vectors = vectors_base(); unsigned int vectors = vectors_base();
mm_segment_t fs;
console_verbose(); console_verbose();
printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n", printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n",
handler[reason], processor_modes[proc_mode]); handler[reason], processor_modes[proc_mode]);
/*
* We need to switch to kernel mode so that we can use __get_user
* to safely read from kernel space. Note that we now dump the
* code first, just in case the backtrace kills us.
*/
fs = get_fs();
set_fs(KERNEL_DS);
/* /*
* Dump out the vectors and stub routines. Maybe a better solution * Dump out the vectors and stub routines. Maybe a better solution
* would be to dump them out only if we detect that they are corrupted. * would be to dump them out only if we detect that they are corrupted.
...@@ -296,10 +296,8 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode) ...@@ -296,10 +296,8 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
dump_mem(KERN_CRIT "Vectors: ", vectors, vectors + 0x40); dump_mem(KERN_CRIT "Vectors: ", vectors, vectors + 0x40);
dump_mem(KERN_CRIT "Stubs: ", vectors + 0x200, vectors + 0x4b8); dump_mem(KERN_CRIT "Stubs: ", vectors + 0x200, vectors + 0x4b8);
set_fs(fs);
die("Oops", regs, 0); die("Oops", regs, 0);
cli(); local_irq_disable();
panic("bad mode"); panic("bad mode");
} }
...@@ -308,13 +306,7 @@ static int bad_syscall(int n, struct pt_regs *regs) ...@@ -308,13 +306,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
struct thread_info *thread = current_thread_info(); struct thread_info *thread = current_thread_info();
siginfo_t info; siginfo_t info;
/* You might think just testing `handler' would be enough, but PER_LINUX
* points it to no_lcall7 to catch undercover SVr4 binaries. Gutted.
*/
if (current->personality != PER_LINUX && thread->exec_domain->handler) { if (current->personality != PER_LINUX && thread->exec_domain->handler) {
/* Hand it off to iBCS. The extra parameter and consequent type
* forcing is necessary because of the weird ARM calling convention.
*/
thread->exec_domain->handler(n, regs); thread->exec_domain->handler(n, regs);
return regs->ARM_r0; return regs->ARM_r0;
} }
...@@ -380,20 +372,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) ...@@ -380,20 +372,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
return 0; return 0;
case NR(breakpoint): /* SWI BREAK_POINT */ case NR(breakpoint): /* SWI BREAK_POINT */
/* ptrace_break(current, regs);
* The PC is always left pointing at the next
* instruction. Fix this.
*/
regs->ARM_pc -= 4;
__ptrace_cancel_bpt(current);
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
info.si_addr = (void *)instruction_pointer(regs) -
(thumb_mode(regs) ? 2 : 4);
force_sig_info(SIGTRAP, &info, current);
return regs->ARM_r0; return regs->ARM_r0;
#ifdef CONFIG_CPU_32 #ifdef CONFIG_CPU_32
...@@ -418,13 +397,13 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) ...@@ -418,13 +397,13 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
case NR(usr26): case NR(usr26):
if (!(elf_hwcap & HWCAP_26BIT)) if (!(elf_hwcap & HWCAP_26BIT))
break; break;
regs->ARM_cpsr &= ~0x10; regs->ARM_cpsr &= ~MODE32_BIT;
return regs->ARM_r0; return regs->ARM_r0;
case NR(usr32): case NR(usr32):
if (!(elf_hwcap & HWCAP_26BIT)) if (!(elf_hwcap & HWCAP_26BIT))
break; break;
regs->ARM_cpsr |= 0x10; regs->ARM_cpsr |= MODE32_BIT;
return regs->ARM_r0; return regs->ARM_r0;
#else #else
case NR(cacheflush): case NR(cacheflush):
......
...@@ -52,25 +52,32 @@ ENTRY(c_backtrace) ...@@ -52,25 +52,32 @@ ENTRY(c_backtrace)
3: tst frame, mask @ Check for address exceptions... 3: tst frame, mask @ Check for address exceptions...
bne 1b bne 1b
1001: ldmda frame, {r0, r1, r2, r3} @ fp, sp, lr, pc 1001: ldr next, [frame, #-12] @ get fp
mov next, r0 1002: ldr r2, [frame, #-4] @ get lr
1003: ldr r3, [frame, #0] @ get pc
sub save, r3, offset @ Correct PC for prefetching sub save, r3, offset @ Correct PC for prefetching
bic save, save, mask bic save, save, mask
1004: ldr r1, [save, #0] @ get instruction at function
mov r1, r1, lsr #10
ldr r3, .Ldsi+4
teq r1, r3
subeq save, save, #4
adr r0, .Lfe adr r0, .Lfe
mov r1, save mov r1, save
bic r2, r2, mask bic r2, r2, mask
bl printk @ print pc and link register bl printk @ print pc and link register
sub r0, frame, #16 ldr r0, [frame, #-8] @ get sp
1002: ldr r1, [save, #4] @ get instruction at function+4 sub r0, r0, #4
1005: ldr r1, [save, #4] @ get instruction at function+4
mov r3, r1, lsr #10 mov r3, r1, lsr #10
ldr r2, .Ldsi+4 ldr r2, .Ldsi+4
teq r3, r2 @ Check for stmia sp!, {args} teq r3, r2 @ Check for stmia sp!, {args}
addeq save, save, #4 @ next instruction addeq save, save, #4 @ next instruction
bleq .Ldumpstm bleq .Ldumpstm
1003: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction sub r0, frame, #16
1006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
mov r3, r1, lsr #10 mov r3, r1, lsr #10
ldr r2, .Ldsi ldr r2, .Ldsi
teq r3, r2 teq r3, r2
...@@ -87,7 +94,7 @@ ENTRY(c_backtrace) ...@@ -87,7 +94,7 @@ ENTRY(c_backtrace)
*/ */
.section .fixup,"ax" .section .fixup,"ax"
.align 0 .align 0
1004: ldr r0, =.Lbad 1007: ldr r0, =.Lbad
mov r1, frame mov r1, frame
bl printk bl printk
LOADREGS(fd, sp!, {r4 - r8, pc}) LOADREGS(fd, sp!, {r4 - r8, pc})
...@@ -96,9 +103,12 @@ ENTRY(c_backtrace) ...@@ -96,9 +103,12 @@ ENTRY(c_backtrace)
.section __ex_table,"a" .section __ex_table,"a"
.align 3 .align 3
.long 1001b, 1004b .long 1001b, 1007b
.long 1002b, 1004b .long 1002b, 1007b
.long 1003b, 1004b .long 1003b, 1007b
.long 1004b, 1007b
.long 1005b, 1007b
.long 1006b, 1007b
.previous .previous
#define instr r4 #define instr r4
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
*/ */
struct order { struct order {
struct page *queue; struct list_head queue;
unsigned int mask; /* (1 << shift) - 1 */ unsigned int mask; /* (1 << shift) - 1 */
unsigned int shift; /* (1 << shift) size of page */ unsigned int shift; /* (1 << shift) size of page */
unsigned int block_mask; /* nr_blocks - 1 */ unsigned int block_mask; /* nr_blocks - 1 */
...@@ -60,10 +60,10 @@ struct order { ...@@ -60,10 +60,10 @@ struct order {
static struct order orders[] = { static struct order orders[] = {
#if PAGE_SIZE == 4096 #if PAGE_SIZE == 4096
{ NULL, 2047, 11, 1, 0x00000003 } { LIST_HEAD_INIT(orders[0].queue), 2047, 11, 1, 0x00000003 }
#elif PAGE_SIZE == 32768 #elif PAGE_SIZE == 32768
{ NULL, 2047, 11, 15, 0x0000ffff }, { LIST_HEAD_INIT(orders[0].queue), 2047, 11, 15, 0x0000ffff },
{ NULL, 8191, 13, 3, 0x0000000f } { LIST_HEAD_INIT(orders[1].queue), 8191, 13, 3, 0x0000000f }
#else #else
#error unsupported page size #error unsupported page size
#endif #endif
...@@ -75,40 +75,19 @@ static struct order orders[] = { ...@@ -75,40 +75,19 @@ static struct order orders[] = {
static spinlock_t small_page_lock = SPIN_LOCK_UNLOCKED; static spinlock_t small_page_lock = SPIN_LOCK_UNLOCKED;
static void add_page_to_queue(struct page *page, struct page **p)
{
#ifdef PEDANTIC
if (page->pprev_hash)
PAGE_BUG(page);
#endif
page->next_hash = *p;
if (*p)
(*p)->pprev_hash = &page->next_hash;
*p = page;
page->pprev_hash = p;
}
static void remove_page_from_queue(struct page *page)
{
if (page->pprev_hash) {
if (page->next_hash)
page->next_hash->pprev_hash = page->pprev_hash;
*page->pprev_hash = page->next_hash;
page->pprev_hash = NULL;
}
}
static unsigned long __get_small_page(int priority, struct order *order) static unsigned long __get_small_page(int priority, struct order *order)
{ {
unsigned long flags; unsigned long flags;
struct page *page; struct page *page;
int offset; int offset;
if (!order->queue) do {
spin_lock_irqsave(&small_page_lock, flags);
if (list_empty(&order->queue))
goto need_new_page; goto need_new_page;
spin_lock_irqsave(&small_page_lock, flags); page = list_entry(order->queue.next, struct page, list);
page = order->queue;
again: again:
#ifdef PEDANTIC #ifdef PEDANTIC
if (USED_MAP(page) & ~order->all_used) if (USED_MAP(page) & ~order->all_used)
...@@ -117,28 +96,28 @@ static unsigned long __get_small_page(int priority, struct order *order) ...@@ -117,28 +96,28 @@ static unsigned long __get_small_page(int priority, struct order *order)
offset = ffz(USED_MAP(page)); offset = ffz(USED_MAP(page));
SET_USED(page, offset); SET_USED(page, offset);
if (USED_MAP(page) == order->all_used) if (USED_MAP(page) == order->all_used)
remove_page_from_queue(page); list_del_init(&page->list);
spin_unlock_irqrestore(&small_page_lock, flags); spin_unlock_irqrestore(&small_page_lock, flags);
return (unsigned long) page_address(page) + (offset << order->shift); return (unsigned long) page_address(page) + (offset << order->shift);
need_new_page: need_new_page:
spin_unlock_irqrestore(&small_page_lock, flags);
page = alloc_page(priority); page = alloc_page(priority);
spin_lock_irqsave(&small_page_lock, flags); spin_lock_irqsave(&small_page_lock, flags);
if (!order->queue) {
if (list_empty(&order->queue)) {
if (!page) if (!page)
goto no_page; goto no_page;
SetPageReserved(page); SetPageReserved(page);
USED_MAP(page) = 0; USED_MAP(page) = 0;
cli(); list_add(&page->list, &order->queue);
add_page_to_queue(page, &order->queue);
} else {
__free_page(page);
cli();
page = order->queue;
}
goto again; goto again;
}
spin_unlock_irqrestore(&small_page_lock, flags);
__free_page(page);
} while (1);
no_page: no_page:
spin_unlock_irqrestore(&small_page_lock, flags); spin_unlock_irqrestore(&small_page_lock, flags);
...@@ -173,7 +152,7 @@ static void __free_small_page(unsigned long spage, struct order *order) ...@@ -173,7 +152,7 @@ static void __free_small_page(unsigned long spage, struct order *order)
spin_lock_irqsave(&small_page_lock, flags); spin_lock_irqsave(&small_page_lock, flags);
if (USED_MAP(page) == order->all_used) if (USED_MAP(page) == order->all_used)
add_page_to_queue(page, &order->queue); list_add(&page->list, &order->queue);
if (!TEST_AND_CLEAR_USED(page, spage)) if (!TEST_AND_CLEAR_USED(page, spage))
goto already_free; goto already_free;
...@@ -189,7 +168,7 @@ static void __free_small_page(unsigned long spage, struct order *order) ...@@ -189,7 +168,7 @@ static void __free_small_page(unsigned long spage, struct order *order)
/* /*
* unlink the page from the small page queue and free it * unlink the page from the small page queue and free it
*/ */
remove_page_from_queue(page); list_del_init(&page->list);
spin_unlock_irqrestore(&small_page_lock, flags); spin_unlock_irqrestore(&small_page_lock, flags);
ClearPageReserved(page); ClearPageReserved(page);
__free_page(page); __free_page(page);
......
...@@ -53,4 +53,4 @@ static int __init personal_pci_init(void) ...@@ -53,4 +53,4 @@ static int __init personal_pci_init(void)
return 0; return 0;
} }
subsys_initcall(&personal_pci_init); subsys_initcall(personal_pci_init);
...@@ -56,6 +56,7 @@ static int __init integrator_init(void) ...@@ -56,6 +56,7 @@ static int __init integrator_init(void)
register_kmi(&integrator_keyboard); register_kmi(&integrator_keyboard);
register_kmi(&integrator_mouse); register_kmi(&integrator_mouse);
#endif #endif
return 0;
} }
__initcall(integrator_init); __initcall(integrator_init);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (C) 2001 Deep Blue Solutions Ltd. * Copyright (C) 2001 Deep Blue Solutions Ltd.
* *
* $Id: cpu.c,v 1.4 2002/05/29 11:41:55 rmk Exp $ * $Id: cpu.c,v 1.5 2002/07/06 16:53:17 rmk Exp $
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -121,8 +121,16 @@ static int __init cpu_init(void) ...@@ -121,8 +121,16 @@ static int __init cpu_init(void)
cpu_freq_khz = vco_to_freq(vco, 1); cpu_freq_khz = vco_to_freq(vco, 1);
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
cpufreq_init(cpu_freq_khz, 1000, 0); {
cpufreq_setfunctions(integrator_validatespeed, integrator_setspeed); struct cpufreq_driver cpufreq_driver;
cpufreq_driver.freq.min = 12000;
cpufreq_driver.freq.max = 160000;
cpufreq_driver.freq.cur = cpu_freq_khz;
cpufreq_driver.validate = &integrator_validatespeed;
cpufreq_driver.setspeed = &integrator_setspeed;
cpufreq_register(cpufreq_driver);
}
#endif #endif
cm_stat = __raw_readl(CM_STAT); cm_stat = __raw_readl(CM_STAT);
......
...@@ -27,8 +27,9 @@ ...@@ -27,8 +27,9 @@
*/ */
#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ #define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \
({ int _ctl_ = -1; \ ({ int _ctl_ = -1; \
if (idsel >= minid && idsel <= maxid && pin >= 1 && pin <= 4) \ unsigned int _idsel = idsel - minid; \
_ctl_ = pci_irq_table[idsel - minid][pin-1]; \ if (_idsel <= maxid) \
_ctl_ = pci_irq_table[_idsel][pin-1]; \
_ctl_; }) _ctl_; })
#define INTA IRQ_IQ80310_INTA #define INTA IRQ_IQ80310_INTA
...@@ -64,6 +65,8 @@ iq80310_pri_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) ...@@ -64,6 +65,8 @@ iq80310_pri_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
{ {
irq_table *pci_irq_table; irq_table *pci_irq_table;
BUG_ON(pin < 1 || pin > 4);
if (!system_rev) { if (!system_rev) {
pci_irq_table = pci_pri_d_irq_table; pci_irq_table = pci_pri_d_irq_table;
} else { } else {
...@@ -99,6 +102,8 @@ iq80310_sec_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) ...@@ -99,6 +102,8 @@ iq80310_sec_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
{ {
irq_table *pci_irq_table; irq_table *pci_irq_table;
BUG_ON(pin < 1 || pin > 4);
if (!system_rev) { if (!system_rev) {
pci_irq_table = pci_sec_d_irq_table; pci_irq_table = pci_sec_d_irq_table;
} else { } else {
......
...@@ -59,7 +59,7 @@ static int __init adsbitsy_init(void) ...@@ -59,7 +59,7 @@ static int __init adsbitsy_init(void)
/* /*
* Enable PWM control for LCD * Enable PWM control for LCD
*/ */
SKPCR |= SKPCR_PWMCLKEN; sa1111_enable_device(SKPCR_PWMCLKEN);
SKPWM0 = 0x7F; // VEE SKPWM0 = 0x7F; // VEE
SKPEN0 = 1; SKPEN0 = 1;
SKPWM1 = 0x01; // Backlight SKPWM1 = 0x01; // Backlight
......
...@@ -88,9 +88,21 @@ static int __init assabet_init(void) ...@@ -88,9 +88,21 @@ static int __init assabet_init(void)
return -EINVAL; return -EINVAL;
/* /*
* Set the IRQ edges * Ensure that these pins are set as outputs and are driving
* logic 0. This ensures that we won't inadvertently toggle
* the WS latch in the CPLD, and we don't float causing
* excessive power drain. --rmk
*/ */
set_irq_type(IRQ_GPIO23, IRQT_RISING); /* UCB1300 */ GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
/*
* Set up registers for sleep mode.
*/
PWER = PWER_GPIO0;
PGSR = 0;
PCFR = 0;
PSDR = 0;
sa1100fb_lcd_power = assabet_lcd_power; sa1100fb_lcd_power = assabet_lcd_power;
sa1100fb_backlight_power = assabet_backlight_power; sa1100fb_backlight_power = assabet_backlight_power;
...@@ -254,13 +266,19 @@ static struct map_desc assabet_io_desc[] __initdata = { ...@@ -254,13 +266,19 @@ static struct map_desc assabet_io_desc[] __initdata = {
static void __init assabet_map_io(void) static void __init assabet_map_io(void)
{ {
extern void neponset_map_io(void);
sa1100_map_io(); sa1100_map_io();
iotable_init(assabet_io_desc, ARRAY_SIZE(assabet_io_desc)); iotable_init(assabet_io_desc, ARRAY_SIZE(assabet_io_desc));
/*
* Set SUS bit in SDCR0 so serial port 1 functions.
* Its called GPCLKR0 in my SA1110 manual.
*/
Ser1SDCR0 |= SDCR0_SUS;
if (machine_has_neponset()) { if (machine_has_neponset()) {
#ifdef CONFIG_ASSABET_NEPONSET #ifdef CONFIG_ASSABET_NEPONSET
extern void neponset_map_io(void);
/* /*
* We map Neponset registers even if it isn't present since * We map Neponset registers even if it isn't present since
* many drivers will try to probe their stuff (and fail). * many drivers will try to probe their stuff (and fail).
...@@ -279,33 +297,11 @@ static void __init assabet_map_io(void) ...@@ -279,33 +297,11 @@ static void __init assabet_map_io(void)
*/ */
sa1100_register_uart(0, 3); sa1100_register_uart(0, 3);
sa1100_register_uart(2, 1); sa1100_register_uart(2, 1);
/*
* Set SUS bit in SDCR0 so serial port 1 functions.
* Its called GPCLKR0 in my SA1110 manual.
*/
Ser1SDCR0 |= SDCR0_SUS;
} else { } else {
sa1100_register_uart_fns(&assabet_port_fns); sa1100_register_uart_fns(&assabet_port_fns);
sa1100_register_uart(0, 1); /* com port */ sa1100_register_uart(0, 1); /* com port */
sa1100_register_uart(2, 3); /* radio module */ sa1100_register_uart(2, 3); /* radio module */
} }
/*
* Ensure that these pins are set as outputs and are driving
* logic 0. This ensures that we won't inadvertently toggle
* the WS latch in the CPLD, and we don't float causing
* excessive power drain. --rmk
*/
GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
/*
* Set up registers for sleep mode.
*/
PWER = PWER_GPIO0;
PGSR = 0;
PCFR = 0;
PSDR = 0;
} }
......
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz); extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
extern unsigned int sa11x0_validatespeed(unsigned int khz); extern unsigned int sa11x0_validatespeed(unsigned int khz);
extern unsigned int sa11x0_getspeed(void);
typedef struct { typedef struct {
int speed; int speed;
...@@ -187,7 +187,7 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed) ...@@ -187,7 +187,7 @@ static void sa1100_update_dram_timings(int current_speed, int new_speed)
static int sa1100_dram_notifier(struct notifier_block *nb, static int sa1100_dram_notifier(struct notifier_block *nb,
unsigned long val, void *data) unsigned long val, void *data)
{ {
struct cpufreq_info *ci = data; struct cpufreq_freqs *ci = data;
switch(val) { switch(val) {
case CPUFREQ_MINMAX: case CPUFREQ_MINMAX:
...@@ -195,13 +195,13 @@ static int sa1100_dram_notifier(struct notifier_block *nb, ...@@ -195,13 +195,13 @@ static int sa1100_dram_notifier(struct notifier_block *nb,
break; break;
case CPUFREQ_PRECHANGE: case CPUFREQ_PRECHANGE:
if(ci->new_freq > ci->old_freq) if(ci->new > ci->cur)
sa1100_update_dram_timings(ci->old_freq, ci->new_freq); sa1100_update_dram_timings(ci->cur, ci->new);
break; break;
case CPUFREQ_POSTCHANGE: case CPUFREQ_POSTCHANGE:
if(ci->new_freq < ci->old_freq) if(ci->new < ci->cur)
sa1100_update_dram_timings(ci->old_freq, ci->new_freq); sa1100_update_dram_timings(ci->cur, ci->new);
break; break;
default: default:
...@@ -230,9 +230,19 @@ static int __init sa1100_dram_init(void) ...@@ -230,9 +230,19 @@ static int __init sa1100_dram_init(void)
int ret = -ENODEV; int ret = -ENODEV;
if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) { if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) {
cpufreq_driver_t cpufreq_driver;
ret = cpufreq_register_notifier(&sa1100_dram_block); ret = cpufreq_register_notifier(&sa1100_dram_block);
if (ret)
return ret;
cpufreq_driver.freq.min = 59000;
cpufreq_driver.freq.max = 287000;
cpufreq_driver.freq.cur = sa11x0_getspeed();
cpufreq_driver.validate = &sa11x0_validatespeed;
cpufreq_driver.setspeed = &sa1100_setspeed;
cpufreq_setfunctions(sa11x0_validatespeed, sa1100_setspeed); ret = cpufreq_register(cpufreq_driver);<
} }
return ret; return ret;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (C) 2001 Russell King * Copyright (C) 2001 Russell King
* *
* $Id: cpu-sa1110.c,v 1.8 2002/01/09 17:13:27 rmk Exp $ * $Id: cpu-sa1110.c,v 1.9 2002/07/06 16:53:18 rmk Exp $
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz); extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
extern unsigned int sa11x0_validatespeed(unsigned int khz); extern unsigned int sa11x0_validatespeed(unsigned int khz);
extern unsigned int sa11x0_getspeed(void);
struct sdram_params { struct sdram_params {
u_char rows; /* bits */ u_char rows; /* bits */
...@@ -88,6 +89,16 @@ static struct sdram_params samsung_km416s4030ct __initdata = { ...@@ -88,6 +89,16 @@ static struct sdram_params samsung_km416s4030ct __initdata = {
cas_latency: 3, cas_latency: 3,
}; };
static struct sdram_params wbond_w982516ah75l_cl3_params __initdata = {
rows: 16,
tck: 8,
trcd: 20,
trp: 20,
twr: 8,
refresh: 64000,
cas_latency: 3,
};
static struct sdram_params sdram_params; static struct sdram_params sdram_params;
/* /*
...@@ -287,6 +298,8 @@ static int __init sa1110_clk_init(void) ...@@ -287,6 +298,8 @@ static int __init sa1110_clk_init(void)
sdram = &samsung_km416s4030ct; sdram = &samsung_km416s4030ct;
if (sdram) { if (sdram) {
struct cpufreq_driver cpufreq_driver;
printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d" printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d"
" twr: %d refresh: %d cas_latency: %d\n", " twr: %d refresh: %d cas_latency: %d\n",
sdram->tck, sdram->trcd, sdram->trp, sdram->tck, sdram->trcd, sdram->trp,
...@@ -294,8 +307,15 @@ static int __init sa1110_clk_init(void) ...@@ -294,8 +307,15 @@ static int __init sa1110_clk_init(void)
memcpy(&sdram_params, sdram, sizeof(sdram_params)); memcpy(&sdram_params, sdram, sizeof(sdram_params));
sa1110_setspeed(cpufreq_get(0)); sa1110_setspeed(sa11x0_getspeed());
cpufreq_setfunctions(sa11x0_validatespeed, sa1110_setspeed);
cpufreq_driver.freq.min = 59000;
cpufreq_driver.freq.max = 287000;
cpufreq_driver.freq.cur = sa11x0_getspeed();
cpufreq_driver.validate = &sa11x0_validatespeed;
cpufreq_driver.setspeed = &sa1110_setspeed;
return cpufreq_register(cpufreq_driver);
} }
return 0; return 0;
......
...@@ -76,13 +76,10 @@ unsigned int sa11x0_validatespeed(unsigned int khz) ...@@ -76,13 +76,10 @@ unsigned int sa11x0_validatespeed(unsigned int khz)
return cclk_frequency_100khz[sa11x0_freq_to_ppcr(khz)] * 100; return cclk_frequency_100khz[sa11x0_freq_to_ppcr(khz)] * 100;
} }
static int __init sa11x0_init_clock(void) unsigned int sa11x0_getspeed(void)
{ {
cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100, 59000, 287000); return cclk_frequency_100khz[PPCR & 0xf] * 100;
return 0;
} }
__initcall(sa11x0_init_clock);
#else #else
/* /*
* We still need to provide this so building without cpufreq works. * We still need to provide this so building without cpufreq works.
...@@ -100,7 +97,7 @@ EXPORT_SYMBOL(cpufreq_get); ...@@ -100,7 +97,7 @@ EXPORT_SYMBOL(cpufreq_get);
static void sa1100_power_off(void) static void sa1100_power_off(void)
{ {
mdelay(100); mdelay(100);
cli(); local_irq_disable();
/* disable internal oscillator, float CS lines */ /* disable internal oscillator, float CS lines */
PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS); PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
/* enable wake-up on GPIO0 (Assabet...) */ /* enable wake-up on GPIO0 (Assabet...) */
......
...@@ -49,7 +49,7 @@ static int __init graphicsmaster_init(void) ...@@ -49,7 +49,7 @@ static int __init graphicsmaster_init(void)
/* /*
* Enable PWM control for LCD * Enable PWM control for LCD
*/ */
SKPCR |= SKPCR_PWMCLKEN; sa1111_enable_device(SKPCR_PWMCLKEN);
SKPWM0 = 0x7F; // VEE SKPWM0 = 0x7F; // VEE
SKPEN0 = 1; SKPEN0 = 1;
SKPWM1 = 0x01; // Backlight SKPWM1 = 0x01; // Backlight
......
...@@ -55,6 +55,12 @@ static int sa1100_gpio_type(unsigned int irq, unsigned int type) ...@@ -55,6 +55,12 @@ static int sa1100_gpio_type(unsigned int irq, unsigned int type)
else else
mask = GPIO11_27_MASK(irq); mask = GPIO11_27_MASK(irq);
if (type == IRQT_PROBE) {
if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
return 0;
type = __IRQT_RISEDGE | __IRQT_FALEDGE;
}
if (type & __IRQT_RISEDGE) { if (type & __IRQT_RISEDGE) {
GPIO_IRQ_rising_edge |= mask; GPIO_IRQ_rising_edge |= mask;
} else } else
......
...@@ -73,7 +73,7 @@ int pm_do_suspend(void) ...@@ -73,7 +73,7 @@ int pm_do_suspend(void)
{ {
unsigned long sleep_save[SLEEP_SAVE_SIZE]; unsigned long sleep_save[SLEEP_SAVE_SIZE];
cli(); local_irq_disable();
leds_event(led_stop); leds_event(led_stop);
...@@ -157,7 +157,7 @@ int pm_do_suspend(void) ...@@ -157,7 +157,7 @@ int pm_do_suspend(void)
leds_event(led_start); leds_event(led_start);
sti(); local_irq_enable();
/* /*
* Restore the CPU frequency settings. * Restore the CPU frequency settings.
......
...@@ -117,11 +117,12 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags) ...@@ -117,11 +117,12 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags)
{ {
unsigned int mask = SA1111_IRQMASK_LO(irq); unsigned int mask = SA1111_IRQMASK_LO(irq);
if (flags == IRQT_PROBE)
return 0;
if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0) if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0)
return -EINVAL; return -EINVAL;
printk("IRQ%d: %s edge\n", irq, flags & __IRQT_RISEDGE ? "rising" : "falling");
if (flags & __IRQT_RISEDGE) if (flags & __IRQT_RISEDGE)
INTPOL0 &= ~mask; INTPOL0 &= ~mask;
else else
...@@ -181,11 +182,12 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags) ...@@ -181,11 +182,12 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags)
{ {
unsigned int mask = SA1111_IRQMASK_HI(irq); unsigned int mask = SA1111_IRQMASK_HI(irq);
if (flags == IRQT_PROBE)
return 0;
if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0) if ((!(flags & __IRQT_RISEDGE) ^ !(flags & __IRQT_FALEDGE)) == 0)
return -EINVAL; return -EINVAL;
printk("IRQ%d: %s edge\n", irq, flags & __IRQT_RISEDGE ? "rising" : "falling");
if (flags & __IRQT_RISEDGE) if (flags & __IRQT_RISEDGE)
INTPOL1 &= ~mask; INTPOL1 &= ~mask;
else else
...@@ -302,7 +304,7 @@ sa1111_probe(struct device *parent, unsigned long phys_addr) ...@@ -302,7 +304,7 @@ sa1111_probe(struct device *parent, unsigned long phys_addr)
/* /*
* Probe for the chip. Only touch the SBI registers. * Probe for the chip. Only touch the SBI registers.
*/ */
id = readl(sa->base + SA1111_SKID); id = sa1111_readl(sa->base + SA1111_SKID);
if ((id & SKID_ID_MASK) != SKID_SA1111_ID) { if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id); printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id);
ret = -ENODEV; ret = -ENODEV;
...@@ -370,11 +372,11 @@ void sa1111_wake(void) ...@@ -370,11 +372,11 @@ void sa1111_wake(void)
/* /*
* Turn VCO on, and disable PLL Bypass. * Turn VCO on, and disable PLL Bypass.
*/ */
r = readl(sa->base + SA1111_SKCR); r = sa1111_readl(sa->base + SA1111_SKCR);
r &= ~SKCR_VCO_OFF; r &= ~SKCR_VCO_OFF;
writel(r, sa->base + SA1111_SKCR); sa1111_writel(r, sa->base + SA1111_SKCR);
r |= SKCR_PLL_BYPASS | SKCR_OE_EN; r |= SKCR_PLL_BYPASS | SKCR_OE_EN;
writel(r, sa->base + SA1111_SKCR); sa1111_writel(r, sa->base + SA1111_SKCR);
/* /*
* Wait lock time. SA1111 manual _doesn't_ * Wait lock time. SA1111 manual _doesn't_
...@@ -386,7 +388,7 @@ void sa1111_wake(void) ...@@ -386,7 +388,7 @@ void sa1111_wake(void)
* Enable RCLK. We also ensure that RDYEN is set. * Enable RCLK. We also ensure that RDYEN is set.
*/ */
r |= SKCR_RCLKEN | SKCR_RDYEN; r |= SKCR_RCLKEN | SKCR_RDYEN;
writel(r, sa->base + SA1111_SKCR); sa1111_writel(r, sa->base + SA1111_SKCR);
/* /*
* Wait 14 RCLK cycles for the chip to finish coming out * Wait 14 RCLK cycles for the chip to finish coming out
...@@ -397,7 +399,7 @@ void sa1111_wake(void) ...@@ -397,7 +399,7 @@ void sa1111_wake(void)
/* /*
* Ensure all clocks are initially off. * Ensure all clocks are initially off.
*/ */
writel(0, sa->base + SA1111_SKPCR); sa1111_writel(0, sa->base + SA1111_SKPCR);
local_irq_restore(flags); local_irq_restore(flags);
} }
...@@ -406,16 +408,18 @@ void sa1111_doze(void) ...@@ -406,16 +408,18 @@ void sa1111_doze(void)
{ {
struct sa1111_device *sa = sa1111; struct sa1111_device *sa = sa1111;
unsigned long flags; unsigned long flags;
unsigned int val;
local_irq_save(flags); local_irq_save(flags);
if (readl(sa->base + SA1111_SKPCR) & SKPCR_UCLKEN) { if (sa1111_readl(sa->base + SA1111_SKPCR) & SKPCR_UCLKEN) {
local_irq_restore(flags); local_irq_restore(flags);
printk("SA1111 doze mode refused\n"); printk("SA1111 doze mode refused\n");
return; return;
} }
writel(readl(sa->base + SA1111_SKCR) & ~SKCR_RCLKEN, sa->base + SA1111_SKCR); val = sa1111_readl(sa->base + SA1111_SKCR);
sa1111_writel(val & ~SKCR_RCLKEN, sa->base + SA1111_SKCR);
local_irq_restore(flags); local_irq_restore(flags);
} }
...@@ -430,9 +434,37 @@ void sa1111_configure_smc(int sdram, unsigned int drac, unsigned int cas_latency ...@@ -430,9 +434,37 @@ void sa1111_configure_smc(int sdram, unsigned int drac, unsigned int cas_latency
if (cas_latency == 3) if (cas_latency == 3)
smcr |= SMCR_CLAT; smcr |= SMCR_CLAT;
writel(smcr, sa->base + SA1111_SMCR); sa1111_writel(smcr, sa->base + SA1111_SMCR);
}
EXPORT_SYMBOL(sa1111_wake);
EXPORT_SYMBOL(sa1111_doze);
void sa1111_enable_device(unsigned int mask)
{
struct sa1111_device *sa = sa1111;
unsigned int val;
preempt_disable();
val = sa1111_readl(sa->base + SA1111_SKPCR);
sa1111_writel(val | mask, sa->base + SA1111_SKPCR);
preempt_enable();
} }
void sa1111_disable_device(unsigned int mask)
{
struct sa1111_device *sa = sa1111;
unsigned int val;
preempt_disable();
val = sa1111_readl(sa->base + SA1111_SKPCR);
sa1111_writel(val & ~mask, sa->base + SA1111_SKPCR);
preempt_enable();
}
EXPORT_SYMBOL(sa1111_enable_device);
EXPORT_SYMBOL(sa1111_disable_device);
/* According to the "Intel StrongARM SA-1111 Microprocessor Companion /* According to the "Intel StrongARM SA-1111 Microprocessor Companion
* Chip Specification Update" (June 2000), erratum #7, there is a * Chip Specification Update" (June 2000), erratum #7, there is a
* significant bug in Serial Audio Controller DMA. If the SAC is * significant bug in Serial Audio Controller DMA. If the SAC is
...@@ -527,7 +559,7 @@ int sa1111_init(struct device *parent, unsigned long phys, unsigned int irq) ...@@ -527,7 +559,7 @@ int sa1111_init(struct device *parent, unsigned long phys, unsigned int irq)
* We only need to turn on DCLK whenever we want to use the * We only need to turn on DCLK whenever we want to use the
* DMA. It can otherwise be held firmly in the off position. * DMA. It can otherwise be held firmly in the off position.
*/ */
SKPCR |= SKPCR_DCLKEN; sa1111_enable_device(SKPCR_DCLKEN);
/* /*
* Enable the SA1110 memory bus request and grant signals. * Enable the SA1110 memory bus request and grant signals.
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/serial_sa1100.h> #include <asm/mach/serial_sa1100.h>
#include <asm/arch/shannon.h>
#include "generic.h" #include "generic.h"
...@@ -23,13 +24,16 @@ static void __init shannon_map_io(void) ...@@ -23,13 +24,16 @@ static void __init shannon_map_io(void)
sa1100_register_uart(0, 3); sa1100_register_uart(0, 3);
sa1100_register_uart(1, 1); sa1100_register_uart(1, 1);
Ser1SDCR0 |= SDCR0_SUS; Ser1SDCR0 |= SDCR0_SUS;
GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD); GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD);
GPDR |= GPIO_UART_TXD; GPDR |= GPIO_UART_TXD | SHANNON_GPIO_CODEC_RESET;
GPDR &= ~GPIO_UART_RXD; GPDR &= ~GPIO_UART_RXD;
PPAR |= PPAR_UPR; PPAR |= PPAR_UPR;
set_GPIO_IRQ_edge(SHANNON_GPIO_IRQ_CODEC); /* reset the codec */
GPCR = SHANNON_GPIO_CODEC_RESET;
GPSR = SHANNON_GPIO_CODEC_RESET;
} }
MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)") MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
......
...@@ -44,7 +44,8 @@ ENTRY(sa1100_cpu_suspend) ...@@ -44,7 +44,8 @@ ENTRY(sa1100_cpu_suspend)
mrc p15, 0, r7, c1, c0, 0 @ control reg mrc p15, 0, r7, c1, c0, 0 @ control reg
@ store them plus current virtual stack ptr on stack @ store them plus current virtual stack ptr on stack
stmfd sp!, {r4 - r7, sp} mov r8, sp
stmfd sp!, {r4 - r8}
@ preserve phys address of stack @ preserve phys address of stack
mov r0, sp mov r0, sp
......
...@@ -309,7 +309,7 @@ static void system3_lcd_on(void) ...@@ -309,7 +309,7 @@ static void system3_lcd_on(void)
PTCTRL0_set( PT_CTRL0_LCD_EN ); PTCTRL0_set( PT_CTRL0_LCD_EN );
/* brightness / contrast */ /* brightness / contrast */
SKPCR |= SKPCR_PWMCLKEN; sa1111_enable_device(SKPCR_PWMCLKEN);
PB_DDR = 0xFFFFFFFF; PB_DDR = 0xFFFFFFFF;
SKPEN0 = 1; SKPEN0 = 1;
SKPEN1 = 1; SKPEN1 = 1;
...@@ -325,7 +325,7 @@ static void system3_lcd_off(void) ...@@ -325,7 +325,7 @@ static void system3_lcd_off(void)
PTCTRL0_clear( PT_CTRL0_LCD_EN ); PTCTRL0_clear( PT_CTRL0_LCD_EN );
SKPEN0 = 0; SKPEN0 = 0;
SKPEN1 = 0; SKPEN1 = 0;
SKPCR &= ~SKPCR_PWMCLKEN; sa1111_disable_device(SKPCR_PWMCLKEN);
} }
/** /**
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
static void xp860_power_off(void) static void xp860_power_off(void)
{ {
cli(); local_irq_disable();
GPDR |= GPIO_GPIO20; GPDR |= GPIO_GPIO20;
GPSR = GPIO_GPIO20; GPSR = GPIO_GPIO20;
mdelay(1000); mdelay(1000);
......
...@@ -42,7 +42,7 @@ p-$(CONFIG_CPU_SA1100) += proc-sa110.o tlb-v4wb.o copypage-v4mc.o abort-ev4.o ...@@ -42,7 +42,7 @@ p-$(CONFIG_CPU_SA1100) += proc-sa110.o tlb-v4wb.o copypage-v4mc.o abort-ev4.o
# ARMv5 # ARMv5
p-$(CONFIG_CPU_ARM926T) += proc-arm926.o tlb-v4wb.o copypage-v4wb.o abort-ev5ej.o p-$(CONFIG_CPU_ARM926T) += proc-arm926.o tlb-v4wb.o copypage-v4wb.o abort-ev5ej.o
p-$(CONFIG_CPU_XSCALE) += proc-xscale.o tlb-v4wb.o copypage-v5te.o abort-ev4t.o minicache.o p-$(CONFIG_CPU_XSCALE) += proc-xscale.o tlb-v4wb.o copypage-xscale.o abort-xscale.o minicache.o
obj-y += $(sort $(p-y)) obj-y += $(sort $(p-y))
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* : r3 = saved SPSR * : r3 = saved SPSR
* *
* Returns : r0 = address of abort * Returns : r0 = address of abort
* : r1 = FSR, bit 8 = write * : r1 = FSR, bit 11 = write
* : r2-r8 = corrupted * : r2-r8 = corrupted
* : r9 = preserved * : r9 = preserved
* : sp = pointer to registers * : sp = pointer to registers
...@@ -22,8 +22,9 @@ ENTRY(v4_early_abort) ...@@ -22,8 +22,9 @@ ENTRY(v4_early_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR mrc p15, 0, r0, c6, c0, 0 @ get FAR
ldr r3, [r2] @ read aborted ARM instruction ldr r3, [r2] @ read aborted ARM instruction
bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
tst r3, #1 << 20 @ L = 1 -> write? tst r3, #1 << 20 @ L = 1 -> write?
orreq r1, r1, #1 << 8 @ yes. orreq r1, r1, #1 << 11 @ yes.
mov pc, lr mov pc, lr
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* : r3 = saved SPSR * : r3 = saved SPSR
* *
* Returns : r0 = address of abort * Returns : r0 = address of abort
* : r1 = FSR, bit 8 = write * : r1 = FSR, bit 11 = write
* : r2-r8 = corrupted * : r2-r8 = corrupted
* : r9 = preserved * : r9 = preserved
* : sp = pointer to registers * : sp = pointer to registers
...@@ -24,8 +24,8 @@ ENTRY(v4t_early_abort) ...@@ -24,8 +24,8 @@ ENTRY(v4t_early_abort)
tst r3, #PSR_T_BIT tst r3, #PSR_T_BIT
ldrneh r3, [r2] @ read aborted thumb instruction ldrneh r3, [r2] @ read aborted thumb instruction
ldreq r3, [r2] @ read aborted ARM instruction ldreq r3, [r2] @ read aborted ARM instruction
bic r1, r1, #1 << 8 bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20 movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
tst r3, #1 << 20 @ check write tst r3, #1 << 20 @ check write
orreq r1, r1, #1 << 8 orreq r1, r1, #1 << 11
mov pc, lr mov pc, lr
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/assembler.h> #include <asm/assembler.h>
/* /*
* Function: v5ej_early_abort * Function: v5tej_early_abort
* *
* Params : r2 = address of aborted instruction * Params : r2 = address of aborted instruction
* : r3 = saved SPSR * : r3 = saved SPSR
* *
* Returns : r0 = address of abort * Returns : r0 = address of abort
* : r1 = FSR, bit 8 = write * : r1 = FSR, bit 11 = write
* : r2-r8 = corrupted * : r2-r8 = corrupted
* : r9 = preserved * : r9 = preserved
* : sp = pointer to registers * : sp = pointer to registers
...@@ -18,18 +18,19 @@ ...@@ -18,18 +18,19 @@
* picture. Unfortunately, this does happen. We live with it. * picture. Unfortunately, this does happen. We live with it.
*/ */
.align 5 .align 5
ENTRY(v5ej_early_abort) ENTRY(v5tej_early_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR mrc p15, 0, r0, c6, c0, 0 @ get FAR
bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
tst r3, #PSR_J_BIT tst r3, #PSR_J_BIT
orrne r1, r1, #1 << 8 @ always assume write orrne r1, r1, #1 << 11 @ always assume write
bne 1f bne 1f
tst r3, #PSR_T_BIT tst r3, #PSR_T_BIT
ldrneh r3, [r2] @ read aborted thumb instruction ldrneh r3, [r2] @ read aborted thumb instruction
ldreq r3, [r2] @ read aborted ARM instruction ldreq r3, [r2] @ read aborted ARM instruction
movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20 movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
tst r3, #1 << 20 @ L = 1 -> write tst r3, #1 << 20 @ L = 1 -> write
orreq r1, r1, #1 << 8 @ yes. orreq r1, r1, #1 << 11 @ yes.
1: mov pc, lr 1: mov pc, lr
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* : r3 = saved SPSR * : r3 = saved SPSR
* *
* Returns : r0 = address of abort * Returns : r0 = address of abort
* : r1 = FSR, bit 8 = writing * : r1 = FSR, bit 11 = write
* : r2-r8 = corrupted * : r2-r8 = corrupted
* : r9 = preserved * : r9 = preserved
* : sp = pointer to registers * : sp = pointer to registers
...@@ -21,10 +21,11 @@ ENTRY(v4t_late_abort) ...@@ -21,10 +21,11 @@ ENTRY(v4t_late_abort)
tst r3, #PSR_T_BIT @ check for thumb mode tst r3, #PSR_T_BIT @ check for thumb mode
mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR mrc p15, 0, r0, c6, c0, 0 @ get FAR
bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
ldreq r8, [r2] @ read arm instruction ldreq r8, [r2] @ read arm instruction
bne .data_thumb_abort bne .data_thumb_abort
tst r8, #1 << 20 @ L = 1 -> write? tst r8, #1 << 20 @ L = 1 -> write?
orreq r1, r1, #1 << 8 @ yes. orreq r1, r1, #1 << 11 @ yes.
and r7, r8, #15 << 24 and r7, r8, #15 << 24
add pc, pc, r7, lsr #22 @ Now branch to the relevant processing routine add pc, pc, r7, lsr #22 @ Now branch to the relevant processing routine
nop nop
......
#include <linux/linkage.h>
#include <asm/assembler.h>
/*
* Function: xscale_abort
*
* Params : r2 = address of aborted instruction
* : r3 = saved SPSR
*
* Returns : r0 = address of abort
* : r1 = FSR, bit 11 = write
* : r2-r8 = corrupted
* : r9 = preserved
* : sp = pointer to registers
*
* Purpose : obtain information about current aborted instruction.
* Note: we read user space. This means we might cause a data
* abort here if the I-TLB and D-TLB aren't seeing the same
* picture. Unfortunately, this does happen. We live with it.
*
* Note: Xscale is contains non-standard architecture extensions.
* It requires its own early abort handler
*/
.align 5
ENTRY(xscale_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
tst r3, #PSR_T_BIT
ldrneh r3, [r2] @ read aborted thumb instruction
ldreq r3, [r2] @ read aborted ARM instruction
bic r1, r1, #1 << 11 @ clear bits 11 of FSR
movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
tst r3, #1 << 20 @ check write
orreq r1, r1, #1 << 11
mov pc, lr
/* /*
* linux/arch/arm/lib/copypage-armv5te.S * linux/arch/arm/lib/copypage-xscale.S
* *
* Copyright (C) 2001 Russell King * Copyright (C) 2001 Russell King
* *
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
.text .text
.align 5 .align 5
/* /*
* ARMv5TE optimised copy_user_page * XScale optimised copy_user_page
* r0 = destination * r0 = destination
* r1 = source * r1 = source
* r2 = virtual user address of ultimate destination page * r2 = virtual user address of ultimate destination page
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
* page. We rely on the mini-cache being smaller than one page, so we'll * page. We rely on the mini-cache being smaller than one page, so we'll
* cycle through the complete cache anyway. * cycle through the complete cache anyway.
*/ */
ENTRY(v5te_mc_copy_user_page) ENTRY(xscale_mc_copy_user_page)
stmfd sp!, {r4, r5, lr} stmfd sp!, {r4, r5, lr}
mov r5, r0 mov r5, r0
mov r0, r1 mov r0, r1
...@@ -58,11 +58,11 @@ ENTRY(v5te_mc_copy_user_page) ...@@ -58,11 +58,11 @@ ENTRY(v5te_mc_copy_user_page)
.align 5 .align 5
/* /*
* ARMv5TE optimised clear_user_page * XScale optimised clear_user_page
* r0 = destination * r0 = destination
* r1 = virtual user address of ultimate destination page * r1 = virtual user address of ultimate destination page
*/ */
ENTRY(v5te_mc_clear_user_page) ENTRY(xscale_mc_clear_user_page)
str lr, [sp, #-4]! str lr, [sp, #-4]!
mov r1, #PAGE_SZ/32 mov r1, #PAGE_SZ/32
mov r2, #0 mov r2, #0
...@@ -80,6 +80,6 @@ ENTRY(v5te_mc_clear_user_page) ...@@ -80,6 +80,6 @@ ENTRY(v5te_mc_clear_user_page)
.section ".text.init", #alloc, #execinstr .section ".text.init", #alloc, #execinstr
ENTRY(v5te_mc_user_fns) ENTRY(xscale_mc_user_fns)
.long v5te_mc_clear_user_page .long xscale_mc_clear_user_page
.long v5te_mc_copy_user_page .long xscale_mc_copy_user_page
...@@ -47,6 +47,10 @@ static struct fsr_info { ...@@ -47,6 +47,10 @@ static struct fsr_info {
int sig; int sig;
const char *name; const char *name;
} fsr_info[] = { } fsr_info[] = {
/*
* The following are the standard ARMv3 and ARMv4 aborts. ARMv5
* defines these to be "precise" aborts.
*/
{ do_bad, SIGSEGV, "vector exception" }, { do_bad, SIGSEGV, "vector exception" },
{ do_bad, SIGILL, "alignment exception" }, { do_bad, SIGILL, "alignment exception" },
{ do_bad, SIGKILL, "terminal exception" }, { do_bad, SIGKILL, "terminal exception" },
...@@ -62,14 +66,35 @@ static struct fsr_info { ...@@ -62,14 +66,35 @@ static struct fsr_info {
{ do_bad, SIGBUS, "external abort on translation" }, { do_bad, SIGBUS, "external abort on translation" },
{ do_sect_fault, SIGSEGV, "section permission fault" }, { do_sect_fault, SIGSEGV, "section permission fault" },
{ do_bad, SIGBUS, "external abort on translation" }, { do_bad, SIGBUS, "external abort on translation" },
{ do_page_fault, SIGSEGV, "page permission fault" } { do_page_fault, SIGSEGV, "page permission fault" },
/*
* The following are "imprecise" aborts, which are signalled by bit
* 10 of the FSR, and may not be recoverable. These are only
* supported if the CPU abort handler supports bit 10.
*/
{ do_bad, SIGBUS, "unknown 16" },
{ do_bad, SIGBUS, "unknown 17" },
{ do_bad, SIGBUS, "unknown 18" },
{ do_bad, SIGBUS, "unknown 19" },
{ do_bad, SIGBUS, "lock abort" }, /* xscale */
{ do_bad, SIGBUS, "unknown 21" },
{ do_bad, SIGBUS, "imprecise external abort" }, /* xscale */
{ do_bad, SIGBUS, "unknown 23" },
{ do_bad, SIGBUS, "dcache parity error" }, /* xscale */
{ do_bad, SIGBUS, "unknown 25" },
{ do_bad, SIGBUS, "unknown 26" },
{ do_bad, SIGBUS, "unknown 27" },
{ do_bad, SIGBUS, "unknown 28" },
{ do_bad, SIGBUS, "unknown 29" },
{ do_bad, SIGBUS, "unknown 30" },
{ do_bad, SIGBUS, "unknown 31" }
}; };
void __init void __init
hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *), hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *),
int sig, const char *name) int sig, const char *name)
{ {
if (nr >= 0 && nr < 16) { if (nr >= 0 && nr < ARRAY_SIZE(fsr_info)) {
fsr_info[nr].fn = fn; fsr_info[nr].fn = fn;
fsr_info[nr].sig = sig; fsr_info[nr].sig = sig;
fsr_info[nr].name = name; fsr_info[nr].name = name;
...@@ -82,7 +107,7 @@ hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *) ...@@ -82,7 +107,7 @@ hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *)
asmlinkage void asmlinkage void
do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{ {
const struct fsr_info *inf = fsr_info + (fsr & 15); const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6);
if (!inf->fn(addr, fsr, regs)) if (!inf->fn(addr, fsr, regs))
return; return;
......
...@@ -34,12 +34,10 @@ ...@@ -34,12 +34,10 @@
#define READ_FAULT(m) (!((m) & FAULT_CODE_WRITE)) #define READ_FAULT(m) (!((m) & FAULT_CODE_WRITE))
#else #else
/* /*
* On 32-bit processors, we define "mode" to be zero when reading, * "code" is actually the FSR register. Bit 11 set means the
* non-zero when writing. This now ties up nicely with the polarity * isntruction was performing a write.
* of the 26-bit machines, and also means that we avoid the horrible
* gcc code for "int val = !other_val;".
*/ */
#define DO_COW(code) ((code) & (1 << 8)) #define DO_COW(code) ((code) & (1 << 11))
#define READ_FAULT(code) (!DO_COW(code)) #define READ_FAULT(code) (!DO_COW(code))
#endif #endif
...@@ -56,7 +54,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr) ...@@ -56,7 +54,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
printk(KERN_ALERT "pgd = %p\n", mm->pgd); printk(KERN_ALERT "pgd = %p\n", mm->pgd);
pgd = pgd_offset(mm, addr); pgd = pgd_offset(mm, addr);
printk(KERN_ALERT "*pgd = %08lx", pgd_val(*pgd)); printk(KERN_ALERT "*pgd=%08lx", pgd_val(*pgd));
do { do {
pmd_t *pmd; pmd_t *pmd;
...@@ -71,7 +69,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr) ...@@ -71,7 +69,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
} }
pmd = pmd_offset(pgd, addr); pmd = pmd_offset(pgd, addr);
printk(", *pmd = %08lx", pmd_val(*pmd)); #if PTRS_PER_PMD != 1
printk(", *pmd=%08lx", pmd_val(*pmd));
#endif
if (pmd_none(*pmd)) if (pmd_none(*pmd))
break; break;
...@@ -84,9 +84,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr) ...@@ -84,9 +84,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
#ifndef CONFIG_HIGHMEM #ifndef CONFIG_HIGHMEM
/* We must not map this if we have highmem enabled */ /* We must not map this if we have highmem enabled */
pte = pte_offset_map(pmd, addr); pte = pte_offset_map(pmd, addr);
printk(", *pte = %08lx", pte_val(*pte)); printk(", *pte=%08lx", pte_val(*pte));
#ifdef CONFIG_CPU_32 #ifdef CONFIG_CPU_32
printk(", *ppte = %08lx", pte_val(pte[-PTRS_PER_PTE])); printk(", *ppte=%08lx", pte_val(pte[-PTRS_PER_PTE]));
#endif #endif
pte_unmap(pte); pte_unmap(pte);
#endif #endif
......
...@@ -394,8 +394,6 @@ ENTRY(cpu_arm1020_set_pmd) ...@@ -394,8 +394,6 @@ ENTRY(cpu_arm1020_set_pmd)
*/ */
.align 5 .align 5
ENTRY(cpu_arm1020_set_pte) ENTRY(cpu_arm1020_set_pte)
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version str r1, [r0], #-2048 @ linux version
eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
...@@ -553,7 +551,7 @@ __arm1020_proc_info: ...@@ -553,7 +551,7 @@ __arm1020_proc_info:
b __arm1020_setup b __arm1020_setup
.long cpu_arch_name .long cpu_arch_name
.long cpu_elf_name .long cpu_elf_name
.long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
.long cpu_arm1020_info .long cpu_arm1020_info
.long arm1020_processor_functions .long arm1020_processor_functions
.long v4wbi_tlb_fns .long v4wbi_tlb_fns
......
...@@ -272,8 +272,6 @@ ENTRY(cpu_arm7_set_pmd) ...@@ -272,8 +272,6 @@ ENTRY(cpu_arm7_set_pmd)
.align 5 .align 5
ENTRY(cpu_arm6_set_pte) ENTRY(cpu_arm6_set_pte)
ENTRY(cpu_arm7_set_pte) ENTRY(cpu_arm7_set_pte)
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version str r1, [r0], #-2048 @ linux version
eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
......
...@@ -135,8 +135,6 @@ ENTRY(cpu_arm720_set_pmd) ...@@ -135,8 +135,6 @@ ENTRY(cpu_arm720_set_pmd)
*/ */
.align 5 .align 5
ENTRY(cpu_arm720_set_pte) ENTRY(cpu_arm720_set_pte)
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version str r1, [r0], #-2048 @ linux version
eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
...@@ -257,7 +255,7 @@ __arm720_proc_info: ...@@ -257,7 +255,7 @@ __arm720_proc_info:
b __arm720_setup @ cpu_flush b __arm720_setup @ cpu_flush
.long cpu_arch_name @ arch_name .long cpu_arch_name @ arch_name
.long cpu_elf_name @ elf_name .long cpu_elf_name @ elf_name
.long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_26BIT @ elf_hwcap .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB @ elf_hwcap
.long cpu_arm720_info @ info .long cpu_arm720_info @ info
.long arm720_processor_functions .long arm720_processor_functions
.long v4_tlb_fns .long v4_tlb_fns
......
...@@ -539,7 +539,7 @@ __arm920_proc_info: ...@@ -539,7 +539,7 @@ __arm920_proc_info:
b __arm920_setup b __arm920_setup
.long cpu_arch_name .long cpu_arch_name
.long cpu_elf_name .long cpu_elf_name
.long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
.long cpu_arm920_info .long cpu_arm920_info
.long arm920_processor_functions .long arm920_processor_functions
.long v4wbi_tlb_fns .long v4wbi_tlb_fns
......
...@@ -395,8 +395,6 @@ ENTRY(cpu_arm922_set_pmd) ...@@ -395,8 +395,6 @@ ENTRY(cpu_arm922_set_pmd)
*/ */
.align 5 .align 5
ENTRY(cpu_arm922_set_pte) ENTRY(cpu_arm922_set_pte)
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version str r1, [r0], #-2048 @ linux version
eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
...@@ -540,7 +538,7 @@ __arm922_proc_info: ...@@ -540,7 +538,7 @@ __arm922_proc_info:
b __arm922_setup b __arm922_setup
.long cpu_arch_name .long cpu_arch_name
.long cpu_elf_name .long cpu_elf_name
.long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
.long cpu_arm922_info .long cpu_arm922_info
.long arm922_processor_functions .long arm922_processor_functions
.long v4wbi_tlb_fns .long v4wbi_tlb_fns
......
/* /*
* linux/arch/arm/mm/arm926.S: MMU functions for ARM926EJ-S * linux/arch/arm/mm/proc-arm926.S: MMU functions for ARM926EJ-S
* *
* Copyright (C) 1999-2001 ARM Limited * Copyright (C) 1999-2001 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd. * Copyright (C) 2000 Deep Blue Solutions Ltd.
...@@ -378,8 +378,6 @@ ENTRY(cpu_arm926_set_pmd) ...@@ -378,8 +378,6 @@ ENTRY(cpu_arm926_set_pmd)
*/ */
.align 5 .align 5
ENTRY(cpu_arm926_set_pte) ENTRY(cpu_arm926_set_pte)
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version str r1, [r0], #-2048 @ linux version
eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
...@@ -483,7 +481,7 @@ __arm926_setup: ...@@ -483,7 +481,7 @@ __arm926_setup:
*/ */
.type arm926_processor_functions, #object .type arm926_processor_functions, #object
arm926_processor_functions: arm926_processor_functions:
.word v5ej_early_abort .word v5tej_early_abort
.word cpu_arm926_check_bugs .word cpu_arm926_check_bugs
.word cpu_arm926_proc_init .word cpu_arm926_proc_init
.word cpu_arm926_proc_fin .word cpu_arm926_proc_fin
...@@ -519,12 +517,12 @@ cpu_arm926_info: ...@@ -519,12 +517,12 @@ cpu_arm926_info:
.type cpu_arch_name, #object .type cpu_arch_name, #object
cpu_arch_name: cpu_arch_name:
.asciz "armv5EJ" .asciz "armv5tej"
.size cpu_arch_name, . - cpu_arch_name .size cpu_arch_name, . - cpu_arch_name
.type cpu_elf_name, #object .type cpu_elf_name, #object
cpu_elf_name: cpu_elf_name:
.asciz "v5EJ" .asciz "v5"
.size cpu_elf_name, . - cpu_elf_name .size cpu_elf_name, . - cpu_elf_name
.align .align
...@@ -538,7 +536,8 @@ __arm926_proc_info: ...@@ -538,7 +536,8 @@ __arm926_proc_info:
b __arm926_setup b __arm926_setup
.long cpu_arch_name .long cpu_arch_name
.long cpu_elf_name .long cpu_elf_name
.long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | \
HWCAP_FAST_MULT | HWCAP_JAVA
.long cpu_arm926_info .long cpu_arm926_info
.long arm926_processor_functions .long arm926_processor_functions
.long v4wbi_tlb_fns .long v4wbi_tlb_fns
......
...@@ -602,8 +602,6 @@ ENTRY(cpu_xscale_set_pmd) ...@@ -602,8 +602,6 @@ ENTRY(cpu_xscale_set_pmd)
*/ */
.align 5 .align 5
ENTRY(cpu_xscale_set_pte) ENTRY(cpu_xscale_set_pte)
tst r0, #2048
streq r0, [r0, -r0] @ BUG_ON
str r1, [r0], #-2048 @ linux version str r1, [r0], #-2048 @ linux version
bic r2, r1, #0xff0 bic r2, r1, #0xff0
...@@ -681,6 +679,9 @@ __xscale_setup: ...@@ -681,6 +679,9 @@ __xscale_setup:
mcr p15, 0, r4, c2, c0, 0 @ load page table pointer mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
mov r0, #0x1f @ Domains 0, 1 = client mov r0, #0x1f @ Domains 0, 1 = client
mcr p15, 0, r0, c3, c0, 0 @ load domain access register mcr p15, 0, r0, c3, c0, 0 @ load domain access register
mov r0, #1 @ Allow access to CP0 and CP13
orr r0, r0, #1 << 13 @ Its undefined whether this
mcr p15, 0, r0, c15, c1, 0 @ affects USR or SVC modes
mrc p15, 0, r0, c1, c0, 0 @ get control register mrc p15, 0, r0, c1, c0, 0 @ get control register
bic r0, r0, #0x0200 @ .... ..R. .... .... bic r0, r0, #0x0200 @ .... ..R. .... ....
bic r0, r0, #0x0082 @ .... .... B... ..A. bic r0, r0, #0x0082 @ .... .... B... ..A.
...@@ -697,7 +698,7 @@ __xscale_setup: ...@@ -697,7 +698,7 @@ __xscale_setup:
.type xscale_processor_functions, #object .type xscale_processor_functions, #object
ENTRY(xscale_processor_functions) ENTRY(xscale_processor_functions)
.word v4t_early_abort .word xscale_abort
.word cpu_xscale_check_bugs .word cpu_xscale_check_bugs
.word cpu_xscale_proc_init .word cpu_xscale_proc_init
.word cpu_xscale_proc_fin .word cpu_xscale_proc_fin
...@@ -739,7 +740,7 @@ cpu_pxa250_info: ...@@ -739,7 +740,7 @@ cpu_pxa250_info:
.type cpu_arch_name, #object .type cpu_arch_name, #object
cpu_arch_name: cpu_arch_name:
.asciz "armv5" .asciz "armv5te"
.size cpu_arch_name, . - cpu_arch_name .size cpu_arch_name, . - cpu_arch_name
.type cpu_elf_name, #object .type cpu_elf_name, #object
...@@ -762,7 +763,7 @@ __80200_proc_info: ...@@ -762,7 +763,7 @@ __80200_proc_info:
.long cpu_80200_info .long cpu_80200_info
.long xscale_processor_functions .long xscale_processor_functions
.long v4wbi_tlb_fns .long v4wbi_tlb_fns
.long v5te_mc_user_fns .long xscale_mc_user_fns
.size __80200_proc_info, . - __80200_proc_info .size __80200_proc_info, . - __80200_proc_info
.type __pxa250_proc_info,#object .type __pxa250_proc_info,#object
...@@ -777,6 +778,6 @@ __pxa250_proc_info: ...@@ -777,6 +778,6 @@ __pxa250_proc_info:
.long cpu_pxa250_info .long cpu_pxa250_info
.long xscale_processor_functions .long xscale_processor_functions
.long v4wbi_tlb_fns .long v4wbi_tlb_fns
.long v5te_mc_user_fns .long xscale_mc_user_fns
.size __pxa250_proc_info, . - __pxa250_proc_info .size __pxa250_proc_info, . - __pxa250_proc_info
...@@ -142,9 +142,6 @@ void FPA11_CheckInit(void) ...@@ -142,9 +142,6 @@ void FPA11_CheckInit(void)
unsigned int EmulateAll(unsigned int opcode) unsigned int EmulateAll(unsigned int opcode)
{ {
unsigned int nRc = 1, code; unsigned int nRc = 1, code;
unsigned long flags;
save_flags(flags); sti();
code = opcode & 0x00000f00; code = opcode & 0x00000f00;
if (code == 0x00000100 || code == 0x00000200) if (code == 0x00000100 || code == 0x00000200)
...@@ -180,8 +177,6 @@ unsigned int EmulateAll(unsigned int opcode) ...@@ -180,8 +177,6 @@ unsigned int EmulateAll(unsigned int opcode)
} }
} }
restore_flags(flags);
return(nRc); return(nRc);
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# To add an entry into this database, please see Documentation/arm/README, # To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk # or contact rmk@arm.linux.org.uk
# #
# Last update: Tue May 21 14:19:05 2002 # Last update: Fri Jul 5 21:32:20 2002
# #
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
# #
...@@ -192,3 +192,18 @@ ks8695 ARCH_KS8695 KS8695 180 ...@@ -192,3 +192,18 @@ ks8695 ARCH_KS8695 KS8695 180
brh ARCH_BRH BRH 181 brh ARCH_BRH BRH 181
s3c2410 ARCH_S3C2410 S3C2410 182 s3c2410 ARCH_S3C2410 S3C2410 182
possio_px30 ARCH_POSSIO_PX30 POSSIO_PX30 183 possio_px30 ARCH_POSSIO_PX30 POSSIO_PX30 183
s3c2800 ARCH_S3C2800 S3C2800 184
fleetwood SA1100_FLEETWOOD FLEETWOOD 185
omaha ARCH_OMAHA OMAHA 186
ta7 ARCH_TA7 TA7 187
nova SA1100_NOVA NOVA 188
hmk ARCH_HMK HMK 189
inphinity ARCH_INPHINITY INPHINITY 190
fester SA1100_FESTER FESTER 191
gpi ARCH_GPI GPI 192
smdk2410 ARCH_SMDK2410 SMDK2410 193
premium ARCH_PREMIUM PREMIUM 194
nexio SA1100_NEXIO NEXIO 195
bitbox SA1100_BITBOX BITBOX 196
g200 SA1100_G200 G200 197
gill SA1100_GILL GILL 198
...@@ -8,10 +8,9 @@ jiffies = jiffies_64; ...@@ -8,10 +8,9 @@ jiffies = jiffies_64;
SECTIONS SECTIONS
{ {
. = TEXTADDR; . = TEXTADDR;
.init : { /* Init code and data */
.init : {
_stext = .; _stext = .;
__init_begin = .; /* Init code and data */ __init_begin = .;
*(.text.init) *(.text.init)
__proc_info_begin = .; __proc_info_begin = .;
*(.proc.info) *(.proc.info)
...@@ -50,7 +49,7 @@ SECTIONS ...@@ -50,7 +49,7 @@ SECTIONS
*(.exitcall.exit) *(.exitcall.exit)
} }
.text : { .text : { /* Real text segment */
_text = .; /* Text and read-only data */ _text = .; /* Text and read-only data */
*(.text) *(.text)
*(.fixup) *(.fixup)
...@@ -59,19 +58,24 @@ SECTIONS ...@@ -59,19 +58,24 @@ SECTIONS
*(.rodata.*) *(.rodata.*)
*(.glue_7) *(.glue_7)
*(.glue_7t) *(.glue_7t)
*(.kstrtab) *(.got) /* Global offset table */
. = ALIGN(16); /* Exception table */
_etext = .; /* End of text section */
}
.kstrtab : { *(.kstrtab) }
. = ALIGN(16);
__ex_table : { /* Exception table */
__start___ex_table = .; __start___ex_table = .;
*(__ex_table) *(__ex_table)
__stop___ex_table = .; __stop___ex_table = .;
}
__start___ksymtab = .; /* Kernel symbol table */ __ksymtab : { /* Kernel symbol table */
__start___ksymtab = .;
*(__ksymtab) *(__ksymtab)
__stop___ksymtab = .; __stop___ksymtab = .;
*(.got) /* Global offset table */
_etext = .; /* End of text section */
} }
.data : { .data : {
...@@ -90,14 +94,12 @@ SECTIONS ...@@ -90,14 +94,12 @@ SECTIONS
_edata = .; _edata = .;
} }
.bss : { .bss : {
__bss_start = .; /* BSS */ __bss_start = .; /* BSS */
*(.bss) *(.bss)
*(COMMON) *(COMMON)
_end = . ; _end = . ;
} }
/* Stabs debugging sections. */ /* Stabs debugging sections. */
.stab 0 : { *(.stab) } .stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) } .stabstr 0 : { *(.stabstr) }
......
...@@ -703,11 +703,11 @@ static ide_startstop_t etrax_dma_intr(struct ata_device *drive, struct request * ...@@ -703,11 +703,11 @@ static ide_startstop_t etrax_dma_intr(struct ata_device *drive, struct request *
i -= rq->current_nr_sectors; i -= rq->current_nr_sectors;
ide_end_request(drive, rq, 1); ide_end_request(drive, rq, 1);
} }
return ide_stopped; return ATA_OP_FINISHED;
} }
printk("%s: bad DMA status\n", drive->name); printk("%s: bad DMA status\n", drive->name);
} }
return ata_error(drive, __FUNCTION__); return ata_error(drive, rq, __FUNCTION__);
} }
/* /*
......
...@@ -389,10 +389,7 @@ CONFIG_SCSI_FCAL=m ...@@ -389,10 +389,7 @@ CONFIG_SCSI_FCAL=m
# Fusion MPT device support # Fusion MPT device support
# #
CONFIG_FUSION=m CONFIG_FUSION=m
# CONFIG_FUSION_BOOT is not set
#
# (ability to boot linux kernel from Fusion device is DISABLED!)
#
CONFIG_FUSION_ISENSE=m CONFIG_FUSION_ISENSE=m
CONFIG_FUSION_CTL=m CONFIG_FUSION_CTL=m
CONFIG_FUSION_LAN=m CONFIG_FUSION_LAN=m
...@@ -576,22 +573,51 @@ CONFIG_DRM_TDFX=m ...@@ -576,22 +573,51 @@ CONFIG_DRM_TDFX=m
# Input device support # Input device support
# #
CONFIG_INPUT=y CONFIG_INPUT=y
#
# Userland interfaces
#
CONFIG_INPUT_KEYBDEV=y CONFIG_INPUT_KEYBDEV=y
CONFIG_INPUT_MOUSEDEV=y CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
CONFIG_INPUT_EVDEV=y CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
# Input I/O drivers
#
# CONFIG_GAMEPORT is not set # CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y CONFIG_SOUND_GAMEPORT=y
# CONFIG_GAMEPORT_NS558 is not set # CONFIG_GAMEPORT_NS558 is not set
# CONFIG_GAMEPORT_L4 is not set # CONFIG_GAMEPORT_L4 is not set
# CONFIG_INPUT_EMU10K1 is not set # CONFIG_INPUT_EMU10K1 is not set
# CONFIG_GAMEPORT_PCIGAME is not set # CONFIG_GAMEPORT_VORTEX is not set
# CONFIG_GAMEPORT_FM801 is not set # CONFIG_GAMEPORT_FM801 is not set
# CONFIG_GAMEPORT_CS461x is not set # CONFIG_GAMEPORT_CS461x is not set
# CONFIG_SERIO is not set # CONFIG_SERIO is not set
# CONFIG_SERIO_I8042 is not set
# CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_SERPORT is not set
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PARKBD is not set
#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_ATKBD is not set
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_PS2SERKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
CONFIG_INPUT_MOUSE=y
# CONFIG_MOUSE_PS2 is not set
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_MOUSE_INPORT is not set
# CONFIG_MOUSE_LOGIBM is not set
# CONFIG_MOUSE_PC110PAD is not set
# CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_JOYSTICK is not set
# CONFIG_JOYSTICK_ANALOG is not set # CONFIG_JOYSTICK_ANALOG is not set
# CONFIG_JOYSTICK_A3D is not set # CONFIG_JOYSTICK_A3D is not set
...@@ -599,6 +625,7 @@ CONFIG_SOUND_GAMEPORT=y ...@@ -599,6 +625,7 @@ CONFIG_SOUND_GAMEPORT=y
# CONFIG_JOYSTICK_COBRA is not set # CONFIG_JOYSTICK_COBRA is not set
# CONFIG_JOYSTICK_GF2K is not set # CONFIG_JOYSTICK_GF2K is not set
# CONFIG_JOYSTICK_GRIP is not set # CONFIG_JOYSTICK_GRIP is not set
# CONFIG_JOYSTICK_GUILLEMOT is not set
# CONFIG_JOYSTICK_INTERACT is not set # CONFIG_JOYSTICK_INTERACT is not set
# CONFIG_JOYSTICK_SIDEWINDER is not set # CONFIG_JOYSTICK_SIDEWINDER is not set
# CONFIG_JOYSTICK_TMDC is not set # CONFIG_JOYSTICK_TMDC is not set
...@@ -609,9 +636,13 @@ CONFIG_SOUND_GAMEPORT=y ...@@ -609,9 +636,13 @@ CONFIG_SOUND_GAMEPORT=y
# CONFIG_JOYSTICK_SPACEORB is not set # CONFIG_JOYSTICK_SPACEORB is not set
# CONFIG_JOYSTICK_SPACEBALL is not set # CONFIG_JOYSTICK_SPACEBALL is not set
# CONFIG_JOYSTICK_STINGER is not set # CONFIG_JOYSTICK_STINGER is not set
# CONFIG_JOYSTICK_TWIDDLER is not set
# CONFIG_JOYSTICK_DB9 is not set # CONFIG_JOYSTICK_DB9 is not set
# CONFIG_JOYSTICK_GAMECON is not set # CONFIG_JOYSTICK_GAMECON is not set
# CONFIG_JOYSTICK_TURBOGRAFX is not set # CONFIG_JOYSTICK_TURBOGRAFX is not set
# CONFIG_INPUT_JOYDUMP is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
# #
# File systems # File systems
...@@ -780,7 +811,6 @@ CONFIG_USB_DEVICEFS=y ...@@ -780,7 +811,6 @@ CONFIG_USB_DEVICEFS=y
# #
CONFIG_USB_EHCI_HCD=m CONFIG_USB_EHCI_HCD=m
CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD=y
CONFIG_USB_UHCI_HCD=m
# CONFIG_USB_UHCI_HCD_ALT is not set # CONFIG_USB_UHCI_HCD_ALT is not set
# #
......
...@@ -136,6 +136,16 @@ struct elf_prpsinfo32 ...@@ -136,6 +136,16 @@ struct elf_prpsinfo32
#define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) #define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
#define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) #define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
#include <linux/time.h>
#define jiffies_to_timeval jiffies_to_timeval32
static __inline__ void
jiffies_to_timeval32(unsigned long jiffies, struct timeval32 *value)
{
value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
value->tv_sec = jiffies / HZ;
}
#define elf_addr_t u32 #define elf_addr_t u32
#define elf_caddr_t u32 #define elf_caddr_t u32
#undef start_thread #undef start_thread
......
...@@ -1202,6 +1202,26 @@ struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask) ...@@ -1202,6 +1202,26 @@ struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask)
return rq; return rq;
} }
/*
* Non-locking blk_get_request variant, for special requests from drivers.
*/
struct request *__blk_get_request(request_queue_t *q, int rw)
{
struct request *rq;
BUG_ON(rw != READ && rw != WRITE);
rq = get_request(q, rw);
if (rq) {
rq->flags = 0;
rq->buffer = NULL;
rq->bio = rq->biotail = NULL;
rq->waiting = NULL;
}
return rq;
}
void blk_put_request(struct request *rq) void blk_put_request(struct request *rq)
{ {
blkdev_release_request(rq); blkdev_release_request(rq);
...@@ -1381,6 +1401,14 @@ void blk_attempt_remerge(request_queue_t *q, struct request *rq) ...@@ -1381,6 +1401,14 @@ void blk_attempt_remerge(request_queue_t *q, struct request *rq)
spin_unlock_irqrestore(q->queue_lock, flags); spin_unlock_irqrestore(q->queue_lock, flags);
} }
/*
* Non-locking blk_attempt_remerge variant.
*/
void __blk_attempt_remerge(request_queue_t *q, struct request *rq)
{
attempt_back_merge(q, rq);
}
static int __make_request(request_queue_t *q, struct bio *bio) static int __make_request(request_queue_t *q, struct bio *bio)
{ {
struct request *req, *freereq = NULL; struct request *req, *freereq = NULL;
...@@ -2039,6 +2067,7 @@ EXPORT_SYMBOL(generic_unplug_device); ...@@ -2039,6 +2067,7 @@ EXPORT_SYMBOL(generic_unplug_device);
EXPORT_SYMBOL(blk_plug_device); EXPORT_SYMBOL(blk_plug_device);
EXPORT_SYMBOL(blk_remove_plug); EXPORT_SYMBOL(blk_remove_plug);
EXPORT_SYMBOL(blk_attempt_remerge); EXPORT_SYMBOL(blk_attempt_remerge);
EXPORT_SYMBOL(__blk_attempt_remerge);
EXPORT_SYMBOL(blk_max_low_pfn); EXPORT_SYMBOL(blk_max_low_pfn);
EXPORT_SYMBOL(blk_max_pfn); EXPORT_SYMBOL(blk_max_pfn);
EXPORT_SYMBOL(blk_queue_max_sectors); EXPORT_SYMBOL(blk_queue_max_sectors);
...@@ -2055,6 +2084,7 @@ EXPORT_SYMBOL(blk_queue_assign_lock); ...@@ -2055,6 +2084,7 @@ EXPORT_SYMBOL(blk_queue_assign_lock);
EXPORT_SYMBOL(blk_phys_contig_segment); EXPORT_SYMBOL(blk_phys_contig_segment);
EXPORT_SYMBOL(blk_hw_contig_segment); EXPORT_SYMBOL(blk_hw_contig_segment);
EXPORT_SYMBOL(blk_get_request); EXPORT_SYMBOL(blk_get_request);
EXPORT_SYMBOL(__blk_get_request);
EXPORT_SYMBOL(blk_put_request); EXPORT_SYMBOL(blk_put_request);
EXPORT_SYMBOL(blk_queue_prep_rq); EXPORT_SYMBOL(blk_queue_prep_rq);
......
...@@ -176,7 +176,6 @@ static int hci_usb_rx_submit(struct hci_usb *husb, struct urb *urb) ...@@ -176,7 +176,6 @@ static int hci_usb_rx_submit(struct hci_usb *husb, struct urb *urb)
pipe = usb_rcvbulkpipe(husb->udev, husb->bulk_in_ep); pipe = usb_rcvbulkpipe(husb->udev, husb->bulk_in_ep);
FILL_BULK_URB(urb, husb->udev, pipe, skb->data, size, hci_usb_rx_complete, skb); FILL_BULK_URB(urb, husb->udev, pipe, skb->data, size, hci_usb_rx_complete, skb);
urb->transfer_flags = USB_QUEUE_BULK;
skb_queue_tail(&husb->pending_q, skb); skb_queue_tail(&husb->pending_q, skb);
err = usb_submit_urb(urb, GFP_ATOMIC); err = usb_submit_urb(urb, GFP_ATOMIC);
...@@ -318,7 +317,7 @@ static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb) ...@@ -318,7 +317,7 @@ static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len, FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
hci_usb_tx_complete, skb); hci_usb_tx_complete, skb);
urb->transfer_flags = USB_QUEUE_BULK | USB_ZERO_PACKET; urb->transfer_flags = USB_ZERO_PACKET;
BT_DBG("%s urb %p len %d", husb->hdev.name, urb, skb->len); BT_DBG("%s urb %p len %d", husb->hdev.name, urb, skb->len);
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
* device are used to bind the other minor numbers to block devices. * device are used to bind the other minor numbers to block devices.
*/ */
#include <linux/init.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/iobuf.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/raw.h> #include <linux/raw.h>
...@@ -86,12 +86,6 @@ int raw_open(struct inode *inode, struct file *filp) ...@@ -86,12 +86,6 @@ int raw_open(struct inode *inode, struct file *filp)
return 0; return 0;
} }
if (!filp->f_iobuf) {
err = alloc_kiovec(1, &filp->f_iobuf);
if (err)
return err;
}
down(&raw_devices[minor].mutex); down(&raw_devices[minor].mutex);
/* /*
* No, it is a normal raw device. All we need to do on open is * No, it is a normal raw device. All we need to do on open is
...@@ -256,124 +250,46 @@ int raw_ctl_ioctl(struct inode *inode, ...@@ -256,124 +250,46 @@ int raw_ctl_ioctl(struct inode *inode,
return err; return err;
} }
ssize_t raw_read(struct file *filp, char * buf, size_t size, loff_t *offp)
ssize_t raw_read(struct file *filp, char * buf,
size_t size, loff_t *offp)
{ {
return rw_raw_dev(READ, filp, buf, size, offp); return rw_raw_dev(READ, filp, buf, size, offp);
} }
ssize_t raw_write(struct file *filp, const char *buf, ssize_t raw_write(struct file *filp, const char *buf, size_t size, loff_t *offp)
size_t size, loff_t *offp)
{ {
return rw_raw_dev(WRITE, filp, (char *) buf, size, offp); return rw_raw_dev(WRITE, filp, (char *) buf, size, offp);
} }
#define SECTOR_BITS 9 ssize_t
#define SECTOR_SIZE (1U << SECTOR_BITS) rw_raw_dev(int rw, struct file *filp, char *buf, size_t size, loff_t *offp)
#define SECTOR_MASK (SECTOR_SIZE - 1)
ssize_t rw_raw_dev(int rw, struct file *filp, char *buf,
size_t size, loff_t *offp)
{ {
struct kiobuf * iobuf;
int new_iobuf;
int err = 0;
unsigned long blocks;
size_t transferred;
int iosize;
int minor;
kdev_t dev;
unsigned long limit;
int sector_size, sector_bits, sector_mask;
sector_t blocknr;
struct block_device *bdev; struct block_device *bdev;
struct inode *inode;
/* int minor;
* First, a few checks on device size limits ssize_t ret = 0;
*/
minor = minor(filp->f_dentry->d_inode->i_rdev); minor = minor(filp->f_dentry->d_inode->i_rdev);
new_iobuf = 0;
iobuf = filp->f_iobuf;
if (test_and_set_bit(0, &filp->f_iobuf_lock)) {
/*
* A parallel read/write is using the preallocated iobuf
* so just run slow and allocate a new one.
*/
err = alloc_kiovec(1, &iobuf);
if (err)
goto out;
new_iobuf = 1;
}
bdev = raw_devices[minor].binding; bdev = raw_devices[minor].binding;
dev = to_kdev_t(bdev->bd_dev); inode = bdev->bd_inode;
sector_size = raw_devices[minor].sector_size;
sector_bits = raw_devices[minor].sector_bits;
sector_mask = sector_size - 1;
limit = bdev->bd_inode->i_size >> sector_bits; if (size == 0)
if (!limit) goto out;
limit = INT_MAX; if (size < 0) {
dprintk ("rw_raw_dev: dev %d:%d (+%d)\n", ret = -EINVAL;
major(dev), minor(dev), limit); goto out;
err = -EINVAL;
if ((*offp & sector_mask) || (size & sector_mask))
goto out_free;
err = 0;
if (size)
err = -ENXIO;
if ((*offp >> sector_bits) >= limit)
goto out_free;
transferred = 0;
blocknr = *offp >> sector_bits;
while (size > 0) {
blocks = size >> sector_bits;
if (blocks > limit - blocknr)
blocks = limit - blocknr;
if (!blocks)
break;
iosize = blocks << sector_bits;
err = map_user_kiobuf(rw, iobuf, (unsigned long) buf, iosize);
if (err)
break;
err = brw_kiovec(rw, 1, &iobuf, raw_devices[minor].binding, &blocknr, sector_size);
if (rw == READ && err > 0)
mark_dirty_kiobuf(iobuf, err);
if (err >= 0) {
transferred += err;
size -= err;
buf += err;
}
blocknr += blocks;
unmap_kiobuf(iobuf);
if (err != iosize)
break;
} }
if (*offp >= inode->i_size) {
if (transferred) { ret = -ENXIO;
*offp += transferred; goto out;
err = transferred;
} }
if (size + *offp > inode->i_size)
out_free: size = inode->i_size - *offp;
if (!new_iobuf)
clear_bit(0, &filp->f_iobuf_lock); ret = generic_file_direct_IO(rw, inode, buf, *offp, size);
else if (ret > 0)
free_kiovec(1, &iobuf); *offp += ret;
out: if (inode->i_mapping->nrpages)
return err; invalidate_inode_pages2(inode->i_mapping);
out:
return ret;
} }
...@@ -994,7 +994,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) ...@@ -994,7 +994,7 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
*/ */
fc->rst_pkt->host->eh_action = &sem; fc->rst_pkt->host->eh_action = &sem;
fc->rst_pkt->request.rq_status = RQ_SCSI_BUSY; fc->rst_pkt->request->rq_status = RQ_SCSI_BUSY;
fc->rst_pkt->done = fcp_scsi_reset_done; fc->rst_pkt->done = fcp_scsi_reset_done;
fcp_scsi_queue_it(fc, fc->rst_pkt, fcmd, 0); fcp_scsi_queue_it(fc, fc->rst_pkt, fcmd, 0);
......
...@@ -160,16 +160,15 @@ static void aec62xx_tune_drive(struct ata_device *drive, unsigned char pio) ...@@ -160,16 +160,15 @@ static void aec62xx_tune_drive(struct ata_device *drive, unsigned char pio)
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
static int aec62xx_udma_setup(struct ata_device *drive) static int __init aec62xx_modes_map(struct ata_channel *ch)
{ {
u32 bmide = pci_resource_start(drive->channel->pci_dev, 4); u32 bmide = pci_resource_start(ch->pci_dev, 4);
short speed;
int map; int map;
map = XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA | XFER_SWDMA | XFER_UDMA; map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA | XFER_UDMA;
if (drive->channel->udma_four) if (ch->udma_four)
switch (drive->channel->pci_dev->device) { switch (ch->pci_dev->device) {
case PCI_DEVICE_ID_ARTOP_ATP865R: case PCI_DEVICE_ID_ARTOP_ATP865R:
case PCI_DEVICE_ID_ARTOP_ATP865: case PCI_DEVICE_ID_ARTOP_ATP865:
/* Can't use these modes simultaneously, /* Can't use these modes simultaneously,
...@@ -180,11 +179,7 @@ static int aec62xx_udma_setup(struct ata_device *drive) ...@@ -180,11 +179,7 @@ static int aec62xx_udma_setup(struct ata_device *drive)
map |= XFER_UDMA_66; map |= XFER_UDMA_66;
} }
speed = ata_timing_mode(drive, map); return map;
aec_set_drive(drive, speed);
udma_enable(drive, drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO, 0);
return 0;
} }
#endif #endif
...@@ -256,11 +251,12 @@ static void __init aec62xx_init_channel(struct ata_channel *ch) ...@@ -256,11 +251,12 @@ static void __init aec62xx_init_channel(struct ata_channel *ch)
ch->tuneproc = aec62xx_tune_drive; ch->tuneproc = aec62xx_tune_drive;
ch->speedproc = aec_set_drive; ch->speedproc = aec_set_drive;
ch->autodma = 0;
ch->io_32bit = 1; ch->io_32bit = 1;
ch->unmask = 1; ch->unmask = 1;
ch->udma_four = aec62xx_ata66_check(ch);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
ch->drives[i].autotune = 1; ch->drives[i].autotune = 1;
ch->drives[i].dn = ch->unit * 2 + i; ch->drives[i].dn = ch->unit * 2 + i;
...@@ -269,11 +265,8 @@ static void __init aec62xx_init_channel(struct ata_channel *ch) ...@@ -269,11 +265,8 @@ static void __init aec62xx_init_channel(struct ata_channel *ch)
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (ch->dma_base) { if (ch->dma_base) {
ch->highmem = 1; ch->highmem = 1;
ch->udma_setup = aec62xx_udma_setup; ch->modes_map = aec62xx_modes_map(ch);
#ifdef CONFIG_IDEDMA_AUTO ch->udma_setup = udma_generic_setup;
if (!noautodma)
ch->autodma = 1;
#endif
} }
#endif #endif
} }
...@@ -306,17 +299,15 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -306,17 +299,15 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_ARTOP, vendor: PCI_VENDOR_ID_ARTOP,
device: PCI_DEVICE_ID_ARTOP_ATP860, device: PCI_DEVICE_ID_ARTOP_ATP860,
init_chipset: aec62xx_init_chipset, init_chipset: aec62xx_init_chipset,
ata66_check: aec62xx_ata66_check,
init_channel: aec62xx_init_channel, init_channel: aec62xx_init_channel,
enablebits: { {0x4a,0x02,0x02}, {0x4a,0x04,0x04} }, enablebits: { {0x4a,0x02,0x02}, {0x4a,0x04,0x04} },
bootable: NEVER_BOARD, bootable: NEVER_BOARD,
flags: ATA_F_IRQ | ATA_F_NOADMA | ATA_F_DMA flags: ATA_F_IRQ | ATA_F_DMA
}, },
{ {
vendor: PCI_VENDOR_ID_ARTOP, vendor: PCI_VENDOR_ID_ARTOP,
device: PCI_DEVICE_ID_ARTOP_ATP860R, device: PCI_DEVICE_ID_ARTOP_ATP860R,
init_chipset: aec62xx_init_chipset, init_chipset: aec62xx_init_chipset,
ata66_check: aec62xx_ata66_check,
init_channel: aec62xx_init_channel, init_channel: aec62xx_init_channel,
enablebits: { {0x4a,0x02,0x02}, {0x4a,0x04,0x04} }, enablebits: { {0x4a,0x02,0x02}, {0x4a,0x04,0x04} },
bootable: OFF_BOARD, bootable: OFF_BOARD,
...@@ -326,7 +317,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -326,7 +317,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_ARTOP, vendor: PCI_VENDOR_ID_ARTOP,
device: PCI_DEVICE_ID_ARTOP_ATP865, device: PCI_DEVICE_ID_ARTOP_ATP865,
init_chipset: aec62xx_init_chipset, init_chipset: aec62xx_init_chipset,
ata66_check: aec62xx_ata66_check,
init_channel: aec62xx_init_channel, init_channel: aec62xx_init_channel,
enablebits: { {0x4a,0x02,0x02}, {0x4a,0x04,0x04} }, enablebits: { {0x4a,0x02,0x02}, {0x4a,0x04,0x04} },
bootable: NEVER_BOARD, bootable: NEVER_BOARD,
...@@ -336,7 +326,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -336,7 +326,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_ARTOP, vendor: PCI_VENDOR_ID_ARTOP,
device: PCI_DEVICE_ID_ARTOP_ATP865R, device: PCI_DEVICE_ID_ARTOP_ATP865R,
init_chipset: aec62xx_init_chipset, init_chipset: aec62xx_init_chipset,
ata66_check: aec62xx_ata66_check,
init_channel: aec62xx_init_channel, init_channel: aec62xx_init_channel,
enablebits: { {0x4a,0x02,0x02}, {0x4a,0x04,0x04} }, enablebits: { {0x4a,0x02,0x02}, {0x4a,0x04,0x04} },
bootable: OFF_BOARD, bootable: OFF_BOARD,
......
...@@ -99,43 +99,6 @@ static void ali15x3_tune_drive(struct ata_device *drive, byte pio) ...@@ -99,43 +99,6 @@ static void ali15x3_tune_drive(struct ata_device *drive, byte pio)
__restore_flags(flags); __restore_flags(flags);
} }
static byte ali15x3_can_ultra(struct ata_device *drive)
{
if (m5229_revision <= 0x20) {
return 0;
} else if ((m5229_revision < 0xC2) &&
#ifndef CONFIG_WDC_ALI15X3
((chip_is_1543c_e && strstr(drive->id->model, "WDC ")) ||
(drive->type != ATA_DISK))) {
#else
(drive->type != ATA_DISK)) {
#endif
return 0;
} else {
return 1;
}
}
static int ali15x3_ratemask(struct ata_device *drive)
{
int map = 0;
if (!ali15x3_can_ultra(drive))
return 0;
map |= XFER_UDMA;
if (!eighty_ninty_three(drive))
return map;
if (m5229_revision >= 0xC4)
map |= XFER_UDMA_100;
if (m5229_revision >= 0xC2)
map |= XFER_UDMA_66;
return map;
}
static int ali15x3_tune_chipset(struct ata_device *drive, byte speed) static int ali15x3_tune_chipset(struct ata_device *drive, byte speed)
{ {
struct pci_dev *dev = drive->channel->pci_dev; struct pci_dev *dev = drive->channel->pci_dev;
...@@ -156,6 +119,7 @@ static int ali15x3_tune_chipset(struct ata_device *drive, byte speed) ...@@ -156,6 +119,7 @@ static int ali15x3_tune_chipset(struct ata_device *drive, byte speed)
if (speed < XFER_SW_DMA_0) if (speed < XFER_SW_DMA_0)
ali15x3_tune_drive(drive, speed); ali15x3_tune_drive(drive, speed);
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
/* FIXME: no support for MWDMA and SWDMA modes --bkz */
else if (speed >= XFER_UDMA_0) { else if (speed >= XFER_UDMA_0) {
pci_read_config_byte(dev, m5229_udma, &tmpbyte); pci_read_config_byte(dev, m5229_udma, &tmpbyte);
tmpbyte &= (0x0f << ((1-unit) << 2)); tmpbyte &= (0x0f << ((1-unit) << 2));
...@@ -176,91 +140,40 @@ static int ali15x3_tune_chipset(struct ata_device *drive, byte speed) ...@@ -176,91 +140,40 @@ static int ali15x3_tune_chipset(struct ata_device *drive, byte speed)
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
static int config_chipset_for_dma(struct ata_device *drive, u8 udma) static int ali15x3_udma_setup(struct ata_device *drive, int map)
{ {
int map; #ifndef CONFIG_WDC_ALI15X3
u8 mode; if ((m5229_revision < 0xC2) && chip_is_1543c_e &&
strstr(drive->id->model, "WDC "))
if (udma) map &= ~XFER_UDMA_ALL;
map = ali15x3_ratemask(drive); #endif
else return udma_generic_setup(drive, map);
map = XFER_SWDMA | XFER_MWDMA;
mode = ata_timing_mode(drive, map);
if (mode < XFER_SW_DMA_0)
return 0;
return !ali15x3_tune_chipset(drive, mode);
} }
static int ali15x3_udma_setup(struct ata_device *drive) static int ali15x3_udma_init(struct ata_device *drive, struct request *rq)
{ {
struct hd_driveid *id = drive->id; if ((m5229_revision < 0xC2) && (drive->type != ATA_DISK))
struct ata_channel *hwif = drive->channel; return ATA_OP_FINISHED; /* try PIO instead of DMA */
int on = 1;
int verbose = 1;
byte can_ultra_dma = ali15x3_can_ultra(drive);
if ((m5229_revision<=0x20) && (drive->type != ATA_DISK)) { return udma_pci_init(drive, rq);
udma_enable(drive, 0, 0); }
return 0;
}
if ((id != NULL) && ((id->capability & 1) != 0) && hwif->autodma) { static int __init ali15x3_modes_map(struct ata_channel *ch)
/* Consult the list of known "bad" drives */ {
if (udma_black_list(drive)) { int map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA;
on = 0;
goto fast_ata_pio;
}
on = 0;
verbose = 0;
if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) {
if (id->dma_ultra & 0x003F) {
/* Force if Capable UltraDMA */
on = config_chipset_for_dma(drive, can_ultra_dma);
if ((id->field_valid & 2) &&
(!on))
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & 0x0007) ||
(id->dma_1word & 0x0007)) {
/* Force if Capable regular DMA modes */
on = config_chipset_for_dma(drive, can_ultra_dma);
if (!on)
goto no_dma_set;
}
} else if (udma_white_list(drive)) {
if (id->eide_dma_time > 150) {
goto no_dma_set;
}
/* Consult the list of known "good" drives */
on = config_chipset_for_dma(drive, can_ultra_dma);
if (!on)
goto no_dma_set;
} else {
goto fast_ata_pio;
}
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
on = 0;
verbose = 0;
no_dma_set:
ali15x3_tune_drive(drive, 255);
}
udma_enable(drive, on, verbose); if (m5229_revision <= 0x20)
return map;
return 0; map |= XFER_UDMA;
}
static int ali15x3_udma_init(struct ata_device *drive, struct request *rq) if (m5229_revision >= 0xC2) {
{ map |= XFER_UDMA_66;
if ((m5229_revision < 0xC2) && (drive->type != ATA_DISK)) if (m5229_revision >= 0xC4)
return ide_stopped; /* try PIO instead of DMA */ map |= XFER_UDMA_100;
}
return udma_pci_init(drive, rq); return map;
} }
#endif #endif
...@@ -426,6 +339,8 @@ static void __init ali15x3_init_channel(struct ata_channel *hwif) ...@@ -426,6 +339,8 @@ static void __init ali15x3_init_channel(struct ata_channel *hwif)
} }
#endif /* CONFIG_SPARC64 */ #endif /* CONFIG_SPARC64 */
hwif->udma_four = ali15x3_ata66_check(hwif);
hwif->tuneproc = &ali15x3_tune_drive; hwif->tuneproc = &ali15x3_tune_drive;
hwif->drives[0].autotune = 1; hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1; hwif->drives[1].autotune = 1;
...@@ -436,22 +351,21 @@ static void __init ali15x3_init_channel(struct ata_channel *hwif) ...@@ -436,22 +351,21 @@ static void __init ali15x3_init_channel(struct ata_channel *hwif)
/* /*
* M1543C or newer for DMAing * M1543C or newer for DMAing
*/ */
hwif->udma_init = ali15x3_udma_init; hwif->modes_map = ali15x3_modes_map(hwif);
if (m5229_revision < 0xC2)
hwif->no_atapi_autodma = 1;
hwif->udma_setup = ali15x3_udma_setup; hwif->udma_setup = ali15x3_udma_setup;
hwif->autodma = 1; hwif->udma_init = ali15x3_udma_init;
} }
if (noautodma)
hwif->autodma = 0;
#else
hwif->autodma = 0;
#endif #endif
} }
static void __init ali15x3_init_dma(struct ata_channel *ch, unsigned long dmabase) static void __init ali15x3_init_dma(struct ata_channel *ch, unsigned long dmabase)
{ {
if ((dmabase) && (m5229_revision < 0x20)) if (dmabase && (m5229_revision < 0x20)) {
ch->autodma = 0;
return; return;
}
ata_init_dma(ch, dmabase); ata_init_dma(ch, dmabase);
} }
...@@ -472,7 +386,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -472,7 +386,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_AL, vendor: PCI_VENDOR_ID_AL,
device: PCI_DEVICE_ID_AL_M5229, device: PCI_DEVICE_ID_AL_M5229,
init_chipset: ali15x3_init_chipset, init_chipset: ali15x3_init_chipset,
ata66_check: ali15x3_ata66_check,
init_channel: ali15x3_init_channel, init_channel: ali15x3_init_channel,
init_dma: ali15x3_init_dma, init_dma: ali15x3_init_dma,
enablebits: { {0x00,0x00,0x00}, {0x00,0x00,0x00} }, enablebits: { {0x00,0x00,0x00}, {0x00,0x00,0x00} },
......
...@@ -175,21 +175,15 @@ static void amd74xx_tune_drive(struct ata_device *drive, u8 pio) ...@@ -175,21 +175,15 @@ static void amd74xx_tune_drive(struct ata_device *drive, u8 pio)
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
static int amd74xx_udma_setup(struct ata_device *drive) static int __init amd_modes_map(struct ata_channel *ch)
{ {
short w80 = drive->channel->udma_four; short w80 = ch->udma_four;
int map = XFER_EPIO | XFER_MWDMA | XFER_UDMA |
short speed = ata_timing_mode(drive,
XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA |
((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) | ((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) |
(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) | (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) |
(w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0)); (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0);
amd_set_drive(drive, speed);
udma_enable(drive, drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO, 0);
return 0; return map;
} }
#endif #endif
...@@ -274,9 +268,10 @@ static void __init amd74xx_init_channel(struct ata_channel *hwif) ...@@ -274,9 +268,10 @@ static void __init amd74xx_init_channel(struct ata_channel *hwif)
{ {
int i; int i;
hwif->udma_four = amd74xx_ata66_check(hwif);
hwif->tuneproc = &amd74xx_tune_drive; hwif->tuneproc = &amd74xx_tune_drive;
hwif->speedproc = &amd_set_drive; hwif->speedproc = &amd_set_drive;
hwif->autodma = 0;
hwif->io_32bit = 1; hwif->io_32bit = 1;
hwif->unmask = 1; hwif->unmask = 1;
...@@ -289,11 +284,8 @@ static void __init amd74xx_init_channel(struct ata_channel *hwif) ...@@ -289,11 +284,8 @@ static void __init amd74xx_init_channel(struct ata_channel *hwif)
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) { if (hwif->dma_base) {
hwif->highmem = 1; hwif->highmem = 1;
hwif->udma_setup = amd74xx_udma_setup; hwif->modes_map = amd_modes_map(hwif);
# ifdef CONFIG_IDEDMA_AUTO hwif->udma_setup = udma_generic_setup;
if (!noautodma)
hwif->autodma = 1;
# endif
} }
#endif #endif
} }
...@@ -314,7 +306,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -314,7 +306,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_AMD, vendor: PCI_VENDOR_ID_AMD,
device: PCI_DEVICE_ID_AMD_COBRA_7401, device: PCI_DEVICE_ID_AMD_COBRA_7401,
init_chipset: amd74xx_init_chipset, init_chipset: amd74xx_init_chipset,
ata66_check: amd74xx_ata66_check,
init_channel: amd74xx_init_channel, init_channel: amd74xx_init_channel,
init_dma: amd74xx_init_dma, init_dma: amd74xx_init_dma,
enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
...@@ -324,7 +315,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -324,7 +315,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_AMD, vendor: PCI_VENDOR_ID_AMD,
device: PCI_DEVICE_ID_AMD_VIPER_7409, device: PCI_DEVICE_ID_AMD_VIPER_7409,
init_chipset: amd74xx_init_chipset, init_chipset: amd74xx_init_chipset,
ata66_check: amd74xx_ata66_check,
init_channel: amd74xx_init_channel, init_channel: amd74xx_init_channel,
init_dma: amd74xx_init_dma, init_dma: amd74xx_init_dma,
enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
...@@ -335,7 +325,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -335,7 +325,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_AMD, vendor: PCI_VENDOR_ID_AMD,
device: PCI_DEVICE_ID_AMD_VIPER_7411, device: PCI_DEVICE_ID_AMD_VIPER_7411,
init_chipset: amd74xx_init_chipset, init_chipset: amd74xx_init_chipset,
ata66_check: amd74xx_ata66_check,
init_channel: amd74xx_init_channel, init_channel: amd74xx_init_channel,
init_dma: amd74xx_init_dma, init_dma: amd74xx_init_dma,
enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
...@@ -345,7 +334,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -345,7 +334,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_AMD, vendor: PCI_VENDOR_ID_AMD,
device: PCI_DEVICE_ID_AMD_OPUS_7441, device: PCI_DEVICE_ID_AMD_OPUS_7441,
init_chipset: amd74xx_init_chipset, init_chipset: amd74xx_init_chipset,
ata66_check: amd74xx_ata66_check,
init_channel: amd74xx_init_channel, init_channel: amd74xx_init_channel,
init_dma: amd74xx_init_dma, init_dma: amd74xx_init_dma,
enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
...@@ -355,7 +343,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -355,7 +343,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_AMD, vendor: PCI_VENDOR_ID_AMD,
device: PCI_DEVICE_ID_AMD_8111_IDE, device: PCI_DEVICE_ID_AMD_8111_IDE,
init_chipset: amd74xx_init_chipset, init_chipset: amd74xx_init_chipset,
ata66_check: amd74xx_ata66_check,
init_channel: amd74xx_init_channel, init_channel: amd74xx_init_channel,
init_dma: amd74xx_init_dma, init_dma: amd74xx_init_dma,
enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, enablebits: {{0x40,0x01,0x01}, {0x40,0x02,0x02}},
...@@ -365,7 +352,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -365,7 +352,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_NVIDIA, vendor: PCI_VENDOR_ID_NVIDIA,
device: PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, device: PCI_DEVICE_ID_NVIDIA_NFORCE_IDE,
init_chipset: amd74xx_init_chipset, init_chipset: amd74xx_init_chipset,
ata66_check: amd74xx_ata66_check,
init_channel: amd74xx_init_channel, init_channel: amd74xx_init_channel,
init_dma: amd74xx_init_dma, init_dma: amd74xx_init_dma,
enablebits: {{0x50,0x01,0x01}, {0x50,0x02,0x02}}, enablebits: {{0x50,0x01,0x01}, {0x50,0x02,0x02}},
......
...@@ -86,9 +86,11 @@ short ata_timing_mode(struct ata_device *drive, int map) ...@@ -86,9 +86,11 @@ short ata_timing_mode(struct ata_device *drive, int map)
if ((map & XFER_UDMA_100) == XFER_UDMA_100) if ((map & XFER_UDMA_100) == XFER_UDMA_100)
if ((best = (id->dma_ultra & 0x0020) ? XFER_UDMA_5 : 0)) return best; if ((best = (id->dma_ultra & 0x0020) ? XFER_UDMA_5 : 0)) return best;
if ((map & XFER_UDMA_66) == XFER_UDMA_66) if ((map & XFER_UDMA_66_4) == XFER_UDMA_66_4)
if ((best = (id->dma_ultra & 0x0010) ? XFER_UDMA_4 : if ((best = (id->dma_ultra & 0x0010) ? XFER_UDMA_4 : 0)) return best;
(id->dma_ultra & 0x0008) ? XFER_UDMA_3 : 0)) return best;
if ((map & XFER_UDMA_66_3) == XFER_UDMA_66_3)
if ((best = (id->dma_ultra & 0x0008) ? XFER_UDMA_3 : 0)) return best;
if ((best = (id->dma_ultra & 0x0004) ? XFER_UDMA_2 : if ((best = (id->dma_ultra & 0x0004) ? XFER_UDMA_2 :
(id->dma_ultra & 0x0002) ? XFER_UDMA_1 : (id->dma_ultra & 0x0002) ? XFER_UDMA_1 :
......
...@@ -59,15 +59,22 @@ extern struct ata_timing ata_timing[]; ...@@ -59,15 +59,22 @@ extern struct ata_timing ata_timing[];
#define ENOUGH(v,unit) (((v)-1)/(unit)+1) #define ENOUGH(v,unit) (((v)-1)/(unit)+1)
#define EZ(v,unit) ((v)?ENOUGH(v,unit):0) #define EZ(v,unit) ((v)?ENOUGH(v,unit):0)
#define XFER_MODE 0xf0 /* see hpt366.c for details */
#define XFER_UDMA_133 0x48 #define XFER_UDMA_66_3 0x100
#define XFER_UDMA_100 0x44 #define XFER_UDMA_66_4 0x200
#define XFER_UDMA_66 0x42
#define XFER_UDMA 0x40 #define XFER_MODE 0xff0
#define XFER_MWDMA 0x20 #define XFER_UDMA_133 0x800
#define XFER_SWDMA 0x10 #define XFER_UDMA_100 0x400
#define XFER_EPIO 0x01 #define XFER_UDMA_66 0x300
#define XFER_PIO 0x00 #define XFER_UDMA 0x040
#define XFER_MWDMA 0x020
#define XFER_SWDMA 0x010
#define XFER_EPIO 0x001
#define XFER_PIO 0x000
#define XFER_UDMA_ALL 0xf40
#define XFER_UDMA_80W 0xf00
/* External interface to host chips channel timing setup. /* External interface to host chips channel timing setup.
* *
......
...@@ -217,10 +217,10 @@ static void cmd64x_tuneproc(struct ata_device *drive, u8 pio) ...@@ -217,10 +217,10 @@ static void cmd64x_tuneproc(struct ata_device *drive, u8 pio)
ide_config_drive_speed(drive, speed); ide_config_drive_speed(drive, speed);
} }
static int cmd64x_ratemask(struct ata_device *drive) static int __init cmd6xx_modes_map(struct ata_channel *ch)
{ {
struct pci_dev *dev = drive->channel->pci_dev; struct pci_dev *dev = ch->pci_dev;
int map = 0; int map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA;
switch(dev->device) { switch(dev->device) {
case PCI_DEVICE_ID_CMD_680: case PCI_DEVICE_ID_CMD_680:
...@@ -234,10 +234,9 @@ static int cmd64x_ratemask(struct ata_device *drive) ...@@ -234,10 +234,9 @@ static int cmd64x_ratemask(struct ata_device *drive)
break; break;
case PCI_DEVICE_ID_CMD_646: case PCI_DEVICE_ID_CMD_646:
{ {
u32 class_rev; u32 rev;
pci_read_config_dword(dev, pci_read_config_dword(dev, PCI_CLASS_REVISION, &rev);
PCI_CLASS_REVISION, &class_rev); rev &= 0xff;
class_rev &= 0xff;
/* /*
* UltraDMA only supported on PCI646U and PCI646U2, which * UltraDMA only supported on PCI646U and PCI646U2, which
* correspond to revisions 0x03, 0x05 and 0x07 respectively. * correspond to revisions 0x03, 0x05 and 0x07 respectively.
...@@ -250,7 +249,7 @@ static int cmd64x_ratemask(struct ata_device *drive) ...@@ -250,7 +249,7 @@ static int cmd64x_ratemask(struct ata_device *drive)
* *
* So we only do UltraDMA on revision 0x05 and 0x07 chipsets. * So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
*/ */
switch(class_rev) { switch(rev) {
case 0x07: case 0x07:
case 0x05: case 0x05:
map |= XFER_UDMA; map |= XFER_UDMA;
...@@ -260,11 +259,6 @@ static int cmd64x_ratemask(struct ata_device *drive) ...@@ -260,11 +259,6 @@ static int cmd64x_ratemask(struct ata_device *drive)
} }
} }
if (!eighty_ninty_three(drive)) {
if (map & XFER_UDMA)
return XFER_UDMA;
return 0;
}
return map; return map;
} }
...@@ -515,80 +509,6 @@ speed_break : ...@@ -515,80 +509,6 @@ speed_break :
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
static int config_chipset_for_dma(struct ata_device *drive, u8 udma)
{
int map;
u8 mode;
if (udma)
map = cmd64x_ratemask(drive);
else
map = XFER_SWDMA | XFER_MWDMA;
mode = ata_timing_mode(drive, map);
return !drive->channel->speedproc(drive, mode);
}
static int cmd6xx_udma_setup(struct ata_device *drive)
{
struct hd_driveid *id = drive->id;
struct ata_channel *hwif = drive->channel;
int on = 1;
int verbose = 1;
hwif->tuneproc(drive, 255);
if ((id != NULL) && ((id->capability & 1) != 0) &&
hwif->autodma && (drive->type == ATA_DISK)) {
/* Consult the list of known "bad" drives */
if (udma_black_list(drive)) {
on = 0;
goto fast_ata_pio;
}
on = 0;
verbose = 0;
if ((id->field_valid & 4)) {
if (id->dma_ultra & 0x007F) {
/* Force if Capable UltraDMA */
on = config_chipset_for_dma(drive, 1);
if ((id->field_valid & 2) &&
(!on))
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & 0x0007) ||
(id->dma_1word & 0x0007)) {
/* Force if Capable regular DMA modes */
on = config_chipset_for_dma(drive, 0);
if (!on)
goto no_dma_set;
}
} else if (udma_white_list(drive)) {
if (id->eide_dma_time > 150) {
goto no_dma_set;
}
/* Consult the list of known "good" drives */
on = config_chipset_for_dma(drive, 0);
if (!on)
goto no_dma_set;
} else {
goto fast_ata_pio;
}
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
on = 0;
verbose = 0;
no_dma_set:
hwif->tuneproc(drive, 255);
}
udma_enable(drive, on, verbose);
return 0;
}
static int cmd64x_udma_stop(struct ata_device *drive) static int cmd64x_udma_stop(struct ata_device *drive)
{ {
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
...@@ -822,13 +742,6 @@ static unsigned int cmd64x_ata66(struct ata_channel *hwif) ...@@ -822,13 +742,6 @@ static unsigned int cmd64x_ata66(struct ata_channel *hwif)
return (ata66 & mask) ? 1 : 0; return (ata66 & mask) ? 1 : 0;
} }
static unsigned int __init cmd64x_ata66_check(struct ata_channel *hwif)
{
if (hwif->pci_dev->device == PCI_DEVICE_ID_CMD_680)
return cmd680_ata66(hwif);
return cmd64x_ata66(hwif);
}
static void __init cmd64x_init_channel(struct ata_channel *hwif) static void __init cmd64x_init_channel(struct ata_channel *hwif)
{ {
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
...@@ -843,32 +756,28 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif) ...@@ -843,32 +756,28 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif)
switch(dev->device) { switch(dev->device) {
case PCI_DEVICE_ID_CMD_680: case PCI_DEVICE_ID_CMD_680:
hwif->busproc = cmd680_busproc; hwif->busproc = cmd680_busproc;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base)
hwif->udma_setup = cmd6xx_udma_setup;
#endif
hwif->resetproc = cmd680_reset; hwif->resetproc = cmd680_reset;
hwif->speedproc = cmd680_tune_chipset; hwif->speedproc = cmd680_tune_chipset;
hwif->tuneproc = cmd680_tuneproc; hwif->tuneproc = cmd680_tuneproc;
hwif->udma_four = cmd680_ata66(hwif);
break; break;
case PCI_DEVICE_ID_CMD_649: case PCI_DEVICE_ID_CMD_649:
case PCI_DEVICE_ID_CMD_648: case PCI_DEVICE_ID_CMD_648:
case PCI_DEVICE_ID_CMD_643: case PCI_DEVICE_ID_CMD_643:
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) { if (hwif->dma_base) {
hwif->udma_setup = cmd6xx_udma_setup;
hwif->udma_stop = cmd64x_udma_stop; hwif->udma_stop = cmd64x_udma_stop;
hwif->udma_irq_status = cmd64x_udma_irq_status; hwif->udma_irq_status = cmd64x_udma_irq_status;
} }
#endif #endif
hwif->tuneproc = cmd64x_tuneproc; hwif->tuneproc = cmd64x_tuneproc;
hwif->speedproc = cmd64x_tune_chipset; hwif->speedproc = cmd64x_tune_chipset;
hwif->udma_four = cmd64x_ata66(hwif);
break; break;
case PCI_DEVICE_ID_CMD_646: case PCI_DEVICE_ID_CMD_646:
hwif->chipset = ide_cmd646; hwif->chipset = ide_cmd646;
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) { if (hwif->dma_base) {
hwif->udma_setup = cmd6xx_udma_setup;
if (class_rev == 0x01) { if (class_rev == 0x01) {
hwif->udma_stop = cmd646_1_udma_stop; hwif->udma_stop = cmd646_1_udma_stop;
} else { } else {
...@@ -879,6 +788,7 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif) ...@@ -879,6 +788,7 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif)
#endif #endif
hwif->tuneproc = cmd64x_tuneproc; hwif->tuneproc = cmd64x_tuneproc;
hwif->speedproc = cmd64x_tune_chipset; hwif->speedproc = cmd64x_tune_chipset;
hwif->udma_four = cmd64x_ata66(hwif);
break; break;
default: default:
break; break;
...@@ -887,10 +797,9 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif) ...@@ -887,10 +797,9 @@ static void __init cmd64x_init_channel(struct ata_channel *hwif)
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) { if (hwif->dma_base) {
hwif->highmem = 1; hwif->highmem = 1;
# ifdef CONFIG_IDEDMA_AUTO hwif->modes_map = cmd6xx_modes_map(hwif);
if (!noautodma) hwif->no_atapi_autodma = 1;
hwif->autodma = 1; hwif->udma_setup = udma_generic_setup;
# endif
} }
#endif #endif
} }
...@@ -919,7 +828,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -919,7 +828,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_CMD, vendor: PCI_VENDOR_ID_CMD,
device: PCI_DEVICE_ID_CMD_648, device: PCI_DEVICE_ID_CMD_648,
init_chipset: cmd64x_init_chipset, init_chipset: cmd64x_init_chipset,
ata66_check: cmd64x_ata66_check,
init_channel: cmd64x_init_channel, init_channel: cmd64x_init_channel,
bootable: ON_BOARD, bootable: ON_BOARD,
flags: ATA_F_DMA flags: ATA_F_DMA
...@@ -928,7 +836,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -928,7 +836,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_CMD, vendor: PCI_VENDOR_ID_CMD,
device: PCI_DEVICE_ID_CMD_649, device: PCI_DEVICE_ID_CMD_649,
init_chipset: cmd64x_init_chipset, init_chipset: cmd64x_init_chipset,
ata66_check: cmd64x_ata66_check,
init_channel: cmd64x_init_channel, init_channel: cmd64x_init_channel,
bootable: ON_BOARD, bootable: ON_BOARD,
flags: ATA_F_DMA flags: ATA_F_DMA
...@@ -937,7 +844,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -937,7 +844,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_CMD, vendor: PCI_VENDOR_ID_CMD,
device: PCI_DEVICE_ID_CMD_680, device: PCI_DEVICE_ID_CMD_680,
init_chipset: cmd64x_init_chipset, init_chipset: cmd64x_init_chipset,
ata66_check: cmd64x_ata66_check,
init_channel: cmd64x_init_channel, init_channel: cmd64x_init_channel,
bootable: ON_BOARD, bootable: ON_BOARD,
flags: ATA_F_DMA flags: ATA_F_DMA
......
...@@ -191,7 +191,7 @@ static int cs5530_config_dma(struct ata_device *drive) ...@@ -191,7 +191,7 @@ static int cs5530_config_dma(struct ata_device *drive)
return 0; return 0;
} }
static int cs5530_udma_setup(struct ata_device *drive) static int cs5530_udma_setup(struct ata_device *drive, int map)
{ {
return cs5530_config_dma(drive); return cs5530_config_dma(drive);
} }
...@@ -285,17 +285,15 @@ static unsigned int __init pci_init_cs5530(struct pci_dev *dev) ...@@ -285,17 +285,15 @@ static unsigned int __init pci_init_cs5530(struct pci_dev *dev)
*/ */
static void __init ide_init_cs5530(struct ata_channel *hwif) static void __init ide_init_cs5530(struct ata_channel *hwif)
{ {
u32 basereg, d0_timings;
hwif->serialized = 1; hwif->serialized = 1;
if (!hwif->dma_base) {
hwif->autodma = 0;
} else {
unsigned int basereg, d0_timings;
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
hwif->udma_setup = cs5530_udma_setup; if (hwif->dma_base) {
hwif->highmem = 1; hwif->highmem = 1;
#else hwif->udma_setup = cs5530_udma_setup;
hwif->autodma = 0; }
#endif #endif
hwif->tuneproc = &cs5530_tuneproc; hwif->tuneproc = &cs5530_tuneproc;
...@@ -311,7 +309,6 @@ static void __init ide_init_cs5530(struct ata_channel *hwif) ...@@ -311,7 +309,6 @@ static void __init ide_init_cs5530(struct ata_channel *hwif)
if (!hwif->drives[1].autotune) if (!hwif->drives[1].autotune)
hwif->drives[1].autotune = 1; /* needs autotuning later */ hwif->drives[1].autotune = 1; /* needs autotuning later */
} }
}
} }
......
...@@ -237,7 +237,7 @@ static void cy82c693_dma_enable(struct ata_device *drive, int mode, int single) ...@@ -237,7 +237,7 @@ static void cy82c693_dma_enable(struct ata_device *drive, int mode, int single)
/* /*
* used to set DMA mode for CY82C693 (single and multi modes) * used to set DMA mode for CY82C693 (single and multi modes)
*/ */
static int cy82c693_udma_setup(struct ata_device *drive) static int cy82c693_udma_setup(struct ata_device *drive, int map)
{ {
/* /*
* Set dma mode for drive everything else is done by the defaul func. * Set dma mode for drive everything else is done by the defaul func.
...@@ -414,14 +414,11 @@ static void __init ide_init_cy82c693(struct ata_channel *hwif) ...@@ -414,14 +414,11 @@ static void __init ide_init_cy82c693(struct ata_channel *hwif)
hwif->tuneproc = cy82c693_tune_drive; hwif->tuneproc = cy82c693_tune_drive;
hwif->drives[0].autotune = 1; hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1; hwif->drives[1].autotune = 1;
hwif->autodma = 0;
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) { if (hwif->dma_base) {
hwif->highmem = 1; hwif->highmem = 1;
hwif->udma_setup = cy82c693_udma_setup; hwif->udma_setup = cy82c693_udma_setup;
if (!noautodma)
hwif->autodma = 1;
} }
#endif #endif
} }
......
...@@ -79,30 +79,8 @@ void ata_mask(struct ata_device *drive) ...@@ -79,30 +79,8 @@ void ata_mask(struct ata_device *drive)
ch->maskproc(drive); ch->maskproc(drive);
} }
/*
* Spin until the drive is no longer busy.
*
* Not exported, since it's not used within any modules.
*/
int ata_busy_poll(struct ata_device *drive, unsigned long timeout)
{
/* spec allows drive 400ns to assert "BUSY" */
udelay(1);
if (!ata_status(drive, 0, BUSY_STAT)) {
timeout += jiffies;
while (!ata_status(drive, 0, BUSY_STAT)) {
if (time_after(jiffies, timeout))
return 1;
}
}
return 0;
}
/* /*
* Check the state of the status register. * Check the state of the status register.
*
* FIXME: Channel lock should be held.
*/ */
int ata_status(struct ata_device *drive, u8 good, u8 bad) int ata_status(struct ata_device *drive, u8 good, u8 bad)
{ {
...@@ -120,31 +98,33 @@ EXPORT_SYMBOL(ata_status); ...@@ -120,31 +98,33 @@ EXPORT_SYMBOL(ata_status);
* all of the "good" bits and none of the "bad" bits, and if all is okay it * all of the "good" bits and none of the "bad" bits, and if all is okay it
* returns 0. All other cases return 1 after invoking error handler -- caller * returns 0. All other cases return 1 after invoking error handler -- caller
* should just return. * should just return.
*
* This routine should get fixed to not hog the cpu during extra long waits..
* That could be done by busy-waiting for the first jiffy or two, and then
* setting a timer to wake up at half second intervals thereafter, until
* timeout is achieved, before timing out.
*
* Channel lock should be held.
*/ */
int ata_status_poll(struct ata_device *drive, u8 good, u8 bad, int ata_status_poll(struct ata_device *drive, u8 good, u8 bad,
unsigned long timeout, unsigned long timeout, struct request *rq)
struct request *rq, ide_startstop_t *startstop)
{ {
int i; int i;
/* bail early if we've exceeded max_failures */ /* bail early if we've exceeded max_failures */
if (drive->max_failures && (drive->failures > drive->max_failures)) { if (drive->max_failures && (drive->failures > drive->max_failures))
*startstop = ide_stopped; return ATA_OP_FINISHED;
/*
* Spin until the drive is no longer busy.
* Spec allows drive 400ns to assert "BUSY"
*/
udelay(1);
if (!ata_status(drive, 0, BUSY_STAT)) {
unsigned long flags;
return 1; __save_flags(flags);
ide__sti();
timeout += jiffies;
while (!ata_status(drive, 0, BUSY_STAT)) {
if (time_after(jiffies, timeout)) {
__restore_flags(flags);
return ata_error(drive, rq, "status timeout");
} }
}
if (ata_busy_poll(drive, timeout)) { __restore_flags(flags);
*startstop = ata_error(drive, rq, "status timeout");
return 1;
} }
/* /*
...@@ -156,12 +136,10 @@ int ata_status_poll(struct ata_device *drive, u8 good, u8 bad, ...@@ -156,12 +136,10 @@ int ata_status_poll(struct ata_device *drive, u8 good, u8 bad,
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
udelay(1); udelay(1);
if (ata_status(drive, good, bad)) if (ata_status(drive, good, bad))
return 0; return ATA_OP_READY;
} }
*startstop = ata_error(drive, rq, "status error"); return ata_error(drive, rq, "status error");
return 1;
} }
EXPORT_SYMBOL(ata_status_poll); EXPORT_SYMBOL(ata_status_poll);
......
...@@ -72,83 +72,13 @@ static void hpt34x_tune_drive(struct ata_device *drive, u8 pio) ...@@ -72,83 +72,13 @@ static void hpt34x_tune_drive(struct ata_device *drive, u8 pio)
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
static int config_chipset_for_dma(struct ata_device *drive, u8 udma) static int hpt34x_udma_setup(struct ata_device *drive, int map)
{ {
int map; #ifdef CONFIG_HPT34X_AUTODMA
u8 mode; return udma_generic_setup(drive, map);
#else
if (drive->type != ATA_DISK)
return 0;
if (udma)
map = XFER_UDMA;
else
map = XFER_SWDMA | XFER_MWDMA;
mode = ata_timing_mode(drive, map);
if (mode < XFER_SW_DMA_0)
return 0; return 0;
return !hpt34x_tune_chipset(drive, mode);
}
static int hpt34x_udma_setup(struct ata_device *drive)
{
struct hd_driveid *id = drive->id;
int on = 1;
int verbose = 1;
if (id && (id->capability & 1) && drive->channel->autodma) {
/* Consult the list of known "bad" drives */
if (udma_black_list(drive)) {
on = 0;
goto fast_ata_pio;
}
on = 0;
verbose = 0;
if (id->field_valid & 4) {
if (id->dma_ultra & 0x0007) {
/* Force if Capable UltraDMA */
on = config_chipset_for_dma(drive, 1);
if ((id->field_valid & 2) &&
(!on))
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & 0x0007) ||
(id->dma_1word & 0x0007)) {
/* Force if Capable regular DMA modes */
on = config_chipset_for_dma(drive, 0);
if (!on)
goto no_dma_set;
}
} else if (udma_white_list(drive)) {
if (id->eide_dma_time > 150) {
goto no_dma_set;
}
/* Consult the list of known "good" drives */
on = config_chipset_for_dma(drive, 0);
if (!on)
goto no_dma_set;
} else {
goto fast_ata_pio;
}
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
on = 0;
verbose = 0;
no_dma_set:
hpt34x_tune_chipset(drive, ata_best_pio_mode(drive));
}
#ifndef CONFIG_HPT34X_AUTODMA
if (on)
on = 0;
#endif #endif
udma_enable(drive, on, verbose);
return 0;
} }
static int hpt34x_udma_stop(struct ata_device *drive) static int hpt34x_udma_stop(struct ata_device *drive)
...@@ -173,7 +103,7 @@ static int hpt34x_udma_init(struct ata_device *drive, struct request *rq) ...@@ -173,7 +103,7 @@ static int hpt34x_udma_init(struct ata_device *drive, struct request *rq)
u8 cmd; u8 cmd;
if (!(count = udma_new_table(drive, rq))) if (!(count = udma_new_table(drive, rq)))
return ide_stopped; /* try PIO instead of DMA */ return ATA_OP_FINISHED; /* try PIO instead of DMA */
if (rq_data_dir(rq) == READ) if (rq_data_dir(rq) == READ)
cmd = 0x09; cmd = 0x09;
...@@ -189,7 +119,7 @@ static int hpt34x_udma_init(struct ata_device *drive, struct request *rq) ...@@ -189,7 +119,7 @@ static int hpt34x_udma_init(struct ata_device *drive, struct request *rq)
OUT_BYTE((cmd == 0x09) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); OUT_BYTE((cmd == 0x09) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
} }
return ide_started; return ATA_OP_CONTINUES;
} }
#endif #endif
...@@ -252,24 +182,21 @@ static void __init ide_init_hpt34x(struct ata_channel *hwif) ...@@ -252,24 +182,21 @@ static void __init ide_init_hpt34x(struct ata_channel *hwif)
unsigned short pcicmd = 0; unsigned short pcicmd = 0;
pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd); pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd);
if (!noautodma) #ifdef CONFIG_IDEDMA_AUTO
hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0; hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0;
else #endif
hwif->autodma = 0;
hwif->udma_stop = hpt34x_udma_stop; hwif->udma_stop = hpt34x_udma_stop;
hwif->udma_init = hpt34x_udma_init; hwif->udma_init = hpt34x_udma_init;
hwif->modes_map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA | XFER_UDMA;
hwif->no_atapi_autodma = 1;
hwif->udma_setup = hpt34x_udma_setup; hwif->udma_setup = hpt34x_udma_setup;
hwif->highmem = 1; hwif->highmem = 1;
} else { } else
#endif
{
hwif->drives[0].autotune = 1; hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1; hwif->drives[1].autotune = 1;
} }
#else
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
hwif->autodma = 0;
#endif
} }
...@@ -281,7 +208,7 @@ static struct ata_pci_device chipset __initdata = { ...@@ -281,7 +208,7 @@ static struct ata_pci_device chipset __initdata = {
init_channel: ide_init_hpt34x, init_channel: ide_init_hpt34x,
bootable: NEVER_BOARD, bootable: NEVER_BOARD,
extra: 16, extra: 16,
flags: ATA_F_NOADMA | ATA_F_DMA flags: ATA_F_DMA
}; };
int __init init_hpt34x(void) int __init init_hpt34x(void)
......
...@@ -493,37 +493,23 @@ static unsigned int hpt_revision(struct pci_dev *dev) ...@@ -493,37 +493,23 @@ static unsigned int hpt_revision(struct pci_dev *dev)
return class_rev; return class_rev;
} }
static int hpt3xx_ratemask(struct ata_device *drive) static int __init hpt3xx_modes_map(struct ata_channel *ch)
{ {
u32 rev = hpt_revision(drive->channel->pci_dev); u32 rev = hpt_revision(ch->pci_dev);
int map = XFER_UDMA; int map = XFER_EPIO | XFER_MWDMA | XFER_UDMA | XFER_UDMA_66;
if (rev >= 8) { /* HPT374 */ if (rev >= 8) { /* HPT374 */
if (HPT374_ALLOW_ATA133_6) if (HPT374_ALLOW_ATA133_6)
map |= XFER_UDMA_133; map |= XFER_UDMA_133;
map |= (XFER_UDMA_100 | XFER_UDMA_66); map |= XFER_UDMA_100;
} else if (rev >= 5) { /* HPT372 */ } else if (rev >= 5) { /* HPT372 */
if (HPT372_ALLOW_ATA133_6) if (HPT372_ALLOW_ATA133_6)
map |= XFER_UDMA_133; map |= XFER_UDMA_133;
map |= (XFER_UDMA_100 | XFER_UDMA_66);
} else if (rev >= 4) { /* HPT370A */
if (HPT370_ALLOW_ATA100_5)
map |= XFER_UDMA_100; map |= XFER_UDMA_100;
map |= XFER_UDMA_66; } else if (rev >= 3) { /* HPT370A / HPT370 */
} else if (rev >= 3) { /* HPT370 */
if (HPT370_ALLOW_ATA100_5) if (HPT370_ALLOW_ATA100_5)
map |= XFER_UDMA_100; map |= XFER_UDMA_100;
map |= XFER_UDMA_66; } /* HPT366 / HPT368 */
if (check_in_drive_lists(drive, bad_ata33))
return 0;
} else { /* HPT366 and HPT368 */
map |= XFER_UDMA_66;
if (check_in_drive_lists(drive, bad_ata33))
return 0;
}
if (!eighty_ninty_three(drive))
return XFER_UDMA;
return map; return map;
} }
...@@ -662,62 +648,42 @@ static int hpt3xx_tune_chipset(struct ata_device *drive, u8 speed) ...@@ -662,62 +648,42 @@ static int hpt3xx_tune_chipset(struct ata_device *drive, u8 speed)
return ide_config_drive_speed(drive, speed); return ide_config_drive_speed(drive, speed);
} }
/* FIXME: pio == 255 -> ata_best_pio_mode(drive) --bkz */
static void hpt3xx_tune_drive(struct ata_device *drive, u8 pio) static void hpt3xx_tune_drive(struct ata_device *drive, u8 pio)
{ {
(void) hpt3xx_tune_chipset(drive, XFER_PIO_0 + min_t(u8, pio, 4)); (void) hpt3xx_tune_chipset(drive, XFER_PIO_0 + min_t(u8, pio, 4));
} }
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
static int config_chipset_for_dma(struct ata_device *drive) static int hpt3xx_udma_setup(struct ata_device *drive, int map)
{ {
int map;
u32 rev; u32 rev;
u8 mode;
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return 0; return 0;
rev = hpt_revision(drive->channel->pci_dev); rev = hpt_revision(drive->channel->pci_dev);
/* FIXME: check SWDMA modes --bkz */ /* FIXME: badlists need futher investigation --bkz */
map = hpt3xx_ratemask(drive) | XFER_MWDMA;
mode = ata_timing_mode(drive, map);
/* FIXME: badlists need futher investigation --bkz /* bad_ata100_5 is for HPT370/370A,
bad_ata100_5 is for HPT370/370A, bad_ata66_4, bad_ata66_3 and bad_ata33 are for HPT366/368 */
bad_ata66_4, bad_ata66_3 and bad_ata33 are for HPT366/368
*/ if (rev < 5 && check_in_drive_lists(drive, bad_ata100_5))
if (mode == XFER_UDMA_5 && rev < 5) {
if (check_in_drive_lists(drive, bad_ata100_5)) {
/* FIXME: make XFER_UDMA_66/100/133
independent of XFER_UDMA --bkz */
map &= ~XFER_UDMA_100; map &= ~XFER_UDMA_100;
map |= XFER_UDMA;
mode = ata_timing_mode(drive, map); if (rev < 3) {
} if (check_in_drive_lists(drive, bad_ata66_4))
} map &= ~XFER_UDMA_66_4;
if (mode == XFER_UDMA_4 && rev < 3) {
if (check_in_drive_lists(drive, bad_ata66_4)) { if (check_in_drive_lists(drive, bad_ata66_3))
if (drive->id->dma_ultra & 0x0008) { map &= ~XFER_UDMA_66_3;
mode = XFER_UDMA_3;
} else { if (check_in_drive_lists(drive, bad_ata33))
map &= ~XFER_UDMA_66; map &= ~XFER_UDMA_ALL;
map |= XFER_UDMA;
mode = ata_timing_mode(drive, map);
}
}
}
if (mode == XFER_UDMA_3 && rev < 3) {
if (check_in_drive_lists(drive, bad_ata66_3)) {
map &= ~XFER_UDMA_66;
map |= XFER_UDMA;
mode = ata_timing_mode(drive, map);
}
} }
if (check_in_drive_lists(drive, bad_ata33) && rev < 3)
mode = ata_timing_mode(drive, XFER_MWDMA);
return !hpt3xx_tune_chipset(drive, mode); return udma_generic_setup(drive, map);
} }
static int hpt3xx_quirkproc(struct ata_device *drive) static int hpt3xx_quirkproc(struct ata_device *drive)
...@@ -754,59 +720,6 @@ static void hpt3xx_maskproc(struct ata_device *drive) ...@@ -754,59 +720,6 @@ static void hpt3xx_maskproc(struct ata_device *drive)
} }
} }
static int hpt3xx_udma_setup(struct ata_device *drive)
{
struct hd_driveid *id = drive->id;
int on = 1;
int verbose = 1;
if (id && (id->capability & 1) && drive->channel->autodma) {
/* Consult the list of known "bad" drives */
if (udma_black_list(drive)) {
on = 0;
goto fast_ata_pio;
}
on = 0;
verbose = 0;
if (id->field_valid & 4) {
if (id->dma_ultra & 0x007F) {
/* Force if Capable UltraDMA */
on = config_chipset_for_dma(drive);
if ((id->field_valid & 2) &&
(!on))
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if (id->dma_mword & 0x0007) {
/* Force if Capable regular DMA modes */
on = config_chipset_for_dma(drive);
if (!on)
goto no_dma_set;
}
} else if (udma_white_list(drive)) {
if (id->eide_dma_time > 150) {
goto no_dma_set;
}
/* Consult the list of known "good" drives */
on = config_chipset_for_dma(drive);
if (!on)
goto no_dma_set;
} else {
goto fast_ata_pio;
}
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
on = 0;
verbose = 0;
no_dma_set:
hpt3xx_tune_chipset(drive, ata_best_pio_mode(drive));
}
udma_enable(drive, on, verbose);
return 0;
}
static void hpt366_udma_irq_lost(struct ata_device *drive) static void hpt366_udma_irq_lost(struct ata_device *drive)
{ {
struct pci_dev *dev = drive->channel->pci_dev; struct pci_dev *dev = drive->channel->pci_dev;
...@@ -1232,6 +1145,8 @@ static void __init hpt366_init_channel(struct ata_channel *ch) ...@@ -1232,6 +1145,8 @@ static void __init hpt366_init_channel(struct ata_channel *ch)
struct pci_dev *dev = ch->pci_dev; struct pci_dev *dev = ch->pci_dev;
u32 rev = hpt_revision(dev); u32 rev = hpt_revision(dev);
ch->udma_four = hpt366_ata66_check(ch);
ch->tuneproc = hpt3xx_tune_drive; ch->tuneproc = hpt3xx_tune_drive;
ch->speedproc = hpt3xx_tune_chipset; ch->speedproc = hpt3xx_tune_chipset;
ch->quirkproc = hpt3xx_quirkproc; ch->quirkproc = hpt3xx_quirkproc;
...@@ -1272,17 +1187,12 @@ static void __init hpt366_init_channel(struct ata_channel *ch) ...@@ -1272,17 +1187,12 @@ static void __init hpt366_init_channel(struct ata_channel *ch)
// ch->resetproc = hpt3xx_reset; // ch->resetproc = hpt3xx_reset;
// ch->busproc = hpt3xx_tristate; // ch->busproc = hpt3xx_tristate;
} }
ch->modes_map = hpt3xx_modes_map(ch);
ch->udma_setup = hpt3xx_udma_setup; ch->udma_setup = hpt3xx_udma_setup;
if (!noautodma)
ch->autodma = 1;
else
ch->autodma = 0;
ch->highmem = 1; ch->highmem = 1;
} else } else
#endif #endif
{ {
ch->autodma = 0;
ch->drives[0].autotune = 1; ch->drives[0].autotune = 1;
ch->drives[1].autotune = 1; ch->drives[1].autotune = 1;
} }
...@@ -1315,7 +1225,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -1315,7 +1225,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_TTI, vendor: PCI_VENDOR_ID_TTI,
device: PCI_DEVICE_ID_TTI_HPT366, device: PCI_DEVICE_ID_TTI_HPT366,
init_chipset: hpt366_init_chipset, init_chipset: hpt366_init_chipset,
ata66_check: hpt366_ata66_check,
init_channel: hpt366_init_channel, init_channel: hpt366_init_channel,
init_dma: hpt366_init_dma, init_dma: hpt366_init_dma,
bootable: OFF_BOARD, bootable: OFF_BOARD,
...@@ -1326,7 +1235,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -1326,7 +1235,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_TTI, vendor: PCI_VENDOR_ID_TTI,
device: PCI_DEVICE_ID_TTI_HPT372, device: PCI_DEVICE_ID_TTI_HPT372,
init_chipset: hpt366_init_chipset, init_chipset: hpt366_init_chipset,
ata66_check: hpt366_ata66_check,
init_channel: hpt366_init_channel, init_channel: hpt366_init_channel,
init_dma: hpt366_init_dma, init_dma: hpt366_init_dma,
bootable: OFF_BOARD, bootable: OFF_BOARD,
...@@ -1337,7 +1245,6 @@ static struct ata_pci_device chipsets[] __initdata = { ...@@ -1337,7 +1245,6 @@ static struct ata_pci_device chipsets[] __initdata = {
vendor: PCI_VENDOR_ID_TTI, vendor: PCI_VENDOR_ID_TTI,
device: PCI_DEVICE_ID_TTI_HPT374, device: PCI_DEVICE_ID_TTI_HPT374,
init_chipset: hpt366_init_chipset, init_chipset: hpt366_init_chipset,
ata66_check: hpt366_ata66_check,
init_channel: hpt366_init_channel, init_channel: hpt366_init_channel,
init_dma: hpt366_init_dma, init_dma: hpt366_init_dma,
bootable: OFF_BOARD, bootable: OFF_BOARD,
......
...@@ -405,7 +405,7 @@ static void icside_dma_enable(struct ata_device *drive, int on, int verbose) ...@@ -405,7 +405,7 @@ static void icside_dma_enable(struct ata_device *drive, int on, int verbose)
#endif #endif
} }
static int icside_dma_check(struct ata_device *drive) static int icside_dma_check(struct ata_device *drive, int map)
{ {
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
struct ata_channel *ch = drive->channel; struct ata_channel *ch = drive->channel;
...@@ -466,7 +466,7 @@ static ide_startstop_t icside_dmaintr(struct ata_device *drive, struct request * ...@@ -466,7 +466,7 @@ static ide_startstop_t icside_dmaintr(struct ata_device *drive, struct request *
if (ata_status(drive, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) { if (ata_status(drive, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) {
if (!dma_stat) { if (!dma_stat) {
__ide_end_request(drive, rq, 1, rq->nr_sectors); __ide_end_request(drive, rq, 1, rq->nr_sectors);
return ide_stopped; return ATA_OP_FINISHED;
} }
printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n", printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
drive->name, dma_stat); drive->name, dma_stat);
...@@ -516,10 +516,10 @@ static int icside_dma_init(struct ata_device *drive, struct request *rq) ...@@ -516,10 +516,10 @@ static int icside_dma_init(struct ata_device *drive, struct request *rq)
u8 int cmd; u8 int cmd;
if (icside_dma_common(drive, rq, DMA_MODE_WRITE)) if (icside_dma_common(drive, rq, DMA_MODE_WRITE))
return ide_stopped; return ATA_OP_FINISHED;
if (drive->type != ATA_DISK) if (drive->type != ATA_DISK)
return ide_started; return ATA_OP_CONTINUES;
ata_set_handler(drive, icside_dmaintr, WAIT_CMD, NULL); ata_set_handler(drive, icside_dmaintr, WAIT_CMD, NULL);
...@@ -535,7 +535,7 @@ static int icside_dma_init(struct ata_device *drive, struct request *rq) ...@@ -535,7 +535,7 @@ static int icside_dma_init(struct ata_device *drive, struct request *rq)
enable_dma(ch->hw.dma); enable_dma(ch->hw.dma);
return ide_started; return ATA_OP_CONTINUES;
} }
static int icside_irq_status(struct ata_device *drive) static int icside_irq_status(struct ata_device *drive)
......
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.
...@@ -179,14 +179,6 @@ static int it8172_tune_chipset(struct ata_device *drive, u8 speed) ...@@ -179,14 +179,6 @@ static int it8172_tune_chipset(struct ata_device *drive, u8 speed)
return ide_config_drive_speed(drive, speed); return ide_config_drive_speed(drive, speed);
} }
static int it8172_udma_setup(struct ata_device *drive)
{
u8 speed = ata_timing_mode(drive, XFER_PIO | XFER_EPIO |
XFER_SWDMA | XFER_MWDMA | XFER_UDMA);
return !it8172_tune_chipset(drive, speed);
}
#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_IT8172_TUNING) */ #endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_IT8172_TUNING) */
...@@ -216,15 +208,11 @@ static void __init ide_init_it8172(struct ata_channel *hwif) ...@@ -216,15 +208,11 @@ static void __init ide_init_it8172(struct ata_channel *hwif)
if (!hwif->dma_base) if (!hwif->dma_base)
return; return;
#ifndef CONFIG_BLK_DEV_IDEDMA
hwif->autodma = 0;
#else /* CONFIG_BLK_DEV_IDEDMA */
# ifdef CONFIG_IT8172_TUNING # ifdef CONFIG_IT8172_TUNING
hwif->autodma = 1; hwif->modes_map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA | XFER_UDMA;
hwif->dmaproc = &it8172_dmaproc; hwif->udma_setup = udma_generic_setup;
hwif->speedproc = &it8172_tune_chipset; hwif->speedproc = &it8172_tune_chipset;
# endif # endif
#endif
cmdBase = dev->resource[0].start; cmdBase = dev->resource[0].start;
ctrlBase = dev->resource[1].start; ctrlBase = dev->resource[1].start;
......
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.
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.
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