diff options
Diffstat (limited to 'drivers/char')
30 files changed, 685 insertions, 288 deletions
diff --git a/drivers/char/ChangeLog b/drivers/char/ChangeLog index 0e61fb819..56e762e71 100644 --- a/drivers/char/ChangeLog +++ b/drivers/char/ChangeLog @@ -1,3 +1,9 @@ +Mon Dec 1 08:24:15 1997 Theodore Ts'o <tytso@rsts-11.mit.edu> + + * tty_io.c (tty_get_baud_rate): Print a warning syslog if the + tty->alt_speed kludge is used; this means the system is + using the deprecated SPD_HI ioctls. + Mon Nov 24 10:37:49 1997 Theodore Ts'o <tytso@rsts-11.mit.edu> * serial.c, esp.c, rocket.c: Change drivers to take advantage of diff --git a/drivers/char/Config.in b/drivers/char/Config.in index 9b13a4d2d..8af5a5e44 100644 --- a/drivers/char/Config.in +++ b/drivers/char/Config.in @@ -6,16 +6,18 @@ comment 'Character devices' bool 'Virtual terminal' CONFIG_VT if [ "$CONFIG_VT" = "y" ]; then - bool 'Console on virtual terminal' CONFIG_VT_CONSOLE + bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE fi tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL +if [ "$CONFIG_SERIAL" = "y" ]; then + bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE +fi bool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then bool ' Support more than 4 serial ports' CONFIG_SERIAL_MANY_PORTS bool ' Support for sharing serial interrupts' CONFIG_SERIAL_SHARE_IRQ bool ' Support special multiport boards' CONFIG_SERIAL_MULTIPORT bool ' Support the Bell Technologies HUB6 card' CONFIG_HUB6 - bool ' Console on serial port' CONFIG_SERIAL_CONSOLE fi bool 'Non-standard serial port support' CONFIG_SERIAL_NONSTANDARD if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then @@ -31,6 +33,10 @@ if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then tristate ' Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION fi tristate 'SDL RISCom/8 card support' CONFIG_RISCOM8 + tristate 'Specialix IO8+ card support' CONFIG_SPECIALIX + if [ "$CONFIG_SPECIALIX" = "y" -o "$CONFIG_SPECIALIX" = "m" ]; then + bool 'Specialix DTR/RTS pin is RTS' CONFIG_SPECIALIX_RTSCTS + fi tristate 'Hayes ESP serial port support' CONFIG_ESPSERIAL if [ "$CONFIG_ESPSERIAL" = "y" -o "$CONFIG_ESPSERIAL" = "m" ]; then int ' DMA channel' CONFIG_ESPSERIAL_DMA_CHANNEL 1 @@ -60,7 +66,11 @@ if [ "$CONFIG_MOUSE" = "y" ]; then tristate 'PC110 digitizer pad support' CONFIG_PC110_PAD fi -if [ "$CONFIG_MODULES" = "y" ]; then +# IRIX compat stuff for X on the Indy relies on CONFIG_UMISC +if [ "$CONFIG_SGI" = "y" ]; then + define_bool CONFIG_UMISC y + bool 'Support for SGI graphic devices' CONFIG_SGI_GRAPHICS +elif [ "$CONFIG_MODULES" = "y" ]; then bool 'Support for user misc device modules' CONFIG_UMISC fi diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 58ca9aa09..807db2c3d 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -125,6 +125,14 @@ else endif endif +ifeq ($(CONFIG_SPECIALIX),y) +L_OBJS += specialix.o +else + ifeq ($(CONFIG_SPECIALIX),m) + M_OBJS += specialix.o + endif +endif + ifeq ($(CONFIG_ATIXL_BUSMOUSE),y) M = y L_OBJS += atixlmouse.o diff --git a/drivers/char/acquirewdt.c b/drivers/char/acquirewdt.c index 8d2600f41..be1c28456 100644 --- a/drivers/char/acquirewdt.c +++ b/drivers/char/acquirewdt.c @@ -64,6 +64,10 @@ static void acq_ping(void) static ssize_t acq_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { + /* Can't seek (pwrite) on this device */ + if (ppos != &file->f_pos) + return -ESPIPE; + if(count) { acq_ping(); diff --git a/drivers/char/bttv.c b/drivers/char/bttv.c index 56d38d7a2..4c1fa303c 100644 --- a/drivers/char/bttv.c +++ b/drivers/char/bttv.c @@ -54,6 +54,7 @@ static unsigned int remap=0; static unsigned int vidmem=0; static unsigned int tuner=0; /* Default tuner */ +MODULE_PARM(tuner,"i"); static int find_vga(void); static void bt848_set_risc_jmps(struct bttv *btv); @@ -603,7 +604,7 @@ static long bttv_read(struct video_device *v, char *buf, unsigned long count, in } interruptible_sleep_on(&btv->vbiq); sti(); - if(current->signal & ~current->blocked) + if(signal_pending(current)) { if(todo==count) return -EINTR; diff --git a/drivers/char/console.c b/drivers/char/console.c index b24def4a2..02ce3a64e 100644 --- a/drivers/char/console.c +++ b/drivers/char/console.c @@ -174,6 +174,7 @@ extern void vesa_powerdown(void); extern void compute_shiftstate(void); extern void reset_palette(int currcons); extern void set_palette(void); +extern int con_is_present(void); extern unsigned long con_type_init(unsigned long, const char **); extern void con_type_init_finish(void); extern int set_get_cmap(unsigned char *, int); @@ -1867,7 +1868,7 @@ void poke_blanked_console(void) } #ifdef CONFIG_VT_CONSOLE -void vt_console_print(const char * b, unsigned count) +void vt_console_print(struct console *co, const char * b, unsigned count) { int currcons = fg_console; unsigned char c; @@ -1916,16 +1917,25 @@ void vt_console_print(const char * b, unsigned count) printing = 0; } -static int vt_console_device(void) +static kdev_t vt_console_device(struct console *c) { - return MKDEV(TTY_MAJOR, fg_console + 1); + return MKDEV(TTY_MAJOR, c->index ? c->index : fg_console + 1); } -extern void keyboard_wait_for_keypress(void); +extern int keyboard_wait_for_keypress(struct console *); struct console vt_console_driver = { - vt_console_print, do_unblank_screen, - keyboard_wait_for_keypress, vt_console_device + "tty", + vt_console_print, + NULL, + vt_console_device, + keyboard_wait_for_keypress, + do_unblank_screen, + NULL, + CON_PRINTBUFFER, + -1, + 0, + NULL }; #endif @@ -2014,6 +2024,9 @@ static void console_bh(void) * * Reads the information preserved by setup.s to determine the current display * type and sets everything accordingly. + * + * FIXME: return early if we don't _have_ a video card installed. + * */ __initfunc(unsigned long con_init(unsigned long kmem_start)) { @@ -2181,7 +2194,7 @@ __initfunc(unsigned long con_init(unsigned long kmem_start)) * within the bus probing code... :-( */ #ifdef CONFIG_VT_CONSOLE - if (video_type != VIDEO_TYPE_TGAC) + if (video_type != VIDEO_TYPE_TGAC && con_is_present()) register_console(&vt_console_driver); #endif diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index ed4ac9846..4535230ac 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -1,6 +1,6 @@ #define BLOCKMOVE static char rcsid[] = -"$Revision: 2.1 $$Date: 1997/11/01 17:42:41 $"; +"$Revision: 2.1.1.1 $$Date: 1997/12/03 17:31:19 $"; /* * linux/drivers/char/cyclades.c @@ -30,6 +30,12 @@ static char rcsid[] = * void cleanup_module(void); * * $Log: cyclades.c,v $ + * Revision 2.1.1.1 1997/12/03 17:31:19 ivan + * Code review for the module cleanup routine (fixed memory leak); + * fixed RTS and DTR status report for new CD1400's in get_modem_info; + * purged conditional code for older kernels; + * includes anonymous changes regarding signal_pending + * * Revision 2.1 1997/11/01 17:42:41 ivan * Changes in the driver to support Alpha systems (except 8Zo V_1); * BREAK fix for the Cyclades-Z boards; @@ -524,8 +530,6 @@ static char rcsid[] = #include <linux/version.h> -#if (LINUX_VERSION_CODE >= 0x020100) - #include <asm/uaccess.h> #include <linux/init.h> @@ -540,17 +544,6 @@ static unsigned long cy_get_user(unsigned long *addr) return result; } -#else - -#define __initfunc(__arginit) __arginit -#define copy_from_user memcpy_fromfs -#define copy_to_user memcpy_tofs -#define cy_get_user get_fs_long -#define cy_put_user put_fs_long -#define ioremap vremap - -#endif - #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif @@ -875,7 +868,6 @@ do_softint(void *private_) if (!tty) return; -#if (LINUX_VERSION_CODE >= 0x020125) if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { tty_hangup(info->tty); wake_up_interruptible(&info->open_wait); @@ -892,24 +884,6 @@ do_softint(void *private_) } wake_up_interruptible(&tty->write_wait); } -#else - if (clear_bit(Cy_EVENT_HANGUP, &info->event)) { - tty_hangup(info->tty); - wake_up_interruptible(&info->open_wait); - info->flags &= ~(ASYNC_NORMAL_ACTIVE| - ASYNC_CALLOUT_ACTIVE); - } - if (clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) { - wake_up_interruptible(&info->open_wait); - } - if (clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) { - if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP)) - && tty->ldisc.write_wakeup){ - (tty->ldisc.write_wakeup)(tty); - } - wake_up_interruptible(&tty->write_wait); - } -#endif } /* do_softint */ @@ -2339,7 +2313,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, break; } restore_flags(flags); - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { retval = -ERESTARTSYS; break; } @@ -2397,7 +2371,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, || (cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD))) { break; } - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { retval = -ERESTARTSYS; break; } @@ -3318,12 +3292,18 @@ get_modem_info(struct cyclades_port * info, unsigned int *value) status |= cy_readb(base_addr+(CyMSVR2<<index)); restore_flags(flags); - result = ((status & CyRTS) ? TIOCM_RTS : 0) - | ((status & CyDTR) ? TIOCM_DTR : 0) - | ((status & CyDCD) ? TIOCM_CAR : 0) - | ((status & CyRI) ? TIOCM_RNG : 0) - | ((status & CyDSR) ? TIOCM_DSR : 0) - | ((status & CyCTS) ? TIOCM_CTS : 0); + + if (info->rtsdtr_inv) { + result = ((status & CyRTS) ? TIOCM_DTR : 0) + | ((status & CyDTR) ? TIOCM_RTS : 0); + } else { + result = ((status & CyRTS) ? TIOCM_RTS : 0) + | ((status & CyDTR) ? TIOCM_DTR : 0); + } + result |= ((status & CyDCD) ? TIOCM_CAR : 0) + | ((status & CyRI) ? TIOCM_RNG : 0) + | ((status & CyDSR) ? TIOCM_DSR : 0) + | ((status & CyCTS) ? TIOCM_CTS : 0); } else { base_addr = (unsigned char*) (cy_card[card].base_addr); @@ -4329,7 +4309,7 @@ cy_detect_isa(void)) /* probe for CD1400... */ -#if !defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020100) +#if !defined(__alpha__) cy_isa_address = ioremap((unsigned int)cy_isa_address, CyISA_Ywin); #endif @@ -4483,9 +4463,6 @@ cy_detect_pci(void)) continue; } #else -#if (LINUX_VERSION_CODE < 0x020100) - if ((ulong)cy_pci_addr2 >= 0x100000) /* above 1M? */ -#endif cy_pci_addr2 = (ulong) ioremap(cy_pci_addr2, CyPCI_Ywin); #endif @@ -5098,10 +5075,13 @@ cleanup_module(void) save_flags(flags); cli(); remove_bh(CYCLADES_BH); + + free_page((unsigned long)tmp_buf); if (tty_unregister_driver(&cy_callout_driver)) printk("Couldn't unregister Cyclom callout driver\n"); if (tty_unregister_driver(&cy_serial_driver)) printk("Couldn't unregister Cyclom serial driver\n"); + restore_flags(flags); for (i = 0; i < NR_CARDS; i++) { diff --git a/drivers/char/esp.c b/drivers/char/esp.c index 5fdcd8a77..5f4c480c7 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c @@ -932,6 +932,20 @@ static int startup(struct esp_struct * info) IRQ_ports[info->irq] = info; /* + * Set up the tty->alt_speed kludge + */ + if (info->tty) { + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + info->tty->alt_speed = 57600; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + info->tty->alt_speed = 115200; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + info->tty->alt_speed = 230400; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + info->tty->alt_speed = 460800; + } + + /* * set the speed of the serial port */ change_speed(info); @@ -1118,7 +1132,8 @@ static void change_speed(struct esp_struct *info) #endif baud = tty_get_baud_rate(info->tty); - if (baud == 38400) + if (baud == 38400 && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) quot = info->custom_divisor; else { if (baud == 134) diff --git a/drivers/char/ftape/Config.in b/drivers/char/ftape/Config.in index 858f327d3..2f837be5b 100644 --- a/drivers/char/ftape/Config.in +++ b/drivers/char/ftape/Config.in @@ -17,7 +17,7 @@ choice 'Debugging output' \ "Normal CONFIG_FT_NORMAL_DEBUG \ Excessive CONFIG_FT_FULL_DEBUG \ Reduced CONFIG_FT_NO_TRACE \ - None CONIFG_FT_NO_TRACE_AT_ALL" Normal + None CONFIG_FT_NO_TRACE_AT_ALL" Normal comment 'Hardware configuration' choice 'Floppy tape controllers' \ "Standard CONFIG_FT_STD_FDC \ diff --git a/drivers/char/ftape/lowlevel/fdc-io.c b/drivers/char/ftape/lowlevel/fdc-io.c index 904a99ac5..47229c5b4 100644 --- a/drivers/char/ftape/lowlevel/fdc-io.c +++ b/drivers/char/ftape/lowlevel/fdc-io.c @@ -445,7 +445,7 @@ int fdc_interrupt_wait(unsigned int time) fdc_reset(); resetting = 0; } - TRACE_EXIT (current->signal & ~current->blocked) ? -EINTR : -ETIME; + TRACE_EXIT (signal_pending(current)) ? -EINTR : -ETIME; } /* Start/stop drive motor. Enable DMA mode. diff --git a/drivers/char/ftape/lowlevel/ftape-init.c b/drivers/char/ftape/lowlevel/ftape-init.c index 7a8d15f5e..28cdd5739 100644 --- a/drivers/char/ftape/lowlevel/ftape-init.c +++ b/drivers/char/ftape/lowlevel/ftape-init.c @@ -94,7 +94,7 @@ KERN_INFO "Compiled for Linux version %s" #ifdef MODULE while (ftape_set_nr_buffers(CONFIG_FT_NR_BUFFERS) < 0) { ftape_sleep(FT_SECOND/20); - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { (void)ftape_set_nr_buffers(0); TRACE(ft_t_bug, "Killed by signal while allocating buffers."); diff --git a/drivers/char/ftape/lowlevel/ftape-io.c b/drivers/char/ftape/lowlevel/ftape-io.c index af81d1802..e43da1e27 100644 --- a/drivers/char/ftape/lowlevel/ftape-io.c +++ b/drivers/char/ftape/lowlevel/ftape-io.c @@ -103,7 +103,7 @@ void ftape_sleep(unsigned int time) } /* Mmm. Isn't current->blocked == 0xffffffff ? */ - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { TRACE(ft_t_err, "awoken by non-blocked signal :-("); break; /* exit on signal */ diff --git a/drivers/char/hfmodem/main.c b/drivers/char/hfmodem/main.c index eb30cec3e..b39ba2854 100644 --- a/drivers/char/hfmodem/main.c +++ b/drivers/char/hfmodem/main.c @@ -136,8 +136,6 @@ struct hfmodem_state hfmodem_state[NR_DEVICE]; #define LPT_CONTROL(iobase) (iobase+2) #define LPT_IRQ_ENABLE 0x10 -#define LPT_EXTENT 3 - #define MIDI_DATA(iobase) (iobase) #define MIDI_STATUS(iobase) (iobase+1) #define MIDI_READ_FULL 0x80 /* attention: negative logic!! */ @@ -150,33 +148,37 @@ struct hfmodem_state hfmodem_state[NR_DEVICE]; #define SP_MIDI 4 /* ---------------------------------------------------------------------- */ -/* - * returns 0 if ok and != 0 on error; - * the same behaviour as par96_check_lpt in baycom.c - */ -__initfunc(static int check_lpt(unsigned int iobase)) +static int parptt_preempt(void *handle) { - unsigned char b1,b2; - int i; + /* we cannot relinquish the port in the middle of an operation */ + return 1; +} - if (iobase <= 0 || iobase > 0x1000-LPT_EXTENT) - return 0; - if (check_region(iobase, LPT_EXTENT)) - return 0; - b1 = inb(LPT_DATA(iobase)); - b2 = inb(LPT_CONTROL(iobase)); - outb(0xaa, LPT_DATA(iobase)); - i = inb(LPT_DATA(iobase)) == 0xaa; - outb(0x55, LPT_DATA(iobase)); - i &= inb(LPT_DATA(iobase)) == 0x55; - outb(0x0a, LPT_CONTROL(iobase)); - i &= (inb(LPT_CONTROL(iobase)) & 0xf) == 0x0a; - outb(0x05, LPT_CONTROL(iobase)); - i &= (inb(LPT_CONTROL(iobase)) & 0xf) == 0x05; - outb(b1, LPT_DATA(iobase)); - outb(b2, LPT_CONTROL(iobase)); - return !i; +/* --------------------------------------------------------------------- */ + +static void parptt_wakeup(void *handle) +{ + struct hfmodem_state *dev = (struct hfmodem_state *)handle; + + printk(KERN_DEBUG "%s: parptt: why am I being woken up?\n", hfmodem_drvname); + if (!parport_claim(dev->ptt_out.pardev)) + printk(KERN_DEBUG "%s: parptt: I'm broken.\n", hfmodem_drvname); +} + +/* --------------------------------------------------------------------- */ +__initfunc(static int check_lpt(struct hfmodem_state *dev, unsigned int iobase)) +{ + struct parport *pp = parport_enumerate(); + + while (pp && pp->base != iobase) + pp = pp->next; + if (!pp) + return 0; + if (!(dev->ptt_out.pardev = parport_register_device(pp, hfmodem_drvname, parptt_preempt, parptt_wakeup, + NULL, PARPORT_DEV_LURK, dev))) + return 0; + return 1; } /* --------------------------------------------------------------------- */ @@ -272,8 +274,7 @@ __initfunc(static void output_check(struct hfmodem_state *dev)) { enum uart u = c_uart_unknown; - if (dev->ptt_out.seriobase > 0 && dev->ptt_out.seriobase <= 0x1000-SER_EXTENT && - ((u = check_uart(dev->ptt_out.seriobase))) != c_uart_unknown) + if (((u = check_uart(dev->ptt_out.seriobase))) != c_uart_unknown) printk(KERN_INFO "%s: PTT output: uart found at address 0x%x type %s\n", hfmodem_drvname, dev->ptt_out.seriobase, uart_str[u]); else { @@ -282,8 +283,7 @@ __initfunc(static void output_check(struct hfmodem_state *dev)) hfmodem_drvname, dev->ptt_out.seriobase); dev->ptt_out.seriobase = 0; } - if (dev->ptt_out.pariobase > 0 && dev->ptt_out.pariobase <= 0x1000-LPT_EXTENT && - !check_lpt(dev->ptt_out.pariobase)) + if (check_lpt(dev, dev->ptt_out.pariobase)) printk(KERN_INFO "%s: PTT output: parallel port found at address 0x%x\n", hfmodem_drvname, dev->ptt_out.pariobase); else { @@ -291,6 +291,7 @@ __initfunc(static void output_check(struct hfmodem_state *dev)) printk(KERN_WARNING "%s: PTT output: no parallel port found at address 0x%x\n", hfmodem_drvname, dev->ptt_out.pariobase); dev->ptt_out.pariobase = 0; + dev->ptt_out.pardev = NULL; } if (dev->ptt_out.midiiobase > 0 && dev->ptt_out.midiiobase <= 0x1000-MIDI_EXTENT && check_midi(dev->ptt_out.midiiobase)) @@ -324,12 +325,11 @@ static void output_open(struct hfmodem_state *dev) hfmodem_drvname, dev->ptt_out.seriobase); } if (dev->ptt_out.pariobase > 0) { - if (!check_region(dev->ptt_out.pariobase, LPT_EXTENT)) { - request_region(dev->ptt_out.pariobase, LPT_EXTENT, "hfmodem par ptt"); - dev->ptt_out.flags |= SP_PAR; - } else + if (parport_claim(dev->ptt_out.pardev)) printk(KERN_WARNING "%s: PTT output: parallel port at 0x%x busy\n", hfmodem_drvname, dev->ptt_out.pariobase); + else + dev->ptt_out.flags |= SP_PAR; } if (dev->ptt_out.midiiobase > 0) { if (!check_region(dev->ptt_out.midiiobase, MIDI_EXTENT)) { @@ -361,7 +361,7 @@ static void output_close(struct hfmodem_state *dev) if (dev->ptt_out.flags & SP_SER) release_region(dev->ptt_out.seriobase, SER_EXTENT); if (dev->ptt_out.flags & SP_PAR) - release_region(dev->ptt_out.pariobase, LPT_EXTENT); + parport_release(dev->ptt_out.pardev); if (dev->ptt_out.flags & SP_MIDI) release_region(dev->ptt_out.midiiobase, MIDI_EXTENT); dev->ptt_out.flags = 0; @@ -671,6 +671,10 @@ __initfunc(int init_module(void)) void cleanup_module(void) { + struct hfmodem_state *dev = &hfmodem_state[0]; + + if (dev->ptt_out.pariobase > 0) + parport_unregister_device(dev->ptt_out.pardev); misc_deregister(&hfmodem_device); } @@ -733,4 +737,3 @@ __initfunc(void hfmodem_init(void)) /* --------------------------------------------------------------------- */ #endif /* MODULE */ - diff --git a/drivers/char/joystick.c b/drivers/char/joystick.c index c8c44d77a..82fa23627 100644 --- a/drivers/char/joystick.c +++ b/drivers/char/joystick.c @@ -1,5 +1,5 @@ /* - * $Id: joystick.c,v 1.2 1997/10/31 19:11:48 mj Exp $ + * $Id: joystick.c,v 1.2 1997/12/06 23:52:28 ralf Exp $ * * Copyright (C) 1997 Vojtech Pavlik */ @@ -470,7 +470,7 @@ static ssize_t js_read(struct file *file, char *buf, size_t count, loff_t *ppos) retval = -EAGAIN; break; } - if (current->signal & ~current->blocked) { + if (signal_pending(current)) { retval = -ERESTARTSYS; break; } diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 932578806..6a427c684 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -63,10 +63,12 @@ extern void scrollback(int); extern void scrollfront(int); struct wait_queue * keypress_wait = NULL; +struct console; -void keyboard_wait_for_keypress(void) +int keyboard_wait_for_keypress(struct console *co) { sleep_on(&keypress_wait); + return 0; } /* diff --git a/drivers/char/lp.c b/drivers/char/lp.c index fdfb961c7..fb30c3e0c 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -64,6 +64,11 @@ static char *dev_name = "lp"; #undef LP_DEBUG #undef LP_READ_DEBUG +/* Magic numbers */ +#define AUTO -3 +#define OFF -2 +#define UNSPEC -1 + static inline void lp_parport_release (int minor) { parport_release (lp_table[minor].dev); @@ -163,9 +168,7 @@ static inline int lp_char(char lpchar, int minor, int use_polling) static void lp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct parport *pb = (struct parport *) dev_id; - struct pardevice *pd = pb->cad; - struct lp_struct *lp_dev = (struct lp_struct *) pd->private; + struct lp_struct *lp_dev = (struct lp_struct *) dev_id; if (waitqueue_active (&lp_dev->lp_wait_q)) wake_up(&lp_dev->lp_wait_q); @@ -272,11 +275,11 @@ static inline int lp_write_buf(unsigned int minor, const char *buf, int count) return total_bytes_written; } -static ssize_t lp_write(struct file * file, const char * buf, size_t count, loff_t *ppos) +static ssize_t lp_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) { - struct inode *inode = file->f_dentry->d_inode; - unsigned int minor = MINOR(inode->i_rdev); - int retv; + unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); + ssize_t retv; if (jiffies-lp_table[minor].lastcall > LP_TIME(minor)) lp_table[minor].runchars = 0; @@ -288,7 +291,7 @@ static ssize_t lp_write(struct file * file, const char * buf, size_t count, loff */ lp_parport_claim (minor); - retv = lp_write_buf(minor, buf, count); + retv = lp_write_buf(minor, buf, count); lp_parport_release (minor); return retv; @@ -315,15 +318,15 @@ static void lp_select_in_high(int minor) { } /* Status readback confirming to ieee1284 */ -static ssize_t lp_read(struct file * file, char * buf, size_t count, loff_t *ppos) +static ssize_t lp_read(struct file * file, char * buf, + size_t count, loff_t *ppos) { - struct inode *inode = file->f_dentry->d_inode; unsigned char z=0, Byte=0, status; char *temp; - int retval; + ssize_t retval; unsigned int counter=0; unsigned int i; - unsigned int minor=MINOR(inode->i_rdev); + unsigned int minor=MINOR(file->f_dentry->d_inode->i_rdev); /* Claim Parport or sleep until it becomes available * (see lp_wakeup() for details) @@ -568,7 +571,7 @@ static struct file_operations lp_fops = { lp_release }; -static int parport[LP_NO] = { -1, }; +static int parport[LP_NO] = { UNSPEC, }; #ifdef MODULE #define lp_init init_module @@ -589,11 +592,11 @@ void lp_setup(char *str, int *ints) printk(KERN_INFO "lp: too many ports, %s ignored.\n", str); } else if (!strcmp(str, "auto")) { - parport[0] = -3; + parport[0] = AUTO; } else { if (ints[0] == 0 || ints[1] == 0) { /* disable driver on "lp=" or "lp=0" */ - parport[0] = -2; + parport[0] = OFF; } else { printk(KERN_WARNING "warning: 'lp=0x%x' is deprecated, ignored\n", ints[1]); } @@ -619,7 +622,7 @@ void lp_wakeup(void *ref) static int inline lp_searchfor(int list[], int a) { int i; - for (i = 0; i < LP_NO && list[i] != -1; i++) { + for (i = 0; i < LP_NO && list[i] != UNSPEC; i++) { if (list[i] == a) return 1; } return 0; @@ -630,15 +633,16 @@ int lp_init(void) int count = 0; struct parport *pb; - if (parport[0] == -2) return 0; + if (parport[0] == OFF) return 0; pb = parport_enumerate(); while (pb) { /* We only understand PC-style ports. */ if (pb->modes & PARPORT_MODE_PCSPP) { - if (parport[0] == -1 || lp_searchfor(parport, count) || - (parport[0] == -3 && + if (parport[0] == UNSPEC || + lp_searchfor(parport, count) || + (parport[0] == AUTO && pb->probe_info.class == PARPORT_CLASS_PRINTER)) { lp_table[count].dev = parport_register_device(pb, dev_name, @@ -646,6 +650,10 @@ int lp_init(void) lp_interrupt, PARPORT_DEV_TRAN, (void *) &lp_table[count]); lp_table[count].flags |= LP_EXIST; + init_waitqueue (&lp_table[count].lp_wait_q); + lp_parport_claim (count); + lp_reset (count); + lp_parport_release (count); printk(KERN_INFO "lp%d: using %s (%s).\n", count, pb->name, (pb->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven"); } diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 177862c2a..08d11b901 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -539,7 +539,7 @@ __initfunc(int chr_dev_init(void)) * Some joysticks only appear when the soundcard they are * connected too is confgured. Keep the sound/joystick ordering. */ - joystick_init(); + js_init(); #endif #if CONFIG_QIC02_TAPE qic02_tape_init(); diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 3581b81c3..251f73f96 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c @@ -40,6 +40,7 @@ #include <asm/bitops.h> #define CONSOLE_DEV MKDEV(TTY_MAJOR,0) +#define SYSCONS_DEV MKDEV(TTYAUX_MAJOR,1) #ifndef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -53,7 +54,7 @@ * unthrottling the TTY driver. These watermarks are used for * controlling the space in the read buffer. */ -#define TTY_THRESHOLD_THROTTLE (N_TTY_BUF_SIZE - 128) +#define TTY_THRESHOLD_THROTTLE 128 /* now based on remaining room */ #define TTY_THRESHOLD_UNTHROTTLE 128 static inline void put_tty_queue(unsigned char c, struct tty_struct *tty) @@ -65,21 +66,42 @@ static inline void put_tty_queue(unsigned char c, struct tty_struct *tty) } } +/* + * Check whether to call the driver.unthrottle function. + * We test the TTY_THROTTLED bit first so that it always + * indicates the current state. + */ +static void check_unthrottle(struct tty_struct * tty) +{ + if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && + tty->driver.unthrottle) + tty->driver.unthrottle(tty); +} + /* - * Flush the input buffer + * Reset the read buffer counters, clear the flags, + * and make sure the driver is unthrottled. Called + * from n_tty_open() and n_tty_flush_buffer(). */ -void n_tty_flush_buffer(struct tty_struct * tty) +static void reset_buffer_flags(struct tty_struct *tty) { tty->read_head = tty->read_tail = tty->read_cnt = 0; tty->canon_head = tty->canon_data = tty->erasing = 0; memset(&tty->read_flags, 0, sizeof tty->read_flags); + check_unthrottle(tty); +} + +/* + * Flush the input buffer + */ +void n_tty_flush_buffer(struct tty_struct * tty) +{ + /* clear everything and unthrottle the driver */ + reset_buffer_flags(tty); if (!tty->link) return; - if (tty->driver.unthrottle && - test_and_clear_bit(TTY_THROTTLED, &tty->flags)) - tty->driver.unthrottle(tty); if (tty->link->packet) { tty->ctrl_status |= TIOCPKT_FLUSHREAD; wake_up_interruptible(&tty->link->read_wait); @@ -507,7 +529,7 @@ send_signal: return; } } - if (L_ICANON(tty)) { + if (tty->icanon) { if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) || (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) { eraser(c, tty); @@ -610,11 +632,29 @@ send_signal: put_tty_queue(c, tty); } +static int n_tty_receive_room(struct tty_struct *tty) +{ + int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; + + /* + * If we are doing input canonicalization, and there are no + * pending newlines, let characters through without limit, so + * that erase characters will be handled. Other excess + * characters will be beeped. + */ + if (tty->icanon && !tty->canon_data) + return N_TTY_BUF_SIZE; + + if (left > 0) + return left; + return 0; +} + static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { const unsigned char *p; - char *f, flags = 0; + char *f, flags = TTY_NORMAL; int i; if (!tty->read_buf) @@ -669,34 +709,23 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, wake_up_interruptible(&tty->read_wait); } - if ((tty->read_cnt >= TTY_THRESHOLD_THROTTLE) && - tty->driver.throttle && - !test_and_set_bit(TTY_THROTTLED, &tty->flags)) - tty->driver.throttle(tty); -} - -static int n_tty_receive_room(struct tty_struct *tty) -{ - int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; - /* - * If we are doing input canonicalization, and there are no - * pending newlines, let characters through without limit, so - * that erase characters will be handled. Other excess - * characters will be beeped. + * Check the remaining room for the input canonicalization + * mode. We don't want to throttle the driver if we're in + * canonical mode and don't have a newline yet! */ - if (tty->icanon && !tty->canon_data) - return N_TTY_BUF_SIZE; - - if (left > 0) - return left; - return 0; + if (n_tty_receive_room(tty) < TTY_THRESHOLD_THROTTLE) { + /* check TTY_THROTTLED first so it indicates our state */ + if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && + tty->driver.throttle) + tty->driver.throttle(tty); + } } int is_ignored(int sig) { - return ((current->blocked & (1<<(sig-1))) || - (current->sig->action[sig-1].sa_handler == SIG_IGN)); + return (sigismember(¤t->blocked, sig) || + current->sig->action[sig-1].sa.sa_handler == SIG_IGN); } static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) @@ -785,10 +814,8 @@ static int n_tty_open(struct tty_struct *tty) return -ENOMEM; } memset(tty->read_buf, 0, N_TTY_BUF_SIZE); - tty->read_head = tty->read_tail = tty->read_cnt = 0; - tty->canon_head = tty->canon_data = tty->erasing = 0; + reset_buffer_flags(tty); tty->column = 0; - memset(tty->read_flags, 0, sizeof(tty->read_flags)); n_tty_set_termios(tty, 0); tty->minimum_to_wake = 1; tty->closing = 0; @@ -797,7 +824,7 @@ static int n_tty_open(struct tty_struct *tty) static inline int input_available_p(struct tty_struct *tty, int amt) { - if (L_ICANON(tty)) { + if (tty->icanon) { if (tty->canon_data) return 1; } else if (tty->read_cnt >= (amt ? amt : 1)) @@ -824,7 +851,8 @@ static inline void copy_from_read_buf(struct tty_struct *tty, n = MIN(*nr, MIN(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail)); if (!n) return; - copy_to_user(*b, &tty->read_buf[tty->read_tail], n); + /* N.B. copy_to_user may work only partially */ + n -= copy_to_user(*b, &tty->read_buf[tty->read_tail], n); tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); tty->read_cnt -= n; *b += n; @@ -854,6 +882,7 @@ do_it_again: check of the logic of this change. -- jlc */ /* don't stop on /dev/console */ if (file->f_dentry->d_inode->i_rdev != CONSOLE_DEV && + file->f_dentry->d_inode->i_rdev != SYSCONS_DEV && current->tty == tty) { if (tty->pgrp <= 0) printk("read_chan: tty->pgrp <= 0!\n"); @@ -866,7 +895,7 @@ do_it_again: } } - if (L_ICANON(tty)) { + if (tty->icanon) { minimum = time = 0; current->timeout = (unsigned long) -1; } else { @@ -895,9 +924,10 @@ do_it_again: while (1) { /* First test for status change. */ if (tty->packet && tty->link->ctrl_status) { - if (b != buf) + if (b != buf || !nr) break; put_user(tty->link->ctrl_status, b++); + nr--; tty->link->ctrl_status = 0; break; } @@ -935,50 +965,52 @@ do_it_again: current->state = TASK_RUNNING; /* Deal with packet mode. */ - if (tty->packet && b == buf) { + if (tty->packet && b == buf && nr) { put_user(TIOCPKT_DATA, b++); nr--; } - if (L_ICANON(tty)) { - while (1) { - int eol; + if (tty->icanon) { + /* N.B. avoid overrun if nr == 0 */ + while (nr && tty->read_cnt) { + int eol; - if (!tty->read_cnt) { - break; - } eol = test_and_clear_bit(tty->read_tail, &tty->read_flags); c = tty->read_buf[tty->read_tail]; tty->read_tail = ((tty->read_tail+1) & (N_TTY_BUF_SIZE-1)); tty->read_cnt--; - if (!eol) { - put_user(c, b++); - if (--nr) - continue; - break; - } - if (--tty->canon_data < 0) { - tty->canon_data = 0; - } - if (c != __DISABLED_CHAR) { + + if (!eol || (c != __DISABLED_CHAR)) { put_user(c, b++); nr--; } - break; + if (eol) { + /* this test should be redundant: + * we shouldn't be reading data if + * canon_data is 0 + */ + if (--tty->canon_data < 0) + tty->canon_data = 0; + break; + } } } else { + /* N.B. check for errors writing to user space? */ copy_from_read_buf(tty, &b, &nr); copy_from_read_buf(tty, &b, &nr); } /* If there is enough space in the read buffer now, let the - low-level driver know. */ - if (tty->driver.unthrottle && - (tty->read_cnt <= TTY_THRESHOLD_UNTHROTTLE) - && test_and_clear_bit(TTY_THROTTLED, &tty->flags)) - tty->driver.unthrottle(tty); + * low-level driver know. We use n_tty_chars_in_buffer() to + * check the buffer, as it now knows about canonical mode. + * Otherwise, if the driver is throttled and the line is + * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, + * we won't get any more characters. + */ + if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) + check_unthrottle(tty); if (b - buf >= minimum || !nr) break; @@ -1012,7 +1044,8 @@ static ssize_t write_chan(struct tty_struct * tty, struct file * file, ssize_t retval = 0, num; /* Job control check -- must be done at start (POSIX.1 7.1.1.4). */ - if (L_TOSTOP(tty) && file->f_dentry->d_inode->i_rdev != CONSOLE_DEV) { + if (L_TOSTOP(tty) && file->f_dentry->d_inode->i_rdev != CONSOLE_DEV && + file->f_dentry->d_inode->i_rdev != SYSCONS_DEV) { retval = tty_check_change(tty); if (retval) return retval; @@ -1045,6 +1078,10 @@ static ssize_t write_chan(struct tty_struct * tty, struct file * file, tty->driver.flush_chars(tty); } else { c = tty->driver.write(tty, 1, b, nr); + if (c < 0) { + retval = c; + break; + } b += c; nr -= c; } diff --git a/drivers/char/pcwd.c b/drivers/char/pcwd.c index 213306349..207fc4cf4 100644 --- a/drivers/char/pcwd.c +++ b/drivers/char/pcwd.c @@ -29,6 +29,7 @@ * 961118 Changed some verbiage on some of the output, tidied up * code bits, and added compatibility to 2.1.x. * 970912 Enabled board on open and disable on close. + * 971107 Took account of recent VFS changes (broke read). */ #include <linux/module.h> @@ -222,7 +223,7 @@ static void pcwd_send_heartbeat(void) } static int pcwd_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { int i, cdat, rv; static struct watchdog_info ident= @@ -359,8 +360,13 @@ static int pcwd_ioctl(struct inode *inode, struct file *file, return 0; } -static long pcwd_write(struct inode *inode, struct file *file, const char *buf, unsigned long len) +static ssize_t pcwd_write(struct file *file, const char *buf, size_t len, + loff_t *ppos) { + /* Can't seek (pwrite) on this device */ + if (ppos != &file->f_pos) + return -ESPIPE; + if (len) { pcwd_send_heartbeat(); @@ -381,11 +387,15 @@ static int pcwd_open(struct inode *ino, struct file *filep) return(0); } -static ssize_t pcwd_read(struct file *file, char *buf, size_t count, loff_t *ppos) +static ssize_t pcwd_read(struct file *file, char *buf, size_t count, + loff_t *ppos) { unsigned short c = inb(current_readport); unsigned char cp; + /* Can't seek (pread) on this device */ + if (ppos != &file->f_pos) + return -ESPIPE; switch(MINOR(file->f_dentry->d_inode->i_rdev)) { case TEMP_MINOR: @@ -488,11 +498,16 @@ static struct file_operations pcwd_fops = { pcwd_read, /* Read */ pcwd_write, /* Write */ NULL, /* Readdir */ - NULL, /* Select */ + NULL, /* Poll */ pcwd_ioctl, /* IOctl */ NULL, /* MMAP */ pcwd_open, /* Open */ - pcwd_close /* Close */ + pcwd_close, /* Release */ + NULL, /* Fsync */ + NULL, /* Fasync */ + NULL, /* CheckMediaChange */ + NULL, /* Revalidate */ + NULL, /* Lock */ }; static struct miscdevice pcwd_miscdev = { diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index ef9af462b..2a616142c 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c @@ -622,7 +622,7 @@ static void init_r_port(int board, int aiop, int chan) rp_table[line] = info; } -#if (LINUX_VERSION_CODE < 131393) /* Linux 2.1.65 */ +#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */ static int baud_table[] = { 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, @@ -673,7 +673,7 @@ static void configure_r_port(struct r_port *info) } /* baud rate */ -#if (LINUX_VERSION_CODE < 131393) /* Linux 2.1.65 */ +#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */ i = cflag & CBAUD; if (i & CBAUDEX) { i &= ~CBAUDEX; @@ -974,7 +974,21 @@ static int rp_open(struct tty_struct *tty, struct file * filp) sEnTransmit(cp); info->flags |= ROCKET_INITIALIZED; - + +#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */ + /* + * Set up the tty->alt_speed kludge + */ + if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI) + info->tty->alt_speed = 57600; + if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI) + info->tty->alt_speed = 115200; + if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI) + info->tty->alt_speed = 230400; + if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP) + info->tty->alt_speed = 460800; +#endif + configure_r_port(info); if (tty->termios->c_cflag & CBAUD) { sSetDTR(cp); @@ -1190,7 +1204,7 @@ static void rp_set_termios(struct tty_struct *tty, struct termios *old_termios) /* * Here are the routines used by rp_ioctl */ -#if (LINUX_VERSION_CODE < 131393) /* Linux 2.1.65 */ +#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */ static void send_break( struct r_port * info, int duration) { current->state = TASK_INTERRUPTIBLE; @@ -1316,7 +1330,7 @@ static int set_config(struct r_port * info, struct rocket_config * new_info) info->close_delay = new_serial.close_delay; info->closing_wait = new_serial.closing_wait; -#if (LINUX_VERSION_CODE >= 131393) /* Linux 2.1.65 */ +#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */ if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI) info->tty->alt_speed = 57600; if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI) @@ -1357,7 +1371,7 @@ static int rp_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) { struct r_port * info = (struct r_port *)tty->driver_data; -#if (LINUX_VERSION_CODE < 131393) /* Linux 2.1.65 */ +#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */ int retval, tmp; #endif @@ -1366,7 +1380,7 @@ static int rp_ioctl(struct tty_struct *tty, struct file * file, return -ENODEV; switch (cmd) { -#if (LINUX_VERSION_CODE < 131393) /* Linux 2.1.65 */ +#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */ case TCSBRK: /* SVID version: non-zero arg --> no break */ retval = tty_check_change(tty); if (retval) @@ -2133,7 +2147,7 @@ __initfunc(int rp_init(void)) rocket_driver.stop = rp_stop; rocket_driver.start = rp_start; rocket_driver.hangup = rp_hangup; -#if (LINUX_VERSION_CODE >= 131393) /* Linux 2.1.65 */ +#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */ rocket_driver.break_ctl = rp_break; #endif #if (LINUX_VERSION_CODE >= 131343) diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 26cfa4768..1b1990480 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -52,11 +52,11 @@ #include <linux/fcntl.h> #include <linux/mc146818rtc.h> #include <linux/init.h> +#include <linux/poll.h> #include <asm/io.h> #include <asm/uaccess.h> #include <asm/system.h> -#include <asm/poll.h> /* Adjust starting epoch if ARC console time is being used */ #ifdef CONFIG_RTC_ARC diff --git a/drivers/char/serial.c b/drivers/char/serial.c index 7d21673aa..7af575780 100644 --- a/drivers/char/serial.c +++ b/drivers/char/serial.c @@ -51,6 +51,9 @@ #include <linux/mm.h> #include <linux/malloc.h> #include <linux/init.h> +#ifdef CONFIG_SERIAL_CONSOLE +#include <linux/console.h> +#endif #include <asm/system.h> #include <asm/io.h> @@ -158,6 +161,9 @@ static int IRQ_timeout[16]; static volatile int rs_irq_triggered; static volatile int rs_triggered; static int rs_wild_int_mask; +#ifdef CONFIG_SERIAL_CONSOLE +static struct console sercons; +#endif static void autoconfig(struct serial_state * info); static void change_speed(struct async_struct *info); @@ -1303,6 +1309,20 @@ static int startup(struct async_struct * info) timer_active |= 1 << RS_TIMER; /* + * Set up the tty->alt_speed kludge + */ + if (info->tty) { + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) + info->tty->alt_speed = 57600; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) + info->tty->alt_speed = 115200; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) + info->tty->alt_speed = 230400; + if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) + info->tty->alt_speed = 460800; + } + + /* * and set the speed of the serial port */ change_speed(info); @@ -1469,7 +1489,8 @@ static void change_speed(struct async_struct *info) /* Determine divisor based on baud rate */ baud = tty_get_baud_rate(info->tty); baud_base = info->state->baud_base; - if (baud == 38400) + if (baud == 38400 && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) quot = info->state->custom_divisor; else { if (baud == 134) @@ -2830,7 +2851,13 @@ static int rs_open(struct tty_struct *tty, struct file * filp) *tty->termios = info->state->callout_termios; change_speed(info); } - +#ifdef CONFIG_SERIAL_CONSOLE + if (sercons.cflag && sercons.index == line) { + tty->termios->c_cflag = sercons.cflag; + sercons.cflag = 0; + change_speed(info); + } +#endif info->session = current->session; info->pgrp = current->pgrp; @@ -3288,7 +3315,18 @@ __initfunc(int rs_init(void)) sizeof(struct rs_multiport_struct)); #endif } - +#ifdef CONFIG_SERIAL_CONSOLE + /* + * The interrupt of the serial console port + * can't be shared. + */ + if (sercons.flags & CON_FIRST) { + for(i = 0; i < NR_PORTS; i++) + if (i != sercons.index && + rs_table[i].irq == rs_table[sercons.index].irq) + rs_table[i].irq = 0; + } +#endif show_serial_version(); /* Initialize the tty_driver structure */ @@ -3491,53 +3529,51 @@ void cleanup_module(void) */ #ifdef CONFIG_SERIAL_CONSOLE -#include <linux/console.h> +#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) /* - * this defines the index into rs_table for the port to use + * Wait for transmitter & holding register to empty */ -#ifndef CONFIG_SERIAL_CONSOLE_PORT -#define CONFIG_SERIAL_CONSOLE_PORT 0 -#endif - -#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) - -/* Wait for transmitter & holding register to empty */ static inline void wait_for_xmitr(struct serial_state *ser) { int lsr; + unsigned int tmout = 1000000; + do { lsr = inb(ser->port + UART_LSR); + if (--tmout == 0) break; } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY); } /* - * Print a string to the serial port trying not to disturb any possible - * real use of the port... + * Print a string to the serial port trying not to disturb + * any possible real use of the port... */ -static void serial_console_write(const char *s, unsigned count) +static void serial_console_write(struct console *co, const char *s, + unsigned count) { struct serial_state *ser; int ier; unsigned i; - ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT; + ser = rs_table + co->index; /* - * First save the IER then disable the interrupts + * First save the IER then disable the interrupts */ ier = inb(ser->port + UART_IER); outb(0x00, ser->port + UART_IER); /* - * Now, do each character + * Now, do each character */ for (i = 0; i < count; i++, s++) { wait_for_xmitr(ser); - /* Send the character out. */ + /* + * Send the character out. + * If a LF, also do CR... + */ outb(*s, ser->port + UART_TX); - - /* if a LF, also do CR... */ if (*s == 10) { wait_for_xmitr(ser); outb(13, ser->port + UART_TX); @@ -3545,29 +3581,29 @@ static void serial_console_write(const char *s, unsigned count) } /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER + * Finally, Wait for transmitter & holding register to empty + * and restore the IER */ wait_for_xmitr(ser); outb(ier, ser->port + UART_IER); } /* - * Receive character from the serial port + * Receive character from the serial port */ -static void serial_console_wait_key(void) +static int serial_console_wait_key(struct console *co) { struct serial_state *ser; int ier; int lsr; int c; - ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT; + ser = rs_table + co->index; /* - * First save the IER then disable the interrupts so - * that the real driver for the port does not get the - * character. + * First save the IER then disable the interrupts so + * that the real driver for the port does not get the + * character. */ ier = inb(ser->port + UART_IER); outb(0x00, ser->port + UART_IER); @@ -3577,41 +3613,151 @@ static void serial_console_wait_key(void) } while (!(lsr & UART_LSR_DR)); c = inb(ser->port + UART_RX); - /* Restore the interrupts */ + /* + * Restore the interrupts + */ outb(ier, ser->port + UART_IER); + + return c; } -static int serial_console_device(void) +static kdev_t serial_console_device(struct console *c) { - return MKDEV(TTYAUX_MAJOR, 64 + CONFIG_SERIAL_CONSOLE_PORT); + return MKDEV(TTY_MAJOR, 64 + c->index); } -long serial_console_init(long kmem_start, long kmem_end) +/* + * Setup initial baud/bits/parity. We do two things here: + * - construct a cflag setting for the first rs_open() + * - initialize the serial port + * Return non-zero if we didn't find a serial port. + */ +__initfunc(static int serial_console_setup(struct console *co, char *options)) { - static struct console console = { - serial_console_write, 0, - serial_console_wait_key, serial_console_device - }; struct serial_state *ser; + unsigned cval; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int cflag = CREAD | HUPCL | CLOCAL; + int quot = 0; + char *s; + + if (options) { + baud = simple_strtoul(options, NULL, 10); + s = options; + while(*s >= '0' && *s <= '9') + s++; + if (*s) parity = *s++; + if (*s) bits = *s - '0'; + } - ser = rs_table + CONFIG_SERIAL_CONSOLE_PORT; + /* + * Now construct a cflag setting. + */ + switch(baud) { + case 1200: + cflag |= B1200; + break; + case 2400: + cflag |= B2400; + break; + case 4800: + cflag |= B4800; + break; + case 19200: + cflag |= B19200; + break; + case 38400: + cflag |= B38400; + break; + case 57600: + cflag |= B57600; + break; + case 115200: + cflag |= B115200; + break; + case 9600: + default: + cflag |= B9600; + break; + } + switch(bits) { + case 7: + cflag |= CS7; + break; + default: + case 8: + cflag |= CS8; + break; + } + switch(parity) { + case 'o': case 'O': + cflag |= PARODD; + break; + case 'e': case 'E': + cflag |= PARENB; + break; + } + co->cflag = cflag; - /* Disable all interrupts, it works in polled mode */ - outb(0x00, ser->port + UART_IER); + /* + * Divisor, bytesize and parity + */ + ser = rs_table + co->index; + quot = BASE_BAUD / baud; + cval = cflag & (CSIZE | CSTOPB); +#if defined(__powerpc__) || defined(__alpha__) + cval >>= 8; +#else /* !__powerpc__ && !__alpha__ */ + cval >>= 4; +#endif /* !__powerpc__ && !__alpha__ */ + if (cflag & PARENB) + cval |= UART_LCR_PARITY; + if (!(cflag & PARODD)) + cval |= UART_LCR_EPAR; /* - * now do hardwired init + * Disable UART interrupts, set DTR and RTS high + * and set speed. */ - outb(0x03, ser->port + UART_LCR); /* No parity, 8 data bits, 1 stop */ - outb(0x83, ser->port + UART_LCR); /* Access divisor latch */ - outb(0x00, ser->port + UART_DLM); /* 9600 baud */ - outb(0x0c, ser->port + UART_DLL); - outb(0x03, ser->port + UART_LCR); /* Done with divisor */ + outb(0, ser->port + UART_IER); + outb(UART_MCR_DTR | UART_MCR_RTS, ser->port + UART_MCR); + outb(cval | UART_LCR_DLAB, ser->port + UART_LCR); /* set DLAB */ + outb(quot & 0xff, ser->port + UART_DLL); /* LS of divisor */ + outb(quot >> 8, ser->port + UART_DLM); /* MS of divisor */ + outb(cval, ser->port + UART_LCR); /* reset DLAB */ - register_console(&console); - return kmem_start; + /* + * If we read 0xff from the LSR, there is no UART here. + */ + if (inb(ser->port + UART_LSR) == 0xff) + return -1; + return 0; } +static struct console sercons = { + "ttyS", + serial_console_write, + NULL, + serial_console_device, + serial_console_wait_key, + NULL, + serial_console_setup, + CON_PRINTBUFFER, + -1, + 0, + NULL +}; + +/* + * Register console. + */ +__initfunc (long serial_console_init(long kmem_start, long kmem_end)) +{ + register_console(&sercons); + return kmem_start; +} #endif #ifdef CONFIG_REMOTE_DEBUG diff --git a/drivers/char/softdog.c b/drivers/char/softdog.c index be63f08b4..c0ecaccf4 100644 --- a/drivers/char/softdog.c +++ b/drivers/char/softdog.c @@ -115,6 +115,10 @@ static void softdog_ping(void) static ssize_t softdog_write(struct file *file, const char *data, size_t len, loff_t *ppos) { + /* Can't seek (pwrite) on this device */ + if (ppos != &file->f_pos) + return -ESPIPE; + /* * Refresh the timer. */ diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 8e378215f..9fadb9e4e 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c @@ -101,11 +101,34 @@ typedef struct { int irqtype; } stlconf_t; +/*static stlconf_t stl_brdconf[] = { + { BRD_EASYIO, 0x2a0, 0, 0, 10, 0 }, +};*/ + +#ifdef MODULE +static char *brdtype[STL_MAXBRDS] = {"\0", }; +static int io[STL_MAXBRDS] = { 0, }; +static int secio[STL_MAXBRDS] = { 0, }; +static int irq[STL_MAXBRDS] = { 0, }; + +MODULE_PARM(brdtype, "1-" __MODULE_STRING(STL_MAXBRDS) "s"); +MODULE_PARM(io, "1-" __MODULE_STRING(STL_MAXBRDS) "i"); +MODULE_PARM(secio, "1-" __MODULE_STRING(STL_MAXBRDS) "i"); +MODULE_PARM(irq, "1-" __MODULE_STRING(STL_MAXBRDS) "i"); + +static stlconf_t stl_brdconf[STL_MAXBRDS]; +static int stl_nrbrds = 0; + +#else static stlconf_t stl_brdconf[] = { { BRD_EASYIO, 0x2a0, 0, 0, 10, 0 }, + { BRD_EASYIO, 0x2a8, 0, 0, 10, 0 }, + { BRD_EASYIO, 0x2b0, 0, 0, 10, 0 }, + { BRD_ECH, 0x2a0, 0x240, 0, 10, 0 }, }; static int stl_nrbrds = sizeof(stl_brdconf) / sizeof(stlconf_t); +#endif /*****************************************************************************/ @@ -616,9 +639,22 @@ static struct file_operations stl_fsiomem = { * Loadable module initialization stuff. */ +struct board_type_elem +{ + int type_id; + char *name; +}; + +struct board_type_elem board_types[] = { + { BRD_EASYIO, "easyio" }, + { BRD_ECH, "ech" }, + { BRD_ECHMC, "echmc" }, + { BRD_ECHPCI, "echpci" } }; + int init_module() { unsigned long flags; + int i, j, num_board_types; #if DEBUG printk("init_module()\n"); @@ -626,6 +662,25 @@ int init_module() save_flags(flags); cli(); + + num_board_types = sizeof(board_types) / sizeof(struct board_type_elem); + for (i = 0; (i < STL_MAXBRDS && io[i]); i++) + { + stl_brdconf[stl_nrbrds].brdtype = 0; + for (j = 0; j < num_board_types; j++) + if(strcmp(board_types[j].name, brdtype[i]) == 0) + stl_brdconf[stl_nrbrds].brdtype = board_types[j].type_id; + if(stl_brdconf[stl_nrbrds].brdtype != 0) + { + stl_brdconf[stl_nrbrds].ioaddr1 = io[i]; + stl_brdconf[stl_nrbrds].ioaddr2 = secio[i]; + stl_brdconf[stl_nrbrds].memaddr = 0; + stl_brdconf[stl_nrbrds].irq = irq[i]; + stl_brdconf[stl_nrbrds].irqtype = 0; + stl_nrbrds++; + } + } + stl_init(); restore_flags(flags); @@ -823,7 +878,10 @@ static int stl_open(struct tty_struct *tty, struct file *filp) return(-EBUSY); } else { if ((rc = stl_waitcarrier(portp, filp)) != 0) + { + MOD_INC_USE_COUNT; return(rc); + } } portp->flags |= ASYNC_NORMAL_ACTIVE; } @@ -838,6 +896,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp) portp->session = current->session; portp->pgrp = current->pgrp; + MOD_INC_USE_COUNT; return(0); } @@ -925,6 +984,7 @@ static void stl_close(struct tty_struct *tty, struct file *filp) restore_flags(flags); return; } + MOD_DEC_USE_COUNT; if (portp->refcount-- > 1) { restore_flags(flags); return; @@ -2237,10 +2297,12 @@ static inline int stl_initbrds() printk("stl_initbrds()\n"); #endif +#ifndef MODULE if (stl_nrbrds > STL_MAXBRDS) { printk("STALLION: too many boards in configuration table, truncating to %d\n", STL_MAXBRDS); stl_nrbrds = STL_MAXBRDS; } +#endif /* * Firstly scan the list of static boards configured. Allocate diff --git a/drivers/char/tga.c b/drivers/char/tga.c index f4e7b48ab..d824294ec 100644 --- a/drivers/char/tga.c +++ b/drivers/char/tga.c @@ -443,6 +443,19 @@ void set_vesa_blanking(const unsigned long arg) { } + +/* + * See if we have a TGA card. + */ +__initfunc(int con_is_present()) +{ + int status; + + status = pcibios_find_device (PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA, + 0, &pci_bus, &pci_devfn); + return (status == PCIBIOS_DEVICE_NOT_FOUND) ? 0 : 1; +} + /* * video init code, called from within the PCI bus probing code; * when TGA console is configured, at the end of the probing code, diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index a2f092b74..1c1beddab 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -90,6 +90,7 @@ #define CONSOLE_DEV MKDEV(TTY_MAJOR,0) #define TTY_DEV MKDEV(TTYAUX_MAJOR,0) +#define SYSCONS_DEV MKDEV(TTYAUX_MAJOR,1) #undef TTY_DEBUG_HANGUP @@ -386,7 +387,8 @@ void do_tty_hangup(void *data) continue; if (!filp->f_dentry->d_inode) continue; - if (filp->f_dentry->d_inode->i_rdev == CONSOLE_DEV) + if (filp->f_dentry->d_inode->i_rdev == CONSOLE_DEV || + filp->f_dentry->d_inode->i_rdev == SYSCONS_DEV) continue; if (filp->f_op != &tty_fops) continue; @@ -517,9 +519,7 @@ void disassociate_ctty(int on_exit) void wait_for_keypress(void) { struct console *c = console_drivers; - while(c && !c->wait_key) - c = c->next; - if (c) c->wait_key(); + if (c) c->wait_key(c); } void stop_tty(struct tty_struct *tty) @@ -647,8 +647,13 @@ static ssize_t tty_write(struct file * file, const char * buf, size_t count, if (ppos != &file->f_pos) return -ESPIPE; + /* + * For now, we redirect writes from /dev/console as + * well as /dev/tty0. + */ inode = file->f_dentry->d_inode; - is_console = (inode->i_rdev == CONSOLE_DEV); + is_console = (inode->i_rdev == SYSCONS_DEV || + inode->i_rdev == CONSOLE_DEV); if (is_console && redirect) tty = redirect; @@ -1182,13 +1187,20 @@ retry_open: filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ /* noctty = 1; */ } +#ifdef CONFIG_VT if (device == CONSOLE_DEV) { + extern int fg_console; + device = MKDEV(TTY_MAJOR, fg_console + 1); + noctty = 1; + } +#endif + if (device == SYSCONS_DEV) { struct console *c = console_drivers; while(c && !c->device) c = c->next; if (!c) return -ENODEV; - device = c->device(); + device = c->device(c); noctty = 1; } minor = MINOR(device); @@ -1369,7 +1381,8 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, static int tioccons(struct tty_struct *tty, struct tty_struct *real_tty) { - if (tty->driver.type == TTY_DRIVER_TYPE_CONSOLE) { + if (tty->driver.type == TTY_DRIVER_TYPE_CONSOLE || + tty->driver.type == TTY_DRIVER_TYPE_SYSCONS) { if (!suser()) return -EPERM; redirect = NULL; @@ -1466,6 +1479,19 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t return 0; } +static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t *arg) +{ + /* + * (tty == real_tty) is a cheap way of + * testing if the tty is NOT a master pty. + */ + if (tty == real_tty && current->tty != real_tty) + return -ENOTTY; + if (real_tty->session <= 0) + return -ENOTTY; + return put_user(real_tty->session, arg); +} + static int tiocttygstruct(struct tty_struct *tty, struct tty_struct *arg) { if (copy_to_user(arg, tty, sizeof(*arg))) @@ -1585,6 +1611,8 @@ static int tty_ioctl(struct inode * inode, struct file * file, return tiocgpgrp(tty, real_tty, (pid_t *) arg); case TIOCSPGRP: return tiocspgrp(tty, real_tty, (pid_t *) arg); + case TIOCGSID: + return tiocgsid(tty, real_tty, (pid_t *) arg); case TIOCGETD: return put_user(tty->ldisc.num, (int *) arg); case TIOCSETD: @@ -1742,8 +1770,13 @@ int tty_get_baud_rate(struct tty_struct *tty) else i += 15; } - if (i==15 && tty->alt_speed) + if (i==15 && tty->alt_speed) { + if (!tty->warned) { + printk("Use of setserial/setrocket to set SPD_* flags is deprecated\n"); + tty->warned = 1; + } return(tty->alt_speed); + } return baud_table[i]; } @@ -1885,16 +1918,17 @@ long console_init(long kmem_start, long kmem_end) * set up the console device so that later boot sequences can * inform about problems etc.. */ -#ifdef CONFIG_SERIAL_CONSOLE - kmem_start = serial_console_init(kmem_start, kmem_end); -#endif #ifdef CONFIG_VT kmem_start = con_init(kmem_start); #endif +#ifdef CONFIG_SERIAL_CONSOLE + kmem_start = serial_console_init(kmem_start, kmem_end); +#endif return kmem_start; } -static struct tty_driver dev_tty_driver, dev_console_driver; +static struct tty_driver dev_tty_driver, dev_console_driver, + dev_syscons_driver; /* * Ok, now we can initialize the rest of the tty devices and can count @@ -1925,17 +1959,28 @@ __initfunc(int tty_init(void)) if (tty_register_driver(&dev_tty_driver)) panic("Couldn't register /dev/tty driver\n"); + dev_syscons_driver = dev_tty_driver; + dev_syscons_driver.driver_name = "/dev/console"; + dev_syscons_driver.name = dev_syscons_driver.driver_name + 5; + dev_syscons_driver.major = TTYAUX_MAJOR; + dev_syscons_driver.minor_start = 1; + dev_syscons_driver.type = TTY_DRIVER_TYPE_SYSTEM; + dev_syscons_driver.subtype = SYSTEM_TYPE_SYSCONS; + + if (tty_register_driver(&dev_syscons_driver)) + panic("Couldn't register /dev/console driver\n"); + +#ifdef CONFIG_VT dev_console_driver = dev_tty_driver; - dev_console_driver.driver_name = "/dev/console"; + dev_console_driver.driver_name = "/dev/tty0"; dev_console_driver.name = dev_console_driver.driver_name + 5; dev_console_driver.major = TTY_MAJOR; dev_console_driver.type = TTY_DRIVER_TYPE_SYSTEM; dev_console_driver.subtype = SYSTEM_TYPE_CONSOLE; if (tty_register_driver(&dev_console_driver)) - panic("Couldn't register /dev/console driver\n"); + panic("Couldn't register /dev/tty0 driver\n"); -#ifdef CONFIG_VT kbd_init(); #endif #ifdef CONFIG_ESPSERIAL /* init ESP before rs, so rs doesn't see the port */ @@ -1965,6 +2010,9 @@ __initfunc(int tty_init(void)) #ifdef CONFIG_RISCOM8 riscom8_init(); #endif +#ifdef CONFIG_SPECIALIX + specialix_init(); +#endif pty_init(); #ifdef CONFIG_VT vcs_init(); diff --git a/drivers/char/vga.c b/drivers/char/vga.c index c3fee1ae7..3c932ad7c 100644 --- a/drivers/char/vga.c +++ b/drivers/char/vga.c @@ -57,7 +57,6 @@ #ifdef __mips__ #include <asm/bootinfo.h> -#include <asm/deskstation.h> #include <asm/sni.h> /* * The video control ports are mapped at virtual address @@ -166,6 +165,31 @@ set_cursor(int currcons) hide_cursor(); } +__initfunc(int con_is_present(void)) +{ + unsigned short saved; + unsigned short *p; + + /* + * Find out if there is a graphics card present. + * Are there smarter methods around? + */ + p = (unsigned short *) video_mem_base; + saved = scr_readw(p); + scr_writew(0xAA55, p); + if (scr_readw(p) != 0xAA55) { + scr_writew(saved, p); + return 0; + } + scr_writew(0x55AA, p); + if (scr_readw(p) != 0x55AA) { + scr_writew(saved, p); + return 0; + } + scr_writew(saved, p); + return 1; +} + __initfunc(unsigned long con_type_init(unsigned long kmem_start, const char **display_desc)) { @@ -219,32 +243,6 @@ con_type_init(unsigned long kmem_start, const char **display_desc)) } else #endif -#ifdef CONFIG_DESKSTATION_RPC44 - /* - * KLUDGE -- imp - */ - if (mips_machgroup == MACH_GROUP_ARC - && mips_machtype == MACH_DESKSTATION_RPC44) - { - /* XXX */ - can_do_color = 1; - video_port_base = RPC44_PORT_BASE; - video_port_reg = 0x3d4; - video_port_val = 0x3d5; - video_type = VIDEO_TYPE_VGAC; - video_mem_base = 0xa00a000; - video_mem_term = video_mem_base + 0x8000; - *display_desc = "IMP-HACK"; - screen_info.orig_video_ega_bx = 0x11; - screen_info.orig_video_mode = 8; /* not 7 */ - screen_info.orig_video_isVGA = 1; - /* - * Don't request a region - the video ports are outside of - * the normal port address range. - */ - } - else -#endif if (ORIG_VIDEO_MODE == 7) /* Is this a monochrome display? */ { video_mem_base = 0xb0000 + VGA_OFFSET; diff --git a/drivers/char/videodev.c b/drivers/char/videodev.c index 71e88f04c..38b9a6743 100644 --- a/drivers/char/videodev.c +++ b/drivers/char/videodev.c @@ -249,7 +249,7 @@ int videodev_init(void) return 0; } - +#ifdef MODULE int init_module(void) { return videodev_init(); @@ -260,5 +260,7 @@ void cleanup_module(void) unregister_chrdev(VIDEO_MAJOR, "video_capture"); } +#endif + EXPORT_SYMBOL(video_register_device); EXPORT_SYMBOL(video_unregister_device); diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 6ba0c687d..12924d2f5 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -730,7 +730,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, extern int spawnpid, spawnsig; if (!perm) return -EPERM; - if (arg < 1 || arg > NSIG || arg == SIGKILL) + if (arg < 1 || arg > _NSIG || arg == SIGKILL) return -EINVAL; spawnpid = current->pid; spawnsig = arg; diff --git a/drivers/char/wdt.c b/drivers/char/wdt.c index 37f444e29..36af5fdcc 100644 --- a/drivers/char/wdt.c +++ b/drivers/char/wdt.c @@ -53,7 +53,7 @@ static int wdt_is_open=0; */ static int io=0x240; -static int irq=14; +static int irq=11; #define WD_TIMO (100*60) /* 1 minute */ @@ -171,6 +171,10 @@ static void wdt_ping(void) static ssize_t wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { + /* Can't seek (pwrite) on this device */ + if (ppos != &file->f_pos) + return -ESPIPE; + if(count) { wdt_ping(); @@ -189,6 +193,10 @@ static ssize_t wdt_read(struct file *file, char *buf, size_t count, loff_t *ptr) unsigned char cp; int err; + /* Can't seek (pread) on this device */ + if (ptr != &file->f_pos) + return -ESPIPE; + switch(MINOR(file->f_dentry->d_inode->i_rdev)) { case TEMP_MINOR: |