VERSION = 2
PATCHLEVEL = 0
-SUBLEVEL = 14
+SUBLEVEL = 15
ARCH = i386
{
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) ||
return 1;
}
- if (jiffies < delay){
+ if (jiffies - delay < 0){
del_timer(&fd_timer);
fd_timer.function = function;
fd_timer.expires = delay;
* 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
} 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");
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");
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
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)
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();
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
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
*/
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;
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
*/
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;
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]);
par[1] <= video_num_lines) {
top=par[0]-1;
bottom=par[1];
- gotoxy(currcons,0,0);
+ gotoxay(currcons,0,0);
}
continue;
case 's':
#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)
{
#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
#if CONFIG_QIC02_TAPE
qic02_tape_init();
#endif
-#ifdef CONFIG_PCWATCHDOG
- pcwatchdog_init();
-#endif
#if CONFIG_ISDN
isdn_init();
#endif
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
#ifdef CONFIG_SOFT_WATCHDOG
watchdog_init();
#endif
+#ifdef CONFIG_PCWATCHDOG
+ pcwatchdog_init();
+#endif
#ifdef CONFIG_APM
apm_bios_init();
#endif
* 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>
#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 */
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)
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;
MOD_DEC_USE_COUNT;
}
-struct file_operations pcwd_fops = {
+static struct file_operations pcwd_fops = {
NULL, /* Seek */
NULL, /* Read */
pcwd_write, /* Write */
pcwd_ioctl, /* IOctl */
NULL, /* MMAP */
pcwd_open, /* Open */
- pcwd_close, /* Close */
- NULL
+ pcwd_close /* Close */
};
static struct miscdevice pcwd_miscdev = {
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();
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");
#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?)
+*/
* 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. */
#include <linux/sched.h>
#include <linux/kernel.h>
+#include <linux/interrupt.h>
#include <linux/fcntl.h>
#include <linux/errno.h>
#include <linux/timer.h>
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;
}
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;
}
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;
}
{
int len = skb->len;
unsigned long flags;
+ struct sk_buff *nskb;
if (len > 4000) {
printk(KERN_WARNING
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;
}
- 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
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};
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
ti->current_skb=NULL;
}
dev->tbusy=0;
+ if (ti->readlog_pending) tr_readlog(dev);
}
}
break;
ti->current_skb=NULL;
}
dev->tbusy=0;
+ if (ti->readlog_pending) tr_readlog(dev);
}
}
break;
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) {
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) {
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:
} /* 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 */
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;
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)
}
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
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;
struct tr_statistics tr_stats;
unsigned char auto_ringspeedsave;
open_state open_status;
+ unsigned char readlog_pending;
};
/* token ring adapter commands */
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>
#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;
}
#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;
}
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. */
/* 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 {
}
}
+ 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. */
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;
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;
}
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
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;
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;
* 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)
{
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);
* (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);
* 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" \
"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" \
"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" \
"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" \
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" \
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);
"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" \
"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" \
"\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" \
"\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) \
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" \
"\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" \
"\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) \
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" \
* 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)
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);
}
* 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)
(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)
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)
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)
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 );
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 );
if ( ftmp == NULL )
{
-#ifdef DEBUG_CONFIG_IP_FIREWALL
+#ifdef DEBUG_IP_FIREWALL
printk("ip_fw_ctl: chain is empty\n");
#endif
restore_flags(flags);
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);
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
#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);
#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);
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
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
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
/*
* 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);
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
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
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));
/*
* 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);
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);
}