Compare commits
69 Commits
qemu-sparc
...
opensuse-2
Author | SHA1 | Date | |
---|---|---|---|
|
265aa090c4 | ||
|
b7f162a686 | ||
|
491b61b48c | ||
|
a3ada2d4ba | ||
|
6562305928 | ||
|
1f01b4d6f3 | ||
|
854b5adf36 | ||
|
d77a9e7e19 | ||
|
9999bb270b | ||
|
c266d99908 | ||
|
ac4e972999 | ||
|
5a47222773 | ||
|
1dd9e4b00e | ||
|
61eb543d36 | ||
|
9f8a42e3f3 | ||
|
5f29f9ab1d | ||
|
9f7f59799e | ||
|
2d4128223e | ||
|
8e5cea1968 | ||
|
9d2c9efdb4 | ||
|
60f6f3204d | ||
|
db87d12d0e | ||
|
a6cfc94b9a | ||
|
9115b36311 | ||
|
c559aa3037 | ||
|
c08b11cce7 | ||
|
3e3bf236d5 | ||
|
eccd42e2e9 | ||
|
fd5aa800d1 | ||
e2e103eaa7 | |||
|
803968c258 | ||
7c9a134065 | |||
|
0b135a5863 | ||
3a45e30cfe | |||
|
5219d096e1 | ||
|
21e9a3360b | ||
|
d464395f48 | ||
|
aacebb4ff8 | ||
|
4aa17b7cf5 | ||
|
4203277655 | ||
|
0e73e519a0 | ||
|
fd4fc533fb | ||
|
a6a54eb0ce | ||
|
b00ff88b97 | ||
|
674ccdfa8c | ||
|
7c81e618f5 | ||
|
975ac12982 | ||
|
d84e1f7cb1 | ||
|
5f1f3f0769 | ||
|
4f30787729 | ||
|
dbab3749b2 | ||
|
4d8d32bbd3 | ||
|
d6a5cfe7d3 | ||
|
a5a2c84614 | ||
|
0f2a2996a0 | ||
|
394f7f1470 | ||
|
9d58ff5695 | ||
|
25dd5db5e0 | ||
|
73678412d1 | ||
|
9f443d183c | ||
|
5a101ff0b5 | ||
|
c0baf4a943 | ||
|
382d3ca372 | ||
|
4259605f8b | ||
|
b62c901c47 | ||
|
219067ccab | ||
|
3861f88d6d | ||
|
92a7da2889 | ||
|
69e1d0ef9e |
@@ -36,6 +36,10 @@ endif
|
||||
PROGS=$(QEMU_PROG) $(QEMU_PROGW)
|
||||
STPFILES=
|
||||
|
||||
ifdef CONFIG_LINUX_USER
|
||||
PROGS+=$(QEMU_PROG)-binfmt
|
||||
endif
|
||||
|
||||
config-target.h: config-target.h-timestamp
|
||||
config-target.h-timestamp: config-target.mak
|
||||
|
||||
@@ -115,6 +119,8 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) \
|
||||
obj-y += linux-user/
|
||||
obj-y += gdbstub.o thunk.o user-exec.o
|
||||
|
||||
obj-binfmt-y += linux-user/
|
||||
|
||||
endif #CONFIG_LINUX_USER
|
||||
|
||||
#########################################################
|
||||
@@ -163,7 +169,11 @@ endif # CONFIG_SOFTMMU
|
||||
# Workaround for http://gcc.gnu.org/PR55489, see configure.
|
||||
%/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS)
|
||||
|
||||
ifdef CONFIG_LINUX_USER
|
||||
dummy := $(call unnest-vars,,obj-y obj-binfmt-y)
|
||||
else
|
||||
dummy := $(call unnest-vars,,obj-y)
|
||||
endif
|
||||
all-obj-y := $(obj-y)
|
||||
|
||||
target-obj-y :=
|
||||
@@ -200,6 +210,9 @@ ifdef CONFIG_DARWIN
|
||||
$(call quiet-command,SetFile -a C $@," SETFILE $(TARGET_DIR)$@")
|
||||
endif
|
||||
|
||||
$(QEMU_PROG)-binfmt: $(obj-binfmt-y)
|
||||
$(call LINK,$^)
|
||||
|
||||
gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
|
||||
$(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@")
|
||||
|
||||
|
@@ -21,6 +21,8 @@ block-obj-$(CONFIG_GLUSTERFS) += gluster.o
|
||||
block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o
|
||||
block-obj-$(CONFIG_LIBSSH2) += ssh.o
|
||||
block-obj-y += accounting.o dirty-bitmap.o
|
||||
block-obj-y += dictzip.o
|
||||
block-obj-y += tar.o
|
||||
block-obj-y += write-threshold.o
|
||||
|
||||
block-obj-y += crypto.o
|
||||
|
586
block/dictzip.c
Normal file
586
block/dictzip.c
Normal file
@@ -0,0 +1,586 @@
|
||||
/*
|
||||
* DictZip Block driver for dictzip enabled gzip files
|
||||
*
|
||||
* Use the "dictzip" tool from the "dictd" package to create gzip files that
|
||||
* contain the extra DictZip headers.
|
||||
*
|
||||
* dictzip(1) is a compression program which creates compressed files in the
|
||||
* gzip format (see RFC 1952). However, unlike gzip(1), dictzip(1) compresses
|
||||
* the file in pieces and stores an index to the pieces in the gzip header.
|
||||
* This allows random access to the file at the granularity of the compressed
|
||||
* pieces (currently about 64kB) while maintaining good compression ratios
|
||||
* (within 5% of the expected ratio for dictionary data).
|
||||
* dictd(8) uses files stored in this format.
|
||||
*
|
||||
* For details on DictZip see http://dict.org/.
|
||||
*
|
||||
* Copyright (c) 2009 Alexander Graf <agraf@suse.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu-common.h"
|
||||
#include "block/block_int.h"
|
||||
#include <zlib.h>
|
||||
|
||||
// #define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define dprintf(fmt, ...) do { printf("dzip: " fmt, ## __VA_ARGS__); } while (0)
|
||||
#else
|
||||
#define dprintf(fmt, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
#define Z_STREAM_COUNT 4
|
||||
#define CACHE_COUNT 20
|
||||
|
||||
/* magic values */
|
||||
|
||||
#define GZ_MAGIC1 0x1f
|
||||
#define GZ_MAGIC2 0x8b
|
||||
#define DZ_MAGIC1 'R'
|
||||
#define DZ_MAGIC2 'A'
|
||||
|
||||
#define GZ_FEXTRA 0x04 /* Optional field (random access index) */
|
||||
#define GZ_FNAME 0x08 /* Original name */
|
||||
#define GZ_COMMENT 0x10 /* Zero-terminated, human-readable comment */
|
||||
#define GZ_FHCRC 0x02 /* Header CRC16 */
|
||||
|
||||
/* offsets */
|
||||
|
||||
#define GZ_ID 0 /* GZ_MAGIC (16bit) */
|
||||
#define GZ_FLG 3 /* FLaGs (see above) */
|
||||
#define GZ_XLEN 10 /* eXtra LENgth (16bit) */
|
||||
#define GZ_SI 12 /* Subfield ID (16bit) */
|
||||
#define GZ_VERSION 16 /* Version for subfield format */
|
||||
#define GZ_CHUNKSIZE 18 /* Chunk size (16bit) */
|
||||
#define GZ_CHUNKCNT 20 /* Number of chunks (16bit) */
|
||||
#define GZ_RNDDATA 22 /* Random access data (16bit) */
|
||||
|
||||
#define GZ_99_CHUNKSIZE 18 /* Chunk size (32bit) */
|
||||
#define GZ_99_CHUNKCNT 22 /* Number of chunks (32bit) */
|
||||
#define GZ_99_FILESIZE 26 /* Size of unpacked file (64bit) */
|
||||
#define GZ_99_RNDDATA 34 /* Random access data (32bit) */
|
||||
|
||||
struct BDRVDictZipState;
|
||||
|
||||
typedef struct DictZipAIOCB {
|
||||
BlockAIOCB common;
|
||||
struct BDRVDictZipState *s;
|
||||
QEMUIOVector *qiov; /* QIOV of the original request */
|
||||
QEMUIOVector *qiov_gz; /* QIOV of the gz subrequest */
|
||||
QEMUBH *bh; /* BH for cache */
|
||||
z_stream *zStream; /* stream to use for decoding */
|
||||
int zStream_id; /* stream id of the above pointer */
|
||||
size_t start; /* offset into the uncompressed file */
|
||||
size_t len; /* uncompressed bytes to read */
|
||||
uint8_t *gzipped; /* the gzipped data */
|
||||
uint8_t *buf; /* cached result */
|
||||
size_t gz_len; /* amount of gzip data */
|
||||
size_t gz_start; /* uncompressed starting point of gzip data */
|
||||
uint64_t offset; /* offset for "start" into the uncompressed chunk */
|
||||
int chunks_len; /* amount of uncompressed data in all gzip data */
|
||||
} DictZipAIOCB;
|
||||
|
||||
typedef struct dict_cache {
|
||||
size_t start;
|
||||
size_t len;
|
||||
uint8_t *buf;
|
||||
} DictCache;
|
||||
|
||||
typedef struct BDRVDictZipState {
|
||||
BlockDriverState *hd;
|
||||
z_stream zStream[Z_STREAM_COUNT];
|
||||
DictCache cache[CACHE_COUNT];
|
||||
int cache_index;
|
||||
uint8_t stream_in_use;
|
||||
uint64_t chunk_len;
|
||||
uint32_t chunk_cnt;
|
||||
uint16_t *chunks;
|
||||
uint32_t *chunks32;
|
||||
uint64_t *offsets;
|
||||
int64_t file_len;
|
||||
} BDRVDictZipState;
|
||||
|
||||
static int start_zStream(z_stream *zStream)
|
||||
{
|
||||
zStream->zalloc = NULL;
|
||||
zStream->zfree = NULL;
|
||||
zStream->opaque = NULL;
|
||||
zStream->next_in = 0;
|
||||
zStream->avail_in = 0;
|
||||
zStream->next_out = NULL;
|
||||
zStream->avail_out = 0;
|
||||
|
||||
return inflateInit2( zStream, -15 );
|
||||
}
|
||||
|
||||
static QemuOptsList runtime_opts = {
|
||||
.name = "dzip",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
|
||||
.desc = {
|
||||
{
|
||||
.name = "filename",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "URL to the dictzip file",
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
};
|
||||
|
||||
static int dictzip_open(BlockDriverState *bs, QDict *options, int flags, Error **errp)
|
||||
{
|
||||
BDRVDictZipState *s = bs->opaque;
|
||||
const char *err = "Unknown (read error?)";
|
||||
uint8_t magic[2];
|
||||
char buf[100];
|
||||
uint8_t header_flags;
|
||||
uint16_t chunk_len16;
|
||||
uint16_t chunk_cnt16;
|
||||
uint32_t chunk_len32;
|
||||
uint16_t header_ver;
|
||||
uint16_t tmp_short;
|
||||
uint64_t offset;
|
||||
int chunks_len;
|
||||
int headerLength = GZ_XLEN - 1;
|
||||
int rnd_offs;
|
||||
int ret;
|
||||
int i;
|
||||
QemuOpts *opts;
|
||||
Error *local_err = NULL;
|
||||
const char *filename;
|
||||
|
||||
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
|
||||
qemu_opts_absorb_qdict(opts, options, &local_err);
|
||||
if (local_err != NULL) {
|
||||
error_propagate(errp, local_err);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
filename = qemu_opt_get(opts, "filename");
|
||||
|
||||
if (!strncmp(filename, "dzip://", 7))
|
||||
filename += 7;
|
||||
else if (!strncmp(filename, "dzip:", 5))
|
||||
filename += 5;
|
||||
|
||||
s->hd = bdrv_open(filename, NULL, NULL, flags | BDRV_O_PROTOCOL, errp);
|
||||
if (!s->hd) {
|
||||
ret = -EINVAL;
|
||||
qemu_opts_del(opts);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* initialize zlib streams */
|
||||
for (i = 0; i < Z_STREAM_COUNT; i++) {
|
||||
if (start_zStream( &s->zStream[i] ) != Z_OK) {
|
||||
err = s->zStream[i].msg;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* gzip header */
|
||||
if (bdrv_pread(s->hd->file, GZ_ID, &magic, sizeof(magic)) != sizeof(magic))
|
||||
goto fail;
|
||||
|
||||
if (!((magic[0] == GZ_MAGIC1) && (magic[1] == GZ_MAGIC2))) {
|
||||
err = "No gzip file";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* dzip header */
|
||||
if (bdrv_pread(s->hd->file, GZ_FLG, &header_flags, 1) != 1)
|
||||
goto fail;
|
||||
|
||||
if (!(header_flags & GZ_FEXTRA)) {
|
||||
err = "Not a dictzip file (wrong flags)";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* extra length */
|
||||
if (bdrv_pread(s->hd->file, GZ_XLEN, &tmp_short, 2) != 2)
|
||||
goto fail;
|
||||
|
||||
headerLength += le16_to_cpu(tmp_short) + 2;
|
||||
|
||||
/* DictZip magic */
|
||||
if (bdrv_pread(s->hd->file, GZ_SI, &magic, 2) != 2)
|
||||
goto fail;
|
||||
|
||||
if (magic[0] != DZ_MAGIC1 || magic[1] != DZ_MAGIC2) {
|
||||
err = "Not a dictzip file (missing extra magic)";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* DictZip version */
|
||||
if (bdrv_pread(s->hd->file, GZ_VERSION, &header_ver, 2) != 2)
|
||||
goto fail;
|
||||
|
||||
header_ver = le16_to_cpu(header_ver);
|
||||
|
||||
switch (header_ver) {
|
||||
case 1: /* Normal DictZip */
|
||||
/* number of chunks */
|
||||
if (bdrv_pread(s->hd->file, GZ_CHUNKSIZE, &chunk_len16, 2) != 2)
|
||||
goto fail;
|
||||
|
||||
s->chunk_len = le16_to_cpu(chunk_len16);
|
||||
|
||||
/* chunk count */
|
||||
if (bdrv_pread(s->hd->file, GZ_CHUNKCNT, &chunk_cnt16, 2) != 2)
|
||||
goto fail;
|
||||
|
||||
s->chunk_cnt = le16_to_cpu(chunk_cnt16);
|
||||
chunks_len = sizeof(short) * s->chunk_cnt;
|
||||
rnd_offs = GZ_RNDDATA;
|
||||
break;
|
||||
case 99: /* Special Alex pigz version */
|
||||
/* number of chunks */
|
||||
if (bdrv_pread(s->hd->file, GZ_99_CHUNKSIZE, &chunk_len32, 4) != 4)
|
||||
goto fail;
|
||||
|
||||
dprintf("chunk len [%#x] = %d\n", GZ_99_CHUNKSIZE, chunk_len32);
|
||||
s->chunk_len = le32_to_cpu(chunk_len32);
|
||||
|
||||
/* chunk count */
|
||||
if (bdrv_pread(s->hd->file, GZ_99_CHUNKCNT, &s->chunk_cnt, 4) != 4)
|
||||
goto fail;
|
||||
|
||||
s->chunk_cnt = le32_to_cpu(s->chunk_cnt);
|
||||
|
||||
dprintf("chunk len | count = %"PRId64" | %d\n", s->chunk_len, s->chunk_cnt);
|
||||
|
||||
/* file size */
|
||||
if (bdrv_pread(s->hd->file, GZ_99_FILESIZE, &s->file_len, 8) != 8)
|
||||
goto fail;
|
||||
|
||||
s->file_len = le64_to_cpu(s->file_len);
|
||||
chunks_len = sizeof(int) * s->chunk_cnt;
|
||||
rnd_offs = GZ_99_RNDDATA;
|
||||
break;
|
||||
default:
|
||||
err = "Invalid DictZip version";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* random access data */
|
||||
s->chunks = g_malloc(chunks_len);
|
||||
if (header_ver == 99)
|
||||
s->chunks32 = (uint32_t *)s->chunks;
|
||||
|
||||
if (bdrv_pread(s->hd->file, rnd_offs, s->chunks, chunks_len) != chunks_len)
|
||||
goto fail;
|
||||
|
||||
/* orig filename */
|
||||
if (header_flags & GZ_FNAME) {
|
||||
if (bdrv_pread(s->hd->file, headerLength + 1, buf, sizeof(buf)) != sizeof(buf))
|
||||
goto fail;
|
||||
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
headerLength += strlen(buf) + 1;
|
||||
|
||||
if (strlen(buf) == sizeof(buf))
|
||||
goto fail;
|
||||
|
||||
dprintf("filename: %s\n", buf);
|
||||
}
|
||||
|
||||
/* comment field */
|
||||
if (header_flags & GZ_COMMENT) {
|
||||
if (bdrv_pread(s->hd->file, headerLength, buf, sizeof(buf)) != sizeof(buf))
|
||||
goto fail;
|
||||
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
headerLength += strlen(buf) + 1;
|
||||
|
||||
if (strlen(buf) == sizeof(buf))
|
||||
goto fail;
|
||||
|
||||
dprintf("comment: %s\n", buf);
|
||||
}
|
||||
|
||||
if (header_flags & GZ_FHCRC)
|
||||
headerLength += 2;
|
||||
|
||||
/* uncompressed file length*/
|
||||
if (!s->file_len) {
|
||||
uint32_t file_len;
|
||||
|
||||
if (bdrv_pread(s->hd->file, bdrv_getlength(s->hd) - 4, &file_len, 4) != 4)
|
||||
goto fail;
|
||||
|
||||
s->file_len = le32_to_cpu(file_len);
|
||||
}
|
||||
|
||||
/* compute offsets */
|
||||
s->offsets = g_malloc(sizeof( *s->offsets ) * s->chunk_cnt);
|
||||
|
||||
for (offset = headerLength + 1, i = 0; i < s->chunk_cnt; i++) {
|
||||
s->offsets[i] = offset;
|
||||
switch (header_ver) {
|
||||
case 1:
|
||||
offset += le16_to_cpu(s->chunks[i]);
|
||||
break;
|
||||
case 99:
|
||||
offset += le32_to_cpu(s->chunks32[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
dprintf("chunk %#"PRIx64" - %#"PRIx64" = offset %#"PRIx64" -> %#"PRIx64"\n", i * s->chunk_len, (i+1) * s->chunk_len, s->offsets[i], offset);
|
||||
}
|
||||
qemu_opts_del(opts);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
fprintf(stderr, "DictZip: Error opening file: %s\n", err);
|
||||
bdrv_unref(s->hd);
|
||||
if (s->chunks)
|
||||
g_free(s->chunks);
|
||||
qemu_opts_del(opts);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* This callback gets invoked when we have the result in cache already */
|
||||
static void dictzip_cache_cb(void *opaque)
|
||||
{
|
||||
DictZipAIOCB *acb = (DictZipAIOCB *)opaque;
|
||||
|
||||
qemu_iovec_from_buf(acb->qiov, 0, acb->buf, acb->len);
|
||||
acb->common.cb(acb->common.opaque, 0);
|
||||
qemu_bh_delete(acb->bh);
|
||||
qemu_aio_unref(acb);
|
||||
}
|
||||
|
||||
/* This callback gets invoked by the underlying block reader when we have
|
||||
* all compressed data. We uncompress in here. */
|
||||
static void dictzip_read_cb(void *opaque, int ret)
|
||||
{
|
||||
DictZipAIOCB *acb = (DictZipAIOCB *)opaque;
|
||||
struct BDRVDictZipState *s = acb->s;
|
||||
uint8_t *buf;
|
||||
DictCache *cache;
|
||||
int r, i;
|
||||
|
||||
buf = g_malloc(acb->chunks_len);
|
||||
|
||||
/* try to find zlib stream for decoding */
|
||||
do {
|
||||
for (i = 0; i < Z_STREAM_COUNT; i++) {
|
||||
if (!(s->stream_in_use & (1 << i))) {
|
||||
s->stream_in_use |= (1 << i);
|
||||
acb->zStream_id = i;
|
||||
acb->zStream = &s->zStream[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(!acb->zStream);
|
||||
|
||||
/* sure, we could handle more streams, but this callback should be single
|
||||
threaded and when it's not, we really want to know! */
|
||||
assert(i == 0);
|
||||
|
||||
/* uncompress the chunk */
|
||||
acb->zStream->next_in = acb->gzipped;
|
||||
acb->zStream->avail_in = acb->gz_len;
|
||||
acb->zStream->next_out = buf;
|
||||
acb->zStream->avail_out = acb->chunks_len;
|
||||
|
||||
r = inflate( acb->zStream, Z_PARTIAL_FLUSH );
|
||||
if ( (r != Z_OK) && (r != Z_STREAM_END) )
|
||||
fprintf(stderr, "Error inflating: [%d] %s\n", r, acb->zStream->msg);
|
||||
|
||||
if ( r == Z_STREAM_END )
|
||||
inflateReset(acb->zStream);
|
||||
|
||||
dprintf("inflating [%d] left: %d | %d bytes\n", r, acb->zStream->avail_in, acb->zStream->avail_out);
|
||||
s->stream_in_use &= ~(1 << acb->zStream_id);
|
||||
|
||||
/* nofity the caller */
|
||||
qemu_iovec_from_buf(acb->qiov, 0, buf + acb->offset, acb->len);
|
||||
acb->common.cb(acb->common.opaque, 0);
|
||||
|
||||
/* fill the cache */
|
||||
cache = &s->cache[s->cache_index];
|
||||
s->cache_index++;
|
||||
if (s->cache_index == CACHE_COUNT)
|
||||
s->cache_index = 0;
|
||||
|
||||
cache->len = 0;
|
||||
if (cache->buf)
|
||||
g_free(cache->buf);
|
||||
cache->start = acb->gz_start;
|
||||
cache->buf = buf;
|
||||
cache->len = acb->chunks_len;
|
||||
|
||||
/* free occupied ressources */
|
||||
g_free(acb->qiov_gz);
|
||||
qemu_aio_unref(acb);
|
||||
}
|
||||
|
||||
static const AIOCBInfo dictzip_aiocb_info = {
|
||||
.aiocb_size = sizeof(DictZipAIOCB),
|
||||
};
|
||||
|
||||
/* This is where we get a request from a caller to read something */
|
||||
static BlockAIOCB *dictzip_aio_readv(BlockDriverState *bs,
|
||||
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
||||
BlockCompletionFunc *cb, void *opaque)
|
||||
{
|
||||
BDRVDictZipState *s = bs->opaque;
|
||||
DictZipAIOCB *acb;
|
||||
QEMUIOVector *qiov_gz;
|
||||
struct iovec *iov;
|
||||
uint8_t *buf;
|
||||
size_t start = sector_num * SECTOR_SIZE;
|
||||
size_t len = nb_sectors * SECTOR_SIZE;
|
||||
size_t end = start + len;
|
||||
size_t gz_start;
|
||||
size_t gz_len;
|
||||
int64_t gz_sector_num;
|
||||
int gz_nb_sectors;
|
||||
int first_chunk, last_chunk;
|
||||
int first_offset;
|
||||
int i;
|
||||
|
||||
acb = qemu_aio_get(&dictzip_aiocb_info, bs, cb, opaque);
|
||||
if (!acb)
|
||||
return NULL;
|
||||
|
||||
/* Search Cache */
|
||||
for (i = 0; i < CACHE_COUNT; i++) {
|
||||
if (!s->cache[i].len)
|
||||
continue;
|
||||
|
||||
if ((start >= s->cache[i].start) &&
|
||||
(end <= (s->cache[i].start + s->cache[i].len))) {
|
||||
acb->buf = s->cache[i].buf + (start - s->cache[i].start);
|
||||
acb->len = len;
|
||||
acb->qiov = qiov;
|
||||
acb->bh = qemu_bh_new(dictzip_cache_cb, acb);
|
||||
qemu_bh_schedule(acb->bh);
|
||||
|
||||
return &acb->common;
|
||||
}
|
||||
}
|
||||
|
||||
/* No cache, so let's decode */
|
||||
/* We need to read these chunks */
|
||||
first_chunk = start / s->chunk_len;
|
||||
first_offset = start - first_chunk * s->chunk_len;
|
||||
last_chunk = end / s->chunk_len;
|
||||
|
||||
gz_start = s->offsets[first_chunk];
|
||||
gz_len = 0;
|
||||
for (i = first_chunk; i <= last_chunk; i++) {
|
||||
if (s->chunks32)
|
||||
gz_len += le32_to_cpu(s->chunks32[i]);
|
||||
else
|
||||
gz_len += le16_to_cpu(s->chunks[i]);
|
||||
}
|
||||
|
||||
gz_sector_num = gz_start / SECTOR_SIZE;
|
||||
gz_nb_sectors = (gz_len / SECTOR_SIZE);
|
||||
|
||||
/* account for tail and heads */
|
||||
while ((gz_start + gz_len) > ((gz_sector_num + gz_nb_sectors) * SECTOR_SIZE))
|
||||
gz_nb_sectors++;
|
||||
|
||||
/* Allocate qiov, iov and buf in one chunk so we only need to free qiov */
|
||||
qiov_gz = g_malloc0(sizeof(QEMUIOVector) + sizeof(struct iovec) +
|
||||
(gz_nb_sectors * SECTOR_SIZE));
|
||||
iov = (struct iovec *)(((char *)qiov_gz) + sizeof(QEMUIOVector));
|
||||
buf = ((uint8_t *)iov) + sizeof(struct iovec *);
|
||||
|
||||
/* Kick off the read by the backing file, so we can start decompressing */
|
||||
iov->iov_base = (void *)buf;
|
||||
iov->iov_len = gz_nb_sectors * 512;
|
||||
qemu_iovec_init_external(qiov_gz, iov, 1);
|
||||
|
||||
dprintf("read %zd - %zd => %zd - %zd\n", start, end, gz_start, gz_start + gz_len);
|
||||
|
||||
acb->s = s;
|
||||
acb->qiov = qiov;
|
||||
acb->qiov_gz = qiov_gz;
|
||||
acb->start = start;
|
||||
acb->len = len;
|
||||
acb->gzipped = buf + (gz_start % SECTOR_SIZE);
|
||||
acb->gz_len = gz_len;
|
||||
acb->gz_start = first_chunk * s->chunk_len;
|
||||
acb->offset = first_offset;
|
||||
acb->chunks_len = (last_chunk - first_chunk + 1) * s->chunk_len;
|
||||
|
||||
return bdrv_aio_readv(s->hd->file, gz_sector_num, qiov_gz, gz_nb_sectors,
|
||||
dictzip_read_cb, acb);
|
||||
}
|
||||
|
||||
static void dictzip_close(BlockDriverState *bs)
|
||||
{
|
||||
BDRVDictZipState *s = bs->opaque;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CACHE_COUNT; i++) {
|
||||
if (!s->cache[i].len)
|
||||
continue;
|
||||
|
||||
g_free(s->cache[i].buf);
|
||||
}
|
||||
|
||||
for (i = 0; i < Z_STREAM_COUNT; i++) {
|
||||
inflateEnd(&s->zStream[i]);
|
||||
}
|
||||
|
||||
if (s->chunks)
|
||||
g_free(s->chunks);
|
||||
|
||||
if (s->offsets)
|
||||
g_free(s->offsets);
|
||||
|
||||
dprintf("Close\n");
|
||||
}
|
||||
|
||||
static int64_t dictzip_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVDictZipState *s = bs->opaque;
|
||||
dprintf("getlength -> %ld\n", s->file_len);
|
||||
return s->file_len;
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_dictzip = {
|
||||
.format_name = "dzip",
|
||||
.protocol_name = "dzip",
|
||||
|
||||
.instance_size = sizeof(BDRVDictZipState),
|
||||
.bdrv_file_open = dictzip_open,
|
||||
.bdrv_close = dictzip_close,
|
||||
.bdrv_getlength = dictzip_getlength,
|
||||
|
||||
.bdrv_aio_readv = dictzip_aio_readv,
|
||||
};
|
||||
|
||||
static void dictzip_block_init(void)
|
||||
{
|
||||
bdrv_register(&bdrv_dictzip);
|
||||
}
|
||||
|
||||
block_init(dictzip_block_init);
|
379
block/tar.c
Normal file
379
block/tar.c
Normal file
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* Tar block driver
|
||||
*
|
||||
* Copyright (c) 2009 Alexander Graf <agraf@suse.de>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu-common.h"
|
||||
#include "block/block_int.h"
|
||||
|
||||
// #define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define dprintf(fmt, ...) do { printf("tar: " fmt, ## __VA_ARGS__); } while (0)
|
||||
#else
|
||||
#define dprintf(fmt, ...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
|
||||
#define POSIX_TAR_MAGIC "ustar"
|
||||
#define OFFS_LENGTH 0x7c
|
||||
#define OFFS_TYPE 0x9c
|
||||
#define OFFS_MAGIC 0x101
|
||||
|
||||
#define OFFS_S_SP 0x182
|
||||
#define OFFS_S_EXT 0x1e2
|
||||
#define OFFS_S_LENGTH 0x1e3
|
||||
#define OFFS_SX_EXT 0x1f8
|
||||
|
||||
typedef struct SparseCache {
|
||||
uint64_t start;
|
||||
uint64_t end;
|
||||
} SparseCache;
|
||||
|
||||
typedef struct BDRVTarState {
|
||||
BlockDriverState *hd;
|
||||
size_t file_sec;
|
||||
uint64_t file_len;
|
||||
SparseCache *sparse;
|
||||
int sparse_num;
|
||||
uint64_t last_end;
|
||||
char longfile[2048];
|
||||
} BDRVTarState;
|
||||
|
||||
static int str_ends(char *str, const char *end)
|
||||
{
|
||||
int end_len = strlen(end);
|
||||
int str_len = strlen(str);
|
||||
|
||||
if (str_len < end_len)
|
||||
return 0;
|
||||
|
||||
return !strncmp(str + str_len - end_len, end, end_len);
|
||||
}
|
||||
|
||||
static int is_target_file(BlockDriverState *bs, char *filename,
|
||||
char *header)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (str_ends(filename, ".raw"))
|
||||
retval = 1;
|
||||
|
||||
if (str_ends(filename, ".qcow"))
|
||||
retval = 1;
|
||||
|
||||
if (str_ends(filename, ".qcow2"))
|
||||
retval = 1;
|
||||
|
||||
if (str_ends(filename, ".vmdk"))
|
||||
retval = 1;
|
||||
|
||||
if (retval &&
|
||||
(header[OFFS_TYPE] != '0') &&
|
||||
(header[OFFS_TYPE] != 'S')) {
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
dprintf("does filename %s match? %s\n", filename, retval ? "yes" : "no");
|
||||
|
||||
/* make sure we're not using this name again */
|
||||
filename[0] = '\0';
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static uint64_t tar2u64(char *ptr)
|
||||
{
|
||||
uint64_t retval;
|
||||
char oldend = ptr[12];
|
||||
|
||||
ptr[12] = '\0';
|
||||
if (*ptr & 0x80) {
|
||||
/* XXX we only support files up to 64 bit length */
|
||||
retval = be64_to_cpu(*(uint64_t *)(ptr+4));
|
||||
dprintf("Convert %lx -> %#lx\n", *(uint64_t*)(ptr+4), retval);
|
||||
} else {
|
||||
retval = strtol(ptr, NULL, 8);
|
||||
dprintf("Convert %s -> %#lx\n", ptr, retval);
|
||||
}
|
||||
|
||||
ptr[12] = oldend;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void tar_sparse(BDRVTarState *s, uint64_t offs, uint64_t len)
|
||||
{
|
||||
SparseCache *sparse;
|
||||
|
||||
if (!len)
|
||||
return;
|
||||
if (!(offs - s->last_end)) {
|
||||
s->last_end += len;
|
||||
return;
|
||||
}
|
||||
if (s->last_end > offs)
|
||||
return;
|
||||
|
||||
dprintf("Last chunk until %lx new chunk at %lx\n", s->last_end, offs);
|
||||
|
||||
s->sparse = g_realloc(s->sparse, (s->sparse_num + 1) * sizeof(SparseCache));
|
||||
sparse = &s->sparse[s->sparse_num];
|
||||
sparse->start = s->last_end;
|
||||
sparse->end = offs;
|
||||
s->last_end = offs + len;
|
||||
s->sparse_num++;
|
||||
dprintf("Sparse at %lx end=%lx\n", sparse->start,
|
||||
sparse->end);
|
||||
}
|
||||
|
||||
static QemuOptsList runtime_opts = {
|
||||
.name = "tar",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
|
||||
.desc = {
|
||||
{
|
||||
.name = "filename",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "URL to the tar file",
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
};
|
||||
|
||||
static int tar_open(BlockDriverState *bs, QDict *options, int flags, Error **errp)
|
||||
{
|
||||
BDRVTarState *s = bs->opaque;
|
||||
char header[SECTOR_SIZE];
|
||||
char *real_file = header;
|
||||
char *magic;
|
||||
size_t header_offs = 0;
|
||||
int ret;
|
||||
QemuOpts *opts;
|
||||
Error *local_err = NULL;
|
||||
const char *filename;
|
||||
|
||||
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
|
||||
qemu_opts_absorb_qdict(opts, options, &local_err);
|
||||
if (local_err != NULL) {
|
||||
error_propagate(errp, local_err);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
filename = qemu_opt_get(opts, "filename");
|
||||
|
||||
if (!strncmp(filename, "tar://", 6))
|
||||
filename += 6;
|
||||
else if (!strncmp(filename, "tar:", 4))
|
||||
filename += 4;
|
||||
|
||||
s->hd = bdrv_open(filename, NULL, NULL, flags | BDRV_O_PROTOCOL, errp);
|
||||
if (!s->hd) {
|
||||
ret = -EINVAL;
|
||||
qemu_opts_del(opts);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Search the file for an image */
|
||||
|
||||
do {
|
||||
/* tar header */
|
||||
if (bdrv_pread(s->hd->file, header_offs, header, SECTOR_SIZE) != SECTOR_SIZE)
|
||||
goto fail;
|
||||
|
||||
if ((header_offs > 1) && !header[0]) {
|
||||
fprintf(stderr, "Tar: No image file found in archive\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
magic = &header[OFFS_MAGIC];
|
||||
if (strncmp(magic, POSIX_TAR_MAGIC, 5)) {
|
||||
fprintf(stderr, "Tar: Invalid magic: %s\n", magic);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dprintf("file type: %c\n", header[OFFS_TYPE]);
|
||||
|
||||
/* file length*/
|
||||
s->file_len = (tar2u64(&header[OFFS_LENGTH]) + (SECTOR_SIZE - 1)) &
|
||||
~(SECTOR_SIZE - 1);
|
||||
s->file_sec = (header_offs / SECTOR_SIZE) + 1;
|
||||
|
||||
header_offs += s->file_len + SECTOR_SIZE;
|
||||
|
||||
if (header[OFFS_TYPE] == 'L') {
|
||||
bdrv_pread(s->hd->file, header_offs - s->file_len, s->longfile,
|
||||
sizeof(s->longfile));
|
||||
s->longfile[sizeof(s->longfile)-1] = '\0';
|
||||
real_file = header;
|
||||
} else if (s->longfile[0]) {
|
||||
real_file = s->longfile;
|
||||
} else {
|
||||
real_file = header;
|
||||
}
|
||||
} while(!is_target_file(bs, real_file, header));
|
||||
|
||||
/* We found an image! */
|
||||
|
||||
if (header[OFFS_TYPE] == 'S') {
|
||||
uint8_t isextended;
|
||||
int i;
|
||||
|
||||
for (i = OFFS_S_SP; i < (OFFS_S_SP + (4 * 24)); i += 24)
|
||||
tar_sparse(s, tar2u64(&header[i]), tar2u64(&header[i+12]));
|
||||
|
||||
s->file_len = tar2u64(&header[OFFS_S_LENGTH]);
|
||||
isextended = header[OFFS_S_EXT];
|
||||
|
||||
while (isextended) {
|
||||
if (bdrv_pread(s->hd->file, s->file_sec * SECTOR_SIZE, header,
|
||||
SECTOR_SIZE) != SECTOR_SIZE)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < (21 * 24); i += 24)
|
||||
tar_sparse(s, tar2u64(&header[i]), tar2u64(&header[i+12]));
|
||||
isextended = header[OFFS_SX_EXT];
|
||||
s->file_sec++;
|
||||
}
|
||||
tar_sparse(s, s->file_len, 1);
|
||||
}
|
||||
qemu_opts_del(opts);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
fprintf(stderr, "Tar: Error opening file\n");
|
||||
bdrv_unref(s->hd);
|
||||
qemu_opts_del(opts);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
typedef struct TarAIOCB {
|
||||
BlockAIOCB common;
|
||||
QEMUBH *bh;
|
||||
} TarAIOCB;
|
||||
|
||||
/* This callback gets invoked when we have pure sparseness */
|
||||
static void tar_sparse_cb(void *opaque)
|
||||
{
|
||||
TarAIOCB *acb = (TarAIOCB *)opaque;
|
||||
|
||||
acb->common.cb(acb->common.opaque, 0);
|
||||
qemu_bh_delete(acb->bh);
|
||||
qemu_aio_unref(acb);
|
||||
}
|
||||
|
||||
static AIOCBInfo tar_aiocb_info = {
|
||||
.aiocb_size = sizeof(TarAIOCB),
|
||||
};
|
||||
|
||||
/* This is where we get a request from a caller to read something */
|
||||
static BlockAIOCB *tar_aio_readv(BlockDriverState *bs,
|
||||
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
||||
BlockCompletionFunc *cb, void *opaque)
|
||||
{
|
||||
BDRVTarState *s = bs->opaque;
|
||||
SparseCache *sparse;
|
||||
int64_t sec_file = sector_num + s->file_sec;
|
||||
int64_t start = sector_num * SECTOR_SIZE;
|
||||
int64_t end = start + (nb_sectors * SECTOR_SIZE);
|
||||
int i;
|
||||
TarAIOCB *acb;
|
||||
|
||||
for (i = 0; i < s->sparse_num; i++) {
|
||||
sparse = &s->sparse[i];
|
||||
if (sparse->start > end) {
|
||||
/* We expect the cache to be start increasing */
|
||||
break;
|
||||
} else if ((sparse->start < start) && (sparse->end <= start)) {
|
||||
/* sparse before our offset */
|
||||
sec_file -= (sparse->end - sparse->start) / SECTOR_SIZE;
|
||||
} else if ((sparse->start <= start) && (sparse->end >= end)) {
|
||||
/* all our sectors are sparse */
|
||||
char *buf = g_malloc0(nb_sectors * SECTOR_SIZE);
|
||||
|
||||
acb = qemu_aio_get(&tar_aiocb_info, bs, cb, opaque);
|
||||
qemu_iovec_from_buf(qiov, 0, buf, nb_sectors * SECTOR_SIZE);
|
||||
g_free(buf);
|
||||
acb->bh = qemu_bh_new(tar_sparse_cb, acb);
|
||||
qemu_bh_schedule(acb->bh);
|
||||
|
||||
return &acb->common;
|
||||
} else if (((sparse->start >= start) && (sparse->start < end)) ||
|
||||
((sparse->end >= start) && (sparse->end < end))) {
|
||||
/* we're semi-sparse (worst case) */
|
||||
/* let's go synchronous and read all sectors individually */
|
||||
char *buf = g_malloc(nb_sectors * SECTOR_SIZE);
|
||||
uint64_t offs;
|
||||
|
||||
for (offs = 0; offs < (nb_sectors * SECTOR_SIZE);
|
||||
offs += SECTOR_SIZE) {
|
||||
bdrv_pread(bs->file, (sector_num * SECTOR_SIZE) + offs,
|
||||
buf + offs, SECTOR_SIZE);
|
||||
}
|
||||
|
||||
qemu_iovec_from_buf(qiov, 0, buf, nb_sectors * SECTOR_SIZE);
|
||||
acb = qemu_aio_get(&tar_aiocb_info, bs, cb, opaque);
|
||||
acb->bh = qemu_bh_new(tar_sparse_cb, acb);
|
||||
qemu_bh_schedule(acb->bh);
|
||||
|
||||
return &acb->common;
|
||||
}
|
||||
}
|
||||
|
||||
return bdrv_aio_readv(s->hd->file, sec_file, qiov, nb_sectors,
|
||||
cb, opaque);
|
||||
}
|
||||
|
||||
static void tar_close(BlockDriverState *bs)
|
||||
{
|
||||
dprintf("Close\n");
|
||||
}
|
||||
|
||||
static int64_t tar_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVTarState *s = bs->opaque;
|
||||
dprintf("getlength -> %ld\n", s->file_len);
|
||||
return s->file_len;
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_tar = {
|
||||
.format_name = "tar",
|
||||
.protocol_name = "tar",
|
||||
|
||||
.instance_size = sizeof(BDRVTarState),
|
||||
.bdrv_file_open = tar_open,
|
||||
.bdrv_close = tar_close,
|
||||
.bdrv_getlength = tar_getlength,
|
||||
|
||||
.bdrv_aio_readv = tar_aio_readv,
|
||||
};
|
||||
|
||||
static void tar_block_init(void)
|
||||
{
|
||||
bdrv_register(&bdrv_tar);
|
||||
}
|
||||
|
||||
block_init(tar_block_init);
|
5
configure
vendored
5
configure
vendored
@@ -1545,7 +1545,7 @@ fi
|
||||
|
||||
if test "$pie" = ""; then
|
||||
case "$cpu-$targetos" in
|
||||
i386-Linux|x86_64-Linux|x32-Linux|i386-OpenBSD|x86_64-OpenBSD)
|
||||
i386-Linux|x86_64-Linux|x32-Linux|ppc*-Linux|i386-OpenBSD|x86_64-OpenBSD)
|
||||
;;
|
||||
*)
|
||||
pie="no"
|
||||
@@ -1902,6 +1902,9 @@ if test "$seccomp" != "no" ; then
|
||||
ppc|ppc64)
|
||||
libseccomp_minver="2.3.0"
|
||||
;;
|
||||
s390|s390x)
|
||||
libseccomp_minver="2.2.0"
|
||||
;;
|
||||
*)
|
||||
libseccomp_minver=""
|
||||
;;
|
||||
|
2
exec.c
2
exec.c
@@ -1230,11 +1230,13 @@ static void *file_ram_alloc(RAMBlock *block,
|
||||
int fd = -1;
|
||||
int64_t page_size;
|
||||
|
||||
#ifndef TARGET_PPC
|
||||
if (kvm_enabled() && !kvm_has_sync_mmu()) {
|
||||
error_setg(errp,
|
||||
"host lacks kvm mmu notifiers, -mem-path unsupported");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
fd = open(path, O_RDWR);
|
||||
|
@@ -125,7 +125,7 @@ ssize_t v9fs_iov_vunmarshal(struct iovec *out_sg, int out_num, size_t offset,
|
||||
str->data = g_malloc(str->size + 1);
|
||||
copied = v9fs_unpack(str->data, out_sg, out_num, offset,
|
||||
str->size);
|
||||
if (copied > 0) {
|
||||
if (copied >= 0) {
|
||||
str->data[str->size] = 0;
|
||||
} else {
|
||||
v9fs_string_free(str);
|
||||
|
@@ -9,6 +9,13 @@
|
||||
* the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
/* work around a broken sys/capability.h */
|
||||
#if defined(__i386__)
|
||||
typedef unsigned long long __u64;
|
||||
#endif
|
||||
#if defined(__powerpc64__)
|
||||
#include <asm/types.h>
|
||||
#endif
|
||||
#include "qemu/osdep.h"
|
||||
#include <sys/resource.h>
|
||||
#include <getopt.h>
|
||||
|
45
hw/9pfs/9p.c
45
hw/9pfs/9p.c
@@ -1628,20 +1628,17 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
|
||||
{
|
||||
ssize_t err;
|
||||
size_t offset = 7;
|
||||
int read_count;
|
||||
int64_t xattr_len;
|
||||
uint64_t read_count;
|
||||
V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);
|
||||
VirtQueueElement *elem = v->elems[pdu->idx];
|
||||
|
||||
xattr_len = fidp->fs.xattr.len;
|
||||
read_count = xattr_len - off;
|
||||
if (fidp->fs.xattr.len < off) {
|
||||
read_count = 0;
|
||||
} else {
|
||||
read_count = fidp->fs.xattr.len - off;
|
||||
}
|
||||
if (read_count > max_count) {
|
||||
read_count = max_count;
|
||||
} else if (read_count < 0) {
|
||||
/*
|
||||
* read beyond XATTR value
|
||||
*/
|
||||
read_count = 0;
|
||||
}
|
||||
err = pdu_marshal(pdu, offset, "d", read_count);
|
||||
if (err < 0) {
|
||||
@@ -1812,14 +1809,15 @@ static void v9fs_read(void *opaque)
|
||||
if (len < 0) {
|
||||
/* IO error return the error */
|
||||
err = len;
|
||||
goto out;
|
||||
goto out_free_iovec;
|
||||
}
|
||||
} while (count < max_count && len > 0);
|
||||
err = pdu_marshal(pdu, offset, "d", count);
|
||||
if (err < 0) {
|
||||
goto out;
|
||||
goto out_free_iovec;
|
||||
}
|
||||
err += offset + count;
|
||||
out_free_iovec:
|
||||
qemu_iovec_destroy(&qiov);
|
||||
qemu_iovec_destroy(&qiov_full);
|
||||
} else if (fidp->fid_type == P9_FID_XATTR) {
|
||||
@@ -1968,23 +1966,18 @@ static int v9fs_xattr_write(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
|
||||
{
|
||||
int i, to_copy;
|
||||
ssize_t err = 0;
|
||||
int write_count;
|
||||
int64_t xattr_len;
|
||||
uint64_t write_count;
|
||||
size_t offset = 7;
|
||||
|
||||
|
||||
xattr_len = fidp->fs.xattr.len;
|
||||
write_count = xattr_len - off;
|
||||
if (write_count > count) {
|
||||
write_count = count;
|
||||
} else if (write_count < 0) {
|
||||
/*
|
||||
* write beyond XATTR value len specified in
|
||||
* xattrcreate
|
||||
*/
|
||||
if (fidp->fs.xattr.len < off) {
|
||||
err = -ENOSPC;
|
||||
goto out;
|
||||
}
|
||||
write_count = fidp->fs.xattr.len - off;
|
||||
if (write_count > count) {
|
||||
write_count = count;
|
||||
}
|
||||
err = pdu_marshal(pdu, offset, "d", write_count);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
@@ -2079,7 +2072,7 @@ static void v9fs_write(void *opaque)
|
||||
offset = 7;
|
||||
err = pdu_marshal(pdu, offset, "d", total);
|
||||
if (err < 0) {
|
||||
goto out;
|
||||
goto out_qiov;
|
||||
}
|
||||
err += offset;
|
||||
trace_v9fs_write_return(pdu->tag, pdu->id, total, err);
|
||||
@@ -2402,6 +2395,7 @@ static void v9fs_link(void *opaque)
|
||||
if (!err) {
|
||||
err = offset;
|
||||
}
|
||||
put_fid(pdu, oldfidp);
|
||||
out:
|
||||
put_fid(pdu, dfidp);
|
||||
out_nofid:
|
||||
@@ -3160,7 +3154,7 @@ static void v9fs_xattrwalk(void *opaque)
|
||||
goto out;
|
||||
}
|
||||
v9fs_path_copy(&xattr_fidp->path, &file_fidp->path);
|
||||
if (name.data == NULL) {
|
||||
if (!v9fs_string_size(&name)) {
|
||||
/*
|
||||
* listxattr request. Get the size first
|
||||
*/
|
||||
@@ -3268,7 +3262,8 @@ static void v9fs_xattrcreate(void *opaque)
|
||||
xattr_fidp->fs.xattr.flags = flags;
|
||||
v9fs_string_init(&xattr_fidp->fs.xattr.name);
|
||||
v9fs_string_copy(&xattr_fidp->fs.xattr.name, &name);
|
||||
xattr_fidp->fs.xattr.value = g_malloc(size);
|
||||
g_free(xattr_fidp->fs.xattr.value);
|
||||
xattr_fidp->fs.xattr.value = g_malloc0(size);
|
||||
err = offset;
|
||||
put_fid(pdu, file_fidp);
|
||||
out_nofid:
|
||||
|
@@ -416,7 +416,8 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
|
||||
}
|
||||
|
||||
left = len;
|
||||
while (left > 0) {
|
||||
s = st->bentries;
|
||||
while (left > 0 && s-- > 0) {
|
||||
copy = left;
|
||||
if (copy > st->bsize - st->lpib)
|
||||
copy = st->bsize - st->lpib;
|
||||
|
@@ -111,6 +111,7 @@ struct XenBlkDev {
|
||||
int requests_inflight;
|
||||
int requests_finished;
|
||||
|
||||
gboolean cache_unsafe;
|
||||
/* Persistent grants extension */
|
||||
gboolean feature_discard;
|
||||
gboolean feature_persistent;
|
||||
@@ -793,6 +794,16 @@ static void blk_parse_discard(struct XenBlkDev *blkdev)
|
||||
}
|
||||
}
|
||||
|
||||
static void blk_parse_cache_unsafe(struct XenBlkDev *blkdev)
|
||||
{
|
||||
int enable;
|
||||
|
||||
blkdev->cache_unsafe = false;
|
||||
|
||||
if (xenstore_read_be_int(&blkdev->xendev, "suse-diskcache-disable-flush", &enable) == 0)
|
||||
blkdev->cache_unsafe = !!enable;
|
||||
}
|
||||
|
||||
static int blk_init(struct XenDevice *xendev)
|
||||
{
|
||||
struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
|
||||
@@ -864,6 +875,7 @@ static int blk_init(struct XenDevice *xendev)
|
||||
xenstore_write_be_int(&blkdev->xendev, "info", info);
|
||||
|
||||
blk_parse_discard(blkdev);
|
||||
blk_parse_cache_unsafe(blkdev);
|
||||
|
||||
g_free(directiosafe);
|
||||
return 0;
|
||||
@@ -906,6 +918,9 @@ static int blk_connect(struct XenDevice *xendev)
|
||||
qflags |= BDRV_O_UNMAP;
|
||||
}
|
||||
|
||||
if (blkdev->cache_unsafe)
|
||||
qflags |= BDRV_O_NO_FLUSH;
|
||||
|
||||
/* init qemu block driver */
|
||||
index = (blkdev->xendev.dev - 202 * 256) / 16;
|
||||
blkdev->dinfo = drive_get(IF_XEN, 0, index);
|
||||
|
@@ -153,8 +153,9 @@ static void serial_update_parameters(SerialState *s)
|
||||
int speed, parity, data_bits, stop_bits, frame_size;
|
||||
QEMUSerialSetParams ssp;
|
||||
|
||||
if (s->divider == 0)
|
||||
if (s->divider == 0 || s->divider > s->baudbase) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Start bit. */
|
||||
frame_size = 1;
|
||||
|
@@ -333,6 +333,7 @@ static void virtio_gpu_resource_create_2d(VirtIOGPU *g,
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: host couldn't handle guest format %d\n",
|
||||
__func__, c2d.format);
|
||||
g_free(res);
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
|
||||
return;
|
||||
}
|
||||
|
@@ -676,11 +676,13 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
|
||||
cursor.bpp = vmsvga_fifo_read(s);
|
||||
|
||||
args = SVGA_BITMAP_SIZE(x, y) + SVGA_PIXMAP_SIZE(x, y, cursor.bpp);
|
||||
if (cursor.width > 256 ||
|
||||
cursor.height > 256 ||
|
||||
cursor.bpp > 32 ||
|
||||
SVGA_BITMAP_SIZE(x, y) > sizeof cursor.mask ||
|
||||
SVGA_PIXMAP_SIZE(x, y, cursor.bpp) > sizeof cursor.image) {
|
||||
if (cursor.width > 256
|
||||
|| cursor.height > 256
|
||||
|| cursor.bpp > 32
|
||||
|| SVGA_BITMAP_SIZE(x, y)
|
||||
> sizeof(cursor.mask) / sizeof(cursor.mask[0])
|
||||
|| SVGA_PIXMAP_SIZE(x, y, cursor.bpp)
|
||||
> sizeof(cursor.image) / sizeof(cursor.image[0])) {
|
||||
goto badcmd;
|
||||
}
|
||||
|
||||
|
@@ -460,7 +460,7 @@ static void rc4030_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
break;
|
||||
/* Interval timer reload */
|
||||
case 0x0228:
|
||||
s->itr = val;
|
||||
s->itr = val & 0x01FF;
|
||||
qemu_irq_lower(s->timer_irq);
|
||||
set_next_tick(s);
|
||||
break;
|
||||
|
@@ -314,6 +314,28 @@ static void xen_platform_ioport_writeb(void *opaque, hwaddr addr,
|
||||
case 0: /* Platform flags */
|
||||
platform_fixed_ioport_writeb(opaque, 0, (uint32_t)val);
|
||||
break;
|
||||
case 4:
|
||||
if (val == 1 && size == 1) {
|
||||
/*
|
||||
* SUSE unplug for Xenlinux
|
||||
* xen-kmp used this since xen-3.0.4, instead the official protocol from xen-3.3+
|
||||
* It did an unconditional "outl(1, (ioaddr + 4));"
|
||||
* This approach was used until openSUSE 12.3, up to SLE11SP3 and in SLE10.
|
||||
* Starting with openSUSE 13.1, SLE11SP4 and SLE12 the official protocol is used.
|
||||
* pre VMDP 1.7 made use of 4 and 8 depending on how vmdp was configured.
|
||||
* If VMDP was to control both disk and LAN it would use 4.
|
||||
* If it controlled just disk or just LAN, it would use 8 below.
|
||||
*/
|
||||
PCIDevice *pci_dev = PCI_DEVICE(s);
|
||||
DPRINTF("unplug disks\n");
|
||||
blk_drain_all();
|
||||
blk_flush_all();
|
||||
pci_unplug_disks(pci_dev->bus);
|
||||
DPRINTF("unplug nics\n");
|
||||
pci_unplug_nics(pci_dev->bus);
|
||||
DPRINTF("done\n");
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
log_writeb(s, (uint32_t)val);
|
||||
break;
|
||||
|
@@ -1843,6 +1843,7 @@ static void pci_nic_uninit(PCIDevice *pci_dev)
|
||||
EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
|
||||
|
||||
vmstate_unregister(&pci_dev->qdev, s->vmstate, s);
|
||||
g_free(s->vmstate);
|
||||
eeprom93xx_free(&pci_dev->qdev, s->eeprom);
|
||||
qemu_del_nic(s->nic);
|
||||
}
|
||||
|
@@ -220,6 +220,8 @@ static const VMStateDescription vmstate_imx_eth = {
|
||||
#define PHY_INT_PARFAULT (1 << 2)
|
||||
#define PHY_INT_AUTONEG_PAGE (1 << 1)
|
||||
|
||||
#define IMX_MAX_DESC 1024
|
||||
|
||||
static void imx_eth_update(IMXFECState *s);
|
||||
|
||||
/*
|
||||
@@ -402,12 +404,12 @@ static void imx_eth_update(IMXFECState *s)
|
||||
|
||||
static void imx_fec_do_tx(IMXFECState *s)
|
||||
{
|
||||
int frame_size = 0;
|
||||
int frame_size = 0, descnt = 0;
|
||||
uint8_t frame[ENET_MAX_FRAME_SIZE];
|
||||
uint8_t *ptr = frame;
|
||||
uint32_t addr = s->tx_descriptor;
|
||||
|
||||
while (1) {
|
||||
while (descnt++ < IMX_MAX_DESC) {
|
||||
IMXFECBufDesc bd;
|
||||
int len;
|
||||
|
||||
|
@@ -23,6 +23,7 @@ do { printf("mcf_fec: " fmt , ## __VA_ARGS__); } while (0)
|
||||
#define DPRINTF(fmt, ...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#define FEC_MAX_DESC 1024
|
||||
#define FEC_MAX_FRAME_SIZE 2032
|
||||
|
||||
typedef struct {
|
||||
@@ -149,7 +150,7 @@ static void mcf_fec_do_tx(mcf_fec_state *s)
|
||||
uint32_t addr;
|
||||
mcf_fec_bd bd;
|
||||
int frame_size;
|
||||
int len;
|
||||
int len, descnt = 0;
|
||||
uint8_t frame[FEC_MAX_FRAME_SIZE];
|
||||
uint8_t *ptr;
|
||||
|
||||
@@ -157,7 +158,7 @@ static void mcf_fec_do_tx(mcf_fec_state *s)
|
||||
ptr = frame;
|
||||
frame_size = 0;
|
||||
addr = s->tx_descriptor;
|
||||
while (1) {
|
||||
while (descnt++ < FEC_MAX_DESC) {
|
||||
mcf_fec_read_bd(&bd, addr);
|
||||
DPRINTF("tx_bd %x flags %04x len %d data %08x\n",
|
||||
addr, bd.flags, bd.length, bd.data);
|
||||
|
@@ -1429,8 +1429,11 @@ static void pcnet_csr_writew(PCNetState *s, uint32_t rap, uint32_t new_value)
|
||||
case 47: /* POLLINT */
|
||||
case 72:
|
||||
case 74:
|
||||
break;
|
||||
case 76: /* RCVRL */
|
||||
case 78: /* XMTRL */
|
||||
val = (val > 0) ? val : 512;
|
||||
break;
|
||||
case 112:
|
||||
if (CSR_STOP(s) || CSR_SPND(s))
|
||||
break;
|
||||
|
@@ -860,7 +860,7 @@ static void rocker_io_writel(void *opaque, hwaddr addr, uint32_t val)
|
||||
rocker_msix_irq(r, val);
|
||||
break;
|
||||
case ROCKER_TEST_DMA_SIZE:
|
||||
r->test_dma_size = val;
|
||||
r->test_dma_size = val & 0xFFFF;
|
||||
break;
|
||||
case ROCKER_TEST_DMA_ADDR + 4:
|
||||
r->test_dma_addr = ((uint64_t)val) << 32 | r->lower32;
|
||||
|
@@ -2350,7 +2350,7 @@ static void rtl8139_cplus_transmit(RTL8139State *s)
|
||||
{
|
||||
int txcount = 0;
|
||||
|
||||
while (rtl8139_cplus_transmit_one(s))
|
||||
while (txcount < 64 && rtl8139_cplus_transmit_one(s))
|
||||
{
|
||||
++txcount;
|
||||
}
|
||||
|
@@ -531,6 +531,7 @@ static void vmxnet3_complete_packet(VMXNET3State *s, int qidx, uint32_t tx_ridx)
|
||||
|
||||
VMXNET3_RING_DUMP(VMW_RIPRN, "TXC", qidx, &s->txq_descr[qidx].comp_ring);
|
||||
|
||||
memset(&txcq_descr, 0, sizeof(txcq_descr));
|
||||
txcq_descr.txdIdx = tx_ridx;
|
||||
txcq_descr.gen = vmxnet3_ring_curr_gen(&s->txq_descr[qidx].comp_ring);
|
||||
|
||||
|
@@ -158,7 +158,7 @@ static size_t mptsas_config_pack(uint8_t **data, const char *fmt, ...)
|
||||
va_end(ap);
|
||||
|
||||
if (data) {
|
||||
assert(ret < 256 && (ret % 4) == 0);
|
||||
assert(ret / 4 < 256 && (ret % 4) == 0);
|
||||
stb_p(*data + 1, ret / 4);
|
||||
}
|
||||
return ret;
|
||||
@@ -203,7 +203,7 @@ size_t mptsas_config_manufacturing_1(MPTSASState *s, uint8_t **data, int address
|
||||
{
|
||||
/* VPD - all zeros */
|
||||
return MPTSAS_CONFIG_PACK(1, MPI_CONFIG_PAGETYPE_MANUFACTURING, 0x00,
|
||||
"s256");
|
||||
"*s256");
|
||||
}
|
||||
|
||||
static
|
||||
@@ -328,7 +328,7 @@ size_t mptsas_config_ioc_0(MPTSASState *s, uint8_t **data, int address)
|
||||
return MPTSAS_CONFIG_PACK(0, MPI_CONFIG_PAGETYPE_IOC, 0x01,
|
||||
"*l*lwwb*b*b*blww",
|
||||
pcic->vendor_id, pcic->device_id, pcic->revision,
|
||||
pcic->subsystem_vendor_id,
|
||||
pcic->class_id, pcic->subsystem_vendor_id,
|
||||
pcic->subsystem_id);
|
||||
}
|
||||
|
||||
|
@@ -304,7 +304,7 @@ static int mptsas_process_scsi_io_request(MPTSASState *s,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
req = g_new(MPTSASRequest, 1);
|
||||
req = g_new0(MPTSASRequest, 1);
|
||||
QTAILQ_INSERT_TAIL(&s->pending, req, next);
|
||||
req->scsi_io = *scsi_io;
|
||||
req->dev = s;
|
||||
|
@@ -40,6 +40,8 @@
|
||||
#define PVSCSI_MAX_DEVS (64)
|
||||
#define PVSCSI_MSIX_NUM_VECTORS (1)
|
||||
|
||||
#define PVSCSI_MAX_SG_ELEM 2048
|
||||
|
||||
#define PVSCSI_MAX_CMD_DATA_WORDS \
|
||||
(sizeof(PVSCSICmdDescSetupRings)/sizeof(uint32_t))
|
||||
|
||||
@@ -251,8 +253,11 @@ static hwaddr
|
||||
pvscsi_ring_pop_req_descr(PVSCSIRingInfo *mgr)
|
||||
{
|
||||
uint32_t ready_ptr = RS_GET_FIELD(mgr, reqProdIdx);
|
||||
uint32_t ring_size = PVSCSI_MAX_NUM_PAGES_REQ_RING
|
||||
* PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
|
||||
|
||||
if (ready_ptr != mgr->consumed_ptr) {
|
||||
if (ready_ptr != mgr->consumed_ptr
|
||||
&& ready_ptr - mgr->consumed_ptr < ring_size) {
|
||||
uint32_t next_ready_ptr =
|
||||
mgr->consumed_ptr++ & mgr->txr_len_mask;
|
||||
uint32_t next_ready_page =
|
||||
@@ -634,17 +639,16 @@ pvscsi_queue_pending_descriptor(PVSCSIState *s, SCSIDevice **d,
|
||||
static void
|
||||
pvscsi_convert_sglist(PVSCSIRequest *r)
|
||||
{
|
||||
int chunk_size;
|
||||
uint32_t chunk_size, elmcnt = 0;
|
||||
uint64_t data_length = r->req.dataLen;
|
||||
PVSCSISGState sg = r->sg;
|
||||
while (data_length) {
|
||||
while (!sg.resid) {
|
||||
while (data_length && elmcnt < PVSCSI_MAX_SG_ELEM) {
|
||||
while (!sg.resid && elmcnt++ < PVSCSI_MAX_SG_ELEM) {
|
||||
pvscsi_get_next_sg_elem(&sg);
|
||||
trace_pvscsi_convert_sglist(r->req.context, r->sg.dataAddr,
|
||||
r->sg.resid);
|
||||
}
|
||||
assert(data_length > 0);
|
||||
chunk_size = MIN((unsigned) data_length, sg.resid);
|
||||
chunk_size = MIN(data_length, sg.resid);
|
||||
if (chunk_size) {
|
||||
qemu_sglist_add(&r->sgl, sg.dataAddr, chunk_size);
|
||||
}
|
||||
|
@@ -1426,6 +1426,7 @@ static int ehci_process_itd(EHCIState *ehci,
|
||||
if (off + len > 4096) {
|
||||
/* transfer crosses page border */
|
||||
if (pg == 6) {
|
||||
qemu_sglist_destroy(&ehci->isgl);
|
||||
return -1; /* avoid page pg + 1 */
|
||||
}
|
||||
ptr2 = (itd->bufptr[pg + 1] & ITD_BUFPTR_MASK);
|
||||
|
@@ -54,6 +54,8 @@
|
||||
* to the specs when it gets them */
|
||||
#define ER_FULL_HACK
|
||||
|
||||
#define TRB_LINK_LIMIT 4
|
||||
|
||||
#define LEN_CAP 0x40
|
||||
#define LEN_OPER (0x400 + 0x10 * MAXPORTS)
|
||||
#define LEN_RUNTIME ((MAXINTRS + 1) * 0x20)
|
||||
@@ -1000,6 +1002,7 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb,
|
||||
dma_addr_t *addr)
|
||||
{
|
||||
PCIDevice *pci_dev = PCI_DEVICE(xhci);
|
||||
uint32_t link_cnt = 0;
|
||||
|
||||
while (1) {
|
||||
TRBType type;
|
||||
@@ -1026,6 +1029,9 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb,
|
||||
ring->dequeue += TRB_SIZE;
|
||||
return type;
|
||||
} else {
|
||||
if (++link_cnt > TRB_LINK_LIMIT) {
|
||||
return 0;
|
||||
}
|
||||
ring->dequeue = xhci_mask64(trb->parameter);
|
||||
if (trb->control & TRB_LK_TC) {
|
||||
ring->ccs = !ring->ccs;
|
||||
@@ -1043,6 +1049,7 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring)
|
||||
bool ccs = ring->ccs;
|
||||
/* hack to bundle together the two/three TDs that make a setup transfer */
|
||||
bool control_td_set = 0;
|
||||
uint32_t link_cnt = 0;
|
||||
|
||||
while (1) {
|
||||
TRBType type;
|
||||
@@ -1058,6 +1065,9 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring)
|
||||
type = TRB_TYPE(trb);
|
||||
|
||||
if (type == TR_LINK) {
|
||||
if (++link_cnt > TRB_LINK_LIMIT) {
|
||||
return -length;
|
||||
}
|
||||
dequeue = xhci_mask64(trb.parameter);
|
||||
if (trb.control & TRB_LK_TC) {
|
||||
ccs = !ccs;
|
||||
@@ -3709,8 +3719,7 @@ static void usb_xhci_exit(PCIDevice *dev)
|
||||
/* destroy msix memory region */
|
||||
if (dev->msix_table && dev->msix_pba
|
||||
&& dev->msix_entry_used) {
|
||||
memory_region_del_subregion(&xhci->mem, &dev->msix_table_mmio);
|
||||
memory_region_del_subregion(&xhci->mem, &dev->msix_pba_mmio);
|
||||
msix_uninit(dev, &xhci->mem, &xhci->mem);
|
||||
}
|
||||
|
||||
usb_bus_release(&xhci->bus);
|
||||
|
@@ -473,6 +473,11 @@ static void virtqueue_map_desc(unsigned int *p_num_sg, hwaddr *addr, struct iove
|
||||
}
|
||||
|
||||
iov[num_sg].iov_base = cpu_physical_memory_map(pa, &len, is_write);
|
||||
if (!iov[num_sg].iov_base) {
|
||||
error_report("virtio: bogus descriptor or out of resources");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
iov[num_sg].iov_len = len;
|
||||
addr[num_sg] = pa;
|
||||
|
||||
|
@@ -401,7 +401,7 @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, target_ulong addr,
|
||||
int access_type, int mmu_idx)
|
||||
{
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
return g2h(vaddr);
|
||||
return g2h(addr);
|
||||
#else
|
||||
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
|
||||
CPUTLBEntry *tlbentry = &env->tlb_table[mmu_idx][index];
|
||||
|
@@ -37,6 +37,7 @@ typedef enum argtype {
|
||||
TYPE_ARRAY,
|
||||
TYPE_STRUCT,
|
||||
TYPE_OLDDEVT,
|
||||
TYPE_INTBITFIELD,
|
||||
} argtype;
|
||||
|
||||
#define MK_PTR(type) TYPE_PTR, type
|
||||
@@ -89,6 +90,7 @@ static inline int thunk_type_size(const argtype *type_ptr, int is_host)
|
||||
case TYPE_SHORT:
|
||||
return 2;
|
||||
case TYPE_INT:
|
||||
case TYPE_INTBITFIELD:
|
||||
return 4;
|
||||
case TYPE_LONGLONG:
|
||||
case TYPE_ULONGLONG:
|
||||
@@ -151,6 +153,7 @@ static inline int thunk_type_align(const argtype *type_ptr, int is_host)
|
||||
case TYPE_SHORT:
|
||||
return 2;
|
||||
case TYPE_INT:
|
||||
case TYPE_INTBITFIELD:
|
||||
return 4;
|
||||
case TYPE_LONGLONG:
|
||||
case TYPE_ULONGLONG:
|
||||
|
@@ -6,3 +6,5 @@ obj-$(TARGET_HAS_BFLT) += flatload.o
|
||||
obj-$(TARGET_I386) += vm86.o
|
||||
obj-$(TARGET_ARM) += arm/nwfpe/
|
||||
obj-$(TARGET_M68K) += m68k-sim.o
|
||||
|
||||
obj-binfmt-y = binfmt.o
|
||||
|
68
linux-user/binfmt.c
Normal file
68
linux-user/binfmt.c
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define ARCH_NAME "x86_64"
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
char *binfmt;
|
||||
char **new_argv;
|
||||
|
||||
/*
|
||||
* Check if our file name ends with -binfmt
|
||||
*/
|
||||
binfmt = argv[0] + strlen(argv[0]) - strlen("-binfmt");
|
||||
if (strcmp(binfmt, "-binfmt")) {
|
||||
fprintf(stderr, "%s: Invalid executable name\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "%s: Please use me through binfmt with P flag\n",
|
||||
argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
binfmt[0] = '\0';
|
||||
/* Now argv[0] is the real qemu binary name */
|
||||
|
||||
#ifdef ARCH_NAME
|
||||
{
|
||||
char *hostbin;
|
||||
char *guestarch;
|
||||
int r;
|
||||
|
||||
guestarch = strrchr(argv[0], '-') ;
|
||||
if (!guestarch) {
|
||||
goto skip;
|
||||
}
|
||||
guestarch++;
|
||||
r = asprintf(&hostbin, "/emul/" ARCH_NAME "-for-%s/%s", guestarch, argv[1]);
|
||||
if ((r > 0) && !access(hostbin, X_OK)) {
|
||||
/*
|
||||
* We found a host binary replacement for the non-host binary. Let's
|
||||
* use that instead!
|
||||
*/
|
||||
return execve(hostbin, &argv[2], envp);
|
||||
}
|
||||
}
|
||||
skip:
|
||||
#endif
|
||||
|
||||
new_argv = (char **)malloc((argc + 2) * sizeof(*new_argv));
|
||||
if (argc > 3) {
|
||||
memcpy(&new_argv[4], &argv[3], (argc - 3) * sizeof(*new_argv));
|
||||
}
|
||||
new_argv[0] = argv[0];
|
||||
new_argv[1] = (char *)"-0";
|
||||
new_argv[2] = argv[2];
|
||||
new_argv[3] = argv[1];
|
||||
new_argv[argc + 1] = NULL;
|
||||
|
||||
return execve(new_argv[0], new_argv, envp);
|
||||
}
|
@@ -119,6 +119,8 @@
|
||||
IOCTL_SPECIAL(FS_IOC_FIEMAP, IOC_W | IOC_R, do_ioctl_fs_ioc_fiemap,
|
||||
MK_PTR(MK_STRUCT(STRUCT_fiemap)))
|
||||
#endif
|
||||
IOCTL(FS_IOC_GETFLAGS, IOC_R, MK_PTR(TYPE_LONG))
|
||||
IOCTL(FS_IOC_SETFLAGS, IOC_W, MK_PTR(TYPE_LONG))
|
||||
|
||||
IOCTL(SIOCATMARK, IOC_R, MK_PTR(TYPE_INT))
|
||||
IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
|
||||
@@ -348,6 +350,11 @@
|
||||
IOCTL(VFAT_IOCTL_READDIR_BOTH, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2)))
|
||||
IOCTL(VFAT_IOCTL_READDIR_SHORT, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2)))
|
||||
|
||||
/* FIXME: including these on x86 / x86_64 breaks qemu-i386 */
|
||||
#ifdef __powerpc__
|
||||
#include "ioctls_alsa.h"
|
||||
#endif
|
||||
|
||||
IOCTL(LOOP_SET_FD, 0, TYPE_INT)
|
||||
IOCTL(LOOP_CLR_FD, 0, TYPE_INT)
|
||||
IOCTL(LOOP_SET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
|
||||
|
467
linux-user/ioctls_alsa.h
Normal file
467
linux-user/ioctls_alsa.h
Normal file
@@ -0,0 +1,467 @@
|
||||
#define SNDRV_SEQ_IOCTL_PVERSION _IOR ('S', 0x00, int)
|
||||
#define SNDRV_SEQ_IOCTL_CLIENT_ID _IOR ('S', 0x01, int)
|
||||
#define SNDRV_SEQ_IOCTL_SYSTEM_INFO _IOWR('S', 0x02, struct sndrv_seq_system_info)
|
||||
#define SNDRV_SEQ_IOCTL_RUNNING_MODE _IOWR('S', 0x03, struct sndrv_seq_running_info)
|
||||
#define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO _IOWR('S', 0x10, struct sndrv_seq_client_info)
|
||||
#define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO _IOW ('S', 0x11, struct sndrv_seq_client_info)
|
||||
#define SNDRV_SEQ_IOCTL_CREATE_PORT _IOWR('S', 0x20, struct sndrv_seq_port_info)
|
||||
#define SNDRV_SEQ_IOCTL_DELETE_PORT _IOW ('S', 0x21, struct sndrv_seq_port_info)
|
||||
#define SNDRV_SEQ_IOCTL_GET_PORT_INFO _IOWR('S', 0x22, struct sndrv_seq_port_info)
|
||||
#define SNDRV_SEQ_IOCTL_SET_PORT_INFO _IOW ('S', 0x23, struct sndrv_seq_port_info)
|
||||
#define SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT _IOW ('S', 0x30, struct sndrv_seq_port_subscribe)
|
||||
#define SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT _IOW ('S', 0x31, struct sndrv_seq_port_subscribe)
|
||||
#define SNDRV_SEQ_IOCTL_CREATE_QUEUE _IOWR('S', 0x32, struct sndrv_seq_queue_info)
|
||||
#define SNDRV_SEQ_IOCTL_DELETE_QUEUE _IOW ('S', 0x33, struct sndrv_seq_queue_info)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_INFO _IOWR('S', 0x34, struct sndrv_seq_queue_info)
|
||||
#define SNDRV_SEQ_IOCTL_SET_QUEUE_INFO _IOWR('S', 0x35, struct sndrv_seq_queue_info)
|
||||
#define SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE _IOWR('S', 0x36, struct sndrv_seq_queue_info)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS _IOWR('S', 0x40, struct sndrv_seq_queue_status)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO _IOWR('S', 0x41, struct sndrv_seq_queue_tempo)
|
||||
#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO _IOW ('S', 0x42, struct sndrv_seq_queue_tempo)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER _IOWR('S', 0x43, struct sndrv_seq_queue_owner)
|
||||
#define SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER _IOW ('S', 0x44, struct sndrv_seq_queue_owner)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER _IOWR('S', 0x45, struct sndrv_seq_queue_timer)
|
||||
#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER _IOW ('S', 0x46, struct sndrv_seq_queue_timer)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC _IOWR('S', 0x53, struct sndrv_seq_queue_sync)
|
||||
#define SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC _IOW ('S', 0x54, struct sndrv_seq_queue_sync)
|
||||
#define SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT _IOWR('S', 0x49, struct sndrv_seq_queue_client)
|
||||
#define SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT _IOW ('S', 0x4a, struct sndrv_seq_queue_client)
|
||||
#define SNDRV_SEQ_IOCTL_GET_CLIENT_POOL _IOWR('S', 0x4b, struct sndrv_seq_client_pool)
|
||||
#define SNDRV_SEQ_IOCTL_SET_CLIENT_POOL _IOW ('S', 0x4c, struct sndrv_seq_client_pool)
|
||||
#define SNDRV_SEQ_IOCTL_REMOVE_EVENTS _IOW ('S', 0x4e, struct sndrv_seq_remove_events)
|
||||
#define SNDRV_SEQ_IOCTL_QUERY_SUBS _IOWR('S', 0x4f, struct sndrv_seq_query_subs)
|
||||
#define SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION _IOWR('S', 0x50, struct sndrv_seq_port_subscribe)
|
||||
#define SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT _IOWR('S', 0x51, struct sndrv_seq_client_info)
|
||||
#define SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT _IOWR('S', 0x52, struct sndrv_seq_port_info)
|
||||
#define SNDRV_DM_FM_IOCTL_INFO _IOR('H', 0x20, snd_dm_fm_info_t)
|
||||
#define SNDRV_DM_FM_IOCTL_RESET _IO ('H', 0x21)
|
||||
#define SNDRV_DM_FM_IOCTL_PLAY_NOTE _IOW('H', 0x22, snd_dm_fm_note_t)
|
||||
#define SNDRV_DM_FM_IOCTL_SET_VOICE _IOW('H', 0x23, snd_dm_fm_voice_t)
|
||||
#define SNDRV_DM_FM_IOCTL_SET_PARAMS _IOW('H', 0x24, snd_dm_fm_params_t)
|
||||
#define SNDRV_DM_FM_IOCTL_SET_MODE _IOW('H', 0x25, int)
|
||||
#define SNDRV_DM_FM_IOCTL_SET_CONNECTION _IOW('H', 0x26, int)
|
||||
#define SNDRV_DM_FM_OSS_IOCTL_RESET 0x20
|
||||
#define SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21
|
||||
#define SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22
|
||||
#define SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23
|
||||
#define SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24
|
||||
#define SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25
|
||||
#define SNDRV_HWDEP_IOCTL_PVERSION _IOR ('H', 0x00, int)
|
||||
#define SNDRV_HWDEP_IOCTL_INFO _IOR ('H', 0x01, struct sndrv_hwdep_info)
|
||||
#define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct sndrv_hwdep_dsp_status)
|
||||
#define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct sndrv_hwdep_dsp_image)
|
||||
#define SNDRV_PCM_IOCTL_PVERSION _IOR('A', 0x00, int)
|
||||
#define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct sndrv_pcm_info)
|
||||
#define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int)
|
||||
#define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct sndrv_pcm_hw_params)
|
||||
#define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct sndrv_pcm_hw_params)
|
||||
#define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12)
|
||||
#define SNDRV_PCM_IOCTL_SW_PARAMS _IOWR('A', 0x13, struct sndrv_pcm_sw_params)
|
||||
#define SNDRV_PCM_IOCTL_STATUS _IOR('A', 0x20, struct sndrv_pcm_status)
|
||||
#define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, sndrv_pcm_sframes_t)
|
||||
#define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22)
|
||||
#define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr)
|
||||
#define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct sndrv_pcm_channel_info)
|
||||
#define SNDRV_PCM_IOCTL_PREPARE _IO('A', 0x40)
|
||||
#define SNDRV_PCM_IOCTL_RESET _IO('A', 0x41)
|
||||
#define SNDRV_PCM_IOCTL_START _IO('A', 0x42)
|
||||
#define SNDRV_PCM_IOCTL_DROP _IO('A', 0x43)
|
||||
#define SNDRV_PCM_IOCTL_DRAIN _IO('A', 0x44)
|
||||
#define SNDRV_PCM_IOCTL_PAUSE _IOW('A', 0x45, int)
|
||||
#define SNDRV_PCM_IOCTL_REWIND _IOW('A', 0x46, sndrv_pcm_uframes_t)
|
||||
#define SNDRV_PCM_IOCTL_RESUME _IO('A', 0x47)
|
||||
#define SNDRV_PCM_IOCTL_XRUN _IO('A', 0x48)
|
||||
#define SNDRV_PCM_IOCTL_FORWARD _IOW('A', 0x49, sndrv_pcm_uframes_t)
|
||||
#define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct sndrv_xferi)
|
||||
#define SNDRV_PCM_IOCTL_READI_FRAMES _IOR('A', 0x51, struct sndrv_xferi)
|
||||
#define SNDRV_PCM_IOCTL_WRITEN_FRAMES _IOW('A', 0x52, struct sndrv_xfern)
|
||||
#define SNDRV_PCM_IOCTL_READN_FRAMES _IOR('A', 0x53, struct sndrv_xfern)
|
||||
#define SNDRV_PCM_IOCTL_LINK _IOW('A', 0x60, int)
|
||||
#define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61)
|
||||
#define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int)
|
||||
#define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct sndrv_rawmidi_info)
|
||||
#define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct sndrv_rawmidi_params)
|
||||
#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct sndrv_rawmidi_status)
|
||||
#define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int)
|
||||
#define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int)
|
||||
#define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int)
|
||||
#define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct sndrv_timer_id)
|
||||
#define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int)
|
||||
#define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct sndrv_timer_ginfo)
|
||||
#define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct sndrv_timer_gparams)
|
||||
#define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct sndrv_timer_gstatus)
|
||||
#define SNDRV_TIMER_IOCTL_SELECT _IOW('T', 0x10, struct sndrv_timer_select)
|
||||
#define SNDRV_TIMER_IOCTL_INFO _IOR('T', 0x11, struct sndrv_timer_info)
|
||||
#define SNDRV_TIMER_IOCTL_PARAMS _IOW('T', 0x12, struct sndrv_timer_params)
|
||||
#define SNDRV_TIMER_IOCTL_STATUS _IOR('T', 0x14, struct sndrv_timer_status)
|
||||
#define SNDRV_TIMER_IOCTL_START _IO('T', 0xa0)
|
||||
#define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1)
|
||||
#define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2)
|
||||
#define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3)
|
||||
#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int)
|
||||
#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct sndrv_ctl_card_info)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct sndrv_ctl_elem_list)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct sndrv_ctl_elem_info)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct sndrv_ctl_elem_value)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_WRITE _IOWR('U', 0x13, struct sndrv_ctl_elem_value)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_LOCK _IOW('U', 0x14, struct sndrv_ctl_elem_id)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_UNLOCK _IOW('U', 0x15, struct sndrv_ctl_elem_id)
|
||||
#define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_ADD _IOWR('U', 0x17, struct sndrv_ctl_elem_info)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_REPLACE _IOWR('U', 0x18, struct sndrv_ctl_elem_info)
|
||||
#define SNDRV_CTL_IOCTL_ELEM_REMOVE _IOWR('U', 0x19, struct sndrv_ctl_elem_id)
|
||||
#define SNDRV_CTL_IOCTL_TLV_READ _IOWR('U', 0x1a, struct sndrv_ctl_tlv)
|
||||
#define SNDRV_CTL_IOCTL_TLV_WRITE _IOWR('U', 0x1b, struct sndrv_ctl_tlv)
|
||||
#define SNDRV_CTL_IOCTL_TLV_COMMAND _IOWR('U', 0x1c, struct sndrv_ctl_tlv)
|
||||
#define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int)
|
||||
#define SNDRV_CTL_IOCTL_HWDEP_INFO _IOR('U', 0x21, struct sndrv_hwdep_info)
|
||||
#define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE _IOR('U', 0x30, int)
|
||||
#define SNDRV_CTL_IOCTL_PCM_INFO _IOWR('U', 0x31, struct sndrv_pcm_info)
|
||||
#define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int)
|
||||
#define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int)
|
||||
#define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct sndrv_rawmidi_info)
|
||||
#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int)
|
||||
#define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int)
|
||||
#define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int)
|
||||
#define SNDRV_IOCTL_READV _IOW('K', 0x00, struct sndrv_xferv)
|
||||
#define SNDRV_IOCTL_WRITEV _IOW('K', 0x01, struct sndrv_xferv)
|
||||
#define SNDRV_EMU10K1_IOCTL_INFO _IOR ('H', 0x10, emu10k1_fx8010_info_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_CODE_POKE _IOW ('H', 0x11, emu10k1_fx8010_code_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_CODE_PEEK _IOWR('H', 0x12, emu10k1_fx8010_code_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_TRAM_SETUP _IOW ('H', 0x20, int)
|
||||
#define SNDRV_EMU10K1_IOCTL_TRAM_POKE _IOW ('H', 0x21, emu10k1_fx8010_tram_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK _IOWR('H', 0x22, emu10k1_fx8010_tram_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_PCM_POKE _IOW ('H', 0x30, emu10k1_fx8010_pcm_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_PCM_PEEK _IOWR('H', 0x31, emu10k1_fx8010_pcm_t)
|
||||
#define SNDRV_EMU10K1_IOCTL_PVERSION _IOR ('H', 0x40, int)
|
||||
#define SNDRV_EMU10K1_IOCTL_STOP _IO ('H', 0x80)
|
||||
#define SNDRV_EMU10K1_IOCTL_CONTINUE _IO ('H', 0x81)
|
||||
#define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82)
|
||||
#define SNDRV_EMU10K1_IOCTL_SINGLE_STEP _IOW ('H', 0x83, int)
|
||||
#define SNDRV_EMU10K1_IOCTL_DBG_READ _IOR ('H', 0x84, int)
|
||||
#define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, hdsp_peak_rms_t)
|
||||
#define SNDRV_HDSP_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, hdsp_config_info_t)
|
||||
#define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, hdsp_firmware_t)
|
||||
#define SNDRV_HDSP_IOCTL_GET_VERSION _IOR('H', 0x43, hdsp_version_t)
|
||||
#define SNDRV_HDSP_IOCTL_GET_MIXER _IOR('H', 0x44, hdsp_mixer_t)
|
||||
#define SNDRV_HDSP_IOCTL_GET_9632_AEB _IOR('H', 0x45, hdsp_9632_aeb_t)
|
||||
#define SNDRV_SB_CSP_IOCTL_INFO _IOR('H', 0x10, snd_sb_csp_info_t)
|
||||
#define SNDRV_SB_CSP_IOCTL_LOAD_CODE _IOW('H', 0x11, snd_sb_csp_microcode_t)
|
||||
#define SNDRV_SB_CSP_IOCTL_UNLOAD_CODE _IO('H', 0x12)
|
||||
#define SNDRV_SB_CSP_IOCTL_START _IOW('H', 0x13, snd_sb_csp_start_t)
|
||||
#define SNDRV_SB_CSP_IOCTL_STOP _IO('H', 0x14)
|
||||
#define SNDRV_SB_CSP_IOCTL_PAUSE _IO('H', 0x15)
|
||||
#define SNDRV_SB_CSP_IOCTL_RESTART _IO('H', 0x16)
|
||||
#define SND_SSCAPE_LOAD_BOOTB _IOWR('P', 100, struct sscape_bootblock)
|
||||
#define SND_SSCAPE_LOAD_MCODE _IOW ('P', 101, struct sscape_microcode)
|
||||
|
||||
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_PVERSION TARGET_IOR ('S', 0x00, int)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_CLIENT_ID TARGET_IOR ('S', 0x01, int)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SYSTEM_INFO TARGET_IOWRU('S', 0x02)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_RUNNING_MODE TARGET_IOWRU('S', 0x03)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_CLIENT_INFO TARGET_IOWRU('S', 0x10)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_CLIENT_INFO TARGET_IOWU ('S', 0x11)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_CREATE_PORT TARGET_IOWRU('S', 0x20)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_DELETE_PORT TARGET_IOWU ('S', 0x21)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_PORT_INFO TARGET_IOWRU('S', 0x22)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_PORT_INFO TARGET_IOWU ('S', 0x23)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT TARGET_IOWU ('S', 0x30)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT TARGET_IOWU ('S', 0x31)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_CREATE_QUEUE TARGET_IOWRU('S', 0x32)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_DELETE_QUEUE TARGET_IOWU ('S', 0x33)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_INFO TARGET_IOWRU('S', 0x34)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_INFO TARGET_IOWRU('S', 0x35)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE TARGET_IOWRU('S', 0x36)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS TARGET_IOWRU('S', 0x40)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO TARGET_IOWRU('S', 0x41)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO TARGET_IOWU ('S', 0x42)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER TARGET_IOWRU('S', 0x43)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER TARGET_IOWU ('S', 0x44)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER TARGET_IOWRU('S', 0x45)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER TARGET_IOWU ('S', 0x46)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC TARGET_IOWRU('S', 0x53)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC TARGET_IOWU ('S', 0x54)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT TARGET_IOWRU('S', 0x49)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT TARGET_IOWU ('S', 0x4a)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_CLIENT_POOL TARGET_IOWRU('S', 0x4b)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_SET_CLIENT_POOL TARGET_IOWU ('S', 0x4c)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_REMOVE_EVENTS TARGET_IOWU ('S', 0x4e)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_QUERY_SUBS TARGET_IOWRU('S', 0x4f)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION TARGET_IOWRU('S', 0x50)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT TARGET_IOWRU('S', 0x51)
|
||||
#define TARGET_SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT TARGET_IOWRU('S', 0x52)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_INFO TARGET_IORU('H', 0x20)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_RESET TARGET_IO ('H', 0x21)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_PLAY_NOTE TARGET_IOWU('H', 0x22)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_SET_VOICE TARGET_IOWU('H', 0x23)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_SET_PARAMS TARGET_IOWU('H', 0x24)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_SET_MODE TARGET_IOW('H', 0x25, int)
|
||||
#define TARGET_SNDRV_DM_FM_IOCTL_SET_CONNECTION TARGET_IOW('H', 0x26, int)
|
||||
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_RESET 0x20
|
||||
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21
|
||||
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22
|
||||
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23
|
||||
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24
|
||||
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25
|
||||
#define TARGET_SNDRV_HWDEP_IOCTL_PVERSION TARGET_IOR ('H', 0x00, int)
|
||||
#define TARGET_SNDRV_HWDEP_IOCTL_INFO TARGET_IORU ('H', 0x01)
|
||||
#define TARGET_SNDRV_HWDEP_IOCTL_DSP_STATUS TARGET_IORU('H', 0x02)
|
||||
#define TARGET_SNDRV_HWDEP_IOCTL_DSP_LOAD TARGET_IOWU('H', 0x03)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_PVERSION TARGET_IOR('A', 0x00, int)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_INFO TARGET_IORU('A', 0x01)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_TSTAMP TARGET_IOW('A', 0x02, int)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_HW_REFINE TARGET_IOWRU('A', 0x10)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_HW_PARAMS TARGET_IOWRU('A', 0x11)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_HW_FREE TARGET_IO('A', 0x12)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_SW_PARAMS TARGET_IOWRU('A', 0x13)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_STATUS TARGET_IORU('A', 0x20)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_DELAY TARGET_IORU('A', 0x21)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_HWSYNC TARGET_IO('A', 0x22)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_SYNC_PTR TARGET_IOWRU('A', 0x23)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_CHANNEL_INFO TARGET_IORU('A', 0x32)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_PREPARE TARGET_IO('A', 0x40)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_RESET TARGET_IO('A', 0x41)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_START TARGET_IO('A', 0x42)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_DROP TARGET_IO('A', 0x43)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_DRAIN TARGET_IO('A', 0x44)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_PAUSE TARGET_IOW('A', 0x45, int)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_REWIND TARGET_IOWU('A', 0x46)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_RESUME TARGET_IO('A', 0x47)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_XRUN TARGET_IO('A', 0x48)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_FORWARD TARGET_IOWU('A', 0x49)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_WRITEI_FRAMES TARGET_IOWU('A', 0x50)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_READI_FRAMES TARGET_IORU('A', 0x51)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_WRITEN_FRAMES TARGET_IOWU('A', 0x52)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_READN_FRAMES TARGET_IORU('A', 0x53)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_LINK TARGET_IOW('A', 0x60, int)
|
||||
#define TARGET_SNDRV_PCM_IOCTL_UNLINK TARGET_IO('A', 0x61)
|
||||
#define TARGET_SNDRV_RAWMIDI_IOCTL_PVERSION TARGET_IOR('W', 0x00, int)
|
||||
#define TARGET_SNDRV_RAWMIDI_IOCTL_INFO TARGET_IORU('W', 0x01)
|
||||
#define TARGET_SNDRV_RAWMIDI_IOCTL_PARAMS TARGET_IOWRU('W', 0x10)
|
||||
#define TARGET_SNDRV_RAWMIDI_IOCTL_STATUS TARGET_IOWRU('W', 0x20)
|
||||
#define TARGET_SNDRV_RAWMIDI_IOCTL_DROP TARGET_IOW('W', 0x30, int)
|
||||
#define TARGET_SNDRV_RAWMIDI_IOCTL_DRAIN TARGET_IOW('W', 0x31, int)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_PVERSION TARGET_IOR('T', 0x00, int)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_NEXT_DEVICE TARGET_IOWRU('T', 0x01)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_TREAD TARGET_IOW('T', 0x02, int)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_GINFO TARGET_IOWRU('T', 0x03)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_GPARAMS TARGET_IOWU('T', 0x04)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_GSTATUS TARGET_IOWRU('T', 0x05)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_SELECT TARGET_IOWU('T', 0x10)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_INFO TARGET_IORU('T', 0x11)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_PARAMS TARGET_IOWU('T', 0x12)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_STATUS TARGET_IORU('T', 0x14)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_START TARGET_IO('T', 0xa0)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_STOP TARGET_IO('T', 0xa1)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_CONTINUE TARGET_IO('T', 0xa2)
|
||||
#define TARGET_SNDRV_TIMER_IOCTL_PAUSE TARGET_IO('T', 0xa3)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_PVERSION TARGET_IOR('U', 0x00, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_CARD_INFO TARGET_IORU('U', 0x01)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_LIST TARGET_IOWRU('U', 0x10)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_INFO TARGET_IOWRU('U', 0x11)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_READ TARGET_IOWRU('U', 0x12)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_WRITE TARGET_IOWRU('U', 0x13)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_LOCK TARGET_IOWU('U', 0x14)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_UNLOCK TARGET_IOWU('U', 0x15)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS TARGET_IOWR('U', 0x16, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_ADD TARGET_IOWRU('U', 0x17)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_REPLACE TARGET_IOWRU('U', 0x18)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_ELEM_REMOVE TARGET_IOWRU('U', 0x19)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_TLV_READ TARGET_IOWRU('U', 0x1a)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_TLV_WRITE TARGET_IOWRU('U', 0x1b)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_TLV_COMMAND TARGET_IOWRU('U', 0x1c)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE TARGET_IOWR('U', 0x20, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_HWDEP_INFO TARGET_IORU('U', 0x21)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE TARGET_IOR('U', 0x30, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_PCM_INFO TARGET_IOWRU('U', 0x31)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE TARGET_IOW('U', 0x32, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE TARGET_IOWR('U', 0x40, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_INFO TARGET_IOWRU('U', 0x41)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE TARGET_IOW('U', 0x42, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_POWER TARGET_IOWR('U', 0xd0, int)
|
||||
#define TARGET_SNDRV_CTL_IOCTL_POWER_STATE TARGET_IOR('U', 0xd1, int)
|
||||
#define TARGET_SNDRV_IOCTL_READV TARGET_IOWU('K', 0x00)
|
||||
#define TARGET_SNDRV_IOCTL_WRITEV TARGET_IOWU('K', 0x01)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_INFO TARGET_IORU ('H', 0x10)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_CODE_POKE TARGET_IOWU ('H', 0x11)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_CODE_PEEK TARGET_IOWRU('H', 0x12)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_SETUP TARGET_IOW ('H', 0x20, int)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_POKE TARGET_IOWU ('H', 0x21)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_PEEK TARGET_IOWRU('H', 0x22)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_PCM_POKE TARGET_IOWU ('H', 0x30)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_PCM_PEEK TARGET_IOWRU('H', 0x31)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_PVERSION TARGET_IOR ('H', 0x40, int)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_STOP TARGET_IO ('H', 0x80)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_CONTINUE TARGET_IO ('H', 0x81)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER TARGET_IO ('H', 0x82)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_SINGLE_STEP TARGET_IOW ('H', 0x83, int)
|
||||
#define TARGET_SNDRV_EMU10K1_IOCTL_DBG_READ TARGET_IOR ('H', 0x84, int)
|
||||
#define TARGET_SNDRV_HDSP_IOCTL_GET_PEAK_RMS TARGET_IORU('H', 0x40)
|
||||
#define TARGET_SNDRV_HDSP_IOCTL_GET_CONFIG_INFO TARGET_IORU('H', 0x41)
|
||||
#define TARGET_SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE TARGET_IOWU('H', 0x42)
|
||||
#define TARGET_SNDRV_HDSP_IOCTL_GET_VERSION TARGET_IORU('H', 0x43)
|
||||
#define TARGET_SNDRV_HDSP_IOCTL_GET_MIXER TARGET_IORU('H', 0x44)
|
||||
#define TARGET_SNDRV_HDSP_IOCTL_GET_9632_AEB TARGET_IORU('H', 0x45)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_INFO TARGET_IORU('H', 0x10)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_LOAD_CODE TARGET_IOWU('H', 0x11)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_UNLOAD_CODE TARGET_IO('H', 0x12)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_START TARGET_IOWU('H', 0x13)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_STOP TARGET_IO('H', 0x14)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_PAUSE TARGET_IO('H', 0x15)
|
||||
#define TARGET_SNDRV_SB_CSP_IOCTL_RESTART TARGET_IO('H', 0x16)
|
||||
#define TARGET_SND_SSCAPE_LOAD_BOOTB TARGET_IOWRU('P', 100)
|
||||
#define TARGET_SND_SSCAPE_LOAD_MCODE TARGET_IOWU ('P', 101)
|
||||
|
||||
IOCTL( SNDRV_SEQ_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_CLIENT_ID , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SYSTEM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_system_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_RUNNING_MODE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_running_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_CLIENT_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_CLIENT_INFO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_CREATE_PORT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_DELETE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_PORT_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_PORT_INFO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_CREATE_QUEUE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_DELETE_QUEUE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_status)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_tempo)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_tempo)) )
|
||||
//IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_owner)) )
|
||||
//IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_owner)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_timer)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_timer)) )
|
||||
//IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_sync)) )
|
||||
//IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_sync)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_client)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_client)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_CLIENT_POOL , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_pool)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_SET_CLIENT_POOL , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_pool)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_REMOVE_EVENTS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_remove_events)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_QUERY_SUBS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_query_subs)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) )
|
||||
IOCTL( SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_info)) )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_RESET , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_PLAY_NOTE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_note)) )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_SET_VOICE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_voice)) )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_SET_PARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_params)) )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_SET_MODE , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_DM_FM_IOCTL_SET_CONNECTION , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_HWDEP_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_HWDEP_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_info)) )
|
||||
IOCTL( SNDRV_HWDEP_IOCTL_DSP_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_dsp_status)) )
|
||||
IOCTL( SNDRV_HWDEP_IOCTL_DSP_LOAD , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_dsp_image)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_info)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_TSTAMP , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_HW_REFINE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_hw_params)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_HW_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_hw_params)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_HW_FREE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_SW_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sw_params)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_status)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_DELAY , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sframes)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_HWSYNC , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_SYNC_PTR , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sync_ptr)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_CHANNEL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_channel_info)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_PREPARE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_RESET , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_START , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_DROP , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_DRAIN , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_PAUSE , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_REWIND , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_uframes)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_RESUME , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_XRUN , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_PCM_IOCTL_FORWARD , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_uframes)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_WRITEI_FRAMES , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferi)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_READI_FRAMES , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferi)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_WRITEN_FRAMES , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xfern)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_READN_FRAMES , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_xfern)) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_LINK , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_PCM_IOCTL_UNLINK , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_RAWMIDI_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_RAWMIDI_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_info)) )
|
||||
IOCTL( SNDRV_RAWMIDI_IOCTL_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_params)) )
|
||||
IOCTL( SNDRV_RAWMIDI_IOCTL_STATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_status)) )
|
||||
IOCTL( SNDRV_RAWMIDI_IOCTL_DROP , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_RAWMIDI_IOCTL_DRAIN , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_NEXT_DEVICE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_id)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_TREAD , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_GINFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_ginfo)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_GPARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_gparams)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_GSTATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_gstatus)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_SELECT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_select)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_info)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_PARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_params)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_status)) )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_START , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_STOP , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_CONTINUE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_TIMER_IOCTL_PAUSE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_CTL_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_CARD_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_card_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_LIST , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_list)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_READ , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_value)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_WRITE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_value)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_LOCK , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_UNLOCK , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS , IOC_RW, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_ADD , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_REPLACE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_ELEM_REMOVE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_TLV_READ , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_TLV_WRITE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_TLV_COMMAND , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE , IOC_RW, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_HWDEP_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_PCM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE , IOC_RW, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_info)) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_POWER , IOC_RW, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_CTL_IOCTL_POWER_STATE , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_IOCTL_READV , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferv)) )
|
||||
IOCTL( SNDRV_IOCTL_WRITEV , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferv)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_info)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_CODE_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_code)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_CODE_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_code)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_SETUP , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_tram)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_tram)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_PCM_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_pcm)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_PCM_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_pcm)) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_STOP , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_CONTINUE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_SINGLE_STEP , IOC_W, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_EMU10K1_IOCTL_DBG_READ , IOC_R, MK_PTR(TYPE_INT) )
|
||||
IOCTL( SNDRV_HDSP_IOCTL_GET_PEAK_RMS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_peak_rms)) )
|
||||
IOCTL( SNDRV_HDSP_IOCTL_GET_CONFIG_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_config_info)) )
|
||||
IOCTL( SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_hdsp_firmware)) )
|
||||
IOCTL( SNDRV_HDSP_IOCTL_GET_VERSION , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_version)) )
|
||||
IOCTL( SNDRV_HDSP_IOCTL_GET_MIXER , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_mixer)) )
|
||||
IOCTL( SNDRV_HDSP_IOCTL_GET_9632_AEB , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_9632_aeb)) )
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_info)) )
|
||||
#if _IOC_SIZEBITS > 13
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_LOAD_CODE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_microcode)) )
|
||||
#endif
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_UNLOAD_CODE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_START , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_start)) )
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_STOP , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_PAUSE , 0, TYPE_NULL )
|
||||
IOCTL( SNDRV_SB_CSP_IOCTL_RESTART , 0, TYPE_NULL )
|
||||
IOCTL( SND_SSCAPE_LOAD_BOOTB , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sscape_bootblock)) )
|
||||
IOCTL( SND_SSCAPE_LOAD_MCODE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sscape_microcode)) )
|
1740
linux-user/ioctls_alsa_structs.h
Normal file
1740
linux-user/ioctls_alsa_structs.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "qemu.h"
|
||||
#include "qemu-common.h"
|
||||
#include "tcg.h"
|
||||
#include "translate-all.h"
|
||||
|
||||
//#define DEBUG_MMAP
|
||||
@@ -33,6 +34,7 @@ void mmap_lock(void)
|
||||
{
|
||||
if (mmap_lock_count++ == 0) {
|
||||
pthread_mutex_lock(&mmap_mutex);
|
||||
tcg_lock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +42,7 @@ void mmap_unlock(void)
|
||||
{
|
||||
if (--mmap_lock_count == 0) {
|
||||
pthread_mutex_unlock(&mmap_mutex);
|
||||
tcg_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,6 +360,9 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
|
||||
}
|
||||
}
|
||||
|
||||
#define SNDRV_PCM_MMAP_OFFSET_STATUS 0x80000000
|
||||
#define SNDRV_PCM_MMAP_OFFSET_CONTROL 0x81000000
|
||||
|
||||
/* NOTE: all the constants are the HOST ones */
|
||||
abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
|
||||
int flags, int fd, abi_ulong offset)
|
||||
@@ -391,6 +397,17 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Alsa tries to communcate with the kernel via mmap. This usually
|
||||
* is a good idea when user- and kernelspace are running on the
|
||||
* same architecture but does not work out when not. To make alsa
|
||||
* not to use mmap, we can just have it fail on the mmap calls that
|
||||
* would initiate this.
|
||||
*/
|
||||
if(offset == SNDRV_PCM_MMAP_OFFSET_STATUS || offset == SNDRV_PCM_MMAP_OFFSET_CONTROL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (offset & ~TARGET_PAGE_MASK) {
|
||||
errno = EINVAL;
|
||||
goto fail;
|
||||
|
@@ -193,10 +193,10 @@ abi_long memcpy_to_target(abi_ulong dest, const void *src,
|
||||
void target_set_brk(abi_ulong new_brk);
|
||||
abi_long do_brk(abi_ulong new_brk);
|
||||
void syscall_init(void);
|
||||
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
abi_long arg2, abi_long arg3, abi_long arg4,
|
||||
abi_long arg5, abi_long arg6, abi_long arg7,
|
||||
abi_long arg8);
|
||||
abi_long do_syscall(void *cpu_env, int num, abi_ulong arg1,
|
||||
abi_ulong arg2, abi_ulong arg3, abi_ulong arg4,
|
||||
abi_ulong arg5, abi_ulong arg6, abi_ulong arg7,
|
||||
abi_ulong arg8);
|
||||
void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
|
||||
extern THREAD CPUState *thread_cpu;
|
||||
void cpu_loop(CPUArchState *env);
|
||||
|
@@ -526,6 +526,10 @@ static void QEMU_NORETURN force_sig(int target_sig)
|
||||
trace_user_force_sig(env, target_sig, host_sig);
|
||||
gdb_signalled(env, target_sig);
|
||||
|
||||
if (target_sig == 6) {
|
||||
goto no_core;
|
||||
}
|
||||
|
||||
/* dump core if supported by target binary format */
|
||||
if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
|
||||
stop_all_tasks();
|
||||
@@ -543,6 +547,8 @@ static void QEMU_NORETURN force_sig(int target_sig)
|
||||
target_sig, strsignal(host_sig), "core dumped" );
|
||||
}
|
||||
|
||||
no_core:
|
||||
|
||||
/* The proper exit code for dying from an uncaught signal is
|
||||
* -<signal>. The kernel doesn't allow exit() or _exit() to pass
|
||||
* a negative value. To get the proper exit code we need to
|
||||
|
@@ -4806,6 +4806,11 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
|
||||
uint32_t outbufsz;
|
||||
int free_fm = 0;
|
||||
|
||||
if (1) {
|
||||
/* XXX agraf: fiemap breaks for me */
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
|
||||
assert(arg_type[0] == TYPE_PTR);
|
||||
assert(ie->access == IOC_RW);
|
||||
arg_type++;
|
||||
@@ -5334,7 +5339,12 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
|
||||
ie = ioctl_entries;
|
||||
for(;;) {
|
||||
if (ie->target_cmd == 0) {
|
||||
gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
|
||||
int i;
|
||||
gemu_log("Unsupported ioctl: cmd=0x%04lx (%x)\n", (unsigned long)cmd, (unsigned int)(cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
|
||||
for (i = 0; ioctl_entries[i].target_cmd; i++) {
|
||||
if ((ioctl_entries[i].target_cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) == (cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)))
|
||||
gemu_log("%p\t->\t%s (%x)\n", (void *)(unsigned long)ioctl_entries[i].host_cmd, ioctl_entries[i].name, (ioctl_entries[i].target_cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
|
||||
}
|
||||
return -TARGET_ENOSYS;
|
||||
}
|
||||
if (ie->target_cmd == cmd)
|
||||
@@ -5362,6 +5372,11 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
|
||||
arg_type++;
|
||||
target_size = thunk_type_size(arg_type, 0);
|
||||
switch(ie->access) {
|
||||
/* FIXME: actually the direction given in the ioctl should be
|
||||
* correct so we can assume the communication is uni-directional.
|
||||
* The alsa developers did not like this concept though and
|
||||
* declared ioctls IOC_R and IOC_W even though they were IOC_RW.*/
|
||||
/*
|
||||
case IOC_R:
|
||||
ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
|
||||
if (!is_error(ret)) {
|
||||
@@ -5380,6 +5395,7 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
|
||||
unlock_user(argptr, arg, 0);
|
||||
ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
case IOC_RW:
|
||||
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
|
||||
@@ -5999,6 +6015,15 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
||||
if (nptl_flags & CLONE_SETTLS)
|
||||
cpu_set_tls (new_env, newtls);
|
||||
|
||||
/* agraf: Pin ourselves to a single CPU when running multi-threaded.
|
||||
This turned out to improve stability for me. */
|
||||
{
|
||||
cpu_set_t mask;
|
||||
CPU_ZERO(&mask);
|
||||
CPU_SET(0, &mask);
|
||||
sched_setaffinity(0, sizeof(mask), &mask);
|
||||
}
|
||||
|
||||
/* Grab a mutex so that thread setup appears atomic. */
|
||||
pthread_mutex_lock(&clone_lock);
|
||||
|
||||
@@ -6988,52 +7013,19 @@ int host_to_target_waitstatus(int status)
|
||||
|
||||
static int open_self_cmdline(void *cpu_env, int fd)
|
||||
{
|
||||
int fd_orig = -1;
|
||||
bool word_skipped = false;
|
||||
CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
|
||||
struct linux_binprm *bprm = ((TaskState *)cpu->opaque)->bprm;
|
||||
int i;
|
||||
|
||||
fd_orig = open("/proc/self/cmdline", O_RDONLY);
|
||||
if (fd_orig < 0) {
|
||||
return fd_orig;
|
||||
}
|
||||
for (i = 0; i < bprm->argc; i++) {
|
||||
size_t len = strlen(bprm->argv[i]) + 1;
|
||||
|
||||
while (true) {
|
||||
ssize_t nb_read;
|
||||
char buf[128];
|
||||
char *cp_buf = buf;
|
||||
|
||||
nb_read = read(fd_orig, buf, sizeof(buf));
|
||||
if (nb_read < 0) {
|
||||
int e = errno;
|
||||
fd_orig = close(fd_orig);
|
||||
errno = e;
|
||||
if (write(fd, bprm->argv[i], len) != len) {
|
||||
return -1;
|
||||
} else if (nb_read == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!word_skipped) {
|
||||
/* Skip the first string, which is the path to qemu-*-static
|
||||
instead of the actual command. */
|
||||
cp_buf = memchr(buf, 0, nb_read);
|
||||
if (cp_buf) {
|
||||
/* Null byte found, skip one string */
|
||||
cp_buf++;
|
||||
nb_read -= cp_buf - buf;
|
||||
word_skipped = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (word_skipped) {
|
||||
if (write(fd, cp_buf, nb_read) != nb_read) {
|
||||
int e = errno;
|
||||
close(fd_orig);
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return close(fd_orig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_self_maps(void *cpu_env, int fd)
|
||||
@@ -7122,6 +7114,25 @@ static int open_self_stat(void *cpu_env, int fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_cpuinfo(void *cpu_env, int fd)
|
||||
{
|
||||
dprintf(fd,
|
||||
"Processor : ARMv7 Processor rev 5 (v7l)\n"
|
||||
"BogoMIPS : 799.53\n"
|
||||
"Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3\n"
|
||||
"CPU implementer : 0x41\n"
|
||||
"CPU architecture: 7\n"
|
||||
"CPU variant : 0x2\n"
|
||||
"CPU part : 0xc08\n"
|
||||
"CPU revision : 5\n"
|
||||
"\n"
|
||||
"Hardware : Genesi Efika MX (Smarttop)\n"
|
||||
"Revision : 51030\n"
|
||||
"Serial : 0000000000000000\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_self_auxv(void *cpu_env, int fd)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
|
||||
@@ -7236,6 +7247,7 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
|
||||
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
|
||||
{ "/proc/net/route", open_net_route, is_proc },
|
||||
#endif
|
||||
{ "cpuinfo", open_cpuinfo, is_proc_myself },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
@@ -7304,10 +7316,10 @@ static target_timer_t get_timer_id(abi_long arg)
|
||||
/* do_syscall() should always have a single exit point at the end so
|
||||
that actions, such as logging of syscall results, can be performed.
|
||||
All errnos that do_syscall() returns must be -TARGET_<errcode>. */
|
||||
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
abi_long arg2, abi_long arg3, abi_long arg4,
|
||||
abi_long arg5, abi_long arg6, abi_long arg7,
|
||||
abi_long arg8)
|
||||
abi_long do_syscall(void *cpu_env, int num, abi_ulong arg1,
|
||||
abi_ulong arg2, abi_ulong arg3, abi_ulong arg4,
|
||||
abi_ulong arg5, abi_ulong arg6, abi_ulong arg7,
|
||||
abi_ulong arg8)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(cpu_env);
|
||||
abi_long ret;
|
||||
@@ -7665,9 +7677,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
case TARGET_NR_oldstat:
|
||||
goto unimplemented;
|
||||
#endif
|
||||
case TARGET_NR_lseek:
|
||||
ret = get_errno(lseek(arg1, arg2, arg3));
|
||||
case TARGET_NR_lseek: {
|
||||
off_t off = arg2;
|
||||
if (arg3 != SEEK_SET) {
|
||||
off = (abi_long)arg2;
|
||||
}
|
||||
ret = get_errno(lseek(arg1, off, arg3));
|
||||
break;
|
||||
}
|
||||
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
|
||||
/* Alpha specific */
|
||||
case TARGET_NR_getxpid:
|
||||
@@ -8534,6 +8551,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
case TARGET_NR_gettimeofday:
|
||||
{
|
||||
struct timeval tv;
|
||||
if(copy_from_user_timeval(&tv, arg1))
|
||||
goto efault;
|
||||
ret = get_errno(gettimeofday(&tv, NULL));
|
||||
if (!is_error(ret)) {
|
||||
if (copy_to_user_timeval(arg1, &tv))
|
||||
@@ -9718,7 +9737,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
{
|
||||
struct timespec ts, *pts;
|
||||
|
||||
if (arg3 >= 0) {
|
||||
if ((abi_long)arg3 >= 0) {
|
||||
/* Convert ms to secs, ns */
|
||||
ts.tv_sec = arg3 / 1000;
|
||||
ts.tv_nsec = (arg3 % 1000) * 1000000LL;
|
||||
|
@@ -2502,6 +2502,9 @@ struct target_f_owner_ex {
|
||||
#define TARGET_MTIOCGET TARGET_IOR('m', 2, struct mtget)
|
||||
#define TARGET_MTIOCPOS TARGET_IOR('m', 3, struct mtpos)
|
||||
|
||||
#define TARGET_FS_IOC_GETFLAGS TARGET_IORU('f', 1)
|
||||
#define TARGET_FS_IOC_SETFLAGS TARGET_IOWU('f', 2)
|
||||
|
||||
struct target_sysinfo {
|
||||
abi_long uptime; /* Seconds since boot */
|
||||
abi_ulong loads[3]; /* 1, 5, and 15 minute load averages */
|
||||
@@ -2591,6 +2594,8 @@ struct target_ucred {
|
||||
uint32_t gid;
|
||||
};
|
||||
|
||||
#include "ioctls_alsa_structs.h"
|
||||
|
||||
typedef int32_t target_timer_t;
|
||||
|
||||
#define TARGET_SIGEV_MAX_SIZE 64
|
||||
|
@@ -83,6 +83,11 @@ STRUCT(buffmem_desc,
|
||||
STRUCT(mixer_info,
|
||||
MK_ARRAY(TYPE_CHAR, 16), MK_ARRAY(TYPE_CHAR, 32), TYPE_INT, MK_ARRAY(TYPE_INT, 10))
|
||||
|
||||
/* FIXME: including these on x86 / x86_64 breaks qemu-i386 */
|
||||
#ifdef __powerpc__
|
||||
#include "syscall_types_alsa.h"
|
||||
#endif
|
||||
|
||||
/* loop device ioctls */
|
||||
STRUCT(loop_info,
|
||||
TYPE_INT, /* lo_number */
|
||||
|
1336
linux-user/syscall_types_alsa.h
Normal file
1336
linux-user/syscall_types_alsa.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -110,7 +110,12 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
|
||||
*argend = 0;
|
||||
|
||||
if (strcmp(cmd, "deny") == 0) {
|
||||
acl_rule = g_malloc(sizeof(*acl_rule));
|
||||
acl_rule = calloc(1, sizeof(*acl_rule));
|
||||
if (!acl_rule) {
|
||||
fclose(f);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
if (strcmp(arg, "all") == 0) {
|
||||
acl_rule->type = ACL_DENY_ALL;
|
||||
} else {
|
||||
@@ -119,7 +124,12 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
|
||||
}
|
||||
QSIMPLEQ_INSERT_TAIL(acl_list, acl_rule, entry);
|
||||
} else if (strcmp(cmd, "allow") == 0) {
|
||||
acl_rule = g_malloc(sizeof(*acl_rule));
|
||||
acl_rule = calloc(1, sizeof(*acl_rule));
|
||||
if (!acl_rule) {
|
||||
fclose(f);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
if (strcmp(arg, "all") == 0) {
|
||||
acl_rule->type = ACL_ALLOW_ALL;
|
||||
} else {
|
||||
@@ -413,6 +423,17 @@ int main(int argc, char **argv)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_LIBCAP
|
||||
/* avoid sending the fd as root user if running suid to not fool
|
||||
* peer credentials to daemons that dont expect that
|
||||
*/
|
||||
if (setuid(getuid()) < 0) {
|
||||
fprintf(stderr, "Failed to drop privileges.\n");
|
||||
ret = EXIT_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* write fd to the domain socket */
|
||||
if (send_fd(unixfd, fd) == -1) {
|
||||
fprintf(stderr, "failed to write fd to unix socket: %s\n",
|
||||
@@ -434,7 +455,7 @@ cleanup:
|
||||
}
|
||||
while ((acl_rule = QSIMPLEQ_FIRST(&acl_list)) != NULL) {
|
||||
QSIMPLEQ_REMOVE_HEAD(&acl_list, entry);
|
||||
g_free(acl_rule);
|
||||
free(acl_rule);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
16
qemu-char.c
16
qemu-char.c
@@ -510,6 +510,9 @@ typedef struct {
|
||||
IOEventHandler *chr_event[MAX_MUX];
|
||||
void *ext_opaque[MAX_MUX];
|
||||
CharDriverState *drv;
|
||||
#if defined(TARGET_S390X)
|
||||
QEMUTimer *accept_timer;
|
||||
#endif
|
||||
int focus;
|
||||
int mux_cnt;
|
||||
int term_got_escape;
|
||||
@@ -669,6 +672,15 @@ static void mux_chr_accept_input(CharDriverState *chr)
|
||||
d->chr_read[m](d->ext_opaque[m],
|
||||
&d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
|
||||
}
|
||||
|
||||
#if defined(TARGET_S390X)
|
||||
/* We're still not able to sync producer and consumer, so let's wait a bit
|
||||
and try again by then. */
|
||||
if (d->prod[m] != d->cons[m]) {
|
||||
qemu_mod_timer(d->accept_timer, qemu_get_clock_ns(vm_clock)
|
||||
+ (int64_t)100000);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int mux_chr_can_read(void *opaque)
|
||||
@@ -817,6 +829,10 @@ static CharDriverState *qemu_chr_open_mux(const char *id,
|
||||
chr->opaque = d;
|
||||
d->drv = drv;
|
||||
d->focus = -1;
|
||||
#if defined(TARGET_S390X)
|
||||
d->accept_timer = qemu_new_timer_ns(vm_clock,
|
||||
(QEMUTimerCB*)mux_chr_accept_input, chr);
|
||||
#endif
|
||||
chr->chr_close = mux_chr_close;
|
||||
chr->chr_write = mux_chr_write;
|
||||
chr->chr_update_read_handler = mux_chr_update_read_handler;
|
||||
|
@@ -3132,6 +3132,16 @@ Store the QEMU process PID in @var{file}. It is useful if you launch QEMU
|
||||
from a script.
|
||||
ETEXI
|
||||
|
||||
DEF("nooutgoing", HAS_ARG, QEMU_OPTION_nooutgoing, \
|
||||
"-nooutgoing <IP>\n" \
|
||||
" incoming traffic only from IP, no outgoing\n", \
|
||||
QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
@item -nooutgoing
|
||||
Forbid userspace networking to make outgoing connections. Only accept incoming
|
||||
connections from ip address IP.
|
||||
ETEXI
|
||||
|
||||
DEF("singlestep", 0, QEMU_OPTION_singlestep, \
|
||||
"-singlestep always run in singlestep mode\n", QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
|
@@ -52,6 +52,12 @@ SEABIOS_EXTRAVERSION="-prebuilt.qemu-project.org"
|
||||
#
|
||||
EFIROM ?= $(shell which EfiRom 2>/dev/null)
|
||||
|
||||
# NB: Certain SUSE qemu subpackages use date information, but we want
|
||||
# reproducible builds, so we use a pre-determined timestamp, rather
|
||||
# than the current timestamp to acheive consistent results build to
|
||||
# build.
|
||||
PACKAGING_TIMESTAMP = $(shell date -r ../VERSION +%s)
|
||||
|
||||
default:
|
||||
@echo "nothing is build by default"
|
||||
@echo "available build targets:"
|
||||
@@ -105,7 +111,7 @@ build-lgplvgabios:
|
||||
|
||||
.PHONY: sgabios
|
||||
sgabios:
|
||||
$(MAKE) -C sgabios
|
||||
$(MAKE) -C sgabios PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP)
|
||||
cp sgabios/sgabios.bin ../pc-bios
|
||||
|
||||
|
||||
@@ -125,18 +131,22 @@ efi-rom-%: build-pxe-roms build-efi-roms
|
||||
|
||||
build-pxe-roms:
|
||||
$(MAKE) -C ipxe/src CONFIG=qemu \
|
||||
PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP) \
|
||||
CROSS_COMPILE=$(x86_64_cross_prefix) \
|
||||
$(patsubst %,bin/%.rom,$(pxerom_targets))
|
||||
|
||||
build-efi-roms: build-pxe-roms
|
||||
$(MAKE) -C ipxe/src CONFIG=qemu \
|
||||
PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP) \
|
||||
CROSS_COMPILE=$(x86_64_cross_prefix) \
|
||||
$(patsubst %,bin-i386-efi/%.efidrv,$(pxerom_targets)) \
|
||||
$(patsubst %,bin-x86_64-efi/%.efidrv,$(pxerom_targets))
|
||||
|
||||
|
||||
slof:
|
||||
$(MAKE) -C SLOF CROSS=$(powerpc64_cross_prefix) qemu
|
||||
$(MAKE) -C SLOF CROSS=$(powerpc64_cross_prefix) \
|
||||
PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP) \
|
||||
qemu
|
||||
cp SLOF/boot_rom.bin ../pc-bios/slof.bin
|
||||
|
||||
u-boot.e500:
|
||||
|
@@ -201,7 +201,7 @@ qemu_check_systemd() {
|
||||
}
|
||||
|
||||
qemu_generate_register() {
|
||||
echo ":qemu-$cpu:M::$magic:$mask:$qemu:$FLAGS"
|
||||
echo ":qemu-$cpu:M::$magic:$mask:$qemu:P$FLAGS"
|
||||
}
|
||||
|
||||
qemu_register_interpreter() {
|
||||
@@ -242,9 +242,9 @@ qemu_set_binfmts() {
|
||||
continue
|
||||
fi
|
||||
|
||||
qemu="$QEMU_PATH/qemu-$cpu"
|
||||
qemu="$QEMU_PATH/qemu-$cpu-binfmt"
|
||||
if [ "$cpu" = "i486" ] ; then
|
||||
qemu="$QEMU_PATH/qemu-i386"
|
||||
qemu="$QEMU_PATH/qemu-i386-binfmt"
|
||||
fi
|
||||
|
||||
if [ "$host_family" != "$family" ] ; then
|
||||
@@ -259,7 +259,7 @@ BINFMT_SET=qemu_register_interpreter
|
||||
SYSTEMDDIR="/etc/binfmt.d"
|
||||
DEBIANDIR="/usr/share/binfmts"
|
||||
|
||||
QEMU_PATH=/usr/local/bin
|
||||
QEMU_PATH=/usr/bin
|
||||
FLAGS=""
|
||||
|
||||
options=$(getopt -o ds:Q:e:hc: -l debian,systemd:,qemu-path:,exportdir:,help,credential: -- "$@")
|
||||
|
@@ -608,6 +608,8 @@ sorecvfrom(struct socket *so)
|
||||
} /* if ping packet */
|
||||
}
|
||||
|
||||
extern int slirp_nooutgoing;
|
||||
|
||||
/*
|
||||
* sendto() a socket
|
||||
*/
|
||||
@@ -625,6 +627,12 @@ sosendto(struct socket *so, struct mbuf *m)
|
||||
DEBUG_CALL(" sendto()ing)");
|
||||
sotranslate_out(so, &addr);
|
||||
|
||||
/* Only allow DNS requests */
|
||||
if (slirp_nooutgoing && ntohs(((struct sockaddr_in *)&addr)->sin_port) != 53) {
|
||||
errno = EHOSTUNREACH;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Don't care what port we get */
|
||||
ret = sendto(so->s, m->m_data, m->m_len, 0,
|
||||
(struct sockaddr *)&addr, sockaddr_size(&addr));
|
||||
|
@@ -391,6 +391,8 @@ tcp_sockclosed(struct tcpcb *tp)
|
||||
* nonblocking. Connect returns after the SYN is sent, and does
|
||||
* not wait for ACK+SYN.
|
||||
*/
|
||||
extern int slirp_nooutgoing;
|
||||
|
||||
int tcp_fconnect(struct socket *so, unsigned short af)
|
||||
{
|
||||
int ret=0;
|
||||
@@ -398,6 +400,11 @@ int tcp_fconnect(struct socket *so, unsigned short af)
|
||||
DEBUG_CALL("tcp_fconnect");
|
||||
DEBUG_ARG("so = %p", so);
|
||||
|
||||
if (slirp_nooutgoing) {
|
||||
errno = EHOSTUNREACH;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = so->s = qemu_socket(af, SOCK_STREAM, 0);
|
||||
if (ret >= 0) {
|
||||
int opt, s=so->s;
|
||||
@@ -478,6 +485,11 @@ void tcp_connect(struct socket *inso)
|
||||
tcp_close(sototcpcb(so)); /* This will sofree() as well */
|
||||
return;
|
||||
}
|
||||
if (slirp_nooutgoing && ((struct sockaddr_in *)&addr)->sin_addr.s_addr != slirp_nooutgoing) {
|
||||
tcp_close(sototcpcb(so)); /* This will sofree() as well */
|
||||
closesocket(s);
|
||||
return;
|
||||
}
|
||||
qemu_set_nonblock(s);
|
||||
socket_set_fast_reuse(s);
|
||||
opt = 1;
|
||||
|
29
tcg/tcg.c
29
tcg/tcg.c
@@ -33,6 +33,8 @@
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "config-host.h"
|
||||
#include "qemu/thread.h"
|
||||
|
||||
/* Note: the long term plan is to reduce the dependencies on the QEMU
|
||||
CPU definitions. Currently they are used for qemu_ld/st
|
||||
@@ -120,6 +122,29 @@ static bool tcg_out_tb_finalize(TCGContext *s);
|
||||
static TCGRegSet tcg_target_available_regs[2];
|
||||
static TCGRegSet tcg_target_call_clobber_regs;
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
static __thread int tcg_lock_count;
|
||||
#endif
|
||||
void tcg_lock(void)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
TCGContext *s = &tcg_ctx;
|
||||
if (tcg_lock_count++ == 0) {
|
||||
qemu_mutex_lock(&s->lock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void tcg_unlock(void)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
TCGContext *s = &tcg_ctx;
|
||||
if (--tcg_lock_count == 0) {
|
||||
qemu_mutex_unlock(&s->lock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TCG_TARGET_INSN_UNIT_SIZE == 1
|
||||
static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t v)
|
||||
{
|
||||
@@ -332,6 +357,7 @@ void tcg_context_init(TCGContext *s)
|
||||
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->nb_globals = 0;
|
||||
qemu_mutex_init(&s->lock);
|
||||
|
||||
/* Count total number of arguments and allocate the corresponding
|
||||
space */
|
||||
@@ -2551,6 +2577,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
|
||||
qemu_log("\n");
|
||||
}
|
||||
#endif
|
||||
tcg_lock();
|
||||
|
||||
#ifdef CONFIG_PROFILER
|
||||
s->opt_time -= profile_getclock();
|
||||
@@ -2673,6 +2700,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
|
||||
the buffer completely. Thus we can test for overflow after
|
||||
generating code without having to check during generation. */
|
||||
if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) {
|
||||
tcg_unlock();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -2686,6 +2714,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
|
||||
|
||||
/* flush instruction cache */
|
||||
flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
|
||||
tcg_unlock();
|
||||
|
||||
return tcg_current_code_size(s);
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include "cpu.h"
|
||||
#include "exec/tb-context.h"
|
||||
#include "qemu/bitops.h"
|
||||
#include "qemu/thread.h"
|
||||
#include "tcg-target.h"
|
||||
|
||||
/* XXX: make safe guess about sizes */
|
||||
@@ -697,6 +698,8 @@ struct TCGContext {
|
||||
|
||||
uint16_t gen_insn_end_off[TCG_MAX_INSNS];
|
||||
target_ulong gen_insn_data[TCG_MAX_INSNS][TARGET_INSN_START_WORDS];
|
||||
|
||||
QemuMutex lock;
|
||||
};
|
||||
|
||||
extern TCGContext tcg_ctx;
|
||||
@@ -904,6 +907,9 @@ TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, TCGOpcode opc, int narg);
|
||||
|
||||
void tcg_optimize(TCGContext *s);
|
||||
|
||||
extern void tcg_lock(void);
|
||||
extern void tcg_unlock(void);
|
||||
|
||||
/* only used for debugging purposes */
|
||||
void tcg_dump_ops(TCGContext *s);
|
||||
|
||||
|
@@ -297,7 +297,12 @@ static void thread_pool_init_one(ThreadPool *pool, AioContext *ctx)
|
||||
qemu_mutex_init(&pool->lock);
|
||||
qemu_cond_init(&pool->worker_stopped);
|
||||
qemu_sem_init(&pool->sem, 0);
|
||||
pool->max_threads = 64;
|
||||
if (sizeof(pool) == 4) {
|
||||
/* 32bit systems run out of virtual memory quickly */
|
||||
pool->max_threads = 4;
|
||||
} else {
|
||||
pool->max_threads = 64;
|
||||
}
|
||||
pool->new_thread_bh = aio_bh_new(ctx, spawn_thread_bh_fn, pool);
|
||||
|
||||
QLIST_INIT(&pool->head);
|
||||
|
21
thunk.c
21
thunk.c
@@ -37,6 +37,7 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr)
|
||||
case TYPE_CHAR:
|
||||
case TYPE_SHORT:
|
||||
case TYPE_INT:
|
||||
case TYPE_INTBITFIELD:
|
||||
case TYPE_LONGLONG:
|
||||
case TYPE_ULONGLONG:
|
||||
case TYPE_LONG:
|
||||
@@ -139,6 +140,26 @@ const argtype *thunk_convert(void *dst, const void *src,
|
||||
case TYPE_INT:
|
||||
*(uint32_t *)dst = tswap32(*(uint32_t *)src);
|
||||
break;
|
||||
case TYPE_INTBITFIELD:
|
||||
#if defined(TARGET_I386) && defined(__powerpc__)
|
||||
/* powerpc uses the MSB, whereas i386 uses the LSB
|
||||
* to store the first bit in a field */
|
||||
{
|
||||
unsigned char byte = *(uint8_t *)src;
|
||||
*(uint8_t *)dst = ((byte >> 7) & 1)
|
||||
| ((byte >> 5) & 2)
|
||||
| ((byte >> 3) & 4)
|
||||
| ((byte >> 1) & 8)
|
||||
| ((byte << 1) & 16)
|
||||
| ((byte << 3) & 32)
|
||||
| ((byte << 5) & 64)
|
||||
| ((byte << 7) & 128);
|
||||
/* FIXME: implement for bitfields > 1 byte and other archs */
|
||||
}
|
||||
#else
|
||||
*(uint32_t *)dst = tswap32(*(uint32_t *)src);
|
||||
#endif
|
||||
break;
|
||||
case TYPE_LONGLONG:
|
||||
case TYPE_ULONGLONG:
|
||||
*(uint64_t *)dst = tswap64(*(uint64_t *)src);
|
||||
|
@@ -767,17 +767,21 @@ static TranslationBlock *tb_alloc(target_ulong pc)
|
||||
{
|
||||
TranslationBlock *tb;
|
||||
|
||||
tcg_lock();
|
||||
if (tcg_ctx.tb_ctx.nb_tbs >= tcg_ctx.code_gen_max_blocks) {
|
||||
tcg_unlock();
|
||||
return NULL;
|
||||
}
|
||||
tb = &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs++];
|
||||
tb->pc = pc;
|
||||
tb->cflags = 0;
|
||||
tcg_unlock();
|
||||
return tb;
|
||||
}
|
||||
|
||||
void tb_free(TranslationBlock *tb)
|
||||
{
|
||||
tcg_lock();
|
||||
/* In practice this is mostly used for single use temporary TB
|
||||
Ignore the hard cases and just back up if this TB happens to
|
||||
be the last one generated. */
|
||||
@@ -786,6 +790,7 @@ void tb_free(TranslationBlock *tb)
|
||||
tcg_ctx.code_gen_ptr = tb->tc_ptr;
|
||||
tcg_ctx.tb_ctx.nb_tbs--;
|
||||
}
|
||||
tcg_unlock();
|
||||
}
|
||||
|
||||
static inline void invalidate_page_bitmap(PageDesc *p)
|
||||
@@ -844,6 +849,7 @@ void tb_flush(CPUState *cpu)
|
||||
((unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer)) /
|
||||
tcg_ctx.tb_ctx.nb_tbs : 0);
|
||||
#endif
|
||||
tcg_lock();
|
||||
if ((unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer)
|
||||
> tcg_ctx.code_gen_buffer_size) {
|
||||
cpu_abort(cpu, "Internal error: code buffer overflow\n");
|
||||
@@ -862,6 +868,7 @@ void tb_flush(CPUState *cpu)
|
||||
/* XXX: flush processor icache at this point if cache flush is
|
||||
expensive */
|
||||
tcg_ctx.tb_ctx.tb_flush_count++;
|
||||
tcg_unlock();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TB_CHECK
|
||||
@@ -1320,8 +1327,10 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
|
||||
uint32_t current_flags = 0;
|
||||
#endif /* TARGET_HAS_PRECISE_SMC */
|
||||
|
||||
tcg_lock();
|
||||
p = page_find(start >> TARGET_PAGE_BITS);
|
||||
if (!p) {
|
||||
tcg_unlock();
|
||||
return;
|
||||
}
|
||||
#if defined(TARGET_HAS_PRECISE_SMC)
|
||||
@@ -1392,6 +1401,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
|
||||
cpu_loop_exit_noexc(cpu);
|
||||
}
|
||||
#endif
|
||||
tcg_unlock();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
@@ -1509,13 +1519,16 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
|
||||
{
|
||||
int m_min, m_max, m;
|
||||
uintptr_t v;
|
||||
TranslationBlock *tb;
|
||||
TranslationBlock *tb, *r;
|
||||
|
||||
tcg_lock();
|
||||
if (tcg_ctx.tb_ctx.nb_tbs <= 0) {
|
||||
tcg_unlock();
|
||||
return NULL;
|
||||
}
|
||||
if (tc_ptr < (uintptr_t)tcg_ctx.code_gen_buffer ||
|
||||
tc_ptr >= (uintptr_t)tcg_ctx.code_gen_ptr) {
|
||||
tcg_unlock();
|
||||
return NULL;
|
||||
}
|
||||
/* binary search (cf Knuth) */
|
||||
@@ -1526,6 +1539,7 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
|
||||
tb = &tcg_ctx.tb_ctx.tbs[m];
|
||||
v = (uintptr_t)tb->tc_ptr;
|
||||
if (v == tc_ptr) {
|
||||
tcg_unlock();
|
||||
return tb;
|
||||
} else if (tc_ptr < v) {
|
||||
m_max = m - 1;
|
||||
@@ -1533,7 +1547,9 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
|
||||
m_min = m + 1;
|
||||
}
|
||||
}
|
||||
return &tcg_ctx.tb_ctx.tbs[m_max];
|
||||
r = &tcg_ctx.tb_ctx.tbs[m_max];
|
||||
tcg_unlock();
|
||||
return r;
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
|
@@ -868,7 +868,7 @@ static void console_putchar(QemuConsole *s, int ch)
|
||||
} else {
|
||||
if (s->nb_esc_params < MAX_ESC_PARAMS)
|
||||
s->nb_esc_params++;
|
||||
if (ch == ';')
|
||||
if (ch == ';' || ch == '?')
|
||||
break;
|
||||
trace_console_putchar_csi(s->esc_params[0], s->esc_params[1],
|
||||
ch, s->nb_esc_params);
|
||||
|
55
ui/vnc.c
55
ui/vnc.c
@@ -58,6 +58,8 @@ static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
|
||||
static QTAILQ_HEAD(, VncDisplay) vnc_displays =
|
||||
QTAILQ_HEAD_INITIALIZER(vnc_displays);
|
||||
|
||||
static int allowed_connections = 0;
|
||||
|
||||
static int vnc_cursor_define(VncState *vs);
|
||||
static void vnc_release_modifiers(VncState *vs);
|
||||
|
||||
@@ -1197,6 +1199,7 @@ static void vnc_disconnect_start(VncState *vs)
|
||||
void vnc_disconnect_finish(VncState *vs)
|
||||
{
|
||||
int i;
|
||||
static int num_disconnects = 0;
|
||||
|
||||
vnc_jobs_join(vs); /* Wait encoding jobs */
|
||||
|
||||
@@ -1247,6 +1250,13 @@ void vnc_disconnect_finish(VncState *vs)
|
||||
object_unref(OBJECT(vs->sioc));
|
||||
vs->sioc = NULL;
|
||||
g_free(vs);
|
||||
|
||||
num_disconnects++;
|
||||
if (allowed_connections > 0 && allowed_connections <= num_disconnects) {
|
||||
VNC_DEBUG("Maximum number of disconnects (%d) reached:"
|
||||
" Session terminating\n", allowed_connections);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
|
||||
@@ -3245,6 +3255,39 @@ static void vnc_display_print_local_addr(VncDisplay *vs)
|
||||
qapi_free_SocketAddress(addr);
|
||||
}
|
||||
|
||||
static void read_file_password(const char *id, const char *filename)
|
||||
{
|
||||
FILE *pfile = NULL;
|
||||
char *passwd = NULL;
|
||||
int start = 0, length = 0, rc = 0;
|
||||
|
||||
if (strlen(filename) == 0) {
|
||||
printf("No file supplied\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pfile = fopen(filename, "r");
|
||||
if (pfile == NULL) {
|
||||
printf("Could not read from %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
start = ftell(pfile);
|
||||
fseek(pfile, 0L, SEEK_END);
|
||||
length = ftell(pfile);
|
||||
fseek(pfile, 0L, start);
|
||||
|
||||
passwd = g_malloc(length + 1);
|
||||
rc = fread(passwd, 1, length, pfile);
|
||||
fclose(pfile);
|
||||
|
||||
if (rc == length && rc > 0) {
|
||||
vnc_display_password(id, passwd);
|
||||
}
|
||||
|
||||
g_free(passwd);
|
||||
}
|
||||
|
||||
static QemuOptsList qemu_vnc_opts = {
|
||||
.name = "vnc",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
|
||||
@@ -3275,6 +3318,9 @@ static QemuOptsList qemu_vnc_opts = {
|
||||
},{
|
||||
.name = "connections",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
},{
|
||||
.name = "allowed-connections",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
},{
|
||||
.name = "to",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
@@ -3287,6 +3333,9 @@ static QemuOptsList qemu_vnc_opts = {
|
||||
},{
|
||||
.name = "password",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
},{
|
||||
.name = "password-file",
|
||||
.type = QEMU_OPT_STRING,
|
||||
},{
|
||||
.name = "reverse",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
@@ -3524,6 +3573,7 @@ void vnc_display_open(const char *id, Error **errp)
|
||||
const char *share, *device_id;
|
||||
QemuConsole *con;
|
||||
bool password = false;
|
||||
const char *password_file;
|
||||
bool reverse = false;
|
||||
const char *vnc;
|
||||
char *h;
|
||||
@@ -3652,6 +3702,10 @@ void vnc_display_open(const char *id, Error **errp)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
password_file = qemu_opt_get(opts, "password-file");
|
||||
if (password_file) {
|
||||
read_file_password(id, password_file);
|
||||
}
|
||||
|
||||
reverse = qemu_opt_get_bool(opts, "reverse", false);
|
||||
lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
|
||||
@@ -3741,6 +3795,7 @@ void vnc_display_open(const char *id, Error **errp)
|
||||
vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
|
||||
}
|
||||
vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
|
||||
allowed_connections = qemu_opt_get_number(opts, "allowed-connections", 0);
|
||||
|
||||
#ifdef CONFIG_VNC_JPEG
|
||||
vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
|
||||
|
@@ -65,6 +65,10 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
|
||||
printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
|
||||
pc, address, is_write, *(unsigned long *)old_set);
|
||||
#endif
|
||||
|
||||
/* Maybe we're still holding the TB fiddling lock? */
|
||||
tb_lock_reset();
|
||||
|
||||
/* XXX: locking issue */
|
||||
if (is_write && h2g_valid(address)) {
|
||||
switch (page_unprotect(h2g(address), pc)) {
|
||||
|
9
vl.c
9
vl.c
@@ -160,6 +160,7 @@ int smp_threads = 1;
|
||||
int acpi_enabled = 1;
|
||||
int no_hpet = 0;
|
||||
int fd_bootchk = 1;
|
||||
int slirp_nooutgoing = 0;
|
||||
static int no_reboot;
|
||||
int no_shutdown = 0;
|
||||
int cursor_hide = 1;
|
||||
@@ -3363,6 +3364,14 @@ int main(int argc, char **argv, char **envp)
|
||||
case QEMU_OPTION_singlestep:
|
||||
singlestep = 1;
|
||||
break;
|
||||
case QEMU_OPTION_nooutgoing:
|
||||
slirp_nooutgoing = inet_addr(optarg);
|
||||
if (slirp_nooutgoing == INADDR_NONE) {
|
||||
printf("Invalid address: %s.\nOnly addresses of the format "
|
||||
"xxx.xxx.xxx.xxx are supported.\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case QEMU_OPTION_S:
|
||||
autostart = 0;
|
||||
break;
|
||||
|
Reference in New Issue
Block a user