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/)
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
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
#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>.
.quad sys_getcwd
.quad sys_capget
.quad sys_capset
- .quad sys_ni_syscall /* 370 */
+ .quad sys_sendfile /* 370 */
* 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,
* 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);
}
.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)
*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;
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
#include <linux/init.h>
-#include <asm/pgtable.h>
-#include <asm/bitops.h>
-#include <asm/pgtable.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_MTRR
-# include <asm/mtrr.h>
-#endif
-
-#define __KERNEL_SYSCALLS__
-#include <linux/unistd.h>
+#include <asm/mtrr.h>
#include "irq.h"
/* Kernel spinlock */
spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
-/*
- * Why isn't this somewhere standard ??
- *
- * Maybe because this procedure is horribly buggy, and does
- * not deserve to live. Think about signedness issues for five
- * seconds to see why. - Linus
- */
-
-extern __inline int max(int a,int b)
-{
- if (a>b)
- return a;
- return b;
-}
-
/*
* function prototypes:
*/
#define SMP_PRINTK(x)
#endif
+/*
+ * IA s/w dev Vol 3, Section 7.4
+ */
+#define APIC_DEFAULT_PHYS_BASE 0xfee00000
+
/*
* Setup routine for controlling SMP activation
*
apic_write(APIC_EOI, 0);
}
-#ifdef CONFIG_X86_VISWS_APIC
/*
- * hacky!
+ * Intel MP BIOS table parsing routines:
*/
-int __init smp_scan_config(unsigned long base, unsigned long length)
-{
- cpu_present_map |= 2; /* or in id 1 */
- apic_version[1] |= 0x10; /* integrated APIC */
- num_processors = 2;
- return 1;
-}
-#else
+#ifndef CONFIG_X86_VISWS_APIC
/*
* Checksum an MP configuration block.
*/
* Scan the memory blocks for an SMP configuration block.
*/
-int __init smp_scan_config(unsigned long base, unsigned long length)
+static int __init smp_scan_config(unsigned long base, unsigned long length)
{
unsigned long *bp=phys_to_virt(base);
struct intel_mp_floating *mpf;
unsigned long cfg;
/* local APIC has default address */
- mp_lapic_addr = 0xFEE00000;
+ mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
/*
* We need to know what the local
* APIC id of the boot CPU is!
return 0;
}
+
+void __init init_intel_smp (void)
+{
+ /*
+ * 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.
+ */
+ unsigned int address;
+
+ 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");
+ }
+}
+
+#else
+
+/*
+ * The Visual Workstation is Intel MP compliant in the hardware
+ * sense, but it doesnt have a BIOS(-configuration table).
+ * No problem for Linux.
+ */
+void __init init_visws_smp(void)
+{
+ smp_found_config = 1;
+
+ cpu_present_map |= 2; /* or in id 1 */
+ apic_version[1] |= 0x10; /* integrated APIC */
+ apic_version[0] |= 0x10;
+
+ mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
+}
+
+#endif
+
+/*
+ * - Intel MP Configuration Table
+ * - or SGI Visual Workstation configuration
+ */
+void __init init_smp_config (void)
+{
+#ifndef CONFIG_VISWS
+ init_intel_smp();
+#else
+ init_visws_smp();
#endif
+}
/*
* Trampoline 80x86 program as an array.
value &= ~APIC_TPRI_MASK; /* Set Task Priority to 'accept all' */
apic_write(APIC_TASKPRI,value);
+ /*
+ * Set arbitrarion priority to 0
+ */
+ value = apic_read(APIC_ARBPRI);
+ value &= ~APIC_ARBPRI_MASK;
+ apic_write(APIC_ARBPRI, value);
+
+ /*
+ * Set the logical destination ID to 'all', just to be safe.
+ * also, put the APIC into flat delivery mode.
+ */
+ value = apic_read(APIC_LDR);
+ value &= ~APIC_LDR_MASK;
+ value |= SET_APIC_LOGICAL_ID(0xff);
+ apic_write(APIC_LDR,value);
+
+ value = apic_read(APIC_DFR);
+ value |= SET_APIC_DFR(0xf);
+ apic_write(APIC_DFR, value);
+
udelay(100); /* B safe */
ack_APIC_irq();
udelay(100);
unsigned long __init init_smp_mappings(unsigned long memory_start)
{
- unsigned long apic_phys, ioapic_phys;
+ unsigned long apic_phys;
memory_start = PAGE_ALIGN(memory_start);
if (smp_found_config) {
apic_phys = mp_lapic_addr;
-#ifdef CONFIG_X86_IO_APIC
- ioapic_phys = mp_ioapic_addr;
-#endif
} else {
/*
* set up a fake all zeroes page to simulate the
* this way if some buggy code writes to this page ...
*/
apic_phys = __pa(memory_start);
- ioapic_phys = __pa(memory_start+PAGE_SIZE);
- memset((void *)memory_start, 0, 2*PAGE_SIZE);
- memory_start += 2*PAGE_SIZE;
+ memset((void *)memory_start, 0, PAGE_SIZE);
+ memory_start += PAGE_SIZE;
}
-
-#ifdef CONFIG_X86_IO_APIC
set_fixmap(FIX_APIC_BASE,apic_phys);
- set_fixmap(FIX_IO_APIC_BASE,ioapic_phys);
-
printk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys);
- printk("mapped IOAPIC to %08lx (%08lx)\n", fix_to_virt(FIX_IO_APIC_BASE), ioapic_phys);
+
+#ifdef CONFIG_X86_IO_APIC
+ {
+ unsigned long ioapic_phys;
+
+ if (smp_found_config) {
+ ioapic_phys = mp_ioapic_addr;
+ } else {
+ ioapic_phys = __pa(memory_start);
+ memset((void *)memory_start, 0, PAGE_SIZE);
+ memory_start += PAGE_SIZE;
+ }
+ set_fixmap(FIX_IO_APIC_BASE,ioapic_phys);
+ printk("mapped IOAPIC to %08lx (%08lx)\n",
+ fix_to_virt(FIX_IO_APIC_BASE), ioapic_phys);
+ }
#endif
return memory_start;
apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */
cfg=apic_read(APIC_ICR);
cfg&=~0xCDFFF; /* Clear bits */
- cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG
- | APIC_DEST_ASSERT | APIC_DEST_DM_INIT);
+ cfg |= (APIC_DEST_LEVELTRIG | APIC_DEST_ASSERT | APIC_DEST_DM_INIT);
apic_write(APIC_ICR, cfg); /* Send IPI */
udelay(200);
apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */
cfg=apic_read(APIC_ICR);
cfg&=~0xCDFFF; /* Clear bits */
- cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG
- | APIC_DEST_DM_INIT);
+ cfg |= (APIC_DEST_LEVELTRIG | APIC_DEST_DM_INIT);
apic_write(APIC_ICR, cfg); /* Send IPI */
/*
apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */
cfg=apic_read(APIC_ICR);
cfg&=~0xCDFFF; /* Clear bits */
- cfg |= (APIC_DEST_FIELD
- | APIC_DEST_DM_STARTUP
- | (start_eip >> 12)); /* Boot on the stack */
+ cfg |= (APIC_DEST_DM_STARTUP | (start_eip >> 12)); /* Boot on the stack */
SMP_PRINTK(("Before start apic_write.\n"));
apic_write(APIC_ICR, cfg); /* Kick the second */
void __init smp_boot_cpus(void)
{
int i;
- unsigned long cfg;
#ifdef CONFIG_MTRR
/* Must be done before other processors booted */
cpu_number_map[boot_cpu_id] = 0;
-#ifdef CONFIG_X86_IO_APIC
/*
- * If we don't conform to the Intel MPS standard, get out
- * of here now!
+ * If we couldnt find an SMP configuration at boot time,
+ * get out of here now!
*/
if (!smp_found_config)
{
printk(KERN_NOTICE "SMP motherboard not detected. Using dummy APIC emulation.\n");
+#ifndef CONFIG_VISWS
io_apic_irqs = 0;
+#endif
cpu_online_map = cpu_present_map;
goto smp_done;
}
-#endif
/*
* If SMP should be disabled, then really disable it!
* Cleanup possible dangling ends...
*/
- /*
- * Install writable page 0 entry.
- */
-
- cfg = pg0[0];
- pg0[0] = 3; /* writeable, present, addr 0 */
- local_flush_tlb();
+#ifndef CONFIG_VISWS
+ {
+ unsigned long cfg;
- /*
- * Paranoid: Set warm reset code and vector here back
- * to default values.
- */
+ /*
+ * Install writable page 0 entry.
+ */
+ cfg = pg0[0];
+ pg0[0] = 3; /* writeable, present, addr 0 */
+ local_flush_tlb();
+
+ /*
+ * Paranoid: Set warm reset code and vector here back
+ * to default values.
+ */
- CMOS_WRITE(0, 0xf);
+ CMOS_WRITE(0, 0xf);
- *((volatile long *) phys_to_virt(0x467)) = 0;
+ *((volatile long *) phys_to_virt(0x467)) = 0;
- /*
- * Restore old page 0 entry.
- */
+ /*
+ * Restore old page 0 entry.
+ */
- pg0[0] = cfg;
- local_flush_tlb();
+ pg0[0] = cfg;
+ local_flush_tlb();
+ }
+#endif
/*
* Allow the user to impress friends.
SMP_PRINTK(("Boot done.\n"));
cache_APIC_registers();
-#ifdef CONFIG_X86_IO_APIC
+#ifndef CONFIG_VISWS
/*
* Here we can be sure that there is an IO-APIC in the system. Let's
* go and set it up:
*/
if (!skip_ioapic_setup)
setup_IO_APIC();
-smp_done:
#endif
+
+smp_done:
}
unsigned int cfg;
cfg = __get_ICR();
- cfg |= APIC_DEST_FIELD|APIC_DEST_DM_FIXED|shortcut|vector;
+ cfg |= APIC_DEST_DM_FIXED|shortcut|vector;
return cfg;
}
((long)(t2-t1)/LOOPS)/(1000000/HZ),
((long)(t2-t1)/LOOPS)%(1000000/HZ) );
- printk("..... APIC bus clock speed is %ld.%04ld MHz.\n",
+ printk("..... system bus clock speed is %ld.%04ld MHz.\n",
calibration_result/(1000000/HZ),
calibration_result%(1000000/HZ) );
#undef LOOPS
* 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;
*/
__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;
{ 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))
/* 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),
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++)
{
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);
} 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;
case TDA9850:
init_tda9850(&(btv->i2c));
break;
+ case TDA9840:
+ init_tda9840(&(btv->i2c));
+ break;
case TDA8425:
init_tda8425(&(btv->i2c));
break;
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);
#ifndef _BTTV_H_
#define _BTTV_H_
-#define BTTV_VERSION_CODE 0x000520
+#define BTTV_VERSION_CODE 0x000523
#include <linux/types.h>
#include <linux/wait.h>
#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
#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
#define I2C_TDA8425 0x82
#define I2C_HAUPEE 0xa0
#define I2C_STBEE 0xae
+#define I2C_VHX 0xc0
#define TDA9840_SW 0x00
#define TDA9840_LVADJ 0x02
* Copyright (C) 1991, 1992 Linus Torvalds
*/
+#include <linux/config.h>
#include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/tpqic02.h>
/* thread */
struct task_struct *thread;
- struct semaphore *wait;
+ struct wait_queue *wq;
struct semaphore *notify;
int active,restart,rmmod;
{
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;
current->fs->umask = 0;
strcpy(current->comm,"msp3400");
- msp->wait = &sem;
+ msp->wq = NULL;
msp->thread = current;
#ifdef __SMP__
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))
done:
dprintk("msp3400: thread: exit\n");
- msp->wait = NULL;
msp->active = 0;
msp->thread = NULL;
goto done;
dprintk("msp3410: thread: sleep\n");
down_interruptible(&sem);
+ sem.owner = 0;
dprintk("msp3410: thread: wakeup\n");
if (msp->rmmod)
goto done;
/* 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)
{
msp->notify = &sem;
msp->rmmod = 1;
- if (!msp->active)
- up(msp->wait);
+ wake_up_interruptible(&msp->wq);
down(&sem);
msp->notify = NULL;
}
/* 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:
#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 */
/*
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;
}
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 */
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;
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 */
#include <asm/bitops.h>
#include <asm/io.h>
#include <linux/errno.h>
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/malloc.h>
#include <linux/delay.h>
#include <linux/init.h>
-#include <linux/config.h>
#include <linux/init.h>
#include <asm/io.h>
{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
-------------------------------------------------------------------------------
-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>
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) {
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);
/* 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);
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 */
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);
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");
MODULE_PARM(trix, "i");
MODULE_PARM(pas2, "i");
MODULE_PARM(sm_games, "i");
+MODULE_PARM(esstype, "i");
void *smw_free = NULL;
}
}
}
-#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
DDB(printk("IRQ test OK (IRQ%d)\n", devc->irq));
}
}
-#endif /* __SMP__ */
} /* IRQ setup */
request_region(hw_config->io_base, 16, "soundblaster");
* 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
* 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
* 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.
* 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.
*/
/*
* 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
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
/*
* 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);
}
}
sb_devc *devc = audio_devs[dev]->devc;
unsigned char bits;
+/* FKS: qqq
sb_dsp_reset(devc);
+*/
/*
* Auto-Initialize:
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;
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.
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;
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";
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)
}
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 ) {
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];
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
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;
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;
}
/*
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;
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);
}
/*
{
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) {
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;
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);
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)
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)) {
goto exit;
}
+nocreate:
error = -ENOENT;
inode = dentry->d_inode;
if (!inode)
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;
}
* 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.
* 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.
};
struct inode_operations proc_kcore_inode_operations = {
- &proc_kcore_operations,
+ &proc_kcore_operations,
};
/*
return -EINVAL;
}
#endif
-
+
memset(prof_buffer, 0, prof_len * sizeof(*prof_buffer));
return count;
}
};
struct inode_operations proc_profile_inode_operations = {
- &proc_profile_operations,
+ &proc_profile_operations,
};
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)
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;
}
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;
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;
}
{
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) {
lib += len;
}
}
- up(&mm->mmap_sem);
+ up(&mm->mmap_sem);
buffer += sprintf(buffer,
"VmSize:\t%8lu kB\n"
"VmLck:\t%8lu kB\n"
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);
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;
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;
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);
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) {
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);
#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)
{
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;
#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;
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
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)
{
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
#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.
*/
* 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.
#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
#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)
#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
*/
#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)
{
{
return *((volatile unsigned short *)(LI_PCIB_VADDR+reg));
}
+#endif
#endif
+
*/
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_
#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
/* 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);
#define __LINUX_VIDEODEV_H
#include <linux/types.h>
+#include <linux/version.h>
#ifdef __KERNEL__
#ifndef IRDA_H
#define IRDA_H
+#include <linux/config.h>
#include <linux/skbuff.h>
#ifndef TRUE
struct page * page;
int count;
- count = (limit << 1) >> priority;
+ count = limit >> priority;
page = mem_map + clock;
do {
clock = page - mem_map;
}
- count--;
referenced = test_and_clear_bit(PG_referenced, &page->flags);
if (PageLocked(page))
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
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; \
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);
/*
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
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.
*/
int kswapd(void *unused)
{
- current->session = 1;
- current->pgrp = 1;
- strcpy(current->comm, "kswapd");
- sigfillset(¤t->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",
* 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;
}
+
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>
flags, 0, 0, 0,
mask, 0, 0, 0);
}
- memset(buffer+len, 0, 127-len);
+ memset(buffer+len, ' ', 127-len);
buffer[127] = '\n';
}
};
-static struct semaphore mfw_sema;
+static struct semaphore mfw_sema = MUTEX;
#ifdef __SMP__
static rwlock_t mfw_lock = RW_LOCK_UNLOCKED;
#endif
__initfunc(int ip_mfw_init(void))
{
- sema_init(&mfw_sema, 1);
return register_ip_masq_mod ((mmod_self=&mfw_mod));
}
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
*
********************************************************************/
-#include <linux/config.h>
#include <linux/module.h>
#include <asm/segment.h>
*
********************************************************************/
-#include <linux/config.h>
-
#include <net/irda/iriap.h>
#include <net/irda/irlmp.h>
#include <net/irda/irttp.h>
*
********************************************************************/
+#include <linux/config.h>
#include <linux/mm.h>
#include <linux/ctype.h>
#include <linux/sysctl.h>