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
f4a818e0
Commit
f4a818e0
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 1.1.55
parent
057f54fb
Changes
23
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
348 additions
and
245 deletions
+348
-245
Makefile
Makefile
+1
-1
drivers/block/floppy.c
drivers/block/floppy.c
+11
-10
drivers/block/hd.c
drivers/block/hd.c
+140
-167
drivers/char/lp.c
drivers/char/lp.c
+8
-0
drivers/sound/Makefile
drivers/sound/Makefile
+5
-1
fs/binfmt_elf.c
fs/binfmt_elf.c
+2
-2
fs/ext/dir.c
fs/ext/dir.c
+17
-5
fs/ext2/dir.c
fs/ext2/dir.c
+70
-24
fs/ext2/namei.c
fs/ext2/namei.c
+5
-2
fs/hpfs/hpfs_fs.c
fs/hpfs/hpfs_fs.c
+6
-3
fs/isofs/dir.c
fs/isofs/dir.c
+4
-1
fs/minix/dir.c
fs/minix/dir.c
+14
-6
fs/minix/namei.c
fs/minix/namei.c
+6
-1
fs/msdos/dir.c
fs/msdos/dir.c
+5
-2
fs/nfs/dir.c
fs/nfs/dir.c
+4
-1
fs/proc/link.c
fs/proc/link.c
+2
-1
fs/read_write.c
fs/read_write.c
+12
-4
fs/sysv/dir.c
fs/sysv/dir.c
+4
-1
fs/xiafs/dir.c
fs/xiafs/dir.c
+17
-5
include/linux/hdreg.h
include/linux/hdreg.h
+0
-1
include/linux/tty.h
include/linux/tty.h
+1
-0
kernel/ksyms.c
kernel/ksyms.c
+4
-0
net/inet/tcp.c
net/inet/tcp.c
+10
-7
No files found.
Makefile
View file @
f4a818e0
VERSION
=
1
PATCHLEVEL
=
1
SUBLEVEL
=
5
4
SUBLEVEL
=
5
5
ARCH
=
i386
...
...
drivers/block/floppy.c
View file @
f4a818e0
...
...
@@ -25,9 +25,9 @@
/* Define the following if you don't like that your drives seek audibly
* after a disk change
* after a disk change
(but it may not work correctly for everybody)
*/
#define SILENT_DC_CLEAR
/* #define SILENT_DC_CLEAR */
/* End of configuration */
...
...
@@ -304,7 +304,7 @@ static struct floppy_struct floppy_type[32] = {
{
5760
,
36
,
2
,
80
,
0
,
0x1B
,
0x43
,
0xAF
,
0x54
,
"CompaQ"
},
/* 9 2.88MB 3.5" */
{
2880
,
18
,
2
,
80
,
0
,
0x25
,
0x00
,
0xDF
,
0x02
,
"h1440"
},
/* 10 1.44MB 5.25" */
{
3360
,
21
,
2
,
80
,
0
,
0x1C
,
0x00
,
0xCF
,
0x
6
C
,
"H1680"
},
/* 11 1.68MB 3.5" */
{
3360
,
21
,
2
,
80
,
0
,
0x1C
,
0x00
,
0xCF
,
0x
0
C
,
"H1680"
},
/* 11 1.68MB 3.5" */
{
820
,
10
,
2
,
41
,
1
,
0x25
,
0x01
,
0xDF
,
0x2E
,
"h410"
},
/* 12 410KB 5.25" */
{
1640
,
10
,
2
,
82
,
0
,
0x25
,
0x02
,
0xDF
,
0x2E
,
"H820"
},
/* 13 820KB 3.5" */
{
2952
,
18
,
2
,
82
,
0
,
0x25
,
0x00
,
0xDF
,
0x02
,
"h1476"
},
/* 14 1.48MB 5.25" */
...
...
@@ -317,8 +317,8 @@ static struct floppy_struct floppy_type[32] = {
{
1760
,
11
,
2
,
80
,
0
,
0x1C
,
0x09
,
0xCF
,
0x6C
,
"h880"
},
/* 20 880KB 5.25" */
{
2080
,
13
,
2
,
80
,
0
,
0x1C
,
0x01
,
0xCF
,
0x6C
,
"D1040"
},
/* 21 1.04MB 3.5" */
{
2240
,
14
,
2
,
80
,
0
,
0x1C
,
0x19
,
0xCF
,
0x6C
,
"D1120"
},
/* 22 1.12MB 3.5" */
{
3200
,
20
,
2
,
80
,
0
,
0x1C
,
0x20
,
0xCF
,
0x
6
C
,
"h1600"
},
/* 23 1.6MB 5.25" */
{
3520
,
22
,
2
,
80
,
0
,
0x1C
,
0x08
,
0xCF
,
0x
6C
,
"H1760"
},
/* 24 1.76MB 3.5" */
{
3200
,
20
,
2
,
80
,
0
,
0x1C
,
0x20
,
0xCF
,
0x
2
C
,
"h1600"
},
/* 23 1.6MB 5.25" */
{
3520
,
22
,
2
,
80
,
0
,
0x1C
,
0x08
,
0xCF
,
0x
2e
,
"H1760"
},
/* 24 1.76MB 3.5" */
{
3840
,
24
,
2
,
80
,
0
,
0x1C
,
0x20
,
0xCF
,
0x6C
,
"H1920"
},
/* 25 1.92MB 3.5" */
{
6400
,
40
,
2
,
80
,
0
,
0x25
,
0x5B
,
0xCF
,
0x6C
,
"E3200"
},
/* 26 3.20MB 3.5" */
{
7040
,
44
,
2
,
80
,
0
,
0x25
,
0x5B
,
0xCF
,
0x6C
,
"E3520"
},
/* 27 3.52MB 3.5" */
...
...
@@ -326,7 +326,7 @@ static struct floppy_struct floppy_type[32] = {
{
3680
,
23
,
2
,
80
,
0
,
0x1C
,
0x10
,
0xCF
,
0x6C
,
"H1840"
},
/* 29 1.84MB 3.5" */
{
1600
,
10
,
2
,
80
,
0
,
0x25
,
0x02
,
0xDF
,
0x2E
,
"D800"
},
/* 30 800KB 3.5" */
{
3200
,
20
,
2
,
80
,
0
,
0x1C
,
0x00
,
0xCF
,
0x
6
C
,
"H1600"
},
/* 31 1.6MB 3.5" */
{
3200
,
20
,
2
,
80
,
0
,
0x1C
,
0x00
,
0xCF
,
0x
2
C
,
"H1600"
},
/* 31 1.6MB 3.5" */
};
#define NUMBER(x) (sizeof(x) / sizeof(*(x)))
...
...
@@ -1278,9 +1278,10 @@ static void recal_interrupt(void)
debugt
(
"recal interrupt need 1 recal:"
);
#endif
/* after a second recalibrate, we still haven't
* reached track 0. Probably no drive */
DRS
->
track
=
PROVEN_ABSENT
;
cont
->
done
(
0
);
* reached track 0. Probably no drive. Raise an
* error, as failing immediately might upset
* computers possessed by the Devil :-) */
cont
->
error
();
cont
->
redo
();
return
;
case
NEED_2_RECAL
:
...
...
@@ -1691,7 +1692,7 @@ static void setup_format_params(void)
int
count
,
head_shift
,
track_shift
;
raw_cmd
.
flags
=
FD_RAW_WRITE
|
FD_RAW_INTR
|
FD_RAW_SPIN
|
FD_RAW_NEED_DISK
|
FD_RAW_NEED_SEEK
;
/*FD_RAW_NEED_DISK |*/
FD_RAW_NEED_SEEK
;
raw_cmd
.
rate
=
floppy
->
rate
&
0x3
;
raw_cmd
.
cmd_count
=
NR_F
;
COMMAND
=
FM_MODE
(
floppy
,
FD_FORMAT
);
...
...
drivers/block/hd.c
View file @
f4a818e0
...
...
@@ -15,10 +15,8 @@
* Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
* in the early extended-partition checks and added DM partitions
*
* IDE IRQ-unmask & drive-id & multiple-mode code added by Mark Lord.
*
* Support for BIOS drive geometry translation added by Mark Lord.
* -- hd.c no longer chokes on drives with "more than 16 heads".
* IRQ-unmask, drive-id, multiple-mode, support for ">16 heads",
* and general streamlining by mlord@bnr.ca (Mark Lord).
*/
#define DEFAULT_MULT_COUNT 0
/* set to 0 to disable multiple mode at boot */
...
...
@@ -62,6 +60,9 @@ static inline unsigned char CMOS_READ(unsigned char addr)
#define RECAL_FREQ 4
/* Recalibrate every 4th retry */
#define MAX_HD 2
#define STAT_OK (READY_STAT|SEEK_STAT)
#define OK_STATUS(s) (((s)&(STAT_OK|(BUSY_STAT|WRERR_STAT|ERR_STAT)))==STAT_OK)
static
void
recal_intr
(
void
);
static
void
bad_rw_intr
(
void
);
...
...
@@ -135,12 +136,12 @@ void hd_setup(char *str, int *ints)
static
void
dump_status
(
char
*
msg
,
unsigned
int
stat
)
{
unsigned
long
flags
;
char
dev
;
char
dev
c
;
dev
=
CURRENT
?
'a'
+
DEVICE_NR
(
CURRENT
->
dev
)
:
'?'
;
dev
c
=
CURRENT
?
'a'
+
DEVICE_NR
(
CURRENT
->
dev
)
:
'?'
;
save_flags
(
flags
);
sti
();
printk
(
"hd%c: %s: status=0x%02x { "
,
dev
,
msg
,
stat
&
0xff
);
printk
(
"hd%c: %s: status=0x%02x { "
,
dev
c
,
msg
,
stat
&
0xff
);
if
(
stat
&
BUSY_STAT
)
printk
(
"Busy "
);
if
(
stat
&
READY_STAT
)
printk
(
"DriveReady "
);
if
(
stat
&
WRERR_STAT
)
printk
(
"WriteFault "
);
...
...
@@ -150,55 +151,48 @@ static void dump_status (char *msg, unsigned int stat)
if
(
stat
&
INDEX_STAT
)
printk
(
"Index "
);
if
(
stat
&
ERR_STAT
)
printk
(
"Error "
);
printk
(
"}
\n
"
);
if
(
stat
&
ERR_STAT
)
{
unsigned
int
err
=
inb
(
HD_ERROR
);
printk
(
"hd%c: %s: error=0x%02x { "
,
dev
,
msg
,
err
&
0xff
);
if
(
err
&
BBD_ERR
)
printk
(
"BadSector "
);
if
(
err
&
ECC_ERR
)
printk
(
"UncorrectableError "
);
if
(
err
&
ID_ERR
)
printk
(
"SectorIdNotFound "
);
if
(
err
&
ABRT_ERR
)
printk
(
"DriveStatusError "
);
if
(
err
&
TRK0_ERR
)
printk
(
"TrackZeroNotFound "
);
if
(
err
&
MARK_ERR
)
printk
(
"AddrMarkNotFound "
);
if
((
stat
&
ERR_STAT
)
==
0
)
{
hd_error
=
0
;
}
else
{
hd_error
=
inb
(
HD_ERROR
);
printk
(
"hd%c: %s: error=0x%02x { "
,
devc
,
msg
,
hd_error
&
0xff
);
if
(
hd_error
&
BBD_ERR
)
printk
(
"BadSector "
);
if
(
hd_error
&
ECC_ERR
)
printk
(
"UncorrectableError "
);
if
(
hd_error
&
ID_ERR
)
printk
(
"SectorIdNotFound "
);
if
(
hd_error
&
ABRT_ERR
)
printk
(
"DriveStatusError "
);
if
(
hd_error
&
TRK0_ERR
)
printk
(
"TrackZeroNotFound "
);
if
(
hd_error
&
MARK_ERR
)
printk
(
"AddrMarkNotFound "
);
printk
(
"}"
);
if
(
err
&
(
BBD_ERR
|
ECC_ERR
|
ID_ERR
|
MARK_ERR
))
{
if
(
CURRENT
)
printk
(
", sector=%ld"
,
CURRENT
->
sector
);
if
(
hd_error
&
(
BBD_ERR
|
ECC_ERR
|
ID_ERR
|
MARK_ERR
))
{
printk
(
", CHS=%d/%d/%d"
,
(
inb
(
HD_HCYL
)
<<
8
)
+
inb
(
HD_LCYL
),
inb
(
HD_CURRENT
)
&
0xf
,
inb
(
HD_SECTOR
));
if
(
CURRENT
)
printk
(
", sector=%ld"
,
CURRENT
->
sector
);
}
printk
(
"
\n
"
);
}
restore_flags
(
flags
);
}
static
int
win_result
(
void
)
void
check_status
(
void
)
{
int
i
=
inb_p
(
HD_STATUS
);
int
i
=
inb_p
(
HD_STATUS
);
if
((
i
&
(
BUSY_STAT
|
READY_STAT
|
WRERR_STAT
|
SEEK_STAT
|
ERR_STAT
))
==
(
READY_STAT
|
SEEK_STAT
))
{
hd_error
=
0
;
return
0
;
/* ok */
if
(
!
OK_STATUS
(
i
))
{
dump_status
(
"check_status"
,
i
);
bad_rw_intr
();
}
dump_status
(
"win_result"
,
i
);
return
1
;
}
static
int
controller_busy
(
void
);
static
int
status_ok
(
void
);
static
int
controller_ready
(
unsigned
int
drive
,
unsigned
int
head
)
static
int
controller_busy
(
void
)
{
int
retry
=
100
;
int
retries
=
100000
;
unsigned
char
status
;
do
{
if
(
controller_busy
()
&
BUSY_STAT
)
return
0
;
outb_p
(
0xA0
|
(
drive
<<
4
)
|
head
,
HD_CURRENT
);
if
(
status_ok
())
return
1
;
}
while
(
--
retry
);
return
0
;
status
=
inb_p
(
HD_STATUS
);
}
while
((
status
&
BUSY_STAT
)
&&
--
retries
);
return
status
;
}
static
int
status_ok
(
void
)
...
...
@@ -206,7 +200,7 @@ static int status_ok(void)
unsigned
char
status
=
inb_p
(
HD_STATUS
);
if
(
status
&
BUSY_STAT
)
return
1
;
return
1
;
/* Ancient, but does it make sense??? */
if
(
status
&
WRERR_STAT
)
return
0
;
if
(
!
(
status
&
READY_STAT
))
...
...
@@ -216,15 +210,18 @@ static int status_ok(void)
return
1
;
}
static
int
controller_
busy
(
voi
d
)
static
int
controller_
ready
(
unsigned
int
drive
,
unsigned
int
hea
d
)
{
int
retries
=
100000
;
unsigned
char
status
;
int
retry
=
100
;
do
{
status
=
inb_p
(
HD_STATUS
);
}
while
((
status
&
BUSY_STAT
)
&&
--
retries
);
return
status
;
if
(
controller_busy
()
&
BUSY_STAT
)
return
0
;
outb_p
(
0xA0
|
(
drive
<<
4
)
|
head
,
HD_CURRENT
);
if
(
status_ok
())
return
1
;
}
while
(
--
retry
);
return
0
;
}
static
void
hd_out
(
unsigned
int
drive
,
unsigned
int
nsect
,
unsigned
int
sect
,
...
...
@@ -233,13 +230,6 @@ static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect,
{
unsigned
short
port
;
#ifdef DEBUG
if
(
drive
>
1
||
head
>
15
)
{
printk
(
"bad drive mapping, trying to access drive=%d, cyl=%d, head=%d, sect=%d
\n
"
,
drive
,
cyl
,
head
,
sect
);
panic
(
"harddisk driver problem"
);
}
#endif
#if (HD_DELAY > 0)
while
(
read_timer
()
-
last_req
<
HD_DELAY
)
/* nothing */
;
...
...
@@ -346,7 +336,7 @@ static void identify_intr(void)
/*
* Early model Quantum drives go weird at this point,
* but doing a recalibrate seems to "fix" them.
* (Doing a full reset confuses some
new
er model Quantums)
* (Doing a full reset confuses some
oth
er model Quantums)
*/
if
(
!
strncmp
(
id
->
model
,
"QUANTUM"
,
7
))
special_op
[
dev
]
=
recalibrate
[
dev
]
=
1
;
...
...
@@ -366,7 +356,7 @@ static void set_multmode_intr(void)
sti
();
if
(
stat
&
(
BUSY_STAT
|
ERR_STAT
))
{
mult_req
[
dev
]
=
mult_count
[
dev
]
=
0
;
dump_status
(
"set mult
iple
mode failed"
,
stat
);
dump_status
(
"set multmode failed"
,
stat
);
}
else
{
if
((
mult_count
[
dev
]
=
mult_req
[
dev
]))
printk
(
" hd%c: enabled %d-sector multiple mode
\n
"
,
...
...
@@ -388,8 +378,7 @@ static int drive_busy(void)
for
(
i
=
0
;
i
<
500000
;
i
++
)
{
c
=
inb_p
(
HD_STATUS
);
c
&=
(
BUSY_STAT
|
READY_STAT
|
SEEK_STAT
);
if
(
c
==
(
READY_STAT
|
SEEK_STAT
))
if
((
c
&
(
BUSY_STAT
|
READY_STAT
|
SEEK_STAT
))
==
STAT_OK
)
return
0
;
}
dump_status
(
"reset timed out"
,
c
);
...
...
@@ -405,9 +394,9 @@ static void reset_controller(void)
outb_p
(
hd_info
[
0
].
ctl
&
0x0f
,
HD_CMD
);
for
(
i
=
0
;
i
<
1000
;
i
++
)
nop
();
if
(
drive_busy
())
printk
(
"
HD-
controller still busy
\n
"
);
if
((
hd_error
=
inb
(
HD_ERROR
))
!=
1
)
printk
(
"
HD-
controller reset failed: %02x
\n
"
,
hd_error
);
printk
(
"
hd:
controller still busy
\n
"
);
else
if
((
hd_error
=
inb
(
HD_ERROR
))
!=
1
)
printk
(
"
hd:
controller reset failed: %02x
\n
"
,
hd_error
);
}
static
void
reset_hd
(
void
)
...
...
@@ -419,12 +408,13 @@ static void reset_hd(void)
reset
=
0
;
i
=
-
1
;
reset_controller
();
}
else
if
(
win_result
())
{
bad_rw_intr
();
}
else
{
check_status
();
if
(
reset
)
goto
repeat
;
}
if
(
++
i
<
NR_HD
)
{
special_op
[
i
]
=
recalibrate
[
i
]
=
1
;
if
(
unmask_intr
[
i
])
{
unmask_intr
[
i
]
=
DEFAULT_UNMASK_INTR
;
printk
(
"hd%c: reset irq-unmasking to %d
\n
"
,
i
+
'a'
,
...
...
@@ -444,7 +434,6 @@ static void reset_hd(void)
hd_request
();
}
/*
* Ok, don't know what to do with the unexpected interrupts: on some machines
* doing a reset and a retry seems to result in an eternal loop. Right now I
...
...
@@ -478,11 +467,11 @@ static void bad_rw_intr(void)
dev
=
DEVICE_NR
(
CURRENT
->
dev
);
if
(
++
CURRENT
->
errors
>=
MAX_ERRORS
||
(
hd_error
&
BBD_ERR
))
{
end_request
(
0
);
special_op
[
dev
]
+
=
recalibrate
[
dev
]
=
1
;
special_op
[
dev
]
=
recalibrate
[
dev
]
=
1
;
}
else
if
(
CURRENT
->
errors
%
RESET_FREQ
==
0
)
reset
=
1
;
else
if
((
hd_error
&
TRK0_ERR
)
||
CURRENT
->
errors
%
RECAL_FREQ
==
0
)
special_op
[
dev
]
+
=
recalibrate
[
dev
]
=
1
;
special_op
[
dev
]
=
recalibrate
[
dev
]
=
1
;
/* Otherwise just retry */
}
...
...
@@ -497,9 +486,6 @@ static inline int wait_DRQ(void)
return
-
1
;
}
#define STAT_MASK (BUSY_STAT | READY_STAT | WRERR_STAT | SEEK_STAT | ERR_STAT)
#define STAT_OK (READY_STAT | SEEK_STAT)
static
void
read_intr
(
void
)
{
unsigned
int
dev
=
DEVICE_NR
(
CURRENT
->
dev
);
...
...
@@ -511,7 +497,7 @@ static void read_intr(void)
i
=
(
unsigned
)
inb_p
(
HD_STATUS
);
if
(
i
&
BUSY_STAT
)
continue
;
if
(
(
i
&
STAT_MASK
)
!=
STAT_OK
)
if
(
!
OK_STATUS
(
i
)
)
break
;
if
(
i
&
DRQ_STAT
)
goto
ok_to_read
;
...
...
@@ -534,9 +520,9 @@ static void read_intr(void)
i
=
(
CURRENT
->
nr_sectors
-=
nsect
);
#ifdef DEBUG
printk
(
"hd%c: read: sectors(%ld-%ld), remaining=%ld, buffer=%08lx
\n
"
,
printk
(
"hd%c: read: sectors(%ld-%ld), remaining=%ld, buffer=
0x
%08lx
\n
"
,
dev
+
'a'
,
CURRENT
->
sector
,
CURRENT
->
sector
+
nsect
,
CURRENT
->
nr_sectors
,
(
long
)
CURRENT
->
buffer
+
(
nsect
<<
9
));
CURRENT
->
nr_sectors
,
(
unsigned
long
)
CURRENT
->
buffer
+
(
nsect
<<
9
));
#endif
if
((
CURRENT
->
current_nr_sectors
-=
nsect
)
<=
0
)
end_request
(
1
);
...
...
@@ -581,7 +567,7 @@ static void multwrite_intr(void)
if
(
unmask_intr
[
dev
])
sti
();
if
(
((
i
=
inb_p
(
HD_STATUS
))
&
STAT_MASK
)
==
STAT_OK
)
{
if
(
OK_STATUS
(
i
=
inb_p
(
HD_STATUS
))
)
{
if
(
i
&
DRQ_STAT
)
{
if
(
WCURRENT
.
nr_sectors
)
{
multwrite
(
dev
);
...
...
@@ -619,7 +605,7 @@ static void write_intr(void)
i
=
(
unsigned
)
inb_p
(
HD_STATUS
);
if
(
i
&
BUSY_STAT
)
continue
;
if
(
(
i
&
STAT_MASK
)
!=
STAT_OK
)
if
(
!
OK_STATUS
(
i
)
)
break
;
if
((
CURRENT
->
nr_sectors
<=
1
)
||
(
i
&
DRQ_STAT
))
goto
ok_to_write
;
...
...
@@ -650,8 +636,7 @@ static void write_intr(void)
static
void
recal_intr
(
void
)
{
if
(
win_result
())
bad_rw_intr
();
check_status
();
#if (HD_DELAY > 0)
last_req
=
read_timer
();
#endif
...
...
@@ -664,116 +649,118 @@ static void recal_intr(void)
*/
static
void
hd_times_out
(
void
)
{
unsigned
int
dev
;
DEVICE_INTR
=
NULL
;
sti
();
if
(
!
CURRENT
)
return
;
disable_irq
(
HD_IRQ
);
sti
();
reset
=
1
;
printk
(
KERN_DEBUG
"HD timeout
\n
"
);
dev
=
DEVICE_NR
(
CURRENT
->
dev
);
printk
(
"hd%c: timeout
\n
"
,
dev
+
'a'
);
if
(
++
CURRENT
->
errors
>=
MAX_ERRORS
)
{
#ifdef DEBUG
printk
(
"hd
: too many errors.
\n
"
);
printk
(
"hd
%c: too many errors
\n
"
,
dev
+
'a'
);
#endif
end_request
(
0
);
}
cli
();
hd_request
();
enable_irq
(
HD_IRQ
);
}
int
do_special_op
(
unsigned
int
dev
)
{
if
(
recalibrate
[
dev
])
{
recalibrate
[
dev
]
=
0
;
hd_out
(
dev
,
hd_info
[
dev
].
sect
,
0
,
0
,
0
,
WIN_RESTORE
,
&
recal_intr
);
return
reset
;
}
if
(
!
identified
[
dev
])
{
identified
[
dev
]
=
1
;
unmask_intr
[
dev
]
=
DEFAULT_UNMASK_INTR
;
mult_req
[
dev
]
=
DEFAULT_MULT_COUNT
;
hd_out
(
dev
,
0
,
0
,
0
,
0
,
WIN_IDENTIFY
,
&
identify_intr
);
return
reset
;
}
if
(
mult_req
[
dev
]
!=
mult_count
[
dev
])
{
hd_out
(
dev
,
mult_req
[
dev
],
0
,
0
,
0
,
WIN_SETMULT
,
&
set_multmode_intr
);
return
reset
;
}
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
);
}
special_op
[
dev
]
=
0
;
return
1
;
}
/*
* The driver has been modified to enable interrupts a bit more: in order to
* do this we first (a) disable the timeout-interrupt and (b) clear the
* device-interrupt. This way the interrupts won't mess with out code (the
* worst that can happen is that an unexpected HD-interrupt comes in and
* sets the "reset" variable and starts the timer)
* The driver enables interrupts as much as possible. In order to do this,
* (a) the device-interrupt is disabled before entering hd_request(),
* and (b) the timeout-interrupt is disabled before the sti().
*
* Interrupts are still masked (by default) whenever we are exchanging
* data/cmds with a drive, because some drives seem to have very poor
* tolerance for latency during I/O. For devices which don't suffer from
* that problem (most don't), the unmask_intr[] flag can be set to unmask
* other interrupts during data/cmd transfers (by defining DEFAULT_UNMASK_INTR
* to 1, or by using "hdparm -u1 /dev/hd?" from the shell).
*/
static
void
hd_request
(
void
)
{
unsigned
int
block
,
dev
;
unsigned
int
sec
,
head
,
cyl
,
track
;
unsigned
int
nsect
;
unsigned
int
dev
,
block
,
nsect
,
sec
,
track
,
head
,
cyl
;
if
(
CURRENT
&&
CURRENT
->
dev
<
0
)
return
;
if
(
DEVICE_INTR
)
return
;
repeat:
timer_active
&=
~
(
1
<<
HD_TIMER
);
sti
();
INIT_REQUEST
;
if
(
reset
)
{
cli
();
reset_hd
();
return
;
}
dev
=
MINOR
(
CURRENT
->
dev
);
block
=
CURRENT
->
sector
;
nsect
=
CURRENT
->
nr_sectors
;
if
(
dev
>=
(
NR_HD
<<
6
)
||
block
>=
hd
[
dev
].
nr_sects
)
{
if
(
dev
>=
(
NR_HD
<<
6
)
||
block
>=
hd
[
dev
].
nr_sects
||
((
block
+
nsect
)
>
hd
[
dev
].
nr_sects
)
)
{
#ifdef DEBUG
printk
(
"hd : attempted read for sector %d past end of device at sector %d.
\n
"
,
block
,
hd
[
dev
].
nr_sects
);
if
(
dev
>=
(
NR_HD
<<
6
))
printk
(
"hd: bad minor number: device=0x%04x
\n
"
,
CURRENT
->
dev
);
else
printk
(
"hd%c: bad access: block=%d, count=%d
\n
"
,
(
CURRENT
->
dev
>>
6
)
+
'a'
,
block
,
nsect
);
#endif
end_request
(
0
);
goto
repeat
;
}
block
+=
hd
[
dev
].
start_sect
;
dev
>>=
6
;
if
(
special_op
[
dev
])
{
if
(
do_special_op
(
dev
))
goto
repeat
;
return
;
}
sec
=
block
%
hd_info
[
dev
].
sect
+
1
;
track
=
block
/
hd_info
[
dev
].
sect
;
head
=
track
%
hd_info
[
dev
].
head
;
cyl
=
track
/
hd_info
[
dev
].
head
;
#ifdef DEBUG
printk
(
"hd%c : cyl = %d, head = %d, sector = %d, buffer = %08x
\n
"
,
dev
+
'a'
,
cyl
,
head
,
sec
,
CURRENT
->
buffer
);
printk
(
"hd%c: %sing: CHS=%d/%d/%d, sectors=%d, buffer=0x%08lx
\n
"
,
dev
+
'a'
,
(
CURRENT
->
cmd
==
READ
)
?
"read"
:
"writ"
,
cyl
,
head
,
sec
,
nsect
,
(
unsigned
long
)
CURRENT
->
buffer
);
#endif
if
(
!
unmask_intr
[
dev
])
cli
();
if
(
reset
)
{
int
i
;
for
(
i
=
0
;
i
<
NR_HD
;
i
++
)
special_op
[
i
]
=
recalibrate
[
i
]
=
1
;
cli
();
/* better play it safe, as resets are the last resort */
reset_hd
();
return
;
}
if
(
special_op
[
dev
])
{
/* we use "special_op" to reduce overhead on r/w */
if
(
recalibrate
[
dev
])
{
recalibrate
[
dev
]
=
0
;
hd_out
(
dev
,
hd_info
[
dev
].
sect
,
0
,
0
,
0
,
WIN_RESTORE
,
&
recal_intr
);
if
(
reset
)
goto
repeat
;
return
;
}
if
(
!
identified
[
dev
])
{
identified
[
dev
]
=
1
;
unmask_intr
[
dev
]
=
DEFAULT_UNMASK_INTR
;
mult_req
[
dev
]
=
DEFAULT_MULT_COUNT
;
hd_out
(
dev
,
0
,
0
,
0
,
0
,
WIN_IDENTIFY
,
&
identify_intr
);
if
(
reset
)
goto
repeat
;
return
;
}
if
(
mult_req
[
dev
]
!=
mult_count
[
dev
])
{
hd_out
(
dev
,
mult_req
[
dev
],
0
,
0
,
0
,
WIN_SETMULT
,
&
set_multmode_intr
);
if
(
reset
)
goto
repeat
;
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
;
}
--
special_op
[
dev
];
}
/* special_op[dev] */
if
(
CURRENT
->
cmd
==
READ
)
{
unsigned
int
cmd
=
mult_count
[
dev
]
>
1
?
WIN_MULTREAD
:
WIN_READ
;
hd_out
(
dev
,
nsect
,
sec
,
head
,
cyl
,
cmd
,
&
read_intr
);
if
(
reset
)
goto
repeat
;
#ifdef DEBUG
printk
(
"hd%c: reading %d sectors(%ld-%ld), buffer=%08lx
\n
"
,
dev
+
'a'
,
nsect
,
CURRENT
->
sector
,
CURRENT
->
sector
+
nsect
-
1
,
(
long
)
CURRENT
->
buffer
);
#endif
return
;
}
if
(
CURRENT
->
cmd
==
WRITE
)
{
...
...
@@ -783,11 +770,6 @@ static void hd_request(void)
hd_out
(
dev
,
nsect
,
sec
,
head
,
cyl
,
WIN_WRITE
,
&
write_intr
);
if
(
reset
)
goto
repeat
;
#ifdef DEBUG
printk
(
"hd%c: writing %d sectors(%ld-%ld), buffer=%08lx
\n
"
,
dev
+
'a'
,
nsect
,
CURRENT
->
sector
,
CURRENT
->
sector
+
nsect
-
1
,
(
long
)
CURRENT
->
buffer
);
#endif
if
(
wait_DRQ
())
{
bad_rw_intr
();
goto
repeat
;
...
...
@@ -795,9 +777,8 @@ static void hd_request(void)
if
(
mult_count
[
dev
])
{
WCURRENT
=
*
CURRENT
;
multwrite
(
dev
);
}
else
{
}
else
outsw
(
HD_DATA
,
CURRENT
->
buffer
,
256
);
}
return
;
}
panic
(
"unknown hd-command"
);
...
...
@@ -905,11 +886,11 @@ static int hd_ioctl(struct inode * inode, struct file * file,
if
(
arg
>
max_mult
[
dev
])
err
=
-
EINVAL
;
/* out of range for device */
else
if
(
mult_req
[
dev
]
!=
mult_count
[
dev
])
{
++
special_op
[
dev
]
;
special_op
[
dev
]
=
1
;
err
=
-
EBUSY
;
/* busy, try again */
}
else
{
mult_req
[
dev
]
=
arg
;
++
special_op
[
dev
]
;
special_op
[
dev
]
=
1
;
err
=
0
;
}
restore_flags
(
flags
);
...
...
@@ -1045,8 +1026,6 @@ static void hd_geninit(void)
}
i
=
NR_HD
;
while
(
i
--
>
0
)
{
hd
[
i
<<
6
].
nr_sects
=
0
;
if
(
bios_info
[
i
].
head
>
16
)
{
/*
* The newer E-IDE BIOSs handle drives larger than 1024
* cylinders by increasing the number of logical heads
...
...
@@ -1055,12 +1034,6 @@ static void hd_geninit(void)
* what's happening here, we'll find out and correct
* it later when "identifying" the drive.
*/
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
=
bios_info
[
i
].
head
*
bios_info
[
i
].
sect
*
bios_info
[
i
].
cyl
;
hd_ident_info
[
i
]
=
(
struct
hd_driveid
*
)
kmalloc
(
512
,
GFP_KERNEL
);
...
...
@@ -1068,7 +1041,7 @@ static void hd_geninit(void)
}
if
(
NR_HD
)
{
if
(
request_irq
(
HD_IRQ
,
hd_interrupt
,
SA_INTERRUPT
,
"hd"
))
{
printk
(
"hd
.c
: unable to get IRQ%d for the harddisk driver
\n
"
,
HD_IRQ
);
printk
(
"hd: unable to get IRQ%d for the harddisk driver
\n
"
,
HD_IRQ
);
NR_HD
=
0
;
}
}
...
...
@@ -1094,7 +1067,7 @@ static struct file_operations hd_fops = {
unsigned
long
hd_init
(
unsigned
long
mem_start
,
unsigned
long
mem_end
)
{
if
(
register_blkdev
(
MAJOR_NR
,
"hd"
,
&
hd_fops
))
{
printk
(
"
U
nable to get major %d for harddisk
\n
"
,
MAJOR_NR
);
printk
(
"
hd: u
nable to get major %d for harddisk
\n
"
,
MAJOR_NR
);
return
mem_start
;
}
blk_dev
[
MAJOR_NR
].
request_fn
=
DEVICE_REQUEST
;
...
...
drivers/char/lp.c
View file @
f4a818e0
...
...
@@ -514,4 +514,12 @@ int init_module(void)
return
0
;
}
void
cleanup_module
(
void
)
{
if
(
MOD_IN_USE
)
printk
(
"lp: busy - remove delayed
\n
"
);
else
unregister_chrdev
(
LP_MAJOR
,
"lp"
);
}
#endif
drivers/sound/Makefile
View file @
f4a818e0
...
...
@@ -54,7 +54,11 @@ config: configure /usr/include/sys/soundcard.h
@
echo
\#
define SOUND_CONFIG_DATE
\"
`
date
`
\"
>>
local.h
@
echo
\#
define SOUND_CONFIG_BY
\"
`
whoami
`
\"
>>
local.h
@
echo
\#
define SOUND_CONFIG_HOST
\"
`
hostname
`
\"
>>
local.h
@
echo
\#
define SOUND_CONFIG_DOMAIN
\"
`
domainname
`
\"
>>
local.h
@
if
[
-x
/bin/dnsdomainname
]
;
then
\
echo
\#
define SOUND_CONFIG_DOMAIN
\"
`
dnsdomainname
`
\"
;
\
else
\
echo
\#
define SOUND_CONFIG_DOMAIN
\"
`
domainname
`
\"
;
\
fi
>>
local.h
clrconf
:
rm
-f
local.h .depend
...
...
fs/binfmt_elf.c
View file @
f4a818e0
...
...
@@ -612,8 +612,8 @@ load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
current
->
mm
->
start_code
=
start_code
;
current
->
mm
->
end_data
=
end_data
;
current
->
mm
->
start_stack
=
bprm
->
p
;
current
->
suid
=
current
->
euid
=
bprm
->
e_uid
;
current
->
sgid
=
current
->
egid
=
bprm
->
e_gid
;
current
->
suid
=
current
->
euid
=
current
->
fsuid
=
bprm
->
e_uid
;
current
->
sgid
=
current
->
egid
=
current
->
fsgid
=
bprm
->
e_gid
;
/* Calling sys_brk effectively mmaps the pages that we need for the bss and break
sections */
...
...
fs/ext/dir.c
View file @
f4a818e0
...
...
@@ -20,6 +20,9 @@
#include <linux/ext_fs.h>
#include <linux/stat.h>
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static
int
ext_dir_read
(
struct
inode
*
inode
,
struct
file
*
filp
,
char
*
buf
,
int
count
)
{
return
-
EISDIR
;
...
...
@@ -65,6 +68,7 @@ static int ext_readdir(struct inode * inode, struct file * filp,
struct
dirent
*
dirent
,
int
count
)
{
unsigned
int
i
;
unsigned
int
ret
;
off_t
offset
;
char
c
;
struct
buffer_head
*
bh
;
...
...
@@ -74,15 +78,23 @@ static int ext_readdir(struct inode * inode, struct file * filp,
return
-
EBADF
;
if
((
filp
->
f_pos
&
7
)
!=
0
)
return
-
EBADF
;
while
(
filp
->
f_pos
<
inode
->
i_size
)
{
ret
=
0
;
while
(
!
ret
&&
filp
->
f_pos
<
inode
->
i_size
)
{
offset
=
filp
->
f_pos
&
1023
;
bh
=
ext_bread
(
inode
,(
filp
->
f_pos
)
>>
BLOCK_SIZE_BITS
,
0
);
if
(
!
bh
)
{
filp
->
f_pos
+=
1024
-
offset
;
continue
;
}
for
(
i
=
0
;
i
<
1024
&&
i
<
offset
;
)
{
de
=
(
struct
ext_dir_entry
*
)
(
bh
->
b_data
+
i
);
if
(
!
de
->
rec_len
)
break
;
i
+=
de
->
rec_len
;
}
offset
=
i
;
de
=
(
struct
ext_dir_entry
*
)
(
offset
+
bh
->
b_data
);
while
(
offset
<
1024
&&
filp
->
f_pos
<
inode
->
i_size
)
{
while
(
!
ret
&&
offset
<
1024
&&
filp
->
f_pos
<
inode
->
i_size
)
{
if
(
de
->
rec_len
<
8
||
de
->
rec_len
%
8
!=
0
||
de
->
rec_len
<
de
->
name_len
+
8
||
(
de
->
rec_len
+
(
off_t
)
filp
->
f_pos
-
1
)
/
1024
>
((
off_t
)
filp
->
f_pos
/
1024
))
{
...
...
@@ -106,8 +118,8 @@ static int ext_readdir(struct inode * inode, struct file * filp,
put_fs_long
(
de
->
inode
,
&
dirent
->
d_ino
);
put_fs_byte
(
0
,
i
+
dirent
->
d_name
);
put_fs_word
(
i
,
&
dirent
->
d_reclen
);
brelse
(
bh
);
return
i
;
ret
=
ROUND_UP
(
NAME_OFFSET
(
dirent
)
+
i
+
1
);
break
;
}
}
de
=
(
struct
ext_dir_entry
*
)
((
char
*
)
de
...
...
@@ -115,5 +127,5 @@ static int ext_readdir(struct inode * inode, struct file * filp,
}
brelse
(
bh
);
}
return
0
;
return
ret
;
}
fs/ext2/dir.c
View file @
f4a818e0
...
...
@@ -22,6 +22,9 @@
#include <linux/sched.h>
#include <linux/stat.h>
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static
int
ext2_dir_read
(
struct
inode
*
inode
,
struct
file
*
filp
,
char
*
buf
,
int
count
)
{
...
...
@@ -98,17 +101,21 @@ static int ext2_readdir (struct inode * inode, struct file * filp,
struct
dirent
*
dirent
,
int
count
)
{
unsigned
long
offset
,
blk
;
int
i
,
num
;
int
i
,
num
,
stored
,
dlen
;
struct
buffer_head
*
bh
,
*
tmp
,
*
bha
[
16
];
struct
ext2_dir_entry
*
de
;
struct
super_block
*
sb
;
int
err
;
int
err
,
version
;
if
(
!
inode
||
!
S_ISDIR
(
inode
->
i_mode
))
return
-
EBADF
;
sb
=
inode
->
i_sb
;
while
(
filp
->
f_pos
<
inode
->
i_size
)
{
stored
=
0
;
bh
=
NULL
;
offset
=
filp
->
f_pos
&
(
sb
->
s_blocksize
-
1
);
while
(
count
>
0
&&
!
stored
&&
filp
->
f_pos
<
inode
->
i_size
)
{
blk
=
(
filp
->
f_pos
)
>>
EXT2_BLOCK_SIZE_BITS
(
sb
);
bh
=
ext2_bread
(
inode
,
blk
,
0
,
&
err
);
if
(
!
bh
)
{
...
...
@@ -135,39 +142,78 @@ static int ext2_readdir (struct inode * inode, struct file * filp,
}
}
de
=
(
struct
ext2_dir_entry
*
)
(
offset
+
bh
->
b_data
);
while
(
offset
<
sb
->
s_blocksize
&&
filp
->
f_pos
<
inode
->
i_size
)
{
revalidate:
/* If the dir block has changed since the last call to
readdir(2), then we might be pointing to an invalid dirent
right now. Scan from the start of the block to make
sure. */
for
(
i
=
0
;
i
<
sb
->
s_blocksize
&&
i
<
offset
;
)
{
de
=
(
struct
ext2_dir_entry
*
)
(
bh
->
b_data
+
i
);
/* It's too expensive to do a full dirent test
* each time round this loop, but we do have
* to test at least that it is non-zero. A
* failure will be detected in the dirent test
* below. */
if
(
de
->
rec_len
<
EXT2_DIR_REC_LEN
(
1
))
break
;
i
+=
de
->
rec_len
;
}
offset
=
i
;
filp
->
f_pos
=
(
filp
->
f_pos
&
~
(
sb
->
s_blocksize
-
1
))
|
offset
;
while
(
count
>
0
&&
filp
->
f_pos
<
inode
->
i_size
&&
offset
<
sb
->
s_blocksize
)
{
de
=
(
struct
ext2_dir_entry
*
)
(
bh
->
b_data
+
offset
);
if
(
!
ext2_check_dir_entry
(
"ext2_readdir"
,
inode
,
de
,
bh
,
offset
))
{
/* On error, skip the f_pos to the next block. */
filp
->
f_pos
=
(
filp
->
f_pos
&
(
sb
->
s_blocksize
-
1
))
+
sb
->
s_blocksize
;
brelse
(
bh
);
return
0
;
return
stored
;
}
offset
+=
de
->
rec_len
;
filp
->
f_pos
+=
de
->
rec_len
;
if
(
de
->
inode
)
{
memcpy_tofs
(
dirent
->
d_name
,
de
->
name
,
de
->
name_len
);
dlen
=
ROUND_UP
(
NAME_OFFSET
(
dirent
)
+
de
->
name_len
+
1
);
/* Old libc libraries always use a count of 1. */
if
(
count
==
1
&&
!
stored
)
count
=
dlen
;
if
(
count
<
dlen
)
{
count
=
0
;
break
;
}
/* We might block in the next section
* if the data destination is
* currently swapped out. So, use a
* version stamp to detect whether or
* not the directory has been modified
* during the copy operation. */
version
=
inode
->
i_version
;
i
=
de
->
name_len
;
memcpy_tofs
(
dirent
->
d_name
,
de
->
name
,
i
);
put_fs_long
(
de
->
inode
,
&
dirent
->
d_ino
);
put_fs_byte
(
0
,
de
->
name_len
+
dirent
->
d_name
);
put_fs_word
(
de
->
name_len
,
&
dirent
->
d_reclen
);
put_fs_byte
(
0
,
dirent
->
d_name
+
i
);
put_fs_word
(
i
,
&
dirent
->
d_reclen
);
put_fs_long
(
dlen
,
&
dirent
->
d_off
);
if
(
version
!=
inode
->
i_version
)
goto
revalidate
;
dcache_add
(
inode
,
de
->
name
,
de
->
name_len
,
de
->
inode
);
i
=
de
->
name_len
;
brelse
(
bh
);
if
(
!
IS_RDONLY
(
inode
))
{
inode
->
i_atime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
}
return
i
;
stored
+=
dlen
;
count
-=
dlen
;
((
char
*
)
dirent
)
+=
dlen
;
}
de
=
(
struct
ext2_dir_entry
*
)
((
char
*
)
de
+
de
->
rec_len
)
;
offset
+=
de
->
rec_len
;
filp
->
f_pos
+=
de
->
rec_len
;
}
offset
=
0
;
brelse
(
bh
);
}
if
(
!
IS_RDONLY
(
inode
))
{
inode
->
i_atime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
}
return
0
;
return
stored
;
}
fs/ext2/namei.c
View file @
f4a818e0
...
...
@@ -318,6 +318,7 @@ static struct buffer_head * ext2_add_entry (struct inode * dir,
*/
dir
->
i_mtime
=
dir
->
i_ctime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
dir
->
i_version
=
++
event
;
mark_buffer_dirty
(
bh
,
1
);
*
res_dir
=
de
;
*
err
=
0
;
...
...
@@ -923,8 +924,10 @@ static int do_ext2_rename (struct inode * old_dir, const char * old_name,
goto
start_up
;
try_again:
if
(
new_bh
&&
new_de
)
if
(
new_bh
&&
new_de
)
{
ext2_delete_entry
(
new_de
,
new_bh
);
new_dir
->
i_version
=
++
event
;
}
brelse
(
old_bh
);
brelse
(
new_bh
);
brelse
(
dir_bh
);
...
...
@@ -1002,6 +1005,7 @@ static int do_ext2_rename (struct inode * old_dir, const char * old_name,
&
retval
);
if
(
!
new_bh
)
goto
end_rename
;
new_dir
->
i_version
=
++
event
;
/*
* sanity checking before doing the rename - avoid races
*/
...
...
@@ -1015,7 +1019,6 @@ static int do_ext2_rename (struct inode * old_dir, const char * old_name,
* ok, that's it
*/
new_de
->
inode
=
old_inode
->
i_ino
;
new_dir
->
i_version
=
++
event
;
dcache_add
(
new_dir
,
new_de
->
name
,
new_de
->
name_len
,
new_de
->
inode
);
retval
=
ext2_delete_entry
(
old_de
,
old_bh
);
if
(
retval
==
-
ENOENT
)
...
...
fs/hpfs/hpfs_fs.c
View file @
f4a818e0
...
...
@@ -117,6 +117,9 @@
/* notation */
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
#define little_ushort(x) (*(unsigned short *) &(x))
typedef
void
nonconst
;
...
...
@@ -1345,13 +1348,13 @@ static int hpfs_readdir(struct inode *inode, struct file *filp,
case
0
:
write_one_dirent
(
dirent
,
"."
,
1
,
inode
->
i_ino
,
lc
);
filp
->
f_pos
=
-
1
;
return
1
;
return
ROUND_UP
(
NAME_OFFSET
(
dirent
)
+
2
)
;
case
-
1
:
write_one_dirent
(
dirent
,
".."
,
2
,
inode
->
i_hpfs_parent_dir
,
lc
);
filp
->
f_pos
=
1
;
return
2
;
return
ROUND_UP
(
NAME_OFFSET
(
dirent
)
+
3
)
;
case
-
2
:
return
0
;
...
...
@@ -1371,7 +1374,7 @@ static int hpfs_readdir(struct inode *inode, struct file *filp,
write_one_dirent
(
dirent
,
de
->
name
,
namelen
,
ino
,
lc
);
brelse4
(
&
qbh
);
return
namelen
;
return
ROUND_UP
(
NAME_OFFSET
(
dirent
)
+
namelen
+
1
)
;
}
}
...
...
fs/isofs/dir.c
View file @
f4a818e0
...
...
@@ -22,6 +22,9 @@
#include <linux/sched.h>
#include <linux/locks.h>
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static
int
isofs_readdir
(
struct
inode
*
,
struct
file
*
,
struct
dirent
*
,
int
);
static
struct
file_operations
isofs_dir_operations
=
{
...
...
@@ -228,7 +231,7 @@ static int isofs_readdir(struct inode * inode, struct file * filp,
put_fs_byte
(
0
,
i
+
dirent
->
d_name
);
put_fs_word
(
i
,
&
dirent
->
d_reclen
);
brelse
(
bh
);
return
i
;
return
ROUND_UP
(
NAME_OFFSET
(
dirent
)
+
i
+
1
)
;
}
}
/* We go here for any condition we cannot handle. We also drop through
...
...
fs/minix/dir.c
View file @
f4a818e0
...
...
@@ -13,6 +13,9 @@
#include <linux/minix_fs.h>
#include <linux/stat.h>
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static
int
minix_dir_read
(
struct
inode
*
inode
,
struct
file
*
filp
,
char
*
buf
,
int
count
)
{
return
-
EISDIR
;
...
...
@@ -57,7 +60,8 @@ struct inode_operations minix_dir_inode_operations = {
static
int
minix_readdir
(
struct
inode
*
inode
,
struct
file
*
filp
,
struct
dirent
*
dirent
,
int
count
)
{
unsigned
int
offset
,
i
;
unsigned
int
offset
,
i
,
ret
;
int
version
;
char
c
;
struct
buffer_head
*
bh
;
struct
minix_dir_entry
*
de
;
...
...
@@ -68,17 +72,19 @@ static int minix_readdir(struct inode * inode, struct file * filp,
info
=
&
inode
->
i_sb
->
u
.
minix_sb
;
if
(
filp
->
f_pos
&
(
info
->
s_dirsize
-
1
))
return
-
EBADF
;
while
(
filp
->
f_pos
<
inode
->
i_size
)
{
ret
=
0
;
while
(
!
ret
&&
filp
->
f_pos
<
inode
->
i_size
)
{
offset
=
filp
->
f_pos
&
1023
;
bh
=
minix_bread
(
inode
,(
filp
->
f_pos
)
>>
BLOCK_SIZE_BITS
,
0
);
if
(
!
bh
)
{
filp
->
f_pos
+=
1024
-
offset
;
continue
;
}
while
(
offset
<
1024
&&
filp
->
f_pos
<
inode
->
i_size
)
{
while
(
!
ret
&&
offset
<
1024
&&
filp
->
f_pos
<
inode
->
i_size
)
{
de
=
(
struct
minix_dir_entry
*
)
(
offset
+
bh
->
b_data
);
offset
+=
info
->
s_dirsize
;
filp
->
f_pos
+=
info
->
s_dirsize
;
retry:
if
(
de
->
inode
)
{
for
(
i
=
0
;
i
<
info
->
s_namelen
;
i
++
)
if
((
c
=
de
->
name
[
i
])
!=
0
)
...
...
@@ -86,15 +92,17 @@ static int minix_readdir(struct inode * inode, struct file * filp,
else
break
;
if
(
i
)
{
version
=
inode
->
i_version
;
put_fs_long
(
de
->
inode
,
&
dirent
->
d_ino
);
put_fs_byte
(
0
,
i
+
dirent
->
d_name
);
put_fs_word
(
i
,
&
dirent
->
d_reclen
);
brelse
(
bh
);
return
i
;
if
(
version
!=
inode
->
i_version
)
goto
retry
;
ret
=
ROUND_UP
(
NAME_OFFSET
(
dirent
)
+
i
+
1
);
}
}
}
brelse
(
bh
);
}
return
0
;
return
ret
;
}
fs/minix/namei.c
View file @
f4a818e0
...
...
@@ -195,6 +195,7 @@ static int minix_add_entry(struct inode * dir,
dir
->
i_mtime
=
dir
->
i_ctime
=
CURRENT_TIME
;
for
(
i
=
0
;
i
<
info
->
s_namelen
;
i
++
)
de
->
name
[
i
]
=
(
i
<
namelen
)
?
name
[
i
]
:
0
;
dir
->
i_version
=
++
event
;
mark_buffer_dirty
(
bh
,
1
);
*
res_dir
=
de
;
break
;
...
...
@@ -470,11 +471,12 @@ int minix_rmdir(struct inode * dir, const char * name, int len)
if
(
inode
->
i_nlink
!=
2
)
printk
(
"empty directory has nlink!=2 (%d)
\n
"
,
inode
->
i_nlink
);
de
->
inode
=
0
;
dir
->
i_version
=
++
event
;
mark_buffer_dirty
(
bh
,
1
);
inode
->
i_nlink
=
0
;
inode
->
i_dirt
=
1
;
dir
->
i_nlink
--
;
inode
->
i_ctime
=
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_nlink
--
;
dir
->
i_dirt
=
1
;
retval
=
0
;
end_rmdir:
...
...
@@ -523,6 +525,7 @@ int minix_unlink(struct inode * dir, const char * name, int len)
inode
->
i_nlink
=
1
;
}
de
->
inode
=
0
;
dir
->
i_version
=
++
event
;
mark_buffer_dirty
(
bh
,
1
);
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
dir
->
i_dirt
=
1
;
...
...
@@ -768,8 +771,10 @@ static int do_minix_rename(struct inode * old_dir, const char * old_name, int ol
new_de
->
inode
=
old_inode
->
i_ino
;
old_dir
->
i_ctime
=
old_dir
->
i_mtime
=
CURRENT_TIME
;
old_dir
->
i_dirt
=
1
;
old_dir
->
i_version
=
++
event
;
new_dir
->
i_ctime
=
new_dir
->
i_mtime
=
CURRENT_TIME
;
new_dir
->
i_dirt
=
1
;
new_dir
->
i_version
=
++
event
;
if
(
new_inode
)
{
new_inode
->
i_nlink
--
;
new_inode
->
i_ctime
=
CURRENT_TIME
;
...
...
fs/msdos/dir.c
View file @
f4a818e0
...
...
@@ -14,6 +14,9 @@
#include <linux/stat.h>
#include <linux/string.h>
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static
int
msdos_dir_read
(
struct
inode
*
inode
,
struct
file
*
filp
,
char
*
buf
,
int
count
)
{
...
...
@@ -73,7 +76,7 @@ int msdos_readdir(
put_fs_long
(
MSDOS_ROOT_INO
,
&
dirent
->
d_ino
);
put_fs_byte
(
0
,
dirent
->
d_name
+
i
);
put_fs_word
(
i
,
&
dirent
->
d_reclen
);
return
i
;
return
ROUND_UP
(
NAME_OFFSET
(
dirent
)
+
i
+
1
)
;
}
}
if
(
filp
->
f_pos
&
(
sizeof
(
struct
msdos_dir_entry
)
-
1
))
return
-
ENOENT
;
...
...
@@ -110,7 +113,7 @@ int msdos_readdir(
memcpy_tofs
(
dirent
->
d_name
,
bufname
,
i
+
1
);
put_fs_word
(
i
,
&
dirent
->
d_reclen
);
brelse
(
bh
);
return
i
;
return
ROUND_UP
(
NAME_OFFSET
(
dirent
)
+
i
+
1
)
;
}
}
}
...
...
fs/nfs/dir.c
View file @
f4a818e0
...
...
@@ -18,6 +18,9 @@
#include <asm/segment.h>
/* for fs functions */
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static
int
nfs_dir_read
(
struct
inode
*
,
struct
file
*
filp
,
char
*
buf
,
int
count
);
static
int
nfs_readdir
(
struct
inode
*
,
struct
file
*
,
struct
dirent
*
,
int
);
...
...
@@ -153,7 +156,7 @@ static int nfs_readdir(struct inode *inode, struct file *filp,
put_fs_long
(
entry
->
fileid
,
&
dirent
->
d_ino
);
put_fs_word
(
i
,
&
dirent
->
d_reclen
);
filp
->
f_pos
=
entry
->
cookie
;
return
i
;
return
ROUND_UP
(
NAME_OFFSET
(
dirent
)
+
i
+
1
)
;
}
return
0
;
}
...
...
fs/proc/link.c
View file @
f4a818e0
...
...
@@ -92,7 +92,8 @@ static int proc_fd_dupf(struct inode * inode, struct file * f)
new_f
->
f_count
++
;
current
->
files
->
fd
[
fd
]
=
new_f
;
f
->
f_count
--
;
if
(
!--
f
->
f_count
)
iput
(
f
->
f_inode
);
return
0
;
}
...
...
fs/read_write.c
View file @
f4a818e0
...
...
@@ -13,8 +13,14 @@
#include <asm/segment.h>
/*
* Count is not yet used: but we'll probably support reading several entries
* at once in the future. Use count=1 in the library for future expansions.
* Count is now a supported feature, but currently only the ext2fs
* uses it. A count value of 1 is supported for compatibility with
* earlier libraries, but larger values are supported: count should
* indicate the total buffer space available for filling with dirents.
* The d_off entry in the dirents will then indicate the offset from
* each dirent to the next, and the return value will indicate the
* number of bytes written. All dirents will be written at
* word-aligned addresses. [sct Oct 1994]
*/
asmlinkage
int
sys_readdir
(
unsigned
int
fd
,
struct
dirent
*
dirent
,
unsigned
int
count
)
{
...
...
@@ -62,8 +68,10 @@ asmlinkage int sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
}
if
(
tmp
<
0
)
return
-
EINVAL
;
if
(
tmp
!=
file
->
f_pos
)
{
file
->
f_pos
=
tmp
;
file
->
f_reada
=
0
;
}
return
file
->
f_pos
;
}
...
...
fs/sysv/dir.c
View file @
f4a818e0
...
...
@@ -20,6 +20,9 @@
#include <linux/sysv_fs.h>
#include <linux/stat.h>
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static
int
sysv_dir_read
(
struct
inode
*
inode
,
struct
file
*
filp
,
char
*
buf
,
int
count
)
{
return
-
EISDIR
;
...
...
@@ -100,7 +103,7 @@ static int sysv_readdir(struct inode * inode, struct file * filp,
put_fs_byte
(
0
,
i
+
dirent
->
d_name
);
put_fs_word
(
i
,
&
dirent
->
d_reclen
);
brelse
(
bh
);
return
i
;
return
ROUND_UP
(
NAME_OFFSET
(
dirent
)
+
i
+
1
)
;
}
}
}
...
...
fs/xiafs/dir.c
View file @
f4a818e0
...
...
@@ -19,6 +19,9 @@
#include "xiafs_mac.h"
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP(x) (((x)+3) & ~3)
static
int
xiafs_dir_read
(
struct
inode
*
,
struct
file
*
,
char
*
,
int
);
static
int
xiafs_readdir
(
struct
inode
*
,
struct
file
*
,
struct
dirent
*
,
int
);
...
...
@@ -65,7 +68,7 @@ static int xiafs_dir_read(struct inode * inode,
static
int
xiafs_readdir
(
struct
inode
*
inode
,
struct
file
*
filp
,
struct
dirent
*
dirent
,
int
count
)
{
u_int
offset
,
i
;
u_int
offset
,
i
,
ret
;
struct
buffer_head
*
bh
;
struct
xiafs_direct
*
de
;
...
...
@@ -73,15 +76,24 @@ static int xiafs_readdir(struct inode * inode,
return
-
EBADF
;
if
(
inode
->
i_size
&
(
XIAFS_ZSIZE
(
inode
->
i_sb
)
-
1
)
)
return
-
EBADF
;
while
(
filp
->
f_pos
<
inode
->
i_size
)
{
ret
=
0
;
while
(
!
ret
&&
filp
->
f_pos
<
inode
->
i_size
)
{
offset
=
filp
->
f_pos
&
(
XIAFS_ZSIZE
(
inode
->
i_sb
)
-
1
);
bh
=
xiafs_bread
(
inode
,
filp
->
f_pos
>>
XIAFS_ZSIZE_BITS
(
inode
->
i_sb
),
0
);
if
(
!
bh
)
{
filp
->
f_pos
+=
XIAFS_ZSIZE
(
inode
->
i_sb
)
-
offset
;
continue
;
}
for
(
i
=
0
;
i
<
XIAFS_ZSIZE
(
inode
->
i_sb
)
&&
i
<
offset
;
)
{
de
=
(
struct
xiafs_direct
*
)
(
bh
->
b_data
+
i
);
if
(
!
de
->
d_rec_len
)
break
;
i
+=
de
->
d_rec_len
;
}
offset
=
i
;
de
=
(
struct
xiafs_direct
*
)
(
offset
+
bh
->
b_data
);
while
(
offset
<
XIAFS_ZSIZE
(
inode
->
i_sb
)
&&
filp
->
f_pos
<
inode
->
i_size
)
{
while
(
!
ret
&&
offset
<
XIAFS_ZSIZE
(
inode
->
i_sb
)
&&
filp
->
f_pos
<
inode
->
i_size
)
{
if
(
de
->
d_ino
>
inode
->
i_sb
->
u
.
xiafs_sb
.
s_ninodes
||
de
->
d_rec_len
<
12
||
(
char
*
)
de
+
de
->
d_rec_len
>
XIAFS_ZSIZE
(
inode
->
i_sb
)
+
bh
->
b_data
||
...
...
@@ -100,12 +112,12 @@ static int xiafs_readdir(struct inode * inode,
put_fs_byte
(
0
,
i
+
dirent
->
d_name
);
put_fs_long
(
de
->
d_ino
,
&
dirent
->
d_ino
);
put_fs_word
(
i
,
&
dirent
->
d_reclen
);
brelse
(
bh
);
if
(
!
IS_RDONLY
(
inode
))
{
inode
->
i_atime
=
CURRENT_TIME
;
inode
->
i_dirt
=
1
;
}
return
i
;
ret
=
ROUND_UP
(
NAME_OFFSET
(
dirent
)
+
i
+
1
);
break
;
}
de
=
(
struct
xiafs_direct
*
)
(
offset
+
bh
->
b_data
);
}
...
...
include/linux/hdreg.h
View file @
f4a818e0
...
...
@@ -71,7 +71,6 @@ struct hd_geometry {
#define HDIO_SETUNMASKINTR 0x303
#define HDIO_GETMULTCOUNT 0x304
#define HDIO_SETMULTCOUNT 0x305
#define HDIO_SETFEATURE 0x306
#define HDIO_GETIDENTITY 0x307
#endif
...
...
include/linux/tty.h
View file @
f4a818e0
...
...
@@ -289,6 +289,7 @@ extern void stop_tty(struct tty_struct * tty);
extern
void
start_tty
(
struct
tty_struct
*
tty
);
extern
int
tty_register_ldisc
(
int
disc
,
struct
tty_ldisc
*
new_ldisc
);
extern
int
tty_register_driver
(
struct
tty_driver
*
driver
);
extern
int
tty_unregister_driver
(
struct
tty_driver
*
driver
);
extern
int
tty_read_raw_data
(
struct
tty_struct
*
tty
,
unsigned
char
*
bufp
,
int
buflen
);
...
...
kernel/ksyms.c
View file @
f4a818e0
...
...
@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/termios.h>
#include <linux/tqueue.h>
#include <linux/tty.h>
#include <linux/serial.h>
#ifdef CONFIG_INET
#include <linux/netdevice.h>
...
...
@@ -91,6 +92,9 @@ struct symbol_table symbol_table = { 0, 0, 0, /* for stacked module support */
X
(
unregister_chrdev
),
X
(
register_blkdev
),
X
(
unregister_blkdev
),
X
(
tty_register_driver
),
X
(
tty_unregister_driver
),
X
(
tty_std_termios
),
/* block device driver support */
X
(
block_read
),
...
...
net/inet/tcp.c
View file @
f4a818e0
...
...
@@ -83,6 +83,7 @@
* Matt Dillon : Yet more small nasties remove from the TCP code
* (Be very nice to this man if tcp finally works 100%) 8)
* Alan Cox : BSD accept semantics.
* Peter De Schrijver : ENOTCONN check missing in tcp_sendto().
*
*
* To Fix:
...
...
@@ -1221,15 +1222,17 @@ static int tcp_sendto(struct sock *sk, unsigned char *from,
{
if
(
flags
&
~
(
MSG_OOB
|
MSG_DONTROUTE
))
return
-
EINVAL
;
if
(
!
tcp_connected
(
sk
->
state
))
return
-
ENOTCONN
;
if
(
addr_len
<
sizeof
(
*
addr
))
return
(
-
EINVAL
)
;
return
-
EINVAL
;
if
(
addr
->
sin_family
&&
addr
->
sin_family
!=
AF_INET
)
return
(
-
EINVAL
)
;
return
-
EINVAL
;
if
(
addr
->
sin_port
!=
sk
->
dummy_th
.
dest
)
return
(
-
EISCONN
)
;
return
-
EISCONN
;
if
(
addr
->
sin_addr
.
s_addr
!=
sk
->
daddr
)
return
(
-
EISCONN
)
;
return
(
tcp_write
(
sk
,
from
,
len
,
nonblock
,
flags
)
);
return
-
EISCONN
;
return
tcp_write
(
sk
,
from
,
len
,
nonblock
,
flags
);
}
...
...
@@ -2238,7 +2241,7 @@ static void tcp_close(struct sock *sk, int timeout)
/* The +1 is not needed because the FIN takes up seq
is not read!!! */
if
(
skb
->
len
>
0
&&
after
(
skb
->
h
.
th
->
seq
+
skb
->
len
,
sk
->
copied_seq
))
need_reset
=
1
;
need_reset
=
0
;
kfree_skb
(
skb
,
FREE_READ
);
}
if
(
sk
->
debug
)
...
...
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