Commit 9fe6314a authored by Linus Torvalds's avatar Linus Torvalds

Import 1.3.62

parent d2c53d83
VERSION = 1
PATCHLEVEL = 3
SUBLEVEL = 61
SUBLEVEL = 62
ARCH = i386
......
......@@ -45,8 +45,10 @@ CONFIG_ST506=y
CONFIG_BLK_DEV_IDE=y
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_RZ1000 is not set
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_TRITON is not set
# CONFIG_IDE_CHIPSETS is not set
# CONFIG_BLK_DEV_XD is not set
#
......@@ -164,6 +166,7 @@ CONFIG_MSDOS_FS=y
# CONFIG_UMSDOS_FS is not set
CONFIG_PROC_FS=y
CONFIG_NFS_FS=y
# CONFIG_ROOT_NFS is not set
# CONFIG_SMB_FS is not set
CONFIG_ISO9660_FS=y
# CONFIG_HPFS_FS is not set
......
......@@ -128,26 +128,12 @@ entInt:
/* set up the arguments to the C interrupt handler */
lda $27,do_entInt
jsr $26,($27),do_entInt
/* ok, check if we need to do software interrupts */
1: lda $0,intr_count
/* ok, return */
lda $0,intr_count
ldq $1,0($0)
subq $1,1,$1
bne $1,2f /* interrupt within interrupt: return now */
lda $2,bh_active
ldq $3,0($2)
lda $2,bh_mask
ldq $2,0($2)
and $2,$3,$2
bne $2,3f
stq $1,0($0)
br $31,ret_from_sys_call
.align 3
2: stq $1,0($0)
br $31,restore_all
.align 3
3: lda $27,do_bottom_half
jsr $26,($27),do_bottom_half
br $31,1b
.end entInt
.align 3
......@@ -204,7 +190,7 @@ kernel_clone:
lda $27,sys_clone
jsr $26,($27),sys_clone
stq $0,0($30)
br ret_from_sys_call
br $31,ret_from_sys_call
.end kernel_clone
/*
......@@ -502,10 +488,23 @@ entSys:
blt $0,syscall_error /* the call failed */
stq $0,0($30)
stq $31,72($30) /* a3=0 => no error */
.align 3
ret_from_sys_call:
ldq $0,SP_OFF($30)
cmovne $26,0,$19 /* $19 = 0 => non-restartable */
/* check bottom half interrupts */
lda $0,intr_count
ldq $1,0($0)
bne $1,ret_from_handle_bh
lda $2,bh_active
ldq $3,0($2)
lda $2,bh_mask
ldq $4,0($2)
addq $1,1,$1
and $3,$4,$2
bne $2,handle_bottom_half
ret_from_handle_bh:
ldq $0,SP_OFF($30)
and $0,8,$0
beq $0,restore_all
ret_from_reschedule:
......@@ -525,6 +524,25 @@ restore_all:
RESTORE_ALL
rti
.align 3
handle_bottom_half:
/*
* We're called with $0 containing the address of
* 'intr_count' and $1 containing 'intr_count+1'
*/
stq $1,0($0) /* intr_count = 1 */
subq $30,16,$30
stq $19,0($30) /* save syscall nr */
stq $20,8($30) /* and error indication (a3) */
lda $27,do_bottom_half
jsr $26,($27),do_bottom_half
lda $0,intr_count
ldq $19,0($30)
ldq $20,8($30)
addq $30,16,$30
stq $31,0($0) /* intr_count = 0 */
br $31,ret_from_handle_bh
.align 3
syscall_error:
/*
......
......@@ -79,13 +79,18 @@
* Try to eliminate byteorder assumptions.
* Use atapi_cdrom_subchnl struct definition.
* Add STANDARD_ATAPI compilation option.
* 3.07 Jan 29, 1996 -- More twiddling for broken drives: Sony 55D,
* Vertos 300.
* Add NO_DOOR_LOCKING configuration option.
* Handle drive_cmd requests w/NULL args (for hdparm -t).
* Work around sporadic Sony55e audio play problem.
*
* NOTE: Direct audio reads will only work on some types of drive.
* So far, i've received reports of success for Sony and Toshiba drives.
*
* ATAPI cd-rom driver. To be used with ide.c.
*
* Copyright (C) 1994, 1995 scott snyder <snyder@fnald0.fnal.gov>
* Copyright (C) 1994, 1995, 1996 scott snyder <snyder@fnald0.fnal.gov>
* May be copied or modified under the terms of the GNU General Public License
* (../../COPYING).
*/
......@@ -130,6 +135,14 @@
#endif
/* Turning this on will disable the door-locking functionality.
This is apparently needed for supermount. */
#ifndef NO_DOOR_LOCKING
#define NO_DOOR_LOCKING 0
#endif
/************************************************************************/
#define SECTOR_SIZE 512
......@@ -1420,6 +1433,43 @@ int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc)
}
/****************************************************************************
* drive_cmd handling.
*
* Most of the functions accessed via drive_cmd are not valid for ATAPI
* devices. Only attempt to execute those which actually should be valid.
*/
static
void cdrom_do_drive_cmd (ide_drive_t *drive)
{
struct request *rq = HWGROUP(drive)->rq;
byte *args = rq->buffer;
if (args)
{
#if 0 /* This bit isn't done yet... */
if (args[0] == WIN_SETFEATURES &&
(args[2] == 0x66 || args[2] == 0xcc || args[2] == 0x02 ||
args[2] == 0xdd || args[2] == 0x5d))
{
OUT_BYTE (args[2], io_base + IDE_FEATURE_OFFSET);
<send cmd>
}
else
#endif
{
printk ("%s: Unsupported drive command %02x %02x %02x\n",
drive->name, args[0], args[1], args[2]);
rq->errors = 1;
}
}
cdrom_end_request (1, drive);
}
/****************************************************************************
* cdrom driver request routine.
......@@ -1439,6 +1489,9 @@ void ide_do_rw_cdrom (ide_drive_t *drive, unsigned long block)
return;
}
else if (rq -> cmd == IDE_DRIVE_CMD)
cdrom_do_drive_cmd (drive);
else if (rq -> cmd != READ)
{
printk ("ide-cd: bad cmd %d\n", rq -> cmd);
......@@ -1890,10 +1943,8 @@ cdrom_play_lba_range_msf (ide_drive_t *drive, int lba_start, int lba_end,
#endif /* not STANDARD_ATAPI */
/* Play audio starting at LBA LBA_START and finishing with the
LBA before LBA_END. */
static int
cdrom_play_lba_range (ide_drive_t *drive, int lba_start, int lba_end,
cdrom_play_lba_range_1 (ide_drive_t *drive, int lba_start, int lba_end,
struct atapi_request_sense *reqbuf)
{
/* This is rather annoying.
......@@ -1942,6 +1993,38 @@ cdrom_play_lba_range (ide_drive_t *drive, int lba_start, int lba_end,
}
/* Play audio starting at LBA LBA_START and finishing with the
LBA before LBA_END. */
static int
cdrom_play_lba_range (ide_drive_t *drive, int lba_start, int lba_end,
struct atapi_request_sense *reqbuf)
{
int i, stat;
struct atapi_request_sense my_reqbuf;
if (reqbuf == NULL)
reqbuf = &my_reqbuf;
/* Some drives, will, for certain audio cds,
give an error if you ask them to play the entire cd using the
values which are returned in the TOC. The play will succeed, however,
if the ending address is adjusted downwards by a few frames. */
for (i=0; i<75; i++)
{
stat = cdrom_play_lba_range_1 (drive, lba_start, lba_end, reqbuf);
if (stat == 0 ||
!(reqbuf->sense_key == ILLEGAL_REQUEST && reqbuf->asc == 0x24))
return stat;
--lba_end;
if (lba_end <= lba_start) break;
}
return stat;
}
static
int cdrom_get_toc_entry (ide_drive_t *drive, int track,
struct atapi_toc_entry **ent,
......@@ -2575,7 +2658,12 @@ void ide_cdrom_setup (ide_drive_t *drive)
/* Turn this off by default, since many people don't like it. */
CDROM_STATE_FLAGS (drive)->eject_on_close= 0;
#if NO_DOOR_LOCKING
CDROM_CONFIG_FLAGS (drive)->no_doorlock = 1;
#else
CDROM_CONFIG_FLAGS (drive)->no_doorlock = 0;
#endif
CDROM_CONFIG_FLAGS (drive)->drq_interrupt =
((drive->id->config & 0x0060) == 0x20);
......@@ -2608,17 +2696,30 @@ void ide_cdrom_setup (ide_drive_t *drive)
CDROM_CONFIG_FLAGS (drive)->no_playaudio12 = 1;
}
else if (strcmp (drive->id->model, "V003S0DS") == 0 || /* Vertos */
strcmp (drive->id->model, "0V300SSD") == 0)
/* Vertos 300.
There seem to be at least two different, incompatible versions
of this drive floating around. Luckily, they appear to return their
id strings with different byte orderings. */
else if (strcmp (drive->id->model, "V003S0DS") == 0)
{
CDROM_CONFIG_FLAGS (drive)->vertos_lossage = 1;
CDROM_CONFIG_FLAGS (drive)->playmsf_uses_bcd = 1;
CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
}
else if (strcmp (drive->id->model, "0V300SSD") == 0 ||
strcmp (drive->id->model, "V003M0DP") == 0)
CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
/* Vertos 400. */
else if (strcmp (drive->id->model, "V004E0DT") == 0 ||
strcmp (drive->id->model, "0V400ETD") == 0)
CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
else if ( strcmp (drive->id->model, "CD-ROM CDU55D") == 0) /*sony cdu55d */
CDROM_CONFIG_FLAGS (drive)->no_playaudio12 = 1;
else if (strcmp (drive->id->model, "CD-ROM CDU55E") == 0)
CDROM_CONFIG_FLAGS (drive)->no_playaudio12 = 1;
#endif /* not STANDARD_ATAPI */
drive->cdrom_info.toc = NULL;
......
Fri Feb 9 14:15:47 1996 <tytso@rsts-11.mit.edu>
* serial.c (block_til_ready): Fixed another race condition which
happens if a hangup happens during the open.
Wed Jan 10 10:08:00 1996 <tytso@rsts-11.mit.edu>
* serial.c (block_til_ready): Remove race condition which happened
......
......@@ -705,6 +705,9 @@ static void do_apm_timer(unsigned long unused)
if (err)
apm_error("busy", err);
}
if (!(((standbys_pending > 0) || (suspends_pending > 0))
&& (apm_bios_info.version == 0x100)))
check_events();
init_timer(&apm_timer);
......
......@@ -72,6 +72,12 @@
#define CTRL_ACTION 0x0d00ff81
#define CTRL_ALWAYS 0x0800f501 /* Cannot be overridden by disp_ctrl */
/*
* Here is the default bell parameters: 750HZ, 1/8th of a second
*/
#define DEFAULT_BELL_PITCH 750
#define DEFAULT_BELL_DURATION (HZ/8)
/*
* NOTE!!! We sometimes disable and enable interrupts for a short while
* (to put a word in video IO), but this will work even for keyboard
......@@ -1136,17 +1142,16 @@ static void setterm_command(int currcons)
break;
case 10: /* set bell frequency in Hz */
if (npar >= 1)
bell_pitch = (par[1] < 20 || par[1] > 32767) ?
0 : 1193180 / par[1];
bell_pitch = par[1];
else
bell_pitch = 0x637;
bell_pitch = DEFAULT_BELL_PITCH;
break;
case 11: /* set bell duration in msec */
if (npar >= 1)
bell_duration = (par[1] < 2000) ?
par[1]*HZ/1000 : 0;
else
bell_duration = HZ/8;
bell_duration = DEFAULT_BELL_DURATION;
break;
case 12: /* bring specified console to the front */
if (par[1] >= 1 && vc_cons_allocated(par[1]-1))
......@@ -1318,8 +1323,8 @@ static void reset_terminal(int currcons, int do_clear)
tab_stop[3] =
tab_stop[4] = 0x01010101;
bell_pitch = 0x637;
bell_duration = HZ/8;
bell_pitch = DEFAULT_BELL_PITCH;
bell_duration = DEFAULT_BELL_DURATION;
gotoxy(currcons,0,0);
save_cur(currcons);
......@@ -1475,7 +1480,7 @@ static int con_write(struct tty_struct * tty, int from_user,
*/
switch (c) {
case 7:
if (bell_pitch && bell_duration)
if (bell_duration)
kd_mksound(bell_pitch, bell_duration);
continue;
case 8:
......
......@@ -2218,6 +2218,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
*/
if (tty_hung_up_p(filp) ||
(info->flags & ASYNC_CLOSING)) {
if (info->flags & ASYNC_CLOSING)
interruptible_sleep_on(&info->close_wait);
#ifdef SERIAL_DO_RESTART
if (info->flags & ASYNC_HUP_NOTIFY)
......
......@@ -155,9 +155,15 @@ kd_nosound(unsigned long ignored)
}
void
kd_mksound(unsigned int count, unsigned int ticks)
_kd_mksound(unsigned int hz, unsigned int ticks)
{
static struct timer_list sound_timer = { NULL, NULL, 0, 0, kd_nosound };
static struct timer_list sound_timer = { NULL, NULL, 0, 0,
kd_nosound };
unsigned int count = 0;
if (hz > 20 && hz < 32767)
count = 1193180 / hz;
cli();
del_timer(&sound_timer);
......@@ -180,6 +186,8 @@ kd_mksound(unsigned int count, unsigned int ticks)
return;
}
void (*kd_mksound)(unsigned int hz, unsigned int ticks) = _kd_mksound;
/*
* We handle the console-specific ioctl's here. We allow the
* capability to modify any console, not just the fg_console.
......@@ -211,22 +219,22 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
case KIOCSOUND:
if (!perm)
return -EPERM;
kd_mksound((unsigned int)arg, 0);
kd_mksound(1193180 / (unsigned int) arg, 0);
return 0;
case KDMKTONE:
if (!perm)
return -EPERM;
{
unsigned int ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
unsigned int ticks, count;
/*
* Generate the tone for the appropriate number of ticks.
* If the time is zero, turn off sound ourselves.
*/
kd_mksound(arg & 0xffff, ticks);
if (ticks == 0)
kd_nosound(0);
ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
count = ticks ? (1193180 / (arg & 0xffff)) : 0;
kd_mksound(count, ticks);
return 0;
}
......
......@@ -30,7 +30,7 @@ extern struct vt_struct {
struct wait_queue *paste_wait;
} *vt_cons[MAX_NR_CONSOLES];
void kd_mksound(unsigned int count, unsigned int ticks);
void (*kd_mksound)(unsigned int hz, unsigned int ticks);
int vc_allocate(unsigned int console);
int vc_cons_allocated(unsigned int console);
int vc_resize(unsigned long lines, unsigned long cols);
......
......@@ -413,6 +413,16 @@ static int vortex_found_device(struct device *dev, int ioaddr, int irq,
vp = (struct vortex_private *)dev->priv;
vp->product_name = product_names[product_index];
vp->options = options;
if (options >= 0) {
vp->media_override = options & 7;
vp->full_duplex = (options & 8) ? 1 : 0;
vp->bus_master = (options & 16) ? 1 : 0;
} else {
vp->media_override = 7;
vp->full_duplex = 0;
vp->bus_master = 0;
}
vortex_probe1(dev);
#endif /* MODULE */
return 0;
......
......@@ -1242,7 +1242,7 @@ DPRINTK("tada: sending packet...\n");
if (dev->tbusy) {
int ticks_waited=jiffies - dev->trans_start;
if(ticks_waited<5)
if(ticks_waited<TX_TIMEOUT)
return 1;
DPRINTK("Arrg. Transmitter busy for more than 50 msec. Donald resets adapter, but resetting\n \
the IBM tokenring adapter takes a long time. It might not even help when the\n \
......
......@@ -8,6 +8,16 @@
#define NOTOK 0
#define TOKDEBUG 1
/* Mike Eckhoff -- 96/02/08 */
/* This defines the minimum timeout. If a transmission takes */
/* longer then TX_TIMEOUT to send, we will wait and retry. */
/* On large networks, this value may need to be increased. */
/* We will start at .2s because that is what most drivers seem to be doing */
/* now and the original value of .05s was not nearly enough for large nets. */
#define TX_TIMEOUT (HZ/5)
#ifndef IBMTR_SHARED_RAM_BASE
#define IBMTR_SHARED_RAM_BASE 0xD0
#define IBMTR_SHARED_RAM_SIZE 0x10
......
......@@ -11,7 +11,7 @@
Copyright 1992, 1993, 1994, 1995 Kai Makisara
email Kai.Makisara@metla.fi
Last modified: Thu Dec 14 21:51:16 1995 by root@kai.makisara.fi
Last modified: Mon Jan 29 21:18:12 1996 by root@kai.makisara.fi
Some small formal changes - aeb, 950809
*/
......@@ -438,6 +438,11 @@ flush_buffer(struct inode * inode, struct file * filp, int seek_next)
if (!result && backspace > 0)
result = st_int_ioctl(inode, filp, MTBSR, backspace);
}
else if ((STp->eof == ST_FM) && !STp->eof_hit) {
(STp->mt_status)->mt_fileno++;
STp->drv_block = 0;
}
return result;
}
......@@ -1849,6 +1854,10 @@ st_ioctl(struct inode * inode,struct file * file,
if (i)
return i;
i = flush_buffer(inode, file, FALSE);
if (i < 0)
return i;
(STp->mt_status)->mt_dsreg =
((STp->block_size << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK) |
((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK);
......
......@@ -17,6 +17,7 @@
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/ioctl.h>
#include <linux/dirent.h>
#include <asm/segment.h>
......@@ -44,30 +45,12 @@ struct file_operations fat_dir_operations = {
file_fsync /* fsync */
};
int fat_dir_ioctl(struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long arg)
{
switch (cmd) {
#if 0
/*
* We want to provide an interface for Samba to be able
* to get the short filename for a given long filename.
* We should be able to accomplish by modifying fat_readdir
* slightly.
*/
case VFAT_LONGNAME_TO_SHORT:
#endif
default:
return -EINVAL;
}
}
int fat_readdir(
int fat_readdirx(
struct inode *inode,
struct file *filp,
void *dirent,
filldir_t filldir)
filldir_t filldir,
int both)
{
struct super_block *sb = inode->i_sb;
int ino,i,i2,last;
......@@ -76,7 +59,7 @@ int fat_readdir(
struct msdos_dir_entry *de;
unsigned long oldpos = filp->f_pos;
int is_long;
char longname[256];
char longname[275];
unsigned char long_len = 0; /* Make compiler warning go away */
unsigned char alias_checksum = 0; /* Make compiler warning go away */
......@@ -209,7 +192,7 @@ int fat_readdir(
}
PRINTK(("Long filename: %s, get_new_entry: %d\n", longname, get_new_entry));
} else if (!IS_FREE(de->name) && !(de->attr & ATTR_VOLUME)) {
char bufname[13];
char bufname[14];
char *ptname = bufname;
int dotoffset = 0;
......@@ -258,11 +241,20 @@ int fat_readdir(
ino = fat_parent_ino(inode,0);
if (!is_long) {
dcache_add(inode, bufname, i+dotoffset, ino);
if (both) {
bufname[i+dotoffset] = '\0';
}
if (filldir(dirent, bufname, i+dotoffset, oldpos, ino) < 0) {
filp->f_pos = oldpos;
break;
}
} else {
dcache_add(inode, longname, long_len, ino);
if (both) {
memcpy(&longname[long_len+1], bufname, i+dotoffset);
long_len += i+dotoffset;
}
if (filldir(dirent, longname, long_len, oldpos, ino) < 0) {
filp->f_pos = oldpos;
break;
......@@ -280,3 +272,80 @@ int fat_readdir(
if (bh) brelse(bh);
return 0;
}
int fat_readdir(
struct inode *inode,
struct file *filp,
void *dirent,
filldir_t filldir)
{
return fat_readdirx(inode, filp, dirent, filldir, 0);
}
static int vfat_ioctl_fill(
void * buf,
const char * name,
int name_len,
off_t offset,
ino_t ino)
{
struct dirent *d1 = (struct dirent *)buf;
struct dirent *d2 = d1 + 1;
int len, slen;
int dotdir;
if (get_user(&d1->d_reclen) != 0) {
return -1;
}
if ((name_len == 1 && name[0] == '.') ||
(name_len == 2 && name[0] == '.' && name[1] == '.')) {
dotdir = 1;
len = name_len;
} else {
dotdir = 0;
len = strlen(name);
}
if (len != name_len) {
memcpy_tofs(d2->d_name, name, len);
put_user(0, d2->d_name + len);
put_user(len, &d2->d_reclen);
put_user(ino, &d2->d_ino);
put_user(offset, &d2->d_off);
slen = name_len - len;
memcpy_tofs(d1->d_name, name+len+1, slen);
put_user(0, d1->d_name+slen);
put_user(slen, &d1->d_reclen);
} else {
put_user(0, d2->d_name);
put_user(0, &d2->d_reclen);
memcpy_tofs(d1->d_name, name, len);
put_user(0, d1->d_name+len);
put_user(len, &d1->d_reclen);
}
PRINTK(("FAT d1=%p d2=%p len=%d, name_len=%d\n",
d1, d2, len, name_len));
return 0;
}
int fat_dir_ioctl(struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long arg)
{
/*
* We want to provide an interface for Samba to be able
* to get the short filename for a given long filename.
* Samba should use this ioctl instead of readdir() to
* get the information it needs.
*/
switch (cmd) {
case VFAT_IOCTL_READDIR_BOTH: {
struct dirent *d1 = (struct dirent *)arg;
put_user(0, &d1->d_reclen);
return fat_readdirx(inode,filp,(void *)arg,vfat_ioctl_fill,1);
}
default:
return -EINVAL;
}
return 0;
}
......@@ -434,7 +434,7 @@ void fat_read_inode(struct inode *inode, struct inode_operations *fs_dir_inode_o
inode->i_size = CF_LE_L(raw_entry->size);
}
if(raw_entry->attr & ATTR_SYS)
if (MSDOS_I(inode)->sys_immutable)
if (MSDOS_SB(inode->i_sb)->sys_immutable)
inode->i_flags |= S_IMMUTABLE;
MSDOS_I(inode)->i_binary = is_binary(MSDOS_SB(inode->i_sb)->conversion,
raw_entry->ext);
......
......@@ -123,9 +123,6 @@ struct inode_operations proc_kcore_inode_operations = {
};
extern unsigned long prof_len;
extern unsigned long * prof_buffer;
extern unsigned long prof_shift;
/*
* This function accesses profiling information. The returned data is
* binary: the sampling step and the actual contents of the profile
......@@ -137,21 +134,21 @@ static int read_profile(struct inode *inode, struct file *file, char *buf, int c
unsigned long p = file->f_pos;
int read;
char * pnt;
unsigned long sample_step = 1 << prof_shift;
unsigned int sample_step = 1 << prof_shift;
if (count < 0)
return -EINVAL;
if (p >= (prof_len+1)*sizeof(unsigned long))
if (p >= (prof_len+1)*sizeof(unsigned int))
return 0;
if (count > (prof_len+1)*sizeof(unsigned long) - p)
count = (prof_len+1)*sizeof(unsigned long) - p;
if (count > (prof_len+1)*sizeof(unsigned int) - p)
count = (prof_len+1)*sizeof(unsigned int) - p;
read = 0;
while (p < sizeof(unsigned long) && count > 0) {
while (p < sizeof(unsigned int) && count > 0) {
put_user(*((char *)(&sample_step)+p),buf);
buf++; p++; count--; read++;
}
pnt = (char *)prof_buffer + p - sizeof(unsigned long);
pnt = (char *)prof_buffer + p - sizeof(unsigned int);
memcpy_tofs(buf,(void *)pnt,count);
read += count;
file->f_pos += read;
......
......@@ -37,6 +37,12 @@
#define ATTR_EXT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
/* bits that are used by the Windows 95/Windows NT extended FAT */
#define ATTR_DIR_READ_BOTH 512 /* read both short and long names from the
* vfat filesystem. This is used by Samba
* to export the vfat filesystem with correct
* shortnames. */
#define ATTR_DIR_READ_SHORT 1024
#define CASE_LOWER_BASE 8 /* base is lower case */
#define CASE_LOWER_EXT 16 /* extension is lower case */
......@@ -63,6 +69,17 @@
#define MSDOS_FAT12 4078 /* maximum number of clusters in a 12 bit FAT */
/*
* Inode flags
*/
#define FAT_BINARY_FL 0x00000001 /* File contains binary data */
/*
* ioctl commands
*/
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, long)
#define VFAT_IOCTL_READDIR_SHORT _IOW('r', 2, long)
/*
* Conversion from and to little-endian byte order. (no-op on i386/i486)
*
......@@ -128,14 +145,6 @@ struct slot_info {
int ino; /* ino for the file */
};
struct fat_cache {
kdev_t device; /* device number. 0 means unused. */
int ino; /* inode number. */
int file_cluster; /* cluster number in the file. */
int disk_cluster; /* cluster number on disk. */
struct fat_cache *next; /* next cache entry */
};
/* Determine whether this FS has kB-aligned data. */
#define MSDOS_CAN_BMAP(mib) (!(((mib)->cluster_size & 1) || \
((mib)->data_start & 1)))
......@@ -149,6 +158,14 @@ struct fat_cache {
#ifdef __KERNEL__
struct fat_cache {
kdev_t device; /* device number. 0 means unused. */
int ino; /* inode number. */
int file_cluster; /* cluster number in the file. */
int disk_cluster; /* cluster number on disk. */
struct fat_cache *next; /* next cache entry */
};
/* misc.c */
extern int is_binary(char conversion,char *extension);
extern void lock_fat(struct super_block *sb);
......
......@@ -34,7 +34,6 @@ struct msdos_inode_info {
struct inode *i_old; /* pointer to the old inode this inode
depends on */
int i_binary; /* file contains non-text data */
int sys_immutable; /* file is an immutable system file */
};
#endif
......@@ -25,18 +25,20 @@ struct rand_pool_info {
#ifdef __KERNEL__
void rand_initialize(void);
void rand_initialize_irq(int irq);
void rand_initialize_blkdev(int irq, int mode);
extern void rand_initialize(void);
extern void rand_initialize_irq(int irq);
extern void rand_initialize_blkdev(int irq, int mode);
void add_keyboard_randomness(unsigned char scancode);
void add_mouse_randomness(__u32 mouse_data);
void add_interrupt_randomness(int irq);
void add_blkdev_randomness(int major);
extern void add_keyboard_randomness(unsigned char scancode);
extern void add_mouse_randomness(__u32 mouse_data);
extern void add_interrupt_randomness(int irq);
extern void add_blkdev_randomness(int major);
void get_random_bytes(void *buf, int nbytes);
extern void get_random_bytes(void *buf, int nbytes);
struct file_operations random_fops, urandom_fops;
#ifndef MODULE
extern struct file_operations random_fops, urandom_fops;
#endif
#endif /* __KERNEL___ */
......
......@@ -314,7 +314,7 @@ extern struct timeval xtime;
extern int need_resched;
extern void do_timer(struct pt_regs *);
extern unsigned long * prof_buffer;
extern unsigned int * prof_buffer;
extern unsigned long prof_len;
extern unsigned long prof_shift;
......
......@@ -17,6 +17,9 @@
#ifndef _LINUX_TCP_H
#define _LINUX_TCP_H
#include <linux/types.h>
#include <asm/byteorder.h>
struct tcphdr {
__u16 source;
__u16 dest;
......
......@@ -2,8 +2,8 @@
#define _LINUX_TIME_H
struct timespec {
long tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
long ts_sec; /* seconds */
long ts_nsec; /* nanoseconds */
};
struct timeval {
......
......@@ -19,6 +19,10 @@
#define _ICMP_H
#include <linux/icmp.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/protocol.h>
extern struct icmp_err icmp_err_convert[];
extern struct icmp_mib icmp_statistics;
......
......@@ -23,7 +23,6 @@
#ifndef _PROTOCOL_H
#define _PROTOCOL_H
#define MAX_INET_PROTOS 32 /* Must be a power of 2 */
......
......@@ -19,6 +19,7 @@
#define _TCP_H
#include <linux/tcp.h>
#include <net/checksum.h>
#define MAX_SYN_SIZE 44 + MAX_HEADER + 15
#define MAX_FIN_SIZE 40 + MAX_HEADER + 15
......@@ -104,24 +105,16 @@ extern __inline int between(__u32 seq1, __u32 seq2, __u32 seq3)
return (after(seq1+1, seq2) && before(seq1, seq3+1));
}
/*
* List all states of a TCP socket that can be viewed as a "connected"
* state. This now includes TCP_SYN_RECV, although I am not yet fully
* convinced that this is the solution for the 'getpeername(2)'
* problem. Thanks to Stephen A. Wood <saw@cebaf.gov> -FvK
*/
extern __inline const int tcp_connected(const int state)
static __inline__ int min(unsigned int a, unsigned int b)
{
return(state == TCP_ESTABLISHED || state == TCP_CLOSE_WAIT ||
state == TCP_FIN_WAIT1 || state == TCP_FIN_WAIT2 ||
state == TCP_SYN_RECV);
if (a < b)
return(a);
return(b);
}
extern struct proto tcp_prot;
extern struct tcp_mib tcp_statistics;
extern struct wait_queue *master_select_wakeup;
extern void tcp_err(int type, int code, unsigned char *header, __u32 daddr,
__u32, struct inet_protocol *protocol);
......@@ -133,11 +126,193 @@ extern int tcp_rcv(struct sk_buff *skb, struct device *dev,
extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg);
extern void tcp_read_wakeup(struct sock *);
extern void tcp_write_xmit(struct sock *);
extern void tcp_time_wait(struct sock *);
extern void tcp_retransmit(struct sock *, int);
extern void tcp_do_retransmit(struct sock *, int);
extern void tcp_send_check(struct tcphdr *th, unsigned long saddr,
unsigned long daddr, int len, struct sock *sk);
extern void tcp_send_probe0(struct sock *sk);
/* tcp_output.c */
extern void tcp_send_probe0(struct sock *);
extern void tcp_send_partial(struct sock *);
extern void tcp_write_wakeup(struct sock *);
extern void tcp_send_fin(struct sock *sk);
extern void tcp_send_synack(struct sock *, struct sock *, struct sk_buff *);
extern void tcp_send_skb(struct sock *, struct sk_buff *);
extern void tcp_send_ack(u32, u32, struct sock *sk, struct tcphdr *th, u32);
extern void tcp_send_reset(unsigned long saddr, unsigned long daddr, struct tcphdr *th,
struct proto *prot, struct options *opt, struct device *dev, int tos, int ttl);
extern void tcp_enqueue_partial(struct sk_buff *, struct sock *);
extern struct sk_buff * tcp_dequeue_partial(struct sock *);
/* tcp_input.c */
extern void tcp_cache_zap(void);
/* tcp_timer.c */
#define tcp_reset_msl_timer(x,y,z) reset_timer(x,y,z)
extern void tcp_reset_xmit_timer(struct sock *, int, unsigned long);
extern void tcp_retransmit_timer(unsigned long);
/*
* Default sequence number picking algorithm.
* As close as possible to RFC 793, which
* suggests using a 250kHz clock.
* Further reading shows this assumes 2MB/s networks.
* For 10MB/s ethernet, a 1MHz clock is appropriate.
* That's funny, Linux has one built in! Use it!
*/
static inline u32 tcp_init_seq(void)
{
struct timeval tv;
do_gettimeofday(&tv);
return tv.tv_usec+tv.tv_sec*1000000;
}
/*
* This function returns the amount that we can raise the
* usable window based on the following constraints
*
* 1. The window can never be shrunk once it is offered (RFC 793)
* 2. We limit memory per socket
*/
static __inline__ unsigned short tcp_raise_window(struct sock *sk)
{
long free_space = sock_rspace(sk);
long window;
if (free_space > 1024)
free_space &= ~0x3FF; /* make free space a multiple of 1024 */
if(sk->window_clamp)
free_space = min(sk->window_clamp, free_space);
/*
* compute the actual window i.e.
* old_window - received_bytes_on_that_win
*/
window = sk->window - (sk->acked_seq - sk->lastwin_seq);
if (sk->mss == 0)
sk->mss = sk->mtu;
if ( window < 0 ) {
window = 0;
printk(KERN_DEBUG "TRW: win < 0 w=%d 1=%u 2=%u\n",
sk->window, sk->acked_seq, sk->lastwin_seq);
}
if ( (free_space - window) >= min(sk->mss, MAX_WINDOW/2) )
return ((free_space - window) / sk->mss) * sk->mss;
return 0;
}
static __inline__ unsigned short tcp_select_window(struct sock *sk)
{
long free_space = sock_rspace(sk);
long window;
if (free_space > 1024)
free_space &= ~0x3FF; /* make free space a multiple of 1024 */
if (sk->window_clamp)
free_space = min(sk->window_clamp, free_space);
/*
* compute the actual window i.e.
* old_window - received_bytes_on_that_win
*/
if (sk->mss == 0)
sk->mss = sk->mtu;
window = sk->window - (sk->acked_seq - sk->lastwin_seq);
if ( window < 0 ) {
window = 0;
printk(KERN_DEBUG "TSW: win < 0 w=%d 1=%u 2=%u\n",
sk->window, sk->acked_seq, sk->lastwin_seq);
}
/*
* RFC 1122:
* "the suggested [SWS] avoidance algoritm for the receiver is to keep
* RECV.NEXT + RCV.WIN fixed until:
* RCV.BUFF - RCV.USER - RCV.WINDOW >= min(1/2 RCV.BUFF, MSS)"
*
* i.e. don't raise the right edge of the window until you can't raise
* it MSS bytes
*/
if ( (free_space - window) >= min(sk->mss, MAX_WINDOW/2) )
window += ((free_space - window) / sk->mss) * sk->mss;
sk->window = window;
sk->lastwin_seq = sk->acked_seq;
return sk->window;
}
/*
* List all states of a TCP socket that can be viewed as a "connected"
* state. This now includes TCP_SYN_RECV, although I am not yet fully
* convinced that this is the solution for the 'getpeername(2)'
* problem. Thanks to Stephen A. Wood <saw@cebaf.gov> -FvK
*/
extern __inline const int tcp_connected(const int state)
{
return(state == TCP_ESTABLISHED || state == TCP_CLOSE_WAIT ||
state == TCP_FIN_WAIT1 || state == TCP_FIN_WAIT2 ||
state == TCP_SYN_RECV);
}
/*
* Calculate(/check) TCP checksum
*/
static __inline__ u16 tcp_check(struct tcphdr *th, int len,
unsigned long saddr, unsigned long daddr, unsigned long base)
{
return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base);
}
#undef STATE_TRACE
#ifdef STATE_TRACE
static char *statename[]={
"Unused","Established","Syn Sent","Syn Recv",
"Fin Wait 1","Fin Wait 2","Time Wait", "Close",
"Close Wait","Last ACK","Listen","Closing"
};
#endif
static __inline__ void tcp_set_state(struct sock *sk, int state)
{
if(sk->state==TCP_ESTABLISHED)
tcp_statistics.TcpCurrEstab--;
#ifdef STATE_TRACE
if(sk->debug)
printk("TCP sk=%p, State %s -> %s\n",sk, statename[sk->state],statename[state]);
#endif
/* This is a hack but it doesn't occur often and it's going to
be a real to fix nicely */
if(state==TCP_ESTABLISHED && sk->state==TCP_SYN_RECV)
{
wake_up_interruptible(&master_select_wakeup);
}
sk->state=state;
if(state==TCP_ESTABLISHED)
tcp_statistics.TcpCurrEstab++;
if(sk->state==TCP_CLOSE)
tcp_cache_zap();
}
#endif /* _TCP_H */
......@@ -456,7 +456,7 @@ static void parse_options(char *line)
if (!strncmp(line, "nfsaddrs=", 9)) {
line += 9;
strncpy(nfs_root_addrs, line, sizeof(nfs_root_addrs));
nfs_root_addrs[sizeof(nfs_root_addrs)] = '\0';
nfs_root_addrs[sizeof(nfs_root_addrs)-1] = '\0';
continue;
}
#endif
......@@ -620,11 +620,11 @@ asmlinkage void start_kernel(void)
#endif
#endif
if (prof_shift) {
prof_buffer = (unsigned long *) memory_start;
prof_buffer = (unsigned int *) memory_start;
/* only text is profiled */
prof_len = (unsigned long) &_etext - (unsigned long) &_stext;
prof_len >>= prof_shift;
memory_start += prof_len * sizeof(unsigned long);
memory_start += prof_len * sizeof(unsigned int);
}
memory_start = console_init(memory_start,memory_end);
#ifdef CONFIG_PCI
......
......@@ -72,7 +72,7 @@ int need_resched = 0;
unsigned long event = 0;
extern int _setitimer(int, struct itimerval *, struct itimerval *);
unsigned long * prof_buffer = NULL;
unsigned int * prof_buffer = NULL;
unsigned long prof_len = 0;
unsigned long prof_shift = 0;
......@@ -1115,8 +1115,8 @@ asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval)
if (error)
return error;
t.tv_sec = 0;
t.tv_nsec = 0; /* <-- Linus, please fill correct value in here */
t.ts_sec = 0;
t.ts_nsec = 0; /* <-- Linus, please fill correct value in here */
return -ENOSYS; /* and then delete this line. Thanks! */
memcpy_tofs(interval, &t, sizeof(struct timespec));
......
......@@ -169,19 +169,19 @@ int sock_setsockopt(struct sock *sk, int level, int optname,
sk->broadcast=valbool;
return 0;
case SO_SNDBUF:
if(val>32767)
val=32767;
if(val<256)
val=256;
sk->sndbuf=val;
if(val > SK_WMEM_MAX*2)
val = SK_WMEM_MAX*2;
if(val < 256)
val = 256;
sk->sndbuf = val;
return 0;
case SO_RCVBUF:
if(val>32767)
val=32767;
if(val<256)
val=256;
sk->rcvbuf=val;
if(val > SK_RMEM_MAX*2)
val = SK_RMEM_MAX*2;
if(val < 256)
val = 256;
sk->rcvbuf = val;
return(0);
case SO_KEEPALIVE:
......
......@@ -9,9 +9,10 @@
O_TARGET := ipv4.o
IPV4_OBJS := utils.o route.o proc.o timer.o protocol.o packet.o \
arp.o ip_input.o ip_fragment.o ip_forward.o ip_options.o \
ip_output.o ip_sockglue.o raw.o icmp.o tcp.o udp.o \
devinet.o af_inet.o igmp.o ip_fw.o
ip_input.o ip_fragment.o ip_forward.o ip_options.o \
ip_output.o ip_sockglue.o \
tcp.o tcp_input.o tcp_output.o tcp_timer.o \
raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o ip_fw.o
MOD_LIST_NAME := IPV4_MODULES
M_OBJS :=
......
......@@ -290,13 +290,6 @@ void destroy_sock(struct sock *sk)
sk->inuse = 1; /* just to be safe. */
/*
* In case it's sleeping somewhere.
*/
if (!sk->dead)
sk->write_space(sk);
remove_sock(sk);
/*
......@@ -326,6 +319,13 @@ void destroy_sock(struct sock *sk)
kfree_skb(skb, FREE_WRITE);
}
/*
* In case it's sleeping somewhere.
*/
if (!sk->dead)
sk->write_space(sk);
/*
* Don't discard received data until the user side kills its
* half of the socket.
......@@ -383,6 +383,7 @@ void destroy_sock(struct sock *sk)
while((skb=skb_dequeue(&sk->back_log))!=NULL)
{
/* this should [almost] never happen. */
skb->sk = NULL;
kfree_skb(skb, FREE_READ);
}
......@@ -562,7 +563,7 @@ static void def_callback2(struct sock *sk,int len)
static void def_callback3(struct sock *sk)
{
if(!sk->dead)
if(!sk->dead && sk->wmem_alloc*2 <= sk->sndbuf)
{
wake_up_interruptible(sk->sleep);
sock_wake_async(sk->socket, 2);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* INET An implementation of the TCP/IP protocol suite for the LINUX
* operating system. INET is implemented using the BSD Socket
* interface as the means of communication with the user level.
*
* Implementation of the Transmission Control Protocol(TCP).
*
* Version: @(#)tcp.c 1.0.16 05/25/93
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Corey Minyard <wf-rch!minyard@relay.EU.net>
* Florian La Roche, <flla@stud.uni-sb.de>
* Charles Hedrick, <hedrick@klinzhai.rutgers.edu>
* Linus Torvalds, <torvalds@cs.helsinki.fi>
* Alan Cox, <gw4pts@gw4pts.ampr.org>
* Matthew Dillon, <dillon@apollo.west.oic.com>
* Arnt Gulbrandsen, <agulbra@nvg.unit.no>
* Jorge Cwik, <jorge@laser.satlink.net>
*/
#include <net/tcp.h>
/*
* Reset the retransmission timer
*/
void tcp_reset_xmit_timer(struct sock *sk, int why, unsigned long when)
{
del_timer(&sk->retransmit_timer);
sk->ip_xmit_timeout = why;
if((long)when < 0)
{
when=3;
printk("Error: Negative timer in xmit_timer\n");
}
sk->retransmit_timer.expires=jiffies+when;
add_timer(&sk->retransmit_timer);
}
/*
* This is the normal code called for timeouts. It does the retransmission
* and then does backoff. tcp_do_retransmit is separated out because
* tcp_ack needs to send stuff from the retransmit queue without
* initiating a backoff.
*/
static void tcp_retransmit_time(struct sock *sk, int all)
{
tcp_do_retransmit(sk, all);
/*
* Increase the timeout each time we retransmit. Note that
* we do not increase the rtt estimate. rto is initialized
* from rtt, but increases here. Jacobson (SIGCOMM 88) suggests
* that doubling rto each time is the least we can get away with.
* In KA9Q, Karn uses this for the first few times, and then
* goes to quadratic. netBSD doubles, but only goes up to *64,
* and clamps at 1 to 64 sec afterwards. Note that 120 sec is
* defined in the protocol as the maximum possible RTT. I guess
* we'll have to use something other than TCP to talk to the
* University of Mars.
*
* PAWS allows us longer timeouts and large windows, so once
* implemented ftp to mars will work nicely. We will have to fix
* the 120 second clamps though!
*/
sk->retransmits++;
sk->prot->retransmits++;
sk->backoff++;
sk->rto = min(sk->rto << 1, 120*HZ);
tcp_reset_xmit_timer(sk, TIME_WRITE, sk->rto);
}
/*
* A timer event has trigger a tcp retransmit timeout. The
* socket xmit queue is ready and set up to send. Because
* the ack receive code keeps the queue straight we do
* nothing clever here.
*/
void tcp_retransmit(struct sock *sk, int all)
{
if (all)
{
tcp_retransmit_time(sk, all);
return;
}
sk->ssthresh = sk->cong_window >> 1; /* remember window where we lost */
/* sk->ssthresh in theory can be zero. I guess that's OK */
sk->cong_count = 0;
sk->cong_window = 1;
/* Do the actual retransmit. */
tcp_retransmit_time(sk, all);
}
/*
* A write timeout has occurred. Process the after effects.
*/
static int tcp_write_timeout(struct sock *sk)
{
/*
* Look for a 'soft' timeout.
*/
if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7))
|| (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1))
{
/*
* Attempt to recover if arp has changed (unlikely!) or
* a route has shifted (not supported prior to 1.3).
*/
ip_rt_advice(&sk->ip_route_cache, 0);
}
/*
* Have we tried to SYN too many times (repent repent 8))
*/
if(sk->retransmits > TCP_SYN_RETRIES && sk->state==TCP_SYN_SENT)
{
if(sk->err_soft)
sk->err=sk->err_soft;
else
sk->err=ETIMEDOUT;
sk->error_report(sk);
del_timer(&sk->retransmit_timer);
tcp_statistics.TcpAttemptFails++; /* Is this right ??? - FIXME - */
tcp_set_state(sk,TCP_CLOSE);
/* Don't FIN, we got nothing back */
release_sock(sk);
return 0;
}
/*
* Has it gone just too far ?
*/
if (sk->retransmits > TCP_RETR2)
{
if(sk->err_soft)
sk->err = sk->err_soft;
else
sk->err = ETIMEDOUT;
sk->error_report(sk);
del_timer(&sk->retransmit_timer);
/*
* Time wait the socket
*/
if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 || sk->state == TCP_CLOSING )
{
tcp_set_state(sk,TCP_TIME_WAIT);
tcp_reset_msl_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
}
else
{
/*
* Clean up time.
*/
tcp_set_state(sk, TCP_CLOSE);
release_sock(sk);
return 0;
}
}
return 1;
}
/*
* The TCP retransmit timer. This lacks a few small details.
*
* 1. An initial rtt timeout on the probe0 should cause what we can
* of the first write queue buffer to be split and sent.
* 2. On a 'major timeout' as defined by RFC1122 we shouldn't report
* ETIMEDOUT if we know an additional 'soft' error caused this.
* tcp_err should save a 'soft error' for us.
*/
void tcp_retransmit_timer(unsigned long data)
{
struct sock *sk = (struct sock*)data;
int why = sk->ip_xmit_timeout;
/*
* We are reset. We will send no more retransmits.
*/
if(sk->zapped)
return;
/*
* Only process if socket is not in use
*/
cli();
if (sk->inuse || in_bh)
{
/* Try again in 1 second */
sk->retransmit_timer.expires = jiffies+HZ;
add_timer(&sk->retransmit_timer);
sti();
return;
}
sk->inuse = 1;
sti();
if (sk->ack_backlog && !sk->dead)
sk->data_ready(sk,0);
/* Now we need to figure out why the socket was on the timer. */
switch (why)
{
/* Window probing */
case TIME_PROBE0:
tcp_send_probe0(sk);
tcp_write_timeout(sk);
break;
/* Retransmitting */
case TIME_WRITE:
/* It could be we got here because we needed to send an ack.
* So we need to check for that.
*/
{
struct sk_buff *skb;
unsigned long flags;
save_flags(flags);
cli();
skb = sk->send_head;
if (!skb)
{
if (sk->ack_backlog)
tcp_read_wakeup(sk);
restore_flags(flags);
}
else
{
/*
* Kicked by a delayed ack. Reset timer
* correctly now
*/
if (jiffies < skb->when + sk->rto)
{
if (sk->ack_backlog)
tcp_read_wakeup(sk);
tcp_reset_xmit_timer (sk, TIME_WRITE, skb->when + sk->rto - jiffies);
restore_flags(flags);
break;
}
restore_flags(flags);
/*
* Retransmission
*/
sk->retransmits++;
sk->prot->retransmits++;
sk->prot->retransmit (sk, 0);
tcp_write_timeout(sk);
}
break;
}
/* Sending Keepalives */
case TIME_KEEPOPEN:
/*
* this reset_timer() call is a hack, this is not
* how KEEPOPEN is supposed to work.
*/
tcp_reset_xmit_timer (sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);
/* Send something to keep the connection open. */
if (sk->prot->write_wakeup)
sk->prot->write_wakeup (sk);
sk->retransmits++;
sk->prot->retransmits++;
tcp_write_timeout(sk);
break;
default:
printk ("rexmit_timer: timer expired - reason unknown\n");
break;
}
release_sock(sk);
}
......@@ -142,6 +142,7 @@ void net_timer (unsigned long data)
if(sk->wmem_alloc==0 && sk->rmem_alloc==0)
destroy_sock(sk); /* Socket gone, DON'T update sk->inuse! */
break;
case TIME_CLOSE:
/* We've waited long enough, close the socket. */
sk->state = TCP_CLOSE;
......@@ -152,6 +153,7 @@ void net_timer (unsigned long data)
reset_timer (sk, TIME_DESTROY, TCP_DONE_TIME);
release_sock (sk);
break;
default:
printk ("net_timer: timer expired - reason %d is unknown\n", why);
release_sock (sk);
......
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