Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
5d278332
Commit
5d278332
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 1.1.94
parent
fde9fa96
Changes
42
Hide whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
1098 additions
and
570 deletions
+1098
-570
Makefile
Makefile
+1
-1
arch/alpha/kernel/entry.S
arch/alpha/kernel/entry.S
+12
-0
arch/alpha/kernel/process.c
arch/alpha/kernel/process.c
+50
-8
arch/alpha/kernel/traps.c
arch/alpha/kernel/traps.c
+19
-0
arch/i386/kernel/process.c
arch/i386/kernel/process.c
+22
-11
arch/i386/kernel/ptrace.c
arch/i386/kernel/ptrace.c
+27
-4
arch/sparc/mm/fault.c
arch/sparc/mm/fault.c
+0
-5
arch/sparc/mm/init.c
arch/sparc/mm/init.c
+2
-2
drivers/block/sonycd535.c
drivers/block/sonycd535.c
+321
-186
drivers/char/ChangeLog
drivers/char/ChangeLog
+72
-0
drivers/char/n_tty.c
drivers/char/n_tty.c
+12
-1
drivers/char/selection.c
drivers/char/selection.c
+7
-4
drivers/char/selection.h
drivers/char/selection.h
+5
-3
drivers/char/serial.c
drivers/char/serial.c
+238
-84
drivers/char/tty_io.c
drivers/char/tty_io.c
+3
-0
drivers/net/README.wavelan
drivers/net/README.wavelan
+3
-21
drivers/net/wavelan.c
drivers/net/wavelan.c
+27
-17
fs/buffer.c
fs/buffer.c
+1
-1
fs/isofs/dir.c
fs/isofs/dir.c
+11
-8
fs/isofs/inode.c
fs/isofs/inode.c
+8
-0
fs/isofs/namei.c
fs/isofs/namei.c
+0
-11
fs/locks.c
fs/locks.c
+31
-48
fs/proc/mem.c
fs/proc/mem.c
+57
-42
include/asm-alpha/byteorder.h
include/asm-alpha/byteorder.h
+8
-14
include/asm-alpha/pgtable.h
include/asm-alpha/pgtable.h
+15
-0
include/asm-i386/byteorder.h
include/asm-i386/byteorder.h
+8
-14
include/asm-sparc/system.h
include/asm-sparc/system.h
+2
-0
include/asm-sparc/vac-ops.h
include/asm-sparc/vac-ops.h
+2
-2
include/linux/fs.h
include/linux/fs.h
+3
-2
include/linux/iso_fs_sb.h
include/linux/iso_fs_sb.h
+1
-0
include/linux/sched.h
include/linux/sched.h
+2
-1
include/linux/serial.h
include/linux/serial.h
+46
-2
include/linux/serial_reg.h
include/linux/serial_reg.h
+24
-0
include/linux/sys.h
include/linux/sys.h
+0
-5
include/linux/termios.h
include/linux/termios.h
+3
-0
include/linux/tty.h
include/linux/tty.h
+1
-0
ipc/shm.c
ipc/shm.c
+26
-53
kernel/fork.c
kernel/fork.c
+3
-4
kernel/sys.c
kernel/sys.c
+1
-0
mm/swap.c
mm/swap.c
+18
-14
net/inet/af_inet.c
net/inet/af_inet.c
+2
-0
net/inet/tcp.c
net/inet/tcp.c
+4
-2
No files found.
Makefile
View file @
5d278332
VERSION
=
1
VERSION
=
1
PATCHLEVEL
=
1
PATCHLEVEL
=
1
SUBLEVEL
=
9
3
SUBLEVEL
=
9
4
ARCH
=
i386
ARCH
=
i386
...
...
arch/alpha/kernel/entry.S
View file @
5d278332
...
@@ -145,6 +145,18 @@ entUna:
...
@@ -145,6 +145,18 @@ entUna:
rti
rti
.
end
entUna
.
end
entUna
.
align
5
.
globl
entSys
.
ent
entSys
entSys
:
SAVE_ALL
bis
$
30
,
$
30
,
$
19
lda
$
27
,
do_entSys
jsr
$
26
,(
$
27
),
do_entSys
RESTORE_ALL
rti
.
end
entSys
.
align
5
.
align
5
.
globl
sys_call_table
.
globl
sys_call_table
sys_call_table
:
sys_call_table
:
...
...
arch/alpha/kernel/process.c
View file @
5d278332
...
@@ -60,19 +60,19 @@ void flush_thread(void)
...
@@ -60,19 +60,19 @@ void flush_thread(void)
}
}
/*
/*
* This needs
lots of
work still..
* This needs
some
work still..
*/
*/
unsigned
long
copy_thread
(
int
nr
,
unsigned
long
clone_flags
,
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
void
copy_thread
(
int
nr
,
unsigned
long
clone_flags
,
unsigned
long
usp
,
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
{
{
struct
pt_regs
*
childregs
;
struct
pt_regs
*
childregs
;
p
->
tss
.
usp
=
rdusp
()
;
p
->
tss
.
usp
=
usp
;
childregs
=
((
struct
pt_regs
*
)
(
p
->
kernel_stack_page
+
PAGE_SIZE
))
-
1
;
childregs
=
((
struct
pt_regs
*
)
(
p
->
kernel_stack_page
+
PAGE_SIZE
))
-
1
;
*
childregs
=
*
regs
;
*
childregs
=
*
regs
;
p
->
tss
.
ksp
=
(
unsigned
long
)
childregs
;
p
->
tss
.
ksp
=
(
unsigned
long
)
childregs
;
/* p->tss.pc = XXXX; */
/* p->tss.pc = XXXX; */
halt
();
panic
(
"copy_thread not implemented"
);
return
clone_flags
;
}
}
/*
/*
...
@@ -84,9 +84,51 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
...
@@ -84,9 +84,51 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
/*
/*
* sys_execve() executes a new program.
* sys_execve() executes a new program.
*
* This works due to the alpha calling sequence: the first 6 args
* are gotten from registers, while the rest is on the stack, so
* we get a0-a5 for free, and then magically find "struct pt_regs"
* on the stack for us..
*
* Don't do this at home.
*/
*/
asmlinkage
int
sys_execve
(
struct
pt_regs
regs
)
asmlinkage
int
sys_execve
(
unsigned
long
a0
,
unsigned
long
a1
,
unsigned
long
a2
,
unsigned
long
a3
,
unsigned
long
a4
,
unsigned
long
a5
,
struct
pt_regs
regs
)
{
{
halt
();
int
error
;
return
0
;
char
*
filename
;
error
=
getname
((
char
*
)
a0
,
&
filename
);
if
(
error
)
return
error
;
error
=
do_execve
(
filename
,
(
char
**
)
a1
,
(
char
**
)
a2
,
&
regs
);
putname
(
filename
);
return
error
;
}
/*
* sys_fork() does the obvious thing, but not the obvious way.
* See sys_execve() above.
*/
asmlinkage
int
sys_fork
(
unsigned
long
a0
,
unsigned
long
a1
,
unsigned
long
a2
,
unsigned
long
a3
,
unsigned
long
a4
,
unsigned
long
a5
,
struct
pt_regs
regs
)
{
return
do_fork
(
COPYVM
|
SIGCHLD
,
rdusp
(),
&
regs
);
}
asmlinkage
int
sys_clone
(
unsigned
long
a0
,
unsigned
long
a1
,
unsigned
long
a2
,
unsigned
long
a3
,
unsigned
long
a4
,
unsigned
long
a5
,
struct
pt_regs
regs
)
{
unsigned
long
clone_flags
=
a0
;
unsigned
long
newsp
;
newsp
=
rdusp
();
if
(
newsp
==
a1
||
!
a1
)
clone_flags
|=
COPYVM
;
else
newsp
=
a1
;
return
do_fork
(
clone_flags
,
newsp
,
&
regs
);
}
}
arch/alpha/kernel/traps.c
View file @
5d278332
...
@@ -38,10 +38,28 @@ asmlinkage void do_entUna(unsigned long va, unsigned long opcode, unsigned long
...
@@ -38,10 +38,28 @@ asmlinkage void do_entUna(unsigned long va, unsigned long opcode, unsigned long
die_if_kernel
(
"Unaligned"
,
regs
,
0
);
die_if_kernel
(
"Unaligned"
,
regs
,
0
);
}
}
/*
* DEC means people to use the "retsys" instruction for return from
* a system call, but they are clearly misguided about this. We use
* "rti" in all cases, and fill in the stack with the return values.
* That should make signal handling etc much cleaner.
*
* Even more horribly, DEC doesn't allow system calls from kernel mode.
* "Security" features letting the user do something the kernel can't
* are a thinko. DEC palcode is strange. The PAL-code designers probably
* got terminally tainted by VMS at some point.
*/
asmlinkage
void
do_entSys
(
unsigned
long
sysnr
,
unsigned
long
arg1
,
unsigned
long
arg2
,
struct
pt_regs
*
regs
)
{
printk
(
"System call %ld(%ld,%ld)
\n
"
,
sysnr
,
arg1
,
arg2
);
die_if_kernel
(
"Syscall"
,
regs
,
0
);
}
extern
asmlinkage
void
entMM
(
void
);
extern
asmlinkage
void
entMM
(
void
);
extern
asmlinkage
void
entIF
(
void
);
extern
asmlinkage
void
entIF
(
void
);
extern
asmlinkage
void
entArith
(
void
);
extern
asmlinkage
void
entArith
(
void
);
extern
asmlinkage
void
entUna
(
void
);
extern
asmlinkage
void
entUna
(
void
);
extern
asmlinkage
void
entSys
(
void
);
void
trap_init
(
void
)
void
trap_init
(
void
)
{
{
...
@@ -59,4 +77,5 @@ void trap_init(void)
...
@@ -59,4 +77,5 @@ void trap_init(void)
wrent
(
entMM
,
2
);
wrent
(
entMM
,
2
);
wrent
(
entIF
,
3
);
wrent
(
entIF
,
3
);
wrent
(
entUna
,
4
);
wrent
(
entUna
,
4
);
wrent
(
entSys
,
5
);
}
}
arch/i386/kernel/process.c
View file @
5d278332
...
@@ -150,9 +150,8 @@ void flush_thread(void)
...
@@ -150,9 +150,8 @@ void flush_thread(void)
current
->
debugreg
[
i
]
=
0
;
current
->
debugreg
[
i
]
=
0
;
}
}
#define IS_CLONE (regs->orig_eax == __NR_clone)
void
copy_thread
(
int
nr
,
unsigned
long
clone_flags
,
unsigned
long
esp
,
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
unsigned
long
copy_thread
(
int
nr
,
unsigned
long
clone_flags
,
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
{
{
int
i
;
int
i
;
struct
pt_regs
*
childregs
;
struct
pt_regs
*
childregs
;
...
@@ -171,15 +170,9 @@ unsigned long copy_thread(int nr, unsigned long clone_flags, struct task_struct
...
@@ -171,15 +170,9 @@ unsigned long copy_thread(int nr, unsigned long clone_flags, struct task_struct
p
->
tss
.
eip
=
(
unsigned
long
)
ret_from_sys_call
;
p
->
tss
.
eip
=
(
unsigned
long
)
ret_from_sys_call
;
*
childregs
=
*
regs
;
*
childregs
=
*
regs
;
childregs
->
eax
=
0
;
childregs
->
eax
=
0
;
childregs
->
esp
=
esp
;
p
->
tss
.
back_link
=
0
;
p
->
tss
.
back_link
=
0
;
p
->
tss
.
eflags
=
regs
->
eflags
&
0xffffcfff
;
/* iopl is always 0 for a new process */
p
->
tss
.
eflags
=
regs
->
eflags
&
0xffffcfff
;
/* iopl is always 0 for a new process */
if
(
IS_CLONE
)
{
if
(
regs
->
ebx
)
childregs
->
esp
=
regs
->
ebx
;
clone_flags
=
regs
->
ecx
;
if
(
childregs
->
esp
==
regs
->
esp
)
clone_flags
|=
COPYVM
;
}
p
->
tss
.
ldt
=
_LDT
(
nr
);
p
->
tss
.
ldt
=
_LDT
(
nr
);
if
(
p
->
ldt
)
{
if
(
p
->
ldt
)
{
p
->
ldt
=
(
struct
desc_struct
*
)
vmalloc
(
LDT_ENTRIES
*
LDT_ENTRY_SIZE
);
p
->
ldt
=
(
struct
desc_struct
*
)
vmalloc
(
LDT_ENTRIES
*
LDT_ENTRY_SIZE
);
...
@@ -196,7 +189,6 @@ unsigned long copy_thread(int nr, unsigned long clone_flags, struct task_struct
...
@@ -196,7 +189,6 @@ unsigned long copy_thread(int nr, unsigned long clone_flags, struct task_struct
p
->
tss
.
io_bitmap
[
i
]
=
~
0
;
p
->
tss
.
io_bitmap
[
i
]
=
~
0
;
if
(
last_task_used_math
==
current
)
if
(
last_task_used_math
==
current
)
__asm__
(
"clts ; fnsave %0 ; frstor %0"
:
"=m"
(
p
->
tss
.
i387
));
__asm__
(
"clts ; fnsave %0 ; frstor %0"
:
"=m"
(
p
->
tss
.
i387
));
return
clone_flags
;
}
}
/*
/*
...
@@ -238,6 +230,25 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
...
@@ -238,6 +230,25 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
}
}
}
}
asmlinkage
int
sys_fork
(
struct
pt_regs
regs
)
{
return
do_fork
(
COPYVM
|
SIGCHLD
,
regs
.
esp
,
&
regs
);
}
asmlinkage
int
sys_clone
(
struct
pt_regs
regs
)
{
unsigned
long
clone_flags
;
unsigned
long
newsp
;
newsp
=
regs
.
ebx
;
clone_flags
=
regs
.
ecx
;
if
(
!
newsp
)
newsp
=
regs
.
esp
;
if
(
newsp
==
regs
.
esp
)
clone_flags
|=
COPYVM
;
return
do_fork
(
clone_flags
,
newsp
,
&
regs
);
}
/*
/*
* sys_execve() executes a new program.
* sys_execve() executes a new program.
*/
*/
...
...
arch/i386/kernel/ptrace.c
View file @
5d278332
#define THREE_LEVEL
/* ptrace.c */
/* ptrace.c */
/* By Ross Biro 1/23/92 */
/* By Ross Biro 1/23/92 */
/* edited by Linus Torvalds */
/* edited by Linus Torvalds */
...
@@ -86,11 +87,12 @@ static inline int put_stack_long(struct task_struct *task, int offset,
...
@@ -86,11 +87,12 @@ static inline int put_stack_long(struct task_struct *task, int offset,
static
unsigned
long
get_long
(
struct
vm_area_struct
*
vma
,
unsigned
long
addr
)
static
unsigned
long
get_long
(
struct
vm_area_struct
*
vma
,
unsigned
long
addr
)
{
{
pgd_t
*
pgdir
;
pgd_t
*
pgdir
;
pmd_t
*
pgmiddle
;
pte_t
*
pgtable
;
pte_t
*
pgtable
;
unsigned
long
page
;
unsigned
long
page
;
repeat:
repeat:
pgdir
=
PAGE_DIR_OFFSET
(
vma
->
vm_task
,
addr
);
pgdir
=
pgd_offset
(
vma
->
vm_task
,
addr
);
if
(
pgd_none
(
*
pgdir
))
{
if
(
pgd_none
(
*
pgdir
))
{
do_no_page
(
vma
,
addr
,
0
);
do_no_page
(
vma
,
addr
,
0
);
goto
repeat
;
goto
repeat
;
...
@@ -100,7 +102,17 @@ static unsigned long get_long(struct vm_area_struct * vma, unsigned long addr)
...
@@ -100,7 +102,17 @@ static unsigned long get_long(struct vm_area_struct * vma, unsigned long addr)
pgd_clear
(
pgdir
);
pgd_clear
(
pgdir
);
return
0
;
return
0
;
}
}
pgtable
=
(
pte_t
*
)
(
PAGE_PTR
(
addr
)
+
pgd_page
(
*
pgdir
));
pgmiddle
=
pmd_offset
(
pgdir
,
addr
);
if
(
pmd_none
(
*
pgmiddle
))
{
do_no_page
(
vma
,
addr
,
0
);
goto
repeat
;
}
if
(
pmd_bad
(
*
pgmiddle
))
{
printk
(
"ptrace: bad page middle %08lx
\n
"
,
pmd_val
(
*
pgmiddle
));
pmd_clear
(
pgmiddle
);
return
0
;
}
pgtable
=
pte_offset
(
pgmiddle
,
addr
);
if
(
!
pte_present
(
*
pgtable
))
{
if
(
!
pte_present
(
*
pgtable
))
{
do_no_page
(
vma
,
addr
,
0
);
do_no_page
(
vma
,
addr
,
0
);
goto
repeat
;
goto
repeat
;
...
@@ -126,11 +138,12 @@ static void put_long(struct vm_area_struct * vma, unsigned long addr,
...
@@ -126,11 +138,12 @@ static void put_long(struct vm_area_struct * vma, unsigned long addr,
unsigned
long
data
)
unsigned
long
data
)
{
{
pgd_t
*
pgdir
;
pgd_t
*
pgdir
;
pmd_t
*
pgmiddle
;
pte_t
*
pgtable
;
pte_t
*
pgtable
;
unsigned
long
page
;
unsigned
long
page
;
repeat:
repeat:
pgdir
=
PAGE_DIR_OFFSET
(
vma
->
vm_task
,
addr
);
pgdir
=
pgd_offset
(
vma
->
vm_task
,
addr
);
if
(
!
pgd_present
(
*
pgdir
))
{
if
(
!
pgd_present
(
*
pgdir
))
{
do_no_page
(
vma
,
addr
,
1
);
do_no_page
(
vma
,
addr
,
1
);
goto
repeat
;
goto
repeat
;
...
@@ -140,7 +153,17 @@ static void put_long(struct vm_area_struct * vma, unsigned long addr,
...
@@ -140,7 +153,17 @@ static void put_long(struct vm_area_struct * vma, unsigned long addr,
pgd_clear
(
pgdir
);
pgd_clear
(
pgdir
);
return
;
return
;
}
}
pgtable
=
(
pte_t
*
)
(
PAGE_PTR
(
addr
)
+
pgd_page
(
*
pgdir
));
pgmiddle
=
pmd_offset
(
pgdir
,
addr
);
if
(
pmd_none
(
*
pgmiddle
))
{
do_no_page
(
vma
,
addr
,
0
);
goto
repeat
;
}
if
(
pmd_bad
(
*
pgmiddle
))
{
printk
(
"ptrace: bad page middle %08lx
\n
"
,
pmd_val
(
*
pgmiddle
));
pmd_clear
(
pgmiddle
);
return
;
}
pgtable
=
pte_offset
(
pgmiddle
,
addr
);
if
(
!
pte_present
(
*
pgtable
))
{
if
(
!
pte_present
(
*
pgtable
))
{
do_no_page
(
vma
,
addr
,
1
);
do_no_page
(
vma
,
addr
,
1
);
goto
repeat
;
goto
repeat
;
...
...
arch/sparc/mm/fault.c
View file @
5d278332
...
@@ -14,11 +14,6 @@
...
@@ -14,11 +14,6 @@
extern
unsigned
long
pg0
[
1024
];
/* page table for 0-4MB for everybody */
extern
unsigned
long
pg0
[
1024
];
/* page table for 0-4MB for everybody */
extern
void
die_if_kernel
(
char
*
,
struct
pt_regs
*
,
long
);
extern
void
die_if_kernel
(
char
*
,
struct
pt_regs
*
,
long
);
/* Sparc stuff... I know this is a ugly place to put the PROM vector, don't
* remind me.
*/
extern
unsigned
int
trapbase
[];
extern
unsigned
int
end
[],
etext
[],
msgbuf
[];
struct
linux_romvec
*
romvec
;
struct
linux_romvec
*
romvec
;
/* foo */
/* foo */
...
...
arch/sparc/mm/init.c
View file @
5d278332
...
@@ -160,7 +160,7 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
...
@@ -160,7 +160,7 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
* self-modifying code.
* self-modifying code.
*/
*/
a
=
(
unsigned
long
)
etext
;
a
=
(
unsigned
long
)
&
etext
;
mask
=~
(
PTE_NC
|
PTE_W
);
/* make cacheable + not writable */
mask
=~
(
PTE_NC
|
PTE_W
);
/* make cacheable + not writable */
printk
(
"changing kernel text perms...
\n
"
);
printk
(
"changing kernel text perms...
\n
"
);
...
@@ -173,7 +173,7 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
...
@@ -173,7 +173,7 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
for
(
i
=
0
;
i
<
8
;
i
++
)
for
(
i
=
0
;
i
<
8
;
i
++
)
{
{
b
=
PAGE_ALIGN
((
unsigned
long
)
trapbase
);
b
=
PAGE_ALIGN
((
unsigned
long
)
&
trapbase
);
switch_to_context
(
i
);
switch_to_context
(
i
);
...
...
drivers/block/sonycd535.c
View file @
5d278332
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
* This is a modified version of the CDU-31A device driver (see below).
* This is a modified version of the CDU-31A device driver (see below).
* Changes were made using documentation for the CDU-531 (which Sony
* Changes were made using documentation for the CDU-531 (which Sony
* assures me is very similar to the 535) and partial disassembly of the
* assures me is very similar to the 535) and partial disassembly of the
* DOS driver. I used Minyard's driver and replaced the the CDU-31A
* DOS driver. I used Minyard's driver and replaced the the CDU-31A
* commands with the CDU-531 commands. This was complicated by a different
* commands with the CDU-531 commands. This was complicated by a different
* interface protocol with the drive. The driver is still polled.
* interface protocol with the drive. The driver is still polled.
*
*
...
@@ -23,18 +23,23 @@
...
@@ -23,18 +23,23 @@
*
*
* Things to do:
* Things to do:
* - handle errors and status better, put everything into a single word
* - handle errors and status better, put everything into a single word
* - use interrupts, DMA
* - use interrupts (code mostly there, but a big hole still missing)
* - handle multi-session CDs?
* - use DMA?
*
*
* Known Bugs:
* Known Bugs:
* -
* -
*
*
* Ken Pizzini (ken@halcyon.com)
*
* Original by:
* Ron Jeppesen (ronj.an@site007.saic.com)
* Ron Jeppesen (ronj.an@site007.saic.com)
*
*
*
*
*------------------------------------------------------------------------
*------------------------------------------------------------------------
* Sony CDROM interface device driver.
* Sony CDROM interface device driver.
*
*
* Corey Minyard (minyard@wf-rch.cirr.com) (CDU-535 complaints to
ronj
above)
* Corey Minyard (minyard@wf-rch.cirr.com) (CDU-535 complaints to
Ken
above)
*
*
* Colossians 3:17
* Colossians 3:17
*
*
...
@@ -99,6 +104,9 @@
...
@@ -99,6 +104,9 @@
# include <linux/module.h>
# include <linux/module.h>
# include <linux/malloc.h>
# include <linux/malloc.h>
# include <linux/version.h>
# include <linux/version.h>
# ifndef CONFIG_MODVERSIONS
char
kernel_version
[]
=
UTS_RELEASE
;
# endif
#endif
#endif
#include <linux/errno.h>
#include <linux/errno.h>
...
@@ -137,9 +145,11 @@
...
@@ -137,9 +145,11 @@
* proper address.
* proper address.
*/
*/
#ifndef CDU535_ADDRESS
#ifndef CDU535_ADDRESS
# define CDU535_ADDRESS (0x340)
# define CDU535_ADDRESS 0x340
#endif
#ifndef CDU535_INTERRUPT
# define CDU535_INTERRUPT 0
#endif
#endif
#ifndef CDU535_HANDLE
#ifndef CDU535_HANDLE
# define CDU535_HANDLE "cdu535"
# define CDU535_HANDLE "cdu535"
#endif
#endif
...
@@ -171,7 +181,9 @@
...
@@ -171,7 +181,9 @@
* if LOCK_DOORS is defined then the eject button is disabled while
* if LOCK_DOORS is defined then the eject button is disabled while
* the device is open.
* the device is open.
*/
*/
#define LOCK_DOORS
#ifndef NO_LOCK_DOORS
# define LOCK_DOORS
#endif
static
int
read_subcode
(
void
);
static
int
read_subcode
(
void
);
static
void
sony_get_toc
(
void
);
static
void
sony_get_toc
(
void
);
...
@@ -179,11 +191,14 @@ static int cdu_open(struct inode *inode, struct file *filp);
...
@@ -179,11 +191,14 @@ static int cdu_open(struct inode *inode, struct file *filp);
static
inline
unsigned
int
int_to_bcd
(
unsigned
int
val
);
static
inline
unsigned
int
int_to_bcd
(
unsigned
int
val
);
static
unsigned
int
bcd_to_int
(
unsigned
int
bcd
);
static
unsigned
int
bcd_to_int
(
unsigned
int
bcd
);
static
int
do_sony_cmd
(
Byte
*
cmd
,
int
nCmd
,
Byte
status
[
2
],
static
int
do_sony_cmd
(
Byte
*
cmd
,
int
nCmd
,
Byte
status
[
2
],
Byte
*
response
,
int
n
R
esponse
,
int
ignoreStatusBit7
);
Byte
*
response
,
int
n
_r
esponse
,
int
ignoreStatusBit7
);
/* The base I/O address of the Sony Interface. This is a variable (not a
/* The base I/O address of the Sony Interface. This is a variable (not a
#define) so it can be easily changed via some future ioctl() */
#define) so it can be easily changed via some future ioctl() */
static
unsigned
short
sony_cd_base_io
=
CDU535_ADDRESS
;
#ifndef MODULE
static
#endif
unsigned
short
sony535_cd_base_io
=
CDU535_ADDRESS
;
/*
/*
* The following are I/O addresses of the various registers for the drive. The
* The following are I/O addresses of the various registers for the drive. The
...
@@ -217,10 +232,10 @@ static struct s535_sony_toc *sony_toc; /* Points to the table of
...
@@ -217,10 +232,10 @@ static struct s535_sony_toc *sony_toc; /* Points to the table of
static
struct
s535_sony_subcode
*
last_sony_subcode
;
/* Points to the last
static
struct
s535_sony_subcode
*
last_sony_subcode
;
/* Points to the last
subcode address read */
subcode address read */
#ifndef MODULE
#ifndef MODULE
static
unsigned
char
*
sony_buffer
;
/* Points to the read-ahead buffer */
static
Byte
*
sony_buffer
;
/* Points to the read-ahead buffer */
#else
#else
static
unsigned
char
**
sony_buffer
;
/* Points to the pointers
static
Byte
**
sony_buffer
;
/* Points to the pointers
to the sector buffers */
to the sector buffers */
#endif
#endif
static
int
sony_inuse
=
0
;
/* is the drive in use? Only one
static
int
sony_inuse
=
0
;
/* is the drive in use? Only one
open at a time allowed */
open at a time allowed */
...
@@ -240,8 +255,17 @@ static int sony_audio_status = CDROM_AUDIO_NO_STATUS;
...
@@ -240,8 +255,17 @@ static int sony_audio_status = CDROM_AUDIO_NO_STATUS;
* I just kept the CDU-31A driver behavior rather than using the PAUSE
* I just kept the CDU-31A driver behavior rather than using the PAUSE
* command on the CDU-535.
* command on the CDU-535.
*/
*/
static
unsigned
char
cur_pos_msf
[
3
]
=
{
0
,
0
,
0
};
static
Byte
cur_pos_msf
[
3
]
=
{
0
,
0
,
0
};
static
unsigned
char
final_pos_msf
[
3
]
=
{
0
,
0
,
0
};
static
Byte
final_pos_msf
[
3
]
=
{
0
,
0
,
0
};
/* What IRQ is the drive using? 0 if none. */
#ifndef MODULE
static
#endif
int
sony535_irq_used
=
CDU535_INTERRUPT
;
/* The interrupt handler will wake this queue up when it gets an interrupt. */
static
struct
wait_queue
*
cdu535_irq_wait
=
NULL
;
/*
/*
...
@@ -251,10 +275,10 @@ static unsigned char final_pos_msf[3] = {0, 0, 0};
...
@@ -251,10 +275,10 @@ static unsigned char final_pos_msf[3] = {0, 0, 0};
static
int
static
int
cdu535_check_media_change
(
dev_t
full_dev
)
cdu535_check_media_change
(
dev_t
full_dev
)
{
{
int
retval
;
int
retval
;
if
(
MINOR
(
full_dev
)
!=
0
)
{
if
(
MINOR
(
full_dev
)
!=
0
)
{
printk
(
"Sony CD-ROM
request error: invalid device.
\n
"
);
printk
(
CDU535_MESSAGE_NAME
"
request error: invalid device.
\n
"
);
return
0
;
return
0
;
}
}
...
@@ -264,18 +288,64 @@ cdu535_check_media_change(dev_t full_dev)
...
@@ -264,18 +288,64 @@ cdu535_check_media_change(dev_t full_dev)
return
retval
;
return
retval
;
}
}
static
inline
void
enable_interrupts
(
void
)
{
#ifdef USE_IRQ
/* this code snarfed from cdu31a.c; it will not
* directly work for the cdu535 as written...
*/
curr_control_reg
|=
(
SONY_ATTN_INT_EN_BIT
|
SONY_RES_RDY_INT_EN_BIT
|
SONY_DATA_RDY_INT_EN_BIT
);
outb
(
curr_control_reg
,
sony_cd_control_reg
);
#endif
}
static
inline
void
disable_interrupts
(
void
)
{
#ifdef USE_IRQ
/* this code snarfed from cdu31a.c; it will not
* directly work for the cdu535 as written...
*/
curr_control_reg
&=
~
(
SONY_ATTN_INT_EN_BIT
|
SONY_RES_RDY_INT_EN_BIT
|
SONY_DATA_RDY_INT_EN_BIT
);
outb
(
curr_control_reg
,
sony_cd_control_reg
);
#endif
}
static
void
cdu535_interrupt
(
int
irq
,
struct
pt_regs
*
regs
)
{
disable_interrupts
();
if
(
cdu535_irq_wait
!=
NULL
)
wake_up
(
&
cdu535_irq_wait
);
else
printk
(
CDU535_MESSAGE_NAME
": Got an interrupt but nothing was waiting
\n
"
);
}
/*
/*
* Wait a little while (used for polling the drive). If in initialization,
* Wait a little while (used for polling the drive). If in initialization,
* setting a timeout doesn't work, so just loop for a while
(w
e trust
* setting a timeout doesn't work, so just loop for a while
. (W
e trust
* that the sony_sleep() call is protected by a test for proper jiffies count
).
* that the sony_sleep() call is protected by a test for proper jiffies count
.)
*/
*/
static
inline
void
static
inline
void
sony_sleep
(
void
)
sony_sleep
(
void
)
{
{
current
->
state
=
TASK_INTERRUPTIBLE
;
if
(
sony535_irq_used
<=
0
)
{
/* poll */
current
->
timeout
=
jiffies
;
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule
();
current
->
timeout
=
jiffies
;
schedule
();
}
else
{
/* Interrupt driven */
cli
();
enable_interrupts
();
interruptible_sleep_on
(
&
cdu535_irq_wait
);
sti
();
}
}
}
/*------------------start of SONY CDU535 very specific ---------------------*/
/*------------------start of SONY CDU535 very specific ---------------------*/
...
@@ -293,23 +363,24 @@ select_unit(int unit_no)
...
@@ -293,23 +363,24 @@ select_unit(int unit_no)
}
}
/***************************************************************************
/***************************************************************************
* int read_result_reg(
unsigned char
*data_ptr )
* int read_result_reg(
Byte
*data_ptr )
*
*
* Read a result byte from the Sony CDU controller, store in location pointed
* Read a result byte from the Sony CDU controller, store in location pointed
* to by data_ptr. Return zero on success, TIME_OUT if we did not receive
* to by data_ptr. Return zero on success, TIME_OUT if we did not receive
* data.
* data.
***************************************************************************/
***************************************************************************/
static
int
static
int
read_result_reg
(
unsigned
char
*
data_ptr
)
read_result_reg
(
Byte
*
data_ptr
)
{
{
int
retry_count
;
int
retry_count
;
int
read_status
;
int
read_status
;
retry_count
=
jiffies
+
SONY_JIFFIES_TIMEOUT
;
retry_count
=
jiffies
+
SONY_JIFFIES_TIMEOUT
;
while
(
jiffies
<
retry_count
)
{
while
(
jiffies
<
retry_count
)
{
if
(((
read_status
=
inb
(
read_status_reg
))
&
SONY535_RESULT_NOT_READY_BIT
)
==
0
)
{
if
(((
read_status
=
inb
(
read_status_reg
))
&
SONY535_RESULT_NOT_READY_BIT
)
==
0
)
{
#if DEBUG > 1
#if DEBUG > 1
printk
(
"read_result_reg(): readStatReg = 0x%x
\n
"
,
read_status
);
printk
(
CDU535_MESSAGE_NAME
": read_result_reg(): readStatReg = 0x%x
\n
"
,
read_status
);
#endif
#endif
*
data_ptr
=
inb
(
result_reg
);
*
data_ptr
=
inb
(
result_reg
);
return
0
;
return
0
;
...
@@ -317,14 +388,14 @@ read_result_reg(unsigned char *data_ptr)
...
@@ -317,14 +388,14 @@ read_result_reg(unsigned char *data_ptr)
sony_sleep
();
sony_sleep
();
}
}
}
}
printk
(
" Sony CDROM
read_result_reg: TIME OUT!
\n
"
);
printk
(
CDU535_MESSAGE_NAME
"
read_result_reg: TIME OUT!
\n
"
);
return
TIME_OUT
;
return
TIME_OUT
;
}
}
/****************************************************************************
/****************************************************************************
* int read_exec_status( Byte status[2] )
* int read_exec_status( Byte status[2] )
*
*
* Read the execution status of the last command and put into status.
* Read the execution status of the last command and put into status.
* Handles reading second status word if available. Returns 0 on success,
* Handles reading second status word if available. Returns 0 on success,
* TIME_OUT on failure.
* TIME_OUT on failure.
****************************************************************************/
****************************************************************************/
...
@@ -339,10 +410,8 @@ read_exec_status(Byte status[2])
...
@@ -339,10 +410,8 @@ read_exec_status(Byte status[2])
return
TIME_OUT
;
return
TIME_OUT
;
}
}
#if DEBUG > 1
#if DEBUG > 1
printk
(
"read_exec_status: read 0x%x
\n
"
,
status
[
0
]);
printk
(
CDU535_MESSAGE_NAME
": read_exec_status: read 0x%x 0x%x
\n
"
,
if
(
status
[
0
]
&
0x80
)
status
[
0
],
status
[
1
]);
printk
(
" and 0x%x
\n
"
,
status
[
1
]);
printk
(
"
\n
"
);
#endif
#endif
return
0
;
return
0
;
}
}
...
@@ -357,9 +426,9 @@ read_exec_status(Byte status[2])
...
@@ -357,9 +426,9 @@ read_exec_status(Byte status[2])
static
int
static
int
check_drive_status
(
void
)
check_drive_status
(
void
)
{
{
Byte
status
,
e_status
[
2
];
Byte
status
,
e_status
[
2
];
int
CDD
,
ATN
;
int
CDD
,
ATN
;
unsigned
char
cmd
;
Byte
cmd
;
select_unit
(
0
);
select_unit
(
0
);
if
(
sony_audio_status
==
CDROM_AUDIO_PLAY
)
{
/* check status */
if
(
sony_audio_status
==
CDROM_AUDIO_PLAY
)
{
/* check status */
...
@@ -387,7 +456,7 @@ check_drive_status(void)
...
@@ -387,7 +456,7 @@ check_drive_status(void)
return
TIME_OUT
;
return
TIME_OUT
;
#if DEBUG > 1
#if DEBUG > 1
printk
(
"--
check_drive_status() got 0x%x
\n
"
,
status
);
printk
(
CDU535_MESSAGE_NAME
":
check_drive_status() got 0x%x
\n
"
,
status
);
#endif
#endif
if
(
status
==
0
)
if
(
status
==
0
)
...
@@ -401,17 +470,17 @@ check_drive_status(void)
...
@@ -401,17 +470,17 @@ check_drive_status(void)
break
;
/* go on to CDD stuff */
break
;
/* go on to CDD stuff */
case
SONY535_ATN_BUSY
:
case
SONY535_ATN_BUSY
:
if
(
initialized
)
if
(
initialized
)
printk
(
"Sony CDROM error,
drive busy
\n
"
);
printk
(
CDU535_MESSAGE_NAME
" error:
drive busy
\n
"
);
return
CD_BUSY
;
return
CD_BUSY
;
case
SONY535_ATN_EJECT_IN_PROGRESS
:
case
SONY535_ATN_EJECT_IN_PROGRESS
:
printk
(
"Sony CDROM error,
eject in progress
\n
"
);
printk
(
CDU535_MESSAGE_NAME
" error:
eject in progress
\n
"
);
sony_audio_status
=
CDROM_AUDIO_INVALID
;
sony_audio_status
=
CDROM_AUDIO_INVALID
;
return
CD_BUSY
;
return
CD_BUSY
;
case
SONY535_ATN_RESET_OCCURRED
:
case
SONY535_ATN_RESET_OCCURRED
:
case
SONY535_ATN_DISC_CHANGED
:
case
SONY535_ATN_DISC_CHANGED
:
case
SONY535_ATN_RESET_AND_DISC_CHANGED
:
case
SONY535_ATN_RESET_AND_DISC_CHANGED
:
#if DEBUG > 0
#if DEBUG > 0
printk
(
"Sony CDROM,
reset occurred or disc changed
\n
"
);
printk
(
CDU535_MESSAGE_NAME
" notice:
reset occurred or disc changed
\n
"
);
#endif
#endif
sony_disc_changed
=
1
;
sony_disc_changed
=
1
;
sony_toc_read
=
0
;
sony_toc_read
=
0
;
...
@@ -425,16 +494,17 @@ check_drive_status(void)
...
@@ -425,16 +494,17 @@ check_drive_status(void)
}
}
return
0
;
return
0
;
default:
default:
printk
(
"Sony CDROM error,
drive busy (ATN=0x%x)
\n
"
,
ATN
);
printk
(
CDU535_MESSAGE_NAME
" error:
drive busy (ATN=0x%x)
\n
"
,
ATN
);
return
CD_BUSY
;
return
CD_BUSY
;
}
}
switch
(
CDD
)
{
/* the 531 docs are not helpful in decoding this */
switch
(
CDD
)
{
/* the 531 docs are not helpful in decoding this */
case
0x0
:
/* just use the values from the DOS driver */
case
0x0
:
/* just use the values from the DOS driver */
case
0x2
:
case
0x2
:
case
0xa
:
case
0xa
:
break
;
/* no error */
break
;
/* no error */
case
0xc
:
case
0xc
:
printk
(
"check_drive_status(): CDD = 0xc! Not properly handled!
\n
"
);
printk
(
CDU535_MESSAGE_NAME
": check_drive_status(): CDD = 0xc! Not properly handled!
\n
"
);
return
CD_BUSY
;
/* ? */
return
CD_BUSY
;
/* ? */
default:
default:
return
CD_BUSY
;
return
CD_BUSY
;
...
@@ -443,14 +513,14 @@ check_drive_status(void)
...
@@ -443,14 +513,14 @@ check_drive_status(void)
}
/* check_drive_status() */
}
/* check_drive_status() */
/*****************************************************************************
/*****************************************************************************
* int do_sony_cmd( Byte *cmd, int n_cmd, Byte status[2],
* int do_sony_cmd( Byte *cmd, int n_cmd, Byte status[2],
* Byte *response, int n_response, int ignore_status_bit7 )
* Byte *response, int n_response, int ignore_status_bit7 )
*
*
* Generic routine for executing commands. The command and its parameters
* Generic routine for executing commands. The command and its parameters
* should be placed in the cmd[] array, number of bytes in the command is
* should be placed in the cmd[] array, number of bytes in the command is
* stored in nCmd. The response from the command will be stored in the
* stored in nCmd. The response from the command will be stored in the
* response array. The number of bytes you expect back (excluding status)
* response array. The number of bytes you expect back (excluding status)
* should be passed in n
R
esponse. Finally, some
* should be passed in n
_r
esponse. Finally, some
* commands set bit 7 of the return status even when there is no second
* commands set bit 7 of the return status even when there is no second
* status byte, on these commands set ignoreStatusBit7 TRUE.
* status byte, on these commands set ignoreStatusBit7 TRUE.
* If the command was sent and data received back, then we return 0,
* If the command was sent and data received back, then we return 0,
...
@@ -462,7 +532,7 @@ static int
...
@@ -462,7 +532,7 @@ static int
do_sony_cmd
(
Byte
*
cmd
,
int
n_cmd
,
Byte
status
[
2
],
do_sony_cmd
(
Byte
*
cmd
,
int
n_cmd
,
Byte
status
[
2
],
Byte
*
response
,
int
n_response
,
int
ignore_status_bit7
)
Byte
*
response
,
int
n_response
,
int
ignore_status_bit7
)
{
{
int
i
;
int
i
;
/* write out the command */
/* write out the command */
for
(
i
=
0
;
i
<
n_cmd
;
i
++
)
for
(
i
=
0
;
i
<
n_cmd
;
i
++
)
...
@@ -471,7 +541,7 @@ do_sony_cmd(Byte * cmd, int n_cmd, Byte status[2],
...
@@ -471,7 +541,7 @@ do_sony_cmd(Byte * cmd, int n_cmd, Byte status[2],
/* read back the status */
/* read back the status */
if
(
read_result_reg
(
status
)
!=
0
)
if
(
read_result_reg
(
status
)
!=
0
)
return
TIME_OUT
;
return
TIME_OUT
;
if
(
!
ignore_status_bit7
&&
((
status
[
0
]
&
0x80
)
!=
0
))
{
if
(
!
ignore_status_bit7
&&
((
status
[
0
]
&
0x80
)
!=
0
))
{
/* get second status byte */
/* get second status byte */
if
(
read_result_reg
(
status
+
1
)
!=
0
)
if
(
read_result_reg
(
status
+
1
)
!=
0
)
return
TIME_OUT
;
return
TIME_OUT
;
...
@@ -479,7 +549,8 @@ do_sony_cmd(Byte * cmd, int n_cmd, Byte status[2],
...
@@ -479,7 +549,8 @@ do_sony_cmd(Byte * cmd, int n_cmd, Byte status[2],
status
[
1
]
=
0
;
status
[
1
]
=
0
;
}
}
#if DEBUG > 2
#if DEBUG > 2
printk
(
"do_sony_cmd %x: %x %x
\n
"
,
*
cmd
,
status
[
0
],
status
[
1
]);
printk
(
CDU535_MESSAGE_NAME
": do_sony_cmd %x: %x %x
\n
"
,
*
cmd
,
status
[
0
],
status
[
1
]);
#endif
#endif
/* do not know about when I should read set of data and when not to */
/* do not know about when I should read set of data and when not to */
...
@@ -502,7 +573,8 @@ do_sony_cmd(Byte * cmd, int n_cmd, Byte status[2],
...
@@ -502,7 +573,8 @@ do_sony_cmd(Byte * cmd, int n_cmd, Byte status[2],
static
int
static
int
set_drive_mode
(
int
mode
,
Byte
status
[
2
])
set_drive_mode
(
int
mode
,
Byte
status
[
2
])
{
{
Byte
cmd_buff
[
2
],
ret_buff
[
1
];
Byte
cmd_buff
[
2
];
Byte
ret_buff
[
1
];
cmd_buff
[
0
]
=
SONY535_SET_DRIVE_MODE
;
cmd_buff
[
0
]
=
SONY535_SET_DRIVE_MODE
;
cmd_buff
[
1
]
=
mode
;
cmd_buff
[
1
]
=
mode
;
...
@@ -510,7 +582,7 @@ set_drive_mode(int mode, Byte status[2])
...
@@ -510,7 +582,7 @@ set_drive_mode(int mode, Byte status[2])
}
}
/***************************************************************************
/***************************************************************************
* int seek_and_read_N_blocks( Byte params[], int n_blocks, Byte status[2],
* int seek_and_read_N_blocks( Byte params[], int n_blocks, Byte status[2],
* Byte *data_buff, int buff_size )
* Byte *data_buff, int buff_size )
*
*
* Read n_blocks of data from the CDROM starting at position params[0:2],
* Read n_blocks of data from the CDROM starting at position params[0:2],
...
@@ -527,19 +599,19 @@ seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
...
@@ -527,19 +599,19 @@ seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
Byte
*
data_buff
,
int
buf_size
)
Byte
*
data_buff
,
int
buf_size
)
#else
#else
seek_and_read_N_blocks
(
Byte
params
[],
int
n_blocks
,
Byte
status
[
2
],
seek_and_read_N_blocks
(
Byte
params
[],
int
n_blocks
,
Byte
status
[
2
],
unsigned
char
**
buff
,
int
buf_size
)
Byte
**
buff
,
int
buf_size
)
#endif
#endif
{
{
int
i
;
const
int
block_size
=
2048
;
const
int
block_size
=
2048
;
Byte
cmd_buff
[
7
];
Byte
cmd_buff
[
7
];
int
read_status
;
int
i
;
int
retry_count
;
int
read_status
;
#ifdef MODULE
int
retry_count
;
Byte
*
data_buff
;
#ifndef MODULE
int
sector_count
=
0
;
Byte
*
start_pos
=
data_buff
;
#else
#else
Byte
*
start_pos
=
data_buff
;
Byte
*
data_buff
;
int
sector_count
=
0
;
#endif
#endif
if
(
buf_size
<
((
long
)
block_size
)
*
n_blocks
)
if
(
buf_size
<
((
long
)
block_size
)
*
n_blocks
)
...
@@ -598,11 +670,11 @@ seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
...
@@ -598,11 +670,11 @@ seek_and_read_N_blocks(Byte params[], int n_blocks, Byte status[2],
static
int
static
int
request_toc_data
(
Byte
status
[
2
],
struct
s535_sony_toc
*
toc
)
request_toc_data
(
Byte
status
[
2
],
struct
s535_sony_toc
*
toc
)
{
{
int
to_status
;
int
to_status
;
int
i
,
j
,
n_tracks
,
track_no
;
int
i
,
j
,
n_tracks
,
track_no
;
Byte
cmd_no
=
0xb2
;
int
first_track_num
,
last_track_num
;
Byte
track_address_buffer
[
5
]
;
Byte
cmd_no
=
0xb2
;
int
first_track_num
,
last_track_num
;
Byte
track_address_buffer
[
5
]
;
/* read the fixed portion of the table of contents */
/* read the fixed portion of the table of contents */
if
((
to_status
=
do_sony_cmd
(
&
cmd_no
,
1
,
status
,
(
Byte
*
)
toc
,
15
,
1
))
!=
0
)
if
((
to_status
=
do_sony_cmd
(
&
cmd_no
,
1
,
status
,
(
Byte
*
)
toc
,
15
,
1
))
!=
0
)
...
@@ -636,19 +708,19 @@ request_toc_data(Byte status[2], struct s535_sony_toc *toc)
...
@@ -636,19 +708,19 @@ request_toc_data(Byte status[2], struct s535_sony_toc *toc)
static
int
static
int
spin_up_drive
(
Byte
status
[
2
])
spin_up_drive
(
Byte
status
[
2
])
{
{
Byte
cmd_buff
[
1
]
;
Byte
cmd
;
/* first see if the drive is already spinning */
/* first see if the drive is already spinning */
cmd
_buff
[
0
]
=
SONY535_REQUEST_DRIVE_STATUS_1
;
cmd
=
SONY535_REQUEST_DRIVE_STATUS_1
;
if
(
do_sony_cmd
(
cmd_buff
,
1
,
status
,
NULL
,
0
,
0
)
!=
0
)
if
(
do_sony_cmd
(
&
cmd
,
1
,
status
,
NULL
,
0
,
0
)
!=
0
)
return
TIME_OUT
;
return
TIME_OUT
;
if
((
status
[
0
]
&
SONY535_STATUS1_NOT_SPINNING
)
==
0
)
if
((
status
[
0
]
&
SONY535_STATUS1_NOT_SPINNING
)
==
0
)
return
0
;
/* its already spinning */
return
0
;
/* its already spinning */
/*
el
se, give the spin-up command */
/*
otherwi
se, give the spin-up command */
cmd
_buff
[
0
]
=
SONY535_SPIN_UP
;
cmd
=
SONY535_SPIN_UP
;
return
do_sony_cmd
(
cmd_buff
,
1
,
status
,
NULL
,
0
,
0
);
return
do_sony_cmd
(
&
cmd
,
1
,
status
,
NULL
,
0
,
0
);
}
/* spin_up_drive() */
}
/*--------------------end of SONY CDU535 very specific ---------------------*/
/*--------------------end of SONY CDU535 very specific ---------------------*/
...
@@ -656,8 +728,7 @@ spin_up_drive(Byte status[2])
...
@@ -656,8 +728,7 @@ spin_up_drive(Byte status[2])
static
inline
unsigned
int
static
inline
unsigned
int
int_to_bcd
(
unsigned
int
val
)
int_to_bcd
(
unsigned
int
val
)
{
{
int
retval
;
int
retval
;
retval
=
(
val
/
10
)
<<
4
;
retval
=
(
val
/
10
)
<<
4
;
retval
=
retval
|
val
%
10
;
retval
=
retval
|
val
%
10
;
...
@@ -678,7 +749,7 @@ bcd_to_int(unsigned int bcd)
...
@@ -678,7 +749,7 @@ bcd_to_int(unsigned int bcd)
* a block device) to an MSF format.
* a block device) to an MSF format.
*/
*/
static
void
static
void
log_to_msf
(
unsigned
int
log
,
unsigned
char
*
msf
)
log_to_msf
(
unsigned
int
log
,
Byte
*
msf
)
{
{
log
=
log
+
LOG_START_OFFSET
;
log
=
log
+
LOG_START_OFFSET
;
msf
[
0
]
=
int_to_bcd
(
log
/
4500
);
msf
[
0
]
=
int_to_bcd
(
log
/
4500
);
...
@@ -692,7 +763,7 @@ log_to_msf(unsigned int log, unsigned char *msf)
...
@@ -692,7 +763,7 @@ log_to_msf(unsigned int log, unsigned char *msf)
* Convert an MSF format to a logical sector.
* Convert an MSF format to a logical sector.
*/
*/
static
unsigned
int
static
unsigned
int
msf_to_log
(
unsigned
char
*
msf
)
msf_to_log
(
Byte
*
msf
)
{
{
unsigned
int
log
;
unsigned
int
log
;
...
@@ -711,8 +782,7 @@ msf_to_log(unsigned char *msf)
...
@@ -711,8 +782,7 @@ msf_to_log(unsigned char *msf)
* the drive would want to see a number-of-sector value.
* the drive would want to see a number-of-sector value.
*/
*/
static
void
static
void
size_to_buf
(
unsigned
int
size
,
size_to_buf
(
unsigned
int
size
,
Byte
*
buf
)
unsigned
char
*
buf
)
{
{
buf
[
0
]
=
size
/
65536
;
buf
[
0
]
=
size
/
65536
;
size
=
size
%
65536
;
size
=
size
%
65536
;
...
@@ -731,14 +801,15 @@ size_to_buf(unsigned int size,
...
@@ -731,14 +801,15 @@ size_to_buf(unsigned int size,
static
void
static
void
do_cdu535_request
(
void
)
do_cdu535_request
(
void
)
{
{
int
block
;
unsigned
int
dev
;
unsigned
int
dev
;
int
nsect
;
unsigned
char
params
[
10
];
int
copyoff
;
int
spin_up_retry
;
unsigned
int
read_size
;
unsigned
int
read_size
;
unsigned
char
status
[
2
],
cmd
[
2
];
int
block
;
int
nsect
;
int
copyoff
;
int
spin_up_retry
;
Byte
params
[
10
];
Byte
status
[
2
];
Byte
cmd
[
2
];
if
(
!
sony_inuse
)
{
if
(
!
sony_inuse
)
{
...
@@ -798,33 +869,37 @@ do_cdu535_request(void)
...
@@ -798,33 +869,37 @@ do_cdu535_request(void)
size_to_buf
(
read_size
,
&
params
[
3
]);
size_to_buf
(
read_size
,
&
params
[
3
]);
/*
/*
* Read the data. If the drive was not spinning,
spin it up and try
* Read the data. If the drive was not spinning,
*
once more. I know, the goto is ugly, but I am too lazy to fix it
.
*
spin it up and try once more
.
*/
*/
spin_up_retry
=
0
;
spin_up_retry
=
0
;
try_read_again:
for
(;;)
{
#if DEBUG > 1
#if DEBUG > 1
if
(
check_drive_status
()
!=
0
)
{
/* drive not ready */
if
(
check_drive_status
()
!=
0
)
{
sony_first_block
=
-
1
;
/* drive not ready */
sony_last_block
=
-
1
;
sony_first_block
=
-
1
;
end_request
(
0
);
sony_last_block
=
-
1
;
return
;
end_request
(
0
);
}
return
;
}
#endif
#endif
if
(
seek_and_read_N_blocks
(
params
,
read_size
,
status
,
sony_buffer
,
if
(
0
<=
seek_and_read_N_blocks
(
params
,
read_size
,
(
read_size
*
2048
))
<
0
)
{
status
,
sony_buffer
,
(
read_size
*
2048
)))
if
((
status
[
0
]
&
SONY535_STATUS1_NOT_SPINNING
)
&&
(
!
spin_up_retry
))
{
break
;
printk
(
" Sony535 Debug -- calling spin up when reading data!
\n
"
);
if
(
!
(
status
[
0
]
&
SONY535_STATUS1_NOT_SPINNING
)
||
cmd
[
0
]
=
SONY535_SPIN_UP
;
spin_up_retry
)
{
do_sony_cmd
(
cmd
,
1
,
status
,
NULL
,
0
,
0
);
printk
(
CDU535_MESSAGE_NAME
" Read error: 0x%.2x
\n
"
,
spin_up_retry
=
1
;
status
[
0
]);
goto
try_read_again
;
sony_first_block
=
-
1
;
sony_last_block
=
-
1
;
end_request
(
0
);
return
;
}
}
printk
(
"Sony CDROM Read error: 0x%.2x
\n
"
,
status
[
0
]);
printk
(
CDU535_MESSAGE_NAME
sony_first_block
=
-
1
;
" debug: calling spin up when reading data!
\n
"
)
;
sony_last_block
=
-
1
;
cmd
[
0
]
=
SONY535_SPIN_UP
;
end_request
(
0
);
do_sony_cmd
(
cmd
,
1
,
status
,
NULL
,
0
,
0
);
return
;
spin_up_retry
=
1
;
}
}
}
}
/*
/*
...
@@ -866,7 +941,7 @@ do_cdu535_request(void)
...
@@ -866,7 +941,7 @@ do_cdu535_request(void)
static
void
static
void
sony_get_toc
(
void
)
sony_get_toc
(
void
)
{
{
unsigned
char
status
[
2
];
Byte
status
[
2
];
if
(
!
sony_toc_read
)
{
if
(
!
sony_toc_read
)
{
/* do not call check_drive_status() from here since it can call this routine */
/* do not call check_drive_status() from here since it can call this routine */
if
(
request_toc_data
(
status
,
sony_toc
)
<
0
)
if
(
request_toc_data
(
status
,
sony_toc
)
<
0
)
...
@@ -884,8 +959,8 @@ sony_get_toc(void)
...
@@ -884,8 +959,8 @@ sony_get_toc(void)
static
int
static
int
find_track
(
int
track
)
find_track
(
int
track
)
{
{
int
i
;
int
i
;
int
num_tracks
;
int
num_tracks
;
num_tracks
=
bcd_to_int
(
sony_toc
->
last_track_num
)
-
num_tracks
=
bcd_to_int
(
sony_toc
->
last_track_num
)
-
...
@@ -905,16 +980,17 @@ find_track(int track)
...
@@ -905,16 +980,17 @@ find_track(int track)
static
int
static
int
read_subcode
(
void
)
read_subcode
(
void
)
{
{
Byte
cmd
=
SONY535_REQUEST_SUB_Q_DATA
,
status
[
2
];
Byte
cmd
=
SONY535_REQUEST_SUB_Q_DATA
;
int
dsc_status
;
Byte
status
[
2
];
int
dsc_status
;
if
(
check_drive_status
()
!=
0
)
if
(
check_drive_status
()
!=
0
)
return
-
EIO
;
return
-
EIO
;
if
((
dsc_status
=
do_sony_cmd
(
&
cmd
,
1
,
status
,
(
Byte
*
)
last_sony_subcode
,
if
((
dsc_status
=
do_sony_cmd
(
&
cmd
,
1
,
status
,
(
Byte
*
)
last_sony_subcode
,
sizeof
(
struct
s535_sony_subcode
),
1
))
!=
0
)
{
sizeof
(
struct
s535_sony_subcode
),
1
))
!=
0
)
{
printk
(
"Sony CDROM error 0x%.2x, %d (read_subcode)
\n
"
,
status
[
0
]
,
printk
(
CDU535_MESSAGE_NAME
" error 0x%.2x, %d (read_subcode)
\n
"
,
dsc_status
);
status
[
0
],
dsc_status
);
return
-
EIO
;
return
-
EIO
;
}
}
return
0
;
return
0
;
...
@@ -942,9 +1018,9 @@ sony_get_subchnl_info(long arg)
...
@@ -942,9 +1018,9 @@ sony_get_subchnl_info(long arg)
if
(
!
sony_toc_read
)
{
if
(
!
sony_toc_read
)
{
return
-
EIO
;
return
-
EIO
;
}
}
verify_area
(
VERIFY_WRITE
/* and read */
,
(
char
*
)
arg
,
sizeof
(
schi
)
);
verify_area
(
VERIFY_WRITE
/* and read */
,
(
char
*
)
arg
,
sizeof
schi
);
memcpy_fromfs
(
&
schi
,
(
char
*
)
arg
,
sizeof
(
schi
)
);
memcpy_fromfs
(
&
schi
,
(
char
*
)
arg
,
sizeof
schi
);
switch
(
sony_audio_status
)
{
switch
(
sony_audio_status
)
{
case
CDROM_AUDIO_PLAY
:
case
CDROM_AUDIO_PLAY
:
...
@@ -959,7 +1035,7 @@ sony_get_subchnl_info(long arg)
...
@@ -959,7 +1035,7 @@ sony_get_subchnl_info(long arg)
case
CDROM_AUDIO_NO_STATUS
:
case
CDROM_AUDIO_NO_STATUS
:
schi
.
cdsc_audiostatus
=
sony_audio_status
;
schi
.
cdsc_audiostatus
=
sony_audio_status
;
memcpy_tofs
((
char
*
)
arg
,
&
schi
,
sizeof
(
schi
)
);
memcpy_tofs
((
char
*
)
arg
,
&
schi
,
sizeof
schi
);
return
0
;
return
0
;
break
;
break
;
...
@@ -986,7 +1062,7 @@ sony_get_subchnl_info(long arg)
...
@@ -986,7 +1062,7 @@ sony_get_subchnl_info(long arg)
schi
.
cdsc_absaddr
.
lba
=
msf_to_log
(
last_sony_subcode
->
abs_msf
);
schi
.
cdsc_absaddr
.
lba
=
msf_to_log
(
last_sony_subcode
->
abs_msf
);
schi
.
cdsc_reladdr
.
lba
=
msf_to_log
(
last_sony_subcode
->
rel_msf
);
schi
.
cdsc_reladdr
.
lba
=
msf_to_log
(
last_sony_subcode
->
rel_msf
);
}
}
memcpy_tofs
((
char
*
)
arg
,
&
schi
,
sizeof
(
schi
)
);
memcpy_tofs
((
char
*
)
arg
,
&
schi
,
sizeof
schi
);
return
0
;
return
0
;
}
}
...
@@ -1001,9 +1077,9 @@ cdu_ioctl(struct inode *inode,
...
@@ -1001,9 +1077,9 @@ cdu_ioctl(struct inode *inode,
unsigned
long
arg
)
unsigned
long
arg
)
{
{
unsigned
int
dev
;
unsigned
int
dev
;
unsigned
char
status
[
2
];
Byte
status
[
2
];
unsigned
char
cmd_buff
[
10
],
params
[
10
];
Byte
cmd_buff
[
10
],
params
[
10
];
int
i
,
dsc_status
;
int
i
,
dsc_status
;
if
(
!
inode
)
{
if
(
!
inode
)
{
...
@@ -1019,7 +1095,8 @@ cdu_ioctl(struct inode *inode,
...
@@ -1019,7 +1095,8 @@ cdu_ioctl(struct inode *inode,
switch
(
cmd
)
{
switch
(
cmd
)
{
case
CDROMSTART
:
/* Spin up the drive */
case
CDROMSTART
:
/* Spin up the drive */
if
(
spin_up_drive
(
status
)
<
0
)
{
if
(
spin_up_drive
(
status
)
<
0
)
{
printk
(
"Sony CDROM error 0x%.2x (CDROMSTART)
\n
"
,
status
[
0
]);
printk
(
CDU535_MESSAGE_NAME
" error 0x%.2x (CDROMSTART)
\n
"
,
status
[
0
]);
return
-
EIO
;
return
-
EIO
;
}
}
return
0
;
return
0
;
...
@@ -1038,7 +1115,8 @@ cdu_ioctl(struct inode *inode,
...
@@ -1038,7 +1115,8 @@ cdu_ioctl(struct inode *inode,
dsc_status
=
do_sony_cmd
(
cmd_buff
,
1
,
status
,
NULL
,
0
,
0
);
dsc_status
=
do_sony_cmd
(
cmd_buff
,
1
,
status
,
NULL
,
0
,
0
);
if
(((
dsc_status
<
0
)
&&
(
dsc_status
!=
BAD_STATUS
))
||
if
(((
dsc_status
<
0
)
&&
(
dsc_status
!=
BAD_STATUS
))
||
((
status
[
0
]
&
~
(
SONY535_STATUS1_NOT_SPINNING
))
!=
0
))
{
((
status
[
0
]
&
~
(
SONY535_STATUS1_NOT_SPINNING
))
!=
0
))
{
printk
(
"Sony CDROM error 0x%.2x (CDROMSTOP)
\n
"
,
status
[
0
]);
printk
(
CDU535_MESSAGE_NAME
" error 0x%.2x (CDROMSTOP)
\n
"
,
status
[
0
]);
return
-
EIO
;
return
-
EIO
;
}
}
return
0
;
return
0
;
...
@@ -1047,7 +1125,8 @@ cdu_ioctl(struct inode *inode,
...
@@ -1047,7 +1125,8 @@ cdu_ioctl(struct inode *inode,
case
CDROMPAUSE
:
/* Pause the drive */
case
CDROMPAUSE
:
/* Pause the drive */
cmd_buff
[
0
]
=
SONY535_HOLD
;
/* CDU-31 driver uses AUDIO_STOP, not pause */
cmd_buff
[
0
]
=
SONY535_HOLD
;
/* CDU-31 driver uses AUDIO_STOP, not pause */
if
(
do_sony_cmd
(
cmd_buff
,
1
,
status
,
NULL
,
0
,
0
)
!=
0
)
{
if
(
do_sony_cmd
(
cmd_buff
,
1
,
status
,
NULL
,
0
,
0
)
!=
0
)
{
printk
(
"Sony CDROM error 0x%.2x (CDROMPAUSE)
\n
"
,
status
[
0
]);
printk
(
CDU535_MESSAGE_NAME
" error 0x%.2x (CDROMPAUSE)
\n
"
,
status
[
0
]);
return
-
EIO
;
return
-
EIO
;
}
}
/* Get the current position and save it for resuming */
/* Get the current position and save it for resuming */
...
@@ -1082,7 +1161,8 @@ cdu_ioctl(struct inode *inode,
...
@@ -1082,7 +1161,8 @@ cdu_ioctl(struct inode *inode,
cmd_buff
[
9
]
=
final_pos_msf
[
2
];
cmd_buff
[
9
]
=
final_pos_msf
[
2
];
if
((
do_sony_cmd
(
cmd_buff
,
5
,
status
,
NULL
,
0
,
0
)
!=
0
)
||
if
((
do_sony_cmd
(
cmd_buff
,
5
,
status
,
NULL
,
0
,
0
)
!=
0
)
||
(
do_sony_cmd
(
cmd_buff
+
5
,
5
,
status
,
NULL
,
0
,
0
)
!=
0
))
{
(
do_sony_cmd
(
cmd_buff
+
5
,
5
,
status
,
NULL
,
0
,
0
)
!=
0
))
{
printk
(
"Sony CDROM error 0x%.2x (CDROMRESUME)
\n
"
,
status
[
0
]);
printk
(
CDU535_MESSAGE_NAME
" error 0x%.2x (CDROMRESUME)
\n
"
,
status
[
0
]);
return
-
EIO
;
return
-
EIO
;
}
}
sony_audio_status
=
CDROM_AUDIO_PLAY
;
sony_audio_status
=
CDROM_AUDIO_PLAY
;
...
@@ -1108,7 +1188,8 @@ cdu_ioctl(struct inode *inode,
...
@@ -1108,7 +1188,8 @@ cdu_ioctl(struct inode *inode,
/* cmd_buff[7-9] are filled in for loop above */
/* cmd_buff[7-9] are filled in for loop above */
if
((
do_sony_cmd
(
cmd_buff
,
5
,
status
,
NULL
,
0
,
0
)
!=
0
)
||
if
((
do_sony_cmd
(
cmd_buff
,
5
,
status
,
NULL
,
0
,
0
)
!=
0
)
||
(
do_sony_cmd
(
cmd_buff
+
5
,
5
,
status
,
NULL
,
0
,
0
)
!=
0
))
{
(
do_sony_cmd
(
cmd_buff
+
5
,
5
,
status
,
NULL
,
0
,
0
)
!=
0
))
{
printk
(
"Sony CDROM error 0x%.2x (CDROMPLAYMSF)
\n
"
,
status
[
0
]);
printk
(
CDU535_MESSAGE_NAME
" error 0x%.2x (CDROMPLAYMSF)
\n
"
,
status
[
0
]);
return
-
EIO
;
return
-
EIO
;
}
}
/* Save the final position for pauses and resumes */
/* Save the final position for pauses and resumes */
...
@@ -1128,10 +1209,10 @@ cdu_ioctl(struct inode *inode,
...
@@ -1128,10 +1209,10 @@ cdu_ioctl(struct inode *inode,
if
(
!
sony_toc_read
)
if
(
!
sony_toc_read
)
return
-
EIO
;
return
-
EIO
;
hdr
=
(
struct
cdrom_tochdr
*
)
arg
;
hdr
=
(
struct
cdrom_tochdr
*
)
arg
;
verify_area
(
VERIFY_WRITE
,
hdr
,
sizeof
(
*
hdr
)
);
verify_area
(
VERIFY_WRITE
,
hdr
,
sizeof
*
hdr
);
loc_hdr
.
cdth_trk0
=
bcd_to_int
(
sony_toc
->
first_track_num
);
loc_hdr
.
cdth_trk0
=
bcd_to_int
(
sony_toc
->
first_track_num
);
loc_hdr
.
cdth_trk1
=
bcd_to_int
(
sony_toc
->
last_track_num
);
loc_hdr
.
cdth_trk1
=
bcd_to_int
(
sony_toc
->
last_track_num
);
memcpy_tofs
(
hdr
,
&
loc_hdr
,
sizeof
(
*
hdr
)
);
memcpy_tofs
(
hdr
,
&
loc_hdr
,
sizeof
*
hdr
);
}
}
return
0
;
return
0
;
break
;
break
;
...
@@ -1140,17 +1221,17 @@ cdu_ioctl(struct inode *inode,
...
@@ -1140,17 +1221,17 @@ cdu_ioctl(struct inode *inode,
{
{
struct
cdrom_tocentry
*
entry
;
struct
cdrom_tocentry
*
entry
;
struct
cdrom_tocentry
loc_entry
;
struct
cdrom_tocentry
loc_entry
;
int
track_idx
;
int
track_idx
;
unsigned
char
*
msf_val
=
NULL
;
Byte
*
msf_val
=
NULL
;
sony_get_toc
();
sony_get_toc
();
if
(
!
sony_toc_read
)
{
if
(
!
sony_toc_read
)
{
return
-
EIO
;
return
-
EIO
;
}
}
entry
=
(
struct
cdrom_tocentry
*
)
arg
;
entry
=
(
struct
cdrom_tocentry
*
)
arg
;
verify_area
(
VERIFY_WRITE
/* and read */
,
entry
,
sizeof
(
*
entry
)
);
verify_area
(
VERIFY_WRITE
/* and read */
,
entry
,
sizeof
*
entry
);
memcpy_fromfs
(
&
loc_entry
,
entry
,
sizeof
(
loc_entry
)
);
memcpy_fromfs
(
&
loc_entry
,
entry
,
sizeof
loc_entry
);
/* Lead out is handled separately since it is special. */
/* Lead out is handled separately since it is special. */
if
(
loc_entry
.
cdte_track
==
CDROM_LEADOUT
)
{
if
(
loc_entry
.
cdte_track
==
CDROM_LEADOUT
)
{
...
@@ -1174,7 +1255,7 @@ cdu_ioctl(struct inode *inode,
...
@@ -1174,7 +1255,7 @@ cdu_ioctl(struct inode *inode,
loc_entry
.
cdte_addr
.
msf
.
second
=
bcd_to_int
(
*
(
msf_val
+
1
));
loc_entry
.
cdte_addr
.
msf
.
second
=
bcd_to_int
(
*
(
msf_val
+
1
));
loc_entry
.
cdte_addr
.
msf
.
frame
=
bcd_to_int
(
*
(
msf_val
+
2
));
loc_entry
.
cdte_addr
.
msf
.
frame
=
bcd_to_int
(
*
(
msf_val
+
2
));
}
}
memcpy_tofs
(
entry
,
&
loc_entry
,
sizeof
(
*
entry
)
);
memcpy_tofs
(
entry
,
&
loc_entry
,
sizeof
*
entry
);
}
}
return
0
;
return
0
;
break
;
break
;
...
@@ -1182,14 +1263,14 @@ cdu_ioctl(struct inode *inode,
...
@@ -1182,14 +1263,14 @@ cdu_ioctl(struct inode *inode,
case
CDROMPLAYTRKIND
:
/* Play a track. This currently ignores index. */
case
CDROMPLAYTRKIND
:
/* Play a track. This currently ignores index. */
{
{
struct
cdrom_ti
ti
;
struct
cdrom_ti
ti
;
int
track_idx
;
int
track_idx
;
sony_get_toc
();
sony_get_toc
();
if
(
!
sony_toc_read
)
if
(
!
sony_toc_read
)
return
-
EIO
;
return
-
EIO
;
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
sizeof
(
ti
)
);
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
sizeof
ti
);
memcpy_fromfs
(
&
ti
,
(
char
*
)
arg
,
sizeof
(
ti
)
);
memcpy_fromfs
(
&
ti
,
(
char
*
)
arg
,
sizeof
ti
);
if
((
ti
.
cdti_trk0
<
sony_toc
->
first_track_num
)
if
((
ti
.
cdti_trk0
<
sony_toc
->
first_track_num
)
||
(
sony_toc
->
last_track_num
<
ti
.
cdti_trk0
)
||
(
sony_toc
->
last_track_num
<
ti
.
cdti_trk0
)
||
(
ti
.
cdti_trk1
<
ti
.
cdti_trk0
))
{
||
(
ti
.
cdti_trk1
<
ti
.
cdti_trk0
))
{
...
@@ -1234,9 +1315,11 @@ cdu_ioctl(struct inode *inode,
...
@@ -1234,9 +1315,11 @@ cdu_ioctl(struct inode *inode,
cmd_buff
[
9
]
=
params
[
6
];
cmd_buff
[
9
]
=
params
[
6
];
if
((
do_sony_cmd
(
cmd_buff
,
5
,
status
,
NULL
,
0
,
0
)
!=
0
)
||
if
((
do_sony_cmd
(
cmd_buff
,
5
,
status
,
NULL
,
0
,
0
)
!=
0
)
||
(
do_sony_cmd
(
cmd_buff
+
5
,
5
,
status
,
NULL
,
0
,
0
)
!=
0
))
{
(
do_sony_cmd
(
cmd_buff
+
5
,
5
,
status
,
NULL
,
0
,
0
)
!=
0
))
{
printk
(
"Params: %x %x %x %x %x %x %x
\n
"
,
params
[
0
],
params
[
1
],
printk
(
CDU535_MESSAGE_NAME
" error 0x%.2x (CDROMPLAYTRKIND)
\n
"
,
params
[
2
],
params
[
3
],
params
[
4
],
params
[
5
],
params
[
6
]);
status
[
0
]);
printk
(
"Sony CDROM error 0x%.2x (CDROMPLAYTRKIND)
\n
"
,
status
[
0
]);
printk
(
"... Params: %x %x %x %x %x %x %x
\n
"
,
params
[
0
],
params
[
1
],
params
[
2
],
params
[
3
],
params
[
4
],
params
[
5
],
params
[
6
]);
return
-
EIO
;
return
-
EIO
;
}
}
/* Save the final position for pauses and resumes */
/* Save the final position for pauses and resumes */
...
@@ -1254,14 +1337,15 @@ cdu_ioctl(struct inode *inode,
...
@@ -1254,14 +1337,15 @@ cdu_ioctl(struct inode *inode,
{
{
struct
cdrom_volctrl
volctrl
;
struct
cdrom_volctrl
volctrl
;
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
sizeof
(
volctrl
)
);
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
sizeof
volctrl
);
memcpy_fromfs
(
&
volctrl
,
(
char
*
)
arg
,
sizeof
(
volctrl
)
);
memcpy_fromfs
(
&
volctrl
,
(
char
*
)
arg
,
sizeof
volctrl
);
cmd_buff
[
0
]
=
SONY535_SET_VOLUME
;
cmd_buff
[
0
]
=
SONY535_SET_VOLUME
;
cmd_buff
[
1
]
=
volctrl
.
channel0
;
cmd_buff
[
1
]
=
volctrl
.
channel0
;
cmd_buff
[
2
]
=
volctrl
.
channel1
;
cmd_buff
[
2
]
=
volctrl
.
channel1
;
if
(
do_sony_cmd
(
cmd_buff
,
3
,
status
,
NULL
,
0
,
0
)
!=
0
)
{
if
(
do_sony_cmd
(
cmd_buff
,
3
,
status
,
NULL
,
0
,
0
)
!=
0
)
{
printk
(
"Sony CDROM error 0x%.2x (CDROMVOLCTRL)
\n
"
,
status
[
0
]);
printk
(
CDU535_MESSAGE_NAME
" error 0x%.2x (CDROMVOLCTRL)
\n
"
,
status
[
0
]);
return
-
EIO
;
return
-
EIO
;
}
}
}
}
...
@@ -1276,7 +1360,8 @@ cdu_ioctl(struct inode *inode,
...
@@ -1276,7 +1360,8 @@ cdu_ioctl(struct inode *inode,
sony_audio_status
=
CDROM_AUDIO_INVALID
;
sony_audio_status
=
CDROM_AUDIO_INVALID
;
cmd_buff
[
0
]
=
SONY535_EJECT_CADDY
;
cmd_buff
[
0
]
=
SONY535_EJECT_CADDY
;
if
(
do_sony_cmd
(
cmd_buff
,
1
,
status
,
NULL
,
0
,
0
)
!=
0
)
{
if
(
do_sony_cmd
(
cmd_buff
,
1
,
status
,
NULL
,
0
,
0
)
!=
0
)
{
printk
(
"Sony CDROM error 0x%.2x (CDROMEJECT)
\n
"
,
status
[
0
]);
printk
(
CDU535_MESSAGE_NAME
" error 0x%.2x (CDROMEJECT)
\n
"
,
status
[
0
]);
return
-
EIO
;
return
-
EIO
;
}
}
return
0
;
return
0
;
...
@@ -1296,7 +1381,7 @@ static int
...
@@ -1296,7 +1381,7 @@ static int
cdu_open
(
struct
inode
*
inode
,
cdu_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
struct
file
*
filp
)
{
{
unsigned
char
status
[
2
],
cmd_buff
[
2
];
Byte
status
[
2
],
cmd_buff
[
2
];
if
(
sony_inuse
)
if
(
sony_inuse
)
...
@@ -1307,7 +1392,8 @@ cdu_open(struct inode *inode,
...
@@ -1307,7 +1392,8 @@ cdu_open(struct inode *inode,
MOD_INC_USE_COUNT
;
MOD_INC_USE_COUNT
;
if
(
spin_up_drive
(
status
)
!=
0
)
{
if
(
spin_up_drive
(
status
)
!=
0
)
{
printk
(
"Sony CDROM error 0x%.2x (cdu_open, spin up)
\n
"
,
status
[
0
]);
printk
(
CDU535_MESSAGE_NAME
" error 0x%.2x (cdu_open, spin up)
\n
"
,
status
[
0
]);
sony_inuse
=
0
;
sony_inuse
=
0
;
MOD_DEC_USE_COUNT
;
MOD_DEC_USE_COUNT
;
return
-
EIO
;
return
-
EIO
;
...
@@ -1343,7 +1429,7 @@ static void
...
@@ -1343,7 +1429,7 @@ static void
cdu_release
(
struct
inode
*
inode
,
cdu_release
(
struct
inode
*
inode
,
struct
file
*
filp
)
struct
file
*
filp
)
{
{
unsigned
char
status
[
2
],
cmd_no
;
Byte
status
[
2
],
cmd_no
;
sony_inuse
=
0
;
sony_inuse
=
0
;
MOD_DEC_USE_COUNT
;
MOD_DEC_USE_COUNT
;
...
@@ -1392,28 +1478,44 @@ static struct file_operations cdu_fops =
...
@@ -1392,28 +1478,44 @@ static struct file_operations cdu_fops =
unsigned
long
unsigned
long
sony535_init
(
unsigned
long
mem_start
,
unsigned
long
mem_end
)
sony535_init
(
unsigned
long
mem_start
,
unsigned
long
mem_end
)
#else
#else
int
int
init_module
(
void
)
init_module
(
void
)
#endif
#endif
{
{
struct
s535_sony_drive_config
drive_config
;
struct
s535_sony_drive_config
drive_config
;
unsigned
char
cmd_buff
[
3
],
ret_buff
[
2
];
Byte
cmd_buff
[
3
];
unsigned
char
status
[
2
];
Byte
ret_buff
[
2
];
int
retry_count
;
Byte
status
[
2
];
int
retry_count
;
int
tmp_irq
;
#ifdef MODULE
#ifdef MODULE
int
i
;
int
i
;
#endif
#endif
/* Setting the base I/O address to 0xffff will disable it. */
if
(
sony535_cd_base_io
==
0xffff
)
goto
bail
;
/* Set up all the register locations */
/* Set up all the register locations */
result_reg
=
sony_cd_base_io
;
result_reg
=
sony535_cd_base_io
;
command_reg
=
sony_cd_base_io
;
command_reg
=
sony535_cd_base_io
;
data_reg
=
sony_cd_base_io
+
1
;
data_reg
=
sony535_cd_base_io
+
1
;
read_status_reg
=
sony_cd_base_io
+
2
;
read_status_reg
=
sony535_cd_base_io
+
2
;
select_unit_reg
=
sony_cd_base_io
+
3
;
select_unit_reg
=
sony535_cd_base_io
+
3
;
printk
(
"sonycd535: probing base address %03X
\n
"
,
sony_cd_base_io
);
#ifndef USE_IRQ
if
(
check_region
(
sony_cd_base_io
,
4
))
{
sony535_irq_used
=
0
;
/* polling only until this is ready... */
printk
(
"sonycd535: my base address is not free!
\n
"
);
#endif
/* we need to poll until things get initialized */
tmp_irq
=
sony535_irq_used
;
sony535_irq_used
=
0
;
#if DEBUG > 0
printk
(
CDU535_MESSAGE_NAME
": probing base address %03X
\n
"
,
sony535_cd_base_io
);
#endif
if
(
check_region
(
sony535_cd_base_io
,
4
))
{
printk
(
CDU535_MESSAGE_NAME
": my base address is not free!
\n
"
);
#ifndef MODULE
#ifndef MODULE
return
mem_start
;
return
mem_start
;
#else
#else
...
@@ -1433,19 +1535,46 @@ init_module(void)
...
@@ -1433,19 +1535,46 @@ init_module(void)
select_unit
(
0
);
select_unit
(
0
);
if
(
inb
(
result_reg
)
!=
0xff
)
if
(
inb
(
result_reg
)
!=
0xff
)
break
;
break
;
sony_sleep
();
/* about 1-2 ms on my machine */
sony_sleep
();
}
}
if
((
jiffies
<
retry_count
)
&&
(
check_drive_status
()
!=
TIME_OUT
))
{
if
((
jiffies
<
retry_count
)
&&
(
check_drive_status
()
!=
TIME_OUT
))
{
/* CD-ROM drive responded -- get the drive configuration */
/* CD-ROM drive responded -- get the drive configuration */
cmd_buff
[
0
]
=
SONY535_INQUIRY
;
cmd_buff
[
0
]
=
SONY535_INQUIRY
;
if
(
do_sony_cmd
(
cmd_buff
,
1
,
status
,
(
Byte
*
)
&
drive_config
,
28
,
1
)
==
0
)
{
if
(
do_sony_cmd
(
cmd_buff
,
1
,
status
,
/* was able to get the configuration, set drive mode as rest of init */
(
Byte
*
)
&
drive_config
,
28
,
1
)
==
0
)
{
/* was able to get the configuration,
* set drive mode as rest of init
*/
#if DEBUG > 0
#if DEBUG > 0
/* 0x50 == CADDY_NOT_INSERTED | NOT_SPINNING */
/* 0x50 == CADDY_NOT_INSERTED | NOT_SPINNING */
if
(
(
status
[
0
]
&
0x7f
)
!=
0
&&
(
status
[
0
]
&
0x7f
)
!=
0x50
)
if
(
(
status
[
0
]
&
0x7f
)
!=
0
&&
(
status
[
0
]
&
0x7f
)
!=
0x50
)
printk
(
"Inquiry command returned status = 0x%x
\n
"
,
status
[
0
]);
printk
(
CDU535_MESSAGE_NAME
"Inquiry command returned status = 0x%x
\n
"
,
status
[
0
]);
#endif
/* now ready to use interrupts, if available */
sony535_irq_used
=
tmp_irq
;
#ifndef MODULE
/* This code is not in MODULEs by default, since the autoirq stuff might
* not be in the module-accessable symbol table.
*/
/* A negative sony535_irq_used will attempt an autoirq. */
if
(
sony535_irq_used
<
0
)
{
autoirq_setup
(
0
);
enable_interrupts
();
outb
(
0
,
read_status_reg
);
/* does a reset? */
sony535_irq_used
=
autoirq_report
(
10
);
disable_interrupts
();
}
#endif
#endif
if
(
sony535_irq_used
>
0
)
{
if
(
request_irq
(
sony535_irq_used
,
cdu535_interrupt
,
SA_INTERRUPT
,
CDU535_HANDLE
))
{
printk
(
"Unable to grab IRQ%d for the "
CDU535_MESSAGE_NAME
" driver; polling instead.
\n
"
,
sony535_irq_used
);
sony535_irq_used
=
0
;
}
}
cmd_buff
[
0
]
=
SONY535_SET_DRIVE_MODE
;
cmd_buff
[
0
]
=
SONY535_SET_DRIVE_MODE
;
cmd_buff
[
1
]
=
0x0
;
/* default audio */
cmd_buff
[
1
]
=
0x0
;
/* default audio */
if
(
do_sony_cmd
(
cmd_buff
,
2
,
status
,
ret_buff
,
1
,
1
)
==
0
)
{
if
(
do_sony_cmd
(
cmd_buff
,
2
,
status
,
ret_buff
,
1
,
1
)
==
0
)
{
...
@@ -1453,11 +1582,14 @@ init_module(void)
...
@@ -1453,11 +1582,14 @@ init_module(void)
sony_buffer_size
=
SONY535_BUFFER_SIZE
;
sony_buffer_size
=
SONY535_BUFFER_SIZE
;
sony_buffer_sectors
=
sony_buffer_size
/
2048
;
sony_buffer_sectors
=
sony_buffer_size
/
2048
;
printk
(
"Sony
I/F CDROM : %8.8s %16.16s %4.4s"
,
printk
(
CDU535_MESSAGE_NAME
"
I/F CDROM : %8.8s %16.16s %4.4s"
,
drive_config
.
vendor_id
,
drive_config
.
vendor_id
,
drive_config
.
product_id
,
drive_config
.
product_id
,
drive_config
.
product_rev_level
);
drive_config
.
product_rev_level
);
printk
(
" using %d byte buffer
\n
"
,
sony_buffer_size
);
printk
(
" base address %03X, "
,
sony535_cd_base_io
);
if
(
tmp_irq
>
0
)
printk
(
"IRQ%d, "
,
tmp_irq
);
printk
(
"using %d byte buffer
\n
"
,
sony_buffer_size
);
if
(
register_blkdev
(
MAJOR_NR
,
CDU535_HANDLE
,
&
cdu_fops
))
{
if
(
register_blkdev
(
MAJOR_NR
,
CDU535_HANDLE
,
&
cdu_fops
))
{
printk
(
"Unable to get major %d for %s
\n
"
,
printk
(
"Unable to get major %d for %s
\n
"
,
...
@@ -1473,21 +1605,21 @@ init_module(void)
...
@@ -1473,21 +1605,21 @@ init_module(void)
#ifndef MODULE
#ifndef MODULE
sony_toc
=
(
struct
s535_sony_toc
*
)
mem_start
;
sony_toc
=
(
struct
s535_sony_toc
*
)
mem_start
;
mem_start
+=
sizeof
(
*
sony_toc
)
;
mem_start
+=
sizeof
*
sony_toc
;
last_sony_subcode
=
(
struct
s535_sony_subcode
*
)
mem_start
;
last_sony_subcode
=
(
struct
s535_sony_subcode
*
)
mem_start
;
mem_start
+=
sizeof
(
*
last_sony_subcode
)
;
mem_start
+=
sizeof
*
last_sony_subcode
;
sony_buffer
=
(
unsigned
char
*
)
mem_start
;
sony_buffer
=
(
Byte
*
)
mem_start
;
mem_start
+=
sony_buffer_size
;
mem_start
+=
sony_buffer_size
;
#else
/* MODULE */
#else
/* MODULE */
sony_toc
=
(
struct
s535_sony_toc
*
)
sony_toc
=
(
struct
s535_sony_toc
*
)
kmalloc
(
sizeof
(
*
sony_toc
)
,
GFP_KERNEL
);
kmalloc
(
sizeof
*
sony_toc
,
GFP_KERNEL
);
last_sony_subcode
=
(
struct
s535_sony_subcode
*
)
last_sony_subcode
=
(
struct
s535_sony_subcode
*
)
kmalloc
(
sizeof
(
*
last_sony_subcode
)
,
GFP_KERNEL
);
kmalloc
(
sizeof
*
last_sony_subcode
,
GFP_KERNEL
);
sony_buffer
=
(
unsigned
char
**
)
sony_buffer
=
(
Byte
**
)
kmalloc
(
4
*
sony_buffer_sectors
,
GFP_KERNEL
);
kmalloc
(
4
*
sony_buffer_sectors
,
GFP_KERNEL
);
for
(
i
=
0
;
i
<
sony_buffer_sectors
;
i
++
)
for
(
i
=
0
;
i
<
sony_buffer_sectors
;
i
++
)
sony_buffer
[
i
]
=
(
unsigned
char
*
)
kmalloc
(
2048
,
GFP_KERNEL
);
sony_buffer
[
i
]
=
(
Byte
*
)
kmalloc
(
2048
,
GFP_KERNEL
);
#endif
/* MODULE */
#endif
/* MODULE */
initialized
=
1
;
initialized
=
1
;
}
}
...
@@ -1500,8 +1632,9 @@ init_module(void)
...
@@ -1500,8 +1632,9 @@ init_module(void)
return
-
EIO
;
return
-
EIO
;
#endif
#endif
}
else
{
}
else
{
request_region
(
sony_cd_base_io
,
4
,
CDU535_HANDLE
);
request_region
(
sony
535
_cd_base_io
,
4
,
CDU535_HANDLE
);
}
}
bail:
#ifndef MODULE
#ifndef MODULE
return
mem_start
;
return
mem_start
;
#else
#else
...
@@ -1511,7 +1644,7 @@ init_module(void)
...
@@ -1511,7 +1644,7 @@ init_module(void)
#ifndef MODULE
#ifndef MODULE
/*
/*
* accept "kernel command line" parameters
* accept "kernel command line" parameters
* (added by emoenke@gwdg.de)
* (added by emoenke@gwdg.de)
*
*
* use: tell LILO:
* use: tell LILO:
...
@@ -1522,33 +1655,35 @@ init_module(void)
...
@@ -1522,33 +1655,35 @@ init_module(void)
void
void
sonycd535_setup
(
char
*
strings
,
int
*
ints
)
sonycd535_setup
(
char
*
strings
,
int
*
ints
)
{
{
/* if IRQ change and default io base desired,
* then call with io base of 0
*/
if
(
ints
[
0
]
>
0
)
if
(
ints
[
0
]
>
0
)
sony_cd_base_io
=
ints
[
1
];
if
(
ints
[
0
]
!=
0
)
#if 0 /* placeholder for future use */
sony535_cd_base_io
=
ints
[
1
];
if
(
ints
[
0
]
>
1
)
if
(
ints
[
0
]
>
1
)
irq_used = ints[2];
sony535_irq_used
=
ints
[
2
];
#endif
if
((
strings
!=
NULL
)
&&
(
*
strings
!=
'\0'
))
if
((
strings
!=
NULL
)
&&
(
*
strings
!=
'\0'
))
printk
(
"%s: Warning: Unknown interface type: %s
\n
"
,
printk
(
CDU535_MESSAGE_NAME
strings
,
CDU535_MESSAGE_NAME
);
": Warning: Unknown interface type: %s
\n
"
,
strings
);
}
}
#else
/* MODULE */
#else
/* MODULE */
void
void
cleanup_module
(
void
)
cleanup_module
(
void
)
{
{
int
i
;
int
i
;
if
(
MOD_IN_USE
)
{
if
(
MOD_IN_USE
)
{
printk
(
"Sony 535
module in use, cannot remove
\n
"
);
printk
(
CDU535_HANDLE
"
module in use, cannot remove
\n
"
);
return
;
return
;
}
}
release_region
(
sony_cd_base_io
,
4
);
release_region
(
sony535_cd_base_io
,
4
);
kfree_s
(
sony_toc
,
sizeof
(
*
sony_toc
));
kfree_s
(
last_sony_subcode
,
sizeof
(
*
last_sony_subcode
));
for
(
i
=
0
;
i
<
sony_buffer_sectors
;
i
++
)
for
(
i
=
0
;
i
<
sony_buffer_sectors
;
i
++
)
kfree_s
(
sony_buffer
[
i
],
2048
);
kfree_s
(
sony_buffer
[
i
],
2048
);
kfree_s
(
sony_buffer
,
4
*
sony_buffer_sectors
);
kfree_s
(
sony_buffer
,
4
*
sony_buffer_sectors
);
kfree_s
(
last_sony_subcode
,
sizeof
*
last_sony_subcode
);
kfree_s
(
sony_toc
,
sizeof
*
sony_toc
);
if
(
unregister_blkdev
(
MAJOR_NR
,
CDU535_HANDLE
)
==
-
EINVAL
)
if
(
unregister_blkdev
(
MAJOR_NR
,
CDU535_HANDLE
)
==
-
EINVAL
)
printk
(
"Uh oh, couldn't unregister "
CDU535_HANDLE
"
\n
"
);
printk
(
"Uh oh, couldn't unregister "
CDU535_HANDLE
"
\n
"
);
else
else
...
...
drivers/char/ChangeLog
View file @
5d278332
Sat Feb 18 12:13:51 1995 Theodore Y. Ts'o (tytso@rt-11)
* tty_io.c (disassociate_ctty, tty_open, tty_ioctl): Clear
current->tty_old_pgrp field when a session leader
acquires a controlling tty, and after a session leader
has disassociated from a controlling tty.
Fri Feb 17 09:34:09 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_interrupt_single, rs_interrupt, rs_interrupt_multi):
Change the the number of passes made from 64 to be 256,
configurable with the #define RS_ISR_PASS_LIMIT.
* serial.c (rs_init, set_serial_info, get_serial_info, rs_close):
Remove support for closing_wait2. Instead, set
tty->closing and rely on the line dispcline to prevent
echo wars.
* n_tty.c (n_tty_receive_char): IEXTEN does not need to be
enabled in order for IXANY to be active.
If tty->closing is set, then only process XON and XOFF
characters.
Sun Feb 12 23:57:48 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_timer): Change the interrupt poll time from 60
seconds to 10 seconds, configurable with the #define
RS_STROBE_TIME.
* serial.c (rs_interrupt_multi, startup, shutdown, rs_ioctl,
set_multiport_struct, get_multiport_struct): Add
provisions for a new type of interrutp service routine,
which better supports multiple serial ports on a single
IRQ.
Sun Feb 5 19:35:11 1995 Theodore Y. Ts'o (tytso@rt-11)
* tty_ioctl.c (n_tty_ioctl, set_termios, tty_wait_until_sent):
* serial.c (rs_ioctl, rs_close):
* cyclades.c (cy_ioctl, cy_close):
* n_tty.c (n_tty_close): Rename wait_until_sent to
tty_wait_until_sent, so that it's a better name to export
in ksyms.c.
Sat Feb 4 23:36:20 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_close): Added missing check for closing_wait2 being
ASYNC_CLOSING_WAIT_NONE.
Thu Jan 26 09:02:49 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_init, set_serial_info, get_serial_info,
rs_close): Support close_wait in the serial driver.
This is helpful for slow devices (like serial
plotters) so that their outputs don't get flushed upon
device close. This has to be configurable because
normally we don't want ports to be hung up for long
periods of time during a close when they are not
connected to a device, or the device is powered off.
The default is to wait 30 seconds; in the case of a
very slow device, the close_wait timeout should be
lengthed. If it is set to 0, the kernel will wait
forever for all of the data to be transmitted.
Thu Jan 17 01:17:20 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (startup, change_speed, rs_init): Add support to detect
the StarTech 16650 chip. Treat it as a 16450 for now,
because of its FIFO bugs.
Thu Jan 5 21:21:57 1995 <dhinds@allegro.stanford.edu>
Thu Jan 5 21:21:57 1995 <dhinds@allegro.stanford.edu>
* serial.c: (receive_char): Added counter to prevent infinite loop
* serial.c: (receive_char): Added counter to prevent infinite loop
...
...
drivers/char/n_tty.c
View file @
5d278332
...
@@ -345,7 +345,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
...
@@ -345,7 +345,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
return
;
return
;
}
}
if
(
tty
->
stopped
&&
I_IXON
(
tty
)
&&
I_IXANY
(
tty
)
&&
L_IEXTEN
(
tty
)
)
{
if
(
tty
->
stopped
&&
I_IXON
(
tty
)
&&
I_IXANY
(
tty
))
{
start_tty
(
tty
);
start_tty
(
tty
);
return
;
return
;
}
}
...
@@ -355,6 +355,16 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
...
@@ -355,6 +355,16 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
if
(
I_IUCLC
(
tty
)
&&
L_IEXTEN
(
tty
))
if
(
I_IUCLC
(
tty
)
&&
L_IEXTEN
(
tty
))
c
=
tolower
(
c
);
c
=
tolower
(
c
);
if
(
tty
->
closing
)
{
if
(
I_IXON
(
tty
))
{
if
(
c
==
START_CHAR
(
tty
))
start_tty
(
tty
);
else
if
(
c
==
STOP_CHAR
(
tty
))
stop_tty
(
tty
);
}
return
;
}
/*
/*
* If the previous character was LNEXT, or we know that this
* If the previous character was LNEXT, or we know that this
* character is not one of the characters that we'll have to
* character is not one of the characters that we'll have to
...
@@ -690,6 +700,7 @@ static int n_tty_open(struct tty_struct *tty)
...
@@ -690,6 +700,7 @@ static int n_tty_open(struct tty_struct *tty)
memset
(
tty
->
read_flags
,
0
,
sizeof
(
tty
->
read_flags
));
memset
(
tty
->
read_flags
,
0
,
sizeof
(
tty
->
read_flags
));
n_tty_set_termios
(
tty
,
0
);
n_tty_set_termios
(
tty
,
0
);
tty
->
minimum_to_wake
=
1
;
tty
->
minimum_to_wake
=
1
;
tty
->
closing
=
0
;
return
0
;
return
0
;
}
}
...
...
drivers/char/selection.c
View file @
5d278332
...
@@ -3,10 +3,10 @@
...
@@ -3,10 +3,10 @@
*
*
* This module exports the functions:
* This module exports the functions:
*
*
* 'int set_selection(const
int
arg)'
* 'int set_selection(const
unsigned long
arg)'
* 'void clear_selection(void)'
* 'void clear_selection(void)'
* 'int paste_selection(struct tty_struct *tty)'
* 'int paste_selection(struct tty_struct *tty)'
* 'int sel_loadlut(const
int
arg)'
* 'int sel_loadlut(const
unsigned long
arg)'
*
*
* Now that /dev/vcs exists, most of this can disappear again.
* Now that /dev/vcs exists, most of this can disappear again.
*/
*/
...
@@ -15,6 +15,9 @@
...
@@ -15,6 +15,9 @@
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/mm.h>
#include <linux/malloc.h>
#include <linux/malloc.h>
#include <asm/segment.h>
#include "vt_kern.h"
#include "vt_kern.h"
#include "consolemap.h"
#include "consolemap.h"
#include "selection.h"
#include "selection.h"
...
@@ -82,7 +85,7 @@ static inline int inword(const unsigned char c) {
...
@@ -82,7 +85,7 @@ static inline int inword(const unsigned char c) {
}
}
/* set inwordLut contents. Invoked by ioctl(). */
/* set inwordLut contents. Invoked by ioctl(). */
int
sel_loadlut
(
const
int
arg
)
int
sel_loadlut
(
const
unsigned
long
arg
)
{
{
int
i
=
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
36
);
int
i
=
verify_area
(
VERIFY_READ
,
(
char
*
)
arg
,
36
);
if
(
i
)
if
(
i
)
...
@@ -107,7 +110,7 @@ static inline unsigned short limit(const unsigned short v, const unsigned short
...
@@ -107,7 +110,7 @@ static inline unsigned short limit(const unsigned short v, const unsigned short
}
}
/* set the current selection. Invoked by ioctl(). */
/* set the current selection. Invoked by ioctl(). */
int
set_selection
(
const
int
arg
,
struct
tty_struct
*
tty
)
int
set_selection
(
const
unsigned
long
arg
,
struct
tty_struct
*
tty
)
{
{
int
sel_mode
,
new_sel_start
,
new_sel_end
,
spc
;
int
sel_mode
,
new_sel_start
,
new_sel_end
,
spc
;
char
*
bp
,
*
obp
;
char
*
bp
,
*
obp
;
...
...
drivers/char/selection.h
View file @
5d278332
...
@@ -6,9 +6,9 @@
...
@@ -6,9 +6,9 @@
extern
int
sel_cons
;
extern
int
sel_cons
;
extern
void
clear_selection
(
void
);
extern
void
clear_selection
(
void
);
extern
int
set_selection
(
const
int
arg
,
struct
tty_struct
*
tty
);
extern
int
set_selection
(
const
unsigned
long
arg
,
struct
tty_struct
*
tty
);
extern
int
paste_selection
(
struct
tty_struct
*
tty
);
extern
int
paste_selection
(
struct
tty_struct
*
tty
);
extern
int
sel_loadlut
(
const
int
arg
);
extern
int
sel_loadlut
(
const
unsigned
long
arg
);
extern
int
mouse_reporting
(
void
);
extern
int
mouse_reporting
(
void
);
extern
void
mouse_report
(
struct
tty_struct
*
tty
,
int
butt
,
int
mrx
,
int
mry
);
extern
void
mouse_report
(
struct
tty_struct
*
tty
,
int
butt
,
int
mrx
,
int
mry
);
...
@@ -33,7 +33,9 @@ extern void putconsxy(int currcons, char *p);
...
@@ -33,7 +33,9 @@ extern void putconsxy(int currcons, char *p);
/* how to access screen memory */
/* how to access screen memory */
#ifdef __alpha__
#ifdef __alpha__
#include <asm/io.h>
static
inline
void
scr_writew
(
unsigned
short
val
,
unsigned
short
*
addr
)
static
inline
void
scr_writew
(
unsigned
short
val
,
unsigned
short
*
addr
)
{
{
if
((
long
)
addr
<
0
)
if
((
long
)
addr
<
0
)
...
...
drivers/char/serial.c
View file @
5d278332
...
@@ -67,12 +67,14 @@ static int serial_refcount;
...
@@ -67,12 +67,14 @@ static int serial_refcount;
#define SERIAL_PARANOIA_CHECK
#define SERIAL_PARANOIA_CHECK
#define CONFIG_SERIAL_NOPAUSE_IO
#define CONFIG_SERIAL_NOPAUSE_IO
#define SERIAL_DO_RESTART
#define SERIAL_DO_RESTART
#define CONFIG_SERIAL_NEW_ISR
#undef SERIAL_DEBUG_INTR
#undef SERIAL_DEBUG_INTR
#undef SERIAL_DEBUG_OPEN
#undef SERIAL_DEBUG_OPEN
#undef SERIAL_DEBUG_FLOW
#undef SERIAL_DEBUG_FLOW
#define RS_STROBE_TIME 10
#define RS_ISR_PASS_LIMIT 256
#define _INLINE_ inline
#define _INLINE_ inline
/*
/*
...
@@ -81,6 +83,7 @@ static int serial_refcount;
...
@@ -81,6 +83,7 @@ static int serial_refcount;
*/
*/
static
struct
async_struct
*
IRQ_ports
[
16
];
static
struct
async_struct
*
IRQ_ports
[
16
];
static
struct
rs_multiport_struct
rs_multiport
[
16
];
static
int
IRQ_timeout
[
16
];
static
int
IRQ_timeout
[
16
];
static
volatile
int
rs_irq_triggered
;
static
volatile
int
rs_irq_triggered
;
static
volatile
int
rs_triggered
;
static
volatile
int
rs_triggered
;
...
@@ -420,9 +423,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
...
@@ -420,9 +423,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
if
((
info
->
xmit_cnt
<=
0
)
||
info
->
tty
->
stopped
||
if
((
info
->
xmit_cnt
<=
0
)
||
info
->
tty
->
stopped
||
info
->
tty
->
hw_stopped
)
{
info
->
tty
->
hw_stopped
)
{
info
->
IER
&=
~
UART_IER_THRI
;
info
->
IER
&=
~
UART_IER_THRI
;
#ifdef CONFIG_SERIAL_NEW_ISR
serial_out
(
info
,
UART_IER
,
info
->
IER
);
serial_out
(
info
,
UART_IER
,
info
->
IER
);
#endif
return
;
return
;
}
}
...
@@ -445,9 +446,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
...
@@ -445,9 +446,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
if
(
info
->
xmit_cnt
<=
0
)
{
if
(
info
->
xmit_cnt
<=
0
)
{
info
->
IER
&=
~
UART_IER_THRI
;
info
->
IER
&=
~
UART_IER_THRI
;
#ifdef CONFIG_SERIAL_NEW_ISR
serial_out
(
info
,
UART_IER
,
info
->
IER
);
serial_out
(
info
,
UART_IER
,
info
->
IER
);
#endif
}
}
}
}
...
@@ -480,9 +479,7 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
...
@@ -480,9 +479,7 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
#endif
#endif
info
->
tty
->
hw_stopped
=
0
;
info
->
tty
->
hw_stopped
=
0
;
info
->
IER
|=
UART_IER_THRI
;
info
->
IER
|=
UART_IER_THRI
;
#ifdef CONFIG_SERIAL_NEW_ISR
serial_out
(
info
,
UART_IER
,
info
->
IER
);
serial_out
(
info
,
UART_IER
,
info
->
IER
);
#endif
rs_sched_event
(
info
,
RS_EVENT_WRITE_WAKEUP
);
rs_sched_event
(
info
,
RS_EVENT_WRITE_WAKEUP
);
return
;
return
;
}
}
...
@@ -493,15 +490,12 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
...
@@ -493,15 +490,12 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
#endif
#endif
info
->
tty
->
hw_stopped
=
1
;
info
->
tty
->
hw_stopped
=
1
;
info
->
IER
&=
~
UART_IER_THRI
;
info
->
IER
&=
~
UART_IER_THRI
;
#ifdef CONFIG_SERIAL_NEW_ISR
serial_out
(
info
,
UART_IER
,
info
->
IER
);
serial_out
(
info
,
UART_IER
,
info
->
IER
);
#endif
}
}
}
}
}
}
}
}
#ifdef CONFIG_SERIAL_NEW_ISR
/*
/*
* This is the serial driver's generic interrupt routine
* This is the serial driver's generic interrupt routine
*/
*/
...
@@ -511,6 +505,8 @@ static void rs_interrupt(int irq, struct pt_regs * regs)
...
@@ -511,6 +505,8 @@ static void rs_interrupt(int irq, struct pt_regs * regs)
struct
async_struct
*
info
;
struct
async_struct
*
info
;
int
pass_counter
=
0
;
int
pass_counter
=
0
;
struct
async_struct
*
end_mark
=
0
;
struct
async_struct
*
end_mark
=
0
;
int
first_multi
=
0
;
struct
rs_multiport_struct
*
multi
;
#ifdef SERIAL_DEBUG_INTR
#ifdef SERIAL_DEBUG_INTR
printk
(
"rs_interrupt(%d)..."
,
irq
);
printk
(
"rs_interrupt(%d)..."
,
irq
);
...
@@ -520,6 +516,10 @@ static void rs_interrupt(int irq, struct pt_regs * regs)
...
@@ -520,6 +516,10 @@ static void rs_interrupt(int irq, struct pt_regs * regs)
if
(
!
info
)
if
(
!
info
)
return
;
return
;
multi
=
&
rs_multiport
[
irq
];
if
(
multi
->
port_monitor
)
first_multi
=
inb
(
multi
->
port_monitor
);
do
{
do
{
if
(
!
info
->
tty
||
if
(
!
info
->
tty
||
(
serial_in
(
info
,
UART_IIR
)
&
UART_IIR_NO_INT
))
{
(
serial_in
(
info
,
UART_IIR
)
&
UART_IIR_NO_INT
))
{
...
@@ -545,7 +545,7 @@ static void rs_interrupt(int irq, struct pt_regs * regs)
...
@@ -545,7 +545,7 @@ static void rs_interrupt(int irq, struct pt_regs * regs)
info
=
info
->
next_port
;
info
=
info
->
next_port
;
if
(
!
info
)
{
if
(
!
info
)
{
info
=
IRQ_ports
[
irq
];
info
=
IRQ_ports
[
irq
];
if
(
pass_counter
++
>
64
)
{
if
(
pass_counter
++
>
RS_ISR_PASS_LIMIT
)
{
#if 0
#if 0
printk("rs loop break\n");
printk("rs loop break\n");
#endif
#endif
...
@@ -554,6 +554,9 @@ static void rs_interrupt(int irq, struct pt_regs * regs)
...
@@ -554,6 +554,9 @@ static void rs_interrupt(int irq, struct pt_regs * regs)
continue
;
continue
;
}
}
}
while
(
end_mark
!=
info
);
}
while
(
end_mark
!=
info
);
if
(
multi
->
port_monitor
)
printk
(
"rs port monitor (normal) irq %d: 0x%x, 0x%x
\n
"
,
info
->
irq
,
first_multi
,
inb
(
multi
->
port_monitor
));
#ifdef SERIAL_DEBUG_INTR
#ifdef SERIAL_DEBUG_INTR
printk
(
"end.
\n
"
);
printk
(
"end.
\n
"
);
#endif
#endif
...
@@ -566,7 +569,9 @@ static void rs_interrupt_single(int irq, struct pt_regs * regs)
...
@@ -566,7 +569,9 @@ static void rs_interrupt_single(int irq, struct pt_regs * regs)
{
{
int
status
;
int
status
;
int
pass_counter
=
0
;
int
pass_counter
=
0
;
int
first_multi
=
0
;
struct
async_struct
*
info
;
struct
async_struct
*
info
;
struct
rs_multiport_struct
*
multi
;
#ifdef SERIAL_DEBUG_INTR
#ifdef SERIAL_DEBUG_INTR
printk
(
"rs_interrupt_single(%d)..."
,
irq
);
printk
(
"rs_interrupt_single(%d)..."
,
irq
);
...
@@ -576,6 +581,10 @@ static void rs_interrupt_single(int irq, struct pt_regs * regs)
...
@@ -576,6 +581,10 @@ static void rs_interrupt_single(int irq, struct pt_regs * regs)
if
(
!
info
||
!
info
->
tty
)
if
(
!
info
||
!
info
->
tty
)
return
;
return
;
multi
=
&
rs_multiport
[
irq
];
if
(
multi
->
port_monitor
)
first_multi
=
inb
(
multi
->
port_monitor
);
do
{
do
{
status
=
serial_inp
(
info
,
UART_LSR
)
&
info
->
read_status_mask
;
status
=
serial_inp
(
info
,
UART_LSR
)
&
info
->
read_status_mask
;
#ifdef SERIAL_DEBUG_INTR
#ifdef SERIAL_DEBUG_INTR
...
@@ -586,7 +595,7 @@ static void rs_interrupt_single(int irq, struct pt_regs * regs)
...
@@ -586,7 +595,7 @@ static void rs_interrupt_single(int irq, struct pt_regs * regs)
check_modem_status
(
info
);
check_modem_status
(
info
);
if
(
status
&
UART_LSR_THRE
)
if
(
status
&
UART_LSR_THRE
)
transmit_chars
(
info
,
0
);
transmit_chars
(
info
,
0
);
if
(
pass_counter
++
>
64
)
{
if
(
pass_counter
++
>
RS_ISR_PASS_LIMIT
)
{
#if 0
#if 0
printk("rs_single loop break.\n");
printk("rs_single loop break.\n");
#endif
#endif
...
@@ -594,102 +603,95 @@ static void rs_interrupt_single(int irq, struct pt_regs * regs)
...
@@ -594,102 +603,95 @@ static void rs_interrupt_single(int irq, struct pt_regs * regs)
}
}
}
while
(
!
(
serial_in
(
info
,
UART_IIR
)
&
UART_IIR_NO_INT
));
}
while
(
!
(
serial_in
(
info
,
UART_IIR
)
&
UART_IIR_NO_INT
));
info
->
last_active
=
jiffies
;
info
->
last_active
=
jiffies
;
if
(
multi
->
port_monitor
)
printk
(
"rs port monitor (single) irq %d: 0x%x, 0x%x
\n
"
,
info
->
irq
,
first_multi
,
inb
(
multi
->
port_monitor
));
#ifdef SERIAL_DEBUG_INTR
#ifdef SERIAL_DEBUG_INTR
printk
(
"end.
\n
"
);
printk
(
"end.
\n
"
);
#endif
#endif
}
}
#else
/* CONFIG_SERIAL_NEW_ISR */
/*
/*
* This is the serial driver's
generic interrupt routine
* This is the serial driver's
for multiport boards
*/
*/
static
void
rs_interrupt
(
int
irq
,
struct
pt_regs
*
regs
)
static
void
rs_interrupt
_multi
(
int
irq
,
struct
pt_regs
*
regs
)
{
{
int
status
;
int
status
;
struct
async_struct
*
info
;
struct
async_struct
*
info
;
int
done
=
1
,
pass_counter
=
0
;
int
pass_counter
=
0
;
int
first_multi
=
0
;
struct
rs_multiport_struct
*
multi
;
#ifdef SERIAL_DEBUG_INTR
#ifdef SERIAL_DEBUG_INTR
printk
(
"rs_interrupt(%d)..."
,
irq
);
printk
(
"rs_interrupt
_multi
(%d)..."
,
irq
);
#endif
#endif
info
=
IRQ_ports
[
irq
];
info
=
IRQ_ports
[
irq
];
if
(
!
info
)
if
(
!
info
)
return
;
return
;
multi
=
&
rs_multiport
[
irq
];
if
(
!
multi
->
port1
)
{
/* Should never happen */
printk
(
"rs_interrupt_multi: NULL port1!
\n
"
);
return
;
}
if
(
multi
->
port_monitor
)
first_multi
=
inb
(
multi
->
port_monitor
);
while
(
1
)
{
while
(
1
)
{
if
(
!
info
->
tty
)
if
(
!
info
->
tty
||
(
serial_in
(
info
,
UART_IIR
)
&
UART_IIR_NO_INT
))
goto
next
;
goto
next
;
serial_outp
(
info
,
UART_IER
,
0
);
info
->
last_active
=
jiffies
;
status
=
serial_inp
(
info
,
UART_LSR
)
&
info
->
read_status_mask
;
status
=
serial_inp
(
info
,
UART_LSR
)
&
info
->
read_status_mask
;
if
(
status
&
UART_LSR_DR
)
{
#ifdef SERIAL_DEBUG_INTR
printk
(
"status = %x..."
,
status
);
#endif
if
(
status
&
UART_LSR_DR
)
receive_chars
(
info
,
&
status
);
receive_chars
(
info
,
&
status
);
done
=
0
;
}
check_modem_status
(
info
);
check_modem_status
(
info
);
if
(
status
&
UART_LSR_THRE
)
if
(
status
&
UART_LSR_THRE
)
transmit_chars
(
info
,
&
done
);
transmit_chars
(
info
,
0
);
next:
next:
info
=
info
->
next_port
;
info
=
info
->
next_port
;
if
(
!
info
)
{
if
(
info
)
info
=
IRQ_ports
[
irq
];
continue
;
if
(
done
)
break
;
info
=
IRQ_ports
[
irq
];
done
=
1
;
if
(
pass_counter
++
>
RS_ISR_PASS_LIMIT
)
{
if
(
pass_counter
++
>
64
)
{
#if 1
#if 0
printk
(
"rs_multi loop break
\n
"
);
printk("rs loop break\n");
#endif
#endif
break
;
/* Prevent infinite loops */
break
;
/* Prevent infinite loops */
}
}
}
}
if
(
multi
->
port_monitor
)
printk
(
"rs port monitor irq %d: 0x%x, 0x%x
\n
"
,
/*
info
->
irq
,
first_multi
,
* Reset the IER registers; info is already set up from the
inb
(
multi
->
port_monitor
));
* above while loop.
if
((
inb
(
multi
->
port1
)
&
multi
->
mask1
)
!=
multi
->
match1
)
*/
continue
;
do
if
(
!
multi
->
port2
)
serial_outp
(
info
,
UART_IER
,
info
->
IER
)
;
break
;
while
((
info
=
info
->
next_port
)
!=
NULL
);
if
((
inb
(
multi
->
port2
)
&
multi
->
mask2
)
!=
multi
->
match2
)
}
continue
;
if
(
!
multi
->
port3
)
/*
break
;
* This is the serial driver's interrupt routine for a single port
if
((
inb
(
multi
->
port3
)
&
multi
->
mask3
)
!=
multi
->
match3
)
*/
continue
;
static
void
rs_interrupt_single
(
int
irq
,
struct
pt_regs
*
regs
)
if
(
!
multi
->
port4
)
{
break
;
int
status
;
if
((
inb
(
multi
->
port4
)
&
multi
->
mask4
)
==
multi
->
match4
)
struct
async_struct
*
info
;
continue
;
break
;
}
#ifdef SERIAL_DEBUG_INTR
#ifdef SERIAL_DEBUG_INTR
printk
(
"
rs_interrupt_single(%d)..."
,
irq
);
printk
(
"
end.
\n
"
);
#endif
#endif
info
=
IRQ_ports
[
irq
];
if
(
!
info
||
!
info
->
tty
)
return
;
serial_outp
(
info
,
UART_IER
,
0
);
status
=
serial_inp
(
info
,
UART_LSR
)
&
info
->
read_status_mask
;
if
(
status
&
UART_LSR_DR
)
receive_chars
(
info
,
&
status
);
check_modem_status
(
info
);
if
(
status
&
UART_LSR_THRE
)
transmit_chars
(
info
,
0
);
/*
* Reset the IER register
*/
serial_outp
(
info
,
UART_IER
,
info
->
IER
);
}
}
#endif
/* CONFIG_SERIAL_NEW_ISR */
/*
/*
* -------------------------------------------------------------------
* -------------------------------------------------------------------
...
@@ -747,7 +749,7 @@ static void rs_timer(void)
...
@@ -747,7 +749,7 @@ static void rs_timer(void)
struct
async_struct
*
info
;
struct
async_struct
*
info
;
unsigned
int
i
;
unsigned
int
i
;
if
((
jiffies
-
last_strobe
)
>=
60
*
HZ
)
{
if
((
jiffies
-
last_strobe
)
>=
RS_STROBE_TIME
*
HZ
)
{
for
(
i
=
1
;
i
<
16
;
i
++
)
{
for
(
i
=
1
;
i
<
16
;
i
++
)
{
info
=
IRQ_ports
[
i
];
info
=
IRQ_ports
[
i
];
if
(
!
info
)
if
(
!
info
)
...
@@ -760,14 +762,17 @@ static void rs_timer(void)
...
@@ -760,14 +762,17 @@ static void rs_timer(void)
serial_out
(
info
,
UART_IER
,
info
->
IER
);
serial_out
(
info
,
UART_IER
,
info
->
IER
);
info
=
info
->
next_port
;
info
=
info
->
next_port
;
}
while
(
info
);
}
while
(
info
);
rs_interrupt
(
i
,
NULL
);
if
(
rs_multiport
[
i
].
port1
)
rs_interrupt_multi
(
i
,
NULL
);
else
rs_interrupt
(
i
,
NULL
);
}
else
}
else
rs_interrupt_single
(
i
,
NULL
);
rs_interrupt_single
(
i
,
NULL
);
sti
();
sti
();
}
}
}
}
last_strobe
=
jiffies
;
last_strobe
=
jiffies
;
timer_table
[
RS_TIMER
].
expires
=
jiffies
+
60
*
HZ
;
timer_table
[
RS_TIMER
].
expires
=
jiffies
+
RS_STROBE_TIME
*
HZ
;
timer_active
|=
1
<<
RS_TIMER
;
timer_active
|=
1
<<
RS_TIMER
;
if
(
IRQ_ports
[
0
])
{
if
(
IRQ_ports
[
0
])
{
...
@@ -877,7 +882,11 @@ static int startup(struct async_struct * info)
...
@@ -877,7 +882,11 @@ static int startup(struct async_struct * info)
* Clear the FIFO buffers and disable them
* Clear the FIFO buffers and disable them
* (they will be reenabled in change_speed())
* (they will be reenabled in change_speed())
*/
*/
if
(
info
->
type
==
PORT_16550A
)
{
if
(
info
->
type
==
PORT_16650
)
{
serial_outp
(
info
,
UART_FCR
,
(
UART_FCR_CLEAR_RCVR
|
UART_FCR_CLEAR_XMIT
));
info
->
xmit_fifo_size
=
1
;
/* disabled for now */
}
else
if
(
info
->
type
==
PORT_16550A
)
{
serial_outp
(
info
,
UART_FCR
,
(
UART_FCR_CLEAR_RCVR
|
serial_outp
(
info
,
UART_FCR
,
(
UART_FCR_CLEAR_RCVR
|
UART_FCR_CLEAR_XMIT
));
UART_FCR_CLEAR_XMIT
));
info
->
xmit_fifo_size
=
16
;
info
->
xmit_fifo_size
=
16
;
...
@@ -906,7 +915,10 @@ static int startup(struct async_struct * info)
...
@@ -906,7 +915,10 @@ static int startup(struct async_struct * info)
!
IRQ_ports
[
info
->
irq
]
->
next_port
))
{
!
IRQ_ports
[
info
->
irq
]
->
next_port
))
{
if
(
IRQ_ports
[
info
->
irq
])
{
if
(
IRQ_ports
[
info
->
irq
])
{
free_irq
(
info
->
irq
);
free_irq
(
info
->
irq
);
handler
=
rs_interrupt
;
if
(
rs_multiport
[
info
->
irq
].
port1
)
handler
=
rs_interrupt_multi
;
else
handler
=
rs_interrupt
;
}
else
}
else
handler
=
rs_interrupt_single
;
handler
=
rs_interrupt_single
;
...
@@ -1148,6 +1160,18 @@ static void change_speed(struct async_struct *info)
...
@@ -1148,6 +1160,18 @@ static void change_speed(struct async_struct *info)
fcr
=
UART_FCR_ENABLE_FIFO
|
UART_FCR_TRIGGER_1
;
fcr
=
UART_FCR_ENABLE_FIFO
|
UART_FCR_TRIGGER_1
;
else
else
fcr
=
UART_FCR_ENABLE_FIFO
|
UART_FCR_TRIGGER_8
;
fcr
=
UART_FCR_ENABLE_FIFO
|
UART_FCR_TRIGGER_8
;
}
else
if
(
info
->
type
==
PORT_16650
)
{
/*
* On the 16650, we disable the FIFOs altogether
* because of a design bug in how the implement
* things. We could support it by completely changing
* how we handle the interrupt driver, but not today....
*
* N.B. Because there's no way to set a FIFO trigger
* at 1 char, we'd probably disable at speed below
* 2400 baud anyway...
*/
fcr
=
0
;
}
else
}
else
fcr
=
0
;
fcr
=
0
;
...
@@ -1404,6 +1428,7 @@ static int get_serial_info(struct async_struct * info,
...
@@ -1404,6 +1428,7 @@ static int get_serial_info(struct async_struct * info,
tmp
.
flags
=
info
->
flags
;
tmp
.
flags
=
info
->
flags
;
tmp
.
baud_base
=
info
->
baud_base
;
tmp
.
baud_base
=
info
->
baud_base
;
tmp
.
close_delay
=
info
->
close_delay
;
tmp
.
close_delay
=
info
->
close_delay
;
tmp
.
closing_wait
=
info
->
closing_wait
;
tmp
.
custom_divisor
=
info
->
custom_divisor
;
tmp
.
custom_divisor
=
info
->
custom_divisor
;
tmp
.
hub6
=
info
->
hub6
;
tmp
.
hub6
=
info
->
hub6
;
memcpy_tofs
(
retinfo
,
&
tmp
,
sizeof
(
*
retinfo
));
memcpy_tofs
(
retinfo
,
&
tmp
,
sizeof
(
*
retinfo
));
...
@@ -1471,6 +1496,7 @@ static int set_serial_info(struct async_struct * info,
...
@@ -1471,6 +1496,7 @@ static int set_serial_info(struct async_struct * info,
info
->
custom_divisor
=
new_serial
.
custom_divisor
;
info
->
custom_divisor
=
new_serial
.
custom_divisor
;
info
->
type
=
new_serial
.
type
;
info
->
type
=
new_serial
.
type
;
info
->
close_delay
=
new_serial
.
close_delay
;
info
->
close_delay
=
new_serial
.
close_delay
;
info
->
closing_wait
=
new_serial
.
closing_wait
;
release_region
(
info
->
port
,
8
);
release_region
(
info
->
port
,
8
);
if
(
change_port
||
change_irq
)
{
if
(
change_port
||
change_irq
)
{
...
@@ -1676,6 +1702,101 @@ static int check_wild_interrupts(int doprint)
...
@@ -1676,6 +1702,101 @@ static int check_wild_interrupts(int doprint)
return
wild_interrupts
;
return
wild_interrupts
;
}
}
static
int
get_multiport_struct
(
struct
async_struct
*
info
,
struct
serial_multiport_struct
*
retinfo
)
{
struct
serial_multiport_struct
ret
;
struct
rs_multiport_struct
*
multi
;
multi
=
&
rs_multiport
[
info
->
irq
];
ret
.
port_monitor
=
multi
->
port_monitor
;
ret
.
port1
=
multi
->
port1
;
ret
.
mask1
=
multi
->
mask1
;
ret
.
match1
=
multi
->
match1
;
ret
.
port2
=
multi
->
port2
;
ret
.
mask2
=
multi
->
mask2
;
ret
.
match2
=
multi
->
match2
;
ret
.
port3
=
multi
->
port3
;
ret
.
mask3
=
multi
->
mask3
;
ret
.
match3
=
multi
->
match3
;
ret
.
port4
=
multi
->
port4
;
ret
.
mask4
=
multi
->
mask4
;
ret
.
match4
=
multi
->
match4
;
ret
.
irq
=
info
->
irq
;
memcpy_tofs
(
retinfo
,
&
ret
,
sizeof
(
*
retinfo
));
return
0
;
}
static
int
set_multiport_struct
(
struct
async_struct
*
info
,
struct
serial_multiport_struct
*
in_multi
)
{
struct
serial_multiport_struct
new_multi
;
struct
rs_multiport_struct
*
multi
;
int
was_multi
,
now_multi
;
int
retval
;
void
(
*
handler
)(
int
,
struct
pt_regs
*
);
if
(
!
suser
())
return
-
EPERM
;
if
(
!
in_multi
)
return
-
EFAULT
;
memcpy_fromfs
(
&
new_multi
,
in_multi
,
sizeof
(
struct
serial_multiport_struct
));
if
(
new_multi
.
irq
!=
info
->
irq
||
info
->
irq
==
0
||
!
IRQ_ports
[
info
->
irq
])
return
-
EINVAL
;
multi
=
&
rs_multiport
[
info
->
irq
];
was_multi
=
(
multi
->
port1
!=
0
);
multi
->
port_monitor
=
new_multi
.
port_monitor
;
multi
->
port1
=
new_multi
.
port1
;
multi
->
mask1
=
new_multi
.
mask1
;
multi
->
match1
=
new_multi
.
match1
;
multi
->
port2
=
new_multi
.
port2
;
multi
->
mask2
=
new_multi
.
mask2
;
multi
->
match2
=
new_multi
.
match2
;
multi
->
port3
=
new_multi
.
port3
;
multi
->
mask3
=
new_multi
.
mask3
;
multi
->
match3
=
new_multi
.
match3
;
multi
->
port4
=
new_multi
.
port4
;
multi
->
mask4
=
new_multi
.
mask4
;
multi
->
match4
=
new_multi
.
match4
;
now_multi
=
(
multi
->
port1
!=
0
);
if
(
IRQ_ports
[
info
->
irq
]
->
next_port
&&
(
was_multi
!=
now_multi
))
{
free_irq
(
info
->
irq
);
if
(
now_multi
)
handler
=
rs_interrupt_multi
;
else
handler
=
rs_interrupt
;
retval
=
request_irq
(
info
->
irq
,
handler
,
SA_INTERRUPT
,
"serial"
);
if
(
retval
)
{
printk
(
"Couldn't reallocate serial interrupt "
"driver!!
\n
"
);
}
}
return
0
;
}
static
int
rs_ioctl
(
struct
tty_struct
*
tty
,
struct
file
*
file
,
static
int
rs_ioctl
(
struct
tty_struct
*
tty
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
unsigned
int
cmd
,
unsigned
long
arg
)
{
{
...
@@ -1778,6 +1899,16 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
...
@@ -1778,6 +1899,16 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
info
,
sizeof
(
struct
async_struct
));
info
,
sizeof
(
struct
async_struct
));
return
0
;
return
0
;
case
TIOCSERGETMULTI
:
error
=
verify_area
(
VERIFY_WRITE
,
(
void
*
)
arg
,
sizeof
(
struct
serial_multiport_struct
));
if
(
error
)
return
error
;
return
get_multiport_struct
(
info
,
(
struct
serial_multiport_struct
*
)
arg
);
case
TIOCSERSETMULTI
:
return
set_multiport_struct
(
info
,
(
struct
serial_multiport_struct
*
)
arg
);
default:
default:
return
-
ENOIOCTLCMD
;
return
-
ENOIOCTLCMD
;
}
}
...
@@ -1871,6 +2002,13 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
...
@@ -1871,6 +2002,13 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
info
->
normal_termios
=
*
tty
->
termios
;
info
->
normal_termios
=
*
tty
->
termios
;
if
(
info
->
flags
&
ASYNC_CALLOUT_ACTIVE
)
if
(
info
->
flags
&
ASYNC_CALLOUT_ACTIVE
)
info
->
callout_termios
=
*
tty
->
termios
;
info
->
callout_termios
=
*
tty
->
termios
;
/*
* Now we wait for the trnasmit buffer to clear; and we notify
* the line discpline only process XON/XOFF characters.
*/
tty
->
closing
=
1
;
if
(
info
->
closing_wait
!=
ASYNC_CLOSING_WAIT_NONE
)
tty_wait_until_sent
(
tty
,
info
->
closing_wait
);
/*
/*
* At this point we stop accepting input. To do this, we
* At this point we stop accepting input. To do this, we
* disable the receive line status interrupts, and tell the
* disable the receive line status interrupts, and tell the
...
@@ -1881,7 +2019,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
...
@@ -1881,7 +2019,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
info
->
read_status_mask
&=
~
UART_LSR_DR
;
info
->
read_status_mask
&=
~
UART_LSR_DR
;
if
(
info
->
flags
&
ASYNC_INITIALIZED
)
{
if
(
info
->
flags
&
ASYNC_INITIALIZED
)
{
serial_out
(
info
,
UART_IER
,
info
->
IER
);
serial_out
(
info
,
UART_IER
,
info
->
IER
);
tty_wait_until_sent
(
tty
,
3000
);
/* 30 seconds timeout */
/*
/*
* Before we drop DTR, make sure the UART transmitter
* Before we drop DTR, make sure the UART transmitter
* has completely drained; this is especially
* has completely drained; this is especially
...
@@ -1901,6 +2038,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
...
@@ -1901,6 +2038,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
tty
->
driver
.
flush_buffer
(
tty
);
tty
->
driver
.
flush_buffer
(
tty
);
if
(
tty
->
ldisc
.
flush_buffer
)
if
(
tty
->
ldisc
.
flush_buffer
)
tty
->
ldisc
.
flush_buffer
(
tty
);
tty
->
ldisc
.
flush_buffer
(
tty
);
tty
->
closing
=
0
;
info
->
event
=
0
;
info
->
event
=
0
;
info
->
tty
=
0
;
info
->
tty
=
0
;
if
(
tty
->
ldisc
.
num
!=
ldiscs
[
N_TTY
].
num
)
{
if
(
tty
->
ldisc
.
num
!=
ldiscs
[
N_TTY
].
num
)
{
...
@@ -2155,7 +2293,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
...
@@ -2155,7 +2293,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
*/
*/
static
void
show_serial_version
(
void
)
static
void
show_serial_version
(
void
)
{
{
printk
(
"Serial driver version 4.
00
with"
);
printk
(
"Serial driver version 4.
11
with"
);
#ifdef CONFIG_HUB6
#ifdef CONFIG_HUB6
printk
(
" HUB-6"
);
printk
(
" HUB-6"
);
#define SERIAL_OPT
#define SERIAL_OPT
...
@@ -2329,6 +2467,10 @@ static void autoconfig(struct async_struct * info)
...
@@ -2329,6 +2467,10 @@ static void autoconfig(struct async_struct * info)
if
(
info
->
flags
&
ASYNC_AUTO_IRQ
)
if
(
info
->
flags
&
ASYNC_AUTO_IRQ
)
info
->
irq
=
do_auto_irq
(
info
);
info
->
irq
=
do_auto_irq
(
info
);
scratch2
=
serial_in
(
info
,
UART_LCR
);
serial_outp
(
info
,
UART_LCR
,
scratch2
|
UART_LCR_DLAB
);
serial_outp
(
info
,
UART_EFR
,
0
);
/* EFR is the same as FCR */
serial_outp
(
info
,
UART_LCR
,
scratch2
);
serial_outp
(
info
,
UART_FCR
,
UART_FCR_ENABLE_FIFO
);
serial_outp
(
info
,
UART_FCR
,
UART_FCR_ENABLE_FIFO
);
scratch
=
serial_in
(
info
,
UART_IIR
)
>>
6
;
scratch
=
serial_in
(
info
,
UART_IIR
)
>>
6
;
info
->
xmit_fifo_size
=
1
;
info
->
xmit_fifo_size
=
1
;
...
@@ -2343,8 +2485,15 @@ static void autoconfig(struct async_struct * info)
...
@@ -2343,8 +2485,15 @@ static void autoconfig(struct async_struct * info)
info
->
type
=
PORT_16550
;
info
->
type
=
PORT_16550
;
break
;
break
;
case
3
:
case
3
:
info
->
type
=
PORT_16550A
;
serial_outp
(
info
,
UART_LCR
,
scratch2
|
UART_LCR_DLAB
);
info
->
xmit_fifo_size
=
16
;
if
(
serial_in
(
info
,
UART_EFR
)
==
0
)
{
info
->
type
=
PORT_16650
;
info
->
xmit_fifo_size
=
32
;
}
else
{
info
->
type
=
PORT_16550A
;
info
->
xmit_fifo_size
=
16
;
}
serial_outp
(
info
,
UART_LCR
,
scratch2
);
break
;
break
;
}
}
if
(
info
->
type
==
PORT_16450
)
{
if
(
info
->
type
==
PORT_16450
)
{
...
@@ -2398,6 +2547,7 @@ long rs_init(long kmem_start)
...
@@ -2398,6 +2547,7 @@ long rs_init(long kmem_start)
for
(
i
=
0
;
i
<
16
;
i
++
)
{
for
(
i
=
0
;
i
<
16
;
i
++
)
{
IRQ_ports
[
i
]
=
0
;
IRQ_ports
[
i
]
=
0
;
IRQ_timeout
[
i
]
=
0
;
IRQ_timeout
[
i
]
=
0
;
memset
(
&
rs_multiport
[
i
],
0
,
sizeof
(
struct
rs_multiport_struct
));
}
}
show_serial_version
();
show_serial_version
();
...
@@ -2458,6 +2608,7 @@ long rs_init(long kmem_start)
...
@@ -2458,6 +2608,7 @@ long rs_init(long kmem_start)
info
->
type
=
PORT_UNKNOWN
;
info
->
type
=
PORT_UNKNOWN
;
info
->
custom_divisor
=
0
;
info
->
custom_divisor
=
0
;
info
->
close_delay
=
50
;
info
->
close_delay
=
50
;
info
->
closing_wait
=
3000
;
info
->
x_char
=
0
;
info
->
x_char
=
0
;
info
->
event
=
0
;
info
->
event
=
0
;
info
->
count
=
0
;
info
->
count
=
0
;
...
@@ -2493,6 +2644,9 @@ long rs_init(long kmem_start)
...
@@ -2493,6 +2644,9 @@ long rs_init(long kmem_start)
case
PORT_16550A
:
case
PORT_16550A
:
printk
(
" is a 16550A
\n
"
);
printk
(
" is a 16550A
\n
"
);
break
;
break
;
case
PORT_16650
:
printk
(
" is a 16650
\n
"
);
break
;
default:
default:
printk
(
"
\n
"
);
printk
(
"
\n
"
);
break
;
break
;
...
...
drivers/char/tty_io.c
View file @
5d278332
...
@@ -452,6 +452,7 @@ void disassociate_ctty(int priv)
...
@@ -452,6 +452,7 @@ void disassociate_ctty(int priv)
kill_pg
(
tty
->
pgrp
,
SIGCONT
,
priv
);
kill_pg
(
tty
->
pgrp
,
SIGCONT
,
priv
);
}
}
current
->
tty_old_pgrp
=
0
;
tty
->
session
=
0
;
tty
->
session
=
0
;
tty
->
pgrp
=
-
1
;
tty
->
pgrp
=
-
1
;
...
@@ -1165,6 +1166,7 @@ static int tty_open(struct inode * inode, struct file * filp)
...
@@ -1165,6 +1166,7 @@ static int tty_open(struct inode * inode, struct file * filp)
!
current
->
tty
&&
!
current
->
tty
&&
tty
->
session
==
0
)
{
tty
->
session
==
0
)
{
current
->
tty
=
tty
;
current
->
tty
=
tty
;
current
->
tty_old_pgrp
=
0
;
tty
->
session
=
current
->
session
;
tty
->
session
=
current
->
session
;
tty
->
pgrp
=
current
->
pgrp
;
tty
->
pgrp
=
current
->
pgrp
;
}
}
...
@@ -1393,6 +1395,7 @@ static int tty_ioctl(struct inode * inode, struct file * file,
...
@@ -1393,6 +1395,7 @@ static int tty_ioctl(struct inode * inode, struct file * file,
return
-
EPERM
;
return
-
EPERM
;
}
}
current
->
tty
=
tty
;
current
->
tty
=
tty
;
current
->
tty_old_pgrp
=
0
;
tty
->
session
=
current
->
session
;
tty
->
session
=
current
->
session
;
tty
->
pgrp
=
current
->
pgrp
;
tty
->
pgrp
=
current
->
pgrp
;
return
0
;
return
0
;
...
...
drivers/net/README.wavelan
View file @
5d278332
#if defined(CONFIG_WAVELAN)
#if defined(CONFIG_WAVELAN)
T
ue Jan 31 10:42:35
EST 1995
T
hu Feb 23 00:10:31
EST 1995
0. This document refers to Version 5 of the Linux WaveLAN device driver software.
1. At present the driver autoprobes for a WaveLAN card only at I/O address 0x390.
It has been tested successfully under the 1.1.87 release of the Linux
kernel. It is `beta-test' software, so caveat emptor. Please report bugs
to me so that I can fix them quickly.
1. At present the driver only autoprobes for a WaveLAN card at I/O address 0x390.
The version of the card that I use (NCR) supports four I/O addresses (selectable
The version of the card that I use (NCR) supports four I/O addresses (selectable
via a pair of DIP switches). If you want the driver to autoprobe a different
via a pair of DIP switches). If you want the driver to autoprobe a different
subset of the four valid addresses then you will need to edit
subset of the four valid addresses then you will need to edit
...
@@ -28,20 +23,7 @@ Tue Jan 31 10:42:35 EST 1995
...
@@ -28,20 +23,7 @@ Tue Jan 31 10:42:35 EST 1995
append ="ether=0,0x390,0x4321,eth0"
append ="ether=0,0x390,0x4321,eth0"
..
..
3. The files that comprise this software must be incorporated into the Linux
3. If you encounter any problems send me some email.
kernel source tree (usually rooted at /usr/src/linux). Following that a
"make clean; make config; make dep; make zImage" should produce a Linux
kernel incorporating the WaveLAN driver, ready for installation.
The files:
drivers/net/wavelan.[ch]
drivers/net/i82586.h
are unique to this package and simply may be moved into place. The
others are modified versions of pre-existing files and must
be incorporated more carefully. However, the regions of modified code
within these files are small and are bracketed by the preprocessor
symbol CONFIG_WAVELAN, so incorporation should be straightforward.
4. If you encounter any problems send me some email.
Good luck,
Good luck,
Bruce Janson (bruce@cs.usyd.edu.au)
Bruce Janson (bruce@cs.usyd.edu.au)
...
...
drivers/net/wavelan.c
View file @
5d278332
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#include <linux/ioport.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/in.h>
#include <linux/string.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <asm/system.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/io.h>
...
@@ -70,7 +71,7 @@ struct net_local
...
@@ -70,7 +71,7 @@ struct net_local
extern
int
wavelan_probe
(
device
*
);
/* See Space.c */
extern
int
wavelan_probe
(
device
*
);
/* See Space.c */
static
char
*
version
=
"wavelan.c:v
5 31/1
/95
\n
"
;
static
char
*
version
=
"wavelan.c:v
6 22/2
/95
\n
"
;
/*
/*
* Entry point forward declarations.
* Entry point forward declarations.
...
@@ -103,14 +104,6 @@ static void wavelan_local_show(device *);
...
@@ -103,14 +104,6 @@ static void wavelan_local_show(device *);
static
unsigned
int
wavelan_debug
=
WAVELAN_DEBUG
;
static
unsigned
int
wavelan_debug
=
WAVELAN_DEBUG
;
static
net_local
*
first_wavelan
=
(
net_local
*
)
0
;
static
net_local
*
first_wavelan
=
(
net_local
*
)
0
;
static
void
busy_loop
(
int
i
)
{
while
(
i
--
>
0
)
;
}
static
static
unsigned
long
unsigned
long
wavelan_splhi
(
void
)
wavelan_splhi
(
void
)
...
@@ -150,7 +143,7 @@ hacr_write_slow(unsigned short ioaddr, int hacr)
...
@@ -150,7 +143,7 @@ hacr_write_slow(unsigned short ioaddr, int hacr)
{
{
hacr_write
(
ioaddr
,
hacr
);
hacr_write
(
ioaddr
,
hacr
);
/* delay might only be needed sometimes */
/* delay might only be needed sometimes */
busy_loop
(
1000
);
udelay
(
1000
);
}
}
/*
/*
...
@@ -444,11 +437,13 @@ wavelan_ack(device *dev)
...
@@ -444,11 +437,13 @@ wavelan_ack(device *dev)
set_chan_attn
(
ioaddr
,
lp
->
hacr
);
set_chan_attn
(
ioaddr
,
lp
->
hacr
);
for
(
i
=
1000
000
;
i
>
0
;
i
--
)
for
(
i
=
1000
;
i
>
0
;
i
--
)
{
{
obram_read
(
ioaddr
,
scboff
(
OFFSET_SCB
,
scb_command
),
(
unsigned
char
*
)
&
scb_cs
,
sizeof
(
scb_cs
));
obram_read
(
ioaddr
,
scboff
(
OFFSET_SCB
,
scb_command
),
(
unsigned
char
*
)
&
scb_cs
,
sizeof
(
scb_cs
));
if
(
scb_cs
==
0
)
if
(
scb_cs
==
0
)
break
;
break
;
udelay
(
1000
);
}
}
if
(
i
<=
0
)
if
(
i
<=
0
)
...
@@ -477,11 +472,13 @@ wavelan_synchronous_cmd(device *dev, char *str)
...
@@ -477,11 +472,13 @@ wavelan_synchronous_cmd(device *dev, char *str)
set_chan_attn
(
ioaddr
,
lp
->
hacr
);
set_chan_attn
(
ioaddr
,
lp
->
hacr
);
for
(
i
=
64
000
;
i
>
0
;
i
--
)
for
(
i
=
64
;
i
>
0
;
i
--
)
{
{
obram_read
(
ioaddr
,
OFFSET_CU
,
(
unsigned
char
*
)
&
cb
,
sizeof
(
cb
));
obram_read
(
ioaddr
,
OFFSET_CU
,
(
unsigned
char
*
)
&
cb
,
sizeof
(
cb
));
if
(
cb
.
ac_status
&
AC_SFLD_C
)
if
(
cb
.
ac_status
&
AC_SFLD_C
)
break
;
break
;
udelay
(
1000
);
}
}
if
(
i
<=
0
||
!
(
cb
.
ac_status
&
AC_SFLD_OK
))
if
(
i
<=
0
||
!
(
cb
.
ac_status
&
AC_SFLD_OK
))
...
@@ -557,23 +554,27 @@ wavelan_hardware_reset(device *dev)
...
@@ -557,23 +554,27 @@ wavelan_hardware_reset(device *dev)
set_chan_attn
(
ioaddr
,
lp
->
hacr
);
set_chan_attn
(
ioaddr
,
lp
->
hacr
);
for
(
i
=
1000
000
;
i
>
0
;
i
--
)
for
(
i
=
1000
;
i
>
0
;
i
--
)
{
{
obram_read
(
ioaddr
,
OFFSET_ISCP
,
(
unsigned
char
*
)
&
iscp
,
sizeof
(
iscp
));
obram_read
(
ioaddr
,
OFFSET_ISCP
,
(
unsigned
char
*
)
&
iscp
,
sizeof
(
iscp
));
if
(
iscp
.
iscp_busy
==
(
unsigned
short
)
0
)
if
(
iscp
.
iscp_busy
==
(
unsigned
short
)
0
)
break
;
break
;
udelay
(
1000
);
}
}
if
(
i
<=
0
)
if
(
i
<=
0
)
printk
(
"%s: wavelan_hardware_reset(): iscp_busy timeout.
\n
"
,
dev
->
name
);
printk
(
"%s: wavelan_hardware_reset(): iscp_busy timeout.
\n
"
,
dev
->
name
);
for
(
i
=
15
000
;
i
>
0
;
i
--
)
for
(
i
=
15
;
i
>
0
;
i
--
)
{
{
obram_read
(
ioaddr
,
OFFSET_SCB
,
(
unsigned
char
*
)
&
scb
,
sizeof
(
scb
));
obram_read
(
ioaddr
,
OFFSET_SCB
,
(
unsigned
char
*
)
&
scb
,
sizeof
(
scb
));
if
(
scb
.
scb_status
==
(
SCB_ST_CX
|
SCB_ST_CNA
))
if
(
scb
.
scb_status
==
(
SCB_ST_CX
|
SCB_ST_CNA
))
break
;
break
;
udelay
(
1000
);
}
}
if
(
i
<=
0
)
if
(
i
<=
0
)
...
@@ -970,11 +971,13 @@ wavelan_ru_start(device *dev)
...
@@ -970,11 +971,13 @@ wavelan_ru_start(device *dev)
set_chan_attn
(
ioaddr
,
lp
->
hacr
);
set_chan_attn
(
ioaddr
,
lp
->
hacr
);
for
(
i
=
1000
000
;
i
>
0
;
i
--
)
for
(
i
=
1000
;
i
>
0
;
i
--
)
{
{
obram_read
(
ioaddr
,
scboff
(
OFFSET_SCB
,
scb_command
),
(
unsigned
char
*
)
&
scb_cs
,
sizeof
(
scb_cs
));
obram_read
(
ioaddr
,
scboff
(
OFFSET_SCB
,
scb_command
),
(
unsigned
char
*
)
&
scb_cs
,
sizeof
(
scb_cs
));
if
(
scb_cs
==
0
)
if
(
scb_cs
==
0
)
break
;
break
;
udelay
(
1000
);
}
}
if
(
i
<=
0
)
if
(
i
<=
0
)
...
@@ -1049,11 +1052,13 @@ wavelan_cu_start(device *dev)
...
@@ -1049,11 +1052,13 @@ wavelan_cu_start(device *dev)
set_chan_attn
(
ioaddr
,
lp
->
hacr
);
set_chan_attn
(
ioaddr
,
lp
->
hacr
);
for
(
i
=
1000
000
;
i
>
0
;
i
--
)
for
(
i
=
1000
;
i
>
0
;
i
--
)
{
{
obram_read
(
ioaddr
,
scboff
(
OFFSET_SCB
,
scb_command
),
(
unsigned
char
*
)
&
scb_cs
,
sizeof
(
scb_cs
));
obram_read
(
ioaddr
,
scboff
(
OFFSET_SCB
,
scb_command
),
(
unsigned
char
*
)
&
scb_cs
,
sizeof
(
scb_cs
));
if
(
scb_cs
==
0
)
if
(
scb_cs
==
0
)
break
;
break
;
udelay
(
1000
);
}
}
if
(
i
<=
0
)
if
(
i
<=
0
)
...
@@ -1849,6 +1854,7 @@ void
...
@@ -1849,6 +1854,7 @@ void
wavelan_set_multicast_list
(
device
*
dev
,
int
num_addrs
,
void
*
addrs
)
wavelan_set_multicast_list
(
device
*
dev
,
int
num_addrs
,
void
*
addrs
)
{
{
net_local
*
lp
;
net_local
*
lp
;
unsigned
long
x
;
lp
=
(
net_local
*
)
dev
->
priv
;
lp
=
(
net_local
*
)
dev
->
priv
;
...
@@ -1859,7 +1865,9 @@ wavelan_set_multicast_list(device *dev, int num_addrs, void *addrs)
...
@@ -1859,7 +1865,9 @@ wavelan_set_multicast_list(device *dev, int num_addrs, void *addrs)
* Promiscuous mode: receive all packets.
* Promiscuous mode: receive all packets.
*/
*/
lp
->
promiscuous
=
1
;
lp
->
promiscuous
=
1
;
x
=
wavelan_splhi
();
(
void
)
wavelan_hardware_reset
(
dev
);
(
void
)
wavelan_hardware_reset
(
dev
);
wavelan_splx
(
x
);
break
;
break
;
case
0
:
case
0
:
...
@@ -1868,7 +1876,9 @@ wavelan_set_multicast_list(device *dev, int num_addrs, void *addrs)
...
@@ -1868,7 +1876,9 @@ wavelan_set_multicast_list(device *dev, int num_addrs, void *addrs)
* clear multicast list.
* clear multicast list.
*/
*/
lp
->
promiscuous
=
0
;
lp
->
promiscuous
=
0
;
x
=
wavelan_splhi
();
(
void
)
wavelan_hardware_reset
(
dev
);
(
void
)
wavelan_hardware_reset
(
dev
);
wavelan_splx
(
x
);
break
;
break
;
default:
default:
...
@@ -2319,9 +2329,9 @@ wavelan_local_show(device *dev)
...
@@ -2319,9 +2329,9 @@ wavelan_local_show(device *dev)
* Allan Creighton (allanc@cs.usyd.edu.au),
* Allan Creighton (allanc@cs.usyd.edu.au),
* Matthew Geier (matthew@cs.usyd.edu.au),
* Matthew Geier (matthew@cs.usyd.edu.au),
* Remo di Giovanni (remo@cs.usyd.edu.au),
* Remo di Giovanni (remo@cs.usyd.edu.au),
* Eckhard Grah (grah@wrcs1.urz.uni-wuppertal.de),
* Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM),
* Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM),
* Tim Nicholson (tim@cs.usyd.edu.au),
* Tim Nicholson (tim@cs.usyd.edu.au),
* Jeff Noxon (jeff@oylpatch.sccsi.com),
* Ian Parkin (ian@cs.usyd.edu.au),
* Ian Parkin (ian@cs.usyd.edu.au),
* John Rosenberg (johnr@cs.usyd.edu.au),
* John Rosenberg (johnr@cs.usyd.edu.au),
* George Rossi (george@phm.gov.au),
* George Rossi (george@phm.gov.au),
...
...
fs/buffer.c
View file @
5d278332
...
@@ -1363,7 +1363,7 @@ static int shrink_specific_buffers(unsigned int priority, int size)
...
@@ -1363,7 +1363,7 @@ static int shrink_specific_buffers(unsigned int priority, int size)
if
(
priority
>
3
&&
nlist
==
BUF_SHARED
)
continue
;
if
(
priority
>
3
&&
nlist
==
BUF_SHARED
)
continue
;
bh
=
lru_list
[
nlist
];
bh
=
lru_list
[
nlist
];
if
(
!
bh
)
continue
;
if
(
!
bh
)
continue
;
i
=
nr_buffers_type
[
nlist
]
>>
priority
;
i
=
2
*
nr_buffers_type
[
nlist
]
>>
priority
;
for
(
;
i
--
>
0
;
bh
=
bh
->
b_next_free
)
{
for
(
;
i
--
>
0
;
bh
=
bh
->
b_next_free
)
{
/* We may have stalled while waiting for I/O to complete. */
/* We may have stalled while waiting for I/O to complete. */
if
(
bh
->
b_list
!=
nlist
)
goto
repeat1
;
if
(
bh
->
b_list
!=
nlist
)
goto
repeat1
;
...
...
fs/isofs/dir.c
View file @
5d278332
...
@@ -183,14 +183,17 @@ static int isofs_readdir(struct inode * inode, struct file * filp,
...
@@ -183,14 +183,17 @@ static int isofs_readdir(struct inode * inode, struct file * filp,
is no Rock Ridge NM field. */
is no Rock Ridge NM field. */
else
{
else
{
/* Do not report hidden or associated files */
if
(
inode
->
i_sb
->
u
.
isofs_sb
.
s_unhide
==
'n'
)
high_sierra
=
inode
->
i_sb
->
u
.
isofs_sb
.
s_high_sierra
;
{
if
(
de
->
flags
[
-
high_sierra
]
&
5
)
{
/* Do not report hidden or associated files */
if
(
cpnt
)
{
high_sierra
=
inode
->
i_sb
->
u
.
isofs_sb
.
s_high_sierra
;
kfree
(
cpnt
);
if
(
de
->
flags
[
-
high_sierra
]
&
5
)
{
cpnt
=
NULL
;
if
(
cpnt
)
{
};
kfree
(
cpnt
);
continue
;
cpnt
=
NULL
;
};
continue
;
}
}
}
dlen
=
de
->
name_len
[
0
];
dlen
=
de
->
name_len
[
0
];
dpnt
=
de
->
name
;
dpnt
=
de
->
name
;
...
...
fs/isofs/inode.c
View file @
5d278332
...
@@ -63,6 +63,7 @@ struct iso9660_options{
...
@@ -63,6 +63,7 @@ struct iso9660_options{
char
map
;
char
map
;
char
rock
;
char
rock
;
char
cruft
;
char
cruft
;
char
unhide
;
unsigned
char
conversion
;
unsigned
char
conversion
;
unsigned
int
blocksize
;
unsigned
int
blocksize
;
mode_t
mode
;
mode_t
mode
;
...
@@ -77,6 +78,7 @@ static int parse_options(char *options, struct iso9660_options * popt)
...
@@ -77,6 +78,7 @@ static int parse_options(char *options, struct iso9660_options * popt)
popt
->
map
=
'n'
;
popt
->
map
=
'n'
;
popt
->
rock
=
'y'
;
popt
->
rock
=
'y'
;
popt
->
cruft
=
'n'
;
popt
->
cruft
=
'n'
;
popt
->
unhide
=
'n'
;
popt
->
conversion
=
'a'
;
popt
->
conversion
=
'a'
;
popt
->
blocksize
=
1024
;
popt
->
blocksize
=
1024
;
popt
->
mode
=
S_IRUGO
;
popt
->
mode
=
S_IRUGO
;
...
@@ -88,6 +90,10 @@ static int parse_options(char *options, struct iso9660_options * popt)
...
@@ -88,6 +90,10 @@ static int parse_options(char *options, struct iso9660_options * popt)
popt
->
rock
=
'n'
;
popt
->
rock
=
'n'
;
continue
;
continue
;
};
};
if
(
strncmp
(
this_char
,
"unhide"
,
6
)
==
0
)
{
popt
->
unhide
=
'y'
;
continue
;
};
if
(
strncmp
(
this_char
,
"cruft"
,
5
)
==
0
)
{
if
(
strncmp
(
this_char
,
"cruft"
,
5
)
==
0
)
{
popt
->
cruft
=
'y'
;
popt
->
cruft
=
'y'
;
continue
;
continue
;
...
@@ -214,6 +220,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
...
@@ -214,6 +220,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
printk("map = %c\n", opt.map);
printk("map = %c\n", opt.map);
printk("rock = %c\n", opt.rock);
printk("rock = %c\n", opt.rock);
printk("cruft = %c\n", opt.cruft);
printk("cruft = %c\n", opt.cruft);
printk("unhide = %c\n", opt.unhide);
printk("conversion = %c\n", opt.conversion);
printk("conversion = %c\n", opt.conversion);
printk("blocksize = %d\n", opt.blocksize);
printk("blocksize = %d\n", opt.blocksize);
printk("gid = %d\n", opt.gid);
printk("gid = %d\n", opt.gid);
...
@@ -353,6 +360,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
...
@@ -353,6 +360,7 @@ struct super_block *isofs_read_super(struct super_block *s,void *data,
s
->
u
.
isofs_sb
.
s_rock
=
(
opt
.
rock
==
'y'
?
1
:
0
);
s
->
u
.
isofs_sb
.
s_rock
=
(
opt
.
rock
==
'y'
?
1
:
0
);
s
->
u
.
isofs_sb
.
s_conversion
=
opt
.
conversion
;
s
->
u
.
isofs_sb
.
s_conversion
=
opt
.
conversion
;
s
->
u
.
isofs_sb
.
s_cruft
=
opt
.
cruft
;
s
->
u
.
isofs_sb
.
s_cruft
=
opt
.
cruft
;
s
->
u
.
isofs_sb
.
s_unhide
=
opt
.
unhide
;
s
->
u
.
isofs_sb
.
s_uid
=
opt
.
uid
;
s
->
u
.
isofs_sb
.
s_uid
=
opt
.
uid
;
s
->
u
.
isofs_sb
.
s_gid
=
opt
.
gid
;
s
->
u
.
isofs_sb
.
s_gid
=
opt
.
gid
;
/*
/*
...
...
fs/isofs/namei.c
View file @
5d278332
...
@@ -73,7 +73,6 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
...
@@ -73,7 +73,6 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
unsigned
int
old_offset
;
unsigned
int
old_offset
;
unsigned
int
backlink
;
unsigned
int
backlink
;
int
dlen
,
rrflag
,
match
;
int
dlen
,
rrflag
,
match
;
int
high_sierra
=
0
;
char
*
dpnt
;
char
*
dpnt
;
struct
iso_directory_record
*
de
;
struct
iso_directory_record
*
de
;
char
c
;
char
c
;
...
@@ -155,16 +154,6 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
...
@@ -155,16 +154,6 @@ static struct buffer_head * isofs_find_entry(struct inode * dir,
backlink
=
0
;
backlink
=
0
;
}
}
/* Do not report hidden or associated files */
high_sierra
=
dir
->
i_sb
->
u
.
isofs_sb
.
s_high_sierra
;
if
(
de
->
flags
[
-
high_sierra
]
&
5
)
{
if
(
cpnt
)
{
kfree
(
cpnt
);
cpnt
=
NULL
;
};
continue
;
}
dlen
=
de
->
name_len
[
0
];
dlen
=
de
->
name_len
[
0
];
dpnt
=
de
->
name
;
dpnt
=
de
->
name
;
/* Now convert the filename in the buffer to lower case */
/* Now convert the filename in the buffer to lower case */
...
...
fs/locks.c
View file @
5d278332
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Deadlock Detection added by Kelly Carmichael, kelly@[142.24.8.65]
* Deadlock Detection added by Kelly Carmichael, kelly@[142.24.8.65]
* September 17, 1994.
* September 17, 1994.
*
*
* FIXME: one thing isn't handled yet:
*
FIXME: one thing isn't handled yet:
* - mandatory locks (requires lots of changes elsewhere)
* - mandatory locks (requires lots of changes elsewhere)
*
*
* Edited by Kai Petzke, wpp@marie.physik.tu-berlin.de
* Edited by Kai Petzke, wpp@marie.physik.tu-berlin.de
...
@@ -22,7 +22,11 @@
...
@@ -22,7 +22,11 @@
* process. Since locks still depend on the process id, locks are inherited
* process. Since locks still depend on the process id, locks are inherited
* after an exec() but not after a fork(). This agrees with POSIX, and both
* after an exec() but not after a fork(). This agrees with POSIX, and both
* BSD and SVR4 practice.
* BSD and SVR4 practice.
* Andy Walker (andy@keo.kvaerner.no), February 14, 1994
* Andy Walker (andy@keo.kvaerner.no), February 14, 1995
*
* Scrapped free list which is redundant now that we allocate locks
* dynamically with kmalloc()/kfree().
* Andy Walker (andy@keo.kvaerner.no), February 21, 1995
*
*
*/
*/
...
@@ -45,16 +49,11 @@ static int overlap(struct file_lock *fl1, struct file_lock *fl2);
...
@@ -45,16 +49,11 @@ static int overlap(struct file_lock *fl1, struct file_lock *fl2);
static
int
lock_it
(
struct
file
*
filp
,
struct
file_lock
*
caller
);
static
int
lock_it
(
struct
file
*
filp
,
struct
file_lock
*
caller
);
static
struct
file_lock
*
alloc_lock
(
struct
file_lock
**
pos
,
struct
file_lock
*
fl
);
static
struct
file_lock
*
alloc_lock
(
struct
file_lock
**
pos
,
struct
file_lock
*
fl
);
static
void
free_lock
(
struct
file_lock
**
fl
);
static
void
free_lock
(
struct
file_lock
**
fl
);
static
void
free_list_garbage_collect
(
void
);
#ifdef DEADLOCK_DETECTION
#ifdef DEADLOCK_DETECTION
int
locks_deadlocked
(
int
my_pid
,
int
blocked_pid
);
int
locks_deadlocked
(
int
my_pid
,
int
blocked_pid
);
#endif
#endif
#define FREE_LIST_GARBAGE_COLLECT 20
static
struct
file_lock
*
file_lock_table
=
NULL
;
static
struct
file_lock
*
file_lock_table
=
NULL
;
static
struct
file_lock
*
file_lock_free_list
=
NULL
;
static
int
free_list_cnt
=
0
;
int
fcntl_getlk
(
unsigned
int
fd
,
struct
flock
*
l
)
int
fcntl_getlk
(
unsigned
int
fd
,
struct
flock
*
l
)
{
{
...
@@ -155,7 +154,8 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
...
@@ -155,7 +154,8 @@ int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
if
(
current
->
signal
&
~
current
->
blocked
)
if
(
current
->
signal
&
~
current
->
blocked
)
return
-
ERESTARTSYS
;
return
-
ERESTARTSYS
;
#ifdef DEADLOCK_DETECTION
#ifdef DEADLOCK_DETECTION
if
(
locks_deadlocked
(
file_lock
.
fl_owner
->
pid
,
fl
->
fl_owner
->
pid
))
return
-
EDEADLOCK
;
if
(
locks_deadlocked
(
file_lock
.
fl_owner
->
pid
,
fl
->
fl_owner
->
pid
))
return
-
EDEADLOCK
;
#endif
#endif
interruptible_sleep_on
(
&
fl
->
fl_wait
);
interruptible_sleep_on
(
&
fl
->
fl_wait
);
if
(
current
->
signal
&
~
current
->
blocked
)
if
(
current
->
signal
&
~
current
->
blocked
)
...
@@ -192,9 +192,11 @@ int locks_deadlocked(int my_pid,int blocked_pid)
...
@@ -192,9 +192,11 @@ int locks_deadlocked(int my_pid,int blocked_pid)
dlock_wait
=
fl
->
fl_wait
;
dlock_wait
=
fl
->
fl_wait
;
do
{
do
{
if
(
dlock_wait
->
task
!=
NULL
)
{
if
(
dlock_wait
->
task
!=
NULL
)
{
if
(
dlock_wait
->
task
->
pid
==
blocked_pid
)
return
-
EDEADLOCK
;
if
(
dlock_wait
->
task
->
pid
==
blocked_pid
)
return
-
EDEADLOCK
;
ret_val
=
locks_deadlocked
(
dlock_wait
->
task
->
pid
,
blocked_pid
);
ret_val
=
locks_deadlocked
(
dlock_wait
->
task
->
pid
,
blocked_pid
);
if
(
ret_val
)
return
-
EDEADLOCK
;
if
(
ret_val
)
return
-
EDEADLOCK
;
}
}
dlock_wait
=
dlock_wait
->
next
;
dlock_wait
=
dlock_wait
->
next
;
}
while
(
dlock_wait
!=
fl
->
fl_wait
);
}
while
(
dlock_wait
!=
fl
->
fl_wait
);
...
@@ -445,40 +447,26 @@ static int lock_it(struct file *filp, struct file_lock *caller)
...
@@ -445,40 +447,26 @@ static int lock_it(struct file *filp, struct file_lock *caller)
/*
/*
* File_lock() inserts a lock at the position pos of the linked list.
* File_lock() inserts a lock at the position pos of the linked list.
*
* Modified to create a new node if no free entries available - Chad Page
*
*/
*/
static
struct
file_lock
*
alloc_lock
(
struct
file_lock
**
pos
,
static
struct
file_lock
*
alloc_lock
(
struct
file_lock
**
pos
,
struct
file_lock
*
fl
)
struct
file_lock
*
fl
)
{
{
struct
file_lock
*
tmp
;
struct
file_lock
*
tmp
;
tmp
=
file_lock_free_list
;
/* Okay, let's make a new file_lock structure... */
tmp
=
(
struct
file_lock
*
)
kmalloc
(
sizeof
(
struct
file_lock
),
GFP_KERNEL
);
if
(
tmp
==
NULL
)
if
(
!
tmp
)
{
return
tmp
;
/* Okay, let's make a new file_lock structure... */
tmp
->
fl_nextlink
=
file_lock_table
;
tmp
=
(
struct
file_lock
*
)
kmalloc
(
sizeof
(
struct
file_lock
),
GFP_KERNEL
);
tmp
->
fl_prevlink
=
NULL
;
tmp
->
fl_owner
=
NULL
;
if
(
file_lock_table
!=
NULL
)
tmp
->
fl_next
=
file_lock_free_list
;
file_lock_table
->
fl_prevlink
=
tmp
;
tmp
->
fl_nextlink
=
file_lock_table
;
file_lock_table
=
tmp
;
file_lock_table
=
tmp
;
}
else
{
/* remove from free list */
file_lock_free_list
=
tmp
->
fl_next
;
free_list_cnt
--
;
}
if
(
tmp
->
fl_owner
!=
NULL
)
panic
(
"alloc_lock: broken free list
\n
"
);
tmp
->
fl_next
=
*
pos
;
/* insert into file's list */
tmp
->
fl_next
=
*
pos
;
/* insert into file's list */
*
pos
=
tmp
;
*
pos
=
tmp
;
tmp
->
fl_owner
=
current
;
/* FIXME: needed? */
tmp
->
fl_owner
=
current
;
tmp
->
fl_wait
=
NULL
;
tmp
->
fl_wait
=
NULL
;
tmp
->
fl_type
=
fl
->
fl_type
;
tmp
->
fl_type
=
fl
->
fl_type
;
...
@@ -490,7 +478,7 @@ static struct file_lock *alloc_lock(struct file_lock **pos,
...
@@ -490,7 +478,7 @@ static struct file_lock *alloc_lock(struct file_lock **pos,
}
}
/*
/*
*
Add a lock to the free list
...
*
Free up a lock
...
*/
*/
static
void
free_lock
(
struct
file_lock
**
fl_p
)
static
void
free_lock
(
struct
file_lock
**
fl_p
)
...
@@ -498,24 +486,19 @@ static void free_lock(struct file_lock **fl_p)
...
@@ -498,24 +486,19 @@ static void free_lock(struct file_lock **fl_p)
struct
file_lock
*
fl
;
struct
file_lock
*
fl
;
fl
=
*
fl_p
;
fl
=
*
fl_p
;
if
(
fl
->
fl_owner
==
NULL
)
/* sanity check */
panic
(
"free_lock: broken lock list
\n
"
);
*
fl_p
=
(
*
fl_p
)
->
fl_next
;
*
fl_p
=
(
*
fl_p
)
->
fl_next
;
fl
->
fl_next
=
file_lock_free_list
;
/* add to free list */
if
(
fl
->
fl_nextlink
!=
NULL
)
file_lock_free_list
=
fl
;
fl
->
fl_nextlink
->
fl_prevlink
=
fl
->
fl_prevlink
;
fl
->
fl_owner
=
NULL
;
/* for sanity checks */
free_list_cnt
++
;
if
(
fl
->
fl_prevlink
!=
NULL
)
if
(
free_list_cnt
==
FREE_LIST_GARBAGE_COLLECT
)
fl
->
fl_prevlink
->
fl_nextlink
=
fl
->
fl_nextlink
;
free_list_garbage_collect
();
else
file_lock_table
=
fl
->
fl_nextlink
;
wake_up
(
&
fl
->
fl_wait
);
wake_up
(
&
fl
->
fl_wait
);
}
static
void
free_list_garbage_collect
(
void
)
kfree
(
fl
);
{
/* Do nothing for now */
return
;
return
;
}
}
fs/proc/mem.c
View file @
5d278332
#define THREE_LEVEL
/*
/*
* linux/fs/proc/mem.c
* linux/fs/proc/mem.c
*
*
...
@@ -25,7 +26,8 @@
...
@@ -25,7 +26,8 @@
static
int
mem_read
(
struct
inode
*
inode
,
struct
file
*
file
,
char
*
buf
,
int
count
)
static
int
mem_read
(
struct
inode
*
inode
,
struct
file
*
file
,
char
*
buf
,
int
count
)
{
{
pgd_t
*
pgdir
;
pgd_t
*
page_dir
;
pmd_t
*
page_middle
;
pte_t
pte
;
pte_t
pte
;
char
*
page
;
char
*
page
;
struct
task_struct
*
tsk
;
struct
task_struct
*
tsk
;
...
@@ -50,15 +52,23 @@ static int mem_read(struct inode * inode, struct file * file,char * buf, int cou
...
@@ -50,15 +52,23 @@ static int mem_read(struct inode * inode, struct file * file,char * buf, int cou
while
(
count
>
0
)
{
while
(
count
>
0
)
{
if
(
current
->
signal
&
~
current
->
blocked
)
if
(
current
->
signal
&
~
current
->
blocked
)
break
;
break
;
p
gdir
=
PAGE_DIR_OFFSET
(
tsk
,
addr
);
p
age_dir
=
pgd_offset
(
tsk
,
addr
);
if
(
pgd_none
(
*
p
g
dir
))
if
(
pgd_none
(
*
p
age_
dir
))
break
;
break
;
if
(
pgd_bad
(
*
p
g
dir
))
{
if
(
pgd_bad
(
*
p
age_
dir
))
{
printk
(
"Bad page dir entry %08lx
\n
"
,
pgd_val
(
*
p
g
dir
));
printk
(
"Bad page dir entry %08lx
\n
"
,
pgd_val
(
*
p
age_
dir
));
pgd_clear
(
p
g
dir
);
pgd_clear
(
p
age_
dir
);
break
;
break
;
}
}
pte
=
*
(
pte_t
*
)
(
PAGE_PTR
(
addr
)
+
pgd_page
(
*
pgdir
));
page_middle
=
pmd_offset
(
page_dir
,
addr
);
if
(
pmd_none
(
*
page_middle
))
break
;
if
(
pmd_bad
(
*
page_middle
))
{
printk
(
"Bad page middle entry %08lx
\n
"
,
pmd_val
(
*
page_middle
));
pmd_clear
(
page_middle
);
break
;
}
pte
=
*
pte_offset
(
page_middle
,
addr
);
if
(
!
pte_present
(
pte
))
if
(
!
pte_present
(
pte
))
break
;
break
;
page
=
(
char
*
)
pte_page
(
pte
)
+
(
addr
&
~
PAGE_MASK
);
page
=
(
char
*
)
pte_page
(
pte
)
+
(
addr
&
~
PAGE_MASK
);
...
@@ -78,8 +88,9 @@ static int mem_read(struct inode * inode, struct file * file,char * buf, int cou
...
@@ -78,8 +88,9 @@ static int mem_read(struct inode * inode, struct file * file,char * buf, int cou
static
int
mem_write
(
struct
inode
*
inode
,
struct
file
*
file
,
char
*
buf
,
int
count
)
static
int
mem_write
(
struct
inode
*
inode
,
struct
file
*
file
,
char
*
buf
,
int
count
)
{
{
pgd_t
*
pgdir
;
pgd_t
*
page_dir
;
pte_t
*
pte
;
pmd_t
*
page_middle
;
pte_t
pte
;
char
*
page
;
char
*
page
;
struct
task_struct
*
tsk
;
struct
task_struct
*
tsk
;
unsigned
long
addr
,
pid
;
unsigned
long
addr
,
pid
;
...
@@ -103,15 +114,23 @@ static int mem_write(struct inode * inode, struct file * file,char * buf, int co
...
@@ -103,15 +114,23 @@ static int mem_write(struct inode * inode, struct file * file,char * buf, int co
while
(
count
>
0
)
{
while
(
count
>
0
)
{
if
(
current
->
signal
&
~
current
->
blocked
)
if
(
current
->
signal
&
~
current
->
blocked
)
break
;
break
;
p
gdir
=
PAGE_DIR_OFFSET
(
tsk
,
addr
);
p
age_dir
=
pgd_offset
(
tsk
,
addr
);
if
(
pgd_none
(
*
p
g
dir
))
if
(
pgd_none
(
*
p
age_
dir
))
break
;
break
;
if
(
pgd_bad
(
*
p
g
dir
))
{
if
(
pgd_bad
(
*
p
age_
dir
))
{
printk
(
"Bad page dir entry %08lx
\n
"
,
pgd_val
(
*
p
g
dir
));
printk
(
"Bad page dir entry %08lx
\n
"
,
pgd_val
(
*
p
age_
dir
));
pgd_clear
(
p
g
dir
);
pgd_clear
(
p
age_
dir
);
break
;
break
;
}
}
pte
=
*
(
pte_t
*
)
(
PAGE_PTR
(
addr
)
+
pgd_page
(
*
pgdir
));
page_middle
=
pmd_offset
(
page_dir
,
addr
);
if
(
pmd_none
(
*
page_middle
))
break
;
if
(
pmd_bad
(
*
page_middle
))
{
printk
(
"Bad page middle entry %08lx
\n
"
,
pmd_val
(
*
page_middle
));
pmd_clear
(
page_middle
);
break
;
}
pte
=
*
pte_offset
(
page_middle
,
addr
);
if
(
!
pte_present
(
pte
))
if
(
!
pte_present
(
pte
))
break
;
break
;
if
(
!
pte_write
(
pte
))
if
(
!
pte_write
(
pte
))
...
@@ -157,6 +176,7 @@ int mem_mmap(struct inode * inode, struct file * file,
...
@@ -157,6 +176,7 @@ int mem_mmap(struct inode * inode, struct file * file,
{
{
struct
task_struct
*
tsk
;
struct
task_struct
*
tsk
;
pgd_t
*
src_dir
,
*
dest_dir
;
pgd_t
*
src_dir
,
*
dest_dir
;
pmd_t
*
src_middle
,
*
dest_middle
;
pte_t
*
src_table
,
*
dest_table
;
pte_t
*
src_table
,
*
dest_table
;
unsigned
long
stmp
,
dtmp
;
unsigned
long
stmp
,
dtmp
;
struct
vm_area_struct
*
src_vma
=
NULL
;
struct
vm_area_struct
*
src_vma
=
NULL
;
...
@@ -168,7 +188,6 @@ int mem_mmap(struct inode * inode, struct file * file,
...
@@ -168,7 +188,6 @@ int mem_mmap(struct inode * inode, struct file * file,
for
(
i
=
1
;
i
<
NR_TASKS
;
i
++
)
for
(
i
=
1
;
i
<
NR_TASKS
;
i
++
)
if
(
task
[
i
]
&&
task
[
i
]
->
pid
==
(
inode
->
i_ino
>>
16
))
{
if
(
task
[
i
]
&&
task
[
i
]
->
pid
==
(
inode
->
i_ino
>>
16
))
{
tsk
=
task
[
i
];
tsk
=
task
[
i
];
src_vma
=
task
[
i
]
->
mm
->
mmap
;
break
;
break
;
}
}
...
@@ -180,6 +199,7 @@ int mem_mmap(struct inode * inode, struct file * file,
...
@@ -180,6 +199,7 @@ int mem_mmap(struct inode * inode, struct file * file,
moment because working out the vm_area_struct & nattach stuff isn't
moment because working out the vm_area_struct & nattach stuff isn't
worth it. */
worth it. */
src_vma
=
tsk
->
mm
->
mmap
;
stmp
=
vma
->
vm_offset
;
stmp
=
vma
->
vm_offset
;
while
(
stmp
<
vma
->
vm_offset
+
(
vma
->
vm_end
-
vma
->
vm_start
))
{
while
(
stmp
<
vma
->
vm_offset
+
(
vma
->
vm_end
-
vma
->
vm_start
))
{
while
(
src_vma
&&
stmp
>
src_vma
->
vm_end
)
while
(
src_vma
&&
stmp
>
src_vma
->
vm_end
)
...
@@ -187,15 +207,21 @@ int mem_mmap(struct inode * inode, struct file * file,
...
@@ -187,15 +207,21 @@ int mem_mmap(struct inode * inode, struct file * file,
if
(
!
src_vma
||
(
src_vma
->
vm_flags
&
VM_SHM
))
if
(
!
src_vma
||
(
src_vma
->
vm_flags
&
VM_SHM
))
return
-
EINVAL
;
return
-
EINVAL
;
src_dir
=
PAGE_DIR_OFFSET
(
tsk
,
stmp
);
src_dir
=
pgd_offset
(
tsk
,
stmp
);
if
(
pgd_none
(
*
src_dir
))
if
(
pgd_none
(
*
src_dir
))
return
-
EINVAL
;
return
-
EINVAL
;
if
(
pgd_bad
(
*
src_dir
))
{
if
(
pgd_bad
(
*
src_dir
))
{
printk
(
"Bad source page dir entry %08lx
\n
"
,
pgd_val
(
*
src_dir
));
printk
(
"Bad source page dir entry %08lx
\n
"
,
pgd_val
(
*
src_dir
));
return
-
EINVAL
;
return
-
EINVAL
;
}
}
src_middle
=
pmd_offset
(
src_dir
,
stmp
);
src_table
=
(
pte_t
*
)(
pgd_page
(
*
src_dir
)
+
PAGE_PTR
(
stmp
));
if
(
pmd_none
(
*
src_middle
))
return
-
EINVAL
;
if
(
pmd_bad
(
*
src_middle
))
{
printk
(
"Bad source page middle entry %08lx
\n
"
,
pmd_val
(
*
src_middle
));
return
-
EINVAL
;
}
src_table
=
pte_offset
(
src_middle
,
stmp
);
if
(
pte_none
(
*
src_table
))
if
(
pte_none
(
*
src_table
))
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -208,7 +234,7 @@ int mem_mmap(struct inode * inode, struct file * file,
...
@@ -208,7 +234,7 @@ int mem_mmap(struct inode * inode, struct file * file,
stmp
+=
PAGE_SIZE
;
stmp
+=
PAGE_SIZE
;
}
}
src_vma
=
t
ask
[
i
]
->
mm
->
mmap
;
src_vma
=
t
sk
->
mm
->
mmap
;
stmp
=
vma
->
vm_offset
;
stmp
=
vma
->
vm_offset
;
dtmp
=
vma
->
vm_start
;
dtmp
=
vma
->
vm_start
;
...
@@ -216,28 +242,17 @@ int mem_mmap(struct inode * inode, struct file * file,
...
@@ -216,28 +242,17 @@ int mem_mmap(struct inode * inode, struct file * file,
while
(
src_vma
&&
stmp
>
src_vma
->
vm_end
)
while
(
src_vma
&&
stmp
>
src_vma
->
vm_end
)
src_vma
=
src_vma
->
vm_next
;
src_vma
=
src_vma
->
vm_next
;
src_dir
=
PAGE_DIR_OFFSET
(
tsk
,
stmp
);
src_dir
=
pgd_offset
(
tsk
,
stmp
);
src_table
=
(
pte_t
*
)
(
pgd_page
(
*
src_dir
)
+
PAGE_PTR
(
stmp
));
src_middle
=
pmd_offset
(
src_dir
,
stmp
);
src_table
=
pte_offset
(
src_middle
,
stmp
);
dest_dir
=
PAGE_DIR_OFFSET
(
current
,
dtmp
);
dest_dir
=
pgd_offset
(
current
,
dtmp
);
if
(
pgd_none
(
*
dest_dir
))
{
dest_middle
=
pmd_alloc
(
dest_dir
,
dtmp
);
unsigned
long
page
=
get_free_page
(
GFP_KERNEL
);
if
(
!
dest_middle
)
if
(
!
page
)
return
-
ENOMEM
;
return
-
ENOMEM
;
dest_table
=
pte_alloc
(
dest_middle
,
dtmp
);
if
(
pgd_none
(
*
dest_dir
))
{
if
(
!
dest_table
)
pgd_set
(
dest_dir
,
(
pte_t
*
)
page
);
return
-
ENOMEM
;
}
else
{
free_page
(
page
);
}
}
if
(
pgd_bad
(
*
dest_dir
))
{
printk
(
"Bad dest directory entry %08lx
\n
"
,
pgd_val
(
*
dest_dir
));
return
-
EINVAL
;
}
dest_table
=
(
pte_t
*
)
(
pgd_page
(
*
dest_dir
)
+
PAGE_PTR
(
dtmp
));
if
(
!
pte_present
(
*
src_table
))
if
(
!
pte_present
(
*
src_table
))
do_no_page
(
src_vma
,
stmp
,
1
);
do_no_page
(
src_vma
,
stmp
,
1
);
...
...
include/asm-alpha/byteorder.h
View file @
5d278332
...
@@ -32,14 +32,11 @@ __ntohl(unsigned long int x)
...
@@ -32,14 +32,11 @@ __ntohl(unsigned long int x)
((
x
&
0xff000000U
)
>>
24
));
((
x
&
0xff000000U
)
>>
24
));
}
}
extern
__inline__
unsigned
long
int
#define __constant_ntohl(x) \
__constant_ntohl
(
unsigned
long
int
x
)
((unsigned int)((((unsigned int)(x) & 0x000000ffU) << 24) | \
{
(((unsigned int)(x) & 0x0000ff00U) << 8) | \
return
(((
x
&
0x000000ffU
)
<<
24
)
|
(((unsigned int)(x) & 0x00ff0000U) >> 8) | \
((
x
&
0x0000ff00U
)
<<
8
)
|
(((unsigned int)(x) & 0xff000000U) >> 24)))
((
x
&
0x00ff0000U
)
>>
8
)
|
((
x
&
0xff000000U
)
>>
24
));
}
extern
__inline__
unsigned
short
int
extern
__inline__
unsigned
short
int
__ntohs
(
unsigned
short
int
x
)
__ntohs
(
unsigned
short
int
x
)
...
@@ -48,12 +45,9 @@ __ntohs(unsigned short int x)
...
@@ -48,12 +45,9 @@ __ntohs(unsigned short int x)
((
x
&
0xff00
)
>>
8
));
((
x
&
0xff00
)
>>
8
));
}
}
extern
__inline__
unsigned
short
int
#define __constant_ntohs(x) \
__constant_ntohs
(
unsigned
short
int
x
)
((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
{
(((unsigned short int)(x) & 0xff00) >> 8)))
return
(((
x
&
0x00ff
)
<<
8
)
|
((
x
&
0xff00
)
>>
8
));
}
#define __htonl(x) __ntohl(x)
#define __htonl(x) __ntohl(x)
#define __htons(x) __ntohs(x)
#define __htons(x) __ntohs(x)
...
...
include/asm-alpha/pgtable.h
View file @
5d278332
...
@@ -160,18 +160,33 @@ extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
...
@@ -160,18 +160,33 @@ extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
extern
inline
int
pte_present
(
pte_t
pte
)
{
return
pte_val
(
pte
)
&
_PAGE_VALID
;
}
extern
inline
int
pte_present
(
pte_t
pte
)
{
return
pte_val
(
pte
)
&
_PAGE_VALID
;
}
extern
inline
int
pte_inuse
(
pte_t
*
ptep
)
{
return
mem_map
[
MAP_NR
(
ptep
)]
>
1
;
}
extern
inline
int
pte_inuse
(
pte_t
*
ptep
)
{
return
mem_map
[
MAP_NR
(
ptep
)]
>
1
;
}
extern
inline
void
pte_clear
(
pte_t
*
ptep
)
{
pte_val
(
*
ptep
)
=
0
;
}
extern
inline
void
pte_clear
(
pte_t
*
ptep
)
{
pte_val
(
*
ptep
)
=
0
;
}
extern
inline
void
pte_reuse
(
pte_t
*
ptep
)
{
if
(
!
(
mem_map
[
MAP_NR
(
ptep
)]
&
MAP_PAGE_RESERVED
))
mem_map
[
MAP_NR
(
ptep
)]
++
;
}
extern
inline
int
pmd_none
(
pmd_t
pmd
)
{
return
!
pmd_val
(
pmd
);
}
extern
inline
int
pmd_none
(
pmd_t
pmd
)
{
return
!
pmd_val
(
pmd
);
}
extern
inline
int
pmd_bad
(
pmd_t
pmd
)
{
return
(
pmd_val
(
pmd
)
&
~
_PFN_MASK
)
!=
_PAGE_TABLE
||
pmd_page
(
pmd
)
>
high_memory
;
}
extern
inline
int
pmd_bad
(
pmd_t
pmd
)
{
return
(
pmd_val
(
pmd
)
&
~
_PFN_MASK
)
!=
_PAGE_TABLE
||
pmd_page
(
pmd
)
>
high_memory
;
}
extern
inline
int
pmd_present
(
pmd_t
pmd
)
{
return
pmd_val
(
pmd
)
&
_PAGE_VALID
;
}
extern
inline
int
pmd_present
(
pmd_t
pmd
)
{
return
pmd_val
(
pmd
)
&
_PAGE_VALID
;
}
extern
inline
int
pmd_inuse
(
pmd_t
*
pmdp
)
{
return
mem_map
[
MAP_NR
(
pmdp
)]
>
1
;
}
extern
inline
int
pmd_inuse
(
pmd_t
*
pmdp
)
{
return
mem_map
[
MAP_NR
(
pmdp
)]
>
1
;
}
extern
inline
void
pmd_clear
(
pmd_t
*
pmdp
)
{
pmd_val
(
*
pmdp
)
=
0
;
}
extern
inline
void
pmd_clear
(
pmd_t
*
pmdp
)
{
pmd_val
(
*
pmdp
)
=
0
;
}
extern
inline
void
pmd_reuse
(
pmd_t
*
pmdp
)
{
if
(
!
(
mem_map
[
MAP_NR
(
pmdp
)]
&
MAP_PAGE_RESERVED
))
mem_map
[
MAP_NR
(
pmdp
)]
++
;
}
extern
inline
int
pgd_none
(
pgd_t
pgd
)
{
return
!
pgd_val
(
pgd
);
}
extern
inline
int
pgd_none
(
pgd_t
pgd
)
{
return
!
pgd_val
(
pgd
);
}
extern
inline
int
pgd_bad
(
pgd_t
pgd
)
{
return
(
pgd_val
(
pgd
)
&
~
_PFN_MASK
)
!=
_PAGE_TABLE
||
pgd_page
(
pgd
)
>
high_memory
;
}
extern
inline
int
pgd_bad
(
pgd_t
pgd
)
{
return
(
pgd_val
(
pgd
)
&
~
_PFN_MASK
)
!=
_PAGE_TABLE
||
pgd_page
(
pgd
)
>
high_memory
;
}
extern
inline
int
pgd_present
(
pgd_t
pgd
)
{
return
pgd_val
(
pgd
)
&
_PAGE_VALID
;
}
extern
inline
int
pgd_present
(
pgd_t
pgd
)
{
return
pgd_val
(
pgd
)
&
_PAGE_VALID
;
}
extern
inline
int
pgd_inuse
(
pgd_t
*
pgdp
)
{
return
mem_map
[
MAP_NR
(
pgdp
)]
>
1
;
}
extern
inline
int
pgd_inuse
(
pgd_t
*
pgdp
)
{
return
mem_map
[
MAP_NR
(
pgdp
)]
>
1
;
}
extern
inline
void
pgd_clear
(
pgd_t
*
pgdp
)
{
pgd_val
(
*
pgdp
)
=
0
;
}
extern
inline
void
pgd_clear
(
pgd_t
*
pgdp
)
{
pgd_val
(
*
pgdp
)
=
0
;
}
extern
inline
void
pgd_reuse
(
pgd_t
*
pgdp
)
{
if
(
!
(
mem_map
[
MAP_NR
(
pgdp
)]
&
MAP_PAGE_RESERVED
))
mem_map
[
MAP_NR
(
pgdp
)]
++
;
}
/*
/*
* The following only work if pte_present() is true.
* The following only work if pte_present() is true.
...
...
include/asm-i386/byteorder.h
View file @
5d278332
...
@@ -27,14 +27,11 @@ __ntohl(unsigned long int x)
...
@@ -27,14 +27,11 @@ __ntohl(unsigned long int x)
return
x
;
return
x
;
}
}
extern
__inline__
unsigned
long
int
#define __constant_ntohl(x) \
__constant_ntohl
(
unsigned
long
int
x
)
((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
{
(((unsigned long int)(x) & 0x0000ff00U) << 8) | \
return
(((
x
&
0x000000ffU
)
<<
24
)
|
(((unsigned long int)(x) & 0x00ff0000U) >> 8) | \
((
x
&
0x0000ff00U
)
<<
8
)
|
(((unsigned long int)(x) & 0xff000000U) >> 24)))
((
x
&
0x00ff0000U
)
>>
8
)
|
((
x
&
0xff000000U
)
>>
24
));
}
extern
__inline__
unsigned
short
int
extern
__inline__
unsigned
short
int
__ntohs
(
unsigned
short
int
x
)
__ntohs
(
unsigned
short
int
x
)
...
@@ -45,12 +42,9 @@ __ntohs(unsigned short int x)
...
@@ -45,12 +42,9 @@ __ntohs(unsigned short int x)
return
x
;
return
x
;
}
}
extern
__inline__
unsigned
short
int
#define __constant_ntohs(x) \
__constant_ntohs
(
unsigned
short
int
x
)
((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
{
(((unsigned short int)(x) & 0xff00) >> 8))) \
return
(((
x
&
0x00ff
)
<<
8
)
|
((
x
&
0xff00
)
>>
8
));
}
#define __htonl(x) __ntohl(x)
#define __htonl(x) __ntohl(x)
#define __htons(x) __ntohs(x)
#define __htons(x) __ntohs(x)
...
...
include/asm-sparc/system.h
View file @
5d278332
#ifndef __SPARC_SYSTEM_H
#ifndef __SPARC_SYSTEM_H
#define __SPARC_SYSTEM_H
#define __SPARC_SYSTEM_H
#include <asm/segment.h>
/*
/*
* System defines.. Note that this is included both from .c and .S
* System defines.. Note that this is included both from .c and .S
* files, so it does only defines, not any C code.
* files, so it does only defines, not any C code.
...
...
include/asm-sparc/vac-ops.h
View file @
5d278332
...
@@ -7,8 +7,8 @@
...
@@ -7,8 +7,8 @@
Copyright (C) 1994, David S. Miller (davem@caip.rutgers.edu)
Copyright (C) 1994, David S. Miller (davem@caip.rutgers.edu)
*/
*/
extern
unsigned
int
trapbase
[]
;
extern
unsigned
long
*
trapbase
;
extern
unsigned
int
end
[],
etext
[],
msgbuf
[]
;
extern
char
end
,
etext
,
msgbuf
;
extern
void
flush_vac_context
(
void
);
extern
void
flush_vac_context
(
void
);
extern
void
flush_vac_segment
(
unsigned
int
foo_segment
);
extern
void
flush_vac_segment
(
unsigned
int
foo_segment
);
...
...
include/linux/fs.h
View file @
5d278332
...
@@ -266,8 +266,9 @@ struct file {
...
@@ -266,8 +266,9 @@ struct file {
};
};
struct
file_lock
{
struct
file_lock
{
struct
file_lock
*
fl_next
;
/* singly linked list */
struct
file_lock
*
fl_next
;
/* singly linked list for this inode (or the free list) */
struct
file_lock
*
fl_nextlink
;
struct
file_lock
*
fl_nextlink
;
/* doubly linked list of all locks */
struct
file_lock
*
fl_prevlink
;
/* used to simplify garbage collecting */
struct
task_struct
*
fl_owner
;
/* NULL if on free list, for sanity checks */
struct
task_struct
*
fl_owner
;
/* NULL if on free list, for sanity checks */
struct
wait_queue
*
fl_wait
;
struct
wait_queue
*
fl_wait
;
char
fl_type
;
char
fl_type
;
...
...
include/linux/iso_fs_sb.h
View file @
5d278332
...
@@ -18,6 +18,7 @@ struct isofs_sb_info {
...
@@ -18,6 +18,7 @@ struct isofs_sb_info {
unsigned
char
s_cruft
;
/* Broken disks with high
unsigned
char
s_cruft
;
/* Broken disks with high
byte of length containing
byte of length containing
junk */
junk */
unsigned
char
s_unhide
;
unsigned
char
s_nosuid
;
unsigned
char
s_nosuid
;
unsigned
char
s_nodev
;
unsigned
char
s_nodev
;
mode_t
s_mode
;
mode_t
s_mode
;
...
...
include/linux/sched.h
View file @
5d278332
...
@@ -268,11 +268,12 @@ extern int request_irq(unsigned int irq,void (*handler)(int, struct pt_regs *),
...
@@ -268,11 +268,12 @@ extern int request_irq(unsigned int irq,void (*handler)(int, struct pt_regs *),
unsigned
long
flags
,
const
char
*
device
);
unsigned
long
flags
,
const
char
*
device
);
extern
void
free_irq
(
unsigned
int
irq
);
extern
void
free_irq
(
unsigned
int
irq
);
extern
unsigned
long
copy_thread
(
int
,
unsigned
long
,
struct
task_struct
*
,
struct
pt_regs
*
);
extern
void
copy_thread
(
int
,
unsigned
long
,
unsigned
long
,
struct
task_struct
*
,
struct
pt_regs
*
);
extern
void
flush_thread
(
void
);
extern
void
flush_thread
(
void
);
extern
void
exit_thread
(
void
);
extern
void
exit_thread
(
void
);
extern
int
do_execve
(
char
*
,
char
**
,
char
**
,
struct
pt_regs
*
);
extern
int
do_execve
(
char
*
,
char
**
,
char
**
,
struct
pt_regs
*
);
extern
int
do_fork
(
unsigned
long
,
unsigned
long
,
struct
pt_regs
*
);
asmlinkage
int
do_signal
(
unsigned
long
,
struct
pt_regs
*
);
asmlinkage
int
do_signal
(
unsigned
long
,
struct
pt_regs
*
);
/*
/*
...
...
include/linux/serial.h
View file @
5d278332
...
@@ -22,9 +22,18 @@ struct serial_struct {
...
@@ -22,9 +22,18 @@ struct serial_struct {
unsigned
short
close_delay
;
unsigned
short
close_delay
;
char
reserved_char
[
2
];
char
reserved_char
[
2
];
int
hub6
;
int
hub6
;
int
reserved
[
5
];
unsigned
short
closing_wait
;
/* time to wait before closing */
unsigned
short
closing_wait2
;
/* no longer used... */
int
reserved
[
4
];
};
};
/*
* For the close wait times, 0 means wait forever for serial port to
* flush its output. 65535 means don't wait at all.
*/
#define ASYNC_CLOSING_WAIT_INF 0
#define ASYNC_CLOSING_WAIT_NONE 65535
/*
/*
* These are the supported serial types.
* These are the supported serial types.
*/
*/
...
@@ -34,7 +43,8 @@ struct serial_struct {
...
@@ -34,7 +43,8 @@ struct serial_struct {
#define PORT_16550 3
#define PORT_16550 3
#define PORT_16550A 4
#define PORT_16550A 4
#define PORT_CIRRUS 5
#define PORT_CIRRUS 5
#define PORT_MAX 5
#define PORT_16650 6
#define PORT_MAX 6
/*
/*
* Definitions for async_struct (and serial_struct) flags field
* Definitions for async_struct (and serial_struct) flags field
...
@@ -70,6 +80,23 @@ struct serial_struct {
...
@@ -70,6 +80,23 @@ struct serial_struct {
#define ASYNC_CTS_FLOW 0x04000000
/* Do CTS flow control */
#define ASYNC_CTS_FLOW 0x04000000
/* Do CTS flow control */
#define ASYNC_CHECK_CD 0x02000000
/* i.e., CLOCAL */
#define ASYNC_CHECK_CD 0x02000000
/* i.e., CLOCAL */
/*
* Multiport serial configuration structure --- external structure
*/
struct
serial_multiport_struct
{
int
irq
;
int
port1
;
unsigned
char
mask1
,
match1
;
int
port2
;
unsigned
char
mask2
,
match2
;
int
port3
;
unsigned
char
mask3
,
match3
;
int
port4
;
unsigned
char
mask4
,
match4
;
int
port_monitor
;
int
reserved
[
32
];
};
#ifdef __KERNEL__
#ifdef __KERNEL__
/*
/*
* This is our internal structure for each serial port's state.
* This is our internal structure for each serial port's state.
...
@@ -96,6 +123,8 @@ struct async_struct {
...
@@ -96,6 +123,8 @@ struct async_struct {
int
custom_divisor
;
int
custom_divisor
;
int
x_char
;
/* xon/xoff character */
int
x_char
;
/* xon/xoff character */
int
close_delay
;
int
close_delay
;
unsigned
short
closing_wait
;
unsigned
short
closing_wait2
;
int
IER
;
/* Interrupt Enable Register */
int
IER
;
/* Interrupt Enable Register */
int
MCR
;
/* Modem control register */
int
MCR
;
/* Modem control register */
int
MCR_noint
;
/* MCR with interrupts off */
int
MCR_noint
;
/* MCR with interrupts off */
...
@@ -133,6 +162,21 @@ struct async_struct {
...
@@ -133,6 +162,21 @@ struct async_struct {
#define RS_EVENT_WRITE_WAKEUP 0
#define RS_EVENT_WRITE_WAKEUP 0
#define RS_EVENT_HANGUP 1
#define RS_EVENT_HANGUP 1
/*
* Multiport serial configuration structure --- internal structure
*/
struct
rs_multiport_struct
{
int
port1
;
unsigned
char
mask1
,
match1
;
int
port2
;
unsigned
char
mask2
,
match2
;
int
port3
;
unsigned
char
mask3
,
match3
;
int
port4
;
unsigned
char
mask4
,
match4
;
int
port_monitor
;
};
/* Export to allow PCMCIA to use this - Dave Hinds */
/* Export to allow PCMCIA to use this - Dave Hinds */
extern
int
register_serial
(
struct
serial_struct
*
req
);
extern
int
register_serial
(
struct
serial_struct
*
req
);
extern
void
unregister_serial
(
int
line
);
extern
void
unregister_serial
(
int
line
);
...
...
include/linux/serial_reg.h
View file @
5d278332
...
@@ -21,6 +21,8 @@
...
@@ -21,6 +21,8 @@
#define UART_IER 1
/* Out: Interrupt Enable Register */
#define UART_IER 1
/* Out: Interrupt Enable Register */
#define UART_IIR 2
/* In: Interrupt ID Register */
#define UART_IIR 2
/* In: Interrupt ID Register */
#define UART_FCR 2
/* Out: FIFO Control Register */
#define UART_FCR 2
/* Out: FIFO Control Register */
#define UART_EFR 2
/* I/O: Extended Features Register */
/* (DLAB=1, 16C660 only) */
#define UART_LCR 3
/* Out: Line Control Register */
#define UART_LCR 3
/* Out: Line Control Register */
#define UART_MCR 4
/* Out: Modem Control Register */
#define UART_MCR 4
/* Out: Modem Control Register */
#define UART_LSR 5
/* In: Line Status Register */
#define UART_LSR 5
/* In: Line Status Register */
...
@@ -29,6 +31,7 @@
...
@@ -29,6 +31,7 @@
/*
/*
* These are the definitions for the FIFO Control Register
* These are the definitions for the FIFO Control Register
* (16650 only)
*/
*/
#define UART_FCR_ENABLE_FIFO 0x01
/* Enable the FIFO */
#define UART_FCR_ENABLE_FIFO 0x01
/* Enable the FIFO */
#define UART_FCR_CLEAR_RCVR 0x02
/* Clear the RCVR FIFO */
#define UART_FCR_CLEAR_RCVR 0x02
/* Clear the RCVR FIFO */
...
@@ -39,6 +42,15 @@
...
@@ -39,6 +42,15 @@
#define UART_FCR_TRIGGER_4 0x40
/* Mask for trigger set at 4 */
#define UART_FCR_TRIGGER_4 0x40
/* Mask for trigger set at 4 */
#define UART_FCR_TRIGGER_8 0x80
/* Mask for trigger set at 8 */
#define UART_FCR_TRIGGER_8 0x80
/* Mask for trigger set at 8 */
#define UART_FCR_TRIGGER_14 0xC0
/* Mask for trigger set at 14 */
#define UART_FCR_TRIGGER_14 0xC0
/* Mask for trigger set at 14 */
/* 16650 redefinitions */
#define UART_FCR6_R_TRIGGER_8 0x00
/* Mask for receive trigger set at 1 */
#define UART_FCR6_R_TRIGGER_16 0x40
/* Mask for receive trigger set at 4 */
#define UART_FCR6_R_TRIGGER_24 0x80
/* Mask for receive trigger set at 8 */
#define UART_FCR6_R_TRIGGER_28 0xC0
/* Mask for receive trigger set at 14 */
#define UART_FCR6_T_TRIGGER_16 0x00
/* Mask for transmit trigger set at 16 */
#define UART_FCR6_T_TRIGGER_8 0x10
/* Mask for transmit trigger set at 8 */
#define UART_FCR6_T_TRIGGER_24 0x20
/* Mask for transmit trigger set at 24 */
#define UART_FCR6_T_TRIGGER_30 0x30
/* Mask for transmit trigger set at 30 */
/*
/*
* These are the definitions for the Line Control Register
* These are the definitions for the Line Control Register
...
@@ -109,5 +121,17 @@
...
@@ -109,5 +121,17 @@
#define UART_MSR_DCTS 0x01
/* Delta CTS */
#define UART_MSR_DCTS 0x01
/* Delta CTS */
#define UART_MSR_ANY_DELTA 0x0F
/* Any of the delta bits! */
#define UART_MSR_ANY_DELTA 0x0F
/* Any of the delta bits! */
/*
* These are the definitions for the Extended Features Register
* (StarTech 16C660 only, when DLAB=1)
*/
#define UART_EFR_CTS 0x80
/* CTS flow control */
#define UART_EFR_RTS 0x40
/* RTS flow control */
#define UART_EFR_SCD 0x20
/* Special character detect */
#define UART_EFR_ENI 0x10
/* Enhanced Interrupt */
/*
* the low four bits control software flow control
*/
#endif
/* _LINUX_SERIAL_REG_H */
#endif
/* _LINUX_SERIAL_REG_H */
include/linux/sys.h
View file @
5d278332
...
@@ -6,11 +6,6 @@
...
@@ -6,11 +6,6 @@
*/
*/
#define NR_syscalls 256
#define NR_syscalls 256
/*
* These are system calls with the same entry-point
*/
#define _sys_clone _sys_fork
/*
/*
* These are system calls that will be removed at some time
* These are system calls that will be removed at some time
* due to newer versions existing..
* due to newer versions existing..
...
...
include/linux/termios.h
View file @
5d278332
...
@@ -54,6 +54,8 @@
...
@@ -54,6 +54,8 @@
#define TIOCSLCKTRMIOS 0x5457
#define TIOCSLCKTRMIOS 0x5457
#define TIOCSERGSTRUCT 0x5458
/* For debugging only */
#define TIOCSERGSTRUCT 0x5458
/* For debugging only */
#define TIOCSERGETLSR 0x5459
/* Get line status register */
#define TIOCSERGETLSR 0x5459
/* Get line status register */
#define TIOCSERGETMULTI 0x545A
/* Get multiport config */
#define TIOCSERSETMULTI 0x545B
/* Set multiport config */
/* Used for packet mode */
/* Used for packet mode */
#define TIOCPKT_DATA 0
#define TIOCPKT_DATA 0
...
@@ -193,6 +195,7 @@ struct termios {
...
@@ -193,6 +195,7 @@ struct termios {
#define CBAUDEX 0010000
#define CBAUDEX 0010000
#define B57600 0010001
#define B57600 0010001
#define B115200 0010002
#define B115200 0010002
#define B230400 0010003
#define CIBAUD 002003600000
/* input baud rate (not used) */
#define CIBAUD 002003600000
/* input baud rate (not used) */
#define CRTSCTS 020000000000
/* flow control */
#define CRTSCTS 020000000000
/* flow control */
...
...
include/linux/tty.h
View file @
5d278332
...
@@ -222,6 +222,7 @@ struct tty_struct {
...
@@ -222,6 +222,7 @@ struct tty_struct {
*/
*/
unsigned
int
column
;
unsigned
int
column
;
unsigned
char
lnext
:
1
,
erasing
:
1
,
raw
:
1
,
real_raw
:
1
,
icanon
:
1
;
unsigned
char
lnext
:
1
,
erasing
:
1
,
raw
:
1
,
real_raw
:
1
,
icanon
:
1
;
unsigned
char
closing
:
1
;
unsigned
short
minimum_to_wake
;
unsigned
short
minimum_to_wake
;
unsigned
overrun_time
;
unsigned
overrun_time
;
int
num_overrun
;
int
num_overrun
;
...
...
ipc/shm.c
View file @
5d278332
#define THREE_LEVEL
/*
/*
* linux/ipc/shm.c
* linux/ipc/shm.c
* Copyright (C) 1992, 1993 Krishna Balasubramanian
* Copyright (C) 1992, 1993 Krishna Balasubramanian
...
@@ -20,7 +21,7 @@ extern int ipcperms (struct ipc_perm *ipcp, short shmflg);
...
@@ -20,7 +21,7 @@ extern int ipcperms (struct ipc_perm *ipcp, short shmflg);
extern
unsigned
int
get_swap_page
(
void
);
extern
unsigned
int
get_swap_page
(
void
);
static
int
findkey
(
key_t
key
);
static
int
findkey
(
key_t
key
);
static
int
newseg
(
key_t
key
,
int
shmflg
,
int
size
);
static
int
newseg
(
key_t
key
,
int
shmflg
,
int
size
);
static
int
shm_map
(
struct
vm_area_struct
*
shmd
,
int
remap
);
static
int
shm_map
(
struct
vm_area_struct
*
shmd
);
static
void
killseg
(
int
id
);
static
void
killseg
(
int
id
);
static
void
shm_open
(
struct
vm_area_struct
*
shmd
);
static
void
shm_open
(
struct
vm_area_struct
*
shmd
);
static
void
shm_close
(
struct
vm_area_struct
*
shmd
);
static
void
shm_close
(
struct
vm_area_struct
*
shmd
);
...
@@ -411,34 +412,16 @@ static inline void remove_attach (struct shmid_ds * shp, struct vm_area_struct *
...
@@ -411,34 +412,16 @@ static inline void remove_attach (struct shmid_ds * shp, struct vm_area_struct *
}
}
/*
/*
*
check range is unmapped,
ensure page tables exist
* ensure page tables exist
* mark page table entries with shm_sgn.
* mark page table entries with shm_sgn.
* if remap != 0 the range is remapped.
*/
*/
static
int
shm_map
(
struct
vm_area_struct
*
shmd
,
int
remap
)
static
int
shm_map
(
struct
vm_area_struct
*
shmd
)
{
{
pgd_t
*
page_dir
;
pgd_t
*
page_dir
;
pmd_t
*
page_middle
;
pte_t
*
page_table
;
pte_t
*
page_table
;
unsigned
long
tmp
,
shm_sgn
;
unsigned
long
tmp
,
shm_sgn
;
int
error
;
/* check that the range is unmapped */
if
(
!
remap
)
for
(
tmp
=
shmd
->
vm_start
;
tmp
<
shmd
->
vm_end
;
tmp
+=
PAGE_SIZE
)
{
page_dir
=
PAGE_DIR_OFFSET
(
shmd
->
vm_task
,
tmp
);
if
(
pgd_none
(
*
page_dir
))
continue
;
if
(
pgd_bad
(
*
page_dir
))
{
printk
(
"bad ipc page directory entry %08lx
\n
"
,
pgd_val
(
*
page_dir
));
pgd_clear
(
page_dir
);
continue
;
}
page_table
=
(
pte_t
*
)
pgd_page
(
*
page_dir
);
page_table
+=
((
tmp
>>
PAGE_SHIFT
)
&
(
PTRS_PER_PAGE
-
1
));
if
(
!
pte_none
(
*
page_table
))
{
/* printk("shmat() -> EINVAL because address 0x%lx is already mapped.\n",tmp); */
return
-
EINVAL
;
}
}
/* clear old mappings */
/* clear old mappings */
do_munmap
(
shmd
->
vm_start
,
shmd
->
vm_end
-
shmd
->
vm_start
);
do_munmap
(
shmd
->
vm_start
,
shmd
->
vm_end
-
shmd
->
vm_start
);
...
@@ -447,35 +430,17 @@ static int shm_map (struct vm_area_struct *shmd, int remap)
...
@@ -447,35 +430,17 @@ static int shm_map (struct vm_area_struct *shmd, int remap)
insert_vm_struct
(
current
,
shmd
);
insert_vm_struct
(
current
,
shmd
);
merge_segments
(
current
,
shmd
->
vm_start
,
shmd
->
vm_end
);
merge_segments
(
current
,
shmd
->
vm_start
,
shmd
->
vm_end
);
/* check that the range has page_tables */
for
(
tmp
=
shmd
->
vm_start
;
tmp
<
shmd
->
vm_end
;
tmp
+=
PAGE_SIZE
)
{
page_dir
=
PAGE_DIR_OFFSET
(
shmd
->
vm_task
,
tmp
);
if
(
!
pgd_none
(
*
page_dir
))
{
page_table
=
(
pte_t
*
)
pgd_page
(
*
page_dir
);
page_table
+=
((
tmp
>>
PAGE_SHIFT
)
&
(
PTRS_PER_PAGE
-
1
));
if
(
!
pte_none
(
*
page_table
))
{
if
(
pte_present
(
*
page_table
))
{
--
current
->
mm
->
rss
;
free_page
(
pte_page
(
*
page_table
));
}
else
swap_free
(
pte_val
(
*
page_table
));
pte_clear
(
page_table
);
}
}
else
{
if
(
!
(
page_table
=
(
pte_t
*
)
get_free_page
(
GFP_KERNEL
)))
return
-
ENOMEM
;
pgd_set
(
page_dir
,
page_table
);
tmp
|=
(
PGDIR_SIZE
-
PAGE_SIZE
);
}
}
/* map page range */
/* map page range */
shm_sgn
=
shmd
->
vm_pte
+
((
shmd
->
vm_offset
>>
PAGE_SHIFT
)
<<
SHM_IDX_SHIFT
);
shm_sgn
=
shmd
->
vm_pte
+
((
shmd
->
vm_offset
>>
PAGE_SHIFT
)
<<
SHM_IDX_SHIFT
);
for
(
tmp
=
shmd
->
vm_start
;
tmp
<
shmd
->
vm_end
;
tmp
+=
PAGE_SIZE
,
for
(
tmp
=
shmd
->
vm_start
;
tmp
<
shmd
->
vm_end
;
tmp
+=
PAGE_SIZE
,
shm_sgn
+=
(
1
<<
SHM_IDX_SHIFT
))
{
shm_sgn
+=
(
1
<<
SHM_IDX_SHIFT
))
{
page_dir
=
PAGE_DIR_OFFSET
(
shmd
->
vm_task
,
tmp
);
page_dir
=
pgd_offset
(
shmd
->
vm_task
,
tmp
);
page_table
=
(
pte_t
*
)
pgd_page
(
*
page_dir
);
page_middle
=
pmd_alloc
(
page_dir
,
tmp
);
page_table
+=
(
tmp
>>
PAGE_SHIFT
)
&
(
PTRS_PER_PAGE
-
1
);
if
(
!
page_middle
)
break
;
page_table
=
pte_alloc
(
page_middle
,
tmp
);
if
(
!
page_table
)
break
;
pte_val
(
*
page_table
)
=
shm_sgn
;
pte_val
(
*
page_table
)
=
shm_sgn
;
}
}
invalidate
();
invalidate
();
...
@@ -553,7 +518,7 @@ int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
...
@@ -553,7 +518,7 @@ int sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
shmd
->
vm_ops
=
&
shm_vm_ops
;
shmd
->
vm_ops
=
&
shm_vm_ops
;
shp
->
shm_nattch
++
;
/* prevent destruction */
shp
->
shm_nattch
++
;
/* prevent destruction */
if
((
err
=
shm_map
(
shmd
,
shmflg
&
SHM_REMAP
)))
{
if
((
err
=
shm_map
(
shmd
)))
{
if
(
--
shp
->
shm_nattch
<=
0
&&
shp
->
shm_perm
.
mode
&
SHM_DEST
)
if
(
--
shp
->
shm_nattch
<=
0
&&
shp
->
shm_perm
.
mode
&
SHM_DEST
)
killseg
(
id
);
killseg
(
id
);
kfree
(
shmd
);
kfree
(
shmd
);
...
@@ -749,6 +714,7 @@ int shm_swap (int prio)
...
@@ -749,6 +714,7 @@ int shm_swap (int prio)
for
(
shmd
=
shp
->
attaches
;
;
)
{
for
(
shmd
=
shp
->
attaches
;
;
)
{
do
{
do
{
pgd_t
*
page_dir
;
pgd_t
*
page_dir
;
pmd_t
*
page_middle
;
pte_t
*
page_table
,
pte
;
pte_t
*
page_table
,
pte
;
unsigned
long
tmp
;
unsigned
long
tmp
;
...
@@ -759,15 +725,21 @@ int shm_swap (int prio)
...
@@ -759,15 +725,21 @@ int shm_swap (int prio)
tmp
=
shmd
->
vm_start
+
(
idx
<<
PAGE_SHIFT
)
-
shmd
->
vm_offset
;
tmp
=
shmd
->
vm_start
+
(
idx
<<
PAGE_SHIFT
)
-
shmd
->
vm_offset
;
if
(
!
(
tmp
>=
shmd
->
vm_start
&&
tmp
<
shmd
->
vm_end
))
if
(
!
(
tmp
>=
shmd
->
vm_start
&&
tmp
<
shmd
->
vm_end
))
continue
;
continue
;
page_dir
=
PAGE_DIR_OFFSET
(
shmd
->
vm_task
,
tmp
);
page_dir
=
pgd_offset
(
shmd
->
vm_task
,
tmp
);
if
(
pgd_none
(
*
page_dir
)
||
pgd_bad
(
*
page_dir
))
{
if
(
pgd_none
(
*
page_dir
)
||
pgd_bad
(
*
page_dir
))
{
printk
(
"shm_swap: bad pgtbl! id=%ld start=%lx idx=%ld
\n
"
,
printk
(
"shm_swap: bad pgtbl! id=%ld start=%lx idx=%ld
\n
"
,
id
,
shmd
->
vm_start
,
idx
);
id
,
shmd
->
vm_start
,
idx
);
pgd_clear
(
page_dir
);
pgd_clear
(
page_dir
);
continue
;
continue
;
}
}
page_table
=
(
pte_t
*
)
pgd_page
(
*
page_dir
);
page_middle
=
pmd_offset
(
page_dir
,
tmp
);
page_table
+=
((
tmp
>>
PAGE_SHIFT
)
&
(
PTRS_PER_PAGE
-
1
));
if
(
pmd_none
(
*
page_middle
)
||
pmd_bad
(
*
page_middle
))
{
printk
(
"shm_swap: bad pgmid! id=%ld start=%lx idx=%ld
\n
"
,
id
,
shmd
->
vm_start
,
idx
);
pmd_clear
(
page_middle
);
continue
;
}
page_table
=
pte_offset
(
page_middle
,
tmp
);
pte
=
*
page_table
;
pte
=
*
page_table
;
if
(
!
pte_present
(
pte
))
if
(
!
pte_present
(
pte
))
continue
;
continue
;
...
@@ -779,7 +751,8 @@ int shm_swap (int prio)
...
@@ -779,7 +751,8 @@ int shm_swap (int prio)
printk
(
"shm_swap_out: page and pte mismatch
\n
"
);
printk
(
"shm_swap_out: page and pte mismatch
\n
"
);
pte_val
(
*
page_table
)
=
shmd
->
vm_pte
|
idx
<<
SHM_IDX_SHIFT
;
pte_val
(
*
page_table
)
=
shmd
->
vm_pte
|
idx
<<
SHM_IDX_SHIFT
;
mem_map
[
MAP_NR
(
pte_page
(
pte
))]
--
;
mem_map
[
MAP_NR
(
pte_page
(
pte
))]
--
;
shmd
->
vm_task
->
mm
->
rss
--
;
if
(
shmd
->
vm_task
->
mm
->
rss
>
0
)
shmd
->
vm_task
->
mm
->
rss
--
;
invalid
++
;
invalid
++
;
/* continue looping through circular list */
/* continue looping through circular list */
}
while
(
0
);
}
while
(
0
);
...
...
kernel/fork.c
View file @
5d278332
...
@@ -163,12 +163,11 @@ static void copy_fs(unsigned long clone_flags, struct task_struct * p)
...
@@ -163,12 +163,11 @@ static void copy_fs(unsigned long clone_flags, struct task_struct * p)
* information (task[nr]) and sets up the necessary registers. It
* information (task[nr]) and sets up the necessary registers. It
* also copies the data segment in its entirety.
* also copies the data segment in its entirety.
*/
*/
asmlinkage
int
sys_fork
(
struct
pt_regs
regs
)
int
do_fork
(
unsigned
long
clone_flags
,
unsigned
long
usp
,
struct
pt_regs
*
regs
)
{
{
int
nr
;
int
nr
;
struct
task_struct
*
p
;
unsigned
long
new_stack
;
unsigned
long
new_stack
;
unsigned
long
clone_flags
=
COPYVM
|
SIGCHLD
;
struct
task_struct
*
p
;
if
(
!
(
p
=
(
struct
task_struct
*
)
__get_free_page
(
GFP_KERNEL
)))
if
(
!
(
p
=
(
struct
task_struct
*
)
__get_free_page
(
GFP_KERNEL
)))
goto
bad_fork
;
goto
bad_fork
;
...
@@ -206,7 +205,7 @@ asmlinkage int sys_fork(struct pt_regs regs)
...
@@ -206,7 +205,7 @@ asmlinkage int sys_fork(struct pt_regs regs)
task
[
nr
]
=
p
;
task
[
nr
]
=
p
;
/* copy all the process information */
/* copy all the process information */
c
lone_flags
=
copy_thread
(
nr
,
COPYVM
|
SIGCHLD
,
p
,
&
regs
);
c
opy_thread
(
nr
,
clone_flags
,
usp
,
p
,
regs
);
if
(
copy_mm
(
clone_flags
,
p
))
if
(
copy_mm
(
clone_flags
,
p
))
goto
bad_fork_cleanup
;
goto
bad_fork_cleanup
;
p
->
semundo
=
NULL
;
p
->
semundo
=
NULL
;
...
...
kernel/sys.c
View file @
5d278332
...
@@ -517,6 +517,7 @@ asmlinkage int sys_setsid(void)
...
@@ -517,6 +517,7 @@ asmlinkage int sys_setsid(void)
current
->
leader
=
1
;
current
->
leader
=
1
;
current
->
session
=
current
->
pgrp
=
current
->
pid
;
current
->
session
=
current
->
pgrp
=
current
->
pid
;
current
->
tty
=
NULL
;
current
->
tty
=
NULL
;
current
->
tty_old_pgrp
=
0
;
return
current
->
pgrp
;
return
current
->
pgrp
;
}
}
...
...
mm/swap.c
View file @
5d278332
...
@@ -506,11 +506,10 @@ static int swap_out_process(struct task_struct * p)
...
@@ -506,11 +506,10 @@ static int swap_out_process(struct task_struct * p)
static
int
swap_out
(
unsigned
int
priority
)
static
int
swap_out
(
unsigned
int
priority
)
{
{
static
int
swap_task
;
static
int
swap_task
;
int
loop
;
int
loop
,
counter
;
int
counter
=
NR_TASKS
*
2
>>
priority
;
struct
task_struct
*
p
;
struct
task_struct
*
p
;
counter
=
NR_TASKS
*
2
>>
priority
;
counter
=
2
*
NR_TASKS
>>
priority
;
for
(;
counter
>=
0
;
counter
--
,
swap_task
++
)
{
for
(;
counter
>=
0
;
counter
--
,
swap_task
++
)
{
/*
/*
* Check that swap_task is suitable for swapping. If not, look for
* Check that swap_task is suitable for swapping. If not, look for
...
@@ -557,6 +556,15 @@ static int swap_out(unsigned int priority)
...
@@ -557,6 +556,15 @@ static int swap_out(unsigned int priority)
return
0
;
return
0
;
}
}
/*
* we keep on shrinking one resource until it's considered "too hard",
* and then switch to the next one (priority being an indication on how
* hard we should try with the resource).
*
* This should automatically find the resource that can most easily be
* free'd, so hopefully we'll get reasonable behaviour even under very
* different circumstances.
*/
static
int
try_to_free_page
(
int
priority
)
static
int
try_to_free_page
(
int
priority
)
{
{
static
int
state
=
0
;
static
int
state
=
0
;
...
@@ -565,23 +573,19 @@ static int try_to_free_page(int priority)
...
@@ -565,23 +573,19 @@ static int try_to_free_page(int priority)
switch
(
state
)
{
switch
(
state
)
{
do
{
do
{
case
0
:
case
0
:
if
(
priority
!=
GFP_NOBUFFER
&&
shrink_buffers
(
i
))
{
if
(
priority
!=
GFP_NOBUFFER
&&
shrink_buffers
(
i
))
state
=
1
;
return
1
;
return
1
;
}
state
=
1
;
case
1
:
case
1
:
if
(
shm_swap
(
i
))
{
if
(
shm_swap
(
i
))
state
=
2
;
return
1
;
return
1
;
}
state
=
2
;
case
2
:
default:
if
(
swap_out
(
i
))
{
if
(
swap_out
(
i
))
state
=
0
;
return
1
;
return
1
;
}
state
=
0
;
}
while
(
--
i
);
}
while
(
--
i
);
}
}
state
=
2
;
return
0
;
return
0
;
}
}
...
...
net/inet/af_inet.c
View file @
5d278332
...
@@ -864,11 +864,13 @@ static int inet_bind(struct socket *sock, struct sockaddr *uaddr,
...
@@ -864,11 +864,13 @@ static int inet_bind(struct socket *sock, struct sockaddr *uaddr,
{
{
/* should be below! */
/* should be below! */
if
(
sk2
->
num
!=
snum
)
continue
;
if
(
sk2
->
num
!=
snum
)
continue
;
#if 0
if (sk2->dead)
if (sk2->dead)
{
{
destroy_sock(sk2);
destroy_sock(sk2);
goto outside_loop;
goto outside_loop;
}
}
#endif
if
(
!
sk
->
reuse
)
if
(
!
sk
->
reuse
)
{
{
sti
();
sti
();
...
...
net/inet/tcp.c
View file @
5d278332
...
@@ -2769,9 +2769,9 @@ static void tcp_conn_request(struct sock *sk, struct sk_buff *skb,
...
@@ -2769,9 +2769,9 @@ static void tcp_conn_request(struct sock *sk, struct sk_buff *skb,
newsk
->
linger
=
0
;
newsk
->
linger
=
0
;
newsk
->
destroy
=
0
;
newsk
->
destroy
=
0
;
init_timer
(
&
newsk
->
timer
);
init_timer
(
&
newsk
->
timer
);
init_timer
(
&
newsk
->
retransmit_timer
);
newsk
->
timer
.
data
=
(
unsigned
long
)
newsk
;
newsk
->
timer
.
data
=
(
unsigned
long
)
newsk
;
newsk
->
timer
.
function
=
&
net_timer
;
newsk
->
timer
.
function
=
&
net_timer
;
init_timer
(
&
newsk
->
retransmit_timer
);
newsk
->
retransmit_timer
.
data
=
(
unsigned
long
)
newsk
;
newsk
->
retransmit_timer
.
data
=
(
unsigned
long
)
newsk
;
newsk
->
retransmit_timer
.
function
=&
retransmit_timer
;
newsk
->
retransmit_timer
.
function
=&
retransmit_timer
;
newsk
->
dummy_th
.
source
=
skb
->
h
.
th
->
dest
;
newsk
->
dummy_th
.
source
=
skb
->
h
.
th
->
dest
;
...
@@ -4393,7 +4393,9 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
...
@@ -4393,7 +4393,9 @@ static int tcp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
tcp_set_state
(
sk
,
TCP_SYN_SENT
);
tcp_set_state
(
sk
,
TCP_SYN_SENT
);
sk
->
rto
=
TCP_TIMEOUT_INIT
;
sk
->
rto
=
TCP_TIMEOUT_INIT
;
init_timer
(
&
sk
->
retransmit_timer
);
#if 0 /* we already did this */
init_timer(&sk->retransmit_timer);
#endif
sk
->
retransmit_timer
.
function
=&
retransmit_timer
;
sk
->
retransmit_timer
.
function
=&
retransmit_timer
;
sk
->
retransmit_timer
.
data
=
(
unsigned
long
)
sk
;
sk
->
retransmit_timer
.
data
=
(
unsigned
long
)
sk
;
reset_xmit_timer
(
sk
,
TIME_WRITE
,
sk
->
rto
);
/* Timer for repeating the SYN until an answer */
reset_xmit_timer
(
sk
,
TIME_WRITE
,
sk
->
rto
);
/* Timer for repeating the SYN until an answer */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment