Merge remote-tracking branch 'kwolf/for-anthony' into staging

This commit is contained in:
Anthony Liguori 2011-11-07 10:57:27 -06:00
commit 2963e65a4e
4 changed files with 137 additions and 87 deletions

View File

@ -44,10 +44,12 @@ static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
"#V2.0 Format\n" "#V2.0 Format\n"
"modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n"; "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n";
int length = strlen(magic_version_2_0); int length = strlen(magic_version_2_0);
if(length>buf_size) if (length > buf_size) {
length = buf_size; length = buf_size;
if(!memcmp(magic_version_2_0,buf,length)) }
if (!memcmp(magic_version_2_0, buf, length)) {
return 2; return 2;
}
return 0; return 0;
} }
@ -80,16 +82,18 @@ static int cloop_open(BlockDriverState *bs, int flags)
s->offsets[i] = be64_to_cpu(s->offsets[i]); s->offsets[i] = be64_to_cpu(s->offsets[i]);
if (i > 0) { if (i > 0) {
uint32_t size = s->offsets[i] - s->offsets[i - 1]; uint32_t size = s->offsets[i] - s->offsets[i - 1];
if(size>max_compressed_block_size) if (size > max_compressed_block_size) {
max_compressed_block_size = size; max_compressed_block_size = size;
} }
} }
}
/* initialize zlib engine */ /* initialize zlib engine */
s->compressed_block = g_malloc(max_compressed_block_size + 1); s->compressed_block = g_malloc(max_compressed_block_size + 1);
s->uncompressed_block = g_malloc(s->block_size); s->uncompressed_block = g_malloc(s->block_size);
if(inflateInit(&s->zstream) != Z_OK) if (inflateInit(&s->zstream) != Z_OK) {
goto cloop_close; goto cloop_close;
}
s->current_block = s->n_blocks; s->current_block = s->n_blocks;
s->sectors_per_block = s->block_size/512; s->sectors_per_block = s->block_size/512;
@ -111,19 +115,22 @@ static inline int cloop_read_block(BlockDriverState *bs, int block_num)
ret = bdrv_pread(bs->file, s->offsets[block_num], s->compressed_block, ret = bdrv_pread(bs->file, s->offsets[block_num], s->compressed_block,
bytes); bytes);
if (ret != bytes) if (ret != bytes) {
return -1; return -1;
}
s->zstream.next_in = s->compressed_block; s->zstream.next_in = s->compressed_block;
s->zstream.avail_in = bytes; s->zstream.avail_in = bytes;
s->zstream.next_out = s->uncompressed_block; s->zstream.next_out = s->uncompressed_block;
s->zstream.avail_out = s->block_size; s->zstream.avail_out = s->block_size;
ret = inflateReset(&s->zstream); ret = inflateReset(&s->zstream);
if(ret != Z_OK) if (ret != Z_OK) {
return -1; return -1;
}
ret = inflate(&s->zstream, Z_FINISH); ret = inflate(&s->zstream, Z_FINISH);
if(ret != Z_STREAM_END || s->zstream.total_out != s->block_size) if (ret != Z_STREAM_END || s->zstream.total_out != s->block_size) {
return -1; return -1;
}
s->current_block = block_num; s->current_block = block_num;
} }
@ -137,11 +144,14 @@ static int cloop_read(BlockDriverState *bs, int64_t sector_num,
int i; int i;
for (i = 0; i < nb_sectors; i++) { for (i = 0; i < nb_sectors; i++) {
uint32_t sector_offset_in_block=((sector_num+i)%s->sectors_per_block), uint32_t sector_offset_in_block =
((sector_num + i) % s->sectors_per_block),
block_num = (sector_num + i) / s->sectors_per_block; block_num = (sector_num + i) / s->sectors_per_block;
if(cloop_read_block(bs, block_num) != 0) if (cloop_read_block(bs, block_num) != 0) {
return -1; return -1;
memcpy(buf+i*512,s->uncompressed_block+sector_offset_in_block*512,512); }
memcpy(buf + i * 512,
s->uncompressed_block + sector_offset_in_block * 512, 512);
} }
return 0; return 0;
} }
@ -160,10 +170,11 @@ static coroutine_fn int cloop_co_read(BlockDriverState *bs, int64_t sector_num,
static void cloop_close(BlockDriverState *bs) static void cloop_close(BlockDriverState *bs)
{ {
BDRVCloopState *s = bs->opaque; BDRVCloopState *s = bs->opaque;
if(s->n_blocks>0) if (s->n_blocks > 0) {
free(s->offsets); g_free(s->offsets);
free(s->compressed_block); }
free(s->uncompressed_block); g_free(s->compressed_block);
g_free(s->uncompressed_block);
inflateEnd(&s->zstream); inflateEnd(&s->zstream);
} }

View File

@ -799,6 +799,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
/* root directory */ /* root directory */
int cur = s->directory.next; int cur = s->directory.next;
array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1); array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
s->directory.next = ROOT_ENTRIES;
memset(array_get(&(s->directory), cur), 0, memset(array_get(&(s->directory), cur), 0,
(ROOT_ENTRIES - cur) * sizeof(direntry_t)); (ROOT_ENTRIES - cur) * sizeof(direntry_t));
} }
@ -915,11 +916,8 @@ static int init_directories(BDRVVVFATState* s,
cluster = mapping->end; cluster = mapping->end;
if(cluster > s->cluster_count) { if(cluster > s->cluster_count) {
fprintf(stderr,"Directory does not fit in FAT%d (capacity %s)\n", fprintf(stderr,"Directory does not fit in FAT%d (capacity %.2f MB)\n",
s->fat_type, s->fat_type, s->sector_count / 2000.0);
s->fat_type == 12 ? s->sector_count == 2880 ? "1.44 MB"
: "2.88 MB"
: "504MB");
return -EINVAL; return -EINVAL;
} }
@ -953,7 +951,7 @@ static int init_directories(BDRVVVFATState* s,
bootsector->number_of_fats=0x2; /* number of FATs */ bootsector->number_of_fats=0x2; /* number of FATs */
bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10); bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);
bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count); bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
bootsector->media_type=(s->fat_type!=12?0xf8:s->sector_count==5760?0xf9:0xf8); /* media descriptor */ bootsector->media_type=(s->first_sectors_number>1?0xf8:0xf0); /* media descriptor (f8=hd, f0=3.5 fd)*/
s->fat.pointer[0] = bootsector->media_type; s->fat.pointer[0] = bootsector->media_type;
bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat); bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
bootsector->sectors_per_track=cpu_to_le16(s->bs->secs); bootsector->sectors_per_track=cpu_to_le16(s->bs->secs);
@ -962,7 +960,7 @@ static int init_directories(BDRVVVFATState* s,
bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0); bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);
/* LATER TODO: if FAT32, this is wrong */ /* LATER TODO: if FAT32, this is wrong */
bootsector->u.fat16.drive_number=s->fat_type==12?0:0x80; /* assume this is hda (TODO) */ bootsector->u.fat16.drive_number=s->first_sectors_number==1?0:0x80; /* fda=0, hda=0x80 */
bootsector->u.fat16.current_head=0; bootsector->u.fat16.current_head=0;
bootsector->u.fat16.signature=0x29; bootsector->u.fat16.signature=0x29;
bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd); bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);
@ -984,7 +982,6 @@ static int is_consistent(BDRVVVFATState *s);
static int vvfat_open(BlockDriverState *bs, const char* dirname, int flags) static int vvfat_open(BlockDriverState *bs, const char* dirname, int flags)
{ {
BDRVVVFATState *s = bs->opaque; BDRVVVFATState *s = bs->opaque;
int floppy = 0;
int i; int i;
#ifdef DEBUG #ifdef DEBUG
@ -998,11 +995,8 @@ DLOG(if (stderr == NULL) {
s->bs = bs; s->bs = bs;
s->fat_type=16;
/* LATER TODO: if FAT32, adjust */ /* LATER TODO: if FAT32, adjust */
s->sectors_per_cluster=0x10; s->sectors_per_cluster=0x10;
/* 504MB disk*/
bs->cyls=1024; bs->heads=16; bs->secs=63;
s->current_cluster=0xffffffff; s->current_cluster=0xffffffff;
@ -1017,16 +1011,6 @@ DLOG(if (stderr == NULL) {
if (!strstart(dirname, "fat:", NULL)) if (!strstart(dirname, "fat:", NULL))
return -1; return -1;
if (strstr(dirname, ":floppy:")) {
floppy = 1;
s->fat_type = 12;
s->first_sectors_number = 1;
s->sectors_per_cluster=2;
bs->cyls = 80; bs->heads = 2; bs->secs = 36;
}
s->sector_count=bs->cyls*bs->heads*bs->secs;
if (strstr(dirname, ":32:")) { if (strstr(dirname, ":32:")) {
fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n"); fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n");
s->fat_type = 32; s->fat_type = 32;
@ -1034,9 +1018,31 @@ DLOG(if (stderr == NULL) {
s->fat_type = 16; s->fat_type = 16;
} else if (strstr(dirname, ":12:")) { } else if (strstr(dirname, ":12:")) {
s->fat_type = 12; s->fat_type = 12;
s->sector_count=2880;
} }
if (strstr(dirname, ":floppy:")) {
/* 1.44MB or 2.88MB floppy. 2.88MB can be FAT12 (default) or FAT16. */
if (!s->fat_type) {
s->fat_type = 12;
bs->secs = 36;
s->sectors_per_cluster=2;
} else {
bs->secs=(s->fat_type == 12 ? 18 : 36);
s->sectors_per_cluster=1;
}
s->first_sectors_number = 1;
bs->cyls=80; bs->heads=2;
} else {
/* 32MB or 504MB disk*/
if (!s->fat_type) {
s->fat_type = 16;
}
bs->cyls=(s->fat_type == 12 ? 64 : 1024);
bs->heads=16; bs->secs=63;
}
s->sector_count=bs->cyls*bs->heads*bs->secs-(s->first_sectors_number-1);
if (strstr(dirname, ":rw:")) { if (strstr(dirname, ":rw:")) {
if (enable_write_target(s)) if (enable_write_target(s))
return -1; return -1;
@ -1060,10 +1066,10 @@ DLOG(if (stderr == NULL) {
if(s->first_sectors_number==0x40) if(s->first_sectors_number==0x40)
init_mbr(s); init_mbr(s);
else {
/* for some reason or other, MS-DOS does not like to know about CHS... */ /* MS-DOS does not like to know about CHS (?). */
if (floppy)
bs->heads = bs->cyls = bs->secs = 0; bs->heads = bs->cyls = bs->secs = 0;
}
// assert(is_consistent(s)); // assert(is_consistent(s));
qemu_co_mutex_init(&s->lock); qemu_co_mutex_init(&s->lock);
@ -1244,7 +1250,7 @@ static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
int i; int i;
for(i=0;i<nb_sectors;i++,sector_num++) { for(i=0;i<nb_sectors;i++,sector_num++) {
if (sector_num >= s->sector_count) if (sector_num >= bs->total_sectors)
return -1; return -1;
if (s->qcow) { if (s->qcow) {
int n; int n;
@ -1270,7 +1276,7 @@ DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
uint32_t sector=sector_num-s->faked_sectors, uint32_t sector=sector_num-s->faked_sectors,
sector_offset_in_cluster=(sector%s->sectors_per_cluster), sector_offset_in_cluster=(sector%s->sectors_per_cluster),
cluster_num=sector/s->sectors_per_cluster; cluster_num=sector/s->sectors_per_cluster;
if(read_cluster(s, cluster_num) != 0) { if(cluster_num > s->cluster_count || read_cluster(s, cluster_num) != 0) {
/* LATER TODO: strict: return -1; */ /* LATER TODO: strict: return -1; */
memset(buf+i*0x200,0,0x200); memset(buf+i*0x200,0,0x200);
continue; continue;

View File

@ -358,6 +358,14 @@ static void DMA_run (void)
struct dma_cont *d; struct dma_cont *d;
int icont, ichan; int icont, ichan;
int rearm = 0; int rearm = 0;
static int running = 0;
if (running) {
rearm = 1;
goto out;
} else {
running = 1;
}
d = dma_controllers; d = dma_controllers;
@ -374,6 +382,8 @@ static void DMA_run (void)
} }
} }
running = 0;
out:
if (rearm) if (rearm)
qemu_bh_schedule_idle(dma_bh); qemu_bh_schedule_idle(dma_bh);
} }

View File

@ -596,6 +596,9 @@ static int readv_f(int argc, char **argv)
nr_iov = argc - optind; nr_iov = argc - optind;
buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab); buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab);
if (buf == NULL) {
return 0;
}
gettimeofday(&t1, NULL); gettimeofday(&t1, NULL);
cnt = do_aio_readv(&qiov, offset, &total); cnt = do_aio_readv(&qiov, offset, &total);
@ -850,6 +853,9 @@ static int writev_f(int argc, char **argv)
nr_iov = argc - optind; nr_iov = argc - optind;
buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern); buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern);
if (buf == NULL) {
return 0;
}
gettimeofday(&t1, NULL); gettimeofday(&t1, NULL);
cnt = do_aio_writev(&qiov, offset, &total); cnt = do_aio_writev(&qiov, offset, &total);
@ -950,25 +956,25 @@ static int multiwrite_f(int argc, char **argv)
} }
} }
reqs = g_malloc(nr_reqs * sizeof(*reqs)); reqs = g_malloc0(nr_reqs * sizeof(*reqs));
buf = g_malloc(nr_reqs * sizeof(*buf)); buf = g_malloc0(nr_reqs * sizeof(*buf));
qiovs = g_malloc(nr_reqs * sizeof(*qiovs)); qiovs = g_malloc(nr_reqs * sizeof(*qiovs));
for (i = 0; i < nr_reqs; i++) { for (i = 0; i < nr_reqs && optind < argc; i++) {
int j; int j;
/* Read the offset of the request */ /* Read the offset of the request */
offset = cvtnum(argv[optind]); offset = cvtnum(argv[optind]);
if (offset < 0) { if (offset < 0) {
printf("non-numeric offset argument -- %s\n", argv[optind]); printf("non-numeric offset argument -- %s\n", argv[optind]);
return 0; goto out;
} }
optind++; optind++;
if (offset & 0x1ff) { if (offset & 0x1ff) {
printf("offset %lld is not sector aligned\n", printf("offset %lld is not sector aligned\n",
(long long)offset); (long long)offset);
return 0; goto out;
} }
if (i == 0) { if (i == 0) {
@ -985,8 +991,12 @@ static int multiwrite_f(int argc, char **argv)
nr_iov = j - optind; nr_iov = j - optind;
/* Build request */ /* Build request */
buf[i] = create_iovec(&qiovs[i], &argv[optind], nr_iov, pattern);
if (buf[i] == NULL) {
goto out;
}
reqs[i].qiov = &qiovs[i]; reqs[i].qiov = &qiovs[i];
buf[i] = create_iovec(reqs[i].qiov, &argv[optind], nr_iov, pattern);
reqs[i].sector = offset >> 9; reqs[i].sector = offset >> 9;
reqs[i].nb_sectors = reqs[i].qiov->size >> 9; reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
@ -995,6 +1005,9 @@ static int multiwrite_f(int argc, char **argv)
pattern++; pattern++;
} }
/* If there were empty requests at the end, ignore them */
nr_reqs = i;
gettimeofday(&t1, NULL); gettimeofday(&t1, NULL);
cnt = do_aio_multiwrite(reqs, nr_reqs, &total); cnt = do_aio_multiwrite(reqs, nr_reqs, &total);
gettimeofday(&t2, NULL); gettimeofday(&t2, NULL);
@ -1014,8 +1027,10 @@ static int multiwrite_f(int argc, char **argv)
out: out:
for (i = 0; i < nr_reqs; i++) { for (i = 0; i < nr_reqs; i++) {
qemu_io_free(buf[i]); qemu_io_free(buf[i]);
if (reqs[i].qiov != NULL) {
qemu_iovec_destroy(&qiovs[i]); qemu_iovec_destroy(&qiovs[i]);
} }
}
g_free(buf); g_free(buf);
g_free(reqs); g_free(reqs);
g_free(qiovs); g_free(qiovs);
@ -1185,6 +1200,10 @@ static int aio_read_f(int argc, char **argv)
nr_iov = argc - optind; nr_iov = argc - optind;
ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab); ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);
if (ctx->buf == NULL) {
free(ctx);
return 0;
}
gettimeofday(&ctx->t1, NULL); gettimeofday(&ctx->t1, NULL);
acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov, acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
@ -1280,6 +1299,10 @@ static int aio_write_f(int argc, char **argv)
nr_iov = argc - optind; nr_iov = argc - optind;
ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern); ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);
if (ctx->buf == NULL) {
free(ctx);
return 0;
}
gettimeofday(&ctx->t1, NULL); gettimeofday(&ctx->t1, NULL);
acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov, acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,