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
S: USA
N: Bernhard Kaindl
E: bartelt@computerhaus.at
E: edv@bartelt.via.at
D: Author of a menu based configuration tool, kmenu, which
D: is the predecessor of 'make menuconfig' and 'make xconfig'.
S: Tallak 95
......@@ -1161,7 +1161,8 @@ D: the gpm mouse server and kernel support for it
N: Thomas Sailer
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: 8408 Winterthur
S: Switzerland
......
......@@ -1875,17 +1875,29 @@ CONFIG_SCC
running kernel whenever you want), say M here and read
Documentation/modules.txt.
BAYCOM ser12 and par96 kiss emulation driver for AX.25
BAYCOM ser12 and par96 driver for AX.25
CONFIG_BAYCOM
This is an experimental driver for Baycom style simple amateur radio
modems that connect to either a serial interface or a parallel
interface. The driver supports the ser12 and par96 designs. To
configure the driver, use the setbaycom utility available from
http://www.ife.ee.ethz.ch/~sailer/ham/ham.html#lnxbay. For
information on the modems, see http://www.baycom.de and
drivers/char/README.baycom. 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
configure the driver, use the sethdlc utility available
in the standard ax25 utilities package. For information on the modems,
see http://www.baycom.de and drivers/net/README.baycom.
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.
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.
PLIP (parallel port) support
......
VERSION = 2
PATCHLEVEL = 1
SUBLEVEL = 6
SUBLEVEL = 7
ARCH = i386
......
......@@ -14,7 +14,7 @@
#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_REG 8
......@@ -142,9 +142,29 @@ entInt:
.ent entMM
entMM:
SAVE_ALL
lda $27,do_page_fault
lda $26,ret_from_sys_call
jsr $31,($27),do_page_fault
/* save $9 - $15 so the inline exception code can manipulate them. */
subq $30,56,$30
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
.align 3
......@@ -190,7 +210,7 @@ kernel_clone:
SAVE_ALL
lda $27,sys_clone
jsr $26,($27),sys_clone
stq $0,0($30)
stq $0,0($30)
br $31,ret_from_sys_call
.end kernel_clone
......@@ -424,7 +444,7 @@ entUnaUser:
/*
* A fork is the same as clone(SIGCHLD, 0);
*/
*/
.align 3
.globl sys_fork
.ent sys_fork
......@@ -508,7 +528,7 @@ ret_from_sys_call:
ldq $4,0($2)
addq $1,1,$1
and $3,$4,$2
bne $2,handle_bottom_half
bne $2,handle_bottom_half
ret_from_handle_bh:
ldq $0,SP_OFF($30)
and $0,8,$0
......@@ -529,9 +549,9 @@ ret_from_reschedule:
restore_all:
RESTORE_ALL
rti
/* PTRACE syscall handler */
/* PTRACE syscall handler */
.align 3
strace:
/* set up signal stack, call syscall_trace */
......@@ -588,7 +608,7 @@ strace_error:
lda $27,syscall_trace
jsr $26,($27),syscall_trace
bis $9,$9,$19
bis $10,$10,$20
bis $10,$10,$20
bsr $1,undo_switch_stack
bis $31,$31,$26 /* tell "ret_from_sys_call" that we can restart */
......
......@@ -178,63 +178,217 @@ struct unaligned_stat {
unsigned long count, va, pc;
} 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,
unsigned long a3, unsigned long a4, unsigned long a5,
struct allregs regs)
{
static int cnt = 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) {
cnt = 0;
}
if (++cnt < 5) {
printk("kernel: unaligned trap at %016lx: %p %lx %ld\n",
regs.pc - 4, va, opcode, reg);
pc, va, opcode, reg);
}
last_time = jiffies;
++unaligned[0].count;
unaligned[0].va = (unsigned long) va - 4;
unaligned[0].pc = regs.pc;
/* $16-$18 are PAL-saved, and are offset by 19 entries */
if (reg >= 16 && reg <= 18)
reg += 19;
{
/* Set up an exception handler address just in case we are
handling an unaligned fixup within get_user(). Notice
that we do *not* change the exception count because we
only want to bounce possible exceptions on through. */
__label__ handle_ex;
register void *ex_vector __asm__("$28");
__asm__ __volatile__ ("" : "=r"(ex_vector) : "0"(&&handle_ex));
switch (opcode) {
case 0x28: /* ldl */
*(reg+regs.regs) = get_unaligned((int *)va);
return;
case 0x29: /* ldq */
*(reg+regs.regs) = get_unaligned((long *)va);
return;
case 0x2c: /* stl */
put_unaligned(*(reg+regs.regs), (int *)va);
return;
case 0x2d: /* stq */
put_unaligned(*(reg+regs.regs), (long *)va);
return;
/* We'll only get back here if we are handling a
valid exception. */
handle_ex:
(&regs)->pc = *(28+regs.regs);
return;
}
unaligned[0].count++;
unaligned[0].va = (unsigned long) va;
unaligned[0].pc = pc;
/* We don't want to use the generic get/put unaligned macros as
we want to trap exceptions. Only if we actually get an
exception will we decide whether we should have caught it. */
switch (opcode) {
#ifdef __HAVE_CPU_BWX
case 0x0c: /* ldwu */
__asm__ __volatile__(
"1: ldq_u %1,0(%3)\n"
"2: ldq_u %2,1(%3)\n"
" extwl %1,%3,%1\n"
" extwh %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;
#endif
case 0x28: /* ldl */
__asm__ __volatile__(
"1: ldq_u %1,0(%3)\n"
"2: ldq_u %2,3(%3)\n"
" extll %1,%3,%1\n"
" 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",
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);
}
......
......@@ -25,6 +25,14 @@
* $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 noreorder
.align 4
......@@ -38,7 +46,7 @@ $loop:
and $1, 3, $4 # e0 :
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 $4, 1, $4 # e0 :
addq $6, 8, $6 # .. e1 :
......@@ -48,13 +56,13 @@ $loop:
1: bic $1, 3, $1 # e0 :
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 :
stq_u $31, 8($6) # e0 :
EX( stq_u $31, 8($6) ) # e0 :
subq $0, 8, $0 # .. e1 :
stq_u $31, 16($6) # e0 :
EX( stq_u $31, 16($6) ) # e0 :
subq $0, 8, $0 # .. e1 :
stq_u $31, 24($6) # e0 :
EX( stq_u $31, 24($6) ) # e0 :
subq $0, 8, $0 # .. e1 :
subq $1, 4, $1 # e0 :
addq $6, 32, $6 # .. e1 :
......@@ -62,35 +70,29 @@ $loop:
$tail:
bne $2, 1f # e1 : is there a tail to do?
stq $3, 0($7) # e0 : decrement exception count
ret $31, ($28), 1 # .. e1 :
1: ldq_u $5, 0($6) # e1 :
mskqh $5, $0, $5 # e0 :
stq_u $5, 0($6) # e0 :
1: EX( ldq_u $5, 0($6) ) # e0 :
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 :
__clear_user:
ldq $3, 0($7) # e0 : load exception count for increment
beq $0, $zerolength # .. e1 :
and $6, 7, $4 # e0 : find dest misalignment
addq $0, $4, $1 # e1 : bias counter
addq $3, 1, $5 # e0 :
and $1, 7, $2 # .. e1 : number of bytes in tail
beq $0, $zerolength # .. e1 :
addq $0, $4, $1 # e0 : bias counter
and $1, 7, $2 # e1 : number of bytes in tail
srl $1, 3, $1 # e0 :
unop # :
stq $5, 0($7) # e0 : increment exception count
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?
mskql $5, $6, $5 # e0 : take care of misaligned head
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
subq $1, 1, $1 # e0 :
subq $0, 8, $0 # .. e1 :
......@@ -101,11 +103,11 @@ $oneword:
mskql $5, $6, $4 # e0 :
mskqh $5, $2, $5 # e0 :
or $5, $4, $5 # e1 :
stq_u $5, 0($6) # e0 :
EX( stq_u $5, 0($6) ) # e0 :
clr $0 # .. e1 :
stq $3, 0($7) # e0 : decrement exception count
$zerolength:
$exception:
ret $31, ($28), 1 # .. e1 :
.end __clear_user
......@@ -18,7 +18,7 @@
* destination address in $6
* source address in $7
* exception pointer in $8
* return address in $28 (exceptions expect it there)
* return address in $28
*
* Outputs:
* bytes left to copy in $0
......@@ -27,28 +27,33 @@
* $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
.align 3
.globl __copy_user
.ent __copy_user
__copy_user:
ldq $5,0($8)
beq $0,$35
and $6,7,$3
addq $5,1,$1
stq $1,0($8)
beq $0,$35
beq $3,$36
subq $3,8,$3
.align 5
$37:
ldq_u $1,0($7)
ldq_u $2,0($6)
EX( ldq_u $1,0($7) )
EX( ldq_u $2,0($6) )
extbl $1,$7,$1
mskbl $2,$6,$2
insbl $1,$6,$1
addq $3,1,$3
bis $1,$2,$1
stq_u $1,0($6)
EX( stq_u $1,0($6) )
subq $0,1,$0
addq $6,1,$6
addq $7,1,$7
......@@ -59,10 +64,10 @@ $36:
bic $0,7,$4
beq $1,$43
beq $4,$48
ldq_u $3,0($7)
EX( ldq_u $3,0($7) )
.align 5
$50:
ldq_u $2,8($7)
EX( ldq_u $2,8($7) )
subq $4,8,$4
extql $3,$7,$3
extqh $2,$7,$1
......@@ -77,13 +82,13 @@ $48:
beq $0,$41
.align 5
$57:
ldq_u $1,0($7)
ldq_u $2,0($6)
EX( ldq_u $1,0($7) )
EX( ldq_u $2,0($6) )
extbl $1,$7,$1
mskbl $2,$6,$2
insbl $1,$6,$1
bis $1,$2,$1
stq_u $1,0($6)
EX( stq_u $1,0($6) )
subq $0,1,$0
addq $6,1,$6
addq $7,1,$7
......@@ -93,9 +98,8 @@ $57:
$43:
beq $4,$65
.align 5
.align 5
$66:
ldq $1,0($7)
EX( ldq $1,0($7) )
subq $4,8,$4
stq $1,0($6)
addq $7,8,$7
......@@ -104,15 +108,15 @@ $66:
bne $4,$66
$65:
beq $0,$41
ldq $2,0($7)
ldq $1,0($6)
EX( ldq $2,0($7) )
EX( ldq $1,0($6) )
mskql $2,$0,$2
mskqh $1,$0,$1
bis $2,$1,$2
stq $2,0($6)
EX( stq $2,0($6) )
bis $31,$31,$0
$41:
stq $5,0($8)
$35:
$exit:
ret $31,($28),1
.end __copy_user
This diff is collapsed.
......@@ -7,7 +7,7 @@
#
# 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)
$(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);
* -1 = instruction fetch
* 0 = load
* 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,
struct pt_regs regs)
/* Macro for exception fixup code to access integer registers. */
#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 task_struct *tsk = current;
struct mm_struct *mm = tsk->mm;
unsigned fixup;
down(&mm->mmap_sem);
vma = find_vma(mm, address);
......@@ -97,18 +107,21 @@ asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr, long c
*/
bad_area:
up(&mm->mmap_sem);
/* Did we have an exception handler installed? */
if (current->tss.ex.count == 1) {
printk("Taking exception at %lx (%lx)\n", regs.pc, regs.r28);
current->tss.ex.count = 0;
/* return to the address in r28 */
(&regs)->pc = regs.r28;
/* Are we prepared to handle this fault as an exception? */
if ((fixup = search_exception_table(regs->pc)) != 0) {
unsigned long newpc;
newpc = fixup_exception(dpf_reg, fixup, regs->pc);
printk("Taking exception at %lx (%lx)\n", regs->pc, newpc);
regs->pc = newpc;
return;
}
if (user_mode(&regs)) {
printk("%s: memory violation at pc=%08lx rp=%08lx (bad address = %08lx)\n",
tsk->comm, regs.pc, regs.r26, address);
die_if_kernel("oops", &regs, cause);
if (user_mode(regs)) {
printk("%s: memory violation at pc=%08lx ra=%08lx "
"(bad address = %08lx)\n",
tsk->comm, regs->pc, regs->r26, address);
die_if_kernel("oops", regs, cause);
force_sig(SIGSEGV, tsk);
return;
}
......@@ -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
* terminate things with extreme prejudice.
*/
printk(KERN_ALERT
"Unable to handle kernel paging request at virtual address %016lx\n", address);
die_if_kernel("Oops", &regs, cause);
printk(KERN_ALERT "Unable to handle kernel paging request at "
"virtual address %016lx\n", address);
die_if_kernel("Oops", regs, cause);
do_exit(SIGKILL);
}
......@@ -8,6 +8,6 @@
# Note 2! The CFLAGS definition is now in the main makefile...
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
/*
* 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)
struct vm_area_struct * vma;
unsigned long address;
unsigned long page;
unsigned long fixup;
int write;
/* get the address */
......@@ -161,14 +162,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
*/
bad_area:
up(&mm->mmap_sem);
/* is there valid exception data? Return to indicated handler if so */
if (tsk->tss.ex.count == 0) {
printk("Exception at %lx (%lx)\n", regs->eip, regs->edx);
tsk->tss.ex.count--;
regs->eip = regs->edx;
regs->edx = -EFAULT;
/* Are we prepared to handle this fault? */
if ((fixup = search_exception_table(regs->eip)) != 0) {
printk("Exception at %lx (%lx)\n", regs->eip, fixup);
regs->eip = fixup;
return;
}
if (error_code & 4) {
tsk->tss.cr2 = address;
tsk->tss.error_code = error_code;
......
......@@ -40,6 +40,7 @@
#define MD_DRIVER
#include <linux/blk.h>
#include <asm/uaccess.h>
static struct hd_struct md_hd_struct[MAX_MD_DEV];
static int md_blocksizes[MAX_MD_DEV];
......@@ -296,10 +297,9 @@ static int md_ioctl (struct inode *inode, struct file *file,
case BLKGETSIZE: /* Return device size */
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)
return err;
put_user (md_hd_struct[MINOR(inode->i_rdev)].nr_sects, (long *) arg);
break;
case BLKFLSBUF:
......@@ -315,10 +315,9 @@ static int md_ioctl (struct inode *inode, struct file *file,
case BLKRAGET:
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)
return err;
put_user (read_ahead[MAJOR(inode->i_rdev)], (long *) arg);
break;
/* 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,
case HDIO_GETGEO:
if (!loc) return -EINVAL;
err = verify_area(VERIFY_WRITE, loc, sizeof(*loc));
err = put_user (2, (char *) &loc->heads);
if (err)
return err;
put_user (2, (char *) &loc->heads);
put_user (4, (char *) &loc->sectors);
put_user (md_hd_struct[minor].nr_sects/8, (short *) &loc->cylinders);
put_user (md_hd_struct[MINOR(inode->i_rdev)].start_sect,
err = put_user (4, (char *) &loc->sectors);
if (err)
return err;
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);
if (err)
return err;
break;
RO_IOCTLS(inode->i_rdev,arg);
......@@ -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)
{
int minor=MINOR(inode->i_rdev);
......@@ -378,7 +382,7 @@ static int md_read (struct inode *inode, struct file *file,
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)
{
int minor=MINOR(inode->i_rdev);
......
......@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/fcntl.h>
#include <asm/uaccess.h>
#include <linux/cdrom.h>
#include <linux/ucdrom.h>
......
This diff is collapsed.
......@@ -23,7 +23,7 @@
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/ftape.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include "tracing.h"
#include "ftape-eof.h"
......
......@@ -30,7 +30,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/ftape.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <linux/ioctl.h>
#include <linux/mtio.h>
......
......@@ -30,7 +30,7 @@
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/ftape.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include "tracing.h"
#include "ftape-read.h"
......
......@@ -33,7 +33,7 @@
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/ftape.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include "tracing.h"
#include "ftape-write.h"
......
......@@ -24,7 +24,7 @@
#include <linux/version.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/major.h>
......
......@@ -184,12 +184,14 @@ static struct symbol_table misc_syms = {
#include <linux/symtab_end.h>
};
#if defined(CONFIG_PROC_FS) && !defined(MODULE)
static struct proc_dir_entry proc_misc = {
0, 4, "misc",
S_IFREG | S_IRUGO, 1, 0, 0,
0, NULL /* ops -- default to array */,
&proc_misc_read /* get_info */,
};
#endif
int misc_init(void)
{
......
......@@ -1940,9 +1940,6 @@ int tty_init(void)
#endif
#ifdef CONFIG_RISCOM8
riscom8_init();
#endif
#ifdef CONFIG_BAYCOM
baycom_init();
#endif
pty_init();
vcs_init();
......
......@@ -117,6 +117,7 @@
*
*/
#include <asm/uaccess.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/version.h>
......@@ -915,7 +916,7 @@ void isdn_info_update(void)
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);
int len = 0;
......@@ -988,12 +989,13 @@ static int isdn_read(struct inode *inode, struct file *file, char *buf, int coun
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;
}
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);
int drvidx;
......
......@@ -106,6 +106,7 @@
*
*/
#include <asm/uaccess.h>
#include <linux/config.h>
#define __NO_VERSION__
#include <linux/module.h>
......
......@@ -73,6 +73,7 @@
/* TODO: right tbusy handling when using MP */
#include <asm/uaccess.h>
#include <linux/config.h>
#define __NO_VERSION__
#include <linux/module.h>
......@@ -391,7 +392,7 @@ int isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long a
switch (cmd) {
case PPPIOCBUNDLE:
#ifdef CONFIG_ISDN_MPP
if ((r = get_user(val, arg)))
if ((r = get_user(val, argp)))
return r;
printk(KERN_DEBUG "iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n",
(int) min, (int) is->unit, (int) val);
......@@ -588,7 +589,6 @@ int isdn_ppp_read(int min, struct file *file, char *buf, int count)
{
struct ippp_struct *is;
struct ippp_buf_queue *b;
int r;
unsigned long flags;
is = file->private_data;
......@@ -1445,7 +1445,6 @@ static int isdn_ppp_dev_ioctl_stats(int slot,struct ifreq *ifr,struct device *de
{
struct ppp_stats *res, t;
isdn_net_local *lp = (isdn_net_local *) dev->priv;
int err;
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
int isdn_ppp_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
{
int error;
int error = 0;
char *r;
int len;
isdn_net_local *lp = (isdn_net_local *) dev->priv;
......
......@@ -109,6 +109,7 @@
*
*/
#include <asm/uaccess.h>
#define __NO_VERSION__
#include <linux/config.h>
#include <linux/module.h>
......
......@@ -47,6 +47,7 @@
*/
#define __NO_VERSION__
#include "teles.h"
#include <asm/uaccess.h>
extern struct IsdnCard cards[];
extern int nrcards;
......
......@@ -25,7 +25,8 @@ fi
bool 'Radio network interfaces' CONFIG_NET_RADIO
if [ "$CONFIG_NET_RADIO" != "n" ]; 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
if [ "$CONFIG_AX25" = "y" ]; then
bool 'Gracilis PackeTwin support' CONFIG_PT
......
......@@ -18,6 +18,8 @@ CONFIG_8390_BUILTIN :=
CONFIG_8390_MODULE :=
CONFIG_SLHC_BUILTIN :=
CONFIG_SLHC_MODULE :=
CONFIG_HDLCDRV_BUILTIN :=
CONFIG_HDLCDRV_MODULE :=
ifeq ($(CONFIG_ISDN),y)
ifeq ($(CONFIG_ISDN_PPP),y)
......@@ -518,6 +520,37 @@ else
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
clean:
......
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
amateur radio modems. The driver supports the following modems:
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
is responsible for regenerating the receiver bit clock, as well as
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
port, the kernel driver for serial ports cannot be used, and this
driver only supports standard serial hardware (8250, 16450, 16550)
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.
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 PC then empties the shift register in a burst. This modem connects
to the parallel port, hence the name. The modem leaves the
implementation of the HDLC protocol and the scrambler polynomial to
the PC.
par97: 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
and can therefore be fed from the parallel port and does not require
an additional power supply.
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
is responsible for regenerating the receiver bit clock, as well as
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
port, the kernel driver for serial ports cannot be used, and this
driver only supports standard serial hardware (8250, 16450, 16550)
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.
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 PC then empties the shift register in a burst. This modem connects
to the parallel port, hence the name. The modem leaves the
implementation of the HDLC protocol and the scrambler polynomial to
the PC.
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
and can therefore be fed from the parallel port and does not require
an additional power supply. Furthermore, it incorporates a carrier
detect circuitry.
All of the above modems only support half duplex communications. However,
the driver supports the KISS (see below) fullduplex command. It then simply
......@@ -37,44 +38,14 @@ access protocol.
The Interface of the driver
The driver interfaces to the AX25 stack via a KISS interface. The driver
can be accessed as a character device with major 60. Major 60 is the first
number of the local/experimental range. I did no steps to coordinate a
major number for this driver, but I plan to do so in the near future.
The driver supports multiple modems (currently four, as defined with
NR_PORTS). It therefore responds to minor numbers 0 to 3. I recommend
to access the driver via the special device files /dev/bc[0-3], which
can be created with 'make bc'.
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
Unlike previous drivers, the driver is no longer a character device,
but it is now a true kernel network interface. Installation is therefore
simple. Once installed, four interfaces named bc[0-3] are available.
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
......@@ -87,23 +58,21 @@ driver from the insmod command line (or by means of an option line in
Examples:
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
serial port (COM1 under DOS). options=1 instructs the driver to use
the software DCD algorithm (see below).
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
first parallel port (LPT1 under DOS). options=1 instructs the driver to use
the software DCD algorithm (see below).
The channel access parameters must be set through KISS parameter frames. The
AX25 stack may be used to generate such frames. KA9Q NET derivatives such
as WAMPES or TNOS offer the 'param' command for this purpose.
The channel access parameters can be set with sethdlc -a or kissparms.
Note that both utilities interpret the values slightly different.
Hardware DCD versus Software DCD
......@@ -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
the hardware (options=0).
ser12: if software DCD is utilised, the radio's squelch should always be
open. It is highly recommended to use the software DCD algorithm,
as it is much faster than most hardware squelch circuitry. The
disadvantage is a slightly higher load on the system.
ser12: if software DCD is utilised, the radio's squelch should always be
open. It is highly recommended to use the software DCD algorithm,
as it is much faster than most hardware squelch circuitry. The
disadvantage is a slightly higher load on the system.
par96: the software DCD algorithm for this type of modem is rather poor.
The modem simply does not provide enough information to implement
a reasonable DCD algorithm in software. Therefore, if your radio
feeds the DCD input of the PAR96 modem, the use of the hardware
DCD circuitry is recommended.
par96: the software DCD algorithm for this type of modem is rather poor.
The modem simply does not provide enough information to implement
a reasonable DCD algorithm in software. Therefore, if your radio
feeds the DCD input of the PAR96 modem, the use of the hardware
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
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
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
......@@ -160,5 +114,5 @@ leave it to kerneld to load the correct driver depending on the application.
vy 73s de
Tom Sailer, hb9jnx@radio.amiv.ethz.ch
Tom Sailer, sailer@ife.ee.ethz.ch
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 =
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/uaccess.h>
#include <linux/errno.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 BANNER "Z8530 SCC driver version "VERSION".dl1bke (experimental) by DL1BKE\n"
......@@ -78,13 +78,12 @@
* Source moved to drivers/net/
* Includes Z8530 defines from drivers/net/z8530.h
* Uses sk_buffer memory management
* Doesn't have own queues anymore
* Reduced overhead of /proc/net/z8530drv output
* Streamlined quite a lot things
* Invents brand new bugs... ;-)
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
reports!
......@@ -120,6 +119,7 @@
#define MAXSCC 4 /* number of max. supported chips */
#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 */
/* enable_irq()/disable_irq() */
#undef SCC_DEBUG
......@@ -129,8 +129,6 @@
/* ----------------------------------------------------------------------- */
#include <linux/module.h>
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/sched.h>
......@@ -150,6 +148,8 @@
#include <linux/if_arp.h>
#include <linux/socket.h>
#include <linux/config.h> /* for CONFIG_PROC_FS */
#include <linux/scc.h>
#include "z8530.h"
......@@ -309,7 +309,6 @@ scc_lock_dev(struct scc_channel *scc)
static __inline__ void
scc_unlock_dev(struct scc_channel *scc)
{
scc->tx_next_buff = NULL;
scc->dev->tbusy = 0;
}
......@@ -327,12 +326,9 @@ scc_discard_buffers(struct scc_channel *scc)
scc->tx_buff = NULL;
}
if (scc->tx_next_buff != NULL)
{
dev_kfree_skb(scc->tx_next_buff, FREE_WRITE);
scc->tx_next_buff = NULL;
}
while (skb_queue_len(&scc->tx_queue))
dev_kfree_skb(skb_dequeue(&scc->tx_queue), FREE_WRITE);
restore_flags(flags);
}
......@@ -399,8 +395,9 @@ scc_txint(struct scc_channel *scc)
if (skb == NULL)
{
skb = scc->tx_next_buff;
skb = skb_dequeue(&scc->tx_queue);
scc->tx_buff = skb;
scc_unlock_dev(scc);
if (skb == NULL)
{
......@@ -417,8 +414,6 @@ scc_txint(struct scc_channel *scc)
Outb(scc->ctrl, RES_Tx_P);
return;
}
scc_unlock_dev(scc);
scc->stat.tx_state = TXS_ACTIVE;
......@@ -1150,7 +1145,7 @@ t_dwait(unsigned long channel)
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_unlock_dev(scc); /* t_maxkeyup locked it. */
......@@ -1620,7 +1615,8 @@ scc_net_open(struct device *dev)
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);
......@@ -1746,19 +1742,12 @@ scc_net_tx(struct sk_buff *skb, struct device *dev)
save_flags(flags);
cli();
scc_lock_dev(scc);
__skb_queue_tail(&scc->tx_queue, skb);
if (scc->tx_next_buff != NULL)
{
printk(KERN_ERR "z8530drv: race condition, discarding frame\n");
dev_kfree_skb(skb, FREE_WRITE);
if (skb_queue_len(&scc->tx_queue) == MAXQUEUE)
scc_lock_dev(scc);
restore_flags(flags);
return 0;
}
dev->trans_start = jiffies;
scc->tx_next_buff = skb;
/*
* Start transmission if the trx state is idle or
......@@ -1798,10 +1787,10 @@ scc_net_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
struct scc_kiss_cmd kiss_cmd;
struct scc_mem_config memcfg;
struct scc_hw_config hwcfg;
unsigned char device_name[10];
struct scc_channel *scc;
int chan;
unsigned char device_name[10];
void *arg;
struct scc_channel *scc;
scc = (struct scc_channel *) dev->priv;
if (scc == NULL || scc->magic != SCC_MAGIC)
......@@ -1964,7 +1953,8 @@ scc_net_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
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;
return 0;
......
This diff is collapsed.
This diff is collapsed.
......@@ -1133,6 +1133,25 @@ static void set_multicast_list(struct device *dev)
} while (++i < 15);
/* 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 *))
if (cptr == NULL) panic("aha1740.c: unable to allocate DMA memory\n");
for(i=0; i<SCpnt->use_sg; i++)
{
cptr[i].dataptr = (long) sgpnt[i].address;
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].dataptr = (long) cptr;
ecb[ecbno].dataptr = virt_to_bus(cptr);
#ifdef DEBUG
printk("cptr %x: ",cptr);
ptr = (unsigned char *) cptr;
......@@ -351,15 +351,15 @@ int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
{
SCpnt->host_scribble = NULL;
ecb[ecbno].datalen = bufflen;
ecb[ecbno].dataptr = (long) buff;
ecb[ecbno].dataptr = virt_to_bus(buff);
}
ecb[ecbno].lun = SCpnt->lun;
ecb[ecbno].ses = 1; /* Suppress underrun errors */
ecb[ecbno].dir= direction;
ecb[ecbno].ars=1; /* Yes, get the sense on an error */
ecb[ecbno].senselen = 12;
ecb[ecbno].senseptr = (long) ecb[ecbno].sense;
ecb[ecbno].statusptr = (long) ecb[ecbno].status;
ecb[ecbno].senseptr = virt_to_bus(ecb[ecbno].sense);
ecb[ecbno].statusptr = virt_to_bus(ecb[ecbno].status);
ecb[ecbno].done = done;
ecb[ecbno].SCpnt = SCpnt;
#ifdef DEBUG
......
......@@ -224,12 +224,6 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
#ifdef CONFIG_SCSI_ADVANSYS
ADVANSYS,
#endif
#ifdef CONFIG_SCSI_EATA_DMA
EATA_DMA,
#endif
#ifdef CONFIG_SCSI_EATA_PIO
EATA_PIO,
#endif
/* BusLogic must come before aha1542.c */
#ifdef CONFIG_SCSI_BUSLOGIC
BUSLOGIC,
......@@ -288,6 +282,12 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
#ifdef CONFIG_SCSI_NCR53C8XX
NCR53C8XX,
#endif
#ifdef CONFIG_SCSI_EATA_DMA
EATA_DMA,
#endif
#ifdef CONFIG_SCSI_EATA_PIO
EATA_PIO,
#endif
#ifdef CONFIG_SCSI_7000FASST
WD7000,
#endif
......
......@@ -1799,7 +1799,8 @@ static void scsi_done (Scsi_Cmnd * SCpnt)
if ((++SCpnt->retries) < SCpnt->allowed)
{
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))
{
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)
return -EBADF;
if (filp->f_inode->i_op->bmap == NULL)
return -EINVAL;
error = verify_area(VERIFY_WRITE,(void *) arg,4);
if (error)
if ((error = get_user(block, (int *) arg)) != 0)
return error;
get_user(block, (int *) arg);
block = filp->f_inode->i_op->bmap(filp->f_inode,block);
put_user(block,(int *) arg);
return 0;
return put_user(block, (int *) arg);
case FIGETBSZ:
if (filp->f_inode->i_sb == NULL)
return -EBADF;
error = verify_area(VERIFY_WRITE,(void *) arg,4);
if (error)
return error;
put_user(filp->f_inode->i_sb->s_blocksize, (int *) arg);
return 0;
return put_user(filp->f_inode->i_sb->s_blocksize,
(int *) arg);
case FIONREAD:
error = verify_area(VERIFY_WRITE,(void *) arg,sizeof(int));
if (error)
return error;
put_user(filp->f_inode->i_size - filp->f_pos, (int *) arg);
return 0;
return put_user(filp->f_inode->i_size - filp->f_pos,
(int *) arg);
}
if (filp->f_op && filp->f_op->ioctl)
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)
asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct file * filp;
int on;
int on, error;
if (fd >= NR_OPEN || !(filp = current->files->fd[fd]))
return -EBADF;
......@@ -70,11 +61,8 @@ asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
return 0;
case FIONBIO:
on = verify_area(VERIFY_READ, (unsigned int *)arg,
sizeof(unsigned int));
if(on)
return on;
get_user(on, (unsigned int *) arg);
if ((error = get_user(on, (int *)arg)) != 0)
return error;
if (on)
filp->f_flags |= O_NONBLOCK;
else
......@@ -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,
but it's here for completeness. */
on = verify_area(VERIFY_READ, (unsigned int *)arg,
sizeof(unsigned int));
if(on)
return on;
get_user(on, (unsigned int *) arg);
if ((error = get_user(on, (int *)arg)) != 0)
return error;
if (on)
filp->f_flags |= O_SYNC;
else
......
......@@ -17,7 +17,7 @@
#include <linux/malloc.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <asm/string.h>
#include <linux/ncp.h>
......
......@@ -146,6 +146,8 @@ void remove_vfsmnt(kdev_t dev)
if (vfsmnttail->mnt_dev == dev)
vfsmnttail = lptr;
}
if (tofree == mru_vfsmnt)
mru_vfsmnt = NULL;
kfree(tofree->mnt_devname);
kfree(tofree->mnt_dirname);
kfree_s(tofree, sizeof(struct vfsmount));
......
......@@ -20,15 +20,6 @@
#define MCA_bus 0
#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 {
/* the fields below are used by PALcode and must match struct pcb: */
unsigned long ksp;
......@@ -45,12 +36,10 @@ struct thread_struct {
unsigned long res1, res2;
/* the fields below are Linux-specific: */
/*
* bit 0: perform syscall argument validation (get/set_fs)
* bit 1..5: IEEE_TRAP_ENABLE bits (see fpu.h)
*/
/* bit 1..5: IEEE_TRAP_ENABLE bits (see fpu.h) */
unsigned long flags;
struct exception_struct ex;
/* perform syscall argument validation (get/set_fs) */
unsigned long fs;
};
#define INIT_MMAP { &init_mm, 0xfffffc0000000000, 0xfffffc0010000000, \
......@@ -61,7 +50,7 @@ struct thread_struct {
0, 0, 0, \
0, 0, 0, \
0, \
{ 0 } \
0 \
}
#define alloc_kernel_stack() __get_free_page(GFP_KERNEL)
......
This diff is collapsed.
......@@ -40,16 +40,6 @@ extern int EISA_bus;
*/
#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.
*/
......@@ -120,7 +110,6 @@ struct thread_struct {
struct vm86_struct * vm86_info;
unsigned long screen_bitmap;
unsigned long v86flags, v86mask, v86mode;
struct exception_struct ex;
};
#define INIT_MMAP { &init_mm, 0xC0000000, 0xFFFFF000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC }
......@@ -139,7 +128,6 @@ struct thread_struct {
_TSS(0), 0, 0, 0, KERNEL_DS, \
{ { 0, }, }, /* 387 state */ \
NULL, 0, 0, 0, 0 /* vm86_info */, \
{ -1, } \
}
#define alloc_kernel_stack() __get_free_page(GFP_KERNEL)
......
This diff is collapsed.
......@@ -7,61 +7,38 @@
#ifndef _BAYCOM_H
#define _BAYCOM_H
#include <linux/ioctl.h>
#undef BAYCOM_DEBUG
#include <linux/sockios.h>
#include <linux/if_ether.h>
/* -------------------------------------------------------------------- */
/*
* structs for the IOCTL commands
*/
struct baycom_statistics {
unsigned long rx_packets, tx_packets;
unsigned long ptt_keyed;
unsigned long rx_bufferoverrun, tx_bufferoverrun;
struct baycom_debug_data {
unsigned long debug1;
unsigned long debug2;
long debug3;
};
struct baycom_params {
int modem_type;
int iobase;
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)
struct baycom_modem_type {
unsigned char modem_type;
unsigned int options;
};
#define KISS_CMD_DATA 0
#define KISS_CMD_TXDELAY 1
#define KISS_CMD_PPERSIST 2
#define KISS_CMD_SLOTTIME 3
#define KISS_CMD_TXTAIL 4
#define KISS_CMD_FULLDUP 5
struct baycom_ioctl {
int cmd;
union {
struct baycom_modem_type mt;
struct baycom_debug_data dbg;
} data;
};
/*
* use bottom halves? (HDLC processing done with interrupts on or off)
*/
#define BAYCOM_USE_BH
/* -------------------------------------------------------------------- */
/*
* modem types
*/
#define BAYCOM_MODEM_INVALID 0
#define BAYCOM_MODEM_SER12 1
#define BAYCOM_MODEM_PAR96 2
......@@ -71,59 +48,15 @@ struct baycom_params {
*/
#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_GETBITS _IOR(BAYCOM_IOCTL_TYPE, 17, unsigned char)
#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 */
#define BAYCOMCTL_GETMODEMTYPE 0x90
#define BAYCOMCTL_SETMODEMTYPE 0x91
#define BAYCOMCTL_GETDEBUG 0x92
/* -------------------------------------------------------------------- */
#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 {
DIGI_BH,
SERIAL_BH,
RISCOM8_BH,
BAYCOM_BH,
NET_BH,
IMMEDIATE_BH,
KEYBOARD_BH,
......
......@@ -18,7 +18,6 @@
#ifndef _MD_H
#define _MD_H
#include <asm/segment.h>
#include <linux/major.h>
#include <linux/mm.h>
#include <linux/ioctl.h>
......
This diff is collapsed.
This diff is collapsed.
......@@ -292,7 +292,6 @@ extern int cy_init(void);
extern int stl_init(void);
extern int stli_init(void);
extern int riscom8_init(void);
extern int baycom_init(void);
extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
const char *routine);
......
......@@ -172,6 +172,9 @@ extern void riscom8_setup(char *str, int *ints);
#ifdef CONFIG_BAYCOM
extern void baycom_setup(char *str, int *ints);
#endif
#ifdef CONFIG_SOUNDMODEM
extern void sm_setup(char *str, int *ints);
#endif
#if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD)
......@@ -414,6 +417,9 @@ struct {
#endif
#ifdef CONFIG_BAYCOM
{ "baycom=", baycom_setup },
#endif
#ifdef CONFIG_SOUNDMODEM
{ "soundmodem=", sm_setup },
#endif
{ 0, 0 }
};
......
This diff is collapsed.
......@@ -1369,6 +1369,9 @@ extern int pi_init(void);
extern int scc_init(void);
extern void sdla_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
static struct proc_dir_entry proc_net_dev = {
......@@ -1419,6 +1422,12 @@ int net_dev_init(void)
#endif
#if defined(CONFIG_SDLA)
sdla_setup();
#endif
#if defined(CONFIG_BAYCOM)
baycom_init();
#endif
#if defined(CONFIG_SOUNDMODEM)
sm_init();
#endif
/*
* 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