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
598a477a
Commit
598a477a
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 1.1.41
parent
1235b44f
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
3315 additions
and
1537 deletions
+3315
-1537
CREDITS
CREDITS
+3
-3
Makefile
Makefile
+1
-1
boot/head.S
boot/head.S
+4
-9
drivers/block/blk.h
drivers/block/blk.h
+1
-1
drivers/block/floppy.c
drivers/block/floppy.c
+2434
-942
drivers/block/hd.c
drivers/block/hd.c
+21
-13
drivers/block/ll_rw_blk.c
drivers/block/ll_rw_blk.c
+2
-0
drivers/char/n_tty.c
drivers/char/n_tty.c
+1
-1
drivers/char/pty.c
drivers/char/pty.c
+2
-1
drivers/char/serial.c
drivers/char/serial.c
+56
-32
drivers/char/tty_ioctl.c
drivers/char/tty_ioctl.c
+45
-53
fs/block_dev.c
fs/block_dev.c
+2
-0
fs/super.c
fs/super.c
+3
-0
include/i386/string.h
include/i386/string.h
+429
-0
include/linux/fd.h
include/linux/fd.h
+177
-6
include/linux/fdreg.h
include/linux/fdreg.h
+29
-2
include/linux/fs.h
include/linux/fs.h
+2
-0
include/linux/string.h
include/linux/string.h
+21
-424
kernel/vsprintf.c
kernel/vsprintf.c
+82
-49
No files found.
CREDITS
View file @
598a477a
...
...
@@ -419,11 +419,11 @@ S: FIN-00330 Helsingfors
S: Finland
N: David C. Niemi
E:
David.Niemi@oasis.gtegsc
.com
E:
niemidc@slma
.com
D: FSSTND, The XFree86 Project
D: DMA memory support
and future
floppy driver
D: DMA memory support
,
floppy driver
S: 2364 Old Trail Drive
S: Reston, V
A
22091
S: Reston, V
irginia
22091
S: USA
N: Kai Petzke
...
...
Makefile
View file @
598a477a
VERSION
=
1
PATCHLEVEL
=
1
SUBLEVEL
=
4
0
SUBLEVEL
=
4
1
all
:
Version zImage
...
...
boot/head.S
View file @
598a477a
...
...
@@ -14,10 +14,12 @@
.
globl
_empty_bad_page
.
globl
_empty_bad_page_table
.
globl
_empty_zero_page
.
globl
_
tmp_floppy_area
,
_
floppy_track_buffer
.
globl
_floppy_track_buffer
#include <linux/tasks.h>
#include <linux/segment.h>
#define ASSEMBLER
#include <linux/fd.h>
#define CL_MAGIC_ADDR 0x90020
#define CL_MAGIC 0xA33F
...
...
@@ -275,13 +277,6 @@ _empty_bad_page_table:
_empty_zero_page
:
.
org
0
x6000
/*
*
tmp_floppy_area
is
used
by
the
floppy
-
driver
when
DMA
cannot
*
reach
to
a
buffer
-
block
.
It
needs
to
be
aligned
,
so
that
it
isn
't
*
on
a
64
kB
border
.
*/
_tmp_floppy_area
:
.
fill
1024
,
1
,
0
/*
*
floppy_track_buffer
is
used
to
buffer
one
track
of
floppy
data
:
it
*
has
to
be
separate
from
the
tmp_floppy
area
,
as
otherwise
a
single
-
...
...
@@ -289,7 +284,7 @@ _tmp_floppy_area:
*
data
(
36
*
2
*
512
bytes
)
.
*/
_floppy_track_buffer
:
.
fill
512
*
2
*
36
,
1
,
0
.
fill
512
*
2
*
MAX_BUFFER_SECTORS
,
1
,
0
/*
This
is
the
default
interrupt
"handler"
:
-)
*/
int_msg
:
...
...
drivers/block/blk.h
View file @
598a477a
...
...
@@ -124,7 +124,7 @@ static void floppy_off(unsigned int nr);
#define DEVICE_NAME "floppy"
#define DEVICE_INTR do_floppy
#define DEVICE_REQUEST do_fd_request
#define DEVICE_NR(device) (
(device) & 3
)
#define DEVICE_NR(device) (
((device) & 3) | (((device) & 0x80 ) >> 5 )
)
#define DEVICE_ON(device) floppy_on(DEVICE_NR(device))
#define DEVICE_OFF(device) floppy_off(DEVICE_NR(device))
...
...
drivers/block/floppy.c
View file @
598a477a
This source diff could not be displayed because it is too large. You can
view the blob
instead.
drivers/block/hd.c
View file @
598a477a
...
...
@@ -73,10 +73,6 @@ static struct wait_queue * busy_wait = NULL;
static
int
reset
=
0
;
static
int
hd_error
=
0
;
#if (HD_DELAY > 0)
unsigned
long
last_req
,
read_timer
();
#endif
/*
* This struct defines the HD's and their types.
*/
...
...
@@ -100,17 +96,20 @@ static int hd_sizes[MAX_HD<<6] = {0, };
static
int
hd_blocksizes
[
MAX_HD
<<
6
]
=
{
0
,
};
#if (HD_DELAY > 0)
unsigned
long
last_req
;
unsigned
long
read_timer
(
void
)
{
unsigned
long
t
;
unsigned
long
t
,
flags
;
int
i
;
save_flags
(
flags
);
cli
();
t
=
jiffies
*
11932
;
outb_p
(
0
,
0x43
);
i
=
inb_p
(
0x40
);
i
|=
inb
(
0x40
)
<<
8
;
sti
(
);
restore_flags
(
flags
);
return
(
t
-
i
);
}
#endif
...
...
@@ -287,6 +286,9 @@ static void identify_intr(void)
insw
(
HD_DATA
,(
char
*
)
&
id
,
sizeof
(
id
)
/
2
);
insw
(
HD_DATA
,(
char
*
)
&
id
,
sizeof
(
id
)
/
2
);
}
#if (HD_DELAY > 0)
last_req
=
read_timer
();
#endif
hd_request
();
return
;
}
...
...
@@ -307,6 +309,9 @@ static void set_multmode_intr(void)
else
printk
(
" hd%c: disabled multiple mode
\n
"
,
dev
+
'a'
);
}
#if (HD_DELAY > 0)
last_req
=
read_timer
();
#endif
hd_request
();
return
;
}
...
...
@@ -425,7 +430,6 @@ static void read_intr(void)
if
(
unmask_intr
[
dev
])
sti
();
/* permit other IRQs during xfer */
read_next:
do
{
i
=
(
unsigned
)
inb_p
(
HD_STATUS
);
if
(
i
&
BUSY_STAT
)
...
...
@@ -442,7 +446,6 @@ static void read_intr(void)
printk
(
"hd%c: read_intr: error = 0x%02x
\n
"
,
dev
+
'a'
,
hd_error
);
}
bad_rw_intr
();
cli
();
hd_request
();
return
;
ok_to_read:
...
...
@@ -467,7 +470,7 @@ static void read_intr(void)
end_request
(
1
);
if
(
i
>
0
)
{
if
(
msect
)
goto
read_next
;
goto
ok_to_read
;
SET_INTR
(
&
read_intr
);
return
;
}
...
...
@@ -535,7 +538,6 @@ static void multwrite_intr(void)
printk
(
"hd:%c multwrite_intr: error = 0x%02x
\n
"
,
dev
+
'a'
,
hd_error
);
}
bad_rw_intr
();
cli
();
hd_request
();
}
...
...
@@ -544,6 +546,8 @@ static void write_intr(void)
int
i
;
int
retries
=
100000
;
if
(
unmask_intr
[
DEVICE_NR
(
WCURRENT
.
dev
)])
sti
();
do
{
i
=
(
unsigned
)
inb_p
(
HD_STATUS
);
if
(
i
&
BUSY_STAT
)
...
...
@@ -560,7 +564,6 @@ static void write_intr(void)
printk
(
"HD: write_intr: error = 0x%02x
\n
"
,
hd_error
);
}
bad_rw_intr
();
cli
();
hd_request
();
return
;
ok_to_write:
...
...
@@ -587,6 +590,9 @@ static void recal_intr(void)
{
if
(
win_result
())
bad_rw_intr
();
#if (HD_DELAY > 0)
last_req
=
read_timer
();
#endif
hd_request
();
}
...
...
@@ -1067,17 +1073,19 @@ static int revalidate_hddisk(int dev, int maxusage)
int
max_p
;
int
start
;
int
i
;
long
flags
;
target
=
DEVICE_NR
(
MINOR
(
dev
));
gdev
=
&
GENDISK_STRUCT
;
save_flags
(
flags
);
cli
();
if
(
DEVICE_BUSY
||
USAGE
>
maxusage
)
{
sti
(
);
restore_flags
(
flags
);
return
-
EBUSY
;
};
DEVICE_BUSY
=
1
;
sti
(
);
restore_flags
(
flags
);
max_p
=
gdev
->
max_p
;
start
=
target
<<
gdev
->
minor_shift
;
...
...
drivers/block/ll_rw_blk.c
View file @
598a477a
...
...
@@ -125,6 +125,7 @@ int is_read_only(int dev)
major
=
MAJOR
(
dev
);
minor
=
MINOR
(
dev
);
if
(
major
==
FLOPPY_MAJOR
&&
floppy_is_wp
(
minor
)
)
return
1
;
if
(
major
<
0
||
major
>=
MAX_BLKDEV
)
return
0
;
return
ro_bits
[
major
][
minor
>>
5
]
&
(
1
<<
(
minor
&
31
));
}
...
...
@@ -225,6 +226,7 @@ static void make_request(int major,int rw, struct buffer_head * bh)
* to add links to the top entry for scsi devices.
*/
if
((
major
==
HD_MAJOR
||
major
==
FLOPPY_MAJOR
||
major
==
SCSI_DISK_MAJOR
||
major
==
SCSI_CDROM_MAJOR
)
&&
(
req
=
blk_dev
[
major
].
current_request
))
...
...
drivers/char/n_tty.c
View file @
598a477a
...
...
@@ -111,7 +111,7 @@ static int opost(unsigned char c, struct tty_struct *tty)
if
(
O_ONLCR
(
tty
))
{
if
(
space
<
2
)
return
-
1
;
tty
->
driver
.
write
(
tty
,
0
,
"
\r
"
,
1
);
tty
->
driver
.
put_char
(
tty
,
'\r'
);
tty
->
column
=
0
;
}
tty
->
canon_column
=
tty
->
column
;
...
...
drivers/char/pty.c
View file @
598a477a
...
...
@@ -200,7 +200,7 @@ long pty_init(long kmem_start)
pty_driver
.
init_termios
=
tty_std_termios
;
pty_driver
.
init_termios
.
c_iflag
=
0
;
pty_driver
.
init_termios
.
c_oflag
=
0
;
pty_driver
.
init_termios
.
c_cflag
=
B
96
00
|
CS8
|
CREAD
;
pty_driver
.
init_termios
.
c_cflag
=
B
384
00
|
CS8
|
CREAD
;
pty_driver
.
init_termios
.
c_lflag
=
0
;
pty_driver
.
flags
=
TTY_DRIVER_RESET_TERMIOS
|
TTY_DRIVER_REAL_RAW
;
pty_driver
.
refcount
=
&
pty_refcount
;
...
...
@@ -221,6 +221,7 @@ long pty_init(long kmem_start)
pty_slave_driver
.
subtype
=
PTY_TYPE_SLAVE
;
pty_slave_driver
.
minor_start
=
192
;
pty_slave_driver
.
init_termios
=
tty_std_termios
;
pty_slave_driver
.
init_termios
.
c_cflag
=
B38400
|
CS8
|
CREAD
;
pty_slave_driver
.
table
=
ttyp_table
;
pty_slave_driver
.
termios
=
ttyp_termios
;
pty_slave_driver
.
termios_locked
=
ttyp_termios_locked
;
...
...
drivers/char/serial.c
View file @
598a477a
...
...
@@ -69,6 +69,7 @@ static int serial_refcount;
#undef SERIAL_DEBUG_INTR
#undef SERIAL_DEBUG_OPEN
#undef SERIAL_DEBUG_FLOW
#define _INLINE_ inline
...
...
@@ -186,6 +187,18 @@ static struct termios *serial_termios_locked[NR_PORTS];
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
/*
* tmp_buf is used as a temporary buffer by serial_write. We need to
* lock it in case the memcpy_fromfs blocks while swapping in a page,
* and some other program tries to do a serial write at the same time.
* Since the lock will only come under contention when the system is
* swapping and available memory is low, it makes sense to share one
* buffer across all the serial ports, since it significantly saves
* memory if large numbers of serial ports are open.
*/
static
unsigned
char
*
tmp_buf
=
0
;
static
struct
semaphore
tmp_buf_sem
=
MUTEX
;
static
inline
int
serial_paranoia_check
(
struct
async_struct
*
info
,
dev_t
device
,
const
char
*
routine
)
{
...
...
@@ -283,12 +296,6 @@ static void rs_stop(struct tty_struct *tty)
if
(
serial_paranoia_check
(
info
,
tty
->
device
,
"rs_stop"
))
return
;
if
(
info
->
flags
&
ASYNC_CLOSING
)
{
tty
->
stopped
=
0
;
tty
->
hw_stopped
=
0
;
return
;
}
save_flags
(
flags
);
cli
();
if
(
info
->
IER
&
UART_IER_THRI
)
{
info
->
IER
&=
~
UART_IER_THRI
;
...
...
@@ -405,7 +412,8 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
*
intr_done
=
0
;
return
;
}
if
(
!
info
->
xmit_cnt
||
info
->
tty
->
stopped
||
info
->
tty
->
hw_stopped
)
{
if
((
info
->
xmit_cnt
<=
0
)
||
info
->
tty
->
stopped
||
info
->
tty
->
hw_stopped
)
{
info
->
IER
&=
~
UART_IER_THRI
;
#ifdef CONFIG_SERIAL_NEW_ISR
serial_out
(
info
,
UART_IER
,
info
->
IER
);
...
...
@@ -417,7 +425,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
do
{
serial_out
(
info
,
UART_TX
,
info
->
xmit_buf
[
info
->
xmit_tail
++
]);
info
->
xmit_tail
=
info
->
xmit_tail
&
(
SERIAL_XMIT_SIZE
-
1
);
if
(
--
info
->
xmit_cnt
=
=
0
)
if
(
--
info
->
xmit_cnt
<
=
0
)
break
;
}
while
(
--
count
>
0
);
...
...
@@ -430,7 +438,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
if
(
intr_done
)
*
intr_done
=
0
;
if
(
info
->
xmit_cnt
=
=
0
)
{
if
(
info
->
xmit_cnt
<
=
0
)
{
info
->
IER
&=
~
UART_IER_THRI
;
#ifdef CONFIG_SERIAL_NEW_ISR
serial_out
(
info
,
UART_IER
,
info
->
IER
);
...
...
@@ -462,7 +470,7 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
if
(
info
->
flags
&
ASYNC_CTS_FLOW
)
{
if
(
info
->
tty
->
hw_stopped
)
{
if
(
status
&
UART_MSR_CTS
)
{
#if
def SERIAL_DEBUG_INTR
#if
(defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
printk
(
"CTS tx start..."
);
#endif
info
->
tty
->
hw_stopped
=
0
;
...
...
@@ -475,7 +483,7 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
}
}
else
{
if
(
!
(
status
&
UART_MSR_CTS
))
{
#if
def SERIAL_DEBUG_INTR
#if
(defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
printk
(
"CTS tx stop..."
);
#endif
info
->
tty
->
hw_stopped
=
1
;
...
...
@@ -926,6 +934,8 @@ static int startup(struct async_struct * info)
info
->
MCR
=
UART_MCR_DTR
|
UART_MCR_RTS
|
UART_MCR_OUT2
;
info
->
MCR_noint
=
UART_MCR_DTR
|
UART_MCR_RTS
;
}
if
(
info
->
irq
==
0
)
info
->
MCR
=
info
->
MCR_noint
;
serial_outp
(
info
,
UART_MCR
,
info
->
MCR
);
/*
...
...
@@ -1190,6 +1200,7 @@ static void change_speed(struct async_struct *info)
static
void
rs_put_char
(
struct
tty_struct
*
tty
,
unsigned
char
ch
)
{
struct
async_struct
*
info
=
tty
->
driver_data
;
unsigned
long
flags
;
if
(
serial_paranoia_check
(
info
,
tty
->
device
,
"rs_put_char"
))
return
;
...
...
@@ -1197,12 +1208,16 @@ static void rs_put_char(struct tty_struct *tty, unsigned char ch)
if
(
!
tty
||
tty
->
stopped
||
tty
->
hw_stopped
||
!
info
->
xmit_buf
)
return
;
if
(
info
->
xmit_cnt
>=
SERIAL_XMIT_SIZE
-
1
)
save_flags
(
flags
);
cli
();
if
(
info
->
xmit_cnt
>=
SERIAL_XMIT_SIZE
-
1
)
{
restore_flags
(
flags
);
return
;
}
info
->
xmit_buf
[
info
->
xmit_head
++
]
=
ch
;
info
->
xmit_head
&=
SERIAL_XMIT_SIZE
-
1
;
info
->
xmit_cnt
++
;
restore_flags
(
flags
);
}
static
void
rs_flush_chars
(
struct
tty_struct
*
tty
)
...
...
@@ -1213,7 +1228,7 @@ static void rs_flush_chars(struct tty_struct *tty)
if
(
serial_paranoia_check
(
info
,
tty
->
device
,
"rs_flush_chars"
))
return
;
if
(
info
->
xmit_cnt
=
=
0
||
tty
->
stopped
||
tty
->
hw_stopped
||
if
(
info
->
xmit_cnt
<
=
0
||
tty
->
stopped
||
tty
->
hw_stopped
||
!
info
->
xmit_buf
)
return
;
...
...
@@ -1233,29 +1248,33 @@ static int rs_write(struct tty_struct * tty, int from_user,
if
(
serial_paranoia_check
(
info
,
tty
->
device
,
"rs_write"
))
return
0
;
if
(
!
tty
||
!
info
->
xmit_buf
)
if
(
!
tty
||
!
info
->
xmit_buf
||
!
tmp_buf
)
return
0
;
save_flags
(
flags
);
while
(
1
)
{
cli
();
c
=
MIN
(
count
,
MIN
(
SERIAL_XMIT_SIZE
-
info
->
xmit_cnt
-
1
,
SERIAL_XMIT_SIZE
-
info
->
xmit_head
));
if
(
!
c
)
if
(
c
<=
0
)
break
;
if
(
from_user
)
memcpy_fromfs
(
info
->
xmit_buf
+
info
->
xmit_head
,
buf
,
c
);
else
if
(
from_user
)
{
down
(
&
tmp_buf_sem
);
memcpy_fromfs
(
tmp_buf
,
buf
,
c
);
c
=
MIN
(
c
,
MIN
(
SERIAL_XMIT_SIZE
-
info
->
xmit_cnt
-
1
,
SERIAL_XMIT_SIZE
-
info
->
xmit_head
));
memcpy
(
info
->
xmit_buf
+
info
->
xmit_head
,
tmp_buf
,
c
);
up
(
&
tmp_buf_sem
);
}
else
memcpy
(
info
->
xmit_buf
+
info
->
xmit_head
,
buf
,
c
);
info
->
xmit_head
=
(
info
->
xmit_head
+
c
)
&
(
SERIAL_XMIT_SIZE
-
1
);
cli
();
info
->
xmit_cnt
+=
c
;
sti
(
);
restore_flags
(
flags
);
buf
+=
c
;
count
-=
c
;
total
+=
c
;
}
save_flags
(
flags
);
cli
();
if
(
info
->
xmit_cnt
&&
!
tty
->
stopped
&&
!
tty
->
hw_stopped
&&
!
(
info
->
IER
&
UART_IER_THRI
))
{
info
->
IER
|=
UART_IER_THRI
;
...
...
@@ -1268,10 +1287,14 @@ static int rs_write(struct tty_struct * tty, int from_user,
static
int
rs_write_room
(
struct
tty_struct
*
tty
)
{
struct
async_struct
*
info
=
tty
->
driver_data
;
int
ret
;
if
(
serial_paranoia_check
(
info
,
tty
->
device
,
"rs_write_room"
))
return
0
;
return
SERIAL_XMIT_SIZE
-
info
->
xmit_cnt
-
1
;
ret
=
SERIAL_XMIT_SIZE
-
info
->
xmit_cnt
-
1
;
if
(
ret
<
0
)
ret
=
0
;
return
ret
;
}
static
int
rs_chars_in_buffer
(
struct
tty_struct
*
tty
)
...
...
@@ -1770,7 +1793,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
if
(
info
->
count
)
return
;
info
->
flags
|=
ASYNC_CLOSING
;
info
->
flags
&=
~
ASYNC_CTS_FLOW
;
/*
* Save the termios structure, since this port may have
* separate termios for callout and dialin.
...
...
@@ -1779,12 +1801,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
info
->
normal_termios
=
*
tty
->
termios
;
if
(
info
->
flags
&
ASYNC_CALLOUT_ACTIVE
)
info
->
callout_termios
=
*
tty
->
termios
;
tty
->
stopped
=
0
;
/* Force flush to succeed */
tty
->
hw_stopped
=
0
;
if
(
info
->
flags
&
ASYNC_INITIALIZED
)
{
rs_start
(
tty
);
wait_until_sent
(
tty
,
6000
);
/* 60 seconds timeout */
}
if
(
info
->
flags
&
ASYNC_INITIALIZED
)
wait_until_sent
(
tty
,
3000
);
/* 30 seconds timeout */
shutdown
(
info
);
if
(
tty
->
driver
.
flush_buffer
)
tty
->
driver
.
flush_buffer
(
tty
);
...
...
@@ -1980,6 +1998,12 @@ int rs_open(struct tty_struct *tty, struct file * filp)
tty
->
driver_data
=
info
;
info
->
tty
=
tty
;
if
(
!
tmp_buf
)
{
tmp_buf
=
(
unsigned
char
*
)
get_free_page
(
GFP_KERNEL
);
if
(
!
tmp_buf
)
return
-
ENOMEM
;
}
if
((
info
->
count
==
1
)
&&
(
info
->
flags
&
ASYNC_SPLIT_TERMIOS
))
{
if
(
tty
->
driver
.
subtype
==
SERIAL_TYPE_NORMAL
)
*
tty
->
termios
=
info
->
normal_termios
;
...
...
drivers/char/tty_ioctl.c
View file @
598a477a
...
...
@@ -31,6 +31,13 @@
# define PRINTK(x)
/**/
#endif
/*
* Internal flag options for termios setting behavior
*/
#define TERMIOS_FLUSH 1
#define TERMIOS_WAIT 2
#define TERMIOS_TERMIO 4
void
wait_until_sent
(
struct
tty_struct
*
tty
,
int
timeout
)
{
struct
wait_queue
wait
=
{
current
,
NULL
};
...
...
@@ -79,13 +86,41 @@ static void unset_locked_termios(struct termios *termios,
old
->
c_cc
[
i
]
:
termios
->
c_cc
[
i
];
}
static
int
set_termios
_2
(
struct
tty_struct
*
tty
,
struct
termios
*
termios
)
static
int
set_termios
(
struct
tty_struct
*
tty
,
unsigned
long
arg
,
int
opt
)
{
struct
termio
tmp_termio
;
struct
termios
tmp_termios
;
struct
termios
old_termios
=
*
tty
->
termios
;
int
canon_change
;
int
retval
,
canon_change
;
retval
=
tty_check_change
(
tty
);
if
(
retval
)
return
retval
;
if
(
opt
&
TERMIOS_TERMIO
)
{
tmp_termios
=
*
tty
->
termios
;
memcpy_fromfs
(
&
tmp_termio
,
(
struct
termio
*
)
arg
,
sizeof
(
struct
termio
));
#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y))
SET_LOW_BITS
(
tmp_termios
.
c_iflag
,
tmp_termio
.
c_iflag
);
SET_LOW_BITS
(
tmp_termios
.
c_oflag
,
tmp_termio
.
c_oflag
);
SET_LOW_BITS
(
tmp_termios
.
c_cflag
,
tmp_termio
.
c_cflag
);
SET_LOW_BITS
(
tmp_termios
.
c_lflag
,
tmp_termio
.
c_lflag
);
memcpy
(
&
tmp_termios
.
c_cc
,
&
tmp_termio
.
c_cc
,
NCC
);
#undef SET_LOW_BITS
}
else
memcpy_fromfs
(
&
tmp_termios
,
(
struct
termios
*
)
arg
,
sizeof
(
struct
termios
));
if
((
opt
&
TERMIOS_FLUSH
)
&&
tty
->
ldisc
.
flush_buffer
)
tty
->
ldisc
.
flush_buffer
(
tty
);
if
(
opt
&
TERMIOS_WAIT
)
wait_until_sent
(
tty
,
0
);
cli
();
*
tty
->
termios
=
*
termios
;
*
tty
->
termios
=
tmp_
termios
;
unset_locked_termios
(
tty
->
termios
,
&
old_termios
,
tty
->
termios_locked
);
canon_change
=
(
old_termios
.
c_lflag
^
tty
->
termios
->
c_lflag
)
&
ICANON
;
if
(
canon_change
)
{
...
...
@@ -127,14 +162,6 @@ static int set_termios_2(struct tty_struct * tty, struct termios * termios)
return
0
;
}
static
int
set_termios
(
struct
tty_struct
*
tty
,
struct
termios
*
termios
)
{
struct
termios
tmp_termios
;
memcpy_fromfs
(
&
tmp_termios
,
termios
,
sizeof
(
struct
termios
));
return
set_termios_2
(
tty
,
&
tmp_termios
);
}
static
int
get_termio
(
struct
tty_struct
*
tty
,
struct
termio
*
termio
)
{
int
i
;
...
...
@@ -154,27 +181,6 @@ static int get_termio(struct tty_struct * tty, struct termio * termio)
return
0
;
}
static
int
set_termio
(
struct
tty_struct
*
tty
,
struct
termio
*
termio
)
{
struct
termio
tmp_termio
;
struct
termios
tmp_termios
;
tmp_termios
=
*
tty
->
termios
;
memcpy_fromfs
(
&
tmp_termio
,
termio
,
sizeof
(
struct
termio
));
#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y))
SET_LOW_BITS
(
tmp_termios
.
c_iflag
,
tmp_termio
.
c_iflag
);
SET_LOW_BITS
(
tmp_termios
.
c_oflag
,
tmp_termio
.
c_oflag
);
SET_LOW_BITS
(
tmp_termios
.
c_cflag
,
tmp_termio
.
c_cflag
);
SET_LOW_BITS
(
tmp_termios
.
c_lflag
,
tmp_termio
.
c_lflag
);
memcpy
(
&
tmp_termios
.
c_cc
,
&
tmp_termio
.
c_cc
,
NCC
);
#undef SET_LOW_BITS
return
set_termios_2
(
tty
,
&
tmp_termios
);
}
static
unsigned
long
inq_canon
(
struct
tty_struct
*
tty
)
{
int
nr
,
head
,
tail
;
...
...
@@ -199,6 +205,7 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
{
struct
tty_struct
*
real_tty
;
int
retval
;
int
opt
=
0
;
if
(
tty
->
driver
.
type
==
TTY_DRIVER_TYPE_PTY
&&
tty
->
driver
.
subtype
==
PTY_TYPE_MASTER
)
...
...
@@ -217,34 +224,19 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
sizeof
(
struct
termios
));
return
0
;
case
TCSETSF
:
opt
|=
TERMIOS_FLUSH
;
case
TCSETSW
:
opt
|=
TERMIOS_WAIT
;
case
TCSETS
:
retval
=
tty_check_change
(
real_tty
);
if
(
retval
)
return
retval
;
if
(
cmd
==
TCSETSF
||
cmd
==
TCSETSW
)
{
if
(
cmd
==
TCSETSF
&&
real_tty
->
ldisc
.
flush_buffer
)
real_tty
->
ldisc
.
flush_buffer
(
real_tty
);
wait_until_sent
(
real_tty
,
0
);
}
return
set_termios
(
real_tty
,
(
struct
termios
*
)
arg
);
return
set_termios
(
real_tty
,
arg
,
opt
);
case
TCGETA
:
return
get_termio
(
real_tty
,(
struct
termio
*
)
arg
);
case
TCSETAF
:
opt
|=
TERMIOS_FLUSH
;
case
TCSETAW
:
opt
|=
TERMIOS_WAIT
;
case
TCSETA
:
retval
=
tty_check_change
(
real_tty
);
if
(
retval
)
return
retval
;
if
(
cmd
==
TCSETAF
||
cmd
==
TCSETAW
)
{
if
(
cmd
==
TCSETAF
&&
real_tty
->
ldisc
.
flush_buffer
)
real_tty
->
ldisc
.
flush_buffer
(
real_tty
);
wait_until_sent
(
real_tty
,
0
);
}
return
set_termio
(
real_tty
,
(
struct
termio
*
)
arg
);
return
set_termios
(
real_tty
,
arg
,
opt
|
TERMIOS_TERMIO
);
case
TCXONC
:
retval
=
tty_check_change
(
tty
);
if
(
retval
)
...
...
fs/block_dev.c
View file @
598a477a
...
...
@@ -32,6 +32,8 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
register
char
*
p
;
dev
=
inode
->
i_rdev
;
if
(
is_read_only
(
inode
->
i_rdev
))
return
-
EPERM
;
blocksize
=
BLOCK_SIZE
;
if
(
blksize_size
[
MAJOR
(
dev
)]
&&
blksize_size
[
MAJOR
(
dev
)][
MINOR
(
dev
)])
blocksize
=
blksize_size
[
MAJOR
(
dev
)][
MINOR
(
dev
)];
...
...
fs/super.c
View file @
598a477a
...
...
@@ -479,6 +479,9 @@ static int do_remount_sb(struct super_block *sb, int flags, char *data)
{
int
retval
;
if
(
!
(
flags
&
MS_RDONLY
)
&&
sb
->
s_dev
&&
is_read_only
(
sb
->
s_dev
))
return
-
EACCES
;
/*flags |= MS_RDONLY;*/
/* If we are remounting RDONLY, make sure there are no rw files open */
if
((
flags
&
MS_RDONLY
)
&&
!
(
sb
->
s_flags
&
MS_RDONLY
))
if
(
!
fs_may_remount_ro
(
sb
->
s_dev
))
...
...
include/i386/string.h
0 → 100644
View file @
598a477a
#ifndef _I386_STRING_H_
#define _I386_STRING_H_
/*
* This string-include defines all string functions as inline
* functions. Use gcc. It also assumes ds=es=data space, this should be
* normal. Most of the string-functions are rather heavily hand-optimized,
* see especially strtok,strstr,str[c]spn. They should work, but are not
* very easy to understand. Everything is done entirely within the register
* set, making the functions fast and clean. String instructions have been
* used through-out, making for "slightly" unclear code :-)
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
extern
inline
char
*
strcpy
(
char
*
dest
,
const
char
*
src
)
{
__asm__
__volatile__
(
"cld
\n
"
"1:
\t
lodsb
\n\t
"
"stosb
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b"
:
/* no output */
:
"S"
(
src
),
"D"
(
dest
)
:
"si"
,
"di"
,
"ax"
,
"memory"
);
return
dest
;
}
extern
inline
char
*
strncpy
(
char
*
dest
,
const
char
*
src
,
size_t
count
)
{
__asm__
__volatile__
(
"cld
\n
"
"1:
\t
decl %2
\n\t
"
"js 2f
\n\t
"
"lodsb
\n\t
"
"stosb
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b
\n\t
"
"rep
\n\t
"
"stosb
\n
"
"2:"
:
/* no output */
:
"S"
(
src
),
"D"
(
dest
),
"c"
(
count
)
:
"si"
,
"di"
,
"ax"
,
"cx"
,
"memory"
);
return
dest
;
}
extern
inline
char
*
strcat
(
char
*
dest
,
const
char
*
src
)
{
__asm__
__volatile__
(
"cld
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"decl %1
\n
"
"1:
\t
lodsb
\n\t
"
"stosb
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b"
:
/* no output */
:
"S"
(
src
),
"D"
(
dest
),
"a"
(
0
),
"c"
(
0xffffffff
)
:
"si"
,
"di"
,
"ax"
,
"cx"
);
return
dest
;
}
extern
inline
char
*
strncat
(
char
*
dest
,
const
char
*
src
,
size_t
count
)
{
__asm__
__volatile__
(
"cld
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"decl %1
\n\t
"
"movl %4,%3
\n
"
"1:
\t
decl %3
\n\t
"
"js 2f
\n\t
"
"lodsb
\n\t
"
"stosb
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b
\n
"
"2:
\t
xorl %2,%2
\n\t
"
"stosb"
:
/* no output */
:
"S"
(
src
),
"D"
(
dest
),
"a"
(
0
),
"c"
(
0xffffffff
),
"g"
(
count
)
:
"si"
,
"di"
,
"ax"
,
"cx"
,
"memory"
);
return
dest
;
}
extern
inline
int
strcmp
(
const
char
*
cs
,
const
char
*
ct
)
{
register
int
__res
;
__asm__
__volatile__
(
"cld
\n
"
"1:
\t
lodsb
\n\t
"
"scasb
\n\t
"
"jne 2f
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b
\n\t
"
"xorl %%eax,%%eax
\n\t
"
"jmp 3f
\n
"
"2:
\t
sbbl %%eax,%%eax
\n\t
"
"orb $1,%%eax
\n
"
"3:"
:
"=a"
(
__res
)
:
"S"
(
cs
),
"D"
(
ct
)
:
"si"
,
"di"
);
return
__res
;
}
extern
inline
int
strncmp
(
const
char
*
cs
,
const
char
*
ct
,
size_t
count
)
{
register
int
__res
;
__asm__
__volatile__
(
"cld
\n
"
"1:
\t
decl %3
\n\t
"
"js 2f
\n\t
"
"lodsb
\n\t
"
"scasb
\n\t
"
"jne 3f
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b
\n
"
"2:
\t
xorl %%eax,%%eax
\n\t
"
"jmp 4f
\n
"
"3:
\t
sbbl %%eax,%%eax
\n\t
"
"orb $1,%%al
\n
"
"4:"
:
"=a"
(
__res
)
:
"S"
(
cs
),
"D"
(
ct
),
"c"
(
count
)
:
"si"
,
"di"
,
"cx"
);
return
__res
;
}
extern
inline
char
*
strchr
(
const
char
*
s
,
char
c
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"movb %%al,%%ah
\n
"
"1:
\t
lodsb
\n\t
"
"cmpb %%ah,%%al
\n\t
"
"je 2f
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b
\n\t
"
"movl $1,%1
\n
"
"2:
\t
movl %1,%0
\n\t
"
"decl %0"
:
"=a"
(
__res
)
:
"S"
(
s
),
"0"
(
c
)
:
"si"
);
return
__res
;
}
extern
inline
char
*
strrchr
(
const
char
*
s
,
char
c
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"movb %%al,%%ah
\n
"
"1:
\t
lodsb
\n\t
"
"cmpb %%ah,%%al
\n\t
"
"jne 2f
\n\t
"
"leal -1(%%esi),%0
\n
"
"2:
\t
testb %%al,%%al
\n\t
"
"jne 1b"
:
"=d"
(
__res
)
:
"0"
(
0
),
"S"
(
s
),
"a"
(
c
)
:
"ax"
,
"si"
);
return
__res
;
}
extern
inline
size_t
strspn
(
const
char
*
cs
,
const
char
*
ct
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"movl %4,%%edi
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"notl %%ecx
\n\t
"
"decl %%ecx
\n\t
"
"movl %%ecx,%%edx
\n
"
"1:
\t
lodsb
\n\t
"
"testb %%al,%%al
\n\t
"
"je 2f
\n\t
"
"movl %4,%%edi
\n\t
"
"movl %%edx,%%ecx
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"je 1b
\n
"
"2:
\t
decl %0"
:
"=S"
(
__res
)
:
"a"
(
0
),
"c"
(
0xffffffff
),
"0"
(
cs
),
"g"
(
ct
)
:
"ax"
,
"cx"
,
"dx"
,
"di"
);
return
__res
-
cs
;
}
extern
inline
size_t
strcspn
(
const
char
*
cs
,
const
char
*
ct
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"movl %4,%%edi
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"notl %%ecx
\n\t
"
"decl %%ecx
\n\t
"
"movl %%ecx,%%edx
\n
"
"1:
\t
lodsb
\n\t
"
"testb %%al,%%al
\n\t
"
"je 2f
\n\t
"
"movl %4,%%edi
\n\t
"
"movl %%edx,%%ecx
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"jne 1b
\n
"
"2:
\t
decl %0"
:
"=S"
(
__res
)
:
"a"
(
0
),
"c"
(
0xffffffff
),
"0"
(
cs
),
"g"
(
ct
)
:
"ax"
,
"cx"
,
"dx"
,
"di"
);
return
__res
-
cs
;
}
extern
inline
char
*
strpbrk
(
const
char
*
cs
,
const
char
*
ct
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"movl %4,%%edi
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"notl %%ecx
\n\t
"
"decl %%ecx
\n\t
"
"movl %%ecx,%%edx
\n
"
"1:
\t
lodsb
\n\t
"
"testb %%al,%%al
\n\t
"
"je 2f
\n\t
"
"movl %4,%%edi
\n\t
"
"movl %%edx,%%ecx
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"jne 1b
\n\t
"
"decl %0
\n\t
"
"jmp 3f
\n
"
"2:
\t
xorl %0,%0
\n
"
"3:"
:
"=S"
(
__res
)
:
"a"
(
0
),
"c"
(
0xffffffff
),
"0"
(
cs
),
"g"
(
ct
)
:
"ax"
,
"cx"
,
"dx"
,
"di"
);
return
__res
;
}
extern
inline
char
*
strstr
(
const
char
*
cs
,
const
char
*
ct
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
\
"movl %4,%%edi
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"notl %%ecx
\n\t
"
"decl %%ecx
\n\t
"
/* NOTE! This also sets Z if searchstring='' */
"movl %%ecx,%%edx
\n
"
"1:
\t
movl %4,%%edi
\n\t
"
"movl %%esi,%%eax
\n\t
"
"movl %%edx,%%ecx
\n\t
"
"repe
\n\t
"
"cmpsb
\n\t
"
"je 2f
\n\t
"
/* also works for empty string, see above */
"xchgl %%eax,%%esi
\n\t
"
"incl %%esi
\n\t
"
"cmpb $0,-1(%%eax)
\n\t
"
"jne 1b
\n\t
"
"xorl %%eax,%%eax
\n\t
"
"2:"
:
"=a"
(
__res
)
:
"0"
(
0
),
"c"
(
0xffffffff
),
"S"
(
cs
),
"g"
(
ct
)
:
"cx"
,
"dx"
,
"di"
,
"si"
);
return
__res
;
}
extern
inline
size_t
strlen
(
const
char
*
s
)
{
register
int
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"notl %0
\n\t
"
"decl %0"
:
"=c"
(
__res
)
:
"D"
(
s
),
"a"
(
0
),
"0"
(
0xffffffff
)
:
"di"
);
return
__res
;
}
extern
char
*
___strtok
;
extern
inline
char
*
strtok
(
char
*
s
,
const
char
*
ct
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"testl %1,%1
\n\t
"
"jne 1f
\n\t
"
"testl %0,%0
\n\t
"
"je 8f
\n\t
"
"movl %0,%1
\n
"
"1:
\t
xorl %0,%0
\n\t
"
"movl $-1,%%ecx
\n\t
"
"xorl %%eax,%%eax
\n\t
"
"cld
\n\t
"
"movl %4,%%edi
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"notl %%ecx
\n\t
"
"decl %%ecx
\n\t
"
"je 7f
\n\t
"
/* empty delimeter-string */
"movl %%ecx,%%edx
\n
"
"2:
\t
lodsb
\n\t
"
"testb %%al,%%al
\n\t
"
"je 7f
\n\t
"
"movl %4,%%edi
\n\t
"
"movl %%edx,%%ecx
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"je 2b
\n\t
"
"decl %1
\n\t
"
"cmpb $0,(%1)
\n\t
"
"je 7f
\n\t
"
"movl %1,%0
\n
"
"3:
\t
lodsb
\n\t
"
"testb %%al,%%al
\n\t
"
"je 5f
\n\t
"
"movl %4,%%edi
\n\t
"
"movl %%edx,%%ecx
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"jne 3b
\n\t
"
"decl %1
\n\t
"
"cmpb $0,(%1)
\n\t
"
"je 5f
\n\t
"
"movb $0,(%1)
\n\t
"
"incl %1
\n\t
"
"jmp 6f
\n
"
"5:
\t
xorl %1,%1
\n
"
"6:
\t
cmpb $0,(%0)
\n\t
"
"jne 7f
\n\t
"
"xorl %0,%0
\n
"
"7:
\t
testl %0,%0
\n\t
"
"jne 8f
\n\t
"
"movl %0,%1
\n
"
"8:"
:
"=b"
(
__res
),
"=S"
(
___strtok
)
:
"0"
(
___strtok
),
"1"
(
s
),
"g"
(
ct
)
:
"ax"
,
"cx"
,
"dx"
,
"di"
,
"memory"
);
return
__res
;
}
extern
inline
void
*
memcpy
(
void
*
to
,
const
void
*
from
,
size_t
n
)
{
__asm__
__volatile__
(
"cld
\n\t
"
"movl %%edx, %%ecx
\n\t
"
"shrl $2,%%ecx
\n\t
"
"rep ; movsl
\n\t
"
"testb $1,%%dl
\n\t
"
"je 1f
\n\t
"
"movsb
\n
"
"1:
\t
testb $2,%%dl
\n\t
"
"je 2f
\n\t
"
"movsw
\n
"
"2:
\n
"
:
/* no output */
:
"d"
(
n
),
"D"
((
long
)
to
),
"S"
((
long
)
from
)
:
"cx"
,
"di"
,
"si"
,
"memory"
);
return
(
to
);
}
extern
inline
void
*
memmove
(
void
*
dest
,
const
void
*
src
,
size_t
n
)
{
if
(
dest
<
src
)
__asm__
__volatile__
(
"cld
\n\t
"
"rep
\n\t
"
"movsb"
:
/* no output */
:
"c"
(
n
),
"S"
(
src
),
"D"
(
dest
)
:
"cx"
,
"si"
,
"di"
);
else
__asm__
__volatile__
(
"std
\n\t
"
"rep
\n\t
"
"movsb
\n\t
"
"cld"
:
/* no output */
:
"c"
(
n
),
"S"
(
n
-
1
+
(
const
char
*
)
src
),
"D"
(
n
-
1
+
(
char
*
)
dest
)
:
"cx"
,
"si"
,
"di"
,
"memory"
);
return
dest
;
}
extern
inline
int
memcmp
(
const
void
*
cs
,
const
void
*
ct
,
size_t
count
)
{
register
int
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"repe
\n\t
"
"cmpsb
\n\t
"
"je 1f
\n\t
"
"sbbl %%eax,%%eax
\n\t
"
"orb $1,%%al
\n
"
"1:"
:
"=a"
(
__res
)
:
"0"
(
0
),
"S"
(
cs
),
"D"
(
ct
),
"c"
(
count
)
:
"si"
,
"di"
,
"cx"
);
return
__res
;
}
extern
inline
void
*
memchr
(
const
void
*
cs
,
char
c
,
size_t
count
)
{
register
void
*
__res
;
if
(
!
count
)
return
NULL
;
__asm__
__volatile__
(
"cld
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"je 1f
\n\t
"
"movl $1,%0
\n
"
"1:
\t
decl %0"
:
"=D"
(
__res
)
:
"a"
(
c
),
"D"
(
cs
),
"c"
(
count
)
:
"cx"
);
return
__res
;
}
extern
inline
void
*
memset
(
void
*
s
,
char
c
,
size_t
count
)
{
__asm__
__volatile__
(
"cld
\n\t
"
"rep
\n\t
"
"stosb"
:
/* no output */
:
"a"
(
c
),
"D"
(
s
),
"c"
(
count
)
:
"cx"
,
"di"
,
"memory"
);
return
s
;
}
#endif
include/linux/fd.h
View file @
598a477a
...
...
@@ -3,8 +3,11 @@
#define FDCLRPRM 0
/* clear user-defined parameters */
#define FDSETPRM 1
/* set user-defined parameters for current media */
#define FDSETMEDIAPRM 1
#define FDDEFPRM 2
/* set user-defined parameters until explicitly cleared */
#define FDDEFMEDIAPRM 2
#define FDGETPRM 3
/* get disk parameters */
#define FDGETMEDIAPRM 3
#define FDMSGON 4
/* issue kernel messages on media type change */
#define FDMSGOFF 5
/* don't issue kernel messages on media type change */
#define FDFMTBEG 6
/* begin formatting a disk */
...
...
@@ -14,17 +17,48 @@
#define FDFLUSH 11
/* flush buffers for media; either for verifying media, or for
handling a media change without closing the file
descriptor */
#define FDSETMAXERRS 12
/* set abortion and read_track treshold */
#define FDGETMAXERRS 14
/* get abortion and read_track treshold */
#define FDGETDRVTYP 16
/* get drive type: 5 1/4 or 3 1/2 */
#define FDSETDRVPRM 20
/* set drive parameters */
#define FDGETDRVPRM 21
/* get drive parameters */
#define FDGETDRVSTAT 22
/* get drive state */
#define FDPOLLDRVSTAT 23
/* get drive state */
#define FDGETFDCSTAT 25
/* get fdc state */
#define FDRESET 24
/* reset FDC */
#define FD_RESET_IF_NEEDED 0
#define FD_RESET_IF_RAWCMD 1
#define FD_RESET_ALWAYS 2
#define FDBAILOUT 26
/* release all fdc locks */
#define FD_CLEAR_RESET 0
#define FD_COMPLETE_FORMAT 1
#define FD_UNLOCK_FDC 2
#define FDRAWCMD 30
/* send a raw command to the fdc */
#define FDTWADDLE 40
/* flicker motor-on bit before reading a sector */
/*
* Maximum number of sectors in a track buffer. Track buffering is disabled
* if tracks are bigger.
*/
#define MAX_BUFFER_SECTORS 24
/* was 18 -bb */
#define FD_FILL_BYTE 0xF6
/* format fill byte */
#define FORMAT_NONE 0
/* no format request */
#define FORMAT_WAIT 1
/* format request is waiting */
#define FORMAT_BUSY 2
/* formatting in progress */
#define FORMAT_OKAY 3
/* successful completion */
#define FORMAT_ERROR 4
/* formatting error */
#define FD_2M 0x4
#define FD_SIZECODEMASK 0x38
#define FD_SIZECODE(floppy) (((( (floppy)->rate ) & FD_SIZECODEMASK) >> 3)+ 2)
#define FD_SECTSIZE(floppy) ( (floppy)->rate & FD_2M ? \
512 : 128 << FD_SIZECODE(floppy) )
#define FD_PERP 0x40
#ifndef ASSEMBLER
struct
floppy_struct
{
unsigned
int
size
,
/* nr of
512-byte
sectors total */
unsigned
int
size
,
/* nr of sectors total */
sect
,
/* sectors per track */
head
,
/* nr of heads */
track
,
/* nr of tracks */
...
...
@@ -40,4 +74,141 @@ struct format_descr {
unsigned
int
device
,
head
,
track
;
};
struct
floppy_max_errors
{
unsigned
int
abort
,
/* number of errors to be reached before aborting */
read_track
,
/* maximal number of errors permitted to read an
* entire track at once */
reset
,
/* maximal number of errors before a reset is tried */
recal
,
/* maximal number of errors before a recalibrate is
* tried */
/*
* Threshold for reporting FDC errors to the console.
* Setting this to zero may flood your screen when using
* ultra cheap floppies ;-)
*/
reporting
;
};
struct
floppy_drive_params
{
char
cmos
;
/* cmos type */
/* Spec2 is (HLD<<1 | ND), where HLD is head load time (1=2ms, 2=4 ms etc)
* and ND is set means no DMA. Hardcoded to 6 (HLD=6ms, use DMA).
*/
unsigned
long
max_dtr
;
/* Step rate, usec */
unsigned
long
hlt
;
/* Head load/settle time, msec */
unsigned
long
hut
;
/* Head unload time (remnant of 8" drives) */
unsigned
long
srt
;
/* Step rate, usec */
unsigned
long
spinup
;
/* time needed for spinup ( in jiffies) */
unsigned
long
spindown
;
/* timeout needed for spindown */
unsigned
char
spindown_offset
;
/* decides in which position the disk
* will stop */
unsigned
char
select_delay
;
/* delay to wait after select */
unsigned
char
rps
;
/* rotations per second */
unsigned
char
tracks
;
/* maximum number of tracks */
unsigned
long
timeout
;
/* timeout for interrupt requests */
unsigned
char
interleave_sect
;
/* if there are more sectors, use interleave */
struct
floppy_max_errors
max_errors
;
char
flags
;
/* various flags, including ftd_msg */
/*
* Announce successful media type detection and media information loss after
* disk changes.
* Also used to enable/disable printing of overrun warnings.
*/
#define FTD_MSG 0x10
char
read_track
;
/* use readtrack during probing? */
/*
* Auto-detection. Each drive type has eight formats which are
* used in succession to try to read the disk. If the FDC cannot lock onto
* the disk, the next format is tried. This uses the variable 'probing'.
*/
short
autodetect
[
8
];
/* autodetected formats */
int
checkfreq
;
/* how often should the drive be checked for disk changes */
int
native_format
;
/* native format of this drive */
};
struct
floppy_drive_struct
{
signed
char
flags
;
/* values for these flags */
#define FD_NEED_TWADDLE 1
/* more magic */
#define FD_VERIFY 2
/* this is set at bootup to force an initial drive status
inquiry*/
#define FD_DISK_NEWCHANGE 4
/* change detected, and no action undertaken yet to
clear media change status */
#define FD_DRIVE_PRESENT 8
#define FD_DISK_WRITABLE 32
unsigned
long
volatile
spinup_date
;
unsigned
long
volatile
select_date
;
unsigned
long
volatile
first_read_date
;
short
probed_format
;
short
track
;
/* current track */
short
maxblock
;
/* id of highest block read */
short
maxtrack
;
/* id of highest half track read */
int
generation
;
/* how many diskchanges? */
/*
* (User-provided) media information is _not_ discarded after a media change
* if the corresponding keep_data flag is non-zero. Positive values are
* decremented after each probe.
*/
int
keep_data
;
/* Prevent "aliased" accesses. */
int
fd_ref
;
int
fd_device
;
int
last_checked
;
/* when was the drive last checked for a disk change? */
};
struct
floppy_fdc_state
{
int
spec1
;
/* spec1 value last used */
int
spec2
;
/* spec2 value last used */
int
dtr
;
unsigned
char
version
;
/* FDC version code */
unsigned
char
dor
;
int
address
;
/* io address */
unsigned
int
rawcmd
:
2
;
unsigned
int
reset
:
1
;
unsigned
int
need_configure
:
1
;
unsigned
int
perp_mode
:
2
;
unsigned
int
has_fifo
:
1
;
};
struct
floppy_raw_cmd
{
void
*
data
;
long
length
;
unsigned
char
rate
;
unsigned
char
flags
;
unsigned
char
cmd_count
;
unsigned
char
cmd
[
9
];
unsigned
char
reply_count
;
unsigned
char
reply
[
7
];
int
track
;
};
#endif
/* meaning of the various bytes */
/* flags */
#define FD_RAW_READ 1
#define FD_RAW_WRITE 2
#define FD_RAW_INTR 8
#define FD_RAW_SPIN 16
#define FD_RAW_NEED_DISK 64
#define FD_RAW_NEED_SEEK 128
#define FD_RAW_USER_SUPPLIED 256
#endif
include/linux/fdreg.h
View file @
598a477a
...
...
@@ -6,13 +6,30 @@
* Handbook", Sanches and Canton.
*/
#ifdef FDPATCHES
/* Fd controller regs. S&C, about page 340 */
#define FD_STATUS (4 + fdc_state[fdc].address )
#define FD_DATA (5 + fdc_state[fdc].address )
/* Digital Output Register */
#define FD_DOR (2 + fdc_state[fdc].address )
/* Digital Input Register (read) */
#define FD_DIR (7 + fdc_state[fdc].address )
/* Diskette Control Register (write)*/
#define FD_DCR (7 + fdc_state[fdc].address )
#else
#define FD_STATUS 0x3f4
#define FD_DATA 0x3f5
#define FD_DOR 0x3f2
/* Digital Output Register */
#define FD_DIR 0x3f7
/* Digital Input Register (read) */
#define FD_DCR 0x3f7
/* Diskette Control Register (write)*/
#endif
/* Bits of main status register */
#define STATUS_BUSYMASK 0x0F
/* drive busy mask */
#define STATUS_BUSY 0x10
/* FDC busy */
...
...
@@ -65,13 +82,23 @@
#define FD_CONFIGURE 0x13
/* configure FIFO operation */
#define FD_PERPENDICULAR 0x12
/* perpendicular r/w mode */
#define FD_GETSTATUS 0x04
/* read ST3 */
#define FD_DUMPREGS 0x0E
/* dump the contents of the fdc regs */
#define FD_READID 0xEA
/* prints the header of a sector */
#define FD_UNLOCK 0x14
/* Fifo config unlock */
#define FD_LOCK 0x94
/* Fifo config lock */
/* DMA commands */
#define DMA_READ 0x46
#define DMA_WRITE 0x4A
/* FDC version return types */
#define FDC_TYPE_STD 0x80
/* normal 8272A clone FDC */
#define FDC_TYPE_82077 0x90
/* FIFO + perpendicular support */
#define FDC_NONE 0x00
#define FDC_UNKNOWN 0x10
#define FDC_8272A 0x20
/* Intel 8272a, NEC 765 */
#define FDC_765ED 0x30
/* Non-Intel 1MB-compatible FDC, can't detect */
#define FDC_82072 0x40
/* Intel 82072; 8272a + FIFO + DUMPREGS */
#define FDC_82077_ORIG 0x50
/* Original version of 82077AA, sans LOCK */
#define FDC_82077 0x52
/* 82077AA-1 */
#define FD_RESET_DELAY 20
#endif
include/linux/fs.h
View file @
598a477a
...
...
@@ -422,6 +422,7 @@ extern inline void mark_buffer_dirty(struct buffer_head * bh, int flag)
extern
int
check_disk_change
(
dev_t
dev
);
extern
void
invalidate_inodes
(
dev_t
dev
);
extern
void
invalidate_buffers
(
dev_t
dev
);
extern
int
floppy_is_wp
(
int
minor
);
extern
void
sync_inodes
(
dev_t
dev
);
extern
void
sync_dev
(
dev_t
dev
);
extern
int
fsync_dev
(
dev_t
dev
);
...
...
@@ -446,6 +447,7 @@ extern struct buffer_head * getblk(dev_t dev, int block, int size);
extern
void
ll_rw_block
(
int
rw
,
int
nr
,
struct
buffer_head
*
bh
[]);
extern
void
ll_rw_page
(
int
rw
,
int
dev
,
int
nr
,
char
*
buffer
);
extern
void
ll_rw_swap_file
(
int
rw
,
int
dev
,
unsigned
int
*
b
,
int
nb
,
char
*
buffer
);
extern
int
is_read_only
(
int
dev
);
extern
void
brelse
(
struct
buffer_head
*
buf
);
extern
void
set_blocksize
(
dev_t
dev
,
int
size
);
extern
struct
buffer_head
*
bread
(
dev_t
dev
,
int
block
,
int
size
);
...
...
include/linux/string.h
View file @
598a477a
...
...
@@ -11,430 +11,27 @@
extern
"C"
{
#endif
/*
* This string-include defines all string functions as inline
* functions. Use gcc. It also assumes ds=es=data space, this should be
* normal. Most of the string-functions are rather heavily hand-optimized,
* see especially strtok,strstr,str[c]spn. They should work, but are not
* very easy to understand. Everything is done entirely within the register
* set, making the functions fast and clean. String instructions have been
* used through-out, making for "slightly" unclear code :-)
*
* Copyright (C) 1991, 1992 Linus Torvalds
*/
extern
inline
char
*
strcpy
(
char
*
dest
,
const
char
*
src
)
{
__asm__
__volatile__
(
"cld
\n
"
"1:
\t
lodsb
\n\t
"
"stosb
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b"
:
/* no output */
:
"S"
(
src
),
"D"
(
dest
)
:
"si"
,
"di"
,
"ax"
,
"memory"
);
return
dest
;
}
extern
inline
char
*
strncpy
(
char
*
dest
,
const
char
*
src
,
size_t
count
)
{
__asm__
__volatile__
(
"cld
\n
"
"1:
\t
decl %2
\n\t
"
"js 2f
\n\t
"
"lodsb
\n\t
"
"stosb
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b
\n\t
"
"rep
\n\t
"
"stosb
\n
"
"2:"
:
/* no output */
:
"S"
(
src
),
"D"
(
dest
),
"c"
(
count
)
:
"si"
,
"di"
,
"ax"
,
"cx"
,
"memory"
);
return
dest
;
}
extern
inline
char
*
strcat
(
char
*
dest
,
const
char
*
src
)
{
__asm__
__volatile__
(
"cld
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"decl %1
\n
"
"1:
\t
lodsb
\n\t
"
"stosb
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b"
:
/* no output */
:
"S"
(
src
),
"D"
(
dest
),
"a"
(
0
),
"c"
(
0xffffffff
)
:
"si"
,
"di"
,
"ax"
,
"cx"
);
return
dest
;
}
extern
inline
char
*
strncat
(
char
*
dest
,
const
char
*
src
,
size_t
count
)
{
__asm__
__volatile__
(
"cld
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"decl %1
\n\t
"
"movl %4,%3
\n
"
"1:
\t
decl %3
\n\t
"
"js 2f
\n\t
"
"lodsb
\n\t
"
"stosb
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b
\n
"
"2:
\t
xorl %2,%2
\n\t
"
"stosb"
:
/* no output */
:
"S"
(
src
),
"D"
(
dest
),
"a"
(
0
),
"c"
(
0xffffffff
),
"g"
(
count
)
:
"si"
,
"di"
,
"ax"
,
"cx"
,
"memory"
);
return
dest
;
}
extern
inline
int
strcmp
(
const
char
*
cs
,
const
char
*
ct
)
{
register
int
__res
;
__asm__
__volatile__
(
"cld
\n
"
"1:
\t
lodsb
\n\t
"
"scasb
\n\t
"
"jne 2f
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b
\n\t
"
"xorl %%eax,%%eax
\n\t
"
"jmp 3f
\n
"
"2:
\t
sbbl %%eax,%%eax
\n\t
"
"orb $1,%%eax
\n
"
"3:"
:
"=a"
(
__res
)
:
"S"
(
cs
),
"D"
(
ct
)
:
"si"
,
"di"
);
return
__res
;
}
extern
inline
int
strncmp
(
const
char
*
cs
,
const
char
*
ct
,
size_t
count
)
{
register
int
__res
;
__asm__
__volatile__
(
"cld
\n
"
"1:
\t
decl %3
\n\t
"
"js 2f
\n\t
"
"lodsb
\n\t
"
"scasb
\n\t
"
"jne 3f
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b
\n
"
"2:
\t
xorl %%eax,%%eax
\n\t
"
"jmp 4f
\n
"
"3:
\t
sbbl %%eax,%%eax
\n\t
"
"orb $1,%%al
\n
"
"4:"
:
"=a"
(
__res
)
:
"S"
(
cs
),
"D"
(
ct
),
"c"
(
count
)
:
"si"
,
"di"
,
"cx"
);
return
__res
;
}
extern
inline
char
*
strchr
(
const
char
*
s
,
char
c
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"movb %%al,%%ah
\n
"
"1:
\t
lodsb
\n\t
"
"cmpb %%ah,%%al
\n\t
"
"je 2f
\n\t
"
"testb %%al,%%al
\n\t
"
"jne 1b
\n\t
"
"movl $1,%1
\n
"
"2:
\t
movl %1,%0
\n\t
"
"decl %0"
:
"=a"
(
__res
)
:
"S"
(
s
),
"0"
(
c
)
:
"si"
);
return
__res
;
}
extern
inline
char
*
strrchr
(
const
char
*
s
,
char
c
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"movb %%al,%%ah
\n
"
"1:
\t
lodsb
\n\t
"
"cmpb %%ah,%%al
\n\t
"
"jne 2f
\n\t
"
"leal -1(%%esi),%0
\n
"
"2:
\t
testb %%al,%%al
\n\t
"
"jne 1b"
:
"=d"
(
__res
)
:
"0"
(
0
),
"S"
(
s
),
"a"
(
c
)
:
"ax"
,
"si"
);
return
__res
;
}
extern
inline
size_t
strspn
(
const
char
*
cs
,
const
char
*
ct
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"movl %4,%%edi
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"notl %%ecx
\n\t
"
"decl %%ecx
\n\t
"
"movl %%ecx,%%edx
\n
"
"1:
\t
lodsb
\n\t
"
"testb %%al,%%al
\n\t
"
"je 2f
\n\t
"
"movl %4,%%edi
\n\t
"
"movl %%edx,%%ecx
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"je 1b
\n
"
"2:
\t
decl %0"
:
"=S"
(
__res
)
:
"a"
(
0
),
"c"
(
0xffffffff
),
"0"
(
cs
),
"g"
(
ct
)
:
"ax"
,
"cx"
,
"dx"
,
"di"
);
return
__res
-
cs
;
}
extern
inline
size_t
strcspn
(
const
char
*
cs
,
const
char
*
ct
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"movl %4,%%edi
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"notl %%ecx
\n\t
"
"decl %%ecx
\n\t
"
"movl %%ecx,%%edx
\n
"
"1:
\t
lodsb
\n\t
"
"testb %%al,%%al
\n\t
"
"je 2f
\n\t
"
"movl %4,%%edi
\n\t
"
"movl %%edx,%%ecx
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"jne 1b
\n
"
"2:
\t
decl %0"
:
"=S"
(
__res
)
:
"a"
(
0
),
"c"
(
0xffffffff
),
"0"
(
cs
),
"g"
(
ct
)
:
"ax"
,
"cx"
,
"dx"
,
"di"
);
return
__res
-
cs
;
}
extern
inline
char
*
strpbrk
(
const
char
*
cs
,
const
char
*
ct
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"movl %4,%%edi
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"notl %%ecx
\n\t
"
"decl %%ecx
\n\t
"
"movl %%ecx,%%edx
\n
"
"1:
\t
lodsb
\n\t
"
"testb %%al,%%al
\n\t
"
"je 2f
\n\t
"
"movl %4,%%edi
\n\t
"
"movl %%edx,%%ecx
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"jne 1b
\n\t
"
"decl %0
\n\t
"
"jmp 3f
\n
"
"2:
\t
xorl %0,%0
\n
"
"3:"
:
"=S"
(
__res
)
:
"a"
(
0
),
"c"
(
0xffffffff
),
"0"
(
cs
),
"g"
(
ct
)
:
"ax"
,
"cx"
,
"dx"
,
"di"
);
return
__res
;
}
extern
inline
char
*
strstr
(
const
char
*
cs
,
const
char
*
ct
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
\
"movl %4,%%edi
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"notl %%ecx
\n\t
"
"decl %%ecx
\n\t
"
/* NOTE! This also sets Z if searchstring='' */
"movl %%ecx,%%edx
\n
"
"1:
\t
movl %4,%%edi
\n\t
"
"movl %%esi,%%eax
\n\t
"
"movl %%edx,%%ecx
\n\t
"
"repe
\n\t
"
"cmpsb
\n\t
"
"je 2f
\n\t
"
/* also works for empty string, see above */
"xchgl %%eax,%%esi
\n\t
"
"incl %%esi
\n\t
"
"cmpb $0,-1(%%eax)
\n\t
"
"jne 1b
\n\t
"
"xorl %%eax,%%eax
\n\t
"
"2:"
:
"=a"
(
__res
)
:
"0"
(
0
),
"c"
(
0xffffffff
),
"S"
(
cs
),
"g"
(
ct
)
:
"cx"
,
"dx"
,
"di"
,
"si"
);
return
__res
;
}
extern
inline
size_t
strlen
(
const
char
*
s
)
{
register
int
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"notl %0
\n\t
"
"decl %0"
:
"=c"
(
__res
)
:
"D"
(
s
),
"a"
(
0
),
"0"
(
0xffffffff
)
:
"di"
);
return
__res
;
}
extern
char
*
___strtok
;
extern
inline
char
*
strtok
(
char
*
s
,
const
char
*
ct
)
{
register
char
*
__res
;
__asm__
__volatile__
(
"testl %1,%1
\n\t
"
"jne 1f
\n\t
"
"testl %0,%0
\n\t
"
"je 8f
\n\t
"
"movl %0,%1
\n
"
"1:
\t
xorl %0,%0
\n\t
"
"movl $-1,%%ecx
\n\t
"
"xorl %%eax,%%eax
\n\t
"
"cld
\n\t
"
"movl %4,%%edi
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"notl %%ecx
\n\t
"
"decl %%ecx
\n\t
"
"je 7f
\n\t
"
/* empty delimeter-string */
"movl %%ecx,%%edx
\n
"
"2:
\t
lodsb
\n\t
"
"testb %%al,%%al
\n\t
"
"je 7f
\n\t
"
"movl %4,%%edi
\n\t
"
"movl %%edx,%%ecx
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"je 2b
\n\t
"
"decl %1
\n\t
"
"cmpb $0,(%1)
\n\t
"
"je 7f
\n\t
"
"movl %1,%0
\n
"
"3:
\t
lodsb
\n\t
"
"testb %%al,%%al
\n\t
"
"je 5f
\n\t
"
"movl %4,%%edi
\n\t
"
"movl %%edx,%%ecx
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"jne 3b
\n\t
"
"decl %1
\n\t
"
"cmpb $0,(%1)
\n\t
"
"je 5f
\n\t
"
"movb $0,(%1)
\n\t
"
"incl %1
\n\t
"
"jmp 6f
\n
"
"5:
\t
xorl %1,%1
\n
"
"6:
\t
cmpb $0,(%0)
\n\t
"
"jne 7f
\n\t
"
"xorl %0,%0
\n
"
"7:
\t
testl %0,%0
\n\t
"
"jne 8f
\n\t
"
"movl %0,%1
\n
"
"8:"
:
"=b"
(
__res
),
"=S"
(
___strtok
)
:
"0"
(
___strtok
),
"1"
(
s
),
"g"
(
ct
)
:
"ax"
,
"cx"
,
"dx"
,
"di"
,
"memory"
);
return
__res
;
}
extern
inline
void
*
memcpy
(
void
*
to
,
const
void
*
from
,
size_t
n
)
{
__asm__
__volatile__
(
"cld
\n\t
"
"movl %%edx, %%ecx
\n\t
"
"shrl $2,%%ecx
\n\t
"
"rep ; movsl
\n\t
"
"testb $1,%%dl
\n\t
"
"je 1f
\n\t
"
"movsb
\n
"
"1:
\t
testb $2,%%dl
\n\t
"
"je 2f
\n\t
"
"movsw
\n
"
"2:
\n
"
:
/* no output */
:
"d"
(
n
),
"D"
((
long
)
to
),
"S"
((
long
)
from
)
:
"cx"
,
"di"
,
"si"
,
"memory"
);
return
(
to
);
}
extern
inline
void
*
memmove
(
void
*
dest
,
const
void
*
src
,
size_t
n
)
{
if
(
dest
<
src
)
__asm__
__volatile__
(
"cld
\n\t
"
"rep
\n\t
"
"movsb"
:
/* no output */
:
"c"
(
n
),
"S"
(
src
),
"D"
(
dest
)
:
"cx"
,
"si"
,
"di"
);
else
__asm__
__volatile__
(
"std
\n\t
"
"rep
\n\t
"
"movsb
\n\t
"
"cld"
:
/* no output */
:
"c"
(
n
),
"S"
(
n
-
1
+
(
const
char
*
)
src
),
"D"
(
n
-
1
+
(
char
*
)
dest
)
:
"cx"
,
"si"
,
"di"
,
"memory"
);
return
dest
;
}
extern
inline
int
memcmp
(
const
void
*
cs
,
const
void
*
ct
,
size_t
count
)
{
register
int
__res
;
__asm__
__volatile__
(
"cld
\n\t
"
"repe
\n\t
"
"cmpsb
\n\t
"
"je 1f
\n\t
"
"sbbl %%eax,%%eax
\n\t
"
"orb $1,%%al
\n
"
"1:"
:
"=a"
(
__res
)
:
"0"
(
0
),
"S"
(
cs
),
"D"
(
ct
),
"c"
(
count
)
:
"si"
,
"di"
,
"cx"
);
return
__res
;
}
extern
inline
void
*
memchr
(
const
void
*
cs
,
char
c
,
size_t
count
)
{
register
void
*
__res
;
if
(
!
count
)
return
NULL
;
__asm__
__volatile__
(
"cld
\n\t
"
"repne
\n\t
"
"scasb
\n\t
"
"je 1f
\n\t
"
"movl $1,%0
\n
"
"1:
\t
decl %0"
:
"=D"
(
__res
)
:
"a"
(
c
),
"D"
(
cs
),
"c"
(
count
)
:
"cx"
);
return
__res
;
}
extern
inline
void
*
memset
(
void
*
s
,
char
c
,
size_t
count
)
{
__asm__
__volatile__
(
"cld
\n\t
"
"rep
\n\t
"
"stosb"
:
/* no output */
:
"a"
(
c
),
"D"
(
s
),
"c"
(
count
)
:
"cx"
,
"di"
,
"memory"
);
return
s
;
}
#include <i386/string.h>
/* inline functions for i386.. */
extern
char
*
strcpy
(
char
*
,
const
char
*
);
extern
char
*
strncpy
(
char
*
,
const
char
*
,
size_t
);
extern
char
*
strcat
(
char
*
,
const
char
*
);
extern
char
*
strncat
(
char
*
,
const
char
*
,
size_t
);
extern
int
strcmp
(
const
char
*
,
const
char
*
);
extern
int
strncmp
(
const
char
*
,
const
char
*
,
size_t
);
extern
char
*
strchr
(
const
char
*
,
char
);
extern
char
*
strrchr
(
const
char
*
,
char
);
extern
size_t
strspn
(
const
char
*
,
const
char
*
);
extern
size_t
strcspn
(
const
char
*
,
const
char
*
);
extern
char
*
strpbrk
(
const
char
*
,
const
char
*
);
extern
char
*
strstr
(
const
char
*
,
const
char
*
);
extern
size_t
strlen
(
const
char
*
);
extern
char
*
strtok
(
char
*
,
const
char
*
);
extern
void
*
memcpy
(
void
*
,
const
void
*
,
size_t
);
extern
void
*
memmove
(
void
*
,
const
void
*
,
size_t
);
extern
int
memcmp
(
const
void
*
,
const
void
*
,
size_t
);
extern
void
*
memchr
(
const
void
*
,
char
,
size_t
);
extern
void
*
memset
(
void
*
,
char
,
size_t
);
#ifdef __cplusplus
}
...
...
kernel/vsprintf.c
View file @
598a477a
...
...
@@ -57,61 +57,76 @@ static int skip_atoi(const char **s)
#define SPACE 8
/* space if plus */
#define LEFT 16
/* left justified */
#define SPECIAL 32
/* 0x */
#define
SMALL 64
/* use 'abcdef' instead of 'ABCDEF
' */
#define
LARGE 64
/* use 'ABCDEF' instead of 'abcdef
' */
#define do_div(n,base) ({ \
int __res; \
__asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \
__res = ((unsigned long) n) % (unsigned) base; \
n = ((unsigned long) n) / (unsigned) base; \
__res; })
static
char
*
number
(
char
*
str
,
int
num
,
int
base
,
int
size
,
int
precision
static
char
*
number
(
char
*
str
,
long
num
,
int
base
,
int
size
,
int
precision
,
int
type
)
{
char
c
,
sign
,
tmp
[
36
];
const
char
*
digits
=
"0123456789
ABCDEFGHIJKLMNOPQRSTUVWXYZ
"
;
const
char
*
digits
=
"0123456789
abcdefghijklmnopqrstuvwxyz
"
;
int
i
;
if
(
type
&
SMALL
)
digits
=
"0123456789abcdefghijklmnopqrstuvwxyz"
;
if
(
type
&
LEFT
)
type
&=
~
ZEROPAD
;
if
(
base
<
2
||
base
>
36
)
if
(
type
&
LARGE
)
digits
=
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
;
if
(
type
&
LEFT
)
type
&=
~
ZEROPAD
;
if
(
base
<
2
||
base
>
36
)
return
0
;
c
=
(
type
&
ZEROPAD
)
?
'0'
:
' '
;
if
(
type
&
SIGN
&&
num
<
0
)
{
sign
=
'-'
;
c
=
(
type
&
ZEROPAD
)
?
'0'
:
' '
;
sign
=
0
;
if
(
type
&
SIGN
)
{
if
(
num
<
0
)
{
sign
=
'-'
;
num
=
-
num
;
}
else
sign
=
(
type
&
PLUS
)
?
'+'
:
((
type
&
SPACE
)
?
' '
:
0
);
if
(
sign
)
size
--
;
if
(
type
&
SPECIAL
)
if
(
base
==
16
)
size
-=
2
;
else
if
(
base
==
8
)
size
--
;
i
=
0
;
if
(
num
==
0
)
size
--
;
}
else
if
(
type
&
PLUS
)
{
sign
=
'+'
;
size
--
;
}
else
if
(
type
&
SPACE
)
{
sign
=
' '
;
size
--
;
}
}
if
(
type
&
SPECIAL
)
{
if
(
base
==
16
)
size
-=
2
;
else
if
(
base
==
8
)
size
--
;
}
i
=
0
;
if
(
num
==
0
)
tmp
[
i
++
]
=
'0'
;
else
while
(
num
!=
0
)
tmp
[
i
++
]
=
digits
[
do_div
(
num
,
base
)];
if
(
i
>
precision
)
precision
=
i
;
else
while
(
num
!=
0
)
tmp
[
i
++
]
=
digits
[
do_div
(
num
,
base
)];
if
(
i
>
precision
)
precision
=
i
;
size
-=
precision
;
if
(
!
(
type
&
(
ZEROPAD
+
LEFT
)))
while
(
size
-->
0
)
*
str
++
=
' '
;
if
(
sign
)
*
str
++
=
sign
;
if
(
type
&
SPECIAL
)
if
(
type
&
SPECIAL
)
if
(
base
==
8
)
*
str
++
=
'0'
;
else
if
(
base
==
16
)
{
*
str
++
=
'0'
;
*
str
++
=
digits
[
33
];
}
if
(
!
(
type
&
LEFT
))
while
(
size
-->
0
)
if
(
!
(
type
&
LEFT
))
while
(
size
--
>
0
)
*
str
++
=
c
;
while
(
i
<
precision
--
)
while
(
i
<
precision
--
)
*
str
++
=
'0'
;
while
(
i
-->
0
)
while
(
i
--
>
0
)
*
str
++
=
tmp
[
i
];
while
(
size
-->
0
)
while
(
size
--
>
0
)
*
str
++
=
' '
;
return
str
;
}
...
...
@@ -119,10 +134,10 @@ static char * number(char * str, int num, int base, int size, int precision
int
vsprintf
(
char
*
buf
,
const
char
*
fmt
,
va_list
args
)
{
int
len
;
int
i
;
unsigned
long
num
;
int
i
,
base
;
char
*
str
;
char
*
s
;
int
*
ip
;
int
flags
;
/* flags to number() */
...
...
@@ -183,6 +198,9 @@ int vsprintf(char *buf, const char *fmt, va_list args)
++
fmt
;
}
/* default base */
base
=
10
;
switch
(
*
fmt
)
{
case
'c'
:
if
(
!
(
flags
&
LEFT
))
...
...
@@ -191,7 +209,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
*
str
++
=
(
unsigned
char
)
va_arg
(
args
,
int
);
while
(
--
field_width
>
0
)
*
str
++
=
' '
;
break
;
continue
;
case
's'
:
s
=
va_arg
(
args
,
char
*
);
...
...
@@ -210,12 +228,7 @@ int vsprintf(char *buf, const char *fmt, va_list args)
*
str
++
=
*
s
++
;
while
(
len
<
field_width
--
)
*
str
++
=
' '
;
break
;
case
'o'
:
str
=
number
(
str
,
va_arg
(
args
,
unsigned
long
),
8
,
field_width
,
precision
,
flags
);
break
;
continue
;
case
'p'
:
if
(
field_width
==
-
1
)
{
...
...
@@ -225,26 +238,34 @@ int vsprintf(char *buf, const char *fmt, va_list args)
str
=
number
(
str
,
(
unsigned
long
)
va_arg
(
args
,
void
*
),
16
,
field_width
,
precision
,
flags
);
continue
;
case
'n'
:
if
(
qualifier
==
'l'
)
{
long
*
ip
=
va_arg
(
args
,
long
*
);
*
ip
=
(
str
-
buf
);
}
else
{
int
*
ip
=
va_arg
(
args
,
int
*
);
*
ip
=
(
str
-
buf
);
}
continue
;
/* integer number formats - set up the flags and "break" */
case
'o'
:
base
=
8
;
break
;
case
'x'
:
flags
|=
SMALL
;
case
'X'
:
str
=
number
(
str
,
va_arg
(
args
,
unsigned
long
),
16
,
field_width
,
precision
,
flags
);
flags
|=
LARGE
;
case
'x'
:
base
=
16
;
break
;
case
'd'
:
case
'i'
:
flags
|=
SIGN
;
case
'u'
:
str
=
number
(
str
,
va_arg
(
args
,
unsigned
long
),
10
,
field_width
,
precision
,
flags
);
break
;
case
'n'
:
ip
=
va_arg
(
args
,
int
*
);
*
ip
=
(
str
-
buf
);
break
;
default:
...
...
@@ -254,8 +275,20 @@ int vsprintf(char *buf, const char *fmt, va_list args)
*
str
++
=
*
fmt
;
else
--
fmt
;
break
;
continue
;
}
if
(
qualifier
==
'l'
)
num
=
va_arg
(
args
,
unsigned
long
);
else
if
(
qualifier
==
'h'
)
if
(
flags
&
SIGN
)
num
=
va_arg
(
args
,
short
);
else
num
=
va_arg
(
args
,
unsigned
short
);
else
if
(
flags
&
SIGN
)
num
=
va_arg
(
args
,
int
);
else
num
=
va_arg
(
args
,
unsigned
int
);
str
=
number
(
str
,
num
,
base
,
field_width
,
precision
,
flags
);
}
*
str
=
'\0'
;
return
str
-
buf
;
...
...
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