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
Kirill Smelkov
linux
Commits
eebbb0b8
Commit
eebbb0b8
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 1.1.37
parent
ba00f557
Changes
46
Show whitespace changes
Inline
Side-by-side
Showing
46 changed files
with
1128 additions
and
681 deletions
+1128
-681
Makefile
Makefile
+2
-2
drivers/block/README.hd
drivers/block/README.hd
+66
-5
drivers/block/blk.h
drivers/block/blk.h
+2
-1
drivers/block/hd.c
drivers/block/hd.c
+69
-39
drivers/char/mem.c
drivers/char/mem.c
+0
-4
drivers/char/psaux.c
drivers/char/psaux.c
+1
-1
drivers/scsi/aha1542.c
drivers/scsi/aha1542.c
+42
-7
drivers/scsi/g_NCR5380.c
drivers/scsi/g_NCR5380.c
+0
-5
drivers/scsi/hosts.c
drivers/scsi/hosts.c
+24
-54
drivers/scsi/hosts.h
drivers/scsi/hosts.h
+26
-0
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+33
-69
drivers/scsi/scsi.h
drivers/scsi/scsi.h
+1
-17
drivers/scsi/sd.c
drivers/scsi/sd.c
+91
-38
drivers/scsi/seagate.c
drivers/scsi/seagate.c
+0
-4
drivers/scsi/sg.c
drivers/scsi/sg.c
+64
-31
drivers/scsi/sr.c
drivers/scsi/sr.c
+100
-49
drivers/scsi/sr_ioctl.c
drivers/scsi/sr_ioctl.c
+3
-1
drivers/scsi/st.c
drivers/scsi/st.c
+67
-25
fs/Makefile
fs/Makefile
+1
-1
fs/dcache.c
fs/dcache.c
+251
-0
fs/ext2/Makefile
fs/ext2/Makefile
+2
-2
fs/ext2/dir.c
fs/ext2/dir.c
+1
-4
fs/ext2/inode.c
fs/ext2/inode.c
+1
-0
fs/ext2/namei.c
fs/ext2/namei.c
+18
-54
fs/ext2/super.c
fs/ext2/super.c
+0
-3
fs/inode.c
fs/inode.c
+1
-0
fs/isofs/rock.c
fs/isofs/rock.c
+20
-15
fs/msdos/mmap.c
fs/msdos/mmap.c
+0
-3
fs/nfs/mmap.c
fs/nfs/mmap.c
+0
-3
fs/sysv/Makefile
fs/sysv/Makefile
+1
-1
fs/sysv/README
fs/sysv/README
+1
-1
fs/sysv/file.c
fs/sysv/file.c
+2
-3
fs/sysv/mmap.c
fs/sysv/mmap.c
+85
-0
ibcs/binfmt_elf.c
ibcs/binfmt_elf.c
+3
-2
include/linux/ext2_fs.h
include/linux/ext2_fs.h
+0
-16
include/linux/fs.h
include/linux/fs.h
+4
-0
include/linux/page.h
include/linux/page.h
+5
-1
include/linux/sched.h
include/linux/sched.h
+3
-7
include/linux/sysv_fs.h
include/linux/sysv_fs.h
+1
-2
init/main.c
init/main.c
+1
-0
kernel/Makefile
kernel/Makefile
+1
-1
kernel/ksyms.c
kernel/ksyms.c
+0
-2
kernel/sched.c
kernel/sched.c
+3
-2
kernel/sys.c
kernel/sys.c
+3
-2
mm/mmap.c
mm/mmap.c
+17
-40
mm/swap.c
mm/swap.c
+112
-164
No files found.
Makefile
View file @
eebbb0b8
VERSION
=
1
VERSION
=
1
PATCHLEVEL
=
1
PATCHLEVEL
=
1
SUBLEVEL
=
3
6
SUBLEVEL
=
3
7
all
:
Version zImage
all
:
Version zImage
...
@@ -127,7 +127,7 @@ endif
...
@@ -127,7 +127,7 @@ endif
.c.s
:
.c.s
:
$(CC)
$(CFLAGS)
-S
-o
$*
.s
$<
$(CC)
$(CFLAGS)
-S
-o
$*
.s
$<
.s.o
:
.s.o
:
$(AS)
-
c
-
o
$*
.o
$<
$(AS)
-o
$*
.o
$<
.c.o
:
.c.o
:
$(CC)
$(CFLAGS)
-c
-o
$*
.o
$<
$(CC)
$(CFLAGS)
-c
-o
$*
.o
$<
...
...
drivers/block/README.hd
View file @
eebbb0b8
IDE Performance Enhancements Version 2.
0
IDE Performance Enhancements Version 2.
1
============================ ===========
============================ ===========
What's new in version 2.1:
-- Support added for E-IDE BIOSs, for systems with IDE drives
that "have more than 16 logical heads" (according the BIOS).
-- the HDIO_SETUNMASKINTR and HDIO_SETMULTCOUNT now permit
only the superuser to change settings, and no longer permit
minor device numbers to be used.
This version of hd.c includes support for two optional features:
This version of hd.c includes support for two optional features:
(1) The disk I/O routines can now run with interrupts unmasked
(1) The disk I/O routines can now run with interrupts unmasked
...
@@ -22,9 +29,8 @@ It works on most systems, but use at your own risk!!
...
@@ -22,9 +29,8 @@ It works on most systems, but use at your own risk!!
Drives which support "Multiple Sector Mode" are identified by the
Drives which support "Multiple Sector Mode" are identified by the
kernel at boot time, and a message is displayed indicating the
kernel at boot time, and a message is displayed indicating the
largest possible setting for "MaxMult". I recommend using settings
largest possible setting for "MaxMult" (max sector count for
of 8, 16, or 32. Many drives also support non-powers of two,
"Multiple Sector Mode").
but many other drives do not -- try strange values at your own risk!
For more detailed boot-time information about your drive, change
For more detailed boot-time information about your drive, change
the definition of VERBOSE_DRIVE_INFO from 0 to 1 near the top
the definition of VERBOSE_DRIVE_INFO from 0 to 1 near the top
...
@@ -34,12 +40,16 @@ Some drives (mostly older CONNER drives) do not implement multiple mode
...
@@ -34,12 +40,16 @@ Some drives (mostly older CONNER drives) do not implement multiple mode
correctly, and data corruption may occur.. but if you wait long enough
correctly, and data corruption may occur.. but if you wait long enough
the error recovery logic *should* be able to recover eventually.
the error recovery logic *should* be able to recover eventually.
I recommend using settings of 8, 16, or 32. Many drives also support
non-powers of two, but other drives do not -- try strange values at
your own risk!
To try this out more safely, mount the drive's partitions read-only
To try this out more safely, mount the drive's partitions read-only
before using hdparm (see below) for the first time. If it doesn't
before using hdparm (see below) for the first time. If it doesn't
work, email me (mlord@bnr.ca) with the drive name as displayed at
work, email me (mlord@bnr.ca) with the drive name as displayed at
boot time, so I can warn others and possibly add a hook to the code.
boot time, so I can warn others and possibly add a hook to the code.
To enable the features, a small program is included: hdparm.c
To enable the features, a small program is included
below
: hdparm.c
This one is *different* from previous versions -- be sure to recompile it!
This one is *different* from previous versions -- be sure to recompile it!
Compile this using cc -O -o /usr/bin/hdparm hdparm.c
Compile this using cc -O -o /usr/bin/hdparm hdparm.c
...
@@ -96,3 +106,54 @@ and rebuild and install the new kernel.
...
@@ -96,3 +106,54 @@ and rebuild and install the new kernel.
Enjoy,
Enjoy,
mlord@bnr.ca
mlord@bnr.ca
**** CUT HERE for hdparm.c ****
/* make using: cc -O -o /usr/bin/hdparm hdparm.c */
#include <linux/hdreg.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
/* extern int hd_ioctl(struct inode * inode, struct file * file,
* unsigned int cmd, unsigned long arg);
*/
void main (int argc, char *argv[])
{
int fd, mrc, irc;
static long mcount, irqmode;
if (argc != 4 && argc != 2) {
fprintf(stderr,"Usage: %s <device>"
" [<MultModeCount:0-64> <unmask:0/1>]\n", *argv);
exit (1);
}
fd = open (*++argv, O_RDONLY);
if (fd < 0) {
printf ("open failed - '%s' - %d\n", *argv, fd);
exit(1);
}
if (argc == 4) {
mcount = atoi(*++argv);
mrc = ioctl (fd, HDIO_SETMULTCOUNT, &mcount);
/* note that the new mcount does not take effect
until the next disk I/O operation, so if we were
to query it before then, the old value will show.
Also, the drive may reject the new value, which will
result in multiple mode being turned OFF completely! */
irqmode = atoi(*++argv);
irc = ioctl (fd, HDIO_SETUNMASKINTR, &irqmode);
}
else {
mrc = ioctl (fd, HDIO_GETMULTCOUNT, &mcount);
irc = ioctl (fd, HDIO_GETUNMASKINTR, &irqmode);
}
printf("MultModeCount=%d, rc=%d\n", mcount, mrc);
printf("unmask=%d, rc=%d\n", irqmode, irc);
}
drivers/block/blk.h
View file @
eebbb0b8
...
@@ -288,6 +288,7 @@ static void end_request(int uptodate)
...
@@ -288,6 +288,7 @@ static void end_request(int uptodate)
req
->
bh
=
bh
->
b_reqnext
;
req
->
bh
=
bh
->
b_reqnext
;
bh
->
b_reqnext
=
NULL
;
bh
->
b_reqnext
=
NULL
;
bh
->
b_uptodate
=
uptodate
;
bh
->
b_uptodate
=
uptodate
;
if
(
!
uptodate
)
bh
->
b_req
=
0
;
/* So no "Weird" errors */
unlock_buffer
(
bh
);
unlock_buffer
(
bh
);
if
((
bh
=
req
->
bh
)
!=
NULL
)
{
if
((
bh
=
req
->
bh
)
!=
NULL
)
{
req
->
current_nr_sectors
=
bh
->
b_size
>>
9
;
req
->
current_nr_sectors
=
bh
->
b_size
>>
9
;
...
...
drivers/block/hd.c
View file @
eebbb0b8
...
@@ -16,6 +16,9 @@
...
@@ -16,6 +16,9 @@
* in the early extended-partition checks and added DM partitions
* in the early extended-partition checks and added DM partitions
*
*
* IDE IRQ-unmask & drive-id & multiple-mode code added by Mark Lord.
* IDE IRQ-unmask & drive-id & multiple-mode code added by Mark Lord.
*
* Support for E-IDE BIOS drive geometry translation added by Mark Lord.
* -- hd.c no longer chokes on E-IDE drives with "more than 16 heads".
*/
*/
#define DEFAULT_MULT_COUNT 0
/* set to 0 to disable multiple mode at boot */
#define DEFAULT_MULT_COUNT 0
/* set to 0 to disable multiple mode at boot */
...
@@ -80,10 +83,12 @@ struct hd_i_struct {
...
@@ -80,10 +83,12 @@ struct hd_i_struct {
unsigned
int
head
,
sect
,
cyl
,
wpcom
,
lzone
,
ctl
;
unsigned
int
head
,
sect
,
cyl
,
wpcom
,
lzone
,
ctl
;
};
};
#ifdef HD_TYPE
#ifdef HD_TYPE
struct
hd_i_struct
hd_info
[]
=
{
HD_TYPE
};
static
struct
hd_i_struct
hd_info
[]
=
{
HD_TYPE
};
struct
hd_i_struct
bios_info
[]
=
{
HD_TYPE
};
static
int
NR_HD
=
((
sizeof
(
hd_info
))
/
(
sizeof
(
struct
hd_i_struct
)));
static
int
NR_HD
=
((
sizeof
(
hd_info
))
/
(
sizeof
(
struct
hd_i_struct
)));
#else
#else
struct
hd_i_struct
hd_info
[]
=
{
{
0
,
0
,
0
,
0
,
0
,
0
},{
0
,
0
,
0
,
0
,
0
,
0
}
};
static
struct
hd_i_struct
hd_info
[]
=
{
{
0
,
0
,
0
,
0
,
0
,
0
},{
0
,
0
,
0
,
0
,
0
,
0
}
};
struct
hd_i_struct
bios_info
[]
=
{
{
0
,
0
,
0
,
0
,
0
,
0
},{
0
,
0
,
0
,
0
,
0
,
0
}
};
static
int
NR_HD
=
0
;
static
int
NR_HD
=
0
;
#endif
#endif
...
@@ -113,14 +118,14 @@ void hd_setup(char *str, int *ints)
...
@@ -113,14 +118,14 @@ void hd_setup(char *str, int *ints)
if
(
ints
[
0
]
!=
3
)
if
(
ints
[
0
]
!=
3
)
return
;
return
;
if
(
hd
_info
[
0
].
head
!=
0
)
if
(
bios
_info
[
0
].
head
!=
0
)
hdind
=
1
;
hdind
=
1
;
hd_info
[
hdind
].
head
=
ints
[
2
];
bios_info
[
hdind
].
head
=
hd_info
[
hdind
].
head
=
ints
[
2
];
hd_info
[
hdind
].
sect
=
ints
[
3
];
bios_info
[
hdind
].
sect
=
hd_info
[
hdind
].
sect
=
ints
[
3
];
hd_info
[
hdind
].
cyl
=
ints
[
1
];
bios_info
[
hdind
].
cyl
=
hd_info
[
hdind
].
cyl
=
ints
[
1
];
hd_info
[
hdind
].
wpcom
=
0
;
bios_info
[
hdind
].
wpcom
=
hd_info
[
hdind
].
wpcom
=
0
;
hd_info
[
hdind
].
lzone
=
ints
[
1
];
bios_info
[
hdind
].
lzone
=
hd_info
[
hdind
].
lzone
=
ints
[
1
];
hd_info
[
hdind
].
ctl
=
(
ints
[
2
]
>
8
?
8
:
0
);
bios_info
[
hdind
].
ctl
=
hd_info
[
hdind
].
ctl
=
(
ints
[
2
]
>
8
?
8
:
0
);
NR_HD
=
hdind
+
1
;
NR_HD
=
hdind
+
1
;
}
}
...
@@ -270,7 +275,7 @@ static void dump_identity (unsigned int dev, unsigned short ib[])
...
@@ -270,7 +275,7 @@ static void dump_identity (unsigned int dev, unsigned short ib[])
printk
(
"
\n
Config={"
);
printk
(
"
\n
Config={"
);
for
(
i
=
0
;
i
<=
15
;
i
++
)
if
(
ib
[
0
]
&
(
1
<<
i
))
printk
(
cfg_str
[
i
]);
for
(
i
=
0
;
i
<=
15
;
i
++
)
if
(
ib
[
0
]
&
(
1
<<
i
))
printk
(
cfg_str
[
i
]);
printk
(
" }
\n
"
);
printk
(
" }
\n
"
);
printk
(
" Default
c/h/s
=%d/%d/%d, TrkSize=%d, SectSize=%d, ECCbytes=%d
\n
"
,
printk
(
" Default
CHS
=%d/%d/%d, TrkSize=%d, SectSize=%d, ECCbytes=%d
\n
"
,
ib
[
1
],
ib
[
3
],
ib
[
6
],
ib
[
4
],
ib
[
5
],
ib
[
22
]);
ib
[
1
],
ib
[
3
],
ib
[
6
],
ib
[
4
],
ib
[
5
],
ib
[
22
]);
dmpstr
(
" BuffType="
,
ib
[
20
],
BuffType
,
3
);
dmpstr
(
" BuffType="
,
ib
[
20
],
BuffType
,
3
);
ib
[
47
]
&=
0xFF
;
ib
[
47
]
&=
0xFF
;
...
@@ -280,7 +285,7 @@ static void dump_identity (unsigned int dev, unsigned short ib[])
...
@@ -280,7 +285,7 @@ static void dump_identity (unsigned int dev, unsigned short ib[])
dmpstr
(
", tPIO="
,
ib
[
51
]
>>
8
,
SlowMedFast
,
2
);
dmpstr
(
", tPIO="
,
ib
[
51
]
>>
8
,
SlowMedFast
,
2
);
if
(
ib
[
49
]
&
0x100
&&
(
ib
[
53
]
&
1
))
if
(
ib
[
49
]
&
0x100
&&
(
ib
[
53
]
&
1
))
dmpstr
(
", tDMA="
,
ib
[
52
]
>>
8
,
SlowMedFast
,
2
);
dmpstr
(
", tDMA="
,
ib
[
52
]
>>
8
,
SlowMedFast
,
2
);
printk
(
"
\n
(%s): Current
c/h/s
=%d/%d/%d, TotSect=%d"
,
printk
(
"
\n
(%s): Current
CHS
=%d/%d/%d, TotSect=%d"
,
(((
ib
[
53
]
&
1
)
==
0
)
?
"maybe"
:
"valid"
),
(((
ib
[
53
]
&
1
)
==
0
)
?
"maybe"
:
"valid"
),
ib
[
54
],
ib
[
55
],
ib
[
56
],
*
(
int
*
)
&
ib
[
57
]);
ib
[
54
],
ib
[
55
],
ib
[
56
],
*
(
int
*
)
&
ib
[
57
]);
if
(
ib
[
49
]
&
0x200
)
if
(
ib
[
49
]
&
0x200
)
...
@@ -309,8 +314,21 @@ static void identify_intr(void)
...
@@ -309,8 +314,21 @@ static void identify_intr(void)
printk
(
" hd%c: "
,
dev
+
'a'
);
printk
(
" hd%c: "
,
dev
+
'a'
);
rawstring
(
NULL
,
(
char
*
)
&
ib
[
27
],
40
);
rawstring
(
NULL
,
(
char
*
)
&
ib
[
27
],
40
);
max_mult
[
dev
]
=
ib
[
47
]
&
0xff
;
max_mult
[
dev
]
=
ib
[
47
]
&
0xff
;
printk
(
" (%dMB IDE w/%dKB Cache, MaxMult=%d)
\n
"
,
if
(
ib
[
53
]
&
1
&&
ib
[
54
]
&&
ib
[
55
]
&&
ib
[
56
])
{
ib
[
1
]
*
ib
[
3
]
*
ib
[
6
]
/
2048
,
ib
[
21
]
>>
1
,
max_mult
[
dev
]);
/*
* Extract the physical drive geometry for our use.
* Note that we purposely do *not* update the bios_info.
* This way, programs that use it (like fdisk) will
* still have the same logical view as the BIOS does,
* which keeps the partition table from being screwed.
*/
hd_info
[
dev
].
cyl
=
ib
[
54
];
hd_info
[
dev
].
head
=
ib
[
55
];
hd_info
[
dev
].
sect
=
ib
[
56
];
}
printk
(
" (%dMB IDE w/%dKB Cache, MaxMult=%d, CHS=%d/%d/%d)
\n
"
,
ib
[
1
]
*
ib
[
3
]
*
ib
[
6
]
/
2048
,
ib
[
21
]
>>
1
,
max_mult
[
dev
],
hd_info
[
dev
].
cyl
,
hd_info
[
dev
].
head
,
hd_info
[
dev
].
sect
);
insw
(
HD_DATA
,(
char
*
)
ib
,
64
);
/* flush remaining 384 ID bytes */
insw
(
HD_DATA
,(
char
*
)
ib
,
64
);
/* flush remaining 384 ID bytes */
insw
(
HD_DATA
,(
char
*
)
ib
,
64
);
insw
(
HD_DATA
,(
char
*
)
ib
,
64
);
insw
(
HD_DATA
,(
char
*
)
ib
,
64
);
insw
(
HD_DATA
,(
char
*
)
ib
,
64
);
...
@@ -449,10 +467,11 @@ static inline int wait_DRQ(void)
...
@@ -449,10 +467,11 @@ static inline int wait_DRQ(void)
static
void
read_intr
(
void
)
static
void
read_intr
(
void
)
{
{
unsigned
int
dev
=
DEVICE_NR
(
CURRENT
->
dev
);
unsigned
int
dev
=
DEVICE_NR
(
CURRENT
->
dev
);
int
i
,
retries
=
100000
,
msect
,
nsect
;
int
i
,
retries
=
100000
,
msect
=
mult_count
[
dev
]
,
nsect
;
if
(
unmask_intr
[
dev
])
if
(
unmask_intr
[
dev
])
sti
();
/* permit other IRQs during xfer */
sti
();
/* permit other IRQs during xfer */
read_next:
do
{
do
{
i
=
(
unsigned
)
inb_p
(
HD_STATUS
);
i
=
(
unsigned
)
inb_p
(
HD_STATUS
);
if
(
i
&
BUSY_STAT
)
if
(
i
&
BUSY_STAT
)
...
@@ -473,8 +492,6 @@ static void read_intr(void)
...
@@ -473,8 +492,6 @@ static void read_intr(void)
hd_request
();
hd_request
();
return
;
return
;
ok_to_read:
ok_to_read:
msect
=
mult_count
[
dev
];
read_next:
if
(
msect
)
{
if
(
msect
)
{
if
((
nsect
=
CURRENT
->
current_nr_sectors
)
>
msect
)
if
((
nsect
=
CURRENT
->
current_nr_sectors
)
>
msect
)
nsect
=
msect
;
nsect
=
msect
;
...
@@ -717,6 +734,11 @@ static void hd_request(void)
...
@@ -717,6 +734,11 @@ static void hd_request(void)
goto
repeat
;
goto
repeat
;
return
;
return
;
}
}
if
(
hd_info
[
dev
].
head
>
16
)
{
printk
(
"hd%c: cannot handle device with more than 16 heads - giving up
\n
"
,
dev
+
'a'
);
end_request
(
0
);
goto
repeat
;
}
if
(
CURRENT
->
cmd
==
READ
)
{
if
(
CURRENT
->
cmd
==
READ
)
{
unsigned
int
cmd
=
mult_count
[
dev
]
>
1
?
WIN_MULTREAD
:
WIN_READ
;
unsigned
int
cmd
=
mult_count
[
dev
]
>
1
?
WIN_MULTREAD
:
WIN_READ
;
hd_out
(
dev
,
nsect
,
sec
,
head
,
cyl
,
cmd
,
&
read_intr
);
hd_out
(
dev
,
nsect
,
sec
,
head
,
cyl
,
cmd
,
&
read_intr
);
...
@@ -781,11 +803,11 @@ static int hd_ioctl(struct inode * inode, struct file * file,
...
@@ -781,11 +803,11 @@ static int hd_ioctl(struct inode * inode, struct file * file,
err
=
verify_area
(
VERIFY_WRITE
,
loc
,
sizeof
(
*
loc
));
err
=
verify_area
(
VERIFY_WRITE
,
loc
,
sizeof
(
*
loc
));
if
(
err
)
if
(
err
)
return
err
;
return
err
;
put_fs_byte
(
hd
_info
[
dev
].
head
,
put_fs_byte
(
bios
_info
[
dev
].
head
,
(
char
*
)
&
loc
->
heads
);
(
char
*
)
&
loc
->
heads
);
put_fs_byte
(
hd
_info
[
dev
].
sect
,
put_fs_byte
(
bios
_info
[
dev
].
sect
,
(
char
*
)
&
loc
->
sectors
);
(
char
*
)
&
loc
->
sectors
);
put_fs_word
(
hd
_info
[
dev
].
cyl
,
put_fs_word
(
bios
_info
[
dev
].
cyl
,
(
short
*
)
&
loc
->
cylinders
);
(
short
*
)
&
loc
->
cylinders
);
put_fs_long
(
hd
[
MINOR
(
inode
->
i_rdev
)].
start_sect
,
put_fs_long
(
hd
[
MINOR
(
inode
->
i_rdev
)].
start_sect
,
(
long
*
)
&
loc
->
start
);
(
long
*
)
&
loc
->
start
);
...
@@ -815,6 +837,8 @@ static int hd_ioctl(struct inode * inode, struct file * file,
...
@@ -815,6 +837,8 @@ static int hd_ioctl(struct inode * inode, struct file * file,
return
revalidate_hddisk
(
inode
->
i_rdev
,
1
);
return
revalidate_hddisk
(
inode
->
i_rdev
,
1
);
case
HDIO_SETUNMASKINTR
:
case
HDIO_SETUNMASKINTR
:
if
(
!
suser
())
return
-
EACCES
;
if
(
MINOR
(
inode
->
i_rdev
)
&
0x3F
)
return
-
EINVAL
;
if
(
!
arg
)
return
-
EINVAL
;
if
(
!
arg
)
return
-
EINVAL
;
err
=
verify_area
(
VERIFY_READ
,
(
long
*
)
arg
,
sizeof
(
long
));
err
=
verify_area
(
VERIFY_READ
,
(
long
*
)
arg
,
sizeof
(
long
));
if
(
err
)
if
(
err
)
...
@@ -841,7 +865,9 @@ static int hd_ioctl(struct inode * inode, struct file * file,
...
@@ -841,7 +865,9 @@ static int hd_ioctl(struct inode * inode, struct file * file,
case
HDIO_SETMULTCOUNT
:
case
HDIO_SETMULTCOUNT
:
{
{
unsigned
long
flags
;
unsigned
long
flags
;
if
(
!
suser
())
return
-
EACCES
;
if
(
!
arg
)
return
-
EINVAL
;
if
(
!
arg
)
return
-
EINVAL
;
if
(
MINOR
(
inode
->
i_rdev
)
&
0x3F
)
return
-
EINVAL
;
err
=
verify_area
(
VERIFY_READ
,
(
long
*
)
arg
,
sizeof
(
long
));
err
=
verify_area
(
VERIFY_READ
,
(
long
*
)
arg
,
sizeof
(
long
));
if
(
err
)
if
(
err
)
return
err
;
return
err
;
...
@@ -903,7 +929,7 @@ static struct gendisk hd_gendisk = {
...
@@ -903,7 +929,7 @@ static struct gendisk hd_gendisk = {
hd
,
/* hd struct */
hd
,
/* hd struct */
hd_sizes
,
/* block sizes */
hd_sizes
,
/* block sizes */
0
,
/* number */
0
,
/* number */
(
void
*
)
hd
_info
,
/* internal */
(
void
*
)
bios
_info
,
/* internal */
NULL
/* next */
NULL
/* next */
};
};
...
@@ -944,12 +970,12 @@ static void hd_geninit(void)
...
@@ -944,12 +970,12 @@ static void hd_geninit(void)
if
(
!
NR_HD
)
{
if
(
!
NR_HD
)
{
for
(
drive
=
0
;
drive
<
2
;
drive
++
)
{
for
(
drive
=
0
;
drive
<
2
;
drive
++
)
{
hd_info
[
drive
].
cyl
=
*
(
unsigned
short
*
)
BIOS
;
bios_info
[
drive
].
cyl
=
hd_info
[
drive
].
cyl
=
*
(
unsigned
short
*
)
BIOS
;
hd_info
[
drive
].
head
=
*
(
2
+
BIOS
);
bios_info
[
drive
].
head
=
hd_info
[
drive
].
head
=
*
(
2
+
BIOS
);
hd_info
[
drive
].
wpcom
=
*
(
unsigned
short
*
)
(
5
+
BIOS
);
bios_info
[
drive
].
wpcom
=
hd_info
[
drive
].
wpcom
=
*
(
unsigned
short
*
)
(
5
+
BIOS
);
hd_info
[
drive
].
ctl
=
*
(
8
+
BIOS
);
bios_info
[
drive
].
ctl
=
hd_info
[
drive
].
ctl
=
*
(
8
+
BIOS
);
hd_info
[
drive
].
lzone
=
*
(
unsigned
short
*
)
(
12
+
BIOS
);
bios_info
[
drive
].
lzone
=
hd_info
[
drive
].
lzone
=
*
(
unsigned
short
*
)
(
12
+
BIOS
);
hd_info
[
drive
].
sect
=
*
(
14
+
BIOS
);
bios_info
[
drive
].
sect
=
hd_info
[
drive
].
sect
=
*
(
14
+
BIOS
);
#ifdef does_not_work_for_everybody_with_scsi_but_helps_ibm_vp
#ifdef does_not_work_for_everybody_with_scsi_but_helps_ibm_vp
if
(
hd_info
[
drive
].
cyl
&&
NR_HD
==
drive
)
if
(
hd_info
[
drive
].
cyl
&&
NR_HD
==
drive
)
NR_HD
++
;
NR_HD
++
;
...
@@ -988,19 +1014,23 @@ static void hd_geninit(void)
...
@@ -988,19 +1014,23 @@ static void hd_geninit(void)
i
=
NR_HD
;
i
=
NR_HD
;
while
(
i
--
>
0
)
{
while
(
i
--
>
0
)
{
hd
[
i
<<
6
].
nr_sects
=
0
;
hd
[
i
<<
6
].
nr_sects
=
0
;
if
(
hd_info
[
i
].
head
>
16
)
{
if
(
bios_info
[
i
].
head
>
16
)
{
printk
(
"hd.c: ST-506 interface disk with more than 16 heads detected,
\n
"
);
/*
printk
(
" probably due to non-standard sector translation. Giving up.
\n
"
);
* The newer E-IDE BIOSs handle drives larger than 1024
printk
(
" (disk %d: cyl=%d, sect=%d, head=%d)
\n
"
,
i
,
* cylinders by increasing the number of logical heads
hd_info
[
i
].
cyl
,
* to keep the number of logical cylinders below the
hd_info
[
i
].
sect
,
* sacred INT13 limit of 1024 (10 bits). If that is
hd_info
[
i
].
head
);
* what's happening here, we'll find out and correct
if
(
i
+
1
==
NR_HD
)
* it later when "identifying" the drive.
NR_HD
--
;
*/
continue
;
printk
(
"hd.c: IDE/ST-506 disk with more than 16 heads detected.
\n
"
);
printk
(
" (hd%c: cyl=%d, sect=%d, head=%d)
\n
"
,
i
+
'a'
,
bios_info
[
i
].
cyl
,
bios_info
[
i
].
sect
,
bios_info
[
i
].
head
);
}
}
hd
[
i
<<
6
].
nr_sects
=
hd_info
[
i
].
head
*
hd
[
i
<<
6
].
nr_sects
=
bios_info
[
i
].
head
*
hd_info
[
i
].
sect
*
hd
_info
[
i
].
cyl
;
bios_info
[
i
].
sect
*
bios
_info
[
i
].
cyl
;
}
}
if
(
NR_HD
)
{
if
(
NR_HD
)
{
if
(
irqaction
(
HD_IRQ
,
&
hd_sigaction
))
{
if
(
irqaction
(
HD_IRQ
,
&
hd_sigaction
))
{
...
@@ -1043,7 +1073,7 @@ unsigned long hd_init(unsigned long mem_start, unsigned long mem_end)
...
@@ -1043,7 +1073,7 @@ unsigned long hd_init(unsigned long mem_start, unsigned long mem_end)
#define DEVICE_BUSY busy[target]
#define DEVICE_BUSY busy[target]
#define USAGE access_count[target]
#define USAGE access_count[target]
#define CAPACITY (
hd_info[target].head*hd_info[target].sect*hd
_info[target].cyl)
#define CAPACITY (
bios_info[target].head*bios_info[target].sect*bios
_info[target].cyl)
/* We assume that the the bios parameters do not change, so the disk capacity
/* We assume that the the bios parameters do not change, so the disk capacity
will not change */
will not change */
#undef MAYBE_REINIT
#undef MAYBE_REINIT
...
...
drivers/char/mem.c
View file @
eebbb0b8
...
@@ -93,8 +93,6 @@ static int mmap_mem(struct inode * inode, struct file * file, struct vm_area_str
...
@@ -93,8 +93,6 @@ static int mmap_mem(struct inode * inode, struct file * file, struct vm_area_str
return
-
EAGAIN
;
return
-
EAGAIN
;
vma
->
vm_inode
=
inode
;
vma
->
vm_inode
=
inode
;
inode
->
i_count
++
;
inode
->
i_count
++
;
insert_vm_struct
(
current
,
vma
);
merge_segments
(
current
->
mm
->
mmap
);
return
0
;
return
0
;
}
}
...
@@ -167,8 +165,6 @@ static int mmap_zero(struct inode * inode, struct file * file, struct vm_area_st
...
@@ -167,8 +165,6 @@ static int mmap_zero(struct inode * inode, struct file * file, struct vm_area_st
return
-
EINVAL
;
return
-
EINVAL
;
if
(
zeromap_page_range
(
vma
->
vm_start
,
vma
->
vm_end
-
vma
->
vm_start
,
vma
->
vm_page_prot
))
if
(
zeromap_page_range
(
vma
->
vm_start
,
vma
->
vm_end
-
vma
->
vm_start
,
vma
->
vm_page_prot
))
return
-
EAGAIN
;
return
-
EAGAIN
;
insert_vm_struct
(
current
,
vma
);
merge_segments
(
current
->
mm
->
mmap
);
return
0
;
return
0
;
}
}
...
...
drivers/char/psaux.c
View file @
eebbb0b8
...
@@ -25,11 +25,11 @@
...
@@ -25,11 +25,11 @@
/* #define INITIALIZE_DEVICE */
/* #define INITIALIZE_DEVICE */
#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/fcntl.h>
#include <linux/fcntl.h>
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/timer.h>
#include <asm/io.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/segment.h>
...
...
drivers/scsi/aha1542.c
View file @
eebbb0b8
...
@@ -18,6 +18,8 @@
...
@@ -18,6 +18,8 @@
#include <linux/string.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <asm/dma.h>
#include <asm/dma.h>
...
@@ -90,6 +92,20 @@ static int aha1542_restart(struct Scsi_Host * shost);
...
@@ -90,6 +92,20 @@ static int aha1542_restart(struct Scsi_Host * shost);
} \
} \
}
}
/* Similar to WAIT, except we use the udelay call to regulate the
amount of time we wait. */
#define WAITd(port, mask, allof, noneof, timeout) \
{ register WAITbits; \
register WAITtimeout = timeout; \
while (1) { \
WAITbits = inb(port) & (mask); \
if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
break; \
udelay(1000); \
if (--WAITtimeout == 0) goto fail; \
} \
}
static
void
aha1542_stat
(
void
)
static
void
aha1542_stat
(
void
)
{
{
/* int s = inb(STATUS), i = inb(INTRFLAGS);
/* int s = inb(STATUS), i = inb(INTRFLAGS);
...
@@ -145,6 +161,24 @@ static int aha1542_in(unsigned int base, unchar *cmdp, int len)
...
@@ -145,6 +161,24 @@ static int aha1542_in(unsigned int base, unchar *cmdp, int len)
return
1
;
return
1
;
}
}
/* Similar to aha1542_in, except that we wait a very short period of time.
We use this if we know the board is alive and awake, but we are not sure
if the board will respond the the command we are about to send or not */
static
int
aha1542_in1
(
unsigned
int
base
,
unchar
*
cmdp
,
int
len
)
{
cli
();
while
(
len
--
)
{
WAITd
(
STATUS
(
base
),
DF
,
DF
,
0
,
100
);
*
cmdp
++
=
inb
(
DATA
(
base
));
}
sti
();
return
0
;
fail:
sti
();
return
1
;
}
static
int
makecode
(
unsigned
hosterr
,
unsigned
scsierr
)
static
int
makecode
(
unsigned
hosterr
,
unsigned
scsierr
)
{
{
switch
(
hosterr
)
{
switch
(
hosterr
)
{
...
@@ -718,8 +752,9 @@ static int aha1542_mbenable(int base)
...
@@ -718,8 +752,9 @@ static int aha1542_mbenable(int base)
mbenable_cmd
[
0
]
=
CMD_EXTBIOS
;
mbenable_cmd
[
0
]
=
CMD_EXTBIOS
;
aha1542_out
(
base
,
mbenable_cmd
,
1
);
aha1542_out
(
base
,
mbenable_cmd
,
1
);
aha1542_in
(
base
,
mbenable_result
,
2
);
if
(
aha1542_in1
(
base
,
mbenable_result
,
2
))
WAIT
(
INTRFLAGS
(
base
),
INTRMASK
,
HACC
,
0
);
return
retval
;
WAITd
(
INTRFLAGS
(
base
),
INTRMASK
,
HACC
,
0
,
100
);
aha1542_intr_reset
(
base
);
aha1542_intr_reset
(
base
);
if
((
mbenable_result
[
0
]
&
0x08
)
||
mbenable_result
[
1
])
{
if
((
mbenable_result
[
0
]
&
0x08
)
||
mbenable_result
[
1
])
{
...
@@ -770,11 +805,11 @@ static int aha1542_query(int base_io, int * transl)
...
@@ -770,11 +805,11 @@ static int aha1542_query(int base_io, int * transl)
return
1
;
return
1
;
};
};
/*
1542C returns 0x44, 1542CF returns 0x45 */
/*
Always call this - boards that do not support extended bios translation
if
(
inquiry_result
[
0
]
==
0x44
||
inquiry_result
[
0
]
==
0x45
)
will ignore the command, and we will set the proper default */
{
/* Detect 1542C */
*
transl
=
aha1542_mbenable
(
base_io
);
*
transl
=
aha1542_mbenable
(
base_io
);
};
return
0
;
return
0
;
}
}
...
...
drivers/scsi/g_NCR5380.c
View file @
eebbb0b8
...
@@ -55,9 +55,6 @@
...
@@ -55,9 +55,6 @@
* $Log: generic_NCR5380.c,v $
* $Log: generic_NCR5380.c,v $
*/
*/
#include <linux/config.h>
#if defined(CONFIG_SCSI_GENERIC_NCR5380)
/* Standard option */
#define AUTOPROBE_IRQ
#define AUTOPROBE_IRQ
#include <asm/system.h>
#include <asm/system.h>
...
@@ -175,5 +172,3 @@ const char * generic_NCR5380_info (void) {
...
@@ -175,5 +172,3 @@ const char * generic_NCR5380_info (void) {
}
}
#include "NCR5380.c"
#include "NCR5380.c"
#endif
/* defined(CONFIG_SCSI_GENERIC_NCR5380) */
drivers/scsi/hosts.c
View file @
eebbb0b8
...
@@ -161,6 +161,7 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
...
@@ -161,6 +161,7 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
*/
*/
struct
Scsi_Host
*
scsi_hostlist
=
NULL
;
struct
Scsi_Host
*
scsi_hostlist
=
NULL
;
struct
Scsi_Device_Template
*
scsi_devicelist
;
int
max_scsi_hosts
=
0
;
int
max_scsi_hosts
=
0
;
static
int
next_host
=
0
;
static
int
next_host
=
0
;
...
@@ -223,6 +224,15 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
...
@@ -223,6 +224,15 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
return
retval
;
return
retval
;
}
}
int
scsi_register_device
(
struct
Scsi_Device_Template
*
sdpnt
)
{
if
(
sdpnt
->
next
)
panic
(
"Device already registered"
);
sdpnt
->
next
=
scsi_devicelist
;
scsi_devicelist
=
sdpnt
;
return
0
;
}
unsigned
int
scsi_init
()
unsigned
int
scsi_init
()
{
{
static
int
called
=
0
;
static
int
called
=
0
;
...
@@ -263,60 +273,20 @@ unsigned int scsi_init()
...
@@ -263,60 +273,20 @@ unsigned int scsi_init()
}
}
printk
(
"scsi : %d hosts.
\n
"
,
count
);
printk
(
"scsi : %d hosts.
\n
"
,
count
);
/* Now attach the high level drivers */
#ifdef CONFIG_BLK_DEV_SD
scsi_register_device
(
&
sd_template
);
#endif
#ifdef CONFIG_BLK_DEV_SR
scsi_register_device
(
&
sr_template
);
#endif
#ifdef CONFIG_CHR_DEV_ST
scsi_register_device
(
&
st_template
);
#endif
#ifdef CONFIG_CHR_DEV_SG
scsi_register_device
(
&
sg_template
);
#endif
max_scsi_hosts
=
count
;
max_scsi_hosts
=
count
;
return
0
;
return
0
;
}
}
#ifndef CONFIG_BLK_DEV_SD
unsigned
long
sd_init
(
unsigned
long
memory_start
,
unsigned
long
memory_end
){
return
memory_start
;
};
void
sd_init1
(){
return
;
};
void
sd_attach
(
Scsi_Device
*
SDp
){
};
int
NR_SD
=-
1
;
int
MAX_SD
=
0
;
#endif
#ifndef CONFIG_BLK_DEV_SR
unsigned
long
sr_init
(
unsigned
long
memory_start
,
unsigned
long
memory_end
){
return
memory_start
;
};
void
sr_init1
(){
return
;
};
void
sr_attach
(
Scsi_Device
*
SDp
){
};
int
NR_SR
=-
1
;
int
MAX_SR
=
0
;
#endif
#ifndef CONFIG_CHR_DEV_ST
unsigned
long
st_init
(
unsigned
long
memory_start
,
unsigned
long
memory_end
){
return
memory_start
;
};
void
st_init1
(){
return
;
};
void
st_attach
(
Scsi_Device
*
SDp
){
};
int
NR_ST
=-
1
;
int
MAX_ST
=
0
;
#endif
#ifndef CONFIG_CHR_DEV_SG
unsigned
long
sg_init
(
unsigned
long
memory_start
,
unsigned
long
memory_end
){
return
memory_start
;
};
void
sg_init1
(){
return
;
};
void
sg_attach
(
Scsi_Device
*
SDp
){
};
int
NR_SG
=-
1
;
int
MAX_SG
=
0
;
#endif
drivers/scsi/hosts.h
View file @
eebbb0b8
...
@@ -254,6 +254,7 @@ struct Scsi_Host
...
@@ -254,6 +254,7 @@ struct Scsi_Host
};
};
extern
struct
Scsi_Host
*
scsi_hostlist
;
extern
struct
Scsi_Host
*
scsi_hostlist
;
extern
struct
Scsi_Device_Template
*
scsi_devicelist
;
extern
Scsi_Host_Template
*
scsi_hosts
;
extern
Scsi_Host_Template
*
scsi_hosts
;
...
@@ -278,3 +279,28 @@ extern void scsi_unregister(struct Scsi_Host * i);
...
@@ -278,3 +279,28 @@ extern void scsi_unregister(struct Scsi_Host * i);
#define BLANK_HOST {"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define BLANK_HOST {"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#endif
#endif
struct
Scsi_Device_Template
{
struct
Scsi_Device_Template
*
next
;
char
*
name
;
char
*
tag
;
unsigned
char
scsi_type
;
unsigned
char
major
;
unsigned
char
nr_dev
;
/* Number currently attached */
unsigned
char
dev_noticed
;
/* Number of devices detected. */
unsigned
char
dev_max
;
/* Current size of arrays */
unsigned
blk
:
1
;
/* 0 if character device */
int
(
*
detect
)(
Scsi_Device
*
);
/* Returns 1 if we can attach this device */
void
(
*
init
)(
void
);
/* Sizes arrays based upon number of devices detected */
void
(
*
finish
)(
void
);
/* Perform initialization after attachment */
void
(
*
attach
)(
Scsi_Device
*
);
/* Attach devices to arrays */
void
(
*
detach
)(
Scsi_Device
*
);
};
extern
struct
Scsi_Device_Template
sd_template
;
extern
struct
Scsi_Device_Template
st_template
;
extern
struct
Scsi_Device_Template
sr_template
;
extern
struct
Scsi_Device_Template
sg_template
;
int
scsi_register_device
(
struct
Scsi_Device_Template
*
sdpnt
);
drivers/scsi/scsi.c
View file @
eebbb0b8
...
@@ -64,13 +64,10 @@ const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] =
...
@@ -64,13 +64,10 @@ const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] =
/*
/*
global variables :
global variables :
NR_SCSI_DEVICES is the number of SCSI devices we have detected,
scsi_devices an array of these specifing the address for each
scsi_devices an array of these specifing the address for each
(host, id, LUN)
(host, id, LUN)
*/
*/
int
NR_SCSI_DEVICES
=
0
;
Scsi_Device
*
scsi_devices
=
NULL
;
Scsi_Device
*
scsi_devices
=
NULL
;
static
unsigned
char
generic_sense
[
6
]
=
{
REQUEST_SENSE
,
0
,
0
,
0
,
255
,
0
};
static
unsigned
char
generic_sense
[
6
]
=
{
REQUEST_SENSE
,
0
,
0
,
0
,
255
,
0
};
...
@@ -221,6 +218,7 @@ static void scan_scsis (struct Scsi_Host * shpnt)
...
@@ -221,6 +218,7 @@ static void scan_scsis (struct Scsi_Host * shpnt)
unsigned
char
scsi_cmd
[
12
];
unsigned
char
scsi_cmd
[
12
];
unsigned
char
scsi_result
[
256
];
unsigned
char
scsi_result
[
256
];
Scsi_Device
*
SDpnt
,
*
SDtail
;
Scsi_Device
*
SDpnt
,
*
SDtail
;
struct
Scsi_Device_Template
*
sdtpnt
;
Scsi_Cmnd
SCmd
;
Scsi_Cmnd
SCmd
;
++
in_scan
;
++
in_scan
;
...
@@ -249,6 +247,7 @@ static void scan_scsis (struct Scsi_Host * shpnt)
...
@@ -249,6 +247,7 @@ static void scan_scsis (struct Scsi_Host * shpnt)
SDpnt
->
lun
=
lun
;
SDpnt
->
lun
=
lun
;
SDpnt
->
device_wait
=
NULL
;
SDpnt
->
device_wait
=
NULL
;
SDpnt
->
next
=
NULL
;
SDpnt
->
next
=
NULL
;
SDpnt
->
attached
=
0
;
/*
/*
* Assume that the device will have handshaking problems, and then
* Assume that the device will have handshaking problems, and then
* fix this field later if it turns out it doesn't.
* fix this field later if it turns out it doesn't.
...
@@ -381,29 +380,12 @@ static void scan_scsis (struct Scsi_Host * shpnt)
...
@@ -381,29 +380,12 @@ static void scan_scsis (struct Scsi_Host * shpnt)
if
(
type
!=
-
1
)
if
(
type
!=
-
1
)
{
{
struct
Scsi_Device_Template
*
sdtpnt
;
print_inquiry
(
scsi_result
);
print_inquiry
(
scsi_result
);
switch
(
type
){
case
TYPE_TAPE
:
printk
(
"Detected scsi tape st%d at scsi%d, id %d, lun %d
\n
"
,
MAX_ST
,
shpnt
->
host_no
,
dev
,
lun
);
if
(
NR_ST
!=
-
1
)
++
MAX_ST
;
break
;
case
TYPE_ROM
:
printk
(
"Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d
\n
"
,
MAX_SR
,
shpnt
->
host_no
,
dev
,
lun
);
if
(
NR_SR
!=
-
1
)
++
MAX_SR
;
break
;
case
TYPE_DISK
:
case
TYPE_MOD
:
printk
(
"Detected scsi disk sd%c at scsi%d, id %d, lun %d
\n
"
,
'a'
+
MAX_SD
,
shpnt
->
host_no
,
dev
,
lun
);
if
(
NR_SD
!=
-
1
)
++
MAX_SD
;
break
;
default:
break
;
};
if
(
NR_SG
!=
-
1
)
++
MAX_SG
;
for
(
sdtpnt
=
scsi_devicelist
;
sdtpnt
;
sdtpnt
=
sdtpnt
->
next
)
if
(
sdtpnt
->
detect
)
SDpnt
->
attached
+=
(
*
sdtpnt
->
detect
)(
SDpnt
);
SDpnt
->
scsi_level
=
scsi_result
[
2
]
&
0x07
;
SDpnt
->
scsi_level
=
scsi_result
[
2
]
&
0x07
;
if
(
SDpnt
->
scsi_level
>=
2
||
if
(
SDpnt
->
scsi_level
>=
2
||
...
@@ -483,7 +465,6 @@ static void scan_scsis (struct Scsi_Host * shpnt)
...
@@ -483,7 +465,6 @@ static void scan_scsis (struct Scsi_Host * shpnt)
scsi_devices
=
SDpnt
;
scsi_devices
=
SDpnt
;
SDtail
=
SDpnt
;
SDtail
=
SDpnt
;
++
NR_SCSI_DEVICES
;
SDpnt
=
(
Scsi_Device
*
)
scsi_init_malloc
(
sizeof
(
Scsi_Device
));
SDpnt
=
(
Scsi_Device
*
)
scsi_init_malloc
(
sizeof
(
Scsi_Device
));
/* Some scsi devices cannot be polled for lun != 0
/* Some scsi devices cannot be polled for lun != 0
due to firmware bugs */
due to firmware bugs */
...
@@ -501,14 +482,10 @@ static void scan_scsis (struct Scsi_Host * shpnt)
...
@@ -501,14 +482,10 @@ static void scan_scsis (struct Scsi_Host * shpnt)
shpnt
->
host_queue
=
NULL
;
/* No longer needed here */
shpnt
->
host_queue
=
NULL
;
/* No longer needed here */
printk
(
"scsi : detected "
);
printk
(
"scsi : detected "
);
if
(
NR_SD
!=
-
1
)
for
(
sdtpnt
=
scsi_devicelist
;
sdtpnt
;
sdtpnt
=
sdtpnt
->
next
)
printk
(
"%d SCSI disk%s "
,
MAX_SD
,
(
MAX_SD
!=
1
)
?
"s"
:
""
);
if
(
sdtpnt
->
dev_noticed
&&
sdtpnt
->
name
)
printk
(
"%d SCSI %s%s "
,
sdtpnt
->
dev_noticed
,
sdtpnt
->
name
,
if
(
NR_ST
!=
-
1
)
(
sdtpnt
->
dev_noticed
!=
1
)
?
"s"
:
""
);
printk
(
"%d tape%s "
,
MAX_ST
,
(
MAX_ST
!=
1
)
?
"s"
:
""
);
if
(
NR_SR
!=
-
1
)
printk
(
"%d CD-ROM drive%s "
,
MAX_SR
,
(
MAX_SR
!=
1
)
?
"s"
:
""
);
printk
(
"total.
\n
"
);
printk
(
"total.
\n
"
);
...
@@ -1756,6 +1733,7 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
...
@@ -1756,6 +1733,7 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
struct
Scsi_Host
*
host
=
NULL
;
struct
Scsi_Host
*
host
=
NULL
;
Scsi_Device
*
SDpnt
;
Scsi_Device
*
SDpnt
;
struct
Scsi_Host
*
shpnt
;
struct
Scsi_Host
*
shpnt
;
struct
Scsi_Device_Template
*
sdtpnt
;
Scsi_Cmnd
*
SCpnt
;
Scsi_Cmnd
*
SCpnt
;
#ifdef FOO_ON_YOU
#ifdef FOO_ON_YOU
return
;
return
;
...
@@ -1776,29 +1754,14 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
...
@@ -1776,29 +1754,14 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
for
(
shpnt
=
scsi_hostlist
;
shpnt
;
shpnt
=
shpnt
->
next
)
for
(
shpnt
=
scsi_hostlist
;
shpnt
;
shpnt
=
shpnt
->
next
)
scan_scsis
(
shpnt
);
/* scan for scsi devices */
scan_scsis
(
shpnt
);
/* scan for scsi devices */
sd_init1
();
for
(
sdtpnt
=
scsi_devicelist
;
sdtpnt
;
sdtpnt
=
sdtpnt
->
next
)
st_init1
();
if
(
sdtpnt
->
init
&&
sdtpnt
->
dev_noticed
)
(
*
sdtpnt
->
init
)();
sr_init1
();
sg_init1
();
for
(
SDpnt
=
scsi_devices
;
SDpnt
;
SDpnt
=
SDpnt
->
next
)
{
for
(
SDpnt
=
scsi_devices
;
SDpnt
;
SDpnt
=
SDpnt
->
next
)
{
int
j
;
int
j
;
SDpnt
->
scsi_request_fn
=
NULL
;
SDpnt
->
scsi_request_fn
=
NULL
;
switch
(
SDpnt
->
type
)
for
(
sdtpnt
=
scsi_devicelist
;
sdtpnt
;
sdtpnt
=
sdtpnt
->
next
)
{
if
(
sdtpnt
->
attach
)
(
*
sdtpnt
->
attach
)(
SDpnt
);
case
TYPE_TAPE
:
st_attach
(
SDpnt
);
break
;
case
TYPE_ROM
:
sr_attach
(
SDpnt
);
break
;
case
TYPE_DISK
:
case
TYPE_MOD
:
sd_attach
(
SDpnt
);
default:
break
;
};
sg_attach
(
SDpnt
);
if
(
SDpnt
->
type
!=
-
1
){
if
(
SDpnt
->
type
!=
-
1
){
for
(
j
=
0
;
j
<
SDpnt
->
host
->
hostt
->
cmd_per_lun
;
j
++
){
for
(
j
=
0
;
j
<
SDpnt
->
host
->
hostt
->
cmd_per_lun
;
j
++
){
SCpnt
=
(
Scsi_Cmnd
*
)
scsi_init_malloc
(
sizeof
(
Scsi_Cmnd
));
SCpnt
=
(
Scsi_Cmnd
*
)
scsi_init_malloc
(
sizeof
(
Scsi_Cmnd
));
...
@@ -1822,8 +1785,7 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
...
@@ -1822,8 +1785,7 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
};
};
};
};
memory_start
=
scsi_init_memory_start
;
if
(
scsi_devicelist
)
if
(
NR_SD
>
0
||
NR_SR
>
0
||
NR_ST
>
0
)
dma_sectors
=
16
;
/* Base value we use */
dma_sectors
=
16
;
/* Base value we use */
for
(
SDpnt
=
scsi_devices
;
SDpnt
;
SDpnt
=
SDpnt
->
next
)
{
for
(
SDpnt
=
scsi_devices
;
SDpnt
;
SDpnt
=
SDpnt
->
next
)
{
...
@@ -1846,23 +1808,25 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
...
@@ -1846,23 +1808,25 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
dma_sectors
=
(
dma_sectors
+
15
)
&
0xfff0
;
dma_sectors
=
(
dma_sectors
+
15
)
&
0xfff0
;
dma_free_sectors
=
dma_sectors
;
/* This must be a multiple of 16 */
dma_free_sectors
=
dma_sectors
;
/* This must be a multiple of 16 */
memory_start
=
(
memory_start
+
3
)
&
0xfffffffc
;
scsi_init_memory_start
=
(
scsi_init_
memory_start
+
3
)
&
0xfffffffc
;
dma_malloc_freelist
=
(
unsigned
short
*
)
memory_start
;
dma_malloc_freelist
=
(
unsigned
short
*
)
memory_start
+=
dma_sectors
>>
3
;
scsi_init_malloc
(
dma_sectors
>>
3
)
;
memset
(
dma_malloc_freelist
,
0
,
dma_sectors
>>
3
);
memset
(
dma_malloc_freelist
,
0
,
dma_sectors
>>
3
);
if
(
memory_start
&
1
)
memory_start
++
;
/* Some host adapters require
/* Some host adapters require buffers to be word aligned */
buffers to be word aligned */
if
(
scsi_init_memory_start
&
1
)
scsi_init_memory_start
++
;
dma_malloc_buffer
=
(
unsigned
char
*
)
memory_start
;
memory_start
+=
dma_sectors
<<
9
;
dma_malloc_buffer
=
(
unsigned
char
*
)
scsi_init_malloc
(
dma_sectors
<<
9
);
memory_start
=
sd_init
(
memory_start
,
memory_end
);
/* init scsi disks */
/* OK, now we finish the initialization by doing spin-up, read
memory_start
=
st_init
(
memory_start
,
memory_end
);
/* init scsi tapes */
capacity, etc, etc */
memory_start
=
sr_init
(
memory_start
,
memory_end
);
/* init scsi CDROMs */
for
(
sdtpnt
=
scsi_devicelist
;
sdtpnt
;
sdtpnt
=
sdtpnt
->
next
)
memory_start
=
sg_init
(
memory_start
,
memory_end
);
/* init scsi generic */
if
(
sdtpnt
->
finish
&&
sdtpnt
->
nr_dev
)
(
*
sdtpnt
->
finish
)();
scsi_loadable_module_flag
=
1
;
scsi_loadable_module_flag
=
1
;
return
memory_start
;
return
scsi_init_
memory_start
;
}
}
static
void
print_inquiry
(
unsigned
char
*
data
)
static
void
print_inquiry
(
unsigned
char
*
data
)
...
...
drivers/scsi/scsi.h
View file @
eebbb0b8
...
@@ -260,6 +260,7 @@ extern const unsigned char scsi_command_size[8];
...
@@ -260,6 +260,7 @@ extern const unsigned char scsi_command_size[8];
typedef
struct
scsi_device
{
typedef
struct
scsi_device
{
struct
scsi_device
*
next
;
/* Used for linked list */
struct
scsi_device
*
next
;
/* Used for linked list */
unsigned
char
id
,
lun
;
unsigned
char
id
,
lun
;
int
attached
;
/* # of high level drivers attached to this */
int
access_count
;
/* Count of open channels/mounts */
int
access_count
;
/* Count of open channels/mounts */
struct
wait_queue
*
device_wait
;
/* Used to wait if device is busy */
struct
wait_queue
*
device_wait
;
/* Used to wait if device is busy */
struct
Scsi_Host
*
host
;
struct
Scsi_Host
*
host
;
...
@@ -298,7 +299,6 @@ typedef struct scsi_device {
...
@@ -298,7 +299,6 @@ typedef struct scsi_device {
These are the SCSI devices available on the system.
These are the SCSI devices available on the system.
*/
*/
extern
int
NR_SCSI_DEVICES
;
extern
Scsi_Device
*
scsi_devices
;
extern
Scsi_Device
*
scsi_devices
;
/*
/*
Initializes all SCSI devices. This scans all scsi busses.
Initializes all SCSI devices. This scans all scsi busses.
...
@@ -500,22 +500,6 @@ extern Scsi_Cmnd * request_queueable(struct request *, Scsi_Device *);
...
@@ -500,22 +500,6 @@ extern Scsi_Cmnd * request_queueable(struct request *, Scsi_Device *);
extern
int
scsi_reset
(
Scsi_Cmnd
*
);
extern
int
scsi_reset
(
Scsi_Cmnd
*
);
extern
int
max_scsi_hosts
;
extern
int
max_scsi_hosts
;
extern
int
MAX_SD
,
NR_SD
,
MAX_ST
,
NR_ST
,
MAX_SR
,
NR_SR
,
NR_SG
,
MAX_SG
;
extern
unsigned
long
sd_init
(
unsigned
long
,
unsigned
long
);
extern
void
sd_init1
(
void
);
extern
void
sd_attach
(
Scsi_Device
*
);
extern
unsigned
long
sr_init
(
unsigned
long
,
unsigned
long
);
extern
void
sr_init1
(
void
);
extern
void
sr_attach
(
Scsi_Device
*
);
extern
unsigned
long
st_init
(
unsigned
long
,
unsigned
long
);
extern
void
st_init1
(
void
);
extern
void
st_attach
(
Scsi_Device
*
);
extern
unsigned
long
sg_init
(
unsigned
long
,
unsigned
long
);
extern
void
sg_init1
(
void
);
extern
void
sg_attach
(
Scsi_Device
*
);
#if defined(MAJOR_NR) && (MAJOR_NR != SCSI_TAPE_MAJOR)
#if defined(MAJOR_NR) && (MAJOR_NR != SCSI_TAPE_MAJOR)
static
void
end_scsi_request
(
Scsi_Cmnd
*
SCpnt
,
int
uptodate
,
int
sectors
)
static
void
end_scsi_request
(
Scsi_Cmnd
*
SCpnt
,
int
uptodate
,
int
sectors
)
...
...
drivers/scsi/sd.c
View file @
eebbb0b8
...
@@ -46,8 +46,6 @@ static const char RCSid[] = "$Header:";
...
@@ -46,8 +46,6 @@ static const char RCSid[] = "$Header:";
struct
hd_struct
*
sd
;
struct
hd_struct
*
sd
;
int
NR_SD
=
0
;
int
MAX_SD
=
0
;
Scsi_Disk
*
rscsi_disks
;
Scsi_Disk
*
rscsi_disks
;
static
int
*
sd_sizes
;
static
int
*
sd_sizes
;
static
int
*
sd_blocksizes
;
static
int
*
sd_blocksizes
;
...
@@ -61,12 +59,22 @@ static sd_init_onedisk(int);
...
@@ -61,12 +59,22 @@ static sd_init_onedisk(int);
static
void
requeue_sd_request
(
Scsi_Cmnd
*
SCpnt
);
static
void
requeue_sd_request
(
Scsi_Cmnd
*
SCpnt
);
static
void
sd_init
(
void
);
static
void
sd_finish
(
void
);
static
void
sd_attach
(
Scsi_Device
*
);
static
int
sd_detect
(
Scsi_Device
*
);
struct
Scsi_Device_Template
sd_template
=
{
NULL
,
"disk"
,
"sd"
,
TYPE_DISK
,
SCSI_DISK_MAJOR
,
0
,
0
,
0
,
1
,
sd_detect
,
sd_init
,
sd_finish
,
sd_attach
,
NULL
};
static
int
sd_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
static
int
sd_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
{
{
int
target
;
int
target
;
target
=
DEVICE_NR
(
MINOR
(
inode
->
i_rdev
));
target
=
DEVICE_NR
(
MINOR
(
inode
->
i_rdev
));
if
(
target
>=
NR_SD
||
!
rscsi_disks
[
target
].
device
)
if
(
target
>=
sd_template
.
dev_max
||
!
rscsi_disks
[
target
].
device
)
return
-
ENXIO
;
/* No such device */
return
-
ENXIO
;
/* No such device */
/* Make sure that only one process can do a check_change_disk at one time.
/* Make sure that only one process can do a check_change_disk at one time.
...
@@ -135,9 +143,10 @@ static void sd_geninit (void)
...
@@ -135,9 +143,10 @@ static void sd_geninit (void)
{
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
NR_SD
;
++
i
)
for
(
i
=
0
;
i
<
sd_template
.
dev_max
;
++
i
)
if
(
rscsi_disks
[
i
].
device
)
sd
[
i
<<
4
].
nr_sects
=
rscsi_disks
[
i
].
capacity
;
sd
[
i
<<
4
].
nr_sects
=
rscsi_disks
[
i
].
capacity
;
sd_gendisk
.
nr_real
=
NR_SD
;
sd_gendisk
.
nr_real
=
sd_template
.
dev_max
;
}
}
/*
/*
...
@@ -358,7 +367,7 @@ static void do_sd_request (void)
...
@@ -358,7 +367,7 @@ static void do_sd_request (void)
to have the interrupts off when monkeying with the request list, because
to have the interrupts off when monkeying with the request list, because
otherwise the kernel might try and slip in a request inbetween somewhere. */
otherwise the kernel might try and slip in a request inbetween somewhere. */
if
(
!
SCpnt
&&
NR_SD
>
1
){
if
(
!
SCpnt
&&
sd_template
.
nr_dev
>
1
){
struct
request
*
req1
;
struct
request
*
req1
;
req1
=
NULL
;
req1
=
NULL
;
cli
();
cli
();
...
@@ -410,7 +419,9 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt)
...
@@ -410,7 +419,9 @@ static void requeue_sd_request (Scsi_Cmnd * SCpnt)
printk
(
"Doing sd request, dev = %d, block = %d
\n
"
,
dev
,
block
);
printk
(
"Doing sd request, dev = %d, block = %d
\n
"
,
dev
,
block
);
#endif
#endif
if
(
dev
>=
(
NR_SD
<<
4
)
||
block
+
SCpnt
->
request
.
nr_sectors
>
sd
[
dev
].
nr_sects
)
if
(
dev
>=
(
sd_template
.
dev_max
<<
4
)
||
!
rscsi_disks
[
DEVICE_NR
(
dev
)].
device
||
block
+
SCpnt
->
request
.
nr_sectors
>
sd
[
dev
].
nr_sects
)
{
{
end_scsi_request
(
SCpnt
,
0
,
SCpnt
->
request
.
nr_sectors
);
end_scsi_request
(
SCpnt
,
0
,
SCpnt
->
request
.
nr_sectors
);
goto
repeat
;
goto
repeat
;
...
@@ -747,7 +758,8 @@ static int check_scsidisk_media_change(dev_t full_dev){
...
@@ -747,7 +758,8 @@ static int check_scsidisk_media_change(dev_t full_dev){
target
=
DEVICE_NR
(
MINOR
(
full_dev
));
target
=
DEVICE_NR
(
MINOR
(
full_dev
));
if
(
target
>=
NR_SD
)
{
if
(
target
>=
sd_template
.
dev_max
||
!
rscsi_disks
[
target
].
device
)
{
printk
(
"SCSI disk request error: invalid device.
\n
"
);
printk
(
"SCSI disk request error: invalid device.
\n
"
);
return
0
;
return
0
;
};
};
...
@@ -957,11 +969,8 @@ static int sd_init_onedisk(int i)
...
@@ -957,11 +969,8 @@ static int sd_init_onedisk(int i)
rscsi_disks
[
i
].
capacity
=
0
;
rscsi_disks
[
i
].
capacity
=
0
;
}
else
{
}
else
{
printk
(
"scsi : deleting disk entry.
\n
"
);
printk
(
"scsi : deleting disk entry.
\n
"
);
for
(
j
=
i
;
j
<
NR_SD
-
1
;)
rscsi_disks
[
j
].
device
=
NULL
;
rscsi_disks
[
j
]
=
rscsi_disks
[
++
j
];
sd_template
.
nr_dev
--
;
--
i
;
--
NR_SD
;
scsi_free
(
buffer
,
512
);
return
i
;
return
i
;
};
};
}
}
...
@@ -983,35 +992,55 @@ static int sd_init_onedisk(int i)
...
@@ -983,35 +992,55 @@ static int sd_init_onedisk(int i)
*/
*/
unsigned
long
sd_init
(
unsigned
long
memory_start
,
unsigned
long
memory_end
)
static
void
sd_init
(
)
{
{
int
i
;
int
i
;
static
int
sd_registered
=
0
;
if
(
sd_template
.
dev_noticed
==
0
)
return
;
if
(
!
sd_registered
)
{
if
(
register_blkdev
(
MAJOR_NR
,
"sd"
,
&
sd_fops
))
{
if
(
register_blkdev
(
MAJOR_NR
,
"sd"
,
&
sd_fops
))
{
printk
(
"Unable to get major %d for SCSI disk
\n
"
,
MAJOR_NR
);
printk
(
"Unable to get major %d for SCSI disk
\n
"
,
MAJOR_NR
);
return
memory_start
;
return
;
}
sd_registered
++
;
}
}
if
(
MAX_SD
==
0
)
return
memory_start
;
sd_sizes
=
(
int
*
)
memory_start
;
/* We do not support attaching loadable devices yet. */
memory_start
+=
(
MAX_SD
<<
4
)
*
sizeof
(
int
);
if
(
scsi_loadable_module_flag
)
return
;
memset
(
sd_sizes
,
0
,
(
MAX_SD
<<
4
)
*
sizeof
(
int
));
sd_template
.
dev_max
=
sd_template
.
dev_noticed
;
sd_blocksizes
=
(
int
*
)
memory_start
;
rscsi_disks
=
(
Scsi_Disk
*
)
memory_start
+=
(
MAX_SD
<<
4
)
*
sizeof
(
int
);
scsi_init_malloc
(
sd_template
.
dev_max
*
sizeof
(
Scsi_Disk
));
for
(
i
=
0
;
i
<
(
MAX_SD
<<
4
);
i
++
)
sd_blocksizes
[
i
]
=
1024
;
sd_sizes
=
(
int
*
)
scsi_init_malloc
((
sd_template
.
dev_max
<<
4
)
*
sizeof
(
int
));
memset
(
sd_sizes
,
0
,
(
sd_template
.
dev_max
<<
4
)
*
sizeof
(
int
));
sd_blocksizes
=
(
int
*
)
scsi_init_malloc
((
sd_template
.
dev_max
<<
4
)
*
sizeof
(
int
));
for
(
i
=
0
;
i
<
(
sd_template
.
dev_max
<<
4
);
i
++
)
sd_blocksizes
[
i
]
=
1024
;
blksize_size
[
MAJOR_NR
]
=
sd_blocksizes
;
blksize_size
[
MAJOR_NR
]
=
sd_blocksizes
;
sd
=
(
struct
hd_struct
*
)
memory_start
;
sd
=
(
struct
hd_struct
*
)
scsi_init_malloc
((
sd_template
.
dev_max
<<
4
)
*
memory_start
+=
(
MAX_SD
<<
4
)
*
sizeof
(
struct
hd_struct
);
sizeof
(
struct
hd_struct
)
);
sd_gendisk
.
max_nr
=
MAX_SD
;
sd_gendisk
.
max_nr
=
sd_template
.
dev_max
;
sd_gendisk
.
part
=
sd
;
sd_gendisk
.
part
=
sd
;
sd_gendisk
.
sizes
=
sd_sizes
;
sd_gendisk
.
sizes
=
sd_sizes
;
sd_gendisk
.
real_devices
=
(
void
*
)
rscsi_disks
;
sd_gendisk
.
real_devices
=
(
void
*
)
rscsi_disks
;
for
(
i
=
0
;
i
<
NR_SD
;
++
i
)
}
i
=
sd_init_onedisk
(
i
);
static
void
sd_finish
()
{
int
i
;
for
(
i
=
0
;
i
<
sd_template
.
dev_max
;
++
i
)
if
(
rscsi_disks
[
i
].
device
)
i
=
sd_init_onedisk
(
i
);
blk_dev
[
MAJOR_NR
].
request_fn
=
DEVICE_REQUEST
;
blk_dev
[
MAJOR_NR
].
request_fn
=
DEVICE_REQUEST
;
...
@@ -1026,17 +1055,41 @@ unsigned long sd_init(unsigned long memory_start, unsigned long memory_end)
...
@@ -1026,17 +1055,41 @@ unsigned long sd_init(unsigned long memory_start, unsigned long memory_end)
sd_gendisk
.
next
=
gendisk_head
;
sd_gendisk
.
next
=
gendisk_head
;
gendisk_head
=
&
sd_gendisk
;
gendisk_head
=
&
sd_gendisk
;
return
memory_start
;
return
;
}
}
void
sd_init1
(){
static
int
sd_detect
(
Scsi_Device
*
SDp
){
rscsi_disks
=
(
Scsi_Disk
*
)
scsi_init_malloc
(
MAX_SD
*
sizeof
(
Scsi_Disk
));
/* We do not support attaching loadable devices yet. */
};
if
(
scsi_loadable_module_flag
)
return
0
;
if
(
SDp
->
type
!=
TYPE_DISK
&&
SDp
->
type
!=
TYPE_MOD
)
return
0
;
printk
(
"Detected scsi disk sd%c at scsi%d, id %d, lun %d
\n
"
,
'a'
+
(
sd_template
.
dev_noticed
++
),
SDp
->
host
->
host_no
,
SDp
->
id
,
SDp
->
lun
);
return
1
;
}
static
void
sd_attach
(
Scsi_Device
*
SDp
){
Scsi_Disk
*
dpnt
;
int
i
;
/* We do not support attaching loadable devices yet. */
if
(
scsi_loadable_module_flag
)
return
;
if
(
SDp
->
type
!=
TYPE_DISK
&&
SDp
->
type
!=
TYPE_MOD
)
return
;
if
(
sd_template
.
nr_dev
>=
sd_template
.
dev_max
)
panic
(
"scsi_devices corrupt (sd)"
);
for
(
dpnt
=
rscsi_disks
,
i
=
0
;
i
<
sd_template
.
dev_max
;
i
++
,
dpnt
++
)
if
(
!
dpnt
->
device
)
break
;
if
(
i
>=
sd_template
.
dev_max
)
panic
(
"scsi_devices corrupt (sd)"
);
void
sd_attach
(
Scsi_Device
*
SDp
){
SDp
->
scsi_request_fn
=
do_sd_request
;
SDp
->
scsi_request_fn
=
do_sd_request
;
rscsi_disks
[
NR_SD
++
].
device
=
SDp
;
rscsi_disks
[
i
].
device
=
SDp
;
if
(
NR_SD
>
MAX_SD
)
panic
(
"scsi_devices corrupt (sd)"
)
;
sd_template
.
nr_dev
++
;
};
};
#define DEVICE_BUSY rscsi_disks[target].device->busy
#define DEVICE_BUSY rscsi_disks[target].device->busy
...
...
drivers/scsi/seagate.c
View file @
eebbb0b8
...
@@ -46,9 +46,7 @@
...
@@ -46,9 +46,7 @@
* transfer rate if handshaking isn't working correctly.
* transfer rate if handshaking isn't working correctly.
*/
*/
#include <linux/config.h>
#if defined(CONFIG_SCSI_SEAGATE) || defined(CONFIG_SCSI_FD_8xx)
#include <asm/io.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/system.h>
#include <linux/signal.h>
#include <linux/signal.h>
...
@@ -1697,5 +1695,3 @@ printk("scsi%d : heads = %d cylinders = %d sectors = %d total = %d formatted = %
...
@@ -1697,5 +1695,3 @@ printk("scsi%d : heads = %d cylinders = %d sectors = %d total = %d formatted = %
return
result
;
return
result
;
}
}
#endif
/* defined(CONFIG_SCSI_SEGATE) */
drivers/scsi/sg.c
View file @
eebbb0b8
...
@@ -21,11 +21,19 @@
...
@@ -21,11 +21,19 @@
#include "../block/blk.h"
#include "../block/blk.h"
#include "scsi.h"
#include "scsi.h"
#include "hosts.h"
#include "scsi_ioctl.h"
#include "scsi_ioctl.h"
#include "sg.h"
#include "sg.h"
int
NR_SG
=
0
;
static
void
sg_init
(
void
);
int
MAX_SG
=
0
;
static
void
sg_attach
(
Scsi_Device
*
);
static
int
sg_detect
(
Scsi_Device
*
);
struct
Scsi_Device_Template
sg_template
=
{
NULL
,
NULL
,
"sg"
,
0xff
,
SCSI_GENERIC_MAJOR
,
0
,
0
,
0
,
0
,
sg_detect
,
sg_init
,
NULL
,
sg_attach
,
NULL
};
#ifdef SG_BIG_BUFF
#ifdef SG_BIG_BUFF
static
char
*
big_buff
;
static
char
*
big_buff
;
...
@@ -55,7 +63,7 @@ static int sg_ioctl(struct inode * inode,struct file * file,
...
@@ -55,7 +63,7 @@ static int sg_ioctl(struct inode * inode,struct file * file,
unsigned
int
cmd_in
,
unsigned
long
arg
)
unsigned
int
cmd_in
,
unsigned
long
arg
)
{
{
int
dev
=
MINOR
(
inode
->
i_rdev
);
int
dev
=
MINOR
(
inode
->
i_rdev
);
if
((
dev
<
0
)
||
(
dev
>=
NR_SG
))
if
((
dev
<
0
)
||
(
dev
>=
sg_template
.
dev_max
))
return
-
ENXIO
;
return
-
ENXIO
;
switch
(
cmd_in
)
switch
(
cmd_in
)
{
{
...
@@ -73,7 +81,7 @@ static int sg_open(struct inode * inode, struct file * filp)
...
@@ -73,7 +81,7 @@ static int sg_open(struct inode * inode, struct file * filp)
{
{
int
dev
=
MINOR
(
inode
->
i_rdev
);
int
dev
=
MINOR
(
inode
->
i_rdev
);
int
flags
=
filp
->
f_flags
;
int
flags
=
filp
->
f_flags
;
if
(
dev
>=
NR_SG
)
if
(
dev
>=
sg_template
.
dev_max
||
!
scsi_generics
[
dev
].
device
)
return
-
ENXIO
;
return
-
ENXIO
;
if
(
O_RDWR
!=
(
flags
&
O_ACCMODE
))
if
(
O_RDWR
!=
(
flags
&
O_ACCMODE
))
return
-
EACCES
;
return
-
EACCES
;
...
@@ -295,45 +303,70 @@ static struct file_operations sg_fops = {
...
@@ -295,45 +303,70 @@ static struct file_operations sg_fops = {
};
};
static
int
sg_detect
(
Scsi_Device
*
SDp
){
/* We do not support attaching loadable devices yet. */
if
(
scsi_loadable_module_flag
)
return
0
;
++
sg_template
.
dev_noticed
;
return
1
;
}
/* Driver initialization */
/* Driver initialization */
unsigned
long
sg_init
(
unsigned
long
mem_start
,
unsigned
long
mem_end
)
static
void
sg_init
(
)
{
{
static
int
sg_registered
=
0
;
if
(
sg_template
.
dev_noticed
==
0
)
return
;
if
(
!
sg_registered
)
{
if
(
register_chrdev
(
SCSI_GENERIC_MAJOR
,
"sg"
,
&
sg_fops
))
if
(
register_chrdev
(
SCSI_GENERIC_MAJOR
,
"sg"
,
&
sg_fops
))
{
{
printk
(
"Unable to get major %d for generic SCSI device
\n
"
,
printk
(
"Unable to get major %d for generic SCSI device
\n
"
,
SCSI_GENERIC_MAJOR
);
SCSI_GENERIC_MAJOR
);
return
mem_start
;
return
;
}
sg_registered
++
;
}
}
if
(
NR_SG
==
0
)
return
mem_start
;
/* We do not support attaching loadable devices yet. */
if
(
scsi_loadable_module_flag
)
return
;
#ifdef DEBUG
#ifdef DEBUG
printk
(
"sg: Init generic device.
\n
"
);
printk
(
"sg: Init generic device.
\n
"
);
#endif
#endif
#ifdef SG_BIG_BUFF
#ifdef SG_BIG_BUFF
big_buff
=
(
char
*
)
mem_start
;
big_buff
=
(
char
*
)
scsi_init_malloc
(
SG_BIG_BUFF
);
mem_start
+=
SG_BIG_BUFF
;
#endif
#endif
return
mem_start
;
}
void
sg_init1
()
{
scsi_generics
=
(
struct
scsi_generic
*
)
scsi_generics
=
(
struct
scsi_generic
*
)
scsi_init_malloc
(
MAX_SG
*
sizeof
(
struct
scsi_generic
));
scsi_init_malloc
(
sg_template
.
dev_noticed
*
sizeof
(
struct
scsi_generic
));
};
sg_template
.
dev_max
=
sg_template
.
dev_noticed
;
}
void
sg_attach
(
Scsi_Device
*
SDp
)
static
void
sg_attach
(
Scsi_Device
*
SDp
)
{
{
if
(
NR_SG
>=
MAX_SG
)
struct
scsi_generic
*
gpnt
;
int
i
;
/* We do not support attaching loadable devices yet. */
if
(
scsi_loadable_module_flag
)
return
;
if
(
sg_template
.
nr_dev
>=
sg_template
.
dev_max
)
panic
(
"scsi_devices corrupt (sg)"
);
panic
(
"scsi_devices corrupt (sg)"
);
scsi_generics
[
NR_SG
].
device
=
SDp
;
scsi_generics
[
NR_SG
].
users
=
0
;
for
(
gpnt
=
scsi_generics
,
i
=
0
;
i
<
sg_template
.
dev_max
;
i
++
,
gpnt
++
)
scsi_generics
[
NR_SG
].
generic_wait
=
NULL
;
if
(
!
gpnt
->
device
)
break
;
scsi_generics
[
NR_SG
].
read_wait
=
NULL
;
scsi_generics
[
NR_SG
].
write_wait
=
NULL
;
if
(
i
>=
sg_template
.
dev_max
)
panic
(
"scsi_devices corrupt (sg)"
);
scsi_generics
[
NR_SG
].
exclude
=
0
;
scsi_generics
[
NR_SG
].
pending
=
0
;
scsi_generics
[
i
].
device
=
SDp
;
scsi_generics
[
NR_SG
].
timeout
=
SG_DEFAULT_TIMEOUT
;
scsi_generics
[
i
].
users
=
0
;
NR_SG
++
;
scsi_generics
[
i
].
generic_wait
=
NULL
;
scsi_generics
[
i
].
read_wait
=
NULL
;
scsi_generics
[
i
].
write_wait
=
NULL
;
scsi_generics
[
i
].
exclude
=
0
;
scsi_generics
[
i
].
pending
=
0
;
scsi_generics
[
i
].
timeout
=
SG_DEFAULT_TIMEOUT
;
sg_template
.
nr_dev
++
;
};
};
drivers/scsi/sr.c
View file @
eebbb0b8
...
@@ -29,11 +29,19 @@
...
@@ -29,11 +29,19 @@
#include "scsi_ioctl.h"
/* For the door lock/unlock commands */
#include "scsi_ioctl.h"
/* For the door lock/unlock commands */
#include "constants.h"
#include "constants.h"
#define MAX_RETRIES 1
#define MAX_RETRIES 3
#define SR_TIMEOUT 500
#define SR_TIMEOUT 5000
static
void
sr_init
(
void
);
static
void
sr_finish
(
void
);
static
void
sr_attach
(
Scsi_Device
*
);
static
int
sr_detect
(
Scsi_Device
*
);
struct
Scsi_Device_Template
sr_template
=
{
NULL
,
"cdrom"
,
"sr"
,
TYPE_ROM
,
SCSI_CDROM_MAJOR
,
0
,
0
,
0
,
1
,
sr_detect
,
sr_init
,
sr_finish
,
sr_attach
,
NULL
};
int
NR_SR
=
0
;
int
MAX_SR
=
0
;
Scsi_CD
*
scsi_CDs
;
Scsi_CD
*
scsi_CDs
;
static
int
*
sr_sizes
;
static
int
*
sr_sizes
;
...
@@ -88,7 +96,7 @@ int check_cdrom_media_change(dev_t full_dev){
...
@@ -88,7 +96,7 @@ int check_cdrom_media_change(dev_t full_dev){
target
=
MINOR
(
full_dev
);
target
=
MINOR
(
full_dev
);
if
(
target
>=
NR_SR
)
{
if
(
target
>=
sr_template
.
nr_dev
)
{
printk
(
"CD-ROM request error: invalid device.
\n
"
);
printk
(
"CD-ROM request error: invalid device.
\n
"
);
return
0
;
return
0
;
};
};
...
@@ -265,7 +273,7 @@ static void rw_intr (Scsi_Cmnd * SCpnt)
...
@@ -265,7 +273,7 @@ static void rw_intr (Scsi_Cmnd * SCpnt)
static
int
sr_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
static
int
sr_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
{
{
if
(
MINOR
(
inode
->
i_rdev
)
>=
NR_SR
||
if
(
MINOR
(
inode
->
i_rdev
)
>=
sr_template
.
nr_dev
||
!
scsi_CDs
[
MINOR
(
inode
->
i_rdev
)].
device
)
return
-
ENXIO
;
/* No such device */
!
scsi_CDs
[
MINOR
(
inode
->
i_rdev
)].
device
)
return
-
ENXIO
;
/* No such device */
if
(
filp
->
f_mode
&
2
)
if
(
filp
->
f_mode
&
2
)
...
@@ -321,7 +329,7 @@ static void do_sr_request (void)
...
@@ -321,7 +329,7 @@ static void do_sr_request (void)
to have the interrupts off when monkeying with the request list, because
to have the interrupts off when monkeying with the request list, because
otherwise the kernel might try and slip in a request inbetween somewhere. */
otherwise the kernel might try and slip in a request inbetween somewhere. */
if
(
!
SCpnt
&&
NR_SR
>
1
){
if
(
!
SCpnt
&&
sr_template
.
nr_dev
>
1
){
struct
request
*
req1
;
struct
request
*
req1
;
req1
=
NULL
;
req1
=
NULL
;
cli
();
cli
();
...
@@ -371,7 +379,7 @@ void requeue_sr_request (Scsi_Cmnd * SCpnt)
...
@@ -371,7 +379,7 @@ void requeue_sr_request (Scsi_Cmnd * SCpnt)
buffer
=
NULL
;
buffer
=
NULL
;
this_count
=
0
;
this_count
=
0
;
if
(
dev
>=
NR_SR
)
if
(
dev
>=
sr_template
.
nr_dev
)
{
{
/* printk("CD-ROM request error: invalid device.\n"); */
/* printk("CD-ROM request error: invalid device.\n"); */
end_scsi_request
(
SCpnt
,
0
,
SCpnt
->
request
.
nr_sectors
);
end_scsi_request
(
SCpnt
,
0
,
SCpnt
->
request
.
nr_sectors
);
...
@@ -610,14 +618,14 @@ are any multiple of 512 bytes long. */
...
@@ -610,14 +618,14 @@ are any multiple of 512 bytes long. */
}
}
#ifdef DEBUG
#ifdef DEBUG
{
{
int
i
;
int
i
;
printk
(
"ReadCD: %d %d %d %d
\n
"
,
block
,
realcount
,
buffer
,
this_count
);
printk
(
"ReadCD: %d %d %d %d
\n
"
,
block
,
realcount
,
buffer
,
this_count
);
printk
(
"Use sg: %d
\n
"
,
SCpnt
->
use_sg
);
printk
(
"Use sg: %d
\n
"
,
SCpnt
->
use_sg
);
printk
(
"Dumping command: "
);
printk
(
"Dumping command: "
);
for
(
i
=
0
;
i
<
12
;
i
++
)
printk
(
"%2.2x "
,
cmd
[
i
]);
for
(
i
=
0
;
i
<
12
;
i
++
)
printk
(
"%2.2x "
,
cmd
[
i
]);
printk
(
"
\n
"
);
printk
(
"
\n
"
);
};
};
#endif
#endif
SCpnt
->
this_count
=
this_count
;
SCpnt
->
this_count
=
this_count
;
...
@@ -626,15 +634,43 @@ are any multiple of 512 bytes long. */
...
@@ -626,15 +634,43 @@ are any multiple of 512 bytes long. */
rw_intr
,
SR_TIMEOUT
,
MAX_RETRIES
);
rw_intr
,
SR_TIMEOUT
,
MAX_RETRIES
);
}
}
void
sr_init1
(){
static
int
sr_detect
(
Scsi_Device
*
SDp
){
scsi_CDs
=
(
Scsi_CD
*
)
scsi_init_malloc
(
MAX_SR
*
sizeof
(
Scsi_CD
));
};
/* We do not support attaching loadable devices yet. */
if
(
scsi_loadable_module_flag
)
return
0
;
if
(
SDp
->
type
!=
TYPE_ROM
&&
SDp
->
type
!=
TYPE_WORM
)
return
0
;
printk
(
"Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d
\n
"
,
++
sr_template
.
dev_noticed
,
SDp
->
host
->
host_no
,
SDp
->
id
,
SDp
->
lun
);
return
1
;
}
static
void
sr_attach
(
Scsi_Device
*
SDp
){
Scsi_CD
*
cpnt
;
int
i
;
/* We do not support attaching loadable devices yet. */
if
(
scsi_loadable_module_flag
)
return
;
if
(
SDp
->
type
!=
TYPE_ROM
&&
SDp
->
type
!=
TYPE_WORM
)
return
;
if
(
sr_template
.
nr_dev
>=
sr_template
.
dev_max
)
panic
(
"scsi_devices corrupt (sr)"
);
for
(
cpnt
=
scsi_CDs
,
i
=
0
;
i
<
sr_template
.
dev_max
;
i
++
,
cpnt
++
)
if
(
!
cpnt
->
device
)
break
;
if
(
i
>=
sr_template
.
dev_max
)
panic
(
"scsi_devices corrupt (sr)"
);
void
sr_attach
(
Scsi_Device
*
SDp
){
SDp
->
scsi_request_fn
=
do_sr_request
;
SDp
->
scsi_request_fn
=
do_sr_request
;
scsi_CDs
[
NR_SR
++
].
device
=
SDp
;
scsi_CDs
[
i
].
device
=
SDp
;
if
(
NR_SR
>
MAX_SR
)
panic
(
"scsi_devices corrupt (sr)"
);
sr_template
.
nr_dev
++
;
};
if
(
sr_template
.
nr_dev
>
sr_template
.
dev_max
)
panic
(
"scsi_devices corrupt (sr)"
);
}
static
void
sr_init_done
(
Scsi_Cmnd
*
SCpnt
)
static
void
sr_init_done
(
Scsi_Cmnd
*
SCpnt
)
{
{
...
@@ -713,26 +749,41 @@ static void get_sectorsize(int i){
...
@@ -713,26 +749,41 @@ static void get_sectorsize(int i){
};
};
}
}
unsigned
long
sr_init
(
unsigned
long
memory_start
,
unsigned
long
memory_end
)
static
void
sr_init
(
)
{
{
int
i
;
int
i
;
static
int
sr_registered
=
0
;
if
(
sr_template
.
dev_noticed
==
0
)
return
;
if
(
!
sr_registered
)
{
if
(
register_blkdev
(
MAJOR_NR
,
"sr"
,
&
sr_fops
))
{
if
(
register_blkdev
(
MAJOR_NR
,
"sr"
,
&
sr_fops
))
{
printk
(
"Unable to get major %d for SCSI-CD
\n
"
,
MAJOR_NR
);
printk
(
"Unable to get major %d for SCSI-CD
\n
"
,
MAJOR_NR
);
return
memory_start
;
return
;
}
}
}
if
(
MAX_SR
==
0
)
return
memory_start
;
sr_sizes
=
(
int
*
)
memory_start
;
/* We do not support attaching loadable devices yet. */
memory_start
+=
MAX_SR
*
sizeof
(
int
);
if
(
scsi_loadable_module_flag
)
return
;
memset
(
sr_sizes
,
0
,
MAX_SR
*
sizeof
(
int
));
sr_blocksizes
=
(
int
*
)
memory_start
;
sr_template
.
dev_max
=
sr_template
.
dev_noticed
;
memory_start
+=
MAX_SR
*
sizeof
(
int
);
scsi_CDs
=
(
Scsi_CD
*
)
scsi_init_malloc
(
sr_template
.
dev_max
*
sizeof
(
Scsi_CD
));
for
(
i
=
0
;
i
<
MAX_SR
;
i
++
)
sr_blocksizes
[
i
]
=
2048
;
sr_sizes
=
(
int
*
)
scsi_init_malloc
(
sr_template
.
dev_max
*
sizeof
(
int
));
memset
(
sr_sizes
,
0
,
sr_template
.
dev_max
*
sizeof
(
int
));
sr_blocksizes
=
(
int
*
)
scsi_init_malloc
(
sr_template
.
dev_max
*
sizeof
(
int
));
for
(
i
=
0
;
i
<
sr_template
.
dev_max
;
i
++
)
sr_blocksizes
[
i
]
=
2048
;
blksize_size
[
MAJOR_NR
]
=
sr_blocksizes
;
blksize_size
[
MAJOR_NR
]
=
sr_blocksizes
;
for
(
i
=
0
;
i
<
NR_SR
;
++
i
)
}
void
sr_finish
()
{
int
i
;
for
(
i
=
0
;
i
<
sr_template
.
nr_dev
;
++
i
)
{
{
get_sectorsize
(
i
);
get_sectorsize
(
i
);
printk
(
"Scd sectorsize = %d bytes
\n
"
,
scsi_CDs
[
i
].
sector_size
);
printk
(
"Scd sectorsize = %d bytes
\n
"
,
scsi_CDs
[
i
].
sector_size
);
...
@@ -753,5 +804,5 @@ unsigned long sr_init(unsigned long memory_start, unsigned long memory_end)
...
@@ -753,5 +804,5 @@ unsigned long sr_init(unsigned long memory_start, unsigned long memory_end)
else
else
read_ahead
[
MAJOR_NR
]
=
4
;
/* 4 sector read-ahead */
read_ahead
[
MAJOR_NR
]
=
4
;
/* 4 sector read-ahead */
return
memory_start
;
return
;
}
}
drivers/scsi/sr_ioctl.c
View file @
eebbb0b8
...
@@ -96,7 +96,9 @@ int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne
...
@@ -96,7 +96,9 @@ int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne
int
result
,
target
,
err
;
int
result
,
target
,
err
;
target
=
MINOR
(
dev
);
target
=
MINOR
(
dev
);
if
(
target
>=
NR_SR
)
return
-
ENXIO
;
if
(
target
>=
sr_template
.
nr_dev
||
!
scsi_CDs
[
target
].
device
)
return
-
ENXIO
;
switch
(
cmd
)
switch
(
cmd
)
{
{
...
...
drivers/scsi/st.c
View file @
eebbb0b8
...
@@ -28,6 +28,7 @@
...
@@ -28,6 +28,7 @@
#define MAJOR_NR SCSI_TAPE_MAJOR
#define MAJOR_NR SCSI_TAPE_MAJOR
#include "../block/blk.h"
#include "../block/blk.h"
#include "scsi.h"
#include "scsi.h"
#include "hosts.h"
#include "scsi_ioctl.h"
#include "scsi_ioctl.h"
#include "st.h"
#include "st.h"
#include "constants.h"
#include "constants.h"
...
@@ -83,8 +84,15 @@ static int st_write_threshold = ST_WRITE_THRESHOLD;
...
@@ -83,8 +84,15 @@ static int st_write_threshold = ST_WRITE_THRESHOLD;
static
int
st_max_buffers
=
ST_MAX_BUFFERS
;
static
int
st_max_buffers
=
ST_MAX_BUFFERS
;
static
Scsi_Tape
*
scsi_tapes
;
static
Scsi_Tape
*
scsi_tapes
;
int
NR_ST
=
0
;
int
MAX_ST
=
0
;
static
void
st_init
(
void
);
static
void
st_attach
(
Scsi_Device
*
);
static
int
st_detect
(
Scsi_Device
*
);
struct
Scsi_Device_Template
st_template
=
{
NULL
,
"tape"
,
"st"
,
TYPE_TAPE
,
SCSI_TAPE_MAJOR
,
0
,
0
,
0
,
0
,
st_detect
,
st_init
,
NULL
,
st_attach
,
NULL
};
static
int
st_int_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
static
int
st_int_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd_in
,
unsigned
long
arg
);
unsigned
int
cmd_in
,
unsigned
long
arg
);
...
@@ -146,7 +154,7 @@ st_sleep_done (Scsi_Cmnd * SCpnt)
...
@@ -146,7 +154,7 @@ st_sleep_done (Scsi_Cmnd * SCpnt)
int
st_nbr
,
remainder
;
int
st_nbr
,
remainder
;
Scsi_Tape
*
STp
;
Scsi_Tape
*
STp
;
if
((
st_nbr
=
SCpnt
->
request
.
dev
)
<
NR_ST
&&
st_nbr
>=
0
)
{
if
((
st_nbr
=
SCpnt
->
request
.
dev
)
<
st_template
.
nr_dev
&&
st_nbr
>=
0
)
{
STp
=
&
(
scsi_tapes
[
st_nbr
]);
STp
=
&
(
scsi_tapes
[
st_nbr
]);
if
((
STp
->
buffer
)
->
writing
&&
if
((
STp
->
buffer
)
->
writing
&&
(
SCpnt
->
sense_buffer
[
0
]
&
0x70
)
==
0x70
&&
(
SCpnt
->
sense_buffer
[
0
]
&
0x70
)
==
0x70
&&
...
@@ -381,7 +389,7 @@ scsi_tape_open(struct inode * inode, struct file * filp)
...
@@ -381,7 +389,7 @@ scsi_tape_open(struct inode * inode, struct file * filp)
Scsi_Tape
*
STp
;
Scsi_Tape
*
STp
;
dev
=
MINOR
(
inode
->
i_rdev
)
&
127
;
dev
=
MINOR
(
inode
->
i_rdev
)
&
127
;
if
(
dev
>=
NR_ST
)
if
(
dev
>=
st_template
.
dev_max
||
!
scsi_tapes
[
dev
].
device
)
return
(
-
ENXIO
);
return
(
-
ENXIO
);
STp
=
&
(
scsi_tapes
[
dev
]);
STp
=
&
(
scsi_tapes
[
dev
]);
if
(
STp
->
in_use
)
{
if
(
STp
->
in_use
)
{
...
@@ -1677,34 +1685,70 @@ static struct file_operations st_fops = {
...
@@ -1677,34 +1685,70 @@ static struct file_operations st_fops = {
NULL
/* fsync */
NULL
/* fsync */
};
};
void
st_attach
(
Scsi_Device
*
SDp
){
static
void
st_attach
(
Scsi_Device
*
SDp
){
scsi_tapes
[
NR_ST
++
].
device
=
SDp
;
Scsi_Tape
*
tpnt
;
if
(
NR_ST
>
MAX_ST
)
panic
(
"scsi_devices corrupt (st)"
);
int
i
;
};
/* We do not support attaching loadable devices yet. */
if
(
scsi_loadable_module_flag
)
return
;
if
(
SDp
->
type
!=
TYPE_TAPE
)
return
;
void
st_init1
(){
if
(
st_template
.
nr_dev
>=
st_template
.
dev_max
)
scsi_tapes
=
(
Scsi_Tape
*
)
scsi_init_malloc
(
MAX_ST
*
sizeof
(
Scsi_Tape
));
panic
(
"scsi_devices corrupt (st)"
);
for
(
tpnt
=
scsi_tapes
,
i
=
0
;
i
<
st_template
.
dev_max
;
i
++
,
tpnt
++
)
if
(
!
tpnt
->
device
)
break
;
if
(
i
>=
st_template
.
dev_max
)
panic
(
"scsi_devices corrupt (st)"
);
scsi_tapes
[
i
].
device
=
SDp
;
st_template
.
nr_dev
++
;
};
};
static
int
st_detect
(
Scsi_Device
*
SDp
){
/* We do not support attaching loadable devices yet. */
if
(
scsi_loadable_module_flag
)
return
0
;
if
(
SDp
->
type
!=
TYPE_TAPE
)
return
0
;
printk
(
"Detected scsi tape st%d at scsi%d, id %d, lun %d
\n
"
,
++
st_template
.
dev_noticed
,
SDp
->
host
->
host_no
,
SDp
->
id
,
SDp
->
lun
);
return
1
;
}
/* Driver initialization */
/* Driver initialization */
unsigned
long
st_init
(
unsigned
long
mem_start
,
unsigned
long
mem_end
)
static
void
st_init
(
)
{
{
int
i
;
int
i
;
Scsi_Tape
*
STp
;
Scsi_Tape
*
STp
;
Scsi_Device
*
SDp
;
Scsi_Device
*
SDp
;
static
int
st_registered
=
0
;
if
(
st_template
.
dev_noticed
==
0
)
return
;
if
(
!
st_registered
)
{
if
(
register_chrdev
(
MAJOR_NR
,
"st"
,
&
st_fops
))
{
if
(
register_chrdev
(
MAJOR_NR
,
"st"
,
&
st_fops
))
{
printk
(
"Unable to get major %d for SCSI tapes
\n
"
,
MAJOR_NR
);
printk
(
"Unable to get major %d for SCSI tapes
\n
"
,
MAJOR_NR
);
return
mem_start
;
return
;
}
}
if
(
NR_ST
==
0
)
return
mem_start
;
st_registered
++
;
}
/* We do not support attaching loadable devices yet. */
if
(
scsi_loadable_module_flag
)
return
;
scsi_tapes
=
(
Scsi_Tape
*
)
scsi_init_malloc
(
st_template
.
dev_noticed
*
sizeof
(
Scsi_Tape
));
st_template
.
dev_max
=
st_template
.
dev_noticed
;
#ifdef DEBUG
#ifdef DEBUG
printk
(
"st: Buffer size %d bytes, write threshold %d bytes.
\n
"
,
printk
(
"st: Buffer size %d bytes, write threshold %d bytes.
\n
"
,
st_buffer_size
,
st_write_threshold
);
st_buffer_size
,
st_write_threshold
);
#endif
#endif
for
(
i
=
0
,
SDp
=
scsi_devices
;
i
<
NR_ST
;
++
i
)
{
for
(
i
=
0
,
SDp
=
scsi_devices
;
i
<
st_template
.
dev_noticed
;
++
i
)
{
STp
=
&
(
scsi_tapes
[
i
]);
STp
=
&
(
scsi_tapes
[
i
]);
STp
->
capacity
=
0xfffff
;
STp
->
capacity
=
0xfffff
;
STp
->
dirty
=
0
;
STp
->
dirty
=
0
;
...
@@ -1721,8 +1765,7 @@ unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
...
@@ -1721,8 +1765,7 @@ unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
STp
->
write_threshold
=
st_write_threshold
;
STp
->
write_threshold
=
st_write_threshold
;
STp
->
drv_block
=
0
;
STp
->
drv_block
=
0
;
STp
->
moves_after_eof
=
1
;
STp
->
moves_after_eof
=
1
;
STp
->
mt_status
=
(
struct
mtget
*
)
mem_start
;
STp
->
mt_status
=
(
struct
mtget
*
)
scsi_init_malloc
(
sizeof
(
struct
mtget
));
mem_start
+=
sizeof
(
struct
mtget
);
/* Initialize status */
/* Initialize status */
memset
((
void
*
)
scsi_tapes
[
i
].
mt_status
,
0
,
sizeof
(
struct
mtget
));
memset
((
void
*
)
scsi_tapes
[
i
].
mt_status
,
0
,
sizeof
(
struct
mtget
));
for
(;
SDp
;
SDp
=
SDp
->
next
)
for
(;
SDp
;
SDp
=
SDp
->
next
)
...
@@ -1740,20 +1783,19 @@ unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
...
@@ -1740,20 +1783,19 @@ unsigned long st_init(unsigned long mem_start, unsigned long mem_end)
}
}
/* Allocate the buffers */
/* Allocate the buffers */
st_nbr_buffers
=
NR_ST
;
st_nbr_buffers
=
st_template
.
dev_noticed
;
if
(
st_nbr_buffers
>
st_max_buffers
)
if
(
st_nbr_buffers
>
st_max_buffers
)
st_nbr_buffers
=
st_max_buffers
;
st_nbr_buffers
=
st_max_buffers
;
st_buffers
=
(
ST_buffer
**
)
mem_start
;
st_buffers
=
(
ST_buffer
**
)
scsi_init_malloc
(
st_nbr_buffers
*
mem_start
+=
st_nbr_buffers
*
sizeof
(
ST_buffer
*
);
sizeof
(
ST_buffer
*
)
);
for
(
i
=
0
;
i
<
st_nbr_buffers
;
i
++
)
{
for
(
i
=
0
;
i
<
st_nbr_buffers
;
i
++
)
{
st_buffers
[
i
]
=
(
ST_buffer
*
)
mem_start
;
st_buffers
[
i
]
=
(
ST_buffer
*
)
scsi_init_malloc
(
sizeof
(
ST_buffer
)
-
1
+
st_buffer_size
);
#ifdef DEBUG
#ifdef DEBUG
/* printk("st: Buffer address: %p\n", st_buffers[i]); */
/* printk("st: Buffer address: %p\n", st_buffers[i]); */
#endif
#endif
mem_start
+=
sizeof
(
ST_buffer
)
-
1
+
st_buffer_size
;
st_buffers
[
i
]
->
in_use
=
0
;
st_buffers
[
i
]
->
in_use
=
0
;
st_buffers
[
i
]
->
writing
=
0
;
st_buffers
[
i
]
->
writing
=
0
;
}
}
return
;
return
mem_start
;
}
}
fs/Makefile
View file @
eebbb0b8
...
@@ -52,7 +52,7 @@ endif
...
@@ -52,7 +52,7 @@ endif
OBJS
=
open.o read_write.o inode.o devices.o file_table.o buffer.o super.o
\
OBJS
=
open.o read_write.o inode.o devices.o file_table.o buffer.o super.o
\
block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o
\
block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o
\
select
.o fifo.o locks.o filesystems.o
$(BINFMTS)
select
.o fifo.o locks.o filesystems.o
dcache.o
$(BINFMTS)
all
:
fs.o filesystems.a
all
:
fs.o filesystems.a
...
...
fs/dcache.c
0 → 100644
View file @
eebbb0b8
/*
* linux/fs/dcache.c
*
* (C) Copyright 1994 Linus Torvalds
*/
/*
* The directory cache is a "two-level" cache, each level doing LRU on
* its entries. Adding new entries puts them at the end of the LRU
* queue on the first-level cache, while the second-level cache is
* fed by any cache hits.
*
* The idea is that new additions (from readdir(), for example) will not
* flush the cache of entries that have really been used.
*
* There is a global hash-table over both caches that hashes the entries
* based on the directory inode number and device as well as on a
* string-hash computed over the name.
*/
#include <stddef.h>
#include <linux/fs.h>
#include <linux/string.h>
/*
* Don't bother caching long names.. They just take up space in the cache, and
* for a name cache you just want to cache the "normal" names anyway which tend
* to be short.
*/
#define DCACHE_NAME_LEN 15
#define DCACHE_SIZE 64
struct
hash_list
{
struct
dir_cache_entry
*
next
;
struct
dir_cache_entry
*
prev
;
};
/*
* The dir_cache_entry must be in this order: we do ugly things with the pointers
*/
struct
dir_cache_entry
{
struct
hash_list
h
;
unsigned
long
dev
;
unsigned
long
dir
;
unsigned
long
version
;
unsigned
long
ino
;
unsigned
char
name_len
;
char
name
[
DCACHE_NAME_LEN
];
struct
dir_cache_entry
**
lru_head
;
struct
dir_cache_entry
*
next_lru
,
*
prev_lru
;
};
#define COPYDATA(de, newde) \
memcpy((void *) &newde->dev, (void *) &de->dev, \
4*sizeof(unsigned long) + 1 + DCACHE_NAME_LEN)
static
struct
dir_cache_entry
level1_cache
[
DCACHE_SIZE
];
static
struct
dir_cache_entry
level2_cache
[
DCACHE_SIZE
];
/*
* The LRU-lists are doubly-linked circular lists, and do not change in size
* so these pointers always have something to point to (after _init)
*/
static
struct
dir_cache_entry
*
level1_head
;
static
struct
dir_cache_entry
*
level2_head
;
/*
* The hash-queues are also doubly-linked circular lists, but the head is
* itself on the doubly-linked list, not just a pointer to the first entry.
*/
#define DCACHE_HASH_QUEUES 19
#define hash_fn(dev,dir,namehash) (((dev) ^ (dir) ^ (namehash)) % DCACHE_HASH_QUEUES)
static
struct
hash_list
hash_table
[
DCACHE_HASH_QUEUES
];
static
inline
void
remove_lru
(
struct
dir_cache_entry
*
de
)
{
de
->
next_lru
->
prev_lru
=
de
->
prev_lru
;
de
->
prev_lru
->
next_lru
=
de
->
next_lru
;
}
static
inline
void
add_lru
(
struct
dir_cache_entry
*
de
,
struct
dir_cache_entry
*
head
)
{
de
->
next_lru
=
head
;
de
->
prev_lru
=
head
->
prev_lru
;
de
->
prev_lru
->
next_lru
=
de
;
head
->
prev_lru
=
de
;
}
static
inline
void
update_lru
(
struct
dir_cache_entry
*
de
)
{
if
(
de
==
*
de
->
lru_head
)
*
de
->
lru_head
=
de
->
next_lru
;
else
{
remove_lru
(
de
);
add_lru
(
de
,
*
de
->
lru_head
);
}
}
/*
* Stupid name"hash" algorithm. Write something better if you want to,
* but I doubt it matters that much
*/
static
inline
unsigned
long
namehash
(
const
char
*
name
,
int
len
)
{
return
len
*
*
(
unsigned
char
*
)
name
;
}
/*
* Hash queue manipulation. Look out for the casts..
*/
static
inline
void
remove_hash
(
struct
dir_cache_entry
*
de
)
{
if
(
de
->
h
.
next
)
{
de
->
h
.
next
->
h
.
prev
=
de
->
h
.
prev
;
de
->
h
.
prev
->
h
.
next
=
de
->
h
.
next
;
de
->
h
.
next
=
NULL
;
}
}
static
inline
void
add_hash
(
struct
dir_cache_entry
*
de
,
struct
hash_list
*
hash
)
{
de
->
h
.
next
=
hash
->
next
;
de
->
h
.
prev
=
(
struct
dir_cache_entry
*
)
hash
;
hash
->
next
->
h
.
prev
=
de
;
hash
->
next
=
de
;
}
/*
* Find a directory cache entry given all the necessary info.
*/
static
struct
dir_cache_entry
*
find_entry
(
struct
inode
*
dir
,
const
char
*
name
,
int
len
,
struct
hash_list
*
hash
)
{
struct
dir_cache_entry
*
de
=
hash
->
next
;
for
(
de
=
hash
->
next
;
de
!=
(
struct
dir_cache_entry
*
)
hash
;
de
=
de
->
h
.
next
)
{
if
(
de
->
dev
!=
dir
->
i_dev
)
continue
;
if
(
de
->
dir
!=
dir
->
i_ino
)
continue
;
if
(
de
->
version
!=
dir
->
i_version
)
continue
;
if
(
de
->
name_len
!=
len
)
continue
;
if
(
memcmp
(
de
->
name
,
name
,
len
))
continue
;
return
de
;
}
return
NULL
;
}
/*
* Move a successfully used entry to level2. If already at level2,
* move it to the end of the LRU queue..
*/
static
inline
void
move_to_level2
(
struct
dir_cache_entry
*
old_de
,
struct
hash_list
*
hash
)
{
struct
dir_cache_entry
*
de
;
if
(
old_de
->
lru_head
==
&
level2_head
)
{
update_lru
(
old_de
);
return
;
}
de
=
level2_head
;
level2_head
=
de
->
next_lru
;
remove_hash
(
de
);
COPYDATA
(
old_de
,
de
);
add_hash
(
de
,
hash
);
}
unsigned
long
dcache_lookup
(
struct
inode
*
dir
,
const
char
*
name
,
int
len
)
{
struct
hash_list
*
hash
;
struct
dir_cache_entry
*
de
;
if
(
len
>
DCACHE_NAME_LEN
)
return
0
;
hash
=
hash_table
+
hash_fn
(
dir
->
i_dev
,
dir
->
i_ino
,
namehash
(
name
,
len
));
de
=
find_entry
(
dir
,
name
,
len
,
hash
);
if
(
!
de
)
return
0
;
move_to_level2
(
de
,
hash
);
return
de
->
ino
;
}
void
dcache_add
(
struct
inode
*
dir
,
const
char
*
name
,
int
len
,
unsigned
long
ino
)
{
struct
hash_list
*
hash
;
struct
dir_cache_entry
*
de
;
if
(
len
>
DCACHE_NAME_LEN
)
return
;
hash
=
hash_table
+
hash_fn
(
dir
->
i_dev
,
dir
->
i_ino
,
namehash
(
name
,
len
));
if
((
de
=
find_entry
(
dir
,
name
,
len
,
hash
))
!=
NULL
)
{
update_lru
(
de
);
return
;
}
de
=
level1_head
;
level1_head
=
de
->
next_lru
;
remove_hash
(
de
);
de
->
dev
=
dir
->
i_dev
;
de
->
dir
=
dir
->
i_ino
;
de
->
version
=
dir
->
i_version
;
de
->
ino
=
ino
;
de
->
name_len
=
len
;
memcpy
(
de
->
name
,
name
,
len
);
add_hash
(
de
,
hash
);
}
unsigned
long
name_cache_init
(
unsigned
long
mem_start
,
unsigned
long
mem_end
)
{
int
i
;
struct
dir_cache_entry
*
p
;
/*
* Init level1 LRU lists..
*/
p
=
level1_cache
;
do
{
p
[
1
].
prev_lru
=
p
;
p
[
0
].
next_lru
=
p
+
1
;
p
[
0
].
lru_head
=
&
level1_head
;
}
while
(
++
p
<
level1_cache
+
DCACHE_SIZE
-
1
);
level1_cache
[
0
].
prev_lru
=
p
;
p
[
0
].
next_lru
=
&
level1_cache
[
0
];
p
[
0
].
lru_head
=
&
level1_head
;
level1_head
=
level1_cache
;
/*
* Init level2 LRU lists..
*/
p
=
level2_cache
;
do
{
p
[
1
].
prev_lru
=
p
;
p
[
0
].
next_lru
=
p
+
1
;
p
[
0
].
lru_head
=
&
level2_head
;
}
while
(
++
p
<
level2_cache
+
DCACHE_SIZE
-
1
);
level2_cache
[
0
].
prev_lru
=
p
;
p
[
0
].
next_lru
=
&
level2_cache
[
0
];
p
[
0
].
lru_head
=
&
level2_head
;
level2_head
=
level2_cache
;
/*
* Empty hash queues..
*/
for
(
i
=
0
;
i
<
DCACHE_HASH_QUEUES
;
i
++
)
hash_table
[
i
].
next
=
hash_table
[
i
].
next
=
(
struct
dir_cache_entry
*
)
&
hash_table
[
i
];
return
mem_start
;
}
fs/ext2/Makefile
View file @
eebbb0b8
...
@@ -14,8 +14,8 @@
...
@@ -14,8 +14,8 @@
.s.o
:
.s.o
:
$(AS)
-o
$*
.o
$<
$(AS)
-o
$*
.o
$<
OBJS
=
acl.o balloc.o bitmap.o d
cache.o dir.o file.o fsyn
c.o
\
OBJS
=
acl.o balloc.o bitmap.o d
ir.o file.o fsync.o iallo
c.o
\
i
alloc.o i
node.o ioctl.o namei.o super.o symlink.o truncate.o
inode.o ioctl.o namei.o super.o symlink.o truncate.o
ext2.o
:
$(OBJS)
ext2.o
:
$(OBJS)
$(LD)
-r
-o
ext2.o
$(OBJS)
$(LD)
-r
-o
ext2.o
$(OBJS)
...
...
fs/ext2/dir.c
View file @
eebbb0b8
...
@@ -144,11 +144,8 @@ static int ext2_readdir (struct inode * inode, struct file * filp,
...
@@ -144,11 +144,8 @@ static int ext2_readdir (struct inode * inode, struct file * filp,
put_fs_long
(
de
->
inode
,
&
dirent
->
d_ino
);
put_fs_long
(
de
->
inode
,
&
dirent
->
d_ino
);
put_fs_byte
(
0
,
de
->
name_len
+
dirent
->
d_name
);
put_fs_byte
(
0
,
de
->
name_len
+
dirent
->
d_name
);
put_fs_word
(
de
->
name_len
,
&
dirent
->
d_reclen
);
put_fs_word
(
de
->
name_len
,
&
dirent
->
d_reclen
);
#ifndef DONT_USE_DCACHE
dcache_add
(
inode
,
de
->
name
,
de
->
name_len
,
ext2_dcache_add
(
inode
->
i_dev
,
inode
->
i_ino
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
de
->
inode
);
#endif
i
=
de
->
name_len
;
i
=
de
->
name_len
;
brelse
(
bh
);
brelse
(
bh
);
if
(
!
IS_RDONLY
(
inode
))
{
if
(
!
IS_RDONLY
(
inode
))
{
...
...
fs/ext2/inode.c
View file @
eebbb0b8
...
@@ -538,6 +538,7 @@ void ext2_read_inode (struct inode * inode)
...
@@ -538,6 +538,7 @@ void ext2_read_inode (struct inode * inode)
inode
->
u
.
ext2_i
.
i_dtime
=
raw_inode
->
i_dtime
;
inode
->
u
.
ext2_i
.
i_dtime
=
raw_inode
->
i_dtime
;
inode
->
i_blksize
=
inode
->
i_sb
->
s_blocksize
;
inode
->
i_blksize
=
inode
->
i_sb
->
s_blocksize
;
inode
->
i_blocks
=
raw_inode
->
i_blocks
;
inode
->
i_blocks
=
raw_inode
->
i_blocks
;
inode
->
i_version
=
++
event
;
inode
->
u
.
ext2_i
.
i_flags
=
raw_inode
->
i_flags
;
inode
->
u
.
ext2_i
.
i_flags
=
raw_inode
->
i_flags
;
inode
->
u
.
ext2_i
.
i_faddr
=
raw_inode
->
i_faddr
;
inode
->
u
.
ext2_i
.
i_faddr
=
raw_inode
->
i_faddr
;
inode
->
u
.
ext2_i
.
i_frag
=
raw_inode
->
i_frag
;
inode
->
u
.
ext2_i
.
i_frag
=
raw_inode
->
i_frag
;
...
...
fs/ext2/namei.c
View file @
eebbb0b8
...
@@ -181,22 +181,15 @@ int ext2_lookup (struct inode * dir, const char * name, int len,
...
@@ -181,22 +181,15 @@ int ext2_lookup (struct inode * dir, const char * name, int len,
iput
(
dir
);
iput
(
dir
);
return
-
ENOENT
;
return
-
ENOENT
;
}
}
#ifndef DONT_USE_DCACHE
if
(
!
(
ino
=
dcache_lookup
(
dir
,
name
,
len
)))
{
if
(
!
(
ino
=
ext2_dcache_lookup
(
dir
->
i_dev
,
dir
->
i_ino
,
name
,
len
)))
{
#endif
if
(
!
(
bh
=
ext2_find_entry
(
dir
,
name
,
len
,
&
de
)))
{
if
(
!
(
bh
=
ext2_find_entry
(
dir
,
name
,
len
,
&
de
)))
{
iput
(
dir
);
iput
(
dir
);
return
-
ENOENT
;
return
-
ENOENT
;
}
}
ino
=
de
->
inode
;
ino
=
de
->
inode
;
#ifndef DONT_USE_DCACHE
dcache_add
(
dir
,
de
->
name
,
de
->
name_len
,
ino
);
ext2_dcache_add
(
dir
->
i_dev
,
dir
->
i_ino
,
de
->
name
,
de
->
name_len
,
ino
);
#endif
brelse
(
bh
);
brelse
(
bh
);
#ifndef DONT_USE_DCACHE
}
}
#endif
if
(
!
(
*
result
=
iget
(
dir
->
i_sb
,
ino
)))
{
if
(
!
(
*
result
=
iget
(
dir
->
i_sb
,
ino
)))
{
iput
(
dir
);
iput
(
dir
);
return
-
EACCES
;
return
-
EACCES
;
...
@@ -390,11 +383,8 @@ int ext2_create (struct inode * dir,const char * name, int len, int mode,
...
@@ -390,11 +383,8 @@ int ext2_create (struct inode * dir,const char * name, int len, int mode,
return
err
;
return
err
;
}
}
de
->
inode
=
inode
->
i_ino
;
de
->
inode
=
inode
->
i_ino
;
dir
->
i_version
++
;
dir
->
i_version
=
++
event
;
#ifndef DONT_USE_DCACHE
dcache_add
(
dir
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
ext2_dcache_add
(
dir
->
i_dev
,
dir
->
i_ino
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
#endif
mark_buffer_dirty
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
dir
))
{
if
(
IS_SYNC
(
dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
ll_rw_block
(
WRITE
,
1
,
&
bh
);
...
@@ -457,11 +447,8 @@ int ext2_mknod (struct inode * dir, const char * name, int len, int mode,
...
@@ -457,11 +447,8 @@ int ext2_mknod (struct inode * dir, const char * name, int len, int mode,
return
err
;
return
err
;
}
}
de
->
inode
=
inode
->
i_ino
;
de
->
inode
=
inode
->
i_ino
;
dir
->
i_version
++
;
dir
->
i_version
=
++
event
;
#ifndef DONT_USE_DCACHE
dcache_add
(
dir
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
ext2_dcache_add
(
dir
->
i_dev
,
dir
->
i_ino
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
#endif
mark_buffer_dirty
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
dir
))
{
if
(
IS_SYNC
(
dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
ll_rw_block
(
WRITE
,
1
,
&
bh
);
...
@@ -534,11 +521,8 @@ int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
...
@@ -534,11 +521,8 @@ int ext2_mkdir (struct inode * dir, const char * name, int len, int mode)
return
err
;
return
err
;
}
}
de
->
inode
=
inode
->
i_ino
;
de
->
inode
=
inode
->
i_ino
;
dir
->
i_version
++
;
dir
->
i_version
=
++
event
;
#ifndef DONT_USE_DCACHE
dcache_add
(
dir
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
ext2_dcache_add
(
dir
->
i_dev
,
dir
->
i_ino
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
#endif
mark_buffer_dirty
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
dir
))
{
if
(
IS_SYNC
(
dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
ll_rw_block
(
WRITE
,
1
,
&
bh
);
...
@@ -660,7 +644,7 @@ int ext2_rmdir (struct inode * dir, const char * name, int len)
...
@@ -660,7 +644,7 @@ int ext2_rmdir (struct inode * dir, const char * name, int len)
inode
->
i_size
=
0
;
inode
->
i_size
=
0
;
}
}
retval
=
ext2_delete_entry
(
de
,
bh
);
retval
=
ext2_delete_entry
(
de
,
bh
);
dir
->
i_version
++
;
dir
->
i_version
=
++
event
;
}
}
up
(
&
inode
->
i_sem
);
up
(
&
inode
->
i_sem
);
if
(
retval
)
if
(
retval
)
...
@@ -670,17 +654,11 @@ int ext2_rmdir (struct inode * dir, const char * name, int len)
...
@@ -670,17 +654,11 @@ int ext2_rmdir (struct inode * dir, const char * name, int len)
ll_rw_block
(
WRITE
,
1
,
&
bh
);
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
wait_on_buffer
(
bh
);
}
}
#ifndef DONT_USE_DCACHE
ext2_dcache_remove
(
inode
->
i_dev
,
inode
->
i_ino
,
"."
,
1
);
ext2_dcache_remove
(
inode
->
i_dev
,
inode
->
i_ino
,
".."
,
2
);
#endif
if
(
inode
->
i_nlink
!=
2
)
if
(
inode
->
i_nlink
!=
2
)
ext2_warning
(
inode
->
i_sb
,
"ext2_rmdir"
,
ext2_warning
(
inode
->
i_sb
,
"ext2_rmdir"
,
"empty directory has nlink!=2 (%d)"
,
"empty directory has nlink!=2 (%d)"
,
inode
->
i_nlink
);
inode
->
i_nlink
);
#ifndef DONT_USE_DCACHE
inode
->
i_version
=
++
event
;
ext2_dcache_remove
(
dir
->
i_dev
,
dir
->
i_ino
,
de
->
name
,
de
->
name_len
);
#endif
inode
->
i_nlink
=
0
;
inode
->
i_nlink
=
0
;
inode
->
i_dirt
=
1
;
inode
->
i_dirt
=
1
;
dir
->
i_nlink
--
;
dir
->
i_nlink
--
;
...
@@ -733,15 +711,12 @@ int ext2_unlink (struct inode * dir, const char * name, int len)
...
@@ -733,15 +711,12 @@ int ext2_unlink (struct inode * dir, const char * name, int len)
retval
=
ext2_delete_entry
(
de
,
bh
);
retval
=
ext2_delete_entry
(
de
,
bh
);
if
(
retval
)
if
(
retval
)
goto
end_unlink
;
goto
end_unlink
;
dir
->
i_version
++
;
dir
->
i_version
=
++
event
;
mark_buffer_dirty
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
dir
))
{
if
(
IS_SYNC
(
dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
ll_rw_block
(
WRITE
,
1
,
&
bh
);
wait_on_buffer
(
bh
);
wait_on_buffer
(
bh
);
}
}
#ifndef DONT_USE_DCACHE
ext2_dcache_remove
(
dir
->
i_dev
,
dir
->
i_ino
,
de
->
name
,
de
->
name_len
);
#endif
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
dir
->
i_dirt
=
1
;
inode
->
i_nlink
--
;
inode
->
i_nlink
--
;
...
@@ -822,11 +797,8 @@ int ext2_symlink (struct inode * dir, const char * name, int len,
...
@@ -822,11 +797,8 @@ int ext2_symlink (struct inode * dir, const char * name, int len,
return
err
;
return
err
;
}
}
de
->
inode
=
inode
->
i_ino
;
de
->
inode
=
inode
->
i_ino
;
dir
->
i_version
++
;
dir
->
i_version
=
++
event
;
#ifndef DONT_USE_DCACHE
dcache_add
(
dir
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
ext2_dcache_add
(
dir
->
i_dev
,
dir
->
i_ino
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
#endif
mark_buffer_dirty
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
dir
))
{
if
(
IS_SYNC
(
dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
ll_rw_block
(
WRITE
,
1
,
&
bh
);
...
@@ -869,11 +841,8 @@ int ext2_link (struct inode * oldinode, struct inode * dir,
...
@@ -869,11 +841,8 @@ int ext2_link (struct inode * oldinode, struct inode * dir,
return
err
;
return
err
;
}
}
de
->
inode
=
oldinode
->
i_ino
;
de
->
inode
=
oldinode
->
i_ino
;
dir
->
i_version
++
;
dir
->
i_version
=
++
event
;
#ifndef DONT_USE_DCACHE
dcache_add
(
dir
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
ext2_dcache_add
(
dir
->
i_dev
,
dir
->
i_ino
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
#endif
mark_buffer_dirty
(
bh
,
1
);
mark_buffer_dirty
(
bh
,
1
);
if
(
IS_SYNC
(
dir
))
{
if
(
IS_SYNC
(
dir
))
{
ll_rw_block
(
WRITE
,
1
,
&
bh
);
ll_rw_block
(
WRITE
,
1
,
&
bh
);
...
@@ -1032,19 +1001,14 @@ static int do_ext2_rename (struct inode * old_dir, const char * old_name,
...
@@ -1032,19 +1001,14 @@ static int do_ext2_rename (struct inode * old_dir, const char * old_name,
* ok, that's it
* ok, that's it
*/
*/
new_de
->
inode
=
old_inode
->
i_ino
;
new_de
->
inode
=
old_inode
->
i_ino
;
#ifndef DONT_USE_DCACHE
dcache_add
(
new_dir
,
new_de
->
name
,
new_de
->
name_len
,
new_de
->
inode
);
ext2_dcache_remove
(
old_dir
->
i_dev
,
old_dir
->
i_ino
,
old_de
->
name
,
old_de
->
name_len
);
ext2_dcache_add
(
new_dir
->
i_dev
,
new_dir
->
i_ino
,
new_de
->
name
,
new_de
->
name_len
,
new_de
->
inode
);
#endif
retval
=
ext2_delete_entry
(
old_de
,
old_bh
);
retval
=
ext2_delete_entry
(
old_de
,
old_bh
);
if
(
retval
==
-
ENOENT
)
if
(
retval
==
-
ENOENT
)
goto
try_again
;
goto
try_again
;
if
(
retval
)
if
(
retval
)
goto
end_rename
;
goto
end_rename
;
new_dir
->
i_version
++
;
new_dir
->
i_version
=
++
event
;
old_dir
->
i_version
++
;
old_dir
->
i_version
=
++
event
;
if
(
new_inode
)
{
if
(
new_inode
)
{
new_inode
->
i_nlink
--
;
new_inode
->
i_nlink
--
;
new_inode
->
i_ctime
=
CURRENT_TIME
;
new_inode
->
i_ctime
=
CURRENT_TIME
;
...
...
fs/ext2/super.c
View file @
eebbb0b8
...
@@ -98,9 +98,6 @@ void ext2_put_super (struct super_block * sb)
...
@@ -98,9 +98,6 @@ void ext2_put_super (struct super_block * sb)
sb
->
u
.
ext2_sb
.
s_es
->
s_state
=
sb
->
u
.
ext2_sb
.
s_mount_state
;
sb
->
u
.
ext2_sb
.
s_es
->
s_state
=
sb
->
u
.
ext2_sb
.
s_mount_state
;
mark_buffer_dirty
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
mark_buffer_dirty
(
sb
->
u
.
ext2_sb
.
s_sbh
,
1
);
}
}
#ifndef DONT_USE_DCACHE
ext2_dcache_invalidate
(
sb
->
s_dev
);
#endif
sb
->
s_dev
=
0
;
sb
->
s_dev
=
0
;
for
(
i
=
0
;
i
<
EXT2_MAX_GROUP_DESC
;
i
++
)
for
(
i
=
0
;
i
<
EXT2_MAX_GROUP_DESC
;
i
++
)
if
(
sb
->
u
.
ext2_sb
.
s_group_desc
[
i
])
if
(
sb
->
u
.
ext2_sb
.
s_group_desc
[
i
])
...
...
fs/inode.c
View file @
eebbb0b8
...
@@ -384,6 +384,7 @@ struct inode * get_empty_inode(void)
...
@@ -384,6 +384,7 @@ struct inode * get_empty_inode(void)
clear_inode
(
inode
);
clear_inode
(
inode
);
inode
->
i_count
=
1
;
inode
->
i_count
=
1
;
inode
->
i_nlink
=
1
;
inode
->
i_nlink
=
1
;
inode
->
i_version
=
++
event
;
inode
->
i_sem
.
count
=
1
;
inode
->
i_sem
.
count
=
1
;
nr_free_inodes
--
;
nr_free_inodes
--
;
if
(
nr_free_inodes
<
0
)
{
if
(
nr_free_inodes
<
0
)
{
...
...
fs/isofs/rock.c
View file @
eebbb0b8
...
@@ -65,12 +65,16 @@
...
@@ -65,12 +65,16 @@
offset &= 1023; \
offset &= 1023; \
if(offset + cont_size >= 1024) { \
if(offset + cont_size >= 1024) { \
bh = bread(DEV->i_dev, block++, ISOFS_BUFFER_SIZE(DEV)); \
bh = bread(DEV->i_dev, block++, ISOFS_BUFFER_SIZE(DEV)); \
if(!bh) {printk("Unable to read continuation Rock Ridge record\n"); \
kfree(buffer); \
buffer = NULL; } else { \
memcpy(buffer, bh->b_data + offset, 1024 - offset); \
memcpy(buffer, bh->b_data + offset, 1024 - offset); \
brelse(bh); \
brelse(bh); \
offset1 = 1024 - offset; \
offset1 = 1024 - offset; \
offset = 0;
\
offset = 0;}
\
} \
} \
}; \
}; \
if(buffer) { \
bh = bread(DEV->i_dev, block, ISOFS_BUFFER_SIZE(DEV)); \
bh = bread(DEV->i_dev, block, ISOFS_BUFFER_SIZE(DEV)); \
if(bh){ \
if(bh){ \
memcpy(buffer + offset1, bh->b_data + offset, cont_size - offset1); \
memcpy(buffer + offset1, bh->b_data + offset, cont_size - offset1); \
...
@@ -82,6 +86,7 @@
...
@@ -82,6 +86,7 @@
cont_offset = 0; \
cont_offset = 0; \
goto LABEL; \
goto LABEL; \
}; \
}; \
} \
printk("Unable to read rock-ridge attributes\n"); \
printk("Unable to read rock-ridge attributes\n"); \
}}
}}
...
...
fs/msdos/mmap.c
View file @
eebbb0b8
...
@@ -94,12 +94,9 @@ int msdos_mmap(struct inode * inode, struct file * file, struct vm_area_struct *
...
@@ -94,12 +94,9 @@ int msdos_mmap(struct inode * inode, struct file * file, struct vm_area_struct *
inode
->
i_dirt
=
1
;
inode
->
i_dirt
=
1
;
}
}
unmap_page_range
(
vma
->
vm_start
,
vma
->
vm_end
-
vma
->
vm_start
);
vma
->
vm_inode
=
inode
;
vma
->
vm_inode
=
inode
;
inode
->
i_count
++
;
inode
->
i_count
++
;
vma
->
vm_ops
=
&
msdos_file_mmap
;
vma
->
vm_ops
=
&
msdos_file_mmap
;
insert_vm_struct
(
current
,
vma
);
merge_segments
(
current
->
mm
->
mmap
);
return
0
;
return
0
;
}
}
fs/nfs/mmap.c
View file @
eebbb0b8
...
@@ -96,11 +96,8 @@ int nfs_mmap(struct inode * inode, struct file * file, struct vm_area_struct * v
...
@@ -96,11 +96,8 @@ int nfs_mmap(struct inode * inode, struct file * file, struct vm_area_struct * v
inode
->
i_dirt
=
1
;
inode
->
i_dirt
=
1
;
}
}
unmap_page_range
(
vma
->
vm_start
,
vma
->
vm_end
-
vma
->
vm_start
);
vma
->
vm_inode
=
inode
;
vma
->
vm_inode
=
inode
;
inode
->
i_count
++
;
inode
->
i_count
++
;
vma
->
vm_ops
=
&
nfs_file_mmap
;
vma
->
vm_ops
=
&
nfs_file_mmap
;
insert_vm_struct
(
current
,
vma
);
merge_segments
(
current
->
mm
->
mmap
);
return
0
;
return
0
;
}
}
fs/sysv/Makefile
View file @
eebbb0b8
...
@@ -15,7 +15,7 @@
...
@@ -15,7 +15,7 @@
$(AS)
-o
$*
.o
$<
$(AS)
-o
$*
.o
$<
OBJS
=
ialloc.o balloc.o inode.o file.o dir.o symlink.o namei.o
\
OBJS
=
ialloc.o balloc.o inode.o file.o dir.o symlink.o namei.o
\
fsync.o truncate.o
#
mmap.o
fsync.o truncate.o mmap.o
sysv.o
:
$(OBJS)
sysv.o
:
$(OBJS)
$(LD)
-r
-o
sysv.o
$(OBJS)
$(LD)
-r
-o
sysv.o
$(OBJS)
...
...
fs/sysv/README
View file @
eebbb0b8
...
@@ -4,7 +4,7 @@ It implements all of
...
@@ -4,7 +4,7 @@ It implements all of
- SystemV/386 FS,
- SystemV/386 FS,
- Coherent FS.
- Coherent FS.
This is version beta
1
.
This is version beta
2
.
To install:
To install:
* Answer the 'System V and Coherent filesystem support' question with 'y'
* Answer the 'System V and Coherent filesystem support' question with 'y'
...
...
fs/sysv/file.c
View file @
eebbb0b8
...
@@ -32,7 +32,6 @@
...
@@ -32,7 +32,6 @@
#include <linux/fs.h>
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include <linux/sysv_fs.h>
static
int
sysv_file_read
(
struct
inode
*
,
struct
file
*
,
char
*
,
int
);
static
int
sysv_file_write
(
struct
inode
*
,
struct
file
*
,
char
*
,
int
);
static
int
sysv_file_write
(
struct
inode
*
,
struct
file
*
,
char
*
,
int
);
/*
/*
...
@@ -46,7 +45,7 @@ static struct file_operations sysv_file_operations = {
...
@@ -46,7 +45,7 @@ static struct file_operations sysv_file_operations = {
NULL
,
/* readdir - bad */
NULL
,
/* readdir - bad */
NULL
,
/* select - default */
NULL
,
/* select - default */
NULL
,
/* ioctl - default */
NULL
,
/* ioctl - default */
NULL
,
/* mmap */
sysv_mmap
,
/* mmap */
NULL
,
/* no special open is needed */
NULL
,
/* no special open is needed */
NULL
,
/* release */
NULL
,
/* release */
sysv_sync_file
/* fsync */
sysv_sync_file
/* fsync */
...
@@ -106,7 +105,7 @@ struct sysv_buffer {
...
@@ -106,7 +105,7 @@ struct sysv_buffer {
char
*
bh_data
;
char
*
bh_data
;
};
};
static
int
sysv_file_read
(
struct
inode
*
inode
,
struct
file
*
filp
,
char
*
buf
,
int
count
)
int
sysv_file_read
(
struct
inode
*
inode
,
struct
file
*
filp
,
char
*
buf
,
int
count
)
{
{
struct
super_block
*
sb
=
inode
->
i_sb
;
struct
super_block
*
sb
=
inode
->
i_sb
;
int
read
,
left
,
chars
;
int
read
,
left
,
chars
;
...
...
fs/sysv/mmap.c
0 → 100644
View file @
eebbb0b8
/*
* linux/fs/sysv/mmap.c
*
* mm/memory.c, mm/mmap.c
* Copyright (C) 1991, 1992, 1993 Linus Torvalds
*
* nfs/mmap.c
* Copyright (C) 1993 Jon Tombs
*
* fs/msdos/mmap.c
* Copyright (C) 1994 Jacques Gelinas
*
* fs/sysv/mmap.c
* Copyright (C) 1994 Bruno Haible
*
* SystemV/Coherent mmap handling
*/
#include <asm/segment.h>
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/malloc.h>
/*
* Fill in the supplied page for mmap
*/
static
unsigned
long
sysv_file_mmap_nopage
(
struct
vm_area_struct
*
area
,
unsigned
long
address
,
unsigned
long
page
,
int
no_share
)
{
int
remaining
,
count
,
old_fs
;
struct
file
filp
;
address
&=
PAGE_MASK
;
/* prepare a file pointer */
filp
.
f_pos
=
address
-
area
->
vm_start
+
area
->
vm_offset
;
filp
.
f_reada
=
0
;
remaining
=
area
->
vm_end
-
address
;
if
(
remaining
>
PAGE_SIZE
)
remaining
=
PAGE_SIZE
;
/* read from the file. page is in kernel space, not user space. */
old_fs
=
get_fs
();
set_fs
(
get_ds
());
count
=
sysv_file_read
(
area
->
vm_inode
,
&
filp
,
(
char
*
)
page
,
remaining
);
set_fs
(
old_fs
);
if
(
count
<
0
)
count
=
0
;
/* do nothing on I/O error ?? */
else
remaining
-=
count
;
if
(
remaining
>
0
)
memset
((
char
*
)
page
+
count
,
0
,
remaining
);
return
page
;
}
static
struct
vm_operations_struct
sysv_file_mmap
=
{
NULL
,
/* open */
NULL
,
/* close */
sysv_file_mmap_nopage
,
/* nopage */
NULL
,
/* wppage */
NULL
,
/* share */
NULL
,
/* unmap */
};
int
sysv_mmap
(
struct
inode
*
inode
,
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
{
if
(
vma
->
vm_page_prot
&
PAGE_RW
)
/* only PAGE_COW or read-only supported right now */
return
-
EINVAL
;
if
(
vma
->
vm_offset
&
(
inode
->
i_sb
->
s_blocksize
-
1
))
return
-
EINVAL
;
if
(
!
inode
->
i_sb
||
!
S_ISREG
(
inode
->
i_mode
))
return
-
EACCES
;
if
(
!
IS_RDONLY
(
inode
))
{
inode
->
i_atime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
}
vma
->
vm_inode
=
inode
;
inode
->
i_count
++
;
vma
->
vm_ops
=
&
sysv_file_mmap
;
return
0
;
}
ibcs/binfmt_elf.c
View file @
eebbb0b8
...
@@ -66,12 +66,13 @@ unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exe
...
@@ -66,12 +66,13 @@ unsigned long * create_elf_tables(char * p,int argc,int envc,struct elfhdr * exe
mpnt
->
vm_start
=
PAGE_MASK
&
(
unsigned
long
)
p
;
mpnt
->
vm_start
=
PAGE_MASK
&
(
unsigned
long
)
p
;
mpnt
->
vm_end
=
TASK_SIZE
;
mpnt
->
vm_end
=
TASK_SIZE
;
mpnt
->
vm_page_prot
=
PAGE_PRIVATE
|
PAGE_DIRTY
;
mpnt
->
vm_page_prot
=
PAGE_PRIVATE
|
PAGE_DIRTY
;
mpnt
->
vm_flags
=
VM_STACK_FLAGS
;
mpnt
->
vm_share
=
NULL
;
mpnt
->
vm_share
=
NULL
;
mpnt
->
vm_ops
=
NULL
;
mpnt
->
vm_inode
=
NULL
;
mpnt
->
vm_inode
=
NULL
;
mpnt
->
vm_offset
=
0
;
mpnt
->
vm_offset
=
0
;
mpnt
->
vm_
ops
=
NULL
;
mpnt
->
vm_
pte
=
0
;
insert_vm_struct
(
current
,
mpnt
);
insert_vm_struct
(
current
,
mpnt
);
current
->
mm
->
stk_vma
=
mpnt
;
}
}
sp
=
(
unsigned
long
*
)
(
0xfffffffc
&
(
unsigned
long
)
p
);
sp
=
(
unsigned
long
*
)
(
0xfffffffc
&
(
unsigned
long
)
p
);
if
(
exec
)
sp
-=
DLINFO_ITEMS
*
2
;
if
(
exec
)
sp
-=
DLINFO_ITEMS
*
2
;
...
...
include/linux/ext2_fs.h
View file @
eebbb0b8
...
@@ -39,11 +39,6 @@
...
@@ -39,11 +39,6 @@
*/
*/
#undef EXT2FS_PRE_02B_COMPAT
#undef EXT2FS_PRE_02B_COMPAT
/*
* Define DONT_USE_DCACHE to inhibit the directory cache
*/
#define DONT_USE_DCACHE
/*
/*
* Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
* Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
*/
*/
...
@@ -355,17 +350,6 @@ extern void ext2_check_blocks_bitmap (struct super_block *);
...
@@ -355,17 +350,6 @@ extern void ext2_check_blocks_bitmap (struct super_block *);
/* bitmap.c */
/* bitmap.c */
extern
unsigned
long
ext2_count_free
(
struct
buffer_head
*
,
unsigned
);
extern
unsigned
long
ext2_count_free
(
struct
buffer_head
*
,
unsigned
);
#ifndef DONT_USE_DCACHE
/* dcache.c */
extern
void
ext2_dcache_invalidate
(
unsigned
short
);
extern
unsigned
long
ext2_dcache_lookup
(
unsigned
short
,
unsigned
long
,
const
char
*
,
int
);
extern
void
ext2_dcache_add
(
unsigned
short
,
unsigned
long
,
const
char
*
,
int
,
unsigned
long
);
extern
void
ext2_dcache_remove
(
unsigned
short
,
unsigned
long
,
const
char
*
,
int
);
#endif
/* dir.c */
/* dir.c */
extern
int
ext2_check_dir_entry
(
char
*
,
struct
inode
*
,
extern
int
ext2_check_dir_entry
(
char
*
,
struct
inode
*
,
struct
ext2_dir_entry
*
,
struct
buffer_head
*
,
struct
ext2_dir_entry
*
,
struct
buffer_head
*
,
...
...
include/linux/fs.h
View file @
eebbb0b8
...
@@ -45,6 +45,7 @@
...
@@ -45,6 +45,7 @@
extern
void
buffer_init
(
void
);
extern
void
buffer_init
(
void
);
extern
unsigned
long
inode_init
(
unsigned
long
start
,
unsigned
long
end
);
extern
unsigned
long
inode_init
(
unsigned
long
start
,
unsigned
long
end
);
extern
unsigned
long
file_table_init
(
unsigned
long
start
,
unsigned
long
end
);
extern
unsigned
long
file_table_init
(
unsigned
long
start
,
unsigned
long
end
);
extern
unsigned
long
name_cache_init
(
unsigned
long
start
,
unsigned
long
end
);
#define MAJOR(a) (int)((unsigned short)(a) >> 8)
#define MAJOR(a) (int)((unsigned short)(a) >> 8)
#define MINOR(a) (int)((unsigned short)(a) & 0xFF)
#define MINOR(a) (int)((unsigned short)(a) & 0xFF)
...
@@ -469,6 +470,9 @@ extern int generic_mmap(struct inode *, struct file *, struct vm_area_struct *);
...
@@ -469,6 +470,9 @@ extern int generic_mmap(struct inode *, struct file *, struct vm_area_struct *);
extern
int
block_fsync
(
struct
inode
*
,
struct
file
*
);
extern
int
block_fsync
(
struct
inode
*
,
struct
file
*
);
extern
int
file_fsync
(
struct
inode
*
,
struct
file
*
);
extern
int
file_fsync
(
struct
inode
*
,
struct
file
*
);
extern
void
dcache_add
(
struct
inode
*
,
const
char
*
,
int
,
unsigned
long
);
extern
unsigned
long
dcache_lookup
(
struct
inode
*
,
const
char
*
,
int
);
extern
inline
struct
inode
*
iget
(
struct
super_block
*
sb
,
int
nr
)
extern
inline
struct
inode
*
iget
(
struct
super_block
*
sb
,
int
nr
)
{
{
return
__iget
(
sb
,
nr
,
1
);
return
__iget
(
sb
,
nr
,
1
);
...
...
include/linux/page.h
View file @
eebbb0b8
...
@@ -3,7 +3,9 @@
...
@@ -3,7 +3,9 @@
/* PAGE_SHIFT determines the page size */
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
#define PAGE_SHIFT 12
#define PAGE_SIZE ((unsigned long)1<<PAGE_SHIFT)
#define PGDIR_SHIFT 22
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#ifdef __KERNEL__
#ifdef __KERNEL__
...
@@ -11,6 +13,8 @@
...
@@ -11,6 +13,8 @@
#define BITS_PER_PTR (8*sizeof(unsigned long))
#define BITS_PER_PTR (8*sizeof(unsigned long))
/* to mask away the intra-page address bits */
/* to mask away the intra-page address bits */
#define PAGE_MASK (~(PAGE_SIZE-1))
#define PAGE_MASK (~(PAGE_SIZE-1))
/* to mask away the intra-page address bits */
#define PGDIR_MASK (~(PGDIR_SIZE-1))
/* to align the pointer to the (next) page boundary */
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
/* to align the pointer to a pointer address */
/* to align the pointer to a pointer address */
...
...
include/linux/sched.h
View file @
eebbb0b8
#ifndef _LINUX_SCHED_H
#ifndef _LINUX_SCHED_H
#define _LINUX_SCHED_H
#define _LINUX_SCHED_H
#define NEW_SWAP
/*
/*
* define DEBUG if you want the wait-queues to have some extra
* define DEBUG if you want the wait-queues to have some extra
* debugging code. It's not normally used, but might catch some
* debugging code. It's not normally used, but might catch some
...
@@ -22,6 +20,7 @@ extern int ignore_irq13;
...
@@ -22,6 +20,7 @@ extern int ignore_irq13;
extern
int
wp_works_ok
;
extern
int
wp_works_ok
;
extern
unsigned
long
intr_count
;
extern
unsigned
long
intr_count
;
extern
unsigned
long
event
;
#define start_bh_atomic() \
#define start_bh_atomic() \
__asm__ __volatile__("incl _intr_count")
__asm__ __volatile__("incl _intr_count")
...
@@ -222,13 +221,10 @@ struct mm_struct {
...
@@ -222,13 +221,10 @@ struct mm_struct {
unsigned
long
rss
;
unsigned
long
rss
;
unsigned
long
min_flt
,
maj_flt
,
cmin_flt
,
cmaj_flt
;
unsigned
long
min_flt
,
maj_flt
,
cmin_flt
,
cmaj_flt
;
int
swappable
:
1
;
int
swappable
:
1
;
#ifdef NEW_SWAP
unsigned
long
swap_address
;
unsigned
long
old_maj_flt
;
/* old value of maj_flt */
unsigned
long
old_maj_flt
;
/* old value of maj_flt */
unsigned
long
dec_flt
;
/* page fault count of the last time */
unsigned
long
dec_flt
;
/* page fault count of the last time */
unsigned
long
swap_cnt
;
/* number of pages to swap on next pass */
unsigned
long
swap_cnt
;
/* number of pages to swap on next pass */
short
swap_table
;
/* current page table */
short
swap_page
;
/* current page */
#endif NEW_SWAP
struct
vm_area_struct
*
mmap
;
struct
vm_area_struct
*
mmap
;
};
};
...
@@ -240,7 +236,7 @@ struct mm_struct {
...
@@ -240,7 +236,7 @@ struct mm_struct {
0, \
0, \
/* ?_flt */
0, 0, 0, 0, \
/* ?_flt */
0, 0, 0, 0, \
0, \
0, \
/* swap */
0, 0, 0, 0,
0,
\
/* swap */
0, 0, 0, 0, \
NULL }
NULL }
struct
task_struct
{
struct
task_struct
{
...
...
include/linux/sysv_fs.h
View file @
eebbb0b8
...
@@ -414,6 +414,7 @@ extern int sysv_bmap(struct inode *,int);
...
@@ -414,6 +414,7 @@ extern int sysv_bmap(struct inode *,int);
extern
struct
buffer_head
*
sysv_getblk
(
struct
inode
*
,
unsigned
int
,
int
,
char
*
*
);
extern
struct
buffer_head
*
sysv_getblk
(
struct
inode
*
,
unsigned
int
,
int
,
char
*
*
);
extern
struct
buffer_head
*
sysv_file_bread
(
struct
inode
*
,
int
,
int
,
char
*
*
);
extern
struct
buffer_head
*
sysv_file_bread
(
struct
inode
*
,
int
,
int
,
char
*
*
);
extern
int
sysv_file_read
(
struct
inode
*
,
struct
file
*
,
char
*
,
int
);
extern
void
sysv_truncate
(
struct
inode
*
);
extern
void
sysv_truncate
(
struct
inode
*
);
extern
void
sysv_put_super
(
struct
super_block
*
);
extern
void
sysv_put_super
(
struct
super_block
*
);
...
@@ -426,9 +427,7 @@ extern void sysv_put_inode(struct inode *);
...
@@ -426,9 +427,7 @@ extern void sysv_put_inode(struct inode *);
extern
void
sysv_statfs
(
struct
super_block
*
,
struct
statfs
*
);
extern
void
sysv_statfs
(
struct
super_block
*
,
struct
statfs
*
);
extern
int
sysv_sync_inode
(
struct
inode
*
);
extern
int
sysv_sync_inode
(
struct
inode
*
);
extern
int
sysv_sync_file
(
struct
inode
*
,
struct
file
*
);
extern
int
sysv_sync_file
(
struct
inode
*
,
struct
file
*
);
#if 0
extern
int
sysv_mmap
(
struct
inode
*
,
struct
file
*
,
unsigned
long
,
size_t
,
int
,
unsigned
long
);
extern
int
sysv_mmap
(
struct
inode
*
,
struct
file
*
,
unsigned
long
,
size_t
,
int
,
unsigned
long
);
#endif
extern
struct
inode_operations
sysv_file_inode_operations
;
extern
struct
inode_operations
sysv_file_inode_operations
;
extern
struct
inode_operations
sysv_file_inode_operations_with_bmap
;
extern
struct
inode_operations
sysv_file_inode_operations_with_bmap
;
...
...
init/main.c
View file @
eebbb0b8
...
@@ -420,6 +420,7 @@ asmlinkage void start_kernel(void)
...
@@ -420,6 +420,7 @@ asmlinkage void start_kernel(void)
#endif
#endif
memory_start
=
inode_init
(
memory_start
,
memory_end
);
memory_start
=
inode_init
(
memory_start
,
memory_end
);
memory_start
=
file_table_init
(
memory_start
,
memory_end
);
memory_start
=
file_table_init
(
memory_start
,
memory_end
);
memory_start
=
name_cache_init
(
memory_start
,
memory_end
);
mem_init
(
low_memory_start
,
memory_start
,
memory_end
);
mem_init
(
low_memory_start
,
memory_start
,
memory_end
);
buffer_init
();
buffer_init
();
time_init
();
time_init
();
...
...
kernel/Makefile
View file @
eebbb0b8
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
.c.s
:
.c.s
:
$(CC)
$(CFLAGS)
-S
$<
$(CC)
$(CFLAGS)
-S
$<
.s.o
:
.s.o
:
$(AS)
-
c
-
o
$*
.o
$<
$(AS)
-o
$*
.o
$<
.c.o
:
.c.o
:
$(CC)
$(CFLAGS)
-c
$<
$(CC)
$(CFLAGS)
-c
$<
...
...
kernel/ksyms.c
View file @
eebbb0b8
...
@@ -77,10 +77,8 @@ struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */
...
@@ -77,10 +77,8 @@ struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */
X
(
verify_area
),
X
(
verify_area
),
X
(
do_mmap
),
X
(
do_mmap
),
X
(
do_munmap
),
X
(
do_munmap
),
X
(
insert_vm_struct
),
X
(
zeromap_page_range
),
X
(
zeromap_page_range
),
X
(
unmap_page_range
),
X
(
unmap_page_range
),
X
(
merge_segments
),
/* internal kernel memory management */
/* internal kernel memory management */
X
(
__get_free_pages
),
X
(
__get_free_pages
),
...
...
kernel/sched.c
View file @
eebbb0b8
...
@@ -62,6 +62,7 @@ long time_adjust = 0;
...
@@ -62,6 +62,7 @@ long time_adjust = 0;
long
time_adjust_step
=
0
;
long
time_adjust_step
=
0
;
int
need_resched
=
0
;
int
need_resched
=
0
;
unsigned
long
event
=
0
;
/*
/*
* Tell us the machine setup..
* Tell us the machine setup..
...
@@ -278,7 +279,7 @@ void wake_up(struct wait_queue **q)
...
@@ -278,7 +279,7 @@ void wake_up(struct wait_queue **q)
if
((
p
->
state
==
TASK_UNINTERRUPTIBLE
)
||
if
((
p
->
state
==
TASK_UNINTERRUPTIBLE
)
||
(
p
->
state
==
TASK_INTERRUPTIBLE
))
{
(
p
->
state
==
TASK_INTERRUPTIBLE
))
{
p
->
state
=
TASK_RUNNING
;
p
->
state
=
TASK_RUNNING
;
if
(
p
->
counter
>
current
->
counter
)
if
(
p
->
counter
>
current
->
counter
+
3
)
need_resched
=
1
;
need_resched
=
1
;
}
}
}
}
...
@@ -304,7 +305,7 @@ void wake_up_interruptible(struct wait_queue **q)
...
@@ -304,7 +305,7 @@ void wake_up_interruptible(struct wait_queue **q)
if
((
p
=
tmp
->
task
)
!=
NULL
)
{
if
((
p
=
tmp
->
task
)
!=
NULL
)
{
if
(
p
->
state
==
TASK_INTERRUPTIBLE
)
{
if
(
p
->
state
==
TASK_INTERRUPTIBLE
)
{
p
->
state
=
TASK_RUNNING
;
p
->
state
=
TASK_RUNNING
;
if
(
p
->
counter
>
current
->
counter
)
if
(
p
->
counter
>
current
->
counter
+
3
)
need_resched
=
1
;
need_resched
=
1
;
}
}
}
}
...
...
kernel/sys.c
View file @
eebbb0b8
...
@@ -299,8 +299,8 @@ asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
...
@@ -299,8 +299,8 @@ asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
int
old_ruid
=
current
->
uid
;
int
old_ruid
=
current
->
uid
;
if
(
ruid
!=
(
uid_t
)
-
1
)
{
if
(
ruid
!=
(
uid_t
)
-
1
)
{
if
((
current
->
euid
==
ruid
)
||
if
((
old_ruid
==
ruid
)
||
(
old_ruid
==
ruid
)
||
(
current
->
euid
==
ruid
)
||
suser
())
suser
())
current
->
uid
=
ruid
;
current
->
uid
=
ruid
;
else
else
...
@@ -309,6 +309,7 @@ asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
...
@@ -309,6 +309,7 @@ asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
if
(
euid
!=
(
uid_t
)
-
1
)
{
if
(
euid
!=
(
uid_t
)
-
1
)
{
if
((
old_ruid
==
euid
)
||
if
((
old_ruid
==
euid
)
||
(
current
->
euid
==
euid
)
||
(
current
->
euid
==
euid
)
||
(
current
->
suid
==
euid
)
||
suser
())
suser
())
current
->
euid
=
euid
;
current
->
euid
=
euid
;
else
{
else
{
...
...
mm/mmap.c
View file @
eebbb0b8
...
@@ -154,13 +154,15 @@ int do_mmap(struct file * file, unsigned long addr, unsigned long len,
...
@@ -154,13 +154,15 @@ int do_mmap(struct file * file, unsigned long addr, unsigned long len,
else
else
error
=
anon_map
(
NULL
,
NULL
,
vma
);
error
=
anon_map
(
NULL
,
NULL
,
vma
);
if
(
!
error
)
if
(
error
)
{
return
addr
;
kfree
(
vma
);
kfree
(
vma
);
if
(
!
current
->
errno
)
if
(
!
current
->
errno
)
current
->
errno
=
-
error
;
current
->
errno
=
-
error
;
return
-
1
;
return
-
1
;
}
insert_vm_struct
(
current
,
vma
);
merge_segments
(
current
->
mm
->
mmap
);
return
addr
;
}
}
asmlinkage
int
sys_mmap
(
unsigned
long
*
buffer
)
asmlinkage
int
sys_mmap
(
unsigned
long
*
buffer
)
...
@@ -336,7 +338,6 @@ int do_munmap(unsigned long addr, size_t len)
...
@@ -336,7 +338,6 @@ int do_munmap(unsigned long addr, size_t len)
int
generic_mmap
(
struct
inode
*
inode
,
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
int
generic_mmap
(
struct
inode
*
inode
,
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
{
{
extern
struct
vm_operations_struct
file_mmap
;
extern
struct
vm_operations_struct
file_mmap
;
struct
buffer_head
*
bh
;
if
(
vma
->
vm_page_prot
&
PAGE_RW
)
/* only PAGE_COW or read-only supported right now */
if
(
vma
->
vm_page_prot
&
PAGE_RW
)
/* only PAGE_COW or read-only supported right now */
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -346,54 +347,33 @@ int generic_mmap(struct inode * inode, struct file * file, struct vm_area_struct
...
@@ -346,54 +347,33 @@ int generic_mmap(struct inode * inode, struct file * file, struct vm_area_struct
return
-
EACCES
;
return
-
EACCES
;
if
(
!
inode
->
i_op
||
!
inode
->
i_op
->
bmap
)
if
(
!
inode
->
i_op
||
!
inode
->
i_op
->
bmap
)
return
-
ENOEXEC
;
return
-
ENOEXEC
;
if
(
!
(
bh
=
bread
(
inode
->
i_dev
,
bmap
(
inode
,
0
),
inode
->
i_sb
->
s_blocksize
)))
return
-
EACCES
;
if
(
!
IS_RDONLY
(
inode
))
{
if
(
!
IS_RDONLY
(
inode
))
{
inode
->
i_atime
=
CURRENT_TIME
;
inode
->
i_atime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
inode
->
i_dirt
=
1
;
}
}
brelse
(
bh
);
unmap_page_range
(
vma
->
vm_start
,
vma
->
vm_end
-
vma
->
vm_start
);
vma
->
vm_inode
=
inode
;
vma
->
vm_inode
=
inode
;
inode
->
i_count
++
;
inode
->
i_count
++
;
vma
->
vm_ops
=
&
file_mmap
;
vma
->
vm_ops
=
&
file_mmap
;
insert_vm_struct
(
current
,
vma
);
merge_segments
(
current
->
mm
->
mmap
);
return
0
;
return
0
;
}
}
/*
/*
* Insert vm structure into process list
* Insert vm structure into process list sorted by address.
* This makes sure the list is sorted by start address, and
* some some simple overlap checking.
* JSGF
*/
*/
void
insert_vm_struct
(
struct
task_struct
*
t
,
struct
vm_area_struct
*
vmp
)
void
insert_vm_struct
(
struct
task_struct
*
t
,
struct
vm_area_struct
*
vmp
)
{
{
struct
vm_area_struct
**
nxtpp
,
*
mpnt
;
struct
vm_area_struct
**
p
,
*
mpnt
;
nxtpp
=
&
t
->
mm
->
mmap
;
for
(
mpnt
=
t
->
mm
->
mmap
;
mpnt
!=
NULL
;
mpnt
=
mpnt
->
vm_next
)
p
=
&
t
->
mm
->
mmap
;
{
while
((
mpnt
=
*
p
)
!=
NULL
)
{
if
(
mpnt
->
vm_start
>
vmp
->
vm_start
)
if
(
mpnt
->
vm_start
>
vmp
->
vm_start
)
break
;
break
;
nxtpp
=
&
mpnt
->
vm_next
;
if
(
mpnt
->
vm_end
>
vmp
->
vm_start
)
printk
(
"insert_vm_struct: overlapping memory areas
\n
"
);
if
((
vmp
->
vm_start
>=
mpnt
->
vm_start
&&
p
=
&
mpnt
->
vm_next
;
vmp
->
vm_start
<
mpnt
->
vm_end
)
||
(
vmp
->
vm_end
>=
mpnt
->
vm_start
&&
vmp
->
vm_end
<
mpnt
->
vm_end
))
printk
(
"insert_vm_struct: ins area %lx-%lx in area %lx-%lx
\n
"
,
vmp
->
vm_start
,
vmp
->
vm_end
,
mpnt
->
vm_start
,
vmp
->
vm_end
);
}
}
vmp
->
vm_next
=
mpnt
;
vmp
->
vm_next
=
mpnt
;
*
p
=
vmp
;
*
nxtpp
=
vmp
;
}
}
/*
/*
...
@@ -456,8 +436,5 @@ static int anon_map(struct inode *ino, struct file * file, struct vm_area_struct
...
@@ -456,8 +436,5 @@ static int anon_map(struct inode *ino, struct file * file, struct vm_area_struct
{
{
if
(
zeromap_page_range
(
vma
->
vm_start
,
vma
->
vm_end
-
vma
->
vm_start
,
vma
->
vm_page_prot
))
if
(
zeromap_page_range
(
vma
->
vm_start
,
vma
->
vm_end
-
vma
->
vm_start
,
vma
->
vm_page_prot
))
return
-
ENOMEM
;
return
-
ENOMEM
;
insert_vm_struct
(
current
,
vma
);
merge_segments
(
current
->
mm
->
mmap
);
return
0
;
return
0
;
}
}
mm/swap.c
View file @
eebbb0b8
...
@@ -353,7 +353,7 @@ static inline int try_to_swap_out(unsigned long * table_ptr)
...
@@ -353,7 +353,7 @@ static inline int try_to_swap_out(unsigned long * table_ptr)
*
*
* (C) 1993 Kai Petzke, wpp@marie.physik.tu-berlin.de
* (C) 1993 Kai Petzke, wpp@marie.physik.tu-berlin.de
*/
*/
#ifdef NEW_SWAP
/*
/*
* These are the miminum and maximum number of pages to swap from one process,
* These are the miminum and maximum number of pages to swap from one process,
* before proceeding to the next:
* before proceeding to the next:
...
@@ -367,68 +367,31 @@ static inline int try_to_swap_out(unsigned long * table_ptr)
...
@@ -367,68 +367,31 @@ static inline int try_to_swap_out(unsigned long * table_ptr)
*/
*/
#define SWAP_RATIO 128
#define SWAP_RATIO 128
static
int
swap_out
(
unsigned
int
priority
)
static
int
swap_out
_process
(
struct
task_struct
*
p
)
{
{
static
int
swap_task
;
unsigned
long
address
;
int
table
;
unsigned
long
offset
;
int
page
;
unsigned
long
*
pgdir
;
long
pg_table
;
unsigned
long
pg_table
;
int
loop
;
int
counter
=
NR_TASKS
*
2
>>
priority
;
struct
task_struct
*
p
;
counter
=
NR_TASKS
*
2
>>
priority
;
for
(;
counter
>=
0
;
counter
--
,
swap_task
++
)
{
/*
* Check that swap_task is suitable for swapping. If not, look for
* the next suitable process.
*/
loop
=
0
;
while
(
1
)
{
if
(
swap_task
>=
NR_TASKS
)
{
swap_task
=
1
;
if
(
loop
)
/* all processes are unswappable or already swapped out */
return
0
;
loop
=
1
;
}
p
=
task
[
swap_task
];
if
(
p
&&
p
->
mm
->
swappable
&&
p
->
mm
->
rss
)
break
;
swap_task
++
;
}
/*
* Determine the number of pages to swap from this process.
*/
if
(
!
p
->
mm
->
swap_cnt
)
{
p
->
mm
->
dec_flt
=
(
p
->
mm
->
dec_flt
*
3
)
/
4
+
p
->
mm
->
maj_flt
-
p
->
mm
->
old_maj_flt
;
p
->
mm
->
old_maj_flt
=
p
->
mm
->
maj_flt
;
if
(
p
->
mm
->
dec_flt
>=
SWAP_RATIO
/
SWAP_MIN
)
{
p
->
mm
->
dec_flt
=
SWAP_RATIO
/
SWAP_MIN
;
p
->
mm
->
swap_cnt
=
SWAP_MIN
;
}
else
if
(
p
->
mm
->
dec_flt
<=
SWAP_RATIO
/
SWAP_MAX
)
p
->
mm
->
swap_cnt
=
SWAP_MAX
;
else
p
->
mm
->
swap_cnt
=
SWAP_RATIO
/
p
->
mm
->
dec_flt
;
}
/*
/*
* Go through process' page directory.
* Go through process' page directory.
*/
*/
for
(
table
=
p
->
mm
->
swap_table
;
table
<
1024
;
table
++
)
{
address
=
p
->
mm
->
swap_address
;
pg_table
=
((
unsigned
long
*
)
p
->
tss
.
cr3
)[
table
];
pgdir
=
(
address
>>
PGDIR_SHIFT
)
+
(
unsigned
long
*
)
p
->
tss
.
cr3
;
if
(
pg_table
>=
high_memory
)
offset
=
address
&
~
PGDIR_MASK
;
address
&=
PGDIR_MASK
;
for
(
;
address
<
TASK_SIZE
;
pgdir
++
,
address
=
address
+
PGDIR_SIZE
,
offset
=
0
)
{
pg_table
=
*
pgdir
;
if
(
pg_table
>=
high_memory
)
continue
;
continue
;
if
(
mem_map
[
MAP_NR
(
pg_table
)]
&
MAP_PAGE_RESERVED
)
if
(
mem_map
[
MAP_NR
(
pg_table
)]
&
MAP_PAGE_RESERVED
)
continue
;
continue
;
if
(
!
(
PAGE_PRESENT
&
pg_table
))
{
if
(
!
(
PAGE_PRESENT
&
pg_table
))
{
printk
(
"swap_out: bad page-table at pg_dir[%d]
: %08lx
\n
"
,
printk
(
"swap_out_process (%s): bad page-table at vm %08lx
: %08lx
\n
"
,
table
,
pg_table
);
p
->
comm
,
address
+
offset
,
pg_table
);
((
unsigned
long
*
)
p
->
tss
.
cr3
)[
table
]
=
0
;
*
pgdir
=
0
;
continue
;
continue
;
}
}
pg_table
&=
0xfffff000
;
pg_table
&=
0xfffff000
;
...
@@ -436,18 +399,15 @@ static int swap_out(unsigned int priority)
...
@@ -436,18 +399,15 @@ static int swap_out(unsigned int priority)
/*
/*
* Go through this page table.
* Go through this page table.
*/
*/
for
(
page
=
p
->
mm
->
swap_page
;
page
<
1024
;
page
++
)
{
for
(
;
offset
<
~
PGDIR_MASK
;
offset
+=
PAGE_SIZE
)
{
switch
(
try_to_swap_out
(
page
+
(
unsigned
long
*
)
pg_table
))
{
switch
(
try_to_swap_out
((
unsigned
long
*
)
(
pg_table
+
(
offset
>>
10
))
))
{
case
0
:
case
0
:
break
;
break
;
case
1
:
case
1
:
p
->
mm
->
rss
--
;
p
->
mm
->
rss
--
;
/* continue with the following page the next time */
/* continue with the following page the next time */
p
->
mm
->
swap_table
=
table
;
p
->
mm
->
swap_address
=
address
+
offset
+
PAGE_SIZE
;
p
->
mm
->
swap_page
=
page
+
1
;
if
((
--
p
->
mm
->
swap_cnt
)
==
0
)
swap_task
++
;
return
1
;
return
1
;
default:
default:
...
@@ -455,87 +415,69 @@ static int swap_out(unsigned int priority)
...
@@ -455,87 +415,69 @@ static int swap_out(unsigned int priority)
break
;
break
;
}
}
}
}
p
->
mm
->
swap_page
=
0
;
}
}
/*
/*
* Finish work with this process, if we reached the end of the page
* Finish work with this process, if we reached the end of the page
* directory. Mark restart from the beginning the next time.
* directory. Mark restart from the beginning the next time.
*/
*/
p
->
mm
->
swap_table
=
0
;
p
->
mm
->
swap_address
=
0
;
}
return
0
;
return
0
;
}
}
#else
/* old swapping procedure */
/*
* Go through the page tables, searching for a user page that
* we can swap out.
*
* We now check that the process is swappable (normally only 'init'
* is un-swappable), allowing high-priority processes which cannot be
* swapped out (things like user-level device drivers (Not implemented)).
*/
static
int
swap_out
(
unsigned
int
priority
)
static
int
swap_out
(
unsigned
int
priority
)
{
{
static
int
swap_task
=
1
;
static
int
swap_task
;
static
int
swap_table
=
0
;
int
loop
;
static
int
swap_page
=
0
;
int
counter
=
NR_TASKS
*
2
>>
priority
;
int
counter
=
NR_TASKS
*
8
;
struct
task_struct
*
p
;
int
pg_table
;
struct
task_struct
*
p
;
counter
=
NR_TASKS
*
2
>>
priority
;
for
(;
counter
>=
0
;
counter
--
,
swap_task
++
)
{
counter
>>=
priority
;
/*
check_task:
* Check that swap_task is suitable for swapping. If not, look for
if
(
counter
--
<
0
)
* the next suitable process.
return
0
;
*/
loop
=
0
;
while
(
1
)
{
if
(
swap_task
>=
NR_TASKS
)
{
if
(
swap_task
>=
NR_TASKS
)
{
swap_task
=
1
;
swap_task
=
1
;
goto
check_task
;
if
(
loop
)
/* all processes are unswappable or already swapped out */
return
0
;
loop
=
1
;
}
}
p
=
task
[
swap_task
];
p
=
task
[
swap_task
];
if
(
!
p
||
!
p
->
mm
->
swappable
)
{
if
(
p
&&
p
->
mm
->
swappable
&&
p
->
mm
->
rss
)
break
;
swap_task
++
;
swap_task
++
;
goto
check_task
;
}
}
check_dir:
if
(
swap_table
>=
PTRS_PER_PAGE
)
{
/*
swap_table
=
0
;
* Determine the number of pages to swap from this process.
*/
if
(
!
p
->
mm
->
swap_cnt
)
{
p
->
mm
->
dec_flt
=
(
p
->
mm
->
dec_flt
*
3
)
/
4
+
p
->
mm
->
maj_flt
-
p
->
mm
->
old_maj_flt
;
p
->
mm
->
old_maj_flt
=
p
->
mm
->
maj_flt
;
if
(
p
->
mm
->
dec_flt
>=
SWAP_RATIO
/
SWAP_MIN
)
{
p
->
mm
->
dec_flt
=
SWAP_RATIO
/
SWAP_MIN
;
p
->
mm
->
swap_cnt
=
SWAP_MIN
;
}
else
if
(
p
->
mm
->
dec_flt
<=
SWAP_RATIO
/
SWAP_MAX
)
p
->
mm
->
swap_cnt
=
SWAP_MAX
;
else
p
->
mm
->
swap_cnt
=
SWAP_RATIO
/
p
->
mm
->
dec_flt
;
}
if
(
swap_out_process
(
p
))
{
if
((
--
p
->
mm
->
swap_cnt
)
==
0
)
swap_task
++
;
swap_task
++
;
goto
check_task
;
return
1
;
}
}
pg_table
=
((
unsigned
long
*
)
p
->
tss
.
cr3
)[
swap_table
];
if
(
pg_table
>=
high_memory
||
(
mem_map
[
MAP_NR
(
pg_table
)]
&
MAP_PAGE_RESERVED
))
{
swap_table
++
;
goto
check_dir
;
}
}
if
(
!
(
PAGE_PRESENT
&
pg_table
))
{
return
0
;
printk
(
"bad page-table at pg_dir[%d]: %08x
\n
"
,
swap_table
,
pg_table
);
((
unsigned
long
*
)
p
->
tss
.
cr3
)[
swap_table
]
=
0
;
swap_table
++
;
goto
check_dir
;
}
pg_table
&=
PAGE_MASK
;
check_table:
if
(
swap_page
>=
PTRS_PER_PAGE
)
{
swap_page
=
0
;
swap_table
++
;
goto
check_dir
;
}
switch
(
try_to_swap_out
(
swap_page
+
(
unsigned
long
*
)
pg_table
))
{
case
0
:
break
;
case
1
:
p
->
mm
->
rss
--
;
return
1
;
default:
p
->
mm
->
rss
--
;
}
swap_page
++
;
goto
check_table
;
}
}
#endif
static
int
try_to_free_page
(
int
priority
)
static
int
try_to_free_page
(
int
priority
)
{
{
int
i
=
6
;
int
i
=
6
;
...
@@ -599,6 +541,21 @@ static inline void free_pages_ok(unsigned long addr, unsigned long order)
...
@@ -599,6 +541,21 @@ static inline void free_pages_ok(unsigned long addr, unsigned long order)
add_mem_queue
(
free_area_list
+
order
,
(
struct
mem_list
*
)
addr
);
add_mem_queue
(
free_area_list
+
order
,
(
struct
mem_list
*
)
addr
);
}
}
static
inline
void
check_free_buffers
(
unsigned
long
addr
)
{
struct
buffer_head
*
bh
;
bh
=
buffer_pages
[
MAP_NR
(
addr
)];
if
(
bh
)
{
struct
buffer_head
*
tmp
=
bh
;
do
{
if
(
tmp
->
b_list
==
BUF_SHARED
&&
tmp
->
b_dev
!=
0xffff
)
refile_buffer
(
tmp
);
tmp
=
tmp
->
b_this_page
;
}
while
(
tmp
!=
bh
);
}
}
void
free_pages
(
unsigned
long
addr
,
unsigned
long
order
)
void
free_pages
(
unsigned
long
addr
,
unsigned
long
order
)
{
{
if
(
addr
<
high_memory
)
{
if
(
addr
<
high_memory
)
{
...
@@ -613,17 +570,8 @@ void free_pages(unsigned long addr, unsigned long order)
...
@@ -613,17 +570,8 @@ void free_pages(unsigned long addr, unsigned long order)
delete_from_swap_cache
(
addr
);
delete_from_swap_cache
(
addr
);
}
}
restore_flags
(
flag
);
restore_flags
(
flag
);
if
(
*
map
==
1
)
{
if
(
*
map
==
1
)
int
j
;
check_free_buffers
(
addr
);
struct
buffer_head
*
bh
,
*
tmp
;
bh
=
buffer_pages
[
MAP_NR
(
addr
)];
if
(
bh
)
for
(
j
=
0
,
tmp
=
bh
;
tmp
&&
(
!
j
||
tmp
!=
bh
);
tmp
=
tmp
->
b_this_page
,
j
++
)
if
(
tmp
->
b_list
==
BUF_SHARED
&&
tmp
->
b_dev
!=
0xffff
)
refile_buffer
(
tmp
);
}
}
}
return
;
return
;
}
}
...
...
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