Commit 6b4869cb authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.7

parent d86fb96f
...@@ -668,7 +668,7 @@ S: Chapel Hill, North Carolina 27514-4818 ...@@ -668,7 +668,7 @@ S: Chapel Hill, North Carolina 27514-4818
S: USA S: USA
N: Bernhard Kaindl N: Bernhard Kaindl
E: bartelt@computerhaus.at E: edv@bartelt.via.at
D: Author of a menu based configuration tool, kmenu, which D: Author of a menu based configuration tool, kmenu, which
D: is the predecessor of 'make menuconfig' and 'make xconfig'. D: is the predecessor of 'make menuconfig' and 'make xconfig'.
S: Tallak 95 S: Tallak 95
...@@ -1161,7 +1161,8 @@ D: the gpm mouse server and kernel support for it ...@@ -1161,7 +1161,8 @@ D: the gpm mouse server and kernel support for it
N: Thomas Sailer N: Thomas Sailer
E: sailer@ife.ee.ethz.ch E: sailer@ife.ee.ethz.ch
D: Baycom radio modem driver E: HB9JNX@HB9W.CHE.EU (packet radio)
D: Baycom and Soundcard radio modem driver
S: Weinbergstrasse 76 S: Weinbergstrasse 76
S: 8408 Winterthur S: 8408 Winterthur
S: Switzerland S: Switzerland
......
...@@ -1875,17 +1875,29 @@ CONFIG_SCC ...@@ -1875,17 +1875,29 @@ CONFIG_SCC
running kernel whenever you want), say M here and read running kernel whenever you want), say M here and read
Documentation/modules.txt. Documentation/modules.txt.
BAYCOM ser12 and par96 kiss emulation driver for AX.25 BAYCOM ser12 and par96 driver for AX.25
CONFIG_BAYCOM CONFIG_BAYCOM
This is an experimental driver for Baycom style simple amateur radio This is an experimental driver for Baycom style simple amateur radio
modems that connect to either a serial interface or a parallel modems that connect to either a serial interface or a parallel
interface. The driver supports the ser12 and par96 designs. To interface. The driver supports the ser12 and par96 designs. To
configure the driver, use the setbaycom utility available from configure the driver, use the sethdlc utility available
http://www.ife.ee.ethz.ch/~sailer/ham/ham.html#lnxbay. For in the standard ax25 utilities package. For information on the modems,
information on the modems, see http://www.baycom.de and see http://www.baycom.de and drivers/net/README.baycom.
drivers/char/README.baycom. If you want to compile this as a module If you want to compile this as a module ( = code which can be
( = code which can be inserted in and removed from the running inserted in and removed from the running kernel whenever you want),
kernel whenever you want), say M here and read say M here and read Documentation/modules.txt. This is recommended.
Soundcard modem driver for AX.25
CONFIG_SOUNDMODEM
This experimental driver allows a standard SoundBlaster or
WindowsSoundSystem compatible soundcard to be used as a packet radio
modem. To configure the driver, use the sethdlc, smdiag and smmixer
utilities available in the standard ax25 utilities package. For
informations on how to key the transmitter, see
http://www.ife.ee.ethz.ch/~sailer/pcf/ptt_circ/ptt.html and
drivers/net/README.soundmodem. If you want to compile this as a
module ( = code which can be inserted in and removed from the
running kernel whenever you want), say M here and read
Documentation/modules.txt. This is recommended. Documentation/modules.txt. This is recommended.
PLIP (parallel port) support PLIP (parallel port) support
......
VERSION = 2 VERSION = 2
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 6 SUBLEVEL = 7
ARCH = i386 ARCH = i386
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#define osf_vfork sys_fork #define osf_vfork sys_fork
/* /*
* These offsets must match with "struct hae" in io.h: * These offsets must match with "struct hae" in io.h:
*/ */
#define HAE_CACHE 0 #define HAE_CACHE 0
#define HAE_REG 8 #define HAE_REG 8
...@@ -142,9 +142,29 @@ entInt: ...@@ -142,9 +142,29 @@ entInt:
.ent entMM .ent entMM
entMM: entMM:
SAVE_ALL SAVE_ALL
lda $27,do_page_fault /* save $9 - $15 so the inline exception code can manipulate them. */
lda $26,ret_from_sys_call subq $30,56,$30
jsr $31,($27),do_page_fault stq $9,0($30)
stq $10,8($30)
stq $11,16($30)
stq $12,24($30)
stq $13,32($30)
stq $14,40($30)
stq $15,48($30)
addq $30,56,$19
/* handle the fault */
jsr $26,do_page_fault
/* reload the registers after the exception code played. */
ldq $9,0($30)
ldq $10,8($30)
ldq $11,16($30)
ldq $12,24($30)
ldq $13,32($30)
ldq $14,40($30)
ldq $15,48($30)
addq $30,56,$30
/* finish up the syscall as normal. */
br ret_from_sys_call
.end entMM .end entMM
.align 3 .align 3
...@@ -190,7 +210,7 @@ kernel_clone: ...@@ -190,7 +210,7 @@ kernel_clone:
SAVE_ALL SAVE_ALL
lda $27,sys_clone lda $27,sys_clone
jsr $26,($27),sys_clone jsr $26,($27),sys_clone
stq $0,0($30) stq $0,0($30)
br $31,ret_from_sys_call br $31,ret_from_sys_call
.end kernel_clone .end kernel_clone
...@@ -424,7 +444,7 @@ entUnaUser: ...@@ -424,7 +444,7 @@ entUnaUser:
/* /*
* A fork is the same as clone(SIGCHLD, 0); * A fork is the same as clone(SIGCHLD, 0);
*/ */
.align 3 .align 3
.globl sys_fork .globl sys_fork
.ent sys_fork .ent sys_fork
...@@ -508,7 +528,7 @@ ret_from_sys_call: ...@@ -508,7 +528,7 @@ ret_from_sys_call:
ldq $4,0($2) ldq $4,0($2)
addq $1,1,$1 addq $1,1,$1
and $3,$4,$2 and $3,$4,$2
bne $2,handle_bottom_half bne $2,handle_bottom_half
ret_from_handle_bh: ret_from_handle_bh:
ldq $0,SP_OFF($30) ldq $0,SP_OFF($30)
and $0,8,$0 and $0,8,$0
...@@ -529,9 +549,9 @@ ret_from_reschedule: ...@@ -529,9 +549,9 @@ ret_from_reschedule:
restore_all: restore_all:
RESTORE_ALL RESTORE_ALL
rti rti
/* PTRACE syscall handler */ /* PTRACE syscall handler */
.align 3 .align 3
strace: strace:
/* set up signal stack, call syscall_trace */ /* set up signal stack, call syscall_trace */
...@@ -588,7 +608,7 @@ strace_error: ...@@ -588,7 +608,7 @@ strace_error:
lda $27,syscall_trace lda $27,syscall_trace
jsr $26,($27),syscall_trace jsr $26,($27),syscall_trace
bis $9,$9,$19 bis $9,$9,$19
bis $10,$10,$20 bis $10,$10,$20
bsr $1,undo_switch_stack bsr $1,undo_switch_stack
bis $31,$31,$26 /* tell "ret_from_sys_call" that we can restart */ bis $31,$31,$26 /* tell "ret_from_sys_call" that we can restart */
......
...@@ -178,63 +178,217 @@ struct unaligned_stat { ...@@ -178,63 +178,217 @@ struct unaligned_stat {
unsigned long count, va, pc; unsigned long count, va, pc;
} unaligned[2]; } unaligned[2];
/* Macro for exception fixup code to access integer registers. */
#define una_reg(r) (regs.regs[(r) >= 16 && (r) <= 18 ? (r)+19 : (r)])
asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg, asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg,
unsigned long a3, unsigned long a4, unsigned long a5, unsigned long a3, unsigned long a4, unsigned long a5,
struct allregs regs) struct allregs regs)
{ {
static int cnt = 0; static int cnt = 0;
static long last_time = 0; static long last_time = 0;
long error, tmp1, tmp2, tmp3, tmp4;
unsigned long pc = regs.pc - 4;
unsigned fixup;
if (cnt >= 5 && jiffies - last_time > 5*HZ) { if (cnt >= 5 && jiffies - last_time > 5*HZ) {
cnt = 0; cnt = 0;
} }
if (++cnt < 5) { if (++cnt < 5) {
printk("kernel: unaligned trap at %016lx: %p %lx %ld\n", printk("kernel: unaligned trap at %016lx: %p %lx %ld\n",
regs.pc - 4, va, opcode, reg); pc, va, opcode, reg);
} }
last_time = jiffies; last_time = jiffies;
++unaligned[0].count; unaligned[0].count++;
unaligned[0].va = (unsigned long) va - 4; unaligned[0].va = (unsigned long) va;
unaligned[0].pc = regs.pc; unaligned[0].pc = pc;
/* $16-$18 are PAL-saved, and are offset by 19 entries */ /* We don't want to use the generic get/put unaligned macros as
if (reg >= 16 && reg <= 18) we want to trap exceptions. Only if we actually get an
reg += 19; exception will we decide whether we should have caught it. */
{ switch (opcode) {
/* Set up an exception handler address just in case we are #ifdef __HAVE_CPU_BWX
handling an unaligned fixup within get_user(). Notice case 0x0c: /* ldwu */
that we do *not* change the exception count because we __asm__ __volatile__(
only want to bounce possible exceptions on through. */ "1: ldq_u %1,0(%3)\n"
"2: ldq_u %2,1(%3)\n"
__label__ handle_ex; " extwl %1,%3,%1\n"
register void *ex_vector __asm__("$28"); " extwh %2,%3,%2\n"
__asm__ __volatile__ ("" : "=r"(ex_vector) : "0"(&&handle_ex)); "3:\n"
".section __ex_table,\"a\"\n"
switch (opcode) { " .gprel32 1b\n"
case 0x28: /* ldl */ " lda %1,3b-1b(%0)\n"
*(reg+regs.regs) = get_unaligned((int *)va); " .gprel32 2b\n"
return; " lda %2,3b-2b(%0)\n"
case 0x29: /* ldq */ ".text"
*(reg+regs.regs) = get_unaligned((long *)va); : "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
return; : "r"(va), "0"(0));
case 0x2c: /* stl */ if (error)
put_unaligned(*(reg+regs.regs), (int *)va); goto got_exception;
return; una_reg(reg) = tmp1|tmp2;
case 0x2d: /* stq */ return;
put_unaligned(*(reg+regs.regs), (long *)va); #endif
return;
case 0x28: /* ldl */
/* We'll only get back here if we are handling a __asm__ __volatile__(
valid exception. */ "1: ldq_u %1,0(%3)\n"
handle_ex: "2: ldq_u %2,3(%3)\n"
(&regs)->pc = *(28+regs.regs); " extll %1,%3,%1\n"
return; " extlh %2,%3,%2\n"
} "3:\n"
".section __ex_table,\"a\"\n"
" .gprel32 1b\n"
" lda %1,3b-1b(%0)\n"
" .gprel32 2b\n"
" lda %2,3b-2b(%0)\n"
".text"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
: "r"(va), "0"(0));
if (error)
goto got_exception;
una_reg(reg) = (int)(tmp1|tmp2);
return;
case 0x29: /* ldq */
__asm__ __volatile__(
"1: ldq_u %1,0(%3)\n"
"2: ldq_u %2,7(%3)\n"
" extql %1,%3,%1\n"
" extqh %2,%3,%2\n"
"3:\n"
".section __ex_table,\"a\"\n"
" .gprel32 1b\n"
" lda %1,3b-1b(%0)\n"
" .gprel32 2b\n"
" lda %2,3b-2b(%0)\n"
".text"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2)
: "r"(va), "0"(0));
if (error)
goto got_exception;
una_reg(reg) = tmp1|tmp2;
return;
/* Note that the store sequences do not indicate that they change
memory because it _should_ be affecting nothing in this context.
(Otherwise we have other, much larger, problems.) */
#ifdef __HAVE_CPU_BWX
case 0x0d: /* stw */
__asm__ __volatile__(
"1: ldq_u %2,1(%5)\n"
"2: ldq_u %1,0(%5)\n"
" inswh %6,%5,%4\n"
" inswl %6,%5,%3\n"
" mskwh %2,%5,%2\n"
" mskwl %1,%5,%1\n"
" or %2,%4,%2\n"
" or %1,%3,%1\n"
"3: stq_u %2,1(%5)\n"
"4: stq_u %1,0(%5)\n"
"5:\n"
".section __ex_table,\"a\"\n"
" .gprel32 1b\n"
" lda %2,5b-1b(%0)\n"
" .gprel32 2b\n"
" lda %1,5b-2b(%0)\n"
" .gprel32 3b\n"
" lda $31,5b-3b(%0)\n"
" .gprel32 4b\n"
" lda $31,5b-4b(%0)\n"
".text"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
"=&r"(tmp3), "=&r"(tmp4)
: "r"(va), "r"(una_reg(reg)), "0"(0));
if (error)
goto got_exception;
return;
#endif
case 0x2c: /* stl */
__asm__ __volatile__(
"1: ldq_u %2,3(%5)\n"
"2: ldq_u %1,0(%5)\n"
" inslh %6,%5,%4\n"
" insll %6,%5,%3\n"
" msklh %2,%5,%2\n"
" mskll %1,%5,%1\n"
" or %2,%4,%2\n"
" or %1,%3,%1\n"
"3: stq_u %2,3(%5)\n"
"4: stq_u %1,0(%5)\n"
"5:\n"
".section __ex_table,\"a\"\n"
" .gprel32 1b\n"
" lda %2,5b-1b(%0)\n"
" .gprel32 2b\n"
" lda %1,5b-2b(%0)\n"
" .gprel32 3b\n"
" lda $31,5b-3b(%0)\n"
" .gprel32 4b\n"
" lda $31,5b-4b(%0)\n"
".text"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
"=&r"(tmp3), "=&r"(tmp4)
: "r"(va), "r"(una_reg(reg)), "0"(0));
if (error)
goto got_exception;
return;
case 0x2d: /* stq */
__asm__ __volatile__(
"1: ldq_u %2,7(%5)\n"
"2: ldq_u %1,0(%5)\n"
" insqh %6,%5,%4\n"
" insql %6,%5,%3\n"
" mskqh %2,%5,%2\n"
" mskql %1,%5,%1\n"
" or %2,%4,%2\n"
" or %1,%3,%1\n"
"3: stq_u %2,7(%5)\n"
"4: stq_u %1,0(%5)\n"
"5:\n"
".section __ex_table,\"a\"\n\t"
" .gprel32 1b\n"
" lda %2,5b-1b(%0)\n"
" .gprel32 2b\n"
" lda %1,5b-2b(%0)\n"
" .gprel32 3b\n"
" lda $31,5b-3b(%0)\n"
" .gprel32 4b\n"
" lda $31,5b-4b(%0)\n"
".text"
: "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
"=&r"(tmp3), "=&r"(tmp4)
: "r"(va), "r"(una_reg(reg)), "0"(0));
if (error)
goto got_exception;
return;
} }
printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n", printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n",
regs.pc, va, opcode, reg); pc, va, opcode, reg);
do_exit(SIGSEGV);
return;
got_exception:
/* Ok, we caught the exception, but we don't want it. Is there
someone to pass it along to? */
if ((fixup = search_exception_table(pc)) != 0) {
unsigned long newpc;
newpc = fixup_exception(una_reg, fixup, pc);
printk("Forwarding unaligned exception at %lx (%lx)\n",
pc, newpc);
(&regs)->pc = newpc;
return;
}
/* Yikes! No one to forward the exception to. */
printk("%s: unhandled unaligned exception at pc=%lx ra=%lx"
" (bad address = %p)\n", current->comm,
pc, una_reg(26), va);
do_exit(SIGSEGV); do_exit(SIGSEGV);
} }
......
...@@ -25,6 +25,14 @@ ...@@ -25,6 +25,14 @@
* $1,$2,$3,$4,$5,$6 * $1,$2,$3,$4,$5,$6
*/ */
/* Allow an exception for an insn; exit if we get one. */
#define EX(x,y...) \
99: x,##y; \
.section __ex_table,"a"; \
.gprel32 99b; \
lda $31, $exception-99b($31); \
.text
.set noat .set noat
.set noreorder .set noreorder
.align 4 .align 4
...@@ -38,7 +46,7 @@ $loop: ...@@ -38,7 +46,7 @@ $loop:
and $1, 3, $4 # e0 : and $1, 3, $4 # e0 :
beq $4, 1f # .. e1 : beq $4, 1f # .. e1 :
0: stq_u $31, 0($6) # e0 : zero one word 0: EX( stq_u $31, 0($6) ) # e0 : zero one word
subq $0, 8, $0 # .. e1 : subq $0, 8, $0 # .. e1 :
subq $4, 1, $4 # e0 : subq $4, 1, $4 # e0 :
addq $6, 8, $6 # .. e1 : addq $6, 8, $6 # .. e1 :
...@@ -48,13 +56,13 @@ $loop: ...@@ -48,13 +56,13 @@ $loop:
1: bic $1, 3, $1 # e0 : 1: bic $1, 3, $1 # e0 :
beq $1, $tail # .. e1 : beq $1, $tail # .. e1 :
2: stq_u $31, 0($6) # e0 : zero four words 2: EX( stq_u $31, 0($6) ) # e0 : zero four words
subq $0, 8, $0 # .. e1 : subq $0, 8, $0 # .. e1 :
stq_u $31, 8($6) # e0 : EX( stq_u $31, 8($6) ) # e0 :
subq $0, 8, $0 # .. e1 : subq $0, 8, $0 # .. e1 :
stq_u $31, 16($6) # e0 : EX( stq_u $31, 16($6) ) # e0 :
subq $0, 8, $0 # .. e1 : subq $0, 8, $0 # .. e1 :
stq_u $31, 24($6) # e0 : EX( stq_u $31, 24($6) ) # e0 :
subq $0, 8, $0 # .. e1 : subq $0, 8, $0 # .. e1 :
subq $1, 4, $1 # e0 : subq $1, 4, $1 # e0 :
addq $6, 32, $6 # .. e1 : addq $6, 32, $6 # .. e1 :
...@@ -62,35 +70,29 @@ $loop: ...@@ -62,35 +70,29 @@ $loop:
$tail: $tail:
bne $2, 1f # e1 : is there a tail to do? bne $2, 1f # e1 : is there a tail to do?
stq $3, 0($7) # e0 : decrement exception count
ret $31, ($28), 1 # .. e1 : ret $31, ($28), 1 # .. e1 :
1: ldq_u $5, 0($6) # e1 : 1: EX( ldq_u $5, 0($6) ) # e0 :
mskqh $5, $0, $5 # e0 :
stq_u $5, 0($6) # e0 :
clr $0 # .. e1 : clr $0 # .. e1 :
stq $3, 0($7) # e0 : decrement exception count nop # e1 :
mskqh $5, $0, $5 # e0 :
EX( stq_u $5, 0($6) ) # e0 :
ret $31, ($28), 1 # .. e1 : ret $31, ($28), 1 # .. e1 :
__clear_user: __clear_user:
ldq $3, 0($7) # e0 : load exception count for increment
beq $0, $zerolength # .. e1 :
and $6, 7, $4 # e0 : find dest misalignment and $6, 7, $4 # e0 : find dest misalignment
addq $0, $4, $1 # e1 : bias counter beq $0, $zerolength # .. e1 :
addq $3, 1, $5 # e0 : addq $0, $4, $1 # e0 : bias counter
and $1, 7, $2 # .. e1 : number of bytes in tail and $1, 7, $2 # e1 : number of bytes in tail
srl $1, 3, $1 # e0 : srl $1, 3, $1 # e0 :
unop # :
stq $5, 0($7) # e0 : increment exception count
beq $4, $loop # .. e1 : beq $4, $loop # .. e1 :
ldq_u $5, 0($6) # e0 : load dst word to mask back in EX( ldq_u $5, 0($6) ) # e0 : load dst word to mask back in
beq $1, $oneword # .. e1 : sub-word store? beq $1, $oneword # .. e1 : sub-word store?
mskql $5, $6, $5 # e0 : take care of misaligned head mskql $5, $6, $5 # e0 : take care of misaligned head
addq $6, 8, $6 # .. e1 : addq $6, 8, $6 # .. e1 :
stq_u $5, -8($6) # e0 : EX( stq_u $5, -8($6) ) # e0 :
addq $0, $4, $0 # .. e1 : bytes left -= 8 - misalignment addq $0, $4, $0 # .. e1 : bytes left -= 8 - misalignment
subq $1, 1, $1 # e0 : subq $1, 1, $1 # e0 :
subq $0, 8, $0 # .. e1 : subq $0, 8, $0 # .. e1 :
...@@ -101,11 +103,11 @@ $oneword: ...@@ -101,11 +103,11 @@ $oneword:
mskql $5, $6, $4 # e0 : mskql $5, $6, $4 # e0 :
mskqh $5, $2, $5 # e0 : mskqh $5, $2, $5 # e0 :
or $5, $4, $5 # e1 : or $5, $4, $5 # e1 :
stq_u $5, 0($6) # e0 : EX( stq_u $5, 0($6) ) # e0 :
clr $0 # .. e1 : clr $0 # .. e1 :
stq $3, 0($7) # e0 : decrement exception count
$zerolength: $zerolength:
$exception:
ret $31, ($28), 1 # .. e1 : ret $31, ($28), 1 # .. e1 :
.end __clear_user .end __clear_user
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* destination address in $6 * destination address in $6
* source address in $7 * source address in $7
* exception pointer in $8 * exception pointer in $8
* return address in $28 (exceptions expect it there) * return address in $28
* *
* Outputs: * Outputs:
* bytes left to copy in $0 * bytes left to copy in $0
...@@ -27,28 +27,33 @@ ...@@ -27,28 +27,33 @@
* $1,$2,$3,$4,$5,$6,$7 * $1,$2,$3,$4,$5,$6,$7
*/ */
/* Allow an exception for an insn; exit if we get one. */
#define EX(x,y...) \
99: x,##y; \
.section __ex_table,"a"; \
.gprel32 99b; \
lda $31, $exit-99b($31); \
.text
.set noat .set noat
.align 3 .align 3
.globl __copy_user .globl __copy_user
.ent __copy_user .ent __copy_user
__copy_user: __copy_user:
ldq $5,0($8)
beq $0,$35
and $6,7,$3 and $6,7,$3
addq $5,1,$1 beq $0,$35
stq $1,0($8)
beq $3,$36 beq $3,$36
subq $3,8,$3 subq $3,8,$3
.align 5 .align 5
$37: $37:
ldq_u $1,0($7) EX( ldq_u $1,0($7) )
ldq_u $2,0($6) EX( ldq_u $2,0($6) )
extbl $1,$7,$1 extbl $1,$7,$1
mskbl $2,$6,$2 mskbl $2,$6,$2
insbl $1,$6,$1 insbl $1,$6,$1
addq $3,1,$3 addq $3,1,$3
bis $1,$2,$1 bis $1,$2,$1
stq_u $1,0($6) EX( stq_u $1,0($6) )
subq $0,1,$0 subq $0,1,$0
addq $6,1,$6 addq $6,1,$6
addq $7,1,$7 addq $7,1,$7
...@@ -59,10 +64,10 @@ $36: ...@@ -59,10 +64,10 @@ $36:
bic $0,7,$4 bic $0,7,$4
beq $1,$43 beq $1,$43
beq $4,$48 beq $4,$48
ldq_u $3,0($7) EX( ldq_u $3,0($7) )
.align 5 .align 5
$50: $50:
ldq_u $2,8($7) EX( ldq_u $2,8($7) )
subq $4,8,$4 subq $4,8,$4
extql $3,$7,$3 extql $3,$7,$3
extqh $2,$7,$1 extqh $2,$7,$1
...@@ -77,13 +82,13 @@ $48: ...@@ -77,13 +82,13 @@ $48:
beq $0,$41 beq $0,$41
.align 5 .align 5
$57: $57:
ldq_u $1,0($7) EX( ldq_u $1,0($7) )
ldq_u $2,0($6) EX( ldq_u $2,0($6) )
extbl $1,$7,$1 extbl $1,$7,$1
mskbl $2,$6,$2 mskbl $2,$6,$2
insbl $1,$6,$1 insbl $1,$6,$1
bis $1,$2,$1 bis $1,$2,$1
stq_u $1,0($6) EX( stq_u $1,0($6) )
subq $0,1,$0 subq $0,1,$0
addq $6,1,$6 addq $6,1,$6
addq $7,1,$7 addq $7,1,$7
...@@ -93,9 +98,8 @@ $57: ...@@ -93,9 +98,8 @@ $57:
$43: $43:
beq $4,$65 beq $4,$65
.align 5 .align 5
.align 5
$66: $66:
ldq $1,0($7) EX( ldq $1,0($7) )
subq $4,8,$4 subq $4,8,$4
stq $1,0($6) stq $1,0($6)
addq $7,8,$7 addq $7,8,$7
...@@ -104,15 +108,15 @@ $66: ...@@ -104,15 +108,15 @@ $66:
bne $4,$66 bne $4,$66
$65: $65:
beq $0,$41 beq $0,$41
ldq $2,0($7) EX( ldq $2,0($7) )
ldq $1,0($6) EX( ldq $1,0($6) )
mskql $2,$0,$2 mskql $2,$0,$2
mskqh $1,$0,$1 mskqh $1,$0,$1
bis $2,$1,$2 bis $2,$1,$2
stq $2,0($6) EX( stq $2,0($6) )
bis $31,$31,$0 bis $31,$31,$0
$41: $41:
stq $5,0($8)
$35: $35:
$exit:
ret $31,($28),1 ret $31,($28),1
.end __copy_user .end __copy_user
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# #
# Note 2! The CFLAGS definition is now in the main makefile... # Note 2! The CFLAGS definition is now in the main makefile...
OBJS = init.o fault.o OBJS = init.o fault.o extable.o
mm.o: $(OBJS) mm.o: $(OBJS)
$(LD) -r -o mm.o $(OBJS) $(LD) -r -o mm.o $(OBJS)
......
/*
* linux/arch/alpha/mm/extable.c
*/
#include <asm/uaccess.h>
extern const struct exception_table_entry __start___ex_table[];
extern const struct exception_table_entry __stop___ex_table[];
static inline unsigned
search_one_table(const struct exception_table_entry *first,
const struct exception_table_entry *last,
signed int value)
{
while (first <= last) {
const struct exception_table_entry *mid;
long diff;
mid = (last - first) / 2 + first;
diff = mid->insn - value;
if (diff == 0)
return mid->fixup.unit;
else if (diff < 0)
first = mid+1;
else
last = mid-1;
}
return 0;
}
unsigned
search_exception_table(unsigned long addr)
{
unsigned ret;
signed int reladdr;
/* Search the kernel's table first. */
{
register unsigned long gp __asm__("$29");
reladdr = addr - gp;
}
ret = search_one_table(__start___ex_table,
__stop___ex_table-1, reladdr);
if (ret)
return ret;
/* FIXME -- search the module's tables here */
return 0;
}
...@@ -52,14 +52,24 @@ extern void die_if_kernel(char *,struct pt_regs *,long); ...@@ -52,14 +52,24 @@ extern void die_if_kernel(char *,struct pt_regs *,long);
* -1 = instruction fetch * -1 = instruction fetch
* 0 = load * 0 = load
* 1 = store * 1 = store
*
* Registers $9 through $15 are saved in a block just prior to `regs' and
* are saved and restored around the call to allow exception code to
* modify them.
*/ */
asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr, long cause,
unsigned long a3, unsigned long a4, unsigned long a5, /* Macro for exception fixup code to access integer registers. */
struct pt_regs regs) #define dpf_reg(r) \
(((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-16 : \
(r) <= 18 ? (r)+8 : (r)-10])
asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr,
long cause, struct pt_regs *regs)
{ {
struct vm_area_struct * vma; struct vm_area_struct * vma;
struct task_struct *tsk = current; struct task_struct *tsk = current;
struct mm_struct *mm = tsk->mm; struct mm_struct *mm = tsk->mm;
unsigned fixup;
down(&mm->mmap_sem); down(&mm->mmap_sem);
vma = find_vma(mm, address); vma = find_vma(mm, address);
...@@ -97,18 +107,21 @@ asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr, long c ...@@ -97,18 +107,21 @@ asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr, long c
*/ */
bad_area: bad_area:
up(&mm->mmap_sem); up(&mm->mmap_sem);
/* Did we have an exception handler installed? */
if (current->tss.ex.count == 1) { /* Are we prepared to handle this fault as an exception? */
printk("Taking exception at %lx (%lx)\n", regs.pc, regs.r28); if ((fixup = search_exception_table(regs->pc)) != 0) {
current->tss.ex.count = 0; unsigned long newpc;
/* return to the address in r28 */ newpc = fixup_exception(dpf_reg, fixup, regs->pc);
(&regs)->pc = regs.r28; printk("Taking exception at %lx (%lx)\n", regs->pc, newpc);
regs->pc = newpc;
return; return;
} }
if (user_mode(&regs)) {
printk("%s: memory violation at pc=%08lx rp=%08lx (bad address = %08lx)\n", if (user_mode(regs)) {
tsk->comm, regs.pc, regs.r26, address); printk("%s: memory violation at pc=%08lx ra=%08lx "
die_if_kernel("oops", &regs, cause); "(bad address = %08lx)\n",
tsk->comm, regs->pc, regs->r26, address);
die_if_kernel("oops", regs, cause);
force_sig(SIGSEGV, tsk); force_sig(SIGSEGV, tsk);
return; return;
} }
...@@ -116,8 +129,8 @@ asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr, long c ...@@ -116,8 +129,8 @@ asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr, long c
* Oops. The kernel tried to access some bad page. We'll have to * Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice. * terminate things with extreme prejudice.
*/ */
printk(KERN_ALERT printk(KERN_ALERT "Unable to handle kernel paging request at "
"Unable to handle kernel paging request at virtual address %016lx\n", address); "virtual address %016lx\n", address);
die_if_kernel("Oops", &regs, cause); die_if_kernel("Oops", regs, cause);
do_exit(SIGKILL); do_exit(SIGKILL);
} }
...@@ -8,6 +8,6 @@ ...@@ -8,6 +8,6 @@
# Note 2! The CFLAGS definition is now in the main makefile... # Note 2! The CFLAGS definition is now in the main makefile...
O_TARGET := mm.o O_TARGET := mm.o
O_OBJS := init.o fault.o ioremap.o O_OBJS := init.o fault.o ioremap.o extable.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
/*
* linux/arch/i386/mm/extable.c
*/
#include <asm/uaccess.h>
extern const struct exception_table_entry __start___ex_table[];
extern const struct exception_table_entry __stop___ex_table[];
static inline unsigned long
search_one_table(const struct exception_table_entry *first,
const struct exception_table_entry *last,
unsigned long value)
{
/* Some versions of the linker are buggy and do not align the
__start pointer along with the section, thus we may be low. */
if ((long)first & 3)
(long)first = ((long)first | 3) + 1;
while (first <= last) {
const struct exception_table_entry *mid;
long diff;
mid = (last - first) / 2 + first;
diff = mid->insn - value;
if (diff == 0)
return mid->fixup;
else if (diff < 0)
first = mid+1;
else
last = mid-1;
}
return 0;
}
unsigned long
search_exception_table(unsigned long addr)
{
unsigned long ret;
/* Search the kernel's table first. */
ret = search_one_table(__start___ex_table,
__stop___ex_table-1, addr);
if (ret)
return ret;
/* FIXME -- search the module's tables here */
return 0;
}
...@@ -93,6 +93,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -93,6 +93,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
struct vm_area_struct * vma; struct vm_area_struct * vma;
unsigned long address; unsigned long address;
unsigned long page; unsigned long page;
unsigned long fixup;
int write; int write;
/* get the address */ /* get the address */
...@@ -161,14 +162,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) ...@@ -161,14 +162,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
*/ */
bad_area: bad_area:
up(&mm->mmap_sem); up(&mm->mmap_sem);
/* is there valid exception data? Return to indicated handler if so */
if (tsk->tss.ex.count == 0) { /* Are we prepared to handle this fault? */
printk("Exception at %lx (%lx)\n", regs->eip, regs->edx); if ((fixup = search_exception_table(regs->eip)) != 0) {
tsk->tss.ex.count--; printk("Exception at %lx (%lx)\n", regs->eip, fixup);
regs->eip = regs->edx; regs->eip = fixup;
regs->edx = -EFAULT;
return; return;
} }
if (error_code & 4) { if (error_code & 4) {
tsk->tss.cr2 = address; tsk->tss.cr2 = address;
tsk->tss.error_code = error_code; tsk->tss.error_code = error_code;
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#define MD_DRIVER #define MD_DRIVER
#include <linux/blk.h> #include <linux/blk.h>
#include <asm/uaccess.h>
static struct hd_struct md_hd_struct[MAX_MD_DEV]; static struct hd_struct md_hd_struct[MAX_MD_DEV];
static int md_blocksizes[MAX_MD_DEV]; static int md_blocksizes[MAX_MD_DEV];
...@@ -296,10 +297,9 @@ static int md_ioctl (struct inode *inode, struct file *file, ...@@ -296,10 +297,9 @@ static int md_ioctl (struct inode *inode, struct file *file,
case BLKGETSIZE: /* Return device size */ case BLKGETSIZE: /* Return device size */
if (!arg) return -EINVAL; if (!arg) return -EINVAL;
err=verify_area (VERIFY_WRITE, (long *) arg, sizeof(long)); err = put_user (md_hd_struct[MINOR(inode->i_rdev)].nr_sects, (long *) arg);
if (err) if (err)
return err; return err;
put_user (md_hd_struct[MINOR(inode->i_rdev)].nr_sects, (long *) arg);
break; break;
case BLKFLSBUF: case BLKFLSBUF:
...@@ -315,10 +315,9 @@ static int md_ioctl (struct inode *inode, struct file *file, ...@@ -315,10 +315,9 @@ static int md_ioctl (struct inode *inode, struct file *file,
case BLKRAGET: case BLKRAGET:
if (!arg) return -EINVAL; if (!arg) return -EINVAL;
err=verify_area (VERIFY_WRITE, (long *) arg, sizeof(long)); err = put_user (read_ahead[MAJOR(inode->i_rdev)], (long *) arg);
if (err) if (err)
return err; return err;
put_user (read_ahead[MAJOR(inode->i_rdev)], (long *) arg);
break; break;
/* We have a problem here : there is no easy way to give a CHS /* We have a problem here : there is no easy way to give a CHS
...@@ -328,14 +327,19 @@ static int md_ioctl (struct inode *inode, struct file *file, ...@@ -328,14 +327,19 @@ static int md_ioctl (struct inode *inode, struct file *file,
case HDIO_GETGEO: case HDIO_GETGEO:
if (!loc) return -EINVAL; if (!loc) return -EINVAL;
err = verify_area(VERIFY_WRITE, loc, sizeof(*loc)); err = put_user (2, (char *) &loc->heads);
if (err) if (err)
return err; return err;
put_user (2, (char *) &loc->heads); err = put_user (4, (char *) &loc->sectors);
put_user (4, (char *) &loc->sectors); if (err)
put_user (md_hd_struct[minor].nr_sects/8, (short *) &loc->cylinders); return err;
put_user (md_hd_struct[MINOR(inode->i_rdev)].start_sect, err = put_user (md_hd_struct[minor].nr_sects/8, (short *) &loc->cylinders);
if (err)
return err;
err = put_user (md_hd_struct[MINOR(inode->i_rdev)].start_sect,
(long *) &loc->start); (long *) &loc->start);
if (err)
return err;
break; break;
RO_IOCTLS(inode->i_rdev,arg); RO_IOCTLS(inode->i_rdev,arg);
...@@ -367,7 +371,7 @@ static void md_release (struct inode *inode, struct file *file) ...@@ -367,7 +371,7 @@ static void md_release (struct inode *inode, struct file *file)
} }
static int md_read (struct inode *inode, struct file *file, static long md_read (struct inode *inode, struct file *file,
char *buf, int count) char *buf, int count)
{ {
int minor=MINOR(inode->i_rdev); int minor=MINOR(inode->i_rdev);
...@@ -378,7 +382,7 @@ static int md_read (struct inode *inode, struct file *file, ...@@ -378,7 +382,7 @@ static int md_read (struct inode *inode, struct file *file,
return block_read (inode, file, buf, count); return block_read (inode, file, buf, count);
} }
static int md_write (struct inode *inode, struct file *file, static long md_write (struct inode *inode, struct file *file,
const char *buf, int count) const char *buf, int count)
{ {
int minor=MINOR(inode->i_rdev); int minor=MINOR(inode->i_rdev);
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <asm/fcntl.h> #include <asm/fcntl.h>
#include <asm/uaccess.h>
#include <linux/cdrom.h> #include <linux/cdrom.h>
#include <linux/ucdrom.h> #include <linux/ucdrom.h>
......
This diff is collapsed.
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/ftape.h> #include <linux/ftape.h>
#include <asm/segment.h> #include <asm/uaccess.h>
#include "tracing.h" #include "tracing.h"
#include "ftape-eof.h" #include "ftape-eof.h"
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/ftape.h> #include <linux/ftape.h>
#include <asm/segment.h> #include <asm/uaccess.h>
#include <asm/system.h> #include <asm/system.h>
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/mtio.h> #include <linux/mtio.h>
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/ftape.h> #include <linux/ftape.h>
#include <asm/segment.h> #include <asm/uaccess.h>
#include "tracing.h" #include "tracing.h"
#include "ftape-read.h" #include "ftape-read.h"
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/ftape.h> #include <linux/ftape.h>
#include <asm/segment.h> #include <asm/uaccess.h>
#include "tracing.h" #include "tracing.h"
#include "ftape-write.h" #include "ftape-write.h"
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <linux/version.h> #include <linux/version.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <asm/segment.h> #include <asm/uaccess.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/major.h> #include <linux/major.h>
......
...@@ -184,12 +184,14 @@ static struct symbol_table misc_syms = { ...@@ -184,12 +184,14 @@ static struct symbol_table misc_syms = {
#include <linux/symtab_end.h> #include <linux/symtab_end.h>
}; };
#if defined(CONFIG_PROC_FS) && !defined(MODULE)
static struct proc_dir_entry proc_misc = { static struct proc_dir_entry proc_misc = {
0, 4, "misc", 0, 4, "misc",
S_IFREG | S_IRUGO, 1, 0, 0, S_IFREG | S_IRUGO, 1, 0, 0,
0, NULL /* ops -- default to array */, 0, NULL /* ops -- default to array */,
&proc_misc_read /* get_info */, &proc_misc_read /* get_info */,
}; };
#endif
int misc_init(void) int misc_init(void)
{ {
......
...@@ -1940,9 +1940,6 @@ int tty_init(void) ...@@ -1940,9 +1940,6 @@ int tty_init(void)
#endif #endif
#ifdef CONFIG_RISCOM8 #ifdef CONFIG_RISCOM8
riscom8_init(); riscom8_init();
#endif
#ifdef CONFIG_BAYCOM
baycom_init();
#endif #endif
pty_init(); pty_init();
vcs_init(); vcs_init();
......
...@@ -117,6 +117,7 @@ ...@@ -117,6 +117,7 @@
* *
*/ */
#include <asm/uaccess.h>
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/version.h> #include <linux/version.h>
...@@ -915,7 +916,7 @@ void isdn_info_update(void) ...@@ -915,7 +916,7 @@ void isdn_info_update(void)
wake_up_interruptible(&(dev->info_waitq)); wake_up_interruptible(&(dev->info_waitq));
} }
static int isdn_read(struct inode *inode, struct file *file, char *buf, int count) static long isdn_read(struct inode *inode, struct file *file, char *buf, unsigned long count)
{ {
uint minor = MINOR(inode->i_rdev); uint minor = MINOR(inode->i_rdev);
int len = 0; int len = 0;
...@@ -988,12 +989,13 @@ static int isdn_read(struct inode *inode, struct file *file, char *buf, int coun ...@@ -988,12 +989,13 @@ static int isdn_read(struct inode *inode, struct file *file, char *buf, int coun
return -ENODEV; return -ENODEV;
} }
static int isdn_lseek(struct inode *inode, struct file *file, off_t offset, int orig) static long long isdn_lseek(struct inode *inode, struct file *file, long long offset, int orig)
{ {
return -ESPIPE; return -ESPIPE;
} }
static int isdn_write(struct inode *inode, struct file *file, const char *buf, int count) static long isdn_write(struct inode *inode, struct file *file,
const char *buf, unsigned long count)
{ {
uint minor = MINOR(inode->i_rdev); uint minor = MINOR(inode->i_rdev);
int drvidx; int drvidx;
......
...@@ -106,6 +106,7 @@ ...@@ -106,6 +106,7 @@
* *
*/ */
#include <asm/uaccess.h>
#include <linux/config.h> #include <linux/config.h>
#define __NO_VERSION__ #define __NO_VERSION__
#include <linux/module.h> #include <linux/module.h>
......
...@@ -73,6 +73,7 @@ ...@@ -73,6 +73,7 @@
/* TODO: right tbusy handling when using MP */ /* TODO: right tbusy handling when using MP */
#include <asm/uaccess.h>
#include <linux/config.h> #include <linux/config.h>
#define __NO_VERSION__ #define __NO_VERSION__
#include <linux/module.h> #include <linux/module.h>
...@@ -391,7 +392,7 @@ int isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long a ...@@ -391,7 +392,7 @@ int isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long a
switch (cmd) { switch (cmd) {
case PPPIOCBUNDLE: case PPPIOCBUNDLE:
#ifdef CONFIG_ISDN_MPP #ifdef CONFIG_ISDN_MPP
if ((r = get_user(val, arg))) if ((r = get_user(val, argp)))
return r; return r;
printk(KERN_DEBUG "iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n", printk(KERN_DEBUG "iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n",
(int) min, (int) is->unit, (int) val); (int) min, (int) is->unit, (int) val);
...@@ -588,7 +589,6 @@ int isdn_ppp_read(int min, struct file *file, char *buf, int count) ...@@ -588,7 +589,6 @@ int isdn_ppp_read(int min, struct file *file, char *buf, int count)
{ {
struct ippp_struct *is; struct ippp_struct *is;
struct ippp_buf_queue *b; struct ippp_buf_queue *b;
int r;
unsigned long flags; unsigned long flags;
is = file->private_data; is = file->private_data;
...@@ -1445,7 +1445,6 @@ static int isdn_ppp_dev_ioctl_stats(int slot,struct ifreq *ifr,struct device *de ...@@ -1445,7 +1445,6 @@ static int isdn_ppp_dev_ioctl_stats(int slot,struct ifreq *ifr,struct device *de
{ {
struct ppp_stats *res, t; struct ppp_stats *res, t;
isdn_net_local *lp = (isdn_net_local *) dev->priv; isdn_net_local *lp = (isdn_net_local *) dev->priv;
int err;
res = (struct ppp_stats *) ifr->ifr_ifru.ifru_data; res = (struct ppp_stats *) ifr->ifr_ifru.ifru_data;
...@@ -1476,7 +1475,7 @@ static int isdn_ppp_dev_ioctl_stats(int slot,struct ifreq *ifr,struct device *de ...@@ -1476,7 +1475,7 @@ static int isdn_ppp_dev_ioctl_stats(int slot,struct ifreq *ifr,struct device *de
int isdn_ppp_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd) int isdn_ppp_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
{ {
int error; int error = 0;
char *r; char *r;
int len; int len;
isdn_net_local *lp = (isdn_net_local *) dev->priv; isdn_net_local *lp = (isdn_net_local *) dev->priv;
......
...@@ -109,6 +109,7 @@ ...@@ -109,6 +109,7 @@
* *
*/ */
#include <asm/uaccess.h>
#define __NO_VERSION__ #define __NO_VERSION__
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
*/ */
#define __NO_VERSION__ #define __NO_VERSION__
#include "teles.h" #include "teles.h"
#include <asm/uaccess.h>
extern struct IsdnCard cards[]; extern struct IsdnCard cards[];
extern int nrcards; extern int nrcards;
......
...@@ -25,7 +25,8 @@ fi ...@@ -25,7 +25,8 @@ fi
bool 'Radio network interfaces' CONFIG_NET_RADIO bool 'Radio network interfaces' CONFIG_NET_RADIO
if [ "$CONFIG_NET_RADIO" != "n" ]; then if [ "$CONFIG_NET_RADIO" != "n" ]; then
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'BAYCOM ser12 and par96 kiss emulation driver for AX.25' CONFIG_BAYCOM tristate 'BAYCOM ser12 and par96 driver for AX.25' CONFIG_BAYCOM
tristate 'Soundcard modem driver for AX.25' CONFIG_SOUNDMODEM
fi fi
if [ "$CONFIG_AX25" = "y" ]; then if [ "$CONFIG_AX25" = "y" ]; then
bool 'Gracilis PackeTwin support' CONFIG_PT bool 'Gracilis PackeTwin support' CONFIG_PT
......
...@@ -18,6 +18,8 @@ CONFIG_8390_BUILTIN := ...@@ -18,6 +18,8 @@ CONFIG_8390_BUILTIN :=
CONFIG_8390_MODULE := CONFIG_8390_MODULE :=
CONFIG_SLHC_BUILTIN := CONFIG_SLHC_BUILTIN :=
CONFIG_SLHC_MODULE := CONFIG_SLHC_MODULE :=
CONFIG_HDLCDRV_BUILTIN :=
CONFIG_HDLCDRV_MODULE :=
ifeq ($(CONFIG_ISDN),y) ifeq ($(CONFIG_ISDN),y)
ifeq ($(CONFIG_ISDN_PPP),y) ifeq ($(CONFIG_ISDN_PPP),y)
...@@ -518,6 +520,37 @@ else ...@@ -518,6 +520,37 @@ else
endif endif
endif endif
ifeq ($(CONFIG_BAYCOM),y)
L_OBJS += baycom.o
CONFIG_HDLCDRV_BUILTIN = y
else
ifeq ($(CONFIG_BAYCOM),m)
CONFIG_HDLCDRV_MODULE = y
M_OBJS += baycom.o
endif
endif
ifeq ($(CONFIG_SOUNDMODEM),y)
L_OBJS += soundmodem.o
CONFIG_HDLCDRV_BUILTIN = y
else
ifeq ($(CONFIG_SOUNDMODEM),m)
CONFIG_HDLCDRV_MODULE = y
M_OBJS += soundmodem.o
endif
endif
# If anything built-in uses the hdlcdrv, then build it into the kernel also.
# If not, but a module uses it, build as a module.
ifdef CONFIG_HDLCDRV_BUILTIN
LX_OBJS += hdlcdrv.o
else
ifdef CONFIG_HDLCDRV_MODULE
MX_OBJS += hdlcdrv.o
endif
endif
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
clean: clean:
......
LINUX DRIVER FOR BAYCOM MODEMS LINUX DRIVER FOR BAYCOM MODEMS
Thomas M. Sailer <hb9jnx@radio.amiv.ethz.ch> Thomas M. Sailer, HB9JNX/AE4WA, <sailer@ife.ee.ethz.ch>
This document describes the Linux Kernel Driver for simple Baycom style This document describes the Linux Kernel Driver for simple Baycom style
amateur radio modems. The driver supports the following modems: amateur radio modems. The driver supports the following modems:
ser12: This is a very simple 1200 baud AFSK modem. The modem consists only ser12: This is a very simple 1200 baud AFSK modem. The modem consists only
of a modulator/demodulator chip, usually a TI TCM3105. The computer of a modulator/demodulator chip, usually a TI TCM3105. The computer
is responsible for regenerating the receiver bit clock, as well as is responsible for regenerating the receiver bit clock, as well as
for handling the HDLC protocol. The modem connects to a serial port, for handling the HDLC protocol. The modem connects to a serial port,
hence the name. Since the serial port is not used as an async serial hence the name. Since the serial port is not used as an async serial
port, the kernel driver for serial ports cannot be used, and this port, the kernel driver for serial ports cannot be used, and this
driver only supports standard serial hardware (8250, 16450, 16550) driver only supports standard serial hardware (8250, 16450, 16550)
par96: This is a modem for 9600 baud FSK compatible to the G3RUH standard. par96: This is a modem for 9600 baud FSK compatible to the G3RUH standard.
The modem does all the filtering and regenerates the receiver clock. The modem does all the filtering and regenerates the receiver clock.
Data is transferred from and to the PC via a shift register. Data is transferred from and to the PC via a shift register.
The shift register is filled with 16 bits and an interrupt is signalled. The shift register is filled with 16 bits and an interrupt is signalled.
The PC then empties the shift register in a burst. This modem connects The PC then empties the shift register in a burst. This modem connects
to the parallel port, hence the name. The modem leaves the to the parallel port, hence the name. The modem leaves the
implementation of the HDLC protocol and the scrambler polynomial to implementation of the HDLC protocol and the scrambler polynomial to
the PC. the PC.
par97: This is a redesign of the par96 modem by Henning Rech, DF9IC. The modem picpar: This is a redesign of the par96 modem by Henning Rech, DF9IC. The modem
is protocol compatible to par96, but uses only three low power ICs is protocol compatible to par96, but uses only three low power ICs
and can therefore be fed from the parallel port and does not require and can therefore be fed from the parallel port and does not require
an additional power supply. an additional power supply. Furthermore, it incorporates a carrier
detect circuitry.
All of the above modems only support half duplex communications. However, All of the above modems only support half duplex communications. However,
the driver supports the KISS (see below) fullduplex command. It then simply the driver supports the KISS (see below) fullduplex command. It then simply
...@@ -37,44 +38,14 @@ access protocol. ...@@ -37,44 +38,14 @@ access protocol.
The Interface of the driver The Interface of the driver
The driver interfaces to the AX25 stack via a KISS interface. The driver Unlike previous drivers, the driver is no longer a character device,
can be accessed as a character device with major 60. Major 60 is the first but it is now a true kernel network interface. Installation is therefore
number of the local/experimental range. I did no steps to coordinate a simple. Once installed, four interfaces named bc[0-3] are available.
major number for this driver, but I plan to do so in the near future. sethdlc from the ax25 utilities may be used to set driver states etc.
The driver supports multiple modems (currently four, as defined with Users of userland AX.25 stacks may use the net2kiss utility (also available
NR_PORTS). It therefore responds to minor numbers 0 to 3. I recommend in the ax25 utilities package) to converts packets of a network interface
to access the driver via the special device files /dev/bc[0-3], which to a KISS stream on a pseudo tty. There's also a patch available from
can be created with 'make bc'. me for WAMPES which allows attaching a kernel network interface directly.
Compiling and installing the driver
First unpack the source files into a directory. Then enter the following: (you
must be root to do it)
make dep
make
This will create the files baycom.o and setbaycom. baycom.o is as well copied
to /lib/modules/`uname -n`/misc. If you plan to use kerneld, do the following:
depmod -a
Do not forget to create the device special files if you install the driver the
first time. This can be done with:
make bc
You are now ready to use the driver. You can now activate the driver manually
by entering
insmod baycom
or leave this task to kerneld (if installed). Add the following line to
/etc/conf.modules
alias char-major-60 baycom
Configuring the driver Configuring the driver
...@@ -87,23 +58,21 @@ driver from the insmod command line (or by means of an option line in ...@@ -87,23 +58,21 @@ driver from the insmod command line (or by means of an option line in
Examples: Examples:
insmod baycom modem=1 iobase=0x3f8 irq=4 options=1 insmod baycom modem=1 iobase=0x3f8 irq=4 options=1
setbaycom -i /dev/bc0 -p ser12 0x3f8 4 1 sethdlc -i bc0 -p type ser12 io 0x3f8 irq 4 options 1
Both lines configure the first port to drive a ser12 modem at the first Both lines configure the first port to drive a ser12 modem at the first
serial port (COM1 under DOS). options=1 instructs the driver to use serial port (COM1 under DOS). options=1 instructs the driver to use
the software DCD algorithm (see below). the software DCD algorithm (see below).
insmod baycom modem=2 iobase=0x378 irq=7 options=1 insmod baycom modem=2 iobase=0x378 irq=7 options=1
setbaycom -i /dev/bc0 -p par96 0x378 7 1 sethdlc -i bc0 -p type par96 io 0x378 irq 7 options 1
Both lines configure the first port to drive a par96 or par97 modem at the Both lines configure the first port to drive a par96 or par97 modem at the
first parallel port (LPT1 under DOS). options=1 instructs the driver to use first parallel port (LPT1 under DOS). options=1 instructs the driver to use
the software DCD algorithm (see below). the software DCD algorithm (see below).
The channel access parameters must be set through KISS parameter frames. The The channel access parameters can be set with sethdlc -a or kissparms.
AX25 stack may be used to generate such frames. KA9Q NET derivatives such Note that both utilities interpret the values slightly different.
as WAMPES or TNOS offer the 'param' command for this purpose.
Hardware DCD versus Software DCD Hardware DCD versus Software DCD
...@@ -113,39 +82,24 @@ busy. This is the task of the DCD circuitry/software. The driver may either ...@@ -113,39 +82,24 @@ busy. This is the task of the DCD circuitry/software. The driver may either
utilise a software DCD algorithm (options=1) or use a DCD signal from utilise a software DCD algorithm (options=1) or use a DCD signal from
the hardware (options=0). the hardware (options=0).
ser12: if software DCD is utilised, the radio's squelch should always be ser12: if software DCD is utilised, the radio's squelch should always be
open. It is highly recommended to use the software DCD algorithm, open. It is highly recommended to use the software DCD algorithm,
as it is much faster than most hardware squelch circuitry. The as it is much faster than most hardware squelch circuitry. The
disadvantage is a slightly higher load on the system. disadvantage is a slightly higher load on the system.
par96: the software DCD algorithm for this type of modem is rather poor. par96: the software DCD algorithm for this type of modem is rather poor.
The modem simply does not provide enough information to implement The modem simply does not provide enough information to implement
a reasonable DCD algorithm in software. Therefore, if your radio a reasonable DCD algorithm in software. Therefore, if your radio
feeds the DCD input of the PAR96 modem, the use of the hardware feeds the DCD input of the PAR96 modem, the use of the hardware
DCD circuitry is recommended. DCD circuitry is recommended.
par97: as far as I know it is in this respect equivalent to par96. picpar: the picpar modem features a builtin DCD hardware, which is highly
recommended.
Compatibility with the rest of the Linux kernel Compatibility with the rest of the Linux kernel
The tty interface gave me some headaches. I did not find a reasonable
documentation of its interfaces, so I'm not particularly sure if I implemented
it the way I should. Perhaps someone with a more profound knowledge about
tty drivers could check the interface routines.
The driver produces a rather high interrupt load. par96/par97 generates 600
interrupts per second, ser12 1200 while transmitting and 2400 if hardware
DCD is used, 3600 otherwise. If other device drivers disable interrupts
too long, the performance of the driver drops (the packet loss rate increases),
especially with the ser12 modem.
There were also reports that under rather high load situations the driver
drops frames. This might be either an interrupt problem, or an AX25 stack
running in user mode might not get enough CPU time to process the packets
before the drivers internal buffers overflow. There is no way to throttle
the other radio stations from this layer, throttling must be done in the
AX25 layer.
The serial driver, the line printer (lp) driver and the baycom driver compete The serial driver, the line printer (lp) driver and the baycom driver compete
for the same hardware resources. Of course only one driver can access a given for the same hardware resources. Of course only one driver can access a given
interface at a time. The serial driver grabs all interfaces it can find at interface at a time. The serial driver grabs all interfaces it can find at
...@@ -160,5 +114,5 @@ leave it to kerneld to load the correct driver depending on the application. ...@@ -160,5 +114,5 @@ leave it to kerneld to load the correct driver depending on the application.
vy 73s de vy 73s de
Tom Sailer, hb9jnx@radio.amiv.ethz.ch Tom Sailer, sailer@ife.ee.ethz.ch
hb9jnx @ hb9w.ampr.org hb9jnx @ hb9w.ampr.org
LINUX DRIVER FOR SOUNDCARDS AS AX.25 MODEMS
Thomas M. Sailer, HB9JNX/AE4WA, <sailer@ife.ee.ethz.ch>
This driver allows either SoundBlaster (sbc) or WindowsSoundSystem (wss)
compatible soundcards to be used as either 1200 baud AFSK or 9600 baud FSK
AX.25 packet radio modems. Only half duplex operation is supported; an
attempt to include full duplex support failed because the hardware did
not support it (it appeared that the card only provides one DMA channel,
although the Codec chip would support two channels). The driver needs
some processing power! A 486DX/2 66MHz is a minimum requirement, otherwise
interactive performance of the computer may become sluggish.
The Interface of the driver
The driver provides a kernel network drivers named sm[0-3]. sethdlc
from the ax25 utilities may be used to set driver states etc. Users
of userland AX.25 stacks may use the net2kiss utility (also available
in the ax25 utilities package) to converts packets of a network interface
to a KISS stream on a pseudo tty. There's also a patch available from
me for WAMPES which allows attaching a kernel network interface directly.
Configuring the driver
Some sound cards need to be initialized before they operate in either
SoundBlaster or WSS compatibility mode. The driver does _NOT_ do this;
you may use the standard linux sound driver to initialize the soundcard;
compile it as a module, and do
insmod sound
rmmod sound
The soundcard should then be initialized correctly. If this does not help,
you'll have to write your own initialization utility.
Every time the driver is inserted into the kernel, it has to know which
modems it should access at which ports. This can be done with the setbaycom
utility. If you are only using one modem, you can also configure the
driver from the insmod command line (or by means of an option line in
/etc/conf.modules).
Examples:
insmod soundmodem hw=0 mode=0 iobase=0x220 irq=5 dma=1
sethdlc -i sm0 -p hw sbc type afsk1200 io 0x220 irq 5 dma 1
Both lines configure the first port to drive a soundblaster card
in 1200 baud AFSK mode.
The channel access parameters can be set with sethdlc -a or kissparms.
Note that both utilities interpret the values slightly different.
Input and output levels
It is important that the input and output levels are adjusted properly.
There are two utilities, available in the ax25 utilities distribution,
to facilitate this: smmixer and smdiag. smdiag allows you to display
the input signal in an oscilloscope like display or an eye diagram.
smmixer allows you to adjust input/output levels. See the respective
man pages.
Transmitter keying
Since soundcards do not have a DC coupled output; PTT keying options include
the following:
* VOX circuitry
* Serial port pin
* Parallel port pin
* MPU401 MIDI output via a retriggerable monoflop.
Circuit schematics may be found at
http://www.ife.ee.ethz.ch/~sailer/pcf/ptt_circ/ptt.html.
Compatibility with the rest of the Linux kernel
The sound driver and the soundcard modem driver compete for the same
hardware resources. Of course only one driver can access a given
interface at a time. Worse yet, the sound driver grabs the soundcard
at startup time. Therefore the soundcard modem driver subsequently won't
be able to access the soundcard. You might therefore find it necessary to
unload the sound driver before using the soundcard modem driver.
vy 73s de
Tom Sailer, sailer@ife.ee.ethz.ch
hb9jnx @ hb9w.ampr.org
This diff is collapsed.
...@@ -128,6 +128,7 @@ static const char *version = ...@@ -128,6 +128,7 @@ static const char *version =
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/dma.h> #include <asm/dma.h>
#include <asm/uaccess.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
......
This diff is collapsed.
#define RCS_ID "$Id: scc.c,v 1.63 1996/10/09 16:45:47 jreuter Exp jreuter $" #define RCS_ID "$Id: scc.c,v 1.64 1996/10/30 18:58:26 jreuter Exp jreuter $"
#define VERSION "3.0" #define VERSION "3.0"
#define BANNER "Z8530 SCC driver version "VERSION".dl1bke (experimental) by DL1BKE\n" #define BANNER "Z8530 SCC driver version "VERSION".dl1bke (experimental) by DL1BKE\n"
...@@ -78,13 +78,12 @@ ...@@ -78,13 +78,12 @@
* Source moved to drivers/net/ * Source moved to drivers/net/
* Includes Z8530 defines from drivers/net/z8530.h * Includes Z8530 defines from drivers/net/z8530.h
* Uses sk_buffer memory management * Uses sk_buffer memory management
* Doesn't have own queues anymore
* Reduced overhead of /proc/net/z8530drv output * Reduced overhead of /proc/net/z8530drv output
* Streamlined quite a lot things * Streamlined quite a lot things
* Invents brand new bugs... ;-) * Invents brand new bugs... ;-)
The move to version number 3.0 reflects theses changes. The move to version number 3.0 reflects theses changes.
You can use version 2.4 if you need a KISS TNC emulator. You can use version 2.4a if you need a KISS TNC emulator.
Thanks to all who contributed to this driver with ideas and bug Thanks to all who contributed to this driver with ideas and bug
reports! reports!
...@@ -120,6 +119,7 @@ ...@@ -120,6 +119,7 @@
#define MAXSCC 4 /* number of max. supported chips */ #define MAXSCC 4 /* number of max. supported chips */
#define BUFSIZE 384 /* must not exceed 4096 */ #define BUFSIZE 384 /* must not exceed 4096 */
#define MAXQUEUE 8 /* number of buffers we queue ourself */
#undef DISABLE_ALL_INTS /* use cli()/sti() in ISR instead of */ #undef DISABLE_ALL_INTS /* use cli()/sti() in ISR instead of */
/* enable_irq()/disable_irq() */ /* enable_irq()/disable_irq() */
#undef SCC_DEBUG #undef SCC_DEBUG
...@@ -129,8 +129,6 @@ ...@@ -129,8 +129,6 @@
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
#include <linux/module.h> #include <linux/module.h>
#include <linux/config.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -150,6 +148,8 @@ ...@@ -150,6 +148,8 @@
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/config.h> /* for CONFIG_PROC_FS */
#include <linux/scc.h> #include <linux/scc.h>
#include "z8530.h" #include "z8530.h"
...@@ -309,7 +309,6 @@ scc_lock_dev(struct scc_channel *scc) ...@@ -309,7 +309,6 @@ scc_lock_dev(struct scc_channel *scc)
static __inline__ void static __inline__ void
scc_unlock_dev(struct scc_channel *scc) scc_unlock_dev(struct scc_channel *scc)
{ {
scc->tx_next_buff = NULL;
scc->dev->tbusy = 0; scc->dev->tbusy = 0;
} }
...@@ -327,12 +326,9 @@ scc_discard_buffers(struct scc_channel *scc) ...@@ -327,12 +326,9 @@ scc_discard_buffers(struct scc_channel *scc)
scc->tx_buff = NULL; scc->tx_buff = NULL;
} }
if (scc->tx_next_buff != NULL) while (skb_queue_len(&scc->tx_queue))
{ dev_kfree_skb(skb_dequeue(&scc->tx_queue), FREE_WRITE);
dev_kfree_skb(scc->tx_next_buff, FREE_WRITE);
scc->tx_next_buff = NULL;
}
restore_flags(flags); restore_flags(flags);
} }
...@@ -399,8 +395,9 @@ scc_txint(struct scc_channel *scc) ...@@ -399,8 +395,9 @@ scc_txint(struct scc_channel *scc)
if (skb == NULL) if (skb == NULL)
{ {
skb = scc->tx_next_buff; skb = skb_dequeue(&scc->tx_queue);
scc->tx_buff = skb; scc->tx_buff = skb;
scc_unlock_dev(scc);
if (skb == NULL) if (skb == NULL)
{ {
...@@ -417,8 +414,6 @@ scc_txint(struct scc_channel *scc) ...@@ -417,8 +414,6 @@ scc_txint(struct scc_channel *scc)
Outb(scc->ctrl, RES_Tx_P); Outb(scc->ctrl, RES_Tx_P);
return; return;
} }
scc_unlock_dev(scc);
scc->stat.tx_state = TXS_ACTIVE; scc->stat.tx_state = TXS_ACTIVE;
...@@ -1150,7 +1145,7 @@ t_dwait(unsigned long channel) ...@@ -1150,7 +1145,7 @@ t_dwait(unsigned long channel)
if (scc->stat.tx_state == TXS_WAIT) /* maxkeyup or idle timeout */ if (scc->stat.tx_state == TXS_WAIT) /* maxkeyup or idle timeout */
{ {
if (scc->tx_next_buff == NULL) /* nothing to send */ if (skb_queue_len(&scc->tx_queue) == 0) /* nothing to send */
{ {
scc->stat.tx_state = TXS_IDLE; scc->stat.tx_state = TXS_IDLE;
scc_unlock_dev(scc); /* t_maxkeyup locked it. */ scc_unlock_dev(scc); /* t_maxkeyup locked it. */
...@@ -1620,7 +1615,8 @@ scc_net_open(struct device *dev) ...@@ -1620,7 +1615,8 @@ scc_net_open(struct device *dev)
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
scc->tx_buff = scc->tx_next_buff = NULL; scc->tx_buff = NULL;
skb_queue_head_init(&scc->tx_queue);
init_channel(scc); init_channel(scc);
...@@ -1746,19 +1742,12 @@ scc_net_tx(struct sk_buff *skb, struct device *dev) ...@@ -1746,19 +1742,12 @@ scc_net_tx(struct sk_buff *skb, struct device *dev)
save_flags(flags); save_flags(flags);
cli(); cli();
scc_lock_dev(scc); __skb_queue_tail(&scc->tx_queue, skb);
if (scc->tx_next_buff != NULL) if (skb_queue_len(&scc->tx_queue) == MAXQUEUE)
{
printk(KERN_ERR "z8530drv: race condition, discarding frame\n");
dev_kfree_skb(skb, FREE_WRITE);
scc_lock_dev(scc); scc_lock_dev(scc);
restore_flags(flags);
return 0;
}
dev->trans_start = jiffies; dev->trans_start = jiffies;
scc->tx_next_buff = skb;
/* /*
* Start transmission if the trx state is idle or * Start transmission if the trx state is idle or
...@@ -1798,10 +1787,10 @@ scc_net_ioctl(struct device *dev, struct ifreq *ifr, int cmd) ...@@ -1798,10 +1787,10 @@ scc_net_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
struct scc_kiss_cmd kiss_cmd; struct scc_kiss_cmd kiss_cmd;
struct scc_mem_config memcfg; struct scc_mem_config memcfg;
struct scc_hw_config hwcfg; struct scc_hw_config hwcfg;
unsigned char device_name[10];
struct scc_channel *scc;
int chan; int chan;
unsigned char device_name[10];
void *arg; void *arg;
struct scc_channel *scc;
scc = (struct scc_channel *) dev->priv; scc = (struct scc_channel *) dev->priv;
if (scc == NULL || scc->magic != SCC_MAGIC) if (scc == NULL || scc->magic != SCC_MAGIC)
...@@ -1964,7 +1953,8 @@ scc_net_ioctl(struct device *dev, struct ifreq *ifr, int cmd) ...@@ -1964,7 +1953,8 @@ scc_net_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
scc->kiss.softdcd = 0; /* hardware dcd */ scc->kiss.softdcd = 0; /* hardware dcd */
} }
scc->tx_buff = scc->tx_next_buff = NULL; scc->tx_buff = NULL;
skb_queue_head_init(&scc->tx_queue);
scc->init = 1; scc->init = 1;
return 0; return 0;
......
This diff is collapsed.
This diff is collapsed.
...@@ -1133,6 +1133,25 @@ static void set_multicast_list(struct device *dev) ...@@ -1133,6 +1133,25 @@ static void set_multicast_list(struct device *dev)
} while (++i < 15); } while (++i < 15);
/* Now add this frame to the Tx list. */ /* Now add this frame to the Tx list. */
{
unsigned long flags;
unsigned int entry;
save_flags(flags); cli();
entry = tp->cur_tx++ % TX_RING_SIZE;
tp->dirty_tx++;
restore_flags(flags);
tp->tx_skbuff[entry] = 0;
/* Put the setup frame on the Tx list. */
tp->tx_ring[entry].length = 192 |
(entry == TX_RING_SIZE-1 ? 0x0a000000 : 0x08000000);
tp->tx_ring[entry].buffer1 = virt_to_bus((char *)tp->setup_frame);
tp->tx_ring[entry].buffer2 = 0;
tp->tx_ring[entry].status = TRING_OWN;
/* Trigger an immediate transmit demand. */
tio_write(TPOLL_TRIGGER, CSR1);
}
} }
} }
......
...@@ -336,11 +336,11 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -336,11 +336,11 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
if (cptr == NULL) panic("aha1740.c: unable to allocate DMA memory\n"); if (cptr == NULL) panic("aha1740.c: unable to allocate DMA memory\n");
for(i=0; i<SCpnt->use_sg; i++) for(i=0; i<SCpnt->use_sg; i++)
{ {
cptr[i].dataptr = (long) sgpnt[i].address;
cptr[i].datalen = sgpnt[i].length; cptr[i].datalen = sgpnt[i].length;
cptr[i].dataptr = virt_to_bus(sgpnt[i].address);
} }
ecb[ecbno].datalen = SCpnt->use_sg * sizeof(struct aha1740_chain); ecb[ecbno].datalen = SCpnt->use_sg * sizeof(struct aha1740_chain);
ecb[ecbno].dataptr = (long) cptr; ecb[ecbno].dataptr = virt_to_bus(cptr);
#ifdef DEBUG #ifdef DEBUG
printk("cptr %x: ",cptr); printk("cptr %x: ",cptr);
ptr = (unsigned char *) cptr; ptr = (unsigned char *) cptr;
...@@ -351,15 +351,15 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) ...@@ -351,15 +351,15 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
{ {
SCpnt->host_scribble = NULL; SCpnt->host_scribble = NULL;
ecb[ecbno].datalen = bufflen; ecb[ecbno].datalen = bufflen;
ecb[ecbno].dataptr = (long) buff; ecb[ecbno].dataptr = virt_to_bus(buff);
} }
ecb[ecbno].lun = SCpnt->lun; ecb[ecbno].lun = SCpnt->lun;
ecb[ecbno].ses = 1; /* Suppress underrun errors */ ecb[ecbno].ses = 1; /* Suppress underrun errors */
ecb[ecbno].dir= direction; ecb[ecbno].dir= direction;
ecb[ecbno].ars=1; /* Yes, get the sense on an error */ ecb[ecbno].ars=1; /* Yes, get the sense on an error */
ecb[ecbno].senselen = 12; ecb[ecbno].senselen = 12;
ecb[ecbno].senseptr = (long) ecb[ecbno].sense; ecb[ecbno].senseptr = virt_to_bus(ecb[ecbno].sense);
ecb[ecbno].statusptr = (long) ecb[ecbno].status; ecb[ecbno].statusptr = virt_to_bus(ecb[ecbno].status);
ecb[ecbno].done = done; ecb[ecbno].done = done;
ecb[ecbno].SCpnt = SCpnt; ecb[ecbno].SCpnt = SCpnt;
#ifdef DEBUG #ifdef DEBUG
......
...@@ -224,12 +224,6 @@ static Scsi_Host_Template builtin_scsi_hosts[] = ...@@ -224,12 +224,6 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
#ifdef CONFIG_SCSI_ADVANSYS #ifdef CONFIG_SCSI_ADVANSYS
ADVANSYS, ADVANSYS,
#endif #endif
#ifdef CONFIG_SCSI_EATA_DMA
EATA_DMA,
#endif
#ifdef CONFIG_SCSI_EATA_PIO
EATA_PIO,
#endif
/* BusLogic must come before aha1542.c */ /* BusLogic must come before aha1542.c */
#ifdef CONFIG_SCSI_BUSLOGIC #ifdef CONFIG_SCSI_BUSLOGIC
BUSLOGIC, BUSLOGIC,
...@@ -288,6 +282,12 @@ static Scsi_Host_Template builtin_scsi_hosts[] = ...@@ -288,6 +282,12 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
#ifdef CONFIG_SCSI_NCR53C8XX #ifdef CONFIG_SCSI_NCR53C8XX
NCR53C8XX, NCR53C8XX,
#endif #endif
#ifdef CONFIG_SCSI_EATA_DMA
EATA_DMA,
#endif
#ifdef CONFIG_SCSI_EATA_PIO
EATA_PIO,
#endif
#ifdef CONFIG_SCSI_7000FASST #ifdef CONFIG_SCSI_7000FASST
WD7000, WD7000,
#endif #endif
......
...@@ -1799,7 +1799,8 @@ static void scsi_done (Scsi_Cmnd * SCpnt) ...@@ -1799,7 +1799,8 @@ static void scsi_done (Scsi_Cmnd * SCpnt)
if ((++SCpnt->retries) < SCpnt->allowed) if ((++SCpnt->retries) < SCpnt->allowed)
{ {
if ((SCpnt->retries >= (SCpnt->allowed >> 1)) if ((SCpnt->retries >= (SCpnt->allowed >> 1))
&& !(jiffies < SCpnt->host->last_reset + MIN_RESET_PERIOD) && !(SCpnt->host->last_reset > 0 &&
jiffies < SCpnt->host->last_reset + MIN_RESET_PERIOD)
&& !(SCpnt->flags & WAS_RESET)) && !(SCpnt->flags & WAS_RESET))
{ {
printk("scsi%d channel %d : resetting for second half of retries.\n", printk("scsi%d channel %d : resetting for second half of retries.\n",
......
...@@ -25,27 +25,18 @@ static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg) ...@@ -25,27 +25,18 @@ static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
return -EBADF; return -EBADF;
if (filp->f_inode->i_op->bmap == NULL) if (filp->f_inode->i_op->bmap == NULL)
return -EINVAL; return -EINVAL;
error = verify_area(VERIFY_WRITE,(void *) arg,4); if ((error = get_user(block, (int *) arg)) != 0)
if (error)
return error; return error;
get_user(block, (int *) arg);
block = filp->f_inode->i_op->bmap(filp->f_inode,block); block = filp->f_inode->i_op->bmap(filp->f_inode,block);
put_user(block,(int *) arg); return put_user(block, (int *) arg);
return 0;
case FIGETBSZ: case FIGETBSZ:
if (filp->f_inode->i_sb == NULL) if (filp->f_inode->i_sb == NULL)
return -EBADF; return -EBADF;
error = verify_area(VERIFY_WRITE,(void *) arg,4); return put_user(filp->f_inode->i_sb->s_blocksize,
if (error) (int *) arg);
return error;
put_user(filp->f_inode->i_sb->s_blocksize, (int *) arg);
return 0;
case FIONREAD: case FIONREAD:
error = verify_area(VERIFY_WRITE,(void *) arg,sizeof(int)); return put_user(filp->f_inode->i_size - filp->f_pos,
if (error) (int *) arg);
return error;
put_user(filp->f_inode->i_size - filp->f_pos, (int *) arg);
return 0;
} }
if (filp->f_op && filp->f_op->ioctl) if (filp->f_op && filp->f_op->ioctl)
return filp->f_op->ioctl(filp->f_inode, filp, cmd, arg); return filp->f_op->ioctl(filp->f_inode, filp, cmd, arg);
...@@ -56,7 +47,7 @@ static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg) ...@@ -56,7 +47,7 @@ static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{ {
struct file * filp; struct file * filp;
int on; int on, error;
if (fd >= NR_OPEN || !(filp = current->files->fd[fd])) if (fd >= NR_OPEN || !(filp = current->files->fd[fd]))
return -EBADF; return -EBADF;
...@@ -70,11 +61,8 @@ asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) ...@@ -70,11 +61,8 @@ asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
return 0; return 0;
case FIONBIO: case FIONBIO:
on = verify_area(VERIFY_READ, (unsigned int *)arg, if ((error = get_user(on, (int *)arg)) != 0)
sizeof(unsigned int)); return error;
if(on)
return on;
get_user(on, (unsigned int *) arg);
if (on) if (on)
filp->f_flags |= O_NONBLOCK; filp->f_flags |= O_NONBLOCK;
else else
...@@ -83,11 +71,8 @@ asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) ...@@ -83,11 +71,8 @@ asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
case FIOASYNC: /* O_SYNC is not yet implemented, case FIOASYNC: /* O_SYNC is not yet implemented,
but it's here for completeness. */ but it's here for completeness. */
on = verify_area(VERIFY_READ, (unsigned int *)arg, if ((error = get_user(on, (int *)arg)) != 0)
sizeof(unsigned int)); return error;
if(on)
return on;
get_user(on, (unsigned int *) arg);
if (on) if (on)
filp->f_flags |= O_SYNC; filp->f_flags |= O_SYNC;
else else
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <linux/malloc.h> #include <linux/malloc.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <asm/segment.h> #include <asm/uaccess.h>
#include <asm/string.h> #include <asm/string.h>
#include <linux/ncp.h> #include <linux/ncp.h>
......
...@@ -146,6 +146,8 @@ void remove_vfsmnt(kdev_t dev) ...@@ -146,6 +146,8 @@ void remove_vfsmnt(kdev_t dev)
if (vfsmnttail->mnt_dev == dev) if (vfsmnttail->mnt_dev == dev)
vfsmnttail = lptr; vfsmnttail = lptr;
} }
if (tofree == mru_vfsmnt)
mru_vfsmnt = NULL;
kfree(tofree->mnt_devname); kfree(tofree->mnt_devname);
kfree(tofree->mnt_dirname); kfree(tofree->mnt_dirname);
kfree_s(tofree, sizeof(struct vfsmount)); kfree_s(tofree, sizeof(struct vfsmount));
......
...@@ -20,15 +20,6 @@ ...@@ -20,15 +20,6 @@
#define MCA_bus 0 #define MCA_bus 0
#define MCA_bus__is_a_macro /* for versions in ksyms.c */ #define MCA_bus__is_a_macro /* for versions in ksyms.c */
/*
* The VM exception save area. We need to save only the
* exception count, so that the exception handling can know
* whether the system is set up to handle exceptions..
*/
struct exception_struct {
unsigned long count;
};
struct thread_struct { struct thread_struct {
/* the fields below are used by PALcode and must match struct pcb: */ /* the fields below are used by PALcode and must match struct pcb: */
unsigned long ksp; unsigned long ksp;
...@@ -45,12 +36,10 @@ struct thread_struct { ...@@ -45,12 +36,10 @@ struct thread_struct {
unsigned long res1, res2; unsigned long res1, res2;
/* the fields below are Linux-specific: */ /* the fields below are Linux-specific: */
/* /* bit 1..5: IEEE_TRAP_ENABLE bits (see fpu.h) */
* bit 0: perform syscall argument validation (get/set_fs)
* bit 1..5: IEEE_TRAP_ENABLE bits (see fpu.h)
*/
unsigned long flags; unsigned long flags;
struct exception_struct ex; /* perform syscall argument validation (get/set_fs) */
unsigned long fs;
}; };
#define INIT_MMAP { &init_mm, 0xfffffc0000000000, 0xfffffc0010000000, \ #define INIT_MMAP { &init_mm, 0xfffffc0000000000, 0xfffffc0010000000, \
...@@ -61,7 +50,7 @@ struct thread_struct { ...@@ -61,7 +50,7 @@ struct thread_struct {
0, 0, 0, \ 0, 0, 0, \
0, 0, 0, \ 0, 0, 0, \
0, \ 0, \
{ 0 } \ 0 \
} }
#define alloc_kernel_stack() __get_free_page(GFP_KERNEL) #define alloc_kernel_stack() __get_free_page(GFP_KERNEL)
......
This diff is collapsed.
...@@ -40,16 +40,6 @@ extern int EISA_bus; ...@@ -40,16 +40,6 @@ extern int EISA_bus;
*/ */
#define TASK_SIZE (0xC0000000UL) #define TASK_SIZE (0xC0000000UL)
/*
* VM exception register save area..
*
* When no exceptions are active, count = -1.
*/
struct exception_struct {
unsigned long count;
unsigned long eip;
};
/* /*
* Size of io_bitmap in longwords: 32 is ports 0-0x3ff. * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
*/ */
...@@ -120,7 +110,6 @@ struct thread_struct { ...@@ -120,7 +110,6 @@ struct thread_struct {
struct vm86_struct * vm86_info; struct vm86_struct * vm86_info;
unsigned long screen_bitmap; unsigned long screen_bitmap;
unsigned long v86flags, v86mask, v86mode; unsigned long v86flags, v86mask, v86mode;
struct exception_struct ex;
}; };
#define INIT_MMAP { &init_mm, 0xC0000000, 0xFFFFF000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC } #define INIT_MMAP { &init_mm, 0xC0000000, 0xFFFFF000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC }
...@@ -139,7 +128,6 @@ struct thread_struct { ...@@ -139,7 +128,6 @@ struct thread_struct {
_TSS(0), 0, 0, 0, KERNEL_DS, \ _TSS(0), 0, 0, 0, KERNEL_DS, \
{ { 0, }, }, /* 387 state */ \ { { 0, }, }, /* 387 state */ \
NULL, 0, 0, 0, 0 /* vm86_info */, \ NULL, 0, 0, 0, 0 /* vm86_info */, \
{ -1, } \
} }
#define alloc_kernel_stack() __get_free_page(GFP_KERNEL) #define alloc_kernel_stack() __get_free_page(GFP_KERNEL)
......
This diff is collapsed.
...@@ -7,61 +7,38 @@ ...@@ -7,61 +7,38 @@
#ifndef _BAYCOM_H #ifndef _BAYCOM_H
#define _BAYCOM_H #define _BAYCOM_H
#include <linux/ioctl.h> #include <linux/sockios.h>
#undef BAYCOM_DEBUG #include <linux/if_ether.h>
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/*
* structs for the IOCTL commands
*/
struct baycom_statistics { struct baycom_debug_data {
unsigned long rx_packets, tx_packets; unsigned long debug1;
unsigned long ptt_keyed; unsigned long debug2;
unsigned long rx_bufferoverrun, tx_bufferoverrun; long debug3;
}; };
struct baycom_params { struct baycom_modem_type {
int modem_type; unsigned char modem_type;
int iobase; unsigned int options;
int irq; };
int options;
int tx_delay; /* the transmitter keyup delay in 10ms units */
int tx_tail; /* the transmitter keyoff delay in 10ms units */
int slottime; /* the slottime in 10ms; usually 10 = 100ms */
int ppersist; /* the p-persistence 0..255 */
int fulldup; /* the driver does not support full duplex, setting */
/* this just makes the driver send even if DCD is on */
};
/* -------------------------------------------------------------------- */
#define BAYCOM_MAJOR 51
/* maximum packet length, excluding CRC */
#define BAYCOM_MAXFLEN 400
/* the ioctl type of this driver */
#define BAYCOM_IOCTL_TYPE 'B'
#define KISS_FEND ((unsigned char)0300)
#define KISS_FESC ((unsigned char)0333)
#define KISS_TFEND ((unsigned char)0334)
#define KISS_TFESC ((unsigned char)0335)
#define KISS_CMD_DATA 0 struct baycom_ioctl {
#define KISS_CMD_TXDELAY 1 int cmd;
#define KISS_CMD_PPERSIST 2 union {
#define KISS_CMD_SLOTTIME 3 struct baycom_modem_type mt;
#define KISS_CMD_TXTAIL 4 struct baycom_debug_data dbg;
#define KISS_CMD_FULLDUP 5 } data;
};
/* /* -------------------------------------------------------------------- */
* use bottom halves? (HDLC processing done with interrupts on or off)
*/
#define BAYCOM_USE_BH
/* /*
* modem types * modem types
*/ */
#define BAYCOM_MODEM_INVALID 0 #define BAYCOM_MODEM_INVALID 0
#define BAYCOM_MODEM_SER12 1 #define BAYCOM_MODEM_SER12 1
#define BAYCOM_MODEM_PAR96 2 #define BAYCOM_MODEM_PAR96 2
...@@ -71,59 +48,15 @@ struct baycom_params { ...@@ -71,59 +48,15 @@ struct baycom_params {
*/ */
#define BAYCOM_OPTIONS_SOFTDCD 1 #define BAYCOM_OPTIONS_SOFTDCD 1
/*
* ioctl constants
*/
#define BAYCOMCTL_GETDCD _IOR(BAYCOM_IOCTL_TYPE, 0, unsigned char)
#define BAYCOMCTL_GETPTT _IOR(BAYCOM_IOCTL_TYPE, 1, unsigned char)
#define BAYCOMCTL_PARAM_TXDELAY _IO(BAYCOM_IOCTL_TYPE, 2)
#define BAYCOMCTL_PARAM_PPERSIST _IO(BAYCOM_IOCTL_TYPE, 3)
#define BAYCOMCTL_PARAM_SLOTTIME _IO(BAYCOM_IOCTL_TYPE, 4)
#define BAYCOMCTL_PARAM_TXTAIL _IO(BAYCOM_IOCTL_TYPE, 5)
#define BAYCOMCTL_PARAM_FULLDUP _IO(BAYCOM_IOCTL_TYPE, 6)
#define BAYCOMCTL_GETSTAT _IOR(BAYCOM_IOCTL_TYPE, 7, \
struct baycom_statistics)
#define BAYCOMCTL_GETPARAMS _IOR(BAYCOM_IOCTL_TYPE, 8, \
struct baycom_params)
#define BAYCOMCTL_SETPARAMS _IOR(BAYCOM_IOCTL_TYPE, 9, \
struct baycom_params)
#define BAYCOMCTL_CALIBRATE _IO(BAYCOM_IOCTL_TYPE, 10)
#ifdef BAYCOM_DEBUG
/* /*
* these are mainly for debugging purposes * ioctl values change for baycom_net
*/ */
#define BAYCOMCTL_GETSAMPLES _IOR(BAYCOM_IOCTL_TYPE, 16, unsigned char) #define BAYCOMCTL_GETMODEMTYPE 0x90
#define BAYCOMCTL_GETBITS _IOR(BAYCOM_IOCTL_TYPE, 17, unsigned char) #define BAYCOMCTL_SETMODEMTYPE 0x91
#define BAYCOMCTL_GETDEBUG 0x92
#define BAYCOMCTL_DEBUG1 _IOR(BAYCOM_IOCTL_TYPE, 18, unsigned long)
#define BAYCOMCTL_DEBUG2 _IOR(BAYCOM_IOCTL_TYPE, 19, unsigned long)
#define BAYCOMCTL_DEBUG3 _IOR(BAYCOM_IOCTL_TYPE, 20, unsigned long)
#endif /* BAYCOM_DEBUG */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
#endif /* _BAYCOM_H */ #endif /* _BAYCOM_H */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-indent-level: 8
* c-brace-imaginary-offset: 0
* c-brace-offset: -8
* c-argdecl-indent: 8
* c-label-offset: -8
* c-continued-statement-offset: 8
* c-continued-brace-offset: 0
* End:
*/
This diff is collapsed.
...@@ -33,7 +33,6 @@ enum { ...@@ -33,7 +33,6 @@ enum {
DIGI_BH, DIGI_BH,
SERIAL_BH, SERIAL_BH,
RISCOM8_BH, RISCOM8_BH,
BAYCOM_BH,
NET_BH, NET_BH,
IMMEDIATE_BH, IMMEDIATE_BH,
KEYBOARD_BH, KEYBOARD_BH,
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#ifndef _MD_H #ifndef _MD_H
#define _MD_H #define _MD_H
#include <asm/segment.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/ioctl.h> #include <linux/ioctl.h>
......
This diff is collapsed.
This diff is collapsed.
...@@ -292,7 +292,6 @@ extern int cy_init(void); ...@@ -292,7 +292,6 @@ extern int cy_init(void);
extern int stl_init(void); extern int stl_init(void);
extern int stli_init(void); extern int stli_init(void);
extern int riscom8_init(void); extern int riscom8_init(void);
extern int baycom_init(void);
extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device, extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
const char *routine); const char *routine);
......
...@@ -172,6 +172,9 @@ extern void riscom8_setup(char *str, int *ints); ...@@ -172,6 +172,9 @@ extern void riscom8_setup(char *str, int *ints);
#ifdef CONFIG_BAYCOM #ifdef CONFIG_BAYCOM
extern void baycom_setup(char *str, int *ints); extern void baycom_setup(char *str, int *ints);
#endif #endif
#ifdef CONFIG_SOUNDMODEM
extern void sm_setup(char *str, int *ints);
#endif
#if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD) #if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD)
...@@ -414,6 +417,9 @@ struct { ...@@ -414,6 +417,9 @@ struct {
#endif #endif
#ifdef CONFIG_BAYCOM #ifdef CONFIG_BAYCOM
{ "baycom=", baycom_setup }, { "baycom=", baycom_setup },
#endif
#ifdef CONFIG_SOUNDMODEM
{ "soundmodem=", sm_setup },
#endif #endif
{ 0, 0 } { 0, 0 }
}; };
......
This diff is collapsed.
...@@ -1369,6 +1369,9 @@ extern int pi_init(void); ...@@ -1369,6 +1369,9 @@ extern int pi_init(void);
extern int scc_init(void); extern int scc_init(void);
extern void sdla_setup(void); extern void sdla_setup(void);
extern void dlci_setup(void); extern void dlci_setup(void);
extern int pt_init(void);
extern int sm_init(void);
extern int baycom_init(void);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
static struct proc_dir_entry proc_net_dev = { static struct proc_dir_entry proc_net_dev = {
...@@ -1419,6 +1422,12 @@ int net_dev_init(void) ...@@ -1419,6 +1422,12 @@ int net_dev_init(void)
#endif #endif
#if defined(CONFIG_SDLA) #if defined(CONFIG_SDLA)
sdla_setup(); sdla_setup();
#endif
#if defined(CONFIG_BAYCOM)
baycom_init();
#endif
#if defined(CONFIG_SOUNDMODEM)
sm_init();
#endif #endif
/* /*
* SLHC if present needs attaching so other people see it * SLHC if present needs attaching so other people see it
......
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