Commit 36513793 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.0.15

parent 8cf64f0c
VERSION = 2
PATCHLEVEL = 0
SUBLEVEL = 14
SUBLEVEL = 15
ARCH = i386
......
......@@ -662,7 +662,7 @@ static int disk_change(int drive)
{
int fdc=FDC(drive);
#ifdef FLOPPY_SANITY_CHECK
if (jiffies < UDP->select_delay + UDRS->select_date)
if (jiffies - UDRS->select_date < UDP->select_delay)
DPRINT("WARNING disk change called early\n");
if (!(FDCS->dor & (0x10 << UNIT(drive))) ||
(FDCS->dor & 3) != UNIT(drive) ||
......@@ -966,7 +966,7 @@ static int wait_for_completion(int delay, timeout_fn function)
return 1;
}
if (jiffies < delay){
if (jiffies - delay < 0){
del_timer(&fd_timer);
fd_timer.function = function;
fd_timer.expires = delay;
......@@ -1415,7 +1415,7 @@ static void setup_rw_floppy(void)
* again just before spinup completion. Beware that
* after scandrives, we must again wait for selection.
*/
if (ready_date > jiffies + DP->select_delay){
if (ready_date - jiffies > DP->select_delay){
ready_date -= DP->select_delay;
function = (timeout_fn) floppy_start;
} else
......@@ -1685,9 +1685,13 @@ void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs)
} while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2);
}
if (handler) {
/* expected interrupt */
floppy_tq.routine = (void *)(void *) handler;
queue_task_irq(&floppy_tq, &tq_timer);
if(intr_count >= 2) {
/* expected interrupt */
floppy_tq.routine = (void *)(void *) handler;
queue_task_irq(&floppy_tq, &tq_immediate);
mark_bh(IMMEDIATE_BH);
} else
handler();
} else
FDCS->reset = 1;
is_alive("normal interrupt end");
......@@ -1925,7 +1929,8 @@ static int wait_til_done(void (*handler)(void), int interruptible)
unsigned long flags;
floppy_tq.routine = (void *)(void *) handler;
queue_task(&floppy_tq, &tq_timer);
queue_task(&floppy_tq, &tq_immediate);
mark_bh(IMMEDIATE_BH);
INT_OFF;
while(command_status < 2 && NO_SIGNAL){
is_alive("wait_til_done");
......@@ -2733,7 +2738,8 @@ static void redo_fd_request(void)
if (TESTF(FD_NEED_TWADDLE))
twaddle();
floppy_tq.routine = (void *)(void *) floppy_start;
queue_task(&floppy_tq, &tq_timer);
queue_task(&floppy_tq, &tq_immediate);
mark_bh(IMMEDIATE_BH);
#ifdef DEBUGT
debugt("queue fd request");
#endif
......@@ -2754,7 +2760,8 @@ static struct tq_struct request_tq =
static void process_fd_request(void)
{
cont = &rw_cont;
queue_task(&request_tq, &tq_timer);
queue_task(&request_tq, &tq_immediate);
mark_bh(IMMEDIATE_BH);
}
static void do_fd_request(void)
......@@ -3649,7 +3656,7 @@ static int check_floppy_change(kdev_t dev)
if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY))
return 1;
if (UDRS->last_checked + UDP->checkfreq < jiffies){
if (UDP->checkfreq < jiffies - UDRS->last_checked){
lock_fdc(drive,0);
poll_drive(0,0);
process_fd_request();
......
......@@ -141,6 +141,16 @@ else
endif
endif
ifeq ($(CONFIG_PCWATCHDOG),y)
M = y
L_OBJS += pcwd.o
else
ifeq ($(CONFIG_PCWATCHDOG),m)
M_OBJS += pcwd.o
MM = m
endif
endif
ifdef CONFIG_SUN_MOUSE
M = y
endif
......@@ -194,16 +204,6 @@ else
endif
endif
ifeq ($(CONFIG_PCWATCHDOG),y)
M = y
L_OBJS += pcwd.o
else
ifeq ($(CONFIG_PCWATCHDOG),m)
M_OBJS += pcwd.o
MM = m
endif
endif
ifeq ($(CONFIG_BAYCOM),y)
L_OBJS += baycom.o
else
......
......@@ -482,7 +482,7 @@ int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
*/
static void gotoxy(int currcons, int new_x, int new_y)
{
int max_y;
int min_y, max_y;
if (new_x < 0)
x = 0;
......@@ -492,21 +492,28 @@ static void gotoxy(int currcons, int new_x, int new_y)
else
x = new_x;
if (decom) {
new_y += top;
min_y = top;
max_y = bottom;
} else
} else {
min_y = 0;
max_y = video_num_lines;
if (new_y < 0)
y = 0;
}
if (new_y < min_y)
y = min_y;
else if (new_y >= max_y)
y = max_y - 1;
else
if (new_y >= max_y)
y = max_y - 1;
else
y = new_y;
y = new_y;
pos = origin + y*video_size_row + (x<<1);
need_wrap = 0;
}
/* for absolute user moves, when decom is set */
static void gotoxay(int currcons, int new_x, int new_y)
{
gotoxy(currcons, new_x, decom ? (top+new_y) : new_y);
}
/*
* Hardware scrollback support
*/
......@@ -1075,7 +1082,7 @@ static void set_mode(int currcons, int on_off)
break;
case 6: /* Origin relative/absolute */
decom = on_off;
gotoxy(currcons,0,0);
gotoxay(currcons,0,0);
break;
case 7: /* Autowrap on/off */
decawm = on_off;
......@@ -1683,12 +1690,12 @@ static int con_write(struct tty_struct * tty, int from_user,
continue;
case 'd':
if (par[0]) par[0]--;
gotoxy(currcons,x,par[0]);
gotoxay(currcons,x,par[0]);
continue;
case 'H': case 'f':
if (par[0]) par[0]--;
if (par[1]) par[1]--;
gotoxy(currcons,par[1],par[0]);
gotoxay(currcons,par[1],par[0]);
continue;
case 'J':
csi_J(currcons,par[0]);
......@@ -1739,7 +1746,7 @@ static int con_write(struct tty_struct * tty, int from_user,
par[1] <= video_num_lines) {
top=par[0]-1;
bottom=par[1];
gotoxy(currcons,0,0);
gotoxay(currcons,0,0);
}
continue;
case 's':
......
......@@ -29,6 +29,9 @@ void soundcard_init(void);
#ifdef CONFIG_ISDN
void isdn_init(void);
#endif
#ifdef CONFIG_PCWATCHDOG
void pcwatchdog_init(void);
#endif
static int read_ram(struct inode * inode, struct file * file, char * buf, int count)
{
......@@ -392,6 +395,7 @@ int chr_dev_init(void)
#if defined (CONFIG_BUSMOUSE) || defined(CONFIG_UMISC) || \
defined (CONFIG_PSMOUSE) || defined (CONFIG_MS_BUSMOUSE) || \
defined (CONFIG_ATIXL_BUSMOUSE) || defined(CONFIG_SOFT_WATCHDOG) || \
defined (CONFIG_PCWATCHDOG) || \
defined (CONFIG_APM) || defined (CONFIG_RTC) || defined (CONFIG_SUN_MOUSE)
misc_init();
#endif
......@@ -401,9 +405,6 @@ int chr_dev_init(void)
#if CONFIG_QIC02_TAPE
qic02_tape_init();
#endif
#ifdef CONFIG_PCWATCHDOG
pcwatchdog_init();
#endif
#if CONFIG_ISDN
isdn_init();
#endif
......
......@@ -67,6 +67,7 @@ extern int ms_bus_mouse_init(void);
extern int atixl_busmouse_init(void);
extern int sun_mouse_init(void);
extern void watchdog_init(void);
extern void pcwatchdog_init(void);
extern int rtc_init(void);
#ifdef CONFIG_PROC_FS
......@@ -218,6 +219,9 @@ int misc_init(void)
#ifdef CONFIG_SOFT_WATCHDOG
watchdog_init();
#endif
#ifdef CONFIG_PCWATCHDOG
pcwatchdog_init();
#endif
#ifdef CONFIG_APM
apm_bios_init();
#endif
......
......@@ -13,6 +13,8 @@
* inclusion in Linux 2.0.x kernels, thanks to Alan Cox.
* 960717 Removed read/seek routines, replaced with ioctl. Also, added
* check_region command due to Alan's suggestion.
* 960821 Made changes to compile in newer 2.0.x kernels. Added
* "cold reboot sense" entry.
*/
#include <linux/module.h>
......@@ -35,7 +37,7 @@
#include <asm/io.h>
#define WD_VER "0.41 (07/17/96)"
#define WD_VER "0.50 (08/21/96)"
#define WD_MINOR 130 /* Minor device number */
#define WD_TIMEOUT 3 /* 1 1/2 seconds for a timeout */
......@@ -160,7 +162,11 @@ void pcwd_showprevstate(void)
printk("pcwd: Previous reboot was caused by the card.\n");
if (card_status & WD_T110)
printk("pcwd: CPU overheat sense\n");
printk("pcwd: CPU overheat sense.\n");
if ((!(card_status & WD_WDRST)) &&
(!(card_status & WD_T110)))
printk("pcwd: Cold boot sense.\n");
}
static int pcwd_return_data(void)
......@@ -190,7 +196,7 @@ static int pcwd_write(struct inode *inode, struct file *file, const char *data,
return(1);
}
static int pcwd_ioctl(struct tty_struct *tty, struct file *file,
static int pcwd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
int i, cdat, rv;
......@@ -246,7 +252,7 @@ static void pcwd_close(struct inode *ino, struct file *filep)
MOD_DEC_USE_COUNT;
}
struct file_operations pcwd_fops = {
static struct file_operations pcwd_fops = {
NULL, /* Seek */
NULL, /* Read */
pcwd_write, /* Write */
......@@ -255,8 +261,7 @@ struct file_operations pcwd_fops = {
pcwd_ioctl, /* IOctl */
NULL, /* MMAP */
pcwd_open, /* Open */
pcwd_close, /* Close */
NULL
pcwd_close /* Close */
};
static struct miscdevice pcwd_miscdev = {
......@@ -295,12 +300,12 @@ int pcwatchdog_init(void)
current_readport = WD_CTLSTAT_PORT2;
if (!pcwd_checkcard()) {
printk("pcwd: No card detected.\n");
printk("pcwd: No card detected, or wrong port assigned.\n");
return(-EIO);
} else
printk("pcwd: Port available at 0x370.\n");
printk("pcwd: Watchdog Rev.A detected at port 0x370\n");
} else
printk("pcwd: Port available at 0x270.\n");
printk("pcwd: Watchdog Rev.A detected at port 0x270\n");
pcwd_showprevstate();
......@@ -308,7 +313,7 @@ int pcwatchdog_init(void)
printk("pcwd: Requesting region entry\n");
#endif
request_region(current_ctlport, WD_PORT_EXTENT, "PCWD (Berkshire)");
request_region(current_ctlport, WD_PORT_EXTENT, "PCWD Rev.A (Berkshire)");
#ifdef DEBUG
printk("pcwd: character device creation.\n");
......@@ -329,3 +334,20 @@ void cleanup_module(void)
#endif
}
#endif
/*
** TODO:
**
** Both Revisions:
** o) Support for revision B of the Watchdog Card
** o) Implement the rest of the IOCTLs as discussed with Alan Cox
** o) Implement only card heartbeat reset via IOCTL, not via write
** o) Faster card detection routines
** o) /proc device creation
**
** Revision B functions:
** o) /dev/temp device creation for temperature device (possibly use
** the one from the WDT drivers?)
** o) Direct Motorola controller chip access via read/write routines
** o) Autoprobe IO Ports for autodetection (possibly by chip detect?)
*/
......@@ -25,6 +25,9 @@
* Rearranged SIGIO support to use code from tty_io. 9Sept95 ctm@ardi.com
*
* Modularised 8-Sep-95 Philip Blundell <pjb27@cam.ac.uk>
*
* Fixed keyboard lockups at open time
* 3-Jul-96, 22-Aug-96 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
*/
/* Uncomment the following line if your mouse needs initialization. */
......@@ -35,6 +38,7 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/fcntl.h>
#include <linux/errno.h>
#include <linux/timer.h>
......@@ -258,10 +262,14 @@ static void release_aux(struct inode * inode, struct file * file)
fasync_aux(inode, file, 0);
if (--aux_count)
return;
/* disable kbd bh to avoid mixing of cmd bytes */
disable_bh(KEYBOARD_BH);
aux_write_cmd(AUX_INTS_OFF); /* disable controller ints */
poll_aux_status();
outb_p(AUX_DISABLE,AUX_COMMAND); /* Disable Aux device */
poll_aux_status();
/* reenable kbd bh */
enable_bh(KEYBOARD_BH);
free_irq(AUX_IRQ, NULL);
MOD_DEC_USE_COUNT;
}
......@@ -316,11 +324,16 @@ static int open_aux(struct inode * inode, struct file * file)
return -EBUSY;
}
MOD_INC_USE_COUNT;
/* disable kbd bh to avoid mixing of cmd bytes */
disable_bh(KEYBOARD_BH);
poll_aux_status();
outb_p(AUX_ENABLE,AUX_COMMAND); /* Enable Aux */
aux_write_dev(AUX_ENABLE_DEV); /* enable aux device */
aux_write_cmd(AUX_INTS_ON); /* enable controller ints */
poll_aux_status();
/* reenable kbd bh */
enable_bh(KEYBOARD_BH);
aux_ready = 0;
return 0;
}
......@@ -377,18 +390,33 @@ static int open_qp(struct inode * inode, struct file * file)
static int write_aux(struct inode * inode, struct file * file, const char * buffer, int count)
{
int i = count;
while (i--) {
if (!poll_aux_status())
return -EIO;
outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
if (!poll_aux_status())
return -EIO;
outb_p(get_user(buffer++),AUX_OUTPUT_PORT);
int retval = 0;
if (count > 0) {
int written = 0;
/* disable kbd bh to avoid mixing of cmd bytes */
disable_bh(KEYBOARD_BH);
do {
if (!poll_aux_status())
break;
outb_p(AUX_MAGIC_WRITE,AUX_COMMAND);
if (!poll_aux_status())
break;
outb_p(get_user(buffer++),AUX_OUTPUT_PORT);
written++;
} while (--count);
/* reenable kbd bh */
enable_bh(KEYBOARD_BH);
retval = -EIO;
if (written) {
retval = written;
inode->i_mtime = CURRENT_TIME;
}
}
inode->i_mtime = CURRENT_TIME;
return count;
return retval;
}
......
......@@ -687,6 +687,7 @@ static int icn_sendbuf(int channel, struct sk_buff *skb, icn_card * card)
{
int len = skb->len;
unsigned long flags;
struct sk_buff *nskb;
if (len > 4000) {
printk(KERN_WARNING
......@@ -701,8 +702,14 @@ static int icn_sendbuf(int channel, struct sk_buff *skb, icn_card * card)
save_flags(flags);
cli();
card->sndcount[channel] += len;
skb_queue_tail(&card->spqueue[channel], skb);
nskb = skb_clone(skb, GFP_ATOMIC);
if (nskb) {
skb_queue_tail(&card->spqueue[channel], nskb);
dev_kfree_skb(skb, FREE_WRITE);
}
restore_flags(flags);
if (!nskb)
return 0;
}
return len;
}
......
......@@ -50,6 +50,11 @@
- detecting PCMCIA Card Removal in interrupt handler. if
ISRP is FF, then a PCMCIA card has been removed
Changes by Paul Norton (pnorton@cts.com) :
- restructured the READ.LOG logic to prevent the transmit SRB
from being rudely overwritten before the transmit cycle is
complete. (August 15 1996)
Warnings !!!!!!!!!!!!!!
This driver is only partially sanitized for support of multiple
adapters. It will almost definitely fail if more than one
......@@ -168,6 +173,7 @@ static int tok_open(struct device *dev);
static int tok_close(struct device *dev);
static int tok_send_packet(struct sk_buff *skb, struct device *dev);
static struct enet_statistics * tok_get_stats(struct device *dev);
void tr_readlog(struct device *dev);
static struct timer_list tr_timer={NULL,NULL,0,0L,tok_open_adapter};
......@@ -331,6 +337,7 @@ int tok_probe(struct device *dev)
memset(ti, 0, sizeof(struct tok_info));
ti->mmio= t_mmio;
ti->readlog_pending = 0;
dev->priv = ti; /* this seems like the logical use of the
field ... let's try some empirical tests
......@@ -730,6 +737,7 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
ti->current_skb=NULL;
}
dev->tbusy=0;
if (ti->readlog_pending) tr_readlog(dev);
}
}
break;
......@@ -746,6 +754,7 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
ti->current_skb=NULL;
}
dev->tbusy=0;
if (ti->readlog_pending) tr_readlog(dev);
}
}
break;
......@@ -761,7 +770,7 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
ti->current_skb=NULL;
open_ret_code = readb(ti->init_srb +offsetof(struct srb_open_response, ret_code));
open_error_code = readw(ti->init_srb +offsetof(struct srb_open_response, error_code));
open_error_code = ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, error_code)));
if (open_ret_code==7) {
......@@ -774,7 +783,7 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
DPRINTK("retrying open to adjust to ring speed\n");
else if ((open_error_code==0x2d) && ti->auto_ringspeedsave)
DPRINTK("No signal detected for Auto Speed Detection\n");
else DPRINTK("Unrecoverable error: error code = %02X\n",
else DPRINTK("Unrecoverable error: error code = %04x\n",
open_error_code);
} else if (!open_ret_code) {
......@@ -887,10 +896,6 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
case REC_DATA:
case XMIT_UI_FRAME:
case XMIT_DIR_FRAME:
if (readb(ti->asb+2)!=0xff) /* checks ret_code */
DPRINTK("ASB error %02X in cmd %02X\n",
(int)readb(ti->asb+2),
(int)readb(ti->asb));
break;
default:
......@@ -899,6 +904,9 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
} /* ASB command check */
if (readb(ti->asb+2)!=0xff) /* checks ret_code */
DPRINTK("ASB error %02X in cmd %02X\n",
(int)readb(ti->asb+2),(int)readb(ti->asb));
writeb(~ASB_FREE_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
} /* ASB response */
......@@ -938,14 +946,10 @@ void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
DPRINTK("New ring status: %02X\n", ring_status);
if (ring_status & LOG_OVERFLOW) {
writeb(DIR_READ_LOG, ti->srb);
writeb(INT_ENABLE,
ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
writeb(CMD_IN_SRB,
ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
dev->tbusy=1; /* really srb busy... */
if (dev->tbusy)
ti->readlog_pending = 1;
else
tr_readlog(dev);
}
}
break;
......@@ -1269,6 +1273,7 @@ static void tr_tx(struct device *dev)
dev_kfree_skb(ti->current_skb,FREE_WRITE);
ti->current_skb=NULL;
mark_bh(NET_BH);
if (ti->readlog_pending) tr_readlog(dev);
}
static void tr_rx(struct device *dev)
......@@ -1468,7 +1473,18 @@ static int tok_send_packet(struct sk_buff *skb, struct device *dev)
}
return 0;
}
}
void tr_readlog(struct device *dev) {
struct tok_info *ti;
ti=(struct tok_info *) dev->priv;
ti->readlog_pending = 0;
writeb(DIR_READ_LOG, ti->srb);
writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
dev->tbusy=1; /* really srb busy... */
}
/* tok_get_stats(): Basically a scaffold routine which will return
the address of the tr_statistics structure associated with
......@@ -1493,16 +1509,21 @@ static struct device dev_ibmtr = {
0, 0, 0, NULL, tok_probe };
static int io = 0xa20;
static char *device = NULL;
int init_module(void)
{
if (device)
strcpy(dev_ibmtr.name,device);
else if (!dev_ibmtr.name[0]) strcpy(dev_ibmtr.name,"tr0");
if (io == 0)
printk("ibmtr: You should not use auto-probing with insmod!\n");
dev_ibmtr.base_addr = io;
dev_ibmtr.irq = 0;
if (register_netdev(&dev_ibmtr) != 0) {
printk("ibmtr: register_netdev() returned non-zero.\n");
printk("ibmtr: No adapters were found.\n");
return -EIO;
}
return 0;
......
......@@ -206,6 +206,7 @@ struct tok_info {
struct tr_statistics tr_stats;
unsigned char auto_ringspeedsave;
open_state open_status;
unsigned char readlog_pending;
};
/* token ring adapter commands */
......
......@@ -30,9 +30,10 @@
to Donald Becker. I didn't receive any answer on all my letters
to him. Who knows why... But may be you are more lucky? ;-)
SAW
Fixed 7990 autoIRQ failure and reversed unneeded alignment. 8/20/96 djb
*/
static const char *version = "lance.c:v1.08.02 Mar 17 1996 tsbogend@bigbug.franken.de\n";
static const char *version = "lance.c:v1.09 Aug 20 1996 dplatt@3do.com, becker@cesdis.gsfc.nasa.gov\n";
#include <linux/config.h>
#include <linux/kernel.h>
......@@ -314,7 +315,8 @@ int lance_init(void)
#if defined(CONFIG_PCI)
if (pcibios_present()) {
int pci_index;
printk("lance.c: PCI bios is present, checking for devices...\n");
if (lance_debug > 1)
printk("lance.c: PCI bios is present, checking for devices...\n");
for (pci_index = 0; pci_index < 8; pci_index++) {
unsigned char pci_bus, pci_device_fn;
unsigned int pci_ioaddr;
......@@ -449,16 +451,19 @@ void lance_probe1(int ioaddr)
}
#endif
/* Make certain the data structures used by the LANCE are aligned and DMAble. */
lp = (struct lance_private *) LANCE_KMALLOC(sizeof(*lp));
lp = (struct lance_private *)(((unsigned long)kmalloc(sizeof(*lp)+7,
GFP_DMA | GFP_KERNEL)+7) & ~7);
if (lance_debug > 6) printk(" (#0x%05lx)", (unsigned long)lp);
memset(lp, 0, sizeof(*lp));
dev->priv = lp;
lp->name = chipname;
/* I'm not sure that buffs also must be aligned but it's safer to do it -- SAW */
lp->rx_buffs = (unsigned long) LANCE_KMALLOC(PKT_BUF_SZ*RX_RING_SIZE);
lp->tx_bounce_buffs = NULL;
lp->rx_buffs = (unsigned long)kmalloc(PKT_BUF_SZ*RX_RING_SIZE,
GFP_DMA | GFP_KERNEL);
if (lance_need_isa_bounce_buffers)
lp->tx_bounce_buffs = LANCE_KMALLOC(PKT_BUF_SZ*TX_RING_SIZE);
lp->tx_bounce_buffs = kmalloc(PKT_BUF_SZ*TX_RING_SIZE,
GFP_DMA | GFP_KERNEL);
else
lp->tx_bounce_buffs = NULL;
lp->chip_version = lance_version;
......@@ -516,7 +521,7 @@ void lance_probe1(int ioaddr)
}
if (dev->irq >= 2)
printk(" assigned IRQ %d", dev->irq);
else {
else if (lance_version != 0) { /* 7990 boards need DMA detection first. */
/* To auto-IRQ we enable the initialization-done and DMA error
interrupts. For ISA boards we get a DMA error, but VLB and PCI
boards will work. */
......@@ -525,7 +530,7 @@ void lance_probe1(int ioaddr)
/* Trigger an initialization just for the interrupt. */
outw(0x0041, ioaddr+LANCE_DATA);
dev->irq = autoirq_report(1);
dev->irq = autoirq_report(2);
if (dev->irq)
printk(", probed IRQ %d", dev->irq);
else {
......@@ -583,6 +588,20 @@ void lance_probe1(int ioaddr)
}
}
if (lance_version == 0 && dev->irq == 0) {
/* We may auto-IRQ now that we have a DMA channel. */
/* Trigger an initialization just for the interrupt. */
autoirq_setup(0);
outw(0x0041, ioaddr+LANCE_DATA);
dev->irq = autoirq_report(4);
if (dev->irq == 0) {
printk(" Failed to detect the 7990 IRQ line.\n");
return;
}
printk(" Auto-IRQ detected IRQ%d.\n", dev->irq);
}
if (chip_table[lp->chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
/* Turn on auto-select of media (10baseT or BNC) so that the user
can watch the LEDs even if the board isn't opened. */
......
......@@ -179,6 +179,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
struct elf_phdr *elf_phdata = NULL;
struct elf_phdr *eppnt;
unsigned long load_addr;
int load_addr_set = 0;
int elf_exec_fileno;
int retval;
unsigned long last_bss, elf_bss;
......@@ -247,7 +248,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
if (eppnt->p_flags & PF_R) elf_prot = PROT_READ;
if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
if (interp_elf_ex->e_type == ET_EXEC || load_addr != 0) {
if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) {
elf_type |= MAP_FIXED;
vaddr = eppnt->p_vaddr;
}
......@@ -266,8 +267,10 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
return ~0UL;
}
if (!load_addr && interp_elf_ex->e_type == ET_DYN)
if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) {
load_addr = error;
load_addr_set = 1;
}
/*
* Find the end of the file mapping for this phdr, and keep
......@@ -365,6 +368,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
struct exec interp_ex;
struct inode *interpreter_inode;
unsigned long load_addr;
int load_addr_set = 0;
unsigned int interpreter_type = INTERPRETER_NONE;
unsigned char ibcs2_interpreter;
int i;
......@@ -588,8 +592,10 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
elf_stack = ELF_PAGESTART(elf_ppnt->p_vaddr);
#endif
if (!load_addr)
if (!load_addr_set) {
load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset;
load_addr_set = 1;
}
k = elf_ppnt->p_vaddr;
if (k < start_code) start_code = k;
k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
......
......@@ -860,13 +860,16 @@ static int get_statm(int pid, char * buffer)
* f_pos = (number of the vma in the task->mm->mmap list) * MAPS_LINE_LENGTH
* + (index into the line)
*/
#ifdef __alpha__
#define MAPS_LINE_FORMAT "%016lx-%016lx %s %016lx %s %lu\n"
#define MAPS_LINE_MAX 73 /* sum of 16 1 16 1 4 1 16 1 5 1 10 1 */
#else
#define MAPS_LINE_FORMAT "%08lx-%08lx %s %08lx %s %lu\n"
#define MAPS_LINE_MAX 49 /* sum of 8 1 8 1 4 1 8 1 5 1 10 1 */
#endif
/* for systems with sizeof(void*) == 4: */
#define MAPS_LINE_FORMAT4 "%08lx-%08lx %s %08lx %s %lu\n"
#define MAPS_LINE_MAX4 49 /* sum of 8 1 8 1 4 1 8 1 5 1 10 1 */
/* for systems with sizeof(void*) == 8: */
#define MAPS_LINE_FORMAT8 "%016lx-%016lx %s %016lx %s %lu\n"
#define MAPS_LINE_MAX8 73 /* sum of 16 1 16 1 4 1 16 1 5 1 10 1 */
#define MAPS_LINE_MAX MAPS_LINE_MAX8
static int read_maps (int pid, struct file * file, char * buf, int count)
{
......@@ -918,7 +921,8 @@ static int read_maps (int pid, struct file * file, char * buf, int count)
ino = 0;
}
len = sprintf(line, MAPS_LINE_FORMAT,
len = sprintf(line,
sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8,
map->vm_start, map->vm_end, str, map->vm_offset,
kdevname(dev), ino);
......
......@@ -38,11 +38,12 @@
* (assuming they are running OSF/1 PALcode, I guess).
*/
struct el_common {
unsigned int size; /* size in bytes of logout area */
int sbz1 : 31; /* should be zero */
char retry : 1; /* retry flag */
unsigned int proc_offset; /* processor-specific offset */
unsigned int sys_offset; /* system-specific offset */
unsigned int size; /* size in bytes of logout area */
int sbz1 : 31; /* should be zero */
char retry : 1; /* retry flag */
unsigned int proc_offset; /* processor-specific offset */
unsigned int sys_offset; /* system-specific offset */
unsigned long code; /* machine check code */
};
extern void wrent(void *, unsigned long);
......
......@@ -81,7 +81,7 @@ extern void enable_irq(unsigned int);
* a bit - without them it seems that the harddisk driver won't work on
* all hardware. Arghh.
*/
#define ACK_FIRST(mask) \
#define ACK_FIRST(mask,nr) \
"inb $0x21,%al\n\t" \
"jmp 1f\n" \
"1:\tjmp 1f\n" \
......@@ -90,10 +90,10 @@ extern void enable_irq(unsigned int);
"outb %al,$0x21\n\t" \
"jmp 1f\n" \
"1:\tjmp 1f\n" \
"1:\tmovb $0x20,%al\n\t" \
"1:\tmovb $0x60+"#nr",%al\n\t" \
"outb %al,$0x20\n\t"
#define ACK_SECOND(mask) \
#define ACK_SECOND(mask,nr) \
"inb $0xA1,%al\n\t" \
"jmp 1f\n" \
"1:\tjmp 1f\n" \
......@@ -102,11 +102,12 @@ extern void enable_irq(unsigned int);
"outb %al,$0xA1\n\t" \
"jmp 1f\n" \
"1:\tjmp 1f\n" \
"1:\tmovb $0x20,%al\n\t" \
"1:\tmovb $0x60+"#nr",%al\n\t" \
"outb %al,$0xA0\n\t" \
"jmp 1f\n" \
"1:\tjmp 1f\n" \
"1:\toutb %al,$0x20\n\t"
"1:\tmovb $0x62,%al\n\t" \
"outb %al,$0x20\n\t"
#define UNBLK_FIRST(mask) \
"inb $0x21,%al\n\t" \
......@@ -207,7 +208,7 @@ SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
"pushl $-"#nr"-2\n\t" \
SAVE_ALL \
ENTER_KERNEL \
ACK_##chip(mask) \
ACK_##chip(mask,(nr&7)) \
"incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
"sti\n\t" \
"movl %esp,%ebx\n\t" \
......@@ -224,7 +225,7 @@ SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
SAVE_MOST \
ENTER_KERNEL \
ACK_##chip(mask) \
ACK_##chip(mask,(nr&7)) \
"incl "SYMBOL_NAME_STR(intr_count)"\n\t" \
"pushl $" #nr "\n\t" \
"call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
......@@ -238,7 +239,7 @@ SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
SAVE_MOST \
ENTER_KERNEL \
ACK_##chip(mask) \
ACK_##chip(mask,(nr&7)) \
LEAVE_KERNEL \
RESTORE_MOST);
......@@ -255,7 +256,7 @@ SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
"pushl $-"#nr"-2\n\t" \
SAVE_ALL \
ENTER_KERNEL \
ACK_##chip(mask) \
ACK_##chip(mask,(nr&7)) \
"incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
"movl %esp,%ebx\n\t" \
"pushl %ebx\n\t" \
......@@ -283,7 +284,7 @@ SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
"pushl $-"#nr"-2\n\t" \
SAVE_ALL \
ENTER_KERNEL \
ACK_##chip(mask) \
ACK_##chip(mask,(nr&7)) \
"incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
"sti\n\t" \
"movl %esp,%ebx\n\t" \
......@@ -301,7 +302,7 @@ SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
"\n"__ALIGN_STR"\n" \
SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
SAVE_MOST \
ACK_##chip(mask) \
ACK_##chip(mask,(nr&7)) \
SMP_PROF_IPI_CNT \
"pushl $" #nr "\n\t" \
"call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
......@@ -312,7 +313,7 @@ SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
"\n"__ALIGN_STR"\n" \
SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
SAVE_MOST \
ACK_##chip(mask) \
ACK_##chip(mask,(nr&7)) \
RESTORE_MOST);
#define BUILD_RESCHEDIRQ(nr) \
......@@ -345,7 +346,7 @@ __asm__( \
SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
"pushl $-"#nr"-2\n\t" \
SAVE_ALL \
ACK_##chip(mask) \
ACK_##chip(mask,(nr&7)) \
"incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
"sti\n\t" \
"movl %esp,%ebx\n\t" \
......@@ -360,7 +361,7 @@ SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
"\n"__ALIGN_STR"\n" \
SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
SAVE_MOST \
ACK_##chip(mask) \
ACK_##chip(mask,(nr&7)) \
"incl "SYMBOL_NAME_STR(intr_count)"\n\t" \
"pushl $" #nr "\n\t" \
"call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
......@@ -372,7 +373,7 @@ SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
"\n"__ALIGN_STR"\n" \
SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
SAVE_MOST \
ACK_##chip(mask) \
ACK_##chip(mask,(nr&7)) \
RESTORE_MOST);
#define BUILD_TIMER_IRQ(chip,nr,mask) \
......@@ -386,7 +387,7 @@ SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
"pushl $-"#nr"-2\n\t" \
SAVE_ALL \
ACK_##chip(mask) \
ACK_##chip(mask,(nr&7)) \
"incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
"movl %esp,%ebx\n\t" \
"pushl %ebx\n\t" \
......
......@@ -398,70 +398,58 @@ extern inline struct file *file_from_fd(const unsigned int fd)
* to keep them correct. Use only these two functions to add/remove
* entries in the queues.
*/
extern inline void __add_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
{
struct wait_queue *head = *p;
struct wait_queue *next = wait;
if (head) {
next = head->next;
p = &head->next;
}
*p = wait;
wait->next = next;
}
extern inline void add_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
{
unsigned long flags;
#ifdef DEBUG
if (wait->next) {
__label__ here;
unsigned long pc;
pc = (unsigned long) &&here;
here:
printk("add_wait_queue (%08lx): wait->next = %08lx\n",pc,(unsigned long) wait->next);
}
#endif
save_flags(flags);
cli();
if (!*p) {
wait->next = wait;
*p = wait;
} else {
wait->next = (*p)->next;
(*p)->next = wait;
}
__add_wait_queue(p, wait);
restore_flags(flags);
}
extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
extern inline void __remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
{
unsigned long flags;
struct wait_queue * tmp;
#ifdef DEBUG
unsigned long ok = 0;
#endif
struct wait_queue * next = wait->next;
save_flags(flags);
cli();
if ((*p == wait) &&
#ifdef DEBUG
(ok = 1) &&
#endif
((*p = wait->next) == wait)) {
if (wait == next) {
*p = NULL;
} else {
tmp = wait;
while (tmp->next != wait) {
tmp = tmp->next;
#ifdef DEBUG
if (tmp == *p)
ok = 1;
#endif
struct wait_queue *head = *p;
if (head == wait)
*p = next;
for (;;) {
struct wait_queue *nextlist = head->next;
if (nextlist == wait)
break;
head = nextlist;
}
tmp->next = wait->next;
head->next = next;
}
wait->next = NULL;
}
extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
{
unsigned long flags;
save_flags(flags);
cli();
__remove_wait_queue(p, wait);
restore_flags(flags);
#ifdef DEBUG
if (!ok) {
__label__ here;
ok = (unsigned long) &&here;
printk("removed wait_queue not on list.\n");
printk("list = %08lx, queue = %08lx\n",(unsigned long) p, (unsigned long) wait);
here:
printk("eip = %08lx\n",ok);
}
#endif
}
extern inline void select_wait(struct wait_queue ** wait_address, select_table * p)
......
......@@ -501,11 +501,13 @@ static inline void __sleep_on(struct wait_queue **p, int state)
if (current == task[0])
panic("task[0] trying to sleep");
current->state = state;
add_wait_queue(p, &wait);
save_flags(flags);
cli();
__add_wait_queue(p, &wait);
sti();
schedule();
remove_wait_queue(p, &wait);
cli();
__remove_wait_queue(p, &wait);
restore_flags(flags);
}
......
......@@ -117,7 +117,7 @@
* Implement IP packet firewall
*/
#ifdef CONFIG_IP_FIREWALL_DEBUG
#ifdef DEBUG_IP_FIREWALL
#define dprintf1(a) printk(a)
#define dprintf2(a1,a2) printk(a1,a2)
#define dprintf3(a1,a2,a3) printk(a1,a2,a3)
......@@ -134,7 +134,7 @@
(ntohl(a)>>8)&0xFF,\
(ntohl(a))&0xFF);
#ifdef CONFIG_IP_FIREWALL_DEBUG
#ifdef DEBUG_IP_FIREWALL
#define dprint_ip(a) print_ip(a)
#else
#define dprint_ip(a)
......@@ -291,7 +291,7 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, __u16 *redirport, struct ip_
if (!offset) {
src_port=ntohs(tcp->source);
dst_port=ntohs(tcp->dest);
if(!tcp->ack)
if(!tcp->ack && !tcp->rst)
/* We do NOT have ACK, value TRUE */
notcpack=1;
if(!tcp->syn || !notcpack)
......@@ -321,7 +321,7 @@ int ip_fw_chk(struct iphdr *ip, struct device *rif, __u16 *redirport, struct ip_
prt=IP_FW_F_ALL;
break;
}
#ifdef CONFIG_IP_FIREWALL_DEBUG
#ifdef DEBUG_IP_FIREWALL
dprint_ip(ip->saddr);
if (ip->protocol==IPPROTO_TCP || ip->protocol==IPPROTO_UDP)
......@@ -610,7 +610,7 @@ static int insert_in_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,
ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
if ( ftmp == NULL )
{
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: malloc said no\n");
#endif
return( ENOMEM );
......@@ -652,7 +652,7 @@ static int append_to_chain(struct ip_fw *volatile* chainptr, struct ip_fw *frwl,
ftmp = kmalloc( sizeof(struct ip_fw), GFP_ATOMIC );
if ( ftmp == NULL )
{
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: malloc said no\n");
#endif
return( ENOMEM );
......@@ -704,7 +704,7 @@ static int del_from_chain(struct ip_fw *volatile*chainptr, struct ip_fw *frwl)
if ( ftmp == NULL )
{
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: chain is empty\n");
#endif
restore_flags(flags);
......@@ -773,7 +773,7 @@ struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
if ( len != sizeof(struct ip_fw) )
{
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: len=%d, want %d\n",len, sizeof(struct ip_fw));
#endif
return(NULL);
......@@ -781,7 +781,7 @@ struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
if ( (frwl->fw_flg & ~IP_FW_F_MASK) != 0 )
{
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: undefined flag bits set (flags=%x)\n",
frwl->fw_flg);
#endif
......@@ -790,7 +790,7 @@ struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
#ifndef CONFIG_IP_TRANSPARENT_PROXY
if (frwl->fw_flg & IP_FW_F_REDIR) {
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: unsupported flag IP_FW_F_REDIR\n");
#endif
return(NULL);
......@@ -799,7 +799,7 @@ struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
#ifndef CONFIG_IP_MASQUERADE
if (frwl->fw_flg & IP_FW_F_MASQ) {
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: unsupported flag IP_FW_F_MASQ\n");
#endif
return(NULL);
......@@ -808,7 +808,7 @@ struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
if ( (frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2 )
{
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: src range set but fw_nsp=%d\n",
frwl->fw_nsp);
#endif
......@@ -817,7 +817,7 @@ struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
if ( (frwl->fw_flg & IP_FW_F_DRNG) && frwl->fw_ndp < 2 )
{
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: dst range set but fw_ndp=%d\n",
frwl->fw_ndp);
#endif
......@@ -826,7 +826,7 @@ struct ip_fw *check_ipfw_struct(struct ip_fw *frwl, int len)
if ( frwl->fw_nsp + frwl->fw_ndp > (frwl->fw_flg & IP_FW_F_REDIR ? IP_FW_MAX_PORTS - 1 : IP_FW_MAX_PORTS) )
{
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: too many ports (%d+%d)\n",
frwl->fw_nsp,frwl->fw_ndp);
#endif
......@@ -873,13 +873,13 @@ int ip_acct_ctl(int stage, void *m, int len)
/*
* Should be panic but... (Why ??? - AC)
*/
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_acct_ctl: unknown request %d\n",stage);
#endif
return(EINVAL);
}
}
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_acct_ctl: unknown request %d\n",stage);
#endif
return(EINVAL);
......@@ -922,7 +922,7 @@ int ip_fw_ctl(int stage, void *m, int len)
if ( len != sizeof(struct ip_fwpkt) )
{
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: length=%d, expected %d\n",
len, sizeof(struct ip_fwpkt));
#endif
......@@ -933,18 +933,18 @@ int ip_fw_ctl(int stage, void *m, int len)
ip = &(ipfwp->fwp_iph);
if ( !(viadev = dev_get(ipfwp->fwp_vianame)) ) {
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: invalid device \"%s\"\n", ipfwp->fwp_vianame);
#endif
return(EINVAL);
} else if ( viadev->pa_addr != ipfwp->fwp_via.s_addr ) {
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: device \"%s\" has another IP address\n",
ipfwp->fwp_vianame);
#endif
return(EINVAL);
} else if ( ip->ihl != sizeof(struct iphdr) / sizeof(int)) {
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: ip->ihl=%d, want %d\n",ip->ihl,
sizeof(struct iphdr)/sizeof(int));
#endif
......@@ -974,7 +974,7 @@ int ip_fw_ctl(int stage, void *m, int len)
if ( len != sizeof(struct ip_fw_masq) )
{
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl (masq): length %d, expected %d\n",
len, sizeof(struct ip_fw_masq));
......@@ -1032,14 +1032,14 @@ int ip_fw_ctl(int stage, void *m, int len)
/*
* Should be panic but... (Why are BSD people panic obsessed ??)
*/
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: unknown request %d\n",stage);
#endif
return(EINVAL);
}
}
#ifdef DEBUG_CONFIG_IP_FIREWALL
#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: unknown request %d\n",stage);
#endif
return(EINVAL);
......
......@@ -867,15 +867,24 @@ static inline int tcp_memory_free(struct sock *sk)
static void wait_for_tcp_memory(struct sock * sk)
{
release_sock(sk);
cli();
if (!tcp_memory_free(sk) &&
(sk->state == TCP_ESTABLISHED||sk->state == TCP_CLOSE_WAIT)
&& sk->err == 0 /* && check shutdown ?? */)
{
if (!tcp_memory_free(sk)) {
struct wait_queue wait = { current, NULL };
sk->socket->flags &= ~SO_NOSPACE;
interruptible_sleep_on(sk->sleep);
add_wait_queue(sk->sleep, &wait);
for (;;) {
current->state = TASK_INTERRUPTIBLE;
if (tcp_memory_free(sk))
break;
if (sk->shutdown & SEND_SHUTDOWN)
break;
if (sk->err)
break;
schedule();
}
current->state = TASK_RUNNING;
remove_wait_queue(sk->sleep, &wait);
}
sti();
lock_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