Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
a4673e27
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a4673e27
编写于
6月 14, 2010
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote branch 'kwolf/for-anthony' into staging
Conflicts: hw/pc.c
上级
a2da0395
653dbec7
变更
48
隐藏空白更改
内联
并排
Showing
48 changed file
with
916 addition
and
785 deletion
+916
-785
Makefile.objs
Makefile.objs
+1
-1
block.c
block.c
+63
-28
block.h
block.h
+1
-0
block/raw-posix.c
block/raw-posix.c
+11
-9
blockdev.c
blockdev.c
+600
-0
blockdev.h
blockdev.h
+71
-0
hw/acpi_piix4.c
hw/acpi_piix4.c
+1
-0
hw/apb_pci.c
hw/apb_pci.c
+1
-0
hw/device-hotplug.c
hw/device-hotplug.c
+1
-3
hw/fdc.c
hw/fdc.c
+0
-1
hw/fdc.h
hw/fdc.h
+1
-1
hw/ide/cmd646.c
hw/ide/cmd646.c
+2
-2
hw/ide/core.c
hw/ide/core.c
+62
-46
hw/ide/internal.h
hw/ide/internal.h
+6
-7
hw/ide/isa.c
hw/ide/isa.c
+1
-1
hw/ide/macio.c
hw/ide/macio.c
+1
-1
hw/ide/microdrive.c
hw/ide/microdrive.c
+2
-1
hw/ide/mmio.c
hw/ide/mmio.c
+1
-1
hw/ide/piix.c
hw/ide/piix.c
+2
-2
hw/ide/qdev.c
hw/ide/qdev.c
+18
-3
hw/lan9118.c
hw/lan9118.c
+1
-0
hw/nand.c
hw/nand.c
+1
-2
hw/omap2.c
hw/omap2.c
+2
-0
hw/onenand.c
hw/onenand.c
+1
-2
hw/parallel.c
hw/parallel.c
+1
-0
hw/pc.c
hw/pc.c
+1
-0
hw/pc_piix.c
hw/pc_piix.c
+1
-0
hw/pci-hotplug.c
hw/pci-hotplug.c
+0
-2
hw/pcmcia.h
hw/pcmcia.h
+1
-1
hw/pl181.c
hw/pl181.c
+0
-1
hw/qdev-properties.c
hw/qdev-properties.c
+11
-1
hw/qdev.c
hw/qdev.c
+6
-0
hw/qdev.h
hw/qdev.h
+5
-1
hw/scsi-bus.c
hw/scsi-bus.c
+0
-1
hw/scsi-disk.c
hw/scsi-disk.c
+19
-7
hw/scsi-generic.c
hw/scsi-generic.c
+0
-1
hw/serial.c
hw/serial.c
+1
-0
hw/ssi-sd.c
hw/ssi-sd.c
+0
-1
hw/usb-hid.c
hw/usb-hid.c
+1
-0
hw/usb-msd.c
hw/usb-msd.c
+2
-2
hw/virtio-blk.c
hw/virtio-blk.c
+4
-5
hw/virtio-pci.c
hw/virtio-pci.c
+0
-1
monitor.c
monitor.c
+1
-103
qemu-char.c
qemu-char.c
+0
-1
qemu-io.c
qemu-io.c
+2
-2
savevm.c
savevm.c
+1
-1
sysemu.h
sysemu.h
+0
-52
vl.c
vl.c
+8
-491
未找到文件。
Makefile.objs
浏览文件 @
a4673e27
...
...
@@ -44,7 +44,7 @@ fsdev-obj-$(CONFIG_LINUX) += $(addprefix fsdev/, $(fsdev-nested-y))
# system emulation, i.e. a single QEMU executable should support all
# CPUs and machines.
common-obj-y
=
$
(
block-obj-y
)
common-obj-y
=
$
(
block-obj-y
)
blockdev.o
common-obj-y
+=
$
(
net-obj-y
)
common-obj-y
+=
$
(
qobject-obj-y
)
common-obj-$(CONFIG_LINUX)
+=
$
(
fsdev-obj-
$(CONFIG_LINUX)
)
...
...
block.c
浏览文件 @
a4673e27
...
...
@@ -331,8 +331,8 @@ static BlockDriver *find_image_format(const char *filename)
if
(
ret
<
0
)
return
NULL
;
/* Return the raw BlockDriver * to scsi-generic devices */
if
(
bs
->
sg
)
{
/* Return the raw BlockDriver * to scsi-generic devices
or empty drives
*/
if
(
bs
->
sg
||
!
bdrv_is_inserted
(
bs
)
)
{
bdrv_delete
(
bs
);
return
bdrv_find_format
(
"raw"
);
}
...
...
@@ -522,7 +522,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
bdrv_delete
(
bs1
);
return
ret
;
}
total_size
=
bdrv_getlength
(
bs1
)
>>
BDRV_SECTOR_BITS
;
total_size
=
bdrv_getlength
(
bs1
)
&
BDRV_SECTOR_MASK
;
if
(
bs1
->
drv
&&
bs1
->
drv
->
protocol_name
)
is_protocol
=
1
;
...
...
@@ -541,7 +541,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
bdrv_qcow2
=
bdrv_find_format
(
"qcow2"
);
options
=
parse_option_parameters
(
""
,
bdrv_qcow2
->
create_options
,
NULL
);
set_option_parameter_int
(
options
,
BLOCK_OPT_SIZE
,
total_size
*
512
);
set_option_parameter_int
(
options
,
BLOCK_OPT_SIZE
,
total_size
);
set_option_parameter
(
options
,
BLOCK_OPT_BACKING_FILE
,
backing_filename
);
if
(
drv
)
{
set_option_parameter
(
options
,
BLOCK_OPT_BACKING_FMT
,
...
...
@@ -648,6 +648,15 @@ void bdrv_close(BlockDriverState *bs)
}
}
void
bdrv_close_all
(
void
)
{
BlockDriverState
*
bs
;
QTAILQ_FOREACH
(
bs
,
&
bdrv_states
,
list
)
{
bdrv_close
(
bs
);
}
}
void
bdrv_delete
(
BlockDriverState
*
bs
)
{
/* remove from list, if necessary */
...
...
@@ -684,7 +693,7 @@ int bdrv_commit(BlockDriverState *bs)
int64_t
i
,
total_sectors
;
int
n
,
j
,
ro
,
open_flags
;
int
ret
=
0
,
rw_ret
=
0
;
unsigned
char
sector
[
512
];
unsigned
char
sector
[
BDRV_SECTOR_SIZE
];
char
filename
[
1024
];
BlockDriverState
*
bs_rw
,
*
bs_ro
;
...
...
@@ -824,7 +833,8 @@ static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
static
int
bdrv_check_request
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
int
nb_sectors
)
{
return
bdrv_check_byte_request
(
bs
,
sector_num
*
512
,
nb_sectors
*
512
);
return
bdrv_check_byte_request
(
bs
,
sector_num
*
BDRV_SECTOR_SIZE
,
nb_sectors
*
BDRV_SECTOR_SIZE
);
}
/* return < 0 if error. See bdrv_write() for the return codes */
...
...
@@ -1059,7 +1069,7 @@ struct partition {
static
int
guess_disk_lchs
(
BlockDriverState
*
bs
,
int
*
pcylinders
,
int
*
pheads
,
int
*
psectors
)
{
uint8_t
buf
[
512
];
uint8_t
buf
[
BDRV_SECTOR_SIZE
];
int
ret
,
i
,
heads
,
sectors
,
cylinders
;
struct
partition
*
p
;
uint32_t
nr_sects
;
...
...
@@ -1535,7 +1545,7 @@ static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
"} }"
,
bs
->
rd_bytes
,
bs
->
wr_bytes
,
bs
->
rd_ops
,
bs
->
wr_ops
,
bs
->
wr_highest_sector
*
512
);
bs
->
wr_highest_sector
*
(
long
)
BDRV_SECTOR_SIZE
);
dict
=
qobject_to_qdict
(
res
);
if
(
*
bs
->
device_name
)
{
...
...
@@ -1621,9 +1631,11 @@ int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
BlockDriver
*
drv
=
bs
->
drv
;
if
(
!
drv
)
return
-
ENOMEDIUM
;
if
(
!
drv
->
bdrv_save_vmstate
)
return
-
ENOTSUP
;
return
drv
->
bdrv_save_vmstate
(
bs
,
buf
,
pos
,
size
);
if
(
drv
->
bdrv_save_vmstate
)
return
drv
->
bdrv_save_vmstate
(
bs
,
buf
,
pos
,
size
);
if
(
bs
->
file
)
return
bdrv_save_vmstate
(
bs
->
file
,
buf
,
pos
,
size
);
return
-
ENOTSUP
;
}
int
bdrv_load_vmstate
(
BlockDriverState
*
bs
,
uint8_t
*
buf
,
...
...
@@ -1632,9 +1644,11 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
BlockDriver
*
drv
=
bs
->
drv
;
if
(
!
drv
)
return
-
ENOMEDIUM
;
if
(
!
drv
->
bdrv_load_vmstate
)
return
-
ENOTSUP
;
return
drv
->
bdrv_load_vmstate
(
bs
,
buf
,
pos
,
size
);
if
(
drv
->
bdrv_load_vmstate
)
return
drv
->
bdrv_load_vmstate
(
bs
,
buf
,
pos
,
size
);
if
(
bs
->
file
)
return
bdrv_load_vmstate
(
bs
->
file
,
buf
,
pos
,
size
);
return
-
ENOTSUP
;
}
void
bdrv_debug_event
(
BlockDriverState
*
bs
,
BlkDebugEvent
event
)
...
...
@@ -1658,20 +1672,37 @@ int bdrv_snapshot_create(BlockDriverState *bs,
BlockDriver
*
drv
=
bs
->
drv
;
if
(
!
drv
)
return
-
ENOMEDIUM
;
if
(
!
drv
->
bdrv_snapshot_create
)
return
-
ENOTSUP
;
return
drv
->
bdrv_snapshot_create
(
bs
,
sn_info
);
if
(
drv
->
bdrv_snapshot_create
)
return
drv
->
bdrv_snapshot_create
(
bs
,
sn_info
);
if
(
bs
->
file
)
return
bdrv_snapshot_create
(
bs
->
file
,
sn_info
);
return
-
ENOTSUP
;
}
int
bdrv_snapshot_goto
(
BlockDriverState
*
bs
,
const
char
*
snapshot_id
)
{
BlockDriver
*
drv
=
bs
->
drv
;
int
ret
,
open_ret
;
if
(
!
drv
)
return
-
ENOMEDIUM
;
if
(
!
drv
->
bdrv_snapshot_goto
)
return
-
ENOTSUP
;
return
drv
->
bdrv_snapshot_goto
(
bs
,
snapshot_id
);
if
(
drv
->
bdrv_snapshot_goto
)
return
drv
->
bdrv_snapshot_goto
(
bs
,
snapshot_id
);
if
(
bs
->
file
)
{
drv
->
bdrv_close
(
bs
);
ret
=
bdrv_snapshot_goto
(
bs
->
file
,
snapshot_id
);
open_ret
=
drv
->
bdrv_open
(
bs
,
bs
->
open_flags
);
if
(
open_ret
<
0
)
{
bdrv_delete
(
bs
->
file
);
bs
->
drv
=
NULL
;
return
open_ret
;
}
return
ret
;
}
return
-
ENOTSUP
;
}
int
bdrv_snapshot_delete
(
BlockDriverState
*
bs
,
const
char
*
snapshot_id
)
...
...
@@ -1679,9 +1710,11 @@ int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
BlockDriver
*
drv
=
bs
->
drv
;
if
(
!
drv
)
return
-
ENOMEDIUM
;
if
(
!
drv
->
bdrv_snapshot_delete
)
return
-
ENOTSUP
;
return
drv
->
bdrv_snapshot_delete
(
bs
,
snapshot_id
);
if
(
drv
->
bdrv_snapshot_delete
)
return
drv
->
bdrv_snapshot_delete
(
bs
,
snapshot_id
);
if
(
bs
->
file
)
return
bdrv_snapshot_delete
(
bs
->
file
,
snapshot_id
);
return
-
ENOTSUP
;
}
int
bdrv_snapshot_list
(
BlockDriverState
*
bs
,
...
...
@@ -1690,9 +1723,11 @@ int bdrv_snapshot_list(BlockDriverState *bs,
BlockDriver
*
drv
=
bs
->
drv
;
if
(
!
drv
)
return
-
ENOMEDIUM
;
if
(
!
drv
->
bdrv_snapshot_list
)
return
-
ENOTSUP
;
return
drv
->
bdrv_snapshot_list
(
bs
,
psn_info
);
if
(
drv
->
bdrv_snapshot_list
)
return
drv
->
bdrv_snapshot_list
(
bs
,
psn_info
);
if
(
bs
->
file
)
return
bdrv_snapshot_list
(
bs
->
file
,
psn_info
);
return
-
ENOTSUP
;
}
#define NB_SUFFIXES 4
...
...
@@ -2197,7 +2232,7 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
async_ret
=
NOT_DONE
;
iov
.
iov_base
=
(
void
*
)
buf
;
iov
.
iov_len
=
nb_sectors
*
512
;
iov
.
iov_len
=
nb_sectors
*
BDRV_SECTOR_SIZE
;
qemu_iovec_init_external
(
&
qiov
,
&
iov
,
1
);
acb
=
bdrv_aio_readv
(
bs
,
sector_num
,
&
qiov
,
nb_sectors
,
bdrv_rw_em_cb
,
&
async_ret
);
...
...
@@ -2228,7 +2263,7 @@ static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
async_ret
=
NOT_DONE
;
iov
.
iov_base
=
(
void
*
)
buf
;
iov
.
iov_len
=
nb_sectors
*
512
;
iov
.
iov_len
=
nb_sectors
*
BDRV_SECTOR_SIZE
;
qemu_iovec_init_external
(
&
qiov
,
&
iov
,
1
);
acb
=
bdrv_aio_writev
(
bs
,
sector_num
,
&
qiov
,
nb_sectors
,
bdrv_rw_em_cb
,
&
async_ret
);
...
...
block.h
浏览文件 @
a4673e27
...
...
@@ -123,6 +123,7 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
/* Ensure contents are flushed to disk. */
void
bdrv_flush
(
BlockDriverState
*
bs
);
void
bdrv_flush_all
(
void
);
void
bdrv_close_all
(
void
);
int
bdrv_has_zero_init
(
BlockDriverState
*
bs
);
int
bdrv_is_allocated
(
BlockDriverState
*
bs
,
int64_t
sector_num
,
int
nb_sectors
,
...
...
block/raw-posix.c
浏览文件 @
a4673e27
...
...
@@ -392,8 +392,9 @@ static int raw_read(BlockDriverState *bs, int64_t sector_num,
{
int
ret
;
ret
=
raw_pread
(
bs
,
sector_num
*
512
,
buf
,
nb_sectors
*
512
);
if
(
ret
==
(
nb_sectors
*
512
))
ret
=
raw_pread
(
bs
,
sector_num
*
BDRV_SECTOR_SIZE
,
buf
,
nb_sectors
*
BDRV_SECTOR_SIZE
);
if
(
ret
==
(
nb_sectors
*
BDRV_SECTOR_SIZE
))
ret
=
0
;
return
ret
;
}
...
...
@@ -480,8 +481,9 @@ static int raw_write(BlockDriverState *bs, int64_t sector_num,
const
uint8_t
*
buf
,
int
nb_sectors
)
{
int
ret
;
ret
=
raw_pwrite
(
bs
,
sector_num
*
512
,
buf
,
nb_sectors
*
512
);
if
(
ret
==
(
nb_sectors
*
512
))
ret
=
raw_pwrite
(
bs
,
sector_num
*
BDRV_SECTOR_SIZE
,
buf
,
nb_sectors
*
BDRV_SECTOR_SIZE
);
if
(
ret
==
(
nb_sectors
*
BDRV_SECTOR_SIZE
))
ret
=
0
;
return
ret
;
}
...
...
@@ -494,7 +496,7 @@ static int qiov_is_aligned(QEMUIOVector *qiov)
int
i
;
for
(
i
=
0
;
i
<
qiov
->
niov
;
i
++
)
{
if
((
uintptr_t
)
qiov
->
iov
[
i
].
iov_base
%
512
)
{
if
((
uintptr_t
)
qiov
->
iov
[
i
].
iov_base
%
BDRV_SECTOR_SIZE
)
{
return
0
;
}
}
...
...
@@ -703,7 +705,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options)
/* Read out options */
while
(
options
&&
options
->
name
)
{
if
(
!
strcmp
(
options
->
name
,
BLOCK_OPT_SIZE
))
{
total_size
=
options
->
value
.
n
/
512
;
total_size
=
options
->
value
.
n
/
BDRV_SECTOR_SIZE
;
}
options
++
;
}
...
...
@@ -713,7 +715,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options)
if
(
fd
<
0
)
{
result
=
-
errno
;
}
else
{
if
(
ftruncate
(
fd
,
total_size
*
512
)
!=
0
)
{
if
(
ftruncate
(
fd
,
total_size
*
BDRV_SECTOR_SIZE
)
!=
0
)
{
result
=
-
errno
;
}
if
(
close
(
fd
)
!=
0
)
{
...
...
@@ -976,7 +978,7 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options)
/* Read out options */
while
(
options
&&
options
->
name
)
{
if
(
!
strcmp
(
options
->
name
,
"size"
))
{
total_size
=
options
->
value
.
n
/
512
;
total_size
=
options
->
value
.
n
/
BDRV_SECTOR_SIZE
;
}
options
++
;
}
...
...
@@ -989,7 +991,7 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options)
ret
=
-
errno
;
else
if
(
!
S_ISBLK
(
stat_buf
.
st_mode
)
&&
!
S_ISCHR
(
stat_buf
.
st_mode
))
ret
=
-
ENODEV
;
else
if
(
lseek
(
fd
,
0
,
SEEK_END
)
<
total_size
*
512
)
else
if
(
lseek
(
fd
,
0
,
SEEK_END
)
<
total_size
*
BDRV_SECTOR_SIZE
)
ret
=
-
ENOSPC
;
close
(
fd
);
...
...
blockdev.c
0 → 100644
浏览文件 @
a4673e27
/*
* QEMU host block devices
*
* Copyright (c) 2003-2008 Fabrice Bellard
*
* This work is licensed under the terms of the GNU GPL, version 2 or
* later. See the COPYING file in the top-level directory.
*/
#include "block.h"
#include "blockdev.h"
#include "monitor.h"
#include "qerror.h"
#include "qemu-option.h"
#include "qemu-config.h"
#include "sysemu.h"
struct
drivelist
drives
=
QTAILQ_HEAD_INITIALIZER
(
drives
);
QemuOpts
*
drive_add
(
const
char
*
file
,
const
char
*
fmt
,
...)
{
va_list
ap
;
char
optstr
[
1024
];
QemuOpts
*
opts
;
va_start
(
ap
,
fmt
);
vsnprintf
(
optstr
,
sizeof
(
optstr
),
fmt
,
ap
);
va_end
(
ap
);
opts
=
qemu_opts_parse
(
&
qemu_drive_opts
,
optstr
,
0
);
if
(
!
opts
)
{
return
NULL
;
}
if
(
file
)
qemu_opt_set
(
opts
,
"file"
,
file
);
return
opts
;
}
DriveInfo
*
drive_get
(
BlockInterfaceType
type
,
int
bus
,
int
unit
)
{
DriveInfo
*
dinfo
;
/* seek interface, bus and unit */
QTAILQ_FOREACH
(
dinfo
,
&
drives
,
next
)
{
if
(
dinfo
->
type
==
type
&&
dinfo
->
bus
==
bus
&&
dinfo
->
unit
==
unit
)
return
dinfo
;
}
return
NULL
;
}
DriveInfo
*
drive_get_by_id
(
const
char
*
id
)
{
DriveInfo
*
dinfo
;
QTAILQ_FOREACH
(
dinfo
,
&
drives
,
next
)
{
if
(
strcmp
(
id
,
dinfo
->
id
))
continue
;
return
dinfo
;
}
return
NULL
;
}
int
drive_get_max_bus
(
BlockInterfaceType
type
)
{
int
max_bus
;
DriveInfo
*
dinfo
;
max_bus
=
-
1
;
QTAILQ_FOREACH
(
dinfo
,
&
drives
,
next
)
{
if
(
dinfo
->
type
==
type
&&
dinfo
->
bus
>
max_bus
)
max_bus
=
dinfo
->
bus
;
}
return
max_bus
;
}
const
char
*
drive_get_serial
(
BlockDriverState
*
bdrv
)
{
DriveInfo
*
dinfo
;
QTAILQ_FOREACH
(
dinfo
,
&
drives
,
next
)
{
if
(
dinfo
->
bdrv
==
bdrv
)
return
dinfo
->
serial
;
}
return
"
\0
"
;
}
BlockInterfaceErrorAction
drive_get_on_error
(
BlockDriverState
*
bdrv
,
int
is_read
)
{
DriveInfo
*
dinfo
;
QTAILQ_FOREACH
(
dinfo
,
&
drives
,
next
)
{
if
(
dinfo
->
bdrv
==
bdrv
)
return
is_read
?
dinfo
->
on_read_error
:
dinfo
->
on_write_error
;
}
return
is_read
?
BLOCK_ERR_REPORT
:
BLOCK_ERR_STOP_ENOSPC
;
}
static
void
bdrv_format_print
(
void
*
opaque
,
const
char
*
name
)
{
fprintf
(
stderr
,
" %s"
,
name
);
}
void
drive_uninit
(
DriveInfo
*
dinfo
)
{
qemu_opts_del
(
dinfo
->
opts
);
bdrv_delete
(
dinfo
->
bdrv
);
QTAILQ_REMOVE
(
&
drives
,
dinfo
,
next
);
qemu_free
(
dinfo
);
}
static
int
parse_block_error_action
(
const
char
*
buf
,
int
is_read
)
{
if
(
!
strcmp
(
buf
,
"ignore"
))
{
return
BLOCK_ERR_IGNORE
;
}
else
if
(
!
is_read
&&
!
strcmp
(
buf
,
"enospc"
))
{
return
BLOCK_ERR_STOP_ENOSPC
;
}
else
if
(
!
strcmp
(
buf
,
"stop"
))
{
return
BLOCK_ERR_STOP_ANY
;
}
else
if
(
!
strcmp
(
buf
,
"report"
))
{
return
BLOCK_ERR_REPORT
;
}
else
{
fprintf
(
stderr
,
"qemu: '%s' invalid %s error action
\n
"
,
buf
,
is_read
?
"read"
:
"write"
);
return
-
1
;
}
}
DriveInfo
*
drive_init
(
QemuOpts
*
opts
,
int
default_to_scsi
,
int
*
fatal_error
)
{
const
char
*
buf
;
const
char
*
file
=
NULL
;
char
devname
[
128
];
const
char
*
serial
;
const
char
*
mediastr
=
""
;
BlockInterfaceType
type
;
enum
{
MEDIA_DISK
,
MEDIA_CDROM
}
media
;
int
bus_id
,
unit_id
;
int
cyls
,
heads
,
secs
,
translation
;
BlockDriver
*
drv
=
NULL
;
int
max_devs
;
int
index
;
int
ro
=
0
;
int
bdrv_flags
=
0
;
int
on_read_error
,
on_write_error
;
const
char
*
devaddr
;
DriveInfo
*
dinfo
;
int
snapshot
=
0
;
int
ret
;
*
fatal_error
=
1
;
translation
=
BIOS_ATA_TRANSLATION_AUTO
;
if
(
default_to_scsi
)
{
type
=
IF_SCSI
;
max_devs
=
MAX_SCSI_DEVS
;
pstrcpy
(
devname
,
sizeof
(
devname
),
"scsi"
);
}
else
{
type
=
IF_IDE
;
max_devs
=
MAX_IDE_DEVS
;
pstrcpy
(
devname
,
sizeof
(
devname
),
"ide"
);
}
media
=
MEDIA_DISK
;
/* extract parameters */
bus_id
=
qemu_opt_get_number
(
opts
,
"bus"
,
0
);
unit_id
=
qemu_opt_get_number
(
opts
,
"unit"
,
-
1
);
index
=
qemu_opt_get_number
(
opts
,
"index"
,
-
1
);
cyls
=
qemu_opt_get_number
(
opts
,
"cyls"
,
0
);
heads
=
qemu_opt_get_number
(
opts
,
"heads"
,
0
);
secs
=
qemu_opt_get_number
(
opts
,
"secs"
,
0
);
snapshot
=
qemu_opt_get_bool
(
opts
,
"snapshot"
,
0
);
ro
=
qemu_opt_get_bool
(
opts
,
"readonly"
,
0
);
file
=
qemu_opt_get
(
opts
,
"file"
);
serial
=
qemu_opt_get
(
opts
,
"serial"
);
if
((
buf
=
qemu_opt_get
(
opts
,
"if"
))
!=
NULL
)
{
pstrcpy
(
devname
,
sizeof
(
devname
),
buf
);
if
(
!
strcmp
(
buf
,
"ide"
))
{
type
=
IF_IDE
;
max_devs
=
MAX_IDE_DEVS
;
}
else
if
(
!
strcmp
(
buf
,
"scsi"
))
{
type
=
IF_SCSI
;
max_devs
=
MAX_SCSI_DEVS
;
}
else
if
(
!
strcmp
(
buf
,
"floppy"
))
{
type
=
IF_FLOPPY
;
max_devs
=
0
;
}
else
if
(
!
strcmp
(
buf
,
"pflash"
))
{
type
=
IF_PFLASH
;
max_devs
=
0
;
}
else
if
(
!
strcmp
(
buf
,
"mtd"
))
{
type
=
IF_MTD
;
max_devs
=
0
;
}
else
if
(
!
strcmp
(
buf
,
"sd"
))
{
type
=
IF_SD
;
max_devs
=
0
;
}
else
if
(
!
strcmp
(
buf
,
"virtio"
))
{
type
=
IF_VIRTIO
;
max_devs
=
0
;
}
else
if
(
!
strcmp
(
buf
,
"xen"
))
{
type
=
IF_XEN
;
max_devs
=
0
;
}
else
if
(
!
strcmp
(
buf
,
"none"
))
{
type
=
IF_NONE
;
max_devs
=
0
;
}
else
{
fprintf
(
stderr
,
"qemu: unsupported bus type '%s'
\n
"
,
buf
);
return
NULL
;
}
}
if
(
cyls
||
heads
||
secs
)
{
if
(
cyls
<
1
||
(
type
==
IF_IDE
&&
cyls
>
16383
))
{
fprintf
(
stderr
,
"qemu: '%s' invalid physical cyls number
\n
"
,
buf
);
return
NULL
;
}
if
(
heads
<
1
||
(
type
==
IF_IDE
&&
heads
>
16
))
{
fprintf
(
stderr
,
"qemu: '%s' invalid physical heads number
\n
"
,
buf
);
return
NULL
;
}
if
(
secs
<
1
||
(
type
==
IF_IDE
&&
secs
>
63
))
{
fprintf
(
stderr
,
"qemu: '%s' invalid physical secs number
\n
"
,
buf
);
return
NULL
;
}
}
if
((
buf
=
qemu_opt_get
(
opts
,
"trans"
))
!=
NULL
)
{
if
(
!
cyls
)
{
fprintf
(
stderr
,
"qemu: '%s' trans must be used with cyls,heads and secs
\n
"
,
buf
);
return
NULL
;
}
if
(
!
strcmp
(
buf
,
"none"
))
translation
=
BIOS_ATA_TRANSLATION_NONE
;
else
if
(
!
strcmp
(
buf
,
"lba"
))
translation
=
BIOS_ATA_TRANSLATION_LBA
;
else
if
(
!
strcmp
(
buf
,
"auto"
))
translation
=
BIOS_ATA_TRANSLATION_AUTO
;
else
{
fprintf
(
stderr
,
"qemu: '%s' invalid translation type
\n
"
,
buf
);
return
NULL
;
}
}
if
((
buf
=
qemu_opt_get
(
opts
,
"media"
))
!=
NULL
)
{
if
(
!
strcmp
(
buf
,
"disk"
))
{
media
=
MEDIA_DISK
;
}
else
if
(
!
strcmp
(
buf
,
"cdrom"
))
{
if
(
cyls
||
secs
||
heads
)
{
fprintf
(
stderr
,
"qemu: '%s' invalid physical CHS format
\n
"
,
buf
);
return
NULL
;
}
media
=
MEDIA_CDROM
;
}
else
{
fprintf
(
stderr
,
"qemu: '%s' invalid media
\n
"
,
buf
);
return
NULL
;
}
}
if
((
buf
=
qemu_opt_get
(
opts
,
"cache"
))
!=
NULL
)
{
if
(
!
strcmp
(
buf
,
"off"
)
||
!
strcmp
(
buf
,
"none"
))
{
bdrv_flags
|=
BDRV_O_NOCACHE
;
}
else
if
(
!
strcmp
(
buf
,
"writeback"
))
{
bdrv_flags
|=
BDRV_O_CACHE_WB
;
}
else
if
(
!
strcmp
(
buf
,
"unsafe"
))
{
bdrv_flags
|=
BDRV_O_CACHE_WB
;
bdrv_flags
|=
BDRV_O_NO_FLUSH
;
}
else
if
(
!
strcmp
(
buf
,
"writethrough"
))
{
/* this is the default */
}
else
{
fprintf
(
stderr
,
"qemu: invalid cache option
\n
"
);
return
NULL
;
}
}
#ifdef CONFIG_LINUX_AIO
if
((
buf
=
qemu_opt_get
(
opts
,
"aio"
))
!=
NULL
)
{
if
(
!
strcmp
(
buf
,
"native"
))
{
bdrv_flags
|=
BDRV_O_NATIVE_AIO
;
}
else
if
(
!
strcmp
(
buf
,
"threads"
))
{
/* this is the default */
}
else
{
fprintf
(
stderr
,
"qemu: invalid aio option
\n
"
);
return
NULL
;
}
}
#endif
if
((
buf
=
qemu_opt_get
(
opts
,
"format"
))
!=
NULL
)
{
if
(
strcmp
(
buf
,
"?"
)
==
0
)
{
fprintf
(
stderr
,
"qemu: Supported formats:"
);
bdrv_iterate_format
(
bdrv_format_print
,
NULL
);
fprintf
(
stderr
,
"
\n
"
);
return
NULL
;
}
drv
=
bdrv_find_whitelisted_format
(
buf
);
if
(
!
drv
)
{
fprintf
(
stderr
,
"qemu: '%s' invalid format
\n
"
,
buf
);
return
NULL
;
}
}
on_write_error
=
BLOCK_ERR_STOP_ENOSPC
;
if
((
buf
=
qemu_opt_get
(
opts
,
"werror"
))
!=
NULL
)
{
if
(
type
!=
IF_IDE
&&
type
!=
IF_SCSI
&&
type
!=
IF_VIRTIO
&&
type
!=
IF_NONE
)
{
fprintf
(
stderr
,
"werror is no supported by this format
\n
"
);
return
NULL
;
}
on_write_error
=
parse_block_error_action
(
buf
,
0
);
if
(
on_write_error
<
0
)
{
return
NULL
;
}
}
on_read_error
=
BLOCK_ERR_REPORT
;
if
((
buf
=
qemu_opt_get
(
opts
,
"rerror"
))
!=
NULL
)
{
if
(
type
!=
IF_IDE
&&
type
!=
IF_VIRTIO
&&
type
!=
IF_NONE
)
{
fprintf
(
stderr
,
"rerror is no supported by this format
\n
"
);
return
NULL
;
}
on_read_error
=
parse_block_error_action
(
buf
,
1
);
if
(
on_read_error
<
0
)
{
return
NULL
;
}
}
if
((
devaddr
=
qemu_opt_get
(
opts
,
"addr"
))
!=
NULL
)
{
if
(
type
!=
IF_VIRTIO
)
{
fprintf
(
stderr
,
"addr is not supported
\n
"
);
return
NULL
;
}
}
/* compute bus and unit according index */
if
(
index
!=
-
1
)
{
if
(
bus_id
!=
0
||
unit_id
!=
-
1
)
{
fprintf
(
stderr
,
"qemu: index cannot be used with bus and unit
\n
"
);
return
NULL
;
}
if
(
max_devs
==
0
)
{
unit_id
=
index
;
bus_id
=
0
;
}
else
{
unit_id
=
index
%
max_devs
;
bus_id
=
index
/
max_devs
;
}
}
/* if user doesn't specify a unit_id,
* try to find the first free
*/
if
(
unit_id
==
-
1
)
{
unit_id
=
0
;
while
(
drive_get
(
type
,
bus_id
,
unit_id
)
!=
NULL
)
{
unit_id
++
;
if
(
max_devs
&&
unit_id
>=
max_devs
)
{
unit_id
-=
max_devs
;
bus_id
++
;
}
}
}
/* check unit id */
if
(
max_devs
&&
unit_id
>=
max_devs
)
{
fprintf
(
stderr
,
"qemu: unit %d too big (max is %d)
\n
"
,
unit_id
,
max_devs
-
1
);
return
NULL
;
}
/*
* ignore multiple definitions
*/
if
(
drive_get
(
type
,
bus_id
,
unit_id
)
!=
NULL
)
{
*
fatal_error
=
0
;
return
NULL
;
}
/* init */
dinfo
=
qemu_mallocz
(
sizeof
(
*
dinfo
));
if
((
buf
=
qemu_opts_id
(
opts
))
!=
NULL
)
{
dinfo
->
id
=
qemu_strdup
(
buf
);
}
else
{
/* no id supplied -> create one */
dinfo
->
id
=
qemu_mallocz
(
32
);
if
(
type
==
IF_IDE
||
type
==
IF_SCSI
)
mediastr
=
(
media
==
MEDIA_CDROM
)
?
"-cd"
:
"-hd"
;
if
(
max_devs
)
snprintf
(
dinfo
->
id
,
32
,
"%s%i%s%i"
,
devname
,
bus_id
,
mediastr
,
unit_id
);
else
snprintf
(
dinfo
->
id
,
32
,
"%s%s%i"
,
devname
,
mediastr
,
unit_id
);
}
dinfo
->
bdrv
=
bdrv_new
(
dinfo
->
id
);
dinfo
->
devaddr
=
devaddr
;
dinfo
->
type
=
type
;
dinfo
->
bus
=
bus_id
;
dinfo
->
unit
=
unit_id
;
dinfo
->
on_read_error
=
on_read_error
;
dinfo
->
on_write_error
=
on_write_error
;
dinfo
->
opts
=
opts
;
if
(
serial
)
strncpy
(
dinfo
->
serial
,
serial
,
sizeof
(
dinfo
->
serial
)
-
1
);
QTAILQ_INSERT_TAIL
(
&
drives
,
dinfo
,
next
);
switch
(
type
)
{
case
IF_IDE
:
case
IF_SCSI
:
case
IF_XEN
:
case
IF_NONE
:
switch
(
media
)
{
case
MEDIA_DISK
:
if
(
cyls
!=
0
)
{
bdrv_set_geometry_hint
(
dinfo
->
bdrv
,
cyls
,
heads
,
secs
);
bdrv_set_translation_hint
(
dinfo
->
bdrv
,
translation
);
}
break
;
case
MEDIA_CDROM
:
bdrv_set_type_hint
(
dinfo
->
bdrv
,
BDRV_TYPE_CDROM
);
break
;
}
break
;
case
IF_SD
:
/* FIXME: This isn't really a floppy, but it's a reasonable
approximation. */
case
IF_FLOPPY
:
bdrv_set_type_hint
(
dinfo
->
bdrv
,
BDRV_TYPE_FLOPPY
);
break
;
case
IF_PFLASH
:
case
IF_MTD
:
break
;
case
IF_VIRTIO
:
/* add virtio block device */
opts
=
qemu_opts_create
(
&
qemu_device_opts
,
NULL
,
0
);
qemu_opt_set
(
opts
,
"driver"
,
"virtio-blk-pci"
);
qemu_opt_set
(
opts
,
"drive"
,
dinfo
->
id
);
if
(
devaddr
)
qemu_opt_set
(
opts
,
"addr"
,
devaddr
);
break
;
case
IF_COUNT
:
abort
();
}
if
(
!
file
)
{
*
fatal_error
=
0
;
return
NULL
;
}
if
(
snapshot
)
{
/* always use cache=unsafe with snapshot */
bdrv_flags
&=
~
BDRV_O_CACHE_MASK
;
bdrv_flags
|=
(
BDRV_O_SNAPSHOT
|
BDRV_O_CACHE_WB
|
BDRV_O_NO_FLUSH
);
}
if
(
media
==
MEDIA_CDROM
)
{
/* CDROM is fine for any interface, don't check. */
ro
=
1
;
}
else
if
(
ro
==
1
)
{
if
(
type
!=
IF_SCSI
&&
type
!=
IF_VIRTIO
&&
type
!=
IF_FLOPPY
&&
type
!=
IF_NONE
)
{
fprintf
(
stderr
,
"qemu: readonly flag not supported for drive with this interface
\n
"
);
return
NULL
;
}
}
bdrv_flags
|=
ro
?
0
:
BDRV_O_RDWR
;
ret
=
bdrv_open
(
dinfo
->
bdrv
,
file
,
bdrv_flags
,
drv
);
if
(
ret
<
0
)
{
fprintf
(
stderr
,
"qemu: could not open disk image %s: %s
\n
"
,
file
,
strerror
(
-
ret
));
return
NULL
;
}
if
(
bdrv_key_required
(
dinfo
->
bdrv
))
autostart
=
0
;
*
fatal_error
=
0
;
return
dinfo
;
}
void
do_commit
(
Monitor
*
mon
,
const
QDict
*
qdict
)
{
int
all_devices
;
DriveInfo
*
dinfo
;
const
char
*
device
=
qdict_get_str
(
qdict
,
"device"
);
all_devices
=
!
strcmp
(
device
,
"all"
);
QTAILQ_FOREACH
(
dinfo
,
&
drives
,
next
)
{
if
(
!
all_devices
)
if
(
strcmp
(
bdrv_get_device_name
(
dinfo
->
bdrv
),
device
))
continue
;
bdrv_commit
(
dinfo
->
bdrv
);
}
}
static
int
eject_device
(
Monitor
*
mon
,
BlockDriverState
*
bs
,
int
force
)
{
if
(
bdrv_is_inserted
(
bs
))
{
if
(
!
force
)
{
if
(
!
bdrv_is_removable
(
bs
))
{
qerror_report
(
QERR_DEVICE_NOT_REMOVABLE
,
bdrv_get_device_name
(
bs
));
return
-
1
;
}
if
(
bdrv_is_locked
(
bs
))
{
qerror_report
(
QERR_DEVICE_LOCKED
,
bdrv_get_device_name
(
bs
));
return
-
1
;
}
}
bdrv_close
(
bs
);
}
return
0
;
}
int
do_eject
(
Monitor
*
mon
,
const
QDict
*
qdict
,
QObject
**
ret_data
)
{
BlockDriverState
*
bs
;
int
force
=
qdict_get_int
(
qdict
,
"force"
);
const
char
*
filename
=
qdict_get_str
(
qdict
,
"device"
);
bs
=
bdrv_find
(
filename
);
if
(
!
bs
)
{
qerror_report
(
QERR_DEVICE_NOT_FOUND
,
filename
);
return
-
1
;
}
return
eject_device
(
mon
,
bs
,
force
);
}
int
do_block_set_passwd
(
Monitor
*
mon
,
const
QDict
*
qdict
,
QObject
**
ret_data
)
{
BlockDriverState
*
bs
;
int
err
;
bs
=
bdrv_find
(
qdict_get_str
(
qdict
,
"device"
));
if
(
!
bs
)
{
qerror_report
(
QERR_DEVICE_NOT_FOUND
,
qdict_get_str
(
qdict
,
"device"
));
return
-
1
;
}
err
=
bdrv_set_key
(
bs
,
qdict_get_str
(
qdict
,
"password"
));
if
(
err
==
-
EINVAL
)
{
qerror_report
(
QERR_DEVICE_NOT_ENCRYPTED
,
bdrv_get_device_name
(
bs
));
return
-
1
;
}
else
if
(
err
<
0
)
{
qerror_report
(
QERR_INVALID_PASSWORD
);
return
-
1
;
}
return
0
;
}
int
do_change_block
(
Monitor
*
mon
,
const
char
*
device
,
const
char
*
filename
,
const
char
*
fmt
)
{
BlockDriverState
*
bs
;
BlockDriver
*
drv
=
NULL
;
int
bdrv_flags
;
bs
=
bdrv_find
(
device
);
if
(
!
bs
)
{
qerror_report
(
QERR_DEVICE_NOT_FOUND
,
device
);
return
-
1
;
}
if
(
fmt
)
{
drv
=
bdrv_find_whitelisted_format
(
fmt
);
if
(
!
drv
)
{
qerror_report
(
QERR_INVALID_BLOCK_FORMAT
,
fmt
);
return
-
1
;
}
}
if
(
eject_device
(
mon
,
bs
,
0
)
<
0
)
{
return
-
1
;
}
bdrv_flags
=
bdrv_get_type_hint
(
bs
)
==
BDRV_TYPE_CDROM
?
0
:
BDRV_O_RDWR
;
if
(
bdrv_open
(
bs
,
filename
,
bdrv_flags
,
drv
)
<
0
)
{
qerror_report
(
QERR_OPEN_FILE_FAILED
,
filename
);
return
-
1
;
}
return
monitor_read_bdrv_key_start
(
mon
,
bs
,
NULL
,
NULL
);
}
blockdev.h
0 → 100644
浏览文件 @
a4673e27
/*
* QEMU host block devices
*
* Copyright (c) 2003-2008 Fabrice Bellard
*
* This work is licensed under the terms of the GNU GPL, version 2 or
* later. See the COPYING file in the top-level directory.
*/
#ifndef BLOCKDEV_H
#define BLOCKDEV_H
#include "block.h"
#include "qemu-queue.h"
typedef
enum
{
IF_NONE
,
IF_IDE
,
IF_SCSI
,
IF_FLOPPY
,
IF_PFLASH
,
IF_MTD
,
IF_SD
,
IF_VIRTIO
,
IF_XEN
,
IF_COUNT
}
BlockInterfaceType
;
typedef
enum
{
BLOCK_ERR_REPORT
,
BLOCK_ERR_IGNORE
,
BLOCK_ERR_STOP_ENOSPC
,
BLOCK_ERR_STOP_ANY
}
BlockInterfaceErrorAction
;
#define BLOCK_SERIAL_STRLEN 20
typedef
struct
DriveInfo
{
BlockDriverState
*
bdrv
;
char
*
id
;
const
char
*
devaddr
;
BlockInterfaceType
type
;
int
bus
;
int
unit
;
QemuOpts
*
opts
;
BlockInterfaceErrorAction
on_read_error
;
BlockInterfaceErrorAction
on_write_error
;
char
serial
[
BLOCK_SERIAL_STRLEN
+
1
];
QTAILQ_ENTRY
(
DriveInfo
)
next
;
}
DriveInfo
;
#define MAX_IDE_DEVS 2
#define MAX_SCSI_DEVS 7
extern
QTAILQ_HEAD
(
drivelist
,
DriveInfo
)
drives
;
extern
DriveInfo
*
drive_get
(
BlockInterfaceType
type
,
int
bus
,
int
unit
);
extern
DriveInfo
*
drive_get_by_id
(
const
char
*
id
);
extern
int
drive_get_max_bus
(
BlockInterfaceType
type
);
extern
void
drive_uninit
(
DriveInfo
*
dinfo
);
extern
const
char
*
drive_get_serial
(
BlockDriverState
*
bdrv
);
extern
BlockInterfaceErrorAction
drive_get_on_error
(
BlockDriverState
*
bdrv
,
int
is_read
);
extern
QemuOpts
*
drive_add
(
const
char
*
file
,
const
char
*
fmt
,
...);
extern
DriveInfo
*
drive_init
(
QemuOpts
*
arg
,
int
default_to_scsi
,
int
*
fatal_error
);
/* device-hotplug */
DriveInfo
*
add_init_drive
(
const
char
*
opts
);
void
do_commit
(
Monitor
*
mon
,
const
QDict
*
qdict
);
int
do_eject
(
Monitor
*
mon
,
const
QDict
*
qdict
,
QObject
**
ret_data
);
int
do_block_set_passwd
(
Monitor
*
mon
,
const
QDict
*
qdict
,
QObject
**
ret_data
);
int
do_change_block
(
Monitor
*
mon
,
const
char
*
device
,
const
char
*
filename
,
const
char
*
fmt
);
#endif
hw/acpi_piix4.c
浏览文件 @
a4673e27
...
...
@@ -21,6 +21,7 @@
#include "pm_smbus.h"
#include "pci.h"
#include "acpi.h"
#include "sysemu.h"
//#define DEBUG
...
...
hw/apb_pci.c
浏览文件 @
a4673e27
...
...
@@ -31,6 +31,7 @@
#include "pci_host.h"
#include "rwhandler.h"
#include "apb_pci.h"
#include "sysemu.h"
/* debug APB */
//#define DEBUG_APB
...
...
hw/device-hotplug.c
浏览文件 @
a4673e27
...
...
@@ -25,8 +25,6 @@
#include "hw.h"
#include "boards.h"
#include "net.h"
#include "block_int.h"
#include "sysemu.h"
DriveInfo
*
add_init_drive
(
const
char
*
optstr
)
{
...
...
@@ -38,7 +36,7 @@ DriveInfo *add_init_drive(const char *optstr)
if
(
!
opts
)
return
NULL
;
dinfo
=
drive_init
(
opts
,
current_machine
,
&
fatal_error
);
dinfo
=
drive_init
(
opts
,
current_machine
->
use_scsi
,
&
fatal_error
);
if
(
!
dinfo
)
{
qemu_opts_del
(
opts
);
return
NULL
;
...
...
hw/fdc.c
浏览文件 @
a4673e27
...
...
@@ -29,7 +29,6 @@
#include "hw.h"
#include "fdc.h"
#include "block.h"
#include "qemu-timer.h"
#include "isa.h"
#include "sysbus.h"
...
...
hw/fdc.h
浏览文件 @
a4673e27
...
...
@@ -2,7 +2,7 @@
#define HW_FDC_H
/* fdc.c */
#include "
sysemu
.h"
#include "
blockdev
.h"
#define MAX_FD 2
typedef
struct
FDCtrl
FDCtrl
;
...
...
hw/ide/cmd646.c
浏览文件 @
a4673e27
...
...
@@ -260,8 +260,8 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
irq
=
qemu_allocate_irqs
(
cmd646_set_irq
,
d
,
2
);
ide_bus_new
(
&
d
->
bus
[
0
],
&
d
->
dev
.
qdev
);
ide_bus_new
(
&
d
->
bus
[
1
],
&
d
->
dev
.
qdev
);
ide_init2
(
&
d
->
bus
[
0
],
NULL
,
NULL
,
irq
[
0
]);
ide_init2
(
&
d
->
bus
[
1
],
NULL
,
NULL
,
irq
[
1
]);
ide_init2
(
&
d
->
bus
[
0
],
irq
[
0
]);
ide_init2
(
&
d
->
bus
[
1
],
irq
[
1
]);
vmstate_register
(
0
,
&
vmstate_ide_pci
,
d
);
qemu_register_reset
(
cmd646_reset
,
d
);
...
...
hw/ide/core.c
浏览文件 @
a4673e27
...
...
@@ -26,8 +26,6 @@
#include <hw/pc.h>
#include <hw/pci.h>
#include <hw/scsi.h>
#include "block.h"
#include "block_int.h"
#include "qemu-timer.h"
#include "sysemu.h"
#include "dma.h"
...
...
@@ -98,6 +96,7 @@ static void ide_identify(IDEState *s)
{
uint16_t
*
p
;
unsigned
int
oldsize
;
IDEDevice
*
dev
;
if
(
s
->
identify_set
)
{
memcpy
(
s
->
io_buffer
,
s
->
identify_data
,
sizeof
(
s
->
identify_data
));
...
...
@@ -165,8 +164,9 @@ static void ide_identify(IDEState *s)
put_le16
(
p
+
101
,
s
->
nb_sectors
>>
16
);
put_le16
(
p
+
102
,
s
->
nb_sectors
>>
32
);
put_le16
(
p
+
103
,
s
->
nb_sectors
>>
48
);
if
(
s
->
conf
&&
s
->
conf
->
physical_block_size
)
put_le16
(
p
+
106
,
0x6000
|
get_physical_block_exp
(
s
->
conf
));
dev
=
s
->
unit
?
s
->
bus
->
slave
:
s
->
bus
->
master
;
if
(
dev
&&
dev
->
conf
.
physical_block_size
)
put_le16
(
p
+
106
,
0x6000
|
get_physical_block_exp
(
&
dev
->
conf
));
memcpy
(
s
->
identify_data
,
p
,
sizeof
(
s
->
identify_data
));
s
->
identify_set
=
1
;
...
...
@@ -2594,39 +2594,35 @@ void ide_bus_reset(IDEBus *bus)
ide_clear_hob
(
bus
);
}
void
ide_init_drive
(
IDEState
*
s
,
DriveInfo
*
dinfo
,
BlockConf
*
conf
,
const
char
*
version
)
void
ide_init_drive
(
IDEState
*
s
,
DriveInfo
*
dinfo
,
const
char
*
version
,
const
char
*
serial
)
{
int
cylinders
,
heads
,
secs
;
uint64_t
nb_sectors
;
if
(
dinfo
&&
dinfo
->
bdrv
)
{
s
->
bs
=
dinfo
->
bdrv
;
bdrv_get_geometry
(
s
->
bs
,
&
nb_sectors
);
bdrv_guess_geometry
(
s
->
bs
,
&
cylinders
,
&
heads
,
&
secs
);
s
->
cylinders
=
cylinders
;
s
->
heads
=
heads
;
s
->
sectors
=
secs
;
s
->
nb_sectors
=
nb_sectors
;
/* The SMART values should be preserved across power cycles
but they aren't. */
s
->
smart_enabled
=
1
;
s
->
smart_autosave
=
1
;
s
->
smart_errors
=
0
;
s
->
smart_selftest_count
=
0
;
if
(
bdrv_get_type_hint
(
s
->
bs
)
==
BDRV_TYPE_CDROM
)
{
s
->
is_cdrom
=
1
;
bdrv_set_change_cb
(
s
->
bs
,
cdrom_change_cb
,
s
);
}
strncpy
(
s
->
drive_serial_str
,
drive_get_serial
(
s
->
bs
),
sizeof
(
s
->
drive_serial_str
));
if
(
conf
)
{
s
->
conf
=
conf
;
}
s
->
bs
=
dinfo
->
bdrv
;
bdrv_get_geometry
(
s
->
bs
,
&
nb_sectors
);
bdrv_guess_geometry
(
s
->
bs
,
&
cylinders
,
&
heads
,
&
secs
);
s
->
cylinders
=
cylinders
;
s
->
heads
=
heads
;
s
->
sectors
=
secs
;
s
->
nb_sectors
=
nb_sectors
;
/* The SMART values should be preserved across power cycles
but they aren't. */
s
->
smart_enabled
=
1
;
s
->
smart_autosave
=
1
;
s
->
smart_errors
=
0
;
s
->
smart_selftest_count
=
0
;
if
(
bdrv_get_type_hint
(
s
->
bs
)
==
BDRV_TYPE_CDROM
)
{
s
->
is_cdrom
=
1
;
bdrv_set_change_cb
(
s
->
bs
,
cdrom_change_cb
,
s
);
}
if
(
strlen
(
s
->
drive_serial_str
)
==
0
)
if
(
serial
&&
*
serial
)
{
strncpy
(
s
->
drive_serial_str
,
serial
,
sizeof
(
s
->
drive_serial_str
));
}
else
{
snprintf
(
s
->
drive_serial_str
,
sizeof
(
s
->
drive_serial_str
),
"QM%05d"
,
s
->
drive_serial
);
}
if
(
version
)
{
pstrcpy
(
s
->
version
,
sizeof
(
s
->
version
),
version
);
}
else
{
...
...
@@ -2635,27 +2631,47 @@ void ide_init_drive(IDEState *s, DriveInfo *dinfo, BlockConf *conf,
ide_reset
(
s
);
}
void
ide_init2
(
IDEBus
*
bus
,
DriveInfo
*
hd0
,
DriveInfo
*
hd1
,
qemu_irq
irq
)
static
void
ide_init1
(
IDEBus
*
bus
,
int
unit
)
{
IDEState
*
s
;
static
int
drive_serial
=
1
;
IDEState
*
s
=
&
bus
->
ifs
[
unit
];
s
->
bus
=
bus
;
s
->
unit
=
unit
;
s
->
drive_serial
=
drive_serial
++
;
s
->
io_buffer
=
qemu_blockalign
(
s
->
bs
,
IDE_DMA_BUF_SECTORS
*
512
+
4
);
s
->
io_buffer_total_len
=
IDE_DMA_BUF_SECTORS
*
512
+
4
;
s
->
smart_selftest_data
=
qemu_blockalign
(
s
->
bs
,
512
);
s
->
sector_write_timer
=
qemu_new_timer
(
vm_clock
,
ide_sector_write_timer_cb
,
s
);
}
void
ide_init2
(
IDEBus
*
bus
,
qemu_irq
irq
)
{
int
i
;
for
(
i
=
0
;
i
<
2
;
i
++
)
{
s
=
bus
->
ifs
+
i
;
s
->
bus
=
bus
;
s
->
unit
=
i
;
s
->
drive_serial
=
drive_serial
++
;
s
->
io_buffer
=
qemu_blockalign
(
s
->
bs
,
IDE_DMA_BUF_SECTORS
*
512
+
4
);
s
->
io_buffer_total_len
=
IDE_DMA_BUF_SECTORS
*
512
+
4
;
s
->
smart_selftest_data
=
qemu_blockalign
(
s
->
bs
,
512
);
s
->
sector_write_timer
=
qemu_new_timer
(
vm_clock
,
ide_sector_write_timer_cb
,
s
);
if
(
i
==
0
)
ide_init_drive
(
s
,
hd0
,
NULL
,
NULL
);
if
(
i
==
1
)
ide_init_drive
(
s
,
hd1
,
NULL
,
NULL
);
ide_init1
(
bus
,
i
);
ide_reset
(
&
bus
->
ifs
[
i
]);
}
bus
->
irq
=
irq
;
}
/* TODO convert users to qdev and remove */
void
ide_init2_with_non_qdev_drives
(
IDEBus
*
bus
,
DriveInfo
*
hd0
,
DriveInfo
*
hd1
,
qemu_irq
irq
)
{
int
i
;
DriveInfo
*
dinfo
;
for
(
i
=
0
;
i
<
2
;
i
++
)
{
dinfo
=
i
==
0
?
hd0
:
hd1
;
ide_init1
(
bus
,
i
);
if
(
dinfo
)
{
ide_init_drive
(
&
bus
->
ifs
[
i
],
dinfo
,
NULL
,
dinfo
->
serial
);
}
else
{
ide_reset
(
&
bus
->
ifs
[
i
]);
}
}
bus
->
irq
=
irq
;
}
...
...
hw/ide/internal.h
浏览文件 @
a4673e27
...
...
@@ -398,7 +398,6 @@ struct IDEState {
/* set for lba48 access */
uint8_t
lba48
;
BlockDriverState
*
bs
;
BlockConf
*
conf
;
char
version
[
9
];
/* ATAPI specific */
uint8_t
sense_key
;
...
...
@@ -458,14 +457,13 @@ struct IDEDevice {
uint32_t
unit
;
BlockConf
conf
;
char
*
version
;
char
*
serial
;
};
typedef
int
(
*
ide_qdev_initfn
)(
IDEDevice
*
dev
);
struct
IDEDeviceInfo
{
DeviceInfo
qdev
;
ide_qdev_initfn
init
;
uint32_t
unit
;
DriveInfo
*
drive
;
};
#define BM_STATUS_DMAING 0x01
...
...
@@ -557,10 +555,11 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr);
void
ide_data_writel
(
void
*
opaque
,
uint32_t
addr
,
uint32_t
val
);
uint32_t
ide_data_readl
(
void
*
opaque
,
uint32_t
addr
);
void
ide_init_drive
(
IDEState
*
s
,
DriveInfo
*
dinfo
,
BlockConf
*
conf
,
const
char
*
version
);
void
ide_init2
(
IDEBus
*
bus
,
DriveInfo
*
hd0
,
DriveInfo
*
hd1
,
qemu_irq
irq
);
void
ide_init_drive
(
IDEState
*
s
,
DriveInfo
*
dinfo
,
const
char
*
version
,
const
char
*
serial
);
void
ide_init2
(
IDEBus
*
bus
,
qemu_irq
irq
);
void
ide_init2_with_non_qdev_drives
(
IDEBus
*
bus
,
DriveInfo
*
hd0
,
DriveInfo
*
hd1
,
qemu_irq
irq
);
void
ide_init_ioport
(
IDEBus
*
bus
,
int
iobase
,
int
iobase2
);
/* hw/ide/qdev.c */
...
...
hw/ide/isa.c
浏览文件 @
a4673e27
...
...
@@ -70,7 +70,7 @@ static int isa_ide_initfn(ISADevice *dev)
ide_bus_new
(
&
s
->
bus
,
&
s
->
dev
.
qdev
);
ide_init_ioport
(
&
s
->
bus
,
s
->
iobase
,
s
->
iobase2
);
isa_init_irq
(
dev
,
&
s
->
irq
,
s
->
isairq
);
ide_init2
(
&
s
->
bus
,
NULL
,
NULL
,
s
->
irq
);
ide_init2
(
&
s
->
bus
,
s
->
irq
);
vmstate_register
(
0
,
&
vmstate_ide_isa
,
s
);
return
0
;
};
...
...
hw/ide/macio.c
浏览文件 @
a4673e27
...
...
@@ -314,7 +314,7 @@ int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
int
pmac_ide_memory
;
d
=
qemu_mallocz
(
sizeof
(
MACIOIDEState
));
ide_init2
(
&
d
->
bus
,
hd_table
[
0
],
hd_table
[
1
],
irq
);
ide_init2
_with_non_qdev_drives
(
&
d
->
bus
,
hd_table
[
0
],
hd_table
[
1
],
irq
);
if
(
dbdma
)
DBDMA_register_channel
(
dbdma
,
channel
,
dma_irq
,
pmac_ide_transfer
,
pmac_ide_flush
,
d
);
...
...
hw/ide/microdrive.c
浏览文件 @
a4673e27
...
...
@@ -539,7 +539,8 @@ PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv)
md
->
card
.
cis
=
dscm1xxxx_cis
;
md
->
card
.
cis_len
=
sizeof
(
dscm1xxxx_cis
);
ide_init2
(
&
md
->
bus
,
bdrv
,
NULL
,
qemu_allocate_irqs
(
md_set_irq
,
md
,
1
)[
0
]);
ide_init2_with_non_qdev_drives
(
&
md
->
bus
,
bdrv
,
NULL
,
qemu_allocate_irqs
(
md_set_irq
,
md
,
1
)[
0
]);
md
->
bus
.
ifs
[
0
].
is_cf
=
1
;
md
->
bus
.
ifs
[
0
].
mdata_size
=
METADATA_SIZE
;
md
->
bus
.
ifs
[
0
].
mdata_storage
=
(
uint8_t
*
)
qemu_mallocz
(
METADATA_SIZE
);
...
...
hw/ide/mmio.c
浏览文件 @
a4673e27
...
...
@@ -125,7 +125,7 @@ void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2,
MMIOState
*
s
=
qemu_mallocz
(
sizeof
(
MMIOState
));
int
mem1
,
mem2
;
ide_init2
(
&
s
->
bus
,
hd0
,
hd1
,
irq
);
ide_init2
_with_non_qdev_drives
(
&
s
->
bus
,
hd0
,
hd1
,
irq
);
s
->
shift
=
shift
;
...
...
hw/ide/piix.c
浏览文件 @
a4673e27
...
...
@@ -135,8 +135,8 @@ static int pci_piix_ide_initfn(PCIIDEState *d)
ide_init_ioport
(
&
d
->
bus
[
0
],
0x1f0
,
0x3f6
);
ide_init_ioport
(
&
d
->
bus
[
1
],
0x170
,
0x376
);
ide_init2
(
&
d
->
bus
[
0
],
NULL
,
NULL
,
isa_reserve_irq
(
14
));
ide_init2
(
&
d
->
bus
[
1
],
NULL
,
NULL
,
isa_reserve_irq
(
15
));
ide_init2
(
&
d
->
bus
[
0
],
isa_reserve_irq
(
14
));
ide_init2
(
&
d
->
bus
[
1
],
isa_reserve_irq
(
15
));
return
0
;
}
...
...
hw/ide/qdev.c
浏览文件 @
a4673e27
...
...
@@ -17,7 +17,6 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <hw/hw.h>
#include "sysemu.h"
#include "dma.h"
#include <hw/ide/internal.h>
...
...
@@ -99,8 +98,23 @@ typedef struct IDEDrive {
static
int
ide_drive_initfn
(
IDEDevice
*
dev
)
{
IDEBus
*
bus
=
DO_UPCAST
(
IDEBus
,
qbus
,
dev
->
qdev
.
parent_bus
);
ide_init_drive
(
bus
->
ifs
+
dev
->
unit
,
dev
->
conf
.
dinfo
,
&
dev
->
conf
,
dev
->
version
);
IDEState
*
s
=
bus
->
ifs
+
dev
->
unit
;
const
char
*
serial
;
serial
=
dev
->
serial
;
if
(
!
serial
)
{
/* try to fall back to value set with legacy -drive serial=... */
serial
=
dev
->
conf
.
dinfo
->
serial
;
}
ide_init_drive
(
s
,
dev
->
conf
.
dinfo
,
dev
->
version
,
serial
);
if
(
!
dev
->
version
)
{
dev
->
version
=
qemu_strdup
(
s
->
version
);
}
if
(
!
dev
->
serial
)
{
dev
->
serial
=
qemu_strdup
(
s
->
drive_serial_str
);
}
return
0
;
}
...
...
@@ -112,6 +126,7 @@ static IDEDeviceInfo ide_drive_info = {
DEFINE_PROP_UINT32
(
"unit"
,
IDEDrive
,
dev
.
unit
,
-
1
),
DEFINE_BLOCK_PROPERTIES
(
IDEDrive
,
dev
.
conf
),
DEFINE_PROP_STRING
(
"ver"
,
IDEDrive
,
dev
.
version
),
DEFINE_PROP_STRING
(
"serial"
,
IDEDrive
,
dev
.
serial
),
DEFINE_PROP_END_OF_LIST
(),
}
};
...
...
hw/lan9118.c
浏览文件 @
a4673e27
...
...
@@ -10,6 +10,7 @@
#include "sysbus.h"
#include "net.h"
#include "devices.h"
#include "sysemu.h"
/* For crc32 */
#include <zlib.h>
...
...
hw/nand.c
浏览文件 @
a4673e27
...
...
@@ -13,9 +13,8 @@
# include "hw.h"
# include "flash.h"
# include "block.h"
# include "block
dev
.h"
/* FIXME: Pass block device as an argument. */
# include "sysemu.h"
# define NAND_CMD_READ0 0x00
# define NAND_CMD_READ1 0x01
...
...
hw/omap2.c
浏览文件 @
a4673e27
...
...
@@ -17,6 +17,8 @@
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "blockdev.h"
#include "hw.h"
#include "arm-misc.h"
#include "omap.h"
...
...
hw/onenand.c
浏览文件 @
a4673e27
...
...
@@ -21,8 +21,7 @@
#include "qemu-common.h"
#include "flash.h"
#include "irq.h"
#include "sysemu.h"
#include "block.h"
#include "blockdev.h"
/* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
#define PAGE_SHIFT 11
...
...
hw/parallel.c
浏览文件 @
a4673e27
...
...
@@ -26,6 +26,7 @@
#include "qemu-char.h"
#include "isa.h"
#include "pc.h"
#include "sysemu.h"
//#define DEBUG_PARALLEL
...
...
hw/pc.c
浏览文件 @
a4673e27
...
...
@@ -36,6 +36,7 @@
#include "multiboot.h"
#include "mc146818rtc.h"
#include "sysbus.h"
#include "sysemu.h"
/* output Bochs bios info messages */
//#define DEBUG_BIOS
...
...
hw/pc_piix.c
浏览文件 @
a4673e27
...
...
@@ -32,6 +32,7 @@
#include "boards.h"
#include "ide.h"
#include "kvm.h"
#include "sysemu.h"
#define MAX_IDE_BUS 2
...
...
hw/pci-hotplug.c
浏览文件 @
a4673e27
...
...
@@ -26,10 +26,8 @@
#include "boards.h"
#include "pci.h"
#include "net.h"
#include "sysemu.h"
#include "pc.h"
#include "monitor.h"
#include "block_int.h"
#include "scsi.h"
#include "virtio-blk.h"
#include "qemu-config.h"
...
...
hw/pcmcia.h
浏览文件 @
a4673e27
/* PCMCIA/Cardbus */
#include "qemu-common.h"
#include "
sysemu
.h"
#include "
blockdev
.h"
typedef
struct
{
qemu_irq
irq
;
...
...
hw/pl181.c
浏览文件 @
a4673e27
...
...
@@ -9,7 +9,6 @@
#include "sysbus.h"
#include "sd.h"
#include "sysemu.h"
//#define DEBUG_PL181 1
...
...
hw/qdev-properties.c
浏览文件 @
a4673e27
#include "sysemu.h"
#include "net.h"
#include "qdev.h"
#include "qerror.h"
...
...
@@ -260,6 +259,11 @@ static int parse_string(DeviceState *dev, Property *prop, const char *str)
return
0
;
}
static
void
free_string
(
DeviceState
*
dev
,
Property
*
prop
)
{
qemu_free
(
*
(
char
**
)
qdev_get_prop_ptr
(
dev
,
prop
));
}
static
int
print_string
(
DeviceState
*
dev
,
Property
*
prop
,
char
*
dest
,
size_t
len
)
{
char
**
ptr
=
qdev_get_prop_ptr
(
dev
,
prop
);
...
...
@@ -274,6 +278,7 @@ PropertyInfo qdev_prop_string = {
.
size
=
sizeof
(
char
*
),
.
parse
=
parse_string
,
.
print
=
print_string
,
.
free
=
free_string
,
};
/* --- drive --- */
...
...
@@ -617,6 +622,11 @@ void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value)
qdev_prop_set
(
dev
,
name
,
&
value
,
PROP_TYPE_UINT64
);
}
void
qdev_prop_set_string
(
DeviceState
*
dev
,
const
char
*
name
,
char
*
value
)
{
qdev_prop_set
(
dev
,
name
,
&
value
,
PROP_TYPE_STRING
);
}
void
qdev_prop_set_drive
(
DeviceState
*
dev
,
const
char
*
name
,
DriveInfo
*
value
)
{
qdev_prop_set
(
dev
,
name
,
&
value
,
PROP_TYPE_DRIVE
);
...
...
hw/qdev.c
浏览文件 @
a4673e27
...
...
@@ -334,6 +334,7 @@ void qdev_init_nofail(DeviceState *dev)
void
qdev_free
(
DeviceState
*
dev
)
{
BusState
*
bus
;
Property
*
prop
;
if
(
dev
->
state
==
DEV_STATE_INITIALIZED
)
{
while
(
dev
->
num_child_bus
)
{
...
...
@@ -349,6 +350,11 @@ void qdev_free(DeviceState *dev)
}
qemu_unregister_reset
(
qdev_reset
,
dev
);
QLIST_REMOVE
(
dev
,
sibling
);
for
(
prop
=
dev
->
info
->
props
;
prop
&&
prop
->
name
;
prop
++
)
{
if
(
prop
->
info
->
free
)
{
prop
->
info
->
free
(
dev
,
prop
);
}
}
qemu_free
(
dev
);
}
...
...
hw/qdev.h
浏览文件 @
a4673e27
...
...
@@ -2,7 +2,7 @@
#define QDEV_H
#include "hw.h"
#include "
sysemu
.h"
#include "
blockdev
.h"
#include "qemu-queue.h"
#include "qemu-char.h"
#include "qemu-option.h"
...
...
@@ -98,6 +98,7 @@ struct PropertyInfo {
enum
PropertyType
type
;
int
(
*
parse
)(
DeviceState
*
dev
,
Property
*
prop
,
const
char
*
str
);
int
(
*
print
)(
DeviceState
*
dev
,
Property
*
prop
,
char
*
dest
,
size_t
len
);
void
(
*
free
)(
DeviceState
*
dev
,
Property
*
prop
);
};
typedef
struct
GlobalProperty
{
...
...
@@ -124,6 +125,8 @@ void qdev_machine_creation_done(void);
qemu_irq
qdev_get_gpio_in
(
DeviceState
*
dev
,
int
n
);
void
qdev_connect_gpio_out
(
DeviceState
*
dev
,
int
n
,
qemu_irq
pin
);
BlockDriverState
*
qdev_init_bdrv
(
DeviceState
*
dev
,
BlockInterfaceType
type
);
BusState
*
qdev_get_child_bus
(
DeviceState
*
dev
,
const
char
*
name
);
/*** Device API. ***/
...
...
@@ -268,6 +271,7 @@ void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value);
void
qdev_prop_set_uint32
(
DeviceState
*
dev
,
const
char
*
name
,
uint32_t
value
);
void
qdev_prop_set_int32
(
DeviceState
*
dev
,
const
char
*
name
,
int32_t
value
);
void
qdev_prop_set_uint64
(
DeviceState
*
dev
,
const
char
*
name
,
uint64_t
value
);
void
qdev_prop_set_string
(
DeviceState
*
dev
,
const
char
*
name
,
char
*
value
);
void
qdev_prop_set_chr
(
DeviceState
*
dev
,
const
char
*
name
,
CharDriverState
*
value
);
void
qdev_prop_set_netdev
(
DeviceState
*
dev
,
const
char
*
name
,
VLANClientState
*
value
);
void
qdev_prop_set_vlan
(
DeviceState
*
dev
,
const
char
*
name
,
VLANState
*
value
);
...
...
hw/scsi-bus.c
浏览文件 @
a4673e27
...
...
@@ -2,7 +2,6 @@
#include "qemu-error.h"
#include "scsi.h"
#include "scsi-defs.h"
#include "block.h"
#include "qdev.h"
static
struct
BusInfo
scsi_bus_info
=
{
...
...
hw/scsi-disk.c
浏览文件 @
a4673e27
...
...
@@ -33,9 +33,9 @@ do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
#include "qemu-common.h"
#include "qemu-error.h"
#include "block.h"
#include "scsi.h"
#include "scsi-defs.h"
#include "sysemu.h"
#define SCSI_DMA_BUF_SIZE 131072
#define SCSI_MAX_INQUIRY_LEN 256
...
...
@@ -66,6 +66,7 @@ struct SCSIDiskState
uint64_t
max_lba
;
QEMUBH
*
bh
;
char
*
version
;
char
*
serial
;
};
static
SCSIDiskReq
*
scsi_new_request
(
SCSIDevice
*
d
,
uint32_t
tag
,
uint32_t
lun
)
...
...
@@ -359,9 +360,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
case
0x80
:
/* Device serial number, optional */
{
const
char
*
serial
=
req
->
dev
->
conf
.
dinfo
->
serial
?
req
->
dev
->
conf
.
dinfo
->
serial
:
"0"
;
int
l
=
strlen
(
serial
);
int
l
=
strlen
(
s
->
serial
);
if
(
l
>
req
->
cmd
.
xfer
)
l
=
req
->
cmd
.
xfer
;
...
...
@@ -371,7 +370,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
DPRINTF
(
"Inquiry EVPD[Serial number] "
"buffer size %zd
\n
"
,
req
->
cmd
.
xfer
);
outbuf
[
buflen
++
]
=
l
;
memcpy
(
outbuf
+
buflen
,
serial
,
l
);
memcpy
(
outbuf
+
buflen
,
s
->
s
erial
,
l
);
buflen
+=
l
;
break
;
}
...
...
@@ -463,8 +462,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
}
memcpy
(
&
outbuf
[
8
],
"QEMU "
,
8
);
memset
(
&
outbuf
[
32
],
0
,
4
);
memcpy
(
&
outbuf
[
32
],
s
->
version
?
s
->
version
:
QEMU_VERSION
,
MIN
(
4
,
strlen
(
s
->
version
?
s
->
version
:
QEMU_VERSION
)));
memcpy
(
&
outbuf
[
32
],
s
->
version
,
MIN
(
4
,
strlen
(
s
->
version
)));
/*
* We claim conformance to SPC-3, which is required for guests
* to ask for modern features like READ CAPACITY(16) or the
...
...
@@ -1058,6 +1056,19 @@ static int scsi_disk_initfn(SCSIDevice *dev)
}
s
->
bs
=
s
->
qdev
.
conf
.
dinfo
->
bdrv
;
if
(
!
s
->
serial
)
{
if
(
*
dev
->
conf
.
dinfo
->
serial
)
{
/* try to fall back to value set with legacy -drive serial=... */
s
->
serial
=
qemu_strdup
(
dev
->
conf
.
dinfo
->
serial
);
}
else
{
s
->
serial
=
qemu_strdup
(
"0"
);
}
}
if
(
!
s
->
version
)
{
s
->
version
=
qemu_strdup
(
QEMU_VERSION
);
}
if
(
bdrv_is_sg
(
s
->
bs
))
{
error_report
(
"scsi-disk: unwanted /dev/sg*"
);
return
-
1
;
...
...
@@ -1090,6 +1101,7 @@ static SCSIDeviceInfo scsi_disk_info = {
.
qdev
.
props
=
(
Property
[])
{
DEFINE_BLOCK_PROPERTIES
(
SCSIDiskState
,
qdev
.
conf
),
DEFINE_PROP_STRING
(
"ver"
,
SCSIDiskState
,
version
),
DEFINE_PROP_STRING
(
"serial"
,
SCSIDiskState
,
serial
),
DEFINE_PROP_END_OF_LIST
(),
},
};
...
...
hw/scsi-generic.c
浏览文件 @
a4673e27
...
...
@@ -13,7 +13,6 @@
#include "qemu-common.h"
#include "qemu-error.h"
#include "block.h"
#include "scsi.h"
#ifdef __linux__
...
...
hw/serial.c
浏览文件 @
a4673e27
...
...
@@ -27,6 +27,7 @@
#include "isa.h"
#include "pc.h"
#include "qemu-timer.h"
#include "sysemu.h"
//#define DEBUG_SERIAL
...
...
hw/ssi-sd.c
浏览文件 @
a4673e27
...
...
@@ -9,7 +9,6 @@
#include "ssi.h"
#include "sd.h"
#include "sysemu.h"
//#define DEBUG_SSI_SD 1
...
...
hw/usb-hid.c
浏览文件 @
a4673e27
...
...
@@ -25,6 +25,7 @@
#include "hw.h"
#include "console.h"
#include "usb.h"
#include "sysemu.h"
/* HID interface requests */
#define GET_REPORT 0xa101
...
...
hw/usb-msd.c
浏览文件 @
a4673e27
...
...
@@ -11,10 +11,10 @@
#include "qemu-option.h"
#include "qemu-config.h"
#include "usb.h"
#include "block.h"
#include "scsi.h"
#include "console.h"
#include "monitor.h"
#include "sysemu.h"
//#define DEBUG_MSD
...
...
@@ -584,7 +584,7 @@ static USBDevice *usb_msd_init(const char *filename)
qemu_opt_set
(
opts
,
"if"
,
"none"
);
/* create host drive */
dinfo
=
drive_init
(
opts
,
NULL
,
&
fatal_error
);
dinfo
=
drive_init
(
opts
,
0
,
&
fatal_error
);
if
(
!
dinfo
)
{
qemu_opts_del
(
opts
);
return
NULL
;
...
...
hw/virtio-blk.c
浏览文件 @
a4673e27
...
...
@@ -12,9 +12,7 @@
*/
#include <qemu-common.h>
#include <sysemu.h>
#include "virtio-blk.h"
#include "block_int.h"
#ifdef __linux__
# include <scsi/sg.h>
#endif
...
...
@@ -277,7 +275,7 @@ static void virtio_blk_handle_write(BlockRequest *blkreq, int *num_writes,
}
blkreq
[
*
num_writes
].
sector
=
req
->
out
->
sector
;
blkreq
[
*
num_writes
].
nb_sectors
=
req
->
qiov
.
size
/
512
;
blkreq
[
*
num_writes
].
nb_sectors
=
req
->
qiov
.
size
/
BDRV_SECTOR_SIZE
;
blkreq
[
*
num_writes
].
qiov
=
&
req
->
qiov
;
blkreq
[
*
num_writes
].
cb
=
virtio_blk_rw_complete
;
blkreq
[
*
num_writes
].
opaque
=
req
;
...
...
@@ -296,7 +294,8 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
}
acb
=
bdrv_aio_readv
(
req
->
dev
->
bs
,
req
->
out
->
sector
,
&
req
->
qiov
,
req
->
qiov
.
size
/
512
,
virtio_blk_rw_complete
,
req
);
req
->
qiov
.
size
/
BDRV_SECTOR_SIZE
,
virtio_blk_rw_complete
,
req
);
if
(
!
acb
)
{
virtio_blk_rw_complete
(
req
,
-
EIO
);
}
...
...
@@ -505,7 +504,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
s
->
bs
=
conf
->
dinfo
->
bdrv
;
s
->
conf
=
conf
;
s
->
rq
=
NULL
;
s
->
sector_mask
=
(
s
->
conf
->
logical_block_size
/
512
)
-
1
;
s
->
sector_mask
=
(
s
->
conf
->
logical_block_size
/
BDRV_SECTOR_SIZE
)
-
1
;
bdrv_guess_geometry
(
s
->
bs
,
&
cylinders
,
&
heads
,
&
secs
);
s
->
vq
=
virtio_add_queue
(
&
s
->
vdev
,
128
,
virtio_blk_handle_output
);
...
...
hw/virtio-pci.c
浏览文件 @
a4673e27
...
...
@@ -22,7 +22,6 @@
#include "qemu-error.h"
#include "msix.h"
#include "net.h"
#include "block_int.h"
#include "loader.h"
#include "kvm.h"
...
...
monitor.c
浏览文件 @
a4673e27
...
...
@@ -38,7 +38,7 @@
#include "monitor.h"
#include "readline.h"
#include "console.h"
#include "block.h"
#include "block
dev
.h"
#include "audio/audio.h"
#include "disas.h"
#include "balloon.h"
...
...
@@ -530,21 +530,6 @@ static void do_help_cmd(Monitor *mon, const QDict *qdict)
help_cmd
(
mon
,
qdict_get_try_str
(
qdict
,
"name"
));
}
static
void
do_commit
(
Monitor
*
mon
,
const
QDict
*
qdict
)
{
int
all_devices
;
DriveInfo
*
dinfo
;
const
char
*
device
=
qdict_get_str
(
qdict
,
"device"
);
all_devices
=
!
strcmp
(
device
,
"all"
);
QTAILQ_FOREACH
(
dinfo
,
&
drives
,
next
)
{
if
(
!
all_devices
)
if
(
strcmp
(
bdrv_get_device_name
(
dinfo
->
bdrv
),
device
))
continue
;
bdrv_commit
(
dinfo
->
bdrv
);
}
}
static
void
user_monitor_complete
(
void
*
opaque
,
QObject
*
ret_data
)
{
MonitorCompletionData
*
data
=
(
MonitorCompletionData
*
)
opaque
;
...
...
@@ -935,93 +920,6 @@ static int do_quit(Monitor *mon, const QDict *qdict, QObject **ret_data)
return
0
;
}
static
int
eject_device
(
Monitor
*
mon
,
BlockDriverState
*
bs
,
int
force
)
{
if
(
bdrv_is_inserted
(
bs
))
{
if
(
!
force
)
{
if
(
!
bdrv_is_removable
(
bs
))
{
qerror_report
(
QERR_DEVICE_NOT_REMOVABLE
,
bdrv_get_device_name
(
bs
));
return
-
1
;
}
if
(
bdrv_is_locked
(
bs
))
{
qerror_report
(
QERR_DEVICE_LOCKED
,
bdrv_get_device_name
(
bs
));
return
-
1
;
}
}
bdrv_close
(
bs
);
}
return
0
;
}
static
int
do_eject
(
Monitor
*
mon
,
const
QDict
*
qdict
,
QObject
**
ret_data
)
{
BlockDriverState
*
bs
;
int
force
=
qdict_get_int
(
qdict
,
"force"
);
const
char
*
filename
=
qdict_get_str
(
qdict
,
"device"
);
bs
=
bdrv_find
(
filename
);
if
(
!
bs
)
{
qerror_report
(
QERR_DEVICE_NOT_FOUND
,
filename
);
return
-
1
;
}
return
eject_device
(
mon
,
bs
,
force
);
}
static
int
do_block_set_passwd
(
Monitor
*
mon
,
const
QDict
*
qdict
,
QObject
**
ret_data
)
{
BlockDriverState
*
bs
;
int
err
;
bs
=
bdrv_find
(
qdict_get_str
(
qdict
,
"device"
));
if
(
!
bs
)
{
qerror_report
(
QERR_DEVICE_NOT_FOUND
,
qdict_get_str
(
qdict
,
"device"
));
return
-
1
;
}
err
=
bdrv_set_key
(
bs
,
qdict_get_str
(
qdict
,
"password"
));
if
(
err
==
-
EINVAL
)
{
qerror_report
(
QERR_DEVICE_NOT_ENCRYPTED
,
bdrv_get_device_name
(
bs
));
return
-
1
;
}
else
if
(
err
<
0
)
{
qerror_report
(
QERR_INVALID_PASSWORD
);
return
-
1
;
}
return
0
;
}
static
int
do_change_block
(
Monitor
*
mon
,
const
char
*
device
,
const
char
*
filename
,
const
char
*
fmt
)
{
BlockDriverState
*
bs
;
BlockDriver
*
drv
=
NULL
;
int
bdrv_flags
;
bs
=
bdrv_find
(
device
);
if
(
!
bs
)
{
qerror_report
(
QERR_DEVICE_NOT_FOUND
,
device
);
return
-
1
;
}
if
(
fmt
)
{
drv
=
bdrv_find_whitelisted_format
(
fmt
);
if
(
!
drv
)
{
qerror_report
(
QERR_INVALID_BLOCK_FORMAT
,
fmt
);
return
-
1
;
}
}
if
(
eject_device
(
mon
,
bs
,
0
)
<
0
)
{
return
-
1
;
}
bdrv_flags
=
bdrv_get_type_hint
(
bs
)
==
BDRV_TYPE_CDROM
?
0
:
BDRV_O_RDWR
;
if
(
bdrv_open
(
bs
,
filename
,
bdrv_flags
,
drv
)
<
0
)
{
qerror_report
(
QERR_OPEN_FILE_FAILED
,
filename
);
return
-
1
;
}
return
monitor_read_bdrv_key_start
(
mon
,
bs
,
NULL
,
NULL
);
}
static
int
change_vnc_password
(
const
char
*
password
)
{
if
(
vnc_display_password
(
NULL
,
password
)
<
0
)
{
...
...
qemu-char.c
浏览文件 @
a4673e27
...
...
@@ -28,7 +28,6 @@
#include "sysemu.h"
#include "qemu-timer.h"
#include "qemu-char.h"
#include "block.h"
#include "hw/usb.h"
#include "hw/baum.h"
#include "hw/msmouse.h"
...
...
qemu-io.c
浏览文件 @
a4673e27
...
...
@@ -1317,7 +1317,7 @@ truncate_f(int argc, char **argv)
ret
=
bdrv_truncate
(
bs
,
offset
);
if
(
ret
<
0
)
{
printf
(
"truncate: %s
"
,
strerror
(
ret
));
printf
(
"truncate: %s
\n
"
,
strerror
(
-
ret
));
return
0
;
}
...
...
@@ -1342,7 +1342,7 @@ length_f(int argc, char **argv)
size
=
bdrv_getlength
(
bs
);
if
(
size
<
0
)
{
printf
(
"getlength: %s
"
,
strerror
(
size
));
printf
(
"getlength: %s
\n
"
,
strerror
(
-
size
));
return
0
;
}
...
...
savevm.c
浏览文件 @
a4673e27
...
...
@@ -77,7 +77,7 @@
#include "sysemu.h"
#include "qemu-timer.h"
#include "qemu-char.h"
#include "block.h"
#include "block
dev
.h"
#include "audio/audio.h"
#include "migration.h"
#include "qemu_socket.h"
...
...
sysemu.h
浏览文件 @
a4673e27
...
...
@@ -142,58 +142,6 @@ extern int nb_option_roms;
extern
const
char
*
prom_envs
[
MAX_PROM_ENVS
];
extern
unsigned
int
nb_prom_envs
;
typedef
enum
{
IF_NONE
,
IF_IDE
,
IF_SCSI
,
IF_FLOPPY
,
IF_PFLASH
,
IF_MTD
,
IF_SD
,
IF_VIRTIO
,
IF_XEN
,
IF_COUNT
}
BlockInterfaceType
;
typedef
enum
{
BLOCK_ERR_REPORT
,
BLOCK_ERR_IGNORE
,
BLOCK_ERR_STOP_ENOSPC
,
BLOCK_ERR_STOP_ANY
}
BlockInterfaceErrorAction
;
#define BLOCK_SERIAL_STRLEN 20
typedef
struct
DriveInfo
{
BlockDriverState
*
bdrv
;
char
*
id
;
const
char
*
devaddr
;
BlockInterfaceType
type
;
int
bus
;
int
unit
;
QemuOpts
*
opts
;
BlockInterfaceErrorAction
on_read_error
;
BlockInterfaceErrorAction
on_write_error
;
char
serial
[
BLOCK_SERIAL_STRLEN
+
1
];
QTAILQ_ENTRY
(
DriveInfo
)
next
;
}
DriveInfo
;
#define MAX_IDE_DEVS 2
#define MAX_SCSI_DEVS 7
#define MAX_DRIVES 32
extern
QTAILQ_HEAD
(
drivelist
,
DriveInfo
)
drives
;
extern
QTAILQ_HEAD
(
driveoptlist
,
DriveOpt
)
driveopts
;
extern
DriveInfo
*
drive_get
(
BlockInterfaceType
type
,
int
bus
,
int
unit
);
extern
DriveInfo
*
drive_get_by_id
(
const
char
*
id
);
extern
int
drive_get_max_bus
(
BlockInterfaceType
type
);
extern
void
drive_uninit
(
DriveInfo
*
dinfo
);
extern
const
char
*
drive_get_serial
(
BlockDriverState
*
bdrv
);
extern
BlockInterfaceErrorAction
drive_get_on_error
(
BlockDriverState
*
bdrv
,
int
is_read
);
BlockDriverState
*
qdev_init_bdrv
(
DeviceState
*
dev
,
BlockInterfaceType
type
);
extern
QemuOpts
*
drive_add
(
const
char
*
file
,
const
char
*
fmt
,
...);
extern
DriveInfo
*
drive_init
(
QemuOpts
*
arg
,
void
*
machine
,
int
*
fatal_error
);
/* device-hotplug */
DriveInfo
*
add_init_drive
(
const
char
*
opts
);
/* pci-hotplug */
void
pci_device_hot_add
(
Monitor
*
mon
,
const
QDict
*
qdict
);
void
drive_hot_add
(
Monitor
*
mon
,
const
QDict
*
qdict
);
...
...
vl.c
浏览文件 @
a4673e27
...
...
@@ -137,7 +137,7 @@ int main(int argc, char **argv)
#include "qemu-char.h"
#include "cache-utils.h"
#include "block.h"
#include "block
_int
.h"
#include "block
dev
.h"
#include "block-migration.h"
#include "dma.h"
#include "audio/audio.h"
...
...
@@ -170,10 +170,6 @@ int main(int argc, char **argv)
static
const
char
*
data_dir
;
const
char
*
bios_name
=
NULL
;
/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
to store the VM snapshots */
struct
drivelist
drives
=
QTAILQ_HEAD_INITIALIZER
(
drives
);
struct
driveoptlist
driveopts
=
QTAILQ_HEAD_INITIALIZER
(
driveopts
);
enum
vga_retrace_method
vga_retrace_method
=
VGA_RETRACE_DUMB
;
DisplayType
display_type
=
DT_DEFAULT
;
const
char
*
keyboard_layout
=
NULL
;
...
...
@@ -633,492 +629,12 @@ static int bt_parse(const char *opt)
#define MTD_ALIAS "if=mtd"
#define SD_ALIAS "index=0,if=sd"
QemuOpts
*
drive_add
(
const
char
*
file
,
const
char
*
fmt
,
...)
{
va_list
ap
;
char
optstr
[
1024
];
QemuOpts
*
opts
;
va_start
(
ap
,
fmt
);
vsnprintf
(
optstr
,
sizeof
(
optstr
),
fmt
,
ap
);
va_end
(
ap
);
opts
=
qemu_opts_parse
(
&
qemu_drive_opts
,
optstr
,
0
);
if
(
!
opts
)
{
return
NULL
;
}
if
(
file
)
qemu_opt_set
(
opts
,
"file"
,
file
);
return
opts
;
}
DriveInfo
*
drive_get
(
BlockInterfaceType
type
,
int
bus
,
int
unit
)
{
DriveInfo
*
dinfo
;
/* seek interface, bus and unit */
QTAILQ_FOREACH
(
dinfo
,
&
drives
,
next
)
{
if
(
dinfo
->
type
==
type
&&
dinfo
->
bus
==
bus
&&
dinfo
->
unit
==
unit
)
return
dinfo
;
}
return
NULL
;
}
DriveInfo
*
drive_get_by_id
(
const
char
*
id
)
{
DriveInfo
*
dinfo
;
QTAILQ_FOREACH
(
dinfo
,
&
drives
,
next
)
{
if
(
strcmp
(
id
,
dinfo
->
id
))
continue
;
return
dinfo
;
}
return
NULL
;
}
int
drive_get_max_bus
(
BlockInterfaceType
type
)
{
int
max_bus
;
DriveInfo
*
dinfo
;
max_bus
=
-
1
;
QTAILQ_FOREACH
(
dinfo
,
&
drives
,
next
)
{
if
(
dinfo
->
type
==
type
&&
dinfo
->
bus
>
max_bus
)
max_bus
=
dinfo
->
bus
;
}
return
max_bus
;
}
const
char
*
drive_get_serial
(
BlockDriverState
*
bdrv
)
{
DriveInfo
*
dinfo
;
QTAILQ_FOREACH
(
dinfo
,
&
drives
,
next
)
{
if
(
dinfo
->
bdrv
==
bdrv
)
return
dinfo
->
serial
;
}
return
"
\0
"
;
}
BlockInterfaceErrorAction
drive_get_on_error
(
BlockDriverState
*
bdrv
,
int
is_read
)
{
DriveInfo
*
dinfo
;
QTAILQ_FOREACH
(
dinfo
,
&
drives
,
next
)
{
if
(
dinfo
->
bdrv
==
bdrv
)
return
is_read
?
dinfo
->
on_read_error
:
dinfo
->
on_write_error
;
}
return
is_read
?
BLOCK_ERR_REPORT
:
BLOCK_ERR_STOP_ENOSPC
;
}
static
void
bdrv_format_print
(
void
*
opaque
,
const
char
*
name
)
{
fprintf
(
stderr
,
" %s"
,
name
);
}
void
drive_uninit
(
DriveInfo
*
dinfo
)
{
qemu_opts_del
(
dinfo
->
opts
);
bdrv_delete
(
dinfo
->
bdrv
);
QTAILQ_REMOVE
(
&
drives
,
dinfo
,
next
);
qemu_free
(
dinfo
);
}
static
int
parse_block_error_action
(
const
char
*
buf
,
int
is_read
)
{
if
(
!
strcmp
(
buf
,
"ignore"
))
{
return
BLOCK_ERR_IGNORE
;
}
else
if
(
!
is_read
&&
!
strcmp
(
buf
,
"enospc"
))
{
return
BLOCK_ERR_STOP_ENOSPC
;
}
else
if
(
!
strcmp
(
buf
,
"stop"
))
{
return
BLOCK_ERR_STOP_ANY
;
}
else
if
(
!
strcmp
(
buf
,
"report"
))
{
return
BLOCK_ERR_REPORT
;
}
else
{
fprintf
(
stderr
,
"qemu: '%s' invalid %s error action
\n
"
,
buf
,
is_read
?
"read"
:
"write"
);
return
-
1
;
}
}
DriveInfo
*
drive_init
(
QemuOpts
*
opts
,
void
*
opaque
,
int
*
fatal_error
)
{
const
char
*
buf
;
const
char
*
file
=
NULL
;
char
devname
[
128
];
const
char
*
serial
;
const
char
*
mediastr
=
""
;
BlockInterfaceType
type
;
enum
{
MEDIA_DISK
,
MEDIA_CDROM
}
media
;
int
bus_id
,
unit_id
;
int
cyls
,
heads
,
secs
,
translation
;
BlockDriver
*
drv
=
NULL
;
QEMUMachine
*
machine
=
opaque
;
int
max_devs
;
int
index
;
int
ro
=
0
;
int
bdrv_flags
=
0
;
int
on_read_error
,
on_write_error
;
const
char
*
devaddr
;
DriveInfo
*
dinfo
;
int
snapshot
=
0
;
*
fatal_error
=
1
;
translation
=
BIOS_ATA_TRANSLATION_AUTO
;
if
(
machine
&&
machine
->
use_scsi
)
{
type
=
IF_SCSI
;
max_devs
=
MAX_SCSI_DEVS
;
pstrcpy
(
devname
,
sizeof
(
devname
),
"scsi"
);
}
else
{
type
=
IF_IDE
;
max_devs
=
MAX_IDE_DEVS
;
pstrcpy
(
devname
,
sizeof
(
devname
),
"ide"
);
}
media
=
MEDIA_DISK
;
/* extract parameters */
bus_id
=
qemu_opt_get_number
(
opts
,
"bus"
,
0
);
unit_id
=
qemu_opt_get_number
(
opts
,
"unit"
,
-
1
);
index
=
qemu_opt_get_number
(
opts
,
"index"
,
-
1
);
cyls
=
qemu_opt_get_number
(
opts
,
"cyls"
,
0
);
heads
=
qemu_opt_get_number
(
opts
,
"heads"
,
0
);
secs
=
qemu_opt_get_number
(
opts
,
"secs"
,
0
);
snapshot
=
qemu_opt_get_bool
(
opts
,
"snapshot"
,
0
);
ro
=
qemu_opt_get_bool
(
opts
,
"readonly"
,
0
);
file
=
qemu_opt_get
(
opts
,
"file"
);
serial
=
qemu_opt_get
(
opts
,
"serial"
);
if
((
buf
=
qemu_opt_get
(
opts
,
"if"
))
!=
NULL
)
{
pstrcpy
(
devname
,
sizeof
(
devname
),
buf
);
if
(
!
strcmp
(
buf
,
"ide"
))
{
type
=
IF_IDE
;
max_devs
=
MAX_IDE_DEVS
;
}
else
if
(
!
strcmp
(
buf
,
"scsi"
))
{
type
=
IF_SCSI
;
max_devs
=
MAX_SCSI_DEVS
;
}
else
if
(
!
strcmp
(
buf
,
"floppy"
))
{
type
=
IF_FLOPPY
;
max_devs
=
0
;
}
else
if
(
!
strcmp
(
buf
,
"pflash"
))
{
type
=
IF_PFLASH
;
max_devs
=
0
;
}
else
if
(
!
strcmp
(
buf
,
"mtd"
))
{
type
=
IF_MTD
;
max_devs
=
0
;
}
else
if
(
!
strcmp
(
buf
,
"sd"
))
{
type
=
IF_SD
;
max_devs
=
0
;
}
else
if
(
!
strcmp
(
buf
,
"virtio"
))
{
type
=
IF_VIRTIO
;
max_devs
=
0
;
}
else
if
(
!
strcmp
(
buf
,
"xen"
))
{
type
=
IF_XEN
;
max_devs
=
0
;
}
else
if
(
!
strcmp
(
buf
,
"none"
))
{
type
=
IF_NONE
;
max_devs
=
0
;
}
else
{
fprintf
(
stderr
,
"qemu: unsupported bus type '%s'
\n
"
,
buf
);
return
NULL
;
}
}
if
(
cyls
||
heads
||
secs
)
{
if
(
cyls
<
1
||
(
type
==
IF_IDE
&&
cyls
>
16383
))
{
fprintf
(
stderr
,
"qemu: '%s' invalid physical cyls number
\n
"
,
buf
);
return
NULL
;
}
if
(
heads
<
1
||
(
type
==
IF_IDE
&&
heads
>
16
))
{
fprintf
(
stderr
,
"qemu: '%s' invalid physical heads number
\n
"
,
buf
);
return
NULL
;
}
if
(
secs
<
1
||
(
type
==
IF_IDE
&&
secs
>
63
))
{
fprintf
(
stderr
,
"qemu: '%s' invalid physical secs number
\n
"
,
buf
);
return
NULL
;
}
}
if
((
buf
=
qemu_opt_get
(
opts
,
"trans"
))
!=
NULL
)
{
if
(
!
cyls
)
{
fprintf
(
stderr
,
"qemu: '%s' trans must be used with cyls,heads and secs
\n
"
,
buf
);
return
NULL
;
}
if
(
!
strcmp
(
buf
,
"none"
))
translation
=
BIOS_ATA_TRANSLATION_NONE
;
else
if
(
!
strcmp
(
buf
,
"lba"
))
translation
=
BIOS_ATA_TRANSLATION_LBA
;
else
if
(
!
strcmp
(
buf
,
"auto"
))
translation
=
BIOS_ATA_TRANSLATION_AUTO
;
else
{
fprintf
(
stderr
,
"qemu: '%s' invalid translation type
\n
"
,
buf
);
return
NULL
;
}
}
if
((
buf
=
qemu_opt_get
(
opts
,
"media"
))
!=
NULL
)
{
if
(
!
strcmp
(
buf
,
"disk"
))
{
media
=
MEDIA_DISK
;
}
else
if
(
!
strcmp
(
buf
,
"cdrom"
))
{
if
(
cyls
||
secs
||
heads
)
{
fprintf
(
stderr
,
"qemu: '%s' invalid physical CHS format
\n
"
,
buf
);
return
NULL
;
}
media
=
MEDIA_CDROM
;
}
else
{
fprintf
(
stderr
,
"qemu: '%s' invalid media
\n
"
,
buf
);
return
NULL
;
}
}
if
((
buf
=
qemu_opt_get
(
opts
,
"cache"
))
!=
NULL
)
{
if
(
!
strcmp
(
buf
,
"off"
)
||
!
strcmp
(
buf
,
"none"
))
{
bdrv_flags
|=
BDRV_O_NOCACHE
;
}
else
if
(
!
strcmp
(
buf
,
"writeback"
))
{
bdrv_flags
|=
BDRV_O_CACHE_WB
;
}
else
if
(
!
strcmp
(
buf
,
"unsafe"
))
{
bdrv_flags
|=
BDRV_O_CACHE_WB
;
bdrv_flags
|=
BDRV_O_NO_FLUSH
;
}
else
if
(
!
strcmp
(
buf
,
"writethrough"
))
{
/* this is the default */
}
else
{
fprintf
(
stderr
,
"qemu: invalid cache option
\n
"
);
return
NULL
;
}
}
#ifdef CONFIG_LINUX_AIO
if
((
buf
=
qemu_opt_get
(
opts
,
"aio"
))
!=
NULL
)
{
if
(
!
strcmp
(
buf
,
"native"
))
{
bdrv_flags
|=
BDRV_O_NATIVE_AIO
;
}
else
if
(
!
strcmp
(
buf
,
"threads"
))
{
/* this is the default */
}
else
{
fprintf
(
stderr
,
"qemu: invalid aio option
\n
"
);
return
NULL
;
}
}
#endif
if
((
buf
=
qemu_opt_get
(
opts
,
"format"
))
!=
NULL
)
{
if
(
strcmp
(
buf
,
"?"
)
==
0
)
{
fprintf
(
stderr
,
"qemu: Supported formats:"
);
bdrv_iterate_format
(
bdrv_format_print
,
NULL
);
fprintf
(
stderr
,
"
\n
"
);
return
NULL
;
}
drv
=
bdrv_find_whitelisted_format
(
buf
);
if
(
!
drv
)
{
fprintf
(
stderr
,
"qemu: '%s' invalid format
\n
"
,
buf
);
return
NULL
;
}
}
on_write_error
=
BLOCK_ERR_STOP_ENOSPC
;
if
((
buf
=
qemu_opt_get
(
opts
,
"werror"
))
!=
NULL
)
{
if
(
type
!=
IF_IDE
&&
type
!=
IF_SCSI
&&
type
!=
IF_VIRTIO
&&
type
!=
IF_NONE
)
{
fprintf
(
stderr
,
"werror is no supported by this format
\n
"
);
return
NULL
;
}
on_write_error
=
parse_block_error_action
(
buf
,
0
);
if
(
on_write_error
<
0
)
{
return
NULL
;
}
}
on_read_error
=
BLOCK_ERR_REPORT
;
if
((
buf
=
qemu_opt_get
(
opts
,
"rerror"
))
!=
NULL
)
{
if
(
type
!=
IF_IDE
&&
type
!=
IF_VIRTIO
&&
type
!=
IF_NONE
)
{
fprintf
(
stderr
,
"rerror is no supported by this format
\n
"
);
return
NULL
;
}
on_read_error
=
parse_block_error_action
(
buf
,
1
);
if
(
on_read_error
<
0
)
{
return
NULL
;
}
}
if
((
devaddr
=
qemu_opt_get
(
opts
,
"addr"
))
!=
NULL
)
{
if
(
type
!=
IF_VIRTIO
)
{
fprintf
(
stderr
,
"addr is not supported
\n
"
);
return
NULL
;
}
}
/* compute bus and unit according index */
if
(
index
!=
-
1
)
{
if
(
bus_id
!=
0
||
unit_id
!=
-
1
)
{
fprintf
(
stderr
,
"qemu: index cannot be used with bus and unit
\n
"
);
return
NULL
;
}
if
(
max_devs
==
0
)
{
unit_id
=
index
;
bus_id
=
0
;
}
else
{
unit_id
=
index
%
max_devs
;
bus_id
=
index
/
max_devs
;
}
}
/* if user doesn't specify a unit_id,
* try to find the first free
*/
if
(
unit_id
==
-
1
)
{
unit_id
=
0
;
while
(
drive_get
(
type
,
bus_id
,
unit_id
)
!=
NULL
)
{
unit_id
++
;
if
(
max_devs
&&
unit_id
>=
max_devs
)
{
unit_id
-=
max_devs
;
bus_id
++
;
}
}
}
/* check unit id */
if
(
max_devs
&&
unit_id
>=
max_devs
)
{
fprintf
(
stderr
,
"qemu: unit %d too big (max is %d)
\n
"
,
unit_id
,
max_devs
-
1
);
return
NULL
;
}
/*
* ignore multiple definitions
*/
if
(
drive_get
(
type
,
bus_id
,
unit_id
)
!=
NULL
)
{
*
fatal_error
=
0
;
return
NULL
;
}
/* init */
dinfo
=
qemu_mallocz
(
sizeof
(
*
dinfo
));
if
((
buf
=
qemu_opts_id
(
opts
))
!=
NULL
)
{
dinfo
->
id
=
qemu_strdup
(
buf
);
}
else
{
/* no id supplied -> create one */
dinfo
->
id
=
qemu_mallocz
(
32
);
if
(
type
==
IF_IDE
||
type
==
IF_SCSI
)
mediastr
=
(
media
==
MEDIA_CDROM
)
?
"-cd"
:
"-hd"
;
if
(
max_devs
)
snprintf
(
dinfo
->
id
,
32
,
"%s%i%s%i"
,
devname
,
bus_id
,
mediastr
,
unit_id
);
else
snprintf
(
dinfo
->
id
,
32
,
"%s%s%i"
,
devname
,
mediastr
,
unit_id
);
}
dinfo
->
bdrv
=
bdrv_new
(
dinfo
->
id
);
dinfo
->
devaddr
=
devaddr
;
dinfo
->
type
=
type
;
dinfo
->
bus
=
bus_id
;
dinfo
->
unit
=
unit_id
;
dinfo
->
on_read_error
=
on_read_error
;
dinfo
->
on_write_error
=
on_write_error
;
dinfo
->
opts
=
opts
;
if
(
serial
)
strncpy
(
dinfo
->
serial
,
serial
,
sizeof
(
serial
));
QTAILQ_INSERT_TAIL
(
&
drives
,
dinfo
,
next
);
switch
(
type
)
{
case
IF_IDE
:
case
IF_SCSI
:
case
IF_XEN
:
case
IF_NONE
:
switch
(
media
)
{
case
MEDIA_DISK
:
if
(
cyls
!=
0
)
{
bdrv_set_geometry_hint
(
dinfo
->
bdrv
,
cyls
,
heads
,
secs
);
bdrv_set_translation_hint
(
dinfo
->
bdrv
,
translation
);
}
break
;
case
MEDIA_CDROM
:
bdrv_set_type_hint
(
dinfo
->
bdrv
,
BDRV_TYPE_CDROM
);
break
;
}
break
;
case
IF_SD
:
/* FIXME: This isn't really a floppy, but it's a reasonable
approximation. */
case
IF_FLOPPY
:
bdrv_set_type_hint
(
dinfo
->
bdrv
,
BDRV_TYPE_FLOPPY
);
break
;
case
IF_PFLASH
:
case
IF_MTD
:
break
;
case
IF_VIRTIO
:
/* add virtio block device */
opts
=
qemu_opts_create
(
&
qemu_device_opts
,
NULL
,
0
);
qemu_opt_set
(
opts
,
"driver"
,
"virtio-blk-pci"
);
qemu_opt_set
(
opts
,
"drive"
,
dinfo
->
id
);
if
(
devaddr
)
qemu_opt_set
(
opts
,
"addr"
,
devaddr
);
break
;
case
IF_COUNT
:
abort
();
}
if
(
!
file
)
{
*
fatal_error
=
0
;
return
NULL
;
}
if
(
snapshot
)
{
/* always use cache=unsafe with snapshot */
bdrv_flags
&=
~
BDRV_O_CACHE_MASK
;
bdrv_flags
|=
(
BDRV_O_SNAPSHOT
|
BDRV_O_CACHE_WB
|
BDRV_O_NO_FLUSH
);
}
if
(
media
==
MEDIA_CDROM
)
{
/* CDROM is fine for any interface, don't check. */
ro
=
1
;
}
else
if
(
ro
==
1
)
{
if
(
type
!=
IF_SCSI
&&
type
!=
IF_VIRTIO
&&
type
!=
IF_FLOPPY
&&
type
!=
IF_NONE
)
{
fprintf
(
stderr
,
"qemu: readonly flag not supported for drive with this interface
\n
"
);
return
NULL
;
}
}
bdrv_flags
|=
ro
?
0
:
BDRV_O_RDWR
;
if
(
bdrv_open
(
dinfo
->
bdrv
,
file
,
bdrv_flags
,
drv
)
<
0
)
{
fprintf
(
stderr
,
"qemu: could not open disk image %s: %s
\n
"
,
file
,
strerror
(
errno
));
return
NULL
;
}
if
(
bdrv_key_required
(
dinfo
->
bdrv
))
autostart
=
0
;
*
fatal_error
=
0
;
return
dinfo
;
}
static
int
drive_init_func
(
QemuOpts
*
opts
,
void
*
opaque
)
{
QEMUMachine
*
machine
=
opaque
;
int
*
use_scsi
=
opaque
;
int
fatal_error
=
0
;
if
(
drive_init
(
opts
,
machine
,
&
fatal_error
)
==
NULL
)
{
if
(
drive_init
(
opts
,
*
use_scsi
,
&
fatal_error
)
==
NULL
)
{
if
(
fatal_error
)
return
1
;
}
...
...
@@ -1297,7 +813,7 @@ static void smp_parse(const char *optarg)
/***********************************************************/
/* USB devices */
static
int
usb_device_add
(
const
char
*
devname
,
int
is_hotplug
)
static
int
usb_device_add
(
const
char
*
devname
)
{
const
char
*
p
;
USBDevice
*
dev
=
NULL
;
...
...
@@ -1349,7 +865,7 @@ static int usb_device_del(const char *devname)
static
int
usb_parse
(
const
char
*
cmdline
)
{
int
r
;
r
=
usb_device_add
(
cmdline
,
0
);
r
=
usb_device_add
(
cmdline
);
if
(
r
<
0
)
{
fprintf
(
stderr
,
"qemu: could not add USB device '%s'
\n
"
,
cmdline
);
}
...
...
@@ -1359,7 +875,7 @@ static int usb_parse(const char *cmdline)
void
do_usb_add
(
Monitor
*
mon
,
const
QDict
*
qdict
)
{
const
char
*
devname
=
qdict_get_str
(
qdict
,
"devname"
);
if
(
usb_device_add
(
devname
,
1
)
<
0
)
{
if
(
usb_device_add
(
devname
)
<
0
)
{
error_report
(
"could not add USB device '%s'"
,
devname
);
}
}
...
...
@@ -1841,6 +1357,7 @@ static void main_loop(void)
vm_stop
(
r
);
}
}
bdrv_close_all
();
pause_all_vcpus
();
}
...
...
@@ -3243,7 +2760,7 @@ int main(int argc, char **argv, char **envp)
/* open the virtual block devices */
if
(
snapshot
)
qemu_opts_foreach
(
&
qemu_drive_opts
,
drive_enable_snapshot
,
NULL
,
0
);
if
(
qemu_opts_foreach
(
&
qemu_drive_opts
,
drive_init_func
,
machine
,
1
)
!=
0
)
if
(
qemu_opts_foreach
(
&
qemu_drive_opts
,
drive_init_func
,
&
machine
->
use_scsi
,
1
)
!=
0
)
exit
(
1
);
register_savevm_live
(
"ram"
,
0
,
3
,
NULL
,
ram_save_live
,
NULL
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录