Commit f6cce5da authored by Linus Torvalds's avatar Linus Torvalds

Linux 2.2.0

> Compile this code
>
> ---- cut here ----
> #include <fcntlbits.h>
> void main( int argc, char *argv[] ) {
>         open( argv[ 1 ], O_WRONLY|O_CREAT|O_TRUNC, 0666 );
> }
> ---- and here  ----
>
> and run it like this
>
>     strace ./a.out >(cat - )
>
> with 2.0.36 & 2.2.0-pre[67] you get:
>
>     open("/dev/fd/63", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
>
> with 2.2.0-pre[89] you get:
>
>     open("/dev/fd/63", O_WRONLY|O_CREAT|O_TRUNC, 0666) = -1 ENOENT (No
> such file or directory)

Ok, this seems to be due to pre9 removing some rather bogus code that
happened to hide another problem in open_namei().
I haven't actually tested this, but it looks really obvious, so does this
patch fix it for you? (This should also fix a potential performance
bogosity - there's absolutely no reason why we should get the directory
lock when we don't need to for a normal open of an existing file).

                Linus
parent 182f4220
VERSION = 2
PATCHLEVEL = 2
SUBLEVEL = 0
EXTRAVERSION =-final
EXTRAVERSION =
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
......
......@@ -49,7 +49,11 @@ ifeq ($(have_mcpu),y)
ifeq ($(have_mcpu_ev6),y)
CFLAGS := $(CFLAGS) -mcpu=ev6
else
CFLAGS := $(CFLAGS) -mcpu=pca56
ifeq ($(have_mcpu_pca56),y)
CFLAGS := $(CFLAGS) -mcpu=pca56
else
CFLAGS := $(CFLAGS) -mcpu=ev56
endif
endif
endif
endif
......@@ -72,6 +76,9 @@ else
ifeq ($(CONFIG_ALPHA_POLARIS),y)
CFLAGS := $(CFLAGS) -Wa,-m21164pc
endif
ifeq ($(CONFIG_ALPHA_TSUNAMI),y)
CFLAGS := $(CFLAGS) -Wa,-mev6
endif
endif
HEAD := arch/alpha/kernel/head.o
......
......@@ -10,7 +10,7 @@
#define rti .long PAL_rti
#define SIGCHLD 20
#define NR_SYSCALLS 370
#define NR_SYSCALLS 371
/*
* These offsets must match with alpha_mv in <asm/machvec.h>.
......@@ -1138,4 +1138,4 @@ sys_call_table:
.quad sys_getcwd
.quad sys_capget
.quad sys_capset
.quad sys_ni_syscall /* 370 */
.quad sys_sendfile /* 370 */
......@@ -211,8 +211,6 @@ rx164_pci_fixup(void)
* The System Vector
*/
#define POLARIS_IACK_SC POLARIS_IACK_BASE /* hack, move to header */
struct alpha_machine_vector rx164_mv __initmv = {
vector_name: "RX164",
DO_EV5_MMU,
......
......@@ -232,7 +232,7 @@ noname_pci_fixup(void)
* selected... :-(
*/
layout_all_busses(DEFAULT_IO_BASE, APECS_AND_LCA_DEFAULT_MEM_BASE);
sio_pci_fixup(noname_map_irq, 0x0b0a0f0e);
sio_pci_fixup(noname_map_irq, 0x0b0a0f0d);
sio_fixup_irq_levels(sio_collect_irq_levels());
enable_ide(0x26e);
}
......
......@@ -76,7 +76,6 @@ __down_failed:
.globl __down_failed_interruptible
.ent __down_failed_interruptible
__down_failed_interruptible:
ldgp $29,0($27)
ldgp $29,0($27)
lda $30, -20*8($30)
stq $28, 0*8($30)
......
......@@ -341,6 +341,13 @@ __initfunc(void setup_arch(char **cmdline_p,
*memory_start_p = memory_start;
*memory_end_p = memory_end;
#ifdef __SMP__
/*
* Save possible boot-time SMP configuration:
*/
init_smp_config();
#endif
#ifdef CONFIG_BLK_DEV_INITRD
if (LOADER_TYPE) {
initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
......
This diff is collapsed.
......@@ -279,39 +279,6 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_
* kernel.
* It may also hold the MP configuration table when we are booting SMP.
*/
#ifdef __SMP__
/*
* FIXME: Linux assumes you have 640K of base ram..
* this continues the error...
*
* 1) Scan the bottom 1K for a signature
* 2) Scan the top 1K of base RAM
* 3) Scan the 64K of bios
*/
if (!smp_scan_config(0x0,0x400) &&
!smp_scan_config(639*0x400,0x400) &&
!smp_scan_config(0xF0000,0x10000)) {
/*
* If it is an SMP machine we should know now, unless the
* configuration is in an EISA/MCA bus machine with an
* extended bios data area.
*
* there is a real-mode segmented pointer pointing to the
* 4K EBDA area at 0x40E, calculate and scan it here.
*
* NOTE! There are Linux loaders that will corrupt the EBDA
* area, and as such this kind of SMP config may be less
* trustworthy, simply because the SMP table may have been
* stomped on during early boot. These loaders are buggy and
* should be fixed.
*/
address = *(unsigned short *)phys_to_virt(0x40E);
address<<=4;
smp_scan_config(address, 0x1000);
if (smp_found_config)
printk(KERN_WARNING "WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.rutgers.edu if you experience SMP problems!\n");
}
#endif
start_mem = PAGE_ALIGN(start_mem);
address = PAGE_OFFSET;
pg_dir = swapper_pg_dir;
......
......@@ -150,22 +150,15 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = {
*/
__initfunc(static unsigned int ide_special_settings (struct pci_dev *dev, const char *name))
{
unsigned int addressbios = 0;
pci_read_config_dword(dev, PCI_ROM_ADDRESS, &addressbios);
switch(dev->device) {
case PCI_DEVICE_ID_ARTOP_ATP850UF:
case PCI_DEVICE_ID_PROMISE_20246:
pci_write_config_byte(dev, PCI_ROM_ADDRESS, PCI_ROM_ADDRESS_ENABLE);
printk("%s: ROM enabled ", name);
if (!addressbios) {
printk("but no address\n");
} else {
printk("at 0x%08x\n", addressbios);
if (dev->rom_address) {
pci_write_config_byte(dev, PCI_ROM_ADDRESS,
dev->rom_address | PCI_ROM_ADDRESS_ENABLE);
printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->rom_address);
}
if ((dev->class >> 8) == PCI_CLASS_STORAGE_RAID) {
unsigned char irq1 = 0, irq2 = 0;
......
......@@ -535,6 +535,8 @@ static struct tvcard tvcards[] =
{ 3, 4, 0, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0}, 0},
/* AVerMedia TVCapture 98 */
{ 3, 4, 0, 2, 15, { 2, 3, 1, 1}, { 13, 14, 11, 7, 0, 0}, 0},
/* Aimslab VHX */
{ 3, 1, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4}},
};
#define TVCARDS (sizeof(tvcards)/sizeof(tvcard))
......@@ -764,7 +766,7 @@ static struct tvnorm tvnorms[] = {
/* NTSC */
{ 28636363,
768, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0),
910, 128, 754, 0x1a, 144},
910, 128, 910, 0x1a, 144},
/*
{ 28636363,
640, 480, 910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0),
......@@ -815,10 +817,6 @@ static void make_vbitab(struct bttv *btv)
DEBUG(printk(KERN_DEBUG "po: 0x%08x\n",(int)po));
DEBUG(printk(KERN_DEBUG "pe: 0x%08x\n",(int)pe));
/* setup proper VBI capture length for given video mode */
btwrite(tvnorms[btv->win.norm].vbipack, BT848_VBI_PACK_SIZE);
btwrite(1, BT848_VBI_PACK_DEL);
*(po++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(po++)=0;
for (i=0; i<16; i++)
{
......@@ -1281,6 +1279,8 @@ static void bt848_set_geo(struct bttv *btv, u16 width, u16 height, u16 fmt)
btwrite(tvn->adelay, BT848_ADELAY);
btwrite(tvn->bdelay, BT848_BDELAY);
btaor(tvn->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), BT848_IFORM);
btwrite(tvn->vbipack, BT848_VBI_PACK_SIZE);
btwrite(1, BT848_VBI_PACK_DEL);
btv->pll.pll_ofreq = tvn->Fsc;
set_pll(btv);
......@@ -2880,7 +2880,9 @@ static void idcard(int i)
} else if (I2CRead(&(btv->i2c), I2C_STBEE)>=0) {
btv->type=BTTV_STB;
} else
if (I2CRead(&(btv->i2c), I2C_VHX)>=0) {
btv->type=BTTV_VHX;
} else {
if (I2CRead(&(btv->i2c), 0x80)>=0) /* check for msp34xx */
btv->type = BTTV_MIROPRO;
......@@ -2938,6 +2940,9 @@ static void idcard(int i)
case TDA9850:
init_tda9850(&(btv->i2c));
break;
case TDA9840:
init_tda9840(&(btv->i2c));
break;
case TDA8425:
init_tda8425(&(btv->i2c));
break;
......@@ -2977,6 +2982,9 @@ static void idcard(int i)
case BTTV_AVERMEDIA98:
strcat(btv->video_dev.name,"(AVerMedia TVCapture 98)");
break;
case BTTV_VHX:
strcpy(btv->video_dev.name,"BT848(Aimslab-VHX)");
break;
}
printk("%s\n",btv->video_dev.name);
audio(btv, AUDIO_MUTE);
......
......@@ -21,7 +21,7 @@
#ifndef _BTTV_H_
#define _BTTV_H_
#define BTTV_VERSION_CODE 0x000520
#define BTTV_VERSION_CODE 0x000523
#include <linux/types.h>
#include <linux/wait.h>
......@@ -37,8 +37,7 @@
#define MAX_GBUFFERS 2
#define RISCMEM_LEN (32744*2)
#define VBI_MAXLINES 19
#define VBIBUF_SIZE (2048*VBI_MAXLINES*2)
#define VBIBUF_SIZE 65536
/* maximum needed buffer size for extended VBI frame mode capturing */
#define BTTV_MAX_FBUF 0x190000
......@@ -207,6 +206,7 @@ struct bttv
#define BTTV_MIROPRO 0x0b
#define BTTV_ADSTECH_TV 0x0c
#define BTTV_AVERMEDIA98 0x0d
#define BTTV_VHX 0x0e
#define AUDIO_TUNER 0x00
#define AUDIO_RADIO 0x01
......@@ -227,6 +227,7 @@ struct bttv
#define I2C_TDA8425 0x82
#define I2C_HAUPEE 0xa0
#define I2C_STBEE 0xae
#define I2C_VHX 0xc0
#define TDA9840_SW 0x00
#define TDA9840_LVADJ 0x02
......
......@@ -4,6 +4,7 @@
* Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/tpqic02.h>
......
......@@ -83,7 +83,7 @@ struct msp3400c {
/* thread */
struct task_struct *thread;
struct semaphore *wait;
struct wait_queue *wq;
struct semaphore *notify;
int active,restart,rmmod;
......@@ -500,14 +500,12 @@ static void msp3400c_stereo_wake(unsigned long data)
{
struct msp3400c *msp = (struct msp3400c*)data; /* XXX alpha ??? */
if (!msp->active)
up(msp->wait);
wake_up_interruptible(&msp->wq);
}
static int msp3400c_thread(void *data)
{
struct msp3400c *msp = data;
struct semaphore sem = MUTEX_LOCKED;
struct CARRIER_DETECT *cd;
int count, max1,max2,val1,val2, val,this;
......@@ -525,7 +523,7 @@ static int msp3400c_thread(void *data)
current->fs->umask = 0;
strcpy(current->comm,"msp3400");
msp->wait = &sem;
msp->wq = NULL;
msp->thread = current;
#ifdef __SMP__
......@@ -541,7 +539,7 @@ static int msp3400c_thread(void *data)
goto done;
if (debug > 1)
printk("msp3400: thread: sleep\n");
down_interruptible(&sem);
interruptible_sleep_on(&msp->wq);
if (debug > 1)
printk("msp3400: thread: wakeup\n");
if (msp->rmmod || signal_pending(current))
......@@ -735,7 +733,6 @@ static int msp3400c_thread(void *data)
done:
dprintk("msp3400: thread: exit\n");
msp->wait = NULL;
msp->active = 0;
msp->thread = NULL;
......@@ -777,6 +774,7 @@ static int msp3410d_thread(void *data)
goto done;
dprintk("msp3410: thread: sleep\n");
down_interruptible(&sem);
sem.owner = 0;
dprintk("msp3410: thread: wakeup\n");
if (msp->rmmod)
goto done;
......@@ -1072,12 +1070,12 @@ static int msp3400c_attach(struct i2c_device *device)
/* startup control thread */
MOD_INC_USE_COUNT;
msp->wq = NULL;
msp->notify = &sem;
kernel_thread(msp3400c_thread, (void *)msp, 0);
down(&sem);
msp->notify = NULL;
if (!msp->active)
up(msp->wait);
wake_up_interruptible(&msp->wq);
printk(KERN_INFO "msp3400: init: chip=%s",device->name);
if (msp->nicam)
......@@ -1109,8 +1107,7 @@ static int msp3400c_detach(struct i2c_device *device)
{
msp->notify = &sem;
msp->rmmod = 1;
if (!msp->active)
up(msp->wait);
wake_up_interruptible(&msp->wq);
down(&sem);
msp->notify = NULL;
}
......@@ -1158,10 +1155,9 @@ static int msp3400c_command(struct i2c_device *device,
/* channels switching step two -- trigger sound carrier scan */
msp->watch_stereo=0;
del_timer(&msp->wake_stereo);
if (!msp->active)
up(msp->wait);
else
if (msp->active)
msp->restart = 1;
wake_up_interruptible(&msp->wq);
break;
case MSP_GET_VOLUME:
......
......@@ -79,11 +79,11 @@ static int aux_count = 0;
#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
#define MAX_RETRIES 60 /* some aux operations take long time*/
#if defined(__alpha__) && !defined(CONFIG_PCI)
# define AUX_IRQ 9 /* Jensen is odd indeed */
#else
#ifndef AUX_IRQ
# define AUX_IRQ 12
#endif
#endif /* CONFIG_PSMOUSE */
/*
......@@ -811,7 +811,7 @@ static int release_aux(struct inode * inode, struct file * file)
if (--aux_count)
return 0;
kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */
kbd_write(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG);
kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_DISABLE);
free_irq(AUX_IRQ, AUX_DEV);
return 0;
}
......@@ -831,7 +831,7 @@ static int open_aux(struct inode * inode, struct file * file)
aux_count--;
return -EBUSY;
}
kbd_write(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG); /* Enable the
kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE); /* Enable the
auxiliary port on
controller. */
aux_write_dev(AUX_ENABLE_DEV); /* Enable aux device */
......@@ -950,14 +950,14 @@ static int __init psaux_init(void)
queue->proc_list = NULL;
#ifdef INITIALIZE_MOUSE
kbd_write(KBD_CCMD_MOUSE_ENABLE, KBD_CNTL_REG); /* Enable Aux. */
kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */
aux_write_dev(AUX_SET_SAMPLE);
aux_write_dev(100); /* 100 samples/sec */
aux_write_dev(AUX_SET_RES);
aux_write_dev(3); /* 8 counts per mm */
aux_write_dev(AUX_SET_SCALE21); /* 2:1 scaling */
#endif /* INITIALIZE_MOUSE */
kbd_write(KBD_CCMD_MOUSE_DISABLE, KBD_CNTL_REG); /* Disable aux device. */
kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */
kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */
return 0;
......
......@@ -801,10 +801,10 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
struct tok_info *ti;
struct device *dev;
dev = dev_id;
#if TR_VERBOSE
DPRINTK("Int from tok_driver, dev : %p\n",dev);
#endif
dev = dev_id;
ti = (struct tok_info *) dev->priv;
/* Disable interrupts till processing is finished */
......
......@@ -53,7 +53,6 @@
#include <asm/bitops.h>
#include <asm/io.h>
#include <linux/errno.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/skbuff.h>
......
......@@ -42,7 +42,6 @@
#include <linux/malloc.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/config.h>
#include <linux/init.h>
#include <asm/io.h>
......
......@@ -70,6 +70,7 @@ pci_clone_list[] __initdata = {
{0x4a14, 0x5000, "NetVin NV5000SC"},
{0x1106, 0x0926, "Via 82C926"},
{0x10bd, 0x0e34, "SureCom NE34"},
{0x1050, 0x5a5a, "Winbond"},
{0,}
};
......
#ifndef __MEGARAID_H__
#define __MEGARAID_H__
#include <linux/version.h>
#define IN_ISR 0x80000000L
#define NO_INTR 0x40000000L
#define IN_TIMEOUT 0x20000000L
......
/*
AD1816 lowlevel sound driver for Linux 2.1.128 (and above)
AD1816 lowlevel sound driver for Linux 2.2.0 and above
Copyright (C) 1998 by Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de>
Based on the CS4232/AD1848 driver Copyright (C) by Hannu Savolainen 1993-1996
......@@ -32,16 +32,18 @@ Please report any bugs to: tek@rbg.informatik.tu-darmstadt.de
-------------------------------------------------------------------------------
version: 1.1
cvs: $Header: /home/tek/tmp/CVSROOT/sound21/ad1816.c,v 1.24.2.8 1998/12/04 16:39:46 tek Exp $
version: 1.2
cvs: $Header: /home/tek/tmp/CVSROOT/sound21/ad1816.c,v 1.28 1999/01/16 19:01:36 tek Exp $
status: experimental
date: 1998/12/04
date: 1999/01/16
Changes:
Oleg Drokin: Some cleanup of load/unload functions. 1998/11/24
Thorsten Knabe: attach and unload rewritten,
some argument checks added 1998/11/30
Thorsten Knabe: Buggy isa bridge workaround added 1999/01/16
*/
#include <linux/config.h>
......@@ -164,7 +166,9 @@ static void ad1816_halt_input (int dev)
save_flags (flags);
cli ();
disable_dma(audio_devs[dev]->dmap_in->dma);
if(!isa_dma_bridge_buggy) {
disable_dma(audio_devs[dev]->dmap_in->dma);
}
buffer=inb(devc->base+9);
if (buffer & 0x01) {
......@@ -172,8 +176,10 @@ static void ad1816_halt_input (int dev)
outb(buffer & ~0x01,devc->base+9);
}
enable_dma(audio_devs[dev]->dmap_in->dma);
if(!isa_dma_bridge_buggy) {
enable_dma(audio_devs[dev]->dmap_in->dma);
}
/* Clear interrupt status */
outb (~0x40, devc->base+1);
......@@ -195,15 +201,20 @@ static void ad1816_halt_output (int dev)
/* Mute pcm output */
ad_write(devc, 4, ad_read(devc,4)|0x8080);
disable_dma(audio_devs[dev]->dmap_out->dma);
if(!isa_dma_bridge_buggy) {
disable_dma(audio_devs[dev]->dmap_out->dma);
}
buffer=inb(devc->base+8);
if (buffer & 0x01) {
/* disable capture */
outb(buffer & ~0x01,devc->base+8);
}
enable_dma(audio_devs[dev]->dmap_out->dma);
if(!isa_dma_bridge_buggy) {
enable_dma(audio_devs[dev]->dmap_out->dma);
}
/* Clear interrupt status */
outb ((unsigned char)~0x80, devc->base+1);
......@@ -707,11 +718,11 @@ MIX_ENT(SOUND_MIXER_LINE3, 39, 0, 9, 4, 39, 1, 0, 5)
static unsigned short default_mixer_levels[SOUND_MIXER_NRDEVICES] =
{
0x6464, /* Master Volume */
0x4343, /* Master Volume */
0x3232, /* Bass */
0x3232, /* Treble */
0x0000, /* FM */
0x6464, /* PCM */
0x4343, /* PCM */
0x0000, /* PC Speaker */
0x0000, /* Ext Line */
0x0000, /* Mic */
......@@ -1080,7 +1091,13 @@ int probe_ad1816 ( struct address_info *hw_config )
int tmp;
printk("ad1816: AD1816 sounddriver Copyright (C) 1998 by Thorsten Knabe\n");
printk("ad1816: $Header: /home/tek/tmp/CVSROOT/sound21/ad1816.c,v 1.24.2.8 1998/12/04 16:39:46 tek Exp $\n");
printk("ad1816: $Header: /home/tek/tmp/CVSROOT/sound21/ad1816.c,v 1.28 1999/01/16 19:01:36 tek Exp $\n");
printk("ad1816: io=0x%x, irq=%d, dma=%d, dma2=%d, isadmabug=%d\n",
hw_config->io_base,
hw_config->irq,
hw_config->dma,
hw_config->dma2,
isa_dma_bridge_buggy);
if (check_region (io_base, 16)) {
printk ("ad1816: I/O port 0x%03x not free\n", io_base);
......
......@@ -136,6 +136,7 @@ int trix = 0; /* Set trix=1 to load this as support for trix */
int pas2 = 0; /* Set pas2=1 to load this as support for pas2 */
int sm_games = 0; /* Mixer - see sb_mixer.c */
int acer = 0; /* Do acer notebook init */
int esstype = 0; /* ESS chip type */
MODULE_PARM(io, "i");
MODULE_PARM(irq, "i");
......@@ -147,6 +148,7 @@ MODULE_PARM(mad16, "i");
MODULE_PARM(trix, "i");
MODULE_PARM(pas2, "i");
MODULE_PARM(sm_games, "i");
MODULE_PARM(esstype, "i");
void *smw_free = NULL;
......
......@@ -645,10 +645,6 @@ int sb_dsp_init(struct address_info *hw_config)
}
}
}
#if defined(__SMP__)
/* Skip IRQ detection if SMP (doesn't work) */
devc->irq_ok = 1;
#else
if (devc->major == 4 && devc->minor <= 11 ) /* Won't work */
devc->irq_ok = 1;
else
......@@ -671,7 +667,6 @@ int sb_dsp_init(struct address_info *hw_config)
DDB(printk("IRQ test OK (IRQ%d)\n", devc->irq));
}
}
#endif /* __SMP__ */
} /* IRQ setup */
request_region(hw_config->io_base, 16, "soundblaster");
......
......@@ -2,8 +2,6 @@
* Created: 9-Jan-1999
*
* TODO: consistency speed calculations!!
* what's the sample rate when duplex? Docs contradict.
* I broke IRQ detection for non-SMP machines
* ????: Did I break MIDI support?
*
* This files contains ESS chip specifics. It's based on the existing ESS
......@@ -19,6 +17,10 @@
* be one of 0, 1 or 3, dma16 can be one of 0, 1, 3 or 5. DMA 5 is a 16 bit
* DMA channel, while the others are 8 bit..
*
* ESS detection isn't full proof (yet). If it fails an additional module
* parameter esstype can be specified to be one of the following:
* 688, 1688, 1868, 1869, 1788, 1887, 1888
*
* History:
*
* Rolf Fokkens (Dec 20 1998): ES188x recording level support on a per
......@@ -77,6 +79,9 @@
* Oh, and this is another trap: in ES1887 docs mixer register 0x70 is decribed
* as if it's exactly the same as register 0xa1. This is *NOT* true. The
* description of 0x70 in ES1869 docs is accurate however.
* Well, the assumption about ES1869 was wrong: register 0x70 is very much
* like register 0xa1, except that bit 7 is allways 1, whatever you want
* it to be.
*
* When using audio 2 mixer register 0x72 seems te be meaningless. Only 0xa2
* has effect.
......@@ -85,6 +90,16 @@
* the fact that register 0x78 isn't reset is great when you wanna change back
* to single dma operation (simplex): audio 2 is still operation, and uses the
* same dma as audio 1: your ess changes into a funny echo machine.
*
* Received the new that ES1688 is detected as a ES1788. Did some thinking:
* the ES1887 detection scheme suggests in step 2 to try if bit 3 of register
* 0x64 can be changed. This is inaccurate, first I inverted the * check: "If
* can be modified, it's a 1688", which lead to a correct detection
* of my ES1887. It resulted however in bad detection of 1688 (reported by mail)
* and 1868 (if no PnP detection first): they result in a 1788 being detected.
* I don't have docs on 1688, but I do have docs on 1868: The documentation is
* probably inaccurate in the fact that I should check bit 2, not bit 3. This
* is what I do now.
*/
/*
......@@ -141,14 +156,14 @@
* ES1946 yes This is a PCI chip; not handled by this driver
*/
#include <linux/delay.h>
#include "sound_config.h"
#include "sb_mixer.h"
#include "sb.h"
#include "sb_ess.h"
extern int esstype; /* module parameter in sb_card.c */
#ifdef FKS_LOGGING
static void ess_show_mixerregs (sb_devc *devc);
#endif
......@@ -255,10 +270,10 @@ static int ess_calc_div (int clock, int revert, int *speedp, int *diffp)
int retval;
speed = *speedp;
divider = (clock + speed / 2) / *speedp;
divider = (clock + speed / 2) / speed;
retval = revert - divider;
if (retval > 127) {
retval = 127;
if (retval > revert - 1) {
retval = revert - 1;
divider = revert - retval;
}
/* This line is suggested. Must be wrong I think
......@@ -299,60 +314,59 @@ static int ess_calc_best_speed
/*
* Depending on the audiochannel ESS devices can
* have different clock settings.
* have different clock settings. These are made consistent for duplex
* however.
* callers of ess_speed only do an audionum suggestion, which means
* input suggests 1, output suggests 2. This suggestion is only true
* however when doing duplex.
*/
static void ess_speed (sb_devc *devc, int audionum)
static void ess_common_speed (sb_devc *devc, int *speedp, int *divp)
{
int choice;
int speed = devc->speed;
int clock1, clock2;
int rev1, rev2;
int div;
if (!devc->duplex) audionum = 1;
int diff = 0, div, choice;
if (audionum == 1) {
rev1 = 128;
clock1 = 397700;
rev2 = 256;
clock2 = 795500;
if (devc->duplex) {
/*
* The 0x80 is important for the first audio channel
*/
div = 0x80 | ess_calc_div (795500, 128, speedp, &diff);
} else {
rev1 = 128;
clock1 = 793800;
rev2 = 128;
clock2 = 768000;
choice = ess_calc_best_speed (397700, 128, 795500, 256, &div, speedp);
if (choice == 2) div |= 0x80;
}
choice = ess_calc_best_speed
(clock1, rev1, clock2, rev2, &div, &speed);
*divp = div;
}
static void ess_speed (sb_devc *devc, int audionum)
{
int speed;
int div, div2;
ess_common_speed (devc, &(devc->speed), &div);
#ifdef FKS_REG_LOGGING
printk (KERN_INFO "FKS: ess_speed (%d) b speed = %d, div=%x\n", audionum, speed, div);
printk (KERN_INFO "FKS: ess_speed (%d) b speed = %d, div=%x\n", audionum, devc->speed, div);
#endif
if (choice == 2) div |= 0x80;
/* Set filter roll-off to 90% of speed/2 */
speed = (devc->speed * 9) / 20;
div2 = 256 - 7160000 / (speed * 82);
if (!devc->duplex) audionum = 1;
if (audionum == 1) {
/* Change behaviour of register A1 *
sb_chg_mixer(devc, 0x71, 0x20, 0x20)
* For ES1869 only??? */
ess_write (devc, 0xa1, div);
ess_write (devc, 0xa2, div2);
} else {
ess_setmixer (devc, 0x70, div);
}
/* Set filter roll-off to 90% of speed/2 */
speed = (speed * 9) / 20;
div = 256 - 7160000 / (speed * 82);
if (audionum == 1) {
ess_write (devc, 0xa2, div);
} else {
ess_write (devc, 0xa2, div);
ess_setmixer (devc, 0x72, div);
/*
* FKS: fascinating: 0x72 doesn't seem to work.
*/
ess_write (devc, 0xa2, div2);
ess_setmixer (devc, 0x72, div2);
}
}
......@@ -442,7 +456,9 @@ static int ess_audio_prepare_for_output_audio2 (int dev, int bsize, int bcount)
sb_devc *devc = audio_devs[dev]->devc;
unsigned char bits;
/* FKS: qqq
sb_dsp_reset(devc);
*/
/*
* Auto-Initialize:
......@@ -626,31 +642,19 @@ static void ess_audio_trigger(int dev, int bits)
devc->trigger_bits = bits | bits_16;
}
/*
* FKS: Change this!! it's the old routine!
*/
static int ess_audio_set_speed(int dev, int speed)
{
sb_devc *devc = audio_devs[dev]->devc;
int divider;
int minspeed, maxspeed, dummydiv;
if (speed > 0)
{
if (speed < 5000)
speed = 5000;
if (speed > 48000)
speed = 48000;
if (speed > 0) {
minspeed = (devc->duplex ? 6215 : 5000 );
maxspeed = (devc->duplex ? 44100 : 48000);
if (speed < minspeed) speed = minspeed;
if (speed > maxspeed) speed = maxspeed;
ess_common_speed (devc, &speed, &dummydiv);
if (speed > 22000)
{
divider = (795500 + speed / 2) / speed;
speed = (795500 + divider / 2) / divider;
}
else
{
divider = (397700 + speed / 2) / speed;
speed = (397700 + divider / 2) / divider;
}
devc->speed = speed;
}
return devc->speed;
......@@ -972,7 +976,7 @@ int ess_init(sb_devc * devc, struct address_info *hw_config)
unsigned char cfg;
int ess_major = 0, ess_minor = 0;
int i;
static char name[100];
static char name[100], modelname[10];
/*
* Try to detect ESS chips.
......@@ -1022,13 +1026,42 @@ int ess_init(sb_devc * devc, struct address_info *hw_config)
if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) {
char *chip = NULL;
if ((ess_minor & 0x0f) < 8) {
if (esstype) {
int submodel = -1;
switch (esstype) {
case 688:
submodel = 0x00;
break;
case 1688:
submodel = 0x08;
break;
case 1868:
submodel = SUBMDL_ES1868;
break;
case 1869:
submodel = SUBMDL_ES1869;
break;
case 1788:
submodel = SUBMDL_ES1788;
break;
case 1887:
submodel = SUBMDL_ES1887;
break;
case 1888:
submodel = SUBMDL_ES1888;
break;
};
if (submodel != -1) {
devc->submodel = submodel;
sprintf (modelname, "ES%d", esstype);
chip = modelname;
};
};
if (chip == NULL && (ess_minor & 0x0f) < 8) {
chip = "ES688";
};
#ifdef FKS_LOGGING
printk(KERN_INFO "FKS: mixer_reset\n");
ess_setmixer (devc, 0x00, 0x00);
#endif
if (chip == NULL) {
int type;
......@@ -1049,7 +1082,24 @@ printk(KERN_INFO "FKS: mixer_reset\n");
break;
};
};
if (chip == NULL && !ess_probe(devc, 0x64, (1 << 3))) {
#if 0
/*
* this one failed:
* the probing of bit 4 is another thought: from ES1788 and up, all
* chips seem to have hardware volume control. Bit 4 is readonly to
* check if a hardware volume interrupt has fired.
* Cause ES688/ES1688 don't have this feature, bit 4 might be writeable
* for these chips.
*/
if (chip == NULL && !ess_probe(devc, 0x64, (1 << 4))) {
#endif
/*
* the probing of bit 2 is my idea. The ES1887 docs want me to probe
* bit 3. This results in ES1688 being detected as ES1788.
* Bit 2 is for "Enable HWV IRQE", but as ES(1)688 chips don't have
* HardWare Volume, I think they don't have this IRQE.
*/
if (chip == NULL && ess_probe(devc, 0x64, (1 << 2))) {
if (ess_probe (devc, 0x70, 0x7f)) {
if (ess_probe (devc, 0x64, (1 << 5))) {
chip = "ES1887";
......
......@@ -425,7 +425,6 @@ static int set_recmask(sb_devc * devc, int mask)
if (devc->model == MDL_ESS && ess_set_recmask (devc, &devmask)) {
break;
};
printk (KERN_INFO "FKS: set_recmask not handled by ess_set_recmask\n");
if (devmask != SOUND_MASK_MIC &&
devmask != SOUND_MASK_LINE &&
devmask != SOUND_MASK_CD)
......
......@@ -83,19 +83,21 @@ int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
}
cnp = ITOC(*inode);
if ( cnp->c_magic == 0 ) {
memset(cnp, 0, (int) sizeof(struct coda_inode_info));
cnp->c_fid = *fid;
cnp->c_magic = CODA_CNODE_MAGIC;
cnp->c_flags = 0;
cnp->c_vnode = *inode;
INIT_LIST_HEAD(&(cnp->c_cnhead));
INIT_LIST_HEAD(&(cnp->c_volrootlist));
} else {
cnp->c_flags = 0;
printk("coda_cnode make on initialized inode %ld, %s!\n",
(*inode)->i_ino, coda_f2s(&cnp->c_fid));
}
if ( cnp->c_magic != 0 ) {
printk("coda_cnode make on initialized inode %ld, old %s new
%s!\n",
(*inode)->i_ino, coda_f2s(&cnp->c_fid), coda_f2s2(fid));
iput(*inode);
return -ENOENT;
}
memset(cnp, 0, (int) sizeof(struct coda_inode_info));
cnp->c_fid = *fid;
cnp->c_magic = CODA_CNODE_MAGIC;
cnp->c_flags = 0;
cnp->c_vnode = *inode;
INIT_LIST_HEAD(&(cnp->c_cnhead));
INIT_LIST_HEAD(&(cnp->c_volrootlist));
/* fill in the inode attributes */
if ( coda_f2i(fid) != ino ) {
......
......@@ -30,7 +30,7 @@ int coda_debug = 0;
int coda_print_entry = 0;
int coda_access_cache = 1;
/* caller must allocate 36 byte string ! */
/* print a fid */
char * coda_f2s(ViceFid *f)
{
static char s[60];
......@@ -41,6 +41,17 @@ char * coda_f2s(ViceFid *f)
return s;
}
/* print another fid */
char * coda_f2s2(ViceFid *f)
{
static char s[60];
if ( f ) {
sprintf(s, "(%-#lx,%-#lx,%-#lx)",
f->Volume, f->Vnode, f->Unique);
}
return s;
}
/* recognize special .CONTROL name */
int coda_iscontrol(const char *name, size_t length)
{
......
/*
* Directory operations for Coda filesystem
* Original version: (C) 1996 P. Braam and M. Callahan
......@@ -834,12 +835,19 @@ CDEBUG(D_FILE, "entry %d: ino %ld, namlen %d, reclen %d, type %d, pos %d, string
if ( !vdirent->d_reclen ) {
printk("CODA: Invalid directory, cfino: %ld\n",
filp->f_dentry->d_inode->i_ino);
result = -EINVAL;
break;
}
pos += (unsigned int) vdirent->d_reclen;
i++;
}
if ( i >= 1024 ) {
printk("Repeating too much in readdir %ld\n",
filp->f_dentry->d_inode->i_ino);
result = -EINVAL;
}
exit:
CODA_FREE(buff, DIR_BUFSIZE);
return result;
......@@ -853,18 +861,35 @@ static int coda_dentry_revalidate(struct dentry *de)
struct coda_inode_info *cii;
ENTRY;
if (inode) {
if (is_bad_inode(inode))
return 0;
cii = ITOC(de->d_inode);
if (cii->c_flags & C_PURGE)
valid = 0;
if (cii->c_flags & C_FLUSH) {
coda_flag_inode_children(inode, C_FLUSH);
valid = 0;
}
if (!inode)
return 1;
cii = ITOC(de->d_inode);
if (coda_isroot(inode))
return 1;
if (is_bad_inode(inode))
return 0;
if (! (cii->c_flags & (C_PURGE | C_FLUSH)) )
return valid;
shrink_dcache_parent(de);
if (de->d_count > 1) {
/* pretend it's valid, but don't change the flags */
CDEBUG(D_DOWNCALL, "BOOM for: ino %ld, %s\n",
de->d_inode->i_ino, coda_f2s(&cii->c_fid));
return 1;
}
return valid || coda_isroot(de->d_inode);
/* propagate for a flush */
if (cii->c_flags & C_FLUSH)
coda_flag_inode_children(inode, C_FLUSH);
/* clear the flags. */
cii->c_flags &= ~(C_VATTR | C_PURGE | C_FLUSH);
return 0;
}
/*
......
......@@ -480,17 +480,6 @@ struct dentry * d_alloc(struct dentry * parent, const struct qstr *name)
char * str;
struct dentry *dentry;
/*
* Prune the dcache if there are too many unused dentries.
*/
if (dentry_stat.nr_unused > 3*(nr_inodes >> 1)) {
#ifdef DCACHE_DEBUG
printk("d_alloc: %d unused, pruning dcache\n", dentry_stat.nr_unused);
#endif
prune_dcache(8);
free_inode_memory(8);
}
dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
if (!dentry)
return NULL;
......
......@@ -354,36 +354,28 @@ static int free_inodes(int goal)
return found;
}
static void shrink_dentry_inodes(int goal)
{
int found;
spin_unlock(&inode_lock);
found = select_dcache(goal, 0);
if (found < goal)
found = goal;
prune_dcache(found);
spin_lock(&inode_lock);
}
/*
* Searches the inodes list for freeable inodes,
* possibly shrinking the dcache before or after.
* shrinking the dcache before (and possible after,
* if we're low)
*/
static void try_to_free_inodes(int goal)
{
int retry = 1, found;
/*
* Check whether to preshrink the dcache ...
*/
if (inodes_stat.preshrink)
goto preshrink;
retry = 0;
do {
if (free_inodes(goal))
break;
/*
* If we didn't free any inodes, do a limited
* pruning of the dcache to help the next time.
*/
preshrink:
spin_unlock(&inode_lock);
found = select_dcache(goal, 0);
if (found < goal)
found = goal;
prune_dcache(found);
spin_lock(&inode_lock);
} while (retry--);
shrink_dentry_inodes(goal);
if (!free_inodes(goal))
shrink_dentry_inodes(goal);
}
/*
......@@ -408,6 +400,21 @@ static struct inode * grow_inodes(void)
{
struct inode * inode;
/*
* Check whether to restock the unused list.
*/
if (inodes_stat.preshrink) {
struct list_head *tmp;
try_to_free_inodes(8);
tmp = inode_unused.next;
if (tmp != &inode_unused) {
inodes_stat.nr_free_inodes--;
list_del(tmp);
inode = list_entry(tmp, struct inode, i_list);
return inode;
}
}
spin_unlock(&inode_lock);
inode = (struct inode *)__get_free_page(GFP_KERNEL);
if (inode) {
......@@ -512,6 +519,12 @@ static inline void read_inode(struct inode *inode, struct super_block *sb)
sb->s_op->read_inode(inode);
}
/*
* This is called by things like the networking layer
* etc that want to get an inode without any inode
* number, or filesystems that allocate new inodes with
* no pre-existing information.
*/
struct inode * get_empty_inode(void)
{
static unsigned long last_ino = 0;
......@@ -519,11 +532,6 @@ struct inode * get_empty_inode(void)
struct list_head * tmp;
spin_lock(&inode_lock);
/*
* Check whether to restock the unused list.
*/
if (inodes_stat.nr_free_inodes < 16)
try_to_free_inodes(8);
tmp = inode_unused.next;
if (tmp != &inode_unused) {
list_del(tmp);
......@@ -629,25 +637,18 @@ struct inode *iget(struct super_block *sb, unsigned long ino)
struct inode * inode;
spin_lock(&inode_lock);
if (!inodes_stat.nr_free_inodes)
goto restock;
search:
inode = find_inode(sb, ino, head);
if (!inode) {
return get_new_inode(sb, ino, head);
if (inode) {
spin_unlock(&inode_lock);
wait_on_inode(inode);
return inode;
}
spin_unlock(&inode_lock);
wait_on_inode(inode);
return inode;
/*
* We restock the freelist before calling find,
* in order to avoid repeating the search.
* (The unused list usually won't be empty.)
* get_new_inode() will do the right thing, releasing
* the inode lock and re-trying the search in case it
* had to block at any point.
*/
restock:
try_to_free_inodes(8);
goto search;
return get_new_inode(sb, ino, head);
}
void insert_inode_hash(struct inode *inode)
......
......@@ -678,9 +678,12 @@ struct dentry * open_namei(const char * pathname, int flag, int mode)
if (flag & O_CREAT) {
struct dentry *dir;
error = -EEXIST;
if (dentry->d_inode && (flag & O_EXCL))
if (dentry->d_inode) {
if (!(flag & O_EXCL))
goto nocreate;
error = -EEXIST;
goto exit;
}
dir = lock_parent(dentry);
if (!check_parent(dir, dentry)) {
......@@ -723,6 +726,7 @@ struct dentry * open_namei(const char * pathname, int flag, int mode)
goto exit;
}
nocreate:
error = -ENOENT;
inode = dentry->d_inode;
if (!inode)
......
......@@ -268,8 +268,10 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, u32 *statp)
if (!(rp = rqstp->rq_cacherep) || cache_disabled)
return;
len = resp->len - (statp - resp->base);
/* Don't cache excessive amounts of data and XDR failures */
if (!statp || (len = resp->buf - statp) > (256 >> 2)) {
if (!statp || len > (256 >> 2)) {
rp->c_state = RC_UNUSED;
return;
}
......
......@@ -14,7 +14,7 @@
* EVERY character on the current page.
* <middelin@polyware.iaf.nl>
*
* Danny ter Haar : added cpuinfo
* Danny ter Haar : added cpuinfo
* <dth@cistron.nl>
*
* Alessandro Rubini : profile extension.
......@@ -33,13 +33,13 @@
* and /proc/<pid>/cpu extension
* <forissier@isia.cma.fr>
* - Incorporation and non-SMP safe operation
* of forissier patch in 2.1.78 by
* of forissier patch in 2.1.78 by
* Hans Marcus <crowbar@concepts.nl>
*
* aeb@cwi.nl : /proc/partitions
*
*
* Alan Cox : security fixes.
* Alan Cox : security fixes.
* <Alan.Cox@linux.org>
*
* Andi Kleen : Race Fixes.
......@@ -142,7 +142,7 @@ static struct file_operations proc_kcore_operations = {
};
struct inode_operations proc_kcore_inode_operations = {
&proc_kcore_operations,
&proc_kcore_operations,
};
/*
......@@ -198,7 +198,7 @@ static ssize_t write_profile(struct file * file, const char * buf,
return -EINVAL;
}
#endif
memset(prof_buffer, 0, prof_len * sizeof(*prof_buffer));
return count;
}
......@@ -210,7 +210,7 @@ static struct file_operations proc_profile_operations = {
};
struct inode_operations proc_profile_inode_operations = {
&proc_profile_operations,
&proc_profile_operations,
};
......@@ -388,29 +388,29 @@ static int get_cmdline(char * buffer)
return sprintf(buffer, "%s\n", saved_command_line);
}
/*
/*
* Caller must release_mm the mm_struct later.
* You don't get any access to init_mm.
*/
static struct mm_struct *get_mm_and_lock(int pid)
{
struct mm_struct *mm = NULL;
struct task_struct *tsk;
read_lock(&tasklist_lock);
tsk = find_task_by_pid(pid);
* You don't get any access to init_mm.
*/
static struct mm_struct *get_mm_and_lock(int pid)
{
struct mm_struct *mm = NULL;
struct task_struct *tsk;
read_lock(&tasklist_lock);
tsk = find_task_by_pid(pid);
if (tsk && tsk->mm && tsk->mm != &init_mm)
mmget(mm = tsk->mm);
mmget(mm = tsk->mm);
read_unlock(&tasklist_lock);
if (mm != NULL)
down(&mm->mmap_sem);
return mm;
if (mm != NULL)
down(&mm->mmap_sem);
return mm;
}
static void release_mm(struct mm_struct *mm)
{
up(&mm->mmap_sem);
mmput(mm);
up(&mm->mmap_sem);
mmput(mm);
}
static unsigned long get_phys_addr(struct mm_struct *mm, unsigned long ptr)
......@@ -423,7 +423,7 @@ static unsigned long get_phys_addr(struct mm_struct *mm, unsigned long ptr)
return 0;
/* Check for NULL pgd .. shouldn't happen! */
if (!mm->pgd) {
printk(KERN_DEBUG "missing pgd for mm %p\n", mm);
printk(KERN_DEBUG "missing pgd for mm %p\n", mm);
return 0;
}
......@@ -480,12 +480,12 @@ static int get_array(struct mm_struct *mm, unsigned long start, unsigned long en
static int get_env(int pid, char * buffer)
{
struct mm_struct *mm;
int res = 0;
struct mm_struct *mm;
int res = 0;
mm = get_mm_and_lock(pid);
if (mm) {
res = get_array(mm, mm->env_start, mm->env_end, buffer);
mm = get_mm_and_lock(pid);
if (mm) {
res = get_array(mm, mm->env_start, mm->env_end, buffer);
release_mm(mm);
}
return res;
......@@ -493,14 +493,14 @@ static int get_env(int pid, char * buffer)
static int get_arg(int pid, char * buffer)
{
struct mm_struct *mm;
int res = 0;
struct mm_struct *mm;
int res = 0;
mm = get_mm_and_lock(pid);
mm = get_mm_and_lock(pid);
if (mm) {
res = get_array(mm, mm->arg_start, mm->arg_end, buffer);
release_mm(mm);
}
res = get_array(mm, mm->arg_start, mm->arg_end, buffer);
release_mm(mm);
}
return res;
}
......@@ -754,14 +754,14 @@ static inline char * task_mem(struct task_struct *p, char *buffer)
{
struct mm_struct * mm = p->mm;
if (!mm)
if (!mm)
return buffer;
if (mm != &init_mm) {
struct vm_area_struct * vma;
unsigned long data = 0, stack = 0;
unsigned long exec = 0, lib = 0;
down(&mm->mmap_sem);
down(&mm->mmap_sem);
for (vma = mm->mmap; vma; vma = vma->vm_next) {
unsigned long len = (vma->vm_end - vma->vm_start) >> 10;
if (!vma->vm_file) {
......@@ -779,7 +779,7 @@ static inline char * task_mem(struct task_struct *p, char *buffer)
lib += len;
}
}
up(&mm->mmap_sem);
up(&mm->mmap_sem);
buffer += sprintf(buffer,
"VmSize:\t%8lu kB\n"
"VmLck:\t%8lu kB\n"
......@@ -849,35 +849,31 @@ extern inline char *task_cap(struct task_struct *p, char *buffer)
cap_t(p->cap_effective));
}
static struct task_struct *grab_task(int pid, struct task_struct *dst)
static struct task_struct *grab_task(int pid)
{
struct task_struct *tsk = current;
if (pid != tsk->pid) {
struct task_struct *tsk = current;
if (pid != tsk->pid) {
read_lock(&tasklist_lock);
tsk = find_task_by_pid(pid);
if (tsk) {
memcpy(dst, tsk, sizeof(struct task_struct));
tsk = dst;
if (tsk->mm && tsk->mm != &init_mm)
mmget(tsk->mm);
}
if (tsk && tsk->mm && tsk->mm != &init_mm)
mmget(tsk->mm);
read_unlock(&tasklist_lock);
}
return tsk;
return tsk;
}
static void release_task(struct task_struct *tsk)
{
if (tsk != current && tsk->mm && tsk->mm != &init_mm)
mmput(tsk->mm);
mmput(tsk->mm);
}
static int get_status(int pid, char * buffer)
{
char * orig = buffer;
struct task_struct *tsk, mytask;
struct task_struct *tsk;
tsk = grab_task(pid, &mytask);
tsk = grab_task(pid);
if (!tsk)
return 0;
buffer = task_name(tsk, buffer);
......@@ -885,13 +881,13 @@ static int get_status(int pid, char * buffer)
buffer = task_mem(tsk, buffer);
buffer = task_sig(tsk, buffer);
buffer = task_cap(tsk, buffer);
release_task(tsk);
release_task(tsk);
return buffer - orig;
}
static int get_stat(int pid, char * buffer)
{
struct task_struct *tsk, mytask;
struct task_struct *tsk;
unsigned long vsize, eip, esp, wchan;
long priority, nice;
int tty_pgrp;
......@@ -899,8 +895,8 @@ static int get_stat(int pid, char * buffer)
char state;
int res;
tsk = grab_task(pid, &mytask);
if (!tsk)
tsk = grab_task(pid);
if (!tsk)
return 0;
state = *get_task_state(tsk);
vsize = eip = esp = 0;
......@@ -908,10 +904,10 @@ static int get_stat(int pid, char * buffer)
struct vm_area_struct *vma;
down(&tsk->mm->mmap_sem);
for (vma = tsk->mm->mmap; vma; vma = vma->vm_next) {
for (vma = tsk->mm->mmap; vma; vma = vma->vm_next) {
vsize += vma->vm_end - vma->vm_start;
}
up(&tsk->mm->mmap_sem);
up(&tsk->mm->mmap_sem);
eip = KSTK_EIP(tsk);
esp = KSTK_ESP(tsk);
......@@ -1061,8 +1057,8 @@ static int get_statm(int pid, char * buffer)
int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0;
struct mm_struct *mm;
mm = get_mm_and_lock(pid);
if (mm) {
mm = get_mm_and_lock(pid);
if (mm) {
struct vm_area_struct * vma = mm->mmap;
while (vma) {
......@@ -1084,7 +1080,7 @@ static int get_statm(int pid, char * buffer)
drs += pages;
vma = vma->vm_next;
}
release_mm(mm);
release_mm(mm);
}
return sprintf(buffer,"%d %d %d %d %d %d %d\n",
size, resident, share, trs, lrs, drs, dt);
......@@ -1122,7 +1118,7 @@ static int get_statm(int pid, char * buffer)
#define MAPS_LINE_MAX MAPS_LINE_MAX8
/* FIXME: this does not do proper mm locking */
/* FIXME: this does not do proper mm locking */
static ssize_t read_maps (int pid, struct file * file, char * buf,
size_t count, loff_t *ppos)
{
......@@ -1170,7 +1166,7 @@ static ssize_t read_maps (int pid, struct file * file, char * buf,
int flags;
kdev_t dev;
unsigned long ino;
int maxlen = (sizeof(void*) == 4) ?
int maxlen = (sizeof(void*) == 4) ?
MAPS_LINE_MAX4 : MAPS_LINE_MAX8;
int len;
......@@ -1254,10 +1250,10 @@ static ssize_t read_maps (int pid, struct file * file, char * buf,
#ifdef __SMP__
static int get_pidcpu(int pid, char * buffer)
{
struct task_struct * tsk, mytask;
struct task_struct * tsk;
int i, len;
tsk = grab_task(pid, &mytask);
tsk = grab_task(pid);
if (!tsk)
return 0;
......@@ -1272,7 +1268,7 @@ static int get_pidcpu(int pid, char * buffer)
tsk->per_cpu_utime[cpu_logical_map(i)],
tsk->per_cpu_stime[cpu_logical_map(i)]);
release_task(tsk);
release_task(tsk);
return len;
}
#endif
......@@ -1399,10 +1395,9 @@ static int process_unauthorized(int type, int pid)
read_lock(&tasklist_lock);
/*
* Grab the lock, find the task, save the uid and
* Grab the lock, find the task, save the uid and
* check it has an mm still (ie its not dead)
*/
p = find_task_by_pid(pid);
if(p)
{
......
......@@ -1657,9 +1657,9 @@ int vfat_rename(struct inode *old_dir,struct dentry *old_dentry,
drop_aliases(new_dentry);
}
res = vfat_remove_entry(new_dir,&sinfo,new_inode);
if (res)
goto rename_done;
}
if (res)
goto rename_done;
/* Serious lossage here. FAT uses braindead inode numbers scheme,
* so we can't simply cannibalize the entry. It means that we have
......
......@@ -27,6 +27,8 @@
#define POLARIS_DENSE_IO_BASE (IDENT_ADDR + 0xf9fc000000)
#define POLARIS_DENSE_CONFIG_BASE (IDENT_ADDR + 0xf9fe000000)
#define POLARIS_IACK_SC POLARIS_IACK_BASE
/* The Polaris command/status registers live in PCI Config space for
* bus 0/device 0. As such, they may be bytes, words, or doublewords.
*/
......
......@@ -7,6 +7,9 @@
* Defines for the AlphaPC EISA IO and memory address space.
*/
/* The Jensen is strange */
#define AUX_IRQ (9)
/*
* NOTE! The memory operations do not set any memory barriers, as it's
* not needed for cases like a frame buffer that is essentially memory-like.
......
......@@ -307,6 +307,7 @@
#define __NR_getcwd 367
#define __NR_capget 368
#define __NR_capset 369
#define __NR_sendfile 370
#if defined(__LIBRARY__) && defined(__GNUC__)
......
#include <linux/config.h>
#ifndef __I386_COBALT_H
#define __I386_COBALT_H
......
......@@ -14,12 +14,15 @@
#define APIC_TASKPRI 0x80
#define APIC_TPRI_MASK 0xFF
#define APIC_ARBPRI 0x90
#define APIC_ARBPRI_MASK 0xFF
#define APIC_PROCPRI 0xA0
#define APIC_EOI 0xB0
#define APIC_EIO_ACK 0x0 /* Write this to the EOI register */
#define APIC_RRR 0xC0
#define APIC_LDR 0xD0
#define APIC_LDR_MASK (0xFF<<24)
#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF)
#define SET_APIC_LOGICAL_ID(x) (((x)<<24))
#define APIC_DFR 0xE0
#define GET_APIC_DFR(x) (((x)>>28)&0x0F)
#define SET_APIC_DFR(x) ((x)<<28)
......@@ -36,7 +39,6 @@
#define APIC_ESR_RECVILL 0x00040
#define APIC_ESR_ILLREGA 0x00080
#define APIC_ICR 0x300
#define APIC_DEST_FIELD 0x00000
#define APIC_DEST_SELF 0x40000
#define APIC_DEST_ALLINC 0x80000
#define APIC_DEST_ALLBUT 0xC0000
......
#ifndef __I386_LITHIUM_H
#define __I386_LITHIUM_H
#include <linux/config.h>
/*
* Lithium is the I/O ASIC on the SGI 320 and 540 Visual Workstations
*/
......@@ -16,6 +18,7 @@
#define LI_PCI_BUSNUM 0x44 /* lo8: primary, hi8: sub */
#define LI_PCI_INTEN 0x46
#ifdef CONFIG_X86_VISWS_APIC
/* More special purpose macros... */
extern __inline void li_pcia_write16(unsigned long reg, unsigned short v)
{
......@@ -36,5 +39,7 @@ extern __inline unsigned short li_pcib_read16(unsigned long reg)
{
return *((volatile unsigned short *)(LI_PCIB_VADDR+reg));
}
#endif
#endif
......@@ -163,7 +163,7 @@ struct mpc_config_intlocal
*/
extern int smp_found_config;
extern int smp_scan_config(unsigned long, unsigned long);
extern void init_smp_config(void);
extern unsigned long smp_alloc_memory(unsigned long mem_base);
extern unsigned char boot_cpu_id;
extern unsigned long cpu_present_map;
......
/*
You may distribute this file under either of the two licenses that
follow at your discretion.
*/
/* BLURB lgpl
Coda File System
Release 5
Copyright (c) 1987-1999 Carnegie Mellon University
Additional copyrights listed below
This code is distributed "AS IS" without warranty of any kind under
the terms of the GNU Library General Public Licence Version 2, as
shown in the file LICENSE, or under the license shown below. The
technical and financial contributors to Coda are listed in the file
CREDITS.
Additional copyrights
*/
/*
Coda: an Experimental Distributed File System
Release 4.0
Copyright (c) 1987-1999 Carnegie Mellon University
All Rights Reserved
Permission to use, copy, modify and distribute this software and its
documentation is hereby granted, provided that both the copyright
notice and this permission notice appear in all copies of the
software, derivative works or modified versions, and any portions
thereof, and that both notices appear in supporting documentation, and
that credit is given to Carnegie Mellon University in all documents
and publicity pertaining to direct or indirect use of this code or its
derivatives.
CODA IS AN EXPERIMENTAL SOFTWARE SYSTEM AND IS KNOWN TO HAVE BUGS,
SOME OF WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON ALLOWS
FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON
DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE OR OF
ANY DERIVATIVE WORK.
Carnegie Mellon encourages users of this software to return any
improvements or extensions that they make, and to grant Carnegie
Mellon the rights to redistribute these changes without encumbrance.
*/
/*
*
* Based on cfs.h from Mach, but revamped for increased simplicity.
* Linux modifications by Peter Braam, Aug 1996
* Linux modifications by
* Peter Braam, Aug 1996
*/
#ifndef _CODA_HEADER_
......@@ -178,8 +229,12 @@ typedef u_int32_t vgid_t;
#ifndef _CODACRED_T_
#define _CODACRED_T_
struct coda_cred {
vuid_t cr_uid, cr_euid, cr_suid, cr_fsuid; /* Real, efftve, set, fs uid*/
vgid_t cr_groupid, cr_egid, cr_sgid, cr_fsgid; /* same for groups */
vuid_t cr_uid, cr_euid, cr_suid, cr_fsuid;
vgid_t cr_groupid, cr_egid, cr_sgid, cr_fsgid;
#if defined(CODA_SUPPORTS_SUPPLEMENTARY_GROUPS)
int cr_nsupgps;
vgid_t cr_supgps[NGROUPS];
#endif /* defined(CODA_SUPPORTS_SUPPLEMENTARY_GROUPS) */
};
#endif
......
......@@ -46,6 +46,7 @@ extern int coda_access_cache;
/* this file: heloers */
static __inline__ struct ViceFid *coda_i2f(struct inode *);
char *coda_f2s(ViceFid *f);
char *coda_f2s2(ViceFid *f);
int coda_isroot(struct inode *i);
int coda_fid_is_volroot(struct ViceFid *);
int coda_fid_is_weird(struct ViceFid *fid);
......
......@@ -2,6 +2,7 @@
#define __LINUX_VIDEODEV_H
#include <linux/types.h>
#include <linux/version.h>
#ifdef __KERNEL__
......
......@@ -25,6 +25,7 @@
#ifndef IRDA_H
#define IRDA_H
#include <linux/config.h>
#include <linux/skbuff.h>
#ifndef TRUE
......
......@@ -125,7 +125,7 @@ int shrink_mmap(int priority, int gfp_mask)
struct page * page;
int count;
count = (limit << 1) >> priority;
count = limit >> priority;
page = mem_map + clock;
do {
......@@ -147,7 +147,6 @@ int shrink_mmap(int priority, int gfp_mask)
clock = page - mem_map;
}
count--;
referenced = test_and_clear_bit(PG_referenced, &page->flags);
if (PageLocked(page))
......@@ -160,6 +159,8 @@ int shrink_mmap(int priority, int gfp_mask)
if (atomic_read(&page->count) != 1)
continue;
count--;
/*
* Is it a page swap page? If so, we want to
* drop it if it is no longer used, even if it
......
......@@ -155,12 +155,12 @@ void free_pages(unsigned long addr, unsigned long order)
change_bit((index) >> (1+(order)), (area)->map)
#define CAN_DMA(x) (PageDMA(x))
#define ADDRESS(x) (PAGE_OFFSET + ((x) << PAGE_SHIFT))
#define RMQUEUE(order, dma) \
#define RMQUEUE(order, gfp_mask) \
do { struct free_area_struct * area = free_area+order; \
unsigned long new_order = order; \
do { struct page *prev = memory_head(area), *ret = prev->next; \
while (memory_head(area) != ret) { \
if (!dma || CAN_DMA(ret)) { \
if (!(gfp_mask & __GFP_DMA) || CAN_DMA(ret)) { \
unsigned long map_nr; \
(prev->next = ret->next)->prev = prev; \
map_nr = ret - mem_map; \
......@@ -198,45 +198,45 @@ unsigned long __get_free_pages(int gfp_mask, unsigned long order)
if (order >= NR_MEM_LISTS)
goto nopage;
if (gfp_mask & __GFP_WAIT) {
if (in_interrupt()) {
static int count = 0;
if (++count < 5) {
printk("gfp called nonatomically from interrupt %p\n",
__builtin_return_address(0));
}
goto nopage;
#ifdef ATOMIC_MEMORY_DEBUGGING
if ((gfp_mask & __GFP_WAIT) && in_interrupt()) {
static int count = 0;
if (++count < 5) {
printk("gfp called nonatomically from interrupt %p\n",
__builtin_return_address(0));
}
goto nopage;
}
#endif
/*
* If this is a recursive call, we'd better
* do our best to just allocate things without
* further thought.
*/
if (!(current->flags & PF_MEMALLOC)) {
int freed;
if (nr_free_pages > freepages.min) {
if (!low_on_memory)
goto ok_to_allocate;
if (nr_free_pages >= freepages.high) {
low_on_memory = 0;
goto ok_to_allocate;
}
/*
* If this is a recursive call, we'd better
* do our best to just allocate things without
* further thought.
*/
if (!(current->flags & PF_MEMALLOC)) {
int freed;
if (nr_free_pages > freepages.min) {
if (!low_on_memory)
goto ok_to_allocate;
if (nr_free_pages >= freepages.high) {
low_on_memory = 0;
goto ok_to_allocate;
}
}
low_on_memory = 1;
current->flags |= PF_MEMALLOC;
freed = try_to_free_pages(gfp_mask);
current->flags &= ~PF_MEMALLOC;
low_on_memory = 1;
current->flags |= PF_MEMALLOC;
freed = try_to_free_pages(gfp_mask);
current->flags &= ~PF_MEMALLOC;
if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH)))
goto nopage;
}
if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH)))
goto nopage;
}
ok_to_allocate:
spin_lock_irqsave(&page_alloc_lock, flags);
RMQUEUE(order, (gfp_mask & GFP_DMA));
RMQUEUE(order, gfp_mask);
spin_unlock_irqrestore(&page_alloc_lock, flags);
/*
......
......@@ -367,6 +367,54 @@ static int swap_out(unsigned int priority, int gfp_mask)
return 0;
}
/*
* We need to make the locks finer granularity, but right
* now we need this so that we can do page allocations
* without holding the kernel lock etc.
*
* We want to try to free "count" pages, and we need to
* cluster them so that we get good swap-out behaviour. See
* the "free_memory()" macro for details.
*/
static int do_try_to_free_pages(unsigned int gfp_mask)
{
int priority;
int count = SWAP_CLUSTER_MAX;
lock_kernel();
/* Always trim SLAB caches when memory gets low. */
kmem_cache_reap(gfp_mask);
priority = 6;
do {
while (shrink_mmap(priority, gfp_mask)) {
if (!--count)
goto done;
}
/* Try to get rid of some shared memory pages.. */
if (gfp_mask & __GFP_IO) {
while (shm_swap(priority, gfp_mask)) {
if (!--count)
goto done;
}
}
/* Then, try to page stuff out.. */
while (swap_out(priority, gfp_mask)) {
if (!--count)
goto done;
}
shrink_dcache_memory(priority, gfp_mask);
} while (--priority >= 0);
done:
unlock_kernel();
return priority >= 0;
}
/*
* Before we start the kernel thread, print out the
* kswapd initialization message (otherwise the init message
......@@ -388,6 +436,8 @@ void __init kswapd_setup(void)
printk ("Starting kswapd v%.*s\n", i, s);
}
static struct task_struct *kswapd_process;
/*
* The background pageout daemon, started as a kernel thread
* from the init process.
......@@ -404,10 +454,13 @@ void __init kswapd_setup(void)
*/
int kswapd(void *unused)
{
current->session = 1;
current->pgrp = 1;
strcpy(current->comm, "kswapd");
sigfillset(&current->blocked);
struct task_struct *tsk = current;
kswapd_process = tsk;
tsk->session = 1;
tsk->pgrp = 1;
strcpy(tsk->comm, "kswapd");
sigfillset(&tsk->blocked);
/*
* Tell the memory management that we're a "memory allocator",
......@@ -421,78 +474,52 @@ int kswapd(void *unused)
* us from recursively trying to free more memory as we're
* trying to free the first piece of memory in the first place).
*/
current->flags |= PF_MEMALLOC;
tsk->flags |= PF_MEMALLOC;
while (1) {
int tmo;
/*
* Wake up once a second to see if we need to make
* more memory available. When we get into a low
* memory situation, we start waking up more often.
* more memory available.
*
* We consider "freepages.low" to be low on memory,
* but we also try to be aggressive if other processes
* are low on memory and would otherwise block when
* calling __get_free_page().
* If we actually get into a low-memory situation,
* the processes needing more memory will wake us
* up on a more timely basis.
*/
tmo = HZ;
if (nr_free_pages < freepages.high) {
if (nr_free_pages < freepages.low || low_on_memory) {
if (try_to_free_pages(GFP_KSWAPD))
tmo = (HZ+9)/10;
}
}
do {
if (nr_free_pages >= freepages.high)
break;
if (!do_try_to_free_pages(GFP_KSWAPD))
break;
} while (!tsk->need_resched);
run_task_queue(&tq_disk);
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(tmo);
tsk->state = TASK_INTERRUPTIBLE;
schedule_timeout(HZ);
}
}
/*
* We need to make the locks finer granularity, but right
* now we need this so that we can do page allocations
* without holding the kernel lock etc.
* Called by non-kswapd processes when they want more
* memory.
*
* We want to try to free "count" pages, and we need to
* cluster them so that we get good swap-out behaviour. See
* the "free_memory()" macro for details.
* In a perfect world, this should just wake up kswapd
* and return. We don't actually want to swap stuff out
* from user processes, because the locking issues are
* nasty to the extreme (file write locks, and MM locking)
*
* One option might be to let kswapd do all the page-out
* and VM page table scanning that needs locking, and this
* process thread could do just the mmap shrink stage that
* can be done by just dropping cached pages without having
* any deadlock issues.
*/
int try_to_free_pages(unsigned int gfp_mask)
{
int priority;
int count = SWAP_CLUSTER_MAX;
lock_kernel();
/* Always trim SLAB caches when memory gets low. */
kmem_cache_reap(gfp_mask);
priority = 6;
do {
while (shrink_mmap(priority, gfp_mask)) {
if (!--count)
goto done;
}
/* Try to get rid of some shared memory pages.. */
if (gfp_mask & __GFP_IO) {
while (shm_swap(priority, gfp_mask)) {
if (!--count)
goto done;
}
}
/* Then, try to page stuff out.. */
while (swap_out(priority, gfp_mask)) {
if (!--count)
goto done;
}
shrink_dcache_memory(priority, gfp_mask);
} while (--priority >= 0);
done:
unlock_kernel();
int retval = 1;
return priority >= 0;
wake_up_process(kswapd_process);
if (gfp_mask & __GFP_WAIT)
retval = do_try_to_free_pages(gfp_mask);
return retval;
}
......@@ -4,9 +4,12 @@
For information on the Linux DECnet Project and the latest progress,
look at the project home page:
http://www-sigproc.eng.cam.ac.uk/~sjw44/
http://www.sucs.swan.ac.uk/~rohan/DECnet/
To contribute either mail <SteveW@ACM.org> or post on one of the Linux
mailing lists (either linux-net or netdev).
mailing lists (either linux-net or netdev). DECnet for Linux will not
be distributed as part of the 2.2.xx kernel series. It is available as a
patch from the above site. Expect DECnet to arrive as part of the standard
kernel distribution early in the 2.3.xx series.
Steve Whitehouse <SteveW@ACM.org>
......@@ -984,7 +984,7 @@ void fib_node_get_info(int type, int dead, struct fib_info *fi, u32 prefix, u32
flags, 0, 0, 0,
mask, 0, 0, 0);
}
memset(buffer+len, 0, 127-len);
memset(buffer+len, ' ', 127-len);
buffer[127] = '\n';
}
......
......@@ -79,7 +79,7 @@ struct ip_masq_mfw {
};
static struct semaphore mfw_sema;
static struct semaphore mfw_sema = MUTEX;
#ifdef __SMP__
static rwlock_t mfw_lock = RW_LOCK_UNLOCKED;
#endif
......@@ -748,7 +748,6 @@ static struct ip_masq_mod mfw_mod = {
__initfunc(int ip_mfw_init(void))
{
sema_init(&mfw_sema, 1);
return register_ip_masq_mod ((mmod_self=&mfw_mod));
}
......
......@@ -1691,7 +1691,7 @@ static int prune_queue(struct sock *sk)
do { net_statistics.OfoPruned += skb->len;
kfree_skb(skb);
skb = __skb_dequeue_tail(&tp->out_of_order_queue);
} while((skb = __skb_dequeue_tail(&tp->out_of_order_queue)) != NULL);
} while(skb != NULL);
/* Reset SACK state. A conforming SACK implementation will
* do the same at a timeout based retransmit. When a connection
......
......@@ -24,7 +24,6 @@
*
********************************************************************/
#include <linux/config.h>
#include <linux/module.h>
#include <asm/segment.h>
......
......@@ -17,8 +17,6 @@
*
********************************************************************/
#include <linux/config.h>
#include <net/irda/iriap.h>
#include <net/irda/irlmp.h>
#include <net/irda/irttp.h>
......
......@@ -22,6 +22,7 @@
*
********************************************************************/
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/ctype.h>
#include <linux/sysctl.h>
......
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