Commit 98606bdd authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.13

parent 16119ae5
This file is a registry of magic numbers which are in use. When you
add a magic number to a structure, you should also add it to this
file, since it is best if the magic numbers used by various structures
are unique.
It is a *very* good idea to protect kernel data structures with magic
numbers. This allows you to check at run time whether (a) a structure
has been clobbered, or (b) you've passed the wrong structure to a
routine. This last is especially useful --- particlarly when you are
passing pointers to structures via a void * pointer. The tty code,
for example, does this frequently to pass driver-specific and line
discipline-specific structures back and forth.
The way to use magic numbers is to declare then at the beginning of
the structure, like so:
struct tty_ldisc {
int magic;
...
};
Please follow this discpline when you are adding future enhancements
to the kernel! It has saved me countless hours of debugging,
especially in the screw cases where an array has been overrun and
structures following the array have been overwritten. Using this
discpline, these cases get detected quickly and safely.
Theodore Ts'o
31-Mar-94
Magic Name Number Structure File
===========================================================================
FASYNC_MAGIC 0x4601 struct fasync_struct include/linux/fs.h
PTY_MAGIC 0x5001 struct pty_struct drivers/char/pty.c
PPP_MAGIC 0x5002 struct ppp_struct include/linux/ppp.h
TTY_MAGIC 0x5401 struct tty_struct include/linux/tty.h
TTY_DRIVER_MAGIC 0x5402 struct tty_driver include/linux/tty_driver.h
TTY_LDISC_MAGIC 0x5403 struct tty_ldisc include/linux/tty_ldisc.h
SERIAL_MAGIC 0x5301 struct async_struct include/linux/serial.h
SLIP_MAGIC 0x5302 struct slip drivers/net/slip.h
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 12
SUBLEVEL = 13
all: Version zImage
......
......@@ -5,24 +5,24 @@
comment 'General setup'
bool 'Kernel math emulation' CONFIG_MATH_EMULATION y
bool 'Kernel math emulation' CONFIG_MATH_EMULATION n
bool 'Normal harddisk support' CONFIG_BLK_DEV_HD y
bool 'XT harddisk support' CONFIG_BLK_DEV_XD n
bool 'TCP/IP networking' CONFIG_INET y
bool 'Networking support' CONFIG_NET y
bool 'Limit memory to low 16MB' CONFIG_MAX_16M n
bool 'System V IPC' CONFIG_SYSVIPC y
bool 'Use -m486 flag for 486-specific optimizations' CONFIG_M486 y
if [ "$CONFIG_INET" = "y" ]; then
if [ "$CONFIG_NET" = "y" ]; then
comment 'Networking options'
bool 'TCP/IP networking' CONFIG_INET y
if [ "$CONFIG_INET" "=" "y" ]; then
comment '(it is safe to leave these untouched)'
comment 'IP (required for now) y'
bool 'Reverse ARP' CONFIG_INET_RARP y
bool 'Reverse ARP' CONFIG_INET_RARP n
bool 'Assume subnets are local' CONFIG_INET_SNARL y
bool 'Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n
#bool 'Novell IPX protocol' CONFIG_IPX n
fi
bool 'The IPX protocol' CONFIG_IPX y
#bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n
fi
......@@ -62,10 +62,13 @@ bool 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR n
bool '7000FASST SCSI support' CONFIG_SCSI_7000FASST n
fi
if [ "$CONFIG_NET" = "y" ]; then
comment 'Network device support'
bool 'Network device support?' CONFIG_ETHERCARDS y
if [ "$CONFIG_ETHERCARDS" = "n" ]; then
bool 'Network device support?' CONFIG_NETDEVICES y
if [ "$CONFIG_NETDEVICES" = "n" ]; then
comment 'Skipping ethercard configuration options...'
......@@ -76,15 +79,16 @@ if [ "$CONFIG_SLIP" = "y" ]; then
# bool ' SLIP debugging on' SL_DUMP y
fi
#bool 'PPP (point-to-point) support' CONFIG_PPP n
bool 'Load balancing support (very experimental)' CONFIG_SLAVE_BALANCING n
bool 'PLIP (parallel port) support' CONFIG_PLIP n
bool 'NE2000/NE1000 support' CONFIG_NE2000 n
bool 'WD80*3 support' CONFIG_WD80x3 y
bool 'WD80*3 support' CONFIG_WD80x3 n
bool 'SMC Ultra support' CONFIG_ULTRA n
bool '3c501 support' CONFIG_EL1 n
bool '3c503 support' CONFIG_EL2 n
#bool '3c505 support' CONFIG_ELPLUS n
#bool '3c507 support' CONFIG_EL16 n
bool '3c509/3c579 support' CONFIG_EL3 n
bool '3c509/3c579 support' CONFIG_EL3 y
bool 'HP PCLAN support' CONFIG_HPLAN n
bool 'AT1500 and NE2100 (LANCE and PCnet-ISA) support' CONFIG_LANCE n
bool 'AT1700 support' CONFIG_AT1700 n
......@@ -98,6 +102,7 @@ bool 'DEPCA support' CONFIG_DEPCA n
bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n
bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP n
fi
fi
comment 'CD-ROM drivers'
......@@ -113,7 +118,9 @@ bool 'Second extended fs support' CONFIG_EXT2_FS y
bool 'xiafs filesystem support' CONFIG_XIA_FS n
bool 'msdos fs support' CONFIG_MSDOS_FS y
bool '/proc filesystem support' CONFIG_PROC_FS y
if [ "$CONFIG_INET" = "y" ]; then
bool 'NFS filesystem support' CONFIG_NFS_FS y
fi
bool 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS n
bool 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS n
bool 'System V and Coherent filesystem support' CONFIG_SYSV_FS n
......@@ -122,7 +129,7 @@ comment 'character devices'
bool 'Parallel printer support' CONFIG_PRINTER n
bool 'Logitech busmouse support' CONFIG_BUSMOUSE n
bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE y
bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE n
if [ "$CONFIG_PSMOUSE" = "y" ]; then
bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE y
fi
......
......@@ -103,9 +103,9 @@ typedef void (*FUNC)(void);
typedef struct fpu_reg FPU_REG;
typedef struct { unsigned char address_size, operand_size, segment; }
overrides;
/* This structure is 32 bits: */
/* This structure is 48 bits: */
typedef struct { overrides override;
unsigned char vm86; } fpu_addr_modes;
unsigned char mode16, vm86, p286; } fpu_addr_modes;
#define st(x) ( regs[((top+x) &7 )] )
......
......@@ -173,13 +173,20 @@ asmlinkage void math_emulate(long arg)
SETUP_DATA_AREA(arg);
addr_modes.vm86 = (FPU_EFLAGS & 0x00020000) != 0;
addr_modes.p286 = (!addr_modes.vm86
&& current->ldt
&& (current->ldt[FPU_CS >> 3].b & 0xf000) == 0xf000
&& (current->ldt[FPU_CS >> 3].b & (1 << 22)) == 0);
addr_modes.mode16 = addr_modes.vm86 | addr_modes.p286;
if ( addr_modes.vm86 )
FPU_EIP += FPU_CS << 4;
else if ( addr_modes.p286 )
FPU_EIP += LDT_BASE_ADDR(FPU_CS);
FPU_ORIG_EIP = FPU_EIP;
if ( !addr_modes.vm86 )
if ( !addr_modes.mode16 )
{
/* user code space? */
if (FPU_CS == KERNEL_CS)
......@@ -283,6 +290,8 @@ asmlinkage void math_emulate(long arg)
if ( addr_modes.vm86 )
FPU_EIP -= FPU_CS << 4;
else if ( addr_modes.p286 )
FPU_EIP -= LDT_BASE_ADDR(FPU_CS);
RE_ENTRANT_CHECK_OFF;
current->tss.trap_no = 16;
......@@ -552,6 +561,8 @@ asmlinkage void math_emulate(long arg)
if ( addr_modes.vm86 )
FPU_EIP -= FPU_CS << 4;
else if ( addr_modes.p286 )
FPU_EIP -= LDT_BASE_ADDR(FPU_CS);
RE_ENTRANT_CHECK_OFF;
}
......
......@@ -30,6 +30,10 @@
#define FPU_EIP (FPU_info->___eip)
#define FPU_ORIG_EIP (FPU_info->___orig_eip)
#define LDT_BASE_ADDR(s) ((current->ldt[(s) >> 3].b & 0xff000000) \
| ((current->ldt[(s) >> 3].b & 0xff) << 16) \
| (current->ldt[(s) >> 3].a >> 16))
#define FPU_lookahead (I387.soft.lookahead)
#define FPU_entry_eip (I387.soft.entry_eip)
......
......@@ -52,6 +52,19 @@ static int reg_offset_vm86[] = {
#define VM86_REG_(x) (*(unsigned short *) \
(reg_offset_vm86[((unsigned)x)]+(char *) FPU_info))
static int reg_offset_p286[] = {
offsetof(struct info,___cs),
offsetof(struct info,___ds),
offsetof(struct info,___es),
offsetof(struct info,___fs),
offsetof(struct info,___gs),
offsetof(struct info,___ss),
offsetof(struct info,___ds)
};
#define P286_REG_(x) (*(unsigned short *) \
(reg_offset_p286[((unsigned)x)]+(char *) FPU_info))
/* Decode the SIB byte. This function assumes mod != 0 */
static void *sib(int mod, unsigned long *fpu_eip)
......@@ -108,9 +121,10 @@ static void *sib(int mod, unsigned long *fpu_eip)
}
static unsigned long vm86_segment(unsigned char segment)
static unsigned long mode16_segment(fpu_addr_modes addr_modes)
{
segment--;
int segment = addr_modes.override.segment - 1;
#ifdef PARANOID
if ( segment > PREFIX_SS_ )
{
......@@ -118,7 +132,11 @@ static unsigned long vm86_segment(unsigned char segment)
math_abort(FPU_info,SIGSEGV);
}
#endif PARANOID
return (unsigned long)VM86_REG_(segment) << 4;
if ( addr_modes.vm86 )
return (unsigned long)VM86_REG_(segment) << 4;
else if ( addr_modes.p286 )
return (unsigned long)LDT_BASE_ADDR(P286_REG_(segment));
return 0;
}
......@@ -152,7 +170,7 @@ void get_address(unsigned char FPU_modrm, unsigned long *fpu_eip,
#endif PECULIAR_486
/* Memory accessed via the cs selector is write protected
in 32 bit protected mode. */
in protected mode. */
#define FPU_WRITE_BIT 0x10
if ( !addr_modes.vm86 && (FPU_modrm & FPU_WRITE_BIT)
&& (addr_modes.override.segment == PREFIX_CS_) )
......@@ -210,9 +228,9 @@ void get_address(unsigned char FPU_modrm, unsigned long *fpu_eip,
EXCEPTION(EX_Invalid);
}
if ( addr_modes.vm86 )
if ( addr_modes.mode16 )
{
offset += vm86_segment(addr_modes.override.segment);
offset += mode16_segment(addr_modes);
}
FPU_data_address = offset + (char *)*cpu_reg_ptr;
......@@ -231,7 +249,7 @@ void get_address_16(unsigned char FPU_modrm, unsigned long *fpu_eip,
#endif PECULIAR_486
/* Memory accessed via the cs selector is write protected
in 32 bit protected mode. */
in protected mode. */
#define FPU_WRITE_BIT 0x10
if ( !addr_modes.vm86 && (FPU_modrm & FPU_WRITE_BIT)
&& (addr_modes.override.segment == PREFIX_CS_) )
......@@ -313,9 +331,9 @@ void get_address_16(unsigned char FPU_modrm, unsigned long *fpu_eip,
add_segment:
offset &= 0xffff;
if ( addr_modes.vm86 )
if ( addr_modes.mode16 )
{
offset += vm86_segment(addr_modes.override.segment);
offset += mode16_segment(addr_modes);
}
FPU_data_address = (void *)offset ;
......
......@@ -1170,7 +1170,7 @@ char *fldenv(fpu_addr_modes addr_modes)
unsigned char tag;
int i;
if ( addr_modes.vm86
if ( addr_modes.mode16
|| (addr_modes.override.operand_size == OP_SIZE_PREFIX) )
{
RE_ENTRANT_CHECK_OFF;
......@@ -1189,6 +1189,11 @@ char *fldenv(fpu_addr_modes addr_modes)
ip_offset += (cs_selector & 0xf000) << 4;
data_operand_offset += (operand_selector & 0xf000) << 4;
}
else if ( addr_modes.p286 )
{
ip_offset += LDT_BASE_ADDR(cs_selector);
data_operand_offset += LDT_BASE_ADDR(operand_selector);
}
}
else
{
......@@ -1317,7 +1322,7 @@ char *fstenv(fpu_addr_modes addr_modes)
{
char *d = (char *)FPU_data_address;
if ( addr_modes.vm86
if ( addr_modes.mode16
|| (addr_modes.override.operand_size == OP_SIZE_PREFIX) )
{
RE_ENTRANT_CHECK_OFF;
......
......@@ -16,7 +16,7 @@
.c.o:
$(CC) $(CFLAGS) -c $<
OBJS = tty_io.o console.o keyboard.o serial.o \
OBJS = tty_io.o n_tty.o console.o keyboard.o serial.o \
tty_ioctl.o pty.o vt.o mem.o \
defkeymap.o
......
This diff is collapsed.
......@@ -14,10 +14,11 @@
#define KEYBOARD_IRQ 1
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/mm.h>
#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <linux/config.h>
#include <linux/signal.h>
#include <linux/string.h>
......@@ -26,6 +27,7 @@
#include "kbd_kern.h"
#include "diacr.h"
#include "vt_kern.h"
#define SIZE(x) (sizeof(x)/sizeof((x)[0]))
......@@ -59,7 +61,7 @@
#include <asm/io.h>
#include <asm/system.h>
extern void do_keyboard_interrupt(void);
extern void poke_blanked_console(void);
extern void ctrl_alt_del(void);
extern void change_console(unsigned int new_console);
extern void scrollback(int);
......@@ -89,6 +91,7 @@ static int npadch = -1; /* -1 or number assembled on pad */
static unsigned char diacr = 0;
static char rep = 0; /* flag telling character repeat */
struct kbd_struct kbd_table[NR_CONSOLES];
static struct tty_struct **ttytab;
static struct kbd_struct * kbd = kbd_table;
static struct tty_struct * tty = NULL;
......@@ -110,7 +113,7 @@ static k_hand key_handler[] = {
/* maximum values each key_handler can handle */
const int max_vals[] = {
255, NR_FUNC - 1, 14, 17, 4, 255, 3, NR_SHIFT,
255, NR_FUNC - 1, 15, 17, 4, 255, 3, NR_SHIFT,
255, 9, 3, 255
};
......@@ -118,12 +121,11 @@ const int NR_TYPES = SIZE(max_vals);
static void put_queue(int);
static unsigned char handle_diacr(unsigned char);
static void SAK(void);
/* pt_regs - set by keyboard_interrupt(), used by show_ptregs() */
static struct pt_regs * pt_regs;
static int got_break = 0;
static inline void kb_wait(void)
{
int i;
......@@ -224,7 +226,7 @@ static void keyboard_interrupt(int int_pt_regs)
prev_scancode = 0;
goto end_kbd_intr;
}
tty = TTY_TABLE(0);
tty = ttytab[fg_console];
kbd = kbd_table + fg_console;
if ((raw_mode = vc_kbd_mode(kbd,VC_RAW))) {
put_queue(scancode);
......@@ -332,8 +334,7 @@ static void keyboard_interrupt(int int_pt_regs)
*/
if (!rep ||
(vc_kbd_mode(kbd,VC_REPEAT) && tty &&
(L_ECHO(tty) || (EMPTY(&tty->secondary) && EMPTY(&tty->read_q)))))
{
(L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
u_short key_code;
u_char type;
......@@ -357,36 +358,24 @@ static void keyboard_interrupt(int int_pt_regs)
static void put_queue(int ch)
{
struct tty_queue *qp;
wake_up(&keypress_wait);
if (!tty)
return;
qp = &tty->read_q;
if (LEFT(qp)) {
qp->buf[qp->head] = ch;
INC(qp->head);
if (tty) {
tty_insert_flip_char(tty, ch, 0);
tty_schedule_flip(tty);
}
}
static void puts_queue(char *cp)
{
struct tty_queue *qp;
char ch;
/* why interruptible here, plain wake_up above? */
wake_up_interruptible(&keypress_wait);
wake_up(&keypress_wait);
if (!tty)
return;
qp = &tty->read_q;
while ((ch = *(cp++)) != 0) {
if (LEFT(qp)) {
qp->buf[qp->head] = ch;
INC(qp->head);
}
while (*cp) {
tty_insert_flip_char(tty, *cp, 0);
cp++;
}
tty_schedule_flip(tty);
}
static void applkey(int key, char mode)
......@@ -479,7 +468,9 @@ static void lastcons(void)
static void send_intr(void)
{
got_break = 1;
if (tty->termios && I_IGNBRK(tty))
return;
tty_insert_flip_char(tty, 0, TTY_BREAK);
}
static void scrll_forw(void)
......@@ -502,6 +493,33 @@ static void compose(void)
dead_key_next = 1;
}
static void SAK(void)
{
do_SAK(tty);
#if 0
/*
* Need to fix SAK handling to fix up RAW/MEDIUM_RAW and
* vt_cons modes before we can enable RAW/MEDIUM_RAW SAK
* handling.
*
* We should do this some day --- the whole point of a secure
* attention key is that it should be guaranteed to always
* work.
*/
clr_vc_kbd_flag(kbd, VC_RAW);
clr_vc_kbd_flag(kbd, VC_MEDIUMRAW);
vt_cons[fg_console].vc_mode = KD_TEXT;
vt_cons[fg_console].vt_mode.mode = VT_AUTO;
vt_cons[fg_console].vt_mode.waitv = 0;
vt_cons[fg_console].vt_mode.relsig = 0;
vt_cons[fg_console].vt_mode.acqsig = 0;
vt_cons[fg_console].vt_mode.frsig = 0;
vt_cons[fg_console].vt_pid = -1;
vt_cons[fg_console].vt_newvt = -1;
unblank_screen();
#endif
}
static void do_spec(unsigned char value, char up_flag)
{
typedef void (*fnp)(void);
......@@ -509,7 +527,7 @@ static void do_spec(unsigned char value, char up_flag)
NULL, enter, show_ptregs, show_mem,
show_state, send_intr, lastcons, caps_toggle,
num, hold, scrll_forw, scrll_back,
boot_it, caps_on, compose
boot_it, caps_on, compose, SAK
};
if (up_flag)
......@@ -683,7 +701,8 @@ static void do_shift(unsigned char value, char up_flag)
/* kludge... */
if (value == KVAL(K_CAPSSHIFT)) {
value = KVAL(K_SHIFT);
clr_vc_kbd_led(kbd, VC_CAPSLOCK);
if (!up_flag)
clr_vc_kbd_led(kbd, VC_CAPSLOCK);
}
if (up_flag) {
......@@ -819,27 +838,7 @@ static void kbd_bh(void * unused)
}
want_console = -1;
}
if (got_break) {
if (tty && !I_IGNBRK(tty)) {
if (I_BRKINT(tty)) {
flush_input(tty);
flush_output(tty);
if (tty->pgrp > 0)
kill_pg(tty->pgrp, SIGINT, 1);
} else {
cli();
if (LEFT(&tty->read_q) >= 2) {
set_bit(tty->read_q.head,
&tty->readq_flags);
put_queue(TTY_BREAK);
put_queue(0);
}
sti();
}
}
got_break = 0;
}
do_keyboard_interrupt();
poke_blanked_console();
cli();
if ((inb_p(0x64) & kbd_read_mask) == 0x01)
fake_keyboard_interrupt();
......@@ -877,6 +876,7 @@ unsigned long kbd_init(unsigned long kmem_start)
{
int i;
struct kbd_struct * kbd;
extern struct tty_driver console_driver;
kbd = kbd_table + 0;
for (i = 0 ; i < NR_CONSOLES ; i++,kbd++) {
......@@ -885,6 +885,7 @@ unsigned long kbd_init(unsigned long kmem_start)
kbd->lockstate = KBD_DEFLOCK;
kbd->modeflags = KBD_DEFMODE;
}
ttytab = console_driver.table;
bh_base[KEYBOARD_BH].routine = kbd_bh;
request_irq(KEYBOARD_IRQ,keyboard_interrupt);
......
This diff is collapsed.
......@@ -14,36 +14,59 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/major.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/bitops.h>
struct pty_struct {
int magic;
struct wait_queue * open_wait;
};
#define PTY_MAGIC 0x5001
#define PTY_BUF_SIZE 1024
static unsigned char tmp_buf[PTY_BUF_SIZE];
struct tty_driver pty_driver, pty_slave_driver;
static int pty_refcount;
static struct tty_struct *pty_table[NR_PTYS];
static struct termios *pty_termios[NR_PTYS];
static struct termios *pty_termios_locked[NR_PTYS];
static struct tty_struct *ttyp_table[NR_PTYS];
static struct termios *ttyp_termios[NR_PTYS];
static struct termios *ttyp_termios_locked[NR_PTYS];
static struct pty_struct pty_state[NR_PTYS];
#define MIN(a,b) ((a) < (b) ? (a) : (b))
static void pty_close(struct tty_struct * tty, struct file * filp)
{
if (!tty)
return;
if (IS_A_PTY_MASTER(tty->line)) {
if (tty->driver.subtype == PTY_TYPE_MASTER) {
if (tty->count > 1)
printk("master pty_close: count = %d!!\n", tty->count);
} else {
if (tty->count > 2)
return;
}
wake_up_interruptible(&tty->secondary.proc_list);
wake_up_interruptible(&tty->read_q.proc_list);
wake_up_interruptible(&tty->write_q.proc_list);
wake_up_interruptible(&tty->read_wait);
wake_up_interruptible(&tty->write_wait);
if (!tty->link)
return;
wake_up_interruptible(&tty->link->secondary.proc_list);
wake_up_interruptible(&tty->link->read_q.proc_list);
wake_up_interruptible(&tty->link->write_q.proc_list);
if (IS_A_PTY_MASTER(tty->line))
wake_up_interruptible(&tty->link->read_wait);
wake_up_interruptible(&tty->link->write_wait);
if (tty->driver.subtype == PTY_TYPE_MASTER)
tty_hangup(tty->link);
else {
start_tty(tty);
......@@ -51,58 +74,137 @@ static void pty_close(struct tty_struct * tty, struct file * filp)
}
}
static inline void pty_copy(struct tty_struct * from, struct tty_struct * to)
static int pty_write(struct tty_struct * tty, int from_user,
unsigned char *buf, int count)
{
unsigned long count, n;
struct tty_queue *fq, *tq;
struct tty_struct *to = tty->link;
int c, n;
if (from->stopped || EMPTY(&from->write_q))
return;
fq = &from->write_q;
tq = &to->read_q;
count = MIN(CHARS(fq), LEFT(tq));
while (count) {
n = MIN(MIN(TTY_BUF_SIZE - fq->tail, TTY_BUF_SIZE - tq->head),
count);
memcpy(&tq->buf[tq->head], &fq->buf[fq->tail], n);
count -= n;
fq->tail = (fq->tail + n) & (TTY_BUF_SIZE - 1);
tq->head = (tq->head + n) & (TTY_BUF_SIZE - 1);
}
TTY_READ_FLUSH(to);
if (LEFT(fq) > WAKEUP_CHARS)
wake_up_interruptible(&fq->proc_list);
if (from->write_data_cnt) {
set_bit(from->line, &tty_check_write);
mark_bh(TTY_BH);
}
if (!to || tty->stopped)
return 0;
count = MIN(count, to->ldisc.receive_room(to));
if (from_user) {
for (c = count; c > 0; c -= n) {
n = MIN(c, PTY_BUF_SIZE);
memcpy_fromfs(tmp_buf, buf, n);
to->ldisc.receive_buf(to, tmp_buf, 0, n);
buf += n;
}
} else
to->ldisc.receive_buf(to, buf, 0, count);
return count;
}
/*
* This routine gets called when tty_write has put something into
* the write_queue. It copies the input to the output-queue of its
* slave.
*/
static void pty_write(struct tty_struct * tty)
static int pty_write_room(struct tty_struct *tty)
{
if (tty->link)
pty_copy(tty,tty->link);
struct tty_struct *to = tty->link;
if (!to || tty->stopped)
return 0;
return to->ldisc.receive_room(to);
}
static int pty_chars_in_buffer(struct tty_struct *tty)
{
struct tty_struct *to = tty->link;
if (!to)
return 0;
return to->ldisc.chars_in_buffer(to);
}
static void pty_flush_buffer(struct tty_struct *tty)
{
struct tty_struct *to = tty->link;
if (!to)
return;
if (to->ldisc.flush_buffer)
to->ldisc.flush_buffer(to);
if (to->packet) {
tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
wake_up_interruptible(&to->read_wait);
}
}
int pty_open(struct tty_struct *tty, struct file * filp)
{
int line;
struct pty_struct *pty;
if (!tty || !tty->link)
return -ENODEV;
if (IS_A_PTY_SLAVE(tty->line))
line = MINOR(tty->device) - tty->driver.minor_start;
if ((line < 0) || (line >= NR_PTYS))
return -ENODEV;
pty = pty_state + line;
tty->driver_data = pty;
if (tty->driver.subtype == PTY_TYPE_SLAVE)
clear_bit(TTY_SLAVE_CLOSED, &tty->link->flags);
tty->write = tty->link->write = pty_write;
tty->close = tty->link->close = pty_close;
wake_up_interruptible(&tty->read_q.proc_list);
wake_up_interruptible(&pty->open_wait);
if (filp->f_flags & O_NDELAY)
return 0;
while (!tty->link->count && !(current->signal & ~current->blocked))
interruptible_sleep_on(&tty->link->read_q.proc_list);
interruptible_sleep_on(&pty->open_wait);
if (!tty->link->count)
return -ERESTARTSYS;
return 0;
}
long pty_init(long kmem_start)
{
memset(&pty_state, 0, sizeof(pty_state));
memset(&pty_driver, 0, sizeof(struct tty_driver));
pty_driver.magic = TTY_DRIVER_MAGIC;
pty_driver.name = "pty";
pty_driver.major = TTY_MAJOR;
pty_driver.minor_start = 128;
pty_driver.num = NR_PTYS;
pty_driver.type = TTY_DRIVER_TYPE_PTY;
pty_driver.subtype = PTY_TYPE_MASTER;
pty_driver.init_termios = tty_std_termios;
pty_driver.init_termios.c_iflag = 0;
pty_driver.init_termios.c_oflag = 0;
pty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD;
pty_driver.init_termios.c_lflag = 0;
pty_driver.flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW;
pty_driver.refcount = &pty_refcount;
pty_driver.table = pty_table;
pty_driver.termios = pty_termios;
pty_driver.termios_locked = pty_termios_locked;
pty_driver.other = &pty_slave_driver;
pty_driver.open = pty_open;
pty_driver.close = pty_close;
pty_driver.write = pty_write;
pty_driver.write_room = pty_write_room;
pty_driver.flush_buffer = pty_flush_buffer;
pty_driver.chars_in_buffer = pty_chars_in_buffer;
pty_slave_driver = pty_driver;
pty_slave_driver.name = "ttyp";
pty_slave_driver.subtype = PTY_TYPE_SLAVE;
pty_slave_driver.minor_start = 192;
pty_slave_driver.init_termios = tty_std_termios;
pty_slave_driver.table = ttyp_table;
pty_slave_driver.termios = ttyp_termios;
pty_slave_driver.termios_locked = ttyp_termios_locked;
pty_slave_driver.other = &pty_driver;
if (tty_register_driver(&pty_driver))
panic("Couldn't register pty driver\n");
if (tty_register_driver(&pty_slave_driver))
panic("Couldn't register pty slave driver\n");
return kmem_start;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -22,6 +22,8 @@
#include "vt_kern.h"
#include "diacr.h"
extern struct tty_driver console_driver;
/*
* Console (vt and kd) routines, as defined by USL SVR4 manual, and by
* experimentation and study of X386 SYSV handling.
......@@ -119,11 +121,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
int console, i;
unsigned char ucval;
struct kbd_struct * kbd;
struct vt_struct *vt = tty->driver_data;
console = tty->line - 1;
console = vt->vc_num;
if (console < 0 || console >= NR_CONSOLES)
return -EINVAL;
return -ENOIOCTLCMD;
kbd = kbd_table + console;
switch (cmd) {
......@@ -234,7 +237,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
default:
return -EINVAL;
}
flush_input(tty);
if (tty->ldisc.flush_buffer)
tty->ldisc.flush_buffer(tty);
return 0;
case KDGKBMODE:
......@@ -304,6 +308,13 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return -EINVAL;
if (KVAL(v) > max_vals[KTYP(v)])
return -EINVAL;
/*
* Only the Superuser can set or unset the Secure
* Attention Key.
*/
if (((key_map[s][i] == K_SAK) || (v == K_SAK)) &&
!suser())
return -EPERM;
key_map[s][i] = v;
return 0;
}
......@@ -473,8 +484,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
return i;
put_fs_word(fg_console + 1, &vtstat->v_active);
state = 1; /* /dev/tty0 is always open */
for (i = 1, mask = 2; i <= NR_CONSOLES; ++i, mask <<= 1)
if (tty_table[i] && tty_table[i]->count > 0)
for (i = 0, mask = 2; i < NR_CONSOLES; ++i, mask <<= 1)
if (console_driver.table[i] &&
console_driver.table[i]->count > 0)
state |= mask;
put_fs_word(state, &vtstat->v_state);
return 0;
......@@ -487,10 +499,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
i = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
if (i)
return i;
for (i = 1; i <= NR_CONSOLES; ++i)
if (!tty_table[i] || tty_table[i]->count == 0)
for (i = 0; i < NR_CONSOLES; ++i)
if (!console_driver.table[i] ||
console_driver.table[i]->count == 0)
break;
put_fs_long(i <= NR_CONSOLES ? i : -1, (unsigned long *)arg);
put_fs_long(i < NR_CONSOLES ? (i+1) : -1,
(unsigned long *)arg);
return 0;
/*
......@@ -586,6 +600,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
/* con_get_trans() defined in console.c */
default:
return -EINVAL;
return -ENOIOCTLCMD;
}
}
......@@ -9,6 +9,7 @@
#include <linux/vt.h>
extern struct vt_struct {
int vc_num; /* The console number */
unsigned char vc_mode; /* KD_TEXT, ... */
unsigned char vc_kbdraw;
unsigned char vc_kbde0;
......@@ -16,6 +17,7 @@ extern struct vt_struct {
struct vt_mode vt_mode;
int vt_pid;
int vt_newvt;
struct wait_queue *paste_wait;
} vt_cons[NR_CONSOLES];
void kd_mksound(unsigned int count, unsigned int ticks);
......
......@@ -327,7 +327,7 @@ el_interrupt(int reg_ptr)
" gp=%03x rp=%03x.\n", dev->name, txsr, axsr,
inw(ioaddr + EL1_DATAPTR), inw(ioaddr + EL1_RXPTR));
dev->tbusy = 0;
mark_bh(INET_BH);
mark_bh(NET_BH);
} else if (txsr & TX_16COLLISIONS) {
if (el_debug)
printk("%s: Transmit failed 16 times, ethernet jammed?\n",
......@@ -349,7 +349,7 @@ el_interrupt(int reg_ptr)
printk(" Tx succeeded %s\n",
(txsr & TX_RDY) ? "." : "but tx is busy!");
dev->tbusy = 0;
mark_bh(INET_BH);
mark_bh(NET_BH);
}
} else {
int rxsr = inb(RX_STATUS);
......
......@@ -530,7 +530,7 @@ el16_interrupt(int reg_ptr)
lp->stats.tx_packets++;
lp->stats.collisions += tx_status & 0xf;
dev->tbusy = 0;
mark_bh(INET_BH); /* Inform upper layers. */
mark_bh(NET_BH); /* Inform upper layers. */
} else {
lp->stats.tx_errors++;
if (tx_status & 0x0600) lp->stats.tx_carrier_errors++;
......
......@@ -31,6 +31,10 @@ static char *version = "3c509.c:pl15k 3/5/94 becker@super.org\n";
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#ifdef MODULE
#include <linux/module.h>
#include "../../tools/version.h"
#endif
......@@ -312,6 +316,9 @@ el3_open(struct device *dev)
printk("%s: Opened 3c509 IRQ %d status %4.4x.\n",
dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
return 0; /* Always succeed */
}
......@@ -436,7 +443,7 @@ el3_interrupt(int reg_ptr)
/* There's room in the FIFO for a full-sized packet. */
outw(0x6808, ioaddr + EL3_CMD); /* Ack IRQ */
dev->tbusy = 0;
mark_bh(INET_BH);
mark_bh(NET_BH);
}
if (status & 0x80) /* Statistics full. */
update_stats(ioaddr, dev);
......@@ -645,6 +652,9 @@ el3_close(struct device *dev)
irq2dev_map[dev->irq] = 0;
update_stats(ioaddr, dev);
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
return 0;
}
......@@ -656,3 +666,29 @@ el3_close(struct device *dev)
* tab-width: 4
* End:
*/
#ifdef MODULE
char kernel_version[] = UTS_RELEASE;
static struct device dev_3c509 = {
"" /*"3c509"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, el3_probe };
int
init_module(void)
{
if (register_netdev(&dev_3c509) != 0)
return -EIO;
return 0;
}
void
cleanup_module(void)
{
if (MOD_IN_USE)
printk("3c509: device busy, remove delayed\n");
else
{
unregister_netdev(&dev_3c509);
kfree_s(dev_3c509.priv,sizeof(struct el3_private));
dev_3c509.priv=NULL;
}
}
#endif /* MODULE */
This diff is collapsed.
This diff is collapsed.
MODULES = \
3c509.o \
de600.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -128,5 +128,6 @@
#define ERESTARTSYS 512
#define ERESTARTNOINTR 513
#define ERESTARTNOHAND 514 /* restart if no handler.. */
#define ENOIOCTLCMD 515 /* No ioctl command */
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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