Commit 8cf64f0c authored by Linus Torvalds's avatar Linus Torvalds

Import 2.0.14

parent cde5f10a
......@@ -26,11 +26,14 @@ http://slug.ctv.es/~alfredo/Cambios.html.
valtozasokrol, az alabbi cimen megtalaljak Nyitrai Tamas forditasat:
http://www.datanet.hu/generations/linux/newkernel.html.
Tamas also maintains a version of this file in English at
http://www.datanet.hu/generations/linux/Changes.html.
For people who prefer Japanese (thanks to Mitsuhiro Kojima): Kono
bunshou no nihongo ban wa
http://jf.gee.kyoto-u.ac.jp/JF/v2.0/Changes-2.0.html ni arimasu.
Last updated: August 6, 1996.
Last updated: August 18, 1996.
Current Author: Chris Ricker (gt1355b@prism.gatech.edu).
Current Releases
......@@ -147,6 +150,14 @@ especially when compiling a new kernel:
caused by hardware problems. See http://www.bitwizard.nl/sig11/ for
the sig11 FAQ.
On the other hand, if you're using a gcc patched for Pentium
optimization and are getting these errors, downgrade to a standard GNU
gcc before assuming your hardware (or the kernel) is to blame..
On a related note, if you get random OOPses that don't seem to be
related to anything and you have a motherboard with APM support, try
disabling the APM support and/or compiling the kernel with APM support.
Procps utilities
================
......@@ -528,7 +539,7 @@ solution is to edit the file /usr/lib/man.config and change all
`-Tlatin1' options to `-Tascii'. An alternate solution, for those of
you who can't reformat your man files in .../cat* directories is to
edit /usr/lib/man.config, setting the PAGER to `PAGER
(LESSCHARSET=latin1;export LESSCHARSET;/usr/bin/less -is'.
(LESSCHARSET=latin1;export LESSCHARSET;/usr/bin/less -is)'.
E2fsprogs
=========
......
VERSION = 2
PATCHLEVEL = 0
SUBLEVEL = 13
SUBLEVEL = 14
ARCH = i386
......
......@@ -189,13 +189,48 @@ asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len,
return do_mmap(file, addr, len, prot, flags, off);
}
asmlinkage int osf_statfs(char * path, struct statfs * buffer, unsigned long bufsiz)
/*
* The OSF/1 statfs structure is much larger, but this should
* match the beginning, at least.
*/
struct osf_statfs {
short f_type;
short f_flags;
int f_fsize;
int f_bsize;
int f_blocks;
int f_bfree;
int f_bavail;
int f_files;
int f_ffree;
__kernel_fsid_t f_fsid;
} * osf_stat;
static void linux_to_osf_statfs (struct statfs * linux_stat, struct osf_statfs * osf_stat)
{
osf_stat->f_type = linux_stat->f_type;
osf_stat->f_flags = 0; /* mount flags */
/* Linux doesn't provide a "fundamental filesystem block size": */
osf_stat->f_fsize = linux_stat->f_bsize;
osf_stat->f_bsize = linux_stat->f_bsize;
osf_stat->f_blocks = linux_stat->f_blocks;
osf_stat->f_bfree = linux_stat->f_bfree;
osf_stat->f_bavail = linux_stat->f_bavail;
osf_stat->f_files = linux_stat->f_files;
osf_stat->f_ffree = linux_stat->f_ffree;
osf_stat->f_fsid = linux_stat->f_fsid;
}
asmlinkage int osf_statfs(char * path, struct osf_statfs * buffer, unsigned long bufsiz)
{
struct statfs linux_stat;
struct inode * inode;
int retval;
if (bufsiz > sizeof(struct statfs))
bufsiz = sizeof(struct statfs);
if (bufsiz > sizeof(struct osf_statfs))
bufsiz = sizeof(struct osf_statfs);
retval = verify_area(VERIFY_WRITE, buffer, bufsiz);
if (retval)
return retval;
......@@ -206,13 +241,15 @@ asmlinkage int osf_statfs(char * path, struct statfs * buffer, unsigned long buf
iput(inode);
return -ENOSYS;
}
inode->i_sb->s_op->statfs(inode->i_sb, buffer, bufsiz);
inode->i_sb->s_op->statfs(inode->i_sb, &linux_stat, sizeof(linux_stat));
linux_to_osf_statfs(&linux_stat, buffer);
iput(inode);
return 0;
}
asmlinkage int osf_fstatfs(unsigned long fd, struct statfs * buffer, unsigned long bufsiz)
asmlinkage int osf_fstatfs(unsigned long fd, struct osf_statfs * buffer, unsigned long bufsiz)
{
struct statfs linux_stat;
struct file * file;
struct inode * inode;
int retval;
......@@ -220,15 +257,16 @@ asmlinkage int osf_fstatfs(unsigned long fd, struct statfs * buffer, unsigned lo
retval = verify_area(VERIFY_WRITE, buffer, bufsiz);
if (retval)
return retval;
if (bufsiz > sizeof(struct statfs))
bufsiz = sizeof(struct statfs);
if (bufsiz > sizeof(struct osf_statfs))
bufsiz = sizeof(struct osf_statfs);
if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
return -EBADF;
if (!(inode = file->f_inode))
return -ENOENT;
if (!inode->i_sb->s_op->statfs)
return -ENOSYS;
inode->i_sb->s_op->statfs(inode->i_sb, buffer, bufsiz);
inode->i_sb->s_op->statfs(inode->i_sb, &linux_stat, sizeof(linux_stat));
linux_to_osf_statfs(&linux_stat, buffer);
return 0;
}
......
......@@ -85,7 +85,7 @@ void show_regs(struct pt_regs * regs)
*/
void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
{
current->tss.segment = USER_DS;
set_fs(USER_DS);
regs->pc = pc;
regs->ps = 8;
wrusp(sp);
......@@ -157,7 +157,8 @@ void copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
childstack->r26 = (unsigned long) ret_from_sys_call;
p->tss.usp = usp;
p->tss.ksp = (unsigned long) childstack;
p->tss.flags = 1;
p->tss.pal_flags = 1; /* set FEN, clear everything else */
p->tss.flags = current->tss.flags;
p->mm->context = 0;
}
......
......@@ -135,11 +135,10 @@ void setup_arch(char **cmdline_p,
* installation. Later we'll add other abbreviations
* as well...
*/
if(strcmp(COMMAND_LINE, "INSTALL") == 0) {
if (strcmp(COMMAND_LINE, "INSTALL") == 0) {
strcpy(command_line, "root=/dev/fd0 load_ramdisk=1");
strcpy(saved_command_line, command_line);
}
else {
} else {
strcpy(command_line, COMMAND_LINE);
strcpy(saved_command_line, COMMAND_LINE);
}
......
......@@ -30,24 +30,42 @@ extern int ptrace_cancel_bpt (struct task_struct *child);
/*
* The OSF/1 sigprocmask calling sequence is different from the
* C sigprocmask() sequence..
*
* how:
* 1 - SIG_BLOCK
* 2 - SIG_UNBLOCK
* 3 - SIG_SETMASK
*
* We change the range to -1 .. 1 in order to let gcc easily
* use the conditional move instructions.
*/
asmlinkage unsigned long osf_sigprocmask(int how, unsigned long newmask)
asmlinkage unsigned long osf_sigprocmask(int how, unsigned long newmask,
long a2, long a3, long a4, long a5, struct pt_regs regs)
{
unsigned long oldmask = current->blocked;
unsigned long ok, oldmask;
struct task_struct * tsk;
ok = how-1; /* 0 .. 2 */
tsk = current;
ok = ok <= 2;
oldmask = -EINVAL;
if (ok) {
long sign; /* -1 .. 1 */
unsigned long block, unblock;
newmask &= _BLOCKABLE;
switch (how) {
case SIG_BLOCK:
current->blocked |= newmask;
return oldmask;
case SIG_UNBLOCK:
current->blocked &= ~newmask;
return oldmask;
case SIG_SETMASK:
current->blocked = newmask;
return oldmask;
oldmask = tsk->blocked;
newmask &= _BLOCKABLE;
sign = how-2;
unblock = oldmask & ~newmask;
block = oldmask | newmask;
if (!sign)
block = unblock;
regs.r0 = 0; /* special no error return */
if (sign <= 0)
newmask = block;
tsk->blocked = newmask;
}
return -EINVAL;
return oldmask;
}
/*
......
......@@ -156,24 +156,83 @@ void insw (unsigned long port, void *dst, unsigned long count)
/*
* Read COUNT 32-bit words from port PORT into memory starting at
* SRC. SRC must be at least word aligned. This is used by the
* IDE driver to read disk sectors. Performance is important, but
* the interfaces seems to be slow: just using the inlined version
* of the inw() breaks things.
* SRC. Now works with any alignment in SRC. Performance is important,
* but the interfaces seems to be slow: just using the inlined version
* of the inl() breaks things.
*/
void insl (unsigned long port, void *dst, unsigned long count)
{
if (((unsigned long)dst) & 0x3) {
panic("insl: memory not aligned");
}
while (count) {
unsigned int l = 0, l2;
if (!count)
return;
switch (((unsigned long) dst) & 0x3)
{
case 0x00: /* Buffer 32-bit aligned */
while (count--)
{
*(unsigned int *) dst = inl(port);
((unsigned int *) dst)++;
}
break;
/* Assuming little endian Alphas in cases 0x01 -- 0x03 ... */
case 0x02: /* Buffer 16-bit aligned */
--count;
*(unsigned int *) dst = inl(port);
((unsigned int *) dst)++;
l = inl(port);
*(unsigned short *) dst = l;
((unsigned short *) dst)++;
while (count--)
{
l2 = inl(port);
*(unsigned int *) dst = l >> 16 | l2 << 16;
((unsigned int *) dst)++;
l = l2;
}
*(unsigned short *) dst = l >> 16;
break;
case 0x01: /* Buffer 8-bit aligned */
--count;
l = inl(port);
*(unsigned char *) dst = l;
((unsigned char *) dst)++;
*(unsigned short *) dst = l >> 8;
((unsigned short *) dst)++;
while (count--)
{
l2 = inl(port);
*(unsigned int *) dst = l >> 24 | l2 << 8;
((unsigned int *) dst)++;
l = l2;
}
*(unsigned char *) dst = l >> 24;
break;
case 0x03: /* Buffer 8-bit aligned */
--count;
l = inl(port);
*(unsigned char *) dst = l;
((unsigned char *) dst)++;
while (count--)
{
l2 = inl(port);
*(unsigned int *) dst = l << 24 | l2 >> 8;
((unsigned int *) dst)++;
l = l2;
}
*(unsigned short *) dst = l >> 8;
((unsigned short *) dst)++;
*(unsigned char *) dst = l >> 24;
break;
}
}
/*
* Like insb but in the opposite direction.
* Don't worry as much about doing aligned memory transfers:
......@@ -223,20 +282,79 @@ void outsw (unsigned long port, const void *src, unsigned long count)
/*
* Like insl but in the opposite direction. This is used by the IDE
* driver to write disk sectors. Performance is important, but the
* interfaces seems to be slow: just using the inlined version of the
* outw() breaks things.
* driver to write disk sectors. Works with any alignment in SRC.
* Performance is important, but the interfaces seems to be slow:
* just using the inlined version of the outl() breaks things.
*/
void outsl (unsigned long port, const void *src, unsigned long count)
{
if (((unsigned long)src) & 0x3) {
panic("outsw: memory not aligned");
}
while (count) {
unsigned int l = 0, l2;
if (!count)
return;
switch (((unsigned long) src) & 0x3)
{
case 0x00: /* Buffer 32-bit aligned */
while (count--)
{
outl(*(unsigned int *) src, port);
((unsigned int *) src)++;
}
break;
/* Assuming little endian Alphas in cases 0x01 -- 0x03 ... */
case 0x02: /* Buffer 16-bit aligned */
--count;
outl(*(unsigned int *) src, port);
((unsigned int *) src)++;
l = *(unsigned short *) src << 16;
((unsigned short *) src)++;
while (count--)
{
l2 = *(unsigned int *) src;
((unsigned int *) src)++;
outl (l >> 16 | l2 << 16, port);
l = l2;
}
l2 = *(unsigned short *) src;
outl (l >> 16 | l2 << 16, port);
break;
case 0x01: /* Buffer 8-bit aligned */
--count;
l = *(unsigned char *) src << 8;
((unsigned char *) src)++;
l |= *(unsigned short *) src << 16;
((unsigned short *) src)++;
while (count--)
{
l2 = *(unsigned int *) src;
((unsigned int *) src)++;
outl (l >> 8 | l2 << 24, port);
l = l2;
}
l2 = *(unsigned char *) src;
outl (l >> 8 | l2 << 24, port);
break;
case 0x03: /* Buffer 8-bit aligned */
--count;
l = *(unsigned char *) src << 24;
((unsigned char *) src)++;
while (count--)
{
l2 = *(unsigned int *) src;
((unsigned int *) src)++;
outl (l >> 24 | l2 << 8, port);
l = l2;
}
l2 = *(unsigned short *) src;
((unsigned short *) src)++;
l2 |= *(unsigned char *) src << 16;
outl (l >> 24 | l2 << 8, port);
break;
}
}
......
......@@ -131,8 +131,8 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT;
pgd_val(swapper_pg_dir[1023]) = (newptbr << 32) | pgprot_val(PAGE_KERNEL);
init_task.tss.ptbr = newptbr;
init_task.tss.flags = 1;
init_task.tss.segment = KERNEL_DS;
init_task.tss.pal_flags = 1; /* set FEN, clear everything else */
init_task.tss.flags = 0;
init_task.kernel_stack_page = INIT_STACK;
load_PCB(&init_task.tss);
......
......@@ -37,6 +37,7 @@
*/
#include <asm/unaligned.h>
#define SYS_IND(p) get_unaligned(&p->sys_ind)
#define NR_SECTS(p) get_unaligned(&p->nr_sects)
#define START_SECT(p) get_unaligned(&p->start_sect)
......@@ -100,8 +101,8 @@ static void add_partition (struct gendisk *hd, int minor, int start, int size)
static inline int is_extended_partition(struct partition *p)
{
return (p->sys_ind == DOS_EXTENDED_PARTITION ||
p->sys_ind == LINUX_EXTENDED_PARTITION);
return (SYS_IND(p) == DOS_EXTENDED_PARTITION ||
SYS_IND(p) == LINUX_EXTENDED_PARTITION);
}
#ifdef CONFIG_MSDOS_PARTITION
......@@ -277,7 +278,7 @@ static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_s
*/
extern int ide_xlate_1024(kdev_t, int, const char *);
unsigned int sig = *(unsigned short *)(data + 2);
if (p->sys_ind == EZD_PARTITION) {
if (SYS_IND(p) == EZD_PARTITION) {
/*
* The remainder of the disk must be accessed using
* a translated geometry that reduces the number of
......@@ -290,7 +291,7 @@ static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_s
data += 512;
goto check_table;
}
} else if (p->sys_ind == DM6_PARTITION) {
} else if (SYS_IND(p) == DM6_PARTITION) {
/*
* Everything on the disk is offset by 63 sectors,
......@@ -313,7 +314,7 @@ static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_s
* DM6 signature in MBR, courtesy of OnTrack
*/
(void) ide_xlate_1024 (dev, 0, " [DM6:MBR]");
} else if (p->sys_ind == DM6_AUX1PARTITION || p->sys_ind == DM6_AUX3PARTITION) {
} else if (SYS_IND(p) == DM6_AUX1PARTITION || SYS_IND(p) == DM6_AUX3PARTITION) {
/*
* DM6 on other than the first (boot) drive
*/
......@@ -364,7 +365,7 @@ static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_s
hd->part[minor].nr_sects = 2;
}
#ifdef CONFIG_BSD_DISKLABEL
if (p->sys_ind == BSD_PARTITION) {
if (SYS_IND(p) == BSD_PARTITION) {
printk(" <");
bsd_disklabel_partition(hd, MKDEV(hd->major, minor));
printk(" >");
......
/*
* linux/drivers/block/ide-tape.c Version 1.5 - ALPHA Apr 12, 1996
* linux/drivers/block/ide-tape.c Version 1.6 - ALPHA Aug 16, 1996
*
* Copyright (C) 1995, 1996 Gadi Oxman <gadio@netvision.net.il>
*
......@@ -184,6 +184,8 @@
* Ver 1.5 Apr 12 96 Fixed shared interface operation, broken in 1.3.85.
* Fixed pipelined read mode inefficiency.
* Fixed nasty null dereferencing bug.
* Ver 1.6 Aug 16 96 Fixed FPU usage in the driver.
* Fixed end of media bug.
*
* We are currently in an *alpha* stage. The driver is not complete and not
* much tested. I would strongly suggest to:
......@@ -1224,8 +1226,7 @@ void idetape_setup (ide_drive_t *drive)
{
idetape_tape_t *tape=&(drive->tape);
unsigned int allocation_length;
double service_time,nr_units;
#if IDETAPE_DEBUG_LOG
printk ("ide-tape: Reached idetape_setup\n");
#endif /* IDETAPE_DEBUG_LOG */
......@@ -1259,8 +1260,11 @@ void idetape_setup (ide_drive_t *drive)
idetape_get_mode_sense_results (drive);
tape->data_buffer_size=tape->capabilities.ctl*tape->tape_block_size;
tape->data_buffer_size = tape->capabilities.ctl * tape->tape_block_size;
while (tape->data_buffer_size > 0xffff) {
tape->capabilities.ctl /= 2;
tape->data_buffer_size = tape->capabilities.ctl * tape->tape_block_size;
}
allocation_length=tape->data_buffer_size;
if (tape->data_buffer_size % IDETAPE_ALLOCATION_BLOCK)
allocation_length+=IDETAPE_ALLOCATION_BLOCK;
......@@ -1304,14 +1308,11 @@ void idetape_setup (ide_drive_t *drive)
* constantly streaming.
*/
service_time=((double) tape->data_buffer_size/1024.0)/((double) tape->capabilities.speed*(1000.0/1024.0));
nr_units=(double) tape->capabilities.buffer_size*512.0/(double) tape->data_buffer_size;
if (tape->max_number_of_stages)
tape->best_dsc_rw_frequency=(unsigned long) (0.5*nr_units*service_time*HZ);
else
tape->best_dsc_rw_frequency=(unsigned long) (service_time*HZ);
tape->best_dsc_rw_frequency = (unsigned long) ((tape->capabilities.buffer_size * 32 * HZ) / (tape->capabilities.speed * 125));
else
tape->best_dsc_rw_frequency = (unsigned long) ((tape->data_buffer_size * HZ) / (tape->capabilities.speed * 1000));
/*
* Ensure that the number we got makes sense.
*/
......@@ -2105,6 +2106,7 @@ void idetape_media_access_finished (ide_drive_t *drive)
void idetape_retry_pc (ide_drive_t *drive)
{
idetape_tape_t *tape = &drive->tape;
idetape_packet_command_t *pc;
struct request *new_rq;
......@@ -2116,6 +2118,7 @@ void idetape_retry_pc (ide_drive_t *drive)
pc->buffer=pc->temp_buffer;
pc->buffer_size=IDETAPE_TEMP_BUFFER_SIZE;
pc->current_position=pc->temp_buffer;
tape->reset_issued = 1;
idetape_queue_pc_head (drive,pc,new_rq);
}
......@@ -3217,7 +3220,7 @@ int idetape_add_chrdev_read_request (ide_drive_t *drive,int blocks,char *buffer)
rq.sector = tape->block_address;
rq.nr_sectors = rq.current_nr_sectors = blocks;
if (tape->active_data_request != NULL || tape->current_number_of_stages <= 0.25*tape->max_number_of_stages) {
if (tape->active_data_request != NULL || tape->current_number_of_stages <= tape->max_number_of_stages / 4) {
new_stage=idetape_kmalloc_stage (drive);
while (new_stage != NULL) {
new_stage->rq=rq;
......@@ -3335,7 +3338,7 @@ int idetape_add_chrdev_write_request (ide_drive_t *drive,int blocks,char *buffer
* keep up with the higher speeds of the tape.
*/
if (tape->active_data_request == NULL && tape->current_number_of_stages >= 0.75*tape->max_number_of_stages)
if (tape->active_data_request == NULL && tape->current_number_of_stages >= (3 * tape->max_number_of_stages) / 4)
idetape_insert_pipeline_into_queue (drive);
if (tape->error_in_pipeline_stage) { /* Return a deferred error */
......@@ -4458,8 +4461,7 @@ void idetape_increase_max_pipeline_stages (ide_drive_t *drive)
printk ("Reached idetape_increase_max_pipeline_stages\n");
#endif /* IDETAPE_DEBUG_LOG */
tape->max_number_of_stages+=IDETAPE_INCREASE_STAGES_RATE*
(IDETAPE_MAX_PIPELINE_STAGES-IDETAPE_MIN_PIPELINE_STAGES);
tape->max_number_of_stages+=IDETAPE_INCREASE_STAGES_RATE;
if (tape->max_number_of_stages >= IDETAPE_MAX_PIPELINE_STAGES)
tape->max_number_of_stages = IDETAPE_MAX_PIPELINE_STAGES;
......
......@@ -53,7 +53,7 @@
#define IDETAPE_MIN_PIPELINE_STAGES 100
#define IDETAPE_MAX_PIPELINE_STAGES 200
#define IDETAPE_INCREASE_STAGES_RATE 0.2
#define IDETAPE_INCREASE_STAGES_RATE 20
/*
* Assuming the tape shares an interface with another device, the default
......
......@@ -47,11 +47,11 @@ static char *version = "3c509.c:1.07 6/15/95 becker@cesdis.gsfc.nasa.gov\n";
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/config.h> /* for CONFIG_MCA */
#include <linux/delay.h> /* for udelay() */
#include <asm/bitops.h>
#include <asm/io.h>
#ifdef EL3_DEBUG
int el3_debug = EL3_DEBUG;
#else
......@@ -310,28 +310,24 @@ int el3_probe(struct device *dev)
*/
static ushort read_eeprom(short ioaddr, int index)
{
int timer;
outw(EEPROM_READ + index, ioaddr + 10);
/* Pause for at least 162 us. for the read to take place. */
for (timer = 0; timer < 162*4 + 400; timer++)
SLOW_DOWN_IO;
udelay (200);
return inw(ioaddr + 12);
}
/* Read a word from the EEPROM when in the ISA ID probe state. */
static ushort id_read_eeprom(int index)
{
int timer, bit, word = 0;
int bit, word = 0;
/* Issue read command, and pause for at least 162 us. for it to complete.
Assume extra-fast 16Mhz bus. */
outb(EEPROM_READ + index, id_port);
/* This should really be done by looking at one of the timer channels. */
for (timer = 0; timer < 162*4 + 400; timer++)
SLOW_DOWN_IO;
/* Pause for at least 162 us. for the read to take place. */
udelay (200);
for (bit = 15; bit >= 0; bit--)
word = (word << 1) + (inb(id_port) & 0x01);
......
This diff is collapsed.
......@@ -337,10 +337,19 @@
#define IMR_TIM 0x00000001 /* Transmit Interrupt Mask */
/*
** DC21040 Missed Frame Counter (DE4X5_MFC)
** DC21040 Missed Frames Counter (DE4X5_MFC)
*/
#define MFC_OVFL 0x00010000 /* Counter Overflow Bit */
#define MFC_CNTR 0x0000ffff /* Counter Bits */
#define MFC_OVFL 0x00010000 /* Missed Frames Counter Overflow Bit */
#define MFC_CNTR 0x0000ffff /* Missed Frames Counter Bits */
/*
** DC21140 Missed Frames and FIFO Overflow Counters (DE4X5_MFC)
*/
#define MFC_FOCO 0x10000000 /* FIFO Overflow Counter Overflow Bit */
#define MFC_FOC 0x0ffe0000 /* FIFO Overflow Counter Bits */
#define MFC_OVFL 0x00010000 /* Missed Frames Counter Overflow Bit */
#define MFC_CNTR 0x0000ffff /* Missed Frames Counter Bits */
#define MFC_FOCM 0x1ffe0000 /* FIFO Overflow Counter Mask */
/*
** DC21040 Ethernet Address PROM (DE4X5_APROM)
......
This diff is collapsed.
......@@ -127,17 +127,18 @@
0.40 27-Dec-95 Rationalise MODULE and autoprobe code.
Rewrite for portability & updated.
ALPHA support from <jestabro@amt.tay1.dec.com>
Added verify_area() calls in depca_ioctl() from
Added verify_area() calls in ewrk3_ioctl() from
suggestion by <heiko@colossus.escape.de>.
Add new multicasting code.
0.41 20-Jan-96 Fix IRQ set up problem reported by
<kenneth@bbs.sas.ntu.ac.sg>.
0.42 22-Apr-96 Fix alloc_device() bug <jari@markkus2.fimr.fi>
0.43 16-Aug-96 Update alloc_device() to conform to de4x5.c
=========================================================================
*/
static const char *version = "ewrk3.c:v0.42 96/4/22 davies@wanton.lkg.dec.com\n";
static const char *version = "ewrk3.c:v0.43 96/8/16 davies@wanton.lkg.dec.com\n";
#include <linux/module.h>
......@@ -162,6 +163,7 @@ static const char *version = "ewrk3.c:v0.42 96/4/22 davies@wanton.lkg.dec.com\n"
#include <linux/time.h>
#include <linux/types.h>
#include <linux/unistd.h>
#include <linux/ctype.h>
#include "ewrk3.h"
......@@ -315,6 +317,8 @@ static u_char get_hw_addr (struct device *dev, u_char *eeprom_image, char chipTy
static void isa_probe(struct device *dev, u_long iobase);
static void eisa_probe(struct device *dev, u_long iobase);
static struct device *alloc_device(struct device *dev, u_long iobase);
static int ewrk3_dev_index(char *s);
static struct device *insert_device(struct device *dev, u_long iobase, int (*init)(struct device *));
#ifdef MODULE
......@@ -1368,113 +1372,95 @@ static void eisa_probe(struct device *dev, u_long ioaddr)
}
/*
** Allocate the device by pointing to the next available space in the
** device structure. Should one not be available, it is created.
** Search the entire 'eth' device list for a fixed probe. If a match isn't
** found then check for an autoprobe or unused device location. If they
** are not available then insert a new device structure at the end of
** the current list.
*/
static struct device *alloc_device(struct device *dev, u_long iobase)
static struct device *
alloc_device(struct device *dev, u_long iobase)
{
int addAutoProbe = 0;
struct device *tmp = NULL, *ret;
int (*init)(struct device *) = NULL;
struct device *adev = NULL;
int fixed = 0, new_dev = 0;
/*
** Check the device structures for an end of list or unused device
*/
if (!loading_module) {
while (dev->next != NULL) {
if ((dev->base_addr == EWRK3_NDA) || (dev->base_addr == 0)) break;
dev = dev->next; /* walk through eth device list */
num_eth++; /* increment eth device number */
num_eth = ewrk3_dev_index(dev->name);
if (loading_module) return dev;
while (1) {
if (((dev->base_addr == EWRK3_NDA) || (dev->base_addr==0)) && !adev) {
adev=dev;
} else if ((dev->priv == NULL) && (dev->base_addr==iobase)) {
fixed = 1;
} else {
if (dev->next == NULL) {
new_dev = 1;
} else if (strncmp(dev->next->name, "eth", 3) != 0) {
new_dev = 1;
}
}
if ((dev->next == NULL) || new_dev || fixed) break;
dev = dev->next;
num_eth++;
}
if (adev && !fixed) {
dev = adev;
num_eth = ewrk3_dev_index(dev->name);
new_dev = 0;
}
/*
** If an autoprobe is requested for another device, we must re-insert
** the request later in the list. Remember the current position first.
*/
if ((dev->base_addr == 0) && (num_ewrk3s > 0)) {
addAutoProbe++;
tmp = dev->next; /* point to the next device */
init = dev->init; /* remember the probe function */
if (((dev->next == NULL) &&
((dev->base_addr != EWRK3_NDA) && (dev->base_addr != 0)) && !fixed) ||
new_dev) {
num_eth++; /* New device */
dev = insert_device(dev, iobase, ewrk3_probe);
}
return dev;
}
/*
** If at end of list and can't use current entry, malloc one up.
** If memory could not be allocated, print an error message.
*/
if ((dev->next == NULL) &&
!((dev->base_addr == EWRK3_NDA) || (dev->base_addr == 0))){
dev->next = (struct device *)kmalloc(sizeof(struct device) + 8,
GFP_KERNEL);
dev = dev->next; /* point to the new device */
if (dev == NULL) {
printk("eth%d: Device not initialised, insufficient memory\n",
num_eth);
} else {
/*
** If the memory was allocated, point to the new memory area
** and initialize it (name, I/O address, next device (NULL) and
** initialisation probe routine).
*/
/*
** If at end of eth device list and can't use current entry, malloc
** one up. If memory could not be allocated, print an error message.
*/
static struct device *
insert_device(struct device *dev, u_long iobase, int (*init)(struct device *))
{
struct device *new;
new = (struct device *)kmalloc(sizeof(struct device)+8, GFP_KERNEL);
if (new == NULL) {
printk("eth%d: Device not initialised, insufficient memory\n",num_eth);
return NULL;
} else {
new->next = dev->next;
dev->next = new;
dev = dev->next; /* point to the new device */
dev->name = (char *)(dev + 1);
if (num_eth > 9999) {
sprintf(dev->name,"eth????"); /* New device name */
sprintf(dev->name,"eth????");/* New device name */
} else {
sprintf(dev->name,"eth%d", num_eth);/* New device name */
sprintf(dev->name,"eth%d", num_eth);/* New device name */
}
dev->base_addr = iobase; /* assign the io address */
dev->next = NULL; /* mark the end of list */
dev->init = &ewrk3_probe; /* initialisation routine */
num_ewrk3s++;
}
dev->base_addr = iobase; /* assign the io address */
dev->init = init; /* initialisation routine */
}
ret = dev; /* return current struct, or NULL */
/*
** Now figure out what to do with the autoprobe that has to be inserted.
** Firstly, search the (possibly altered) list for an empty space.
*/
if (ret != NULL) {
if (addAutoProbe) {
for (;(tmp->next!=NULL) && (tmp->base_addr!=EWRK3_NDA); tmp=tmp->next);
/*
** If no more device structures and can't use the current one, malloc
** one up. If memory could not be allocated, print an error message.
*/
if ((tmp->next == NULL) && !(tmp->base_addr == EWRK3_NDA)) {
tmp->next = (struct device *)kmalloc(sizeof(struct device) + 8,
GFP_KERNEL);
tmp = tmp->next; /* point to the new device */
if (tmp == NULL) {
printk("%s: Insufficient memory to extend the device list.\n",
dev->name);
} else {
/*
** If the memory was allocated, point to the new memory area
** and initialize it (name, I/O address, next device (NULL) and
** initialisation probe routine).
*/
tmp->name = (char *)(tmp + 1);
if (num_eth > 9999) {
sprintf(tmp->name,"eth????"); /* New device name */
} else {
sprintf(tmp->name,"eth%d", num_eth);/* New device name */
}
tmp->base_addr = 0; /* re-insert the io address */
tmp->next = NULL; /* mark the end of list */
tmp->init = init; /* initialisation routine */
}
} else { /* structure already exists */
tmp->base_addr = 0; /* re-insert the io address */
}
}
return dev;
}
static int
ewrk3_dev_index(char *s)
{
int i=0, j=0;
for (;*s; s++) {
if (isdigit(*s)) {
j=1;
i = (i * 10) + (*s - '0');
} else if (j) break;
}
} else {
ret = dev;
}
return ret;
return i;
}
/*
......@@ -1927,9 +1913,9 @@ cleanup_module(void)
/*
* Local variables:
* kernel-compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -m486 -c ewrk3.c"
* compile-command: "gcc -D__KERNEL__ -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c ewrk3.c"
*
* module-compile-command: "gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -m486 -c ewrk3.c"
* compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c ewrk3.c"
* End:
*/
......@@ -69,7 +69,7 @@ struct net_local
extern int wavelan_probe(device *); /* See Space.c */
static const char *version = "wavelan.c:v7 95/4/8\n";
static const char *version = "wavelan.c:v8 96/8/18\n";
/*
* Entry point forward declarations.
......@@ -786,6 +786,13 @@ wavelan_probe(device *dev)
#endif /* 0 */
0x390,
};
static struct proc_dir_entry pe =
{
PROC_NET_WAVELAN, 7, "wavelan",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_net_inode_operations,
wavelan_get_info
};
if (wavelan_debug > 0)
printk("%s: ->wavelan_probe(dev=0x%x (base_addr=0x%x))\n", dev->name, (unsigned int)dev, (unsigned int)dev->base_addr);
......@@ -822,6 +829,8 @@ wavelan_probe(device *dev)
r = wavelan_probe1(dev, base_addr);
if (wavelan_debug > 0)
printk("%s: <-wavelan_probe(): %d\n", dev->name, r);
if (r == 0)
proc_net_register(&pe);
return r;
}
......@@ -834,13 +843,7 @@ wavelan_probe(device *dev)
{
if (wavelan_debug > 0)
printk("%s: <-wavelan_probe(): 0\n", dev->name);
proc_net_register(&(struct proc_dir_entry) {
PROC_NET_WAVELAN, 7, "wavelan",
S_IFREG | S_IRUGO, 1, 0, 0,
0, &proc_net_inode_operations,
wavelan_get_info
});
proc_net_register(&pe);
return 0;
}
}
......@@ -2495,6 +2498,7 @@ wavelan_local_show(device *dev)
* Marc Meertens (Marc.Meertens@Utrecht.NCR.com),
* Pauline Middelink (middelin@polyware.iaf.nl),
* Robert Morris (rtm@das.harvard.edu),
* Jean Tourrilhes (jt@hplb.hpl.hp.com),
* Girish Welling (welling@paul.rutgers.edu),
*
* Thanks go also to:
......@@ -2517,6 +2521,6 @@ wavelan_local_show(device *dev)
* Please send bug reports, updates, comments to:
*
* Bruce Janson Email: bruce@cs.usyd.edu.au
* Basser Department of Computer Science Phone: +61-2-351-3423
* University of Sydney, N.S.W., 2006, AUSTRALIA Fax: +61-2-351-3838
* Basser Department of Computer Science Phone: +61-2-9351-3423
* University of Sydney, N.S.W., 2006, AUSTRALIA Fax: +61-2-9351-3838
*/
......@@ -205,7 +205,9 @@ struct pci_dev_info dev_info[] = {
DEVICE( CYCLADES, CYCLOM_Z_Hi, "Cyclom-Z above 1Mbyte"),
DEVICE( SYMPHONY, SYMPHONY_101, "82C101"),
DEVICE( TEKRAM, TEKRAM_DC290, "DC-290"),
DEVICE( 3DLABS, 3DLABS_300SX, "GLINT 300SX"),
DEVICE( AVANCE, AVANCE_2302, "ALG-2302"),
DEVICE( S3, S3_ViRGE, "ViRGE"),
DEVICE( S3, S3_811, "Trio32/Trio64"),
DEVICE( S3, S3_868, "Vision 868"),
DEVICE( S3, S3_928, "Vision 928-P"),
......@@ -509,6 +511,7 @@ const char *pci_strvendor(unsigned int vendor)
case PCI_VENDOR_ID_CYCLADES: return "Cyclades";
case PCI_VENDOR_ID_SYMPHONY: return "Symphony";
case PCI_VENDOR_ID_TEKRAM: return "Tekram";
case PCI_VENDOR_ID_3DLABS: return "3Dlabs";
case PCI_VENDOR_ID_AVANCE: return "Avance";
case PCI_VENDOR_ID_S3: return "S3 Inc.";
case PCI_VENDOR_ID_INTEL: return "Intel";
......
This diff is collapsed.
This diff is collapsed.
......@@ -477,11 +477,11 @@ ad1848_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
switch (cmd & 0xff)
{
case SOUND_MIXER_RECSRC:
return snd_ioctl_return ((int *) arg, ad1848_set_recmask (devc, get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, ad1848_set_recmask (devc, get_user ((int *) arg)));
break;
default:
return snd_ioctl_return ((int *) arg, ad1848_mixer_set (devc, cmd & 0xff, get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, ad1848_mixer_set (devc, cmd & 0xff, get_user ((int *) arg)));
}
else
switch (cmd & 0xff) /*
......
......@@ -35,7 +35,7 @@ static int audio_format[MAX_AUDIO_DEV];
static int local_conversion[MAX_AUDIO_DEV];
static int
set_format (int dev, int fmt)
set_format (int dev, long fmt)
{
if (fmt != AFMT_QUERY)
{
......@@ -64,7 +64,7 @@ int
audio_open (int dev, struct fileinfo *file)
{
int ret;
int bits;
long bits;
int dev_type = dev & 0x0f;
int mode = file->mode & O_ACCMODE;
......@@ -381,7 +381,7 @@ audio_ioctl (int dev, struct fileinfo *file,
break;
case SNDCTL_DSP_SETFMT:
return snd_ioctl_return ((int *) arg, set_format (dev, get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, set_format (dev, get_user ((int *) arg)));
case SNDCTL_DSP_GETISPACE:
if (!(audio_devs[dev]->open_mode & OPEN_READ))
......
......@@ -227,13 +227,13 @@ close_dmap (int dev, struct dma_buffparms *dmap, int chan)
static unsigned int
default_set_bits (int dev, unsigned int bits)
{
return audio_devs[dev]->d->ioctl (dev, SNDCTL_DSP_SETFMT, (caddr_t) bits, 1);
return audio_devs[dev]->d->ioctl (dev, SNDCTL_DSP_SETFMT, (caddr_t) (long) bits, 1);
}
static int
default_set_speed (int dev, int speed)
{
return audio_devs[dev]->d->ioctl (dev, SNDCTL_DSP_SPEED, (caddr_t) speed, 1);
return audio_devs[dev]->d->ioctl (dev, SNDCTL_DSP_SPEED, (caddr_t) (long) speed, 1);
}
static short
......@@ -241,7 +241,7 @@ default_set_channels (int dev, short channels)
{
int c = channels;
return audio_devs[dev]->d->ioctl (dev, SNDCTL_DSP_CHANNELS, (caddr_t) c, 1);
return audio_devs[dev]->d->ioctl (dev, SNDCTL_DSP_CHANNELS, (caddr_t) (long) c, 1);
}
static void
......@@ -761,14 +761,14 @@ DMAbuf_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
{
struct dma_buffparms *dmap_out = audio_devs[dev]->dmap_out;
struct dma_buffparms *dmap_in = audio_devs[dev]->dmap_in;
int iarg = (int) arg;
long larg = (long) arg;
switch (cmd)
{
case SOUND_PCM_WRITE_RATE:
if (local)
return audio_devs[dev]->d->set_speed (dev, (int) arg);
return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_speed (dev, get_fs_long ((long *) arg)));
return audio_devs[dev]->d->set_speed (dev, larg);
return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_speed (dev, get_user ((int *) arg)));
case SOUND_PCM_READ_RATE:
if (local)
......@@ -777,13 +777,13 @@ DMAbuf_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
case SNDCTL_DSP_STEREO:
if (local)
return audio_devs[dev]->d->set_channels (dev, (int) arg + 1) - 1;
return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_channels (dev, get_fs_long ((long *) arg) + 1) - 1);
return audio_devs[dev]->d->set_channels (dev, larg + 1) - 1;
return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_channels (dev, get_user ((int *) arg) + 1) - 1);
case SOUND_PCM_WRITE_CHANNELS:
if (local)
return audio_devs[dev]->d->set_channels (dev, (short) iarg);
return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_channels (dev, get_fs_long ((long *) arg)));
return audio_devs[dev]->d->set_channels (dev, (short) larg);
return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_channels (dev, get_user ((int *) arg)));
case SOUND_PCM_READ_CHANNELS:
if (local)
......@@ -792,8 +792,8 @@ DMAbuf_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
case SNDCTL_DSP_SAMPLESIZE:
if (local)
return audio_devs[dev]->d->set_bits (dev, (unsigned int) arg);
return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_bits (dev, get_fs_long ((long *) arg)));
return audio_devs[dev]->d->set_bits (dev, larg);
return snd_ioctl_return ((int *) arg, audio_devs[dev]->d->set_bits (dev, get_user ((int *) arg)));
case SOUND_PCM_READ_BITS:
if (local)
......@@ -827,7 +827,7 @@ DMAbuf_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
case SNDCTL_DSP_SUBDIVIDE:
{
int fact = get_fs_long ((long *) arg);
int fact = get_user ((int *) arg);
int ret;
ret = dma_subdivide (dev, dmap_out, arg, fact);
......@@ -851,7 +851,7 @@ DMAbuf_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
case SNDCTL_DSP_SETFRAGMENT:
{
int fact = get_fs_long ((long *) arg);
int fact = get_user ((int *) arg);
int ret;
ret = dma_set_fragment (dev, dmap_out, arg, fact);
......@@ -930,7 +930,7 @@ DMAbuf_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
{
unsigned long flags;
int bits = get_fs_long ((long *) arg) & audio_devs[dev]->open_mode;
int bits = get_user ((int *) arg) & audio_devs[dev]->open_mode;
int changed;
if (audio_devs[dev]->d->trigger == NULL)
......
......@@ -2195,7 +2195,7 @@ gus_audio_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
case SOUND_PCM_WRITE_RATE:
if (local)
return gus_audio_set_speed ((int) arg);
return snd_ioctl_return ((int *) arg, gus_audio_set_speed (get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, gus_audio_set_speed (get_user ((int *) arg)));
break;
case SOUND_PCM_READ_RATE:
......@@ -2207,13 +2207,13 @@ gus_audio_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
case SNDCTL_DSP_STEREO:
if (local)
return gus_audio_set_channels ((int) arg + 1) - 1;
return snd_ioctl_return ((int *) arg, gus_audio_set_channels (get_fs_long ((long *) arg) + 1) - 1);
return snd_ioctl_return ((int *) arg, gus_audio_set_channels (get_user ((int *) arg) + 1) - 1);
break;
case SOUND_PCM_WRITE_CHANNELS:
if (local)
return gus_audio_set_channels ((int) arg);
return snd_ioctl_return ((int *) arg, gus_audio_set_channels (get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, gus_audio_set_channels (get_user ((int *) arg)));
break;
case SOUND_PCM_READ_CHANNELS:
......@@ -2225,7 +2225,7 @@ gus_audio_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
case SNDCTL_DSP_SETFMT:
if (local)
return gus_audio_set_bits ((int) arg);
return snd_ioctl_return ((int *) arg, gus_audio_set_bits (get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, gus_audio_set_bits (get_user ((int *) arg)));
break;
case SOUND_PCM_READ_BITS:
......@@ -3046,7 +3046,7 @@ gus_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
switch (cmd & 0xff)
{
case SOUND_MIXER_RECSRC:
gus_recmask = get_fs_long ((long *) arg) & MIX_DEVS;
gus_recmask = get_user ((int *) arg) & MIX_DEVS;
if (!(gus_recmask & (SOUND_MASK_MIC | SOUND_MASK_LINE)))
gus_recmask = SOUND_MASK_MIC;
/* Note! Input volumes are updated during next open for recording */
......@@ -3055,7 +3055,7 @@ gus_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
case SOUND_MIXER_MIC:
{
int vol = get_fs_long ((long *) arg) & 0xff;
int vol = get_user ((int *) arg) & 0xff;
if (vol < 0)
vol = 0;
......@@ -3069,7 +3069,7 @@ gus_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
case SOUND_MIXER_LINE:
{
int vol = get_fs_long ((long *) arg) & 0xff;
int vol = get_user ((int *) arg) & 0xff;
if (vol < 0)
vol = 0;
......@@ -3082,7 +3082,7 @@ gus_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
break;
case SOUND_MIXER_PCM:
gus_pcm_volume = get_fs_long ((long *) arg) & 0xff;
gus_pcm_volume = get_user ((int *) arg) & 0xff;
if (gus_pcm_volume < 0)
gus_pcm_volume = 0;
if (gus_pcm_volume > 100)
......@@ -3095,7 +3095,7 @@ gus_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
{
int voice;
gus_wave_volume = get_fs_long ((long *) arg) & 0xff;
gus_wave_volume = get_user ((int *) arg) & 0xff;
if (gus_wave_volume < 0)
gus_wave_volume = 0;
......
......@@ -128,23 +128,23 @@ ics2101_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
break;
case SOUND_MIXER_MIC:
return snd_ioctl_return ((int *) arg, set_volumes (DEV_MIC, get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, set_volumes (DEV_MIC, get_user ((int *) arg)));
break;
case SOUND_MIXER_CD:
return snd_ioctl_return ((int *) arg, set_volumes (DEV_CD, get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, set_volumes (DEV_CD, get_user ((int *) arg)));
break;
case SOUND_MIXER_LINE:
return snd_ioctl_return ((int *) arg, set_volumes (DEV_LINE, get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, set_volumes (DEV_LINE, get_user ((int *) arg)));
break;
case SOUND_MIXER_SYNTH:
return snd_ioctl_return ((int *) arg, set_volumes (DEV_GF1, get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, set_volumes (DEV_GF1, get_user ((int *) arg)));
break;
case SOUND_MIXER_VOLUME:
return snd_ioctl_return ((int *) arg, set_volumes (DEV_VOL, get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, set_volumes (DEV_VOL, get_user ((int *) arg)));
break;
default:
......
......@@ -473,7 +473,7 @@ MIDIbuf_ioctl (int dev, struct fileinfo *file,
{
case SNDCTL_MIDI_PRETIME:
val = (int) get_fs_long ((long *) arg);
val = (int) get_user ((int *) arg);
if (val < 0)
val = 0;
......
......@@ -790,7 +790,7 @@ mpu401_ioctl (int dev, unsigned cmd, caddr_t arg)
printk ("MPU-401: Intelligent mode not supported by the HW\n");
return -(EINVAL);
}
set_uart_mode (dev, devc, !get_fs_long ((long *) arg));
set_uart_mode (dev, devc, !get_user ((int *) arg));
return 0;
break;
......@@ -1590,7 +1590,7 @@ mpu_timer_ioctl (int dev,
{
case SNDCTL_TMR_SOURCE:
{
int parm = (int) get_fs_long ((long *) arg) & timer_caps;
int parm = (int) get_user ((int *) arg) & timer_caps;
if (parm != 0)
{
......@@ -1628,7 +1628,7 @@ mpu_timer_ioctl (int dev,
case SNDCTL_TMR_TIMEBASE:
{
int val = (int) get_fs_long ((long *) arg);
int val = (int) get_user ((int *) arg);
if (val)
set_timebase (midi_dev, val);
......@@ -1639,7 +1639,7 @@ mpu_timer_ioctl (int dev,
case SNDCTL_TMR_TEMPO:
{
int val = (int) get_fs_long ((long *) arg);
int val = (int) get_user ((int *) arg);
int ret;
if (val)
......@@ -1662,14 +1662,14 @@ mpu_timer_ioctl (int dev,
break;
case SNDCTL_SEQ_CTRLRATE:
if (get_fs_long ((long *) arg) != 0) /* Can't change */
if (get_user ((int *) arg) != 0) /* Can't change */
return -(EINVAL);
return snd_ioctl_return ((int *) arg, ((curr_tempo * curr_timebase) + 30) / 60);
break;
case SNDCTL_TMR_METRONOME:
metronome_mode = (int) get_fs_long ((long *) arg);
metronome_mode = (int) get_user ((int *) arg);
setup_metronome (midi_dev);
return 0;
break;
......
......@@ -218,7 +218,7 @@ pas_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
if (cmd == SOUND_MIXER_PRIVATE1) /* Set loudness bit */
{
int level = get_fs_long ((long *) arg);
int level = get_user ((int *) arg);
if (level == -1) /* Return current settings */
{
......@@ -240,7 +240,7 @@ pas_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
if (cmd == SOUND_MIXER_PRIVATE2) /* Set enhance bit */
{
int level = get_fs_long ((long *) arg);
int level = get_user ((int *) arg);
if (level == -1) /* Return current settings */
{
......@@ -269,7 +269,7 @@ pas_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
if (cmd == SOUND_MIXER_PRIVATE3) /* Set mute bit */
{
int level = get_fs_long ((long *) arg);
int level = get_user ((int *) arg);
if (level == -1) /* Return current settings */
{
......@@ -293,7 +293,7 @@ pas_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
if (((cmd >> 8) & 0xff) == 'M')
{
if (_IOC_DIR (cmd) & _IOC_WRITE)
return snd_ioctl_return ((int *) arg, pas_mixer_set (cmd & 0xff, get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, pas_mixer_set (cmd & 0xff, get_user ((int *) arg)));
else
{ /*
* Read parameters
......
......@@ -156,7 +156,7 @@ pas_audio_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
case SOUND_PCM_WRITE_RATE:
if (local)
return pcm_set_speed ((int) arg);
return snd_ioctl_return ((int *) arg, pcm_set_speed (get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, pcm_set_speed (get_user ((int *) arg)));
break;
case SOUND_PCM_READ_RATE:
......@@ -168,13 +168,13 @@ pas_audio_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
case SNDCTL_DSP_STEREO:
if (local)
return pcm_set_channels ((int) arg + 1) - 1;
return snd_ioctl_return ((int *) arg, pcm_set_channels (get_fs_long ((long *) arg) + 1) - 1);
return snd_ioctl_return ((int *) arg, pcm_set_channels (get_user ((int *) arg) + 1) - 1);
break;
case SOUND_PCM_WRITE_CHANNELS:
if (local)
return pcm_set_channels ((int) arg);
return snd_ioctl_return ((int *) arg, pcm_set_channels (get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, pcm_set_channels (get_user ((int *) arg)));
break;
case SOUND_PCM_READ_CHANNELS:
......@@ -186,7 +186,7 @@ pas_audio_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
case SNDCTL_DSP_SETFMT:
if (local)
return pcm_set_bits ((int) arg);
return snd_ioctl_return ((int *) arg, pcm_set_bits (get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, pcm_set_bits (get_user ((int *) arg)));
break;
case SOUND_PCM_READ_BITS:
......@@ -197,9 +197,9 @@ pas_audio_ioctl (int dev, unsigned int cmd, caddr_t arg, int local)
case SOUND_PCM_WRITE_FILTER: /*
* NOT YET IMPLEMENTED
*/
if (get_fs_long ((long *) arg) > 1)
if (get_user ((int *) arg) > 1)
return -(EINVAL);
pcm_filter = get_fs_long ((long *) arg);
pcm_filter = get_user ((int *) arg);
break;
case SOUND_PCM_READ_FILTER:
......
......@@ -307,12 +307,12 @@ sb_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
switch (cmd & 0xff)
{
case SOUND_MIXER_RECSRC:
return snd_ioctl_return ((int *) arg, set_recmask (devc, get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, set_recmask (devc, get_user ((int *) arg)));
break;
default:
return snd_ioctl_return ((int *) arg, sb_mixer_set (devc, cmd & 0xff, get_fs_long ((long *) arg)));
return snd_ioctl_return ((int *) arg, sb_mixer_set (devc, cmd & 0xff, get_user ((int *) arg)));
}
else
switch (cmd & 0xff)
......
......@@ -1544,7 +1544,7 @@ sequencer_ioctl (int dev, struct fileinfo *file,
if (seq_mode != SEQ_2)
return -(EINVAL);
pending_timer = get_fs_long ((long *) arg);
pending_timer = get_user ((int *) arg);
if (pending_timer < 0 || pending_timer >= num_sound_timers)
{
......@@ -1591,7 +1591,7 @@ sequencer_ioctl (int dev, struct fileinfo *file,
*/
return -(EIO);
midi_dev = get_fs_long ((long *) arg);
midi_dev = get_user ((int *) arg);
if (midi_dev >= max_mididev)
return -(ENXIO);
......@@ -1639,7 +1639,7 @@ sequencer_ioctl (int dev, struct fileinfo *file,
if (seq_mode == SEQ_2)
return tmr->ioctl (tmr_no, cmd, arg);
if (get_fs_long ((long *) arg) != 0)
if (get_user ((int *) arg) != 0)
return -(EINVAL);
return snd_ioctl_return ((int *) arg, HZ);
......@@ -1649,7 +1649,7 @@ sequencer_ioctl (int dev, struct fileinfo *file,
{
int err;
dev = get_fs_long ((long *) arg);
dev = get_user ((int *) arg);
if (dev < 0 || dev >= num_synths)
{
return -(ENXIO);
......@@ -1678,7 +1678,7 @@ sequencer_ioctl (int dev, struct fileinfo *file,
case SNDCTL_SYNTH_MEMAVL:
{
int dev = get_fs_long ((long *) arg);
int dev = get_user ((int *) arg);
if (dev < 0 || dev >= num_synths)
return -(ENXIO);
......@@ -1692,7 +1692,7 @@ sequencer_ioctl (int dev, struct fileinfo *file,
case SNDCTL_FM_4OP_ENABLE:
{
int dev = get_fs_long ((long *) arg);
int dev = get_user ((int *) arg);
if (dev < 0 || dev >= num_synths)
return -(ENXIO);
......@@ -1833,7 +1833,7 @@ sequencer_ioctl (int dev, struct fileinfo *file,
case SNDCTL_SEQ_THRESHOLD:
{
int tmp = get_fs_long ((long *) arg);
int tmp = get_user ((int *) arg);
if (dev) /*
* Patch manager
......@@ -1851,7 +1851,7 @@ sequencer_ioctl (int dev, struct fileinfo *file,
case SNDCTL_MIDI_PRETIME:
{
int val = get_fs_long ((long *) arg);
int val = get_user ((int *) arg);
if (val < 0)
val = 0;
......
......@@ -214,7 +214,7 @@ timer_ioctl (int dev,
case SNDCTL_TMR_TIMEBASE:
{
int val = get_fs_long ((long *) arg);
int val = get_user ((int *) arg);
if (val)
{
......@@ -231,7 +231,7 @@ timer_ioctl (int dev,
case SNDCTL_TMR_TEMPO:
{
int val = get_fs_long ((long *) arg);
int val = get_user ((int *) arg);
if (val)
{
......@@ -251,7 +251,7 @@ timer_ioctl (int dev,
break;
case SNDCTL_SEQ_CTRLRATE:
if (get_fs_long ((long *) arg) != 0) /* Can't change */
if (get_user ((int *) arg) != 0) /* Can't change */
return -(EINVAL);
return snd_ioctl_return ((int *) arg, ((curr_tempo * curr_timebase) + 30) / 60);
......
......@@ -48,7 +48,7 @@ snd_ioctl_return (int *addr, int value)
if (value < 0)
return value;
put_fs_long (value, (long *) &((addr)[0]));
put_user (value, addr);
return 0;
}
......@@ -668,7 +668,7 @@ sound_alloc_dmap (int dev, struct dma_buffparms *dmap, int chan)
audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz);
if ((start_addr = (char *) __get_free_pages (GFP_ATOMIC, sz, MAX_DMA_ADDRESS)) == NULL)
if ((start_addr = (char *) __get_dma_pages (GFP_ATOMIC, sz)) == NULL)
audio_devs[dev]->buffsize /= 2;
}
......
......@@ -213,7 +213,7 @@ def_tmr_ioctl (int dev,
case SNDCTL_TMR_TIMEBASE:
{
int val = get_fs_long ((long *) arg);
int val = get_user ((int *) arg);
if (val)
{
......@@ -230,7 +230,7 @@ def_tmr_ioctl (int dev,
case SNDCTL_TMR_TEMPO:
{
int val = get_fs_long ((long *) arg);
int val = get_user ((int *) arg);
if (val)
{
......@@ -249,7 +249,7 @@ def_tmr_ioctl (int dev,
break;
case SNDCTL_SEQ_CTRLRATE:
if (get_fs_long ((long *) arg) != 0) /* Can't change */
if (get_user ((int *) arg) != 0) /* Can't change */
return -(EINVAL);
return snd_ioctl_return ((int *) arg, ((curr_tempo * curr_timebase) + 30) / 60);
......
......@@ -17,6 +17,7 @@
#include <linux/tty.h>
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/file.h>
#include <asm/segment.h>
#include <asm/bitops.h>
......@@ -602,6 +603,16 @@ asmlinkage int sys_creat(const char * pathname, int mode)
#endif
void __fput(struct file *filp, struct inode *inode)
{
if (filp->f_op && filp->f_op->release)
filp->f_op->release(inode,filp);
filp->f_inode = NULL;
if (filp->f_mode & FMODE_WRITE)
put_write_access(inode);
iput(inode);
}
int close_fp(struct file *filp)
{
struct inode *inode;
......@@ -613,17 +624,7 @@ int close_fp(struct file *filp)
inode = filp->f_inode;
if (inode)
locks_remove_locks(current, filp);
if (filp->f_count > 1) {
filp->f_count--;
return 0;
}
if (filp->f_op && filp->f_op->release)
filp->f_op->release(inode,filp);
filp->f_count--;
filp->f_inode = NULL;
if (filp->f_mode & FMODE_WRITE)
put_write_access(inode);
iput(inode);
fput(filp, inode);
return 0;
}
......
......@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fcntl.h>
#include <linux/file.h>
#include <linux/mm.h>
#include <linux/uio.h>
......@@ -106,21 +107,33 @@ asmlinkage int sys_read(unsigned int fd,char * buf,int count)
struct file * file;
struct inode * inode;
if (fd>=NR_OPEN || !(file=current->files->fd[fd]) || !(inode=file->f_inode))
return -EBADF;
error = -EBADF;
file = fget(fd);
if (!file)
goto bad_file;
inode = file->f_inode;
if (!inode)
goto out;
error = -EBADF;
if (!(file->f_mode & 1))
return -EBADF;
goto out;
error = -EINVAL;
if (!file->f_op || !file->f_op->read)
return -EINVAL;
goto out;
error = 0;
if (count <= 0)
return 0;
goto out;
error = locks_verify_area(FLOCK_VERIFY_READ,inode,file,file->f_pos,count);
if (error)
return error;
goto out;
error = verify_area(VERIFY_WRITE,buf,count);
if (error)
return error;
return file->f_op->read(inode,file,buf,count);
goto out;
error = file->f_op->read(inode,file,buf,count);
out:
fput(file, inode);
bad_file:
return error;
}
asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count)
......@@ -128,22 +141,28 @@ asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count)
int error;
struct file * file;
struct inode * inode;
int written;
if (fd>=NR_OPEN || !(file=current->files->fd[fd]) || !(inode=file->f_inode))
return -EBADF;
error = -EBADF;
file = fget(fd);
if (!file)
goto bad_file;
inode = file->f_inode;
if (!inode)
goto out;
if (!(file->f_mode & 2))
return -EBADF;
goto out;
error = -EINVAL;
if (!file->f_op || !file->f_op->write)
return -EINVAL;
goto out;
error = 0;
if (!count)
return 0;
goto out;
error = locks_verify_area(FLOCK_VERIFY_WRITE,inode,file,file->f_pos,count);
if (error)
return error;
goto out;
error = verify_area(VERIFY_READ,buf,count);
if (error)
return error;
goto out;
/*
* If data has been written to the file, remove the setuid and
* the setgid bits. We do it anyway otherwise there is an
......@@ -164,9 +183,12 @@ asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count)
}
down(&inode->i_sem);
written = file->f_op->write(inode,file,buf,count);
error = file->f_op->write(inode,file,buf,count);
up(&inode->i_sem);
return written;
out:
fput(file, inode);
bad_file:
return error;
}
static int sock_readv_writev(int type, struct inode * inode, struct file * file,
......
......@@ -5,8 +5,10 @@
* ELF register definitions..
*/
/*
* Note: ELF_NGREG must ben the same as EF_SIZE/8.
/*
* The OSF/1 version of <sys/procfs.h> makes gregset_t 46 entries long.
* I have no idea why that is so. For now, we just leave it at 33
* (32 general regs + processor status word).
*/
#define ELF_NGREG 33
#define ELF_NFPREG 32
......@@ -32,12 +34,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 8192
#define ELF_CORE_COPY_REGS(_dest,_regs) \
{ struct user _dump; \
dump_thread(_regs, &_dump); \
memcpy((char *) &_dest, (char *) &_dump.regs, \
sizeof(elf_gregset_t)); }
/* $0 is set by ld.so to a pointer to a function which might be
registered using atexit. This provides a mean for the dynamic
linker to call DT_FINI functions for shared libraries that have
......@@ -49,4 +45,50 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#define ELF_PLAT_INIT(_r) _r->r0 = 0
/* Use the same format as the OSF/1 procfs interface. The register
layout is sane. However, since dump_thread() creates the funky
layout that ECOFF coredumps want, we need to undo that layout here.
Eventually, it would be nice if the ECOFF core-dump had to do the
translation, then ELF_CORE_COPY_REGS() would become trivial and
faster. */
#define ELF_CORE_COPY_REGS(_dest,_regs) \
{ \
struct user _dump; \
\
dump_thread(_regs, &_dump); \
_dest[ 0] = _dump.regs[EF_V0]; \
_dest[ 1] = _dump.regs[EF_T0]; \
_dest[ 2] = _dump.regs[EF_T1]; \
_dest[ 3] = _dump.regs[EF_T2]; \
_dest[ 4] = _dump.regs[EF_T3]; \
_dest[ 5] = _dump.regs[EF_T4]; \
_dest[ 6] = _dump.regs[EF_T5]; \
_dest[ 7] = _dump.regs[EF_T6]; \
_dest[ 8] = _dump.regs[EF_T7]; \
_dest[ 9] = _dump.regs[EF_S0]; \
_dest[10] = _dump.regs[EF_S1]; \
_dest[11] = _dump.regs[EF_S2]; \
_dest[12] = _dump.regs[EF_S3]; \
_dest[13] = _dump.regs[EF_S4]; \
_dest[14] = _dump.regs[EF_S5]; \
_dest[15] = _dump.regs[EF_S6]; \
_dest[16] = _dump.regs[EF_A0]; \
_dest[17] = _dump.regs[EF_A1]; \
_dest[18] = _dump.regs[EF_A2]; \
_dest[19] = _dump.regs[EF_A3]; \
_dest[20] = _dump.regs[EF_A4]; \
_dest[21] = _dump.regs[EF_A5]; \
_dest[22] = _dump.regs[EF_T8]; \
_dest[23] = _dump.regs[EF_T9]; \
_dest[24] = _dump.regs[EF_T10]; \
_dest[25] = _dump.regs[EF_T11]; \
_dest[26] = _dump.regs[EF_RA]; \
_dest[27] = _dump.regs[EF_T12]; \
_dest[28] = _dump.regs[EF_AT]; \
_dest[29] = _dump.regs[EF_GP]; \
_dest[30] = _dump.regs[EF_SP]; \
_dest[31] = _dump.regs[EF_PC]; /* store PC here */ \
_dest[32] = _dump.regs[EF_PS]; \
}
#endif
......@@ -27,6 +27,7 @@
#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
struct thread_struct {
/* the fields below are used by PALcode and must match struct pcb: */
unsigned long ksp;
unsigned long usp;
unsigned long ptbr;
......@@ -34,12 +35,18 @@ struct thread_struct {
unsigned int asn;
unsigned long unique;
/*
* bit 0.. 0: floating point enable (used by PALcode)
* bit 1.. 5: IEEE_TRAP_ENABLE bits (see fpu.h)
* bit 0: floating point enable
* bit 62: performance monitor enable
*/
unsigned long flags;
unsigned long pal_flags;
unsigned long res1, res2;
unsigned long segment;
/* the fields below are Linux-specific: */
/*
* bit 0: perform syscall argument validation (get/set_fs)
* bit 1..5: IEEE_TRAP_ENABLE bits (see fpu.h)
*/
unsigned long flags;
};
#define INIT_MMAP { &init_mm, 0xfffffc0000000000, 0xfffffc0010000000, \
......@@ -48,7 +55,8 @@ struct thread_struct {
#define INIT_TSS { \
0, 0, 0, \
0, 0, 0, \
0, 0, 0, KERNEL_DS, \
0, 0, 0, \
0 \
}
#define alloc_kernel_stack() get_free_page(GFP_KERNEL)
......
......@@ -102,17 +102,18 @@ static inline void memcpy_tofs(void * to, const void * from, unsigned long n)
}
/*
* For segmented architectures, these are used to specify which segment
* to use for the above functions.
* The fs value determines whether argument validity checking should be
* performed or not. If get_fs() == USER_DS, checking is performed, with
* get_fs() == KERNEL_DS, checking is bypassed.
*
* The alpha is not segmented, so these are just dummies.
* For historical reasons, these macros are grossly misnamed.
*/
#define KERNEL_DS 0
#define USER_DS 1
#define KERNEL_DS 0
#define USER_DS 1
#define get_fs() (current->tss.segment)
#define set_fs(x) (current->tss.segment=(x))
#define get_fs() (current->tss.flags & 0x1)
#define set_fs(x) (current->tss.flags = (current->tss.flags & ~0x1) | ((x) & 0x1))
static inline unsigned long get_ds(void)
{
......
......@@ -3,29 +3,23 @@
#ifndef __KERNEL_STRICT_NAMES
#include <linux/posix_types.h>
#include <linux/types.h>
typedef __kernel_fsid_t fsid_t;
#endif
/*
* The OSF/1 statfs structure is much larger, but this should
* match the beginning, at least.
*/
struct statfs {
short f_type;
short f_flags;
int f_fsize;
int f_bsize;
int f_blocks;
int f_bfree;
int f_bavail;
int f_files;
int f_ffree;
int f_type;
int f_bsize;
int f_blocks;
int f_bfree;
int f_bavail;
int f_files;
int f_ffree;
__kernel_fsid_t f_fsid;
/* linux-specific entries start here.. */
int f_namelen;
int f_namelen;
int f_spare[6];
};
#endif
#ifndef __LINUX_FILE_H
#define __LINUX_FILE_H
extern inline struct file * fget(unsigned long fd)
{
struct file * file = NULL;
if (fd < NR_OPEN) {
file = current->files->fd[fd];
if (file)
file->f_count++;
}
return file;
}
extern void __fput(struct file *, struct inode *);
extern inline void fput(struct file *file, struct inode *inode)
{
int count = file->f_count-1;
if (!count)
__fput(file, inode);
file->f_count = count;
}
#endif
/*
* Linux NET3: Internet Gateway Management Protocol [IGMP]
* Linux NET3: Internet Group Management Protocol [IGMP]
*
* Authors:
* Alan Cox <Alan.Cox@linux.org>
......
......@@ -24,7 +24,7 @@
enum {
IPPROTO_IP = 0, /* Dummy protocol for TCP */
IPPROTO_ICMP = 1, /* Internet Control Message Protocol */
IPPROTO_IGMP = 2, /* Internet Gateway Management Protocol */
IPPROTO_IGMP = 2, /* Internet Group Management Protocol */
IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
IPPROTO_TCP = 6, /* Transmission Control Protocol */
IPPROTO_EGP = 8, /* Exterior Gateway Protocol */
......
......@@ -521,10 +521,14 @@
#define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
#define PCI_VENDOR_ID_3DLABS 0x3D3D
#define PCI_DEVICE_ID_3DLABS_300SX 0x0001
#define PCI_VENDOR_ID_AVANCE 0x4005
#define PCI_DEVICE_ID_AVANCE_2302 0x2302
#define PCI_VENDOR_ID_S3 0x5333
#define PCI_DEVICE_ID_S3_ViRGE 0x5631
#define PCI_DEVICE_ID_S3_811 0x8811
#define PCI_DEVICE_ID_S3_868 0x8880
#define PCI_DEVICE_ID_S3_928 0x88b0
......
......@@ -46,6 +46,6 @@ extern struct exec_domain default_exec_domain;
extern struct exec_domain *lookup_exec_domain(unsigned long personality);
extern int register_exec_domain(struct exec_domain *it);
extern int unregister_exec_domain(struct exec_domain *it);
extern asmlinkage int sys_personality(unsigned long personality);
asmlinkage int sys_personality(unsigned long personality);
#endif /* _PERSONALITY_H */
......@@ -997,23 +997,11 @@ static void timer_bh(void)
run_timer_list();
}
/*
* Run the bottom half stuff only about 100 times a second,
* we'd just use up unnecessary CPU time for timer handling
* otherwise
*/
#if HZ > 100
#define should_run_timers(x) ((x) >= HZ/100)
#else
#define should_run_timers(x) (1)
#endif
void do_timer(struct pt_regs * regs)
{
(*(unsigned long *)&jiffies)++;
lost_ticks++;
if (should_run_timers(lost_ticks))
mark_bh(TIMER_BH);
mark_bh(TIMER_BH);
if (!user_mode(regs)) {
lost_ticks_system++;
if (prof_buffer && current->pid) {
......
......@@ -70,6 +70,7 @@
* Alan Cox : Allow NULL arguments on some SO_ opts
* Alan Cox : Generic socket allocation to make hooks
* easier (suggested by Craig Metz).
* Michael Pall : SO_ERROR returns positive errno again
*
* To Fix:
*
......@@ -280,7 +281,7 @@ int sock_getsockopt(struct sock *sk, int level, int optname,
break;
case SO_ERROR:
val = sock_error(sk);
val = -sock_error(sk);
if(val==0)
val=xchg(&sk->err_soft,0);
break;
......
/*
* Linux NET3: Internet Gateway Management Protocol [IGMP]
* Linux NET3: Internet Group Management Protocol [IGMP]
*
* This code implements the IGMP protocol as defined in RFC1122. There has
* This code implements the IGMP protocol as defined in RFC1112. There has
* been a further revision of this protocol since which is now supported.
*
* If you have trouble with this module be careful what gcc you have used,
......
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