Commit 5d278332 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.94

parent fde9fa96
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 93
SUBLEVEL = 94
ARCH = i386
......
......@@ -145,6 +145,18 @@ entUna:
rti
.end entUna
.align 5
.globl entSys
.ent entSys
entSys:
SAVE_ALL
bis $30,$30,$19
lda $27,do_entSys
jsr $26,($27),do_entSys
RESTORE_ALL
rti
.end entSys
.align 5
.globl sys_call_table
sys_call_table:
......
......@@ -60,19 +60,19 @@ void flush_thread(void)
}
/*
* This needs lots of work still..
* This needs some work still..
*/
unsigned long copy_thread(int nr, unsigned long clone_flags, struct task_struct * p, struct pt_regs * regs)
void copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
p->tss.usp = rdusp();
p->tss.usp = usp;
childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1;
*childregs = *regs;
p->tss.ksp = (unsigned long) childregs;
/* p->tss.pc = XXXX; */
halt();
return clone_flags;
panic("copy_thread not implemented");
}
/*
......@@ -84,9 +84,51 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
/*
* sys_execve() executes a new program.
*
* This works due to the alpha calling sequence: the first 6 args
* are gotten from registers, while the rest is on the stack, so
* we get a0-a5 for free, and then magically find "struct pt_regs"
* on the stack for us..
*
* Don't do this at home.
*/
asmlinkage int sys_execve(struct pt_regs regs)
asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs regs)
{
halt();
return 0;
int error;
char * filename;
error = getname((char *) a0, &filename);
if (error)
return error;
error = do_execve(filename, (char **) a1, (char **) a2, &regs);
putname(filename);
return error;
}
/*
* sys_fork() does the obvious thing, but not the obvious way.
* See sys_execve() above.
*/
asmlinkage int sys_fork(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs regs)
{
return do_fork(COPYVM | SIGCHLD, rdusp(), &regs);
}
asmlinkage int sys_clone(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs regs)
{
unsigned long clone_flags = a0;
unsigned long newsp;
newsp = rdusp();
if (newsp == a1 || !a1)
clone_flags |= COPYVM;
else
newsp = a1;
return do_fork(clone_flags, newsp, &regs);
}
......@@ -38,10 +38,28 @@ asmlinkage void do_entUna(unsigned long va, unsigned long opcode, unsigned long
die_if_kernel("Unaligned", regs, 0);
}
/*
* DEC means people to use the "retsys" instruction for return from
* a system call, but they are clearly misguided about this. We use
* "rti" in all cases, and fill in the stack with the return values.
* That should make signal handling etc much cleaner.
*
* Even more horribly, DEC doesn't allow system calls from kernel mode.
* "Security" features letting the user do something the kernel can't
* are a thinko. DEC palcode is strange. The PAL-code designers probably
* got terminally tainted by VMS at some point.
*/
asmlinkage void do_entSys(unsigned long sysnr, unsigned long arg1, unsigned long arg2, struct pt_regs *regs)
{
printk("System call %ld(%ld,%ld)\n", sysnr, arg1, arg2);
die_if_kernel("Syscall", regs, 0);
}
extern asmlinkage void entMM(void);
extern asmlinkage void entIF(void);
extern asmlinkage void entArith(void);
extern asmlinkage void entUna(void);
extern asmlinkage void entSys(void);
void trap_init(void)
{
......@@ -59,4 +77,5 @@ void trap_init(void)
wrent(entMM, 2);
wrent(entIF, 3);
wrent(entUna, 4);
wrent(entSys, 5);
}
......@@ -150,9 +150,8 @@ void flush_thread(void)
current->debugreg[i] = 0;
}
#define IS_CLONE (regs->orig_eax == __NR_clone)
unsigned long copy_thread(int nr, unsigned long clone_flags, struct task_struct * p, struct pt_regs * regs)
void copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
struct task_struct * p, struct pt_regs * regs)
{
int i;
struct pt_regs * childregs;
......@@ -171,15 +170,9 @@ unsigned long copy_thread(int nr, unsigned long clone_flags, struct task_struct
p->tss.eip = (unsigned long) ret_from_sys_call;
*childregs = *regs;
childregs->eax = 0;
childregs->esp = esp;
p->tss.back_link = 0;
p->tss.eflags = regs->eflags & 0xffffcfff; /* iopl is always 0 for a new process */
if (IS_CLONE) {
if (regs->ebx)
childregs->esp = regs->ebx;
clone_flags = regs->ecx;
if (childregs->esp == regs->esp)
clone_flags |= COPYVM;
}
p->tss.ldt = _LDT(nr);
if (p->ldt) {
p->ldt = (struct desc_struct*) vmalloc(LDT_ENTRIES*LDT_ENTRY_SIZE);
......@@ -196,7 +189,6 @@ unsigned long copy_thread(int nr, unsigned long clone_flags, struct task_struct
p->tss.io_bitmap[i] = ~0;
if (last_task_used_math == current)
__asm__("clts ; fnsave %0 ; frstor %0":"=m" (p->tss.i387));
return clone_flags;
}
/*
......@@ -238,6 +230,25 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
}
}
asmlinkage int sys_fork(struct pt_regs regs)
{
return do_fork(COPYVM | SIGCHLD, regs.esp, &regs);
}
asmlinkage int sys_clone(struct pt_regs regs)
{
unsigned long clone_flags;
unsigned long newsp;
newsp = regs.ebx;
clone_flags = regs.ecx;
if (!newsp)
newsp = regs.esp;
if (newsp == regs.esp)
clone_flags |= COPYVM;
return do_fork(clone_flags, newsp, &regs);
}
/*
* sys_execve() executes a new program.
*/
......
#define THREE_LEVEL
/* ptrace.c */
/* By Ross Biro 1/23/92 */
/* edited by Linus Torvalds */
......@@ -86,11 +87,12 @@ static inline int put_stack_long(struct task_struct *task, int offset,
static unsigned long get_long(struct vm_area_struct * vma, unsigned long addr)
{
pgd_t * pgdir;
pmd_t * pgmiddle;
pte_t * pgtable;
unsigned long page;
repeat:
pgdir = PAGE_DIR_OFFSET(vma->vm_task, addr);
pgdir = pgd_offset(vma->vm_task, addr);
if (pgd_none(*pgdir)) {
do_no_page(vma, addr, 0);
goto repeat;
......@@ -100,7 +102,17 @@ static unsigned long get_long(struct vm_area_struct * vma, unsigned long addr)
pgd_clear(pgdir);
return 0;
}
pgtable = (pte_t *) (PAGE_PTR(addr) + pgd_page(*pgdir));
pgmiddle = pmd_offset(pgdir, addr);
if (pmd_none(*pgmiddle)) {
do_no_page(vma, addr, 0);
goto repeat;
}
if (pmd_bad(*pgmiddle)) {
printk("ptrace: bad page middle %08lx\n", pmd_val(*pgmiddle));
pmd_clear(pgmiddle);
return 0;
}
pgtable = pte_offset(pgmiddle, addr);
if (!pte_present(*pgtable)) {
do_no_page(vma, addr, 0);
goto repeat;
......@@ -126,11 +138,12 @@ static void put_long(struct vm_area_struct * vma, unsigned long addr,
unsigned long data)
{
pgd_t *pgdir;
pmd_t *pgmiddle;
pte_t *pgtable;
unsigned long page;
repeat:
pgdir = PAGE_DIR_OFFSET(vma->vm_task, addr);
pgdir = pgd_offset(vma->vm_task, addr);
if (!pgd_present(*pgdir)) {
do_no_page(vma, addr, 1);
goto repeat;
......@@ -140,7 +153,17 @@ static void put_long(struct vm_area_struct * vma, unsigned long addr,
pgd_clear(pgdir);
return;
}
pgtable = (pte_t *) (PAGE_PTR(addr) + pgd_page(*pgdir));
pgmiddle = pmd_offset(pgdir, addr);
if (pmd_none(*pgmiddle)) {
do_no_page(vma, addr, 0);
goto repeat;
}
if (pmd_bad(*pgmiddle)) {
printk("ptrace: bad page middle %08lx\n", pmd_val(*pgmiddle));
pmd_clear(pgmiddle);
return;
}
pgtable = pte_offset(pgmiddle, addr);
if (!pte_present(*pgtable)) {
do_no_page(vma, addr, 1);
goto repeat;
......
......@@ -14,11 +14,6 @@
extern unsigned long pg0[1024]; /* page table for 0-4MB for everybody */
extern void die_if_kernel(char *,struct pt_regs *,long);
/* Sparc stuff... I know this is a ugly place to put the PROM vector, don't
* remind me.
*/
extern unsigned int trapbase[];
extern unsigned int end[], etext[], msgbuf[];
struct linux_romvec *romvec;
/* foo */
......
......@@ -160,7 +160,7 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
* self-modifying code.
*/
a= (unsigned long) etext;
a= (unsigned long) &etext;
mask=~(PTE_NC|PTE_W); /* make cacheable + not writable */
printk("changing kernel text perms...\n");
......@@ -173,7 +173,7 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
for(i=0; i<8; i++)
{
b=PAGE_ALIGN((unsigned long) trapbase);
b=PAGE_ALIGN((unsigned long) &trapbase);
switch_to_context(i);
......
This diff is collapsed.
Sat Feb 18 12:13:51 1995 Theodore Y. Ts'o (tytso@rt-11)
* tty_io.c (disassociate_ctty, tty_open, tty_ioctl): Clear
current->tty_old_pgrp field when a session leader
acquires a controlling tty, and after a session leader
has disassociated from a controlling tty.
Fri Feb 17 09:34:09 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_interrupt_single, rs_interrupt, rs_interrupt_multi):
Change the the number of passes made from 64 to be 256,
configurable with the #define RS_ISR_PASS_LIMIT.
* serial.c (rs_init, set_serial_info, get_serial_info, rs_close):
Remove support for closing_wait2. Instead, set
tty->closing and rely on the line dispcline to prevent
echo wars.
* n_tty.c (n_tty_receive_char): IEXTEN does not need to be
enabled in order for IXANY to be active.
If tty->closing is set, then only process XON and XOFF
characters.
Sun Feb 12 23:57:48 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_timer): Change the interrupt poll time from 60
seconds to 10 seconds, configurable with the #define
RS_STROBE_TIME.
* serial.c (rs_interrupt_multi, startup, shutdown, rs_ioctl,
set_multiport_struct, get_multiport_struct): Add
provisions for a new type of interrutp service routine,
which better supports multiple serial ports on a single
IRQ.
Sun Feb 5 19:35:11 1995 Theodore Y. Ts'o (tytso@rt-11)
* tty_ioctl.c (n_tty_ioctl, set_termios, tty_wait_until_sent):
* serial.c (rs_ioctl, rs_close):
* cyclades.c (cy_ioctl, cy_close):
* n_tty.c (n_tty_close): Rename wait_until_sent to
tty_wait_until_sent, so that it's a better name to export
in ksyms.c.
Sat Feb 4 23:36:20 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_close): Added missing check for closing_wait2 being
ASYNC_CLOSING_WAIT_NONE.
Thu Jan 26 09:02:49 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_init, set_serial_info, get_serial_info,
rs_close): Support close_wait in the serial driver.
This is helpful for slow devices (like serial
plotters) so that their outputs don't get flushed upon
device close. This has to be configurable because
normally we don't want ports to be hung up for long
periods of time during a close when they are not
connected to a device, or the device is powered off.
The default is to wait 30 seconds; in the case of a
very slow device, the close_wait timeout should be
lengthed. If it is set to 0, the kernel will wait
forever for all of the data to be transmitted.
Thu Jan 17 01:17:20 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (startup, change_speed, rs_init): Add support to detect
the StarTech 16650 chip. Treat it as a 16450 for now,
because of its FIFO bugs.
Thu Jan 5 21:21:57 1995 <dhinds@allegro.stanford.edu>
* serial.c: (receive_char): Added counter to prevent infinite loop
......
......@@ -345,7 +345,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
return;
}
if (tty->stopped && I_IXON(tty) && I_IXANY(tty) && L_IEXTEN(tty)) {
if (tty->stopped && I_IXON(tty) && I_IXANY(tty)) {
start_tty(tty);
return;
}
......@@ -355,6 +355,16 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
if (I_IUCLC(tty) && L_IEXTEN(tty))
c=tolower(c);
if (tty->closing) {
if (I_IXON(tty)) {
if (c == START_CHAR(tty))
start_tty(tty);
else if (c == STOP_CHAR(tty))
stop_tty(tty);
}
return;
}
/*
* If the previous character was LNEXT, or we know that this
* character is not one of the characters that we'll have to
......@@ -690,6 +700,7 @@ static int n_tty_open(struct tty_struct *tty)
memset(tty->read_flags, 0, sizeof(tty->read_flags));
n_tty_set_termios(tty, 0);
tty->minimum_to_wake = 1;
tty->closing = 0;
return 0;
}
......
......@@ -3,10 +3,10 @@
*
* This module exports the functions:
*
* 'int set_selection(const int arg)'
* 'int set_selection(const unsigned long arg)'
* 'void clear_selection(void)'
* 'int paste_selection(struct tty_struct *tty)'
* 'int sel_loadlut(const int arg)'
* 'int sel_loadlut(const unsigned long arg)'
*
* Now that /dev/vcs exists, most of this can disappear again.
*/
......@@ -15,6 +15,9 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/malloc.h>
#include <asm/segment.h>
#include "vt_kern.h"
#include "consolemap.h"
#include "selection.h"
......@@ -82,7 +85,7 @@ static inline int inword(const unsigned char c) {
}
/* set inwordLut contents. Invoked by ioctl(). */
int sel_loadlut(const int arg)
int sel_loadlut(const unsigned long arg)
{
int i = verify_area(VERIFY_READ, (char *) arg, 36);
if (i)
......@@ -107,7 +110,7 @@ static inline unsigned short limit(const unsigned short v, const unsigned short
}
/* set the current selection. Invoked by ioctl(). */
int set_selection(const int arg, struct tty_struct *tty)
int set_selection(const unsigned long arg, struct tty_struct *tty)
{
int sel_mode, new_sel_start, new_sel_end, spc;
char *bp, *obp;
......
......@@ -6,9 +6,9 @@
extern int sel_cons;
extern void clear_selection(void);
extern int set_selection(const int arg, struct tty_struct *tty);
extern int set_selection(const unsigned long arg, struct tty_struct *tty);
extern int paste_selection(struct tty_struct *tty);
extern int sel_loadlut(const int arg);
extern int sel_loadlut(const unsigned long arg);
extern int mouse_reporting(void);
extern void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry);
......@@ -33,7 +33,9 @@ extern void putconsxy(int currcons, char *p);
/* how to access screen memory */
#ifdef __alpha__
#include <asm/io.h>
static inline void scr_writew(unsigned short val, unsigned short * addr)
{
if ((long) addr < 0)
......
This diff is collapsed.
......@@ -452,6 +452,7 @@ void disassociate_ctty(int priv)
kill_pg(tty->pgrp, SIGCONT, priv);
}
current->tty_old_pgrp = 0;
tty->session = 0;
tty->pgrp = -1;
......@@ -1165,6 +1166,7 @@ static int tty_open(struct inode * inode, struct file * filp)
!current->tty &&
tty->session == 0) {
current->tty = tty;
current->tty_old_pgrp = 0;
tty->session = current->session;
tty->pgrp = current->pgrp;
}
......@@ -1393,6 +1395,7 @@ static int tty_ioctl(struct inode * inode, struct file * file,
return -EPERM;
}
current->tty = tty;
current->tty_old_pgrp = 0;
tty->session = current->session;
tty->pgrp = current->pgrp;
return 0;
......
#if defined(CONFIG_WAVELAN)
Tue Jan 31 10:42:35 EST 1995
Thu Feb 23 00:10:31 EST 1995
0. This document refers to Version 5 of the Linux WaveLAN device driver software.
It has been tested successfully under the 1.1.87 release of the Linux
kernel. It is `beta-test' software, so caveat emptor. Please report bugs
to me so that I can fix them quickly.
1. At present the driver only autoprobes for a WaveLAN card at I/O address 0x390.
1. At present the driver autoprobes for a WaveLAN card only at I/O address 0x390.
The version of the card that I use (NCR) supports four I/O addresses (selectable
via a pair of DIP switches). If you want the driver to autoprobe a different
subset of the four valid addresses then you will need to edit
......@@ -28,20 +23,7 @@ Tue Jan 31 10:42:35 EST 1995
append ="ether=0,0x390,0x4321,eth0"
..
3. The files that comprise this software must be incorporated into the Linux
kernel source tree (usually rooted at /usr/src/linux). Following that a
"make clean; make config; make dep; make zImage" should produce a Linux
kernel incorporating the WaveLAN driver, ready for installation.
The files:
drivers/net/wavelan.[ch]
drivers/net/i82586.h
are unique to this package and simply may be moved into place. The
others are modified versions of pre-existing files and must
be incorporated more carefully. However, the regions of modified code
within these files are small and are bracketed by the preprocessor
symbol CONFIG_WAVELAN, so incorporation should be straightforward.
4. If you encounter any problems send me some email.
3. If you encounter any problems send me some email.
Good luck,
Bruce Janson (bruce@cs.usyd.edu.au)
......
......@@ -21,6 +21,7 @@
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/io.h>
......@@ -70,7 +71,7 @@ struct net_local
extern int wavelan_probe(device *); /* See Space.c */
static char *version = "wavelan.c:v5 31/1/95\n";
static char *version = "wavelan.c:v6 22/2/95\n";
/*
* Entry point forward declarations.
......@@ -103,14 +104,6 @@ static void wavelan_local_show(device *);
static unsigned int wavelan_debug = WAVELAN_DEBUG;
static net_local *first_wavelan = (net_local *)0;
static
void
busy_loop(int i)
{
while (i-- > 0)
;
}
static
unsigned long
wavelan_splhi(void)
......@@ -150,7 +143,7 @@ hacr_write_slow(unsigned short ioaddr, int hacr)
{
hacr_write(ioaddr, hacr);
/* delay might only be needed sometimes */
busy_loop(1000);
udelay(1000);
}
/*
......@@ -444,11 +437,13 @@ wavelan_ack(device *dev)
set_chan_attn(ioaddr, lp->hacr);
for (i = 1000000; i > 0; i--)
for (i = 1000; i > 0; i--)
{
obram_read(ioaddr, scboff(OFFSET_SCB, scb_command), (unsigned char *)&scb_cs, sizeof(scb_cs));
if (scb_cs == 0)
break;
udelay(1000);
}
if (i <= 0)
......@@ -477,11 +472,13 @@ wavelan_synchronous_cmd(device *dev, char *str)
set_chan_attn(ioaddr, lp->hacr);
for (i = 64000; i > 0; i--)
for (i = 64; i > 0; i--)
{
obram_read(ioaddr, OFFSET_CU, (unsigned char *)&cb, sizeof(cb));
if (cb.ac_status & AC_SFLD_C)
break;
udelay(1000);
}
if (i <= 0 || !(cb.ac_status & AC_SFLD_OK))
......@@ -557,23 +554,27 @@ wavelan_hardware_reset(device *dev)
set_chan_attn(ioaddr, lp->hacr);
for (i = 1000000; i > 0; i--)
for (i = 1000; i > 0; i--)
{
obram_read(ioaddr, OFFSET_ISCP, (unsigned char *)&iscp, sizeof(iscp));
if (iscp.iscp_busy == (unsigned short)0)
break;
udelay(1000);
}
if (i <= 0)
printk("%s: wavelan_hardware_reset(): iscp_busy timeout.\n", dev->name);
for (i = 15000; i > 0; i--)
for (i = 15; i > 0; i--)
{
obram_read(ioaddr, OFFSET_SCB, (unsigned char *)&scb, sizeof(scb));
if (scb.scb_status == (SCB_ST_CX | SCB_ST_CNA))
break;
udelay(1000);
}
if (i <= 0)
......@@ -970,11 +971,13 @@ wavelan_ru_start(device *dev)
set_chan_attn(ioaddr, lp->hacr);
for (i = 1000000; i > 0; i--)
for (i = 1000; i > 0; i--)
{
obram_read(ioaddr, scboff(OFFSET_SCB, scb_command), (unsigned char *)&scb_cs, sizeof(scb_cs));
if (scb_cs == 0)
break;
udelay(1000);
}
if (i <= 0)
......@@ -1049,11 +1052,13 @@ wavelan_cu_start(device *dev)
set_chan_attn(ioaddr, lp->hacr);
for (i = 1000000; i > 0; i--)
for (i = 1000; i > 0; i--)
{
obram_read(ioaddr, scboff(OFFSET_SCB, scb_command), (unsigned char *)&scb_cs, sizeof(scb_cs));
if (scb_cs == 0)
break;
udelay(1000);
}
if (i <= 0)
......@@ -1849,6 +1854,7 @@ void
wavelan_set_multicast_list(device *dev, int num_addrs, void *addrs)
{
net_local *lp;
unsigned long x;
lp = (net_local *)dev->priv;
......@@ -1859,7 +1865,9 @@ wavelan_set_multicast_list(device *dev, int num_addrs, void *addrs)
* Promiscuous mode: receive all packets.
*/
lp->promiscuous = 1;
x = wavelan_splhi();
(void)wavelan_hardware_reset(dev);
wavelan_splx(x);
break;
case 0:
......@@ -1868,7 +1876,9 @@ wavelan_set_multicast_list(device *dev, int num_addrs, void *addrs)
* clear multicast list.
*/
lp->promiscuous = 0;
x = wavelan_splhi();
(void)wavelan_hardware_reset(dev);
wavelan_splx(x);
break;
default:
......@@ -2319,9 +2329,9 @@ wavelan_local_show(device *dev)
* Allan Creighton (allanc@cs.usyd.edu.au),
* Matthew Geier (matthew@cs.usyd.edu.au),
* Remo di Giovanni (remo@cs.usyd.edu.au),
* Eckhard Grah (grah@wrcs1.urz.uni-wuppertal.de),
* Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM),
* Tim Nicholson (tim@cs.usyd.edu.au),
* Jeff Noxon (jeff@oylpatch.sccsi.com),
* Ian Parkin (ian@cs.usyd.edu.au),
* John Rosenberg (johnr@cs.usyd.edu.au),
* George Rossi (george@phm.gov.au),
......
......@@ -1363,7 +1363,7 @@ static int shrink_specific_buffers(unsigned int priority, int size)
if(priority > 3 && nlist == BUF_SHARED) continue;
bh = lru_list[nlist];
if(!bh) continue;
i = nr_buffers_type[nlist] >> priority;
i = 2*nr_buffers_type[nlist] >> priority;
for ( ; i-- > 0 ; bh = bh->b_next_free) {
/* We may have stalled while waiting for I/O to complete. */
if(bh->b_list != nlist) goto repeat1;
......
......@@ -183,14 +183,17 @@ static int isofs_readdir(struct inode * inode, struct file * filp,
is no Rock Ridge NM field. */
else {
/* Do not report hidden or associated files */
high_sierra = inode->i_sb->u.isofs_sb.s_high_sierra;
if (de->flags[-high_sierra] & 5) {
if (cpnt) {
kfree(cpnt);
cpnt = NULL;
};
continue;
if (inode->i_sb->u.isofs_sb.s_unhide=='n')
{
/* Do not report hidden or associated files */
high_sierra = inode->i_sb->u.isofs_sb.s_high_sierra;
if (de->flags[-high_sierra] & 5) {
if (cpnt) {
kfree(cpnt);
cpnt = NULL;
};
continue;
}
}
dlen = de->name_len[0];
dpnt = de->name;
......
......@@ -63,6 +63,7 @@ struct iso9660_options{
char map;
char rock;
char cruft;
char unhide;
unsigned char conversion;
unsigned int blocksize;
mode_t mode;
......@@ -77,6 +78,7 @@ static int parse_options(char *options, struct iso9660_options * popt)
popt->map = 'n';
popt->rock = 'y';
popt->cruft = 'n';
popt->unhide = 'n';
popt->conversion = 'a';
popt->blocksize = 1024;
popt->mode = S_IRUGO;
......@@ -88,6 +90,10 @@ static int parse_options(char *options, struct iso9660_options * popt)
popt->rock = 'n';
continue;
};
if (strncmp(this_char,"unhide",6) == 0) {
popt->unhide = 'y';
continue;
};
if (strncmp(this_char,"cruft",5) == 0) {
popt->cruft = 'y';
continue;
......@@ -214,6 +220,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
printk("map = %c\n", opt.map);
printk("rock = %c\n", opt.rock);
printk("cruft = %c\n", opt.cruft);
printk("unhide = %c\n", opt.unhide);
printk("conversion = %c\n", opt.conversion);
printk("blocksize = %d\n", opt.blocksize);
printk("gid = %d\n", opt.gid);
......@@ -353,6 +360,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
s->u.isofs_sb.s_rock = (opt.rock == 'y' ? 1 : 0);
s->u.isofs_sb.s_conversion = opt.conversion;
s->u.isofs_sb.s_cruft = opt.cruft;
s->u.isofs_sb.s_unhide = opt.unhide;
s->u.isofs_sb.s_uid = opt.uid;
s->u.isofs_sb.s_gid = opt.gid;
/*
......
......@@ -73,7 +73,6 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
unsigned int old_offset;
unsigned int backlink;
int dlen, rrflag, match;
int high_sierra = 0;
char * dpnt;
struct iso_directory_record * de;
char c;
......@@ -155,16 +154,6 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
backlink = 0;
}
/* Do not report hidden or associated files */
high_sierra = dir->i_sb->u.isofs_sb.s_high_sierra;
if (de->flags[-high_sierra] & 5) {
if (cpnt) {
kfree(cpnt);
cpnt = NULL;
};
continue;
}
dlen = de->name_len[0];
dpnt = de->name;
/* Now convert the filename in the buffer to lower case */
......
......@@ -7,7 +7,7 @@
* Deadlock Detection added by Kelly Carmichael, kelly@[142.24.8.65]
* September 17, 1994.
*
* FIXME: one thing isn't handled yet:
* FIXME: one thing isn't handled yet:
* - mandatory locks (requires lots of changes elsewhere)
*
* Edited by Kai Petzke, wpp@marie.physik.tu-berlin.de
......@@ -22,7 +22,11 @@
* process. Since locks still depend on the process id, locks are inherited
* after an exec() but not after a fork(). This agrees with POSIX, and both
* BSD and SVR4 practice.
* Andy Walker (andy@keo.kvaerner.no), February 14, 1994
* Andy Walker (andy@keo.kvaerner.no), February 14, 1995
*
* Scrapped free list which is redundant now that we allocate locks
* dynamically with kmalloc()/kfree().
* Andy Walker (andy@keo.kvaerner.no), February 21, 1995
*
*/
......@@ -45,16 +49,11 @@ static int overlap(struct file_lock *fl1, struct file_lock *fl2);
static int lock_it(struct file *filp, struct file_lock *caller);
static struct file_lock *alloc_lock(struct file_lock **pos, struct file_lock *fl);
static void free_lock(struct file_lock **fl);
static void free_list_garbage_collect(void);
#ifdef DEADLOCK_DETECTION
int locks_deadlocked(int my_pid,int blocked_pid);
#endif
#define FREE_LIST_GARBAGE_COLLECT 20
static struct file_lock *file_lock_table = NULL;
static struct file_lock *file_lock_free_list = NULL;
static int free_list_cnt = 0;
int fcntl_getlk(unsigned int fd, struct flock *l)
{
......@@ -155,7 +154,8 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
if (current->signal & ~current->blocked)
return -ERESTARTSYS;
#ifdef DEADLOCK_DETECTION
if (locks_deadlocked(file_lock.fl_owner->pid,fl->fl_owner->pid)) return -EDEADLOCK;
if (locks_deadlocked(file_lock.fl_owner->pid,fl->fl_owner->pid))
return -EDEADLOCK;
#endif
interruptible_sleep_on(&fl->fl_wait);
if (current->signal & ~current->blocked)
......@@ -192,9 +192,11 @@ int locks_deadlocked(int my_pid,int blocked_pid)
dlock_wait = fl->fl_wait;
do {
if (dlock_wait->task != NULL) {
if (dlock_wait->task->pid == blocked_pid) return -EDEADLOCK;
if (dlock_wait->task->pid == blocked_pid)
return -EDEADLOCK;
ret_val = locks_deadlocked(dlock_wait->task->pid,blocked_pid);
if (ret_val) return -EDEADLOCK;
if (ret_val)
return -EDEADLOCK;
}
dlock_wait = dlock_wait->next;
} while (dlock_wait != fl->fl_wait);
......@@ -445,40 +447,26 @@ static int lock_it(struct file *filp, struct file_lock *caller)
/*
* File_lock() inserts a lock at the position pos of the linked list.
*
* Modified to create a new node if no free entries available - Chad Page
*
*/
static struct file_lock *alloc_lock(struct file_lock **pos,
struct file_lock *fl)
{
struct file_lock *tmp;
tmp = file_lock_free_list;
if (tmp == NULL)
{
/* Okay, let's make a new file_lock structure... */
tmp = (struct file_lock *)kmalloc(sizeof(struct file_lock), GFP_KERNEL);
tmp -> fl_owner = NULL;
tmp -> fl_next = file_lock_free_list;
tmp -> fl_nextlink = file_lock_table;
file_lock_table = tmp;
}
else
{
/* remove from free list */
file_lock_free_list = tmp->fl_next;
free_list_cnt--;
}
if (tmp->fl_owner != NULL)
panic("alloc_lock: broken free list\n");
/* Okay, let's make a new file_lock structure... */
tmp = (struct file_lock *)kmalloc(sizeof(struct file_lock), GFP_KERNEL);
if (!tmp)
return tmp;
tmp->fl_nextlink = file_lock_table;
tmp->fl_prevlink = NULL;
if (file_lock_table != NULL)
file_lock_table->fl_prevlink = tmp;
file_lock_table = tmp;
tmp->fl_next = *pos; /* insert into file's list */
*pos = tmp;
tmp->fl_owner = current; /* FIXME: needed? */
tmp->fl_owner = current;
tmp->fl_wait = NULL;
tmp->fl_type = fl->fl_type;
......@@ -490,7 +478,7 @@ static struct file_lock *alloc_lock(struct file_lock **pos,
}
/*
* Add a lock to the free list ...
* Free up a lock...
*/
static void free_lock(struct file_lock **fl_p)
......@@ -498,24 +486,19 @@ static void free_lock(struct file_lock **fl_p)
struct file_lock *fl;
fl = *fl_p;
if (fl->fl_owner == NULL) /* sanity check */
panic("free_lock: broken lock list\n");
*fl_p = (*fl_p)->fl_next;
fl->fl_next = file_lock_free_list; /* add to free list */
file_lock_free_list = fl;
fl->fl_owner = NULL; /* for sanity checks */
if (fl->fl_nextlink != NULL)
fl->fl_nextlink->fl_prevlink = fl->fl_prevlink;
free_list_cnt++;
if (free_list_cnt == FREE_LIST_GARBAGE_COLLECT)
free_list_garbage_collect();
if (fl->fl_prevlink != NULL)
fl->fl_prevlink->fl_nextlink = fl->fl_nextlink;
else
file_lock_table = fl->fl_nextlink;
wake_up(&fl->fl_wait);
}
static void free_list_garbage_collect(void)
{
/* Do nothing for now */
kfree(fl);
return;
}
#define THREE_LEVEL
/*
* linux/fs/proc/mem.c
*
......@@ -25,7 +26,8 @@
static int mem_read(struct inode * inode, struct file * file,char * buf, int count)
{
pgd_t *pgdir;
pgd_t *page_dir;
pmd_t *page_middle;
pte_t pte;
char * page;
struct task_struct * tsk;
......@@ -50,15 +52,23 @@ static int mem_read(struct inode * inode, struct file * file,char * buf, int cou
while (count > 0) {
if (current->signal & ~current->blocked)
break;
pgdir = PAGE_DIR_OFFSET(tsk,addr);
if (pgd_none(*pgdir))
page_dir = pgd_offset(tsk,addr);
if (pgd_none(*page_dir))
break;
if (pgd_bad(*pgdir)) {
printk("Bad page dir entry %08lx\n", pgd_val(*pgdir));
pgd_clear(pgdir);
if (pgd_bad(*page_dir)) {
printk("Bad page dir entry %08lx\n", pgd_val(*page_dir));
pgd_clear(page_dir);
break;
}
pte = *(pte_t *) (PAGE_PTR(addr) + pgd_page(*pgdir));
page_middle = pmd_offset(page_dir,addr);
if (pmd_none(*page_middle))
break;
if (pmd_bad(*page_middle)) {
printk("Bad page middle entry %08lx\n", pmd_val(*page_middle));
pmd_clear(page_middle);
break;
}
pte = *pte_offset(page_middle,addr);
if (!pte_present(pte))
break;
page = (char *) pte_page(pte) + (addr & ~PAGE_MASK);
......@@ -78,8 +88,9 @@ static int mem_read(struct inode * inode, struct file * file,char * buf, int cou
static int mem_write(struct inode * inode, struct file * file,char * buf, int count)
{
pgd_t * pgdir;
pte_t * pte;
pgd_t *page_dir;
pmd_t *page_middle;
pte_t pte;
char * page;
struct task_struct * tsk;
unsigned long addr, pid;
......@@ -103,15 +114,23 @@ static int mem_write(struct inode * inode, struct file * file,char * buf, int co
while (count > 0) {
if (current->signal & ~current->blocked)
break;
pgdir = PAGE_DIR_OFFSET(tsk,addr);
if (pgd_none(*pgdir))
page_dir = pgd_offset(tsk,addr);
if (pgd_none(*page_dir))
break;
if (pgd_bad(*pgdir)) {
printk("Bad page dir entry %08lx\n", pgd_val(*pgdir));
pgd_clear(pgdir);
if (pgd_bad(*page_dir)) {
printk("Bad page dir entry %08lx\n", pgd_val(*page_dir));
pgd_clear(page_dir);
break;
}
pte = *(pte_t *) (PAGE_PTR(addr) + pgd_page(*pgdir));
page_middle = pmd_offset(page_dir,addr);
if (pmd_none(*page_middle))
break;
if (pmd_bad(*page_middle)) {
printk("Bad page middle entry %08lx\n", pmd_val(*page_middle));
pmd_clear(page_middle);
break;
}
pte = *pte_offset(page_middle,addr);
if (!pte_present(pte))
break;
if (!pte_write(pte))
......@@ -157,6 +176,7 @@ int mem_mmap(struct inode * inode, struct file * file,
{
struct task_struct *tsk;
pgd_t *src_dir, *dest_dir;
pmd_t *src_middle, *dest_middle;
pte_t *src_table, *dest_table;
unsigned long stmp, dtmp;
struct vm_area_struct *src_vma = NULL;
......@@ -168,7 +188,6 @@ int mem_mmap(struct inode * inode, struct file * file,
for (i = 1 ; i < NR_TASKS ; i++)
if (task[i] && task[i]->pid == (inode->i_ino >> 16)) {
tsk = task[i];
src_vma = task[i]->mm->mmap;
break;
}
......@@ -180,6 +199,7 @@ int mem_mmap(struct inode * inode, struct file * file,
moment because working out the vm_area_struct & nattach stuff isn't
worth it. */
src_vma = tsk->mm->mmap;
stmp = vma->vm_offset;
while (stmp < vma->vm_offset + (vma->vm_end - vma->vm_start)) {
while (src_vma && stmp > src_vma->vm_end)
......@@ -187,15 +207,21 @@ int mem_mmap(struct inode * inode, struct file * file,
if (!src_vma || (src_vma->vm_flags & VM_SHM))
return -EINVAL;
src_dir = PAGE_DIR_OFFSET(tsk, stmp);
src_dir = pgd_offset(tsk, stmp);
if (pgd_none(*src_dir))
return -EINVAL;
if (pgd_bad(*src_dir)) {
printk("Bad source page dir entry %08lx\n", pgd_val(*src_dir));
return -EINVAL;
}
src_table = (pte_t *)(pgd_page(*src_dir) + PAGE_PTR(stmp));
src_middle = pmd_offset(src_dir, stmp);
if (pmd_none(*src_middle))
return -EINVAL;
if (pmd_bad(*src_middle)) {
printk("Bad source page middle entry %08lx\n", pmd_val(*src_middle));
return -EINVAL;
}
src_table = pte_offset(src_middle, stmp);
if (pte_none(*src_table))
return -EINVAL;
......@@ -208,7 +234,7 @@ int mem_mmap(struct inode * inode, struct file * file,
stmp += PAGE_SIZE;
}
src_vma = task[i]->mm->mmap;
src_vma = tsk->mm->mmap;
stmp = vma->vm_offset;
dtmp = vma->vm_start;
......@@ -216,28 +242,17 @@ int mem_mmap(struct inode * inode, struct file * file,
while (src_vma && stmp > src_vma->vm_end)
src_vma = src_vma->vm_next;
src_dir = PAGE_DIR_OFFSET(tsk, stmp);
src_table = (pte_t *) (pgd_page(*src_dir) + PAGE_PTR(stmp));
dest_dir = PAGE_DIR_OFFSET(current, dtmp);
if (pgd_none(*dest_dir)) {
unsigned long page = get_free_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
if (pgd_none(*dest_dir)) {
pgd_set(dest_dir, (pte_t *) page);
} else {
free_page(page);
}
}
if (pgd_bad(*dest_dir)) {
printk("Bad dest directory entry %08lx\n", pgd_val(*dest_dir));
return -EINVAL;
}
dest_table = (pte_t *) (pgd_page(*dest_dir) + PAGE_PTR(dtmp));
src_dir = pgd_offset(tsk, stmp);
src_middle = pmd_offset(src_dir, stmp);
src_table = pte_offset(src_middle, stmp);
dest_dir = pgd_offset(current, dtmp);
dest_middle = pmd_alloc(dest_dir, dtmp);
if (!dest_middle)
return -ENOMEM;
dest_table = pte_alloc(dest_middle, dtmp);
if (!dest_table)
return -ENOMEM;
if (!pte_present(*src_table))
do_no_page(src_vma, stmp, 1);
......
......@@ -32,14 +32,11 @@ __ntohl(unsigned long int x)
((x & 0xff000000U) >> 24));
}
extern __inline__ unsigned long int
__constant_ntohl(unsigned long int x)
{
return (((x & 0x000000ffU) << 24) |
((x & 0x0000ff00U) << 8) |
((x & 0x00ff0000U) >> 8) |
((x & 0xff000000U) >> 24));
}
#define __constant_ntohl(x) \
((unsigned int)((((unsigned int)(x) & 0x000000ffU) << 24) | \
(((unsigned int)(x) & 0x0000ff00U) << 8) | \
(((unsigned int)(x) & 0x00ff0000U) >> 8) | \
(((unsigned int)(x) & 0xff000000U) >> 24)))
extern __inline__ unsigned short int
__ntohs(unsigned short int x)
......@@ -48,12 +45,9 @@ __ntohs(unsigned short int x)
((x & 0xff00) >> 8));
}
extern __inline__ unsigned short int
__constant_ntohs(unsigned short int x)
{
return (((x & 0x00ff) << 8) |
((x & 0xff00) >> 8));
}
#define __constant_ntohs(x) \
((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
(((unsigned short int)(x) & 0xff00) >> 8)))
#define __htonl(x) __ntohl(x)
#define __htons(x) __ntohs(x)
......
......@@ -160,18 +160,33 @@ extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_VALID; }
extern inline int pte_inuse(pte_t *ptep) { return mem_map[MAP_NR(ptep)] > 1; }
extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; }
extern inline void pte_reuse(pte_t * ptep)
{
if (!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED))
mem_map[MAP_NR(ptep)]++;
}
extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); }
extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~_PFN_MASK) != _PAGE_TABLE || pmd_page(pmd) > high_memory; }
extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_VALID; }
extern inline int pmd_inuse(pmd_t *pmdp) { return mem_map[MAP_NR(pmdp)] > 1; }
extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; }
extern inline void pmd_reuse(pmd_t * pmdp)
{
if (!(mem_map[MAP_NR(pmdp)] & MAP_PAGE_RESERVED))
mem_map[MAP_NR(pmdp)]++;
}
extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); }
extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE || pgd_page(pgd) > high_memory; }
extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_VALID; }
extern inline int pgd_inuse(pgd_t *pgdp) { return mem_map[MAP_NR(pgdp)] > 1; }
extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; }
extern inline void pgd_reuse(pgd_t * pgdp)
{
if (!(mem_map[MAP_NR(pgdp)] & MAP_PAGE_RESERVED))
mem_map[MAP_NR(pgdp)]++;
}
/*
* The following only work if pte_present() is true.
......
......@@ -27,14 +27,11 @@ __ntohl(unsigned long int x)
return x;
}
extern __inline__ unsigned long int
__constant_ntohl(unsigned long int x)
{
return (((x & 0x000000ffU) << 24) |
((x & 0x0000ff00U) << 8) |
((x & 0x00ff0000U) >> 8) |
((x & 0xff000000U) >> 24));
}
#define __constant_ntohl(x) \
((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
(((unsigned long int)(x) & 0x0000ff00U) << 8) | \
(((unsigned long int)(x) & 0x00ff0000U) >> 8) | \
(((unsigned long int)(x) & 0xff000000U) >> 24)))
extern __inline__ unsigned short int
__ntohs(unsigned short int x)
......@@ -45,12 +42,9 @@ __ntohs(unsigned short int x)
return x;
}
extern __inline__ unsigned short int
__constant_ntohs(unsigned short int x)
{
return (((x & 0x00ff) << 8) |
((x & 0xff00) >> 8));
}
#define __constant_ntohs(x) \
((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
(((unsigned short int)(x) & 0xff00) >> 8))) \
#define __htonl(x) __ntohl(x)
#define __htons(x) __ntohs(x)
......
#ifndef __SPARC_SYSTEM_H
#define __SPARC_SYSTEM_H
#include <asm/segment.h>
/*
* System defines.. Note that this is included both from .c and .S
* files, so it does only defines, not any C code.
......
......@@ -7,8 +7,8 @@
Copyright (C) 1994, David S. Miller (davem@caip.rutgers.edu)
*/
extern unsigned int trapbase[];
extern unsigned int end[], etext[], msgbuf[];
extern unsigned long *trapbase;
extern char end, etext, msgbuf;
extern void flush_vac_context(void);
extern void flush_vac_segment(unsigned int foo_segment);
......
......@@ -266,8 +266,9 @@ struct file {
};
struct file_lock {
struct file_lock *fl_next; /* singly linked list */
struct file_lock *fl_nextlink;
struct file_lock *fl_next; /* singly linked list for this inode (or the free list) */
struct file_lock *fl_nextlink; /* doubly linked list of all locks */
struct file_lock *fl_prevlink; /* used to simplify garbage collecting */
struct task_struct *fl_owner; /* NULL if on free list, for sanity checks */
struct wait_queue *fl_wait;
char fl_type;
......
......@@ -18,6 +18,7 @@ struct isofs_sb_info {
unsigned char s_cruft; /* Broken disks with high
byte of length containing
junk */
unsigned char s_unhide;
unsigned char s_nosuid;
unsigned char s_nodev;
mode_t s_mode;
......
......@@ -268,11 +268,12 @@ extern int request_irq(unsigned int irq,void (*handler)(int, struct pt_regs *),
unsigned long flags, const char *device);
extern void free_irq(unsigned int irq);
extern unsigned long copy_thread(int, unsigned long, struct task_struct *, struct pt_regs *);
extern void copy_thread(int, unsigned long, unsigned long, struct task_struct *, struct pt_regs *);
extern void flush_thread(void);
extern void exit_thread(void);
extern int do_execve(char *, char **, char **, struct pt_regs *);
extern int do_fork(unsigned long, unsigned long, struct pt_regs *);
asmlinkage int do_signal(unsigned long, struct pt_regs *);
/*
......
......@@ -22,9 +22,18 @@ struct serial_struct {
unsigned short close_delay;
char reserved_char[2];
int hub6;
int reserved[5];
unsigned short closing_wait; /* time to wait before closing */
unsigned short closing_wait2; /* no longer used... */
int reserved[4];
};
/*
* For the close wait times, 0 means wait forever for serial port to
* flush its output. 65535 means don't wait at all.
*/
#define ASYNC_CLOSING_WAIT_INF 0
#define ASYNC_CLOSING_WAIT_NONE 65535
/*
* These are the supported serial types.
*/
......@@ -34,7 +43,8 @@ struct serial_struct {
#define PORT_16550 3
#define PORT_16550A 4
#define PORT_CIRRUS 5
#define PORT_MAX 5
#define PORT_16650 6
#define PORT_MAX 6
/*
* Definitions for async_struct (and serial_struct) flags field
......@@ -70,6 +80,23 @@ struct serial_struct {
#define ASYNC_CTS_FLOW 0x04000000 /* Do CTS flow control */
#define ASYNC_CHECK_CD 0x02000000 /* i.e., CLOCAL */
/*
* Multiport serial configuration structure --- external structure
*/
struct serial_multiport_struct {
int irq;
int port1;
unsigned char mask1, match1;
int port2;
unsigned char mask2, match2;
int port3;
unsigned char mask3, match3;
int port4;
unsigned char mask4, match4;
int port_monitor;
int reserved[32];
};
#ifdef __KERNEL__
/*
* This is our internal structure for each serial port's state.
......@@ -96,6 +123,8 @@ struct async_struct {
int custom_divisor;
int x_char; /* xon/xoff character */
int close_delay;
unsigned short closing_wait;
unsigned short closing_wait2;
int IER; /* Interrupt Enable Register */
int MCR; /* Modem control register */
int MCR_noint; /* MCR with interrupts off */
......@@ -133,6 +162,21 @@ struct async_struct {
#define RS_EVENT_WRITE_WAKEUP 0
#define RS_EVENT_HANGUP 1
/*
* Multiport serial configuration structure --- internal structure
*/
struct rs_multiport_struct {
int port1;
unsigned char mask1, match1;
int port2;
unsigned char mask2, match2;
int port3;
unsigned char mask3, match3;
int port4;
unsigned char mask4, match4;
int port_monitor;
};
/* Export to allow PCMCIA to use this - Dave Hinds */
extern int register_serial(struct serial_struct *req);
extern void unregister_serial(int line);
......
......@@ -21,6 +21,8 @@
#define UART_IER 1 /* Out: Interrupt Enable Register */
#define UART_IIR 2 /* In: Interrupt ID Register */
#define UART_FCR 2 /* Out: FIFO Control Register */
#define UART_EFR 2 /* I/O: Extended Features Register */
/* (DLAB=1, 16C660 only) */
#define UART_LCR 3 /* Out: Line Control Register */
#define UART_MCR 4 /* Out: Modem Control Register */
#define UART_LSR 5 /* In: Line Status Register */
......@@ -29,6 +31,7 @@
/*
* These are the definitions for the FIFO Control Register
* (16650 only)
*/
#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */
#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */
......@@ -39,6 +42,15 @@
#define UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */
#define UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */
#define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */
/* 16650 redefinitions */
#define UART_FCR6_R_TRIGGER_8 0x00 /* Mask for receive trigger set at 1 */
#define UART_FCR6_R_TRIGGER_16 0x40 /* Mask for receive trigger set at 4 */
#define UART_FCR6_R_TRIGGER_24 0x80 /* Mask for receive trigger set at 8 */
#define UART_FCR6_R_TRIGGER_28 0xC0 /* Mask for receive trigger set at 14 */
#define UART_FCR6_T_TRIGGER_16 0x00 /* Mask for transmit trigger set at 16 */
#define UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */
#define UART_FCR6_T_TRIGGER_24 0x20 /* Mask for transmit trigger set at 24 */
#define UART_FCR6_T_TRIGGER_30 0x30 /* Mask for transmit trigger set at 30 */
/*
* These are the definitions for the Line Control Register
......@@ -109,5 +121,17 @@
#define UART_MSR_DCTS 0x01 /* Delta CTS */
#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */
/*
* These are the definitions for the Extended Features Register
* (StarTech 16C660 only, when DLAB=1)
*/
#define UART_EFR_CTS 0x80 /* CTS flow control */
#define UART_EFR_RTS 0x40 /* RTS flow control */
#define UART_EFR_SCD 0x20 /* Special character detect */
#define UART_EFR_ENI 0x10 /* Enhanced Interrupt */
/*
* the low four bits control software flow control
*/
#endif /* _LINUX_SERIAL_REG_H */
......@@ -6,11 +6,6 @@
*/
#define NR_syscalls 256
/*
* These are system calls with the same entry-point
*/
#define _sys_clone _sys_fork
/*
* These are system calls that will be removed at some time
* due to newer versions existing..
......
......@@ -54,6 +54,8 @@
#define TIOCSLCKTRMIOS 0x5457
#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
#define TIOCSERGETLSR 0x5459 /* Get line status register */
#define TIOCSERGETMULTI 0x545A /* Get multiport config */
#define TIOCSERSETMULTI 0x545B /* Set multiport config */
/* Used for packet mode */
#define TIOCPKT_DATA 0
......@@ -193,6 +195,7 @@ struct termios {
#define CBAUDEX 0010000
#define B57600 0010001
#define B115200 0010002
#define B230400 0010003
#define CIBAUD 002003600000 /* input baud rate (not used) */
#define CRTSCTS 020000000000 /* flow control */
......
......@@ -222,6 +222,7 @@ struct tty_struct {
*/
unsigned int column;
unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1;
unsigned char closing:1;
unsigned short minimum_to_wake;
unsigned overrun_time;
int num_overrun;
......
#define THREE_LEVEL
/*
* linux/ipc/shm.c
* Copyright (C) 1992, 1993 Krishna Balasubramanian
......@@ -20,7 +21,7 @@ extern int ipcperms (struct ipc_perm *ipcp, short shmflg);
extern unsigned int get_swap_page (void);
static int findkey (key_t key);
static int newseg (key_t key, int shmflg, int size);
static int shm_map (struct vm_area_struct *shmd, int remap);
static int shm_map (struct vm_area_struct *shmd);
static void killseg (int id);
static void shm_open (struct vm_area_struct *shmd);
static void shm_close (struct vm_area_struct *shmd);
......@@ -411,34 +412,16 @@ static inline void remove_attach (struct shmid_ds * shp, struct vm_area_struct *
}
/*
* check range is unmapped, ensure page tables exist
* ensure page tables exist
* mark page table entries with shm_sgn.
* if remap != 0 the range is remapped.
*/
static int shm_map (struct vm_area_struct *shmd, int remap)
static int shm_map (struct vm_area_struct *shmd)
{
pgd_t *page_dir;
pmd_t *page_middle;
pte_t *page_table;
unsigned long tmp, shm_sgn;
/* check that the range is unmapped */
if (!remap)
for (tmp = shmd->vm_start; tmp < shmd->vm_end; tmp += PAGE_SIZE) {
page_dir = PAGE_DIR_OFFSET(shmd->vm_task,tmp);
if (pgd_none(*page_dir))
continue;
if (pgd_bad(*page_dir)) {
printk("bad ipc page directory entry %08lx\n", pgd_val(*page_dir));
pgd_clear(page_dir);
continue;
}
page_table = (pte_t *) pgd_page(*page_dir);
page_table += ((tmp >> PAGE_SHIFT) & (PTRS_PER_PAGE-1));
if (!pte_none(*page_table)) {
/* printk("shmat() -> EINVAL because address 0x%lx is already mapped.\n",tmp); */
return -EINVAL;
}
}
int error;
/* clear old mappings */
do_munmap(shmd->vm_start, shmd->vm_end - shmd->vm_start);
......@@ -447,35 +430,17 @@ static int shm_map (struct vm_area_struct *shmd, int remap)
insert_vm_struct(current, shmd);
merge_segments(current, shmd->vm_start, shmd->vm_end);
/* check that the range has page_tables */
for (tmp = shmd->vm_start; tmp < shmd->vm_end; tmp += PAGE_SIZE) {
page_dir = PAGE_DIR_OFFSET(shmd->vm_task,tmp);
if (!pgd_none(*page_dir)) {
page_table = (pte_t *) pgd_page(*page_dir);
page_table += ((tmp >> PAGE_SHIFT) & (PTRS_PER_PAGE-1));
if (!pte_none(*page_table)) {
if (pte_present(*page_table)) {
--current->mm->rss;
free_page (pte_page(*page_table));
} else
swap_free(pte_val(*page_table));
pte_clear(page_table);
}
} else {
if (!(page_table = (pte_t *) get_free_page(GFP_KERNEL)))
return -ENOMEM;
pgd_set(page_dir, page_table);
tmp |= (PGDIR_SIZE - PAGE_SIZE);
}
}
/* map page range */
shm_sgn = shmd->vm_pte + ((shmd->vm_offset >> PAGE_SHIFT) << SHM_IDX_SHIFT);
for (tmp = shmd->vm_start; tmp < shmd->vm_end; tmp += PAGE_SIZE,
shm_sgn += (1 << SHM_IDX_SHIFT)) {
page_dir = PAGE_DIR_OFFSET(shmd->vm_task,tmp);
page_table = (pte_t *) pgd_page(*page_dir);
page_table += (tmp >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
page_dir = pgd_offset(shmd->vm_task,tmp);
page_middle = pmd_alloc(page_dir,tmp);
if (!page_middle)
break;
page_table = pte_alloc(page_middle,tmp);
if (!page_table)
break;
pte_val(*page_table) = shm_sgn;
}
invalidate();
......@@ -553,7 +518,7 @@ int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
shmd->vm_ops = &shm_vm_ops;
shp->shm_nattch++; /* prevent destruction */
if ((err = shm_map (shmd, shmflg & SHM_REMAP))) {
if ((err = shm_map (shmd))) {
if (--shp->shm_nattch <= 0 && shp->shm_perm.mode & SHM_DEST)
killseg(id);
kfree(shmd);
......@@ -749,6 +714,7 @@ int shm_swap (int prio)
for (shmd = shp->attaches; ; ) {
do {
pgd_t *page_dir;
pmd_t *page_middle;
pte_t *page_table, pte;
unsigned long tmp;
......@@ -759,15 +725,21 @@ int shm_swap (int prio)
tmp = shmd->vm_start + (idx << PAGE_SHIFT) - shmd->vm_offset;
if (!(tmp >= shmd->vm_start && tmp < shmd->vm_end))
continue;
page_dir = PAGE_DIR_OFFSET(shmd->vm_task,tmp);
page_dir = pgd_offset(shmd->vm_task,tmp);
if (pgd_none(*page_dir) || pgd_bad(*page_dir)) {
printk("shm_swap: bad pgtbl! id=%ld start=%lx idx=%ld\n",
id, shmd->vm_start, idx);
pgd_clear(page_dir);
continue;
}
page_table = (pte_t *) pgd_page(*page_dir);
page_table += ((tmp >> PAGE_SHIFT) & (PTRS_PER_PAGE-1));
page_middle = pmd_offset(page_dir,tmp);
if (pmd_none(*page_middle) || pmd_bad(*page_middle)) {
printk("shm_swap: bad pgmid! id=%ld start=%lx idx=%ld\n",
id, shmd->vm_start, idx);
pmd_clear(page_middle);
continue;
}
page_table = pte_offset(page_middle,tmp);
pte = *page_table;
if (!pte_present(pte))
continue;
......@@ -779,7 +751,8 @@ int shm_swap (int prio)
printk("shm_swap_out: page and pte mismatch\n");
pte_val(*page_table) = shmd->vm_pte | idx << SHM_IDX_SHIFT;
mem_map[MAP_NR(pte_page(pte))]--;
shmd->vm_task->mm->rss--;
if (shmd->vm_task->mm->rss > 0)
shmd->vm_task->mm->rss--;
invalid++;
/* continue looping through circular list */
} while (0);
......
......@@ -163,12 +163,11 @@ static void copy_fs(unsigned long clone_flags, struct task_struct * p)
* information (task[nr]) and sets up the necessary registers. It
* also copies the data segment in its entirety.
*/
asmlinkage int sys_fork(struct pt_regs regs)
int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
{
int nr;
struct task_struct *p;
unsigned long new_stack;
unsigned long clone_flags = COPYVM | SIGCHLD;
struct task_struct *p;
if(!(p = (struct task_struct*)__get_free_page(GFP_KERNEL)))
goto bad_fork;
......@@ -206,7 +205,7 @@ asmlinkage int sys_fork(struct pt_regs regs)
task[nr] = p;
/* copy all the process information */
clone_flags = copy_thread(nr, COPYVM | SIGCHLD, p, &regs);
copy_thread(nr, clone_flags, usp, p, regs);
if (copy_mm(clone_flags, p))
goto bad_fork_cleanup;
p->semundo = NULL;
......
......@@ -517,6 +517,7 @@ asmlinkage int sys_setsid(void)
current->leader = 1;
current->session = current->pgrp = current->pid;
current->tty = NULL;
current->tty_old_pgrp = 0;
return current->pgrp;
}
......
......@@ -506,11 +506,10 @@ static int swap_out_process(struct task_struct * p)
static int swap_out(unsigned int priority)
{
static int swap_task;
int loop;
int counter = NR_TASKS * 2 >> priority;
int loop, counter;
struct task_struct *p;
counter = NR_TASKS * 2 >> priority;
counter = 2*NR_TASKS >> priority;
for(; counter >= 0; counter--, swap_task++) {
/*
* Check that swap_task is suitable for swapping. If not, look for
......@@ -557,6 +556,15 @@ static int swap_out(unsigned int priority)
return 0;
}
/*
* we keep on shrinking one resource until it's considered "too hard",
* and then switch to the next one (priority being an indication on how
* hard we should try with the resource).
*
* This should automatically find the resource that can most easily be
* free'd, so hopefully we'll get reasonable behaviour even under very
* different circumstances.
*/
static int try_to_free_page(int priority)
{
static int state = 0;
......@@ -565,23 +573,19 @@ static int try_to_free_page(int priority)
switch (state) {
do {
case 0:
if (priority != GFP_NOBUFFER && shrink_buffers(i)) {
state = 1;
if (priority != GFP_NOBUFFER && shrink_buffers(i))
return 1;
}
state = 1;
case 1:
if (shm_swap(i)) {
state = 2;
if (shm_swap(i))
return 1;
}
case 2:
if (swap_out(i)) {
state = 0;
state = 2;
default:
if (swap_out(i))
return 1;
}
state = 0;
} while(--i);
}
state = 2;
return 0;
}
......
......@@ -864,11 +864,13 @@ static int inet_bind(struct socket *sock, struct sockaddr *uaddr,
{
/* should be below! */
if (sk2->num != snum) continue;
#if 0
if (sk2->dead)
{
destroy_sock(sk2);
goto outside_loop;
}
#endif
if (!sk->reuse)
{
sti();
......
......@@ -2769,9 +2769,9 @@ static void tcp_conn_request(struct sock *sk, struct sk_buff *skb,
newsk->linger=0;
newsk->destroy = 0;
init_timer(&newsk->timer);
init_timer(&newsk->retransmit_timer);
newsk->timer.data = (unsigned long)newsk;
newsk->timer.function = &net_timer;
init_timer(&newsk->retransmit_timer);
newsk->retransmit_timer.data = (unsigned long)newsk;
newsk->retransmit_timer.function=&retransmit_timer;
newsk->dummy_th.source = skb->h.th->dest;
......@@ -4393,7 +4393,9 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
tcp_set_state(sk,TCP_SYN_SENT);
sk->rto = TCP_TIMEOUT_INIT;
init_timer(&sk->retransmit_timer);
#if 0 /* we already did this */
init_timer(&sk->retransmit_timer);
#endif
sk->retransmit_timer.function=&retransmit_timer;
sk->retransmit_timer.data = (unsigned long)sk;
reset_xmit_timer(sk, TIME_WRITE, sk->rto); /* Timer for repeating the SYN until an answer */
......
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