Commit 81803bc1 authored by Paul Mackerras's avatar Paul Mackerras

Merge samba.org:/home/paulus/kernel/linux-2.5

into samba.org:/home/paulus/kernel/for-linus-ppc
parents 48f97bf4 acf7aa2c
......@@ -1490,7 +1490,7 @@ static struct hw_interrupt_type lapic_irq_type = {
end_lapic_irq
};
static void enable_NMI_through_LVT0 (void * dummy)
void enable_NMI_through_LVT0 (void * dummy)
{
unsigned int v, ver;
......
......@@ -445,6 +445,11 @@ int __init start_secondary(void *unused)
while (!test_bit(smp_processor_id(), &smp_commenced_mask))
rep_nop();
setup_secondary_APIC_clock();
if (nmi_watchdog == NMI_IO_APIC) {
disable_8259A_irq(0);
enable_NMI_through_LVT0(NULL);
enable_8259A_irq(0);
}
enable_APIC_timer();
/*
* low-memory mappings have been cleared, flush them from
......
......@@ -59,6 +59,9 @@ endmenu
mainmenu_option next_comment
comment 'Console drivers'
bool 'PROM console' CONFIG_PROM_CONSOLE
if [ "$CONFIG_PROM_CONSOLE" != "y" ]; then
define_bool CONFIG_DUMMY_CONSOLE y
fi
source drivers/video/Config.in
endmenu
......@@ -214,6 +217,8 @@ if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
fi
endmenu
source drivers/input/Config.in
source fs/Config.in
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
......
This diff is collapsed.
......@@ -13,7 +13,7 @@ export-objs := sparc_ksyms.o
IRQ_OBJS := irq.o sun4m_irq.o sun4c_irq.o sun4d_irq.o
obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o ${IRQ_OBJS} \
process.o signal.o ioport.o setup.o idprom.o \
sys_sparc.o sunos_asm.o sparc-stub.o systbls.o \
sys_sparc.o sunos_asm.o systbls.o \
time.o windows.o cpu.o devices.o sclow.o \
tadpole.o tick14.o ptrace.o sys_solaris.o \
unaligned.o muldiv.o pcic.o semaphore.o sparc_ksyms.o
......
......@@ -11,8 +11,7 @@ case $1 in
echo " sizeof(struct $2_struct)," >> $4
;;
-ints)
sed -n -e '/check_asm_data:/,/\.size/p' <$2 | sed -e 's/check_asm_data://' -e 's/\.size.*//' -e 's/\.ident.*//' -e 's/\.long[ ]\([0-9]*\)/\1,/' >>$3
;;
sed -n -e '/check_asm_data:/,/\.size/p' <$2 | sed -e 's/check_asm_data://' -e 's/\.size.*//' -e 's/\.ident.*//' -e 's/\.global.*//' -e 's/\.long[ ]\([0-9]*\)/\1,/' >>$3 ;;
*)
exit 1
;;
......
......@@ -24,8 +24,6 @@
struct linux_ebus *ebus_chain = 0;
extern void rs_init(void);
/* We are together with pcic.c under CONFIG_PCI. */
extern unsigned int pcic_pin_to_irq(unsigned int, char *name);
......@@ -361,6 +359,4 @@ void __init ebus_init(void)
ebus->next = 0;
++num_ebus;
}
rs_init();
}
......@@ -53,6 +53,7 @@ in_trap_handler:
.text
.align 4
#if 0 /* kgdb is dropped from 2.5.33 */
! This function is called when any SPARC trap (except window overflow or
! underflow) occurs. It makes sure that the invalid register window is still
! available before jumping into C code. It will also restore the world if you
......@@ -119,7 +120,7 @@ C_LABEL(trap_low):
STORE_PT_PRIV(sp, l0, l1, l2)
RESTORE_ALL
#endif
#ifdef CONFIG_BLK_DEV_FD
.text
......
......@@ -7,7 +7,7 @@
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
struct mm_struct init_mm = INIT_MM(init_mm);
struct task_struct init_task = INIT_TASK(init_task);
......
/* $Id: pcic.c,v 1.23 2002/01/23 14:33:55 davem Exp $
* pcic.c: Sparc/PCI controller support
/*
* pcic.c: MicroSPARC-IIep PCI controller support
*
* Copyright (C) 1998 V. Roganov and G. Raiko
*
......@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <asm/ebus.h>
#include <asm/sbus.h> /* for sanity check... */
......@@ -193,48 +194,26 @@ static void pci_do_settimeofday(struct timeval *tv);
#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3))
static int pcic_read_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *value)
static int pcic_read_config_dword(unsigned int busno, unsigned int devfn,
int where, u32 *value)
{
unsigned int v;
unsigned char busnum = bus->number;
struct linux_pcic *pcic;
unsigned long flags;
/* unsigned char where; */
switch (size) {
case 1:
pcic_read_config(bus, devfn, where&~3, 4, &v);
*value = 0xff & (v >> (8*(where & 3)));
return PCIBIOS_SUCCESSFUL;
break;
case 2:
if (where&1) return PCIBIOS_BAD_REGISTER_NUMBER;
pcic_read_config(bus, devfn, where&~3, 4, &v);
*value = 0xffff & (v >> (8*(where & 3)));
return PCIBIOS_SUCCESSFUL;
break;
}
/* size == 4, i.e. dword */
if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER;
if (busnum != 0) return PCIBIOS_DEVICE_NOT_FOUND;
pcic = &pcic0;
save_and_cli(flags);
local_irq_save(flags);
#if 0 /* does not fail here */
pcic_speculative = 1;
pcic_trapped = 0;
#endif
writel(CONFIG_CMD(busnum,devfn,where), pcic->pcic_config_space_addr);
writel(CONFIG_CMD(busno, devfn, where), pcic->pcic_config_space_addr);
#if 0 /* does not fail here */
nop();
if (pcic_trapped) {
restore_flags(flags);
local_irq_restore(flags);
*value = ~0;
return PCIBIOS_SUCCESSFUL;
return 0;
}
#endif
pcic_speculative = 2;
......@@ -243,50 +222,77 @@ static int pcic_read_config(struct pci_bus *bus, unsigned int devfn,
nop();
if (pcic_trapped) {
pcic_speculative = 0;
restore_flags(flags);
local_irq_restore(flags);
*value = ~0;
return PCIBIOS_SUCCESSFUL;
return 0;
}
pcic_speculative = 0;
restore_flags(flags);
return PCIBIOS_SUCCESSFUL;
local_irq_restore(flags);
return 0;
}
static int pcic_write_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 value)
static int pcic_read_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
unsigned int v;
unsigned char busnum = bus->number;
struct linux_pcic *pcic;
unsigned long flags;
if (bus->number != 0) return -EINVAL;
switch (size) {
case 1:
pcic_read_config(bus, devfn, where&~3, 4, &v);
v = (v & ~(0xff << (8*(where&3)))) |
((0xff&(unsigned)value) << (8*(where&3)));
return pcic_write_config(bus, devfn, where&~3, 4, v);
break;
pcic_read_config_dword(bus->number, devfn, where&~3, &v);
*val = 0xff & (v >> (8*(where & 3)));
return 0;
case 2:
if (where&1) return PCIBIOS_BAD_REGISTER_NUMBER;
pcic_read_config(bus, devfn, where&~3, 4, &v);
v = (v & ~(0xffff << (8*(where&3)))) |
((0xffff&(unsigned)value) << (8*(where&3)));
return pcic_write_config(bus, devfn, where&~3, 4, v);
break;
if (where&1) return -EINVAL;
pcic_read_config_dword(bus->number, devfn, where&~3, &v);
*val = 0xffff & (v >> (8*(where & 3)));
return 0;
case 4:
if (where&3) return -EINVAL;
pcic_read_config_dword(bus->number, devfn, where&~3, val);
return 0;
}
return -EINVAL;
}
static int pcic_write_config_dword(unsigned int busno, unsigned int devfn,
int where, u32 value)
{
struct linux_pcic *pcic;
unsigned long flags;
/* size == 4, i.e. dword */
if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER;
if (busnum != 0) return PCIBIOS_DEVICE_NOT_FOUND;
pcic = &pcic0;
save_and_cli(flags);
writel(CONFIG_CMD(busnum,devfn,where), pcic->pcic_config_space_addr);
local_irq_save(flags);
writel(CONFIG_CMD(busno, devfn, where), pcic->pcic_config_space_addr);
writel(value, pcic->pcic_config_space_data + (where&4));
restore_flags(flags);
return PCIBIOS_SUCCESSFUL;
local_irq_restore(flags);
return 0;
}
static int pcic_write_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 val)
{
unsigned int v;
if (bus->number != 0) return -EINVAL;
switch (size) {
case 1:
pcic_read_config_dword(bus->number, devfn, where&~3, &v);
v = (v & ~(0xff << (8*(where&3)))) |
((0xff&val) << (8*(where&3)));
return pcic_write_config_dword(bus->number, devfn, where&~3, v);
case 2:
if (where&1) return -EINVAL;
pcic_read_config_dword(bus->number, devfn, where&~3, &v);
v = (v & ~(0xffff << (8*(where&3)))) |
((0xffff&val) << (8*(where&3)));
return pcic_write_config_dword(bus->number, devfn, where&~3, v);
case 4:
if (where&3) return -EINVAL;
return pcic_write_config_dword(bus->number, devfn, where, val);
}
return -EINVAL;
}
static struct pci_ops pcic_ops = {
......@@ -420,7 +426,7 @@ static void __init pcic_pbm_scan_bus(struct linux_pcic *pcic)
/*
* Main entry point from the PCI subsystem.
*/
static int __init pcibios_init(void)
static int __init pcic_init(void)
{
struct linux_pcic *pcic;
......@@ -623,7 +629,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
{
struct list_head *walk;
int i, has_io, has_mem;
unsigned short cmd;
unsigned int cmd;
struct linux_pcic *pcic;
/* struct linux_pbm_info* pbm = &pcic->pbm; */
int node;
......@@ -663,19 +669,21 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
} else if (f & IORESOURCE_MEM)
has_mem = 1;
}
pcic_read_config_word(dev, PCI_COMMAND, &cmd);
pcic_read_config(dev->bus, dev->devfn, PCI_COMMAND, 2, &cmd);
if (has_io && !(cmd & PCI_COMMAND_IO)) {
printk("PCIC: Enabling I/O for device %02x:%02x\n",
dev->bus->number, dev->devfn);
cmd |= PCI_COMMAND_IO;
pcic_write_config_word(dev, PCI_COMMAND, cmd);
pcic_write_config(dev->bus, dev->devfn,
PCI_COMMAND, 2, cmd);
}
if (has_mem && !(cmd & PCI_COMMAND_MEMORY)) {
printk("PCIC: Enabling memory for device %02x:%02x\n",
dev->bus->number, dev->devfn);
cmd |= PCI_COMMAND_MEMORY;
pcic_write_config_word(dev, PCI_COMMAND, cmd);
}
pcic_write_config(dev->bus, dev->devfn,
PCI_COMMAND, 2, cmd);
}
node = pdev_to_pnode(&pcic->pbm, dev);
if(node == 0)
......@@ -785,46 +793,54 @@ static __inline__ unsigned long do_gettimeoffset(void)
return offset + count;
}
extern volatile unsigned long wall_jiffies;
extern unsigned long wall_jiffies;
extern rwlock_t xtime_lock;
static void pci_do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
save_and_cli(flags);
*tv = xtime;
tv->tv_usec += do_gettimeoffset();
unsigned long flags;
unsigned long usec, sec;
/*
* xtime is atomically updated in timer_bh. The difference
* between jiffies and wall_jiffies is nonzero if the timer
* bottom half hasnt executed yet.
*/
if ((jiffies - wall_jiffies) != 0)
tv->tv_usec += USECS_PER_JIFFY;
read_lock_irqsave(&xtime_lock, flags);
usec = do_gettimeoffset();
{
unsigned long lost = jiffies - wall_jiffies;
if (lost)
usec += lost * (1000000 / HZ);
}
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
read_unlock_irqrestore(&xtime_lock, flags);
restore_flags(flags);
while (usec >= 1000000) {
usec -= 1000000;
sec++;
}
if (tv->tv_usec >= 1000000) {
tv->tv_usec -= 1000000;
tv->tv_sec++;
}
tv->tv_sec = sec;
tv->tv_usec = usec;
}
static void pci_do_settimeofday(struct timeval *tv)
{
cli();
/*
* This is revolting. We need to set "xtime" correctly. However, the
* value in this location is the value at the most recent update of
* wall time. Discover what correction gettimeofday() would have
* made, and then undo it!
*/
tv->tv_usec -= do_gettimeoffset();
if(tv->tv_usec < 0) {
tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
while (tv->tv_usec < 0) {
tv->tv_usec += 1000000;
tv->tv_sec--;
}
xtime = *tv;
xtime.tv_sec = tv->tv_sec;
xtime.tv_nsec = (tv->tv_usec * 1000);
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
sti();
}
#if 0
......@@ -853,7 +869,7 @@ void pcibios_align_resource(void *data, struct resource *res,
{
}
int pcibios_enable_device(struct pci_dev *pdev)
int pcibios_enable_device(struct pci_dev *pdev, int mask)
{
return 0;
}
......@@ -898,9 +914,9 @@ static void pcic_disable_irq(unsigned int irq_nr)
unsigned long mask, flags;
mask = get_irqmask(irq_nr);
save_and_cli(flags);
local_irq_save(flags);
writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_SET);
restore_flags(flags);
local_irq_restore(flags);
}
static void pcic_enable_irq(unsigned int irq_nr)
......@@ -908,9 +924,9 @@ static void pcic_enable_irq(unsigned int irq_nr)
unsigned long mask, flags;
mask = get_irqmask(irq_nr);
save_and_cli(flags);
local_irq_save(flags);
writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_CLEAR);
restore_flags(flags);
local_irq_restore(flags);
}
static void pcic_clear_profile_irq(int cpu)
......@@ -1021,4 +1037,4 @@ void insl(unsigned long addr, void *dst, unsigned long count) {
#endif
subsys_initcall(pcibios_init);
subsys_initcall(pcic_init);
......@@ -94,7 +94,7 @@ int cpu_idle(void)
extern unsigned long sun4c_kernel_faults;
extern void sun4c_grow_kernel_ring(void);
save_and_cli(flags);
local_irq_save(flags);
now = jiffies;
count -= (now - last_jiffies);
last_jiffies = now;
......@@ -110,7 +110,7 @@ int cpu_idle(void)
sun4c_grow_kernel_ring();
}
}
restore_flags(flags);
local_irq_restore(flags);
}
while((!need_resched()) && pm_idle) {
......@@ -144,8 +144,6 @@ int cpu_idle(void)
extern char reboot_command [];
extern int serial_console;
extern void (*prom_palette)(int);
void machine_halt(void)
......
......@@ -34,7 +34,6 @@
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/kgdb.h>
#include <asm/processor.h>
#include <asm/oplib.h>
#include <asm/page.h>
......@@ -67,8 +66,6 @@ struct screen_info screen_info = {
*/
extern unsigned long trapbase;
extern int serial_console;
extern void breakpoint(void);
void (*prom_palette)(int);
asmlinkage void sys_sync(void); /* it's really int */
......@@ -105,28 +102,15 @@ void prom_sync_me(void)
return;
}
extern void rs_kgdb_hook(int tty_num); /* sparc/serial.c */
unsigned int boot_flags __initdata = 0;
#define BOOTME_DEBUG 0x1
#define BOOTME_SINGLE 0x2
#define BOOTME_KGDBA 0x4
#define BOOTME_KGDBB 0x8
#define BOOTME_KGDB 0xc
static int console_fb __initdata = 0;
/* Exported for mm/init.c:paging_init. */
unsigned long cmdline_memory_size __initdata = 0;
void kernel_enter_debugger(void)
{
if (boot_flags & BOOTME_KGDB) {
printk("KGDB: Entered\n");
breakpoint();
}
}
static void
prom_console_write(struct console *con, const char *s, unsigned n)
{
......@@ -142,11 +126,6 @@ static struct console prom_debug_console = {
int obp_system_intr(void)
{
if (boot_flags & BOOTME_KGDB) {
printk("KGDB: system interrupted\n");
breakpoint();
return 1;
}
if (boot_flags & BOOTME_DEBUG) {
printk("OBP: system interrupted\n");
prom_halt();
......@@ -196,24 +175,6 @@ static void __init boot_flags_init(char *commands)
commands++;
while (*commands && *commands != ' ')
process_switch(*commands++);
} else if (strlen(commands) >= 9
&& !strncmp(commands, "kgdb=tty", 8)) {
switch (commands[8]) {
#ifdef CONFIG_SUN_SERIAL
case 'a':
boot_flags |= BOOTME_KGDBA;
prom_printf("KGDB: Using serial line /dev/ttya.\n");
break;
case 'b':
boot_flags |= BOOTME_KGDBB;
prom_printf("KGDB: Using serial line /dev/ttyb.\n");
break;
#endif
default:
printk("KGDB: Unknown tty line.\n");
break;
}
commands += 9;
} else {
if (!strncmp(commands, "console=", 8)) {
commands += 8;
......@@ -378,65 +339,48 @@ void __init setup_arch(char **cmdline_p)
prom_setsync(prom_sync_me);
{
#if !CONFIG_SUN_SERIAL
serial_console = 0;
#ifndef CONFIG_SERIAL_CONSOLE /* Not CONFIG_SERIAL_SUNCORE: to be gone. */
serial_console = 0;
#else
switch (console_fb) {
case 0: /* Let get our io devices from prom */
{
int idev = prom_query_input_device();
int odev = prom_query_output_device();
if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) {
serial_console = 0;
} else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) {
serial_console = 1;
} else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) {
serial_console = 2;
} else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OTTYA) {
prom_printf("MrCoffee ttya\n");
serial_console = 1;
} else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OSCREEN) {
serial_console = 0;
prom_printf("MrCoffee keyboard\n");
} else {
prom_printf("Inconsistent or unknown console\n");
prom_printf("You cannot mix serial and non serial input/output devices\n");
prom_halt();
}
switch (console_fb) {
case 0: /* Let get our io devices from prom */
{
int idev = prom_query_input_device();
int odev = prom_query_output_device();
if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) {
serial_console = 0;
} else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) {
serial_console = 1;
} else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) {
serial_console = 2;
} else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OTTYA) {
prom_printf("MrCoffee ttya\n");
serial_console = 1;
} else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OSCREEN) {
serial_console = 0;
prom_printf("MrCoffee keyboard\n");
} else {
prom_printf("Inconsistent or unknown console\n");
prom_printf("You cannot mix serial and non serial input/output devices\n");
prom_halt();
}
break;
case 1: serial_console = 0; break; /* Force one of the framebuffers as console */
case 2: serial_console = 1; break; /* Force ttya as console */
case 3: serial_console = 2; break; /* Force ttyb as console */
}
#endif
}
if ((boot_flags & BOOTME_KGDBA)) {
rs_kgdb_hook(0);
}
if ((boot_flags & BOOTME_KGDBB)) {
rs_kgdb_hook(1);
break;
case 1: serial_console = 0; break; /* Force one of the framebuffers as console */
case 2: serial_console = 1; break; /* Force ttya as console */
case 3: serial_console = 2; break; /* Force ttyb as console */
}
#endif
if((boot_flags&BOOTME_DEBUG) && (linux_dbvec!=0) &&
((*(short *)linux_dbvec) != -1)) {
printk("Booted under KADB. Syncing trap table.\n");
(*(linux_dbvec->teach_debugger))();
}
if((boot_flags & BOOTME_KGDB)) {
set_debug_traps();
prom_printf ("Breakpoint!\n");
breakpoint();
}
init_mm.context = (unsigned long) NO_CONTEXT;
init_task.thread.kregs = &fake_swapper_regs;
if (serial_console)
conswitchp = NULL;
paging_init();
}
......@@ -514,3 +458,19 @@ struct seq_operations cpuinfo_op = {
.stop = c_stop,
.show = show_cpuinfo,
};
extern int stop_a_enabled;
void sun_do_break(void)
{
if (!stop_a_enabled)
return;
printk("\n");
flush_user_windows();
prom_cmdline();
}
int serial_console;
int stop_a_enabled = 1;
......@@ -38,11 +38,6 @@ extern void fpload(unsigned long *fpregs, unsigned long *fsr);
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_o0, int restart_syscall);
/* This turned off for production... */
/* #define DEBUG_SIGNALS 1 */
/* #define DEBUG_SIGNALS_TRACE 1 */
/* #define DEBUG_SIGNALS_MAPS 1 */
/* Signal frames: the original one (compatible with SunOS):
*
* Set up a signal frame... Make the stack look the way SunOS
......@@ -470,12 +465,6 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
synchronize_user_stack();
sframep = (struct signal_sframe *)get_sigframe(sa, regs, SF_ALIGNEDSZ);
if (invalid_frame_pointer (sframep, sizeof(*sframep))){
#ifdef DEBUG_SIGNALS /* fills up the console logs during crashme runs, yuck... */
printk("%s [%d]: User has trashed signal stack\n",
current->comm, current->pid);
printk("Sigstack ptr %p handler at pc<%08lx> for sig<%d>\n",
sframep, pc, signr);
#endif
/* Don't change signal code and address, so that
* post mortem debuggers can have a look.
*/
......@@ -635,13 +624,8 @@ new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
if (invalid_frame_pointer (sf, sigframe_size))
goto sigill_and_return;
if (current->thread.w_saved != 0) {
#ifdef DEBUG_SIGNALS
printk ("%s [%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
#endif
if (current->thread.w_saved != 0)
goto sigill_and_return;
}
/* 2. Save the current process state */
err = __copy_to_user(&sf->info.si_regs, regs, sizeof (struct pt_regs));
......@@ -795,12 +779,8 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
synchronize_user_stack();
sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, SVR4_SF_ALIGNED + REGWIN_SZ);
if (invalid_frame_pointer (sfp, sizeof (*sfp))){
#ifdef DEBUG_SIGNALS
printk ("Invalid stack frame\n");
#endif
if (invalid_frame_pointer (sfp, sizeof (*sfp)))
goto sigill_and_return;
}
/* Start with a clean frame pointer and fill it */
err = __clear_user(sfp, sizeof (*sfp));
......@@ -883,9 +863,6 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs->pc = (unsigned long) sa->sa_handler;
regs->npc = (regs->pc + 4);
#ifdef DEBUG_SIGNALS
printk ("Solaris-frame: %x %x\n", (int) regs->pc, (int) regs->npc);
#endif
/* Arguments passed to signal handler */
if (regs->u_regs [14]){
struct reg_window *rw = (struct reg_window *) regs->u_regs [14];
......@@ -1090,61 +1067,6 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
}
}
#ifdef DEBUG_SIGNALS_MAPS
#define MAPS_LINE_FORMAT "%08lx-%08lx %s %08lx %02x:%02x %lu "
static inline void read_maps (void)
{
struct vm_area_struct * map, * next;
char * buffer;
ssize_t i;
buffer = (char*)__get_free_page(GFP_KERNEL);
if (!buffer)
return;
for (map = current->mm->mmap ; map ; map = next ) {
/* produce the next line */
char *line;
char str[5], *cp = str;
int flags;
dev_t dev;
unsigned long ino;
/*
* Get the next vma now (but it won't be used if we sleep).
*/
next = map->vm_next;
flags = map->vm_flags;
*cp++ = flags & VM_READ ? 'r' : '-';
*cp++ = flags & VM_WRITE ? 'w' : '-';
*cp++ = flags & VM_EXEC ? 'x' : '-';
*cp++ = flags & VM_MAYSHARE ? 's' : 'p';
*cp++ = 0;
dev = 0;
ino = 0;
if (map->vm_file != NULL) {
dev = map->vm_file->f_dentry->d_inode->i_dev;
ino = map->vm_file->f_dentry->d_inode->i_ino;
line = d_path(map->vm_file->f_dentry,
map->vm_file->f_vfsmnt,
buffer, PAGE_SIZE);
}
printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
MAJOR(dev), MINOR(dev), ino);
if (map->vm_file != NULL)
printk("%s\n", line);
else
printk("\n");
}
free_page((unsigned long)buffer);
return;
}
#endif
/* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
......@@ -1152,7 +1074,6 @@ static inline void read_maps (void)
asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_i0, int restart_syscall)
{
unsigned long signr;
struct k_sigaction *ka;
siginfo_t info;
......@@ -1171,9 +1092,21 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
oldset = &current->blocked;
for (;;) {
spin_lock_irq(&current->sigmask_lock);
signr = dequeue_signal(&current->blocked, &info);
spin_unlock_irq(&current->sigmask_lock);
sigset_t *mask = &current->blocked;
unsigned long signr = 0;
local_irq_disable();
if (current->sig->shared_pending.head) {
spin_lock(&current->sig->siglock);
signr = dequeue_signal(&current->sig->shared_pending, mask, &info);
spin_unlock(&current->sig->siglock);
}
if (!signr) {
spin_lock(&current->sigmask_lock);
signr = dequeue_signal(&current->pending, mask, &info);
spin_unlock(&current->sigmask_lock);
}
local_irq_enable();
if (!signr)
break;
......@@ -1193,7 +1126,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
restart_syscall = 0;
}
current->exit_code = signr;
current->state = TASK_STOPPED;
set_current_state(TASK_STOPPED);
/* This happens to be SMP safe so no need to
* grab master kernel lock even in this case.
......@@ -1254,52 +1187,27 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
if (is_orphaned_pgrp(current->pgrp))
continue;
case SIGSTOP:
if (current->ptrace & PT_PTRACED)
continue;
current->state = TASK_STOPPED;
case SIGSTOP: {
struct signal_struct *sig;
set_current_state(TASK_STOPPED);
current->exit_code = signr;
/* notify_parent() is SMP safe */
if(!(current->parent->sig->action[SIGCHLD-1].sa.sa_flags &
SA_NOCLDSTOP))
sig = current->parent->sig;
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
SA_NOCLDSTOP))
notify_parent(current, SIGCHLD);
schedule();
continue;
}
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
#ifdef DEBUG_SIGNALS
/* Very useful to debug dynamic linker problems */
printk ("Sig %ld going for %s[%d]...\n", signr, current->comm, current->pid);
show_regs (regs);
#ifdef DEBUG_SIGNALS_TRACE
{
struct reg_window *rw = (struct reg_window *)regs->u_regs[UREG_FP];
unsigned int ins[8];
while (rw &&
!(((unsigned long) rw) & 0x3)) {
copy_from_user(ins, &rw->ins[0], sizeof(ins));
printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
rw = (struct reg_window *)(unsigned long)ins[6];
}
}
#endif
#ifdef DEBUG_SIGNALS_MAPS
printk("Maps:\n");
read_maps();
#endif
#endif
/* fall through */
/* FALLTHRU */
default:
sigaddset(&current->pending.signal, signr);
recalc_sigpending();
current->flags |= PF_SIGNALED;
do_exit(exit_code);
sig_exit(signr, exit_code, &info);
/* NOT REACHED */
}
}
......
......@@ -188,22 +188,16 @@ static inline void copy_ttentry(struct tt_entry *src, struct tt_entry *dest)
/* Initialize the kgdb_savettable so that debugging can commence */
static void eh_init(void)
{
int i, flags;
int i;
save_and_cli(flags);
for(i=0; i < 256; i++)
copy_ttentry(&sparc_ttable[i], &kgdb_savettable[i]);
restore_flags(flags);
}
/* Install an exception handler for kgdb */
static void exceptionHandler(int tnum, trapfunc_t trap_entry)
{
unsigned long te_addr = (unsigned long) trap_entry;
int flags;
/* We are dorking with a live trap table, all irqs off */
save_and_cli(flags);
/* Make new vector */
sparc_ttable[tnum].inst_one =
......@@ -212,8 +206,6 @@ static void exceptionHandler(int tnum, trapfunc_t trap_entry)
sparc_ttable[tnum].inst_two = SPARC_RD_PSR_L0;
sparc_ttable[tnum].inst_three = SPARC_NOP;
sparc_ttable[tnum].inst_four = SPARC_NOP;
restore_flags(flags);
}
/* Convert ch from a hex digit to an int */
......@@ -406,7 +398,7 @@ set_debug_traps(void)
struct hard_trap_info *ht;
unsigned long flags;
save_and_cli(flags);
local_irq_save(flags);
#if 0
/* Have to sort this out. This cannot be done after initialization. */
BTFIXUPSET_CALL(flush_cache_all, flush_cache_all_nop, BTFIXUPCALL_NOP);
......@@ -438,7 +430,7 @@ set_debug_traps(void)
#endif
initialized = 1; /* connect! */
restore_flags(flags);
local_irq_restore(flags);
}
/* Convert the SPARC hardware trap type code to a unix signal number. */
......
......@@ -55,7 +55,7 @@ sys_call_table:
/*170*/ .long sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
/*175*/ .long sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_query_module
/*185*/ .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sys_newuname
/*185*/ .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname
/*190*/ .long sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
/*195*/ .long sys_nis_syscall, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask
/*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir
......
......@@ -56,6 +56,9 @@ static void clk_slow(void)
"g2", "g3", "g4", "g5");
}
/*
* Tadpole is guaranteed to be UP, using local_irq_save.
*/
static void tsu_clockstop(void)
{
unsigned int mcsr;
......@@ -64,28 +67,28 @@ static void tsu_clockstop(void)
if (!clk_ctrl)
return;
if (!(clk_state & CLOCK_INIT_DONE)) {
save_and_cli(flags);
local_irq_save(flags);
clk_init();
clk_state |= CLOCK_INIT_DONE; /* all done */
restore_flags(flags);
local_irq_restore(flags);
return;
}
if (!(clk_ctrl[2] & 1))
return; /* no speed up yet */
save_and_cli(flags);
local_irq_save(flags);
/* if SCSI DMA in progress, don't slow clock */
mcsr = ldphys(MACIO_SCSI_CSR_ADDR);
if ((mcsr&MACIO_EN_DMA) != 0) {
restore_flags(flags);
local_irq_restore(flags);
return;
}
/* TODO... the minimum clock setting ought to increase the
* memory refresh interval..
*/
clk_slow();
restore_flags(flags);
local_irq_restore(flags);
}
static void swift_clockstop(void)
......
......@@ -29,32 +29,30 @@ extern unsigned long lvl14_save[5];
static unsigned long *linux_lvl14 = NULL;
static unsigned long obp_lvl14[4];
/*
* Call with timer IRQ closed.
* First time we do it with disable_irq, later prom code uses spin_lock_irq().
*/
void install_linux_ticker(void)
{
unsigned long flags;
if (!linux_lvl14)
return;
save_and_cli(flags);
linux_lvl14[0] = lvl14_save[0];
linux_lvl14[1] = lvl14_save[1];
linux_lvl14[2] = lvl14_save[2];
linux_lvl14[3] = lvl14_save[3];
restore_flags(flags);
}
void install_obp_ticker(void)
{
unsigned long flags;
if (!linux_lvl14)
return;
save_and_cli(flags);
linux_lvl14[0] = obp_lvl14[0];
linux_lvl14[1] = obp_lvl14[1];
linux_lvl14[2] = obp_lvl14[2];
linux_lvl14[3] = obp_lvl14[3];
restore_flags(flags);
}
void claim_ticker14(void (*handler)(int, void *, struct pt_regs *),
......
......@@ -43,6 +43,8 @@
extern rwlock_t xtime_lock;
extern unsigned long wall_jiffies;
u64 jiffies_64;
enum sparc_clock_type sp_clock_typ;
......@@ -114,6 +116,9 @@ __volatile__ unsigned int *master_l10_limit;
* timer_interrupt() needs to keep up the real-time clock,
* as well as call the "do_timer()" routine every clocktick
*/
#define TICK_SIZE (tick_nsec / 1000)
void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
/* last time the cmos clock got updated */
......@@ -142,8 +147,8 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
/* Determine when to update the Mostek clock. */
if ((time_status & STA_UNSYNC) == 0 &&
xtime.tv_sec > last_rtc_update + 660 &&
xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
(xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
(xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec;
else
......@@ -400,7 +405,7 @@ void __init sbus_time_init(void)
mon = MSTK_REG_MONTH(mregs);
year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_usec = 0;
xtime.tv_nsec = 0;
mregs->creg &= ~MSTK_CREG_READ;
spin_unlock_irq(&mostek_lock);
#ifdef CONFIG_SUN4
......@@ -431,7 +436,7 @@ void __init sbus_time_init(void)
intersil_start(iregs);
xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_usec = 0;
xtime.tv_nsec = 0;
printk("%u/%u/%u %u:%u:%u\n",day,mon,year,hour,min,sec);
}
#endif
......@@ -467,48 +472,33 @@ extern __inline__ unsigned long do_gettimeoffset(void)
return offset + count;
}
/* This need not obtain the xtime_lock as it is coded in
* an implicitly SMP safe way already.
/* Ok, my cute asm atomicity trick doesn't work anymore.
* There are just too many variables that need to be protected
* now (both members of xtime, wall_jiffies, et al.)
*/
void do_gettimeofday(struct timeval *tv)
{
/* Load doubles must be used on xtime so that what we get
* is guarenteed to be atomic, this is why we can run this
* with interrupts on full blast. Don't touch this... -DaveM
*/
__asm__ __volatile__(
"sethi %hi(master_l10_counter), %o1\n\t"
"ld [%o1 + %lo(master_l10_counter)], %g3\n\t"
"sethi %hi(xtime), %g2\n"
"1:\n\t"
"ldd [%g2 + %lo(xtime)], %o4\n\t"
"ld [%g3], %o1\n\t"
"ldd [%g2 + %lo(xtime)], %o2\n\t"
"xor %o4, %o2, %o2\n\t"
"xor %o5, %o3, %o3\n\t"
"orcc %o2, %o3, %g0\n\t"
"bne 1b\n\t"
" cmp %o1, 0\n\t"
"bge 1f\n\t"
" srl %o1, 0xa, %o1\n\t"
"sethi %hi(tick), %o3\n\t"
"ld [%o3 + %lo(tick)], %o3\n\t"
"sethi %hi(0x1fffff), %o2\n\t"
"or %o2, %lo(0x1fffff), %o2\n\t"
"add %o5, %o3, %o5\n\t"
"and %o1, %o2, %o1\n"
"1:\n\t"
"add %o5, %o1, %o5\n\t"
"sethi %hi(1000000), %o2\n\t"
"or %o2, %lo(1000000), %o2\n\t"
"cmp %o5, %o2\n\t"
"bl,a 1f\n\t"
" st %o4, [%o0 + 0x0]\n\t"
"add %o4, 0x1, %o4\n\t"
"sub %o5, %o2, %o5\n\t"
"st %o4, [%o0 + 0x0]\n"
"1:\n\t"
"st %o5, [%o0 + 0x4]\n");
unsigned long flags;
unsigned long usec, sec;
read_lock_irqsave(&xtime_lock, flags);
usec = do_gettimeoffset();
{
unsigned long lost = jiffies - wall_jiffies;
if (lost)
usec += lost * (1000000 / HZ);
}
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
read_unlock_irqrestore(&xtime_lock, flags);
while (usec >= 1000000) {
usec -= 1000000;
sec++;
}
tv->tv_sec = sec;
tv->tv_usec = usec;
}
void do_settimeofday(struct timeval *tv)
......@@ -520,12 +510,20 @@ void do_settimeofday(struct timeval *tv)
static void sbus_do_settimeofday(struct timeval *tv)
{
/*
* This is revolting. We need to set "xtime" correctly. However, the
* value in this location is the value at the most recent update of
* wall time. Discover what correction gettimeofday() would have
* made, and then undo it!
*/
tv->tv_usec -= do_gettimeoffset();
if(tv->tv_usec < 0) {
tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
while (tv->tv_usec < 0) {
tv->tv_usec += 1000000;
tv->tv_sec--;
}
xtime = *tv;
xtime.tv_sec = tv->tv_sec;
xtime.tv_nsec = (tv->tv_usec * 1000);
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
......
......@@ -506,9 +506,18 @@ asmlinkage void user_unaligned_trap(struct pt_regs *regs, unsigned int insn)
break;
case both:
#if 0 /* unsupported */
do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
(unsigned long *) addr,
user_unaligned_trap_fault);
#else
/*
* This was supported in 2.4. However, we question
* the value of SWAP instruction across word boundaries.
*/
printk("Unaligned SWAP unsupported.\n");
goto kill_user;
#endif
break;
default:
......
......@@ -1212,7 +1212,6 @@ extern int linux_num_cpus;
void (*poke_srmmu)(void) __initdata = NULL;
extern unsigned long bootmem_init(unsigned long *pages_avail);
extern void sun_serial_setup(void);
void __init srmmu_paging_init(void)
{
......@@ -1281,13 +1280,6 @@ void __init srmmu_paging_init(void)
flush_cache_all();
flush_tlb_all();
/*
* This does not logically belong here, but we need to
* call it at the moment we are able to use the bootmem
* allocator.
*/
sun_serial_setup();
sparc_context_init(num_contexts);
kmap_init();
......
......@@ -2001,7 +2001,6 @@ extern void sparc_context_init(int);
extern unsigned long end;
extern unsigned long bootmem_init(unsigned long *pages_avail);
extern unsigned long last_valid_pfn;
extern void sun_serial_setup(void);
void __init sun4c_paging_init(void)
{
......@@ -2018,12 +2017,6 @@ void __init sun4c_paging_init(void)
last_valid_pfn = bootmem_init(&pages_avail);
end_pfn = last_valid_pfn;
/* This does not logically belong here, but we need to
* call it at the moment we are able to use the bootmem
* allocator.
*/
sun_serial_setup();
sun4c_probe_mmu();
invalid_segment = (num_segmaps - 1);
sun4c_init_mmu_entry_pool();
......
......@@ -12,6 +12,7 @@
#include <asm/openprom.h>
#include <asm/oplib.h>
#include <asm/auxio.h>
#include <asm/system.h>
extern void restore_current(void);
......@@ -47,7 +48,6 @@ prom_feval(char *fstring)
/* We want to do this more nicely some day. */
extern void (*prom_palette)(int);
extern int serial_console;
/* Drop into the prom, with the chance to continue with the 'go'
* prom command.
......@@ -55,20 +55,18 @@ extern int serial_console;
void
prom_cmdline(void)
{
extern void kernel_enter_debugger(void);
extern void install_obp_ticker(void);
extern void install_linux_ticker(void);
unsigned long flags;
kernel_enter_debugger();
if(!serial_console && prom_palette)
prom_palette (1);
install_obp_ticker();
spin_lock_irqsave(&prom_lock, flags);
install_obp_ticker();
(*(romvec->pv_abort))();
restore_current();
spin_unlock_irqrestore(&prom_lock, flags);
install_linux_ticker();
spin_unlock_irqrestore(&prom_lock, flags);
#ifdef CONFIG_SUN_AUXIO
TURN_ON_LED;
#endif
......
......@@ -204,6 +204,8 @@ CONFIG_BLK_DEV_IDE=y
#
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_HD_IDE is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
# CONFIG_IDEDISK_STROKE is not set
......@@ -218,7 +220,7 @@ CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_BLK_DEV_TIVO is not set
# CONFIG_BLK_DEV_IDECS is not set
CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDECD_BAILOUT is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set
......@@ -229,8 +231,8 @@ CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
# CONFIG_BLK_DEV_ISAPNP is not set
# CONFIG_BLK_DEV_RZ1000 is not set
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_BLK_DEV_GENERIC is not set
# CONFIG_IDEPCI_SHARE_IRQ is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set
......@@ -239,29 +241,29 @@ CONFIG_IDEDMA_PCI_AUTO=y
CONFIG_IDEDMA_ONLYDISK=y
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_PCI_WIP is not set
# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
CONFIG_BLK_DEV_ADMA=y
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_AEC62XX_TUNING is not set
CONFIG_BLK_DEV_ALI15X3=y
# CONFIG_WDC_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
# CONFIG_AMD74XX_OVERRIDE is not set
CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_CMD680 is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_HPT34X_AUTODMA is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_NFORCE is not set
CONFIG_BLK_DEV_NS87415=y
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_ADMA100 is not set
# CONFIG_BLK_DEV_PDC202XX is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_PDC202XX_BURST is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_RZ1000 is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIIMAGE is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
......@@ -954,7 +956,7 @@ CONFIG_USB_AUERSWALD=m
CONFIG_USB_RIO500=m
# CONFIG_USB_BRLVGER is not set
CONFIG_USB_LCD=m
CONFIG_USB_SPEEDTOUCH=m
# CONFIG_USB_SPEEDTOUCH is not set
#
# Bluetooth support
......
......@@ -1795,69 +1795,3 @@ __flushw_user:
restore %g0, %g0, %g0
2: retl
nop
/* This need not obtain the xtime_lock as it is coded in
* an implicitly SMP safe way already.
*/
.align 64
.globl do_gettimeofday
do_gettimeofday: /* %o0 = timevalp */
/* Load doubles must be used on xtime so that what we get
* is guarenteed to be atomic, this is why we can run this
* with interrupts on full blast. Don't touch this... -DaveM
*
* Note with time_t changes to the timeval type, I must now use
* nucleus atomic quad 128-bit loads.
*
* If xtime was stored recently, I've seen crap from the
* quad load on Cheetah. Putting a membar SYNC before
* the quad load seems to make the problem go away. -DaveM
* (we should nop out workarounds like this on spitfire)
*/
sethi %hi(timer_tick_offset), %g3
sethi %hi(xtime), %g2
sethi %hi(timer_tick_compare), %g1
ldx [%g3 + %lo(timer_tick_offset)], %g3
or %g2, %lo(xtime), %g2
or %g1, %lo(timer_tick_compare), %g1
1: membar #Sync
ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o4
BRANCH_IF_ANY_CHEETAH(o2,o1,2f)
ba,pt %xcc, 3f
rd %tick, %o1
2: ba,pt %xcc, 3f
rd %asr24, %o1
3: ldx [%g1], %g7
membar #Sync
ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o2
xor %o4, %o2, %o2
xor %o5, %o3, %o3
orcc %o2, %o3, %g0
bne,pn %xcc, 1b
sethi %hi(wall_jiffies), %o2
sethi %hi(jiffies), %o3
ldx [%o2 + %lo(wall_jiffies)], %o2
ldx [%o3 + %lo(jiffies)], %o3
sub %o3, %o2, %o2
sethi %hi(timer_ticks_per_usec_quotient), %o3
add %g3, %o1, %o1
ldx [%o3 + %lo(timer_ticks_per_usec_quotient)], %o3
sub %o1, %g7, %o1
mulx %o3, %o1, %o1
brz,pt %o2, 1f
srlx %o1, 32, %o1
sethi %hi(10000), %g2
or %g2, %lo(10000), %g2
add %o1, %g2, %o1
1: sethi %hi(1000000), %o2
srlx %o5, 32, %o5
or %o2, %lo(1000000), %o2
add %o5, %o1, %o5
cmp %o5, %o2
bl,a,pn %xcc, 1f
stx %o4, [%o0 + 0x0]
add %o4, 0x1, %o4
sub %o5, %o2, %o5
stx %o4, [%o0 + 0x0]
1: retl
st %o5, [%o0 + 0x8]
......@@ -8,7 +8,7 @@
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS;
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
struct mm_struct init_mm = INIT_MM(init_mm);
/* .text section in head.S is aligned at 2 page boundry and this gets linked
......
......@@ -365,7 +365,7 @@ void pcibios_align_resource(void *data, struct resource *res,
{
}
int pcibios_enable_device(struct pci_dev *pdev)
int pcibios_enable_device(struct pci_dev *pdev, int mask)
{
return 0;
}
......
......@@ -11,6 +11,7 @@
#include <linux/signal.h>
#include <linux/delay.h>
#include <asm/system.h>
#include <asm/ebus.h>
#define __KERNEL_SYSCALLS__
......@@ -37,8 +38,6 @@ extern void machine_halt(void);
extern void machine_alt_power_off(void);
static void (*poweroff_method)(void) = machine_alt_power_off;
extern int serial_console;
void machine_power_off(void)
{
if (!serial_console) {
......
......@@ -110,7 +110,6 @@ int cpu_idle(void)
extern char reboot_command [];
extern void (*prom_palette)(int);
extern int serial_console;
extern void (*prom_keyboard)(void);
void machine_halt(void)
......
......@@ -314,12 +314,9 @@ int prom_callback(long *args)
return 0;
}
extern void rs_kgdb_hook(int tty_num); /* sparc/serial.c */
unsigned int boot_flags = 0;
#define BOOTME_DEBUG 0x1
#define BOOTME_SINGLE 0x2
#define BOOTME_KGDB 0x4
static int console_fb __initdata = 0;
......@@ -389,26 +386,6 @@ static void __init boot_flags_init(char *commands)
commands++;
while (*commands && *commands != ' ')
process_switch(*commands++);
} else if (strlen(commands) >= 9
&& !strncmp(commands, "kgdb=tty", 8)) {
boot_flags |= BOOTME_KGDB;
switch (commands[8]) {
#ifdef CONFIG_SUN_SERIAL
case 'a':
rs_kgdb_hook(0);
prom_printf("KGDB: Using serial line /dev/ttya.\n");
break;
case 'b':
rs_kgdb_hook(1);
prom_printf("KGDB: Using serial line /dev/ttyb.\n");
break;
#endif
default:
printk("KGDB: Unknown tty line.\n");
boot_flags &= ~BOOTME_KGDB;
break;
}
commands += 9;
} else {
if (!strncmp(commands, "console=", 8)) {
commands += 8;
......@@ -484,7 +461,6 @@ extern void paging_init(void);
void __init setup_arch(char **cmdline_p)
{
extern int serial_console; /* in console.c, of course */
unsigned long highest_paddr;
int i;
......@@ -568,7 +544,6 @@ void __init setup_arch(char **cmdline_p)
}
#endif
#ifdef CONFIG_SUN_SERIAL
switch (console_fb) {
case 0: /* Let's get our io devices from prom */
{
......@@ -597,10 +572,7 @@ void __init setup_arch(char **cmdline_p)
case 3: /* Force ttyb as console */
serial_console = 2;
break;
}
#else
serial_console = 0;
#endif
};
if (serial_console)
conswitchp = NULL;
......
......@@ -36,11 +36,6 @@
static int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_o0, int ret_from_syscall);
/* This turned off for production... */
/* #define DEBUG_SIGNALS 1 */
/* #define DEBUG_SIGNALS_TRACE 1 */
/* #define DEBUG_SIGNALS_MAPS 1 */
int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
{
if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
......@@ -535,13 +530,8 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
if (invalid_frame_pointer (sf, sigframe_size))
goto sigill;
if (get_thread_wsaved() != 0) {
#ifdef DEBUG_SIGNALS
printk ("%s[%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
#endif
if (get_thread_wsaved() != 0)
goto sigill;
}
/* 2. Save the current process state */
err = copy_to_user(&sf->regs, regs, sizeof (*regs));
......@@ -631,62 +621,6 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
}
}
#ifdef DEBUG_SIGNALS_MAPS
#define MAPS_LINE_FORMAT "%016lx-%016lx %s %016lx %02x:%02x %lu "
static inline void read_maps (void)
{
struct vm_area_struct * map, * next;
char * buffer;
ssize_t i;
buffer = (char*)__get_free_page(GFP_KERNEL);
if (!buffer)
return;
for (map = current->mm->mmap ; map ; map = next ) {
/* produce the next line */
char *line;
char str[5], *cp = str;
int flags;
dev_t dev;
unsigned long ino;
/*
* Get the next vma now (but it won't be used if we sleep).
*/
next = map->vm_next;
flags = map->vm_flags;
*cp++ = flags & VM_READ ? 'r' : '-';
*cp++ = flags & VM_WRITE ? 'w' : '-';
*cp++ = flags & VM_EXEC ? 'x' : '-';
*cp++ = flags & VM_MAYSHARE ? 's' : 'p';
*cp++ = 0;
dev = 0;
ino = 0;
if (map->vm_file != NULL) {
dev = map->vm_file->f_dentry->d_inode->i_dev;
ino = map->vm_file->f_dentry->d_inode->i_ino;
line = d_path(map->vm_file->f_dentry,
map->vm_file->f_vfsmnt,
buffer, PAGE_SIZE);
}
printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
MAJOR(dev), MINOR(dev), ino);
if (map->vm_file != NULL)
printk("%s\n", line);
else
printk("\n");
}
free_page((unsigned long)buffer);
return;
}
#endif
/* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
......@@ -694,7 +628,6 @@ static inline void read_maps (void)
static int do_signal(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_i0, int restart_syscall)
{
unsigned long signr;
siginfo_t info;
struct k_sigaction *ka;
......@@ -709,9 +642,21 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
}
#endif
for (;;) {
spin_lock_irq(&current->sigmask_lock);
signr = dequeue_signal(&current->blocked, &info);
spin_unlock_irq(&current->sigmask_lock);
sigset_t *mask = &current->blocked;
unsigned long signr = 0;
local_irq_disable();
if (current->sig->shared_pending.head) {
spin_lock(&current->sig->siglock);
signr = dequeue_signal(&current->sig->shared_pending, mask, &info);
spin_unlock(&current->sig->siglock);
}
if (!signr) {
spin_lock(&current->sigmask_lock);
signr = dequeue_signal(&current->pending, mask, &info);
spin_unlock(&current->sigmask_lock);
}
local_irq_enable();
if (!signr)
break;
......@@ -732,7 +677,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
}
current->exit_code = signr;
current->state = TASK_STOPPED;
set_current_state(TASK_STOPPED);
notify_parent(current, SIGCHLD);
schedule();
if (!(signr = current->exit_code))
......@@ -787,8 +732,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
case SIGSTOP: {
struct signal_struct *sig;
current->state = TASK_STOPPED;
set_current_state(TASK_STOPPED);
current->exit_code = signr;
sig = current->parent->sig;
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
......@@ -803,29 +747,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
#ifdef DEBUG_SIGNALS
/* Very useful to debug the dynamic linker */
printk ("Sig %d going...\n", (int)signr);
show_regs (regs);
#ifdef DEBUG_SIGNALS_TRACE
{
struct reg_window *rw = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
unsigned long ins[8];
while (rw &&
!(((unsigned long) rw) & 0x3)) {
copy_from_user(ins, &rw->ins[0], sizeof(ins));
printk("Caller[%016lx](%016lx,%016lx,%016lx,%016lx,%016lx,%016lx)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
rw = (struct reg_window *)(unsigned long)(ins[6] + STACK_BIAS);
}
}
#endif
#ifdef DEBUG_SIGNALS_MAPS
printk("Maps:\n");
read_maps();
#endif
#endif
/* fall through */
/* FALLTHRU */
default:
sig_exit(signr, exit_code, &info);
/* NOT REACHED */
......
......@@ -34,12 +34,6 @@
int do_signal32(sigset_t *oldset, struct pt_regs *regs,
unsigned long orig_o0, int ret_from_syscall);
/* This turned off for production... */
/* #define DEBUG_SIGNALS 1 */
/* #define DEBUG_SIGNALS_TRACE 1 */
/* #define DEBUG_SIGNALS_MAPS 1 */
/* #define DEBUG_SIGNALS_TLB 1 */
/* Signal frames: the original one (compatible with SunOS):
*
* Set up a signal frame... Make the stack look the way SunOS
......@@ -525,12 +519,6 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
sframep = (struct signal_sframe32 *)get_sigframe(sa, regs, SF_ALIGNEDSZ);
if (invalid_frame_pointer (sframep, sizeof(*sframep))){
#ifdef DEBUG_SIGNALS /* fills up the console logs during crashme runs, yuck... */
printk("%s [%d]: User has trashed signal stack\n",
current->comm, current->pid);
printk("Sigstack ptr %p handler at pc<%016lx> for sig<%d>\n",
sframep, pc, signr);
#endif
/* Don't change signal code and address, so that
* post mortem debuggers can have a look.
*/
......@@ -696,21 +684,11 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg
sf = (struct new_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size);
if (invalid_frame_pointer (sf, sigframe_size)) {
#ifdef DEBUG_SIGNALS
printk("new_setup_frame32(%s:%d): invalid_frame_pointer(%p, %d)\n",
current->comm, current->pid, sf, sigframe_size);
#endif
if (invalid_frame_pointer (sf, sigframe_size))
goto sigill;
}
if (get_thread_wsaved() != 0) {
#ifdef DEBUG_SIGNALS
printk ("%s[%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
#endif
if (get_thread_wsaved() != 0)
goto sigill;
}
/* 2. Save the current process state */
if (test_thread_flag(TIF_32BIT)) {
......@@ -835,12 +813,8 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, REGWIN_SZ + SVR4_SF_ALIGNED);
if (invalid_frame_pointer (sfp, sizeof (*sfp))){
#ifdef DEBUG_SIGNALS
printk ("Invalid stack frame\n");
#endif
if (invalid_frame_pointer (sfp, sizeof (*sfp)))
do_exit(SIGILL);
}
/* Start with a clean frame pointer and fill it */
err = clear_user(sfp, sizeof (*sfp));
......@@ -939,9 +913,6 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs->tnpc &= 0xffffffff;
}
#ifdef DEBUG_SIGNALS
printk ("Solaris-frame: %x %x\n", (int) regs->tpc, (int) regs->tnpc);
#endif
/* Arguments passed to signal handler */
if (regs->u_regs [14]){
struct reg_window32 *rw = (struct reg_window32 *)
......@@ -975,12 +946,9 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs)
synchronize_user_stack();
save_and_clear_fpu();
if (get_thread_wsaved()) {
#ifdef DEBUG_SIGNALS
printk ("Uh oh, w_saved is not zero (%d)\n", (int) get_thread_wsaved());
#endif
if (get_thread_wsaved())
do_exit (SIGSEGV);
}
err = clear_user(uc, sizeof (*uc));
/* Setup convenience variables */
......@@ -1047,12 +1015,9 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
*/
flush_user_windows();
if (get_thread_wsaved()) {
#ifdef DEBUG_SIGNALS
printk ("Uh oh, w_saved is: 0x%x\n", get_thread_wsaved());
#endif
if (get_thread_wsaved())
goto sigsegv;
}
if (((unsigned long) c) & 3){
printk ("Unaligned structure passed\n");
goto sigsegv;
......@@ -1067,12 +1032,8 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
gr = &c->mcontext.greg;
err = __get_user(pc, &((*gr)[SVR4_PC]));
err |= __get_user(npc, &((*gr)[SVR4_NPC]));
if ((pc | npc) & 3) {
#ifdef DEBUG_SIGNALS
printk ("setcontext, PC or nPC were bogus\n");
#endif
if ((pc | npc) & 3)
goto sigsegv;
}
/* Retrieve information from passed ucontext */
/* note that nPC is ored a 1, this is used to inform entry.S */
......@@ -1148,21 +1109,11 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs
sf = (struct rt_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size);
if (invalid_frame_pointer (sf, sigframe_size)) {
#ifdef DEBUG_SIGNALS
printk("rt_setup_frame32(%s:%d): invalid_frame_pointer(%p, %d)\n",
current->comm, current->pid, sf, sigframe_size);
#endif
if (invalid_frame_pointer (sf, sigframe_size))
goto sigill;
}
if (get_thread_wsaved() != 0) {
#ifdef DEBUG_SIGNALS
printk ("%s[%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
#endif
if (get_thread_wsaved() != 0)
goto sigill;
}
/* 2. Save the current process state */
if (test_thread_flag(TIF_32BIT)) {
......@@ -1317,62 +1268,6 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
}
}
#ifdef DEBUG_SIGNALS_MAPS
#define MAPS_LINE_FORMAT "%016lx-%016lx %s %016lx %02x:%02x %lu "
static inline void read_maps (void)
{
struct vm_area_struct * map, * next;
char * buffer;
ssize_t i;
buffer = (char*)__get_free_page(GFP_KERNEL);
if (!buffer)
return;
for (map = current->mm->mmap ; map ; map = next ) {
/* produce the next line */
char *line;
char str[5], *cp = str;
int flags;
dev_t dev;
unsigned long ino;
/*
* Get the next vma now (but it won't be used if we sleep).
*/
next = map->vm_next;
flags = map->vm_flags;
*cp++ = flags & VM_READ ? 'r' : '-';
*cp++ = flags & VM_WRITE ? 'w' : '-';
*cp++ = flags & VM_EXEC ? 'x' : '-';
*cp++ = flags & VM_MAYSHARE ? 's' : 'p';
*cp++ = 0;
dev = 0;
ino = 0;
if (map->vm_file != NULL) {
dev = map->vm_file->f_dentry->d_inode->i_dev;
ino = map->vm_file->f_dentry->d_inode->i_ino;
line = d_path(map->vm_file->f_dentry,
map->vm_file->f_vfsmnt,
buffer, PAGE_SIZE);
}
printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
MAJOR(dev), MINOR(dev), ino);
if (map->vm_file != NULL)
printk("%s\n", line);
else
printk("\n");
}
free_page((unsigned long)buffer);
return;
}
#endif
/* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
......@@ -1380,16 +1275,27 @@ static inline void read_maps (void)
int do_signal32(sigset_t *oldset, struct pt_regs * regs,
unsigned long orig_i0, int restart_syscall)
{
unsigned long signr;
struct k_sigaction *ka;
siginfo_t info;
int svr4_signal = current->personality == PER_SVR4;
for (;;) {
spin_lock_irq(&current->sigmask_lock);
signr = dequeue_signal(&current->blocked, &info);
spin_unlock_irq(&current->sigmask_lock);
sigset_t *mask = &current->blocked;
unsigned long signr = 0;
local_irq_disable();
if (current->sig->shared_pending.head) {
spin_lock(&current->sig->siglock);
signr = dequeue_signal(&current->sig->shared_pending, mask, &info);
spin_unlock(&current->sig->siglock);
}
if (!signr) {
spin_lock(&current->sigmask_lock);
signr = dequeue_signal(&current->pending, mask, &info);
spin_unlock(&current->sigmask_lock);
}
local_irq_enable();
if (!signr)
break;
......@@ -1410,7 +1316,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
}
current->exit_code = signr;
current->state = TASK_STOPPED;
set_current_state(TASK_STOPPED);
notify_parent(current, SIGCHLD);
schedule();
if (!(signr = current->exit_code))
......@@ -1465,8 +1371,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
case SIGSTOP: {
struct signal_struct *sig;
current->state = TASK_STOPPED;
set_current_state(TASK_STOPPED);
current->exit_code = signr;
sig = current->parent->sig;
if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags &
......@@ -1480,40 +1385,8 @@ int do_signal32(sigset_t *oldset, struct pt_regs * regs,
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
#ifdef DEBUG_SIGNALS
/* Very useful to debug dynamic linker problems */
printk ("Sig %ld going for %s[%d]...\n", signr, current->comm, current->pid);
/* On SMP we are only interested in the current
* CPU's registers.
*/
__show_regs (regs);
#ifdef DEBUG_SIGNALS_TLB
do {
extern void sparc_ultra_dump_itlb(void);
extern void sparc_ultra_dump_dtlb(void);
sparc_ultra_dump_dtlb();
sparc_ultra_dump_itlb();
} while (0);
#endif
#ifdef DEBUG_SIGNALS_TRACE
{
struct reg_window32 *rw = (struct reg_window32 *)(regs->u_regs[UREG_FP] & 0xffffffff);
unsigned int ins[8];
while (rw &&
!(((unsigned long) rw) & 0x3)) {
copy_from_user(ins, &rw->ins[0], sizeof(ins));
printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
rw = (struct reg_window32 *)(unsigned long)ins[6];
}
}
#endif
#ifdef DEBUG_SIGNALS_MAPS
printk("Maps:\n");
read_maps();
#endif
#endif
/* fall through */
/* FALLTHRU */
default:
sig_exit(signr, exit_code, &info);
/* NOT REACHED */
......
......@@ -1921,30 +1921,42 @@ sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
return -EINVAL;
}
spin_lock_irq(&current->sigmask_lock);
sig = dequeue_signal(&these, &info);
spin_lock_irq(&current->sig->siglock);
spin_lock(&current->sigmask_lock);
sig = dequeue_signal(&current->sig->shared_pending, &these, &info);
if (!sig)
sig = dequeue_signal(&current->pending, &these, &info);
if (!sig) {
/* None ready -- temporarily unblock those we're interested
in so that we'll be awakened when they arrive. */
sigset_t oldblocked = current->blocked;
sigandsets(&current->blocked, &current->blocked, &these);
recalc_sigpending();
spin_unlock_irq(&current->sigmask_lock);
timeout = MAX_SCHEDULE_TIMEOUT;
if (uts)
timeout = (timespec_to_jiffies(&ts)
+ (ts.tv_sec || ts.tv_nsec));
current->state = TASK_INTERRUPTIBLE;
timeout = schedule_timeout(timeout);
spin_lock_irq(&current->sigmask_lock);
sig = dequeue_signal(&these, &info);
current->blocked = oldblocked;
recalc_sigpending();
if (timeout) {
/* None ready -- temporarily unblock those we're
* interested while we are sleeping in so that we'll
* be awakened when they arrive. */
current->real_blocked = current->blocked;
sigandsets(&current->blocked, &current->blocked, &these);
recalc_sigpending();
spin_unlock(&current->sigmask_lock);
spin_unlock_irq(&current->sig->siglock);
current->state = TASK_INTERRUPTIBLE;
timeout = schedule_timeout(timeout);
spin_lock_irq(&current->sig->siglock);
spin_lock(&current->sigmask_lock);
sig = dequeue_signal(&current->sig->shared_pending, &these, &info);
if (!sig)
sig = dequeue_signal(&current->pending, &these, &info);
current->blocked = current->real_blocked;
siginitset(&current->real_blocked, 0);
recalc_sigpending();
}
}
spin_unlock_irq(&current->sigmask_lock);
spin_unlock(&current->sigmask_lock);
spin_unlock_irq(&current->sig->siglock);
if (sig) {
ret = sig;
......
......@@ -56,7 +56,7 @@ sys_call_table32:
/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys32_getdents
.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys32_sigpending, sys32_query_module
.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname
/*190*/ .word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
/*200*/ .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir
......@@ -115,7 +115,7 @@ sys_call_table:
/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_query_module
.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_nis_syscall, sparc64_newuname
.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname
/*190*/ .word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
.word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
/*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
......
......@@ -44,6 +44,8 @@ unsigned long mstk48t02_regs = 0UL;
unsigned long ds1287_regs = 0UL;
#endif
extern unsigned long wall_jiffies;
u64 jiffies_64;
static unsigned long mstk48t08_regs = 0UL;
......@@ -61,6 +63,8 @@ unsigned long timer_tick_offset;
unsigned long timer_tick_compare;
unsigned long timer_ticks_per_usec_quotient;
#define TICK_SIZE (tick_nsec / 1000)
static __inline__ void timer_check_rtc(void)
{
/* last time the cmos clock got updated */
......@@ -69,8 +73,8 @@ static __inline__ void timer_check_rtc(void)
/* Determine when to update the Mostek clock. */
if ((time_status & STA_UNSYNC) == 0 &&
xtime.tv_sec > last_rtc_update + 660 &&
xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
(xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
(xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec;
else
......@@ -390,7 +394,7 @@ static void __init set_system_time(void)
}
xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_usec = 0;
xtime.tv_nsec = 0;
if (mregs) {
tmp = mostek_read(mregs + MOSTEK_CREG);
......@@ -428,7 +432,7 @@ void __init clock_probe(void)
(unsigned int) (long) &unix_tod);
prom_feval(obp_gettod);
xtime.tv_sec = unix_tod;
xtime.tv_usec = 0;
xtime.tv_nsec = 0;
return;
}
......@@ -658,22 +662,58 @@ void do_settimeofday(struct timeval *tv)
return;
write_lock_irq(&xtime_lock);
/*
* This is revolting. We need to set "xtime" correctly. However, the
* value in this location is the value at the most recent update of
* wall time. Discover what correction gettimeofday() would have
* made, and then undo it!
*/
tv->tv_usec -= do_gettimeoffset();
if(tv->tv_usec < 0) {
tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
while (tv->tv_usec < 0) {
tv->tv_usec += 1000000;
tv->tv_sec--;
}
xtime = *tv;
xtime.tv_sec = tv->tv_sec;
xtime.tv_nsec = (tv->tv_usec * 1000);
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
write_unlock_irq(&xtime_lock);
}
/* Ok, my cute asm atomicity trick doesn't work anymore.
* There are just too many variables that need to be protected
* now (both members of xtime, wall_jiffies, et al.)
*/
void do_gettimeofday(struct timeval *tv)
{
unsigned long flags;
unsigned long usec, sec;
read_lock_irqsave(&xtime_lock, flags);
usec = do_gettimeoffset();
{
unsigned long lost = jiffies - wall_jiffies;
if (lost)
usec += lost * (1000000 / HZ);
}
sec = xtime.tv_sec;
usec += (xtime.tv_nsec / 1000);
read_unlock_irqrestore(&xtime_lock, flags);
while (usec >= 1000000) {
usec -= 1000000;
sec++;
}
tv->tv_sec = sec;
tv->tv_usec = usec;
}
static int set_rtc_mmss(unsigned long nowtime)
{
int real_seconds, real_minutes, chip_minutes;
......
......@@ -1515,14 +1515,6 @@ void __init paging_init(void)
pages_avail = 0;
last_valid_pfn = end_pfn = bootmem_init(&pages_avail);
#ifdef CONFIG_SUN_SERIAL
/* This does not logically belong here, but we need to
* call it at the moment we are able to use the bootmem
* allocator.
*/
sun_serial_setup();
#endif
/* Inherit non-locked OBP mappings. */
inherit_prom_mappings();
......
......@@ -14,6 +14,7 @@
#include <linux/delay.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
#include <asm/system.h>
/* Reset and reboot the machine with the command 'bcommand'. */
void prom_reboot(char *bcommand)
......@@ -33,7 +34,6 @@ void prom_feval(char *fstring)
/* We want to do this more nicely some day. */
extern void (*prom_palette)(int);
extern int serial_console;
#ifdef CONFIG_SMP
extern void smp_capture(void);
......
......@@ -201,25 +201,29 @@ raw_ctl_ioctl(struct inode *inode, struct file *filp,
}
static ssize_t
rw_raw_dev(int rw, struct file *filp, char *buf, size_t size, loff_t *offp)
rw_raw_dev(int rw, struct file *filp, const struct iovec *iov, unsigned long nr_segs, loff_t *offp)
{
const int minor = minor(filp->f_dentry->d_inode->i_rdev);
struct block_device *bdev = raw_devices[minor].binding;
struct inode *inode = bdev->bd_inode;
size_t count = iov_length(iov, nr_segs);
ssize_t ret = 0;
if (size == 0)
goto out;
ret = -EINVAL;
if (size < 0)
goto out;
ret = -ENXIO;
if (*offp >= inode->i_size)
goto out;
if (count == 0)
goto out;
if ((ssize_t)count < 0)
return -EINVAL;
if (*offp >= inode->i_size)
return -ENXIO;
if (count + *offp > inode->i_size) {
count = inode->i_size - *offp;
nr_segs = iov_shorten((struct iovec *)iov, nr_segs, count);
}
ret = generic_file_direct_IO(rw, inode, iov, *offp, nr_segs);
if (size + *offp > inode->i_size)
size = inode->i_size - *offp;
ret = generic_file_direct_IO(rw, inode, buf, *offp, size);
if (ret > 0)
*offp += ret;
out:
......@@ -227,15 +231,31 @@ rw_raw_dev(int rw, struct file *filp, char *buf, size_t size, loff_t *offp)
}
static ssize_t
raw_read(struct file *filp, char * buf, size_t size, loff_t *offp)
raw_read(struct file *filp, char *buf, size_t size, loff_t *offp)
{
return rw_raw_dev(READ, filp, buf, size, offp);
struct iovec local_iov = { .iov_base = buf, .iov_len = size};
return rw_raw_dev(READ, filp, &local_iov, 1, offp);
}
static ssize_t
raw_write(struct file *filp, const char *buf, size_t size, loff_t *offp)
{
return rw_raw_dev(WRITE, filp, (char *)buf, size, offp);
struct iovec local_iov = { .iov_base = buf, .iov_len = size};
return rw_raw_dev(WRITE, filp, &local_iov, 1, offp);
}
static ssize_t
raw_readv(struct file *filp, const struct iovec *iov, unsigned long nr_segs, loff_t *offp)
{
return rw_raw_dev(READ, filp, iov, nr_segs, offp);
}
static ssize_t
raw_writev(struct file *filp, const struct iovec *iov, unsigned long nr_segs, loff_t *offp)
{
return rw_raw_dev(WRITE, filp, iov, nr_segs, offp);
}
static struct file_operations raw_fops = {
......@@ -244,6 +264,8 @@ static struct file_operations raw_fops = {
.open = raw_open,
.release= raw_release,
.ioctl = raw_ioctl,
.readv = raw_readv,
.writev = raw_writev,
.owner = THIS_MODULE,
};
......
This diff is collapsed.
......@@ -58,6 +58,11 @@
#define TG3PCI_MAX_LAT 0x0000003f
#define TG3PCI_X_CAPS 0x00000040
#define PCIX_CAPS_RELAXED_ORDERING 0x00020000
#define PCIX_CAPS_SPLIT_MASK 0x00700000
#define PCIX_CAPS_SPLIT_SHIFT 20
#define PCIX_CAPS_BURST_MASK 0x000c0000
#define PCIX_CAPS_BURST_SHIFT 18
#define PCIX_CAPS_MAX_BURST_5704 2
#define TG3PCI_PM_CAP_PTR 0x00000041
#define TG3PCI_X_COMMAND 0x00000042
#define TG3PCI_X_STATUS 0x00000044
......@@ -109,10 +114,13 @@
#define CHIPREV_ID_5703_A0 0x1000
#define CHIPREV_ID_5703_A1 0x1001
#define CHIPREV_ID_5703_A2 0x1002
#define CHIPREV_ID_5703_A3 0x1003
#define CHIPREV_ID_5704_A0 0x2000
#define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12)
#define ASIC_REV_5700 0x07
#define ASIC_REV_5701 0x00
#define ASIC_REV_5703 0x01
#define ASIC_REV_5704 0x02
#define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8)
#define CHIPREV_5700_AX 0x70
#define CHIPREV_5700_BX 0x71
......@@ -165,6 +173,7 @@
#define PCISTATE_ROM_ENABLE 0x00000020
#define PCISTATE_ROM_RETRY_ENABLE 0x00000040
#define PCISTATE_FLAT_VIEW 0x00000100
#define PCISTATE_RETRY_SAME_DMA 0x00002000
#define TG3PCI_CLOCK_CTRL 0x00000074
#define CLOCK_CTRL_CORECLK_DISABLE 0x00000200
#define CLOCK_CTRL_RXCLK_DISABLE 0x00000400
......@@ -843,6 +852,8 @@
#define RDMAC_MODE_FIFOURUN_ENAB 0x00000080
#define RDMAC_MODE_FIFOOREAD_ENAB 0x00000100
#define RDMAC_MODE_LNGREAD_ENAB 0x00000200
#define RDMAC_MODE_SPLIT_ENABLE 0x00000800
#define RDMAC_MODE_SPLIT_RESET 0x00001000
#define RDMAC_STATUS 0x00004804
#define RDMAC_STATUS_TGTABORT 0x00000004
#define RDMAC_STATUS_MSTABORT 0x00000008
......@@ -1126,6 +1137,8 @@
#define GRC_MISC_CFG_BOARD_ID_5702FE 0x00004000
#define GRC_MISC_CFG_BOARD_ID_5703 0x00000000
#define GRC_MISC_CFG_BOARD_ID_5703S 0x00002000
#define GRC_MISC_CFG_BOARD_ID_5704 0x00000000
#define GRC_MISC_CFG_BOARD_ID_5704CIOBE 0x00004000
#define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000
#define GRC_LOCAL_CTRL 0x00006808
#define GRC_LCLCTRL_INT_ACTIVE 0x00000001
......@@ -1248,14 +1261,19 @@
#define NIC_SRAM_DATA_SIG_MAGIC 0x4b657654 /* ascii for 'KevT' */
#define NIC_SRAM_DATA_CFG 0x00000b58
#define NIC_SRAM_DATA_CFG_PHY_TYPE_MASK 0x0000000c
#define NIC_SRAM_DATA_CFG_PHY_TYPE_UNKNOWN 0x00000000
#define NIC_SRAM_DATA_CFG_PHY_TYPE_COPPER 0x00000004
#define NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER 0x00000008
#define NIC_SRAM_DATA_CFG_LED_MODE_MASK 0x00000030
#define NIC_SRAM_DATA_CFG_LED_MODE_MASK 0x0000000c
#define NIC_SRAM_DATA_CFG_LED_MODE_UNKNOWN 0x00000000
#define NIC_SRAM_DATA_CFG_LED_TRIPLE_SPD 0x00000010
#define NIC_SRAM_DATA_CFG_LED_LINK_SPD 0x00000020
#define NIC_SRAM_DATA_CFG_LED_TRIPLE_SPD 0x00000004
#define NIC_SRAM_DATA_CFG_LED_OPEN_DRAIN 0x00000004
#define NIC_SRAM_DATA_CFG_LED_LINK_SPD 0x00000008
#define NIC_SRAM_DATA_CFG_LED_OUTPUT 0x00000008
#define NIC_SRAM_DATA_CFG_PHY_TYPE_MASK 0x00000030
#define NIC_SRAM_DATA_CFG_PHY_TYPE_UNKNOWN 0x00000000
#define NIC_SRAM_DATA_CFG_PHY_TYPE_COPPER 0x00000010
#define NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER 0x00000020
#define NIC_SRAM_DATA_CFG_WOL_ENABLE 0x00000040
#define NIC_SRAM_DATA_CFG_ASF_ENABLE 0x00000080
#define NIC_SRAM_DATA_CFG_EEPROM_WP 0x00000100
#define NIC_SRAM_DATA_PHY_ID 0x00000b74
#define NIC_SRAM_DATA_PHY_ID1_MASK 0xffff0000
......@@ -1292,7 +1310,8 @@
#define NIC_SRAM_RX_BUFFER_DESC 0x00006000 /* 256 entries */
#define NIC_SRAM_RX_JUMBO_BUFFER_DESC 0x00007000 /* 256 entries */
#define NIC_SRAM_MBUF_POOL_BASE 0x00008000
#define NIC_SRAM_MBUF_POOL_SIZE 0x00018000
#define NIC_SRAM_MBUF_POOL_SIZE96 0x00018000
#define NIC_SRAM_MBUF_POOL_SIZE64 0x00018000
/* Currently this is fixed. */
#define PHY_ADDR 0x01
......@@ -1410,6 +1429,7 @@ struct tg3_tx_buffer_desc {
u32 vlan_tag;
#define TXD_VLAN_TAG_SHIFT 0
#define TXD_MSS_SHIFT 16
};
#define TXD_ADDR 0x00UL /* 64-bit */
......@@ -1660,6 +1680,12 @@ struct ring_info {
DECLARE_PCI_UNMAP_ADDR(mapping)
};
struct tx_ring_info {
struct sk_buff *skb;
DECLARE_PCI_UNMAP_ADDR(mapping)
u32 prev_vlan_tag;
};
struct tg3_config_info {
u32 flags;
};
......@@ -1737,11 +1763,13 @@ struct tg3 {
#define TG3_FLAG_RX_CHECKSUMS 0x00000004
#define TG3_FLAG_USE_LINKCHG_REG 0x00000008
#define TG3_FLAG_USE_MI_INTERRUPT 0x00000010
#define TG3_FLAG_ENABLE_ASF 0x00000020
#define TG3_FLAG_POLL_SERDES 0x00000080
#define TG3_FLAG_PHY_RESET_ON_INIT 0x00000100
#define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100
#define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200
#define TG3_FLAG_WOL_SPEED_100MB 0x00000400
#define TG3_FLAG_WOL_ENABLE 0x00001000
#define TG3_FLAG_WOL_ENABLE 0x00000800
#define TG3_FLAG_EEPROM_WRITE_PROT 0x00001000
#define TG3_FLAG_NVRAM 0x00002000
#define TG3_FLAG_NVRAM_BUFFERED 0x00004000
#define TG3_FLAG_RX_PAUSE 0x00008000
......@@ -1759,14 +1787,20 @@ struct tg3 {
#define TG3_FLAG_PAUSE_TX 0x08000000
#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000
#define TG3_FLAG_SPLIT_MODE 0x40000000
#define TG3_FLAG_INIT_COMPLETE 0x80000000
u32 msg_enable;
u32 split_mode_max_reqs;
#define SPLIT_MODE_5704_MAX_REQ 3
struct timer_list timer;
u16 timer_counter;
u16 timer_multiplier;
u32 timer_offset;
u16 asf_counter;
u16 asf_multiplier;
struct tg3_link_config link_config;
struct tg3_bufmgr_config bufmgr_config;
......@@ -1807,6 +1841,7 @@ struct tg3 {
#define PHY_ID_BCM5411 0x60008070
#define PHY_ID_BCM5701 0x60008110
#define PHY_ID_BCM5703 0x60008160
#define PHY_ID_BCM5704 0x60008190
#define PHY_ID_BCM8002 0x60010140
#define PHY_ID_SERDES 0xfeedbee0
#define PHY_ID_INVALID 0xffffffff
......@@ -1826,7 +1861,7 @@ struct tg3 {
#define KNOWN_PHY_ID(X) \
((X) == PHY_ID_BCM5400 || (X) == PHY_ID_BCM5401 || \
(X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
(X) == PHY_ID_BCM5703 || \
(X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
(X) == PHY_ID_BCM8002 || (X) == PHY_ID_SERDES)
unsigned long regs;
......@@ -1853,7 +1888,7 @@ struct tg3 {
/* TX descs are only used if TG3_FLAG_HOST_TXDS is set. */
struct tg3_tx_buffer_desc *tx_ring;
struct ring_info *tx_buffers;
struct tx_ring_info *tx_buffers;
dma_addr_t tx_desc_mapping;
struct tg3_hw_status *hw_status;
......
......@@ -5053,6 +5053,7 @@
14e4 000b BCM5703 1000BaseTX
14e4 8009 BCM5703 1000BaseTX
14e4 800a BCM5703 1000BaseTX
1648 NetXtreme BCM5704 Gigabit Ethernet
164d NetXtreme BCM5702FE Gigabit Ethernet
16a6 NetXtreme BCM5702X Gigabit Ethernet
16a7 NetXtreme BCM5703X Gigabit Ethernet
......
......@@ -34,6 +34,7 @@
#include <linux/serio.h>
#endif
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/irq.h>
......@@ -1019,6 +1020,8 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
if (!up->port_node || !up->su_type)
return;
up->port.iotype = SERIAL_IO_MEM;
/*
* First we look for Ebus-bases su's
*/
......
......@@ -382,13 +382,6 @@ static void sunzilog_receive_chars(struct uart_sunzilog_port *up,
sun_do_break();
return;
}
#ifndef CONFIG_SPARC64
/* Look for kgdb 'stop' character. */
if (ZS_IS_KGDB(up) && (ch == '\003')) {
breakpoint();
return;
}
#endif
/* A real serial line, record the character and status. */
*tty->flip.char_buf_ptr = ch;
......@@ -1152,11 +1145,11 @@ static struct zilog_layout * __init get_zs_sun4u(int chip)
static struct zilog_layout * __init get_zs_sun4cmd(int chip)
{
struct linux_prom_irqs irq_info[2];
unsigned long mapped_addr;
int zsnode, chipid, cpunode;
unsigned long mapped_addr = 0;
int zsnode, chipid, cpunode, bbnode;
if (sparc_cpu_model == sun4d) {
int bbnode, walk, no;
int walk, no;
zsnode = 0;
bbnode = 0;
......@@ -1249,7 +1242,7 @@ static struct zilog_layout * __init get_zs_sun4cmd(int chip)
} else if (zilog_irq != irq_info[0].pri) {
prom_printf("SunZilog: Inconsistent IRQ layout for Zilog %d.\n",
chip);
promt_halt();
prom_halt();
}
break;
}
......@@ -1290,7 +1283,7 @@ static struct zilog_layout * __init get_zs(int chip)
zilog_irq = 12;
res.end = (res.start + (8 - 1));
res.flags = IORESOURCE_IO;
return sbus_ioremap(&res, 0, 8, "SunZilog");
return (struct zilog_layout *) sbus_ioremap(&res, 0, 8, "SunZilog");
}
return get_zs_sun4cmd(chip);
......@@ -1649,13 +1642,10 @@ static int __init sunzilog_init(void)
/* Sun4 Zilog setup is hard coded, no probing to do. */
if (sparc_cpu_model == sun4) {
NUM_SUNZILOG = 2;
goto no_probe;
}
node = prom_getchild(prom_root_node);
if (sparc_cpu_model == sun4d) {
} else if (sparc_cpu_model == sun4d) {
int bbnode;
node = prom_getchild(prom_root_node);
NUM_SUNZILOG = 0;
while (node &&
(node = prom_searchsiblings(node, "cpu-unit"))) {
......@@ -1664,7 +1654,6 @@ static int __init sunzilog_init(void)
NUM_SUNZILOG += 2;
node = prom_getsibling(node);
}
goto no_probe;
} else if (sparc_cpu_model == sun4u) {
int central_node;
......@@ -1675,27 +1664,28 @@ static int __init sunzilog_init(void)
if (central_node != 0 && central_node != -1)
node = prom_searchsiblings(prom_getchild(central_node), "fhc");
else
node = prom_searchsiblings(node, "sbus");
node = prom_searchsiblings(prom_getchild(prom_root_node), "sbus");
if (node != 0 && node != -1)
node = prom_getchild(node);
if (node == 0 || node == -1)
return -ENODEV;
node = prom_searchsiblings(node, "zs");
if (!node)
return -ENODEV;
NUM_SUNZILOG = 2;
} else {
node = prom_getchild(prom_root_node);
node = prom_searchsiblings(node, "obio");
if (node)
node = prom_getchild(node);
if (!node)
return -ENODEV;
NUM_SUNZILOG = 2;
goto no_probe;
}
node = prom_searchsiblings(node, "zs");
if (!node)
return -ENODEV;
NUM_SUNZILOG = 2;
no_probe:
sunzilog_alloc_tables();
sunzilog_ports_init();
......
......@@ -30,10 +30,11 @@
#include <linux/compiler.h>
#include <linux/brlock.h>
#include <linux/module.h>
#include <linux/tqueue.h>
#include <linux/highmem.h>
#include <asm/kmap_types.h>
#include <asm/uaccess.h>
#include <linux/highmem.h>
#if DEBUG > 1
#define dprintk printk
......@@ -304,10 +305,25 @@ void wait_for_all_aios(struct kioctx *ctx)
schedule();
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
}
set_task_state(tsk, TASK_RUNNING);
__set_task_state(tsk, TASK_RUNNING);
remove_wait_queue(&ctx->wait, &wait);
}
/* wait_on_sync_kiocb:
* Waits on the given sync kiocb to complete.
*/
ssize_t wait_on_sync_kiocb(struct kiocb *iocb)
{
while (iocb->ki_users) {
set_current_state(TASK_UNINTERRUPTIBLE);
if (!iocb->ki_users)
break;
schedule();
}
__set_current_state(TASK_RUNNING);
return iocb->ki_user_data;
}
/* exit_aio: called when the last user of mm goes away. At this point,
* there is no way for any new requests to be submited or any of the
* io_* syscalls to be called on the context. However, there may be
......@@ -516,13 +532,36 @@ static inline struct kioctx *lookup_ioctx(unsigned long ctx_id)
int aio_complete(struct kiocb *iocb, long res, long res2)
{
struct kioctx *ctx = iocb->ki_ctx;
struct aio_ring_info *info = &ctx->ring_info;
struct aio_ring_info *info;
struct aio_ring *ring;
struct io_event *event;
unsigned long flags;
unsigned long tail;
int ret;
/* Special case handling for sync iocbs: events go directly
* into the iocb for fast handling. Note that this will not
* work if we allow sync kiocbs to be cancelled. in which
* case the usage count checks will have to move under ctx_lock
* for all cases.
*/
if (ctx == &ctx->mm->default_kioctx) {
int ret;
iocb->ki_user_data = res;
if (iocb->ki_users == 1) {
iocb->ki_users = 0;
return 1;
}
spin_lock_irq(&ctx->ctx_lock);
iocb->ki_users--;
ret = (0 == iocb->ki_users);
spin_unlock_irq(&ctx->ctx_lock);
return 0;
}
info = &ctx->ring_info;
/* add a completion event to the ring buffer.
* must be done holding ctx->ctx_lock to prevent
* other code from messing with the tail
......
This diff is collapsed.
This diff is collapsed.
......@@ -46,6 +46,8 @@ struct file_operations ext2_file_operations = {
.open = generic_file_open,
.release = ext2_release_file,
.fsync = ext2_sync_file,
.readv = generic_file_readv,
.writev = generic_file_writev,
.sendfile = generic_file_sendfile,
};
......
......@@ -619,11 +619,11 @@ ext2_get_blocks(struct inode *inode, sector_t iblock, unsigned long max_blocks,
}
static int
ext2_direct_IO(int rw, struct inode *inode, char *buf,
loff_t offset, size_t count)
ext2_direct_IO(int rw, struct inode *inode, const struct iovec *iov,
loff_t offset, unsigned long nr_segs)
{
return generic_direct_IO(rw, inode, buf,
offset, count, ext2_get_blocks);
return generic_direct_IO(rw, inode, iov,
offset, nr_segs, ext2_get_blocks);
}
static int
......
This diff is collapsed.
......@@ -1399,13 +1399,15 @@ static int ext3_releasepage(struct page *page, int wait)
* If the O_DIRECT write is intantiating holes inside i_size and the machine
* crashes then stale disk data _may_ be exposed inside the file.
*/
static int ext3_direct_IO(int rw, struct inode *inode, char *buf,
loff_t offset, size_t count)
static int ext3_direct_IO(int rw, struct inode *inode,
const struct iovec *iov, loff_t offset,
unsigned long nr_segs)
{
struct ext3_inode_info *ei = EXT3_I(inode);
handle_t *handle = NULL;
int ret;
int orphan = 0;
size_t count = iov_length(iov, nr_segs);
if (rw == WRITE) {
loff_t final_size = offset + count;
......@@ -1428,8 +1430,8 @@ static int ext3_direct_IO(int rw, struct inode *inode, char *buf,
}
}
ret = generic_direct_IO(rw, inode, buf, offset,
count, ext3_direct_io_get_blocks);
ret = generic_direct_IO(rw, inode, iov, offset,
nr_segs, ext3_direct_io_get_blocks);
out_stop:
if (handle) {
......
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