308 lines
6.9 KiB
Plaintext
308 lines
6.9 KiB
Plaintext
Ptch, um den seriellen Treiber nachladen zu können.
|
|
|
|
Warnung: Seit einiger Zeit nicht mehr getestet.
|
|
|
|
--- /pub/src/linux/kernel/linux-1.1/drivers/char/serial.c Tue Jan 24 12:44:05 1995
|
|
+++ drivers/char/serial.c Sat Feb 11 07:12:10 1995
|
|
@@ -17,6 +17,14 @@
|
|
* int rs_open(struct tty_struct * tty, struct file * filp)
|
|
*/
|
|
|
|
+#ifdef MODULE
|
|
+#include <linux/version.h>
|
|
+#include <linux/module.h>
|
|
+#else
|
|
+#define MOD_INC_USE_COUNT
|
|
+#define MOD_DEC_USE_COUNT
|
|
+#endif
|
|
+
|
|
#include <linux/errno.h>
|
|
#include <linux/signal.h>
|
|
#include <linux/sched.h>
|
|
@@ -80,11 +88,13 @@
|
|
* should be after the IRQ has been active.
|
|
*/
|
|
|
|
-static struct async_struct *IRQ_ports[16];
|
|
+static struct async_struct *IRQ_ports[16] = {NULL,};
|
|
static int IRQ_timeout[16];
|
|
+#ifndef MODULE
|
|
static volatile int rs_irq_triggered;
|
|
static volatile int rs_triggered;
|
|
static int rs_wild_int_mask;
|
|
+#endif
|
|
|
|
static void autoconfig(struct async_struct * info);
|
|
static void change_speed(struct async_struct *info);
|
|
@@ -343,6 +353,7 @@
|
|
* -----------------------------------------------------------------------
|
|
*/
|
|
|
|
+#ifndef MODULE
|
|
/*
|
|
* This is the serial driver's interrupt routine while we are probing
|
|
* for submarines.
|
|
@@ -353,6 +364,7 @@
|
|
rs_triggered |= 1 << irq;
|
|
return;
|
|
}
|
|
+#endif
|
|
|
|
/*
|
|
* This routine is used by the interrupt handler to schedule
|
|
@@ -788,6 +804,7 @@
|
|
* ---------------------------------------------------------------
|
|
*/
|
|
|
|
+#ifndef MODULE
|
|
/*
|
|
* Grab all interrupts in preparation for doing an automatic irq
|
|
* detection. dontgrab is a mask of irq's _not_ to grab. Returns a
|
|
@@ -819,6 +836,7 @@
|
|
free_irq(i);
|
|
}
|
|
}
|
|
+#endif
|
|
|
|
/*
|
|
* This routine figures out the correct timeout for a particular IRQ.
|
|
@@ -1632,6 +1650,7 @@
|
|
sti();
|
|
}
|
|
|
|
+#ifndef MODULE
|
|
/*
|
|
* This routine returns a bitfield of "wild interrupts". Basically,
|
|
* any unclaimed interrupts which is flapping around.
|
|
@@ -1675,6 +1694,7 @@
|
|
restore_flags(flags);
|
|
return wild_interrupts;
|
|
}
|
|
+#endif
|
|
|
|
static int rs_ioctl(struct tty_struct *tty, struct file * file,
|
|
unsigned int cmd, unsigned long arg)
|
|
@@ -1745,6 +1765,7 @@
|
|
case TIOCSERCONFIG:
|
|
return do_autoconfig(info);
|
|
|
|
+#ifndef MODULE
|
|
case TIOCSERGWILD:
|
|
error = verify_area(VERIFY_WRITE, (void *) arg,
|
|
sizeof(int));
|
|
@@ -1752,6 +1773,7 @@
|
|
return error;
|
|
put_fs_long(rs_wild_int_mask, (unsigned long *) arg);
|
|
return 0;
|
|
+#endif
|
|
|
|
case TIOCSERGETLSR: /* Get line status register */
|
|
error = verify_area(VERIFY_WRITE, (void *) arg,
|
|
@@ -1761,6 +1783,7 @@
|
|
else
|
|
return get_lsr_info(info, (unsigned int *) arg);
|
|
|
|
+#ifndef MODULE
|
|
case TIOCSERSWILD:
|
|
if (!suser())
|
|
return -EPERM;
|
|
@@ -1768,6 +1791,7 @@
|
|
if (rs_wild_int_mask < 0)
|
|
rs_wild_int_mask = check_wild_interrupts(0);
|
|
return 0;
|
|
+#endif
|
|
|
|
case TIOCSERGSTRUCT:
|
|
error = verify_area(VERIFY_WRITE, (void *) arg,
|
|
@@ -1835,6 +1859,7 @@
|
|
|
|
if (tty_hung_up_p(filp)) {
|
|
restore_flags(flags);
|
|
+ MOD_DEC_USE_COUNT;
|
|
return;
|
|
}
|
|
|
|
@@ -1860,6 +1885,7 @@
|
|
}
|
|
if (info->count) {
|
|
restore_flags(flags);
|
|
+ MOD_DEC_USE_COUNT;
|
|
return;
|
|
}
|
|
info->flags |= ASYNC_CLOSING;
|
|
@@ -1923,6 +1949,7 @@
|
|
ASYNC_CLOSING);
|
|
wake_up_interruptible(&info->close_wait);
|
|
restore_flags(flags);
|
|
+ MOD_DEC_USE_COUNT;
|
|
}
|
|
|
|
/*
|
|
@@ -2097,22 +2124,27 @@
|
|
printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
|
|
info->count);
|
|
#endif
|
|
+ MOD_INC_USE_COUNT;
|
|
info->count++;
|
|
tty->driver_data = info;
|
|
info->tty = tty;
|
|
|
|
if (!tmp_buf) {
|
|
tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL);
|
|
- if (!tmp_buf)
|
|
+ if (!tmp_buf) {
|
|
+ MOD_DEC_USE_COUNT;
|
|
return -ENOMEM;
|
|
}
|
|
+ }
|
|
|
|
/*
|
|
* Start up serial port
|
|
*/
|
|
retval = startup(info);
|
|
- if (retval)
|
|
+ if (retval) {
|
|
+ MOD_DEC_USE_COUNT;
|
|
return retval;
|
|
+ }
|
|
|
|
retval = block_til_ready(tty, filp, info);
|
|
if (retval) {
|
|
@@ -2120,6 +2152,7 @@
|
|
printk("rs_open returning after block_til_ready with %d\n",
|
|
retval);
|
|
#endif
|
|
+ MOD_DEC_USE_COUNT;
|
|
return retval;
|
|
}
|
|
|
|
@@ -2168,6 +2201,8 @@
|
|
#undef SERIAL_OPT
|
|
}
|
|
|
|
+
|
|
+#ifndef MODULE
|
|
/*
|
|
* This routine is called by do_auto_irq(); it attempts to determine
|
|
* which interrupt a serial port is configured to use. It is not
|
|
@@ -2259,6 +2294,7 @@
|
|
free_all_interrupts(irq_lines);
|
|
return (irq_try_1 == irq_try_2) ? irq_try_1 : 0;
|
|
}
|
|
+#endif /* CONFIG_SERIAL */
|
|
|
|
/*
|
|
* This routine is called by rs_init() to initialize a specific serial
|
|
@@ -2322,12 +2358,14 @@
|
|
}
|
|
}
|
|
|
|
+#ifndef MODULE
|
|
/*
|
|
* If the AUTO_IRQ flag is set, try to do the automatic IRQ
|
|
* detection.
|
|
*/
|
|
if (info->flags & ASYNC_AUTO_IRQ)
|
|
info->irq = do_auto_irq(info);
|
|
+#endif
|
|
|
|
serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
|
|
scratch = serial_in(info, UART_IIR) >> 6;
|
|
@@ -2382,15 +2420,31 @@
|
|
/*
|
|
* The serial driver boot-time initialization code!
|
|
*/
|
|
+#ifdef MODULE
|
|
+
|
|
+char kernel_version[]= UTS_RELEASE;
|
|
+
|
|
+void cleanup_module(void)
|
|
+{
|
|
+ tty_unregister_driver(&serial_driver);
|
|
+ tty_unregister_driver(&callout_driver);
|
|
+ bh_base[SERIAL_BH].routine = NULL;
|
|
+ timer_table[RS_TIMER].fn = NULL;
|
|
+}
|
|
+
|
|
+int init_module(void)
|
|
+#else
|
|
long rs_init(long kmem_start)
|
|
+#endif
|
|
{
|
|
- int i;
|
|
+ int i, err;
|
|
struct async_struct * info;
|
|
|
|
bh_base[SERIAL_BH].routine = do_serial_bh;
|
|
+ enable_bh(SERIAL_BH);
|
|
timer_table[RS_TIMER].fn = rs_timer;
|
|
timer_table[RS_TIMER].expires = 0;
|
|
-#ifdef CONFIG_AUTO_IRQ
|
|
+#if defined(CONFIG_AUTO_IRQ) && !defined(MODULE)
|
|
rs_wild_int_mask = check_wild_interrupts(1);
|
|
#endif
|
|
|
|
@@ -2445,10 +2499,15 @@
|
|
callout_driver.major = TTYAUX_MAJOR;
|
|
callout_driver.subtype = SERIAL_TYPE_CALLOUT;
|
|
|
|
- if (tty_register_driver(&serial_driver))
|
|
- panic("Couldn't register serial driver\n");
|
|
- if (tty_register_driver(&callout_driver))
|
|
- panic("Couldn't register callout driver\n");
|
|
+ if ((err = tty_register_driver(&serial_driver)) < 0) {
|
|
+ printk("Couldn't register serial driver\n");
|
|
+ return err;
|
|
+ }
|
|
+ if ((err = tty_register_driver(&callout_driver)) < 0) {
|
|
+ printk("Couldn't register callout driver\n");
|
|
+ tty_unregister_driver(&serial_driver);
|
|
+ return err;
|
|
+ }
|
|
|
|
for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
|
|
info->magic = SERIAL_MAGIC;
|
|
@@ -2471,6 +2530,7 @@
|
|
info->prev_port = 0;
|
|
if (info->irq == 2)
|
|
info->irq = 9;
|
|
+#ifndef MODULE
|
|
if (!(info->flags & ASYNC_BOOT_AUTOCONF))
|
|
continue;
|
|
autoconfig(info);
|
|
@@ -2496,8 +2556,13 @@
|
|
printk("\n");
|
|
break;
|
|
}
|
|
+#endif
|
|
}
|
|
+#ifndef MODULE
|
|
return kmem_start;
|
|
+#else
|
|
+ return 0;
|
|
+#endif
|
|
}
|
|
|
|
/*
|
|
@@ -2533,12 +2598,14 @@
|
|
"device already open\n", i, req->port, req->irq);
|
|
return -1;
|
|
}
|
|
+ MOD_INC_USE_COUNT;
|
|
info->irq = req->irq;
|
|
info->port = req->port;
|
|
autoconfig(info);
|
|
if (info->type == PORT_UNKNOWN) {
|
|
restore_flags(flags);
|
|
printk("register_serial(): autoconfig failed\n");
|
|
+ MOD_DEC_USE_COUNT;
|
|
return -1;
|
|
}
|
|
printk("tty%02d at 0x%04x (irq = %d)", info->line,
|
|
@@ -2571,4 +2638,5 @@
|
|
info->type = PORT_UNKNOWN;
|
|
printk("tty%02d unloaded\n", info->line);
|
|
restore_flags(flags);
|
|
+ MOD_DEC_USE_COUNT;
|
|
}
|