Commit 0fd8b35e authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.83

parent ce0bc3ba
......@@ -32,6 +32,14 @@ S: Department of Computer Science
S: University of Calgary
S: Calgary, Alberta, Canada
N: Ralf Baechle
E: ralf@waldorf-gmbh.de
D: Linux/MIPS port
D: Linux/68k hacker
S: Hauptstrasse 19
S: 79837 St. Blasien
S: Germany
N: Krishna Balasubramanian
E: balasub@cis.ohio-state.edu
D: Wrote SYS V IPC (part of standard kernel since 0.99.10)
......@@ -629,6 +637,13 @@ S: Dragonvagen 1 A 13
S: FIN-00330 Helsingfors
S: Finland
N: Michael Neuffer
E: neuffer@goofy.zdv.uni-mainz.de
D: developer and maintainer of the eata_dma SCSI driver
S: Zum Schiersteiner Grund 2
S: 55127 Mainz
S: Germany
N: David C. Niemi
E: niemidc@clark.net
E: niemidc@slma.com
......@@ -922,6 +937,15 @@ S: 17 Canterbury Square #101
S: Alexandria, Virginia 22304
S: USA
N: Niibe Yutaka
E: gniibe@mri.co.jp
D: PLIP driver
D: Asynchronous socket I/O in the NET code
S: Mitsubishi Research Institute, Inc.
S: ARCO Tower 1-8-1 Shimomeguro Meguro-ku
S: Tokyo 153
S: Japan
N: Orest Zborowski
E: orestz@eskimo.com
D: XFree86 and kernel development
......
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 82
SUBLEVEL = 83
ARCH = i386
......@@ -165,6 +165,7 @@ include/linux/version.h: $(CONFIGURATION) Makefile newversion
echo \#define LINUX_COMPILE_DOMAIN \"`domainname`\"; \
fi >> include/linux/version.h
@echo \#define LINUX_COMPILER \"`$(HOSTCC) -v 2>&1 | tail -1`\" >> include/linux/version.h
@echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)` >> include/linux/version.h
init/version.o: init/version.c include/linux/version.h
$(CC) $(CFLAGS) -DUTS_MACHINE='"$(ARCH)"' -c -o init/version.o init/version.c
......
......@@ -21,8 +21,8 @@
OBJECTS = head.o main.o
all:
@echo Be careful.. This works for me, not for you
all: tools/lxboot tools/bootlx vmlinux
@echo run mkfloppy on machine with floppy drive
msb: tools/lxboot tools/bootlx vmlinux
( cat tools/lxboot tools/bootlx vmlinux ) > /dev/rz0a
......
......@@ -75,13 +75,13 @@ struct pcb_struct * find_pa(unsigned long *vptb, struct pcb_struct * pcb)
#define new_vptb (0xfffffffe00000000UL)
void pal_init(void)
{
unsigned long i, rev;
unsigned long *L1;
unsigned long i, rev, sum;
unsigned long *L1, *l;
struct percpu_struct * percpu;
struct pcb_struct * pcb_pa;
/* Find the level 1 page table and duplicate it in high memory */
L1 = (unsigned long *) 0x200802000UL;
L1 = (unsigned long *) 0x200802000UL; /* (1<<33 | 1<<23 | 1<<13) */
L1[1023] = L1[1];
percpu = (struct percpu_struct *) (hwrpb.processor_offset + (unsigned long) &hwrpb),
......@@ -113,7 +113,15 @@ void pal_init(void)
halt();
}
rev = percpu->pal_revision = percpu->palcode_avail[2];
hwrpb.vptb = new_vptb;
/* update checksum: */
sum = 0;
for (l = (unsigned long *) &hwrpb; l < (unsigned long *) &hwrpb.chksum; ++l)
sum += *l;
hwrpb.chksum = sum;
printk("Ok (rev %lx)\n", rev);
/* remove the old virtual page-table mapping */
L1[1] = 0;
......
......@@ -9,6 +9,7 @@ bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD n
bool 'Normal harddisk support' CONFIG_BLK_DEV_HD n
bool 'XT harddisk support' CONFIG_BLK_DEV_XD n
bool 'Networking support' CONFIG_NET n
bool 'PCI alpha motherboard' CONFIG_PCI n
bool 'System V IPC' CONFIG_SYSVIPC n
bool 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y
......
......@@ -87,6 +87,42 @@ entMM:
rti
.end entMM
.align 5
.globl entArith
.ent entArith
entArith:
SAVE_ALL
bis $30,$30,$19
lda $27,do_entArith
jsr $26,($27),do_entArith
RESTORE_ALL
rti
.end entArith
.align 5
.globl entIF
.ent entIF
entIF:
SAVE_ALL
bis $30,$30,$19
lda $27,do_entIF
jsr $26,($27),do_entIF
RESTORE_ALL
rti
.end entIF
.align 5
.globl entUna
.ent entUna
entUna:
SAVE_ALL
bis $30,$30,$19
lda $27,do_entUna
jsr $26,($27),do_entUna
RESTORE_ALL
rti
.end entUna
.align 5
.globl sys_call_table
sys_call_table:
......
......@@ -10,6 +10,7 @@
* should be easier.
*/
#include <linux/config.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/kernel_stat.h>
......@@ -139,62 +140,125 @@ void free_irq(unsigned int irq)
halt();
}
static void handle_irq(int irq, struct pt_regs * regs)
static void handle_nmi(struct pt_regs * regs)
{
printk("Whee.. NMI received. Probable hardware error\n");
printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461));
}
static void unexpected_irq(int irq, struct pt_regs * regs)
{
int i;
printk("IO device interrupt, irq = %d\n", irq);
printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
printk("Expecting: ");
for (i = 0; i < 16; i++)
if (irq_action[i].handler)
printk("[%s:%d] ", irq_action[i].name, i);
printk("\n");
printk("64=%02x, 60=%02x, 3fa=%02x 2fa=%02x\n",
inb(0x64), inb(0x60), inb(0x3fa), inb(0x2fa));
outb(0x0c, 0x3fc);
outb(0x0c, 0x2fc);
outb(0,0x61);
outb(0,0x461);
}
static inline void handle_irq(int irq, struct pt_regs * regs)
{
struct irqaction * action = irq + irq_action;
kstat.interrupts[irq]++;
if (action->handler)
action->handler(irq, regs);
if (!action->handler) {
unexpected_irq(irq, regs);
return;
}
action->handler(irq, regs);
}
static void local_device_interrupt(unsigned long vector, struct pt_regs * regs)
{
switch (vector) {
/* com1: map to irq 4 */
case 0x900:
handle_irq(4, regs);
return;
/* com2: map to irq 3 */
case 0x920:
handle_irq(3, regs);
return;
/* keyboard: map to irq 1 */
case 0x980:
handle_irq(1, regs);
return;
/* mouse: map to irq 12 */
case 0x990:
handle_irq(12, regs);
return;
default:
printk("Unknown local interrupt %lx\n", vector);
}
}
/*
* I don't have any good documentation on the EISA hardware interrupt
* stuff: I don't know the mapping between the interrupt vector and the
* EISA interrupt number.
*
* It *seems* to be 0x8X0 for EISA interrupt X, and 0x9X0 for the
* local motherboard interrupts..
* The vector is 0x8X0 for EISA interrupt X, and 0x9X0 for the local
* motherboard interrupts.. This is for the Jensen.
*
* 0x660 - NMI?
* 0x660 - NMI
*
* 0x800 - ??? I've gotten this, but EISA irq0 shouldn't happen
* as the timer is not on the EISA bus
*
* 0x860 - ??? floppy disk (EISA irq6)
*
* 0x900 - ??? I get this at autoprobing when the EISA serial
* lines com3/com4 don't exist. It keeps coming after
* that..
* 0x800 - IRQ0 interval timer (not used, as we use the RTC timer)
* 0x810 - IRQ1 line printer (duh..)
* 0x860 - IRQ6 floppy disk
* 0x8E0 - IRQ14 SCSI controller
*
* 0x900 - COM1
* 0x920 - COM2
* 0x980 - keyboard
* 0x990 - mouse
*
* We'll see..
* The PCI version is more sane: it doesn't have the local interrupts at
* all, and has only normal PCI interrupts from devices. Happily it's easy
* enough to do a sane mapping from the Jensen.. Note that this means
* that we may have to do a hardware "ack" to a different interrupt than
* we report to the rest of the world..
*/
static void device_interrupt(unsigned long vector, struct pt_regs * regs)
{
int i;
static int nr = 0;
int irq, ack;
if (vector == 0x980 && irq_action[1].handler) {
handle_irq(1, regs);
if (vector == 0x660) {
handle_nmi(regs);
return;
}
if (nr > 3)
ack = irq = (vector - 0x800) >> 4;
#ifndef CONFIG_PCI
if (vector >= 0x900) {
local_device_interrupt(vector, regs);
return;
nr++;
printk("IO device interrupt, vector = %lx\n", vector);
printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
printk("Expecting: ");
for (i = 0; i < 16; i++)
if (irq_action[i].handler)
printk("[%s:%d] ", irq_action[i].name, i);
printk("\n");
printk("64=%02x, 60=%02x, 3fa=%02x 2fa=%02x\n",
inb(0x64), inb(0x60), inb(0x3fa), inb(0x2fa));
printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461));
}
/* irq1 is supposed to be the keyboard, silly Jensen */
if (irq == 1)
irq = 7;
#endif
printk("%d%d", irq, ack);
if (!irq)
printk(".");
else
handle_irq(irq, regs);
/* ACK the interrupt making it the lowest priority */
/* First the slave .. */
if (ack > 7) {
outb(0xC0 | (ack - 8), 0xa0);
ack = 2;
}
/* .. then the master */
outb(0xC0 | ack, 0x20);
}
static void machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs)
......
......@@ -65,12 +65,12 @@ static unsigned long find_end_memory(void)
cluster = memdesc->cluster;
for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
unsigned long tmp;
if (cluster->usage & 1)
continue;
tmp = (cluster->start_pfn + cluster->numpages) << PAGE_SHIFT;
if (tmp > high)
high = tmp;
}
/* round it up to an even number of pages.. */
high = (high + PAGE_SIZE) & (PAGE_MASK*2);
return PAGE_OFFSET + high;
}
......
......@@ -15,12 +15,33 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err)
unsigned long i;
printk("%s %ld\n", str, err);
for (i = 0 ; i++ ; i < 500000000)
printk("PC = %016lx PS = %04lx\n", regs->pc, regs->ps);
for (i = 0 ; i < 5000000000 ; i++)
/* pause */;
halt();
}
asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask, unsigned long a2, struct pt_regs * regs)
{
printk("Arithmetic trap: %02lx %016lx\n", summary, write_mask);
die_if_kernel("Arithmetic fault", regs, 0);
}
asmlinkage void do_entIF(unsigned long type, unsigned long a1, unsigned long a2, struct pt_regs * regs)
{
die_if_kernel("Instruction fault", regs, type);
}
asmlinkage void do_entUna(unsigned long va, unsigned long opcode, unsigned long reg, struct pt_regs * regs)
{
printk("Unaligned trap: %016lx %ld %ld\n", va, opcode, reg);
die_if_kernel("Unaligned", regs, 0);
}
extern asmlinkage void entMM(void);
extern asmlinkage void entIF(void);
extern asmlinkage void entArith(void);
extern asmlinkage void entUna(void);
void trap_init(void)
{
......@@ -30,5 +51,9 @@ void trap_init(void)
"___tmp:\tldgp %0,0(%0)"
: "=r" (gptr));
wrkgp(gptr);
wrent(entArith, 1);
wrent(entMM, 2);
wrent(entIF, 3);
wrent(entUna, 4);
}
......@@ -44,12 +44,9 @@ asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr,
if (mmcsr == 1)
goto bad_area;
for (vma = current->mm->mmap ; ; vma = vma->vm_next) {
if (!vma)
goto bad_area;
if (vma->vm_end > address)
break;
}
vma = find_vma(current, address);
if (!vma)
goto bad_area;
if (vma->vm_start <= address)
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
......
......@@ -91,7 +91,7 @@ extern unsigned long free_area_init(unsigned long, unsigned long);
* unmaps the bootup page table (as we're now in KSEG, so we don't need it).
*
* The bootup sequence put the virtual page table into high memory: that
* means that we cah change the L1 page table by just using VL1p below.
* means that we can change the L1 page table by just using VL1p below.
*/
#define VL1p ((unsigned long *) 0xffffffffffffe000)
unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
......
......@@ -187,6 +187,7 @@ if [ "$CONFIG_SBPCD" = "y" ]; then
fi
fi
fi
bool 'Aztech/Orchid/Okano/Wearnes (non IDE) CDROM support' CONFIG_AZTCD n
comment 'Filesystems'
......
......@@ -550,17 +550,17 @@ void burst_bridge(unsigned char bus,unsigned char dev_fn,unsigned char pos, int
for (i=0;i<OPTIMISATION_NUM;i++)
{
printk(" %s : ",optimisation[i].type);
if (bridge_mapping[pos+i].adress==0) printk("Not supported.");
if (bridge_mapping[pos+i].address==0) printk("Not supported.");
else {
pcibios_read_config_byte(
bus, dev_fn, bridge_mapping[pos+i].adress, &val);
bus, dev_fn, bridge_mapping[pos+i].address, &val);
if ((val & bridge_mapping[pos+i].mask)==bridge_mapping[pos+i].value)
{
printk("%s.",optimisation[i].on);
if (turn_on==0)
{
pcibios_write_config_byte(
bus, dev_fn, bridge_mapping[pos+i].adress,
bus, dev_fn, bridge_mapping[pos+i].address,
(val | bridge_mapping[pos+i].mask) -
bridge_mapping[pos+i].value);
printk("Changed! now %s.",optimisation[i].off);
......@@ -570,7 +570,7 @@ void burst_bridge(unsigned char bus,unsigned char dev_fn,unsigned char pos, int
if (turn_on==1)
{
pcibios_write_config_byte(
bus, dev_fn, bridge_mapping[pos+i].adress,
bus, dev_fn, bridge_mapping[pos+i].address,
(val & (0xff-bridge_mapping[pos+i].mask)) +
bridge_mapping[pos+i].value);
printk("Changed! now %s.",optimisation[i].on);
......@@ -644,7 +644,7 @@ void add_pci_resource(unsigned char bus, unsigned char dev_fn)
{
printk("Unknown PCI device. PCI Vendor id=%x. PCI Device id=%x.\n",
vendor_id & 0xffff,device_id & 0xffff);
printk("PLEASE MAIL POTTER@CAO-VLSI.IBP.FR your harware description and /proc/pci.\n");
printk("PLEASE MAIL POTTER@CAO-VLSI.IBP.FR your hardware description and /proc/pci.\n");
return;
}
/*
......
......@@ -53,6 +53,8 @@ asmlinkage int sys_idle(void)
*/
void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp)
{
regs->cs = USER_CS;
regs->ds = regs->es = regs->ss = regs->fs = regs->gs = USER_DS;
regs->eip = eip;
regs->esp = esp;
}
......
......@@ -152,17 +152,14 @@ static void put_long(struct vm_area_struct * vma, unsigned long addr,
}
}
static struct vm_area_struct * find_vma(struct task_struct * tsk, unsigned long addr)
static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, unsigned long addr)
{
struct vm_area_struct * vma;
addr &= PAGE_MASK;
for (vma = tsk->mm->mmap ; ; vma = vma->vm_next) {
if (!vma)
return NULL;
if (vma->vm_end > addr)
break;
}
vma = find_vma(tsk,addr);
if (!vma)
return NULL;
if (vma->vm_start <= addr)
return vma;
if (!(vma->vm_flags & VM_GROWSDOWN))
......@@ -181,7 +178,7 @@ static struct vm_area_struct * find_vma(struct task_struct * tsk, unsigned long
static int read_long(struct task_struct * tsk, unsigned long addr,
unsigned long * result)
{
struct vm_area_struct * vma = find_vma(tsk, addr);
struct vm_area_struct * vma = find_extend_vma(tsk, addr);
if (!vma)
return -EIO;
......@@ -223,7 +220,7 @@ static int read_long(struct task_struct * tsk, unsigned long addr,
static int write_long(struct task_struct * tsk, unsigned long addr,
unsigned long data)
{
struct vm_area_struct * vma = find_vma(tsk, addr);
struct vm_area_struct * vma = find_extend_vma(tsk, addr);
if (!vma)
return -EIO;
......
......@@ -14,6 +14,7 @@
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
#include <asm/system.h>
#include <asm/segment.h>
......@@ -33,12 +34,9 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
/* get the address */
__asm__("movl %%cr2,%0":"=r" (address));
for (vma = current->mm->mmap ; ; vma = vma->vm_next) {
if (!vma)
goto bad_area;
if (vma->vm_end > address)
break;
}
vma = find_vma(current, address);
if (!vma)
goto bad_area;
if (vma->vm_start <= address)
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
......
......@@ -10,7 +10,7 @@
#
#
# Fake compessed boot
# Fake compressed boot
#
zImage: $(CONFIGURE) $(TOPDIR)/vmlinux
ln -fs $(TOPDIR)/vmlinux zImage
......
......@@ -19,7 +19,7 @@
$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
OBJS = process.o signal.o entry.o traps.o irq.o ptrace.o cache.o resume.o \
ioport.o bootinfo.o
ioport.o setup.o bios32.o
all: kernel.o head.o
......
/*
* bios 32 replacement
*/
unsigned long bios32_init(unsigned long memory_start, unsigned long memory_end)
{
return memory_start;
}
/*
* arch/mips/kernel/bootinfo.c
*
* Copyright (C) 1995 Ralf Baechle
*
* Kernel data passed by the loader
*/
#include <asm/bootinfo.h>
/*
* Initialise this structure so that it will be placed in the
* .data section of the object file
*/
struct bootinfo boot_info = BOOT_INFO;
......@@ -41,6 +41,10 @@ ENOSYS = 38
.set noreorder
.align 4
handle_bottom_half:
/*
* If your assembler breaks on the next line it's
* time to update!
*/
lui s0,%hi(_intr_count)
lw s1,%lo(_intr_count)(s0)
mfc0 s3,CP0_STATUS # Enable IRQs
......@@ -286,7 +290,7 @@ poll_second: li t1,0x0f
.align 5
spurious_interrupt:
/*
* Nothing happend... (whistle)
* Nothing happened... (whistle)
*/
lui t1,%hi(_spurious_count)
lw t0,%lo(_spurious_count)(t1)
......
......@@ -306,7 +306,7 @@ setup_paging:
mtc0 zero,CP0_INDEX
la t0,TLB_ROOT
dmtc0 t0,CP0_ENTRYHI
li t0,_swapper_pg_dir
la t0,_swapper_pg_dir
srl t0,t0,6
ori t0,t0,MODE_ALIAS # uncachable, dirty, valid
dmtc0 t0,CP0_ENTRYLO0
......@@ -315,8 +315,9 @@ setup_paging:
/*
* Make page zero unaccessible to catch zero references
*/
la t0,_pg0
li t0,KERNELBASE
addiu t0,_pg0
addu t0,t1
sw zero,(t0)
/*
* Load the context register with a value that allows
......@@ -437,7 +438,7 @@ final:
.data
/*
* Instead of Intel's strage and unportable segment descriptor magic
* Instead of Intel's strange and unportable segment descriptor magic
* we difference user and kernel space by their address.
* Kernel space (== physical memory) is mapped at KSEG[01],
* User space is mapped at 0x0.
......@@ -446,7 +447,7 @@ final:
_segment_fs: .word KERNEL_DS
/*
* Inital mapping tables for supported Mips boards.
* Initial mapping tables for supported Mips boards.
* First item is always the number of wired TLB entries,
* following by EntryHi/EntryLo pairs and page mask.
* Since everything must be quad-aligned (8) we insert
......@@ -501,7 +502,7 @@ map0_tyne: .word 3 # no. of wired TLB entries
* Initial mapping for ACER PICA-61 boards.
* FIXME: These are rather preliminary since many drivers,
* such as serial, parallel, scsi and ethernet need some
* changes to distuingish between "local" (built-in) and
* changes to distinguish between "local" (built-in) and
* "optional" (ISA/PCI) I/O hardware.
* Local video ram is mapped to the same location as the
* bios maps it to. Console driver has been changed
......
......@@ -15,10 +15,6 @@ typedef struct resource_entry_t {
struct resource_entry_t *next;
} resource_entry_t;
static resource_entry_t iolist = { 0, 0, "", NULL };
static resource_entry_t iotable[IOTABLE_SIZE];
/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
{
......
/*
* linux/kernel/irq.c
* linux/arch/mips/kernel/irq.c
*
* Copyright (C) 1992 Linus Torvalds
*
......@@ -12,14 +12,7 @@
/*
* IRQ's are in fact implemented a bit like signal handlers for the kernel.
* The same sigaction struct is used, and with similar semantics (ie there
* is a SA_INTERRUPT flag etc). Naturally it's not a 1:1 relation, but there
* are similarities.
*
* sa_handler(int irq_NR) is the default function called (0 if no).
* sa_mask is horribly ugly (I won't even mention it)
* sa_flags contains various info: SA_INTERRUPT etc
* sa_restorer is the unused
* Naturally it's not a 1:1 relation, but there are similarities.
*/
#include <linux/ptrace.h>
......@@ -28,6 +21,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/timex.h>
#include <asm/system.h>
#include <asm/io.h>
......@@ -90,7 +84,14 @@ extern void bad_interrupt(void);
/*
* Initial irq handlers.
*/
static struct sigaction irq_sigaction[16] = {
struct irqaction {
void (*handler)(int, struct pt_regs *);
unsigned long flags;
unsigned long mask;
const char *name;
};
static struct irqaction irq_action[16] = {
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
......@@ -104,15 +105,15 @@ static struct sigaction irq_sigaction[16] = {
int get_irq_list(char *buf)
{
int i, len = 0;
struct sigaction * sa = irq_sigaction;
struct irqaction * action = irq_action;
for (i = 0 ; i < 16 ; i++, sa++) {
if (!sa->sa_handler)
for (i = 0 ; i < 16 ; i++, action++) {
if (!action->handler)
continue;
len += sprintf(buf+len, "%2d: %8d %c %s\n",
i, kstat.interrupts[i],
(sa->sa_flags & SA_INTERRUPT) ? '+' : ' ',
(char *) sa->sa_mask);
(action->flags & SA_INTERRUPT) ? '+' : ' ',
action->name);
}
return len;
}
......@@ -126,10 +127,10 @@ int get_irq_list(char *buf)
*/
asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
{
struct sigaction * sa = irq + irq_sigaction;
struct irqaction * action = irq + irq_action;
kstat.interrupts[irq]++;
sa->sa_handler((int) regs);
action->handler(irq, regs);
}
/*
......@@ -139,38 +140,38 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
*/
asmlinkage void do_fast_IRQ(int irq)
{
struct sigaction * sa = irq + irq_sigaction;
struct irqaction * action = irq + irq_action;
kstat.interrupts[irq]++;
sa->sa_handler(irq);
action->handler(irq, NULL);
}
#define SA_PROBE SA_ONESHOT
/*
* Using "struct sigaction" is slightly silly, but there
* are historical reasons and it works well, so..
*/
static int irqaction(unsigned int irq, struct sigaction * new_sa)
int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
unsigned long irqflags, const char * devname)
{
struct sigaction * sa;
struct irqaction * action;
unsigned long flags;
if (irq > 15)
return -EINVAL;
sa = irq + irq_sigaction;
if (sa->sa_handler)
action = irq + irq_action;
if (action->handler)
return -EBUSY;
if (!new_sa->sa_handler)
if (!handler)
return -EINVAL;
save_flags(flags);
cli();
*sa = *new_sa;
/*
* FIXME: Does the SA_INTERRUPT flag make any sense on the MIPS???
*/
if (!(sa->sa_flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */
if (sa->sa_flags & SA_INTERRUPT)
action->handler = handler;
action->flags = irqflags;
action->mask = 0;
action->name = devname;
if (!(action->flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */
/*
* FIXME: Does the SA_INTERRUPT flag make any sense on MIPS???
*/
if (action->flags & SA_INTERRUPT)
set_intr_gate(irq,fast_interrupt);
else
set_intr_gate(irq,interrupt);
......@@ -188,28 +189,16 @@ static int irqaction(unsigned int irq, struct sigaction * new_sa)
return 0;
}
int request_irq(unsigned int irq, void (*handler)(int),
unsigned long flags, const char * devname)
{
struct sigaction sa;
sa.sa_handler = handler;
sa.sa_flags = flags;
sa.sa_mask = (unsigned long) devname;
sa.sa_restorer = NULL;
return irqaction(irq,&sa);
}
void free_irq(unsigned int irq)
{
struct sigaction * sa = irq + irq_sigaction;
struct irqaction * action = irq + irq_action;
unsigned long flags;
if (irq > 15) {
printk("Trying to free IRQ%d\n",irq);
return;
}
if (!sa->sa_handler) {
if (!action->handler) {
printk("Trying to free free IRQ%d\n",irq);
return;
}
......@@ -223,26 +212,14 @@ void free_irq(unsigned int irq)
outb(cache_A1,0xA1);
}
set_intr_gate(irq,bad_interrupt);
sa->sa_handler = NULL;
sa->sa_flags = 0;
sa->sa_mask = 0;
sa->sa_restorer = NULL;
action->handler = NULL;
action->flags = 0;
action->mask = 0;
action->name = NULL;
restore_flags(flags);
}
#if 0
/*
* handle fpu errors
*/
static void math_error_irq(int cpl)
{
if (!hard_math)
return;
handle_fpe();
}
#endif
static void no_action(int cpl) { }
static void no_action(int cpl, struct pt_regs * regs) { }
unsigned int probe_irq_on (void)
{
......@@ -300,6 +277,10 @@ void init_IRQ(void)
{
int i;
/* set the clock to 100 Hz */
outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */
outb_p(LATCH & 0xff , 0x40); /* LSB */
outb(LATCH >> 8 , 0x40); /* MSB */
for (i = 0; i < 16 ; i++)
set_intr_gate(i, bad_interrupt);
if (request_irq(2, no_action, SA_INTERRUPT, "cascade"))
......
......@@ -27,17 +27,6 @@
#include <asm/mipsconfig.h>
#include <asm/stackframe.h>
/*
* Tell us the machine setup..
*/
#pragma char wp_works_ok = 0; /* set if paging hardware honours WP */
char wait_available; /* set if the "wait" instruction available */
/*
* Bus types ..
*/
int EISA_bus = 0;
asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
/*
......@@ -115,7 +104,7 @@ unsigned long copy_thread(int nr, unsigned long clone_flags, struct task_struct
/*
* New tasks loose permission to use the fpu. This accelerates context
* switching for non fp programms, which true for the most programms.
* switching for non fp programs, which true for the most programs.
*/
p->tss.cp0_status = regs->cp0_status &
~(ST0_CU1|ST0_CU0|ST0_KSU|ST0_ERL|ST0_EXL);
......
......@@ -152,17 +152,14 @@ static void put_long(struct vm_area_struct * vma, unsigned long addr,
}
}
static struct vm_area_struct * find_vma(struct task_struct * tsk, unsigned long addr)
static struct vm_area_struct * find_extend_vma(struct task_struct * tsk, unsigned long addr)
{
struct vm_area_struct * vma;
addr &= PAGE_MASK;
for (vma = tsk->mm->mmap ; ; vma = vma->vm_next) {
if (!vma)
return NULL;
if (vma->vm_end > addr)
break;
}
vma = find_vma(tsk, addr);
if (!vma)
return NULL;
if (vma->vm_start <= addr)
return vma;
if (!(vma->vm_flags & VM_GROWSDOWN))
......@@ -181,7 +178,7 @@ static struct vm_area_struct * find_vma(struct task_struct * tsk, unsigned long
static int read_long(struct task_struct * tsk, unsigned long addr,
unsigned long * result)
{
struct vm_area_struct * vma = find_vma(tsk, addr);
struct vm_area_struct * vma = find_extend_vma(tsk, addr);
if (!vma)
return -EIO;
......@@ -223,7 +220,7 @@ static int read_long(struct task_struct * tsk, unsigned long addr,
static int write_long(struct task_struct * tsk, unsigned long addr,
unsigned long data)
{
struct vm_area_struct * vma = find_vma(tsk, addr);
struct vm_area_struct * vma = find_extend_vma(tsk, addr);
if (!vma)
return -EIO;
......
/*
* linux/arch/mips/kernel/setup.c
*
* Copyright (C) 1995 Linus Torvalds
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/malloc.h>
#include <linux/ldt.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/tty.h>
#include <asm/bootinfo.h>
#include <asm/segment.h>
#include <asm/system.h>
/*
* Tell us the machine setup..
*/
char wait_available; /* set if the "wait" instruction available */
/*
* Bus types ..
*/
int EISA_bus = 0;
/*
* Setup options
*/
struct drive_info_struct drive_info;
struct screen_info screen_info;
unsigned char aux_device_present;
extern int ramdisk_size;
extern int root_mountflags;
extern int end;
extern char empty_zero_page[PAGE_SIZE];
/*
* Initialise this structure so that it will be placed in the
* .data section of the object file
*/
struct bootinfo boot_info = BOOT_INFO;
/*
* This is set up by the setup-routine at boot-time
*/
#define PARAM empty_zero_page
#define EXT_MEM (boot_info.memupper)
#define DRIVE_INFO (boot_info.drive_info)
#define SCREEN_INFO (screen_info)
#define MOUNT_ROOT_RDONLY (boot_info.mount_root_rdonly)
#define RAMDISK_SIZE (boot_info.ramdisk_size)
#if 0
#define ORIG_ROOT_DEV (*(unsigned short *) (PARAM+0x1FC))
#define AUX_DEVICE_INFO (*(unsigned char *) (PARAM+0x1FF))
#endif
#define COMMAND_LINE (boot_info.command_line)
static char command_line[CL_SIZE] = { 0, };
void setup_arch(char **cmdline_p,
unsigned long * memory_start_p, unsigned long * memory_end_p)
{
unsigned long memory_start, memory_end;
char c = ' ', *to = command_line, *from = COMMAND_LINE;
int len = 0;
#if 0
ROOT_DEV = ORIG_ROOT_DEV;
#endif
drive_info = DRIVE_INFO;
screen_info = SCREEN_INFO;
#if 0
aux_device_present = AUX_DEVICE_INFO;
#endif
memory_end = EXT_MEM;
memory_end &= PAGE_MASK;
ramdisk_size = RAMDISK_SIZE;
if (MOUNT_ROOT_RDONLY)
root_mountflags |= MS_RDONLY;
memory_start = (unsigned long) &end - KERNELBASE;
for (;;) {
if (c == ' ' && *(unsigned long *)from == *(unsigned long *)"mem=") {
memory_end = simple_strtoul(from+4, &from, 0);
if ( *from == 'K' || *from == 'k' ) {
memory_end = memory_end << 10;
from++;
} else if ( *from == 'M' || *from == 'm' ) {
memory_end = memory_end << 20;
from++;
}
}
c = *(from++);
if (!c)
break;
if (CL_SIZE <= ++len)
break;
*(to++) = c;
}
*to = '\0';
*cmdline_p = command_line;
*memory_start_p = memory_start;
*memory_end_p = memory_end;
}
......@@ -244,7 +244,7 @@ void do_cpu(struct pt_regs *regs)
case 0x44000000:
case 0xc4000000:
case 0xe4000000:
printk("CP1 instruction - enabeling cp1.\n");
printk("CP1 instruction - enabling cp1.\n");
regs->cp0_status |= ST0_CU1;
/*
* No need to handle branch delay slots
......@@ -252,7 +252,7 @@ void do_cpu(struct pt_regs *regs)
break;
default:
/*
* This wasn't a cp1 instruction and therfore illegal.
* This wasn't a cp1 instruction and therefore illegal.
* Default is to kill the process.
*/
send_sig(SIGILL, current, 1);
......@@ -289,7 +289,7 @@ void do_watch(struct pt_regs *regs)
void do_reserved(struct pt_regs *regs)
{
/*
* Game over - no way to handle this if it ever occours.
* Game over - no way to handle this if it ever occurs.
* Most probably caused by a new unknown cpu type or a
* after another deadly hard/software error.
*/
......
......@@ -14,7 +14,7 @@
.c.s:
$(CC) $(CFLAGS) -S $<
OBJS = fault.o
OBJS = fault.o init.o
mm.o: $(OBJS)
$(LD) -r -o mm.o $(OBJS)
......
/*
* arch/mips/mm/memory.c
* arch/mips/mm/fault.c
*
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
* Ported to MIPS by Ralf Baechle
......@@ -20,12 +20,7 @@
#include <asm/segment.h>
#include <asm/mipsconfig.h>
extern unsigned long pg0[1024]; /* page table for 0-4MB for everybody */
extern void scsi_mem_init(unsigned long);
extern void sound_mem_init(void);
extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void);
extern void die_if_kernel(char *, struct pt_regs *, long);
/*
* This routine handles page faults. It determines the address,
......@@ -42,12 +37,9 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
__asm__("dmfc0\t%0,$8"
: "=r" (address));
for (vma = current->mm->mmap ; ; vma = vma->vm_next) {
if (!vma)
goto bad_area;
if (vma->vm_end > address)
break;
}
vma = find_vma(current, address);
if (!vma)
goto bad_area;
if (vma->vm_start <= address)
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
......@@ -117,227 +109,3 @@ printk("Bad Area...\n");
die_if_kernel("Oops", regs, error_code);
do_exit(SIGKILL);
}
/*
* BAD_PAGE is the page that is used for page faults when linux
* is out-of-memory. Older versions of linux just did a
* do_exit(), but using this instead means there is less risk
* for a process dying in kernel mode, possibly leaving a inode
* unused etc..
*
* BAD_PAGETABLE is the accompanying page-table: it is initialized
* to point to BAD_PAGE entries.
*
* ZERO_PAGE is a special page that is used for zero-initialized
* data and COW.
*/
unsigned long __bad_pagetable(void)
{
extern char empty_bad_page_table[PAGE_SIZE];
unsigned long dummy;
__asm__ __volatile__(
".set\tnoreorder\n\t"
"1:\tsw\t%2,(%0)\n\t"
"subu\t%1,%1,1\n\t"
"bne\t$0,%1,1b\n\t"
"addiu\t%0,%0,1\n\t"
".set\treorder"
:"=r" (dummy),
"=r" (dummy)
:"r" (BAD_PAGE + PAGE_TABLE),
"0" ((long) empty_bad_page_table),
"1" (PTRS_PER_PAGE));
return (unsigned long) empty_bad_page_table;
}
unsigned long __bad_page(void)
{
extern char empty_bad_page[PAGE_SIZE];
unsigned long dummy;
__asm__ __volatile__(
".set\tnoreorder\n\t"
"1:\tsw\t$0,(%0)\n\t"
"subu\t%1,%1,1\n\t"
"bne\t$0,%1,1b\n\t"
"addiu\t%0,%0,1\n\t"
".set\treorder"
:"=r" (dummy),
"=r" (dummy)
:"0" ((long) empty_bad_page),
"1" (PTRS_PER_PAGE));
return (unsigned long) empty_bad_page;
}
unsigned long __zero_page(void)
{
extern char empty_zero_page[PAGE_SIZE];
unsigned long dummy;
__asm__ __volatile__(
".set\tnoreorder\n\t"
"1:\tsw\t$0,(%0)\n\t"
"subu\t%1,%1,1\n\t"
"bne\t$0,%1,1b\n\t"
"addiu\t%0,%0,1\n\t"
".set\treorder"
:"=r" (dummy),
"=r" (dummy)
:"0" ((long) empty_zero_page),
"1" (PTRS_PER_PAGE));
return (unsigned long) empty_zero_page;
}
void show_mem(void)
{
int i,free = 0,total = 0,reserved = 0;
int shared = 0;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = high_memory >> PAGE_SHIFT;
while (i-- > 0) {
total++;
if (mem_map[i] & MAP_PAGE_RESERVED)
reserved++;
else if (!mem_map[i])
free++;
else
shared += mem_map[i]-1;
}
printk("%d pages of RAM\n",total);
printk("%d free pages\n",free);
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
show_buffers();
#ifdef CONFIG_NET
show_net_buffers();
#endif
}
extern unsigned long free_area_init(unsigned long, unsigned long);
/*
* paging_init() sets up the page tables - note that the first 4MB are
* already mapped by head.S.
*
* This routines also unmaps the page at virtual kernel address 0, so
* that we can trap those pesky NULL-reference errors in the kernel.
*/
unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
{
unsigned long * pg_dir;
unsigned long * pg_table;
unsigned long tmp;
unsigned long address;
start_mem = PAGE_ALIGN(start_mem);
address = 0;
pg_dir = swapper_pg_dir;
while (address < end_mem) {
tmp = *pg_dir;
tmp &= PAGE_MASK;
if (!tmp) {
tmp = start_mem;
start_mem += PAGE_SIZE;
}
/*
* also map it in at 0x00000000 for init
*/
*pg_dir = tmp | PAGE_TABLE;
pg_dir++;
pg_table = (unsigned long *) (tmp & PAGE_MASK);
for (tmp = 0 ; tmp < PTRS_PER_PAGE ; tmp++,pg_table++) {
if (address < end_mem)
*pg_table = address | PAGE_SHARED;
else
*pg_table = 0;
address += PAGE_SIZE;
}
}
#if KERNELBASE == KSEG0
cacheflush();
#endif
invalidate();
return free_area_init(start_mem, end_mem);
}
void mem_init(unsigned long start_mem, unsigned long end_mem)
{
int codepages = 0;
int reservedpages = 0;
int datapages = 0;
unsigned long tmp;
extern int etext;
end_mem &= PAGE_MASK;
high_memory = end_mem;
/* mark usable pages in the mem_map[] */
start_mem = PAGE_ALIGN(start_mem);
while (start_mem < high_memory) {
mem_map[MAP_NR(start_mem)] = 0;
start_mem += PAGE_SIZE;
}
#ifdef CONFIG_SCSI
scsi_mem_init(high_memory);
#endif
#ifdef CONFIG_SOUND
sound_mem_init();
#endif
for (tmp = 0 ; tmp < high_memory ; tmp += PAGE_SIZE) {
if (mem_map[MAP_NR(tmp)]) {
/*
* We don't have any reserved pages on the
* MIPS systems supported until now
*/
if (0)
reservedpages++;
else if (tmp < ((unsigned long) &etext - KERNELBASE))
codepages++;
else
datapages++;
continue;
}
mem_map[MAP_NR(tmp)] = 1;
free_page(tmp);
}
tmp = nr_free_pages << PAGE_SHIFT;
printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
tmp >> 10,
high_memory >> 10,
codepages << (PAGE_SHIFT-10),
reservedpages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10));
invalidate();
return;
}
void si_meminfo(struct sysinfo *val)
{
int i;
i = high_memory >> PAGE_SHIFT;
val->totalram = 0;
val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT;
val->bufferram = buffermem;
while (i-- > 0) {
if (mem_map[i] & MAP_PAGE_RESERVED)
continue;
val->totalram++;
if (!mem_map[i])
continue;
val->sharedram += mem_map[i]-1;
}
val->totalram <<= PAGE_SHIFT;
val->sharedram <<= PAGE_SHIFT;
return;
}
/*
* arch/mips/mm/init.c
*
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
* Ported to MIPS by Ralf Baechle
*/
#include <linux/config.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/head.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/mipsconfig.h>
extern unsigned long pg0[1024]; /* page table for 0-4MB for everybody */
extern void scsi_mem_init(unsigned long);
extern void sound_mem_init(void);
extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void);
/*
* BAD_PAGE is the page that is used for page faults when linux
* is out-of-memory. Older versions of linux just did a
* do_exit(), but using this instead means there is less risk
* for a process dying in kernel mode, possibly leaving a inode
* unused etc..
*
* BAD_PAGETABLE is the accompanying page-table: it is initialized
* to point to BAD_PAGE entries.
*
* ZERO_PAGE is a special page that is used for zero-initialized
* data and COW.
*/
unsigned long __bad_pagetable(void)
{
extern char empty_bad_page_table[PAGE_SIZE];
unsigned long dummy;
__asm__ __volatile__(
".set\tnoreorder\n\t"
"1:\tsw\t%2,(%0)\n\t"
"subu\t%1,%1,1\n\t"
"bne\t$0,%1,1b\n\t"
"addiu\t%0,%0,1\n\t"
".set\treorder"
:"=r" (dummy),
"=r" (dummy)
:"r" (BAD_PAGE + PAGE_TABLE),
"0" ((long) empty_bad_page_table),
"1" (PTRS_PER_PAGE));
return (unsigned long) empty_bad_page_table;
}
unsigned long __bad_page(void)
{
extern char empty_bad_page[PAGE_SIZE];
unsigned long dummy;
__asm__ __volatile__(
".set\tnoreorder\n\t"
"1:\tsw\t$0,(%0)\n\t"
"subu\t%1,%1,1\n\t"
"bne\t$0,%1,1b\n\t"
"addiu\t%0,%0,1\n\t"
".set\treorder"
:"=r" (dummy),
"=r" (dummy)
:"0" ((long) empty_bad_page),
"1" (PTRS_PER_PAGE));
return (unsigned long) empty_bad_page;
}
unsigned long __zero_page(void)
{
extern char empty_zero_page[PAGE_SIZE];
unsigned long dummy;
__asm__ __volatile__(
".set\tnoreorder\n\t"
"1:\tsw\t$0,(%0)\n\t"
"subu\t%1,%1,1\n\t"
"bne\t$0,%1,1b\n\t"
"addiu\t%0,%0,1\n\t"
".set\treorder"
:"=r" (dummy),
"=r" (dummy)
:"0" ((long) empty_zero_page),
"1" (PTRS_PER_PAGE));
return (unsigned long) empty_zero_page;
}
void show_mem(void)
{
int i,free = 0,total = 0,reserved = 0;
int shared = 0;
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
i = high_memory >> PAGE_SHIFT;
while (i-- > 0) {
total++;
if (mem_map[i] & MAP_PAGE_RESERVED)
reserved++;
else if (!mem_map[i])
free++;
else
shared += mem_map[i]-1;
}
printk("%d pages of RAM\n",total);
printk("%d free pages\n",free);
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
show_buffers();
#ifdef CONFIG_NET
show_net_buffers();
#endif
}
extern unsigned long free_area_init(unsigned long, unsigned long);
/*
* paging_init() sets up the page tables - note that the first 4MB are
* already mapped by head.S.
*
* This routines also unmaps the page at virtual kernel address 0, so
* that we can trap those pesky NULL-reference errors in the kernel.
*/
unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
{
unsigned long * pg_dir;
unsigned long * pg_table;
unsigned long tmp;
unsigned long address;
start_mem = PAGE_ALIGN(start_mem);
address = 0;
pg_dir = swapper_pg_dir;
while (address < end_mem) {
tmp = *pg_dir;
tmp &= PAGE_MASK;
if (!tmp) {
tmp = start_mem;
start_mem += PAGE_SIZE;
}
/*
* also map it in at 0x00000000 for init
*/
*pg_dir = tmp | PAGE_TABLE;
pg_dir++;
pg_table = (unsigned long *) (tmp & PAGE_MASK);
for (tmp = 0 ; tmp < PTRS_PER_PAGE ; tmp++,pg_table++) {
if (address < end_mem)
*pg_table = address | PAGE_SHARED;
else
*pg_table = 0;
address += PAGE_SIZE;
}
}
#if KERNELBASE == KSEG0
cacheflush();
#endif
invalidate();
return free_area_init(start_mem, end_mem);
}
void mem_init(unsigned long start_mem, unsigned long end_mem)
{
int codepages = 0;
int reservedpages = 0;
int datapages = 0;
unsigned long tmp;
extern int etext;
end_mem &= PAGE_MASK;
high_memory = end_mem;
/* mark usable pages in the mem_map[] */
start_mem = PAGE_ALIGN(start_mem);
while (start_mem < high_memory) {
mem_map[MAP_NR(start_mem)] = 0;
start_mem += PAGE_SIZE;
}
#ifdef CONFIG_SCSI
scsi_mem_init(high_memory);
#endif
#ifdef CONFIG_SOUND
sound_mem_init();
#endif
for (tmp = 0 ; tmp < high_memory ; tmp += PAGE_SIZE) {
if (mem_map[MAP_NR(tmp)]) {
/*
* We don't have any reserved pages on the
* MIPS systems supported until now
*/
if (0)
reservedpages++;
else if (tmp < ((unsigned long) &etext - KERNELBASE))
codepages++;
else
datapages++;
continue;
}
mem_map[MAP_NR(tmp)] = 1;
free_page(tmp);
}
tmp = nr_free_pages << PAGE_SHIFT;
printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
tmp >> 10,
high_memory >> 10,
codepages << (PAGE_SHIFT-10),
reservedpages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10));
invalidate();
return;
}
void si_meminfo(struct sysinfo *val)
{
int i;
i = high_memory >> PAGE_SHIFT;
val->totalram = 0;
val->sharedram = 0;
val->freeram = nr_free_pages << PAGE_SHIFT;
val->bufferram = buffermem;
while (i-- > 0) {
if (mem_map[i] & MAP_PAGE_RESERVED)
continue;
val->totalram++;
if (!mem_map[i])
continue;
val->sharedram += mem_map[i]-1;
}
val->totalram <<= PAGE_SHIFT;
val->sharedram <<= PAGE_SHIFT;
return;
}
/* ioport.c: I/O access on the Sparc. Work in progress.. Most of the things
* in this file are for the sole purpose of getting the kernel
* throught the compiler. :-)
* through the compiler. :-)
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
......
......@@ -34,6 +34,11 @@ OBJS := $(OBJS) mcd.o
SRCS := $(SRCS) mcd.c
endif
ifdef CONFIG_AZTCD
OBJS := $(OBJS) aztcd.o
SRCS := $(SRCS) aztcd.c
endif
ifdef CONFIG_SBPCD
OBJS := $(OBJS) sbpcd.o
SRCS := $(SRCS) sbpcd.c
......
This diff is collapsed.
This diff is collapsed.
......@@ -44,6 +44,9 @@
extern unsigned long cdu31a_init(unsigned long mem_start, unsigned long mem_end);
extern unsigned long mcd_init(unsigned long mem_start, unsigned long mem_end);
#ifdef CONFIG_AZTCD
extern unsigned long aztcd_init(unsigned long mem_start, unsigned long mem_end);
#endif
#ifdef CONFIG_BLK_DEV_HD
extern unsigned long hd_init(unsigned long mem_start, unsigned long mem_end);
#endif
......@@ -170,6 +173,14 @@ static void floppy_off(unsigned int nr);
#define DEVICE_ON(device)
#define DEVICE_OFF(device)
#elif (MAJOR_NR == AZTECH_CDROM_MAJOR)
#define DEVICE_NAME "Aztech CD-ROM"
#define DEVICE_REQUEST do_aztcd_request
#define DEVICE_NR(device) (MINOR(device))
#define DEVICE_ON(device)
#define DEVICE_OFF(device)
#elif (MAJOR_NR == MATSUSHITA_CDROM_MAJOR)
#define DEVICE_NAME "Matsushita CD-ROM controller #1"
......
This diff is collapsed.
......@@ -1218,7 +1218,7 @@ static void ide_intr (int irq, struct pt_regs *regs)
#if SUPPORT_SHARING_IRQ
/* entry point for all interrupts on ide0/ide1 when sharing_single_irq==1 */
static void ide_shared_intr (int irq)
static void ide_shared_intr (int irq, struct pt_regs * regs)
{
IDE_INTR(current_hwif);
}
......
......@@ -547,6 +547,9 @@ long blk_dev_init(long mem_start, long mem_end)
#ifdef CONFIG_MCD
mem_start = mcd_init(mem_start,mem_end);
#endif
#ifdef CONFIG_AZTCD
mem_start = aztcd_init(mem_start,mem_end);
#endif
#ifdef CONFIG_BLK_DEV_FD
floppy_init();
#else
......
......@@ -153,11 +153,11 @@
* experiments by Serge Robyns.
* First attempts to support the TEAC CD-55A drives; but still not
* usable yet.
* Implemented the CDROMMULTISESSION and CDROMMULTISESSION_SYS ioctls;
* this is an attempt to handle multi session CDs more "transparent"
* (redirection handling has to be done within the isofs routines, and
* only for the special purpose of obtaining the "right" volume
* descriptor; accesses to the raw device should not get redirected).
* Implemented the CDROMMULTISESSION ioctl; this is an attempt to handle
* multi session CDs more "transparent" (redirection handling has to be
* done within the isofs routines, and only for the special purpose of
* obtaining the "right" volume descriptor; accesses to the raw device
* should not get redirected).
*
* 3.0 Just a "normal" increment, with some provisions to do it better. ;-)
* Introduced "#define READ_AUDIO" to specify the maximum number of
......@@ -3472,7 +3472,7 @@ static int sbpcd_ioctl(struct inode *inode, struct file *file, u_int cmd,
return (0);
} /* end of CDROMREADAUDIO */
case CDROMMULTISESSION: /* tell start-of-last-session to user */
case CDROMMULTISESSION: /* tell start-of-last-session */
DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMMULTISESSION entered.\n"));
st=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_multisession));
if (st) return (st);
......@@ -3491,17 +3491,6 @@ static int sbpcd_ioctl(struct inode *inode, struct file *file, u_int cmd,
ms_info.xa_flag, ms_info.addr.lba));
return (0);
case CDROMMULTISESSION_SYS: /* tell start-of-last-session to kernel */
DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMMULTISESSION_SYS entered.\n"));
if(!suser()) return -EACCES;
if (DriveStruct[d].f_multisession)
*((unsigned int *) arg)=DriveStruct[d].lba_multi;
else
*((unsigned int *) arg)=0;
DPRINTF((DBG_MUL,"SBPCD: ioctl: CDROMMULTISESSION_SYS done (%d).\n",
((unsigned int *) arg)[0]));
return (0);
case BLKRASET:
if(!suser()) return -EACCES;
if(!inode->i_rdev) return -EINVAL;
......
......@@ -1082,7 +1082,7 @@ static void invert_screen(int currcons) {
if (can_do_color)
for (p = (unsigned short *)origin; p < (unsigned short *)scr_end; p++) {
unsigned short old = readw(p);
writew((old & 0x88ff) | (((old >> 4) | (old << 4)) & 0x7700), p);
writew((old & 0x88ff) | (((old >> 4) | ((old & 0xff00) << 4)) & 0x7700), p);
}
else
for (p = (unsigned short *)origin; p < (unsigned short *)scr_end; p++) {
......@@ -2004,6 +2004,7 @@ long con_init(long kmem_start)
scr_end = video_mem_start + video_num_lines * video_size_row;
gotoxy(currcons,orig_x,orig_y);
set_origin(currcons);
csi_J(currcons, 0);
printable = 1;
printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n",
can_do_color ? "colour" : "mono",
......
......@@ -941,6 +941,10 @@ static int startup(struct async_struct * info)
info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
info->MCR_noint = UART_MCR_DTR | UART_MCR_RTS;
}
#ifdef __alpha__
info->MCR |= UART_MCR_OUT1 | UART_MCR_OUT2;
info->MCR_noint |= UART_MCR_OUT1 | UART_MCR_OUT2;
#endif
if (info->irq == 0)
info->MCR = info->MCR_noint;
serial_outp(info, UART_MCR, info->MCR);
......@@ -2358,7 +2362,15 @@ static void autoconfig(struct async_struct * info)
/*
* Reset the UART.
*/
#ifdef __alpha__
/*
* I wonder what DEC did to the OUT1 and OUT2 lines?
* clearing them results in endless interrupts.
*/
serial_outp(info, UART_MCR, 0x0c);
#else
serial_outp(info, UART_MCR, 0x00);
#endif
serial_outp(info, UART_FCR, (UART_FCR_CLEAR_RCVR |
UART_FCR_CLEAR_XMIT));
(void)serial_in(info, UART_RX);
......
......@@ -1443,7 +1443,8 @@ static int tty_ioctl(struct inode * inode, struct file * file,
arg = get_fs_long((unsigned long *) arg);
return tty_set_ldisc(tty, arg);
case TIOCLINUX:
if (current->tty != tty && !suser())
if ((current->tty != tty ||
tty->driver.type != TTY_DRIVER_TYPE_CONSOLE) && !suser())
return -EPERM;
retval = verify_area(VERIFY_READ, (void *) arg, 1);
if (retval)
......
......@@ -364,7 +364,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
const struct kbentry * a = (struct kbentry *)arg;
ushort *key_map;
u_char s;
u_short v;
u_short v, ov;
if (!perm)
return -EPERM;
......@@ -379,7 +379,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if (!i && v == K_NOSUCHMAP) {
/* disallocate map */
key_map = key_maps[s];
if (key_map) {
if (s && key_map) {
key_maps[s] = 0;
if (key_map[0] == U(K_ALLOCATED)) {
kfree_s(key_map, sizeof(plain_map));
......@@ -401,6 +401,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return 0;
if (!(key_map = key_maps[s])) {
int j;
if (keymap_count >= MAX_NR_OF_USER_KEYMAPS && !suser())
return -EPERM;
......@@ -410,18 +412,22 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return -ENOMEM;
key_maps[s] = key_map;
key_map[0] = U(K_ALLOCATED);
for (s = 1; s < NR_KEYS; s++)
key_map[s] = U(K_HOLE);
for (j = 1; j < NR_KEYS; j++)
key_map[j] = U(K_HOLE);
keymap_count++;
}
ov = U(key_map[i]);
if (v == ov)
return 0; /* nothing to do */
/*
* Only the Superuser can set or unset the Secure
* Attention Key.
*/
if (((key_map[i] == U(K_SAK)) || (v == K_SAK)) &&
!suser())
if (((ov == K_SAK) || (v == K_SAK)) && !suser())
return -EPERM;
key_map[i] = U(v);
if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
compute_shiftstate();
return 0;
}
......
......@@ -96,6 +96,7 @@ unsigned int de600_debug = DE600_DEBUG;
#include <linux/fcntl.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <linux/in.h>
#include <linux/ptrace.h>
......@@ -261,7 +262,6 @@ static int adapter_init(struct device *dev);
/*
* D-Link driver variables:
*/
extern struct device *irq2dev_map[16];
static volatile int rx_page = 0;
#define TX_PAGES 2
......@@ -686,6 +686,12 @@ de600_probe(struct device *dev)
return ENODEV;
}
if (check_region(DE600_IO, 3)) {
printk(", port 0x%x busy\n", DE600_IO);
return EBUSY;
}
request_region(DE600_IO, 3, "de600");
printk(", Ethernet Address: %02X", dev->dev_addr[0]);
for (i = 1; i < ETH_ALEN; i++)
printk(":%02X",dev->dev_addr[i]);
......@@ -838,5 +844,6 @@ cleanup_module(void)
printk("de600: device busy, remove delayed\n");
else
unregister_netdev(&de600_dev);
release_region(DE600_IO, 3);
}
#endif /* MODULE */
......@@ -100,6 +100,13 @@ static char *version =
#define COUNT_LOOPS
*/
#endif
static int bnc, utp;
/*
* Force media with insmod:
* insmod de620.o bnc=1
* or
* insmod de620.o utp=1
*/
#include <linux/kernel.h>
#include <linux/sched.h>
......@@ -107,6 +114,7 @@ static char *version =
#include <linux/fcntl.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <asm/io.h>
#include <linux/in.h>
#include <linux/ptrace.h>
......@@ -192,7 +200,6 @@ static int read_eeprom(void);
#define DE620_RX_START_PAGE 12 /* 12 pages (=3k) reserved for tx */
#define DEF_NIC_CMD IRQEN | ICEN | DS1
extern struct device *irq2dev_map[16];
unsigned int de620_debug = DE620_DEBUG;
static volatile byte NIC_Cmd;
......@@ -719,6 +726,11 @@ adapter_init(struct device *dev)
EIPRegister = NCTL0 | NIS0;
}
if (utp)
EIPRegister = NCTL0 | NIS0;
if (bnc)
EIPRegister = NCTL0;
de620_send_command(W_CR | RNOP | CLEAR);
de620_send_command(W_CR | RNOP);
......@@ -812,6 +824,12 @@ de620_probe(struct device *dev)
return ENODEV;
}
if (check_region(DE620_IO, 3)) {
printk(", port 0x%x busy\n", DE620_IO);
return EBUSY;
}
request_region(DE620_IO, 3, "de620");
/* else, got it! */
printk(", Ethernet Address: %2.2X",
dev->dev_addr[0] = nic_data.NodeID[0]);
......@@ -973,6 +991,7 @@ cleanup_module(void)
printk("de620: device busy, remove delayed\n");
else
unregister_netdev(&de620_dev);
release_region(DE620_IO, 3);
}
#endif /* MODULE */
......
Mon Jan 16 07:18:23 1995 Eric Youngdale (eric@andante)
* Linux 1.1.82 released.
Throughout.
- Change all interrupt handlers to accept new calling convention.
In particular, we now receive the irq number as one of the arguments.
* More minor spelling corrections in some of the new files.
* aha1542.c, buslogic.c: Clean up interrupt handler a little now
that we receive the irq as an arg.
* aha274x.c: s/snarf_region/request_region/
* eata.c: Update to version 1.12. Fix some comments and display a
message if we cannot reserve the port addresses.
* u14-34f.c: Update to version 1.13. Fix some comments and display a
message if we cannot reserve the port addresses.
* eata_dma.c: Define get_board_data function (send INQUIRY command).
Use to improve detection of variants of different DPT boards. Change
version subnumber to "0g".
* fdomain.c: Update to version 5.26. Improve detection of some boards
repackaged by IBM.
* scsi.c (scsi_register_host): Change "name" to const char *.
* sr.c: Fix problem in set mode command for Toshiba drives.
* sr.c: Fix typo from patch 81.
Fri Jan 13 12:54:46 1995 Eric Youngdale (eric@andante)
* Linux 1.1.81 released. Codefreeze for 1.2 release announced.
Big changes here.
* eata_dma.*: New files from Michael Neuffer.
(neuffer@goofy.zdv.uni-mainz.de). Should support
all eata/dpt cards.
* hosts.c, Makefile: Add eata_dma.
* README.st: Document MTEOM.
Patches from me (ERY) to finish support for low-level loadable scsi.
It now works, and is actually useful.
* Throughout - add new argument to scsi_init_malloc that takes an
additional parameter. This is used as a priority to kmalloc,
and you can specify the GFP_DMA flag if you need DMA-able memory.
* Makefile: For source files that are loadable, always add name
to SCSI_SRCS. Fill in modules: target.
* hosts.c: Change next_host to next_scsi_host, and make global.
Print hosts after we have identified all of them. Use info()
function if present, otherwise use name field.
* hosts.h: Change attach function to return int, not void.
Define number of device slots to allow for loadable devices.
Define tags to tell scsi module code what type of module we
are loading.
* scsi.c: Fix scan_scsis so that it can be run by a user process.
Do not use waiting loops - use up and down mechanism as long
as current != task[0].
* scsi.c(scan_scsis): Do not use stack variables for I/O - this
could be > 16Mb if we are loading a module at runtime (i.e. use
scsi_init_malloc to get some memory we know will be safe).
* scsi.c: Change dma freelist to be a set of pages. This allows
us to dynamicly adjust the size of the list by adding more pages
to the pagelist. Fix scsi_malloc and scsi_free accordingly.
* scsi_module.c: Fix include.
* sd.c: Declare detach function. Increment/decrement module usage
count as required. Fix init functions to allow loaded devices.
Revalidate all new disks so we get the partition tables. Define
detach function.
* sr.c: Likewise.
* sg.c: Declare detach function. Allow attachment of devices on
loaded drivers.
* st.c: Declare detach function. Increment/decrement module usage
count as required.
Tue Jan 10 10:09:58 1995 Eric Youngdale (eric@andante)
* Linux 1.1.79 released.
......
......@@ -2,7 +2,7 @@
* linux/kernel/aha1542.c
*
* Copyright (C) 1992 Tommy Thorn
* Copyright (C) 1993, 1994 Eric Youngdale
* Copyright (C) 1993, 1994, 1995 Eric Youngdale
*
* Modified by Eric Youngdale
* Use request_irq and request_dma to help prevent unexpected conflicts
......@@ -1093,7 +1093,6 @@ static int aha1542_restart(struct Scsi_Host * shost)
int aha1542_abort(Scsi_Cmnd * SCpnt)
{
#if 0
int intval[3];
unchar ahacmd = CMD_START_SCSI;
unsigned long flags;
struct mailbox * mb;
......@@ -1119,8 +1118,7 @@ int aha1542_abort(Scsi_Cmnd * SCpnt)
if(mb[mbi].status) {
printk("Lost interrupt discovered on irq %d - attempting to recover\n",
SCpnt->host->irq);
intval[0] = SCpnt->host->irq;
aha1542_intr_handle((int) &intval[2]);
aha1542_intr_handle(SCpnt->host->irq, NULL);
return 0;
}
......
......@@ -1408,10 +1408,7 @@ int buslogic_abort(Scsi_Cmnd *scpnt)
" - attempting to recover...\n",
scpnt->host->irq);
{
int intval[3];
intval[0] = scpnt->host->irq;
buslogic_interrupt((int)&intval[2]);
buslogic_interrupt(scpnt->host->irq, NULL);
return SCSI_ABORT_SUCCESS;
}
}
......
......@@ -695,8 +695,8 @@ int register_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
buff = get_board_data((uint)base, gc->IRQ, gc->scsi_id[3]);
if(!(strncmp("PM2322", &buff[16], 6) || strncmp("PM3021", &buff[16], 6)
|| strncmp("PM3222", &buff[16], 6) || strncmp("PM3224", &buff[16], 6)))
if(strncmp("PM2322", &buff[16], 6) && strncmp("PM3021", &buff[16], 6)
&& strncmp("PM3222", &buff[16], 6) && strncmp("PM3224", &buff[16], 6))
gc->MAX_CHAN = 0;
if (gc->MAX_CHAN) {
......@@ -732,7 +732,9 @@ int register_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
sh->can_queue = ntohs(gc->queuesiz) / (gc->MAX_CHAN + 1);
if (gc->OCS_enabled == TRUE) {
sh->cmd_per_lun = sh->can_queue/C_P_L_DIV;
sh->cmd_per_lun = sh->can_queue/C_P_L_DIV;
if (sh->cmd_per_lun < 2)
sh->cmd_per_lun = 2;
} else {
sh->cmd_per_lun = 1;
}
......
......@@ -377,7 +377,7 @@ typedef struct emul_pp {
unchar p_code:6,
null:1,
p_save:1;
unchar p_lenght;
unchar p_length;
ushort cylinder;
unchar heads;
unchar sectors;
......
/*
* hosts.c Copyright (C) 1992 Drew Eckhardt
* mid to lowlevel SCSI driver interface by
* Drew Eckhardt
* Copyright (C) 1993, 1994, 1995 Eric Youngdale
*
* mid to lowlevel SCSI driver interface
* Initial versions: Drew Eckhardt
* Subsequent revisions: Eric Youngdale
*
* <drew@colorado.edu>
*/
......@@ -329,7 +332,8 @@ unsigned int scsi_init()
shpnt->host_no, name);
}
printk ("scsi : %d hosts.\n", next_scsi_host);
printk ("scsi : %d host%s.\n", next_scsi_host,
(next_scsi_host == 1) ? "" : "s");
{
int block_count = 0, index;
......
This diff is collapsed.
This diff is collapsed.
......@@ -96,7 +96,9 @@ static void *base_address = NULL; /*
used to calculate memory mapped
register location.
*/
#ifdef notyet
static volatile int abort_confirm = 0;
#endif
static volatile void *st0x_cr_sr; /*
control register write,
......
This diff is collapsed.
This diff is collapsed.
......@@ -873,7 +873,7 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
printk("Ux4F: abort while completed command pending\n");
restore_flags(flags);
cli();
ultrastor_interrupt(0);
ultrastor_interrupt(0, NULL);
restore_flags(flags);
return SCSI_ABORT_SUCCESS; /* FIXME - is this correct? -ERY */
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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