Commit c54c8322 authored by Linus Torvalds's avatar Linus Torvalds

Linux 2.1.129

To a large degree is more merges for PPC and Sparc (and
somehow I must have missed ARM _again_, so I'll have to find that).

But there's a few other things in there:
 - ncr53c8xx tag fix
 - more sound fixes.
 - NFS fixed
 - some subtle TCP issues fixed
 - and lots of mm smoothness tweaks (most of those have been floating
   around for some time - like getting rid of the last vestiges of page
   ages which just complicated and hurt the code)

Have fun with it, and tell me if it breaks. But it won't. I'm finally
getting the old "greased weasel" feeling back. In short, this is the much
awaited perfect and bug-free release, and the only reason I don't call it
2.2 is that I'm chicken.

	Kvaa, kvaa,
			Linus
parent 03c31052
......@@ -69,6 +69,7 @@ CONFIG_SUN_MOSTEK_RTC=y
# CONFIG_SPARCAUDIO_AMD7930 is not set
# CONFIG_SPARCAUDIO_CS4231 is not set
# CONFIG_SPARCAUDIO_DBRI is not set
# CONFIG_SPARCAUDIO_DUMMY is not set
CONFIG_SUN_OPENPROMFS=m
CONFIG_NET=y
CONFIG_SYSVIPC=y
......
# $Id: config.in,v 1.57 1998/09/17 11:05:14 jj Exp $
# $Id: config.in,v 1.58 1998/11/16 04:47:30 davem Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
......
......@@ -74,6 +74,7 @@ CONFIG_OBP_FLASH=m
# CONFIG_SPARCAUDIO_AMD7930 is not set
# CONFIG_SPARCAUDIO_CS4231 is not set
# CONFIG_SPARCAUDIO_DBRI is not set
# CONFIG_SPARCAUDIO_DUMMY is not set
CONFIG_SUN_OPENPROMFS=m
CONFIG_PCI_OLD_PROC=y
CONFIG_NET=y
......@@ -238,7 +239,6 @@ CONFIG_HAPPYMEAL=y
CONFIG_SUNQE=m
CONFIG_MYRI_SBUS=m
CONFIG_DE4X5=m
CONFIG_VORTEX=m
#
# Filesystems
......
/* $Id: ioctl32.c,v 1.54 1998/11/11 17:09:04 jj Exp $
/* $Id: ioctl32.c,v 1.55 1998/11/17 07:43:17 davem Exp $
* ioctl32.c: Conversion between 32bit and 64bit native ioctls.
*
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
......@@ -53,6 +53,8 @@
#include <asm/envctrl.h>
#include <asm/audioio.h>
#include <linux/soundcard.h>
/* Use this to get at 32-bit user passed pointers.
See sys_sparc32.c for description about these. */
#define A(__x) ((unsigned long)(__x))
......@@ -1885,6 +1887,152 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
case AUDIO_GETDEV_SUNOS:
case AUDIO_FLUSH:
/* Big Q for sound/OSS */
case SNDCTL_SEQ_RESET:
case SNDCTL_SEQ_SYNC:
case SNDCTL_SYNTH_INFO:
case SNDCTL_SEQ_CTRLRATE:
case SNDCTL_SEQ_GETOUTCOUNT:
case SNDCTL_SEQ_GETINCOUNT:
case SNDCTL_SEQ_PERCMODE:
case SNDCTL_FM_LOAD_INSTR:
case SNDCTL_SEQ_TESTMIDI:
case SNDCTL_SEQ_RESETSAMPLES:
case SNDCTL_SEQ_NRSYNTHS:
case SNDCTL_SEQ_NRMIDIS:
case SNDCTL_MIDI_INFO:
case SNDCTL_SEQ_THRESHOLD:
case SNDCTL_SYNTH_MEMAVL:
case SNDCTL_FM_4OP_ENABLE:
case SNDCTL_SEQ_PANIC:
case SNDCTL_SEQ_OUTOFBAND:
case SNDCTL_SEQ_GETTIME:
case SNDCTL_SYNTH_ID:
case SNDCTL_SYNTH_CONTROL:
case SNDCTL_SYNTH_REMOVESAMPLE:
/* Big T for sound/OSS */
case SNDCTL_TMR_TIMEBASE:
case SNDCTL_TMR_START:
case SNDCTL_TMR_STOP:
case SNDCTL_TMR_CONTINUE:
case SNDCTL_TMR_TEMPO:
case SNDCTL_TMR_SOURCE:
case SNDCTL_TMR_METRONOME:
case SNDCTL_TMR_SELECT:
/* Little m for sound/OSS */
case SNDCTL_MIDI_PRETIME:
case SNDCTL_MIDI_MPUMODE:
case SNDCTL_MIDI_MPUCMD:
/* Big P for sound/OSS */
case SNDCTL_DSP_RESET:
case SNDCTL_DSP_SYNC:
case SNDCTL_DSP_SPEED:
case SNDCTL_DSP_STEREO:
case SNDCTL_DSP_GETBLKSIZE:
case SNDCTL_DSP_CHANNELS:
case SOUND_PCM_WRITE_FILTER:
case SNDCTL_DSP_POST:
case SNDCTL_DSP_SUBDIVIDE:
case SNDCTL_DSP_SETFRAGMENT:
case SNDCTL_DSP_GETFMTS:
case SNDCTL_DSP_SETFMT:
case SNDCTL_DSP_GETOSPACE:
case SNDCTL_DSP_GETISPACE:
case SNDCTL_DSP_NONBLOCK:
case SNDCTL_DSP_GETCAPS:
case SNDCTL_DSP_GETTRIGGER:
case SNDCTL_DSP_SETTRIGGER:
case SNDCTL_DSP_GETIPTR:
case SNDCTL_DSP_GETOPTR:
/* case SNDCTL_DSP_MAPINBUF: XXX needs translation */
/* case SNDCTL_DSP_MAPOUTBUF: XXX needs translation */
case SNDCTL_DSP_SETSYNCRO:
case SNDCTL_DSP_SETDUPLEX:
case SNDCTL_DSP_GETODELAY:
case SNDCTL_DSP_PROFILE:
case SOUND_PCM_READ_RATE:
case SOUND_PCM_READ_CHANNELS:
case SOUND_PCM_READ_BITS:
case SOUND_PCM_READ_FILTER:
/* Big C for sound/OSS */
case SNDCTL_COPR_RESET:
case SNDCTL_COPR_LOAD:
case SNDCTL_COPR_RDATA:
case SNDCTL_COPR_RCODE:
case SNDCTL_COPR_WDATA:
case SNDCTL_COPR_WCODE:
case SNDCTL_COPR_RUN:
case SNDCTL_COPR_HALT:
case SNDCTL_COPR_SENDMSG:
case SNDCTL_COPR_RCVMSG:
/* Big M for sound/OSS */
case SOUND_MIXER_READ_VOLUME:
case SOUND_MIXER_READ_BASS:
case SOUND_MIXER_READ_TREBLE:
case SOUND_MIXER_READ_SYNTH:
case SOUND_MIXER_READ_PCM:
case SOUND_MIXER_READ_SPEAKER:
case SOUND_MIXER_READ_LINE:
case SOUND_MIXER_READ_MIC:
case SOUND_MIXER_READ_CD:
case SOUND_MIXER_READ_IMIX:
case SOUND_MIXER_READ_ALTPCM:
case SOUND_MIXER_READ_RECLEV:
case SOUND_MIXER_READ_IGAIN:
case SOUND_MIXER_READ_OGAIN:
case SOUND_MIXER_READ_LINE1:
case SOUND_MIXER_READ_LINE2:
case SOUND_MIXER_READ_LINE3:
case SOUND_MIXER_READ_MUTE:
/* case SOUND_MIXER_READ_ENHANCE: same value as READ_MUTE */
/* case SOUND_MIXER_READ_LOUD: same value as READ_MUTE */
case SOUND_MIXER_READ_RECSRC:
case SOUND_MIXER_READ_DEVMASK:
case SOUND_MIXER_READ_RECMASK:
case SOUND_MIXER_READ_STEREODEVS:
case SOUND_MIXER_READ_CAPS:
case SOUND_MIXER_WRITE_VOLUME:
case SOUND_MIXER_WRITE_BASS:
case SOUND_MIXER_WRITE_TREBLE:
case SOUND_MIXER_WRITE_SYNTH:
case SOUND_MIXER_WRITE_PCM:
case SOUND_MIXER_WRITE_SPEAKER:
case SOUND_MIXER_WRITE_LINE:
case SOUND_MIXER_WRITE_MIC:
case SOUND_MIXER_WRITE_CD:
case SOUND_MIXER_WRITE_IMIX:
case SOUND_MIXER_WRITE_ALTPCM:
case SOUND_MIXER_WRITE_RECLEV:
case SOUND_MIXER_WRITE_IGAIN:
case SOUND_MIXER_WRITE_OGAIN:
case SOUND_MIXER_WRITE_LINE1:
case SOUND_MIXER_WRITE_LINE2:
case SOUND_MIXER_WRITE_LINE3:
case SOUND_MIXER_WRITE_MUTE:
/* case SOUND_MIXER_WRITE_ENHANCE: same value as WRITE_MUTE */
/* case SOUND_MIXER_WRITE_LOUD: same value as WRITE_MUTE */
case SOUND_MIXER_WRITE_RECSRC:
case SOUND_MIXER_INFO:
case SOUND_OLD_MIXER_INFO:
case SOUND_MIXER_ACCESS:
case SOUND_MIXER_PRIVATE1:
case SOUND_MIXER_PRIVATE2:
case SOUND_MIXER_PRIVATE3:
case SOUND_MIXER_PRIVATE4:
case SOUND_MIXER_PRIVATE5:
case SOUND_MIXER_GETLEVELS:
case SOUND_MIXER_SETLEVELS:
case OSS_GETVERSION:
/* AUTOFS */
case AUTOFS_IOC_READY:
case AUTOFS_IOC_FAIL:
......
/* $Id: parport_ax.c,v 1.13 1998/10/26 20:01:59 davem Exp $
/* $Id: parport_ax.c,v 1.14 1998/11/16 04:48:02 davem Exp $
* Parallel-port routines for Sun Ultra/AX architecture
*
* Author: Eddie C. Dost <ecd@skynet.be>
......
......@@ -10,4 +10,5 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_tristate ' AMD7930 Lowlevel Driver' CONFIG_SPARCAUDIO_AMD7930 $CONFIG_SPARCAUDIO
dep_tristate ' CS4231 Lowlevel Driver' CONFIG_SPARCAUDIO_CS4231 $CONFIG_SPARCAUDIO
dep_tristate ' DBRI Lowlevel Driver' CONFIG_SPARCAUDIO_DBRI $CONFIG_SPARCAUDIO
dep_tristate ' Dummy Lowlevel Driver' CONFIG_SPARCAUDIO_DUMMY $CONFIG_SPARCAUDIO
fi
......@@ -16,47 +16,57 @@ O_OBJS :=
M_OBJS :=
ifeq ($(CONFIG_SPARCAUDIO),y)
SBUS_AUDIO=y
M=y
else
ifeq ($(CONFIG_SPARCAUDIO),m)
SBUS_AUDIO_MODULE=y
MM=y
endif
endif
ifeq ($(CONFIG_SPARCAUDIO_AMD7930),y)
SBUS_AUDIO=y
M=y
OX_OBJS += amd7930.o
else
ifeq ($(CONFIG_SPARCAUDIO_AMD7930),m)
SBUS_AUDIO_MODULE=y
MM=y
MX_OBJS += amd7930.o
endif
endif
ifeq ($(CONFIG_SPARCAUDIO_CS4231),y)
SBUS_AUDIO=y
M=y
O_OBJS += cs4231.o
else
ifeq ($(CONFIG_SPARCAUDIO_CS4231),m)
SBUS_AUDIO_MODULE=y
MM=y
M_OBJS += cs4231.o
endif
endif
ifeq ($(CONFIG_SPARCAUDIO_DBRI),y)
SBUS_AUDIO=y
M=y
OX_OBJS += dbri.o
else
ifeq ($(CONFIG_SPARCAUDIO_DBRI),m)
SBUS_AUDIO_MODULE=y
MM=y
MX_OBJS += dbri.o
endif
endif
ifdef SBUS_AUDIO
ifeq ($(CONFIG_SPARCAUDIO_DUMMY),y)
M=y
O_OBJS += dmy.o
else
ifeq ($(CONFIG_SPARCAUDIO_DUMMY),m)
MM=y
M_OBJS += dmy.o
endif
endif
ifdef M
OX_OBJS += audio.o
else
ifdef SBUS_AUDIO_MODULE
ifdef MM
MX_OBJS += audio.o
endif
endif
......
This diff is collapsed.
......@@ -14,6 +14,7 @@
#define _AMD7930_H_
#include <linux/types.h>
#include <linux/version.h>
/* Register interface presented to the CPU by the amd7930. */
struct amd7930
......
This diff is collapsed.
This diff is collapsed.
......@@ -49,10 +49,13 @@ struct cs4231_chip {
volatile __u8 * output_ptr;
volatile unsigned long output_size;
volatile __u32 * output_dma_handle, * output_next_dma_handle;
volatile unsigned long output_dma_size, output_next_dma_size;
/* Current record buffer. */
volatile __u8 * input_ptr;
volatile unsigned long input_size;
volatile __u32 * input_dma_handle, * input_next_dma_handle;
volatile unsigned long input_dma_size, input_next_dma_size;
/* Number of buffers in the pipe. */
volatile unsigned long playing_count;
......
......@@ -51,6 +51,7 @@
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/malloc.h>
#include <linux/version.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
#include <asm/system.h>
......@@ -62,10 +63,11 @@
#include <asm/audioio.h>
#include "dbri.h"
#if defined(DBRI_ISDN) || defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff
#include "../../isdn/hisax/hisax.h"
#include "../../isdn/hisax/isdnl1.h"
#include "../../isdn/hisax/foreign.h"
#endif
/* #define DBRI_DEBUG */
......@@ -106,7 +108,7 @@ static char *cmds[] = {
static struct sparcaudio_driver drivers[MAX_DRIVERS];
static char drv_name[] = "DBRI/audio";
static int num_drivers = 0;
static int num_drivers;
static void * output_callback_arg;
......@@ -180,7 +182,7 @@ static void dbri_detach(struct sparcaudio_driver *drv)
struct dbri *info = (struct dbri *)drv->private;
dbri_reset(drv);
unregister_sparcaudio_driver(drv);
unregister_sparcaudio_driver(drv, 1);
free_irq(info->irq, drv);
sparc_free_io(info->regs, info->regs_size);
kfree(drv->private);
......@@ -660,7 +662,6 @@ void dbri_isdn_init(struct dbri *dbri)
dbri_cmdsend(dbri, n);
}
void dbri_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct sparcaudio_driver *drv = (struct sparcaudio_driver *)dev_id;
......@@ -838,13 +839,6 @@ static int dbri_open(struct inode * inode, struct file * file,
{
struct dbri *dbri = (struct dbri *)drv->private;
#if 0
/* Set the default audio parameters. */
info->rgain = 128;
info->pgain = 200;
info->mgain = 0;
#endif
MOD_INC_USE_COUNT;
return 0;
......@@ -889,6 +883,8 @@ static void dbri_stop_output(struct sparcaudio_driver *drv)
struct dbri *dbri = (struct dbri *)drv->private;
}
static struct sparcaudio_operations dbri_ops = {
dbri_open,
dbri_release,
......@@ -935,19 +931,17 @@ static struct sparcaudio_operations dbri_ops = {
dummy, /* dbri_get_output_muted, */
};
/*
****************************************************************************
************************** ISDN (Hisax) Interface **************************
****************************************************************************
*/
int dbri_get_irqnum(int dev)
{
struct dbri *dbri;
if (dev >= num_drivers) {
if (dev > num_drivers) {
return(0);
}
......@@ -961,7 +955,7 @@ int dbri_get_liu_state(int dev)
{
struct dbri *dbri;
if (dev >= num_drivers) {
if (dev > num_drivers) {
return(0);
}
......@@ -974,7 +968,7 @@ void dbri_liu_init(int dev, void (*callback)(void *), void *callback_arg)
{
struct dbri *dbri;
if (dev >= num_drivers) {
if (dev > num_drivers) {
return;
}
......@@ -992,7 +986,7 @@ void dbri_liu_activate(int dev, int priority)
struct dbri *dbri;
int n, val;
if (dev >= num_drivers) {
if (dev > num_drivers) {
return;
}
......@@ -1014,7 +1008,7 @@ void dbri_liu_deactivate(int dev)
{
struct dbri *dbri;
if (dev >= num_drivers) {
if (dev > num_drivers) {
return;
}
......@@ -1030,7 +1024,7 @@ void dbri_dxmit(int dev, __u8 *buffer, unsigned int count,
struct dbri *dbri;
int n, val;
if (dev >= num_drivers) {
if (dev > num_drivers) {
return;
}
......@@ -1068,7 +1062,7 @@ void dbri_drecv(int dev, __u8 *buffer, unsigned int size,
struct dbri *dbri;
int n, val;
if (dev >= num_drivers) {
if (dev > num_drivers) {
return;
}
......@@ -1108,7 +1102,7 @@ int dbri_bopen(int dev, unsigned int chan,
struct dbri *dbri;
int n, val;
if (dev >= num_drivers || chan > 1) {
if (dev > num_drivers || chan > 1) {
return -1;
}
......@@ -1158,7 +1152,7 @@ void dbri_bclose(int dev, unsigned int chan)
{
struct dbri *dbri;
if (dev >= num_drivers || chan > 1) {
if (dev > num_drivers || chan > 1) {
return;
}
......@@ -1176,7 +1170,7 @@ void dbri_bxmit(int dev, unsigned int chan,
struct dbri *dbri;
int n, val;
if (dev >= num_drivers || chan > 1) {
if (dev > num_drivers || chan > 1) {
return;
}
......@@ -1215,7 +1209,7 @@ void dbri_brecv(int dev, unsigned int chan,
struct dbri *dbri;
int n, val;
if (dev >= num_drivers || chan > 1) {
if (dev > num_drivers || chan > 1) {
return;
}
......@@ -1249,6 +1243,7 @@ void dbri_brecv(int dev, unsigned int chan,
dbri->B[chan].input_callback_arg = callback_arg;
}
#if defined(DBRI_ISDN) || defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff
struct foreign_interface dbri_foreign_interface = {
dbri_get_irqnum,
dbri_get_liu_state,
......@@ -1263,6 +1258,7 @@ struct foreign_interface dbri_foreign_interface = {
dbri_brecv
};
EXPORT_SYMBOL(dbri_foreign_interface);
#endif
/*
****************************************************************************
......@@ -1270,7 +1266,6 @@ EXPORT_SYMBOL(dbri_foreign_interface);
****************************************************************************
*/
static int dbri_attach(struct sparcaudio_driver *drv,
struct linux_sbus_device *sdev)
{
......@@ -1319,7 +1314,7 @@ static int dbri_attach(struct sparcaudio_driver *drv,
}
/* Register ourselves with the midlevel audio driver. */
err = register_sparcaudio_driver(drv);
err = register_sparcaudio_driver(drv,1);
if (err) {
printk(KERN_ERR "DBRI: unable to register audio\n");
free_irq(dbri->irq, drv);
......@@ -1397,7 +1392,7 @@ void cleanup_module(void)
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* Local Variables:
* c-indent-level: 8
* c-brace-imaginary-offset: 0
* c-brace-offset: -8
......
......@@ -1758,7 +1758,7 @@ int init_module(void) {
void cleanup_module( void)
{
struct gendisk * prev_sdgd;
struct gendisk ** prev_sdgd_link;
struct gendisk * sdgd;
int i;
int removed = 0;
......@@ -1778,16 +1778,20 @@ void cleanup_module( void)
scsi_init_free((char *) sd_hardsizes, sd_template.dev_max * sizeof(int));
scsi_init_free((char *) sd,
(sd_template.dev_max << 4) * sizeof(struct hd_struct));
/*
* Now remove sd_gendisks from the linked list
*/
for (sdgd = gendisk_head; sdgd; sdgd = sdgd->next)
{
if (sdgd->next >= sd_gendisks && sdgd->next <= LAST_SD_GENDISK.max_nr)
removed++, sdgd->next = sdgd->next->next;
else sdgd = sdgd->next;
prev_sdgd_link = &gendisk_head;
while ((sdgd = *prev_sdgd_link) != NULL) {
if (sdgd >= sd_gendisks && sdgd <= &LAST_SD_GENDISK) {
removed++;
*prev_sdgd_link = sdgd->next;
continue;
}
prev_sdgd_link = &sdgd->next;
}
if (removed != N_USED_SD_MAJORS)
printk("%s %d sd_gendisks in disk chain",
removed > N_USED_SD_MAJORS ? "total" : "just", removed);
......
/* $Id: openpromfs.c,v 1.31 1998/08/26 10:32:19 davem Exp $
/* $Id: openpromfs.c,v 1.32 1998/11/18 06:15:20 davem Exp $
* openpromfs.c: /proc/openprom handling routines
*
* Copyright (C) 1996-1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
......@@ -822,6 +822,10 @@ static int openpromfs_lookup(struct inode * dir, struct dentry *dentry)
inode->i_rdev = d->rdev;
break;
}
inode->i_gid = 0;
inode->i_uid = 0;
d_add(dentry, inode);
return 0;
}
......
......@@ -25,7 +25,7 @@
{ LONG_MAX, LONG_MAX }, \
{ LONG_MAX, LONG_MAX }, \
{ LONG_MAX, LONG_MAX }, \
{ _STK_LIM, _STK_LIM }, \
{ _STK_LIM, LONG_MAX }, \
{ 0, LONG_MAX }, \
{ LONG_MAX, LONG_MAX }, \
{ MAX_TASKS_PER_USER, MAX_TASKS_PER_USER }, \
......
......@@ -88,6 +88,7 @@ typedef struct audio_info {
#define AUDIO_ENCODING_ULAW (1) /* u-law encoding */
#define AUDIO_ENCODING_ALAW (2) /* A-law encoding */
#define AUDIO_ENCODING_LINEAR (3) /* Linear PCM encoding */
#define AUDIO_ENCODING_FLOAT (4) /* IEEE float (-1. <-> +1.) */
#define AUDIO_ENCODING_DVI (104) /* DVI ADPCM */
#define AUDIO_ENCODING_LINEAR8 (105) /* 8 bit UNSIGNED */
#define AUDIO_ENCODING_LINEARLE (106) /* Linear PCM LE encoding */
......@@ -139,8 +140,7 @@ typedef struct audio_info {
#define AUDIO_LINE_IN 0x02 /* input from line in */
#define AUDIO_CD 0x04 /* input from on-board CD inputs */
#define AUDIO_INTERNAL_CD_IN AUDIO_CD /* input from internal CDROM */
/* Supposedly an undocumented feature of the 4231 */
#define AUDIO_ANALOG_LOOPBACK 0x40
#define AUDIO_ANALOG_LOOPBACK 0x40 /* input from output */
/*
......@@ -227,22 +227,10 @@ typedef struct audio_device {
* if the hardware supports this. The argument is TRUE to set loopback,
* FALSE to reset to normal operation. If the hardware does not support
* internal loopback, the ioctl should fail with EINVAL.
* Causes ADC data to be digitally mixed in and sent to the DAC.
*/
#define AUDIO_DIAG_LOOPBACK _IOW('A', 101, int)
#ifdef notneeded
/*
* Structure sent up as a M_PROTO message on trace streams
*/
typedef struct audtrace_hdr audtrace_hdr_t;
struct audtrace_hdr {
unsigned int seq; /* Sequence number (per-aud_stream) */
int type; /* device-dependent */
struct timeval timestamp;
char _f[8]; /* filler */
};
#endif
/*
* Linux kernel internal implementation.
*/
......@@ -257,12 +245,31 @@ struct audtrace_hdr {
#define SDF_OPEN_WRITE 0x00000001
#define SDF_OPEN_READ 0x00000002
struct sparcaudio_ringbuffer
{
__u8 *rb_start, *rb_end; /* start, end of this memory buffer */
__u8 *rb_in, *rb_out; /* input, output pointers */
int rb_fragsize; /* size of an audio frag */
int rb_numfrags; /* number of frags */
int rb_count, rb_hiwat, rb_lowat; /* bytes in use, hi/lo wat points */
int rb_bufsize; /* total size of buffer */
};
struct sparcaudio_driver
{
const char * name;
struct sparcaudio_operations *ops;
void *private;
unsigned long flags;
struct strevent *sd_siglist;
/* duplex: 0=simplex, 1=duplex, 2=loop */
int sd_sigflags, duplex;
/* Which audio device are we? */
int index;
/* This device */
struct linux_sbus_device *dev;
......@@ -273,32 +280,37 @@ struct sparcaudio_driver
/* Task queue for this driver's bottom half. */
struct tq_struct tqueue;
/* Start of ring buffer support */
__u8 *input_buffer, *output_buffer;
/* Support for a circular queue of output buffers. */
__u8 **output_buffers;
size_t *output_sizes, output_size;
int num_output_buffers, output_front, output_rear;
int output_count, output_active, playing_count;
size_t *output_sizes, output_size, output_buffer_size;
int num_output_buffers, output_front, output_rear, output_offset;
int output_count, output_active, playing_count, output_eof;
struct wait_queue *output_write_wait, *output_drain_wait;
char *output_notify;
/* Support for a circular queue of input buffers. */
__u8 **input_buffers;
int input_offset;
int num_input_buffers, input_front, input_rear;
size_t *input_sizes, input_size, input_buffer_size;
int num_input_buffers, input_front, input_rear, input_offset;
int input_count, input_active, recording_count;
struct wait_queue *input_read_wait;
/* Hack to make it look like we support variable size buffers. */
int buffer_size;
};
struct sparcaudio_operations
{
int (*open)(struct inode *, struct file *, struct sparcaudio_driver *);
void (*release)(struct inode *, struct file *, struct
sparcaudio_driver *);
int (*ioctl)(struct inode *, struct file *, unsigned int,
unsigned long, struct sparcaudio_driver *);
void (*release)(struct inode *, struct file *, struct sparcaudio_driver *);
int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long,
struct sparcaudio_driver *);
/* Ask driver to begin playing a buffer. */
void (*start_output)(struct sparcaudio_driver *, __u8 *,
unsigned long);
void (*start_output)(struct sparcaudio_driver *, __u8 *, unsigned long);
/* Ask driver to stop playing a buffer. */
void (*stop_output)(struct sparcaudio_driver *);
......@@ -382,35 +394,125 @@ struct sparcaudio_operations
/* Get and set output mute */
int (*set_output_muted)(struct sparcaudio_driver *, int);
int (*get_output_muted)(struct sparcaudio_driver *);
/* Get and set output pause */
int (*set_output_pause)(struct sparcaudio_driver *, int);
int (*get_output_pause)(struct sparcaudio_driver *);
/* Get and set input pause */
int (*set_input_pause)(struct sparcaudio_driver *, int);
int (*get_input_pause)(struct sparcaudio_driver *);
/* Get and set output samples */
int (*set_output_samples)(struct sparcaudio_driver *, int);
int (*get_output_samples)(struct sparcaudio_driver *);
/* Get and set input samples */
int (*set_input_samples)(struct sparcaudio_driver *, int);
int (*get_input_samples)(struct sparcaudio_driver *);
/* Get and set output error */
int (*set_output_error)(struct sparcaudio_driver *, int);
int (*get_output_error)(struct sparcaudio_driver *);
/* Get and set input error */
int (*set_input_error)(struct sparcaudio_driver *, int);
int (*get_input_error)(struct sparcaudio_driver *);
/* Get supported encodings */
int (*get_formats)(struct sparcaudio_driver *);
};
extern int register_sparcaudio_driver(struct sparcaudio_driver *);
extern int unregister_sparcaudio_driver(struct sparcaudio_driver *);
extern int register_sparcaudio_driver(struct sparcaudio_driver *, int);
extern int unregister_sparcaudio_driver(struct sparcaudio_driver *, int);
extern void sparcaudio_output_done(struct sparcaudio_driver *, int);
extern void sparcaudio_input_done(struct sparcaudio_driver *);
extern void sparcaudio_input_done(struct sparcaudio_driver *, int);
extern int sparcaudio_init(void);
extern int amd7930_init(void);
extern int cs4231_init(void);
#endif
/* Mixer helper ioctls */
#define right(a) (((a >> 8) & 0xff) % 101)
#define left(a) ((a & 0xff) % 101)
/* Macros to convert between mixer stereo volumes and gain (mono) */
#define s_to_m(a) (((((a) >> 8) & 0x7f) + ((a) & 0x7f)) / 2)
#define m_to_s(a) (((a) << 8) + (a))
#define s_to_m(a) ((((left(a) + right(a)) * 255) / 200) % 256)
#define m_to_s(a) ((a * 100 / 255) + ((a * 100 / 255) << 8))
/* convert mixer stereo volume to balance */
#define s_to_b(a) (AUDIO_RIGHT_BALANCE * ((((a) >> 8) & 0xff) / (((((a) >> 8) & 0xff) + ((a) & 0xff)) / 2)))
#define s_to_b(a) (s_to_g(a) == 0) ? 32 : ((left(a) * AUDIO_RIGHT_BALANCE / (left(a) + right(a))))
/* convert mixer stereo volume to audio gain */
#define s_to_g(a) (((((a) >> 8) & 0xff) + ((a) & 0xff)) / 2)
#define s_to_g(a) ((((right(a) + left(a)) * 255) / 200) % 256)
/* convert gain a and balance b to mixer volume */
#define b_to_s(a,b) ((a * (b / AUDIO_RIGHT_BALANCE) << 8) + (a * (1 - (b / AUDIO_RIGHT_BALANCE))))
#define b_to_s(a,b) (((((b * a * 200) / (AUDIO_RIGHT_BALANCE * 255)) % 100) << 8) + ((((AUDIO_RIGHT_BALANCE - b) * a * 200) / (AUDIO_RIGHT_BALANCE * 255)) % 100))
/* Device minor numbers */
#define SPARCAUDIO_MIXER_MINOR 0
#define SPARCAUDIO_DSP16_MINOR 1
/* No sequencer (1) */
/* No midi (2) */
#define SPARCAUDIO_DSP_MINOR 3
#define SPARCAUDIO_AUDIO_MINOR 4
#define SPARCAUDIO_AUDIOCTL_MINOR 5
#define SPARCAUDIO_DSP16_MINOR 5
#define SPARCAUDIO_STATUS_MINOR 6
#define SPARCAUDIO_AUDIOCTL_MINOR 7
/* No sequencer l2 (8) */
/* No sound processor (9) */
/* allocate 2^SPARCAUDIO_DEVICE_SHIFT minors per audio device */
#define SPARCAUDIO_DEVICE_SHIFT 4
/* With the coming of dummy devices this should perhaps be as high as 5? */
#define SPARCAUDIO_MAX_DEVICES 3
/* Streams crap for realaudio */
typedef
struct strevent {
struct strevent *se_next; /* next event for this stream or NULL*/
struct strevent *se_prev; /* previous event for this stream or last
* event if this is the first one*/
pid_t se_pid; /* process to be signaled */
short se_evs; /* events wanted */
} strevent_t;
typedef
struct stdata
{
struct stdata *sd_next ; /* all stdatas are linked together */
struct stdata *sd_prev ;
struct strevent *sd_siglist; /* processes to be sent SIGPOLL */
int sd_sigflags; /* logical OR of all siglist events */
} stdata_t;
#define I_NREAD _IOR('S',01, int)
#define I_NREAD_SOLARIS (('S'<<8)|1)
#define I_FLUSH _IO('S',05)
#define I_FLUSH_SOLARIS (('S'<<8)|5)
#define FLUSHR 1 /* flush read queue */
#define FLUSHW 2 /* flush write queue */
#define FLUSHRW 3 /* flush both queues */
#define I_SETSIG _IO('S',011)
#define I_SETSIG_SOLARIS (('S'<<8)|11)
#define S_INPUT 0x01
#define S_HIPRI 0x02
#define S_OUTPUT 0x04
#define S_MSG 0x08
#define S_ERROR 0x0010
#define S_HANGUP 0x0020
#define S_RDNORM 0x0040
#define S_WRNORM S_OUTPUT
#define S_RDBAND 0x0080
#define S_WRBAND 0x0100
#define S_BANDURG 0x0200
#define S_ALL 0x03FF
#define I_GETSIG _IOR('S',012,int)
#define I_GETSIG_SOLARIS (('S'<<8)|12)
#endif
......@@ -88,6 +88,7 @@ typedef struct audio_info {
#define AUDIO_ENCODING_ULAW (1) /* u-law encoding */
#define AUDIO_ENCODING_ALAW (2) /* A-law encoding */
#define AUDIO_ENCODING_LINEAR (3) /* Linear PCM encoding */
#define AUDIO_ENCODING_FLOAT (4) /* IEEE float (-1. <-> +1.) */
#define AUDIO_ENCODING_DVI (104) /* DVI ADPCM */
#define AUDIO_ENCODING_LINEAR8 (105) /* 8 bit UNSIGNED */
#define AUDIO_ENCODING_LINEARLE (106) /* Linear PCM LE encoding */
......@@ -139,8 +140,7 @@ typedef struct audio_info {
#define AUDIO_LINE_IN 0x02 /* input from line in */
#define AUDIO_CD 0x04 /* input from on-board CD inputs */
#define AUDIO_INTERNAL_CD_IN AUDIO_CD /* input from internal CDROM */
/* Supposedly an undocumented feature of the 4231 */
#define AUDIO_ANALOG_LOOPBACK 0x40
#define AUDIO_ANALOG_LOOPBACK 0x40 /* input from output */
/*
......@@ -227,22 +227,10 @@ typedef struct audio_device {
* if the hardware supports this. The argument is TRUE to set loopback,
* FALSE to reset to normal operation. If the hardware does not support
* internal loopback, the ioctl should fail with EINVAL.
* Causes ADC data to be digitally mixed in and sent to the DAC.
*/
#define AUDIO_DIAG_LOOPBACK _IOW('A', 101, int)
#ifdef notneeded
/*
* Structure sent up as a M_PROTO message on trace streams
*/
typedef struct audtrace_hdr audtrace_hdr_t;
struct audtrace_hdr {
unsigned int seq; /* Sequence number (per-aud_stream) */
int type; /* device-dependent */
struct timeval timestamp;
char _f[8]; /* filler */
};
#endif
/*
* Linux kernel internal implementation.
*/
......@@ -257,12 +245,31 @@ struct audtrace_hdr {
#define SDF_OPEN_WRITE 0x00000001
#define SDF_OPEN_READ 0x00000002
struct sparcaudio_ringbuffer
{
__u8 *rb_start, *rb_end; /* start, end of this memory buffer */
__u8 *rb_in, *rb_out; /* input, output pointers */
int rb_fragsize; /* size of an audio frag */
int rb_numfrags; /* number of frags */
int rb_count, rb_hiwat, rb_lowat; /* bytes in use, hi/lo wat points */
int rb_bufsize; /* total size of buffer */
};
struct sparcaudio_driver
{
const char * name;
struct sparcaudio_operations *ops;
void *private;
unsigned long flags;
struct strevent *sd_siglist;
/* duplex: 0=simplex, 1=duplex, 2=loop */
int sd_sigflags, duplex;
/* Which audio device are we? */
int index;
/* This device */
struct linux_sbus_device *dev;
......@@ -273,32 +280,37 @@ struct sparcaudio_driver
/* Task queue for this driver's bottom half. */
struct tq_struct tqueue;
/* Start of ring buffer support */
__u8 *input_buffer, *output_buffer;
/* Support for a circular queue of output buffers. */
__u8 **output_buffers;
size_t *output_sizes, output_size;
int num_output_buffers, output_front, output_rear;
int output_count, output_active, playing_count;
size_t *output_sizes, output_size, output_buffer_size;
int num_output_buffers, output_front, output_rear, output_offset;
int output_count, output_active, playing_count, output_eof;
struct wait_queue *output_write_wait, *output_drain_wait;
char *output_notify;
/* Support for a circular queue of input buffers. */
__u8 **input_buffers;
int input_offset;
int num_input_buffers, input_front, input_rear;
size_t *input_sizes, input_size, input_buffer_size;
int num_input_buffers, input_front, input_rear, input_offset;
int input_count, input_active, recording_count;
struct wait_queue *input_read_wait;
/* Hack to make it look like we support variable size buffers. */
int buffer_size;
};
struct sparcaudio_operations
{
int (*open)(struct inode *, struct file *, struct sparcaudio_driver *);
void (*release)(struct inode *, struct file *,
void (*release)(struct inode *, struct file *, struct sparcaudio_driver *);
int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long,
struct sparcaudio_driver *);
int (*ioctl)(struct inode *, struct file *, unsigned int,
unsigned long, struct sparcaudio_driver *);
/* Ask driver to begin playing a buffer. */
void (*start_output)(struct sparcaudio_driver *, __u8 *,
unsigned long);
void (*start_output)(struct sparcaudio_driver *, __u8 *, unsigned long);
/* Ask driver to stop playing a buffer. */
void (*stop_output)(struct sparcaudio_driver *);
......@@ -382,35 +394,125 @@ struct sparcaudio_operations
/* Get and set output mute */
int (*set_output_muted)(struct sparcaudio_driver *, int);
int (*get_output_muted)(struct sparcaudio_driver *);
/* Get and set output pause */
int (*set_output_pause)(struct sparcaudio_driver *, int);
int (*get_output_pause)(struct sparcaudio_driver *);
/* Get and set input pause */
int (*set_input_pause)(struct sparcaudio_driver *, int);
int (*get_input_pause)(struct sparcaudio_driver *);
/* Get and set output samples */
int (*set_output_samples)(struct sparcaudio_driver *, int);
int (*get_output_samples)(struct sparcaudio_driver *);
/* Get and set input samples */
int (*set_input_samples)(struct sparcaudio_driver *, int);
int (*get_input_samples)(struct sparcaudio_driver *);
/* Get and set output error */
int (*set_output_error)(struct sparcaudio_driver *, int);
int (*get_output_error)(struct sparcaudio_driver *);
/* Get and set input error */
int (*set_input_error)(struct sparcaudio_driver *, int);
int (*get_input_error)(struct sparcaudio_driver *);
/* Get supported encodings */
int (*get_formats)(struct sparcaudio_driver *);
};
extern int register_sparcaudio_driver(struct sparcaudio_driver *);
extern int unregister_sparcaudio_driver(struct sparcaudio_driver *);
extern int register_sparcaudio_driver(struct sparcaudio_driver *, int);
extern int unregister_sparcaudio_driver(struct sparcaudio_driver *, int);
extern void sparcaudio_output_done(struct sparcaudio_driver *, int);
extern void sparcaudio_input_done(struct sparcaudio_driver *);
extern void sparcaudio_input_done(struct sparcaudio_driver *, int);
extern int sparcaudio_init(void);
extern int amd7930_init(void);
extern int cs4231_init(void);
#endif
/* Mixer helper ioctls */
#define right(a) (((a >> 8) & 0xff) % 101)
#define left(a) ((a & 0xff) % 101)
/* Macros to convert between mixer stereo volumes and gain (mono) */
#define s_to_m(a) (((((a) >> 8) & 0x7f) + ((a) & 0x7f)) / 2)
#define m_to_s(a) (((a) << 8) + (a))
#define s_to_m(a) ((((left(a) + right(a)) * 255) / 200) % 256)
#define m_to_s(a) ((a * 100 / 255) + ((a * 100 / 255) << 8))
/* convert mixer stereo volume to balance */
#define s_to_b(a) (AUDIO_RIGHT_BALANCE * ((((a) >> 8) & 0xff) / (((((a) >> 8) & 0xff) + ((a) & 0xff)) / 2)))
#define s_to_b(a) (s_to_g(a) == 0) ? 32 : ((left(a) * AUDIO_RIGHT_BALANCE / (left(a) + right(a))))
/* convert mixer stereo volume to audio gain */
#define s_to_g(a) (((((a) >> 8) & 0xff) + ((a) & 0xff)) / 2)
#define s_to_g(a) ((((right(a) + left(a)) * 255) / 200) % 256)
/* convert gain a and balance b to mixer volume */
#define b_to_s(a,b) ((a * (b / AUDIO_RIGHT_BALANCE) << 8) + (a * (1 - (b / AUDIO_RIGHT_BALANCE))))
#define b_to_s(a,b) (((((b * a * 200) / (AUDIO_RIGHT_BALANCE * 255)) % 100) << 8) + ((((AUDIO_RIGHT_BALANCE - b) * a * 200) / (AUDIO_RIGHT_BALANCE * 255)) % 100))
/* Device minor numbers */
#define SPARCAUDIO_MIXER_MINOR 0
#define SPARCAUDIO_DSP16_MINOR 1
/* No sequencer (1) */
/* No midi (2) */
#define SPARCAUDIO_DSP_MINOR 3
#define SPARCAUDIO_AUDIO_MINOR 4
#define SPARCAUDIO_AUDIOCTL_MINOR 5
#define SPARCAUDIO_DSP16_MINOR 5
#define SPARCAUDIO_STATUS_MINOR 6
#define SPARCAUDIO_AUDIOCTL_MINOR 7
/* No sequencer l2 (8) */
/* No sound processor (9) */
/* allocate 2^SPARCAUDIO_DEVICE_SHIFT minors per audio device */
#define SPARCAUDIO_DEVICE_SHIFT 4
/* With the coming of dummy devices this should perhaps be as high as 5? */
#define SPARCAUDIO_MAX_DEVICES 3
/* Streams crap for realaudio */
typedef
struct strevent {
struct strevent *se_next; /* next event for this stream or NULL*/
struct strevent *se_prev; /* previous event for this stream or last
* event if this is the first one*/
pid_t se_pid; /* process to be signaled */
short se_evs; /* events wanted */
} strevent_t;
typedef
struct stdata
{
struct stdata *sd_next ; /* all stdatas are linked together */
struct stdata *sd_prev ;
struct strevent *sd_siglist; /* processes to be sent SIGPOLL */
int sd_sigflags; /* logical OR of all siglist events */
} stdata_t;
#define I_NREAD _IOR('S',01, int)
#define I_NREAD_SOLARIS (('S'<<8)|1)
#define I_FLUSH _IO('S',05)
#define I_FLUSH_SOLARIS (('S'<<8)|5)
#define FLUSHR 1 /* flush read queue */
#define FLUSHW 2 /* flush write queue */
#define FLUSHRW 3 /* flush both queues */
#define I_SETSIG _IO('S',011)
#define I_SETSIG_SOLARIS (('S'<<8)|11)
#define S_INPUT 0x01
#define S_HIPRI 0x02
#define S_OUTPUT 0x04
#define S_MSG 0x08
#define S_ERROR 0x0010
#define S_HANGUP 0x0020
#define S_RDNORM 0x0040
#define S_WRNORM S_OUTPUT
#define S_RDBAND 0x0080
#define S_WRBAND 0x0100
#define S_BANDURG 0x0200
#define S_ALL 0x03FF
#define I_GETSIG _IOR('S',012,int)
#define I_GETSIG_SOLARIS (('S'<<8)|12)
#endif
......@@ -117,7 +117,7 @@ typedef struct page {
unsigned long offset;
struct page *next_hash;
atomic_t count;
unsigned int age;
unsigned int unused;
unsigned long flags; /* atomic flags, some possibly updated asynchronously */
struct wait_queue *wait;
struct page **pprev_hash;
......@@ -226,8 +226,6 @@ typedef struct page {
* For choosing which pages to swap out, inode pages carry a
* page->referenced bit, which is set any time the system accesses
* that page through the (inode,offset) hash table.
* There is also the page->age counter, which implements a linear
* decay (why not an exponential decay?), see swapctl.h.
*/
extern mem_map_t * mem_map;
......
......@@ -83,7 +83,6 @@ static inline void remove_page_from_hash_queue(struct page * page)
static inline void __add_page_to_hash_queue(struct page * page, struct page **p)
{
page_cache_size++;
page->age = PAGE_AGE_VALUE;
if((page->next_hash = *p) != NULL)
(*p)->pprev_hash = &page->next_hash;
*p = page;
......
......@@ -94,32 +94,6 @@ static inline int AGE_CLUSTER_SIZE(int resources)
return n;
}
static inline void touch_page(struct page *page)
{
if (page->age < (MAX_PAGE_AGE - PAGE_ADVANCE))
page->age += PAGE_ADVANCE;
else
page->age = MAX_PAGE_AGE;
}
static inline void age_page(struct page *page)
{
if (page->age > PAGE_DECLINE)
page->age -= PAGE_DECLINE;
else
page->age = 0;
}
static inline int age_of(unsigned long addr)
{
return mem_map[MAP_NR(addr)].age;
}
static inline void set_page_new(unsigned long addr)
{
mem_map[MAP_NR(addr)].age = PAGE_INITIAL_AGE;
}
#endif /* __KERNEL */
#endif /* _LINUX_SWAPCTL_H */
......@@ -273,6 +273,7 @@ static int do_acct_process(long exitcode, struct file *file)
struct acct ac;
mm_segment_t fs;
unsigned long vsize;
struct inode *inode;
/*
* First check to see if there is enough free_space to continue
......@@ -336,8 +337,11 @@ static int do_acct_process(long exitcode, struct file *file)
*/
fs = get_fs();
set_fs(KERNEL_DS);
inode = file->f_dentry->d_inode;
down(&inode->i_sem);
file->f_op->write(file, (char *)&ac,
sizeof(struct acct), &file->f_pos);
up(&inode->i_sem);
set_fs(fs);
fput(file);
return 0;
......
......@@ -273,9 +273,9 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
goto out_nolock;
/* The null signal is a permissions and process existance probe.
No signal is actually delivered. */
No signal is actually delivered. Same goes for zombies. */
ret = 0;
if (!sig)
if (!sig || !t->sig)
goto out_nolock;
spin_lock_irqsave(&t->sigmask_lock, flags);
......
......@@ -290,10 +290,9 @@ int vsprintf(char *buf, const char *fmt, va_list args)
if (qualifier == 'l')
num = va_arg(args, unsigned long);
else if (qualifier == 'h') {
num = (unsigned short) va_arg(args, int);
if (flags & SIGN)
num = va_arg(args, short);
else
num = va_arg(args, unsigned short);
num = (short) num;
} else if (flags & SIGN)
num = va_arg(args, int);
else
......
......@@ -172,10 +172,8 @@ static inline int shrink_one_page(struct page *page, int gfp_mask)
delete_from_swap_cache(page);
return 1;
}
if (test_and_clear_bit(PG_referenced, &page->flags)) {
touch_page(page);
if (test_and_clear_bit(PG_referenced, &page->flags))
break;
}
if (pgcache_under_min())
break;
remove_inode_page(page);
......@@ -209,8 +207,8 @@ int shrink_mmap(int priority, int gfp_mask)
struct page * page;
int count_max, count_min;
count_max = (limit<<2) >> (priority>>1);
count_min = (limit<<2) >> (priority);
count_max = (limit<<1) >> (priority>>1);
count_min = (limit<<1) >> (priority);
page = mem_map + clock;
do {
......
......@@ -231,7 +231,6 @@ do { unsigned long size = 1 << high; \
map += size; \
} \
atomic_set(&map->count, 1); \
map->age = PAGE_INITIAL_AGE; \
} while (0)
unsigned long __get_free_pages(int gfp_mask, unsigned long order)
......
/* linux/net/inet/arp.c
*
* Version: $Id: arp.c,v 1.74 1998/11/01 22:15:06 davem Exp $
* Version: $Id: arp.c,v 1.75 1998/11/16 04:51:56 davem Exp $
*
* Copyright (C) 1994 by Florian La Roche
*
......
......@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
* Version: $Id: tcp_input.c,v 1.140 1998/11/12 06:45:15 davem Exp $
* Version: $Id: tcp_input.c,v 1.141 1998/11/18 02:12:07 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
......@@ -1978,8 +1978,27 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
int queued = 0;
/* state == CLOSED, hash lookup always fails, so no worries. -DaveM */
switch (sk->state) {
case TCP_CLOSE:
/* When state == CLOSED, hash lookup always fails.
*
* But, there is a back door, the backlog queue.
* If we have a sequence of packets in the backlog
* during __release_sock() which have a sequence such
* that:
* packet X causes entry to TCP_CLOSE state
* ...
* packet X + N has FIN bit set
*
* We report a (luckily) harmless error in this case.
* The issue is that backlog queue processing bypasses
* any hash lookups (we know which socket packets are for).
* The correct behavior here is what 2.0.x did, since
* a TCP_CLOSE socket does not exist. Drop the frame
* and send a RST back to the other end.
*/
return 1;
case TCP_LISTEN:
/* These use the socket TOS..
* might want to be the received TOS
......
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