@@ -261,7+261,7 @@ S: Maintained
PPP PROTOCOL DRIVERS AND COMPRESSORS
P: Al Longyear
-M: longyear@netcom.com, Cc: longyear@sii.com
+M: longyear@pobox.com
L: linux-ppp@vger.rutgers.edu
S: Maintained
VERSION = 2
PATCHLEVEL = 1
-SUBLEVEL = 23
+SUBLEVEL = 24
ARCH = i386
@@ -356,7+356,11 @@ struct moveparams { void setup_output_buffer_if_we_run_high(struct moveparams *mv)
{
high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE);
+#ifdef STANDARD_MEMORY_BIOS_CALL
if (EXT_MEM_K < (3*1024)) error("Less than 4MB of memory.\n");
+#else
+ if (EXT_MEM_K*64 < (3*1024)) error("Less than 4MB of memory.\n");
+#endif
mv->low_buffer_start = output_data = (char *)LOW_BUFFER_START;
high_loaded = 1;
free_mem_end_ptr = (long)high_buffer_start;
@@ -638,11+638,11 @@ void smp_callin(void) load_ldt(0);
local_flush_tlb();
- while(!task[cpuid] || current_set[cpuid] != task[cpuid])
+ while (cpu_number_map[cpuid] == -1)
barrier();
- if (cpu_number_map[cpuid] == -1)
- while(1);
+ while(!task[cpuid] || current_set[cpuid] != task[cpu_number_map[cpuid]])
+ barrier();
local_flush_tlb();
load_TR(cpu_number_map[cpuid]);
@@ -4128,7+4128,6 @@ static void floppy_release_irq_and_dma(void) extern char *get_options(char *str, int *ints);
char *floppy=NULL;
-MODULE_PARM(floppy, "s");
static void parse_floppy_cfg_string(char *cfg)
{
/*
- * linux/drivers/block/triton.c Version 1.13 Aug 12, 1996
+ * linux/drivers/block/triton.c Version 1.20 Jan 27, 1997
*
- * Copyright (c) 1995-1996 Mark Lord
+ * Copyright (c) 1995-1997 Mark Lord
* May be copied or modified under the terms of the GNU General Public License
*/
* available from ftp://ftp.intel.com/pub/bios/10004bs0.exe
* (thanks to Glen Morrell <glen@spin.Stanford.edu> for researching this).
*
+ * Thanks to "Christopher J. Reimer" <reimer@doe.carleton.ca> for fixing the
+ * problem with some (all?) ACER motherboards/BIOSs.
+ *
* And, yes, Intel Zappa boards really *do* use the Triton IDE ports.
*/
#include <linux/types.h>
@@ -143,7+146,11 @@ const char *good_dma_drives[] = {"Micropolis 2112A", */
#define PRD_BYTES 8
#define PRD_ENTRIES (PAGE_SIZE / (2 * PRD_BYTES))
-#define DEFAULT_BMIBA 0xe800 /* in case BIOS did not init it */
+
+/*
+ * Interface to access piix registers
+ */
+static unsigned int piix_key;
/*
* dma_intr() is the handler for disk read/write DMA interrupts
@@ -366,6+373,53 @@ static void init_triton_dma (ide_hwif_t *hwif, unsigned short base) printk("\n");
}
+/* The next two functions were stolen from cmd640.c, with
+ a few modifications */
+
+static void put_piix_reg (unsigned short reg, long val)
+{
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+ outl_p((reg & 0xfc) | piix_key, 0xcf8);
+ outl_p(val, (reg & 3) | 0xcfc);
+ restore_flags(flags);
+}
+
+static long get_piix_reg (unsigned short reg)
+{
+ long b;
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+ outl_p((reg & 0xfc) | piix_key, 0xcf8);
+ b = inl_p((reg & 3) | 0xcfc);
+ restore_flags(flags);
+ return b;
+}
+
+/*
+ * Search for an (apparently) unused block of I/O space
+ * of "size" bytes in length.
+ */
+static short find_free_region (unsigned short size)
+{
+ unsigned short i, base = 0xe800;
+ for (base = 0xe800; base > 0; base -= 0x800) {
+ if (!check_region(base,size)) {
+ for (i = 0; i < size; i++) {
+ if (inb(base+i) != 0xff)
+ goto next;
+ }
+ return base; /* success */
+ }
+ next:
+ }
+ return 0; /* failure */
+}
+
/*
* ide_init_triton() prepares the IDE driver for DMA operation.
* This routine is called once, from ide.c during driver initialization,
@@ -379,8+433,9 @@ void ide_init_triton (byte bus, byte fn) unsigned int bmiba, timings;
printk("ide: i82371 PIIX (Triton) on PCI bus %d function %d\n", bus, fn);
+
/*
- * See if IDE and BM-DMA features are enabled:
+ * See if IDE ports are enabled
*/
if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)))
goto quit;
@@ -388,42+443,44 @@ void ide_init_triton (byte bus, byte fn) printk("ide: ports are not enabled (BIOS)\n");
goto quit;
}
+ if ((rc = pcibios_read_config_dword(bus, fn, 0x40, &timings)))
+ goto quit;
+ if (!(timings & 0x80008000)) {
+ printk("ide: neither port is enabled\n");
+ goto quit;
+ }
+
+ /*
+ * See if Bus-Mastered DMA is enabled
+ */
if ((pcicmd & 4) == 0) {
printk("ide: BM-DMA feature is not enabled (BIOS)\n");
} else {
/*
* Get the bmiba base address
*/
- int try_again = 1;
- do {
- if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba)))
- goto quit;
- bmiba &= 0xfff0; /* extract port base address */
- if (bmiba) {
- dma_enabled = 1;
- break;
- } else {
- printk("ide: BM-DMA base register is invalid (0x%04x, PnP BIOS problem)\n", bmiba);
- if (inb(DEFAULT_BMIBA) != 0xff || !try_again)
- break;
- printk("ide: setting BM-DMA base register to 0x%04x\n", DEFAULT_BMIBA);
- if ((rc = pcibios_write_config_word(bus, fn, 0x04, pcicmd&~1)))
- goto quit;
- rc = pcibios_write_config_dword(bus, fn, 0x20, DEFAULT_BMIBA|1);
- if (pcibios_write_config_word(bus, fn, 0x04, pcicmd|5) || rc)
- goto quit;
+ if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba)))
+ goto quit;
+ bmiba &= 0xfff0; /* extract port base address */
+ if (bmiba) {
+ dma_enabled = 1;
+ } else {
+ unsigned short base;
+ printk("ide: BM-DMA base register is invalid (0x%04x, PnP BIOS problem)\n", bmiba);
+ base = find_free_region(16);
+ if (base) {
+ printk("ide: bypassing BIOS; setting BMIBA to 0x%04x\n", base);
+ piix_key = 0x80000000 + (fn * 0x100);
+ put_piix_reg(0x04,get_piix_reg(0x04)&~5);
+ put_piix_reg(0x20,(get_piix_reg(0x20)&0xFFFF000F)|base|1);
+ put_piix_reg(0x04,get_piix_reg(0x04)|5);
+ bmiba = get_piix_reg(0x20)&0x0000FFF0;
+ if (bmiba == base && (get_piix_reg(0x04) & 5) == 5)
+ dma_enabled = 1;
+ else
+ printk("ide: no such luck; DMA disabled\n");
}
- } while (try_again--);
- }
-
- /*
- * See if ide port(s) are enabled
- */
- if ((rc = pcibios_read_config_dword(bus, fn, 0x40, &timings)))
- goto quit;
- if (!(timings & 0x80008000)) {
- printk("ide: neither port is enabled\n");
- goto quit;
+ }
}
/*
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
+#include <asm/poll.h>
/*
* We sponge a minor off of the misc major. No need slurping
@@ -46,6+46,7 @@ static int soft_margin = TIMER_MARGIN; /* in seconds */
struct timer_list watchdog_ticktock;
static int timer_alive = 0;
+static int in_use = 0;
/*
@@ -70,8+71,9 @@ static void watchdog_fire(unsigned long data)
static int softdog_open(struct inode *inode, struct file *file)
{
- if(timer_alive)
+ if(in_use)
return -EBUSY;
+ in_use = 1;
MOD_INC_USE_COUNT;
/*
* Activate timer
@@ -94,6+96,7 @@ static void softdog_release(struct inode *inode, struct file *file) MOD_DEC_USE_COUNT;
timer_alive=0;
#endif
+ in_use = 0;
}
static void softdog_ping(void)
* Dynamic PPP devices by Jim Freeman <jfree@caldera.com>.
* ppp_tty_receive ``noisy-raise-bug'' fixed by Ove Ewerlid <ewerlid@syscon.uu.se>
*
- * ==FILEVERSION 960528==
+ * ==FILEVERSION 970126==
*
* NOTE TO MAINTAINERS:
* If you modify this file at all, please set the number above to the
@@ -138,7+138,6 @@ extern inline int lock_buffer (register struct ppp_buffer *buf);
static int rcv_proto_ip (struct ppp *, __u16, __u8 *, int);
static int rcv_proto_ipx (struct ppp *, __u16, __u8 *, int);
-static int rcv_proto_ipv6 (struct ppp *, __u16, __u8 *, int);
static int rcv_proto_vjc_comp (struct ppp *, __u16, __u8 *, int);
static int rcv_proto_vjc_uncomp (struct ppp *, __u16, __u8 *, int);
static int rcv_proto_unknown (struct ppp *, __u16, __u8 *, int);
@@ -266,7+265,6 @@ static ppp_proto_type proto_list[] = {
{ PPP_IP, rcv_proto_ip },
{ PPP_IPX, rcv_proto_ipx },
- { PPP_IPV6, rcv_proto_ipv6 },
{ PPP_VJC_COMP, rcv_proto_vjc_comp },
{ PPP_VJC_UNCOMP, rcv_proto_vjc_uncomp },
{ PPP_LQR, rcv_proto_lqr },
@@ -1230,18+1228,6 @@ rcv_proto_ipx (struct ppp *ppp, __u16 proto, __u8 * data, int count) }
/*
- * Process the receipt of an IPV6 frame
- */
-
-static int
-rcv_proto_ipv6 (struct ppp *ppp, __u16 proto, __u8 * data, int count)
-{
- if (((ppp2dev (ppp)->flags & IFF_UP) != 0) && (count > 0))
- return ppp_rcv_rx (ppp, htons (ETH_P_IPV6), data, count);
- return 0;
-}
-
-/*
* Process the receipt of an VJ Compressed frame
*/
@@ -3076,10+3062,6 @@ ppp_dev_xmit (sk_buff *skb, struct device *dev) answer = ppp_dev_xmit_ip (dev, ppp, data);
break;
- case ETH_P_IPV6:
- answer = ppp_dev_xmit_ipx (dev, ppp, data, len, PPP_IPV6);
- break;
-
default: /* All others have no support at this time. */
dev_kfree_skb (skb, FREE_WRITE);
return 0;
@@ -65,7+65,7 @@ u_short altgr_map[NR_KEYS] = { u_short ctrl_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf100, 0xf101, 0xf109,
0xf102, 0xf10a, 0xf103, 0xf10b, 0xf104, 0xf701, 0xf105, 0xf200,
- 0xf107, 0xf200, 0xf108, 0xf703, 0xf603, 0xf11d, 0xf200, 0xf204,
+ 0xf106, 0xf107, 0xf108, 0xf703, 0xf603, 0xf11d, 0xf200, 0xf204,
0xf601, 0xf200, 0xf200, 0xf600, 0xf602, 0xf200, 0xf200, 0xf000,
0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f, 0xf07f, 0xf200, 0xf200,
0xf01f, 0xf200, 0xf000, 0xf008, 0xf115, 0xf200, 0xf30d, 0xf30c,
@@ -103,7+103,7 @@ u_short shift_ctrl_map[NR_KEYS] = { u_short alt_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf500, 0xf501, 0xf509,
0xf502, 0xf50a, 0xf503, 0xf50b, 0xf504, 0xf701, 0xf505, 0xf200,
- 0xf507, 0xf200, 0xf508, 0xf703, 0xf603, 0xf11d, 0xf200, 0xf209,
+ 0xf506, 0xf507, 0xf508, 0xf703, 0xf603, 0xf11d, 0xf200, 0xf209,
0xf210, 0xf200, 0xf200, 0xf600, 0xf211, 0xf81b, 0xf831, 0xf832,
0xf833, 0xf834, 0xf835, 0xf836, 0xf837, 0xf838, 0xf839, 0xf830,
0xf82d, 0xf83d, 0xf860, 0xf87f, 0xf115, 0xf200, 0xf30d, 0xf30c,
@@ -122,7+122,7 @@ u_short alt_map[NR_KEYS] = { u_short ctrl_alt_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf500, 0xf501, 0xf509,
0xf502, 0xf50a, 0xf503, 0xf50b, 0xf504, 0xf701, 0xf505, 0xf200,
- 0xf507, 0xf200, 0xf508, 0xf703, 0xf603, 0xf11d, 0xf200, 0xf200,
+ 0xf506, 0xf507, 0xf508, 0xf703, 0xf603, 0xf11d, 0xf200, 0xf200,
0xf601, 0xf200, 0xf200, 0xf600, 0xf602, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf115, 0xf200, 0xf30d, 0xf30c,
@@ -51,13+51,13 @@ keycode 0x0e = F6 F16 Console_18 # BLANK KEY on type 5 keyboards
keycode 0x0f =
keycode 0x10 = F7 F17 Console_19
- control Keycode 0x10 = F7
+ control keycode 0x10 = F7
alt keycode 0x10 = Console_7
control alt keycode 0x10 = Console_7
keycode 0x11 = F8 F18 Console_20
- control keycode 0x10 = F8
- alt keycode 0x10 = Console_8
- control alt keycode 0x10 = Console_8
+ control keycode 0x11 = F8
+ alt keycode 0x11 = Console_8
+ control alt keycode 0x11 = Console_8
keycode 0x12 = F9 F19 Console_21
control keycode 0x12 = F9
alt keycode 0x12 = Console_9
#define CNTLREG2 0x2C /* rw control register two */
#define CNTLREG2_ENF 0x40 /* enable features */
-#define CNTLREG3 0x30 /* rw control register three */
+#define CNTLREG3 0x30 /* rw control register three */
#define CNTLREG3_ADIDCHK 0x80 /* additional ID check */
#define CNTLREG3_FASTSCSI 0x10 /* fast SCSI */
#define CNTLREG3_FASTCLK 0x08 /* fast SCSI clocking */
-#define CNTLREG4 0x34 /* rw control register four */
+#define CNTLREG4 0x34 /* rw control register four */
#define CNTLREG4_GLITCH 0xC0 /* glitch eater */
#define CNTLREG4_PWD 0x20 /* reduced power feature */
#define CNTLREG4_RAE 0x08 /* write only, active negot. ctrl. */
@@ -268,7+268,7 @@ extern struct proc_dir_entry proc_scsi_am53c974;
#define AM53C974 { \
NULL, /* pointer to next in list */ \
- NULL, /* long * usage_count */ \
+ NULL, /* struct module *module */ \
&proc_scsi_am53c974, /* struct proc_dir_entry *proc_dir */ \
NULL, /* int (*proc_info)(char *, char **, off_t, int, int, int); */ \
"AM53C974", /* name */ \
-Sat Jan 18 15:51:45 1997 Richard Henderson <richard@twiddle.rth.home>
+Sat Jan 18 15:51:45 1997 Richard Henderson <rth@tamu.edu>
* Don't play with usage_count directly, instead hand around
the module header and use the module macros.
* for more info.
*/
#include <linux/config.h>
-
+#include <linux/poll.h>
#include "sound_config.h"
@@ -542,44+542,31 @@ audio_init_devices (void) */
}
-int
-audio_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+audio_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
{
char *dma_buf;
+ unsigned int mask = 0;
int buf_no, buf_ptr, buf_size;
dev = dev >> 4;
- switch (sel_type)
- {
- case SEL_IN:
- if (audio_mode[dev] & AM_WRITE && !(audio_devs[dev]->flags & DMA_DUPLEX))
- {
- return 0; /* Not recording */
- }
-
- return DMAbuf_select (dev, file, sel_type, wait);
- break;
+ mask = DMAbuf_poll (dev, file, wait);
- case SEL_OUT:
- if (audio_mode[dev] & AM_READ && !(audio_devs[dev]->flags & DMA_DUPLEX))
- {
- return 0; /* Wrong direction */
- }
+/* sel_in */
+ if (audio_mode[dev] & AM_WRITE && !(audio_devs[dev]->flags & DMA_DUPLEX))
+ mask &= ~(POLLIN | POLLRDNORM); /* Wrong direction */
- if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
- {
- return 1; /* There is space in the current buffer */
- }
-
- return DMAbuf_select (dev, file, sel_type, wait);
- break;
-
- case SEL_EX:
- return 0;
- }
+/* sel_out */
+ if (audio_mode[dev] & AM_READ && !(audio_devs[dev]->flags & DMA_DUPLEX)) {
+ mask &= ~(POLLOUT | POLLWRNORM); /* Wrong direction */
+ goto sel_ex;
+ }
+ if (DMAbuf_get_curr_buffer (dev, &buf_no, &dma_buf, &buf_ptr, &buf_size) >= 0)
+ mask |= POLLOUT | POLLWRNORM;
- return 0;
+ sel_ex:
+ return mask;
}
* for more info.
*/
#include <linux/config.h>
-
+#include <linux/poll.h>
#include "sound_config.h"
@@ -1834,109+1834,70 @@ DMAbuf_reset_dma (int dev) {
}
-int
-DMAbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+DMAbuf_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
{
+ unsigned int mask = 0;
struct dma_buffparms *dmap;
unsigned long flags;
- switch (sel_type)
- {
- case SEL_IN:
- if (!(audio_devs[dev]->open_mode))
- return 0;
-
- dmap = audio_devs[dev]->dmap_in;
-
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- {
- if (dmap->qlen)
- return 1;
-
- save_flags (flags);
- cli ();
-
- in_sleep_flag[dev].opts = WK_SLEEP;
- select_wait (&in_sleeper[dev], wait);
- restore_flags (flags);
- return 0;
- }
-
- if (dmap->dma_mode != DMODE_INPUT)
- {
- if (dmap->dma_mode == DMODE_NONE &&
- audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT &&
- !dmap->qlen &&
- audio_devs[dev]->go)
- {
- unsigned long flags;
-
- save_flags (flags);
- cli ();
- activate_recording (dev, dmap);
- restore_flags (flags);
- }
- return 0;
- }
-
- if (!dmap->qlen)
- {
- save_flags (flags);
- cli ();
-
- in_sleep_flag[dev].opts = WK_SLEEP;
- select_wait (&in_sleeper[dev], wait);
- restore_flags (flags);
- return 0;
- }
- return 1;
- break;
-
- case SEL_OUT:
- dmap = audio_devs[dev]->dmap_out;
-
- if (dmap->mapping_flags & DMA_MAP_MAPPED)
- {
- if (dmap->qlen)
- return 1;
+ save_flags (flags);
+ cli ();
- save_flags (flags);
- cli ();
+ in_sleep_flag[dev].opts = WK_SLEEP;
+ poll_wait (&in_sleeper[dev], wait);
+ out_sleep_flag[dev].opts = WK_SLEEP;
+ poll_wait (&out_sleeper[dev], wait);
- out_sleep_flag[dev].opts = WK_SLEEP;
- select_wait (&out_sleeper[dev], wait);
- restore_flags (flags);
- return 0;
- }
-
- if (dmap->dma_mode == DMODE_INPUT)
- {
- return 0;
- }
+ restore_flags (flags);
- if (dmap->dma_mode == DMODE_NONE)
- {
- return 1;
- }
+/* sel_in */
+ dmap = audio_devs[dev]->dmap_in;
+ if (!(audio_devs[dev]->open_mode))
+ goto sel_out;
+ if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+ if (dmap->qlen)
+ mask |= POLLIN | POLLRDNORM;
+ goto sel_out;
+ }
+ if (dmap->dma_mode != DMODE_INPUT) {
+ if (dmap->dma_mode == DMODE_NONE &&
+ audio_devs[dev]->enable_bits & PCM_ENABLE_INPUT &&
+ !dmap->qlen &&
+ audio_devs[dev]->go) {
+ unsigned long flags;
- if (!space_in_queue (dev))
- {
- save_flags (flags);
- cli ();
+ save_flags (flags);
+ cli ();
+ activate_recording (dev, dmap);
+ restore_flags (flags);
+ }
+ goto sel_out;
+ }
+ if (!dmap->qlen)
+ goto sel_out;
+ mask |= POLLIN | POLLRDNORM;
- out_sleep_flag[dev].opts = WK_SLEEP;
- select_wait (&out_sleeper[dev], wait);
- restore_flags (flags);
- return 0;
- }
- return 1;
- break;
+ sel_out:
+ dmap = audio_devs[dev]->dmap_out;
- case SEL_EX:
- return 0;
- }
+ if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+ if (dmap->qlen)
+ mask |= POLLOUT | POLLWRNORM;
+ goto sel_ex;
+ }
+ if (dmap->dma_mode == DMODE_INPUT)
+ goto sel_ex;
+ if (dmap->dma_mode == DMODE_NONE) {
+ mask |= POLLOUT | POLLWRNORM;
+ goto sel_ex;
+ }
+ if (!space_in_queue (dev))
+ goto sel_ex;
+ mask |= POLLOUT | POLLWRNORM;
- return 0;
+sel_ex:
+ return mask;
}
* for more info.
*/
#include <linux/config.h>
+#include <linux/poll.h>
#include "sound_config.h"
@@ -497,40+498,21 @@ MIDIbuf_ioctl (int dev, struct fileinfo *file, }
}
-int
-MIDIbuf_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+MIDIbuf_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
{
- dev = dev >> 4;
-
- switch (sel_type)
- {
- case SEL_IN:
- if (!DATA_AVAIL (midi_in_buf[dev]))
- {
-
- input_sleep_flag[dev].opts = WK_SLEEP;
- select_wait (&input_sleeper[dev], wait);
- return 0;
- }
- return 1;
- break;
-
- case SEL_OUT:
- if (SPACE_AVAIL (midi_out_buf[dev]))
- {
-
- midi_sleep_flag[dev].opts = WK_SLEEP;
- select_wait (&midi_sleeper[dev], wait);
- return 0;
- }
- return 1;
- break;
-
- case SEL_EX:
- return 0;
- }
-
- return 0;
+ unsigned int mask = 0;
+
+ input_sleep_flag[dev].opts = WK_SLEEP;
+ poll_wait (&input_sleeper[dev], wait);
+ midi_sleep_flag[dev].opts = WK_SLEEP;
+ poll_wait (&midi_sleeper[dev], wait);
+
+ if (DATA_AVAIL (midi_in_buf[dev]))
+ mask |= POLLIN | POLLRDNORM;
+ if (!SPACE_AVAIL (midi_out_buf[dev]))
+ mask |= POLLOUT | POLLWRNORM;
+ return mask;
}
* for more info.
*/
#include <linux/config.h>
+#include <linux/poll.h>
#define SEQUENCER_C
@@ -1768,50+1769,28 @@ sequencer_ioctl (int dev, struct fileinfo *file, return -EINVAL;
}
-int
-sequencer_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
+unsigned int
+sequencer_poll (kdev_t dev, struct fileinfo *file, poll_table * wait)
{
+ unsigned int mask = 0;
unsigned long flags;
- dev = dev >> 4;
-
- switch (sel_type)
- {
- case SEL_IN:
- save_flags (flags);
- cli ();
- if (!iqlen)
- {
-
- midi_sleep_flag.opts = WK_SLEEP;
- select_wait (&midi_sleeper, wait);
- restore_flags (flags);
- return 0;
- }
- restore_flags (flags);
- return 1;
- break;
+ save_flags (flags);
+ cli ();
- case SEL_OUT:
- save_flags (flags);
- cli ();
- if ((SEQ_MAX_QUEUE - qlen) < output_threshold)
- {
+ midi_sleep_flag.opts = WK_SLEEP;
+ poll_wait (&midi_sleeper, wait);
+ seq_sleep_flag.opts = WK_SLEEP;
+ poll_wait (&seq_sleeper, wait);
- seq_sleep_flag.opts = WK_SLEEP;
- select_wait (&seq_sleeper, wait);
- restore_flags (flags);
- return 0;
- }
- restore_flags (flags);
- return 1;
- break;
+ restore_flags (flags);
- case SEL_EX:
- return 0;
- }
+ if (iqlen)
+ mask |= POLLIN | POLLRDNORM;
+ if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
+ mask |= POLLOUT | POLLWRNORM;
- return 0;
+ return mask;
}
@@ -18,7+18,7 @@ void DMAbuf_close_dma (int dev); void DMAbuf_reset_dma (int dev);
void DMAbuf_inputintr(int dev);
void DMAbuf_outputintr(int dev, int underflow_flag);
-int DMAbuf_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int DMAbuf_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
void DMAbuf_start_device(int dev);
void DMAbuf_start_devices(unsigned int devmask);
void DMAbuf_reset (int dev);
@@ -36,7+36,7 @@ int audio_ioctl (int dev, struct fileinfo *file, unsigned int cmd, caddr_t arg);
void audio_init_devices (void);
-int audio_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int audio_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
/*
* System calls for the /dev/sequencer
@@ -56,7+56,7 @@ unsigned long compute_finetune(unsigned long base_freq, int bend, int range); void seq_input_event(unsigned char *event, int len);
void seq_copy_to_input (unsigned char *event, int len);
-int sequencer_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int sequencer_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
/*
* System calls for the /dev/midi
@@ -72,7+72,7 @@ int MIDIbuf_lseek (int dev, struct fileinfo *file, off_t offset, int orig); void MIDIbuf_bytes_received(int dev, unsigned char *buf, int count);
void MIDIbuf_init(void);
-int MIDIbuf_select(int dev, struct fileinfo *file, int sel_type, select_table * wait);
+unsigned int MIDIbuf_poll(kdev_t dev, struct fileinfo *file, poll_table * wait);
/*
*
@@ -192,29+192,29 @@ sound_ioctl (struct inode *inode, struct file *file, return err;
}
-static int
-sound_select (struct inode *inode, struct file *file, int sel_type, select_table * wait)
+static unsigned int
+sound_poll (struct file *file, poll_table * wait)
{
int dev;
- dev = MINOR (inode->i_rdev);
+ dev = MINOR (file->f_inode->i_rdev);
files[dev].flags = file->f_flags;
- DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));
+ DEB (printk ("sound_poll(dev=%d)\n", dev));
switch (dev & 0x0f)
{
#ifdef CONFIG_SEQUENCER
case SND_DEV_SEQ:
case SND_DEV_SEQ2:
- return sequencer_select (dev, &files[dev], sel_type, wait);
+ return sequencer_poll (dev, &files[dev], wait);
break;
#endif
#ifdef CONFIG_MIDI
case SND_DEV_MIDIN:
- return MIDIbuf_select (dev, &files[dev], sel_type, wait);
+ return MIDIbuf_poll (dev, &files[dev], wait);
break;
#endif
@@ -222,7+222,7 @@ sound_select (struct inode *inode, struct file *file, int sel_type, select_table case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
- return audio_select (dev, &files[dev], sel_type, wait);
+ return audio_poll (dev, &files[dev], wait);
break;
#endif
@@ -327,7+327,7 @@ static struct file_operations sound_fops = sound_read,
sound_write,
NULL, /* sound_readdir */
- sound_select,
+ sound_poll,
sound_ioctl,
sound_mmap,
sound_open,
@@ -76,7+76,6 @@ static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs) /*
* OK, now restart the process with the interpreter's inode.
*/
- bprm->filename = interp;
retval = open_namei(interp, 0, 0, &bprm->inode, NULL);
if (retval)
return retval;
@@ -1011,6+1011,7 @@ extern int get_pci_list(char*); extern int get_md_status (char *);
extern int get_rtc_status (char *);
extern int get_locks_status (char *);
+extern int get_swaparea_info (char *);
#ifdef __SMP_PROF__
extern int get_smp_prof_list(char *);
#endif
@@ -1088,6+1089,9 @@ static long get_root_array(char * page, int type, char **start,
case PROC_MTAB:
return get_filesystem_info( page );
+
+ case PROC_SWAP:
+ return get_swaparea_info(page);
#ifdef CONFIG_RTC
case PROC_RTC:
return get_rtc_status(page);
@@ -510,6+510,10 @@ static struct proc_dir_entry proc_root_mounts = { PROC_MTAB, 6, "mounts",
S_IFREG | S_IRUGO, 1, 0, 0,
};
+static struct proc_dir_entry proc_root_swaps = {
+ PROC_MTAB, 5, "swaps",
+ S_IFREG | S_IRUGO, 1, 0, 0,
+};
static struct proc_dir_entry proc_root_profile = {
PROC_PROFILE, 7, "profile",
S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
@@ -572,6+576,7 @@ void proc_root_init(void) proc_register(&proc_root, &proc_root_locks);
proc_register(&proc_root, &proc_root_mounts);
+ proc_register(&proc_root, &proc_root_swaps);
#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
#ifdef CONFIG_SUN_OPENPROMFS
-/* $Id: namei.h,v 1.1 1996/12/13 14:48:20 jj Exp $
+/* $Id: namei.h,v 1.3 1997/01/26 23:36:36 davem Exp $
* linux/include/asm-sparc/namei.h
*
* Routines to handle famous /usr/gnemul/s*.
#define SPARC_BSD_EMUL "usr/gnemul/sunos/"
#define SPARC_SOL_EMUL "usr/gnemul/solaris/"
-#if 1
-#define gnemul_namei(pathname, base, follow_links, res_inode) ({ \
+#define translate_namei(pathname, base, follow_links, res_inode) ({ \
if ((current->personality & (PER_BSD|PER_SVR4)) && !base && *pathname == '/') { \
struct inode *emul_ino; \
int namelen; \
base->i_count++; \
} \
})
-#else
-#define gnemul_namei(pathname, base, follow_links, res_inode) do { } while (0)
-#endif
-#define gnemul_open_namei(pathname, flag, mode, res_inode, base) ({ \
+#define translate_open_namei(pathname, flag, mode, res_inode, base) ({ \
if ((current->personality & (PER_BSD|PER_SVR4)) && !base && *pathname == '/') { \
struct inode *emul_ino; \
int namelen; \
@@ -43,6+43,7 @@ enum root_directory_inos { PROC_CMDLINE,
PROC_SYS,
PROC_MTAB,
+ PROC_SWAP,
PROC_MD,
PROC_RTC,
PROC_LOCKS,
@@ -154,7+154,7 @@ struct mm_struct { #define INIT_MM { \
1, \
swapper_pg_dir, \
- -1, \
+ 0, \
0, 0, 0, 0, \
0, 0, 0, 0, \
0, 0, 0, 0, \
struct swap_info_struct {
unsigned int flags;
kdev_t swap_device;
+ char *swap_filename;
struct inode * swap_file;
unsigned char * swap_map;
unsigned char * swap_lockmap;
@@ -293,6+293,14 @@ struct tcp_opt * }
*/
+/* Define this to get the sk->debug debugging facility. */
+#define SOCK_DEBUGGING
+#ifdef SOCK_DEBUGGING
+#define SOCK_DEBUG(sk, msg...) if((sk) && ((sk)->debug)) printk(KERN_DEBUG ## msg)
+#else
+#define SOCK_DEBUG(sk, msg...) do { } while (0)
+#endif
+
/*
* TCP will start to use the new protinfo while *still using the old* fields
*/
@@ -432,8+432,7 @@ static __inline__ void tcp_set_state(struct sock *sk, int state) sk->state = state;
#ifdef STATE_TRACE
- if(sk->debug)
- printk("TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
+ SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
#endif
switch (state) {
* 1996-04-21 Modified by Ulrich Windl to make NTP work
* 1996-12-23 Modified by Dave Grothe to fix bugs in semaphores and
* make semaphores SMP safe
+ * 1997-01-28 Modified by Finn Arne Gangstad to make timers scale better.
*/
/*
@@ -630,74+631,174 @@ void sleep_on(struct wait_queue **p) __sleep_on(p,TASK_UNINTERRUPTIBLE);
}
-/*
- * The head for the timer-list has a "expires" field of MAX_UINT,
- * and the sorting routine counts on this..
- */
-static struct timer_list timer_head = { &timer_head, &timer_head, ~0, 0, NULL };
+
+#define TVN_BITS 6
+#define TVR_BITS 8
+#define TVN_SIZE (1 << TVN_BITS)
+#define TVR_SIZE (1 << TVR_BITS)
+#define TVN_MASK (TVN_SIZE - 1)
+#define TVR_MASK (TVR_SIZE - 1)
+
#define SLOW_BUT_DEBUGGING_TIMERS 0
-void add_timer(struct timer_list * timer)
+struct timer_vec {
+ int index;
+ struct timer_list *vec[TVN_SIZE];
+};
+
+struct timer_vec_root {
+ int index;
+ struct timer_list *vec[TVR_SIZE];
+};
+
+static struct timer_vec tv5 = { 0 };
+static struct timer_vec tv4 = { 0 };
+static struct timer_vec tv3 = { 0 };
+static struct timer_vec tv2 = { 0 };
+static struct timer_vec_root tv1 = { 0 };
+
+static struct timer_vec * const tvecs[] = {
+ (struct timer_vec *)&tv1, &tv2, &tv3, &tv4, &tv5
+};
+
+#define NOOF_TVECS (sizeof(tvecs) / sizeof(tvecs[0]))
+
+static unsigned long timer_jiffies = 0;
+
+static inline void insert_timer(struct timer_list *timer,
+ struct timer_list **vec, int idx)
{
- unsigned long flags;
- struct timer_list *p;
+ if ((timer->next = vec[idx]))
+ vec[idx]->prev = timer;
+ vec[idx] = timer;
+ timer->prev = (struct timer_list *)&vec[idx];
+}
-#if SLOW_BUT_DEBUGGING_TIMERS
- if (timer->next || timer->prev) {
- printk("add_timer() called with non-zero list from %p\n",
- __builtin_return_address(0));
- return;
+static inline void internal_add_timer(struct timer_list *timer)
+{
+ /*
+ * must be cli-ed when calling this
+ */
+ unsigned long expires = timer->expires;
+ unsigned long idx = expires - timer_jiffies;
+
+ if (idx < TVR_SIZE) {
+ int i = expires & TVR_MASK;
+ insert_timer(timer, tv1.vec, i);
+ } else if (idx < 1 << (TVR_BITS + TVN_BITS)) {
+ int i = (expires >> TVR_BITS) & TVN_MASK;
+ insert_timer(timer, tv2.vec, i);
+ } else if (idx < 1 << (TVR_BITS + 2 * TVN_BITS)) {
+ int i = (expires >> (TVR_BITS + TVN_BITS)) & TVN_MASK;
+ insert_timer(timer, tv3.vec, i);
+ } else if (idx < 1 << (TVR_BITS + 3 * TVN_BITS)) {
+ int i = (expires >> (TVR_BITS + 2 * TVN_BITS)) & TVN_MASK;
+ insert_timer(timer, tv4.vec, i);
+ } else if ((idx + 1UL) == 0UL) {
+ /* can happen if you add a timer with expires == jiffies */
+ insert_timer(timer, tv1.vec, tv1.index);
+ } else if (idx < 0xffffffffUL) {
+ int i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
+ insert_timer(timer, tv5.vec, i);
+ } else {
+ /* Can only get here on architectures with 64-bit jiffies */
+ timer->next = timer->prev = timer;
}
-#endif
- p = &timer_head;
+}
+
+void add_timer(struct timer_list *timer)
+{
+ unsigned long flags;
save_flags(flags);
cli();
- do {
- p = p->next;
- } while (timer->expires > p->expires);
- timer->next = p;
- timer->prev = p->prev;
- p->prev = timer;
- timer->prev->next = timer;
+#if SLOW_BUT_DEBUGGING_TIMERS
+ if (timer->next || timer->prev) {
+ printk("add_timer() called with non-zero list from %p\n",
+ __builtin_return_address(0));
+ goto out;
+ }
+#endif
+ internal_add_timer(timer);
+#if SLOW_BUT_DEBUGGING_TIMERS
+out:
+#endif
restore_flags(flags);
}
-int del_timer(struct timer_list * timer)
+static inline int detach_timer(struct timer_list *timer)
{
int ret = 0;
- if (timer->next) {
- unsigned long flags;
- struct timer_list * next;
- save_flags(flags);
- cli();
- if ((next = timer->next) != NULL) {
- (next->prev = timer->prev)->next = next;
- timer->next = timer->prev = NULL;
- ret = 1;
- }
- restore_flags(flags);
+ struct timer_list *next, *prev;
+ next = timer->next;
+ prev = timer->prev;
+ if (next) {
+ next->prev = prev;
+ }
+ if (prev) {
+ ret = 1;
+ prev->next = next;
}
return ret;
}
-static inline void run_timer_list(void)
+
+int del_timer(struct timer_list * timer)
+{
+ int ret;
+ unsigned long flags;
+ save_flags(flags);
+ cli();
+ ret = detach_timer(timer);
+ timer->next = timer->prev = 0;
+ restore_flags(flags);
+ return ret;
+}
+
+static inline void cascade_timers(struct timer_vec *tv)
{
- struct timer_list * timer;
+ /* cascade all the timers from tv up one level */
+ struct timer_list *timer;
+ timer = tv->vec[tv->index];
+ /*
+ * We are removing _all_ timers from the list, so we don't have to
+ * detach them individually, just clear the list afterwards.
+ */
+ while (timer) {
+ struct timer_list *tmp = timer;
+ timer = timer->next;
+ internal_add_timer(tmp);
+ }
+ tv->vec[tv->index] = NULL;
+ tv->index = (tv->index + 1) & TVN_MASK;
+}
+static inline void run_timer_list(void)
+{
cli();
- while ((timer = timer_head.next) != &timer_head && timer->expires <= jiffies) {
- void (*fn)(unsigned long) = timer->function;
- unsigned long data = timer->data;
- timer->next->prev = timer->prev;
- timer->prev->next = timer->next;
- timer->next = timer->prev = NULL;
- sti();
- fn(data);
- cli();
+ while ((long)(jiffies - timer_jiffies) >= 0) {
+ struct timer_list *timer;
+ if (!tv1.index) {
+ int n = 1;
+ do {
+ cascade_timers(tvecs[n]);
+ } while (tvecs[n]->index == 1 && ++n < NOOF_TVECS);
+ }
+ while ((timer = tv1.vec[tv1.index])) {
+ void (*fn)(unsigned long) = timer->function;
+ unsigned long data = timer->data;
+ detach_timer(timer);
+ timer->next = timer->prev = NULL;
+ sti();
+ fn(data);
+ cli();
+ }
+ ++timer_jiffies;
+ tv1.index = (tv1.index + 1) & TVR_MASK;
}
sti();
}
+
static inline void run_old_timers(void)
{
struct timer_struct *tp;
#include <linux/swap.h>
#include <linux/fs.h>
#include <linux/swapctl.h>
+#include <linux/malloc.h>
#include <linux/blkdev.h> /* for blk_size */
#include <linux/vmalloc.h>
@@ -393,6+394,8 @@ asmlinkage int sys_swapoff(const char * specialfile)
nr_swap_pages -= p->pages;
iput(p->swap_file);
+ if (p->swap_filename)
+ kfree(p->swap_filename);
p->swap_file = NULL;
p->swap_device = 0;
vfree(p->swap_map);
return err;
}
+int get_swaparea_info(char *buf)
+{
+ struct swap_info_struct *ptr = swap_info;
+ int i, j, len = 0, usedswap;
+
+ len += sprintf(buf, "Filename\t\t\tType\t\tSize\tUsed\tPriority\n");
+ for (i = 0 ; i < nr_swapfiles ; i++, ptr++)
+ if (ptr->flags & SWP_USED) {
+ if (ptr->swap_filename)
+ len += sprintf(buf + len, "%-31s ", ptr->swap_filename);
+ else
+ len += sprintf(buf + len, "(null)\t\t\t");
+ if (ptr->swap_file)
+ len += sprintf(buf + len, "file\t\t");
+ else
+ len += sprintf(buf + len, "partition\t");
+ usedswap = 0;
+ for (j = 0; j < ptr->max; ++j)
+ switch (ptr->swap_map[j]) {
+ case 128:
+ case 0:
+ continue;
+ default:
+ usedswap++;
+ }
+ len += sprintf(buf + len, "%d\t%d\t%d\n", ptr->pages << (PAGE_SHIFT - 10),
+ usedswap << (PAGE_SHIFT - 10), ptr->prio);
+ }
+ return len;
+}
+
/*
* Written 01/25/92 by Simmule Turner, heavily changed by Linus.
*
@@ -418,6+452,7 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags) unsigned int type;
int i, j, prev;
int error = -EPERM;
+ char *tmp;
struct file filp;
static int least_priority = 0;
@@ -434,6+469,7 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags) if (type >= nr_swapfiles)
nr_swapfiles = type+1;
p->flags = SWP_USED;
+ p->swap_filename = NULL;
p->swap_file = NULL;
p->swap_device = 0;
p->swap_map = NULL;
@@ -541,6+577,12 @@ asmlinkage int sys_swapon(const char * specialfile, int swap_flags) prev = i;
}
p->next = i;
+ if (!getname(specialfile, &tmp)) {
+ if ((p->swap_filename =
+ (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
+ strcpy(p->swap_filename, tmp);
+ putname(tmp);
+ }
if (prev < 0) {
swap_list.head = swap_list.next = p - swap_info;
} else {
@@ -1484,8+1484,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len,
/* Build a packet */
- if(sk->debug)
- printk("SK %p: Got address.\n",sk);
+ SOCK_DEBUG(sk, "SK %p: Got address.\n",sk);
size=sizeof(struct ddpehdr)+len+ddp_dl->header_length; /* For headers */
@@ -1507,8+1506,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, dev=rt->dev;
}
- if(sk->debug)
- printk("SK %p: Size needed %d, device %s\n", sk, size, dev->name);
+ SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", sk, size, dev->name);
size += dev->hard_header_len;
@@ -1523,8+1521,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len,
skb->dev=dev;
- if(sk->debug)
- printk("SK %p: Begin build.\n", sk);
+ SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk);
ddp=(struct ddpehdr *)skb_put(skb,sizeof(struct ddpehdr));
ddp->deh_pad=0;
@@ -1544,8+1541,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, ddp->deh_dport=usat->sat_port;
ddp->deh_sport=sk->protinfo.af_at.src_port;
- if(sk->debug)
- printk("SK %p: Copy user data (%d bytes).\n", sk, len);
+ SOCK_DEBUG(sk, "SK %p: Copy user data (%d bytes).\n", sk, len);
err = memcpy_fromiovec(skb_put(skb,len),msg->msg_iov,len);
if (err)
@@ -1582,8+1578,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, if(skb2)
{
loopback=1;
- if(sk->debug)
- printk("SK %p: send out(copy).\n", sk);
+ SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk);
if(aarp_send_ddp(dev,skb2,&usat->sat_addr, NULL)==-1)
kfree_skb(skb2, FREE_WRITE);
/* else queued/sent above in the aarp queue */
@@ -1593,8+1588,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len,
if((dev->flags&IFF_LOOPBACK) || loopback)
{
- if(sk->debug)
- printk("SK %p: Loop back.\n", sk);
+ SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk);
/* loop back */
skb_orphan(skb);
ddp_dl->datalink_header(ddp_dl, skb, dev->dev_addr);
@@ -1606,9+1600,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, }
else
{
- if(sk->debug)
- printk("SK %p: send out.\n", sk);
-
+ SOCK_DEBUG(sk, "SK %p: send out.\n", sk);
if ( rt->flags & RTF_GATEWAY ) {
gsat.sat_addr = rt->gateway;
usat = &gsat;
@@ -1618,8+1610,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, kfree_skb(skb, FREE_WRITE);
/* else queued/sent above in the aarp queue */
}
- if(sk->debug)
- printk("SK %p: Done write (%d).\n", sk, len);
+ SOCK_DEBUG(sk, "SK %p: Done write (%d).\n", sk, len);
return len;
}
@@ -1374,41+1374,32 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) else
sk->protinfo.ax25->source_addr = *call;
- if (sk->debug)
- printk("AX25: source address set to %s\n", ax2asc(&sk->protinfo.ax25->source_addr));
+ SOCK_DEBUG(sk, "AX25: source address set to %s\n", ax2asc(&sk->protinfo.ax25->source_addr));
if (addr_len == sizeof(struct full_sockaddr_ax25) && addr->fsa_ax25.sax25_ndigis == 1) {
if (ax25cmp(&addr->fsa_digipeater[0], &null_ax25_address) == 0) {
dev = NULL;
- if (sk->debug)
- printk("AX25: bound to any device\n");
+ SOCK_DEBUG(sk, "AX25: bound to any device\n");
} else {
if ((dev = ax25rtr_get_dev(&addr->fsa_digipeater[0])) == NULL) {
- if (sk->debug)
- printk("AX25: bind failed - no device\n");
+ SOCK_DEBUG(sk, "AX25: bind failed - no device\n");
return -EADDRNOTAVAIL;
}
- if (sk->debug)
- printk("AX25: bound to device %s\n", dev->name);
+ SOCK_DEBUG(sk, "AX25: bound to device %s\n", dev->name);
}
} else {
if ((dev = ax25rtr_get_dev(&addr->fsa_ax25.sax25_call)) == NULL) {
- if (sk->debug)
- printk("AX25: bind failed - no device\n");
+ SOCK_DEBUG(sk, "AX25: bind failed - no device\n");
return -EADDRNOTAVAIL;
}
- if (sk->debug)
- printk("AX25: bound to device %s\n", dev->name);
+ SOCK_DEBUG(sk, "AX25: bound to device %s\n", dev->name);
}
ax25_fillin_cb(sk->protinfo.ax25, dev);
ax25_insert_socket(sk->protinfo.ax25);
sk->zapped = 0;
-
- if (sk->debug)
- printk("AX25: socket is bound\n");
-
+ SOCK_DEBUG(sk, "AX25: socket is bound\n");
return 0;
}
@@ -2028,12+2019,10 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, int len, dp = sk->protinfo.ax25->digipeat;
}
- if (sk->debug)
- printk("AX.25: sendto: Addresses built.\n");
+ SOCK_DEBUG(sk, "AX.25: sendto: Addresses built.\n");
/* Build a packet */
- if (sk->debug)
- printk("AX.25: sendto: building packet.\n");
+ SOCK_DEBUG(sk, "AX.25: sendto: building packet.\n");
/* Assume the worst case */
size = len + 3 + size_ax25_addr(dp) + AX25_BPQ_HEADER_LEN;
@@ -2045,8+2034,7 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, int len,
skb_reserve(skb, size - len);
- if (sk->debug)
- printk("AX.25: Appending user data\n");
+ SOCK_DEBUG(sk, "AX.25: Appending user data\n");
/* User data follows immediately after the AX.25 data */
memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
@@ -2055,8+2043,7 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, int len, asmptr = skb_push(skb, 1);
*asmptr = sk->protocol;
- if (sk->debug)
- printk("AX.25: Transmitting buffer\n");
+ SOCK_DEBUG(sk, "AX.25: Transmitting buffer\n");
if (sk->type == SOCK_SEQPACKET) {
/* Connected mode sockets go via the LAPB machine */
@@ -2071,22+2058,18 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, int len, } else {
asmptr = skb_push(skb, 1 + size_ax25_addr(dp));
- if (sk->debug) {
- printk("Building AX.25 Header (dp=%p).\n", dp);
- if (dp != 0)
- printk("Num digipeaters=%d\n", dp->ndigi);
- }
+ SOCK_DEBUG(sk, "Building AX.25 Header (dp=%p).\n", dp);
+ if(dp != 0)
+ SOCK_DEBUG(sk, "Num digipeaters=%d\n", dp->ndigi);
/* Build an AX.25 header */
asmptr += (lv = build_ax25_addr(asmptr, &sk->protinfo.ax25->source_addr, &sax.sax25_call, dp, AX25_COMMAND, AX25_MODULUS));
- if (sk->debug)
- printk("Built header (%d bytes)\n",lv);
+ SOCK_DEBUG(sk, "Built header (%d bytes)\n",lv);
skb->h.raw = asmptr;
- if (sk->debug)
- printk("base=%p pos=%p\n", skb->data, asmptr);
+ SOCK_DEBUG(sk, "base=%p pos=%p\n", skb->data, asmptr);
*asmptr = AX25_UI;
@@ -528,8+528,7 @@ void ax25_kiss_cmd(ax25_cb *ax25, unsigned char cmd, unsigned char param) void ax25_dama_on(ax25_cb *ax25)
{
if (ax25_dev_is_dama_slave(ax25->device) == 0) {
- if (ax25->sk != NULL && ax25->sk->debug)
- printk("ax25_dama_on: DAMA on\n");
+ SOCK_DEBUG(ax25->sk, "ax25_dama_on: DAMA on\n");
ax25_kiss_cmd(ax25, 5, 1);
}
}
@@ -541,8+540,7 @@ void ax25_dama_off(ax25_cb *ax25)
ax25->dama_slave = 0;
if (ax25_dev_is_dama_slave(ax25->device) == 0) {
- if (ax25->sk != NULL && ax25->sk->debug)
- printk("ax25_dama_off: DAMA off\n");
+ SOCK_DEBUG(ax25->sk, "ax25_dama_off: DAMA off\n");
ax25_kiss_cmd(ax25, 5, 0);
}
}
@@ -149,8+149,7 @@ static void ax25_timer(unsigned long param)
ax25->state = AX25_STATE_0;
if (ax25->sk != NULL) {
- if (ax25->sk->debug)
- printk(KERN_DEBUG "AX.25 T3 Timeout\n");
+ SOCK_DEBUG(ax25->sk, "AX.25 T3 Timeout\n");
ax25->sk->state = TCP_CLOSE;
ax25->sk->err = ETIMEDOUT;
ax25->sk->shutdown |= SEND_SHUTDOWN;
@@ -298,8+297,7 @@ void ax25_t1_timeout(ax25_cb * ax25) ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
ax25->state = AX25_STATE_0;
if (ax25->sk != NULL) {
- if (ax25->sk->debug)
- printk(KERN_DEBUG "AX.25 link Failure\n");
+ SOCK_DEBUG(ax25->sk, "AX.25 link Failure\n");
ax25->sk->state = TCP_CLOSE;
ax25->sk->err = ETIMEDOUT;
ax25->sk->shutdown |= SEND_SHUTDOWN;
@@ -524,16+524,13 @@ static int tcp_readable(struct sock *sk) int sum;
unsigned long flags;
- if(sk && sk->debug)
- printk("tcp_readable: %p - ",sk);
-
+ SOCK_DEBUG(sk, "tcp_readable: %p - ",sk);
save_flags(flags);
cli();
if (sk == NULL || (skb = skb_peek(&sk->receive_queue)) == NULL)
{
restore_flags(flags);
- if(sk && sk->debug)
- printk("empty\n");
+ SOCK_DEBUG(sk, "empty\n");
return(0);
}
@@ -592,8+589,7 @@ static int tcp_readable(struct sock *sk) while(skb != (struct sk_buff *)&sk->receive_queue);
restore_flags(flags);
- if(sk->debug)
- printk("got %lu bytes.\n",amount);
+ SOCK_DEBUG(sk, "got %lu bytes.\n",amount);
return(amount);
}
@@ -1043,9+1039,6 @@ int tcp_do_sendmsg(struct sock *sk, int iovlen, struct iovec *iov, sk->write_seq += copy;
tcp_send_skb(sk, skb);
-
- release_sock(sk);
- lock_sock(sk);
}
}
@@ -1159,7+1152,7 @@ static int tcp_recv_urg(struct sock * sk, int nonblock,
static inline void tcp_eat_skb(struct sock *sk, struct sk_buff * skb)
{
- sk->ack_backlog++;
+ sk->delayed_acks++;
__skb_unlink(skb, &sk->receive_queue);
kfree_skb(skb, FREE_READ);
@@ -1169,41+1162,36 @@ static inline void tcp_eat_skb(struct sock *sk, struct sk_buff * skb) static void cleanup_rbuf(struct sock *sk)
{
struct sk_buff *skb;
- struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- unsigned long pspace, rspace;
/*
* NOTE! The socket must be locked, so that we don't get
* a messed-up receive queue.
*/
- pspace = sock_rspace(sk);
-
while ((skb=skb_peek(&sk->receive_queue)) != NULL) {
if (!skb->used || skb->users>1)
break;
tcp_eat_skb(sk, skb);
}
-
- if(sk->debug)
- printk("sk->rspace = %lu\n", sock_rspace(sk));
-
+
+ SOCK_DEBUG(sk, "sk->rspace = %lu\n", sock_rspace(sk));
+
/*
* We send a ACK if the sender is blocked
* else let tcp_data deal with the acking policy.
*/
- rspace = sock_rspace(sk);
-
- if ((rspace > pspace) &&
- (rspace > tp->rcv_wnd - (tp->rcv_nxt - tp->rcv_wup)) &&
- (tp->rcv_wnd - (tp->rcv_nxt - tp->rcv_wup) < sk->mss))
+ if (sk->delayed_acks)
{
- /* Send an ack right now. */
- sk->delayed_acks++;
- tcp_read_wakeup(sk);
- }
-}
+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+ __u32 rcv_wnd;
+
+ rcv_wnd = tp->rcv_wnd - (tp->rcv_nxt - tp->rcv_wup);
+
+ if ((rcv_wnd < sk->mss) && (sock_rspace(sk) > rcv_wnd))
+ tcp_read_wakeup(sk);
+ }
+}
/*
@@ -1413,7+1401,8 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, */
*seq -= err;
atomic_dec(&skb->users);
- return -EFAULT;
+ copied = -EFAULT;
+ break;
}
copied += used;
@@ -1467,7+1456,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, msg->msg_name);
}
if(addr_len)
- *addr_len= tp->af_specific->sockaddr_len;
+ *addr_len = tp->af_specific->sockaddr_len;
remove_wait_queue(sk->sleep, &wait);
current->state = TASK_RUNNING;
@@ -1583,10+1572,10 @@ void tcp_shutdown(struct sock *sk, int how) /*
* FIN if needed
*/
-
+
if (tcp_close_state(sk,0))
tcp_send_fin(sk);
-
+
release_sock(sk);
}
@@ -301,7+301,7 @@ int tcp_parse_options(struct tcphdr *th) * See draft-stevens-tcpca-spec-01 for documentation.
*/
-static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup)
+static void tcp_fast_retrans(struct sock *sk, u32 seq, u32 ack, int not_dup)
{
struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp);
@@ -316,24+316,24 @@ static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup) * The packet acked data after high_seq;
*/
- if (ack == tp->snd_una && sk->packets_out && (not_dup == 0) &&
- after(ack, tp->high_seq))
+ if (ack == tp->snd_una && sk->packets_out && (not_dup == 0))
{
-
- sk->dup_acks++;
-
-
/*
* 1. When the third duplicate ack is received, set ssthresh
* to one half the current congestion window, but no less
* than two segments. Retransmit the missing segment.
*/
-
- if (sk->dup_acks == 3)
+
+ if (tp->high_seq == 0 || after(seq, tp->high_seq))
{
- sk->ssthresh = max(sk->cong_window >> 1, 2);
- sk->cong_window = sk->ssthresh + 3;
- tcp_do_retransmit(sk, 0);
+ sk->dup_acks++;
+
+ if (sk->dup_acks == 3)
+ {
+ sk->ssthresh = max(sk->cong_window >> 1, 2);
+ sk->cong_window = sk->ssthresh + 3;
+ tcp_do_retransmit(sk, 0);
+ }
}
/*
@@ -343,9+343,10 @@ static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup) * Packet transmission will be done on normal flow processing
* since we're not in "retransmit mode"
*/
-
- if (sk->dup_acks > 3)
+
+ if (sk->dup_acks >= 3)
{
+ sk->dup_acks++;
sk->cong_window++;
}
}
@@ -358,13+359,13 @@ static void tcp_fast_retrans(struct sock *sk, u32 ack, int not_dup)
if (sk->dup_acks >= 3)
{
- sk->tp_pinfo.af_tcp.retrans_head = NULL;
+ tp->retrans_head = NULL;
sk->cong_window = sk->ssthresh;
sk->retransmits = 0;
}
sk->dup_acks = 0;
+ tp->high_seq = 0;
}
-
}
/*
@@ -536,9+537,11 @@ static int tcp_clean_rtx_queue(struct sock *sk, __u32 ack, __u32 *seq, /* Check for a bug. */
if (skb->next != (struct sk_buff*) &sk->write_queue &&
- after(skb->end_seq, skb->next->seq))
- printk("INET: tcp_input.c: *** "
+ after(skb->end_seq, skb->next->seq))
+ {
+ printk(KERN_DEBUG "INET: tcp_input.c: *** "
"bug send_list out of order.\n");
+ }
#endif
/*
* If our packet is before the ack sequence we can
@@ -549,12+552,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __u32 ack, __u32 *seq, if (after(skb->end_seq, ack))
break;
- if (sk->debug)
- {
- printk(KERN_DEBUG "removing seg %x-%x from "
- "retransmit queue\n", skb->seq, skb->end_seq);
- }
-
+ SOCK_DEBUG(sk, "removing seg %x-%x from retransmit queue\n", skb->seq, skb->end_seq);
acked = FLAG_DATA_ACKED;
atomic_dec(&sk->packets_out);
@@ -624,19+622,18 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th, if(sk->zapped)
return(1); /* Dead, can't ack any more so why bother */
-
if (tp->pending == TIME_KEEPOPEN)
{
tp->probes_out = 0;
}
tp->rcv_tstamp = jiffies;
-
+
/*
* If the ack is newer than sent or older than previous acks
* then we can probably ignore it.
*/
-
+
if (after(ack, tp->snd_nxt) || before(ack, tp->snd_una))
goto uninteresting_ack;
@@ -660,27+657,30 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th, * segments from shrinking the window
*/
- if ((tp->snd_wl1 == 0) || before(tp->snd_wl1, ack_seq) ||
+ if (before(tp->snd_wl1, ack_seq) ||
(tp->snd_wl1 == ack_seq && !after(tp->snd_wl2, ack)))
{
- tp->snd_wnd = ntohs(th->window);
- tp->snd_wl1 = ack_seq;
- tp->snd_wl2 = ack;
-
- flag |= FLAG_WIN_UPDATE;
+ unsigned long nwin;
- if (tp->snd_wnd > sk->max_window)
+ nwin = ntohs(th->window);
+ if ((tp->snd_wl2 != ack) || (nwin > tp->snd_wnd))
{
- sk->max_window = tp->snd_wnd;
+ flag |= FLAG_WIN_UPDATE;
+ tp->snd_wnd = nwin;
+
+ tp->snd_wl1 = ack_seq;
+ tp->snd_wl2 = ack;
+
+ if (nwin > sk->max_window)
+ sk->max_window = nwin;
}
}
-
/*
* We passed data and got it acked, remove any soft error
* log. Something worked...
*/
-
+
sk->err_soft = 0;
/*
@@ -702,8+702,8 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th, flag |= FLAG_DATA_ACKED;
- /*
- * if we where retransmiting don't count rtt estimate
+ /*
+ * if we where retransmiting don't count rtt estimate
*/
if (sk->retransmits)
@@ -728,38+728,22 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th, if (flag & FLAG_DATA_ACKED)
{
tcp_rtt_estimator(tp, seq_rtt);
-
+
(*tcp_sys_cong_ctl_f)(sk, seq, ack, seq_rtt);
}
}
-
-#ifdef TCP_DEBUG
-
- /* Sanity check out packets_out counter */
- if (skb_queue_len(&sk->write_queue) == 0 ||
- ack == tp->snd_nxt )
- {
- if (sk->packets_out)
- {
- printk(KERN_DEBUG "tcp_ack: packets_out %d\n",
- sk->packets_out);
- sk->packets_out = 0;
- }
- }
-#endif
-
if (sk->packets_out)
{
if (flag & FLAG_DATA_ACKED)
{
long when;
-
+
skb = skb_peek(&sk->write_queue);
-
+
when = tp->rto - (jiffies - skb->when);
-
- if (when <= 0)
+
+ if (when <= 0)
{
tp->retrans_head = NULL;
/*
@@ -770,32+754,27 @@ static int tcp_ack(struct sock *sk, struct tcphdr *th, tcp_reset_xmit_timer(sk, TIME_RETRANS,
tp->rto);
}
- else
+ else
tcp_reset_xmit_timer(sk, TIME_RETRANS, when);
}
}
else
tcp_clear_xmit_timer(sk, TIME_RETRANS);
-
+
+
+ tcp_fast_retrans(sk, ack_seq, ack, (flag & (FLAG_DATA|FLAG_WIN_UPDATE)));
/*
* Remember the highest ack received.
*/
-
- tp->snd_una = ack;
-
- tcp_fast_retrans(sk, ack, (flag & (FLAG_DATA|FLAG_WIN_UPDATE)));
+ tp->snd_una = ack;
return 1;
uninteresting_ack:
- tcp_fast_retrans(sk, ack, 0);
-
- if(sk->debug)
- printk("Ack ignored %u %u\n",ack,tp->snd_nxt);
-
+ SOCK_DEBUG(sk, "Ack ignored %u %u\n", ack, tp->snd_nxt);
return 0;
}
@@ -914,18+893,13 @@ static void tcp_ofo_queue(struct sock *sk) break;
if (!after(skb->end_seq, tp->rcv_nxt)) {
-
- if (sk->debug)
- printk("ofo packet was allready received \n");
-
+ SOCK_DEBUG(sk, "ofo packet already received \n");
skb_unlink(skb);
kfree_skb(skb, FREE_READ);
continue;
}
-
- if (sk->debug)
- printk("ofo requeuing : rcv_next %X seq %X - %X\n",
+ SOCK_DEBUG(sk, "ofo requeuing : rcv_next %X seq %X - %X\n",
tp->rcv_nxt, skb->seq, skb->end_seq);
skb_unlink(skb);
@@ -982,10+956,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) * 2nd most common case.
* force an imediate ack
*/
-
- if (sk->debug)
- printk("retransmit received: seq %X\n", skb->seq);
-
+ SOCK_DEBUG(sk, "retransmit received: seq %X\n", skb->seq);
sk->delayed_acks = MAX_DELAY_ACK;
kfree_skb(skb, FREE_READ);
@@ -999,13+970,10 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) * Partial packet
* seq < rcv_next < end_seq
*/
-
- if (sk->debug)
- printk("partial packet: rcv_next %X seq %X - %X\n",
+ SOCK_DEBUG(sk, "partial packet: rcv_next %X seq %X - %X\n",
tp->rcv_nxt, skb->seq, skb->end_seq);
-
- skb_queue_tail(&sk->receive_queue, skb);
+ skb_queue_tail(&sk->receive_queue, skb);
tp->rcv_nxt = skb->end_seq;
@@ -1014,15+982,15 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) if (skb_queue_len(&sk->out_of_order_queue) == 0)
tp->pred_flags = htonl((0x5010 << 16) | tp->snd_wnd);
- return;
+ return;
}
- /*
- * Ok. This is an out_of_order segment
+ /*
+ * Ok. This is an out_of_order segment
*/
-
+
/* Force an ack */
-
+
sk->delayed_acks = MAX_DELAY_ACK;
/*
@@ -1031,8+999,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
tp->pred_flags = 0;
- if (sk->debug)
- printk("out of order segment: rcv_next %X seq %X - %X\n",
+ SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n",
tp->rcv_nxt, skb->seq, skb->end_seq);
if (skb_peek(&sk->out_of_order_queue) == NULL) {
@@ -1055,7+1022,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) skb_append(skb1,skb);
break;
}
-
+
/*
* See if we've hit the start. If so insert.
*/
@@ -1064,7+1031,6 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) break;
}
}
-
}
@@ -1096,9+1062,9 @@ static int tcp_data(struct sk_buff *skb, struct sock *sk, unsigned int len) * The bytes in the receive read/assembly queue has increased.
* Needed for the low memory discard algorithm
*/
-
+
sk->bytes_rcv += skb->len;
-
+
/*
* We no longer have anyone receiving data on this connection.
*/
@@ -1107,23+1073,21 @@ static int tcp_data(struct sk_buff *skb, struct sock *sk, unsigned int len)
if (before(tp->rcv_nxt, sk->copied_seq))
{
- printk("*** tcp.c:tcp_data bug acked < copied\n");
+ printk(KERN_DEBUG "*** tcp.c:tcp_data bug acked < copied\n");
tp->rcv_nxt = sk->copied_seq;
}
sk->delayed_acks++;
-
/*
* Now tell the user we may have some data.
*/
-
- if (!sk->dead)
+
+ if (!sk->dead)
{
- if(sk->debug)
- printk("Data wakeup.\n");
+ SOCK_DEBUG(sk, "Data Wakeup.\n");
sk->data_ready(sk,0);
- }
+ }
return(1);
}
@@ -1132,7+1096,7 @@ static void tcp_data_snd_check(struct sock *sk) struct sk_buff *skb;
struct tcp_opt *tp=&(sk->tp_pinfo.af_tcp);
- if ((skb = tp->send_head))
+ if ((skb = tp->send_head))
{
if (!after(skb->end_seq, tp->snd_una + tp->snd_wnd) &&
sk->packets_out < sk->cong_window )
@@ -1151,9+1115,9 @@ static void tcp_data_snd_check(struct sock *sk) * Data to queue but no room.
*/
tcp_reset_xmit_timer(sk, TIME_PROBE0, tp->rto);
- }
+ }
}
-}
+}
static __inline__ void tcp_ack_snd_check(struct sock *sk)
{
@@ -1168,15+1132,20 @@ static __inline__ void tcp_ack_snd_check(struct sock *sk) */
if (sk->delayed_acks == 0)
+ {
+ /*
+ * We sent a data segment already
+ */
return;
+ }
- if (sk->delayed_acks >= MAX_DELAY_ACK || tcp_raise_window(sk))
+ if (sk->delayed_acks >= MAX_DELAY_ACK || tcp_raise_window(sk))
{
tcp_send_ack(sk);
}
- else
- {
- tcp_send_delayed_ack(sk, HZ/2);
+ else
+ {
+ tcp_send_delayed_ack(sk, HZ/2);
}
}
@@ -1319,13+1288,11 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, if (len == sizeof(struct tcphdr))
{
tcp_ack(sk, th, skb->seq, skb->ack_seq, len);
+ tcp_data_snd_check(sk);
}
- tcp_data_snd_check(sk);
-
kfree_skb(skb, FREE_READ);
return 0;
-
}
else if (skb->ack_seq == tp->snd_una)
{
@@ -1342,12+1309,14 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, sk->data_ready(sk, 0);
tcp_delack_estimator(tp);
- if (sk->delayed_acks++)
+ if (sk->delayed_acks++ == 0)
{
tcp_send_delayed_ack(sk, HZ/2);
}
else
+ {
tcp_send_ack(sk);
+ }
return 0;
}
@@ -1516,6+1485,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
if(th->ack)
{
+ tp->snd_wl1 = skb->seq;
+
/* We got an ack, but it's not a good ack */
if(!tcp_ack(sk,th, skb->seq, skb->ack_seq, len))
{
@@ -1730,19+1701,19 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, break;
case TCP_FIN_WAIT1:
-
+
if (tp->snd_una == sk->write_seq)
{
sk->shutdown |= SEND_SHUTDOWN;
tcp_set_state(sk, TCP_FIN_WAIT2);
- if (!sk->dead)
+ if (!sk->dead)
sk->state_change(sk);
}
break;
- case TCP_CLOSING:
+ case TCP_CLOSING:
- if (tp->snd_una == sk->write_seq)
+ if (tp->snd_una == sk->write_seq)
{
tcp_time_wait(sk);
}
@@ -1750,7+1721,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
case TCP_LAST_ACK:
- if (tp->snd_una == sk->write_seq)
+ if (tp->snd_una == sk->write_seq)
{
sk->shutdown = SHUTDOWN_MASK;
tcp_set_state(sk,TCP_CLOSE);
@@ -1839,9+1810,9 @@ int tcp_sysctl_congavoid(ctl_table *ctl, int write, struct file * filp, {
int val = sysctl_tcp_cong_avoidance;
int retv;
-
- retv = proc_dointvec(ctl, write, filp, buffer, lenp);
-
+
+ retv = proc_dointvec(ctl, write, filp, buffer, lenp);
+
if (write)
{
switch (sysctl_tcp_cong_avoidance) {
@@ -1856,13+1827,6 @@ int tcp_sysctl_congavoid(ctl_table *ctl, int write, struct file * filp, sysctl_tcp_cong_avoidance = val;
}
}
-
+
return retv;
}
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strength-reduce -pipe -m486 -DCPU=486 -c -o tcp_input.o tcp_input.c"
- * c-file-style: "Linux"
- * End:
- */
@@ -346,7+346,6 @@ void tcp_v4_err(struct sk_buff *skb, unsigned char *dp) struct tcphdr *th = (struct tcphdr*)(dp+(iph->ihl<<2));
int type = skb->h.icmph->type;
int code = skb->h.icmph->code;
- struct tcp_opt *tp;
struct sock *sk;
sk = get_sock(&tcp_prot, th->source, iph->daddr, th->dest, iph->saddr);
@@ -356,19+355,12 @@ void tcp_v4_err(struct sk_buff *skb, unsigned char *dp)
if (type == ICMP_SOURCE_QUENCH)
{
- /*
- * FIXME:
- * Follow BSD for now and just reduce cong_window to 1 again.
- * It is possible that we just want to reduce the
- * window by 1/2, or that we want to reduce ssthresh by 1/2
- * here as well.
- */
-
- tp = &sk->tp_pinfo.af_tcp;
+ struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
- sk->cong_window = 1;
+ sk->ssthresh = max(sk->cong_window >> 1, 2);
+ sk->cong_window = sk->ssthresh + 3;
tp->high_seq = tp->snd_nxt;
-
+
return;
}
@@ -629,10+621,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb, void *ptr, __u32 i /* If the socket is dead, don't accept the connection. */
if (sk->dead)
{
- if(sk->debug)
- {
- printk("Reset on %p: Connect on dead socket.\n",sk);
- }
+ SOCK_DEBUG(sk, "Reset on %p: Connect on dead socket.\n",sk);
tcp_statistics.TcpAttemptFails++;
return -ENOTCONN;
}
@@ -1229,10+1218,3 @@ struct proto tcp_prot = { 0, 0,
NULL
};
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strength-reduce -pipe -m486 -DCPU=486 -c -o tcp_ipv4.o tcp_ipv4.c"
- * c-file-style: "Linux"
- * End:
- */
@@ -377,7+377,7 @@ void tcp_write_xmit(struct sock *sk) * c) not retransmiting [Nagle]
*/
- start_bh_atomic();
+ lock_sock(sk);
rcv_wnd = htons(tcp_select_window(sk));
@@ -456,7+456,7 @@ void tcp_write_xmit(struct sock *sk) tcp_reset_xmit_timer(sk, TIME_RETRANS, tp->rto);
}
- end_bh_atomic();
+ release_sock(sk);
}
@@ -637,7+637,7 @@ void tcp_do_retransmit(struct sock *sk, int all) int ct=0;
struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
- start_bh_atomic();
+ lock_sock(sk);
if (tp->retrans_head == NULL)
tp->retrans_head = skb_peek(&sk->write_queue);
@@ -693,9+693,7 @@ void tcp_do_retransmit(struct sock *sk, int all) break;
}
- if (sk->debug)
- printk("retransmit sending\n");
-
+ SOCK_DEBUG(sk, "retransmit sending\n");
/*
* update ack and window
*/
@@ -705,13+703,13 @@ void tcp_do_retransmit(struct sock *sk, int all)
size = skb->tail - (unsigned char *) th;
tp->af_specific->send_check(sk, th, size, skb);
-
+
skb->when = jiffies;
buff = skb_clone(skb, GFP_ATOMIC);
skb_set_owner_w(buff, sk);
-
+
clear_delayed_acks(sk);
-
+
tp->af_specific->queue_xmit(buff);
/*
@@ -722,14+720,8 @@ void tcp_do_retransmit(struct sock *sk, int all) sk->prot->retransmits ++;
tcp_statistics.TcpRetransSegs++;
- /*
- * Record the high sequence number to help avoid doing
- * to much fast retransmission.
- */
+ tp->high_seq = tp->snd_nxt;
- if (sk->retransmits)
- tp->high_seq = tp->snd_nxt;
-
/*
* Only one retransmit requested.
*/
@@ -756,7+748,7 @@ void tcp_do_retransmit(struct sock *sk, int all) }
}
- end_bh_atomic();
+ release_sock(sk);
}
/*
@@ -1035,12+1027,8 @@ void tcp_send_ack(struct sock *sk)
tp->af_specific->send_check(sk, th, sizeof(struct tcphdr), buff);
- if (sk->debug)
- printk("\rtcp_send_ack: seq %x ack %x\n",
- tp->snd_nxt, tp->rcv_nxt);
-
+ SOCK_DEBUG(sk, "\rtcp_send_ack: seq %x ack %x\n", tp->snd_nxt, tp->rcv_nxt);
tp->af_specific->queue_xmit(buff);
-
tcp_statistics.TcpOutSegs++;
}
@@ -477,10+477,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb, void *ptr, /* If the socket is dead, don't accept the connection. */
if (sk->dead)
{
- if(sk->debug)
- {
- printk("Reset on %p: Connect on dead socket.\n",sk);
- }
+ SOCK_DEBUG(sk, "Reset on %p: Connect on dead socket.\n",sk);
tcp_statistics.TcpAttemptFails++;
return -ENOTCONN;
}
@@ -1895,9+1895,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) sk->protinfo.af_ipx.node,
sk->protinfo.af_ipx.port) != NULL)
{
- if(sk->debug)
- printk("IPX: bind failed because port %X in"
- " use.\n", (int)addr->sipx_port);
+ SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", (int)addr->sipx_port);
return -EADDRINUSE;
}
}
@@ -1912,9+1910,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) IPX_NODE_LEN);
if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
- if(sk->debug)
- printk("IPX: bind failed because port %X in"
- " use.\n", (int)addr->sipx_port);
+ SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", (int)addr->sipx_port);
return -EADDRINUSE;
}
}
@@ -1925,9+1921,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) an interface routed to IPX with the ipx routing ioctl() */
if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
- if(sk->debug)
- printk("IPX: bind failed because port %X in use.\n",
- (int)addr->sipx_port);
+ SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", (int)addr->sipx_port);
return -EADDRINUSE;
}
@@ -1935,8+1929,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
ipxitf_insert_socket(intrfc, sk);
sk->zapped=0;
- if(sk->debug)
- printk("IPX: socket is bound.\n");
+ SOCK_DEBUG(sk, "IPX: socket is bound.\n");
return 0;
}
@@ -510,10+510,7 @@ static int netbeui_sendmsg(struct socket *sock, struct msghdr *msg, int len, int }
/* Build a packet */
-
- if(sk->debug)
- printk("SK %p: Got address.\n",sk);
-
+ SOCK_DEBUG(sk, "SK %p: Got address.\n",sk);
size=sizeof(struct ddpehdr)+len+nb_dl->header_length; /* For headers */
if(usat->sat_addr.s_net!=0 || usat->sat_addr.s_node == ATADDR_ANYNODE)
@@ -533,12+530,8 @@ static int netbeui_sendmsg(struct socket *sock, struct msghdr *msg, int len, int return -ENETUNREACH;
dev=rt->dev;
}
-
- if(sk->debug)
- printk("SK %p: Size needed %d, device %s\n", sk, size, dev->name);
-
+ SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", sk, size, dev->name);
size += dev->hard_header_len;
-
skb = sock_alloc_send_skb(sk, size, 0, 0 , &err);
if(skb==NULL)
return err;
@@ -548,12+541,8 @@ static int netbeui_sendmsg(struct socket *sock, struct msghdr *msg, int len, int skb->arp=1;
skb_reserve(skb,nb_dl->header_length);
skb_reserve(skb,dev->hard_header_len);
-
skb->dev=dev;
-
- if(sk->debug)
- printk("SK %p: Begin build.\n", sk);
-
+ SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk);
ddp=(struct ddpehdr *)skb_put(skb,sizeof(struct ddpehdr));
ddp->deh_pad=0;
ddp->deh_hops=0;
@@ -571,10+560,7 @@ static int netbeui_sendmsg(struct socket *sock, struct msghdr *msg, int len, int ddp->deh_snode=sk->protinfo.af_at.src_node;
ddp->deh_dport=usat->sat_port;
ddp->deh_sport=sk->protinfo.af_at.src_port;
-
- if(sk->debug)
- printk("SK %p: Copy user data (%d bytes).\n", sk, len);
-
+ SOCK_DEBUG(sk, "SK %p: Copy user data (%d bytes).\n", sk, len);
err = memcpy_fromiovec(skb_put(skb,len),msg->msg_iov,len);
if (err)
{
@@ -610,8+596,7 @@ static int netbeui_sendmsg(struct socket *sock, struct msghdr *msg, int len, int if(skb2)
{
loopback=1;
- if(sk->debug)
- printk("SK %p: send out(copy).\n", sk);
+ SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk);
if(aarp_send_ddp(dev,skb2,&usat->sat_addr, NULL)==-1)
kfree_skb(skb2, FREE_WRITE);
/* else queued/sent above in the aarp queue */
@@ -621,8+606,7 @@ static int netbeui_sendmsg(struct socket *sock, struct msghdr *msg, int len, int
if((dev->flags&IFF_LOOPBACK) || loopback)
{
- if(sk->debug)
- printk("SK %p: Loop back.\n", sk);
+ SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk);
/* loop back */
atomic_sub(skb->truesize, &sk->wmem_alloc);
nb_dl->datalink_header(nb_dl, skb, dev->dev_addr);
@@ -635,9+619,7 @@ static int netbeui_sendmsg(struct socket *sock, struct msghdr *msg, int len, int }
else
{
- if(sk->debug)
- printk("SK %p: send out.\n", sk);
-
+ SOCK_DEBUG(sk, "SK %p: send out.\n", sk);
if ( rt->flags & RTF_GATEWAY ) {
gsat.sat_addr = rt->gateway;
usat = &gsat;
@@ -647,8+629,7 @@ static int netbeui_sendmsg(struct socket *sock, struct msghdr *msg, int len, int kfree_skb(skb, FREE_WRITE);
/* else queued/sent above in the aarp queue */
}
- if(sk->debug)
- printk("SK %p: Done write (%d).\n", sk, len);
+ SOCK_DEBUG(sk, "SK %p: Done write (%d).\n", sk, len);
return len;
}
@@ -735,8+735,7 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) return -EINVAL;
if ((dev = nr_dev_get(&addr->fsa_ax25.sax25_call)) == NULL) {
- if (sk->debug)
- printk("NET/ROM: bind failed: invalid node callsign\n");
+ SOCK_DEBUG(sk, "NET/ROM: bind failed: invalid node callsign\n");
return -EADDRNOTAVAIL;
}
@@ -765,10+764,7 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) nr_insert_socket(sk);
sk->zapped = 0;
-
- if (sk->debug)
- printk("NET/ROM: socket is bound\n");
-
+ SOCK_DEBUG(sk, "NET/ROM: socket is bound\n");
return 0;
}
@@ -1105,14+1101,10 @@ static int nr_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct s sax.sax25_family = AF_NETROM;
sax.sax25_call = sk->protinfo.nr->dest_addr;
}
-
- if (sk->debug)
- printk("NET/ROM: sendto: Addresses built.\n");
+ SOCK_DEBUG(sk, "NET/ROM: sendto: Addresses built.\n");
/* Build a packet */
- if (sk->debug)
- printk("NET/ROM: sendto: building packet.\n");
-
+ SOCK_DEBUG(sk, "NET/ROM: sendto: building packet.\n");
size = len + AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN + NR_TRANSPORT_LEN;
if ((skb = sock_alloc_send_skb(sk, size, 0, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
@@ -1127,9+1119,7 @@ static int nr_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct s */
asmptr = skb_push(skb, NR_TRANSPORT_LEN);
-
- if (sk->debug)
- printk("Building NET/ROM Header.\n");
+ SOCK_DEBUG(sk, "Building NET/ROM Header.\n");
/* Build a NET/ROM Transport header */
@@ -1138,9+1128,7 @@ static int nr_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct s *asmptr++ = 0; /* To be filled in later */
*asmptr++ = 0; /* Ditto */
*asmptr++ = NR_INFO;
-
- if (sk->debug)
- printk("Built header.\n");
+ SOCK_DEBUG(sk, "Built header.\n");
/*
* Put the data on the end
@@ -1149,15+1137,11 @@ static int nr_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct s skb->h.raw = skb_put(skb, len);
asmptr = skb->h.raw;
-
- if (sk->debug)
- printk("NET/ROM: Appending user data\n");
+ SOCK_DEBUG(sk, "NET/ROM: Appending user data\n");
/* User data follows immediately after the NET/ROM transport header */
memcpy_fromiovec(asmptr, msg->msg_iov, len);
-
- if (sk->debug)
- printk("NET/ROM: Transmitting buffer\n");
+ SOCK_DEBUG(sk, "NET/ROM: Transmitting buffer\n");
if (sk->state != TCP_ESTABLISHED) {
kfree_skb(skb, FREE_WRITE);
@@ -797,8+797,7 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) return -EINVAL;
if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) {
- if (sk->debug)
- printk("Rose: bind failed: invalid address\n");
+ SOCK_DEBUG(sk, "Rose: bind failed: invalid address\n");
return -EADDRNOTAVAIL;
}
@@ -822,10+821,7 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) rose_insert_socket(sk);
sk->zapped = 0;
-
- if (sk->debug)
- printk("Rose: socket is bound\n");
-
+ SOCK_DEBUG(sk, "Rose: socket is bound\n");
return 0;
}
@@ -1134,14+1130,10 @@ static int rose_sendmsg(struct socket *sock, struct msghdr *msg, int len, srose.srose_digi = sk->protinfo.rose->dest_digi;
}
}
-
- if (sk->debug)
- printk("Rose: sendto: Addresses built.\n");
+ SOCK_DEBUG(sk, "Rose: sendto: Addresses built.\n");
/* Build a packet */
- if (sk->debug)
- printk("Rose: sendto: building packet.\n");
-
+ SOCK_DEBUG(sk, "Rose: sendto: building packet.\n");
size = len + AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN;
if ((skb = sock_alloc_send_skb(sk, size, 0, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
@@ -1156,18+1148,14 @@ static int rose_sendmsg(struct socket *sock, struct msghdr *msg, int len, */
asmptr = skb_push(skb, ROSE_MIN_LEN);
-
- if (sk->debug)
- printk("Building Rose Header.\n");
+ SOCK_DEBUG(sk, "Building Rose Header.\n");
/* Build a Rose Transport header */
*asmptr++ = ((sk->protinfo.rose->lci >> 8) & 0x0F) | ROSE_GFI;
*asmptr++ = (sk->protinfo.rose->lci >> 0) & 0xFF;
*asmptr++ = ROSE_DATA;
-
- if (sk->debug)
- printk("Built header.\n");
+ SOCK_DEBUG(sk, "Built header.\n");
/*
* Put the data on the end
@@ -1176,15+1164,11 @@ static int rose_sendmsg(struct socket *sock, struct msghdr *msg, int len, skb->h.raw = skb_put(skb, len);
asmptr = skb->h.raw;
-
- if (sk->debug)
- printk("Rose: Appending user data\n");
+ SOCK_DEBUG(sk, "Rose: Appending user data\n");
/* User data follows immediately after the Rose transport header */
memcpy_fromiovec(asmptr, msg->msg_iov, len);
-
- if (sk->debug)
- printk("Rose: Transmitting buffer\n");
+ SOCK_DEBUG(sk, "Rose: Transmitting buffer\n");
if (sk->state != TCP_ESTABLISHED) {
kfree_skb(skb, FREE_WRITE);
@@ -652,10+652,7 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) x25_insert_socket(sk);
sk->zapped = 0;
-
- if (sk->debug)
- printk(KERN_DEBUG "x25_bind: socket is bound\n");
-
+ SOCK_DEBUG(sk, "x25_bind: socket is bound\n");
return 0;
}
@@ -937,14+934,10 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct sx25.sx25_family = AF_X25;
sx25.sx25_addr = sk->protinfo.x25->dest_addr;
}
-
- if (sk->debug)
- printk(KERN_DEBUG "x25_sendmsg: sendto: Addresses built.\n");
+ SOCK_DEBUG(sk, "x25_sendmsg: sendto: Addresses built.\n");
/* Build a packet */
- if (sk->debug)
- printk(KERN_DEBUG "x25_sendmsg: sendto: building packet.\n");
-
+ SOCK_DEBUG(sk, "x25_sendmsg: sendto: building packet.\n");
if ((msg->msg_flags & MSG_OOB) && len > 32)
len = 32;
@@ -958,9+951,7 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct /*
* Put the data on the end
*/
- if (sk->debug)
- printk(KERN_DEBUG "x25_sendmsg: Copying user data\n");
-
+ SOCK_DEBUG(sk, "x25_sendmsg: Copying user data\n");
skb->h.raw = skb_put(skb, len);
asmptr = skb->h.raw;
@@ -978,9+969,7 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct /*
* Push down the X.25 header
*/
- if (sk->debug)
- printk(KERN_DEBUG "x25_sendmsg: Building X.25 Header.\n");
-
+ SOCK_DEBUG(sk, "x25_sendmsg: Building X.25 Header.\n");
if (msg->msg_flags & MSG_OOB) {
if (sk->protinfo.x25->neighbour->extended) {
asmptr = skb_push(skb, X25_STD_MIN_LEN);
@@ -1012,12+1001,8 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct if (qbit)
skb->data[0] |= X25_Q_BIT;
}
-
- if (sk->debug)
- printk(KERN_DEBUG "x25_sendmsg: Built header.\n");
-
- if (sk->debug)
- printk(KERN_DEBUG "x25_sendmsg: Transmitting buffer\n");
+ SOCK_DEBUG(sk, "x25_sendmsg: Built header.\n");
+ SOCK_DEBUG(sk, "x25_sendmsg: Transmitting buffer\n");
if (sk->state != TCP_ESTABLISHED) {
kfree_skb(skb, FREE_WRITE);